2 * Copyright (C) 2010 Motorola, Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 #include <linux/delay.h>
20 #include <linux/i2c.h>
21 #include <linux/leds.h>
22 #include <linux/platform_device.h>
23 #include <linux/slab.h>
24 #include <linux/types.h>
26 #include <linux/led-lm3559.h>
30 #define LM3559_ALLOWED_R_BYTES 1
31 #define LM3559_ALLOWED_W_BYTES 2
32 #define LM3559_MAX_RW_RETRIES 5
33 #define LM3559_I2C_RETRY_DELAY 10
34 #define LM3559_TORCH_STEP 64
35 #define LM3559_STROBE_STEP 24
36 #define LM3559_PRIVACY_STEP 32
37 #define LM3559_RGB_STEP 32
39 #define LM3559_ENABLE_REG 0x10
40 #define LM3559_PRIVACY_REG 0x11
41 #define LM3559_MSG_IND_REG 0x12
42 #define LM3559_MSG_BLINK_REG 0x13
43 #define LM3559_PWM_REG 0x14
44 #define LM3559_GPIO_REG 0x20
45 #define LM3559_VLED_MON_REG 0x30
46 #define LM3559_ADC_DELAY_REG 0x31
47 #define LM3559_VIN_MONITOR 0x80
48 #define LM3559_LAST_FLASH 0x81
49 #define LM3559_TORCH_BRIGHTNESS 0xA0
50 #define LM3559_FLASH_BRIGHTNESS 0xB0
51 #define LM3559_FLASH_DURATION 0xC0
52 #define LM3559_FLAG_REG 0xD0
53 #define LM3559_CONFIG_REG_1 0xE0
54 #define LM3559_CONFIG_REG_2 0xF0
57 #define LED_FAULT 0x04
58 #define THERMAL_SHUTDOWN 0x02
59 #define TX1_INTERRUPT_FAULT 0x08
60 #define THERMAL_MONITOR_FAULT 0x20
61 #define VOLTAGE_MONITOR_FAULT 0x80
64 struct i2c_client *client;
65 struct lm3559_platform_data *pdata;
66 struct led_classdev led_dev;
67 struct led_classdev spotlight_dev;
68 struct led_classdev msg_ind_red_class_dev;
69 struct led_classdev msg_ind_green_class_dev;
70 struct led_classdev msg_ind_blue_class_dev;
71 struct mutex enable_reg_lock;
72 struct work_struct wq;
73 int camera_strobe_brightness;
74 int flash_light_brightness;
75 int torch_light_brightness;
76 int privacy_light_brightness;
77 int msg_ind_light_brightness;
86 { "ENABLE", LM3559_ENABLE_REG},
87 { "PRIVACY", LM3559_PRIVACY_REG},
88 { "MSG_IND", LM3559_MSG_IND_REG},
89 { "MSG_BLINK", LM3559_MSG_BLINK_REG},
90 { "PRIVACY_PWM", LM3559_PWM_REG},
91 { "GPIO", LM3559_GPIO_REG},
92 { "VLED_MON", LM3559_VLED_MON_REG},
93 { "ADC_DELAY", LM3559_ADC_DELAY_REG},
94 { "VIN_MONITOR", LM3559_VIN_MONITOR},
95 { "LAST_FLASH", LM3559_LAST_FLASH},
96 { "TORCH_BRIGHTNESS", LM3559_TORCH_BRIGHTNESS},
97 { "FLASH_BRIGHTNESS", LM3559_FLASH_BRIGHTNESS},
98 { "FLASH_DURATION", LM3559_FLASH_DURATION},
99 { "FLAG", LM3559_FLAG_REG},
100 { "CONFIG_REG_1", LM3559_CONFIG_REG_1},
101 { "CONFIG_REG_2", LM3559_CONFIG_REG_2},
105 static uint32_t lm3559_debug;
106 module_param_named(flash_debug, lm3559_debug, uint, 0664);
108 int lm3559_read_reg(struct lm3559_data *torch_data, uint8_t reg, uint8_t * val)
115 pr_err("%s: invalid value pointer\n", __func__);
118 /* If I2C client doesn't exist */
119 if (torch_data->client == NULL) {
120 pr_err("%s: null i2c client\n", __func__);
126 err = i2c_master_send(torch_data->client, &dest_buffer,
127 LM3559_ALLOWED_R_BYTES);
128 if (err == LM3559_ALLOWED_R_BYTES)
129 err = i2c_master_recv(torch_data->client, val,
130 LM3559_ALLOWED_R_BYTES);
131 if (err != LM3559_ALLOWED_R_BYTES)
132 msleep_interruptible(LM3559_I2C_RETRY_DELAY);
133 } while ((err != LM3559_ALLOWED_R_BYTES) &&
134 ((++i) < LM3559_MAX_RW_RETRIES));
136 if (err != LM3559_ALLOWED_R_BYTES)
142 int lm3559_write_reg(struct lm3559_data *torch_data, uint8_t reg, uint8_t val)
146 uint8_t buf[LM3559_ALLOWED_W_BYTES] = { reg, val };
148 /* If I2C client doesn't exist */
149 if (torch_data->client == NULL) {
150 pr_err("%s: null i2c client\n", __func__);
155 bytes = i2c_master_send(torch_data->client, buf,
156 LM3559_ALLOWED_W_BYTES);
158 if (bytes != LM3559_ALLOWED_W_BYTES)
159 msleep_interruptible(LM3559_I2C_RETRY_DELAY);
160 } while ((bytes != LM3559_ALLOWED_W_BYTES) &&
161 ((++i) < LM3559_MAX_RW_RETRIES));
163 if (bytes != LM3559_ALLOWED_W_BYTES) {
164 pr_err("%s: i2c_master_send error\n", __func__);
172 static ssize_t ld_lm3559_registers_show(struct device *dev,
173 struct device_attribute *attr, char *buf)
175 struct i2c_client *client = container_of(dev->parent, struct i2c_client,
177 struct lm3559_data *flash_data = i2c_get_clientdata(client);
178 unsigned i, n, reg_count;
181 reg_count = sizeof(lm3559_regs) / sizeof(lm3559_regs[0]);
182 for (i = 0, n = 0; i < reg_count; i++) {
183 lm3559_read_reg(flash_data, lm3559_regs[i].reg, &value);
184 n += scnprintf(buf + n, PAGE_SIZE - n,
193 static ssize_t ld_lm3559_registers_store(struct device *dev,
194 struct device_attribute *attr,
195 const char *buf, size_t count)
197 struct i2c_client *client = container_of(dev->parent,
198 struct i2c_client, dev);
199 struct lm3559_data *flash_data = i2c_get_clientdata(client);
200 unsigned i, reg_count, value;
205 pr_err("%s:input too long\n", __func__);
209 if (sscanf(buf, "%s %x", name, &value) != 2) {
210 pr_err("%s:unable to parse input\n", __func__);
214 reg_count = sizeof(lm3559_regs) / sizeof(lm3559_regs[0]);
215 for (i = 0; i < reg_count; i++) {
216 if (!strcmp(name, lm3559_regs[i].name)) {
217 error = lm3559_write_reg(flash_data,
221 pr_err("%s:Failed to write register %s\n",
229 pr_err("%s:no such register %s\n", __func__, name);
232 static DEVICE_ATTR(registers, 0644, ld_lm3559_registers_show,
233 ld_lm3559_registers_store);
236 int lm3559_init_registers(struct lm3559_data *torch_data)
239 if (lm3559_write_reg(torch_data, LM3559_TORCH_BRIGHTNESS,
240 torch_data->pdata->torch_brightness_def) ||
241 lm3559_write_reg(torch_data, LM3559_ADC_DELAY_REG,
242 torch_data->pdata->adc_delay_reg_def) ||
243 lm3559_write_reg(torch_data, LM3559_FLASH_BRIGHTNESS,
244 torch_data->pdata->flash_brightness_def) ||
245 lm3559_write_reg(torch_data, LM3559_FLASH_DURATION,
246 torch_data->pdata->flash_duration_def) ||
247 lm3559_write_reg(torch_data, LM3559_CONFIG_REG_1,
248 torch_data->pdata->config_reg_1_def) ||
249 lm3559_write_reg(torch_data, LM3559_CONFIG_REG_2,
250 torch_data->pdata->config_reg_2_def) ||
251 lm3559_write_reg(torch_data, LM3559_VIN_MONITOR,
252 torch_data->pdata->vin_monitor_def) ||
253 lm3559_write_reg(torch_data, LM3559_GPIO_REG,
254 torch_data->pdata->gpio_reg_def) ||
255 lm3559_write_reg(torch_data, LM3559_FLAG_REG,
256 torch_data->pdata->flag_reg_def) ||
257 lm3559_write_reg(torch_data, LM3559_PRIVACY_REG,
258 torch_data->pdata->privacy_reg_def) ||
259 lm3559_write_reg(torch_data, LM3559_MSG_IND_REG,
260 torch_data->pdata->msg_ind_reg_def) ||
261 lm3559_write_reg(torch_data, LM3559_MSG_BLINK_REG,
262 torch_data->pdata->msg_ind_blink_reg_def) ||
263 lm3559_write_reg(torch_data, LM3559_PWM_REG,
264 torch_data->pdata->pwm_reg_def) ||
265 lm3559_write_reg(torch_data, LM3559_ENABLE_REG,
266 torch_data->pdata->enable_reg_def)) {
267 pr_err("%s:Register initialization failed\n", __func__);
272 static int lm3559_enable_led(struct lm3559_data *torch_data, uint8_t enable_val)
278 mutex_lock(&torch_data->enable_reg_lock);
279 err = lm3559_read_reg(torch_data, LM3559_ENABLE_REG,
282 pr_err("%s: Reading 0x%X failed %i\n",
283 __func__, LM3559_ENABLE_REG, err);
284 goto unlock_and_return;
287 temp_val = (val | enable_val);
288 err = lm3559_write_reg(torch_data, LM3559_ENABLE_REG,
291 pr_err("%s: Writing to 0x%X failed %i\n",
292 __func__, LM3559_ENABLE_REG, err);
296 mutex_unlock(&torch_data->enable_reg_lock);
300 static int lm3559_disable_led(struct lm3559_data *torch_data,
307 mutex_lock(&torch_data->enable_reg_lock);
308 err = lm3559_read_reg(torch_data, LM3559_ENABLE_REG,
311 pr_err("%s: Reading 0x%X failed %i\n",
312 __func__, LM3559_ENABLE_REG, err);
313 goto unlock_and_return;
315 temp_val = (val & enable_val);
316 err = lm3559_write_reg(torch_data, LM3559_ENABLE_REG,
319 pr_err("%s: Writing to 0x%X failed %i\n",
320 __func__, LM3559_ENABLE_REG, err);
324 mutex_unlock(&torch_data->enable_reg_lock);
327 static int lm3559_privacy_write(struct lm3559_data *torch_data)
330 uint8_t privacy_light_val;
333 err = lm3559_read_reg(torch_data, LM3559_FLAG_REG, &err_flags);
335 pr_err("%s: Reading the status failed for %i\n",
340 if (torch_data->pdata->flags & LM3559_ERROR_CHECK) {
341 if (err_flags & (VOLTAGE_MONITOR_FAULT |
342 THERMAL_MONITOR_FAULT | LED_FAULT |
344 pr_err("%s: Error indicated by the chip 0x%X\n",
345 __func__, err_flags);
349 if (torch_data->privacy_light_brightness) {
350 privacy_light_val = (torch_data->pdata->privacy_reg_def & 0xf8);
351 privacy_light_val |= (torch_data->privacy_light_brightness /
352 LM3559_PRIVACY_STEP);
353 err = lm3559_write_reg(torch_data, LM3559_PRIVACY_REG,
356 pr_err("%s: Writing to 0x%X failed %i\n",
357 __func__, LM3559_PRIVACY_REG, err);
360 err = lm3559_write_reg(torch_data, LM3559_PWM_REG,
361 torch_data->pdata->pwm_val);
363 pr_err("%s: Writing to 0x%X failed %i\n",
364 __func__, LM3559_PWM_REG, err);
367 err = lm3559_enable_led(torch_data,
368 torch_data->pdata->privacy_enable_val);
370 err = lm3559_disable_led(torch_data, 0xc0);
376 static int lm3559_torch_write(struct lm3559_data *torch_data)
382 if (torch_data->torch_light_brightness) {
383 temp_val = torch_data->torch_light_brightness /
385 val |= temp_val << 3;
388 err = lm3559_write_reg(torch_data, LM3559_TORCH_BRIGHTNESS,
392 pr_err("%s: Writing to 0x%X failed %i\n",
393 __func__, LM3559_TORCH_BRIGHTNESS, err);
397 err = lm3559_write_reg(torch_data, LM3559_FLASH_DURATION,
398 torch_data->pdata->flash_duration_def);
400 pr_err("%s: Writing to 0x%X failed %i\n",
401 __func__, LM3559_FLASH_DURATION, err);
405 err = lm3559_write_reg(torch_data, LM3559_VIN_MONITOR,
406 torch_data->pdata->vin_monitor_def);
408 pr_err("%s: Writing to 0x%X failed %i\n",
409 __func__, LM3559_VIN_MONITOR, err);
413 err = lm3559_enable_led(torch_data,
414 torch_data->pdata->torch_enable_val);
416 err = lm3559_disable_led(torch_data, 0xc0);
422 static int lm3559_strobe_write(struct lm3559_data *torch_data)
426 uint8_t strobe_brightness;
429 err = lm3559_read_reg(torch_data, LM3559_FLAG_REG, &err_flags);
431 pr_err("%s: Reading the status failed for %i\n",
435 if (torch_data->pdata->flags & LM3559_ERROR_CHECK) {
436 if (err_flags & (VOLTAGE_MONITOR_FAULT |
437 THERMAL_MONITOR_FAULT | LED_FAULT |
439 pr_err("%s: Error indicated by the chip 0x%X\n",
440 __func__, err_flags);
444 if (torch_data->camera_strobe_brightness) {
445 val = torch_data->camera_strobe_brightness / LM3559_STROBE_STEP;
446 strobe_brightness = val << 4;
447 strobe_brightness |= val ;
449 err = lm3559_write_reg(torch_data, LM3559_FLASH_BRIGHTNESS,
450 torch_data->camera_strobe_brightness);
452 pr_err("%s: Writing to 0x%X failed %i\n",
453 __func__, LM3559_FLASH_BRIGHTNESS, err);
457 err = lm3559_write_reg(torch_data, LM3559_TORCH_BRIGHTNESS,
458 torch_data->pdata->torch_brightness_def);
460 pr_err("%s: Writing to 0x%X failed %i\n",
461 __func__, LM3559_TORCH_BRIGHTNESS, err);
465 err = lm3559_write_reg(torch_data, LM3559_FLASH_DURATION,
466 torch_data->pdata->flash_duration_def);
468 pr_err("%s: Writing to 0x%X failed %i\n",
469 __func__, LM3559_FLASH_DURATION, err);
473 err = lm3559_write_reg(torch_data, LM3559_VIN_MONITOR,
474 torch_data->pdata->vin_monitor_def);
476 pr_err("%s: Writing to 0x%X failed %i\n",
477 __func__, LM3559_VIN_MONITOR, err);
481 err = lm3559_enable_led(torch_data,
482 torch_data->pdata->flash_enable_val);
484 err = lm3559_disable_led(torch_data, 0xc0);
490 static void lm3559_rgb_work(struct work_struct *work)
497 struct lm3559_data *msg_ind_data =
498 container_of(work, struct lm3559_data, wq);
500 if (msg_ind_data->msg_ind_light_brightness) {
501 if (msg_ind_data->blink_val) {
502 err = lm3559_write_reg(msg_ind_data,
503 LM3559_MSG_BLINK_REG,
504 msg_ind_data->pdata->msg_ind_blink_val);
506 pr_err("%s: Reading 0x%X failed %i\n",
507 __func__, LM3559_MSG_BLINK_REG, err);
512 rgb_val = msg_ind_data->pdata->msg_ind_val;
513 rgb_val |= (msg_ind_data->msg_ind_light_brightness /
516 err = lm3559_write_reg(msg_ind_data, LM3559_MSG_IND_REG,
519 pr_err("%s: Writing reg 0x%X failed %i\n",
520 __func__, LM3559_MSG_IND_REG, err);
524 if (msg_ind_data->blink_val) {
526 pr_info("%s: Blink MSG LED\n", __func__);
530 temp_val = (val | 0x40);
531 err = lm3559_enable_led(msg_ind_data, temp_val);
534 if (msg_ind_data->blink_val == 0) {
536 pr_info("%s: Turn off blink MSG LED\n",
543 err = lm3559_disable_led(msg_ind_data, val);
547 /* This is a dummy interface for the LED class this will clear
548 the error flag register */
549 static void lm3559_brightness_set(struct led_classdev *led_cdev,
550 enum led_brightness value)
555 struct lm3559_data *torch_data =
556 container_of(led_cdev, struct lm3559_data, led_dev);
558 err = lm3559_read_reg(torch_data, LM3559_FLAG_REG, &err_flags);
560 pr_err("%s: Reading the status failed for %i\n", __func__,
567 static ssize_t lm3559_strobe_err_show(struct device *dev,
568 struct device_attribute *attr, char *buf)
572 struct i2c_client *client = container_of(dev->parent,
573 struct i2c_client, dev);
574 struct lm3559_data *torch_data = i2c_get_clientdata(client);
576 err = lm3559_read_reg(torch_data, LM3559_FLAG_REG, &err_flags);
578 pr_err("%s: Reading the status failed for %i\n",
583 sprintf(buf, "%d\n", (err_flags & TX1_INTERRUPT_FAULT));
587 static DEVICE_ATTR(strobe_err, 0644, lm3559_strobe_err_show, NULL);
589 static ssize_t lm3559_torch_show(struct device *dev,
590 struct device_attribute *attr, char *buf)
592 struct i2c_client *client = container_of(dev->parent,
593 struct i2c_client, dev);
594 struct lm3559_data *torch_data = i2c_get_clientdata(client);
596 sprintf(buf, "%d\n", torch_data->flash_light_brightness);
602 static ssize_t lm3559_torch_store(struct device *dev,
603 struct device_attribute *attr,
604 const char *buf, size_t count)
607 unsigned long torch_val = LED_OFF;
609 struct i2c_client *client = container_of(dev->parent,
610 struct i2c_client, dev);
611 struct lm3559_data *torch_data = i2c_get_clientdata(client);
613 err = strict_strtoul(buf, 10, &torch_val);
615 pr_err("%s: Invalid parameter sent\n", __func__);
619 torch_data->torch_light_brightness = torch_val;
620 err = lm3559_torch_write(torch_data);
625 static DEVICE_ATTR(flash_light, 0644, lm3559_torch_show, lm3559_torch_store);
627 static void lm3559_spot_light_brightness_set(struct led_classdev *led_cdev,
628 enum led_brightness value)
630 struct lm3559_data *torch_data =
631 container_of(led_cdev, struct lm3559_data, spotlight_dev);
633 torch_data->torch_light_brightness = value;
634 lm3559_torch_write(torch_data);
637 static ssize_t lm3559_strobe_show(struct device *dev,
638 struct device_attribute *attr, char *buf)
640 struct i2c_client *client = container_of(dev->parent,
641 struct i2c_client, dev);
642 struct lm3559_data *torch_data = i2c_get_clientdata(client);
644 sprintf(buf, "%d\n", torch_data->camera_strobe_brightness);
649 static ssize_t lm3559_strobe_store(struct device *dev,
650 struct device_attribute *attr,
651 const char *buf, size_t count)
654 unsigned long strobe_val = LED_OFF;
656 struct i2c_client *client = container_of(dev->parent,
657 struct i2c_client, dev);
658 struct lm3559_data *torch_data = i2c_get_clientdata(client);
660 err = strict_strtoul(buf, 10, &strobe_val);
662 pr_err("%s: Invalid parameter sent\n", __func__);
666 torch_data->camera_strobe_brightness = strobe_val;
667 err = lm3559_strobe_write(torch_data);
671 static DEVICE_ATTR(camera_strobe, 0644, lm3559_strobe_show,
672 lm3559_strobe_store);
674 static ssize_t lm3559_privacy_light_show(struct device *dev,
675 struct device_attribute *attr, char *buf)
677 struct i2c_client *client = container_of(dev->parent,
678 struct i2c_client, dev);
679 struct lm3559_data *torch_data = i2c_get_clientdata(client);
681 sprintf(buf, "%d\n", torch_data->privacy_light_brightness);
686 static ssize_t lm3559_privacy_light_store(struct device *dev,
687 struct device_attribute *attr,
688 const char *buf, size_t count)
691 unsigned long privacy_val = LED_OFF;
693 struct i2c_client *client = container_of(dev->parent,
694 struct i2c_client, dev);
695 struct lm3559_data *torch_data = i2c_get_clientdata(client);
697 err = strict_strtoul(buf, 10, &privacy_val);
699 pr_err("%s: Invalid parameter sent\n", __func__);
703 torch_data->privacy_light_brightness = privacy_val;
704 err = lm3559_privacy_write(torch_data);
709 static DEVICE_ATTR(privacy_light, 0644, lm3559_privacy_light_show,
710 lm3559_privacy_light_store);
713 static void msg_ind_red_set(struct led_classdev *led_cdev,
714 enum led_brightness value)
716 struct lm3559_data *msg_ind_data =
717 container_of(led_cdev, struct lm3559_data,
718 msg_ind_red_class_dev);
720 msg_ind_data->msg_ind_light_brightness = value;
721 schedule_work(&msg_ind_data->wq);
724 static void msg_ind_green_set(struct led_classdev *led_cdev,
725 enum led_brightness value)
727 struct lm3559_data *msg_ind_data =
728 container_of(led_cdev, struct lm3559_data,
729 msg_ind_green_class_dev);
731 msg_ind_data->msg_ind_light_brightness = value;
732 schedule_work(&msg_ind_data->wq);
735 static void msg_ind_blue_set(struct led_classdev *led_cdev,
736 enum led_brightness value)
738 struct lm3559_data *msg_ind_data =
739 container_of(led_cdev, struct lm3559_data,
740 msg_ind_blue_class_dev);
742 msg_ind_data->msg_ind_light_brightness = value;
743 schedule_work(&msg_ind_data->wq);
746 static int msg_ind_red_blink(struct led_classdev *led_cdev,
747 unsigned long *delay_on,
748 unsigned long *delay_off)
750 struct lm3559_data *msg_ind_data =
751 container_of(led_cdev, struct lm3559_data,
752 msg_ind_red_class_dev);
754 msg_ind_data->blink_val = *delay_on;
755 schedule_work(&msg_ind_data->wq);
759 static int msg_ind_green_blink(struct led_classdev *led_cdev,
760 unsigned long *delay_on,
761 unsigned long *delay_off)
763 struct lm3559_data *msg_ind_data =
764 container_of(led_cdev, struct lm3559_data,
765 msg_ind_green_class_dev);
767 msg_ind_data->blink_val = *delay_on;
768 schedule_work(&msg_ind_data->wq);
772 static int msg_ind_blue_blink(struct led_classdev *led_cdev,
773 unsigned long *delay_on,
774 unsigned long *delay_off)
776 struct lm3559_data *msg_ind_data =
777 container_of(led_cdev, struct lm3559_data,
778 msg_ind_blue_class_dev);
780 msg_ind_data->blink_val = *delay_on;
781 schedule_work(&msg_ind_data->wq);
785 static int lm3559_probe(struct i2c_client *client,
786 const struct i2c_device_id *id)
788 struct lm3559_platform_data *pdata = client->dev.platform_data;
789 struct lm3559_data *torch_data;
793 dev_err(&client->dev, "platform data is NULL. exiting.\n");
798 pr_err("%s: Device does not exist\n", __func__);
802 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
803 dev_err(&client->dev, "client not i2c capable\n");
807 torch_data = kzalloc(sizeof(struct lm3559_data), GFP_KERNEL);
808 if (torch_data == NULL) {
809 dev_err(&client->dev, "kzalloc failed\n");
813 torch_data->client = client;
814 torch_data->pdata = pdata;
816 mutex_init(&torch_data->enable_reg_lock);
818 i2c_set_clientdata(client, torch_data);
820 err = lm3559_init_registers(torch_data);
824 INIT_WORK(&torch_data->wq, lm3559_rgb_work);
826 torch_data->led_dev.name = LM3559_LED_DEV;
827 torch_data->led_dev.brightness_set = lm3559_brightness_set;
828 torch_data->led_dev.brightness = LED_OFF;
829 torch_data->led_dev.max_brightness = 255;
830 err = led_classdev_register((struct device *)
831 &client->dev, &torch_data->led_dev);
834 pr_err("%s: Register led class failed: %d\n",
839 if (torch_data->pdata->flags & LM3559_TORCH) {
841 pr_info("%s: Creating Torch\n", __func__);
842 err = device_create_file(torch_data->led_dev.dev,
843 &dev_attr_flash_light);
846 pr_err("%s:File device creation failed: %d\n",
852 if (torch_data->pdata->flags & LM3559_FLASH) {
854 pr_info("%s: Creating Flash\n", __func__);
855 err = device_create_file(torch_data->led_dev.dev,
856 &dev_attr_camera_strobe);
859 pr_err("%s:File device creation failed: %d\n",
863 err = device_create_file(torch_data->led_dev.dev,
864 &dev_attr_strobe_err);
867 pr_err("%s:File device creation failed: %d\n",
873 if (torch_data->pdata->flags & LM3559_PRIVACY) {
875 pr_info("%s: Creating Privacy\n", __func__);
876 err = device_create_file(torch_data->led_dev.dev,
877 &dev_attr_privacy_light);
880 pr_err("%s:File device creation failed: %d\n",
886 if (torch_data->pdata->flags & LM3559_FLASH_LIGHT) {
888 pr_info("%s: Creating Spotlight\n", __func__);
889 torch_data->spotlight_dev.name = LM3559_LED_SPOTLIGHT;
890 torch_data->spotlight_dev.brightness_set =
891 lm3559_spot_light_brightness_set;
892 torch_data->spotlight_dev.brightness = LED_OFF;
893 torch_data->spotlight_dev.max_brightness = 255;
895 err = led_classdev_register((struct device *)
896 &client->dev, &torch_data->spotlight_dev);
899 pr_err("%s: Register led class failed: %d\n",
905 if (torch_data->pdata->flags & LM3559_MSG_IND_RED) {
907 pr_info("%s: Creating MSG Red Indication\n",
909 torch_data->msg_ind_red_class_dev.name = "red";
910 torch_data->msg_ind_red_class_dev.brightness_set =
912 torch_data->msg_ind_red_class_dev.blink_set =
914 torch_data->msg_ind_red_class_dev.brightness = LED_OFF;
915 torch_data->msg_ind_red_class_dev.max_brightness = 255;
917 err = led_classdev_register((struct device *)
918 &client->dev, &torch_data->msg_ind_red_class_dev);
920 pr_err("%s:Register Red LED class failed\n",
922 goto err_reg_red_class_failed;
926 if (torch_data->pdata->flags & LM3559_MSG_IND_GREEN) {
928 pr_info("%s: Creating MSG Green Indication\n",
930 torch_data->msg_ind_green_class_dev.name = "green";
931 torch_data->msg_ind_green_class_dev.brightness_set =
933 torch_data->msg_ind_green_class_dev.blink_set =
935 torch_data->msg_ind_red_class_dev.brightness = LED_OFF;
936 torch_data->msg_ind_red_class_dev.max_brightness = 255;
937 err = led_classdev_register((struct device *)
938 &client->dev, &torch_data->msg_ind_green_class_dev);
940 pr_err("%s: Register Green LED class failed\n",
942 goto err_reg_green_class_failed;
946 if (torch_data->pdata->flags & LM3559_MSG_IND_BLUE) {
948 pr_info("%s: Creating MSG Blue Indication\n",
950 torch_data->msg_ind_blue_class_dev.name = "blue";
951 torch_data->msg_ind_blue_class_dev.brightness_set =
953 torch_data->msg_ind_blue_class_dev.blink_set =
955 torch_data->msg_ind_blue_class_dev.brightness = LED_OFF;
956 torch_data->msg_ind_blue_class_dev.max_brightness = 255;
958 err = led_classdev_register((struct device *)
959 &client->dev, &torch_data->msg_ind_blue_class_dev);
961 pr_err("%s: Register Blue LED class failed\n",
963 goto err_reg_blue_class_failed;
967 err = device_create_file(torch_data->led_dev.dev, &dev_attr_registers);
969 pr_err("%s:File device creation failed: %d\n", __func__, err);
974 err_reg_blue_class_failed:
975 if (torch_data->pdata->flags & LM3559_MSG_IND_GREEN)
976 led_classdev_unregister(&torch_data->msg_ind_green_class_dev);
977 err_reg_green_class_failed:
978 if (torch_data->pdata->flags & LM3559_MSG_IND_RED)
979 led_classdev_unregister(&torch_data->msg_ind_red_class_dev);
980 err_reg_red_class_failed:
981 if (torch_data->pdata->flags & LM3559_PRIVACY)
982 device_remove_file(torch_data->led_dev.dev,
983 &dev_attr_privacy_light);
985 if (torch_data->pdata->flags & LM3559_FLASH_LIGHT)
986 led_classdev_unregister(&torch_data->spotlight_dev);
987 if (torch_data->pdata->flags & LM3559_FLASH)
988 device_remove_file(torch_data->led_dev.dev,
989 &dev_attr_strobe_err);
991 if (torch_data->pdata->flags & LM3559_FLASH)
992 device_remove_file(torch_data->led_dev.dev,
993 &dev_attr_camera_strobe);
995 if (torch_data->pdata->flags & LM3559_TORCH)
996 device_remove_file(torch_data->led_dev.dev,
997 &dev_attr_flash_light);
999 led_classdev_unregister(&torch_data->led_dev);
1006 static int lm3559_remove(struct i2c_client *client)
1008 struct lm3559_data *torch_data = i2c_get_clientdata(client);
1010 if (torch_data->pdata->flags & LM3559_FLASH) {
1011 device_remove_file(torch_data->led_dev.dev,
1012 &dev_attr_camera_strobe);
1013 device_remove_file(torch_data->led_dev.dev,
1014 &dev_attr_strobe_err);
1016 if (torch_data->pdata->flags & LM3559_TORCH)
1017 device_remove_file(torch_data->led_dev.dev,
1018 &dev_attr_flash_light);
1020 led_classdev_unregister(&torch_data->led_dev);
1022 if (torch_data->pdata->flags & LM3559_FLASH_LIGHT)
1023 led_classdev_unregister(&torch_data->spotlight_dev);
1025 if (torch_data->pdata->flags & LM3559_PRIVACY)
1026 device_remove_file(torch_data->led_dev.dev,
1027 &dev_attr_privacy_light);
1029 if (torch_data->pdata->flags & LM3559_MSG_IND_RED)
1030 led_classdev_unregister(&torch_data->msg_ind_red_class_dev);
1032 if (torch_data->pdata->flags & LM3559_MSG_IND_GREEN)
1033 led_classdev_unregister(&torch_data->msg_ind_green_class_dev);
1035 if (torch_data->pdata->flags & LM3559_MSG_IND_BLUE)
1036 led_classdev_unregister(&torch_data->msg_ind_blue_class_dev);
1039 device_remove_file(torch_data->led_dev.dev, &dev_attr_registers);
1041 kfree(torch_data->pdata);
1046 static const struct i2c_device_id lm3559_id[] = {
1051 static struct i2c_driver lm3559_i2c_driver = {
1052 .probe = lm3559_probe,
1053 .remove = lm3559_remove,
1054 .id_table = lm3559_id,
1056 .name = LM3559_NAME,
1057 .owner = THIS_MODULE,
1061 static int __init lm3559_init(void)
1063 return i2c_add_driver(&lm3559_i2c_driver);
1066 static void lm3559_exit(void)
1068 i2c_del_driver(&lm3559_i2c_driver);
1071 module_init(lm3559_init);
1072 module_exit(lm3559_exit);
1074 /****************************************************************************/
1076 MODULE_DESCRIPTION("Lighting driver for LM3559");
1077 MODULE_AUTHOR("MOTOROLA");
1078 MODULE_LICENSE("GPL");