leds: Create generic CPCAP led driver
authorDan Murphy <wldm10@motorola.com>
Wed, 2 Jun 2010 12:40:55 +0000 (07:40 -0500)
committerColin Cross <ccross@android.com>
Wed, 6 Oct 2010 23:33:02 +0000 (16:33 -0700)
Commonized the CPCAP LED driver into a single driver for all LEDs
connected to the CPCAP.

Change-Id: Ic62356010f3e1b355f7da757c3f08608765a71da
Signed-off-by: Dan Murphy <wldm10@motorola.com>
drivers/leds/Kconfig
drivers/leds/Makefile
drivers/leds/leds-ld-cpcap-disp.c [deleted file]
drivers/leds/leds-ld-cpcap.c [new file with mode: 0755]
include/linux/leds-ld-cpcap.h
include/linux/spi/cpcap.h

index 79a73be5e836ca95f014775e8e9370c560566dd6..8012334ab14b73ae72797ffdbe68a2d7a679a2de 100644 (file)
@@ -144,7 +144,7 @@ config LEDS_AUO_PANEL
        help
          This option enables support for AUO display backlight driver
 
-config LEDS_CPCAP_DISP
+config LEDS_CPCAP
        tristate "LED Support for Display LEDS connected to CPCAP"
        depends on LEDS_CLASS && MFD_CPCAP
        help
index ac8203b3f07fb6b4d09f03d4cffaa52f1f1b9ff7..975a65694254cf18ef364fc10999d20f8e309565 100644 (file)
@@ -39,7 +39,7 @@ obj-$(CONFIG_LEDS_DELL_NETBOOKS)      += dell-led.o
 obj-$(CONFIG_LEDS_MC13783)             += leds-mc13783.o
 obj-$(CONFIG_LEDS_NS2)                 += leds-ns2.o
 obj-$(CONFIG_LEDS_AUO_PANEL)           += leds-auo-panel-backlight.o
-obj-$(CONFIG_LEDS_CPCAP_DISP)          += leds-ld-cpcap-disp.o
+obj-$(CONFIG_LEDS_CPCAP)               += leds-ld-cpcap.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)          += leds-dac124s085.o
diff --git a/drivers/leds/leds-ld-cpcap-disp.c b/drivers/leds/leds-ld-cpcap-disp.c
deleted file mode 100755 (executable)
index 564e927..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2009 Motorola, Inc.
- *
- * This program is free dispware; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free dispware Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free dispware
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-
-#include <linux/err.h>
-#include <linux/leds.h>
-#include <linux/leds-ld-cpcap.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/regulator/consumer.h>
-#include <linux/spi/cpcap.h>
-#include <linux/spi/cpcap-regbits.h>
-
-struct disp_button_led_data {
-       struct led_classdev disp_button_class_dev;
-       struct cpcap_device *cpcap;
-       struct regulator *regulator;
-       struct work_struct brightness_work;
-       enum led_brightness brightness;
-       int regulator_state;
-};
-
-static void disp_button_set(struct led_classdev *led_cdev,
-                           enum led_brightness brightness)
-{
-       struct disp_button_led_data *disp_button_led_data =
-               container_of(led_cdev, struct disp_button_led_data,
-               disp_button_class_dev);
-
-       if (brightness > 255)
-               brightness = 255;
-
-       disp_button_led_data->brightness = brightness;
-       schedule_work(&disp_button_led_data->brightness_work);
-}
-EXPORT_SYMBOL(disp_button_set);
-
-static void disp_button_brightness_work(struct work_struct *work)
-{
-       int cpcap_status = 0;
-       unsigned short brightness = 0;
-
-       struct disp_button_led_data *disp_button_led_data =
-           container_of(work, struct disp_button_led_data, brightness_work);
-
-       brightness = disp_button_led_data->brightness;
-
-       if (brightness > 0) {
-               brightness = (LD_DISP_BUTTON_DUTY_CYCLE |
-                       LD_DISP_BUTTON_CURRENT | LD_DISP_BUTTON_ON);
-
-               if ((disp_button_led_data->regulator) &&
-                   (disp_button_led_data->regulator_state == 0)) {
-                       regulator_enable(disp_button_led_data->regulator);
-                       disp_button_led_data->regulator_state = 1;
-               }
-
-               cpcap_status = cpcap_regacc_write(disp_button_led_data->cpcap,
-                                                 CPCAP_REG_KLC,
-                                                 brightness,
-                                                 LD_DISP_BUTTON_CPCAP_MASK);
-
-               if (cpcap_status < 0)
-                       pr_err("%s: Writing to the register failed for %i\n",
-                              __func__, cpcap_status);
-
-       } else {
-               if ((disp_button_led_data->regulator) &&
-                   (disp_button_led_data->regulator_state == 1)) {
-                       regulator_disable(disp_button_led_data->regulator);
-                       disp_button_led_data->regulator_state = 0;
-               }
-               /* Due to a HW issue turn off the current then
-               turn off the duty cycle */
-               brightness = 0x01;
-               cpcap_status = cpcap_regacc_write(disp_button_led_data->cpcap,
-                                         CPCAP_REG_KLC, brightness,
-                                         LD_DISP_BUTTON_CPCAP_MASK);
-
-               brightness = 0x00;
-               cpcap_status = cpcap_regacc_write(disp_button_led_data->cpcap,
-                                                 CPCAP_REG_KLC, brightness,
-                                                 LD_DISP_BUTTON_CPCAP_MASK);
-
-               if (cpcap_status < 0)
-                       pr_err("%s: Writing to the register failed for %i\n",
-                              __func__, cpcap_status);
-       }
-}
-
-static int disp_button_probe(struct platform_device *pdev)
-{
-       int ret = 0;
-       struct disp_button_led_data *info;
-
-       if (pdev == NULL) {
-               pr_err("%s: platform data required\n", __func__);
-               return -ENODEV;
-
-       }
-       info = kzalloc(sizeof(struct disp_button_led_data), GFP_KERNEL);
-       if (info == NULL) {
-               ret = -ENOMEM;
-               return ret;
-       }
-
-       info->cpcap = pdev->dev.platform_data;
-       platform_set_drvdata(pdev, info);
-
-       info->regulator = regulator_get(&pdev->dev, LD_SUPPLY);
-       if (IS_ERR(info->regulator)) {
-               pr_err("%s: Cannot get %s regulator\n", __func__, LD_SUPPLY);
-               ret = PTR_ERR(info->regulator);
-               goto exit_request_reg_failed;
-
-       }
-       info->regulator_state = 0;
-
-       info->disp_button_class_dev.name = "button-backlight";
-       info->disp_button_class_dev.brightness_set = disp_button_set;
-       ret = led_classdev_register(&pdev->dev, &info->disp_button_class_dev);
-       if (ret < 0) {
-               pr_err("%s:Register button backlight class failed\n", __func__);
-               goto err_reg_button_class_failed;
-       }
-       INIT_WORK(&info->brightness_work, disp_button_brightness_work);
-       return ret;
-
-err_reg_button_class_failed:
-       if (info->regulator)
-               regulator_put(info->regulator);
-exit_request_reg_failed:
-       kfree(info);
-       return ret;
-}
-
-static int disp_button_remove(struct platform_device *pdev)
-{
-       struct disp_button_led_data *info = platform_get_drvdata(pdev);
-
-       if (info->regulator)
-               regulator_put(info->regulator);
-
-       led_classdev_unregister(&info->disp_button_class_dev);
-       return 0;
-}
-
-static struct platform_driver ld_disp_button_driver = {
-       .probe = disp_button_probe,
-       .remove = disp_button_remove,
-       .driver = {
-                  .name = LD_DISP_BUTTON_DEV,
-       },
-};
-
-static int __init led_disp_button_init(void)
-{
-       return platform_driver_register(&ld_disp_button_driver);
-}
-
-static void __exit led_disp_button_exit(void)
-{
-       platform_driver_unregister(&ld_disp_button_driver);
-}
-
-module_init(led_disp_button_init);
-module_exit(led_disp_button_exit);
-
-MODULE_DESCRIPTION("Display Button Lighting driver");
-MODULE_AUTHOR("Motorola");
-MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-ld-cpcap.c b/drivers/leds/leds-ld-cpcap.c
new file mode 100755 (executable)
index 0000000..b0cebda
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2010 Motorola, Inc.
+ *
+ * This program is free dispware; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free dispware Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free dispware
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+#include <linux/err.h>
+#include <linux/leds.h>
+#include <linux/leds-ld-cpcap.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/cpcap.h>
+#include <linux/spi/cpcap-regbits.h>
+
+struct cpcap_led_data {
+       struct led_classdev cpcap_class_dev;
+       struct cpcap_device *cpcap;
+       struct cpcap_led *pdata;
+       struct regulator *regulator;
+       struct work_struct brightness_work;
+       enum led_brightness brightness;
+       int regulator_state;
+};
+
+static void cpcap_set(struct led_classdev *led_cdev,
+                           enum led_brightness brightness)
+{
+       struct cpcap_led_data *cpcap_led_data =
+               container_of(led_cdev, struct cpcap_led_data,
+               cpcap_class_dev);
+
+       if (brightness > 255)
+               brightness = 255;
+
+       cpcap_led_data->brightness = brightness;
+       schedule_work(&cpcap_led_data->brightness_work);
+}
+EXPORT_SYMBOL(cpcap_set);
+
+static void cpcap_brightness_work(struct work_struct *work)
+{
+       int cpcap_status = 0;
+       unsigned short brightness = 0;
+
+       struct cpcap_led_data *cpcap_led_data =
+           container_of(work, struct cpcap_led_data, brightness_work);
+
+       brightness = cpcap_led_data->brightness;
+
+       if (brightness > 0) {
+               brightness = (cpcap_led_data->pdata->cpcap_duty_cycle |
+                       cpcap_led_data->pdata->cpcap_current | 0x01);
+
+               if ((cpcap_led_data->regulator) &&
+                   (cpcap_led_data->regulator_state == 0)) {
+                       regulator_enable(cpcap_led_data->regulator);
+                       cpcap_led_data->regulator_state = 1;
+               }
+
+               cpcap_status = cpcap_regacc_write(cpcap_led_data->cpcap,
+                               cpcap_led_data->pdata->cpcap_register,
+                               brightness,
+                               cpcap_led_data->pdata->cpcap_mask);
+
+               if (cpcap_status < 0)
+                       pr_err("%s: Writing to the register failed for %i\n",
+                              __func__, cpcap_status);
+
+       } else {
+               if ((cpcap_led_data->regulator) &&
+                   (cpcap_led_data->regulator_state == 1)) {
+                       regulator_disable(cpcap_led_data->regulator);
+                       cpcap_led_data->regulator_state = 0;
+               }
+               /* Due to a HW issue turn off the current then
+               turn off the duty cycle */
+               brightness = 0x01;
+               cpcap_status = cpcap_regacc_write(cpcap_led_data->cpcap,
+                               cpcap_led_data->pdata->cpcap_register,
+                               brightness,
+                               cpcap_led_data->pdata->cpcap_mask);
+
+
+               brightness = 0x00;
+               cpcap_status = cpcap_regacc_write(cpcap_led_data->cpcap,
+                               cpcap_led_data->pdata->cpcap_register,
+                               brightness,
+                               cpcap_led_data->pdata->cpcap_mask);
+
+
+               if (cpcap_status < 0)
+                       pr_err("%s: Writing to the register failed for %i\n",
+                              __func__, cpcap_status);
+       }
+}
+
+static int cpcap_probe(struct platform_device *pdev)
+{
+       int ret = 0;
+       struct cpcap_led_data *info;
+
+       if (pdev == NULL) {
+               pr_err("%s: platform data required\n", __func__);
+               return -ENODEV;
+
+       }
+       info = kzalloc(sizeof(struct cpcap_led_data), GFP_KERNEL);
+       if (info == NULL) {
+               ret = -ENOMEM;
+               return ret;
+       }
+
+       info->pdata = pdev->dev.platform_data;
+       info->cpcap = platform_get_drvdata(pdev);
+       platform_set_drvdata(pdev, info);
+
+       if (info->pdata->led_regulator != NULL) {
+               info->regulator = regulator_get(&pdev->dev,
+                               info->pdata->led_regulator);
+               if (IS_ERR(info->regulator)) {
+                       pr_err("%s: Cannot get %s regulator\n",
+                               __func__, info->pdata->led_regulator);
+                       ret = PTR_ERR(info->regulator);
+                       goto exit_request_reg_failed;
+
+               }
+       }
+       info->regulator_state = 0;
+
+       info->cpcap_class_dev.name = info->pdata->class_name;
+       info->cpcap_class_dev.brightness_set = cpcap_set;
+       ret = led_classdev_register(&pdev->dev, &info->cpcap_class_dev);
+       if (ret < 0) {
+               pr_err("%s:Register %s class failed\n",
+                       __func__, info->cpcap_class_dev.name);
+               goto err_reg_button_class_failed;
+       }
+       INIT_WORK(&info->brightness_work, cpcap_brightness_work);
+       return ret;
+
+err_reg_button_class_failed:
+       if (info->regulator)
+               regulator_put(info->regulator);
+exit_request_reg_failed:
+       kfree(info);
+       return ret;
+}
+
+static int cpcap_remove(struct platform_device *pdev)
+{
+       struct cpcap_led_data *info = platform_get_drvdata(pdev);
+
+       if (info->regulator)
+               regulator_put(info->regulator);
+
+       led_classdev_unregister(&info->cpcap_class_dev);
+       return 0;
+}
+
+static struct platform_driver ld_cpcap_driver = {
+       .probe = cpcap_probe,
+       .remove = cpcap_remove,
+       .driver = {
+                  .name = LD_CPCAP_LED_DRV,
+       },
+};
+
+static int __init led_cpcap_init(void)
+{
+       return platform_driver_register(&ld_cpcap_driver);
+}
+
+static void __exit led_cpcap_exit(void)
+{
+       platform_driver_unregister(&ld_cpcap_driver);
+}
+
+module_init(led_cpcap_init);
+module_exit(led_cpcap_exit);
+
+MODULE_DESCRIPTION("CPCAP Lighting driver");
+MODULE_AUTHOR("Dan Murphy <D.Murphy@Motorola.com>");
+MODULE_LICENSE("GPL");
index 4881fb4fe8f0826cbbdc8f1280e5fa6c0f029dbc..208551be2106d27656f8295c023063ce2a7c3125 100644 (file)
 #ifndef __LED_LD_CPCAP_H__
 #define __LED_LD_CPCAP_H__
 
-#define LD_MSG_IND_DEV "notification-led"
-#define LD_DISP_BUTTON_DEV "button-backlight"
-#define LD_KPAD_DEV "keyboard-backlight"
-#define LD_AF_LED_DEV "af-led"
-#define LD_SUPPLY "sw5"
-
-#define LD_MSG_IND_ON               0x1
-#define LD_MSG_IND_CURRENT          0x2
-#define LD_MSG_IND_LO_CURRENT       0x0
-
-#define LD_MSG_IND_CPCAP_MASK       0x3FF
-
-#define LD_MSG_IND_LOW              0x20
-#define LD_MSG_IND_LOW_MED          0x20
-#define LD_MSG_IND_MEDIUM           0x30
-#define LD_MSG_IND_MED_HIGH         0x40
-#define LD_MSG_IND_HIGH             0x50
+#ifdef __KERNEL__
 
-#define LD_LED_RED                  0x01
-#define LD_LED_GREEN                0x02
-#define LD_LED_BLUE                 0x04
-
-#define LD_DISP_BUTTON_ON           0x1
-#define LD_DISP_BUTTON_CURRENT      0x0
-#define LD_DISP_BUTTON_DUTY_CYCLE      0x2A0
-#define LD_DISP_BUTTON_CPCAP_MASK      0x3FF
-
-#define LD_BLED_CPCAP_DUTY_CYCLE    0x41
-#define LD_BLED_CPCAP_MASK          0x3FF
-#define LD_BLED_CPCAP_CURRENT       0x6
-
-#define LD_ALT_ADBL_CURRENT         0x4
+#define LD_CPCAP_LED_DRV "cpcap_led_driver"
 
+#define LD_DISP_BUTTON_DEV "button-backlight"
+#define LD_PRIVACY_LED_DEV "privacy-led"
+
+struct cpcap_display_led {
+       unsigned int display_reg;
+       unsigned int display_mask;
+       unsigned int display_on;
+       unsigned int display_off;
+       unsigned int display_init;
+       unsigned int poll_intvl;
+       unsigned int zone0;
+       unsigned int zone1;
+       unsigned int zone2;
+       unsigned int zone3;
+       unsigned int zone4;
+};
+
+struct cpcap_led {
+       unsigned int cpcap_register;
+       unsigned int cpcap_mask;
+       unsigned int on_val;
+       unsigned int off_val;
+       unsigned int cpcap_duty_cycle;
+       unsigned int cpcap_current;
+       char *class_name;
+       char *led_regulator;
+};
+
+#endif  /* __KERNEL__ */
 #endif  /* __LED_LD_CPCAP_H__ */
index a89396ff0ad47b8ed6ed9cf599df20428412d1dc..13df90046c35312818b0b39853fbccd4b0e81d91 100644 (file)
@@ -65,7 +65,6 @@ enum cpcap_regulator_id {
        CPCAP_VVIB,
        CPCAP_VUSB,
        CPCAP_VAUDIO,
-
        CPCAP_NUM_REGULATORS
 };
 
@@ -504,48 +503,6 @@ struct cpcap_adc_ato {
        unsigned short atox_ps_factor_out;
 };
 
-struct cpcap_display_led {
-       unsigned int display_reg;
-       unsigned int display_mask;
-       unsigned int display_on;
-       unsigned int display_off;
-       unsigned int display_init;
-       unsigned int poll_intvl;
-       unsigned int zone0;
-       unsigned int zone1;
-       unsigned int zone2;
-       unsigned int zone3;
-       unsigned int zone4;
-};
-
-struct cpcap_button_led {
-       unsigned int button_reg;
-       unsigned int button_mask;
-       unsigned int button_on;
-       unsigned int button_off;
-};
-
-struct cpcap_kpad_led {
-       unsigned int kpad_reg;
-       unsigned int kpad_mask;
-       unsigned int kpad_on;
-       unsigned int kpad_off;
-};
-
-struct cpcap_rgb_led {
-       unsigned int rgb_reg;
-       unsigned int rgb_mask;
-       unsigned int rgb_on;
-       unsigned int rgb_off;
-};
-
-struct cpcap_leds {
-       struct cpcap_display_led display_led;
-       struct cpcap_button_led button_led;
-       struct cpcap_kpad_led kpad_led;
-       struct cpcap_rgb_led rgb_led;
-};
-
 struct cpcap_batt_data {
        int status;
        int health;
@@ -581,7 +538,6 @@ struct cpcap_platform_data {
        unsigned short *regulator_off_mode_values;
        struct regulator_init_data *regulator_init;
        struct cpcap_adc_ato *adc_ato;
-       struct cpcap_leds *leds;
        void (*ac_changed)(struct power_supply *,
                           struct cpcap_batt_ac_data *);
        void (*batt_changed)(struct power_supply *,