18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
28c2ecf20Sopenharmony_ci//
38c2ecf20Sopenharmony_ci// em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB
48c2ecf20Sopenharmony_ci//		    video capture devices
58c2ecf20Sopenharmony_ci//
68c2ecf20Sopenharmony_ci// Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
78c2ecf20Sopenharmony_ci//		      Markus Rechberger <mrechberger@gmail.com>
88c2ecf20Sopenharmony_ci//		      Mauro Carvalho Chehab <mchehab@kernel.org>
98c2ecf20Sopenharmony_ci//		      Sascha Sommer <saschasommer@freenet.de>
108c2ecf20Sopenharmony_ci// Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com>
118c2ecf20Sopenharmony_ci//
128c2ecf20Sopenharmony_ci// This program is free software; you can redistribute it and/or modify
138c2ecf20Sopenharmony_ci// it under the terms of the GNU General Public License as published by
148c2ecf20Sopenharmony_ci// the Free Software Foundation; either version 2 of the License, or
158c2ecf20Sopenharmony_ci// (at your option) any later version.
168c2ecf20Sopenharmony_ci//
178c2ecf20Sopenharmony_ci// This program is distributed in the hope that it will be useful,
188c2ecf20Sopenharmony_ci// but WITHOUT ANY WARRANTY; without even the implied warranty of
198c2ecf20Sopenharmony_ci// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
208c2ecf20Sopenharmony_ci// GNU General Public License for more details.
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci#include "em28xx.h"
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#include <linux/init.h>
258c2ecf20Sopenharmony_ci#include <linux/module.h>
268c2ecf20Sopenharmony_ci#include <linux/slab.h>
278c2ecf20Sopenharmony_ci#include <linux/delay.h>
288c2ecf20Sopenharmony_ci#include <linux/i2c.h>
298c2ecf20Sopenharmony_ci#include <linux/usb.h>
308c2ecf20Sopenharmony_ci#include <media/tuner.h>
318c2ecf20Sopenharmony_ci#include <media/drv-intf/msp3400.h>
328c2ecf20Sopenharmony_ci#include <media/i2c/saa7115.h>
338c2ecf20Sopenharmony_ci#include <dt-bindings/media/tvp5150.h>
348c2ecf20Sopenharmony_ci#include <media/i2c/tvaudio.h>
358c2ecf20Sopenharmony_ci#include <media/tveeprom.h>
368c2ecf20Sopenharmony_ci#include <media/v4l2-common.h>
378c2ecf20Sopenharmony_ci#include <sound/ac97_codec.h>
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci#define DRIVER_NAME         "em28xx"
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_cistatic int tuner = -1;
428c2ecf20Sopenharmony_cimodule_param(tuner, int, 0444);
438c2ecf20Sopenharmony_ciMODULE_PARM_DESC(tuner, "tuner type");
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_cistatic unsigned int disable_ir;
468c2ecf20Sopenharmony_cimodule_param(disable_ir, int, 0444);
478c2ecf20Sopenharmony_ciMODULE_PARM_DESC(disable_ir, "disable infrared remote support");
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_cistatic unsigned int disable_usb_speed_check;
508c2ecf20Sopenharmony_cimodule_param(disable_usb_speed_check, int, 0444);
518c2ecf20Sopenharmony_ciMODULE_PARM_DESC(disable_usb_speed_check,
528c2ecf20Sopenharmony_ci		 "override min bandwidth requirement of 480M bps");
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_cistatic unsigned int card[]     = {[0 ... (EM28XX_MAXBOARDS - 1)] = -1U };
558c2ecf20Sopenharmony_cimodule_param_array(card,  int, NULL, 0444);
568c2ecf20Sopenharmony_ciMODULE_PARM_DESC(card,     "card type");
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistatic int usb_xfer_mode = -1;
598c2ecf20Sopenharmony_cimodule_param(usb_xfer_mode, int, 0444);
608c2ecf20Sopenharmony_ciMODULE_PARM_DESC(usb_xfer_mode,
618c2ecf20Sopenharmony_ci		 "USB transfer mode for frame data (-1 = auto, 0 = prefer isoc, 1 = prefer bulk)");
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS - 1 */
648c2ecf20Sopenharmony_cistatic DECLARE_BITMAP(em28xx_devused, EM28XX_MAXBOARDS);
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_cistruct em28xx_hash_table {
678c2ecf20Sopenharmony_ci	unsigned long hash;
688c2ecf20Sopenharmony_ci	unsigned int  model;
698c2ecf20Sopenharmony_ci	unsigned int  tuner;
708c2ecf20Sopenharmony_ci};
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_cistatic void em28xx_pre_card_setup(struct em28xx *dev);
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci/*
758c2ecf20Sopenharmony_ci *  Reset sequences for analog/digital modes
768c2ecf20Sopenharmony_ci */
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci/* Reset for the most [analog] boards */
798c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq default_analog[] = {
808c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6d,   ~EM_GPIO_4,	10},
818c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
828c2ecf20Sopenharmony_ci};
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci/* Reset for the most [digital] boards */
858c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq default_digital[] = {
868c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
878c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
888c2ecf20Sopenharmony_ci};
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci/* Board :Zolid Hybrid Tv Stick */
918c2ecf20Sopenharmony_cistatic struct em28xx_reg_seq zolid_tuner[] = {
928c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,		0xfd,		0xff,	100},
938c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,		0xfe,		0xff,	100},
948c2ecf20Sopenharmony_ci	{		-1,					-1,			-1,		 -1},
958c2ecf20Sopenharmony_ci};
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_cistatic struct em28xx_reg_seq zolid_digital[] = {
988c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,		0x6a,		0xff,	100},
998c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,		0x7a,		0xff,	100},
1008c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,			0x04,		0xff,	100},
1018c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,			0x0c,		0xff,	100},
1028c2ecf20Sopenharmony_ci	{	-1,						-1,			-1,		 -1},
1038c2ecf20Sopenharmony_ci};
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci/* Board Hauppauge WinTV HVR 900 analog */
1068c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
1078c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x2d,	~EM_GPIO_4,	10},
1088c2ecf20Sopenharmony_ci	{	0x05,		0xff,	0x10,		10},
1098c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
1108c2ecf20Sopenharmony_ci};
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci/* Board Hauppauge WinTV HVR 900 digital */
1138c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
1148c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x2e,	~EM_GPIO_4,	10},
1158c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x04,	0x0f,		10},
1168c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x0c,	0x0f,		10},
1178c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
1188c2ecf20Sopenharmony_ci};
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci/* Board Hauppauge WinTV HVR 900 (R2) digital */
1218c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = {
1228c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x2e,	~EM_GPIO_4,	10},
1238c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x0c,	0x0f,		10},
1248c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
1258c2ecf20Sopenharmony_ci};
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
1288c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
1298c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x69,   ~EM_GPIO_4,	10},
1308c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
1318c2ecf20Sopenharmony_ci};
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci/* Board - EM2882 Kworld 315U digital */
1348c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq em2882_kworld_315u_digital[] = {
1358c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
1368c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xfe,	0xff,		10},
1378c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x04,	0xff,		10},
1388c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x0c,	0xff,		10},
1398c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x7e,	0xff,		10},
1408c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
1418c2ecf20Sopenharmony_ci};
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = {
1448c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x08,	0xff,		10},
1458c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x0c,	0xff,		10},
1468c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x08,	0xff,		10},
1478c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x0c,	0xff,		10},
1488c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
1498c2ecf20Sopenharmony_ci};
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq kworld_330u_analog[] = {
1528c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6d,	~EM_GPIO_4,	10},
1538c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x00,	0xff,		10},
1548c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
1558c2ecf20Sopenharmony_ci};
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq kworld_330u_digital[] = {
1588c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
1598c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x08,	0xff,		10},
1608c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
1618c2ecf20Sopenharmony_ci};
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci/*
1648c2ecf20Sopenharmony_ci * Evga inDtube
1658c2ecf20Sopenharmony_ci * GPIO0 - Enable digital power (s5h1409) - low to enable
1668c2ecf20Sopenharmony_ci * GPIO1 - Enable analog power (tvp5150/emp202) - low to enable
1678c2ecf20Sopenharmony_ci * GPIO4 - xc3028 reset
1688c2ecf20Sopenharmony_ci * GOP3  - s5h1409 reset
1698c2ecf20Sopenharmony_ci */
1708c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq evga_indtube_analog[] = {
1718c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x79,   0xff,		60},
1728c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
1738c2ecf20Sopenharmony_ci};
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq evga_indtube_digital[] = {
1768c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x7a,	0xff,		 1},
1778c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x04,	0xff,		10},
1788c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x0c,	0xff,		 1},
1798c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
1808c2ecf20Sopenharmony_ci};
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci/*
1838c2ecf20Sopenharmony_ci * KWorld PlusTV 340U, UB435-Q and UB435-Q V2 (ATSC) GPIOs map:
1848c2ecf20Sopenharmony_ci * EM_GPIO_0 - currently unknown
1858c2ecf20Sopenharmony_ci * EM_GPIO_1 - LED disable/enable (1 = off, 0 = on)
1868c2ecf20Sopenharmony_ci * EM_GPIO_2 - currently unknown
1878c2ecf20Sopenharmony_ci * EM_GPIO_3 - currently unknown
1888c2ecf20Sopenharmony_ci * EM_GPIO_4 - TDA18271HD/C1 tuner (1 = active, 0 = in reset)
1898c2ecf20Sopenharmony_ci * EM_GPIO_5 - LGDT3304 ATSC/QAM demod (1 = active, 0 = in reset)
1908c2ecf20Sopenharmony_ci * EM_GPIO_6 - currently unknown
1918c2ecf20Sopenharmony_ci * EM_GPIO_7 - currently unknown
1928c2ecf20Sopenharmony_ci */
1938c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq kworld_a340_digital[] = {
1948c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6d,	~EM_GPIO_4,	10},
1958c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
1968c2ecf20Sopenharmony_ci};
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq kworld_ub435q_v3_digital[] = {
1998c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	100},
2008c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfe,	0xff,	100},
2018c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xbe,	0xff,	100},
2028c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfe,	0xff,	100},
2038c2ecf20Sopenharmony_ci	{	-1,			-1,	-1,	-1},
2048c2ecf20Sopenharmony_ci};
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci/* Pinnacle Hybrid Pro eb1a:2881 */
2078c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = {
2088c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xfd,   ~EM_GPIO_4,	10},
2098c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
2108c2ecf20Sopenharmony_ci};
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = {
2138c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
2148c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x04,	0xff,	       100},/* zl10353 reset */
2158c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x0c,	0xff,		 1},
2168c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
2178c2ecf20Sopenharmony_ci};
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_analog[] = {
2208c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6d,	~EM_GPIO_4,	10},
2218c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x00,	0xff,		10},
2228c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
2238c2ecf20Sopenharmony_ci};
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = {
2268c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
2278c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x08,	0xff,		10},
2288c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
2298c2ecf20Sopenharmony_ci};
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci/*
2328c2ecf20Sopenharmony_ci * PCTV HD Mini (80e) GPIOs
2338c2ecf20Sopenharmony_ci * 0-5: not used
2348c2ecf20Sopenharmony_ci * 6:   demod reset, active low
2358c2ecf20Sopenharmony_ci * 7:   LED on, active high
2368c2ecf20Sopenharmony_ci */
2378c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq em2874_pctv_80e_digital[] = {
2388c2ecf20Sopenharmony_ci	{EM28XX_R06_I2C_CLK,    0x45,   0xff,		  10}, /*400 KHz*/
2398c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL, 0x00,   0xff,		  100},/*Demod reset*/
2408c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL, 0x40,   0xff,		  10},
2418c2ecf20Sopenharmony_ci	{  -1,			-1,	-1,		  -1},
2428c2ecf20Sopenharmony_ci};
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci/*
2458c2ecf20Sopenharmony_ci * eb1a:2868 Reddo DVB-C USB TV Box
2468c2ecf20Sopenharmony_ci * GPIO4 - CU1216L NIM
2478c2ecf20Sopenharmony_ci * Other GPIOs seems to be don't care.
2488c2ecf20Sopenharmony_ci */
2498c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq reddo_dvb_c_usb_box[] = {
2508c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xfe,	0xff,		10},
2518c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xde,	0xff,		10},
2528c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xfe,	0xff,		10},
2538c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
2548c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x7f,	0xff,		10},
2558c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6f,	0xff,		10},
2568c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
2578c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
2588c2ecf20Sopenharmony_ci};
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci/* Callback for the most boards */
2618c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq default_tuner_gpio[] = {
2628c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	EM_GPIO_4,	EM_GPIO_4,	10},
2638c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0,		EM_GPIO_4,	10},
2648c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	EM_GPIO_4,	EM_GPIO_4,	10},
2658c2ecf20Sopenharmony_ci	{	-1,		-1,		-1,		-1},
2668c2ecf20Sopenharmony_ci};
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci/* Mute/unmute */
2698c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq compro_unmute_tv_gpio[] = {
2708c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	5,	7,	10},
2718c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,	-1},
2728c2ecf20Sopenharmony_ci};
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq compro_unmute_svid_gpio[] = {
2758c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	4,	7,	10},
2768c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,	-1},
2778c2ecf20Sopenharmony_ci};
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq compro_mute_gpio[] = {
2808c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	6,	7,	10},
2818c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,	-1},
2828c2ecf20Sopenharmony_ci};
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci/* Terratec AV350 */
2858c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq terratec_av350_mute_gpio[] = {
2868c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0x7f,		10},
2878c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
2888c2ecf20Sopenharmony_ci};
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq terratec_av350_unmute_gpio[] = {
2918c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
2928c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
2938c2ecf20Sopenharmony_ci};
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq silvercrest_reg_seq[] = {
2968c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
2978c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x01,	0xf7,		10},
2988c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
2998c2ecf20Sopenharmony_ci};
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq vc211a_enable[] = {
3028c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0x07,		10},
3038c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0x0f,		10},
3048c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0xff,	0x0b,		10},
3058c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
3068c2ecf20Sopenharmony_ci};
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq dikom_dk300_digital[] = {
3098c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
3108c2ecf20Sopenharmony_ci	{EM2880_R04_GPO,	0x08,	0xff,		10},
3118c2ecf20Sopenharmony_ci	{	-1,		-1,	-1,		-1},
3128c2ecf20Sopenharmony_ci};
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_ci/* Reset for the most [digital] boards */
3158c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq leadership_digital[] = {
3168c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x70,	0xff,	10},
3178c2ecf20Sopenharmony_ci	{	-1,			-1,	-1,	-1},
3188c2ecf20Sopenharmony_ci};
3198c2ecf20Sopenharmony_ci
3208c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq leadership_reset[] = {
3218c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf0,	0xff,	10},
3228c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xb0,	0xff,	10},
3238c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf0,	0xff,	10},
3248c2ecf20Sopenharmony_ci	{	-1,			-1,	-1,	-1},
3258c2ecf20Sopenharmony_ci};
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_ci/*
3288c2ecf20Sopenharmony_ci * 2013:024f PCTV nanoStick T2 290e
3298c2ecf20Sopenharmony_ci * GPIO_6 - demod reset
3308c2ecf20Sopenharmony_ci * GPIO_7 - LED
3318c2ecf20Sopenharmony_ci */
3328c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq pctv_290e[] = {
3338c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x00,	0xff,	80},
3348c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x40,	0xff,	80}, /* GPIO_6 = 1 */
3358c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xc0,	0xff,	80}, /* GPIO_7 = 1 */
3368c2ecf20Sopenharmony_ci	{	-1,			-1,	-1,	-1},
3378c2ecf20Sopenharmony_ci};
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_ci#if 0
3408c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq terratec_h5_gpio[] = {
3418c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,		0xff,	0xff,	10},
3428c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
3438c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf2,	0xff,	50},
3448c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	50},
3458c2ecf20Sopenharmony_ci	{	-1,			-1,	-1,	-1},
3468c2ecf20Sopenharmony_ci};
3478c2ecf20Sopenharmony_ci
3488c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq terratec_h5_digital[] = {
3498c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	10},
3508c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
3518c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	10},
3528c2ecf20Sopenharmony_ci	{	-1,			-1,	-1,	-1},
3538c2ecf20Sopenharmony_ci};
3548c2ecf20Sopenharmony_ci#endif
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci/*
3578c2ecf20Sopenharmony_ci * 2013:024f PCTV DVB-S2 Stick 460e
3588c2ecf20Sopenharmony_ci * GPIO_0 - POWER_ON
3598c2ecf20Sopenharmony_ci * GPIO_1 - BOOST
3608c2ecf20Sopenharmony_ci * GPIO_2 - VUV_LNB (red LED)
3618c2ecf20Sopenharmony_ci * GPIO_3 - EXT_12V
3628c2ecf20Sopenharmony_ci * GPIO_4 - INT_DEM (DEMOD GPIO_0)
3638c2ecf20Sopenharmony_ci * GPIO_5 - INT_LNB
3648c2ecf20Sopenharmony_ci * GPIO_6 - RESET_DEM
3658c2ecf20Sopenharmony_ci * GPIO_7 - LED (green LED)
3668c2ecf20Sopenharmony_ci */
3678c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq pctv_460e[] = {
3688c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x01,	0xff,	50},
3698c2ecf20Sopenharmony_ci	{	0x0d,			0xff,	0xff,	50},
3708c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x41,	0xff,	50}, /* GPIO_6=1 */
3718c2ecf20Sopenharmony_ci	{	0x0d,			0x42,	0xff,	50},
3728c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x61,	0xff,	50}, /* GPIO_5=1 */
3738c2ecf20Sopenharmony_ci	{	-1,			-1,	-1,	-1},
3748c2ecf20Sopenharmony_ci};
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq c3tech_digital_duo_digital[] = {
3778c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	10},
3788c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfd,	0xff,	10}, /* xc5000 reset */
3798c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf9,	0xff,	35},
3808c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfd,	0xff,	10},
3818c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	10},
3828c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfe,	0xff,	10},
3838c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xbe,	0xff,	10},
3848c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfe,	0xff,	20},
3858c2ecf20Sopenharmony_ci	{	-1,			-1,	-1,	-1},
3868c2ecf20Sopenharmony_ci};
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ci/*
3898c2ecf20Sopenharmony_ci * 2013:0258 PCTV DVB-S2 Stick (461e)
3908c2ecf20Sopenharmony_ci * GPIO 0 = POWER_ON
3918c2ecf20Sopenharmony_ci * GPIO 1 = BOOST
3928c2ecf20Sopenharmony_ci * GPIO 2 = VUV_LNB (red LED)
3938c2ecf20Sopenharmony_ci * GPIO 3 = #EXT_12V
3948c2ecf20Sopenharmony_ci * GPIO 4 = INT_DEM
3958c2ecf20Sopenharmony_ci * GPIO 5 = INT_LNB
3968c2ecf20Sopenharmony_ci * GPIO 6 = #RESET_DEM
3978c2ecf20Sopenharmony_ci * GPIO 7 = P07_LED (green LED)
3988c2ecf20Sopenharmony_ci */
3998c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq pctv_461e[] = {
4008c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0x7f, 0xff,    0},
4018c2ecf20Sopenharmony_ci	{0x0d,                 0xff, 0xff,    0},
4028c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0x3f, 0xff,  100}, /* reset demod */
4038c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0x7f, 0xff,  200}, /* reset demod */
4048c2ecf20Sopenharmony_ci	{0x0d,                 0x42, 0xff,    0},
4058c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xeb, 0xff,    0},
4068c2ecf20Sopenharmony_ci	{EM2874_R5F_TS_ENABLE, 0x84, 0x84,    0}, /* parallel? | null discard */
4078c2ecf20Sopenharmony_ci	{                  -1,   -1,   -1,   -1},
4088c2ecf20Sopenharmony_ci};
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_ci#if 0
4118c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq hauppauge_930c_gpio[] = {
4128c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x6f,	0xff,	10},
4138c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x4f,	0xff,	10}, /* xc5000 reset */
4148c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x6f,	0xff,	10},
4158c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x4f,	0xff,	10},
4168c2ecf20Sopenharmony_ci	{	-1,			-1,	-1,	-1},
4178c2ecf20Sopenharmony_ci};
4188c2ecf20Sopenharmony_ci
4198c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq hauppauge_930c_digital[] = {
4208c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	10},
4218c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
4228c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	10},
4238c2ecf20Sopenharmony_ci	{	-1,			-1,	-1,	-1},
4248c2ecf20Sopenharmony_ci};
4258c2ecf20Sopenharmony_ci#endif
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_ci/*
4288c2ecf20Sopenharmony_ci * 1b80:e425 MaxMedia UB425-TC
4298c2ecf20Sopenharmony_ci * 1b80:e1cc Delock 61959
4308c2ecf20Sopenharmony_ci * GPIO_6 - demod reset, 0=active
4318c2ecf20Sopenharmony_ci * GPIO_7 - LED, 0=active
4328c2ecf20Sopenharmony_ci */
4338c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq maxmedia_ub425_tc[] = {
4348c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x83,	0xff,	100},
4358c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xc3,	0xff,	100}, /* GPIO_6 = 1 */
4368c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x43,	0xff,	000}, /* GPIO_7 = 0 */
4378c2ecf20Sopenharmony_ci	{	-1,			-1,	-1,	-1},
4388c2ecf20Sopenharmony_ci};
4398c2ecf20Sopenharmony_ci
4408c2ecf20Sopenharmony_ci/*
4418c2ecf20Sopenharmony_ci * 2304:0242 PCTV QuatroStick (510e)
4428c2ecf20Sopenharmony_ci * GPIO_2: decoder reset, 0=active
4438c2ecf20Sopenharmony_ci * GPIO_4: decoder suspend, 0=active
4448c2ecf20Sopenharmony_ci * GPIO_6: demod reset, 0=active
4458c2ecf20Sopenharmony_ci * GPIO_7: LED, 1=active
4468c2ecf20Sopenharmony_ci */
4478c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq pctv_510e[] = {
4488c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x10,	0xff,	100},
4498c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x14,	0xff,	100}, /* GPIO_2 = 1 */
4508c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x54,	0xff,	050}, /* GPIO_6 = 1 */
4518c2ecf20Sopenharmony_ci	{	-1,			-1,	-1,	-1},
4528c2ecf20Sopenharmony_ci};
4538c2ecf20Sopenharmony_ci
4548c2ecf20Sopenharmony_ci/*
4558c2ecf20Sopenharmony_ci * 2013:0251 PCTV QuatroStick nano (520e)
4568c2ecf20Sopenharmony_ci * GPIO_2: decoder reset, 0=active
4578c2ecf20Sopenharmony_ci * GPIO_4: decoder suspend, 0=active
4588c2ecf20Sopenharmony_ci * GPIO_6: demod reset, 0=active
4598c2ecf20Sopenharmony_ci * GPIO_7: LED, 1=active
4608c2ecf20Sopenharmony_ci */
4618c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq pctv_520e[] = {
4628c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x10,	0xff,	100},
4638c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x14,	0xff,	100}, /* GPIO_2 = 1 */
4648c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x54,	0xff,	050}, /* GPIO_6 = 1 */
4658c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xd4,	0xff,	000}, /* GPIO_7 = 1 */
4668c2ecf20Sopenharmony_ci	{	-1,			-1,	-1,	-1},
4678c2ecf20Sopenharmony_ci};
4688c2ecf20Sopenharmony_ci
4698c2ecf20Sopenharmony_ci/*
4708c2ecf20Sopenharmony_ci * 1ae7:9003/9004 SpeedLink Vicious And Devine Laplace webcam
4718c2ecf20Sopenharmony_ci * reg 0x80/0x84:
4728c2ecf20Sopenharmony_ci * GPIO_0: capturing LED, 0=on, 1=off
4738c2ecf20Sopenharmony_ci * GPIO_2: AV mute button, 0=pressed, 1=unpressed
4748c2ecf20Sopenharmony_ci * GPIO 3: illumination button, 0=pressed, 1=unpressed
4758c2ecf20Sopenharmony_ci * GPIO_6: illumination/flash LED, 0=on, 1=off
4768c2ecf20Sopenharmony_ci * reg 0x81/0x85:
4778c2ecf20Sopenharmony_ci * GPIO_7: snapshot button, 0=pressed, 1=unpressed
4788c2ecf20Sopenharmony_ci */
4798c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq speedlink_vad_laplace_reg_seq[] = {
4808c2ecf20Sopenharmony_ci	{EM2820_R08_GPIO_CTRL,		0xf7,	0xff,	10},
4818c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xb2,	10},
4828c2ecf20Sopenharmony_ci	{	-1,			-1,	-1,	-1},
4838c2ecf20Sopenharmony_ci};
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq pctv_292e[] = {
4868c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xff, 0xff,      0},
4878c2ecf20Sopenharmony_ci	{0x0d,                         0xff, 0xff,    950},
4888c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xbd, 0xff,    100},
4898c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xfd, 0xff,    410},
4908c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0x7d, 0xff,    300},
4918c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0x7c, 0xff,     60},
4928c2ecf20Sopenharmony_ci	{0x0d,                         0x42, 0xff,     50},
4938c2ecf20Sopenharmony_ci	{EM2874_R5F_TS_ENABLE,         0x85, 0xff,      0},
4948c2ecf20Sopenharmony_ci	{-1,                             -1,   -1,     -1},
4958c2ecf20Sopenharmony_ci};
4968c2ecf20Sopenharmony_ci
4978c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq terratec_t2_stick_hd[] = {
4988c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	0},
4998c2ecf20Sopenharmony_ci	{0x0d,				0xff,	0xff,	600},
5008c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfc,	0xff,	10},
5018c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xbc,	0xff,	100},
5028c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfc,	0xff,	100},
5038c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0x00,	0xff,	300},
5048c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xf8,	0xff,	100},
5058c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfc,	0xff,	300},
5068c2ecf20Sopenharmony_ci	{0x0d,				0x42,	0xff,	1000},
5078c2ecf20Sopenharmony_ci	{EM2874_R5F_TS_ENABLE,		0x85,	0xff,	0},
5088c2ecf20Sopenharmony_ci	{-1,                             -1,   -1,     -1},
5098c2ecf20Sopenharmony_ci};
5108c2ecf20Sopenharmony_ci
5118c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq plex_px_bcud[] = {
5128c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	0},
5138c2ecf20Sopenharmony_ci	{0x0d,				0xff,	0xff,	0},
5148c2ecf20Sopenharmony_ci	{EM2874_R50_IR_CONFIG,		0x01,	0xff,	0},
5158c2ecf20Sopenharmony_ci	{EM28XX_R06_I2C_CLK,		0x40,	0xff,	0},
5168c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfd,	0xff,	100},
5178c2ecf20Sopenharmony_ci	{EM28XX_R12_VINENABLE,		0x20,	0x20,	0},
5188c2ecf20Sopenharmony_ci	{0x0d,				0x42,	0xff,	1000},
5198c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfc,	0xff,	10},
5208c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,	0xfd,	0xff,	10},
5218c2ecf20Sopenharmony_ci	{0x73,				0xfd,	0xff,	100},
5228c2ecf20Sopenharmony_ci	{-1,				-1,	-1,	-1},
5238c2ecf20Sopenharmony_ci};
5248c2ecf20Sopenharmony_ci
5258c2ecf20Sopenharmony_ci/*
5268c2ecf20Sopenharmony_ci * 2040:0265 Hauppauge WinTV-dualHD DVB Isoc
5278c2ecf20Sopenharmony_ci * 2040:8265 Hauppauge WinTV-dualHD DVB Bulk
5288c2ecf20Sopenharmony_ci * 2040:026d Hauppauge WinTV-dualHD ATSC/QAM Isoc
5298c2ecf20Sopenharmony_ci * 2040:826d Hauppauge WinTV-dualHD ATSC/QAM Bulk
5308c2ecf20Sopenharmony_ci * reg 0x80/0x84:
5318c2ecf20Sopenharmony_ci * GPIO_0: Yellow LED tuner 1, 0=on, 1=off
5328c2ecf20Sopenharmony_ci * GPIO_1: Green LED tuner 1, 0=on, 1=off
5338c2ecf20Sopenharmony_ci * GPIO_2: Yellow LED tuner 2, 0=on, 1=off
5348c2ecf20Sopenharmony_ci * GPIO_3: Green LED tuner 2, 0=on, 1=off
5358c2ecf20Sopenharmony_ci * GPIO_5: Reset #2, 0=active
5368c2ecf20Sopenharmony_ci * GPIO_6: Reset #1, 0=active
5378c2ecf20Sopenharmony_ci */
5388c2ecf20Sopenharmony_cistatic const struct em28xx_reg_seq hauppauge_dualhd_dvb[] = {
5398c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xff, 0xff,      0},
5408c2ecf20Sopenharmony_ci	{0x0d,                         0xff, 0xff,    200},
5418c2ecf20Sopenharmony_ci	{0x50,                         0x04, 0xff,    300},
5428c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xbf, 0xff,    100}, /* demod 1 reset */
5438c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xff, 0xff,    100},
5448c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xdf, 0xff,    100}, /* demod 2 reset */
5458c2ecf20Sopenharmony_ci	{EM2874_R80_GPIO_P0_CTRL,      0xff, 0xff,    100},
5468c2ecf20Sopenharmony_ci	{EM2874_R5F_TS_ENABLE,         0x00, 0xff,     50}, /* disable TS filters */
5478c2ecf20Sopenharmony_ci	{EM2874_R5D_TS1_PKT_SIZE,      0x05, 0xff,     50},
5488c2ecf20Sopenharmony_ci	{EM2874_R5E_TS2_PKT_SIZE,      0x05, 0xff,     50},
5498c2ecf20Sopenharmony_ci	{-1,                             -1,   -1,     -1},
5508c2ecf20Sopenharmony_ci};
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci/*
5538c2ecf20Sopenharmony_ci *  Button definitions
5548c2ecf20Sopenharmony_ci */
5558c2ecf20Sopenharmony_cistatic const struct em28xx_button std_snapshot_button[] = {
5568c2ecf20Sopenharmony_ci	{
5578c2ecf20Sopenharmony_ci		.role         = EM28XX_BUTTON_SNAPSHOT,
5588c2ecf20Sopenharmony_ci		.reg_r        = EM28XX_R0C_USBSUSP,
5598c2ecf20Sopenharmony_ci		.reg_clearing = EM28XX_R0C_USBSUSP,
5608c2ecf20Sopenharmony_ci		.mask         = EM28XX_R0C_USBSUSP_SNAPSHOT,
5618c2ecf20Sopenharmony_ci		.inverted     = 0,
5628c2ecf20Sopenharmony_ci	},
5638c2ecf20Sopenharmony_ci	{-1, 0, 0, 0, 0},
5648c2ecf20Sopenharmony_ci};
5658c2ecf20Sopenharmony_ci
5668c2ecf20Sopenharmony_cistatic const struct em28xx_button speedlink_vad_laplace_buttons[] = {
5678c2ecf20Sopenharmony_ci	{
5688c2ecf20Sopenharmony_ci		.role     = EM28XX_BUTTON_SNAPSHOT,
5698c2ecf20Sopenharmony_ci		.reg_r    = EM2874_R85_GPIO_P1_STATE,
5708c2ecf20Sopenharmony_ci		.mask     = 0x80,
5718c2ecf20Sopenharmony_ci		.inverted = 1,
5728c2ecf20Sopenharmony_ci	},
5738c2ecf20Sopenharmony_ci	{
5748c2ecf20Sopenharmony_ci		.role     = EM28XX_BUTTON_ILLUMINATION,
5758c2ecf20Sopenharmony_ci		.reg_r    = EM2874_R84_GPIO_P0_STATE,
5768c2ecf20Sopenharmony_ci		.mask     = 0x08,
5778c2ecf20Sopenharmony_ci		.inverted = 1,
5788c2ecf20Sopenharmony_ci	},
5798c2ecf20Sopenharmony_ci	{-1, 0, 0, 0, 0},
5808c2ecf20Sopenharmony_ci};
5818c2ecf20Sopenharmony_ci
5828c2ecf20Sopenharmony_ci/*
5838c2ecf20Sopenharmony_ci *  LED definitions
5848c2ecf20Sopenharmony_ci */
5858c2ecf20Sopenharmony_cistatic struct em28xx_led speedlink_vad_laplace_leds[] = {
5868c2ecf20Sopenharmony_ci	{
5878c2ecf20Sopenharmony_ci		.role      = EM28XX_LED_ANALOG_CAPTURING,
5888c2ecf20Sopenharmony_ci		.gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
5898c2ecf20Sopenharmony_ci		.gpio_mask = 0x01,
5908c2ecf20Sopenharmony_ci		.inverted  = 1,
5918c2ecf20Sopenharmony_ci	},
5928c2ecf20Sopenharmony_ci	{
5938c2ecf20Sopenharmony_ci		.role      = EM28XX_LED_ILLUMINATION,
5948c2ecf20Sopenharmony_ci		.gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
5958c2ecf20Sopenharmony_ci		.gpio_mask = 0x40,
5968c2ecf20Sopenharmony_ci		.inverted  = 1,
5978c2ecf20Sopenharmony_ci	},
5988c2ecf20Sopenharmony_ci	{-1, 0, 0, 0},
5998c2ecf20Sopenharmony_ci};
6008c2ecf20Sopenharmony_ci
6018c2ecf20Sopenharmony_cistatic struct em28xx_led kworld_ub435q_v3_leds[] = {
6028c2ecf20Sopenharmony_ci	{
6038c2ecf20Sopenharmony_ci		.role      = EM28XX_LED_DIGITAL_CAPTURING,
6048c2ecf20Sopenharmony_ci		.gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
6058c2ecf20Sopenharmony_ci		.gpio_mask = 0x80,
6068c2ecf20Sopenharmony_ci		.inverted  = 1,
6078c2ecf20Sopenharmony_ci	},
6088c2ecf20Sopenharmony_ci	{-1, 0, 0, 0},
6098c2ecf20Sopenharmony_ci};
6108c2ecf20Sopenharmony_ci
6118c2ecf20Sopenharmony_cistatic struct em28xx_led pctv_80e_leds[] = {
6128c2ecf20Sopenharmony_ci	{
6138c2ecf20Sopenharmony_ci		.role      = EM28XX_LED_DIGITAL_CAPTURING,
6148c2ecf20Sopenharmony_ci		.gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
6158c2ecf20Sopenharmony_ci		.gpio_mask = 0x80,
6168c2ecf20Sopenharmony_ci		.inverted  = 0,
6178c2ecf20Sopenharmony_ci	},
6188c2ecf20Sopenharmony_ci	{-1, 0, 0, 0},
6198c2ecf20Sopenharmony_ci};
6208c2ecf20Sopenharmony_ci
6218c2ecf20Sopenharmony_cistatic struct em28xx_led terratec_grabby_leds[] = {
6228c2ecf20Sopenharmony_ci	{
6238c2ecf20Sopenharmony_ci		.role      = EM28XX_LED_ANALOG_CAPTURING,
6248c2ecf20Sopenharmony_ci		.gpio_reg  = EM2820_R08_GPIO_CTRL,
6258c2ecf20Sopenharmony_ci		.gpio_mask = EM_GPIO_3,
6268c2ecf20Sopenharmony_ci		.inverted  = 1,
6278c2ecf20Sopenharmony_ci	},
6288c2ecf20Sopenharmony_ci	{-1, 0, 0, 0},
6298c2ecf20Sopenharmony_ci};
6308c2ecf20Sopenharmony_ci
6318c2ecf20Sopenharmony_cistatic struct em28xx_led hauppauge_dualhd_leds[] = {
6328c2ecf20Sopenharmony_ci	{
6338c2ecf20Sopenharmony_ci		.role      = EM28XX_LED_DIGITAL_CAPTURING,
6348c2ecf20Sopenharmony_ci		.gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
6358c2ecf20Sopenharmony_ci		.gpio_mask = EM_GPIO_1,
6368c2ecf20Sopenharmony_ci		.inverted  = 1,
6378c2ecf20Sopenharmony_ci	},
6388c2ecf20Sopenharmony_ci	{
6398c2ecf20Sopenharmony_ci		.role      = EM28XX_LED_DIGITAL_CAPTURING_TS2,
6408c2ecf20Sopenharmony_ci		.gpio_reg  = EM2874_R80_GPIO_P0_CTRL,
6418c2ecf20Sopenharmony_ci		.gpio_mask = EM_GPIO_3,
6428c2ecf20Sopenharmony_ci		.inverted  = 1,
6438c2ecf20Sopenharmony_ci	},
6448c2ecf20Sopenharmony_ci	{-1, 0, 0, 0},
6458c2ecf20Sopenharmony_ci};
6468c2ecf20Sopenharmony_ci
6478c2ecf20Sopenharmony_ci/*
6488c2ecf20Sopenharmony_ci *  Board definitions
6498c2ecf20Sopenharmony_ci */
6508c2ecf20Sopenharmony_ciconst struct em28xx_board em28xx_boards[] = {
6518c2ecf20Sopenharmony_ci	[EM2750_BOARD_UNKNOWN] = {
6528c2ecf20Sopenharmony_ci		.name          = "EM2710/EM2750/EM2751 webcam grabber",
6538c2ecf20Sopenharmony_ci		.xclk          = EM28XX_XCLK_FREQUENCY_20MHZ,
6548c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
6558c2ecf20Sopenharmony_ci		.is_webcam     = 1,
6568c2ecf20Sopenharmony_ci		.input         = { {
6578c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
6588c2ecf20Sopenharmony_ci			.vmux     = 0,
6598c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
6608c2ecf20Sopenharmony_ci			.gpio     = silvercrest_reg_seq,
6618c2ecf20Sopenharmony_ci		} },
6628c2ecf20Sopenharmony_ci	},
6638c2ecf20Sopenharmony_ci	[EM2800_BOARD_UNKNOWN] = {
6648c2ecf20Sopenharmony_ci		.name         = "Unknown EM2800 video grabber",
6658c2ecf20Sopenharmony_ci		.is_em2800    = 1,
6668c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
6678c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
6688c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
6698c2ecf20Sopenharmony_ci		.input        = { {
6708c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
6718c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
6728c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
6738c2ecf20Sopenharmony_ci		}, {
6748c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
6758c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
6768c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
6778c2ecf20Sopenharmony_ci		} },
6788c2ecf20Sopenharmony_ci	},
6798c2ecf20Sopenharmony_ci	[EM2820_BOARD_UNKNOWN] = {
6808c2ecf20Sopenharmony_ci		.name          = "Unknown EM2750/28xx video grabber",
6818c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
6828c2ecf20Sopenharmony_ci		.is_webcam     = 1,	/* To enable sensor probe */
6838c2ecf20Sopenharmony_ci	},
6848c2ecf20Sopenharmony_ci	[EM2882_BOARD_ZOLID_HYBRID_TV_STICK] = {
6858c2ecf20Sopenharmony_ci		.name			= ":ZOLID HYBRID TV STICK",
6868c2ecf20Sopenharmony_ci		.tuner_type		= TUNER_XC2028,
6878c2ecf20Sopenharmony_ci		.tuner_gpio		= zolid_tuner,
6888c2ecf20Sopenharmony_ci		.decoder		= EM28XX_TVP5150,
6898c2ecf20Sopenharmony_ci		.xclk			= EM28XX_XCLK_FREQUENCY_12MHZ,
6908c2ecf20Sopenharmony_ci		.mts_firmware	= 1,
6918c2ecf20Sopenharmony_ci		.has_dvb		= 1,
6928c2ecf20Sopenharmony_ci		.dvb_gpio		= zolid_digital,
6938c2ecf20Sopenharmony_ci	},
6948c2ecf20Sopenharmony_ci	[EM2750_BOARD_DLCW_130] = {
6958c2ecf20Sopenharmony_ci		/* Beijing Huaqi Information Digital Technology Co., Ltd */
6968c2ecf20Sopenharmony_ci		.name          = "Huaqi DLCW-130",
6978c2ecf20Sopenharmony_ci		.valid         = EM28XX_BOARD_NOT_VALIDATED,
6988c2ecf20Sopenharmony_ci		.xclk          = EM28XX_XCLK_FREQUENCY_48MHZ,
6998c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
7008c2ecf20Sopenharmony_ci		.is_webcam     = 1,
7018c2ecf20Sopenharmony_ci		.input         = { {
7028c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
7038c2ecf20Sopenharmony_ci			.vmux     = 0,
7048c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
7058c2ecf20Sopenharmony_ci		} },
7068c2ecf20Sopenharmony_ci	},
7078c2ecf20Sopenharmony_ci	[EM2820_BOARD_KWORLD_PVRTV2800RF] = {
7088c2ecf20Sopenharmony_ci		.name         = "Kworld PVR TV 2800 RF",
7098c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_TEMIC_PAL,
7108c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
7118c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
7128c2ecf20Sopenharmony_ci		.input        = { {
7138c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
7148c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
7158c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
7168c2ecf20Sopenharmony_ci		}, {
7178c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
7188c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
7198c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
7208c2ecf20Sopenharmony_ci		} },
7218c2ecf20Sopenharmony_ci	},
7228c2ecf20Sopenharmony_ci	[EM2820_BOARD_GADMEI_TVR200] = {
7238c2ecf20Sopenharmony_ci		.name         = "Gadmei TVR200",
7248c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
7258c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
7268c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
7278c2ecf20Sopenharmony_ci		.input        = { {
7288c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
7298c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
7308c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
7318c2ecf20Sopenharmony_ci		}, {
7328c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
7338c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
7348c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
7358c2ecf20Sopenharmony_ci		}, {
7368c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
7378c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
7388c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
7398c2ecf20Sopenharmony_ci		} },
7408c2ecf20Sopenharmony_ci	},
7418c2ecf20Sopenharmony_ci	[EM2820_BOARD_TERRATEC_CINERGY_250] = {
7428c2ecf20Sopenharmony_ci		.name         = "Terratec Cinergy 250 USB",
7438c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
7448c2ecf20Sopenharmony_ci		.has_ir_i2c   = 1,
7458c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
7468c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
7478c2ecf20Sopenharmony_ci		.input        = { {
7488c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
7498c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
7508c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
7518c2ecf20Sopenharmony_ci		}, {
7528c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
7538c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
7548c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
7558c2ecf20Sopenharmony_ci		}, {
7568c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
7578c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
7588c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
7598c2ecf20Sopenharmony_ci		} },
7608c2ecf20Sopenharmony_ci	},
7618c2ecf20Sopenharmony_ci	[EM2820_BOARD_PINNACLE_USB_2] = {
7628c2ecf20Sopenharmony_ci		.name         = "Pinnacle PCTV USB 2",
7638c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
7648c2ecf20Sopenharmony_ci		.has_ir_i2c   = 1,
7658c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
7668c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
7678c2ecf20Sopenharmony_ci		.input        = { {
7688c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
7698c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
7708c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
7718c2ecf20Sopenharmony_ci		}, {
7728c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
7738c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
7748c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
7758c2ecf20Sopenharmony_ci		}, {
7768c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
7778c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
7788c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
7798c2ecf20Sopenharmony_ci		} },
7808c2ecf20Sopenharmony_ci	},
7818c2ecf20Sopenharmony_ci	[EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = {
7828c2ecf20Sopenharmony_ci		.name         = "Hauppauge WinTV USB 2",
7838c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_FM1236_MK3,
7848c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT |
7858c2ecf20Sopenharmony_ci				TDA9887_PORT1_ACTIVE |
7868c2ecf20Sopenharmony_ci				TDA9887_PORT2_ACTIVE,
7878c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
7888c2ecf20Sopenharmony_ci		.has_msp34xx  = 1,
7898c2ecf20Sopenharmony_ci		.has_ir_i2c   = 1,
7908c2ecf20Sopenharmony_ci		.input        = { {
7918c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
7928c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
7938c2ecf20Sopenharmony_ci			.amux     = MSP_INPUT_DEFAULT,
7948c2ecf20Sopenharmony_ci		}, {
7958c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
7968c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
7978c2ecf20Sopenharmony_ci			.amux     = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
7988c2ecf20Sopenharmony_ci					MSP_DSP_IN_SCART, MSP_DSP_IN_SCART),
7998c2ecf20Sopenharmony_ci		} },
8008c2ecf20Sopenharmony_ci	},
8018c2ecf20Sopenharmony_ci	[EM2820_BOARD_DLINK_USB_TV] = {
8028c2ecf20Sopenharmony_ci		.name         = "D-Link DUB-T210 TV Tuner",
8038c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
8048c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
8058c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
8068c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
8078c2ecf20Sopenharmony_ci		.input        = { {
8088c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
8098c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
8108c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
8118c2ecf20Sopenharmony_ci		}, {
8128c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
8138c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
8148c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
8158c2ecf20Sopenharmony_ci		}, {
8168c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
8178c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
8188c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
8198c2ecf20Sopenharmony_ci		} },
8208c2ecf20Sopenharmony_ci	},
8218c2ecf20Sopenharmony_ci	[EM2820_BOARD_HERCULES_SMART_TV_USB2] = {
8228c2ecf20Sopenharmony_ci		.name         = "Hercules Smart TV USB 2.0",
8238c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
8248c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
8258c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
8268c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
8278c2ecf20Sopenharmony_ci		.input        = { {
8288c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
8298c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
8308c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
8318c2ecf20Sopenharmony_ci		}, {
8328c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
8338c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
8348c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
8358c2ecf20Sopenharmony_ci		}, {
8368c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
8378c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
8388c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
8398c2ecf20Sopenharmony_ci		} },
8408c2ecf20Sopenharmony_ci	},
8418c2ecf20Sopenharmony_ci	[EM2820_BOARD_PINNACLE_USB_2_FM1216ME] = {
8428c2ecf20Sopenharmony_ci		.name         = "Pinnacle PCTV USB 2 (Philips FM1216ME)",
8438c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
8448c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_FM1216ME_MK3,
8458c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
8468c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
8478c2ecf20Sopenharmony_ci		.input        = { {
8488c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
8498c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
8508c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
8518c2ecf20Sopenharmony_ci		}, {
8528c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
8538c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
8548c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
8558c2ecf20Sopenharmony_ci		}, {
8568c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
8578c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
8588c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
8598c2ecf20Sopenharmony_ci		} },
8608c2ecf20Sopenharmony_ci	},
8618c2ecf20Sopenharmony_ci	[EM2820_BOARD_GADMEI_UTV310] = {
8628c2ecf20Sopenharmony_ci		.name         = "Gadmei UTV310",
8638c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
8648c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_TNF_5335MF,
8658c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
8668c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
8678c2ecf20Sopenharmony_ci		.input        = { {
8688c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
8698c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE1,
8708c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
8718c2ecf20Sopenharmony_ci		}, {
8728c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
8738c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
8748c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
8758c2ecf20Sopenharmony_ci		}, {
8768c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
8778c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
8788c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
8798c2ecf20Sopenharmony_ci		} },
8808c2ecf20Sopenharmony_ci	},
8818c2ecf20Sopenharmony_ci	[EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE] = {
8828c2ecf20Sopenharmony_ci		.name         = "Leadtek Winfast USB II Deluxe",
8838c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
8848c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_FM1216ME_MK3,
8858c2ecf20Sopenharmony_ci		.has_ir_i2c   = 1,
8868c2ecf20Sopenharmony_ci		.tvaudio_addr = 0x58,
8878c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT |
8888c2ecf20Sopenharmony_ci				TDA9887_PORT2_ACTIVE |
8898c2ecf20Sopenharmony_ci				TDA9887_QSS,
8908c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
8918c2ecf20Sopenharmony_ci		.adecoder     = EM28XX_TVAUDIO,
8928c2ecf20Sopenharmony_ci		.input        = { {
8938c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
8948c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE4,
8958c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_AUX,
8968c2ecf20Sopenharmony_ci		}, {
8978c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
8988c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE5,
8998c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
9008c2ecf20Sopenharmony_ci		}, {
9018c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
9028c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
9038c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
9048c2ecf20Sopenharmony_ci		} },
9058c2ecf20Sopenharmony_ci			.radio	  = {
9068c2ecf20Sopenharmony_ci			.type     = EM28XX_RADIO,
9078c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_AUX,
9088c2ecf20Sopenharmony_ci			}
9098c2ecf20Sopenharmony_ci	},
9108c2ecf20Sopenharmony_ci	[EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
9118c2ecf20Sopenharmony_ci		.name         = "Videology 20K14XUSB USB2.0",
9128c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
9138c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
9148c2ecf20Sopenharmony_ci		.is_webcam    = 1,
9158c2ecf20Sopenharmony_ci		.input        = { {
9168c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
9178c2ecf20Sopenharmony_ci			.vmux     = 0,
9188c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
9198c2ecf20Sopenharmony_ci		} },
9208c2ecf20Sopenharmony_ci	},
9218c2ecf20Sopenharmony_ci	[EM2820_BOARD_SILVERCREST_WEBCAM] = {
9228c2ecf20Sopenharmony_ci		.name         = "Silvercrest Webcam 1.3mpix",
9238c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
9248c2ecf20Sopenharmony_ci		.is_webcam    = 1,
9258c2ecf20Sopenharmony_ci		.input        = { {
9268c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
9278c2ecf20Sopenharmony_ci			.vmux     = 0,
9288c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
9298c2ecf20Sopenharmony_ci			.gpio     = silvercrest_reg_seq,
9308c2ecf20Sopenharmony_ci		} },
9318c2ecf20Sopenharmony_ci	},
9328c2ecf20Sopenharmony_ci	[EM2821_BOARD_SUPERCOMP_USB_2] = {
9338c2ecf20Sopenharmony_ci		.name         = "Supercomp USB 2.0 TV",
9348c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
9358c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_FM1236_MK3,
9368c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT |
9378c2ecf20Sopenharmony_ci				TDA9887_PORT1_ACTIVE |
9388c2ecf20Sopenharmony_ci				TDA9887_PORT2_ACTIVE,
9398c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
9408c2ecf20Sopenharmony_ci		.input        = { {
9418c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
9428c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
9438c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
9448c2ecf20Sopenharmony_ci		}, {
9458c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
9468c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
9478c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
9488c2ecf20Sopenharmony_ci		}, {
9498c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
9508c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
9518c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
9528c2ecf20Sopenharmony_ci		} },
9538c2ecf20Sopenharmony_ci	},
9548c2ecf20Sopenharmony_ci	[EM2821_BOARD_USBGEAR_VD204] = {
9558c2ecf20Sopenharmony_ci		.name         = "Usbgear VD204v9",
9568c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
9578c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,	/* Capture only device */
9588c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
9598c2ecf20Sopenharmony_ci		.input        = { {
9608c2ecf20Sopenharmony_ci			.type  = EM28XX_VMUX_COMPOSITE,
9618c2ecf20Sopenharmony_ci			.vmux  = SAA7115_COMPOSITE0,
9628c2ecf20Sopenharmony_ci			.amux  = EM28XX_AMUX_LINE_IN,
9638c2ecf20Sopenharmony_ci		}, {
9648c2ecf20Sopenharmony_ci			.type  = EM28XX_VMUX_SVIDEO,
9658c2ecf20Sopenharmony_ci			.vmux  = SAA7115_SVIDEO3,
9668c2ecf20Sopenharmony_ci			.amux  = EM28XX_AMUX_LINE_IN,
9678c2ecf20Sopenharmony_ci		} },
9688c2ecf20Sopenharmony_ci	},
9698c2ecf20Sopenharmony_ci	[EM2860_BOARD_NETGMBH_CAM] = {
9708c2ecf20Sopenharmony_ci		/* Beijing Huaqi Information Digital Technology Co., Ltd */
9718c2ecf20Sopenharmony_ci		.name         = "NetGMBH Cam",
9728c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
9738c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
9748c2ecf20Sopenharmony_ci		.is_webcam    = 1,
9758c2ecf20Sopenharmony_ci		.input        = { {
9768c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
9778c2ecf20Sopenharmony_ci			.vmux     = 0,
9788c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
9798c2ecf20Sopenharmony_ci		} },
9808c2ecf20Sopenharmony_ci	},
9818c2ecf20Sopenharmony_ci	[EM2860_BOARD_TYPHOON_DVD_MAKER] = {
9828c2ecf20Sopenharmony_ci		.name         = "Typhoon DVD Maker",
9838c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
9848c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,	/* Capture only device */
9858c2ecf20Sopenharmony_ci		.input        = { {
9868c2ecf20Sopenharmony_ci			.type  = EM28XX_VMUX_COMPOSITE,
9878c2ecf20Sopenharmony_ci			.vmux  = SAA7115_COMPOSITE0,
9888c2ecf20Sopenharmony_ci			.amux  = EM28XX_AMUX_LINE_IN,
9898c2ecf20Sopenharmony_ci		}, {
9908c2ecf20Sopenharmony_ci			.type  = EM28XX_VMUX_SVIDEO,
9918c2ecf20Sopenharmony_ci			.vmux  = SAA7115_SVIDEO3,
9928c2ecf20Sopenharmony_ci			.amux  = EM28XX_AMUX_LINE_IN,
9938c2ecf20Sopenharmony_ci		} },
9948c2ecf20Sopenharmony_ci	},
9958c2ecf20Sopenharmony_ci	[EM2860_BOARD_GADMEI_UTV330] = {
9968c2ecf20Sopenharmony_ci		.name         = "Gadmei UTV330",
9978c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
9988c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_TNF_5335MF,
9998c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
10008c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
10018c2ecf20Sopenharmony_ci		.input        = { {
10028c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
10038c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
10048c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
10058c2ecf20Sopenharmony_ci		}, {
10068c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
10078c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
10088c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
10098c2ecf20Sopenharmony_ci		}, {
10108c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
10118c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
10128c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
10138c2ecf20Sopenharmony_ci		} },
10148c2ecf20Sopenharmony_ci	},
10158c2ecf20Sopenharmony_ci	[EM2861_BOARD_GADMEI_UTV330PLUS] = {
10168c2ecf20Sopenharmony_ci		.name         = "Gadmei UTV330+",
10178c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_TNF_5335MF,
10188c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
10198c2ecf20Sopenharmony_ci		.ir_codes     = RC_MAP_GADMEI_RM008Z,
10208c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
10218c2ecf20Sopenharmony_ci		.xclk         = EM28XX_XCLK_FREQUENCY_12MHZ,
10228c2ecf20Sopenharmony_ci		.input        = { {
10238c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
10248c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
10258c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
10268c2ecf20Sopenharmony_ci		}, {
10278c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
10288c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
10298c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
10308c2ecf20Sopenharmony_ci		}, {
10318c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
10328c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
10338c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
10348c2ecf20Sopenharmony_ci		} },
10358c2ecf20Sopenharmony_ci	},
10368c2ecf20Sopenharmony_ci	[EM2860_BOARD_TERRATEC_HYBRID_XS] = {
10378c2ecf20Sopenharmony_ci		.name         = "Terratec Cinergy A Hybrid XS",
10388c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
10398c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
10408c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
10418c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
10428c2ecf20Sopenharmony_ci
10438c2ecf20Sopenharmony_ci		.input        = { {
10448c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
10458c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
10468c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
10478c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
10488c2ecf20Sopenharmony_ci		}, {
10498c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
10508c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
10518c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
10528c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
10538c2ecf20Sopenharmony_ci		}, {
10548c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
10558c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
10568c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
10578c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
10588c2ecf20Sopenharmony_ci		} },
10598c2ecf20Sopenharmony_ci	},
10608c2ecf20Sopenharmony_ci	[EM2861_BOARD_KWORLD_PVRTV_300U] = {
10618c2ecf20Sopenharmony_ci		.name	      = "KWorld PVRTV 300U",
10628c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
10638c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
10648c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
10658c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
10668c2ecf20Sopenharmony_ci		.input        = { {
10678c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
10688c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
10698c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
10708c2ecf20Sopenharmony_ci		}, {
10718c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
10728c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
10738c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
10748c2ecf20Sopenharmony_ci		}, {
10758c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
10768c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
10778c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
10788c2ecf20Sopenharmony_ci		} },
10798c2ecf20Sopenharmony_ci	},
10808c2ecf20Sopenharmony_ci	[EM2861_BOARD_YAKUMO_MOVIE_MIXER] = {
10818c2ecf20Sopenharmony_ci		.name          = "Yakumo MovieMixer",
10828c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,	/* Capture only device */
10838c2ecf20Sopenharmony_ci		.decoder       = EM28XX_TVP5150,
10848c2ecf20Sopenharmony_ci		.input         = { {
10858c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
10868c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
10878c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
10888c2ecf20Sopenharmony_ci		}, {
10898c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
10908c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
10918c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
10928c2ecf20Sopenharmony_ci		}, {
10938c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
10948c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
10958c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
10968c2ecf20Sopenharmony_ci		} },
10978c2ecf20Sopenharmony_ci	},
10988c2ecf20Sopenharmony_ci	[EM2860_BOARD_TVP5150_REFERENCE_DESIGN] = {
10998c2ecf20Sopenharmony_ci		.name          = "EM2860/TVP5150 Reference Design",
11008c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,	/* Capture only device */
11018c2ecf20Sopenharmony_ci		.decoder       = EM28XX_TVP5150,
11028c2ecf20Sopenharmony_ci		.input         = { {
11038c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
11048c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
11058c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
11068c2ecf20Sopenharmony_ci		}, {
11078c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
11088c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
11098c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
11108c2ecf20Sopenharmony_ci		} },
11118c2ecf20Sopenharmony_ci	},
11128c2ecf20Sopenharmony_ci	[EM2861_BOARD_PLEXTOR_PX_TV100U] = {
11138c2ecf20Sopenharmony_ci		.name         = "Plextor ConvertX PX-TV100U",
11148c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_TNF_5335MF,
11158c2ecf20Sopenharmony_ci		.xclk         = EM28XX_XCLK_I2S_MSB_TIMING |
11168c2ecf20Sopenharmony_ci				EM28XX_XCLK_FREQUENCY_12MHZ,
11178c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
11188c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
11198c2ecf20Sopenharmony_ci		.has_msp34xx  = 1,
11208c2ecf20Sopenharmony_ci		.input        = { {
11218c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
11228c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
11238c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
11248c2ecf20Sopenharmony_ci			.gpio     = pinnacle_hybrid_pro_analog,
11258c2ecf20Sopenharmony_ci		}, {
11268c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
11278c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
11288c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
11298c2ecf20Sopenharmony_ci			.gpio     = pinnacle_hybrid_pro_analog,
11308c2ecf20Sopenharmony_ci		}, {
11318c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
11328c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
11338c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
11348c2ecf20Sopenharmony_ci			.gpio     = pinnacle_hybrid_pro_analog,
11358c2ecf20Sopenharmony_ci		} },
11368c2ecf20Sopenharmony_ci	},
11378c2ecf20Sopenharmony_ci
11388c2ecf20Sopenharmony_ci	/* Those boards with em2870 are DVB Only*/
11398c2ecf20Sopenharmony_ci
11408c2ecf20Sopenharmony_ci	[EM2870_BOARD_TERRATEC_XS] = {
11418c2ecf20Sopenharmony_ci		.name         = "Terratec Cinergy T XS",
11428c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
11438c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
11448c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
11458c2ecf20Sopenharmony_ci	},
11468c2ecf20Sopenharmony_ci	[EM2870_BOARD_TERRATEC_XS_MT2060] = {
11478c2ecf20Sopenharmony_ci		.name         = "Terratec Cinergy T XS (MT2060)",
11488c2ecf20Sopenharmony_ci		.xclk         = EM28XX_XCLK_IR_RC5_MODE |
11498c2ecf20Sopenharmony_ci				EM28XX_XCLK_FREQUENCY_12MHZ,
11508c2ecf20Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE,
11518c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT, /* MT2060 */
11528c2ecf20Sopenharmony_ci		.has_dvb      = 1,
11538c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
11548c2ecf20Sopenharmony_ci	},
11558c2ecf20Sopenharmony_ci	[EM2870_BOARD_KWORLD_350U] = {
11568c2ecf20Sopenharmony_ci		.name         = "Kworld 350 U DVB-T",
11578c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
11588c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
11598c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
11608c2ecf20Sopenharmony_ci	},
11618c2ecf20Sopenharmony_ci	[EM2870_BOARD_KWORLD_355U] = {
11628c2ecf20Sopenharmony_ci		.name         = "Kworld 355 U DVB-T",
11638c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
11648c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
11658c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
11668c2ecf20Sopenharmony_ci		.has_dvb      = 1,
11678c2ecf20Sopenharmony_ci		.dvb_gpio     = default_digital,
11688c2ecf20Sopenharmony_ci	},
11698c2ecf20Sopenharmony_ci	[EM2870_BOARD_PINNACLE_PCTV_DVB] = {
11708c2ecf20Sopenharmony_ci		.name         = "Pinnacle PCTV DVB-T",
11718c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
11728c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT, /* MT2060 */
11738c2ecf20Sopenharmony_ci		/* djh - I have serious doubts this is right... */
11748c2ecf20Sopenharmony_ci		.xclk         = EM28XX_XCLK_IR_RC5_MODE |
11758c2ecf20Sopenharmony_ci				EM28XX_XCLK_FREQUENCY_10MHZ,
11768c2ecf20Sopenharmony_ci	},
11778c2ecf20Sopenharmony_ci	[EM2870_BOARD_COMPRO_VIDEOMATE] = {
11788c2ecf20Sopenharmony_ci		.name         = "Compro, VideoMate U3",
11798c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
11808c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT, /* MT2060 */
11818c2ecf20Sopenharmony_ci	},
11828c2ecf20Sopenharmony_ci
11838c2ecf20Sopenharmony_ci	[EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = {
11848c2ecf20Sopenharmony_ci		.name         = "Terratec Hybrid XS Secam",
11858c2ecf20Sopenharmony_ci		.has_msp34xx  = 1,
11868c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
11878c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
11888c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
11898c2ecf20Sopenharmony_ci		.has_dvb      = 1,
11908c2ecf20Sopenharmony_ci		.dvb_gpio     = terratec_cinergy_USB_XS_FR_digital,
11918c2ecf20Sopenharmony_ci		.input        = { {
11928c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
11938c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
11948c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
11958c2ecf20Sopenharmony_ci			.gpio     = terratec_cinergy_USB_XS_FR_analog,
11968c2ecf20Sopenharmony_ci		}, {
11978c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
11988c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
11998c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
12008c2ecf20Sopenharmony_ci			.gpio     = terratec_cinergy_USB_XS_FR_analog,
12018c2ecf20Sopenharmony_ci		}, {
12028c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
12038c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
12048c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
12058c2ecf20Sopenharmony_ci			.gpio     = terratec_cinergy_USB_XS_FR_analog,
12068c2ecf20Sopenharmony_ci		} },
12078c2ecf20Sopenharmony_ci	},
12088c2ecf20Sopenharmony_ci	[EM2884_BOARD_TERRATEC_H5] = {
12098c2ecf20Sopenharmony_ci		.name         = "Terratec Cinergy H5",
12108c2ecf20Sopenharmony_ci		.has_dvb      = 1,
12118c2ecf20Sopenharmony_ci#if 0
12128c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_TDA8290,
12138c2ecf20Sopenharmony_ci		.tuner_addr   = 0x41,
12148c2ecf20Sopenharmony_ci		.dvb_gpio     = terratec_h5_digital, /* FIXME: probably wrong */
12158c2ecf20Sopenharmony_ci		.tuner_gpio   = terratec_h5_gpio,
12168c2ecf20Sopenharmony_ci#else
12178c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
12188c2ecf20Sopenharmony_ci#endif
12198c2ecf20Sopenharmony_ci		.def_i2c_bus  = 1,
12208c2ecf20Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
12218c2ecf20Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
12228c2ecf20Sopenharmony_ci	},
12238c2ecf20Sopenharmony_ci	[EM2884_BOARD_TERRATEC_H6] = {
12248c2ecf20Sopenharmony_ci		.name         = "Terratec Cinergy H6 rev. 2",
12258c2ecf20Sopenharmony_ci		.has_dvb      = 1,
12268c2ecf20Sopenharmony_ci		.ir_codes     = RC_MAP_NEC_TERRATEC_CINERGY_XS,
12278c2ecf20Sopenharmony_ci#if 0
12288c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_TDA8290,
12298c2ecf20Sopenharmony_ci		.tuner_addr   = 0x41,
12308c2ecf20Sopenharmony_ci		.dvb_gpio     = terratec_h5_digital, /* FIXME: probably wrong */
12318c2ecf20Sopenharmony_ci		.tuner_gpio   = terratec_h5_gpio,
12328c2ecf20Sopenharmony_ci#else
12338c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
12348c2ecf20Sopenharmony_ci#endif
12358c2ecf20Sopenharmony_ci		.def_i2c_bus  = 1,
12368c2ecf20Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
12378c2ecf20Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
12388c2ecf20Sopenharmony_ci	},
12398c2ecf20Sopenharmony_ci	[EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = {
12408c2ecf20Sopenharmony_ci		.name         = "Hauppauge WinTV HVR 930C",
12418c2ecf20Sopenharmony_ci		.has_dvb      = 1,
12428c2ecf20Sopenharmony_ci#if 0 /* FIXME: Add analog support */
12438c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC5000,
12448c2ecf20Sopenharmony_ci		.tuner_addr   = 0x41,
12458c2ecf20Sopenharmony_ci		.dvb_gpio     = hauppauge_930c_digital,
12468c2ecf20Sopenharmony_ci		.tuner_gpio   = hauppauge_930c_gpio,
12478c2ecf20Sopenharmony_ci#else
12488c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
12498c2ecf20Sopenharmony_ci#endif
12508c2ecf20Sopenharmony_ci		.ir_codes     = RC_MAP_HAUPPAUGE,
12518c2ecf20Sopenharmony_ci		.def_i2c_bus  = 1,
12528c2ecf20Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
12538c2ecf20Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
12548c2ecf20Sopenharmony_ci	},
12558c2ecf20Sopenharmony_ci	[EM2884_BOARD_C3TECH_DIGITAL_DUO] = {
12568c2ecf20Sopenharmony_ci		.name         = "C3 Tech Digital Duo HDTV/SDTV USB",
12578c2ecf20Sopenharmony_ci		.has_dvb      = 1,
12588c2ecf20Sopenharmony_ci		/* FIXME: Add analog support - need a saa7136 driver */
12598c2ecf20Sopenharmony_ci		.tuner_type = TUNER_ABSENT,	/* Digital-only TDA18271HD */
12608c2ecf20Sopenharmony_ci		.ir_codes     = RC_MAP_EMPTY,
12618c2ecf20Sopenharmony_ci		.def_i2c_bus  = 1,
12628c2ecf20Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE,
12638c2ecf20Sopenharmony_ci		.dvb_gpio     = c3tech_digital_duo_digital,
12648c2ecf20Sopenharmony_ci	},
12658c2ecf20Sopenharmony_ci	[EM2884_BOARD_CINERGY_HTC_STICK] = {
12668c2ecf20Sopenharmony_ci		.name         = "Terratec Cinergy HTC Stick",
12678c2ecf20Sopenharmony_ci		.has_dvb      = 1,
12688c2ecf20Sopenharmony_ci		.ir_codes     = RC_MAP_NEC_TERRATEC_CINERGY_XS,
12698c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
12708c2ecf20Sopenharmony_ci		.def_i2c_bus  = 1,
12718c2ecf20Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
12728c2ecf20Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
12738c2ecf20Sopenharmony_ci	},
12748c2ecf20Sopenharmony_ci	[EM2884_BOARD_ELGATO_EYETV_HYBRID_2008] = {
12758c2ecf20Sopenharmony_ci		.name         = "Elgato EyeTV Hybrid 2008 INT",
12768c2ecf20Sopenharmony_ci		.has_dvb      = 1,
12778c2ecf20Sopenharmony_ci		.ir_codes     = RC_MAP_NEC_TERRATEC_CINERGY_XS,
12788c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
12798c2ecf20Sopenharmony_ci		.def_i2c_bus  = 1,
12808c2ecf20Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
12818c2ecf20Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
12828c2ecf20Sopenharmony_ci	},
12838c2ecf20Sopenharmony_ci	[EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = {
12848c2ecf20Sopenharmony_ci		.name         = "Hauppauge WinTV HVR 900",
12858c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
12868c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
12878c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
12888c2ecf20Sopenharmony_ci		.mts_firmware = 1,
12898c2ecf20Sopenharmony_ci		.has_dvb      = 1,
12908c2ecf20Sopenharmony_ci		.dvb_gpio     = hauppauge_wintv_hvr_900_digital,
12918c2ecf20Sopenharmony_ci		.ir_codes     = RC_MAP_HAUPPAUGE,
12928c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
12938c2ecf20Sopenharmony_ci		.input        = { {
12948c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
12958c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
12968c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
12978c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
12988c2ecf20Sopenharmony_ci		}, {
12998c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
13008c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
13018c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
13028c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
13038c2ecf20Sopenharmony_ci		}, {
13048c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
13058c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
13068c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
13078c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
13088c2ecf20Sopenharmony_ci		} },
13098c2ecf20Sopenharmony_ci	},
13108c2ecf20Sopenharmony_ci	[EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = {
13118c2ecf20Sopenharmony_ci		.name         = "Hauppauge WinTV HVR 900 (R2)",
13128c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
13138c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
13148c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
13158c2ecf20Sopenharmony_ci		.mts_firmware = 1,
13168c2ecf20Sopenharmony_ci		.has_dvb      = 1,
13178c2ecf20Sopenharmony_ci		.dvb_gpio     = hauppauge_wintv_hvr_900R2_digital,
13188c2ecf20Sopenharmony_ci		.ir_codes     = RC_MAP_HAUPPAUGE,
13198c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
13208c2ecf20Sopenharmony_ci		.input        = { {
13218c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
13228c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
13238c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
13248c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
13258c2ecf20Sopenharmony_ci		}, {
13268c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
13278c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
13288c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
13298c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
13308c2ecf20Sopenharmony_ci		}, {
13318c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
13328c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
13338c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
13348c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
13358c2ecf20Sopenharmony_ci		} },
13368c2ecf20Sopenharmony_ci	},
13378c2ecf20Sopenharmony_ci	[EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850] = {
13388c2ecf20Sopenharmony_ci		.name           = "Hauppauge WinTV HVR 850",
13398c2ecf20Sopenharmony_ci		.tuner_type     = TUNER_XC2028,
13408c2ecf20Sopenharmony_ci		.tuner_gpio     = default_tuner_gpio,
13418c2ecf20Sopenharmony_ci		.mts_firmware   = 1,
13428c2ecf20Sopenharmony_ci		.has_dvb        = 1,
13438c2ecf20Sopenharmony_ci		.dvb_gpio       = hauppauge_wintv_hvr_900_digital,
13448c2ecf20Sopenharmony_ci		.ir_codes       = RC_MAP_HAUPPAUGE,
13458c2ecf20Sopenharmony_ci		.decoder        = EM28XX_TVP5150,
13468c2ecf20Sopenharmony_ci		.input          = { {
13478c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
13488c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
13498c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
13508c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
13518c2ecf20Sopenharmony_ci		}, {
13528c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
13538c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
13548c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
13558c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
13568c2ecf20Sopenharmony_ci		}, {
13578c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
13588c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
13598c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
13608c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
13618c2ecf20Sopenharmony_ci		} },
13628c2ecf20Sopenharmony_ci	},
13638c2ecf20Sopenharmony_ci	[EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
13648c2ecf20Sopenharmony_ci		.name           = "Hauppauge WinTV HVR 950",
13658c2ecf20Sopenharmony_ci		.tuner_type     = TUNER_XC2028,
13668c2ecf20Sopenharmony_ci		.tuner_gpio     = default_tuner_gpio,
13678c2ecf20Sopenharmony_ci		.mts_firmware   = 1,
13688c2ecf20Sopenharmony_ci		.has_dvb        = 1,
13698c2ecf20Sopenharmony_ci		.dvb_gpio       = hauppauge_wintv_hvr_900_digital,
13708c2ecf20Sopenharmony_ci		.ir_codes       = RC_MAP_HAUPPAUGE,
13718c2ecf20Sopenharmony_ci		.decoder        = EM28XX_TVP5150,
13728c2ecf20Sopenharmony_ci		.input          = { {
13738c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
13748c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
13758c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
13768c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
13778c2ecf20Sopenharmony_ci		}, {
13788c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
13798c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
13808c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
13818c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
13828c2ecf20Sopenharmony_ci		}, {
13838c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
13848c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
13858c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
13868c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
13878c2ecf20Sopenharmony_ci		} },
13888c2ecf20Sopenharmony_ci	},
13898c2ecf20Sopenharmony_ci	[EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = {
13908c2ecf20Sopenharmony_ci		.name           = "Pinnacle PCTV HD Pro Stick",
13918c2ecf20Sopenharmony_ci		.tuner_type     = TUNER_XC2028,
13928c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
13938c2ecf20Sopenharmony_ci		.mts_firmware   = 1,
13948c2ecf20Sopenharmony_ci		.has_dvb        = 1,
13958c2ecf20Sopenharmony_ci		.dvb_gpio       = hauppauge_wintv_hvr_900_digital,
13968c2ecf20Sopenharmony_ci		.ir_codes       = RC_MAP_PINNACLE_PCTV_HD,
13978c2ecf20Sopenharmony_ci		.decoder        = EM28XX_TVP5150,
13988c2ecf20Sopenharmony_ci		.input          = { {
13998c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
14008c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
14018c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
14028c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
14038c2ecf20Sopenharmony_ci		}, {
14048c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
14058c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
14068c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
14078c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
14088c2ecf20Sopenharmony_ci		}, {
14098c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
14108c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
14118c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
14128c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
14138c2ecf20Sopenharmony_ci		} },
14148c2ecf20Sopenharmony_ci	},
14158c2ecf20Sopenharmony_ci	[EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = {
14168c2ecf20Sopenharmony_ci		.name           = "AMD ATI TV Wonder HD 600",
14178c2ecf20Sopenharmony_ci		.tuner_type     = TUNER_XC2028,
14188c2ecf20Sopenharmony_ci		.tuner_gpio     = default_tuner_gpio,
14198c2ecf20Sopenharmony_ci		.mts_firmware   = 1,
14208c2ecf20Sopenharmony_ci		.has_dvb        = 1,
14218c2ecf20Sopenharmony_ci		.dvb_gpio       = hauppauge_wintv_hvr_900_digital,
14228c2ecf20Sopenharmony_ci		.ir_codes       = RC_MAP_ATI_TV_WONDER_HD_600,
14238c2ecf20Sopenharmony_ci		.decoder        = EM28XX_TVP5150,
14248c2ecf20Sopenharmony_ci		.input          = { {
14258c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
14268c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
14278c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
14288c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
14298c2ecf20Sopenharmony_ci		}, {
14308c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
14318c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
14328c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
14338c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
14348c2ecf20Sopenharmony_ci		}, {
14358c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
14368c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
14378c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
14388c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
14398c2ecf20Sopenharmony_ci		} },
14408c2ecf20Sopenharmony_ci	},
14418c2ecf20Sopenharmony_ci	[EM2880_BOARD_TERRATEC_HYBRID_XS] = {
14428c2ecf20Sopenharmony_ci		.name           = "Terratec Hybrid XS",
14438c2ecf20Sopenharmony_ci		.tuner_type     = TUNER_XC2028,
14448c2ecf20Sopenharmony_ci		.tuner_gpio     = default_tuner_gpio,
14458c2ecf20Sopenharmony_ci		.decoder        = EM28XX_TVP5150,
14468c2ecf20Sopenharmony_ci		.has_dvb        = 1,
14478c2ecf20Sopenharmony_ci		.dvb_gpio       = default_digital,
14488c2ecf20Sopenharmony_ci		.ir_codes       = RC_MAP_TERRATEC_CINERGY_XS,
14498c2ecf20Sopenharmony_ci		.xclk           = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */
14508c2ecf20Sopenharmony_ci		.input          = { {
14518c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
14528c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
14538c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
14548c2ecf20Sopenharmony_ci			.gpio     = default_analog,
14558c2ecf20Sopenharmony_ci		}, {
14568c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
14578c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
14588c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
14598c2ecf20Sopenharmony_ci			.gpio     = default_analog,
14608c2ecf20Sopenharmony_ci		}, {
14618c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
14628c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
14638c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
14648c2ecf20Sopenharmony_ci			.gpio     = default_analog,
14658c2ecf20Sopenharmony_ci		} },
14668c2ecf20Sopenharmony_ci	},
14678c2ecf20Sopenharmony_ci	/*
14688c2ecf20Sopenharmony_ci	 * maybe there's a reason behind it why Terratec sells the Hybrid XS
14698c2ecf20Sopenharmony_ci	 * as Prodigy XS with a different PID, let's keep it separated for now
14708c2ecf20Sopenharmony_ci	 * maybe we'll need it later on
14718c2ecf20Sopenharmony_ci	 */
14728c2ecf20Sopenharmony_ci	[EM2880_BOARD_TERRATEC_PRODIGY_XS] = {
14738c2ecf20Sopenharmony_ci		.name         = "Terratec Prodigy XS",
14748c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
14758c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
14768c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
14778c2ecf20Sopenharmony_ci		.input        = { {
14788c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
14798c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
14808c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
14818c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
14828c2ecf20Sopenharmony_ci		}, {
14838c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
14848c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
14858c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
14868c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
14878c2ecf20Sopenharmony_ci		}, {
14888c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
14898c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
14908c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
14918c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
14928c2ecf20Sopenharmony_ci		} },
14938c2ecf20Sopenharmony_ci	},
14948c2ecf20Sopenharmony_ci	[EM2820_BOARD_MSI_VOX_USB_2] = {
14958c2ecf20Sopenharmony_ci		.name		   = "MSI VOX USB 2.0",
14968c2ecf20Sopenharmony_ci		.tuner_type	   = TUNER_LG_PAL_NEW_TAPC,
14978c2ecf20Sopenharmony_ci		.tda9887_conf	   = TDA9887_PRESENT      |
14988c2ecf20Sopenharmony_ci				     TDA9887_PORT1_ACTIVE |
14998c2ecf20Sopenharmony_ci				     TDA9887_PORT2_ACTIVE,
15008c2ecf20Sopenharmony_ci		.max_range_640_480 = 1,
15018c2ecf20Sopenharmony_ci		.decoder           = EM28XX_SAA711X,
15028c2ecf20Sopenharmony_ci		.input             = { {
15038c2ecf20Sopenharmony_ci			.type      = EM28XX_VMUX_TELEVISION,
15048c2ecf20Sopenharmony_ci			.vmux      = SAA7115_COMPOSITE4,
15058c2ecf20Sopenharmony_ci			.amux      = EM28XX_AMUX_VIDEO,
15068c2ecf20Sopenharmony_ci		}, {
15078c2ecf20Sopenharmony_ci			.type      = EM28XX_VMUX_COMPOSITE,
15088c2ecf20Sopenharmony_ci			.vmux      = SAA7115_COMPOSITE0,
15098c2ecf20Sopenharmony_ci			.amux      = EM28XX_AMUX_LINE_IN,
15108c2ecf20Sopenharmony_ci		}, {
15118c2ecf20Sopenharmony_ci			.type      = EM28XX_VMUX_SVIDEO,
15128c2ecf20Sopenharmony_ci			.vmux      = SAA7115_SVIDEO3,
15138c2ecf20Sopenharmony_ci			.amux      = EM28XX_AMUX_LINE_IN,
15148c2ecf20Sopenharmony_ci		} },
15158c2ecf20Sopenharmony_ci	},
15168c2ecf20Sopenharmony_ci	[EM2800_BOARD_TERRATEC_CINERGY_200] = {
15178c2ecf20Sopenharmony_ci		.name         = "Terratec Cinergy 200 USB",
15188c2ecf20Sopenharmony_ci		.is_em2800    = 1,
15198c2ecf20Sopenharmony_ci		.has_ir_i2c   = 1,
15208c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_LG_TALN,
15218c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
15228c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
15238c2ecf20Sopenharmony_ci		.input        = { {
15248c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
15258c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
15268c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
15278c2ecf20Sopenharmony_ci		}, {
15288c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
15298c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
15308c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
15318c2ecf20Sopenharmony_ci		}, {
15328c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
15338c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
15348c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
15358c2ecf20Sopenharmony_ci		} },
15368c2ecf20Sopenharmony_ci	},
15378c2ecf20Sopenharmony_ci	[EM2800_BOARD_GRABBEEX_USB2800] = {
15388c2ecf20Sopenharmony_ci		.name       = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
15398c2ecf20Sopenharmony_ci		.is_em2800  = 1,
15408c2ecf20Sopenharmony_ci		.decoder    = EM28XX_SAA711X,
15418c2ecf20Sopenharmony_ci		.tuner_type = TUNER_ABSENT, /* capture only board */
15428c2ecf20Sopenharmony_ci		.input      = { {
15438c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
15448c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
15458c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
15468c2ecf20Sopenharmony_ci		}, {
15478c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
15488c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
15498c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
15508c2ecf20Sopenharmony_ci		} },
15518c2ecf20Sopenharmony_ci	},
15528c2ecf20Sopenharmony_ci	[EM2800_BOARD_VC211A] = {
15538c2ecf20Sopenharmony_ci		.name         = "Actionmaster/LinXcel/Digitus VC211A",
15548c2ecf20Sopenharmony_ci		.is_em2800    = 1,
15558c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,	/* Capture-only board */
15568c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
15578c2ecf20Sopenharmony_ci		.input        = { {
15588c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
15598c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
15608c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
15618c2ecf20Sopenharmony_ci			.gpio     = vc211a_enable,
15628c2ecf20Sopenharmony_ci		}, {
15638c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
15648c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
15658c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
15668c2ecf20Sopenharmony_ci			.gpio     = vc211a_enable,
15678c2ecf20Sopenharmony_ci		} },
15688c2ecf20Sopenharmony_ci	},
15698c2ecf20Sopenharmony_ci	[EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
15708c2ecf20Sopenharmony_ci		.name         = "Leadtek Winfast USB II",
15718c2ecf20Sopenharmony_ci		.is_em2800    = 1,
15728c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
15738c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
15748c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
15758c2ecf20Sopenharmony_ci		.input        = { {
15768c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
15778c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
15788c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
15798c2ecf20Sopenharmony_ci		}, {
15808c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
15818c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
15828c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
15838c2ecf20Sopenharmony_ci		}, {
15848c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
15858c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
15868c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
15878c2ecf20Sopenharmony_ci		} },
15888c2ecf20Sopenharmony_ci	},
15898c2ecf20Sopenharmony_ci	[EM2800_BOARD_KWORLD_USB2800] = {
15908c2ecf20Sopenharmony_ci		.name         = "Kworld USB2800",
15918c2ecf20Sopenharmony_ci		.is_em2800    = 1,
15928c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_FCV1236D,
15938c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
15948c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
15958c2ecf20Sopenharmony_ci		.input        = { {
15968c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
15978c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
15988c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
15998c2ecf20Sopenharmony_ci		}, {
16008c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
16018c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
16028c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
16038c2ecf20Sopenharmony_ci		}, {
16048c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
16058c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
16068c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
16078c2ecf20Sopenharmony_ci		} },
16088c2ecf20Sopenharmony_ci	},
16098c2ecf20Sopenharmony_ci	[EM2820_BOARD_PINNACLE_DVC_90] = {
16108c2ecf20Sopenharmony_ci		.name	      = "Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker / Kworld DVD Maker 2 / Plextor ConvertX PX-AV100U",
16118c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT, /* capture only board */
16128c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
16138c2ecf20Sopenharmony_ci		.input        = { {
16148c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
16158c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
16168c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
16178c2ecf20Sopenharmony_ci		}, {
16188c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
16198c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
16208c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
16218c2ecf20Sopenharmony_ci		} },
16228c2ecf20Sopenharmony_ci	},
16238c2ecf20Sopenharmony_ci	[EM2800_BOARD_VGEAR_POCKETTV] = {
16248c2ecf20Sopenharmony_ci		.name         = "V-Gear PocketTV",
16258c2ecf20Sopenharmony_ci		.is_em2800    = 1,
16268c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
16278c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
16288c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
16298c2ecf20Sopenharmony_ci		.input        = { {
16308c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
16318c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
16328c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
16338c2ecf20Sopenharmony_ci		}, {
16348c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
16358c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
16368c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
16378c2ecf20Sopenharmony_ci		}, {
16388c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
16398c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
16408c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
16418c2ecf20Sopenharmony_ci		} },
16428c2ecf20Sopenharmony_ci	},
16438c2ecf20Sopenharmony_ci	[EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2] = {
16448c2ecf20Sopenharmony_ci		.name         = "Pixelview PlayTV Box 4 USB 2.0",
16458c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
16468c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_YMEC_TVF_5533MF,
16478c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
16488c2ecf20Sopenharmony_ci		.input        = { {
16498c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
16508c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
16518c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
16528c2ecf20Sopenharmony_ci			.aout     = EM28XX_AOUT_MONO |	/* I2S */
16538c2ecf20Sopenharmony_ci				    EM28XX_AOUT_MASTER,	/* Line out pin */
16548c2ecf20Sopenharmony_ci		}, {
16558c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
16568c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
16578c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
16588c2ecf20Sopenharmony_ci		}, {
16598c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
16608c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
16618c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
16628c2ecf20Sopenharmony_ci		} },
16638c2ecf20Sopenharmony_ci	},
16648c2ecf20Sopenharmony_ci	[EM2820_BOARD_PROLINK_PLAYTV_USB2] = {
16658c2ecf20Sopenharmony_ci		.name         = "SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0",
16668c2ecf20Sopenharmony_ci		.buttons = std_snapshot_button,
16678c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
16688c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_YMEC_TVF_5533MF,
16698c2ecf20Sopenharmony_ci		.tuner_addr   = 0x60,
16708c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
16718c2ecf20Sopenharmony_ci		.input        = { {
16728c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
16738c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE2,
16748c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
16758c2ecf20Sopenharmony_ci			.aout     = EM28XX_AOUT_MONO |	/* I2S */
16768c2ecf20Sopenharmony_ci				    EM28XX_AOUT_MASTER,	/* Line out pin */
16778c2ecf20Sopenharmony_ci		}, {
16788c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
16798c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
16808c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
16818c2ecf20Sopenharmony_ci		}, {
16828c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
16838c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
16848c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
16858c2ecf20Sopenharmony_ci		} },
16868c2ecf20Sopenharmony_ci	},
16878c2ecf20Sopenharmony_ci	[EM2860_BOARD_SAA711X_REFERENCE_DESIGN] = {
16888c2ecf20Sopenharmony_ci		.name                = "EM2860/SAA711X Reference Design",
16898c2ecf20Sopenharmony_ci		.buttons = std_snapshot_button,
16908c2ecf20Sopenharmony_ci		.tuner_type          = TUNER_ABSENT,
16918c2ecf20Sopenharmony_ci		.decoder             = EM28XX_SAA711X,
16928c2ecf20Sopenharmony_ci		.input               = { {
16938c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
16948c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
16958c2ecf20Sopenharmony_ci		}, {
16968c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
16978c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
16988c2ecf20Sopenharmony_ci		} },
16998c2ecf20Sopenharmony_ci	},
17008c2ecf20Sopenharmony_ci
17018c2ecf20Sopenharmony_ci	[EM2874_BOARD_LEADERSHIP_ISDBT] = {
17028c2ecf20Sopenharmony_ci		.def_i2c_bus	= 1,
17038c2ecf20Sopenharmony_ci		.i2c_speed      = EM28XX_I2C_CLK_WAIT_ENABLE |
17048c2ecf20Sopenharmony_ci				  EM28XX_I2C_FREQ_100_KHZ,
17058c2ecf20Sopenharmony_ci		.xclk		= EM28XX_XCLK_FREQUENCY_10MHZ,
17068c2ecf20Sopenharmony_ci		.name		= "EM2874 Leadership ISDBT",
17078c2ecf20Sopenharmony_ci		.tuner_type	= TUNER_ABSENT,
17088c2ecf20Sopenharmony_ci		.tuner_gpio     = leadership_reset,
17098c2ecf20Sopenharmony_ci		.dvb_gpio       = leadership_digital,
17108c2ecf20Sopenharmony_ci		.has_dvb	= 1,
17118c2ecf20Sopenharmony_ci	},
17128c2ecf20Sopenharmony_ci
17138c2ecf20Sopenharmony_ci	[EM2880_BOARD_MSI_DIGIVOX_AD] = {
17148c2ecf20Sopenharmony_ci		.name         = "MSI DigiVox A/D",
17158c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
17168c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
17178c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
17188c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
17198c2ecf20Sopenharmony_ci		.input        = { {
17208c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
17218c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
17228c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
17238c2ecf20Sopenharmony_ci			.gpio     = em2880_msi_digivox_ad_analog,
17248c2ecf20Sopenharmony_ci		}, {
17258c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
17268c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
17278c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
17288c2ecf20Sopenharmony_ci			.gpio     = em2880_msi_digivox_ad_analog,
17298c2ecf20Sopenharmony_ci		}, {
17308c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
17318c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
17328c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
17338c2ecf20Sopenharmony_ci			.gpio     = em2880_msi_digivox_ad_analog,
17348c2ecf20Sopenharmony_ci		} },
17358c2ecf20Sopenharmony_ci	},
17368c2ecf20Sopenharmony_ci	[EM2880_BOARD_MSI_DIGIVOX_AD_II] = {
17378c2ecf20Sopenharmony_ci		.name         = "MSI DigiVox A/D II",
17388c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
17398c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
17408c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
17418c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
17428c2ecf20Sopenharmony_ci		.input        = { {
17438c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
17448c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
17458c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
17468c2ecf20Sopenharmony_ci			.gpio     = em2880_msi_digivox_ad_analog,
17478c2ecf20Sopenharmony_ci		}, {
17488c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
17498c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
17508c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
17518c2ecf20Sopenharmony_ci			.gpio     = em2880_msi_digivox_ad_analog,
17528c2ecf20Sopenharmony_ci		}, {
17538c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
17548c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
17558c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
17568c2ecf20Sopenharmony_ci			.gpio     = em2880_msi_digivox_ad_analog,
17578c2ecf20Sopenharmony_ci		} },
17588c2ecf20Sopenharmony_ci	},
17598c2ecf20Sopenharmony_ci	[EM2880_BOARD_KWORLD_DVB_305U] = {
17608c2ecf20Sopenharmony_ci		.name	      = "KWorld DVB-T 305U",
17618c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
17628c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
17638c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
17648c2ecf20Sopenharmony_ci		.input        = { {
17658c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
17668c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
17678c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
17688c2ecf20Sopenharmony_ci		}, {
17698c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
17708c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
17718c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
17728c2ecf20Sopenharmony_ci		}, {
17738c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
17748c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
17758c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
17768c2ecf20Sopenharmony_ci		} },
17778c2ecf20Sopenharmony_ci	},
17788c2ecf20Sopenharmony_ci	[EM2880_BOARD_KWORLD_DVB_310U] = {
17798c2ecf20Sopenharmony_ci		.name	      = "KWorld DVB-T 310U",
17808c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
17818c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
17828c2ecf20Sopenharmony_ci		.has_dvb      = 1,
17838c2ecf20Sopenharmony_ci		.dvb_gpio     = default_digital,
17848c2ecf20Sopenharmony_ci		.mts_firmware = 1,
17858c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
17868c2ecf20Sopenharmony_ci		.input        = { {
17878c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
17888c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
17898c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
17908c2ecf20Sopenharmony_ci			.gpio     = default_analog,
17918c2ecf20Sopenharmony_ci		}, {
17928c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
17938c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
17948c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
17958c2ecf20Sopenharmony_ci			.gpio     = default_analog,
17968c2ecf20Sopenharmony_ci		}, {	/* S-video has not been tested yet */
17978c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
17988c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
17998c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
18008c2ecf20Sopenharmony_ci			.gpio     = default_analog,
18018c2ecf20Sopenharmony_ci		} },
18028c2ecf20Sopenharmony_ci	},
18038c2ecf20Sopenharmony_ci	[EM2882_BOARD_KWORLD_ATSC_315U] = {
18048c2ecf20Sopenharmony_ci		.name		= "KWorld ATSC 315U HDTV TV Box",
18058c2ecf20Sopenharmony_ci		.valid		= EM28XX_BOARD_NOT_VALIDATED,
18068c2ecf20Sopenharmony_ci		.tuner_type	= TUNER_THOMSON_DTT761X,
18078c2ecf20Sopenharmony_ci		.tuner_gpio	= em2882_kworld_315u_tuner_gpio,
18088c2ecf20Sopenharmony_ci		.tda9887_conf	= TDA9887_PRESENT,
18098c2ecf20Sopenharmony_ci		.decoder	= EM28XX_SAA711X,
18108c2ecf20Sopenharmony_ci		.has_dvb	= 1,
18118c2ecf20Sopenharmony_ci		.dvb_gpio	= em2882_kworld_315u_digital,
18128c2ecf20Sopenharmony_ci		.ir_codes	= RC_MAP_KWORLD_315U,
18138c2ecf20Sopenharmony_ci		.xclk		= EM28XX_XCLK_FREQUENCY_12MHZ,
18148c2ecf20Sopenharmony_ci		.i2c_speed	= EM28XX_I2C_CLK_WAIT_ENABLE,
18158c2ecf20Sopenharmony_ci#if 0
18168c2ecf20Sopenharmony_ci		/* FIXME: Analog mode - still not ready */
18178c2ecf20Sopenharmony_ci		.input        = { {
18188c2ecf20Sopenharmony_ci			.type = EM28XX_VMUX_TELEVISION,
18198c2ecf20Sopenharmony_ci			.vmux = SAA7115_COMPOSITE2,
18208c2ecf20Sopenharmony_ci			.amux = EM28XX_AMUX_VIDEO,
18218c2ecf20Sopenharmony_ci			.gpio = em2882_kworld_315u_analog,
18228c2ecf20Sopenharmony_ci			.aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
18238c2ecf20Sopenharmony_ci		}, {
18248c2ecf20Sopenharmony_ci			.type = EM28XX_VMUX_COMPOSITE,
18258c2ecf20Sopenharmony_ci			.vmux = SAA7115_COMPOSITE0,
18268c2ecf20Sopenharmony_ci			.amux = EM28XX_AMUX_LINE_IN,
18278c2ecf20Sopenharmony_ci			.gpio = em2882_kworld_315u_analog1,
18288c2ecf20Sopenharmony_ci			.aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
18298c2ecf20Sopenharmony_ci		}, {
18308c2ecf20Sopenharmony_ci			.type = EM28XX_VMUX_SVIDEO,
18318c2ecf20Sopenharmony_ci			.vmux = SAA7115_SVIDEO3,
18328c2ecf20Sopenharmony_ci			.amux = EM28XX_AMUX_LINE_IN,
18338c2ecf20Sopenharmony_ci			.gpio = em2882_kworld_315u_analog1,
18348c2ecf20Sopenharmony_ci			.aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
18358c2ecf20Sopenharmony_ci		} },
18368c2ecf20Sopenharmony_ci#endif
18378c2ecf20Sopenharmony_ci	},
18388c2ecf20Sopenharmony_ci	[EM2880_BOARD_EMPIRE_DUAL_TV] = {
18398c2ecf20Sopenharmony_ci		.name = "Empire dual TV",
18408c2ecf20Sopenharmony_ci		.tuner_type = TUNER_XC2028,
18418c2ecf20Sopenharmony_ci		.tuner_gpio = default_tuner_gpio,
18428c2ecf20Sopenharmony_ci		.has_dvb = 1,
18438c2ecf20Sopenharmony_ci		.dvb_gpio = default_digital,
18448c2ecf20Sopenharmony_ci		.mts_firmware = 1,
18458c2ecf20Sopenharmony_ci		.decoder = EM28XX_TVP5150,
18468c2ecf20Sopenharmony_ci		.input = { {
18478c2ecf20Sopenharmony_ci			.type = EM28XX_VMUX_TELEVISION,
18488c2ecf20Sopenharmony_ci			.vmux = TVP5150_COMPOSITE0,
18498c2ecf20Sopenharmony_ci			.amux = EM28XX_AMUX_VIDEO,
18508c2ecf20Sopenharmony_ci			.gpio = default_analog,
18518c2ecf20Sopenharmony_ci		}, {
18528c2ecf20Sopenharmony_ci			.type = EM28XX_VMUX_COMPOSITE,
18538c2ecf20Sopenharmony_ci			.vmux = TVP5150_COMPOSITE1,
18548c2ecf20Sopenharmony_ci			.amux = EM28XX_AMUX_LINE_IN,
18558c2ecf20Sopenharmony_ci			.gpio = default_analog,
18568c2ecf20Sopenharmony_ci		}, {
18578c2ecf20Sopenharmony_ci			.type = EM28XX_VMUX_SVIDEO,
18588c2ecf20Sopenharmony_ci			.vmux = TVP5150_SVIDEO,
18598c2ecf20Sopenharmony_ci			.amux = EM28XX_AMUX_LINE_IN,
18608c2ecf20Sopenharmony_ci			.gpio = default_analog,
18618c2ecf20Sopenharmony_ci		} },
18628c2ecf20Sopenharmony_ci	},
18638c2ecf20Sopenharmony_ci	[EM2881_BOARD_DNT_DA2_HYBRID] = {
18648c2ecf20Sopenharmony_ci		.name         = "DNT DA2 Hybrid",
18658c2ecf20Sopenharmony_ci		.valid        = EM28XX_BOARD_NOT_VALIDATED,
18668c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
18678c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
18688c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
18698c2ecf20Sopenharmony_ci		.input        = { {
18708c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
18718c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
18728c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
18738c2ecf20Sopenharmony_ci			.gpio     = default_analog,
18748c2ecf20Sopenharmony_ci		}, {
18758c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
18768c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
18778c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
18788c2ecf20Sopenharmony_ci			.gpio     = default_analog,
18798c2ecf20Sopenharmony_ci		}, {
18808c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
18818c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
18828c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
18838c2ecf20Sopenharmony_ci			.gpio     = default_analog,
18848c2ecf20Sopenharmony_ci		} },
18858c2ecf20Sopenharmony_ci	},
18868c2ecf20Sopenharmony_ci	[EM2881_BOARD_PINNACLE_HYBRID_PRO] = {
18878c2ecf20Sopenharmony_ci		.name         = "Pinnacle Hybrid Pro",
18888c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
18898c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
18908c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
18918c2ecf20Sopenharmony_ci		.has_dvb      = 1,
18928c2ecf20Sopenharmony_ci		.dvb_gpio     = pinnacle_hybrid_pro_digital,
18938c2ecf20Sopenharmony_ci		.input        = { {
18948c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
18958c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
18968c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
18978c2ecf20Sopenharmony_ci			.gpio     = pinnacle_hybrid_pro_analog,
18988c2ecf20Sopenharmony_ci		}, {
18998c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
19008c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
19018c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
19028c2ecf20Sopenharmony_ci			.gpio     = pinnacle_hybrid_pro_analog,
19038c2ecf20Sopenharmony_ci		}, {
19048c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
19058c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
19068c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
19078c2ecf20Sopenharmony_ci			.gpio     = pinnacle_hybrid_pro_analog,
19088c2ecf20Sopenharmony_ci		} },
19098c2ecf20Sopenharmony_ci	},
19108c2ecf20Sopenharmony_ci	[EM2882_BOARD_PINNACLE_HYBRID_PRO_330E] = {
19118c2ecf20Sopenharmony_ci		.name         = "Pinnacle Hybrid Pro (330e)",
19128c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
19138c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
19148c2ecf20Sopenharmony_ci		.mts_firmware = 1,
19158c2ecf20Sopenharmony_ci		.has_dvb      = 1,
19168c2ecf20Sopenharmony_ci		.dvb_gpio     = hauppauge_wintv_hvr_900R2_digital,
19178c2ecf20Sopenharmony_ci		.ir_codes     = RC_MAP_PINNACLE_PCTV_HD,
19188c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
19198c2ecf20Sopenharmony_ci		.input        = { {
19208c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
19218c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
19228c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
19238c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
19248c2ecf20Sopenharmony_ci		}, {
19258c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
19268c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
19278c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
19288c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
19298c2ecf20Sopenharmony_ci		}, {
19308c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
19318c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
19328c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
19338c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
19348c2ecf20Sopenharmony_ci		} },
19358c2ecf20Sopenharmony_ci	},
19368c2ecf20Sopenharmony_ci	[EM2882_BOARD_KWORLD_VS_DVBT] = {
19378c2ecf20Sopenharmony_ci		.name         = "Kworld VS-DVB-T 323UR",
19388c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
19398c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
19408c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
19418c2ecf20Sopenharmony_ci		.mts_firmware = 1,
19428c2ecf20Sopenharmony_ci		.has_dvb      = 1,
19438c2ecf20Sopenharmony_ci		.dvb_gpio     = kworld_330u_digital,
19448c2ecf20Sopenharmony_ci		.xclk         = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */
19458c2ecf20Sopenharmony_ci		.ir_codes     = RC_MAP_KWORLD_315U,
19468c2ecf20Sopenharmony_ci		.input        = { {
19478c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
19488c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
19498c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
19508c2ecf20Sopenharmony_ci		}, {
19518c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
19528c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
19538c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
19548c2ecf20Sopenharmony_ci		}, {
19558c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
19568c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
19578c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
19588c2ecf20Sopenharmony_ci		} },
19598c2ecf20Sopenharmony_ci	},
19608c2ecf20Sopenharmony_ci	[EM2882_BOARD_TERRATEC_HYBRID_XS] = {
19618c2ecf20Sopenharmony_ci		.name         = "Terratec Cinergy Hybrid T USB XS (em2882)",
19628c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
19638c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
19648c2ecf20Sopenharmony_ci		.mts_firmware = 1,
19658c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
19668c2ecf20Sopenharmony_ci		.has_dvb      = 1,
19678c2ecf20Sopenharmony_ci		.dvb_gpio     = hauppauge_wintv_hvr_900_digital,
19688c2ecf20Sopenharmony_ci		.ir_codes     = RC_MAP_TERRATEC_CINERGY_XS,
19698c2ecf20Sopenharmony_ci		.xclk         = EM28XX_XCLK_FREQUENCY_12MHZ,
19708c2ecf20Sopenharmony_ci		.input        = { {
19718c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
19728c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
19738c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
19748c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
19758c2ecf20Sopenharmony_ci		}, {
19768c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
19778c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
19788c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
19798c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
19808c2ecf20Sopenharmony_ci		}, {
19818c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
19828c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
19838c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
19848c2ecf20Sopenharmony_ci			.gpio     = hauppauge_wintv_hvr_900_analog,
19858c2ecf20Sopenharmony_ci		} },
19868c2ecf20Sopenharmony_ci	},
19878c2ecf20Sopenharmony_ci	[EM2882_BOARD_DIKOM_DK300] = {
19888c2ecf20Sopenharmony_ci		.name         = "Dikom DK300",
19898c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
19908c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
19918c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
19928c2ecf20Sopenharmony_ci		.mts_firmware = 1,
19938c2ecf20Sopenharmony_ci		.has_dvb      = 1,
19948c2ecf20Sopenharmony_ci		.dvb_gpio     = dikom_dk300_digital,
19958c2ecf20Sopenharmony_ci		.input        = { {
19968c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
19978c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
19988c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
19998c2ecf20Sopenharmony_ci			.gpio     = default_analog,
20008c2ecf20Sopenharmony_ci		} },
20018c2ecf20Sopenharmony_ci	},
20028c2ecf20Sopenharmony_ci	[EM2883_BOARD_KWORLD_HYBRID_330U] = {
20038c2ecf20Sopenharmony_ci		.name         = "Kworld PlusTV HD Hybrid 330",
20048c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
20058c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
20068c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
20078c2ecf20Sopenharmony_ci		.mts_firmware = 1,
20088c2ecf20Sopenharmony_ci		.has_dvb      = 1,
20098c2ecf20Sopenharmony_ci		.dvb_gpio     = kworld_330u_digital,
20108c2ecf20Sopenharmony_ci		.xclk             = EM28XX_XCLK_FREQUENCY_12MHZ,
20118c2ecf20Sopenharmony_ci		.i2c_speed        = EM28XX_I2C_CLK_WAIT_ENABLE |
20128c2ecf20Sopenharmony_ci				    EM28XX_I2C_EEPROM_ON_BOARD |
20138c2ecf20Sopenharmony_ci				    EM28XX_I2C_EEPROM_KEY_VALID,
20148c2ecf20Sopenharmony_ci		.input        = { {
20158c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
20168c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
20178c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
20188c2ecf20Sopenharmony_ci			.gpio     = kworld_330u_analog,
20198c2ecf20Sopenharmony_ci			.aout     = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
20208c2ecf20Sopenharmony_ci		}, {
20218c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
20228c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
20238c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
20248c2ecf20Sopenharmony_ci			.gpio     = kworld_330u_analog,
20258c2ecf20Sopenharmony_ci			.aout     = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
20268c2ecf20Sopenharmony_ci		}, {
20278c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
20288c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
20298c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
20308c2ecf20Sopenharmony_ci			.gpio     = kworld_330u_analog,
20318c2ecf20Sopenharmony_ci		} },
20328c2ecf20Sopenharmony_ci	},
20338c2ecf20Sopenharmony_ci	[EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
20348c2ecf20Sopenharmony_ci		.name         = "Compro VideoMate ForYou/Stereo",
20358c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
20368c2ecf20Sopenharmony_ci		.tvaudio_addr = 0xb0,
20378c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
20388c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
20398c2ecf20Sopenharmony_ci		.adecoder     = EM28XX_TVAUDIO,
20408c2ecf20Sopenharmony_ci		.mute_gpio    = compro_mute_gpio,
20418c2ecf20Sopenharmony_ci		.input        = { {
20428c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
20438c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
20448c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
20458c2ecf20Sopenharmony_ci			.gpio     = compro_unmute_tv_gpio,
20468c2ecf20Sopenharmony_ci		}, {
20478c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
20488c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
20498c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
20508c2ecf20Sopenharmony_ci			.gpio     = compro_unmute_svid_gpio,
20518c2ecf20Sopenharmony_ci		} },
20528c2ecf20Sopenharmony_ci	},
20538c2ecf20Sopenharmony_ci	[EM2860_BOARD_KAIOMY_TVNPC_U2] = {
20548c2ecf20Sopenharmony_ci		.name	      = "Kaiomy TVnPC U2",
20558c2ecf20Sopenharmony_ci		.vchannels    = 3,
20568c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
20578c2ecf20Sopenharmony_ci		.tuner_addr   = 0x61,
20588c2ecf20Sopenharmony_ci		.mts_firmware = 1,
20598c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
20608c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
20618c2ecf20Sopenharmony_ci		.ir_codes     = RC_MAP_KAIOMY,
20628c2ecf20Sopenharmony_ci		.input          = { {
20638c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
20648c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
20658c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
20668c2ecf20Sopenharmony_ci
20678c2ecf20Sopenharmony_ci		}, {
20688c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
20698c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
20708c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
20718c2ecf20Sopenharmony_ci		}, {
20728c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
20738c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
20748c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
20758c2ecf20Sopenharmony_ci		} },
20768c2ecf20Sopenharmony_ci		.radio		= {
20778c2ecf20Sopenharmony_ci			.type     = EM28XX_RADIO,
20788c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
20798c2ecf20Sopenharmony_ci		}
20808c2ecf20Sopenharmony_ci	},
20818c2ecf20Sopenharmony_ci	[EM2860_BOARD_EASYCAP] = {
20828c2ecf20Sopenharmony_ci		.name         = "Easy Cap Capture DC-60",
20838c2ecf20Sopenharmony_ci		.vchannels    = 2,
20848c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
20858c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
20868c2ecf20Sopenharmony_ci		.input           = { {
20878c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
20888c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
20898c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
20908c2ecf20Sopenharmony_ci		}, {
20918c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
20928c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
20938c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
20948c2ecf20Sopenharmony_ci		} },
20958c2ecf20Sopenharmony_ci	},
20968c2ecf20Sopenharmony_ci	[EM2820_BOARD_IODATA_GVMVP_SZ] = {
20978c2ecf20Sopenharmony_ci		.name       = "IO-DATA GV-MVP/SZ",
20988c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_PHILIPS_FM1236_MK3,
20998c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
21008c2ecf20Sopenharmony_ci		.tda9887_conf = TDA9887_PRESENT,
21018c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
21028c2ecf20Sopenharmony_ci		.input        = { {
21038c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
21048c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
21058c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
21068c2ecf20Sopenharmony_ci		}, { /* Composite has not been tested yet */
21078c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
21088c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
21098c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
21108c2ecf20Sopenharmony_ci		}, { /* S-video has not been tested yet */
21118c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
21128c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
21138c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
21148c2ecf20Sopenharmony_ci		} },
21158c2ecf20Sopenharmony_ci	},
21168c2ecf20Sopenharmony_ci	[EM2860_BOARD_TERRATEC_GRABBY] = {
21178c2ecf20Sopenharmony_ci		.name            = "Terratec Grabby",
21188c2ecf20Sopenharmony_ci		.vchannels       = 2,
21198c2ecf20Sopenharmony_ci		.tuner_type      = TUNER_ABSENT,
21208c2ecf20Sopenharmony_ci		.decoder         = EM28XX_SAA711X,
21218c2ecf20Sopenharmony_ci		.xclk            = EM28XX_XCLK_FREQUENCY_12MHZ,
21228c2ecf20Sopenharmony_ci		.input           = { {
21238c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
21248c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
21258c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
21268c2ecf20Sopenharmony_ci		}, {
21278c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
21288c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
21298c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
21308c2ecf20Sopenharmony_ci		} },
21318c2ecf20Sopenharmony_ci		.buttons         = std_snapshot_button,
21328c2ecf20Sopenharmony_ci		.leds            = terratec_grabby_leds,
21338c2ecf20Sopenharmony_ci	},
21348c2ecf20Sopenharmony_ci	[EM2860_BOARD_TERRATEC_AV350] = {
21358c2ecf20Sopenharmony_ci		.name            = "Terratec AV350",
21368c2ecf20Sopenharmony_ci		.vchannels       = 2,
21378c2ecf20Sopenharmony_ci		.tuner_type      = TUNER_ABSENT,
21388c2ecf20Sopenharmony_ci		.decoder         = EM28XX_TVP5150,
21398c2ecf20Sopenharmony_ci		.xclk            = EM28XX_XCLK_FREQUENCY_12MHZ,
21408c2ecf20Sopenharmony_ci		.mute_gpio       = terratec_av350_mute_gpio,
21418c2ecf20Sopenharmony_ci		.input           = { {
21428c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
21438c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
21448c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
21458c2ecf20Sopenharmony_ci			.gpio     = terratec_av350_unmute_gpio,
21468c2ecf20Sopenharmony_ci
21478c2ecf20Sopenharmony_ci		}, {
21488c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
21498c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
21508c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
21518c2ecf20Sopenharmony_ci			.gpio     = terratec_av350_unmute_gpio,
21528c2ecf20Sopenharmony_ci		} },
21538c2ecf20Sopenharmony_ci	},
21548c2ecf20Sopenharmony_ci
21558c2ecf20Sopenharmony_ci	[EM2860_BOARD_ELGATO_VIDEO_CAPTURE] = {
21568c2ecf20Sopenharmony_ci		.name         = "Elgato Video Capture",
21578c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
21588c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,   /* Capture only device */
21598c2ecf20Sopenharmony_ci		.input        = { {
21608c2ecf20Sopenharmony_ci			.type  = EM28XX_VMUX_COMPOSITE,
21618c2ecf20Sopenharmony_ci			.vmux  = SAA7115_COMPOSITE0,
21628c2ecf20Sopenharmony_ci			.amux  = EM28XX_AMUX_LINE_IN,
21638c2ecf20Sopenharmony_ci		}, {
21648c2ecf20Sopenharmony_ci			.type  = EM28XX_VMUX_SVIDEO,
21658c2ecf20Sopenharmony_ci			.vmux  = SAA7115_SVIDEO3,
21668c2ecf20Sopenharmony_ci			.amux  = EM28XX_AMUX_LINE_IN,
21678c2ecf20Sopenharmony_ci		} },
21688c2ecf20Sopenharmony_ci	},
21698c2ecf20Sopenharmony_ci
21708c2ecf20Sopenharmony_ci	[EM2882_BOARD_EVGA_INDTUBE] = {
21718c2ecf20Sopenharmony_ci		.name         = "Evga inDtube",
21728c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_XC2028,
21738c2ecf20Sopenharmony_ci		.tuner_gpio   = default_tuner_gpio,
21748c2ecf20Sopenharmony_ci		.decoder      = EM28XX_TVP5150,
21758c2ecf20Sopenharmony_ci		.xclk         = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */
21768c2ecf20Sopenharmony_ci		.mts_firmware = 1,
21778c2ecf20Sopenharmony_ci		.has_dvb      = 1,
21788c2ecf20Sopenharmony_ci		.dvb_gpio     = evga_indtube_digital,
21798c2ecf20Sopenharmony_ci		.ir_codes     = RC_MAP_EVGA_INDTUBE,
21808c2ecf20Sopenharmony_ci		.input        = { {
21818c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_TELEVISION,
21828c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE0,
21838c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
21848c2ecf20Sopenharmony_ci			.gpio     = evga_indtube_analog,
21858c2ecf20Sopenharmony_ci		}, {
21868c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
21878c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
21888c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
21898c2ecf20Sopenharmony_ci			.gpio     = evga_indtube_analog,
21908c2ecf20Sopenharmony_ci		}, {
21918c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
21928c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
21938c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
21948c2ecf20Sopenharmony_ci			.gpio     = evga_indtube_analog,
21958c2ecf20Sopenharmony_ci		} },
21968c2ecf20Sopenharmony_ci	},
21978c2ecf20Sopenharmony_ci	/*
21988c2ecf20Sopenharmony_ci	 * eb1a:2868 Empia EM2870 + Philips CU1216L NIM
21998c2ecf20Sopenharmony_ci	 * (Philips TDA10023 + Infineon TUA6034)
22008c2ecf20Sopenharmony_ci	 */
22018c2ecf20Sopenharmony_ci	[EM2870_BOARD_REDDO_DVB_C_USB_BOX] = {
22028c2ecf20Sopenharmony_ci		.name          = "Reddo DVB-C USB TV Box",
22038c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
22048c2ecf20Sopenharmony_ci		.tuner_gpio    = reddo_dvb_c_usb_box,
22058c2ecf20Sopenharmony_ci		.has_dvb       = 1,
22068c2ecf20Sopenharmony_ci	},
22078c2ecf20Sopenharmony_ci	/*
22088c2ecf20Sopenharmony_ci	 * 1b80:a340 - Empia EM2870, NXP TDA18271HD and LG DT3304, sold
22098c2ecf20Sopenharmony_ci	 * initially as the KWorld PlusTV 340U, then as the UB435-Q.
22108c2ecf20Sopenharmony_ci	 * Early variants have a TDA18271HD/C1, later ones a TDA18271HD/C2
22118c2ecf20Sopenharmony_ci	 */
22128c2ecf20Sopenharmony_ci	[EM2870_BOARD_KWORLD_A340] = {
22138c2ecf20Sopenharmony_ci		.name       = "KWorld PlusTV 340U or UB435-Q (ATSC)",
22148c2ecf20Sopenharmony_ci		.tuner_type = TUNER_ABSENT,	/* Digital-only TDA18271HD */
22158c2ecf20Sopenharmony_ci		.has_dvb    = 1,
22168c2ecf20Sopenharmony_ci		.dvb_gpio   = kworld_a340_digital,
22178c2ecf20Sopenharmony_ci		.tuner_gpio = default_tuner_gpio,
22188c2ecf20Sopenharmony_ci	},
22198c2ecf20Sopenharmony_ci	/*
22208c2ecf20Sopenharmony_ci	 * 2013:024f PCTV nanoStick T2 290e.
22218c2ecf20Sopenharmony_ci	 * Empia EM28174, Sony CXD2820R and NXP TDA18271HD/C2
22228c2ecf20Sopenharmony_ci	 */
22238c2ecf20Sopenharmony_ci	[EM28174_BOARD_PCTV_290E] = {
22248c2ecf20Sopenharmony_ci		.name          = "PCTV nanoStick T2 290e",
22258c2ecf20Sopenharmony_ci		.def_i2c_bus   = 1,
22268c2ecf20Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
22278c2ecf20Sopenharmony_ci				 EM28XX_I2C_FREQ_100_KHZ,
22288c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
22298c2ecf20Sopenharmony_ci		.tuner_gpio    = pctv_290e,
22308c2ecf20Sopenharmony_ci		.has_dvb       = 1,
22318c2ecf20Sopenharmony_ci		.ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
22328c2ecf20Sopenharmony_ci	},
22338c2ecf20Sopenharmony_ci	/*
22348c2ecf20Sopenharmony_ci	 * 2013:024f PCTV DVB-S2 Stick 460e
22358c2ecf20Sopenharmony_ci	 * Empia EM28174, NXP TDA10071, Conexant CX24118A and Allegro A8293
22368c2ecf20Sopenharmony_ci	 */
22378c2ecf20Sopenharmony_ci	[EM28174_BOARD_PCTV_460E] = {
22388c2ecf20Sopenharmony_ci		.def_i2c_bus   = 1,
22398c2ecf20Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
22408c2ecf20Sopenharmony_ci				 EM28XX_I2C_FREQ_400_KHZ,
22418c2ecf20Sopenharmony_ci		.name          = "PCTV DVB-S2 Stick (460e)",
22428c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
22438c2ecf20Sopenharmony_ci		.tuner_gpio    = pctv_460e,
22448c2ecf20Sopenharmony_ci		.has_dvb       = 1,
22458c2ecf20Sopenharmony_ci		.ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
22468c2ecf20Sopenharmony_ci	},
22478c2ecf20Sopenharmony_ci	/*
22488c2ecf20Sopenharmony_ci	 * eb1a:5006 Honestech VIDBOX NW03
22498c2ecf20Sopenharmony_ci	 * Empia EM2860, Philips SAA7113, Empia EMP202, No Tuner
22508c2ecf20Sopenharmony_ci	 */
22518c2ecf20Sopenharmony_ci	[EM2860_BOARD_HT_VIDBOX_NW03] = {
22528c2ecf20Sopenharmony_ci		.name                = "Honestech Vidbox NW03",
22538c2ecf20Sopenharmony_ci		.tuner_type          = TUNER_ABSENT,
22548c2ecf20Sopenharmony_ci		.decoder             = EM28XX_SAA711X,
22558c2ecf20Sopenharmony_ci		.input               = { {
22568c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
22578c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
22588c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
22598c2ecf20Sopenharmony_ci		}, {
22608c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
22618c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,  /* S-VIDEO needs check */
22628c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
22638c2ecf20Sopenharmony_ci		} },
22648c2ecf20Sopenharmony_ci	},
22658c2ecf20Sopenharmony_ci	/*
22668c2ecf20Sopenharmony_ci	 * 1b80:e425 MaxMedia UB425-TC
22678c2ecf20Sopenharmony_ci	 * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2
22688c2ecf20Sopenharmony_ci	 */
22698c2ecf20Sopenharmony_ci	[EM2874_BOARD_MAXMEDIA_UB425_TC] = {
22708c2ecf20Sopenharmony_ci		.name          = "MaxMedia UB425-TC",
22718c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
22728c2ecf20Sopenharmony_ci		.tuner_gpio    = maxmedia_ub425_tc,
22738c2ecf20Sopenharmony_ci		.has_dvb       = 1,
22748c2ecf20Sopenharmony_ci		.ir_codes      = RC_MAP_REDDO,
22758c2ecf20Sopenharmony_ci		.def_i2c_bus   = 1,
22768c2ecf20Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
22778c2ecf20Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
22788c2ecf20Sopenharmony_ci	},
22798c2ecf20Sopenharmony_ci	/*
22808c2ecf20Sopenharmony_ci	 * 2304:0242 PCTV QuatroStick (510e)
22818c2ecf20Sopenharmony_ci	 * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2
22828c2ecf20Sopenharmony_ci	 */
22838c2ecf20Sopenharmony_ci	[EM2884_BOARD_PCTV_510E] = {
22848c2ecf20Sopenharmony_ci		.name          = "PCTV QuatroStick (510e)",
22858c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
22868c2ecf20Sopenharmony_ci		.tuner_gpio    = pctv_510e,
22878c2ecf20Sopenharmony_ci		.has_dvb       = 1,
22888c2ecf20Sopenharmony_ci		.ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
22898c2ecf20Sopenharmony_ci		.def_i2c_bus   = 1,
22908c2ecf20Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
22918c2ecf20Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
22928c2ecf20Sopenharmony_ci	},
22938c2ecf20Sopenharmony_ci	/*
22948c2ecf20Sopenharmony_ci	 * 2013:0251 PCTV QuatroStick nano (520e)
22958c2ecf20Sopenharmony_ci	 * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2
22968c2ecf20Sopenharmony_ci	 */
22978c2ecf20Sopenharmony_ci	[EM2884_BOARD_PCTV_520E] = {
22988c2ecf20Sopenharmony_ci		.name          = "PCTV QuatroStick nano (520e)",
22998c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
23008c2ecf20Sopenharmony_ci		.tuner_gpio    = pctv_520e,
23018c2ecf20Sopenharmony_ci		.has_dvb       = 1,
23028c2ecf20Sopenharmony_ci		.ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
23038c2ecf20Sopenharmony_ci		.def_i2c_bus   = 1,
23048c2ecf20Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
23058c2ecf20Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
23068c2ecf20Sopenharmony_ci	},
23078c2ecf20Sopenharmony_ci	[EM2884_BOARD_TERRATEC_HTC_USB_XS] = {
23088c2ecf20Sopenharmony_ci		.name         = "Terratec Cinergy HTC USB XS",
23098c2ecf20Sopenharmony_ci		.has_dvb      = 1,
23108c2ecf20Sopenharmony_ci		.ir_codes     = RC_MAP_NEC_TERRATEC_CINERGY_XS,
23118c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
23128c2ecf20Sopenharmony_ci		.def_i2c_bus  = 1,
23138c2ecf20Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
23148c2ecf20Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
23158c2ecf20Sopenharmony_ci	},
23168c2ecf20Sopenharmony_ci	/*
23178c2ecf20Sopenharmony_ci	 * 1b80:e1cc Delock 61959
23188c2ecf20Sopenharmony_ci	 * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2
23198c2ecf20Sopenharmony_ci	 * mostly the same as MaxMedia UB-425-TC but different remote
23208c2ecf20Sopenharmony_ci	 */
23218c2ecf20Sopenharmony_ci	[EM2874_BOARD_DELOCK_61959] = {
23228c2ecf20Sopenharmony_ci		.name          = "Delock 61959",
23238c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
23248c2ecf20Sopenharmony_ci		.tuner_gpio    = maxmedia_ub425_tc,
23258c2ecf20Sopenharmony_ci		.has_dvb       = 1,
23268c2ecf20Sopenharmony_ci		.ir_codes      = RC_MAP_DELOCK_61959,
23278c2ecf20Sopenharmony_ci		.def_i2c_bus   = 1,
23288c2ecf20Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
23298c2ecf20Sopenharmony_ci				EM28XX_I2C_FREQ_400_KHZ,
23308c2ecf20Sopenharmony_ci	},
23318c2ecf20Sopenharmony_ci	/*
23328c2ecf20Sopenharmony_ci	 * 1b80:e346 KWorld USB ATSC TV Stick UB435-Q V2
23338c2ecf20Sopenharmony_ci	 * Empia EM2874B + LG DT3305 + NXP TDA18271HDC2
23348c2ecf20Sopenharmony_ci	 */
23358c2ecf20Sopenharmony_ci	[EM2874_BOARD_KWORLD_UB435Q_V2] = {
23368c2ecf20Sopenharmony_ci		.name		= "KWorld USB ATSC TV Stick UB435-Q V2",
23378c2ecf20Sopenharmony_ci		.tuner_type	= TUNER_ABSENT,
23388c2ecf20Sopenharmony_ci		.has_dvb	= 1,
23398c2ecf20Sopenharmony_ci		.dvb_gpio	= kworld_a340_digital,
23408c2ecf20Sopenharmony_ci		.tuner_gpio	= default_tuner_gpio,
23418c2ecf20Sopenharmony_ci		.def_i2c_bus	= 1,
23428c2ecf20Sopenharmony_ci	},
23438c2ecf20Sopenharmony_ci	/*
23448c2ecf20Sopenharmony_ci	 * 1b80:e34c KWorld USB ATSC TV Stick UB435-Q V3
23458c2ecf20Sopenharmony_ci	 * Empia EM2874B + LG DT3305 + NXP TDA18271HDC2
23468c2ecf20Sopenharmony_ci	 */
23478c2ecf20Sopenharmony_ci	[EM2874_BOARD_KWORLD_UB435Q_V3] = {
23488c2ecf20Sopenharmony_ci		.name		= "KWorld USB ATSC TV Stick UB435-Q V3",
23498c2ecf20Sopenharmony_ci		.tuner_type	= TUNER_ABSENT,
23508c2ecf20Sopenharmony_ci		.has_dvb	= 1,
23518c2ecf20Sopenharmony_ci		.tuner_gpio	= kworld_ub435q_v3_digital,
23528c2ecf20Sopenharmony_ci		.def_i2c_bus	= 1,
23538c2ecf20Sopenharmony_ci		.i2c_speed      = EM28XX_I2C_CLK_WAIT_ENABLE |
23548c2ecf20Sopenharmony_ci				  EM28XX_I2C_FREQ_100_KHZ,
23558c2ecf20Sopenharmony_ci		.leds = kworld_ub435q_v3_leds,
23568c2ecf20Sopenharmony_ci	},
23578c2ecf20Sopenharmony_ci	[EM2874_BOARD_PCTV_HD_MINI_80E] = {
23588c2ecf20Sopenharmony_ci		.name         = "Pinnacle PCTV HD Mini",
23598c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
23608c2ecf20Sopenharmony_ci		.has_dvb      = 1,
23618c2ecf20Sopenharmony_ci		.dvb_gpio     = em2874_pctv_80e_digital,
23628c2ecf20Sopenharmony_ci		.decoder      = EM28XX_NODECODER,
23638c2ecf20Sopenharmony_ci		.ir_codes     = RC_MAP_PINNACLE_PCTV_HD,
23648c2ecf20Sopenharmony_ci		.leds         = pctv_80e_leds,
23658c2ecf20Sopenharmony_ci	},
23668c2ecf20Sopenharmony_ci	/*
23678c2ecf20Sopenharmony_ci	 * 1ae7:9003/9004 SpeedLink Vicious And Devine Laplace webcam
23688c2ecf20Sopenharmony_ci	 * Empia EM2765 + OmniVision OV2640
23698c2ecf20Sopenharmony_ci	 */
23708c2ecf20Sopenharmony_ci	[EM2765_BOARD_SPEEDLINK_VAD_LAPLACE] = {
23718c2ecf20Sopenharmony_ci		.name         = "SpeedLink Vicious And Devine Laplace webcam",
23728c2ecf20Sopenharmony_ci		.xclk         = EM28XX_XCLK_FREQUENCY_24MHZ,
23738c2ecf20Sopenharmony_ci		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
23748c2ecf20Sopenharmony_ci				EM28XX_I2C_FREQ_100_KHZ,
23758c2ecf20Sopenharmony_ci		.def_i2c_bus  = 1,
23768c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
23778c2ecf20Sopenharmony_ci		.is_webcam    = 1,
23788c2ecf20Sopenharmony_ci		.input        = { {
23798c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
23808c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_VIDEO,
23818c2ecf20Sopenharmony_ci			.gpio     = speedlink_vad_laplace_reg_seq,
23828c2ecf20Sopenharmony_ci		} },
23838c2ecf20Sopenharmony_ci		.buttons = speedlink_vad_laplace_buttons,
23848c2ecf20Sopenharmony_ci		.leds = speedlink_vad_laplace_leds,
23858c2ecf20Sopenharmony_ci	},
23868c2ecf20Sopenharmony_ci	/*
23878c2ecf20Sopenharmony_ci	 * 2013:0258 PCTV DVB-S2 Stick (461e)
23888c2ecf20Sopenharmony_ci	 * Empia EM28178, Montage M88DS3103, Montage M88TS2022, Allegro A8293
23898c2ecf20Sopenharmony_ci	 */
23908c2ecf20Sopenharmony_ci	[EM28178_BOARD_PCTV_461E] = {
23918c2ecf20Sopenharmony_ci		.def_i2c_bus   = 1,
23928c2ecf20Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
23938c2ecf20Sopenharmony_ci				 EM28XX_I2C_FREQ_400_KHZ,
23948c2ecf20Sopenharmony_ci		.name          = "PCTV DVB-S2 Stick (461e)",
23958c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
23968c2ecf20Sopenharmony_ci		.tuner_gpio    = pctv_461e,
23978c2ecf20Sopenharmony_ci		.has_dvb       = 1,
23988c2ecf20Sopenharmony_ci		.ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
23998c2ecf20Sopenharmony_ci	},
24008c2ecf20Sopenharmony_ci	/*
24018c2ecf20Sopenharmony_ci	 * 2013:0259 PCTV DVB-S2 Stick (461e_v2)
24028c2ecf20Sopenharmony_ci	 * Empia EM28178, Montage M88DS3103b, Montage M88TS2022, Allegro A8293
24038c2ecf20Sopenharmony_ci	 */
24048c2ecf20Sopenharmony_ci	[EM28178_BOARD_PCTV_461E_V2] = {
24058c2ecf20Sopenharmony_ci		.def_i2c_bus   = 1,
24068c2ecf20Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
24078c2ecf20Sopenharmony_ci				 EM28XX_I2C_FREQ_400_KHZ,
24088c2ecf20Sopenharmony_ci		.name          = "PCTV DVB-S2 Stick (461e v2)",
24098c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
24108c2ecf20Sopenharmony_ci		.tuner_gpio    = pctv_461e,
24118c2ecf20Sopenharmony_ci		.has_dvb       = 1,
24128c2ecf20Sopenharmony_ci		.ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
24138c2ecf20Sopenharmony_ci	},
24148c2ecf20Sopenharmony_ci	/*
24158c2ecf20Sopenharmony_ci	 * 2013:025f PCTV tripleStick (292e).
24168c2ecf20Sopenharmony_ci	 * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2157
24178c2ecf20Sopenharmony_ci	 */
24188c2ecf20Sopenharmony_ci	[EM28178_BOARD_PCTV_292E] = {
24198c2ecf20Sopenharmony_ci		.name          = "PCTV tripleStick (292e)",
24208c2ecf20Sopenharmony_ci		.def_i2c_bus   = 1,
24218c2ecf20Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
24228c2ecf20Sopenharmony_ci				 EM28XX_I2C_FREQ_400_KHZ,
24238c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
24248c2ecf20Sopenharmony_ci		.tuner_gpio    = pctv_292e,
24258c2ecf20Sopenharmony_ci		.has_dvb       = 1,
24268c2ecf20Sopenharmony_ci		.ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
24278c2ecf20Sopenharmony_ci	},
24288c2ecf20Sopenharmony_ci	[EM2861_BOARD_LEADTEK_VC100] = {
24298c2ecf20Sopenharmony_ci		.name          = "Leadtek VC100",
24308c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,	/* Capture only device */
24318c2ecf20Sopenharmony_ci		.decoder       = EM28XX_TVP5150,
24328c2ecf20Sopenharmony_ci		.input         = { {
24338c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
24348c2ecf20Sopenharmony_ci			.vmux     = TVP5150_COMPOSITE1,
24358c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
24368c2ecf20Sopenharmony_ci		}, {
24378c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
24388c2ecf20Sopenharmony_ci			.vmux     = TVP5150_SVIDEO,
24398c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
24408c2ecf20Sopenharmony_ci		} },
24418c2ecf20Sopenharmony_ci	},
24428c2ecf20Sopenharmony_ci	/*
24438c2ecf20Sopenharmony_ci	 * eb1a:8179 Terratec Cinergy T2 Stick HD.
24448c2ecf20Sopenharmony_ci	 * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2146
24458c2ecf20Sopenharmony_ci	 */
24468c2ecf20Sopenharmony_ci	[EM28178_BOARD_TERRATEC_T2_STICK_HD] = {
24478c2ecf20Sopenharmony_ci		.name          = "Terratec Cinergy T2 Stick HD",
24488c2ecf20Sopenharmony_ci		.def_i2c_bus   = 1,
24498c2ecf20Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
24508c2ecf20Sopenharmony_ci				 EM28XX_I2C_FREQ_400_KHZ,
24518c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
24528c2ecf20Sopenharmony_ci		.tuner_gpio    = terratec_t2_stick_hd,
24538c2ecf20Sopenharmony_ci		.has_dvb       = 1,
24548c2ecf20Sopenharmony_ci		.ir_codes      = RC_MAP_TERRATEC_SLIM_2,
24558c2ecf20Sopenharmony_ci	},
24568c2ecf20Sopenharmony_ci
24578c2ecf20Sopenharmony_ci	/*
24588c2ecf20Sopenharmony_ci	 * 3275:0085 PLEX PX-BCUD.
24598c2ecf20Sopenharmony_ci	 * Empia EM28178, TOSHIBA TC90532XBG, Sharp QM1D1C0042
24608c2ecf20Sopenharmony_ci	 */
24618c2ecf20Sopenharmony_ci	[EM28178_BOARD_PLEX_PX_BCUD] = {
24628c2ecf20Sopenharmony_ci		.name          = "PLEX PX-BCUD",
24638c2ecf20Sopenharmony_ci		.xclk          = EM28XX_XCLK_FREQUENCY_4_3MHZ,
24648c2ecf20Sopenharmony_ci		.def_i2c_bus   = 1,
24658c2ecf20Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE,
24668c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
24678c2ecf20Sopenharmony_ci		.tuner_gpio    = plex_px_bcud,
24688c2ecf20Sopenharmony_ci		.has_dvb       = 1,
24698c2ecf20Sopenharmony_ci	},
24708c2ecf20Sopenharmony_ci	/*
24718c2ecf20Sopenharmony_ci	 * 2040:0265 Hauppauge WinTV-dualHD (DVB version) Isoc.
24728c2ecf20Sopenharmony_ci	 * 2040:8265 Hauppauge WinTV-dualHD (DVB version) Bulk.
24738c2ecf20Sopenharmony_ci	 * Empia EM28274, 2x Silicon Labs Si2168, 2x Silicon Labs Si2157
24748c2ecf20Sopenharmony_ci	 */
24758c2ecf20Sopenharmony_ci	[EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB] = {
24768c2ecf20Sopenharmony_ci		.name          = "Hauppauge WinTV-dualHD DVB",
24778c2ecf20Sopenharmony_ci		.def_i2c_bus   = 1,
24788c2ecf20Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
24798c2ecf20Sopenharmony_ci				 EM28XX_I2C_FREQ_400_KHZ,
24808c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
24818c2ecf20Sopenharmony_ci		.tuner_gpio    = hauppauge_dualhd_dvb,
24828c2ecf20Sopenharmony_ci		.has_dvb       = 1,
24838c2ecf20Sopenharmony_ci		.has_dual_ts   = 1,
24848c2ecf20Sopenharmony_ci		.ir_codes      = RC_MAP_HAUPPAUGE,
24858c2ecf20Sopenharmony_ci		.leds          = hauppauge_dualhd_leds,
24868c2ecf20Sopenharmony_ci	},
24878c2ecf20Sopenharmony_ci	/*
24888c2ecf20Sopenharmony_ci	 * 2040:026d Hauppauge WinTV-dualHD (model 01595 - ATSC/QAM) Isoc.
24898c2ecf20Sopenharmony_ci	 * 2040:826d Hauppauge WinTV-dualHD (model 01595 - ATSC/QAM) Bulk.
24908c2ecf20Sopenharmony_ci	 * Empia EM28274, 2x LG LGDT3306A, 2x Silicon Labs Si2157
24918c2ecf20Sopenharmony_ci	 */
24928c2ecf20Sopenharmony_ci	[EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595] = {
24938c2ecf20Sopenharmony_ci		.name          = "Hauppauge WinTV-dualHD 01595 ATSC/QAM",
24948c2ecf20Sopenharmony_ci		.def_i2c_bus   = 1,
24958c2ecf20Sopenharmony_ci		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
24968c2ecf20Sopenharmony_ci				 EM28XX_I2C_FREQ_400_KHZ,
24978c2ecf20Sopenharmony_ci		.tuner_type    = TUNER_ABSENT,
24988c2ecf20Sopenharmony_ci		.tuner_gpio    = hauppauge_dualhd_dvb,
24998c2ecf20Sopenharmony_ci		.has_dvb       = 1,
25008c2ecf20Sopenharmony_ci		.has_dual_ts   = 1,
25018c2ecf20Sopenharmony_ci		.ir_codes      = RC_MAP_HAUPPAUGE,
25028c2ecf20Sopenharmony_ci		.leds          = hauppauge_dualhd_leds,
25038c2ecf20Sopenharmony_ci	},
25048c2ecf20Sopenharmony_ci	/*
25058c2ecf20Sopenharmony_ci	 * 1b80:e349 Magix USB Videowandler-2
25068c2ecf20Sopenharmony_ci	 * (same chips as Honestech VIDBOX NW03)
25078c2ecf20Sopenharmony_ci	 * Empia EM2860, Philips SAA7113, Empia EMP202, No Tuner
25088c2ecf20Sopenharmony_ci	 */
25098c2ecf20Sopenharmony_ci	[EM2861_BOARD_MAGIX_VIDEOWANDLER2] = {
25108c2ecf20Sopenharmony_ci		.name                = "Magix USB Videowandler-2",
25118c2ecf20Sopenharmony_ci		.tuner_type          = TUNER_ABSENT,
25128c2ecf20Sopenharmony_ci		.decoder             = EM28XX_SAA711X,
25138c2ecf20Sopenharmony_ci		.input               = { {
25148c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
25158c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
25168c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
25178c2ecf20Sopenharmony_ci		}, {
25188c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
25198c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
25208c2ecf20Sopenharmony_ci		} },
25218c2ecf20Sopenharmony_ci	},
25228c2ecf20Sopenharmony_ci	/*
25238c2ecf20Sopenharmony_ci	 * 1f4d:1abe MyGica iGrabber
25248c2ecf20Sopenharmony_ci	 * (same as several other EM2860 devices)
25258c2ecf20Sopenharmony_ci	 * Empia EM2860, Philips SAA7113, Empia EMP202, No Tuner
25268c2ecf20Sopenharmony_ci	 */
25278c2ecf20Sopenharmony_ci	[EM2860_BOARD_MYGICA_IGRABBER] = {
25288c2ecf20Sopenharmony_ci		.name         = "MyGica iGrabber",
25298c2ecf20Sopenharmony_ci		.vchannels    = 2,
25308c2ecf20Sopenharmony_ci		.tuner_type   = TUNER_ABSENT,
25318c2ecf20Sopenharmony_ci		.decoder      = EM28XX_SAA711X,
25328c2ecf20Sopenharmony_ci		.input           = { {
25338c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_COMPOSITE,
25348c2ecf20Sopenharmony_ci			.vmux     = SAA7115_COMPOSITE0,
25358c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
25368c2ecf20Sopenharmony_ci		}, {
25378c2ecf20Sopenharmony_ci			.type     = EM28XX_VMUX_SVIDEO,
25388c2ecf20Sopenharmony_ci			.vmux     = SAA7115_SVIDEO3,
25398c2ecf20Sopenharmony_ci			.amux     = EM28XX_AMUX_LINE_IN,
25408c2ecf20Sopenharmony_ci		} },
25418c2ecf20Sopenharmony_ci	},
25428c2ecf20Sopenharmony_ci};
25438c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(em28xx_boards);
25448c2ecf20Sopenharmony_ci
25458c2ecf20Sopenharmony_cistatic const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
25468c2ecf20Sopenharmony_ci
25478c2ecf20Sopenharmony_ci/* table of devices that work with this driver */
25488c2ecf20Sopenharmony_cistruct usb_device_id em28xx_id_table[] = {
25498c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2750),
25508c2ecf20Sopenharmony_ci			.driver_info = EM2750_BOARD_UNKNOWN },
25518c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2751),
25528c2ecf20Sopenharmony_ci			.driver_info = EM2750_BOARD_UNKNOWN },
25538c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2800),
25548c2ecf20Sopenharmony_ci			.driver_info = EM2800_BOARD_UNKNOWN },
25558c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2710),
25568c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
25578c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2820),
25588c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
25598c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2821),
25608c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
25618c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2860),
25628c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
25638c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2861),
25648c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
25658c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2862),
25668c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
25678c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2863),
25688c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
25698c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2870),
25708c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
25718c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2881),
25728c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
25738c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2883), /* used by :Zolid Hybrid Tv Stick */
25748c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
25758c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2868),
25768c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
25778c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2875),
25788c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_UNKNOWN },
25798c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2885), /* MSI Digivox Trio */
25808c2ecf20Sopenharmony_ci			.driver_info = EM2884_BOARD_TERRATEC_H5 },
25818c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe300),
25828c2ecf20Sopenharmony_ci			.driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
25838c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe303),
25848c2ecf20Sopenharmony_ci			.driver_info = EM2860_BOARD_KAIOMY_TVNPC_U2 },
25858c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe305),
25868c2ecf20Sopenharmony_ci			.driver_info = EM2880_BOARD_KWORLD_DVB_305U },
25878c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe310),
25888c2ecf20Sopenharmony_ci			.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD },
25898c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xa313),
25908c2ecf20Sopenharmony_ci		.driver_info = EM2882_BOARD_KWORLD_ATSC_315U },
25918c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xa316),
25928c2ecf20Sopenharmony_ci			.driver_info = EM2883_BOARD_KWORLD_HYBRID_330U },
25938c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe320),
25948c2ecf20Sopenharmony_ci			.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II },
25958c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe323),
25968c2ecf20Sopenharmony_ci			.driver_info = EM2882_BOARD_KWORLD_VS_DVBT },
25978c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe350),
25988c2ecf20Sopenharmony_ci			.driver_info = EM2870_BOARD_KWORLD_350U },
25998c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe355),
26008c2ecf20Sopenharmony_ci			.driver_info = EM2870_BOARD_KWORLD_355U },
26018c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x2801),
26028c2ecf20Sopenharmony_ci			.driver_info = EM2800_BOARD_GRABBEEX_USB2800 },
26038c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe357),
26048c2ecf20Sopenharmony_ci			.driver_info = EM2870_BOARD_KWORLD_355U },
26058c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0xe359),
26068c2ecf20Sopenharmony_ci			.driver_info = EM2870_BOARD_KWORLD_355U },
26078c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe302), /* Kaiser Baas Video to DVD maker */
26088c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
26098c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe304), /* Kworld DVD Maker 2 */
26108c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
26118c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x0036),
26128c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
26138c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x004c),
26148c2ecf20Sopenharmony_ci			.driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS_FR },
26158c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x004f),
26168c2ecf20Sopenharmony_ci			.driver_info = EM2860_BOARD_TERRATEC_HYBRID_XS },
26178c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x005e),
26188c2ecf20Sopenharmony_ci			.driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
26198c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x0042),
26208c2ecf20Sopenharmony_ci			.driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
26218c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x0043),
26228c2ecf20Sopenharmony_ci			.driver_info = EM2870_BOARD_TERRATEC_XS_MT2060 },
26238c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x008e),	/* Cinergy HTC USB XS Rev. 1 */
26248c2ecf20Sopenharmony_ci			.driver_info = EM2884_BOARD_TERRATEC_HTC_USB_XS },
26258c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x00ac),	/* Cinergy HTC USB XS Rev. 2 */
26268c2ecf20Sopenharmony_ci			.driver_info = EM2884_BOARD_TERRATEC_HTC_USB_XS },
26278c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x10a2),	/* H5 Rev. 1 */
26288c2ecf20Sopenharmony_ci			.driver_info = EM2884_BOARD_TERRATEC_H5 },
26298c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x10ad),	/* H5 Rev. 2 */
26308c2ecf20Sopenharmony_ci			.driver_info = EM2884_BOARD_TERRATEC_H5 },
26318c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x10b6),	/* H5 Rev. 3 */
26328c2ecf20Sopenharmony_ci			.driver_info = EM2884_BOARD_TERRATEC_H5 },
26338c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x10b2),	/* H6 */
26348c2ecf20Sopenharmony_ci			.driver_info = EM2884_BOARD_TERRATEC_H6 },
26358c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x0084),
26368c2ecf20Sopenharmony_ci			.driver_info = EM2860_BOARD_TERRATEC_AV350 },
26378c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x0096),
26388c2ecf20Sopenharmony_ci			.driver_info = EM2860_BOARD_TERRATEC_GRABBY },
26398c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x10AF),
26408c2ecf20Sopenharmony_ci			.driver_info = EM2860_BOARD_TERRATEC_GRABBY },
26418c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0ccd, 0x00b2),
26428c2ecf20Sopenharmony_ci			.driver_info = EM2884_BOARD_CINERGY_HTC_STICK },
26438c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0fd9, 0x0018),
26448c2ecf20Sopenharmony_ci			.driver_info = EM2884_BOARD_ELGATO_EYETV_HYBRID_2008 },
26458c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0fd9, 0x0033),
26468c2ecf20Sopenharmony_ci			.driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE },
26478c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x185b, 0x2870),
26488c2ecf20Sopenharmony_ci			.driver_info = EM2870_BOARD_COMPRO_VIDEOMATE },
26498c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x185b, 0x2041),
26508c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU },
26518c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x4200),
26528c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
26538c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x4201),
26548c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
26558c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x6500),
26568c2ecf20Sopenharmony_ci			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
26578c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x6502),
26588c2ecf20Sopenharmony_ci			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 },
26598c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */
26608c2ecf20Sopenharmony_ci			.driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
26618c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x6517), /* HP  HVR-950 */
26628c2ecf20Sopenharmony_ci			.driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
26638c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x651b), /* RP  HVR-950 */
26648c2ecf20Sopenharmony_ci			.driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
26658c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x651f),
26668c2ecf20Sopenharmony_ci			.driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 },
26678c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x0265),
26688c2ecf20Sopenharmony_ci			.driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB },
26698c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x8265),
26708c2ecf20Sopenharmony_ci			.driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB },
26718c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x026d),
26728c2ecf20Sopenharmony_ci			.driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 },
26738c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x826d),
26748c2ecf20Sopenharmony_ci			.driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 },
26758c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0438, 0xb002),
26768c2ecf20Sopenharmony_ci			.driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 },
26778c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2001, 0xf112),
26788c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_DLINK_USB_TV },
26798c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2304, 0x0207),
26808c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
26818c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2304, 0x0208),
26828c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_PINNACLE_USB_2 },
26838c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2304, 0x021a),
26848c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
26858c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2304, 0x0226),
26868c2ecf20Sopenharmony_ci			.driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO_330E },
26878c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2304, 0x0227),
26888c2ecf20Sopenharmony_ci			.driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
26898c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2304, 0x023f),
26908c2ecf20Sopenharmony_ci			.driver_info = EM2874_BOARD_PCTV_HD_MINI_80E },
26918c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0413, 0x6023),
26928c2ecf20Sopenharmony_ci			.driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII },
26938c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x093b, 0xa003),
26948c2ecf20Sopenharmony_ci		       .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
26958c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x093b, 0xa005),
26968c2ecf20Sopenharmony_ci			.driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U },
26978c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x04bb, 0x0515),
26988c2ecf20Sopenharmony_ci			.driver_info = EM2820_BOARD_IODATA_GVMVP_SZ },
26998c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x50a6),
27008c2ecf20Sopenharmony_ci			.driver_info = EM2860_BOARD_GADMEI_UTV330 },
27018c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xa340),
27028c2ecf20Sopenharmony_ci			.driver_info = EM2870_BOARD_KWORLD_A340 },
27038c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe346),
27048c2ecf20Sopenharmony_ci			.driver_info = EM2874_BOARD_KWORLD_UB435Q_V2 },
27058c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe34c),
27068c2ecf20Sopenharmony_ci			.driver_info = EM2874_BOARD_KWORLD_UB435Q_V3 },
27078c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x024f),
27088c2ecf20Sopenharmony_ci			.driver_info = EM28174_BOARD_PCTV_290E },
27098c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x024c),
27108c2ecf20Sopenharmony_ci			.driver_info = EM28174_BOARD_PCTV_460E },
27118c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x1605),
27128c2ecf20Sopenharmony_ci			.driver_info = EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C },
27138c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe755),
27148c2ecf20Sopenharmony_ci			.driver_info = EM2884_BOARD_C3TECH_DIGITAL_DUO },
27158c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x5006),
27168c2ecf20Sopenharmony_ci			.driver_info = EM2860_BOARD_HT_VIDBOX_NW03 },
27178c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe309), /* Sveon STV40 */
27188c2ecf20Sopenharmony_ci			.driver_info = EM2860_BOARD_EASYCAP },
27198c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe425),
27208c2ecf20Sopenharmony_ci			.driver_info = EM2874_BOARD_MAXMEDIA_UB425_TC },
27218c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x1f4d, 0x1abe),
27228c2ecf20Sopenharmony_ci			.driver_info = EM2860_BOARD_MYGICA_IGRABBER },
27238c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2304, 0x0242),
27248c2ecf20Sopenharmony_ci			.driver_info = EM2884_BOARD_PCTV_510E },
27258c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x0251),
27268c2ecf20Sopenharmony_ci			.driver_info = EM2884_BOARD_PCTV_520E },
27278c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe1cc),
27288c2ecf20Sopenharmony_ci			.driver_info = EM2874_BOARD_DELOCK_61959 },
27298c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x1ae7, 0x9003),
27308c2ecf20Sopenharmony_ci			.driver_info = EM2765_BOARD_SPEEDLINK_VAD_LAPLACE },
27318c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x1ae7, 0x9004),
27328c2ecf20Sopenharmony_ci			.driver_info = EM2765_BOARD_SPEEDLINK_VAD_LAPLACE },
27338c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x0258),
27348c2ecf20Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_461E },
27358c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x0461),
27368c2ecf20Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_461E_V2 },
27378c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x0259),
27388c2ecf20Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_461E_V2 },
27398c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x025f),
27408c2ecf20Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_292E },
27418c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2013, 0x0264), /* Hauppauge WinTV-soloHD 292e SE */
27428c2ecf20Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_292E },
27438c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x0264), /* Hauppauge WinTV-soloHD Isoc */
27448c2ecf20Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_292E },
27458c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x8264), /* Hauppauge OEM Generic WinTV-soloHD Bulk */
27468c2ecf20Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_292E },
27478c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x2040, 0x8268), /* Hauppauge Retail WinTV-soloHD Bulk */
27488c2ecf20Sopenharmony_ci			.driver_info = EM28178_BOARD_PCTV_292E },
27498c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x0413, 0x6f07),
27508c2ecf20Sopenharmony_ci			.driver_info = EM2861_BOARD_LEADTEK_VC100 },
27518c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x8179),
27528c2ecf20Sopenharmony_ci			.driver_info = EM28178_BOARD_TERRATEC_T2_STICK_HD },
27538c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x3275, 0x0085),
27548c2ecf20Sopenharmony_ci			.driver_info = EM28178_BOARD_PLEX_PX_BCUD },
27558c2ecf20Sopenharmony_ci	{ USB_DEVICE(0xeb1a, 0x5051), /* Ion Video 2 PC MKII / Startech svid2usb23 / Raygo R12-41373 */
27568c2ecf20Sopenharmony_ci			.driver_info = EM2860_BOARD_TVP5150_REFERENCE_DESIGN },
27578c2ecf20Sopenharmony_ci	{ USB_DEVICE(0x1b80, 0xe349), /* Magix USB Videowandler-2 */
27588c2ecf20Sopenharmony_ci		.driver_info = EM2861_BOARD_MAGIX_VIDEOWANDLER2 },
27598c2ecf20Sopenharmony_ci	{ },
27608c2ecf20Sopenharmony_ci};
27618c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(usb, em28xx_id_table);
27628c2ecf20Sopenharmony_ci
27638c2ecf20Sopenharmony_ci/*
27648c2ecf20Sopenharmony_ci * EEPROM hash table for devices with generic USB IDs
27658c2ecf20Sopenharmony_ci */
27668c2ecf20Sopenharmony_cistatic const struct em28xx_hash_table em28xx_eeprom_hash[] = {
27678c2ecf20Sopenharmony_ci	/* P/N: SA 60002070465 Tuner: TVF7533-MF */
27688c2ecf20Sopenharmony_ci	{0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
27698c2ecf20Sopenharmony_ci	{0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
27708c2ecf20Sopenharmony_ci	{0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028},
27718c2ecf20Sopenharmony_ci	{0x166a0441, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028},
27728c2ecf20Sopenharmony_ci	{0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028},
27738c2ecf20Sopenharmony_ci	{0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028},
27748c2ecf20Sopenharmony_ci	{0x63f653bd, EM2870_BOARD_REDDO_DVB_C_USB_BOX, TUNER_ABSENT},
27758c2ecf20Sopenharmony_ci	{0x4e913442, EM2882_BOARD_DIKOM_DK300, TUNER_XC2028},
27768c2ecf20Sopenharmony_ci	{0x85dd871e, EM2882_BOARD_ZOLID_HYBRID_TV_STICK, TUNER_XC2028},
27778c2ecf20Sopenharmony_ci};
27788c2ecf20Sopenharmony_ci
27798c2ecf20Sopenharmony_ci/* I2C devicelist hash table for devices with generic USB IDs */
27808c2ecf20Sopenharmony_cistatic const struct em28xx_hash_table em28xx_i2c_hash[] = {
27818c2ecf20Sopenharmony_ci	{0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
27828c2ecf20Sopenharmony_ci	{0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
27838c2ecf20Sopenharmony_ci	{0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT},
27848c2ecf20Sopenharmony_ci	{0x77800080, EM2860_BOARD_TVP5150_REFERENCE_DESIGN, TUNER_ABSENT},
27858c2ecf20Sopenharmony_ci	{0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
27868c2ecf20Sopenharmony_ci	{0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF},
27878c2ecf20Sopenharmony_ci	{0x6b800080, EM2874_BOARD_LEADERSHIP_ISDBT, TUNER_ABSENT},
27888c2ecf20Sopenharmony_ci	{0x27e10080, EM2882_BOARD_ZOLID_HYBRID_TV_STICK, TUNER_XC2028},
27898c2ecf20Sopenharmony_ci};
27908c2ecf20Sopenharmony_ci
27918c2ecf20Sopenharmony_ci/* NOTE: introduce a separate hash table for devices with 16 bit eeproms */
27928c2ecf20Sopenharmony_ci
27938c2ecf20Sopenharmony_ciint em28xx_tuner_callback(void *ptr, int component, int command, int arg)
27948c2ecf20Sopenharmony_ci{
27958c2ecf20Sopenharmony_ci	struct em28xx_i2c_bus *i2c_bus = ptr;
27968c2ecf20Sopenharmony_ci	struct em28xx *dev = i2c_bus->dev;
27978c2ecf20Sopenharmony_ci	int rc = 0;
27988c2ecf20Sopenharmony_ci
27998c2ecf20Sopenharmony_ci	if (dev->tuner_type != TUNER_XC2028 && dev->tuner_type != TUNER_XC5000)
28008c2ecf20Sopenharmony_ci		return 0;
28018c2ecf20Sopenharmony_ci
28028c2ecf20Sopenharmony_ci	if (command != XC2028_TUNER_RESET && command != XC5000_TUNER_RESET)
28038c2ecf20Sopenharmony_ci		return 0;
28048c2ecf20Sopenharmony_ci
28058c2ecf20Sopenharmony_ci	rc = em28xx_gpio_set(dev, dev->board.tuner_gpio);
28068c2ecf20Sopenharmony_ci
28078c2ecf20Sopenharmony_ci	return rc;
28088c2ecf20Sopenharmony_ci}
28098c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(em28xx_tuner_callback);
28108c2ecf20Sopenharmony_ci
28118c2ecf20Sopenharmony_cistatic inline void em28xx_set_xclk_i2c_speed(struct em28xx *dev)
28128c2ecf20Sopenharmony_ci{
28138c2ecf20Sopenharmony_ci	const struct em28xx_board *board = &em28xx_boards[dev->model];
28148c2ecf20Sopenharmony_ci	u8 xclk = board->xclk, i2c_speed = board->i2c_speed;
28158c2ecf20Sopenharmony_ci
28168c2ecf20Sopenharmony_ci	/*
28178c2ecf20Sopenharmony_ci	 * Those are the default values for the majority of boards
28188c2ecf20Sopenharmony_ci	 * Use those values if not specified otherwise at boards entry
28198c2ecf20Sopenharmony_ci	 */
28208c2ecf20Sopenharmony_ci	if (!xclk)
28218c2ecf20Sopenharmony_ci		xclk = EM28XX_XCLK_IR_RC5_MODE |
28228c2ecf20Sopenharmony_ci		       EM28XX_XCLK_FREQUENCY_12MHZ;
28238c2ecf20Sopenharmony_ci
28248c2ecf20Sopenharmony_ci	em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk);
28258c2ecf20Sopenharmony_ci
28268c2ecf20Sopenharmony_ci	if (!i2c_speed)
28278c2ecf20Sopenharmony_ci		i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE |
28288c2ecf20Sopenharmony_ci			    EM28XX_I2C_FREQ_100_KHZ;
28298c2ecf20Sopenharmony_ci
28308c2ecf20Sopenharmony_ci	dev->i2c_speed = i2c_speed & 0x03;
28318c2ecf20Sopenharmony_ci
28328c2ecf20Sopenharmony_ci	if (!dev->board.is_em2800)
28338c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, i2c_speed);
28348c2ecf20Sopenharmony_ci	msleep(50);
28358c2ecf20Sopenharmony_ci}
28368c2ecf20Sopenharmony_ci
28378c2ecf20Sopenharmony_cistatic inline void em28xx_set_model(struct em28xx *dev)
28388c2ecf20Sopenharmony_ci{
28398c2ecf20Sopenharmony_ci	dev->board = em28xx_boards[dev->model];
28408c2ecf20Sopenharmony_ci	dev->has_msp34xx = dev->board.has_msp34xx;
28418c2ecf20Sopenharmony_ci	dev->is_webcam = dev->board.is_webcam;
28428c2ecf20Sopenharmony_ci
28438c2ecf20Sopenharmony_ci	em28xx_set_xclk_i2c_speed(dev);
28448c2ecf20Sopenharmony_ci
28458c2ecf20Sopenharmony_ci	/* Should be initialized early, for I2C to work */
28468c2ecf20Sopenharmony_ci	dev->def_i2c_bus = dev->board.def_i2c_bus;
28478c2ecf20Sopenharmony_ci}
28488c2ecf20Sopenharmony_ci
28498c2ecf20Sopenharmony_ci/*
28508c2ecf20Sopenharmony_ci * Wait until AC97_RESET reports the expected value reliably before proceeding.
28518c2ecf20Sopenharmony_ci * We also check that two unrelated registers accesses don't return the same
28528c2ecf20Sopenharmony_ci * value to avoid premature return.
28538c2ecf20Sopenharmony_ci * This procedure helps ensuring AC97 register accesses are reliable.
28548c2ecf20Sopenharmony_ci */
28558c2ecf20Sopenharmony_cistatic int em28xx_wait_until_ac97_features_equals(struct em28xx *dev,
28568c2ecf20Sopenharmony_ci						  int expected_feat)
28578c2ecf20Sopenharmony_ci{
28588c2ecf20Sopenharmony_ci	unsigned long timeout = jiffies + msecs_to_jiffies(2000);
28598c2ecf20Sopenharmony_ci	int feat, powerdown;
28608c2ecf20Sopenharmony_ci
28618c2ecf20Sopenharmony_ci	while (time_is_after_jiffies(timeout)) {
28628c2ecf20Sopenharmony_ci		feat = em28xx_read_ac97(dev, AC97_RESET);
28638c2ecf20Sopenharmony_ci		if (feat < 0)
28648c2ecf20Sopenharmony_ci			return feat;
28658c2ecf20Sopenharmony_ci
28668c2ecf20Sopenharmony_ci		powerdown = em28xx_read_ac97(dev, AC97_POWERDOWN);
28678c2ecf20Sopenharmony_ci		if (powerdown < 0)
28688c2ecf20Sopenharmony_ci			return powerdown;
28698c2ecf20Sopenharmony_ci
28708c2ecf20Sopenharmony_ci		if (feat == expected_feat && feat != powerdown)
28718c2ecf20Sopenharmony_ci			return 0;
28728c2ecf20Sopenharmony_ci
28738c2ecf20Sopenharmony_ci		msleep(50);
28748c2ecf20Sopenharmony_ci	}
28758c2ecf20Sopenharmony_ci
28768c2ecf20Sopenharmony_ci	dev_warn(&dev->intf->dev, "AC97 registers access is not reliable !\n");
28778c2ecf20Sopenharmony_ci	return -ETIMEDOUT;
28788c2ecf20Sopenharmony_ci}
28798c2ecf20Sopenharmony_ci
28808c2ecf20Sopenharmony_ci/*
28818c2ecf20Sopenharmony_ci * Since em28xx_pre_card_setup() requires a proper dev->model,
28828c2ecf20Sopenharmony_ci * this won't work for boards with generic PCI IDs
28838c2ecf20Sopenharmony_ci */
28848c2ecf20Sopenharmony_cistatic void em28xx_pre_card_setup(struct em28xx *dev)
28858c2ecf20Sopenharmony_ci{
28868c2ecf20Sopenharmony_ci	/*
28878c2ecf20Sopenharmony_ci	 * Set the initial XCLK and I2C clock values based on the board
28888c2ecf20Sopenharmony_ci	 * definition
28898c2ecf20Sopenharmony_ci	 */
28908c2ecf20Sopenharmony_ci	em28xx_set_xclk_i2c_speed(dev);
28918c2ecf20Sopenharmony_ci
28928c2ecf20Sopenharmony_ci	/* request some modules */
28938c2ecf20Sopenharmony_ci	switch (dev->model) {
28948c2ecf20Sopenharmony_ci	case EM2861_BOARD_PLEXTOR_PX_TV100U:
28958c2ecf20Sopenharmony_ci		/* Sets the msp34xx I2S speed */
28968c2ecf20Sopenharmony_ci		dev->i2s_speed = 2048000;
28978c2ecf20Sopenharmony_ci		break;
28988c2ecf20Sopenharmony_ci	case EM2861_BOARD_KWORLD_PVRTV_300U:
28998c2ecf20Sopenharmony_ci	case EM2880_BOARD_KWORLD_DVB_305U:
29008c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x6d);
29018c2ecf20Sopenharmony_ci		usleep_range(10000, 11000);
29028c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x7d);
29038c2ecf20Sopenharmony_ci		usleep_range(10000, 11000);
29048c2ecf20Sopenharmony_ci		break;
29058c2ecf20Sopenharmony_ci	case EM2870_BOARD_COMPRO_VIDEOMATE:
29068c2ecf20Sopenharmony_ci		/*
29078c2ecf20Sopenharmony_ci		 * TODO: someone can do some cleanup here...
29088c2ecf20Sopenharmony_ci		 *	 not everything's needed
29098c2ecf20Sopenharmony_ci		 */
29108c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2880_R04_GPO, 0x00);
29118c2ecf20Sopenharmony_ci		usleep_range(10000, 11000);
29128c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2880_R04_GPO, 0x01);
29138c2ecf20Sopenharmony_ci		usleep_range(10000, 11000);
29148c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
29158c2ecf20Sopenharmony_ci		msleep(70);
29168c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfc);
29178c2ecf20Sopenharmony_ci		msleep(70);
29188c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xdc);
29198c2ecf20Sopenharmony_ci		msleep(70);
29208c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfc);
29218c2ecf20Sopenharmony_ci		msleep(70);
29228c2ecf20Sopenharmony_ci		break;
29238c2ecf20Sopenharmony_ci	case EM2870_BOARD_TERRATEC_XS_MT2060:
29248c2ecf20Sopenharmony_ci		/*
29258c2ecf20Sopenharmony_ci		 * this device needs some gpio writes to get the DVB-T
29268c2ecf20Sopenharmony_ci		 * demod work
29278c2ecf20Sopenharmony_ci		 */
29288c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
29298c2ecf20Sopenharmony_ci		msleep(70);
29308c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde);
29318c2ecf20Sopenharmony_ci		msleep(70);
29328c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
29338c2ecf20Sopenharmony_ci		msleep(70);
29348c2ecf20Sopenharmony_ci		break;
29358c2ecf20Sopenharmony_ci	case EM2870_BOARD_PINNACLE_PCTV_DVB:
29368c2ecf20Sopenharmony_ci		/*
29378c2ecf20Sopenharmony_ci		 * this device needs some gpio writes to get the
29388c2ecf20Sopenharmony_ci		 * DVB-T demod work
29398c2ecf20Sopenharmony_ci		 */
29408c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
29418c2ecf20Sopenharmony_ci		msleep(70);
29428c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde);
29438c2ecf20Sopenharmony_ci		msleep(70);
29448c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
29458c2ecf20Sopenharmony_ci		msleep(70);
29468c2ecf20Sopenharmony_ci		break;
29478c2ecf20Sopenharmony_ci	case EM2820_BOARD_GADMEI_UTV310:
29488c2ecf20Sopenharmony_ci	case EM2820_BOARD_MSI_VOX_USB_2:
29498c2ecf20Sopenharmony_ci		/* enables audio for that devices */
29508c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
29518c2ecf20Sopenharmony_ci		break;
29528c2ecf20Sopenharmony_ci
29538c2ecf20Sopenharmony_ci	case EM2882_BOARD_KWORLD_ATSC_315U:
29548c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
29558c2ecf20Sopenharmony_ci		usleep_range(10000, 11000);
29568c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
29578c2ecf20Sopenharmony_ci		usleep_range(10000, 11000);
29588c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2880_R04_GPO, 0x00);
29598c2ecf20Sopenharmony_ci		usleep_range(10000, 11000);
29608c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2880_R04_GPO, 0x08);
29618c2ecf20Sopenharmony_ci		usleep_range(10000, 11000);
29628c2ecf20Sopenharmony_ci		break;
29638c2ecf20Sopenharmony_ci
29648c2ecf20Sopenharmony_ci	case EM2860_BOARD_KAIOMY_TVNPC_U2:
29658c2ecf20Sopenharmony_ci		em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1);
29668c2ecf20Sopenharmony_ci		em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
29678c2ecf20Sopenharmony_ci		em28xx_write_regs(dev, 0x0d, "\x42", 1);
29688c2ecf20Sopenharmony_ci		em28xx_write_regs(dev, 0x08, "\xfd", 1);
29698c2ecf20Sopenharmony_ci		usleep_range(10000, 11000);
29708c2ecf20Sopenharmony_ci		em28xx_write_regs(dev, 0x08, "\xff", 1);
29718c2ecf20Sopenharmony_ci		usleep_range(10000, 11000);
29728c2ecf20Sopenharmony_ci		em28xx_write_regs(dev, 0x08, "\x7f", 1);
29738c2ecf20Sopenharmony_ci		usleep_range(10000, 11000);
29748c2ecf20Sopenharmony_ci		em28xx_write_regs(dev, 0x08, "\x6b", 1);
29758c2ecf20Sopenharmony_ci
29768c2ecf20Sopenharmony_ci		break;
29778c2ecf20Sopenharmony_ci	case EM2860_BOARD_EASYCAP:
29788c2ecf20Sopenharmony_ci		em28xx_write_regs(dev, 0x08, "\xf8", 1);
29798c2ecf20Sopenharmony_ci		break;
29808c2ecf20Sopenharmony_ci
29818c2ecf20Sopenharmony_ci	case EM2820_BOARD_IODATA_GVMVP_SZ:
29828c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
29838c2ecf20Sopenharmony_ci		msleep(70);
29848c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
29858c2ecf20Sopenharmony_ci		usleep_range(10000, 11000);
29868c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
29878c2ecf20Sopenharmony_ci		msleep(70);
29888c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
29898c2ecf20Sopenharmony_ci		msleep(70);
29908c2ecf20Sopenharmony_ci		break;
29918c2ecf20Sopenharmony_ci
29928c2ecf20Sopenharmony_ci	case EM2860_BOARD_TERRATEC_GRABBY:
29938c2ecf20Sopenharmony_ci		/*
29948c2ecf20Sopenharmony_ci		 * HACK?: Ensure AC97 register reading is reliable before
29958c2ecf20Sopenharmony_ci		 * proceeding. In practice, this will wait about 1.6 seconds.
29968c2ecf20Sopenharmony_ci		 */
29978c2ecf20Sopenharmony_ci		em28xx_wait_until_ac97_features_equals(dev, 0x6a90);
29988c2ecf20Sopenharmony_ci		break;
29998c2ecf20Sopenharmony_ci	}
30008c2ecf20Sopenharmony_ci
30018c2ecf20Sopenharmony_ci	em28xx_gpio_set(dev, dev->board.tuner_gpio);
30028c2ecf20Sopenharmony_ci	em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
30038c2ecf20Sopenharmony_ci
30048c2ecf20Sopenharmony_ci	/* Unlock device */
30058c2ecf20Sopenharmony_ci	em28xx_set_mode(dev, EM28XX_SUSPEND);
30068c2ecf20Sopenharmony_ci}
30078c2ecf20Sopenharmony_ci
30088c2ecf20Sopenharmony_cistatic int em28xx_hint_board(struct em28xx *dev)
30098c2ecf20Sopenharmony_ci{
30108c2ecf20Sopenharmony_ci	int i;
30118c2ecf20Sopenharmony_ci
30128c2ecf20Sopenharmony_ci	if (dev->is_webcam) {
30138c2ecf20Sopenharmony_ci		if (dev->em28xx_sensor == EM28XX_MT9V011) {
30148c2ecf20Sopenharmony_ci			dev->model = EM2820_BOARD_SILVERCREST_WEBCAM;
30158c2ecf20Sopenharmony_ci		} else if (dev->em28xx_sensor == EM28XX_MT9M001 ||
30168c2ecf20Sopenharmony_ci			   dev->em28xx_sensor == EM28XX_MT9M111) {
30178c2ecf20Sopenharmony_ci			dev->model = EM2750_BOARD_UNKNOWN;
30188c2ecf20Sopenharmony_ci		}
30198c2ecf20Sopenharmony_ci		/* FIXME: IMPROVE ! */
30208c2ecf20Sopenharmony_ci
30218c2ecf20Sopenharmony_ci		return 0;
30228c2ecf20Sopenharmony_ci	}
30238c2ecf20Sopenharmony_ci
30248c2ecf20Sopenharmony_ci	/*
30258c2ecf20Sopenharmony_ci	 * HINT method: EEPROM
30268c2ecf20Sopenharmony_ci	 *
30278c2ecf20Sopenharmony_ci	 * This method works only for boards with eeprom.
30288c2ecf20Sopenharmony_ci	 * Uses a hash of all eeprom bytes. The hash should be
30298c2ecf20Sopenharmony_ci	 * unique for a vendor/tuner pair.
30308c2ecf20Sopenharmony_ci	 * There are a high chance that tuners for different
30318c2ecf20Sopenharmony_ci	 * video standards produce different hashes.
30328c2ecf20Sopenharmony_ci	 */
30338c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(em28xx_eeprom_hash); i++) {
30348c2ecf20Sopenharmony_ci		if (dev->hash == em28xx_eeprom_hash[i].hash) {
30358c2ecf20Sopenharmony_ci			dev->model = em28xx_eeprom_hash[i].model;
30368c2ecf20Sopenharmony_ci			dev->tuner_type = em28xx_eeprom_hash[i].tuner;
30378c2ecf20Sopenharmony_ci
30388c2ecf20Sopenharmony_ci			dev_err(&dev->intf->dev,
30398c2ecf20Sopenharmony_ci				"Your board has no unique USB ID.\n"
30408c2ecf20Sopenharmony_ci				"A hint were successfully done, based on eeprom hash.\n"
30418c2ecf20Sopenharmony_ci				"This method is not 100%% failproof.\n"
30428c2ecf20Sopenharmony_ci				"If the board were misdetected, please email this log to:\n"
30438c2ecf20Sopenharmony_ci				"\tV4L Mailing List  <linux-media@vger.kernel.org>\n"
30448c2ecf20Sopenharmony_ci				"Board detected as %s\n",
30458c2ecf20Sopenharmony_ci			       em28xx_boards[dev->model].name);
30468c2ecf20Sopenharmony_ci
30478c2ecf20Sopenharmony_ci			return 0;
30488c2ecf20Sopenharmony_ci		}
30498c2ecf20Sopenharmony_ci	}
30508c2ecf20Sopenharmony_ci
30518c2ecf20Sopenharmony_ci	/*
30528c2ecf20Sopenharmony_ci	 * HINT method: I2C attached devices
30538c2ecf20Sopenharmony_ci	 *
30548c2ecf20Sopenharmony_ci	 * This method works for all boards.
30558c2ecf20Sopenharmony_ci	 * Uses a hash of i2c scanned devices.
30568c2ecf20Sopenharmony_ci	 * Devices with the same i2c attached chips will
30578c2ecf20Sopenharmony_ci	 * be considered equal.
30588c2ecf20Sopenharmony_ci	 * This method is less precise than the eeprom one.
30598c2ecf20Sopenharmony_ci	 */
30608c2ecf20Sopenharmony_ci
30618c2ecf20Sopenharmony_ci	/* user did not request i2c scanning => do it now */
30628c2ecf20Sopenharmony_ci	if (!dev->i2c_hash)
30638c2ecf20Sopenharmony_ci		em28xx_do_i2c_scan(dev, dev->def_i2c_bus);
30648c2ecf20Sopenharmony_ci
30658c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(em28xx_i2c_hash); i++) {
30668c2ecf20Sopenharmony_ci		if (dev->i2c_hash == em28xx_i2c_hash[i].hash) {
30678c2ecf20Sopenharmony_ci			dev->model = em28xx_i2c_hash[i].model;
30688c2ecf20Sopenharmony_ci			dev->tuner_type = em28xx_i2c_hash[i].tuner;
30698c2ecf20Sopenharmony_ci			dev_err(&dev->intf->dev,
30708c2ecf20Sopenharmony_ci				"Your board has no unique USB ID.\n"
30718c2ecf20Sopenharmony_ci				"A hint were successfully done, based on i2c devicelist hash.\n"
30728c2ecf20Sopenharmony_ci				"This method is not 100%% failproof.\n"
30738c2ecf20Sopenharmony_ci				"If the board were misdetected, please email this log to:\n"
30748c2ecf20Sopenharmony_ci				"\tV4L Mailing List  <linux-media@vger.kernel.org>\n"
30758c2ecf20Sopenharmony_ci				"Board detected as %s\n",
30768c2ecf20Sopenharmony_ci				em28xx_boards[dev->model].name);
30778c2ecf20Sopenharmony_ci
30788c2ecf20Sopenharmony_ci			return 0;
30798c2ecf20Sopenharmony_ci		}
30808c2ecf20Sopenharmony_ci	}
30818c2ecf20Sopenharmony_ci
30828c2ecf20Sopenharmony_ci	dev_err(&dev->intf->dev,
30838c2ecf20Sopenharmony_ci		"Your board has no unique USB ID and thus need a hint to be detected.\n"
30848c2ecf20Sopenharmony_ci		"You may try to use card=<n> insmod option to workaround that.\n"
30858c2ecf20Sopenharmony_ci		"Please send an email with this log to:\n"
30868c2ecf20Sopenharmony_ci		"\tV4L Mailing List <linux-media@vger.kernel.org>\n"
30878c2ecf20Sopenharmony_ci		"Board eeprom hash is 0x%08lx\n"
30888c2ecf20Sopenharmony_ci		"Board i2c devicelist hash is 0x%08lx\n",
30898c2ecf20Sopenharmony_ci		dev->hash, dev->i2c_hash);
30908c2ecf20Sopenharmony_ci
30918c2ecf20Sopenharmony_ci	dev_err(&dev->intf->dev,
30928c2ecf20Sopenharmony_ci		"Here is a list of valid choices for the card=<n> insmod option:\n");
30938c2ecf20Sopenharmony_ci	for (i = 0; i < em28xx_bcount; i++) {
30948c2ecf20Sopenharmony_ci		dev_err(&dev->intf->dev,
30958c2ecf20Sopenharmony_ci			"    card=%d -> %s\n", i, em28xx_boards[i].name);
30968c2ecf20Sopenharmony_ci	}
30978c2ecf20Sopenharmony_ci	return -1;
30988c2ecf20Sopenharmony_ci}
30998c2ecf20Sopenharmony_ci
31008c2ecf20Sopenharmony_cistatic void em28xx_card_setup(struct em28xx *dev)
31018c2ecf20Sopenharmony_ci{
31028c2ecf20Sopenharmony_ci	int i, j, idx;
31038c2ecf20Sopenharmony_ci	bool duplicate_entry;
31048c2ecf20Sopenharmony_ci
31058c2ecf20Sopenharmony_ci	/*
31068c2ecf20Sopenharmony_ci	 * If the device can be a webcam, seek for a sensor.
31078c2ecf20Sopenharmony_ci	 * If sensor is not found, then it isn't a webcam.
31088c2ecf20Sopenharmony_ci	 */
31098c2ecf20Sopenharmony_ci	if (dev->is_webcam) {
31108c2ecf20Sopenharmony_ci		em28xx_detect_sensor(dev);
31118c2ecf20Sopenharmony_ci		if (dev->em28xx_sensor == EM28XX_NOSENSOR)
31128c2ecf20Sopenharmony_ci			/* NOTE: error/unknown sensor/no sensor */
31138c2ecf20Sopenharmony_ci			dev->is_webcam = 0;
31148c2ecf20Sopenharmony_ci	}
31158c2ecf20Sopenharmony_ci
31168c2ecf20Sopenharmony_ci	switch (dev->model) {
31178c2ecf20Sopenharmony_ci	case EM2750_BOARD_UNKNOWN:
31188c2ecf20Sopenharmony_ci	case EM2820_BOARD_UNKNOWN:
31198c2ecf20Sopenharmony_ci	case EM2800_BOARD_UNKNOWN:
31208c2ecf20Sopenharmony_ci		/*
31218c2ecf20Sopenharmony_ci		 * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD.
31228c2ecf20Sopenharmony_ci		 *
31238c2ecf20Sopenharmony_ci		 * This occurs because they share identical USB vendor and
31248c2ecf20Sopenharmony_ci		 * product IDs.
31258c2ecf20Sopenharmony_ci		 *
31268c2ecf20Sopenharmony_ci		 * What we do here is look up the EEPROM hash of the K-WORLD
31278c2ecf20Sopenharmony_ci		 * and if it is found then we decide that we do not have
31288c2ecf20Sopenharmony_ci		 * a DIGIVOX and reset the device to the K-WORLD instead.
31298c2ecf20Sopenharmony_ci		 *
31308c2ecf20Sopenharmony_ci		 * This solution is only valid if they do not share eeprom
31318c2ecf20Sopenharmony_ci		 * hash identities which has not been determined as yet.
31328c2ecf20Sopenharmony_ci		 */
31338c2ecf20Sopenharmony_ci		if (em28xx_hint_board(dev) < 0) {
31348c2ecf20Sopenharmony_ci			dev_err(&dev->intf->dev, "Board not discovered\n");
31358c2ecf20Sopenharmony_ci		} else {
31368c2ecf20Sopenharmony_ci			em28xx_set_model(dev);
31378c2ecf20Sopenharmony_ci			em28xx_pre_card_setup(dev);
31388c2ecf20Sopenharmony_ci		}
31398c2ecf20Sopenharmony_ci		break;
31408c2ecf20Sopenharmony_ci	default:
31418c2ecf20Sopenharmony_ci		em28xx_set_model(dev);
31428c2ecf20Sopenharmony_ci	}
31438c2ecf20Sopenharmony_ci
31448c2ecf20Sopenharmony_ci	dev_info(&dev->intf->dev, "Identified as %s (card=%d)\n",
31458c2ecf20Sopenharmony_ci		 dev->board.name, dev->model);
31468c2ecf20Sopenharmony_ci
31478c2ecf20Sopenharmony_ci	dev->tuner_type = em28xx_boards[dev->model].tuner_type;
31488c2ecf20Sopenharmony_ci
31498c2ecf20Sopenharmony_ci	/* request some modules */
31508c2ecf20Sopenharmony_ci	switch (dev->model) {
31518c2ecf20Sopenharmony_ci	case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
31528c2ecf20Sopenharmony_ci	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
31538c2ecf20Sopenharmony_ci	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
31548c2ecf20Sopenharmony_ci	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
31558c2ecf20Sopenharmony_ci	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
31568c2ecf20Sopenharmony_ci	case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C:
31578c2ecf20Sopenharmony_ci	case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB:
31588c2ecf20Sopenharmony_ci	case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595:
31598c2ecf20Sopenharmony_ci	{
31608c2ecf20Sopenharmony_ci		struct tveeprom tv;
31618c2ecf20Sopenharmony_ci
31628c2ecf20Sopenharmony_ci		if (!dev->eedata)
31638c2ecf20Sopenharmony_ci			break;
31648c2ecf20Sopenharmony_ci#if defined(CONFIG_MODULES) && defined(MODULE)
31658c2ecf20Sopenharmony_ci		request_module("tveeprom");
31668c2ecf20Sopenharmony_ci#endif
31678c2ecf20Sopenharmony_ci		/* Call first TVeeprom */
31688c2ecf20Sopenharmony_ci
31698c2ecf20Sopenharmony_ci		tveeprom_hauppauge_analog(&tv, dev->eedata);
31708c2ecf20Sopenharmony_ci
31718c2ecf20Sopenharmony_ci		dev->tuner_type = tv.tuner_type;
31728c2ecf20Sopenharmony_ci
31738c2ecf20Sopenharmony_ci		if (tv.audio_processor == TVEEPROM_AUDPROC_MSP) {
31748c2ecf20Sopenharmony_ci			dev->i2s_speed = 2048000;
31758c2ecf20Sopenharmony_ci			dev->has_msp34xx = 1;
31768c2ecf20Sopenharmony_ci		}
31778c2ecf20Sopenharmony_ci		break;
31788c2ecf20Sopenharmony_ci	}
31798c2ecf20Sopenharmony_ci	case EM2882_BOARD_KWORLD_ATSC_315U:
31808c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, 0x0d, 0x42);
31818c2ecf20Sopenharmony_ci		usleep_range(10000, 11000);
31828c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
31838c2ecf20Sopenharmony_ci		usleep_range(10000, 11000);
31848c2ecf20Sopenharmony_ci		break;
31858c2ecf20Sopenharmony_ci	case EM2820_BOARD_KWORLD_PVRTV2800RF:
31868c2ecf20Sopenharmony_ci		/* GPIO enables sound on KWORLD PVR TV 2800RF */
31878c2ecf20Sopenharmony_ci		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf9);
31888c2ecf20Sopenharmony_ci		break;
31898c2ecf20Sopenharmony_ci	case EM2820_BOARD_UNKNOWN:
31908c2ecf20Sopenharmony_ci	case EM2800_BOARD_UNKNOWN:
31918c2ecf20Sopenharmony_ci		/*
31928c2ecf20Sopenharmony_ci		 * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD.
31938c2ecf20Sopenharmony_ci		 *
31948c2ecf20Sopenharmony_ci		 * This occurs because they share identical USB vendor and
31958c2ecf20Sopenharmony_ci		 * product IDs.
31968c2ecf20Sopenharmony_ci		 *
31978c2ecf20Sopenharmony_ci		 * What we do here is look up the EEPROM hash of the K-WORLD
31988c2ecf20Sopenharmony_ci		 * and if it is found then we decide that we do not have
31998c2ecf20Sopenharmony_ci		 * a DIGIVOX and reset the device to the K-WORLD instead.
32008c2ecf20Sopenharmony_ci		 *
32018c2ecf20Sopenharmony_ci		 * This solution is only valid if they do not share eeprom
32028c2ecf20Sopenharmony_ci		 * hash identities which has not been determined as yet.
32038c2ecf20Sopenharmony_ci		 */
32048c2ecf20Sopenharmony_ci	case EM2880_BOARD_MSI_DIGIVOX_AD:
32058c2ecf20Sopenharmony_ci		if (!em28xx_hint_board(dev))
32068c2ecf20Sopenharmony_ci			em28xx_set_model(dev);
32078c2ecf20Sopenharmony_ci
32088c2ecf20Sopenharmony_ci		/*
32098c2ecf20Sopenharmony_ci		 * In cases where we had to use a board hint, the call to
32108c2ecf20Sopenharmony_ci		 * em28xx_set_mode() in em28xx_pre_card_setup() was a no-op,
32118c2ecf20Sopenharmony_ci		 * so make the call now so the analog GPIOs are set properly
32128c2ecf20Sopenharmony_ci		 * before probing the i2c bus.
32138c2ecf20Sopenharmony_ci		 */
32148c2ecf20Sopenharmony_ci		em28xx_gpio_set(dev, dev->board.tuner_gpio);
32158c2ecf20Sopenharmony_ci		em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
32168c2ecf20Sopenharmony_ci		break;
32178c2ecf20Sopenharmony_ci
32188c2ecf20Sopenharmony_ci		/*
32198c2ecf20Sopenharmony_ci		 * The Dikom DK300 is detected as an Kworld VS-DVB-T 323UR.
32208c2ecf20Sopenharmony_ci		 *
32218c2ecf20Sopenharmony_ci		 * This occurs because they share identical USB vendor and
32228c2ecf20Sopenharmony_ci		 * product IDs.
32238c2ecf20Sopenharmony_ci		 *
32248c2ecf20Sopenharmony_ci		 * What we do here is look up the EEPROM hash of the Dikom
32258c2ecf20Sopenharmony_ci		 * and if it is found then we decide that we do not have
32268c2ecf20Sopenharmony_ci		 * a Kworld and reset the device to the Dikom instead.
32278c2ecf20Sopenharmony_ci		 *
32288c2ecf20Sopenharmony_ci		 * This solution is only valid if they do not share eeprom
32298c2ecf20Sopenharmony_ci		 * hash identities which has not been determined as yet.
32308c2ecf20Sopenharmony_ci		 */
32318c2ecf20Sopenharmony_ci	case EM2882_BOARD_KWORLD_VS_DVBT:
32328c2ecf20Sopenharmony_ci		if (!em28xx_hint_board(dev))
32338c2ecf20Sopenharmony_ci			em28xx_set_model(dev);
32348c2ecf20Sopenharmony_ci
32358c2ecf20Sopenharmony_ci		/*
32368c2ecf20Sopenharmony_ci		 * In cases where we had to use a board hint, the call to
32378c2ecf20Sopenharmony_ci		 * em28xx_set_mode() in em28xx_pre_card_setup() was a no-op,
32388c2ecf20Sopenharmony_ci		 * so make the call now so the analog GPIOs are set properly
32398c2ecf20Sopenharmony_ci		 * before probing the i2c bus.
32408c2ecf20Sopenharmony_ci		 */
32418c2ecf20Sopenharmony_ci		em28xx_gpio_set(dev, dev->board.tuner_gpio);
32428c2ecf20Sopenharmony_ci		em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
32438c2ecf20Sopenharmony_ci		break;
32448c2ecf20Sopenharmony_ci	}
32458c2ecf20Sopenharmony_ci
32468c2ecf20Sopenharmony_ci	if (dev->board.valid == EM28XX_BOARD_NOT_VALIDATED) {
32478c2ecf20Sopenharmony_ci		dev_err(&dev->intf->dev,
32488c2ecf20Sopenharmony_ci			"\n\n"
32498c2ecf20Sopenharmony_ci			"The support for this board weren't valid yet.\n"
32508c2ecf20Sopenharmony_ci			"Please send a report of having this working\n"
32518c2ecf20Sopenharmony_ci			"not to V4L mailing list (and/or to other addresses)\n\n");
32528c2ecf20Sopenharmony_ci	}
32538c2ecf20Sopenharmony_ci
32548c2ecf20Sopenharmony_ci	/* Free eeprom data memory */
32558c2ecf20Sopenharmony_ci	kfree(dev->eedata);
32568c2ecf20Sopenharmony_ci	dev->eedata = NULL;
32578c2ecf20Sopenharmony_ci
32588c2ecf20Sopenharmony_ci	/* Allow override tuner type by a module parameter */
32598c2ecf20Sopenharmony_ci	if (tuner >= 0)
32608c2ecf20Sopenharmony_ci		dev->tuner_type = tuner;
32618c2ecf20Sopenharmony_ci
32628c2ecf20Sopenharmony_ci	/*
32638c2ecf20Sopenharmony_ci	 * Dynamically generate a list of valid audio inputs for this
32648c2ecf20Sopenharmony_ci	 * specific board, mapping them via enum em28xx_amux.
32658c2ecf20Sopenharmony_ci	 */
32668c2ecf20Sopenharmony_ci
32678c2ecf20Sopenharmony_ci	idx = 0;
32688c2ecf20Sopenharmony_ci	for (i = 0; i < MAX_EM28XX_INPUT; i++) {
32698c2ecf20Sopenharmony_ci		if (!INPUT(i)->type)
32708c2ecf20Sopenharmony_ci			continue;
32718c2ecf20Sopenharmony_ci
32728c2ecf20Sopenharmony_ci		/* Skip already mapped audio inputs */
32738c2ecf20Sopenharmony_ci		duplicate_entry = false;
32748c2ecf20Sopenharmony_ci		for (j = 0; j < idx; j++) {
32758c2ecf20Sopenharmony_ci			if (INPUT(i)->amux == dev->amux_map[j]) {
32768c2ecf20Sopenharmony_ci				duplicate_entry = true;
32778c2ecf20Sopenharmony_ci				break;
32788c2ecf20Sopenharmony_ci			}
32798c2ecf20Sopenharmony_ci		}
32808c2ecf20Sopenharmony_ci		if (duplicate_entry)
32818c2ecf20Sopenharmony_ci			continue;
32828c2ecf20Sopenharmony_ci
32838c2ecf20Sopenharmony_ci		dev->amux_map[idx++] = INPUT(i)->amux;
32848c2ecf20Sopenharmony_ci	}
32858c2ecf20Sopenharmony_ci	for (; idx < MAX_EM28XX_INPUT; idx++)
32868c2ecf20Sopenharmony_ci		dev->amux_map[idx] = EM28XX_AMUX_UNUSED;
32878c2ecf20Sopenharmony_ci}
32888c2ecf20Sopenharmony_ci
32898c2ecf20Sopenharmony_civoid em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
32908c2ecf20Sopenharmony_ci{
32918c2ecf20Sopenharmony_ci	memset(ctl, 0, sizeof(*ctl));
32928c2ecf20Sopenharmony_ci
32938c2ecf20Sopenharmony_ci	ctl->fname   = XC2028_DEFAULT_FIRMWARE;
32948c2ecf20Sopenharmony_ci	ctl->max_len = 64;
32958c2ecf20Sopenharmony_ci	ctl->mts = em28xx_boards[dev->model].mts_firmware;
32968c2ecf20Sopenharmony_ci
32978c2ecf20Sopenharmony_ci	switch (dev->model) {
32988c2ecf20Sopenharmony_ci	case EM2880_BOARD_EMPIRE_DUAL_TV:
32998c2ecf20Sopenharmony_ci	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
33008c2ecf20Sopenharmony_ci	case EM2882_BOARD_TERRATEC_HYBRID_XS:
33018c2ecf20Sopenharmony_ci	case EM2880_BOARD_TERRATEC_HYBRID_XS:
33028c2ecf20Sopenharmony_ci	case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
33038c2ecf20Sopenharmony_ci	case EM2881_BOARD_PINNACLE_HYBRID_PRO:
33048c2ecf20Sopenharmony_ci	case EM2882_BOARD_ZOLID_HYBRID_TV_STICK:
33058c2ecf20Sopenharmony_ci		ctl->demod = XC3028_FE_ZARLINK456;
33068c2ecf20Sopenharmony_ci		break;
33078c2ecf20Sopenharmony_ci	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
33088c2ecf20Sopenharmony_ci	case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E:
33098c2ecf20Sopenharmony_ci		ctl->demod = XC3028_FE_DEFAULT;
33108c2ecf20Sopenharmony_ci		break;
33118c2ecf20Sopenharmony_ci	case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
33128c2ecf20Sopenharmony_ci		ctl->demod = XC3028_FE_DEFAULT;
33138c2ecf20Sopenharmony_ci		ctl->fname = XC3028L_DEFAULT_FIRMWARE;
33148c2ecf20Sopenharmony_ci		break;
33158c2ecf20Sopenharmony_ci	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
33168c2ecf20Sopenharmony_ci	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
33178c2ecf20Sopenharmony_ci	case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
33188c2ecf20Sopenharmony_ci		/* FIXME: Better to specify the needed IF */
33198c2ecf20Sopenharmony_ci		ctl->demod = XC3028_FE_DEFAULT;
33208c2ecf20Sopenharmony_ci		break;
33218c2ecf20Sopenharmony_ci	case EM2883_BOARD_KWORLD_HYBRID_330U:
33228c2ecf20Sopenharmony_ci	case EM2882_BOARD_DIKOM_DK300:
33238c2ecf20Sopenharmony_ci	case EM2882_BOARD_KWORLD_VS_DVBT:
33248c2ecf20Sopenharmony_ci		ctl->demod = XC3028_FE_CHINA;
33258c2ecf20Sopenharmony_ci		ctl->fname = XC2028_DEFAULT_FIRMWARE;
33268c2ecf20Sopenharmony_ci		break;
33278c2ecf20Sopenharmony_ci	case EM2882_BOARD_EVGA_INDTUBE:
33288c2ecf20Sopenharmony_ci		ctl->demod = XC3028_FE_CHINA;
33298c2ecf20Sopenharmony_ci		ctl->fname = XC3028L_DEFAULT_FIRMWARE;
33308c2ecf20Sopenharmony_ci		break;
33318c2ecf20Sopenharmony_ci	default:
33328c2ecf20Sopenharmony_ci		ctl->demod = XC3028_FE_OREN538;
33338c2ecf20Sopenharmony_ci	}
33348c2ecf20Sopenharmony_ci}
33358c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(em28xx_setup_xc3028);
33368c2ecf20Sopenharmony_ci
33378c2ecf20Sopenharmony_cistatic void request_module_async(struct work_struct *work)
33388c2ecf20Sopenharmony_ci{
33398c2ecf20Sopenharmony_ci	struct em28xx *dev = container_of(work,
33408c2ecf20Sopenharmony_ci			     struct em28xx, request_module_wk);
33418c2ecf20Sopenharmony_ci
33428c2ecf20Sopenharmony_ci	/*
33438c2ecf20Sopenharmony_ci	 * The em28xx extensions can be modules or builtin. If the
33448c2ecf20Sopenharmony_ci	 * modules are already loaded or are built in, those extensions
33458c2ecf20Sopenharmony_ci	 * can be initialised right now. Otherwise, the module init
33468c2ecf20Sopenharmony_ci	 * code will do it.
33478c2ecf20Sopenharmony_ci	 */
33488c2ecf20Sopenharmony_ci
33498c2ecf20Sopenharmony_ci	/*
33508c2ecf20Sopenharmony_ci	 * Devices with an audio-only intf also have a V4L/DVB/RC
33518c2ecf20Sopenharmony_ci	 * intf. Don't register extensions twice on those devices.
33528c2ecf20Sopenharmony_ci	 */
33538c2ecf20Sopenharmony_ci	if (dev->is_audio_only) {
33548c2ecf20Sopenharmony_ci#if defined(CONFIG_MODULES) && defined(MODULE)
33558c2ecf20Sopenharmony_ci		request_module("em28xx-alsa");
33568c2ecf20Sopenharmony_ci#endif
33578c2ecf20Sopenharmony_ci		return;
33588c2ecf20Sopenharmony_ci	}
33598c2ecf20Sopenharmony_ci
33608c2ecf20Sopenharmony_ci	em28xx_init_extension(dev);
33618c2ecf20Sopenharmony_ci
33628c2ecf20Sopenharmony_ci#if defined(CONFIG_MODULES) && defined(MODULE)
33638c2ecf20Sopenharmony_ci	if (dev->has_video)
33648c2ecf20Sopenharmony_ci		request_module("em28xx-v4l");
33658c2ecf20Sopenharmony_ci	if (dev->usb_audio_type == EM28XX_USB_AUDIO_CLASS)
33668c2ecf20Sopenharmony_ci		request_module("snd-usb-audio");
33678c2ecf20Sopenharmony_ci	else if (dev->usb_audio_type == EM28XX_USB_AUDIO_VENDOR)
33688c2ecf20Sopenharmony_ci		request_module("em28xx-alsa");
33698c2ecf20Sopenharmony_ci	if (dev->board.has_dvb)
33708c2ecf20Sopenharmony_ci		request_module("em28xx-dvb");
33718c2ecf20Sopenharmony_ci	if (dev->board.buttons ||
33728c2ecf20Sopenharmony_ci	    ((dev->board.ir_codes || dev->board.has_ir_i2c) && !disable_ir))
33738c2ecf20Sopenharmony_ci		request_module("em28xx-rc");
33748c2ecf20Sopenharmony_ci#endif /* CONFIG_MODULES */
33758c2ecf20Sopenharmony_ci}
33768c2ecf20Sopenharmony_ci
33778c2ecf20Sopenharmony_cistatic void request_modules(struct em28xx *dev)
33788c2ecf20Sopenharmony_ci{
33798c2ecf20Sopenharmony_ci	INIT_WORK(&dev->request_module_wk, request_module_async);
33808c2ecf20Sopenharmony_ci	schedule_work(&dev->request_module_wk);
33818c2ecf20Sopenharmony_ci}
33828c2ecf20Sopenharmony_ci
33838c2ecf20Sopenharmony_cistatic void flush_request_modules(struct em28xx *dev)
33848c2ecf20Sopenharmony_ci{
33858c2ecf20Sopenharmony_ci	flush_work(&dev->request_module_wk);
33868c2ecf20Sopenharmony_ci}
33878c2ecf20Sopenharmony_ci
33888c2ecf20Sopenharmony_cistatic int em28xx_media_device_init(struct em28xx *dev,
33898c2ecf20Sopenharmony_ci				    struct usb_device *udev)
33908c2ecf20Sopenharmony_ci{
33918c2ecf20Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER
33928c2ecf20Sopenharmony_ci	struct media_device *mdev;
33938c2ecf20Sopenharmony_ci
33948c2ecf20Sopenharmony_ci	mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
33958c2ecf20Sopenharmony_ci	if (!mdev)
33968c2ecf20Sopenharmony_ci		return -ENOMEM;
33978c2ecf20Sopenharmony_ci
33988c2ecf20Sopenharmony_ci	if (udev->product)
33998c2ecf20Sopenharmony_ci		media_device_usb_init(mdev, udev, udev->product);
34008c2ecf20Sopenharmony_ci	else if (udev->manufacturer)
34018c2ecf20Sopenharmony_ci		media_device_usb_init(mdev, udev, udev->manufacturer);
34028c2ecf20Sopenharmony_ci	else
34038c2ecf20Sopenharmony_ci		media_device_usb_init(mdev, udev, dev_name(&dev->intf->dev));
34048c2ecf20Sopenharmony_ci
34058c2ecf20Sopenharmony_ci	dev->media_dev = mdev;
34068c2ecf20Sopenharmony_ci#endif
34078c2ecf20Sopenharmony_ci	return 0;
34088c2ecf20Sopenharmony_ci}
34098c2ecf20Sopenharmony_ci
34108c2ecf20Sopenharmony_cistatic void em28xx_unregister_media_device(struct em28xx *dev)
34118c2ecf20Sopenharmony_ci{
34128c2ecf20Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER
34138c2ecf20Sopenharmony_ci	if (dev->media_dev) {
34148c2ecf20Sopenharmony_ci		media_device_unregister(dev->media_dev);
34158c2ecf20Sopenharmony_ci		media_device_cleanup(dev->media_dev);
34168c2ecf20Sopenharmony_ci		kfree(dev->media_dev);
34178c2ecf20Sopenharmony_ci		dev->media_dev = NULL;
34188c2ecf20Sopenharmony_ci	}
34198c2ecf20Sopenharmony_ci#endif
34208c2ecf20Sopenharmony_ci}
34218c2ecf20Sopenharmony_ci
34228c2ecf20Sopenharmony_ci/*
34238c2ecf20Sopenharmony_ci * em28xx_release_resources()
34248c2ecf20Sopenharmony_ci * unregisters the v4l2,i2c and usb devices
34258c2ecf20Sopenharmony_ci * called when the device gets disconnected or at module unload
34268c2ecf20Sopenharmony_ci */
34278c2ecf20Sopenharmony_cistatic void em28xx_release_resources(struct em28xx *dev)
34288c2ecf20Sopenharmony_ci{
34298c2ecf20Sopenharmony_ci	struct usb_device *udev = interface_to_usbdev(dev->intf);
34308c2ecf20Sopenharmony_ci
34318c2ecf20Sopenharmony_ci	/*FIXME: I2C IR should be disconnected */
34328c2ecf20Sopenharmony_ci
34338c2ecf20Sopenharmony_ci	mutex_lock(&dev->lock);
34348c2ecf20Sopenharmony_ci
34358c2ecf20Sopenharmony_ci	em28xx_unregister_media_device(dev);
34368c2ecf20Sopenharmony_ci
34378c2ecf20Sopenharmony_ci	if (dev->def_i2c_bus)
34388c2ecf20Sopenharmony_ci		em28xx_i2c_unregister(dev, 1);
34398c2ecf20Sopenharmony_ci	em28xx_i2c_unregister(dev, 0);
34408c2ecf20Sopenharmony_ci
34418c2ecf20Sopenharmony_ci	if (dev->ts == PRIMARY_TS)
34428c2ecf20Sopenharmony_ci		usb_put_dev(udev);
34438c2ecf20Sopenharmony_ci
34448c2ecf20Sopenharmony_ci	/* Mark device as unused */
34458c2ecf20Sopenharmony_ci	clear_bit(dev->devno, em28xx_devused);
34468c2ecf20Sopenharmony_ci
34478c2ecf20Sopenharmony_ci	mutex_unlock(&dev->lock);
34488c2ecf20Sopenharmony_ci};
34498c2ecf20Sopenharmony_ci
34508c2ecf20Sopenharmony_ci/**
34518c2ecf20Sopenharmony_ci * em28xx_free_device() - Free em28xx device
34528c2ecf20Sopenharmony_ci *
34538c2ecf20Sopenharmony_ci * @ref: struct kref for em28xx device
34548c2ecf20Sopenharmony_ci *
34558c2ecf20Sopenharmony_ci * This is called when all extensions and em28xx core unregisters a device
34568c2ecf20Sopenharmony_ci */
34578c2ecf20Sopenharmony_civoid em28xx_free_device(struct kref *ref)
34588c2ecf20Sopenharmony_ci{
34598c2ecf20Sopenharmony_ci	struct em28xx *dev = kref_to_dev(ref);
34608c2ecf20Sopenharmony_ci
34618c2ecf20Sopenharmony_ci	dev_info(&dev->intf->dev, "Freeing device\n");
34628c2ecf20Sopenharmony_ci
34638c2ecf20Sopenharmony_ci	if (!dev->disconnected)
34648c2ecf20Sopenharmony_ci		em28xx_release_resources(dev);
34658c2ecf20Sopenharmony_ci
34668c2ecf20Sopenharmony_ci	if (dev->ts == PRIMARY_TS)
34678c2ecf20Sopenharmony_ci		kfree(dev->alt_max_pkt_size_isoc);
34688c2ecf20Sopenharmony_ci
34698c2ecf20Sopenharmony_ci	kfree(dev);
34708c2ecf20Sopenharmony_ci}
34718c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(em28xx_free_device);
34728c2ecf20Sopenharmony_ci
34738c2ecf20Sopenharmony_ci/*
34748c2ecf20Sopenharmony_ci * em28xx_init_dev()
34758c2ecf20Sopenharmony_ci * allocates and inits the device structs, registers i2c bus and v4l device
34768c2ecf20Sopenharmony_ci */
34778c2ecf20Sopenharmony_cistatic int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
34788c2ecf20Sopenharmony_ci			   struct usb_interface *intf,
34798c2ecf20Sopenharmony_ci			   int minor)
34808c2ecf20Sopenharmony_ci{
34818c2ecf20Sopenharmony_ci	int retval;
34828c2ecf20Sopenharmony_ci	const char *chip_name = NULL;
34838c2ecf20Sopenharmony_ci
34848c2ecf20Sopenharmony_ci	dev->intf = intf;
34858c2ecf20Sopenharmony_ci	mutex_init(&dev->ctrl_urb_lock);
34868c2ecf20Sopenharmony_ci	spin_lock_init(&dev->slock);
34878c2ecf20Sopenharmony_ci
34888c2ecf20Sopenharmony_ci	dev->em28xx_write_regs = em28xx_write_regs;
34898c2ecf20Sopenharmony_ci	dev->em28xx_read_reg = em28xx_read_reg;
34908c2ecf20Sopenharmony_ci	dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len;
34918c2ecf20Sopenharmony_ci	dev->em28xx_write_regs_req = em28xx_write_regs_req;
34928c2ecf20Sopenharmony_ci	dev->em28xx_read_reg_req = em28xx_read_reg_req;
34938c2ecf20Sopenharmony_ci	dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
34948c2ecf20Sopenharmony_ci
34958c2ecf20Sopenharmony_ci	em28xx_set_model(dev);
34968c2ecf20Sopenharmony_ci
34978c2ecf20Sopenharmony_ci	dev->wait_after_write = 5;
34988c2ecf20Sopenharmony_ci
34998c2ecf20Sopenharmony_ci	/* Based on the Chip ID, set the device configuration */
35008c2ecf20Sopenharmony_ci	retval = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
35018c2ecf20Sopenharmony_ci	if (retval > 0) {
35028c2ecf20Sopenharmony_ci		dev->chip_id = retval;
35038c2ecf20Sopenharmony_ci
35048c2ecf20Sopenharmony_ci		switch (dev->chip_id) {
35058c2ecf20Sopenharmony_ci		case CHIP_ID_EM2800:
35068c2ecf20Sopenharmony_ci			chip_name = "em2800";
35078c2ecf20Sopenharmony_ci			break;
35088c2ecf20Sopenharmony_ci		case CHIP_ID_EM2710:
35098c2ecf20Sopenharmony_ci			chip_name = "em2710";
35108c2ecf20Sopenharmony_ci			break;
35118c2ecf20Sopenharmony_ci		case CHIP_ID_EM2750:
35128c2ecf20Sopenharmony_ci			chip_name = "em2750";
35138c2ecf20Sopenharmony_ci			break;
35148c2ecf20Sopenharmony_ci		case CHIP_ID_EM2765:
35158c2ecf20Sopenharmony_ci			chip_name = "em2765";
35168c2ecf20Sopenharmony_ci			dev->wait_after_write = 0;
35178c2ecf20Sopenharmony_ci			dev->is_em25xx = 1;
35188c2ecf20Sopenharmony_ci			dev->eeprom_addrwidth_16bit = 1;
35198c2ecf20Sopenharmony_ci			break;
35208c2ecf20Sopenharmony_ci		case CHIP_ID_EM2820:
35218c2ecf20Sopenharmony_ci			chip_name = "em2710/2820";
35228c2ecf20Sopenharmony_ci			if (le16_to_cpu(udev->descriptor.idVendor) == 0xeb1a) {
35238c2ecf20Sopenharmony_ci				__le16 idProd = udev->descriptor.idProduct;
35248c2ecf20Sopenharmony_ci
35258c2ecf20Sopenharmony_ci				if (le16_to_cpu(idProd) == 0x2710)
35268c2ecf20Sopenharmony_ci					chip_name = "em2710";
35278c2ecf20Sopenharmony_ci				else if (le16_to_cpu(idProd) == 0x2820)
35288c2ecf20Sopenharmony_ci					chip_name = "em2820";
35298c2ecf20Sopenharmony_ci			}
35308c2ecf20Sopenharmony_ci			/* NOTE: the em2820 is used in webcams, too ! */
35318c2ecf20Sopenharmony_ci			break;
35328c2ecf20Sopenharmony_ci		case CHIP_ID_EM2840:
35338c2ecf20Sopenharmony_ci			chip_name = "em2840";
35348c2ecf20Sopenharmony_ci			break;
35358c2ecf20Sopenharmony_ci		case CHIP_ID_EM2860:
35368c2ecf20Sopenharmony_ci			chip_name = "em2860";
35378c2ecf20Sopenharmony_ci			break;
35388c2ecf20Sopenharmony_ci		case CHIP_ID_EM2870:
35398c2ecf20Sopenharmony_ci			chip_name = "em2870";
35408c2ecf20Sopenharmony_ci			dev->wait_after_write = 0;
35418c2ecf20Sopenharmony_ci			break;
35428c2ecf20Sopenharmony_ci		case CHIP_ID_EM2874:
35438c2ecf20Sopenharmony_ci			chip_name = "em2874";
35448c2ecf20Sopenharmony_ci			dev->wait_after_write = 0;
35458c2ecf20Sopenharmony_ci			dev->eeprom_addrwidth_16bit = 1;
35468c2ecf20Sopenharmony_ci			break;
35478c2ecf20Sopenharmony_ci		case CHIP_ID_EM28174:
35488c2ecf20Sopenharmony_ci			chip_name = "em28174";
35498c2ecf20Sopenharmony_ci			dev->wait_after_write = 0;
35508c2ecf20Sopenharmony_ci			dev->eeprom_addrwidth_16bit = 1;
35518c2ecf20Sopenharmony_ci			break;
35528c2ecf20Sopenharmony_ci		case CHIP_ID_EM28178:
35538c2ecf20Sopenharmony_ci			chip_name = "em28178";
35548c2ecf20Sopenharmony_ci			dev->wait_after_write = 0;
35558c2ecf20Sopenharmony_ci			dev->eeprom_addrwidth_16bit = 1;
35568c2ecf20Sopenharmony_ci			break;
35578c2ecf20Sopenharmony_ci		case CHIP_ID_EM2883:
35588c2ecf20Sopenharmony_ci			chip_name = "em2882/3";
35598c2ecf20Sopenharmony_ci			dev->wait_after_write = 0;
35608c2ecf20Sopenharmony_ci			break;
35618c2ecf20Sopenharmony_ci		case CHIP_ID_EM2884:
35628c2ecf20Sopenharmony_ci			chip_name = "em2884";
35638c2ecf20Sopenharmony_ci			dev->wait_after_write = 0;
35648c2ecf20Sopenharmony_ci			dev->eeprom_addrwidth_16bit = 1;
35658c2ecf20Sopenharmony_ci			break;
35668c2ecf20Sopenharmony_ci		}
35678c2ecf20Sopenharmony_ci	}
35688c2ecf20Sopenharmony_ci	if (!chip_name)
35698c2ecf20Sopenharmony_ci		dev_info(&dev->intf->dev,
35708c2ecf20Sopenharmony_ci			 "unknown em28xx chip ID (%d)\n", dev->chip_id);
35718c2ecf20Sopenharmony_ci	else
35728c2ecf20Sopenharmony_ci		dev_info(&dev->intf->dev, "chip ID is %s\n", chip_name);
35738c2ecf20Sopenharmony_ci
35748c2ecf20Sopenharmony_ci	em28xx_media_device_init(dev, udev);
35758c2ecf20Sopenharmony_ci
35768c2ecf20Sopenharmony_ci	if (dev->is_audio_only) {
35778c2ecf20Sopenharmony_ci		retval = em28xx_audio_setup(dev);
35788c2ecf20Sopenharmony_ci		if (retval) {
35798c2ecf20Sopenharmony_ci			retval = -ENODEV;
35808c2ecf20Sopenharmony_ci			goto err_deinit_media;
35818c2ecf20Sopenharmony_ci		}
35828c2ecf20Sopenharmony_ci		em28xx_init_extension(dev);
35838c2ecf20Sopenharmony_ci
35848c2ecf20Sopenharmony_ci		return 0;
35858c2ecf20Sopenharmony_ci	}
35868c2ecf20Sopenharmony_ci
35878c2ecf20Sopenharmony_ci	em28xx_pre_card_setup(dev);
35888c2ecf20Sopenharmony_ci
35898c2ecf20Sopenharmony_ci	rt_mutex_init(&dev->i2c_bus_lock);
35908c2ecf20Sopenharmony_ci
35918c2ecf20Sopenharmony_ci	/* register i2c bus 0 */
35928c2ecf20Sopenharmony_ci	if (dev->board.is_em2800)
35938c2ecf20Sopenharmony_ci		retval = em28xx_i2c_register(dev, 0, EM28XX_I2C_ALGO_EM2800);
35948c2ecf20Sopenharmony_ci	else
35958c2ecf20Sopenharmony_ci		retval = em28xx_i2c_register(dev, 0, EM28XX_I2C_ALGO_EM28XX);
35968c2ecf20Sopenharmony_ci	if (retval < 0) {
35978c2ecf20Sopenharmony_ci		dev_err(&dev->intf->dev,
35988c2ecf20Sopenharmony_ci			"%s: em28xx_i2c_register bus 0 - error [%d]!\n",
35998c2ecf20Sopenharmony_ci		       __func__, retval);
36008c2ecf20Sopenharmony_ci		goto err_deinit_media;
36018c2ecf20Sopenharmony_ci	}
36028c2ecf20Sopenharmony_ci
36038c2ecf20Sopenharmony_ci	/* register i2c bus 1 */
36048c2ecf20Sopenharmony_ci	if (dev->def_i2c_bus) {
36058c2ecf20Sopenharmony_ci		if (dev->is_em25xx)
36068c2ecf20Sopenharmony_ci			retval = em28xx_i2c_register(dev, 1,
36078c2ecf20Sopenharmony_ci						     EM28XX_I2C_ALGO_EM25XX_BUS_B);
36088c2ecf20Sopenharmony_ci		else
36098c2ecf20Sopenharmony_ci			retval = em28xx_i2c_register(dev, 1,
36108c2ecf20Sopenharmony_ci						     EM28XX_I2C_ALGO_EM28XX);
36118c2ecf20Sopenharmony_ci		if (retval < 0) {
36128c2ecf20Sopenharmony_ci			dev_err(&dev->intf->dev,
36138c2ecf20Sopenharmony_ci				"%s: em28xx_i2c_register bus 1 - error [%d]!\n",
36148c2ecf20Sopenharmony_ci				__func__, retval);
36158c2ecf20Sopenharmony_ci
36168c2ecf20Sopenharmony_ci			goto err_unreg_i2c;
36178c2ecf20Sopenharmony_ci		}
36188c2ecf20Sopenharmony_ci	}
36198c2ecf20Sopenharmony_ci
36208c2ecf20Sopenharmony_ci	/* Do board specific init and eeprom reading */
36218c2ecf20Sopenharmony_ci	em28xx_card_setup(dev);
36228c2ecf20Sopenharmony_ci
36238c2ecf20Sopenharmony_ci	return 0;
36248c2ecf20Sopenharmony_ci
36258c2ecf20Sopenharmony_cierr_unreg_i2c:
36268c2ecf20Sopenharmony_ci	em28xx_i2c_unregister(dev, 0);
36278c2ecf20Sopenharmony_cierr_deinit_media:
36288c2ecf20Sopenharmony_ci	em28xx_unregister_media_device(dev);
36298c2ecf20Sopenharmony_ci	return retval;
36308c2ecf20Sopenharmony_ci}
36318c2ecf20Sopenharmony_ci
36328c2ecf20Sopenharmony_cistatic int em28xx_duplicate_dev(struct em28xx *dev)
36338c2ecf20Sopenharmony_ci{
36348c2ecf20Sopenharmony_ci	int nr;
36358c2ecf20Sopenharmony_ci	struct em28xx *sec_dev = kmemdup(dev, sizeof(*sec_dev), GFP_KERNEL);
36368c2ecf20Sopenharmony_ci
36378c2ecf20Sopenharmony_ci	if (!sec_dev) {
36388c2ecf20Sopenharmony_ci		dev->dev_next = NULL;
36398c2ecf20Sopenharmony_ci		return -ENOMEM;
36408c2ecf20Sopenharmony_ci	}
36418c2ecf20Sopenharmony_ci	/* Check to see next free device and mark as used */
36428c2ecf20Sopenharmony_ci	do {
36438c2ecf20Sopenharmony_ci		nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS);
36448c2ecf20Sopenharmony_ci		if (nr >= EM28XX_MAXBOARDS) {
36458c2ecf20Sopenharmony_ci			/* No free device slots */
36468c2ecf20Sopenharmony_ci			dev_warn(&dev->intf->dev, ": Supports only %i em28xx boards.\n",
36478c2ecf20Sopenharmony_ci				 EM28XX_MAXBOARDS);
36488c2ecf20Sopenharmony_ci			kfree(sec_dev);
36498c2ecf20Sopenharmony_ci			dev->dev_next = NULL;
36508c2ecf20Sopenharmony_ci			return -ENOMEM;
36518c2ecf20Sopenharmony_ci		}
36528c2ecf20Sopenharmony_ci	} while (test_and_set_bit(nr, em28xx_devused));
36538c2ecf20Sopenharmony_ci	sec_dev->devno = nr;
36548c2ecf20Sopenharmony_ci	snprintf(sec_dev->name, 28, "em28xx #%d", nr);
36558c2ecf20Sopenharmony_ci	sec_dev->dev_next = NULL;
36568c2ecf20Sopenharmony_ci	dev->dev_next = sec_dev;
36578c2ecf20Sopenharmony_ci	return 0;
36588c2ecf20Sopenharmony_ci}
36598c2ecf20Sopenharmony_ci
36608c2ecf20Sopenharmony_ci/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
36618c2ecf20Sopenharmony_ci#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
36628c2ecf20Sopenharmony_ci
36638c2ecf20Sopenharmony_cistatic void em28xx_check_usb_descriptor(struct em28xx *dev,
36648c2ecf20Sopenharmony_ci					struct usb_device *udev,
36658c2ecf20Sopenharmony_ci					struct usb_interface *intf,
36668c2ecf20Sopenharmony_ci					int alt, int ep,
36678c2ecf20Sopenharmony_ci					bool *has_vendor_audio,
36688c2ecf20Sopenharmony_ci					bool *has_video,
36698c2ecf20Sopenharmony_ci					bool *has_dvb)
36708c2ecf20Sopenharmony_ci{
36718c2ecf20Sopenharmony_ci	const struct usb_endpoint_descriptor *e;
36728c2ecf20Sopenharmony_ci	int sizedescr, size;
36738c2ecf20Sopenharmony_ci
36748c2ecf20Sopenharmony_ci	/*
36758c2ecf20Sopenharmony_ci	 * NOTE:
36768c2ecf20Sopenharmony_ci	 *
36778c2ecf20Sopenharmony_ci	 * Old logic with support for isoc transfers only was:
36788c2ecf20Sopenharmony_ci	 *  0x82	isoc		=> analog
36798c2ecf20Sopenharmony_ci	 *  0x83	isoc		=> audio
36808c2ecf20Sopenharmony_ci	 *  0x84	isoc		=> digital
36818c2ecf20Sopenharmony_ci	 *
36828c2ecf20Sopenharmony_ci	 * New logic with support for bulk transfers
36838c2ecf20Sopenharmony_ci	 *  0x82	isoc		=> analog
36848c2ecf20Sopenharmony_ci	 *  0x82	bulk		=> analog
36858c2ecf20Sopenharmony_ci	 *  0x83	isoc*		=> audio
36868c2ecf20Sopenharmony_ci	 *  0x84	isoc		=> digital
36878c2ecf20Sopenharmony_ci	 *  0x84	bulk		=> analog or digital**
36888c2ecf20Sopenharmony_ci	 *  0x85	isoc		=> digital TS2
36898c2ecf20Sopenharmony_ci	 *  0x85	bulk		=> digital TS2
36908c2ecf20Sopenharmony_ci	 * (*: audio should always be isoc)
36918c2ecf20Sopenharmony_ci	 * (**: analog, if ep 0x82 is isoc, otherwise digital)
36928c2ecf20Sopenharmony_ci	 *
36938c2ecf20Sopenharmony_ci	 * The new logic preserves backwards compatibility and
36948c2ecf20Sopenharmony_ci	 * reflects the endpoint configurations we have seen
36958c2ecf20Sopenharmony_ci	 * so far. But there might be devices for which this
36968c2ecf20Sopenharmony_ci	 * logic is not sufficient...
36978c2ecf20Sopenharmony_ci	 */
36988c2ecf20Sopenharmony_ci
36998c2ecf20Sopenharmony_ci	e = &intf->altsetting[alt].endpoint[ep].desc;
37008c2ecf20Sopenharmony_ci
37018c2ecf20Sopenharmony_ci	if (!usb_endpoint_dir_in(e))
37028c2ecf20Sopenharmony_ci		return;
37038c2ecf20Sopenharmony_ci
37048c2ecf20Sopenharmony_ci	sizedescr = le16_to_cpu(e->wMaxPacketSize);
37058c2ecf20Sopenharmony_ci	size = sizedescr & 0x7ff;
37068c2ecf20Sopenharmony_ci
37078c2ecf20Sopenharmony_ci	if (udev->speed == USB_SPEED_HIGH)
37088c2ecf20Sopenharmony_ci		size = size * hb_mult(sizedescr);
37098c2ecf20Sopenharmony_ci
37108c2ecf20Sopenharmony_ci	/* Only inspect input endpoints */
37118c2ecf20Sopenharmony_ci
37128c2ecf20Sopenharmony_ci	switch (e->bEndpointAddress) {
37138c2ecf20Sopenharmony_ci	case 0x82:
37148c2ecf20Sopenharmony_ci		*has_video = true;
37158c2ecf20Sopenharmony_ci		if (usb_endpoint_xfer_isoc(e)) {
37168c2ecf20Sopenharmony_ci			dev->analog_ep_isoc = e->bEndpointAddress;
37178c2ecf20Sopenharmony_ci			dev->alt_max_pkt_size_isoc[alt] = size;
37188c2ecf20Sopenharmony_ci		} else if (usb_endpoint_xfer_bulk(e)) {
37198c2ecf20Sopenharmony_ci			dev->analog_ep_bulk = e->bEndpointAddress;
37208c2ecf20Sopenharmony_ci		}
37218c2ecf20Sopenharmony_ci		return;
37228c2ecf20Sopenharmony_ci	case 0x83:
37238c2ecf20Sopenharmony_ci		if (usb_endpoint_xfer_isoc(e))
37248c2ecf20Sopenharmony_ci			*has_vendor_audio = true;
37258c2ecf20Sopenharmony_ci		else
37268c2ecf20Sopenharmony_ci			dev_err(&intf->dev,
37278c2ecf20Sopenharmony_ci				"error: skipping audio endpoint 0x83, because it uses bulk transfers !\n");
37288c2ecf20Sopenharmony_ci		return;
37298c2ecf20Sopenharmony_ci	case 0x84:
37308c2ecf20Sopenharmony_ci		if (*has_video && (usb_endpoint_xfer_bulk(e))) {
37318c2ecf20Sopenharmony_ci			dev->analog_ep_bulk = e->bEndpointAddress;
37328c2ecf20Sopenharmony_ci		} else {
37338c2ecf20Sopenharmony_ci			if (usb_endpoint_xfer_isoc(e)) {
37348c2ecf20Sopenharmony_ci				if (size > dev->dvb_max_pkt_size_isoc) {
37358c2ecf20Sopenharmony_ci					/*
37368c2ecf20Sopenharmony_ci					 * 2) some manufacturers (e.g. Terratec)
37378c2ecf20Sopenharmony_ci					 * disable endpoints by setting
37388c2ecf20Sopenharmony_ci					 * wMaxPacketSize to 0 bytes for all
37398c2ecf20Sopenharmony_ci					 * alt settings. So far, we've seen
37408c2ecf20Sopenharmony_ci					 * this for DVB isoc endpoints only.
37418c2ecf20Sopenharmony_ci					 */
37428c2ecf20Sopenharmony_ci					*has_dvb = true;
37438c2ecf20Sopenharmony_ci					dev->dvb_ep_isoc = e->bEndpointAddress;
37448c2ecf20Sopenharmony_ci					dev->dvb_max_pkt_size_isoc = size;
37458c2ecf20Sopenharmony_ci					dev->dvb_alt_isoc = alt;
37468c2ecf20Sopenharmony_ci				}
37478c2ecf20Sopenharmony_ci			} else {
37488c2ecf20Sopenharmony_ci				*has_dvb = true;
37498c2ecf20Sopenharmony_ci				dev->dvb_ep_bulk = e->bEndpointAddress;
37508c2ecf20Sopenharmony_ci			}
37518c2ecf20Sopenharmony_ci		}
37528c2ecf20Sopenharmony_ci		return;
37538c2ecf20Sopenharmony_ci	case 0x85:
37548c2ecf20Sopenharmony_ci		if (usb_endpoint_xfer_isoc(e)) {
37558c2ecf20Sopenharmony_ci			if (size > dev->dvb_max_pkt_size_isoc_ts2) {
37568c2ecf20Sopenharmony_ci				dev->dvb_ep_isoc_ts2 = e->bEndpointAddress;
37578c2ecf20Sopenharmony_ci				dev->dvb_max_pkt_size_isoc_ts2 = size;
37588c2ecf20Sopenharmony_ci				dev->dvb_alt_isoc = alt;
37598c2ecf20Sopenharmony_ci			}
37608c2ecf20Sopenharmony_ci		} else {
37618c2ecf20Sopenharmony_ci			dev->dvb_ep_bulk_ts2 = e->bEndpointAddress;
37628c2ecf20Sopenharmony_ci		}
37638c2ecf20Sopenharmony_ci		return;
37648c2ecf20Sopenharmony_ci	}
37658c2ecf20Sopenharmony_ci}
37668c2ecf20Sopenharmony_ci
37678c2ecf20Sopenharmony_ci/*
37688c2ecf20Sopenharmony_ci * em28xx_usb_probe()
37698c2ecf20Sopenharmony_ci * checks for supported devices
37708c2ecf20Sopenharmony_ci */
37718c2ecf20Sopenharmony_cistatic int em28xx_usb_probe(struct usb_interface *intf,
37728c2ecf20Sopenharmony_ci			    const struct usb_device_id *id)
37738c2ecf20Sopenharmony_ci{
37748c2ecf20Sopenharmony_ci	struct usb_device *udev;
37758c2ecf20Sopenharmony_ci	struct em28xx *dev = NULL;
37768c2ecf20Sopenharmony_ci	int retval;
37778c2ecf20Sopenharmony_ci	bool has_vendor_audio = false, has_video = false, has_dvb = false;
37788c2ecf20Sopenharmony_ci	int i, nr, try_bulk;
37798c2ecf20Sopenharmony_ci	const int ifnum = intf->altsetting[0].desc.bInterfaceNumber;
37808c2ecf20Sopenharmony_ci	char *speed;
37818c2ecf20Sopenharmony_ci
37828c2ecf20Sopenharmony_ci	udev = usb_get_dev(interface_to_usbdev(intf));
37838c2ecf20Sopenharmony_ci
37848c2ecf20Sopenharmony_ci	/* Check to see next free device and mark as used */
37858c2ecf20Sopenharmony_ci	do {
37868c2ecf20Sopenharmony_ci		nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS);
37878c2ecf20Sopenharmony_ci		if (nr >= EM28XX_MAXBOARDS) {
37888c2ecf20Sopenharmony_ci			/* No free device slots */
37898c2ecf20Sopenharmony_ci			dev_err(&intf->dev,
37908c2ecf20Sopenharmony_ci				"Driver supports up to %i em28xx boards.\n",
37918c2ecf20Sopenharmony_ci			       EM28XX_MAXBOARDS);
37928c2ecf20Sopenharmony_ci			retval = -ENOMEM;
37938c2ecf20Sopenharmony_ci			goto err_no_slot;
37948c2ecf20Sopenharmony_ci		}
37958c2ecf20Sopenharmony_ci	} while (test_and_set_bit(nr, em28xx_devused));
37968c2ecf20Sopenharmony_ci
37978c2ecf20Sopenharmony_ci	/* Don't register audio interfaces */
37988c2ecf20Sopenharmony_ci	if (intf->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
37998c2ecf20Sopenharmony_ci		dev_info(&intf->dev,
38008c2ecf20Sopenharmony_ci			"audio device (%04x:%04x): interface %i, class %i\n",
38018c2ecf20Sopenharmony_ci			le16_to_cpu(udev->descriptor.idVendor),
38028c2ecf20Sopenharmony_ci			le16_to_cpu(udev->descriptor.idProduct),
38038c2ecf20Sopenharmony_ci			ifnum,
38048c2ecf20Sopenharmony_ci			intf->altsetting[0].desc.bInterfaceClass);
38058c2ecf20Sopenharmony_ci
38068c2ecf20Sopenharmony_ci		retval = -ENODEV;
38078c2ecf20Sopenharmony_ci		goto err;
38088c2ecf20Sopenharmony_ci	}
38098c2ecf20Sopenharmony_ci
38108c2ecf20Sopenharmony_ci	/* allocate memory for our device state and initialize it */
38118c2ecf20Sopenharmony_ci	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
38128c2ecf20Sopenharmony_ci	if (!dev) {
38138c2ecf20Sopenharmony_ci		retval = -ENOMEM;
38148c2ecf20Sopenharmony_ci		goto err;
38158c2ecf20Sopenharmony_ci	}
38168c2ecf20Sopenharmony_ci
38178c2ecf20Sopenharmony_ci	/* compute alternate max packet sizes */
38188c2ecf20Sopenharmony_ci	dev->alt_max_pkt_size_isoc = kcalloc(intf->num_altsetting,
38198c2ecf20Sopenharmony_ci					     sizeof(dev->alt_max_pkt_size_isoc[0]),
38208c2ecf20Sopenharmony_ci					     GFP_KERNEL);
38218c2ecf20Sopenharmony_ci	if (!dev->alt_max_pkt_size_isoc) {
38228c2ecf20Sopenharmony_ci		kfree(dev);
38238c2ecf20Sopenharmony_ci		retval = -ENOMEM;
38248c2ecf20Sopenharmony_ci		goto err;
38258c2ecf20Sopenharmony_ci	}
38268c2ecf20Sopenharmony_ci
38278c2ecf20Sopenharmony_ci	/* Get endpoints */
38288c2ecf20Sopenharmony_ci	for (i = 0; i < intf->num_altsetting; i++) {
38298c2ecf20Sopenharmony_ci		int ep;
38308c2ecf20Sopenharmony_ci
38318c2ecf20Sopenharmony_ci		for (ep = 0;
38328c2ecf20Sopenharmony_ci		     ep < intf->altsetting[i].desc.bNumEndpoints;
38338c2ecf20Sopenharmony_ci		     ep++)
38348c2ecf20Sopenharmony_ci			em28xx_check_usb_descriptor(dev, udev, intf,
38358c2ecf20Sopenharmony_ci						    i, ep,
38368c2ecf20Sopenharmony_ci						    &has_vendor_audio,
38378c2ecf20Sopenharmony_ci						    &has_video,
38388c2ecf20Sopenharmony_ci						    &has_dvb);
38398c2ecf20Sopenharmony_ci	}
38408c2ecf20Sopenharmony_ci
38418c2ecf20Sopenharmony_ci	if (!(has_vendor_audio || has_video || has_dvb)) {
38428c2ecf20Sopenharmony_ci		retval = -ENODEV;
38438c2ecf20Sopenharmony_ci		goto err_free;
38448c2ecf20Sopenharmony_ci	}
38458c2ecf20Sopenharmony_ci
38468c2ecf20Sopenharmony_ci	switch (udev->speed) {
38478c2ecf20Sopenharmony_ci	case USB_SPEED_LOW:
38488c2ecf20Sopenharmony_ci		speed = "1.5";
38498c2ecf20Sopenharmony_ci		break;
38508c2ecf20Sopenharmony_ci	case USB_SPEED_UNKNOWN:
38518c2ecf20Sopenharmony_ci	case USB_SPEED_FULL:
38528c2ecf20Sopenharmony_ci		speed = "12";
38538c2ecf20Sopenharmony_ci		break;
38548c2ecf20Sopenharmony_ci	case USB_SPEED_HIGH:
38558c2ecf20Sopenharmony_ci		speed = "480";
38568c2ecf20Sopenharmony_ci		break;
38578c2ecf20Sopenharmony_ci	default:
38588c2ecf20Sopenharmony_ci		speed = "unknown";
38598c2ecf20Sopenharmony_ci	}
38608c2ecf20Sopenharmony_ci
38618c2ecf20Sopenharmony_ci	dev_info(&intf->dev,
38628c2ecf20Sopenharmony_ci		"New device %s %s @ %s Mbps (%04x:%04x, interface %d, class %d)\n",
38638c2ecf20Sopenharmony_ci		udev->manufacturer ? udev->manufacturer : "",
38648c2ecf20Sopenharmony_ci		udev->product ? udev->product : "",
38658c2ecf20Sopenharmony_ci		speed,
38668c2ecf20Sopenharmony_ci		le16_to_cpu(udev->descriptor.idVendor),
38678c2ecf20Sopenharmony_ci		le16_to_cpu(udev->descriptor.idProduct),
38688c2ecf20Sopenharmony_ci		ifnum,
38698c2ecf20Sopenharmony_ci		intf->altsetting->desc.bInterfaceNumber);
38708c2ecf20Sopenharmony_ci
38718c2ecf20Sopenharmony_ci	/*
38728c2ecf20Sopenharmony_ci	 * Make sure we have 480 Mbps of bandwidth, otherwise things like
38738c2ecf20Sopenharmony_ci	 * video stream wouldn't likely work, since 12 Mbps is generally
38748c2ecf20Sopenharmony_ci	 * not enough even for most Digital TV streams.
38758c2ecf20Sopenharmony_ci	 */
38768c2ecf20Sopenharmony_ci	if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) {
38778c2ecf20Sopenharmony_ci		dev_err(&intf->dev, "Device initialization failed.\n");
38788c2ecf20Sopenharmony_ci		dev_err(&intf->dev,
38798c2ecf20Sopenharmony_ci			"Device must be connected to a high-speed USB 2.0 port.\n");
38808c2ecf20Sopenharmony_ci		retval = -ENODEV;
38818c2ecf20Sopenharmony_ci		goto err_free;
38828c2ecf20Sopenharmony_ci	}
38838c2ecf20Sopenharmony_ci
38848c2ecf20Sopenharmony_ci	kref_init(&dev->ref);
38858c2ecf20Sopenharmony_ci
38868c2ecf20Sopenharmony_ci	dev->devno = nr;
38878c2ecf20Sopenharmony_ci	dev->model = id->driver_info;
38888c2ecf20Sopenharmony_ci	dev->alt   = -1;
38898c2ecf20Sopenharmony_ci	dev->is_audio_only = has_vendor_audio && !(has_video || has_dvb);
38908c2ecf20Sopenharmony_ci	dev->has_video = has_video;
38918c2ecf20Sopenharmony_ci	dev->ifnum = ifnum;
38928c2ecf20Sopenharmony_ci
38938c2ecf20Sopenharmony_ci	dev->ts = PRIMARY_TS;
38948c2ecf20Sopenharmony_ci	snprintf(dev->name, 28, "em28xx");
38958c2ecf20Sopenharmony_ci	dev->dev_next = NULL;
38968c2ecf20Sopenharmony_ci
38978c2ecf20Sopenharmony_ci	if (has_vendor_audio) {
38988c2ecf20Sopenharmony_ci		dev_info(&intf->dev,
38998c2ecf20Sopenharmony_ci			"Audio interface %i found (Vendor Class)\n", ifnum);
39008c2ecf20Sopenharmony_ci		dev->usb_audio_type = EM28XX_USB_AUDIO_VENDOR;
39018c2ecf20Sopenharmony_ci	}
39028c2ecf20Sopenharmony_ci	/* Checks if audio is provided by a USB Audio Class intf */
39038c2ecf20Sopenharmony_ci	for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
39048c2ecf20Sopenharmony_ci		struct usb_interface *uif = udev->config->interface[i];
39058c2ecf20Sopenharmony_ci
39068c2ecf20Sopenharmony_ci		if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
39078c2ecf20Sopenharmony_ci			if (has_vendor_audio)
39088c2ecf20Sopenharmony_ci				dev_err(&intf->dev,
39098c2ecf20Sopenharmony_ci					"em28xx: device seems to have vendor AND usb audio class interfaces !\n"
39108c2ecf20Sopenharmony_ci					"\t\tThe vendor interface will be ignored. Please contact the developers <linux-media@vger.kernel.org>\n");
39118c2ecf20Sopenharmony_ci			dev->usb_audio_type = EM28XX_USB_AUDIO_CLASS;
39128c2ecf20Sopenharmony_ci			break;
39138c2ecf20Sopenharmony_ci		}
39148c2ecf20Sopenharmony_ci	}
39158c2ecf20Sopenharmony_ci
39168c2ecf20Sopenharmony_ci	if (has_video)
39178c2ecf20Sopenharmony_ci		dev_info(&intf->dev, "Video interface %i found:%s%s\n",
39188c2ecf20Sopenharmony_ci			ifnum,
39198c2ecf20Sopenharmony_ci			dev->analog_ep_bulk ? " bulk" : "",
39208c2ecf20Sopenharmony_ci			dev->analog_ep_isoc ? " isoc" : "");
39218c2ecf20Sopenharmony_ci	if (has_dvb)
39228c2ecf20Sopenharmony_ci		dev_info(&intf->dev, "DVB interface %i found:%s%s\n",
39238c2ecf20Sopenharmony_ci			ifnum,
39248c2ecf20Sopenharmony_ci			dev->dvb_ep_bulk ? " bulk" : "",
39258c2ecf20Sopenharmony_ci			dev->dvb_ep_isoc ? " isoc" : "");
39268c2ecf20Sopenharmony_ci
39278c2ecf20Sopenharmony_ci	dev->num_alt = intf->num_altsetting;
39288c2ecf20Sopenharmony_ci
39298c2ecf20Sopenharmony_ci	if ((unsigned int)card[nr] < em28xx_bcount)
39308c2ecf20Sopenharmony_ci		dev->model = card[nr];
39318c2ecf20Sopenharmony_ci
39328c2ecf20Sopenharmony_ci	/* save our data pointer in this intf device */
39338c2ecf20Sopenharmony_ci	usb_set_intfdata(intf, dev);
39348c2ecf20Sopenharmony_ci
39358c2ecf20Sopenharmony_ci	/* allocate device struct and check if the device is a webcam */
39368c2ecf20Sopenharmony_ci	mutex_init(&dev->lock);
39378c2ecf20Sopenharmony_ci	retval = em28xx_init_dev(dev, udev, intf, nr);
39388c2ecf20Sopenharmony_ci	if (retval)
39398c2ecf20Sopenharmony_ci		goto err_free;
39408c2ecf20Sopenharmony_ci
39418c2ecf20Sopenharmony_ci	if (usb_xfer_mode < 0) {
39428c2ecf20Sopenharmony_ci		if (dev->is_webcam)
39438c2ecf20Sopenharmony_ci			try_bulk = 1;
39448c2ecf20Sopenharmony_ci		else
39458c2ecf20Sopenharmony_ci			try_bulk = 0;
39468c2ecf20Sopenharmony_ci	} else {
39478c2ecf20Sopenharmony_ci		try_bulk = usb_xfer_mode > 0;
39488c2ecf20Sopenharmony_ci	}
39498c2ecf20Sopenharmony_ci
39508c2ecf20Sopenharmony_ci	/* Disable V4L2 if the device doesn't have a decoder or image sensor */
39518c2ecf20Sopenharmony_ci	if (has_video &&
39528c2ecf20Sopenharmony_ci	    dev->board.decoder == EM28XX_NODECODER &&
39538c2ecf20Sopenharmony_ci	    dev->em28xx_sensor == EM28XX_NOSENSOR) {
39548c2ecf20Sopenharmony_ci		dev_err(&intf->dev,
39558c2ecf20Sopenharmony_ci			"Currently, V4L2 is not supported on this model\n");
39568c2ecf20Sopenharmony_ci		has_video = false;
39578c2ecf20Sopenharmony_ci		dev->has_video = false;
39588c2ecf20Sopenharmony_ci	}
39598c2ecf20Sopenharmony_ci
39608c2ecf20Sopenharmony_ci	if (dev->board.has_dual_ts &&
39618c2ecf20Sopenharmony_ci	    (dev->tuner_type != TUNER_ABSENT || INPUT(0)->type)) {
39628c2ecf20Sopenharmony_ci		/*
39638c2ecf20Sopenharmony_ci		 * The logic with sets alternate is not ready for dual-tuners
39648c2ecf20Sopenharmony_ci		 * which analog modes.
39658c2ecf20Sopenharmony_ci		 */
39668c2ecf20Sopenharmony_ci		dev_err(&intf->dev,
39678c2ecf20Sopenharmony_ci			"We currently don't support analog TV or stream capture on dual tuners.\n");
39688c2ecf20Sopenharmony_ci		has_video = false;
39698c2ecf20Sopenharmony_ci	}
39708c2ecf20Sopenharmony_ci
39718c2ecf20Sopenharmony_ci	/* Select USB transfer types to use */
39728c2ecf20Sopenharmony_ci	if (has_video) {
39738c2ecf20Sopenharmony_ci		if (!dev->analog_ep_isoc || (try_bulk && dev->analog_ep_bulk))
39748c2ecf20Sopenharmony_ci			dev->analog_xfer_bulk = 1;
39758c2ecf20Sopenharmony_ci		dev_info(&intf->dev, "analog set to %s mode.\n",
39768c2ecf20Sopenharmony_ci			dev->analog_xfer_bulk ? "bulk" : "isoc");
39778c2ecf20Sopenharmony_ci	}
39788c2ecf20Sopenharmony_ci	if (has_dvb) {
39798c2ecf20Sopenharmony_ci		if (!dev->dvb_ep_isoc || (try_bulk && dev->dvb_ep_bulk))
39808c2ecf20Sopenharmony_ci			dev->dvb_xfer_bulk = 1;
39818c2ecf20Sopenharmony_ci		dev_info(&intf->dev, "dvb set to %s mode.\n",
39828c2ecf20Sopenharmony_ci			dev->dvb_xfer_bulk ? "bulk" : "isoc");
39838c2ecf20Sopenharmony_ci	}
39848c2ecf20Sopenharmony_ci
39858c2ecf20Sopenharmony_ci	if (dev->board.has_dual_ts && em28xx_duplicate_dev(dev) == 0) {
39868c2ecf20Sopenharmony_ci		kref_init(&dev->dev_next->ref);
39878c2ecf20Sopenharmony_ci
39888c2ecf20Sopenharmony_ci		dev->dev_next->ts = SECONDARY_TS;
39898c2ecf20Sopenharmony_ci		dev->dev_next->alt   = -1;
39908c2ecf20Sopenharmony_ci		dev->dev_next->is_audio_only = has_vendor_audio &&
39918c2ecf20Sopenharmony_ci						!(has_video || has_dvb);
39928c2ecf20Sopenharmony_ci		dev->dev_next->has_video = false;
39938c2ecf20Sopenharmony_ci		dev->dev_next->ifnum = ifnum;
39948c2ecf20Sopenharmony_ci		dev->dev_next->model = id->driver_info;
39958c2ecf20Sopenharmony_ci
39968c2ecf20Sopenharmony_ci		mutex_init(&dev->dev_next->lock);
39978c2ecf20Sopenharmony_ci		retval = em28xx_init_dev(dev->dev_next, udev, intf,
39988c2ecf20Sopenharmony_ci					 dev->dev_next->devno);
39998c2ecf20Sopenharmony_ci		if (retval)
40008c2ecf20Sopenharmony_ci			goto err_free;
40018c2ecf20Sopenharmony_ci
40028c2ecf20Sopenharmony_ci		dev->dev_next->board.ir_codes = NULL; /* No IR for 2nd tuner */
40038c2ecf20Sopenharmony_ci		dev->dev_next->board.has_ir_i2c = 0; /* No IR for 2nd tuner */
40048c2ecf20Sopenharmony_ci
40058c2ecf20Sopenharmony_ci		if (usb_xfer_mode < 0) {
40068c2ecf20Sopenharmony_ci			if (dev->dev_next->is_webcam)
40078c2ecf20Sopenharmony_ci				try_bulk = 1;
40088c2ecf20Sopenharmony_ci			else
40098c2ecf20Sopenharmony_ci				try_bulk = 0;
40108c2ecf20Sopenharmony_ci		} else {
40118c2ecf20Sopenharmony_ci			try_bulk = usb_xfer_mode > 0;
40128c2ecf20Sopenharmony_ci		}
40138c2ecf20Sopenharmony_ci
40148c2ecf20Sopenharmony_ci		/* Select USB transfer types to use */
40158c2ecf20Sopenharmony_ci		if (has_dvb) {
40168c2ecf20Sopenharmony_ci			if (!dev->dvb_ep_isoc_ts2 ||
40178c2ecf20Sopenharmony_ci			    (try_bulk && dev->dvb_ep_bulk_ts2))
40188c2ecf20Sopenharmony_ci				dev->dev_next->dvb_xfer_bulk = 1;
40198c2ecf20Sopenharmony_ci			dev_info(&dev->intf->dev, "dvb ts2 set to %s mode.\n",
40208c2ecf20Sopenharmony_ci				 dev->dev_next->dvb_xfer_bulk ? "bulk" : "isoc");
40218c2ecf20Sopenharmony_ci		}
40228c2ecf20Sopenharmony_ci
40238c2ecf20Sopenharmony_ci		dev->dev_next->dvb_ep_isoc = dev->dvb_ep_isoc_ts2;
40248c2ecf20Sopenharmony_ci		dev->dev_next->dvb_ep_bulk = dev->dvb_ep_bulk_ts2;
40258c2ecf20Sopenharmony_ci		dev->dev_next->dvb_max_pkt_size_isoc = dev->dvb_max_pkt_size_isoc_ts2;
40268c2ecf20Sopenharmony_ci		dev->dev_next->dvb_alt_isoc = dev->dvb_alt_isoc;
40278c2ecf20Sopenharmony_ci
40288c2ecf20Sopenharmony_ci		/* Configuare hardware to support TS2*/
40298c2ecf20Sopenharmony_ci		if (dev->dvb_xfer_bulk) {
40308c2ecf20Sopenharmony_ci			/* The ep4 and ep5 are configuared for BULK */
40318c2ecf20Sopenharmony_ci			em28xx_write_reg(dev, 0x0b, 0x96);
40328c2ecf20Sopenharmony_ci			mdelay(100);
40338c2ecf20Sopenharmony_ci			em28xx_write_reg(dev, 0x0b, 0x80);
40348c2ecf20Sopenharmony_ci			mdelay(100);
40358c2ecf20Sopenharmony_ci		} else {
40368c2ecf20Sopenharmony_ci			/* The ep4 and ep5 are configuared for ISO */
40378c2ecf20Sopenharmony_ci			em28xx_write_reg(dev, 0x0b, 0x96);
40388c2ecf20Sopenharmony_ci			mdelay(100);
40398c2ecf20Sopenharmony_ci			em28xx_write_reg(dev, 0x0b, 0x82);
40408c2ecf20Sopenharmony_ci			mdelay(100);
40418c2ecf20Sopenharmony_ci		}
40428c2ecf20Sopenharmony_ci	}
40438c2ecf20Sopenharmony_ci
40448c2ecf20Sopenharmony_ci	request_modules(dev);
40458c2ecf20Sopenharmony_ci
40468c2ecf20Sopenharmony_ci	/*
40478c2ecf20Sopenharmony_ci	 * Do it at the end, to reduce dynamic configuration changes during
40488c2ecf20Sopenharmony_ci	 * the device init. Yet, as request_modules() can be async, the
40498c2ecf20Sopenharmony_ci	 * topology will likely change after the load of the em28xx subdrivers.
40508c2ecf20Sopenharmony_ci	 */
40518c2ecf20Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER
40528c2ecf20Sopenharmony_ci	retval = media_device_register(dev->media_dev);
40538c2ecf20Sopenharmony_ci#endif
40548c2ecf20Sopenharmony_ci
40558c2ecf20Sopenharmony_ci	return 0;
40568c2ecf20Sopenharmony_ci
40578c2ecf20Sopenharmony_cierr_free:
40588c2ecf20Sopenharmony_ci	kfree(dev->alt_max_pkt_size_isoc);
40598c2ecf20Sopenharmony_ci	kfree(dev);
40608c2ecf20Sopenharmony_ci
40618c2ecf20Sopenharmony_cierr:
40628c2ecf20Sopenharmony_ci	clear_bit(nr, em28xx_devused);
40638c2ecf20Sopenharmony_ci
40648c2ecf20Sopenharmony_cierr_no_slot:
40658c2ecf20Sopenharmony_ci	usb_put_dev(udev);
40668c2ecf20Sopenharmony_ci	return retval;
40678c2ecf20Sopenharmony_ci}
40688c2ecf20Sopenharmony_ci
40698c2ecf20Sopenharmony_ci/*
40708c2ecf20Sopenharmony_ci * em28xx_usb_disconnect()
40718c2ecf20Sopenharmony_ci * called when the device gets disconnected
40728c2ecf20Sopenharmony_ci * video device will be unregistered on v4l2_close in case it is still open
40738c2ecf20Sopenharmony_ci */
40748c2ecf20Sopenharmony_cistatic void em28xx_usb_disconnect(struct usb_interface *intf)
40758c2ecf20Sopenharmony_ci{
40768c2ecf20Sopenharmony_ci	struct em28xx *dev;
40778c2ecf20Sopenharmony_ci
40788c2ecf20Sopenharmony_ci	dev = usb_get_intfdata(intf);
40798c2ecf20Sopenharmony_ci	usb_set_intfdata(intf, NULL);
40808c2ecf20Sopenharmony_ci
40818c2ecf20Sopenharmony_ci	if (!dev)
40828c2ecf20Sopenharmony_ci		return;
40838c2ecf20Sopenharmony_ci
40848c2ecf20Sopenharmony_ci	if (dev->dev_next) {
40858c2ecf20Sopenharmony_ci		dev->dev_next->disconnected = 1;
40868c2ecf20Sopenharmony_ci		dev_info(&dev->intf->dev, "Disconnecting %s\n",
40878c2ecf20Sopenharmony_ci			 dev->dev_next->name);
40888c2ecf20Sopenharmony_ci	}
40898c2ecf20Sopenharmony_ci
40908c2ecf20Sopenharmony_ci	dev->disconnected = 1;
40918c2ecf20Sopenharmony_ci
40928c2ecf20Sopenharmony_ci	dev_info(&dev->intf->dev, "Disconnecting %s\n", dev->name);
40938c2ecf20Sopenharmony_ci
40948c2ecf20Sopenharmony_ci	flush_request_modules(dev);
40958c2ecf20Sopenharmony_ci
40968c2ecf20Sopenharmony_ci	em28xx_close_extension(dev);
40978c2ecf20Sopenharmony_ci
40988c2ecf20Sopenharmony_ci	if (dev->dev_next)
40998c2ecf20Sopenharmony_ci		em28xx_release_resources(dev->dev_next);
41008c2ecf20Sopenharmony_ci	em28xx_release_resources(dev);
41018c2ecf20Sopenharmony_ci
41028c2ecf20Sopenharmony_ci	if (dev->dev_next) {
41038c2ecf20Sopenharmony_ci		kref_put(&dev->dev_next->ref, em28xx_free_device);
41048c2ecf20Sopenharmony_ci		dev->dev_next = NULL;
41058c2ecf20Sopenharmony_ci	}
41068c2ecf20Sopenharmony_ci	kref_put(&dev->ref, em28xx_free_device);
41078c2ecf20Sopenharmony_ci}
41088c2ecf20Sopenharmony_ci
41098c2ecf20Sopenharmony_cistatic int em28xx_usb_suspend(struct usb_interface *intf,
41108c2ecf20Sopenharmony_ci			      pm_message_t message)
41118c2ecf20Sopenharmony_ci{
41128c2ecf20Sopenharmony_ci	struct em28xx *dev;
41138c2ecf20Sopenharmony_ci
41148c2ecf20Sopenharmony_ci	dev = usb_get_intfdata(intf);
41158c2ecf20Sopenharmony_ci	if (!dev)
41168c2ecf20Sopenharmony_ci		return 0;
41178c2ecf20Sopenharmony_ci	em28xx_suspend_extension(dev);
41188c2ecf20Sopenharmony_ci	return 0;
41198c2ecf20Sopenharmony_ci}
41208c2ecf20Sopenharmony_ci
41218c2ecf20Sopenharmony_cistatic int em28xx_usb_resume(struct usb_interface *intf)
41228c2ecf20Sopenharmony_ci{
41238c2ecf20Sopenharmony_ci	struct em28xx *dev;
41248c2ecf20Sopenharmony_ci
41258c2ecf20Sopenharmony_ci	dev = usb_get_intfdata(intf);
41268c2ecf20Sopenharmony_ci	if (!dev)
41278c2ecf20Sopenharmony_ci		return 0;
41288c2ecf20Sopenharmony_ci	em28xx_resume_extension(dev);
41298c2ecf20Sopenharmony_ci	return 0;
41308c2ecf20Sopenharmony_ci}
41318c2ecf20Sopenharmony_ci
41328c2ecf20Sopenharmony_cistatic struct usb_driver em28xx_usb_driver = {
41338c2ecf20Sopenharmony_ci	.name = "em28xx",
41348c2ecf20Sopenharmony_ci	.probe = em28xx_usb_probe,
41358c2ecf20Sopenharmony_ci	.disconnect = em28xx_usb_disconnect,
41368c2ecf20Sopenharmony_ci	.suspend = em28xx_usb_suspend,
41378c2ecf20Sopenharmony_ci	.resume = em28xx_usb_resume,
41388c2ecf20Sopenharmony_ci	.reset_resume = em28xx_usb_resume,
41398c2ecf20Sopenharmony_ci	.id_table = em28xx_id_table,
41408c2ecf20Sopenharmony_ci};
41418c2ecf20Sopenharmony_ci
41428c2ecf20Sopenharmony_cimodule_usb_driver(em28xx_usb_driver);
4143