Merge tag 'nfsd-5.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
[linux-block.git] / drivers / staging / greybus / light.c
CommitLineData
eb50fd3a 1// SPDX-License-Identifier: GPL-2.0
2870b52b
RMS
2/*
3 * Greybus Lights protocol driver.
4 *
5 * Copyright 2015 Google Inc.
6 * Copyright 2015 Linaro Ltd.
2870b52b
RMS
7 */
8
9#include <linux/kernel.h>
10#include <linux/leds.h>
a7af2fe6 11#include <linux/led-class-flash.h>
2870b52b
RMS
12#include <linux/module.h>
13#include <linux/slab.h>
ec0ad868 14#include <linux/greybus.h>
a7af2fe6 15#include <media/v4l2-flash-led-class.h>
2870b52b 16
2870b52b
RMS
17#define NAMES_MAX 32
18
19struct gb_channel {
20 u8 id;
21 u32 flags;
22 u32 color;
23 char *color_name;
24 u8 fade_in;
25 u8 fade_out;
26 u32 mode;
27 char *mode_name;
28 struct attribute **attrs;
29 struct attribute_group *attr_group;
30 const struct attribute_group **attr_groups;
2870b52b 31 struct led_classdev *led;
a7af2fe6 32#if IS_REACHABLE(CONFIG_LEDS_CLASS_FLASH)
2870b52b
RMS
33 struct led_classdev_flash fled;
34 struct led_flash_setting intensity_uA;
35 struct led_flash_setting timeout_us;
36#else
37 struct led_classdev cled;
38#endif
39 struct gb_light *light;
40 bool is_registered;
41 bool releasing;
42 bool strobe_state;
cc43368a
KH
43 bool active;
44 struct mutex lock;
2870b52b
RMS
45};
46
47struct gb_light {
48 u8 id;
49 char *name;
50 struct gb_lights *glights;
51 u32 flags;
52 u8 channels_count;
53 struct gb_channel *channels;
54 bool has_flash;
c6ad27a9 55 bool ready;
a7af2fe6 56#if IS_REACHABLE(CONFIG_V4L2_FLASH_LED_CLASS)
2870b52b 57 struct v4l2_flash *v4l2_flash;
503dd28a 58 struct v4l2_flash *v4l2_flash_ind;
2870b52b
RMS
59#endif
60};
61
62struct gb_lights {
63 struct gb_connection *connection;
64 u8 lights_count;
65 struct gb_light *lights;
66 struct mutex lights_lock;
67};
68
69static void gb_lights_channel_free(struct gb_channel *channel);
70
71static struct gb_connection *get_conn_from_channel(struct gb_channel *channel)
72{
73 return channel->light->glights->connection;
74}
75
76static struct gb_connection *get_conn_from_light(struct gb_light *light)
77{
78 return light->glights->connection;
79}
80
81static bool is_channel_flash(struct gb_channel *channel)
82{
83 return !!(channel->mode & (GB_CHANNEL_MODE_FLASH | GB_CHANNEL_MODE_TORCH
84 | GB_CHANNEL_MODE_INDICATOR));
85}
86
a7af2fe6 87#if IS_REACHABLE(CONFIG_LEDS_CLASS_FLASH)
2870b52b
RMS
88static struct gb_channel *get_channel_from_cdev(struct led_classdev *cdev)
89{
90 struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(cdev);
91
92 return container_of(fled_cdev, struct gb_channel, fled);
93}
94
95static struct led_classdev *get_channel_cdev(struct gb_channel *channel)
96{
97 return &channel->fled.led_cdev;
98}
99
100static struct gb_channel *get_channel_from_mode(struct gb_light *light,
101 u32 mode)
102{
103 struct gb_channel *channel = NULL;
104 int i;
105
106 for (i = 0; i < light->channels_count; i++) {
107 channel = &light->channels[i];
108 if (channel && channel->mode == mode)
109 break;
110 }
111 return channel;
112}
113
114static int __gb_lights_flash_intensity_set(struct gb_channel *channel,
115 u32 intensity)
116{
117 struct gb_connection *connection = get_conn_from_channel(channel);
9141ad87 118 struct gb_bundle *bundle = connection->bundle;
2870b52b 119 struct gb_lights_set_flash_intensity_request req;
9141ad87 120 int ret;
2870b52b
RMS
121
122 if (channel->releasing)
123 return -ESHUTDOWN;
124
9141ad87
KH
125 ret = gb_pm_runtime_get_sync(bundle);
126 if (ret < 0)
127 return ret;
128
2870b52b
RMS
129 req.light_id = channel->light->id;
130 req.channel_id = channel->id;
131 req.intensity_uA = cpu_to_le32(intensity);
132
9141ad87
KH
133 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FLASH_INTENSITY,
134 &req, sizeof(req), NULL, 0);
135
136 gb_pm_runtime_put_autosuspend(bundle);
137
138 return ret;
2870b52b
RMS
139}
140
141static int __gb_lights_flash_brightness_set(struct gb_channel *channel)
142{
143 u32 intensity;
144
145 /* If the channel is flash we need to get the attached torch channel */
146 if (channel->mode & GB_CHANNEL_MODE_FLASH)
147 channel = get_channel_from_mode(channel->light,
148 GB_CHANNEL_MODE_TORCH);
149
150 /* For not flash we need to convert brightness to intensity */
151 intensity = channel->intensity_uA.min +
152 (channel->intensity_uA.step * channel->led->brightness);
153
154 return __gb_lights_flash_intensity_set(channel, intensity);
155}
a7af2fe6 156#else
2870b52b
RMS
157static struct gb_channel *get_channel_from_cdev(struct led_classdev *cdev)
158{
159 return container_of(cdev, struct gb_channel, cled);
160}
161
162static struct led_classdev *get_channel_cdev(struct gb_channel *channel)
163{
164 return &channel->cled;
165}
166
167static int __gb_lights_flash_brightness_set(struct gb_channel *channel)
168{
169 return 0;
170}
a7af2fe6 171#endif
2870b52b 172
2870b52b
RMS
173static int gb_lights_color_set(struct gb_channel *channel, u32 color);
174static int gb_lights_fade_set(struct gb_channel *channel);
175
2870b52b
RMS
176static void led_lock(struct led_classdev *cdev)
177{
178 mutex_lock(&cdev->led_access);
179}
180
181static void led_unlock(struct led_classdev *cdev)
182{
183 mutex_unlock(&cdev->led_access);
184}
2870b52b
RMS
185
186#define gb_lights_fade_attr(__dir) \
187static ssize_t fade_##__dir##_show(struct device *dev, \
188 struct device_attribute *attr, \
189 char *buf) \
190{ \
191 struct led_classdev *cdev = dev_get_drvdata(dev); \
192 struct gb_channel *channel = get_channel_from_cdev(cdev); \
193 \
194 return sprintf(buf, "%u\n", channel->fade_##__dir); \
195} \
196 \
197static ssize_t fade_##__dir##_store(struct device *dev, \
198 struct device_attribute *attr, \
199 const char *buf, size_t size) \
200{ \
201 struct led_classdev *cdev = dev_get_drvdata(dev); \
202 struct gb_channel *channel = get_channel_from_cdev(cdev); \
203 u8 fade; \
204 int ret; \
205 \
206 led_lock(cdev); \
207 if (led_sysfs_is_disabled(cdev)) { \
208 ret = -EBUSY; \
209 goto unlock; \
210 } \
211 \
212 ret = kstrtou8(buf, 0, &fade); \
213 if (ret < 0) { \
214 dev_err(dev, "could not parse fade value %d\n", ret); \
215 goto unlock; \
216 } \
217 if (channel->fade_##__dir == fade) \
218 goto unlock; \
219 channel->fade_##__dir = fade; \
220 \
221 ret = gb_lights_fade_set(channel); \
222 if (ret < 0) \
223 goto unlock; \
224 \
225 ret = size; \
226unlock: \
227 led_unlock(cdev); \
228 return ret; \
229} \
230static DEVICE_ATTR_RW(fade_##__dir)
231
232gb_lights_fade_attr(in);
233gb_lights_fade_attr(out);
234
235static ssize_t color_show(struct device *dev, struct device_attribute *attr,
236 char *buf)
237{
238 struct led_classdev *cdev = dev_get_drvdata(dev);
239 struct gb_channel *channel = get_channel_from_cdev(cdev);
240
241 return sprintf(buf, "0x%08x\n", channel->color);
242}
243
244static ssize_t color_store(struct device *dev, struct device_attribute *attr,
245 const char *buf, size_t size)
246{
247 struct led_classdev *cdev = dev_get_drvdata(dev);
248 struct gb_channel *channel = get_channel_from_cdev(cdev);
249 u32 color;
250 int ret;
251
252 led_lock(cdev);
253 if (led_sysfs_is_disabled(cdev)) {
254 ret = -EBUSY;
255 goto unlock;
256 }
257 ret = kstrtou32(buf, 0, &color);
258 if (ret < 0) {
259 dev_err(dev, "could not parse color value %d\n", ret);
260 goto unlock;
261 }
262
263 ret = gb_lights_color_set(channel, color);
264 if (ret < 0)
265 goto unlock;
266
267 channel->color = color;
268 ret = size;
269unlock:
270 led_unlock(cdev);
271 return ret;
272}
273static DEVICE_ATTR_RW(color);
274
275static int channel_attr_groups_set(struct gb_channel *channel,
276 struct led_classdev *cdev)
277{
278 int attr = 0;
279 int size = 0;
280
281 if (channel->flags & GB_LIGHT_CHANNEL_MULTICOLOR)
282 size++;
283 if (channel->flags & GB_LIGHT_CHANNEL_FADER)
0e352343 284 size += 2;
2870b52b
RMS
285
286 if (!size)
287 return 0;
288
289 /* Set attributes based in the channel flags */
3855eeec 290 channel->attrs = kcalloc(size + 1, sizeof(*channel->attrs), GFP_KERNEL);
2870b52b
RMS
291 if (!channel->attrs)
292 return -ENOMEM;
6500966d 293 channel->attr_group = kzalloc(sizeof(*channel->attr_group), GFP_KERNEL);
2870b52b
RMS
294 if (!channel->attr_group)
295 return -ENOMEM;
296 channel->attr_groups = kcalloc(2, sizeof(*channel->attr_groups),
297 GFP_KERNEL);
298 if (!channel->attr_groups)
299 return -ENOMEM;
300
301 if (channel->flags & GB_LIGHT_CHANNEL_MULTICOLOR)
302 channel->attrs[attr++] = &dev_attr_color.attr;
303 if (channel->flags & GB_LIGHT_CHANNEL_FADER) {
304 channel->attrs[attr++] = &dev_attr_fade_in.attr;
305 channel->attrs[attr++] = &dev_attr_fade_out.attr;
306 }
307
308 channel->attr_group->attrs = channel->attrs;
309
310 channel->attr_groups[0] = channel->attr_group;
311
312 cdev->groups = channel->attr_groups;
313
314 return 0;
315}
316
317static int gb_lights_fade_set(struct gb_channel *channel)
318{
319 struct gb_connection *connection = get_conn_from_channel(channel);
9141ad87 320 struct gb_bundle *bundle = connection->bundle;
2870b52b 321 struct gb_lights_set_fade_request req;
9141ad87 322 int ret;
2870b52b
RMS
323
324 if (channel->releasing)
325 return -ESHUTDOWN;
326
9141ad87
KH
327 ret = gb_pm_runtime_get_sync(bundle);
328 if (ret < 0)
329 return ret;
330
2870b52b
RMS
331 req.light_id = channel->light->id;
332 req.channel_id = channel->id;
333 req.fade_in = channel->fade_in;
334 req.fade_out = channel->fade_out;
9141ad87
KH
335 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FADE,
336 &req, sizeof(req), NULL, 0);
337
338 gb_pm_runtime_put_autosuspend(bundle);
339
340 return ret;
2870b52b
RMS
341}
342
343static int gb_lights_color_set(struct gb_channel *channel, u32 color)
344{
345 struct gb_connection *connection = get_conn_from_channel(channel);
9141ad87 346 struct gb_bundle *bundle = connection->bundle;
2870b52b 347 struct gb_lights_set_color_request req;
9141ad87 348 int ret;
2870b52b
RMS
349
350 if (channel->releasing)
351 return -ESHUTDOWN;
352
9141ad87
KH
353 ret = gb_pm_runtime_get_sync(bundle);
354 if (ret < 0)
355 return ret;
356
2870b52b
RMS
357 req.light_id = channel->light->id;
358 req.channel_id = channel->id;
359 req.color = cpu_to_le32(color);
9141ad87
KH
360 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_COLOR,
361 &req, sizeof(req), NULL, 0);
362
363 gb_pm_runtime_put_autosuspend(bundle);
364
365 return ret;
2870b52b 366}
2870b52b
RMS
367
368static int __gb_lights_led_brightness_set(struct gb_channel *channel)
369{
370 struct gb_lights_set_brightness_request req;
371 struct gb_connection *connection = get_conn_from_channel(channel);
9141ad87 372 struct gb_bundle *bundle = connection->bundle;
cc43368a 373 bool old_active;
9141ad87
KH
374 int ret;
375
cc43368a 376 mutex_lock(&channel->lock);
9141ad87
KH
377 ret = gb_pm_runtime_get_sync(bundle);
378 if (ret < 0)
cc43368a
KH
379 goto out_unlock;
380
381 old_active = channel->active;
2870b52b
RMS
382
383 req.light_id = channel->light->id;
384 req.channel_id = channel->id;
385 req.brightness = (u8)channel->led->brightness;
386
9141ad87
KH
387 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_BRIGHTNESS,
388 &req, sizeof(req), NULL, 0);
cc43368a
KH
389 if (ret < 0)
390 goto out_pm_put;
391
392 if (channel->led->brightness)
393 channel->active = true;
394 else
395 channel->active = false;
9141ad87 396
cc43368a
KH
397 /* we need to keep module alive when turning to active state */
398 if (!old_active && channel->active)
399 goto out_unlock;
400
401 /*
402 * on the other hand if going to inactive we still hold a reference and
403 * need to put it, so we could go to suspend.
404 */
405 if (old_active && !channel->active)
406 gb_pm_runtime_put_autosuspend(bundle);
407
408out_pm_put:
9141ad87 409 gb_pm_runtime_put_autosuspend(bundle);
cc43368a
KH
410out_unlock:
411 mutex_unlock(&channel->lock);
9141ad87
KH
412
413 return ret;
2870b52b
RMS
414}
415
416static int __gb_lights_brightness_set(struct gb_channel *channel)
417{
418 int ret;
419
420 if (channel->releasing)
421 return 0;
422
423 if (is_channel_flash(channel))
424 ret = __gb_lights_flash_brightness_set(channel);
425 else
426 ret = __gb_lights_led_brightness_set(channel);
427
428 return ret;
429}
430
9c06c6a2
RMS
431static int gb_brightness_set(struct led_classdev *cdev,
432 enum led_brightness value)
433{
434 struct gb_channel *channel = get_channel_from_cdev(cdev);
435
436 channel->led->brightness = value;
437
438 return __gb_lights_brightness_set(channel);
439}
2870b52b
RMS
440
441static enum led_brightness gb_brightness_get(struct led_classdev *cdev)
442
443{
444 struct gb_channel *channel = get_channel_from_cdev(cdev);
445
446 return channel->led->brightness;
447}
448
449static int gb_blink_set(struct led_classdev *cdev, unsigned long *delay_on,
450 unsigned long *delay_off)
451{
452 struct gb_channel *channel = get_channel_from_cdev(cdev);
453 struct gb_connection *connection = get_conn_from_channel(channel);
9141ad87 454 struct gb_bundle *bundle = connection->bundle;
2870b52b 455 struct gb_lights_blink_request req;
cc43368a 456 bool old_active;
9141ad87 457 int ret;
2870b52b
RMS
458
459 if (channel->releasing)
460 return -ESHUTDOWN;
461
dc875c77
RMS
462 if (!delay_on || !delay_off)
463 return -EINVAL;
464
cc43368a 465 mutex_lock(&channel->lock);
9141ad87
KH
466 ret = gb_pm_runtime_get_sync(bundle);
467 if (ret < 0)
cc43368a
KH
468 goto out_unlock;
469
470 old_active = channel->active;
9141ad87 471
2870b52b
RMS
472 req.light_id = channel->light->id;
473 req.channel_id = channel->id;
474 req.time_on_ms = cpu_to_le16(*delay_on);
475 req.time_off_ms = cpu_to_le16(*delay_off);
476
9141ad87
KH
477 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_BLINK, &req,
478 sizeof(req), NULL, 0);
cc43368a
KH
479 if (ret < 0)
480 goto out_pm_put;
481
5cf62679 482 if (*delay_on)
cc43368a
KH
483 channel->active = true;
484 else
485 channel->active = false;
486
487 /* we need to keep module alive when turning to active state */
488 if (!old_active && channel->active)
489 goto out_unlock;
9141ad87 490
cc43368a
KH
491 /*
492 * on the other hand if going to inactive we still hold a reference and
493 * need to put it, so we could go to suspend.
494 */
495 if (old_active && !channel->active)
496 gb_pm_runtime_put_autosuspend(bundle);
497
498out_pm_put:
9141ad87 499 gb_pm_runtime_put_autosuspend(bundle);
cc43368a
KH
500out_unlock:
501 mutex_unlock(&channel->lock);
9141ad87
KH
502
503 return ret;
2870b52b
RMS
504}
505
506static void gb_lights_led_operations_set(struct gb_channel *channel,
507 struct led_classdev *cdev)
508{
2870b52b 509 cdev->brightness_get = gb_brightness_get;
9c06c6a2 510 cdev->brightness_set_blocking = gb_brightness_set;
2870b52b
RMS
511
512 if (channel->flags & GB_LIGHT_CHANNEL_BLINK)
513 cdev->blink_set = gb_blink_set;
514}
515
a7af2fe6 516#if IS_REACHABLE(CONFIG_V4L2_FLASH_LED_CLASS)
2870b52b 517/* V4L2 specific helpers */
3f85c787
RMS
518static const struct v4l2_flash_ops v4l2_flash_ops;
519
2870b52b
RMS
520static void __gb_lights_channel_v4l2_config(struct led_flash_setting *channel_s,
521 struct led_flash_setting *v4l2_s)
522{
523 v4l2_s->min = channel_s->min;
524 v4l2_s->max = channel_s->max;
525 v4l2_s->step = channel_s->step;
526 /* For v4l2 val is the default value */
527 v4l2_s->val = channel_s->max;
528}
529
530static int gb_lights_light_v4l2_register(struct gb_light *light)
531{
532 struct gb_connection *connection = get_conn_from_light(light);
5fd18b37 533 struct device *dev = &connection->bundle->dev;
503dd28a 534 struct v4l2_flash_config sd_cfg = { {0} }, sd_cfg_ind = { {0} };
2870b52b 535 struct led_classdev_flash *fled;
85f7ff97 536 struct led_classdev *iled = NULL;
2870b52b 537 struct gb_channel *channel_torch, *channel_ind, *channel_flash;
2870b52b
RMS
538
539 channel_torch = get_channel_from_mode(light, GB_CHANNEL_MODE_TORCH);
540 if (channel_torch)
541 __gb_lights_channel_v4l2_config(&channel_torch->intensity_uA,
503dd28a 542 &sd_cfg.intensity);
2870b52b
RMS
543
544 channel_ind = get_channel_from_mode(light, GB_CHANNEL_MODE_INDICATOR);
545 if (channel_ind) {
546 __gb_lights_channel_v4l2_config(&channel_ind->intensity_uA,
503dd28a 547 &sd_cfg_ind.intensity);
85f7ff97 548 iled = &channel_ind->fled.led_cdev;
2870b52b
RMS
549 }
550
551 channel_flash = get_channel_from_mode(light, GB_CHANNEL_MODE_FLASH);
552 WARN_ON(!channel_flash);
553
554 fled = &channel_flash->fled;
555
428359cb 556 snprintf(sd_cfg.dev_name, sizeof(sd_cfg.dev_name), "%s", light->name);
503dd28a
SA
557 snprintf(sd_cfg_ind.dev_name, sizeof(sd_cfg_ind.dev_name),
558 "%s indicator", light->name);
2870b52b
RMS
559
560 /* Set the possible values to faults, in our case all faults */
428359cb 561 sd_cfg.flash_faults = LED_FAULT_OVER_VOLTAGE | LED_FAULT_TIMEOUT |
2870b52b
RMS
562 LED_FAULT_OVER_TEMPERATURE | LED_FAULT_SHORT_CIRCUIT |
563 LED_FAULT_OVER_CURRENT | LED_FAULT_INDICATOR |
564 LED_FAULT_UNDER_VOLTAGE | LED_FAULT_INPUT_VOLTAGE |
565 LED_FAULT_LED_OVER_TEMPERATURE;
566
503dd28a
SA
567 light->v4l2_flash = v4l2_flash_init(dev, NULL, fled, &v4l2_flash_ops,
568 &sd_cfg);
428359cb
RMS
569 if (IS_ERR(light->v4l2_flash))
570 return PTR_ERR(light->v4l2_flash);
2870b52b 571
503dd28a
SA
572 if (channel_ind) {
573 light->v4l2_flash_ind =
574 v4l2_flash_indicator_init(dev, NULL, iled, &sd_cfg_ind);
575 if (IS_ERR(light->v4l2_flash_ind)) {
576 v4l2_flash_release(light->v4l2_flash);
577 return PTR_ERR(light->v4l2_flash_ind);
578 }
579 }
580
428359cb 581 return 0;
2870b52b
RMS
582}
583
584static void gb_lights_light_v4l2_unregister(struct gb_light *light)
585{
503dd28a 586 v4l2_flash_release(light->v4l2_flash_ind);
2870b52b
RMS
587 v4l2_flash_release(light->v4l2_flash);
588}
589#else
590static int gb_lights_light_v4l2_register(struct gb_light *light)
591{
592 struct gb_connection *connection = get_conn_from_light(light);
593
5fd18b37 594 dev_err(&connection->bundle->dev, "no support for v4l2 subdevices\n");
2870b52b
RMS
595 return 0;
596}
597
598static void gb_lights_light_v4l2_unregister(struct gb_light *light)
599{
600}
601#endif
602
a7af2fe6 603#if IS_REACHABLE(CONFIG_LEDS_CLASS_FLASH)
2870b52b
RMS
604/* Flash specific operations */
605static int gb_lights_flash_intensity_set(struct led_classdev_flash *fcdev,
606 u32 brightness)
607{
608 struct gb_channel *channel = container_of(fcdev, struct gb_channel,
609 fled);
610 int ret;
611
612 ret = __gb_lights_flash_intensity_set(channel, brightness);
613 if (ret < 0)
614 return ret;
615
616 fcdev->brightness.val = brightness;
617
618 return 0;
619}
620
621static int gb_lights_flash_intensity_get(struct led_classdev_flash *fcdev,
622 u32 *brightness)
623{
624 *brightness = fcdev->brightness.val;
625
626 return 0;
627}
628
629static int gb_lights_flash_strobe_set(struct led_classdev_flash *fcdev,
630 bool state)
631{
632 struct gb_channel *channel = container_of(fcdev, struct gb_channel,
633 fled);
634 struct gb_connection *connection = get_conn_from_channel(channel);
9141ad87 635 struct gb_bundle *bundle = connection->bundle;
2870b52b
RMS
636 struct gb_lights_set_flash_strobe_request req;
637 int ret;
638
639 if (channel->releasing)
640 return -ESHUTDOWN;
641
9141ad87
KH
642 ret = gb_pm_runtime_get_sync(bundle);
643 if (ret < 0)
644 return ret;
645
2870b52b
RMS
646 req.light_id = channel->light->id;
647 req.channel_id = channel->id;
648 req.state = state ? 1 : 0;
649
650 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FLASH_STROBE,
651 &req, sizeof(req), NULL, 0);
9141ad87
KH
652 if (!ret)
653 channel->strobe_state = state;
2870b52b 654
9141ad87
KH
655 gb_pm_runtime_put_autosuspend(bundle);
656
657 return ret;
2870b52b
RMS
658}
659
660static int gb_lights_flash_strobe_get(struct led_classdev_flash *fcdev,
661 bool *state)
662{
663 struct gb_channel *channel = container_of(fcdev, struct gb_channel,
664 fled);
665
666 *state = channel->strobe_state;
667 return 0;
668}
669
670static int gb_lights_flash_timeout_set(struct led_classdev_flash *fcdev,
671 u32 timeout)
672{
673 struct gb_channel *channel = container_of(fcdev, struct gb_channel,
674 fled);
675 struct gb_connection *connection = get_conn_from_channel(channel);
9141ad87 676 struct gb_bundle *bundle = connection->bundle;
2870b52b
RMS
677 struct gb_lights_set_flash_timeout_request req;
678 int ret;
679
680 if (channel->releasing)
681 return -ESHUTDOWN;
682
9141ad87
KH
683 ret = gb_pm_runtime_get_sync(bundle);
684 if (ret < 0)
685 return ret;
686
2870b52b
RMS
687 req.light_id = channel->light->id;
688 req.channel_id = channel->id;
689 req.timeout_us = cpu_to_le32(timeout);
690
691 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FLASH_TIMEOUT,
692 &req, sizeof(req), NULL, 0);
9141ad87
KH
693 if (!ret)
694 fcdev->timeout.val = timeout;
2870b52b 695
9141ad87
KH
696 gb_pm_runtime_put_autosuspend(bundle);
697
698 return ret;
2870b52b
RMS
699}
700
701static int gb_lights_flash_fault_get(struct led_classdev_flash *fcdev,
702 u32 *fault)
703{
704 struct gb_channel *channel = container_of(fcdev, struct gb_channel,
705 fled);
706 struct gb_connection *connection = get_conn_from_channel(channel);
9141ad87 707 struct gb_bundle *bundle = connection->bundle;
2870b52b
RMS
708 struct gb_lights_get_flash_fault_request req;
709 struct gb_lights_get_flash_fault_response resp;
710 int ret;
711
712 if (channel->releasing)
713 return -ESHUTDOWN;
714
9141ad87
KH
715 ret = gb_pm_runtime_get_sync(bundle);
716 if (ret < 0)
717 return ret;
718
2870b52b
RMS
719 req.light_id = channel->light->id;
720 req.channel_id = channel->id;
721
722 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_GET_FLASH_FAULT,
723 &req, sizeof(req), &resp, sizeof(resp));
9141ad87
KH
724 if (!ret)
725 *fault = le32_to_cpu(resp.fault);
2870b52b 726
9141ad87 727 gb_pm_runtime_put_autosuspend(bundle);
2870b52b 728
9141ad87 729 return ret;
2870b52b
RMS
730}
731
732static const struct led_flash_ops gb_lights_flash_ops = {
733 .flash_brightness_set = gb_lights_flash_intensity_set,
734 .flash_brightness_get = gb_lights_flash_intensity_get,
735 .strobe_set = gb_lights_flash_strobe_set,
736 .strobe_get = gb_lights_flash_strobe_get,
737 .timeout_set = gb_lights_flash_timeout_set,
738 .fault_get = gb_lights_flash_fault_get,
739};
740
741static int __gb_lights_channel_torch_attach(struct gb_channel *channel,
742 struct gb_channel *channel_torch)
743{
744 char *name;
745
746 /* we can only attach torch to a flash channel */
747 if (!(channel->mode & GB_CHANNEL_MODE_FLASH))
748 return 0;
749
750 /* Move torch brightness to the destination */
751 channel->led->max_brightness = channel_torch->led->max_brightness;
752
753 /* append mode name to flash name */
754 name = kasprintf(GFP_KERNEL, "%s_%s", channel->led->name,
755 channel_torch->mode_name);
756 if (!name)
757 return -ENOMEM;
758 kfree(channel->led->name);
759 channel->led->name = name;
760
2870b52b
RMS
761 channel_torch->led = channel->led;
762
763 return 0;
764}
765
766static int __gb_lights_flash_led_register(struct gb_channel *channel)
767{
768 struct gb_connection *connection = get_conn_from_channel(channel);
769 struct led_classdev_flash *fled = &channel->fled;
770 struct led_flash_setting *fset;
771 struct gb_channel *channel_torch;
772 int ret;
773
774 fled->ops = &gb_lights_flash_ops;
775
776 fled->led_cdev.flags |= LED_DEV_CAP_FLASH;
777
778 fset = &fled->brightness;
779 fset->min = channel->intensity_uA.min;
780 fset->max = channel->intensity_uA.max;
781 fset->step = channel->intensity_uA.step;
1700507d 782 fset->val = channel->intensity_uA.max;
2870b52b
RMS
783
784 /* Only the flash mode have the timeout constraints settings */
785 if (channel->mode & GB_CHANNEL_MODE_FLASH) {
786 fset = &fled->timeout;
787 fset->min = channel->timeout_us.min;
788 fset->max = channel->timeout_us.max;
789 fset->step = channel->timeout_us.step;
1700507d 790 fset->val = channel->timeout_us.max;
2870b52b
RMS
791 }
792
793 /*
794 * If light have torch mode channel, this channel will be the led
795 * classdev of the registered above flash classdev
796 */
797 channel_torch = get_channel_from_mode(channel->light,
798 GB_CHANNEL_MODE_TORCH);
799 if (channel_torch) {
800 ret = __gb_lights_channel_torch_attach(channel, channel_torch);
801 if (ret < 0)
802 goto fail;
803 }
804
f865734d 805 ret = led_classdev_flash_register(&connection->bundle->dev, fled);
2870b52b
RMS
806 if (ret < 0)
807 goto fail;
808
809 channel->is_registered = true;
810 return 0;
811fail:
812 channel->led = NULL;
813 return ret;
814}
815
816static void __gb_lights_flash_led_unregister(struct gb_channel *channel)
817{
818 if (!channel->is_registered)
819 return;
820
821 led_classdev_flash_unregister(&channel->fled);
822}
823
824static int gb_lights_channel_flash_config(struct gb_channel *channel)
825{
826 struct gb_connection *connection = get_conn_from_channel(channel);
827 struct gb_lights_get_channel_flash_config_request req;
828 struct gb_lights_get_channel_flash_config_response conf;
829 struct led_flash_setting *fset;
830 int ret;
831
832 req.light_id = channel->light->id;
833 req.channel_id = channel->id;
834
835 ret = gb_operation_sync(connection,
836 GB_LIGHTS_TYPE_GET_CHANNEL_FLASH_CONFIG,
837 &req, sizeof(req), &conf, sizeof(conf));
838 if (ret < 0)
839 return ret;
840
841 /*
842 * Intensity constraints for flash related modes: flash, torch,
843 * indicator. They will be needed for v4l2 registration.
844 */
845 fset = &channel->intensity_uA;
846 fset->min = le32_to_cpu(conf.intensity_min_uA);
847 fset->max = le32_to_cpu(conf.intensity_max_uA);
848 fset->step = le32_to_cpu(conf.intensity_step_uA);
849
850 /*
851 * On flash type, max brightness is set as the number of intensity steps
852 * available.
853 */
854 channel->led->max_brightness = (fset->max - fset->min) / fset->step;
855
856 /* Only the flash mode have the timeout constraints settings */
857 if (channel->mode & GB_CHANNEL_MODE_FLASH) {
858 fset = &channel->timeout_us;
859 fset->min = le32_to_cpu(conf.timeout_min_us);
860 fset->max = le32_to_cpu(conf.timeout_max_us);
861 fset->step = le32_to_cpu(conf.timeout_step_us);
862 }
863
864 return 0;
865}
866#else
867static int gb_lights_channel_flash_config(struct gb_channel *channel)
868{
869 struct gb_connection *connection = get_conn_from_channel(channel);
870
5fd18b37 871 dev_err(&connection->bundle->dev, "no support for flash devices\n");
2870b52b
RMS
872 return 0;
873}
874
875static int __gb_lights_flash_led_register(struct gb_channel *channel)
876{
877 return 0;
878}
879
880static void __gb_lights_flash_led_unregister(struct gb_channel *channel)
881{
882}
883
a7af2fe6 884#endif
2870b52b
RMS
885
886static int __gb_lights_led_register(struct gb_channel *channel)
887{
888 struct gb_connection *connection = get_conn_from_channel(channel);
889 struct led_classdev *cdev = get_channel_cdev(channel);
890 int ret;
891
f865734d 892 ret = led_classdev_register(&connection->bundle->dev, cdev);
2870b52b
RMS
893 if (ret < 0)
894 channel->led = NULL;
895 else
896 channel->is_registered = true;
897 return ret;
898}
899
900static int gb_lights_channel_register(struct gb_channel *channel)
901{
902 /* Normal LED channel, just register in led classdev and we are done */
903 if (!is_channel_flash(channel))
904 return __gb_lights_led_register(channel);
905
906 /*
907 * Flash Type need more work, register flash classdev, indicator as
908 * flash classdev, torch will be led classdev of the flash classdev.
909 */
910 if (!(channel->mode & GB_CHANNEL_MODE_TORCH))
911 return __gb_lights_flash_led_register(channel);
912
913 return 0;
914}
915
916static void __gb_lights_led_unregister(struct gb_channel *channel)
917{
918 struct led_classdev *cdev = get_channel_cdev(channel);
919
920 if (!channel->is_registered)
921 return;
922
923 led_classdev_unregister(cdev);
04820da2
AY
924 kfree(cdev->name);
925 cdev->name = NULL;
2870b52b
RMS
926 channel->led = NULL;
927}
928
929static void gb_lights_channel_unregister(struct gb_channel *channel)
930{
931 /* The same as register, handle channels differently */
932 if (!is_channel_flash(channel)) {
933 __gb_lights_led_unregister(channel);
934 return;
935 }
936
937 if (channel->mode & GB_CHANNEL_MODE_TORCH)
938 __gb_lights_led_unregister(channel);
939 else
940 __gb_lights_flash_led_unregister(channel);
941}
942
943static int gb_lights_channel_config(struct gb_light *light,
944 struct gb_channel *channel)
945{
946 struct gb_lights_get_channel_config_response conf;
947 struct gb_lights_get_channel_config_request req;
948 struct gb_connection *connection = get_conn_from_light(light);
949 struct led_classdev *cdev = get_channel_cdev(channel);
950 char *name;
951 int ret;
952
953 req.light_id = light->id;
954 req.channel_id = channel->id;
955
956 ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_GET_CHANNEL_CONFIG,
957 &req, sizeof(req), &conf, sizeof(conf));
958 if (ret < 0)
959 return ret;
960
961 channel->light = light;
962 channel->mode = le32_to_cpu(conf.mode);
963 channel->flags = le32_to_cpu(conf.flags);
964 channel->color = le32_to_cpu(conf.color);
965 channel->color_name = kstrndup(conf.color_name, NAMES_MAX, GFP_KERNEL);
966 if (!channel->color_name)
967 return -ENOMEM;
968 channel->mode_name = kstrndup(conf.mode_name, NAMES_MAX, GFP_KERNEL);
969 if (!channel->mode_name)
970 return -ENOMEM;
971
972 channel->led = cdev;
973
974 name = kasprintf(GFP_KERNEL, "%s:%s:%s", light->name,
975 channel->color_name, channel->mode_name);
976 if (!name)
977 return -ENOMEM;
978
979 cdev->name = name;
980
981 cdev->max_brightness = conf.max_brightness;
982
983 ret = channel_attr_groups_set(channel, cdev);
984 if (ret < 0)
985 return ret;
986
987 gb_lights_led_operations_set(channel, cdev);
988
989 /*
990 * If it is not a flash related channel (flash, torch or indicator) we
991 * are done here. If not, continue and fetch flash related
992 * configurations.
993 */
994 if (!is_channel_flash(channel))
995 return ret;
996
997 light->has_flash = true;
998
1cd5929a 999 return gb_lights_channel_flash_config(channel);
2870b52b
RMS
1000}
1001
1002static int gb_lights_light_config(struct gb_lights *glights, u8 id)
1003{
1004 struct gb_light *light = &glights->lights[id];
1005 struct gb_lights_get_light_config_request req;
1006 struct gb_lights_get_light_config_response conf;
1007 int ret;
1008 int i;
1009
1010 light->glights = glights;
1011 light->id = id;
1012
1013 req.id = id;
1014
1015 ret = gb_operation_sync(glights->connection,
1016 GB_LIGHTS_TYPE_GET_LIGHT_CONFIG,
1017 &req, sizeof(req), &conf, sizeof(conf));
1018 if (ret < 0)
1019 return ret;
1020
1021 if (!conf.channel_count)
1022 return -EINVAL;
1023 if (!strlen(conf.name))
1024 return -EINVAL;
1025
1026 light->channels_count = conf.channel_count;
1027 light->name = kstrndup(conf.name, NAMES_MAX, GFP_KERNEL);
9bb086e5
CZ
1028 if (!light->name)
1029 return -ENOMEM;
3036d0e2 1030 light->channels = kcalloc(light->channels_count,
2870b52b
RMS
1031 sizeof(struct gb_channel), GFP_KERNEL);
1032 if (!light->channels)
1033 return -ENOMEM;
1034
1035 /* First we collect all the configurations for all channels */
1036 for (i = 0; i < light->channels_count; i++) {
1037 light->channels[i].id = i;
1038 ret = gb_lights_channel_config(light, &light->channels[i]);
1039 if (ret < 0)
1040 return ret;
1041 }
1042
6ce0eed7
VK
1043 return 0;
1044}
1045
1046static int gb_lights_light_register(struct gb_light *light)
1047{
1048 int ret;
1049 int i;
1050
2870b52b
RMS
1051 /*
1052 * Then, if everything went ok in getting configurations, we register
1053 * the classdev, flash classdev and v4l2 subsystem, if a flash device is
1054 * found.
1055 */
1056 for (i = 0; i < light->channels_count; i++) {
1057 ret = gb_lights_channel_register(&light->channels[i]);
1058 if (ret < 0)
1059 return ret;
cc43368a
KH
1060
1061 mutex_init(&light->channels[i].lock);
2870b52b
RMS
1062 }
1063
c6ad27a9
RMS
1064 light->ready = true;
1065
2870b52b
RMS
1066 if (light->has_flash) {
1067 ret = gb_lights_light_v4l2_register(light);
137f7179
RMS
1068 if (ret < 0) {
1069 light->has_flash = false;
2870b52b 1070 return ret;
137f7179 1071 }
2870b52b
RMS
1072 }
1073
1074 return 0;
1075}
1076
1077static void gb_lights_channel_free(struct gb_channel *channel)
1078{
2870b52b
RMS
1079 kfree(channel->attrs);
1080 kfree(channel->attr_group);
1081 kfree(channel->attr_groups);
1082 kfree(channel->color_name);
1083 kfree(channel->mode_name);
cc43368a 1084 mutex_destroy(&channel->lock);
2870b52b
RMS
1085}
1086
1087static void gb_lights_channel_release(struct gb_channel *channel)
1088{
2870b52b
RMS
1089 channel->releasing = true;
1090
1091 gb_lights_channel_unregister(channel);
1092
1093 gb_lights_channel_free(channel);
1094}
1095
1096static void gb_lights_light_release(struct gb_light *light)
1097{
1098 int i;
2870b52b 1099
c6ad27a9 1100 light->ready = false;
2870b52b 1101
2870b52b
RMS
1102 if (light->has_flash)
1103 gb_lights_light_v4l2_unregister(light);
32910124 1104 light->has_flash = false;
2870b52b 1105
32910124 1106 for (i = 0; i < light->channels_count; i++)
2870b52b 1107 gb_lights_channel_release(&light->channels[i]);
32910124
DC
1108 light->channels_count = 0;
1109
2870b52b 1110 kfree(light->channels);
32910124 1111 light->channels = NULL;
2870b52b 1112 kfree(light->name);
32910124 1113 light->name = NULL;
2870b52b
RMS
1114}
1115
1116static void gb_lights_release(struct gb_lights *glights)
1117{
1118 int i;
1119
1120 if (!glights)
1121 return;
1122
1123 mutex_lock(&glights->lights_lock);
1124 if (!glights->lights)
1125 goto free_glights;
1126
1127 for (i = 0; i < glights->lights_count; i++)
1128 gb_lights_light_release(&glights->lights[i]);
1129
1130 kfree(glights->lights);
1131
1132free_glights:
1133 mutex_unlock(&glights->lights_lock);
1134 mutex_destroy(&glights->lights_lock);
1135 kfree(glights);
1136}
1137
1138static int gb_lights_get_count(struct gb_lights *glights)
1139{
1140 struct gb_lights_get_lights_response resp;
1141 int ret;
1142
1143 ret = gb_operation_sync(glights->connection, GB_LIGHTS_TYPE_GET_LIGHTS,
1144 NULL, 0, &resp, sizeof(resp));
1145 if (ret < 0)
1146 return ret;
1147
1148 if (!resp.lights_count)
1149 return -EINVAL;
1150
1151 glights->lights_count = resp.lights_count;
1152
1153 return 0;
1154}
1155
6ce0eed7 1156static int gb_lights_create_all(struct gb_lights *glights)
2870b52b
RMS
1157{
1158 struct gb_connection *connection = glights->connection;
1159 int ret;
1160 int i;
1161
1162 mutex_lock(&glights->lights_lock);
1163 ret = gb_lights_get_count(glights);
1164 if (ret < 0)
1165 goto out;
1166
3036d0e2 1167 glights->lights = kcalloc(glights->lights_count,
2870b52b
RMS
1168 sizeof(struct gb_light), GFP_KERNEL);
1169 if (!glights->lights) {
1170 ret = -ENOMEM;
1171 goto out;
1172 }
1173
1174 for (i = 0; i < glights->lights_count; i++) {
1175 ret = gb_lights_light_config(glights, i);
1176 if (ret < 0) {
5fd18b37 1177 dev_err(&connection->bundle->dev,
2870b52b
RMS
1178 "Fail to configure lights device\n");
1179 goto out;
1180 }
1181 }
1182
1183out:
1184 mutex_unlock(&glights->lights_lock);
1185 return ret;
1186}
1187
6ce0eed7
VK
1188static int gb_lights_register_all(struct gb_lights *glights)
1189{
1190 struct gb_connection *connection = glights->connection;
1191 int ret = 0;
1192 int i;
1193
1194 mutex_lock(&glights->lights_lock);
1195 for (i = 0; i < glights->lights_count; i++) {
1196 ret = gb_lights_light_register(&glights->lights[i]);
1197 if (ret < 0) {
1198 dev_err(&connection->bundle->dev,
1199 "Fail to enable lights device\n");
1200 break;
1201 }
1202 }
1203
1204 mutex_unlock(&glights->lights_lock);
1205 return ret;
1206}
1207
69564dfe 1208static int gb_lights_request_handler(struct gb_operation *op)
2870b52b
RMS
1209{
1210 struct gb_connection *connection = op->connection;
5fd18b37 1211 struct device *dev = &connection->bundle->dev;
0ec30632 1212 struct gb_lights *glights = gb_connection_get_data(connection);
6ce0eed7 1213 struct gb_light *light;
2870b52b
RMS
1214 struct gb_message *request;
1215 struct gb_lights_event_request *payload;
1216 int ret = 0;
1217 u8 light_id;
1218 u8 event;
1219
69564dfe
VK
1220 if (op->type != GB_LIGHTS_TYPE_EVENT) {
1221 dev_err(dev, "Unsupported unsolicited event: %u\n", op->type);
2870b52b
RMS
1222 return -EINVAL;
1223 }
1224
1225 request = op->request;
1226
1227 if (request->payload_size < sizeof(*payload)) {
5fd18b37 1228 dev_err(dev, "Wrong event size received (%zu < %zu)\n",
2870b52b
RMS
1229 request->payload_size, sizeof(*payload));
1230 return -EINVAL;
1231 }
1232
1233 payload = request->payload;
1234 light_id = payload->light_id;
1235
bf9deb29 1236 if (light_id >= glights->lights_count ||
c6ad27a9 1237 !glights->lights[light_id].ready) {
5fd18b37 1238 dev_err(dev, "Event received for unconfigured light id: %d\n",
2870b52b
RMS
1239 light_id);
1240 return -EINVAL;
1241 }
1242
1243 event = payload->event;
1244
1245 if (event & GB_LIGHTS_LIGHT_CONFIG) {
6ce0eed7
VK
1246 light = &glights->lights[light_id];
1247
2870b52b 1248 mutex_lock(&glights->lights_lock);
6ce0eed7 1249 gb_lights_light_release(light);
2870b52b 1250 ret = gb_lights_light_config(glights, light_id);
6ce0eed7
VK
1251 if (!ret)
1252 ret = gb_lights_light_register(light);
2870b52b 1253 if (ret < 0)
6ce0eed7 1254 gb_lights_light_release(light);
2870b52b
RMS
1255 mutex_unlock(&glights->lights_lock);
1256 }
1257
1258 return ret;
1259}
1260
69564dfe
VK
1261static int gb_lights_probe(struct gb_bundle *bundle,
1262 const struct greybus_bundle_id *id)
2870b52b 1263{
69564dfe
VK
1264 struct greybus_descriptor_cport *cport_desc;
1265 struct gb_connection *connection;
2870b52b
RMS
1266 struct gb_lights *glights;
1267 int ret;
1268
69564dfe
VK
1269 if (bundle->num_cports != 1)
1270 return -ENODEV;
1271
1272 cport_desc = &bundle->cport_desc[0];
1273 if (cport_desc->protocol_id != GREYBUS_PROTOCOL_LIGHTS)
1274 return -ENODEV;
1275
2870b52b
RMS
1276 glights = kzalloc(sizeof(*glights), GFP_KERNEL);
1277 if (!glights)
1278 return -ENOMEM;
1279
957ccca0
VK
1280 mutex_init(&glights->lights_lock);
1281
69564dfe
VK
1282 connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
1283 gb_lights_request_handler);
1284 if (IS_ERR(connection)) {
1285 ret = PTR_ERR(connection);
1286 goto out;
1287 }
1288
2870b52b 1289 glights->connection = connection;
0ec30632 1290 gb_connection_set_data(connection, glights);
2870b52b 1291
69564dfe
VK
1292 greybus_set_drvdata(bundle, glights);
1293
1294 /* We aren't ready to receive an incoming request yet */
1295 ret = gb_connection_enable_tx(connection);
1296 if (ret)
1297 goto error_connection_destroy;
1298
2870b52b
RMS
1299 /*
1300 * Setup all the lights devices over this connection, if anything goes
1301 * wrong tear down all lights
1302 */
6ce0eed7
VK
1303 ret = gb_lights_create_all(glights);
1304 if (ret < 0)
69564dfe
VK
1305 goto error_connection_disable;
1306
1307 /* We are ready to receive an incoming request now, enable RX as well */
1308 ret = gb_connection_enable(connection);
1309 if (ret)
1310 goto error_connection_disable;
6ce0eed7
VK
1311
1312 /* Enable & register lights */
1313 ret = gb_lights_register_all(glights);
2870b52b 1314 if (ret < 0)
69564dfe 1315 goto error_connection_disable;
2870b52b 1316
9141ad87
KH
1317 gb_pm_runtime_put_autosuspend(bundle);
1318
2870b52b
RMS
1319 return 0;
1320
69564dfe
VK
1321error_connection_disable:
1322 gb_connection_disable(connection);
1323error_connection_destroy:
1324 gb_connection_destroy(connection);
2870b52b
RMS
1325out:
1326 gb_lights_release(glights);
1327 return ret;
1328}
1329
69564dfe 1330static void gb_lights_disconnect(struct gb_bundle *bundle)
2870b52b 1331{
69564dfe
VK
1332 struct gb_lights *glights = greybus_get_drvdata(bundle);
1333
9141ad87
KH
1334 if (gb_pm_runtime_get_sync(bundle))
1335 gb_pm_runtime_get_noresume(bundle);
1336
69564dfe
VK
1337 gb_connection_disable(glights->connection);
1338 gb_connection_destroy(glights->connection);
2870b52b
RMS
1339
1340 gb_lights_release(glights);
1341}
1342
69564dfe
VK
1343static const struct greybus_bundle_id gb_lights_id_table[] = {
1344 { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_LIGHTS) },
1345 { }
2870b52b 1346};
69564dfe 1347MODULE_DEVICE_TABLE(greybus, gb_lights_id_table);
2870b52b 1348
69564dfe
VK
1349static struct greybus_driver gb_lights_driver = {
1350 .name = "lights",
1351 .probe = gb_lights_probe,
1352 .disconnect = gb_lights_disconnect,
1353 .id_table = gb_lights_id_table,
1354};
1355module_greybus_driver(gb_lights_driver);
2870b52b
RMS
1356
1357MODULE_LICENSE("GPL v2");