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