aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Weitzel <j.weitzel@phytec.de>2011-05-24 20:13:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-25 11:39:50 -0400
commit3dbf622c153390dc3b038a23fb2847a4a607a802 (patch)
treefeb1e1d8f0c4758b7221e81f28fe82a65c12929d
parent3c1ab50d0a31b27bb4e55168f4901dd91e6e5ea4 (diff)
drivers/leds/leds-pca9532.c: add support pca9530, pca9531 and pca9533
The pca953x family are only different in number of leds and register layout Adding chipinfo to use driver with whole pca953x family Rename driver to pca953x, but left files and platformflags named pca9532. Tested with pca9530 and pca9533 Tested-by: Juergen Kilb <j.kilb@phytec.de> Signed-off-by: Jan Weitzel <j.weitzel@phytec.de> Acked-by: Joachim Eastwood <joachim.eastwood@jotron.com> Tested-by: Joachim Eastwood <joachim.eastwood@jotron.com> Cc: Wolfram Sang <w.sang@pengutronix.de> Cc: H Hartley Sweeten <hsweeten@visionengravers.com> Cc: Richard Purdie <rpurdie@rpsys.net> Cc: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/leds/leds-pca9532.c84
1 files changed, 62 insertions, 22 deletions
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index ebea85603f43..d8d3a1e910a1 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -1,13 +1,14 @@
1/* 1/*
2 * pca9532.c - 16-bit Led dimmer 2 * pca9532.c - 16-bit Led dimmer
3 * 3 *
4 * Copyright (C) 2011 Jan Weitzel
4 * Copyright (C) 2008 Riku Voipio 5 * Copyright (C) 2008 Riku Voipio
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License. 9 * the Free Software Foundation; version 2 of the License.
9 * 10 *
10 * Datasheet: http://www.nxp.com/acrobat/datasheets/PCA9532_3.pdf 11 * Datasheet: http://www.nxp.com/documents/data_sheet/PCA9532.pdf
11 * 12 *
12 */ 13 */
13 14
@@ -21,15 +22,20 @@
21#include <linux/leds-pca9532.h> 22#include <linux/leds-pca9532.h>
22#include <linux/gpio.h> 23#include <linux/gpio.h>
23 24
24#define PCA9532_REG_INPUT(i) ((i)/8) 25/* m = num_leds*/
25#define PCA9532_REG_PSC(i) (0x2+(i)*2) 26#define PCA9532_REG_INPUT(i) ((i) >> 3)
26#define PCA9532_REG_PWM(i) (0x3+(i)*2) 27#define PCA9532_REG_OFFSET(m) ((m) >> 4)
27#define PCA9532_REG_LS0 0x6 28#define PCA9532_REG_PSC(m, i) (PCA9532_REG_OFFSET(m) + 0x1 + (i) * 2)
28#define LED_REG(led) ((led>>2)+PCA9532_REG_LS0) 29#define PCA9532_REG_PWM(m, i) (PCA9532_REG_OFFSET(m) + 0x2 + (i) * 2)
29#define LED_NUM(led) (led & 0x3) 30#define LED_REG(m, led) (PCA9532_REG_OFFSET(m) + 0x5 + (led >> 2))
31#define LED_NUM(led) (led & 0x3)
30 32
31#define ldev_to_led(c) container_of(c, struct pca9532_led, ldev) 33#define ldev_to_led(c) container_of(c, struct pca9532_led, ldev)
32 34
35struct pca9532_chip_info {
36 u8 num_leds;
37};
38
33struct pca9532_data { 39struct pca9532_data {
34 struct i2c_client *client; 40 struct i2c_client *client;
35 struct pca9532_led leds[16]; 41 struct pca9532_led leds[16];
@@ -39,6 +45,7 @@ struct pca9532_data {
39#ifdef CONFIG_LEDS_PCA9532_GPIO 45#ifdef CONFIG_LEDS_PCA9532_GPIO
40 struct gpio_chip gpio; 46 struct gpio_chip gpio;
41#endif 47#endif
48 const struct pca9532_chip_info *chip_info;
42 u8 pwm[2]; 49 u8 pwm[2];
43 u8 psc[2]; 50 u8 psc[2];
44}; 51};
@@ -47,16 +54,41 @@ static int pca9532_probe(struct i2c_client *client,
47 const struct i2c_device_id *id); 54 const struct i2c_device_id *id);
48static int pca9532_remove(struct i2c_client *client); 55static int pca9532_remove(struct i2c_client *client);
49 56
57enum {
58 pca9530,
59 pca9531,
60 pca9532,
61 pca9533,
62};
63
50static const struct i2c_device_id pca9532_id[] = { 64static const struct i2c_device_id pca9532_id[] = {
51 { "pca9532", 0 }, 65 { "pca9530", pca9530 },
66 { "pca9531", pca9531 },
67 { "pca9532", pca9532 },
68 { "pca9533", pca9533 },
52 { } 69 { }
53}; 70};
54 71
55MODULE_DEVICE_TABLE(i2c, pca9532_id); 72MODULE_DEVICE_TABLE(i2c, pca9532_id);
56 73
74static const struct pca9532_chip_info pca9532_chip_info_tbl[] = {
75 [pca9530] = {
76 .num_leds = 2,
77 },
78 [pca9531] = {
79 .num_leds = 8,
80 },
81 [pca9532] = {
82 .num_leds = 16,
83 },
84 [pca9533] = {
85 .num_leds = 4,
86 },
87};
88
57static struct i2c_driver pca9532_driver = { 89static struct i2c_driver pca9532_driver = {
58 .driver = { 90 .driver = {
59 .name = "pca9532", 91 .name = "pca953x",
60 }, 92 },
61 .probe = pca9532_probe, 93 .probe = pca9532_probe,
62 .remove = pca9532_remove, 94 .remove = pca9532_remove,
@@ -73,7 +105,7 @@ static int pca9532_calcpwm(struct i2c_client *client, int pwm, int blink,
73{ 105{
74 int a = 0, b = 0, i = 0; 106 int a = 0, b = 0, i = 0;
75 struct pca9532_data *data = i2c_get_clientdata(client); 107 struct pca9532_data *data = i2c_get_clientdata(client);
76 for (i = 0; i < 16; i++) { 108 for (i = 0; i < data->chip_info->num_leds; i++) {
77 if (data->leds[i].type == PCA9532_TYPE_LED && 109 if (data->leds[i].type == PCA9532_TYPE_LED &&
78 data->leds[i].state == PCA9532_PWM0+pwm) { 110 data->leds[i].state == PCA9532_PWM0+pwm) {
79 a++; 111 a++;
@@ -97,10 +129,12 @@ static int pca9532_calcpwm(struct i2c_client *client, int pwm, int blink,
97static int pca9532_setpwm(struct i2c_client *client, int pwm) 129static int pca9532_setpwm(struct i2c_client *client, int pwm)
98{ 130{
99 struct pca9532_data *data = i2c_get_clientdata(client); 131 struct pca9532_data *data = i2c_get_clientdata(client);
132 u8 maxleds = data->chip_info->num_leds;
133
100 mutex_lock(&data->update_lock); 134 mutex_lock(&data->update_lock);
101 i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(pwm), 135 i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(maxleds, pwm),
102 data->pwm[pwm]); 136 data->pwm[pwm]);
103 i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(pwm), 137 i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(maxleds, pwm),
104 data->psc[pwm]); 138 data->psc[pwm]);
105 mutex_unlock(&data->update_lock); 139 mutex_unlock(&data->update_lock);
106 return 0; 140 return 0;
@@ -111,15 +145,16 @@ static void pca9532_setled(struct pca9532_led *led)
111{ 145{
112 struct i2c_client *client = led->client; 146 struct i2c_client *client = led->client;
113 struct pca9532_data *data = i2c_get_clientdata(client); 147 struct pca9532_data *data = i2c_get_clientdata(client);
148 u8 maxleds = data->chip_info->num_leds;
114 char reg; 149 char reg;
115 150
116 mutex_lock(&data->update_lock); 151 mutex_lock(&data->update_lock);
117 reg = i2c_smbus_read_byte_data(client, LED_REG(led->id)); 152 reg = i2c_smbus_read_byte_data(client, LED_REG(maxleds, led->id));
118 /* zero led bits */ 153 /* zero led bits */
119 reg = reg & ~(0x3<<LED_NUM(led->id)*2); 154 reg = reg & ~(0x3<<LED_NUM(led->id)*2);
120 /* set the new value */ 155 /* set the new value */
121 reg = reg | (led->state << LED_NUM(led->id)*2); 156 reg = reg | (led->state << LED_NUM(led->id)*2);
122 i2c_smbus_write_byte_data(client, LED_REG(led->id), reg); 157 i2c_smbus_write_byte_data(client, LED_REG(maxleds, led->id), reg);
123 mutex_unlock(&data->update_lock); 158 mutex_unlock(&data->update_lock);
124} 159}
125 160
@@ -188,10 +223,12 @@ static int pca9532_event(struct input_dev *dev, unsigned int type,
188 223
189static void pca9532_input_work(struct work_struct *work) 224static void pca9532_input_work(struct work_struct *work)
190{ 225{
191 struct pca9532_data *data; 226 struct pca9532_data *data =
192 data = container_of(work, struct pca9532_data, work); 227 container_of(work, struct pca9532_data, work);
228 u8 maxleds = data->chip_info->num_leds;
229
193 mutex_lock(&data->update_lock); 230 mutex_lock(&data->update_lock);
194 i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(1), 231 i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(maxleds, 1),
195 data->pwm[1]); 232 data->pwm[1]);
196 mutex_unlock(&data->update_lock); 233 mutex_unlock(&data->update_lock);
197} 234}
@@ -301,17 +338,18 @@ static int pca9532_configure(struct i2c_client *client,
301{ 338{
302 int i, err = 0; 339 int i, err = 0;
303 int gpios = 0; 340 int gpios = 0;
341 u8 maxleds = data->chip_info->num_leds;
304 342
305 for (i = 0; i < 2; i++) { 343 for (i = 0; i < 2; i++) {
306 data->pwm[i] = pdata->pwm[i]; 344 data->pwm[i] = pdata->pwm[i];
307 data->psc[i] = pdata->psc[i]; 345 data->psc[i] = pdata->psc[i];
308 i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(i), 346 i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(maxleds, i),
309 data->pwm[i]); 347 data->pwm[i]);
310 i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(i), 348 i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(maxleds, i),
311 data->psc[i]); 349 data->psc[i]);
312 } 350 }
313 351
314 for (i = 0; i < 16; i++) { 352 for (i = 0; i < data->chip_info->num_leds; i++) {
315 struct pca9532_led *led = &data->leds[i]; 353 struct pca9532_led *led = &data->leds[i];
316 struct pca9532_led *pled = &pdata->leds[i]; 354 struct pca9532_led *pled = &pdata->leds[i];
317 led->client = client; 355 led->client = client;
@@ -382,7 +420,7 @@ static int pca9532_configure(struct i2c_client *client,
382 data->gpio.request = pca9532_gpio_request_pin; 420 data->gpio.request = pca9532_gpio_request_pin;
383 data->gpio.can_sleep = 1; 421 data->gpio.can_sleep = 1;
384 data->gpio.base = pdata->gpio_base; 422 data->gpio.base = pdata->gpio_base;
385 data->gpio.ngpio = 16; 423 data->gpio.ngpio = data->chip_info->num_leds;
386 data->gpio.dev = &client->dev; 424 data->gpio.dev = &client->dev;
387 data->gpio.owner = THIS_MODULE; 425 data->gpio.owner = THIS_MODULE;
388 426
@@ -424,6 +462,8 @@ static int pca9532_probe(struct i2c_client *client,
424 if (!data) 462 if (!data)
425 return -ENOMEM; 463 return -ENOMEM;
426 464
465 data->chip_info = &pca9532_chip_info_tbl[id->driver_data];
466
427 dev_info(&client->dev, "setting platform data\n"); 467 dev_info(&client->dev, "setting platform data\n");
428 i2c_set_clientdata(client, data); 468 i2c_set_clientdata(client, data);
429 data->client = client; 469 data->client = client;
@@ -441,7 +481,7 @@ static int pca9532_remove(struct i2c_client *client)
441 struct pca9532_data *data = i2c_get_clientdata(client); 481 struct pca9532_data *data = i2c_get_clientdata(client);
442 int err; 482 int err;
443 483
444 err = pca9532_destroy_devices(data, 16); 484 err = pca9532_destroy_devices(data, data->chip_info->num_leds);
445 if (err) 485 if (err)
446 return err; 486 return err;
447 487