diff options
Diffstat (limited to 'drivers/leds/leds-lp5523.c')
-rw-r--r-- | drivers/leds/leds-lp5523.c | 56 |
1 files changed, 16 insertions, 40 deletions
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c index 6cb41607519d..d0c4068ecddd 100644 --- a/drivers/leds/leds-lp5523.c +++ b/drivers/leds/leds-lp5523.c | |||
@@ -105,7 +105,6 @@ | |||
105 | #define SHIFT_MASK(id) (((id) - 1) * 2) | 105 | #define SHIFT_MASK(id) (((id) - 1) * 2) |
106 | 106 | ||
107 | struct lp5523_engine { | 107 | struct lp5523_engine { |
108 | const struct attribute_group *attributes; | ||
109 | int id; | 108 | int id; |
110 | u8 mode; | 109 | u8 mode; |
111 | u8 prog_page; | 110 | u8 prog_page; |
@@ -403,14 +402,23 @@ static ssize_t store_engine_leds(struct device *dev, | |||
403 | struct i2c_client *client = to_i2c_client(dev); | 402 | struct i2c_client *client = to_i2c_client(dev); |
404 | struct lp5523_chip *chip = i2c_get_clientdata(client); | 403 | struct lp5523_chip *chip = i2c_get_clientdata(client); |
405 | u16 mux = 0; | 404 | u16 mux = 0; |
405 | ssize_t ret; | ||
406 | 406 | ||
407 | if (lp5523_mux_parse(buf, &mux, len)) | 407 | if (lp5523_mux_parse(buf, &mux, len)) |
408 | return -EINVAL; | 408 | return -EINVAL; |
409 | 409 | ||
410 | mutex_lock(&chip->lock); | ||
411 | ret = -EINVAL; | ||
412 | if (chip->engines[nr - 1].mode != LP5523_CMD_LOAD) | ||
413 | goto leave; | ||
414 | |||
410 | if (lp5523_load_mux(&chip->engines[nr - 1], mux)) | 415 | if (lp5523_load_mux(&chip->engines[nr - 1], mux)) |
411 | return -EINVAL; | 416 | goto leave; |
412 | 417 | ||
413 | return len; | 418 | ret = len; |
419 | leave: | ||
420 | mutex_unlock(&chip->lock); | ||
421 | return ret; | ||
414 | } | 422 | } |
415 | 423 | ||
416 | #define store_leds(nr) \ | 424 | #define store_leds(nr) \ |
@@ -556,7 +564,11 @@ static int lp5523_do_store_load(struct lp5523_engine *engine, | |||
556 | 564 | ||
557 | mutex_lock(&chip->lock); | 565 | mutex_lock(&chip->lock); |
558 | 566 | ||
559 | 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 | |||
560 | mutex_unlock(&chip->lock); | 572 | mutex_unlock(&chip->lock); |
561 | 573 | ||
562 | if (ret) { | 574 | if (ret) { |
@@ -737,37 +749,18 @@ static struct attribute *lp5523_attributes[] = { | |||
737 | &dev_attr_engine2_mode.attr, | 749 | &dev_attr_engine2_mode.attr, |
738 | &dev_attr_engine3_mode.attr, | 750 | &dev_attr_engine3_mode.attr, |
739 | &dev_attr_selftest.attr, | 751 | &dev_attr_selftest.attr, |
740 | NULL | ||
741 | }; | ||
742 | |||
743 | static struct attribute *lp5523_engine1_attributes[] = { | ||
744 | &dev_attr_engine1_load.attr, | 752 | &dev_attr_engine1_load.attr, |
745 | &dev_attr_engine1_leds.attr, | 753 | &dev_attr_engine1_leds.attr, |
746 | NULL | ||
747 | }; | ||
748 | |||
749 | static struct attribute *lp5523_engine2_attributes[] = { | ||
750 | &dev_attr_engine2_load.attr, | 754 | &dev_attr_engine2_load.attr, |
751 | &dev_attr_engine2_leds.attr, | 755 | &dev_attr_engine2_leds.attr, |
752 | NULL | ||
753 | }; | ||
754 | |||
755 | static struct attribute *lp5523_engine3_attributes[] = { | ||
756 | &dev_attr_engine3_load.attr, | 756 | &dev_attr_engine3_load.attr, |
757 | &dev_attr_engine3_leds.attr, | 757 | &dev_attr_engine3_leds.attr, |
758 | NULL | ||
759 | }; | 758 | }; |
760 | 759 | ||
761 | static const struct attribute_group lp5523_group = { | 760 | static const struct attribute_group lp5523_group = { |
762 | .attrs = lp5523_attributes, | 761 | .attrs = lp5523_attributes, |
763 | }; | 762 | }; |
764 | 763 | ||
765 | static const struct attribute_group lp5523_engine_group[] = { | ||
766 | {.attrs = lp5523_engine1_attributes }, | ||
767 | {.attrs = lp5523_engine2_attributes }, | ||
768 | {.attrs = lp5523_engine3_attributes }, | ||
769 | }; | ||
770 | |||
771 | static int lp5523_register_sysfs(struct i2c_client *client) | 764 | static int lp5523_register_sysfs(struct i2c_client *client) |
772 | { | 765 | { |
773 | struct device *dev = &client->dev; | 766 | struct device *dev = &client->dev; |
@@ -788,10 +781,6 @@ static void lp5523_unregister_sysfs(struct i2c_client *client) | |||
788 | 781 | ||
789 | sysfs_remove_group(&dev->kobj, &lp5523_group); | 782 | sysfs_remove_group(&dev->kobj, &lp5523_group); |
790 | 783 | ||
791 | for (i = 0; i < ARRAY_SIZE(chip->engines); i++) | ||
792 | if (chip->engines[i].mode == LP5523_CMD_LOAD) | ||
793 | sysfs_remove_group(&dev->kobj, &lp5523_engine_group[i]); | ||
794 | |||
795 | for (i = 0; i < chip->num_leds; i++) | 784 | for (i = 0; i < chip->num_leds; i++) |
796 | sysfs_remove_group(&chip->leds[i].cdev.dev->kobj, | 785 | sysfs_remove_group(&chip->leds[i].cdev.dev->kobj, |
797 | &lp5523_led_attribute_group); | 786 | &lp5523_led_attribute_group); |
@@ -802,10 +791,6 @@ static void lp5523_unregister_sysfs(struct i2c_client *client) | |||
802 | /*--------------------------------------------------------------*/ | 791 | /*--------------------------------------------------------------*/ |
803 | static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode) | 792 | static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode) |
804 | { | 793 | { |
805 | /* engine to chip */ | ||
806 | struct lp5523_chip *chip = engine_to_lp5523(engine); | ||
807 | struct i2c_client *client = chip->client; | ||
808 | struct device *dev = &client->dev; | ||
809 | int ret = 0; | 794 | int ret = 0; |
810 | 795 | ||
811 | /* if in that mode already do nothing, except for run */ | 796 | /* if in that mode already do nothing, except for run */ |
@@ -817,18 +802,10 @@ static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode) | |||
817 | } else if (mode == LP5523_CMD_LOAD) { | 802 | } else if (mode == LP5523_CMD_LOAD) { |
818 | lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); | 803 | lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); |
819 | lp5523_set_engine_mode(engine, LP5523_CMD_LOAD); | 804 | lp5523_set_engine_mode(engine, LP5523_CMD_LOAD); |
820 | |||
821 | ret = sysfs_create_group(&dev->kobj, engine->attributes); | ||
822 | if (ret) | ||
823 | return ret; | ||
824 | } else if (mode == LP5523_CMD_DISABLED) { | 805 | } else if (mode == LP5523_CMD_DISABLED) { |
825 | lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); | 806 | lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); |
826 | } | 807 | } |
827 | 808 | ||
828 | /* remove load attribute from sysfs if not in load mode */ | ||
829 | if (engine->mode == LP5523_CMD_LOAD && mode != LP5523_CMD_LOAD) | ||
830 | sysfs_remove_group(&dev->kobj, engine->attributes); | ||
831 | |||
832 | engine->mode = mode; | 809 | engine->mode = mode; |
833 | 810 | ||
834 | return ret; | 811 | return ret; |
@@ -845,7 +822,6 @@ static int __init lp5523_init_engine(struct lp5523_engine *engine, int id) | |||
845 | engine->engine_mask = LP5523_ENG_MASK_BASE >> SHIFT_MASK(id); | 822 | engine->engine_mask = LP5523_ENG_MASK_BASE >> SHIFT_MASK(id); |
846 | engine->prog_page = id - 1; | 823 | engine->prog_page = id - 1; |
847 | engine->mux_page = id + 2; | 824 | engine->mux_page = id + 2; |
848 | engine->attributes = &lp5523_engine_group[id - 1]; | ||
849 | 825 | ||
850 | return 0; | 826 | return 0; |
851 | } | 827 | } |