Diff markup
1 /* 1 /*
2 em28xx-cards.c - driver for Empia EM2800/EM 2 em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB
3 video capture devices 3 video capture devices
4 4
5 Copyright (C) 2005 Ludovico Cavedon <cavedo 5 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
6 Markus Rechberger <mrech 6 Markus Rechberger <mrechberger@gmail.com>
7 Mauro Carvalho Chehab <m 7 Mauro Carvalho Chehab <mchehab@infradead.org>
8 Sascha Sommer <saschasom 8 Sascha Sommer <saschasommer@freenet.de>
9 9
10 This program is free software; you can redi 10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Publi 11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either versio 12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version. 13 (at your option) any later version.
14 14
15 This program is distributed in the hope tha 15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the 16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details 18 GNU General Public License for more details.
19 19
20 You should have received a copy of the GNU 20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to t 21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, 22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */ 23 */
24 24
25 #include <linux/init.h> 25 #include <linux/init.h>
26 #include <linux/module.h> 26 #include <linux/module.h>
27 #include <linux/delay.h> 27 #include <linux/delay.h>
28 #include <linux/i2c.h> 28 #include <linux/i2c.h>
29 #include <linux/usb.h> 29 #include <linux/usb.h>
30 #include <media/tuner.h> 30 #include <media/tuner.h>
31 #include <media/msp3400.h> 31 #include <media/msp3400.h>
32 #include <media/saa7115.h> 32 #include <media/saa7115.h>
33 #include <media/tvp5150.h> 33 #include <media/tvp5150.h>
34 #include <media/tveeprom.h> 34 #include <media/tveeprom.h>
35 #include <media/audiochip.h> 35 #include <media/audiochip.h>
36 #include <media/v4l2-common.h> 36 #include <media/v4l2-common.h>
37 37
38 #include "em28xx.h" 38 #include "em28xx.h"
39 #include "tuner-xc2028.h" 39 #include "tuner-xc2028.h"
40 40
41 static int tuner = -1; 41 static int tuner = -1;
42 module_param(tuner, int, 0444); 42 module_param(tuner, int, 0444);
43 MODULE_PARM_DESC(tuner, "tuner type"); 43 MODULE_PARM_DESC(tuner, "tuner type");
44 44
45 static unsigned int disable_ir; 45 static unsigned int disable_ir;
46 module_param(disable_ir, int, 0444); 46 module_param(disable_ir, int, 0444);
47 MODULE_PARM_DESC(disable_ir, "disable infrared 47 MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
48 48
49 struct em28xx_hash_table { 49 struct em28xx_hash_table {
50 unsigned long hash; 50 unsigned long hash;
51 unsigned int model; 51 unsigned int model;
52 unsigned int tuner; 52 unsigned int tuner;
53 }; 53 };
54 54
55 /* Boards supported by driver */ 55 /* Boards supported by driver */
56 56
57 #define EM2800_BOARD_UNKNOWN 57 #define EM2800_BOARD_UNKNOWN 0
58 #define EM2820_BOARD_UNKNOWN 58 #define EM2820_BOARD_UNKNOWN 1
59 #define EM2820_BOARD_TERRATEC_CINERGY_250 59 #define EM2820_BOARD_TERRATEC_CINERGY_250 2
60 #define EM2820_BOARD_PINNACLE_USB_2 60 #define EM2820_BOARD_PINNACLE_USB_2 3
61 #define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 61 #define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4
62 #define EM2820_BOARD_MSI_VOX_USB_2 62 #define EM2820_BOARD_MSI_VOX_USB_2 5
63 #define EM2800_BOARD_TERRATEC_CINERGY_200 63 #define EM2800_BOARD_TERRATEC_CINERGY_200 6
64 #define EM2800_BOARD_LEADTEK_WINFAST_USBII 64 #define EM2800_BOARD_LEADTEK_WINFAST_USBII 7
65 #define EM2800_BOARD_KWORLD_USB2800 65 #define EM2800_BOARD_KWORLD_USB2800 8
66 #define EM2820_BOARD_PINNACLE_DVC_90 66 #define EM2820_BOARD_PINNACLE_DVC_90 9
67 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 67 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 10
68 #define EM2880_BOARD_TERRATEC_HYBRID_XS 68 #define EM2880_BOARD_TERRATEC_HYBRID_XS 11
69 #define EM2820_BOARD_KWORLD_PVRTV2800RF 69 #define EM2820_BOARD_KWORLD_PVRTV2800RF 12
70 #define EM2880_BOARD_TERRATEC_PRODIGY_XS 70 #define EM2880_BOARD_TERRATEC_PRODIGY_XS 13
71 #define EM2820_BOARD_PROLINK_PLAYTV_USB2 71 #define EM2820_BOARD_PROLINK_PLAYTV_USB2 14
72 #define EM2800_BOARD_VGEAR_POCKETTV 72 #define EM2800_BOARD_VGEAR_POCKETTV 15
73 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 73 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 16
74 74
75 struct em28xx_board em28xx_boards[] = { 75 struct em28xx_board em28xx_boards[] = {
76 [EM2800_BOARD_UNKNOWN] = { 76 [EM2800_BOARD_UNKNOWN] = {
77 .name = "Unknown EM280 77 .name = "Unknown EM2800 video grabber",
78 .is_em2800 = 1, 78 .is_em2800 = 1,
79 .vchannels = 2, 79 .vchannels = 2,
80 .tda9887_conf = TDA9887_PRESEN 80 .tda9887_conf = TDA9887_PRESENT,
81 .decoder = EM28XX_SAA7113 81 .decoder = EM28XX_SAA7113,
82 .input = { { 82 .input = { {
83 .type = EM28XX_VMU 83 .type = EM28XX_VMUX_COMPOSITE1,
84 .vmux = SAA7115_CO 84 .vmux = SAA7115_COMPOSITE0,
85 .amux = 1, 85 .amux = 1,
86 }, { 86 }, {
87 .type = EM28XX_VMU 87 .type = EM28XX_VMUX_SVIDEO,
88 .vmux = SAA7115_SV 88 .vmux = SAA7115_SVIDEO3,
89 .amux = 1, 89 .amux = 1,
90 } }, 90 } },
91 }, 91 },
92 [EM2820_BOARD_UNKNOWN] = { 92 [EM2820_BOARD_UNKNOWN] = {
93 .name = "Unknown EM275 93 .name = "Unknown EM2750/28xx video grabber",
94 .is_em2800 = 0, 94 .is_em2800 = 0,
95 .tuner_type = TUNER_ABSENT, 95 .tuner_type = TUNER_ABSENT,
96 }, 96 },
97 [EM2820_BOARD_KWORLD_PVRTV2800RF] = { 97 [EM2820_BOARD_KWORLD_PVRTV2800RF] = {
98 .name = "Kworld PVR TV 98 .name = "Kworld PVR TV 2800 RF",
99 .is_em2800 = 0, 99 .is_em2800 = 0,
100 .vchannels = 2, 100 .vchannels = 2,
101 .tuner_type = TUNER_TEMIC_PA 101 .tuner_type = TUNER_TEMIC_PAL,
102 .tda9887_conf = TDA9887_PRESEN 102 .tda9887_conf = TDA9887_PRESENT,
103 .decoder = EM28XX_SAA7113 103 .decoder = EM28XX_SAA7113,
104 .input = { { 104 .input = { {
105 .type = EM28XX_VMU 105 .type = EM28XX_VMUX_COMPOSITE1,
106 .vmux = SAA7115_CO 106 .vmux = SAA7115_COMPOSITE0,
107 .amux = 1, 107 .amux = 1,
108 }, { 108 }, {
109 .type = EM28XX_VMU 109 .type = EM28XX_VMUX_SVIDEO,
110 .vmux = SAA7115_SV 110 .vmux = SAA7115_SVIDEO3,
111 .amux = 1, 111 .amux = 1,
112 } }, 112 } },
113 }, 113 },
114 [EM2820_BOARD_TERRATEC_CINERGY_250] = 114 [EM2820_BOARD_TERRATEC_CINERGY_250] = {
115 .name = "Terratec Cine 115 .name = "Terratec Cinergy 250 USB",
116 .vchannels = 3, 116 .vchannels = 3,
117 .tuner_type = TUNER_LG_PAL_N 117 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
118 .tda9887_conf = TDA9887_PRESEN 118 .tda9887_conf = TDA9887_PRESENT,
119 .decoder = EM28XX_SAA7113 119 .decoder = EM28XX_SAA7113,
120 .input = { { 120 .input = { {
121 .type = EM28XX_VMU 121 .type = EM28XX_VMUX_TELEVISION,
122 .vmux = SAA7115_CO 122 .vmux = SAA7115_COMPOSITE2,
123 .amux = 1, 123 .amux = 1,
124 }, { 124 }, {
125 .type = EM28XX_VMU 125 .type = EM28XX_VMUX_COMPOSITE1,
126 .vmux = SAA7115_CO 126 .vmux = SAA7115_COMPOSITE0,
127 .amux = 1, 127 .amux = 1,
128 }, { 128 }, {
129 .type = EM28XX_VMU 129 .type = EM28XX_VMUX_SVIDEO,
130 .vmux = SAA7115_SV 130 .vmux = SAA7115_SVIDEO3,
131 .amux = 1, 131 .amux = 1,
132 } }, 132 } },
133 }, 133 },
134 [EM2820_BOARD_PINNACLE_USB_2] = { 134 [EM2820_BOARD_PINNACLE_USB_2] = {
135 .name = "Pinnacle PCTV 135 .name = "Pinnacle PCTV USB 2",
136 .vchannels = 3, 136 .vchannels = 3,
137 .tuner_type = TUNER_LG_PAL_N 137 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
138 .tda9887_conf = TDA9887_PRESEN 138 .tda9887_conf = TDA9887_PRESENT,
139 .decoder = EM28XX_SAA7113 139 .decoder = EM28XX_SAA7113,
140 .input = { { 140 .input = { {
141 .type = EM28XX_VMU 141 .type = EM28XX_VMUX_TELEVISION,
142 .vmux = SAA7115_CO 142 .vmux = SAA7115_COMPOSITE2,
143 .amux = 0, 143 .amux = 0,
144 }, { 144 }, {
145 .type = EM28XX_VMU 145 .type = EM28XX_VMUX_COMPOSITE1,
146 .vmux = SAA7115_CO 146 .vmux = SAA7115_COMPOSITE0,
147 .amux = 1, 147 .amux = 1,
148 }, { 148 }, {
149 .type = EM28XX_VMU 149 .type = EM28XX_VMUX_SVIDEO,
150 .vmux = SAA7115_SV 150 .vmux = SAA7115_SVIDEO3,
151 .amux = 1, 151 .amux = 1,
152 } }, 152 } },
153 }, 153 },
154 [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = 154 [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = {
155 .name = "Hauppauge Win 155 .name = "Hauppauge WinTV USB 2",
156 .vchannels = 3, 156 .vchannels = 3,
157 .tuner_type = TUNER_PHILIPS_ 157 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
158 .tda9887_conf = TDA9887_PRESEN 158 .tda9887_conf = TDA9887_PRESENT |
159 TDA9887_PORT1_ 159 TDA9887_PORT1_ACTIVE|
160 TDA9887_PORT2_ 160 TDA9887_PORT2_ACTIVE,
161 .decoder = EM28XX_TVP5150 161 .decoder = EM28XX_TVP5150,
162 .has_msp34xx = 1, 162 .has_msp34xx = 1,
163 /*FIXME: S-Video not tested */ 163 /*FIXME: S-Video not tested */
164 .input = { { 164 .input = { {
165 .type = EM28XX_VMU 165 .type = EM28XX_VMUX_TELEVISION,
166 .vmux = TVP5150_CO 166 .vmux = TVP5150_COMPOSITE0,
167 .amux = MSP_INPUT_ 167 .amux = MSP_INPUT_DEFAULT,
168 }, { 168 }, {
169 .type = EM28XX_VMU 169 .type = EM28XX_VMUX_SVIDEO,
170 .vmux = TVP5150_SV 170 .vmux = TVP5150_SVIDEO,
171 .amux = MSP_INPUT( 171 .amux = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
172 MSP_DS 172 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART),
173 } }, 173 } },
174 }, 174 },
175 [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] 175 [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = {
176 .name = "Hauppauge Win 176 .name = "Hauppauge WinTV HVR 900",
177 .vchannels = 3, 177 .vchannels = 3,
178 .tda9887_conf = TDA9887_PRESEN 178 .tda9887_conf = TDA9887_PRESENT,
179 .tuner_type = TUNER_XC2028, 179 .tuner_type = TUNER_XC2028,
180 .mts_firmware = 1, 180 .mts_firmware = 1,
181 .decoder = EM28XX_TVP5150 181 .decoder = EM28XX_TVP5150,
182 .input = { { 182 .input = { {
183 .type = EM28XX_VMU 183 .type = EM28XX_VMUX_TELEVISION,
184 .vmux = TVP5150_CO 184 .vmux = TVP5150_COMPOSITE0,
185 .amux = 0, 185 .amux = 0,
186 }, { 186 }, {
187 .type = EM28XX_VMU 187 .type = EM28XX_VMUX_COMPOSITE1,
188 .vmux = TVP5150_CO 188 .vmux = TVP5150_COMPOSITE1,
189 .amux = 1, 189 .amux = 1,
190 }, { 190 }, {
191 .type = EM28XX_VMU 191 .type = EM28XX_VMUX_SVIDEO,
192 .vmux = TVP5150_SV 192 .vmux = TVP5150_SVIDEO,
193 .amux = 1, 193 .amux = 1,
194 } }, 194 } },
195 }, 195 },
196 [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] 196 [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
197 .name = "Hauppauge W 197 .name = "Hauppauge WinTV HVR 950",
198 .vchannels = 3, 198 .vchannels = 3,
199 .tda9887_conf = TDA9887_PRES 199 .tda9887_conf = TDA9887_PRESENT,
200 .tuner_type = TUNER_XC2028 200 .tuner_type = TUNER_XC2028,
201 .mts_firmware = 1, 201 .mts_firmware = 1,
202 .has_12mhz_i2s = 1, 202 .has_12mhz_i2s = 1,
203 .decoder = EM28XX_TVP51 203 .decoder = EM28XX_TVP5150,
204 .input = { { 204 .input = { {
205 .type = EM28XX_VMU 205 .type = EM28XX_VMUX_TELEVISION,
206 .vmux = TVP5150_CO 206 .vmux = TVP5150_COMPOSITE0,
207 .amux = 0, 207 .amux = 0,
208 }, { 208 }, {
209 .type = EM28XX_VMU 209 .type = EM28XX_VMUX_COMPOSITE1,
210 .vmux = TVP5150_CO 210 .vmux = TVP5150_COMPOSITE1,
211 .amux = 1, 211 .amux = 1,
212 }, { 212 }, {
213 .type = EM28XX_VMU 213 .type = EM28XX_VMUX_SVIDEO,
214 .vmux = TVP5150_SV 214 .vmux = TVP5150_SVIDEO,
215 .amux = 1, 215 .amux = 1,
216 } }, 216 } },
217 217
218 /* gpio's 4, 1, 0 */ 218 /* gpio's 4, 1, 0 */
219 .analog_gpio = 0x003d2d, 219 .analog_gpio = 0x003d2d,
220 }, 220 },
221 [EM2880_BOARD_TERRATEC_HYBRID_XS] = { 221 [EM2880_BOARD_TERRATEC_HYBRID_XS] = {
222 .name = "Terratec Hybr 222 .name = "Terratec Hybrid XS",
223 .vchannels = 3, 223 .vchannels = 3,
224 .tda9887_conf = TDA9887_PRESEN 224 .tda9887_conf = TDA9887_PRESENT,
225 .tuner_type = TUNER_XC2028, 225 .tuner_type = TUNER_XC2028,
226 .decoder = EM28XX_TVP5150 226 .decoder = EM28XX_TVP5150,
227 .input = { { 227 .input = { {
228 .type = EM28XX_VMU 228 .type = EM28XX_VMUX_TELEVISION,
229 .vmux = TVP5150_CO 229 .vmux = TVP5150_COMPOSITE0,
230 .amux = 0, 230 .amux = 0,
231 }, { 231 }, {
232 .type = EM28XX_VMU 232 .type = EM28XX_VMUX_COMPOSITE1,
233 .vmux = TVP5150_CO 233 .vmux = TVP5150_COMPOSITE1,
234 .amux = 1, 234 .amux = 1,
235 }, { 235 }, {
236 .type = EM28XX_VMU 236 .type = EM28XX_VMUX_SVIDEO,
237 .vmux = TVP5150_SV 237 .vmux = TVP5150_SVIDEO,
238 .amux = 1, 238 .amux = 1,
239 } }, 239 } },
240 }, 240 },
241 /* maybe there's a reason behind it wh 241 /* maybe there's a reason behind it why Terratec sells the Hybrid XS
242 as Prodigy XS with a different PID, 242 as Prodigy XS with a different PID, let's keep it separated for now
243 maybe we'll need it lateron */ 243 maybe we'll need it lateron */
244 [EM2880_BOARD_TERRATEC_PRODIGY_XS] = { 244 [EM2880_BOARD_TERRATEC_PRODIGY_XS] = {
245 .name = "Terratec Prod 245 .name = "Terratec Prodigy XS",
246 .vchannels = 3, 246 .vchannels = 3,
247 .tda9887_conf = TDA9887_PRESEN 247 .tda9887_conf = TDA9887_PRESENT,
248 .tuner_type = TUNER_XC2028, 248 .tuner_type = TUNER_XC2028,
249 .decoder = EM28XX_TVP5150 249 .decoder = EM28XX_TVP5150,
250 .input = { { 250 .input = { {
251 .type = EM28XX_VMU 251 .type = EM28XX_VMUX_TELEVISION,
252 .vmux = TVP5150_CO 252 .vmux = TVP5150_COMPOSITE0,
253 .amux = 0, 253 .amux = 0,
254 }, { 254 }, {
255 .type = EM28XX_VMU 255 .type = EM28XX_VMUX_COMPOSITE1,
256 .vmux = TVP5150_CO 256 .vmux = TVP5150_COMPOSITE1,
257 .amux = 1, 257 .amux = 1,
258 }, { 258 }, {
259 .type = EM28XX_VMU 259 .type = EM28XX_VMUX_SVIDEO,
260 .vmux = TVP5150_SV 260 .vmux = TVP5150_SVIDEO,
261 .amux = 1, 261 .amux = 1,
262 } }, 262 } },
263 }, 263 },
264 [EM2820_BOARD_MSI_VOX_USB_2] = { 264 [EM2820_BOARD_MSI_VOX_USB_2] = {
265 .name = "MSI VOX 265 .name = "MSI VOX USB 2.0",
266 .vchannels = 3, 266 .vchannels = 3,
267 .tuner_type = TUNER_LG_ 267 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
268 .tda9887_conf = TDA9887_P 268 .tda9887_conf = TDA9887_PRESENT |
269 TDA9887_P 269 TDA9887_PORT1_ACTIVE |
270 TDA9887_P 270 TDA9887_PORT2_ACTIVE,
271 .max_range_640_480 = 1, 271 .max_range_640_480 = 1,
272 272
273 .decoder = EM28XX_SA 273 .decoder = EM28XX_SAA7114,
274 .input = { { 274 .input = { {
275 .type = EM28XX_VM 275 .type = EM28XX_VMUX_TELEVISION,
276 .vmux = SAA7115_C 276 .vmux = SAA7115_COMPOSITE4,
277 .amux = 0, 277 .amux = 0,
278 }, { 278 }, {
279 .type = EM28XX_VM 279 .type = EM28XX_VMUX_COMPOSITE1,
280 .vmux = SAA7115_C 280 .vmux = SAA7115_COMPOSITE0,
281 .amux = 1, 281 .amux = 1,
282 }, { 282 }, {
283 .type = EM28XX_VM 283 .type = EM28XX_VMUX_SVIDEO,
284 .vmux = SAA7115_S 284 .vmux = SAA7115_SVIDEO3,
285 .amux = 1, 285 .amux = 1,
286 } }, 286 } },
287 }, 287 },
288 [EM2800_BOARD_TERRATEC_CINERGY_200] = 288 [EM2800_BOARD_TERRATEC_CINERGY_200] = {
289 .name = "Terratec Cine 289 .name = "Terratec Cinergy 200 USB",
290 .is_em2800 = 1, 290 .is_em2800 = 1,
291 .vchannels = 3, 291 .vchannels = 3,
292 .tuner_type = TUNER_LG_PAL_N 292 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
293 .tda9887_conf = TDA9887_PRESEN 293 .tda9887_conf = TDA9887_PRESENT,
294 .decoder = EM28XX_SAA7113 294 .decoder = EM28XX_SAA7113,
295 .input = { { 295 .input = { {
296 .type = EM28XX_VMU 296 .type = EM28XX_VMUX_TELEVISION,
297 .vmux = SAA7115_CO 297 .vmux = SAA7115_COMPOSITE2,
298 .amux = 0, 298 .amux = 0,
299 }, { 299 }, {
300 .type = EM28XX_VMU 300 .type = EM28XX_VMUX_COMPOSITE1,
301 .vmux = SAA7115_CO 301 .vmux = SAA7115_COMPOSITE0,
302 .amux = 1, 302 .amux = 1,
303 }, { 303 }, {
304 .type = EM28XX_VMU 304 .type = EM28XX_VMUX_SVIDEO,
305 .vmux = SAA7115_SV 305 .vmux = SAA7115_SVIDEO3,
306 .amux = 1, 306 .amux = 1,
307 } }, 307 } },
308 }, 308 },
309 [EM2800_BOARD_LEADTEK_WINFAST_USBII] = 309 [EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
310 .name = "Leadtek Winfa 310 .name = "Leadtek Winfast USB II",
311 .is_em2800 = 1, 311 .is_em2800 = 1,
312 .vchannels = 3, 312 .vchannels = 3,
313 .tuner_type = TUNER_LG_PAL_N 313 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
314 .tda9887_conf = TDA9887_PRESEN 314 .tda9887_conf = TDA9887_PRESENT,
315 .decoder = EM28XX_SAA7113 315 .decoder = EM28XX_SAA7113,
316 .input = { { 316 .input = { {
317 .type = EM28XX_VMU 317 .type = EM28XX_VMUX_TELEVISION,
318 .vmux = SAA7115_CO 318 .vmux = SAA7115_COMPOSITE2,
319 .amux = 0, 319 .amux = 0,
320 }, { 320 }, {
321 .type = EM28XX_VMU 321 .type = EM28XX_VMUX_COMPOSITE1,
322 .vmux = SAA7115_CO 322 .vmux = SAA7115_COMPOSITE0,
323 .amux = 1, 323 .amux = 1,
324 }, { 324 }, {
325 .type = EM28XX_VMU 325 .type = EM28XX_VMUX_SVIDEO,
326 .vmux = SAA7115_SV 326 .vmux = SAA7115_SVIDEO3,
327 .amux = 1, 327 .amux = 1,
328 } }, 328 } },
329 }, 329 },
330 [EM2800_BOARD_KWORLD_USB2800] = { 330 [EM2800_BOARD_KWORLD_USB2800] = {
331 .name = "Kworld USB280 331 .name = "Kworld USB2800",
332 .is_em2800 = 1, 332 .is_em2800 = 1,
333 .vchannels = 3, 333 .vchannels = 3,
334 .tuner_type = TUNER_PHILIPS_ 334 .tuner_type = TUNER_PHILIPS_ATSC,
335 .tda9887_conf = TDA9887_PRESEN 335 .tda9887_conf = TDA9887_PRESENT,
336 .decoder = EM28XX_SAA7113 336 .decoder = EM28XX_SAA7113,
337 .input = { { 337 .input = { {
338 .type = EM28XX_VMU 338 .type = EM28XX_VMUX_TELEVISION,
339 .vmux = SAA7115_CO 339 .vmux = SAA7115_COMPOSITE2,
340 .amux = 0, 340 .amux = 0,
341 }, { 341 }, {
342 .type = EM28XX_VMU 342 .type = EM28XX_VMUX_COMPOSITE1,
343 .vmux = SAA7115_CO 343 .vmux = SAA7115_COMPOSITE0,
344 .amux = 1, 344 .amux = 1,
345 }, { 345 }, {
346 .type = EM28XX_VMU 346 .type = EM28XX_VMUX_SVIDEO,
347 .vmux = SAA7115_SV 347 .vmux = SAA7115_SVIDEO3,
348 .amux = 1, 348 .amux = 1,
349 } }, 349 } },
350 }, 350 },
351 [EM2820_BOARD_PINNACLE_DVC_90] = { 351 [EM2820_BOARD_PINNACLE_DVC_90] = {
352 .name = "Pinnacle Dazz 352 .name = "Pinnacle Dazzle DVC 90/DVC 100",
353 .vchannels = 3, 353 .vchannels = 3,
354 .tuner_type = TUNER_ABSENT, 354 .tuner_type = TUNER_ABSENT,
355 .decoder = EM28XX_SAA7113 355 .decoder = EM28XX_SAA7113,
356 .input = { { 356 .input = { {
357 .type = EM28XX_VMU 357 .type = EM28XX_VMUX_COMPOSITE1,
358 .vmux = SAA7115_CO 358 .vmux = SAA7115_COMPOSITE0,
359 .amux = 1, 359 .amux = 1,
360 }, { 360 }, {
361 .type = EM28XX_VMU 361 .type = EM28XX_VMUX_SVIDEO,
362 .vmux = SAA7115_SV 362 .vmux = SAA7115_SVIDEO3,
363 .amux = 1, 363 .amux = 1,
364 } }, 364 } },
365 }, 365 },
366 [EM2800_BOARD_VGEAR_POCKETTV] = { 366 [EM2800_BOARD_VGEAR_POCKETTV] = {
367 .name = "V-Gear Pocket 367 .name = "V-Gear PocketTV",
368 .is_em2800 = 1, 368 .is_em2800 = 1,
369 .vchannels = 3, 369 .vchannels = 3,
370 .tuner_type = TUNER_LG_PAL_N 370 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
371 .tda9887_conf = TDA9887_PRESEN 371 .tda9887_conf = TDA9887_PRESENT,
372 .decoder = EM28XX_SAA7113 372 .decoder = EM28XX_SAA7113,
373 .input = { { 373 .input = { {
374 .type = EM28XX_VMU 374 .type = EM28XX_VMUX_TELEVISION,
375 .vmux = SAA7115_CO 375 .vmux = SAA7115_COMPOSITE2,
376 .amux = 0, 376 .amux = 0,
377 }, { 377 }, {
378 .type = EM28XX_VMU 378 .type = EM28XX_VMUX_COMPOSITE1,
379 .vmux = SAA7115_CO 379 .vmux = SAA7115_COMPOSITE0,
380 .amux = 1, 380 .amux = 1,
381 }, { 381 }, {
382 .type = EM28XX_VMU 382 .type = EM28XX_VMUX_SVIDEO,
383 .vmux = SAA7115_SV 383 .vmux = SAA7115_SVIDEO3,
384 .amux = 1, 384 .amux = 1,
385 } }, 385 } },
386 }, 386 },
387 [EM2820_BOARD_PROLINK_PLAYTV_USB2] = { 387 [EM2820_BOARD_PROLINK_PLAYTV_USB2] = {
388 .name = "Pixelview Pro 388 .name = "Pixelview Prolink PlayTV USB 2.0",
389 .vchannels = 3, 389 .vchannels = 3,
390 .tda9887_conf = TDA9887_PRESEN 390 .tda9887_conf = TDA9887_PRESENT,
391 .tuner_type = TUNER_YMEC_TVF 391 .tuner_type = TUNER_YMEC_TVF_5533MF,
392 .decoder = EM28XX_SAA7113 392 .decoder = EM28XX_SAA7113,
393 .input = { { 393 .input = { {
394 .type = EM28XX_VMU 394 .type = EM28XX_VMUX_TELEVISION,
395 .vmux = SAA7115_CO 395 .vmux = SAA7115_COMPOSITE2,
396 .amux = EM28XX_AMU 396 .amux = EM28XX_AMUX_LINE_IN,
397 }, { 397 }, {
398 .type = EM28XX_VMU 398 .type = EM28XX_VMUX_COMPOSITE1,
399 .vmux = SAA7115_CO 399 .vmux = SAA7115_COMPOSITE0,
400 .amux = EM28XX_AMU 400 .amux = EM28XX_AMUX_LINE_IN,
401 }, { 401 }, {
402 .type = EM28XX_VMU 402 .type = EM28XX_VMUX_SVIDEO,
403 .vmux = SAA7115_SV 403 .vmux = SAA7115_SVIDEO3,
404 .amux = EM28XX_AMU 404 .amux = EM28XX_AMUX_LINE_IN,
405 } }, 405 } },
406 }, 406 },
407 }; 407 };
408 const unsigned int em28xx_bcount = ARRAY_SIZE( 408 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
409 409
410 /* table of devices that work with this driver 410 /* table of devices that work with this driver */
411 struct usb_device_id em28xx_id_table [] = { 411 struct usb_device_id em28xx_id_table [] = {
412 { USB_DEVICE(0xeb1a, 0x2750), 412 { USB_DEVICE(0xeb1a, 0x2750),
413 .driver_info = EM2820_ 413 .driver_info = EM2820_BOARD_UNKNOWN },
414 { USB_DEVICE(0xeb1a, 0x2800), 414 { USB_DEVICE(0xeb1a, 0x2800),
415 .driver_info = EM2800_ 415 .driver_info = EM2800_BOARD_UNKNOWN },
416 { USB_DEVICE(0xeb1a, 0x2820), 416 { USB_DEVICE(0xeb1a, 0x2820),
417 .driver_info = EM2820_ 417 .driver_info = EM2820_BOARD_UNKNOWN },
418 { USB_DEVICE(0xeb1a, 0x2821), 418 { USB_DEVICE(0xeb1a, 0x2821),
419 .driver_info = EM2820_ 419 .driver_info = EM2820_BOARD_UNKNOWN },
420 { USB_DEVICE(0xeb1a, 0x2860), 420 { USB_DEVICE(0xeb1a, 0x2860),
421 .driver_info = EM2820_ 421 .driver_info = EM2820_BOARD_UNKNOWN },
422 { USB_DEVICE(0xeb1a, 0x2861), 422 { USB_DEVICE(0xeb1a, 0x2861),
423 .driver_info = EM2820_ 423 .driver_info = EM2820_BOARD_UNKNOWN },
424 { USB_DEVICE(0xeb1a, 0x2870), 424 { USB_DEVICE(0xeb1a, 0x2870),
425 .driver_info = EM2820_ 425 .driver_info = EM2820_BOARD_UNKNOWN },
426 { USB_DEVICE(0xeb1a, 0x2881), 426 { USB_DEVICE(0xeb1a, 0x2881),
427 .driver_info = EM2820_ 427 .driver_info = EM2820_BOARD_UNKNOWN },
428 { USB_DEVICE(0xeb1a, 0x2883), 428 { USB_DEVICE(0xeb1a, 0x2883),
429 .driver_info = EM2820_ 429 .driver_info = EM2820_BOARD_UNKNOWN },
430 { USB_DEVICE(0x0ccd, 0x0036), 430 { USB_DEVICE(0x0ccd, 0x0036),
431 .driver_info = EM2820_ 431 .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
432 { USB_DEVICE(0x2304, 0x0208), 432 { USB_DEVICE(0x2304, 0x0208),
433 .driver_info = EM2820_ 433 .driver_info = EM2820_BOARD_PINNACLE_USB_2 },
434 { USB_DEVICE(0x2040, 0x4200), 434 { USB_DEVICE(0x2040, 0x4200),
435 .driver_info = EM2820_ 435 .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
436 { USB_DEVICE(0x2040, 0x4201), 436 { USB_DEVICE(0x2040, 0x4201),
437 .driver_info = EM2820_ 437 .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
438 { USB_DEVICE(0x2304, 0x0207), 438 { USB_DEVICE(0x2304, 0x0207),
439 .driver_info = EM2820_ 439 .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
440 { USB_DEVICE(0x2304, 0x021a), 440 { USB_DEVICE(0x2304, 0x021a),
441 .driver_info = EM2820_ 441 .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
442 { USB_DEVICE(0x2040, 0x6500), 442 { USB_DEVICE(0x2040, 0x6500),
443 .driver_info = EM2880_ 443 .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
444 { USB_DEVICE(0x2040, 0x6502), 444 { USB_DEVICE(0x2040, 0x6502),
445 .driver_info = EM2880_ 445 .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
446 { USB_DEVICE(0x2040, 0x6513), 446 { USB_DEVICE(0x2040, 0x6513),
447 .driver_info = EM2880_ 447 .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
448 { USB_DEVICE(0x0ccd, 0x0042), 448 { USB_DEVICE(0x0ccd, 0x0042),
449 .driver_info = EM2880_ 449 .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
450 { USB_DEVICE(0x0ccd, 0x0047), 450 { USB_DEVICE(0x0ccd, 0x0047),
451 .driver_info = EM2880_ 451 .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS },
452 { }, 452 { },
453 }; 453 };
454 MODULE_DEVICE_TABLE(usb, em28xx_id_table); 454 MODULE_DEVICE_TABLE(usb, em28xx_id_table);
455 455
456 /* EEPROM hash table for devices with generic 456 /* EEPROM hash table for devices with generic USB IDs */
457 static struct em28xx_hash_table em28xx_eeprom_ 457 static struct em28xx_hash_table em28xx_eeprom_hash [] = {
458 /* P/N: SA 60002070465 Tuner: TVF7533- 458 /* P/N: SA 60002070465 Tuner: TVF7533-MF */
459 {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAY 459 {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
460 }; 460 };
461 461
462 /* I2C devicelist hash table for devices with 462 /* I2C devicelist hash table for devices with generic USB IDs */
463 static struct em28xx_hash_table em28xx_i2c_has 463 static struct em28xx_hash_table em28xx_i2c_hash[] = {
464 {0xb06a32c3, EM2800_BOARD_TERRATEC_CIN 464 {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
465 {0xf51200e3, EM2800_BOARD_VGEAR_POCKET 465 {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
466 }; 466 };
467 467
468 /* Since em28xx_pre_card_setup() requires a pr 468 /* Since em28xx_pre_card_setup() requires a proper dev->model,
469 * this won't work for boards with generic PCI 469 * this won't work for boards with generic PCI IDs
470 */ 470 */
471 void em28xx_pre_card_setup(struct em28xx *dev) 471 void em28xx_pre_card_setup(struct em28xx *dev)
472 { 472 {
473 /* request some modules */ 473 /* request some modules */
474 switch (dev->model) { 474 switch (dev->model) {
475 case EM2880_BOARD_TERRATEC_PRODIGY_XS: 475 case EM2880_BOARD_TERRATEC_PRODIGY_XS:
476 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_ 476 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
477 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_ 477 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
478 case EM2880_BOARD_TERRATEC_HYBRID_XS: 478 case EM2880_BOARD_TERRATEC_HYBRID_XS:
479 em28xx_write_regs(dev, XCLK_RE 479 em28xx_write_regs(dev, XCLK_REG, "\x27", 1);
480 em28xx_write_regs(dev, I2C_CLK 480 em28xx_write_regs(dev, I2C_CLK_REG, "\x40", 1);
481 em28xx_write_regs(dev, 0x08, " 481 em28xx_write_regs(dev, 0x08, "\xff", 1);
482 em28xx_write_regs(dev, 0x04, " 482 em28xx_write_regs(dev, 0x04, "\x00", 1);
483 msleep(100); 483 msleep(100);
484 em28xx_write_regs(dev, 0x04, " 484 em28xx_write_regs(dev, 0x04, "\x08", 1);
485 msleep(100); 485 msleep(100);
486 em28xx_write_regs(dev, 0x08, " 486 em28xx_write_regs(dev, 0x08, "\xff", 1);
487 msleep(50); 487 msleep(50);
488 em28xx_write_regs(dev, 0x08, " 488 em28xx_write_regs(dev, 0x08, "\x2d", 1);
489 msleep(50); 489 msleep(50);
490 em28xx_write_regs(dev, 0x08, " 490 em28xx_write_regs(dev, 0x08, "\x3d", 1);
491 break; 491 break;
492 } 492 }
493 } 493 }
494 494
495 static int em28xx_tuner_callback(void *ptr, in 495 static int em28xx_tuner_callback(void *ptr, int command, int arg)
496 { 496 {
497 int rc = 0; 497 int rc = 0;
498 struct em28xx *dev = ptr; 498 struct em28xx *dev = ptr;
499 499
500 if (dev->tuner_type != TUNER_XC2028) 500 if (dev->tuner_type != TUNER_XC2028)
501 return 0; 501 return 0;
502 502
503 switch (command) { 503 switch (command) {
504 case XC2028_TUNER_RESET: 504 case XC2028_TUNER_RESET:
505 { 505 {
506 /* GPIO and initialization cod 506 /* GPIO and initialization codes for analog TV and radio
507 This code should be complem 507 This code should be complemented for DTV, since reset
508 codes are different. 508 codes are different.
509 */ 509 */
510 510
511 dev->em28xx_write_regs_req(dev 511 dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1);
512 dev->em28xx_write_regs_req(dev 512 dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1);
513 513
514 if (dev->analog_gpio) { 514 if (dev->analog_gpio) {
515 char gpio0 = dev->anal 515 char gpio0 = dev->analog_gpio & 0xff;
516 char gpio1 = (dev->ana 516 char gpio1 = (dev->analog_gpio >> 8) & 0xff;
517 char gpio4 = dev->anal 517 char gpio4 = dev->analog_gpio >> 24;
518 518
519 if (gpio4) { 519 if (gpio4) {
520 dev->em28xx_wr 520 dev->em28xx_write_regs(dev, 0x04, &gpio4, 1);
521 msleep(140); 521 msleep(140);
522 } 522 }
523 523
524 msleep(6); 524 msleep(6);
525 dev->em28xx_write_regs 525 dev->em28xx_write_regs(dev, 0x08, &gpio0, 1);
526 msleep(10); 526 msleep(10);
527 dev->em28xx_write_regs 527 dev->em28xx_write_regs(dev, 0x08, &gpio1, 1);
528 msleep(5); 528 msleep(5);
529 } 529 }
530 530
531 break; 531 break;
532 } 532 }
533 } 533 }
534 return rc; 534 return rc;
535 } 535 }
536 536
537 static void em28xx_config_tuner(struct em28xx 537 static void em28xx_config_tuner(struct em28xx *dev)
538 { 538 {
539 struct v4l2_priv_tun_config xc2028_cf 539 struct v4l2_priv_tun_config xc2028_cfg;
540 struct xc2028_ctrl ctl; 540 struct xc2028_ctrl ctl;
541 struct tuner_setup tun_setup 541 struct tuner_setup tun_setup;
542 struct v4l2_frequency f; 542 struct v4l2_frequency f;
543 543
544 if (dev->tuner_type == TUNER_ABSENT) 544 if (dev->tuner_type == TUNER_ABSENT)
545 return; 545 return;
546 546
547 tun_setup.mode_mask = T_ANALOG_TV | T_ 547 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
548 tun_setup.type = dev->tuner_type; 548 tun_setup.type = dev->tuner_type;
549 tun_setup.addr = dev->tuner_addr; 549 tun_setup.addr = dev->tuner_addr;
550 tun_setup.tuner_callback = em28xx_tune 550 tun_setup.tuner_callback = em28xx_tuner_callback;
551 551
552 em28xx_i2c_call_clients(dev, TUNER_SET 552 em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
553 553
554 if (dev->tuner_type == TUNER_XC2028) { 554 if (dev->tuner_type == TUNER_XC2028) {
555 memset(&ctl, 0, sizeof(ctl)); 555 memset(&ctl, 0, sizeof(ctl));
556 556
557 ctl.fname = XC2028_DEFAULT_F 557 ctl.fname = XC2028_DEFAULT_FIRMWARE;
558 ctl.max_len = 64; 558 ctl.max_len = 64;
559 ctl.mts = em28xx_boards[dev->m 559 ctl.mts = em28xx_boards[dev->model].mts_firmware;
560 560
561 xc2028_cfg.tuner = TUNER_XC202 561 xc2028_cfg.tuner = TUNER_XC2028;
562 xc2028_cfg.priv = &ctl; 562 xc2028_cfg.priv = &ctl;
563 563
564 em28xx_i2c_call_clients(dev, T 564 em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
565 } 565 }
566 566
567 /* configure tuner */ 567 /* configure tuner */
568 f.tuner = 0; 568 f.tuner = 0;
569 f.type = V4L2_TUNER_ANALOG_TV; 569 f.type = V4L2_TUNER_ANALOG_TV;
570 f.frequency = 9076; /* just a magi 570 f.frequency = 9076; /* just a magic number */
571 dev->ctl_freq = f.frequency; 571 dev->ctl_freq = f.frequency;
572 em28xx_i2c_call_clients(dev, VIDIOC_S_ 572 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
573 } 573 }
574 574
575 static int em28xx_hint_board(struct em28xx *de 575 static int em28xx_hint_board(struct em28xx *dev)
576 { 576 {
577 int i; 577 int i;
578 578
579 /* HINT method: EEPROM 579 /* HINT method: EEPROM
580 * 580 *
581 * This method works only for boards w 581 * This method works only for boards with eeprom.
582 * Uses a hash of all eeprom bytes. Th 582 * Uses a hash of all eeprom bytes. The hash should be
583 * unique for a vendor/tuner pair. 583 * unique for a vendor/tuner pair.
584 * There are a high chance that tuners 584 * There are a high chance that tuners for different
585 * video standards produce different h 585 * video standards produce different hashes.
586 */ 586 */
587 for (i = 0; i < ARRAY_SIZE(em28xx_eepr 587 for (i = 0; i < ARRAY_SIZE(em28xx_eeprom_hash); i++) {
588 if (dev->hash == em28xx_eeprom 588 if (dev->hash == em28xx_eeprom_hash[i].hash) {
589 dev->model = em28xx_ee 589 dev->model = em28xx_eeprom_hash[i].model;
590 dev->tuner_type = em28 590 dev->tuner_type = em28xx_eeprom_hash[i].tuner;
591 591
592 em28xx_errdev("Your bo 592 em28xx_errdev("Your board has no unique USB ID.\n");
593 em28xx_errdev("A hint 593 em28xx_errdev("A hint were successfully done, "
594 "based o 594 "based on eeprom hash.\n");
595 em28xx_errdev("This me 595 em28xx_errdev("This method is not 100%% failproof.\n");
596 em28xx_errdev("If the 596 em28xx_errdev("If the board were missdetected, "
597 "please 597 "please email this log to:\n");
598 em28xx_errdev("\tV4L M 598 em28xx_errdev("\tV4L Mailing List "
599 " <video 599 " <video4linux-list@redhat.com>\n");
600 em28xx_errdev("Board d 600 em28xx_errdev("Board detected as %s\n",
601 em28xx_b 601 em28xx_boards[dev->model].name);
602 602
603 return 0; 603 return 0;
604 } 604 }
605 } 605 }
606 606
607 /* HINT method: I2C attached devices 607 /* HINT method: I2C attached devices
608 * 608 *
609 * This method works for all boards. 609 * This method works for all boards.
610 * Uses a hash of i2c scanned devices. 610 * Uses a hash of i2c scanned devices.
611 * Devices with the same i2c attached 611 * Devices with the same i2c attached chips will
612 * be considered equal. 612 * be considered equal.
613 * This method is less precise than th 613 * This method is less precise than the eeprom one.
614 */ 614 */
615 615
616 /* user did not request i2c scanning = 616 /* user did not request i2c scanning => do it now */
617 if (!dev->i2c_hash) 617 if (!dev->i2c_hash)
618 em28xx_do_i2c_scan(dev); 618 em28xx_do_i2c_scan(dev);
619 619
620 for (i = 0; i < ARRAY_SIZE(em28xx_i2c_ 620 for (i = 0; i < ARRAY_SIZE(em28xx_i2c_hash); i++) {
621 if (dev->i2c_hash == em28xx_i2 621 if (dev->i2c_hash == em28xx_i2c_hash[i].hash) {
622 dev->model = em28xx_i2 622 dev->model = em28xx_i2c_hash[i].model;
623 dev->tuner_type = em28 623 dev->tuner_type = em28xx_i2c_hash[i].tuner;
624 em28xx_errdev("Your bo 624 em28xx_errdev("Your board has no unique USB ID.\n");
625 em28xx_errdev("A hint 625 em28xx_errdev("A hint were successfully done, "
626 "based o 626 "based on i2c devicelist hash.\n");
627 em28xx_errdev("This me 627 em28xx_errdev("This method is not 100%% failproof.\n");
628 em28xx_errdev("If the 628 em28xx_errdev("If the board were missdetected, "
629 "please 629 "please email this log to:\n");
630 em28xx_errdev("\tV4L M 630 em28xx_errdev("\tV4L Mailing List "
631 " <video 631 " <video4linux-list@redhat.com>\n");
632 em28xx_errdev("Board d 632 em28xx_errdev("Board detected as %s\n",
633 em28xx_b 633 em28xx_boards[dev->model].name);
634 634
635 return 0; 635 return 0;
636 } 636 }
637 } 637 }
638 638
639 em28xx_errdev("Your board has no uniqu 639 em28xx_errdev("Your board has no unique USB ID and thus need a "
640 "hint to be detected.\n" 640 "hint to be detected.\n");
641 em28xx_errdev("You may try to use card 641 em28xx_errdev("You may try to use card=<n> insmod option to "
642 "workaround that.\n"); 642 "workaround that.\n");
643 em28xx_errdev("Please send an email wi 643 em28xx_errdev("Please send an email with this log to:\n");
644 em28xx_errdev("\tV4L Mailing List <vid 644 em28xx_errdev("\tV4L Mailing List <video4linux-list@redhat.com>\n");
645 em28xx_errdev("Board eeprom hash is 0x 645 em28xx_errdev("Board eeprom hash is 0x%08lx\n", dev->hash);
646 em28xx_errdev("Board i2c devicelist ha 646 em28xx_errdev("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash);
647 647
648 em28xx_errdev("Here is a list of valid 648 em28xx_errdev("Here is a list of valid choices for the card=<n>"
649 " insmod option:\n"); 649 " insmod option:\n");
650 for (i = 0; i < em28xx_bcount; i++) { 650 for (i = 0; i < em28xx_bcount; i++) {
651 em28xx_errdev(" card=%d -> 651 em28xx_errdev(" card=%d -> %s\n",
652 i, em28xx_boar 652 i, em28xx_boards[i].name);
653 } 653 }
654 return -1; 654 return -1;
655 } 655 }
656 656
657 657
658 static void em28xx_set_model(struct em28xx *de 658 static void em28xx_set_model(struct em28xx *dev)
659 { 659 {
660 dev->is_em2800 = em28xx_boards[dev->mo 660 dev->is_em2800 = em28xx_boards[dev->model].is_em2800;
661 dev->has_msp34xx = em28xx_boards[dev-> 661 dev->has_msp34xx = em28xx_boards[dev->model].has_msp34xx;
662 dev->tda9887_conf = em28xx_boards[dev- 662 dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf;
663 dev->decoder = em28xx_boards[dev->mode 663 dev->decoder = em28xx_boards[dev->model].decoder;
664 dev->video_inputs = em28xx_boards[dev- 664 dev->video_inputs = em28xx_boards[dev->model].vchannels;
665 dev->analog_gpio = em28xx_boards[dev-> 665 dev->analog_gpio = em28xx_boards[dev->model].analog_gpio;
666 dev->has_12mhz_i2s = em28xx_boards[dev 666 dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s;
667 dev->max_range_640_480 = em28xx_boards 667 dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480;
668 } 668 }
669 669
670 /* ------------------------------------------- 670 /* ----------------------------------------------------------------------- */
671 void em28xx_set_ir(struct em28xx *dev, struct 671 void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
672 { 672 {
673 if (disable_ir) { 673 if (disable_ir) {
674 ir->get_key = NULL; 674 ir->get_key = NULL;
675 return ; 675 return ;
676 } 676 }
677 677
678 /* detect & configure */ 678 /* detect & configure */
679 switch (dev->model) { 679 switch (dev->model) {
680 case (EM2800_BOARD_UNKNOWN): 680 case (EM2800_BOARD_UNKNOWN):
681 break; 681 break;
682 case (EM2820_BOARD_UNKNOWN): 682 case (EM2820_BOARD_UNKNOWN):
683 break; 683 break;
684 case (EM2800_BOARD_TERRATEC_CINERGY_20 684 case (EM2800_BOARD_TERRATEC_CINERGY_200):
685 case (EM2820_BOARD_TERRATEC_CINERGY_25 685 case (EM2820_BOARD_TERRATEC_CINERGY_250):
686 ir->ir_codes = ir_codes_em_ter 686 ir->ir_codes = ir_codes_em_terratec;
687 ir->get_key = em28xx_get_key_t 687 ir->get_key = em28xx_get_key_terratec;
688 snprintf(ir->c.name, sizeof(ir 688 snprintf(ir->c.name, sizeof(ir->c.name),
689 "i2c IR (EM28XX Terra 689 "i2c IR (EM28XX Terratec)");
690 break; 690 break;
691 case (EM2820_BOARD_PINNACLE_USB_2): 691 case (EM2820_BOARD_PINNACLE_USB_2):
692 ir->ir_codes = ir_codes_pinnac 692 ir->ir_codes = ir_codes_pinnacle_grey;
693 ir->get_key = em28xx_get_key_p 693 ir->get_key = em28xx_get_key_pinnacle_usb_grey;
694 snprintf(ir->c.name, sizeof(ir 694 snprintf(ir->c.name, sizeof(ir->c.name),
695 "i2c IR (EM28XX Pinna 695 "i2c IR (EM28XX Pinnacle PCTV)");
696 break; 696 break;
697 case (EM2820_BOARD_HAUPPAUGE_WINTV_USB 697 case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
698 ir->ir_codes = ir_codes_hauppa 698 ir->ir_codes = ir_codes_hauppauge_new;
699 ir->get_key = em28xx_get_key_e 699 ir->get_key = em28xx_get_key_em_haup;
700 snprintf(ir->c.name, sizeof(ir 700 snprintf(ir->c.name, sizeof(ir->c.name),
701 "i2c IR (EM2840 Haupp 701 "i2c IR (EM2840 Hauppauge)");
702 break; 702 break;
703 case (EM2820_BOARD_MSI_VOX_USB_2): 703 case (EM2820_BOARD_MSI_VOX_USB_2):
704 break; 704 break;
705 case (EM2800_BOARD_LEADTEK_WINFAST_USB 705 case (EM2800_BOARD_LEADTEK_WINFAST_USBII):
706 break; 706 break;
707 case (EM2800_BOARD_KWORLD_USB2800): 707 case (EM2800_BOARD_KWORLD_USB2800):
708 break; 708 break;
709 } 709 }
710 } 710 }
711 711
712 void em28xx_card_setup(struct em28xx *dev) 712 void em28xx_card_setup(struct em28xx *dev)
713 { 713 {
714 em28xx_set_model(dev); 714 em28xx_set_model(dev);
715 715
716 dev->tuner_type = em28xx_boards[dev->m 716 dev->tuner_type = em28xx_boards[dev->model].tuner_type;
717 717
718 /* request some modules */ 718 /* request some modules */
719 switch (dev->model) { 719 switch (dev->model) {
720 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_ 720 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
721 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_ 721 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
722 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_ 722 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
723 { 723 {
724 struct tveeprom tv; 724 struct tveeprom tv;
725 #ifdef CONFIG_MODULES 725 #ifdef CONFIG_MODULES
726 request_module("tveeprom"); 726 request_module("tveeprom");
727 #endif 727 #endif
728 /* Call first TVeeprom */ 728 /* Call first TVeeprom */
729 729
730 dev->i2c_client.addr = 0xa0 >> 730 dev->i2c_client.addr = 0xa0 >> 1;
731 tveeprom_hauppauge_analog(&dev 731 tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata);
732 732
733 dev->tuner_type = tv.tuner_typ 733 dev->tuner_type = tv.tuner_type;
734 734
735 if (tv.audio_processor == AUDI 735 if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
736 dev->i2s_speed = 20480 736 dev->i2s_speed = 2048000;
737 dev->has_msp34xx = 1; 737 dev->has_msp34xx = 1;
738 } 738 }
739 #ifdef CONFIG_MODULES 739 #ifdef CONFIG_MODULES
740 if (tv.has_ir) 740 if (tv.has_ir)
741 request_module("ir-kbd 741 request_module("ir-kbd-i2c");
742 #endif 742 #endif
743 break; 743 break;
744 } 744 }
745 case EM2820_BOARD_KWORLD_PVRTV2800RF: 745 case EM2820_BOARD_KWORLD_PVRTV2800RF:
746 /* GPIO enables sound on KWORL 746 /* GPIO enables sound on KWORLD PVR TV 2800RF */
747 em28xx_write_regs_req(dev, 0x0 747 em28xx_write_regs_req(dev, 0x00, 0x08, "\xf9", 1);
748 break; 748 break;
749 case EM2820_BOARD_UNKNOWN: 749 case EM2820_BOARD_UNKNOWN:
750 case EM2800_BOARD_UNKNOWN: 750 case EM2800_BOARD_UNKNOWN:
751 if (!em28xx_hint_board(dev)) 751 if (!em28xx_hint_board(dev))
752 em28xx_set_model(dev); 752 em28xx_set_model(dev);
753 } 753 }
754 754
755 /* Allow override tuner type by a modu 755 /* Allow override tuner type by a module parameter */
756 if (tuner >= 0) 756 if (tuner >= 0)
757 dev->tuner_type = tuner; 757 dev->tuner_type = tuner;
758 758
759 #ifdef CONFIG_MODULES 759 #ifdef CONFIG_MODULES
760 /* request some modules */ 760 /* request some modules */
761 if (dev->has_msp34xx) 761 if (dev->has_msp34xx)
762 request_module("msp3400"); 762 request_module("msp3400");
763 if (dev->decoder == EM28XX_SAA7113 || 763 if (dev->decoder == EM28XX_SAA7113 || dev->decoder == EM28XX_SAA7114)
764 request_module("saa7115"); 764 request_module("saa7115");
765 if (dev->decoder == EM28XX_TVP5150) 765 if (dev->decoder == EM28XX_TVP5150)
766 request_module("tvp5150"); 766 request_module("tvp5150");
767 if (dev->tuner_type != TUNER_ABSENT) 767 if (dev->tuner_type != TUNER_ABSENT)
768 request_module("tuner"); 768 request_module("tuner");
769 #endif 769 #endif
770 770
771 em28xx_config_tuner(dev); 771 em28xx_config_tuner(dev);
772 } 772 }
773 773
|
This page was automatically generated by the
LXR engine.
|