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
35 #define LP5521_REG_R_PWM 0x02
36 #define LP5521_REG_B_PWM 0x04
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 */
80 struct i2c_client
*client
;
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
);
105 static int lp5521_configure(struct i2c_client
*client
)
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 */
132 static int lp5521_load_program(struct lp5521_chip
*chip
, u8
*pattern
)
134 struct i2c_client
*client
= chip
->client
;
137 /* Enter load program mode for all led channels */
138 ret
|= lp5521_write(client
, LP5521_REG_OP_MODE
, 0x15); /* 0001 0101 */
143 ret
|= i2c_smbus_write_i2c_block_data(client
,
144 LP5521_REG_R_PROG_MEM
,
145 LP5521_PROGRAM_LENGTH
,
148 ret
|= i2c_smbus_write_i2c_block_data(client
,
149 LP5521_REG_G_PROG_MEM
,
150 LP5521_PROGRAM_LENGTH
,
153 ret
|= i2c_smbus_write_i2c_block_data(client
,
154 LP5521_REG_B_PROG_MEM
,
155 LP5521_PROGRAM_LENGTH
,
161 static int lp5521_run_program(struct lp5521_chip
*chip
)
163 struct i2c_client
*client
= chip
->client
;
169 ret
= lp5521_read(client
, LP5521_REG_ENABLE
, &enable_reg
);
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
);
191 /*--------------------------------------------------------------*/
192 /* Sysfs interface */
193 /*--------------------------------------------------------------*/
195 static ssize_t
show_active_channels(struct device
*dev
,
196 struct device_attribute
*attr
,
199 struct lp5521_chip
*chip
= dev_get_drvdata(dev
);
203 #ifdef LED_CONNECTED_WRONG
205 pos
+= sprintf(channels
+ pos
, "r");
207 pos
+= sprintf(channels
+ pos
, "g");
209 pos
+= sprintf(channels
+ pos
, "b");
213 pos
+= sprintf(channels
+ pos
, "r");
215 pos
+= sprintf(channels
+ pos
, "g");
217 pos
+= sprintf(channels
+ pos
, "b");
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
);
235 #ifdef LED_CONNECTED_WRONG
236 if (strchr(buf
, 'r') != NULL
)
238 if (strchr(buf
, 'b') != NULL
)
241 if (strchr(buf
, 'r') != NULL
)
243 if (strchr(buf
, 'b') != NULL
)
246 if (strchr(buf
, 'g') != NULL
)
252 static ssize_t
show_color(struct device
*dev
,
253 struct device_attribute
*attr
,
256 struct i2c_client
*client
= to_i2c_client(dev
);
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
);
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
);
280 ret
= sscanf(buf
, "%2x:%2x:%2x", &r
, &g
, &b
);
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
);
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;
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
);
312 pattern
[i
] = (u8
)cmd
;
318 /* pattern commands are always two bytes long */
322 mutex_lock(&chip
->lock
);
324 ret
= lp5521_load_program(chip
, pattern
);
325 mutex_unlock(&chip
->lock
);
328 dev_err(dev
, "lp5521 failed loading pattern\n");
334 dev_err(dev
, "lp5521 wrong pattern format\n");
338 static ssize_t
show_mode(struct device
*dev
,
339 struct device_attribute
*attr
,
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
);
367 static ssize_t
show_current(struct device
*dev
,
368 struct device_attribute
*attr
,
371 struct i2c_client
*client
= to_i2c_client(dev
);
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
);
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
);
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
;
401 ret
= sscanf(buf
, "%1x", &curr
);
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
);
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
;
431 ret
= device_create_file(dev
, &dev_attr_color
);
434 ret
= device_create_file(dev
, &dev_attr_load
);
437 ret
= device_create_file(dev
, &dev_attr_active_channels
);
440 ret
= device_create_file(dev
, &dev_attr_mode
);
443 ret
= device_create_file(dev
, &dev_attr_led_current
);
449 device_remove_file(dev
, &dev_attr_mode
);
451 device_remove_file(dev
, &dev_attr_active_channels
);
453 device_remove_file(dev
, &dev_attr_load
);
455 device_remove_file(dev
, &dev_attr_color
);
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
;
483 /* if in that mode already do nothing, except for run */
484 if (!strcmp(mode
, chip
->mode
) && strcmp(mode
, LP5521_MODE_RUN
))
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);
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
;
512 chip
= kzalloc(sizeof(*chip
), GFP_KERNEL
);
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
);
524 dev_err(&client
->dev
, "lp5521 error configuring chip \n");
528 /* Set default values */
529 chip
->mode
= LP5521_MODE_DIRECT_CONTROL
;
534 ret
= lp5521_register_sysfs(client
);
536 dev_err(&client
->dev
, "lp5521 registering sysfs failed \n");
545 static int lp5521_remove(struct i2c_client
*client
)
547 struct lp5521_chip
*chip
= i2c_get_clientdata(client
);
549 lp5521_unregister_sysfs(client
);
555 static const struct i2c_device_id lp5521_id
[] = {
556 { LP5521_DRIVER_NAME
, 0},
559 MODULE_DEVICE_TABLE(i2c
, lp5521_id
);
561 static struct i2c_driver lp5521_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
);