0001
0002
0003
0004
0005
0006
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
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
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
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
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
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
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
0227 adv748x_afe_set_video_standard(state,
0228 ADV748X_AFE_STD_AD_PAL_BG_NTSC_J_SECAM);
0229
0230 msleep(100);
0231
0232
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
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
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
0327
0328
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
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
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
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
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
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
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
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
0516 for (i = ADV748X_PORT_AIN0; i <= ADV748X_PORT_AIN7; i++) {
0517
0518 if (state->endpoints[i]) {
0519 afe->input = i;
0520 break;
0521 }
0522 }
0523
0524
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 }