162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
262306a36Sopenharmony_ci//
362306a36Sopenharmony_ci// em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB
462306a36Sopenharmony_ci//		    video capture devices
562306a36Sopenharmony_ci//
662306a36Sopenharmony_ci// Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
762306a36Sopenharmony_ci//		      Markus Rechberger <mrechberger@gmail.com>
862306a36Sopenharmony_ci//		      Mauro Carvalho Chehab <mchehab@kernel.org>
962306a36Sopenharmony_ci//		      Sascha Sommer <saschasommer@freenet.de>
1062306a36Sopenharmony_ci// Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include "em28xx.h"
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/init.h>
1562306a36Sopenharmony_ci#include <linux/module.h>
1662306a36Sopenharmony_ci#include <linux/slab.h>
1762306a36Sopenharmony_ci#include <linux/delay.h>
1862306a36Sopenharmony_ci#include <linux/i2c.h>
1962306a36Sopenharmony_ci#include <linux/usb.h>
2062306a36Sopenharmony_ci#include <media/tuner.h>
2162306a36Sopenharmony_ci#include <media/drv-intf/msp3400.h>
2262306a36Sopenharmony_ci#include <media/i2c/saa7115.h>
2362306a36Sopenharmony_ci#include <dt-bindings/media/tvp5150.h>
2462306a36Sopenharmony_ci#include <media/i2c/tvaudio.h>
2562306a36Sopenharmony_ci#include <media/tveeprom.h>
2662306a36Sopenharmony_ci#include <media/v4l2-common.h>
2762306a36Sopenharmony_ci#include <sound/ac97_codec.h>
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#define DRIVER_NAME         "em28xx"
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cistatic int tuner = -1;
3262306a36Sopenharmony_cimodule_param(tuner, int, 0444);
3362306a36Sopenharmony_ciMODULE_PARM_DESC(tuner, "tuner type");
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistatic unsigned int disable_ir;
3662306a36Sopenharmony_cimodule_param(disable_ir, int, 0444);
3762306a36Sopenharmony_ciMODULE_PARM_DESC(disable_ir, "disable infrared remote support");
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_cistatic unsigned int disable_usb_speed_check;
4062306a36Sopenharmony_cimodule_param(disable_usb_speed_check, int, 0444);
4162306a36Sopenharmony_ciMODULE_PARM_DESC(disable_usb_speed_check,
4262306a36Sopenharmony_ci		 "override min bandwidth requirement of 480M bps");
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cistatic unsigned int card[]     = {[0 ... (EM28XX_MAXBOARDS - 1)] = -1U };
4562306a36Sopenharmony_cimodule_param_array(card,  int, NULL, 0444);
4662306a36Sopenharmony_ciMODULE_PARM_DESC(card,     "card type");
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_cistatic int usb_xfer_mode = -1;
4962306a36Sopenharmony_cimodule_param(usb_xfer_mode, int, 0444);
5062306a36Sopenharmony_ciMODULE_PARM_DESC(usb_xfer_mode,
5162306a36Sopenharmony_ci		 "USB transfer mode for frame data (-1 = auto, 0 = prefer isoc, 1 = prefer bulk)");
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS - 1 */
5462306a36Sopenharmony_cistatic DECLARE_BITMAP(em28xx_devused, EM28XX_MAXBOARDS);
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_cistruct em28xx_hash_table {
5762306a36Sopenharmony_ci	unsigned long hash;
5862306a36Sopenharmony_ci	unsigned int  model;
5962306a36Sopenharmony_ci	unsigned int  tuner;
6062306a36Sopenharmony_ci};
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_cistatic void em28xx_pre_card_setup(struct em28xx *dev);
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci/*
6562306a36Sopenharmony_ci *  Reset sequences for analog/digital modes
6662306a36Sopenharmony_ci */
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci/* Reset for the most [analog] boards */
6962306a36Sopenharmony_cistatic const struct em28xx_reg_seq default_analog[] = {
7062306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6d,   ~EM_GPIO_4,	10},
7162306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
7262306a36Sopenharmony_ci};
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci/* Reset for the most [digital] boards */
7562306a36Sopenharmony_cistatic const struct em28xx_reg_seq default_digital[] = {
7662306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
7762306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
7862306a36Sopenharmony_ci};
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci/* Board :Zolid Hybrid Tv Stick */
8162306a36Sopenharmony_cistatic struct em28xx_reg_seq zolid_tuner[] = {
8262306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,		0xfd,		0xff,	100},
8362306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,		0xfe,		0xff,	100},
8462306a36Sopenharmony_ci	{		-1,					-1,			-1,		 -1},
8562306a36Sopenharmony_ci};
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_cistatic struct em28xx_reg_seq zolid_digital[] = {
8862306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,		0x6a,		0xff,	100},
8962306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,		0x7a,		0xff,	100},
9062306a36Sopenharmony_ci	{EM2880_R04_GPO,			0x04,		0xff,	100},
9162306a36Sopenharmony_ci	{EM2880_R04_GPO,			0x0c,		0xff,	100},
9262306a36Sopenharmony_ci	{	-1,						-1,			-1,		 -1},
9362306a36Sopenharmony_ci};
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci/* Board Hauppauge WinTV HVR 900 analog */
9662306a36Sopenharmony_cistatic const struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
9762306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x2d,	~EM_GPIO_4,	10},
9862306a36Sopenharmony_ci	{	0x05,		0xff,	0x10,		10},
9962306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
10062306a36Sopenharmony_ci};
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci/* Board Hauppauge WinTV HVR 900 digital */
10362306a36Sopenharmony_cistatic const struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
10462306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x2e,	~EM_GPIO_4,	10},
10562306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x04,	0x0f,		10},
10662306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x0c,	0x0f,		10},
10762306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
10862306a36Sopenharmony_ci};
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci/* Board Hauppauge WinTV HVR 900 (R2) digital */
11162306a36Sopenharmony_cistatic const struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = {
11262306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x2e,	~EM_GPIO_4,	10},
11362306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x0c,	0x0f,		10},
11462306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
11562306a36Sopenharmony_ci};
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
11862306a36Sopenharmony_cistatic const struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
11962306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x69,   ~EM_GPIO_4,	10},
12062306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
12162306a36Sopenharmony_ci};
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci/* Board - EM2882 Kworld 315U digital */
12462306a36Sopenharmony_cistatic const struct em28xx_reg_seq em2882_kworld_315u_digital[] = {
12562306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
12662306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xfe,	0xff,		10},
12762306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x04,	0xff,		10},
12862306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x0c,	0xff,		10},
12962306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x7e,	0xff,		10},
13062306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
13162306a36Sopenharmony_ci};
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_cistatic const struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = {
13462306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x08,	0xff,		10},
13562306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x0c,	0xff,		10},
13662306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x08,	0xff,		10},
13762306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x0c,	0xff,		10},
13862306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
13962306a36Sopenharmony_ci};
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_cistatic const struct em28xx_reg_seq kworld_330u_analog[] = {
14262306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6d,	~EM_GPIO_4,	10},
14362306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x00,	0xff,		10},
14462306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
14562306a36Sopenharmony_ci};
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_cistatic const struct em28xx_reg_seq kworld_330u_digital[] = {
14862306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
14962306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x08,	0xff,		10},
15062306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
15162306a36Sopenharmony_ci};
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci/*
15462306a36Sopenharmony_ci * Evga inDtube
15562306a36Sopenharmony_ci * GPIO0 - Enable digital power (s5h1409) - low to enable
15662306a36Sopenharmony_ci * GPIO1 - Enable analog power (tvp5150/emp202) - low to enable
15762306a36Sopenharmony_ci * GPIO4 - xc3028 reset
15862306a36Sopenharmony_ci * GOP3  - s5h1409 reset
15962306a36Sopenharmony_ci */
16062306a36Sopenharmony_cistatic const struct em28xx_reg_seq evga_indtube_analog[] = {
16162306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x79,   0xff,		60},
16262306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
16362306a36Sopenharmony_ci};
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_cistatic const struct em28xx_reg_seq evga_indtube_digital[] = {
16662306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x7a,	0xff,		 1},
16762306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x04,	0xff,		10},
16862306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x0c,	0xff,		 1},
16962306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
17062306a36Sopenharmony_ci};
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci/*
17362306a36Sopenharmony_ci * KWorld PlusTV 340U, UB435-Q and UB435-Q V2 (ATSC) GPIOs map:
17462306a36Sopenharmony_ci * EM_GPIO_0 - currently unknown
17562306a36Sopenharmony_ci * EM_GPIO_1 - LED disable/enable (1 = off, 0 = on)
17662306a36Sopenharmony_ci * EM_GPIO_2 - currently unknown
17762306a36Sopenharmony_ci * EM_GPIO_3 - currently unknown
17862306a36Sopenharmony_ci * EM_GPIO_4 - TDA18271HD/C1 tuner (1 = active, 0 = in reset)
17962306a36Sopenharmony_ci * EM_GPIO_5 - LGDT3304 ATSC/QAM demod (1 = active, 0 = in reset)
18062306a36Sopenharmony_ci * EM_GPIO_6 - currently unknown
18162306a36Sopenharmony_ci * EM_GPIO_7 - currently unknown
18262306a36Sopenharmony_ci */
18362306a36Sopenharmony_cistatic const struct em28xx_reg_seq kworld_a340_digital[] = {
18462306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6d,	~EM_GPIO_4,	10},
18562306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
18662306a36Sopenharmony_ci};
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_cistatic const struct em28xx_reg_seq kworld_ub435q_v3_digital[] = {
18962306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	100},
19062306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfe,	0xff,	100},
19162306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xbe,	0xff,	100},
19262306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfe,	0xff,	100},
19362306a36Sopenharmony_ci	{	-1,			-1,	-1,	-1},
19462306a36Sopenharmony_ci};
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci/* Pinnacle Hybrid Pro eb1a:2881 */
19762306a36Sopenharmony_cistatic const struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = {
19862306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xfd,   ~EM_GPIO_4,	10},
19962306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
20062306a36Sopenharmony_ci};
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_cistatic const struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = {
20362306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
20462306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x04,	0xff,	       100},/* zl10353 reset */
20562306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x0c,	0xff,		 1},
20662306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
20762306a36Sopenharmony_ci};
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_cistatic const struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_analog[] = {
21062306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6d,	~EM_GPIO_4,	10},
21162306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x00,	0xff,		10},
21262306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
21362306a36Sopenharmony_ci};
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_cistatic const struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = {
21662306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
21762306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x08,	0xff,		10},
21862306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
21962306a36Sopenharmony_ci};
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci/*
22262306a36Sopenharmony_ci * PCTV HD Mini (80e) GPIOs
22362306a36Sopenharmony_ci * 0-5: not used
22462306a36Sopenharmony_ci * 6:   demod reset, active low
22562306a36Sopenharmony_ci * 7:   LED on, active high
22662306a36Sopenharmony_ci */
22762306a36Sopenharmony_cistatic const struct em28xx_reg_seq em2874_pctv_80e_digital[] = {
22862306a36Sopenharmony_ci	{EM28XX_R06_I2C_CLK,    0x45,   0xff,		  10}, /*400 KHz*/
22962306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL, 0x00,   0xff,		  100},/*Demod reset*/
23062306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL, 0x40,   0xff,		  10},
23162306a36Sopenharmony_ci	{  -1,			-1,	-1,		  -1},
23262306a36Sopenharmony_ci};
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci/*
23562306a36Sopenharmony_ci * eb1a:2868 Reddo DVB-C USB TV Box
23662306a36Sopenharmony_ci * GPIO4 - CU1216L NIM
23762306a36Sopenharmony_ci * Other GPIOs seems to be don't care.
23862306a36Sopenharmony_ci */
23962306a36Sopenharmony_cistatic const struct em28xx_reg_seq reddo_dvb_c_usb_box[] = {
24062306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xfe,	0xff,		10},
24162306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xde,	0xff,		10},
24262306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xfe,	0xff,		10},
24362306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
24462306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x7f,	0xff,		10},
24562306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6f,	0xff,		10},
24662306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
24762306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
24862306a36Sopenharmony_ci};
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci/* Callback for the most boards */
25162306a36Sopenharmony_cistatic const struct em28xx_reg_seq default_tuner_gpio[] = {
25262306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	EM_GPIO_4,	EM_GPIO_4,	10},
25362306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0,		EM_GPIO_4,	10},
25462306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	EM_GPIO_4,	EM_GPIO_4,	10},
25562306a36Sopenharmony_ci	{	-1,		-1,		-1,		-1},
25662306a36Sopenharmony_ci};
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci/* Mute/unmute */
25962306a36Sopenharmony_cistatic const struct em28xx_reg_seq compro_unmute_tv_gpio[] = {
26062306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	5,	7,	10},
26162306a36Sopenharmony_ci	{	-1,		-1,	-1,	-1},
26262306a36Sopenharmony_ci};
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_cistatic const struct em28xx_reg_seq compro_unmute_svid_gpio[] = {
26562306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	4,	7,	10},
26662306a36Sopenharmony_ci	{	-1,		-1,	-1,	-1},
26762306a36Sopenharmony_ci};
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_cistatic const struct em28xx_reg_seq compro_mute_gpio[] = {
27062306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	6,	7,	10},
27162306a36Sopenharmony_ci	{	-1,		-1,	-1,	-1},
27262306a36Sopenharmony_ci};
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci/* Terratec AV350 */
27562306a36Sopenharmony_cistatic const struct em28xx_reg_seq terratec_av350_mute_gpio[] = {
27662306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0x7f,		10},
27762306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
27862306a36Sopenharmony_ci};
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_cistatic const struct em28xx_reg_seq terratec_av350_unmute_gpio[] = {
28162306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
28262306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
28362306a36Sopenharmony_ci};
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_cistatic const struct em28xx_reg_seq silvercrest_reg_seq[] = {
28662306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
28762306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x01,	0xf7,		10},
28862306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
28962306a36Sopenharmony_ci};
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_cistatic const struct em28xx_reg_seq vc211a_enable[] = {
29262306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0x07,		10},
29362306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0x0f,		10},
29462306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0x0b,		10},
29562306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
29662306a36Sopenharmony_ci};
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_cistatic const struct em28xx_reg_seq dikom_dk300_digital[] = {
29962306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
30062306a36Sopenharmony_ci	{EM2880_R04_GPO,	0x08,	0xff,		10},
30162306a36Sopenharmony_ci	{	-1,		-1,	-1,		-1},
30262306a36Sopenharmony_ci};
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci/* Reset for the most [digital] boards */
30562306a36Sopenharmony_cistatic const struct em28xx_reg_seq leadership_digital[] = {
30662306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x70,	0xff,	10},
30762306a36Sopenharmony_ci	{	-1,			-1,	-1,	-1},
30862306a36Sopenharmony_ci};
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_cistatic const struct em28xx_reg_seq leadership_reset[] = {
31162306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf0,	0xff,	10},
31262306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xb0,	0xff,	10},
31362306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf0,	0xff,	10},
31462306a36Sopenharmony_ci	{	-1,			-1,	-1,	-1},
31562306a36Sopenharmony_ci};
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci/*
31862306a36Sopenharmony_ci * 2013:024f PCTV nanoStick T2 290e
31962306a36Sopenharmony_ci * GPIO_6 - demod reset
32062306a36Sopenharmony_ci * GPIO_7 - LED
32162306a36Sopenharmony_ci */
32262306a36Sopenharmony_cistatic const struct em28xx_reg_seq pctv_290e[] = {
32362306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x00,	0xff,	80},
32462306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x40,	0xff,	80}, /* GPIO_6 = 1 */
32562306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xc0,	0xff,	80}, /* GPIO_7 = 1 */
32662306a36Sopenharmony_ci	{	-1,			-1,	-1,	-1},
32762306a36Sopenharmony_ci};
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci#if 0
33062306a36Sopenharmony_cistatic const struct em28xx_reg_seq terratec_h5_gpio[] = {
33162306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,		0xff,	0xff,	10},
33262306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
33362306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf2,	0xff,	50},
33462306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	50},
33562306a36Sopenharmony_ci	{	-1,			-1,	-1,	-1},
33662306a36Sopenharmony_ci};
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_cistatic const struct em28xx_reg_seq terratec_h5_digital[] = {
33962306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	10},
34062306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
34162306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	10},
34262306a36Sopenharmony_ci	{	-1,			-1,	-1,	-1},
34362306a36Sopenharmony_ci};
34462306a36Sopenharmony_ci#endif
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci/*
34762306a36Sopenharmony_ci * 2013:024f PCTV DVB-S2 Stick 460e
34862306a36Sopenharmony_ci * GPIO_0 - POWER_ON
34962306a36Sopenharmony_ci * GPIO_1 - BOOST
35062306a36Sopenharmony_ci * GPIO_2 - VUV_LNB (red LED)
35162306a36Sopenharmony_ci * GPIO_3 - EXT_12V
35262306a36Sopenharmony_ci * GPIO_4 - INT_DEM (DEMOD GPIO_0)
35362306a36Sopenharmony_ci * GPIO_5 - INT_LNB
35462306a36Sopenharmony_ci * GPIO_6 - RESET_DEM
35562306a36Sopenharmony_ci * GPIO_7 - LED (green LED)
35662306a36Sopenharmony_ci */
35762306a36Sopenharmony_cistatic const struct em28xx_reg_seq pctv_460e[] = {
35862306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x01,	0xff,	50},
35962306a36Sopenharmony_ci	{	0x0d,			0xff,	0xff,	50},
36062306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x41,	0xff,	50}, /* GPIO_6=1 */
36162306a36Sopenharmony_ci	{	0x0d,			0x42,	0xff,	50},
36262306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x61,	0xff,	50}, /* GPIO_5=1 */
36362306a36Sopenharmony_ci	{	-1,			-1,	-1,	-1},
36462306a36Sopenharmony_ci};
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_cistatic const struct em28xx_reg_seq c3tech_digital_duo_digital[] = {
36762306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	10},
36862306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfd,	0xff,	10}, /* xc5000 reset */
36962306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf9,	0xff,	35},
37062306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfd,	0xff,	10},
37162306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	10},
37262306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfe,	0xff,	10},
37362306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xbe,	0xff,	10},
37462306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfe,	0xff,	20},
37562306a36Sopenharmony_ci	{	-1,			-1,	-1,	-1},
37662306a36Sopenharmony_ci};
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci/*
37962306a36Sopenharmony_ci * 2013:0258 PCTV DVB-S2 Stick (461e)
38062306a36Sopenharmony_ci * GPIO 0 = POWER_ON
38162306a36Sopenharmony_ci * GPIO 1 = BOOST
38262306a36Sopenharmony_ci * GPIO 2 = VUV_LNB (red LED)
38362306a36Sopenharmony_ci * GPIO 3 = #EXT_12V
38462306a36Sopenharmony_ci * GPIO 4 = INT_DEM
38562306a36Sopenharmony_ci * GPIO 5 = INT_LNB
38662306a36Sopenharmony_ci * GPIO 6 = #RESET_DEM
38762306a36Sopenharmony_ci * GPIO 7 = P07_LED (green LED)
38862306a36Sopenharmony_ci */
38962306a36Sopenharmony_cistatic const struct em28xx_reg_seq pctv_461e[] = {
39062306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0x7f, 0xff,    0},
39162306a36Sopenharmony_ci	{0x0d,                 0xff, 0xff,    0},
39262306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0x3f, 0xff,  100}, /* reset demod */
39362306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0x7f, 0xff,  200}, /* reset demod */
39462306a36Sopenharmony_ci	{0x0d,                 0x42, 0xff,    0},
39562306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xeb, 0xff,    0},
39662306a36Sopenharmony_ci	{EM2874_R5F_TS_ENABLE, 0x84, 0x84,    0}, /* parallel? | null discard */
39762306a36Sopenharmony_ci	{                  -1,   -1,   -1,   -1},
39862306a36Sopenharmony_ci};
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci#if 0
40162306a36Sopenharmony_cistatic const struct em28xx_reg_seq hauppauge_930c_gpio[] = {
40262306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x6f,	0xff,	10},
40362306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x4f,	0xff,	10}, /* xc5000 reset */
40462306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x6f,	0xff,	10},
40562306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x4f,	0xff,	10},
40662306a36Sopenharmony_ci	{	-1,			-1,	-1,	-1},
40762306a36Sopenharmony_ci};
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_cistatic const struct em28xx_reg_seq hauppauge_930c_digital[] = {
41062306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	10},
41162306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
41262306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	10},
41362306a36Sopenharmony_ci	{	-1,			-1,	-1,	-1},
41462306a36Sopenharmony_ci};
41562306a36Sopenharmony_ci#endif
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci/*
41862306a36Sopenharmony_ci * 1b80:e425 MaxMedia UB425-TC
41962306a36Sopenharmony_ci * 1b80:e1cc Delock 61959
42062306a36Sopenharmony_ci * GPIO_6 - demod reset, 0=active
42162306a36Sopenharmony_ci * GPIO_7 - LED, 0=active
42262306a36Sopenharmony_ci */
42362306a36Sopenharmony_cistatic const struct em28xx_reg_seq maxmedia_ub425_tc[] = {
42462306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x83,	0xff,	100},
42562306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xc3,	0xff,	100}, /* GPIO_6 = 1 */
42662306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x43,	0xff,	000}, /* GPIO_7 = 0 */
42762306a36Sopenharmony_ci	{	-1,			-1,	-1,	-1},
42862306a36Sopenharmony_ci};
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci/*
43162306a36Sopenharmony_ci * 2304:0242 PCTV QuatroStick (510e)
43262306a36Sopenharmony_ci * GPIO_2: decoder reset, 0=active
43362306a36Sopenharmony_ci * GPIO_4: decoder suspend, 0=active
43462306a36Sopenharmony_ci * GPIO_6: demod reset, 0=active
43562306a36Sopenharmony_ci * GPIO_7: LED, 1=active
43662306a36Sopenharmony_ci */
43762306a36Sopenharmony_cistatic const struct em28xx_reg_seq pctv_510e[] = {
43862306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x10,	0xff,	100},
43962306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x14,	0xff,	100}, /* GPIO_2 = 1 */
44062306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x54,	0xff,	050}, /* GPIO_6 = 1 */
44162306a36Sopenharmony_ci	{	-1,			-1,	-1,	-1},
44262306a36Sopenharmony_ci};
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci/*
44562306a36Sopenharmony_ci * 2013:0251 PCTV QuatroStick nano (520e)
44662306a36Sopenharmony_ci * GPIO_2: decoder reset, 0=active
44762306a36Sopenharmony_ci * GPIO_4: decoder suspend, 0=active
44862306a36Sopenharmony_ci * GPIO_6: demod reset, 0=active
44962306a36Sopenharmony_ci * GPIO_7: LED, 1=active
45062306a36Sopenharmony_ci */
45162306a36Sopenharmony_cistatic const struct em28xx_reg_seq pctv_520e[] = {
45262306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x10,	0xff,	100},
45362306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x14,	0xff,	100}, /* GPIO_2 = 1 */
45462306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x54,	0xff,	050}, /* GPIO_6 = 1 */
45562306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xd4,	0xff,	000}, /* GPIO_7 = 1 */
45662306a36Sopenharmony_ci	{	-1,			-1,	-1,	-1},
45762306a36Sopenharmony_ci};
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_ci/*
46062306a36Sopenharmony_ci * 1ae7:9003/9004 SpeedLink Vicious And Devine Laplace webcam
46162306a36Sopenharmony_ci * reg 0x80/0x84:
46262306a36Sopenharmony_ci * GPIO_0: capturing LED, 0=on, 1=off
46362306a36Sopenharmony_ci * GPIO_2: AV mute button, 0=pressed, 1=unpressed
46462306a36Sopenharmony_ci * GPIO 3: illumination button, 0=pressed, 1=unpressed
46562306a36Sopenharmony_ci * GPIO_6: illumination/flash LED, 0=on, 1=off
46662306a36Sopenharmony_ci * reg 0x81/0x85:
46762306a36Sopenharmony_ci * GPIO_7: snapshot button, 0=pressed, 1=unpressed
46862306a36Sopenharmony_ci */
46962306a36Sopenharmony_cistatic const struct em28xx_reg_seq speedlink_vad_laplace_reg_seq[] = {
47062306a36Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,		0xf7,	0xff,	10},
47162306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xb2,	10},
47262306a36Sopenharmony_ci	{	-1,			-1,	-1,	-1},
47362306a36Sopenharmony_ci};
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_cistatic const struct em28xx_reg_seq pctv_292e[] = {
47662306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xff, 0xff,      0},
47762306a36Sopenharmony_ci	{0x0d,                         0xff, 0xff,    950},
47862306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xbd, 0xff,    100},
47962306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xfd, 0xff,    410},
48062306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0x7d, 0xff,    300},
48162306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0x7c, 0xff,     60},
48262306a36Sopenharmony_ci	{0x0d,                         0x42, 0xff,     50},
48362306a36Sopenharmony_ci	{EM2874_R5F_TS_ENABLE,         0x85, 0xff,      0},
48462306a36Sopenharmony_ci	{-1,                             -1,   -1,     -1},
48562306a36Sopenharmony_ci};
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_cistatic const struct em28xx_reg_seq terratec_t2_stick_hd[] = {
48862306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	0},
48962306a36Sopenharmony_ci	{0x0d,				0xff,	0xff,	600},
49062306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfc,	0xff,	10},
49162306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xbc,	0xff,	100},
49262306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfc,	0xff,	100},
49362306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x00,	0xff,	300},
49462306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf8,	0xff,	100},
49562306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfc,	0xff,	300},
49662306a36Sopenharmony_ci	{0x0d,				0x42,	0xff,	1000},
49762306a36Sopenharmony_ci	{EM2874_R5F_TS_ENABLE,		0x85,	0xff,	0},
49862306a36Sopenharmony_ci	{-1,                             -1,   -1,     -1},
49962306a36Sopenharmony_ci};
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_cistatic const struct em28xx_reg_seq plex_px_bcud[] = {
50262306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	0},
50362306a36Sopenharmony_ci	{0x0d,				0xff,	0xff,	0},
50462306a36Sopenharmony_ci	{EM2874_R50_IR_CONFIG,		0x01,	0xff,	0},
50562306a36Sopenharmony_ci	{EM28XX_R06_I2C_CLK,		0x40,	0xff,	0},
50662306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfd,	0xff,	100},
50762306a36Sopenharmony_ci	{EM28XX_R12_VINENABLE,		0x20,	0x20,	0},
50862306a36Sopenharmony_ci	{0x0d,				0x42,	0xff,	1000},
50962306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfc,	0xff,	10},
51062306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfd,	0xff,	10},
51162306a36Sopenharmony_ci	{0x73,				0xfd,	0xff,	100},
51262306a36Sopenharmony_ci	{-1,				-1,	-1,	-1},
51362306a36Sopenharmony_ci};
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_ci/*
51662306a36Sopenharmony_ci * 2040:0265 Hauppauge WinTV-dualHD DVB Isoc
51762306a36Sopenharmony_ci * 2040:8265 Hauppauge WinTV-dualHD DVB Bulk
51862306a36Sopenharmony_ci * 2040:026d Hauppauge WinTV-dualHD ATSC/QAM Isoc
51962306a36Sopenharmony_ci * 2040:826d Hauppauge WinTV-dualHD ATSC/QAM Bulk
52062306a36Sopenharmony_ci * reg 0x80/0x84:
52162306a36Sopenharmony_ci * GPIO_0: Yellow LED tuner 1, 0=on, 1=off
52262306a36Sopenharmony_ci * GPIO_1: Green LED tuner 1, 0=on, 1=off
52362306a36Sopenharmony_ci * GPIO_2: Yellow LED tuner 2, 0=on, 1=off
52462306a36Sopenharmony_ci * GPIO_3: Green LED tuner 2, 0=on, 1=off
52562306a36Sopenharmony_ci * GPIO_5: Reset #2, 0=active
52662306a36Sopenharmony_ci * GPIO_6: Reset #1, 0=active
52762306a36Sopenharmony_ci */
52862306a36Sopenharmony_cistatic const struct em28xx_reg_seq hauppauge_dualhd_dvb[] = {
52962306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xff, 0xff,      0},
53062306a36Sopenharmony_ci	{0x0d,                         0xff, 0xff,    200},
53162306a36Sopenharmony_ci	{0x50,                         0x04, 0xff,    300},
53262306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xbf, 0xff,    100}, /* demod 1 reset */
53362306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xff, 0xff,    100},
53462306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xdf, 0xff,    100}, /* demod 2 reset */
53562306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xff, 0xff,    100},
53662306a36Sopenharmony_ci	{EM2874_R5F_TS_ENABLE,         0x00, 0xff,     50}, /* disable TS filters */
53762306a36Sopenharmony_ci	{EM2874_R5D_TS1_PKT_SIZE,      0x05, 0xff,     50},
53862306a36Sopenharmony_ci	{EM2874_R5E_TS2_PKT_SIZE,      0x05, 0xff,     50},
53962306a36Sopenharmony_ci	{-1,                             -1,   -1,     -1},
54062306a36Sopenharmony_ci};
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_ci/* Hauppauge USB QuadHD */
54362306a36Sopenharmony_cistatic struct em28xx_reg_seq hauppauge_usb_quadhd_atsc_reg_seq[] = {
54462306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xff, 0xff,      0},
54562306a36Sopenharmony_ci	{0x0d,                         0xff, 0xff,    200},
54662306a36Sopenharmony_ci	{0x50,                         0x04, 0xff,    300},
54762306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xb0, 0xf0,    100}, /* demod 1 reset */
54862306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xf0, 0xf0,    100},
54962306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xd0, 0xf0,    100}, /* demod 2 reset */
55062306a36Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xf0, 0xf0,    100},
55162306a36Sopenharmony_ci	{EM2874_R5F_TS_ENABLE,         0x44, 0xff,     50},
55262306a36Sopenharmony_ci	{EM2874_R5D_TS1_PKT_SIZE,      0x05, 0xff,     50},
55362306a36Sopenharmony_ci	{EM2874_R5E_TS2_PKT_SIZE,      0x05, 0xff,     50},
55462306a36Sopenharmony_ci	{-1,                           -1,   -1,       -1},
55562306a36Sopenharmony_ci};
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci/*
55862306a36Sopenharmony_ci *  Button definitions
55962306a36Sopenharmony_ci */
56062306a36Sopenharmony_cistatic const struct em28xx_button std_snapshot_button[] = {
56162306a36Sopenharmony_ci	{
56262306a36Sopenharmony_ci		.role         = EM28XX_BUTTON_SNAPSHOT,
56362306a36Sopenharmony_ci		.reg_r        = EM28XX_R0C_USBSUSP,
56462306a36Sopenharmony_ci		.reg_clearing = EM28XX_R0C_USBSUSP,
56562306a36Sopenharmony_ci		.mask         = EM28XX_R0C_USBSUSP_SNAPSHOT,
56662306a36Sopenharmony_ci		.inverted     = 0,
56762306a36Sopenharmony_ci	},
56862306a36Sopenharmony_ci	{-1, 0, 0, 0, 0},
56962306a36Sopenharmony_ci};
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_cistatic const struct em28xx_button speedlink_vad_laplace_buttons[] = {
57262306a36Sopenharmony_ci	{
57362306a36Sopenharmony_ci		.role     = EM28XX_BUTTON_SNAPSHOT,
57462306a36Sopenharmony_ci		.reg_r    = EM2874_R85_GPIO_P1_STATE,
57562306a36Sopenharmony_ci		.mask     = 0x80,
57662306a36Sopenharmony_ci		.inverted = 1,
57762306a36Sopenharmony_ci	},
57862306a36Sopenharmony_ci	{
57962306a36Sopenharmony_ci		.role     = EM28XX_BUTTON_ILLUMINATION,
58062306a36Sopenharmony_ci		.reg_r    = EM2874_R84_GPIO_P0_STATE,
58162306a36Sopenharmony_ci		.mask     = 0x08,
58262306a36Sopenharmony_ci		.inverted = 1,
58362306a36Sopenharmony_ci	},
58462306a36Sopenharmony_ci	{-1, 0, 0, 0, 0},
58562306a36Sopenharmony_ci};
58662306a36Sopenharmony_ci
58762306a36Sopenharmony_ci/*
58862306a36Sopenharmony_ci *  LED definitions
58962306a36Sopenharmony_ci */
59062306a36Sopenharmony_cistatic struct em28xx_led speedlink_vad_laplace_leds[] = {
59162306a36Sopenharmony_ci	{
59262306a36Sopenharmony_ci		.role      = EM28XX_LED_ANALOG_CAPTURING,
59362306a36Sopenharmony_ci		.gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
59462306a36Sopenharmony_ci		.gpio_mask = 0x01,
59562306a36Sopenharmony_ci		.inverted  = 1,
59662306a36Sopenharmony_ci	},
59762306a36Sopenharmony_ci	{
59862306a36Sopenharmony_ci		.role      = EM28XX_LED_ILLUMINATION,
59962306a36Sopenharmony_ci		.gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
60062306a36Sopenharmony_ci		.gpio_mask = 0x40,
60162306a36Sopenharmony_ci		.inverted  = 1,
60262306a36Sopenharmony_ci	},
60362306a36Sopenharmony_ci	{-1, 0, 0, 0},
60462306a36Sopenharmony_ci};
60562306a36Sopenharmony_ci
60662306a36Sopenharmony_cistatic struct em28xx_led kworld_ub435q_v3_leds[] = {
60762306a36Sopenharmony_ci	{
60862306a36Sopenharmony_ci		.role      = EM28XX_LED_DIGITAL_CAPTURING,
60962306a36Sopenharmony_ci		.gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
61062306a36Sopenharmony_ci		.gpio_mask = 0x80,
61162306a36Sopenharmony_ci		.inverted  = 1,
61262306a36Sopenharmony_ci	},
61362306a36Sopenharmony_ci	{-1, 0, 0, 0},
61462306a36Sopenharmony_ci};
61562306a36Sopenharmony_ci
61662306a36Sopenharmony_cistatic struct em28xx_led pctv_80e_leds[] = {
61762306a36Sopenharmony_ci	{
61862306a36Sopenharmony_ci		.role      = EM28XX_LED_DIGITAL_CAPTURING,
61962306a36Sopenharmony_ci		.gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
62062306a36Sopenharmony_ci		.gpio_mask = 0x80,
62162306a36Sopenharmony_ci		.inverted  = 0,
62262306a36Sopenharmony_ci	},
62362306a36Sopenharmony_ci	{-1, 0, 0, 0},
62462306a36Sopenharmony_ci};
62562306a36Sopenharmony_ci
62662306a36Sopenharmony_cistatic struct em28xx_led terratec_grabby_leds[] = {
62762306a36Sopenharmony_ci	{
62862306a36Sopenharmony_ci		.role      = EM28XX_LED_ANALOG_CAPTURING,
62962306a36Sopenharmony_ci		.gpio_reg  = EM2820_R08_GPIO_CTRL,
63062306a36Sopenharmony_ci		.gpio_mask = EM_GPIO_3,
63162306a36Sopenharmony_ci		.inverted  = 1,
63262306a36Sopenharmony_ci	},
63362306a36Sopenharmony_ci	{-1, 0, 0, 0},
63462306a36Sopenharmony_ci};
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_cistatic struct em28xx_led hauppauge_dualhd_leds[] = {
63762306a36Sopenharmony_ci	{
63862306a36Sopenharmony_ci		.role      = EM28XX_LED_DIGITAL_CAPTURING,
63962306a36Sopenharmony_ci		.gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
64062306a36Sopenharmony_ci		.gpio_mask = EM_GPIO_1,
64162306a36Sopenharmony_ci		.inverted  = 1,
64262306a36Sopenharmony_ci	},
64362306a36Sopenharmony_ci	{
64462306a36Sopenharmony_ci		.role      = EM28XX_LED_DIGITAL_CAPTURING_TS2,
64562306a36Sopenharmony_ci		.gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
64662306a36Sopenharmony_ci		.gpio_mask = EM_GPIO_3,
64762306a36Sopenharmony_ci		.inverted  = 1,
64862306a36Sopenharmony_ci	},
64962306a36Sopenharmony_ci	{-1, 0, 0, 0},
65062306a36Sopenharmony_ci};
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_cistatic struct em28xx_led hauppauge_usb_quadhd_leds[] = {
65362306a36Sopenharmony_ci	{
65462306a36Sopenharmony_ci		.role      = EM28XX_LED_DIGITAL_CAPTURING,
65562306a36Sopenharmony_ci		.gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
65662306a36Sopenharmony_ci		.gpio_mask = EM_GPIO_2,
65762306a36Sopenharmony_ci		.inverted  = 1,
65862306a36Sopenharmony_ci	},
65962306a36Sopenharmony_ci	{
66062306a36Sopenharmony_ci		.role      = EM28XX_LED_DIGITAL_CAPTURING_TS2,
66162306a36Sopenharmony_ci		.gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
66262306a36Sopenharmony_ci		.gpio_mask = EM_GPIO_0,
66362306a36Sopenharmony_ci		.inverted  = 1,
66462306a36Sopenharmony_ci	},
66562306a36Sopenharmony_ci	{-1, 0, 0, 0},
66662306a36Sopenharmony_ci};
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_ci/*
66962306a36Sopenharmony_ci *  Board definitions
67062306a36Sopenharmony_ci */
67162306a36Sopenharmony_ciconst struct em28xx_board em28xx_boards[] = {
67262306a36Sopenharmony_ci	[EM2750_BOARD_UNKNOWN] = {
67362306a36Sopenharmony_ci		.name          = "EM2710/EM2750/EM2751 webcam grabber",
67462306a36Sopenharmony_ci		.xclk          = EM28XX_XCLK_FREQUENCY_20MHZ,
67562306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
67662306a36Sopenharmony_ci		.is_webcam     = 1,
67762306a36Sopenharmony_ci		.input         = { {
67862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
67962306a36Sopenharmony_ci			.vmux     = 0,
68062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
68162306a36Sopenharmony_ci			.gpio     = silvercrest_reg_seq,
68262306a36Sopenharmony_ci		} },
68362306a36Sopenharmony_ci	},
68462306a36Sopenharmony_ci	[EM2800_BOARD_UNKNOWN] = {
68562306a36Sopenharmony_ci		.name         = "Unknown EM2800 video grabber",
68662306a36Sopenharmony_ci		.is_em2800    = 1,
68762306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
68862306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
68962306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
69062306a36Sopenharmony_ci		.input        = { {
69162306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
69262306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
69362306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
69462306a36Sopenharmony_ci		}, {
69562306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
69662306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
69762306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
69862306a36Sopenharmony_ci		} },
69962306a36Sopenharmony_ci	},
70062306a36Sopenharmony_ci	[EM2820_BOARD_UNKNOWN] = {
70162306a36Sopenharmony_ci		.name          = "Unknown EM2750/28xx video grabber",
70262306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
70362306a36Sopenharmony_ci		.is_webcam     = 1,	/* To enable sensor probe */
70462306a36Sopenharmony_ci	},
70562306a36Sopenharmony_ci	[EM2882_BOARD_ZOLID_HYBRID_TV_STICK] = {
70662306a36Sopenharmony_ci		.name			= ":ZOLID HYBRID TV STICK",
70762306a36Sopenharmony_ci		.tuner_type		= TUNER_XC2028,
70862306a36Sopenharmony_ci		.tuner_gpio		= zolid_tuner,
70962306a36Sopenharmony_ci		.decoder		= EM28XX_TVP5150,
71062306a36Sopenharmony_ci		.xclk			= EM28XX_XCLK_FREQUENCY_12MHZ,
71162306a36Sopenharmony_ci		.mts_firmware	= 1,
71262306a36Sopenharmony_ci		.has_dvb		= 1,
71362306a36Sopenharmony_ci		.dvb_gpio		= zolid_digital,
71462306a36Sopenharmony_ci	},
71562306a36Sopenharmony_ci	[EM2750_BOARD_DLCW_130] = {
71662306a36Sopenharmony_ci		/* Beijing Huaqi Information Digital Technology Co., Ltd */
71762306a36Sopenharmony_ci		.name          = "Huaqi DLCW-130",
71862306a36Sopenharmony_ci		.valid         = EM28XX_BOARD_NOT_VALIDATED,
71962306a36Sopenharmony_ci		.xclk          = EM28XX_XCLK_FREQUENCY_48MHZ,
72062306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
72162306a36Sopenharmony_ci		.is_webcam     = 1,
72262306a36Sopenharmony_ci		.input         = { {
72362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
72462306a36Sopenharmony_ci			.vmux     = 0,
72562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
72662306a36Sopenharmony_ci		} },
72762306a36Sopenharmony_ci	},
72862306a36Sopenharmony_ci	[EM2820_BOARD_KWORLD_PVRTV2800RF] = {
72962306a36Sopenharmony_ci		.name         = "Kworld PVR TV 2800 RF",
73062306a36Sopenharmony_ci		.tuner_type   = TUNER_TEMIC_PAL,
73162306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
73262306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
73362306a36Sopenharmony_ci		.input        = { {
73462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
73562306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
73662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
73762306a36Sopenharmony_ci		}, {
73862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
73962306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
74062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
74162306a36Sopenharmony_ci		} },
74262306a36Sopenharmony_ci	},
74362306a36Sopenharmony_ci	[EM2820_BOARD_GADMEI_TVR200] = {
74462306a36Sopenharmony_ci		.name         = "Gadmei TVR200",
74562306a36Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
74662306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
74762306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
74862306a36Sopenharmony_ci		.input        = { {
74962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
75062306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
75162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
75262306a36Sopenharmony_ci		}, {
75362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
75462306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
75562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
75662306a36Sopenharmony_ci		}, {
75762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
75862306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
75962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
76062306a36Sopenharmony_ci		} },
76162306a36Sopenharmony_ci	},
76262306a36Sopenharmony_ci	[EM2820_BOARD_TERRATEC_CINERGY_250] = {
76362306a36Sopenharmony_ci		.name         = "Terratec Cinergy 250 USB",
76462306a36Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
76562306a36Sopenharmony_ci		.has_ir_i2c   = 1,
76662306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
76762306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
76862306a36Sopenharmony_ci		.input        = { {
76962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
77062306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
77162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
77262306a36Sopenharmony_ci		}, {
77362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
77462306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
77562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
77662306a36Sopenharmony_ci		}, {
77762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
77862306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
77962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
78062306a36Sopenharmony_ci		} },
78162306a36Sopenharmony_ci	},
78262306a36Sopenharmony_ci	[EM2820_BOARD_PINNACLE_USB_2] = {
78362306a36Sopenharmony_ci		.name         = "Pinnacle PCTV USB 2",
78462306a36Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
78562306a36Sopenharmony_ci		.has_ir_i2c   = 1,
78662306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
78762306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
78862306a36Sopenharmony_ci		.input        = { {
78962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
79062306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
79162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
79262306a36Sopenharmony_ci		}, {
79362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
79462306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
79562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
79662306a36Sopenharmony_ci		}, {
79762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
79862306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
79962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
80062306a36Sopenharmony_ci		} },
80162306a36Sopenharmony_ci	},
80262306a36Sopenharmony_ci	[EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = {
80362306a36Sopenharmony_ci		.name         = "Hauppauge WinTV USB 2",
80462306a36Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_FM1236_MK3,
80562306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT |
80662306a36Sopenharmony_ci				TDA9887_PORT1_ACTIVE |
80762306a36Sopenharmony_ci				TDA9887_PORT2_ACTIVE,
80862306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
80962306a36Sopenharmony_ci		.has_msp34xx  = 1,
81062306a36Sopenharmony_ci		.has_ir_i2c   = 1,
81162306a36Sopenharmony_ci		.input        = { {
81262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
81362306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
81462306a36Sopenharmony_ci			.amux     = MSP_INPUT_DEFAULT,
81562306a36Sopenharmony_ci		}, {
81662306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
81762306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
81862306a36Sopenharmony_ci			.amux     = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
81962306a36Sopenharmony_ci					MSP_DSP_IN_SCART, MSP_DSP_IN_SCART),
82062306a36Sopenharmony_ci		} },
82162306a36Sopenharmony_ci	},
82262306a36Sopenharmony_ci	[EM2820_BOARD_DLINK_USB_TV] = {
82362306a36Sopenharmony_ci		.name         = "D-Link DUB-T210 TV Tuner",
82462306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
82562306a36Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
82662306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
82762306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
82862306a36Sopenharmony_ci		.input        = { {
82962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
83062306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
83162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
83262306a36Sopenharmony_ci		}, {
83362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
83462306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
83562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
83662306a36Sopenharmony_ci		}, {
83762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
83862306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
83962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
84062306a36Sopenharmony_ci		} },
84162306a36Sopenharmony_ci	},
84262306a36Sopenharmony_ci	[EM2820_BOARD_HERCULES_SMART_TV_USB2] = {
84362306a36Sopenharmony_ci		.name         = "Hercules Smart TV USB 2.0",
84462306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
84562306a36Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
84662306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
84762306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
84862306a36Sopenharmony_ci		.input        = { {
84962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
85062306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
85162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
85262306a36Sopenharmony_ci		}, {
85362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
85462306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
85562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
85662306a36Sopenharmony_ci		}, {
85762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
85862306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
85962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
86062306a36Sopenharmony_ci		} },
86162306a36Sopenharmony_ci	},
86262306a36Sopenharmony_ci	[EM2820_BOARD_PINNACLE_USB_2_FM1216ME] = {
86362306a36Sopenharmony_ci		.name         = "Pinnacle PCTV USB 2 (Philips FM1216ME)",
86462306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
86562306a36Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_FM1216ME_MK3,
86662306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
86762306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
86862306a36Sopenharmony_ci		.input        = { {
86962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
87062306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
87162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
87262306a36Sopenharmony_ci		}, {
87362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
87462306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
87562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
87662306a36Sopenharmony_ci		}, {
87762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
87862306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
87962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
88062306a36Sopenharmony_ci		} },
88162306a36Sopenharmony_ci	},
88262306a36Sopenharmony_ci	[EM2820_BOARD_GADMEI_UTV310] = {
88362306a36Sopenharmony_ci		.name         = "Gadmei UTV310",
88462306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
88562306a36Sopenharmony_ci		.tuner_type   = TUNER_TNF_5335MF,
88662306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
88762306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
88862306a36Sopenharmony_ci		.input        = { {
88962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
89062306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE1,
89162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
89262306a36Sopenharmony_ci		}, {
89362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
89462306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
89562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
89662306a36Sopenharmony_ci		}, {
89762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
89862306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
89962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
90062306a36Sopenharmony_ci		} },
90162306a36Sopenharmony_ci	},
90262306a36Sopenharmony_ci	[EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE] = {
90362306a36Sopenharmony_ci		.name         = "Leadtek Winfast USB II Deluxe",
90462306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
90562306a36Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_FM1216ME_MK3,
90662306a36Sopenharmony_ci		.has_ir_i2c   = 1,
90762306a36Sopenharmony_ci		.tvaudio_addr = 0x58,
90862306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT |
90962306a36Sopenharmony_ci				TDA9887_PORT2_ACTIVE |
91062306a36Sopenharmony_ci				TDA9887_QSS,
91162306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
91262306a36Sopenharmony_ci		.adecoder     = EM28XX_TVAUDIO,
91362306a36Sopenharmony_ci		.input        = { {
91462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
91562306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE4,
91662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_AUX,
91762306a36Sopenharmony_ci		}, {
91862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
91962306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE5,
92062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
92162306a36Sopenharmony_ci		}, {
92262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
92362306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
92462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
92562306a36Sopenharmony_ci		} },
92662306a36Sopenharmony_ci			.radio	  = {
92762306a36Sopenharmony_ci			.type     = EM28XX_RADIO,
92862306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_AUX,
92962306a36Sopenharmony_ci			}
93062306a36Sopenharmony_ci	},
93162306a36Sopenharmony_ci	[EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
93262306a36Sopenharmony_ci		.name         = "Videology 20K14XUSB USB2.0",
93362306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
93462306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
93562306a36Sopenharmony_ci		.is_webcam    = 1,
93662306a36Sopenharmony_ci		.input        = { {
93762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
93862306a36Sopenharmony_ci			.vmux     = 0,
93962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
94062306a36Sopenharmony_ci		} },
94162306a36Sopenharmony_ci	},
94262306a36Sopenharmony_ci	[EM2820_BOARD_SILVERCREST_WEBCAM] = {
94362306a36Sopenharmony_ci		.name         = "Silvercrest Webcam 1.3mpix",
94462306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
94562306a36Sopenharmony_ci		.is_webcam    = 1,
94662306a36Sopenharmony_ci		.input        = { {
94762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
94862306a36Sopenharmony_ci			.vmux     = 0,
94962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
95062306a36Sopenharmony_ci			.gpio     = silvercrest_reg_seq,
95162306a36Sopenharmony_ci		} },
95262306a36Sopenharmony_ci	},
95362306a36Sopenharmony_ci	[EM2821_BOARD_SUPERCOMP_USB_2] = {
95462306a36Sopenharmony_ci		.name         = "Supercomp USB 2.0 TV",
95562306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
95662306a36Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_FM1236_MK3,
95762306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT |
95862306a36Sopenharmony_ci				TDA9887_PORT1_ACTIVE |
95962306a36Sopenharmony_ci				TDA9887_PORT2_ACTIVE,
96062306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
96162306a36Sopenharmony_ci		.input        = { {
96262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
96362306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
96462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
96562306a36Sopenharmony_ci		}, {
96662306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
96762306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
96862306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
96962306a36Sopenharmony_ci		}, {
97062306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
97162306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
97262306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
97362306a36Sopenharmony_ci		} },
97462306a36Sopenharmony_ci	},
97562306a36Sopenharmony_ci	[EM2821_BOARD_USBGEAR_VD204] = {
97662306a36Sopenharmony_ci		.name         = "Usbgear VD204v9",
97762306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
97862306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,	/* Capture only device */
97962306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
98062306a36Sopenharmony_ci		.input        = { {
98162306a36Sopenharmony_ci			.type  = EM28XX_VMUX_COMPOSITE,
98262306a36Sopenharmony_ci			.vmux  = SAA7115_COMPOSITE0,
98362306a36Sopenharmony_ci			.amux  = EM28XX_AMUX_LINE_IN,
98462306a36Sopenharmony_ci		}, {
98562306a36Sopenharmony_ci			.type  = EM28XX_VMUX_SVIDEO,
98662306a36Sopenharmony_ci			.vmux  = SAA7115_SVIDEO3,
98762306a36Sopenharmony_ci			.amux  = EM28XX_AMUX_LINE_IN,
98862306a36Sopenharmony_ci		} },
98962306a36Sopenharmony_ci	},
99062306a36Sopenharmony_ci	[EM2860_BOARD_NETGMBH_CAM] = {
99162306a36Sopenharmony_ci		/* Beijing Huaqi Information Digital Technology Co., Ltd */
99262306a36Sopenharmony_ci		.name         = "NetGMBH Cam",
99362306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
99462306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
99562306a36Sopenharmony_ci		.is_webcam    = 1,
99662306a36Sopenharmony_ci		.input        = { {
99762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
99862306a36Sopenharmony_ci			.vmux     = 0,
99962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
100062306a36Sopenharmony_ci		} },
100162306a36Sopenharmony_ci	},
100262306a36Sopenharmony_ci	[EM2860_BOARD_TYPHOON_DVD_MAKER] = {
100362306a36Sopenharmony_ci		.name         = "Typhoon DVD Maker",
100462306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
100562306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,	/* Capture only device */
100662306a36Sopenharmony_ci		.input        = { {
100762306a36Sopenharmony_ci			.type  = EM28XX_VMUX_COMPOSITE,
100862306a36Sopenharmony_ci			.vmux  = SAA7115_COMPOSITE0,
100962306a36Sopenharmony_ci			.amux  = EM28XX_AMUX_LINE_IN,
101062306a36Sopenharmony_ci		}, {
101162306a36Sopenharmony_ci			.type  = EM28XX_VMUX_SVIDEO,
101262306a36Sopenharmony_ci			.vmux  = SAA7115_SVIDEO3,
101362306a36Sopenharmony_ci			.amux  = EM28XX_AMUX_LINE_IN,
101462306a36Sopenharmony_ci		} },
101562306a36Sopenharmony_ci	},
101662306a36Sopenharmony_ci	[EM2860_BOARD_GADMEI_UTV330] = {
101762306a36Sopenharmony_ci		.name         = "Gadmei UTV330",
101862306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
101962306a36Sopenharmony_ci		.tuner_type   = TUNER_TNF_5335MF,
102062306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
102162306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
102262306a36Sopenharmony_ci		.input        = { {
102362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
102462306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
102562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
102662306a36Sopenharmony_ci		}, {
102762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
102862306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
102962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
103062306a36Sopenharmony_ci		}, {
103162306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
103262306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
103362306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
103462306a36Sopenharmony_ci		} },
103562306a36Sopenharmony_ci	},
103662306a36Sopenharmony_ci	[EM2861_BOARD_GADMEI_UTV330PLUS] = {
103762306a36Sopenharmony_ci		.name         = "Gadmei UTV330+",
103862306a36Sopenharmony_ci		.tuner_type   = TUNER_TNF_5335MF,
103962306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
104062306a36Sopenharmony_ci		.ir_codes     = RC_MAP_GADMEI_RM008Z,
104162306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
104262306a36Sopenharmony_ci		.xclk         = EM28XX_XCLK_FREQUENCY_12MHZ,
104362306a36Sopenharmony_ci		.input        = { {
104462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
104562306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
104662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
104762306a36Sopenharmony_ci		}, {
104862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
104962306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
105062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
105162306a36Sopenharmony_ci		}, {
105262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
105362306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
105462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
105562306a36Sopenharmony_ci		} },
105662306a36Sopenharmony_ci	},
105762306a36Sopenharmony_ci	[EM2860_BOARD_TERRATEC_HYBRID_XS] = {
105862306a36Sopenharmony_ci		.name         = "Terratec Cinergy A Hybrid XS",
105962306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
106062306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
106162306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
106262306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
106362306a36Sopenharmony_ci
106462306a36Sopenharmony_ci		.input        = { {
106562306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
106662306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
106762306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
106862306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
106962306a36Sopenharmony_ci		}, {
107062306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
107162306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
107262306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
107362306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
107462306a36Sopenharmony_ci		}, {
107562306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
107662306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
107762306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
107862306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
107962306a36Sopenharmony_ci		} },
108062306a36Sopenharmony_ci	},
108162306a36Sopenharmony_ci	[EM2861_BOARD_KWORLD_PVRTV_300U] = {
108262306a36Sopenharmony_ci		.name	      = "KWorld PVRTV 300U",
108362306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
108462306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
108562306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
108662306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
108762306a36Sopenharmony_ci		.input        = { {
108862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
108962306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
109062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
109162306a36Sopenharmony_ci		}, {
109262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
109362306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
109462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
109562306a36Sopenharmony_ci		}, {
109662306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
109762306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
109862306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
109962306a36Sopenharmony_ci		} },
110062306a36Sopenharmony_ci	},
110162306a36Sopenharmony_ci	[EM2861_BOARD_YAKUMO_MOVIE_MIXER] = {
110262306a36Sopenharmony_ci		.name          = "Yakumo MovieMixer",
110362306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,	/* Capture only device */
110462306a36Sopenharmony_ci		.decoder       = EM28XX_TVP5150,
110562306a36Sopenharmony_ci		.input         = { {
110662306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
110762306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
110862306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
110962306a36Sopenharmony_ci		}, {
111062306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
111162306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
111262306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
111362306a36Sopenharmony_ci		}, {
111462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
111562306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
111662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
111762306a36Sopenharmony_ci		} },
111862306a36Sopenharmony_ci	},
111962306a36Sopenharmony_ci	[EM2860_BOARD_TVP5150_REFERENCE_DESIGN] = {
112062306a36Sopenharmony_ci		.name          = "EM2860/TVP5150 Reference Design",
112162306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,	/* Capture only device */
112262306a36Sopenharmony_ci		.decoder       = EM28XX_TVP5150,
112362306a36Sopenharmony_ci		.input         = { {
112462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
112562306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
112662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
112762306a36Sopenharmony_ci		}, {
112862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
112962306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
113062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
113162306a36Sopenharmony_ci		} },
113262306a36Sopenharmony_ci	},
113362306a36Sopenharmony_ci	[EM2861_BOARD_PLEXTOR_PX_TV100U] = {
113462306a36Sopenharmony_ci		.name         = "Plextor ConvertX PX-TV100U",
113562306a36Sopenharmony_ci		.tuner_type   = TUNER_TNF_5335MF,
113662306a36Sopenharmony_ci		.xclk         = EM28XX_XCLK_I2S_MSB_TIMING |
113762306a36Sopenharmony_ci				EM28XX_XCLK_FREQUENCY_12MHZ,
113862306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
113962306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
114062306a36Sopenharmony_ci		.has_msp34xx  = 1,
114162306a36Sopenharmony_ci		.input        = { {
114262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
114362306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
114462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
114562306a36Sopenharmony_ci			.gpio     = pinnacle_hybrid_pro_analog,
114662306a36Sopenharmony_ci		}, {
114762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
114862306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
114962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
115062306a36Sopenharmony_ci			.gpio     = pinnacle_hybrid_pro_analog,
115162306a36Sopenharmony_ci		}, {
115262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
115362306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
115462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
115562306a36Sopenharmony_ci			.gpio     = pinnacle_hybrid_pro_analog,
115662306a36Sopenharmony_ci		} },
115762306a36Sopenharmony_ci	},
115862306a36Sopenharmony_ci
115962306a36Sopenharmony_ci	/* Those boards with em2870 are DVB Only*/
116062306a36Sopenharmony_ci
116162306a36Sopenharmony_ci	[EM2870_BOARD_TERRATEC_XS] = {
116262306a36Sopenharmony_ci		.name         = "Terratec Cinergy T XS",
116362306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
116462306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
116562306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
116662306a36Sopenharmony_ci	},
116762306a36Sopenharmony_ci	[EM2870_BOARD_TERRATEC_XS_MT2060] = {
116862306a36Sopenharmony_ci		.name         = "Terratec Cinergy T XS (MT2060)",
116962306a36Sopenharmony_ci		.xclk         = EM28XX_XCLK_IR_RC5_MODE |
117062306a36Sopenharmony_ci				EM28XX_XCLK_FREQUENCY_12MHZ,
117162306a36Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE,
117262306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT, /* MT2060 */
117362306a36Sopenharmony_ci		.has_dvb      = 1,
117462306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
117562306a36Sopenharmony_ci	},
117662306a36Sopenharmony_ci	[EM2870_BOARD_KWORLD_350U] = {
117762306a36Sopenharmony_ci		.name         = "Kworld 350 U DVB-T",
117862306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
117962306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
118062306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
118162306a36Sopenharmony_ci	},
118262306a36Sopenharmony_ci	[EM2870_BOARD_KWORLD_355U] = {
118362306a36Sopenharmony_ci		.name         = "Kworld 355 U DVB-T",
118462306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
118562306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
118662306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
118762306a36Sopenharmony_ci		.has_dvb      = 1,
118862306a36Sopenharmony_ci		.dvb_gpio     = default_digital,
118962306a36Sopenharmony_ci	},
119062306a36Sopenharmony_ci	[EM2870_BOARD_PINNACLE_PCTV_DVB] = {
119162306a36Sopenharmony_ci		.name         = "Pinnacle PCTV DVB-T",
119262306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
119362306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT, /* MT2060 */
119462306a36Sopenharmony_ci		/* djh - I have serious doubts this is right... */
119562306a36Sopenharmony_ci		.xclk         = EM28XX_XCLK_IR_RC5_MODE |
119662306a36Sopenharmony_ci				EM28XX_XCLK_FREQUENCY_10MHZ,
119762306a36Sopenharmony_ci	},
119862306a36Sopenharmony_ci	[EM2870_BOARD_COMPRO_VIDEOMATE] = {
119962306a36Sopenharmony_ci		.name         = "Compro, VideoMate U3",
120062306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
120162306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT, /* MT2060 */
120262306a36Sopenharmony_ci	},
120362306a36Sopenharmony_ci
120462306a36Sopenharmony_ci	[EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = {
120562306a36Sopenharmony_ci		.name         = "Terratec Hybrid XS Secam",
120662306a36Sopenharmony_ci		.has_msp34xx  = 1,
120762306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
120862306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
120962306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
121062306a36Sopenharmony_ci		.has_dvb      = 1,
121162306a36Sopenharmony_ci		.dvb_gpio     = terratec_cinergy_USB_XS_FR_digital,
121262306a36Sopenharmony_ci		.input        = { {
121362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
121462306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
121562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
121662306a36Sopenharmony_ci			.gpio     = terratec_cinergy_USB_XS_FR_analog,
121762306a36Sopenharmony_ci		}, {
121862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
121962306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
122062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
122162306a36Sopenharmony_ci			.gpio     = terratec_cinergy_USB_XS_FR_analog,
122262306a36Sopenharmony_ci		}, {
122362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
122462306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
122562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
122662306a36Sopenharmony_ci			.gpio     = terratec_cinergy_USB_XS_FR_analog,
122762306a36Sopenharmony_ci		} },
122862306a36Sopenharmony_ci	},
122962306a36Sopenharmony_ci	[EM2884_BOARD_TERRATEC_H5] = {
123062306a36Sopenharmony_ci		.name         = "Terratec Cinergy H5",
123162306a36Sopenharmony_ci		.has_dvb      = 1,
123262306a36Sopenharmony_ci#if 0
123362306a36Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_TDA8290,
123462306a36Sopenharmony_ci		.tuner_addr   = 0x41,
123562306a36Sopenharmony_ci		.dvb_gpio     = terratec_h5_digital, /* FIXME: probably wrong */
123662306a36Sopenharmony_ci		.tuner_gpio   = terratec_h5_gpio,
123762306a36Sopenharmony_ci#else
123862306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
123962306a36Sopenharmony_ci#endif
124062306a36Sopenharmony_ci		.def_i2c_bus  = 1,
124162306a36Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
124262306a36Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
124362306a36Sopenharmony_ci	},
124462306a36Sopenharmony_ci	[EM2884_BOARD_TERRATEC_H6] = {
124562306a36Sopenharmony_ci		.name         = "Terratec Cinergy H6 rev. 2",
124662306a36Sopenharmony_ci		.has_dvb      = 1,
124762306a36Sopenharmony_ci		.ir_codes     = RC_MAP_NEC_TERRATEC_CINERGY_XS,
124862306a36Sopenharmony_ci#if 0
124962306a36Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_TDA8290,
125062306a36Sopenharmony_ci		.tuner_addr   = 0x41,
125162306a36Sopenharmony_ci		.dvb_gpio     = terratec_h5_digital, /* FIXME: probably wrong */
125262306a36Sopenharmony_ci		.tuner_gpio   = terratec_h5_gpio,
125362306a36Sopenharmony_ci#else
125462306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
125562306a36Sopenharmony_ci#endif
125662306a36Sopenharmony_ci		.def_i2c_bus  = 1,
125762306a36Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
125862306a36Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
125962306a36Sopenharmony_ci	},
126062306a36Sopenharmony_ci	[EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = {
126162306a36Sopenharmony_ci		.name         = "Hauppauge WinTV HVR 930C",
126262306a36Sopenharmony_ci		.has_dvb      = 1,
126362306a36Sopenharmony_ci#if 0 /* FIXME: Add analog support */
126462306a36Sopenharmony_ci		.tuner_type   = TUNER_XC5000,
126562306a36Sopenharmony_ci		.tuner_addr   = 0x41,
126662306a36Sopenharmony_ci		.dvb_gpio     = hauppauge_930c_digital,
126762306a36Sopenharmony_ci		.tuner_gpio   = hauppauge_930c_gpio,
126862306a36Sopenharmony_ci#else
126962306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
127062306a36Sopenharmony_ci#endif
127162306a36Sopenharmony_ci		.ir_codes     = RC_MAP_HAUPPAUGE,
127262306a36Sopenharmony_ci		.def_i2c_bus  = 1,
127362306a36Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
127462306a36Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
127562306a36Sopenharmony_ci	},
127662306a36Sopenharmony_ci	[EM2884_BOARD_C3TECH_DIGITAL_DUO] = {
127762306a36Sopenharmony_ci		.name         = "C3 Tech Digital Duo HDTV/SDTV USB",
127862306a36Sopenharmony_ci		.has_dvb      = 1,
127962306a36Sopenharmony_ci		/* FIXME: Add analog support - need a saa7136 driver */
128062306a36Sopenharmony_ci		.tuner_type = TUNER_ABSENT,	/* Digital-only TDA18271HD */
128162306a36Sopenharmony_ci		.ir_codes     = RC_MAP_EMPTY,
128262306a36Sopenharmony_ci		.def_i2c_bus  = 1,
128362306a36Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE,
128462306a36Sopenharmony_ci		.dvb_gpio     = c3tech_digital_duo_digital,
128562306a36Sopenharmony_ci	},
128662306a36Sopenharmony_ci	[EM2884_BOARD_CINERGY_HTC_STICK] = {
128762306a36Sopenharmony_ci		.name         = "Terratec Cinergy HTC Stick",
128862306a36Sopenharmony_ci		.has_dvb      = 1,
128962306a36Sopenharmony_ci		.ir_codes     = RC_MAP_NEC_TERRATEC_CINERGY_XS,
129062306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
129162306a36Sopenharmony_ci		.def_i2c_bus  = 1,
129262306a36Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
129362306a36Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
129462306a36Sopenharmony_ci	},
129562306a36Sopenharmony_ci	[EM2884_BOARD_ELGATO_EYETV_HYBRID_2008] = {
129662306a36Sopenharmony_ci		.name         = "Elgato EyeTV Hybrid 2008 INT",
129762306a36Sopenharmony_ci		.has_dvb      = 1,
129862306a36Sopenharmony_ci		.ir_codes     = RC_MAP_NEC_TERRATEC_CINERGY_XS,
129962306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
130062306a36Sopenharmony_ci		.def_i2c_bus  = 1,
130162306a36Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
130262306a36Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
130362306a36Sopenharmony_ci	},
130462306a36Sopenharmony_ci	[EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = {
130562306a36Sopenharmony_ci		.name         = "Hauppauge WinTV HVR 900",
130662306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
130762306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
130862306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
130962306a36Sopenharmony_ci		.mts_firmware = 1,
131062306a36Sopenharmony_ci		.has_dvb      = 1,
131162306a36Sopenharmony_ci		.dvb_gpio     = hauppauge_wintv_hvr_900_digital,
131262306a36Sopenharmony_ci		.ir_codes     = RC_MAP_HAUPPAUGE,
131362306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
131462306a36Sopenharmony_ci		.input        = { {
131562306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
131662306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
131762306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
131862306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
131962306a36Sopenharmony_ci		}, {
132062306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
132162306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
132262306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
132362306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
132462306a36Sopenharmony_ci		}, {
132562306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
132662306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
132762306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
132862306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
132962306a36Sopenharmony_ci		} },
133062306a36Sopenharmony_ci	},
133162306a36Sopenharmony_ci	[EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = {
133262306a36Sopenharmony_ci		.name         = "Hauppauge WinTV HVR 900 (R2)",
133362306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
133462306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
133562306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
133662306a36Sopenharmony_ci		.mts_firmware = 1,
133762306a36Sopenharmony_ci		.has_dvb      = 1,
133862306a36Sopenharmony_ci		.dvb_gpio     = hauppauge_wintv_hvr_900R2_digital,
133962306a36Sopenharmony_ci		.ir_codes     = RC_MAP_HAUPPAUGE,
134062306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
134162306a36Sopenharmony_ci		.input        = { {
134262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
134362306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
134462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
134562306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
134662306a36Sopenharmony_ci		}, {
134762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
134862306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
134962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
135062306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
135162306a36Sopenharmony_ci		}, {
135262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
135362306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
135462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
135562306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
135662306a36Sopenharmony_ci		} },
135762306a36Sopenharmony_ci	},
135862306a36Sopenharmony_ci	[EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850] = {
135962306a36Sopenharmony_ci		.name           = "Hauppauge WinTV HVR 850",
136062306a36Sopenharmony_ci		.tuner_type     = TUNER_XC2028,
136162306a36Sopenharmony_ci		.tuner_gpio     = default_tuner_gpio,
136262306a36Sopenharmony_ci		.mts_firmware   = 1,
136362306a36Sopenharmony_ci		.has_dvb        = 1,
136462306a36Sopenharmony_ci		.dvb_gpio       = hauppauge_wintv_hvr_900_digital,
136562306a36Sopenharmony_ci		.ir_codes       = RC_MAP_HAUPPAUGE,
136662306a36Sopenharmony_ci		.decoder        = EM28XX_TVP5150,
136762306a36Sopenharmony_ci		.input          = { {
136862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
136962306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
137062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
137162306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
137262306a36Sopenharmony_ci		}, {
137362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
137462306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
137562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
137662306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
137762306a36Sopenharmony_ci		}, {
137862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
137962306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
138062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
138162306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
138262306a36Sopenharmony_ci		} },
138362306a36Sopenharmony_ci	},
138462306a36Sopenharmony_ci	[EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
138562306a36Sopenharmony_ci		.name           = "Hauppauge WinTV HVR 950",
138662306a36Sopenharmony_ci		.tuner_type     = TUNER_XC2028,
138762306a36Sopenharmony_ci		.tuner_gpio     = default_tuner_gpio,
138862306a36Sopenharmony_ci		.mts_firmware   = 1,
138962306a36Sopenharmony_ci		.has_dvb        = 1,
139062306a36Sopenharmony_ci		.dvb_gpio       = hauppauge_wintv_hvr_900_digital,
139162306a36Sopenharmony_ci		.ir_codes       = RC_MAP_HAUPPAUGE,
139262306a36Sopenharmony_ci		.decoder        = EM28XX_TVP5150,
139362306a36Sopenharmony_ci		.input          = { {
139462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
139562306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
139662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
139762306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
139862306a36Sopenharmony_ci		}, {
139962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
140062306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
140162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
140262306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
140362306a36Sopenharmony_ci		}, {
140462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
140562306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
140662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
140762306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
140862306a36Sopenharmony_ci		} },
140962306a36Sopenharmony_ci	},
141062306a36Sopenharmony_ci	[EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = {
141162306a36Sopenharmony_ci		.name           = "Pinnacle PCTV HD Pro Stick",
141262306a36Sopenharmony_ci		.tuner_type     = TUNER_XC2028,
141362306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
141462306a36Sopenharmony_ci		.mts_firmware   = 1,
141562306a36Sopenharmony_ci		.has_dvb        = 1,
141662306a36Sopenharmony_ci		.dvb_gpio       = hauppauge_wintv_hvr_900_digital,
141762306a36Sopenharmony_ci		.ir_codes       = RC_MAP_PINNACLE_PCTV_HD,
141862306a36Sopenharmony_ci		.decoder        = EM28XX_TVP5150,
141962306a36Sopenharmony_ci		.input          = { {
142062306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
142162306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
142262306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
142362306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
142462306a36Sopenharmony_ci		}, {
142562306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
142662306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
142762306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
142862306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
142962306a36Sopenharmony_ci		}, {
143062306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
143162306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
143262306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
143362306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
143462306a36Sopenharmony_ci		} },
143562306a36Sopenharmony_ci	},
143662306a36Sopenharmony_ci	[EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = {
143762306a36Sopenharmony_ci		.name           = "AMD ATI TV Wonder HD 600",
143862306a36Sopenharmony_ci		.tuner_type     = TUNER_XC2028,
143962306a36Sopenharmony_ci		.tuner_gpio     = default_tuner_gpio,
144062306a36Sopenharmony_ci		.mts_firmware   = 1,
144162306a36Sopenharmony_ci		.has_dvb        = 1,
144262306a36Sopenharmony_ci		.dvb_gpio       = hauppauge_wintv_hvr_900_digital,
144362306a36Sopenharmony_ci		.ir_codes       = RC_MAP_ATI_TV_WONDER_HD_600,
144462306a36Sopenharmony_ci		.decoder        = EM28XX_TVP5150,
144562306a36Sopenharmony_ci		.input          = { {
144662306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
144762306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
144862306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
144962306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
145062306a36Sopenharmony_ci		}, {
145162306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
145262306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
145362306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
145462306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
145562306a36Sopenharmony_ci		}, {
145662306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
145762306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
145862306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
145962306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
146062306a36Sopenharmony_ci		} },
146162306a36Sopenharmony_ci	},
146262306a36Sopenharmony_ci	[EM2880_BOARD_TERRATEC_HYBRID_XS] = {
146362306a36Sopenharmony_ci		.name           = "Terratec Hybrid XS",
146462306a36Sopenharmony_ci		.tuner_type     = TUNER_XC2028,
146562306a36Sopenharmony_ci		.tuner_gpio     = default_tuner_gpio,
146662306a36Sopenharmony_ci		.decoder        = EM28XX_TVP5150,
146762306a36Sopenharmony_ci		.has_dvb        = 1,
146862306a36Sopenharmony_ci		.dvb_gpio       = default_digital,
146962306a36Sopenharmony_ci		.ir_codes       = RC_MAP_TERRATEC_CINERGY_XS,
147062306a36Sopenharmony_ci		.xclk           = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */
147162306a36Sopenharmony_ci		.input          = { {
147262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
147362306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
147462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
147562306a36Sopenharmony_ci			.gpio     = default_analog,
147662306a36Sopenharmony_ci		}, {
147762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
147862306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
147962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
148062306a36Sopenharmony_ci			.gpio     = default_analog,
148162306a36Sopenharmony_ci		}, {
148262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
148362306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
148462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
148562306a36Sopenharmony_ci			.gpio     = default_analog,
148662306a36Sopenharmony_ci		} },
148762306a36Sopenharmony_ci	},
148862306a36Sopenharmony_ci	/*
148962306a36Sopenharmony_ci	 * maybe there's a reason behind it why Terratec sells the Hybrid XS
149062306a36Sopenharmony_ci	 * as Prodigy XS with a different PID, let's keep it separated for now
149162306a36Sopenharmony_ci	 * maybe we'll need it later on
149262306a36Sopenharmony_ci	 */
149362306a36Sopenharmony_ci	[EM2880_BOARD_TERRATEC_PRODIGY_XS] = {
149462306a36Sopenharmony_ci		.name         = "Terratec Prodigy XS",
149562306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
149662306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
149762306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
149862306a36Sopenharmony_ci		.input        = { {
149962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
150062306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
150162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
150262306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
150362306a36Sopenharmony_ci		}, {
150462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
150562306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
150662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
150762306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
150862306a36Sopenharmony_ci		}, {
150962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
151062306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
151162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
151262306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
151362306a36Sopenharmony_ci		} },
151462306a36Sopenharmony_ci	},
151562306a36Sopenharmony_ci	[EM2820_BOARD_MSI_VOX_USB_2] = {
151662306a36Sopenharmony_ci		.name		   = "MSI VOX USB 2.0",
151762306a36Sopenharmony_ci		.tuner_type	   = TUNER_LG_PAL_NEW_TAPC,
151862306a36Sopenharmony_ci		.tda9887_conf	   = TDA9887_PRESENT      |
151962306a36Sopenharmony_ci				     TDA9887_PORT1_ACTIVE |
152062306a36Sopenharmony_ci				     TDA9887_PORT2_ACTIVE,
152162306a36Sopenharmony_ci		.max_range_640_480 = 1,
152262306a36Sopenharmony_ci		.decoder           = EM28XX_SAA711X,
152362306a36Sopenharmony_ci		.input             = { {
152462306a36Sopenharmony_ci			.type      = EM28XX_VMUX_TELEVISION,
152562306a36Sopenharmony_ci			.vmux      = SAA7115_COMPOSITE4,
152662306a36Sopenharmony_ci			.amux      = EM28XX_AMUX_VIDEO,
152762306a36Sopenharmony_ci		}, {
152862306a36Sopenharmony_ci			.type      = EM28XX_VMUX_COMPOSITE,
152962306a36Sopenharmony_ci			.vmux      = SAA7115_COMPOSITE0,
153062306a36Sopenharmony_ci			.amux      = EM28XX_AMUX_LINE_IN,
153162306a36Sopenharmony_ci		}, {
153262306a36Sopenharmony_ci			.type      = EM28XX_VMUX_SVIDEO,
153362306a36Sopenharmony_ci			.vmux      = SAA7115_SVIDEO3,
153462306a36Sopenharmony_ci			.amux      = EM28XX_AMUX_LINE_IN,
153562306a36Sopenharmony_ci		} },
153662306a36Sopenharmony_ci	},
153762306a36Sopenharmony_ci	[EM2800_BOARD_TERRATEC_CINERGY_200] = {
153862306a36Sopenharmony_ci		.name         = "Terratec Cinergy 200 USB",
153962306a36Sopenharmony_ci		.is_em2800    = 1,
154062306a36Sopenharmony_ci		.has_ir_i2c   = 1,
154162306a36Sopenharmony_ci		.tuner_type   = TUNER_LG_TALN,
154262306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
154362306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
154462306a36Sopenharmony_ci		.input        = { {
154562306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
154662306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
154762306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
154862306a36Sopenharmony_ci		}, {
154962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
155062306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
155162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
155262306a36Sopenharmony_ci		}, {
155362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
155462306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
155562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
155662306a36Sopenharmony_ci		} },
155762306a36Sopenharmony_ci	},
155862306a36Sopenharmony_ci	[EM2800_BOARD_GRABBEEX_USB2800] = {
155962306a36Sopenharmony_ci		.name       = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
156062306a36Sopenharmony_ci		.is_em2800  = 1,
156162306a36Sopenharmony_ci		.decoder    = EM28XX_SAA711X,
156262306a36Sopenharmony_ci		.tuner_type = TUNER_ABSENT, /* capture only board */
156362306a36Sopenharmony_ci		.input      = { {
156462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
156562306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
156662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
156762306a36Sopenharmony_ci		}, {
156862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
156962306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
157062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
157162306a36Sopenharmony_ci		} },
157262306a36Sopenharmony_ci	},
157362306a36Sopenharmony_ci	[EM2800_BOARD_VC211A] = {
157462306a36Sopenharmony_ci		.name         = "Actionmaster/LinXcel/Digitus VC211A",
157562306a36Sopenharmony_ci		.is_em2800    = 1,
157662306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,	/* Capture-only board */
157762306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
157862306a36Sopenharmony_ci		.input        = { {
157962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
158062306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
158162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
158262306a36Sopenharmony_ci			.gpio     = vc211a_enable,
158362306a36Sopenharmony_ci		}, {
158462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
158562306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
158662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
158762306a36Sopenharmony_ci			.gpio     = vc211a_enable,
158862306a36Sopenharmony_ci		} },
158962306a36Sopenharmony_ci	},
159062306a36Sopenharmony_ci	[EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
159162306a36Sopenharmony_ci		.name         = "Leadtek Winfast USB II",
159262306a36Sopenharmony_ci		.is_em2800    = 1,
159362306a36Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
159462306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
159562306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
159662306a36Sopenharmony_ci		.input        = { {
159762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
159862306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
159962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
160062306a36Sopenharmony_ci		}, {
160162306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
160262306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
160362306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
160462306a36Sopenharmony_ci		}, {
160562306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
160662306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
160762306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
160862306a36Sopenharmony_ci		} },
160962306a36Sopenharmony_ci	},
161062306a36Sopenharmony_ci	[EM2800_BOARD_KWORLD_USB2800] = {
161162306a36Sopenharmony_ci		.name         = "Kworld USB2800",
161262306a36Sopenharmony_ci		.is_em2800    = 1,
161362306a36Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_FCV1236D,
161462306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
161562306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
161662306a36Sopenharmony_ci		.input        = { {
161762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
161862306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
161962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
162062306a36Sopenharmony_ci		}, {
162162306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
162262306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
162362306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
162462306a36Sopenharmony_ci		}, {
162562306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
162662306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
162762306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
162862306a36Sopenharmony_ci		} },
162962306a36Sopenharmony_ci	},
163062306a36Sopenharmony_ci	[EM2820_BOARD_PINNACLE_DVC_90] = {
163162306a36Sopenharmony_ci		.name	      = "Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker / Kworld DVD Maker 2 / Plextor ConvertX PX-AV100U",
163262306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT, /* capture only board */
163362306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
163462306a36Sopenharmony_ci		.input        = { {
163562306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
163662306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
163762306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
163862306a36Sopenharmony_ci		}, {
163962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
164062306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
164162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
164262306a36Sopenharmony_ci		} },
164362306a36Sopenharmony_ci	},
164462306a36Sopenharmony_ci	[EM2800_BOARD_VGEAR_POCKETTV] = {
164562306a36Sopenharmony_ci		.name         = "V-Gear PocketTV",
164662306a36Sopenharmony_ci		.is_em2800    = 1,
164762306a36Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
164862306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
164962306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
165062306a36Sopenharmony_ci		.input        = { {
165162306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
165262306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
165362306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
165462306a36Sopenharmony_ci		}, {
165562306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
165662306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
165762306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
165862306a36Sopenharmony_ci		}, {
165962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
166062306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
166162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
166262306a36Sopenharmony_ci		} },
166362306a36Sopenharmony_ci	},
166462306a36Sopenharmony_ci	[EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2] = {
166562306a36Sopenharmony_ci		.name         = "Pixelview PlayTV Box 4 USB 2.0",
166662306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
166762306a36Sopenharmony_ci		.tuner_type   = TUNER_YMEC_TVF_5533MF,
166862306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
166962306a36Sopenharmony_ci		.input        = { {
167062306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
167162306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
167262306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
167362306a36Sopenharmony_ci			.aout     = EM28XX_AOUT_MONO |	/* I2S */
167462306a36Sopenharmony_ci				    EM28XX_AOUT_MASTER,	/* Line out pin */
167562306a36Sopenharmony_ci		}, {
167662306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
167762306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
167862306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
167962306a36Sopenharmony_ci		}, {
168062306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
168162306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
168262306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
168362306a36Sopenharmony_ci		} },
168462306a36Sopenharmony_ci	},
168562306a36Sopenharmony_ci	[EM2820_BOARD_PROLINK_PLAYTV_USB2] = {
168662306a36Sopenharmony_ci		.name         = "SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0",
168762306a36Sopenharmony_ci		.buttons = std_snapshot_button,
168862306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
168962306a36Sopenharmony_ci		.tuner_type   = TUNER_YMEC_TVF_5533MF,
169062306a36Sopenharmony_ci		.tuner_addr   = 0x60,
169162306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
169262306a36Sopenharmony_ci		.input        = { {
169362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
169462306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
169562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
169662306a36Sopenharmony_ci			.aout     = EM28XX_AOUT_MONO |	/* I2S */
169762306a36Sopenharmony_ci				    EM28XX_AOUT_MASTER,	/* Line out pin */
169862306a36Sopenharmony_ci		}, {
169962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
170062306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
170162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
170262306a36Sopenharmony_ci		}, {
170362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
170462306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
170562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
170662306a36Sopenharmony_ci		} },
170762306a36Sopenharmony_ci	},
170862306a36Sopenharmony_ci	[EM2860_BOARD_SAA711X_REFERENCE_DESIGN] = {
170962306a36Sopenharmony_ci		.name                = "EM2860/SAA711X Reference Design",
171062306a36Sopenharmony_ci		.buttons = std_snapshot_button,
171162306a36Sopenharmony_ci		.tuner_type          = TUNER_ABSENT,
171262306a36Sopenharmony_ci		.decoder             = EM28XX_SAA711X,
171362306a36Sopenharmony_ci		.input               = { {
171462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
171562306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
171662306a36Sopenharmony_ci		}, {
171762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
171862306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
171962306a36Sopenharmony_ci		} },
172062306a36Sopenharmony_ci	},
172162306a36Sopenharmony_ci
172262306a36Sopenharmony_ci	[EM2874_BOARD_LEADERSHIP_ISDBT] = {
172362306a36Sopenharmony_ci		.def_i2c_bus	= 1,
172462306a36Sopenharmony_ci		.i2c_speed      = EM28XX_I2C_CLK_WAIT_ENABLE |
172562306a36Sopenharmony_ci				  EM28XX_I2C_FREQ_100_KHZ,
172662306a36Sopenharmony_ci		.xclk		= EM28XX_XCLK_FREQUENCY_10MHZ,
172762306a36Sopenharmony_ci		.name		= "EM2874 Leadership ISDBT",
172862306a36Sopenharmony_ci		.tuner_type	= TUNER_ABSENT,
172962306a36Sopenharmony_ci		.tuner_gpio     = leadership_reset,
173062306a36Sopenharmony_ci		.dvb_gpio       = leadership_digital,
173162306a36Sopenharmony_ci		.has_dvb	= 1,
173262306a36Sopenharmony_ci	},
173362306a36Sopenharmony_ci
173462306a36Sopenharmony_ci	[EM2880_BOARD_MSI_DIGIVOX_AD] = {
173562306a36Sopenharmony_ci		.name         = "MSI DigiVox A/D",
173662306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
173762306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
173862306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
173962306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
174062306a36Sopenharmony_ci		.input        = { {
174162306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
174262306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
174362306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
174462306a36Sopenharmony_ci			.gpio     = em2880_msi_digivox_ad_analog,
174562306a36Sopenharmony_ci		}, {
174662306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
174762306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
174862306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
174962306a36Sopenharmony_ci			.gpio     = em2880_msi_digivox_ad_analog,
175062306a36Sopenharmony_ci		}, {
175162306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
175262306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
175362306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
175462306a36Sopenharmony_ci			.gpio     = em2880_msi_digivox_ad_analog,
175562306a36Sopenharmony_ci		} },
175662306a36Sopenharmony_ci	},
175762306a36Sopenharmony_ci	[EM2880_BOARD_MSI_DIGIVOX_AD_II] = {
175862306a36Sopenharmony_ci		.name         = "MSI DigiVox A/D II",
175962306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
176062306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
176162306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
176262306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
176362306a36Sopenharmony_ci		.input        = { {
176462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
176562306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
176662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
176762306a36Sopenharmony_ci			.gpio     = em2880_msi_digivox_ad_analog,
176862306a36Sopenharmony_ci		}, {
176962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
177062306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
177162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
177262306a36Sopenharmony_ci			.gpio     = em2880_msi_digivox_ad_analog,
177362306a36Sopenharmony_ci		}, {
177462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
177562306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
177662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
177762306a36Sopenharmony_ci			.gpio     = em2880_msi_digivox_ad_analog,
177862306a36Sopenharmony_ci		} },
177962306a36Sopenharmony_ci	},
178062306a36Sopenharmony_ci	[EM2880_BOARD_KWORLD_DVB_305U] = {
178162306a36Sopenharmony_ci		.name	      = "KWorld DVB-T 305U",
178262306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
178362306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
178462306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
178562306a36Sopenharmony_ci		.input        = { {
178662306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
178762306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
178862306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
178962306a36Sopenharmony_ci		}, {
179062306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
179162306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
179262306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
179362306a36Sopenharmony_ci		}, {
179462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
179562306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
179662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
179762306a36Sopenharmony_ci		} },
179862306a36Sopenharmony_ci	},
179962306a36Sopenharmony_ci	[EM2880_BOARD_KWORLD_DVB_310U] = {
180062306a36Sopenharmony_ci		.name	      = "KWorld DVB-T 310U",
180162306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
180262306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
180362306a36Sopenharmony_ci		.has_dvb      = 1,
180462306a36Sopenharmony_ci		.dvb_gpio     = default_digital,
180562306a36Sopenharmony_ci		.mts_firmware = 1,
180662306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
180762306a36Sopenharmony_ci		.input        = { {
180862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
180962306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
181062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
181162306a36Sopenharmony_ci			.gpio     = default_analog,
181262306a36Sopenharmony_ci		}, {
181362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
181462306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
181562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
181662306a36Sopenharmony_ci			.gpio     = default_analog,
181762306a36Sopenharmony_ci		}, {	/* S-video has not been tested yet */
181862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
181962306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
182062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
182162306a36Sopenharmony_ci			.gpio     = default_analog,
182262306a36Sopenharmony_ci		} },
182362306a36Sopenharmony_ci	},
182462306a36Sopenharmony_ci	[EM2882_BOARD_KWORLD_ATSC_315U] = {
182562306a36Sopenharmony_ci		.name		= "KWorld ATSC 315U HDTV TV Box",
182662306a36Sopenharmony_ci		.valid		= EM28XX_BOARD_NOT_VALIDATED,
182762306a36Sopenharmony_ci		.tuner_type	= TUNER_THOMSON_DTT761X,
182862306a36Sopenharmony_ci		.tuner_gpio	= em2882_kworld_315u_tuner_gpio,
182962306a36Sopenharmony_ci		.tda9887_conf	= TDA9887_PRESENT,
183062306a36Sopenharmony_ci		.decoder	= EM28XX_SAA711X,
183162306a36Sopenharmony_ci		.has_dvb	= 1,
183262306a36Sopenharmony_ci		.dvb_gpio	= em2882_kworld_315u_digital,
183362306a36Sopenharmony_ci		.ir_codes	= RC_MAP_KWORLD_315U,
183462306a36Sopenharmony_ci		.xclk		= EM28XX_XCLK_FREQUENCY_12MHZ,
183562306a36Sopenharmony_ci		.i2c_speed	= EM28XX_I2C_CLK_WAIT_ENABLE,
183662306a36Sopenharmony_ci#if 0
183762306a36Sopenharmony_ci		/* FIXME: Analog mode - still not ready */
183862306a36Sopenharmony_ci		.input        = { {
183962306a36Sopenharmony_ci			.type = EM28XX_VMUX_TELEVISION,
184062306a36Sopenharmony_ci			.vmux = SAA7115_COMPOSITE2,
184162306a36Sopenharmony_ci			.amux = EM28XX_AMUX_VIDEO,
184262306a36Sopenharmony_ci			.gpio = em2882_kworld_315u_analog,
184362306a36Sopenharmony_ci			.aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
184462306a36Sopenharmony_ci		}, {
184562306a36Sopenharmony_ci			.type = EM28XX_VMUX_COMPOSITE,
184662306a36Sopenharmony_ci			.vmux = SAA7115_COMPOSITE0,
184762306a36Sopenharmony_ci			.amux = EM28XX_AMUX_LINE_IN,
184862306a36Sopenharmony_ci			.gpio = em2882_kworld_315u_analog1,
184962306a36Sopenharmony_ci			.aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
185062306a36Sopenharmony_ci		}, {
185162306a36Sopenharmony_ci			.type = EM28XX_VMUX_SVIDEO,
185262306a36Sopenharmony_ci			.vmux = SAA7115_SVIDEO3,
185362306a36Sopenharmony_ci			.amux = EM28XX_AMUX_LINE_IN,
185462306a36Sopenharmony_ci			.gpio = em2882_kworld_315u_analog1,
185562306a36Sopenharmony_ci			.aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
185662306a36Sopenharmony_ci		} },
185762306a36Sopenharmony_ci#endif
185862306a36Sopenharmony_ci	},
185962306a36Sopenharmony_ci	[EM2880_BOARD_EMPIRE_DUAL_TV] = {
186062306a36Sopenharmony_ci		.name = "Empire dual TV",
186162306a36Sopenharmony_ci		.tuner_type = TUNER_XC2028,
186262306a36Sopenharmony_ci		.tuner_gpio = default_tuner_gpio,
186362306a36Sopenharmony_ci		.has_dvb = 1,
186462306a36Sopenharmony_ci		.dvb_gpio = default_digital,
186562306a36Sopenharmony_ci		.mts_firmware = 1,
186662306a36Sopenharmony_ci		.decoder = EM28XX_TVP5150,
186762306a36Sopenharmony_ci		.input = { {
186862306a36Sopenharmony_ci			.type = EM28XX_VMUX_TELEVISION,
186962306a36Sopenharmony_ci			.vmux = TVP5150_COMPOSITE0,
187062306a36Sopenharmony_ci			.amux = EM28XX_AMUX_VIDEO,
187162306a36Sopenharmony_ci			.gpio = default_analog,
187262306a36Sopenharmony_ci		}, {
187362306a36Sopenharmony_ci			.type = EM28XX_VMUX_COMPOSITE,
187462306a36Sopenharmony_ci			.vmux = TVP5150_COMPOSITE1,
187562306a36Sopenharmony_ci			.amux = EM28XX_AMUX_LINE_IN,
187662306a36Sopenharmony_ci			.gpio = default_analog,
187762306a36Sopenharmony_ci		}, {
187862306a36Sopenharmony_ci			.type = EM28XX_VMUX_SVIDEO,
187962306a36Sopenharmony_ci			.vmux = TVP5150_SVIDEO,
188062306a36Sopenharmony_ci			.amux = EM28XX_AMUX_LINE_IN,
188162306a36Sopenharmony_ci			.gpio = default_analog,
188262306a36Sopenharmony_ci		} },
188362306a36Sopenharmony_ci	},
188462306a36Sopenharmony_ci	[EM2881_BOARD_DNT_DA2_HYBRID] = {
188562306a36Sopenharmony_ci		.name         = "DNT DA2 Hybrid",
188662306a36Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
188762306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
188862306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
188962306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
189062306a36Sopenharmony_ci		.input        = { {
189162306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
189262306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
189362306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
189462306a36Sopenharmony_ci			.gpio     = default_analog,
189562306a36Sopenharmony_ci		}, {
189662306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
189762306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
189862306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
189962306a36Sopenharmony_ci			.gpio     = default_analog,
190062306a36Sopenharmony_ci		}, {
190162306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
190262306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
190362306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
190462306a36Sopenharmony_ci			.gpio     = default_analog,
190562306a36Sopenharmony_ci		} },
190662306a36Sopenharmony_ci	},
190762306a36Sopenharmony_ci	[EM2881_BOARD_PINNACLE_HYBRID_PRO] = {
190862306a36Sopenharmony_ci		.name         = "Pinnacle Hybrid Pro",
190962306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
191062306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
191162306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
191262306a36Sopenharmony_ci		.has_dvb      = 1,
191362306a36Sopenharmony_ci		.dvb_gpio     = pinnacle_hybrid_pro_digital,
191462306a36Sopenharmony_ci		.input        = { {
191562306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
191662306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
191762306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
191862306a36Sopenharmony_ci			.gpio     = pinnacle_hybrid_pro_analog,
191962306a36Sopenharmony_ci		}, {
192062306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
192162306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
192262306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
192362306a36Sopenharmony_ci			.gpio     = pinnacle_hybrid_pro_analog,
192462306a36Sopenharmony_ci		}, {
192562306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
192662306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
192762306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
192862306a36Sopenharmony_ci			.gpio     = pinnacle_hybrid_pro_analog,
192962306a36Sopenharmony_ci		} },
193062306a36Sopenharmony_ci	},
193162306a36Sopenharmony_ci	[EM2882_BOARD_PINNACLE_HYBRID_PRO_330E] = {
193262306a36Sopenharmony_ci		.name         = "Pinnacle Hybrid Pro (330e)",
193362306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
193462306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
193562306a36Sopenharmony_ci		.mts_firmware = 1,
193662306a36Sopenharmony_ci		.has_dvb      = 1,
193762306a36Sopenharmony_ci		.dvb_gpio     = hauppauge_wintv_hvr_900R2_digital,
193862306a36Sopenharmony_ci		.ir_codes     = RC_MAP_PINNACLE_PCTV_HD,
193962306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
194062306a36Sopenharmony_ci		.input        = { {
194162306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
194262306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
194362306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
194462306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
194562306a36Sopenharmony_ci		}, {
194662306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
194762306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
194862306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
194962306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
195062306a36Sopenharmony_ci		}, {
195162306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
195262306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
195362306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
195462306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
195562306a36Sopenharmony_ci		} },
195662306a36Sopenharmony_ci	},
195762306a36Sopenharmony_ci	[EM2882_BOARD_KWORLD_VS_DVBT] = {
195862306a36Sopenharmony_ci		.name         = "Kworld VS-DVB-T 323UR",
195962306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
196062306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
196162306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
196262306a36Sopenharmony_ci		.mts_firmware = 1,
196362306a36Sopenharmony_ci		.has_dvb      = 1,
196462306a36Sopenharmony_ci		.dvb_gpio     = kworld_330u_digital,
196562306a36Sopenharmony_ci		.xclk         = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */
196662306a36Sopenharmony_ci		.ir_codes     = RC_MAP_KWORLD_315U,
196762306a36Sopenharmony_ci		.input        = { {
196862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
196962306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
197062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
197162306a36Sopenharmony_ci		}, {
197262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
197362306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
197462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
197562306a36Sopenharmony_ci		}, {
197662306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
197762306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
197862306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
197962306a36Sopenharmony_ci		} },
198062306a36Sopenharmony_ci	},
198162306a36Sopenharmony_ci	[EM2882_BOARD_TERRATEC_HYBRID_XS] = {
198262306a36Sopenharmony_ci		.name         = "Terratec Cinergy Hybrid T USB XS (em2882)",
198362306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
198462306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
198562306a36Sopenharmony_ci		.mts_firmware = 1,
198662306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
198762306a36Sopenharmony_ci		.has_dvb      = 1,
198862306a36Sopenharmony_ci		.dvb_gpio     = hauppauge_wintv_hvr_900_digital,
198962306a36Sopenharmony_ci		.ir_codes     = RC_MAP_TERRATEC_CINERGY_XS,
199062306a36Sopenharmony_ci		.xclk         = EM28XX_XCLK_FREQUENCY_12MHZ,
199162306a36Sopenharmony_ci		.input        = { {
199262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
199362306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
199462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
199562306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
199662306a36Sopenharmony_ci		}, {
199762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
199862306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
199962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
200062306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
200162306a36Sopenharmony_ci		}, {
200262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
200362306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
200462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
200562306a36Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
200662306a36Sopenharmony_ci		} },
200762306a36Sopenharmony_ci	},
200862306a36Sopenharmony_ci	[EM2882_BOARD_DIKOM_DK300] = {
200962306a36Sopenharmony_ci		.name         = "Dikom DK300",
201062306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
201162306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
201262306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
201362306a36Sopenharmony_ci		.mts_firmware = 1,
201462306a36Sopenharmony_ci		.has_dvb      = 1,
201562306a36Sopenharmony_ci		.dvb_gpio     = dikom_dk300_digital,
201662306a36Sopenharmony_ci		.input        = { {
201762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
201862306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
201962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
202062306a36Sopenharmony_ci			.gpio     = default_analog,
202162306a36Sopenharmony_ci		} },
202262306a36Sopenharmony_ci	},
202362306a36Sopenharmony_ci	[EM2883_BOARD_KWORLD_HYBRID_330U] = {
202462306a36Sopenharmony_ci		.name         = "Kworld PlusTV HD Hybrid 330",
202562306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
202662306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
202762306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
202862306a36Sopenharmony_ci		.mts_firmware = 1,
202962306a36Sopenharmony_ci		.has_dvb      = 1,
203062306a36Sopenharmony_ci		.dvb_gpio     = kworld_330u_digital,
203162306a36Sopenharmony_ci		.xclk             = EM28XX_XCLK_FREQUENCY_12MHZ,
203262306a36Sopenharmony_ci		.i2c_speed        = EM28XX_I2C_CLK_WAIT_ENABLE |
203362306a36Sopenharmony_ci				    EM28XX_I2C_EEPROM_ON_BOARD |
203462306a36Sopenharmony_ci				    EM28XX_I2C_EEPROM_KEY_VALID,
203562306a36Sopenharmony_ci		.input        = { {
203662306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
203762306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
203862306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
203962306a36Sopenharmony_ci			.gpio     = kworld_330u_analog,
204062306a36Sopenharmony_ci			.aout     = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
204162306a36Sopenharmony_ci		}, {
204262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
204362306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
204462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
204562306a36Sopenharmony_ci			.gpio     = kworld_330u_analog,
204662306a36Sopenharmony_ci			.aout     = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
204762306a36Sopenharmony_ci		}, {
204862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
204962306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
205062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
205162306a36Sopenharmony_ci			.gpio     = kworld_330u_analog,
205262306a36Sopenharmony_ci		} },
205362306a36Sopenharmony_ci	},
205462306a36Sopenharmony_ci	[EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
205562306a36Sopenharmony_ci		.name         = "Compro VideoMate ForYou/Stereo",
205662306a36Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
205762306a36Sopenharmony_ci		.tvaudio_addr = 0xb0,
205862306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
205962306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
206062306a36Sopenharmony_ci		.adecoder     = EM28XX_TVAUDIO,
206162306a36Sopenharmony_ci		.mute_gpio    = compro_mute_gpio,
206262306a36Sopenharmony_ci		.input        = { {
206362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
206462306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
206562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
206662306a36Sopenharmony_ci			.gpio     = compro_unmute_tv_gpio,
206762306a36Sopenharmony_ci		}, {
206862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
206962306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
207062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
207162306a36Sopenharmony_ci			.gpio     = compro_unmute_svid_gpio,
207262306a36Sopenharmony_ci		} },
207362306a36Sopenharmony_ci	},
207462306a36Sopenharmony_ci	[EM2860_BOARD_KAIOMY_TVNPC_U2] = {
207562306a36Sopenharmony_ci		.name	      = "Kaiomy TVnPC U2",
207662306a36Sopenharmony_ci		.vchannels    = 3,
207762306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
207862306a36Sopenharmony_ci		.tuner_addr   = 0x61,
207962306a36Sopenharmony_ci		.mts_firmware = 1,
208062306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
208162306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
208262306a36Sopenharmony_ci		.ir_codes     = RC_MAP_KAIOMY,
208362306a36Sopenharmony_ci		.input          = { {
208462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
208562306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
208662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
208762306a36Sopenharmony_ci
208862306a36Sopenharmony_ci		}, {
208962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
209062306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
209162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
209262306a36Sopenharmony_ci		}, {
209362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
209462306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
209562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
209662306a36Sopenharmony_ci		} },
209762306a36Sopenharmony_ci		.radio		= {
209862306a36Sopenharmony_ci			.type     = EM28XX_RADIO,
209962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
210062306a36Sopenharmony_ci		}
210162306a36Sopenharmony_ci	},
210262306a36Sopenharmony_ci	[EM2860_BOARD_EASYCAP] = {
210362306a36Sopenharmony_ci		.name         = "Easy Cap Capture DC-60",
210462306a36Sopenharmony_ci		.vchannels    = 2,
210562306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
210662306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
210762306a36Sopenharmony_ci		.input           = { {
210862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
210962306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
211062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
211162306a36Sopenharmony_ci		}, {
211262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
211362306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
211462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
211562306a36Sopenharmony_ci		} },
211662306a36Sopenharmony_ci	},
211762306a36Sopenharmony_ci	[EM2820_BOARD_IODATA_GVMVP_SZ] = {
211862306a36Sopenharmony_ci		.name       = "IO-DATA GV-MVP/SZ",
211962306a36Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_FM1236_MK3,
212062306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
212162306a36Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
212262306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
212362306a36Sopenharmony_ci		.input        = { {
212462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
212562306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
212662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
212762306a36Sopenharmony_ci		}, { /* Composite has not been tested yet */
212862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
212962306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
213062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
213162306a36Sopenharmony_ci		}, { /* S-video has not been tested yet */
213262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
213362306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
213462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
213562306a36Sopenharmony_ci		} },
213662306a36Sopenharmony_ci	},
213762306a36Sopenharmony_ci	[EM2860_BOARD_TERRATEC_GRABBY] = {
213862306a36Sopenharmony_ci		.name            = "Terratec Grabby",
213962306a36Sopenharmony_ci		.vchannels       = 2,
214062306a36Sopenharmony_ci		.tuner_type      = TUNER_ABSENT,
214162306a36Sopenharmony_ci		.decoder         = EM28XX_SAA711X,
214262306a36Sopenharmony_ci		.xclk            = EM28XX_XCLK_FREQUENCY_12MHZ,
214362306a36Sopenharmony_ci		.input           = { {
214462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
214562306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
214662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
214762306a36Sopenharmony_ci		}, {
214862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
214962306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
215062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
215162306a36Sopenharmony_ci		} },
215262306a36Sopenharmony_ci		.buttons         = std_snapshot_button,
215362306a36Sopenharmony_ci		.leds            = terratec_grabby_leds,
215462306a36Sopenharmony_ci	},
215562306a36Sopenharmony_ci	[EM2860_BOARD_TERRATEC_AV350] = {
215662306a36Sopenharmony_ci		.name            = "Terratec AV350",
215762306a36Sopenharmony_ci		.vchannels       = 2,
215862306a36Sopenharmony_ci		.tuner_type      = TUNER_ABSENT,
215962306a36Sopenharmony_ci		.decoder         = EM28XX_TVP5150,
216062306a36Sopenharmony_ci		.xclk            = EM28XX_XCLK_FREQUENCY_12MHZ,
216162306a36Sopenharmony_ci		.mute_gpio       = terratec_av350_mute_gpio,
216262306a36Sopenharmony_ci		.input           = { {
216362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
216462306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
216562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
216662306a36Sopenharmony_ci			.gpio     = terratec_av350_unmute_gpio,
216762306a36Sopenharmony_ci
216862306a36Sopenharmony_ci		}, {
216962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
217062306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
217162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
217262306a36Sopenharmony_ci			.gpio     = terratec_av350_unmute_gpio,
217362306a36Sopenharmony_ci		} },
217462306a36Sopenharmony_ci	},
217562306a36Sopenharmony_ci
217662306a36Sopenharmony_ci	[EM2860_BOARD_ELGATO_VIDEO_CAPTURE] = {
217762306a36Sopenharmony_ci		.name         = "Elgato Video Capture",
217862306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
217962306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,   /* Capture only device */
218062306a36Sopenharmony_ci		.input        = { {
218162306a36Sopenharmony_ci			.type  = EM28XX_VMUX_COMPOSITE,
218262306a36Sopenharmony_ci			.vmux  = SAA7115_COMPOSITE0,
218362306a36Sopenharmony_ci			.amux  = EM28XX_AMUX_LINE_IN,
218462306a36Sopenharmony_ci		}, {
218562306a36Sopenharmony_ci			.type  = EM28XX_VMUX_SVIDEO,
218662306a36Sopenharmony_ci			.vmux  = SAA7115_SVIDEO3,
218762306a36Sopenharmony_ci			.amux  = EM28XX_AMUX_LINE_IN,
218862306a36Sopenharmony_ci		} },
218962306a36Sopenharmony_ci	},
219062306a36Sopenharmony_ci
219162306a36Sopenharmony_ci	[EM2882_BOARD_EVGA_INDTUBE] = {
219262306a36Sopenharmony_ci		.name         = "Evga inDtube",
219362306a36Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
219462306a36Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
219562306a36Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
219662306a36Sopenharmony_ci		.xclk         = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */
219762306a36Sopenharmony_ci		.mts_firmware = 1,
219862306a36Sopenharmony_ci		.has_dvb      = 1,
219962306a36Sopenharmony_ci		.dvb_gpio     = evga_indtube_digital,
220062306a36Sopenharmony_ci		.ir_codes     = RC_MAP_EVGA_INDTUBE,
220162306a36Sopenharmony_ci		.input        = { {
220262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
220362306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
220462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
220562306a36Sopenharmony_ci			.gpio     = evga_indtube_analog,
220662306a36Sopenharmony_ci		}, {
220762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
220862306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
220962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
221062306a36Sopenharmony_ci			.gpio     = evga_indtube_analog,
221162306a36Sopenharmony_ci		}, {
221262306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
221362306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
221462306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
221562306a36Sopenharmony_ci			.gpio     = evga_indtube_analog,
221662306a36Sopenharmony_ci		} },
221762306a36Sopenharmony_ci	},
221862306a36Sopenharmony_ci	/*
221962306a36Sopenharmony_ci	 * eb1a:2868 Empia EM2870 + Philips CU1216L NIM
222062306a36Sopenharmony_ci	 * (Philips TDA10023 + Infineon TUA6034)
222162306a36Sopenharmony_ci	 */
222262306a36Sopenharmony_ci	[EM2870_BOARD_REDDO_DVB_C_USB_BOX] = {
222362306a36Sopenharmony_ci		.name          = "Reddo DVB-C USB TV Box",
222462306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
222562306a36Sopenharmony_ci		.tuner_gpio    = reddo_dvb_c_usb_box,
222662306a36Sopenharmony_ci		.has_dvb       = 1,
222762306a36Sopenharmony_ci	},
222862306a36Sopenharmony_ci	/*
222962306a36Sopenharmony_ci	 * 1b80:a340 - Empia EM2870, NXP TDA18271HD and LG DT3304, sold
223062306a36Sopenharmony_ci	 * initially as the KWorld PlusTV 340U, then as the UB435-Q.
223162306a36Sopenharmony_ci	 * Early variants have a TDA18271HD/C1, later ones a TDA18271HD/C2
223262306a36Sopenharmony_ci	 */
223362306a36Sopenharmony_ci	[EM2870_BOARD_KWORLD_A340] = {
223462306a36Sopenharmony_ci		.name       = "KWorld PlusTV 340U or UB435-Q (ATSC)",
223562306a36Sopenharmony_ci		.tuner_type = TUNER_ABSENT,	/* Digital-only TDA18271HD */
223662306a36Sopenharmony_ci		.has_dvb    = 1,
223762306a36Sopenharmony_ci		.dvb_gpio   = kworld_a340_digital,
223862306a36Sopenharmony_ci		.tuner_gpio = default_tuner_gpio,
223962306a36Sopenharmony_ci	},
224062306a36Sopenharmony_ci	/*
224162306a36Sopenharmony_ci	 * 2013:024f PCTV nanoStick T2 290e.
224262306a36Sopenharmony_ci	 * Empia EM28174, Sony CXD2820R and NXP TDA18271HD/C2
224362306a36Sopenharmony_ci	 */
224462306a36Sopenharmony_ci	[EM28174_BOARD_PCTV_290E] = {
224562306a36Sopenharmony_ci		.name          = "PCTV nanoStick T2 290e",
224662306a36Sopenharmony_ci		.def_i2c_bus   = 1,
224762306a36Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
224862306a36Sopenharmony_ci				 EM28XX_I2C_FREQ_100_KHZ,
224962306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
225062306a36Sopenharmony_ci		.tuner_gpio    = pctv_290e,
225162306a36Sopenharmony_ci		.has_dvb       = 1,
225262306a36Sopenharmony_ci		.ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
225362306a36Sopenharmony_ci	},
225462306a36Sopenharmony_ci	/*
225562306a36Sopenharmony_ci	 * 2013:024f PCTV DVB-S2 Stick 460e
225662306a36Sopenharmony_ci	 * Empia EM28174, NXP TDA10071, Conexant CX24118A and Allegro A8293
225762306a36Sopenharmony_ci	 */
225862306a36Sopenharmony_ci	[EM28174_BOARD_PCTV_460E] = {
225962306a36Sopenharmony_ci		.def_i2c_bus   = 1,
226062306a36Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
226162306a36Sopenharmony_ci				 EM28XX_I2C_FREQ_400_KHZ,
226262306a36Sopenharmony_ci		.name          = "PCTV DVB-S2 Stick (460e)",
226362306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
226462306a36Sopenharmony_ci		.tuner_gpio    = pctv_460e,
226562306a36Sopenharmony_ci		.has_dvb       = 1,
226662306a36Sopenharmony_ci		.ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
226762306a36Sopenharmony_ci	},
226862306a36Sopenharmony_ci	/*
226962306a36Sopenharmony_ci	 * eb1a:5006 Honestech VIDBOX NW03
227062306a36Sopenharmony_ci	 * Empia EM2860, Philips SAA7113, Empia EMP202, No Tuner
227162306a36Sopenharmony_ci	 */
227262306a36Sopenharmony_ci	[EM2860_BOARD_HT_VIDBOX_NW03] = {
227362306a36Sopenharmony_ci		.name                = "Honestech Vidbox NW03",
227462306a36Sopenharmony_ci		.tuner_type          = TUNER_ABSENT,
227562306a36Sopenharmony_ci		.decoder             = EM28XX_SAA711X,
227662306a36Sopenharmony_ci		.input               = { {
227762306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
227862306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
227962306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
228062306a36Sopenharmony_ci		}, {
228162306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
228262306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,  /* S-VIDEO needs check */
228362306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
228462306a36Sopenharmony_ci		} },
228562306a36Sopenharmony_ci	},
228662306a36Sopenharmony_ci	/*
228762306a36Sopenharmony_ci	 * 1b80:e425 MaxMedia UB425-TC
228862306a36Sopenharmony_ci	 * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2
228962306a36Sopenharmony_ci	 */
229062306a36Sopenharmony_ci	[EM2874_BOARD_MAXMEDIA_UB425_TC] = {
229162306a36Sopenharmony_ci		.name          = "MaxMedia UB425-TC",
229262306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
229362306a36Sopenharmony_ci		.tuner_gpio    = maxmedia_ub425_tc,
229462306a36Sopenharmony_ci		.has_dvb       = 1,
229562306a36Sopenharmony_ci		.ir_codes      = RC_MAP_REDDO,
229662306a36Sopenharmony_ci		.def_i2c_bus   = 1,
229762306a36Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
229862306a36Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
229962306a36Sopenharmony_ci	},
230062306a36Sopenharmony_ci	/*
230162306a36Sopenharmony_ci	 * 2304:0242 PCTV QuatroStick (510e)
230262306a36Sopenharmony_ci	 * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2
230362306a36Sopenharmony_ci	 */
230462306a36Sopenharmony_ci	[EM2884_BOARD_PCTV_510E] = {
230562306a36Sopenharmony_ci		.name          = "PCTV QuatroStick (510e)",
230662306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
230762306a36Sopenharmony_ci		.tuner_gpio    = pctv_510e,
230862306a36Sopenharmony_ci		.has_dvb       = 1,
230962306a36Sopenharmony_ci		.ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
231062306a36Sopenharmony_ci		.def_i2c_bus   = 1,
231162306a36Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
231262306a36Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
231362306a36Sopenharmony_ci	},
231462306a36Sopenharmony_ci	/*
231562306a36Sopenharmony_ci	 * 2013:0251 PCTV QuatroStick nano (520e)
231662306a36Sopenharmony_ci	 * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2
231762306a36Sopenharmony_ci	 */
231862306a36Sopenharmony_ci	[EM2884_BOARD_PCTV_520E] = {
231962306a36Sopenharmony_ci		.name          = "PCTV QuatroStick nano (520e)",
232062306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
232162306a36Sopenharmony_ci		.tuner_gpio    = pctv_520e,
232262306a36Sopenharmony_ci		.has_dvb       = 1,
232362306a36Sopenharmony_ci		.ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
232462306a36Sopenharmony_ci		.def_i2c_bus   = 1,
232562306a36Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
232662306a36Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
232762306a36Sopenharmony_ci	},
232862306a36Sopenharmony_ci	[EM2884_BOARD_TERRATEC_HTC_USB_XS] = {
232962306a36Sopenharmony_ci		.name         = "Terratec Cinergy HTC USB XS",
233062306a36Sopenharmony_ci		.has_dvb      = 1,
233162306a36Sopenharmony_ci		.ir_codes     = RC_MAP_NEC_TERRATEC_CINERGY_XS,
233262306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
233362306a36Sopenharmony_ci		.def_i2c_bus  = 1,
233462306a36Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
233562306a36Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
233662306a36Sopenharmony_ci	},
233762306a36Sopenharmony_ci	/*
233862306a36Sopenharmony_ci	 * 1b80:e1cc Delock 61959
233962306a36Sopenharmony_ci	 * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2
234062306a36Sopenharmony_ci	 * mostly the same as MaxMedia UB-425-TC but different remote
234162306a36Sopenharmony_ci	 */
234262306a36Sopenharmony_ci	[EM2874_BOARD_DELOCK_61959] = {
234362306a36Sopenharmony_ci		.name          = "Delock 61959",
234462306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
234562306a36Sopenharmony_ci		.tuner_gpio    = maxmedia_ub425_tc,
234662306a36Sopenharmony_ci		.has_dvb       = 1,
234762306a36Sopenharmony_ci		.ir_codes      = RC_MAP_DELOCK_61959,
234862306a36Sopenharmony_ci		.def_i2c_bus   = 1,
234962306a36Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
235062306a36Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
235162306a36Sopenharmony_ci	},
235262306a36Sopenharmony_ci	/*
235362306a36Sopenharmony_ci	 * 1b80:e346 KWorld USB ATSC TV Stick UB435-Q V2
235462306a36Sopenharmony_ci	 * Empia EM2874B + LG DT3305 + NXP TDA18271HDC2
235562306a36Sopenharmony_ci	 */
235662306a36Sopenharmony_ci	[EM2874_BOARD_KWORLD_UB435Q_V2] = {
235762306a36Sopenharmony_ci		.name		= "KWorld USB ATSC TV Stick UB435-Q V2",
235862306a36Sopenharmony_ci		.tuner_type	= TUNER_ABSENT,
235962306a36Sopenharmony_ci		.has_dvb	= 1,
236062306a36Sopenharmony_ci		.dvb_gpio	= kworld_a340_digital,
236162306a36Sopenharmony_ci		.tuner_gpio	= default_tuner_gpio,
236262306a36Sopenharmony_ci		.def_i2c_bus	= 1,
236362306a36Sopenharmony_ci	},
236462306a36Sopenharmony_ci	/*
236562306a36Sopenharmony_ci	 * 1b80:e34c KWorld USB ATSC TV Stick UB435-Q V3
236662306a36Sopenharmony_ci	 * Empia EM2874B + LG DT3305 + NXP TDA18271HDC2
236762306a36Sopenharmony_ci	 */
236862306a36Sopenharmony_ci	[EM2874_BOARD_KWORLD_UB435Q_V3] = {
236962306a36Sopenharmony_ci		.name		= "KWorld USB ATSC TV Stick UB435-Q V3",
237062306a36Sopenharmony_ci		.tuner_type	= TUNER_ABSENT,
237162306a36Sopenharmony_ci		.has_dvb	= 1,
237262306a36Sopenharmony_ci		.tuner_gpio	= kworld_ub435q_v3_digital,
237362306a36Sopenharmony_ci		.def_i2c_bus	= 1,
237462306a36Sopenharmony_ci		.i2c_speed      = EM28XX_I2C_CLK_WAIT_ENABLE |
237562306a36Sopenharmony_ci				  EM28XX_I2C_FREQ_100_KHZ,
237662306a36Sopenharmony_ci		.leds = kworld_ub435q_v3_leds,
237762306a36Sopenharmony_ci	},
237862306a36Sopenharmony_ci	[EM2874_BOARD_PCTV_HD_MINI_80E] = {
237962306a36Sopenharmony_ci		.name         = "Pinnacle PCTV HD Mini",
238062306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
238162306a36Sopenharmony_ci		.has_dvb      = 1,
238262306a36Sopenharmony_ci		.dvb_gpio     = em2874_pctv_80e_digital,
238362306a36Sopenharmony_ci		.decoder      = EM28XX_NODECODER,
238462306a36Sopenharmony_ci		.ir_codes     = RC_MAP_PINNACLE_PCTV_HD,
238562306a36Sopenharmony_ci		.leds         = pctv_80e_leds,
238662306a36Sopenharmony_ci	},
238762306a36Sopenharmony_ci	/*
238862306a36Sopenharmony_ci	 * 1ae7:9003/9004 SpeedLink Vicious And Devine Laplace webcam
238962306a36Sopenharmony_ci	 * Empia EM2765 + OmniVision OV2640
239062306a36Sopenharmony_ci	 */
239162306a36Sopenharmony_ci	[EM2765_BOARD_SPEEDLINK_VAD_LAPLACE] = {
239262306a36Sopenharmony_ci		.name         = "SpeedLink Vicious And Devine Laplace webcam",
239362306a36Sopenharmony_ci		.xclk         = EM28XX_XCLK_FREQUENCY_24MHZ,
239462306a36Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
239562306a36Sopenharmony_ci				EM28XX_I2C_FREQ_100_KHZ,
239662306a36Sopenharmony_ci		.def_i2c_bus  = 1,
239762306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
239862306a36Sopenharmony_ci		.is_webcam    = 1,
239962306a36Sopenharmony_ci		.input        = { {
240062306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
240162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
240262306a36Sopenharmony_ci			.gpio     = speedlink_vad_laplace_reg_seq,
240362306a36Sopenharmony_ci		} },
240462306a36Sopenharmony_ci		.buttons = speedlink_vad_laplace_buttons,
240562306a36Sopenharmony_ci		.leds = speedlink_vad_laplace_leds,
240662306a36Sopenharmony_ci	},
240762306a36Sopenharmony_ci	/*
240862306a36Sopenharmony_ci	 * 2013:0258 PCTV DVB-S2 Stick (461e)
240962306a36Sopenharmony_ci	 * Empia EM28178, Montage M88DS3103, Montage M88TS2022, Allegro A8293
241062306a36Sopenharmony_ci	 */
241162306a36Sopenharmony_ci	[EM28178_BOARD_PCTV_461E] = {
241262306a36Sopenharmony_ci		.def_i2c_bus   = 1,
241362306a36Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
241462306a36Sopenharmony_ci				 EM28XX_I2C_FREQ_400_KHZ,
241562306a36Sopenharmony_ci		.name          = "PCTV DVB-S2 Stick (461e)",
241662306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
241762306a36Sopenharmony_ci		.tuner_gpio    = pctv_461e,
241862306a36Sopenharmony_ci		.has_dvb       = 1,
241962306a36Sopenharmony_ci		.ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
242062306a36Sopenharmony_ci	},
242162306a36Sopenharmony_ci	/*
242262306a36Sopenharmony_ci	 * 2013:0259 PCTV DVB-S2 Stick (461e_v2)
242362306a36Sopenharmony_ci	 * Empia EM28178, Montage M88DS3103b, Montage M88TS2022, Allegro A8293
242462306a36Sopenharmony_ci	 */
242562306a36Sopenharmony_ci	[EM28178_BOARD_PCTV_461E_V2] = {
242662306a36Sopenharmony_ci		.def_i2c_bus   = 1,
242762306a36Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
242862306a36Sopenharmony_ci				 EM28XX_I2C_FREQ_400_KHZ,
242962306a36Sopenharmony_ci		.name          = "PCTV DVB-S2 Stick (461e v2)",
243062306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
243162306a36Sopenharmony_ci		.tuner_gpio    = pctv_461e,
243262306a36Sopenharmony_ci		.has_dvb       = 1,
243362306a36Sopenharmony_ci		.ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
243462306a36Sopenharmony_ci	},
243562306a36Sopenharmony_ci	/*
243662306a36Sopenharmony_ci	 * 2013:025f PCTV tripleStick (292e).
243762306a36Sopenharmony_ci	 * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2157
243862306a36Sopenharmony_ci	 */
243962306a36Sopenharmony_ci	[EM28178_BOARD_PCTV_292E] = {
244062306a36Sopenharmony_ci		.name          = "PCTV tripleStick (292e)",
244162306a36Sopenharmony_ci		.def_i2c_bus   = 1,
244262306a36Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
244362306a36Sopenharmony_ci				 EM28XX_I2C_FREQ_400_KHZ,
244462306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
244562306a36Sopenharmony_ci		.tuner_gpio    = pctv_292e,
244662306a36Sopenharmony_ci		.has_dvb       = 1,
244762306a36Sopenharmony_ci		.ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
244862306a36Sopenharmony_ci	},
244962306a36Sopenharmony_ci	[EM2861_BOARD_LEADTEK_VC100] = {
245062306a36Sopenharmony_ci		.name          = "Leadtek VC100",
245162306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,	/* Capture only device */
245262306a36Sopenharmony_ci		.decoder       = EM28XX_TVP5150,
245362306a36Sopenharmony_ci		.input         = { {
245462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
245562306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
245662306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
245762306a36Sopenharmony_ci		}, {
245862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
245962306a36Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
246062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
246162306a36Sopenharmony_ci		} },
246262306a36Sopenharmony_ci	},
246362306a36Sopenharmony_ci	/*
246462306a36Sopenharmony_ci	 * eb1a:8179 Terratec Cinergy T2 Stick HD.
246562306a36Sopenharmony_ci	 * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2146
246662306a36Sopenharmony_ci	 */
246762306a36Sopenharmony_ci	[EM28178_BOARD_TERRATEC_T2_STICK_HD] = {
246862306a36Sopenharmony_ci		.name          = "Terratec Cinergy T2 Stick HD",
246962306a36Sopenharmony_ci		.def_i2c_bus   = 1,
247062306a36Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
247162306a36Sopenharmony_ci				 EM28XX_I2C_FREQ_400_KHZ,
247262306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
247362306a36Sopenharmony_ci		.tuner_gpio    = terratec_t2_stick_hd,
247462306a36Sopenharmony_ci		.has_dvb       = 1,
247562306a36Sopenharmony_ci		.ir_codes      = RC_MAP_TERRATEC_SLIM_2,
247662306a36Sopenharmony_ci	},
247762306a36Sopenharmony_ci
247862306a36Sopenharmony_ci	/*
247962306a36Sopenharmony_ci	 * 3275:0085 PLEX PX-BCUD.
248062306a36Sopenharmony_ci	 * Empia EM28178, TOSHIBA TC90532XBG, Sharp QM1D1C0042
248162306a36Sopenharmony_ci	 */
248262306a36Sopenharmony_ci	[EM28178_BOARD_PLEX_PX_BCUD] = {
248362306a36Sopenharmony_ci		.name          = "PLEX PX-BCUD",
248462306a36Sopenharmony_ci		.xclk          = EM28XX_XCLK_FREQUENCY_4_3MHZ,
248562306a36Sopenharmony_ci		.def_i2c_bus   = 1,
248662306a36Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE,
248762306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
248862306a36Sopenharmony_ci		.tuner_gpio    = plex_px_bcud,
248962306a36Sopenharmony_ci		.has_dvb       = 1,
249062306a36Sopenharmony_ci	},
249162306a36Sopenharmony_ci	/*
249262306a36Sopenharmony_ci	 * 2040:0265 Hauppauge WinTV-dualHD (DVB version) Isoc.
249362306a36Sopenharmony_ci	 * 2040:8265 Hauppauge WinTV-dualHD (DVB version) Bulk.
249462306a36Sopenharmony_ci	 * Empia EM28274, 2x Silicon Labs Si2168, 2x Silicon Labs Si2157
249562306a36Sopenharmony_ci	 */
249662306a36Sopenharmony_ci	[EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB] = {
249762306a36Sopenharmony_ci		.name          = "Hauppauge WinTV-dualHD DVB",
249862306a36Sopenharmony_ci		.def_i2c_bus   = 1,
249962306a36Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
250062306a36Sopenharmony_ci				 EM28XX_I2C_FREQ_400_KHZ,
250162306a36Sopenharmony_ci		.tuner_type    = TUNER_SI2157,
250262306a36Sopenharmony_ci		.tuner_gpio    = hauppauge_dualhd_dvb,
250362306a36Sopenharmony_ci		.has_dvb       = 1,
250462306a36Sopenharmony_ci		.has_dual_ts   = 1,
250562306a36Sopenharmony_ci		.ir_codes      = RC_MAP_HAUPPAUGE,
250662306a36Sopenharmony_ci		.leds          = hauppauge_dualhd_leds,
250762306a36Sopenharmony_ci		.input         = { {
250862306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
250962306a36Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
251062306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
251162306a36Sopenharmony_ci		} },
251262306a36Sopenharmony_ci	},
251362306a36Sopenharmony_ci	/*
251462306a36Sopenharmony_ci	 * 2040:026d Hauppauge WinTV-dualHD (model 01595 - ATSC/QAM) Isoc.
251562306a36Sopenharmony_ci	 * 2040:826d Hauppauge WinTV-dualHD (model 01595 - ATSC/QAM) Bulk.
251662306a36Sopenharmony_ci	 * Empia EM28274, 2x LG LGDT3306A, 2x Silicon Labs Si2157
251762306a36Sopenharmony_ci	 */
251862306a36Sopenharmony_ci	[EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595] = {
251962306a36Sopenharmony_ci		.name          = "Hauppauge WinTV-dualHD 01595 ATSC/QAM",
252062306a36Sopenharmony_ci		.def_i2c_bus   = 1,
252162306a36Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
252262306a36Sopenharmony_ci				 EM28XX_I2C_FREQ_400_KHZ,
252362306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
252462306a36Sopenharmony_ci		.tuner_gpio    = hauppauge_dualhd_dvb,
252562306a36Sopenharmony_ci		.has_dvb       = 1,
252662306a36Sopenharmony_ci		.has_dual_ts   = 1,
252762306a36Sopenharmony_ci		.ir_codes      = RC_MAP_HAUPPAUGE,
252862306a36Sopenharmony_ci		.leds          = hauppauge_dualhd_leds,
252962306a36Sopenharmony_ci	},
253062306a36Sopenharmony_ci	/*
253162306a36Sopenharmony_ci	 * 1b80:e349 Magix USB Videowandler-2
253262306a36Sopenharmony_ci	 * (same chips as Honestech VIDBOX NW03)
253362306a36Sopenharmony_ci	 * Empia EM2860, Philips SAA7113, Empia EMP202, No Tuner
253462306a36Sopenharmony_ci	 */
253562306a36Sopenharmony_ci	[EM2861_BOARD_MAGIX_VIDEOWANDLER2] = {
253662306a36Sopenharmony_ci		.name                = "Magix USB Videowandler-2",
253762306a36Sopenharmony_ci		.tuner_type          = TUNER_ABSENT,
253862306a36Sopenharmony_ci		.decoder             = EM28XX_SAA711X,
253962306a36Sopenharmony_ci		.input               = { {
254062306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
254162306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
254262306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
254362306a36Sopenharmony_ci		}, {
254462306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
254562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
254662306a36Sopenharmony_ci		} },
254762306a36Sopenharmony_ci	},
254862306a36Sopenharmony_ci	/*
254962306a36Sopenharmony_ci	 * 1f4d:1abe MyGica iGrabber
255062306a36Sopenharmony_ci	 * (same as several other EM2860 devices)
255162306a36Sopenharmony_ci	 * Empia EM2860, Philips SAA7113, Empia EMP202, No Tuner
255262306a36Sopenharmony_ci	 */
255362306a36Sopenharmony_ci	[EM2860_BOARD_MYGICA_IGRABBER] = {
255462306a36Sopenharmony_ci		.name         = "MyGica iGrabber",
255562306a36Sopenharmony_ci		.vchannels    = 2,
255662306a36Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
255762306a36Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
255862306a36Sopenharmony_ci		.input           = { {
255962306a36Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
256062306a36Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
256162306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
256262306a36Sopenharmony_ci		}, {
256362306a36Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
256462306a36Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
256562306a36Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
256662306a36Sopenharmony_ci		} },
256762306a36Sopenharmony_ci	},
256862306a36Sopenharmony_ci	/* 2040:826d Hauppauge USB QuadHD
256962306a36Sopenharmony_ci	 * Empia 28274, Max Linear 692 ATSC combo demod/tuner
257062306a36Sopenharmony_ci	 */
257162306a36Sopenharmony_ci	[EM2874_BOARD_HAUPPAUGE_USB_QUADHD] = {
257262306a36Sopenharmony_ci		.name          = "Hauppauge USB QuadHD ATSC",
257362306a36Sopenharmony_ci		.def_i2c_bus   = 1,
257462306a36Sopenharmony_ci		.has_dual_ts   = 1,
257562306a36Sopenharmony_ci		.has_dvb       = 1,
257662306a36Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ,
257762306a36Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
257862306a36Sopenharmony_ci		.tuner_gpio    = hauppauge_usb_quadhd_atsc_reg_seq,
257962306a36Sopenharmony_ci		.leds          = hauppauge_usb_quadhd_leds,
258062306a36Sopenharmony_ci	},
258162306a36Sopenharmony_ci};
258262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(em28xx_boards);
258362306a36Sopenharmony_ci
258462306a36Sopenharmony_cistatic const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
258562306a36Sopenharmony_ci
258662306a36Sopenharmony_ci/* table of devices that work with this driver */
258762306a36Sopenharmony_cistruct usb_device_id em28xx_id_table[] = {
258862306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2750),
258962306a36Sopenharmony_ci			.driver_info = EM2750_BOARD_UNKNOWN },
259062306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2751),
259162306a36Sopenharmony_ci			.driver_info = EM2750_BOARD_UNKNOWN },
259262306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2800),
259362306a36Sopenharmony_ci			.driver_info = EM2800_BOARD_UNKNOWN },
259462306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2710),
259562306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
259662306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2820),
259762306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
259862306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2821),
259962306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
260062306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2860),
260162306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
260262306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2861),
260362306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
260462306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2862),
260562306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
260662306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2863),
260762306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
260862306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2870),
260962306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
261062306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2881),
261162306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
261262306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2883), /* used by :Zolid Hybrid Tv Stick */
261362306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
261462306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2868),
261562306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
261662306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2875),
261762306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
261862306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2885), /* MSI Digivox Trio */
261962306a36Sopenharmony_ci			.driver_info = EM2884_BOARD_TERRATEC_H5 },
262062306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe300),
262162306a36Sopenharmony_ci			.driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
262262306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe303),
262362306a36Sopenharmony_ci			.driver_info = EM2860_BOARD_KAIOMY_TVNPC_U2 },
262462306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe305),
262562306a36Sopenharmony_ci			.driver_info = EM2880_BOARD_KWORLD_DVB_305U },
262662306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe310),
262762306a36Sopenharmony_ci			.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD },
262862306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xa313),
262962306a36Sopenharmony_ci		.driver_info = EM2882_BOARD_KWORLD_ATSC_315U },
263062306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xa316),
263162306a36Sopenharmony_ci			.driver_info = EM2883_BOARD_KWORLD_HYBRID_330U },
263262306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe320),
263362306a36Sopenharmony_ci			.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II },
263462306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe323),
263562306a36Sopenharmony_ci			.driver_info = EM2882_BOARD_KWORLD_VS_DVBT },
263662306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe350),
263762306a36Sopenharmony_ci			.driver_info = EM2870_BOARD_KWORLD_350U },
263862306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe355),
263962306a36Sopenharmony_ci			.driver_info = EM2870_BOARD_KWORLD_355U },
264062306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2801),
264162306a36Sopenharmony_ci			.driver_info = EM2800_BOARD_GRABBEEX_USB2800 },
264262306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe357),
264362306a36Sopenharmony_ci			.driver_info = EM2870_BOARD_KWORLD_355U },
264462306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe359),
264562306a36Sopenharmony_ci			.driver_info = EM2870_BOARD_KWORLD_355U },
264662306a36Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe302), /* Kaiser Baas Video to DVD maker */
264762306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
264862306a36Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe304), /* Kworld DVD Maker 2 */
264962306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
265062306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x0036),
265162306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
265262306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x004c),
265362306a36Sopenharmony_ci			.driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS_FR },
265462306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x004f),
265562306a36Sopenharmony_ci			.driver_info = EM2860_BOARD_TERRATEC_HYBRID_XS },
265662306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x005e),
265762306a36Sopenharmony_ci			.driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
265862306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x0042),
265962306a36Sopenharmony_ci			.driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
266062306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x0043),
266162306a36Sopenharmony_ci			.driver_info = EM2870_BOARD_TERRATEC_XS_MT2060 },
266262306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x008e),	/* Cinergy HTC USB XS Rev. 1 */
266362306a36Sopenharmony_ci			.driver_info = EM2884_BOARD_TERRATEC_HTC_USB_XS },
266462306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x00ac),	/* Cinergy HTC USB XS Rev. 2 */
266562306a36Sopenharmony_ci			.driver_info = EM2884_BOARD_TERRATEC_HTC_USB_XS },
266662306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x10a2),	/* H5 Rev. 1 */
266762306a36Sopenharmony_ci			.driver_info = EM2884_BOARD_TERRATEC_H5 },
266862306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x10ad),	/* H5 Rev. 2 */
266962306a36Sopenharmony_ci			.driver_info = EM2884_BOARD_TERRATEC_H5 },
267062306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x10b6),	/* H5 Rev. 3 */
267162306a36Sopenharmony_ci			.driver_info = EM2884_BOARD_TERRATEC_H5 },
267262306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x10b2),	/* H6 */
267362306a36Sopenharmony_ci			.driver_info = EM2884_BOARD_TERRATEC_H6 },
267462306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x0084),
267562306a36Sopenharmony_ci			.driver_info = EM2860_BOARD_TERRATEC_AV350 },
267662306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x0096),
267762306a36Sopenharmony_ci			.driver_info = EM2860_BOARD_TERRATEC_GRABBY },
267862306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x10AF),
267962306a36Sopenharmony_ci			.driver_info = EM2860_BOARD_TERRATEC_GRABBY },
268062306a36Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x00b2),
268162306a36Sopenharmony_ci			.driver_info = EM2884_BOARD_CINERGY_HTC_STICK },
268262306a36Sopenharmony_ci	{ USB_DEVICE(0x0fd9, 0x0018),
268362306a36Sopenharmony_ci			.driver_info = EM2884_BOARD_ELGATO_EYETV_HYBRID_2008 },
268462306a36Sopenharmony_ci	{ USB_DEVICE(0x0fd9, 0x0033),
268562306a36Sopenharmony_ci			.driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE },
268662306a36Sopenharmony_ci	{ USB_DEVICE(0x185b, 0x2870),
268762306a36Sopenharmony_ci			.driver_info = EM2870_BOARD_COMPRO_VIDEOMATE },
268862306a36Sopenharmony_ci	{ USB_DEVICE(0x185b, 0x2041),
268962306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU },
269062306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x4200),
269162306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
269262306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x4201),
269362306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
269462306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x6500),
269562306a36Sopenharmony_ci			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
269662306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x6502),
269762306a36Sopenharmony_ci			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 },
269862306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */
269962306a36Sopenharmony_ci			.driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
270062306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x6517), /* HP  HVR-950 */
270162306a36Sopenharmony_ci			.driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
270262306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x651b), /* RP  HVR-950 */
270362306a36Sopenharmony_ci			.driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
270462306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x651f),
270562306a36Sopenharmony_ci			.driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 },
270662306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x0265),
270762306a36Sopenharmony_ci			.driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB },
270862306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x8265),
270962306a36Sopenharmony_ci			.driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB },
271062306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x026d),
271162306a36Sopenharmony_ci			.driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 },
271262306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x826d),
271362306a36Sopenharmony_ci			.driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 },
271462306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x846d),
271562306a36Sopenharmony_ci			.driver_info = EM2874_BOARD_HAUPPAUGE_USB_QUADHD },
271662306a36Sopenharmony_ci	{ USB_DEVICE(0x0438, 0xb002),
271762306a36Sopenharmony_ci			.driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 },
271862306a36Sopenharmony_ci	{ USB_DEVICE(0x2001, 0xf112),
271962306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_DLINK_USB_TV },
272062306a36Sopenharmony_ci	{ USB_DEVICE(0x2304, 0x0207),
272162306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
272262306a36Sopenharmony_ci	{ USB_DEVICE(0x2304, 0x0208),
272362306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_PINNACLE_USB_2 },
272462306a36Sopenharmony_ci	{ USB_DEVICE(0x2304, 0x021a),
272562306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
272662306a36Sopenharmony_ci	{ USB_DEVICE(0x2304, 0x0226),
272762306a36Sopenharmony_ci			.driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO_330E },
272862306a36Sopenharmony_ci	{ USB_DEVICE(0x2304, 0x0227),
272962306a36Sopenharmony_ci			.driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
273062306a36Sopenharmony_ci	{ USB_DEVICE(0x2304, 0x023f),
273162306a36Sopenharmony_ci			.driver_info = EM2874_BOARD_PCTV_HD_MINI_80E },
273262306a36Sopenharmony_ci	{ USB_DEVICE(0x0413, 0x6023),
273362306a36Sopenharmony_ci			.driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII },
273462306a36Sopenharmony_ci	{ USB_DEVICE(0x093b, 0xa003),
273562306a36Sopenharmony_ci		       .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
273662306a36Sopenharmony_ci	{ USB_DEVICE(0x093b, 0xa005),
273762306a36Sopenharmony_ci			.driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U },
273862306a36Sopenharmony_ci	{ USB_DEVICE(0x04bb, 0x0515),
273962306a36Sopenharmony_ci			.driver_info = EM2820_BOARD_IODATA_GVMVP_SZ },
274062306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x50a6),
274162306a36Sopenharmony_ci			.driver_info = EM2860_BOARD_GADMEI_UTV330 },
274262306a36Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xa340),
274362306a36Sopenharmony_ci			.driver_info = EM2870_BOARD_KWORLD_A340 },
274462306a36Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe346),
274562306a36Sopenharmony_ci			.driver_info = EM2874_BOARD_KWORLD_UB435Q_V2 },
274662306a36Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe34c),
274762306a36Sopenharmony_ci			.driver_info = EM2874_BOARD_KWORLD_UB435Q_V3 },
274862306a36Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x024f),
274962306a36Sopenharmony_ci			.driver_info = EM28174_BOARD_PCTV_290E },
275062306a36Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x024c),
275162306a36Sopenharmony_ci			.driver_info = EM28174_BOARD_PCTV_460E },
275262306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x1605),
275362306a36Sopenharmony_ci			.driver_info = EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C },
275462306a36Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe755),
275562306a36Sopenharmony_ci			.driver_info = EM2884_BOARD_C3TECH_DIGITAL_DUO },
275662306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x5006),
275762306a36Sopenharmony_ci			.driver_info = EM2860_BOARD_HT_VIDBOX_NW03 },
275862306a36Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe309), /* Sveon STV40 */
275962306a36Sopenharmony_ci			.driver_info = EM2860_BOARD_EASYCAP },
276062306a36Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe425),
276162306a36Sopenharmony_ci			.driver_info = EM2874_BOARD_MAXMEDIA_UB425_TC },
276262306a36Sopenharmony_ci	{ USB_DEVICE(0x1f4d, 0x1abe),
276362306a36Sopenharmony_ci			.driver_info = EM2860_BOARD_MYGICA_IGRABBER },
276462306a36Sopenharmony_ci	{ USB_DEVICE(0x2304, 0x0242),
276562306a36Sopenharmony_ci			.driver_info = EM2884_BOARD_PCTV_510E },
276662306a36Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x0251),
276762306a36Sopenharmony_ci			.driver_info = EM2884_BOARD_PCTV_520E },
276862306a36Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe1cc),
276962306a36Sopenharmony_ci			.driver_info = EM2874_BOARD_DELOCK_61959 },
277062306a36Sopenharmony_ci	{ USB_DEVICE(0x1ae7, 0x9003),
277162306a36Sopenharmony_ci			.driver_info = EM2765_BOARD_SPEEDLINK_VAD_LAPLACE },
277262306a36Sopenharmony_ci	{ USB_DEVICE(0x1ae7, 0x9004),
277362306a36Sopenharmony_ci			.driver_info = EM2765_BOARD_SPEEDLINK_VAD_LAPLACE },
277462306a36Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x0258),
277562306a36Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_461E },
277662306a36Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x8258), /* Bulk transport 461e */
277762306a36Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_461E },
277862306a36Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x0461),
277962306a36Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_461E_V2 },
278062306a36Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x8461), /* Bulk transport 461e v2 */
278162306a36Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_461E_V2 },
278262306a36Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x0259),
278362306a36Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_461E_V2 },
278462306a36Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x025f),
278562306a36Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_292E },
278662306a36Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x0264), /* Hauppauge WinTV-soloHD 292e SE */
278762306a36Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_292E },
278862306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x0264), /* Hauppauge WinTV-soloHD Isoc */
278962306a36Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_292E },
279062306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x8264), /* Hauppauge OEM Generic WinTV-soloHD Bulk */
279162306a36Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_292E },
279262306a36Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x8268), /* Hauppauge Retail WinTV-soloHD Bulk */
279362306a36Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_292E },
279462306a36Sopenharmony_ci	{ USB_DEVICE(0x0413, 0x6f07),
279562306a36Sopenharmony_ci			.driver_info = EM2861_BOARD_LEADTEK_VC100 },
279662306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x8179),
279762306a36Sopenharmony_ci			.driver_info = EM28178_BOARD_TERRATEC_T2_STICK_HD },
279862306a36Sopenharmony_ci	{ USB_DEVICE(0x3275, 0x0085),
279962306a36Sopenharmony_ci			.driver_info = EM28178_BOARD_PLEX_PX_BCUD },
280062306a36Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x5051), /* Ion Video 2 PC MKII / Startech svid2usb23 / Raygo R12-41373 */
280162306a36Sopenharmony_ci			.driver_info = EM2860_BOARD_TVP5150_REFERENCE_DESIGN },
280262306a36Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe349), /* Magix USB Videowandler-2 */
280362306a36Sopenharmony_ci		.driver_info = EM2861_BOARD_MAGIX_VIDEOWANDLER2 },
280462306a36Sopenharmony_ci	{ },
280562306a36Sopenharmony_ci};
280662306a36Sopenharmony_ciMODULE_DEVICE_TABLE(usb, em28xx_id_table);
280762306a36Sopenharmony_ci
280862306a36Sopenharmony_ci/*
280962306a36Sopenharmony_ci * EEPROM hash table for devices with generic USB IDs
281062306a36Sopenharmony_ci */
281162306a36Sopenharmony_cistatic const struct em28xx_hash_table em28xx_eeprom_hash[] = {
281262306a36Sopenharmony_ci	/* P/N: SA 60002070465 Tuner: TVF7533-MF */
281362306a36Sopenharmony_ci	{0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
281462306a36Sopenharmony_ci	{0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
281562306a36Sopenharmony_ci	{0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028},
281662306a36Sopenharmony_ci	{0x166a0441, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028},
281762306a36Sopenharmony_ci	{0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028},
281862306a36Sopenharmony_ci	{0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028},
281962306a36Sopenharmony_ci	{0x63f653bd, EM2870_BOARD_REDDO_DVB_C_USB_BOX, TUNER_ABSENT},
282062306a36Sopenharmony_ci	{0x4e913442, EM2882_BOARD_DIKOM_DK300, TUNER_XC2028},
282162306a36Sopenharmony_ci	{0x85dd871e, EM2882_BOARD_ZOLID_HYBRID_TV_STICK, TUNER_XC2028},
282262306a36Sopenharmony_ci};
282362306a36Sopenharmony_ci
282462306a36Sopenharmony_ci/* I2C devicelist hash table for devices with generic USB IDs */
282562306a36Sopenharmony_cistatic const struct em28xx_hash_table em28xx_i2c_hash[] = {
282662306a36Sopenharmony_ci	{0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
282762306a36Sopenharmony_ci	{0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
282862306a36Sopenharmony_ci	{0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT},
282962306a36Sopenharmony_ci	{0x77800080, EM2860_BOARD_TVP5150_REFERENCE_DESIGN, TUNER_ABSENT},
283062306a36Sopenharmony_ci	{0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
283162306a36Sopenharmony_ci	{0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF},
283262306a36Sopenharmony_ci	{0x6b800080, EM2874_BOARD_LEADERSHIP_ISDBT, TUNER_ABSENT},
283362306a36Sopenharmony_ci	{0x27e10080, EM2882_BOARD_ZOLID_HYBRID_TV_STICK, TUNER_XC2028},
283462306a36Sopenharmony_ci};
283562306a36Sopenharmony_ci
283662306a36Sopenharmony_ci/* NOTE: introduce a separate hash table for devices with 16 bit eeproms */
283762306a36Sopenharmony_ci
283862306a36Sopenharmony_ciint em28xx_tuner_callback(void *ptr, int component, int command, int arg)
283962306a36Sopenharmony_ci{
284062306a36Sopenharmony_ci	struct em28xx_i2c_bus *i2c_bus = ptr;
284162306a36Sopenharmony_ci	struct em28xx *dev = i2c_bus->dev;
284262306a36Sopenharmony_ci	int rc = 0;
284362306a36Sopenharmony_ci
284462306a36Sopenharmony_ci	if (dev->tuner_type != TUNER_XC2028 && dev->tuner_type != TUNER_XC5000)
284562306a36Sopenharmony_ci		return 0;
284662306a36Sopenharmony_ci
284762306a36Sopenharmony_ci	if (command != XC2028_TUNER_RESET && command != XC5000_TUNER_RESET)
284862306a36Sopenharmony_ci		return 0;
284962306a36Sopenharmony_ci
285062306a36Sopenharmony_ci	rc = em28xx_gpio_set(dev, dev->board.tuner_gpio);
285162306a36Sopenharmony_ci
285262306a36Sopenharmony_ci	return rc;
285362306a36Sopenharmony_ci}
285462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(em28xx_tuner_callback);
285562306a36Sopenharmony_ci
285662306a36Sopenharmony_cistatic inline void em28xx_set_xclk_i2c_speed(struct em28xx *dev)
285762306a36Sopenharmony_ci{
285862306a36Sopenharmony_ci	const struct em28xx_board *board = &em28xx_boards[dev->model];
285962306a36Sopenharmony_ci	u8 xclk = board->xclk, i2c_speed = board->i2c_speed;
286062306a36Sopenharmony_ci
286162306a36Sopenharmony_ci	/*
286262306a36Sopenharmony_ci	 * Those are the default values for the majority of boards
286362306a36Sopenharmony_ci	 * Use those values if not specified otherwise at boards entry
286462306a36Sopenharmony_ci	 */
286562306a36Sopenharmony_ci	if (!xclk)
286662306a36Sopenharmony_ci		xclk = EM28XX_XCLK_IR_RC5_MODE |
286762306a36Sopenharmony_ci		       EM28XX_XCLK_FREQUENCY_12MHZ;
286862306a36Sopenharmony_ci
286962306a36Sopenharmony_ci	em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk);
287062306a36Sopenharmony_ci
287162306a36Sopenharmony_ci	if (!i2c_speed)
287262306a36Sopenharmony_ci		i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE |
287362306a36Sopenharmony_ci			    EM28XX_I2C_FREQ_100_KHZ;
287462306a36Sopenharmony_ci
287562306a36Sopenharmony_ci	dev->i2c_speed = i2c_speed & 0x03;
287662306a36Sopenharmony_ci
287762306a36Sopenharmony_ci	if (!dev->board.is_em2800)
287862306a36Sopenharmony_ci		em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, i2c_speed);
287962306a36Sopenharmony_ci	msleep(50);
288062306a36Sopenharmony_ci}
288162306a36Sopenharmony_ci
288262306a36Sopenharmony_cistatic inline void em28xx_set_model(struct em28xx *dev)
288362306a36Sopenharmony_ci{
288462306a36Sopenharmony_ci	dev->board = em28xx_boards[dev->model];
288562306a36Sopenharmony_ci	dev->has_msp34xx = dev->board.has_msp34xx;
288662306a36Sopenharmony_ci	dev->is_webcam = dev->board.is_webcam;
288762306a36Sopenharmony_ci
288862306a36Sopenharmony_ci	em28xx_set_xclk_i2c_speed(dev);
288962306a36Sopenharmony_ci
289062306a36Sopenharmony_ci	/* Should be initialized early, for I2C to work */
289162306a36Sopenharmony_ci	dev->def_i2c_bus = dev->board.def_i2c_bus;
289262306a36Sopenharmony_ci}
289362306a36Sopenharmony_ci
289462306a36Sopenharmony_ci/*
289562306a36Sopenharmony_ci * Wait until AC97_RESET reports the expected value reliably before proceeding.
289662306a36Sopenharmony_ci * We also check that two unrelated registers accesses don't return the same
289762306a36Sopenharmony_ci * value to avoid premature return.
289862306a36Sopenharmony_ci * This procedure helps ensuring AC97 register accesses are reliable.
289962306a36Sopenharmony_ci */
290062306a36Sopenharmony_cistatic int em28xx_wait_until_ac97_features_equals(struct em28xx *dev,
290162306a36Sopenharmony_ci						  int expected_feat)
290262306a36Sopenharmony_ci{
290362306a36Sopenharmony_ci	unsigned long timeout = jiffies + msecs_to_jiffies(2000);
290462306a36Sopenharmony_ci	int feat, powerdown;
290562306a36Sopenharmony_ci
290662306a36Sopenharmony_ci	while (time_is_after_jiffies(timeout)) {
290762306a36Sopenharmony_ci		feat = em28xx_read_ac97(dev, AC97_RESET);
290862306a36Sopenharmony_ci		if (feat < 0)
290962306a36Sopenharmony_ci			return feat;
291062306a36Sopenharmony_ci
291162306a36Sopenharmony_ci		powerdown = em28xx_read_ac97(dev, AC97_POWERDOWN);
291262306a36Sopenharmony_ci		if (powerdown < 0)
291362306a36Sopenharmony_ci			return powerdown;
291462306a36Sopenharmony_ci
291562306a36Sopenharmony_ci		if (feat == expected_feat && feat != powerdown)
291662306a36Sopenharmony_ci			return 0;
291762306a36Sopenharmony_ci
291862306a36Sopenharmony_ci		msleep(50);
291962306a36Sopenharmony_ci	}
292062306a36Sopenharmony_ci
292162306a36Sopenharmony_ci	dev_warn(&dev->intf->dev, "AC97 registers access is not reliable !\n");
292262306a36Sopenharmony_ci	return -ETIMEDOUT;
292362306a36Sopenharmony_ci}
292462306a36Sopenharmony_ci
292562306a36Sopenharmony_ci/*
292662306a36Sopenharmony_ci * Since em28xx_pre_card_setup() requires a proper dev->model,
292762306a36Sopenharmony_ci * this won't work for boards with generic PCI IDs
292862306a36Sopenharmony_ci */
292962306a36Sopenharmony_cistatic void em28xx_pre_card_setup(struct em28xx *dev)
293062306a36Sopenharmony_ci{
293162306a36Sopenharmony_ci	/*
293262306a36Sopenharmony_ci	 * Set the initial XCLK and I2C clock values based on the board
293362306a36Sopenharmony_ci	 * definition
293462306a36Sopenharmony_ci	 */
293562306a36Sopenharmony_ci	em28xx_set_xclk_i2c_speed(dev);
293662306a36Sopenharmony_ci
293762306a36Sopenharmony_ci	/* request some modules */
293862306a36Sopenharmony_ci	switch (dev->model) {
293962306a36Sopenharmony_ci	case EM2861_BOARD_PLEXTOR_PX_TV100U:
294062306a36Sopenharmony_ci		/* Sets the msp34xx I2S speed */
294162306a36Sopenharmony_ci		dev->i2s_speed = 2048000;
294262306a36Sopenharmony_ci		break;
294362306a36Sopenharmony_ci	case EM2861_BOARD_KWORLD_PVRTV_300U:
294462306a36Sopenharmony_ci	case EM2880_BOARD_KWORLD_DVB_305U:
294562306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x6d);
294662306a36Sopenharmony_ci		usleep_range(10000, 11000);
294762306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x7d);
294862306a36Sopenharmony_ci		usleep_range(10000, 11000);
294962306a36Sopenharmony_ci		break;
295062306a36Sopenharmony_ci	case EM2870_BOARD_COMPRO_VIDEOMATE:
295162306a36Sopenharmony_ci		/*
295262306a36Sopenharmony_ci		 * TODO: someone can do some cleanup here...
295362306a36Sopenharmony_ci		 *	 not everything's needed
295462306a36Sopenharmony_ci		 */
295562306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2880_R04_GPO, 0x00);
295662306a36Sopenharmony_ci		usleep_range(10000, 11000);
295762306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2880_R04_GPO, 0x01);
295862306a36Sopenharmony_ci		usleep_range(10000, 11000);
295962306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
296062306a36Sopenharmony_ci		msleep(70);
296162306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfc);
296262306a36Sopenharmony_ci		msleep(70);
296362306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xdc);
296462306a36Sopenharmony_ci		msleep(70);
296562306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfc);
296662306a36Sopenharmony_ci		msleep(70);
296762306a36Sopenharmony_ci		break;
296862306a36Sopenharmony_ci	case EM2870_BOARD_TERRATEC_XS_MT2060:
296962306a36Sopenharmony_ci		/*
297062306a36Sopenharmony_ci		 * this device needs some gpio writes to get the DVB-T
297162306a36Sopenharmony_ci		 * demod work
297262306a36Sopenharmony_ci		 */
297362306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
297462306a36Sopenharmony_ci		msleep(70);
297562306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde);
297662306a36Sopenharmony_ci		msleep(70);
297762306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
297862306a36Sopenharmony_ci		msleep(70);
297962306a36Sopenharmony_ci		break;
298062306a36Sopenharmony_ci	case EM2870_BOARD_PINNACLE_PCTV_DVB:
298162306a36Sopenharmony_ci		/*
298262306a36Sopenharmony_ci		 * this device needs some gpio writes to get the
298362306a36Sopenharmony_ci		 * DVB-T demod work
298462306a36Sopenharmony_ci		 */
298562306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
298662306a36Sopenharmony_ci		msleep(70);
298762306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde);
298862306a36Sopenharmony_ci		msleep(70);
298962306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
299062306a36Sopenharmony_ci		msleep(70);
299162306a36Sopenharmony_ci		break;
299262306a36Sopenharmony_ci	case EM2820_BOARD_GADMEI_UTV310:
299362306a36Sopenharmony_ci	case EM2820_BOARD_MSI_VOX_USB_2:
299462306a36Sopenharmony_ci		/* enables audio for that devices */
299562306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
299662306a36Sopenharmony_ci		break;
299762306a36Sopenharmony_ci
299862306a36Sopenharmony_ci	case EM2882_BOARD_KWORLD_ATSC_315U:
299962306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
300062306a36Sopenharmony_ci		usleep_range(10000, 11000);
300162306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
300262306a36Sopenharmony_ci		usleep_range(10000, 11000);
300362306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2880_R04_GPO, 0x00);
300462306a36Sopenharmony_ci		usleep_range(10000, 11000);
300562306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2880_R04_GPO, 0x08);
300662306a36Sopenharmony_ci		usleep_range(10000, 11000);
300762306a36Sopenharmony_ci		break;
300862306a36Sopenharmony_ci
300962306a36Sopenharmony_ci	case EM2860_BOARD_KAIOMY_TVNPC_U2:
301062306a36Sopenharmony_ci		em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1);
301162306a36Sopenharmony_ci		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
301262306a36Sopenharmony_ci		em28xx_write_regs(dev, 0x0d, "\x42", 1);
301362306a36Sopenharmony_ci		em28xx_write_regs(dev, 0x08, "\xfd", 1);
301462306a36Sopenharmony_ci		usleep_range(10000, 11000);
301562306a36Sopenharmony_ci		em28xx_write_regs(dev, 0x08, "\xff", 1);
301662306a36Sopenharmony_ci		usleep_range(10000, 11000);
301762306a36Sopenharmony_ci		em28xx_write_regs(dev, 0x08, "\x7f", 1);
301862306a36Sopenharmony_ci		usleep_range(10000, 11000);
301962306a36Sopenharmony_ci		em28xx_write_regs(dev, 0x08, "\x6b", 1);
302062306a36Sopenharmony_ci
302162306a36Sopenharmony_ci		break;
302262306a36Sopenharmony_ci	case EM2860_BOARD_EASYCAP:
302362306a36Sopenharmony_ci		em28xx_write_regs(dev, 0x08, "\xf8", 1);
302462306a36Sopenharmony_ci		break;
302562306a36Sopenharmony_ci
302662306a36Sopenharmony_ci	case EM2820_BOARD_IODATA_GVMVP_SZ:
302762306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
302862306a36Sopenharmony_ci		msleep(70);
302962306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
303062306a36Sopenharmony_ci		usleep_range(10000, 11000);
303162306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
303262306a36Sopenharmony_ci		msleep(70);
303362306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
303462306a36Sopenharmony_ci		msleep(70);
303562306a36Sopenharmony_ci		break;
303662306a36Sopenharmony_ci
303762306a36Sopenharmony_ci	case EM2860_BOARD_TERRATEC_GRABBY:
303862306a36Sopenharmony_ci		/*
303962306a36Sopenharmony_ci		 * HACK?: Ensure AC97 register reading is reliable before
304062306a36Sopenharmony_ci		 * proceeding. In practice, this will wait about 1.6 seconds.
304162306a36Sopenharmony_ci		 */
304262306a36Sopenharmony_ci		em28xx_wait_until_ac97_features_equals(dev, 0x6a90);
304362306a36Sopenharmony_ci		break;
304462306a36Sopenharmony_ci	}
304562306a36Sopenharmony_ci
304662306a36Sopenharmony_ci	em28xx_gpio_set(dev, dev->board.tuner_gpio);
304762306a36Sopenharmony_ci	em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
304862306a36Sopenharmony_ci
304962306a36Sopenharmony_ci	/* Unlock device */
305062306a36Sopenharmony_ci	em28xx_set_mode(dev, EM28XX_SUSPEND);
305162306a36Sopenharmony_ci}
305262306a36Sopenharmony_ci
305362306a36Sopenharmony_cistatic int em28xx_hint_board(struct em28xx *dev)
305462306a36Sopenharmony_ci{
305562306a36Sopenharmony_ci	int i;
305662306a36Sopenharmony_ci
305762306a36Sopenharmony_ci	if (dev->is_webcam) {
305862306a36Sopenharmony_ci		if (dev->em28xx_sensor == EM28XX_MT9V011) {
305962306a36Sopenharmony_ci			dev->model = EM2820_BOARD_SILVERCREST_WEBCAM;
306062306a36Sopenharmony_ci		} else if (dev->em28xx_sensor == EM28XX_MT9M001 ||
306162306a36Sopenharmony_ci			   dev->em28xx_sensor == EM28XX_MT9M111) {
306262306a36Sopenharmony_ci			dev->model = EM2750_BOARD_UNKNOWN;
306362306a36Sopenharmony_ci		}
306462306a36Sopenharmony_ci		/* FIXME: IMPROVE ! */
306562306a36Sopenharmony_ci
306662306a36Sopenharmony_ci		return 0;
306762306a36Sopenharmony_ci	}
306862306a36Sopenharmony_ci
306962306a36Sopenharmony_ci	/*
307062306a36Sopenharmony_ci	 * HINT method: EEPROM
307162306a36Sopenharmony_ci	 *
307262306a36Sopenharmony_ci	 * This method works only for boards with eeprom.
307362306a36Sopenharmony_ci	 * Uses a hash of all eeprom bytes. The hash should be
307462306a36Sopenharmony_ci	 * unique for a vendor/tuner pair.
307562306a36Sopenharmony_ci	 * There are a high chance that tuners for different
307662306a36Sopenharmony_ci	 * video standards produce different hashes.
307762306a36Sopenharmony_ci	 */
307862306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(em28xx_eeprom_hash); i++) {
307962306a36Sopenharmony_ci		if (dev->hash == em28xx_eeprom_hash[i].hash) {
308062306a36Sopenharmony_ci			dev->model = em28xx_eeprom_hash[i].model;
308162306a36Sopenharmony_ci			dev->tuner_type = em28xx_eeprom_hash[i].tuner;
308262306a36Sopenharmony_ci
308362306a36Sopenharmony_ci			dev_err(&dev->intf->dev,
308462306a36Sopenharmony_ci				"Your board has no unique USB ID.\n"
308562306a36Sopenharmony_ci				"A hint were successfully done, based on eeprom hash.\n"
308662306a36Sopenharmony_ci				"This method is not 100%% failproof.\n"
308762306a36Sopenharmony_ci				"If the board were misdetected, please email this log to:\n"
308862306a36Sopenharmony_ci				"\tV4L Mailing List  <linux-media@vger.kernel.org>\n"
308962306a36Sopenharmony_ci				"Board detected as %s\n",
309062306a36Sopenharmony_ci			       em28xx_boards[dev->model].name);
309162306a36Sopenharmony_ci
309262306a36Sopenharmony_ci			return 0;
309362306a36Sopenharmony_ci		}
309462306a36Sopenharmony_ci	}
309562306a36Sopenharmony_ci
309662306a36Sopenharmony_ci	/*
309762306a36Sopenharmony_ci	 * HINT method: I2C attached devices
309862306a36Sopenharmony_ci	 *
309962306a36Sopenharmony_ci	 * This method works for all boards.
310062306a36Sopenharmony_ci	 * Uses a hash of i2c scanned devices.
310162306a36Sopenharmony_ci	 * Devices with the same i2c attached chips will
310262306a36Sopenharmony_ci	 * be considered equal.
310362306a36Sopenharmony_ci	 * This method is less precise than the eeprom one.
310462306a36Sopenharmony_ci	 */
310562306a36Sopenharmony_ci
310662306a36Sopenharmony_ci	/* user did not request i2c scanning => do it now */
310762306a36Sopenharmony_ci	if (!dev->i2c_hash)
310862306a36Sopenharmony_ci		em28xx_do_i2c_scan(dev, dev->def_i2c_bus);
310962306a36Sopenharmony_ci
311062306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(em28xx_i2c_hash); i++) {
311162306a36Sopenharmony_ci		if (dev->i2c_hash == em28xx_i2c_hash[i].hash) {
311262306a36Sopenharmony_ci			dev->model = em28xx_i2c_hash[i].model;
311362306a36Sopenharmony_ci			dev->tuner_type = em28xx_i2c_hash[i].tuner;
311462306a36Sopenharmony_ci			dev_err(&dev->intf->dev,
311562306a36Sopenharmony_ci				"Your board has no unique USB ID.\n"
311662306a36Sopenharmony_ci				"A hint were successfully done, based on i2c devicelist hash.\n"
311762306a36Sopenharmony_ci				"This method is not 100%% failproof.\n"
311862306a36Sopenharmony_ci				"If the board were misdetected, please email this log to:\n"
311962306a36Sopenharmony_ci				"\tV4L Mailing List  <linux-media@vger.kernel.org>\n"
312062306a36Sopenharmony_ci				"Board detected as %s\n",
312162306a36Sopenharmony_ci				em28xx_boards[dev->model].name);
312262306a36Sopenharmony_ci
312362306a36Sopenharmony_ci			return 0;
312462306a36Sopenharmony_ci		}
312562306a36Sopenharmony_ci	}
312662306a36Sopenharmony_ci
312762306a36Sopenharmony_ci	dev_err(&dev->intf->dev,
312862306a36Sopenharmony_ci		"Your board has no unique USB ID and thus need a hint to be detected.\n"
312962306a36Sopenharmony_ci		"You may try to use card=<n> insmod option to workaround that.\n"
313062306a36Sopenharmony_ci		"Please send an email with this log to:\n"
313162306a36Sopenharmony_ci		"\tV4L Mailing List <linux-media@vger.kernel.org>\n"
313262306a36Sopenharmony_ci		"Board eeprom hash is 0x%08lx\n"
313362306a36Sopenharmony_ci		"Board i2c devicelist hash is 0x%08lx\n",
313462306a36Sopenharmony_ci		dev->hash, dev->i2c_hash);
313562306a36Sopenharmony_ci
313662306a36Sopenharmony_ci	dev_err(&dev->intf->dev,
313762306a36Sopenharmony_ci		"Here is a list of valid choices for the card=<n> insmod option:\n");
313862306a36Sopenharmony_ci	for (i = 0; i < em28xx_bcount; i++) {
313962306a36Sopenharmony_ci		dev_err(&dev->intf->dev,
314062306a36Sopenharmony_ci			"    card=%d -> %s\n", i, em28xx_boards[i].name);
314162306a36Sopenharmony_ci	}
314262306a36Sopenharmony_ci	return -1;
314362306a36Sopenharmony_ci}
314462306a36Sopenharmony_ci
314562306a36Sopenharmony_cistatic void em28xx_card_setup(struct em28xx *dev)
314662306a36Sopenharmony_ci{
314762306a36Sopenharmony_ci	int i, j, idx;
314862306a36Sopenharmony_ci	bool duplicate_entry;
314962306a36Sopenharmony_ci
315062306a36Sopenharmony_ci	/*
315162306a36Sopenharmony_ci	 * If the device can be a webcam, seek for a sensor.
315262306a36Sopenharmony_ci	 * If sensor is not found, then it isn't a webcam.
315362306a36Sopenharmony_ci	 */
315462306a36Sopenharmony_ci	if (dev->is_webcam) {
315562306a36Sopenharmony_ci		em28xx_detect_sensor(dev);
315662306a36Sopenharmony_ci		if (dev->em28xx_sensor == EM28XX_NOSENSOR)
315762306a36Sopenharmony_ci			/* NOTE: error/unknown sensor/no sensor */
315862306a36Sopenharmony_ci			dev->is_webcam = 0;
315962306a36Sopenharmony_ci	}
316062306a36Sopenharmony_ci
316162306a36Sopenharmony_ci	switch (dev->model) {
316262306a36Sopenharmony_ci	case EM2750_BOARD_UNKNOWN:
316362306a36Sopenharmony_ci	case EM2820_BOARD_UNKNOWN:
316462306a36Sopenharmony_ci	case EM2800_BOARD_UNKNOWN:
316562306a36Sopenharmony_ci		/*
316662306a36Sopenharmony_ci		 * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD.
316762306a36Sopenharmony_ci		 *
316862306a36Sopenharmony_ci		 * This occurs because they share identical USB vendor and
316962306a36Sopenharmony_ci		 * product IDs.
317062306a36Sopenharmony_ci		 *
317162306a36Sopenharmony_ci		 * What we do here is look up the EEPROM hash of the K-WORLD
317262306a36Sopenharmony_ci		 * and if it is found then we decide that we do not have
317362306a36Sopenharmony_ci		 * a DIGIVOX and reset the device to the K-WORLD instead.
317462306a36Sopenharmony_ci		 *
317562306a36Sopenharmony_ci		 * This solution is only valid if they do not share eeprom
317662306a36Sopenharmony_ci		 * hash identities which has not been determined as yet.
317762306a36Sopenharmony_ci		 */
317862306a36Sopenharmony_ci		if (em28xx_hint_board(dev) < 0) {
317962306a36Sopenharmony_ci			dev_err(&dev->intf->dev, "Board not discovered\n");
318062306a36Sopenharmony_ci		} else {
318162306a36Sopenharmony_ci			em28xx_set_model(dev);
318262306a36Sopenharmony_ci			em28xx_pre_card_setup(dev);
318362306a36Sopenharmony_ci		}
318462306a36Sopenharmony_ci		break;
318562306a36Sopenharmony_ci	default:
318662306a36Sopenharmony_ci		em28xx_set_model(dev);
318762306a36Sopenharmony_ci	}
318862306a36Sopenharmony_ci
318962306a36Sopenharmony_ci	dev_info(&dev->intf->dev, "Identified as %s (card=%d)\n",
319062306a36Sopenharmony_ci		 dev->board.name, dev->model);
319162306a36Sopenharmony_ci
319262306a36Sopenharmony_ci	dev->tuner_type = em28xx_boards[dev->model].tuner_type;
319362306a36Sopenharmony_ci
319462306a36Sopenharmony_ci	/* request some modules */
319562306a36Sopenharmony_ci	switch (dev->model) {
319662306a36Sopenharmony_ci	case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
319762306a36Sopenharmony_ci	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
319862306a36Sopenharmony_ci	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
319962306a36Sopenharmony_ci	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
320062306a36Sopenharmony_ci	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
320162306a36Sopenharmony_ci	case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C:
320262306a36Sopenharmony_ci	case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB:
320362306a36Sopenharmony_ci	case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595:
320462306a36Sopenharmony_ci	{
320562306a36Sopenharmony_ci		struct tveeprom tv;
320662306a36Sopenharmony_ci
320762306a36Sopenharmony_ci		if (!dev->eedata)
320862306a36Sopenharmony_ci			break;
320962306a36Sopenharmony_ci#if defined(CONFIG_MODULES) && defined(MODULE)
321062306a36Sopenharmony_ci		request_module("tveeprom");
321162306a36Sopenharmony_ci#endif
321262306a36Sopenharmony_ci		/* Call first TVeeprom */
321362306a36Sopenharmony_ci
321462306a36Sopenharmony_ci		tveeprom_hauppauge_analog(&tv, dev->eedata);
321562306a36Sopenharmony_ci
321662306a36Sopenharmony_ci		dev->tuner_type = tv.tuner_type;
321762306a36Sopenharmony_ci
321862306a36Sopenharmony_ci		if (tv.audio_processor == TVEEPROM_AUDPROC_MSP) {
321962306a36Sopenharmony_ci			dev->i2s_speed = 2048000;
322062306a36Sopenharmony_ci			dev->has_msp34xx = 1;
322162306a36Sopenharmony_ci		}
322262306a36Sopenharmony_ci		break;
322362306a36Sopenharmony_ci	}
322462306a36Sopenharmony_ci	case EM2882_BOARD_KWORLD_ATSC_315U:
322562306a36Sopenharmony_ci		em28xx_write_reg(dev, 0x0d, 0x42);
322662306a36Sopenharmony_ci		usleep_range(10000, 11000);
322762306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
322862306a36Sopenharmony_ci		usleep_range(10000, 11000);
322962306a36Sopenharmony_ci		break;
323062306a36Sopenharmony_ci	case EM2820_BOARD_KWORLD_PVRTV2800RF:
323162306a36Sopenharmony_ci		/* GPIO enables sound on KWORLD PVR TV 2800RF */
323262306a36Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf9);
323362306a36Sopenharmony_ci		break;
323462306a36Sopenharmony_ci	case EM2820_BOARD_UNKNOWN:
323562306a36Sopenharmony_ci	case EM2800_BOARD_UNKNOWN:
323662306a36Sopenharmony_ci		/*
323762306a36Sopenharmony_ci		 * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD.
323862306a36Sopenharmony_ci		 *
323962306a36Sopenharmony_ci		 * This occurs because they share identical USB vendor and
324062306a36Sopenharmony_ci		 * product IDs.
324162306a36Sopenharmony_ci		 *
324262306a36Sopenharmony_ci		 * What we do here is look up the EEPROM hash of the K-WORLD
324362306a36Sopenharmony_ci		 * and if it is found then we decide that we do not have
324462306a36Sopenharmony_ci		 * a DIGIVOX and reset the device to the K-WORLD instead.
324562306a36Sopenharmony_ci		 *
324662306a36Sopenharmony_ci		 * This solution is only valid if they do not share eeprom
324762306a36Sopenharmony_ci		 * hash identities which has not been determined as yet.
324862306a36Sopenharmony_ci		 */
324962306a36Sopenharmony_ci	case EM2880_BOARD_MSI_DIGIVOX_AD:
325062306a36Sopenharmony_ci		if (!em28xx_hint_board(dev))
325162306a36Sopenharmony_ci			em28xx_set_model(dev);
325262306a36Sopenharmony_ci
325362306a36Sopenharmony_ci		/*
325462306a36Sopenharmony_ci		 * In cases where we had to use a board hint, the call to
325562306a36Sopenharmony_ci		 * em28xx_set_mode() in em28xx_pre_card_setup() was a no-op,
325662306a36Sopenharmony_ci		 * so make the call now so the analog GPIOs are set properly
325762306a36Sopenharmony_ci		 * before probing the i2c bus.
325862306a36Sopenharmony_ci		 */
325962306a36Sopenharmony_ci		em28xx_gpio_set(dev, dev->board.tuner_gpio);
326062306a36Sopenharmony_ci		em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
326162306a36Sopenharmony_ci		break;
326262306a36Sopenharmony_ci
326362306a36Sopenharmony_ci		/*
326462306a36Sopenharmony_ci		 * The Dikom DK300 is detected as an Kworld VS-DVB-T 323UR.
326562306a36Sopenharmony_ci		 *
326662306a36Sopenharmony_ci		 * This occurs because they share identical USB vendor and
326762306a36Sopenharmony_ci		 * product IDs.
326862306a36Sopenharmony_ci		 *
326962306a36Sopenharmony_ci		 * What we do here is look up the EEPROM hash of the Dikom
327062306a36Sopenharmony_ci		 * and if it is found then we decide that we do not have
327162306a36Sopenharmony_ci		 * a Kworld and reset the device to the Dikom instead.
327262306a36Sopenharmony_ci		 *
327362306a36Sopenharmony_ci		 * This solution is only valid if they do not share eeprom
327462306a36Sopenharmony_ci		 * hash identities which has not been determined as yet.
327562306a36Sopenharmony_ci		 */
327662306a36Sopenharmony_ci	case EM2882_BOARD_KWORLD_VS_DVBT:
327762306a36Sopenharmony_ci		if (!em28xx_hint_board(dev))
327862306a36Sopenharmony_ci			em28xx_set_model(dev);
327962306a36Sopenharmony_ci
328062306a36Sopenharmony_ci		/*
328162306a36Sopenharmony_ci		 * In cases where we had to use a board hint, the call to
328262306a36Sopenharmony_ci		 * em28xx_set_mode() in em28xx_pre_card_setup() was a no-op,
328362306a36Sopenharmony_ci		 * so make the call now so the analog GPIOs are set properly
328462306a36Sopenharmony_ci		 * before probing the i2c bus.
328562306a36Sopenharmony_ci		 */
328662306a36Sopenharmony_ci		em28xx_gpio_set(dev, dev->board.tuner_gpio);
328762306a36Sopenharmony_ci		em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
328862306a36Sopenharmony_ci		break;
328962306a36Sopenharmony_ci	}
329062306a36Sopenharmony_ci
329162306a36Sopenharmony_ci	if (dev->board.valid == EM28XX_BOARD_NOT_VALIDATED) {
329262306a36Sopenharmony_ci		dev_err(&dev->intf->dev,
329362306a36Sopenharmony_ci			"\n\n"
329462306a36Sopenharmony_ci			"The support for this board weren't valid yet.\n"
329562306a36Sopenharmony_ci			"Please send a report of having this working\n"
329662306a36Sopenharmony_ci			"not to V4L mailing list (and/or to other addresses)\n\n");
329762306a36Sopenharmony_ci	}
329862306a36Sopenharmony_ci
329962306a36Sopenharmony_ci	/* Free eeprom data memory */
330062306a36Sopenharmony_ci	kfree(dev->eedata);
330162306a36Sopenharmony_ci	dev->eedata = NULL;
330262306a36Sopenharmony_ci
330362306a36Sopenharmony_ci	/* Allow override tuner type by a module parameter */
330462306a36Sopenharmony_ci	if (tuner >= 0)
330562306a36Sopenharmony_ci		dev->tuner_type = tuner;
330662306a36Sopenharmony_ci
330762306a36Sopenharmony_ci	/*
330862306a36Sopenharmony_ci	 * Dynamically generate a list of valid audio inputs for this
330962306a36Sopenharmony_ci	 * specific board, mapping them via enum em28xx_amux.
331062306a36Sopenharmony_ci	 */
331162306a36Sopenharmony_ci
331262306a36Sopenharmony_ci	idx = 0;
331362306a36Sopenharmony_ci	for (i = 0; i < MAX_EM28XX_INPUT; i++) {
331462306a36Sopenharmony_ci		if (!INPUT(i)->type)
331562306a36Sopenharmony_ci			continue;
331662306a36Sopenharmony_ci
331762306a36Sopenharmony_ci		/* Skip already mapped audio inputs */
331862306a36Sopenharmony_ci		duplicate_entry = false;
331962306a36Sopenharmony_ci		for (j = 0; j < idx; j++) {
332062306a36Sopenharmony_ci			if (INPUT(i)->amux == dev->amux_map[j]) {
332162306a36Sopenharmony_ci				duplicate_entry = true;
332262306a36Sopenharmony_ci				break;
332362306a36Sopenharmony_ci			}
332462306a36Sopenharmony_ci		}
332562306a36Sopenharmony_ci		if (duplicate_entry)
332662306a36Sopenharmony_ci			continue;
332762306a36Sopenharmony_ci
332862306a36Sopenharmony_ci		dev->amux_map[idx++] = INPUT(i)->amux;
332962306a36Sopenharmony_ci	}
333062306a36Sopenharmony_ci	for (; idx < MAX_EM28XX_INPUT; idx++)
333162306a36Sopenharmony_ci		dev->amux_map[idx] = EM28XX_AMUX_UNUSED;
333262306a36Sopenharmony_ci}
333362306a36Sopenharmony_ci
333462306a36Sopenharmony_civoid em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
333562306a36Sopenharmony_ci{
333662306a36Sopenharmony_ci	memset(ctl, 0, sizeof(*ctl));
333762306a36Sopenharmony_ci
333862306a36Sopenharmony_ci	ctl->fname   = XC2028_DEFAULT_FIRMWARE;
333962306a36Sopenharmony_ci	ctl->max_len = 64;
334062306a36Sopenharmony_ci	ctl->mts = em28xx_boards[dev->model].mts_firmware;
334162306a36Sopenharmony_ci
334262306a36Sopenharmony_ci	switch (dev->model) {
334362306a36Sopenharmony_ci	case EM2880_BOARD_EMPIRE_DUAL_TV:
334462306a36Sopenharmony_ci	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
334562306a36Sopenharmony_ci	case EM2882_BOARD_TERRATEC_HYBRID_XS:
334662306a36Sopenharmony_ci	case EM2880_BOARD_TERRATEC_HYBRID_XS:
334762306a36Sopenharmony_ci	case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
334862306a36Sopenharmony_ci	case EM2881_BOARD_PINNACLE_HYBRID_PRO:
334962306a36Sopenharmony_ci	case EM2882_BOARD_ZOLID_HYBRID_TV_STICK:
335062306a36Sopenharmony_ci		ctl->demod = XC3028_FE_ZARLINK456;
335162306a36Sopenharmony_ci		break;
335262306a36Sopenharmony_ci	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
335362306a36Sopenharmony_ci	case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E:
335462306a36Sopenharmony_ci		ctl->demod = XC3028_FE_DEFAULT;
335562306a36Sopenharmony_ci		break;
335662306a36Sopenharmony_ci	case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
335762306a36Sopenharmony_ci		ctl->demod = XC3028_FE_DEFAULT;
335862306a36Sopenharmony_ci		ctl->fname = XC3028L_DEFAULT_FIRMWARE;
335962306a36Sopenharmony_ci		break;
336062306a36Sopenharmony_ci	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
336162306a36Sopenharmony_ci	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
336262306a36Sopenharmony_ci	case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
336362306a36Sopenharmony_ci		/* FIXME: Better to specify the needed IF */
336462306a36Sopenharmony_ci		ctl->demod = XC3028_FE_DEFAULT;
336562306a36Sopenharmony_ci		break;
336662306a36Sopenharmony_ci	case EM2883_BOARD_KWORLD_HYBRID_330U:
336762306a36Sopenharmony_ci	case EM2882_BOARD_DIKOM_DK300:
336862306a36Sopenharmony_ci	case EM2882_BOARD_KWORLD_VS_DVBT:
336962306a36Sopenharmony_ci		ctl->demod = XC3028_FE_CHINA;
337062306a36Sopenharmony_ci		ctl->fname = XC2028_DEFAULT_FIRMWARE;
337162306a36Sopenharmony_ci		break;
337262306a36Sopenharmony_ci	case EM2882_BOARD_EVGA_INDTUBE:
337362306a36Sopenharmony_ci		ctl->demod = XC3028_FE_CHINA;
337462306a36Sopenharmony_ci		ctl->fname = XC3028L_DEFAULT_FIRMWARE;
337562306a36Sopenharmony_ci		break;
337662306a36Sopenharmony_ci	default:
337762306a36Sopenharmony_ci		ctl->demod = XC3028_FE_OREN538;
337862306a36Sopenharmony_ci	}
337962306a36Sopenharmony_ci}
338062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(em28xx_setup_xc3028);
338162306a36Sopenharmony_ci
338262306a36Sopenharmony_cistatic void request_module_async(struct work_struct *work)
338362306a36Sopenharmony_ci{
338462306a36Sopenharmony_ci	struct em28xx *dev = container_of(work,
338562306a36Sopenharmony_ci			     struct em28xx, request_module_wk);
338662306a36Sopenharmony_ci
338762306a36Sopenharmony_ci	/*
338862306a36Sopenharmony_ci	 * The em28xx extensions can be modules or builtin. If the
338962306a36Sopenharmony_ci	 * modules are already loaded or are built in, those extensions
339062306a36Sopenharmony_ci	 * can be initialised right now. Otherwise, the module init
339162306a36Sopenharmony_ci	 * code will do it.
339262306a36Sopenharmony_ci	 */
339362306a36Sopenharmony_ci
339462306a36Sopenharmony_ci	/*
339562306a36Sopenharmony_ci	 * Devices with an audio-only intf also have a V4L/DVB/RC
339662306a36Sopenharmony_ci	 * intf. Don't register extensions twice on those devices.
339762306a36Sopenharmony_ci	 */
339862306a36Sopenharmony_ci	if (dev->is_audio_only) {
339962306a36Sopenharmony_ci#if defined(CONFIG_MODULES) && defined(MODULE)
340062306a36Sopenharmony_ci		request_module("em28xx-alsa");
340162306a36Sopenharmony_ci#endif
340262306a36Sopenharmony_ci		return;
340362306a36Sopenharmony_ci	}
340462306a36Sopenharmony_ci
340562306a36Sopenharmony_ci	em28xx_init_extension(dev);
340662306a36Sopenharmony_ci
340762306a36Sopenharmony_ci#if defined(CONFIG_MODULES) && defined(MODULE)
340862306a36Sopenharmony_ci	if (dev->has_video)
340962306a36Sopenharmony_ci		request_module("em28xx-v4l");
341062306a36Sopenharmony_ci	if (dev->usb_audio_type == EM28XX_USB_AUDIO_CLASS)
341162306a36Sopenharmony_ci		request_module("snd-usb-audio");
341262306a36Sopenharmony_ci	else if (dev->usb_audio_type == EM28XX_USB_AUDIO_VENDOR)
341362306a36Sopenharmony_ci		request_module("em28xx-alsa");
341462306a36Sopenharmony_ci	if (dev->board.has_dvb)
341562306a36Sopenharmony_ci		request_module("em28xx-dvb");
341662306a36Sopenharmony_ci	if (dev->board.buttons ||
341762306a36Sopenharmony_ci	    ((dev->board.ir_codes || dev->board.has_ir_i2c) && !disable_ir))
341862306a36Sopenharmony_ci		request_module("em28xx-rc");
341962306a36Sopenharmony_ci#endif /* CONFIG_MODULES */
342062306a36Sopenharmony_ci}
342162306a36Sopenharmony_ci
342262306a36Sopenharmony_cistatic void request_modules(struct em28xx *dev)
342362306a36Sopenharmony_ci{
342462306a36Sopenharmony_ci	INIT_WORK(&dev->request_module_wk, request_module_async);
342562306a36Sopenharmony_ci	schedule_work(&dev->request_module_wk);
342662306a36Sopenharmony_ci}
342762306a36Sopenharmony_ci
342862306a36Sopenharmony_cistatic void flush_request_modules(struct em28xx *dev)
342962306a36Sopenharmony_ci{
343062306a36Sopenharmony_ci	flush_work(&dev->request_module_wk);
343162306a36Sopenharmony_ci}
343262306a36Sopenharmony_ci
343362306a36Sopenharmony_cistatic int em28xx_media_device_init(struct em28xx *dev,
343462306a36Sopenharmony_ci				    struct usb_device *udev)
343562306a36Sopenharmony_ci{
343662306a36Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER
343762306a36Sopenharmony_ci	struct media_device *mdev;
343862306a36Sopenharmony_ci
343962306a36Sopenharmony_ci	mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
344062306a36Sopenharmony_ci	if (!mdev)
344162306a36Sopenharmony_ci		return -ENOMEM;
344262306a36Sopenharmony_ci
344362306a36Sopenharmony_ci	if (udev->product)
344462306a36Sopenharmony_ci		media_device_usb_init(mdev, udev, udev->product);
344562306a36Sopenharmony_ci	else if (udev->manufacturer)
344662306a36Sopenharmony_ci		media_device_usb_init(mdev, udev, udev->manufacturer);
344762306a36Sopenharmony_ci	else
344862306a36Sopenharmony_ci		media_device_usb_init(mdev, udev, dev_name(&dev->intf->dev));
344962306a36Sopenharmony_ci
345062306a36Sopenharmony_ci	dev->media_dev = mdev;
345162306a36Sopenharmony_ci#endif
345262306a36Sopenharmony_ci	return 0;
345362306a36Sopenharmony_ci}
345462306a36Sopenharmony_ci
345562306a36Sopenharmony_cistatic void em28xx_unregister_media_device(struct em28xx *dev)
345662306a36Sopenharmony_ci{
345762306a36Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER
345862306a36Sopenharmony_ci	if (dev->media_dev) {
345962306a36Sopenharmony_ci		media_device_unregister(dev->media_dev);
346062306a36Sopenharmony_ci		media_device_cleanup(dev->media_dev);
346162306a36Sopenharmony_ci		kfree(dev->media_dev);
346262306a36Sopenharmony_ci		dev->media_dev = NULL;
346362306a36Sopenharmony_ci	}
346462306a36Sopenharmony_ci#endif
346562306a36Sopenharmony_ci}
346662306a36Sopenharmony_ci
346762306a36Sopenharmony_ci/*
346862306a36Sopenharmony_ci * em28xx_release_resources()
346962306a36Sopenharmony_ci * unregisters the v4l2,i2c and usb devices
347062306a36Sopenharmony_ci * called when the device gets disconnected or at module unload
347162306a36Sopenharmony_ci */
347262306a36Sopenharmony_cistatic void em28xx_release_resources(struct em28xx *dev)
347362306a36Sopenharmony_ci{
347462306a36Sopenharmony_ci	struct usb_device *udev = interface_to_usbdev(dev->intf);
347562306a36Sopenharmony_ci
347662306a36Sopenharmony_ci	/*FIXME: I2C IR should be disconnected */
347762306a36Sopenharmony_ci
347862306a36Sopenharmony_ci	mutex_lock(&dev->lock);
347962306a36Sopenharmony_ci
348062306a36Sopenharmony_ci	em28xx_unregister_media_device(dev);
348162306a36Sopenharmony_ci
348262306a36Sopenharmony_ci	if (dev->def_i2c_bus)
348362306a36Sopenharmony_ci		em28xx_i2c_unregister(dev, 1);
348462306a36Sopenharmony_ci	em28xx_i2c_unregister(dev, 0);
348562306a36Sopenharmony_ci
348662306a36Sopenharmony_ci	if (dev->ts == PRIMARY_TS)
348762306a36Sopenharmony_ci		usb_put_dev(udev);
348862306a36Sopenharmony_ci
348962306a36Sopenharmony_ci	/* Mark device as unused */
349062306a36Sopenharmony_ci	clear_bit(dev->devno, em28xx_devused);
349162306a36Sopenharmony_ci
349262306a36Sopenharmony_ci	mutex_unlock(&dev->lock);
349362306a36Sopenharmony_ci};
349462306a36Sopenharmony_ci
349562306a36Sopenharmony_ci/**
349662306a36Sopenharmony_ci * em28xx_free_device() - Free em28xx device
349762306a36Sopenharmony_ci *
349862306a36Sopenharmony_ci * @ref: struct kref for em28xx device
349962306a36Sopenharmony_ci *
350062306a36Sopenharmony_ci * This is called when all extensions and em28xx core unregisters a device
350162306a36Sopenharmony_ci */
350262306a36Sopenharmony_civoid em28xx_free_device(struct kref *ref)
350362306a36Sopenharmony_ci{
350462306a36Sopenharmony_ci	struct em28xx *dev = kref_to_dev(ref);
350562306a36Sopenharmony_ci
350662306a36Sopenharmony_ci	dev_info(&dev->intf->dev, "Freeing device\n");
350762306a36Sopenharmony_ci
350862306a36Sopenharmony_ci	if (!dev->disconnected)
350962306a36Sopenharmony_ci		em28xx_release_resources(dev);
351062306a36Sopenharmony_ci
351162306a36Sopenharmony_ci	if (dev->ts == PRIMARY_TS)
351262306a36Sopenharmony_ci		kfree(dev->alt_max_pkt_size_isoc);
351362306a36Sopenharmony_ci
351462306a36Sopenharmony_ci	kfree(dev);
351562306a36Sopenharmony_ci}
351662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(em28xx_free_device);
351762306a36Sopenharmony_ci
351862306a36Sopenharmony_ci/*
351962306a36Sopenharmony_ci * em28xx_init_dev()
352062306a36Sopenharmony_ci * allocates and inits the device structs, registers i2c bus and v4l device
352162306a36Sopenharmony_ci */
352262306a36Sopenharmony_cistatic int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
352362306a36Sopenharmony_ci			   struct usb_interface *intf,
352462306a36Sopenharmony_ci			   int minor)
352562306a36Sopenharmony_ci{
352662306a36Sopenharmony_ci	int retval;
352762306a36Sopenharmony_ci	const char *chip_name = NULL;
352862306a36Sopenharmony_ci
352962306a36Sopenharmony_ci	dev->intf = intf;
353062306a36Sopenharmony_ci	mutex_init(&dev->ctrl_urb_lock);
353162306a36Sopenharmony_ci	spin_lock_init(&dev->slock);
353262306a36Sopenharmony_ci
353362306a36Sopenharmony_ci	dev->em28xx_write_regs = em28xx_write_regs;
353462306a36Sopenharmony_ci	dev->em28xx_read_reg = em28xx_read_reg;
353562306a36Sopenharmony_ci	dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len;
353662306a36Sopenharmony_ci	dev->em28xx_write_regs_req = em28xx_write_regs_req;
353762306a36Sopenharmony_ci	dev->em28xx_read_reg_req = em28xx_read_reg_req;
353862306a36Sopenharmony_ci	dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
353962306a36Sopenharmony_ci
354062306a36Sopenharmony_ci	em28xx_set_model(dev);
354162306a36Sopenharmony_ci
354262306a36Sopenharmony_ci	dev->wait_after_write = 5;
354362306a36Sopenharmony_ci
354462306a36Sopenharmony_ci	/* Based on the Chip ID, set the device configuration */
354562306a36Sopenharmony_ci	retval = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
354662306a36Sopenharmony_ci	if (retval > 0) {
354762306a36Sopenharmony_ci		dev->chip_id = retval;
354862306a36Sopenharmony_ci
354962306a36Sopenharmony_ci		switch (dev->chip_id) {
355062306a36Sopenharmony_ci		case CHIP_ID_EM2800:
355162306a36Sopenharmony_ci			chip_name = "em2800";
355262306a36Sopenharmony_ci			break;
355362306a36Sopenharmony_ci		case CHIP_ID_EM2710:
355462306a36Sopenharmony_ci			chip_name = "em2710";
355562306a36Sopenharmony_ci			break;
355662306a36Sopenharmony_ci		case CHIP_ID_EM2750:
355762306a36Sopenharmony_ci			chip_name = "em2750";
355862306a36Sopenharmony_ci			break;
355962306a36Sopenharmony_ci		case CHIP_ID_EM2765:
356062306a36Sopenharmony_ci			chip_name = "em2765";
356162306a36Sopenharmony_ci			dev->wait_after_write = 0;
356262306a36Sopenharmony_ci			dev->is_em25xx = 1;
356362306a36Sopenharmony_ci			dev->eeprom_addrwidth_16bit = 1;
356462306a36Sopenharmony_ci			break;
356562306a36Sopenharmony_ci		case CHIP_ID_EM2820:
356662306a36Sopenharmony_ci			chip_name = "em2710/2820";
356762306a36Sopenharmony_ci			if (le16_to_cpu(udev->descriptor.idVendor) == 0xeb1a) {
356862306a36Sopenharmony_ci				__le16 idProd = udev->descriptor.idProduct;
356962306a36Sopenharmony_ci
357062306a36Sopenharmony_ci				if (le16_to_cpu(idProd) == 0x2710)
357162306a36Sopenharmony_ci					chip_name = "em2710";
357262306a36Sopenharmony_ci				else if (le16_to_cpu(idProd) == 0x2820)
357362306a36Sopenharmony_ci					chip_name = "em2820";
357462306a36Sopenharmony_ci			}
357562306a36Sopenharmony_ci			/* NOTE: the em2820 is used in webcams, too ! */
357662306a36Sopenharmony_ci			break;
357762306a36Sopenharmony_ci		case CHIP_ID_EM2840:
357862306a36Sopenharmony_ci			chip_name = "em2840";
357962306a36Sopenharmony_ci			break;
358062306a36Sopenharmony_ci		case CHIP_ID_EM2860:
358162306a36Sopenharmony_ci			chip_name = "em2860";
358262306a36Sopenharmony_ci			break;
358362306a36Sopenharmony_ci		case CHIP_ID_EM2870:
358462306a36Sopenharmony_ci			chip_name = "em2870";
358562306a36Sopenharmony_ci			dev->wait_after_write = 0;
358662306a36Sopenharmony_ci			break;
358762306a36Sopenharmony_ci		case CHIP_ID_EM2874:
358862306a36Sopenharmony_ci			chip_name = "em2874";
358962306a36Sopenharmony_ci			dev->wait_after_write = 0;
359062306a36Sopenharmony_ci			dev->eeprom_addrwidth_16bit = 1;
359162306a36Sopenharmony_ci			break;
359262306a36Sopenharmony_ci		case CHIP_ID_EM28174:
359362306a36Sopenharmony_ci			chip_name = "em28174";
359462306a36Sopenharmony_ci			dev->wait_after_write = 0;
359562306a36Sopenharmony_ci			dev->eeprom_addrwidth_16bit = 1;
359662306a36Sopenharmony_ci			break;
359762306a36Sopenharmony_ci		case CHIP_ID_EM28178:
359862306a36Sopenharmony_ci			chip_name = "em28178";
359962306a36Sopenharmony_ci			dev->wait_after_write = 0;
360062306a36Sopenharmony_ci			dev->eeprom_addrwidth_16bit = 1;
360162306a36Sopenharmony_ci			break;
360262306a36Sopenharmony_ci		case CHIP_ID_EM2883:
360362306a36Sopenharmony_ci			chip_name = "em2882/3";
360462306a36Sopenharmony_ci			dev->wait_after_write = 0;
360562306a36Sopenharmony_ci			break;
360662306a36Sopenharmony_ci		case CHIP_ID_EM2884:
360762306a36Sopenharmony_ci			chip_name = "em2884";
360862306a36Sopenharmony_ci			dev->wait_after_write = 0;
360962306a36Sopenharmony_ci			dev->eeprom_addrwidth_16bit = 1;
361062306a36Sopenharmony_ci			break;
361162306a36Sopenharmony_ci		}
361262306a36Sopenharmony_ci	}
361362306a36Sopenharmony_ci	if (!chip_name)
361462306a36Sopenharmony_ci		dev_info(&dev->intf->dev,
361562306a36Sopenharmony_ci			 "unknown em28xx chip ID (%d)\n", dev->chip_id);
361662306a36Sopenharmony_ci	else
361762306a36Sopenharmony_ci		dev_info(&dev->intf->dev, "chip ID is %s\n", chip_name);
361862306a36Sopenharmony_ci
361962306a36Sopenharmony_ci	em28xx_media_device_init(dev, udev);
362062306a36Sopenharmony_ci
362162306a36Sopenharmony_ci	if (dev->is_audio_only) {
362262306a36Sopenharmony_ci		retval = em28xx_audio_setup(dev);
362362306a36Sopenharmony_ci		if (retval) {
362462306a36Sopenharmony_ci			retval = -ENODEV;
362562306a36Sopenharmony_ci			goto err_deinit_media;
362662306a36Sopenharmony_ci		}
362762306a36Sopenharmony_ci		em28xx_init_extension(dev);
362862306a36Sopenharmony_ci
362962306a36Sopenharmony_ci		return 0;
363062306a36Sopenharmony_ci	}
363162306a36Sopenharmony_ci
363262306a36Sopenharmony_ci	em28xx_pre_card_setup(dev);
363362306a36Sopenharmony_ci
363462306a36Sopenharmony_ci	rt_mutex_init(&dev->i2c_bus_lock);
363562306a36Sopenharmony_ci
363662306a36Sopenharmony_ci	/* register i2c bus 0 */
363762306a36Sopenharmony_ci	if (dev->board.is_em2800)
363862306a36Sopenharmony_ci		retval = em28xx_i2c_register(dev, 0, EM28XX_I2C_ALGO_EM2800);
363962306a36Sopenharmony_ci	else
364062306a36Sopenharmony_ci		retval = em28xx_i2c_register(dev, 0, EM28XX_I2C_ALGO_EM28XX);
364162306a36Sopenharmony_ci	if (retval < 0) {
364262306a36Sopenharmony_ci		dev_err(&dev->intf->dev,
364362306a36Sopenharmony_ci			"%s: em28xx_i2c_register bus 0 - error [%d]!\n",
364462306a36Sopenharmony_ci		       __func__, retval);
364562306a36Sopenharmony_ci		goto err_deinit_media;
364662306a36Sopenharmony_ci	}
364762306a36Sopenharmony_ci
364862306a36Sopenharmony_ci	/* register i2c bus 1 */
364962306a36Sopenharmony_ci	if (dev->def_i2c_bus) {
365062306a36Sopenharmony_ci		if (dev->is_em25xx)
365162306a36Sopenharmony_ci			retval = em28xx_i2c_register(dev, 1,
365262306a36Sopenharmony_ci						     EM28XX_I2C_ALGO_EM25XX_BUS_B);
365362306a36Sopenharmony_ci		else
365462306a36Sopenharmony_ci			retval = em28xx_i2c_register(dev, 1,
365562306a36Sopenharmony_ci						     EM28XX_I2C_ALGO_EM28XX);
365662306a36Sopenharmony_ci		if (retval < 0) {
365762306a36Sopenharmony_ci			dev_err(&dev->intf->dev,
365862306a36Sopenharmony_ci				"%s: em28xx_i2c_register bus 1 - error [%d]!\n",
365962306a36Sopenharmony_ci				__func__, retval);
366062306a36Sopenharmony_ci
366162306a36Sopenharmony_ci			goto err_unreg_i2c;
366262306a36Sopenharmony_ci		}
366362306a36Sopenharmony_ci	}
366462306a36Sopenharmony_ci
366562306a36Sopenharmony_ci	/* Do board specific init and eeprom reading */
366662306a36Sopenharmony_ci	em28xx_card_setup(dev);
366762306a36Sopenharmony_ci
366862306a36Sopenharmony_ci	return 0;
366962306a36Sopenharmony_ci
367062306a36Sopenharmony_cierr_unreg_i2c:
367162306a36Sopenharmony_ci	em28xx_i2c_unregister(dev, 0);
367262306a36Sopenharmony_cierr_deinit_media:
367362306a36Sopenharmony_ci	em28xx_unregister_media_device(dev);
367462306a36Sopenharmony_ci	return retval;
367562306a36Sopenharmony_ci}
367662306a36Sopenharmony_ci
367762306a36Sopenharmony_cistatic int em28xx_duplicate_dev(struct em28xx *dev)
367862306a36Sopenharmony_ci{
367962306a36Sopenharmony_ci	int nr;
368062306a36Sopenharmony_ci	struct em28xx *sec_dev = kmemdup(dev, sizeof(*sec_dev), GFP_KERNEL);
368162306a36Sopenharmony_ci
368262306a36Sopenharmony_ci	if (!sec_dev) {
368362306a36Sopenharmony_ci		dev->dev_next = NULL;
368462306a36Sopenharmony_ci		return -ENOMEM;
368562306a36Sopenharmony_ci	}
368662306a36Sopenharmony_ci	/* Check to see next free device and mark as used */
368762306a36Sopenharmony_ci	do {
368862306a36Sopenharmony_ci		nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS);
368962306a36Sopenharmony_ci		if (nr >= EM28XX_MAXBOARDS) {
369062306a36Sopenharmony_ci			/* No free device slots */
369162306a36Sopenharmony_ci			dev_warn(&dev->intf->dev, ": Supports only %i em28xx boards.\n",
369262306a36Sopenharmony_ci				 EM28XX_MAXBOARDS);
369362306a36Sopenharmony_ci			kfree(sec_dev);
369462306a36Sopenharmony_ci			dev->dev_next = NULL;
369562306a36Sopenharmony_ci			return -ENOMEM;
369662306a36Sopenharmony_ci		}
369762306a36Sopenharmony_ci	} while (test_and_set_bit(nr, em28xx_devused));
369862306a36Sopenharmony_ci	sec_dev->devno = nr;
369962306a36Sopenharmony_ci	snprintf(sec_dev->name, 28, "em28xx #%d", nr);
370062306a36Sopenharmony_ci	sec_dev->dev_next = NULL;
370162306a36Sopenharmony_ci	dev->dev_next = sec_dev;
370262306a36Sopenharmony_ci	return 0;
370362306a36Sopenharmony_ci}
370462306a36Sopenharmony_ci
370562306a36Sopenharmony_ci/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
370662306a36Sopenharmony_ci#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
370762306a36Sopenharmony_ci
370862306a36Sopenharmony_cistatic void em28xx_check_usb_descriptor(struct em28xx *dev,
370962306a36Sopenharmony_ci					struct usb_device *udev,
371062306a36Sopenharmony_ci					struct usb_interface *intf,
371162306a36Sopenharmony_ci					int alt, int ep,
371262306a36Sopenharmony_ci					bool *has_vendor_audio,
371362306a36Sopenharmony_ci					bool *has_video,
371462306a36Sopenharmony_ci					bool *has_dvb)
371562306a36Sopenharmony_ci{
371662306a36Sopenharmony_ci	const struct usb_endpoint_descriptor *e;
371762306a36Sopenharmony_ci	int sizedescr, size;
371862306a36Sopenharmony_ci
371962306a36Sopenharmony_ci	/*
372062306a36Sopenharmony_ci	 * NOTE:
372162306a36Sopenharmony_ci	 *
372262306a36Sopenharmony_ci	 * Old logic with support for isoc transfers only was:
372362306a36Sopenharmony_ci	 *  0x82	isoc		=> analog
372462306a36Sopenharmony_ci	 *  0x83	isoc		=> audio
372562306a36Sopenharmony_ci	 *  0x84	isoc		=> digital
372662306a36Sopenharmony_ci	 *
372762306a36Sopenharmony_ci	 * New logic with support for bulk transfers
372862306a36Sopenharmony_ci	 *  0x82	isoc		=> analog
372962306a36Sopenharmony_ci	 *  0x82	bulk		=> analog
373062306a36Sopenharmony_ci	 *  0x83	isoc*		=> audio
373162306a36Sopenharmony_ci	 *  0x84	isoc		=> digital
373262306a36Sopenharmony_ci	 *  0x84	bulk		=> analog or digital**
373362306a36Sopenharmony_ci	 *  0x85	isoc		=> digital TS2
373462306a36Sopenharmony_ci	 *  0x85	bulk		=> digital TS2
373562306a36Sopenharmony_ci	 * (*: audio should always be isoc)
373662306a36Sopenharmony_ci	 * (**: analog, if ep 0x82 is isoc, otherwise digital)
373762306a36Sopenharmony_ci	 *
373862306a36Sopenharmony_ci	 * The new logic preserves backwards compatibility and
373962306a36Sopenharmony_ci	 * reflects the endpoint configurations we have seen
374062306a36Sopenharmony_ci	 * so far. But there might be devices for which this
374162306a36Sopenharmony_ci	 * logic is not sufficient...
374262306a36Sopenharmony_ci	 */
374362306a36Sopenharmony_ci
374462306a36Sopenharmony_ci	e = &intf->altsetting[alt].endpoint[ep].desc;
374562306a36Sopenharmony_ci
374662306a36Sopenharmony_ci	if (!usb_endpoint_dir_in(e))
374762306a36Sopenharmony_ci		return;
374862306a36Sopenharmony_ci
374962306a36Sopenharmony_ci	sizedescr = le16_to_cpu(e->wMaxPacketSize);
375062306a36Sopenharmony_ci	size = sizedescr & 0x7ff;
375162306a36Sopenharmony_ci
375262306a36Sopenharmony_ci	if (udev->speed == USB_SPEED_HIGH)
375362306a36Sopenharmony_ci		size = size * hb_mult(sizedescr);
375462306a36Sopenharmony_ci
375562306a36Sopenharmony_ci	/* Only inspect input endpoints */
375662306a36Sopenharmony_ci
375762306a36Sopenharmony_ci	switch (e->bEndpointAddress) {
375862306a36Sopenharmony_ci	case 0x82:
375962306a36Sopenharmony_ci		*has_video = true;
376062306a36Sopenharmony_ci		if (usb_endpoint_xfer_isoc(e)) {
376162306a36Sopenharmony_ci			dev->analog_ep_isoc = e->bEndpointAddress;
376262306a36Sopenharmony_ci			dev->alt_max_pkt_size_isoc[alt] = size;
376362306a36Sopenharmony_ci		} else if (usb_endpoint_xfer_bulk(e)) {
376462306a36Sopenharmony_ci			dev->analog_ep_bulk = e->bEndpointAddress;
376562306a36Sopenharmony_ci		}
376662306a36Sopenharmony_ci		return;
376762306a36Sopenharmony_ci	case 0x83:
376862306a36Sopenharmony_ci		if (usb_endpoint_xfer_isoc(e))
376962306a36Sopenharmony_ci			*has_vendor_audio = true;
377062306a36Sopenharmony_ci		else
377162306a36Sopenharmony_ci			dev_err(&intf->dev,
377262306a36Sopenharmony_ci				"error: skipping audio endpoint 0x83, because it uses bulk transfers !\n");
377362306a36Sopenharmony_ci		return;
377462306a36Sopenharmony_ci	case 0x84:
377562306a36Sopenharmony_ci		if (*has_video && (usb_endpoint_xfer_bulk(e))) {
377662306a36Sopenharmony_ci			dev->analog_ep_bulk = e->bEndpointAddress;
377762306a36Sopenharmony_ci		} else {
377862306a36Sopenharmony_ci			if (usb_endpoint_xfer_isoc(e)) {
377962306a36Sopenharmony_ci				if (size > dev->dvb_max_pkt_size_isoc) {
378062306a36Sopenharmony_ci					/*
378162306a36Sopenharmony_ci					 * 2) some manufacturers (e.g. Terratec)
378262306a36Sopenharmony_ci					 * disable endpoints by setting
378362306a36Sopenharmony_ci					 * wMaxPacketSize to 0 bytes for all
378462306a36Sopenharmony_ci					 * alt settings. So far, we've seen
378562306a36Sopenharmony_ci					 * this for DVB isoc endpoints only.
378662306a36Sopenharmony_ci					 */
378762306a36Sopenharmony_ci					*has_dvb = true;
378862306a36Sopenharmony_ci					dev->dvb_ep_isoc = e->bEndpointAddress;
378962306a36Sopenharmony_ci					dev->dvb_max_pkt_size_isoc = size;
379062306a36Sopenharmony_ci					dev->dvb_alt_isoc = alt;
379162306a36Sopenharmony_ci				}
379262306a36Sopenharmony_ci			} else {
379362306a36Sopenharmony_ci				*has_dvb = true;
379462306a36Sopenharmony_ci				dev->dvb_ep_bulk = e->bEndpointAddress;
379562306a36Sopenharmony_ci			}
379662306a36Sopenharmony_ci		}
379762306a36Sopenharmony_ci		return;
379862306a36Sopenharmony_ci	case 0x85:
379962306a36Sopenharmony_ci		if (usb_endpoint_xfer_isoc(e)) {
380062306a36Sopenharmony_ci			if (size > dev->dvb_max_pkt_size_isoc_ts2) {
380162306a36Sopenharmony_ci				dev->dvb_ep_isoc_ts2 = e->bEndpointAddress;
380262306a36Sopenharmony_ci				dev->dvb_max_pkt_size_isoc_ts2 = size;
380362306a36Sopenharmony_ci				dev->dvb_alt_isoc = alt;
380462306a36Sopenharmony_ci			}
380562306a36Sopenharmony_ci		} else {
380662306a36Sopenharmony_ci			dev->dvb_ep_bulk_ts2 = e->bEndpointAddress;
380762306a36Sopenharmony_ci		}
380862306a36Sopenharmony_ci		return;
380962306a36Sopenharmony_ci	}
381062306a36Sopenharmony_ci}
381162306a36Sopenharmony_ci
381262306a36Sopenharmony_ci/*
381362306a36Sopenharmony_ci * em28xx_usb_probe()
381462306a36Sopenharmony_ci * checks for supported devices
381562306a36Sopenharmony_ci */
381662306a36Sopenharmony_cistatic int em28xx_usb_probe(struct usb_interface *intf,
381762306a36Sopenharmony_ci			    const struct usb_device_id *id)
381862306a36Sopenharmony_ci{
381962306a36Sopenharmony_ci	struct usb_device *udev;
382062306a36Sopenharmony_ci	struct em28xx *dev = NULL;
382162306a36Sopenharmony_ci	int retval;
382262306a36Sopenharmony_ci	bool has_vendor_audio = false, has_video = false, has_dvb = false;
382362306a36Sopenharmony_ci	int i, nr, try_bulk;
382462306a36Sopenharmony_ci	const int ifnum = intf->altsetting[0].desc.bInterfaceNumber;
382562306a36Sopenharmony_ci	char *speed;
382662306a36Sopenharmony_ci
382762306a36Sopenharmony_ci	udev = usb_get_dev(interface_to_usbdev(intf));
382862306a36Sopenharmony_ci
382962306a36Sopenharmony_ci	/* Check to see next free device and mark as used */
383062306a36Sopenharmony_ci	do {
383162306a36Sopenharmony_ci		nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS);
383262306a36Sopenharmony_ci		if (nr >= EM28XX_MAXBOARDS) {
383362306a36Sopenharmony_ci			/* No free device slots */
383462306a36Sopenharmony_ci			dev_err(&intf->dev,
383562306a36Sopenharmony_ci				"Driver supports up to %i em28xx boards.\n",
383662306a36Sopenharmony_ci			       EM28XX_MAXBOARDS);
383762306a36Sopenharmony_ci			retval = -ENOMEM;
383862306a36Sopenharmony_ci			goto err_no_slot;
383962306a36Sopenharmony_ci		}
384062306a36Sopenharmony_ci	} while (test_and_set_bit(nr, em28xx_devused));
384162306a36Sopenharmony_ci
384262306a36Sopenharmony_ci	/* Don't register audio interfaces */
384362306a36Sopenharmony_ci	if (intf->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
384462306a36Sopenharmony_ci		dev_info(&intf->dev,
384562306a36Sopenharmony_ci			"audio device (%04x:%04x): interface %i, class %i\n",
384662306a36Sopenharmony_ci			le16_to_cpu(udev->descriptor.idVendor),
384762306a36Sopenharmony_ci			le16_to_cpu(udev->descriptor.idProduct),
384862306a36Sopenharmony_ci			ifnum,
384962306a36Sopenharmony_ci			intf->altsetting[0].desc.bInterfaceClass);
385062306a36Sopenharmony_ci
385162306a36Sopenharmony_ci		retval = -ENODEV;
385262306a36Sopenharmony_ci		goto err;
385362306a36Sopenharmony_ci	}
385462306a36Sopenharmony_ci
385562306a36Sopenharmony_ci	/* allocate memory for our device state and initialize it */
385662306a36Sopenharmony_ci	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
385762306a36Sopenharmony_ci	if (!dev) {
385862306a36Sopenharmony_ci		retval = -ENOMEM;
385962306a36Sopenharmony_ci		goto err;
386062306a36Sopenharmony_ci	}
386162306a36Sopenharmony_ci
386262306a36Sopenharmony_ci	/* compute alternate max packet sizes */
386362306a36Sopenharmony_ci	dev->alt_max_pkt_size_isoc = kcalloc(intf->num_altsetting,
386462306a36Sopenharmony_ci					     sizeof(dev->alt_max_pkt_size_isoc[0]),
386562306a36Sopenharmony_ci					     GFP_KERNEL);
386662306a36Sopenharmony_ci	if (!dev->alt_max_pkt_size_isoc) {
386762306a36Sopenharmony_ci		kfree(dev);
386862306a36Sopenharmony_ci		retval = -ENOMEM;
386962306a36Sopenharmony_ci		goto err;
387062306a36Sopenharmony_ci	}
387162306a36Sopenharmony_ci
387262306a36Sopenharmony_ci	/* Get endpoints */
387362306a36Sopenharmony_ci	for (i = 0; i < intf->num_altsetting; i++) {
387462306a36Sopenharmony_ci		int ep;
387562306a36Sopenharmony_ci
387662306a36Sopenharmony_ci		for (ep = 0;
387762306a36Sopenharmony_ci		     ep < intf->altsetting[i].desc.bNumEndpoints;
387862306a36Sopenharmony_ci		     ep++)
387962306a36Sopenharmony_ci			em28xx_check_usb_descriptor(dev, udev, intf,
388062306a36Sopenharmony_ci						    i, ep,
388162306a36Sopenharmony_ci						    &has_vendor_audio,
388262306a36Sopenharmony_ci						    &has_video,
388362306a36Sopenharmony_ci						    &has_dvb);
388462306a36Sopenharmony_ci	}
388562306a36Sopenharmony_ci
388662306a36Sopenharmony_ci	if (!(has_vendor_audio || has_video || has_dvb)) {
388762306a36Sopenharmony_ci		retval = -ENODEV;
388862306a36Sopenharmony_ci		goto err_free;
388962306a36Sopenharmony_ci	}
389062306a36Sopenharmony_ci
389162306a36Sopenharmony_ci	switch (udev->speed) {
389262306a36Sopenharmony_ci	case USB_SPEED_LOW:
389362306a36Sopenharmony_ci		speed = "1.5";
389462306a36Sopenharmony_ci		break;
389562306a36Sopenharmony_ci	case USB_SPEED_UNKNOWN:
389662306a36Sopenharmony_ci	case USB_SPEED_FULL:
389762306a36Sopenharmony_ci		speed = "12";
389862306a36Sopenharmony_ci		break;
389962306a36Sopenharmony_ci	case USB_SPEED_HIGH:
390062306a36Sopenharmony_ci		speed = "480";
390162306a36Sopenharmony_ci		break;
390262306a36Sopenharmony_ci	default:
390362306a36Sopenharmony_ci		speed = "unknown";
390462306a36Sopenharmony_ci	}
390562306a36Sopenharmony_ci
390662306a36Sopenharmony_ci	dev_info(&intf->dev,
390762306a36Sopenharmony_ci		"New device %s %s @ %s Mbps (%04x:%04x, interface %d, class %d)\n",
390862306a36Sopenharmony_ci		udev->manufacturer ? udev->manufacturer : "",
390962306a36Sopenharmony_ci		udev->product ? udev->product : "",
391062306a36Sopenharmony_ci		speed,
391162306a36Sopenharmony_ci		le16_to_cpu(udev->descriptor.idVendor),
391262306a36Sopenharmony_ci		le16_to_cpu(udev->descriptor.idProduct),
391362306a36Sopenharmony_ci		ifnum,
391462306a36Sopenharmony_ci		intf->altsetting->desc.bInterfaceNumber);
391562306a36Sopenharmony_ci
391662306a36Sopenharmony_ci	/*
391762306a36Sopenharmony_ci	 * Make sure we have 480 Mbps of bandwidth, otherwise things like
391862306a36Sopenharmony_ci	 * video stream wouldn't likely work, since 12 Mbps is generally
391962306a36Sopenharmony_ci	 * not enough even for most Digital TV streams.
392062306a36Sopenharmony_ci	 */
392162306a36Sopenharmony_ci	if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) {
392262306a36Sopenharmony_ci		dev_err(&intf->dev, "Device initialization failed.\n");
392362306a36Sopenharmony_ci		dev_err(&intf->dev,
392462306a36Sopenharmony_ci			"Device must be connected to a high-speed USB 2.0 port.\n");
392562306a36Sopenharmony_ci		retval = -ENODEV;
392662306a36Sopenharmony_ci		goto err_free;
392762306a36Sopenharmony_ci	}
392862306a36Sopenharmony_ci
392962306a36Sopenharmony_ci	kref_init(&dev->ref);
393062306a36Sopenharmony_ci
393162306a36Sopenharmony_ci	dev->devno = nr;
393262306a36Sopenharmony_ci	dev->model = id->driver_info;
393362306a36Sopenharmony_ci	dev->alt   = -1;
393462306a36Sopenharmony_ci	dev->is_audio_only = has_vendor_audio && !(has_video || has_dvb);
393562306a36Sopenharmony_ci	dev->has_video = has_video;
393662306a36Sopenharmony_ci	dev->ifnum = ifnum;
393762306a36Sopenharmony_ci
393862306a36Sopenharmony_ci	dev->ts = PRIMARY_TS;
393962306a36Sopenharmony_ci	snprintf(dev->name, 28, "em28xx");
394062306a36Sopenharmony_ci	dev->dev_next = NULL;
394162306a36Sopenharmony_ci
394262306a36Sopenharmony_ci	if (has_vendor_audio) {
394362306a36Sopenharmony_ci		dev_info(&intf->dev,
394462306a36Sopenharmony_ci			"Audio interface %i found (Vendor Class)\n", ifnum);
394562306a36Sopenharmony_ci		dev->usb_audio_type = EM28XX_USB_AUDIO_VENDOR;
394662306a36Sopenharmony_ci	}
394762306a36Sopenharmony_ci	/* Checks if audio is provided by a USB Audio Class intf */
394862306a36Sopenharmony_ci	for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
394962306a36Sopenharmony_ci		struct usb_interface *uif = udev->config->interface[i];
395062306a36Sopenharmony_ci
395162306a36Sopenharmony_ci		if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
395262306a36Sopenharmony_ci			if (has_vendor_audio)
395362306a36Sopenharmony_ci				dev_err(&intf->dev,
395462306a36Sopenharmony_ci					"em28xx: device seems to have vendor AND usb audio class interfaces !\n"
395562306a36Sopenharmony_ci					"\t\tThe vendor interface will be ignored. Please contact the developers <linux-media@vger.kernel.org>\n");
395662306a36Sopenharmony_ci			dev->usb_audio_type = EM28XX_USB_AUDIO_CLASS;
395762306a36Sopenharmony_ci			break;
395862306a36Sopenharmony_ci		}
395962306a36Sopenharmony_ci	}
396062306a36Sopenharmony_ci
396162306a36Sopenharmony_ci	if (has_video)
396262306a36Sopenharmony_ci		dev_info(&intf->dev, "Video interface %i found:%s%s\n",
396362306a36Sopenharmony_ci			ifnum,
396462306a36Sopenharmony_ci			dev->analog_ep_bulk ? " bulk" : "",
396562306a36Sopenharmony_ci			dev->analog_ep_isoc ? " isoc" : "");
396662306a36Sopenharmony_ci	if (has_dvb)
396762306a36Sopenharmony_ci		dev_info(&intf->dev, "DVB interface %i found:%s%s\n",
396862306a36Sopenharmony_ci			ifnum,
396962306a36Sopenharmony_ci			dev->dvb_ep_bulk ? " bulk" : "",
397062306a36Sopenharmony_ci			dev->dvb_ep_isoc ? " isoc" : "");
397162306a36Sopenharmony_ci
397262306a36Sopenharmony_ci	dev->num_alt = intf->num_altsetting;
397362306a36Sopenharmony_ci
397462306a36Sopenharmony_ci	if ((unsigned int)card[nr] < em28xx_bcount)
397562306a36Sopenharmony_ci		dev->model = card[nr];
397662306a36Sopenharmony_ci
397762306a36Sopenharmony_ci	/* save our data pointer in this intf device */
397862306a36Sopenharmony_ci	usb_set_intfdata(intf, dev);
397962306a36Sopenharmony_ci
398062306a36Sopenharmony_ci	/* allocate device struct and check if the device is a webcam */
398162306a36Sopenharmony_ci	mutex_init(&dev->lock);
398262306a36Sopenharmony_ci	retval = em28xx_init_dev(dev, udev, intf, nr);
398362306a36Sopenharmony_ci	if (retval)
398462306a36Sopenharmony_ci		goto err_free;
398562306a36Sopenharmony_ci
398662306a36Sopenharmony_ci	if (usb_xfer_mode < 0) {
398762306a36Sopenharmony_ci		if (dev->is_webcam)
398862306a36Sopenharmony_ci			try_bulk = 1;
398962306a36Sopenharmony_ci		else
399062306a36Sopenharmony_ci			try_bulk = 0;
399162306a36Sopenharmony_ci	} else {
399262306a36Sopenharmony_ci		try_bulk = usb_xfer_mode > 0;
399362306a36Sopenharmony_ci	}
399462306a36Sopenharmony_ci
399562306a36Sopenharmony_ci	/* Disable V4L2 if the device doesn't have a decoder or image sensor */
399662306a36Sopenharmony_ci	if (has_video &&
399762306a36Sopenharmony_ci	    dev->board.decoder == EM28XX_NODECODER &&
399862306a36Sopenharmony_ci	    dev->em28xx_sensor == EM28XX_NOSENSOR) {
399962306a36Sopenharmony_ci		dev_err(&intf->dev,
400062306a36Sopenharmony_ci			"Currently, V4L2 is not supported on this model\n");
400162306a36Sopenharmony_ci		has_video = false;
400262306a36Sopenharmony_ci		dev->has_video = false;
400362306a36Sopenharmony_ci	}
400462306a36Sopenharmony_ci
400562306a36Sopenharmony_ci	if (dev->board.has_dual_ts &&
400662306a36Sopenharmony_ci	    (dev->tuner_type != TUNER_ABSENT || INPUT(0)->type)) {
400762306a36Sopenharmony_ci		/*
400862306a36Sopenharmony_ci		 * The logic with sets alternate is not ready for dual-tuners
400962306a36Sopenharmony_ci		 * which analog modes.
401062306a36Sopenharmony_ci		 */
401162306a36Sopenharmony_ci		dev_err(&intf->dev,
401262306a36Sopenharmony_ci			"We currently don't support analog TV or stream capture on dual tuners.\n");
401362306a36Sopenharmony_ci		has_video = false;
401462306a36Sopenharmony_ci	}
401562306a36Sopenharmony_ci
401662306a36Sopenharmony_ci	/* Select USB transfer types to use */
401762306a36Sopenharmony_ci	if (has_video) {
401862306a36Sopenharmony_ci		if (!dev->analog_ep_isoc || (try_bulk && dev->analog_ep_bulk))
401962306a36Sopenharmony_ci			dev->analog_xfer_bulk = 1;
402062306a36Sopenharmony_ci		dev_info(&intf->dev, "analog set to %s mode.\n",
402162306a36Sopenharmony_ci			dev->analog_xfer_bulk ? "bulk" : "isoc");
402262306a36Sopenharmony_ci	}
402362306a36Sopenharmony_ci	if (has_dvb) {
402462306a36Sopenharmony_ci		if (!dev->dvb_ep_isoc || (try_bulk && dev->dvb_ep_bulk))
402562306a36Sopenharmony_ci			dev->dvb_xfer_bulk = 1;
402662306a36Sopenharmony_ci		dev_info(&intf->dev, "dvb set to %s mode.\n",
402762306a36Sopenharmony_ci			dev->dvb_xfer_bulk ? "bulk" : "isoc");
402862306a36Sopenharmony_ci	}
402962306a36Sopenharmony_ci
403062306a36Sopenharmony_ci	if (dev->board.has_dual_ts && em28xx_duplicate_dev(dev) == 0) {
403162306a36Sopenharmony_ci		kref_init(&dev->dev_next->ref);
403262306a36Sopenharmony_ci
403362306a36Sopenharmony_ci		dev->dev_next->ts = SECONDARY_TS;
403462306a36Sopenharmony_ci		dev->dev_next->alt   = -1;
403562306a36Sopenharmony_ci		dev->dev_next->is_audio_only = has_vendor_audio &&
403662306a36Sopenharmony_ci						!(has_video || has_dvb);
403762306a36Sopenharmony_ci		dev->dev_next->has_video = false;
403862306a36Sopenharmony_ci		dev->dev_next->ifnum = ifnum;
403962306a36Sopenharmony_ci		dev->dev_next->model = id->driver_info;
404062306a36Sopenharmony_ci
404162306a36Sopenharmony_ci		mutex_init(&dev->dev_next->lock);
404262306a36Sopenharmony_ci		retval = em28xx_init_dev(dev->dev_next, udev, intf,
404362306a36Sopenharmony_ci					 dev->dev_next->devno);
404462306a36Sopenharmony_ci		if (retval)
404562306a36Sopenharmony_ci			goto err_free;
404662306a36Sopenharmony_ci
404762306a36Sopenharmony_ci		dev->dev_next->board.ir_codes = NULL; /* No IR for 2nd tuner */
404862306a36Sopenharmony_ci		dev->dev_next->board.has_ir_i2c = 0; /* No IR for 2nd tuner */
404962306a36Sopenharmony_ci
405062306a36Sopenharmony_ci		if (usb_xfer_mode < 0) {
405162306a36Sopenharmony_ci			if (dev->dev_next->is_webcam)
405262306a36Sopenharmony_ci				try_bulk = 1;
405362306a36Sopenharmony_ci			else
405462306a36Sopenharmony_ci				try_bulk = 0;
405562306a36Sopenharmony_ci		} else {
405662306a36Sopenharmony_ci			try_bulk = usb_xfer_mode > 0;
405762306a36Sopenharmony_ci		}
405862306a36Sopenharmony_ci
405962306a36Sopenharmony_ci		/* Select USB transfer types to use */
406062306a36Sopenharmony_ci		if (has_dvb) {
406162306a36Sopenharmony_ci			if (!dev->dvb_ep_isoc_ts2 ||
406262306a36Sopenharmony_ci			    (try_bulk && dev->dvb_ep_bulk_ts2))
406362306a36Sopenharmony_ci				dev->dev_next->dvb_xfer_bulk = 1;
406462306a36Sopenharmony_ci			dev_info(&dev->intf->dev, "dvb ts2 set to %s mode.\n",
406562306a36Sopenharmony_ci				 dev->dev_next->dvb_xfer_bulk ? "bulk" : "isoc");
406662306a36Sopenharmony_ci		}
406762306a36Sopenharmony_ci
406862306a36Sopenharmony_ci		dev->dev_next->dvb_ep_isoc = dev->dvb_ep_isoc_ts2;
406962306a36Sopenharmony_ci		dev->dev_next->dvb_ep_bulk = dev->dvb_ep_bulk_ts2;
407062306a36Sopenharmony_ci		dev->dev_next->dvb_max_pkt_size_isoc = dev->dvb_max_pkt_size_isoc_ts2;
407162306a36Sopenharmony_ci		dev->dev_next->dvb_alt_isoc = dev->dvb_alt_isoc;
407262306a36Sopenharmony_ci
407362306a36Sopenharmony_ci		/* Configure hardware to support TS2*/
407462306a36Sopenharmony_ci		if (dev->dvb_xfer_bulk) {
407562306a36Sopenharmony_ci			/* The ep4 and ep5 are configured for BULK */
407662306a36Sopenharmony_ci			em28xx_write_reg(dev, 0x0b, 0x96);
407762306a36Sopenharmony_ci			mdelay(100);
407862306a36Sopenharmony_ci			em28xx_write_reg(dev, 0x0b, 0x80);
407962306a36Sopenharmony_ci			mdelay(100);
408062306a36Sopenharmony_ci		} else {
408162306a36Sopenharmony_ci			/* The ep4 and ep5 are configured for ISO */
408262306a36Sopenharmony_ci			em28xx_write_reg(dev, 0x0b, 0x96);
408362306a36Sopenharmony_ci			mdelay(100);
408462306a36Sopenharmony_ci			em28xx_write_reg(dev, 0x0b, 0x82);
408562306a36Sopenharmony_ci			mdelay(100);
408662306a36Sopenharmony_ci		}
408762306a36Sopenharmony_ci	}
408862306a36Sopenharmony_ci
408962306a36Sopenharmony_ci	request_modules(dev);
409062306a36Sopenharmony_ci
409162306a36Sopenharmony_ci	/*
409262306a36Sopenharmony_ci	 * Do it at the end, to reduce dynamic configuration changes during
409362306a36Sopenharmony_ci	 * the device init. Yet, as request_modules() can be async, the
409462306a36Sopenharmony_ci	 * topology will likely change after the load of the em28xx subdrivers.
409562306a36Sopenharmony_ci	 */
409662306a36Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER
409762306a36Sopenharmony_ci	/*
409862306a36Sopenharmony_ci	 * No need to check the return value, the device will still be
409962306a36Sopenharmony_ci	 * usable without media controller API.
410062306a36Sopenharmony_ci	 */
410162306a36Sopenharmony_ci	retval = media_device_register(dev->media_dev);
410262306a36Sopenharmony_ci#endif
410362306a36Sopenharmony_ci
410462306a36Sopenharmony_ci	return 0;
410562306a36Sopenharmony_ci
410662306a36Sopenharmony_cierr_free:
410762306a36Sopenharmony_ci	kfree(dev->alt_max_pkt_size_isoc);
410862306a36Sopenharmony_ci	kfree(dev);
410962306a36Sopenharmony_ci
411062306a36Sopenharmony_cierr:
411162306a36Sopenharmony_ci	clear_bit(nr, em28xx_devused);
411262306a36Sopenharmony_ci
411362306a36Sopenharmony_cierr_no_slot:
411462306a36Sopenharmony_ci	usb_put_dev(udev);
411562306a36Sopenharmony_ci	return retval;
411662306a36Sopenharmony_ci}
411762306a36Sopenharmony_ci
411862306a36Sopenharmony_ci/*
411962306a36Sopenharmony_ci * em28xx_usb_disconnect()
412062306a36Sopenharmony_ci * called when the device gets disconnected
412162306a36Sopenharmony_ci * video device will be unregistered on v4l2_close in case it is still open
412262306a36Sopenharmony_ci */
412362306a36Sopenharmony_cistatic void em28xx_usb_disconnect(struct usb_interface *intf)
412462306a36Sopenharmony_ci{
412562306a36Sopenharmony_ci	struct em28xx *dev;
412662306a36Sopenharmony_ci
412762306a36Sopenharmony_ci	dev = usb_get_intfdata(intf);
412862306a36Sopenharmony_ci	usb_set_intfdata(intf, NULL);
412962306a36Sopenharmony_ci
413062306a36Sopenharmony_ci	if (!dev)
413162306a36Sopenharmony_ci		return;
413262306a36Sopenharmony_ci
413362306a36Sopenharmony_ci	if (dev->dev_next) {
413462306a36Sopenharmony_ci		dev->dev_next->disconnected = 1;
413562306a36Sopenharmony_ci		dev_info(&dev->intf->dev, "Disconnecting %s\n",
413662306a36Sopenharmony_ci			 dev->dev_next->name);
413762306a36Sopenharmony_ci	}
413862306a36Sopenharmony_ci
413962306a36Sopenharmony_ci	dev->disconnected = 1;
414062306a36Sopenharmony_ci
414162306a36Sopenharmony_ci	dev_info(&dev->intf->dev, "Disconnecting %s\n", dev->name);
414262306a36Sopenharmony_ci
414362306a36Sopenharmony_ci	flush_request_modules(dev);
414462306a36Sopenharmony_ci
414562306a36Sopenharmony_ci	em28xx_close_extension(dev);
414662306a36Sopenharmony_ci
414762306a36Sopenharmony_ci	if (dev->dev_next)
414862306a36Sopenharmony_ci		em28xx_release_resources(dev->dev_next);
414962306a36Sopenharmony_ci	em28xx_release_resources(dev);
415062306a36Sopenharmony_ci
415162306a36Sopenharmony_ci	if (dev->dev_next) {
415262306a36Sopenharmony_ci		kref_put(&dev->dev_next->ref, em28xx_free_device);
415362306a36Sopenharmony_ci		dev->dev_next = NULL;
415462306a36Sopenharmony_ci	}
415562306a36Sopenharmony_ci	kref_put(&dev->ref, em28xx_free_device);
415662306a36Sopenharmony_ci}
415762306a36Sopenharmony_ci
415862306a36Sopenharmony_cistatic int em28xx_usb_suspend(struct usb_interface *intf,
415962306a36Sopenharmony_ci			      pm_message_t message)
416062306a36Sopenharmony_ci{
416162306a36Sopenharmony_ci	struct em28xx *dev;
416262306a36Sopenharmony_ci
416362306a36Sopenharmony_ci	dev = usb_get_intfdata(intf);
416462306a36Sopenharmony_ci	if (!dev)
416562306a36Sopenharmony_ci		return 0;
416662306a36Sopenharmony_ci	em28xx_suspend_extension(dev);
416762306a36Sopenharmony_ci	return 0;
416862306a36Sopenharmony_ci}
416962306a36Sopenharmony_ci
417062306a36Sopenharmony_cistatic int em28xx_usb_resume(struct usb_interface *intf)
417162306a36Sopenharmony_ci{
417262306a36Sopenharmony_ci	struct em28xx *dev;
417362306a36Sopenharmony_ci
417462306a36Sopenharmony_ci	dev = usb_get_intfdata(intf);
417562306a36Sopenharmony_ci	if (!dev)
417662306a36Sopenharmony_ci		return 0;
417762306a36Sopenharmony_ci	em28xx_resume_extension(dev);
417862306a36Sopenharmony_ci	return 0;
417962306a36Sopenharmony_ci}
418062306a36Sopenharmony_ci
418162306a36Sopenharmony_cistatic struct usb_driver em28xx_usb_driver = {
418262306a36Sopenharmony_ci	.name = "em28xx",
418362306a36Sopenharmony_ci	.probe = em28xx_usb_probe,
418462306a36Sopenharmony_ci	.disconnect = em28xx_usb_disconnect,
418562306a36Sopenharmony_ci	.suspend = em28xx_usb_suspend,
418662306a36Sopenharmony_ci	.resume = em28xx_usb_resume,
418762306a36Sopenharmony_ci	.reset_resume = em28xx_usb_resume,
418862306a36Sopenharmony_ci	.id_table = em28xx_id_table,
418962306a36Sopenharmony_ci};
419062306a36Sopenharmony_ci
419162306a36Sopenharmony_cimodule_usb_driver(em28xx_usb_driver);
4192