aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@linuxtv.org>2009-03-11 02:00:38 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:43:25 -0400
commit968cf78285ef03672ae514e9ad7a60919eb97551 (patch)
treec26377d32cdff87748b38c82c436c97806763dfb /drivers/media/dvb/frontends
parent209fdf66b8699a6b2998b58e572d67230dae507f (diff)
V4L/DVB (11065): au8522: add support for analog side of demodulator
Add support for the analog functionality in the au8522 analog/digital demodulator Thanks to Michael Krufky <mkrufky@linuxtv.org> and Steven Toth <stoth@linuxtv.org> for providing sample hardware, engineering level support, and testing. Signed-off-by: Devin Heitmueller <dheitmueller@linuxtv.org> Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> [mchehab: renamed drivers/media/video/au8522_decoder.c as drivers/media/dvb/frontends/au8522_decoder.c to avoid breaking bisect] Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/frontends')
-rw-r--r--drivers/media/dvb/frontends/Makefile2
-rw-r--r--drivers/media/dvb/frontends/au8522.h16
-rw-r--r--drivers/media/dvb/frontends/au8522_decoder.c839
-rw-r--r--drivers/media/dvb/frontends/au8522_priv.h347
4 files changed, 1203 insertions, 1 deletions
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 742826523df5..65a336aa1db6 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -8,7 +8,7 @@ EXTRA_CFLAGS += -Idrivers/media/common/tuners/
8s921-objs := s921_module.o s921_core.o 8s921-objs := s921_module.o s921_core.o
9stb0899-objs = stb0899_drv.o stb0899_algo.o 9stb0899-objs = stb0899_drv.o stb0899_algo.o
10stv0900-objs = stv0900_core.o stv0900_sw.o 10stv0900-objs = stv0900_core.o stv0900_sw.o
11au8522-objs = au8522_dig.o 11au8522-objs = au8522_dig.o au8522_decoder.o
12 12
13obj-$(CONFIG_DVB_PLL) += dvb-pll.o 13obj-$(CONFIG_DVB_PLL) += dvb-pll.o
14obj-$(CONFIG_DVB_STV0299) += stv0299.o 14obj-$(CONFIG_DVB_STV0299) += stv0299.o
diff --git a/drivers/media/dvb/frontends/au8522.h b/drivers/media/dvb/frontends/au8522.h
index 7b94f554a093..565dcf31af57 100644
--- a/drivers/media/dvb/frontends/au8522.h
+++ b/drivers/media/dvb/frontends/au8522.h
@@ -74,6 +74,22 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config,
74} 74}
75#endif /* CONFIG_DVB_AU8522 */ 75#endif /* CONFIG_DVB_AU8522 */
76 76
77/* Other modes may need to be added later */
78enum au8522_video_input {
79 AU8522_COMPOSITE_CH1 = 1,
80 AU8522_COMPOSITE_CH2,
81 AU8522_COMPOSITE_CH3,
82 AU8522_COMPOSITE_CH4,
83 AU8522_COMPOSITE_CH4_SIF,
84 AU8522_SVIDEO_CH13,
85 AU8522_SVIDEO_CH24,
86};
87
88enum au8522_audio_input {
89 AU8522_AUDIO_NONE,
90 AU8522_AUDIO_SIF,
91};
92
77#endif /* __AU8522_H__ */ 93#endif /* __AU8522_H__ */
78 94
79/* 95/*
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
new file mode 100644
index 000000000000..e2927c145cd8
--- /dev/null
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -0,0 +1,839 @@
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>
40#include <media/v4l2-i2c-drv-legacy.h>
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
50static unsigned short normal_i2c[] = { 0x8e >> 1, I2C_CLIENT_END };
51
52module_param_named(analog_debug, au8522_analog_debug, int, 0644);
53
54MODULE_PARM_DESC(analog_debug,
55 "Analog debugging messages [0=Off (default) 1=On]");
56
57I2C_CLIENT_INSMOD;
58
59struct au8522_register_config {
60 u16 reg_name;
61 u8 reg_val[8];
62};
63
64
65/* Video Decoder Filter Coefficients
66 The values are as follows from left to right
67 0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13"
68*/
69struct au8522_register_config filter_coef[] = {
70 {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00}},
71 {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00}},
72 {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00}},
73 {AU8522_FILTER_COEF_R413, {0xe6, 0x00, 0xe6, 0xe6, 0x00, 0x00, 0x00}},
74 {AU8522_FILTER_COEF_R414, {0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00}},
75 {AU8522_FILTER_COEF_R415, {0x1b, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00}},
76 {AU8522_FILTER_COEF_R416, {0xc0, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00}},
77 {AU8522_FILTER_COEF_R417, {0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00}},
78 {AU8522_FILTER_COEF_R418, {0x8c, 0x00, 0x8c, 0x8c, 0x00, 0x00, 0x00}},
79 {AU8522_FILTER_COEF_R419, {0xa0, 0x40, 0xa0, 0xa0, 0x40, 0x40, 0x40}},
80 {AU8522_FILTER_COEF_R41A, {0x21, 0x09, 0x21, 0x21, 0x09, 0x09, 0x09}},
81 {AU8522_FILTER_COEF_R41B, {0x6c, 0x38, 0x6c, 0x6c, 0x38, 0x38, 0x38}},
82 {AU8522_FILTER_COEF_R41C, {0x03, 0xff, 0x03, 0x03, 0xff, 0xff, 0xff}},
83 {AU8522_FILTER_COEF_R41D, {0xbf, 0xc7, 0xbf, 0xbf, 0xc7, 0xc7, 0xc7}},
84 {AU8522_FILTER_COEF_R41E, {0xa0, 0xdf, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf}},
85 {AU8522_FILTER_COEF_R41F, {0x10, 0x06, 0x10, 0x10, 0x06, 0x06, 0x06}},
86 {AU8522_FILTER_COEF_R420, {0xae, 0x30, 0xae, 0xae, 0x30, 0x30, 0x30}},
87 {AU8522_FILTER_COEF_R421, {0xc4, 0x01, 0xc4, 0xc4, 0x01, 0x01, 0x01}},
88 {AU8522_FILTER_COEF_R422, {0x54, 0xdd, 0x54, 0x54, 0xdd, 0xdd, 0xdd}},
89 {AU8522_FILTER_COEF_R423, {0xd0, 0xaf, 0xd0, 0xd0, 0xaf, 0xaf, 0xaf}},
90 {AU8522_FILTER_COEF_R424, {0x1c, 0xf7, 0x1c, 0x1c, 0xf7, 0xf7, 0xf7}},
91 {AU8522_FILTER_COEF_R425, {0x76, 0xdb, 0x76, 0x76, 0xdb, 0xdb, 0xdb}},
92 {AU8522_FILTER_COEF_R426, {0x61, 0xc0, 0x61, 0x61, 0xc0, 0xc0, 0xc0}},
93 {AU8522_FILTER_COEF_R427, {0xd1, 0x2f, 0xd1, 0xd1, 0x2f, 0x2f, 0x2f}},
94 {AU8522_FILTER_COEF_R428, {0x84, 0xd8, 0x84, 0x84, 0xd8, 0xd8, 0xd8}},
95 {AU8522_FILTER_COEF_R429, {0x06, 0xfb, 0x06, 0x06, 0xfb, 0xfb, 0xfb}},
96 {AU8522_FILTER_COEF_R42A, {0x21, 0xd5, 0x21, 0x21, 0xd5, 0xd5, 0xd5}},
97 {AU8522_FILTER_COEF_R42B, {0x0a, 0x3e, 0x0a, 0x0a, 0x3e, 0x3e, 0x3e}},
98 {AU8522_FILTER_COEF_R42C, {0xe6, 0x15, 0xe6, 0xe6, 0x15, 0x15, 0x15}},
99 {AU8522_FILTER_COEF_R42D, {0x01, 0x34, 0x01, 0x01, 0x34, 0x34, 0x34}},
100
101};
102#define NUM_FILTER_COEF (sizeof (filter_coef) / sizeof(struct au8522_register_config))
103
104
105/* Registers 0x060b through 0x0652 are the LP Filter coefficients
106 The values are as follows from left to right
107 0="SIF" 1="ATVRF/ATVRF13"
108 Note: the "ATVRF/ATVRF13" mode has never been tested
109*/
110struct au8522_register_config lpfilter_coef[] = {
111 {0x060b, {0x21, 0x0b}},
112 {0x060c, {0xad, 0xad}},
113 {0x060d, {0x70, 0xf0}},
114 {0x060e, {0xea, 0xe9}},
115 {0x060f, {0xdd, 0xdd}},
116 {0x0610, {0x08, 0x64}},
117 {0x0611, {0x60, 0x60}},
118 {0x0612, {0xf8, 0xb2}},
119 {0x0613, {0x01, 0x02}},
120 {0x0614, {0xe4, 0xb4}},
121 {0x0615, {0x19, 0x02}},
122 {0x0616, {0xae, 0x2e}},
123 {0x0617, {0xee, 0xc5}},
124 {0x0618, {0x56, 0x56}},
125 {0x0619, {0x30, 0x58}},
126 {0x061a, {0xf9, 0xf8}},
127 {0x061b, {0x24, 0x64}},
128 {0x061c, {0x07, 0x07}},
129 {0x061d, {0x30, 0x30}},
130 {0x061e, {0xa9, 0xed}},
131 {0x061f, {0x09, 0x0b}},
132 {0x0620, {0x42, 0xc2}},
133 {0x0621, {0x1d, 0x2a}},
134 {0x0622, {0xd6, 0x56}},
135 {0x0623, {0x95, 0x8b}},
136 {0x0624, {0x2b, 0x2b}},
137 {0x0625, {0x30, 0x24}},
138 {0x0626, {0x3e, 0x3e}},
139 {0x0627, {0x62, 0xe2}},
140 {0x0628, {0xe9, 0xf5}},
141 {0x0629, {0x99, 0x19}},
142 {0x062a, {0xd4, 0x11}},
143 {0x062b, {0x03, 0x04}},
144 {0x062c, {0xb5, 0x85}},
145 {0x062d, {0x1e, 0x20}},
146 {0x062e, {0x2a, 0xea}},
147 {0x062f, {0xd7, 0xd2}},
148 {0x0630, {0x15, 0x15}},
149 {0x0631, {0xa3, 0xa9}},
150 {0x0632, {0x1f, 0x1f}},
151 {0x0633, {0xf9, 0xd1}},
152 {0x0634, {0xc0, 0xc3}},
153 {0x0635, {0x4d, 0x8d}},
154 {0x0636, {0x21, 0x31}},
155 {0x0637, {0x83, 0x83}},
156 {0x0638, {0x08, 0x8c}},
157 {0x0639, {0x19, 0x19}},
158 {0x063a, {0x45, 0xa5}},
159 {0x063b, {0xef, 0xec}},
160 {0x063c, {0x8a, 0x8a}},
161 {0x063d, {0xf4, 0xf6}},
162 {0x063e, {0x8f, 0x8f}},
163 {0x063f, {0x44, 0x0c}},
164 {0x0640, {0xef, 0xf0}},
165 {0x0641, {0x66, 0x66}},
166 {0x0642, {0xcc, 0xd2}},
167 {0x0643, {0x41, 0x41}},
168 {0x0644, {0x63, 0x93}},
169 {0x0645, {0x8e, 0x8e}},
170 {0x0646, {0xa2, 0x42}},
171 {0x0647, {0x7b, 0x7b}},
172 {0x0648, {0x04, 0x04}},
173 {0x0649, {0x00, 0x00}},
174 {0x064a, {0x40, 0x40}},
175 {0x064b, {0x8c, 0x98}},
176 {0x064c, {0x00, 0x00}},
177 {0x064d, {0x63, 0xc3}},
178 {0x064e, {0x04, 0x04}},
179 {0x064f, {0x20, 0x20}},
180 {0x0650, {0x00, 0x00}},
181 {0x0651, {0x40 ,0x40}},
182 {0x0652, {0x01, 0x01}},
183};
184#define NUM_LPFILTER_COEF (sizeof (lpfilter_coef) / sizeof(struct au8522_register_config))
185
186static inline struct au8522_state *to_state(struct v4l2_subdev *sd)
187{
188 return container_of(sd, struct au8522_state, sd);
189}
190
191static void setup_vbi(struct au8522_state *state, int aud_input)
192{
193 int i;
194
195 /* These are set to zero regardless of what mode we're in */
196 au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, 0x00);
197 au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_L_REG018H, 0x00);
198 au8522_writereg(state, AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H, 0x00);
199 au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH, 0x00);
200 au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH, 0x00);
201 au8522_writereg(state, AU8522_TVDEC_VBI_USER_THRESH1_REG01CH, 0x00);
202 au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH, 0x00);
203 au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH, 0x00);
204 au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H, 0x00);
205 au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H,0x00);
206 au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H,0x00);
207 au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H,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
224static 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 au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00);
238 au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00);
239
240 /* Other decoder registers */
241 au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
242
243 if (input_mode == 0x23) {
244 /* S-Video input mapping */
245 au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04);
246 } else {
247 /* All other modes (CVBS/ATVRF etc.) */
248 au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00);
249 }
250
251 au8522_writereg(state, AU8522_TVDEC_PGA_REG012H,
252 AU8522_TVDEC_PGA_REG012H_CVBS);
253 au8522_writereg(state, AU8522_TVDEC_COMB_MODE_REG015H,
254 AU8522_TVDEC_COMB_MODE_REG015H_CVBS);
255 au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H,
256 AU8522_TVDED_DBG_MODE_REG060H_CVBS);
257 au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
258 AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13);
259 au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
260 AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13);
261 au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H,
262 AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS);
263 au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H,
264 AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS);
265 au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR1_REG065H,
266 AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS);
267 au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR2_REG066H,
268 AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS);
269 au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR3_REG067H,
270 AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS);
271 au8522_writereg(state, AU8522_TVDEC_COMB_NOTCH_THR_REG068H,
272 AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS);
273 au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR1_REG069H,
274 AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS);
275 au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR2_REG06AH,
276 AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
277 au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
278 AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
279 au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
280 AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
281 au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
282 AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
283 au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH,
284 AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS);
285 au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH,
286 AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS);
287 au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H,
288 AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS);
289 au8522_writereg(state, AU8522_REG071H, AU8522_REG071H_CVBS);
290 au8522_writereg(state, AU8522_REG072H, AU8522_REG072H_CVBS);
291 au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H,
292 AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS);
293 au8522_writereg(state, AU8522_REG074H, AU8522_REG074H_CVBS);
294 au8522_writereg(state, AU8522_REG075H, AU8522_REG075H_CVBS);
295 au8522_writereg(state, AU8522_TVDEC_DCAGC_CTRL_REG077H,
296 AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS);
297 au8522_writereg(state, AU8522_TVDEC_PIC_START_ADJ_REG078H,
298 AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS);
299 au8522_writereg(state, AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H,
300 AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS);
301 au8522_writereg(state, AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH,
302 AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS);
303 au8522_writereg(state, AU8522_TVDEC_INTRP_CTRL_REG07BH,
304 AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS);
305 au8522_writereg(state, AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H,
306 AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS);
307 au8522_writereg(state, AU8522_TOREGAAGC_REG0E5H,
308 AU8522_TOREGAAGC_REG0E5H_CVBS);
309 au8522_writereg(state, AU8522_REG016H, AU8522_REG016H_CVBS);
310
311 setup_vbi(state, 0);
312
313 if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
314 input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
315 /* Despite what the table says, for the HVR-950q we still need
316 to be in CVBS mode for the S-Video input (reason uknown). */
317 /* filter_coef_type = 3; */
318 filter_coef_type = 5;
319 } else {
320 filter_coef_type = 5;
321 }
322
323 /* Load the Video Decoder Filter Coefficients */
324 for (i = 0; i < NUM_FILTER_COEF; i++) {
325 au8522_writereg(state, filter_coef[i].reg_name,
326 filter_coef[i].reg_val[filter_coef_type]);
327 }
328
329 /* It's not clear what these registers are for, but they are always
330 set to the same value regardless of what mode we're in */
331 au8522_writereg(state, AU8522_REG42EH, 0x87);
332 au8522_writereg(state, AU8522_REG42FH, 0xa2);
333 au8522_writereg(state, AU8522_REG430H, 0xbf);
334 au8522_writereg(state, AU8522_REG431H, 0xcb);
335 au8522_writereg(state, AU8522_REG432H, 0xa1);
336 au8522_writereg(state, AU8522_REG433H, 0x41);
337 au8522_writereg(state, AU8522_REG434H, 0x88);
338 au8522_writereg(state, AU8522_REG435H, 0xc2);
339 au8522_writereg(state, AU8522_REG436H, 0x3c);
340}
341
342static void au8522_setup_cvbs_mode(struct au8522_state *state)
343{
344 /* here we're going to try the pre-programmed route */
345 au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
346 AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
347
348 au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
349 au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
350 au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
351
352 au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
353 AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
354
355 setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
356
357 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
358 AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
359}
360
361static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
362{
363 /* here we're going to try the pre-programmed route */
364 au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
365 AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
366
367 /* It's not clear why they turn off the PGA before enabling the clamp
368 control, but the Windows trace does it so we will too... */
369 au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
370
371 /* Enable clamping control */
372 au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
373
374 /* Turn on the PGA */
375 au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
376
377 /* Set input mode to CVBS on channel 4 with SIF audio input enabled */
378 au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
379 AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
380
381 setup_decoder_defaults(state,
382 AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
383
384 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
385 AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
386}
387
388static void au8522_setup_svideo_mode(struct au8522_state *state)
389{
390 au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
391 AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO);
392
393 /* Set input to Y on Channe1, C on Channel 3 */
394 au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
395 AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
396
397 /* Disable clamping control (required for S-video) */
398 au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
399
400 setup_decoder_defaults(state,
401 AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
402
403 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
404 AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
405}
406
407/* ----------------------------------------------------------------------- */
408
409static void disable_audio_input(struct au8522_state *state)
410{
411 /* This can probably be optimized */
412 au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
413 au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
414 au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
415 au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
416 au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
417
418 au8522_writereg(state, AU8522_ENA_USB_REG101H, 0x00);
419 au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
420 au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
421 au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
422 au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x40);
423
424 au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x11);
425 msleep(5);
426 au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x00);
427
428 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04);
429 au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
430 au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02);
431
432 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
433 AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
434}
435
436/* 0=disable, 1=SIF */
437static void set_audio_input(struct au8522_state *state, int aud_input)
438{
439 int i;
440
441 /* Note that this function needs to be used in conjunction with setting
442 the input routing via register 0x81 */
443
444 if (aud_input == AU8522_AUDIO_NONE) {
445 disable_audio_input(state);
446 return;
447 }
448
449 if (aud_input != AU8522_AUDIO_SIF) {
450 /* The caller asked for a mode we don't currently support */
451 printk("Unsupported audio mode requested! mode=%d\n",
452 aud_input);
453 return;
454 }
455
456 /* Load the Audio Decoder Filter Coefficients */
457 for (i = 0; i < NUM_LPFILTER_COEF; i++) {
458 au8522_writereg(state, lpfilter_coef[i].reg_name,
459 lpfilter_coef[i].reg_val[0]);
460 }
461
462 /* Setup audio */
463 au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
464 au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
465 au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
466 au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
467 au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
468 msleep(150);
469 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00);
470 msleep(1);
471 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d);
472 msleep(50);
473 au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
474 au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
475 au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0xff);
476 msleep(80);
477 au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
478 au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
479 au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
480 au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x82);
481 msleep(70);
482 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x09);
483 au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
484 au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0xc2);
485}
486
487/* ----------------------------------------------------------------------- */
488
489static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
490{
491 struct au8522_state *state = to_state(sd);
492
493 switch (ctrl->id) {
494 case V4L2_CID_BRIGHTNESS:
495 state->brightness = ctrl->value;
496 au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH,
497 ctrl->value - 128);
498 break;
499 case V4L2_CID_CONTRAST:
500 state->contrast = ctrl->value;
501 au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH,
502 ctrl->value);
503 break;
504 case V4L2_CID_SATURATION:
505 case V4L2_CID_HUE:
506 case V4L2_CID_AUDIO_VOLUME:
507 case V4L2_CID_AUDIO_BASS:
508 case V4L2_CID_AUDIO_TREBLE:
509 case V4L2_CID_AUDIO_BALANCE:
510 case V4L2_CID_AUDIO_MUTE:
511 /* Not yet implemented */
512 default:
513 return -EINVAL;
514 }
515
516 return 0;
517}
518
519static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
520{
521 struct au8522_state *state = to_state(sd);
522
523 /* Note that we are using values cached in the state structure instead
524 of reading the registers due to issues with i2c reads not working
525 properly/consistently yet on the HVR-950q */
526
527 switch (ctrl->id) {
528 case V4L2_CID_BRIGHTNESS:
529 ctrl->value = state->brightness;
530 break;
531 case V4L2_CID_CONTRAST:
532 ctrl->value = state->contrast;
533 break;
534 case V4L2_CID_SATURATION:
535 case V4L2_CID_HUE:
536 case V4L2_CID_AUDIO_VOLUME:
537 case V4L2_CID_AUDIO_BASS:
538 case V4L2_CID_AUDIO_TREBLE:
539 case V4L2_CID_AUDIO_BALANCE:
540 case V4L2_CID_AUDIO_MUTE:
541 /* Not yet supported */
542 default:
543 return -EINVAL;
544 }
545
546 return 0;
547}
548
549/* ----------------------------------------------------------------------- */
550
551static int au8522_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
552{
553 switch (fmt->type) {
554 default:
555 return -EINVAL;
556 }
557 return 0;
558}
559
560static int au8522_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
561{
562 switch (fmt->type) {
563 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
564 /* Not yet implemented */
565 break;
566 default:
567 return -EINVAL;
568 }
569
570 return 0;
571}
572
573/* ----------------------------------------------------------------------- */
574
575#ifdef CONFIG_VIDEO_ADV_DEBUG
576static int au8522_g_register(struct v4l2_subdev *sd,
577 struct v4l2_dbg_register *reg)
578{
579 struct i2c_client *client = v4l2_get_subdevdata(sd);
580 struct au8522_state *state = to_state(sd);
581
582 if (!v4l2_chip_match_i2c_client(client, &reg->match))
583 return -EINVAL;
584 if (!capable(CAP_SYS_ADMIN))
585 return -EPERM;
586 reg->val = au8522_readreg(state, reg->reg & 0xffff);
587 return 0;
588}
589
590static int au8522_s_register(struct v4l2_subdev *sd,
591 struct v4l2_dbg_register *reg)
592{
593 struct i2c_client *client = v4l2_get_subdevdata(sd);
594 struct au8522_state *state = to_state(sd);
595
596 if (!v4l2_chip_match_i2c_client(client, &reg->match))
597 return -EINVAL;
598 if (!capable(CAP_SYS_ADMIN))
599 return -EPERM;
600 au8522_writereg(state, reg->reg, reg->val & 0xff);
601 return 0;
602}
603#endif
604
605static int au8522_s_stream(struct v4l2_subdev *sd, int enable)
606{
607 struct au8522_state *state = to_state(sd);
608
609 if (enable) {
610 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
611 0x01);
612 msleep(1);
613 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
614 AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
615 } else {
616 /* This does not completely power down the device
617 (it only reduces it from around 140ma to 80ma) */
618 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
619 1 << 5);
620 }
621 return 0;
622}
623
624static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
625{
626 switch (qc->id) {
627 case V4L2_CID_CONTRAST:
628 return v4l2_ctrl_query_fill(qc, 0, 255, 1,
629 AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
630 case V4L2_CID_BRIGHTNESS:
631 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
632 case V4L2_CID_SATURATION:
633 case V4L2_CID_HUE:
634 /* Not yet implemented */
635 default:
636 break;
637 }
638
639 return -EINVAL;
640}
641
642static int au8522_reset(struct v4l2_subdev *sd, u32 val)
643{
644 struct au8522_state *state = to_state(sd);
645
646 au8522_writereg(state, 0xa4, 1 << 5);
647
648 return 0;
649}
650
651static int au8522_s_video_routing(struct v4l2_subdev *sd,
652 const struct v4l2_routing *route)
653{
654 struct au8522_state *state = to_state(sd);
655
656 au8522_reset(sd, 0);
657
658 /* Jam open the i2c gate to the tuner. We do this here to handle the
659 case where the user went into digital mode (causing the gate to be
660 closed), and then came back to analog mode */
661 au8522_writereg(state, 0x106, 1);
662
663 if (route->input == AU8522_COMPOSITE_CH1) {
664 au8522_setup_cvbs_mode(state);
665 } else if (route->input == AU8522_SVIDEO_CH13) {
666 au8522_setup_svideo_mode(state);
667 } else if (route->input == AU8522_COMPOSITE_CH4_SIF) {
668 au8522_setup_cvbs_tuner_mode(state);
669 } else {
670 printk("au8522 mode not currently supported\n");
671 return -EINVAL;
672 }
673 return 0;
674}
675
676static int au8522_s_audio_routing(struct v4l2_subdev *sd,
677 const struct v4l2_routing *route)
678{
679 struct au8522_state *state = to_state(sd);
680 set_audio_input(state, route->input);
681 return 0;
682}
683
684static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
685{
686 int val = 0;
687 struct au8522_state *state = to_state(sd);
688 u8 lock_status;
689
690 /* Interrogate the decoder to see if we are getting a real signal */
691 lock_status = au8522_readreg(state, 0x00);
692 if (lock_status == 0xa2)
693 vt->signal = 0x01;
694 else
695 vt->signal = 0x00;
696
697 vt->capability |=
698 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
699 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
700
701 val = V4L2_TUNER_SUB_MONO;
702 vt->rxsubchans = val;
703 vt->audmode = V4L2_TUNER_MODE_STEREO;
704 return 0;
705}
706
707static int au8522_g_chip_ident(struct v4l2_subdev *sd,
708 struct v4l2_dbg_chip_ident *chip)
709{
710 struct au8522_state *state = to_state(sd);
711 struct i2c_client *client = v4l2_get_subdevdata(sd);
712
713 return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
714}
715
716static int au8522_log_status(struct v4l2_subdev *sd)
717{
718 /* FIXME: Add some status info here */
719 return 0;
720}
721
722static int au8522_command(struct i2c_client *client, unsigned cmd, void *arg)
723{
724 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
725}
726
727/* ----------------------------------------------------------------------- */
728
729static const struct v4l2_subdev_core_ops au8522_core_ops = {
730 .log_status = au8522_log_status,
731 .g_chip_ident = au8522_g_chip_ident,
732 .g_ctrl = au8522_g_ctrl,
733 .s_ctrl = au8522_s_ctrl,
734 .queryctrl = au8522_queryctrl,
735 .reset = au8522_reset,
736#ifdef CONFIG_VIDEO_ADV_DEBUG
737 .g_register = au8522_g_register,
738 .s_register = au8522_s_register,
739#endif
740};
741
742static const struct v4l2_subdev_tuner_ops au8522_tuner_ops = {
743 .g_tuner = au8522_g_tuner,
744};
745
746static const struct v4l2_subdev_audio_ops au8522_audio_ops = {
747 .s_routing = au8522_s_audio_routing,
748};
749
750static const struct v4l2_subdev_video_ops au8522_video_ops = {
751 .s_routing = au8522_s_video_routing,
752 .g_fmt = au8522_g_fmt,
753 .s_fmt = au8522_s_fmt,
754 .s_stream = au8522_s_stream,
755};
756
757static const struct v4l2_subdev_ops au8522_ops = {
758 .core = &au8522_core_ops,
759 .tuner = &au8522_tuner_ops,
760 .audio = &au8522_audio_ops,
761 .video = &au8522_video_ops,
762};
763
764/* ----------------------------------------------------------------------- */
765
766static int au8522_probe(struct i2c_client *client,
767 const struct i2c_device_id *did)
768{
769 struct au8522_state *state;
770 struct v4l2_subdev *sd;
771 int instance;
772 struct au8522_config *demod_config;
773
774 /* Check if the adapter supports the needed features */
775 if (!i2c_check_functionality(client->adapter,
776 I2C_FUNC_SMBUS_BYTE_DATA)) {
777 return -EIO;
778 }
779
780 /* allocate memory for the internal state */
781 instance = au8522_get_state(&state, client->adapter, client->addr);
782 switch (instance) {
783 case 0:
784 printk("au8522_decoder allocation failed\n");
785 return -EIO;
786 case 1:
787 /* new demod instance */
788 printk("au8522_decoder creating new instance...\n");
789 break;
790 default:
791 /* existing demod instance */
792 printk("au8522_decoder attaching to existing instance...\n");
793 break;
794 }
795
796 demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL);
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
817static 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
825static const struct i2c_device_id au8522_id[] = {
826 {"au8522", 0},
827 {}
828};
829
830MODULE_DEVICE_TABLE(i2c, au8522_id);
831
832static struct v4l2_i2c_driver_data v4l2_i2c_data = {
833 .name = "au8522",
834 .driverid = I2C_DRIVERID_AU8522,
835 .command = au8522_command,
836 .probe = au8522_probe,
837 .remove = au8522_remove,
838 .id_table = au8522_id,
839};
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h
index 98b09caa2123..f328f2b3ad3d 100644
--- a/drivers/media/dvb/frontends/au8522_priv.h
+++ b/drivers/media/dvb/frontends/au8522_priv.h
@@ -35,6 +35,7 @@
35#include "tuner-i2c.h" 35#include "tuner-i2c.h"
36 36
37struct au8522_state { 37struct au8522_state {
38 struct i2c_client *c;
38 struct i2c_adapter *i2c; 39 struct i2c_adapter *i2c;
39 40
40 /* Used for sharing of the state between analog and digital mode */ 41 /* Used for sharing of the state between analog and digital mode */
@@ -51,6 +52,16 @@ struct au8522_state {
51 52
52 u32 fe_status; 53 u32 fe_status;
53 unsigned int led_state; 54 unsigned int led_state;
55
56 /* Analog settings */
57 struct v4l2_subdev sd;
58 v4l2_std_id std;
59 int vid_input;
60 int aud_input;
61 u32 id;
62 u32 rev;
63 u8 brightness;
64 u8 contrast;
54}; 65};
55 66
56/* These are routines shared by both the VSB/QAM demodulator and the analog 67/* These are routines shared by both the VSB/QAM demodulator and the analog
@@ -63,3 +74,339 @@ int au8522_sleep(struct dvb_frontend *fe);
63int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, 74int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
64 u8 client_address); 75 u8 client_address);
65void au8522_release_state(struct au8522_state *state); 76void au8522_release_state(struct au8522_state *state);
77
78/* REGISTERS */
79#define AU8522_INPUT_CONTROL_REG081H 0x081
80#define AU8522_PGA_CONTROL_REG082H 0x082
81#define AU8522_CLAMPING_CONTROL_REG083H 0x083
82
83#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H 0x0A3
84#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H 0x0A4
85#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H 0x0A5
86#define AU8522_AGC_CONTROL_RANGE_REG0A6H 0x0A6
87#define AU8522_SYSTEM_GAIN_CONTROL_REG0A7H 0x0A7
88#define AU8522_TUNER_AGC_RF_STOP_REG0A8H 0x0A8
89#define AU8522_TUNER_AGC_RF_START_REG0A9H 0x0A9
90#define AU8522_TUNER_RF_AGC_DEFAULT_REG0AAH 0x0AA
91#define AU8522_TUNER_AGC_IF_STOP_REG0ABH 0x0AB
92#define AU8522_TUNER_AGC_IF_START_REG0ACH 0x0AC
93#define AU8522_TUNER_AGC_IF_DEFAULT_REG0ADH 0x0AD
94#define AU8522_TUNER_AGC_STEP_REG0AEH 0x0AE
95#define AU8522_TUNER_GAIN_STEP_REG0AFH 0x0AF
96
97/* Receiver registers */
98#define AU8522_FRMREGTHRD1_REG0B0H 0x0B0
99#define AU8522_FRMREGAGC1H_REG0B1H 0x0B1
100#define AU8522_FRMREGSHIFT1_REG0B2H 0x0B2
101#define AU8522_TOREGAGC1_REG0B3H 0x0B3
102#define AU8522_TOREGASHIFT1_REG0B4H 0x0B4
103#define AU8522_FRMREGBBH_REG0B5H 0x0B5
104#define AU8522_FRMREGBBM_REG0B6H 0x0B6
105#define AU8522_FRMREGBBL_REG0B7H 0x0B7
106/* 0xB8 TO 0xD7 are the filter coefficients */
107#define AU8522_FRMREGTHRD2_REG0D8H 0x0D8
108#define AU8522_FRMREGAGC2H_REG0D9H 0x0D9
109#define AU8522_TOREGAGC2_REG0DAH 0x0DA
110#define AU8522_TOREGSHIFT2_REG0DBH 0x0DB
111#define AU8522_FRMREGPILOTH_REG0DCH 0x0DC
112#define AU8522_FRMREGPILOTM_REG0DDH 0x0DD
113#define AU8522_FRMREGPILOTL_REG0DEH 0x0DE
114#define AU8522_TOREGFREQ_REG0DFH 0x0DF
115
116#define AU8522_RX_PGA_RFOUT_REG0EBH 0x0EB
117#define AU8522_RX_PGA_IFOUT_REG0ECH 0x0EC
118#define AU8522_RX_PGA_PGAOUT_REG0EDH 0x0ED
119
120#define AU8522_CHIP_MODE_REG0FEH 0x0FE
121
122/* I2C bus control registers */
123#define AU8522_I2C_CONTROL_REG0_REG090H 0x090
124#define AU8522_I2C_CONTROL_REG1_REG091H 0x091
125#define AU8522_I2C_STATUS_REG092H 0x092
126#define AU8522_I2C_WR_DATA0_REG093H 0x093
127#define AU8522_I2C_WR_DATA1_REG094H 0x094
128#define AU8522_I2C_WR_DATA2_REG095H 0x095
129#define AU8522_I2C_WR_DATA3_REG096H 0x096
130#define AU8522_I2C_WR_DATA4_REG097H 0x097
131#define AU8522_I2C_WR_DATA5_REG098H 0x098
132#define AU8522_I2C_WR_DATA6_REG099H 0x099
133#define AU8522_I2C_WR_DATA7_REG09AH 0x09A
134#define AU8522_I2C_RD_DATA0_REG09BH 0x09B
135#define AU8522_I2C_RD_DATA1_REG09CH 0x09C
136#define AU8522_I2C_RD_DATA2_REG09DH 0x09D
137#define AU8522_I2C_RD_DATA3_REG09EH 0x09E
138#define AU8522_I2C_RD_DATA4_REG09FH 0x09F
139#define AU8522_I2C_RD_DATA5_REG0A0H 0x0A0
140#define AU8522_I2C_RD_DATA6_REG0A1H 0x0A1
141#define AU8522_I2C_RD_DATA7_REG0A2H 0x0A2
142
143#define AU8522_ENA_USB_REG101H 0x101
144
145#define AU8522_I2S_CTRL_0_REG110H 0x110
146#define AU8522_I2S_CTRL_1_REG111H 0x111
147#define AU8522_I2S_CTRL_2_REG112H 0x112
148
149#define AU8522_FRMREGFFECONTROL_REG121H 0x121
150#define AU8522_FRMREGDFECONTROL_REG122H 0x122
151
152#define AU8522_CARRFREQOFFSET0_REG201H 0x201
153#define AU8522_CARRFREQOFFSET1_REG202H 0x202
154
155#define AU8522_DECIMATION_GAIN_REG21AH 0x21A
156#define AU8522_FRMREGIFSLP_REG21BH 0x21B
157#define AU8522_FRMREGTHRDL2_REG21CH 0x21C
158#define AU8522_FRMREGSTEP3DB_REG21DH 0x21D
159#define AU8522_DAGC_GAIN_ADJUSTMENT_REG21EH 0x21E
160#define AU8522_FRMREGPLLMODE_REG21FH 0x21F
161#define AU8522_FRMREGCSTHRD_REG220H 0x220
162#define AU8522_FRMREGCRLOCKDMAX_REG221H 0x221
163#define AU8522_FRMREGCRPERIODMASK_REG222H 0x222
164#define AU8522_FRMREGCRLOCK0THH_REG223H 0x223
165#define AU8522_FRMREGCRLOCK1THH_REG224H 0x224
166#define AU8522_FRMREGCRLOCK0THL_REG225H 0x225
167#define AU8522_FRMREGCRLOCK1THL_REG226H 0x226
168#define AU_FRMREGPLLACQPHASESCL_REG227H 0x227
169#define AU8522_FRMREGFREQFBCTRL_REG228H 0x228
170
171/* Analog TV Decoder */
172#define AU8522_TVDEC_STATUS_REG000H 0x000
173#define AU8522_TVDEC_INT_STATUS_REG001H 0x001
174#define AU8522_TVDEC_MACROVISION_STATUS_REG002H 0x002
175#define AU8522_TVDEC_SHARPNESSREG009H 0x009
176#define AU8522_TVDEC_BRIGHTNESS_REG00AH 0x00A
177#define AU8522_TVDEC_CONTRAST_REG00BH 0x00B
178#define AU8522_TVDEC_SATURATION_CB_REG00CH 0x00C
179#define AU8522_TVDEC_SATURATION_CR_REG00DH 0x00D
180#define AU8522_TVDEC_HUE_H_REG00EH 0x00E
181#define AU8522_TVDEC_HUE_L_REG00FH 0x00F
182#define AU8522_TVDEC_INT_MASK_REG010H 0x010
183#define AU8522_VIDEO_MODE_REG011H 0x011
184#define AU8522_TVDEC_PGA_REG012H 0x012
185#define AU8522_TVDEC_COMB_MODE_REG015H 0x015
186#define AU8522_REG016H 0x016
187#define AU8522_TVDED_DBG_MODE_REG060H 0x060
188#define AU8522_TVDEC_FORMAT_CTRL1_REG061H 0x061
189#define AU8522_TVDEC_FORMAT_CTRL2_REG062H 0x062
190#define AU8522_TVDEC_VCR_DET_LLIM_REG063H 0x063
191#define AU8522_TVDEC_VCR_DET_HLIM_REG064H 0x064
192#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H 0x065
193#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H 0x066
194#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H 0x067
195#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H 0x068
196#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H 0x069
197#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH 0x06A
198#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH 0x06B
199#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH 0x06C
200#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH 0x06D
201#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH 0x06E
202#define AU8522_TVDEC_UV_SEP_THR_REG06FH 0x06F
203#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H 0x070
204#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H 0x073
205#define AU8522_TVDEC_DCAGC_CTRL_REG077H 0x077
206#define AU8522_TVDEC_PIC_START_ADJ_REG078H 0x078
207#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H 0x079
208#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH 0x07A
209#define AU8522_TVDEC_INTRP_CTRL_REG07BH 0x07B
210#define AU8522_TVDEC_PLL_STATUS_REG07EH 0x07E
211#define AU8522_TVDEC_FSC_FREQ_REG07FH 0x07F
212
213#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H 0x0E4
214#define AU8522_TOREGAAGC_REG0E5H 0x0E5
215
216#define AU8522_TVDEC_CHROMA_AGC_REG401H 0x401
217#define AU8522_TVDEC_CHROMA_SFT_REG402H 0x402
218#define AU8522_FILTER_COEF_R410 0x410
219#define AU8522_FILTER_COEF_R411 0x411
220#define AU8522_FILTER_COEF_R412 0x412
221#define AU8522_FILTER_COEF_R413 0x413
222#define AU8522_FILTER_COEF_R414 0x414
223#define AU8522_FILTER_COEF_R415 0x415
224#define AU8522_FILTER_COEF_R416 0x416
225#define AU8522_FILTER_COEF_R417 0x417
226#define AU8522_FILTER_COEF_R418 0x418
227#define AU8522_FILTER_COEF_R419 0x419
228#define AU8522_FILTER_COEF_R41A 0x41A
229#define AU8522_FILTER_COEF_R41B 0x41B
230#define AU8522_FILTER_COEF_R41C 0x41C
231#define AU8522_FILTER_COEF_R41D 0x41D
232#define AU8522_FILTER_COEF_R41E 0x41E
233#define AU8522_FILTER_COEF_R41F 0x41F
234#define AU8522_FILTER_COEF_R420 0x420
235#define AU8522_FILTER_COEF_R421 0x421
236#define AU8522_FILTER_COEF_R422 0x422
237#define AU8522_FILTER_COEF_R423 0x423
238#define AU8522_FILTER_COEF_R424 0x424
239#define AU8522_FILTER_COEF_R425 0x425
240#define AU8522_FILTER_COEF_R426 0x426
241#define AU8522_FILTER_COEF_R427 0x427
242#define AU8522_FILTER_COEF_R428 0x428
243#define AU8522_FILTER_COEF_R429 0x429
244#define AU8522_FILTER_COEF_R42A 0x42A
245#define AU8522_FILTER_COEF_R42B 0x42B
246#define AU8522_FILTER_COEF_R42C 0x42C
247#define AU8522_FILTER_COEF_R42D 0x42D
248
249/* VBI Control Registers */
250#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H 0x004
251#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H 0x005
252#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H 0x006
253#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H 0x007
254#define AU8522_TVDEC_VBI_CTRL_H_REG017H 0x017
255#define AU8522_TVDEC_VBI_CTRL_L_REG018H 0x018
256#define AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H 0x019
257#define AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH 0x01A
258#define AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH 0x01B
259#define AU8522_TVDEC_VBI_USER_THRESH1_REG01CH 0x01C
260#define AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH 0x01E
261#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH 0x01F
262#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H 0x020
263#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H 0x021
264#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H 0x022
265#define AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H 0x023
266
267#define AU8522_REG071H 0x071
268#define AU8522_REG072H 0x072
269#define AU8522_REG074H 0x074
270#define AU8522_REG075H 0x075
271
272/* Digital Demodulator Registers */
273#define AU8522_FRAME_COUNT0_REG084H 0x084
274#define AU8522_RS_STATUS_G0_REG085H 0x085
275#define AU8522_RS_STATUS_B0_REG086H 0x086
276#define AU8522_RS_STATUS_E_REG087H 0x087
277#define AU8522_DEMODULATION_STATUS_REG088H 0x088
278#define AU8522_TOREGTRESTATUS_REG0E6H 0x0E6
279#define AU8522_TSPORT_CONTROL_REG10BH 0x10B
280#define AU8522_TSTHES_REG10CH 0x10C
281#define AU8522_FRMREGDFEKEEP_REG301H 0x301
282#define AU8522_DFE_AVERAGE_REG302H 0x302
283#define AU8522_FRMREGEQLERRWIN_REG303H 0x303
284#define AU8522_FRMREGFFEKEEP_REG304H 0x304
285#define AU8522_FRMREGDFECONTROL1_REG305H 0x305
286#define AU8522_FRMREGEQLERRLOW_REG306H 0x306
287
288#define AU8522_REG42EH 0x42E
289#define AU8522_REG42FH 0x42F
290#define AU8522_REG430H 0x430
291#define AU8522_REG431H 0x431
292#define AU8522_REG432H 0x432
293#define AU8522_REG433H 0x433
294#define AU8522_REG434H 0x434
295#define AU8522_REG435H 0x435
296#define AU8522_REG436H 0x436
297
298/* GPIO Registers */
299#define AU8522_GPIO_CONTROL_REG0E0H 0x0E0
300#define AU8522_GPIO_STATUS_REG0E1H 0x0E1
301#define AU8522_GPIO_DATA_REG0E2H 0x0E2
302
303/* Audio Control Registers */
304#define AU8522_AUDIOAGC_REG0EEH 0x0EE
305#define AU8522_AUDIO_STATUS_REG0F0H 0x0F0
306#define AU8522_AUDIO_MODE_REG0F1H 0x0F1
307#define AU8522_AUDIO_VOLUME_L_REG0F2H 0x0F2
308#define AU8522_AUDIO_VOLUME_R_REG0F3H 0x0F3
309#define AU8522_AUDIO_VOLUME_REG0F4H 0x0F4
310#define AU8522_FRMREGAUPHASE_REG0F7H 0x0F7
311#define AU8522_REG0F9H 0x0F9
312
313#define AU8522_AUDIOAGC2_REG605H 0x605
314#define AU8522_AUDIOFREQ_REG606H 0x606
315
316
317/**************************************************************/
318
319#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4
320#define AU8522_INPUT_CONTROL_REG081H_ATVRF 0xC4
321#define AU8522_INPUT_CONTROL_REG081H_ATVRF13 0xC4
322#define AU8522_INPUT_CONTROL_REG081H_J83B64 0xC4
323#define AU8522_INPUT_CONTROL_REG081H_J83B256 0xC4
324#define AU8522_INPUT_CONTROL_REG081H_CVBS 0x20
325#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH1 0xA2
326#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH2 0xA0
327#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH3 0x69
328#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4 0x68
329#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF 0x28
330/* CH1 AS Y,CH3 AS C */
331#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 0x23
332/* CH2 AS Y,CH4 AS C */
333#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24 0x20
334#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC 0x0C
335#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64 0x09
336#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256 0x09
337#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS 0x12
338#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF 0x1A
339#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF13 0x1A
340#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO 0x02
341
342#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CLEAR 0x00
343#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO 0x9C
344#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS 0x9D
345#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATSC 0xE8
346#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256 0xCA
347#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64 0xCA
348#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF 0xDD
349#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF13 0xDD
350#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_PAL 0xDD
351#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_FM 0xDD
352
353#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATSC 0x80
354#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256 0x80
355#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64 0x80
356#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_ATSC 0x40
357#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B256 0x40
358#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B64 0x40
359#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_CLEAR 0x00
360#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF 0x01
361#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF13 0x01
362#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO 0x04
363#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_CVBS 0x01
364#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM 0x03
365#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS 0x09
366#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PAL 0x01
367#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_FM 0x01
368
369/* STILL NEED TO BE REFACTORED @@@@@@@@@@@@@@ */
370#define AU8522_TVDEC_CONTRAST_REG00BH_CVBS 0x79
371#define AU8522_TVDEC_SATURATION_CB_REG00CH_CVBS 0x80
372#define AU8522_TVDEC_SATURATION_CR_REG00DH_CVBS 0x80
373#define AU8522_TVDEC_HUE_H_REG00EH_CVBS 0x00
374#define AU8522_TVDEC_HUE_L_REG00FH_CVBS 0x00
375#define AU8522_TVDEC_PGA_REG012H_CVBS 0x0F
376#define AU8522_TVDEC_COMB_MODE_REG015H_CVBS 0x00
377#define AU8522_REG016H_CVBS 0x00
378#define AU8522_TVDED_DBG_MODE_REG060H_CVBS 0x00
379#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS 0x0B
380#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13 0x03
381#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13 0x00
382#define AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS 0x19
383#define AU8522_REG0F9H_AUDIO 0x20
384#define AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS 0xA7
385#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS 0x0A
386#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS 0x32
387#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS 0x19
388#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS 0x23
389#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS 0x41
390#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS 0x0A
391#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS 0x32
392#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS 0x34
393#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS 0x05
394#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS 0x6E
395#define AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS 0x0F
396#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS 0x80
397#define AU8522_REG071H_CVBS 0x18
398#define AU8522_REG072H_CVBS 0x30
399#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS 0xF0
400#define AU8522_REG074H_CVBS 0x80
401#define AU8522_REG075H_CVBS 0xF0
402#define AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS 0xFB
403#define AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS 0x04
404#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS 0x00
405#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS 0x00
406#define AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS 0xEE
407#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS 0xFE
408#define AU8522_TOREGAAGC_REG0E5H_CVBS 0x00
409#define AU8522_TVDEC_VBI6A_REG035H_CVBS 0x40
410
411/* Enables Closed captioning */
412#define AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON 0x21