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 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 247 static 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 257 static 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 266 int 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 276 static 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 286 static const struct v4l2_ctrl_ops adv748x_csi2_ctrl_ops = { 287 .s_ctrl = adv748x_csi2_s_ctrl, 288 }; 289 290 static 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 309 int 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 347 err_free_ctrl: 348 v4l2_ctrl_handler_free(&tx->ctrl_hdl); 349 err_free_media: 350 media_entity_cleanup(&tx->sd.entity); 351 352 return ret; 353 } 354 355 void 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