From 556f00ede819c20eaf2af9017a78c713b33ca4e7 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 4 Oct 2012 17:12:05 -0700 Subject: sections: fix section conflicts in drivers/video Signed-off-by: Andi Kleen Cc: Florian Tobias Schandinat Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/aty/aty128fb.c | 2 +- drivers/video/geode/gx1fb_core.c | 2 +- drivers/video/gxt4500.c | 4 ++-- drivers/video/i810/i810_main.c | 2 +- drivers/video/jz4740_fb.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index 747442d2c0f6..0fefa84ed9ae 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c @@ -149,7 +149,7 @@ enum { }; /* Must match above enum */ -static const char *r128_family[] __devinitdata = { +static char * const r128_family[] __devinitconst = { "AGP", "PCI", "PRO AGP", diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c index 5a5d0928df33..265c5ed59ade 100644 --- a/drivers/video/geode/gx1fb_core.c +++ b/drivers/video/geode/gx1fb_core.c @@ -29,7 +29,7 @@ static int crt_option = 1; static char panel_option[32] = ""; /* Modes relevant to the GX1 (taken from modedb.c) */ -static const struct fb_videomode __devinitdata gx1_modedb[] = { +static const struct fb_videomode __devinitconst gx1_modedb[] = { /* 640x480-60 VESA */ { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2, 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, diff --git a/drivers/video/gxt4500.c b/drivers/video/gxt4500.c index 0fad23f810a3..0e9afa41d163 100644 --- a/drivers/video/gxt4500.c +++ b/drivers/video/gxt4500.c @@ -156,7 +156,7 @@ struct gxt4500_par { static char *mode_option; /* default mode: 1280x1024 @ 60 Hz, 8 bpp */ -static const struct fb_videomode defaultmode __devinitdata = { +static const struct fb_videomode defaultmode __devinitconst = { .refresh = 60, .xres = 1280, .yres = 1024, @@ -581,7 +581,7 @@ static int gxt4500_blank(int blank, struct fb_info *info) return 0; } -static const struct fb_fix_screeninfo gxt4500_fix __devinitdata = { +static const struct fb_fix_screeninfo gxt4500_fix __devinitconst = { .id = "IBM GXT4500P", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_PSEUDOCOLOR, diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index b83f36190cae..5c067816a81d 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c @@ -97,7 +97,7 @@ static int i810fb_blank (int blank_mode, struct fb_info *info); static void i810fb_release_resource (struct fb_info *info, struct i810fb_par *par); /* PCI */ -static const char *i810_pci_list[] __devinitdata = { +static const char * const i810_pci_list[] __devinitconst = { "Intel(R) 810 Framebuffer Device" , "Intel(R) 810-DC100 Framebuffer Device" , "Intel(R) 810E Framebuffer Device" , diff --git a/drivers/video/jz4740_fb.c b/drivers/video/jz4740_fb.c index de366937c933..3c63fc24bb1f 100644 --- a/drivers/video/jz4740_fb.c +++ b/drivers/video/jz4740_fb.c @@ -136,7 +136,7 @@ struct jzfb { uint32_t pseudo_palette[16]; }; -static const struct fb_fix_screeninfo jzfb_fix __devinitdata = { +static const struct fb_fix_screeninfo jzfb_fix __devinitconst = { .id = "JZ4740 FB", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_TRUECOLOR, -- cgit v1.2.3-58-ga151 From 5333e254ab3fd3720b172091669f537763bce23d Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 4 Oct 2012 17:12:42 -0700 Subject: drivers/video/backlight/da9052_bl.c: use usleep_range() instead of msleep() for small sleeps Since msleep() might not sleep for the desired amount when less than 20ms, use usleep_range(). Signed-off-by: Jingoo Han Cc: Ashish Jangam Cc: Richard Purdie Cc: Sachin Kamat Cc: Mark Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/da9052_bl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/backlight/da9052_bl.c b/drivers/video/backlight/da9052_bl.c index b628d68f5162..10485c927ac6 100644 --- a/drivers/video/backlight/da9052_bl.c +++ b/drivers/video/backlight/da9052_bl.c @@ -72,7 +72,7 @@ static int da9052_adjust_wled_brightness(struct da9052_bl *wleds) if (ret < 0) return ret; - msleep(10); + usleep_range(10000, 11000); if (wleds->brightness) { ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg], -- cgit v1.2.3-58-ga151 From a08e1a376b0a31e0a978494deffed409fad9c531 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 4 Oct 2012 17:12:44 -0700 Subject: drivers/video/backlight/ltv350qv.c: use usleep_range() instead of msleep() for small sleeps Since msleep() might not sleep for the desired amount when less than 20ms, use usleep_range(). Signed-off-by: Jingoo Han Cc: Haavard Skinnemoen Cc: Richard Purdie Cc: Sachin Kamat Cc: Mark Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/ltv350qv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c index 6c0f1ac0d32a..4066a5bbd826 100644 --- a/drivers/video/backlight/ltv350qv.c +++ b/drivers/video/backlight/ltv350qv.c @@ -75,7 +75,7 @@ static int ltv350qv_power_on(struct ltv350qv *lcd) /* Power On Reset Display off State */ if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, 0x0000)) goto err; - msleep(15); + usleep_range(15000, 16000); /* Power Setting Function 1 */ if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE)) @@ -153,7 +153,7 @@ err_settings: err_power2: err_power1: ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000); - msleep(1); + usleep_range(1000, 1100); err: ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE); return -EIO; @@ -175,7 +175,7 @@ static int ltv350qv_power_off(struct ltv350qv *lcd) ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000); /* Wait at least 1 ms */ - msleep(1); + usleep_range(1000, 1100); /* Power down setting 2 */ ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE); -- cgit v1.2.3-58-ga151 From 7c9332d19e54d3eb1beab931a43930fe7ad1d468 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 4 Oct 2012 17:12:47 -0700 Subject: drivers/video/backlight/kb3886_bl.c: use usleep_range() instead of msleep() for small sleeps Since msleep() might not sleep for the desired amount when less than 20ms, use usleep_range(). Signed-off-by: Jingoo Han Cc: Claudio Nieder Cc: Richard Purdie Cc: Sachin Kamat Cc: Mark Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/kb3886_bl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c index 72dd5556a35b..6c5ed6b242cc 100644 --- a/drivers/video/backlight/kb3886_bl.c +++ b/drivers/video/backlight/kb3886_bl.c @@ -34,9 +34,9 @@ static void kb3886_bl_set_intensity(int intensity) mutex_lock(&bl_mutex); intensity = intensity&0xff; outb(KB3886_ADC_DAC_PWM, KB3886_PARENT); - msleep(10); + usleep_range(10000, 11000); outb(KB3886_PWM0_WRITE, KB3886_IO); - msleep(10); + usleep_range(10000, 11000); outb(intensity, KB3886_IO); mutex_unlock(&bl_mutex); } -- cgit v1.2.3-58-ga151 From 0c2a665a648ea74879ce6333d3a31a96a7c361ce Mon Sep 17 00:00:00 2001 From: "G.Shark Jeong" Date: Thu, 4 Oct 2012 17:12:52 -0700 Subject: backlight: add Backlight driver for lm3630 chip This driver is a general version for LM3630 backlgiht driver chip of TI. LM3630 : The LM3630 is a current mode boost converter which supplies the power and controls the current in two strings of up to 10 LEDs per string. Programming is done over an I2C compatible interface. www.ti.com [akpm@linux-foundation.org: make bled_name[] static, a few coding style tuneups, create new set_intensity(), partly to avoid awkward layout gymnastics] Signed-off-by: G.Shark Jeong Cc: Richard Purdie Cc: Daniel Jeong Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/Kconfig | 7 + drivers/video/backlight/Makefile | 1 + drivers/video/backlight/lm3630_bl.c | 475 ++++++++++++++++++++++++++++++++ include/linux/platform_data/lm3630_bl.h | 57 ++++ 4 files changed, 540 insertions(+) create mode 100644 drivers/video/backlight/lm3630_bl.c create mode 100644 include/linux/platform_data/lm3630_bl.h (limited to 'drivers/video') diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index cf282763a8dc..b9008b54ac5d 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -352,6 +352,13 @@ config BACKLIGHT_AAT2870 If you have a AnalogicTech AAT2870 say Y to enable the backlight driver. +config BACKLIGHT_LM3630 + tristate "Backlight Driver for LM3630" + depends on BACKLIGHT_CLASS_DEVICE && I2C + select REGMAP_I2C + help + This supports TI LM3630 Backlight Driver + config BACKLIGHT_LP855X tristate "Backlight driver for TI LP855X" depends on BACKLIGHT_CLASS_DEVICE && I2C diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index a2ac9cfbaf6b..b0725313cd4d 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o +obj-$(CONFIG_BACKLIGHT_LM3630) += lm3630_bl.o obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o diff --git a/drivers/video/backlight/lm3630_bl.c b/drivers/video/backlight/lm3630_bl.c new file mode 100644 index 000000000000..dc191441796f --- /dev/null +++ b/drivers/video/backlight/lm3630_bl.c @@ -0,0 +1,475 @@ +/* +* Simple driver for Texas Instruments LM3630 Backlight driver chip +* Copyright (C) 2012 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define REG_CTRL 0x00 +#define REG_CONFIG 0x01 +#define REG_BRT_A 0x03 +#define REG_BRT_B 0x04 +#define REG_INT_STATUS 0x09 +#define REG_INT_EN 0x0A +#define REG_FAULT 0x0B +#define REG_PWM_OUTLOW 0x12 +#define REG_PWM_OUTHIGH 0x13 +#define REG_MAX 0x1F + +#define INT_DEBOUNCE_MSEC 10 + +enum lm3630_leds { + BLED_ALL = 0, + BLED_1, + BLED_2 +}; + +static const char *bled_name[] = { + [BLED_ALL] = "lm3630_bled", /*Bank1 controls all string */ + [BLED_1] = "lm3630_bled1", /*Bank1 controls bled1 */ + [BLED_2] = "lm3630_bled2", /*Bank1 or 2 controls bled2 */ +}; + +struct lm3630_chip_data { + struct device *dev; + struct delayed_work work; + int irq; + struct workqueue_struct *irqthread; + struct lm3630_platform_data *pdata; + struct backlight_device *bled1; + struct backlight_device *bled2; + struct regmap *regmap; +}; + +/* initialize chip */ +static int __devinit lm3630_chip_init(struct lm3630_chip_data *pchip) +{ + int ret; + unsigned int reg_val; + struct lm3630_platform_data *pdata = pchip->pdata; + + /*pwm control */ + reg_val = ((pdata->pwm_active & 0x01) << 2) | (pdata->pwm_ctrl & 0x03); + ret = regmap_update_bits(pchip->regmap, REG_CONFIG, 0x07, reg_val); + if (ret < 0) + goto out; + + /* bank control */ + reg_val = ((pdata->bank_b_ctrl & 0x01) << 1) | + (pdata->bank_a_ctrl & 0x07); + ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x07, reg_val); + if (ret < 0) + goto out; + + ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); + if (ret < 0) + goto out; + + /* set initial brightness */ + if (pdata->bank_a_ctrl != BANK_A_CTRL_DISABLE) { + ret = regmap_write(pchip->regmap, + REG_BRT_A, pdata->init_brt_led1); + if (ret < 0) + goto out; + } + + if (pdata->bank_b_ctrl != BANK_B_CTRL_DISABLE) { + ret = regmap_write(pchip->regmap, + REG_BRT_B, pdata->init_brt_led2); + if (ret < 0) + goto out; + } + return ret; + +out: + dev_err(pchip->dev, "i2c failed to access register\n"); + return ret; +} + +/* interrupt handling */ +static void lm3630_delayed_func(struct work_struct *work) +{ + int ret; + unsigned int reg_val; + struct lm3630_chip_data *pchip; + + pchip = container_of(work, struct lm3630_chip_data, work.work); + + ret = regmap_read(pchip->regmap, REG_INT_STATUS, ®_val); + if (ret < 0) { + dev_err(pchip->dev, + "i2c failed to access REG_INT_STATUS Register\n"); + return; + } + + dev_info(pchip->dev, "REG_INT_STATUS Register is 0x%x\n", reg_val); +} + +static irqreturn_t lm3630_isr_func(int irq, void *chip) +{ + int ret; + struct lm3630_chip_data *pchip = chip; + unsigned long delay = msecs_to_jiffies(INT_DEBOUNCE_MSEC); + + queue_delayed_work(pchip->irqthread, &pchip->work, delay); + + ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); + if (ret < 0) + goto out; + + return IRQ_HANDLED; +out: + dev_err(pchip->dev, "i2c failed to access register\n"); + return IRQ_HANDLED; +} + +static int lm3630_intr_config(struct lm3630_chip_data *pchip) +{ + INIT_DELAYED_WORK(&pchip->work, lm3630_delayed_func); + pchip->irqthread = create_singlethread_workqueue("lm3630-irqthd"); + if (!pchip->irqthread) { + dev_err(pchip->dev, "create irq thread fail...\n"); + return -1; + } + if (request_threaded_irq + (pchip->irq, NULL, lm3630_isr_func, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "lm3630_irq", pchip)) { + dev_err(pchip->dev, "request threaded irq fail..\n"); + return -1; + } + return 0; +} + +static bool +set_intensity(struct backlight_device *bl, struct lm3630_chip_data *pchip) +{ + if (!pchip->pdata->pwm_set_intensity) + return false; + pchip->pdata->pwm_set_intensity(bl->props.brightness - 1, + pchip->pdata->pwm_period); + return true; +} + +/* update and get brightness */ +static int lm3630_bank_a_update_status(struct backlight_device *bl) +{ + int ret; + struct lm3630_chip_data *pchip = bl_get_data(bl); + enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; + + /* brightness 0 means disable */ + if (!bl->props.brightness) { + ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x04, 0x00); + if (ret < 0) + goto out; + return bl->props.brightness; + } + + /* pwm control */ + if (pwm_ctrl == PWM_CTRL_BANK_A || pwm_ctrl == PWM_CTRL_BANK_ALL) { + if (!set_intensity(bl, pchip)) + dev_err(pchip->dev, "No pwm control func. in plat-data\n"); + } else { + + /* i2c control */ + ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); + if (ret < 0) + goto out; + mdelay(1); + ret = regmap_write(pchip->regmap, + REG_BRT_A, bl->props.brightness - 1); + if (ret < 0) + goto out; + } + return bl->props.brightness; +out: + dev_err(pchip->dev, "i2c failed to access REG_CTRL\n"); + return bl->props.brightness; +} + +static int lm3630_bank_a_get_brightness(struct backlight_device *bl) +{ + unsigned int reg_val; + int brightness, ret; + struct lm3630_chip_data *pchip = bl_get_data(bl); + enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; + + if (pwm_ctrl == PWM_CTRL_BANK_A || pwm_ctrl == PWM_CTRL_BANK_ALL) { + ret = regmap_read(pchip->regmap, REG_PWM_OUTHIGH, ®_val); + if (ret < 0) + goto out; + brightness = reg_val & 0x01; + ret = regmap_read(pchip->regmap, REG_PWM_OUTLOW, ®_val); + if (ret < 0) + goto out; + brightness = ((brightness << 8) | reg_val) + 1; + } else { + ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); + if (ret < 0) + goto out; + mdelay(1); + ret = regmap_read(pchip->regmap, REG_BRT_A, ®_val); + if (ret < 0) + goto out; + brightness = reg_val + 1; + } + bl->props.brightness = brightness; + return bl->props.brightness; +out: + dev_err(pchip->dev, "i2c failed to access register\n"); + return 0; +} + +static const struct backlight_ops lm3630_bank_a_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = lm3630_bank_a_update_status, + .get_brightness = lm3630_bank_a_get_brightness, +}; + +static int lm3630_bank_b_update_status(struct backlight_device *bl) +{ + int ret; + struct lm3630_chip_data *pchip = bl_get_data(bl); + enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; + + if (pwm_ctrl == PWM_CTRL_BANK_B || pwm_ctrl == PWM_CTRL_BANK_ALL) { + if (!set_intensity(bl, pchip)) + dev_err(pchip->dev, + "no pwm control func. in plat-data\n"); + } else { + ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); + if (ret < 0) + goto out; + mdelay(1); + ret = regmap_write(pchip->regmap, + REG_BRT_B, bl->props.brightness - 1); + } + return bl->props.brightness; +out: + dev_err(pchip->dev, "i2c failed to access register\n"); + return bl->props.brightness; +} + +static int lm3630_bank_b_get_brightness(struct backlight_device *bl) +{ + unsigned int reg_val; + int brightness, ret; + struct lm3630_chip_data *pchip = bl_get_data(bl); + enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; + + if (pwm_ctrl == PWM_CTRL_BANK_B || pwm_ctrl == PWM_CTRL_BANK_ALL) { + ret = regmap_read(pchip->regmap, REG_PWM_OUTHIGH, ®_val); + if (ret < 0) + goto out; + brightness = reg_val & 0x01; + ret = regmap_read(pchip->regmap, REG_PWM_OUTLOW, ®_val); + if (ret < 0) + goto out; + brightness = ((brightness << 8) | reg_val) + 1; + } else { + ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); + if (ret < 0) + goto out; + mdelay(1); + ret = regmap_read(pchip->regmap, REG_BRT_B, ®_val); + if (ret < 0) + goto out; + brightness = reg_val + 1; + } + bl->props.brightness = brightness; + + return bl->props.brightness; +out: + dev_err(pchip->dev, "i2c failed to access register\n"); + return bl->props.brightness; +} + +static const struct backlight_ops lm3630_bank_b_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = lm3630_bank_b_update_status, + .get_brightness = lm3630_bank_b_get_brightness, +}; + +static int lm3630_backlight_register(struct lm3630_chip_data *pchip, + enum lm3630_leds ledno) +{ + const char *name = bled_name[ledno]; + struct backlight_properties props; + struct lm3630_platform_data *pdata = pchip->pdata; + + props.type = BACKLIGHT_RAW; + switch (ledno) { + case BLED_1: + case BLED_ALL: + props.brightness = pdata->init_brt_led1; + props.max_brightness = pdata->max_brt_led1; + pchip->bled1 = + backlight_device_register(name, pchip->dev, pchip, + &lm3630_bank_a_ops, &props); + if (IS_ERR(pchip->bled1)) + return -EIO; + break; + case BLED_2: + props.brightness = pdata->init_brt_led2; + props.max_brightness = pdata->max_brt_led2; + pchip->bled2 = + backlight_device_register(name, pchip->dev, pchip, + &lm3630_bank_b_ops, &props); + if (IS_ERR(pchip->bled2)) + return -EIO; + break; + } + return 0; +} + +static void lm3630_backlight_unregister(struct lm3630_chip_data *pchip) +{ + if (pchip->bled1) + backlight_device_unregister(pchip->bled1); + if (pchip->bled2) + backlight_device_unregister(pchip->bled2); +} + +static const struct regmap_config lm3630_regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = REG_MAX, +}; + +static int __devinit lm3630_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct lm3630_platform_data *pdata = client->dev.platform_data; + struct lm3630_chip_data *pchip; + int ret; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, "fail : i2c functionality check...\n"); + return -EOPNOTSUPP; + } + + if (pdata == NULL) { + dev_err(&client->dev, "fail : no platform data.\n"); + return -ENODATA; + } + + pchip = devm_kzalloc(&client->dev, sizeof(struct lm3630_chip_data), + GFP_KERNEL); + if (!pchip) + return -ENOMEM; + pchip->pdata = pdata; + pchip->dev = &client->dev; + + pchip->regmap = devm_regmap_init_i2c(client, &lm3630_regmap); + if (IS_ERR(pchip->regmap)) { + ret = PTR_ERR(pchip->regmap); + dev_err(&client->dev, "fail : allocate register map: %d\n", + ret); + return ret; + } + i2c_set_clientdata(client, pchip); + + /* chip initialize */ + ret = lm3630_chip_init(pchip); + if (ret < 0) { + dev_err(&client->dev, "fail : init chip\n"); + goto err_chip_init; + } + + switch (pdata->bank_a_ctrl) { + case BANK_A_CTRL_ALL: + ret = lm3630_backlight_register(pchip, BLED_ALL); + pdata->bank_b_ctrl = BANK_B_CTRL_DISABLE; + break; + case BANK_A_CTRL_LED1: + ret = lm3630_backlight_register(pchip, BLED_1); + break; + case BANK_A_CTRL_LED2: + ret = lm3630_backlight_register(pchip, BLED_2); + pdata->bank_b_ctrl = BANK_B_CTRL_DISABLE; + break; + default: + break; + } + + if (ret < 0) + goto err_bl_reg; + + if (pdata->bank_b_ctrl && pchip->bled2 == NULL) { + ret = lm3630_backlight_register(pchip, BLED_2); + if (ret < 0) + goto err_bl_reg; + } + + /* interrupt enable : irq 0 is not allowed for lm3630 */ + pchip->irq = client->irq; + if (pchip->irq) + lm3630_intr_config(pchip); + + dev_info(&client->dev, "LM3630 backlight register OK.\n"); + return 0; + +err_bl_reg: + dev_err(&client->dev, "fail : backlight register.\n"); + lm3630_backlight_unregister(pchip); +err_chip_init: + return ret; +} + +static int __devexit lm3630_remove(struct i2c_client *client) +{ + int ret; + struct lm3630_chip_data *pchip = i2c_get_clientdata(client); + + ret = regmap_write(pchip->regmap, REG_BRT_A, 0); + if (ret < 0) + dev_err(pchip->dev, "i2c failed to access register\n"); + + ret = regmap_write(pchip->regmap, REG_BRT_B, 0); + if (ret < 0) + dev_err(pchip->dev, "i2c failed to access register\n"); + + lm3630_backlight_unregister(pchip); + if (pchip->irq) { + free_irq(pchip->irq, pchip); + flush_workqueue(pchip->irqthread); + destroy_workqueue(pchip->irqthread); + } + return 0; +} + +static const struct i2c_device_id lm3630_id[] = { + {LM3630_NAME, 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, lm3630_id); + +static struct i2c_driver lm3630_i2c_driver = { + .driver = { + .name = LM3630_NAME, + }, + .probe = lm3630_probe, + .remove = __devexit_p(lm3630_remove), + .id_table = lm3630_id, +}; + +module_i2c_driver(lm3630_i2c_driver); + +MODULE_DESCRIPTION("Texas Instruments Backlight driver for LM3630"); +MODULE_AUTHOR("G.Shark Jeong "); +MODULE_AUTHOR("Daniel Jeong "); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/platform_data/lm3630_bl.h b/include/linux/platform_data/lm3630_bl.h new file mode 100644 index 000000000000..9176dd3f2d63 --- /dev/null +++ b/include/linux/platform_data/lm3630_bl.h @@ -0,0 +1,57 @@ +/* +* Simple driver for Texas Instruments LM3630 LED Flash driver chip +* Copyright (C) 2012 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. +* +*/ + +#ifndef __LINUX_LM3630_H +#define __LINUX_LM3630_H + +#define LM3630_NAME "lm3630_bl" + +enum lm3630_pwm_ctrl { + PWM_CTRL_DISABLE = 0, + PWM_CTRL_BANK_A, + PWM_CTRL_BANK_B, + PWM_CTRL_BANK_ALL, +}; + +enum lm3630_pwm_active { + PWM_ACTIVE_HIGH = 0, + PWM_ACTIVE_LOW, +}; + +enum lm3630_bank_a_ctrl { + BANK_A_CTRL_DISABLE = 0x0, + BANK_A_CTRL_LED1 = 0x4, + BANK_A_CTRL_LED2 = 0x1, + BANK_A_CTRL_ALL = 0x5, +}; + +enum lm3630_bank_b_ctrl { + BANK_B_CTRL_DISABLE = 0, + BANK_B_CTRL_LED2, +}; + +struct lm3630_platform_data { + + /* maximum brightness */ + int max_brt_led1; + int max_brt_led2; + + /* initial on brightness */ + int init_brt_led1; + int init_brt_led2; + enum lm3630_pwm_ctrl pwm_ctrl; + enum lm3630_pwm_active pwm_active; + enum lm3630_bank_a_ctrl bank_a_ctrl; + enum lm3630_bank_b_ctrl bank_b_ctrl; + unsigned int pwm_period; + void (*pwm_set_intensity) (int brightness, int max_brightness); +}; + +#endif /* __LINUX_LM3630_H */ -- cgit v1.2.3-58-ga151 From 0f59858d511960caefb42c4535dc73c2c5f3136c Mon Sep 17 00:00:00 2001 From: "G.Shark Jeong" Date: Thu, 4 Oct 2012 17:12:55 -0700 Subject: backlight: add new lm3639 backlight driver This driver is a general version for LM3639 backlgiht + flash driver chip of TI. LM3639: The LM3639 is a single chip LCD Display Backlight driver + white LED Camera driver. Programming is done over an I2C compatible interface. www.ti.com [akpm@linux-foundation.org: code layout tweaks] Signed-off-by: G.Shark Jeong Cc: Richard Purdie Cc: Daniel Jeong Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/Kconfig | 9 + drivers/video/backlight/Makefile | 1 + drivers/video/backlight/lm3639_bl.c | 437 ++++++++++++++++++++++++++++++++ include/linux/platform_data/lm3639_bl.h | 69 +++++ 4 files changed, 516 insertions(+) create mode 100644 drivers/video/backlight/lm3639_bl.c create mode 100644 include/linux/platform_data/lm3639_bl.h (limited to 'drivers/video') diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index b9008b54ac5d..2b98fb8e711d 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -359,6 +359,15 @@ config BACKLIGHT_LM3630 help This supports TI LM3630 Backlight Driver +config BACKLIGHT_LM3639 + tristate "Backlight Driver for LM3639" + depends on BACKLIGHT_CLASS_DEVICE && I2C + select REGMAP_I2C + select NEW_LEDS + select LEDS_CLASS + help + This supports TI LM3639 Backlight + 1.5A Flash LED Driver + config BACKLIGHT_LP855X tristate "Backlight driver for TI LP855X" depends on BACKLIGHT_CLASS_DEVICE && I2C diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index b0725313cd4d..a151378da45b 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o obj-$(CONFIG_BACKLIGHT_LM3630) += lm3630_bl.o +obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c new file mode 100644 index 000000000000..c6915c6c3cd1 --- /dev/null +++ b/drivers/video/backlight/lm3639_bl.c @@ -0,0 +1,437 @@ +/* +* Simple driver for Texas Instruments LM3639 Backlight + Flash LED driver chip +* Copyright (C) 2012 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define REG_DEV_ID 0x00 +#define REG_CHECKSUM 0x01 +#define REG_BL_CONF_1 0x02 +#define REG_BL_CONF_2 0x03 +#define REG_BL_CONF_3 0x04 +#define REG_BL_CONF_4 0x05 +#define REG_FL_CONF_1 0x06 +#define REG_FL_CONF_2 0x07 +#define REG_FL_CONF_3 0x08 +#define REG_IO_CTRL 0x09 +#define REG_ENABLE 0x0A +#define REG_FLAG 0x0B +#define REG_MAX REG_FLAG + +struct lm3639_chip_data { + struct device *dev; + struct lm3639_platform_data *pdata; + + struct backlight_device *bled; + struct led_classdev cdev_flash; + struct led_classdev cdev_torch; + struct regmap *regmap; + + unsigned int bled_mode; + unsigned int bled_map; + unsigned int last_flag; +}; + +/* initialize chip */ +static int __devinit lm3639_chip_init(struct lm3639_chip_data *pchip) +{ + int ret; + unsigned int reg_val; + struct lm3639_platform_data *pdata = pchip->pdata; + + /* input pins config. */ + ret = + regmap_update_bits(pchip->regmap, REG_BL_CONF_1, 0x08, + pdata->pin_pwm); + if (ret < 0) + goto out; + + reg_val = (pdata->pin_pwm & 0x40) | pdata->pin_strobe | pdata->pin_tx; + ret = regmap_update_bits(pchip->regmap, REG_IO_CTRL, 0x7C, reg_val); + if (ret < 0) + goto out; + + /* init brightness */ + ret = regmap_write(pchip->regmap, REG_BL_CONF_4, pdata->init_brt_led); + if (ret < 0) + goto out; + + ret = regmap_write(pchip->regmap, REG_BL_CONF_3, pdata->init_brt_led); + if (ret < 0) + goto out; + + /* output pins config. */ + if (!pdata->init_brt_led) + reg_val = pdata->fled_pins | pdata->bled_pins; + else + reg_val = pdata->fled_pins | pdata->bled_pins | 0x01; + + ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x79, reg_val); + if (ret < 0) + goto out; + + return ret; +out: + dev_err(pchip->dev, "i2c failed to access register\n"); + return ret; +} + +/* update and get brightness */ +static int lm3639_bled_update_status(struct backlight_device *bl) +{ + int ret; + unsigned int reg_val; + struct lm3639_chip_data *pchip = bl_get_data(bl); + struct lm3639_platform_data *pdata = pchip->pdata; + + ret = regmap_read(pchip->regmap, REG_FLAG, ®_val); + if (ret < 0) + goto out; + + if (reg_val != 0) + dev_info(pchip->dev, "last flag is 0x%x\n", reg_val); + + /* pwm control */ + if (pdata->pin_pwm) { + if (pdata->pwm_set_intensity) + pdata->pwm_set_intensity(bl->props.brightness, + pdata->max_brt_led); + else + dev_err(pchip->dev, + "No pwm control func. in plat-data\n"); + return bl->props.brightness; + } + + /* i2c control and set brigtness */ + ret = regmap_write(pchip->regmap, REG_BL_CONF_4, bl->props.brightness); + if (ret < 0) + goto out; + ret = regmap_write(pchip->regmap, REG_BL_CONF_3, bl->props.brightness); + if (ret < 0) + goto out; + + if (!bl->props.brightness) + ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x01, 0x00); + else + ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x01, 0x01); + if (ret < 0) + goto out; + + return bl->props.brightness; +out: + dev_err(pchip->dev, "i2c failed to access registers\n"); + return bl->props.brightness; +} + +static int lm3639_bled_get_brightness(struct backlight_device *bl) +{ + int ret; + unsigned int reg_val; + struct lm3639_chip_data *pchip = bl_get_data(bl); + struct lm3639_platform_data *pdata = pchip->pdata; + + if (pdata->pin_pwm) { + if (pdata->pwm_get_intensity) + bl->props.brightness = pdata->pwm_get_intensity(); + else + dev_err(pchip->dev, + "No pwm control func. in plat-data\n"); + return bl->props.brightness; + } + + ret = regmap_read(pchip->regmap, REG_BL_CONF_1, ®_val); + if (ret < 0) + goto out; + if (reg_val & 0x10) + ret = regmap_read(pchip->regmap, REG_BL_CONF_4, ®_val); + else + ret = regmap_read(pchip->regmap, REG_BL_CONF_3, ®_val); + if (ret < 0) + goto out; + bl->props.brightness = reg_val; + + return bl->props.brightness; +out: + dev_err(pchip->dev, "i2c failed to access register\n"); + return bl->props.brightness; +} + +static const struct backlight_ops lm3639_bled_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = lm3639_bled_update_status, + .get_brightness = lm3639_bled_get_brightness, +}; + +/* backlight mapping mode */ +static ssize_t lm3639_bled_mode_store(struct device *dev, + struct device_attribute *devAttr, + const char *buf, size_t size) +{ + ssize_t ret; + struct lm3639_chip_data *pchip = dev_get_drvdata(dev); + unsigned int state; + + ret = kstrtouint(buf, 10, &state); + if (ret) + goto out_input; + + if (!state) + ret = + regmap_update_bits(pchip->regmap, REG_BL_CONF_1, 0x10, + 0x00); + else + ret = + regmap_update_bits(pchip->regmap, REG_BL_CONF_1, 0x10, + 0x10); + + if (ret < 0) + goto out; + + return size; + +out: + dev_err(pchip->dev, "%s:i2c access fail to register\n", __func__); + return size; + +out_input: + dev_err(pchip->dev, "%s:input conversion fail\n", __func__); + return size; + +} + +static DEVICE_ATTR(bled_mode, 0666, NULL, lm3639_bled_mode_store); + +/* torch */ +static void lm3639_torch_brightness_set(struct led_classdev *cdev, + enum led_brightness brightness) +{ + int ret; + unsigned int reg_val; + struct lm3639_chip_data *pchip; + + pchip = container_of(cdev, struct lm3639_chip_data, cdev_torch); + + ret = regmap_read(pchip->regmap, REG_FLAG, ®_val); + if (ret < 0) + goto out; + if (reg_val != 0) + dev_info(pchip->dev, "last flag is 0x%x\n", reg_val); + + /* brightness 0 means off state */ + if (!brightness) { + ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x00); + if (ret < 0) + goto out; + return; + } + + ret = regmap_update_bits(pchip->regmap, + REG_FL_CONF_1, 0x70, (brightness - 1) << 4); + if (ret < 0) + goto out; + ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x02); + if (ret < 0) + goto out; + + return; +out: + dev_err(pchip->dev, "i2c failed to access register\n"); + return; +} + +/* flash */ +static void lm3639_flash_brightness_set(struct led_classdev *cdev, + enum led_brightness brightness) +{ + int ret; + unsigned int reg_val; + struct lm3639_chip_data *pchip; + + pchip = container_of(cdev, struct lm3639_chip_data, cdev_flash); + + ret = regmap_read(pchip->regmap, REG_FLAG, ®_val); + if (ret < 0) + goto out; + if (reg_val != 0) + dev_info(pchip->dev, "last flag is 0x%x\n", reg_val); + + /* torch off before flash control */ + ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x00); + if (ret < 0) + goto out; + + /* brightness 0 means off state */ + if (!brightness) + return; + + ret = regmap_update_bits(pchip->regmap, + REG_FL_CONF_1, 0x0F, brightness - 1); + if (ret < 0) + goto out; + ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x06); + if (ret < 0) + goto out; + + return; +out: + dev_err(pchip->dev, "i2c failed to access register\n"); + return; +} + +static const struct regmap_config lm3639_regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = REG_MAX, +}; + +static int __devinit lm3639_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret; + struct lm3639_chip_data *pchip; + struct lm3639_platform_data *pdata = client->dev.platform_data; + struct backlight_properties props; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, "i2c functionality check fail.\n"); + return -EOPNOTSUPP; + } + + if (pdata == NULL) { + dev_err(&client->dev, "Needs Platform Data.\n"); + return -ENODATA; + } + + pchip = devm_kzalloc(&client->dev, + sizeof(struct lm3639_chip_data), GFP_KERNEL); + if (!pchip) + return -ENOMEM; + + pchip->pdata = pdata; + pchip->dev = &client->dev; + + pchip->regmap = devm_regmap_init_i2c(client, &lm3639_regmap); + if (IS_ERR(pchip->regmap)) { + ret = PTR_ERR(pchip->regmap); + dev_err(&client->dev, "fail : allocate register map: %d\n", + ret); + return ret; + } + i2c_set_clientdata(client, pchip); + + /* chip initialize */ + ret = lm3639_chip_init(pchip); + if (ret < 0) { + dev_err(&client->dev, "fail : chip init\n"); + goto err_out; + } + + /* backlight */ + props.type = BACKLIGHT_RAW; + props.brightness = pdata->init_brt_led; + props.max_brightness = pdata->max_brt_led; + pchip->bled = + backlight_device_register("lm3639_bled", pchip->dev, pchip, + &lm3639_bled_ops, &props); + if (IS_ERR(pchip->bled)) { + dev_err(&client->dev, "fail : backlight register\n"); + ret = -EIO; + goto err_out; + } + + ret = device_create_file(&(pchip->bled->dev), &dev_attr_bled_mode); + if (ret < 0) { + dev_err(&client->dev, "failed : add sysfs entries\n"); + ret = -EIO; + goto err_bled_mode; + } + + /* flash */ + pchip->cdev_flash.name = "lm3639_flash"; + pchip->cdev_flash.max_brightness = 16; + pchip->cdev_flash.brightness_set = lm3639_flash_brightness_set; + ret = led_classdev_register((struct device *) + &client->dev, &pchip->cdev_flash); + if (ret < 0) { + dev_err(&client->dev, "fail : flash register\n"); + ret = -EIO; + goto err_flash; + } + + /* torch */ + pchip->cdev_torch.name = "lm3639_torch"; + pchip->cdev_torch.max_brightness = 8; + pchip->cdev_torch.brightness_set = lm3639_torch_brightness_set; + ret = led_classdev_register((struct device *) + &client->dev, &pchip->cdev_torch); + if (ret < 0) { + dev_err(&client->dev, "fail : torch register\n"); + ret = -EIO; + goto err_torch; + } + + return 0; + +err_torch: + led_classdev_unregister(&pchip->cdev_flash); +err_flash: + device_remove_file(&(pchip->bled->dev), &dev_attr_bled_mode); +err_bled_mode: + backlight_device_unregister(pchip->bled); +err_out: + return ret; +} + +static int __devexit lm3639_remove(struct i2c_client *client) +{ + struct lm3639_chip_data *pchip = i2c_get_clientdata(client); + + regmap_write(pchip->regmap, REG_ENABLE, 0x00); + + if (&pchip->cdev_torch) + led_classdev_unregister(&pchip->cdev_torch); + if (&pchip->cdev_flash) + led_classdev_unregister(&pchip->cdev_flash); + if (pchip->bled) { + device_remove_file(&(pchip->bled->dev), &dev_attr_bled_mode); + backlight_device_unregister(pchip->bled); + } + return 0; +} + +static const struct i2c_device_id lm3639_id[] = { + {LM3639_NAME, 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, lm3639_id); +static struct i2c_driver lm3639_i2c_driver = { + .driver = { + .name = LM3639_NAME, + }, + .probe = lm3639_probe, + .remove = __devexit_p(lm3639_remove), + .id_table = lm3639_id, +}; + +module_i2c_driver(lm3639_i2c_driver); + +MODULE_DESCRIPTION("Texas Instruments Backlight+Flash LED driver for LM3639"); +MODULE_AUTHOR("Daniel Jeong "); +MODULE_AUTHOR("G.Shark Jeong "); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/platform_data/lm3639_bl.h b/include/linux/platform_data/lm3639_bl.h new file mode 100644 index 000000000000..5234cd5ed166 --- /dev/null +++ b/include/linux/platform_data/lm3639_bl.h @@ -0,0 +1,69 @@ +/* +* Simple driver for Texas Instruments LM3630 LED Flash driver chip +* Copyright (C) 2012 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. +* +*/ + +#ifndef __LINUX_LM3639_H +#define __LINUX_LM3639_H + +#define LM3639_NAME "lm3639_bl" + +enum lm3639_pwm { + LM3639_PWM_DISABLE = 0x00, + LM3639_PWM_EN_ACTLOW = 0x48, + LM3639_PWM_EN_ACTHIGH = 0x40, +}; + +enum lm3639_strobe { + LM3639_STROBE_DISABLE = 0x00, + LM3639_STROBE_EN_ACTLOW = 0x10, + LM3639_STROBE_EN_ACTHIGH = 0x30, +}; + +enum lm3639_txpin { + LM3639_TXPIN_DISABLE = 0x00, + LM3639_TXPIN_EN_ACTLOW = 0x04, + LM3639_TXPIN_EN_ACTHIGH = 0x0C, +}; + +enum lm3639_fleds { + LM3639_FLED_DIASBLE_ALL = 0x00, + LM3639_FLED_EN_1 = 0x40, + LM3639_FLED_EN_2 = 0x20, + LM3639_FLED_EN_ALL = 0x60, +}; + +enum lm3639_bleds { + LM3639_BLED_DIASBLE_ALL = 0x00, + LM3639_BLED_EN_1 = 0x10, + LM3639_BLED_EN_2 = 0x08, + LM3639_BLED_EN_ALL = 0x18, +}; +enum lm3639_bled_mode { + LM3639_BLED_MODE_EXPONETIAL = 0x00, + LM3639_BLED_MODE_LINEAR = 0x10, +}; + +struct lm3639_platform_data { + unsigned int max_brt_led; + unsigned int init_brt_led; + + /* input pins */ + enum lm3639_pwm pin_pwm; + enum lm3639_strobe pin_strobe; + enum lm3639_txpin pin_tx; + + /* output pins */ + enum lm3639_fleds fled_pins; + enum lm3639_bleds bled_pins; + enum lm3639_bled_mode bled_mode; + + void (*pwm_set_intensity) (int brightness, int max_brightness); + int (*pwm_get_intensity) (void); +}; +#endif /* __LINUX_LM3639_H */ -- cgit v1.2.3-58-ga151 From 56a2aba3c4c57ccbbb480f9e64e33aa752cb6a30 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Thu, 4 Oct 2012 17:12:57 -0700 Subject: backlight: remove ProGear driver This driver was for the ProGear webpad device which was produced in 2000/2001 and is not available on a market. I no longer have this hardware so can not even check how Linux works on it. Signed-off-by: Marcin Juszkiewicz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/Kconfig | 7 -- drivers/video/backlight/Makefile | 1 - drivers/video/backlight/progear_bl.c | 162 ----------------------------------- 3 files changed, 170 deletions(-) delete mode 100644 drivers/video/backlight/progear_bl.c (limited to 'drivers/video') diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 2b98fb8e711d..03e5719c914a 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -229,13 +229,6 @@ config BACKLIGHT_HP700 If you have an HP Jornada 700 series, say Y to include backlight control driver. -config BACKLIGHT_PROGEAR - tristate "Frontpath ProGear Backlight Driver" - depends on PCI && X86 - help - If you have a Frontpath ProGear say Y to enable the - backlight driver. - config BACKLIGHT_CARILLO_RANCH tristate "Intel Carillo Ranch Backlight Driver" depends on LCD_CLASS_DEVICE && PCI && X86 && FB_LE80578 diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index a151378da45b..7817e07f05f3 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -28,7 +28,6 @@ obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.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 diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c deleted file mode 100644 index 69b35f02929e..000000000000 --- a/drivers/video/backlight/progear_bl.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Backlight Driver for Frontpath ProGear HX1050+ - * - * Copyright (c) 2006 Marcin Juszkiewicz - * - * Based on Progear LCD driver by M Schacht - * - * - * Based on Sharp's Corgi Backlight Driver - * Based on Backlight Driver for HP Jornada 680 - * - * 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. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include - -#define PMU_LPCR 0xB0 -#define SB_MPS1 0x61 -#define HW_LEVEL_MAX 0x77 -#define HW_LEVEL_MIN 0x4f - -static struct pci_dev *pmu_dev = NULL; -static struct pci_dev *sb_dev = NULL; - -static int progearbl_set_intensity(struct backlight_device *bd) -{ - int intensity = bd->props.brightness; - - if (bd->props.power != FB_BLANK_UNBLANK) - intensity = 0; - if (bd->props.fb_blank != FB_BLANK_UNBLANK) - intensity = 0; - - pci_write_config_byte(pmu_dev, PMU_LPCR, intensity + HW_LEVEL_MIN); - - return 0; -} - -static int progearbl_get_intensity(struct backlight_device *bd) -{ - u8 intensity; - pci_read_config_byte(pmu_dev, PMU_LPCR, &intensity); - - return intensity - HW_LEVEL_MIN; -} - -static const struct backlight_ops progearbl_ops = { - .get_brightness = progearbl_get_intensity, - .update_status = progearbl_set_intensity, -}; - -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) { - pr_err("ALI M7101 PMU not found.\n"); - return -ENODEV; - } - - sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); - if (!sb_dev) { - pr_err("ALI 1533 SB not found.\n"); - 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.type = BACKLIGHT_RAW; - props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; - progear_backlight_device = backlight_device_register("progear-bl", - &pdev->dev, NULL, - &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; - 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) -{ - struct backlight_device *bd = platform_get_drvdata(pdev); - backlight_device_unregister(bd); - - return 0; -} - -static struct platform_driver progearbl_driver = { - .probe = progearbl_probe, - .remove = progearbl_remove, - .driver = { - .name = "progear-bl", - }, -}; - -static struct platform_device *progearbl_device; - -static int __init progearbl_init(void) -{ - int ret = platform_driver_register(&progearbl_driver); - - if (ret) - return ret; - progearbl_device = platform_device_register_simple("progear-bl", -1, - NULL, 0); - if (IS_ERR(progearbl_device)) { - platform_driver_unregister(&progearbl_driver); - return PTR_ERR(progearbl_device); - } - - return 0; -} - -static void __exit progearbl_exit(void) -{ - pci_dev_put(pmu_dev); - pci_dev_put(sb_dev); - - platform_device_unregister(progearbl_device); - platform_driver_unregister(&progearbl_driver); -} - -module_init(progearbl_init); -module_exit(progearbl_exit); - -MODULE_AUTHOR("Marcin Juszkiewicz "); -MODULE_DESCRIPTION("ProGear Backlight Driver"); -MODULE_LICENSE("GPL"); -- cgit v1.2.3-58-ga151 From 66be0e5bf5f555742a14a14712b537470dd2ba7e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 4 Oct 2012 17:12:59 -0700 Subject: drivers/video/backlight/da9052_bl.c: drop devm_kfree of devm_kzalloc'd data devm_kfree should not have to be explicitly used. The semantic patch that fixes this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression x,d; @@ x = devm_kzalloc(...) ... ?-devm_kfree(d,x); // Signed-off-by: Julia Lawall Acked-by: Jingoo Han Signed-off-by: Florian Tobias Schandinat Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/da9052_bl.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/backlight/da9052_bl.c b/drivers/video/backlight/da9052_bl.c index 10485c927ac6..ac196181fe45 100644 --- a/drivers/video/backlight/da9052_bl.c +++ b/drivers/video/backlight/da9052_bl.c @@ -129,7 +129,6 @@ static int da9052_backlight_probe(struct platform_device *pdev) &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); } @@ -149,7 +148,6 @@ static int da9052_backlight_remove(struct platform_device *pdev) wleds->state = DA9052_WLEDS_OFF; da9052_adjust_wled_brightness(wleds); backlight_device_unregister(bl); - devm_kfree(&pdev->dev, wleds); return 0; } -- cgit v1.2.3-58-ga151 From 52e842432f36d5b15227d0ee0d2aa3d2bc3cc0b2 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 4 Oct 2012 17:13:01 -0700 Subject: drivers/video/backlight/platform_lcd.c: add support for device tree based probe This patch adds the of_match_table to platform-lcd driver to be probed when platform-lcd device node is found in the device tree. [akpm@linux-foundation.org: include of.h] Signed-off-by: Jingoo Han Cc: Richard Purdie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/platform_lcd.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/video') diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c index b6672340d6c7..ca4f5d70fe10 100644 --- a/drivers/video/backlight/platform_lcd.c +++ b/drivers/video/backlight/platform_lcd.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include