Thursday, May 02, 2013

How to resolve the USB-Ethernet device un-registration on Android.



         On Our OMAP4 board, we were enabling the USB-Ethernet functionality. We were using the SMSC Ethernet drivers. The 'eth0' interface was getting registered succesfully , but immediately the interface was getting removed off.

  Root Cause : It seems like , android intentionally removing the Ultra Fast Medias from the system.
  In one of the init.rc file, this below piece of code was creating the havoc.

# Remove the Ultra Fast Media Card Reader on EHCI bus
# write /sys/bus/usb/devices/1-1.1/remove 1

TLV320AIC3104 Audio Playback on 3.0.31 kernel.


We have migrated from 3.0.21 kernel to 3.0.31 kernel version.

One of the main issue we have observed is in audio playback. On previous version (3.0.21) the audio playback was working fine. But on 3.0.31 it was failing.

  Root Cause : We are using the TLV320AIC3104 audio codec chip on our OMAP4 board.
 Observation was 'Always the DIN pin was down' But the MCLK, BCLK and WCLK clocks were fine.

  In devices.c file (arch/arm/mach-omap2) omap_init_mcpdm() function, the CLOCKS were getting reset .

I Am not sure why this clock resetting was required in 3.0.31. I has posted an query to TI E2E forum on why the clock resetting was required.
http://e2e.ti.com/support/omap/f/849/p/258490/917666.aspx#917666

How to resolve the OTG Malfunctioning when adb service is started.


   On Our OMAP4 board, we have enabled the OTG (On The Go) functionality .

   It has been enabled in both Master mode and Slave mode.

   Master Mode  : Connect USB mouse to the OTG port on the board. The Board will recognize the USB mouse. In this case, the board is acting as a master and the usb mouse as a slave one.

   Slave Mode  : Connect the OMAP4 board on to the PC.  PC recognizes the board. PC acts as a host device and the board acts as a slave one.

  While Enabling the OTG functionality, we bumped into a problem where in which the OTG functionality was getting failed .

  Root Cause : In init.rc file, we use to start the ADB service which was causing the reset of OTG functionality.

  Comment out the below lines from init.rc file , which has helped in resolving this issue.

#set the adb properties which will help in installing the applications.
#    setprop service.adb.tcp.port 5555
#    stop adbd
#    start adbd

OTG Links
 1) http://en.wikipedia.org/wiki/USB_On-The-Go

Monday, January 28, 2013

Android User application as System Application or as a prebuilt application

In many scenario's with the customized android ROM's, we want some of the android applications to be a part of the android image. i.e we want the apk's as a prebuilt apk.

Follow these instructions, to prepare an apk as a prebuilt apk.

Adding a prebuilt APK (Android.mk)

  LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)
   
  # Module name should match apk name to be installed.
  LOCAL_MODULE := LocalModuleName
  LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
  LOCAL_MODULE_CLASS := APPS
  LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
   
  include $(BUILD_PREBUILT)

Enable LCD Brightness control feature for Generic DPI Panels


By default, the 'LCD brightness control' feature has not been added in the Generic DPI panel drivers.

Follow these steps , which will enable the brightness control for the Generic DPI panel drivers.

Kernel version : 3.0.21
Processor         : OMAP4460
Android O.S    : Ice Cream Sandwich (4.0.3)

List of files which requires modifications are.
1) LCD Driver File - panel-generic-dpi.c
2) Board file      - board-4430dsp.c
3) Kernel Config File.

Changes to the LCD Driver File
(/drivers/video/omap2/displays/panel-generic-dpi.c)

1)  #include <linux/backlight.h>

2) //brightness start
static int generic_bl_get_intensity(struct backlight_device *dev)
{
if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
dev->props.power == FB_BLANK_UNBLANK)
return dev->props.brightness;

return 0;
}

static int generic_bl_update_status(struct backlight_device *bl)
{
struct omap_dss_device *dssdev = dev_get_drvdata(&bl->dev);

int level;

if (!dssdev->set_backlight)
return -EINVAL;

if (bl->props.fb_blank == FB_BLANK_UNBLANK &&
bl->props.power == FB_BLANK_UNBLANK)
level = bl->props.brightness;
else
level = 0;


return dssdev->set_backlight(dssdev, level);

}

static const struct backlight_ops generic_bl_ops = {
.get_brightness = generic_bl_get_intensity,
.update_status  = generic_bl_update_status,
};


3) struct panel_drv_data {

struct omap_dss_device *dssdev;

struct panel_config *panel_config;

//brightness start
struct backlight_device *bldev;
//brightness end
};

