1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Driver for Analog Devices ADV748X CSI-2 Transmitter
4  *
5  * Copyright (C) 2017 Renesas Electronics Corp.
6  */
7 
8 #include <linux/module.h>
9 #include <linux/mutex.h>
10 
11 #include <media/v4l2-ctrls.h>
12 #include <media/v4l2-device.h>
13 #include <media/v4l2-ioctl.h>
14 
15 #include "adv748x.h"
16 
17 static int adv748x_csi2_set_virtual_channel(struct adv748x_csi2 *tx,
18 					    unsigned int vc)
19 {
20 	return tx_write(tx, ADV748X_CSI_VC_REF, vc << ADV748X_CSI_VC_REF_SHIFT);
21 }
22 
23 /**
24  * adv748x_csi2_register_link : Register and link internal entities
25  *
26  * @tx: CSI2 private entity
27  * @v4l2_dev: Video registration device
28  * @src: Source subdevice to establish link
29  * @src_pad: Pad number of source to link to this @tx
30  * @enable: Link enabled flag
31  *
32  * Ensure that the subdevice is registered against the v4l2_device, and link the
33  * source pad to the sink pad of the CSI2 bus entity.
34  */
35 static int adv748x_csi2_register_link(struct adv748x_csi2 *tx,
36 				      struct v4l2_device *v4l2_dev,
37 				      struct v4l2_subdev *src,
38 				      unsigned int src_pad,
39 				      bool enable)
40 {
41 	int ret;
42 
43 	if (!src->v4l2_dev) {
44 		ret = v4l2_device_register_subdev(v4l2_dev, src);
45 		if (ret)
46 			return ret;
47 	}
48 
49 	ret = media_create_pad_link(&src->entity, src_pad,
50 				    &tx->sd.entity, ADV748X_CSI2_SINK,
51 				    enable ? MEDIA_LNK_FL_ENABLED : 0);
52 	if (ret)
53 		return ret;
54 
55 	if (enable)
56 		tx->src = src;
57 
58 	return 0;
59 }
60 
61 /* -----------------------------------------------------------------------------
62  * v4l2_subdev_internal_ops
63  *
64  * We use the internal registered operation to be able to ensure that our
65  * incremental subdevices (not connected in the forward path) can be registered
66  * against the resulting video path and media device.
67  */
68 
69 static int adv748x_csi2_registered(struct v4l2_subdev *sd)
70 {
71 	struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
72 	struct adv748x_state *state = tx->state;
73 	int ret;
74 
75 	adv_dbg(state, "Registered %s (%s)", is_txa(tx) ? "TXA":"TXB",
76 			sd->name);
77 
78 	/*
79 	 * Link TXA to AFE and HDMI, and TXB to AFE only as TXB cannot output
80 	 * HDMI.
81 	 *
82 	 * The HDMI->TXA link is enabled by default, as is the AFE->TXB one.
83 	 */
84 	if (is_afe_enabled(state)) {
85 		ret = adv748x_csi2_register_link(tx, sd->v4l2_dev,
86 						 &state->afe.sd,
87 						 ADV748X_AFE_SOURCE,
88 						 is_txb(tx));
89 		if (ret)
90 			return ret;
91 	}
92 
93 	/* Register link to HDMI for TXA only. */
94 	if (is_txb(tx) || !is_hdmi_enabled(state))
95 		return 0;
96 
97 	return adv748x_csi2_register_link(tx, sd->v4l2_dev, &state->hdmi.sd,
98 					  ADV748X_HDMI_SOURCE, true);
99 }
100 
101 static const struct v4l2_subdev_internal_ops adv748x_csi2_internal_ops = {
102 	.registered = adv748x_csi2_registered,
103 };
104 
105 /* -----------------------------------------------------------------------------
106  * v4l2_subdev_video_ops
107  */
108 
109 static int adv748x_csi2_s_stream(struct v4l2_subdev *sd, int enable)
110 {
111 	struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
112 	struct v4l2_subdev *src;
113 
114 	src = adv748x_get_remote_sd(&tx->pads[ADV748X_CSI2_SINK]);
115 	if (!src)
116 		return -EPIPE;
117 
118 	return v4l2_subdev_call(src, video, s_stream, enable);
119 }
120 
121 static const struct v4l2_subdev_video_ops adv748x_csi2_video_ops = {
122 	.s_stream = adv748x_csi2_s_stream,
123 };
124 
125 /* -----------------------------------------------------------------------------
126  * v4l2_subdev_pad_ops
127  *
128  * The CSI2 bus pads are ignorant to the data sizes or formats.
129  * But we must support setting the pad formats for format propagation.
130  */
131 
132 static struct v4l2_mbus_framefmt *
133 adv748x_csi2_get_pad_format(struct v4l2_subdev *sd,
134 			    struct v4l2_subdev_pad_config *cfg,
135 			    unsigned int pad, u32 which)
136 {
137 	struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
138 
139 	if (which == V4L2_SUBDEV_FORMAT_TRY)
140 		return v4l2_subdev_get_try_format(sd, cfg, pad);
141 
142 	return &tx->format;
143 }
144 
145 static int adv748x_csi2_get_format(struct v4l2_subdev *sd,
146 				   struct v4l2_subdev_pad_config *cfg,
147 				   struct v4l2_subdev_format *sdformat)
148 {
149 	struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
150 	struct adv748x_state *state = tx->state;
151 	struct v4l2_mbus_framefmt *mbusformat;
152 
153 	mbusformat = adv748x_csi2_get_pad_format(sd, cfg, sdformat->pad,
154 						 sdformat->which);
155 	if (!mbusformat)
156 		return -EINVAL;
157 
158 	mutex_lock(&state->mutex);
159 
160 	sdformat->format = *mbusformat;
161 
162 	mutex_unlock(&state->mutex);
163 
164 	return 0;
165 }
166 
167 static int adv748x_csi2_set_format(struct v4l2_subdev *sd,
168 				   struct v4l2_subdev_pad_config *cfg,
169 				   struct v4l2_subdev_format *sdformat)
170 {
171 	struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
172 	struct adv748x_state *state = tx->state;
173 	struct v4l2_mbus_framefmt *mbusformat;
174 	int ret = 0;
175 
176 	mbusformat = adv748x_csi2_get_pad_format(sd, cfg, sdformat->pad,
177 						 sdformat->which);
178 	if (!mbusformat)
179 		return -EINVAL;
180 
181 	mutex_lock(&state->mutex);
182 
183 	if (sdformat->pad == ADV748X_CSI2_SOURCE) {
184 		const struct v4l2_mbus_framefmt *sink_fmt;
185 
186 		sink_fmt = adv748x_csi2_get_pad_format(sd, cfg,
187 						       ADV748X_CSI2_SINK,
188 						       sdformat->which);
189 
190 		if (!sink_fmt) {
191 			ret = -EINVAL;
192 			goto unlock;
193 		}
194 
195 		sdformat->format = *sink_fmt;
196 	}
197 
198 	*mbusformat = sdformat->format;
199 
200 unlock:
201 	mutex_unlock(&state->mutex);
202 
203 	return ret;
204 }
205 
206 static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = {
207 	.get_fmt = adv748x_csi2_get_format,
208 	.set_fmt = adv748x_csi2_set_format,
209 };
210 
211 /* -----------------------------------------------------------------------------
212  * v4l2_subdev_ops
213  */
214 
215 static const struct v4l2_subdev_ops adv748x_csi2_ops = {
216 	.video = &adv748x_csi2_video_ops,
217 	.pad = &adv748x_csi2_pad_ops,
218 };
219 
220 /* -----------------------------------------------------------------------------
221  * Subdev module and controls
222  */
223 
224 int adv748x_csi2_set_pixelrate(struct v4l2_subdev *sd, s64 rate)
225 {
226 	struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
227 
228 	if (!tx->pixel_rate)
229 		return -EINVAL;
230 
231 	return v4l2_ctrl_s_ctrl_int64(tx->pixel_rate, rate);
232 }
233 
234 static int adv748x_csi2_s_ctrl(struct v4l2_ctrl *ctrl)
235 {
236 	switch (ctrl->id) {
237 	case V4L2_CID_PIXEL_RATE:
238 		return 0;
239 	default:
240 		return -EINVAL;
241 	}
242 }
243 
244 static const struct v4l2_ctrl_ops adv748x_csi2_ctrl_ops = {
245 	.s_ctrl = adv748x_csi2_s_ctrl,
246 };
247 
248 static int adv748x_csi2_init_controls(struct adv748x_csi2 *tx)
249 {
250 
251 	v4l2_ctrl_handler_init(&tx->ctrl_hdl, 1);
252 
253 	tx->pixel_rate = v4l2_ctrl_new_std(&tx->ctrl_hdl,
254 					   &adv748x_csi2_ctrl_ops,
255 					   V4L2_CID_PIXEL_RATE, 1, INT_MAX,
256 					   1, 1);
257 
258 	tx->sd.ctrl_handler = &tx->ctrl_hdl;
259 	if (tx->ctrl_hdl.error) {
260 		v4l2_ctrl_handler_free(&tx->ctrl_hdl);
261 		return tx->ctrl_hdl.error;
262 	}
263 
264 	return v4l2_ctrl_handler_setup(&tx->ctrl_hdl);
265 }
266 
267 int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx)
268 {
269 	int ret;
270 
271 	if (!is_tx_enabled(tx))
272 		return 0;
273 
274 	/* Initialise the virtual channel */
275 	adv748x_csi2_set_virtual_channel(tx, 0);
276 
277 	adv748x_subdev_init(&tx->sd, state, &adv748x_csi2_ops,
278 			    MEDIA_ENT_F_VID_IF_BRIDGE,
279 			    is_txa(tx) ? "txa" : "txb");
280 
281 	/* Ensure that matching is based upon the endpoint fwnodes */
282 	tx->sd.fwnode = of_fwnode_handle(state->endpoints[tx->port]);
283 
284 	/* Register internal ops for incremental subdev registration */
285 	tx->sd.internal_ops = &adv748x_csi2_internal_ops;
286 
287 	tx->pads[ADV748X_CSI2_SINK].flags = MEDIA_PAD_FL_SINK;
288 	tx->pads[ADV748X_CSI2_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
289 
290 	ret = media_entity_pads_init(&tx->sd.entity, ADV748X_CSI2_NR_PADS,
291 				     tx->pads);
292 	if (ret)
293 		return ret;
294 
295 	ret = adv748x_csi2_init_controls(tx);
296 	if (ret)
297 		goto err_free_media;
298 
299 	ret = v4l2_async_register_subdev(&tx->sd);
300 	if (ret)
301 		goto err_free_ctrl;
302 
303 	return 0;
304 
305 err_free_ctrl:
306 	v4l2_ctrl_handler_free(&tx->ctrl_hdl);
307 err_free_media:
308 	media_entity_cleanup(&tx->sd.entity);
309 
310 	return ret;
311 }
312 
313 void adv748x_csi2_cleanup(struct adv748x_csi2 *tx)
314 {
315 	if (!is_tx_enabled(tx))
316 		return;
317 
318 	v4l2_async_unregister_subdev(&tx->sd);
319 	media_entity_cleanup(&tx->sd.entity);
320 	v4l2_ctrl_handler_free(&tx->ctrl_hdl);
321 }
322