diff options
author | Daniel Mack <daniel@zonque.org> | 2018-06-27 14:52:36 -0400 |
---|---|---|
committer | Jacek Anaszewski <jacek.anaszewski@gmail.com> | 2018-07-03 16:12:40 -0400 |
commit | 8cd7d6daba9330383259686d1cc1d64caf857b11 (patch) | |
tree | 63adbbf498c2b9c584be479feb026c449afdb9f6 /drivers/leds | |
parent | 73f103c9528135bc896459a58e2371ce86090aea (diff) |
leds: lt3593: Add device tree probing glue
The binding details are described in an earlier commit that adds the
documentation.
Signed-off-by: Daniel Mack <daniel@zonque.org>
Signed-off-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
Diffstat (limited to 'drivers/leds')
-rw-r--r-- | drivers/leds/leds-lt3593.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c index a096ee64cbbb..2e35a4a4c571 100644 --- a/drivers/leds/leds-lt3593.c +++ b/drivers/leds/leds-lt3593.c | |||
@@ -24,8 +24,11 @@ | |||
24 | #include <linux/gpio/consumer.h> | 24 | #include <linux/gpio/consumer.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/of.h> | ||
28 | #include <uapi/linux/uleds.h> | ||
27 | 29 | ||
28 | struct lt3593_led_data { | 30 | struct lt3593_led_data { |
31 | char name[LED_MAX_NAME_SIZE]; | ||
29 | struct led_classdev cdev; | 32 | struct led_classdev cdev; |
30 | struct gpio_desc *gpiod; | 33 | struct gpio_desc *gpiod; |
31 | }; | 34 | }; |
@@ -120,22 +123,89 @@ static int lt3593_led_probe(struct platform_device *pdev) | |||
120 | { | 123 | { |
121 | struct device *dev = &pdev->dev; | 124 | struct device *dev = &pdev->dev; |
122 | struct lt3593_led_data *led_data; | 125 | struct lt3593_led_data *led_data; |
126 | struct fwnode_handle *child; | ||
127 | int ret, state = LEDS_GPIO_DEFSTATE_OFF; | ||
128 | enum gpiod_flags flags = GPIOD_OUT_LOW; | ||
129 | const char *tmp; | ||
123 | 130 | ||
124 | if (dev_get_platdata(dev)) { | 131 | if (dev_get_platdata(dev)) { |
125 | led_data = lt3593_led_probe_pdata(dev); | 132 | led_data = lt3593_led_probe_pdata(dev); |
126 | if (IS_ERR(led_data)) | 133 | if (IS_ERR(led_data)) |
127 | return PTR_ERR(led_data); | 134 | return PTR_ERR(led_data); |
135 | |||
136 | goto out; | ||
128 | } | 137 | } |
129 | 138 | ||
139 | if (!dev->of_node) | ||
140 | return -ENODEV; | ||
141 | |||
142 | led_data = devm_kzalloc(dev, sizeof(*led_data), GFP_KERNEL); | ||
143 | if (!led_data) | ||
144 | return -ENOMEM; | ||
145 | |||
146 | if (device_get_child_node_count(dev) != 1) { | ||
147 | dev_err(dev, "Device must have exactly one LED sub-node."); | ||
148 | return -EINVAL; | ||
149 | } | ||
150 | |||
151 | led_data->gpiod = devm_gpiod_get(dev, "lltc,ctrl", 0); | ||
152 | if (IS_ERR(led_data->gpiod)) | ||
153 | return PTR_ERR(led_data->gpiod); | ||
154 | |||
155 | child = device_get_next_child_node(dev, NULL); | ||
156 | |||
157 | ret = fwnode_property_read_string(child, "label", &tmp); | ||
158 | if (ret < 0) | ||
159 | snprintf(led_data->name, sizeof(led_data->name), | ||
160 | "lt3593::"); | ||
161 | else | ||
162 | snprintf(led_data->name, sizeof(led_data->name), | ||
163 | "lt3593:%s", tmp); | ||
164 | |||
165 | fwnode_property_read_string(child, "linux,default-trigger", | ||
166 | &led_data->cdev.default_trigger); | ||
167 | |||
168 | if (!fwnode_property_read_string(child, "default-state", &tmp)) { | ||
169 | if (!strcmp(tmp, "keep")) { | ||
170 | state = LEDS_GPIO_DEFSTATE_KEEP; | ||
171 | flags = GPIOD_ASIS; | ||
172 | } else if (!strcmp(tmp, "on")) { | ||
173 | state = LEDS_GPIO_DEFSTATE_ON; | ||
174 | flags = GPIOD_OUT_HIGH; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | led_data->cdev.name = led_data->name; | ||
179 | led_data->cdev.brightness_set_blocking = lt3593_led_set; | ||
180 | led_data->cdev.brightness = state ? LED_FULL : LED_OFF; | ||
181 | |||
182 | ret = devm_led_classdev_register(dev, &led_data->cdev); | ||
183 | if (ret < 0) { | ||
184 | fwnode_handle_put(child); | ||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | led_data->cdev.dev->of_node = dev->of_node; | ||
189 | |||
190 | out: | ||
130 | platform_set_drvdata(pdev, led_data); | 191 | platform_set_drvdata(pdev, led_data); |
131 | 192 | ||
132 | return 0; | 193 | return 0; |
133 | } | 194 | } |
134 | 195 | ||
196 | #ifdef CONFIG_OF | ||
197 | static const struct of_device_id of_lt3593_leds_match[] = { | ||
198 | { .compatible = "lltc,lt3593", }, | ||
199 | {}, | ||
200 | }; | ||
201 | MODULE_DEVICE_TABLE(of, of_lt3593_leds_match); | ||
202 | #endif | ||
203 | |||
135 | static struct platform_driver lt3593_led_driver = { | 204 | static struct platform_driver lt3593_led_driver = { |
136 | .probe = lt3593_led_probe, | 205 | .probe = lt3593_led_probe, |
137 | .driver = { | 206 | .driver = { |
138 | .name = "leds-lt3593", | 207 | .name = "leds-lt3593", |
208 | .of_match_table = of_match_ptr(of_lt3593_leds_match), | ||
139 | }, | 209 | }, |
140 | }; | 210 | }; |
141 | 211 | ||