0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/mutex.h>
0010
0011 #include <media/v4l2-ctrls.h>
0012 #include <media/v4l2-device.h>
0013 #include <media/v4l2-ioctl.h>
0014
0015 #include "adv748x.h"
0016
0017 int adv748x_csi2_set_virtual_channel(struct adv748x_csi2 *tx, unsigned int vc)
0018 {
0019 return tx_write(tx, ADV748X_CSI_VC_REF, vc << ADV748X_CSI_VC_REF_SHIFT);
0020 }
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 static int adv748x_csi2_register_link(struct adv748x_csi2 *tx,
0035 struct v4l2_device *v4l2_dev,
0036 struct v4l2_subdev *src,
0037 unsigned int src_pad,
0038 bool enable)
0039 {
0040 int ret;
0041
0042 if (!src->v4l2_dev) {
0043 ret = v4l2_device_register_subdev(v4l2_dev, src);
0044 if (ret)
0045 return ret;
0046 }
0047
0048 ret = media_create_pad_link(&src->entity, src_pad,
0049 &tx->sd.entity, ADV748X_CSI2_SINK,
0050 enable ? MEDIA_LNK_FL_ENABLED : 0);
0051 if (ret)
0052 return ret;
0053
0054 if (enable)
0055 tx->src = src;
0056
0057 return 0;
0058 }
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 static int adv748x_csi2_registered(struct v4l2_subdev *sd)
0069 {
0070 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
0071 struct adv748x_state *state = tx->state;
0072 int ret;
0073
0074 adv_dbg(state, "Registered %s (%s)", is_txa(tx) ? "TXA":"TXB",
0075 sd->name);
0076
0077
0078
0079
0080
0081
0082
0083 if (is_afe_enabled(state)) {
0084 ret = adv748x_csi2_register_link(tx, sd->v4l2_dev,
0085 &state->afe.sd,
0086 ADV748X_AFE_SOURCE,
0087 is_txb(tx));
0088 if (ret)
0089 return ret;
0090
0091
0092 if (is_txb(tx))
0093 state->afe.tx = tx;
0094 }
0095
0096
0097 if (is_txb(tx) || !is_hdmi_enabled(state))
0098 return 0;
0099
0100 ret = adv748x_csi2_register_link(tx, sd->v4l2_dev, &state->hdmi.sd,
0101 ADV748X_HDMI_SOURCE, true);
0102 if (ret)
0103 return ret;
0104
0105
0106 state->hdmi.tx = tx;
0107
0108 return 0;
0109 }
0110
0111 static const struct v4l2_subdev_internal_ops adv748x_csi2_internal_ops = {
0112 .registered = adv748x_csi2_registered,
0113 };
0114
0115
0116
0117
0118
0119 static int adv748x_csi2_s_stream(struct v4l2_subdev *sd, int enable)
0120 {
0121 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
0122 struct v4l2_subdev *src;
0123
0124 src = adv748x_get_remote_sd(&tx->pads[ADV748X_CSI2_SINK]);
0125 if (!src)
0126 return -EPIPE;
0127
0128 return v4l2_subdev_call(src, video, s_stream, enable);
0129 }
0130
0131 static const struct v4l2_subdev_video_ops adv748x_csi2_video_ops = {
0132 .s_stream = adv748x_csi2_s_stream,
0133 };
0134
0135
0136
0137
0138
0139
0140
0141
0142 static struct v4l2_mbus_framefmt *
0143 adv748x_csi2_get_pad_format(struct v4l2_subdev *sd,
0144 struct v4l2_subdev_state *sd_state,
0145 unsigned int pad, u32 which)
0146 {
0147 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
0148
0149 if (which == V4L2_SUBDEV_FORMAT_TRY)
0150 return v4l2_subdev_get_try_format(sd, sd_state, pad);
0151
0152 return &tx->format;
0153 }
0154
0155 static int adv748x_csi2_get_format(struct v4l2_subdev *sd,
0156 struct v4l2_subdev_state *sd_state,
0157 struct v4l2_subdev_format *sdformat)
0158 {
0159 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
0160 struct adv748x_state *state = tx->state;
0161 struct v4l2_mbus_framefmt *mbusformat;
0162
0163 mbusformat = adv748x_csi2_get_pad_format(sd, sd_state, sdformat->pad,
0164 sdformat->which);
0165 if (!mbusformat)
0166 return -EINVAL;
0167
0168 mutex_lock(&state->mutex);
0169
0170 sdformat->format = *mbusformat;
0171
0172 mutex_unlock(&state->mutex);
0173
0174 return 0;
0175 }
0176
0177 static int adv748x_csi2_set_format(struct v4l2_subdev *sd,
0178 struct v4l2_subdev_state *sd_state,
0179 struct v4l2_subdev_format *sdformat)
0180 {
0181 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
0182 struct adv748x_state *state = tx->state;
0183 struct v4l2_mbus_framefmt *mbusformat;
0184 int ret = 0;
0185
0186 mbusformat = adv748x_csi2_get_pad_format(sd, sd_state, sdformat->pad,
0187 sdformat->which);
0188 if (!mbusformat)
0189 return -EINVAL;
0190
0191 mutex_lock(&state->mutex);
0192
0193 if (sdformat->pad == ADV748X_CSI2_SOURCE) {
0194 const struct v4l2_mbus_framefmt *sink_fmt;
0195
0196 sink_fmt = adv748x_csi2_get_pad_format(sd, sd_state,
0197 ADV748X_CSI2_SINK,
0198 sdformat->which);
0199
0200 if (!sink_fmt) {
0201 ret = -EINVAL;
0202 goto unlock;
0203 }
0204
0205 sdformat->format = *sink_fmt;
0206 }
0207
0208 *mbusformat = sdformat->format;
0209
0210 unlock:
0211 mutex_unlock(&state->mutex);
0212
0213 return ret;
0214 }
0215
0216 static int adv748x_csi2_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
0217 struct v4l2_mbus_config *config)
0218 {
0219 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
0220
0221 if (pad != ADV748X_CSI2_SOURCE)
0222 return -EINVAL;
0223
0224 config->type = V4L2_MBUS_CSI2_DPHY;
0225 config->bus.mipi_csi2.num_data_lanes = tx->active_lanes;
0226
0227 return 0;
0228 }
0229
0230 static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = {
0231 .get_fmt = adv748x_csi2_get_format,
0232 .set_fmt = adv748x_csi2_set_format,
0233 .get_mbus_config = adv748x_csi2_get_mbus_config,
0234 };
0235
0236
0237
0238
0239
0240 static const struct v4l2_subdev_ops adv748x_csi2_ops = {
0241 .video = &adv748x_csi2_video_ops,
0242 .pad = &adv748x_csi2_pad_ops,
0243 };
0244
0245
0246
0247
0248
0249 int adv748x_csi2_set_pixelrate(struct v4l2_subdev *sd, s64 rate)
0250 {
0251 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
0252
0253 if (!tx->pixel_rate)
0254 return -EINVAL;
0255
0256 return v4l2_ctrl_s_ctrl_int64(tx->pixel_rate, rate);
0257 }
0258
0259 static int adv748x_csi2_s_ctrl(struct v4l2_ctrl *ctrl)
0260 {
0261 switch (ctrl->id) {
0262 case V4L2_CID_PIXEL_RATE:
0263 return 0;
0264 default:
0265 return -EINVAL;
0266 }
0267 }
0268
0269 static const struct v4l2_ctrl_ops adv748x_csi2_ctrl_ops = {
0270 .s_ctrl = adv748x_csi2_s_ctrl,
0271 };
0272
0273 static int adv748x_csi2_init_controls(struct adv748x_csi2 *tx)
0274 {
0275
0276 v4l2_ctrl_handler_init(&tx->ctrl_hdl, 1);
0277
0278 tx->pixel_rate = v4l2_ctrl_new_std(&tx->ctrl_hdl,
0279 &adv748x_csi2_ctrl_ops,
0280 V4L2_CID_PIXEL_RATE, 1, INT_MAX,
0281 1, 1);
0282
0283 tx->sd.ctrl_handler = &tx->ctrl_hdl;
0284 if (tx->ctrl_hdl.error) {
0285 v4l2_ctrl_handler_free(&tx->ctrl_hdl);
0286 return tx->ctrl_hdl.error;
0287 }
0288
0289 return v4l2_ctrl_handler_setup(&tx->ctrl_hdl);
0290 }
0291
0292 int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx)
0293 {
0294 int ret;
0295
0296 if (!is_tx_enabled(tx))
0297 return 0;
0298
0299 adv748x_subdev_init(&tx->sd, state, &adv748x_csi2_ops,
0300 MEDIA_ENT_F_VID_IF_BRIDGE,
0301 is_txa(tx) ? "txa" : "txb");
0302
0303
0304 tx->sd.fwnode = of_fwnode_handle(state->endpoints[tx->port]);
0305
0306
0307 tx->sd.internal_ops = &adv748x_csi2_internal_ops;
0308
0309 tx->pads[ADV748X_CSI2_SINK].flags = MEDIA_PAD_FL_SINK;
0310 tx->pads[ADV748X_CSI2_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
0311
0312 ret = media_entity_pads_init(&tx->sd.entity, ADV748X_CSI2_NR_PADS,
0313 tx->pads);
0314 if (ret)
0315 return ret;
0316
0317 ret = adv748x_csi2_init_controls(tx);
0318 if (ret)
0319 goto err_free_media;
0320
0321 ret = v4l2_async_register_subdev(&tx->sd);
0322 if (ret)
0323 goto err_free_ctrl;
0324
0325 return 0;
0326
0327 err_free_ctrl:
0328 v4l2_ctrl_handler_free(&tx->ctrl_hdl);
0329 err_free_media:
0330 media_entity_cleanup(&tx->sd.entity);
0331
0332 return ret;
0333 }
0334
0335 void adv748x_csi2_cleanup(struct adv748x_csi2 *tx)
0336 {
0337 if (!is_tx_enabled(tx))
0338 return;
0339
0340 v4l2_async_unregister_subdev(&tx->sd);
0341 media_entity_cleanup(&tx->sd.entity);
0342 v4l2_ctrl_handler_free(&tx->ctrl_hdl);
0343 }