mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 19:51:31 -04:00
Merge branch 'akpm' (Andrew's patch-bomb)
Merge misc patches from Andrew Morton: "The MM tree is rather stuck while I wait to find out what the heck is happening with sched/numa. Probably I'll need to route around all the code which was added to -next, sigh. So this is "everything else", or at least most of it - other small bits are still awaiting resolutions of various kinds." * emailed patches from Andrew Morton <[email protected]>: (180 commits) lib/decompress.c add __init to decompress_method and data kernel/resource.c: fix stack overflow in __reserve_region_with_split() omfs: convert to use beXX_add_cpu() taskstats: cgroupstats_user_cmd() may leak on error aoe: update aoe-internal version number to 50 aoe: update documentation to better reflect aoe-plus-udev usage aoe: remove unused code aoe: make dynamic block minor numbers the default aoe: update and specify AoE address guards and error messages aoe: retain static block device numbers for backwards compatibility aoe: support more AoE addresses with dynamic block device minor numbers aoe: update documentation with new URL and VM settings reference aoe: update copyright year in touched files aoe: update internal version number to 49 aoe: remove unused code and add cosmetic improvements aoe: increase net_device reference count while using it aoe: associate frames with the AoE storage target aoe: disallow unsupported AoE minor addresses aoe: do revalidation steps in order aoe: failover remote interface based on aoe_deadsecs parameter ...
This commit is contained in:
commit
11126c611e
308 changed files with 7393 additions and 2728 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -352,6 +345,22 @@ 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_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
|
||||
|
|
|
|||
|
|
@ -23,10 +23,11 @@ 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_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
|
||||
|
|
|
|||
|
|
@ -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],
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
475
drivers/video/backlight/lm3630_bl.c
Normal file
475
drivers/video/backlight/lm3630_bl.c
Normal file
|
|
@ -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 <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/platform_data/lm3630_bl.h>
|
||||
|
||||
#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 <[email protected]>");
|
||||
MODULE_AUTHOR("Daniel Jeong <[email protected]>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
437
drivers/video/backlight/lm3639_bl.c
Normal file
437
drivers/video/backlight/lm3639_bl.c
Normal file
|
|
@ -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 <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/platform_data/lm3639_bl.h>
|
||||
|
||||
#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 <[email protected]>");
|
||||
MODULE_AUTHOR("G.Shark Jeong <[email protected]>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/fb.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/lcd.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <video/platform_lcd.h>
|
||||
|
|
@ -145,6 +146,14 @@ static SIMPLE_DEV_PM_OPS(platform_lcd_pm_ops, platform_lcd_suspend,
|
|||
platform_lcd_resume);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id platform_lcd_of_match[] = {
|
||||
{ .compatible = "platform-lcd" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, platform_lcd_of_match);
|
||||
#endif
|
||||
|
||||
static struct platform_driver platform_lcd_driver = {
|
||||
.driver = {
|
||||
.name = "platform-lcd",
|
||||
|
|
@ -152,6 +161,7 @@ static struct platform_driver platform_lcd_driver = {
|
|||
#ifdef CONFIG_PM
|
||||
.pm = &platform_lcd_pm_ops,
|
||||
#endif
|
||||
.of_match_table = of_match_ptr(platform_lcd_of_match),
|
||||
},
|
||||
.probe = platform_lcd_probe,
|
||||
.remove = __devexit_p(platform_lcd_remove),
|
||||
|
|
|
|||
|
|
@ -1,162 +0,0 @@
|
|||
/*
|
||||
* Backlight Driver for Frontpath ProGear HX1050+
|
||||
*
|
||||
* Copyright (c) 2006 Marcin Juszkiewicz
|
||||
*
|
||||
* Based on Progear LCD driver by M Schacht
|
||||
* <mschacht at alumni dot washington dot edu>
|
||||
*
|
||||
* 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 <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#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 <[email protected]>");
|
||||
MODULE_DESCRIPTION("ProGear Backlight Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -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 },
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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" ,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue