diff options
Diffstat (limited to 'drivers/video/backlight')
30 files changed, 962 insertions, 56 deletions
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c new file mode 100644 index 00000000000..68d2518fada --- /dev/null +++ b/drivers/video/backlight/88pm860x_bl.c @@ -0,0 +1,307 @@ +/* + * Backlight driver for Marvell Semiconductor 88PM8606 + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/fb.h> +#include <linux/i2c.h> +#include <linux/backlight.h> +#include <linux/mfd/88pm860x.h> +#include <linux/slab.h> + +#define MAX_BRIGHTNESS (0xFF) +#define MIN_BRIGHTNESS (0) + +#define CURRENT_MASK (0x1F << 1) + +struct pm860x_backlight_data { + struct pm860x_chip *chip; + struct i2c_client *i2c; + int current_brightness; + int port; + int pwm; + int iset; +}; + +static inline int wled_a(int port) +{ + int ret; + + ret = ((port - PM8606_BACKLIGHT1) << 1) + 2; + return ret; +} + +static inline int wled_b(int port) +{ + int ret; + + ret = ((port - PM8606_BACKLIGHT1) << 1) + 3; + return ret; +} + +/* WLED2 & WLED3 share the same IDC */ +static inline int wled_idc(int port) +{ + int ret; + + switch (port) { + case PM8606_BACKLIGHT1: + case PM8606_BACKLIGHT2: + ret = ((port - PM8606_BACKLIGHT1) << 1) + 3; + break; + case PM8606_BACKLIGHT3: + default: + ret = ((port - PM8606_BACKLIGHT2) << 1) + 3; + break; + } + return ret; +} + +static int pm860x_backlight_set(struct backlight_device *bl, int brightness) +{ + struct pm860x_backlight_data *data = bl_get_data(bl); + struct pm860x_chip *chip = data->chip; + unsigned char value; + int ret; + + if (brightness > MAX_BRIGHTNESS) + value = MAX_BRIGHTNESS; + else + value = brightness; + + ret = pm860x_reg_write(data->i2c, wled_a(data->port), value); + if (ret < 0) + goto out; + + if ((data->current_brightness == 0) && brightness) { + if (data->iset) { + ret = pm860x_set_bits(data->i2c, wled_idc(data->port), + CURRENT_MASK, data->iset); + if (ret < 0) + goto out; + } + if (data->pwm) { + ret = pm860x_set_bits(data->i2c, PM8606_PWM, + PM8606_PWM_FREQ_MASK, data->pwm); + if (ret < 0) + goto out; + } + if (brightness == MAX_BRIGHTNESS) { + /* set WLED_ON bit as 100% */ + ret = pm860x_set_bits(data->i2c, wled_b(data->port), + PM8606_WLED_ON, PM8606_WLED_ON); + } + } else { + if (brightness == MAX_BRIGHTNESS) { + /* set WLED_ON bit as 100% */ + ret = pm860x_set_bits(data->i2c, wled_b(data->port), + PM8606_WLED_ON, PM8606_WLED_ON); + } else { + /* clear WLED_ON bit since it's not 100% */ + ret = pm860x_set_bits(data->i2c, wled_b(data->port), + PM8606_WLED_ON, 0); + } + } + if (ret < 0) + goto out; + + dev_dbg(chip->dev, "set brightness %d\n", value); + data->current_brightness = value; + return 0; +out: + dev_dbg(chip->dev, "set brightness %d failure with return " + "value:%d\n", value, ret); + return ret; +} + +static int pm860x_backlight_update_status(struct backlight_device *bl) +{ + int brightness = bl->props.brightness; + + if (bl->props.power != FB_BLANK_UNBLANK) + brightness = 0; + + if (bl->props.fb_blank != FB_BLANK_UNBLANK) + brightness = 0; + + if (bl->props.state & BL_CORE_SUSPENDED) + brightness = 0; + + return pm860x_backlight_set(bl, brightness); +} + +static int pm860x_backlight_get_brightness(struct backlight_device *bl) +{ + struct pm860x_backlight_data *data = bl_get_data(bl); + struct pm860x_chip *chip = data->chip; + int ret; + + ret = pm860x_reg_read(data->i2c, wled_a(data->port)); + if (ret < 0) + goto out; + data->current_brightness = ret; + dev_dbg(chip->dev, "get brightness %d\n", data->current_brightness); + return data->current_brightness; +out: + return -EINVAL; +} + +static struct backlight_ops pm860x_backlight_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = pm860x_backlight_update_status, + .get_brightness = pm860x_backlight_get_brightness, +}; + +static int __check_device(struct pm860x_backlight_pdata *pdata, char *name) +{ + struct pm860x_backlight_pdata *p = pdata; + int ret = -EINVAL; + + while (p && p->id) { + if ((p->id != PM8606_ID_BACKLIGHT) || (p->flags < 0)) + break; + + if (!strncmp(name, pm860x_backlight_name[p->flags], + MFD_NAME_SIZE)) { + ret = (int)p->flags; + break; + } + p++; + } + return ret; +} + +static int pm860x_backlight_probe(struct platform_device *pdev) +{ + struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct pm860x_platform_data *pm860x_pdata; + struct pm860x_backlight_pdata *pdata = NULL; + struct pm860x_backlight_data *data; + struct backlight_device *bl; + struct resource *res; + struct backlight_properties props; + unsigned char value; + char name[MFD_NAME_SIZE]; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (res == NULL) { + dev_err(&pdev->dev, "No I/O resource!\n"); + return -EINVAL; + } + + if (pdev->dev.parent->platform_data) { + pm860x_pdata = pdev->dev.parent->platform_data; + pdata = pm860x_pdata->backlight; + } + if (pdata == NULL) { + dev_err(&pdev->dev, "platform data isn't assigned to " + "backlight\n"); + return -EINVAL; + } + + data = kzalloc(sizeof(struct pm860x_backlight_data), GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + strncpy(name, res->name, MFD_NAME_SIZE); + data->chip = chip; + data->i2c = (chip->id == CHIP_PM8606) ? chip->client \ + : chip->companion; + data->current_brightness = MAX_BRIGHTNESS; + data->pwm = pdata->pwm; + data->iset = pdata->iset; + data->port = __check_device(pdata, name); + if (data->port < 0) { + dev_err(&pdev->dev, "wrong platform data is assigned"); + return -EINVAL; + } + + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = MAX_BRIGHTNESS; + bl = backlight_device_register(name, &pdev->dev, data, + &pm860x_backlight_ops, &props); + if (IS_ERR(bl)) { + dev_err(&pdev->dev, "failed to register backlight\n"); + kfree(data); + return PTR_ERR(bl); + } + bl->props.brightness = MAX_BRIGHTNESS; + + platform_set_drvdata(pdev, bl); + + /* Enable reference VSYS */ + ret = pm860x_reg_read(data->i2c, PM8606_VSYS); + if (ret < 0) + goto out; + if ((ret & PM8606_VSYS_EN) == 0) { + value = ret | PM8606_VSYS_EN; + ret = pm860x_reg_write(data->i2c, PM8606_VSYS, value); + if (ret < 0) + goto out; + } + /* Enable reference OSC */ + ret = pm860x_reg_read(data->i2c, PM8606_MISC); + if (ret < 0) + goto out; + if ((ret & PM8606_MISC_OSC_EN) == 0) { + value = ret | PM8606_MISC_OSC_EN; + ret = pm860x_reg_write(data->i2c, PM8606_MISC, value); + if (ret < 0) + goto out; + } + /* read current backlight */ + ret = pm860x_backlight_get_brightness(bl); + if (ret < 0) + goto out; + + backlight_update_status(bl); + return 0; +out: + kfree(data); + return ret; +} + +static int pm860x_backlight_remove(struct platform_device *pdev) +{ + struct backlight_device *bl = platform_get_drvdata(pdev); + struct pm860x_backlight_data *data = bl_get_data(bl); + + backlight_device_unregister(bl); + kfree(data); + return 0; +} + +static struct platform_driver pm860x_backlight_driver = { + .driver = { + .name = "88pm860x-backlight", + .owner = THIS_MODULE, + }, + .probe = pm860x_backlight_probe, + .remove = pm860x_backlight_remove, +}; + +static int __init pm860x_backlight_init(void) +{ + return platform_driver_register(&pm860x_backlight_driver); +} +module_init(pm860x_backlight_init); + +static void __exit pm860x_backlight_exit(void) +{ + platform_driver_unregister(&pm860x_backlight_driver); +} +module_exit(pm860x_backlight_exit); + +MODULE_DESCRIPTION("Backlight Driver for Marvell Semiconductor 88PM8606"); +MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:88pm860x-backlight"); diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 09bfa9662e4..c025c84601b 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -31,6 +31,13 @@ config LCD_CORGI Say y here to support the LCD panels usually found on SHARP corgi (C7x0) and spitz (Cxx00) models. +config LCD_L4F00242T03 + tristate "Epson L4F00242T03 LCD" + depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO + help + SPI driver for Epson L4F00242T03. This provides basic support + for init and powering the LCD up/down through a sysfs interface. + config LCD_LMS283GF05 tristate "Samsung LMS283GF05 LCD" depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO @@ -212,6 +219,13 @@ config BACKLIGHT_DA903X If you have a LCD backlight connected to the WLED output of DA9030 or DA9034 WLED output, say Y here to enable this driver. +config BACKLIGHT_MAX8925 + tristate "Backlight driver for MAX8925" + depends on BACKLIGHT_CLASS_DEVICE && MFD_MAX8925 + help + If you have a LCD backlight connected to the WLED output of MAX8925 + WLED output, say Y here to enable this driver. + config BACKLIGHT_MBP_NVIDIA tristate "MacBook Pro Nvidia Backlight Driver" depends on BACKLIGHT_CLASS_DEVICE && X86 @@ -262,3 +276,9 @@ config BACKLIGHT_ADP5520 To compile this driver as a module, choose M here: the module will be called adp5520_bl. +config BACKLIGHT_88PM860X + tristate "Backlight Driver for 88PM8606 using WLED" + depends on BACKLIGHT_CLASS_DEVICE && MFD_88PM860X + help + Say Y to enable the backlight driver for Marvell 88PM8606. + diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 9a405548874..09d1f14d625 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o +obj-$(CONFIG_LCD_L4F00242T03) += l4f00242t03.o obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o obj-$(CONFIG_LCD_ILI9320) += ili9320.o @@ -22,10 +23,12 @@ obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o +obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o obj-$(CONFIG_BACKLIGHT_ADX) += adx_bl.o obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o +obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c index 86d95c228ad..9f436e014f8 100644 --- a/drivers/video/backlight/adp5520_bl.c +++ b/drivers/video/backlight/adp5520_bl.c @@ -12,6 +12,7 @@ #include <linux/fb.h> #include <linux/backlight.h> #include <linux/mfd/adp5520.h> +#include <linux/slab.h> struct adp5520_bl { struct device *master; @@ -278,6 +279,7 @@ static const struct attribute_group adp5520_bl_attr_group = { static int __devinit adp5520_bl_probe(struct platform_device *pdev) { + struct backlight_properties props; struct backlight_device *bl; struct adp5520_bl *data; int ret = 0; @@ -300,17 +302,17 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev) mutex_init(&data->lock); - bl = backlight_device_register(pdev->name, data->master, - data, &adp5520_bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = ADP5020_MAX_BRIGHTNESS; + bl = backlight_device_register(pdev->name, data->master, data, + &adp5520_bl_ops, &props); if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); kfree(data); return PTR_ERR(bl); } - bl->props.max_brightness = - bl->props.brightness = ADP5020_MAX_BRIGHTNESS; - + bl->props.brightness = ADP5020_MAX_BRIGHTNESS; if (data->pdata->en_ambl_sens) ret = sysfs_create_group(&bl->dev.kobj, &adp5520_bl_attr_group); diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c index d769b0bab21..7f4a7c30a98 100644 --- a/drivers/video/backlight/adx_bl.c +++ b/drivers/video/backlight/adx_bl.c @@ -12,6 +12,7 @@ #include <linux/backlight.h> #include <linux/fb.h> +#include <linux/gfp.h> #include <linux/io.h> #include <linux/module.h> #include <linux/platform_device.h> @@ -56,7 +57,7 @@ static int adx_backlight_get_brightness(struct backlight_device *bldev) return brightness & 0xff; } -static int adx_backlight_check_fb(struct fb_info *fb) +static int adx_backlight_check_fb(struct backlight_device *bldev, struct fb_info *fb) { return 1; } @@ -70,6 +71,7 @@ static const struct backlight_ops adx_backlight_ops = { static int __devinit adx_backlight_probe(struct platform_device *pdev) { + struct backlight_properties props; struct backlight_device *bldev; struct resource *res; struct adxbl *bl; @@ -101,14 +103,15 @@ static int __devinit adx_backlight_probe(struct platform_device *pdev) goto out; } - bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, bl, - &adx_backlight_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 0xff; + bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, + bl, &adx_backlight_ops, &props); if (!bldev) { ret = -ENOMEM; goto out; } - bldev->props.max_brightness = 0xff; bldev->props.brightness = 0xff; bldev->props.power = FB_BLANK_UNBLANK; diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c index f625ffc69ad..e6a66dab088 100644 --- a/drivers/video/backlight/atmel-pwm-bl.c +++ b/drivers/video/backlight/atmel-pwm-bl.c @@ -17,6 +17,7 @@ #include <linux/backlight.h> #include <linux/atmel_pwm.h> #include <linux/atmel-pwm-bl.h> +#include <linux/slab.h> struct atmel_pwm_bl { const struct atmel_pwm_bl_platform_data *pdata; @@ -120,6 +121,7 @@ static const struct backlight_ops atmel_pwm_bl_ops = { static int atmel_pwm_bl_probe(struct platform_device *pdev) { + struct backlight_properties props; const struct atmel_pwm_bl_platform_data *pdata; struct backlight_device *bldev; struct atmel_pwm_bl *pwmbl; @@ -165,8 +167,10 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) goto err_free_gpio; } - bldev = backlight_device_register("atmel-pwm-bl", - &pdev->dev, pwmbl, &atmel_pwm_bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min; + bldev = backlight_device_register("atmel-pwm-bl", &pdev->dev, pwmbl, + &atmel_pwm_bl_ops, &props); if (IS_ERR(bldev)) { retval = PTR_ERR(bldev); goto err_free_gpio; @@ -178,7 +182,6 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) /* Power up the backlight by default at middle intesity. */ bldev->props.power = FB_BLANK_UNBLANK; - bldev->props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min; bldev->props.brightness = bldev->props.max_brightness / 2; retval = atmel_pwm_bl_init_pwm(pwmbl); diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 18829cf68b1..e207810bba3 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -13,6 +13,7 @@ #include <linux/ctype.h> #include <linux/err.h> #include <linux/fb.h> +#include <linux/slab.h> #ifdef CONFIG_PMAC_BACKLIGHT #include <asm/backlight.h> @@ -38,7 +39,7 @@ static int fb_notifier_callback(struct notifier_block *self, mutex_lock(&bd->ops_lock); if (bd->ops) if (!bd->ops->check_fb || - bd->ops->check_fb(evdata->info)) { + bd->ops->check_fb(bd, evdata->info)) { bd->props.fb_blank = *(int *)evdata->data; if (bd->props.fb_blank == FB_BLANK_UNBLANK) bd->props.state &= ~BL_CORE_FBBLANK; @@ -269,7 +270,8 @@ EXPORT_SYMBOL(backlight_force_update); * ERR_PTR() or a pointer to the newly allocated device. */ struct backlight_device *backlight_device_register(const char *name, - struct device *parent, void *devdata, const struct backlight_ops *ops) + struct device *parent, void *devdata, const struct backlight_ops *ops, + const struct backlight_properties *props) { struct backlight_device *new_bd; int rc; @@ -289,6 +291,11 @@ struct backlight_device *backlight_device_register(const char *name, dev_set_name(&new_bd->dev, name); dev_set_drvdata(&new_bd->dev, devdata); + /* Set default properties */ + if (props) + memcpy(&new_bd->props, props, + sizeof(struct backlight_properties)); + rc = device_register(&new_bd->dev); if (rc) { kfree(new_bd); diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c index b4bcf804379..1e71c35083b 100644 --- a/drivers/video/backlight/corgi_lcd.c +++ b/drivers/video/backlight/corgi_lcd.c @@ -24,6 +24,7 @@ #include <linux/lcd.h> #include <linux/spi/spi.h> #include <linux/spi/corgi_lcd.h> +#include <linux/slab.h> #include <asm/mach/sharpsl_param.h> #define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) @@ -533,6 +534,7 @@ err_free_backlight_on: static int __devinit corgi_lcd_probe(struct spi_device *spi) { + struct backlight_properties props; struct corgi_lcd_platform_data *pdata = spi->dev.platform_data; struct corgi_lcd *lcd; int ret = 0; @@ -559,13 +561,14 @@ static int __devinit corgi_lcd_probe(struct spi_device *spi) lcd->power = FB_BLANK_POWERDOWN; lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA; - lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, - lcd, &corgi_bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = pdata->max_intensity; + lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, lcd, + &corgi_bl_ops, &props); if (IS_ERR(lcd->bl_dev)) { ret = PTR_ERR(lcd->bl_dev); goto err_unregister_lcd; } - lcd->bl_dev->props.max_brightness = pdata->max_intensity; lcd->bl_dev->props.brightness = pdata->default_intensity; lcd->bl_dev->props.power = FB_BLANK_UNBLANK; diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c index da86db4374a..a4f4546f0be 100644 --- a/drivers/video/backlight/cr_bllcd.c +++ b/drivers/video/backlight/cr_bllcd.c @@ -36,6 +36,7 @@ #include <linux/backlight.h> #include <linux/lcd.h> #include <linux/pci.h> +#include <linux/slab.h> /* The LVDS- and panel power controls sits on the * GPIO port of the ISA bridge. @@ -170,6 +171,7 @@ static struct lcd_ops cr_lcd_ops = { static int cr_backlight_probe(struct platform_device *pdev) { + struct backlight_properties props; struct backlight_device *bdp; struct lcd_device *ldp; struct cr_panel *crp; @@ -190,8 +192,9 @@ static int cr_backlight_probe(struct platform_device *pdev) return -ENODEV; } - bdp = backlight_device_register("cr-backlight", - &pdev->dev, NULL, &cr_backlight_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + bdp = backlight_device_register("cr-backlight", &pdev->dev, NULL, + &cr_backlight_ops, &props); if (IS_ERR(bdp)) { pci_dev_put(lpc_dev); return PTR_ERR(bdp); @@ -220,9 +223,7 @@ static int cr_backlight_probe(struct platform_device *pdev) crp->cr_lcd_device = ldp; crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK; crp->cr_backlight_device->props.brightness = 0; - crp->cr_backlight_device->props.max_brightness = 0; cr_backlight_set_intensity(crp->cr_backlight_device); - cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK); platform_set_drvdata(pdev, crp); diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c index 74cdc640173..87659ed79bd 100644 --- a/drivers/video/backlight/da903x_bl.c +++ b/drivers/video/backlight/da903x_bl.c @@ -18,6 +18,7 @@ #include <linux/fb.h> #include <linux/backlight.h> #include <linux/mfd/da903x.h> +#include <linux/slab.h> #define DA9030_WLED_CONTROL 0x25 #define DA9030_WLED_CP_EN (1 << 6) @@ -105,6 +106,7 @@ static int da903x_backlight_probe(struct platform_device *pdev) struct da9034_backlight_pdata *pdata = pdev->dev.platform_data; struct da903x_backlight_data *data; struct backlight_device *bl; + struct backlight_properties props; int max_brightness; data = kzalloc(sizeof(*data), GFP_KERNEL); @@ -134,15 +136,15 @@ static int da903x_backlight_probe(struct platform_device *pdev) da903x_write(data->da903x_dev, DA9034_WLED_CONTROL2, DA9034_WLED_ISET(pdata->output_current)); - bl = backlight_device_register(pdev->name, data->da903x_dev, - data, &da903x_backlight_ops); + props.max_brightness = max_brightness; + bl = backlight_device_register(pdev->name, data->da903x_dev, data, + &da903x_backlight_ops, &props); if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); kfree(data); return PTR_ERR(bl); } - bl->props.max_brightness = max_brightness; bl->props.brightness = max_brightness; platform_set_drvdata(pdev, bl); diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c index e6d348e6359..312ca619735 100644 --- a/drivers/video/backlight/generic_bl.c +++ b/drivers/video/backlight/generic_bl.c @@ -78,6 +78,7 @@ static const struct backlight_ops genericbl_ops = { static int genericbl_probe(struct platform_device *pdev) { + struct backlight_properties props; struct generic_bl_info *machinfo = pdev->dev.platform_data; const char *name = "generic-bl"; struct backlight_device *bd; @@ -89,14 +90,15 @@ static int genericbl_probe(struct platform_device *pdev) if (machinfo->name) name = machinfo->name; - bd = backlight_device_register (name, - &pdev->dev, NULL, &genericbl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = machinfo->max_intensity; + bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops, + &props); if (IS_ERR (bd)) return PTR_ERR (bd); platform_set_drvdata(pdev, bd); - bd->props.max_brightness = machinfo->max_intensity; bd->props.power = FB_BLANK_UNBLANK; bd->props.brightness = machinfo->default_intensity; backlight_update_status(bd); diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index f7cc528d5be..267d23f8d64 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c @@ -105,16 +105,18 @@ static const struct backlight_ops hp680bl_ops = { static int __devinit hp680bl_probe(struct platform_device *pdev) { + struct backlight_properties props; struct backlight_device *bd; - bd = backlight_device_register ("hp680-bl", &pdev->dev, NULL, - &hp680bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = HP680_MAX_INTENSITY; + bd = backlight_device_register("hp680-bl", &pdev->dev, NULL, + &hp680bl_ops, &props); if (IS_ERR(bd)) return PTR_ERR(bd); platform_set_drvdata(pdev, bd); - bd->props.max_brightness = HP680_MAX_INTENSITY; bd->props.brightness = HP680_DEFAULT_INTENSITY; hp680bl_send_intensity(bd); diff --git a/drivers/video/backlight/ili9320.c b/drivers/video/backlight/ili9320.c index ba89b41b639..5118a9f029a 100644 --- a/drivers/video/backlight/ili9320.c +++ b/drivers/video/backlight/ili9320.c @@ -17,6 +17,7 @@ #include <linux/init.h> #include <linux/lcd.h> #include <linux/module.h> +#include <linux/slab.h> #include <linux/spi/spi.h> diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c index db9071fc566..2f177b3a488 100644 --- a/drivers/video/backlight/jornada720_bl.c +++ b/drivers/video/backlight/jornada720_bl.c @@ -101,10 +101,14 @@ static const struct backlight_ops jornada_bl_ops = { static int jornada_bl_probe(struct platform_device *pdev) { + struct backlight_properties props; int ret; struct backlight_device *bd; - bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = BL_MAX_BRIGHT; + bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, + &jornada_bl_ops, &props); if (IS_ERR(bd)) { ret = PTR_ERR(bd); @@ -117,7 +121,6 @@ static int jornada_bl_probe(struct platform_device *pdev) /* note. make sure max brightness is set otherwise you will get seemingly non-related errors when trying to change brightness */ - bd->props.max_brightness = BL_MAX_BRIGHT; jornada_bl_update_status(bd); platform_set_drvdata(pdev, bd); diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c index 939e7b830cf..f439a863228 100644 --- a/drivers/video/backlight/kb3886_bl.c +++ b/drivers/video/backlight/kb3886_bl.c @@ -141,20 +141,24 @@ static const struct backlight_ops kb3886bl_ops = { static int kb3886bl_probe(struct platform_device *pdev) { + struct backlight_properties props; struct kb3886bl_machinfo *machinfo = pdev->dev.platform_data; bl_machinfo = machinfo; if (!machinfo->limit_mask) machinfo->limit_mask = -1; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = machinfo->max_intensity; kb3886_backlight_device = backlight_device_register("kb3886-bl", - &pdev->dev, NULL, &kb3886bl_ops); + &pdev->dev, NULL, + &kb3886bl_ops, + &props); if (IS_ERR(kb3886_backlight_device)) return PTR_ERR(kb3886_backlight_device); platform_set_drvdata(pdev, kb3886_backlight_device); - kb3886_backlight_device->props.max_brightness = machinfo->max_intensity; kb3886_backlight_device->props.power = FB_BLANK_UNBLANK; kb3886_backlight_device->props.brightness = machinfo->default_intensity; backlight_update_status(kb3886_backlight_device); diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c new file mode 100644 index 00000000000..bcdb12c93ef --- /dev/null +++ b/drivers/video/backlight/l4f00242t03.c @@ -0,0 +1,258 @@ +/* + * l4f00242t03.c -- support for Epson L4F00242T03 LCD + * + * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * + * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> + * Inspired by Marek Vasut work in l4f00242t03.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/lcd.h> +#include <linux/slab.h> +#include <linux/regulator/consumer.h> + +#include <linux/spi/spi.h> +#include <linux/spi/l4f00242t03.h> + +struct l4f00242t03_priv { + struct spi_device *spi; + struct lcd_device *ld; + int lcd_on:1; + struct regulator *io_reg; + struct regulator *core_reg; +}; + + +static void l4f00242t03_reset(unsigned int gpio) +{ + pr_debug("l4f00242t03_reset.\n"); + gpio_set_value(gpio, 1); + mdelay(100); + gpio_set_value(gpio, 0); + mdelay(10); /* tRES >= 100us */ + gpio_set_value(gpio, 1); + mdelay(20); +} + +#define param(x) ((x) | 0x100) + +static void l4f00242t03_lcd_init(struct spi_device *spi) +{ + struct l4f00242t03_pdata *pdata = spi->dev.platform_data; + struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); + const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) }; + + dev_dbg(&spi->dev, "initializing LCD\n"); + + if (priv->io_reg) { + regulator_set_voltage(priv->io_reg, 1800000, 1800000); + regulator_enable(priv->io_reg); + } + + if (priv->core_reg) { + regulator_set_voltage(priv->core_reg, 2800000, 2800000); + regulator_enable(priv->core_reg); + } + + gpio_set_value(pdata->data_enable_gpio, 1); + msleep(60); + spi_write(spi, (const u8 *)cmd, ARRAY_SIZE(cmd) * sizeof(u16)); +} + +static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power) +{ + struct l4f00242t03_priv *priv = lcd_get_data(ld); + struct spi_device *spi = priv->spi; + + const u16 slpout = 0x11; + const u16 dison = 0x29; + + const u16 slpin = 0x10; + const u16 disoff = 0x28; + + if (power) { + if (priv->lcd_on) + return 0; + + dev_dbg(&spi->dev, "turning on LCD\n"); + + spi_write(spi, (const u8 *)&slpout, sizeof(u16)); + msleep(60); + spi_write(spi, (const u8 *)&dison, sizeof(u16)); + + priv->lcd_on = 1; + } else { + if (!priv->lcd_on) + return 0; + + dev_dbg(&spi->dev, "turning off LCD\n"); + + spi_write(spi, (const u8 *)&disoff, sizeof(u16)); + msleep(60); + spi_write(spi, (const u8 *)&slpin, sizeof(u16)); + + priv->lcd_on = 0; + } + + return 0; +} + +static struct lcd_ops l4f_ops = { + .set_power = l4f00242t03_lcd_power_set, + .get_power = NULL, +}; + +static int __devinit l4f00242t03_probe(struct spi_device *spi) +{ + struct l4f00242t03_priv *priv; + struct l4f00242t03_pdata *pdata = spi->dev.platform_data; + int ret; + + if (pdata == NULL) { + dev_err(&spi->dev, "Uninitialized platform data.\n"); + return -EINVAL; + } + + priv = kzalloc(sizeof(struct l4f00242t03_priv), GFP_KERNEL); + + if (priv == NULL) { + dev_err(&spi->dev, "No memory for this device.\n"); + ret = -ENOMEM; + goto err; + } + + dev_set_drvdata(&spi->dev, priv); + spi->bits_per_word = 9; + spi_setup(spi); + + priv->spi = spi; + + ret = gpio_request(pdata->reset_gpio, "lcd l4f00242t03 reset"); + if (ret) { + dev_err(&spi->dev, + "Unable to get the lcd l4f00242t03 reset gpio.\n"); + return ret; + } + + ret = gpio_direction_output(pdata->reset_gpio, 1); + if (ret) + goto err2; + + ret = gpio_request(pdata->data_enable_gpio, + "lcd l4f00242t03 data enable"); + if (ret) { + dev_err(&spi->dev, + "Unable to get the lcd l4f00242t03 data en gpio.\n"); + return ret; + } + + ret = gpio_direction_output(pdata->data_enable_gpio, 0); + if (ret) + goto err3; + + if (pdata->io_supply) { + priv->io_reg = regulator_get(NULL, pdata->io_supply); + + if (IS_ERR(priv->io_reg)) { + pr_err("%s: Unable to get the IO regulator\n", + __func__); + goto err3; + } + } + + if (pdata->core_supply) { + priv->core_reg = regulator_get(NULL, pdata->core_supply); + + if (IS_ERR(priv->core_reg)) { + pr_err("%s: Unable to get the core regulator\n", + __func__); + goto err4; + } + } + + priv->ld = lcd_device_register("l4f00242t03", + &spi->dev, priv, &l4f_ops); + if (IS_ERR(priv->ld)) { + ret = PTR_ERR(priv->ld); + goto err5; + } + + /* Init the LCD */ + l4f00242t03_reset(pdata->reset_gpio); + l4f00242t03_lcd_init(spi); + l4f00242t03_lcd_power_set(priv->ld, 1); + + dev_info(&spi->dev, "Epson l4f00242t03 lcd probed.\n"); + + return 0; + +err5: + if (priv->core_reg) + regulator_put(priv->core_reg); +err4: + if (priv->io_reg) + regulator_put(priv->io_reg); +err3: + gpio_free(pdata->data_enable_gpio); +err2: + gpio_free(pdata->reset_gpio); +err: + kfree(priv); + + return ret; +} + +static int __devexit l4f00242t03_remove(struct spi_device *spi) +{ + struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); + struct l4f00242t03_pdata *pdata = priv->spi->dev.platform_data; + + l4f00242t03_lcd_power_set(priv->ld, 0); + lcd_device_unregister(priv->ld); + + gpio_free(pdata->data_enable_gpio); + gpio_free(pdata->reset_gpio); + + if (priv->io_reg) + regulator_put(priv->core_reg); + if (priv->core_reg) + regulator_put(priv->io_reg); + + kfree(priv); + + return 0; +} + +static struct spi_driver l4f00242t03_driver = { + .driver = { + .name = "l4f00242t03", + .owner = THIS_MODULE, + }, + .probe = l4f00242t03_probe, + .remove = __devexit_p(l4f00242t03_remove), +}; + +static __init int l4f00242t03_init(void) +{ + return spi_register_driver(&l4f00242t03_driver); +} + +static __exit void l4f00242t03_exit(void) +{ + spi_unregister_driver(&l4f00242t03_driver); +} + +module_init(l4f00242t03_init); +module_exit(l4f00242t03_exit); + +MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>"); +MODULE_DESCRIPTION("EPSON L4F00242T03 LCD"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 9b3be74cee5..71a11cadffc 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c @@ -13,6 +13,7 @@ #include <linux/ctype.h> #include <linux/err.h> #include <linux/fb.h> +#include <linux/slab.h> #if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \ defined(CONFIG_LCD_CLASS_DEVICE_MODULE)) diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c index 447b542a20c..abc43a0eb97 100644 --- a/drivers/video/backlight/lms283gf05.c +++ b/drivers/video/backlight/lms283gf05.c @@ -11,6 +11,7 @@ #include <linux/device.h> #include <linux/kernel.h> #include <linux/delay.h> +#include <linux/slab.h> #include <linux/gpio.h> #include <linux/lcd.h> diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c index 00a9591b000..7571bc26071 100644 --- a/drivers/video/backlight/locomolcd.c +++ b/drivers/video/backlight/locomolcd.c @@ -167,6 +167,7 @@ static int locomolcd_resume(struct locomo_dev *dev) static int locomolcd_probe(struct locomo_dev *ldev) { + struct backlight_properties props; unsigned long flags; local_irq_save(flags); @@ -182,13 +183,16 @@ static int locomolcd_probe(struct locomo_dev *ldev) local_irq_restore(flags); - locomolcd_bl_device = backlight_device_register("locomo-bl", &ldev->dev, NULL, &locomobl_data); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 4; + locomolcd_bl_device = backlight_device_register("locomo-bl", + &ldev->dev, NULL, + &locomobl_data, &props); if (IS_ERR (locomolcd_bl_device)) return PTR_ERR (locomolcd_bl_device); /* Set up frontlight so that screen is readable */ - locomolcd_bl_device->props.max_brightness = 4, locomolcd_bl_device->props.brightness = 2; locomolcd_set_intensity(locomolcd_bl_device); diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c index 4631ca8fa4a..8010aaeb5ad 100644 --- a/drivers/video/backlight/ltv350qv.c +++ b/drivers/video/backlight/ltv350qv.c @@ -13,6 +13,7 @@ #include <linux/init.h> #include <linux/lcd.h> #include <linux/module.h> +#include <linux/slab.h> #include <linux/spi/spi.h> #include "ltv350qv.h" diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c new file mode 100644 index 00000000000..b5accc957ad --- /dev/null +++ b/drivers/video/backlight/max8925_bl.c @@ -0,0 +1,203 @@ +/* + * Backlight driver for Maxim MAX8925 + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/fb.h> +#include <linux/i2c.h> +#include <linux/backlight.h> +#include <linux/mfd/max8925.h> +#include <linux/slab.h> + +#define MAX_BRIGHTNESS (0xff) +#define MIN_BRIGHTNESS (0) + +#define LWX_FREQ(x) (((x - 601) / 100) & 0x7) + +struct max8925_backlight_data { + struct max8925_chip *chip; + + int current_brightness; +}; + +static int max8925_backlight_set(struct backlight_device *bl, int brightness) +{ + struct max8925_backlight_data *data = bl_get_data(bl); + struct max8925_chip *chip = data->chip; + unsigned char value; + int ret; + + if (brightness > MAX_BRIGHTNESS) + value = MAX_BRIGHTNESS; + else + value = brightness; + + ret = max8925_reg_write(chip->i2c, MAX8925_WLED_CNTL, value); + if (ret < 0) + goto out; + + if (!data->current_brightness && brightness) + /* enable WLED output */ + ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 1); + else if (!brightness) + /* disable WLED output */ + ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 0); + if (ret < 0) + goto out; + dev_dbg(chip->dev, "set brightness %d\n", value); + data->current_brightness = value; + return 0; +out: + dev_dbg(chip->dev, "set brightness %d failure with return value:%d\n", + value, ret); + return ret; +} + +static int max8925_backlight_update_status(struct backlight_device *bl) +{ + int brightness = bl->props.brightness; + + if (bl->props.power != FB_BLANK_UNBLANK) + brightness = 0; + + if (bl->props.fb_blank != FB_BLANK_UNBLANK) + brightness = 0; + + if (bl->props.state & BL_CORE_SUSPENDED) + brightness = 0; + + return max8925_backlight_set(bl, brightness); +} + +static int max8925_backlight_get_brightness(struct backlight_device *bl) +{ + struct max8925_backlight_data *data = bl_get_data(bl); + struct max8925_chip *chip = data->chip; + int ret; + + ret = max8925_reg_read(chip->i2c, MAX8925_WLED_CNTL); + if (ret < 0) + return -EINVAL; + data->current_brightness = ret; + dev_dbg(chip->dev, "get brightness %d\n", data->current_brightness); + return ret; +} + +static struct backlight_ops max8925_backlight_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = max8925_backlight_update_status, + .get_brightness = max8925_backlight_get_brightness, +}; + +static int __devinit max8925_backlight_probe(struct platform_device *pdev) +{ + struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct max8925_platform_data *max8925_pdata; + struct max8925_backlight_pdata *pdata = NULL; + struct max8925_backlight_data *data; + struct backlight_device *bl; + struct backlight_properties props; + struct resource *res; + char name[MAX8925_NAME_SIZE]; + unsigned char value; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (res == NULL) { + dev_err(&pdev->dev, "No I/O resource!\n"); + return -EINVAL; + } + + if (pdev->dev.parent->platform_data) { + max8925_pdata = pdev->dev.parent->platform_data; + pdata = max8925_pdata->backlight; + } + + if (!pdata) { + dev_err(&pdev->dev, "platform data isn't assigned to " + "backlight\n"); + return -EINVAL; + } + + data = kzalloc(sizeof(struct max8925_backlight_data), GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + strncpy(name, res->name, MAX8925_NAME_SIZE); + data->chip = chip; + data->current_brightness = 0; + + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = MAX_BRIGHTNESS; + bl = backlight_device_register(name, &pdev->dev, data, + &max8925_backlight_ops, &props); + if (IS_ERR(bl)) { + dev_err(&pdev->dev, "failed to register backlight\n"); + kfree(data); + return PTR_ERR(bl); + } + bl->props.brightness = MAX_BRIGHTNESS; + + platform_set_drvdata(pdev, bl); + + value = 0; + if (pdata->lxw_scl) + value |= (1 << 7); + if (pdata->lxw_freq) + value |= (LWX_FREQ(pdata->lxw_freq) << 4); + if (pdata->dual_string) + value |= (1 << 1); + ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 0xfe, value); + if (ret < 0) + goto out; + + backlight_update_status(bl); + return 0; +out: + kfree(data); + return ret; +} + +static int __devexit max8925_backlight_remove(struct platform_device *pdev) +{ + struct backlight_device *bl = platform_get_drvdata(pdev); + struct max8925_backlight_data *data = bl_get_data(bl); + + backlight_device_unregister(bl); + kfree(data); + return 0; +} + +static struct platform_driver max8925_backlight_driver = { + .driver = { + .name = "max8925-backlight", + .owner = THIS_MODULE, + }, + .probe = max8925_backlight_probe, + .remove = __devexit_p(max8925_backlight_remove), +}; + +static int __init max8925_backlight_init(void) +{ + return platform_driver_register(&max8925_backlight_driver); +} +module_init(max8925_backlight_init); + +static void __exit max8925_backlight_exit(void) +{ + platform_driver_unregister(&max8925_backlight_driver); +}; +module_exit(max8925_backlight_exit); + +MODULE_DESCRIPTION("Backlight Driver for Maxim MAX8925"); +MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:max8925-backlight"); diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c index 2e78b0784bd..1b5d3fe6bbb 100644 --- a/drivers/video/backlight/mbp_nvidia_bl.c +++ b/drivers/video/backlight/mbp_nvidia_bl.c @@ -139,6 +139,51 @@ static int mbp_dmi_match(const struct dmi_system_id *id) static const struct dmi_system_id __initdata mbp_device_table[] = { { .callback = mbp_dmi_match, + .ident = "MacBook 1,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBook 2,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBook 3,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook3,1"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBook 4,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,1"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBook 4,2", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,2"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, .ident = "MacBookPro 3,1", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), @@ -250,6 +295,7 @@ static const struct dmi_system_id __initdata mbp_device_table[] = { static int __init mbp_init(void) { + struct backlight_properties props; if (!dmi_check_system(mbp_device_table)) return -ENODEV; @@ -257,14 +303,17 @@ static int __init mbp_init(void) "Macbook Pro backlight")) return -ENXIO; - mbp_backlight_device = backlight_device_register("mbp_backlight", - NULL, NULL, &driver_data->backlight_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 15; + mbp_backlight_device = backlight_device_register("mbp_backlight", NULL, + NULL, + &driver_data->backlight_ops, + &props); if (IS_ERR(mbp_backlight_device)) { release_region(driver_data->iostart, driver_data->iolen); return PTR_ERR(mbp_backlight_device); } - mbp_backlight_device->props.max_brightness = 15; mbp_backlight_device->props.brightness = driver_data->backlight_ops.get_brightness(mbp_backlight_device); backlight_update_status(mbp_backlight_device); diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c index a3a7f893817..d3bc56296c8 100644 --- a/drivers/video/backlight/omap1_bl.c +++ b/drivers/video/backlight/omap1_bl.c @@ -24,6 +24,7 @@ #include <linux/platform_device.h> #include <linux/fb.h> #include <linux/backlight.h> +#include <linux/slab.h> #include <mach/hardware.h> #include <plat/board.h> @@ -132,6 +133,7 @@ static const struct backlight_ops omapbl_ops = { static int omapbl_probe(struct platform_device *pdev) { + struct backlight_properties props; struct backlight_device *dev; struct omap_backlight *bl; struct omap_backlight_config *pdata = pdev->dev.platform_data; @@ -143,7 +145,10 @@ static int omapbl_probe(struct platform_device *pdev) if (unlikely(!bl)) return -ENOMEM; - dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = OMAPBL_MAX_INTENSITY; + dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops, + &props); if (IS_ERR(dev)) { kfree(bl); return PTR_ERR(dev); @@ -160,7 +165,6 @@ static int omapbl_probe(struct platform_device *pdev) omap_cfg_reg(PWL); /* Conflicts with UART3 */ dev->props.fb_blank = FB_BLANK_UNBLANK; - dev->props.max_brightness = OMAPBL_MAX_INTENSITY; dev->props.brightness = pdata->default_intensity; omapbl_update_status(dev); diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c index 738694d2388..302330acf62 100644 --- a/drivers/video/backlight/platform_lcd.c +++ b/drivers/video/backlight/platform_lcd.c @@ -16,6 +16,7 @@ #include <linux/fb.h> #include <linux/backlight.h> #include <linux/lcd.h> +#include <linux/slab.h> #include <video/platform_lcd.h> diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c index 075786e0503..809278c9073 100644 --- a/drivers/video/backlight/progear_bl.c +++ b/drivers/video/backlight/progear_bl.c @@ -61,8 +61,10 @@ static const struct backlight_ops progearbl_ops = { static int progearbl_probe(struct platform_device *pdev) { + struct backlight_properties props; u8 temp; struct backlight_device *progear_backlight_device; + int ret; pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL); if (!pmu_dev) { @@ -73,28 +75,37 @@ static int progearbl_probe(struct platform_device *pdev) sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); if (!sb_dev) { printk("ALI 1533 SB not found.\n"); - pci_dev_put(pmu_dev); - return -ENODEV; + ret = -ENODEV; + goto put_pmu; } /* Set SB_MPS1 to enable brightness control. */ pci_read_config_byte(sb_dev, SB_MPS1, &temp); pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; progear_backlight_device = backlight_device_register("progear-bl", &pdev->dev, NULL, - &progearbl_ops); - if (IS_ERR(progear_backlight_device)) - return PTR_ERR(progear_backlight_device); + &progearbl_ops, + &props); + if (IS_ERR(progear_backlight_device)) { + ret = PTR_ERR(progear_backlight_device); + goto put_sb; + } platform_set_drvdata(pdev, progear_backlight_device); progear_backlight_device->props.power = FB_BLANK_UNBLANK; progear_backlight_device->props.brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; - progear_backlight_device->props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; progearbl_set_intensity(progear_backlight_device); return 0; +put_sb: + pci_dev_put(sb_dev); +put_pmu: + pci_dev_put(pmu_dev); + return ret; } static int progearbl_remove(struct platform_device *pdev) diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 9d2ec2a1cce..55044351889 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -19,6 +19,7 @@ #include <linux/err.h> #include <linux/pwm.h> #include <linux/pwm_backlight.h> +#include <linux/slab.h> struct pwm_bl_data { struct pwm_device *pwm; @@ -65,6 +66,7 @@ static const struct backlight_ops pwm_backlight_ops = { static int pwm_backlight_probe(struct platform_device *pdev) { + struct backlight_properties props; struct platform_pwm_backlight_data *data = pdev->dev.platform_data; struct backlight_device *bl; struct pwm_bl_data *pb; @@ -100,15 +102,16 @@ static int pwm_backlight_probe(struct platform_device *pdev) } else dev_dbg(&pdev->dev, "got pwm for backlight\n"); - bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, - pb, &pwm_backlight_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = data->max_brightness; + bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb, + &pwm_backlight_ops, &props); if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); ret = PTR_ERR(bl); goto err_bl; } - bl->props.max_brightness = data->max_brightness; bl->props.brightness = data->dft_brightness; backlight_update_status(bl); diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c index 4a3d46e0801..1997e12a105 100644 --- a/drivers/video/backlight/tdo24m.c +++ b/drivers/video/backlight/tdo24m.c @@ -17,6 +17,7 @@ #include <linux/spi/tdo24m.h> #include <linux/fb.h> #include <linux/lcd.h> +#include <linux/slab.h> #define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c index e14ce4d469f..e03e60bbfd8 100644 --- a/drivers/video/backlight/tosa_bl.c +++ b/drivers/video/backlight/tosa_bl.c @@ -18,6 +18,7 @@ #include <linux/gpio.h> #include <linux/fb.h> #include <linux/backlight.h> +#include <linux/slab.h> #include <asm/mach/sharpsl_param.h> @@ -80,6 +81,7 @@ static const struct backlight_ops bl_ops = { static int __devinit tosa_bl_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct backlight_properties props; struct tosa_bl_data *data = kzalloc(sizeof(struct tosa_bl_data), GFP_KERNEL); int ret = 0; if (!data) @@ -99,15 +101,16 @@ static int __devinit tosa_bl_probe(struct i2c_client *client, i2c_set_clientdata(client, data); data->i2c = client; - data->bl = backlight_device_register("tosa-bl", &client->dev, - data, &bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 512 - 1; + data->bl = backlight_device_register("tosa-bl", &client->dev, data, + &bl_ops, &props); if (IS_ERR(data->bl)) { ret = PTR_ERR(data->bl); goto err_reg; } data->bl->props.brightness = 69; - data->bl->props.max_brightness = 512 - 1; data->bl->props.power = FB_BLANK_UNBLANK; backlight_update_status(data->bl); diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c index fa32b94a454..772f6015219 100644 --- a/drivers/video/backlight/tosa_lcd.c +++ b/drivers/video/backlight/tosa_lcd.c @@ -15,6 +15,7 @@ #include <linux/device.h> #include <linux/spi/spi.h> #include <linux/i2c.h> +#include <linux/slab.h> #include <linux/gpio.h> #include <linux/delay.h> #include <linux/lcd.h> diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c index e32add37a20..08fd87f3aec 100644 --- a/drivers/video/backlight/wm831x_bl.c +++ b/drivers/video/backlight/wm831x_bl.c @@ -13,6 +13,7 @@ #include <linux/platform_device.h> #include <linux/fb.h> #include <linux/backlight.h> +#include <linux/slab.h> #include <linux/mfd/wm831x/core.h> #include <linux/mfd/wm831x/pdata.h> @@ -125,6 +126,7 @@ static int wm831x_backlight_probe(struct platform_device *pdev) struct wm831x_backlight_pdata *pdata; struct wm831x_backlight_data *data; struct backlight_device *bl; + struct backlight_properties props; int ret, i, max_isel, isink_reg, dcdc_cfg; /* We need platform data */ @@ -191,15 +193,15 @@ static int wm831x_backlight_probe(struct platform_device *pdev) data->current_brightness = 0; data->isink_reg = isink_reg; - bl = backlight_device_register("wm831x", &pdev->dev, - data, &wm831x_backlight_ops); + props.max_brightness = max_isel; + bl = backlight_device_register("wm831x", &pdev->dev, data, + &wm831x_backlight_ops, &props); if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); kfree(data); return PTR_ERR(bl); } - bl->props.max_brightness = max_isel; bl->props.brightness = max_isel; platform_set_drvdata(pdev, bl); |