leds: led-lm3559: Enable camera flash in led driver
authorDavid Schalig <dschalig@nvidia.com>
Thu, 16 Sep 2010 00:46:42 +0000 (09:46 +0900)
committerColin Cross <ccross@android.com>
Thu, 7 Oct 2010 00:01:24 +0000 (17:01 -0700)
Streamlined LM3559 led driver implementation, fixed register
programming sequence to enable flash trigger via STROBE pin.

Change-Id: Ic2aa97cbd5da508116e7bc635876f0ef95df1df4
Signed-off-by: Rebecca Schultz Zavin <rebecca@android.com>
drivers/leds/led-lm3559.c
include/linux/led-lm3559.h

index 2caaa9e4261459ceaffb79ad8fa732f11715951c..7434eac89a0a976228278f8f6f55d198d21eca81 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/types.h>
+#include <linux/err.h>
 
 #include <linux/led-lm3559.h>
 
-/*#define DEBUG*/
+/* #define DEBUG */
 
 #define LM3559_ALLOWED_R_BYTES   1
 #define LM3559_ALLOWED_W_BYTES   2
 #define LM3559_MAX_RW_RETRIES    5
 #define LM3559_I2C_RETRY_DELAY  10
 #define LM3559_TORCH_STEP      64
-#define LM3559_STROBE_STEP     24
+#define LM3559_STROBE_STEP     16
 #define LM3559_PRIVACY_STEP     32
 #define LM3559_RGB_STEP                32
 
 struct lm3559_data {
        struct i2c_client *client;
        struct lm3559_platform_data *pdata;
-       struct led_classdev led_dev;
-       struct led_classdev spotlight_dev;
-       struct led_classdev msg_ind_red_class_dev;
-       struct led_classdev msg_ind_green_class_dev;
-       struct led_classdev msg_ind_blue_class_dev;
-       struct mutex enable_reg_lock;
-       struct work_struct wq;
-       int camera_strobe_brightness;
-       int flash_light_brightness;
-       int torch_light_brightness;
-       int privacy_light_brightness;
-       int msg_ind_light_brightness;
-       int blink_val;
+       struct led_classdev flash_dev;
+       struct led_classdev torch_dev;
 };
 
 #ifdef DEBUG
