diff options
author | Michael Hennerich <michael.hennerich@analog.com> | 2010-05-26 03:00:59 -0400 |
---|---|---|
committer | Richard Purdie <rpurdie@linux.intel.com> | 2010-05-26 08:08:33 -0400 |
commit | c7c06d8a95fd6b83d9f71a0cfecd3f91945d17e5 (patch) | |
tree | 7e3d5f037fbf47846b6c48a8fb3ae9dcfd3d50d3 /drivers/video/backlight | |
parent | ed601fa46777cb529bda0dbec80c4aec704dd063 (diff) |
backlight: adp8860: add support for ADP8861 & ADP8863
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'drivers/video/backlight')
-rw-r--r-- | drivers/video/backlight/Kconfig | 6 | ||||
-rw-r--r-- | drivers/video/backlight/adp8860_bl.c | 58 |
2 files changed, 44 insertions, 20 deletions
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 2d8052182960..39ecaf71c1f9 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -275,13 +275,13 @@ config BACKLIGHT_ADP5520 | |||
275 | be called adp5520_bl. | 275 | be called adp5520_bl. |
276 | 276 | ||
277 | config BACKLIGHT_ADP8860 | 277 | config BACKLIGHT_ADP8860 |
278 | tristate "Backlight Driver for ADP8860 using WLED" | 278 | tristate "Backlight Driver for ADP8860/ADP8861/ADP8863 using WLED" |
279 | depends on BACKLIGHT_CLASS_DEVICE && I2C | 279 | depends on BACKLIGHT_CLASS_DEVICE && I2C |
280 | select NEW_LEDS | 280 | select NEW_LEDS |
281 | select LEDS_CLASS | 281 | select LEDS_CLASS |
282 | help | 282 | help |
283 | If you have a LCD backlight connected to the ADP8860, | 283 | If you have a LCD backlight connected to the ADP8860, ADP8861 or |
284 | say Y here to enable this driver. | 284 | ADP8863 say Y here to enable this driver. |
285 | 285 | ||
286 | To compile this driver as a module, choose M here: the module will | 286 | To compile this driver as a module, choose M here: the module will |
287 | be called adp8860_bl. | 287 | be called adp8860_bl. |
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c index 99d14ed88571..921ca37398f3 100644 --- a/drivers/video/backlight/adp8860_bl.c +++ b/drivers/video/backlight/adp8860_bl.c | |||
@@ -62,7 +62,9 @@ | |||
62 | #define ADP8860_PH2LEVH 0x24 /* Second phototransistor ambient light level-high byte register */ | 62 | #define ADP8860_PH2LEVH 0x24 /* Second phototransistor ambient light level-high byte register */ |
63 | 63 | ||
64 | #define ADP8860_MANUFID 0x0 /* Analog Devices ADP8860 Manufacturer ID */ | 64 | #define ADP8860_MANUFID 0x0 /* Analog Devices ADP8860 Manufacturer ID */ |
65 | #define ADP8860_DEVICEID 0x7 /* Analog Devices ADP8860 Device ID */ | 65 | #define ADP8861_MANUFID 0x4 /* Analog Devices ADP8861 Manufacturer ID */ |
66 | #define ADP8863_MANUFID 0x2 /* Analog Devices ADP8863 Manufacturer ID */ | ||
67 | |||
66 | #define ADP8860_DEVID(x) ((x) & 0xF) | 68 | #define ADP8860_DEVID(x) ((x) & 0xF) |
67 | #define ADP8860_MANID(x) ((x) >> 4) | 69 | #define ADP8860_MANID(x) ((x) >> 4) |
68 | 70 | ||
@@ -70,6 +72,7 @@ | |||
70 | #define INT_CFG (1 << 6) | 72 | #define INT_CFG (1 << 6) |
71 | #define NSTBY (1 << 5) | 73 | #define NSTBY (1 << 5) |
72 | #define DIM_EN (1 << 4) | 74 | #define DIM_EN (1 << 4) |
75 | #define GDWN_DIS (1 << 3) | ||
73 | #define SIS_EN (1 << 2) | 76 | #define SIS_EN (1 << 2) |
74 | #define CMP_AUTOEN (1 << 1) | 77 | #define CMP_AUTOEN (1 << 1) |
75 | #define BLEN (1 << 0) | 78 | #define BLEN (1 << 0) |
@@ -86,6 +89,12 @@ | |||
86 | #define BL_CFGR_VAL(law, blv) ((((blv) & CFGR_BLV_MASK) << CFGR_BLV_SHIFT) | ((0x3 & (law)) << 1)) | 89 | #define BL_CFGR_VAL(law, blv) ((((blv) & CFGR_BLV_MASK) << CFGR_BLV_SHIFT) | ((0x3 & (law)) << 1)) |
87 | #define ALS_CCFG_VAL(filt) ((0x7 & filt) << 5) | 90 | #define ALS_CCFG_VAL(filt) ((0x7 & filt) << 5) |
88 | 91 | ||
92 | enum { | ||
93 | adp8860, | ||
94 | adp8861, | ||
95 | adp8863 | ||
96 | }; | ||
97 | |||
89 | struct adp8860_led { | 98 | struct adp8860_led { |
90 | struct led_classdev cdev; | 99 | struct led_classdev cdev; |
91 | struct work_struct work; | 100 | struct work_struct work; |
@@ -105,6 +114,8 @@ struct adp8860_bl { | |||
105 | int id; | 114 | int id; |
106 | int revid; | 115 | int revid; |
107 | int current_brightness; | 116 | int current_brightness; |
117 | unsigned en_ambl_sens:1; | ||
118 | unsigned gdwn_dis:1; | ||
108 | }; | 119 | }; |
109 | 120 | ||
110 | static int adp8860_read(struct i2c_client *client, int reg, uint8_t *val) | 121 | static int adp8860_read(struct i2c_client *client, int reg, uint8_t *val) |
@@ -121,7 +132,6 @@ static int adp8860_read(struct i2c_client *client, int reg, uint8_t *val) | |||
121 | return 0; | 132 | return 0; |
122 | } | 133 | } |
123 | 134 | ||
124 | |||
125 | static int adp8860_write(struct i2c_client *client, u8 reg, u8 val) | 135 | static int adp8860_write(struct i2c_client *client, u8 reg, u8 val) |
126 | { | 136 | { |
127 | return i2c_smbus_write_byte_data(client, reg, val); | 137 | return i2c_smbus_write_byte_data(client, reg, val); |
@@ -321,7 +331,7 @@ static int adp8860_bl_set(struct backlight_device *bl, int brightness) | |||
321 | struct i2c_client *client = data->client; | 331 | struct i2c_client *client = data->client; |
322 | int ret = 0; | 332 | int ret = 0; |
323 | 333 | ||
324 | if (data->pdata->en_ambl_sens) { | 334 | if (data->en_ambl_sens) { |
325 | if ((brightness > 0) && (brightness < ADP8860_MAX_BRIGHTNESS)) { | 335 | if ((brightness > 0) && (brightness < ADP8860_MAX_BRIGHTNESS)) { |
326 | /* Disable Ambient Light auto adjust */ | 336 | /* Disable Ambient Light auto adjust */ |
327 | ret |= adp8860_clr_bits(client, ADP8860_MDCR, | 337 | ret |= adp8860_clr_bits(client, ADP8860_MDCR, |
@@ -388,7 +398,7 @@ static int adp8860_bl_setup(struct backlight_device *bl) | |||
388 | ret |= adp8860_write(client, ADP8860_BLMX1, pdata->l1_daylight_max); | 398 | ret |= adp8860_write(client, ADP8860_BLMX1, pdata->l1_daylight_max); |
389 | ret |= adp8860_write(client, ADP8860_BLDM1, pdata->l1_daylight_dim); | 399 | ret |= adp8860_write(client, ADP8860_BLDM1, pdata->l1_daylight_dim); |
390 | 400 | ||
391 | if (pdata->en_ambl_sens) { | 401 | if (data->en_ambl_sens) { |
392 | data->cached_daylight_max = pdata->l1_daylight_max; | 402 | data->cached_daylight_max = pdata->l1_daylight_max; |
393 | ret |= adp8860_write(client, ADP8860_BLMX2, | 403 | ret |= adp8860_write(client, ADP8860_BLMX2, |
394 | pdata->l2_office_max); | 404 | pdata->l2_office_max); |
@@ -413,7 +423,8 @@ static int adp8860_bl_setup(struct backlight_device *bl) | |||
413 | ret |= adp8860_write(client, ADP8860_BLFR, FADE_VAL(pdata->bl_fade_in, | 423 | ret |= adp8860_write(client, ADP8860_BLFR, FADE_VAL(pdata->bl_fade_in, |
414 | pdata->bl_fade_out)); | 424 | pdata->bl_fade_out)); |
415 | 425 | ||
416 | ret |= adp8860_set_bits(client, ADP8860_MDCR, BLEN | DIM_EN | NSTBY); | 426 | ret |= adp8860_set_bits(client, ADP8860_MDCR, BLEN | DIM_EN | NSTBY | |
427 | (data->gdwn_dis ? GDWN_DIS : 0)); | ||
417 | 428 | ||
418 | return ret; | 429 | return ret; |
419 | } | 430 | } |
@@ -663,19 +674,29 @@ static int __devinit adp8860_probe(struct i2c_client *client, | |||
663 | return -EINVAL; | 674 | return -EINVAL; |
664 | } | 675 | } |
665 | 676 | ||
677 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
678 | if (data == NULL) | ||
679 | return -ENOMEM; | ||
680 | |||
666 | ret = adp8860_read(client, ADP8860_MFDVID, ®_val); | 681 | ret = adp8860_read(client, ADP8860_MFDVID, ®_val); |
667 | if (ret < 0) | 682 | if (ret < 0) |
668 | return -EIO; | 683 | goto out2; |
669 | 684 | ||
670 | if (ADP8860_MANID(reg_val) != ADP8860_MANUFID) { | 685 | switch (ADP8860_MANID(reg_val)) { |
686 | case ADP8863_MANUFID: | ||
687 | data->gdwn_dis = !!pdata->gdwn_dis; | ||
688 | case ADP8860_MANUFID: | ||
689 | data->en_ambl_sens = !!pdata->en_ambl_sens; | ||
690 | break; | ||
691 | case ADP8861_MANUFID: | ||
692 | data->gdwn_dis = !!pdata->gdwn_dis; | ||
693 | break; | ||
694 | default: | ||
671 | dev_err(&client->dev, "failed to probe\n"); | 695 | dev_err(&client->dev, "failed to probe\n"); |
672 | return -ENODEV; | 696 | ret = -ENODEV; |
697 | goto out2; | ||
673 | } | 698 | } |
674 | 699 | ||
675 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
676 | if (data == NULL) | ||
677 | return -ENOMEM; | ||
678 | |||
679 | /* It's confirmed that the DEVID field is actually a REVID */ | 700 | /* It's confirmed that the DEVID field is actually a REVID */ |
680 | 701 | ||
681 | data->revid = ADP8860_DEVID(reg_val); | 702 | data->revid = ADP8860_DEVID(reg_val); |
@@ -703,7 +724,7 @@ static int __devinit adp8860_probe(struct i2c_client *client, | |||
703 | 724 | ||
704 | data->bl = bl; | 725 | data->bl = bl; |
705 | 726 | ||
706 | if (pdata->en_ambl_sens) | 727 | if (data->en_ambl_sens) |
707 | ret = sysfs_create_group(&bl->dev.kobj, | 728 | ret = sysfs_create_group(&bl->dev.kobj, |
708 | &adp8860_bl_attr_group); | 729 | &adp8860_bl_attr_group); |
709 | 730 | ||
@@ -720,7 +741,8 @@ static int __devinit adp8860_probe(struct i2c_client *client, | |||
720 | 741 | ||
721 | backlight_update_status(bl); | 742 | backlight_update_status(bl); |
722 | 743 | ||
723 | dev_info(&client->dev, "Rev.%d Backlight\n", data->revid); | 744 | dev_info(&client->dev, "%s Rev.%d Backlight\n", |
745 | client->name, data->revid); | ||
724 | 746 | ||
725 | if (pdata->num_leds) | 747 | if (pdata->num_leds) |
726 | adp8860_led_probe(client); | 748 | adp8860_led_probe(client); |
@@ -728,7 +750,7 @@ static int __devinit adp8860_probe(struct i2c_client *client, | |||
728 | return 0; | 750 | return 0; |
729 | 751 | ||
730 | out: | 752 | out: |
731 | if (data->pdata->en_ambl_sens) | 753 | if (data->en_ambl_sens) |
732 | sysfs_remove_group(&data->bl->dev.kobj, | 754 | sysfs_remove_group(&data->bl->dev.kobj, |
733 | &adp8860_bl_attr_group); | 755 | &adp8860_bl_attr_group); |
734 | out1: | 756 | out1: |
@@ -749,7 +771,7 @@ static int __devexit adp8860_remove(struct i2c_client *client) | |||
749 | if (data->led) | 771 | if (data->led) |
750 | adp8860_led_remove(client); | 772 | adp8860_led_remove(client); |
751 | 773 | ||
752 | if (data->pdata->en_ambl_sens) | 774 | if (data->en_ambl_sens) |
753 | sysfs_remove_group(&data->bl->dev.kobj, | 775 | sysfs_remove_group(&data->bl->dev.kobj, |
754 | &adp8860_bl_attr_group); | 776 | &adp8860_bl_attr_group); |
755 | 777 | ||
@@ -780,7 +802,9 @@ static int adp8860_i2c_resume(struct i2c_client *client) | |||
780 | #endif | 802 | #endif |
781 | 803 | ||
782 | static const struct i2c_device_id adp8860_id[] = { | 804 | static const struct i2c_device_id adp8860_id[] = { |
783 | { "adp8860", 0 }, | 805 | { "adp8860", adp8860 }, |
806 | { "adp8861", adp8861 }, | ||
807 | { "adp8863", adp8863 }, | ||
784 | { } | 808 | { } |
785 | }; | 809 | }; |
786 | MODULE_DEVICE_TABLE(i2c, adp8860_id); | 810 | MODULE_DEVICE_TABLE(i2c, adp8860_id); |