perf tools: Don't clone maps from parent when synthesizing forks
[linux/fpc-iii.git] / drivers / media / i2c / adv748x / adv748x-afe.c
blobedd25e895e5dec3cecb7de0b3afead0e85dcd54d
1 /*
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>
23 #include "adv748x.h"
25 /* -----------------------------------------------------------------------------
26 * SDP
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)
48 int ret;
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;
56 return sdp_read(state, reg);
59 static int adv748x_afe_status(struct adv748x_afe *afe, u32 *signal,
60 v4l2_std_id *std)
62 struct adv748x_state *state = adv748x_afe_to_state(afe);
63 int info;
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;
70 if (signal)
71 *signal = info & ADV748X_SDP_RO_10_IN_LOCK ?
72 0 : V4L2_IN_ST_NO_SIGNAL;
74 if (!std)
75 return 0;
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;
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;
113 return 0;
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;
125 fmt->width = 720;
126 fmt->height = afe->curr_norm & V4L2_STD_525_60 ? 480 : 576;
128 /* Field height */
129 fmt->height /= 2;
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;
151 return -EINVAL;
154 static void adv748x_afe_set_video_standard(struct adv748x_state *state,
155 int sdpstd)
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;
176 } else {
177 aspect->numerator = 54;
178 aspect->denominator = 59;
181 return 0;
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;
194 return 0;
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);
203 if (afe_std < 0)
204 return afe_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);
213 return 0;
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);
220 int afe_std;
221 int ret;
223 mutex_lock(&state->mutex);
225 if (afe->streaming) {
226 ret = -EBUSY;
227 goto unlock;
230 /* Set auto detect mode */
231 adv748x_afe_set_video_standard(state,
232 ADV748X_AFE_STD_AD_PAL_BG_NTSC_J_SECAM);
234 msleep(100);
236 /* Read detected standard */
237 ret = adv748x_afe_status(afe, NULL, std);
239 afe_std = adv748x_afe_std(afe->curr_norm);
240 if (afe_std < 0)
241 goto unlock;
243 /* Restore original state */
244 adv748x_afe_set_video_standard(state, afe_std);
246 unlock:
247 mutex_unlock(&state->mutex);
249 return ret;
252 static int adv748x_afe_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm)
254 *norm = V4L2_STD_ALL;
256 return 0;
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);
263 int ret;
265 mutex_lock(&state->mutex);
267 ret = adv748x_afe_status(afe, status, NULL);
269 mutex_unlock(&state->mutex);
271 return ret;
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;
279 int ret;
281 mutex_lock(&state->mutex);
283 if (enable) {
284 ret = adv748x_afe_s_input(afe, afe->input);
285 if (ret)
286 goto unlock;
289 ret = adv748x_txb_power(state, enable);
290 if (ret)
291 goto unlock;
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");
298 else
299 adv_dbg(state, "Couldn't detect SDP video signal\n");
301 unlock:
302 mutex_unlock(&state->mutex);
304 return ret;
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]);
326 if (!tx)
327 return -ENOLINK;
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)
342 return -EINVAL;
344 code->code = MEDIA_BUS_FMT_UYVY8_2X8;
346 return 0;
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)
358 return -EINVAL;
360 if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) {
361 mbusformat = v4l2_subdev_get_try_format(sd, cfg, sdformat->pad);
362 sdformat->format = *mbusformat;
363 } else {
364 adv748x_afe_fill_format(afe, &sdformat->format);
365 adv748x_afe_propagate_pixelrate(afe);
368 return 0;
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)
379 return -EINVAL;
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;
387 return 0;
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 /* -----------------------------------------------------------------------------
397 * v4l2_subdev_ops
400 static const struct v4l2_subdev_ops adv748x_afe_ops = {
401 .video = &adv748x_afe_video_ops,
402 .pad = &adv748x_afe_pad_ops,
405 /* -----------------------------------------------------------------------------
406 * Controls
409 static const char * const afe_ctrl_frp_menu[] = {
410 "Disabled",
411 "Solid Blue",
412 "Color Bars",
413 "Grey Ramp",
414 "Cb Ramp",
415 "Cr Ramp",
416 "Boundary"
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);
423 bool enable;
424 int ret;
426 ret = sdp_write(state, 0x0e, 0x00);
427 if (ret < 0)
428 return ret;
430 switch (ctrl->id) {
431 case V4L2_CID_BRIGHTNESS:
432 ret = sdp_write(state, ADV748X_SDP_BRI, ctrl->val);
433 break;
434 case V4L2_CID_HUE:
435 /* Hue is inverted according to HSL chart */
436 ret = sdp_write(state, ADV748X_SDP_HUE, -ctrl->val);
437 break;
438 case V4L2_CID_CONTRAST:
439 ret = sdp_write(state, ADV748X_SDP_CON, ctrl->val);
440 break;
441 case V4L2_CID_SATURATION:
442 ret = sdp_write(state, ADV748X_SDP_SD_SAT_U, ctrl->val);
443 if (ret)
444 break;
445 ret = sdp_write(state, ADV748X_SDP_SD_SAT_V, ctrl->val);
446 break;
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,
452 enable);
453 if (ret)
454 break;
455 ret = sdp_clrset(state, ADV748X_SDP_FRP, ADV748X_SDP_FRP_MASK,
456 enable ? ctrl->val - 1 : 0);
457 break;
458 default:
459 return -EINVAL;
462 return ret;
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);
508 int ret;
509 unsigned int i;
511 afe->input = 0;
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]) {
522 afe->input = i;
523 break;
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,
538 afe->pads);
539 if (ret)
540 return ret;
542 ret = adv748x_afe_init_controls(afe);
543 if (ret)
544 goto error;
546 return 0;
548 error:
549 media_entity_cleanup(&afe->sd.entity);
551 return ret;
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);