diff options
-rw-r--r-- | Documentation/devicetree/bindings/leds/leds-pca9532.txt | 10 | ||||
-rw-r--r-- | drivers/leds/leds-pca9532.c | 27 | ||||
-rw-r--r-- | include/linux/leds-pca9532.h | 4 |
3 files changed, 38 insertions, 3 deletions
diff --git a/Documentation/devicetree/bindings/leds/leds-pca9532.txt b/Documentation/devicetree/bindings/leds/leds-pca9532.txt index 198f3ba0e01f..f769c52e3643 100644 --- a/Documentation/devicetree/bindings/leds/leds-pca9532.txt +++ b/Documentation/devicetree/bindings/leds/leds-pca9532.txt | |||
@@ -17,6 +17,8 @@ Optional sub-node properties: | |||
17 | - label: see Documentation/devicetree/bindings/leds/common.txt | 17 | - label: see Documentation/devicetree/bindings/leds/common.txt |
18 | - type: Output configuration, see dt-bindings/leds/leds-pca9532.h (default NONE) | 18 | - type: Output configuration, see dt-bindings/leds/leds-pca9532.h (default NONE) |
19 | - linux,default-trigger: see Documentation/devicetree/bindings/leds/common.txt | 19 | - linux,default-trigger: see Documentation/devicetree/bindings/leds/common.txt |
20 | - default-state: see Documentation/devicetree/bindings/leds/common.txt | ||
21 | This property is only valid for sub-nodes of type <PCA9532_TYPE_LED>. | ||
20 | 22 | ||
21 | Example: | 23 | Example: |
22 | #include <dt-bindings/leds/leds-pca9532.h> | 24 | #include <dt-bindings/leds/leds-pca9532.h> |
@@ -33,6 +35,14 @@ Example: | |||
33 | label = "pca:green:power"; | 35 | label = "pca:green:power"; |
34 | type = <PCA9532_TYPE_LED>; | 36 | type = <PCA9532_TYPE_LED>; |
35 | }; | 37 | }; |
38 | kernel-booting { | ||
39 | type = <PCA9532_TYPE_LED>; | ||
40 | default-state = "on"; | ||
41 | }; | ||
42 | sys-stat { | ||
43 | type = <PCA9532_TYPE_LED>; | ||
44 | default-state = "keep"; // don't touch, was set by U-Boot | ||
45 | }; | ||
36 | }; | 46 | }; |
37 | 47 | ||
38 | For more product information please see the link below: | 48 | For more product information please see the link below: |
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c index 06e63106ae1e..7fea18b0c15d 100644 --- a/drivers/leds/leds-pca9532.c +++ b/drivers/leds/leds-pca9532.c | |||
@@ -254,6 +254,21 @@ static void pca9532_input_work(struct work_struct *work) | |||
254 | mutex_unlock(&data->update_lock); | 254 | mutex_unlock(&data->update_lock); |
255 | } | 255 | } |
256 | 256 | ||
257 | static enum pca9532_state pca9532_getled(struct pca9532_led *led) | ||
258 | { | ||
259 | struct i2c_client *client = led->client; | ||
260 | struct pca9532_data *data = i2c_get_clientdata(client); | ||
261 | u8 maxleds = data->chip_info->num_leds; | ||
262 | char reg; | ||
263 | enum pca9532_state ret; | ||
264 | |||
265 | mutex_lock(&data->update_lock); | ||
266 | reg = i2c_smbus_read_byte_data(client, LED_REG(maxleds, led->id)); | ||
267 | ret = reg >> LED_NUM(led->id)/2; | ||
268 | mutex_unlock(&data->update_lock); | ||
269 | return ret; | ||
270 | } | ||
271 | |||
257 | #ifdef CONFIG_LEDS_PCA9532_GPIO | 272 | #ifdef CONFIG_LEDS_PCA9532_GPIO |
258 | static int pca9532_gpio_request_pin(struct gpio_chip *gc, unsigned offset) | 273 | static int pca9532_gpio_request_pin(struct gpio_chip *gc, unsigned offset) |
259 | { | 274 | { |
@@ -366,7 +381,10 @@ static int pca9532_configure(struct i2c_client *client, | |||
366 | gpios++; | 381 | gpios++; |
367 | break; | 382 | break; |
368 | case PCA9532_TYPE_LED: | 383 | case PCA9532_TYPE_LED: |
369 | led->state = pled->state; | 384 | if (pled->state == PCA9532_KEEP) |
385 | led->state = pca9532_getled(led); | ||
386 | else | ||
387 | led->state = pled->state; | ||
370 | led->name = pled->name; | 388 | led->name = pled->name; |
371 | led->ldev.name = led->name; | 389 | led->ldev.name = led->name; |
372 | led->ldev.default_trigger = pled->default_trigger; | 390 | led->ldev.default_trigger = pled->default_trigger; |
@@ -456,6 +474,7 @@ pca9532_of_populate_pdata(struct device *dev, struct device_node *np) | |||
456 | const struct of_device_id *match; | 474 | const struct of_device_id *match; |
457 | int devid, maxleds; | 475 | int devid, maxleds; |
458 | int i = 0; | 476 | int i = 0; |
477 | const char *state; | ||
459 | 478 | ||
460 | match = of_match_device(of_pca9532_leds_match, dev); | 479 | match = of_match_device(of_pca9532_leds_match, dev); |
461 | if (!match) | 480 | if (!match) |
@@ -475,6 +494,12 @@ pca9532_of_populate_pdata(struct device *dev, struct device_node *np) | |||
475 | of_property_read_u32(child, "type", &pdata->leds[i].type); | 494 | of_property_read_u32(child, "type", &pdata->leds[i].type); |
476 | of_property_read_string(child, "linux,default-trigger", | 495 | of_property_read_string(child, "linux,default-trigger", |
477 | &pdata->leds[i].default_trigger); | 496 | &pdata->leds[i].default_trigger); |
497 | if (!of_property_read_string(child, "default-state", &state)) { | ||
498 | if (!strcmp(state, "on")) | ||
499 | pdata->leds[i].state = PCA9532_ON; | ||
500 | else if (!strcmp(state, "keep")) | ||
501 | pdata->leds[i].state = PCA9532_KEEP; | ||
502 | } | ||
478 | if (++i >= maxleds) { | 503 | if (++i >= maxleds) { |
479 | of_node_put(child); | 504 | of_node_put(child); |
480 | break; | 505 | break; |
diff --git a/include/linux/leds-pca9532.h b/include/linux/leds-pca9532.h index d215b4561180..5e240b2b4d58 100644 --- a/include/linux/leds-pca9532.h +++ b/include/linux/leds-pca9532.h | |||
@@ -22,7 +22,8 @@ enum pca9532_state { | |||
22 | PCA9532_OFF = 0x0, | 22 | PCA9532_OFF = 0x0, |
23 | PCA9532_ON = 0x1, | 23 | PCA9532_ON = 0x1, |
24 | PCA9532_PWM0 = 0x2, | 24 | PCA9532_PWM0 = 0x2, |
25 | PCA9532_PWM1 = 0x3 | 25 | PCA9532_PWM1 = 0x3, |
26 | PCA9532_KEEP = 0xff, | ||
26 | }; | 27 | }; |
27 | 28 | ||
28 | struct pca9532_led { | 29 | struct pca9532_led { |
@@ -44,4 +45,3 @@ struct pca9532_platform_data { | |||
44 | }; | 45 | }; |
45 | 46 | ||
46 | #endif /* __LINUX_PCA9532_H */ | 47 | #endif /* __LINUX_PCA9532_H */ |
47 | |||