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