diff options
author | Milo(Woogyom) Kim <milo.kim@ti.com> | 2013-02-05 05:06:27 -0500 |
---|---|---|
committer | Bryan Wu <cooloney@gmail.com> | 2013-02-06 18:59:28 -0500 |
commit | 9e9b3db1b2f725bacaf1b7e8708a0c78265bde97 (patch) | |
tree | 498353c79883feb33c7ea93dda7742eb7c1b7dcc | |
parent | 6ce6176263393dd80b9a537c1e1462b8529f240b (diff) |
leds-lp55xx: use lp55xx common led registration function
LED class devices are registered in lp5521_register_leds() and
lp5523_register_leds().
Two separate functions are merged into consolidated lp55xx function,
lp55xx_register_leds().
Error handling fix:
Unregistering LEDS are handled in lp55xx_register_leds() when LED registration
failure occurs. So each driver error handler is changed to 'err_register_leds'
Chip dependency: 'brightness_work_fn' and 'set_led_current'
To make the structure abstract, both functions are configured in each driver.
Those functions should be done by each driver because register control is
chip-dependant work.
lp55xx_init_led: skeleton
Will be filled in next patch
Signed-off-by: Milo(Woogyom) Kim <milo.kim@ti.com>
Signed-off-by: Bryan Wu <cooloney@gmail.com>
-rw-r--r-- | drivers/leds/leds-lp5521.c | 43 | ||||
-rw-r--r-- | drivers/leds/leds-lp5523.c | 45 | ||||
-rw-r--r-- | drivers/leds/leds-lp55xx-common.c | 55 | ||||
-rw-r--r-- | drivers/leds/leds-lp55xx-common.h | 11 |
4 files changed, 72 insertions, 82 deletions
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c index dd4526e168fa..dc58f4106d09 100644 --- a/drivers/leds/leds-lp5521.c +++ b/drivers/leds/leds-lp5521.c | |||
@@ -738,44 +738,6 @@ static int lp5521_init_led(struct lp5521_led *led, | |||
738 | return 0; | 738 | return 0; |
739 | } | 739 | } |
740 | 740 | ||
741 | static int lp5521_register_leds(struct lp5521_chip *chip) | ||
742 | { | ||
743 | struct lp5521_platform_data *pdata = chip->pdata; | ||
744 | struct i2c_client *client = chip->client; | ||
745 | int i; | ||
746 | int led; | ||
747 | int ret; | ||
748 | |||
749 | /* Initialize leds */ | ||
750 | chip->num_channels = pdata->num_channels; | ||
751 | chip->num_leds = 0; | ||
752 | led = 0; | ||
753 | for (i = 0; i < pdata->num_channels; i++) { | ||
754 | /* Do not initialize channels that are not connected */ | ||
755 | if (pdata->led_config[i].led_current == 0) | ||
756 | continue; | ||
757 | |||
758 | ret = lp5521_init_led(&chip->leds[led], client, i, pdata); | ||
759 | if (ret) { | ||
760 | dev_err(&client->dev, "error initializing leds\n"); | ||
761 | return ret; | ||
762 | } | ||
763 | chip->num_leds++; | ||
764 | |||
765 | chip->leds[led].id = led; | ||
766 | /* Set initial LED current */ | ||
767 | lp5521_set_led_current(chip, led, | ||
768 | chip->leds[led].led_current); | ||
769 | |||
770 | INIT_WORK(&(chip->leds[led].brightness_work), | ||
771 | lp5521_led_brightness_work); | ||
772 | |||
773 | led++; | ||
774 | } | ||
775 | |||
776 | return 0; | ||
777 | } | ||
778 | |||
779 | static void lp5521_unregister_leds(struct lp5521_chip *chip) | 741 | static void lp5521_unregister_leds(struct lp5521_chip *chip) |
780 | { | 742 | { |
781 | int i; | 743 | int i; |
@@ -836,9 +798,9 @@ static int lp5521_probe(struct i2c_client *client, | |||
836 | 798 | ||
837 | dev_info(&client->dev, "%s programmable led chip found\n", id->name); | 799 | dev_info(&client->dev, "%s programmable led chip found\n", id->name); |
838 | 800 | ||
839 | ret = lp5521_register_leds(old_chip); | 801 | ret = lp55xx_register_leds(led, chip); |
840 | if (ret) | 802 | if (ret) |
841 | goto fail2; | 803 | goto err_register_leds; |
842 | 804 | ||
843 | ret = lp5521_register_sysfs(client); | 805 | ret = lp5521_register_sysfs(client); |
844 | if (ret) { | 806 | if (ret) { |
@@ -848,6 +810,7 @@ static int lp5521_probe(struct i2c_client *client, | |||
848 | return ret; | 810 | return ret; |
849 | fail2: | 811 | fail2: |
850 | lp5521_unregister_leds(old_chip); | 812 | lp5521_unregister_leds(old_chip); |
813 | err_register_leds: | ||
851 | lp55xx_deinit_device(chip); | 814 | lp55xx_deinit_device(chip); |
852 | err_init: | 815 | err_init: |
853 | return ret; | 816 | return ret; |
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c index 3f506e3d4986..41ac502ff82f 100644 --- a/drivers/leds/leds-lp5523.c +++ b/drivers/leds/leds-lp5523.c | |||
@@ -822,46 +822,6 @@ static int lp5523_init_led(struct lp5523_led *led, struct device *dev, | |||
822 | return 0; | 822 | return 0; |
823 | } | 823 | } |
824 | 824 | ||
825 | static int lp5523_register_leds(struct lp5523_chip *chip, const char *name) | ||
826 | { | ||
827 | struct lp5523_platform_data *pdata = chip->pdata; | ||
828 | struct i2c_client *client = chip->client; | ||
829 | int i; | ||
830 | int led; | ||
831 | int ret; | ||
832 | |||
833 | /* Initialize leds */ | ||
834 | chip->num_channels = pdata->num_channels; | ||
835 | chip->num_leds = 0; | ||
836 | led = 0; | ||
837 | for (i = 0; i < pdata->num_channels; i++) { | ||
838 | /* Do not initialize channels that are not connected */ | ||
839 | if (pdata->led_config[i].led_current == 0) | ||
840 | continue; | ||
841 | |||
842 | INIT_WORK(&chip->leds[led].brightness_work, | ||
843 | lp5523_led_brightness_work); | ||
844 | |||
845 | ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata, | ||
846 | name); | ||
847 | if (ret) { | ||
848 | dev_err(&client->dev, "error initializing leds\n"); | ||
849 | return ret; | ||
850 | } | ||
851 | chip->num_leds++; | ||
852 | |||
853 | chip->leds[led].id = led; | ||
854 | /* Set LED current */ | ||
855 | lp5523_write(client, | ||
856 | LP5523_REG_LED_CURRENT_BASE + chip->leds[led].chan_nr, | ||
857 | chip->leds[led].led_current); | ||
858 | |||
859 | led++; | ||
860 | } | ||
861 | |||
862 | return 0; | ||
863 | } | ||
864 | |||
865 | static void lp5523_unregister_leds(struct lp5523_chip *chip) | 825 | static void lp5523_unregister_leds(struct lp5523_chip *chip) |
866 | { | 826 | { |
867 | int i; | 827 | int i; |
@@ -922,9 +882,9 @@ static int lp5523_probe(struct i2c_client *client, | |||
922 | 882 | ||
923 | dev_info(&client->dev, "%s Programmable led chip found\n", id->name); | 883 | dev_info(&client->dev, "%s Programmable led chip found\n", id->name); |
924 | 884 | ||
925 | ret = lp5523_register_leds(old_chip, id->name); | 885 | ret = lp55xx_register_leds(led, chip); |
926 | if (ret) | 886 | if (ret) |
927 | goto fail2; | 887 | goto err_register_leds; |
928 | 888 | ||
929 | ret = lp5523_register_sysfs(client); | 889 | ret = lp5523_register_sysfs(client); |
930 | if (ret) { | 890 | if (ret) { |
@@ -934,6 +894,7 @@ static int lp5523_probe(struct i2c_client *client, | |||
934 | return ret; | 894 | return ret; |
935 | fail2: | 895 | fail2: |
936 | lp5523_unregister_leds(old_chip); | 896 | lp5523_unregister_leds(old_chip); |
897 | err_register_leds: | ||
937 | lp55xx_deinit_device(chip); | 898 | lp55xx_deinit_device(chip); |
938 | err_init: | 899 | err_init: |
939 | return ret; | 900 | return ret; |
diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c index bcabf2cb949a..1fab1d1c4502 100644 --- a/drivers/leds/leds-lp55xx-common.c +++ b/drivers/leds/leds-lp55xx-common.c | |||
@@ -63,6 +63,12 @@ static int lp55xx_post_init_device(struct lp55xx_chip *chip) | |||
63 | return cfg->post_init_device(chip); | 63 | return cfg->post_init_device(chip); |
64 | } | 64 | } |
65 | 65 | ||
66 | static int lp55xx_init_led(struct lp55xx_led *led, | ||
67 | struct lp55xx_chip *chip, int chan) | ||
68 | { | ||
69 | return 0; | ||
70 | } | ||
71 | |||
66 | int lp55xx_write(struct lp55xx_chip *chip, u8 reg, u8 val) | 72 | int lp55xx_write(struct lp55xx_chip *chip, u8 reg, u8 val) |
67 | { | 73 | { |
68 | return i2c_smbus_write_byte_data(chip->cl, reg, val); | 74 | return i2c_smbus_write_byte_data(chip->cl, reg, val); |
@@ -170,6 +176,55 @@ void lp55xx_deinit_device(struct lp55xx_chip *chip) | |||
170 | } | 176 | } |
171 | EXPORT_SYMBOL_GPL(lp55xx_deinit_device); | 177 | EXPORT_SYMBOL_GPL(lp55xx_deinit_device); |
172 | 178 | ||
179 | int lp55xx_register_leds(struct lp55xx_led *led, struct lp55xx_chip *chip) | ||
180 | { | ||
181 | struct lp55xx_platform_data *pdata = chip->pdata; | ||
182 | struct lp55xx_device_config *cfg = chip->cfg; | ||
183 | int num_channels = pdata->num_channels; | ||
184 | struct lp55xx_led *each; | ||
185 | u8 led_current; | ||
186 | int ret; | ||
187 | int i; | ||
188 | |||
189 | if (!cfg->brightness_work_fn) { | ||
190 | dev_err(&chip->cl->dev, "empty brightness configuration\n"); | ||
191 | return -EINVAL; | ||
192 | } | ||
193 | |||
194 | for (i = 0; i < num_channels; i++) { | ||
195 | |||
196 | /* do not initialize channels that are not connected */ | ||
197 | if (pdata->led_config[i].led_current == 0) | ||
198 | continue; | ||
199 | |||
200 | led_current = pdata->led_config[i].led_current; | ||
201 | each = led + i; | ||
202 | ret = lp55xx_init_led(each, chip, i); | ||
203 | if (ret) | ||
204 | goto err_init_led; | ||
205 | |||
206 | INIT_WORK(&each->brightness_work, cfg->brightness_work_fn); | ||
207 | |||
208 | chip->num_leds++; | ||
209 | each->chip = chip; | ||
210 | |||
211 | /* setting led current at each channel */ | ||
212 | if (cfg->set_led_current) | ||
213 | cfg->set_led_current(each, led_current); | ||
214 | } | ||
215 | |||
216 | return 0; | ||
217 | |||
218 | err_init_led: | ||
219 | for (i = 0; i < chip->num_leds; i++) { | ||
220 | each = led + i; | ||
221 | led_classdev_unregister(&each->cdev); | ||
222 | flush_work(&each->brightness_work); | ||
223 | } | ||
224 | return ret; | ||
225 | } | ||
226 | EXPORT_SYMBOL_GPL(lp55xx_register_leds); | ||
227 | |||
173 | MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>"); | 228 | MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>"); |
174 | MODULE_DESCRIPTION("LP55xx Common Driver"); | 229 | MODULE_DESCRIPTION("LP55xx Common Driver"); |
175 | MODULE_LICENSE("GPL"); | 230 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/leds/leds-lp55xx-common.h b/drivers/leds/leds-lp55xx-common.h index 908b00a56b7e..219780a2d4eb 100644 --- a/drivers/leds/leds-lp55xx-common.h +++ b/drivers/leds/leds-lp55xx-common.h | |||
@@ -33,6 +33,8 @@ struct lp55xx_reg { | |||
33 | * @reset : Chip specific reset command | 33 | * @reset : Chip specific reset command |
34 | * @enable : Chip specific enable command | 34 | * @enable : Chip specific enable command |
35 | * @post_init_device : Chip specific initialization code | 35 | * @post_init_device : Chip specific initialization code |
36 | * @brightness_work_fn : Brightness work function | ||
37 | * @set_led_current : LED current set function | ||
36 | */ | 38 | */ |
37 | struct lp55xx_device_config { | 39 | struct lp55xx_device_config { |
38 | const struct lp55xx_reg reset; | 40 | const struct lp55xx_reg reset; |
@@ -40,6 +42,12 @@ struct lp55xx_device_config { | |||
40 | 42 | ||
41 | /* define if the device has specific initialization process */ | 43 | /* define if the device has specific initialization process */ |
42 | int (*post_init_device) (struct lp55xx_chip *chip); | 44 | int (*post_init_device) (struct lp55xx_chip *chip); |
45 | |||
46 | /* access brightness register */ | ||
47 | void (*brightness_work_fn)(struct work_struct *work); | ||
48 | |||
49 | /* current setting function */ | ||
50 | void (*set_led_current) (struct lp55xx_led *led, u8 led_current); | ||
43 | }; | 51 | }; |
44 | 52 | ||
45 | /* | 53 | /* |
@@ -88,4 +96,7 @@ extern int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg, | |||
88 | extern int lp55xx_init_device(struct lp55xx_chip *chip); | 96 | extern int lp55xx_init_device(struct lp55xx_chip *chip); |
89 | extern void lp55xx_deinit_device(struct lp55xx_chip *chip); | 97 | extern void lp55xx_deinit_device(struct lp55xx_chip *chip); |
90 | 98 | ||
99 | /* common LED class device functions */ | ||
100 | extern int lp55xx_register_leds(struct lp55xx_led *led, | ||
101 | struct lp55xx_chip *chip); | ||
91 | #endif /* _LEDS_LP55XX_COMMON_H */ | 102 | #endif /* _LEDS_LP55XX_COMMON_H */ |