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
17static 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 */
35static 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
69static 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		/* TXB can output AFE signals only. */
93		if (is_txb(tx))
94			state->afe.tx = tx;
95	}
96
97	/* Register link to HDMI for TXA only. */
98	if (is_txb(tx) || !is_hdmi_enabled(state))
99		return 0;
100
101	ret = adv748x_csi2_register_link(tx, sd->v4l2_dev, &state->hdmi.sd,
102					 ADV748X_HDMI_SOURCE, true);
103	if (ret)
104		return ret;
105
106	/* The default HDMI output is TXA. */
107	state->hdmi.tx = tx;
108
109	return 0;
110}
111
112static const struct v4l2_subdev_internal_ops adv748x_csi2_internal_ops = {
113	.registered = adv748x_csi2_registered,
114};
115
116/* -----------------------------------------------------------------------------
117 * v4l2_subdev_video_ops
118 */
119
120static int adv748x_csi2_s_stream(struct v4l2_subdev *sd, int enable)
121{
122	struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
123	struct v4l2_subdev *src;
124
125	src = adv748x_get_remote_sd(&tx->pads[ADV748X_CSI2_SINK]);
126	if (!src)
127		return -EPIPE;
128
129	return v4l2_subdev_call(src, video, s_stream, enable);
130}
131
132static const struct v4l2_subdev_video_ops adv748x_csi2_video_ops = {
133	.s_stream = adv748x_csi2_s_stream,
134};
135
136/* -----------------------------------------------------------------------------
137 * v4l2_subdev_pad_ops
138 *
139 * The CSI2 bus pads are ignorant to the data sizes or formats.
140 * But we must support setting the pad formats for format propagation.
141 */
142
143static struct v4l2_mbus_framefmt *
144adv748x_csi2_get_pad_format(struct v4l2_subdev *sd,
145			    struct v4l2_subdev_pad_config *cfg,
146			    unsigned int pad, u32 which)
147{
148	struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
149
150	if (which == V4L2_SUBDEV_FORMAT_TRY)
151		return v4l2_subdev_get_try_format(sd, cfg, pad);
152
153	return &tx->format;
154}
155
156static int adv748x_csi2_get_format(struct v4l2_subdev *sd,
157				   struct v4l2_subdev_pad_config *cfg,
158				   struct v4l2_subdev_format *sdformat)
159{
160	struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
161	struct adv748x_state *state = tx->state;
162	struct v4l2_mbus_framefmt *mbusformat;
163
164	mbusformat = adv748x_csi2_get_pad_format(sd, cfg, sdformat->pad,
165						 sdformat->which);
166	if (!mbusformat)
167		return -EINVAL;
168
169	mutex_lock(&state->mutex);
170
171	sdformat->format = *mbusformat;
172
173	mutex_unlock(&state->mutex);
174
175	return 0;
176}
177
178static int adv748x_csi2_set_format(struct v4l2_subdev *sd,
179				   struct v4l2_subdev_pad_config *cfg,
180				   struct v4l2_subdev_format *sdformat)
181{
182	struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
183	struct adv748x_state *state = tx->state;
184	struct v4l2_mbus_framefmt *mbusformat;
185	int ret = 0;
186
187	mbusformat = adv748x_csi2_get_pad_format(sd, cfg, sdformat->pad,
188						 sdformat->which);
189	if (!mbusformat)
190		return -EINVAL;
191
192	mutex_lock(&state->mutex);
193
194	if (sdformat->pad == ADV748X_CSI2_SOURCE) {
195		const struct v4l2_mbus_framefmt *sink_fmt;
196
197		sink_fmt = adv748x_csi2_get_pad_format(sd, cfg,
198						       ADV748X_CSI2_SINK,
199						       sdformat->which);
200
201		if (!sink_fmt) {
202			ret = -EINVAL;
203			goto unlock;
204		}
205
206		sdformat->format = *sink_fmt;
207	}
208
209	*mbusformat = sdformat->format;
210
211unlock:
212	mutex_unlock(&state->mutex);
213
214	return ret;
215}
216
217static int adv748x_csi2_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
218					struct v4l2_mbus_config *config)
219{
220	struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
221
222	if (pad != ADV748X_CSI2_SOURCE)
223		return -EINVAL;
224
225	config->type = V4L2_MBUS_CSI2_DPHY;
226	switch (tx->active_lanes) {
227	case 1:
228		config->flags = V4L2_MBUS_CSI2_1_LANE;
229		break;
230
231	case 2:
232		config->flags = V4L2_MBUS_CSI2_2_LANE;
233		break;
234
235	case 3:
236		config->flags = V4L2_MBUS_CSI2_3_LANE;
237		break;
238
239	case 4:
240		config->flags = V4L2_MBUS_CSI2_4_LANE;
241		break;
242	}
243
244	return 0;
245}
246
247static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = {
248	.get_fmt = adv748x_csi2_get_format,
249	.set_fmt = adv748x_csi2_set_format,
250	.get_mbus_config = adv748x_csi2_get_mbus_config,
251};
252
253/* -----------------------------------------------------------------------------
254 * v4l2_subdev_ops
255 */
256
257static const struct v4l2_subdev_ops adv748x_csi2_ops = {
258	.video = &adv748x_csi2_video_ops,
259	.pad = &adv748x_csi2_pad_ops,
260};
261
262/* -----------------------------------------------------------------------------
263 * Subdev module and controls
264 */
265
266int adv748x_csi2_set_pixelrate(struct v4l2_subdev *sd, s64 rate)
267{
268	struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
269
270	if (!tx->pixel_rate)
271		return -EINVAL;
272
273	return v4l2_ctrl_s_ctrl_int64(tx->pixel_rate, rate);
274}
275
276static int adv748x_csi2_s_ctrl(struct v4l2_ctrl *ctrl)
277{
278	switch (ctrl->id) {
279	case V4L2_CID_PIXEL_RATE:
280		return 0;
281	default:
282		return -EINVAL;
283	}
284}
285
286static const struct v4l2_ctrl_ops adv748x_csi2_ctrl_ops = {
287	.s_ctrl = adv748x_csi2_s_ctrl,
288};
289
290static int adv748x_csi2_init_controls(struct adv748x_csi2 *tx)
291{
292
293	v4l2_ctrl_handler_init(&tx->ctrl_hdl, 1);
294
295	tx->pixel_rate = v4l2_ctrl_new_std(&tx->ctrl_hdl,
296					   &adv748x_csi2_ctrl_ops,
297					   V4L2_CID_PIXEL_RATE, 1, INT_MAX,
298					   1, 1);
299
300	tx->sd.ctrl_handler = &tx->ctrl_hdl;
301	if (tx->ctrl_hdl.error) {
302		v4l2_ctrl_handler_free(&tx->ctrl_hdl);
303		return tx->ctrl_hdl.error;
304	}
305
306	return v4l2_ctrl_handler_setup(&tx->ctrl_hdl);
307}
308
309int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx)
310{
311	int ret;
312
313	if (!is_tx_enabled(tx))
314		return 0;
315
316	/* Initialise the virtual channel */
317	adv748x_csi2_set_virtual_channel(tx, 0);
318
319	adv748x_subdev_init(&tx->sd, state, &adv748x_csi2_ops,
320			    MEDIA_ENT_F_VID_IF_BRIDGE,
321			    is_txa(tx) ? "txa" : "txb");
322
323	/* Ensure that matching is based upon the endpoint fwnodes */
324	tx->sd.fwnode = of_fwnode_handle(state->endpoints[tx->port]);
325
326	/* Register internal ops for incremental subdev registration */
327	tx->sd.internal_ops = &adv748x_csi2_internal_ops;
328
329	tx->pads[ADV748X_CSI2_SINK].flags = MEDIA_PAD_FL_SINK;
330	tx->pads[ADV748X_CSI2_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
331
332	ret = media_entity_pads_init(&tx->sd.entity, ADV748X_CSI2_NR_PADS,
333				     tx->pads);
334	if (ret)
335		return ret;
336
337	ret = adv748x_csi2_init_controls(tx);
338	if (ret)
339		goto err_free_media;
340
341	ret = v4l2_async_register_subdev(&tx->sd);
342	if (ret)
343		goto err_free_ctrl;
344
345	return 0;
346
347err_free_ctrl:
348	v4l2_ctrl_handler_free(&tx->ctrl_hdl);
349err_free_media:
350	media_entity_cleanup(&tx->sd.entity);
351
352	return ret;
353}
354
355void adv748x_csi2_cleanup(struct adv748x_csi2 *tx)
356{
357	if (!is_tx_enabled(tx))
358		return;
359
360	v4l2_async_unregister_subdev(&tx->sd);
361	media_entity_cleanup(&tx->sd.entity);
362	v4l2_ctrl_handler_free(&tx->ctrl_hdl);
363}
364