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 /* 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 112 static 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 120 static 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 132 static 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 143 static struct v4l2_mbus_framefmt * 144 adv748x_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 156 static 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 178 static 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 211 unlock: 212 mutex_unlock(&state->mutex); 213 214 return ret; 215 } 216 217 static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = { 218 .get_fmt = adv748x_csi2_get_format, 219 .set_fmt = adv748x_csi2_set_format, 220 }; 221 222 /* ----------------------------------------------------------------------------- 223 * v4l2_subdev_ops 224 */ 225 226 static const struct v4l2_subdev_ops adv748x_csi2_ops = { 227 .video = &adv748x_csi2_video_ops, 228 .pad = &adv748x_csi2_pad_ops, 229 }; 230 231 /* ----------------------------------------------------------------------------- 232 * Subdev module and controls 233 */ 234 235 int adv748x_csi2_set_pixelrate(struct v4l2_subdev *sd, s64 rate) 236 { 237 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); 238 239 if (!tx->pixel_rate) 240 return -EINVAL; 241 242 return v4l2_ctrl_s_ctrl_int64(tx->pixel_rate, rate); 243 } 244 245 static int adv748x_csi2_s_ctrl(struct v4l2_ctrl *ctrl) 246 { 247 switch (ctrl->id) { 248 case V4L2_CID_PIXEL_RATE: 249 return 0; 250 default: 251 return -EINVAL; 252 } 253 } 254 255 static const struct v4l2_ctrl_ops adv748x_csi2_ctrl_ops = { 256 .s_ctrl = adv748x_csi2_s_ctrl, 257 }; 258 259 static int adv748x_csi2_init_controls(struct adv748x_csi2 *tx) 260 { 261 262 v4l2_ctrl_handler_init(&tx->ctrl_hdl, 1); 263 264 tx->pixel_rate = v4l2_ctrl_new_std(&tx->ctrl_hdl, 265 &adv748x_csi2_ctrl_ops, 266 V4L2_CID_PIXEL_RATE, 1, INT_MAX, 267 1, 1); 268 269 tx->sd.ctrl_handler = &tx->ctrl_hdl; 270 if (tx->ctrl_hdl.error) { 271 v4l2_ctrl_handler_free(&tx->ctrl_hdl); 272 return tx->ctrl_hdl.error; 273 } 274 275 return v4l2_ctrl_handler_setup(&tx->ctrl_hdl); 276 } 277 278 int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) 279 { 280 int ret; 281 282 if (!is_tx_enabled(tx)) 283 return 0; 284 285 /* Initialise the virtual channel */ 286 adv748x_csi2_set_virtual_channel(tx, 0); 287 288 adv748x_subdev_init(&tx->sd, state, &adv748x_csi2_ops, 289 MEDIA_ENT_F_VID_IF_BRIDGE, 290 is_txa(tx) ? "txa" : "txb"); 291 292 /* Ensure that matching is based upon the endpoint fwnodes */ 293 tx->sd.fwnode = of_fwnode_handle(state->endpoints[tx->port]); 294 295 /* Register internal ops for incremental subdev registration */ 296 tx->sd.internal_ops = &adv748x_csi2_internal_ops; 297 298 tx->pads[ADV748X_CSI2_SINK].flags = MEDIA_PAD_FL_SINK; 299 tx->pads[ADV748X_CSI2_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 300 301 ret = media_entity_pads_init(&tx->sd.entity, ADV748X_CSI2_NR_PADS, 302 tx->pads); 303 if (ret) 304 return ret; 305 306 ret = adv748x_csi2_init_controls(tx); 307 if (ret) 308 goto err_free_media; 309 310 ret = v4l2_async_register_subdev(&tx->sd); 311 if (ret) 312 goto err_free_ctrl; 313 314 return 0; 315 316 err_free_ctrl: 317 v4l2_ctrl_handler_free(&tx->ctrl_hdl); 318 err_free_media: 319 media_entity_cleanup(&tx->sd.entity); 320 321 return ret; 322 } 323 324 void adv748x_csi2_cleanup(struct adv748x_csi2 *tx) 325 { 326 if (!is_tx_enabled(tx)) 327 return; 328 329 v4l2_async_unregister_subdev(&tx->sd); 330 media_entity_cleanup(&tx->sd.entity); 331 v4l2_ctrl_handler_free(&tx->ctrl_hdl); 332 } 333