File Index
Files and directories
Sign in
FILE

light.c

File preview with syntax highlighting.

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