1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Analog Devices AD9389B/AD9889B video encoder driver
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun /*
9*4882a593Smuzhiyun * References (c = chapter, p = page):
10*4882a593Smuzhiyun * REF_01 - Analog Devices, Programming Guide, AD9889B/AD9389B,
11*4882a593Smuzhiyun * HDMI Transitter, Rev. A, October 2010
12*4882a593Smuzhiyun */
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #include <linux/kernel.h>
15*4882a593Smuzhiyun #include <linux/module.h>
16*4882a593Smuzhiyun #include <linux/slab.h>
17*4882a593Smuzhiyun #include <linux/i2c.h>
18*4882a593Smuzhiyun #include <linux/delay.h>
19*4882a593Smuzhiyun #include <linux/videodev2.h>
20*4882a593Smuzhiyun #include <linux/workqueue.h>
21*4882a593Smuzhiyun #include <linux/v4l2-dv-timings.h>
22*4882a593Smuzhiyun #include <media/v4l2-device.h>
23*4882a593Smuzhiyun #include <media/v4l2-common.h>
24*4882a593Smuzhiyun #include <media/v4l2-dv-timings.h>
25*4882a593Smuzhiyun #include <media/v4l2-ctrls.h>
26*4882a593Smuzhiyun #include <media/i2c/ad9389b.h>
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun static int debug;
29*4882a593Smuzhiyun module_param(debug, int, 0644);
30*4882a593Smuzhiyun MODULE_PARM_DESC(debug, "debug level (0-2)");
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun MODULE_DESCRIPTION("Analog Devices AD9389B/AD9889B video encoder driver");
33*4882a593Smuzhiyun MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
34*4882a593Smuzhiyun MODULE_AUTHOR("Martin Bugge <marbugge@cisco.com>");
35*4882a593Smuzhiyun MODULE_LICENSE("GPL");
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun #define MASK_AD9389B_EDID_RDY_INT 0x04
38*4882a593Smuzhiyun #define MASK_AD9389B_MSEN_INT 0x40
39*4882a593Smuzhiyun #define MASK_AD9389B_HPD_INT 0x80
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun #define MASK_AD9389B_HPD_DETECT 0x40
42*4882a593Smuzhiyun #define MASK_AD9389B_MSEN_DETECT 0x20
43*4882a593Smuzhiyun #define MASK_AD9389B_EDID_RDY 0x10
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun #define EDID_MAX_RETRIES (8)
46*4882a593Smuzhiyun #define EDID_DELAY 250
47*4882a593Smuzhiyun #define EDID_MAX_SEGM 8
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun /*
50*4882a593Smuzhiyun **********************************************************************
51*4882a593Smuzhiyun *
52*4882a593Smuzhiyun * Arrays with configuration parameters for the AD9389B
53*4882a593Smuzhiyun *
54*4882a593Smuzhiyun **********************************************************************
55*4882a593Smuzhiyun */
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun struct ad9389b_state_edid {
58*4882a593Smuzhiyun /* total number of blocks */
59*4882a593Smuzhiyun u32 blocks;
60*4882a593Smuzhiyun /* Number of segments read */
61*4882a593Smuzhiyun u32 segments;
62*4882a593Smuzhiyun u8 data[EDID_MAX_SEGM * 256];
63*4882a593Smuzhiyun /* Number of EDID read retries left */
64*4882a593Smuzhiyun unsigned read_retries;
65*4882a593Smuzhiyun };
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun struct ad9389b_state {
68*4882a593Smuzhiyun struct ad9389b_platform_data pdata;
69*4882a593Smuzhiyun struct v4l2_subdev sd;
70*4882a593Smuzhiyun struct media_pad pad;
71*4882a593Smuzhiyun struct v4l2_ctrl_handler hdl;
72*4882a593Smuzhiyun int chip_revision;
73*4882a593Smuzhiyun /* Is the ad9389b powered on? */
74*4882a593Smuzhiyun bool power_on;
75*4882a593Smuzhiyun /* Did we receive hotplug and rx-sense signals? */
76*4882a593Smuzhiyun bool have_monitor;
77*4882a593Smuzhiyun /* timings from s_dv_timings */
78*4882a593Smuzhiyun struct v4l2_dv_timings dv_timings;
79*4882a593Smuzhiyun /* controls */
80*4882a593Smuzhiyun struct v4l2_ctrl *hdmi_mode_ctrl;
81*4882a593Smuzhiyun struct v4l2_ctrl *hotplug_ctrl;
82*4882a593Smuzhiyun struct v4l2_ctrl *rx_sense_ctrl;
83*4882a593Smuzhiyun struct v4l2_ctrl *have_edid0_ctrl;
84*4882a593Smuzhiyun struct v4l2_ctrl *rgb_quantization_range_ctrl;
85*4882a593Smuzhiyun struct i2c_client *edid_i2c_client;
86*4882a593Smuzhiyun struct ad9389b_state_edid edid;
87*4882a593Smuzhiyun /* Running counter of the number of detected EDIDs (for debugging) */
88*4882a593Smuzhiyun unsigned edid_detect_counter;
89*4882a593Smuzhiyun struct delayed_work edid_handler; /* work entry */
90*4882a593Smuzhiyun };
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun static void ad9389b_check_monitor_present_status(struct v4l2_subdev *sd);
93*4882a593Smuzhiyun static bool ad9389b_check_edid_status(struct v4l2_subdev *sd);
94*4882a593Smuzhiyun static void ad9389b_setup(struct v4l2_subdev *sd);
95*4882a593Smuzhiyun static int ad9389b_s_i2s_clock_freq(struct v4l2_subdev *sd, u32 freq);
96*4882a593Smuzhiyun static int ad9389b_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
97*4882a593Smuzhiyun
get_ad9389b_state(struct v4l2_subdev * sd)98*4882a593Smuzhiyun static inline struct ad9389b_state *get_ad9389b_state(struct v4l2_subdev *sd)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun return container_of(sd, struct ad9389b_state, sd);
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun
to_sd(struct v4l2_ctrl * ctrl)103*4882a593Smuzhiyun static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun return &container_of(ctrl->handler, struct ad9389b_state, hdl)->sd;
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun /* ------------------------ I2C ----------------------------------------------- */
109*4882a593Smuzhiyun
ad9389b_rd(struct v4l2_subdev * sd,u8 reg)110*4882a593Smuzhiyun static int ad9389b_rd(struct v4l2_subdev *sd, u8 reg)
111*4882a593Smuzhiyun {
112*4882a593Smuzhiyun struct i2c_client *client = v4l2_get_subdevdata(sd);
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun return i2c_smbus_read_byte_data(client, reg);
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun
ad9389b_wr(struct v4l2_subdev * sd,u8 reg,u8 val)117*4882a593Smuzhiyun static int ad9389b_wr(struct v4l2_subdev *sd, u8 reg, u8 val)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun struct i2c_client *client = v4l2_get_subdevdata(sd);
120*4882a593Smuzhiyun int ret;
121*4882a593Smuzhiyun int i;
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun for (i = 0; i < 3; i++) {
124*4882a593Smuzhiyun ret = i2c_smbus_write_byte_data(client, reg, val);
125*4882a593Smuzhiyun if (ret == 0)
126*4882a593Smuzhiyun return 0;
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun v4l2_err(sd, "%s: failed reg 0x%x, val 0x%x\n", __func__, reg, val);
129*4882a593Smuzhiyun return ret;
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun /* To set specific bits in the register, a clear-mask is given (to be AND-ed),
133*4882a593Smuzhiyun and then the value-mask (to be OR-ed). */
ad9389b_wr_and_or(struct v4l2_subdev * sd,u8 reg,u8 clr_mask,u8 val_mask)134*4882a593Smuzhiyun static inline void ad9389b_wr_and_or(struct v4l2_subdev *sd, u8 reg,
135*4882a593Smuzhiyun u8 clr_mask, u8 val_mask)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun ad9389b_wr(sd, reg, (ad9389b_rd(sd, reg) & clr_mask) | val_mask);
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun
ad9389b_edid_rd(struct v4l2_subdev * sd,u16 len,u8 * buf)140*4882a593Smuzhiyun static void ad9389b_edid_rd(struct v4l2_subdev *sd, u16 len, u8 *buf)
141*4882a593Smuzhiyun {
142*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
143*4882a593Smuzhiyun int i;
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s:\n", __func__);
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun for (i = 0; i < len; i++)
148*4882a593Smuzhiyun buf[i] = i2c_smbus_read_byte_data(state->edid_i2c_client, i);
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun
ad9389b_have_hotplug(struct v4l2_subdev * sd)151*4882a593Smuzhiyun static inline bool ad9389b_have_hotplug(struct v4l2_subdev *sd)
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun return ad9389b_rd(sd, 0x42) & MASK_AD9389B_HPD_DETECT;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
ad9389b_have_rx_sense(struct v4l2_subdev * sd)156*4882a593Smuzhiyun static inline bool ad9389b_have_rx_sense(struct v4l2_subdev *sd)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun return ad9389b_rd(sd, 0x42) & MASK_AD9389B_MSEN_DETECT;
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun
ad9389b_csc_conversion_mode(struct v4l2_subdev * sd,u8 mode)161*4882a593Smuzhiyun static void ad9389b_csc_conversion_mode(struct v4l2_subdev *sd, u8 mode)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x17, 0xe7, (mode & 0x3)<<3);
164*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x18, 0x9f, (mode & 0x3)<<5);
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
ad9389b_csc_coeff(struct v4l2_subdev * sd,u16 A1,u16 A2,u16 A3,u16 A4,u16 B1,u16 B2,u16 B3,u16 B4,u16 C1,u16 C2,u16 C3,u16 C4)167*4882a593Smuzhiyun static void ad9389b_csc_coeff(struct v4l2_subdev *sd,
168*4882a593Smuzhiyun u16 A1, u16 A2, u16 A3, u16 A4,
169*4882a593Smuzhiyun u16 B1, u16 B2, u16 B3, u16 B4,
170*4882a593Smuzhiyun u16 C1, u16 C2, u16 C3, u16 C4)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun /* A */
173*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x18, 0xe0, A1>>8);
174*4882a593Smuzhiyun ad9389b_wr(sd, 0x19, A1);
175*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x1A, 0xe0, A2>>8);
176*4882a593Smuzhiyun ad9389b_wr(sd, 0x1B, A2);
177*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x1c, 0xe0, A3>>8);
178*4882a593Smuzhiyun ad9389b_wr(sd, 0x1d, A3);
179*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x1e, 0xe0, A4>>8);
180*4882a593Smuzhiyun ad9389b_wr(sd, 0x1f, A4);
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun /* B */
183*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x20, 0xe0, B1>>8);
184*4882a593Smuzhiyun ad9389b_wr(sd, 0x21, B1);
185*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x22, 0xe0, B2>>8);
186*4882a593Smuzhiyun ad9389b_wr(sd, 0x23, B2);
187*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x24, 0xe0, B3>>8);
188*4882a593Smuzhiyun ad9389b_wr(sd, 0x25, B3);
189*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x26, 0xe0, B4>>8);
190*4882a593Smuzhiyun ad9389b_wr(sd, 0x27, B4);
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun /* C */
193*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x28, 0xe0, C1>>8);
194*4882a593Smuzhiyun ad9389b_wr(sd, 0x29, C1);
195*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x2A, 0xe0, C2>>8);
196*4882a593Smuzhiyun ad9389b_wr(sd, 0x2B, C2);
197*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x2C, 0xe0, C3>>8);
198*4882a593Smuzhiyun ad9389b_wr(sd, 0x2D, C3);
199*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x2E, 0xe0, C4>>8);
200*4882a593Smuzhiyun ad9389b_wr(sd, 0x2F, C4);
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun
ad9389b_csc_rgb_full2limit(struct v4l2_subdev * sd,bool enable)203*4882a593Smuzhiyun static void ad9389b_csc_rgb_full2limit(struct v4l2_subdev *sd, bool enable)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun if (enable) {
206*4882a593Smuzhiyun u8 csc_mode = 0;
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun ad9389b_csc_conversion_mode(sd, csc_mode);
209*4882a593Smuzhiyun ad9389b_csc_coeff(sd,
210*4882a593Smuzhiyun 4096-564, 0, 0, 256,
211*4882a593Smuzhiyun 0, 4096-564, 0, 256,
212*4882a593Smuzhiyun 0, 0, 4096-564, 256);
213*4882a593Smuzhiyun /* enable CSC */
214*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x3b, 0xfe, 0x1);
215*4882a593Smuzhiyun /* AVI infoframe: Limited range RGB (16-235) */
216*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0xcd, 0xf9, 0x02);
217*4882a593Smuzhiyun } else {
218*4882a593Smuzhiyun /* disable CSC */
219*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x3b, 0xfe, 0x0);
220*4882a593Smuzhiyun /* AVI infoframe: Full range RGB (0-255) */
221*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0xcd, 0xf9, 0x04);
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun
ad9389b_set_IT_content_AVI_InfoFrame(struct v4l2_subdev * sd)225*4882a593Smuzhiyun static void ad9389b_set_IT_content_AVI_InfoFrame(struct v4l2_subdev *sd)
226*4882a593Smuzhiyun {
227*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun if (state->dv_timings.bt.flags & V4L2_DV_FL_IS_CE_VIDEO) {
230*4882a593Smuzhiyun /* CE format, not IT */
231*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0xcd, 0xbf, 0x00);
232*4882a593Smuzhiyun } else {
233*4882a593Smuzhiyun /* IT format */
234*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0xcd, 0xbf, 0x40);
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun
ad9389b_set_rgb_quantization_mode(struct v4l2_subdev * sd,struct v4l2_ctrl * ctrl)238*4882a593Smuzhiyun static int ad9389b_set_rgb_quantization_mode(struct v4l2_subdev *sd, struct v4l2_ctrl *ctrl)
239*4882a593Smuzhiyun {
240*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun switch (ctrl->val) {
243*4882a593Smuzhiyun case V4L2_DV_RGB_RANGE_AUTO:
244*4882a593Smuzhiyun /* automatic */
245*4882a593Smuzhiyun if (state->dv_timings.bt.flags & V4L2_DV_FL_IS_CE_VIDEO) {
246*4882a593Smuzhiyun /* CE format, RGB limited range (16-235) */
247*4882a593Smuzhiyun ad9389b_csc_rgb_full2limit(sd, true);
248*4882a593Smuzhiyun } else {
249*4882a593Smuzhiyun /* not CE format, RGB full range (0-255) */
250*4882a593Smuzhiyun ad9389b_csc_rgb_full2limit(sd, false);
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun break;
253*4882a593Smuzhiyun case V4L2_DV_RGB_RANGE_LIMITED:
254*4882a593Smuzhiyun /* RGB limited range (16-235) */
255*4882a593Smuzhiyun ad9389b_csc_rgb_full2limit(sd, true);
256*4882a593Smuzhiyun break;
257*4882a593Smuzhiyun case V4L2_DV_RGB_RANGE_FULL:
258*4882a593Smuzhiyun /* RGB full range (0-255) */
259*4882a593Smuzhiyun ad9389b_csc_rgb_full2limit(sd, false);
260*4882a593Smuzhiyun break;
261*4882a593Smuzhiyun default:
262*4882a593Smuzhiyun return -EINVAL;
263*4882a593Smuzhiyun }
264*4882a593Smuzhiyun return 0;
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun
ad9389b_set_manual_pll_gear(struct v4l2_subdev * sd,u32 pixelclock)267*4882a593Smuzhiyun static void ad9389b_set_manual_pll_gear(struct v4l2_subdev *sd, u32 pixelclock)
268*4882a593Smuzhiyun {
269*4882a593Smuzhiyun u8 gear;
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun /* Workaround for TMDS PLL problem
272*4882a593Smuzhiyun * The TMDS PLL in AD9389b change gear when the chip is heated above a
273*4882a593Smuzhiyun * certain temperature. The output is disabled when the PLL change gear
274*4882a593Smuzhiyun * so the monitor has to lock on the signal again. A workaround for
275*4882a593Smuzhiyun * this is to use the manual PLL gears. This is a solution from Analog
276*4882a593Smuzhiyun * Devices that is not documented in the datasheets.
277*4882a593Smuzhiyun * 0x98 [7] = enable manual gearing. 0x98 [6:4] = gear
278*4882a593Smuzhiyun *
279*4882a593Smuzhiyun * The pixel frequency ranges are based on readout of the gear the
280*4882a593Smuzhiyun * automatic gearing selects for different pixel clocks
281*4882a593Smuzhiyun * (read from 0x9e [3:1]).
282*4882a593Smuzhiyun */
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun if (pixelclock > 140000000)
285*4882a593Smuzhiyun gear = 0xc0; /* 4th gear */
286*4882a593Smuzhiyun else if (pixelclock > 117000000)
287*4882a593Smuzhiyun gear = 0xb0; /* 3rd gear */
288*4882a593Smuzhiyun else if (pixelclock > 87000000)
289*4882a593Smuzhiyun gear = 0xa0; /* 2nd gear */
290*4882a593Smuzhiyun else if (pixelclock > 60000000)
291*4882a593Smuzhiyun gear = 0x90; /* 1st gear */
292*4882a593Smuzhiyun else
293*4882a593Smuzhiyun gear = 0x80; /* 0th gear */
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x98, 0x0f, gear);
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun /* ------------------------------ CTRL OPS ------------------------------ */
299*4882a593Smuzhiyun
ad9389b_s_ctrl(struct v4l2_ctrl * ctrl)300*4882a593Smuzhiyun static int ad9389b_s_ctrl(struct v4l2_ctrl *ctrl)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun struct v4l2_subdev *sd = to_sd(ctrl);
303*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun v4l2_dbg(1, debug, sd,
306*4882a593Smuzhiyun "%s: ctrl id: %d, ctrl->val %d\n", __func__, ctrl->id, ctrl->val);
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun if (state->hdmi_mode_ctrl == ctrl) {
309*4882a593Smuzhiyun /* Set HDMI or DVI-D */
310*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0xaf, 0xfd,
311*4882a593Smuzhiyun ctrl->val == V4L2_DV_TX_MODE_HDMI ? 0x02 : 0x00);
312*4882a593Smuzhiyun return 0;
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun if (state->rgb_quantization_range_ctrl == ctrl)
315*4882a593Smuzhiyun return ad9389b_set_rgb_quantization_mode(sd, ctrl);
316*4882a593Smuzhiyun return -EINVAL;
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun static const struct v4l2_ctrl_ops ad9389b_ctrl_ops = {
320*4882a593Smuzhiyun .s_ctrl = ad9389b_s_ctrl,
321*4882a593Smuzhiyun };
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun /* ---------------------------- CORE OPS ------------------------------------------- */
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun #ifdef CONFIG_VIDEO_ADV_DEBUG
ad9389b_g_register(struct v4l2_subdev * sd,struct v4l2_dbg_register * reg)326*4882a593Smuzhiyun static int ad9389b_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun reg->val = ad9389b_rd(sd, reg->reg & 0xff);
329*4882a593Smuzhiyun reg->size = 1;
330*4882a593Smuzhiyun return 0;
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun
ad9389b_s_register(struct v4l2_subdev * sd,const struct v4l2_dbg_register * reg)333*4882a593Smuzhiyun static int ad9389b_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
334*4882a593Smuzhiyun {
335*4882a593Smuzhiyun ad9389b_wr(sd, reg->reg & 0xff, reg->val & 0xff);
336*4882a593Smuzhiyun return 0;
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun #endif
339*4882a593Smuzhiyun
ad9389b_log_status(struct v4l2_subdev * sd)340*4882a593Smuzhiyun static int ad9389b_log_status(struct v4l2_subdev *sd)
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
343*4882a593Smuzhiyun struct ad9389b_state_edid *edid = &state->edid;
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun static const char * const states[] = {
346*4882a593Smuzhiyun "in reset",
347*4882a593Smuzhiyun "reading EDID",
348*4882a593Smuzhiyun "idle",
349*4882a593Smuzhiyun "initializing HDCP",
350*4882a593Smuzhiyun "HDCP enabled",
351*4882a593Smuzhiyun "initializing HDCP repeater",
352*4882a593Smuzhiyun "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"
353*4882a593Smuzhiyun };
354*4882a593Smuzhiyun static const char * const errors[] = {
355*4882a593Smuzhiyun "no error",
356*4882a593Smuzhiyun "bad receiver BKSV",
357*4882a593Smuzhiyun "Ri mismatch",
358*4882a593Smuzhiyun "Pj mismatch",
359*4882a593Smuzhiyun "i2c error",
360*4882a593Smuzhiyun "timed out",
361*4882a593Smuzhiyun "max repeater cascade exceeded",
362*4882a593Smuzhiyun "hash check failed",
363*4882a593Smuzhiyun "too many devices",
364*4882a593Smuzhiyun "9", "A", "B", "C", "D", "E", "F"
365*4882a593Smuzhiyun };
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun u8 manual_gear;
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun v4l2_info(sd, "chip revision %d\n", state->chip_revision);
370*4882a593Smuzhiyun v4l2_info(sd, "power %s\n", state->power_on ? "on" : "off");
371*4882a593Smuzhiyun v4l2_info(sd, "%s hotplug, %s Rx Sense, %s EDID (%d block(s))\n",
372*4882a593Smuzhiyun (ad9389b_rd(sd, 0x42) & MASK_AD9389B_HPD_DETECT) ?
373*4882a593Smuzhiyun "detected" : "no",
374*4882a593Smuzhiyun (ad9389b_rd(sd, 0x42) & MASK_AD9389B_MSEN_DETECT) ?
375*4882a593Smuzhiyun "detected" : "no",
376*4882a593Smuzhiyun edid->segments ? "found" : "no", edid->blocks);
377*4882a593Smuzhiyun v4l2_info(sd, "%s output %s\n",
378*4882a593Smuzhiyun (ad9389b_rd(sd, 0xaf) & 0x02) ?
379*4882a593Smuzhiyun "HDMI" : "DVI-D",
380*4882a593Smuzhiyun (ad9389b_rd(sd, 0xa1) & 0x3c) ?
381*4882a593Smuzhiyun "disabled" : "enabled");
382*4882a593Smuzhiyun v4l2_info(sd, "ad9389b: %s\n", (ad9389b_rd(sd, 0xb8) & 0x40) ?
383*4882a593Smuzhiyun "encrypted" : "no encryption");
384*4882a593Smuzhiyun v4l2_info(sd, "state: %s, error: %s, detect count: %u, msk/irq: %02x/%02x\n",
385*4882a593Smuzhiyun states[ad9389b_rd(sd, 0xc8) & 0xf],
386*4882a593Smuzhiyun errors[ad9389b_rd(sd, 0xc8) >> 4],
387*4882a593Smuzhiyun state->edid_detect_counter,
388*4882a593Smuzhiyun ad9389b_rd(sd, 0x94), ad9389b_rd(sd, 0x96));
389*4882a593Smuzhiyun manual_gear = ad9389b_rd(sd, 0x98) & 0x80;
390*4882a593Smuzhiyun v4l2_info(sd, "ad9389b: RGB quantization: %s range\n",
391*4882a593Smuzhiyun ad9389b_rd(sd, 0x3b) & 0x01 ? "limited" : "full");
392*4882a593Smuzhiyun v4l2_info(sd, "ad9389b: %s gear %d\n",
393*4882a593Smuzhiyun manual_gear ? "manual" : "automatic",
394*4882a593Smuzhiyun manual_gear ? ((ad9389b_rd(sd, 0x98) & 0x70) >> 4) :
395*4882a593Smuzhiyun ((ad9389b_rd(sd, 0x9e) & 0x0e) >> 1));
396*4882a593Smuzhiyun if (ad9389b_rd(sd, 0xaf) & 0x02) {
397*4882a593Smuzhiyun /* HDMI only */
398*4882a593Smuzhiyun u8 manual_cts = ad9389b_rd(sd, 0x0a) & 0x80;
399*4882a593Smuzhiyun u32 N = (ad9389b_rd(sd, 0x01) & 0xf) << 16 |
400*4882a593Smuzhiyun ad9389b_rd(sd, 0x02) << 8 |
401*4882a593Smuzhiyun ad9389b_rd(sd, 0x03);
402*4882a593Smuzhiyun u8 vic_detect = ad9389b_rd(sd, 0x3e) >> 2;
403*4882a593Smuzhiyun u8 vic_sent = ad9389b_rd(sd, 0x3d) & 0x3f;
404*4882a593Smuzhiyun u32 CTS;
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun if (manual_cts)
407*4882a593Smuzhiyun CTS = (ad9389b_rd(sd, 0x07) & 0xf) << 16 |
408*4882a593Smuzhiyun ad9389b_rd(sd, 0x08) << 8 |
409*4882a593Smuzhiyun ad9389b_rd(sd, 0x09);
410*4882a593Smuzhiyun else
411*4882a593Smuzhiyun CTS = (ad9389b_rd(sd, 0x04) & 0xf) << 16 |
412*4882a593Smuzhiyun ad9389b_rd(sd, 0x05) << 8 |
413*4882a593Smuzhiyun ad9389b_rd(sd, 0x06);
414*4882a593Smuzhiyun N = (ad9389b_rd(sd, 0x01) & 0xf) << 16 |
415*4882a593Smuzhiyun ad9389b_rd(sd, 0x02) << 8 |
416*4882a593Smuzhiyun ad9389b_rd(sd, 0x03);
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun v4l2_info(sd, "ad9389b: CTS %s mode: N %d, CTS %d\n",
419*4882a593Smuzhiyun manual_cts ? "manual" : "automatic", N, CTS);
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun v4l2_info(sd, "ad9389b: VIC: detected %d, sent %d\n",
422*4882a593Smuzhiyun vic_detect, vic_sent);
423*4882a593Smuzhiyun }
424*4882a593Smuzhiyun if (state->dv_timings.type == V4L2_DV_BT_656_1120)
425*4882a593Smuzhiyun v4l2_print_dv_timings(sd->name, "timings: ",
426*4882a593Smuzhiyun &state->dv_timings, false);
427*4882a593Smuzhiyun else
428*4882a593Smuzhiyun v4l2_info(sd, "no timings set\n");
429*4882a593Smuzhiyun return 0;
430*4882a593Smuzhiyun }
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun /* Power up/down ad9389b */
ad9389b_s_power(struct v4l2_subdev * sd,int on)433*4882a593Smuzhiyun static int ad9389b_s_power(struct v4l2_subdev *sd, int on)
434*4882a593Smuzhiyun {
435*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
436*4882a593Smuzhiyun struct ad9389b_platform_data *pdata = &state->pdata;
437*4882a593Smuzhiyun const int retries = 20;
438*4882a593Smuzhiyun int i;
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s: power %s\n", __func__, on ? "on" : "off");
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun state->power_on = on;
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun if (!on) {
445*4882a593Smuzhiyun /* Power down */
446*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x41, 0xbf, 0x40);
447*4882a593Smuzhiyun return true;
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun /* Power up */
451*4882a593Smuzhiyun /* The ad9389b does not always come up immediately.
452*4882a593Smuzhiyun Retry multiple times. */
453*4882a593Smuzhiyun for (i = 0; i < retries; i++) {
454*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x41, 0xbf, 0x0);
455*4882a593Smuzhiyun if ((ad9389b_rd(sd, 0x41) & 0x40) == 0)
456*4882a593Smuzhiyun break;
457*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x41, 0xbf, 0x40);
458*4882a593Smuzhiyun msleep(10);
459*4882a593Smuzhiyun }
460*4882a593Smuzhiyun if (i == retries) {
461*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "failed to powerup the ad9389b\n");
462*4882a593Smuzhiyun ad9389b_s_power(sd, 0);
463*4882a593Smuzhiyun return false;
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun if (i > 1)
466*4882a593Smuzhiyun v4l2_dbg(1, debug, sd,
467*4882a593Smuzhiyun "needed %d retries to powerup the ad9389b\n", i);
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun /* Select chip: AD9389B */
470*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0xba, 0xef, 0x10);
471*4882a593Smuzhiyun
472*4882a593Smuzhiyun /* Reserved registers that must be set according to REF_01 p. 11*/
473*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x98, 0xf0, 0x07);
474*4882a593Smuzhiyun ad9389b_wr(sd, 0x9c, 0x38);
475*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x9d, 0xfc, 0x01);
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun /* Differential output drive strength */
478*4882a593Smuzhiyun if (pdata->diff_data_drive_strength > 0)
479*4882a593Smuzhiyun ad9389b_wr(sd, 0xa2, pdata->diff_data_drive_strength);
480*4882a593Smuzhiyun else
481*4882a593Smuzhiyun ad9389b_wr(sd, 0xa2, 0x87);
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun if (pdata->diff_clk_drive_strength > 0)
484*4882a593Smuzhiyun ad9389b_wr(sd, 0xa3, pdata->diff_clk_drive_strength);
485*4882a593Smuzhiyun else
486*4882a593Smuzhiyun ad9389b_wr(sd, 0xa3, 0x87);
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun ad9389b_wr(sd, 0x0a, 0x01);
489*4882a593Smuzhiyun ad9389b_wr(sd, 0xbb, 0xff);
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun /* Set number of attempts to read the EDID */
492*4882a593Smuzhiyun ad9389b_wr(sd, 0xc9, 0xf);
493*4882a593Smuzhiyun return true;
494*4882a593Smuzhiyun }
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun /* Enable interrupts */
ad9389b_set_isr(struct v4l2_subdev * sd,bool enable)497*4882a593Smuzhiyun static void ad9389b_set_isr(struct v4l2_subdev *sd, bool enable)
498*4882a593Smuzhiyun {
499*4882a593Smuzhiyun u8 irqs = MASK_AD9389B_HPD_INT | MASK_AD9389B_MSEN_INT;
500*4882a593Smuzhiyun u8 irqs_rd;
501*4882a593Smuzhiyun int retries = 100;
502*4882a593Smuzhiyun
503*4882a593Smuzhiyun /* The datasheet says that the EDID ready interrupt should be
504*4882a593Smuzhiyun disabled if there is no hotplug. */
505*4882a593Smuzhiyun if (!enable)
506*4882a593Smuzhiyun irqs = 0;
507*4882a593Smuzhiyun else if (ad9389b_have_hotplug(sd))
508*4882a593Smuzhiyun irqs |= MASK_AD9389B_EDID_RDY_INT;
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun /*
511*4882a593Smuzhiyun * This i2c write can fail (approx. 1 in 1000 writes). But it
512*4882a593Smuzhiyun * is essential that this register is correct, so retry it
513*4882a593Smuzhiyun * multiple times.
514*4882a593Smuzhiyun *
515*4882a593Smuzhiyun * Note that the i2c write does not report an error, but the readback
516*4882a593Smuzhiyun * clearly shows the wrong value.
517*4882a593Smuzhiyun */
518*4882a593Smuzhiyun do {
519*4882a593Smuzhiyun ad9389b_wr(sd, 0x94, irqs);
520*4882a593Smuzhiyun irqs_rd = ad9389b_rd(sd, 0x94);
521*4882a593Smuzhiyun } while (retries-- && irqs_rd != irqs);
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun if (irqs_rd != irqs)
524*4882a593Smuzhiyun v4l2_err(sd, "Could not set interrupts: hw failure?\n");
525*4882a593Smuzhiyun }
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun /* Interrupt handler */
ad9389b_isr(struct v4l2_subdev * sd,u32 status,bool * handled)528*4882a593Smuzhiyun static int ad9389b_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
529*4882a593Smuzhiyun {
530*4882a593Smuzhiyun u8 irq_status;
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun /* disable interrupts to prevent a race condition */
533*4882a593Smuzhiyun ad9389b_set_isr(sd, false);
534*4882a593Smuzhiyun irq_status = ad9389b_rd(sd, 0x96);
535*4882a593Smuzhiyun /* clear detected interrupts */
536*4882a593Smuzhiyun ad9389b_wr(sd, 0x96, irq_status);
537*4882a593Smuzhiyun /* enable interrupts */
538*4882a593Smuzhiyun ad9389b_set_isr(sd, true);
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s: irq_status 0x%x\n", __func__, irq_status);
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun if (irq_status & (MASK_AD9389B_HPD_INT))
543*4882a593Smuzhiyun ad9389b_check_monitor_present_status(sd);
544*4882a593Smuzhiyun if (irq_status & MASK_AD9389B_EDID_RDY_INT)
545*4882a593Smuzhiyun ad9389b_check_edid_status(sd);
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun *handled = true;
548*4882a593Smuzhiyun return 0;
549*4882a593Smuzhiyun }
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun static const struct v4l2_subdev_core_ops ad9389b_core_ops = {
552*4882a593Smuzhiyun .log_status = ad9389b_log_status,
553*4882a593Smuzhiyun #ifdef CONFIG_VIDEO_ADV_DEBUG
554*4882a593Smuzhiyun .g_register = ad9389b_g_register,
555*4882a593Smuzhiyun .s_register = ad9389b_s_register,
556*4882a593Smuzhiyun #endif
557*4882a593Smuzhiyun .s_power = ad9389b_s_power,
558*4882a593Smuzhiyun .interrupt_service_routine = ad9389b_isr,
559*4882a593Smuzhiyun };
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun /* ------------------------------ VIDEO OPS ------------------------------ */
562*4882a593Smuzhiyun
563*4882a593Smuzhiyun /* Enable/disable ad9389b output */
ad9389b_s_stream(struct v4l2_subdev * sd,int enable)564*4882a593Smuzhiyun static int ad9389b_s_stream(struct v4l2_subdev *sd, int enable)
565*4882a593Smuzhiyun {
566*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s: %sable\n", __func__, (enable ? "en" : "dis"));
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0xa1, ~0x3c, (enable ? 0 : 0x3c));
569*4882a593Smuzhiyun if (enable) {
570*4882a593Smuzhiyun ad9389b_check_monitor_present_status(sd);
571*4882a593Smuzhiyun } else {
572*4882a593Smuzhiyun ad9389b_s_power(sd, 0);
573*4882a593Smuzhiyun }
574*4882a593Smuzhiyun return 0;
575*4882a593Smuzhiyun }
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun static const struct v4l2_dv_timings_cap ad9389b_timings_cap = {
578*4882a593Smuzhiyun .type = V4L2_DV_BT_656_1120,
579*4882a593Smuzhiyun /* keep this initialization for compatibility with GCC < 4.4.6 */
580*4882a593Smuzhiyun .reserved = { 0 },
581*4882a593Smuzhiyun V4L2_INIT_BT_TIMINGS(640, 1920, 350, 1200, 25000000, 170000000,
582*4882a593Smuzhiyun V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
583*4882a593Smuzhiyun V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT,
584*4882a593Smuzhiyun V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_REDUCED_BLANKING |
585*4882a593Smuzhiyun V4L2_DV_BT_CAP_CUSTOM)
586*4882a593Smuzhiyun };
587*4882a593Smuzhiyun
ad9389b_s_dv_timings(struct v4l2_subdev * sd,struct v4l2_dv_timings * timings)588*4882a593Smuzhiyun static int ad9389b_s_dv_timings(struct v4l2_subdev *sd,
589*4882a593Smuzhiyun struct v4l2_dv_timings *timings)
590*4882a593Smuzhiyun {
591*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s:\n", __func__);
594*4882a593Smuzhiyun
595*4882a593Smuzhiyun /* quick sanity check */
596*4882a593Smuzhiyun if (!v4l2_valid_dv_timings(timings, &ad9389b_timings_cap, NULL, NULL))
597*4882a593Smuzhiyun return -EINVAL;
598*4882a593Smuzhiyun
599*4882a593Smuzhiyun /* Fill the optional fields .standards and .flags in struct v4l2_dv_timings
600*4882a593Smuzhiyun if the format is one of the CEA or DMT timings. */
601*4882a593Smuzhiyun v4l2_find_dv_timings_cap(timings, &ad9389b_timings_cap, 0, NULL, NULL);
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun timings->bt.flags &= ~V4L2_DV_FL_REDUCED_FPS;
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun /* save timings */
606*4882a593Smuzhiyun state->dv_timings = *timings;
607*4882a593Smuzhiyun
608*4882a593Smuzhiyun /* update quantization range based on new dv_timings */
609*4882a593Smuzhiyun ad9389b_set_rgb_quantization_mode(sd, state->rgb_quantization_range_ctrl);
610*4882a593Smuzhiyun
611*4882a593Smuzhiyun /* update PLL gear based on new dv_timings */
612*4882a593Smuzhiyun if (state->pdata.tmds_pll_gear == AD9389B_TMDS_PLL_GEAR_SEMI_AUTOMATIC)
613*4882a593Smuzhiyun ad9389b_set_manual_pll_gear(sd, (u32)timings->bt.pixelclock);
614*4882a593Smuzhiyun
615*4882a593Smuzhiyun /* update AVI infoframe */
616*4882a593Smuzhiyun ad9389b_set_IT_content_AVI_InfoFrame(sd);
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun return 0;
619*4882a593Smuzhiyun }
620*4882a593Smuzhiyun
ad9389b_g_dv_timings(struct v4l2_subdev * sd,struct v4l2_dv_timings * timings)621*4882a593Smuzhiyun static int ad9389b_g_dv_timings(struct v4l2_subdev *sd,
622*4882a593Smuzhiyun struct v4l2_dv_timings *timings)
623*4882a593Smuzhiyun {
624*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s:\n", __func__);
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun if (!timings)
629*4882a593Smuzhiyun return -EINVAL;
630*4882a593Smuzhiyun
631*4882a593Smuzhiyun *timings = state->dv_timings;
632*4882a593Smuzhiyun
633*4882a593Smuzhiyun return 0;
634*4882a593Smuzhiyun }
635*4882a593Smuzhiyun
ad9389b_enum_dv_timings(struct v4l2_subdev * sd,struct v4l2_enum_dv_timings * timings)636*4882a593Smuzhiyun static int ad9389b_enum_dv_timings(struct v4l2_subdev *sd,
637*4882a593Smuzhiyun struct v4l2_enum_dv_timings *timings)
638*4882a593Smuzhiyun {
639*4882a593Smuzhiyun if (timings->pad != 0)
640*4882a593Smuzhiyun return -EINVAL;
641*4882a593Smuzhiyun
642*4882a593Smuzhiyun return v4l2_enum_dv_timings_cap(timings, &ad9389b_timings_cap,
643*4882a593Smuzhiyun NULL, NULL);
644*4882a593Smuzhiyun }
645*4882a593Smuzhiyun
ad9389b_dv_timings_cap(struct v4l2_subdev * sd,struct v4l2_dv_timings_cap * cap)646*4882a593Smuzhiyun static int ad9389b_dv_timings_cap(struct v4l2_subdev *sd,
647*4882a593Smuzhiyun struct v4l2_dv_timings_cap *cap)
648*4882a593Smuzhiyun {
649*4882a593Smuzhiyun if (cap->pad != 0)
650*4882a593Smuzhiyun return -EINVAL;
651*4882a593Smuzhiyun
652*4882a593Smuzhiyun *cap = ad9389b_timings_cap;
653*4882a593Smuzhiyun return 0;
654*4882a593Smuzhiyun }
655*4882a593Smuzhiyun
656*4882a593Smuzhiyun static const struct v4l2_subdev_video_ops ad9389b_video_ops = {
657*4882a593Smuzhiyun .s_stream = ad9389b_s_stream,
658*4882a593Smuzhiyun .s_dv_timings = ad9389b_s_dv_timings,
659*4882a593Smuzhiyun .g_dv_timings = ad9389b_g_dv_timings,
660*4882a593Smuzhiyun };
661*4882a593Smuzhiyun
662*4882a593Smuzhiyun /* ------------------------------ PAD OPS ------------------------------ */
663*4882a593Smuzhiyun
ad9389b_get_edid(struct v4l2_subdev * sd,struct v4l2_edid * edid)664*4882a593Smuzhiyun static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
665*4882a593Smuzhiyun {
666*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
667*4882a593Smuzhiyun
668*4882a593Smuzhiyun if (edid->pad != 0)
669*4882a593Smuzhiyun return -EINVAL;
670*4882a593Smuzhiyun if (edid->blocks == 0 || edid->blocks > 256)
671*4882a593Smuzhiyun return -EINVAL;
672*4882a593Smuzhiyun if (!state->edid.segments) {
673*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n");
674*4882a593Smuzhiyun return -ENODATA;
675*4882a593Smuzhiyun }
676*4882a593Smuzhiyun if (edid->start_block >= state->edid.segments * 2)
677*4882a593Smuzhiyun return -E2BIG;
678*4882a593Smuzhiyun if (edid->blocks + edid->start_block >= state->edid.segments * 2)
679*4882a593Smuzhiyun edid->blocks = state->edid.segments * 2 - edid->start_block;
680*4882a593Smuzhiyun memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
681*4882a593Smuzhiyun 128 * edid->blocks);
682*4882a593Smuzhiyun return 0;
683*4882a593Smuzhiyun }
684*4882a593Smuzhiyun
685*4882a593Smuzhiyun static const struct v4l2_subdev_pad_ops ad9389b_pad_ops = {
686*4882a593Smuzhiyun .get_edid = ad9389b_get_edid,
687*4882a593Smuzhiyun .enum_dv_timings = ad9389b_enum_dv_timings,
688*4882a593Smuzhiyun .dv_timings_cap = ad9389b_dv_timings_cap,
689*4882a593Smuzhiyun };
690*4882a593Smuzhiyun
691*4882a593Smuzhiyun /* ------------------------------ AUDIO OPS ------------------------------ */
692*4882a593Smuzhiyun
ad9389b_s_audio_stream(struct v4l2_subdev * sd,int enable)693*4882a593Smuzhiyun static int ad9389b_s_audio_stream(struct v4l2_subdev *sd, int enable)
694*4882a593Smuzhiyun {
695*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s: %sable\n", __func__, (enable ? "en" : "dis"));
696*4882a593Smuzhiyun
697*4882a593Smuzhiyun if (enable)
698*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x45, 0x3f, 0x80);
699*4882a593Smuzhiyun else
700*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x45, 0x3f, 0x40);
701*4882a593Smuzhiyun
702*4882a593Smuzhiyun return 0;
703*4882a593Smuzhiyun }
704*4882a593Smuzhiyun
ad9389b_s_clock_freq(struct v4l2_subdev * sd,u32 freq)705*4882a593Smuzhiyun static int ad9389b_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
706*4882a593Smuzhiyun {
707*4882a593Smuzhiyun u32 N;
708*4882a593Smuzhiyun
709*4882a593Smuzhiyun switch (freq) {
710*4882a593Smuzhiyun case 32000: N = 4096; break;
711*4882a593Smuzhiyun case 44100: N = 6272; break;
712*4882a593Smuzhiyun case 48000: N = 6144; break;
713*4882a593Smuzhiyun case 88200: N = 12544; break;
714*4882a593Smuzhiyun case 96000: N = 12288; break;
715*4882a593Smuzhiyun case 176400: N = 25088; break;
716*4882a593Smuzhiyun case 192000: N = 24576; break;
717*4882a593Smuzhiyun default:
718*4882a593Smuzhiyun return -EINVAL;
719*4882a593Smuzhiyun }
720*4882a593Smuzhiyun
721*4882a593Smuzhiyun /* Set N (used with CTS to regenerate the audio clock) */
722*4882a593Smuzhiyun ad9389b_wr(sd, 0x01, (N >> 16) & 0xf);
723*4882a593Smuzhiyun ad9389b_wr(sd, 0x02, (N >> 8) & 0xff);
724*4882a593Smuzhiyun ad9389b_wr(sd, 0x03, N & 0xff);
725*4882a593Smuzhiyun
726*4882a593Smuzhiyun return 0;
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun
ad9389b_s_i2s_clock_freq(struct v4l2_subdev * sd,u32 freq)729*4882a593Smuzhiyun static int ad9389b_s_i2s_clock_freq(struct v4l2_subdev *sd, u32 freq)
730*4882a593Smuzhiyun {
731*4882a593Smuzhiyun u32 i2s_sf;
732*4882a593Smuzhiyun
733*4882a593Smuzhiyun switch (freq) {
734*4882a593Smuzhiyun case 32000: i2s_sf = 0x30; break;
735*4882a593Smuzhiyun case 44100: i2s_sf = 0x00; break;
736*4882a593Smuzhiyun case 48000: i2s_sf = 0x20; break;
737*4882a593Smuzhiyun case 88200: i2s_sf = 0x80; break;
738*4882a593Smuzhiyun case 96000: i2s_sf = 0xa0; break;
739*4882a593Smuzhiyun case 176400: i2s_sf = 0xc0; break;
740*4882a593Smuzhiyun case 192000: i2s_sf = 0xe0; break;
741*4882a593Smuzhiyun default:
742*4882a593Smuzhiyun return -EINVAL;
743*4882a593Smuzhiyun }
744*4882a593Smuzhiyun
745*4882a593Smuzhiyun /* Set sampling frequency for I2S audio to 48 kHz */
746*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x15, 0xf, i2s_sf);
747*4882a593Smuzhiyun
748*4882a593Smuzhiyun return 0;
749*4882a593Smuzhiyun }
750*4882a593Smuzhiyun
ad9389b_s_routing(struct v4l2_subdev * sd,u32 input,u32 output,u32 config)751*4882a593Smuzhiyun static int ad9389b_s_routing(struct v4l2_subdev *sd, u32 input, u32 output, u32 config)
752*4882a593Smuzhiyun {
753*4882a593Smuzhiyun /* TODO based on input/output/config */
754*4882a593Smuzhiyun /* TODO See datasheet "Programmers guide" p. 39-40 */
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun /* Only 2 channels in use for application */
757*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x50, 0x1f, 0x20);
758*4882a593Smuzhiyun /* Speaker mapping */
759*4882a593Smuzhiyun ad9389b_wr(sd, 0x51, 0x00);
760*4882a593Smuzhiyun
761*4882a593Smuzhiyun /* TODO Where should this be placed? */
762*4882a593Smuzhiyun /* 16 bit audio word length */
763*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x14, 0xf0, 0x02);
764*4882a593Smuzhiyun
765*4882a593Smuzhiyun return 0;
766*4882a593Smuzhiyun }
767*4882a593Smuzhiyun
768*4882a593Smuzhiyun static const struct v4l2_subdev_audio_ops ad9389b_audio_ops = {
769*4882a593Smuzhiyun .s_stream = ad9389b_s_audio_stream,
770*4882a593Smuzhiyun .s_clock_freq = ad9389b_s_clock_freq,
771*4882a593Smuzhiyun .s_i2s_clock_freq = ad9389b_s_i2s_clock_freq,
772*4882a593Smuzhiyun .s_routing = ad9389b_s_routing,
773*4882a593Smuzhiyun };
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun /* --------------------- SUBDEV OPS --------------------------------------- */
776*4882a593Smuzhiyun
777*4882a593Smuzhiyun static const struct v4l2_subdev_ops ad9389b_ops = {
778*4882a593Smuzhiyun .core = &ad9389b_core_ops,
779*4882a593Smuzhiyun .video = &ad9389b_video_ops,
780*4882a593Smuzhiyun .audio = &ad9389b_audio_ops,
781*4882a593Smuzhiyun .pad = &ad9389b_pad_ops,
782*4882a593Smuzhiyun };
783*4882a593Smuzhiyun
784*4882a593Smuzhiyun /* ----------------------------------------------------------------------- */
ad9389b_dbg_dump_edid(int lvl,int debug,struct v4l2_subdev * sd,int segment,u8 * buf)785*4882a593Smuzhiyun static void ad9389b_dbg_dump_edid(int lvl, int debug, struct v4l2_subdev *sd,
786*4882a593Smuzhiyun int segment, u8 *buf)
787*4882a593Smuzhiyun {
788*4882a593Smuzhiyun int i, j;
789*4882a593Smuzhiyun
790*4882a593Smuzhiyun if (debug < lvl)
791*4882a593Smuzhiyun return;
792*4882a593Smuzhiyun
793*4882a593Smuzhiyun v4l2_dbg(lvl, debug, sd, "edid segment %d\n", segment);
794*4882a593Smuzhiyun for (i = 0; i < 256; i += 16) {
795*4882a593Smuzhiyun u8 b[128];
796*4882a593Smuzhiyun u8 *bp = b;
797*4882a593Smuzhiyun
798*4882a593Smuzhiyun if (i == 128)
799*4882a593Smuzhiyun v4l2_dbg(lvl, debug, sd, "\n");
800*4882a593Smuzhiyun for (j = i; j < i + 16; j++) {
801*4882a593Smuzhiyun sprintf(bp, "0x%02x, ", buf[j]);
802*4882a593Smuzhiyun bp += 6;
803*4882a593Smuzhiyun }
804*4882a593Smuzhiyun bp[0] = '\0';
805*4882a593Smuzhiyun v4l2_dbg(lvl, debug, sd, "%s\n", b);
806*4882a593Smuzhiyun }
807*4882a593Smuzhiyun }
808*4882a593Smuzhiyun
ad9389b_edid_handler(struct work_struct * work)809*4882a593Smuzhiyun static void ad9389b_edid_handler(struct work_struct *work)
810*4882a593Smuzhiyun {
811*4882a593Smuzhiyun struct delayed_work *dwork = to_delayed_work(work);
812*4882a593Smuzhiyun struct ad9389b_state *state =
813*4882a593Smuzhiyun container_of(dwork, struct ad9389b_state, edid_handler);
814*4882a593Smuzhiyun struct v4l2_subdev *sd = &state->sd;
815*4882a593Smuzhiyun struct ad9389b_edid_detect ed;
816*4882a593Smuzhiyun
817*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s:\n", __func__);
818*4882a593Smuzhiyun
819*4882a593Smuzhiyun if (ad9389b_check_edid_status(sd)) {
820*4882a593Smuzhiyun /* Return if we received the EDID. */
821*4882a593Smuzhiyun return;
822*4882a593Smuzhiyun }
823*4882a593Smuzhiyun
824*4882a593Smuzhiyun if (ad9389b_have_hotplug(sd)) {
825*4882a593Smuzhiyun /* We must retry reading the EDID several times, it is possible
826*4882a593Smuzhiyun * that initially the EDID couldn't be read due to i2c errors
827*4882a593Smuzhiyun * (DVI connectors are particularly prone to this problem). */
828*4882a593Smuzhiyun if (state->edid.read_retries) {
829*4882a593Smuzhiyun state->edid.read_retries--;
830*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s: edid read failed\n", __func__);
831*4882a593Smuzhiyun ad9389b_s_power(sd, false);
832*4882a593Smuzhiyun ad9389b_s_power(sd, true);
833*4882a593Smuzhiyun schedule_delayed_work(&state->edid_handler, EDID_DELAY);
834*4882a593Smuzhiyun return;
835*4882a593Smuzhiyun }
836*4882a593Smuzhiyun }
837*4882a593Smuzhiyun
838*4882a593Smuzhiyun /* We failed to read the EDID, so send an event for this. */
839*4882a593Smuzhiyun ed.present = false;
840*4882a593Smuzhiyun ed.segment = ad9389b_rd(sd, 0xc4);
841*4882a593Smuzhiyun v4l2_subdev_notify(sd, AD9389B_EDID_DETECT, (void *)&ed);
842*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s: no edid found\n", __func__);
843*4882a593Smuzhiyun }
844*4882a593Smuzhiyun
ad9389b_audio_setup(struct v4l2_subdev * sd)845*4882a593Smuzhiyun static void ad9389b_audio_setup(struct v4l2_subdev *sd)
846*4882a593Smuzhiyun {
847*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s\n", __func__);
848*4882a593Smuzhiyun
849*4882a593Smuzhiyun ad9389b_s_i2s_clock_freq(sd, 48000);
850*4882a593Smuzhiyun ad9389b_s_clock_freq(sd, 48000);
851*4882a593Smuzhiyun ad9389b_s_routing(sd, 0, 0, 0);
852*4882a593Smuzhiyun }
853*4882a593Smuzhiyun
854*4882a593Smuzhiyun /* Initial setup of AD9389b */
855*4882a593Smuzhiyun
856*4882a593Smuzhiyun /* Configure hdmi transmitter. */
ad9389b_setup(struct v4l2_subdev * sd)857*4882a593Smuzhiyun static void ad9389b_setup(struct v4l2_subdev *sd)
858*4882a593Smuzhiyun {
859*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
860*4882a593Smuzhiyun
861*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s\n", __func__);
862*4882a593Smuzhiyun
863*4882a593Smuzhiyun /* Input format: RGB 4:4:4 */
864*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x15, 0xf1, 0x0);
865*4882a593Smuzhiyun /* Output format: RGB 4:4:4 */
866*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x16, 0x3f, 0x0);
867*4882a593Smuzhiyun /* 1st order interpolation 4:2:2 -> 4:4:4 up conversion,
868*4882a593Smuzhiyun Aspect ratio: 16:9 */
869*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x17, 0xf9, 0x06);
870*4882a593Smuzhiyun /* Output format: RGB 4:4:4, Active Format Information is valid. */
871*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x45, 0xc7, 0x08);
872*4882a593Smuzhiyun /* Underscanned */
873*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0x46, 0x3f, 0x80);
874*4882a593Smuzhiyun /* Setup video format */
875*4882a593Smuzhiyun ad9389b_wr(sd, 0x3c, 0x0);
876*4882a593Smuzhiyun /* Active format aspect ratio: same as picure. */
877*4882a593Smuzhiyun ad9389b_wr(sd, 0x47, 0x80);
878*4882a593Smuzhiyun /* No encryption */
879*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0xaf, 0xef, 0x0);
880*4882a593Smuzhiyun /* Positive clk edge capture for input video clock */
881*4882a593Smuzhiyun ad9389b_wr_and_or(sd, 0xba, 0x1f, 0x60);
882*4882a593Smuzhiyun
883*4882a593Smuzhiyun ad9389b_audio_setup(sd);
884*4882a593Smuzhiyun
885*4882a593Smuzhiyun v4l2_ctrl_handler_setup(&state->hdl);
886*4882a593Smuzhiyun
887*4882a593Smuzhiyun ad9389b_set_IT_content_AVI_InfoFrame(sd);
888*4882a593Smuzhiyun }
889*4882a593Smuzhiyun
ad9389b_notify_monitor_detect(struct v4l2_subdev * sd)890*4882a593Smuzhiyun static void ad9389b_notify_monitor_detect(struct v4l2_subdev *sd)
891*4882a593Smuzhiyun {
892*4882a593Smuzhiyun struct ad9389b_monitor_detect mdt;
893*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
894*4882a593Smuzhiyun
895*4882a593Smuzhiyun mdt.present = state->have_monitor;
896*4882a593Smuzhiyun v4l2_subdev_notify(sd, AD9389B_MONITOR_DETECT, (void *)&mdt);
897*4882a593Smuzhiyun }
898*4882a593Smuzhiyun
ad9389b_update_monitor_present_status(struct v4l2_subdev * sd)899*4882a593Smuzhiyun static void ad9389b_update_monitor_present_status(struct v4l2_subdev *sd)
900*4882a593Smuzhiyun {
901*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
902*4882a593Smuzhiyun /* read hotplug and rx-sense state */
903*4882a593Smuzhiyun u8 status = ad9389b_rd(sd, 0x42);
904*4882a593Smuzhiyun
905*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s: status: 0x%x%s%s\n",
906*4882a593Smuzhiyun __func__,
907*4882a593Smuzhiyun status,
908*4882a593Smuzhiyun status & MASK_AD9389B_HPD_DETECT ? ", hotplug" : "",
909*4882a593Smuzhiyun status & MASK_AD9389B_MSEN_DETECT ? ", rx-sense" : "");
910*4882a593Smuzhiyun
911*4882a593Smuzhiyun if (status & MASK_AD9389B_HPD_DETECT) {
912*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s: hotplug detected\n", __func__);
913*4882a593Smuzhiyun state->have_monitor = true;
914*4882a593Smuzhiyun if (!ad9389b_s_power(sd, true)) {
915*4882a593Smuzhiyun v4l2_dbg(1, debug, sd,
916*4882a593Smuzhiyun "%s: monitor detected, powerup failed\n", __func__);
917*4882a593Smuzhiyun return;
918*4882a593Smuzhiyun }
919*4882a593Smuzhiyun ad9389b_setup(sd);
920*4882a593Smuzhiyun ad9389b_notify_monitor_detect(sd);
921*4882a593Smuzhiyun state->edid.read_retries = EDID_MAX_RETRIES;
922*4882a593Smuzhiyun schedule_delayed_work(&state->edid_handler, EDID_DELAY);
923*4882a593Smuzhiyun } else if (!(status & MASK_AD9389B_HPD_DETECT)) {
924*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s: hotplug not detected\n", __func__);
925*4882a593Smuzhiyun state->have_monitor = false;
926*4882a593Smuzhiyun ad9389b_notify_monitor_detect(sd);
927*4882a593Smuzhiyun ad9389b_s_power(sd, false);
928*4882a593Smuzhiyun memset(&state->edid, 0, sizeof(struct ad9389b_state_edid));
929*4882a593Smuzhiyun }
930*4882a593Smuzhiyun
931*4882a593Smuzhiyun /* update read only ctrls */
932*4882a593Smuzhiyun v4l2_ctrl_s_ctrl(state->hotplug_ctrl, ad9389b_have_hotplug(sd) ? 0x1 : 0x0);
933*4882a593Smuzhiyun v4l2_ctrl_s_ctrl(state->rx_sense_ctrl, ad9389b_have_rx_sense(sd) ? 0x1 : 0x0);
934*4882a593Smuzhiyun v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, state->edid.segments ? 0x1 : 0x0);
935*4882a593Smuzhiyun
936*4882a593Smuzhiyun /* update with setting from ctrls */
937*4882a593Smuzhiyun ad9389b_s_ctrl(state->rgb_quantization_range_ctrl);
938*4882a593Smuzhiyun ad9389b_s_ctrl(state->hdmi_mode_ctrl);
939*4882a593Smuzhiyun }
940*4882a593Smuzhiyun
ad9389b_check_monitor_present_status(struct v4l2_subdev * sd)941*4882a593Smuzhiyun static void ad9389b_check_monitor_present_status(struct v4l2_subdev *sd)
942*4882a593Smuzhiyun {
943*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
944*4882a593Smuzhiyun int retry = 0;
945*4882a593Smuzhiyun
946*4882a593Smuzhiyun ad9389b_update_monitor_present_status(sd);
947*4882a593Smuzhiyun
948*4882a593Smuzhiyun /*
949*4882a593Smuzhiyun * Rapid toggling of the hotplug may leave the chip powered off,
950*4882a593Smuzhiyun * even if we think it is on. In that case reset and power up again.
951*4882a593Smuzhiyun */
952*4882a593Smuzhiyun while (state->power_on && (ad9389b_rd(sd, 0x41) & 0x40)) {
953*4882a593Smuzhiyun if (++retry > 5) {
954*4882a593Smuzhiyun v4l2_err(sd, "retried %d times, give up\n", retry);
955*4882a593Smuzhiyun return;
956*4882a593Smuzhiyun }
957*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s: reset and re-check status (%d)\n", __func__, retry);
958*4882a593Smuzhiyun ad9389b_notify_monitor_detect(sd);
959*4882a593Smuzhiyun cancel_delayed_work_sync(&state->edid_handler);
960*4882a593Smuzhiyun memset(&state->edid, 0, sizeof(struct ad9389b_state_edid));
961*4882a593Smuzhiyun ad9389b_s_power(sd, false);
962*4882a593Smuzhiyun ad9389b_update_monitor_present_status(sd);
963*4882a593Smuzhiyun }
964*4882a593Smuzhiyun }
965*4882a593Smuzhiyun
edid_block_verify_crc(u8 * edid_block)966*4882a593Smuzhiyun static bool edid_block_verify_crc(u8 *edid_block)
967*4882a593Smuzhiyun {
968*4882a593Smuzhiyun u8 sum = 0;
969*4882a593Smuzhiyun int i;
970*4882a593Smuzhiyun
971*4882a593Smuzhiyun for (i = 0; i < 128; i++)
972*4882a593Smuzhiyun sum += edid_block[i];
973*4882a593Smuzhiyun return sum == 0;
974*4882a593Smuzhiyun }
975*4882a593Smuzhiyun
edid_verify_crc(struct v4l2_subdev * sd,u32 segment)976*4882a593Smuzhiyun static bool edid_verify_crc(struct v4l2_subdev *sd, u32 segment)
977*4882a593Smuzhiyun {
978*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
979*4882a593Smuzhiyun u32 blocks = state->edid.blocks;
980*4882a593Smuzhiyun u8 *data = state->edid.data;
981*4882a593Smuzhiyun
982*4882a593Smuzhiyun if (edid_block_verify_crc(&data[segment * 256])) {
983*4882a593Smuzhiyun if ((segment + 1) * 2 <= blocks)
984*4882a593Smuzhiyun return edid_block_verify_crc(&data[segment * 256 + 128]);
985*4882a593Smuzhiyun return true;
986*4882a593Smuzhiyun }
987*4882a593Smuzhiyun return false;
988*4882a593Smuzhiyun }
989*4882a593Smuzhiyun
edid_verify_header(struct v4l2_subdev * sd,u32 segment)990*4882a593Smuzhiyun static bool edid_verify_header(struct v4l2_subdev *sd, u32 segment)
991*4882a593Smuzhiyun {
992*4882a593Smuzhiyun static const u8 hdmi_header[] = {
993*4882a593Smuzhiyun 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
994*4882a593Smuzhiyun };
995*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
996*4882a593Smuzhiyun u8 *data = state->edid.data;
997*4882a593Smuzhiyun int i;
998*4882a593Smuzhiyun
999*4882a593Smuzhiyun if (segment)
1000*4882a593Smuzhiyun return true;
1001*4882a593Smuzhiyun
1002*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(hdmi_header); i++)
1003*4882a593Smuzhiyun if (data[i] != hdmi_header[i])
1004*4882a593Smuzhiyun return false;
1005*4882a593Smuzhiyun
1006*4882a593Smuzhiyun return true;
1007*4882a593Smuzhiyun }
1008*4882a593Smuzhiyun
ad9389b_check_edid_status(struct v4l2_subdev * sd)1009*4882a593Smuzhiyun static bool ad9389b_check_edid_status(struct v4l2_subdev *sd)
1010*4882a593Smuzhiyun {
1011*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
1012*4882a593Smuzhiyun struct ad9389b_edid_detect ed;
1013*4882a593Smuzhiyun int segment;
1014*4882a593Smuzhiyun u8 edidRdy = ad9389b_rd(sd, 0xc5);
1015*4882a593Smuzhiyun
1016*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s: edid ready (retries: %d)\n",
1017*4882a593Smuzhiyun __func__, EDID_MAX_RETRIES - state->edid.read_retries);
1018*4882a593Smuzhiyun
1019*4882a593Smuzhiyun if (!(edidRdy & MASK_AD9389B_EDID_RDY))
1020*4882a593Smuzhiyun return false;
1021*4882a593Smuzhiyun
1022*4882a593Smuzhiyun segment = ad9389b_rd(sd, 0xc4);
1023*4882a593Smuzhiyun if (segment >= EDID_MAX_SEGM) {
1024*4882a593Smuzhiyun v4l2_err(sd, "edid segment number too big\n");
1025*4882a593Smuzhiyun return false;
1026*4882a593Smuzhiyun }
1027*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s: got segment %d\n", __func__, segment);
1028*4882a593Smuzhiyun ad9389b_edid_rd(sd, 256, &state->edid.data[segment * 256]);
1029*4882a593Smuzhiyun ad9389b_dbg_dump_edid(2, debug, sd, segment,
1030*4882a593Smuzhiyun &state->edid.data[segment * 256]);
1031*4882a593Smuzhiyun if (segment == 0) {
1032*4882a593Smuzhiyun state->edid.blocks = state->edid.data[0x7e] + 1;
1033*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s: %d blocks in total\n",
1034*4882a593Smuzhiyun __func__, state->edid.blocks);
1035*4882a593Smuzhiyun }
1036*4882a593Smuzhiyun if (!edid_verify_crc(sd, segment) ||
1037*4882a593Smuzhiyun !edid_verify_header(sd, segment)) {
1038*4882a593Smuzhiyun /* edid crc error, force reread of edid segment */
1039*4882a593Smuzhiyun v4l2_err(sd, "%s: edid crc or header error\n", __func__);
1040*4882a593Smuzhiyun ad9389b_s_power(sd, false);
1041*4882a593Smuzhiyun ad9389b_s_power(sd, true);
1042*4882a593Smuzhiyun return false;
1043*4882a593Smuzhiyun }
1044*4882a593Smuzhiyun /* one more segment read ok */
1045*4882a593Smuzhiyun state->edid.segments = segment + 1;
1046*4882a593Smuzhiyun if (((state->edid.data[0x7e] >> 1) + 1) > state->edid.segments) {
1047*4882a593Smuzhiyun /* Request next EDID segment */
1048*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s: request segment %d\n",
1049*4882a593Smuzhiyun __func__, state->edid.segments);
1050*4882a593Smuzhiyun ad9389b_wr(sd, 0xc9, 0xf);
1051*4882a593Smuzhiyun ad9389b_wr(sd, 0xc4, state->edid.segments);
1052*4882a593Smuzhiyun state->edid.read_retries = EDID_MAX_RETRIES;
1053*4882a593Smuzhiyun schedule_delayed_work(&state->edid_handler, EDID_DELAY);
1054*4882a593Smuzhiyun return false;
1055*4882a593Smuzhiyun }
1056*4882a593Smuzhiyun
1057*4882a593Smuzhiyun /* report when we have all segments but report only for segment 0 */
1058*4882a593Smuzhiyun ed.present = true;
1059*4882a593Smuzhiyun ed.segment = 0;
1060*4882a593Smuzhiyun v4l2_subdev_notify(sd, AD9389B_EDID_DETECT, (void *)&ed);
1061*4882a593Smuzhiyun state->edid_detect_counter++;
1062*4882a593Smuzhiyun v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, state->edid.segments ? 0x1 : 0x0);
1063*4882a593Smuzhiyun return ed.present;
1064*4882a593Smuzhiyun }
1065*4882a593Smuzhiyun
1066*4882a593Smuzhiyun /* ----------------------------------------------------------------------- */
1067*4882a593Smuzhiyun
ad9389b_init_setup(struct v4l2_subdev * sd)1068*4882a593Smuzhiyun static void ad9389b_init_setup(struct v4l2_subdev *sd)
1069*4882a593Smuzhiyun {
1070*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
1071*4882a593Smuzhiyun struct ad9389b_state_edid *edid = &state->edid;
1072*4882a593Smuzhiyun
1073*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s\n", __func__);
1074*4882a593Smuzhiyun
1075*4882a593Smuzhiyun /* clear all interrupts */
1076*4882a593Smuzhiyun ad9389b_wr(sd, 0x96, 0xff);
1077*4882a593Smuzhiyun
1078*4882a593Smuzhiyun memset(edid, 0, sizeof(struct ad9389b_state_edid));
1079*4882a593Smuzhiyun state->have_monitor = false;
1080*4882a593Smuzhiyun ad9389b_set_isr(sd, false);
1081*4882a593Smuzhiyun }
1082*4882a593Smuzhiyun
ad9389b_probe(struct i2c_client * client,const struct i2c_device_id * id)1083*4882a593Smuzhiyun static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id *id)
1084*4882a593Smuzhiyun {
1085*4882a593Smuzhiyun const struct v4l2_dv_timings dv1080p60 = V4L2_DV_BT_CEA_1920X1080P60;
1086*4882a593Smuzhiyun struct ad9389b_state *state;
1087*4882a593Smuzhiyun struct ad9389b_platform_data *pdata = client->dev.platform_data;
1088*4882a593Smuzhiyun struct v4l2_ctrl_handler *hdl;
1089*4882a593Smuzhiyun struct v4l2_subdev *sd;
1090*4882a593Smuzhiyun int err = -EIO;
1091*4882a593Smuzhiyun
1092*4882a593Smuzhiyun /* Check if the adapter supports the needed features */
1093*4882a593Smuzhiyun if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1094*4882a593Smuzhiyun return -EIO;
1095*4882a593Smuzhiyun
1096*4882a593Smuzhiyun v4l_dbg(1, debug, client, "detecting ad9389b client on address 0x%x\n",
1097*4882a593Smuzhiyun client->addr << 1);
1098*4882a593Smuzhiyun
1099*4882a593Smuzhiyun state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
1100*4882a593Smuzhiyun if (!state)
1101*4882a593Smuzhiyun return -ENOMEM;
1102*4882a593Smuzhiyun
1103*4882a593Smuzhiyun /* Platform data */
1104*4882a593Smuzhiyun if (pdata == NULL) {
1105*4882a593Smuzhiyun v4l_err(client, "No platform data!\n");
1106*4882a593Smuzhiyun return -ENODEV;
1107*4882a593Smuzhiyun }
1108*4882a593Smuzhiyun memcpy(&state->pdata, pdata, sizeof(state->pdata));
1109*4882a593Smuzhiyun
1110*4882a593Smuzhiyun sd = &state->sd;
1111*4882a593Smuzhiyun v4l2_i2c_subdev_init(sd, client, &ad9389b_ops);
1112*4882a593Smuzhiyun sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1113*4882a593Smuzhiyun
1114*4882a593Smuzhiyun hdl = &state->hdl;
1115*4882a593Smuzhiyun v4l2_ctrl_handler_init(hdl, 5);
1116*4882a593Smuzhiyun
1117*4882a593Smuzhiyun state->hdmi_mode_ctrl = v4l2_ctrl_new_std_menu(hdl, &ad9389b_ctrl_ops,
1118*4882a593Smuzhiyun V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI,
1119*4882a593Smuzhiyun 0, V4L2_DV_TX_MODE_DVI_D);
1120*4882a593Smuzhiyun state->hotplug_ctrl = v4l2_ctrl_new_std(hdl, NULL,
1121*4882a593Smuzhiyun V4L2_CID_DV_TX_HOTPLUG, 0, 1, 0, 0);
1122*4882a593Smuzhiyun state->rx_sense_ctrl = v4l2_ctrl_new_std(hdl, NULL,
1123*4882a593Smuzhiyun V4L2_CID_DV_TX_RXSENSE, 0, 1, 0, 0);
1124*4882a593Smuzhiyun state->have_edid0_ctrl = v4l2_ctrl_new_std(hdl, NULL,
1125*4882a593Smuzhiyun V4L2_CID_DV_TX_EDID_PRESENT, 0, 1, 0, 0);
1126*4882a593Smuzhiyun state->rgb_quantization_range_ctrl =
1127*4882a593Smuzhiyun v4l2_ctrl_new_std_menu(hdl, &ad9389b_ctrl_ops,
1128*4882a593Smuzhiyun V4L2_CID_DV_TX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
1129*4882a593Smuzhiyun 0, V4L2_DV_RGB_RANGE_AUTO);
1130*4882a593Smuzhiyun sd->ctrl_handler = hdl;
1131*4882a593Smuzhiyun if (hdl->error) {
1132*4882a593Smuzhiyun err = hdl->error;
1133*4882a593Smuzhiyun
1134*4882a593Smuzhiyun goto err_hdl;
1135*4882a593Smuzhiyun }
1136*4882a593Smuzhiyun state->pad.flags = MEDIA_PAD_FL_SINK;
1137*4882a593Smuzhiyun sd->entity.function = MEDIA_ENT_F_DV_ENCODER;
1138*4882a593Smuzhiyun err = media_entity_pads_init(&sd->entity, 1, &state->pad);
1139*4882a593Smuzhiyun if (err)
1140*4882a593Smuzhiyun goto err_hdl;
1141*4882a593Smuzhiyun
1142*4882a593Smuzhiyun state->chip_revision = ad9389b_rd(sd, 0x0);
1143*4882a593Smuzhiyun if (state->chip_revision != 2) {
1144*4882a593Smuzhiyun v4l2_err(sd, "chip_revision %d != 2\n", state->chip_revision);
1145*4882a593Smuzhiyun err = -EIO;
1146*4882a593Smuzhiyun goto err_entity;
1147*4882a593Smuzhiyun }
1148*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "reg 0x41 0x%x, chip version (reg 0x00) 0x%x\n",
1149*4882a593Smuzhiyun ad9389b_rd(sd, 0x41), state->chip_revision);
1150*4882a593Smuzhiyun
1151*4882a593Smuzhiyun state->edid_i2c_client = i2c_new_dummy_device(client->adapter, (0x7e >> 1));
1152*4882a593Smuzhiyun if (IS_ERR(state->edid_i2c_client)) {
1153*4882a593Smuzhiyun v4l2_err(sd, "failed to register edid i2c client\n");
1154*4882a593Smuzhiyun err = PTR_ERR(state->edid_i2c_client);
1155*4882a593Smuzhiyun goto err_entity;
1156*4882a593Smuzhiyun }
1157*4882a593Smuzhiyun
1158*4882a593Smuzhiyun INIT_DELAYED_WORK(&state->edid_handler, ad9389b_edid_handler);
1159*4882a593Smuzhiyun state->dv_timings = dv1080p60;
1160*4882a593Smuzhiyun
1161*4882a593Smuzhiyun ad9389b_init_setup(sd);
1162*4882a593Smuzhiyun ad9389b_set_isr(sd, true);
1163*4882a593Smuzhiyun
1164*4882a593Smuzhiyun v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
1165*4882a593Smuzhiyun client->addr << 1, client->adapter->name);
1166*4882a593Smuzhiyun return 0;
1167*4882a593Smuzhiyun
1168*4882a593Smuzhiyun err_entity:
1169*4882a593Smuzhiyun media_entity_cleanup(&sd->entity);
1170*4882a593Smuzhiyun err_hdl:
1171*4882a593Smuzhiyun v4l2_ctrl_handler_free(&state->hdl);
1172*4882a593Smuzhiyun return err;
1173*4882a593Smuzhiyun }
1174*4882a593Smuzhiyun
1175*4882a593Smuzhiyun /* ----------------------------------------------------------------------- */
1176*4882a593Smuzhiyun
ad9389b_remove(struct i2c_client * client)1177*4882a593Smuzhiyun static int ad9389b_remove(struct i2c_client *client)
1178*4882a593Smuzhiyun {
1179*4882a593Smuzhiyun struct v4l2_subdev *sd = i2c_get_clientdata(client);
1180*4882a593Smuzhiyun struct ad9389b_state *state = get_ad9389b_state(sd);
1181*4882a593Smuzhiyun
1182*4882a593Smuzhiyun state->chip_revision = -1;
1183*4882a593Smuzhiyun
1184*4882a593Smuzhiyun v4l2_dbg(1, debug, sd, "%s removed @ 0x%x (%s)\n", client->name,
1185*4882a593Smuzhiyun client->addr << 1, client->adapter->name);
1186*4882a593Smuzhiyun
1187*4882a593Smuzhiyun ad9389b_s_stream(sd, false);
1188*4882a593Smuzhiyun ad9389b_s_audio_stream(sd, false);
1189*4882a593Smuzhiyun ad9389b_init_setup(sd);
1190*4882a593Smuzhiyun cancel_delayed_work_sync(&state->edid_handler);
1191*4882a593Smuzhiyun i2c_unregister_device(state->edid_i2c_client);
1192*4882a593Smuzhiyun v4l2_device_unregister_subdev(sd);
1193*4882a593Smuzhiyun media_entity_cleanup(&sd->entity);
1194*4882a593Smuzhiyun v4l2_ctrl_handler_free(sd->ctrl_handler);
1195*4882a593Smuzhiyun return 0;
1196*4882a593Smuzhiyun }
1197*4882a593Smuzhiyun
1198*4882a593Smuzhiyun /* ----------------------------------------------------------------------- */
1199*4882a593Smuzhiyun
1200*4882a593Smuzhiyun static const struct i2c_device_id ad9389b_id[] = {
1201*4882a593Smuzhiyun { "ad9389b", 0 },
1202*4882a593Smuzhiyun { "ad9889b", 0 },
1203*4882a593Smuzhiyun { }
1204*4882a593Smuzhiyun };
1205*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, ad9389b_id);
1206*4882a593Smuzhiyun
1207*4882a593Smuzhiyun static struct i2c_driver ad9389b_driver = {
1208*4882a593Smuzhiyun .driver = {
1209*4882a593Smuzhiyun .name = "ad9389b",
1210*4882a593Smuzhiyun },
1211*4882a593Smuzhiyun .probe = ad9389b_probe,
1212*4882a593Smuzhiyun .remove = ad9389b_remove,
1213*4882a593Smuzhiyun .id_table = ad9389b_id,
1214*4882a593Smuzhiyun };
1215*4882a593Smuzhiyun
1216*4882a593Smuzhiyun module_i2c_driver(ad9389b_driver);
1217