diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-09 22:42:07 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-09 22:42:07 -0300 |
commit | 06baaa0441c7fec2a211ddf7c502f837cd988132 (patch) | |
tree | 284236ae49b1385a091119cf7b3520bc7d64552a /linux/drivers/media/video/em28xx | |
parent | e5561cf14fe189f7f0d726a1c66ffa992354ab2d (diff) | |
parent | d784aba6717da44bfef18007146f6d00280e39fe (diff) | |
download | mediapointer-dvb-s2-06baaa0441c7fec2a211ddf7c502f837cd988132.tar.gz mediapointer-dvb-s2-06baaa0441c7fec2a211ddf7c502f837cd988132.tar.bz2 |
merge: http://linuxtv.org/hg/~mkrufky/fusionhdtv7
From: Mauro Carvalho Chehab <mchehab@infradead.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/video/em28xx')
-rw-r--r-- | linux/drivers/media/video/em28xx/em28xx-audio.c | 18 | ||||
-rw-r--r-- | linux/drivers/media/video/em28xx/em28xx-cards.c | 78 | ||||
-rw-r--r-- | linux/drivers/media/video/em28xx/em28xx-dvb.c | 62 | ||||
-rw-r--r-- | linux/drivers/media/video/em28xx/em28xx-i2c.c | 19 | ||||
-rw-r--r-- | linux/drivers/media/video/em28xx/em28xx-input.c | 107 | ||||
-rw-r--r-- | linux/drivers/media/video/em28xx/em28xx-reg.h | 1 | ||||
-rw-r--r-- | linux/drivers/media/video/em28xx/em28xx-video.c | 62 | ||||
-rw-r--r-- | linux/drivers/media/video/em28xx/em28xx.h | 16 |
8 files changed, 270 insertions, 93 deletions
diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index 609e28e77..904973305 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -299,6 +299,12 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) dprintk("opening device and trying to acquire exclusive lock\n"); + if (!dev) { + printk(KERN_ERR "BUG: em28xx can't find device struct." + " Can't proceed with open\n"); + return -ENODEV; + } + /* Sets volume, mute, etc */ dev->mute = 0; @@ -486,6 +492,12 @@ static int em28xx_audio_init(struct em28xx *dev) static int devnr; int ret, err; + if (dev->has_audio_class) { + /* This device does not support the extension (in this case + the device is expecting the snd-usb-audio module */ + return 0; + } + printk(KERN_INFO "em28xx-audio.c: probing for em28x1 " "non standard usbaudio\n"); printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus " @@ -529,6 +541,12 @@ static int em28xx_audio_fini(struct em28xx *dev) if (dev == NULL) return 0; + if (dev->has_audio_class) { + /* This device does not support the extension (in this case + the device is expecting the snd-usb-audio module */ + return 0; + } + if (dev->adev) { snd_card_free(dev->adev->sndcard); kfree(dev->adev); diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index a9b6a5ecd..871d81242 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -158,6 +158,28 @@ struct em28xx_board em28xx_boards[] = { .tda9887_conf = TDA9887_PRESENT, .tuner_type = TUNER_XC2028, .mts_firmware = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = { + .name = "Hauppauge WinTV HVR 900 (R2)", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -196,6 +218,29 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, + [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = { + .name = "Pinnacle PCTV HD Pro Stick", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_12mhz_i2s = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, [EM2880_BOARD_TERRATEC_HYBRID_XS] = { .name = "Terratec Hybrid XS", .vchannels = 3, @@ -382,6 +427,19 @@ struct em28xx_board em28xx_boards[] = { .amux = EM28XX_AMUX_LINE_IN, } }, }, + [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = { + .name = "PointNix Intra-Oral Camera", + .has_snapshot_button = 1, + .vchannels = 1, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_ABSENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 0, + } }, + }, }; const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); @@ -417,10 +475,12 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, { USB_DEVICE(0x2304, 0x021a), .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, + { USB_DEVICE(0x2304, 0x0227), + .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO }, { USB_DEVICE(0x2040, 0x6500), .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, { USB_DEVICE(0x2040, 0x6502), - .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, + .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 }, { USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */ .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x2040, 0x6517), /* HP HVR-950 */ @@ -476,6 +536,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash [] = { static struct em28xx_hash_table em28xx_i2c_hash[] = { {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC}, {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, + {0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT}, }; int em28xx_tuner_callback(void *ptr, int command, int arg) @@ -508,6 +569,7 @@ static void em28xx_set_model(struct em28xx *dev) dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s; dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480; dev->has_dvb = em28xx_boards[dev->model].has_dvb; + dev->has_snapshot_button = em28xx_boards[dev->model].has_snapshot_button; } /* Since em28xx_pre_card_setup() requires a proper dev->model, @@ -525,6 +587,9 @@ void em28xx_pre_card_setup(struct em28xx *dev) rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); if (rc > 0) { switch (rc) { + case CHIP_ID_EM2860: + em28xx_info("chip ID is em2860\n"); + break; case CHIP_ID_EM2883: em28xx_info("chip ID is em2882/em2883\n"); dev->wait_after_write = 0; @@ -539,8 +604,10 @@ void em28xx_pre_card_setup(struct em28xx *dev) switch (dev->model) { case EM2880_BOARD_TERRATEC_PRODIGY_XS: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: + case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: case EM2880_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); msleep(50); @@ -573,7 +640,12 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: ctl->demod = XC3028_FE_ZARLINK456; break; + case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: + /* djh - Not sure which demod we need here */ + ctl->demod = XC3028_FE_DEFAULT; + break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: /* FIXME: Better to specify the needed IF */ ctl->demod = XC3028_FE_DEFAULT; break; @@ -751,6 +823,7 @@ void em28xx_card_setup(struct em28xx *dev) switch (dev->model) { case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: + case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: { struct tveeprom tv; @@ -784,6 +857,9 @@ void em28xx_card_setup(struct em28xx *dev) em28xx_set_model(dev); } + if (dev->has_snapshot_button) + em28xx_register_snapshot_button(dev); + /* Allow override tuner type by a module parameter */ if (tuner >= 0) dev->tuner_type = tuner; diff --git a/linux/drivers/media/video/em28xx/em28xx-dvb.c b/linux/drivers/media/video/em28xx/em28xx-dvb.c index a890b8a32..b8a5c61ce 100644 --- a/linux/drivers/media/video/em28xx/em28xx-dvb.c +++ b/linux/drivers/media/video/em28xx/em28xx-dvb.c @@ -5,6 +5,7 @@ (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> - Fixes for the driver to properly work with HVR-950 + - Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick (c) 2008 Aidan Thornton <makosoft@googlemail.com> @@ -27,6 +28,9 @@ #include "lgdt330x.h" #include "zl10353.h" +#ifdef EM28XX_DRX397XD_SUPPORT +#include "drx397xD.h" +#endif MODULE_DESCRIPTION("driver for em28xx based DVB cards"); MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); @@ -59,11 +63,7 @@ struct em28xx_dvb { int nfeeds; /* general boilerplate stuff */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) struct dvb_adapter adapter; -#else - struct dvb_adapter *adapter; -#endif struct dvb_demux demux; struct dmxdev dmxdev; struct dmx_frontend fe_hw; @@ -236,6 +236,13 @@ static struct zl10353_config em28xx_zl10353_with_xc3028 = { .if2 = 45600, }; +#ifdef EM28XX_DRX397XD_SUPPORT +/* [TODO] djh - not sure yet what the device config needs to contain */ +static struct drx397xD_config em28xx_drx397xD_with_xc3028 = { + .demod_address = (0xe0 >> 1), +}; +#endif + /* ------------------------------------------------------------------ */ static int attach_xc3028(u8 addr, struct em28xx *dev) @@ -292,17 +299,10 @@ int register_dvb(struct em28xx_dvb *dvb, /* Ensure all frontends negotiate bus access */ dvb->frontend->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) dvb->adapter.priv = dev; /* register frontend */ result = dvb_register_frontend(&dvb->adapter, dvb->frontend); -#else - dvb->adapter->priv = dev; - - /* register frontend */ - result = dvb_register_frontend(dvb->adapter, dvb->frontend); -#endif if (result < 0) { printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", dev->name, result); @@ -329,11 +329,7 @@ int register_dvb(struct em28xx_dvb *dvb, dvb->dmxdev.filternum = 256; dvb->dmxdev.demux = &dvb->demux.dmx; dvb->dmxdev.capabilities = 0; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); -#else - result = dvb_dmxdev_init(&dvb->dmxdev, dvb->adapter); -#endif if (result < 0) { printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", dev->name, result); @@ -364,11 +360,7 @@ int register_dvb(struct em28xx_dvb *dvb, } /* register network adapter */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); -#else - dvb_net_init(dvb->adapter, &dvb->net, &dvb->demux.dmx); -#endif return 0; fail_fe_conn: @@ -383,11 +375,7 @@ fail_dmx: dvb_unregister_frontend(dvb->frontend); fail_frontend: dvb_frontend_detach(dvb->frontend); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) dvb_unregister_adapter(&dvb->adapter); -#else - dvb_unregister_adapter(dvb->adapter); -#endif fail_adapter: return result; } @@ -401,11 +389,7 @@ static void unregister_dvb(struct em28xx_dvb *dvb) dvb_dmx_release(&dvb->demux); dvb_unregister_frontend(dvb->frontend); dvb_frontend_detach(dvb->frontend); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) dvb_unregister_adapter(&dvb->adapter); -#else - dvb_unregister_adapter(dvb->adapter); -#endif } @@ -414,6 +398,11 @@ static int dvb_init(struct em28xx *dev) int result = 0; struct em28xx_dvb *dvb; + if (!dev->has_dvb) { + /* This device does not support the extension */ + return 0; + } + dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); if (dvb == NULL) { @@ -426,6 +415,7 @@ static int dvb_init(struct em28xx *dev) /* init frontend */ switch (dev->model) { case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: dvb->frontend = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, &dev->i2c_adap); @@ -443,6 +433,19 @@ static int dvb_init(struct em28xx *dev) goto out_free; } break; + case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: +#ifdef EM28XX_DRX397XD_SUPPORT + /* We don't have the config structure properly populated, so + this is commented out for now */ + dvb->frontend = dvb_attach(drx397xD_attach, + &em28xx_drx397xD_with_xc3028, + &dev->i2c_adap); + if (attach_xc3028(0x61, dev) < 0) { + result = -EINVAL; + goto out_free; + } + break; +#endif default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" " isn't supported yet\n", @@ -476,6 +479,11 @@ out_free: static int dvb_fini(struct em28xx *dev) { + if (!dev->has_dvb) { + /* This device does not support the extension */ + return 0; + } + if (dev->dvb) { unregister_dvb(dev->dvb); dev->dvb = NULL; diff --git a/linux/drivers/media/video/em28xx/em28xx-i2c.c b/linux/drivers/media/video/em28xx/em28xx-i2c.c index c22e73019..4d6f650da 100644 --- a/linux/drivers/media/video/em28xx/em28xx-i2c.c +++ b/linux/drivers/media/video/em28xx/em28xx-i2c.c @@ -432,18 +432,6 @@ 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 - /* * attach_inform() * gets called when a device attaches to the i2c bus @@ -521,15 +509,8 @@ static struct i2c_algorithm em28xx_algo = { }; static struct i2c_adapter em28xx_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 = "em28xx", .id = I2C_HW_B_EM28XX, .algo = &em28xx_algo, diff --git a/linux/drivers/media/video/em28xx/em28xx-input.c b/linux/drivers/media/video/em28xx/em28xx-input.c index 49c40f083..e83e3bebd 100644 --- a/linux/drivers/media/video/em28xx/em28xx-input.c +++ b/linux/drivers/media/video/em28xx/em28xx-input.c @@ -31,6 +31,10 @@ #include "compat.h" #include "em28xx.h" +#define EM28XX_SNAPSHOT_KEY KEY_CAMERA +#define EM28XX_SBUTTON_QUERY_INTERVAL 500 +#define EM28XX_R0C_USBSUSP_SNAPSHOT 0x20 + static unsigned int ir_debug; module_param(ir_debug, int, 0644); MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); @@ -130,6 +134,109 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, return 1; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void em28xx_query_sbutton(void *data) +#else +static void em28xx_query_sbutton(struct work_struct *work) +#endif +{ + /* Poll the register and see if the button is depressed */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + struct em28xx *dev = data; +#else + struct em28xx *dev = + container_of(work, struct em28xx, sbutton_query_work.work); +#endif + int ret; + + ret = em28xx_read_reg(dev, EM28XX_R0C_USBSUSP); + + if (ret & EM28XX_R0C_USBSUSP_SNAPSHOT) { + u8 cleared; + /* Button is depressed, clear the register */ + cleared = ((u8) ret) & ~EM28XX_R0C_USBSUSP_SNAPSHOT; + em28xx_write_regs(dev, EM28XX_R0C_USBSUSP, &cleared, 1); + + /* Not emulate the keypress */ + input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY, + 1); + /* Now unpress the key */ + input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY, + 0); + } + + /* Schedule next poll */ + schedule_delayed_work(&dev->sbutton_query_work, + msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL)); +} + +void em28xx_register_snapshot_button(struct em28xx *dev) +{ + struct input_dev *input_dev; + int err; + + em28xx_info("Registering snapshot button...\n"); + input_dev = input_allocate_device(); + if (!input_dev) { + em28xx_errdev("input_allocate_device failed\n"); + return; + } + + usb_make_path(dev->udev, dev->snapshot_button_path, + sizeof(dev->snapshot_button_path)); + strlcat(dev->snapshot_button_path, "/sbutton", + sizeof(dev->snapshot_button_path)); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + INIT_WORK(&dev->sbutton_query_work, em28xx_query_sbutton, dev); +#else + INIT_DELAYED_WORK(&dev->sbutton_query_work, em28xx_query_sbutton); +#endif + + input_dev->name = "em28xx snapshot button"; + input_dev->phys = dev->snapshot_button_path; + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + set_bit(EM28XX_SNAPSHOT_KEY, input_dev->keybit); + input_dev->keycodesize = 0; + input_dev->keycodemax = 0; + input_dev->id.bustype = BUS_USB; + input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); + input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); + input_dev->id.version = 1; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) + input_dev->dev.parent = &dev->udev->dev; +#else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 15) + input_dev->cdev.dev = &dev->udev->dev; +#else + input_dev->dev = &dev->udev->dev; +#endif +#endif + + err = input_register_device(input_dev); + if (err) { + em28xx_errdev("input_register_device failed\n"); + input_free_device(input_dev); + return; + } + + dev->sbutton_input_dev = input_dev; + schedule_delayed_work(&dev->sbutton_query_work, + msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL)); + return; + +} + +void em28xx_deregister_snapshot_button(struct em28xx *dev) +{ + if (dev->sbutton_input_dev != NULL) { + em28xx_info("Deregistering snapshot button\n"); + cancel_rearming_delayed_work(&dev->sbutton_query_work); + input_unregister_device(dev->sbutton_input_dev); + dev->sbutton_input_dev = NULL; + } + return; +} + /* ---------------------------------------------------------------------- * Local variables: * c-basic-offset: 8 diff --git a/linux/drivers/media/video/em28xx/em28xx-reg.h b/linux/drivers/media/video/em28xx/em28xx-reg.h index 9058bed07..fac1ab23f 100644 --- a/linux/drivers/media/video/em28xx/em28xx-reg.h +++ b/linux/drivers/media/video/em28xx/em28xx-reg.h @@ -84,5 +84,6 @@ /* FIXME: Need to be populated with the other chip ID's */ enum em28xx_chip_id { + CHIP_ID_EM2860 = 34, CHIP_ID_EM2883 = 36, }; diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index 9e7965a32..5929d0860 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -42,9 +42,6 @@ #include <media/v4l2-common.h> #include <media/msp3400.h> #include <media/tuner.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#include "i2c-compat.h" -#endif #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ "Markus Rechberger <mrechberger@gmail.com>, " \ @@ -83,25 +80,10 @@ static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -MODULE_PARM(card, "1-" __stringify(EM28XX_MAXBOARDS) "i"); -MODULE_PARM(video_nr, "1-" __stringify(EM28XX_MAXBOARDS) "i"); -MODULE_PARM(vbi_nr, "1-" __stringify(EM28XX_MAXBOARDS) "i"); -MODULE_PARM(radio_nr, "1-" __stringify(EM28XX_MAXBOARDS) "i"); -#else -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) -static int dummy; -module_param_array(card, int, dummy, 0444); -module_param_array(video_nr, int, dummy, 0444); -module_param_array(vbi_nr, int, dummy, 0444); -module_param_array(radio_nr, int, dummy, 0444); -#else module_param_array(card, int, NULL, 0444); module_param_array(video_nr, int, NULL, 0444); module_param_array(vbi_nr, int, NULL, 0444); module_param_array(radio_nr, int, NULL, 0444); -#endif -#endif MODULE_PARM_DESC(card, "card type"); MODULE_PARM_DESC(video_nr, "video device numbers"); MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); @@ -1192,13 +1174,13 @@ static int vidioc_g_register(struct file *file, void *priv, reg->val = ret; } else { - u64 val = 0; + __le64 val = 0; ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, reg->reg, (char *)&val, 2); if (ret < 0) return ret; - reg->val = cpu_to_le64((__u64)val); + reg->val = le64_to_cpu(val); } return 0; @@ -1209,9 +1191,9 @@ static int vidioc_s_register(struct file *file, void *priv, { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - u64 buf; + __le64 buf; - buf = le64_to_cpu((__u64)reg->val); + buf = cpu_to_le64(reg->val); return em28xx_write_regs(dev, reg->reg, (char *)&buf, em28xx_reg_len(reg->reg)); @@ -1667,6 +1649,8 @@ static void em28xx_release_resources(struct em28xx *dev) dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); list_del(&dev->devlist); + if (dev->sbutton_input_dev) + em28xx_deregister_snapshot_button(dev); if (dev->radio_dev) { if (-1 != dev->radio_dev->minor) video_unregister_device(dev->radio_dev); @@ -1835,9 +1819,7 @@ static const struct file_operations em28xx_v4l_fops = { .mmap = em28xx_v4l2_mmap, .ioctl = video_ioctl2, .llseek = no_llseek, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) .compat_ioctl = v4l_compat_ioctl32, -#endif }; static const struct file_operations radio_fops = { @@ -1845,9 +1827,7 @@ static const struct file_operations radio_fops = { .open = em28xx_v4l2_open, .release = em28xx_v4l2_close, .ioctl = video_ioctl2, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) .compat_ioctl = v4l_compat_ioctl32, -#endif .llseek = no_llseek, }; @@ -1934,32 +1914,28 @@ static DEFINE_MUTEX(em28xx_extension_devlist_lock); int em28xx_register_extension(struct em28xx_ops *ops) { - struct em28xx *h, *dev = NULL; - - list_for_each_entry(h, &em28xx_devlist, devlist) - dev = h; + struct em28xx *dev = NULL; mutex_lock(&em28xx_extension_devlist_lock); list_add_tail(&ops->next, &em28xx_extension_devlist); - if (dev) - ops->init(dev); - + list_for_each_entry(dev, &em28xx_devlist, devlist) { + if (dev) + ops->init(dev); + } printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); mutex_unlock(&em28xx_extension_devlist_lock); - return 0; } EXPORT_SYMBOL(em28xx_register_extension); void em28xx_unregister_extension(struct em28xx_ops *ops) { - struct em28xx *h, *dev = NULL; - - list_for_each_entry(h, &em28xx_devlist, devlist) - dev = h; + struct em28xx *dev = NULL; - if (dev) - ops->fini(dev); + list_for_each_entry(dev, &em28xx_devlist, devlist) { + if (dev) + ops->fini(dev); + } mutex_lock(&em28xx_extension_devlist_lock); printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); @@ -1980,10 +1956,8 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, return NULL; *vfd = *template; vfd->minor = -1; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0) vfd->dev = &dev->udev->dev; vfd->release = video_device_release; -#endif vfd->type = type; vfd->debug = video_debug; @@ -2169,9 +2143,6 @@ static void request_module_async(struct work_struct *work) request_module("em28xx-dvb"); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -#define request_modules(dev) -#else static void request_modules(struct em28xx *dev) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) @@ -2182,7 +2153,6 @@ static void request_modules(struct em28xx *dev) #endif schedule_work(&dev->request_module_wk); } -#endif #else #define request_modules(dev) #endif /* CONFIG_MODULES */ diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index d31d11a5e..18b3bc134 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -58,6 +58,9 @@ #define EM2820_BOARD_PROLINK_PLAYTV_USB2 14 #define EM2800_BOARD_VGEAR_POCKETTV 15 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 16 +#define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 +#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 +#define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 @@ -250,6 +253,7 @@ struct em28xx_board { unsigned int has_12mhz_i2s:1; unsigned int max_range_640_480:1; unsigned int has_dvb:1; + unsigned int has_snapshot_button:1; enum em28xx_decoder decoder; @@ -337,6 +341,7 @@ struct em28xx { unsigned int has_12mhz_i2s:1; unsigned int max_range_640_480:1; unsigned int has_dvb:1; + unsigned int has_snapshot_button:1; /* Some older em28xx chips needs a waiting time after writing */ unsigned int wait_after_write; @@ -431,6 +436,15 @@ struct em28xx { /* Caches GPO and GPIO registers */ unsigned char reg_gpo, reg_gpio; + /* Snapshot button */ + char snapshot_button_path[30]; /* path of the input dev */ + struct input_dev *sbutton_input_dev; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + struct work_struct sbutton_query_work; +#else + struct delayed_work sbutton_query_work; +#endif + struct em28xx_dvb *dvb; }; @@ -496,6 +510,8 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); +void em28xx_register_snapshot_button(struct em28xx *dev); +void em28xx_deregister_snapshot_button(struct em28xx *dev); /* printk macros */ |