4) static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
{
struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
struct panel_config *panel_config = NULL;
struct panel_drv_data *drv_data = NULL;

//brightness start
struct backlight_device *bldev = NULL ;
struct backlight_properties props ;
int iTemp = 0;

//brightness end

int i;

dev_dbg(&dssdev->dev, "probe\n");

if (!panel_data || !panel_data->name)
return -EINVAL;

for (i = 0; i < ARRAY_SIZE(generic_dpi_panels); i++) {
if (strcmp(panel_data->name, generic_dpi_panels[i].name) == 0) {
panel_config = &generic_dpi_panels[i];
break;
}
}

if (!panel_config)
return -EINVAL;

dssdev->panel.config = panel_config->config;
dssdev->panel.timings = panel_config->timings;
dssdev->panel.acb = panel_config->acb;
dssdev->panel.acbi = panel_config->acbi;

drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL);
if (!drv_data)
return -ENOMEM;

drv_data->dssdev = dssdev;
drv_data->panel_config = panel_config;

dev_set_drvdata(&dssdev->dev, drv_data);

//brightness start
/* if no platform set_backlight() defined, presume DSI backlight
* control */
memset(&props, 0, sizeof(struct backlight_properties));

       props.max_brightness = 255; //the brightness values have been in the range from 0 - 255
       props.type = BACKLIGHT_RAW;

//The sysfs entries will be created after the registration

bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
dssdev, &generic_bl_ops, &props);

if (IS_ERR(bldev))
{
int r = PTR_ERR(bldev);

printk("SANDEEP:generic_dpi_panel_probe() backlight device register didn't happenned \n");

}

bldev->props.fb_blank = FB_BLANK_UNBLANK;
bldev->props.power = FB_BLANK_UNBLANK;
bldev->props.brightness = dssdev->max_backlight_level;

iTemp = generic_bl_update_status(bldev);

if (iTemp < 0)
{
dev_err(&dssdev->dev, "failed to set lcd brightness\n");

printk("SANDEEP:generic_dpi_panel_probe() Failed to set the LCD brightness \n");

}
drv_data->bldev = bldev ; //Copying the backlight data to the driver data. So, that in the later stages this data can be used.

//brightness end

return 0;
}

5)
static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev)
{
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
//brightness start
struct backlight_device *bldev;
//brightness end
dev_dbg(&dssdev->dev, "remove\n");

//brightness start
if(NULL != drv_data->bldev)
{
bldev = drv_data->bldev ; //getting the backlight data back again.

bldev->props.power = FB_BLANK_POWERDOWN;

backlight_device_unregister(bldev);
}
//brightness end

kfree(drv_data);

dev_set_drvdata(&dssdev->dev, NULL);
}

Changes to the Board File

//brightness start

static int generic_set_backlight(struct omap_dss_device *dssdev, int level)
{
int r;

r = twl_i2c_write_u8(TWL_MODULE_PWM, 0x7F, LED_PWM2OFF);

if (r)
return r;

if (level > 1 && level >=20 && level < 255)
{
  if (level == 255)
                     level = 0x7F;
                else
//                         level = (~(level/2)) & 0x7F;
level = level /2 ; //dummy statement. Needs to check the side effect of this.

                r = twl_i2c_write_u8(TWL_MODULE_PWM, level, LED_PWM2ON);
                if (r)
                        return r;
                r = twl_i2c_write_u8(TWL6030_MODULE_ID1, 0x30, TWL6030_TOGGLE3);
                if (r)
                        return r;
}
else if (level <= 1)
{
                  r = twl_i2c_write_u8(TWL6030_MODULE_ID1, 0x08, TWL6030_TOGGLE3);
                if (r)
                        return r;
                r = twl_i2c_write_u8(TWL6030_MODULE_ID1, 0x28, TWL6030_TOGGLE3);
                if (r)
                        return r;
                r = twl_i2c_write_u8(TWL6030_MODULE_ID1, 0x00, TWL6030_TOGGLE3);
                if (r)
                        return r;
        }
         return 0;
 }

//brightness end

2) struct omap_dss_device omap4_spanda_dvi_device = {
        .type                   = OMAP_DISPLAY_TYPE_DPI,
        .name                   = "generic",
        .driver_name            = "generic_dpi_panel",
        .data                   = &omap4_dvi_panel,
        .phy.dpi.data_lines     = 24,
        .reset_gpio             = PANDA_DVI_TFP410_POWER_DOWN_GPIO,
        .channel                = OMAP_DSS_CHANNEL_LCD2,
 //brightness  start
.set_backlight = generic_set_backlight,
//brightness end
};

Changes to Kernel Config File
CONFIG_BACKLIGHT_GENERIC = y