2005-11-08 21:37:07 -08:00
/*
2005-11-08 21:38:25 -08:00
em28xx - cards . c - driver for Empia EM2800 / EM2820 / 2840 USB video capture devices
2005-11-08 21:37:07 -08:00
2005-11-08 21:38:25 -08:00
Copyright ( C ) 2005 Ludovico Cavedon < cavedon @ sssup . it >
Markus Rechberger < mrechberger @ gmail . com >
2005-11-08 21:37:43 -08:00
Mauro Carvalho Chehab < mchehab @ brturbo . com . br >
2005-11-08 21:38:25 -08:00
Sascha Sommer < saschasommer @ freenet . de >
2005-11-08 21:37:07 -08:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include <linux/init.h>
# include <linux/module.h>
# include <linux/pci.h>
# include <linux/delay.h>
# include <linux/i2c.h>
# include <linux/usb.h>
# include <media/tuner.h>
2005-11-08 21:37:16 -08:00
# include <media/audiochip.h>
# include <media/tveeprom.h>
2006-01-09 15:25:37 -02:00
# include <media/v4l2-common.h>
2005-11-08 21:37:07 -08:00
# include "msp3400.h"
2005-11-08 21:38:25 -08:00
# include "em28xx.h"
2005-11-08 21:37:07 -08:00
2005-11-08 21:38:27 -08:00
struct em28xx_board em28xx_boards [ ] = {
2005-11-08 21:37:24 -08:00
[ EM2800_BOARD_UNKNOWN ] = {
. name = " Unknown EM2800 video grabber " ,
. is_em2800 = 1 ,
. vchannels = 2 ,
. norm = VIDEO_MODE_PAL ,
. tda9887_conf = TDA9887_PRESENT ,
. has_tuner = 1 ,
2005-11-08 21:38:27 -08:00
. decoder = EM28XX_SAA7113 ,
2005-11-08 21:37:24 -08:00
. input = { {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_COMPOSITE1 ,
2005-11-08 21:37:24 -08:00
. vmux = 0 ,
. amux = 1 ,
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_SVIDEO ,
2005-11-08 21:37:24 -08:00
. vmux = 9 ,
. amux = 1 ,
} } ,
} ,
[ EM2820_BOARD_UNKNOWN ] = {
. name = " Unknown EM2820/2840 video grabber " ,
. is_em2800 = 0 ,
. vchannels = 2 ,
. norm = VIDEO_MODE_PAL ,
. tda9887_conf = TDA9887_PRESENT ,
. has_tuner = 1 ,
2005-11-08 21:38:27 -08:00
. decoder = EM28XX_SAA7113 ,
2005-11-08 21:37:24 -08:00
. input = { {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_COMPOSITE1 ,
2005-11-08 21:37:24 -08:00
. vmux = 0 ,
. amux = 1 ,
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_SVIDEO ,
2005-11-08 21:37:24 -08:00
. vmux = 9 ,
. amux = 1 ,
} } ,
} ,
2006-02-07 06:25:39 -02:00
[ EM2820_BOARD_KWORLD_PVRTV2800RF ] = {
2006-02-07 06:25:41 -02:00
. name = " Kworld PVR TV 2800 RF " ,
2006-02-07 06:25:39 -02:00
. is_em2800 = 0 ,
. vchannels = 2 ,
. norm = VIDEO_MODE_PAL ,
. tda9887_conf = TDA9887_PRESENT ,
. has_tuner = 1 ,
. decoder = EM28XX_SAA7113 ,
. input = { {
. type = EM28XX_VMUX_COMPOSITE1 ,
. vmux = 0 ,
. amux = 1 ,
} , {
. type = EM28XX_VMUX_SVIDEO ,
. vmux = 9 ,
. amux = 1 ,
} } ,
} ,
2005-11-08 21:37:07 -08:00
[ EM2820_BOARD_TERRATEC_CINERGY_250 ] = {
. name = " Terratec Cinergy 250 USB " ,
. vchannels = 3 ,
. norm = VIDEO_MODE_PAL ,
. tuner_type = TUNER_LG_PAL_NEW_TAPC ,
. tda9887_conf = TDA9887_PRESENT ,
. has_tuner = 1 ,
2005-11-08 21:38:27 -08:00
. decoder = EM28XX_SAA7113 ,
2005-11-08 21:37:07 -08:00
. input = { {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_TELEVISION ,
2005-11-08 21:37:07 -08:00
. vmux = 2 ,
. amux = 0 ,
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_COMPOSITE1 ,
2005-11-08 21:37:07 -08:00
. vmux = 0 ,
. amux = 1 ,
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_SVIDEO ,
2005-11-08 21:37:07 -08:00
. vmux = 9 ,
. amux = 1 ,
} } ,
} ,
[ EM2820_BOARD_PINNACLE_USB_2 ] = {
. name = " Pinnacle PCTV USB 2 " ,
. vchannels = 3 ,
. norm = VIDEO_MODE_PAL ,
. tuner_type = TUNER_LG_PAL_NEW_TAPC ,
. tda9887_conf = TDA9887_PRESENT ,
. has_tuner = 1 ,
2005-11-08 21:38:27 -08:00
. decoder = EM28XX_SAA7113 ,
2005-11-08 21:37:07 -08:00
. input = { {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_TELEVISION ,
2005-11-08 21:37:07 -08:00
. vmux = 2 ,
. amux = 0 ,
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_COMPOSITE1 ,
2005-11-08 21:37:07 -08:00
. vmux = 0 ,
. amux = 1 ,
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_SVIDEO ,
2005-11-08 21:37:07 -08:00
. vmux = 9 ,
. amux = 1 ,
} } ,
} ,
[ EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 ] = {
. name = " Hauppauge WinTV USB 2 " ,
. vchannels = 3 ,
. norm = VIDEO_MODE_NTSC ,
. tuner_type = TUNER_PHILIPS_FM1236_MK3 ,
. tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE | TDA9887_PORT2_ACTIVE ,
. has_tuner = 1 ,
2005-11-08 21:38:27 -08:00
. decoder = EM28XX_TVP5150 ,
2005-11-08 21:37:07 -08:00
. has_msp34xx = 1 ,
/*FIXME: S-Video not tested */
. input = { {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_TELEVISION ,
2005-11-08 21:37:07 -08:00
. vmux = 0 ,
2005-11-08 21:38:43 -08:00
. amux = 6 ,
2005-11-08 21:37:07 -08:00
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_SVIDEO ,
2005-11-08 21:37:07 -08:00
. vmux = 2 ,
. amux = 1 ,
} } ,
} ,
2006-02-07 06:25:39 -02:00
[ EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 ] = {
. name = " Hauppauge WinTV HVR 900 " ,
. vchannels = 3 ,
. norm = VIDEO_MODE_PAL ,
. tda9887_conf = TDA9887_PRESENT ,
2006-02-27 00:07:27 -03:00
. tuner_type = TUNER_XCEIVE_XC3028 ,
2006-02-07 06:25:39 -02:00
. has_tuner = 1 ,
. decoder = EM28XX_TVP5150 ,
. input = { {
. type = EM28XX_VMUX_COMPOSITE1 ,
. vmux = 2 ,
. amux = 0 ,
} , {
. type = EM28XX_VMUX_TELEVISION ,
. vmux = 0 ,
. amux = 1 ,
} , {
. type = EM28XX_VMUX_SVIDEO ,
. vmux = 9 ,
. amux = 1 ,
} } ,
} ,
[ EM2880_BOARD_TERRATEC_HYBRID_XS ] = {
. name = " Terratec Hybrid XS " ,
2006-01-23 17:11:10 -02:00
. vchannels = 3 ,
. norm = VIDEO_MODE_PAL ,
. tda9887_conf = TDA9887_PRESENT ,
. has_tuner = 1 ,
2006-02-27 00:07:31 -03:00
. tuner_type = TUNER_XCEIVE_XC3028 ,
2006-01-23 17:11:10 -02:00
. decoder = EM28XX_TVP5150 ,
. input = { {
. type = EM28XX_VMUX_COMPOSITE1 ,
. vmux = 2 ,
. amux = 0 ,
} , {
. type = EM28XX_VMUX_TELEVISION ,
. vmux = 0 ,
. amux = 1 ,
} , {
. type = EM28XX_VMUX_SVIDEO ,
. vmux = 9 ,
. amux = 1 ,
} } ,
} ,
2006-02-07 06:14:16 +01:00
/* maybe there's a reason behind it why Terratec sells the Hybrid XS as Prodigy XS with a
* different PID , let ' s keep it separated for now maybe we ' ll need it lateron */
[ EM2880_BOARD_TERRATEC_PRODIGY_XS ] = {
. name = " Terratec Prodigy XS " ,
. vchannels = 3 ,
. norm = VIDEO_MODE_PAL ,
. tda9887_conf = TDA9887_PRESENT ,
. has_tuner = 1 ,
. tuner_type = TUNER_XCEIVE_XC3028 ,
. decoder = EM28XX_TVP5150 ,
. input = { {
. type = EM28XX_VMUX_TELEVISION ,
. vmux = 0 ,
. amux = 0 ,
} , {
. type = EM28XX_VMUX_COMPOSITE1 ,
. vmux = 2 ,
. amux = 1 ,
} , {
. type = EM28XX_VMUX_SVIDEO ,
. vmux = 9 ,
. amux = 1 ,
} } ,
} ,
2005-11-08 21:37:07 -08:00
[ EM2820_BOARD_MSI_VOX_USB_2 ] = {
. name = " MSI VOX USB 2.0 " ,
. vchannels = 3 ,
. norm = VIDEO_MODE_PAL ,
2005-11-08 21:38:05 -08:00
. tuner_type = TUNER_LG_PAL_NEW_TAPC ,
2005-11-08 21:37:07 -08:00
. tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE | TDA9887_PORT2_ACTIVE ,
. has_tuner = 1 ,
2005-11-08 21:38:27 -08:00
. decoder = EM28XX_SAA7114 ,
2005-11-08 21:37:07 -08:00
. input = { {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_TELEVISION ,
2005-11-08 21:38:05 -08:00
. vmux = 4 ,
2005-11-08 21:37:07 -08:00
. amux = 0 ,
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_COMPOSITE1 ,
2005-11-08 21:37:07 -08:00
. vmux = 0 ,
. amux = 1 ,
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_SVIDEO ,
2005-11-08 21:37:07 -08:00
. vmux = 9 ,
. amux = 1 ,
} } ,
} ,
2005-11-08 21:37:24 -08:00
[ EM2800_BOARD_TERRATEC_CINERGY_200 ] = {
. name = " Terratec Cinergy 200 USB " ,
. is_em2800 = 1 ,
. vchannels = 3 ,
. norm = VIDEO_MODE_PAL ,
. tuner_type = TUNER_LG_PAL_NEW_TAPC ,
. tda9887_conf = TDA9887_PRESENT ,
. has_tuner = 1 ,
2005-11-08 21:38:27 -08:00
. decoder = EM28XX_SAA7113 ,
2005-11-08 21:37:24 -08:00
. input = { {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_TELEVISION ,
2005-11-08 21:37:24 -08:00
. vmux = 2 ,
. amux = 0 ,
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_COMPOSITE1 ,
2005-11-08 21:37:24 -08:00
. vmux = 0 ,
. amux = 1 ,
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_SVIDEO ,
2005-11-08 21:37:24 -08:00
. vmux = 9 ,
. amux = 1 ,
} } ,
} ,
[ EM2800_BOARD_LEADTEK_WINFAST_USBII ] = {
. name = " Leadtek Winfast USB II " ,
. is_em2800 = 1 ,
. vchannels = 3 ,
. norm = VIDEO_MODE_PAL ,
. tuner_type = TUNER_LG_PAL_NEW_TAPC ,
. tda9887_conf = TDA9887_PRESENT ,
. has_tuner = 1 ,
2005-11-08 21:38:27 -08:00
. decoder = EM28XX_SAA7113 ,
2005-11-08 21:37:24 -08:00
. input = { {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_TELEVISION ,
2005-11-08 21:37:24 -08:00
. vmux = 2 ,
. amux = 0 ,
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_COMPOSITE1 ,
2005-11-08 21:37:24 -08:00
. vmux = 0 ,
. amux = 1 ,
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_SVIDEO ,
2005-11-08 21:37:24 -08:00
. vmux = 9 ,
. amux = 1 ,
} } ,
} ,
[ EM2800_BOARD_KWORLD_USB2800 ] = {
. name = " Kworld USB2800 " ,
. is_em2800 = 1 ,
. vchannels = 3 ,
. norm = VIDEO_MODE_PAL ,
. tuner_type = TUNER_PHILIPS_ATSC ,
. tda9887_conf = TDA9887_PRESENT ,
. has_tuner = 1 ,
2005-11-08 21:38:27 -08:00
. decoder = EM28XX_SAA7113 ,
2005-11-08 21:37:24 -08:00
. input = { {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_TELEVISION ,
2005-11-08 21:37:24 -08:00
. vmux = 2 ,
. amux = 0 ,
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_COMPOSITE1 ,
2005-11-08 21:37:24 -08:00
. vmux = 0 ,
. amux = 1 ,
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_SVIDEO ,
2005-11-08 21:37:24 -08:00
. vmux = 9 ,
. amux = 1 ,
} } ,
} ,
2005-11-08 21:38:15 -08:00
[ EM2820_BOARD_PINNACLE_DVC_90 ] = {
. name = " Pinnacle Dazzle DVC 90 " ,
. vchannels = 3 ,
. norm = VIDEO_MODE_PAL ,
. has_tuner = 0 ,
2005-11-08 21:38:27 -08:00
. decoder = EM28XX_SAA7113 ,
2005-11-08 21:38:15 -08:00
. input = { {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_COMPOSITE1 ,
2005-11-08 21:38:15 -08:00
. vmux = 0 ,
. amux = 1 ,
} , {
2005-11-08 21:38:27 -08:00
. type = EM28XX_VMUX_SVIDEO ,
2005-11-08 21:38:15 -08:00
. vmux = 9 ,
. amux = 1 ,
} } ,
} ,
2005-11-08 21:37:07 -08:00
} ;
2005-11-08 21:38:27 -08:00
const unsigned int em28xx_bcount = ARRAY_SIZE ( em28xx_boards ) ;
2005-11-08 21:37:07 -08:00
/* table of devices that work with this driver */
2005-11-08 21:38:27 -08:00
struct usb_device_id em28xx_id_table [ ] = {
2005-11-08 21:37:24 -08:00
{ USB_DEVICE ( 0xeb1a , 0x2800 ) , . driver_info = EM2800_BOARD_UNKNOWN } ,
2005-11-08 21:38:05 -08:00
{ USB_DEVICE ( 0xeb1a , 0x2820 ) , . driver_info = EM2820_BOARD_MSI_VOX_USB_2 } ,
2005-11-08 21:37:07 -08:00
{ USB_DEVICE ( 0x0ccd , 0x0036 ) , . driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 } ,
{ USB_DEVICE ( 0x2304 , 0x0208 ) , . driver_info = EM2820_BOARD_PINNACLE_USB_2 } ,
{ USB_DEVICE ( 0x2040 , 0x4200 ) , . driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 } ,
2005-11-08 21:38:15 -08:00
{ USB_DEVICE ( 0x2304 , 0x0207 ) , . driver_info = EM2820_BOARD_PINNACLE_DVC_90 } ,
2006-02-07 06:25:39 -02:00
{ USB_DEVICE ( 0x2040 , 0x6500 ) , . driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 } ,
{ USB_DEVICE ( 0x0ccd , 0x0042 ) , . driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS } ,
2006-02-07 06:14:16 +01:00
{ USB_DEVICE ( 0x0ccd , 0x0047 ) , . driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS } ,
2005-11-08 21:37:07 -08:00
{ } ,
} ;
2006-01-23 17:11:10 -02:00
void em28xx_pre_card_setup ( struct em28xx * dev )
{
/* request some modules */
switch ( dev - > model ) {
2006-02-07 06:14:16 +01:00
case EM2880_BOARD_TERRATEC_PRODIGY_XS :
2006-02-07 06:25:39 -02:00
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 :
case EM2880_BOARD_TERRATEC_HYBRID_XS :
2006-01-23 17:11:10 -02:00
{
em28xx_write_regs_req ( dev , 0x00 , 0x08 , " \x7d " , 1 ) ; // reset through GPIO?
break ;
}
}
}
2005-11-08 21:38:27 -08:00
void em28xx_card_setup ( struct em28xx * dev )
2005-11-08 21:37:07 -08:00
{
/* request some modules */
2006-01-23 17:11:10 -02:00
switch ( dev - > model ) {
case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 :
{
struct tveeprom tv ;
2005-11-08 21:37:07 -08:00
# ifdef CONFIG_MODULES
2006-01-23 17:11:10 -02:00
request_module ( " tveeprom " ) ;
request_module ( " ir-kbd-i2c " ) ;
request_module ( " msp3400 " ) ;
2005-11-08 21:37:07 -08:00
# endif
2006-01-23 17:11:10 -02:00
/* Call first TVeeprom */
2005-11-08 21:37:07 -08:00
2006-01-23 17:11:10 -02:00
dev - > i2c_client . addr = 0xa0 > > 1 ;
tveeprom_hauppauge_analog ( & dev - > i2c_client , & tv , dev - > eedata ) ;
2005-11-08 21:37:07 -08:00
2006-01-23 17:11:10 -02:00
dev - > tuner_type = tv . tuner_type ;
if ( tv . audio_processor = = AUDIO_CHIP_MSP34XX ) {
dev - > i2s_speed = 2048000 ;
dev - > has_msp34xx = 1 ;
} else
dev - > has_msp34xx = 0 ;
break ;
}
2006-02-07 06:25:39 -02:00
case EM2820_BOARD_KWORLD_PVRTV2800RF :
{
em28xx_write_regs_req ( dev , 0x00 , 0x08 , " \xf9 " , 1 ) ; // GPIO enables sound on KWORLD PVR TV 2800RF
break ;
}
2005-11-08 21:37:07 -08:00
}
}
2005-11-08 21:38:27 -08:00
EXPORT_SYMBOL ( em28xx_boards ) ;
EXPORT_SYMBOL ( em28xx_bcount ) ;
EXPORT_SYMBOL ( em28xx_id_table ) ;
2005-11-08 21:37:07 -08:00
2005-11-08 21:38:27 -08:00
MODULE_DEVICE_TABLE ( usb , em28xx_id_table ) ;