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