aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-26 12:49:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-26 12:49:51 -0400
commitc837c93a03be711dd6e09215b74b4f23bbd1ff83 (patch)
tree4b3ffe42eea9c9b3af8eee916345c65a0334edfc
parentd485cb9aa2e302fac7e7fb586a0cb4c0a5211be9 (diff)
parent37c45df740f79c58bb0fc0de151fd2504234032b (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: V4L/DVB (7751): ir-kbd-i2c: Save a temporary memory allocation in ir_probe V4L/DVB (7750): au0828/ cleanups and fixes V4L/DVB (7748): tuner-core: some adjustments at tuner logs, if debug enabled V4L/DVB (7746): pvrusb2: make signed one-bit bitfields unsigned V4L/DVB (7744): pvrusb2-dvb: add atsc/qam support for Hauppauge pvrusb2 model 751xx V4L/DVB (7742): cx88: Add support for the DViCO FusionHDTV_7_GOLD digital modes V4L/DVB (7741): s5h1411: Adding support for this ATSC/QAM demodulator V4L/DVB (7740): tuner-xc2028.c dubious !x & y V4L/DVB (7739): mt312.h: dubious one-bit signed bitfield V4L/DVB (7735): Fix compilation for au0828 V4L/DVB (7734): em28xx: copy and paste error in em28xx_init_isoc V4L/DVB (7733): blackbird_find_mailbox negative return ignored in blackbird_initialize_codec() V4L/DVB (7732): vivi: fix a warning
-rw-r--r--drivers/media/dvb/frontends/Kconfig8
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/mt312.h2
-rw-r--r--drivers/media/dvb/frontends/s5h1411.c888
-rw-r--r--drivers/media/dvb/frontends/s5h1411.h90
-rw-r--r--drivers/media/video/au0828/Kconfig2
-rw-r--r--drivers/media/video/au0828/au0828-cards.c1
-rw-r--r--drivers/media/video/au0828/au0828-core.c26
-rw-r--r--drivers/media/video/au0828/au0828-dvb.c2
-rw-r--r--drivers/media/video/au0828/au0828-i2c.c6
-rw-r--r--drivers/media/video/au0828/au0828.h8
-rw-r--r--drivers/media/video/cx88/Kconfig1
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c6
-rw-r--r--drivers/media/video/cx88/cx88-cards.c1
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c32
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c2
-rw-r--r--drivers/media/video/ir-kbd-i2c.c21
-rw-r--r--drivers/media/video/pvrusb2/Kconfig1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c28
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.h22
-rw-r--r--drivers/media/video/tuner-core.c92
-rw-r--r--drivers/media/video/tuner-xc2028.c2
-rw-r--r--drivers/media/video/vivi.c2
23 files changed, 1135 insertions, 109 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 68fab616f55d..f5fceb3cdb3c 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -307,6 +307,14 @@ config DVB_AU8522
307 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want 307 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
308 to support this frontend. 308 to support this frontend.
309 309
310config DVB_S5H1411
311 tristate "Samsung S5H1411 based"
312 depends on DVB_CORE && I2C
313 default m if DVB_FE_CUSTOMISE
314 help
315 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
316 to support this frontend.
317
310comment "Tuners/PLL support" 318comment "Tuners/PLL support"
311 depends on DVB_CORE 319 depends on DVB_CORE
312 320
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 2f873fc0f649..9747c73dc826 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_DVB_TUNER_XC5000) += xc5000.o
55obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o 55obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
56obj-$(CONFIG_DVB_AU8522) += au8522.o 56obj-$(CONFIG_DVB_AU8522) += au8522.o
57obj-$(CONFIG_DVB_TDA10048) += tda10048.o 57obj-$(CONFIG_DVB_TDA10048) += tda10048.o
58obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h
index 96338f0c4dd4..de796eab3911 100644
--- a/drivers/media/dvb/frontends/mt312.h
+++ b/drivers/media/dvb/frontends/mt312.h
@@ -33,7 +33,7 @@ struct mt312_config {
33 u8 demod_address; 33 u8 demod_address;
34 34
35 /* inverted voltage setting */ 35 /* inverted voltage setting */
36 int voltage_inverted:1; 36 unsigned int voltage_inverted:1;
37}; 37};
38 38
39#if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE)) 39#if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE))
diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c
new file mode 100644
index 000000000000..eb5bfc99d4e9
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1411.c
@@ -0,0 +1,888 @@
1/*
2 Samsung S5H1411 VSB/QAM demodulator driver
3
4 Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20*/
21
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/slab.h>
27#include <linux/delay.h>
28#include "dvb_frontend.h"
29#include "dvb-pll.h"
30#include "s5h1411.h"
31
32struct s5h1411_state {
33
34 struct i2c_adapter *i2c;
35
36 /* configuration settings */
37 const struct s5h1411_config *config;
38
39 struct dvb_frontend frontend;
40
41 fe_modulation_t current_modulation;
42
43 u32 current_frequency;
44 int if_freq;
45
46 u8 inversion;
47};
48
49static int debug;
50
51#define dprintk(arg...) do { \
52 if (debug) \
53 printk(arg); \
54 } while (0)
55
56/* Register values to initialise the demod, defaults to VSB */
57static struct init_tab {
58 u8 addr;
59 u8 reg;
60 u16 data;
61} init_tab[] = {
62 { S5H1411_I2C_TOP_ADDR, 0x00, 0x0071, },
63 { S5H1411_I2C_TOP_ADDR, 0x08, 0x0047, },
64 { S5H1411_I2C_TOP_ADDR, 0x1c, 0x0400, },
65 { S5H1411_I2C_TOP_ADDR, 0x1e, 0x0370, },
66 { S5H1411_I2C_TOP_ADDR, 0x1f, 0x342a, },
67 { S5H1411_I2C_TOP_ADDR, 0x24, 0x0231, },
68 { S5H1411_I2C_TOP_ADDR, 0x25, 0x1011, },
69 { S5H1411_I2C_TOP_ADDR, 0x26, 0x0f07, },
70 { S5H1411_I2C_TOP_ADDR, 0x27, 0x0f04, },
71 { S5H1411_I2C_TOP_ADDR, 0x28, 0x070f, },
72 { S5H1411_I2C_TOP_ADDR, 0x29, 0x2820, },
73 { S5H1411_I2C_TOP_ADDR, 0x2a, 0x102e, },
74 { S5H1411_I2C_TOP_ADDR, 0x2b, 0x0220, },
75 { S5H1411_I2C_TOP_ADDR, 0x2e, 0x0d0e, },
76 { S5H1411_I2C_TOP_ADDR, 0x2f, 0x1013, },
77 { S5H1411_I2C_TOP_ADDR, 0x31, 0x171b, },
78 { S5H1411_I2C_TOP_ADDR, 0x32, 0x0e0f, },
79 { S5H1411_I2C_TOP_ADDR, 0x33, 0x0f10, },
80 { S5H1411_I2C_TOP_ADDR, 0x34, 0x170e, },
81 { S5H1411_I2C_TOP_ADDR, 0x35, 0x4b10, },
82 { S5H1411_I2C_TOP_ADDR, 0x36, 0x0f17, },
83 { S5H1411_I2C_TOP_ADDR, 0x3c, 0x1577, },
84 { S5H1411_I2C_TOP_ADDR, 0x3d, 0x081a, },
85 { S5H1411_I2C_TOP_ADDR, 0x3e, 0x77ee, },
86 { S5H1411_I2C_TOP_ADDR, 0x40, 0x1e09, },
87 { S5H1411_I2C_TOP_ADDR, 0x41, 0x0f0c, },
88 { S5H1411_I2C_TOP_ADDR, 0x42, 0x1f10, },
89 { S5H1411_I2C_TOP_ADDR, 0x4d, 0x0509, },
90 { S5H1411_I2C_TOP_ADDR, 0x4e, 0x0a00, },
91 { S5H1411_I2C_TOP_ADDR, 0x50, 0x0000, },
92 { S5H1411_I2C_TOP_ADDR, 0x5b, 0x0000, },
93 { S5H1411_I2C_TOP_ADDR, 0x5c, 0x0008, },
94 { S5H1411_I2C_TOP_ADDR, 0x57, 0x1101, },
95 { S5H1411_I2C_TOP_ADDR, 0x65, 0x007c, },
96 { S5H1411_I2C_TOP_ADDR, 0x68, 0x0512, },
97 { S5H1411_I2C_TOP_ADDR, 0x69, 0x0258, },
98 { S5H1411_I2C_TOP_ADDR, 0x70, 0x0004, },
99 { S5H1411_I2C_TOP_ADDR, 0x71, 0x0007, },
100 { S5H1411_I2C_TOP_ADDR, 0x76, 0x00a9, },
101 { S5H1411_I2C_TOP_ADDR, 0x78, 0x3141, },
102 { S5H1411_I2C_TOP_ADDR, 0x7a, 0x3141, },
103 { S5H1411_I2C_TOP_ADDR, 0xb3, 0x8003, },
104 { S5H1411_I2C_TOP_ADDR, 0xb5, 0xafbb, },
105 { S5H1411_I2C_TOP_ADDR, 0xb5, 0xa6bb, },
106 { S5H1411_I2C_TOP_ADDR, 0xb6, 0x0609, },
107 { S5H1411_I2C_TOP_ADDR, 0xb7, 0x2f06, },
108 { S5H1411_I2C_TOP_ADDR, 0xb8, 0x003f, },
109 { S5H1411_I2C_TOP_ADDR, 0xb9, 0x2700, },
110 { S5H1411_I2C_TOP_ADDR, 0xba, 0xfac8, },
111 { S5H1411_I2C_TOP_ADDR, 0xbe, 0x1003, },
112 { S5H1411_I2C_TOP_ADDR, 0xbf, 0x103f, },
113 { S5H1411_I2C_TOP_ADDR, 0xce, 0x2000, },
114 { S5H1411_I2C_TOP_ADDR, 0xcf, 0x0800, },
115 { S5H1411_I2C_TOP_ADDR, 0xd0, 0x0800, },
116 { S5H1411_I2C_TOP_ADDR, 0xd1, 0x0400, },
117 { S5H1411_I2C_TOP_ADDR, 0xd2, 0x0800, },
118 { S5H1411_I2C_TOP_ADDR, 0xd3, 0x2000, },
119 { S5H1411_I2C_TOP_ADDR, 0xd4, 0x3000, },
120 { S5H1411_I2C_TOP_ADDR, 0xdb, 0x4a9b, },
121 { S5H1411_I2C_TOP_ADDR, 0xdc, 0x1000, },
122 { S5H1411_I2C_TOP_ADDR, 0xde, 0x0001, },
123 { S5H1411_I2C_TOP_ADDR, 0xdf, 0x0000, },
124 { S5H1411_I2C_TOP_ADDR, 0xe3, 0x0301, },
125 { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0000, },
126 { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0001, },
127 { S5H1411_I2C_QAM_ADDR, 0x08, 0x0600, },
128 { S5H1411_I2C_QAM_ADDR, 0x18, 0x4201, },
129 { S5H1411_I2C_QAM_ADDR, 0x1e, 0x6476, },
130 { S5H1411_I2C_QAM_ADDR, 0x21, 0x0830, },
131 { S5H1411_I2C_QAM_ADDR, 0x0c, 0x5679, },
132 { S5H1411_I2C_QAM_ADDR, 0x0d, 0x579b, },
133 { S5H1411_I2C_QAM_ADDR, 0x24, 0x0102, },
134 { S5H1411_I2C_QAM_ADDR, 0x31, 0x7488, },
135 { S5H1411_I2C_QAM_ADDR, 0x32, 0x0a08, },
136 { S5H1411_I2C_QAM_ADDR, 0x3d, 0x8689, },
137 { S5H1411_I2C_QAM_ADDR, 0x49, 0x0048, },
138 { S5H1411_I2C_QAM_ADDR, 0x57, 0x2012, },
139 { S5H1411_I2C_QAM_ADDR, 0x5d, 0x7676, },
140 { S5H1411_I2C_QAM_ADDR, 0x04, 0x0400, },
141 { S5H1411_I2C_QAM_ADDR, 0x58, 0x00c0, },
142 { S5H1411_I2C_QAM_ADDR, 0x5b, 0x0100, },
143};
144
145/* VSB SNR lookup table */
146static struct vsb_snr_tab {
147 u16 val;
148 u16 data;
149} vsb_snr_tab[] = {
150 { 0x39f, 300, },
151 { 0x39b, 295, },
152 { 0x397, 290, },
153 { 0x394, 285, },
154 { 0x38f, 280, },
155 { 0x38b, 275, },
156 { 0x387, 270, },
157 { 0x382, 265, },
158 { 0x37d, 260, },
159 { 0x377, 255, },
160 { 0x370, 250, },
161 { 0x36a, 245, },
162 { 0x364, 240, },
163 { 0x35b, 235, },
164 { 0x353, 230, },
165 { 0x349, 225, },
166 { 0x340, 320, },
167 { 0x337, 215, },
168 { 0x327, 210, },
169 { 0x31b, 205, },
170 { 0x310, 200, },
171 { 0x302, 195, },
172 { 0x2f3, 190, },
173 { 0x2e4, 185, },
174 { 0x2d7, 180, },
175 { 0x2cd, 175, },
176 { 0x2bb, 170, },
177 { 0x2a9, 165, },
178 { 0x29e, 160, },
179 { 0x284, 155, },
180 { 0x27a, 150, },
181 { 0x260, 145, },
182 { 0x23a, 140, },
183 { 0x224, 135, },
184 { 0x213, 130, },
185 { 0x204, 125, },
186 { 0x1fe, 120, },
187 { 0, 0, },
188};
189
190/* QAM64 SNR lookup table */
191static struct qam64_snr_tab {
192 u16 val;
193 u16 data;
194} qam64_snr_tab[] = {
195 { 0x0001, 0, },
196 { 0x0af0, 300, },
197 { 0x0d80, 290, },
198 { 0x10a0, 280, },
199 { 0x14b5, 270, },
200 { 0x1590, 268, },
201 { 0x1680, 266, },
202 { 0x17b0, 264, },
203 { 0x18c0, 262, },
204 { 0x19b0, 260, },
205 { 0x1ad0, 258, },
206 { 0x1d00, 256, },
207 { 0x1da0, 254, },
208 { 0x1ef0, 252, },
209 { 0x2050, 250, },
210 { 0x20f0, 249, },
211 { 0x21d0, 248, },
212 { 0x22b0, 247, },
213 { 0x23a0, 246, },
214 { 0x2470, 245, },
215 { 0x24f0, 244, },
216 { 0x25a0, 243, },
217 { 0x26c0, 242, },
218 { 0x27b0, 241, },
219 { 0x28d0, 240, },
220 { 0x29b0, 239, },
221 { 0x2ad0, 238, },
222 { 0x2ba0, 237, },
223 { 0x2c80, 236, },
224 { 0x2d20, 235, },
225 { 0x2e00, 234, },
226 { 0x2f10, 233, },
227 { 0x3050, 232, },
228 { 0x3190, 231, },
229 { 0x3300, 230, },
230 { 0x3340, 229, },
231 { 0x3200, 228, },
232 { 0x3550, 227, },
233 { 0x3610, 226, },
234 { 0x3600, 225, },
235 { 0x3700, 224, },
236 { 0x3800, 223, },
237 { 0x3920, 222, },
238 { 0x3a20, 221, },
239 { 0x3b30, 220, },
240 { 0x3d00, 219, },
241 { 0x3e00, 218, },
242 { 0x4000, 217, },
243 { 0x4100, 216, },
244 { 0x4300, 215, },
245 { 0x4400, 214, },
246 { 0x4600, 213, },
247 { 0x4700, 212, },
248 { 0x4800, 211, },
249 { 0x4a00, 210, },
250 { 0x4b00, 209, },
251 { 0x4d00, 208, },
252 { 0x4f00, 207, },
253 { 0x5050, 206, },
254 { 0x5200, 205, },
255 { 0x53c0, 204, },
256 { 0x5450, 203, },
257 { 0x5650, 202, },
258 { 0x5820, 201, },
259 { 0x6000, 200, },
260 { 0xffff, 0, },
261};
262
263/* QAM256 SNR lookup table */
264static struct qam256_snr_tab {
265 u16 val;
266 u16 data;
267} qam256_snr_tab[] = {
268 { 0x0001, 0, },
269 { 0x0970, 400, },
270 { 0x0a90, 390, },
271 { 0x0b90, 380, },
272 { 0x0d90, 370, },
273 { 0x0ff0, 360, },
274 { 0x1240, 350, },
275 { 0x1345, 348, },
276 { 0x13c0, 346, },
277 { 0x14c0, 344, },
278 { 0x1500, 342, },
279 { 0x1610, 340, },
280 { 0x1700, 338, },
281 { 0x1800, 336, },
282 { 0x18b0, 334, },
283 { 0x1900, 332, },
284 { 0x1ab0, 330, },
285 { 0x1bc0, 328, },
286 { 0x1cb0, 326, },
287 { 0x1db0, 324, },
288 { 0x1eb0, 322, },
289 { 0x2030, 320, },
290 { 0x2200, 318, },
291 { 0x2280, 316, },
292 { 0x2410, 314, },
293 { 0x25b0, 312, },
294 { 0x27a0, 310, },
295 { 0x2840, 308, },
296 { 0x29d0, 306, },
297 { 0x2b10, 304, },
298 { 0x2d30, 302, },
299 { 0x2f20, 300, },
300 { 0x30c0, 298, },
301 { 0x3260, 297, },
302 { 0x32c0, 296, },
303 { 0x3300, 295, },
304 { 0x33b0, 294, },
305 { 0x34b0, 293, },
306 { 0x35a0, 292, },
307 { 0x3650, 291, },
308 { 0x3800, 290, },
309 { 0x3900, 289, },
310 { 0x3a50, 288, },
311 { 0x3b30, 287, },
312 { 0x3cb0, 286, },
313 { 0x3e20, 285, },
314 { 0x3fa0, 284, },
315 { 0x40a0, 283, },
316 { 0x41c0, 282, },
317 { 0x42f0, 281, },
318 { 0x44a0, 280, },
319 { 0x4600, 279, },
320 { 0x47b0, 278, },
321 { 0x4900, 277, },
322 { 0x4a00, 276, },
323 { 0x4ba0, 275, },
324 { 0x4d00, 274, },
325 { 0x4f00, 273, },
326 { 0x5000, 272, },
327 { 0x51f0, 272, },
328 { 0x53a0, 270, },
329 { 0x5520, 269, },
330 { 0x5700, 268, },
331 { 0x5800, 267, },
332 { 0x5a00, 266, },
333 { 0x5c00, 265, },
334 { 0x5d00, 264, },
335 { 0x5f00, 263, },
336 { 0x6000, 262, },
337 { 0x6200, 261, },
338 { 0x6400, 260, },
339 { 0xffff, 0, },
340};
341
342/* 8 bit registers, 16 bit values */
343static int s5h1411_writereg(struct s5h1411_state *state,
344 u8 addr, u8 reg, u16 data)
345{
346 int ret;
347 u8 buf [] = { reg, data >> 8, data & 0xff };
348
349 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
350
351 ret = i2c_transfer(state->i2c, &msg, 1);
352
353 if (ret != 1)
354 printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, "
355 "ret == %i)\n", __func__, addr, reg, data, ret);
356
357 return (ret != 1) ? -1 : 0;
358}
359
360static u16 s5h1411_readreg(struct s5h1411_state *state, u8 addr, u8 reg)
361{
362 int ret;
363 u8 b0 [] = { reg };
364 u8 b1 [] = { 0, 0 };
365
366 struct i2c_msg msg [] = {
367 { .addr = addr, .flags = 0, .buf = b0, .len = 1 },
368 { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
369
370 ret = i2c_transfer(state->i2c, msg, 2);
371
372 if (ret != 2)
373 printk(KERN_ERR "%s: readreg error (ret == %i)\n",
374 __func__, ret);
375 return (b1[0] << 8) | b1[1];
376}
377
378static int s5h1411_softreset(struct dvb_frontend *fe)
379{
380 struct s5h1411_state *state = fe->demodulator_priv;
381
382 dprintk("%s()\n", __func__);
383
384 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 0);
385 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 1);
386 return 0;
387}
388
389static int s5h1411_set_if_freq(struct dvb_frontend *fe, int KHz)
390{
391 struct s5h1411_state *state = fe->demodulator_priv;
392
393 dprintk("%s(%d KHz)\n", __func__, KHz);
394
395 switch (KHz) {
396 case 3250:
397 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x10d9);
398 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x5342);
399 s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x10d9);
400 break;
401 case 3500:
402 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1225);
403 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x1e96);
404 s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1225);
405 break;
406 case 4000:
407 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x14bc);
408 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0xb53e);
409 s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x14bd);
410 break;
411 default:
412 dprintk("%s(%d KHz) Invalid, defaulting to 5380\n",
413 __func__, KHz);
414 /* no break, need to continue */
415 case 5380:
416 case 44000:
417 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1be4);
418 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x3655);
419 s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1be4);
420 break;
421 }
422
423 state->if_freq = KHz;
424
425 return 0;
426}
427
428static int s5h1411_set_mpeg_timing(struct dvb_frontend *fe, int mode)
429{
430 struct s5h1411_state *state = fe->demodulator_priv;
431 u16 val;
432
433 dprintk("%s(%d)\n", __func__, mode);
434
435 val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbe) & 0xcfff;
436 switch (mode) {
437 case S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK:
438 val |= 0x0000;
439 break;
440 case S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK:
441 dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode);
442 val |= 0x1000;
443 break;
444 case S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK:
445 val |= 0x2000;
446 break;
447 case S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK:
448 val |= 0x3000;
449 break;
450 default:
451 return -EINVAL;
452 }
453
454 /* Configure MPEG Signal Timing charactistics */
455 return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbe, val);
456}
457
458static int s5h1411_set_spectralinversion(struct dvb_frontend *fe, int inversion)
459{
460 struct s5h1411_state *state = fe->demodulator_priv;
461 u16 val;
462
463 dprintk("%s(%d)\n", __func__, inversion);
464 val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x24) & ~0x1000;
465
466 if (inversion == 1)
467 val |= 0x1000; /* Inverted */
468 else
469 val |= 0x0000;
470
471 state->inversion = inversion;
472 return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x24, val);
473}
474
475static int s5h1411_enable_modulation(struct dvb_frontend *fe,
476 fe_modulation_t m)
477{
478 struct s5h1411_state *state = fe->demodulator_priv;
479
480 dprintk("%s(0x%08x)\n", __func__, m);
481
482 switch (m) {
483 case VSB_8:
484 dprintk("%s() VSB_8\n", __func__);
485 s5h1411_set_if_freq(fe, state->config->vsb_if);
486 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x71);
487 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x00);
488 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0xf1);
489 break;
490 case QAM_64:
491 case QAM_256:
492 dprintk("%s() QAM_AUTO (64/256)\n", __func__);
493 s5h1411_set_if_freq(fe, state->config->qam_if);
494 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x0171);
495 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x0001);
496 s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x16, 0x1101);
497 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0x00f0);
498 break;
499 default:
500 dprintk("%s() Invalid modulation\n", __func__);
501 return -EINVAL;
502 }
503
504 state->current_modulation = m;
505 s5h1411_softreset(fe);
506
507 return 0;
508}
509
510static int s5h1411_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
511{
512 struct s5h1411_state *state = fe->demodulator_priv;
513
514 dprintk("%s(%d)\n", __func__, enable);
515
516 if (enable)
517 return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1);
518 else
519 return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 0);
520}
521
522static int s5h1411_set_gpio(struct dvb_frontend *fe, int enable)
523{
524 struct s5h1411_state *state = fe->demodulator_priv;
525 u16 val;
526
527 dprintk("%s(%d)\n", __func__, enable);
528
529 val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xe0) & ~0x02;
530
531 if (enable)
532 return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0,
533 val | 0x02);
534 else
535 return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, val);
536}
537
538static int s5h1411_sleep(struct dvb_frontend *fe, int enable)
539{
540 struct s5h1411_state *state = fe->demodulator_priv;
541
542 dprintk("%s(%d)\n", __func__, enable);
543
544 if (enable)
545 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 1);
546 else {
547 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 0);
548 s5h1411_softreset(fe);
549 }
550
551 return 0;
552}
553
554static int s5h1411_register_reset(struct dvb_frontend *fe)
555{
556 struct s5h1411_state *state = fe->demodulator_priv;
557
558 dprintk("%s()\n", __func__);
559
560 return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf3, 0);
561}
562
563/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
564static int s5h1411_set_frontend(struct dvb_frontend *fe,
565 struct dvb_frontend_parameters *p)
566{
567 struct s5h1411_state *state = fe->demodulator_priv;
568
569 dprintk("%s(frequency=%d)\n", __func__, p->frequency);
570
571 s5h1411_softreset(fe);
572
573 state->current_frequency = p->frequency;
574
575 s5h1411_enable_modulation(fe, p->u.vsb.modulation);
576
577 /* Allow the demod to settle */
578 msleep(100);
579
580 if (fe->ops.tuner_ops.set_params) {
581 if (fe->ops.i2c_gate_ctrl)
582 fe->ops.i2c_gate_ctrl(fe, 1);
583
584 fe->ops.tuner_ops.set_params(fe, p);
585
586 if (fe->ops.i2c_gate_ctrl)
587 fe->ops.i2c_gate_ctrl(fe, 0);
588 }
589
590 return 0;
591}
592
593/* Reset the demod hardware and reset all of the configuration registers
594 to a default state. */
595static int s5h1411_init(struct dvb_frontend *fe)
596{
597 struct s5h1411_state *state = fe->demodulator_priv;
598 int i;
599
600 dprintk("%s()\n", __func__);
601
602 s5h1411_sleep(fe, 0);
603 s5h1411_register_reset(fe);
604
605 for (i = 0; i < ARRAY_SIZE(init_tab); i++)
606 s5h1411_writereg(state, init_tab[i].addr,
607 init_tab[i].reg,
608 init_tab[i].data);
609
610 /* The datasheet says that after initialisation, VSB is default */
611 state->current_modulation = VSB_8;
612
613 if (state->config->output_mode == S5H1411_SERIAL_OUTPUT)
614 /* Serial */
615 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, 0x1101);
616 else
617 /* Parallel */
618 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, 0x1001);
619
620 s5h1411_set_spectralinversion(fe, state->config->inversion);
621 s5h1411_set_if_freq(fe, state->config->vsb_if);
622 s5h1411_set_gpio(fe, state->config->gpio);
623 s5h1411_set_mpeg_timing(fe, state->config->mpeg_timing);
624 s5h1411_softreset(fe);
625
626 /* Note: Leaving the I2C gate closed. */
627 s5h1411_i2c_gate_ctrl(fe, 0);
628
629 return 0;
630}
631
632static int s5h1411_read_status(struct dvb_frontend *fe, fe_status_t *status)
633{
634 struct s5h1411_state *state = fe->demodulator_priv;
635 u16 reg;
636 u32 tuner_status = 0;
637
638 *status = 0;
639
640 /* Get the demodulator status */
641 reg = (s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2) >> 15)
642 & 0x0001;
643 if (reg)
644 *status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_SIGNAL;
645
646 switch (state->current_modulation) {
647 case QAM_64:
648 case QAM_256:
649 reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf0);
650 if (reg & 0x100)
651 *status |= FE_HAS_VITERBI;
652 if (reg & 0x10)
653 *status |= FE_HAS_SYNC;
654 break;
655 case VSB_8:
656 reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x5e);
657 if (reg & 0x0001)
658 *status |= FE_HAS_SYNC;
659 reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2);
660 if (reg & 0x1000)
661 *status |= FE_HAS_VITERBI;
662 break;
663 default:
664 return -EINVAL;
665 }
666
667 switch (state->config->status_mode) {
668 case S5H1411_DEMODLOCKING:
669 if (*status & FE_HAS_VITERBI)
670 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
671 break;
672 case S5H1411_TUNERLOCKING:
673 /* Get the tuner status */
674 if (fe->ops.tuner_ops.get_status) {
675 if (fe->ops.i2c_gate_ctrl)
676 fe->ops.i2c_gate_ctrl(fe, 1);
677
678 fe->ops.tuner_ops.get_status(fe, &tuner_status);
679
680 if (fe->ops.i2c_gate_ctrl)
681 fe->ops.i2c_gate_ctrl(fe, 0);
682 }
683 if (tuner_status)
684 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
685 break;
686 }
687
688 dprintk("%s() status 0x%08x\n", __func__, *status);
689
690 return 0;
691}
692
693static int s5h1411_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
694{
695 int i, ret = -EINVAL;
696 dprintk("%s()\n", __func__);
697
698 for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) {
699 if (v < qam256_snr_tab[i].val) {
700 *snr = qam256_snr_tab[i].data;
701 ret = 0;
702 break;
703 }
704 }
705 return ret;
706}
707
708static int s5h1411_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
709{
710 int i, ret = -EINVAL;
711 dprintk("%s()\n", __func__);
712
713 for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) {
714 if (v < qam64_snr_tab[i].val) {
715 *snr = qam64_snr_tab[i].data;
716 ret = 0;
717 break;
718 }
719 }
720 return ret;
721}
722
723static int s5h1411_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
724{
725 int i, ret = -EINVAL;
726 dprintk("%s()\n", __func__);
727
728 for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) {
729 if (v > vsb_snr_tab[i].val) {
730 *snr = vsb_snr_tab[i].data;
731 ret = 0;
732 break;
733 }
734 }
735 dprintk("%s() snr=%d\n", __func__, *snr);
736 return ret;
737}
738
739static int s5h1411_read_snr(struct dvb_frontend *fe, u16 *snr)
740{
741 struct s5h1411_state *state = fe->demodulator_priv;
742 u16 reg;
743 dprintk("%s()\n", __func__);
744
745 switch (state->current_modulation) {
746 case QAM_64:
747 reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1);
748 return s5h1411_qam64_lookup_snr(fe, snr, reg);
749 case QAM_256:
750 reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1);
751 return s5h1411_qam256_lookup_snr(fe, snr, reg);
752 case VSB_8:
753 reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR,
754 0xf2) & 0x3ff;
755 return s5h1411_vsb_lookup_snr(fe, snr, reg);
756 default:
757 break;
758 }
759
760 return -EINVAL;
761}
762
763static int s5h1411_read_signal_strength(struct dvb_frontend *fe,
764 u16 *signal_strength)
765{
766 return s5h1411_read_snr(fe, signal_strength);
767}
768
769static int s5h1411_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
770{
771 struct s5h1411_state *state = fe->demodulator_priv;
772
773 *ucblocks = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xc9);
774
775 return 0;
776}
777
778static int s5h1411_read_ber(struct dvb_frontend *fe, u32 *ber)
779{
780 return s5h1411_read_ucblocks(fe, ber);
781}
782
783static int s5h1411_get_frontend(struct dvb_frontend *fe,
784 struct dvb_frontend_parameters *p)
785{
786 struct s5h1411_state *state = fe->demodulator_priv;
787
788 p->frequency = state->current_frequency;
789 p->u.vsb.modulation = state->current_modulation;
790
791 return 0;
792}
793
794static int s5h1411_get_tune_settings(struct dvb_frontend *fe,
795 struct dvb_frontend_tune_settings *tune)
796{
797 tune->min_delay_ms = 1000;
798 return 0;
799}
800
801static void s5h1411_release(struct dvb_frontend *fe)
802{
803 struct s5h1411_state *state = fe->demodulator_priv;
804 kfree(state);
805}
806
807static struct dvb_frontend_ops s5h1411_ops;
808
809struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config,
810 struct i2c_adapter *i2c)
811{
812 struct s5h1411_state *state = NULL;
813 u16 reg;
814
815 /* allocate memory for the internal state */
816 state = kmalloc(sizeof(struct s5h1411_state), GFP_KERNEL);
817 if (state == NULL)
818 goto error;
819
820 /* setup the state */
821 state->config = config;
822 state->i2c = i2c;
823 state->current_modulation = VSB_8;
824 state->inversion = state->config->inversion;
825
826 /* check if the demod exists */
827 reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x05);
828 if (reg != 0x0066)
829 goto error;
830
831 /* create dvb_frontend */
832 memcpy(&state->frontend.ops, &s5h1411_ops,
833 sizeof(struct dvb_frontend_ops));
834
835 state->frontend.demodulator_priv = state;
836
837 if (s5h1411_init(&state->frontend) != 0) {
838 printk(KERN_ERR "%s: Failed to initialize correctly\n",
839 __func__);
840 goto error;
841 }
842
843 /* Note: Leaving the I2C gate open here. */
844 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1);
845
846 return &state->frontend;
847
848error:
849 kfree(state);
850 return NULL;
851}
852EXPORT_SYMBOL(s5h1411_attach);
853
854static struct dvb_frontend_ops s5h1411_ops = {
855
856 .info = {
857 .name = "Samsung S5H1411 QAM/8VSB Frontend",
858 .type = FE_ATSC,
859 .frequency_min = 54000000,
860 .frequency_max = 858000000,
861 .frequency_stepsize = 62500,
862 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
863 },
864
865 .init = s5h1411_init,
866 .i2c_gate_ctrl = s5h1411_i2c_gate_ctrl,
867 .set_frontend = s5h1411_set_frontend,
868 .get_frontend = s5h1411_get_frontend,
869 .get_tune_settings = s5h1411_get_tune_settings,
870 .read_status = s5h1411_read_status,
871 .read_ber = s5h1411_read_ber,
872 .read_signal_strength = s5h1411_read_signal_strength,
873 .read_snr = s5h1411_read_snr,
874 .read_ucblocks = s5h1411_read_ucblocks,
875 .release = s5h1411_release,
876};
877
878module_param(debug, int, 0644);
879MODULE_PARM_DESC(debug, "Enable verbose debug messages");
880
881MODULE_DESCRIPTION("Samsung S5H1411 QAM-B/ATSC Demodulator driver");
882MODULE_AUTHOR("Steven Toth");
883MODULE_LICENSE("GPL");
884
885/*
886 * Local variables:
887 * c-basic-offset: 8
888 */
diff --git a/drivers/media/dvb/frontends/s5h1411.h b/drivers/media/dvb/frontends/s5h1411.h
new file mode 100644
index 000000000000..1855f64ed4d8
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1411.h
@@ -0,0 +1,90 @@
1/*
2 Samsung S5H1411 VSB/QAM demodulator driver
3
4 Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20*/
21
22#ifndef __S5H1411_H__
23#define __S5H1411_H__
24
25#include <linux/dvb/frontend.h>
26
27#define S5H1411_I2C_TOP_ADDR (0x32 >> 1)
28#define S5H1411_I2C_QAM_ADDR (0x34 >> 1)
29
30struct s5h1411_config {
31
32 /* serial/parallel output */
33#define S5H1411_PARALLEL_OUTPUT 0
34#define S5H1411_SERIAL_OUTPUT 1
35 u8 output_mode;
36
37 /* GPIO Setting */
38#define S5H1411_GPIO_OFF 0
39#define S5H1411_GPIO_ON 1
40 u8 gpio;
41
42 /* MPEG signal timing */
43#define S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0
44#define S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1
45#define S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2
46#define S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
47 u16 mpeg_timing;
48
49 /* IF Freq for QAM and VSB in KHz */
50#define S5H1411_IF_2500 2500
51#define S5H1411_IF_3500 3500
52#define S5H1411_IF_4000 4000
53#define S5H1411_IF_5380 5380
54#define S5H1411_IF_44000 44000
55#define S5H1411_VSB_IF_DEFAULT S5H1411_IF_44000
56#define S5H1411_QAM_IF_DEFAULT S5H1411_IF_44000
57 u16 qam_if;
58 u16 vsb_if;
59
60 /* Spectral Inversion */
61#define S5H1411_INVERSION_OFF 0
62#define S5H1411_INVERSION_ON 1
63 u8 inversion;
64
65 /* Return lock status based on tuner lock, or demod lock */
66#define S5H1411_TUNERLOCKING 0
67#define S5H1411_DEMODLOCKING 1
68 u8 status_mode;
69};
70
71#if defined(CONFIG_DVB_S5H1411) || \
72 (defined(CONFIG_DVB_S5H1411_MODULE) && defined(MODULE))
73extern struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config,
74 struct i2c_adapter *i2c);
75#else
76static inline struct dvb_frontend *s5h1411_attach(
77 const struct s5h1411_config *config,
78 struct i2c_adapter *i2c)
79{
80 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
81 return NULL;
82}
83#endif /* CONFIG_DVB_S5H1411 */
84
85#endif /* __S5H1411_H__ */
86
87/*
88 * Local variables:
89 * c-basic-offset: 8
90 */
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig
index c97c4bd24841..41708267e7a4 100644
--- a/drivers/media/video/au0828/Kconfig
+++ b/drivers/media/video/au0828/Kconfig
@@ -1,7 +1,7 @@
1 1
2config VIDEO_AU0828 2config VIDEO_AU0828
3 tristate "Auvitek AU0828 support" 3 tristate "Auvitek AU0828 support"
4 depends on VIDEO_DEV && I2C && INPUT 4 depends on VIDEO_DEV && I2C && INPUT && DVB_CORE
5 select I2C_ALGOBIT 5 select I2C_ALGOBIT
6 select DVB_AU8522 if !DVB_FE_CUSTOMIZE 6 select DVB_AU8522 if !DVB_FE_CUSTOMIZE
7 select DVB_TUNER_XC5000 if !DVB_FE_CUSTOMIZE 7 select DVB_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 8ca91f814277..a2a6983444fa 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -36,7 +36,6 @@ struct au0828_board au0828_boards[] = {
36 .name = "DViCO FusionHDTV USB", 36 .name = "DViCO FusionHDTV USB",
37 }, 37 },
38}; 38};
39const unsigned int au0828_bcount = ARRAY_SIZE(au0828_boards);
40 39
41/* Tuner callback function for au0828 boards. Currently only needed 40/* Tuner callback function for au0828 boards. Currently only needed
42 * for HVR1500Q, which has an xc5000 tuner. 41 * for HVR1500Q, which has an xc5000 tuner.
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c
index e65d5642cb1d..54bfc0f05295 100644
--- a/drivers/media/video/au0828/au0828-core.c
+++ b/drivers/media/video/au0828/au0828-core.c
@@ -32,18 +32,10 @@
32 * 4 = I2C related 32 * 4 = I2C related
33 * 8 = Bridge related 33 * 8 = Bridge related
34 */ 34 */
35unsigned int debug; 35int au0828_debug;
36module_param(debug, int, 0644); 36module_param_named(debug, au0828_debug, int, 0644);
37MODULE_PARM_DESC(debug, "enable debug messages"); 37MODULE_PARM_DESC(debug, "enable debug messages");
38 38
39unsigned int usb_debug;
40module_param(usb_debug, int, 0644);
41MODULE_PARM_DESC(usb_debug, "enable usb debug messages");
42
43unsigned int bridge_debug;
44module_param(bridge_debug, int, 0644);
45MODULE_PARM_DESC(bridge_debug, "enable bridge debug messages");
46
47#define _AU0828_BULKPIPE 0x03 39#define _AU0828_BULKPIPE 0x03
48#define _BULKPIPESIZE 0xffff 40#define _BULKPIPESIZE 0xffff
49 41
@@ -229,24 +221,18 @@ static int __init au0828_init(void)
229{ 221{
230 int ret; 222 int ret;
231 223
232 if (debug) 224 if (au0828_debug & 1)
233 printk(KERN_INFO "%s() Debugging is enabled\n", __func__); 225 printk(KERN_INFO "%s() Debugging is enabled\n", __func__);
234 226
235 if (usb_debug) { 227 if (au0828_debug & 2)
236 printk(KERN_INFO "%s() USB Debugging is enabled\n", __func__); 228 printk(KERN_INFO "%s() USB Debugging is enabled\n", __func__);
237 debug |= 2;
238 }
239 229
240 if (i2c_debug) { 230 if (au0828_debug & 4)
241 printk(KERN_INFO "%s() I2C Debugging is enabled\n", __func__); 231 printk(KERN_INFO "%s() I2C Debugging is enabled\n", __func__);
242 debug |= 4;
243 }
244 232
245 if (bridge_debug) { 233 if (au0828_debug & 8)
246 printk(KERN_INFO "%s() Bridge Debugging is enabled\n", 234 printk(KERN_INFO "%s() Bridge Debugging is enabled\n",
247 __func__); 235 __func__);
248 debug |= 8;
249 }
250 236
251 printk(KERN_INFO "au0828 driver loaded\n"); 237 printk(KERN_INFO "au0828 driver loaded\n");
252 238
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index 85d0ae9a322f..5040d7fc4af5 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -204,7 +204,7 @@ static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed)
204 return ret; 204 return ret;
205} 205}
206 206
207int dvb_register(struct au0828_dev *dev) 207static int dvb_register(struct au0828_dev *dev)
208{ 208{
209 struct au0828_dvb *dvb = &dev->dvb; 209 struct au0828_dvb *dvb = &dev->dvb;
210 int result; 210 int result;
diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c
index 94c8b74a6651..741a4937b050 100644
--- a/drivers/media/video/au0828/au0828-i2c.c
+++ b/drivers/media/video/au0828/au0828-i2c.c
@@ -29,11 +29,7 @@
29 29
30#include <media/v4l2-common.h> 30#include <media/v4l2-common.h>
31 31
32unsigned int i2c_debug; 32static int i2c_scan;
33module_param(i2c_debug, int, 0444);
34MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
35
36unsigned int i2c_scan;
37module_param(i2c_scan, int, 0444); 33module_param(i2c_scan, int, 0444);
38MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); 34MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
39 35
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h
index 0200b9fc5dc4..7beb571798e5 100644
--- a/drivers/media/video/au0828/au0828.h
+++ b/drivers/media/video/au0828/au0828.h
@@ -96,15 +96,12 @@ struct au0828_buff {
96/* au0828-core.c */ 96/* au0828-core.c */
97extern u32 au0828_read(struct au0828_dev *dev, u16 reg); 97extern u32 au0828_read(struct au0828_dev *dev, u16 reg);
98extern u32 au0828_write(struct au0828_dev *dev, u16 reg, u32 val); 98extern u32 au0828_write(struct au0828_dev *dev, u16 reg, u32 val);
99extern unsigned int debug; 99extern int au0828_debug;
100extern unsigned int usb_debug;
101extern unsigned int bridge_debug;
102 100
103/* ----------------------------------------------------------- */ 101/* ----------------------------------------------------------- */
104/* au0828-cards.c */ 102/* au0828-cards.c */
105extern struct au0828_board au0828_boards[]; 103extern struct au0828_board au0828_boards[];
106extern struct usb_device_id au0828_usb_id_table[]; 104extern struct usb_device_id au0828_usb_id_table[];
107extern const unsigned int au0828_bcount;
108extern void au0828_gpio_setup(struct au0828_dev *dev); 105extern void au0828_gpio_setup(struct au0828_dev *dev);
109extern int au0828_tuner_callback(void *priv, int command, int arg); 106extern int au0828_tuner_callback(void *priv, int command, int arg);
110extern void au0828_card_setup(struct au0828_dev *dev); 107extern void au0828_card_setup(struct au0828_dev *dev);
@@ -115,7 +112,6 @@ extern int au0828_i2c_register(struct au0828_dev *dev);
115extern int au0828_i2c_unregister(struct au0828_dev *dev); 112extern int au0828_i2c_unregister(struct au0828_dev *dev);
116extern void au0828_call_i2c_clients(struct au0828_dev *dev, 113extern void au0828_call_i2c_clients(struct au0828_dev *dev,
117 unsigned int cmd, void *arg); 114 unsigned int cmd, void *arg);
118extern unsigned int i2c_debug;
119 115
120/* ----------------------------------------------------------- */ 116/* ----------------------------------------------------------- */
121/* au0828-dvb.c */ 117/* au0828-dvb.c */
@@ -123,6 +119,6 @@ extern int au0828_dvb_register(struct au0828_dev *dev);
123extern void au0828_dvb_unregister(struct au0828_dev *dev); 119extern void au0828_dvb_unregister(struct au0828_dev *dev);
124 120
125#define dprintk(level, fmt, arg...)\ 121#define dprintk(level, fmt, arg...)\
126 do { if (debug & level)\ 122 do { if (au0828_debug & level)\
127 printk(KERN_DEBUG DRIVER_NAME "/0: " fmt, ## arg);\ 123 printk(KERN_DEBUG DRIVER_NAME "/0: " fmt, ## arg);\
128 } while (0) 124 } while (0)
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index bcf6d9ba063d..27635cdcbaf2 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -58,6 +58,7 @@ config VIDEO_CX88_DVB
58 select DVB_CX24123 if !DVB_FE_CUSTOMISE 58 select DVB_CX24123 if !DVB_FE_CUSTOMISE
59 select DVB_ISL6421 if !DVB_FE_CUSTOMISE 59 select DVB_ISL6421 if !DVB_FE_CUSTOMISE
60 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE 60 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE
61 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
61 ---help--- 62 ---help---
62 This adds support for DVB/ATSC cards based on the 63 This adds support for DVB/ATSC cards based on the
63 Conexant 2388x chip. 64 Conexant 2388x chip.
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 61c4f72644b8..6c0c94c5ef91 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -546,10 +546,12 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
546 if (retval < 0) 546 if (retval < 0)
547 return retval; 547 return retval;
548 548
549 dev->mailbox = blackbird_find_mailbox(dev); 549 retval = blackbird_find_mailbox(dev);
550 if (dev->mailbox < 0) 550 if (retval < 0)
551 return -1; 551 return -1;
552 552
553 dev->mailbox = retval;
554
553 retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ 555 retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
554 if (retval < 0) { 556 if (retval < 0) {
555 dprintk(0, "ERROR: Firmware ping failed!\n"); 557 dprintk(0, "ERROR: Firmware ping failed!\n");
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 620159d05506..2b6b283cda15 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1591,6 +1591,7 @@ static const struct cx88_board cx88_boards[] = {
1591 .vmux = 2, 1591 .vmux = 2,
1592 .gpio0 = 0x16d9, 1592 .gpio0 = 0x16d9,
1593 }}, 1593 }},
1594 .mpeg = CX88_MPEG_DVB,
1594 }, 1595 },
1595 [CX88_BOARD_PROLINK_PV_8000GT] = { 1596 [CX88_BOARD_PROLINK_PV_8000GT] = {
1596 .name = "Prolink Pixelview MPEG 8000GT", 1597 .name = "Prolink Pixelview MPEG 8000GT",
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index f1251b844e08..1c7fe6862a60 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -47,6 +47,7 @@
47#include "isl6421.h" 47#include "isl6421.h"
48#include "tuner-simple.h" 48#include "tuner-simple.h"
49#include "tda9887.h" 49#include "tda9887.h"
50#include "s5h1411.h"
50 51
51MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 52MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
52MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 53MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -463,6 +464,22 @@ static struct zl10353_config cx88_geniatech_x8000_mt = {
463 .no_tuner = 1, 464 .no_tuner = 1,
464}; 465};
465 466
467static struct s5h1411_config dvico_fusionhdtv7_config = {
468 .output_mode = S5H1411_SERIAL_OUTPUT,
469 .gpio = S5H1411_GPIO_ON,
470 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
471 .qam_if = S5H1411_IF_44000,
472 .vsb_if = S5H1411_IF_44000,
473 .inversion = S5H1411_INVERSION_OFF,
474 .status_mode = S5H1411_DEMODLOCKING
475};
476
477static struct xc5000_config dvico_fusionhdtv7_tuner_config = {
478 .i2c_address = 0xc2 >> 1,
479 .if_khz = 5380,
480 .tuner_callback = cx88_tuner_callback,
481};
482
466static int attach_xc3028(u8 addr, struct cx8802_dev *dev) 483static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
467{ 484{
468 struct dvb_frontend *fe; 485 struct dvb_frontend *fe;
@@ -844,6 +861,21 @@ static int dvb_register(struct cx8802_dev *dev)
844 if (attach_xc3028(0x61, dev) < 0) 861 if (attach_xc3028(0x61, dev) < 0)
845 return -EINVAL; 862 return -EINVAL;
846 break; 863 break;
864 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
865 dev->dvb.frontend = dvb_attach(s5h1411_attach,
866 &dvico_fusionhdtv7_config,
867 &dev->core->i2c_adap);
868 if (dev->dvb.frontend != NULL) {
869 /* tuner_config.video_dev must point to
870 * i2c_adap.algo_data
871 */
872 dvico_fusionhdtv7_tuner_config.priv =
873 dev->core->i2c_adap.algo_data;
874 dvb_attach(xc5000_attach, dev->dvb.frontend,
875 &dev->core->i2c_adap,
876 &dvico_fusionhdtv7_tuner_config);
877 }
878 break;
847 default: 879 default:
848 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", 880 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
849 dev->core->name); 881 dev->core->name);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index f8c41d8c74c4..5d837c16ee22 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -650,7 +650,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
650 650
651 dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, 651 dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
652 GFP_KERNEL); 652 GFP_KERNEL);
653 if (!dev->isoc_ctl.urb) { 653 if (!dev->isoc_ctl.transfer_buffer) {
654 em28xx_errdev("cannot allocate memory for usbtransfer\n"); 654 em28xx_errdev("cannot allocate memory for usbtransfer\n");
655 kfree(dev->isoc_ctl.urb); 655 kfree(dev->isoc_ctl.urb);
656 return -ENOMEM; 656 return -ENOMEM;
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 11c5fdedc23b..7b65f5e537f8 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -509,8 +509,11 @@ static int ir_probe(struct i2c_adapter *adap)
509 static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; 509 static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 };
510 static const int probe_cx23885[] = { 0x6b, -1 }; 510 static const int probe_cx23885[] = { 0x6b, -1 };
511 const int *probe; 511 const int *probe;
512 struct i2c_client *c; 512 struct i2c_msg msg = {
513 unsigned char buf; 513 .flags = I2C_M_RD,
514 .len = 0,
515 .buf = NULL,
516 };
514 int i, rc; 517 int i, rc;
515 518
516 switch (adap->id) { 519 switch (adap->id) {
@@ -536,23 +539,17 @@ static int ir_probe(struct i2c_adapter *adap)
536 return 0; 539 return 0;
537 } 540 }
538 541
539 c = kzalloc(sizeof(*c), GFP_KERNEL);
540 if (!c)
541 return -ENOMEM;
542
543 c->adapter = adap;
544 for (i = 0; -1 != probe[i]; i++) { 542 for (i = 0; -1 != probe[i]; i++) {
545 c->addr = probe[i]; 543 msg.addr = probe[i];
546 rc = i2c_master_recv(c, &buf, 0); 544 rc = i2c_transfer(adap, &msg, 1);
547 dprintk(1,"probe 0x%02x @ %s: %s\n", 545 dprintk(1,"probe 0x%02x @ %s: %s\n",
548 probe[i], adap->name, 546 probe[i], adap->name,
549 (0 == rc) ? "yes" : "no"); 547 (1 == rc) ? "yes" : "no");
550 if (0 == rc) { 548 if (1 == rc) {
551 ir_attach(adap, probe[i], 0, 0); 549 ir_attach(adap, probe[i], 0, 0);
552 break; 550 break;
553 } 551 }
554 } 552 }
555 kfree(c);
556 return 0; 553 return 0;
557} 554}
558 555
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
index a8da90f69dd9..158b3d0c6532 100644
--- a/drivers/media/video/pvrusb2/Kconfig
+++ b/drivers/media/video/pvrusb2/Kconfig
@@ -64,6 +64,7 @@ config VIDEO_PVRUSB2_DVB
64 depends on VIDEO_PVRUSB2 && DVB_CORE && EXPERIMENTAL 64 depends on VIDEO_PVRUSB2 && DVB_CORE && EXPERIMENTAL
65 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 65 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
66 select DVB_S5H1409 if !DVB_FE_CUSTOMISE 66 select DVB_S5H1409 if !DVB_FE_CUSTOMISE
67 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
67 select DVB_TDA10048 if !DVB_FE_CUSTOMIZE 68 select DVB_TDA10048 if !DVB_FE_CUSTOMIZE
68 select DVB_TDA18271 if !DVB_FE_CUSTOMIZE 69 select DVB_TDA18271 if !DVB_FE_CUSTOMIZE
69 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE 70 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 2dd06a90adce..3a141d93e1a9 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -36,6 +36,7 @@ pvr2_device_desc structures.
36#include "pvrusb2-hdw-internal.h" 36#include "pvrusb2-hdw-internal.h"
37#include "lgdt330x.h" 37#include "lgdt330x.h"
38#include "s5h1409.h" 38#include "s5h1409.h"
39#include "s5h1411.h"
39#include "tda10048.h" 40#include "tda10048.h"
40#include "tda18271.h" 41#include "tda18271.h"
41#include "tda8290.h" 42#include "tda8290.h"
@@ -368,6 +369,15 @@ static struct s5h1409_config pvr2_s5h1409_config = {
368 .status_mode = S5H1409_DEMODLOCKING, 369 .status_mode = S5H1409_DEMODLOCKING,
369}; 370};
370 371
372static struct s5h1411_config pvr2_s5h1411_config = {
373 .output_mode = S5H1411_PARALLEL_OUTPUT,
374 .gpio = S5H1411_GPIO_OFF,
375 .vsb_if = S5H1411_IF_44000,
376 .qam_if = S5H1411_IF_4000,
377 .inversion = S5H1411_INVERSION_ON,
378 .status_mode = S5H1411_DEMODLOCKING,
379};
380
371static struct tda18271_std_map hauppauge_tda18271_std_map = { 381static struct tda18271_std_map hauppauge_tda18271_std_map = {
372 .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3, 382 .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3,
373 .if_lvl = 6, .rfagc_top = 0x37, }, 383 .if_lvl = 6, .rfagc_top = 0x37, },
@@ -390,6 +400,16 @@ static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
390 return -EIO; 400 return -EIO;
391} 401}
392 402
403static int pvr2_s5h1411_attach(struct pvr2_dvb_adapter *adap)
404{
405 adap->fe = dvb_attach(s5h1411_attach, &pvr2_s5h1411_config,
406 &adap->channel.hdw->i2c_adap);
407 if (adap->fe)
408 return 0;
409
410 return -EIO;
411}
412
393static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap) 413static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
394{ 414{
395 dvb_attach(tda829x_attach, adap->fe, 415 dvb_attach(tda829x_attach, adap->fe,
@@ -406,6 +426,11 @@ struct pvr2_dvb_props pvr2_750xx_dvb_props = {
406 .frontend_attach = pvr2_s5h1409_attach, 426 .frontend_attach = pvr2_s5h1409_attach,
407 .tuner_attach = pvr2_tda18271_8295_attach, 427 .tuner_attach = pvr2_tda18271_8295_attach,
408}; 428};
429
430struct pvr2_dvb_props pvr2_751xx_dvb_props = {
431 .frontend_attach = pvr2_s5h1411_attach,
432 .tuner_attach = pvr2_tda18271_8295_attach,
433};
409#endif 434#endif
410 435
411static const char *pvr2_client_75xxx[] = { 436static const char *pvr2_client_75xxx[] = {
@@ -454,6 +479,9 @@ static const struct pvr2_device_desc pvr2_device_751xx = {
454 .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, 479 .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
455 .default_std_mask = V4L2_STD_NTSC_M, 480 .default_std_mask = V4L2_STD_NTSC_M,
456 .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, 481 .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
482#ifdef CONFIG_VIDEO_PVRUSB2_DVB
483 .dvb_props = &pvr2_751xx_dvb_props,
484#endif
457}; 485};
458 486
459 487
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index c2e2b06fe2e0..d016f8b6c70b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -104,28 +104,28 @@ struct pvr2_device_desc {
104 unsigned char digital_control_scheme; 104 unsigned char digital_control_scheme;
105 105
106 /* If set, we don't bother trying to load cx23416 firmware. */ 106 /* If set, we don't bother trying to load cx23416 firmware. */
107 int flag_skip_cx23416_firmware:1; 107 unsigned int flag_skip_cx23416_firmware:1;
108 108
109 /* If set, the encoder must be healthy in order for digital mode to 109 /* If set, the encoder must be healthy in order for digital mode to
110 work (otherwise we assume that digital streaming will work even 110 work (otherwise we assume that digital streaming will work even
111 if we fail to locate firmware for the encoder). If the device 111 if we fail to locate firmware for the encoder). If the device
112 doesn't support digital streaming then this flag has no 112 doesn't support digital streaming then this flag has no
113 effect. */ 113 effect. */
114 int flag_digital_requires_cx23416:1; 114 unsigned int flag_digital_requires_cx23416:1;
115 115
116 /* Device has a hauppauge eeprom which we can interrogate. */ 116 /* Device has a hauppauge eeprom which we can interrogate. */
117 int flag_has_hauppauge_rom:1; 117 unsigned int flag_has_hauppauge_rom:1;
118 118
119 /* Device does not require a powerup command to be issued. */ 119 /* Device does not require a powerup command to be issued. */
120 int flag_no_powerup:1; 120 unsigned int flag_no_powerup:1;
121 121
122 /* Device has a cx25840 - this enables special additional logic to 122 /* Device has a cx25840 - this enables special additional logic to
123 handle it. */ 123 handle it. */
124 int flag_has_cx25840:1; 124 unsigned int flag_has_cx25840:1;
125 125
126 /* Device has a wm8775 - this enables special additional logic to 126 /* Device has a wm8775 - this enables special additional logic to
127 ensure that it is found. */ 127 ensure that it is found. */
128 int flag_has_wm8775:1; 128 unsigned int flag_has_wm8775:1;
129 129
130 /* Device has IR hardware that can be faked into looking like a 130 /* Device has IR hardware that can be faked into looking like a
131 normal Hauppauge i2c IR receiver. This is currently very 131 normal Hauppauge i2c IR receiver. This is currently very
@@ -135,15 +135,15 @@ struct pvr2_device_desc {
135 to virtualize the presence of the non-existant IR receiver chip and 135 to virtualize the presence of the non-existant IR receiver chip and
136 implement the virtual receiver in terms of appropriate FX2 136 implement the virtual receiver in terms of appropriate FX2
137 commands. */ 137 commands. */
138 int flag_has_hauppauge_custom_ir:1; 138 unsigned int flag_has_hauppauge_custom_ir:1;
139 139
140 /* These bits define which kinds of sources the device can handle. 140 /* These bits define which kinds of sources the device can handle.
141 Note: Digital tuner presence is inferred by the 141 Note: Digital tuner presence is inferred by the
142 digital_control_scheme enumeration. */ 142 digital_control_scheme enumeration. */
143 int flag_has_fmradio:1; /* Has FM radio receiver */ 143 unsigned int flag_has_fmradio:1; /* Has FM radio receiver */
144 int flag_has_analogtuner:1; /* Has analog tuner */ 144 unsigned int flag_has_analogtuner:1; /* Has analog tuner */
145 int flag_has_composite:1; /* Has composite input */ 145 unsigned int flag_has_composite:1; /* Has composite input */
146 int flag_has_svideo:1; /* Has s-video input */ 146 unsigned int flag_has_svideo:1; /* Has s-video input */
147}; 147};
148 148
149extern struct usb_device_id pvr2_device_table[]; 149extern struct usb_device_id pvr2_device_table[];
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 529e00952a8d..2b72e10e6b9f 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -369,19 +369,13 @@ static void set_type(struct i2c_client *c, unsigned int type,
369 break; 369 break;
370 } 370 }
371 case TUNER_TEA5767: 371 case TUNER_TEA5767:
372 if (tea5767_attach(&t->fe, t->i2c->adapter, t->i2c->addr) == NULL) { 372 if (!tea5767_attach(&t->fe, t->i2c->adapter, t->i2c->addr))
373 t->type = TUNER_ABSENT; 373 goto attach_failed;
374 t->mode_mask = T_UNINITIALIZED;
375 return;
376 }
377 t->mode_mask = T_RADIO; 374 t->mode_mask = T_RADIO;
378 break; 375 break;
379 case TUNER_TEA5761: 376 case TUNER_TEA5761:
380 if (tea5761_attach(&t->fe, t->i2c->adapter, t->i2c->addr) == NULL) { 377 if (!tea5761_attach(&t->fe, t->i2c->adapter, t->i2c->addr))
381 t->type = TUNER_ABSENT; 378 goto attach_failed;
382 t->mode_mask = T_UNINITIALIZED;
383 return;
384 }
385 t->mode_mask = T_RADIO; 379 t->mode_mask = T_RADIO;
386 break; 380 break;
387 case TUNER_PHILIPS_FMD1216ME_MK3: 381 case TUNER_PHILIPS_FMD1216ME_MK3:
@@ -394,12 +388,9 @@ static void set_type(struct i2c_client *c, unsigned int type,
394 buffer[2] = 0x86; 388 buffer[2] = 0x86;
395 buffer[3] = 0x54; 389 buffer[3] = 0x54;
396 i2c_master_send(c, buffer, 4); 390 i2c_master_send(c, buffer, 4);
397 if (simple_tuner_attach(&t->fe, t->i2c->adapter, t->i2c->addr, 391 if (!simple_tuner_attach(&t->fe, t->i2c->adapter, t->i2c->addr,
398 t->type) == NULL) { 392 t->type))
399 t->type = TUNER_ABSENT; 393 goto attach_failed;
400 t->mode_mask = T_UNINITIALIZED;
401 return;
402 }
403 break; 394 break;
404 case TUNER_PHILIPS_TD1316: 395 case TUNER_PHILIPS_TD1316:
405 buffer[0] = 0x0b; 396 buffer[0] = 0x0b;
@@ -407,12 +398,9 @@ static void set_type(struct i2c_client *c, unsigned int type,
407 buffer[2] = 0x86; 398 buffer[2] = 0x86;
408 buffer[3] = 0xa4; 399 buffer[3] = 0xa4;
409 i2c_master_send(c,buffer,4); 400 i2c_master_send(c,buffer,4);
410 if (simple_tuner_attach(&t->fe, t->i2c->adapter, 401 if (!simple_tuner_attach(&t->fe, t->i2c->adapter,
411 t->i2c->addr, t->type) == NULL) { 402 t->i2c->addr, t->type))
412 t->type = TUNER_ABSENT; 403 goto attach_failed;
413 t->mode_mask = T_UNINITIALIZED;
414 return;
415 }
416 break; 404 break;
417 case TUNER_XC2028: 405 case TUNER_XC2028:
418 { 406 {
@@ -421,40 +409,34 @@ static void set_type(struct i2c_client *c, unsigned int type,
421 .i2c_addr = t->i2c->addr, 409 .i2c_addr = t->i2c->addr,
422 .callback = t->tuner_callback, 410 .callback = t->tuner_callback,
423 }; 411 };
424 if (!xc2028_attach(&t->fe, &cfg)) { 412 if (!xc2028_attach(&t->fe, &cfg))
425 t->type = TUNER_ABSENT; 413 goto attach_failed;
426 t->mode_mask = T_UNINITIALIZED;
427 return;
428 }
429 break; 414 break;
430 } 415 }
431 case TUNER_TDA9887: 416 case TUNER_TDA9887:
432 tda9887_attach(&t->fe, t->i2c->adapter, t->i2c->addr); 417 tda9887_attach(&t->fe, t->i2c->adapter, t->i2c->addr);
433 break; 418 break;
434 case TUNER_XC5000: 419 case TUNER_XC5000:
420 {
421 struct dvb_tuner_ops *xc_tuner_ops;
422
435 xc5000_cfg.i2c_address = t->i2c->addr; 423 xc5000_cfg.i2c_address = t->i2c->addr;
436 xc5000_cfg.if_khz = 5380; 424 xc5000_cfg.if_khz = 5380;
437 xc5000_cfg.priv = c->adapter->algo_data; 425 xc5000_cfg.priv = c->adapter->algo_data;
438 xc5000_cfg.tuner_callback = t->tuner_callback; 426 xc5000_cfg.tuner_callback = t->tuner_callback;
439 if (!xc5000_attach(&t->fe, t->i2c->adapter, &xc5000_cfg)) { 427 if (!xc5000_attach(&t->fe, t->i2c->adapter, &xc5000_cfg))
440 t->type = TUNER_ABSENT; 428 goto attach_failed;
441 t->mode_mask = T_UNINITIALIZED; 429
442 return;
443 }
444 {
445 struct dvb_tuner_ops *xc_tuner_ops;
446 xc_tuner_ops = &t->fe.ops.tuner_ops; 430 xc_tuner_ops = &t->fe.ops.tuner_ops;
447 if(xc_tuner_ops->init != NULL) 431 if (xc_tuner_ops->init)
448 xc_tuner_ops->init(&t->fe); 432 xc_tuner_ops->init(&t->fe);
449 }
450 break; 433 break;
434 }
451 default: 435 default:
452 if (simple_tuner_attach(&t->fe, t->i2c->adapter, 436 if (!simple_tuner_attach(&t->fe, t->i2c->adapter,
453 t->i2c->addr, t->type) == NULL) { 437 t->i2c->addr, t->type))
454 t->type = TUNER_ABSENT; 438 goto attach_failed;
455 t->mode_mask = T_UNINITIALIZED; 439
456 return;
457 }
458 break; 440 break;
459 } 441 }
460 442
@@ -476,11 +458,27 @@ static void set_type(struct i2c_client *c, unsigned int type,
476 if (t->mode_mask == T_UNINITIALIZED) 458 if (t->mode_mask == T_UNINITIALIZED)
477 t->mode_mask = new_mode_mask; 459 t->mode_mask = new_mode_mask;
478 460
479 set_freq(c, (V4L2_TUNER_RADIO == t->mode) ? t->radio_freq : t->tv_freq); 461 /* xc2028/3028 and xc5000 requires a firmware to be set-up later
462 trying to set a frequency here will just fail
463 FIXME: better to move set_freq to the tuner code. This is needed
464 on analog tuners for PLL to properly work
465 */
466 if (t->type != TUNER_XC2028 && t->type != TUNER_XC5000)
467 set_freq(c, (V4L2_TUNER_RADIO == t->mode) ?
468 t->radio_freq : t->tv_freq);
469
480 tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", 470 tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
481 c->adapter->name, c->driver->driver.name, c->addr << 1, type, 471 c->adapter->name, c->driver->driver.name, c->addr << 1, type,
482 t->mode_mask); 472 t->mode_mask);
483 tuner_i2c_address_check(t); 473 tuner_i2c_address_check(t);
474 return;
475
476attach_failed:
477 tuner_dbg("Tuner attach for type = %d failed.\n", t->type);
478 t->type = TUNER_ABSENT;
479 t->mode_mask = T_UNINITIALIZED;
480
481 return;
484} 482}
485 483
486/* 484/*
@@ -495,14 +493,16 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
495{ 493{
496 struct tuner *t = i2c_get_clientdata(c); 494 struct tuner *t = i2c_get_clientdata(c);
497 495
498 tuner_dbg("set addr for type %i\n", t->type);
499
500 if ( (t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) && 496 if ( (t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) &&
501 (t->mode_mask & tun_setup->mode_mask))) || 497 (t->mode_mask & tun_setup->mode_mask))) ||
502 (tun_setup->addr == c->addr)) { 498 (tun_setup->addr == c->addr)) {
503 set_type(c, tun_setup->type, tun_setup->mode_mask, 499 set_type(c, tun_setup->type, tun_setup->mode_mask,
504 tun_setup->config, tun_setup->tuner_callback); 500 tun_setup->config, tun_setup->tuner_callback);
505 } 501 } else
502 tuner_dbg("set addr discarded for type %i, mask %x. "
503 "Asked to change tuner at addr 0x%02x, with mask %x\n",
504 t->type, t->mode_mask,
505 tun_setup->addr, tun_setup->mode_mask);
506} 506}
507 507
508static inline int check_mode(struct tuner *t, char *cmd) 508static inline int check_mode(struct tuner *t, char *cmd)
diff --git a/drivers/media/video/tuner-xc2028.c b/drivers/media/video/tuner-xc2028.c
index cc3db7d79a0d..9e9003cffc7f 100644
--- a/drivers/media/video/tuner-xc2028.c
+++ b/drivers/media/video/tuner-xc2028.c
@@ -432,7 +432,7 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
432 432
433 type &= type_mask; 433 type &= type_mask;
434 434
435 if (!type & SCODE) 435 if (!(type & SCODE))
436 type_mask = ~0; 436 type_mask = ~0;
437 437
438 /* Seek for exact match */ 438 /* Seek for exact match */
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index b1e9592acb90..845be1864f68 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -888,7 +888,7 @@ static int vivi_open(struct inode *inode, struct file *file)
888{ 888{
889 int minor = iminor(inode); 889 int minor = iminor(inode);
890 struct vivi_dev *dev; 890 struct vivi_dev *dev;
891 struct vivi_fh *fh; 891 struct vivi_fh *fh = NULL;
892 int i; 892 int i;
893 int retval = 0; 893 int retval = 0;
894 894