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