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 93 /* Register link to HDMI for TXA only. */ 94 if (is_txb(tx) || !is_hdmi_enabled(state)) 95 return 0; 96 97 return adv748x_csi2_register_link(tx, sd->v4l2_dev, &state->hdmi.sd, 98 ADV748X_HDMI_SOURCE, true); 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 } 322