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