GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / media / i2c / adv748x / adv748x-csi2.c
1 /*
2  * Driver for Analog Devices ADV748X CSI-2 Transmitter
3  *
4  * Copyright (C) 2017 Renesas Electronics Corp.
5  *
6  * This program is free software; you can redistribute  it and/or modify it
7  * under  the terms of  the GNU General  Public License as published by the
8  * Free Software Foundation;  either version 2 of the  License, or (at your
9  * option) any later version.
10  */
11
12 #include <linux/module.h>
13 #include <linux/mutex.h>
14
15 #include <media/v4l2-ctrls.h>
16 #include <media/v4l2-device.h>
17 #include <media/v4l2-ioctl.h>
18
19 #include "adv748x.h"
20
21 static bool is_txa(struct adv748x_csi2 *tx)
22 {
23         return tx == &tx->state->txa;
24 }
25
26 static int adv748x_csi2_set_virtual_channel(struct adv748x_csi2 *tx,
27                                             unsigned int vc)
28 {
29         return tx_write(tx, ADV748X_CSI_VC_REF, vc << ADV748X_CSI_VC_REF_SHIFT);
30 }
31
32 /**
33  * adv748x_csi2_register_link : Register and link internal entities
34  *
35  * @tx: CSI2 private entity
36  * @v4l2_dev: Video registration device
37  * @src: Source subdevice to establish link
38  * @src_pad: Pad number of source to link to this @tx
39  *
40  * Ensure that the subdevice is registered against the v4l2_device, and link the
41  * source pad to the sink pad of the CSI2 bus entity.
42  */
43 static int adv748x_csi2_register_link(struct adv748x_csi2 *tx,
44                                       struct v4l2_device *v4l2_dev,
45                                       struct v4l2_subdev *src,
46                                       unsigned int src_pad)
47 {
48         int enabled = MEDIA_LNK_FL_ENABLED;
49         int ret;
50
51         /*
52          * Dynamic linking of the AFE is not supported.
53          * Register the links as immutable.
54          */
55         enabled |= MEDIA_LNK_FL_IMMUTABLE;
56
57         if (!src->v4l2_dev) {
58                 ret = v4l2_device_register_subdev(v4l2_dev, src);
59                 if (ret)
60                         return ret;
61         }
62
63         return media_create_pad_link(&src->entity, src_pad,
64                                      &tx->sd.entity, ADV748X_CSI2_SINK,
65                                      enabled);
66 }
67
68 /* -----------------------------------------------------------------------------
69  * v4l2_subdev_internal_ops
70  *
71  * We use the internal registered operation to be able to ensure that our
72  * incremental subdevices (not connected in the forward path) can be registered
73  * against the resulting video path and media device.
74  */
75
76 static int adv748x_csi2_registered(struct v4l2_subdev *sd)
77 {
78         struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
79         struct adv748x_state *state = tx->state;
80
81         adv_dbg(state, "Registered %s (%s)", is_txa(tx) ? "TXA":"TXB",
82                         sd->name);
83
84         /*
85          * The adv748x hardware allows the AFE to route through the TXA, however
86          * this is not currently supported in this driver.
87          *
88          * Link HDMI->TXA, and AFE->TXB directly.
89          */
90         if (is_txa(tx)) {
91                 return adv748x_csi2_register_link(tx, sd->v4l2_dev,
92                                                   &state->hdmi.sd,
93                                                   ADV748X_HDMI_SOURCE);
94         } else {
95                 return adv748x_csi2_register_link(tx, sd->v4l2_dev,
96                                                   &state->afe.sd,
97                                                   ADV748X_AFE_SOURCE);
98         }
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 }