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_pad_config *cfg, 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, cfg, pad); 151 152 return &tx->format; 153 } 154 155 static int adv748x_csi2_get_format(struct v4l2_subdev *sd, 156 struct v4l2_subdev_pad_config *cfg, 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, cfg, 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_pad_config *cfg, 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, cfg, 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, cfg, 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 switch (tx->active_lanes) { 226 case 1: 227 config->flags = V4L2_MBUS_CSI2_1_LANE; 228 break; 229 230 case 2: 231 config->flags = V4L2_MBUS_CSI2_2_LANE; 232 break; 233 234 case 3: 235 config->flags = V4L2_MBUS_CSI2_3_LANE; 236 break; 237 238 case 4: 239 config->flags = V4L2_MBUS_CSI2_4_LANE; 240 break; 241 } 242 243 return 0; 244 } 245 246 static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = { 247 .get_fmt = adv748x_csi2_get_format, 248 .set_fmt = adv748x_csi2_set_format, 249 .get_mbus_config = adv748x_csi2_get_mbus_config, 250 }; 251 252 /* ----------------------------------------------------------------------------- 253 * v4l2_subdev_ops 254 */ 255 256 static const struct v4l2_subdev_ops adv748x_csi2_ops = { 257 .video = &adv748x_csi2_video_ops, 258 .pad = &adv748x_csi2_pad_ops, 259 }; 260 261 /* ----------------------------------------------------------------------------- 262 * Subdev module and controls 263 */ 264 265 int adv748x_csi2_set_pixelrate(struct v4l2_subdev *sd, s64 rate) 266 { 267 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); 268 269 if (!tx->pixel_rate) 270 return -EINVAL; 271 272 return v4l2_ctrl_s_ctrl_int64(tx->pixel_rate, rate); 273 } 274 275 static int adv748x_csi2_s_ctrl(struct v4l2_ctrl *ctrl) 276 { 277 switch (ctrl->id) { 278 case V4L2_CID_PIXEL_RATE: 279 return 0; 280 default: 281 return -EINVAL; 282 } 283 } 284 285 static const struct v4l2_ctrl_ops adv748x_csi2_ctrl_ops = { 286 .s_ctrl = adv748x_csi2_s_ctrl, 287 }; 288 289 static int adv748x_csi2_init_controls(struct adv748x_csi2 *tx) 290 { 291 292 v4l2_ctrl_handler_init(&tx->ctrl_hdl, 1); 293 294 tx->pixel_rate = v4l2_ctrl_new_std(&tx->ctrl_hdl, 295 &adv748x_csi2_ctrl_ops, 296 V4L2_CID_PIXEL_RATE, 1, INT_MAX, 297 1, 1); 298 299 tx->sd.ctrl_handler = &tx->ctrl_hdl; 300 if (tx->ctrl_hdl.error) { 301 v4l2_ctrl_handler_free(&tx->ctrl_hdl); 302 return tx->ctrl_hdl.error; 303 } 304 305 return v4l2_ctrl_handler_setup(&tx->ctrl_hdl); 306 } 307 308 int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) 309 { 310 int ret; 311 312 if (!is_tx_enabled(tx)) 313 return 0; 314 315 adv748x_subdev_init(&tx->sd, state, &adv748x_csi2_ops, 316 MEDIA_ENT_F_VID_IF_BRIDGE, 317 is_txa(tx) ? "txa" : "txb"); 318 319 /* Ensure that matching is based upon the endpoint fwnodes */ 320 tx->sd.fwnode = of_fwnode_handle(state->endpoints[tx->port]); 321 322 /* Register internal ops for incremental subdev registration */ 323 tx->sd.internal_ops = &adv748x_csi2_internal_ops; 324 325 tx->pads[ADV748X_CSI2_SINK].flags = MEDIA_PAD_FL_SINK; 326 tx->pads[ADV748X_CSI2_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 327 328 ret = media_entity_pads_init(&tx->sd.entity, ADV748X_CSI2_NR_PADS, 329 tx->pads); 330 if (ret) 331 return ret; 332 333 ret = adv748x_csi2_init_controls(tx); 334 if (ret) 335 goto err_free_media; 336 337 ret = v4l2_async_register_subdev(&tx->sd); 338 if (ret) 339 goto err_free_ctrl; 340 341 return 0; 342 343 err_free_ctrl: 344 v4l2_ctrl_handler_free(&tx->ctrl_hdl); 345 err_free_media: 346 media_entity_cleanup(&tx->sd.entity); 347 348 return ret; 349 } 350 351 void adv748x_csi2_cleanup(struct adv748x_csi2 *tx) 352 { 353 if (!is_tx_enabled(tx)) 354 return; 355 356 v4l2_async_unregister_subdev(&tx->sd); 357 media_entity_cleanup(&tx->sd.entity); 358 v4l2_ctrl_handler_free(&tx->ctrl_hdl); 359 } 360