PRCM: OMAP3: Fix to wrongly modified omap2_clk_wait_ready
[linux-ginger.git] / drivers / i2c / chips / lp5521.c
blob32664c0e1842f658951d609ffda2b25275d61ff5
1 /*
2 * drivers/i2c/chips/lp5521.c
4 * Copyright (C) 2007 Nokia Corporation
6 * Written by Mathias Nyman <mathias.nyman@nokia.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/i2c.h>
26 #include <linux/mutex.h>
27 #include <asm/arch/gpio.h>
29 #define LP5521_DRIVER_NAME "lp5521"
31 #ifdef LED_CONNECTED_WRONG
32 #define LP5521_REG_R_PWM 0x04
33 #define LP5521_REG_B_PWM 0x02
34 #else
35 #define LP5521_REG_R_PWM 0x02
36 #define LP5521_REG_B_PWM 0x04
37 #endif
38 #define LP5521_REG_ENABLE 0x00
39 #define LP5521_REG_OP_MODE 0x01
40 #define LP5521_REG_G_PWM 0x03
41 #define LP5521_REG_R_CNTRL 0x05
42 #define LP5521_REG_G_CNTRL 0x06
43 #define LP5521_REG_B_CNTRL 0x07
44 #define LP5521_REG_MISC 0x08
45 #define LP5521_REG_R_CHANNEL_PC 0x09
46 #define LP5521_REG_G_CHANNEL_PC 0x0a
47 #define LP5521_REG_B_CHANNEL_PC 0x0b
48 #define LP5521_REG_STATUS 0x0c
49 #define LP5521_REG_RESET 0x0d
50 #define LP5521_REG_GPO 0x0e
51 #define LP5521_REG_R_PROG_MEM 0x10
52 #define LP5521_REG_G_PROG_MEM 0x30
53 #define LP5521_REG_B_PROG_MEM 0x50
55 #define LP5521_MODE_LOAD "load"
56 #define LP5521_MODE_RUN "run"
57 #define LP5521_MODE_DIRECT_CONTROL "direct"
59 #define LP5521_CURRENT_1m5 0x0f
60 #define LP5521_CURRENT_3m1 0x1f
61 #define LP5521_CURRENT_4m7 0x2f
62 #define LP5521_CURRENT_6m3 0x3f
63 #define LP5521_CURRENT_7m9 0x4f
64 #define LP5521_CURRENT_9m5 0x5f
65 #define LP5521_CURRENT_11m1 0x6f
66 #define LP5521_CURRENT_12m7 0x7f
67 #define LP5521_CURRENT_14m3 0x8f
68 #define LP5521_CURRENT_15m9 0x9f
69 #define LP5521_CURRENT_17m5 0xaf
70 #define LP5521_CURRENT_19m1 0xbf
71 #define LP5521_CURRENT_20m7 0xcf
72 #define LP5521_CURRENT_22m3 0xdf
73 #define LP5521_CURRENT_23m9 0xef
74 #define LP5521_CURRENT_25m5 0xff
76 #define LP5521_PROGRAM_LENGTH 32 /* in bytes */
78 struct lp5521_chip {
79 struct mutex lock;
80 struct i2c_client *client;
81 char *mode;
82 int red;
83 int green;
84 int blue;
87 static int lp5521_set_mode(struct lp5521_chip *chip, char *mode);
89 static int lp5521_write(struct i2c_client *client, u8 reg, u8 value)
91 return i2c_smbus_write_byte_data(client, reg, value);
94 static int lp5521_read(struct i2c_client *client, u8 reg, u8 *buf)
96 s32 ret = i2c_smbus_read_byte_data(client, reg);
98 if (ret < 0)
99 return -EIO;
101 *buf = ret;
102 return 0;
105 static int lp5521_configure(struct i2c_client *client)
107 int ret = 0;
109 /* Enable chip and set light to logarithmic mode*/
110 ret |= lp5521_write(client, LP5521_REG_ENABLE, 0xc0);
112 /* setting all color pwms to direct control mode */
113 ret |= lp5521_write(client, LP5521_REG_OP_MODE, 0x3f);
115 /* setting current to 4.7 mA for all channels */
116 ret |= lp5521_write(client, LP5521_REG_R_CNTRL, LP5521_CURRENT_4m7);
117 ret |= lp5521_write(client, LP5521_REG_G_CNTRL, LP5521_CURRENT_4m7);
118 ret |= lp5521_write(client, LP5521_REG_B_CNTRL, LP5521_CURRENT_4m7);
120 /* Enable auto-powersave, set charge pump to auto, red to battery */
121 ret |= lp5521_write(client, LP5521_REG_MISC, 0x3c);
123 /* initialize all channels pwm to zero */
124 ret |= lp5521_write(client, LP5521_REG_R_PWM, 0);
125 ret |= lp5521_write(client, LP5521_REG_G_PWM, 0);
126 ret |= lp5521_write(client, LP5521_REG_B_PWM, 0);
128 /* Not much can be done about errors at this point */
129 return ret;
132 static int lp5521_load_program(struct lp5521_chip *chip, u8 *pattern)
134 struct i2c_client *client = chip->client;
135 int ret = 0;
137 /* Enter load program mode for all led channels */
138 ret |= lp5521_write(client, LP5521_REG_OP_MODE, 0x15); /* 0001 0101 */
139 if (ret)
140 return ret;
142 if (chip->red)
143 ret |= i2c_smbus_write_i2c_block_data(client,
144 LP5521_REG_R_PROG_MEM,
145 LP5521_PROGRAM_LENGTH,
146 pattern);
147 if (chip->green)
148 ret |= i2c_smbus_write_i2c_block_data(client,
149 LP5521_REG_G_PROG_MEM,
150 LP5521_PROGRAM_LENGTH,
151 pattern);
152 if (chip->blue)
153 ret |= i2c_smbus_write_i2c_block_data(client,
154 LP5521_REG_B_PROG_MEM,
155 LP5521_PROGRAM_LENGTH,
156 pattern);
158 return ret;
161 static int lp5521_run_program(struct lp5521_chip *chip)
163 struct i2c_client *client = chip->client;
164 int ret;
165 u8 mask = 0xc0;
166 u8 exec_state = 0;
167 u8 enable_reg;
169 ret = lp5521_read(client, LP5521_REG_ENABLE, &enable_reg);
170 if (ret)
171 goto fail;
173 enable_reg &= mask;
175 /* set all active channels exec state to countinous run*/
176 exec_state |= (chip->red << 5);
177 exec_state |= (chip->green << 3);
178 exec_state |= (chip->blue << 1);
180 enable_reg |= exec_state;
182 ret |= lp5521_write(client, LP5521_REG_ENABLE, enable_reg);
184 /* set op-mode to run for active channels, disabled for others */
185 ret |= lp5521_write(client, LP5521_REG_OP_MODE, exec_state);
187 fail:
188 return ret;
191 /*--------------------------------------------------------------*/
192 /* Sysfs interface */
193 /*--------------------------------------------------------------*/
195 static ssize_t show_active_channels(struct device *dev,
196 struct device_attribute *attr,
197 char *buf)
199 struct lp5521_chip *chip = dev_get_drvdata(dev);
200 char channels[4];
201 int pos = 0;
203 #ifdef LED_CONNECTED_WRONG
204 if (chip->blue)
205 pos += sprintf(channels + pos, "r");
206 if (chip->green)
207 pos += sprintf(channels + pos, "g");
208 if (chip->red)
209 pos += sprintf(channels + pos, "b");
211 #else
212 if (chip->red)
213 pos += sprintf(channels + pos, "r");
214 if (chip->green)
215 pos += sprintf(channels + pos, "g");
216 if (chip->blue)
217 pos += sprintf(channels + pos, "b");
218 #endif
220 channels[pos] = '\0';
222 return sprintf(buf, "%s\n", channels);
225 static ssize_t store_active_channels(struct device *dev,
226 struct device_attribute *attr,
227 const char *buf, size_t len)
229 struct lp5521_chip *chip = dev_get_drvdata(dev);
231 chip->red = 0;
232 chip->green = 0;
233 chip->blue = 0;
235 #ifdef LED_CONNECTED_WRONG
236 if (strchr(buf, 'r') != NULL)
237 chip->blue = 1;
238 if (strchr(buf, 'b') != NULL)
239 chip->red = 1;
240 #else
241 if (strchr(buf, 'r') != NULL)
242 chip->red = 1;
243 if (strchr(buf, 'b') != NULL)
244 chip->blue = 1;
245 #endif
246 if (strchr(buf, 'g') != NULL)
247 chip->green = 1;
249 return len;
252 static ssize_t show_color(struct device *dev,
253 struct device_attribute *attr,
254 char *buf)
256 struct i2c_client *client = to_i2c_client(dev);
257 int ret = 0;
258 u8 r, g, b;
260 ret |= lp5521_read(client, LP5521_REG_R_PWM, &r);
261 ret |= lp5521_read(client, LP5521_REG_G_PWM, &g);
262 ret |= lp5521_read(client, LP5521_REG_B_PWM, &b);
264 if (ret)
265 return ret;
267 return sprintf(buf, "%.2x:%.2x:%.2x\n", r, g, b);
270 static ssize_t store_color(struct device *dev,
271 struct device_attribute *attr,
272 const char *buf, size_t len)
274 struct i2c_client *client = to_i2c_client(dev);
275 struct lp5521_chip *chip = i2c_get_clientdata(client);
276 int ret;
277 unsigned r, g, b;
280 ret = sscanf(buf, "%2x:%2x:%2x", &r, &g, &b);
281 if (ret != 3)
282 return -EINVAL;
284 mutex_lock(&chip->lock);
286 ret = lp5521_write(client, LP5521_REG_R_PWM, (u8)r);
287 ret = lp5521_write(client, LP5521_REG_G_PWM, (u8)g);
288 ret = lp5521_write(client, LP5521_REG_B_PWM, (u8)b);
290 mutex_unlock(&chip->lock);
292 return len;
295 static ssize_t store_load(struct device *dev,
296 struct device_attribute *attr,
297 const char *buf, size_t len)
299 struct lp5521_chip *chip = dev_get_drvdata(dev);
300 int ret, nrchars, offset = 0, i = 0;
301 char c[3];
302 unsigned cmd;
303 u8 pattern[LP5521_PROGRAM_LENGTH] = {0};
305 while ((offset < len - 1) && (i < LP5521_PROGRAM_LENGTH)) {
307 /* separate sscanfs because length is working only for %s */
308 ret = sscanf(buf + offset, "%2s%n ", c, &nrchars);
309 ret = sscanf(c, "%2x", &cmd);
310 if (ret != 1)
311 goto fail;
312 pattern[i] = (u8)cmd;
314 offset += nrchars;
315 i++;
318 /* pattern commands are always two bytes long */
319 if (i % 2)
320 goto fail;
322 mutex_lock(&chip->lock);
324 ret = lp5521_load_program(chip, pattern);
325 mutex_unlock(&chip->lock);
327 if (ret) {
328 dev_err(dev, "lp5521 failed loading pattern\n");
329 return ret;
332 return len;
333 fail:
334 dev_err(dev, "lp5521 wrong pattern format\n");
335 return -EINVAL;
338 static ssize_t show_mode(struct device *dev,
339 struct device_attribute *attr,
340 char *buf)
342 struct lp5521_chip *chip = dev_get_drvdata(dev);
344 return sprintf(buf, "%s\n", chip->mode);
347 static ssize_t store_mode(struct device *dev,
348 struct device_attribute *attr,
349 const char *buf, size_t len)
351 struct lp5521_chip *chip = dev_get_drvdata(dev);
353 mutex_lock(&chip->lock);
355 if (!strncmp(buf, "run", 3))
356 lp5521_set_mode(chip, LP5521_MODE_RUN);
357 else if (!strncmp(buf, "load", 4))
358 lp5521_set_mode(chip, LP5521_MODE_LOAD);
359 else if (!strncmp(buf, "direct", 6))
360 lp5521_set_mode(chip, LP5521_MODE_DIRECT_CONTROL);
362 mutex_unlock(&chip->lock);
364 return len;
367 static ssize_t show_current(struct device *dev,
368 struct device_attribute *attr,
369 char *buf)
371 struct i2c_client *client = to_i2c_client(dev);
372 int ret = 0;
373 u8 r_curr, g_curr, b_curr;
375 ret |= lp5521_read(client, LP5521_REG_R_CNTRL, &r_curr);
376 ret |= lp5521_read(client, LP5521_REG_G_CNTRL, &g_curr);
377 ret |= lp5521_read(client, LP5521_REG_B_CNTRL, &b_curr);
379 if (ret)
380 return ret;
382 r_curr = r_curr >> 4;
383 g_curr = g_curr >> 4;
384 b_curr = b_curr >> 4;
386 if (r_curr == g_curr && g_curr == b_curr)
387 return sprintf(buf, "%x\n", r_curr);
388 else
389 return sprintf(buf, "%x %x %x\n", r_curr, g_curr, b_curr);
392 static ssize_t store_current(struct device *dev,
393 struct device_attribute *attr,
394 const char *buf, size_t len)
396 struct lp5521_chip *chip = dev_get_drvdata(dev);
397 struct i2c_client *client = chip->client;
398 int ret;
399 unsigned curr;
401 ret = sscanf(buf, "%1x", &curr);
402 if (ret != 1)
403 return -EINVAL;
405 /* current level is determined by the 4 upper bits, rest is ones */
406 curr = (curr << 4) | 0x0f;
408 mutex_lock(&chip->lock);
410 ret |= lp5521_write(client, LP5521_REG_R_CNTRL, (u8)curr);
411 ret |= lp5521_write(client, LP5521_REG_G_CNTRL, (u8)curr);
412 ret |= lp5521_write(client, LP5521_REG_B_CNTRL, (u8)curr);
414 mutex_unlock(&chip->lock);
416 return len;
419 static DEVICE_ATTR(color, S_IRUGO | S_IWUGO, show_color, store_color);
420 static DEVICE_ATTR(load, S_IWUGO, NULL, store_load);
421 static DEVICE_ATTR(mode, S_IRUGO | S_IWUGO, show_mode, store_mode);
422 static DEVICE_ATTR(active_channels, S_IRUGO | S_IWUGO,
423 show_active_channels, store_active_channels);
424 static DEVICE_ATTR(led_current, S_IRUGO | S_IWUGO, show_current, store_current);
426 static int lp5521_register_sysfs(struct i2c_client *client)
428 struct device *dev = &client->dev;
429 int ret;
431 ret = device_create_file(dev, &dev_attr_color);
432 if (ret)
433 goto fail1;
434 ret = device_create_file(dev, &dev_attr_load);
435 if (ret)
436 goto fail2;
437 ret = device_create_file(dev, &dev_attr_active_channels);
438 if (ret)
439 goto fail3;
440 ret = device_create_file(dev, &dev_attr_mode);
441 if (ret)
442 goto fail4;
443 ret = device_create_file(dev, &dev_attr_led_current);
444 if (ret)
445 goto fail5;
446 return 0;
448 fail5:
449 device_remove_file(dev, &dev_attr_mode);
450 fail4:
451 device_remove_file(dev, &dev_attr_active_channels);
452 fail3:
453 device_remove_file(dev, &dev_attr_load);
454 fail2:
455 device_remove_file(dev, &dev_attr_color);
456 fail1:
457 return ret;
460 static void lp5521_unregister_sysfs(struct i2c_client *client)
462 struct lp5521_chip *chip = i2c_get_clientdata(client);
463 struct device *dev = &client->dev;
465 device_remove_file(dev, &dev_attr_led_current);
466 device_remove_file(dev, &dev_attr_mode);
467 device_remove_file(dev, &dev_attr_active_channels);
468 device_remove_file(dev, &dev_attr_color);
470 if (!strcmp(chip->mode, LP5521_MODE_LOAD))
471 device_remove_file(dev, &dev_attr_load);
474 /*--------------------------------------------------------------*/
475 /* Set chip operating mode */
476 /*--------------------------------------------------------------*/
478 static int lp5521_set_mode(struct lp5521_chip *chip, char *mode)
480 struct i2c_client *client = chip->client ;
481 int ret = 0;
483 /* if in that mode already do nothing, except for run */
484 if (!strcmp(mode, chip->mode) && strcmp(mode, LP5521_MODE_RUN))
485 return 0;
487 if (!strcmp(mode, LP5521_MODE_RUN))
488 ret = lp5521_run_program(chip);
490 if (!strcmp(mode, LP5521_MODE_LOAD))
491 ret |= lp5521_write(client, LP5521_REG_OP_MODE, 0x15);
493 if (!strcmp(mode, LP5521_MODE_DIRECT_CONTROL))
494 ret |= lp5521_write(client, LP5521_REG_OP_MODE, 0x3F);
496 chip->mode = mode;
498 return ret;
501 /*--------------------------------------------------------------*/
502 /* Probe, Attach, Remove */
503 /*--------------------------------------------------------------*/
504 static struct i2c_driver lp5521_driver;
506 static int lp5521_probe(struct i2c_client *client,
507 const struct i2c_device_id *id)
509 struct lp5521_chip *chip;
510 int ret = 0;
512 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
513 if (!chip)
514 return -ENOMEM;
516 chip->client = client;
517 strncpy(client->name, LP5521_DRIVER_NAME, I2C_NAME_SIZE);
518 i2c_set_clientdata(client, chip);
520 mutex_init(&chip->lock);
522 ret = lp5521_configure(client);
523 if (ret < 0) {
524 dev_err(&client->dev, "lp5521 error configuring chip \n");
525 goto fail1;
528 /* Set default values */
529 chip->mode = LP5521_MODE_DIRECT_CONTROL;
530 chip->red = 1;
531 chip->green = 1;
532 chip->blue = 1;
534 ret = lp5521_register_sysfs(client);
535 if (ret)
536 dev_err(&client->dev, "lp5521 registering sysfs failed \n");
538 return ret;
540 fail1:
541 kfree(chip);
542 return ret;
545 static int lp5521_remove(struct i2c_client *client)
547 struct lp5521_chip *chip = i2c_get_clientdata(client);
549 lp5521_unregister_sysfs(client);
550 kfree(chip);
552 return 0;
555 static const struct i2c_device_id lp5521_id[] = {
556 { LP5521_DRIVER_NAME, 0},
557 { },
559 MODULE_DEVICE_TABLE(i2c, lp5521_id);
561 static struct i2c_driver lp5521_driver = {
562 .driver = {
563 .name = LP5521_DRIVER_NAME,
565 .probe = lp5521_probe,
566 .remove = __devexit_p(lp5521_remove),
567 .id_table = lp5521_id,
570 static int __init lp5521_init(void)
572 return i2c_add_driver(&lp5521_driver);
575 static void __exit lp5521_exit(void)
577 i2c_del_driver(&lp5521_driver);
580 MODULE_AUTHOR("Mathias Nyman <mathias.nyman@nokia.com>");
581 MODULE_DESCRIPTION("lp5521 LED driver");
582 MODULE_LICENSE("GPL");
584 module_init(lp5521_init);
585 module_exit(lp5521_exit);