1 /* 2 * Driver for Analog Devices ADV748X 8 channel analog front end (AFE) receiver 3 * with standard definition processor (SDP) 4 * 5 * Copyright (C) 2017 Renesas Electronics Corp. 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2 of the License, or (at your 10 * option) any later version. 11 */ 12 13 #include <linux/delay.h> 14 #include <linux/module.h> 15 #include <linux/mutex.h> 16 #include <linux/v4l2-dv-timings.h> 17 18 #include <media/v4l2-ctrls.h> 19 #include <media/v4l2-device.h> 20 #include <media/v4l2-dv-timings.h> 21 #include <media/v4l2-ioctl.h> 22 23 #include "adv748x.h" 24 25 /* ----------------------------------------------------------------------------- 26 * SDP 27 */ 28 29 #define ADV748X_AFE_STD_AD_PAL_BG_NTSC_J_SECAM 0x0 30 #define ADV748X_AFE_STD_AD_PAL_BG_NTSC_J_SECAM_PED 0x1 31 #define ADV748X_AFE_STD_AD_PAL_N_NTSC_J_SECAM 0x2 32 #define ADV748X_AFE_STD_AD_PAL_N_NTSC_M_SECAM 0x3 33 #define ADV748X_AFE_STD_NTSC_J 0x4 34 #define ADV748X_AFE_STD_NTSC_M 0x5 35 #define ADV748X_AFE_STD_PAL60 0x6 36 #define ADV748X_AFE_STD_NTSC_443 0x7 37 #define ADV748X_AFE_STD_PAL_BG 0x8 38 #define ADV748X_AFE_STD_PAL_N 0x9 39 #define ADV748X_AFE_STD_PAL_M 0xa 40 #define ADV748X_AFE_STD_PAL_M_PED 0xb 41 #define ADV748X_AFE_STD_PAL_COMB_N 0xc 42 #define ADV748X_AFE_STD_PAL_COMB_N_PED 0xd 43 #define ADV748X_AFE_STD_PAL_SECAM 0xe 44 #define ADV748X_AFE_STD_PAL_SECAM_PED 0xf 45 46 static int adv748x_afe_read_ro_map(struct adv748x_state *state, u8 reg) 47 { 48 int ret; 49 50 /* Select SDP Read-Only Main Map */ 51 ret = sdp_write(state, ADV748X_SDP_MAP_SEL, 52 ADV748X_SDP_MAP_SEL_RO_MAIN); 53 if (ret < 0) 54 return ret; 55 56 return sdp_read(state, reg); 57 } 58 59 static int adv748x_afe_status(struct adv748x_afe *afe, u32 *signal, 60 v4l2_std_id *std) 61 { 62 struct adv748x_state *state = adv748x_afe_to_state(afe); 63 int info; 64 65 /* Read status from reg 0x10 of SDP RO Map */ 66 info = adv748x_afe_read_ro_map(state, ADV748X_SDP_RO_10); 67 if (info < 0) 68 return info; 69 70 if (signal) 71 *signal = info & ADV748X_SDP_RO_10_IN_LOCK ? 72 0 : V4L2_IN_ST_NO_SIGNAL; 73 74 if (!std) 75 return 0; 76 77 /* Standard not valid if there is no signal */ 78 if (!(info & ADV748X_SDP_RO_10_IN_LOCK)) { 79 *std = V4L2_STD_UNKNOWN; 80 return 0; 81 } 82 83 switch (info & 0x70) { 84 case 0x00: 85 *std = V4L2_STD_NTSC; 86 break; 87 case 0x10: 88 *std = V4L2_STD_NTSC_443; 89 break; 90 case 0x20: 91 *std = V4L2_STD_PAL_M; 92 break; 93 case 0x30: 94 *std = V4L2_STD_PAL_60; 95 break; 96 case 0x40: 97 *std = V4L2_STD_PAL; 98 break; 99 case 0x50: 100 *std = V4L2_STD_SECAM; 101 break; 102 case 0x60: 103 *std = V4L2_STD_PAL_Nc | V4L2_STD_PAL_N; 104 break; 105 case 0x70: 106 *std = V4L2_STD_SECAM; 107 break; 108 default: 109 *std = V4L2_STD_UNKNOWN; 110 break; 111 } 112 113 return 0; 114 } 115 116 static void adv748x_afe_fill_format(struct adv748x_afe *afe, 117 struct v4l2_mbus_framefmt *fmt) 118 { 119 memset(fmt, 0, sizeof(*fmt)); 120 121 fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; 122 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; 123 fmt->field = V4L2_FIELD_ALTERNATE; 124 125 fmt->width = 720; 126 fmt->height = afe->curr_norm & V4L2_STD_525_60 ? 480 : 576; 127 128 /* Field height */ 129 fmt->height /= 2; 130 } 131 132 static int adv748x_afe_std(v4l2_std_id std) 133 { 134 if (std == V4L2_STD_PAL_60) 135 return ADV748X_AFE_STD_PAL60; 136 if (std == V4L2_STD_NTSC_443) 137 return ADV748X_AFE_STD_NTSC_443; 138 if (std == V4L2_STD_PAL_N) 139 return ADV748X_AFE_STD_PAL_N; 140 if (std == V4L2_STD_PAL_M) 141 return ADV748X_AFE_STD_PAL_M; 142 if (std == V4L2_STD_PAL_Nc) 143 return ADV748X_AFE_STD_PAL_COMB_N; 144 if (std & V4L2_STD_NTSC) 145 return ADV748X_AFE_STD_NTSC_M; 146 if (std & V4L2_STD_PAL) 147 return ADV748X_AFE_STD_PAL_BG; 148 if (std & V4L2_STD_SECAM) 149 return ADV748X_AFE_STD_PAL_SECAM; 150 151 return -EINVAL; 152 } 153 154 static void adv748x_afe_set_video_standard(struct adv748x_state *state, 155 int sdpstd) 156 { 157 sdp_clrset(state, ADV748X_SDP_VID_SEL, ADV748X_SDP_VID_SEL_MASK, 158 (sdpstd & 0xf) << ADV748X_SDP_VID_SEL_SHIFT); 159 } 160 161 static int adv748x_afe_s_input(struct adv748x_afe *afe, unsigned int input) 162 { 163 struct adv748x_state *state = adv748x_afe_to_state(afe); 164 165 return sdp_write(state, ADV748X_SDP_INSEL, input); 166 } 167 168 static int adv748x_afe_g_pixelaspect(struct v4l2_subdev *sd, 169 struct v4l2_fract *aspect) 170 { 171 struct adv748x_afe *afe = adv748x_sd_to_afe(sd); 172 173 if (afe->curr_norm & V4L2_STD_525_60) { 174 aspect->numerator = 11; 175 aspect->denominator = 10; 176 } else { 177 aspect->numerator = 54; 178 aspect->denominator = 59; 179 } 180 181 return 0; 182 } 183 184 /* ----------------------------------------------------------------------------- 185 * v4l2_subdev_video_ops 186 */ 187 188 static int adv748x_afe_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm) 189 { 190 struct adv748x_afe *afe = adv748x_sd_to_afe(sd); 191 192 *norm = afe->curr_norm; 193 194 return 0; 195 } 196 197 static int adv748x_afe_s_std(struct v4l2_subdev *sd, v4l2_std_id std) 198 { 199 struct adv748x_afe *afe = adv748x_sd_to_afe(sd); 200 struct adv748x_state *state = adv748x_afe_to_state(afe); 201 int afe_std = adv748x_afe_std(std); 202 203 if (afe_std < 0) 204 return afe_std; 205 206 mutex_lock(&state->mutex); 207 208 adv748x_afe_set_video_standard(state, afe_std); 209 afe->curr_norm = std; 210 211 mutex_unlock(&state->mutex); 212 213 return 0; 214 } 215 216 static int adv748x_afe_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) 217 { 218 struct adv748x_afe *afe = adv748x_sd_to_afe(sd); 219 struct adv748x_state *state = adv748x_afe_to_state(afe); 220 int afe_std; 221 int ret; 222 223 mutex_lock(&state->mutex); 224 225 if (afe->streaming) { 226 ret = -EBUSY; 227 goto unlock; 228 } 229 230 /* Set auto detect mode */ 231 adv748x_afe_set_video_standard(state, 232 ADV748X_AFE_STD_AD_PAL_BG_NTSC_J_SECAM); 233 234 msleep(100); 235 236 /* Read detected standard */ 237 ret = adv748x_afe_status(afe, NULL, std); 238 239 afe_std = adv748x_afe_std(afe->curr_norm); 240 if (afe_std < 0) 241 goto unlock; 242 243 /* Restore original state */ 244 adv748x_afe_set_video_standard(state, afe_std); 245 246 unlock: 247 mutex_unlock(&state->mutex); 248 249 return ret; 250 } 251 252 static int adv748x_afe_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm) 253 { 254 *norm = V4L2_STD_ALL; 255 256 return 0; 257 } 258 259 static int adv748x_afe_g_input_status(struct v4l2_subdev *sd, u32 *status) 260 { 261 struct adv748x_afe *afe = adv748x_sd_to_afe(sd); 262 struct adv748x_state *state = adv748x_afe_to_state(afe); 263 int ret; 264 265 mutex_lock(&state->mutex); 266 267 ret = adv748x_afe_status(afe, status, NULL); 268 269 mutex_unlock(&state->mutex); 270 271 return ret; 272 } 273 274 static int adv748x_afe_s_stream(struct v4l2_subdev *sd, int enable) 275 { 276 struct adv748x_afe *afe = adv748x_sd_to_afe(sd); 277 struct adv748x_state *state = adv748x_afe_to_state(afe); 278 u32 signal = V4L2_IN_ST_NO_SIGNAL; 279 int ret; 280 281 mutex_lock(&state->mutex); 282 283 if (enable) { 284 ret = adv748x_afe_s_input(afe, afe->input); 285 if (ret) 286 goto unlock; 287 } 288 289 ret = adv748x_txb_power(state, enable); 290 if (ret) 291 goto unlock; 292 293 afe->streaming = enable; 294 295 adv748x_afe_status(afe, &signal, NULL); 296 if (signal != V4L2_IN_ST_NO_SIGNAL) 297 adv_dbg(state, "Detected SDP signal\n"); 298 else 299 adv_dbg(state, "Couldn't detect SDP video signal\n"); 300 301 unlock: 302 mutex_unlock(&state->mutex); 303 304 return ret; 305 } 306 307 static const struct v4l2_subdev_video_ops adv748x_afe_video_ops = { 308 .g_std = adv748x_afe_g_std, 309 .s_std = adv748x_afe_s_std, 310 .querystd = adv748x_afe_querystd, 311 .g_tvnorms = adv748x_afe_g_tvnorms, 312 .g_input_status = adv748x_afe_g_input_status, 313 .s_stream = adv748x_afe_s_stream, 314 .g_pixelaspect = adv748x_afe_g_pixelaspect, 315 }; 316 317 /* ----------------------------------------------------------------------------- 318 * v4l2_subdev_pad_ops 319 */ 320 321 static int adv748x_afe_propagate_pixelrate(struct adv748x_afe *afe) 322 { 323 struct v4l2_subdev *tx; 324 325 tx = adv748x_get_remote_sd(&afe->pads[ADV748X_AFE_SOURCE]); 326 if (!tx) 327 return -ENOLINK; 328 329 /* 330 * The ADV748x ADC sampling frequency is twice the externally supplied 331 * clock whose frequency is required to be 28.63636 MHz. It oversamples 332 * with a factor of 4 resulting in a pixel rate of 14.3180180 MHz. 333 */ 334 return adv748x_csi2_set_pixelrate(tx, 14318180); 335 } 336 337 static int adv748x_afe_enum_mbus_code(struct v4l2_subdev *sd, 338 struct v4l2_subdev_pad_config *cfg, 339 struct v4l2_subdev_mbus_code_enum *code) 340 { 341 if (code->index != 0) 342 return -EINVAL; 343 344 code->code = MEDIA_BUS_FMT_UYVY8_2X8; 345 346 return 0; 347 } 348 349 static int adv748x_afe_get_format(struct v4l2_subdev *sd, 350 struct v4l2_subdev_pad_config *cfg, 351 struct v4l2_subdev_format *sdformat) 352 { 353 struct adv748x_afe *afe = adv748x_sd_to_afe(sd); 354 struct v4l2_mbus_framefmt *mbusformat; 355 356 /* It makes no sense to get the format of the analog sink pads */ 357 if (sdformat->pad != ADV748X_AFE_SOURCE) 358 return -EINVAL; 359 360 if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) { 361 mbusformat = v4l2_subdev_get_try_format(sd, cfg, sdformat->pad); 362 sdformat->format = *mbusformat; 363 } else { 364 adv748x_afe_fill_format(afe, &sdformat->format); 365 adv748x_afe_propagate_pixelrate(afe); 366 } 367 368 return 0; 369 } 370 371 static int adv748x_afe_set_format(struct v4l2_subdev *sd, 372 struct v4l2_subdev_pad_config *cfg, 373 struct v4l2_subdev_format *sdformat) 374 { 375 struct v4l2_mbus_framefmt *mbusformat; 376 377 /* It makes no sense to get the format of the analog sink pads */ 378 if (sdformat->pad != ADV748X_AFE_SOURCE) 379 return -EINVAL; 380 381 if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) 382 return adv748x_afe_get_format(sd, cfg, sdformat); 383 384 mbusformat = v4l2_subdev_get_try_format(sd, cfg, sdformat->pad); 385 *mbusformat = sdformat->format; 386 387 return 0; 388 } 389 390 static const struct v4l2_subdev_pad_ops adv748x_afe_pad_ops = { 391 .enum_mbus_code = adv748x_afe_enum_mbus_code, 392 .set_fmt = adv748x_afe_set_format, 393 .get_fmt = adv748x_afe_get_format, 394 }; 395 396 /* ----------------------------------------------------------------------------- 397 * v4l2_subdev_ops 398 */ 399 400 static const struct v4l2_subdev_ops adv748x_afe_ops = { 401 .video = &adv748x_afe_video_ops, 402 .pad = &adv748x_afe_pad_ops, 403 }; 404 405 /* ----------------------------------------------------------------------------- 406 * Controls 407 */ 408 409 static const char * const afe_ctrl_frp_menu[] = { 410 "Disabled", 411 "Solid Blue", 412 "Color Bars", 413 "Grey Ramp", 414 "Cb Ramp", 415 "Cr Ramp", 416 "Boundary" 417 }; 418 419 static int adv748x_afe_s_ctrl(struct v4l2_ctrl *ctrl) 420 { 421 struct adv748x_afe *afe = adv748x_ctrl_to_afe(ctrl); 422 struct adv748x_state *state = adv748x_afe_to_state(afe); 423 bool enable; 424 int ret; 425 426 ret = sdp_write(state, 0x0e, 0x00); 427 if (ret < 0) 428 return ret; 429 430 switch (ctrl->id) { 431 case V4L2_CID_BRIGHTNESS: 432 ret = sdp_write(state, ADV748X_SDP_BRI, ctrl->val); 433 break; 434 case V4L2_CID_HUE: 435 /* Hue is inverted according to HSL chart */ 436 ret = sdp_write(state, ADV748X_SDP_HUE, -ctrl->val); 437 break; 438 case V4L2_CID_CONTRAST: 439 ret = sdp_write(state, ADV748X_SDP_CON, ctrl->val); 440 break; 441 case V4L2_CID_SATURATION: 442 ret = sdp_write(state, ADV748X_SDP_SD_SAT_U, ctrl->val); 443 if (ret) 444 break; 445 ret = sdp_write(state, ADV748X_SDP_SD_SAT_V, ctrl->val); 446 break; 447 case V4L2_CID_TEST_PATTERN: 448 enable = !!ctrl->val; 449 450 /* Enable/Disable Color bar test patterns */ 451 ret = sdp_clrset(state, ADV748X_SDP_DEF, ADV748X_SDP_DEF_VAL_EN, 452 enable); 453 if (ret) 454 break; 455 ret = sdp_clrset(state, ADV748X_SDP_FRP, ADV748X_SDP_FRP_MASK, 456 enable ? ctrl->val - 1 : 0); 457 break; 458 default: 459 return -EINVAL; 460 } 461 462 return ret; 463 } 464 465 static const struct v4l2_ctrl_ops adv748x_afe_ctrl_ops = { 466 .s_ctrl = adv748x_afe_s_ctrl, 467 }; 468 469 static int adv748x_afe_init_controls(struct adv748x_afe *afe) 470 { 471 struct adv748x_state *state = adv748x_afe_to_state(afe); 472 473 v4l2_ctrl_handler_init(&afe->ctrl_hdl, 5); 474 475 /* Use our mutex for the controls */ 476 afe->ctrl_hdl.lock = &state->mutex; 477 478 v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops, 479 V4L2_CID_BRIGHTNESS, ADV748X_SDP_BRI_MIN, 480 ADV748X_SDP_BRI_MAX, 1, ADV748X_SDP_BRI_DEF); 481 v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops, 482 V4L2_CID_CONTRAST, ADV748X_SDP_CON_MIN, 483 ADV748X_SDP_CON_MAX, 1, ADV748X_SDP_CON_DEF); 484 v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops, 485 V4L2_CID_SATURATION, ADV748X_SDP_SAT_MIN, 486 ADV748X_SDP_SAT_MAX, 1, ADV748X_SDP_SAT_DEF); 487 v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops, 488 V4L2_CID_HUE, ADV748X_SDP_HUE_MIN, 489 ADV748X_SDP_HUE_MAX, 1, ADV748X_SDP_HUE_DEF); 490 491 v4l2_ctrl_new_std_menu_items(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops, 492 V4L2_CID_TEST_PATTERN, 493 ARRAY_SIZE(afe_ctrl_frp_menu) - 1, 494 0, 0, afe_ctrl_frp_menu); 495 496 afe->sd.ctrl_handler = &afe->ctrl_hdl; 497 if (afe->ctrl_hdl.error) { 498 v4l2_ctrl_handler_free(&afe->ctrl_hdl); 499 return afe->ctrl_hdl.error; 500 } 501 502 return v4l2_ctrl_handler_setup(&afe->ctrl_hdl); 503 } 504 505 int adv748x_afe_init(struct adv748x_afe *afe) 506 { 507 struct adv748x_state *state = adv748x_afe_to_state(afe); 508 int ret; 509 unsigned int i; 510 511 afe->input = 0; 512 afe->streaming = false; 513 afe->curr_norm = V4L2_STD_NTSC_M; 514 515 adv748x_subdev_init(&afe->sd, state, &adv748x_afe_ops, 516 MEDIA_ENT_F_ATV_DECODER, "afe"); 517 518 /* Identify the first connector found as a default input if set */ 519 for (i = ADV748X_PORT_AIN0; i <= ADV748X_PORT_AIN7; i++) { 520 /* Inputs and ports are 1-indexed to match the data sheet */ 521 if (state->endpoints[i]) { 522 afe->input = i; 523 break; 524 } 525 } 526 527 adv748x_afe_s_input(afe, afe->input); 528 529 adv_dbg(state, "AFE Default input set to %d\n", afe->input); 530 531 /* Entity pads and sinks are 0-indexed to match the pads */ 532 for (i = ADV748X_AFE_SINK_AIN0; i <= ADV748X_AFE_SINK_AIN7; i++) 533 afe->pads[i].flags = MEDIA_PAD_FL_SINK; 534 535 afe->pads[ADV748X_AFE_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 536 537 ret = media_entity_pads_init(&afe->sd.entity, ADV748X_AFE_NR_PADS, 538 afe->pads); 539 if (ret) 540 return ret; 541 542 ret = adv748x_afe_init_controls(afe); 543 if (ret) 544 goto error; 545 546 return 0; 547 548 error: 549 media_entity_cleanup(&afe->sd.entity); 550 551 return ret; 552 } 553 554 void adv748x_afe_cleanup(struct adv748x_afe *afe) 555 { 556 v4l2_device_unregister_subdev(&afe->sd); 557 media_entity_cleanup(&afe->sd.entity); 558 v4l2_ctrl_handler_free(&afe->ctrl_hdl); 559 } 560