summaryrefslogtreecommitdiffstats
path: root/drivers/video/backlight
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/backlight')
-rw-r--r--drivers/video/backlight/88pm860x_bl.c57
-rw-r--r--drivers/video/backlight/Kconfig27
-rw-r--r--drivers/video/backlight/Makefile5
-rw-r--r--drivers/video/backlight/aat2870_bl.c9
-rw-r--r--drivers/video/backlight/adp5520_bl.c6
-rw-r--r--drivers/video/backlight/adp8860_bl.c12
-rw-r--r--drivers/video/backlight/adp8870_bl.c12
-rw-r--r--drivers/video/backlight/ams369fg06.c13
-rw-r--r--drivers/video/backlight/apple_bl.c23
-rw-r--r--drivers/video/backlight/corgi_lcd.c12
-rw-r--r--drivers/video/backlight/cr_bllcd.c3
-rw-r--r--drivers/video/backlight/da903x_bl.c6
-rw-r--r--drivers/video/backlight/da9052_bl.c187
-rw-r--r--drivers/video/backlight/ep93xx_bl.c25
-rw-r--r--drivers/video/backlight/l4f00242t03.c13
-rw-r--r--drivers/video/backlight/ld9040.c13
-rw-r--r--drivers/video/backlight/lms283gf05.c13
-rw-r--r--drivers/video/backlight/locomolcd.c9
-rw-r--r--drivers/video/backlight/lp855x_bl.c331
-rw-r--r--drivers/video/backlight/ltv350qv.c12
-rw-r--r--drivers/video/backlight/max8925_bl.c7
-rw-r--r--drivers/video/backlight/omap1_bl.c9
-rw-r--r--drivers/video/backlight/ot200_bl.c175
-rw-r--r--drivers/video/backlight/pandora_bl.c171
-rw-r--r--drivers/video/backlight/pcf50633-backlight.c16
-rw-r--r--drivers/video/backlight/platform_lcd.c19
-rw-r--r--drivers/video/backlight/pwm_bl.c7
-rw-r--r--drivers/video/backlight/s6e63m0.c13
-rw-r--r--drivers/video/backlight/tdo24m.c12
-rw-r--r--drivers/video/backlight/tosa_bl.c13
-rw-r--r--drivers/video/backlight/tosa_lcd.c15
-rw-r--r--drivers/video/backlight/vgg2432a4.c15
-rw-r--r--drivers/video/backlight/wm831x_bl.c6
33 files changed, 1003 insertions, 263 deletions
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index a1376dc73d7..f49181c7311 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -67,6 +67,28 @@ static inline int wled_idc(int port)
return ret;
}
+static int backlight_power_set(struct pm860x_chip *chip, int port,
+ int on)
+{
+ int ret = -EINVAL;
+
+ switch (port) {
+ case PM8606_BACKLIGHT1:
+ ret = on ? pm8606_osc_enable(chip, WLED1_DUTY) :
+ pm8606_osc_disable(chip, WLED1_DUTY);
+ break;
+ case PM8606_BACKLIGHT2:
+ ret = on ? pm8606_osc_enable(chip, WLED2_DUTY) :
+ pm8606_osc_disable(chip, WLED2_DUTY);
+ break;
+ case PM8606_BACKLIGHT3:
+ ret = on ? pm8606_osc_enable(chip, WLED3_DUTY) :
+ pm8606_osc_disable(chip, WLED3_DUTY);
+ break;
+ }
+ return ret;
+}
+
static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
{
struct pm860x_backlight_data *data = bl_get_data(bl);
@@ -79,6 +101,9 @@ static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
else
value = brightness;
+ if (brightness)
+ backlight_power_set(chip, data->port, 1);
+
ret = pm860x_reg_write(data->i2c, wled_a(data->port), value);
if (ret < 0)
goto out;
@@ -115,6 +140,9 @@ static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
if (ret < 0)
goto out;
+ if (brightness == 0)
+ backlight_power_set(chip, data->port, 0);
+
dev_dbg(chip->dev, "set brightness %d\n", value);
data->current_brightness = value;
return 0;
@@ -170,7 +198,6 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
struct backlight_device *bl;
struct resource *res;
struct backlight_properties props;
- unsigned char value;
char name[MFD_NAME_SIZE];
int ret;
@@ -187,7 +214,8 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
return -EINVAL;
}
- data = kzalloc(sizeof(struct pm860x_backlight_data), GFP_KERNEL);
+ data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_backlight_data),
+ GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
strncpy(name, res->name, MFD_NAME_SIZE);
@@ -200,7 +228,6 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
data->port = pdata->flags;
if (data->port < 0) {
dev_err(&pdev->dev, "wrong platform data is assigned");
- kfree(data);
return -EINVAL;
}
@@ -211,33 +238,12 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
&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)
@@ -247,17 +253,14 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
return 0;
out:
backlight_device_unregister(bl);
- 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;
}
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 681b36929fe..af16884491e 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -245,6 +245,12 @@ 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_DA9052
+ tristate "Dialog DA9052/DA9053 WLED"
+ depends on PMIC_DA9052
+ help
+ Enable the Backlight Driver for DA9052-BC and DA9053-AA/Bx PMICs.
+
config BACKLIGHT_MAX8925
tristate "Backlight driver for MAX8925"
depends on MFD_MAX8925
@@ -334,6 +340,27 @@ config BACKLIGHT_AAT2870
If you have a AnalogicTech AAT2870 say Y to enable the
backlight driver.
+config BACKLIGHT_LP855X
+ tristate "Backlight driver for TI LP855X"
+ depends on BACKLIGHT_CLASS_DEVICE && I2C
+ help
+ This supports TI LP8550, LP8551, LP8552, LP8553 and LP8556
+ backlight driver.
+
+config BACKLIGHT_OT200
+ tristate "Backlight driver for ot200 visualisation device"
+ depends on BACKLIGHT_CLASS_DEVICE && CS5535_MFGPT && GPIO_CS5535
+ help
+ To compile this driver as a module, choose M here: the module will be
+ called ot200_bl.
+
+config BACKLIGHT_PANDORA
+ tristate "Backlight driver for Pandora console"
+ depends on TWL4030_CORE
+ help
+ If you have a Pandora console, say Y to enable the
+ backlight driver.
+
endif # BACKLIGHT_CLASS_DEVICE
endif # BACKLIGHT_LCD_SUPPORT
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index af5cf654ec7..36855ae887d 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -22,11 +22,14 @@ obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o
obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
+obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
+obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o
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_DA9052) += da9052_bl.o
obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o
obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o
obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
@@ -38,4 +41,4 @@ obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o
obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o
obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o
-
+obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o
diff --git a/drivers/video/backlight/aat2870_bl.c b/drivers/video/backlight/aat2870_bl.c
index 331f1ef1dad..7ff752288b9 100644
--- a/drivers/video/backlight/aat2870_bl.c
+++ b/drivers/video/backlight/aat2870_bl.c
@@ -145,7 +145,9 @@ static int aat2870_bl_probe(struct platform_device *pdev)
goto out;
}
- aat2870_bl = kzalloc(sizeof(struct aat2870_bl_driver_data), GFP_KERNEL);
+ aat2870_bl = devm_kzalloc(&pdev->dev,
+ sizeof(struct aat2870_bl_driver_data),
+ GFP_KERNEL);
if (!aat2870_bl) {
dev_err(&pdev->dev,
"Failed to allocate memory for aat2870 backlight\n");
@@ -162,7 +164,7 @@ static int aat2870_bl_probe(struct platform_device *pdev)
dev_err(&pdev->dev,
"Failed allocate memory for backlight device\n");
ret = PTR_ERR(bd);
- goto out_kfree;
+ goto out;
}
aat2870_bl->pdev = pdev;
@@ -199,8 +201,6 @@ static int aat2870_bl_probe(struct platform_device *pdev)
out_bl_dev_unregister:
backlight_device_unregister(bd);
-out_kfree:
- kfree(aat2870_bl);
out:
return ret;
}
@@ -215,7 +215,6 @@ static int aat2870_bl_remove(struct platform_device *pdev)
backlight_update_status(bd);
backlight_device_unregister(bd);
- kfree(aat2870_bl);
return 0;
}
diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c
index 2e630bf1164..4911ea7989c 100644
--- a/drivers/video/backlight/adp5520_bl.c
+++ b/drivers/video/backlight/adp5520_bl.c
@@ -289,7 +289,7 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
struct adp5520_bl *data;
int ret = 0;
- data = kzalloc(sizeof(*data), GFP_KERNEL);
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
@@ -298,7 +298,6 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
if (data->pdata == NULL) {
dev_err(&pdev->dev, "missing platform data\n");
- kfree(data);
return -ENODEV;
}
@@ -314,7 +313,6 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
&adp5520_bl_ops, &props);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
- kfree(data);
return PTR_ERR(bl);
}
@@ -326,7 +324,6 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
if (ret) {
dev_err(&pdev->dev, "failed to register sysfs\n");
backlight_device_unregister(bl);
- kfree(data);
}
platform_set_drvdata(pdev, bl);
@@ -348,7 +345,6 @@ static int __devexit adp5520_bl_remove(struct platform_device *pdev)
&adp5520_bl_attr_group);
backlight_device_unregister(bl);
- kfree(data);
return 0;
}
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
index 378276c9d3c..550dbf0bb89 100644
--- a/drivers/video/backlight/adp8860_bl.c
+++ b/drivers/video/backlight/adp8860_bl.c
@@ -819,17 +819,7 @@ static struct i2c_driver adp8860_driver = {
.id_table = adp8860_id,
};
-static int __init adp8860_init(void)
-{
- return i2c_add_driver(&adp8860_driver);
-}
-module_init(adp8860_init);
-
-static void __exit adp8860_exit(void)
-{
- i2c_del_driver(&adp8860_driver);
-}
-module_exit(adp8860_exit);
+module_i2c_driver(adp8860_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c
index 6735059376d..9be58c6f18f 100644
--- a/drivers/video/backlight/adp8870_bl.c
+++ b/drivers/video/backlight/adp8870_bl.c
@@ -991,17 +991,7 @@ static struct i2c_driver adp8870_driver = {
.id_table = adp8870_id,
};
-static int __init adp8870_init(void)
-{
- return i2c_add_driver(&adp8870_driver);
-}
-module_init(adp8870_init);
-
-static void __exit adp8870_exit(void)
-{
- i2c_del_driver(&adp8870_driver);
-}
-module_exit(adp8870_exit);
+module_i2c_driver(adp8870_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
diff --git a/drivers/video/backlight/ams369fg06.c b/drivers/video/backlight/ams369fg06.c
index 7838a23fbdd..7bdadc79011 100644
--- a/drivers/video/backlight/ams369fg06.c
+++ b/drivers/video/backlight/ams369fg06.c
@@ -629,18 +629,7 @@ static struct spi_driver ams369fg06_driver = {
.resume = ams369fg06_resume,
};
-static int __init ams369fg06_init(void)
-{
- return spi_register_driver(&ams369fg06_driver);
-}
-
-static void __exit ams369fg06_exit(void)
-{
- spi_unregister_driver(&ams369fg06_driver);
-}
-
-module_init(ams369fg06_init);
-module_exit(ams369fg06_exit);
+module_spi_driver(ams369fg06_driver);
MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
MODULE_DESCRIPTION("ams369fg06 LCD Driver");
diff --git a/drivers/video/backlight/apple_bl.c b/drivers/video/backlight/apple_bl.c
index be98d152b7f..a523b255e12 100644
--- a/drivers/video/backlight/apple_bl.c
+++ b/drivers/video/backlight/apple_bl.c
@@ -24,6 +24,7 @@
#include <linux/io.h>
#include <linux/pci.h>
#include <linux/acpi.h>
+#include <linux/atomic.h>
static struct backlight_device *apple_backlight_device;
@@ -221,14 +222,32 @@ static struct acpi_driver apple_bl_driver = {
},
};
+static atomic_t apple_bl_registered = ATOMIC_INIT(0);
+
+int apple_bl_register(void)
+{
+ if (atomic_xchg(&apple_bl_registered, 1) == 0)
+ return acpi_bus_register_driver(&apple_bl_driver);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(apple_bl_register);
+
+void apple_bl_unregister(void)
+{
+ if (atomic_xchg(&apple_bl_registered, 0) == 1)
+ acpi_bus_unregister_driver(&apple_bl_driver);
+}
+EXPORT_SYMBOL_GPL(apple_bl_unregister);
+
static int __init apple_bl_init(void)
{
- return acpi_bus_register_driver(&apple_bl_driver);
+ return apple_bl_register();
}
static void __exit apple_bl_exit(void)
{
- acpi_bus_unregister_driver(&apple_bl_driver);
+ apple_bl_unregister();
}
module_init(apple_bl_init);
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c
index c6533bad26f..6dab13fe562 100644
--- a/drivers/video/backlight/corgi_lcd.c
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -629,17 +629,7 @@ static struct spi_driver corgi_lcd_driver = {
.resume = corgi_lcd_resume,
};
-static int __init corgi_lcd_init(void)
-{
- return spi_register_driver(&corgi_lcd_driver);
-}
-module_init(corgi_lcd_init);
-
-static void __exit corgi_lcd_exit(void)
-{
- spi_unregister_driver(&corgi_lcd_driver);
-}
-module_exit(corgi_lcd_exit);
+module_spi_driver(corgi_lcd_driver);
MODULE_DESCRIPTION("LCD and backlight driver for SHARP C7x0/Cxx00");
MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c
index 6c8c54041fa..22489eb5f3e 100644
--- a/drivers/video/backlight/cr_bllcd.c
+++ b/drivers/video/backlight/cr_bllcd.c
@@ -212,7 +212,7 @@ static int cr_backlight_probe(struct platform_device *pdev)
&gpio_bar);
gpio_bar &= ~0x3F;
- crp = kzalloc(sizeof(*crp), GFP_KERNEL);
+ crp = devm_kzalloc(&pdev->dev, sizeof(*crp), GFP_KERNEL);
if (!crp) {
lcd_device_unregister(ldp);
backlight_device_unregister(bdp);
@@ -243,7 +243,6 @@ static int cr_backlight_remove(struct platform_device *pdev)
backlight_device_unregister(crp->cr_backlight_device);
lcd_device_unregister(crp->cr_lcd_device);
pci_dev_put(lpc_dev);
- kfree(crp);
return 0;
}
diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c
index abb4a06268f..30e19681a30 100644
--- a/drivers/video/backlight/da903x_bl.c
+++ b/drivers/video/backlight/da903x_bl.c
@@ -110,7 +110,7 @@ static int da903x_backlight_probe(struct platform_device *pdev)
struct backlight_properties props;
int max_brightness;
- data = kzalloc(sizeof(*data), GFP_KERNEL);
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
@@ -124,7 +124,6 @@ static int da903x_backlight_probe(struct platform_device *pdev)
default:
dev_err(&pdev->dev, "invalid backlight device ID(%d)\n",
pdev->id);
- kfree(data);
return -EINVAL;
}
@@ -143,7 +142,6 @@ static int da903x_backlight_probe(struct platform_device *pdev)
&da903x_backlight_ops, &props);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
- kfree(data);
return PTR_ERR(bl);
}
@@ -157,10 +155,8 @@ static int da903x_backlight_probe(struct platform_device *pdev)
static int da903x_backlight_remove(struct platform_device *pdev)
{
struct backlight_device *bl = platform_get_drvdata(pdev);
- struct da903x_backlight_data *data = bl_get_data(bl);
backlight_device_unregister(bl);
- kfree(data);
return 0;
}
diff --git a/drivers/video/backlight/da9052_bl.c b/drivers/video/backlight/da9052_bl.c
new file mode 100644
index 00000000000..b628d68f516
--- /dev/null
+++ b/drivers/video/backlight/da9052_bl.c
@@ -0,0 +1,187 @@
+/*
+ * Backlight Driver for Dialog DA9052 PMICs
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/reg.h>
+
+#define DA9052_MAX_BRIGHTNESS 0xFF
+
+enum {
+ DA9052_WLEDS_OFF,
+ DA9052_WLEDS_ON,
+};
+
+enum {
+ DA9052_TYPE_WLED1,
+ DA9052_TYPE_WLED2,
+ DA9052_TYPE_WLED3,
+};
+
+static unsigned char wled_bank[] = {
+ DA9052_LED1_CONF_REG,
+ DA9052_LED2_CONF_REG,
+ DA9052_LED3_CONF_REG,
+};
+
+struct da9052_bl {
+ struct da9052 *da9052;
+ uint brightness;
+ uint state;
+ uint led_reg;
+};
+
+static int da9052_adjust_wled_brightness(struct da9052_bl *wleds)
+{
+ unsigned char boost_en;
+ unsigned char i_sink;
+ int ret;
+
+ boost_en = 0x3F;
+ i_sink = 0xFF;
+ if (wleds->state == DA9052_WLEDS_OFF) {
+ boost_en = 0x00;
+ i_sink = 0x00;
+ }
+
+ ret = da9052_reg_write(wleds->da9052, DA9052_BOOST_REG, boost_en);
+ if (ret < 0)
+ return ret;
+
+ ret = da9052_reg_write(wleds->da9052, DA9052_LED_CONT_REG, i_sink);
+ if (ret < 0)
+ return ret;
+
+ ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg], 0x0);
+ if (ret < 0)
+ return ret;
+
+ msleep(10);
+
+ if (wleds->brightness) {
+ ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg],
+ wleds->brightness);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int da9052_backlight_update_status(struct backlight_device *bl)
+{
+ int brightness = bl->props.brightness;
+ struct da9052_bl *wleds = bl_get_data(bl);
+
+ wleds->brightness = brightness;
+ wleds->state = DA9052_WLEDS_ON;
+
+ return da9052_adjust_wled_brightness(wleds);
+}
+
+static int da9052_backlight_get_brightness(struct backlight_device *bl)
+{
+ struct da9052_bl *wleds = bl_get_data(bl);
+
+ return wleds->brightness;
+}
+
+static const struct backlight_ops da9052_backlight_ops = {
+ .update_status = da9052_backlight_update_status,
+ .get_brightness = da9052_backlight_get_brightness,
+};
+
+static int da9052_backlight_probe(struct platform_device *pdev)
+{
+ struct backlight_device *bl;
+ struct backlight_properties props;
+ struct da9052_bl *wleds;
+
+ wleds = devm_kzalloc(&pdev->dev, sizeof(struct da9052_bl), GFP_KERNEL);
+ if (!wleds)
+ return -ENOMEM;
+
+ wleds->da9052 = dev_get_drvdata(pdev->dev.parent);
+ wleds->brightness = 0;
+ wleds->led_reg = platform_get_device_id(pdev)->driver_data;
+ wleds->state = DA9052_WLEDS_OFF;
+
+ props.type = BACKLIGHT_RAW;
+ props.max_brightness = DA9052_MAX_BRIGHTNESS;
+
+ bl = backlight_device_register(pdev->name, wleds->da9052->dev, wleds,
+ &da9052_backlight_ops, &props);
+ if (IS_ERR(bl)) {
+ dev_err(&pdev->dev, "Failed to register backlight\n");
+ devm_kfree(&pdev->dev, wleds);
+ return PTR_ERR(bl);
+ }
+
+ bl->props.max_brightness = DA9052_MAX_BRIGHTNESS;
+ bl->props.brightness = 0;
+ platform_set_drvdata(pdev, bl);
+
+ return da9052_adjust_wled_brightness(wleds);
+}
+
+static int da9052_backlight_remove(struct platform_device *pdev)
+{
+ struct backlight_device *bl = platform_get_drvdata(pdev);
+ struct da9052_bl *wleds = bl_get_data(bl);
+
+ wleds->brightness = 0;
+ wleds->state = DA9052_WLEDS_OFF;
+ da9052_adjust_wled_brightness(wleds);
+ backlight_device_unregister(bl);
+ devm_kfree(&pdev->dev, wleds);
+
+ return 0;
+}
+
+static struct platform_device_id da9052_wled_ids[] = {
+ {
+ .name = "da9052-wled1",
+ .driver_data = DA9052_TYPE_WLED1,
+ },
+ {
+ .name = "da9052-wled2",
+ .driver_data = DA9052_TYPE_WLED2,
+ },
+ {
+ .name = "da9052-wled3",
+ .driver_data = DA9052_TYPE_WLED3,
+ },
+};
+
+static struct platform_driver da9052_wled_driver = {
+ .probe = da9052_backlight_probe,
+ .remove = da9052_backlight_remove,
+ .id_table = da9052_wled_ids,
+ .driver = {
+ .name = "da9052-wled",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(da9052_wled_driver);
+
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_DESCRIPTION("Backlight driver for DA9052 PMIC");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da9052-backlight");
diff --git a/drivers/video/backlight/ep93xx_bl.c b/drivers/video/backlight/ep93xx_bl.c
index b62b8b9063b..08214e1f095 100644
--- a/drivers/video/backlight/ep93xx_bl.c
+++ b/drivers/video/backlight/ep93xx_bl.c
@@ -17,11 +17,6 @@
#include <linux/fb.h>
#include <linux/backlight.h>
-#include <mach/hardware.h>
-
-#define EP93XX_RASTER_REG(x) (EP93XX_RASTER_BASE + (x))
-#define EP93XX_RASTER_BRIGHTNESS EP93XX_RASTER_REG(0x20)
-
#define EP93XX_MAX_COUNT 255
#define EP93XX_MAX_BRIGHT 255
#define EP93XX_DEF_BRIGHT 128
@@ -35,7 +30,7 @@ static int ep93xxbl_set(struct backlight_device *bl, int brightness)
{
struct ep93xxbl *ep93xxbl = bl_get_data(bl);
- __raw_writel((brightness << 8) | EP93XX_MAX_COUNT, ep93xxbl->mmio);
+ writel((brightness << 8) | EP93XX_MAX_COUNT, ep93xxbl->mmio);
ep93xxbl->brightness = brightness;
@@ -70,21 +65,29 @@ static int __init ep93xxbl_probe(struct platform_device *dev)
struct ep93xxbl *ep93xxbl;
struct backlight_device *bl;
struct backlight_properties props;
+ struct resource *res;
ep93xxbl = devm_kzalloc(&dev->dev, sizeof(*ep93xxbl), GFP_KERNEL);
if (!ep93xxbl)
return -ENOMEM;
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENXIO;
+
/*
- * This register is located in the range already ioremap'ed by
- * the framebuffer driver. A MFD driver seems a bit of overkill
- * to handle this so use the static I/O mapping; this address
- * is already virtual.
+ * FIXME - We don't do a request_mem_region here because we are
+ * sharing the register space with the framebuffer driver (see
+ * drivers/video/ep93xx-fb.c) and doing so will cause the second
+ * loaded driver to return -EBUSY.
*
* NOTE: No locking is required; the framebuffer does not touch
* this register.
*/
- ep93xxbl->mmio = EP93XX_RASTER_BRIGHTNESS;
+ ep93xxbl->mmio = devm_ioremap(&dev->dev, res->start,
+ resource_size(res));
+ if (!ep93xxbl->mmio)
+ return -ENXIO;
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_RAW;
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c
index 27d1d7a29c7..6022b67285e 100644
--- a/drivers/video/backlight/l4f00242t03.c
+++ b/drivers/video/backlight/l4f00242t03.c
@@ -274,18 +274,7 @@ static struct spi_driver l4f00242t03_driver = {
.shutdown = l4f00242t03_shutdown,
};
-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_spi_driver(l4f00242t03_driver);
MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>");
MODULE_DESCRIPTION("EPSON L4F00242T03 LCD");
diff --git a/drivers/video/backlight/ld9040.c b/drivers/video/backlight/ld9040.c
index 78dafc0c8fc..efd352be21a 100644
--- a/drivers/video/backlight/ld9040.c
+++ b/drivers/video/backlight/ld9040.c
@@ -856,18 +856,7 @@ static struct spi_driver ld9040_driver = {
.resume = ld9040_resume,
};
-static int __init ld9040_init(void)
-{
- return spi_register_driver(&ld9040_driver);
-}
-
-static void __exit ld9040_exit(void)
-{
- spi_unregister_driver(&ld9040_driver);
-}
-
-module_init(ld9040_init);
-module_exit(ld9040_exit);
+module_spi_driver(ld9040_driver);
MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
MODULE_DESCRIPTION("ld9040 LCD Driver");
diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c
index 4ec78cfe26e..4161f9e3982 100644
--- a/drivers/video/backlight/lms283gf05.c
+++ b/drivers/video/backlight/lms283gf05.c
@@ -226,18 +226,7 @@ static struct spi_driver lms283gf05_driver = {
.remove = __devexit_p(lms283gf05_remove),
};
-static __init int lms283gf05_init(void)
-{
- return spi_register_driver(&lms283gf05_driver);
-}
-
-static __exit void lms283gf05_exit(void)
-{
- spi_unregister_driver(&lms283gf05_driver);
-}
-
-module_init(lms283gf05_init);
-module_exit(lms283gf05_exit);
+module_spi_driver(lms283gf05_driver);
MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
MODULE_DESCRIPTION("LCD283GF05 LCD");
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index be20b5cbe26..3a6d5419e3e 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -229,14 +229,7 @@ static struct locomo_driver poodle_lcd_driver = {
static int __init locomolcd_init(void)
{
- int ret = locomo_driver_register(&poodle_lcd_driver);
- if (ret)
- return ret;
-
-#ifdef CONFIG_SA1100_COLLIE
- sa1100fb_lcd_power = locomolcd_power;
-#endif
- return 0;
+ return locomo_driver_register(&poodle_lcd_driver);
}
static void __exit locomolcd_exit(void)
diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c
new file mode 100644
index 00000000000..72a0e0c917c
--- /dev/null
+++ b/drivers/video/backlight/lp855x_bl.c
@@ -0,0 +1,331 @@
+/*
+ * TI LP855x Backlight Driver
+ *
+ * Copyright (C) 2011 Texas Instruments
+ *
+ * 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/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/lp855x.h>
+
+/* Registers */
+#define BRIGHTNESS_CTRL (0x00)
+#define DEVICE_CTRL (0x01)
+
+#define BUF_SIZE 20
+#define DEFAULT_BL_NAME "lcd-backlight"
+#define MAX_BRIGHTNESS 255
+
+struct lp855x {
+ const char *chipname;
+ enum lp855x_chip_id chip_id;
+ struct i2c_client *client;
+ struct backlight_device *bl;
+ struct device *dev;
+ struct mutex xfer_lock;
+ struct lp855x_platform_data *pdata;
+};
+
+static int lp855x_read_byte(struct lp855x *lp, u8 reg, u8 *data)
+{
+ int ret;
+
+ mutex_lock(&lp->xfer_lock);
+ ret = i2c_smbus_read_byte_data(lp->client, reg);
+ if (ret < 0) {
+ mutex_unlock(&lp->xfer_lock);
+ dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
+ return ret;
+ }
+ mutex_unlock(&lp->xfer_lock);
+
+ *data = (u8)ret;
+ return 0;
+}
+
+static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data)
+{
+ int ret;
+
+ mutex_lock(&lp->xfer_lock);
+ ret = i2c_smbus_write_byte_data(lp->client, reg, data);
+ mutex_unlock(&lp->xfer_lock);
+
+ return ret;
+}
+
+static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
+{
+ u8 start, end;
+
+ switch (lp->chip_id) {
+ case LP8550:
+ case LP8551:
+ case LP8552:
+ case LP8553:
+ start = EEPROM_START;
+ end = EEPROM_END;
+ break;
+ case LP8556:
+ start = EPROM_START;
+ end = EPROM_END;
+ break;
+ default:
+ return false;
+ }
+
+ return (addr >= start && addr <= end);
+}
+
+static int lp855x_init_registers(struct lp855x *lp)
+{
+ u8 val, addr;
+ int i, ret;
+ struct lp855x_platform_data *pd = lp->pdata;
+
+ val = pd->initial_brightness;
+ ret = lp855x_write_byte(lp, BRIGHTNESS_CTRL, val);
+ if (ret)
+ return ret;
+
+ val = pd->device_control;
+ ret = lp855x_write_byte(lp, DEVICE_CTRL, val);
+ if (ret)
+ return ret;
+
+ if (pd->load_new_rom_data && pd->size_program) {
+ for (i = 0; i < pd->size_program; i++) {
+ addr = pd->rom_data[i].addr;
+ val = pd->rom_data[i].val;
+ if (!lp855x_is_valid_rom_area(lp, addr))
+ continue;
+
+ ret = lp855x_write_byte(lp, addr, val);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static int lp855x_bl_update_status(struct backlight_device *bl)
+{
+ struct lp855x *lp = bl_get_data(bl);
+ enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
+
+ if (bl->props.state & BL_CORE_SUSPENDED)
+ bl->props.brightness = 0;
+
+ if (mode == PWM_BASED) {
+ struct lp855x_pwm_data *pd = &lp->pdata->pwm_data;
+ int br = bl->props.brightness;
+ int max_br = bl->props.max_brightness;
+
+ if (pd->pwm_set_intensity)
+ pd->pwm_set_intensity(br, max_br);
+
+ } else if (mode == REGISTER_BASED) {
+ u8 val = bl->props.brightness;
+ lp855x_write_byte(lp, BRIGHTNESS_CTRL, val);
+ }
+
+ return 0;
+}
+
+static int lp855x_bl_get_brightness(struct backlight_device *bl)
+{
+ struct lp855x *lp = bl_get_data(bl);
+ enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
+
+ if (mode == PWM_BASED) {
+ struct lp855x_pwm_data *pd = &lp->pdata->pwm_data;
+ int max_br = bl->props.max_brightness;
+
+ if (pd->pwm_get_intensity)
+ bl->props.brightness = pd->pwm_get_intensity(max_br);
+
+ } else if (mode == REGISTER_BASED) {
+ u8 val = 0;
+
+ lp855x_read_byte(lp, BRIGHTNESS_CTRL, &val);
+ bl->props.brightness = val;
+ }
+
+ return bl->props.brightness;
+}
+
+static const struct backlight_ops lp855x_bl_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = lp855x_bl_update_status,
+ .get_brightness = lp855x_bl_get_brightness,
+};
+
+static int lp855x_backlight_register(struct lp855x *lp)
+{
+ struct backlight_device *bl;
+ struct backlight_properties props;
+ struct lp855x_platform_data *pdata = lp->pdata;
+ char *name = pdata->name ? : DEFAULT_BL_NAME;
+
+ props.type = BACKLIGHT_PLATFORM;
+ props.max_brightness = MAX_BRIGHTNESS;
+
+ if (pdata->initial_brightness > props.max_brightness)
+ pdata->initial_brightness = props.max_brightness;
+
+ props.brightness = pdata->initial_brightness;
+
+ bl = backlight_device_register(name, lp->dev, lp,
+ &lp855x_bl_ops, &props);
+ if (IS_ERR(bl))
+ return PTR_ERR(bl);
+
+ lp->bl = bl;
+
+ return 0;
+}
+
+static void lp855x_backlight_unregister(struct lp855x *lp)
+{
+ if (lp->bl)
+ backlight_device_unregister(lp->bl);
+}
+
+static ssize_t lp855x_get_chip_id(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp855x *lp = dev_get_drvdata(dev);
+ return scnprintf(buf, BUF_SIZE, "%s\n", lp->chipname);
+}
+
+static ssize_t lp855x_get_bl_ctl_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp855x *lp = dev_get_drvdata(dev);
+ enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
+ char *strmode = NULL;
+
+ if (mode == PWM_BASED)
+ strmode = "pwm based";
+ else if (mode == REGISTER_BASED)
+ strmode = "register based";
+
+ return scnprintf(buf, BUF_SIZE, "%s\n", strmode);
+}
+
+static DEVICE_ATTR(chip_id, S_IRUGO, lp855x_get_chip_id, NULL);
+static DEVICE_ATTR(bl_ctl_mode, S_IRUGO, lp855x_get_bl_ctl_mode, NULL);
+
+static struct attribute *lp855x_attributes[] = {
+ &dev_attr_chip_id.attr,
+ &dev_attr_bl_ctl_mode.attr,
+ NULL,
+};
+
+static const struct attribute_group lp855x_attr_group = {
+ .attrs = lp855x_attributes,
+};
+
+static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+{
+ struct lp855x *lp;
+ struct lp855x_platform_data *pdata = cl->dev.platform_data;
+ enum lp855x_brightness_ctrl_mode mode;
+ int ret;
+
+ if (!pdata) {
+ dev_err(&cl->dev, "no platform data supplied\n");
+ return -EINVAL;
+ }
+
+ if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
+ return -EIO;
+
+ lp = devm_kzalloc(&cl->dev, sizeof(struct lp855x), GFP_KERNEL);
+ if (!lp)
+ return -ENOMEM;
+
+ mode = pdata->mode;
+ lp->client = cl;
+ lp->dev = &cl->dev;
+ lp->pdata = pdata;
+ lp->chipname = id->name;
+ lp->chip_id = id->driver_data;
+ i2c_set_clientdata(cl, lp);
+
+ mutex_init(&lp->xfer_lock);
+
+ ret = lp855x_init_registers(lp);
+ if (ret) {
+ dev_err(lp->dev, "i2c communication err: %d", ret);
+ if (mode == REGISTER_BASED)
+ goto err_dev;
+ }
+
+ ret = lp855x_backlight_register(lp);
+ if (ret) {
+ dev_err(lp->dev,
+ "failed to register backlight. err: %d\n", ret);
+ goto err_dev;
+ }
+
+ ret = sysfs_create_group(&lp->dev->kobj, &lp855x_attr_group);
+ if (ret) {
+ dev_err(lp->dev, "failed to register sysfs. err: %d\n", ret);
+ goto err_sysfs;
+ }
+
+ backlight_update_status(lp->bl);
+ return 0;
+
+err_sysfs:
+ lp855x_backlight_unregister(lp);
+err_dev:
+ return ret;
+}
+
+static int __devexit lp855x_remove(struct i2c_client *cl)
+{
+ struct lp855x *lp = i2c_get_clientdata(cl);
+
+ lp->bl->props.brightness = 0;
+ backlight_update_status(lp->bl);
+ sysfs_remove_group(&lp->dev->kobj, &lp855x_attr_group);
+ lp855x_backlight_unregister(lp);
+
+ return 0;
+}
+
+static const struct i2c_device_id lp855x_ids[] = {
+ {"lp8550", LP8550},
+ {"lp8551", LP8551},
+ {"lp8552", LP8552},
+ {"lp8553", LP8553},
+ {"lp8556", LP8556},
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, lp855x_ids);
+
+static struct i2c_driver lp855x_driver = {
+ .driver = {
+ .name = "lp855x",
+ },
+ .probe = lp855x_probe,
+ .remove = __devexit_p(lp855x_remove),
+ .id_table = lp855x_ids,
+};
+
+module_i2c_driver(lp855x_driver);
+
+MODULE_DESCRIPTION("Texas Instruments LP855x Backlight driver");
+MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c
index cca43c06d3c..333949ff326 100644
--- a/drivers/video/backlight/ltv350qv.c
+++ b/drivers/video/backlight/ltv350qv.c
@@ -321,17 +321,7 @@ static struct spi_driver ltv350qv_driver = {
.resume = ltv350qv_resume,
};
-static int __init ltv350qv_init(void)
-{
- return spi_register_driver(&ltv350qv_driver);
-}
-
-static void __exit ltv350qv_exit(void)
-{
- spi_unregister_driver(&ltv350qv_driver);
-}
-module_init(ltv350qv_init);
-module_exit(ltv350qv_exit);
+module_spi_driver(ltv350qv_driver);
MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
MODULE_DESCRIPTION("Samsung LTV350QV LCD Driver");
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
index c915e3b5388..e833ac72e06 100644
--- a/drivers/video/backlight/max8925_bl.c
+++ b/drivers/video/backlight/max8925_bl.c
@@ -129,7 +129,8 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
return -EINVAL;
}
- data = kzalloc(sizeof(struct max8925_backlight_data), GFP_KERNEL);
+ data = devm_kzalloc(&pdev->dev, sizeof(struct max8925_backlight_data),
+ GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
strncpy(name, res->name, MAX8925_NAME_SIZE);
@@ -143,7 +144,6 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
&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;
@@ -165,17 +165,14 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
return 0;
out:
backlight_device_unregister(bl);
- 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;
}
diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c
index d8cde277ec8..0175bfb08a1 100644
--- a/drivers/video/backlight/omap1_bl.c
+++ b/drivers/video/backlight/omap1_bl.c
@@ -141,7 +141,8 @@ static int omapbl_probe(struct platform_device *pdev)
if (!pdata)
return -ENXIO;
- bl = kzalloc(sizeof(struct omap_backlight), GFP_KERNEL);
+ bl = devm_kzalloc(&pdev->dev, sizeof(struct omap_backlight),
+ GFP_KERNEL);
if (unlikely(!bl))
return -ENOMEM;
@@ -150,10 +151,8 @@ static int omapbl_probe(struct platform_device *pdev)
props.max_brightness = OMAPBL_MAX_INTENSITY;
dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops,
&props);
- if (IS_ERR(dev)) {
- kfree(bl);
+ if (IS_ERR(dev))
return PTR_ERR(dev);
- }
bl->powermode = FB_BLANK_POWERDOWN;
bl->current_intensity = 0;
@@ -177,10 +176,8 @@ static int omapbl_probe(struct platform_device *pdev)
static int omapbl_remove(struct platform_device *pdev)
{
struct backlight_device *dev = platform_get_drvdata(pdev);
- struct omap_backlight *bl = dev_get_drvdata(&dev->dev);
backlight_device_unregister(dev);
- kfree(bl);
return 0;
}
diff --git a/drivers/video/backlight/ot200_bl.c b/drivers/video/backlight/ot200_bl.c
new file mode 100644
index 00000000000..f519d55a294
--- /dev/null
+++ b/drivers/video/backlight/ot200_bl.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2012 Bachmann electronic GmbH
+ * Christian Gmeiner <christian.gmeiner@gmail.com>
+ *
+ * Backlight driver for ot200 visualisation device from
+ * Bachmann electronic GmbH.
+ *
+ * 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/module.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/gpio.h>
+#include <linux/cs5535.h>
+
+static struct cs5535_mfgpt_timer *pwm_timer;
+
+/* this array defines the mapping of brightness in % to pwm frequency */
+static const u8 dim_table[101] = {0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
+ 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9,
+ 10, 10, 11, 11, 12, 12, 13, 14, 15, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28,
+ 30, 31, 33, 35, 37, 39, 41, 43, 45, 47, 50,
+ 53, 55, 58, 61, 65, 68, 72, 75, 79, 84, 88,
+ 93, 97, 103, 108, 114, 120, 126, 133, 140,
+ 147, 155, 163};
+
+struct ot200_backlight_data {
+ int current_brightness;
+};
+
+#define GPIO_DIMM 27
+#define SCALE 1
+#define CMP1MODE 0x2 /* compare on GE; output high on compare
+ * greater than or equal */
+#define PWM_SETUP (SCALE | CMP1MODE << 6 | MFGPT_SETUP_CNTEN)
+#define MAX_COMP2 163
+
+static int ot200_backlight_update_status(struct backlight_device *bl)
+{
+ struct ot200_backlight_data *data = bl_get_data(bl);
+ int brightness = bl->props.brightness;
+
+ if (bl->props.state & BL_CORE_FBBLANK)
+ brightness = 0;
+
+ /* enable or disable PWM timer */
+ if (brightness == 0)
+ cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, 0);
+ else if (data->current_brightness == 0) {
+ cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0);
+ cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP,
+ MFGPT_SETUP_CNTEN);
+ }
+
+ /* apply new brightness value */
+ cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1,
+ MAX_COMP2 - dim_table[brightness]);
+ data->current_brightness = brightness;
+
+ return 0;
+}
+
+static int ot200_backlight_get_brightness(struct backlight_device *bl)
+{
+ struct ot200_backlight_data *data = bl_get_data(bl);
+ return data->current_brightness;
+}
+
+static const struct backlight_ops ot200_backlight_ops = {
+ .update_status = ot200_backlight_update_status,
+ .get_brightness = ot200_backlight_get_brightness,
+};
+
+static int ot200_backlight_probe(struct platform_device *pdev)
+{
+ struct backlight_device *bl;
+ struct ot200_backlight_data *data;
+ struct backlight_properties props;
+ int retval = 0;
+
+ /* request gpio */
+ if (gpio_request(GPIO_DIMM, "ot200 backlight dimmer") < 0) {
+ dev_err(&pdev->dev, "failed to request GPIO %d\n", GPIO_DIMM);
+ return -ENODEV;
+ }
+
+ /* request timer */
+ pwm_timer = cs5535_mfgpt_alloc_timer(7, MFGPT_DOMAIN_ANY);
+ if (!pwm_timer) {
+ dev_err(&pdev->dev, "MFGPT 7 not available\n");
+ retval = -ENODEV;
+ goto error_mfgpt_alloc;
+ }
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ retval = -ENOMEM;
+ goto error_kzalloc;
+ }
+
+ /* setup gpio */
+ cs5535_gpio_set(GPIO_DIMM, GPIO_OUTPUT_ENABLE);
+ cs5535_gpio_set(GPIO_DIMM, GPIO_OUTPUT_AUX1);
+
+ /* setup timer */
+ cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1, 0);
+ cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP2, MAX_COMP2);
+ cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, PWM_SETUP);
+
+ data->current_brightness = 100;
+ props.max_brightness = 100;
+ props.brightness = 100;
+ props.type = BACKLIGHT_RAW;
+
+ bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, data,
+ &ot200_backlight_ops, &props);
+ if (IS_ERR(bl)) {
+ dev_err(&pdev->dev, "failed to register backlight\n");
+ retval = PTR_ERR(bl);
+ goto error_backlight_device_register;
+ }
+
+ platform_set_drvdata(pdev, bl);
+
+ return 0;
+
+error_backlight_device_register:
+ kfree(data);
+error_kzalloc:
+ cs5535_mfgpt_free_timer(pwm_timer);
+error_mfgpt_alloc:
+ gpio_free(GPIO_DIMM);
+ return retval;
+}
+
+static int ot200_backlight_remove(struct platform_device *pdev)
+{
+ struct backlight_device *bl = platform_get_drvdata(pdev);
+ struct ot200_backlight_data *data = bl_get_data(bl);
+
+ backlight_device_unregister(bl);
+
+ /* on module unload set brightness to 100% */
+ cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0);
+ cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN);
+ cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1,
+ MAX_COMP2 - dim_table[100]);
+
+ cs5535_mfgpt_free_timer(pwm_timer);
+ gpio_free(GPIO_DIMM);
+
+ kfree(data);
+ return 0;
+}
+
+static struct platform_driver ot200_backlight_driver = {
+ .driver = {
+ .name = "ot200-backlight",
+ .owner = THIS_MODULE,
+ },
+ .probe = ot200_backlight_probe,
+ .remove = ot200_backlight_remove,
+};
+
+module_platform_driver(ot200_backlight_driver);
+
+MODULE_DESCRIPTION("backlight driver for ot200 visualisation device");
+MODULE_AUTHOR("Christian Gmeiner <christian.gmeiner@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ot200-backlight");
diff --git a/drivers/video/backlight/pandora_bl.c b/drivers/video/backlight/pandora_bl.c
new file mode 100644
index 00000000000..4ec30748b44
--- /dev/null
+++ b/drivers/video/backlight/pandora_bl.c
@@ -0,0 +1,171 @@
+/*
+ * Backlight driver for Pandora handheld.
+ * Pandora uses TWL4030 PWM0 -> TPS61161 combo for control backlight.
+ * Based on pwm_bl.c
+ *
+ * Copyright 2009,2012 Gražvydas Ignotas <notasas@gmail.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/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/i2c/twl.h>
+#include <linux/err.h>
+
+#define TWL_PWM0_ON 0x00
+#define TWL_PWM0_OFF 0x01
+
+#define TWL_INTBR_GPBR1 0x0c
+#define TWL_INTBR_PMBR1 0x0d
+
+#define TWL_PMBR1_PWM0_MUXMASK 0x0c
+#define TWL_PMBR1_PWM0 0x04
+#define PWM0_CLK_ENABLE BIT(0)
+#define PWM0_ENABLE BIT(2)
+
+/* range accepted by hardware */
+#define MIN_VALUE 9
+#define MAX_VALUE 63
+#define MAX_USER_VALUE (MAX_VALUE - MIN_VALUE)
+
+#define PANDORABL_WAS_OFF BL_CORE_DRIVER1
+
+static int pandora_backlight_update_status(struct backlight_device *bl)
+{
+ int brightness = bl->props.brightness;
+ u8 r;
+
+ if (bl->props.power != FB_BLANK_UNBLANK)
+ brightness = 0;
+ if (bl->props.state & BL_CORE_FBBLANK)
+ brightness = 0;
+ if (bl->props.state & BL_CORE_SUSPENDED)
+ brightness = 0;
+
+ if ((unsigned int)brightness > MAX_USER_VALUE)
+ brightness = MAX_USER_VALUE;
+
+ if (brightness == 0) {
+ if (bl->props.state & PANDORABL_WAS_OFF)
+ goto done;
+
+ /* first disable PWM0 output, then clock */
+ twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1);
+ r &= ~PWM0_ENABLE;
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+ r &= ~PWM0_CLK_ENABLE;
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+
+ goto done;
+ }
+
+ if (bl->props.state & PANDORABL_WAS_OFF) {
+ /*
+ * set PWM duty cycle to max. TPS61161 seems to use this
+ * to calibrate it's PWM sensitivity when it starts.
+ */
+ twl_i2c_write_u8(TWL4030_MODULE_PWM0, MAX_VALUE,
+ TWL_PWM0_OFF);
+
+ /* first enable clock, then PWM0 out */
+ twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1);
+ r &= ~PWM0_ENABLE;
+ r |= PWM0_CLK_ENABLE;
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+ r |= PWM0_ENABLE;
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+
+ /*
+ * TI made it very easy to enable digital control, so easy that
+ * it often triggers unintentionally and disabes PWM control,
+ * so wait until 1 wire mode detection window ends.
+ */
+ usleep_range(2000, 10000);
+ }
+
+ twl_i2c_write_u8(TWL4030_MODULE_PWM0, MIN_VALUE + brightness,
+ TWL_PWM0_OFF);
+
+done:
+ if (brightness != 0)
+ bl->props.state &= ~PANDORABL_WAS_OFF;
+ else
+ bl->props.state |= PANDORABL_WAS_OFF;
+
+ return 0;
+}
+
+static int pandora_backlight_get_brightness(struct backlight_device *bl)
+{
+ return bl->props.brightness;
+}
+
+static const struct backlight_ops pandora_backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = pandora_backlight_update_status,
+ .get_brightness = pandora_backlight_get_brightness,
+};
+
+static int pandora_backlight_probe(struct platform_device *pdev)
+{
+ struct backlight_properties props;
+ struct backlight_device *bl;
+ u8 r;
+
+ memset(&props, 0, sizeof(props));
+ props.max_brightness = MAX_USER_VALUE;
+ props.type = BACKLIGHT_RAW;
+ bl = backlight_device_register(pdev->name, &pdev->dev,
+ NULL, &pandora_backlight_ops, &props);
+ if (IS_ERR(bl)) {
+ dev_err(&pdev->dev, "failed to register backlight\n");
+ return PTR_ERR(bl);
+ }
+
+ platform_set_drvdata(pdev, bl);
+
+ /* 64 cycle period, ON position 0 */
+ twl_i2c_write_u8(TWL4030_MODULE_PWM0, 0x80, TWL_PWM0_ON);
+
+ bl->props.state |= PANDORABL_WAS_OFF;
+ bl->props.brightness = MAX_USER_VALUE;
+ backlight_update_status(bl);
+
+ /* enable PWM function in pin mux */
+ twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_PMBR1);
+ r &= ~TWL_PMBR1_PWM0_MUXMASK;
+ r |= TWL_PMBR1_PWM0;
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_PMBR1);
+
+ return 0;
+}
+
+static int pandora_backlight_remove(struct platform_device *pdev)
+{
+ struct backlight_device *bl = platform_get_drvdata(pdev);
+ backlight_device_unregister(bl);
+ return 0;
+}
+
+static struct platform_driver pandora_backlight_driver = {
+ .driver = {
+ .name = "pandora-backlight",
+ .owner = THIS_MODULE,
+ },
+ .probe = pandora_backlight_probe,
+ .remove = pandora_backlight_remove,
+};
+
+module_platform_driver(pandora_backlight_driver);
+
+MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
+MODULE_DESCRIPTION("Pandora Backlight Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pandora-backlight");
diff --git a/drivers/video/backlight/pcf50633-backlight.c b/drivers/video/backlight/pcf50633-backlight.c
index 13e88b71dae..c65853cb974 100644
--- a/drivers/video/backlight/pcf50633-backlight.c
+++ b/drivers/video/backlight/pcf50633-backlight.c
@@ -101,14 +101,13 @@ static const struct backlight_ops pcf50633_bl_ops = {
static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
{
- int ret;
struct pcf50633_bl *pcf_bl;
struct device *parent = pdev->dev.parent;
struct pcf50633_platform_data *pcf50633_data = parent->platform_data;
struct pcf50633_bl_platform_data *pdata = pcf50633_data->backlight_data;
struct backlight_properties bl_props;
- pcf_bl = kzalloc(sizeof(*pcf_bl), GFP_KERNEL);
+ pcf_bl = devm_kzalloc(&pdev->dev, sizeof(*pcf_bl), GFP_KERNEL);
if (!pcf_bl)
return -ENOMEM;
@@ -129,10 +128,8 @@ static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
pcf_bl->bl = backlight_device_register(pdev->name, &pdev->dev, pcf_bl,
&pcf50633_bl_ops, &bl_props);
- if (IS_ERR(pcf_bl->bl)) {
- ret = PTR_ERR(pcf_bl->bl);
- goto err_free;
- }
+ if (IS_ERR(pcf_bl->bl))
+ return PTR_ERR(pcf_bl->bl);
platform_set_drvdata(pdev, pcf_bl);
@@ -145,11 +142,6 @@ static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
backlight_update_status(pcf_bl->bl);
return 0;
-
-err_free:
- kfree(pcf_bl);
-
- return ret;
}
static int __devexit pcf50633_bl_remove(struct platform_device *pdev)
@@ -160,8 +152,6 @@ static int __devexit pcf50633_bl_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
- kfree(pcf_bl);
-
return 0;
}
diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c
index f0bf491ed08..b6672340d6c 100644
--- a/drivers/video/backlight/platform_lcd.c
+++ b/drivers/video/backlight/platform_lcd.c
@@ -121,9 +121,9 @@ static int __devexit platform_lcd_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
-static int platform_lcd_suspend(struct platform_device *pdev, pm_message_t st)
+static int platform_lcd_suspend(struct device *dev)
{
- struct platform_lcd *plcd = platform_get_drvdata(pdev);
+ struct platform_lcd *plcd = dev_get_drvdata(dev);
plcd->suspended = 1;
platform_lcd_set_power(plcd->lcd, plcd->power);
@@ -131,29 +131,30 @@ static int platform_lcd_suspend(struct platform_device *pdev, pm_message_t st)
return 0;
}
-static int platform_lcd_resume(struct platform_device *pdev)
+static int platform_lcd_resume(struct device *dev)
{
- struct platform_lcd *plcd = platform_get_drvdata(pdev);
+ struct platform_lcd *plcd = dev_get_drvdata(dev);
plcd->suspended = 0;
platform_lcd_set_power(plcd->lcd, plcd->power);
return 0;
}
-#else
-#define platform_lcd_suspend NULL
-#define platform_lcd_resume NULL
+
+static SIMPLE_DEV_PM_OPS(platform_lcd_pm_ops, platform_lcd_suspend,
+ platform_lcd_resume);
#endif
static struct platform_driver platform_lcd_driver = {
.driver = {
.name = "platform-lcd",
.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &platform_lcd_pm_ops,
+#endif
},
.probe = platform_lcd_probe,
.remove = __devexit_p(platform_lcd_remove),
- .suspend = platform_lcd_suspend,
- .resume = platform_lcd_resume,
};
module_platform_driver(platform_lcd_driver);
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 7496d04e1d3..342b7d7cbb6 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -102,7 +102,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
return ret;
}
- pb = kzalloc(sizeof(*pb), GFP_KERNEL);
+ pb = devm_kzalloc(&pdev->dev, sizeof(*pb), GFP_KERNEL);
if (!pb) {
dev_err(&pdev->dev, "no memory for state\n");
ret = -ENOMEM;
@@ -121,7 +121,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
if (IS_ERR(pb->pwm)) {
dev_err(&pdev->dev, "unable to request PWM for backlight\n");
ret = PTR_ERR(pb->pwm);
- goto err_pwm;
+ goto err_alloc;
} else
dev_dbg(&pdev->dev, "got pwm for backlight\n");
@@ -144,8 +144,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)
err_bl:
pwm_free(pb->pwm);
-err_pwm:
- kfree(pb);
err_alloc:
if (data->exit)
data->exit(&pdev->dev);
@@ -162,7 +160,6 @@ static int pwm_backlight_remove(struct platform_device *pdev)
pwm_config(pb->pwm, 0, pb->period);
pwm_disable(pb->pwm);
pwm_free(pb->pwm);
- kfree(pb);
if (data->exit)
data->exit(&pdev->dev);
return 0;
diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c
index 516db703dd2..e264f55b257 100644
--- a/drivers/video/backlight/s6e63m0.c
+++ b/drivers/video/backlight/s6e63m0.c
@@ -909,18 +909,7 @@ static struct spi_driver s6e63m0_driver = {
.resume = s6e63m0_resume,
};
-static int __init s6e63m0_init(void)
-{
- return spi_register_driver(&s6e63m0_driver);
-}
-
-static void __exit s6e63m0_exit(void)
-{
- spi_unregister_driver(&s6e63m0_driver);
-}
-
-module_init(s6e63m0_init);
-module_exit(s6e63m0_exit);
+module_spi_driver(s6e63m0_driver);
MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
MODULE_DESCRIPTION("S6E63M0 LCD Driver");
diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c
index 1997e12a105..2368b8e5f89 100644
--- a/drivers/video/backlight/tdo24m.c
+++ b/drivers/video/backlight/tdo24m.c
@@ -459,17 +459,7 @@ static struct spi_driver tdo24m_driver = {
.resume = tdo24m_resume,
};
-static int __init tdo24m_init(void)
-{
- return spi_register_driver(&tdo24m_driver);
-}
-module_init(tdo24m_init);
-
-static void __exit tdo24m_exit(void)
-{
- spi_unregister_driver(&tdo24m_driver);
-}
-module_exit(tdo24m_exit);
+module_spi_driver(tdo24m_driver);
MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
MODULE_DESCRIPTION("Driver for Toppoly TDO24M LCD Panel");
diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c
index 425a7365470..2b241abced4 100644
--- a/drivers/video/backlight/tosa_bl.c
+++ b/drivers/video/backlight/tosa_bl.c
@@ -181,18 +181,7 @@ static struct i2c_driver tosa_bl_driver = {
.id_table = tosa_bl_id,
};
-static int __init tosa_bl_init(void)
-{
- return i2c_add_driver(&tosa_bl_driver);
-}
-
-static void __exit tosa_bl_exit(void)
-{
- i2c_del_driver(&tosa_bl_driver);
-}
-
-module_init(tosa_bl_init);
-module_exit(tosa_bl_exit);
+module_i2c_driver(tosa_bl_driver);
MODULE_AUTHOR("Dmitry Baryshkov");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c
index 772f6015219..2231aec2391 100644
--- a/drivers/video/backlight/tosa_lcd.c
+++ b/drivers/video/backlight/tosa_lcd.c
@@ -271,7 +271,7 @@ static int tosa_lcd_resume(struct spi_device *spi)
}
#else
#define tosa_lcd_suspend NULL
-#define tosa_lcd_reume NULL
+#define tosa_lcd_resume NULL
#endif
static struct spi_driver tosa_lcd_driver = {
@@ -285,18 +285,7 @@ static struct spi_driver tosa_lcd_driver = {
.resume = tosa_lcd_resume,
};
-static int __init tosa_lcd_init(void)
-{
- return spi_register_driver(&tosa_lcd_driver);
-}
-
-static void __exit tosa_lcd_exit(void)
-{
- spi_unregister_driver(&tosa_lcd_driver);
-}
-
-module_init(tosa_lcd_init);
-module_exit(tosa_lcd_exit);
+module_spi_driver(tosa_lcd_driver);
MODULE_AUTHOR("Dmitry Baryshkov");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/vgg2432a4.c b/drivers/video/backlight/vgg2432a4.c
index b49063c831e..b617fae9aa2 100644
--- a/drivers/video/backlight/vgg2432a4.c
+++ b/drivers/video/backlight/vgg2432a4.c
@@ -262,20 +262,7 @@ static struct spi_driver vgg2432a4_driver = {
.resume = vgg2432a4_resume,
};
-/* Device driver initialisation */
-
-static int __init vgg2432a4_init(void)
-{
- return spi_register_driver(&vgg2432a4_driver);
-}
-
-static void __exit vgg2432a4_exit(void)
-{
- spi_unregister_driver(&vgg2432a4_driver);
-}
-
-module_init(vgg2432a4_init);
-module_exit(vgg2432a4_exit);
+module_spi_driver(vgg2432a4_driver);
MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
MODULE_DESCRIPTION("VGG2432A4 LCD Driver");
diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c
index 4e915f5eca9..5d365deb5f8 100644
--- a/drivers/video/backlight/wm831x_bl.c
+++ b/drivers/video/backlight/wm831x_bl.c
@@ -186,7 +186,7 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
- data = kzalloc(sizeof(*data), GFP_KERNEL);
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
@@ -200,7 +200,6 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
&wm831x_backlight_ops, &props);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
- kfree(data);
return PTR_ERR(bl);
}
@@ -211,7 +210,6 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
/* Disable the DCDC if it was started so we can bootstrap */
wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, WM831X_DC4_ENA, 0);
-
backlight_update_status(bl);
return 0;
@@ -220,10 +218,8 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
static int wm831x_backlight_remove(struct platform_device *pdev)
{
struct backlight_device *bl = platform_get_drvdata(pdev);
- struct wm831x_backlight_data *data = bl_get_data(bl);
backlight_device_unregister(bl);
- kfree(data);
return 0;
}