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