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 int ret, signal = V4L2_IN_ST_NO_SIGNAL; 279 280 mutex_lock(&state->mutex); 281 282 if (enable) { 283 ret = adv748x_afe_s_input(afe, afe->input); 284 if (ret) 285 goto unlock; 286 } 287 288 ret = adv748x_txb_power(state, enable); 289 if (ret) 290 goto unlock; 291 292 afe->streaming = enable; 293 294 adv748x_afe_status(afe, &signal, NULL); 295 if (signal != V4L2_IN_ST_NO_SIGNAL) 296 adv_dbg(state, "Detected SDP signal\n"); 297 else 298 adv_dbg(state, "Couldn't detect SDP video signal\n"); 299 300 unlock: 301 mutex_unlock(&state->mutex); 302 303 return ret; 304 } 305 306 static const struct v4l2_subdev_video_ops adv748x_afe_video_ops = { 307 .g_std = adv748x_afe_g_std, 308 .s_std = adv748x_afe_s_std, 309 .querystd = adv748x_afe_querystd, 310 .g_tvnorms = adv748x_afe_g_tvnorms, 311 .g_input_status = adv748x_afe_g_input_status, 312 .s_stream = adv748x_afe_s_stream, 313 .g_pixelaspect = adv748x_afe_g_pixelaspect, 314 }; 315 316 /* ----------------------------------------------------------------------------- 317 * v4l2_subdev_pad_ops 318 */ 319 320 static int adv748x_afe_propagate_pixelrate(struct adv748x_afe *afe) 321 { 322 struct v4l2_subdev *tx; 323 unsigned int width, height, fps; 324 325 tx = adv748x_get_remote_sd(&afe->pads[ADV748X_AFE_SOURCE]); 326 if (!tx) 327 return -ENOLINK; 328 329 width = 720; 330 height = afe->curr_norm & V4L2_STD_525_60 ? 480 : 576; 331 fps = afe->curr_norm & V4L2_STD_525_60 ? 30 : 25; 332 333 return adv748x_csi2_set_pixelrate(tx, width * height * fps); 334 } 335 336 static int adv748x_afe_enum_mbus_code(struct v4l2_subdev *sd, 337 struct v4l2_subdev_pad_config *cfg, 338 struct v4l2_subdev_mbus_code_enum *code) 339 { 340 if (code->index != 0) 341 return -EINVAL; 342 343 code->code = MEDIA_BUS_FMT_UYVY8_2X8; 344 345 return 0; 346 } 347 348 static int adv748x_afe_get_format(struct v4l2_subdev *sd, 349 struct v4l2_subdev_pad_config *cfg, 350 struct v4l2_subdev_format *sdformat) 351 { 352 struct adv748x_afe *afe = adv748x_sd_to_afe(sd); 353 struct v4l2_mbus_framefmt *mbusformat; 354 355 /* It makes no sense to get the format of the analog sink pads */ 356 if (sdformat->pad != ADV748X_AFE_SOURCE) 357 return -EINVAL; 358 359 if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) { 360 mbusformat = v4l2_subdev_get_try_format(sd, cfg, sdformat->pad); 361 sdformat->format = *mbusformat; 362 } else { 363 adv748x_afe_fill_format(afe, &sdformat->format); 364 adv748x_afe_propagate_pixelrate(afe); 365 } 366 367 return 0; 368 } 369 370 static int adv748x_afe_set_format(struct v4l2_subdev *sd, 371 struct v4l2_subdev_pad_config *cfg, 372 struct v4l2_subdev_format *sdformat) 373 { 374 struct v4l2_mbus_framefmt *mbusformat; 375 376 /* It makes no sense to get the format of the analog sink pads */ 377 if (sdformat->pad != ADV748X_AFE_SOURCE) 378 return -EINVAL; 379 380 if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) 381 return adv748x_afe_get_format(sd, cfg, sdformat); 382 383 mbusformat = v4l2_subdev_get_try_format(sd, cfg, sdformat->pad); 384 *mbusformat = sdformat->format; 385 386 return 0; 387 } 388 389 static const struct v4l2_subdev_pad_ops adv748x_afe_pad_ops = { 390 .enum_mbus_code = adv748x_afe_enum_mbus_code, 391 .set_fmt = adv748x_afe_set_format, 392 .get_fmt = adv748x_afe_get_format, 393 }; 394 395 /* ----------------------------------------------------------------------------- 396 * v4l2_subdev_ops 397 */ 398 399 static const struct v4l2_subdev_ops adv748x_afe_ops = { 400 .video = &adv748x_afe_video_ops, 401 .pad = &adv748x_afe_pad_ops, 402 }; 403 404 /* ----------------------------------------------------------------------------- 405 * Controls 406 */ 407 408 static const char * const afe_ctrl_frp_menu[] = { 409 "Disabled", 410 "Solid Blue", 411 "Color Bars", 412 "Grey Ramp", 413 "Cb Ramp", 414 "Cr Ramp", 415 "Boundary" 416 }; 417 418 static int adv748x_afe_s_ctrl(struct v4l2_ctrl *ctrl) 419 { 420 struct adv748x_afe *afe = adv748x_ctrl_to_afe(ctrl); 421 struct adv748x_state *state = adv748x_afe_to_state(afe); 422 bool enable; 423 int ret; 424 425 ret = sdp_write(state, 0x0e, 0x00); 426 if (ret < 0) 427 return ret; 428 429 switch (ctrl->id) { 430 case V4L2_CID_BRIGHTNESS: 431 ret = sdp_write(state, ADV748X_SDP_BRI, ctrl->val); 432 break; 433 case V4L2_CID_HUE: 434 /* Hue is inverted according to HSL chart */ 435 ret = sdp_write(state, ADV748X_SDP_HUE, -ctrl->val); 436 break; 437 case V4L2_CID_CONTRAST: 438 ret = sdp_write(state, ADV748X_SDP_CON, ctrl->val); 439 break; 440 case V4L2_CID_SATURATION: 441 ret = sdp_write(state, ADV748X_SDP_SD_SAT_U, ctrl->val); 442 if (ret) 443 break; 444 ret = sdp_write(state, ADV748X_SDP_SD_SAT_V, ctrl->val); 445 break; 446 case V4L2_CID_TEST_PATTERN: 447 enable = !!ctrl->val; 448 449 /* Enable/Disable Color bar test patterns */ 450 ret = sdp_clrset(state, ADV748X_SDP_DEF, ADV748X_SDP_DEF_VAL_EN, 451 enable); 452 if (ret) 453 break; 454 ret = sdp_clrset(state, ADV748X_SDP_FRP, ADV748X_SDP_FRP_MASK, 455 enable ? ctrl->val - 1 : 0); 456 break; 457 default: 458 return -EINVAL; 459 } 460 461 return ret; 462 } 463 464 static const struct v4l2_ctrl_ops adv748x_afe_ctrl_ops = { 465 .s_ctrl = adv748x_afe_s_ctrl, 466 }; 467 468 static int adv748x_afe_init_controls(struct adv748x_afe *afe) 469 { 470 struct adv748x_state *state = adv748x_afe_to_state(afe); 471 472 v4l2_ctrl_handler_init(&afe->ctrl_hdl, 5); 473 474 /* Use our mutex for the controls */ 475 afe->ctrl_hdl.lock = &state->mutex; 476 477 v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops, 478 V4L2_CID_BRIGHTNESS, ADV748X_SDP_BRI_MIN, 479 ADV748X_SDP_BRI_MAX, 1, ADV748X_SDP_BRI_DEF); 480 v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops, 481 V4L2_CID_CONTRAST, ADV748X_SDP_CON_MIN, 482 ADV748X_SDP_CON_MAX, 1, ADV748X_SDP_CON_DEF); 483 v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops, 484 V4L2_CID_SATURATION, ADV748X_SDP_SAT_MIN, 485 ADV748X_SDP_SAT_MAX, 1, ADV748X_SDP_SAT_DEF); 486 v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops, 487 V4L2_CID_HUE, ADV748X_SDP_HUE_MIN, 488 ADV748X_SDP_HUE_MAX, 1, ADV748X_SDP_HUE_DEF); 489 490 v4l2_ctrl_new_std_menu_items(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops, 491 V4L2_CID_TEST_PATTERN, 492 ARRAY_SIZE(afe_ctrl_frp_menu) - 1, 493 0, 0, afe_ctrl_frp_menu); 494 495 afe->sd.ctrl_handler = &afe->ctrl_hdl; 496 if (afe->ctrl_hdl.error) { 497 v4l2_ctrl_handler_free(&afe->ctrl_hdl); 498 return afe->ctrl_hdl.error; 499 } 500 501 return v4l2_ctrl_handler_setup(&afe->ctrl_hdl); 502 } 503 504 int adv748x_afe_init(struct adv748x_afe *afe) 505 { 506 struct adv748x_state *state = adv748x_afe_to_state(afe); 507 int ret; 508 unsigned int i; 509 510 afe->input = 0; 511 afe->streaming = false; 512 afe->curr_norm = V4L2_STD_NTSC_M; 513 514 adv748x_subdev_init(&afe->sd, state, &adv748x_afe_ops, 515 MEDIA_ENT_F_ATV_DECODER, "afe"); 516 517 /* Identify the first connector found as a default input if set */ 518 for (i = ADV748X_PORT_AIN0; i <= ADV748X_PORT_AIN7; i++) { 519 /* Inputs and ports are 1-indexed to match the data sheet */ 520 if (state->endpoints[i]) { 521 afe->input = i; 522 break; 523 } 524 } 525 526 adv748x_afe_s_input(afe, afe->input); 527 528 adv_dbg(state, "AFE Default input set to %d\n", afe->input); 529 530 /* Entity pads and sinks are 0-indexed to match the pads */ 531 for (i = ADV748X_AFE_SINK_AIN0; i <= ADV748X_AFE_SINK_AIN7; i++) 532 afe->pads[i].flags = MEDIA_PAD_FL_SINK; 533 534 afe->pads[ADV748X_AFE_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 535 536 ret = media_entity_pads_init(&afe->sd.entity, ADV748X_AFE_NR_PADS, 537 afe->pads); 538 if (ret) 539 return ret; 540 541 ret = adv748x_afe_init_controls(afe); 542 if (ret) 543 goto error; 544 545 return 0; 546 547 error: 548 media_entity_cleanup(&afe->sd.entity); 549 550 return ret; 551 } 552 553 void adv748x_afe_cleanup(struct adv748x_afe *afe) 554 { 555 v4l2_device_unregister_subdev(&afe->sd); 556 media_entity_cleanup(&afe->sd.entity); 557 v4l2_ctrl_handler_free(&afe->ctrl_hdl); 558 } 559