root/drivers/media/i2c/adv748x/adv748x-afe.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. adv748x_afe_read_ro_map
  2. adv748x_afe_status
  3. adv748x_afe_fill_format
  4. adv748x_afe_std
  5. adv748x_afe_set_video_standard
  6. adv748x_afe_s_input
  7. adv748x_afe_g_pixelaspect
  8. adv748x_afe_g_std
  9. adv748x_afe_s_std
  10. adv748x_afe_querystd
  11. adv748x_afe_g_tvnorms
  12. adv748x_afe_g_input_status
  13. adv748x_afe_s_stream
  14. adv748x_afe_propagate_pixelrate
  15. adv748x_afe_enum_mbus_code
  16. adv748x_afe_get_format
  17. adv748x_afe_set_format
  18. adv748x_afe_s_ctrl
  19. adv748x_afe_init_controls
  20. adv748x_afe_init
  21. adv748x_afe_cleanup

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

/* [<][>][^][v][top][bottom][index][help] */