1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * V4L2 flash LED sub-device registration helpers.
4  *
5  *	Copyright (C) 2015 Samsung Electronics Co., Ltd
6  *	Author: Jacek Anaszewski <j.anaszewski@samsung.com>
7  */
8 
9 #ifndef _V4L2_FLASH_H
10 #define _V4L2_FLASH_H
11 
12 #include <media/v4l2-ctrls.h>
13 #include <media/v4l2-subdev.h>
14 
15 struct led_classdev_flash;
16 struct led_classdev;
17 struct v4l2_flash;
18 enum led_brightness;
19 
20 /**
21  * struct v4l2_flash_ctrl_data - flash control initialization data, filled
22  *				basing on the features declared by the LED flash
23  *				class driver in the v4l2_flash_config
24  * @config:	initialization data for a control
25  * @cid:	contains v4l2 flash control id if the config
26  *		field was initialized, 0 otherwise
27  */
28 struct v4l2_flash_ctrl_data {
29 	struct v4l2_ctrl_config config;
30 	u32 cid;
31 };
32 
33 /**
34  * struct v4l2_flash_ops - V4L2 flash operations
35  *
36  * @external_strobe_set: Setup strobing the flash by hardware pin state
37  *	assertion.
38  * @intensity_to_led_brightness: Convert intensity to brightness in a device
39  *	specific manner
40  * @led_brightness_to_intensity: convert brightness to intensity in a device
41  *	specific manner.
42  */
43 struct v4l2_flash_ops {
44 	int (*external_strobe_set)(struct v4l2_flash *v4l2_flash,
45 					bool enable);
46 	enum led_brightness (*intensity_to_led_brightness)
47 		(struct v4l2_flash *v4l2_flash, s32 intensity);
48 	s32 (*led_brightness_to_intensity)
49 		(struct v4l2_flash *v4l2_flash, enum led_brightness);
50 };
51 
52 /**
53  * struct v4l2_flash_config - V4L2 Flash sub-device initialization data
54  * @dev_name:			the name of the media entity,
55  *				unique in the system
56  * @intensity:			non-flash strobe constraints for the LED
57  * @flash_faults:		bitmask of flash faults that the LED flash class
58  *				device can report; corresponding LED_FAULT* bit
59  *				definitions are available in the header file
60  *				<linux/led-class-flash.h>
61  * @has_external_strobe:	external strobe capability
62  */
63 struct v4l2_flash_config {
64 	char dev_name[32];
65 	struct led_flash_setting intensity;
66 	u32 flash_faults;
67 	unsigned int has_external_strobe:1;
68 };
69 
70 /**
71  * struct v4l2_flash - Flash sub-device context
72  * @fled_cdev:		LED flash class device controlled by this sub-device
73  * @iled_cdev:		LED class device representing indicator LED associated
74  *			with the LED flash class device
75  * @ops:		V4L2 specific flash ops
76  * @sd:			V4L2 sub-device
77  * @hdl:		flash controls handler
78  * @ctrls:		array of pointers to controls, whose values define
79  *			the sub-device state
80  */
81 struct v4l2_flash {
82 	struct led_classdev_flash *fled_cdev;
83 	struct led_classdev *iled_cdev;
84 	const struct v4l2_flash_ops *ops;
85 
86 	struct v4l2_subdev sd;
87 	struct v4l2_ctrl_handler hdl;
88 	struct v4l2_ctrl **ctrls;
89 };
90 
91 /**
92  * v4l2_subdev_to_v4l2_flash - Returns a &struct v4l2_flash from the
93  * &struct v4l2_subdev embedded on it.
94  *
95  * @sd: pointer to &struct v4l2_subdev
96  */
97 static inline struct v4l2_flash *v4l2_subdev_to_v4l2_flash(
98 							struct v4l2_subdev *sd)
99 {
100 	return container_of(sd, struct v4l2_flash, sd);
101 }
102 
103 /**
104  * v4l2_ctrl_to_v4l2_flash - Returns a &struct v4l2_flash from the
105  * &struct v4l2_ctrl embedded on it.
106  *
107  * @c: pointer to &struct v4l2_ctrl
108  */
109 static inline struct v4l2_flash *v4l2_ctrl_to_v4l2_flash(struct v4l2_ctrl *c)
110 {
111 	return container_of(c->handler, struct v4l2_flash, hdl);
112 }
113 
114 #if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS)
115 /**
116  * v4l2_flash_init - initialize V4L2 flash led sub-device
117  * @dev:	flash device, e.g. an I2C device
118  * @fwn:	fwnode_handle of the LED, may be NULL if the same as device's
119  * @fled_cdev:	LED flash class device to wrap
120  * @ops:	V4L2 Flash device ops
121  * @config:	initialization data for V4L2 Flash sub-device
122  *
123  * Create V4L2 Flash sub-device wrapping given LED subsystem device.
124  * The ops pointer is stored by the V4L2 flash framework. No
125  * references are held to config nor its contents once this function
126  * has returned.
127  *
128  * Returns: A valid pointer, or, when an error occurs, the return
129  * value is encoded using ERR_PTR(). Use IS_ERR() to check and
130  * PTR_ERR() to obtain the numeric return value.
131  */
132 struct v4l2_flash *v4l2_flash_init(
133 	struct device *dev, struct fwnode_handle *fwn,
134 	struct led_classdev_flash *fled_cdev,
135 	const struct v4l2_flash_ops *ops, struct v4l2_flash_config *config);
136 
137 /**
138  * v4l2_flash_indicator_init - initialize V4L2 indicator sub-device
139  * @dev:	flash device, e.g. an I2C device
140  * @fwn:	fwnode_handle of the LED, may be NULL if the same as device's
141  * @iled_cdev:	LED flash class device representing the indicator LED
142  * @config:	initialization data for V4L2 Flash sub-device
143  *
144  * Create V4L2 Flash sub-device wrapping given LED subsystem device.
145  * The ops pointer is stored by the V4L2 flash framework. No
146  * references are held to config nor its contents once this function
147  * has returned.
148  *
149  * Returns: A valid pointer, or, when an error occurs, the return
150  * value is encoded using ERR_PTR(). Use IS_ERR() to check and
151  * PTR_ERR() to obtain the numeric return value.
152  */
153 struct v4l2_flash *v4l2_flash_indicator_init(
154 	struct device *dev, struct fwnode_handle *fwn,
155 	struct led_classdev *iled_cdev, struct v4l2_flash_config *config);
156 
157 /**
158  * v4l2_flash_release - release V4L2 Flash sub-device
159  * @v4l2_flash: the V4L2 Flash sub-device to release
160  *
161  * Release V4L2 Flash sub-device.
162  */
163 void v4l2_flash_release(struct v4l2_flash *v4l2_flash);
164 
165 #else
166 static inline struct v4l2_flash *v4l2_flash_init(
167 	struct device *dev, struct fwnode_handle *fwn,
168 	struct led_classdev_flash *fled_cdev,
169 	const struct v4l2_flash_ops *ops, struct v4l2_flash_config *config)
170 {
171 	return NULL;
172 }
173 
174 static inline struct v4l2_flash *v4l2_flash_indicator_init(
175 	struct device *dev, struct fwnode_handle *fwn,
176 	struct led_classdev *iled_cdev, struct v4l2_flash_config *config)
177 {
178 	return NULL;
179 }
180 
181 static inline void v4l2_flash_release(struct v4l2_flash *v4l2_flash)
182 {
183 }
184 #endif /* CONFIG_V4L2_FLASH_LED_CLASS */
185 
186 #endif /* _V4L2_FLASH_H */
187