summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/em28xx')
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c1047
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c38
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c87
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c93
-rw-r--r--drivers/media/video/em28xx/em28xx.h61
6 files changed, 1251 insertions, 76 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 8cbda43727c..476ae44a62d 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -32,8 +32,8 @@
#include <media/saa7115.h>
#include <media/tvp5150.h>
#include <media/tveeprom.h>
-#include <media/audiochip.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
#include "em28xx.h"
@@ -52,6 +52,15 @@ struct em28xx_hash_table {
};
struct em28xx_board em28xx_boards[] = {
+ [EM2750_BOARD_UNKNOWN] = {
+ .name = "Unknown EM2750/EM2751 webcam grabber",
+ .vchannels = 1,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 0,
+ } },
+ },
[EM2800_BOARD_UNKNOWN] = {
.name = "Unknown EM2800 video grabber",
.is_em2800 = 1,
@@ -73,6 +82,39 @@ struct em28xx_board em28xx_boards[] = {
.is_em2800 = 0,
.tuner_type = TUNER_ABSENT,
},
+ [EM2750_BOARD_DLCW_130] = {
+ /* Beijing Huaqi Information Digital Technology Co., Ltd */
+ .name = "Huaqi DLCW-130",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 1,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 0,
+ } },
+ },
+ [EM2800_BOARD_KWORLD_USB2800] = {
+ .name = "Kworld USB2800",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .is_em2800 = 1,
+ .vchannels = 3,
+ .tuner_type = TUNER_PHILIPS_FCV1236D,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
[EM2820_BOARD_KWORLD_PVRTV2800RF] = {
.name = "Kworld PVR TV 2800 RF",
.is_em2800 = 0,
@@ -151,6 +193,376 @@ struct em28xx_board em28xx_boards[] = {
MSP_DSP_IN_SCART, MSP_DSP_IN_SCART),
} },
},
+ [EM2820_BOARD_DLINK_USB_TV] = {
+ .name = "D-Link DUB-T210 TV Tuner",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .is_em2800 = 0,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2820_BOARD_HERCULES_SMART_TV_USB2] = {
+ .name = "Hercules Smart TV USB 2.0",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2820_BOARD_PINNACLE_USB_2_FM1216ME] = {
+ .name = "Pinnacle PCTV USB 2 (Philips FM1216ME)",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .is_em2800 = 0,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2820_BOARD_GADMEI_UTV310] = {
+ .name = "Gadmei UTV310",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_TNF_5335MF,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE] = {
+ .name = "Leadtek Winfast USB II Deluxe",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA7114,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = 2,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = 9,
+ .amux = 1,
+ } },
+ },
+ [EM2820_BOARD_PINNACLE_DVC_100] = {
+ .name = "Pinnacle Dazzle DVC 100",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
+ .name = "Videology 20K14XUSB USB2.0",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 1,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 0,
+ } },
+ },
+ [EM2821_BOARD_PROLINK_PLAYTV_USB2] = {
+ .name = "SIIG AVTuner-PVR/Prolink PlayTV USB 2.0",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .is_em2800 = 0,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC, /* unknown? */
+ .tda9887_conf = TDA9887_PRESENT, /* unknown? */
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2821_BOARD_SUPERCOMP_USB_2] = {
+ .name = "Supercomp USB 2.0 TV",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .is_em2800 = 0,
+ .tuner_type = TUNER_PHILIPS_FM1236_MK3,
+ .tda9887_conf = TDA9887_PRESENT |
+ TDA9887_PORT1_ACTIVE |
+ TDA9887_PORT2_ACTIVE,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2821_BOARD_USBGEAR_VD204] = {
+ .name = "Usbgear VD204v9",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 2,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2860_BOARD_NETGMBH_CAM] = {
+ /* Beijing Huaqi Information Digital Technology Co., Ltd */
+ .name = "NetGMBH Cam",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 1,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 0,
+ } },
+ },
+ [EM2860_BOARD_TYPHOON_DVD_MAKER] = {
+ .name = "Typhoon DVD Maker",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 2,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2860_BOARD_GADMEI_UTV330] = {
+ .name = "Gadmei UTV330",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_TNF_5335MF,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2860_BOARD_TERRATEC_HYBRID_XS] = {
+ .name = "Terratec Cinergy A Hybrid XS",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2861_BOARD_KWORLD_PVRTV_300U] = {
+ .name = "KWorld PVRTV 300U",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2861_BOARD_YAKUMO_MOVIE_MIXER] = {
+ .name = "Yakumo MovieMixer",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 1,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2861_BOARD_PLEXTOR_PX_TV100U] = {
+ .name = "Plextor ConvertX PX-TV100U",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_TNF_5335MF,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2870_BOARD_TERRATEC_XS] = {
+ .name = "Terratec Cinergy T XS",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .tuner_type = TUNER_XC2028,
+ },
+ [EM2870_BOARD_TERRATEC_XS_MT2060] = {
+ .name = "Terratec Cinergy T XS (MT2060)",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .tuner_type = TUNER_ABSENT, /* MT2060 */
+ },
+ [EM2870_BOARD_KWORLD_350U] = {
+ .name = "Kworld 350 U DVB-T",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .tuner_type = TUNER_XC2028,
+ },
+ [EM2870_BOARD_KWORLD_355U] = {
+ .name = "Kworld 355 U DVB-T",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ },
+ [EM2870_BOARD_PINNACLE_PCTV_DVB] = {
+ .name = "Pinnacle PCTV DVB-T",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .tuner_type = TUNER_ABSENT, /* MT2060 */
+ },
+ [EM2870_BOARD_COMPRO_VIDEOMATE] = {
+ .name = "Compro, VideoMate U3",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .tuner_type = TUNER_ABSENT, /* MT2060 */
+ },
+ [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = {
+ .name = "Terratec Hybrid XS Secam",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .has_msp34xx = 1,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
[EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = {
.name = "Hauppauge WinTV HVR 900",
.vchannels = 3,
@@ -173,7 +585,28 @@ struct em28xx_board em28xx_boards[] = {
.amux = 1,
} },
},
- [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
+ [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = {
+ .name = "Hauppauge WinTV HVR 900 (R2)",
+ .vchannels = 3,
+ .tda9887_conf = TDA9887_PRESENT,
+ .tuner_type = TUNER_XC2028,
+ .mts_firmware = 1,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
.name = "Hauppauge WinTV HVR 950",
.vchannels = 3,
.tda9887_conf = TDA9887_PRESENT,
@@ -196,12 +629,59 @@ struct em28xx_board em28xx_boards[] = {
.amux = 1,
} },
},
+ [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = {
+ .name = "Pinnacle PCTV HD Pro Stick",
+ .vchannels = 3,
+ .tda9887_conf = TDA9887_PRESENT,
+ .tuner_type = TUNER_XC2028,
+ .mts_firmware = 1,
+ .has_12mhz_i2s = 1,
+ .has_dvb = 1,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = {
+ .name = "AMD ATI TV Wonder HD 600",
+ .vchannels = 3,
+ .tda9887_conf = TDA9887_PRESENT,
+ .tuner_type = TUNER_XC2028,
+ .mts_firmware = 1,
+ .has_12mhz_i2s = 1,
+ .has_dvb = 1,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
[EM2880_BOARD_TERRATEC_HYBRID_XS] = {
.name = "Terratec Hybrid XS",
.vchannels = 3,
.tda9887_conf = TDA9887_PRESENT,
.tuner_type = TUNER_XC2028,
.decoder = EM28XX_TVP5150,
+ .has_dvb = 1,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
.vmux = TVP5150_COMPOSITE0,
@@ -284,6 +764,21 @@ struct em28xx_board em28xx_boards[] = {
.amux = 1,
} },
},
+ [EM2800_BOARD_GRABBEEX_USB2800] = {
+ .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
+ .is_em2800 = 1,
+ .vchannels = 2,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
[EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
.name = "Leadtek Winfast USB II",
.is_em2800 = 1,
@@ -382,13 +877,245 @@ struct em28xx_board em28xx_boards[] = {
.amux = EM28XX_AMUX_LINE_IN,
} },
},
+ [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = {
+ .name = "PointNix Intra-Oral Camera",
+ .has_snapshot_button = 1,
+ .vchannels = 1,
+ .tda9887_conf = TDA9887_PRESENT,
+ .tuner_type = TUNER_ABSENT,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 0,
+ } },
+ },
+ [EM2880_BOARD_MSI_DIGIVOX_AD] = {
+ .name = "MSI DigiVox A/D",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2880_BOARD_MSI_DIGIVOX_AD_II] = {
+ .name = "MSI DigiVox A/D II",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2880_BOARD_KWORLD_DVB_305U] = {
+ .name = "KWorld DVB-T 305U",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2880_BOARD_KWORLD_DVB_310U] = {
+ .name = "KWorld DVB-T 310U",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2881_BOARD_DNT_DA2_HYBRID] = {
+ .name = "DNT DA2 Hybrid",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2881_BOARD_PINNACLE_HYBRID_PRO] = {
+ .name = "Pinnacle Hybrid Pro",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2882_BOARD_PINNACLE_HYBRID_PRO] = {
+ .name = "Pinnacle Hybrid Pro (2)",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2882_BOARD_KWORLD_VS_DVBT] = {
+ .name = "Kworld VS-DVB-T 323UR",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2882_BOARD_TERRATEC_HYBRID_XS] = {
+ .name = "Terratec Hybrid XS (em2882)",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2883_BOARD_KWORLD_HYBRID_A316] = {
+ .name = "Kworld PlusTV HD Hybrid 330",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .is_em2800 = 0,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
+ .name = "Compro VideoMate ForYou/Stereo",
+ .vchannels = 2,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = EM28XX_AMUX_LINE_IN,
+ } },
+ },
};
const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
/* table of devices that work with this driver */
struct usb_device_id em28xx_id_table [] = {
{ USB_DEVICE(0xeb1a, 0x2750),
- .driver_info = EM2820_BOARD_UNKNOWN },
+ .driver_info = EM2750_BOARD_UNKNOWN },
+ { USB_DEVICE(0xeb1a, 0x2751),
+ .driver_info = EM2750_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0x2800),
.driver_info = EM2800_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0x2820),
@@ -405,34 +1132,78 @@ struct usb_device_id em28xx_id_table [] = {
.driver_info = EM2820_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0x2883),
.driver_info = EM2820_BOARD_UNKNOWN },
+ { USB_DEVICE(0xeb1a, 0xe300),
+ .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
+ { USB_DEVICE(0xeb1a, 0xe305),
+ .driver_info = EM2880_BOARD_KWORLD_DVB_305U },
+ { USB_DEVICE(0xeb1a, 0xe310),
+ .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD },
+ { USB_DEVICE(0xeb1a, 0xa316),
+ .driver_info = EM2883_BOARD_KWORLD_HYBRID_A316 },
+ { USB_DEVICE(0xeb1a, 0xe320),
+ .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II },
+ { USB_DEVICE(0xeb1a, 0xe323),
+ .driver_info = EM2882_BOARD_KWORLD_VS_DVBT },
+ { USB_DEVICE(0xeb1a, 0xe350),
+ .driver_info = EM2870_BOARD_KWORLD_350U },
+ { USB_DEVICE(0xeb1a, 0xe355),
+ .driver_info = EM2870_BOARD_KWORLD_355U },
+ { USB_DEVICE(0xeb1a, 0x2801),
+ .driver_info = EM2800_BOARD_GRABBEEX_USB2800 },
+ { USB_DEVICE(0xeb1a, 0xe357),
+ .driver_info = EM2870_BOARD_KWORLD_355U },
{ USB_DEVICE(0x0ccd, 0x0036),
.driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
- { USB_DEVICE(0x2304, 0x0208),
- .driver_info = EM2820_BOARD_PINNACLE_USB_2 },
+ { USB_DEVICE(0x0ccd, 0x004c),
+ .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS_FR },
+ { USB_DEVICE(0x0ccd, 0x004f),
+ .driver_info = EM2860_BOARD_TERRATEC_HYBRID_XS },
+ { USB_DEVICE(0x0ccd, 0x005e),
+ .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
+ { USB_DEVICE(0x0ccd, 0x0042),
+ .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
+ { USB_DEVICE(0x0ccd, 0x0043),
+ .driver_info = EM2870_BOARD_TERRATEC_XS },
+ { USB_DEVICE(0x0ccd, 0x0047),
+ .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS },
+ { USB_DEVICE(0x185b, 0x2870),
+ .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE },
+ { USB_DEVICE(0x185b, 0x2041),
+ .driver_info = EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU },
{ USB_DEVICE(0x2040, 0x4200),
.driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
{ USB_DEVICE(0x2040, 0x4201),
.driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
- { USB_DEVICE(0x2304, 0x0207),
- .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
- { USB_DEVICE(0x2304, 0x021a),
- .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
{ USB_DEVICE(0x2040, 0x6500),
.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
{ USB_DEVICE(0x2040, 0x6502),
- .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
+ .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 },
{ USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */
- .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+ .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
{ USB_DEVICE(0x2040, 0x6517), /* HP HVR-950 */
- .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+ .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
{ USB_DEVICE(0x2040, 0x651b), /* RP HVR-950 */
- .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+ .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
{ USB_DEVICE(0x2040, 0x651f), /* HCW HVR-850 */
- .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
- { USB_DEVICE(0x0ccd, 0x0042),
- .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
- { USB_DEVICE(0x0ccd, 0x0047),
- .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS },
+ .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+ { USB_DEVICE(0x0438, 0xb002),
+ .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 },
+ { USB_DEVICE(0x2001, 0xf112),
+ .driver_info = EM2820_BOARD_DLINK_USB_TV },
+ { USB_DEVICE(0x2304, 0x0207),
+ .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
+ { USB_DEVICE(0x2304, 0x0208),
+ .driver_info = EM2820_BOARD_PINNACLE_USB_2 },
+ { USB_DEVICE(0x2304, 0x021a),
+ .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
+ { USB_DEVICE(0x2304, 0x0226),
+ .driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO },
+ { USB_DEVICE(0x2304, 0x0227),
+ .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
+ { USB_DEVICE(0x0413, 0x6023),
+ .driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII },
+ { USB_DEVICE(0x093b, 0xa005),
+ .driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U },
{ },
};
MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -441,6 +1212,18 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table);
* Reset sequences for analog/digital modes
*/
+/* Reset for the most [analog] boards */
+static struct em28xx_reg_seq default_analog[] = {
+ {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
+ { -1, -1, -1, -1},
+};
+
+/* Reset for the most [digital] boards */
+static struct em28xx_reg_seq default_digital[] = {
+ {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
+ { -1, -1, -1, -1},
+};
+
/* Board Hauppauge WinTV HVR 900 analog */
static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
{EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10},
@@ -456,14 +1239,42 @@ static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
{ -1, -1, -1, -1},
};
-/* Board Hauppauge WinTV HVR 900 tuner_callback */
-static struct em28xx_reg_seq hauppauge_wintv_hvr_900_tuner_callback[] = {
+/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
+static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
+ {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10},
+ { -1, -1, -1, -1},
+};
+
+/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
+static struct em28xx_reg_seq em2880_msi_digivox_ad_digital[] = {
+ {EM28XX_R08_GPIO, 0x6a, ~EM_GPIO_4, 10},
+ { -1, -1, -1, -1},
+};
+
+/* Board - EM2870 Kworld 355u
+ Analog - No input analog */
+static struct em28xx_reg_seq em2870_kworld_355u_digital[] = {
+ {EM2880_R04_GPO, 0x01, 0xff, 10},
+ { -1, -1, -1, -1},
+};
+
+/* Callback for the most boards */
+static struct em28xx_reg_seq default_callback[] = {
{EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
{EM28XX_R08_GPIO, 0, EM_GPIO_4, 10},
{EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
{ -1, -1, -1, -1},
};
+/* Callback for EM2882 TERRATEC HYBRID XS */
+static struct em28xx_reg_seq em2882_terratec_hybrid_xs_digital[] = {
+ {EM28XX_R08_GPIO, 0x2e, 0xff, 6},
+ {EM28XX_R08_GPIO, 0x3e, ~EM_GPIO_4, 6},
+ {EM2880_R04_GPO, 0x04, 0xff, 10},
+ {EM2880_R04_GPO, 0x0c, 0xff, 10},
+ { -1, -1, -1, -1},
+};
+
/*
* EEPROM hash table for devices with generic USB IDs
*/
@@ -476,6 +1287,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash [] = {
static struct em28xx_hash_table em28xx_i2c_hash[] = {
{0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
{0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
+ {0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT},
};
int em28xx_tuner_callback(void *ptr, int command, int arg)
@@ -508,6 +1320,8 @@ static void em28xx_set_model(struct em28xx *dev)
dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s;
dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480;
dev->has_dvb = em28xx_boards[dev->model].has_dvb;
+ dev->has_snapshot_button = em28xx_boards[dev->model].has_snapshot_button;
+ dev->valid = em28xx_boards[dev->model].valid;
}
/* Since em28xx_pre_card_setup() requires a proper dev->model,
@@ -542,8 +1356,13 @@ void em28xx_pre_card_setup(struct em28xx *dev)
switch (dev->model) {
case EM2880_BOARD_TERRATEC_PRODIGY_XS:
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
- case EM2880_BOARD_TERRATEC_HYBRID_XS:
- case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
+ case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
+ case EM2860_BOARD_TERRATEC_HYBRID_XS:
+ case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
+ case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
+ case EM2882_BOARD_PINNACLE_HYBRID_PRO:
+ case EM2883_BOARD_KWORLD_HYBRID_A316:
+ case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
msleep(50);
@@ -551,9 +1370,158 @@ void em28xx_pre_card_setup(struct em28xx *dev)
/* Sets GPO/GPIO sequences for this device */
dev->analog_gpio = hauppauge_wintv_hvr_900_analog;
dev->digital_gpio = hauppauge_wintv_hvr_900_digital;
- dev->tun_analog_gpio = hauppauge_wintv_hvr_900_tuner_callback;
- dev->tun_digital_gpio = hauppauge_wintv_hvr_900_tuner_callback;
+ dev->tun_analog_gpio = default_callback;
+ dev->tun_digital_gpio = default_callback;
+ break;
+
+ case EM2882_BOARD_TERRATEC_HYBRID_XS:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ msleep(50);
+
+ /* should be added ir_codes here */
+ /* Sets GPO/GPIO sequences for this device */
+ dev->analog_gpio = hauppauge_wintv_hvr_900_analog;
+ dev->digital_gpio = hauppauge_wintv_hvr_900_digital;
+ dev->tun_analog_gpio = default_callback;
+ dev->tun_digital_gpio = em2882_terratec_hybrid_xs_digital;
+ break;
+
+ case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
+ case EM2880_BOARD_TERRATEC_HYBRID_XS:
+ case EM2870_BOARD_TERRATEC_XS:
+ case EM2881_BOARD_PINNACLE_HYBRID_PRO:
+ case EM2880_BOARD_KWORLD_DVB_310U:
+ case EM2870_BOARD_KWORLD_350U:
+ case EM2881_BOARD_DNT_DA2_HYBRID:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ msleep(50);
+
+ /* NOTE: EM2881_DNT_DA2_HYBRID spend 140 msleep for digital
+ and analog commands. If this commands doesn't work,
+ add this timer. */
+
+ /* Sets GPO/GPIO sequences for this device */
+ dev->analog_gpio = default_analog;
+ dev->digital_gpio = default_digital;
+ dev->tun_analog_gpio = default_callback;
+ dev->tun_digital_gpio = default_callback;
+ break;
+
+ case EM2880_BOARD_MSI_DIGIVOX_AD:
+ case EM2880_BOARD_MSI_DIGIVOX_AD_II:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ msleep(50);
+
+ /* Sets GPO/GPIO sequences for this device */
+ dev->analog_gpio = em2880_msi_digivox_ad_analog;
+ dev->digital_gpio = em2880_msi_digivox_ad_digital;
+ dev->tun_analog_gpio = default_callback;
+ dev->tun_digital_gpio = default_callback;
+ break;
+
+ case EM2750_BOARD_UNKNOWN:
+ case EM2750_BOARD_DLCW_130:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x0a", 1);
+ break;
+
+ case EM2861_BOARD_PLEXTOR_PX_TV100U:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ /* FIXME guess */
+ /* Turn on analog audio output */
+ em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1);
+ break;
+
+ case EM2861_BOARD_KWORLD_PVRTV_300U:
+ case EM2880_BOARD_KWORLD_DVB_305U:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x4c", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x08, "\x6d", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x08, "\x7d", 1);
+ msleep(10);
+ break;
+
+ case EM2870_BOARD_KWORLD_355U:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ msleep(50);
+
+ /* Sets GPO/GPIO sequences for this device */
+ dev->digital_gpio = em2870_kworld_355u_digital;
+ break;
+
+ case EM2870_BOARD_COMPRO_VIDEOMATE:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ /* TODO: someone can do some cleanup here...
+ not everything's needed */
+ em28xx_write_regs(dev, 0x04, "\x00", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x04, "\x01", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x08, "\xfd", 1);
+ mdelay(70);
+ em28xx_write_regs(dev, 0x08, "\xfc", 1);
+ mdelay(70);
+ em28xx_write_regs(dev, 0x08, "\xdc", 1);
+ mdelay(70);
+ em28xx_write_regs(dev, 0x08, "\xfc", 1);
+ mdelay(70);
+ break;
+
+ case EM2870_BOARD_TERRATEC_XS_MT2060:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ /* this device needs some gpio writes to get the DVB-T
+ demod work */
+ em28xx_write_regs(dev, 0x08, "\xfe", 1);
+ mdelay(70);
+ em28xx_write_regs(dev, 0x08, "\xde", 1);
+ mdelay(70);
+ dev->em28xx_write_regs(dev, 0x08, "\xfe", 1);
+ mdelay(70);
+ break;
+
+ case EM2870_BOARD_PINNACLE_PCTV_DVB:
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ /* this device needs some gpio writes to get the
+ DVB-T demod work */
+ em28xx_write_regs(dev, 0x08, "\xfe", 1);
+ mdelay(70);
+ em28xx_write_regs(dev, 0x08, "\xde", 1);
+ mdelay(70);
+ em28xx_write_regs(dev, 0x08, "\xfe", 1);
+ mdelay(70);
+ /* switch em2880 rc protocol */
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x22", 1);
+ /* should be added ir_codes here */
+ break;
+
+ case EM2820_BOARD_GADMEI_UTV310:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ /* Turn on analog audio output */
+ em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1);
+ break;
+
+ case EM2860_BOARD_GADMEI_UTV330:
+ /* Turn on IR */
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ /* should be added ir_codes here */
+ break;
+
+ case EM2820_BOARD_MSI_VOX_USB_2:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ /* enables audio for that device */
+ em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1);
break;
}
@@ -576,7 +1544,16 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
ctl->demod = XC3028_FE_ZARLINK456;
break;
- case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
+ case EM2880_BOARD_TERRATEC_HYBRID_XS:
+ ctl->demod = XC3028_FE_ZARLINK456;
+ break;
+ case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
+ /* djh - Not sure which demod we need here */
+ ctl->demod = XC3028_FE_DEFAULT;
+ break;
+ case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
+ case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
+ case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
/* FIXME: Better to specify the needed IF */
ctl->demod = XC3028_FE_DEFAULT;
break;
@@ -741,6 +1718,8 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
break;
case (EM2800_BOARD_KWORLD_USB2800):
break;
+ case (EM2800_BOARD_GRABBEEX_USB2800):
+ break;
}
}
@@ -754,7 +1733,8 @@ void em28xx_card_setup(struct em28xx *dev)
switch (dev->model) {
case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
- case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
+ case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
+ case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
{
struct tveeprom tv;
#ifdef CONFIG_MODULES
@@ -767,7 +1747,7 @@ void em28xx_card_setup(struct em28xx *dev)
dev->tuner_type = tv.tuner_type;
- if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
+ if (tv.audio_processor == V4L2_IDENT_MSPX4XX) {
dev->i2s_speed = 2048000;
dev->has_msp34xx = 1;
}
@@ -785,6 +1765,19 @@ void em28xx_card_setup(struct em28xx *dev)
case EM2800_BOARD_UNKNOWN:
if (!em28xx_hint_board(dev))
em28xx_set_model(dev);
+ break;
+ }
+
+ if (dev->has_snapshot_button)
+ em28xx_register_snapshot_button(dev);
+
+ if (dev->valid == EM28XX_BOARD_NOT_VALIDATED) {
+ em28xx_errdev("\n\n");
+ em28xx_errdev("The support for this board weren't "
+ "valid yet.\n");
+ em28xx_errdev("Please send a report of having this working\n");
+ em28xx_errdev("not to V4L mailing list (and/or to other "
+ "addresses)\n\n");
}
/* Allow override tuner type by a module parameter */
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index 0b2333ee07f..4b992bc0083 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -5,6 +5,8 @@
(c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com>
- Fixes for the driver to properly work with HVR-950
+ - Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick
+ - Fixes for the driver to properly work with AMD ATI TV Wonder HD 600
(c) 2008 Aidan Thornton <makosoft@googlemail.com>
@@ -26,6 +28,9 @@
#include "lgdt330x.h"
#include "zl10353.h"
+#ifdef EM28XX_DRX397XD_SUPPORT
+#include "drx397xD.h"
+#endif
MODULE_DESCRIPTION("driver for em28xx based DVB cards");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
@@ -227,6 +232,13 @@ static struct zl10353_config em28xx_zl10353_with_xc3028 = {
.if2 = 45600,
};
+#ifdef EM28XX_DRX397XD_SUPPORT
+/* [TODO] djh - not sure yet what the device config needs to contain */
+static struct drx397xD_config em28xx_drx397xD_with_xc3028 = {
+ .demod_address = (0xe0 >> 1),
+};
+#endif
+
/* ------------------------------------------------------------------ */
static int attach_xc3028(u8 addr, struct em28xx *dev)
@@ -398,7 +410,9 @@ static int dvb_init(struct em28xx *dev)
em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
/* init frontend */
switch (dev->model) {
- case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
+ case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
+ case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
+ case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
dvb->frontend = dvb_attach(lgdt330x_attach,
&em2880_lgdt3303_dev,
&dev->i2c_adap);
@@ -416,6 +430,28 @@ static int dvb_init(struct em28xx *dev)
goto out_free;
}
break;
+ case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
+#ifdef EM28XX_DRX397XD_SUPPORT
+ /* We don't have the config structure properly populated, so
+ this is commented out for now */
+ dvb->frontend = dvb_attach(drx397xD_attach,
+ &em28xx_drx397xD_with_xc3028,
+ &dev->i2c_adap);
+ if (attach_xc3028(0x61, dev) < 0) {
+ result = -EINVAL;
+ goto out_free;
+ }
+ break;
+#endif
+ case EM2880_BOARD_TERRATEC_HYBRID_XS:
+ dvb->frontend = dvb_attach(zl10353_attach,
+ &em28xx_zl10353_with_xc3028,
+ &dev->i2c_adap);
+ if (attach_xc3028(0x61, dev) < 0) {
+ result = -EINVAL;
+ goto out_free;
+ }
+ break;
default:
printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
" isn't supported yet\n",
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index 6a78fd294ca..97853384c94 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -432,7 +432,6 @@ static u32 functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL;
}
-
/*
* attach_inform()
* gets called when a device attaches to the i2c bus
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index bb5807159b8..eab3d9511af 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -30,6 +30,10 @@
#include "em28xx.h"
+#define EM28XX_SNAPSHOT_KEY KEY_CAMERA
+#define EM28XX_SBUTTON_QUERY_INTERVAL 500
+#define EM28XX_R0C_USBSUSP_SNAPSHOT 0x20
+
static unsigned int ir_debug;
module_param(ir_debug, int, 0644);
MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
@@ -124,6 +128,89 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
return 1;
}
+static void em28xx_query_sbutton(struct work_struct *work)
+{
+ /* Poll the register and see if the button is depressed */
+ struct em28xx *dev =
+ container_of(work, struct em28xx, sbutton_query_work.work);
+ int ret;
+
+ ret = em28xx_read_reg(dev, EM28XX_R0C_USBSUSP);
+
+ if (ret & EM28XX_R0C_USBSUSP_SNAPSHOT) {
+ u8 cleared;
+ /* Button is depressed, clear the register */
+ cleared = ((u8) ret) & ~EM28XX_R0C_USBSUSP_SNAPSHOT;
+ em28xx_write_regs(dev, EM28XX_R0C_USBSUSP, &cleared, 1);
+
+ /* Not emulate the keypress */
+ input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY,
+ 1);
+ /* Now unpress the key */
+ input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY,
+ 0);
+ }
+
+ /* Schedule next poll */
+ schedule_delayed_work(&dev->sbutton_query_work,
+ msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL));
+}
+
+void em28xx_register_snapshot_button(struct em28xx *dev)
+{
+ struct input_dev *input_dev;
+ int err;
+
+ em28xx_info("Registering snapshot button...\n");
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ em28xx_errdev("input_allocate_device failed\n");
+ return;
+ }
+
+ usb_make_path(dev->udev, dev->snapshot_button_path,
+ sizeof(dev->snapshot_button_path));
+ strlcat(dev->snapshot_button_path, "/sbutton",
+ sizeof(dev->snapshot_button_path));
+ INIT_DELAYED_WORK(&dev->sbutton_query_work, em28xx_query_sbutton);
+
+ input_dev->name = "em28xx snapshot button";
+ input_dev->phys = dev->snapshot_button_path;
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+ set_bit(EM28XX_SNAPSHOT_KEY, input_dev->keybit);
+ input_dev->keycodesize = 0;
+ input_dev->keycodemax = 0;
+ input_dev->id.bustype = BUS_USB;
+ input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+ input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+ input_dev->id.version = 1;
+ input_dev->dev.parent = &dev->udev->dev;
+
+ err = input_register_device(input_dev);
+ if (err) {
+ em28xx_errdev("input_register_device failed\n");
+ input_free_device(input_dev);
+ return;
+ }
+
+ dev->sbutton_input_dev = input_dev;
+ schedule_delayed_work(&dev->sbutton_query_work,
+ msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL));
+ return;
+
+}
+
+void em28xx_deregister_snapshot_button(struct em28xx *dev)
+{
+ if (dev->sbutton_input_dev != NULL) {
+ em28xx_info("Deregistering snapshot button\n");
+ cancel_rearming_delayed_work(&dev->sbutton_query_work);
+ input_unregister_device(dev->sbutton_input_dev);
+ dev->sbutton_input_dev = NULL;
+ }
+ return;
+}
+
/* ----------------------------------------------------------------------
* Local variables:
* c-basic-offset: 8
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 285bc62bbe4..49ab0629702 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -38,6 +38,7 @@
#include "em28xx.h"
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/msp3400.h>
#include <media/tuner.h>
@@ -683,7 +684,7 @@ static void get_scale(struct em28xx *dev,
IOCTL vidioc handling
------------------------------------------------------------------*/
-static int vidioc_g_fmt_cap(struct file *file, void *priv,
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct em28xx_fh *fh = priv;
@@ -706,7 +707,7 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int vidioc_try_fmt_cap(struct file *file, void *priv,
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct em28xx_fh *fh = priv;
@@ -766,7 +767,7 @@ static int vidioc_try_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int vidioc_s_fmt_cap(struct file *file, void *priv,
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct em28xx_fh *fh = priv;
@@ -777,7 +778,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv,
if (rc < 0)
return rc;
- vidioc_try_fmt_cap(file, priv, f);
+ vidioc_try_fmt_vid_cap(file, priv, f);
mutex_lock(&dev->lock);
@@ -826,7 +827,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
/* Adjusts width/height, if needed */
f.fmt.pix.width = dev->width;
f.fmt.pix.height = dev->height;
- vidioc_try_fmt_cap(file, priv, &f);
+ vidioc_try_fmt_vid_cap(file, priv, &f);
mutex_lock(&dev->lock);
@@ -1277,7 +1278,7 @@ static int vidioc_querycap(struct file *file, void *priv,
return 0;
}
-static int vidioc_enum_fmt_cap(struct file *file, void *priv,
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *fmtd)
{
if (fmtd->index != 0)
@@ -1292,7 +1293,7 @@ static int vidioc_enum_fmt_cap(struct file *file, void *priv,
}
/* Sliced VBI ioctls */
-static int vidioc_g_fmt_vbi_capture(struct file *file, void *priv,
+static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct em28xx_fh *fh = priv;
@@ -1316,7 +1317,7 @@ static int vidioc_g_fmt_vbi_capture(struct file *file, void *priv,
return rc;
}
-static int vidioc_try_set_vbi_capture(struct file *file, void *priv,
+static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct em28xx_fh *fh = priv;
@@ -1590,6 +1591,8 @@ static void em28xx_release_resources(struct em28xx *dev)
dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN,
dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN);
list_del(&dev->devlist);
+ if (dev->sbutton_input_dev)
+ em28xx_deregister_snapshot_button(dev);
if (dev->radio_dev) {
if (-1 != dev->radio_dev->minor)
video_unregister_device(dev->radio_dev);
@@ -1761,32 +1764,19 @@ static const struct file_operations em28xx_v4l_fops = {
.compat_ioctl = v4l_compat_ioctl32,
};
-static const struct file_operations radio_fops = {
- .owner = THIS_MODULE,
- .open = em28xx_v4l2_open,
- .release = em28xx_v4l2_close,
- .ioctl = video_ioctl2,
- .compat_ioctl = v4l_compat_ioctl32,
- .llseek = no_llseek,
-};
-
-static const struct video_device em28xx_video_template = {
- .fops = &em28xx_v4l_fops,
- .release = video_device_release,
-
- .minor = -1,
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap,
- .vidioc_g_fmt_cap = vidioc_g_fmt_cap,
- .vidioc_try_fmt_cap = vidioc_try_fmt_cap,
- .vidioc_s_fmt_cap = vidioc_s_fmt_cap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
.vidioc_g_audio = vidioc_g_audio,
.vidioc_s_audio = vidioc_s_audio,
.vidioc_cropcap = vidioc_cropcap,
- .vidioc_g_fmt_vbi_capture = vidioc_g_fmt_vbi_capture,
- .vidioc_try_fmt_vbi_capture = vidioc_try_set_vbi_capture,
- .vidioc_s_fmt_vbi_capture = vidioc_try_set_vbi_capture,
+ .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
+ .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
+ .vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
.vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf,
@@ -1812,16 +1802,29 @@ static const struct video_device em28xx_video_template = {
#ifdef CONFIG_VIDEO_V4L1_COMPAT
.vidiocgmbuf = vidiocgmbuf,
#endif
+};
+
+static const struct video_device em28xx_video_template = {
+ .fops = &em28xx_v4l_fops,
+ .release = video_device_release,
+ .ioctl_ops = &video_ioctl_ops,
+
+ .minor = -1,
.tvnorms = V4L2_STD_ALL,
.current_norm = V4L2_STD_PAL,
};
-static struct video_device em28xx_radio_template = {
- .name = "em28xx-radio",
- .type = VID_TYPE_TUNER,
- .fops = &radio_fops,
- .minor = -1,
+static const struct file_operations radio_fops = {
+ .owner = THIS_MODULE,
+ .open = em28xx_v4l2_open,
+ .release = em28xx_v4l2_close,
+ .ioctl = video_ioctl2,
+ .compat_ioctl = v4l_compat_ioctl32,
+ .llseek = no_llseek,
+};
+
+static const struct v4l2_ioctl_ops radio_ioctl_ops = {
.vidioc_querycap = radio_querycap,
.vidioc_g_tuner = radio_g_tuner,
.vidioc_enum_input = radio_enum_input,
@@ -1840,6 +1843,13 @@ static struct video_device em28xx_radio_template = {
#endif
};
+static struct video_device em28xx_radio_template = {
+ .name = "em28xx-radio",
+ .fops = &radio_fops,
+ .ioctl_ops = &radio_ioctl_ops,
+ .minor = -1,
+};
+
/******************************** usb interface ******************************/
@@ -1880,7 +1890,6 @@ EXPORT_SYMBOL(em28xx_unregister_extension);
static struct video_device *em28xx_vdev_init(struct em28xx *dev,
const struct video_device *template,
- const int type,
const char *type_name)
{
struct video_device *vfd;
@@ -1890,9 +1899,8 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
return NULL;
*vfd = *template;
vfd->minor = -1;
- vfd->dev = &dev->udev->dev;
+ vfd->parent = &dev->udev->dev;
vfd->release = video_device_release;
- vfd->type = type;
vfd->debug = video_debug;
snprintf(vfd->name, sizeof(vfd->name), "%s %s",
@@ -1970,14 +1978,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
list_add_tail(&dev->devlist, &em28xx_devlist);
/* allocate and fill video video_device struct */
- dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template,
- VID_TYPE_CAPTURE, "video");
+ dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
if (NULL == dev->vdev) {
em28xx_errdev("cannot allocate video_device.\n");
goto fail_unreg;
}
- if (dev->tuner_type != TUNER_ABSENT)
- dev->vdev->type |= VID_TYPE_TUNER;
/* register v4l2 video video_device */
retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
@@ -1989,8 +1994,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
}
/* Allocate and fill vbi video_device struct */
- dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template,
- VFL_TYPE_VBI, "vbi");
+ dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi");
/* register v4l2 vbi video_device */
if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
vbi_nr[dev->devno]) < 0) {
@@ -2000,8 +2004,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
}
if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
- dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
- VFL_TYPE_RADIO, "radio");
+ dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio");
if (NULL == dev->radio_dev) {
em28xx_errdev("cannot allocate video_device.\n");
goto fail_unreg;
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 002f170b211..9a331074868 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -54,12 +54,58 @@
#define EM2880_BOARD_TERRATEC_PRODIGY_XS 13
#define EM2820_BOARD_PROLINK_PLAYTV_USB2 14
#define EM2800_BOARD_VGEAR_POCKETTV 15
-#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 16
+#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 16
+#define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17
+#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18
+#define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19
+#define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20
+#define EM2800_BOARD_GRABBEEX_USB2800 21
+#define EM2750_BOARD_UNKNOWN 22
+#define EM2750_BOARD_DLCW_130 23
+#define EM2820_BOARD_DLINK_USB_TV 24
+#define EM2820_BOARD_GADMEI_UTV310 25
+#define EM2820_BOARD_HERCULES_SMART_TV_USB2 26
+#define EM2820_BOARD_PINNACLE_USB_2_FM1216ME 27
+#define EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE 28
+#define EM2820_BOARD_PINNACLE_DVC_100 29
+#define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30
+#define EM2821_BOARD_USBGEAR_VD204 31
+#define EM2821_BOARD_SUPERCOMP_USB_2 32
+#define EM2821_BOARD_PROLINK_PLAYTV_USB2 33
+#define EM2860_BOARD_TERRATEC_HYBRID_XS 34
+#define EM2860_BOARD_TYPHOON_DVD_MAKER 35
+#define EM2860_BOARD_NETGMBH_CAM 36
+#define EM2860_BOARD_GADMEI_UTV330 37
+#define EM2861_BOARD_YAKUMO_MOVIE_MIXER 38
+#define EM2861_BOARD_KWORLD_PVRTV_300U 39
+#define EM2861_BOARD_PLEXTOR_PX_TV100U 40
+#define EM2870_BOARD_KWORLD_350U 41
+#define EM2870_BOARD_KWORLD_355U 42
+#define EM2870_BOARD_TERRATEC_XS 43
+#define EM2870_BOARD_TERRATEC_XS_MT2060 44
+#define EM2870_BOARD_PINNACLE_PCTV_DVB 45
+#define EM2870_BOARD_COMPRO_VIDEOMATE 46
+#define EM2880_BOARD_KWORLD_DVB_305U 47
+#define EM2880_BOARD_KWORLD_DVB_310U 48
+#define EM2880_BOARD_MSI_DIGIVOX_AD 49
+#define EM2880_BOARD_MSI_DIGIVOX_AD_II 50
+#define EM2880_BOARD_TERRATEC_HYBRID_XS_FR 51
+#define EM2881_BOARD_DNT_DA2_HYBRID 52
+#define EM2881_BOARD_PINNACLE_HYBRID_PRO 53
+#define EM2882_BOARD_KWORLD_VS_DVBT 54
+#define EM2882_BOARD_TERRATEC_HYBRID_XS 55
+#define EM2882_BOARD_PINNACLE_HYBRID_PRO 56
+#define EM2883_BOARD_KWORLD_HYBRID_A316 57
+#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
#define EM28XX_DEF_BUF 8
+/* Params for validated field */
+#define EM28XX_BOARD_NOT_VALIDATED 1
+#define EM28XX_BOARD_VALIDATED 0
+
/* maximum number of em28xx boards */
#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
@@ -247,6 +293,8 @@ struct em28xx_board {
unsigned int has_12mhz_i2s:1;
unsigned int max_range_640_480:1;
unsigned int has_dvb:1;
+ unsigned int has_snapshot_button:1;
+ unsigned int valid:1;
enum em28xx_decoder decoder;
@@ -326,6 +374,8 @@ struct em28xx {
unsigned int has_12mhz_i2s:1;
unsigned int max_range_640_480:1;
unsigned int has_dvb:1;
+ unsigned int has_snapshot_button:1;
+ unsigned int valid:1; /* report for validated boards */
/* Some older em28xx chips needs a waiting time after writing */
unsigned int wait_after_write;
@@ -355,7 +405,7 @@ struct em28xx {
v4l2_std_id norm; /* selected tv norm */
int ctl_freq; /* selected frequency */
unsigned int ctl_input; /* selected input */
- unsigned int ctl_ainput; /* slected audio input */
+ unsigned int ctl_ainput;/* selected audio input */
int mute;
int volume;
/* frame properties */
@@ -416,6 +466,11 @@ struct em28xx {
/* Caches GPO and GPIO registers */
unsigned char reg_gpo, reg_gpio;
+ /* Snapshot button */
+ char snapshot_button_path[30]; /* path of the input dev */
+ struct input_dev *sbutton_input_dev;
+ struct delayed_work sbutton_query_work;
+
struct em28xx_dvb *dvb;
};
@@ -481,6 +536,8 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
u32 *ir_raw);
+void em28xx_register_snapshot_button(struct em28xx *dev);
+void em28xx_deregister_snapshot_button(struct em28xx *dev);
/* printk macros */