Commit c59eef17 authored by Andres Salomon's avatar Andres Salomon Committed by Greg Kroah-Hartman

staging: olpc_dcon: clean up backlight handling

 - Move bl_val and bl_dev into dcon_priv struct....
 - The only time we ever read the backlight val from the dcon is
   at probe time.  Rather than calling dcon_get_backlight for that, just
   read from the register.
 - Drop dcon_get_backlight; it's just returning dcon->bl_val.
 - Rename dcon_set_backlight_hw to dcon_set_backlight, and drop the
   old dcon_set_backlight function.  Move contents of old dcon_set_backlight
   function into dconbl_set.
 - Shuffle backlight_ops callbacks around to be closer to struct, and
   rename them.
 - Make use of new backlight_properties arg to backlight_device_register,
   drop old code that set this manually.
Signed-off-by: default avatarAndres Salomon <dilinger@queued.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 309ef2a2
...@@ -50,9 +50,6 @@ static struct dcon_platform_data *pdata; ...@@ -50,9 +50,6 @@ static struct dcon_platform_data *pdata;
/* Platform devices */ /* Platform devices */
static struct platform_device *dcon_device; static struct platform_device *dcon_device;
/* Backlight device */
static struct backlight_device *dcon_bl_dev;
static DECLARE_WAIT_QUEUE_HEAD(dcon_wait_queue); static DECLARE_WAIT_QUEUE_HEAD(dcon_wait_queue);
static unsigned short normal_i2c[] = { 0x0d, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x0d, I2C_CLIENT_END };
...@@ -67,9 +64,6 @@ static s32 dcon_read(struct dcon_priv *dcon, u8 reg) ...@@ -67,9 +64,6 @@ static s32 dcon_read(struct dcon_priv *dcon, u8 reg)
return i2c_smbus_read_word_data(dcon->client, reg); return i2c_smbus_read_word_data(dcon->client, reg);
} }
/* The current backlight value - this saves us some smbus traffic */
static int bl_val = -1;
/* ===== API functions - these are called by a variety of users ==== */ /* ===== API functions - these are called by a variety of users ==== */
static int dcon_hw_init(struct dcon_priv *dcon, int is_init) static int dcon_hw_init(struct dcon_priv *dcon, int is_init)
...@@ -185,25 +179,13 @@ static int dcon_bus_stabilize(struct dcon_priv *dcon, int is_powered_down) ...@@ -185,25 +179,13 @@ static int dcon_bus_stabilize(struct dcon_priv *dcon, int is_powered_down)
return 0; return 0;
} }
static int dcon_get_backlight(struct dcon_priv *dcon) static void dcon_set_backlight(struct dcon_priv *dcon, u8 level)
{ {
if (!dcon || !dcon->client) dcon->bl_val = level;
return 0; dcon_write(dcon, DCON_REG_BRIGHT, dcon->bl_val);
if (bl_val == -1)
bl_val = dcon_read(dcon, DCON_REG_BRIGHT) & 0x0F;
return bl_val;
}
static void dcon_set_backlight_hw(struct dcon_priv *dcon, int level)
{
bl_val = level & 0x0F;
dcon_write(dcon, DCON_REG_BRIGHT, bl_val);
/* Purposely turn off the backlight when we go to level 0 */ /* Purposely turn off the backlight when we go to level 0 */
if (bl_val == 0) { if (dcon->bl_val == 0) {
dcon->disp_mode &= ~MODE_BL_ENABLE; dcon->disp_mode &= ~MODE_BL_ENABLE;
dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode); dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode);
} else if (!(dcon->disp_mode & MODE_BL_ENABLE)) { } else if (!(dcon->disp_mode & MODE_BL_ENABLE)) {
...@@ -212,17 +194,6 @@ static void dcon_set_backlight_hw(struct dcon_priv *dcon, int level) ...@@ -212,17 +194,6 @@ static void dcon_set_backlight_hw(struct dcon_priv *dcon, int level)
} }
} }
static void dcon_set_backlight(struct dcon_priv *dcon, int level)
{
if (!dcon || !dcon->client)
return;
if (bl_val == (level & 0x0F))
return;
dcon_set_backlight_hw(dcon, level);
}
/* Set the output type to either color or mono */ /* Set the output type to either color or mono */
static int dcon_set_mono_mode(struct dcon_priv *dcon, bool enable_mono) static int dcon_set_mono_mode(struct dcon_priv *dcon, bool enable_mono)
{ {
...@@ -271,7 +242,7 @@ static void dcon_sleep(struct dcon_priv *dcon, bool sleep) ...@@ -271,7 +242,7 @@ static void dcon_sleep(struct dcon_priv *dcon, bool sleep)
dcon->asleep = sleep; dcon->asleep = sleep;
} else { } else {
/* Only re-enable the backlight if the backlight value is set */ /* Only re-enable the backlight if the backlight value is set */
if (bl_val != 0) if (dcon->bl_val != 0)
dcon->disp_mode |= MODE_BL_ENABLE; dcon->disp_mode |= MODE_BL_ENABLE;
x = dcon_bus_stabilize(dcon, 1); x = dcon_bus_stabilize(dcon, 1);
if (x) if (x)
...@@ -281,7 +252,7 @@ static void dcon_sleep(struct dcon_priv *dcon, bool sleep) ...@@ -281,7 +252,7 @@ static void dcon_sleep(struct dcon_priv *dcon, bool sleep)
dcon->asleep = sleep; dcon->asleep = sleep;
/* Restore backlight */ /* Restore backlight */
dcon_set_backlight_hw(dcon, bl_val); dcon_set_backlight(dcon, dcon->bl_val);
} }
/* We should turn off some stuff in the framebuffer - but what? */ /* We should turn off some stuff in the framebuffer - but what? */
...@@ -458,24 +429,6 @@ static void dcon_set_source_sync(struct dcon_priv *dcon, int arg) ...@@ -458,24 +429,6 @@ static void dcon_set_source_sync(struct dcon_priv *dcon, int arg)
flush_scheduled_work(); flush_scheduled_work();
} }
static int dconbl_set(struct backlight_device *dev)
{
struct dcon_priv *dcon = bl_get_data(dev);
int level = dev->props.brightness;
if (dev->props.power != FB_BLANK_UNBLANK)
level = 0;
dcon_set_backlight(dcon, level);
return 0;
}
static int dconbl_get(struct backlight_device *dev)
{
struct dcon_priv *dcon = bl_get_data(dev);
return dcon_get_backlight(dcon);
}
static ssize_t dcon_mode_show(struct device *dev, static ssize_t dcon_mode_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
...@@ -594,11 +547,35 @@ static struct device_attribute dcon_device_files[] = { ...@@ -594,11 +547,35 @@ static struct device_attribute dcon_device_files[] = {
__ATTR(resumeline, 0644, dcon_resumeline_show, dcon_resumeline_store), __ATTR(resumeline, 0644, dcon_resumeline_show, dcon_resumeline_store),
}; };
static int dcon_bl_update(struct backlight_device *dev)
{
struct dcon_priv *dcon = bl_get_data(dev);
u8 level = dev->props.brightness & 0x0F;
if (dev->props.power != FB_BLANK_UNBLANK)
level = 0;
if (level != dcon->bl_val)
dcon_set_backlight(dcon, level);
return 0;
}
static int dcon_bl_get(struct backlight_device *dev)
{
struct dcon_priv *dcon = bl_get_data(dev);
return dcon->bl_val;
}
static const struct backlight_ops dcon_bl_ops = { static const struct backlight_ops dcon_bl_ops = {
.get_brightness = dconbl_get, .update_status = dcon_bl_update,
.update_status = dconbl_set .get_brightness = dcon_bl_get,
}; };
static struct backlight_properties dcon_bl_props = {
.max_brightness = 15,
.power = FB_BLANK_UNBLANK,
};
static int dcon_reboot_notify(struct notifier_block *nb, static int dcon_reboot_notify(struct notifier_block *nb,
unsigned long foo, void *bar) unsigned long foo, void *bar)
...@@ -707,20 +684,16 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -707,20 +684,16 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id)
} }
} }
/* Add the backlight device for the DCON */ dcon->bl_val = dcon_read(dcon, DCON_REG_BRIGHT) & 0x0F;
dcon_bl_dev = backlight_device_register("dcon-bl", &dcon_device->dev,
dcon, &dcon_bl_ops, NULL);
if (IS_ERR(dcon_bl_dev)) {
printk(KERN_ERR "Cannot register the backlight device (%ld)\n",
PTR_ERR(dcon_bl_dev));
dcon_bl_dev = NULL;
} else {
dcon_bl_dev->props.max_brightness = 15;
dcon_bl_dev->props.power = FB_BLANK_UNBLANK;
dcon_bl_dev->props.brightness = dcon_get_backlight(dcon);
backlight_update_status(dcon_bl_dev); /* Add the backlight device for the DCON */
dcon_bl_props.brightness = dcon->bl_val;
dcon->bl_dev = backlight_device_register("dcon-bl", &dcon_device->dev,
dcon, &dcon_bl_ops, &dcon_bl_props);
if (IS_ERR(dcon->bl_dev)) {
dev_err(&client->dev, "cannot register backlight dev (%ld)\n",
PTR_ERR(dcon->bl_dev));
dcon->bl_dev = NULL;
} }
register_reboot_notifier(&dcon->reboot_nb); register_reboot_notifier(&dcon->reboot_nb);
...@@ -755,8 +728,8 @@ static int dcon_remove(struct i2c_client *client) ...@@ -755,8 +728,8 @@ static int dcon_remove(struct i2c_client *client)
free_irq(DCON_IRQ, dcon); free_irq(DCON_IRQ, dcon);
if (dcon_bl_dev != NULL) if (dcon->bl_dev)
backlight_device_unregister(dcon_bl_dev); backlight_device_unregister(dcon->bl_dev);
if (dcon_device != NULL) if (dcon_device != NULL)
platform_device_unregister(dcon_device); platform_device_unregister(dcon_device);
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
struct dcon_priv { struct dcon_priv {
struct i2c_client *client; struct i2c_client *client;
struct fb_info *fbinfo; struct fb_info *fbinfo;
struct backlight_device *bl_dev;
struct work_struct switch_source; struct work_struct switch_source;
struct notifier_block reboot_nb; struct notifier_block reboot_nb;
...@@ -58,6 +59,9 @@ struct dcon_priv { ...@@ -58,6 +59,9 @@ struct dcon_priv {
/* Shadow register for the DCON_REG_MODE register */ /* Shadow register for the DCON_REG_MODE register */
u8 disp_mode; u8 disp_mode;
/* The current backlight value - this saves us some smbus traffic */
u8 bl_val;
/* Current source, initialized at probe time */ /* Current source, initialized at probe time */
int curr_src; int curr_src;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment