aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds/leds-lp5523.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds/leds-lp5523.c')
-rw-r--r--drivers/leds/leds-lp5523.c75
1 files changed, 46 insertions, 29 deletions
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index fbc12acada95..97994ffdc014 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -104,6 +104,11 @@
104#define LED_ACTIVE(mux, led) (!!(mux & (0x0001 << led))) 104#define LED_ACTIVE(mux, led) (!!(mux & (0x0001 << led)))
105#define SHIFT_MASK(id) (((id) - 1) * 2) 105#define SHIFT_MASK(id) (((id) - 1) * 2)
106 106
107enum lp5523_chip_id {
108 LP5523,
109 LP55231,
110};
111
107struct lp5523_engine { 112struct lp5523_engine {
108 int id; 113 int id;
109 u8 mode; 114 u8 mode;
@@ -150,7 +155,7 @@ static inline struct lp5523_chip *led_to_lp5523(struct lp5523_led *led)
150 leds[led->id]); 155 leds[led->id]);
151} 156}
152 157
153static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode); 158static void lp5523_set_mode(struct lp5523_engine *engine, u8 mode);
154static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode); 159static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode);
155static int lp5523_load_program(struct lp5523_engine *engine, const u8 *pattern); 160static int lp5523_load_program(struct lp5523_engine *engine, const u8 *pattern);
156 161
@@ -177,7 +182,7 @@ static int lp5523_detect(struct i2c_client *client)
177 int ret; 182 int ret;
178 u8 buf; 183 u8 buf;
179 184
180 ret = lp5523_write(client, LP5523_REG_ENABLE, 0x40); 185 ret = lp5523_write(client, LP5523_REG_ENABLE, LP5523_ENABLE);
181 if (ret) 186 if (ret)
182 return ret; 187 return ret;
183 ret = lp5523_read(client, LP5523_REG_ENABLE, &buf); 188 ret = lp5523_read(client, LP5523_REG_ENABLE, &buf);
@@ -338,7 +343,8 @@ static int lp5523_mux_parse(const char *buf, u16 *mux, size_t len)
338{ 343{
339 int i; 344 int i;
340 u16 tmp_mux = 0; 345 u16 tmp_mux = 0;
341 len = len < LP5523_LEDS ? len : LP5523_LEDS; 346
347 len = min_t(int, len, LP5523_LEDS);
342 for (i = 0; i < len; i++) { 348 for (i = 0; i < len; i++) {
343 switch (buf[i]) { 349 switch (buf[i]) {
344 case '1': 350 case '1':
@@ -546,6 +552,9 @@ static int lp5523_do_store_load(struct lp5523_engine *engine,
546 unsigned cmd; 552 unsigned cmd;
547 u8 pattern[LP5523_PROGRAM_LENGTH] = {0}; 553 u8 pattern[LP5523_PROGRAM_LENGTH] = {0};
548 554
555 if (engine->mode != LP5523_CMD_LOAD)
556 return -EINVAL;
557
549 while ((offset < len - 1) && (i < LP5523_PROGRAM_LENGTH)) { 558 while ((offset < len - 1) && (i < LP5523_PROGRAM_LENGTH)) {
550 /* separate sscanfs because length is working only for %s */ 559 /* separate sscanfs because length is working only for %s */
551 ret = sscanf(buf + offset, "%2s%n ", c, &nrchars); 560 ret = sscanf(buf + offset, "%2s%n ", c, &nrchars);
@@ -563,12 +572,7 @@ static int lp5523_do_store_load(struct lp5523_engine *engine,
563 goto fail; 572 goto fail;
564 573
565 mutex_lock(&chip->lock); 574 mutex_lock(&chip->lock);
566 575 ret = lp5523_load_program(engine, pattern);
567 if (engine->mode == LP5523_CMD_LOAD)
568 ret = lp5523_load_program(engine, pattern);
569 else
570 ret = -EINVAL;
571
572 mutex_unlock(&chip->lock); 576 mutex_unlock(&chip->lock);
573 577
574 if (ret) { 578 if (ret) {
@@ -755,6 +759,7 @@ static struct attribute *lp5523_attributes[] = {
755 &dev_attr_engine2_leds.attr, 759 &dev_attr_engine2_leds.attr,
756 &dev_attr_engine3_load.attr, 760 &dev_attr_engine3_load.attr,
757 &dev_attr_engine3_leds.attr, 761 &dev_attr_engine3_leds.attr,
762 NULL,
758}; 763};
759 764
760static const struct attribute_group lp5523_group = { 765static const struct attribute_group lp5523_group = {
@@ -789,26 +794,28 @@ static void lp5523_unregister_sysfs(struct i2c_client *client)
789/*--------------------------------------------------------------*/ 794/*--------------------------------------------------------------*/
790/* Set chip operating mode */ 795/* Set chip operating mode */
791/*--------------------------------------------------------------*/ 796/*--------------------------------------------------------------*/
792static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode) 797static void lp5523_set_mode(struct lp5523_engine *engine, u8 mode)
793{ 798{
794 int ret = 0;
795
796 /* if in that mode already do nothing, except for run */ 799 /* if in that mode already do nothing, except for run */
797 if (mode == engine->mode && mode != LP5523_CMD_RUN) 800 if (mode == engine->mode && mode != LP5523_CMD_RUN)
798 return 0; 801 return;
799 802
800 if (mode == LP5523_CMD_RUN) { 803 switch (mode) {
801 ret = lp5523_run_program(engine); 804 case LP5523_CMD_RUN:
802 } else if (mode == LP5523_CMD_LOAD) { 805 lp5523_run_program(engine);
806 break;
807 case LP5523_CMD_LOAD:
803 lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); 808 lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED);
804 lp5523_set_engine_mode(engine, LP5523_CMD_LOAD); 809 lp5523_set_engine_mode(engine, LP5523_CMD_LOAD);
805 } else if (mode == LP5523_CMD_DISABLED) { 810 break;
811 case LP5523_CMD_DISABLED:
806 lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); 812 lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED);
813 break;
814 default:
815 return;
807 } 816 }
808 817
809 engine->mode = mode; 818 engine->mode = mode;
810
811 return ret;
812} 819}
813 820
814/*--------------------------------------------------------------*/ 821/*--------------------------------------------------------------*/
@@ -827,7 +834,8 @@ static int __init lp5523_init_engine(struct lp5523_engine *engine, int id)
827} 834}
828 835
829static int __devinit lp5523_init_led(struct lp5523_led *led, struct device *dev, 836static int __devinit lp5523_init_led(struct lp5523_led *led, struct device *dev,
830 int chan, struct lp5523_platform_data *pdata) 837 int chan, struct lp5523_platform_data *pdata,
838 const char *chip_name)
831{ 839{
832 char name[32]; 840 char name[32];
833 int res; 841 int res;
@@ -846,10 +854,14 @@ static int __devinit lp5523_init_led(struct lp5523_led *led, struct device *dev,
846 return -EINVAL; 854 return -EINVAL;
847 } 855 }
848 856
849 snprintf(name, sizeof(name), "%s:channel%d", 857 if (pdata->led_config[chan].name) {
850 pdata->label ?: "lp5523", chan); 858 led->cdev.name = pdata->led_config[chan].name;
859 } else {
860 snprintf(name, sizeof(name), "%s:channel%d",
861 pdata->label ? : chip_name, chan);
862 led->cdev.name = name;
863 }
851 864
852 led->cdev.name = name;
853 led->cdev.brightness_set = lp5523_set_brightness; 865 led->cdev.brightness_set = lp5523_set_brightness;
854 res = led_classdev_register(dev, &led->cdev); 866 res = led_classdev_register(dev, &led->cdev);
855 if (res < 0) { 867 if (res < 0) {
@@ -917,7 +929,7 @@ static int __devinit lp5523_probe(struct i2c_client *client,
917 if (ret) 929 if (ret)
918 goto fail1; 930 goto fail1;
919 931
920 dev_info(&client->dev, "LP5523 Programmable led chip found\n"); 932 dev_info(&client->dev, "%s Programmable led chip found\n", id->name);
921 933
922 /* Initialize engines */ 934 /* Initialize engines */
923 for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { 935 for (i = 0; i < ARRAY_SIZE(chip->engines); i++) {
@@ -945,7 +957,8 @@ static int __devinit lp5523_probe(struct i2c_client *client,
945 INIT_WORK(&chip->leds[led].brightness_work, 957 INIT_WORK(&chip->leds[led].brightness_work,
946 lp5523_led_brightness_work); 958 lp5523_led_brightness_work);
947 959
948 ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata); 960 ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata,
961 id->name);
949 if (ret) { 962 if (ret) {
950 dev_err(&client->dev, "error initializing leds\n"); 963 dev_err(&client->dev, "error initializing leds\n");
951 goto fail2; 964 goto fail2;
@@ -970,7 +983,7 @@ static int __devinit lp5523_probe(struct i2c_client *client,
970fail2: 983fail2:
971 for (i = 0; i < chip->num_leds; i++) { 984 for (i = 0; i < chip->num_leds; i++) {
972 led_classdev_unregister(&chip->leds[i].cdev); 985 led_classdev_unregister(&chip->leds[i].cdev);
973 cancel_work_sync(&chip->leds[i].brightness_work); 986 flush_work(&chip->leds[i].brightness_work);
974 } 987 }
975fail1: 988fail1:
976 if (pdata->enable) 989 if (pdata->enable)
@@ -985,11 +998,14 @@ static int lp5523_remove(struct i2c_client *client)
985 struct lp5523_chip *chip = i2c_get_clientdata(client); 998 struct lp5523_chip *chip = i2c_get_clientdata(client);
986 int i; 999 int i;
987 1000
1001 /* Disable engine mode */
1002 lp5523_write(client, LP5523_REG_OP_MODE, LP5523_CMD_DISABLED);
1003
988 lp5523_unregister_sysfs(client); 1004 lp5523_unregister_sysfs(client);
989 1005
990 for (i = 0; i < chip->num_leds; i++) { 1006 for (i = 0; i < chip->num_leds; i++) {
991 led_classdev_unregister(&chip->leds[i].cdev); 1007 led_classdev_unregister(&chip->leds[i].cdev);
992 cancel_work_sync(&chip->leds[i].brightness_work); 1008 flush_work(&chip->leds[i].brightness_work);
993 } 1009 }
994 1010
995 if (chip->pdata->enable) 1011 if (chip->pdata->enable)
@@ -1000,7 +1016,8 @@ static int lp5523_remove(struct i2c_client *client)
1000} 1016}
1001 1017
1002static const struct i2c_device_id lp5523_id[] = { 1018static const struct i2c_device_id lp5523_id[] = {
1003 { "lp5523", 0 }, 1019 { "lp5523", LP5523 },
1020 { "lp55231", LP55231 },
1004 { } 1021 { }
1005}; 1022};
1006 1023
@@ -1008,7 +1025,7 @@ MODULE_DEVICE_TABLE(i2c, lp5523_id);
1008 1025
1009static struct i2c_driver lp5523_driver = { 1026static struct i2c_driver lp5523_driver = {
1010 .driver = { 1027 .driver = {
1011 .name = "lp5523", 1028 .name = "lp5523x",
1012 }, 1029 },
1013 .probe = lp5523_probe, 1030 .probe = lp5523_probe,
1014 .remove = lp5523_remove, 1031 .remove = lp5523_remove,