@@ -105,7 +95,8 @@ struct lm3559_reg {
 static uint32_t lm3559_debug;
 module_param_named(flash_debug, lm3559_debug, uint, 0664);
 
-int lm3559_read_reg(struct lm3559_data *torch_data, uint8_t reg, uint8_t * val)
+static int lm3559_read_reg(struct lm3559_data *torch_data,
+                               uint8_t reg, uint8_t* val)
 {
        int err = -1;
        int i = 0;
@@ -139,7 +130,8 @@ int lm3559_read_reg(struct lm3559_data *torch_data, uint8_t reg, uint8_t * val)
        return 0;
 }
 
-int lm3559_write_reg(struct lm3559_data *torch_data, uint8_t reg, uint8_t val)
+static int lm3559_write_reg(struct lm3559_data *torch_data,
+                               uint8_t reg, uint8_t val)
 {
        int bytes;
        int i = 0;
@@ -235,162 +227,71 @@ static DEVICE_ATTR(registers, 0644, ld_lm3559_registers_show,
 
 int lm3559_init_registers(struct lm3559_data *torch_data)
 {
-
-       if (lm3559_write_reg(torch_data, LM3559_TORCH_BRIGHTNESS,
-                            torch_data->pdata->torch_brightness_def) ||
-               lm3559_write_reg(torch_data, LM3559_ADC_DELAY_REG,
-                            torch_data->pdata->adc_delay_reg_def) ||
-               lm3559_write_reg(torch_data, LM3559_FLASH_BRIGHTNESS,
-                            torch_data->pdata->flash_brightness_def) ||
+       if (lm3559_write_reg(torch_data, LM3559_TORCH_BRIGHTNESS, 0) ||
+               lm3559_write_reg(torch_data, LM3559_ADC_DELAY_REG, 0) ||
+               lm3559_write_reg(torch_data, LM3559_FLASH_BRIGHTNESS, 0) ||
                lm3559_write_reg(torch_data, LM3559_FLASH_DURATION,
                             torch_data->pdata->flash_duration_def) ||
-               lm3559_write_reg(torch_data, LM3559_CONFIG_REG_1,
-                            torch_data->pdata->config_reg_1_def) ||
-               lm3559_write_reg(torch_data, LM3559_CONFIG_REG_2,
-                            torch_data->pdata->config_reg_2_def) ||
+               lm3559_write_reg(torch_data, LM3559_CONFIG_REG_1, 0x6C) ||
+               lm3559_write_reg(torch_data, LM3559_CONFIG_REG_2, 0) ||
                lm3559_write_reg(torch_data, LM3559_VIN_MONITOR,
-                            torch_data->pdata->vin_monitor_def) ||
-               lm3559_write_reg(torch_data, LM3559_GPIO_REG,
-                            torch_data->pdata->gpio_reg_def) ||
-               lm3559_write_reg(torch_data, LM3559_FLAG_REG,
-                            torch_data->pdata->flag_reg_def) ||
-               lm3559_write_reg(torch_data, LM3559_PRIVACY_REG,
-                            torch_data->pdata->privacy_reg_def) ||
-               lm3559_write_reg(torch_data, LM3559_MSG_IND_REG,
-                            torch_data->pdata->msg_ind_reg_def) ||
-               lm3559_write_reg(torch_data, LM3559_MSG_BLINK_REG,
-                            torch_data->pdata->msg_ind_blink_reg_def) ||
-               lm3559_write_reg(torch_data, LM3559_PWM_REG,
-                            torch_data->pdata->pwm_reg_def) ||
-               lm3559_write_reg(torch_data, LM3559_ENABLE_REG,
-                            torch_data->pdata->enable_reg_def)) {
+                       torch_data->pdata->vin_monitor_def) ||
+               lm3559_write_reg(torch_data, LM3559_GPIO_REG, 0) ||
+               lm3559_write_reg(torch_data, LM3559_FLAG_REG, 0) ||
+               lm3559_write_reg(torch_data, LM3559_PRIVACY_REG, 0x10) ||
+               lm3559_write_reg(torch_data, LM3559_MSG_IND_REG, 0) ||
+               lm3559_write_reg(torch_data, LM3559_MSG_BLINK_REG, 0) ||
+               lm3559_write_reg(torch_data, LM3559_PWM_REG, 0) ||
+               lm3559_write_reg(torch_data, LM3559_ENABLE_REG, 0)) {
                pr_err("%s:Register initialization failed\n", __func__);
                return -EIO;
        }
        return 0;
 }
-static int lm3559_enable_led(struct lm3559_data *torch_data, uint8_t enable_val)
-{
-       int err = 0;
-       uint8_t val = 0;
-       uint8_t temp_val;
-
-       mutex_lock(&torch_data->enable_reg_lock);
-       err = lm3559_read_reg(torch_data, LM3559_ENABLE_REG,
-               &val);
-       if (err) {
-               pr_err("%s: Reading 0x%X failed %i\n",
-                       __func__, LM3559_ENABLE_REG, err);
-               goto unlock_and_return;
-       }
-
-       temp_val = (val | enable_val);
-       err = lm3559_write_reg(torch_data, LM3559_ENABLE_REG,
-               temp_val);
-       if (err) {
-               pr_err("%s: Writing to 0x%X failed %i\n",
-                       __func__, LM3559_ENABLE_REG, err);
-       }
-
-unlock_and_return:
-       mutex_unlock(&torch_data->enable_reg_lock);
-       return err;
-}
 
-static int lm3559_disable_led(struct lm3559_data *torch_data,
-               uint8_t enable_val)
-{
+static int lm3559_check_led_error(struct lm3559_data *torch_data) {
        int err = 0;
-       uint8_t val = 0;
-       uint8_t temp_val;
-
-       mutex_lock(&torch_data->enable_reg_lock);
-       err = lm3559_read_reg(torch_data, LM3559_ENABLE_REG,
-               &val);
-       if (err) {
-               pr_err("%s: Reading 0x%X failed %i\n",
-                       __func__, LM3559_ENABLE_REG, err);
-               goto unlock_and_return;
-       }
-       temp_val = (val & enable_val);
-       err = lm3559_write_reg(torch_data, LM3559_ENABLE_REG,
-               temp_val);
-       if (err) {
-               pr_err("%s: Writing to 0x%X failed %i\n",
-                       __func__, LM3559_ENABLE_REG, err);
-       }
 
-unlock_and_return:
-       mutex_unlock(&torch_data->enable_reg_lock);
-       return err;
-}
-static int lm3559_privacy_write(struct lm3559_data *torch_data)
-{
-       int err = 0;
-       uint8_t privacy_light_val;
-       uint8_t err_flags;
+       if (torch_data->pdata->flags & LM3559_FLAG_ERROR_CHECK) {
 
-       err = lm3559_read_reg(torch_data, LM3559_FLAG_REG, &err_flags);
-       if (err) {
-               pr_err("%s: Reading the status failed for %i\n",
-                       __func__, err);
-               return -EIO;
-       }
-
-       if (torch_data->pdata->flags & LM3559_ERROR_CHECK) {
-               if (err_flags & (VOLTAGE_MONITOR_FAULT |
-                       THERMAL_MONITOR_FAULT | LED_FAULT |
-                       THERMAL_SHUTDOWN)) {
-                               pr_err("%s: Error indicated by the chip 0x%X\n",
-                                       __func__, err_flags);
-                               return err_flags;
-               }
-       }
-       if (torch_data->privacy_light_brightness) {
-               privacy_light_val = (torch_data->pdata->privacy_reg_def & 0xf8);
-               privacy_light_val |= (torch_data->privacy_light_brightness /
-                               LM3559_PRIVACY_STEP);
-               err = lm3559_write_reg(torch_data, LM3559_PRIVACY_REG,
-                       privacy_light_val);
+               uint8_t err_flags;
+               err = lm3559_read_reg(torch_data, LM3559_FLAG_REG, &err_flags);
                if (err) {
-                       pr_err("%s: Writing to 0x%X failed %i\n",
-                               __func__, LM3559_PRIVACY_REG, err);
+                       pr_err("%s: Reading the status failed for %i\n",
+                               __func__, err);
                        return -EIO;
                }
-               err = lm3559_write_reg(torch_data, LM3559_PWM_REG,
-                       torch_data->pdata->pwm_val);
-               if (err) {
-                       pr_err("%s: Writing to 0x%X failed %i\n",
-                               __func__, LM3559_PWM_REG, err);
-                       return -EIO;
+
+               if (err_flags & (VOLTAGE_MONITOR_FAULT |
+                               THERMAL_MONITOR_FAULT |
+                               LED_FAULT |
+                               THERMAL_SHUTDOWN)) {
+                       pr_err("%s: Error indicated by the chip 0x%X\n",
+                               __func__, err_flags);
+                       err = -EIO;
                }
-               err = lm3559_enable_led(torch_data,
-                       torch_data->pdata->privacy_enable_val);
-       } else {
-               err = lm3559_disable_led(torch_data, 0xc0);
        }
 
        return err;
 }
 
-static int lm3559_torch_write(struct lm3559_data *torch_data)
+static int lm3559_flash_prepare(struct lm3559_data *torch_data)
 {
-       int err = 0;
-       int temp_val;
-       int val = 0;;
-
-       if (torch_data->torch_light_brightness) {
-               temp_val = torch_data->torch_light_brightness /
-                       LM3559_TORCH_STEP;
-               val |= temp_val << 3;
-               val |= temp_val;
+       int err = lm3559_check_led_error(torch_data);
+       if (err)
+               return err;
 
-               err = lm3559_write_reg(torch_data, LM3559_TORCH_BRIGHTNESS,
-                       val);
+       if (torch_data->flash_dev.brightness != LED_OFF) {
+               uint8_t strobe_brightness;
+               uint val = torch_data->flash_dev.brightness;
+               val = (val * (1024/LM3559_STROBE_STEP)) >> 10;
+               strobe_brightness = val | (val << 4);
 
+               err = lm3559_write_reg(torch_data, LM3559_FLASH_BRIGHTNESS,
+                       strobe_brightness);
                if (err) {
                        pr_err("%s: Writing to 0x%X failed %i\n",
-                               __func__, LM3559_TORCH_BRIGHTNESS, err);
+                               __func__, LM3559_FLASH_BRIGHTNESS, err);
                        return -EIO;
                }
 
@@ -403,382 +304,109 @@ static int lm3559_torch_write(struct lm3559_data *torch_data)
                }
 
                err = lm3559_write_reg(torch_data, LM3559_VIN_MONITOR,
-                                       torch_data->pdata->vin_monitor_def);
+                               torch_data->pdata->vin_monitor_def);
                if (err) {
                        pr_err("%s: Writing to 0x%X failed %i\n",
                                __func__, LM3559_VIN_MONITOR, err);
                        return -EIO;
                }
 
-               err = lm3559_enable_led(torch_data,
-                       torch_data->pdata->torch_enable_val);
+               /* setup flash for trigger by strobe pin:
+                  enable LED1 and LED2, but do not enable current */
+               err = lm3559_write_reg(torch_data, LM3559_ENABLE_REG, 0x18);
+
        } else {
-               err = lm3559_disable_led(torch_data, 0xc0);
+               /* disable LED1 and LED2 and current */
+               err = lm3559_write_reg(torch_data, LM3559_ENABLE_REG, 0);
        }
 
+       if (err)
+               pr_err("%s: Writing to 0x%X failed %i\n",
+                       __func__, LM3559_ENABLE_REG, err);
+
        return err;
 }
 
-static int lm3559_strobe_write(struct lm3559_data *torch_data)
+static int lm3559_torch_enable(struct lm3559_data *torch_data)
 {
-       int err;
-       uint8_t err_flags;
-       uint8_t strobe_brightness;
-       int val;
-
-       err = lm3559_read_reg(torch_data, LM3559_FLAG_REG, &err_flags);
-       if (err) {
-               pr_err("%s: Reading the status failed for %i\n",
-                       __func__, err);
-               return -EIO;
-       }
-       if (torch_data->pdata->flags & LM3559_ERROR_CHECK) {
-               if (err_flags & (VOLTAGE_MONITOR_FAULT |
-                       THERMAL_MONITOR_FAULT | LED_FAULT |
-                       THERMAL_SHUTDOWN)) {
-                       pr_err("%s: Error indicated by the chip 0x%X\n",
-                               __func__, err_flags);
-                       return err_flags;
-               }
-       }
-       if (torch_data->camera_strobe_brightness) {
-               val = torch_data->camera_strobe_brightness / LM3559_STROBE_STEP;
-               strobe_brightness = val << 4;
-               strobe_brightness |= val ;
+       int err = lm3559_check_led_error(torch_data);
+       if (err)
+               return err;
 
-               err = lm3559_write_reg(torch_data, LM3559_FLASH_BRIGHTNESS,
-                       torch_data->camera_strobe_brightness);
-               if (err) {
-                       pr_err("%s: Writing to 0x%X failed %i\n",
-                               __func__, LM3559_FLASH_BRIGHTNESS, err);
-                       return -EIO;
-               }
+       if (torch_data->torch_dev.brightness) {
+               uint8_t torch_brightness;
+               uint val = torch_data->torch_dev.brightness;
+               val = (val * (1024/LM3559_TORCH_STEP)) >> 10;
+               torch_brightness = val | (val << 3);
 
                err = lm3559_write_reg(torch_data, LM3559_TORCH_BRIGHTNESS,
-                       torch_data->pdata->torch_brightness_def);
+                       torch_brightness);
                if (err) {
                        pr_err("%s: Writing to 0x%X failed %i\n",
                                __func__, LM3559_TORCH_BRIGHTNESS, err);
                        return -EIO;
                }
 
-               err = lm3559_write_reg(torch_data, LM3559_FLASH_DURATION,
-                       torch_data->pdata->flash_duration_def);
-               if (err) {
-                       pr_err("%s: Writing to 0x%X failed %i\n",
-                               __func__, LM3559_FLASH_DURATION, err);
-                       return -EIO;
-               }
-
                err = lm3559_write_reg(torch_data, LM3559_VIN_MONITOR,
-                               torch_data->pdata->vin_monitor_def);
+                                       torch_data->pdata->vin_monitor_def);
                if (err) {
                        pr_err("%s: Writing to 0x%X failed %i\n",
                                __func__, LM3559_VIN_MONITOR, err);
                        return -EIO;
                }
 
-               err = lm3559_enable_led(torch_data,
-                       torch_data->pdata->flash_enable_val);
+               /* enable LED1 and LED2, enable current */
+               err = lm3559_write_reg(torch_data, LM3559_ENABLE_REG, 0x1A);
+
        } else {
-               err = lm3559_disable_led(torch_data, 0xc0);
+               /* disable LED1 and LED2 and current */
+               err = lm3559_write_reg(torch_data, LM3559_ENABLE_REG, 0);
        }
 
        return err;
 }
 
-static void lm3559_rgb_work(struct work_struct *work)
+static void lm3559_flash_brightness_set(struct led_classdev *led_cdev,
+                                       enum led_brightness value)
 {
-       int err;
-       uint8_t val = 0;
-       uint8_t temp_val;
-       uint8_t rgb_val;
-
-       struct lm3559_data *msg_ind_data =
-               container_of(work, struct lm3559_data, wq);
-
-       if (msg_ind_data->msg_ind_light_brightness) {
-               if (msg_ind_data->blink_val) {
-                       err = lm3559_write_reg(msg_ind_data,
-                               LM3559_MSG_BLINK_REG,
-                               msg_ind_data->pdata->msg_ind_blink_val);
-                       if (err) {
-                               pr_err("%s: Reading 0x%X failed %i\n",
-                                       __func__, LM3559_MSG_BLINK_REG, err);
-                               return;
-                       }
-               }
-
-               rgb_val = msg_ind_data->pdata->msg_ind_val;
-               rgb_val |= (msg_ind_data->msg_ind_light_brightness /
-                       LM3559_RGB_STEP);
-
-               err = lm3559_write_reg(msg_ind_data, LM3559_MSG_IND_REG,
-                       rgb_val);
-               if (err) {
-                       pr_err("%s: Writing reg 0x%X failed %i\n",
-                               __func__, LM3559_MSG_IND_REG, err);
-                       return;
-               }
-
-               if (msg_ind_data->blink_val) {
-                       if (lm3559_debug)
-                               pr_info("%s: Blink MSG LED\n", __func__);
-                       val = 0x80;
-               }
-
-               temp_val = (val | 0x40);
-               err = lm3559_enable_led(msg_ind_data, temp_val);
-
-       } else {
-               if (msg_ind_data->blink_val == 0) {
-                       if (lm3559_debug)
-                               pr_info("%s: Turn off blink MSG LED\n",
-                                       __func__);
-                       val = 0x7f;
-               } else {
-
-                       val = 0x3f;
-               }
-               err = lm3559_disable_led(msg_ind_data, val);
-       }
-}
-
-/* This is a dummy interface for the LED class this will clear
-the error flag register */
-static void lm3559_brightness_set(struct led_classdev *led_cdev,
-                                 enum led_brightness value)
-{
-       int err;
-       uint8_t err_flags;
-
        struct lm3559_data *torch_data =
-           container_of(led_cdev, struct lm3559_data, led_dev);
-
-       err = lm3559_read_reg(torch_data, LM3559_FLAG_REG, &err_flags);
-       if (err) {
-               pr_err("%s: Reading the status failed for %i\n", __func__,
-                      err);
-               return;
-       }
-       return;
-}
-
-static ssize_t lm3559_strobe_err_show(struct device *dev,
-                                struct device_attribute *attr, char *buf)
-{
-       int err;
-       uint8_t err_flags;
-       struct i2c_client *client = container_of(dev->parent,
-                                                struct i2c_client, dev);
-       struct lm3559_data *torch_data = i2c_get_clientdata(client);
-
-       err = lm3559_read_reg(torch_data, LM3559_FLAG_REG, &err_flags);
-       if (err) {
-               pr_err("%s: Reading the status failed for %i\n",
-                       __func__, err);
-               return -EIO;
-       }
-
-       sprintf(buf, "%d\n", (err_flags & TX1_INTERRUPT_FAULT));
-
-       return sizeof(buf);
+           container_of(led_cdev, struct lm3559_data, flash_dev);
+       lm3559_flash_prepare(torch_data);
 }
-static DEVICE_ATTR(strobe_err, 0644, lm3559_strobe_err_show, NULL);
 
-static ssize_t lm3559_torch_show(struct device *dev,
-                                struct device_attribute *attr, char *buf)
-{
-       struct i2c_client *client = container_of(dev->parent,
-                                                struct i2c_client, dev);
-       struct lm3559_data *torch_data = i2c_get_clientdata(client);
-
-       sprintf(buf, "%d\n", torch_data->flash_light_brightness);
-
-       return sizeof(buf);
-}
-
-
-static ssize_t lm3559_torch_store(struct device *dev,
-                                 struct device_attribute *attr,
-                                 const char *buf, size_t count)
-{
-       int err = 0;
-       unsigned long torch_val = LED_OFF;
-
-       struct i2c_client *client = container_of(dev->parent,
-                                                struct i2c_client, dev);
-       struct lm3559_data *torch_data = i2c_get_clientdata(client);
-
-       err = strict_strtoul(buf, 10, &torch_val);
-       if (err) {
-               pr_err("%s: Invalid parameter sent\n", __func__);
-               return -1;
-       }
-
-       torch_data->torch_light_brightness = torch_val;
-       err = lm3559_torch_write(torch_data);
-
-       return err;
-
-};
-static DEVICE_ATTR(flash_light, 0644, lm3559_torch_show, lm3559_torch_store);
-
-static void lm3559_spot_light_brightness_set(struct led_classdev *led_cdev,
-                                 enum led_brightness value)
+static void lm3559_torch_brightness_set(struct led_classdev *led_cdev,
+                                       enum led_brightness value)
 {
        struct lm3559_data *torch_data =
-           container_of(led_cdev, struct lm3559_data, spotlight_dev);
-
-       torch_data->torch_light_brightness = value;
-       lm3559_torch_write(torch_data);
-}
-
-static ssize_t lm3559_strobe_show(struct device *dev,
-                                 struct device_attribute *attr, char *buf)
-{
-       struct i2c_client *client = container_of(dev->parent,
-                                                struct i2c_client, dev);
-       struct lm3559_data *torch_data = i2c_get_clientdata(client);
-
-       sprintf(buf, "%d\n", torch_data->camera_strobe_brightness);
-
-       return sizeof(buf);
+           container_of(led_cdev, struct lm3559_data, torch_dev);
+       lm3559_torch_enable(torch_data);
 }
 
-static ssize_t lm3559_strobe_store(struct device *dev,
-                                  struct device_attribute *attr,
-                                  const char *buf, size_t count)
-{
-       int err;
-       unsigned long strobe_val = LED_OFF;
-
-       struct i2c_client *client = container_of(dev->parent,
-                                                struct i2c_client, dev);
-       struct lm3559_data *torch_data = i2c_get_clientdata(client);
-
-       err = strict_strtoul(buf, 10, &strobe_val);
-       if (err) {
-               pr_err("%s: Invalid parameter sent\n", __func__);
-               return -1;
-       }
-
-       torch_data->camera_strobe_brightness = strobe_val;
-       err = lm3559_strobe_write(torch_data);
-
-       return err;
-}
-static DEVICE_ATTR(camera_strobe, 0644, lm3559_strobe_show,
-       lm3559_strobe_store);
-
-static ssize_t lm3559_privacy_light_show(struct device *dev,
-                                 struct device_attribute *attr, char *buf)
+static int lm3559_remove(struct i2c_client *client)
 {
-       struct i2c_client *client = container_of(dev->parent,
-                                                struct i2c_client, dev);
        struct lm3559_data *torch_data = i2c_get_clientdata(client);
 
-       sprintf(buf, "%d\n", torch_data->privacy_light_brightness);
-
-       return sizeof(buf);
-}
+       if (torch_data) {
 
-static ssize_t lm3559_privacy_light_store(struct device *dev,
-                                  struct device_attribute *attr,
-                                  const char *buf, size_t count)
-{
-       int err = 0;
-       unsigned long privacy_val = LED_OFF;
+               if (!IS_ERR_OR_NULL(torch_data->torch_dev.dev)) {
+#ifdef DEBUG
+                       device_remove_file(torch_data->torch_dev.dev,
+                               &dev_attr_registers);
+#endif
+                       led_classdev_unregister(&torch_data->torch_dev);
+               }
 
-       struct i2c_client *client = container_of(dev->parent,
-                                                struct i2c_client, dev);
-       struct lm3559_data *torch_data = i2c_get_clientdata(client);
+               if (!IS_ERR_OR_NULL(torch_data->flash_dev.dev)) {
+#ifdef DEBUG
+                       device_remove_file(torch_data->flash_dev.dev,
+                               &dev_attr_registers);
+#endif
+                       led_classdev_unregister(&torch_data->flash_dev);
+               }
 
-       err = strict_strtoul(buf, 10, &privacy_val);
-       if (err) {
-               pr_err("%s: Invalid parameter sent\n", __func__);
-               return -1;
+               kfree(torch_data->pdata);
+               kfree(torch_data);
        }
-
-       torch_data->privacy_light_brightness = privacy_val;
-       err = lm3559_privacy_write(torch_data);
-
-       return err;
-
-};
-static DEVICE_ATTR(privacy_light, 0644, lm3559_privacy_light_show,
-                  lm3559_privacy_light_store);
-
-
-static void msg_ind_red_set(struct led_classdev *led_cdev,
-                           enum led_brightness value)
-{
-       struct lm3559_data *msg_ind_data =
-           container_of(led_cdev, struct lm3559_data,
-                        msg_ind_red_class_dev);
-
-       msg_ind_data->msg_ind_light_brightness = value;
-       schedule_work(&msg_ind_data->wq);
-}
-
-static void msg_ind_green_set(struct led_classdev *led_cdev,
-                           enum led_brightness value)
-{
-       struct lm3559_data *msg_ind_data =
-           container_of(led_cdev, struct lm3559_data,
-                        msg_ind_green_class_dev);
-
-       msg_ind_data->msg_ind_light_brightness = value;
-       schedule_work(&msg_ind_data->wq);
-}
-
-static void msg_ind_blue_set(struct led_classdev *led_cdev,
-                           enum led_brightness value)
-{
-       struct lm3559_data *msg_ind_data =
-           container_of(led_cdev, struct lm3559_data,
-                        msg_ind_blue_class_dev);
-
-       msg_ind_data->msg_ind_light_brightness = value;
-       schedule_work(&msg_ind_data->wq);
-}
-
-static int msg_ind_red_blink(struct led_classdev *led_cdev,
-               unsigned long *delay_on,
-               unsigned long *delay_off)
-{
-       struct lm3559_data *msg_ind_data =
-           container_of(led_cdev, struct lm3559_data,
-                        msg_ind_red_class_dev);
-
-       msg_ind_data->blink_val = *delay_on;
-       schedule_work(&msg_ind_data->wq);
-       return 0;
-}
-
-static int msg_ind_green_blink(struct led_classdev *led_cdev,
-               unsigned long *delay_on,
-               unsigned long *delay_off)
-{
-       struct lm3559_data *msg_ind_data =
-           container_of(led_cdev, struct lm3559_data,
-                        msg_ind_green_class_dev);
-
-       msg_ind_data->blink_val = *delay_on;
-       schedule_work(&msg_ind_data->wq);
-       return 0;
-}
-
-static int msg_ind_blue_blink(struct led_classdev *led_cdev,
-               unsigned long *delay_on,
-               unsigned long *delay_off)
-{
-       struct lm3559_data *msg_ind_data =
-           container_of(led_cdev, struct lm3559_data,
-                        msg_ind_blue_class_dev);
-
-       msg_ind_data->blink_val = *delay_on;
-       schedule_work(&msg_ind_data->wq);
        return 0;
 }
 
@@ -794,11 +422,6 @@ static int lm3559_probe(struct i2c_client *client,
                return -ENODEV;
        }
 
-       if (!pdata->flags) {
-               pr_err("%s: Device does not exist\n", __func__);
-               return -ENODEV;
-       }
-
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
                dev_err(&client->dev, "client not i2c capable\n");
                return -ENODEV;
@@ -813,234 +436,54 @@ static int lm3559_probe(struct i2c_client *client,
        torch_data->client = client;
        torch_data->pdata = pdata;
 
-       mutex_init(&torch_data->enable_reg_lock);
-
        i2c_set_clientdata(client, torch_data);
 
        err = lm3559_init_registers(torch_data);
        if (err < 0)
-               goto error2;
+               goto error;
 
-       INIT_WORK(&torch_data->wq, lm3559_rgb_work);
-
-       torch_data->led_dev.name = LM3559_LED_DEV;
-       torch_data->led_dev.brightness_set = lm3559_brightness_set;
-       torch_data->led_dev.brightness = LED_OFF;
-       torch_data->led_dev.max_brightness = 255;
+       torch_data->flash_dev.name = "flash";
+       torch_data->flash_dev.brightness_set = lm3559_flash_brightness_set;
+       torch_data->flash_dev.brightness = LED_OFF;
+       torch_data->flash_dev.max_brightness = LED_FULL;
        err = led_classdev_register((struct device *)
-                                   &client->dev, &torch_data->led_dev);
+               &client->dev, &torch_data->flash_dev);
        if (err < 0) {
-               err = -ENODEV;
-               pr_err("%s: Register led class failed: %d\n",
+               pr_err("%s: Register flash led class failed: %d\n",
                        __func__, err);
-               goto error3;
-       }
-
-       if (torch_data->pdata->flags & LM3559_TORCH) {
-               if (lm3559_debug)
-                       pr_info("%s: Creating Torch\n", __func__);
-               err = device_create_file(torch_data->led_dev.dev,
-                                        &dev_attr_flash_light);
-               if (err < 0) {
-                       err = -ENODEV;
-                       pr_err("%s:File device creation failed: %d\n",
-                               __func__, err);
-                       goto error4;
-               }
-       }
-
-       if (torch_data->pdata->flags & LM3559_FLASH) {
-               if (lm3559_debug)
-                       pr_info("%s: Creating Flash\n", __func__);
-               err = device_create_file(torch_data->led_dev.dev,
-                                        &dev_attr_camera_strobe);
-               if (err < 0) {
-                       err = -ENODEV;
-                       pr_err("%s:File device creation failed: %d\n",
-                               __func__, err);
-                       goto error5;
-               }
-               err = device_create_file(torch_data->led_dev.dev,
-                                        &dev_attr_strobe_err);
-               if (err < 0) {
-                       err = -ENODEV;
-                       pr_err("%s:File device creation failed: %d\n",
-                               __func__, err);
-                       goto error6;
-               }
-       }
-
-       if (torch_data->pdata->flags & LM3559_PRIVACY) {
-               if (lm3559_debug)
-                       pr_info("%s: Creating Privacy\n", __func__);
-               err = device_create_file(torch_data->led_dev.dev,
-                                        &dev_attr_privacy_light);
-               if (err < 0) {
-                       err = -ENODEV;
-                       pr_err("%s:File device creation failed: %d\n",
-                               __func__, err);
-                       goto error7;
-               }
-       }
-
-       if (torch_data->pdata->flags & LM3559_FLASH_LIGHT) {
-               if (lm3559_debug)
-                       pr_info("%s: Creating Spotlight\n", __func__);
-               torch_data->spotlight_dev.name = LM3559_LED_SPOTLIGHT;
-               torch_data->spotlight_dev.brightness_set =
-                       lm3559_spot_light_brightness_set;
-               torch_data->spotlight_dev.brightness = LED_OFF;
-               torch_data->spotlight_dev.max_brightness = 255;
-
-               err = led_classdev_register((struct device *)
-                       &client->dev, &torch_data->spotlight_dev);
-               if (err < 0) {
-                       err = -ENODEV;
-                       pr_err("%s: Register led class failed: %d\n",
-                               __func__, err);
-                       goto error6;
-               }
+               goto error;
        }
 
-       if (torch_data->pdata->flags & LM3559_MSG_IND_RED) {
-               if (lm3559_debug)
-                       pr_info("%s: Creating MSG Red Indication\n",
-                       __func__);
-               torch_data->msg_ind_red_class_dev.name = "red";
-               torch_data->msg_ind_red_class_dev.brightness_set =
-                       msg_ind_red_set;
-               torch_data->msg_ind_red_class_dev.blink_set =
-                       msg_ind_red_blink;
-               torch_data->msg_ind_red_class_dev.brightness = LED_OFF;
-               torch_data->msg_ind_red_class_dev.max_brightness = 255;
-
-               err = led_classdev_register((struct device *)
-                       &client->dev, &torch_data->msg_ind_red_class_dev);
-               if (err < 0) {
-                       pr_err("%s:Register Red LED class failed\n",
-                               __func__);
-                       goto err_reg_red_class_failed;
-               }
-       }
-
-       if (torch_data->pdata->flags & LM3559_MSG_IND_GREEN) {
-               if (lm3559_debug)
-                       pr_info("%s: Creating MSG Green Indication\n",
-                       __func__);
-               torch_data->msg_ind_green_class_dev.name = "green";
-               torch_data->msg_ind_green_class_dev.brightness_set =
-                       msg_ind_green_set;
-               torch_data->msg_ind_green_class_dev.blink_set =
-                       msg_ind_green_blink;
-               torch_data->msg_ind_red_class_dev.brightness = LED_OFF;
-               torch_data->msg_ind_red_class_dev.max_brightness = 255;
-               err = led_classdev_register((struct device *)
-                       &client->dev, &torch_data->msg_ind_green_class_dev);
-               if (err < 0) {
-                       pr_err("%s: Register Green LED class failed\n",
-                               __func__);
-                       goto err_reg_green_class_failed;
-               }
-       }
-
-       if (torch_data->pdata->flags & LM3559_MSG_IND_BLUE) {
-               if (lm3559_debug)
-                       pr_info("%s: Creating MSG Blue Indication\n",
-                       __func__);
-               torch_data->msg_ind_blue_class_dev.name = "blue";
-               torch_data->msg_ind_blue_class_dev.brightness_set =
-                       msg_ind_blue_set;
-               torch_data->msg_ind_blue_class_dev.blink_set =
-                       msg_ind_blue_blink;
-               torch_data->msg_ind_blue_class_dev.brightness = LED_OFF;
-               torch_data->msg_ind_blue_class_dev.max_brightness = 255;
-
-               err = led_classdev_register((struct device *)
-                       &client->dev, &torch_data->msg_ind_blue_class_dev);
-               if (err < 0) {
-                       pr_err("%s: Register Blue LED class failed\n",
-                               __func__);
-                       goto err_reg_blue_class_failed;
-               }
-       }
 #ifdef DEBUG
-       err = device_create_file(torch_data->led_dev.dev, &dev_attr_registers);
+       err = device_create_file(torch_data->flash_dev.dev,
+               &dev_attr_registers);
        if (err < 0)
                pr_err("%s:File device creation failed: %d\n", __func__, err);
 #endif
 
-       return 0;
-
-err_reg_blue_class_failed:
-       if (torch_data->pdata->flags & LM3559_MSG_IND_GREEN)
-               led_classdev_unregister(&torch_data->msg_ind_green_class_dev);
-err_reg_green_class_failed:
-       if (torch_data->pdata->flags & LM3559_MSG_IND_RED)
-               led_classdev_unregister(&torch_data->msg_ind_red_class_dev);
-err_reg_red_class_failed:
-       if (torch_data->pdata->flags & LM3559_PRIVACY)
-               device_remove_file(torch_data->led_dev.dev,
-                       &dev_attr_privacy_light);
-error7:
-       if (torch_data->pdata->flags & LM3559_FLASH_LIGHT)
-               led_classdev_unregister(&torch_data->spotlight_dev);
-       if (torch_data->pdata->flags & LM3559_FLASH)
-               device_remove_file(torch_data->led_dev.dev,
-                       &dev_attr_strobe_err);
-error6:
-       if (torch_data->pdata->flags & LM3559_FLASH)
-               device_remove_file(torch_data->led_dev.dev,
-                       &dev_attr_camera_strobe);
-error5:
-       if (torch_data->pdata->flags & LM3559_TORCH)
-               device_remove_file(torch_data->led_dev.dev,
-                       &dev_attr_flash_light);
-error4:
-       led_classdev_unregister(&torch_data->led_dev);
-error3:
-error2:
-       kfree(torch_data);
-       return err;
-}
-
-static int lm3559_remove(struct i2c_client *client)
-{
-       struct lm3559_data *torch_data = i2c_get_clientdata(client);
-
-       if (torch_data->pdata->flags & LM3559_FLASH) {
-               device_remove_file(torch_data->led_dev.dev,
-                               &dev_attr_camera_strobe);
-               device_remove_file(torch_data->led_dev.dev,
-                               &dev_attr_strobe_err);
+       torch_data->torch_dev.name = "torch";
+       torch_data->torch_dev.brightness_set = lm3559_torch_brightness_set;
+       torch_data->torch_dev.brightness = LED_OFF;
+       torch_data->torch_dev.max_brightness = LED_FULL;
+       err = led_classdev_register((struct device *)
+               &client->dev, &torch_data->torch_dev);
+       if (err < 0) {
+               pr_err("%s: Register torch led class failed: %d\n",
+                       __func__, err);
+               goto error;
        }
-       if (torch_data->pdata->flags & LM3559_TORCH)
-               device_remove_file(torch_data->led_dev.dev,
-                               &dev_attr_flash_light);
-
-       led_classdev_unregister(&torch_data->led_dev);
-
-       if (torch_data->pdata->flags & LM3559_FLASH_LIGHT)
-               led_classdev_unregister(&torch_data->spotlight_dev);
-
-       if (torch_data->pdata->flags & LM3559_PRIVACY)
-               device_remove_file(torch_data->led_dev.dev,
-                               &dev_attr_privacy_light);
-
-       if (torch_data->pdata->flags & LM3559_MSG_IND_RED)
-               led_classdev_unregister(&torch_data->msg_ind_red_class_dev);
-
-       if (torch_data->pdata->flags & LM3559_MSG_IND_GREEN)
-               led_classdev_unregister(&torch_data->msg_ind_green_class_dev);
-
-       if (torch_data->pdata->flags & LM3559_MSG_IND_BLUE)
-               led_classdev_unregister(&torch_data->msg_ind_blue_class_dev);
 
 #ifdef DEBUG
-       device_remove_file(torch_data->led_dev.dev, &dev_attr_registers);
+       err = device_create_file(torch_data->torch_dev.dev,
+               &dev_attr_registers);
+       if (err < 0)
+               pr_err("%s:File device creation failed: %d\n", __func__, err);
 #endif
-       kfree(torch_data->pdata);
-       kfree(torch_data);
+
        return 0;
+error:
+       lm3559_remove(client);
+       return err;
 }
 
 static const struct i2c_device_id lm3559_id[] = {
index 9357bf80c085e7e485c626c7ebec52ee39cb114c..3bdc37de66fd84eb07cbcc711f3336b69e80a220 100644 (file)
 #define LM3559_NAME "lm3559_led"
 
 
-
 #ifdef __KERNEL__
 
-#define LED_RED                  0x01
-#define LED_GREEN                0x02
-#define LED_BLUE                 0x04
-
-#define LM3559_ERROR_CHECK     (1 << 0)
-#define LM3559_PRIVACY         (1 << 1)
-#define LM3559_TORCH           (1 << 2)
-#define LM3559_FLASH           (1 << 3)
-#define LM3559_FLASH_LIGHT     (1 << 4)
-#define LM3559_MSG_IND_RED     (1 << 5)
-#define LM3559_MSG_IND_GREEN   (1 << 6)
-#define LM3559_MSG_IND_BLUE    (1 << 7)
-
+#define LM3559_FLAG_ERROR_CHECK        0x01
 
 struct lm3559_platform_data {
        uint32_t flags;
-       u8 enable_reg_def;
-       u8 gpio_reg_def;
-       u8 adc_delay_reg_def;
-       u8 vin_monitor_def;
-       u8 torch_brightness_def;
-       u8 flash_brightness_def;
        u8 flash_duration_def;
-       u8 flag_reg_def;
-       u8 config_reg_1_def;
-       u8 config_reg_2_def;
-       u8 privacy_reg_def;
-       u8 msg_ind_reg_def;
-       u8 msg_ind_blink_reg_def;
-       u8 pwm_reg_def;
-       u8 torch_enable_val;
-       u8 flash_enable_val;
-       u8 privacy_enable_val;
-       u8 pwm_val;
-       u8 msg_ind_val;
-       u8 msg_ind_blink_val;
+       u8 vin_monitor_def;
 } __attribute__ ((packed));
 
 #endif /* __KERNEL__ */