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