Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Driver for Analog Devices ADV748X 8 channel analog front end (AFE) receiver
0004  * with standard definition processor (SDP)
0005  *
0006  * Copyright (C) 2017 Renesas Electronics Corp.
0007  */
0008 
0009 #include <linux/delay.h>
0010 #include <linux/module.h>
0011 #include <linux/mutex.h>
0012 #include <linux/v4l2-dv-timings.h>
0013 
0014 #include <media/v4l2-ctrls.h>
0015 #include <media/v4l2-device.h>
0016 #include <media/v4l2-dv-timings.h>
0017 #include <media/v4l2-ioctl.h>
0018 
0019 #include "adv748x.h"
0020 
0021 /* -----------------------------------------------------------------------------
0022  * SDP
0023  */
0024 
0025 #define ADV748X_AFE_STD_AD_PAL_BG_NTSC_J_SECAM      0x0
0026 #define ADV748X_AFE_STD_AD_PAL_BG_NTSC_J_SECAM_PED  0x1
0027 #define ADV748X_AFE_STD_AD_PAL_N_NTSC_J_SECAM       0x2
0028 #define ADV748X_AFE_STD_AD_PAL_N_NTSC_M_SECAM       0x3
0029 #define ADV748X_AFE_STD_NTSC_J              0x4
0030 #define ADV748X_AFE_STD_NTSC_M              0x5
0031 #define ADV748X_AFE_STD_PAL60               0x6
0032 #define ADV748X_AFE_STD_NTSC_443            0x7
0033 #define ADV748X_AFE_STD_PAL_BG              0x8
0034 #define ADV748X_AFE_STD_PAL_N               0x9
0035 #define ADV748X_AFE_STD_PAL_M               0xa
0036 #define ADV748X_AFE_STD_PAL_M_PED           0xb
0037 #define ADV748X_AFE_STD_PAL_COMB_N          0xc
0038 #define ADV748X_AFE_STD_PAL_COMB_N_PED          0xd
0039 #define ADV748X_AFE_STD_PAL_SECAM           0xe
0040 #define ADV748X_AFE_STD_PAL_SECAM_PED           0xf
0041 
0042 static int adv748x_afe_read_ro_map(struct adv748x_state *state, u8 reg)
0043 {
0044     int ret;
0045 
0046     /* Select SDP Read-Only Main Map */
0047     ret = sdp_write(state, ADV748X_SDP_MAP_SEL,
0048             ADV748X_SDP_MAP_SEL_RO_MAIN);
0049     if (ret < 0)
0050         return ret;
0051 
0052     return sdp_read(state, reg);
0053 }
0054 
0055 static int adv748x_afe_status(struct adv748x_afe *afe, u32 *signal,
0056                   v4l2_std_id *std)
0057 {
0058     struct adv748x_state *state = adv748x_afe_to_state(afe);
0059     int info;
0060 
0061     /* Read status from reg 0x10 of SDP RO Map */
0062     info = adv748x_afe_read_ro_map(state, ADV748X_SDP_RO_10);
0063     if (info < 0)
0064         return info;
0065 
0066     if (signal)
0067         *signal = info & ADV748X_SDP_RO_10_IN_LOCK ?
0068                 0 : V4L2_IN_ST_NO_SIGNAL;
0069 
0070     if (!std)
0071         return 0;
0072 
0073     /* Standard not valid if there is no signal */
0074     if (!(info & ADV748X_SDP_RO_10_IN_LOCK)) {
0075         *std = V4L2_STD_UNKNOWN;
0076         return 0;
0077     }
0078 
0079     switch (info & 0x70) {
0080     case 0x00:
0081         *std = V4L2_STD_NTSC;
0082         break;
0083     case 0x10:
0084         *std = V4L2_STD_NTSC_443;
0085         break;
0086     case 0x20:
0087         *std = V4L2_STD_PAL_M;
0088         break;
0089     case 0x30:
0090         *std = V4L2_STD_PAL_60;
0091         break;
0092     case 0x40:
0093         *std = V4L2_STD_PAL;
0094         break;
0095     case 0x50:
0096         *std = V4L2_STD_SECAM;
0097         break;
0098     case 0x60:
0099         *std = V4L2_STD_PAL_Nc | V4L2_STD_PAL_N;
0100         break;
0101     case 0x70:
0102         *std = V4L2_STD_SECAM;
0103         break;
0104     default:
0105         *std = V4L2_STD_UNKNOWN;
0106         break;
0107     }
0108 
0109     return 0;
0110 }
0111 
0112 static void adv748x_afe_fill_format(struct adv748x_afe *afe,
0113                     struct v4l2_mbus_framefmt *fmt)
0114 {
0115     memset(fmt, 0, sizeof(*fmt));
0116 
0117     fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
0118     fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
0119     fmt->field = V4L2_FIELD_ALTERNATE;
0120 
0121     fmt->width = 720;
0122     fmt->height = afe->curr_norm & V4L2_STD_525_60 ? 480 : 576;
0123 
0124     /* Field height */
0125     fmt->height /= 2;
0126 }
0127 
0128 static int adv748x_afe_std(v4l2_std_id std)
0129 {
0130     if (std == V4L2_STD_PAL_60)
0131         return ADV748X_AFE_STD_PAL60;
0132     if (std == V4L2_STD_NTSC_443)
0133         return ADV748X_AFE_STD_NTSC_443;
0134     if (std == V4L2_STD_PAL_N)
0135         return ADV748X_AFE_STD_PAL_N;
0136     if (std == V4L2_STD_PAL_M)
0137         return ADV748X_AFE_STD_PAL_M;
0138     if (std == V4L2_STD_PAL_Nc)
0139         return ADV748X_AFE_STD_PAL_COMB_N;
0140     if (std & V4L2_STD_NTSC)
0141         return ADV748X_AFE_STD_NTSC_M;
0142     if (std & V4L2_STD_PAL)
0143         return ADV748X_AFE_STD_PAL_BG;
0144     if (std & V4L2_STD_SECAM)
0145         return ADV748X_AFE_STD_PAL_SECAM;
0146 
0147     return -EINVAL;
0148 }
0149 
0150 static void adv748x_afe_set_video_standard(struct adv748x_state *state,
0151                       int sdpstd)
0152 {
0153     sdp_clrset(state, ADV748X_SDP_VID_SEL, ADV748X_SDP_VID_SEL_MASK,
0154            (sdpstd & 0xf) << ADV748X_SDP_VID_SEL_SHIFT);
0155 }
0156 
0157 int adv748x_afe_s_input(struct adv748x_afe *afe, unsigned int input)
0158 {
0159     struct adv748x_state *state = adv748x_afe_to_state(afe);
0160 
0161     return sdp_write(state, ADV748X_SDP_INSEL, input);
0162 }
0163 
0164 static int adv748x_afe_g_pixelaspect(struct v4l2_subdev *sd,
0165                      struct v4l2_fract *aspect)
0166 {
0167     struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
0168 
0169     if (afe->curr_norm & V4L2_STD_525_60) {
0170         aspect->numerator = 11;
0171         aspect->denominator = 10;
0172     } else {
0173         aspect->numerator = 54;
0174         aspect->denominator = 59;
0175     }
0176 
0177     return 0;
0178 }
0179 
0180 /* -----------------------------------------------------------------------------
0181  * v4l2_subdev_video_ops
0182  */
0183 
0184 static int adv748x_afe_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
0185 {
0186     struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
0187 
0188     *norm = afe->curr_norm;
0189 
0190     return 0;
0191 }
0192 
0193 static int adv748x_afe_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
0194 {
0195     struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
0196     struct adv748x_state *state = adv748x_afe_to_state(afe);
0197     int afe_std = adv748x_afe_std(std);
0198 
0199     if (afe_std < 0)
0200         return afe_std;
0201 
0202     mutex_lock(&state->mutex);
0203 
0204     adv748x_afe_set_video_standard(state, afe_std);
0205     afe->curr_norm = std;
0206 
0207     mutex_unlock(&state->mutex);
0208 
0209     return 0;
0210 }
0211 
0212 static int adv748x_afe_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
0213 {
0214     struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
0215     struct adv748x_state *state = adv748x_afe_to_state(afe);
0216     int afe_std;
0217     int ret;
0218 
0219     mutex_lock(&state->mutex);
0220 
0221     if (afe->streaming) {
0222         ret = -EBUSY;
0223         goto unlock;
0224     }
0225 
0226     /* Set auto detect mode */
0227     adv748x_afe_set_video_standard(state,
0228                        ADV748X_AFE_STD_AD_PAL_BG_NTSC_J_SECAM);
0229 
0230     msleep(100);
0231 
0232     /* Read detected standard */
0233     ret = adv748x_afe_status(afe, NULL, std);
0234 
0235     afe_std = adv748x_afe_std(afe->curr_norm);
0236     if (afe_std < 0)
0237         goto unlock;
0238 
0239     /* Restore original state */
0240     adv748x_afe_set_video_standard(state, afe_std);
0241 
0242 unlock:
0243     mutex_unlock(&state->mutex);
0244 
0245     return ret;
0246 }
0247 
0248 static int adv748x_afe_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm)
0249 {
0250     *norm = V4L2_STD_ALL;
0251 
0252     return 0;
0253 }
0254 
0255 static int adv748x_afe_g_input_status(struct v4l2_subdev *sd, u32 *status)
0256 {
0257     struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
0258     struct adv748x_state *state = adv748x_afe_to_state(afe);
0259     int ret;
0260 
0261     mutex_lock(&state->mutex);
0262 
0263     ret = adv748x_afe_status(afe, status, NULL);
0264 
0265     mutex_unlock(&state->mutex);
0266 
0267     return ret;
0268 }
0269 
0270 static int adv748x_afe_s_stream(struct v4l2_subdev *sd, int enable)
0271 {
0272     struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
0273     struct adv748x_state *state = adv748x_afe_to_state(afe);
0274     u32 signal = V4L2_IN_ST_NO_SIGNAL;
0275     int ret;
0276 
0277     mutex_lock(&state->mutex);
0278 
0279     if (enable) {
0280         ret = adv748x_afe_s_input(afe, afe->input);
0281         if (ret)
0282             goto unlock;
0283     }
0284 
0285     ret = adv748x_tx_power(afe->tx, enable);
0286     if (ret)
0287         goto unlock;
0288 
0289     afe->streaming = enable;
0290 
0291     adv748x_afe_status(afe, &signal, NULL);
0292     if (signal != V4L2_IN_ST_NO_SIGNAL)
0293         adv_dbg(state, "Detected SDP signal\n");
0294     else
0295         adv_dbg(state, "Couldn't detect SDP video signal\n");
0296 
0297 unlock:
0298     mutex_unlock(&state->mutex);
0299 
0300     return ret;
0301 }
0302 
0303 static const struct v4l2_subdev_video_ops adv748x_afe_video_ops = {
0304     .g_std = adv748x_afe_g_std,
0305     .s_std = adv748x_afe_s_std,
0306     .querystd = adv748x_afe_querystd,
0307     .g_tvnorms = adv748x_afe_g_tvnorms,
0308     .g_input_status = adv748x_afe_g_input_status,
0309     .s_stream = adv748x_afe_s_stream,
0310     .g_pixelaspect = adv748x_afe_g_pixelaspect,
0311 };
0312 
0313 /* -----------------------------------------------------------------------------
0314  * v4l2_subdev_pad_ops
0315  */
0316 
0317 static int adv748x_afe_propagate_pixelrate(struct adv748x_afe *afe)
0318 {
0319     struct v4l2_subdev *tx;
0320 
0321     tx = adv748x_get_remote_sd(&afe->pads[ADV748X_AFE_SOURCE]);
0322     if (!tx)
0323         return -ENOLINK;
0324 
0325     /*
0326      * The ADV748x ADC sampling frequency is twice the externally supplied
0327      * clock whose frequency is required to be 28.63636 MHz. It oversamples
0328      * with a factor of 4 resulting in a pixel rate of 14.3180180 MHz.
0329      */
0330     return adv748x_csi2_set_pixelrate(tx, 14318180);
0331 }
0332 
0333 static int adv748x_afe_enum_mbus_code(struct v4l2_subdev *sd,
0334                       struct v4l2_subdev_state *sd_state,
0335                       struct v4l2_subdev_mbus_code_enum *code)
0336 {
0337     if (code->index != 0)
0338         return -EINVAL;
0339 
0340     code->code = MEDIA_BUS_FMT_UYVY8_2X8;
0341 
0342     return 0;
0343 }
0344 
0345 static int adv748x_afe_get_format(struct v4l2_subdev *sd,
0346                       struct v4l2_subdev_state *sd_state,
0347                       struct v4l2_subdev_format *sdformat)
0348 {
0349     struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
0350     struct v4l2_mbus_framefmt *mbusformat;
0351 
0352     /* It makes no sense to get the format of the analog sink pads */
0353     if (sdformat->pad != ADV748X_AFE_SOURCE)
0354         return -EINVAL;
0355 
0356     if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) {
0357         mbusformat = v4l2_subdev_get_try_format(sd, sd_state,
0358                             sdformat->pad);
0359         sdformat->format = *mbusformat;
0360     } else {
0361         adv748x_afe_fill_format(afe, &sdformat->format);
0362         adv748x_afe_propagate_pixelrate(afe);
0363     }
0364 
0365     return 0;
0366 }
0367 
0368 static int adv748x_afe_set_format(struct v4l2_subdev *sd,
0369                       struct v4l2_subdev_state *sd_state,
0370                       struct v4l2_subdev_format *sdformat)
0371 {
0372     struct v4l2_mbus_framefmt *mbusformat;
0373 
0374     /* It makes no sense to get the format of the analog sink pads */
0375     if (sdformat->pad != ADV748X_AFE_SOURCE)
0376         return -EINVAL;
0377 
0378     if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
0379         return adv748x_afe_get_format(sd, sd_state, sdformat);
0380 
0381     mbusformat = v4l2_subdev_get_try_format(sd, sd_state, sdformat->pad);
0382     *mbusformat = sdformat->format;
0383 
0384     return 0;
0385 }
0386 
0387 static const struct v4l2_subdev_pad_ops adv748x_afe_pad_ops = {
0388     .enum_mbus_code = adv748x_afe_enum_mbus_code,
0389     .set_fmt = adv748x_afe_set_format,
0390     .get_fmt = adv748x_afe_get_format,
0391 };
0392 
0393 /* -----------------------------------------------------------------------------
0394  * v4l2_subdev_ops
0395  */
0396 
0397 static const struct v4l2_subdev_ops adv748x_afe_ops = {
0398     .video = &adv748x_afe_video_ops,
0399     .pad = &adv748x_afe_pad_ops,
0400 };
0401 
0402 /* -----------------------------------------------------------------------------
0403  * Controls
0404  */
0405 
0406 static const char * const afe_ctrl_frp_menu[] = {
0407     "Disabled",
0408     "Solid Blue",
0409     "Color Bars",
0410     "Grey Ramp",
0411     "Cb Ramp",
0412     "Cr Ramp",
0413     "Boundary"
0414 };
0415 
0416 static int adv748x_afe_s_ctrl(struct v4l2_ctrl *ctrl)
0417 {
0418     struct adv748x_afe *afe = adv748x_ctrl_to_afe(ctrl);
0419     struct adv748x_state *state = adv748x_afe_to_state(afe);
0420     bool enable;
0421     int ret;
0422 
0423     ret = sdp_write(state, 0x0e, 0x00);
0424     if (ret < 0)
0425         return ret;
0426 
0427     switch (ctrl->id) {
0428     case V4L2_CID_BRIGHTNESS:
0429         ret = sdp_write(state, ADV748X_SDP_BRI, ctrl->val);
0430         break;
0431     case V4L2_CID_HUE:
0432         /* Hue is inverted according to HSL chart */
0433         ret = sdp_write(state, ADV748X_SDP_HUE, -ctrl->val);
0434         break;
0435     case V4L2_CID_CONTRAST:
0436         ret = sdp_write(state, ADV748X_SDP_CON, ctrl->val);
0437         break;
0438     case V4L2_CID_SATURATION:
0439         ret = sdp_write(state, ADV748X_SDP_SD_SAT_U, ctrl->val);
0440         if (ret)
0441             break;
0442         ret = sdp_write(state, ADV748X_SDP_SD_SAT_V, ctrl->val);
0443         break;
0444     case V4L2_CID_TEST_PATTERN:
0445         enable = !!ctrl->val;
0446 
0447         /* Enable/Disable Color bar test patterns */
0448         ret = sdp_clrset(state, ADV748X_SDP_DEF, ADV748X_SDP_DEF_VAL_EN,
0449                 enable);
0450         if (ret)
0451             break;
0452         ret = sdp_clrset(state, ADV748X_SDP_FRP, ADV748X_SDP_FRP_MASK,
0453                 enable ? ctrl->val - 1 : 0);
0454         break;
0455     default:
0456         return -EINVAL;
0457     }
0458 
0459     return ret;
0460 }
0461 
0462 static const struct v4l2_ctrl_ops adv748x_afe_ctrl_ops = {
0463     .s_ctrl = adv748x_afe_s_ctrl,
0464 };
0465 
0466 static int adv748x_afe_init_controls(struct adv748x_afe *afe)
0467 {
0468     struct adv748x_state *state = adv748x_afe_to_state(afe);
0469 
0470     v4l2_ctrl_handler_init(&afe->ctrl_hdl, 5);
0471 
0472     /* Use our mutex for the controls */
0473     afe->ctrl_hdl.lock = &state->mutex;
0474 
0475     v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops,
0476               V4L2_CID_BRIGHTNESS, ADV748X_SDP_BRI_MIN,
0477               ADV748X_SDP_BRI_MAX, 1, ADV748X_SDP_BRI_DEF);
0478     v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops,
0479               V4L2_CID_CONTRAST, ADV748X_SDP_CON_MIN,
0480               ADV748X_SDP_CON_MAX, 1, ADV748X_SDP_CON_DEF);
0481     v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops,
0482               V4L2_CID_SATURATION, ADV748X_SDP_SAT_MIN,
0483               ADV748X_SDP_SAT_MAX, 1, ADV748X_SDP_SAT_DEF);
0484     v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops,
0485               V4L2_CID_HUE, ADV748X_SDP_HUE_MIN,
0486               ADV748X_SDP_HUE_MAX, 1, ADV748X_SDP_HUE_DEF);
0487 
0488     v4l2_ctrl_new_std_menu_items(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops,
0489                      V4L2_CID_TEST_PATTERN,
0490                      ARRAY_SIZE(afe_ctrl_frp_menu) - 1,
0491                      0, 0, afe_ctrl_frp_menu);
0492 
0493     afe->sd.ctrl_handler = &afe->ctrl_hdl;
0494     if (afe->ctrl_hdl.error) {
0495         v4l2_ctrl_handler_free(&afe->ctrl_hdl);
0496         return afe->ctrl_hdl.error;
0497     }
0498 
0499     return v4l2_ctrl_handler_setup(&afe->ctrl_hdl);
0500 }
0501 
0502 int adv748x_afe_init(struct adv748x_afe *afe)
0503 {
0504     struct adv748x_state *state = adv748x_afe_to_state(afe);
0505     int ret;
0506     unsigned int i;
0507 
0508     afe->input = 0;
0509     afe->streaming = false;
0510     afe->curr_norm = V4L2_STD_NTSC_M;
0511 
0512     adv748x_subdev_init(&afe->sd, state, &adv748x_afe_ops,
0513                 MEDIA_ENT_F_ATV_DECODER, "afe");
0514 
0515     /* Identify the first connector found as a default input if set */
0516     for (i = ADV748X_PORT_AIN0; i <= ADV748X_PORT_AIN7; i++) {
0517         /* Inputs and ports are 1-indexed to match the data sheet */
0518         if (state->endpoints[i]) {
0519             afe->input = i;
0520             break;
0521         }
0522     }
0523 
0524     /* Entity pads and sinks are 0-indexed to match the pads */
0525     for (i = ADV748X_AFE_SINK_AIN0; i <= ADV748X_AFE_SINK_AIN7; i++)
0526         afe->pads[i].flags = MEDIA_PAD_FL_SINK;
0527 
0528     afe->pads[ADV748X_AFE_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
0529 
0530     ret = media_entity_pads_init(&afe->sd.entity, ADV748X_AFE_NR_PADS,
0531             afe->pads);
0532     if (ret)
0533         return ret;
0534 
0535     ret = adv748x_afe_init_controls(afe);
0536     if (ret)
0537         goto error;
0538 
0539     return 0;
0540 
0541 error:
0542     media_entity_cleanup(&afe->sd.entity);
0543 
0544     return ret;
0545 }
0546 
0547 void adv748x_afe_cleanup(struct adv748x_afe *afe)
0548 {
0549     v4l2_device_unregister_subdev(&afe->sd);
0550     media_entity_cleanup(&afe->sd.entity);
0551     v4l2_ctrl_handler_free(&afe->ctrl_hdl);
0552 }