2 * Driver for Analog Devices ADV748X 8 channel analog front end (AFE) receiver
3 * with standard definition processor (SDP)
5 * Copyright (C) 2017 Renesas Electronics Corp.
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.
13 #include <linux/delay.h>
14 #include <linux/module.h>
15 #include <linux/mutex.h>
16 #include <linux/v4l2-dv-timings.h>
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>
25 /* -----------------------------------------------------------------------------
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
46 static int adv748x_afe_read_ro_map(struct adv748x_state
*state
, u8 reg
)
50 /* Select SDP Read-Only Main Map */
51 ret
= sdp_write(state
, ADV748X_SDP_MAP_SEL
,
52 ADV748X_SDP_MAP_SEL_RO_MAIN
);
56 return sdp_read(state
, reg
);
59 static int adv748x_afe_status(struct adv748x_afe
*afe
, u32
*signal
,
62 struct adv748x_state
*state
= adv748x_afe_to_state(afe
);
65 /* Read status from reg 0x10 of SDP RO Map */
66 info
= adv748x_afe_read_ro_map(state
, ADV748X_SDP_RO_10
);
71 *signal
= info
& ADV748X_SDP_RO_10_IN_LOCK
?
72 0 : V4L2_IN_ST_NO_SIGNAL
;
77 /* Standard not valid if there is no signal */
78 if (!(info
& ADV748X_SDP_RO_10_IN_LOCK
)) {
79 *std
= V4L2_STD_UNKNOWN
;
83 switch (info
& 0x70) {
88 *std
= V4L2_STD_NTSC_443
;
91 *std
= V4L2_STD_PAL_M
;
94 *std
= V4L2_STD_PAL_60
;
100 *std
= V4L2_STD_SECAM
;
103 *std
= V4L2_STD_PAL_Nc
| V4L2_STD_PAL_N
;
106 *std
= V4L2_STD_SECAM
;
109 *std
= V4L2_STD_UNKNOWN
;
116 static void adv748x_afe_fill_format(struct adv748x_afe
*afe
,
117 struct v4l2_mbus_framefmt
*fmt
)
119 memset(fmt
, 0, sizeof(*fmt
));
121 fmt
->code
= MEDIA_BUS_FMT_UYVY8_2X8
;
122 fmt
->colorspace
= V4L2_COLORSPACE_SMPTE170M
;
123 fmt
->field
= V4L2_FIELD_ALTERNATE
;
126 fmt
->height
= afe
->curr_norm
& V4L2_STD_525_60
? 480 : 576;
132 static int adv748x_afe_std(v4l2_std_id std
)
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
;
154 static void adv748x_afe_set_video_standard(struct adv748x_state
*state
,
157 sdp_clrset(state
, ADV748X_SDP_VID_SEL
, ADV748X_SDP_VID_SEL_MASK
,
158 (sdpstd
& 0xf) << ADV748X_SDP_VID_SEL_SHIFT
);
161 static int adv748x_afe_s_input(struct adv748x_afe
*afe
, unsigned int input
)
163 struct adv748x_state
*state
= adv748x_afe_to_state(afe
);
165 return sdp_write(state
, ADV748X_SDP_INSEL
, input
);
168 static int adv748x_afe_g_pixelaspect(struct v4l2_subdev
*sd
,
169 struct v4l2_fract
*aspect
)
171 struct adv748x_afe
*afe
= adv748x_sd_to_afe(sd
);
173 if (afe
->curr_norm
& V4L2_STD_525_60
) {
174 aspect
->numerator
= 11;
175 aspect
->denominator
= 10;
177 aspect
->numerator
= 54;
178 aspect
->denominator
= 59;
184 /* -----------------------------------------------------------------------------
185 * v4l2_subdev_video_ops
188 static int adv748x_afe_g_std(struct v4l2_subdev
*sd
, v4l2_std_id
*norm
)
190 struct adv748x_afe
*afe
= adv748x_sd_to_afe(sd
);
192 *norm
= afe
->curr_norm
;
197 static int adv748x_afe_s_std(struct v4l2_subdev
*sd
, v4l2_std_id std
)
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
);
206 mutex_lock(&state
->mutex
);
208 adv748x_afe_set_video_standard(state
, afe_std
);
209 afe
->curr_norm
= std
;
211 mutex_unlock(&state
->mutex
);
216 static int adv748x_afe_querystd(struct v4l2_subdev
*sd
, v4l2_std_id
*std
)
218 struct adv748x_afe
*afe
= adv748x_sd_to_afe(sd
);
219 struct adv748x_state
*state
= adv748x_afe_to_state(afe
);
223 mutex_lock(&state
->mutex
);
225 if (afe
->streaming
) {
230 /* Set auto detect mode */
231 adv748x_afe_set_video_standard(state
,
232 ADV748X_AFE_STD_AD_PAL_BG_NTSC_J_SECAM
);
236 /* Read detected standard */
237 ret
= adv748x_afe_status(afe
, NULL
, std
);
239 afe_std
= adv748x_afe_std(afe
->curr_norm
);
243 /* Restore original state */
244 adv748x_afe_set_video_standard(state
, afe_std
);
247 mutex_unlock(&state
->mutex
);
252 static int adv748x_afe_g_tvnorms(struct v4l2_subdev
*sd
, v4l2_std_id
*norm
)
254 *norm
= V4L2_STD_ALL
;
259 static int adv748x_afe_g_input_status(struct v4l2_subdev
*sd
, u32
*status
)
261 struct adv748x_afe
*afe
= adv748x_sd_to_afe(sd
);
262 struct adv748x_state
*state
= adv748x_afe_to_state(afe
);
265 mutex_lock(&state
->mutex
);
267 ret
= adv748x_afe_status(afe
, status
, NULL
);
269 mutex_unlock(&state
->mutex
);
274 static int adv748x_afe_s_stream(struct v4l2_subdev
*sd
, int enable
)
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
;
281 mutex_lock(&state
->mutex
);
284 ret
= adv748x_afe_s_input(afe
, afe
->input
);
289 ret
= adv748x_txb_power(state
, enable
);
293 afe
->streaming
= enable
;
295 adv748x_afe_status(afe
, &signal
, NULL
);
296 if (signal
!= V4L2_IN_ST_NO_SIGNAL
)
297 adv_dbg(state
, "Detected SDP signal\n");
299 adv_dbg(state
, "Couldn't detect SDP video signal\n");
302 mutex_unlock(&state
->mutex
);
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
,
317 /* -----------------------------------------------------------------------------
318 * v4l2_subdev_pad_ops
321 static int adv748x_afe_propagate_pixelrate(struct adv748x_afe
*afe
)
323 struct v4l2_subdev
*tx
;
325 tx
= adv748x_get_remote_sd(&afe
->pads
[ADV748X_AFE_SOURCE
]);
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.
334 return adv748x_csi2_set_pixelrate(tx
, 14318180);
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
)
341 if (code
->index
!= 0)
344 code
->code
= MEDIA_BUS_FMT_UYVY8_2X8
;
349 static int adv748x_afe_get_format(struct v4l2_subdev
*sd
,
350 struct v4l2_subdev_pad_config
*cfg
,
351 struct v4l2_subdev_format
*sdformat
)
353 struct adv748x_afe
*afe
= adv748x_sd_to_afe(sd
);
354 struct v4l2_mbus_framefmt
*mbusformat
;
356 /* It makes no sense to get the format of the analog sink pads */
357 if (sdformat
->pad
!= ADV748X_AFE_SOURCE
)
360 if (sdformat
->which
== V4L2_SUBDEV_FORMAT_TRY
) {
361 mbusformat
= v4l2_subdev_get_try_format(sd
, cfg
, sdformat
->pad
);
362 sdformat
->format
= *mbusformat
;
364 adv748x_afe_fill_format(afe
, &sdformat
->format
);
365 adv748x_afe_propagate_pixelrate(afe
);
371 static int adv748x_afe_set_format(struct v4l2_subdev
*sd
,
372 struct v4l2_subdev_pad_config
*cfg
,
373 struct v4l2_subdev_format
*sdformat
)
375 struct v4l2_mbus_framefmt
*mbusformat
;
377 /* It makes no sense to get the format of the analog sink pads */
378 if (sdformat
->pad
!= ADV748X_AFE_SOURCE
)
381 if (sdformat
->which
== V4L2_SUBDEV_FORMAT_ACTIVE
)
382 return adv748x_afe_get_format(sd
, cfg
, sdformat
);
384 mbusformat
= v4l2_subdev_get_try_format(sd
, cfg
, sdformat
->pad
);
385 *mbusformat
= sdformat
->format
;
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
,
396 /* -----------------------------------------------------------------------------
400 static const struct v4l2_subdev_ops adv748x_afe_ops
= {
401 .video
= &adv748x_afe_video_ops
,
402 .pad
= &adv748x_afe_pad_ops
,
405 /* -----------------------------------------------------------------------------
409 static const char * const afe_ctrl_frp_menu
[] = {
419 static int adv748x_afe_s_ctrl(struct v4l2_ctrl
*ctrl
)
421 struct adv748x_afe
*afe
= adv748x_ctrl_to_afe(ctrl
);
422 struct adv748x_state
*state
= adv748x_afe_to_state(afe
);
426 ret
= sdp_write(state
, 0x0e, 0x00);
431 case V4L2_CID_BRIGHTNESS
:
432 ret
= sdp_write(state
, ADV748X_SDP_BRI
, ctrl
->val
);
435 /* Hue is inverted according to HSL chart */
436 ret
= sdp_write(state
, ADV748X_SDP_HUE
, -ctrl
->val
);
438 case V4L2_CID_CONTRAST
:
439 ret
= sdp_write(state
, ADV748X_SDP_CON
, ctrl
->val
);
441 case V4L2_CID_SATURATION
:
442 ret
= sdp_write(state
, ADV748X_SDP_SD_SAT_U
, ctrl
->val
);
445 ret
= sdp_write(state
, ADV748X_SDP_SD_SAT_V
, ctrl
->val
);
447 case V4L2_CID_TEST_PATTERN
:
448 enable
= !!ctrl
->val
;
450 /* Enable/Disable Color bar test patterns */
451 ret
= sdp_clrset(state
, ADV748X_SDP_DEF
, ADV748X_SDP_DEF_VAL_EN
,
455 ret
= sdp_clrset(state
, ADV748X_SDP_FRP
, ADV748X_SDP_FRP_MASK
,
456 enable
? ctrl
->val
- 1 : 0);
465 static const struct v4l2_ctrl_ops adv748x_afe_ctrl_ops
= {
466 .s_ctrl
= adv748x_afe_s_ctrl
,
469 static int adv748x_afe_init_controls(struct adv748x_afe
*afe
)
471 struct adv748x_state
*state
= adv748x_afe_to_state(afe
);
473 v4l2_ctrl_handler_init(&afe
->ctrl_hdl
, 5);
475 /* Use our mutex for the controls */
476 afe
->ctrl_hdl
.lock
= &state
->mutex
;
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
);
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
);
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
;
502 return v4l2_ctrl_handler_setup(&afe
->ctrl_hdl
);
505 int adv748x_afe_init(struct adv748x_afe
*afe
)
507 struct adv748x_state
*state
= adv748x_afe_to_state(afe
);
512 afe
->streaming
= false;
513 afe
->curr_norm
= V4L2_STD_NTSC_M
;
515 adv748x_subdev_init(&afe
->sd
, state
, &adv748x_afe_ops
,
516 MEDIA_ENT_F_ATV_DECODER
, "afe");
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
]) {
527 adv748x_afe_s_input(afe
, afe
->input
);
529 adv_dbg(state
, "AFE Default input set to %d\n", afe
->input
);
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
;
535 afe
->pads
[ADV748X_AFE_SOURCE
].flags
= MEDIA_PAD_FL_SOURCE
;
537 ret
= media_entity_pads_init(&afe
->sd
.entity
, ADV748X_AFE_NR_PADS
,
542 ret
= adv748x_afe_init_controls(afe
);
549 media_entity_cleanup(&afe
->sd
.entity
);
554 void adv748x_afe_cleanup(struct adv748x_afe
*afe
)
556 v4l2_device_unregister_subdev(&afe
->sd
);
557 media_entity_cleanup(&afe
->sd
.entity
);
558 v4l2_ctrl_handler_free(&afe
->ctrl_hdl
);