1 /*
2  * Auvitek AU8522 QAM/8VSB demodulator driver and video decoder
3  *
4  * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
5  * Copyright (C) 2005-2008 Auvitek International, Ltd.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * As published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301, USA.
21  */
22 
23 /* Developer notes:
24  *
25  * VBI support is not yet working
26  * Enough is implemented here for CVBS and S-Video inputs, but the actual
27  *  analog demodulator code isn't implemented (not needed for xc5000 since it
28  *  has its own demodulator and outputs CVBS)
29  *
30  */
31 
32 #include <linux/kernel.h>
33 #include <linux/slab.h>
34 #include <linux/videodev2.h>
35 #include <linux/i2c.h>
36 #include <linux/delay.h>
37 #include <media/v4l2-common.h>
38 #include <media/v4l2-chip-ident.h>
39 #include <media/v4l2-device.h>
40 #include "au8522.h"
41 #include "au8522_priv.h"
42 
43 MODULE_AUTHOR("Devin Heitmueller");
44 MODULE_LICENSE("GPL");
45 
46 static int au8522_analog_debug;
47 
48 
49 module_param_named(analog_debug, au8522_analog_debug, int, 0644);
50 
51 MODULE_PARM_DESC(analog_debug,
52 		 "Analog debugging messages [0=Off (default) 1=On]");
53 
54 struct au8522_register_config {
55 	u16 reg_name;
56 	u8 reg_val[8];
57 };
58 
59 
60 /* Video Decoder Filter Coefficients
61    The values are as follows from left to right
62    0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13"
63 */
64 static const struct au8522_register_config filter_coef[] = {
65 	{AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} },
66 	{AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} },
67 	{AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} },
68 	{AU8522_FILTER_COEF_R413, {0xe6, 0x00, 0xe6, 0xe6, 0x00, 0x00, 0x00} },
69 	{AU8522_FILTER_COEF_R414, {0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00} },
70 	{AU8522_FILTER_COEF_R415, {0x1b, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00} },
71 	{AU8522_FILTER_COEF_R416, {0xc0, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00} },
72 	{AU8522_FILTER_COEF_R417, {0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00} },
73 	{AU8522_FILTER_COEF_R418, {0x8c, 0x00, 0x8c, 0x8c, 0x00, 0x00, 0x00} },
74 	{AU8522_FILTER_COEF_R419, {0xa0, 0x40, 0xa0, 0xa0, 0x40, 0x40, 0x40} },
75 	{AU8522_FILTER_COEF_R41A, {0x21, 0x09, 0x21, 0x21, 0x09, 0x09, 0x09} },
76 	{AU8522_FILTER_COEF_R41B, {0x6c, 0x38, 0x6c, 0x6c, 0x38, 0x38, 0x38} },
77 	{AU8522_FILTER_COEF_R41C, {0x03, 0xff, 0x03, 0x03, 0xff, 0xff, 0xff} },
78 	{AU8522_FILTER_COEF_R41D, {0xbf, 0xc7, 0xbf, 0xbf, 0xc7, 0xc7, 0xc7} },
79 	{AU8522_FILTER_COEF_R41E, {0xa0, 0xdf, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf} },
80 	{AU8522_FILTER_COEF_R41F, {0x10, 0x06, 0x10, 0x10, 0x06, 0x06, 0x06} },
81 	{AU8522_FILTER_COEF_R420, {0xae, 0x30, 0xae, 0xae, 0x30, 0x30, 0x30} },
82 	{AU8522_FILTER_COEF_R421, {0xc4, 0x01, 0xc4, 0xc4, 0x01, 0x01, 0x01} },
83 	{AU8522_FILTER_COEF_R422, {0x54, 0xdd, 0x54, 0x54, 0xdd, 0xdd, 0xdd} },
84 	{AU8522_FILTER_COEF_R423, {0xd0, 0xaf, 0xd0, 0xd0, 0xaf, 0xaf, 0xaf} },
85 	{AU8522_FILTER_COEF_R424, {0x1c, 0xf7, 0x1c, 0x1c, 0xf7, 0xf7, 0xf7} },
86 	{AU8522_FILTER_COEF_R425, {0x76, 0xdb, 0x76, 0x76, 0xdb, 0xdb, 0xdb} },
87 	{AU8522_FILTER_COEF_R426, {0x61, 0xc0, 0x61, 0x61, 0xc0, 0xc0, 0xc0} },
88 	{AU8522_FILTER_COEF_R427, {0xd1, 0x2f, 0xd1, 0xd1, 0x2f, 0x2f, 0x2f} },
89 	{AU8522_FILTER_COEF_R428, {0x84, 0xd8, 0x84, 0x84, 0xd8, 0xd8, 0xd8} },
90 	{AU8522_FILTER_COEF_R429, {0x06, 0xfb, 0x06, 0x06, 0xfb, 0xfb, 0xfb} },
91 	{AU8522_FILTER_COEF_R42A, {0x21, 0xd5, 0x21, 0x21, 0xd5, 0xd5, 0xd5} },
92 	{AU8522_FILTER_COEF_R42B, {0x0a, 0x3e, 0x0a, 0x0a, 0x3e, 0x3e, 0x3e} },
93 	{AU8522_FILTER_COEF_R42C, {0xe6, 0x15, 0xe6, 0xe6, 0x15, 0x15, 0x15} },
94 	{AU8522_FILTER_COEF_R42D, {0x01, 0x34, 0x01, 0x01, 0x34, 0x34, 0x34} },
95 
96 };
97 #define NUM_FILTER_COEF (sizeof(filter_coef)\
98 			 / sizeof(struct au8522_register_config))
99 
100 
101 /* Registers 0x060b through 0x0652 are the LP Filter coefficients
102    The values are as follows from left to right
103    0="SIF" 1="ATVRF/ATVRF13"
104    Note: the "ATVRF/ATVRF13" mode has never been tested
105 */
106 static const struct au8522_register_config lpfilter_coef[] = {
107 	{0x060b, {0x21, 0x0b} },
108 	{0x060c, {0xad, 0xad} },
109 	{0x060d, {0x70, 0xf0} },
110 	{0x060e, {0xea, 0xe9} },
111 	{0x060f, {0xdd, 0xdd} },
112 	{0x0610, {0x08, 0x64} },
113 	{0x0611, {0x60, 0x60} },
114 	{0x0612, {0xf8, 0xb2} },
115 	{0x0613, {0x01, 0x02} },
116 	{0x0614, {0xe4, 0xb4} },
117 	{0x0615, {0x19, 0x02} },
118 	{0x0616, {0xae, 0x2e} },
119 	{0x0617, {0xee, 0xc5} },
120 	{0x0618, {0x56, 0x56} },
121 	{0x0619, {0x30, 0x58} },
122 	{0x061a, {0xf9, 0xf8} },
123 	{0x061b, {0x24, 0x64} },
124 	{0x061c, {0x07, 0x07} },
125 	{0x061d, {0x30, 0x30} },
126 	{0x061e, {0xa9, 0xed} },
127 	{0x061f, {0x09, 0x0b} },
128 	{0x0620, {0x42, 0xc2} },
129 	{0x0621, {0x1d, 0x2a} },
130 	{0x0622, {0xd6, 0x56} },
131 	{0x0623, {0x95, 0x8b} },
132 	{0x0624, {0x2b, 0x2b} },
133 	{0x0625, {0x30, 0x24} },
134 	{0x0626, {0x3e, 0x3e} },
135 	{0x0627, {0x62, 0xe2} },
136 	{0x0628, {0xe9, 0xf5} },
137 	{0x0629, {0x99, 0x19} },
138 	{0x062a, {0xd4, 0x11} },
139 	{0x062b, {0x03, 0x04} },
140 	{0x062c, {0xb5, 0x85} },
141 	{0x062d, {0x1e, 0x20} },
142 	{0x062e, {0x2a, 0xea} },
143 	{0x062f, {0xd7, 0xd2} },
144 	{0x0630, {0x15, 0x15} },
145 	{0x0631, {0xa3, 0xa9} },
146 	{0x0632, {0x1f, 0x1f} },
147 	{0x0633, {0xf9, 0xd1} },
148 	{0x0634, {0xc0, 0xc3} },
149 	{0x0635, {0x4d, 0x8d} },
150 	{0x0636, {0x21, 0x31} },
151 	{0x0637, {0x83, 0x83} },
152 	{0x0638, {0x08, 0x8c} },
153 	{0x0639, {0x19, 0x19} },
154 	{0x063a, {0x45, 0xa5} },
155 	{0x063b, {0xef, 0xec} },
156 	{0x063c, {0x8a, 0x8a} },
157 	{0x063d, {0xf4, 0xf6} },
158 	{0x063e, {0x8f, 0x8f} },
159 	{0x063f, {0x44, 0x0c} },
160 	{0x0640, {0xef, 0xf0} },
161 	{0x0641, {0x66, 0x66} },
162 	{0x0642, {0xcc, 0xd2} },
163 	{0x0643, {0x41, 0x41} },
164 	{0x0644, {0x63, 0x93} },
165 	{0x0645, {0x8e, 0x8e} },
166 	{0x0646, {0xa2, 0x42} },
167 	{0x0647, {0x7b, 0x7b} },
168 	{0x0648, {0x04, 0x04} },
169 	{0x0649, {0x00, 0x00} },
170 	{0x064a, {0x40, 0x40} },
171 	{0x064b, {0x8c, 0x98} },
172 	{0x064c, {0x00, 0x00} },
173 	{0x064d, {0x63, 0xc3} },
174 	{0x064e, {0x04, 0x04} },
175 	{0x064f, {0x20, 0x20} },
176 	{0x0650, {0x00, 0x00} },
177 	{0x0651, {0x40, 0x40} },
178 	{0x0652, {0x01, 0x01} },
179 };
180 #define NUM_LPFILTER_COEF (sizeof(lpfilter_coef)\
181 			   / sizeof(struct au8522_register_config))
182 
to_state(struct v4l2_subdev * sd)183 static inline struct au8522_state *to_state(struct v4l2_subdev *sd)
184 {
185 	return container_of(sd, struct au8522_state, sd);
186 }
187 
setup_vbi(struct au8522_state * state,int aud_input)188 static void setup_vbi(struct au8522_state *state, int aud_input)
189 {
190 	int i;
191 
192 	/* These are set to zero regardless of what mode we're in */
193 	au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, 0x00);
194 	au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_L_REG018H, 0x00);
195 	au8522_writereg(state, AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H, 0x00);
196 	au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH, 0x00);
197 	au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH, 0x00);
198 	au8522_writereg(state, AU8522_TVDEC_VBI_USER_THRESH1_REG01CH, 0x00);
199 	au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH, 0x00);
200 	au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH, 0x00);
201 	au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H, 0x00);
202 	au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H,
203 			0x00);
204 	au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H,
205 			0x00);
206 	au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H,
207 			0x00);
208 
209 	/* Setup the VBI registers */
210 	for (i = 0x30; i < 0x60; i++)
211 		au8522_writereg(state, i, 0x40);
212 
213 	/* For some reason, every register is 0x40 except register 0x44
214 	   (confirmed via the HVR-950q USB capture) */
215 	au8522_writereg(state, 0x44, 0x60);
216 
217 	/* Enable VBI (we always do this regardless of whether the user is
218 	   viewing closed caption info) */
219 	au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H,
220 			AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON);
221 
222 }
223 
setup_decoder_defaults(struct au8522_state * state,u8 input_mode)224 static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
225 {
226 	int i;
227 	int filter_coef_type;
228 
229 	/* Provide reasonable defaults for picture tuning values */
230 	au8522_writereg(state, AU8522_TVDEC_SHARPNESSREG009H, 0x07);
231 	au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, 0xed);
232 	state->brightness = 0xed - 128;
233 	au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, 0x79);
234 	state->contrast = 0x79;
235 	au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80);
236 	au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80);
237 	state->saturation = 0x80;
238 	au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00);
239 	au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00);
240 	state->hue = 0x00;
241 
242 	/* Other decoder registers */
243 	au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
244 
245 	if (input_mode == 0x23) {
246 		/* S-Video input mapping */
247 		au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04);
248 	} else {
249 		/* All other modes (CVBS/ATVRF etc.) */
250 		au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00);
251 	}
252 
253 	au8522_writereg(state, AU8522_TVDEC_PGA_REG012H,
254 			AU8522_TVDEC_PGA_REG012H_CVBS);
255 	au8522_writereg(state, AU8522_TVDEC_COMB_MODE_REG015H,
256 			AU8522_TVDEC_COMB_MODE_REG015H_CVBS);
257 	au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H,
258 			AU8522_TVDED_DBG_MODE_REG060H_CVBS);
259 	au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
260 			AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13);
261 	au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
262 			AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13);
263 	au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H,
264 			AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS);
265 	au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H,
266 			AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS);
267 	au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR1_REG065H,
268 			AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS);
269 	au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR2_REG066H,
270 			AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS);
271 	au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR3_REG067H,
272 			AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS);
273 	au8522_writereg(state, AU8522_TVDEC_COMB_NOTCH_THR_REG068H,
274 			AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS);
275 	au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR1_REG069H,
276 			AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS);
277 	au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR2_REG06AH,
278 			AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
279 	au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
280 			AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
281 	if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
282 	    input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
283 		au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
284 				AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO);
285 		au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
286 				AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_SVIDEO);
287 	} else {
288 		au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
289 				AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
290 		au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
291 				AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
292 	}
293 	au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH,
294 			AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS);
295 	au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH,
296 			AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS);
297 	au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H,
298 			AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS);
299 	au8522_writereg(state, AU8522_REG071H, AU8522_REG071H_CVBS);
300 	au8522_writereg(state, AU8522_REG072H, AU8522_REG072H_CVBS);
301 	au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H,
302 			AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS);
303 	au8522_writereg(state, AU8522_REG074H, AU8522_REG074H_CVBS);
304 	au8522_writereg(state, AU8522_REG075H, AU8522_REG075H_CVBS);
305 	au8522_writereg(state, AU8522_TVDEC_DCAGC_CTRL_REG077H,
306 			AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS);
307 	au8522_writereg(state, AU8522_TVDEC_PIC_START_ADJ_REG078H,
308 			AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS);
309 	au8522_writereg(state, AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H,
310 			AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS);
311 	au8522_writereg(state, AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH,
312 			AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS);
313 	au8522_writereg(state, AU8522_TVDEC_INTRP_CTRL_REG07BH,
314 			AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS);
315 	au8522_writereg(state, AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H,
316 			AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS);
317 	au8522_writereg(state, AU8522_TOREGAAGC_REG0E5H,
318 			AU8522_TOREGAAGC_REG0E5H_CVBS);
319 	au8522_writereg(state, AU8522_REG016H, AU8522_REG016H_CVBS);
320 
321 	setup_vbi(state, 0);
322 
323 	if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
324 	    input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
325 		/* Despite what the table says, for the HVR-950q we still need
326 		   to be in CVBS mode for the S-Video input (reason unknown). */
327 		/* filter_coef_type = 3; */
328 		filter_coef_type = 5;
329 	} else {
330 		filter_coef_type = 5;
331 	}
332 
333 	/* Load the Video Decoder Filter Coefficients */
334 	for (i = 0; i < NUM_FILTER_COEF; i++) {
335 		au8522_writereg(state, filter_coef[i].reg_name,
336 				filter_coef[i].reg_val[filter_coef_type]);
337 	}
338 
339 	/* It's not clear what these registers are for, but they are always
340 	   set to the same value regardless of what mode we're in */
341 	au8522_writereg(state, AU8522_REG42EH, 0x87);
342 	au8522_writereg(state, AU8522_REG42FH, 0xa2);
343 	au8522_writereg(state, AU8522_REG430H, 0xbf);
344 	au8522_writereg(state, AU8522_REG431H, 0xcb);
345 	au8522_writereg(state, AU8522_REG432H, 0xa1);
346 	au8522_writereg(state, AU8522_REG433H, 0x41);
347 	au8522_writereg(state, AU8522_REG434H, 0x88);
348 	au8522_writereg(state, AU8522_REG435H, 0xc2);
349 	au8522_writereg(state, AU8522_REG436H, 0x3c);
350 }
351 
au8522_setup_cvbs_mode(struct au8522_state * state)352 static void au8522_setup_cvbs_mode(struct au8522_state *state)
353 {
354 	/* here we're going to try the pre-programmed route */
355 	au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
356 			AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
357 
358 	/* PGA in automatic mode */
359 	au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
360 
361 	/* Enable clamping control */
362 	au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
363 
364 	au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
365 			AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
366 
367 	setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
368 
369 	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
370 			AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
371 }
372 
au8522_setup_cvbs_tuner_mode(struct au8522_state * state)373 static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
374 {
375 	/* here we're going to try the pre-programmed route */
376 	au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
377 			AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
378 
379 	/* It's not clear why we have to have the PGA in automatic mode while
380 	   enabling clamp control, but it's what Windows does */
381 	au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
382 
383 	/* Enable clamping control */
384 	au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
385 
386 	/* Disable automatic PGA (since the CVBS is coming from the tuner) */
387 	au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
388 
389 	/* Set input mode to CVBS on channel 4 with SIF audio input enabled */
390 	au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
391 			AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
392 
393 	setup_decoder_defaults(state,
394 			       AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
395 
396 	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
397 			AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
398 }
399 
au8522_setup_svideo_mode(struct au8522_state * state)400 static void au8522_setup_svideo_mode(struct au8522_state *state)
401 {
402 	au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
403 			AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO);
404 
405 	/* Set input to Y on Channe1, C on Channel 3 */
406 	au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
407 			AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
408 
409 	/* PGA in automatic mode */
410 	au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
411 
412 	/* Enable clamping control */
413 	au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
414 
415 	setup_decoder_defaults(state,
416 			       AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
417 
418 	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
419 			AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
420 }
421 
422 /* ----------------------------------------------------------------------- */
423 
disable_audio_input(struct au8522_state * state)424 static void disable_audio_input(struct au8522_state *state)
425 {
426 	au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
427 	au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
428 	au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
429 
430 	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04);
431 	au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02);
432 
433 	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
434 			AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO);
435 }
436 
437 /* 0=disable, 1=SIF */
set_audio_input(struct au8522_state * state,int aud_input)438 static void set_audio_input(struct au8522_state *state, int aud_input)
439 {
440 	int i;
441 
442 	/* Note that this function needs to be used in conjunction with setting
443 	   the input routing via register 0x81 */
444 
445 	if (aud_input == AU8522_AUDIO_NONE) {
446 		disable_audio_input(state);
447 		return;
448 	}
449 
450 	if (aud_input != AU8522_AUDIO_SIF) {
451 		/* The caller asked for a mode we don't currently support */
452 		printk(KERN_ERR "Unsupported audio mode requested! mode=%d\n",
453 		       aud_input);
454 		return;
455 	}
456 
457 	/* Load the Audio Decoder Filter Coefficients */
458 	for (i = 0; i < NUM_LPFILTER_COEF; i++) {
459 		au8522_writereg(state, lpfilter_coef[i].reg_name,
460 				lpfilter_coef[i].reg_val[0]);
461 	}
462 
463 	/* Setup audio */
464 	au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
465 	au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
466 	au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
467 	au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
468 	au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
469 	msleep(150);
470 	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00);
471 	msleep(1);
472 	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d);
473 	msleep(50);
474 	au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
475 	au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
476 	au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0xff);
477 	msleep(80);
478 	au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
479 	au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
480 	au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
481 	au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x82);
482 	msleep(70);
483 	au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x09);
484 	au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
485 	au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0xc2);
486 }
487 
488 /* ----------------------------------------------------------------------- */
489 
au8522_s_ctrl(struct v4l2_subdev * sd,struct v4l2_control * ctrl)490 static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
491 {
492 	struct au8522_state *state = to_state(sd);
493 
494 	switch (ctrl->id) {
495 	case V4L2_CID_BRIGHTNESS:
496 		state->brightness = ctrl->value;
497 		au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH,
498 				ctrl->value - 128);
499 		break;
500 	case V4L2_CID_CONTRAST:
501 		state->contrast = ctrl->value;
502 		au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH,
503 				ctrl->value);
504 		break;
505 	case V4L2_CID_SATURATION:
506 		state->saturation = ctrl->value;
507 		au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH,
508 				ctrl->value);
509 		au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH,
510 				ctrl->value);
511 		break;
512 	case V4L2_CID_HUE:
513 		state->hue = ctrl->value;
514 		au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH,
515 				ctrl->value >> 8);
516 		au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH,
517 				ctrl->value & 0xFF);
518 		break;
519 	case V4L2_CID_AUDIO_VOLUME:
520 	case V4L2_CID_AUDIO_BASS:
521 	case V4L2_CID_AUDIO_TREBLE:
522 	case V4L2_CID_AUDIO_BALANCE:
523 	case V4L2_CID_AUDIO_MUTE:
524 		/* Not yet implemented */
525 	default:
526 		return -EINVAL;
527 	}
528 
529 	return 0;
530 }
531 
au8522_g_ctrl(struct v4l2_subdev * sd,struct v4l2_control * ctrl)532 static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
533 {
534 	struct au8522_state *state = to_state(sd);
535 
536 	/* Note that we are using values cached in the state structure instead
537 	   of reading the registers due to issues with i2c reads not working
538 	   properly/consistently yet on the HVR-950q */
539 
540 	switch (ctrl->id) {
541 	case V4L2_CID_BRIGHTNESS:
542 		ctrl->value = state->brightness;
543 		break;
544 	case V4L2_CID_CONTRAST:
545 		ctrl->value = state->contrast;
546 		break;
547 	case V4L2_CID_SATURATION:
548 		ctrl->value = state->saturation;
549 		break;
550 	case V4L2_CID_HUE:
551 		ctrl->value = state->hue;
552 		break;
553 	case V4L2_CID_AUDIO_VOLUME:
554 	case V4L2_CID_AUDIO_BASS:
555 	case V4L2_CID_AUDIO_TREBLE:
556 	case V4L2_CID_AUDIO_BALANCE:
557 	case V4L2_CID_AUDIO_MUTE:
558 		/* Not yet supported */
559 	default:
560 		return -EINVAL;
561 	}
562 
563 	return 0;
564 }
565 
566 /* ----------------------------------------------------------------------- */
567 
568 #ifdef CONFIG_VIDEO_ADV_DEBUG
au8522_g_register(struct v4l2_subdev * sd,struct v4l2_dbg_register * reg)569 static int au8522_g_register(struct v4l2_subdev *sd,
570 			     struct v4l2_dbg_register *reg)
571 {
572 	struct i2c_client *client = v4l2_get_subdevdata(sd);
573 	struct au8522_state *state = to_state(sd);
574 
575 	if (!v4l2_chip_match_i2c_client(client, &reg->match))
576 		return -EINVAL;
577 	if (!capable(CAP_SYS_ADMIN))
578 		return -EPERM;
579 	reg->val = au8522_readreg(state, reg->reg & 0xffff);
580 	return 0;
581 }
582 
au8522_s_register(struct v4l2_subdev * sd,struct v4l2_dbg_register * reg)583 static int au8522_s_register(struct v4l2_subdev *sd,
584 			     struct v4l2_dbg_register *reg)
585 {
586 	struct i2c_client *client = v4l2_get_subdevdata(sd);
587 	struct au8522_state *state = to_state(sd);
588 
589 	if (!v4l2_chip_match_i2c_client(client, &reg->match))
590 		return -EINVAL;
591 	if (!capable(CAP_SYS_ADMIN))
592 		return -EPERM;
593 	au8522_writereg(state, reg->reg, reg->val & 0xff);
594 	return 0;
595 }
596 #endif
597 
au8522_s_stream(struct v4l2_subdev * sd,int enable)598 static int au8522_s_stream(struct v4l2_subdev *sd, int enable)
599 {
600 	struct au8522_state *state = to_state(sd);
601 
602 	if (enable) {
603 		au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
604 				0x01);
605 		msleep(1);
606 		au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
607 				AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
608 	} else {
609 		/* This does not completely power down the device
610 		   (it only reduces it from around 140ma to 80ma) */
611 		au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
612 				1 << 5);
613 	}
614 	return 0;
615 }
616 
au8522_queryctrl(struct v4l2_subdev * sd,struct v4l2_queryctrl * qc)617 static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
618 {
619 	switch (qc->id) {
620 	case V4L2_CID_CONTRAST:
621 		return v4l2_ctrl_query_fill(qc, 0, 255, 1,
622 					    AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
623 	case V4L2_CID_BRIGHTNESS:
624 		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 109);
625 	case V4L2_CID_SATURATION:
626 		return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
627 	case V4L2_CID_HUE:
628 		return v4l2_ctrl_query_fill(qc, -32768, 32768, 1, 0);
629 	default:
630 		break;
631 	}
632 
633 	qc->type = 0;
634 	return -EINVAL;
635 }
636 
au8522_reset(struct v4l2_subdev * sd,u32 val)637 static int au8522_reset(struct v4l2_subdev *sd, u32 val)
638 {
639 	struct au8522_state *state = to_state(sd);
640 
641 	state->operational_mode = AU8522_ANALOG_MODE;
642 
643 	/* Clear out any state associated with the digital side of the
644 	   chip, so that when it gets powered back up it won't think
645 	   that it is already tuned */
646 	state->current_frequency = 0;
647 
648 	au8522_writereg(state, 0xa4, 1 << 5);
649 
650 	return 0;
651 }
652 
au8522_s_video_routing(struct v4l2_subdev * sd,u32 input,u32 output,u32 config)653 static int au8522_s_video_routing(struct v4l2_subdev *sd,
654 					u32 input, u32 output, u32 config)
655 {
656 	struct au8522_state *state = to_state(sd);
657 
658 	au8522_reset(sd, 0);
659 
660 	/* Jam open the i2c gate to the tuner.  We do this here to handle the
661 	   case where the user went into digital mode (causing the gate to be
662 	   closed), and then came back to analog mode */
663 	au8522_writereg(state, 0x106, 1);
664 
665 	if (input == AU8522_COMPOSITE_CH1) {
666 		au8522_setup_cvbs_mode(state);
667 	} else if (input == AU8522_SVIDEO_CH13) {
668 		au8522_setup_svideo_mode(state);
669 	} else if (input == AU8522_COMPOSITE_CH4_SIF) {
670 		au8522_setup_cvbs_tuner_mode(state);
671 	} else {
672 		printk(KERN_ERR "au8522 mode not currently supported\n");
673 		return -EINVAL;
674 	}
675 	return 0;
676 }
677 
au8522_s_audio_routing(struct v4l2_subdev * sd,u32 input,u32 output,u32 config)678 static int au8522_s_audio_routing(struct v4l2_subdev *sd,
679 					u32 input, u32 output, u32 config)
680 {
681 	struct au8522_state *state = to_state(sd);
682 	set_audio_input(state, input);
683 	return 0;
684 }
685 
au8522_g_tuner(struct v4l2_subdev * sd,struct v4l2_tuner * vt)686 static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
687 {
688 	int val = 0;
689 	struct au8522_state *state = to_state(sd);
690 	u8 lock_status;
691 
692 	/* Interrogate the decoder to see if we are getting a real signal */
693 	lock_status = au8522_readreg(state, 0x00);
694 	if (lock_status == 0xa2)
695 		vt->signal = 0xffff;
696 	else
697 		vt->signal = 0x00;
698 
699 	vt->capability |=
700 		V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
701 		V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
702 
703 	val = V4L2_TUNER_SUB_MONO;
704 	vt->rxsubchans = val;
705 	vt->audmode = V4L2_TUNER_MODE_STEREO;
706 	return 0;
707 }
708 
au8522_g_chip_ident(struct v4l2_subdev * sd,struct v4l2_dbg_chip_ident * chip)709 static int au8522_g_chip_ident(struct v4l2_subdev *sd,
710 			       struct v4l2_dbg_chip_ident *chip)
711 {
712 	struct au8522_state *state = to_state(sd);
713 	struct i2c_client *client = v4l2_get_subdevdata(sd);
714 
715 	return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
716 }
717 
au8522_log_status(struct v4l2_subdev * sd)718 static int au8522_log_status(struct v4l2_subdev *sd)
719 {
720 	/* FIXME: Add some status info here */
721 	return 0;
722 }
723 
724 /* ----------------------------------------------------------------------- */
725 
726 static const struct v4l2_subdev_core_ops au8522_core_ops = {
727 	.log_status = au8522_log_status,
728 	.g_chip_ident = au8522_g_chip_ident,
729 	.g_ctrl = au8522_g_ctrl,
730 	.s_ctrl = au8522_s_ctrl,
731 	.queryctrl = au8522_queryctrl,
732 	.reset = au8522_reset,
733 #ifdef CONFIG_VIDEO_ADV_DEBUG
734 	.g_register = au8522_g_register,
735 	.s_register = au8522_s_register,
736 #endif
737 };
738 
739 static const struct v4l2_subdev_tuner_ops au8522_tuner_ops = {
740 	.g_tuner = au8522_g_tuner,
741 };
742 
743 static const struct v4l2_subdev_audio_ops au8522_audio_ops = {
744 	.s_routing = au8522_s_audio_routing,
745 };
746 
747 static const struct v4l2_subdev_video_ops au8522_video_ops = {
748 	.s_routing = au8522_s_video_routing,
749 	.s_stream = au8522_s_stream,
750 };
751 
752 static const struct v4l2_subdev_ops au8522_ops = {
753 	.core = &au8522_core_ops,
754 	.tuner = &au8522_tuner_ops,
755 	.audio = &au8522_audio_ops,
756 	.video = &au8522_video_ops,
757 };
758 
759 /* ----------------------------------------------------------------------- */
760 
au8522_probe(struct i2c_client * client,const struct i2c_device_id * did)761 static int au8522_probe(struct i2c_client *client,
762 			const struct i2c_device_id *did)
763 {
764 	struct au8522_state *state;
765 	struct v4l2_subdev *sd;
766 	int instance;
767 	struct au8522_config *demod_config;
768 
769 	/* Check if the adapter supports the needed features */
770 	if (!i2c_check_functionality(client->adapter,
771 				     I2C_FUNC_SMBUS_BYTE_DATA)) {
772 		return -EIO;
773 	}
774 
775 	/* allocate memory for the internal state */
776 	instance = au8522_get_state(&state, client->adapter, client->addr);
777 	switch (instance) {
778 	case 0:
779 		printk(KERN_ERR "au8522_decoder allocation failed\n");
780 		return -EIO;
781 	case 1:
782 		/* new demod instance */
783 		printk(KERN_INFO "au8522_decoder creating new instance...\n");
784 		break;
785 	default:
786 		/* existing demod instance */
787 		printk(KERN_INFO "au8522_decoder attach existing instance.\n");
788 		break;
789 	}
790 
791 	demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL);
792 	if (demod_config == NULL) {
793 		if (instance == 1)
794 			kfree(state);
795 		return -ENOMEM;
796 	}
797 	demod_config->demod_address = 0x8e >> 1;
798 
799 	state->config = demod_config;
800 	state->i2c = client->adapter;
801 
802 	sd = &state->sd;
803 	v4l2_i2c_subdev_init(sd, client, &au8522_ops);
804 
805 	state->c = client;
806 	state->vid_input = AU8522_COMPOSITE_CH1;
807 	state->aud_input = AU8522_AUDIO_NONE;
808 	state->id = 8522;
809 	state->rev = 0;
810 
811 	/* Jam open the i2c gate to the tuner */
812 	au8522_writereg(state, 0x106, 1);
813 
814 	return 0;
815 }
816 
au8522_remove(struct i2c_client * client)817 static int au8522_remove(struct i2c_client *client)
818 {
819 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
820 	v4l2_device_unregister_subdev(sd);
821 	au8522_release_state(to_state(sd));
822 	return 0;
823 }
824 
825 static const struct i2c_device_id au8522_id[] = {
826 	{"au8522", 0},
827 	{}
828 };
829 
830 MODULE_DEVICE_TABLE(i2c, au8522_id);
831 
832 static struct i2c_driver au8522_driver = {
833 	.driver = {
834 		.owner	= THIS_MODULE,
835 		.name	= "au8522",
836 	},
837 	.probe		= au8522_probe,
838 	.remove		= au8522_remove,
839 	.id_table	= au8522_id,
840 };
841 
842 module_i2c_driver(au8522_driver);
843