diff options
author | Mauro Carvalho Chehab <devnull@localhost> | 2005-10-28 21:07:27 +0000 |
---|---|---|
committer | Mauro Carvalho Chehab <devnull@localhost> | 2005-10-28 21:07:27 +0000 |
commit | d97761fd746e75acb55fae2af528ea2dc7e87999 (patch) | |
tree | 07e73c10495392ea9221e1440cb44b036ed533f3 /linux | |
parent | 02263b8edde6c350163da2b43cda45b665c40429 (diff) | |
download | mediapointer-dvb-s2-d97761fd746e75acb55fae2af528ea2dc7e87999.tar.gz mediapointer-dvb-s2-d97761fd746e75acb55fae2af528ea2dc7e87999.tar.bz2 |
- module em2820 renamed to em28xx and moved to V4L dir.
Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Diffstat (limited to 'linux')
-rw-r--r-- | linux/Documentation/video4linux/CARDLIST.em2820 | 10 | ||||
-rw-r--r-- | linux/drivers/media/video/em28xx/em28xx-cards.c | 11 | ||||
-rw-r--r-- | linux/drivers/media/video/em28xx/em28xx-core.c | 9 | ||||
-rw-r--r-- | linux/drivers/media/video/em28xx/em28xx-i2c.c | 11 | ||||
-rw-r--r-- | linux/drivers/media/video/em28xx/em28xx-input.c | 40 | ||||
-rw-r--r-- | linux/drivers/media/video/em28xx/em28xx-video.c | 22 | ||||
-rw-r--r-- | linux/drivers/usb/media/em2820-cards.c | 291 | ||||
-rw-r--r-- | linux/drivers/usb/media/em2820-core.c | 838 | ||||
-rw-r--r-- | linux/drivers/usb/media/em2820-i2c.c | 587 | ||||
-rw-r--r-- | linux/drivers/usb/media/em2820-input.c | 183 | ||||
-rw-r--r-- | linux/drivers/usb/media/em2820-video.c | 2091 | ||||
-rw-r--r-- | linux/drivers/usb/media/em2820.h | 514 |
12 files changed, 46 insertions, 4561 deletions
diff --git a/linux/Documentation/video4linux/CARDLIST.em2820 b/linux/Documentation/video4linux/CARDLIST.em2820 deleted file mode 100644 index a0c7cad20..000000000 --- a/linux/Documentation/video4linux/CARDLIST.em2820 +++ /dev/null @@ -1,10 +0,0 @@ - 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800] - 1 -> Unknown EM2820/2840 video grabber (em2820/em2840) - 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036] - 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208] - 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200] - 5 -> MSI VOX USB 2.0 (em2820/em2840) [eb1a:2820] - 6 -> Terratec Cinergy 200 USB (em2800) - 7 -> Leadtek Winfast USB II (em2800) - 8 -> Kworld USB2800 (em2800) - 9 -> Pinnacle Dazzle DVC 90 (em2820/em2840) [2304:0207] diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index e3db795a2..60f38316e 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -1,11 +1,10 @@ /* - em2820-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices + em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices - Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> - Ludovico Cavedon <cavedon@sssup.it> + Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> + Markus Rechberger <mrechberger@gmail.com> Mauro Carvalho Chehab <mchehab@brturbo.com.br> - - Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> + Sascha Sommer <saschasommer@freenet.de> 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 @@ -34,7 +33,7 @@ #include <media/tveeprom.h> #include "msp3400.h" -#include "em2820.h" +#include "em28xx.h" struct em2820_board em2820_boards[] = { [EM2800_BOARD_UNKNOWN] = { diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index ce110cc96..49821c3fb 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -1,11 +1,10 @@ /* em2820-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices - Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> - Ludovico Cavedon <cavedon@sssup.it> + Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> + Markus Rechberger <mrechberger@gmail.com> Mauro Carvalho Chehab <mchehab@brturbo.com.br> - - Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> + Sascha Sommer <saschasommer@freenet.de> 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 @@ -29,7 +28,7 @@ #include <linux/usb.h> #include <linux/vmalloc.h> -#include "em2820.h" +#include "em28xx.h" /* #define ENABLE_DEBUG_ISOC_FRAMES */ diff --git a/linux/drivers/media/video/em28xx/em28xx-i2c.c b/linux/drivers/media/video/em28xx/em28xx-i2c.c index 5f42bb961..100c7bca3 100644 --- a/linux/drivers/media/video/em28xx/em28xx-i2c.c +++ b/linux/drivers/media/video/em28xx/em28xx-i2c.c @@ -1,11 +1,10 @@ /* - em2820-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices + em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices - Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> - Ludovico Cavedon <cavedon@sssup.it> + Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> + Markus Rechberger <mrechberger@gmail.com> Mauro Carvalho Chehab <mchehab@brturbo.com.br> - - Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> + Sascha Sommer <saschasommer@freenet.de> 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 @@ -28,7 +27,7 @@ #include <linux/i2c.h> #include <linux/video_decoder.h> -#include "em2820.h" +#include "em28xx.h" #include <media/tuner.h> /* ----------------------------------------------------------- */ diff --git a/linux/drivers/media/video/em28xx/em28xx-input.c b/linux/drivers/media/video/em28xx/em28xx-input.c index 2780f683d..fcde34f30 100644 --- a/linux/drivers/media/video/em28xx/em28xx-input.c +++ b/linux/drivers/media/video/em28xx/em28xx-input.c @@ -1,22 +1,24 @@ /* - * $Id: em28xx-input.c,v 1.6 2005/10/18 14:16:40 mchehab Exp $ - * - * handle saa7134 IR remotes via linux kernel input layer. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + handle em28xx IR remotes via linux kernel input layer. + + Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> + Markus Rechberger <mrechberger@gmail.com> + Mauro Carvalho Chehab <mchehab@brturbo.com.br> + Sascha Sommer <saschasommer@freenet.de> + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/module.h> @@ -29,7 +31,7 @@ #include <linux/usb.h> #include "compat.h" -#include "em2820.h" +#include "em28xx.h" static unsigned int disable_ir = 0; module_param(disable_ir, int, 0444); diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index 19088890d..59427b561 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -1,11 +1,10 @@ /* - em2820-video.c - driver for Empia EM2800/EM2820/2840 USB video capture devices + em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB video capture devices - Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> - Ludovico Cavedon <cavedon@sssup.it> + Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> + Markus Rechberger <mrechberger@gmail.com> Mauro Carvalho Chehab <mchehab@brturbo.com.br> - - Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> + Sascha Sommer <saschasommer@freenet.de> 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 @@ -30,15 +29,16 @@ #include <linux/i2c.h> #include <linux/video_decoder.h> -#include "em2820.h" +#include "em28xx.h" #include <media/tuner.h> -#define DRIVER_AUTHOR "Markus Rechberger <mrechberger@gmail.com>, " \ - "Ludovico Cavedon <cavedon@sssup.it>, " \ - "Mauro Carvalho Chehab <mchehab@brturbo.com.br>" +#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ + "Markus Rechberger <mrechberger@gmail.com>, " \ + "Mauro Carvalho Chehab <mchehab@brturbo.com.br>, " \ + "Sascha Sommer <saschasommer@freenet.de>" -#define DRIVER_NAME "em2820" -#define DRIVER_DESC "Empia em2820 based USB video device driver" +#define DRIVER_NAME "em28xx" +#define DRIVER_DESC "Empia em28xx based USB video device driver" #define EM2820_VERSION_CODE KERNEL_VERSION(0, 0, 1) #define em2820_videodbg(fmt, arg...) do {\ diff --git a/linux/drivers/usb/media/em2820-cards.c b/linux/drivers/usb/media/em2820-cards.c deleted file mode 100644 index e3db795a2..000000000 --- a/linux/drivers/usb/media/em2820-cards.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - em2820-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices - - Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> - Ludovico Cavedon <cavedon@sssup.it> - Mauro Carvalho Chehab <mchehab@brturbo.com.br> - - Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> - - 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 02139, 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 "compat.h" -#include <media/tuner.h> -#include <media/audiochip.h> -#include <media/tveeprom.h> -#include "msp3400.h" - -#include "em2820.h" - -struct em2820_board em2820_boards[] = { - [EM2800_BOARD_UNKNOWN] = { - .name = "Unknown EM2800 video grabber", - .is_em2800 = 1, - .vchannels = 2, - .norm = VIDEO_MODE_PAL, - .tda9887_conf = TDA9887_PRESENT, - .has_tuner = 1, - .decoder = EM2820_SAA7113, - .input = {{ - .type = EM2820_VMUX_COMPOSITE1, - .vmux = 0, - .amux = 1, - },{ - .type = EM2820_VMUX_SVIDEO, - .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, - .decoder = EM2820_SAA7113, - .input = {{ - .type = EM2820_VMUX_COMPOSITE1, - .vmux = 0, - .amux = 1, - },{ - .type = EM2820_VMUX_SVIDEO, - .vmux = 9, - .amux = 1, - }}, - }, - [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, - .decoder = EM2820_SAA7113, - .input = {{ - .type = EM2820_VMUX_TELEVISION, - .vmux = 2, - .amux = 0, - },{ - .type = EM2820_VMUX_COMPOSITE1, - .vmux = 0, - .amux = 1, - },{ - .type = EM2820_VMUX_SVIDEO, - .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, - .decoder = EM2820_SAA7113, - .input = {{ - .type = EM2820_VMUX_TELEVISION, - .vmux = 2, - .amux = 0, - },{ - .type = EM2820_VMUX_COMPOSITE1, - .vmux = 0, - .amux = 1, - },{ - .type = EM2820_VMUX_SVIDEO, - .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, - .decoder = EM2820_TVP5150, - .has_msp34xx = 1, - /*FIXME: S-Video not tested */ - .input = {{ - .type = EM2820_VMUX_TELEVISION, - .vmux = 0, - .amux = 0, - },{ - .type = EM2820_VMUX_SVIDEO, - .vmux = 2, - .amux = 1, - }}, - }, - [EM2820_BOARD_MSI_VOX_USB_2] = { - .name = "MSI VOX USB 2.0", - .vchannels = 3, - .norm = VIDEO_MODE_PAL, - .tuner_type = TUNER_LG_PAL_NEW_TAPC, - .tda9887_conf = TDA9887_PRESENT|TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE, - .has_tuner = 1, - .decoder = EM2820_SAA7114, - .input = {{ - .type = EM2820_VMUX_TELEVISION, - .vmux = 4, - .amux = 0, - },{ - .type = EM2820_VMUX_COMPOSITE1, - .vmux = 0, - .amux = 1, - },{ - .type = EM2820_VMUX_SVIDEO, - .vmux = 9, - .amux = 1, - }}, - }, - [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, - .decoder = EM2820_SAA7113, - .input = {{ - .type = EM2820_VMUX_TELEVISION, - .vmux = 2, - .amux = 0, - },{ - .type = EM2820_VMUX_COMPOSITE1, - .vmux = 0, - .amux = 1, - },{ - .type = EM2820_VMUX_SVIDEO, - .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, - .decoder = EM2820_SAA7113, - .input = {{ - .type = EM2820_VMUX_TELEVISION, - .vmux = 2, - .amux = 0, - },{ - .type = EM2820_VMUX_COMPOSITE1, - .vmux = 0, - .amux = 1, - },{ - .type = EM2820_VMUX_SVIDEO, - .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, - .decoder = EM2820_SAA7113, - .input = {{ - .type = EM2820_VMUX_TELEVISION, - .vmux = 2, - .amux = 0, - },{ - .type = EM2820_VMUX_COMPOSITE1, - .vmux = 0, - .amux = 1, - },{ - .type = EM2820_VMUX_SVIDEO, - .vmux = 9, - .amux = 1, - }}, - }, - [EM2820_BOARD_PINNACLE_DVC_90] = { - .name = "Pinnacle Dazzle DVC 90", - .vchannels = 3, - .norm = VIDEO_MODE_PAL, - .has_tuner = 0, - .decoder = EM2820_SAA7113, - .input = {{ - .type = EM2820_VMUX_COMPOSITE1, - .vmux = 0, - .amux = 1, - },{ - .type = EM2820_VMUX_SVIDEO, - .vmux = 9, - .amux = 1, - }}, - }, -}; -const unsigned int em2820_bcount = ARRAY_SIZE(em2820_boards); - -/* table of devices that work with this driver */ -struct usb_device_id em2820_id_table [] = { - { USB_DEVICE(0xeb1a, 0x2800), .driver_info = EM2800_BOARD_UNKNOWN }, - { USB_DEVICE(0xeb1a, 0x2820), .driver_info = EM2820_BOARD_MSI_VOX_USB_2 }, - { 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 }, - { USB_DEVICE(0x2304, 0x0207), .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, - { }, -}; - -void em2820_card_setup(struct em2820 *dev) -{ - /* request some modules */ - if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) { - struct tveeprom tv; -#ifdef CONFIG_MODULES - request_module("tveeprom"); - request_module("ir-kbd-i2c"); -#endif - /* Call first TVeeprom */ - - dev->i2c_client.addr = 0xa0 >> 1; - tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata); - - dev->tuner_type= tv.tuner_type; - if (tv.audio_processor == AUDIO_CHIP_MSP34XX) { - dev->has_msp34xx=1; - } else dev->has_msp34xx=0; -#if 1 - em2820_write_regs_req(dev,0x06,0x00,"\x40",1);// Serial Bus Frequency Select Register - em2820_write_regs_req(dev,0x0f,0x00,"\x87",1);// XCLK Frequency Select Register - em2820_write_regs_req(dev,0x88,0x0d,"\xd0",1); -#endif - } -} - -EXPORT_SYMBOL(em2820_boards); -EXPORT_SYMBOL(em2820_bcount); -EXPORT_SYMBOL(em2820_id_table); - -MODULE_DEVICE_TABLE (usb, em2820_id_table); diff --git a/linux/drivers/usb/media/em2820-core.c b/linux/drivers/usb/media/em2820-core.c deleted file mode 100644 index ce110cc96..000000000 --- a/linux/drivers/usb/media/em2820-core.c +++ /dev/null @@ -1,838 +0,0 @@ -/* - em2820-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices - - Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> - Ludovico Cavedon <cavedon@sssup.it> - Mauro Carvalho Chehab <mchehab@brturbo.com.br> - - Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> - - 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 02139, USA. - */ - -#include <linux/init.h> -#include <linux/list.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/usb.h> -#include <linux/vmalloc.h> - -#include "em2820.h" - -/* #define ENABLE_DEBUG_ISOC_FRAMES */ - -unsigned int core_debug = 0; -module_param(core_debug,int,0644); -MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); - -#define em2820_coredbg(fmt, arg...) do {\ - if (core_debug) \ - printk(KERN_INFO "%s %s :"fmt, \ - dev->name, __FUNCTION__, ##arg); } while (0) - -unsigned int reg_debug = 0; -module_param(reg_debug,int,0644); -MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); - -#define em2820_regdbg(fmt, arg...) do {\ - if (reg_debug) \ - printk(KERN_INFO "%s %s :"fmt, \ - dev->name, __FUNCTION__, ##arg); } while (0) - -unsigned int isoc_debug = 0; -module_param(isoc_debug,int,0644); -MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]"); - -#define em2820_isocdbg(fmt, arg...) do {\ - if (isoc_debug) \ - printk(KERN_INFO "%s %s :"fmt, \ - dev->name, __FUNCTION__, ##arg); } while (0) - -static int alt = EM2820_PINOUT; -module_param(alt, int, 0644); -MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); - -/* ------------------------------------------------------------------ */ -/* debug help functions */ - -static const char *v4l1_ioctls[] = { - "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT", - "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ", - "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT", - "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", - "SMICROCODE", "GVBIFMT", "SVBIFMT" }; -#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) - -static const char *v4l2_ioctls[] = { - "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT", - "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF", - "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON", - "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD", - "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER", - "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL", - "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43", - "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT", - "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR", - "S_MODULATOR" -}; -#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) - -void em2820_print_ioctl(char *name, unsigned int cmd) -{ - char *dir; - - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: dir = "--"; break; - case _IOC_READ: dir = "r-"; break; - case _IOC_WRITE: dir = "-w"; break; - case _IOC_READ | _IOC_WRITE: dir = "rw"; break; - default: dir = "??"; break; - } - switch (_IOC_TYPE(cmd)) { - case 'v': - printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n", - name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ? - v4l1_ioctls[_IOC_NR(cmd)] : "???"); - break; - case 'V': - printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n", - name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ? - v4l2_ioctls[_IOC_NR(cmd)] : "???"); - break; - default: - printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n", - name, cmd, dir, _IOC_NR(cmd)); - } -} - -static void *rvmalloc(size_t size) -{ - void *mem; - unsigned long adr; - - size = PAGE_ALIGN(size); - - mem = vmalloc_32((unsigned long)size); - if (!mem) - return NULL; - - memset(mem, 0, size); - - adr = (unsigned long)mem; - while (size > 0) { - SetPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - return mem; -} - -static void rvfree(void *mem, size_t size) -{ - unsigned long adr; - - if (!mem) - return; - - size = PAGE_ALIGN(size); - - adr = (unsigned long)mem; - while (size > 0) { - ClearPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - vfree(mem); -} - -/* - * em2820_request_buffers() - * allocate a number of buffers - */ -u32 em2820_request_buffers(struct em2820 *dev, u32 count) -{ - const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */ - void *buff = NULL; - u32 i; - em2820_coredbg("requested %i buffers with size %i", count, imagesize); - if (count > EM2820_NUM_FRAMES) - count = EM2820_NUM_FRAMES; - - dev->num_frames = count; - while (dev->num_frames > 0) { - if ((buff = rvmalloc(dev->num_frames * imagesize))) - break; - dev->num_frames--; - } - - for (i = 0; i < dev->num_frames; i++) { - dev->frame[i].bufmem = buff + i * imagesize; - dev->frame[i].buf.index = i; - dev->frame[i].buf.m.offset = i * imagesize; - dev->frame[i].buf.length = dev->frame_size; - dev->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - dev->frame[i].buf.sequence = 0; - dev->frame[i].buf.field = V4L2_FIELD_NONE; - dev->frame[i].buf.memory = V4L2_MEMORY_MMAP; - dev->frame[i].buf.flags = 0; - } - return dev->num_frames; -} - -/* - * em2820_queue_unusedframes() - * add all frames that are not currently in use to the inbuffer queue - */ -void em2820_queue_unusedframes(struct em2820 *dev) -{ - unsigned long lock_flags; - u32 i; - - for (i = 0; i < dev->num_frames; i++) - if (dev->frame[i].state == F_UNUSED) { - dev->frame[i].state = F_QUEUED; - spin_lock_irqsave(&dev->queue_lock, lock_flags); - list_add_tail(&dev->frame[i].frame, &dev->inqueue); - spin_unlock_irqrestore(&dev->queue_lock, lock_flags); - } -} - -/* - * em2820_release_buffers() - * free frame buffers - */ -void em2820_release_buffers(struct em2820 *dev) -{ - if (dev->num_frames) { - rvfree(dev->frame[0].bufmem, - dev->num_frames * PAGE_ALIGN(dev->frame[0].buf.length)); - dev->num_frames = 0; - } -} - -/* - * em2820_read_reg_req() - * reads data from the usb device specifying bRequest - */ -int em2820_read_reg_req_len(struct em2820 *dev, u8 req, u16 reg, - char *buf, int len) -{ - int ret, byte; - - em2820_regdbg("req=%02x, reg=%02x ", req, reg); - - ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0000, reg, buf, len, HZ); - - if (reg_debug){ - printk(ret < 0 ? " failed!\n" : "%02x values: ", ret); - for (byte = 0; byte < len; byte++) { - printk(" %02x", buf[byte]); - } - printk("\n"); - } - - return ret; -} - -/* - * em2820_read_reg_req() - * reads data from the usb device specifying bRequest - */ -int em2820_read_reg_req(struct em2820 *dev, u8 req, u16 reg) -{ - u8 val; - int ret; - - em2820_regdbg("req=%02x, reg=%02x:", req, reg); - - ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0000, reg, &val, 1, HZ); - - if (reg_debug) - printk(ret < 0 ? " failed!\n" : "%02x\n", val); - - if (ret < 0) - return ret; - - return val; -} - -int em2820_read_reg(struct em2820 *dev, u16 reg) -{ - return em2820_read_reg_req(dev, USB_REQ_GET_STATUS, reg); -} - -/* - * em2820_write_regs_req() - * sends data to the usb device, specifying bRequest - */ -int em2820_write_regs_req(struct em2820 *dev, u8 req, u16 reg, char *buf, - int len) -{ - int ret; - - /*usb_control_msg seems to expect a kmalloced buffer */ - unsigned char *bufs = kmalloc(len, GFP_KERNEL); - - em2820_regdbg("req=%02x reg=%02x:", req, reg); - - if (reg_debug) { - int i; - for (i = 0; i < len; ++i) - printk (" %02x", (unsigned char)buf[i]); - printk ("\n"); - } - - if (!bufs) - return -ENOMEM; - memcpy(bufs, buf, len); - ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0000, reg, bufs, len, HZ); - mdelay(5); /* FIXME: magic number */ - kfree(bufs); - return ret; -} - -int em2820_write_regs(struct em2820 *dev, u16 reg, char *buf, int len) -{ - return em2820_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len); -} - -/* - * em2820_write_reg_bits() - * sets only some bits (specified by bitmask) of a register, by first reading - * the actual value - */ -int em2820_write_reg_bits(struct em2820 *dev, u16 reg, u8 val, - u8 bitmask) -{ - int oldval; - u8 newval; - if ((oldval = em2820_read_reg(dev, reg)) < 0) - return oldval; - newval = (((u8) oldval) & ~bitmask) | (val & bitmask); - return em2820_write_regs(dev, reg, &newval, 1); -} - -/* - * em2820_write_ac97() - * write a 16 bit value to the specified AC97 address (LSB first!) - */ -int em2820_write_ac97(struct em2820 *dev, u8 reg, u8 * val) -{ - int ret; - u8 addr = reg & 0x7f; - if ((ret = em2820_write_regs(dev, AC97LSB_REG, val, 2)) < 0) - return ret; - if ((ret = em2820_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0) - return ret; - if ((ret = em2820_read_reg(dev, AC97BUSY_REG)) < 0) - return ret; - else if (((u8) ret) & 0x01) { - em2820_warn ("AC97 command still being exectuted: not handled properly!\n"); - } - return 0; -} - -int em2820_audio_analog_set(struct em2820 *dev) -{ - char s[2] = { 0x00, 0x00 }; - s[0] |= 0x1f - dev->volume; - s[1] |= 0x1f - dev->volume; - if (dev->mute) - s[1] |= 0x80; - return em2820_write_ac97(dev, MASTER_AC97, s); -} - -#if 0 -int em2820_audio_analog_mute(struct em2820 *dev, int mute) -{ - /* (un)mute master mixer with maximum volume level */ - return em2820_write_ac97(dev, MASTER_AC97, - mute ? "\x00\x80" : "\x00\x00"); -} -#endif - -int em2820_colorlevels_set_default(struct em2820 *dev) -{ - em2820_write_regs(dev, YGAIN_REG, "\x10", 1); /* contrast */ - em2820_write_regs(dev, YOFFSET_REG, "\x00", 1); /* brightness */ - em2820_write_regs(dev, UVGAIN_REG, "\x10", 1); /* saturation */ - em2820_write_regs(dev, UOFFSET_REG, "\x00", 1); - em2820_write_regs(dev, VOFFSET_REG, "\x00", 1); - em2820_write_regs(dev, SHARPNESS_REG, "\x00", 1); - - em2820_write_regs(dev, GAMMA_REG, "\x20", 1); - em2820_write_regs(dev, RGAIN_REG, "\x20", 1); - em2820_write_regs(dev, GGAIN_REG, "\x20", 1); - em2820_write_regs(dev, BGAIN_REG, "\x20", 1); - em2820_write_regs(dev, ROFFSET_REG, "\x00", 1); - em2820_write_regs(dev, GOFFSET_REG, "\x00", 1); - return em2820_write_regs(dev, BOFFSET_REG, "\x00", 1); -} - -int em2820_capture_start(struct em2820 *dev, int start) -{ - int ret; - /* FIXME: which is the best order? */ - /* video registers are sampled by VREF */ - if ((ret = em2820_write_reg_bits(dev, USBSUSP_REG, start ? 0x10 : 0x00, - 0x10)) < 0) - return ret; - /* enable video capture */ - return em2820_write_regs(dev, VINENABLE_REG, start ? "\x67" : "\x27", 1); -} - -int em2820_outfmt_set_yuv422(struct em2820 *dev) -{ - em2820_write_regs(dev, OUTFMT_REG, "\x34", 1); - em2820_write_regs(dev, VINMODE_REG, "\x10", 1); - return em2820_write_regs(dev, VINCTRL_REG, "\x11", 1); -} - -int em2820_accumulator_set(struct em2820 *dev, u8 xmin, u8 xmax, u8 ymin, - u8 ymax) -{ - em2820_coredbg("em2820 Scale: (%d,%d)-(%d,%d)\n", xmin, ymin, xmax, ymax); - - em2820_write_regs(dev, XMIN_REG, &xmin, 1); - em2820_write_regs(dev, XMAX_REG, &xmax, 1); - em2820_write_regs(dev, YMIN_REG, &ymin, 1); - return em2820_write_regs(dev, YMAX_REG, &ymax, 1); -} - -int em2820_capture_area_set(struct em2820 *dev, u8 hstart, u8 vstart, - u16 width, u16 height) -{ - u8 cwidth = width; - u8 cheight = height; - u8 overflow = (height >> 7 & 0x02) | (width >> 8 & 0x01); - - em2820_coredbg("em2820 Area Set: (%d,%d)\n", (width | (overflow & 2) << 7), - (height | (overflow & 1) << 8)); - - em2820_write_regs(dev, HSTART_REG, &hstart, 1); - em2820_write_regs(dev, VSTART_REG, &vstart, 1); - em2820_write_regs(dev, CWIDTH_REG, &cwidth, 1); - em2820_write_regs(dev, CHEIGHT_REG, &cheight, 1); - return em2820_write_regs(dev, OFLOW_REG, &overflow, 1); -} - -int em2820_scaler_set(struct em2820 *dev, u16 h, u16 v) -{ - u8 mode; - /* the em2800 scaler only supports scaling down to 50% */ - if(dev->is_em2800) - mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); - else { - u8 buf[2]; - buf[0] = h; - buf[1] = h >> 8; - em2820_write_regs(dev, HSCALELOW_REG, (char *)buf, 2); - buf[0] = v; - buf[1] = v >> 8; - em2820_write_regs(dev, VSCALELOW_REG, (char *)buf, 2); - /* it seems that both H and V scalers must be active to work correctly */ - mode = (h || v)? 0x30: 0x00; - } - return em2820_write_reg_bits(dev, COMPR_REG, mode, 0x30); -} - -/* FIXME: this only function read values from dev */ -int em2820_resolution_set(struct em2820 *dev) -{ - int width, height; - width = norm_maxw(dev); - height = norm_maxh(dev) >> 1; - - em2820_outfmt_set_yuv422(dev); - em2820_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); - em2820_capture_area_set(dev, 0, 0, width >> 2, height >> 2); - return em2820_scaler_set(dev, dev->hscale, dev->vscale); -} - - -/******************* isoc transfer handling ****************************/ - -#ifdef ENABLE_DEBUG_ISOC_FRAMES -static void em2820_isoc_dump(struct urb *urb, struct pt_regs *regs) -{ - int len = 0; - int ntrans = 0; - int i; - - printk(KERN_DEBUG "isocIrq: sf=%d np=%d ec=%x\n", - urb->start_frame, urb->number_of_packets, - urb->error_count); - for (i = 0; i < urb->number_of_packets; i++) { - unsigned char *buf = - urb->transfer_buffer + - urb->iso_frame_desc[i].offset; - int alen = urb->iso_frame_desc[i].actual_length; - if (alen > 0) { - if (buf[0] == 0x88) { - ntrans++; - len += alen; - } else if (buf[0] == 0x22) { - printk(KERN_DEBUG - "= l=%d nt=%d bpp=%d\n", - len - 4 * ntrans, ntrans, - ntrans == 0 ? 0 : len / ntrans); - ntrans = 1; - len = alen; - } else - printk(KERN_DEBUG "!\n"); - } - printk(KERN_DEBUG " n=%d s=%d al=%d %x\n", i, - urb->iso_frame_desc[i].status, - urb->iso_frame_desc[i].actual_length, - (unsigned int) - *((unsigned char *)(urb->transfer_buffer + - urb->iso_frame_desc[i]. - offset))); - } -} -#endif - -static inline int em2820_isoc_video(struct em2820 *dev,struct em2820_frame_t **f, - unsigned long *lock_flags, unsigned char buf) -{ - if (!(buf & 0x01)) { - if ((*f)->state == F_GRABBING) { - /*previous frame is incomplete */ - if ((*f)->fieldbytesused < dev->field_size) { - (*f)->state = F_ERROR; - em2820_isocdbg ("dropping incomplete bottom field (%i missing bytes)", - dev->field_size-(*f)->fieldbytesused); - } else { - (*f)->state = F_DONE; - (*f)->buf.bytesused = dev->frame_size; - } - } - if ((*f)->state == F_DONE || (*f)->state == F_ERROR) { - /* move current frame to outqueue and get next free buffer from inqueue */ - spin_lock_irqsave(&dev-> queue_lock, *lock_flags); - list_move_tail(&(*f)->frame, &dev->outqueue); - if (!list_empty(&dev->inqueue)) - (*f) = list_entry(dev-> inqueue.next, - struct em2820_frame_t,frame); - else - (*f) = NULL; - spin_unlock_irqrestore(&dev->queue_lock,*lock_flags); - } - if (!(*f)) { - em2820_isocdbg ("new frame but no buffer is free"); - return -1; - } - do_gettimeofday(&(*f)->buf.timestamp); - (*f)->buf.sequence = ++dev->frame_count; - (*f)->buf.field = V4L2_FIELD_INTERLACED; - (*f)->state = F_GRABBING; - (*f)->buf.bytesused = 0; - (*f)->top_field = 1; - (*f)->fieldbytesused = 0; - } else { - /* acquiring bottom field */ - if ((*f)->state == F_GRABBING) { - if (!(*f)->top_field) { - (*f)->state = F_ERROR; - em2820_isocdbg ("unexpected begin of bottom field; discarding it"); - } else if ((*f)-> fieldbytesused < dev->field_size - 172) { - (*f)->state = F_ERROR; - em2820_isocdbg ("dropping incomplete top field (%i missing bytes)", - dev->field_size-(*f)->fieldbytesused); - } else { - (*f)->top_field = 0; - (*f)->fieldbytesused = 0; - } - } - } - return (0); -} - -static inline void em2820_isoc_video_copy(struct em2820 *dev, - struct em2820_frame_t **f, unsigned char *buf, int len) -{ - void *fieldstart, *startwrite, *startread; - int linesdone, currlinedone, offset, lencopy,remain; - - if(dev->frame_size != (*f)->buf.length){ - em2820_err("frame_size %i and buf.length %i are different!!!\n",dev->frame_size,(*f)->buf.length); - return; - } - - if ((*f)->fieldbytesused + len > dev->field_size) - len =dev->field_size - (*f)->fieldbytesused; - - if (buf[0] != 0x88 && buf[0] != 0x22) { - em2820_isocdbg("frame is not complete\n"); - startread = buf; - len+=4; - } else - startread = buf + 4; - - remain = len; - - if ((*f)->top_field) - fieldstart = (*f)->bufmem; - else - fieldstart = (*f)->bufmem + dev->bytesperline; - - linesdone = (*f)->fieldbytesused / dev->bytesperline; - currlinedone = (*f)->fieldbytesused % dev->bytesperline; - offset = linesdone * dev->bytesperline * 2 + currlinedone; - startwrite = fieldstart + offset; - lencopy = dev->bytesperline - currlinedone; - lencopy = lencopy > remain ? remain : lencopy; - - memcpy(startwrite, startread, lencopy); - remain -= lencopy; - - while (remain > 0) { - startwrite += lencopy + dev->bytesperline; - startread += lencopy; - if (dev->bytesperline > remain) - lencopy = remain; - else - lencopy = dev->bytesperline; - - memcpy(startwrite, startread, lencopy); - remain -= lencopy; - } - - (*f)->fieldbytesused += len; -} - -/* - * em2820_isoIrq() - * handles the incoming isoc urbs and fills the frames from our inqueue - */ -void em2820_isocIrq(struct urb *urb, struct pt_regs *regs) -{ - struct em2820 *dev = urb->context; - int i, status; - struct em2820_frame_t **f; - unsigned long lock_flags; - - if (!dev) - return; -#ifdef ENABLE_DEBUG_ISOC_FRAMES - if (isoc_debug>1) - em2820_isoc_dump(urb, regs); -#endif - - if (urb->status == -ENOENT) - return; - - f = &dev->frame_current; - - if (dev->stream == STREAM_INTERRUPT) { - dev->stream = STREAM_OFF; - if ((*f)) - (*f)->state = F_QUEUED; - em2820_isocdbg("stream interrupted"); - wake_up_interruptible(&dev->wait_stream); - } - - if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) - return; - - if (dev->stream == STREAM_ON && !list_empty(&dev->inqueue)) { - if (!(*f)) - (*f) = list_entry(dev->inqueue.next, - struct em2820_frame_t, frame); - - for (i = 0; i < urb->number_of_packets; i++) { - unsigned char *buf = urb->transfer_buffer + - urb->iso_frame_desc[i].offset; - int len = urb->iso_frame_desc[i].actual_length - 4; - - if (urb->iso_frame_desc[i].status) { - em2820_isocdbg("data error: [%d] len=%d, status=%d", i, - urb->iso_frame_desc[i].actual_length, - urb->iso_frame_desc[i].status); - if (urb->iso_frame_desc[i].status != -EPROTO) - continue; - } - if (urb->iso_frame_desc[i].actual_length <= 0) { - em2820_isocdbg("packet %d is empty",i); - continue; - } - if (urb->iso_frame_desc[i].actual_length > - dev->max_pkt_size) { - em2820_isocdbg("packet bigger than packet size"); - continue; - } - /*new frame */ - if (buf[0] == 0x22 && buf[1] == 0x5a) { - em2820_isocdbg("Video frame, length=%i!",len); - - if (em2820_isoc_video(dev,f,&lock_flags,buf[2])) - break; - } else if (buf[0]==0x33 && buf[1]==0x95 && buf[2]==0x00) { - em2820_isocdbg("VBI HEADER!!!"); - } - - /* actual copying */ - if ((*f)->state == F_GRABBING) { - em2820_isoc_video_copy(dev,f,buf, len); - } - } - } - - for (i = 0; i < urb->number_of_packets; i++) { - urb->iso_frame_desc[i].status = 0; - urb->iso_frame_desc[i].actual_length = 0; - } - - urb->status = 0; - if ((status = usb_submit_urb(urb, GFP_ATOMIC))) { - em2820_errdev("resubmit of urb failed (error=%i)\n", status); - dev->state |= DEV_MISCONFIGURED; - } - wake_up_interruptible(&dev->wait_frame); - return; -} - -/* - * em2820_uninit_isoc() - * deallocates the buffers and urbs allocated during em2820_init_iosc() - */ -void em2820_uninit_isoc(struct em2820 *dev) -{ - int i; - - for (i = 0; i < EM2820_NUM_BUFS; i++) { - if (dev->urb[i]) { - usb_kill_urb(dev->urb[i]); - if (dev->transfer_buffer[i]){ - usb_buffer_free(dev->udev,(EM2820_NUM_PACKETS*dev->max_pkt_size),dev->transfer_buffer[i],dev->urb[i]->transfer_dma); - } - usb_free_urb(dev->urb[i]); - } - dev->urb[i] = NULL; - dev->transfer_buffer[i] = NULL; - } - em2820_capture_start(dev, 0); -} - -/* - * em2820_init_isoc() - * allocates transfer buffers and submits the urbs for isoc transfer - */ -int em2820_init_isoc(struct em2820 *dev) -{ - /* change interface to 3 which allowes the biggest packet sizes */ - int i, errCode; - const int sb_size = EM2820_NUM_PACKETS * dev->max_pkt_size; - - /* reset streaming vars */ - dev->frame_current = NULL; - dev->frame_count = 0; - - /* allocate urbs */ - for (i = 0; i < EM2820_NUM_BUFS; i++) { - struct urb *urb; - int j, k; - /* allocate transfer buffer */ - urb = usb_alloc_urb(EM2820_NUM_PACKETS, GFP_KERNEL); - if (!urb){ - em2820_errdev("cannot alloc urb %i\n", i); - em2820_uninit_isoc(dev); - return -ENOMEM; - } - dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,&urb->transfer_dma); - if (!dev->transfer_buffer[i]) { - em2820_errdev - ("unable to allocate %i bytes for transfer buffer %i\n", - sb_size, i); - em2820_uninit_isoc(dev); - return -ENOMEM; - } - memset(dev->transfer_buffer[i], 0, sb_size); - urb->dev = dev->udev; - urb->context = dev; - urb->pipe = usb_rcvisocpipe(dev->udev, 0x82); - urb->transfer_flags = URB_ISO_ASAP; - urb->interval = 1; - urb->transfer_buffer = dev->transfer_buffer[i]; - urb->complete = em2820_isocIrq; - urb->number_of_packets = EM2820_NUM_PACKETS; - urb->transfer_buffer_length = sb_size; - for (j = k = 0; j < EM2820_NUM_PACKETS; - j++, k += dev->max_pkt_size) { - urb->iso_frame_desc[j].offset = k; - urb->iso_frame_desc[j].length = - dev->max_pkt_size; - } - dev->urb[i] = urb; - } - - /* submit urbs */ - for (i = 0; i < EM2820_NUM_BUFS; i++) { - errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL); - if (errCode) { - em2820_errdev("submit of urb %i failed (error=%i)\n", i, - errCode); - em2820_uninit_isoc(dev); - return errCode; - } - } - - return 0; -} - -int em2820_set_alternate(struct em2820 *dev) -{ - int errCode, prev_alt = dev->alt; - dev->alt = alt; - if (dev->alt == 0) { - int i; - if(dev->is_em2800){ /* always use the max packet size for em2800 based devices */ - for(i=0;i< EM2820_MAX_ALT; i++) - if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt]) - dev->alt=i; - }else{ - unsigned int min_pkt_size = dev->field_size / 137; /* FIXME: empiric magic number */ - em2820_coredbg("minimum isoc packet size: %u", min_pkt_size); - dev->alt = 7; - for (i = 1; i < EM2820_MAX_ALT; i += 2) /* FIXME: skip even alternate: why do they not work? */ - if (dev->alt_max_pkt_size[i] >= min_pkt_size) { - dev->alt = i; - break; - } - } - } - - if (dev->alt != prev_alt) { - dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt]; - em2820_coredbg("setting alternate %d with wMaxPacketSize=%u", dev->alt, - dev->max_pkt_size); - errCode = usb_set_interface(dev->udev, 0, dev->alt); - if (errCode < 0) { - em2820_errdev - ("cannot change alternate number to %d (error=%i)\n", - dev->alt, errCode); - return errCode; - } - } - return 0; -} diff --git a/linux/drivers/usb/media/em2820-i2c.c b/linux/drivers/usb/media/em2820-i2c.c deleted file mode 100644 index 5f42bb961..000000000 --- a/linux/drivers/usb/media/em2820-i2c.c +++ /dev/null @@ -1,587 +0,0 @@ -/* - em2820-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices - - Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> - Ludovico Cavedon <cavedon@sssup.it> - Mauro Carvalho Chehab <mchehab@brturbo.com.br> - - Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> - - 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 02139, USA. - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/usb.h> -#include <linux/i2c.h> -#include <linux/video_decoder.h> - -#include "em2820.h" -#include <media/tuner.h> - -/* ----------------------------------------------------------- */ - -static unsigned int i2c_scan = 0; -module_param(i2c_scan, int, 0444); -MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); - -static unsigned int i2c_debug = 0; -module_param(i2c_debug, int, 0644); -MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); - -#define dprintk1(lvl,fmt, args...) if (i2c_debug>=lvl) do {\ - printk(fmt, ##args); } while (0) -#define dprintk2(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \ - printk(KERN_DEBUG "%s at %s: " fmt, \ - dev->name, __FUNCTION__, ##args); } while (0) - -/* - * em2800_i2c_send_max4() - * send up to 4 bytes to the i2c device - */ -static int em2800_i2c_send_max4(struct em2820 *dev, unsigned char addr, - char *buf, int len) -{ - int ret; - int write_timeout; - unsigned char b2[6]; - BUG_ON(len < 1 || len > 4); - b2[5] = 0x80 + len - 1; - b2[4] = addr; - b2[3] = buf[0]; - if (len > 1) - b2[2] = buf[1]; - if (len > 2) - b2[1] = buf[2]; - if (len > 3) - b2[0] = buf[3]; - - ret = dev->em2820_write_regs(dev, 4 - len, &b2[4 - len], 2 + len); - if (ret != 2 + len) { - em2820_warn("writting to i2c device failed (error=%i)\n", ret); - return -EIO; - } - for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0; - write_timeout -= 5) { - ret = dev->em2820_read_reg(dev, 0x05); - if (ret == 0x80 + len - 1) - return len; - mdelay(5); - } - em2820_warn("i2c write timed out\n"); - return -EIO; -} - -/* - * em2800_i2c_send_bytes() - */ -static int em2800_i2c_send_bytes(void *data, unsigned char addr, char *buf, - short len) -{ - char *bufPtr = buf; - int ret; - int wrcount = 0; - int count; - int maxLen = 4; - struct em2820 *dev = (struct em2820 *)data; - while (len > 0) { - count = (len > maxLen) ? maxLen : len; - ret = em2800_i2c_send_max4(dev, addr, bufPtr, count); - if (ret > 0) { - len -= count; - bufPtr += count; - wrcount += count; - } else - return (ret < 0) ? ret : -EFAULT; - } - return wrcount; -} - -/* - * em2800_i2c_check_for_device() - * check if there is a i2c_device at the supplied address - */ -static int em2800_i2c_check_for_device(struct em2820 *dev, unsigned char addr) -{ - char msg; - int ret; - int write_timeout; - msg = addr; - ret = dev->em2820_write_regs(dev, 0x04, &msg, 1); - if (ret < 0) { - em2820_warn("setting i2c device address failed (error=%i)\n", - ret); - return ret; - } - msg = 0x84; - ret = dev->em2820_write_regs(dev, 0x05, &msg, 1); - if (ret < 0) { - em2820_warn("preparing i2c read failed (error=%i)\n", ret); - return ret; - } - for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0; - write_timeout -= 5) { - unsigned msg = dev->em2820_read_reg(dev, 0x5); - if (msg == 0x94) - return -ENODEV; - else if (msg == 0x84) - return 0; - mdelay(5); - } - return -ENODEV; -} - -/* - * em2800_i2c_recv_bytes() - * read from the i2c device - */ -static int em2800_i2c_recv_bytes(struct em2820 *dev, unsigned char addr, - char *buf, int len) -{ - int ret; - /* check for the device and set i2c read address */ - ret = em2800_i2c_check_for_device(dev, addr); - if (ret) { - em2820_warn - ("preparing read at i2c address 0x%x failed (error=%i)\n", - addr, ret); - return ret; - } - ret = dev->em2820_read_reg_req_len(dev, 0x0, 0x3, buf, len); - if (ret < 0) { - em2820_warn("reading from i2c device at 0x%x failed (error=%i)", - addr, ret); - return ret; - } - return ret; -} - -/* - * em2820_i2c_send_bytes() - * untested for more than 4 bytes - */ -static int em2820_i2c_send_bytes(void *data, unsigned char addr, char *buf, - short len, int stop) -{ - int wrcount = 0; - struct em2820 *dev = (struct em2820 *)data; - - wrcount = dev->em2820_write_regs_req(dev, stop ? 2 : 3, addr, buf, len); - - return wrcount; -} - -/* - * em2820_i2c_recv_bytes() - * read a byte from the i2c device - */ -static int em2820_i2c_recv_bytes(struct em2820 *dev, unsigned char addr, - char *buf, int len) -{ - int ret; - ret = dev->em2820_read_reg_req_len(dev, 2, addr, buf, len); - if (ret < 0) { - em2820_warn("reading i2c device failed (error=%i)\n", ret); - return ret; - } - if (dev->em2820_read_reg(dev, 0x5) != 0) - return -ENODEV; - return ret; -} - -/* - * em2820_i2c_check_for_device() - * check if there is a i2c_device at the supplied address - */ -static int em2820_i2c_check_for_device(struct em2820 *dev, unsigned char addr) -{ - char msg; - int ret; - msg = addr; - - ret = dev->em2820_read_reg_req(dev, 2, addr); - if (ret < 0) { - em2820_warn("reading from i2c device failed (error=%i)\n", ret); - return ret; - } - if (dev->em2820_read_reg(dev, 0x5) != 0) - return -ENODEV; - return 0; -} - -/* - * em2820_i2c_xfer() - * the main i2c transfer function - */ -static int em2820_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msgs[], int num) -{ - struct em2820 *dev = i2c_adap->algo_data; - int addr, rc, i, byte; - - if (num <= 0) - return 0; - for (i = 0; i < num; i++) { - addr = msgs[i].addr << 1; - dprintk2(2,"%s %s addr=%x len=%d:", - (msgs[i].flags & I2C_M_RD) ? "read" : "write", - i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); - if (!msgs[i].len) { /* no len: check only for device presence */ - if (dev->is_em2800) - rc = em2800_i2c_check_for_device(dev, addr); - else - rc = em2820_i2c_check_for_device(dev, addr); - if (rc < 0) { - dprintk2(2," no device\n"); - return rc; - } - - } else if (msgs[i].flags & I2C_M_RD) { - /* read bytes */ - if (dev->is_em2800) - rc = em2800_i2c_recv_bytes(dev, addr, - msgs[i].buf, - msgs[i].len); - else - rc = em2820_i2c_recv_bytes(dev, addr, - msgs[i].buf, - msgs[i].len); - if (i2c_debug>=2) { - for (byte = 0; byte < msgs[i].len; byte++) { - printk(" %02x", msgs[i].buf[byte]); - } - } - } else { - /* write bytes */ - if (i2c_debug>=2) { - for (byte = 0; byte < msgs[i].len; byte++) - printk(" %02x", msgs[i].buf[byte]); - } - if (dev->is_em2800) - rc = em2800_i2c_send_bytes(dev, addr, - msgs[i].buf, - msgs[i].len); - else - rc = em2820_i2c_send_bytes(dev, addr, - msgs[i].buf, - msgs[i].len, - i == num - 1); - if (rc < 0) - goto err; - } - if (i2c_debug>=2) - printk("\n"); - } - - return num; - err: - dprintk2(2," ERROR: %i\n", rc); - return rc; -} - -static int em2820_i2c_eeprom(struct em2820 *dev, unsigned char *eedata, int len) -{ - unsigned char buf, *p = eedata; - struct em2820_eeprom *em_eeprom = (void *)eedata; - int i, err, size = len, block; - - dev->i2c_client.addr = 0xa0 >> 1; - - /* Check if board has eeprom */ - err = i2c_master_recv(&dev->i2c_client, &buf, 0); - if (err < 0) - return -1; - - buf = 0; - if (1 != (err = i2c_master_send(&dev->i2c_client, &buf, 1))) { - printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", - dev->name, err); - return -1; - } - while (size > 0) { - if (size > 16) - block = 16; - else - block = size; - - if (block != - (err = i2c_master_recv(&dev->i2c_client, p, block))) { - printk(KERN_WARNING - "%s: i2c eeprom read error (err=%d)\n", - dev->name, err); - return -1; - } - size -= block; - p += block; - } - for (i = 0; i < len; i++) { - if (0 == (i % 16)) - printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i); - printk(" %02x", eedata[i]); - if (15 == (i % 16)) - printk("\n"); - } - - printk(KERN_INFO "EEPROM ID= 0x%08x\n", em_eeprom->id); - printk(KERN_INFO "Vendor/Product ID= %04x:%04x\n", em_eeprom->vendor_ID, - em_eeprom->product_ID); - - switch (em_eeprom->chip_conf >> 4 & 0x3) { - case 0: - printk(KERN_INFO "No audio on board.\n"); - break; - case 1: - printk(KERN_INFO "AC97 audio (5 sample rates)\n"); - break; - case 2: - printk(KERN_INFO "I2S audio, sample rate=32k\n"); - break; - case 3: - printk(KERN_INFO "I2S audio, 3 sample rates\n"); - break; - } - - if (em_eeprom->chip_conf & 1 << 3) - printk(KERN_INFO "USB Remote wakeup capable\n"); - - if (em_eeprom->chip_conf & 1 << 2) - printk(KERN_INFO "USB Self power capable\n"); - - switch (em_eeprom->chip_conf & 0x3) { - case 0: - printk(KERN_INFO "500mA max power\n"); - break; - case 1: - printk(KERN_INFO "400mA max power\n"); - break; - case 2: - printk(KERN_INFO "300mA max power\n"); - break; - case 3: - printk(KERN_INFO "200mA max power\n"); - break; - } - printk(KERN_INFO "Table at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", - em_eeprom->string_idx_table,em_eeprom->string1, - em_eeprom->string2,em_eeprom->string3); - - return 0; -} - -/* ----------------------------------------------------------- */ - -/* - * algo_control() - */ -static int algo_control(struct i2c_adapter *adapter, - unsigned int cmd, unsigned long arg) -{ - return 0; -} - -/* - * functionality() - */ -static u32 functionality(struct i2c_adapter *adap) -{ - return I2C_FUNC_SMBUS_EMUL; -} - -#ifndef I2C_PEC -static void inc_use(struct i2c_adapter *adap) -{ - MOD_INC_USE_COUNT; -} - -static void dec_use(struct i2c_adapter *adap) -{ - MOD_DEC_USE_COUNT; -} -#endif - -static int em2820_set_tuner(int check_eeprom, struct i2c_client *client) -{ - struct em2820 *dev = client->adapter->algo_data; - struct tuner_setup tun_setup; - - if (dev->has_tuner) { - tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; - tun_setup.type = dev->tuner_type; - tun_setup.addr = dev->tuner_addr; - - em2820_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup); - } - - return (0); -} - -/* - * attach_inform() - * gets called when a device attaches to the i2c bus - * does some basic configuration - */ -static int attach_inform(struct i2c_client *client) -{ - struct em2820 *dev = client->adapter->algo_data; - - switch (client->addr << 1) { - case 0x86: - em2820_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf); - break; - case 0x42: - dprintk1(1,"attach_inform: saa7114 detected.\n"); - break; - case 0x4a: - dprintk1(1,"attach_inform: saa7113 detected.\n"); - break; - case 0xa0: - dprintk1(1,"attach_inform: eeprom detected.\n"); - break; - case 0x60: - case 0x8e: - { - struct IR_i2c *ir = i2c_get_clientdata(client); - dprintk1(1,"attach_inform: IR detected (%s).\n",ir->phys); - em2820_set_ir(dev,ir); - break; - } - case 0x80: - case 0x88: - dprintk1(1,"attach_inform: msp34xx detected.\n"); - break; - case 0xb8: - case 0xba: - dprintk1(1,"attach_inform: tvp5150 detected.\n"); - break; - default: - dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1); - dev->tuner_addr = client->addr; - em2820_set_tuner(-1, client); - } - - return 0; -} - -static struct i2c_algorithm em2820_algo = { - .master_xfer = em2820_i2c_xfer, - .algo_control = algo_control, - .functionality = functionality, -}; - -static struct i2c_adapter em2820_adap_template = { -#ifdef I2C_PEC - .owner = THIS_MODULE, -#else - .inc_use = inc_use, - .dec_use = dec_use, -#endif -#ifdef I2C_CLASS_TV_ANALOG - .class = I2C_CLASS_TV_ANALOG, -#endif - .name = "em2820", - .id = I2C_HW_B_EM2820, - .algo = &em2820_algo, - .client_register = attach_inform, -}; - -static struct i2c_client em2820_client_template = { - .name = "em2820 internal", - .flags = I2C_CLIENT_ALLOW_USE, -}; - -/* ----------------------------------------------------------- */ - -/* - * i2c_devs - * incomplete list of known devices - */ -static char *i2c_devs[128] = { - [0x4a >> 1] = "saa7113h", - [0x60 >> 1] = "remote IR sensor", - [0x8e >> 1] = "remote IR sensor", - [0x86 >> 1] = "tda9887", - [0x80 >> 1] = "msp34xx", - [0x88 >> 1] = "msp34xx", - [0xa0 >> 1] = "eeprom", - [0xb8 >> 1] = "tvp5150a", - [0xba >> 1] = "tvp5150a", - [0xc0 >> 1] = "tuner (analog)", - [0xc2 >> 1] = "tuner (analog)", - [0xc4 >> 1] = "tuner (analog)", - [0xc6 >> 1] = "tuner (analog)", -}; - -/* - * do_i2c_scan() - * check i2c address range for devices - */ -static void do_i2c_scan(char *name, struct i2c_client *c) -{ - unsigned char buf; - int i, rc; - - for (i = 0; i < 128; i++) { - c->addr = i; - rc = i2c_master_recv(c, &buf, 0); - if (rc < 0) - continue; - printk(KERN_INFO "%s: found i2c device @ 0x%x [%s]\n", name, - i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); - } -} - -/* - * em2820_i2c_call_clients() - * send commands to all attached i2c devices - */ -void em2820_i2c_call_clients(struct em2820 *dev, unsigned int cmd, void *arg) -{ - BUG_ON(NULL == dev->i2c_adap.algo_data); - i2c_clients_command(&dev->i2c_adap, cmd, arg); -} - -/* - * em2820_i2c_register() - * register i2c bus - */ -int em2820_i2c_register(struct em2820 *dev) -{ - BUG_ON(!dev->em2820_write_regs || !dev->em2820_read_reg); - BUG_ON(!dev->em2820_write_regs_req || !dev->em2820_read_reg_req); - dev->i2c_adap = em2820_adap_template; - dev->i2c_adap.dev.parent = &dev->udev->dev; - strcpy(dev->i2c_adap.name, dev->name); - dev->i2c_adap.algo_data = dev; - i2c_add_adapter(&dev->i2c_adap); - - dev->i2c_client = em2820_client_template; - dev->i2c_client.adapter = &dev->i2c_adap; - - em2820_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata)); - - if (i2c_scan) - do_i2c_scan(dev->name, &dev->i2c_client); - return 0; -} - -/* - * em2820_i2c_unregister() - * unregister i2c_bus - */ -int em2820_i2c_unregister(struct em2820 *dev) -{ - i2c_del_adapter(&dev->i2c_adap); - return 0; -} diff --git a/linux/drivers/usb/media/em2820-input.c b/linux/drivers/usb/media/em2820-input.c deleted file mode 100644 index 896f5cc0e..000000000 --- a/linux/drivers/usb/media/em2820-input.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * $Id: em2820-input.c,v 1.6 2005/10/18 14:16:40 mchehab Exp $ - * - * handle saa7134 IR remotes via linux kernel input layer. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/input.h> -#include <linux/usb.h> - -#include "compat.h" -#include "em2820.h" - -static unsigned int disable_ir = 0; -module_param(disable_ir, int, 0444); -MODULE_PARM_DESC(disable_ir,"disable infrared remote support"); - -static unsigned int ir_debug = 0; -module_param(ir_debug, int, 0644); -MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); - -#define dprintk(fmt, arg...) if (ir_debug) \ - printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) - -/* ---------------------------------------------------------------------- */ - -static IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = { - [ 0x01 ] = KEY_CHANNEL, - [ 0x02 ] = KEY_SELECT, - [ 0x03 ] = KEY_MUTE, - [ 0x04 ] = KEY_POWER, - [ 0x05 ] = KEY_KP1, - [ 0x06 ] = KEY_KP2, - [ 0x07 ] = KEY_KP3, - [ 0x08 ] = KEY_CHANNELUP, - [ 0x09 ] = KEY_KP4, - [ 0x0a ] = KEY_KP5, - [ 0x0b ] = KEY_KP6, - [ 0x0c ] = KEY_CHANNELDOWN, - [ 0x0d ] = KEY_KP7, - [ 0x0e ] = KEY_KP8, - [ 0x0f ] = KEY_KP9, - [ 0x10 ] = KEY_VOLUMEUP, - [ 0x11 ] = KEY_KP0, - [ 0x12 ] = KEY_MENU, - [ 0x13 ] = KEY_PRINT, - [ 0x14 ] = KEY_VOLUMEDOWN, - [ 0x16 ] = KEY_PAUSE, - [ 0x18 ] = KEY_RECORD, - [ 0x19 ] = KEY_REWIND, - [ 0x1a ] = KEY_PLAY, - [ 0x1b ] = KEY_FORWARD, - [ 0x1c ] = KEY_BACKSPACE, - [ 0x1e ] = KEY_STOP, - [ 0x40 ] = KEY_ZOOM, -}; - -/* ----------------------------------------------------------------------- */ - -static int get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) -{ - unsigned char b; - - /* poll IR chip */ - if (1 != i2c_master_recv(&ir->c,&b,1)) { - dprintk("read error\n"); - return -EIO; - } - - /* it seems that 0xFE indicates that a button is still hold - down, while 0xff indicates that no button is hold - down. 0xfe sequences are sometimes interrupted by 0xFF */ - - dprintk("key %02x\n", b); - - if (b == 0xff) - return 0; - - if (b == 0xfe) - /* keep old data */ - return 1; - - *ir_key = b; - *ir_raw = b; - return 1; -} - - -static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) -{ - unsigned char buf[2]; - unsigned char code; - - /* poll IR chip */ - if (2 != i2c_master_recv(&ir->c,buf,2)) - return -EIO; - - /* Does eliminate repeated parity code */ - if (buf[1]==0xff) - return 0; - - /* avoid fast reapeating */ - if (buf[1]==ir->old) - return 0; - ir->old=buf[1]; - - /* Rearranges bits to the right order */ - code= ((buf[0]&0x01)<<5) | /* 0010 0000 */ - ((buf[0]&0x02)<<3) | /* 0001 0000 */ - ((buf[0]&0x04)<<1) | /* 0000 1000 */ - ((buf[0]&0x08)>>1) | /* 0000 0100 */ - ((buf[0]&0x10)>>3) | /* 0000 0010 */ - ((buf[0]&0x20)>>5); /* 0000 0001 */ - - dprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n",code,buf[0]); - - /* return key */ - *ir_key = code; - *ir_raw = code; - return 1; -} - -/* ----------------------------------------------------------------------- */ -void em2820_set_ir(struct em2820 * dev,struct IR_i2c *ir) -{ - if (disable_ir) { - ir->get_key=NULL; - return ; - } - - /* detect & configure */ - switch (dev->model) { - case (EM2800_BOARD_UNKNOWN): - break; - case (EM2820_BOARD_UNKNOWN): - break; - case (EM2800_BOARD_TERRATEC_CINERGY_200): - case (EM2820_BOARD_TERRATEC_CINERGY_250): - ir->ir_codes = ir_codes_em_terratec; - ir->get_key = get_key_terratec; - snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM2820 Terratec)"); - break; - case (EM2820_BOARD_PINNACLE_USB_2): - break; - case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): - ir->ir_codes = ir_codes_hauppauge_new; - ir->get_key = get_key_em_haup; - snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM2840 Hauppauge)"); - break; - case (EM2820_BOARD_MSI_VOX_USB_2): - break; - case (EM2800_BOARD_LEADTEK_WINFAST_USBII): - break; - case (EM2800_BOARD_KWORLD_USB2800): - break; - } -} - -/* ---------------------------------------------------------------------- - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/linux/drivers/usb/media/em2820-video.c b/linux/drivers/usb/media/em2820-video.c deleted file mode 100644 index 19088890d..000000000 --- a/linux/drivers/usb/media/em2820-video.c +++ /dev/null @@ -1,2091 +0,0 @@ -/* - em2820-video.c - driver for Empia EM2800/EM2820/2840 USB video capture devices - - Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> - Ludovico Cavedon <cavedon@sssup.it> - Mauro Carvalho Chehab <mchehab@brturbo.com.br> - - Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> - - 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 02139, USA. - */ - -#include <linux/init.h> -#include <linux/list.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/usb.h> -#include <linux/i2c.h> -#include <linux/video_decoder.h> - -#include "em2820.h" -#include <media/tuner.h> - -#define DRIVER_AUTHOR "Markus Rechberger <mrechberger@gmail.com>, " \ - "Ludovico Cavedon <cavedon@sssup.it>, " \ - "Mauro Carvalho Chehab <mchehab@brturbo.com.br>" - -#define DRIVER_NAME "em2820" -#define DRIVER_DESC "Empia em2820 based USB video device driver" -#define EM2820_VERSION_CODE KERNEL_VERSION(0, 0, 1) - -#define em2820_videodbg(fmt, arg...) do {\ - if (video_debug) \ - printk(KERN_INFO "%s %s :"fmt, \ - dev->name, __FUNCTION__, ##arg); } while (0) - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -static LIST_HEAD(em2820_devlist); - -static unsigned int card[] = {[0 ... (EM2820_MAXBOARDS - 1)] = UNSET }; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -MODULE_PARM(card,"1-" __stringify(EM2820_MAXBOARDS) "i"); -#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -static int dummy; -module_param_array(card, int, dummy, 0444); -#else -module_param_array(card, int, NULL, 0444); -#endif -MODULE_PARM_DESC(card,"card type"); - -static int tuner = -1; -module_param(tuner, int, 0444); -MODULE_PARM_DESC(tuner, "tuner type"); - -static unsigned int video_debug = 0; -module_param(video_debug,int,0644); -MODULE_PARM_DESC(video_debug,"enable debug messages [video]"); - -/* supported tv norms */ -static struct em2820_tvnorm tvnorms[] = { - { - .name = "PAL", - .id = V4L2_STD_PAL, - .mode = VIDEO_MODE_PAL, - }, { - .name = "NTSC", - .id = V4L2_STD_NTSC, - .mode = VIDEO_MODE_NTSC, - }, { - .name = "SECAM", - .id = V4L2_STD_SECAM, - .mode = VIDEO_MODE_SECAM, - }, { - .name = "PAL-M", - .id = V4L2_STD_PAL_M, - .mode = VIDEO_MODE_PAL, - } -}; - -static const unsigned char saa7114_i2c_init[] = { - 0x00,0x00,0x01,0x08,0x02,0xc4,0x03,0x30,0x04,0x90,0x05,0x90,0x06,0xeb,0x07,0xe0, - 0x08,0x88,0x09,0x40,0x0a,0x80,0x0b,0x44,0x0c,0x40,0x0d,0x00,0x0e,0x81,0x0f,0x2a, - 0x10,0x06,0x11,0x00,0x12,0xc8,0x13,0x80,0x14,0x00,0x15,0x11,0x16,0x01,0x17,0x42, - 0x18,0x40,0x19,0x80,0x40,0x00,0x41,0xff,0x42,0xff,0x43,0xff,0x44,0xff,0x45,0xff, - 0x46,0xff,0x47,0xff,0x48,0xff,0x49,0xff,0x4a,0xff,0x4b,0xff,0x4c,0xff,0x4d,0xff, - 0x4e,0xff,0x4f,0xff,0x50,0xff,0x51,0xff,0x52,0xff,0x53,0xff,0x54,0x5f,0x55,0xff, - 0x56,0xff,0x57,0xff,0x58,0x00,0x59,0x47,0x5a,0x03,0x5b,0x03,0x5d,0x3e,0x5e,0x00, - 0x80,0x1c,0x83,0x01,0x84,0xa5,0x85,0x10,0x86,0x45,0x87,0x41,0x88,0xf0,0x88,0x00, - 0x88,0xf0,0x90,0x00,0x91,0x08,0x92,0x00,0x93,0x80,0x94,0x08,0x95,0x00,0x96,0xc0, - 0x97,0x02,0x98,0x13,0x99,0x00,0x9a,0x38,0x9b,0x01,0x9c,0x80,0x9d,0x02,0x9e,0x06, - 0x9f,0x01,0xa0,0x01,0xa1,0x00,0xa2,0x00,0xa4,0x80,0xa5,0x36,0xa6,0x36,0xa8,0x67, - 0xa9,0x04,0xaa,0x00,0xac,0x33,0xad,0x02,0xae,0x00,0xb0,0xcd,0xb1,0x04,0xb2,0xcd, - 0xb3,0x04,0xb4,0x01,0xb8,0x00,0xb9,0x00,0xba,0x00,0xbb,0x00,0xbc,0x00,0xbd,0x00, - 0xbe,0x00,0xbf,0x00 -}; - -#define TVNORMS ARRAY_SIZE(tvnorms) - -/* supported controls */ -static struct v4l2_queryctrl em2820_qctrl[] = { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = -128, - .maximum = 127, - .step = 1, - .default_value = 0, - .flags = 0, - },{ - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0x0, - .maximum = 0x1f, - .step = 0x1, - .default_value = 0x10, - .flags = 0, - },{ - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", - .minimum = 0x0, - .maximum = 0x1f, - .step = 0x1, - .default_value = 0x10, - .flags = 0, - },{ -#if 0 -/* Control in the saa7113 and not in the em2820 */ - .id = V4L2_CID_HUE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Hue", - .minimum = 0x0, - .maximum = 0x1f, - .step = 0x1, - .default_value = 0x10, - .flags = 0, - },{ -#endif - .id = V4L2_CID_AUDIO_VOLUME, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Volume", - .minimum = 0x0, - .maximum = 0x1f, - .step = 0x1, - .default_value = 0x1f, - .flags = 0, - },{ - .id = V4L2_CID_AUDIO_MUTE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mute", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - .flags = 0, - },{ - .id = V4L2_CID_RED_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Red chroma balance", - .minimum = -128, - .maximum = 127, - .step = 1, - .default_value = 0, - .flags = 0, - },{ - .id = V4L2_CID_BLUE_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Blue chroma balance", - .minimum = -128, - .maximum = 127, - .step = 1, - .default_value = 0, - .flags = 0, - },{ - .id = V4L2_CID_GAMMA, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gamma", - .minimum = 0x0, - .maximum = 0x3f, - .step = 0x1, - .default_value = 0x20, - .flags = 0, - } -}; - -static struct usb_driver em2820_usb_driver; - -static DECLARE_MUTEX(em2820_sysfs_lock); -static DECLARE_RWSEM(em2820_disconnect); - -/********************* v4l2 interface ******************************************/ - -static inline unsigned long kvirt_to_pa(unsigned long adr) -{ - unsigned long kva, ret; - - kva = (unsigned long)page_address(vmalloc_to_page((void *)adr)); - kva |= adr & (PAGE_SIZE - 1); - ret = __pa(kva); - return ret; -} - -/* - * em2820_config() - * inits registers with sane defaults - */ -static int em2820_config(struct em2820 *dev) -{ - - /* Sets I2C speed to 100 KHz */ - em2820_write_regs_req(dev, 0x00, 0x06, "\x40", 1); - - /* enable vbi capturing */ -#if 0 - em2820_write_regs_req(dev,0x00,0x0e,"\xC0",1); - em2820_write_regs_req(dev,0x00,0x0f,"\x80",1); - em2820_write_regs_req(dev,0x00,0x11,"\x51",1); -#endif - em2820_audio_usb_mute(dev, 1); - dev->mute = 1; /* maybe not the right place... */ - dev->volume = 0x1f; - em2820_audio_analog_set(dev); - em2820_audio_analog_setup(dev); - em2820_outfmt_set_yuv422(dev); - em2820_colorlevels_set_default(dev); - em2820_compression_disable(dev); - - return 0; -} - -/* - * em2820_config_i2c() - * configure i2c attached devices - */ -void em2820_config_i2c(struct em2820 *dev) -{ - struct v4l2_frequency f; - struct video_decoder_init em2820_vdi = {.data = NULL }; - -#if 0 - if (dev->decoder == EM2820_SAA7113) { - const unsigned char saa7113_i2c_init[] = { - 0x00, 0x00, /* PH7113_CHIP_VERSION 00 - ID byte */ - 0x01, 0x08, /* PH7113_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0 */ - 0x02, 0xc2, /* PH7113_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0 */ - 0x03, 0x30, /* PH7113_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18 */ - 0x04, 0x00, /* PH7113_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10 */ - 0x05, 0x00, /* PH7113_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20 */ - 0x06, 0x89, /* PH7113_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0 */ - 0x07, 0x0d, /* PH7113_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0 */ - 0x08, 0x88, /* PH7113_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0 */ - 0x09, 0x01, /* PH7113_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0 */ - 0x0a, 0x80, /* PH7113_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0 */ - 0x0b, 0x47, /* PH7113_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0 */ - 0x0c, 0x40, /* PH7113_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0 */ - 0x0d, 0x00, /* PH7113_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0 */ - 0x0e, 0x01, /* PH7113_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0 */ - 0x0f, 0x2a, /* PH7113_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0 */ - 0x10, 0x08, /* PH7113_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0 */ - 0x11, 0x0c, /* PH7113_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO */ - 0x12, 0x07, /* PH7113_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00 */ - 0x13, 0x00, /* PH7113_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0 */ - 0x14, 0x00, /* RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1) */ - 0x15, 0x00, /* PH7113_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0 */ - 0x16, 0x00, /* PH7113_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0 */ - 0x17, 0x00, /* PH7113_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8 */ - }; - - em2820_vdi.data = saa7113_i2c_init; - em2820_vdi.len = sizeof(saa7113_i2c_init); - } -#endif - - /* configure decoder */ - if(dev->model == EM2820_BOARD_MSI_VOX_USB_2){ - em2820_vdi.data=saa7114_i2c_init; - em2820_vdi.len=sizeof(saa7114_i2c_init); - } - - - em2820_i2c_call_clients(dev, DECODER_INIT, &em2820_vdi); - em2820_i2c_call_clients(dev, DECODER_SET_INPUT, &dev->ctl_input); -/* em2820_i2c_call_clients(dev,DECODER_SET_PICTURE, &dev->vpic); */ -/* em2820_i2c_call_clients(dev,DECODER_SET_NORM,&dev->tvnorm->id); */ -/* em2820_i2c_call_clients(dev,DECODER_ENABLE_OUTPUT,&output); */ -/* em2820_i2c_call_clients(dev,DECODER_DUMP, NULL); */ - - /* configure tuner */ - f.tuner = 0; - f.type = V4L2_TUNER_ANALOG_TV; - f.frequency = 9076; /* FIXME:remove magic number */ - dev->ctl_freq = f.frequency; - em2820_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f); - - /* configure tda9887 */ - -#if 0 - em2820_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf); -#endif - -/* em2820_i2c_call_clients(dev,VIDIOC_S_STD,&dev->tvnorm->id); */ -} - -/* - * em2820_empty_framequeues() - * prepare queues for incoming and outgoing frames - */ -static void em2820_empty_framequeues(struct em2820 *dev) -{ - u32 i; - - INIT_LIST_HEAD(&dev->inqueue); - INIT_LIST_HEAD(&dev->outqueue); - - for (i = 0; i < EM2820_NUM_FRAMES; i++) { - dev->frame[i].state = F_UNUSED; - dev->frame[i].buf.bytesused = 0; - } -} - -/* - * em2820_v4l2_open() - * inits the device and starts isoc transfer - */ -static int em2820_v4l2_open(struct inode *inode, struct file *filp) -{ - int minor = iminor(inode); - int errCode = 0; - struct em2820 *h,*dev = NULL; - struct list_head *list; - - list_for_each(list,&em2820_devlist) { - h = list_entry(list, struct em2820, devlist); - if (h->vdev->minor == minor) { - dev = h; - } - } - - filp->private_data=dev; - - - em2820_videodbg("users=%d", dev->users); - - if (!down_read_trylock(&em2820_disconnect)) - return -ERESTARTSYS; - - if (dev->users) { - em2820_warn("this driver can be opened only once\n"); - up_read(&em2820_disconnect); - return -EBUSY; - } - -/* if(dev->vbi_dev->minor == minor){ - dev->type=V4L2_BUF_TYPE_VBI_CAPTURE; - }*/ - if (dev->vdev->minor == minor) { - dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - - init_MUTEX(&dev->fileop_lock); /* to 1 == available */ - spin_lock_init(&dev->queue_lock); - init_waitqueue_head(&dev->wait_frame); - init_waitqueue_head(&dev->wait_stream); - - down(&dev->lock); - - em2820_set_alternate(dev); - - dev->width = norm_maxw(dev); - dev->height = norm_maxh(dev); - dev->frame_size = dev->width * dev->height * 2; - dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */ - dev->bytesperline = dev->width * 2; - dev->hscale = 0; - dev->vscale = 0; - - em2820_capture_start(dev, 1); - em2820_resolution_set(dev); - - /* start the transfer */ - errCode = em2820_init_isoc(dev); - if (errCode) - goto err; - - dev->users++; - filp->private_data = dev; - dev->io = IO_NONE; - dev->stream = STREAM_OFF; - dev->num_frames = 0; - - /* prepare queues */ - em2820_empty_framequeues(dev); - - dev->state |= DEV_INITIALIZED; - - err: - up(&dev->lock); - up_read(&em2820_disconnect); - return errCode; -} - -/* - * em2820_realease_resources() - * unregisters the v4l2,i2c and usb devices - * called when the device gets disconected or at module unload -*/ -static void em2820_release_resources(struct em2820 *dev) -{ - down(&em2820_sysfs_lock); - - em2820_info("V4L2 device /dev/video%d deregistered\n", - dev->vdev->minor); - list_del(&dev->devlist); - video_unregister_device(dev->vdev); -/* video_unregister_device(dev->vbi_dev); */ - em2820_i2c_unregister(dev); - usb_put_dev(dev->udev); - up(&em2820_sysfs_lock); -} - -/* - * em2820_v4l2_close() - * stops streaming and deallocates all resources allocated by the v4l2 calls and ioctls - */ -static int em2820_v4l2_close(struct inode *inode, struct file *filp) -{ - int errCode; - struct em2820 *dev=filp->private_data; - - em2820_videodbg("users=%d", dev->users); - - down(&dev->lock); - - em2820_uninit_isoc(dev); - - em2820_release_buffers(dev); - - /* the device is already disconnect, free the remaining resources */ - if (dev->state & DEV_DISCONNECTED) { - em2820_release_resources(dev); - up(&dev->lock); - kfree(dev); - return 0; - } - - /* set alternate 0 */ - dev->alt = 0; - em2820_videodbg("setting alternate 0"); - errCode = usb_set_interface(dev->udev, 0, 0); - if (errCode < 0) { - em2820_errdev ("cannot change alternate number to 0 (error=%i)\n", - errCode); - } - - dev->users--; - wake_up_interruptible_nr(&dev->open, 1); - up(&dev->lock); - return 0; -} - -/* - * em2820_v4l2_read() - * will allocate buffers when called for the first time - */ -static ssize_t -em2820_v4l2_read(struct file *filp, char __user * buf, size_t count, - loff_t * f_pos) -{ - struct em2820_frame_t *f, *i; - unsigned long lock_flags; - int ret = 0; - struct em2820 *dev = filp->private_data; - -#if 0 - if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - em2820_videodbg("V4l2_Buf_type_videocapture is set\n"); - } - if (dev->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - printk("V4L2_BUF_TYPE_VBI_CAPTURE is set\n"); - printk("not supported yet! ...\n"); - copy_to_user(buf, "", 1); - return (1); - } -#endif - if (down_interruptible(&dev->fileop_lock)) - return -ERESTARTSYS; - - if (dev->state & DEV_DISCONNECTED) { - em2820_videodbg("device not present"); - up(&dev->fileop_lock); - return -ENODEV; - } - - if (dev->state & DEV_MISCONFIGURED) { - em2820_videodbg("device misconfigured; close and open it again"); - up(&dev->fileop_lock); - return -EIO; - } - - if (dev->io == IO_MMAP) { - em2820_videodbg ("IO method is set to mmap; close and open" - " the device again to choose the read method"); - up(&dev->fileop_lock); - return -EINVAL; - } - - if (dev->io == IO_NONE) { - if (!em2820_request_buffers(dev, EM2820_NUM_READ_FRAMES)) { - em2820_errdev("read failed, not enough memory\n"); - up(&dev->fileop_lock); - return -ENOMEM; - } - dev->io = IO_READ; - dev->stream = STREAM_ON; - em2820_queue_unusedframes(dev); - } - - if (!count) { - up(&dev->fileop_lock); - return 0; - } - - if (list_empty(&dev->outqueue)) { - if (filp->f_flags & O_NONBLOCK) { - up(&dev->fileop_lock); - return -EAGAIN; - } - ret = wait_event_interruptible - (dev->wait_frame, - (!list_empty(&dev->outqueue)) || - (dev->state & DEV_DISCONNECTED)); - if (ret) { - up(&dev->fileop_lock); - return ret; - } - if (dev->state & DEV_DISCONNECTED) { - up(&dev->fileop_lock); - return -ENODEV; - } - } - - f = list_entry(dev->outqueue.prev, struct em2820_frame_t, frame); - - spin_lock_irqsave(&dev->queue_lock, lock_flags); - list_for_each_entry(i, &dev->outqueue, frame) - i->state = F_UNUSED; - INIT_LIST_HEAD(&dev->outqueue); - spin_unlock_irqrestore(&dev->queue_lock, lock_flags); - - em2820_queue_unusedframes(dev); - - if (count > f->buf.length) - count = f->buf.length; - - if (copy_to_user(buf, f->bufmem, count)) { - up(&dev->fileop_lock); - return -EFAULT; - } - *f_pos += count; - - up(&dev->fileop_lock); - - return count; -} - -/* - * em2820_v4l2_poll() - * will allocate buffers when called for the first time - */ -static unsigned int em2820_v4l2_poll(struct file *filp, poll_table * wait) -{ - unsigned int mask = 0; - struct em2820 *dev = filp->private_data; - - if (down_interruptible(&dev->fileop_lock)) - return POLLERR; - - if (dev->state & DEV_DISCONNECTED) { - em2820_videodbg("device not present"); - } else if (dev->state & DEV_MISCONFIGURED) { - em2820_videodbg("device is misconfigured; close and open it again"); - } else { - if (dev->io == IO_NONE) { - if (!em2820_request_buffers - (dev, EM2820_NUM_READ_FRAMES)) { - em2820_warn - ("poll() failed, not enough memory\n"); - } else { - dev->io = IO_READ; - dev->stream = STREAM_ON; - } - } - - if (dev->io == IO_READ) { - em2820_queue_unusedframes(dev); - poll_wait(filp, &dev->wait_frame, wait); - - if (!list_empty(&dev->outqueue)) - mask |= POLLIN | POLLRDNORM; - - up(&dev->fileop_lock); - - return mask; - } - } - - up(&dev->fileop_lock); - return POLLERR; -} - -/* - * em2820_vm_open() - */ -static void em2820_vm_open(struct vm_area_struct *vma) -{ - struct em2820_frame_t *f = vma->vm_private_data; - f->vma_use_count++; -} - -/* - * em2820_vm_close() - */ -static void em2820_vm_close(struct vm_area_struct *vma) -{ - /* NOTE: buffers are not freed here */ - struct em2820_frame_t *f = vma->vm_private_data; - f->vma_use_count--; -} - -static struct vm_operations_struct em2820_vm_ops = { - .open = em2820_vm_open, - .close = em2820_vm_close, -}; - -/* - * em2820_v4l2_mmap() - */ -static int em2820_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) -{ - unsigned long size = vma->vm_end - vma->vm_start, - start = vma->vm_start, pos, page; - u32 i; - - struct em2820 *dev = filp->private_data; - - if (down_interruptible(&dev->fileop_lock)) - return -ERESTARTSYS; - - if (dev->state & DEV_DISCONNECTED) { - em2820_videodbg("mmap: device not present"); - up(&dev->fileop_lock); - return -ENODEV; - } - - if (dev->state & DEV_MISCONFIGURED) { - em2820_videodbg ("mmap: Device is misconfigured; close and " - "open it again"); - up(&dev->fileop_lock); - return -EIO; - } - - if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || - size != PAGE_ALIGN(dev->frame[0].buf.length)) { - up(&dev->fileop_lock); - return -EINVAL; - } - - for (i = 0; i < dev->num_frames; i++) { - if ((dev->frame[i].buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) - break; - } - if (i == dev->num_frames) { - em2820_videodbg("mmap: user supplied mapping address is out of range"); - up(&dev->fileop_lock); - return -EINVAL; - } - - /* VM_IO is eventually going to replace PageReserved altogether */ - vma->vm_flags |= VM_IO; - vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */ - - pos = (unsigned long)dev->frame[i].bufmem; - while (size > 0) { /* size is page-aligned */ - page = vmalloc_to_pfn((void *)pos); - if (remap_pfn_range(vma, start, page, PAGE_SIZE, - vma->vm_page_prot)) { - em2820_videodbg("mmap: rename page map failed"); - up(&dev->fileop_lock); - return -EAGAIN; - } - start += PAGE_SIZE; - pos += PAGE_SIZE; - size -= PAGE_SIZE; - } - - vma->vm_ops = &em2820_vm_ops; - vma->vm_private_data = &dev->frame[i]; - - em2820_vm_open(vma); - up(&dev->fileop_lock); - return 0; -} - -/* - * em2820_get_ctrl() - * return the current saturation, brightness or contrast, mute state - */ -static int em2820_get_ctrl(struct em2820 *dev, struct v4l2_control *ctrl) -{ - s32 tmp; - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - ctrl->value = dev->mute; - return 0; - case V4L2_CID_AUDIO_VOLUME: - ctrl->value = dev->volume; - return 0; - case V4L2_CID_BRIGHTNESS: - if ((tmp = em2820_brightness_get(dev)) < 0) - return -EIO; - ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */ - return 0; - case V4L2_CID_CONTRAST: - if ((ctrl->value = em2820_contrast_get(dev)) < 0) - return -EIO; - return 0; - case V4L2_CID_SATURATION: - if ((ctrl->value = em2820_saturation_get(dev)) < 0) - return -EIO; - return 0; - case V4L2_CID_RED_BALANCE: - if ((tmp = em2820_v_balance_get(dev)) < 0) - return -EIO; - ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */ - return 0; - case V4L2_CID_BLUE_BALANCE: - if ((tmp = em2820_u_balance_get(dev)) < 0) - return -EIO; - ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */ - return 0; - case V4L2_CID_GAMMA: - if ((ctrl->value = em2820_gamma_get(dev)) < 0) - return -EIO; - return 0; - default: - return -EINVAL; - } -} - -/* - * em2820_set_ctrl() - * mute or set new saturation, brightness or contrast - */ -static int em2820_set_ctrl(struct em2820 *dev, const struct v4l2_control *ctrl) -{ - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - if (ctrl->value != dev->mute) { - dev->mute = ctrl->value; - em2820_audio_usb_mute(dev, ctrl->value); - return em2820_audio_analog_set(dev); - } - return 0; - case V4L2_CID_AUDIO_VOLUME: - dev->volume = ctrl->value; - return em2820_audio_analog_set(dev); - case V4L2_CID_BRIGHTNESS: - return em2820_brightness_set(dev, ctrl->value); - case V4L2_CID_CONTRAST: - return em2820_contrast_set(dev, ctrl->value); - case V4L2_CID_SATURATION: - return em2820_saturation_set(dev, ctrl->value); - case V4L2_CID_RED_BALANCE: - return em2820_v_balance_set(dev, ctrl->value); - case V4L2_CID_BLUE_BALANCE: - return em2820_u_balance_set(dev, ctrl->value); - case V4L2_CID_GAMMA: - return em2820_gamma_set(dev, ctrl->value); - default: - return -EINVAL; - } -} - -/* - * em2820_stream_interrupt() - * stops streaming - */ -static int em2820_stream_interrupt(struct em2820 *dev) -{ - int ret = 0; - - /* stop reading from the device */ - - dev->stream = STREAM_INTERRUPT; - ret = wait_event_timeout(dev->wait_stream, - (dev->stream == STREAM_OFF) || - (dev->state & DEV_DISCONNECTED), - EM2820_URB_TIMEOUT); - if (dev->state & DEV_DISCONNECTED) - return -ENODEV; - else if (ret) { - dev->state |= DEV_MISCONFIGURED; - em2820_videodbg("device is misconfigured; close and " - "open /dev/video%d again", dev->vdev->minor); - return ret; - } - - return 0; -} - -static int em2820_set_norm(struct em2820 *dev, int width, int height) -{ - unsigned int hscale, vscale; - unsigned int maxh, maxw; - - maxw = norm_maxw(dev); - maxh = norm_maxh(dev); - - /* width must even because of the YUYV format */ - /* height must be even because of interlacing */ - height &= 0xfffe; - width &= 0xfffe; - - if (height < 32) - height = 32; - if (height > maxh) - height = maxh; - if (width < 48) - width = 48; - if (width > maxw) - width = maxw; - - if ((hscale = (((unsigned long)maxw) << 12) / width - 4096L) >= 0x4000) - hscale = 0x3fff; - width = (((unsigned long)maxw) << 12) / (hscale + 4096L); - - if ((vscale = (((unsigned long)maxh) << 12) / height - 4096L) >= 0x4000) - vscale = 0x3fff; - height = (((unsigned long)maxh) << 12) / (vscale + 4096L); - - /* set new image size */ - dev->width = width; - dev->height = height; - dev->frame_size = dev->width * dev->height * 2; - dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */ - dev->bytesperline = dev->width * 2; - dev->hscale = hscale; - dev->vscale = vscale; - - em2820_resolution_set(dev); - - return 0; -} - -static void video_mux(struct em2820 *dev, int index) -{ - int input, ainput; - - input = INPUT(index)->vmux; - dev->ctl_input = index; - - em2820_i2c_call_clients(dev, DECODER_SET_INPUT, &input); - - dev->ctl_ainput = INPUT(index)->amux; - - switch (dev->ctl_ainput) { - case 0: - ainput = EM2820_AUDIO_SRC_TUNER; - break; - default: - ainput = EM2820_AUDIO_SRC_LINE; - } - - em2820_audio_source(dev, ainput); -} - -/* - * em2820_v4l2_do_ioctl() - * This function is _not_ called directly, but from - * em2820_v4l2_ioctl. Userspace - * copying is done already, arg is a kernel pointer. - */ -static int em2820_do_ioctl(struct inode *inode, struct file *filp, - struct em2820 *dev, unsigned int cmd, void *arg, - v4l2_kioctl driver_ioctl) -{ - int ret; - - switch (cmd) { - /* ---------- tv norms ---------- */ - case VIDIOC_ENUMSTD: - { - struct v4l2_standard *e = arg; - unsigned int i; - - i = e->index; - if (i >= TVNORMS) - return -EINVAL; - ret = v4l2_video_std_construct(e, tvnorms[e->index].id, - tvnorms[e->index].name); - e->index = i; - if (ret < 0) - return ret; - return 0; - } - case VIDIOC_G_STD: - { - v4l2_std_id *id = arg; - - *id = dev->tvnorm->id; - return 0; - } - case VIDIOC_S_STD: - { - v4l2_std_id *id = arg; - unsigned int i; - - for (i = 0; i < TVNORMS; i++) - if (*id == tvnorms[i].id) - break; - if (i == TVNORMS) - for (i = 0; i < TVNORMS; i++) - if (*id & tvnorms[i].id) - break; - if (i == TVNORMS) - return -EINVAL; - - down(&dev->lock); - dev->tvnorm = &tvnorms[i]; - - em2820_set_norm(dev, dev->width, dev->height); - -/* - dev->width=norm_maxw(dev); - dev->height=norm_maxh(dev); - dev->frame_size=dev->width*dev->height*2; - dev->field_size=dev->frame_size>>1; - dev->bytesperline=dev->width*2; - dev->hscale=0; - dev->vscale=0; - - em2820_resolution_set(dev); -*/ -/* - em2820_uninit_isoc(dev); - em2820_set_alternate(dev); - em2820_capture_start(dev, 1); - em2820_resolution_set(dev); - em2820_init_isoc(dev); -*/ - em2820_i2c_call_clients(dev, DECODER_SET_NORM, - &tvnorms[i].mode); - em2820_i2c_call_clients(dev, VIDIOC_S_STD, - &dev->tvnorm->id); - - up(&dev->lock); - - return 0; - } - - /* ------ input switching ---------- */ - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *i = arg; - unsigned int n; - static const char *iname[] = { - [EM2820_VMUX_COMPOSITE1] = "Composite1", - [EM2820_VMUX_COMPOSITE2] = "Composite2", - [EM2820_VMUX_COMPOSITE3] = "Composite3", - [EM2820_VMUX_COMPOSITE4] = "Composite4", - [EM2820_VMUX_SVIDEO] = "S-Video", - [EM2820_VMUX_TELEVISION] = "Television", - [EM2820_VMUX_CABLE] = "Cable TV", - [EM2820_VMUX_DVB] = "DVB", - [EM2820_VMUX_DEBUG] = "for debug only", - }; - - n = i->index; - if (n >= MAX_EM2820_INPUT) - return -EINVAL; - if (0 == INPUT(n)->type) - return -EINVAL; - memset(i, 0, sizeof(*i)); - i->index = n; - i->type = V4L2_INPUT_TYPE_CAMERA; - strcpy(i->name, iname[INPUT(n)->type]); - if ((EM2820_VMUX_TELEVISION == INPUT(n)->type) || - (EM2820_VMUX_CABLE == INPUT(n)->type)) - i->type = V4L2_INPUT_TYPE_TUNER; - for (n = 0; n < ARRAY_SIZE(tvnorms); n++) - i->std |= tvnorms[n].id; - return 0; - } - - case VIDIOC_G_INPUT: - { - int *i = arg; - *i = dev->ctl_input; - - return 0; - } - - case VIDIOC_S_INPUT: - { - int *index = arg; - - if (*index >= MAX_EM2820_INPUT) - return -EINVAL; - if (0 == INPUT(*index)->type) - return -EINVAL; - - down(&dev->lock); - video_mux(dev, *index); - up(&dev->lock); - - return 0; - } - - case VIDIOC_G_AUDIO: - { - struct v4l2_audio *a = arg; - unsigned int index = a->index; - - if (a->index > 1) - return -EINVAL; - memset(a, 0, sizeof(*a)); - index = dev->ctl_ainput; - - if (index == 0) { - strcpy(a->name, "Television"); - } else { - strcpy(a->name, "Line In"); - } - a->capability = V4L2_AUDCAP_STEREO; - a->index = index; - return 0; - } - - case VIDIOC_S_AUDIO: - { - struct v4l2_audio *a = arg; -#if 0 - struct video_audio audio; -#endif - if (a->index != dev->ctl_ainput) - return -EINVAL; - - return 0; - } - - /* --- controls ---------------------------------------------- */ - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *qc = arg; - u8 i, n; -#if 0 - if (dev->decoder == EM2820_TVP5150) { - em2820_i2c_call_clients(dev,cmd,arg); - return 0; - } -#endif - n = sizeof(em2820_qctrl) / sizeof(em2820_qctrl[0]); - for (i = 0; i < n; i++) - if (qc->id && qc->id == em2820_qctrl[i].id) { - memcpy(qc, &(em2820_qctrl[i]), - sizeof(*qc)); - return 0; - } - - return -EINVAL; - } - - case VIDIOC_G_CTRL: - { - struct v4l2_control *ctrl = arg; - -#if 0 - if (dev->decoder == EM2820_TVP5150) { - em2820_i2c_call_clients(dev,cmd,arg); - return 0; - } -#endif - - return em2820_get_ctrl(dev, ctrl); - } - - case VIDIOC_S_CTRL_OLD: /* ??? */ - case VIDIOC_S_CTRL: - { - struct v4l2_control *ctrl = arg; - u8 i, n; - -#if 0 - if (dev->decoder == EM2820_TVP5150) { - em2820_i2c_call_clients(dev,cmd,arg); - return 0; - } -#endif - - n = sizeof(em2820_qctrl) / sizeof(em2820_qctrl[0]); - for (i = 0; i < n; i++) - if (ctrl->id == em2820_qctrl[i].id) { - if (ctrl->value < - em2820_qctrl[i].minimum - || ctrl->value > - em2820_qctrl[i].maximum) - return -ERANGE; - - return em2820_set_ctrl(dev, ctrl); - } - return -EINVAL; - } - - /* --- tuner ioctls ------------------------------------------ */ - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *t = arg; - int status = 0; - - if (0 != t->index) - return -EINVAL; - - memset(t, 0, sizeof(*t)); - strcpy(t->name, "Tuner"); - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM; - t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */ -/* t->signal = 0xffff;*/ -/* em2820_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/ - /* No way to get signal strength? */ - down(&dev->lock); - em2820_i2c_call_clients(dev, DECODER_GET_STATUS, - &status); - up(&dev->lock); - t->signal = - (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0; - - em2820_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x", t->signal, - t->afc); - return 0; - } - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *t = arg; - int status = 0; - - if (0 != t->index) - return -EINVAL; - memset(t, 0, sizeof(*t)); - strcpy(t->name, "Tuner"); - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM; - t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */ -/* t->signal = 0xffff; */ - /* No way to get signal strength? */ - down(&dev->lock); - em2820_i2c_call_clients(dev, DECODER_GET_STATUS, - &status); - up(&dev->lock); - t->signal = - (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0; - - em2820_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n", - t->signal, t->afc); - return 0; - } - case VIDIOC_G_FREQUENCY: - { - struct v4l2_frequency *f = arg; - - memset(f, 0, sizeof(*f)); - f->type = V4L2_TUNER_ANALOG_TV; - f->frequency = dev->ctl_freq; - - return 0; - } - case VIDIOC_S_FREQUENCY: - { - struct v4l2_frequency *f = arg; - - if (0 != f->tuner) - return -EINVAL; - - if (V4L2_TUNER_ANALOG_TV != f->type) - return -EINVAL; - - down(&dev->lock); - dev->ctl_freq = f->frequency; - em2820_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f); - up(&dev->lock); - return 0; - } - -#if 0 /* ioctl is optional */ - case VIDIOC_G_PARM: - { - struct v4l2_captureparm *parm = arg; - memset(parm, 0, sizeof(*parm)); - return 0; - } -#endif - case VIDIOC_CROPCAP: - { - struct v4l2_cropcap *cc = arg; - - if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - cc->bounds.left = 0; - cc->bounds.top = 0; - cc->bounds.width = dev->width; - cc->bounds.height = dev->height; - cc->defrect = cc->bounds; - cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */ - cc->pixelaspect.denominator = 59; - return 0; - } - case VIDIOC_STREAMON: - { - int *type = arg; - - if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE - || dev->io != IO_MMAP) - return -EINVAL; - - if (list_empty(&dev->inqueue)) - return -EINVAL; - - dev->stream = STREAM_ON; /* FIXME: Start video capture here? */ - - em2820_videodbg("VIDIOC_STREAMON: starting stream"); - - return 0; - } - case VIDIOC_STREAMOFF: - { - int *type = arg; - int ret; - - if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE - || dev->io != IO_MMAP) - return -EINVAL; - - if (dev->stream == STREAM_ON) { - em2820_videodbg ("VIDIOC_STREAMOFF: interrupting stream"); - if ((ret = em2820_stream_interrupt(dev))) - return ret; - } - em2820_empty_framequeues(dev); - - return 0; - } - default: - return v4l_compat_translate_ioctl(inode, filp, cmd, arg, - driver_ioctl); - } - return 0; -} - -/* - * em2820_v4l2_do_ioctl() - * This function is _not_ called directly, but from - * em2820_v4l2_ioctl. Userspace - * copying is done already, arg is a kernel pointer. - */ -static int em2820_video_do_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, void *arg) -{ - struct em2820 *dev = filp->private_data; - - if (!dev) - return -ENODEV; - - if (video_debug > 1) - em2820_print_ioctl(dev->name,cmd); - - switch (cmd) { - - /* --- capabilities ------------------------------------------ */ - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - - memset(cap, 0, sizeof(*cap)); - strlcpy(cap->driver, "em2820", sizeof(cap->driver)); - strlcpy(cap->card, em2820_boards[dev->model].name, - sizeof(cap->card)); - strlcpy(cap->bus_info, dev->udev->dev.bus_id, - sizeof(cap->bus_info)); - cap->version = EM2820_VERSION_CODE; - cap->capabilities = -#if 0 - V4L2_CAP_VBI_CAPTURE | -#endif - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_AUDIO | - V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; - if (dev->has_tuner) - cap->capabilities |= V4L2_CAP_TUNER; - return 0; - } - - /* --- capture ioctls ---------------------------------------- */ - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *fmtd = arg; - - if (fmtd->index != 0) - return -EINVAL; - memset(fmtd, 0, sizeof(*fmtd)); - fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - strcpy(fmtd->description, "Packed YUY2"); - fmtd->pixelformat = V4L2_PIX_FMT_YUYV; - memset(fmtd->reserved, 0, sizeof(fmtd->reserved)); - return 0; - } - - case VIDIOC_G_FMT: - { - struct v4l2_format *format = arg; - - em2820_videodbg("VIDIOC_G_FMT: type=%s", - format->type == - V4L2_BUF_TYPE_VIDEO_CAPTURE ? - "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type == - V4L2_BUF_TYPE_VBI_CAPTURE ? - "V4L2_BUF_TYPE_VBI_CAPTURE " : - "not supported"); - -#if 0 - if (format->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - format->type = V4L2_BUF_TYPE_VBI_CAPTURE; - format->fmt.vbi.sampling_rate = HZ; - format->fmt.vbi.sample_format = - V4L2_PIX_FMT_GREY; - format->fmt.vbi.offset = norm_maxw(dev); - format->fmt.vbi.count[0] = 7; - format->fmt.vbi.count[1] = 319; - return (0); - } -#endif - if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - format->fmt.pix.width = dev->width; - format->fmt.pix.height = dev->height; - format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; - format->fmt.pix.bytesperline = dev->bytesperline; - format->fmt.pix.sizeimage = dev->frame_size; - format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ - - em2820_videodbg("VIDIOC_G_FMT: %dx%d", dev->width, - dev->height); - return 0; - } - - case VIDIOC_TRY_FMT: - case VIDIOC_S_FMT: - { - struct v4l2_format *format = arg; - u32 i; - int ret = 0; - int width = format->fmt.pix.width; - int height = format->fmt.pix.height; - unsigned int hscale, vscale; - unsigned int maxh, maxw; - - maxw = norm_maxw(dev); - maxh = norm_maxh(dev); - -/* int both_fields; */ - - em2820_videodbg("%s: type=%s", - cmd == - VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" : - "VIDIOC_S_FMT", - format->type == - V4L2_BUF_TYPE_VIDEO_CAPTURE ? - "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type == - V4L2_BUF_TYPE_VBI_CAPTURE ? - "V4L2_BUF_TYPE_VBI_CAPTURE " : - "not supported"); -#if 0 - if (format->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - format->type = V4L2_BUF_TYPE_VBI_CAPTURE; - format->fmt.vbi.sampling_rate = HZ; - format->fmt.vbi.samples_per_line = 2048; - format->fmt.vbi.sample_format = - V4L2_PIX_FMT_GREY; - format->fmt.vbi.offset = 244; - format->fmt.vbi.flags = 0; - format->fmt.vbi.start[0] = 0; - format->fmt.vbi.start[1] = 0; - return (0); - } -#endif - - if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - em2820_videodbg("%s: requested %dx%d", - cmd == - VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" : - "VIDIOC_S_FMT", format->fmt.pix.width, - format->fmt.pix.height); - - /* FIXME: Move some code away from here */ - /* width must even because of the YUYV format */ - /* height must be even because of interlacing */ - height &= 0xfffe; - width &= 0xfffe; - - if (height < 32) - height = 32; - if (height > maxh) - height = maxh; - if (width < 48) - width = 48; - if (width > maxw) - width = maxw; - - if(dev->is_em2800){ - /* the em2800 can only scale down to 50% */ - if(height % (maxh / 2)) - height=maxh; - if(width % (maxw / 2)) - width=maxw; - /* according to empiatech support */ - /* the MaxPacketSize is to small to support */ - /* framesizes larger than 640x480 @ 30 fps */ - /* or 640x576 @ 25 fps. As this would cut */ - /* of a part of the image we prefer */ - /* 360x576 or 360x480 for now */ - if(width == maxw && height == maxh) - width /= 2; - } - - if ((hscale = - (((unsigned long)maxw) << 12) / width - 4096L) >= - 0x4000) - hscale = 0x3fff; - width = - (((unsigned long)maxw) << 12) / (hscale + 4096L); - - if ((vscale = - (((unsigned long)maxh) << 12) / height - 4096L) >= - 0x4000) - vscale = 0x3fff; - height = - (((unsigned long)maxh) << 12) / (vscale + 4096L); - - format->fmt.pix.width = width; - format->fmt.pix.height = height; - format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; - format->fmt.pix.bytesperline = width * 2; - format->fmt.pix.sizeimage = width * 2 * height; - format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - format->fmt.pix.field = V4L2_FIELD_INTERLACED; - - em2820_videodbg("%s: returned %dx%d (%d, %d)", - cmd == - VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" : - "VIDIOC_S_FMT", format->fmt.pix.width, - format->fmt.pix.height, hscale, vscale); - - if (cmd == VIDIOC_TRY_FMT) - return 0; - - for (i = 0; i < dev->num_frames; i++) - if (dev->frame[i].vma_use_count) { - em2820_videodbg("VIDIOC_S_FMT failed. " - "Unmap the buffers first."); - return -EINVAL; - } - - /* stop io in case it is already in progress */ - if (dev->stream == STREAM_ON) { - em2820_videodbg("VIDIOC_SET_FMT: interupting stream"); - if ((ret = em2820_stream_interrupt(dev))) - return ret; - } - - em2820_release_buffers(dev); - dev->io = IO_NONE; - - /* set new image size */ - dev->width = width; - dev->height = height; - dev->frame_size = dev->width * dev->height * 2; - dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */ - dev->bytesperline = dev->width * 2; - dev->hscale = hscale; - dev->vscale = vscale; -/* dev->both_fileds = both_fileds; */ - em2820_uninit_isoc(dev); - em2820_set_alternate(dev); - em2820_capture_start(dev, 1); - em2820_resolution_set(dev); - em2820_init_isoc(dev); - - return 0; - } - - /* --- streaming capture ------------------------------------- */ -#if 0 - case VIDIOCGMBUF: - { - struct video_mbuf *mbuf = arg; - struct videobuf_queue *q; - struct v4l2_requestbuffers req; - unsigned int i; - - q = get_queue(fh); - memset(&req, 0, sizeof(req)); - req.type = q->type; - req.count = 8; - req.memory = V4L2_MEMORY_MMAP; - err = videobuf_reqbufs(q, &req); - if (err < 0) - return err; - memset(mbuf, 0, sizeof(*mbuf)); - mbuf->frames = req.count; - mbuf->size = 0; - for (i = 0; i < mbuf->frames; i++) { - mbuf->offsets[i] = q->bufs[i]->boff; - mbuf->size += q->bufs[i]->bsize; - } - return 0; - } -#endif - case VIDIOC_REQBUFS: - { - struct v4l2_requestbuffers *rb = arg; - u32 i; - int ret; - - if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - rb->memory != V4L2_MEMORY_MMAP) - return -EINVAL; - - if (dev->io == IO_READ) { - em2820_videodbg ("method is set to read;" - " close and open the device again to" - " choose the mmap I/O method"); - return -EINVAL; - } - - for (i = 0; i < dev->num_frames; i++) - if (dev->frame[i].vma_use_count) { - em2820_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped"); - return -EINVAL; - } - - if (dev->stream == STREAM_ON) { - em2820_videodbg("VIDIOC_REQBUFS: interrupting stream"); - if ((ret = em2820_stream_interrupt(dev))) - return ret; - } - - em2820_empty_framequeues(dev); - - em2820_release_buffers(dev); - if (rb->count) - rb->count = - em2820_request_buffers(dev, rb->count); - - dev->frame_current = NULL; - - em2820_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i", - rb->count); - dev->io = rb->count ? IO_MMAP : IO_NONE; - return 0; - } - - case VIDIOC_QUERYBUF: - { - struct v4l2_buffer *b = arg; - - if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - b->index >= dev->num_frames || dev->io != IO_MMAP) - return -EINVAL; - - memcpy(b, &dev->frame[b->index].buf, sizeof(*b)); - - if (dev->frame[b->index].vma_use_count) { - b->flags |= V4L2_BUF_FLAG_MAPPED; - } - if (dev->frame[b->index].state == F_DONE) - b->flags |= V4L2_BUF_FLAG_DONE; - else if (dev->frame[b->index].state != F_UNUSED) - b->flags |= V4L2_BUF_FLAG_QUEUED; - return 0; - } - case VIDIOC_QBUF: - { - struct v4l2_buffer *b = arg; - unsigned long lock_flags; - - if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - b->index >= dev->num_frames || dev->io != IO_MMAP) { - return -EINVAL; - } - - if (dev->frame[b->index].state != F_UNUSED) { - return -EAGAIN; - } - dev->frame[b->index].state = F_QUEUED; - - /* add frame to fifo */ - spin_lock_irqsave(&dev->queue_lock, lock_flags); - list_add_tail(&dev->frame[b->index].frame, - &dev->inqueue); - spin_unlock_irqrestore(&dev->queue_lock, lock_flags); - - return 0; - } - case VIDIOC_DQBUF: - { - struct v4l2_buffer *b = arg; - struct em2820_frame_t *f; - unsigned long lock_flags; - int ret = 0; - - if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE - || dev->io != IO_MMAP) - return -EINVAL; - - if (list_empty(&dev->outqueue)) { - if (dev->stream == STREAM_OFF) - return -EINVAL; - if (filp->f_flags & O_NONBLOCK) - return -EAGAIN; - ret = wait_event_interruptible - (dev->wait_frame, - (!list_empty(&dev->outqueue)) || - (dev->state & DEV_DISCONNECTED)); - if (ret) - return ret; - if (dev->state & DEV_DISCONNECTED) - return -ENODEV; - } - - spin_lock_irqsave(&dev->queue_lock, lock_flags); - f = list_entry(dev->outqueue.next, - struct em2820_frame_t, frame); - list_del(dev->outqueue.next); - spin_unlock_irqrestore(&dev->queue_lock, lock_flags); - - f->state = F_UNUSED; - memcpy(b, &f->buf, sizeof(*b)); - - if (f->vma_use_count) - b->flags |= V4L2_BUF_FLAG_MAPPED; - - return 0; - } - default: - return em2820_do_ioctl(inode, filp, dev, cmd, arg, - em2820_video_do_ioctl); - } - return 0; -} - -/* - * em2820_v4l2_ioctl() - * handle v4l2 ioctl the main action happens in em2820_v4l2_do_ioctl() - */ -static int em2820_v4l2_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - int ret = 0; - struct em2820 *dev = filp->private_data; - - if (down_interruptible(&dev->fileop_lock)) - return -ERESTARTSYS; - - if (dev->state & DEV_DISCONNECTED) { - em2820_errdev("v4l2 ioctl: device not present\n"); - up(&dev->fileop_lock); - return -ENODEV; - } - - if (dev->state & DEV_MISCONFIGURED) { - em2820_errdev - ("v4l2 ioctl: device is misconfigured; close and open it again\n"); - up(&dev->fileop_lock); - return -EIO; - } - - ret = video_usercopy(inode, filp, cmd, arg, em2820_video_do_ioctl); - - up(&dev->fileop_lock); - - return ret; -} - -static struct file_operations em2820_v4l_fops = { - .owner = THIS_MODULE, - .open = em2820_v4l2_open, - .release = em2820_v4l2_close, - .ioctl = em2820_v4l2_ioctl, - .read = em2820_v4l2_read, - .poll = em2820_v4l2_poll, - .mmap = em2820_v4l2_mmap, - .llseek = no_llseek, -}; - -/******************************** usb interface *****************************************/ - -/* - * em2820_init_dev() - * allocates and inits the device structs, registers i2c bus and v4l device - */ -static int em2820_init_dev(struct em2820 **devhandle, struct usb_device *udev, - int minor, int model) -{ - struct em2820 *dev = *devhandle; - int retval = -ENOMEM; - int errCode, i; - unsigned int maxh, maxw; - struct usb_interface *uif; - - dev->udev = udev; - dev->model = model; - init_MUTEX(&dev->lock); - init_waitqueue_head(&dev->open); - - dev->em2820_write_regs = em2820_write_regs; - dev->em2820_read_reg = em2820_read_reg; - dev->em2820_read_reg_req_len = em2820_read_reg_req_len; - dev->em2820_write_regs_req = em2820_write_regs_req; - dev->em2820_read_reg_req = em2820_read_reg_req; - dev->is_em2800 = em2820_boards[model].is_em2800; - dev->has_tuner = em2820_boards[model].has_tuner; - dev->has_msp34xx = em2820_boards[model].has_msp34xx; - dev->tda9887_conf = em2820_boards[model].tda9887_conf; - dev->decoder = em2820_boards[model].decoder; - - if (tuner >= 0) - dev->tuner_type = tuner; - else - dev->tuner_type = em2820_boards[model].tuner_type; - - dev->video_inputs = em2820_boards[model].vchannels; - - for (i = 0; i < TVNORMS; i++) - if (em2820_boards[model].norm == tvnorms[i].mode) - break; - if (i == TVNORMS) - i = 0; - - dev->tvnorm = &tvnorms[i]; /* set default norm */ - - em2820_videodbg("tvnorm=%s\n", dev->tvnorm->name); - - maxw = norm_maxw(dev); - maxh = norm_maxh(dev); - - /* set default image size */ - dev->width = maxw; - dev->height = maxh; - dev->interlaced = EM2820_INTERLACED_DEFAULT; - dev->field_size = dev->width * dev->height; - dev->frame_size = - dev->interlaced ? dev->field_size << 1 : dev->field_size; - dev->bytesperline = dev->width * 2; - dev->hscale = 0; - dev->vscale = 0; - dev->ctl_input = 2; - - /* setup video picture settings for saa7113h */ - memset(&dev->vpic, 0, sizeof(dev->vpic)); - dev->vpic.colour = 128 << 8; - dev->vpic.hue = 128 << 8; - dev->vpic.brightness = 128 << 8; - dev->vpic.contrast = 192 << 8; - dev->vpic.whiteness = 128 << 8; /* This one isn't used */ - dev->vpic.depth = 16; - dev->vpic.palette = VIDEO_PALETTE_YUV422; - - /* compute alternate max packet sizes */ - uif = dev->udev->actconfig->interface[0]; - dev->alt_max_pkt_size[0] = 0; - for (i = 1; i <= EM2820_MAX_ALT && i < uif->num_altsetting ; i++) { - u16 tmp = - le16_to_cpu(uif->altsetting[i].endpoint[1].desc. - wMaxPacketSize); - dev->alt_max_pkt_size[i] = - (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - } - -#ifdef CONFIG_MODULES - /* request some modules */ - if (dev->decoder == EM2820_SAA7113 || dev->decoder == EM2820_SAA7114) - request_module("saa711x"); - if (dev->decoder == EM2820_TVP5150) - request_module("tvp5150"); - if (dev->has_tuner) - request_module("tuner"); - if (dev->tda9887_conf) - request_module("tda9887"); -#endif - errCode = em2820_config(dev); - if (errCode) { - em2820_errdev("error configuring device\n"); - kfree(dev); - return -ENOMEM; - } - - down(&dev->lock); - /* register i2c bus */ - em2820_i2c_register(dev); - - /* Do board specific init and eeprom reading */ - em2820_card_setup(dev); - - /* configure the device */ - em2820_config_i2c(dev); - - up(&dev->lock); - - errCode = em2820_config(dev); - -#ifdef CONFIG_MODULES - if (dev->has_msp34xx) - request_module("msp3400"); -#endif - /* allocate and fill v4l2 device struct */ - dev->vdev = video_device_alloc(); - if (NULL == dev->vdev) { - em2820_errdev("cannot allocate video_device.\n"); - kfree(dev); - return -ENOMEM; - } -#if 0 - dev->vbi_dev = video_device_alloc(); - dev->vbi_dev->type = VID_TYPE_TELETEXT; - dev->vbi_dev->hardware = 0; - dev->vbi_dev->fops = &em2820_v4l_fops; - dev->vbi_dev->minor = -1; - dev->vbi_dev->dev = &dev->udev->dev; - dev->vbi_dev->release = video_device_release; - snprintf(dev->vbi_dev->name, sizeof(dev->vbi_dev->name), "%s", - "em2820 vbi"); -#endif - - dev->vdev->type = VID_TYPE_CAPTURE; - if (dev->has_tuner) - dev->vdev->type |= VID_TYPE_TUNER; - dev->vdev->hardware = 0; - dev->vdev->fops = &em2820_v4l_fops; -#if 0 - dev->vdev->f_op=&em2820_v4l_fops; -#endif - dev->vdev->minor = -1; - dev->vdev->dev = &dev->udev->dev; - dev->vdev->release = video_device_release; - snprintf(dev->vdev->name, sizeof(dev->vdev->name), "%s", - "em2820 video"); - list_add_tail(&dev->devlist,&em2820_devlist); -#if 0 - video_set_drvdata(dev->vbi_dev, dev); -#endif - - /* register v4l2 device */ - down(&dev->lock); - if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1))) { - em2820_errdev("unable to register video device (error=%i).\n", - retval); - up(&dev->lock); - list_del(&dev->devlist); - video_device_release(dev->vdev); - kfree(dev); - return -ENODEV; - } -#if 0 - if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1) < 0) { - printk("unable to register vbi device\n"); - } else { - printk("registered VBI\n"); - } -#endif - if (dev->has_msp34xx) { - /* Send a reset to other chips via gpio */ - em2820_write_regs_req(dev, 0x00, 0x08, "\xf7", 1); - udelay(2500); - em2820_write_regs_req(dev, 0x00, 0x08, "\xff", 1); - udelay(2500); - - } - video_mux(dev, 0); - - up(&dev->lock); - - em2820_info("V4L2 device registered as /dev/video%d\n", - dev->vdev->minor); - - return 0; -} - -/* - * em2820_usb_probe() - * checks for supported devices - */ -static int em2820_usb_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - const struct usb_endpoint_descriptor *endpoint; - struct usb_device *udev; - struct em2820 *dev = NULL; - int retval = -ENODEV; - int model,i,nr,ifnum; - - udev = usb_get_dev(interface_to_usbdev(interface)); - ifnum = interface->altsetting[0].desc.bInterfaceNumber; - - - /* Don't register audio interfaces */ - if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { - em2820_err(DRIVER_NAME " audio device (%04x:%04x): interface %i, class %i\n", - udev->descriptor.idVendor,udev->descriptor.idProduct, - ifnum, - interface->altsetting[0].desc.bInterfaceClass); - return -ENODEV; - } - - em2820_err(DRIVER_NAME " new video device (%04x:%04x): interface %i, class %i\n", - udev->descriptor.idVendor,udev->descriptor.idProduct, - ifnum, - interface->altsetting[0].desc.bInterfaceClass); - - endpoint = &interface->cur_altsetting->endpoint[1].desc; - - /* check if the the device has the iso in endpoint at the correct place */ - if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != - USB_ENDPOINT_XFER_ISOC) { - em2820_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n"); - return -ENODEV; - } - if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { - em2820_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n"); - return -ENODEV; - } - - model=id->driver_info; - nr=interface->minor; - - if (nr>EM2820_MAXBOARDS) { - printk ("em2820: Supports only %i em28xx boards.\n",EM2820_MAXBOARDS); - return -ENOMEM; - } - - /* allocate memory for our device state and initialize it */ - dev = kmalloc(sizeof(*dev), GFP_KERNEL); - if (dev == NULL) { - em2820_err(DRIVER_NAME ": out of memory!\n"); - return -ENOMEM; - } - memset(dev, 0, sizeof(*dev)); - - snprintf(dev->name, 29, "em2820 #%d", nr); - - if ((card[nr]>=0)&&(card[nr]<em2820_bcount)) - model=card[nr]; - - if ((model==EM2800_BOARD_UNKNOWN)||(model==EM2820_BOARD_UNKNOWN)) { - printk( "%s: Your board has no eeprom inside it and thus can't\n" - "%s: be autodetected. Please pass card=<n> insmod option to\n" - "%s: workaround that. Redirect complaints to the vendor of\n" - "%s: the TV card. Best regards,\n" - "%s: -- tux\n", - dev->name,dev->name,dev->name,dev->name,dev->name); - printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n", - dev->name); - for (i = 0; i < em2820_bcount; i++) { - printk("%s: card=%d -> %s\n", - dev->name, i, em2820_boards[i].name); - } - } - - /* allocate device struct */ - retval = em2820_init_dev(&dev, udev, nr, model); - if (retval) - return retval; - - em2820_info("Found %s\n", em2820_boards[model].name); - - /* save our data pointer in this interface device */ - usb_set_intfdata(interface, dev); - return 0; -} - -/* - * em2820_usb_disconnect() - * called when the device gets diconencted - * video device will be unregistered on v4l2_close in case it is still open - */ -static void em2820_usb_disconnect(struct usb_interface *interface) -{ - struct em2820 *dev = usb_get_intfdata(interface); - usb_set_intfdata(interface, NULL); - - if (!dev) - return; - - down_write(&em2820_disconnect); - - down(&dev->lock); - - em2820_info("disconnecting %s\n", dev->vdev->name); - - wake_up_interruptible_all(&dev->open); - - if (dev->users) { - em2820_warn - ("device /dev/video%d is open! Deregistration and memory " - "deallocation are deferred on close.\n", dev->vdev->minor); - dev->state |= DEV_MISCONFIGURED; - em2820_uninit_isoc(dev); - dev->state |= DEV_DISCONNECTED; - wake_up_interruptible(&dev->wait_frame); - wake_up_interruptible(&dev->wait_stream); - } else { - dev->state |= DEV_DISCONNECTED; - em2820_release_resources(dev); - } - - up(&dev->lock); - - if (!dev->users) - kfree(dev); - - up_write(&em2820_disconnect); - -} - -static struct usb_driver em2820_usb_driver = { - .owner = THIS_MODULE, - .name = "em2820", - .probe = em2820_usb_probe, - .disconnect = em2820_usb_disconnect, - .id_table = em2820_id_table, -}; - -static int __init em2820_module_init(void) -{ - int result; - - printk(KERN_INFO DRIVER_NAME " v4l2 driver version %d.%d.%d loaded\n", - (EM2820_VERSION_CODE >> 16) & 0xff, - (EM2820_VERSION_CODE >> 8) & 0xff, EM2820_VERSION_CODE & 0xff); -#ifdef SNAPSHOT - printk(KERN_INFO DRIVER_NAME " snapshot date %04d-%02d-%02d\n", - SNAPSHOT / 10000, (SNAPSHOT / 100) % 100, SNAPSHOT % 100); -#endif - - /* register this driver with the USB subsystem */ - result = usb_register(&em2820_usb_driver); - if (result) - em2820_err(DRIVER_NAME - " usb_register failed. Error number %d.\n", result); - - return result; -} - -static void __exit em2820_module_exit(void) -{ - /* deregister this driver with the USB subsystem */ - usb_deregister(&em2820_usb_driver); -} - -module_init(em2820_module_init); -module_exit(em2820_module_exit); diff --git a/linux/drivers/usb/media/em2820.h b/linux/drivers/usb/media/em2820.h deleted file mode 100644 index d80b86679..000000000 --- a/linux/drivers/usb/media/em2820.h +++ /dev/null @@ -1,514 +0,0 @@ -/* - em2820-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices - - Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> - Ludovico Cavedon <cavedon@sssup.it> - Mauro Carvalho Chehab <mchehab@brturbo.com.br> - - Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> - - 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 02139, USA. - */ - -#ifndef _EM2820_H -#define _EM2820_H - -#include "compat.h" -#include <linux/videodev.h> -#include <linux/i2c.h> -#include <media/ir-kbd-i2c.h> - -/* Boards supported by driver */ - -#define EM2800_BOARD_UNKNOWN 0 -#define EM2820_BOARD_UNKNOWN 1 -#define EM2820_BOARD_TERRATEC_CINERGY_250 2 -#define EM2820_BOARD_PINNACLE_USB_2 3 -#define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4 -#define EM2820_BOARD_MSI_VOX_USB_2 5 -#define EM2800_BOARD_TERRATEC_CINERGY_200 6 -#define EM2800_BOARD_LEADTEK_WINFAST_USBII 7 -#define EM2800_BOARD_KWORLD_USB2800 8 -#define EM2820_BOARD_PINNACLE_DVC_90 9 - -#define UNSET -1 - -/* maximum number of em28xx boards */ -#define EM2820_MAXBOARDS 1 /*FIXME: should be bigger */ - -/* maximum number of frames that can be queued */ -#define EM2820_NUM_FRAMES 5 -/* number of frames that get used for v4l2_read() */ -#define EM2820_NUM_READ_FRAMES 2 - -/* number of buffers for isoc transfers */ -#define EM2820_NUM_BUFS 5 - -/* number of packets for each buffer - windows requests only 40 packets .. so we better do the same - this is what I found out for all alternate numbers there! - */ -#define EM2820_NUM_PACKETS 40 - -/* default alternate; 0 means choose the best */ -#define EM2820_PINOUT 0 -#define EM2820_MAX_ALT 7 - -#define EM2820_INTERLACED_DEFAULT 1 - -/* -#define (use usbview if you want to get the other alternate number infos) -#define -#define alternate number 2 -#define Endpoint Address: 82 - Direction: in - Attribute: 1 - Type: Isoc - Max Packet Size: 1448 - Interval: 125us - - alternate number 7 - - Endpoint Address: 82 - Direction: in - Attribute: 1 - Type: Isoc - Max Packet Size: 3072 - Interval: 125us -*/ - -/* time to wait when stopping the isoc transfer */ -#define EM2820_URB_TIMEOUT msecs_to_jiffies(EM2820_NUM_BUFS * EM2820_NUM_PACKETS) - -/* time in msecs to wait for i2c writes to finish */ -#define EM2800_I2C_WRITE_TIMEOUT 20 - -/* the various frame states */ -enum em2820_frame_state { - F_UNUSED = 0, - F_QUEUED, - F_GRABBING, - F_DONE, - F_ERROR, -}; - -/* stream states */ -enum em2820_stream_state { - STREAM_OFF, - STREAM_INTERRUPT, - STREAM_ON, -}; - -/* frames */ -struct em2820_frame_t { - void *bufmem; - struct v4l2_buffer buf; - enum em2820_frame_state state; - struct list_head frame; - unsigned long vma_use_count; - int top_field; - int fieldbytesused; -}; - -/* io methods */ -enum em2820_io_method { - IO_NONE, - IO_READ, - IO_MMAP, -}; - -/* inputs */ - -#define MAX_EM2820_INPUT 4 -enum enum2820_itype { - EM2820_VMUX_COMPOSITE1 = 1, - EM2820_VMUX_COMPOSITE2, - EM2820_VMUX_COMPOSITE3, - EM2820_VMUX_COMPOSITE4, - EM2820_VMUX_SVIDEO, - EM2820_VMUX_TELEVISION, - EM2820_VMUX_CABLE, - EM2820_VMUX_DVB, - EM2820_VMUX_DEBUG, - EM2820_RADIO, -}; - -struct em2820_input { - enum enum2820_itype type; - unsigned int vmux; - unsigned int amux; -}; - -#define INPUT(nr) (&em2820_boards[dev->model].input[nr]) - -enum em2820_decoder { - EM2820_TVP5150, - EM2820_SAA7113, - EM2820_SAA7114 -}; - -struct em2820_board { - char *name; - int vchannels; - int norm; - int tuner_type; - - /* i2c flags */ - unsigned int is_em2800; - unsigned int tda9887_conf; - - unsigned int has_tuner:1; - unsigned int has_msp34xx:1; - - enum em2820_decoder decoder; - - struct em2820_input input[MAX_EM2820_INPUT]; -}; - -struct em2820_eeprom { - u32 id; /* 0x9567eb1a */ - u16 vendor_ID; - u16 product_ID; - - u16 chip_conf; - - u16 board_conf; - - u16 string1, string2, string3; - - u8 string_idx_table; -}; - -/* device states */ -enum em2820_dev_state { - DEV_INITIALIZED = 0x01, - DEV_DISCONNECTED = 0x02, - DEV_MISCONFIGURED = 0x04, -}; - -/* tvnorms */ -struct em2820_tvnorm { - char *name; - v4l2_std_id id; - /* mode for saa7113h */ - int mode; -}; - -/* main device struct */ -struct em2820 { - /* generic device properties */ - char name[30]; /* name (including minor) of the device */ - int model; /* index in the device_data struct */ - unsigned int is_em2800; - int video_inputs; /* number of video inputs */ - struct list_head devlist; - unsigned int has_tuner:1; - unsigned int has_msp34xx:1; - unsigned int has_tda9887:1; - - enum em2820_decoder decoder; - - int tuner_type; /* type of the tuner */ - int tuner_addr; /* tuner address */ - int tda9887_conf; - /* i2c i/o */ - struct i2c_adapter i2c_adap; - struct i2c_client i2c_client; - /* video for linux */ - int users; /* user count for exclusive use */ - struct video_device *vdev; /* video for linux device struct */ - struct video_picture vpic; /* picture settings only used to init saa7113h */ - struct em2820_tvnorm *tvnorm; /* selected tv norm */ - int ctl_freq; /* selected frequency */ - unsigned int ctl_input; /* selected input */ - unsigned int ctl_ainput; /* slected audio input */ - int mute; - int volume; - /* frame properties */ - struct em2820_frame_t frame[EM2820_NUM_FRAMES]; /* list of frames */ - int num_frames; /* number of frames currently in use */ - unsigned int frame_count; /* total number of transfered frames */ - struct em2820_frame_t *frame_current; /* the frame that is being filled */ - int width; /* current frame width */ - int height; /* current frame height */ - int frame_size; /* current frame size */ - int field_size; /* current field size */ - int bytesperline; - int hscale; /* horizontal scale factor (see datasheet) */ - int vscale; /* vertical scale factor (see datasheet) */ - int interlaced; /* 1=interlace fileds, 0=just top fileds */ - int type; - - /* states */ - enum em2820_dev_state state; - enum em2820_stream_state stream; - enum em2820_io_method io; - /* locks */ - struct semaphore lock, fileop_lock; - spinlock_t queue_lock; - struct list_head inqueue, outqueue; - wait_queue_head_t open, wait_frame, wait_stream; - struct video_device *vbi_dev; - - unsigned char eedata[256]; - - /* usb transfer */ - struct usb_device *udev; /* the usb device */ - int alt; /* alternate */ - int max_pkt_size; /* max packet size of isoc transaction */ - unsigned int alt_max_pkt_size[EM2820_MAX_ALT + 1]; /* array of wMaxPacketSize */ - struct urb *urb[EM2820_NUM_BUFS]; /* urb for isoc transfers */ - char *transfer_buffer[EM2820_NUM_BUFS]; /* transfer buffers for isoc transfer */ - /* helper funcs that call usb_control_msg */ - int (*em2820_write_regs) (struct em2820 * dev, u16 reg, char *buf, - int len); - int (*em2820_read_reg) (struct em2820 * dev, u16 reg); - int (*em2820_read_reg_req_len) (struct em2820 * dev, u8 req, u16 reg, - char *buf, int len); - int (*em2820_write_regs_req) (struct em2820 * dev, u8 req, u16 reg, - char *buf, int len); - int (*em2820_read_reg_req) (struct em2820 * dev, u8 req, u16 reg); -}; - -/* Provided by em2820-i2c.c */ - -void em2820_i2c_call_clients(struct em2820 *dev, unsigned int cmd, void *arg); -int em2820_i2c_register(struct em2820 *dev); -int em2820_i2c_unregister(struct em2820 *dev); - -/* Provided by em2820-input.c */ - -void em2820_set_ir(struct em2820 * dev,struct IR_i2c *ir); - -/* Provided by em2820-core.c */ - -void em2820_print_ioctl(char *name, unsigned int cmd); - -u32 em2820_request_buffers(struct em2820 *dev, u32 count); -void em2820_queue_unusedframes(struct em2820 *dev); -void em2820_release_buffers(struct em2820 *dev); - -int em2820_read_reg_req_len(struct em2820 *dev, u8 req, u16 reg, - char *buf, int len); -int em2820_read_reg_req(struct em2820 *dev, u8 req, u16 reg); -int em2820_read_reg(struct em2820 *dev, u16 reg); -int em2820_write_regs_req(struct em2820 *dev, u8 req, u16 reg, char *buf, - int len); -int em2820_write_regs(struct em2820 *dev, u16 reg, char *buf, int len); -int em2820_write_reg_bits(struct em2820 *dev, u16 reg, u8 val, - u8 bitmask); -int em2820_write_ac97(struct em2820 *dev, u8 reg, u8 * val); -int em2820_audio_analog_set(struct em2820 *dev); -int em2820_colorlevels_set_default(struct em2820 *dev); -int em2820_capture_start(struct em2820 *dev, int start); -int em2820_outfmt_set_yuv422(struct em2820 *dev); -int em2820_accumulator_set(struct em2820 *dev, u8 xmin, u8 xmax, u8 ymin, - u8 ymax); -int em2820_capture_area_set(struct em2820 *dev, u8 hstart, u8 vstart, - u16 width, u16 height); -int em2820_scaler_set(struct em2820 *dev, u16 h, u16 v); -int em2820_resolution_set(struct em2820 *dev); -void em2820_isocIrq(struct urb *urb, struct pt_regs *regs); -int em2820_init_isoc(struct em2820 *dev); -void em2820_uninit_isoc(struct em2820 *dev); -int em2820_set_alternate(struct em2820 *dev); - -/* Provided by em2820-cards.c */ -extern int em2800_variant_detect(struct usb_device* udev,int model); -extern void em2820_card_setup(struct em2820 *dev); -extern struct em2820_board em2820_boards[]; -extern struct usb_device_id em2820_id_table[]; -extern const unsigned int em2820_bcount; - -/* em2820 registers */ -#define CHIPID_REG 0x0a -#define USBSUSP_REG 0x0c /* */ - -#define AUDIOSRC_REG 0x0e -#define XCLK_REG 0x0f - -#define VINMODE_REG 0x10 -#define VINCTRL_REG 0x11 -#define VINENABLE_REG 0x12 /* */ - -#define GAMMA_REG 0x14 -#define RGAIN_REG 0x15 -#define GGAIN_REG 0x16 -#define BGAIN_REG 0x17 -#define ROFFSET_REG 0x18 -#define GOFFSET_REG 0x19 -#define BOFFSET_REG 0x1a - -#define OFLOW_REG 0x1b -#define HSTART_REG 0x1c -#define VSTART_REG 0x1d -#define CWIDTH_REG 0x1e -#define CHEIGHT_REG 0x1f - -#define YGAIN_REG 0x20 -#define YOFFSET_REG 0x21 -#define UVGAIN_REG 0x22 -#define UOFFSET_REG 0x23 -#define VOFFSET_REG 0x24 -#define SHARPNESS_REG 0x25 - -#define COMPR_REG 0x26 -#define OUTFMT_REG 0x27 - -#define XMIN_REG 0x28 -#define XMAX_REG 0x29 -#define YMIN_REG 0x2a -#define YMAX_REG 0x2b - -#define HSCALELOW_REG 0x30 -#define HSCALEHIGH_REG 0x31 -#define VSCALELOW_REG 0x32 -#define VSCALEHIGH_REG 0x33 - -#define AC97LSB_REG 0x40 -#define AC97MSB_REG 0x41 -#define AC97ADDR_REG 0x42 -#define AC97BUSY_REG 0x43 - -/* em202 registers */ -#define MASTER_AC97 0x02 -#define VIDEO_AC97 0x14 - -/* register settings */ -#define EM2820_AUDIO_SRC_TUNER 0xc0 -#define EM2820_AUDIO_SRC_LINE 0x80 - -/* printk macros */ - -#define em2820_err(fmt, arg...) do {\ - printk(KERN_ERR fmt, ##arg); } while (0) - -#define em2820_errdev(fmt, arg...) do {\ - printk(KERN_ERR "%s: "fmt,\ - dev->name, ##arg); } while (0) - -#define em2820_info(fmt, arg...) do {\ - printk(KERN_INFO "%s: "fmt,\ - dev->name, ##arg); } while (0) -#define em2820_warn(fmt, arg...) do {\ - printk(KERN_WARNING "%s: "fmt,\ - dev->name, ##arg); } while (0) - -inline static int em2820_audio_source(struct em2820 *dev, int input) -{ - return em2820_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0); -} - -inline static int em2820_audio_usb_mute(struct em2820 *dev, int mute) -{ - return em2820_write_reg_bits(dev, XCLK_REG, mute ? 0x00 : 0x80, 0x80); -} - -inline static int em2820_audio_analog_setup(struct em2820 *dev) -{ - /* unmute video mixer with default volume level */ - return em2820_write_ac97(dev, VIDEO_AC97, "\x08\x08"); -} - -inline static int em2820_compression_disable(struct em2820 *dev) -{ - /* side effect of disabling scaler and mixer */ - return em2820_write_regs(dev, COMPR_REG, "\x00", 1); -} - -inline static int em2820_contrast_get(struct em2820 *dev) -{ - return em2820_read_reg(dev, YGAIN_REG) & 0x1f; -} - -inline static int em2820_brightness_get(struct em2820 *dev) -{ - return em2820_read_reg(dev, YOFFSET_REG); -} - -inline static int em2820_saturation_get(struct em2820 *dev) -{ - return em2820_read_reg(dev, UVGAIN_REG) & 0x1f; -} - -inline static int em2820_u_balance_get(struct em2820 *dev) -{ - return em2820_read_reg(dev, UOFFSET_REG); -} - -inline static int em2820_v_balance_get(struct em2820 *dev) -{ - return em2820_read_reg(dev, VOFFSET_REG); -} - -inline static int em2820_gamma_get(struct em2820 *dev) -{ - return em2820_read_reg(dev, GAMMA_REG) & 0x3f; -} - -inline static int em2820_contrast_set(struct em2820 *dev, s32 val) -{ - u8 tmp = (u8) val; - return em2820_write_regs(dev, YGAIN_REG, &tmp, 1); -} - -inline static int em2820_brightness_set(struct em2820 *dev, s32 val) -{ - u8 tmp = (u8) val; - return em2820_write_regs(dev, YOFFSET_REG, &tmp, 1); -} - -inline static int em2820_saturation_set(struct em2820 *dev, s32 val) -{ - u8 tmp = (u8) val; - return em2820_write_regs(dev, UVGAIN_REG, &tmp, 1); -} - -inline static int em2820_u_balance_set(struct em2820 *dev, s32 val) -{ - u8 tmp = (u8) val; - return em2820_write_regs(dev, UOFFSET_REG, &tmp, 1); -} - -inline static int em2820_v_balance_set(struct em2820 *dev, s32 val) -{ - u8 tmp = (u8) val; - return em2820_write_regs(dev, VOFFSET_REG, &tmp, 1); -} - -inline static int em2820_gamma_set(struct em2820 *dev, s32 val) -{ - u8 tmp = (u8) val; - return em2820_write_regs(dev, GAMMA_REG, &tmp, 1); -} - -/*FIXME: maxw should be dependent of alt mode */ -inline static unsigned int norm_maxw(struct em2820 *dev) -{ - switch(dev->model){ - case (EM2820_BOARD_MSI_VOX_USB_2): return(640); - default: return(720); - } -} - -inline static unsigned int norm_maxh(struct em2820 *dev) -{ - switch(dev->model){ - case (EM2820_BOARD_MSI_VOX_USB_2): return(480); - default: return (dev->tvnorm->id & V4L2_STD_625_50) ? 576 : 480; - } -} - -#endif |