]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab...
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 11 May 2007 19:57:16 +0000 (12:57 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 11 May 2007 19:57:16 +0000 (12:57 -0700)
* 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (44 commits)
  V4L/DVB (5571): V4l1-compat:  Make VIDIOCSPICT return errors in a useful way
  V4L/DVB (5624): Radio-maestro.c cleanup
  V4L/DVB (5623): Dsbr100.c Replace usb_dsbr100_do_ioctl to use video_ioctl2
  V4L/DVB (5622): Radio-zoltrix.c cleanup
  V4L/DVB (5621): Radio-cadet.c Replace cadet_do_ioctl to use video_ioctl2
  V4L/DVB (5619): Dvb-usb: fix typo
  V4L/DVB (5618): Cx88: Drop the generic i2c client from cx88-vp3054-i2c
  V4L/DVB (5617): V4L2: videodev, allow debugging
  V4L/DVB (5614): M920x: Disable second adapter on LifeView TV Walker Twin
  V4L/DVB (5613): M920x: loosen up 80-col limit
  V4L/DVB (5612): M920x: rename function prefixes from m9206_foo to m920x_foo
  V4L/DVB (5611): M920x: replace deb_rc with deb
  V4L/DVB (5610): M920x: remove duplicated code
  V4L/DVB (5609): M920x: group like functions together
  V4L/DVB (5608): M920x: various whitespace cleanups
  V4L/DVB (5607): M920x: Initial support for devices likely manufactured by Dposh
  V4L/DVB (5606): M920x: add "c-basic-offset: 8" to help emacs to enforce tabbing
  V4L/DVB (5605): M920x: Add support for LifeView TV Walker Twin
  V4L/DVB (5603): V4L: Prevent queueing queued buffers.
  V4L/DVB (5602): Enable DiSEqC in Starbox II (vp7021a)
  ...

65 files changed:
Documentation/video4linux/CARDLIST.saa7134
Documentation/video4linux/sn9c102.txt
drivers/media/Kconfig
drivers/media/Makefile
drivers/media/common/saa7146_core.c
drivers/media/common/saa7146_fops.c
drivers/media/dvb/Kconfig
drivers/media/dvb/dvb-core/Kconfig
drivers/media/dvb/dvb-usb/dvb-usb-ids.h
drivers/media/dvb/dvb-usb/dvb-usb.h
drivers/media/dvb/dvb-usb/m920x.c
drivers/media/dvb/dvb-usb/m920x.h
drivers/media/dvb/dvb-usb/vp702x-fe.c
drivers/media/dvb/pluto2/pluto2.c
drivers/media/dvb/ttpci/av7110.c
drivers/media/dvb/ttpci/budget-ci.c
drivers/media/dvb/ttpci/budget-core.c
drivers/media/radio/Kconfig
drivers/media/radio/dsbr100.c
drivers/media/radio/radio-cadet.c
drivers/media/radio/radio-maestro.c
drivers/media/radio/radio-zoltrix.c
drivers/media/video/Kconfig
drivers/media/video/cx25840/cx25840-core.c
drivers/media/video/cx88/cx88-mpeg.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/cx88/cx88-vp3054-i2c.c
drivers/media/video/cx88/cx88-vp3054-i2c.h
drivers/media/video/em28xx/Kconfig
drivers/media/video/et61x251/Kconfig
drivers/media/video/ivtv/ivtv-driver.c
drivers/media/video/ivtv/ivtv-fileops.c
drivers/media/video/pvrusb2/Kconfig
drivers/media/video/pvrusb2/pvrusb2-encoder.c
drivers/media/video/pvrusb2/pvrusb2-hdw.c
drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
drivers/media/video/pvrusb2/pvrusb2-sysfs.c
drivers/media/video/pwc/Kconfig
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-dvb.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/sn9c102/Kconfig
drivers/media/video/sn9c102/sn9c102.h
drivers/media/video/sn9c102/sn9c102_core.c
drivers/media/video/sn9c102/sn9c102_devtable.h
drivers/media/video/sn9c102/sn9c102_hv7131d.c
drivers/media/video/sn9c102/sn9c102_hv7131r.c
drivers/media/video/sn9c102/sn9c102_mi0343.c
drivers/media/video/sn9c102/sn9c102_mi0360.c
drivers/media/video/sn9c102/sn9c102_ov7630.c
drivers/media/video/sn9c102/sn9c102_ov7660.c
drivers/media/video/sn9c102/sn9c102_pas106b.c
drivers/media/video/sn9c102/sn9c102_pas202bcb.c
drivers/media/video/sn9c102/sn9c102_sensor.h
drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
drivers/media/video/sn9c102/sn9c102_tas5110d.c
drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
drivers/media/video/usbvideo/Kconfig
drivers/media/video/usbvision/Kconfig
drivers/media/video/v4l1-compat.c
drivers/media/video/video-buf.c
drivers/media/video/videodev.c
drivers/media/video/zc0301/Kconfig
include/media/saa7146.h
include/media/saa7146_vv.h

index d7bb2e2e4d9b12cc3e5877033f375c2bd4d09b25..712e8c8333cc90153f37be879adee04ec89b73ea 100644 (file)
@@ -52,7 +52,7 @@
  51 -> ProVideo PV952                           [1540:9524]
  52 -> AverMedia AverTV/305                     [1461:2108]
  53 -> ASUS TV-FM 7135                          [1043:4845]
- 54 -> LifeView FlyTV Platinum FM / Gold        [5168:0214,1489:0214,5168:0304]
+ 54 -> LifeView FlyTV Platinum FM / Gold        [5168:0214,5168:5214,1489:0214,5168:0304]
  55 -> LifeView FlyDVB-T DUO / MSI TV@nywhere Duo [5168:0306,4E42:0306]
  56 -> Avermedia AVerTV 307                     [1461:a70a]
  57 -> Avermedia AVerTV GO 007 FM               [1461:f31f]
 110 -> Avermedia M102                           [1461:f31e]
 111 -> ASUS P7131 4871                          [1043:4871]
 112 -> ASUSTeK P7131 Hybrid                     [1043:4876]
+113 -> Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM) [1019:4cb6]
+114 -> KWorld DVB-T 210                         [17de:7250]
+115 -> Sabrent PCMCIA TV-PCB05                  [0919:2003]
index 5fe0ad7dfc20db7b9fc5093a834572a7bec248dd..279717c96f63c6a0a951d395307d7aa7ebf94c32 100644 (file)
@@ -355,6 +355,9 @@ devices assembling the SN9C1xx PC camera controllers:
 
 Vendor ID  Product ID
 ---------  ----------
+0x0458     0x7025
+0x045e     0x00f5
+0x045e     0x00f7
 0x0471     0x0327
 0x0471     0x0328
 0x0c45     0x6001
@@ -432,7 +435,7 @@ Image sensor / SN9C1xx bridge      | SN9C10[12]  SN9C103  SN9C105  SN9C120
 HV7131D    Hynix Semiconductor     | Yes         No       No       No
 HV7131R    Hynix Semiconductor     | No          Yes      Yes      Yes
 MI-0343    Micron Technology       | Yes         No       No       No
-MI-0360    Micron Technology       | No          Yes      No       No
+MI-0360    Micron Technology       | No          Yes      Yes      Yes
 OV7630     OmniVision Technologies | Yes         Yes      No       No
 OV7660     OmniVision Technologies | No          No       Yes      Yes
 PAS106B    PixArt Imaging          | Yes         No       No       No
@@ -478,13 +481,12 @@ scaling factor is restored to 1.
 This driver supports two different video formats: the first one is the "8-bit
 Sequential Bayer" format and can be used to obtain uncompressed video data
 from the device through the current I/O method, while the second one provides
-"raw" compressed video data (without frame headers not related to the
-compressed data). The compression quality may vary from 0 to 1 and can be
-selected or queried thanks to the VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2
-ioctl's. For maximum flexibility, both the default active video format and the
-default compression quality depend on how the image sensor being used is
-initialized (as described in the documentation of the API for the image sensors
-supplied by this driver).
+either "raw" compressed video data (without frame headers not related to the
+compressed data) or standard JPEG (with frame headers). The compression quality
+may vary from 0 to 1 and can be selected or queried thanks to the
+VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2 ioctl's. For maximum flexibility,
+both the default active video format and the default compression quality
+depend on how the image sensor being used is initialized.
 
 
 11. Video frame formats [1]
index 3a80e0cc73699e9e24bcc6fb4382fab9cb5a9dec..624b21cef5b398617a543e69f48307169788f18b 100644 (file)
@@ -87,6 +87,14 @@ config VIDEO_TVEEPROM
        tristate
        depends on I2C
 
+config DAB
+       boolean "DAB adapters"
+       default y
+       ---help---
+         Allow selecting support for for Digital Audio Broadcasting (DAB)
+         Receiver adapters.
+
+if DAB
 config USB_DABUSB
        tristate "DABUSB driver"
        depends on USB
@@ -100,5 +108,6 @@ config USB_DABUSB
 
          To compile this driver as a module, choose M here: the
          module will be called dabusb.
+endif # DAB
 
 endmenu
index c578a529e7a8e910ea969b3fad2c58b28d95ca2d..8fa19939c2b6e5878bdfd29158d92a08be3dccf2 100644 (file)
@@ -5,4 +5,4 @@
 obj-y := common/
 obj-$(CONFIG_VIDEO_DEV) += video/
 obj-$(CONFIG_VIDEO_DEV) += radio/
-obj-$(CONFIG_DVB)       += dvb/
+obj-$(CONFIG_DVB_CORE)  += dvb/
index 86cbdbcf9d7db1f005e9cfa37a44b76088c59c61..ef3e54cd9407a9dab7c41bcff42f7d9129afdd0b 100644 (file)
@@ -136,28 +136,45 @@ char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa
        char *mem = vmalloc_32(length);
        int slen = 0;
 
-       if (NULL == mem) {
-               return NULL;
-       }
+       if (NULL == mem)
+               goto err_null;
 
-       if (!(pt->slist = vmalloc_to_sg(mem, pages))) {
-               vfree(mem);
-               return NULL;
-       }
+       if (!(pt->slist = vmalloc_to_sg(mem, pages)))
+               goto err_free_mem;
 
-       if (saa7146_pgtable_alloc(pci, pt)) {
-               kfree(pt->slist);
-               pt->slist = NULL;
-               vfree(mem);
-               return NULL;
-       }
+       if (saa7146_pgtable_alloc(pci, pt))
+               goto err_free_slist;
 
-       slen = pci_map_sg(pci,pt->slist,pages,PCI_DMA_FROMDEVICE);
-       if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen)) {
-               return NULL;
-       }
+       pt->nents = pages;
+       slen = pci_map_sg(pci,pt->slist,pt->nents,PCI_DMA_FROMDEVICE);
+       if (0 == slen)
+               goto err_free_pgtable;
+
+       if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen))
+               goto err_unmap_sg;
 
        return mem;
+
+err_unmap_sg:
+       pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
+err_free_pgtable:
+       saa7146_pgtable_free(pci, pt);
+err_free_slist:
+       kfree(pt->slist);
+       pt->slist = NULL;
+err_free_mem:
+       vfree(mem);
+err_null:
+       return NULL;
+}
+
+void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, char *mem, struct saa7146_pgtable *pt)
+{
+       pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
+       saa7146_pgtable_free(pci, pt);
+       kfree(pt->slist);
+       pt->slist = NULL;
+       vfree(mem);
 }
 
 void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
@@ -166,8 +183,6 @@ void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
                return;
        pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
        pt->cpu = NULL;
-       kfree(pt->slist);
-       pt->slist = NULL;
 }
 
 int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
@@ -528,6 +543,7 @@ EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc);
 EXPORT_SYMBOL_GPL(saa7146_pgtable_free);
 EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);
 EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable);
+EXPORT_SYMBOL_GPL(saa7146_vfree_destroy_pgtable);
 EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);
 
 EXPORT_SYMBOL_GPL(saa7146_setgpio);
index c18a5da6493470ae3e3af67342e08650970441e4..b4770aecc01db56afd363b9fcedbdfe49be90a20 100644 (file)
@@ -307,7 +307,6 @@ static int fops_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg);
 static int fops_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 /*
index a97c8f5e9a5d1dc13f6414106e9f75cc7ab9cd09..efd2b746815820e06698a209881e1d53c35d4cc8 100644 (file)
@@ -2,24 +2,16 @@
 # Multimedia device configuration
 #
 
-menu "Digital Video Broadcasting Devices"
+source "drivers/media/dvb/dvb-core/Kconfig"
 
-config DVB
-       bool "DVB For Linux"
-       depends on NET && INET
+menuconfig DVB_CAPTURE_DRIVERS
+       bool "DVB/ATSC adapters"
+       depends on DVB_CORE
+       default y
        ---help---
-         Support Digital Video Broadcasting hardware.  Enable this if you
-         own a DVB adapter and want to use it or if you compile Linux for
-         a digital SetTopBox.
-
-         API specs and user tools are available from <http://www.linuxtv.org/>.
+         Say Y to select Digital TV adapters
 
-         Please report problems regarding this driver to the LinuxDVB
-         mailing list.
-
-         If unsure say N.
-
-source "drivers/media/dvb/dvb-core/Kconfig"
+if DVB_CAPTURE_DRIVERS
 
 comment "Supported SAA7146 based PCI Adapters"
        depends on DVB_CORE && PCI && I2C
@@ -48,4 +40,4 @@ comment "Supported DVB Frontends"
        depends on DVB_CORE
 source "drivers/media/dvb/frontends/Kconfig"
 
-endmenu
+endif # DVB_CAPTURE_DRIVERS
index 1990eda10c469a52471495d8c865d7fa6d908985..e3e6839f807313da679dc2da28e992ad3c8b6e52 100644 (file)
@@ -1,12 +1,22 @@
 config DVB_CORE
-       tristate "DVB Core Support"
-       depends on DVB
+       tristate "DVB for Linux"
+       depends on NET && INET
        select CRC32
        help
+         Support Digital Video Broadcasting hardware.  Enable this if you
+         own a DVB adapter and want to use it or if you compile Linux for
+         a digital SetTopBox.
+
          DVB core utility functions for device handling, software fallbacks etc.
          Say Y when you have a DVB card and want to use it. Say Y if your want
          to build your drivers outside the kernel, but need the DVB core. All
          in-kernel drivers will select this automatically if needed.
+
+         API specs and user tools are available from <http://www.linuxtv.org/>.
+
+         Please report problems regarding this driver to the LinuxDVB
+         mailing list.
+
          If unsure say N.
 
 config DVB_CORE_ATTACH
index 97715f7514d666ae8ba61c9a1bcc9bd3b50ef402..403081689de1bdc30b1d339d7775f36cb479e133 100644 (file)
@@ -19,6 +19,7 @@
 #define USB_VID_COMPRO_UNK                     0x145f
 #define USB_VID_CYPRESS                                0x04b4
 #define USB_VID_DIBCOM                         0x10b8
+#define USB_VID_DPOSH                          0x1498
 #define USB_VID_DVICO                          0x0fe9
 #define USB_VID_EMPIA                          0xeb1a
 #define USB_VID_GENPIX                         0x09c0
@@ -61,6 +62,8 @@
 #define USB_PID_DIBCOM_STK7700P                                0x1e14
 #define USB_PID_DIBCOM_STK7700P_PC                     0x1e78
 #define USB_PID_DIBCOM_ANCHOR_2135_COLD                        0x2131
+#define USB_PID_DPOSH_M9206_COLD                       0x9206
+#define USB_PID_DPOSH_M9206_WARM                       0xa090
 #define USB_PID_UNIWILL_STK7700P                       0x6003
 #define USB_PID_GRANDTEC_DVBT_USB_COLD                 0x0fa0
 #define USB_PID_GRANDTEC_DVBT_USB_WARM                 0x0fa1
 #define USB_PID_MSI_DIGI_VOX_MINI_II                   0x1513
 #define USB_PID_OPERA1_COLD                            0x2830
 #define USB_PID_OPERA1_WARM                            0x3829
+#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD           0x0514
+#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM           0x0513
 
 
 #endif
index 0d721731a5241049c4e5130f63e0d4975458d792..6f824a569e14d5a2b4f9ca83f4e821d97a0437fe 100644 (file)
@@ -119,7 +119,7 @@ struct usb_data_stream_properties {
  * @caps: capabilities of the DVB USB device.
  * @pid_filter_count: number of PID filter position in the optional hardware
  *  PID-filter.
- * @streaming_crtl: called to start and stop the MPEG2-TS streaming of the
+ * @streaming_ctrl: called to start and stop the MPEG2-TS streaming of the
  *  device (not URB submitting/killing).
  * @pid_filter_ctrl: called to en/disable the PID filter, if any.
  * @pid_filter: called to set/unset a PID for filtering.
index 45d7bc214c18eb6e0e6f110079f0ba27209ea7cb..c546ddeda5d4fbd8d7e0f8a4dd8c40f131839cf0 100644 (file)
@@ -3,8 +3,8 @@
  * Copyright (C) 2006 Aapo Tahkola (aet@rasterburn.org)
  *
  *     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, version 2.
+ *     under the terms of the GNU General Public License as published by the
+ *     Free Software Foundation, version 2.
  *
  * see Documentation/dvb/README.dvb-usb for more information
  */
@@ -22,26 +22,7 @@ static int dvb_usb_m920x_debug;
 module_param_named(debug,dvb_usb_m920x_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
 
-static struct dvb_usb_rc_key megasky_rc_keys [] = {
-       { 0x0, 0x12, KEY_POWER },
-       { 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */
-       { 0x0, 0x02, KEY_CHANNELUP },
-       { 0x0, 0x05, KEY_CHANNELDOWN },
-       { 0x0, 0x03, KEY_VOLUMEUP },
-       { 0x0, 0x06, KEY_VOLUMEDOWN },
-       { 0x0, 0x04, KEY_MUTE },
-       { 0x0, 0x07, KEY_OK }, /* TS */
-       { 0x0, 0x08, KEY_STOP },
-       { 0x0, 0x09, KEY_MENU }, /* swap */
-       { 0x0, 0x0a, KEY_REWIND },
-       { 0x0, 0x1b, KEY_PAUSE },
-       { 0x0, 0x1f, KEY_FASTFORWARD },
-       { 0x0, 0x0c, KEY_RECORD },
-       { 0x0, 0x0d, KEY_CAMERA }, /* screenshot */
-       { 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */
-};
-
-static inline int m9206_read(struct usb_device *udev, u8 request, u16 value,\
+static inline int m920x_read(struct usb_device *udev, u8 request, u16 value,
                             u16 index, void *data, int size)
 {
        int ret;
@@ -55,14 +36,14 @@ static inline int m9206_read(struct usb_device *udev, u8 request, u16 value,\
        }
 
        if (ret != size) {
-               deb_rc("m920x_read = no data\n");
+               deb("m920x_read = no data\n");
                return -EIO;
        }
 
        return 0;
 }
 
-static inline int m9206_write(struct usb_device *udev, u8 request,
+static inline int m920x_write(struct usb_device *udev, u8 request,
                              u16 value, u16 index)
 {
        int ret;
@@ -74,32 +55,40 @@ static inline int m9206_write(struct usb_device *udev, u8 request,
        return ret;
 }
 
-static int m9206_init(struct dvb_usb_device *d)
+static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq)
 {
        int ret = 0;
 
        /* Remote controller init. */
        if (d->props.rc_query) {
-               if ((ret = m9206_write(d->udev, M9206_CORE, 0xa8, M9206_RC_INIT2)) != 0)
-                       return ret;
+               deb("Initialising remote control\n");
+               while (rc_seq->address) {
+                       if ((ret = m920x_write(d->udev, M9206_CORE,
+                                              rc_seq->data,
+                                              rc_seq->address)) != 0) {
+                               deb("Initialising remote control failed\n");
+                               return ret;
+                       }
 
-               if ((ret = m9206_write(d->udev, M9206_CORE, 0x51, M9206_RC_INIT1)) != 0)
-                       return ret;
+                       rc_seq++;
+               }
+
+               deb("Initialising remote control success\n");
        }
 
        return ret;
 }
 
-static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 {
-       struct m9206_state *m = d->priv;
+       struct m920x_state *m = d->priv;
        int i, ret = 0;
        u8 rc_state[2];
 
-       if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
+       if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
                goto unlock;
 
-       if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
+       if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
                goto unlock;
 
        for (i = 0; i < d->props.rc_key_map_size; i++)
@@ -111,6 +100,14 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
                                *state = REMOTE_NO_KEY_PRESSED;
                                goto unlock;
 
+                       case 0x88: /* framing error or "invalid code" */
+                       case 0x99:
+                       case 0xc0:
+                       case 0xd8:
+                               *state = REMOTE_NO_KEY_PRESSED;
+                               m->rep_count = 0;
+                               goto unlock;
+
                        case 0x93:
                        case 0x92:
                                m->rep_count = 0;
@@ -118,31 +115,32 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
                                goto unlock;
 
                        case 0x91:
-                               /* For comfort. */
+                               /* prevent immediate auto-repeat */
                                if (++m->rep_count > 2)
                                        *state = REMOTE_KEY_REPEAT;
+                               else
+                                       *state = REMOTE_NO_KEY_PRESSED;
                                goto unlock;
 
                        default:
-                               deb_rc("Unexpected rc response %x\n", rc_state[0]);
+                               deb("Unexpected rc state %02x\n", rc_state[0]);
                                *state = REMOTE_NO_KEY_PRESSED;
                                goto unlock;
                        }
                }
 
        if (rc_state[1] != 0)
-               deb_rc("Unknown rc key %x\n", rc_state[1]);
+               deb("Unknown rc key %02x\n", rc_state[1]);
 
        *state = REMOTE_NO_KEY_PRESSED;
 
      unlock:
+ unlock:
 
        return ret;
 }
 
 /* I2C */
-static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                         int num)
+static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
 {
        struct dvb_usb_device *d = i2c_get_adapdata(adap);
        int i, j;
@@ -155,33 +153,40 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                return -EAGAIN;
 
        for (i = 0; i < num; i++) {
-               if (msg[i].flags & (I2C_M_NO_RD_ACK|I2C_M_IGNORE_NAK|I2C_M_TEN) ||
-                   msg[i].len == 0) {
-                       /* For a 0 byte message, I think sending the address to index 0x80|0x40
-                        * would be the correct thing to do.  However, zero byte messages are
-                        * only used for probing, and since we don't know how to get the slave's
-                        * ack, we can't probe. */
+               if (msg[i].flags & (I2C_M_NO_RD_ACK | I2C_M_IGNORE_NAK | I2C_M_TEN) || msg[i].len == 0) {
+                       /* For a 0 byte message, I think sending the address
+                        * to index 0x80|0x40 would be the correct thing to
+                        * do.  However, zero byte messages are only used for
+                        * probing, and since we don't know how to get the
+                        * slave's ack, we can't probe. */
                        ret = -ENOTSUPP;
                        goto unlock;
                }
                /* Send START & address/RW bit */
                if (!(msg[i].flags & I2C_M_NOSTART)) {
-                       if ((ret = m9206_write(d->udev, M9206_I2C, (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0), 0x80)) != 0)
+                       if ((ret = m920x_write(d->udev, M9206_I2C,
+                                       (msg[i].addr << 1) |
+                                       (msg[i].flags & I2C_M_RD ? 0x01 : 0), 0x80)) != 0)
                                goto unlock;
                        /* Should check for ack here, if we knew how. */
                }
                if (msg[i].flags & I2C_M_RD) {
                        for (j = 0; j < msg[i].len; j++) {
-                               /* Last byte of transaction? Send STOP, otherwise send ACK. */
-                               int stop = (i+1 == num && j+1 == msg[i].len)?0x40:0x01;
-                               if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x20|stop, &msg[i].buf[j], 1)) != 0)
+                               /* Last byte of transaction?
+                                * Send STOP, otherwise send ACK. */
+                               int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x01;
+
+                               if ((ret = m920x_read(d->udev, M9206_I2C, 0x0,
+                                                     0x20 | stop,
+                                                     &msg[i].buf[j], 1)) != 0)
                                        goto unlock;
                        }
                } else {
                        for (j = 0; j < msg[i].len; j++) {
                                /* Last byte of transaction? Then send STOP. */
-                               int stop = (i+1 == num && j+1 == msg[i].len)?0x40:0x00;
-                               if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0)
+                               int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x00;
+
+                               if ((ret = m920x_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0)
                                        goto unlock;
                                /* Should check for ack here too. */
                        }
@@ -189,25 +194,25 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
        }
        ret = num;
 
-unlock:
+ unlock:
        mutex_unlock(&d->i2c_mutex);
 
        return ret;
 }
 
-static u32 m9206_i2c_func(struct i2c_adapter *adapter)
+static u32 m920x_i2c_func(struct i2c_adapter *adapter)
 {
        return I2C_FUNC_I2C;
 }
 
-static struct i2c_algorithm m9206_i2c_algo = {
-       .master_xfer   = m9206_i2c_xfer,
-       .functionality = m9206_i2c_func,
+static struct i2c_algorithm m920x_i2c_algo = {
+       .master_xfer   = m920x_i2c_xfer,
+       .functionality = m920x_i2c_func,
 };
 
-
-static int m9206_set_filter(struct dvb_usb_adapter *adap, int type, int idx,
-                           int pid)
+/* pid filter */
+static int m920x_set_filter(struct dvb_usb_adapter *adap,
+                           int type, int idx, int pid)
 {
        int ret = 0;
 
@@ -216,18 +221,18 @@ static int m9206_set_filter(struct dvb_usb_adapter *adap, int type, int idx,
 
        pid |= 0x8000;
 
-       if ((ret = m9206_write(adap->dev->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0)
+       if ((ret = m920x_write(adap->dev->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0)
                return ret;
 
-       if ((ret = m9206_write(adap->dev->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0)
+       if ((ret = m920x_write(adap->dev->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0)
                return ret;
 
        return ret;
 }
 
-static int m9206_update_filters(struct dvb_usb_adapter *adap)
+static int m920x_update_filters(struct dvb_usb_adapter *adap)
 {
-       struct m9206_state *m = adap->dev->priv;
+       struct m920x_state *m = adap->dev->priv;
        int enabled = m->filtering_enabled;
        int i, ret = 0, filter = 0;
 
@@ -236,14 +241,14 @@ static int m9206_update_filters(struct dvb_usb_adapter *adap)
                        enabled = 0;
 
        /* Disable all filters */
-       if ((ret = m9206_set_filter(adap, 0x81, 1, enabled)) != 0)
+       if ((ret = m920x_set_filter(adap, 0x81, 1, enabled)) != 0)
                return ret;
 
        for (i = 0; i < M9206_MAX_FILTERS; i++)
-               if ((ret = m9206_set_filter(adap, 0x81, i + 2, 0)) != 0)
+               if ((ret = m920x_set_filter(adap, 0x81, i + 2, 0)) != 0)
                        return ret;
 
-       if ((ret = m9206_set_filter(adap, 0x82, 0, 0x0)) != 0)
+       if ((ret = m920x_set_filter(adap, 0x82, 0, 0x0)) != 0)
                return ret;
 
        /* Set */
@@ -252,40 +257,38 @@ static int m9206_update_filters(struct dvb_usb_adapter *adap)
                        if (m->filters[i] == 0)
                                continue;
 
-                       if ((ret = m9206_set_filter(adap, 0x81, filter + 2, m->filters[i])) != 0)
+                       if ((ret = m920x_set_filter(adap, 0x81, filter + 2, m->filters[i])) != 0)
                                return ret;
 
                        filter++;
                }
        }
 
-       if ((ret = m9206_set_filter(adap, 0x82, 0, 0x02f5)) != 0)
+       if ((ret = m920x_set_filter(adap, 0x82, 0, 0x02f5)) != 0)
                return ret;
 
        return ret;
 }
 
-static int m9206_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
+static int m920x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
-       struct m9206_state *m = adap->dev->priv;
+       struct m920x_state *m = adap->dev->priv;
 
        m->filtering_enabled = onoff ? 1 : 0;
 
-       return m9206_update_filters(adap);
+       return m920x_update_filters(adap);
 }
 
-static int m9206_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
-                           int onoff)
+static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
 {
-       struct m9206_state *m = adap->dev->priv;
+       struct m920x_state *m = adap->dev->priv;
 
        m->filters[index] = onoff ? pid : 0;
 
-       return m9206_update_filters(adap);
+       return m920x_update_filters(adap);
 }
 
-static int m9206_firmware_download(struct usb_device *udev,
-                                  const struct firmware *fw)
+static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw)
 {
        u16 value, index, size;
        u8 read[4], *buff;
@@ -293,13 +296,13 @@ static int m9206_firmware_download(struct usb_device *udev,
 
        buff = kmalloc(65536, GFP_KERNEL);
 
-       if ((ret = m9206_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
+       if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
                goto done;
-       deb_rc("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
+       deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
 
-       if ((ret = m9206_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0)
+       if ((ret = m920x_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0)
                goto done;
-       deb_rc("%x\n", read[0]);
+       deb("%x\n", read[0]);
 
        for (pass = 0; pass < 2; pass++) {
                for (i = 0; i + (sizeof(u16) * 3) < fw->size;) {
@@ -317,11 +320,11 @@ static int m9206_firmware_download(struct usb_device *udev,
                                memcpy(buff, fw->data + i, size);
 
                                ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
-                                           M9206_FW,
-                                           USB_TYPE_VENDOR | USB_DIR_OUT,
-                                           value, index, buff, size, 20);
+                                                     M9206_FW,
+                                                     USB_TYPE_VENDOR | USB_DIR_OUT,
+                                                     value, index, buff, size, 20);
                                if (ret != size) {
-                                       deb_rc("error while uploading fw!\n");
+                                       deb("error while uploading fw!\n");
                                        ret = -EIO;
                                        goto done;
                                }
@@ -330,7 +333,7 @@ static int m9206_firmware_download(struct usb_device *udev,
                        i += size;
                }
                if (i != fw->size) {
-                       deb_rc("bad firmware file!\n");
+                       deb("bad firmware file!\n");
                        ret = -EINVAL;
                        goto done;
                }
@@ -338,11 +341,11 @@ static int m9206_firmware_download(struct usb_device *udev,
 
        msleep(36);
 
-       /* m9206 will disconnect itself from the bus after this. */
-       (void) m9206_write(udev, M9206_CORE, 0x01, M9206_FW_GO);
-       deb_rc("firmware uploaded!\n");
+       /* m920x will disconnect itself from the bus after this. */
+       (void) m920x_write(udev, M9206_CORE, 0x01, M9206_FW_GO);
+       deb("firmware uploaded!\n");
 
      done:
+ done:
        kfree(buff);
 
        return ret;
@@ -362,7 +365,8 @@ static int m920x_identify_state(struct usb_device *udev,
        return 0;
 }
 
-static int megasky_mt352_demod_init(struct dvb_frontend *fe)
+/* demod configurations */
+static int m920x_mt352_demod_init(struct dvb_frontend *fe)
 {
        u8 config[] = { CONFIG, 0x3d };
        u8 clock[] = { CLOCK_CTL, 0x30 };
@@ -382,74 +386,174 @@ static int megasky_mt352_demod_init(struct dvb_frontend *fe)
        mt352_write(fe, unk1, ARRAY_SIZE(unk1));
        mt352_write(fe, unk2, ARRAY_SIZE(unk2));
 
-       deb_rc("Demod init!\n");
+       deb("Demod init!\n");
 
        return 0;
 }
 
-static struct mt352_config megasky_mt352_config = {
+static struct mt352_config m920x_mt352_config = {
        .demod_address = 0x0f,
        .no_tuner = 1,
-       .demod_init = megasky_mt352_demod_init,
+       .demod_init = m920x_mt352_demod_init,
+};
+
+static struct tda1004x_config m920x_tda10046_08_config = {
+       .demod_address = 0x08,
+       .invert = 0,
+       .invert_oclk = 0,
+       .ts_mode = TDA10046_TS_SERIAL,
+       .xtal_freq = TDA10046_XTAL_16M,
+       .if_freq = TDA10046_FREQ_045,
+       .agc_config = TDA10046_AGC_TDA827X,
+       .gpio_config = TDA10046_GPTRI,
+       .request_firmware = NULL,
+};
+
+static struct tda1004x_config m920x_tda10046_0b_config = {
+       .demod_address = 0x0b,
+       .invert = 0,
+       .invert_oclk = 0,
+       .ts_mode = TDA10046_TS_SERIAL,
+       .xtal_freq = TDA10046_XTAL_16M,
+       .if_freq = TDA10046_FREQ_045,
+       .agc_config = TDA10046_AGC_TDA827X,
+       .gpio_config = TDA10046_GPTRI,
+       .request_firmware = NULL, /* uses firmware EEPROM */
+};
+
+/* tuner configurations */
+static struct qt1010_config m920x_qt1010_config = {
+       .i2c_address = 0x62
 };
 
-static int megasky_mt352_frontend_attach(struct dvb_usb_adapter *adap)
+/* Callbacks for DVB USB */
+static int m920x_mt352_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       deb_rc("megasky_frontend_attach!\n");
+       deb("%s\n",__FUNCTION__);
 
-       if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) == NULL)
+       if ((adap->fe = dvb_attach(mt352_attach,
+                                  &m920x_mt352_config,
+                                  &adap->dev->i2c_adap)) == NULL)
                return -EIO;
 
        return 0;
 }
 
-static struct qt1010_config megasky_qt1010_config = {
-       .i2c_address = 0x62
-};
-
-static int megasky_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
+static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap,
-                      &megasky_qt1010_config) == NULL)
-               return -ENODEV;
+       deb("%s\n",__FUNCTION__);
+
+       if ((adap->fe = dvb_attach(tda10046_attach,
+                                  &m920x_tda10046_08_config,
+                                  &adap->dev->i2c_adap)) == NULL)
+               return -EIO;
 
        return 0;
 }
 
-static struct tda1004x_config digivox_tda10046_config = {
-       .demod_address = 0x08,
-       .invert = 0,
-       .invert_oclk = 0,
-       .ts_mode = TDA10046_TS_SERIAL,
-       .xtal_freq = TDA10046_XTAL_16M,
-       .if_freq = TDA10046_FREQ_045,
-       .agc_config = TDA10046_AGC_TDA827X,
-       .gpio_config = TDA10046_GPTRI,
-       .request_firmware = NULL,
-};
-
-static int digivox_tda10046_frontend_attach(struct dvb_usb_adapter *adap)
+static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       deb_rc("digivox_tda10046_frontend_attach!\n");
+       deb("%s\n",__FUNCTION__);
 
-       if ((adap->fe = dvb_attach(tda10046_attach, &digivox_tda10046_config,
+       if ((adap->fe = dvb_attach(tda10046_attach,
+                                  &m920x_tda10046_0b_config,
                                   &adap->dev->i2c_adap)) == NULL)
                return -EIO;
 
        return 0;
 }
 
-static int digivox_tda8275_tuner_attach(struct dvb_usb_adapter *adap)
+static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
 {
-       if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap,
-                      NULL) == NULL)
+       deb("%s\n",__FUNCTION__);
+
+       if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, &m920x_qt1010_config) == NULL)
                return -ENODEV;
+
        return 0;
 }
 
+static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       deb("%s\n",__FUNCTION__);
+
+       if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, NULL) == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       deb("%s\n",__FUNCTION__);
+
+       if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+/* device-specific initialization */
+static struct m920x_inits megasky_rc_init [] = {
+       { M9206_RC_INIT2, 0xa8 },
+       { M9206_RC_INIT1, 0x51 },
+       { } /* terminating entry */
+};
+
+static struct m920x_inits tvwalkertwin_rc_init [] = {
+       { M9206_RC_INIT2, 0x00 },
+       { M9206_RC_INIT1, 0xef },
+       { 0xff28,         0x00 },
+       { 0xff23,         0x00 },
+       { 0xff21,         0x30 },
+       { } /* terminating entry */
+};
+
+/* ir keymaps */
+static struct dvb_usb_rc_key megasky_rc_keys [] = {
+       { 0x0, 0x12, KEY_POWER },
+       { 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */
+       { 0x0, 0x02, KEY_CHANNELUP },
+       { 0x0, 0x05, KEY_CHANNELDOWN },
+       { 0x0, 0x03, KEY_VOLUMEUP },
+       { 0x0, 0x06, KEY_VOLUMEDOWN },
+       { 0x0, 0x04, KEY_MUTE },
+       { 0x0, 0x07, KEY_OK }, /* TS */
+       { 0x0, 0x08, KEY_STOP },
+       { 0x0, 0x09, KEY_MENU }, /* swap */
+       { 0x0, 0x0a, KEY_REWIND },
+       { 0x0, 0x1b, KEY_PAUSE },
+       { 0x0, 0x1f, KEY_FASTFORWARD },
+       { 0x0, 0x0c, KEY_RECORD },
+       { 0x0, 0x0d, KEY_CAMERA }, /* screenshot */
+       { 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */
+};
+
+static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = {
+       { 0x0, 0x01, KEY_ZOOM }, /* Full Screen */
+       { 0x0, 0x02, KEY_CAMERA }, /* snapshot */
+       { 0x0, 0x03, KEY_MUTE },
+       { 0x0, 0x04, KEY_REWIND },
+       { 0x0, 0x05, KEY_PLAYPAUSE }, /* Play/Pause */
+       { 0x0, 0x06, KEY_FASTFORWARD },
+       { 0x0, 0x07, KEY_RECORD },
+       { 0x0, 0x08, KEY_STOP },
+       { 0x0, 0x09, KEY_TIME }, /* Timeshift */
+       { 0x0, 0x0c, KEY_COFFEE }, /* Recall */
+       { 0x0, 0x0e, KEY_CHANNELUP },
+       { 0x0, 0x12, KEY_POWER },
+       { 0x0, 0x15, KEY_MENU }, /* source */
+       { 0x0, 0x18, KEY_CYCLEWINDOWS }, /* TWIN PIP */
+       { 0x0, 0x1a, KEY_CHANNELDOWN },
+       { 0x0, 0x1b, KEY_VOLUMEDOWN },
+       { 0x0, 0x1e, KEY_VOLUMEUP },
+};
+
 /* DVB USB Driver stuff */
 static struct dvb_usb_device_properties megasky_properties;
 static struct dvb_usb_device_properties digivox_mini_ii_properties;
+static struct dvb_usb_device_properties tvwalkertwin_properties;
+static struct dvb_usb_device_properties dposh_properties;
 
 static int m920x_probe(struct usb_interface *intf,
                       const struct usb_device_id *id)
@@ -457,19 +561,57 @@ static int m920x_probe(struct usb_interface *intf,
        struct dvb_usb_device *d;
        struct usb_host_interface *alt;
        int ret;
+       struct m920x_inits *rc_init_seq = NULL;
+       int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber;
 
-       deb_rc("Probed!\n");
+       deb("Probing for m920x device at interface %d\n", bInterfaceNumber);
 
-       if (((ret = dvb_usb_device_init(intf, &megasky_properties, THIS_MODULE, &d)) == 0) ||
-           ((ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties, THIS_MODULE, &d)) == 0))
-               goto found;
+       if (bInterfaceNumber == 0) {
+               /* Single-tuner device, or first interface on
+                * multi-tuner device
+                */
 
-       return ret;
+               if ((ret = dvb_usb_device_init(intf, &megasky_properties,
+                                              THIS_MODULE, &d)) == 0) {
+                       rc_init_seq = megasky_rc_init;
+                       goto found;
+               }
+
+               if ((ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties,
+                                              THIS_MODULE, &d)) == 0) {
+                       /* No remote control, so no rc_init_seq */
+                       goto found;
+               }
+
+               /* This configures both tuners on the TV Walker Twin */
+               if ((ret = dvb_usb_device_init(intf, &tvwalkertwin_properties,
+                                              THIS_MODULE, &d)) == 0) {
+                       rc_init_seq = tvwalkertwin_rc_init;
+                       goto found;
+               }
+
+               if ((ret = dvb_usb_device_init(intf, &dposh_properties,
+                                              THIS_MODULE, &d)) == 0) {
+                       /* Remote controller not supported yet. */
+                       goto found;
+               }
+
+               return ret;
+       } else {
+               /* Another interface on a multi-tuner device */
 
-found:
+               /* The LifeView TV Walker Twin gets here, but struct
+                * tvwalkertwin_properties already configured both
+                * tuners, so there is nothing for us to do here
+                */
+
+               return -ENODEV;
+       }
+
+ found:
        alt = usb_altnum_to_altsetting(intf, 1);
        if (alt == NULL) {
-               deb_rc("No alt found!\n");
+               deb("No alt found!\n");
                return -ENODEV;
        }
 
@@ -478,7 +620,7 @@ found:
        if (ret < 0)
                return ret;
 
-       if ((ret = m9206_init(d)) != 0)
+       if ((ret = m920x_init(d, rc_init_seq)) != 0)
                return ret;
 
        return ret;
@@ -488,6 +630,12 @@ static struct usb_device_id m920x_table [] = {
                { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) },
                { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
                             USB_PID_MSI_DIGI_VOX_MINI_II) },
+               { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
+                            USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD) },
+               { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
+                            USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) },
+               { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) },
+               { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) },
                { }             /* Terminating entry */
 };
 MODULE_DEVICE_TABLE (usb, m920x_table);
@@ -497,14 +645,14 @@ static struct dvb_usb_device_properties megasky_properties = {
 
        .usb_ctrl = DEVICE_SPECIFIC,
        .firmware = "dvb-usb-megasky-02.fw",
-       .download_firmware = m9206_firmware_download,
+       .download_firmware = m920x_firmware_download,
 
        .rc_interval      = 100,
        .rc_key_map       = megasky_rc_keys,
        .rc_key_map_size  = ARRAY_SIZE(megasky_rc_keys),
-       .rc_query         = m9206_rc_query,
+       .rc_query         = m920x_rc_query,
 
-       .size_of_priv     = sizeof(struct m9206_state),
+       .size_of_priv     = sizeof(struct m920x_state),
 
        .identify_state   = m920x_identify_state,
        .num_adapters = 1,
@@ -513,11 +661,11 @@ static struct dvb_usb_device_properties megasky_properties = {
                        DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
 
                .pid_filter_count = 8,
-               .pid_filter       = m9206_pid_filter,
-               .pid_filter_ctrl  = m9206_pid_filter_ctrl,
+               .pid_filter       = m920x_pid_filter,
+               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
 
-               .frontend_attach  = megasky_mt352_frontend_attach,
-               .tuner_attach     = megasky_qt1010_tuner_attach,
+               .frontend_attach  = m920x_mt352_frontend_attach,
+               .tuner_attach     = m920x_qt1010_tuner_attach,
 
                .stream = {
                        .type = USB_BULK,
@@ -530,7 +678,7 @@ static struct dvb_usb_device_properties megasky_properties = {
                        }
                },
        }},
-       .i2c_algo         = &m9206_i2c_algo,
+       .i2c_algo         = &m920x_i2c_algo,
 
        .num_device_descs = 1,
        .devices = {
@@ -546,22 +694,22 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = {
 
        .usb_ctrl = DEVICE_SPECIFIC,
        .firmware = "dvb-usb-digivox-02.fw",
-       .download_firmware = m9206_firmware_download,
+       .download_firmware = m920x_firmware_download,
 
-       .size_of_priv     = sizeof(struct m9206_state),
+       .size_of_priv     = sizeof(struct m920x_state),
 
        .identify_state   = m920x_identify_state,
        .num_adapters = 1,
        .adapter = {{
                .caps = DVB_USB_ADAP_HAS_PID_FILTER |
-               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
 
                .pid_filter_count = 8,
-               .pid_filter       = m9206_pid_filter,
-               .pid_filter_ctrl  = m9206_pid_filter_ctrl,
+               .pid_filter       = m920x_pid_filter,
+               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
 
-               .frontend_attach  = digivox_tda10046_frontend_attach,
-               .tuner_attach     = digivox_tda8275_tuner_attach,
+               .frontend_attach  = m920x_tda10046_08_frontend_attach,
+               .tuner_attach     = m920x_tda8275_60_tuner_attach,
 
                .stream = {
                        .type = USB_BULK,
@@ -574,7 +722,7 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = {
                        }
                },
        }},
-       .i2c_algo         = &m9206_i2c_algo,
+       .i2c_algo         = &m920x_i2c_algo,
 
        .num_device_descs = 1,
        .devices = {
@@ -585,6 +733,122 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = {
        }
 };
 
+/* LifeView TV Walker Twin support by Nick Andrew <nick@nick-andrew.net>
+ *
+ * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A
+ * TDA10046 #0 is located at i2c address 0x08
+ * TDA10046 #1 is located at i2c address 0x0b (presently disabled - not yet working)
+ * TDA8275A #0 is located at i2c address 0x60
+ * TDA8275A #1 is located at i2c address 0x61 (presently disabled - not yet working)
+ */
+static struct dvb_usb_device_properties tvwalkertwin_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = DEVICE_SPECIFIC,
+       .firmware = "dvb-usb-tvwalkert.fw",
+       .download_firmware = m920x_firmware_download,
+
+       .rc_interval      = 100,
+       .rc_key_map       = tvwalkertwin_rc_keys,
+       .rc_key_map_size  = ARRAY_SIZE(tvwalkertwin_rc_keys),
+       .rc_query         = m920x_rc_query,
+
+       .size_of_priv     = sizeof(struct m920x_state),
+
+       .identify_state   = m920x_identify_state,
+       .num_adapters = 1,
+       .adapter = {{
+               .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+               .pid_filter_count = 8,
+               .pid_filter       = m920x_pid_filter,
+               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
+
+               .frontend_attach  = m920x_tda10046_08_frontend_attach,
+               .tuner_attach     = m920x_tda8275_60_tuner_attach,
+
+               .stream = {
+                       .type = USB_BULK,
+                       .count = 8,
+                       .endpoint = 0x81,
+                       .u = {
+                                .bulk = {
+                                        .buffersize = 512,
+                                }
+                       }
+               }},{
+               .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+               .pid_filter_count = 8,
+               .pid_filter       = m920x_pid_filter,
+               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
+
+               .frontend_attach  = m920x_tda10046_0b_frontend_attach,
+               .tuner_attach     = m920x_tda8275_61_tuner_attach,
+
+               .stream = {
+                       .type = USB_BULK,
+                       .count = 8,
+                       .endpoint = 0x82,
+                       .u = {
+                                .bulk = {
+                                        .buffersize = 512,
+                                }
+                       }
+               },
+       }},
+       .i2c_algo         = &m920x_i2c_algo,
+
+       .num_device_descs = 1,
+       .devices = {
+               {   .name = "LifeView TV Walker Twin DVB-T USB2.0",
+                   .cold_ids = { &m920x_table[2], NULL },
+                   .warm_ids = { &m920x_table[3], NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties dposh_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = DEVICE_SPECIFIC,
+       .firmware = "dvb-usb-dposh-01.fw",
+       .download_firmware = m920x_firmware_download,
+
+       .size_of_priv     = sizeof(struct m920x_state),
+
+       .identify_state   = m920x_identify_state,
+       .num_adapters = 1,
+       .adapter = {{
+               /* Hardware pid filters don't work with this device/firmware */
+
+               .frontend_attach  = m920x_mt352_frontend_attach,
+               .tuner_attach     = m920x_qt1010_tuner_attach,
+
+               .stream = {
+                       .type = USB_BULK,
+                       .count = 8,
+                       .endpoint = 0x81,
+                       .u = {
+                                .bulk = {
+                                        .buffersize = 512,
+                                }
+                       }
+               },
+       }},
+       .i2c_algo         = &m920x_i2c_algo,
+
+       .num_device_descs = 1,
+       .devices = {
+                {   .name = "Dposh DVB-T USB2.0",
+                    .cold_ids = { &m920x_table[4], NULL },
+                    .warm_ids = { &m920x_table[5], NULL },
+                },
+        }
+};
+
 static struct usb_driver m920x_driver = {
        .name           = "dvb_usb_m920x",
        .probe          = m920x_probe,
@@ -615,6 +879,11 @@ module_init (m920x_module_init);
 module_exit (m920x_module_exit);
 
 MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
-MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / Uli m920x");
+MODULE_DESCRIPTION("DVB Driver for ULI M920x");
 MODULE_VERSION("0.1");
 MODULE_LICENSE("GPL");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
index 7dd3db65c80eeba1a573be349bd9b6675fa4c968..2c8942d042226e51908089523517f18aac934c33 100644 (file)
@@ -4,7 +4,7 @@
 #define DVB_USB_LOG_PREFIX "m920x"
 #include "dvb-usb.h"
 
-#define deb_rc(args...)   dprintk(dvb_usb_m920x_debug,0x01,args)
+#define deb(args...)   dprintk(dvb_usb_m920x_debug,0x01,args)
 
 #define M9206_CORE     0x22
 #define M9206_RC_STATE 0xff51
@@ -59,9 +59,18 @@ What any other bits might mean, or how to get the slave's ACK/NACK
 response to a write, is unknown.
 */
 
-struct m9206_state {
+struct m920x_state {
        u16 filters[M9206_MAX_FILTERS];
        int filtering_enabled;
        int rep_count;
 };
+
+/* Initialisation data for the m920x
+ */
+
+struct m920x_inits {
+       u16 address;
+       u8  data;
+};
+
 #endif
index 3ecb2e0ce80f7ec986023b014a8a249b1fe7dadb..c3fdc7cd094e33f41c4e2c34f4ec7b565233d2e6 100644 (file)
@@ -204,8 +204,8 @@ static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
 static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
                                    struct dvb_diseqc_master_cmd *m)
 {
-       //struct vp702x_fe_state *st = fe->demodulator_priv;
-       u8 cmd[8];//,ibuf[10];
+       struct vp702x_fe_state *st = fe->demodulator_priv;
+       u8 cmd[8],ibuf[10];
        memset(cmd,0,8);
 
        deb_fe("%s\n",__FUNCTION__);
@@ -218,12 +218,12 @@ static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
        memcpy(&cmd[3], m->msg, m->msg_len);
        cmd[7] = vp702x_chksum(cmd,0,7);
 
-//     vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
+       vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
 
-//     if (ibuf[2] == 0 && ibuf[3] == 0)
-//             deb_fe("diseqc cmd failed.\n");
-//     else
-//             deb_fe("diseqc cmd succeeded.\n");
+       if (ibuf[2] == 0 && ibuf[3] == 0)
+               deb_fe("diseqc cmd failed.\n");
+       else
+               deb_fe("diseqc cmd succeeded.\n");
 
        return 0;
 }
index 058df5c100348b89657c79ede7772054444ee42f..08a2599ed74a7463293ae0e8858642fd6b495d84 100644 (file)
@@ -293,12 +293,20 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
         *     but no packets have been transfered.
         * [2] Sometimes (actually very often) NBPACKETS stays at zero
         *     although one packet has been transfered.
+        * [3] Sometimes (actually rarely), the card gets into an erroneous
+        *     mode where it continuously generates interrupts, claiming it
+        *     has recieved nbpackets>TS_DMA_PACKETS packets, but no packet
+        *     has been transfered. Only a reset seems to solve this
         */
        if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
                unsigned int i = 0;
                while (pluto->dma_buf[i] == 0x47)
                        i += 188;
                nbpackets = i / 188;
+               if (i == 0) {
+                       pluto_reset_ts(pluto, 1);
+                       dev_printk(KERN_DEBUG, &pluto->pdev->dev, "resetting TS because of invalid packet counter\n");
+               }
        }
 
        dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
index 67becdd4db609e87f3584c2bdd95c5a8961cfb2c..ef1108c0bf11005167eb6b6b225ac4a890465369 100644 (file)
@@ -1246,6 +1246,9 @@ static void vpeirq(unsigned long data)
        if (!budget->feeding1 || (newdma == olddma))
                return;
 
+       /* Ensure streamed PCI data is synced to CPU */
+       pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE);
+
 #if 0
        /* track rps1 activity */
        printk("vpeirq: %02x Event Counter 1 0x%04x\n",
@@ -2679,8 +2682,8 @@ err_iobuf_vfree_6:
 err_pci_free_5:
        pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus);
 err_saa71466_vfree_4:
-       if (!av7110->grabbing)
-               saa7146_pgtable_free(pdev, &av7110->pt);
+       if (av7110->grabbing)
+               saa7146_vfree_destroy_pgtable(pdev, av7110->grabbing, &av7110->pt);
 err_i2c_del_3:
        i2c_del_adapter(&av7110->i2c_adap);
 err_dvb_unregister_adapter_2:
@@ -2710,7 +2713,7 @@ static int __devexit av7110_detach(struct saa7146_dev* saa)
                SAA7146_ISR_CLEAR(saa, MASK_10);
                msleep(50);
                tasklet_kill(&av7110->vpe_tasklet);
-               saa7146_pgtable_free(saa->pci, &av7110->pt);
+               saa7146_vfree_destroy_pgtable(saa->pci, av7110->grabbing, &av7110->pt);
        }
        av7110_exit_v4l(av7110);
 
index 4ed4599ce816b78be6c5f3527ceb9f84028a2e8e..9d42f88ebb0ed048db14f3f5089da90668381816 100644 (file)
@@ -904,7 +904,7 @@ static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struc
                band = 1;
        } else if (tuner_frequency < 200000000) {
                cp = 6;
-               band = 2;
+               band = 1;
        } else if (tuner_frequency < 290000000) {
                cp = 3;
                band = 2;
index 6b97dc1e6b6561277f867419942f8f16f214e5c3..2557ac9620d02f20794955c6a0f26c87d8df7d19 100644 (file)
@@ -195,6 +195,9 @@ static void vpeirq(unsigned long data)
        u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
        u32 count;
 
+       /* Ensure streamed PCI data is synced to CPU */
+       pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE);
+
        /* nearest lower position divisible by 188 */
        newdma -= newdma % 188;
 
@@ -504,16 +507,16 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
        strcpy(budget->i2c_adap.name, budget->card->name);
 
        if (i2c_add_adapter(&budget->i2c_adap) < 0) {
-               dvb_unregister_adapter(&budget->dvb_adapter);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto err_dvb_unregister;
        }
 
        ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac);
 
-       if (NULL ==
-           (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt))) {
+       budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt);
+       if (NULL == budget->grabbing) {
                ret = -ENOMEM;
-               goto err;
+               goto err_del_i2c;
        }
 
        saa7146_write(dev, PCI_BT_V1, 0x001c0000);
@@ -526,14 +529,16 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
        if (bi->type != BUDGET_FS_ACTIVY)
                saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
 
-       if (budget_register(budget) == 0) {
-               return 0;
-       }
-err:
-       i2c_del_adapter(&budget->i2c_adap);
+       if (budget_register(budget) == 0)
+               return 0; /* Everything OK */
+
+       /* An error occurred, cleanup resources */
+       saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);
 
-       vfree(budget->grabbing);
+err_del_i2c:
+       i2c_del_adapter(&budget->i2c_adap);
 
+err_dvb_unregister:
        dvb_unregister_adapter(&budget->dvb_adapter);
 
        return ret;
@@ -555,15 +560,13 @@ int ttpci_budget_deinit(struct budget *budget)
 
        budget_unregister(budget);
 
-       i2c_del_adapter(&budget->i2c_adap);
-
-       dvb_unregister_adapter(&budget->dvb_adapter);
-
        tasklet_kill(&budget->vpe_tasklet);
 
-       saa7146_pgtable_free(dev->pci, &budget->pt);
+       saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);
 
-       vfree(budget->grabbing);
+       i2c_del_adapter(&budget->i2c_adap);
+
+       dvb_unregister_adapter(&budget->dvb_adapter);
 
        return 0;
 }
index af66a5d5ecd8b484af9ad661f59071c4714f8d5b..a6ac82a609d40c12315b9d60d9ef3a156fbafdd0 100644 (file)
@@ -2,8 +2,14 @@
 # Multimedia Video device configuration
 #
 
-menu "Radio Adapters"
+menuconfig RADIO_ADAPTERS
+       bool "Radio Adapters"
        depends on VIDEO_DEV
+       default y
+       ---help---
+         Say Y here to enable selecting AM/FM radio adapters.
+
+if RADIO_ADAPTERS
 
 config RADIO_CADET
        tristate "ADS Cadet AM/FM Tuner"
@@ -328,4 +334,5 @@ config USB_DSBR
 
          To compile this driver as a module, choose M here: the
          module will be called dsbr100.
-endmenu
+
+endif # RADIO_ADAPTERS
index 449df1bb00d3050914a219a8ee99d8fca498cb48..3bd07f7e377489198ca539deee8e3401ffa5056a 100644 (file)
 
  History:
 
+ Version 0.42:
+       Converted dsbr100 to use video_ioctl2
+       by Douglas Landgraf <dougsland@gmail.com>
+
  Version 0.41-ac1:
        Alan Cox: Some cleanups and fixes
 
@@ -121,8 +125,6 @@ devices, that would be 76 and 91.  */
 static int usb_dsbr100_probe(struct usb_interface *intf,
                             const struct usb_device_id *id);
 static void usb_dsbr100_disconnect(struct usb_interface *intf);
-static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
-                            unsigned int cmd, unsigned long arg);
 static int usb_dsbr100_open(struct inode *inode, struct file *file);
 static int usb_dsbr100_close(struct inode *inode, struct file *file);
 
@@ -142,26 +144,6 @@ struct dsbr100_device {
 };
 
 
-/* File system interface */
-static const struct file_operations usb_dsbr100_fops = {
-       .owner =        THIS_MODULE,
-       .open =         usb_dsbr100_open,
-       .release =      usb_dsbr100_close,
-       .ioctl =        usb_dsbr100_ioctl,
-       .compat_ioctl = v4l_compat_ioctl32,
-       .llseek =       no_llseek,
-};
-
-/* V4L interface */
-static struct video_device dsbr100_videodev_template=
-{
-       .owner =        THIS_MODULE,
-       .name =         "D-Link DSB-R 100",
-       .type =         VID_TYPE_TUNER,
-       .fops =         &usb_dsbr100_fops,
-       .release = video_device_release,
-};
-
 static struct usb_device_id usb_dsbr100_device_table [] = {
        { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) },
        { }                                             /* Terminating entry */
@@ -252,37 +234,6 @@ static void dsbr100_getstat(struct dsbr100_device *radio)
 
 /* USB subsystem interface begins here */
 
-/* check if the device is present and register with v4l and
-usb if it is */
-static int usb_dsbr100_probe(struct usb_interface *intf,
-                        const struct usb_device_id *id)
-{
-       struct dsbr100_device *radio;
-
-       if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL)))
-               return -ENOMEM;
-       if (!(radio->videodev = video_device_alloc())) {
-               kfree(radio);
-               return -ENOMEM;
-       }
-       memcpy(radio->videodev, &dsbr100_videodev_template,
-               sizeof(dsbr100_videodev_template));
-       radio->removed = 0;
-       radio->users = 0;
-       radio->usbdev = interface_to_usbdev(intf);
-       radio->curfreq = FREQ_MIN*FREQ_MUL;
-       video_set_drvdata(radio->videodev, radio);
-       if (video_register_device(radio->videodev, VFL_TYPE_RADIO,
-               radio_nr)) {
-               warn("Could not register video device");
-               video_device_release(radio->videodev);
-               kfree(radio);
-               return -EIO;
-       }
-       usb_set_intfdata(intf, radio);
-       return 0;
-}
-
 /* handle unplugging of the device, release data structures
 if nothing keeps us from doing it.  If something is still
 keeping us busy, the release callback of v4l will take care
@@ -307,133 +258,147 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
 }
 
 
-/* Video for Linux interface */
+static int vidioc_querycap(struct file *file, void *priv,
+                                       struct v4l2_capability *v)
+{
+       strlcpy(v->driver, "dsbr100", sizeof(v->driver));
+       strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card));
+       sprintf(v->bus_info, "ISA");
+       v->version = RADIO_VERSION;
+       v->capabilities = V4L2_CAP_TUNER;
+       return 0;
+}
 
-static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file,
-                               unsigned int cmd, void *arg)
+static int vidioc_g_tuner(struct file *file, void *priv,
+                               struct v4l2_tuner *v)
 {
-       struct dsbr100_device *radio=video_get_drvdata(video_devdata(file));
+       struct dsbr100_device *radio = video_get_drvdata(video_devdata(file));
+
+       if (v->index > 0)
+               return -EINVAL;
+
+       dsbr100_getstat(radio);
+       strcpy(v->name, "FM");
+       v->type = V4L2_TUNER_RADIO;
+       v->rangelow = FREQ_MIN*FREQ_MUL;
+       v->rangehigh = FREQ_MAX*FREQ_MUL;
+       v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+       v->capability = V4L2_TUNER_CAP_LOW;
+       if(radio->stereo)
+               v->audmode = V4L2_TUNER_MODE_STEREO;
+       else
+               v->audmode = V4L2_TUNER_MODE_MONO;
+       v->signal = 0xffff;     /* We can't get the signal strength */
+       return 0;
+}
 
-       if (!radio)
-               return -EIO;
+static int vidioc_s_tuner(struct file *file, void *priv,
+                               struct v4l2_tuner *v)
+{
+       if (v->index > 0)
+               return -EINVAL;
 
-       switch(cmd) {
-               case VIDIOC_QUERYCAP:
-               {
-                       struct v4l2_capability *v = arg;
-                       memset(v,0,sizeof(*v));
-                       strlcpy(v->driver, "dsbr100", sizeof (v->driver));
-                       strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof (v->card));
-                       sprintf(v->bus_info,"ISA");
-                       v->version = RADIO_VERSION;
-                       v->capabilities = V4L2_CAP_TUNER;
+       return 0;
+}
 
-                       return 0;
-               }
-               case VIDIOC_G_TUNER:
-               {
-                       struct v4l2_tuner *v = arg;
+static int vidioc_s_frequency(struct file *file, void *priv,
+                               struct v4l2_frequency *f)
+{
+       struct dsbr100_device *radio = video_get_drvdata(video_devdata(file));
 
-                       if (v->index > 0)
-                               return -EINVAL;
+       radio->curfreq = f->frequency;
+       if (dsbr100_setfreq(radio, radio->curfreq)==-1)
+               warn("Set frequency failed");
+       return 0;
+}
 
-                       dsbr100_getstat(radio);
+static int vidioc_g_frequency(struct file *file, void *priv,
+                               struct v4l2_frequency *f)
+{
+       struct dsbr100_device *radio = video_get_drvdata(video_devdata(file));
 
-                       memset(v,0,sizeof(*v));
-                       strcpy(v->name, "FM");
-                       v->type = V4L2_TUNER_RADIO;
+       f->type = V4L2_TUNER_RADIO;
+       f->frequency = radio->curfreq;
+       return 0;
+}
 
-                       v->rangelow = FREQ_MIN*FREQ_MUL;
-                       v->rangehigh = FREQ_MAX*FREQ_MUL;
-                       v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
-                       v->capability=V4L2_TUNER_CAP_LOW;
-                       if(radio->stereo)
-                               v->audmode = V4L2_TUNER_MODE_STEREO;
-                       else
-                               v->audmode = V4L2_TUNER_MODE_MONO;
-                       v->signal = 0xFFFF;     /* We can't get the signal strength */
+static int vidioc_queryctrl(struct file *file, void *priv,
+                               struct v4l2_queryctrl *qc)
+{
+       int i;
 
+       for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+               if (qc->id && qc->id == radio_qctrl[i].id) {
+                       memcpy(qc, &(radio_qctrl[i]),
+                                               sizeof(*qc));
                        return 0;
                }
-               case VIDIOC_S_TUNER:
-               {
-                       struct v4l2_tuner *v = arg;
-
-                       if (v->index > 0)
-                               return -EINVAL;
+       }
+       return -EINVAL;
+}
 
-                       return 0;
-               }
-               case VIDIOC_S_FREQUENCY:
-               {
-                       struct v4l2_frequency *f = arg;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+                               struct v4l2_control *ctrl)
+{
+       struct dsbr100_device *radio = video_get_drvdata(video_devdata(file));
 
-                       radio->curfreq = f->frequency;
-                       if (dsbr100_setfreq(radio, radio->curfreq)==-1)
-                               warn("Set frequency failed");
-                       return 0;
-               }
-               case VIDIOC_G_FREQUENCY:
-               {
-                       struct v4l2_frequency *f = arg;
+       switch (ctrl->id) {
+       case V4L2_CID_AUDIO_MUTE:
+               ctrl->value = radio->muted;
+               return 0;
+       }
+       return -EINVAL;
+}
 
-                       f->type = V4L2_TUNER_RADIO;
-                       f->frequency = radio->curfreq;
+static int vidioc_s_ctrl(struct file *file, void *priv,
+                               struct v4l2_control *ctrl)
+{
+       struct dsbr100_device *radio = video_get_drvdata(video_devdata(file));
 
-                       return 0;
-               }
-               case VIDIOC_QUERYCTRL:
-               {
-                       struct v4l2_queryctrl *qc = arg;
-                       int i;
-
-                       for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-                               if (qc->id && qc->id == radio_qctrl[i].id) {
-                                       memcpy(qc, &(radio_qctrl[i]),
-                                                               sizeof(*qc));
-                                       return 0;
-                               }
-                       }
-                       return -EINVAL;
-               }
-               case VIDIOC_G_CTRL:
-               {
-                       struct v4l2_control *ctrl= arg;
-
-                       switch (ctrl->id) {
-                       case V4L2_CID_AUDIO_MUTE:
-                               ctrl->value=radio->muted;
-                               return 0;
-                       }
-                       return -EINVAL;
-               }
-               case VIDIOC_S_CTRL:
-               {
-                       struct v4l2_control *ctrl= arg;
-
-                       switch (ctrl->id) {
-                       case V4L2_CID_AUDIO_MUTE:
-                               if (ctrl->value) {
-                                       if (dsbr100_stop(radio)==-1)
-                                               warn("Radio did not respond properly");
-                               } else {
-                                       if (dsbr100_start(radio)==-1)
-                                               warn("Radio did not respond properly");
-                               }
-                               return 0;
-                       }
-                       return -EINVAL;
+       switch (ctrl->id) {
+       case V4L2_CID_AUDIO_MUTE:
+               if (ctrl->value) {
+                       if (dsbr100_stop(radio)==-1)
+                               warn("Radio did not respond properly");
+               } else {
+                       if (dsbr100_start(radio)==-1)
+                               warn("Radio did not respond properly");
                }
-               default:
-                       return v4l_compat_translate_ioctl(inode,file,cmd,arg,
-                                                         usb_dsbr100_do_ioctl);
+               return 0;
        }
+       return -EINVAL;
 }
 
-static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
-                            unsigned int cmd, unsigned long arg)
+static int vidioc_g_audio(struct file *file, void *priv,
+                               struct v4l2_audio *a)
 {
-       return video_usercopy(inode, file, cmd, arg, usb_dsbr100_do_ioctl);
+       if (a->index > 1)
+               return -EINVAL;
+
+       strcpy(a->name, "Radio");
+       a->capability = V4L2_AUDCAP_STEREO;
+       return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+       *i = 0;
+       return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+       if (i != 0)
+               return -EINVAL;
+       return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+                                       struct v4l2_audio *a)
+{
+       if (a->index != 0)
+               return -EINVAL;
+       return 0;
 }
 
 static int usb_dsbr100_open(struct inode *inode, struct file *file)
@@ -465,6 +430,68 @@ static int usb_dsbr100_close(struct inode *inode, struct file *file)
        return 0;
 }
 
+/* File system interface */
+static const struct file_operations usb_dsbr100_fops = {
+       .owner          = THIS_MODULE,
+       .open           = usb_dsbr100_open,
+       .release        = usb_dsbr100_close,
+       .ioctl          = video_ioctl2,
+       .compat_ioctl   = v4l_compat_ioctl32,
+       .llseek         = no_llseek,
+};
+
+/* V4L2 interface */
+static struct video_device dsbr100_videodev_template =
+{
+       .owner          = THIS_MODULE,
+       .name           = "D-Link DSB-R 100",
+       .type           = VID_TYPE_TUNER,
+       .fops           = &usb_dsbr100_fops,
+       .release        = video_device_release,
+       .vidioc_querycap    = vidioc_querycap,
+       .vidioc_g_tuner     = vidioc_g_tuner,
+       .vidioc_s_tuner     = vidioc_s_tuner,
+       .vidioc_g_frequency = vidioc_g_frequency,
+       .vidioc_s_frequency = vidioc_s_frequency,
+       .vidioc_queryctrl   = vidioc_queryctrl,
+       .vidioc_g_ctrl      = vidioc_g_ctrl,
+       .vidioc_s_ctrl      = vidioc_s_ctrl,
+       .vidioc_g_audio     = vidioc_g_audio,
+       .vidioc_s_audio     = vidioc_s_audio,
+       .vidioc_g_input     = vidioc_g_input,
+       .vidioc_s_input     = vidioc_s_input,
+};
+
+/* check if the device is present and register with v4l and
+usb if it is */
+static int usb_dsbr100_probe(struct usb_interface *intf,
+                               const struct usb_device_id *id)
+{
+       struct dsbr100_device *radio;
+
+       if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL)))
+               return -ENOMEM;
+       if (!(radio->videodev = video_device_alloc())) {
+               kfree(radio);
+               return -ENOMEM;
+       }
+       memcpy(radio->videodev, &dsbr100_videodev_template,
+               sizeof(dsbr100_videodev_template));
+       radio->removed = 0;
+       radio->users = 0;
+       radio->usbdev = interface_to_usbdev(intf);
+       radio->curfreq = FREQ_MIN*FREQ_MUL;
+       video_set_drvdata(radio->videodev, radio);
+       if (video_register_device(radio->videodev, VFL_TYPE_RADIO,radio_nr)) {
+               warn("Could not register video device");
+               video_device_release(radio->videodev);
+               kfree(radio);
+               return -EIO;
+       }
+       usb_set_intfdata(intf, radio);
+       return 0;
+}
+
 static int __init dsbr100_init(void)
 {
        int retval = usb_register(&usb_dsbr100_driver);
index 8fbf0d8bd2783fcf1ca42238b92fc6eceae16bf0..8cf2e9df5c8aa0ae5365d2293b1e53c9c417669e 100644 (file)
 
 #define CADET_VERSION KERNEL_VERSION(0,3,3)
 
+static struct v4l2_queryctrl radio_qctrl[] = {
+       {
+               .id            = V4L2_CID_AUDIO_MUTE,
+               .name          = "Mute",
+               .minimum       = 0,
+               .maximum       = 1,
+               .default_value = 1,
+               .type          = V4L2_CTRL_TYPE_BOOLEAN,
+       },{
+               .id            = V4L2_CID_AUDIO_VOLUME,
+               .name          = "Volume",
+               .minimum       = 0,
+               .maximum       = 0xff,
+               .step          = 1,
+               .default_value = 0xff,
+               .type          = V4L2_CTRL_TYPE_INTEGER,
+       }
+};
+
 static int io=-1;              /* default to isapnp activation */
 static int radio_nr = -1;
 static int users=0;
@@ -347,135 +366,165 @@ cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
 }
 
 
+static int vidioc_querycap(struct file *file, void *priv,
+                               struct v4l2_capability *v)
+{
+       v->capabilities =
+               V4L2_CAP_TUNER |
+               V4L2_CAP_READWRITE;
+       v->version = CADET_VERSION;
+       strcpy(v->driver, "ADS Cadet");
+       strcpy(v->card, "ADS Cadet");
+       return 0;
+}
 
-static int cadet_do_ioctl(struct inode *inode, struct file *file,
-                         unsigned int cmd, void *arg)
+static int vidioc_g_tuner(struct file *file, void *priv,
+                               struct v4l2_tuner *v)
 {
-       switch(cmd)
-       {
-               case VIDIOC_QUERYCAP:
-               {
-                       struct v4l2_capability *cap = arg;
-                       memset(cap,0,sizeof(*cap));
-                       cap->capabilities =
-                               V4L2_CAP_TUNER |
-                               V4L2_CAP_READWRITE;
-                       cap->version = CADET_VERSION;
-                       strcpy(cap->driver, "ADS Cadet");
-                       strcpy(cap->card, "ADS Cadet");
-                       return 0;
+       v->type = V4L2_TUNER_RADIO;
+       switch (v->index) {
+       case 0:
+               strcpy(v->name, "FM");
+               v->capability = V4L2_TUNER_CAP_STEREO;
+               v->rangelow = 1400;     /* 87.5 MHz */
+               v->rangehigh = 1728;    /* 108.0 MHz */
+               v->rxsubchans=cadet_getstereo();
+               switch (v->rxsubchans){
+               case V4L2_TUNER_SUB_MONO:
+                       v->audmode = V4L2_TUNER_MODE_MONO;
+                       break;
+               case V4L2_TUNER_SUB_STEREO:
+                       v->audmode = V4L2_TUNER_MODE_STEREO;
+                       break;
+               default: ;
                }
-               case VIDIOC_G_TUNER:
-               {
-                       struct v4l2_tuner *t = arg;
-                       memset(t,0,sizeof(*t));
-                       t->type = V4L2_TUNER_RADIO;
-                       switch (t->index)
-                       {
-                               case 0: strcpy(t->name, "FM");
-                                       t->capability = V4L2_TUNER_CAP_STEREO;
-                                       t->rangelow = 1400;     /* 87.5 MHz */
-                                       t->rangehigh = 1728;    /* 108.0 MHz */
-                                       t->rxsubchans=cadet_getstereo();
-                                       switch (t->rxsubchans){
-                                               case V4L2_TUNER_SUB_MONO:
-                                                       t->audmode = V4L2_TUNER_MODE_MONO;
-                                                       break;
-                                               case V4L2_TUNER_SUB_STEREO:
-                                                       t->audmode = V4L2_TUNER_MODE_STEREO;
-                                                       break;
-                                               default: ;
-                                       }
-                                       break;
-                               case 1: strcpy(t->name, "AM");
-                                       t->capability = V4L2_TUNER_CAP_LOW;
-                                       t->rangelow = 8320;      /* 520 kHz */
-                                       t->rangehigh = 26400;    /* 1650 kHz */
-                                       t->rxsubchans = V4L2_TUNER_SUB_MONO;
-                                       t->audmode = V4L2_TUNER_MODE_MONO;
-                                       break;
-                               default:
-                                       return -EINVAL;
-                       }
+               break;
+       case 1:
+               strcpy(v->name, "AM");
+               v->capability = V4L2_TUNER_CAP_LOW;
+               v->rangelow = 8320;      /* 520 kHz */
+               v->rangehigh = 26400;    /* 1650 kHz */
+               v->rxsubchans = V4L2_TUNER_SUB_MONO;
+               v->audmode = V4L2_TUNER_MODE_MONO;
+               break;
+       default:
+               return -EINVAL;
+       }
+       v->signal = sigstrength; /* We might need to modify scaling of this */
+       return 0;
+}
 
-                       t->signal = sigstrength; /* We might need to modify scaling of this */
-                       return 0;
-               }
-               case VIDIOC_S_TUNER:
-               {
-                       struct v4l2_tuner *t = arg;
-                       if((t->index != 0)&&(t->index != 1))
-                               return -EINVAL;
+static int vidioc_s_tuner(struct file *file, void *priv,
+                               struct v4l2_tuner *v)
+{
+       if((v->index != 0)&&(v->index != 1))
+               return -EINVAL;
+       curtuner = v->index;
+       return 0;
+}
 
-                       curtuner = t->index;
-                       return 0;
-               }
-               case VIDIOC_G_FREQUENCY:
-               {
-                       struct v4l2_frequency *f = arg;
-                       memset(f,0,sizeof(*f));
-                       f->tuner = curtuner;
-                       f->type = V4L2_TUNER_RADIO;
-                       f->frequency = cadet_getfreq();
-                       return 0;
-               }
-               case VIDIOC_S_FREQUENCY:
-               {
-                       struct v4l2_frequency *f = arg;
-                       if (f->type != V4L2_TUNER_RADIO){
-                               return -EINVAL;
-                       }
-                       if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728))) {
-                               return -EINVAL;
-                       }
-                       if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400))) {
-                               return -EINVAL;
-                       }
-                       cadet_setfreq(f->frequency);
-                       return 0;
-               }
-               case VIDIOC_G_CTRL:
-               {
-                       struct v4l2_control *c = arg;
-                       switch (c->id){
-                               case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
-                                       c->value = (cadet_getvol() == 0);
-                                       break;
-                               case V4L2_CID_AUDIO_VOLUME:
-                                       c->value = cadet_getvol();
-                                       break;
-                               default:
-                                       return -EINVAL;
-                       }
-                       return 0;
-               }
-               case VIDIOC_S_CTRL:
-               {
-                       struct v4l2_control *c = arg;
-                       switch (c->id){
-                               case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
-                                       if (c->value) cadet_setvol(0);
-                                               else cadet_setvol(0xffff);
-                                       break;
-                               case V4L2_CID_AUDIO_VOLUME:
-                                       cadet_setvol(c->value);
-                                       break;
-                               default:
-                                       return -EINVAL;
-                       }
+static int vidioc_g_frequency(struct file *file, void *priv,
+                               struct v4l2_frequency *f)
+{
+       f->tuner = curtuner;
+       f->type = V4L2_TUNER_RADIO;
+       f->frequency = cadet_getfreq();
+       return 0;
+}
+
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+                               struct v4l2_frequency *f)
+{
+       if (f->type != V4L2_TUNER_RADIO)
+               return -EINVAL;
+       if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728)))
+               return -EINVAL;
+       if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400)))
+               return -EINVAL;
+       cadet_setfreq(f->frequency);
+       return 0;
+}
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+                               struct v4l2_queryctrl *qc)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+               if (qc->id && qc->id == radio_qctrl[i].id) {
+                       memcpy(qc, &(radio_qctrl[i]),
+                                               sizeof(*qc));
                        return 0;
                }
+       }
+       return -EINVAL;
+}
 
-               default:
-                       return -ENOIOCTLCMD;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+                               struct v4l2_control *ctrl)
+{
+       switch (ctrl->id){
+       case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
+               ctrl->value = (cadet_getvol() == 0);
+               break;
+       case V4L2_CID_AUDIO_VOLUME:
+               ctrl->value = cadet_getvol();
+               break;
+       default:
+               return -EINVAL;
        }
+       return 0;
 }
 
-static int
-cadet_ioctl(struct inode *inode, struct file *file,
-                      unsigned int cmd, unsigned long arg)
+static int vidioc_s_ctrl(struct file *file, void *priv,
+                               struct v4l2_control *ctrl)
 {
-       return video_usercopy(inode, file, cmd, arg, cadet_do_ioctl);
+       switch (ctrl->id){
+       case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
+               if (ctrl->value)
+                       cadet_setvol(0);
+               else
+                       cadet_setvol(0xffff);
+               break;
+       case V4L2_CID_AUDIO_VOLUME:
+               cadet_setvol(ctrl->value);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+                               struct v4l2_audio *a)
+{
+       if (a->index > 1)
+               return -EINVAL;
+       strcpy(a->name, "Radio");
+       a->capability = V4L2_AUDCAP_STEREO;
+       return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+       *i = 0;
+       return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+       if (i != 0)
+               return -EINVAL;
+       return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+                               struct v4l2_audio *a)
+{
+       if (a->index != 0)
+               return -EINVAL;
+       return 0;
 }
 
 static int
@@ -512,7 +561,7 @@ static const struct file_operations cadet_fops = {
        .open           = cadet_open,
        .release        = cadet_release,
        .read           = cadet_read,
-       .ioctl          = cadet_ioctl,
+       .ioctl          = video_ioctl2,
        .poll           = cadet_poll,
        .compat_ioctl   = v4l_compat_ioctl32,
        .llseek         = no_llseek,
@@ -524,6 +573,18 @@ static struct video_device cadet_radio=
        .name           = "Cadet radio",
        .type           = VID_TYPE_TUNER,
        .fops           = &cadet_fops,
+       .vidioc_querycap    = vidioc_querycap,
+       .vidioc_g_tuner     = vidioc_g_tuner,
+       .vidioc_s_tuner     = vidioc_s_tuner,
+       .vidioc_g_frequency = vidioc_g_frequency,
+       .vidioc_s_frequency = vidioc_s_frequency,
+       .vidioc_queryctrl   = vidioc_queryctrl,
+       .vidioc_g_ctrl      = vidioc_g_ctrl,
+       .vidioc_s_ctrl      = vidioc_s_ctrl,
+       .vidioc_g_audio     = vidioc_g_audio,
+       .vidioc_s_audio     = vidioc_s_audio,
+       .vidioc_g_input     = vidioc_g_input,
+       .vidioc_s_input     = vidioc_s_input,
 };
 
 static struct pnp_device_id cadet_pnp_devices[] = {
index 11f80cacd6edef44f0f224a768962a288f63cfa2..8e33a19a22a3134c16109d60ebd5bff971ec6056 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/delay.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <linux/mutex.h>
 #include <linux/pci.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
@@ -110,7 +109,6 @@ struct radio_device {
                muted,  /* VIDEO_AUDIO_MUTE */
                stereo, /* VIDEO_TUNER_STEREO_ON */
                tuned;  /* signal strength (0 or 0xffff) */
-       struct mutex lock;
 };
 
 static u32 radio_bits_get(struct radio_device *dev)
@@ -394,7 +392,6 @@ static int __devinit maestro_probe(struct pci_dev *pdev,
        }
 
        radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA;
-       mutex_init(&radio_unit->lock);
 
        maestro_radio_inst = video_device_alloc();
        if (maestro_radio_inst == NULL) {
index a4715901512d48cf4c93ba5aa477d4536e6e0f24..203f4373eeb8f7ea189cd3ef2705a1ba9c7f55c2 100644 (file)
@@ -410,7 +410,6 @@ static struct video_device zoltrix_radio =
        .owner          = THIS_MODULE,
        .name           = "Zoltrix Radio Plus",
        .type           = VID_TYPE_TUNER,
-       .hardware       = 0,
        .fops           = &zoltrix_fops,
        .vidioc_querycap    = vidioc_querycap,
        .vidioc_g_tuner     = vidioc_g_tuner,
index bc773781993a5b75113388a623f12f64fa697556..5cb3f54b548b1dc9f678d486cafa5b8026c58135 100644 (file)
@@ -2,14 +2,19 @@
 # Multimedia Video device configuration
 #
 
-menu "Video Capture Adapters"
+menuconfig VIDEO_CAPTURE_DRIVERS
+       bool "Video capture adapters"
        depends on VIDEO_DEV
+       default y
+       ---help---
+         Say Y here to enable selecting the video adapters for
+         webcams, analog TV, and hybrid analog/digital TV.
+         Some of those devices also supports FM radio.
 
-comment "Video Capture Adapters"
+if VIDEO_CAPTURE_DRIVERS
 
 config VIDEO_ADV_DEBUG
        bool "Enable advanced debug functionality"
-       depends on VIDEO_DEV
        default n
        ---help---
          Say Y here to enable advanced debugging functionality on some
@@ -34,7 +39,7 @@ config VIDEO_HELPER_CHIPS_AUTO
 #
 
 menu "Encoders/decoders and other helper chips"
-       depends on VIDEO_DEV && !VIDEO_HELPER_CHIPS_AUTO
+       depends on !VIDEO_HELPER_CHIPS_AUTO
 
 comment "Audio decoders"
 
@@ -61,7 +66,7 @@ config VIDEO_TDA7432
 
 config VIDEO_TDA9840
        tristate "Philips TDA9840 audio processor"
-       depends on VIDEO_DEV && I2C
+       depends on I2C
        ---help---
          Support for tda9840 audio decoder chip found on some Zoran boards.
 
@@ -79,7 +84,7 @@ config VIDEO_TDA9875
 
 config VIDEO_TEA6415C
        tristate "Philips TEA6415C audio processor"
-       depends on VIDEO_DEV && I2C
+       depends on I2C
        ---help---
          Support for tea6415c audio decoder chip found on some bt8xx boards.
 
@@ -88,7 +93,7 @@ config VIDEO_TEA6415C
 
 config VIDEO_TEA6420
        tristate "Philips TEA6420 audio processor"
-       depends on VIDEO_DEV && I2C
+       depends on I2C
        ---help---
          Support for tea6420 audio decoder chip found on some bt8xx boards.
 
@@ -469,7 +474,7 @@ config VIDEO_SAA5246A
 
 config VIDEO_SAA5249
        tristate "SAA5249 Teletext processor"
-       depends on VIDEO_DEV && I2C && VIDEO_V4L2
+       depends on I2C && VIDEO_V4L2
        help
          Support for I2C bus based teletext using the SAA5249 chip. At the
          moment this is only useful on some European WinTV cards.
@@ -479,7 +484,7 @@ config VIDEO_SAA5249
 
 config TUNER_3036
        tristate "SAB3036 tuner"
-       depends on VIDEO_DEV && I2C && VIDEO_V4L1
+       depends on I2C && VIDEO_V4L1
        help
          Say Y here to include support for Philips SAB3036 compatible tuners.
          If in doubt, say N.
@@ -681,8 +686,12 @@ config VIDEO_CAFE_CCIC
 # USB Multimedia device configuration
 #
 
-menu "V4L USB devices"
-       depends on USB && VIDEO_DEV
+menuconfig V4L_USB_DRIVERS
+       bool "V4L USB devices"
+       depends on USB
+       default y
+
+if V4L_USB_DRIVERS
 
 source "drivers/media/video/pvrusb2/Kconfig"
 
@@ -707,7 +716,7 @@ config VIDEO_OVCAMCHIP
 
 config USB_W9968CF
        tristate "USB W996[87]CF JPEG Dual Mode Camera support"
-       depends on USB && VIDEO_V4L1 && I2C
+       depends on VIDEO_V4L1 && I2C
        select VIDEO_OVCAMCHIP
        ---help---
          Say Y here if you want support for cameras based on OV681 or
@@ -725,7 +734,7 @@ config USB_W9968CF
 
 config USB_OV511
        tristate "USB OV511 Camera support"
-       depends on USB && VIDEO_V4L1
+       depends on VIDEO_V4L1
        ---help---
          Say Y here if you want to connect this type of camera to your
          computer's USB port. See <file:Documentation/video4linux/ov511.txt>
@@ -736,7 +745,7 @@ config USB_OV511
 
 config USB_SE401
        tristate "USB SE401 Camera support"
-       depends on USB && VIDEO_V4L1
+       depends on VIDEO_V4L1
        ---help---
          Say Y here if you want to connect this type of camera to your
          computer's USB port. See <file:Documentation/video4linux/se401.txt>
@@ -749,7 +758,7 @@ source "drivers/media/video/sn9c102/Kconfig"
 
 config USB_STV680
        tristate "USB STV680 (Pencam) Camera support"
-       depends on USB && VIDEO_V4L1
+       depends on VIDEO_V4L1
        ---help---
          Say Y here if you want to connect this type of camera to your
          computer's USB port. This includes the Pencam line of cameras.
@@ -765,7 +774,7 @@ source "drivers/media/video/pwc/Kconfig"
 
 config USB_ZR364XX
        tristate "USB ZR364XX Camera support"
-       depends on USB && VIDEO_V4L2
+       depends on VIDEO_V4L2
        ---help---
          Say Y here if you want to connect this type of camera to your
          computer's USB port.
@@ -775,6 +784,6 @@ config USB_ZR364XX
          To compile this driver as a module, choose M here: the
          module will be called zr364xx.
 
-endmenu # V4L USB devices
+endif # V4L_USB_DRIVERS
 
-endmenu
+endif # VIDEO_CAPTURE_DRIVERS
index 1757a588970fc242717128f707765029a9862eac..67bda9f9a44bfa48998de9f3566ef57da7222ded 100644 (file)
@@ -555,7 +555,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
 {
        struct v4l2_pix_format *pix;
        int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
-       int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC);
+       int is_50Hz = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60);
 
        switch (fmt->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -567,7 +567,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
                Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
                Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
 
-               Vlines = pix->height + (is_pal ? 4 : 7);
+               Vlines = pix->height + (is_50Hz ? 4 : 7);
 
                if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
                    (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
index 2ebde2fdbcbe8b7cb3c95fd51ad3393ecf01c70c..543b05ebc0e79ba74851f2a7c4b4180bde2d1e93 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
 #include <asm/delay.h>
 
 #include "cx88.h"
@@ -612,7 +613,7 @@ struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board
 }
 
 /* Driver asked for hardware access. */
-int cx8802_request_acquire(struct cx8802_driver *drv)
+static int cx8802_request_acquire(struct cx8802_driver *drv)
 {
        struct cx88_core *core = drv->core;
 
@@ -632,7 +633,7 @@ int cx8802_request_acquire(struct cx8802_driver *drv)
 }
 
 /* Driver asked to release hardware. */
-int cx8802_request_release(struct cx8802_driver *drv)
+static int cx8802_request_release(struct cx8802_driver *drv)
 {
        struct cx88_core *core = drv->core;
 
index b94ef8ab28c1503f4602565bb7b3c24356614734..98fa35421bdd4d3da05be0b0ad6bdfdcbb9804f5 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
+#include <linux/dma-mapping.h>
 #include <asm/div64.h>
 
 #include "cx88.h"
index 6068c9bf82cd45da8f7d78aa06bdc2a5120dae1d..82bc3a28aa22941ad7aa0617ece154c910e17880 100644 (file)
@@ -111,10 +111,6 @@ static struct i2c_adapter vp3054_i2c_adap_template = {
        .id                = I2C_HW_B_CX2388x,
 };
 
-static struct i2c_client vp3054_i2c_client_template = {
-       .name   = "VP-3054",
-};
-
 int vp3054_i2c_probe(struct cx8802_dev *dev)
 {
        struct cx88_core *core = dev->core;
@@ -133,8 +129,6 @@ int vp3054_i2c_probe(struct cx8802_dev *dev)
               sizeof(vp3054_i2c->adap));
        memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template,
               sizeof(vp3054_i2c->algo));
-       memcpy(&vp3054_i2c->client, &vp3054_i2c_client_template,
-              sizeof(vp3054_i2c->client));
 
        vp3054_i2c->adap.class |= I2C_CLASS_TV_DIGITAL;
 
@@ -144,7 +138,6 @@ int vp3054_i2c_probe(struct cx8802_dev *dev)
        vp3054_i2c->algo.data = dev;
        i2c_set_adapdata(&vp3054_i2c->adap, dev);
        vp3054_i2c->adap.algo_data = &vp3054_i2c->algo;
-       vp3054_i2c->client.adapter = &vp3054_i2c->adap;
 
        vp3054_bit_setscl(dev,1);
        vp3054_bit_setsda(dev,1);
index b7a0a04d2423e4034d7c35a6de9f0712f13aca6d..637a7d2322389c79ac161981e1ce6fcd9b7ebf7c 100644 (file)
@@ -26,7 +26,6 @@
 struct vp3054_i2c_state {
        struct i2c_adapter         adap;
        struct i2c_algo_bit_data   algo;
-       struct i2c_client          client;
        u32                        state;
 };
 
index 9285a58e47aae9a166723809b1df65c57f1525a4..3823b62da4a4b70f3f28b5b4298ae65c8cd4fdb2 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_EM28XX
        tristate "Empia EM2800/2820/2840 USB video capture support"
-       depends on VIDEO_V4L1 && USB && I2C
+       depends on VIDEO_V4L1 && I2C
        select VIDEO_BUF
        select VIDEO_TUNER
        select VIDEO_TVEEPROM
index c6bff705688d0e02404b7730a972557042e67cd4..664676f440685cdc0f405ba97a84560e5f132811 100644 (file)
@@ -1,6 +1,6 @@
 config USB_ET61X251
        tristate "USB ET61X[12]51 PC Camera Controller support"
-       depends on USB && VIDEO_V4L1
+       depends on VIDEO_V4L1
        ---help---
          Say Y here if you want support for cameras based on Etoms ET61X151
          or ET61X251 PC Camera Controllers.
index 45b9328a538f5c8d4809462c4147a23c1f217df7..e29f949adf57d255a67b9967dc90d6ce01fa22e9 100644 (file)
@@ -74,7 +74,7 @@ int ivtv_first_minor = 0;
 struct ivtv *ivtv_cards[IVTV_MAX_CARDS];
 
 /* Protects ivtv_cards_active */
-spinlock_t ivtv_cards_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(ivtv_cards_lock);
 
 /* add your revision and whatnot here */
 static struct pci_device_id ivtv_pci_tbl[] __devinitdata = {
index 1637097ddec742c68ddbf2d17be485855c2b4be8..8976487a65f3c7994481a7657616b9acfaf75952 100644 (file)
@@ -804,7 +804,7 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
        struct ivtv_open_id *item;
        struct ivtv *itv = NULL;
        struct ivtv_stream *s = NULL;
-       int minor = MINOR(inode->i_rdev);
+       int minor = iminor(inode);
 
        /* Find which card this open was on */
        spin_lock(&ivtv_cards_lock);
index 5645c9318890d6c701f3bfb9aed7729830fa42fb..d0c2cd7854303fc8167a8203f85ee7f30493a27b 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_PVRUSB2
        tristate "Hauppauge WinTV-PVR USB2 support"
-       depends on VIDEO_V4L2 && USB && I2C && EXPERIMENTAL
+       depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
        select FW_LOADER
        select VIDEO_TUNER
        select VIDEO_TVEEPROM
index 5669c8ca9ca3b5a60e49e1b47b07b99455dbb04a..20b614436d2cffc16b239025ec79736dda9ddab1 100644 (file)
@@ -391,22 +391,29 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
 int pvr2_encoder_configure(struct pvr2_hdw *hdw)
 {
        int ret;
+       int val;
        pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure"
                   " (cx2341x module)");
        hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING;
        hdw->enc_ctl_state.width = hdw->res_hor_val;
        hdw->enc_ctl_state.height = hdw->res_ver_val;
-       hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur &
-                                      (V4L2_STD_NTSC|V4L2_STD_PAL_M)) ?
+       hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & V4L2_STD_525_60) ?
                                      0 : 1);
 
        ret = 0;
 
        ret |= pvr2_encoder_prep_config(hdw);
 
+       /* saa7115: 0xf0 */
+       val = 0xf0;
+       if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
+               /* ivtv cx25840: 0x140 */
+               val = 0x140;
+       }
+
        if (!ret) ret = pvr2_encoder_vcmd(
                hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2,
-               0xf0, 0xf0);
+               val, val);
 
        /* setup firmware to notify us about some events (don't know why...) */
        if (!ret) ret = pvr2_encoder_vcmd(
index acf651e01f94aeebff01dd7e82c1a19832a75b09..1311891e7ee3dd0d85acc751c0ad40362271e3c4 100644 (file)
@@ -83,7 +83,7 @@ static struct pvr2_string_table pvr2_client_lists[] = {
 };
 
 static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
-static DECLARE_MUTEX(pvr2_unit_sem);
+static DEFINE_MUTEX(pvr2_unit_mtx);
 
 static int ctlchg = 0;
 static int initusbreset = 1;
@@ -2076,14 +2076,14 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
        hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
        if (!hdw->ctl_read_urb) goto fail;
 
-       down(&pvr2_unit_sem); do {
+       mutex_lock(&pvr2_unit_mtx); do {
                for (idx = 0; idx < PVR_NUM; idx++) {
                        if (unit_pointers[idx]) continue;
                        hdw->unit_number = idx;
                        unit_pointers[idx] = hdw;
                        break;
                }
-       } while (0); up(&pvr2_unit_sem);
+       } while (0); mutex_unlock(&pvr2_unit_mtx);
 
        cnt1 = 0;
        cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
@@ -2186,13 +2186,13 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
        }
        pvr2_i2c_core_done(hdw);
        pvr2_hdw_remove_usb_stuff(hdw);
-       down(&pvr2_unit_sem); do {
+       mutex_lock(&pvr2_unit_mtx); do {
                if ((hdw->unit_number >= 0) &&
                    (hdw->unit_number < PVR_NUM) &&
                    (unit_pointers[hdw->unit_number] == hdw)) {
                        unit_pointers[hdw->unit_number] = NULL;
                }
-       } while (0); up(&pvr2_unit_sem);
+       } while (0); mutex_unlock(&pvr2_unit_mtx);
        kfree(hdw->controls);
        kfree(hdw->mpeg_ctrl_info);
        kfree(hdw->std_defs);
index 58fc3c730fe189bb5f608f42a04a9316fd10be41..6786d3c0c98beaf8b1a3fc84d55787f97a7f5d89 100644 (file)
@@ -23,6 +23,7 @@
 #include "pvrusb2-hdw-internal.h"
 #include "pvrusb2-debug.h"
 #include "pvrusb2-fx2-cmd.h"
+#include "pvrusb2.h"
 
 #define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
 
@@ -38,6 +39,10 @@ static unsigned int i2c_scan = 0;
 module_param(i2c_scan, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
 
+static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
+module_param_array(ir_mode, int, NULL, 0444);
+MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
+
 static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
                                             unsigned int detail,
                                             char *buf,unsigned int maxlen);
@@ -273,6 +278,15 @@ static int i2c_hack_wm8775(struct pvr2_hdw *hdw,
        return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
 }
 
+/* This is an entry point designed to always fail any attempt to perform a
+   transfer.  We use this to cause certain I2C addresses to not be
+   probed. */
+static int i2c_black_hole(struct pvr2_hdw *hdw,
+                          u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
+{
+       return -EIO;
+}
+
 /* This is a special entry point that is entered if an I2C operation is
    attempted to a cx25840 chip on model 24xxx hardware.  This chip can
    sometimes wedge itself.  Worse still, when this happens msp3400 can
@@ -994,10 +1008,17 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
        }
 
        /* However, deal with various special cases for 24xxx hardware. */
+       if (ir_mode[hdw->unit_number] == 0) {
+               printk(KERN_INFO "%s: IR disabled\n",hdw->name);
+               hdw->i2c_func[0x18] = i2c_black_hole;
+       } else if (ir_mode[hdw->unit_number] == 1) {
+               if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
+                       hdw->i2c_func[0x18] = i2c_24xxx_ir;
+               }
+       }
        if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
                hdw->i2c_func[0x1b] = i2c_hack_wm8775;
                hdw->i2c_func[0x44] = i2c_hack_cx25840;
-               hdw->i2c_func[0x18] = i2c_24xxx_ir;
        }
 
        // Configure the adapter and set up everything else related to it.
index a741c556a39a06119619f0ff7cea0fd7127d71ad..7ab79baa1c8ce43aa771e21001b83e24006d25e5 100644 (file)
@@ -518,40 +518,32 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
        }
        sfp->item_last = cip;
 
-       cip->attr_name.attr.owner = THIS_MODULE;
        cip->attr_name.attr.name = "name";
        cip->attr_name.attr.mode = S_IRUGO;
        cip->attr_name.show = fp->show_name;
 
-       cip->attr_type.attr.owner = THIS_MODULE;
        cip->attr_type.attr.name = "type";
        cip->attr_type.attr.mode = S_IRUGO;
        cip->attr_type.show = fp->show_type;
 
-       cip->attr_min.attr.owner = THIS_MODULE;
        cip->attr_min.attr.name = "min_val";
        cip->attr_min.attr.mode = S_IRUGO;
        cip->attr_min.show = fp->show_min;
 
-       cip->attr_max.attr.owner = THIS_MODULE;
        cip->attr_max.attr.name = "max_val";
        cip->attr_max.attr.mode = S_IRUGO;
        cip->attr_max.show = fp->show_max;
 
-       cip->attr_val.attr.owner = THIS_MODULE;
        cip->attr_val.attr.name = "cur_val";
        cip->attr_val.attr.mode = S_IRUGO;
 
-       cip->attr_custom.attr.owner = THIS_MODULE;
        cip->attr_custom.attr.name = "custom_val";
        cip->attr_custom.attr.mode = S_IRUGO;
 
-       cip->attr_enum.attr.owner = THIS_MODULE;
        cip->attr_enum.attr.name = "enum_val";
        cip->attr_enum.attr.mode = S_IRUGO;
        cip->attr_enum.show = fp->show_enum;
 
-       cip->attr_bits.attr.owner = THIS_MODULE;
        cip->attr_bits.attr.name = "bit_val";
        cip->attr_bits.attr.mode = S_IRUGO;
        cip->attr_bits.show = fp->show_bits;
@@ -616,12 +608,10 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
 
        dip = kzalloc(sizeof(*dip),GFP_KERNEL);
        if (!dip) return;
-       dip->attr_debugcmd.attr.owner = THIS_MODULE;
        dip->attr_debugcmd.attr.name = "debugcmd";
        dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
        dip->attr_debugcmd.show = debugcmd_show;
        dip->attr_debugcmd.store = debugcmd_store;
-       dip->attr_debuginfo.attr.owner = THIS_MODULE;
        dip->attr_debuginfo.attr.name = "debuginfo";
        dip->attr_debuginfo.attr.mode = S_IRUGO;
        dip->attr_debuginfo.show = debuginfo_show;
@@ -811,7 +801,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
                return;
        }
 
-       sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE;
        sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
        sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
        sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
@@ -825,7 +814,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
                sfp->v4l_minor_number_created_ok = !0;
        }
 
-       sfp->attr_v4l_radio_minor_number.attr.owner = THIS_MODULE;
        sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number";
        sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO;
        sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show;
@@ -839,7 +827,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
                sfp->v4l_radio_minor_number_created_ok = !0;
        }
 
-       sfp->attr_unit_number.attr.owner = THIS_MODULE;
        sfp->attr_unit_number.attr.name = "unit_number";
        sfp->attr_unit_number.attr.mode = S_IRUGO;
        sfp->attr_unit_number.show = unit_number_show;
@@ -852,7 +839,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
                sfp->unit_number_created_ok = !0;
        }
 
-       sfp->attr_bus_info.attr.owner = THIS_MODULE;
        sfp->attr_bus_info.attr.name = "bus_info_str";
        sfp->attr_bus_info.attr.mode = S_IRUGO;
        sfp->attr_bus_info.show = bus_info_show;
index 8fdf7101d3bfcabb31863d6f0a5622ed5071bb5e..7298cf2e1650f53f2c5e90f0873045d295e43c17 100644 (file)
@@ -1,6 +1,6 @@
 config USB_PWC
        tristate "USB Philips Cameras"
-       depends on USB && VIDEO_V4L1
+       depends on VIDEO_V4L1
        ---help---
          Say Y or M here if you want to use one of these Philips & OEM
          webcams:
index 4ea479baee7448c18f407c138a00698851344d9d..50f15adfa7c87ff0a77a2d0284e8826aa8c54265 100644 (file)
@@ -1170,6 +1170,42 @@ struct saa7134_board saa7134_boards[] = {
                        .amux   = LINE2,
                },
        },
+    [SAA7134_BOARD_ECS_TVP3XP_4CB6] = {
+               /* Barry Scott <barry.scott@onelan.co.uk> */
+               .name           = "Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM)",
+               .audio_clock    = 0x187de7,
+               .tuner_type     = TUNER_PHILIPS_PAL_I,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .inputs         = {{
+                       .name   = name_tv,
+                       .vmux   = 1,
+                       .amux   = TV,
+                       .tv     = 1,
+               },{
+                       .name   = name_tv_mono,
+                       .vmux   = 1,
+                       .amux   = LINE2,
+                       .tv     = 1,
+               },{
+                       .name   = name_comp1,
+                       .vmux   = 3,
+                       .amux   = LINE1,
+               },{
+                       .name   = name_svideo,
+                       .vmux   = 8,
+                       .amux   = LINE1,
+               },{
+                       .name   = "CVid over SVid",
+                       .vmux   = 0,
+                       .amux   = LINE1,
+               }},
+               .radio = {
+                       .name   = name_radio,
+                       .amux   = LINE2,
+               },
+       },
        [SAA7134_BOARD_AVACSSMARTTV] = {
                /* Roman Pszonczenko <romka@kolos.math.uni.lodz.pl> */
                .name           = "AVACS SmartTV",
@@ -2754,6 +2790,35 @@ struct saa7134_board saa7134_boards[] = {
                        .amux   = LINE1,
                },
        },
+       [SAA7134_BOARD_KWORLD_DVBT_210] = {
+               .name           = "KWorld DVB-T 210",
+               .audio_clock    = 0x00187de7,
+               .tuner_type     = TUNER_PHILIPS_TDA8290,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .mpeg           = SAA7134_MPEG_DVB,
+               .gpiomask       = 1 << 21,
+               .inputs = {{
+                       .name   = name_tv,
+                       .vmux   = 1,
+                       .amux   = TV,
+                       .tv     = 1,
+               },{
+                       .name   = name_comp1,
+                       .vmux   = 3,
+                       .amux   = LINE1,
+               },{
+                       .name   = name_svideo,
+                       .vmux   = 8,
+                       .amux   = LINE1,
+               }},
+               .radio = {
+                       .name   = name_radio,
+                       .amux   = TV,
+                       .gpio   = 0x0200000,
+               },
+       },
        [SAA7134_BOARD_KWORLD_ATSC110] = {
                .name           = "Kworld ATSC110",
                .audio_clock    = 0x00187de7,
@@ -3407,6 +3472,36 @@ struct saa7134_board saa7134_boards[] = {
                        .gpio = 0x0200000,
                },
        },
+       [SAA7134_BOARD_SABRENT_TV_PCB05] = {
+               .name           = "Sabrent PCMCIA TV-PCB05",
+               .audio_clock    = 0x00187de7,
+               .tuner_type     = TUNER_PHILIPS_TDA8290,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .inputs         = {{
+                       .name = name_tv,
+                       .vmux = 1,
+                       .amux = TV,
+                       .tv   = 1,
+               },{
+                       .name = name_comp1,
+                       .vmux = 3,
+                       .amux = LINE1,
+               },{
+                       .name = name_comp2,
+                       .vmux = 0,
+                       .amux = LINE1,
+               },{
+                       .name = name_svideo,
+                       .vmux = 8,
+                       .amux = LINE1,
+               }},
+               .mute = {
+                       .name = name_mute,
+                       .amux = TV,
+               },
+       },
 };
 
 const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -3515,7 +3610,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
                .subvendor    = 0x5168, /* Animation Technologies (LifeView) */
-               .subdevice    = 0x0214, /* Standard PCI, LR214WF */
+               .subdevice    = 0x0214, /* Standard PCI, LR214 Rev E and earlier (SAA7135) */
+               .driver_data  = SAA7134_BOARD_FLYTVPLATINUM_FM,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+               .subvendor    = 0x5168, /* Animation Technologies (LifeView) */
+               .subdevice    = 0x5214, /* Standard PCI, LR214 Rev F onwards (SAA7131) */
                .driver_data  = SAA7134_BOARD_FLYTVPLATINUM_FM,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
@@ -3687,6 +3788,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = 0x1019,
                .subdevice    = 0x4cb5,
                .driver_data  = SAA7134_BOARD_ECS_TVP3XP_4CB5,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+               .subvendor    = 0x1019,
+               .subdevice    = 0x4cb6,
+               .driver_data  = SAA7134_BOARD_ECS_TVP3XP_4CB6,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -3913,6 +4020,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = 0x17de,
                .subdevice    = 0x7201,
                .driver_data  = SAA7134_BOARD_TEVION_DVBT_220RF,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+               .subvendor    = 0x17de,
+               .subdevice    = 0x7250,
+               .driver_data  = SAA7134_BOARD_KWORLD_DVBT_210,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
@@ -4099,6 +4212,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = 0x1043,
                .subdevice    = 0x4857,
                .driver_data  = SAA7134_BOARD_ASUSTeK_P7131_DUAL,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+               .subvendor    = 0x0919, /* SinoVideo PCI 2309 Proteus (7134) */
+               .subdevice    = 0x2003, /* OEM cardbus */
+               .driver_data  = SAA7134_BOARD_SABRENT_TV_PCB05,
        },{
                /* --- boards without eeprom + subsystem ID --- */
                .vendor       = PCI_VENDOR_ID_PHILIPS,
@@ -4178,6 +4297,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
        case SAA7134_BOARD_CINERGY600_MK3:
        case SAA7134_BOARD_ECS_TVP3XP:
        case SAA7134_BOARD_ECS_TVP3XP_4CB5:
+       case SAA7134_BOARD_ECS_TVP3XP_4CB6:
        case SAA7134_BOARD_MD2819:
        case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
        case SAA7134_BOARD_KWORLD_XPERT:
@@ -4426,6 +4546,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
                }
                break;
        case SAA7134_BOARD_PINNACLE_PCTV_310i:
+       case SAA7134_BOARD_KWORLD_DVBT_210:
        case SAA7134_BOARD_TEVION_DVBT_220RF:
        case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
        case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
index 65aec881bbde9a4e6f5dd622b3032a34963f9c15..e0eec80088c7e3060efc95f983d66530b0b709de 100644 (file)
@@ -887,6 +887,20 @@ static struct tda1004x_config asus_p7131_hybrid_lna_config = {
        .antenna_switch= 2,
        .request_firmware = philips_tda1004x_request_firmware
 };
+static struct tda1004x_config kworld_dvb_t_210_config = {
+       .demod_address = 0x08,
+       .invert        = 1,
+       .invert_oclk   = 0,
+       .xtal_freq     = TDA10046_XTAL_16M,
+       .agc_config    = TDA10046_AGC_TDA827X,
+       .gpio_config   = TDA10046_GP11_I,
+       .if_freq       = TDA10046_FREQ_045,
+       .i2c_gate      = 0x4b,
+       .tuner_address = 0x61,
+       .tuner_config  = 2,
+       .antenna_switch= 1,
+       .request_firmware = philips_tda1004x_request_firmware
+};
 /* ------------------------------------------------------------------
  * special case: this card uses saa713x GPIO22 for the mode switch
  */
@@ -1039,6 +1053,9 @@ static int dvb_init(struct saa7134_dev *dev)
                        dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
                }
                break;
+       case SAA7134_BOARD_KWORLD_DVBT_210:
+               configure_tda827x_fe(dev, &kworld_dvb_t_210_config);
+               break;
        case SAA7134_BOARD_PHILIPS_TIGER:
                configure_tda827x_fe(dev, &philips_tiger_config);
                break;
index 62224cc958f1077c5efe6fe491308d7acfd18933..15623b27ad2e0f92ff16434e70a1050c81648c0d 100644 (file)
@@ -235,6 +235,9 @@ struct saa7134_format {
 #define SAA7134_BOARD_AVERMEDIA_M102      110
 #define SAA7134_BOARD_ASUS_P7131_4871     111
 #define SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA 112
+#define SAA7134_BOARD_ECS_TVP3XP_4CB6  113
+#define SAA7134_BOARD_KWORLD_DVBT_210 114
+#define SAA7134_BOARD_SABRENT_TV_PCB05     115
 
 #define SAA7134_MAXBOARDS 8
 #define SAA7134_INPUT_MAX 8
index 19204f5686e16759991a9bb77eb528f6de136c3e..f71f272776dedca9d945ad7b6d4fe760d53767bc 100644 (file)
@@ -1,6 +1,6 @@
 config USB_SN9C102
        tristate "USB SN9C1xx PC Camera Controller support"
-       depends on USB && VIDEO_V4L2
+       depends on VIDEO_V4L2
        ---help---
          Say Y here if you want support for cameras based on SONiX SN9C101,
          SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers.
index 680e74634527ce345ecdb6759cf218b211c17db1..11fcb49f5b99180b34de68f522f1090ca96fa07a 100644 (file)
@@ -141,7 +141,7 @@ sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id)
 
 void
 sn9c102_attach_sensor(struct sn9c102_device* cam,
-                     struct sn9c102_sensor* sensor)
+                     const struct sn9c102_sensor* sensor)
 {
        memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor));
 }
index 89f83354de3be0cbd094fc282fd98cd007244bdd..74a204f8ebc870c254f7b0a850bf9ab5699ede9d 100644 (file)
@@ -48,8 +48,8 @@
 #define SN9C102_MODULE_AUTHOR   "(C) 2004-2007 Luca Risolia"
 #define SN9C102_AUTHOR_EMAIL    "<luca.risolia@studio.unibo.it>"
 #define SN9C102_MODULE_LICENSE  "GPL"
-#define SN9C102_MODULE_VERSION  "1:1.39"
-#define SN9C102_MODULE_VERSION_CODE  KERNEL_VERSION(1, 1, 39)
+#define SN9C102_MODULE_VERSION  "1:1.44"
+#define SN9C102_MODULE_VERSION_CODE  KERNEL_VERSION(1, 1, 44)
 
 /*****************************************************************************/
 
@@ -209,38 +209,41 @@ static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
 }
 
 /*****************************************************************************/
+
 /*
- * Write a sequence of count value/register pairs.  Returns -1 after the
* first failed write, or 0 for no errors.
- */
+   Write a sequence of count value/register pairs. Returns -1 after the first
  failed write, or 0 for no errors.
+*/
 int sn9c102_write_regs(struct sn9c102_device* cam, const u8 valreg[][2],
                       int count)
 {
        struct usb_device* udev = cam->usbdev;
-       u8* value = cam->control_buffer;  /* Needed for DMA'able memory */
+       u8* buff = cam->control_buffer;
        int i, res;
 
        for (i = 0; i < count; i++) {
                u8 index = valreg[i][1];
 
                /*
-                * index is a u8, so it must be <256 and can't be out of range.
-                * If we put in a check anyway, gcc annoys us with a warning
-                * that our check is useless.  People get all uppity when they
-                * see warnings in the kernel compile.
-                */
-
-               *value = valreg[i][0];
-               res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-                                     0x08, 0x41, index, 0,
-                                     value, 1, SN9C102_CTRL_TIMEOUT);
+                  index is a u8, so it must be <256 and can't be out of range.
+                  If we put in a check anyway, gcc annoys us with a warning
+                  hat our check is useless. People get all uppity when they
+                  see warnings in the kernel compile.
+               */
+
+               *buff = valreg[i][0];
+
+               res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08,
+                                     0x41, index, 0, buff, 1,
+                                     SN9C102_CTRL_TIMEOUT);
+
                if (res < 0) {
                        DBG(3, "Failed to write a register (value 0x%02X, "
-                              "index 0x%02X, error %d)", *value, index, res);
+                              "index 0x%02X, error %d)", *buff, index, res);
                        return -1;
                }
 
-               cam->reg[index] = *value;
+               cam->reg[index] = *buff;
        }
 
        return 0;
@@ -272,8 +275,8 @@ int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index)
 }
 
 
-/* NOTE: reading some registers always returns 0 */
-static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
+/* NOTE: with the SN9C10[123] reading some registers always returns 0 */
+int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
 {
        struct usb_device* udev = cam->usbdev;
        u8* buff = cam->control_buffer;
@@ -299,7 +302,8 @@ int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index)
 
 
 static int
-sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor)
+sn9c102_i2c_wait(struct sn9c102_device* cam,
+                const struct sn9c102_sensor* sensor)
 {
        int i, r;
 
@@ -320,7 +324,7 @@ sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor)
 
 static int
 sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
-                             struct sn9c102_sensor* sensor)
+                             const struct sn9c102_sensor* sensor)
 {
        int r , err = 0;
 
@@ -342,7 +346,7 @@ sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
 
 static int
 sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
-                              struct sn9c102_sensor* sensor)
+                              const struct sn9c102_sensor* sensor)
 {
        int r;
        r = sn9c102_read_reg(cam, 0x08);
@@ -352,12 +356,12 @@ sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
 
 int
 sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
-                        struct sn9c102_sensor* sensor, u8 data0, u8 data1,
-                        u8 n, u8 buffer[])
+                        const struct sn9c102_sensor* sensor, u8 data0,
+                        u8 data1, u8 n, u8 buffer[])
 {
        struct usb_device* udev = cam->usbdev;
        u8* data = cam->control_buffer;
-       int err = 0, res;
+       int i = 0, err = 0, res;
 
        /* Write cycle */
        data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
@@ -402,7 +406,8 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
        }
 
        if (buffer)
-               memcpy(buffer, data, sizeof(buffer));
+               for (i = 0; i < n && i < 5; i++)
+                       buffer[n-i-1] = data[4-i];
 
        return (int)data[4];
 }
@@ -410,7 +415,7 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
 
 int
 sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
-                         struct sn9c102_sensor* sensor, u8 n, u8 data0,
+                         const struct sn9c102_sensor* sensor, u8 n, u8 data0,
                          u8 data1, u8 data2, u8 data3, u8 data4, u8 data5)
 {
        struct usb_device* udev = cam->usbdev;
@@ -449,7 +454,7 @@ sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
 
 int
 sn9c102_i2c_try_read(struct sn9c102_device* cam,
-                    struct sn9c102_sensor* sensor, u8 address)
+                    const struct sn9c102_sensor* sensor, u8 address)
 {
        return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id,
                                        address, 1, NULL);
@@ -458,7 +463,7 @@ sn9c102_i2c_try_read(struct sn9c102_device* cam,
 
 int
 sn9c102_i2c_try_write(struct sn9c102_device* cam,
-                     struct sn9c102_sensor* sensor, u8 address, u8 value)
+                     const struct sn9c102_sensor* sensor, u8 address, u8 value)
 {
        return sn9c102_i2c_try_raw_write(cam, sensor, 3,
                                         sensor->i2c_slave_id, address,
@@ -657,16 +662,6 @@ sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
 }
 
 
-static void
-sn9c102_write_eoimarker(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
-{
-       static const u8 eoi_marker[2] = {0xff, 0xd9};
-
-       memcpy(f->bufmem + f->buf.bytesused, eoi_marker, sizeof(eoi_marker));
-       f->buf.bytesused += sizeof(eoi_marker);
-}
-
-
 static void sn9c102_urb_complete(struct urb *urb)
 {
        struct sn9c102_device* cam = urb->context;
@@ -3181,14 +3176,14 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp,
 
 static const struct file_operations sn9c102_fops = {
        .owner = THIS_MODULE,
-       .open =    sn9c102_open,
+       .open = sn9c102_open,
        .release = sn9c102_release,
-       .ioctl =   sn9c102_ioctl,
+       .ioctl = sn9c102_ioctl,
        .compat_ioctl = v4l_compat_ioctl32,
-       .read =    sn9c102_read,
-       .poll =    sn9c102_poll,
-       .mmap =    sn9c102_mmap,
-       .llseek =  no_llseek,
+       .read = sn9c102_read,
+       .poll = sn9c102_poll,
+       .mmap = sn9c102_mmap,
+       .llseek = no_llseek,
 };
 
 /*****************************************************************************/
@@ -3251,7 +3246,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
                break;
        }
 
-       for  (i = 0; sn9c102_sensor_table[i]; i++) {
+       for  (i = 0; i < ARRAY_SIZE(sn9c102_sensor_table); i++) {
                err = sn9c102_sensor_table[i](cam);
                if (!err)
                        break;
@@ -3262,7 +3257,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
                DBG(3, "Support for %s maintained by %s",
                    cam->sensor.name, cam->sensor.maintainer);
        } else {
-               DBG(1, "No supported image sensor detected");
+               DBG(1, "No supported image sensor detected for this bridge");
                err = -ENODEV;
                goto fail;
        }
index f49bd8c5b86ec8e78b176e27766e8d8c1a7f2d03..916054faf9be46d62e083a4ffb670c40d32b582c 100644 (file)
@@ -86,6 +86,8 @@ static const struct usb_device_id sn9c102_id_table[] = {
        { SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), },
        { SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), },
        /* SN9C105 */
+       { SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), },
+       { SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), },
        { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
        { SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
        { SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
@@ -100,6 +102,7 @@ static const struct usb_device_id sn9c102_id_table[] = {
        { SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), },
        { SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), },
        /* SN9C120 */
+       { SN9C102_USB_DEVICE(0x0458, 0x7025, BRIDGE_SN9C120), },
        { SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), },
        { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), },
        { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), },
@@ -148,7 +151,6 @@ static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = {
        &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */
        &sn9c102_probe_tas5110d, /* detection based on USB pid/vid */
        &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */
-       NULL,
 };
 
 #endif /* _SN9C102_DEVTABLE_H_ */
index 28a861aed044a2eb9ad5a3871b22c501b6eafb0b..eaf9ad0dc8a65596a8b5836a161a4d334d34fa87 100644 (file)
@@ -144,7 +144,7 @@ static int hv7131d_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor hv7131d = {
+static const struct sn9c102_sensor hv7131d = {
        .name = "HV7131D",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
@@ -248,12 +248,10 @@ int sn9c102_probe_hv7131d(struct sn9c102_device* cam)
 
        err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
                                       {0x28, 0x17});
-       if (err)
-               return -EIO;
 
        r0 = sn9c102_i2c_try_read(cam, &hv7131d, 0x00);
        r1 = sn9c102_i2c_try_read(cam, &hv7131d, 0x01);
-       if (r0 < 0 || r1 < 0)
+       if (err || r0 < 0 || r1 < 0)
                return -EIO;
 
        if (r0 != 0x00 || r1 != 0x04)
index 5a495baa5f95d6e35c340ba6506546f7fc00b7dd..0fc401223cfc9c08741fa3595b93cadf7811f5b3 100644 (file)
@@ -44,7 +44,6 @@ static int hv7131r_init(struct sn9c102_device* cam)
                                               {0xb0, 0x2b}, {0xc0, 0x2c},
                                               {0xd0, 0x2d}, {0xe0, 0x2e},
                                               {0xf0, 0x2f}, {0xff, 0x30});
-
                break;
        case BRIDGE_SN9C105:
        case BRIDGE_SN9C120:
@@ -254,7 +253,7 @@ static int hv7131r_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor hv7131r = {
+static const struct sn9c102_sensor hv7131r = {
        .name = "HV7131R",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
@@ -350,11 +349,8 @@ int sn9c102_probe_hv7131r(struct sn9c102_device* cam)
                                       {0x34, 0x01}, {0x20, 0x17},
                                       {0x34, 0x01}, {0x46, 0x01});
 
-       if (err)
-               return -EIO;
-
        devid = sn9c102_i2c_try_read(cam, &hv7131r, 0x00);
-       if (devid < 0)
+       if (err || devid < 0)
                return -EIO;
 
        if (devid != 0x02)
index 9200845d011be5fae0f69eaf722c05dc6b326ea8..00b134ca0a3d56ac0d122bc15040c9f38cb99633 100644 (file)
@@ -55,45 +55,45 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam,
                           struct v4l2_control* ctrl)
 {
        struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
-       u8 data[5+1];
+       u8 data[2];
 
        switch (ctrl->id) {
        case V4L2_CID_EXPOSURE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[2];
+               ctrl->value = data[0];
                return 0;
        case V4L2_CID_GAIN:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
+                                            data) < 0)
                        return -EIO;
                break;
        case V4L2_CID_HFLIP:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3] & 0x20 ? 1 : 0;
+               ctrl->value = data[1] & 0x20 ? 1 : 0;
                return 0;
        case V4L2_CID_VFLIP:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3] & 0x80 ? 1 : 0;
+               ctrl->value = data[1] & 0x80 ? 1 : 0;
                return 0;
        case V4L2_CID_RED_BALANCE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
+                                            data) < 0)
                        return -EIO;
                break;
        case V4L2_CID_BLUE_BALANCE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
+                                            data) < 0)
                        return -EIO;
                break;
        case SN9C102_V4L2_CID_GREEN_BALANCE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
+                                            data) < 0)
                        return -EIO;
                break;
        default:
@@ -105,7 +105,7 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam,
        case V4L2_CID_RED_BALANCE:
        case V4L2_CID_BLUE_BALANCE:
        case SN9C102_V4L2_CID_GREEN_BALANCE:
-               ctrl->value = data[3] | (data[2] << 8);
+               ctrl->value = data[1] | (data[0] << 8);
                if (ctrl->value >= 0x10 && ctrl->value <= 0x3f)
                        ctrl->value -= 0x10;
                else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f)
@@ -223,7 +223,7 @@ static int mi0343_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor mi0343 = {
+static const struct sn9c102_sensor mi0343 = {
        .name = "MI-0343",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
@@ -332,20 +332,17 @@ static struct sn9c102_sensor mi0343 = {
 
 int sn9c102_probe_mi0343(struct sn9c102_device* cam)
 {
-       u8 data[5+1];
-       int err = 0;
-
-       err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
-                                      {0x28, 0x17});
+       u8 data[2];
 
-       if (err)
+       if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+                                    {0x28, 0x17}))
                return -EIO;
 
        if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00,
                                     2, data) < 0)
                return -EIO;
 
-       if (data[4] != 0x32 || data[3] != 0xe3)
+       if (data[1] != 0x42 || data[0] != 0xe3)
                return -ENODEV;
 
        sn9c102_attach_sensor(cam, &mi0343);
index 64698acb0b15cd57feaa43a96bbfb6466b0729d9..f8d81d82e8d50e537ea85004b897e086aa1e4a97 100644 (file)
@@ -27,20 +27,105 @@ static int mi0360_init(struct sn9c102_device* cam)
        struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
        int err = 0;
 
-       err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
-                                      {0x0a, 0x14}, {0x40, 0x01},
-                                      {0x20, 0x17}, {0x07, 0x18},
-                                      {0xa0, 0x19}, {0x02, 0x1c},
-                                      {0x03, 0x1d}, {0x0f, 0x1e},
-                                      {0x0c, 0x1f}, {0x00, 0x20},
-                                      {0x10, 0x21}, {0x20, 0x22},
-                                      {0x30, 0x23}, {0x40, 0x24},
-                                      {0x50, 0x25}, {0x60, 0x26},
-                                      {0x70, 0x27}, {0x80, 0x28},
-                                      {0x90, 0x29}, {0xa0, 0x2a},
-                                      {0xb0, 0x2b}, {0xc0, 0x2c},
-                                      {0xd0, 0x2d}, {0xe0, 0x2e},
-                                      {0xf0, 0x2f}, {0xff, 0x30});
+       switch (sn9c102_get_bridge(cam)) {
+       case BRIDGE_SN9C103:
+               err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+                                              {0x0a, 0x14}, {0x40, 0x01},
+                                              {0x20, 0x17}, {0x07, 0x18},
+                                              {0xa0, 0x19}, {0x02, 0x1c},
+                                              {0x03, 0x1d}, {0x0f, 0x1e},
+                                              {0x0c, 0x1f}, {0x00, 0x20},
+                                              {0x10, 0x21}, {0x20, 0x22},
+                                              {0x30, 0x23}, {0x40, 0x24},
+                                              {0x50, 0x25}, {0x60, 0x26},
+                                              {0x70, 0x27}, {0x80, 0x28},
+                                              {0x90, 0x29}, {0xa0, 0x2a},
+                                              {0xb0, 0x2b}, {0xc0, 0x2c},
+                                              {0xd0, 0x2d}, {0xe0, 0x2e},
+                                              {0xf0, 0x2f}, {0xff, 0x30});
+               break;
+       case BRIDGE_SN9C105:
+       case BRIDGE_SN9C120:
+               err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
+                                              {0x00, 0x03}, {0x1a, 0x04},
+                                              {0x50, 0x05}, {0x20, 0x06},
+                                              {0x10, 0x07}, {0x03, 0x10},
+                                              {0x08, 0x14}, {0xa2, 0x17},
+                                              {0x47, 0x18}, {0x00, 0x19},
+                                              {0x1d, 0x1a}, {0x10, 0x1b},
+                                              {0x02, 0x1c}, {0x03, 0x1d},
+                                              {0x0f, 0x1e}, {0x0c, 0x1f},
+                                              {0x00, 0x20}, {0x29, 0x21},
+                                              {0x40, 0x22}, {0x54, 0x23},
+                                              {0x66, 0x24}, {0x76, 0x25},
+                                              {0x85, 0x26}, {0x94, 0x27},
+                                              {0xa1, 0x28}, {0xae, 0x29},
+                                              {0xbb, 0x2a}, {0xc7, 0x2b},
+                                              {0xd3, 0x2c}, {0xde, 0x2d},
+                                              {0xea, 0x2e}, {0xf4, 0x2f},
+                                              {0xff, 0x30}, {0x00, 0x3F},
+                                              {0xC7, 0x40}, {0x01, 0x41},
+                                              {0x44, 0x42}, {0x00, 0x43},
+                                              {0x44, 0x44}, {0x00, 0x45},
+                                              {0x44, 0x46}, {0x00, 0x47},
+                                              {0xC7, 0x48}, {0x01, 0x49},
+                                              {0xC7, 0x4A}, {0x01, 0x4B},
+                                              {0xC7, 0x4C}, {0x01, 0x4D},
+                                              {0x44, 0x4E}, {0x00, 0x4F},
+                                              {0x44, 0x50}, {0x00, 0x51},
+                                              {0x44, 0x52}, {0x00, 0x53},
+                                              {0xC7, 0x54}, {0x01, 0x55},
+                                              {0xC7, 0x56}, {0x01, 0x57},
+                                              {0xC7, 0x58}, {0x01, 0x59},
+                                              {0x44, 0x5A}, {0x00, 0x5B},
+                                              {0x44, 0x5C}, {0x00, 0x5D},
+                                              {0x44, 0x5E}, {0x00, 0x5F},
+                                              {0xC7, 0x60}, {0x01, 0x61},
+                                              {0xC7, 0x62}, {0x01, 0x63},
+                                              {0xC7, 0x64}, {0x01, 0x65},
+                                              {0x44, 0x66}, {0x00, 0x67},
+                                              {0x44, 0x68}, {0x00, 0x69},
+                                              {0x44, 0x6A}, {0x00, 0x6B},
+                                              {0xC7, 0x6C}, {0x01, 0x6D},
+                                              {0xC7, 0x6E}, {0x01, 0x6F},
+                                              {0xC7, 0x70}, {0x01, 0x71},
+                                              {0x44, 0x72}, {0x00, 0x73},
+                                              {0x44, 0x74}, {0x00, 0x75},
+                                              {0x44, 0x76}, {0x00, 0x77},
+                                              {0xC7, 0x78}, {0x01, 0x79},
+                                              {0xC7, 0x7A}, {0x01, 0x7B},
+                                              {0xC7, 0x7C}, {0x01, 0x7D},
+                                              {0x44, 0x7E}, {0x00, 0x7F},
+                                              {0x14, 0x84}, {0x00, 0x85},
+                                              {0x27, 0x86}, {0x00, 0x87},
+                                              {0x07, 0x88}, {0x00, 0x89},
+                                              {0xEC, 0x8A}, {0x0f, 0x8B},
+                                              {0xD8, 0x8C}, {0x0f, 0x8D},
+                                              {0x3D, 0x8E}, {0x00, 0x8F},
+                                              {0x3D, 0x90}, {0x00, 0x91},
+                                              {0xCD, 0x92}, {0x0f, 0x93},
+                                              {0xf7, 0x94}, {0x0f, 0x95},
+                                              {0x0C, 0x96}, {0x00, 0x97},
+                                              {0x00, 0x98}, {0x66, 0x99},
+                                              {0x05, 0x9A}, {0x00, 0x9B},
+                                              {0x04, 0x9C}, {0x00, 0x9D},
+                                              {0x08, 0x9E}, {0x00, 0x9F},
+                                              {0x2D, 0xC0}, {0x2D, 0xC1},
+                                              {0x3A, 0xC2}, {0x05, 0xC3},
+                                              {0x04, 0xC4}, {0x3F, 0xC5},
+                                              {0x00, 0xC6}, {0x00, 0xC7},
+                                              {0x50, 0xC8}, {0x3C, 0xC9},
+                                              {0x28, 0xCA}, {0xD8, 0xCB},
+                                              {0x14, 0xCC}, {0xEC, 0xCD},
+                                              {0x32, 0xCE}, {0xDD, 0xCF},
+                                              {0x32, 0xD0}, {0xDD, 0xD1},
+                                              {0x6A, 0xD2}, {0x50, 0xD3},
+                                              {0x00, 0xD4}, {0x00, 0xD5},
+                                              {0x00, 0xD6});
+               break;
+       default:
+               break;
+       }
 
        err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
                                         0x00, 0x01, 0, 0);
@@ -65,50 +150,50 @@ static int mi0360_get_ctrl(struct sn9c102_device* cam,
                           struct v4l2_control* ctrl)
 {
        struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
-       u8 data[5+1];
+       u8 data[2];
 
        switch (ctrl->id) {
        case V4L2_CID_EXPOSURE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[2];
+               ctrl->value = data[0];
                return 0;
        case V4L2_CID_GAIN:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3];
+               ctrl->value = data[1];
                return 0;
        case V4L2_CID_RED_BALANCE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3];
+               ctrl->value = data[1];
                return 0;
        case V4L2_CID_BLUE_BALANCE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3];
+               ctrl->value = data[1];
                return 0;
        case SN9C102_V4L2_CID_GREEN_BALANCE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3];
+               ctrl->value = data[1];
                return 0;
        case V4L2_CID_HFLIP:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3] & 0x20 ? 1 : 0;
+               ctrl->value = data[1] & 0x20 ? 1 : 0;
                return 0;
        case V4L2_CID_VFLIP:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3] & 0x80 ? 1 : 0;
+               ctrl->value = data[1] & 0x80 ? 1 : 0;
                return 0;
        default:
                return -EINVAL;
@@ -178,8 +263,19 @@ static int mi0360_set_crop(struct sn9c102_device* cam,
 {
        struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
        int err = 0;
-       u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0,
-          v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
+       u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
+
+       switch (sn9c102_get_bridge(cam)) {
+       case BRIDGE_SN9C103:
+               h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0;
+               break;
+       case BRIDGE_SN9C105:
+       case BRIDGE_SN9C120:
+               h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1;
+               break;
+       default:
+               break;
+       }
 
        err += sn9c102_write_reg(cam, h_start, 0x12);
        err += sn9c102_write_reg(cam, v_start, 0x13);
@@ -194,24 +290,30 @@ static int mi0360_set_pix_format(struct sn9c102_device* cam,
        struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
        int err = 0;
 
-       if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) {
-               err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
-                                                0x0a, 0x00, 0x02, 0, 0);
-               err += sn9c102_write_reg(cam, 0x20, 0x19);
-       } else {
+       if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
                err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
                                                 0x0a, 0x00, 0x05, 0, 0);
                err += sn9c102_write_reg(cam, 0x60, 0x19);
+               if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
+                   sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
+                       err += sn9c102_write_reg(cam, 0xa6, 0x17);
+       } else {
+               err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+                                                0x0a, 0x00, 0x02, 0, 0);
+               err += sn9c102_write_reg(cam, 0x20, 0x19);
+               if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
+                   sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
+                       err += sn9c102_write_reg(cam, 0xa2, 0x17);
        }
 
        return err;
 }
 
 
-static struct sn9c102_sensor mi0360 = {
+static const struct sn9c102_sensor mi0360 = {
        .name = "MI-0360",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
-       .supported_bridge = BRIDGE_SN9C103,
+       .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
        .frequency = SN9C102_I2C_100KHZ,
        .interface = SN9C102_I2C_2WIRES,
        .i2c_slave_id = 0x5d,
@@ -317,19 +419,31 @@ static struct sn9c102_sensor mi0360 = {
 
 int sn9c102_probe_mi0360(struct sn9c102_device* cam)
 {
-       u8 data[5+1];
-       int err;
 
-       err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
-                                      {0x28, 0x17});
-       if (err)
-               return -EIO;
+       u8 data[2];
+
+       switch (sn9c102_get_bridge(cam)) {
+       case BRIDGE_SN9C103:
+               if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+                                            {0x28, 0x17}))
+                       return -EIO;
+               break;
+       case BRIDGE_SN9C105:
+       case BRIDGE_SN9C120:
+               if (sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
+                                            {0x01, 0x01}, {0x00, 0x01},
+                                            {0x28, 0x17}))
+                       return -EIO;
+               break;
+       default:
+               break;
+       }
 
        if (sn9c102_i2c_try_raw_read(cam, &mi0360, mi0360.i2c_slave_id, 0x00,
-                                    2+1, data) < 0)
+                                    2, data) < 0)
                return -EIO;
 
-       if (data[2] != 0x82 || data[3] != 0x43)
+       if (data[0] != 0x82 || data[1] != 0x43)
                return -ENODEV;
 
        sn9c102_attach_sensor(cam, &mi0360);
index 31b6080b0615accb67dd25ca077072df5d6543f3..e6832347894fb273c622dc7abdc1e228a4f270cd 100644 (file)
@@ -29,9 +29,8 @@ static int ov7630_init(struct sn9c102_device* cam)
        switch (sn9c102_get_bridge(cam)) {
        case BRIDGE_SN9C101:
        case BRIDGE_SN9C102:
-               err = sn9c102_write_const_regs(cam, {0x00, 0x14},
-                                              {0x60, 0x17}, {0x0f, 0x18},
-                                              {0x50, 0x19});
+               err = sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17},
+                                              {0x0f, 0x18}, {0x50, 0x19});
 
                err += sn9c102_i2c_write(cam, 0x12, 0x8d);
                err += sn9c102_i2c_write(cam, 0x12, 0x0d);
@@ -61,7 +60,6 @@ static int ov7630_init(struct sn9c102_device* cam)
                err += sn9c102_i2c_write(cam, 0x71, 0x00);
                err += sn9c102_i2c_write(cam, 0x74, 0x21);
                err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
-
                break;
        case BRIDGE_SN9C103:
                err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
@@ -253,7 +251,7 @@ static int ov7630_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor ov7630 = {
+static const struct sn9c102_sensor ov7630 = {
        .name = "OV7630",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
@@ -408,19 +406,16 @@ int sn9c102_probe_ov7630(struct sn9c102_device* cam)
        switch (sn9c102_get_bridge(cam)) {
        case BRIDGE_SN9C101:
        case BRIDGE_SN9C102:
-               err = sn9c102_write_const_regs(cam, {0x01, 0x01},
-                                              {0x00, 0x01}, {0x28, 0x17});
-
+               err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+                                              {0x28, 0x17});
                break;
        case BRIDGE_SN9C103: /* do _not_ change anything! */
-               err = sn9c102_write_const_regs(cam, {0x09, 0x01},
-                                              {0x42, 0x01}, {0x28, 0x17},
-                                              {0x44, 0x02});
+               err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x42, 0x01},
+                                              {0x28, 0x17}, {0x44, 0x02});
                pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a);
-               if (err || pid < 0) { /* try a different initialization */
-                       err = sn9c102_write_reg(cam, 0x01, 0x01);
-                       err += sn9c102_write_reg(cam, 0x00, 0x01);
-               }
+               if (err || pid < 0) /* try a different initialization */
+                       err += sn9c102_write_const_regs(cam, {0x01, 0x01},
+                                                       {0x00, 0x01});
                break;
        default:
                break;
index c898e948fe8d07ed70212b426d101094d6cb0fee..4b6474048a72976a66638f8896edc36dc5aa79e0 100644 (file)
@@ -104,8 +104,8 @@ static int ov7660_init(struct sn9c102_device* cam)
        err += sn9c102_i2c_write(cam, 0x12, 0x80);
        err += sn9c102_i2c_write(cam, 0x11, 0x09);
        err += sn9c102_i2c_write(cam, 0x00, 0x0A);
-       err += sn9c102_i2c_write(cam, 0x01, 0x78);
-       err += sn9c102_i2c_write(cam, 0x02, 0x90);
+       err += sn9c102_i2c_write(cam, 0x01, 0x80);
+       err += sn9c102_i2c_write(cam, 0x02, 0x80);
        err += sn9c102_i2c_write(cam, 0x03, 0x00);
        err += sn9c102_i2c_write(cam, 0x04, 0x00);
        err += sn9c102_i2c_write(cam, 0x05, 0x08);
@@ -122,7 +122,7 @@ static int ov7660_init(struct sn9c102_device* cam)
        err += sn9c102_i2c_write(cam, 0x10, 0x20);
        err += sn9c102_i2c_write(cam, 0x11, 0x03);
        err += sn9c102_i2c_write(cam, 0x12, 0x05);
-       err += sn9c102_i2c_write(cam, 0x13, 0xF8);
+       err += sn9c102_i2c_write(cam, 0x13, 0xC7);
        err += sn9c102_i2c_write(cam, 0x14, 0x2C);
        err += sn9c102_i2c_write(cam, 0x15, 0x00);
        err += sn9c102_i2c_write(cam, 0x16, 0x02);
@@ -162,7 +162,7 @@ static int ov7660_init(struct sn9c102_device* cam)
        err += sn9c102_i2c_write(cam, 0x38, 0x02);
        err += sn9c102_i2c_write(cam, 0x39, 0x43);
        err += sn9c102_i2c_write(cam, 0x3A, 0x00);
-       err += sn9c102_i2c_write(cam, 0x3B, 0x02);
+       err += sn9c102_i2c_write(cam, 0x3B, 0x0A);
        err += sn9c102_i2c_write(cam, 0x3C, 0x6C);
        err += sn9c102_i2c_write(cam, 0x3D, 0x99);
        err += sn9c102_i2c_write(cam, 0x3E, 0x0E);
@@ -281,25 +281,34 @@ static int ov7660_get_ctrl(struct sn9c102_device* cam,
                        return -EIO;
                break;
        case V4L2_CID_DO_WHITE_BALANCE:
-               ctrl->value = sn9c102_pread_reg(cam, 0x02);
+               if ((ctrl->value = sn9c102_read_reg(cam, 0x02)) < 0)
+                       return -EIO;
                ctrl->value = (ctrl->value & 0x04) ? 1 : 0;
                break;
        case V4L2_CID_RED_BALANCE:
-               ctrl->value = sn9c102_pread_reg(cam, 0x05);
+               if ((ctrl->value = sn9c102_read_reg(cam, 0x05)) < 0)
+                       return -EIO;
                ctrl->value &= 0x7f;
                break;
        case V4L2_CID_BLUE_BALANCE:
-               ctrl->value = sn9c102_pread_reg(cam, 0x06);
+               if ((ctrl->value = sn9c102_read_reg(cam, 0x06)) < 0)
+                       return -EIO;
                ctrl->value &= 0x7f;
                break;
        case SN9C102_V4L2_CID_GREEN_BALANCE:
-               ctrl->value = sn9c102_pread_reg(cam, 0x07);
+               if ((ctrl->value = sn9c102_read_reg(cam, 0x07)) < 0)
+                       return -EIO;
                ctrl->value &= 0x7f;
                break;
+       case SN9C102_V4L2_CID_BAND_FILTER:
+               if ((ctrl->value = sn9c102_i2c_read(cam, 0x3b)) < 0)
+                       return -EIO;
+               ctrl->value &= 0x08;
+               break;
        case V4L2_CID_GAIN:
                if ((ctrl->value = sn9c102_i2c_read(cam, 0x00)) < 0)
                        return -EIO;
-               ctrl->value &= 0x7f;
+               ctrl->value &= 0x1f;
                break;
        case V4L2_CID_AUTOGAIN:
                if ((ctrl->value = sn9c102_i2c_read(cam, 0x13)) < 0)
@@ -335,12 +344,15 @@ static int ov7660_set_ctrl(struct sn9c102_device* cam,
        case SN9C102_V4L2_CID_GREEN_BALANCE:
                err += sn9c102_write_reg(cam, ctrl->value, 0x07);
                break;
+       case SN9C102_V4L2_CID_BAND_FILTER:
+               err += sn9c102_i2c_write(cam, ctrl->value << 3, 0x3b);
+               break;
        case V4L2_CID_GAIN:
-               err += sn9c102_i2c_write(cam, 0x00, ctrl->value);
+               err += sn9c102_i2c_write(cam, 0x00, 0x60 + ctrl->value);
                break;
        case V4L2_CID_AUTOGAIN:
-               err += sn9c102_i2c_write(cam, 0x13, 0xf0 | ctrl->value |
-                                                   (ctrl->value << 1));
+               err += sn9c102_i2c_write(cam, 0x13, 0xc0 |
+                                                   (ctrl->value * 0x07));
                break;
        default:
                return -EINVAL;
@@ -386,7 +398,7 @@ static int ov7660_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor ov7660 = {
+static const struct sn9c102_sensor ov7660 = {
        .name = "OV7660",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C105 | BRIDGE_SN9C120,
@@ -401,9 +413,9 @@ static struct sn9c102_sensor ov7660 = {
                        .type = V4L2_CTRL_TYPE_INTEGER,
                        .name = "global gain",
                        .minimum = 0x00,
-                       .maximum = 0x7f,
+                       .maximum = 0x1f,
                        .step = 0x01,
-                       .default_value = 0x0a,
+                       .default_value = 0x09,
                        .flags = 0,
                },
                {
@@ -413,7 +425,7 @@ static struct sn9c102_sensor ov7660 = {
                        .minimum = 0x00,
                        .maximum = 0xff,
                        .step = 0x01,
-                       .default_value = 0x50,
+                       .default_value = 0x27,
                        .flags = 0,
                },
                {
@@ -433,7 +445,7 @@ static struct sn9c102_sensor ov7660 = {
                        .minimum = 0x00,
                        .maximum = 0x7f,
                        .step = 0x01,
-                       .default_value = 0x1f,
+                       .default_value = 0x14,
                        .flags = 0,
                },
                {
@@ -443,7 +455,7 @@ static struct sn9c102_sensor ov7660 = {
                        .minimum = 0x00,
                        .maximum = 0x7f,
                        .step = 0x01,
-                       .default_value = 0x1e,
+                       .default_value = 0x14,
                        .flags = 0,
                },
                {
@@ -453,7 +465,7 @@ static struct sn9c102_sensor ov7660 = {
                        .minimum = 0x00,
                        .maximum = 0x01,
                        .step = 0x01,
-                       .default_value = 0x00,
+                       .default_value = 0x01,
                        .flags = 0,
                },
                {
@@ -463,7 +475,17 @@ static struct sn9c102_sensor ov7660 = {
                        .minimum = 0x00,
                        .maximum = 0x7f,
                        .step = 0x01,
-                       .default_value = 0x20,
+                       .default_value = 0x14,
+                       .flags = 0,
+               },
+               {
+                       .id = SN9C102_V4L2_CID_BAND_FILTER,
+                       .type = V4L2_CTRL_TYPE_BOOLEAN,
+                       .name = "band filter",
+                       .minimum = 0x00,
+                       .maximum = 0x01,
+                       .step = 0x01,
+                       .default_value = 0x00,
                        .flags = 0,
                },
        },
@@ -508,6 +530,7 @@ int sn9c102_probe_ov7660(struct sn9c102_device* cam)
                return -EIO;
        if (pid != 0x76 || ver != 0x60)
                return -ENODEV;
+
        sn9c102_attach_sensor(cam, &ov7660);
 
        return 0;
index 67151964801fa6c59df309c8193aef86961908fe..360f2a848bc018212b8b8a3052f91d5787400cfe 100644 (file)
@@ -163,7 +163,7 @@ static int pas106b_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor pas106b = {
+static const struct sn9c102_sensor pas106b = {
        .name = "PAS106B",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
@@ -273,23 +273,21 @@ static struct sn9c102_sensor pas106b = {
 
 int sn9c102_probe_pas106b(struct sn9c102_device* cam)
 {
-       int r0 = 0, r1 = 0, err;
+       int r0 = 0, r1 = 0;
        unsigned int pid = 0;
 
        /*
           Minimal initialization to enable the I2C communication
           NOTE: do NOT change the values!
        */
-       err = sn9c102_write_const_regs(cam,
-                                      {0x01, 0x01}, /* sensor power down */
-                                      {0x00, 0x01}, /* sensor power on */
-                                      {0x28, 0x17});/* sensor clock 24 MHz */
-       if (err)
+       if (sn9c102_write_const_regs(cam,
+                                    {0x01, 0x01}, /* sensor power down */
+                                    {0x00, 0x01}, /* sensor power on */
+                                   {0x28, 0x17})) /* sensor clock at 24 MHz */
                return -EIO;
 
        r0 = sn9c102_i2c_try_read(cam, &pas106b, 0x00);
        r1 = sn9c102_i2c_try_read(cam, &pas106b, 0x01);
-
        if (r0 < 0 || r1 < 0)
                return -EIO;
 
index c1b8d6b63b476b6974a42420900bb1bb942cdd5c..ca4a1506ed3df7cee74976afb2973d41152bf15e 100644 (file)
@@ -35,29 +35,28 @@ static int pas202bcb_init(struct sn9c102_device* cam)
        switch (sn9c102_get_bridge(cam)) {
        case BRIDGE_SN9C101:
        case BRIDGE_SN9C102:
-               err = sn9c102_write_const_regs(cam, {0x00, 0x10},
-                                              {0x00, 0x11}, {0x00, 0x14},
-                                              {0x20, 0x17}, {0x30, 0x19},
-                                              {0x09, 0x18});
+               err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+                                              {0x00, 0x14}, {0x20, 0x17},
+                                              {0x30, 0x19}, {0x09, 0x18});
                break;
        case BRIDGE_SN9C103:
-               err = sn9c102_write_const_regs(cam, {0x00, 0x02},
-                                              {0x00, 0x03}, {0x1a, 0x04},
-                                              {0x20, 0x05}, {0x20, 0x06},
-                                              {0x20, 0x07}, {0x00, 0x10},
-                                              {0x00, 0x11}, {0x00, 0x14},
-                                              {0x20, 0x17}, {0x30, 0x19},
-                                              {0x09, 0x18}, {0x02, 0x1c},
-                                              {0x03, 0x1d}, {0x0f, 0x1e},
-                                              {0x0c, 0x1f}, {0x00, 0x20},
-                                              {0x10, 0x21}, {0x20, 0x22},
-                                              {0x30, 0x23}, {0x40, 0x24},
-                                              {0x50, 0x25}, {0x60, 0x26},
-                                              {0x70, 0x27}, {0x80, 0x28},
-                                              {0x90, 0x29}, {0xa0, 0x2a},
-                                              {0xb0, 0x2b}, {0xc0, 0x2c},
-                                              {0xd0, 0x2d}, {0xe0, 0x2e},
-                                              {0xf0, 0x2f}, {0xff, 0x30});
+               err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
+                                              {0x1a, 0x04}, {0x20, 0x05},
+                                              {0x20, 0x06}, {0x20, 0x07},
+                                              {0x00, 0x10}, {0x00, 0x11},
+                                              {0x00, 0x14}, {0x20, 0x17},
+                                              {0x30, 0x19}, {0x09, 0x18},
+                                              {0x02, 0x1c}, {0x03, 0x1d},
+                                              {0x0f, 0x1e}, {0x0c, 0x1f},
+                                              {0x00, 0x20}, {0x10, 0x21},
+                                              {0x20, 0x22}, {0x30, 0x23},
+                                              {0x40, 0x24}, {0x50, 0x25},
+                                              {0x60, 0x26}, {0x70, 0x27},
+                                              {0x80, 0x28}, {0x90, 0x29},
+                                              {0xa0, 0x2a}, {0xb0, 0x2b},
+                                              {0xc0, 0x2c}, {0xd0, 0x2d},
+                                              {0xe0, 0x2e}, {0xf0, 0x2f},
+                                              {0xff, 0x30});
                break;
        default:
                break;
@@ -197,7 +196,7 @@ static int pas202bcb_set_crop(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor pas202bcb = {
+static const struct sn9c102_sensor pas202bcb = {
        .name = "PAS202BCB",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
@@ -313,9 +312,8 @@ int sn9c102_probe_pas202bcb(struct sn9c102_device* cam)
                                               {0x28, 0x17});/* clock 24 MHz */
                break;
        case BRIDGE_SN9C103: /* do _not_ change anything! */
-               err = sn9c102_write_const_regs(cam, {0x09, 0x01},
-                                              {0x44, 0x01}, {0x44, 0x02},
-                                              {0x29, 0x17});
+               err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x01},
+                                              {0x44, 0x02}, {0x29, 0x17});
                break;
        default:
                break;
index 1bbf64c897a277f19d8a7c10b0e7a2104a34ebec..2d7d786b8430b7a5f236f191ca490d4679186667 100644 (file)
@@ -22,7 +22,7 @@
 #define _SN9C102_SENSOR_H_
 
 #include <linux/usb.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <linux/device.h>
 #include <linux/stddef.h>
 #include <linux/errno.h>
@@ -74,7 +74,7 @@ sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id);
 /* Attach a probed sensor to the camera. */
 extern void
 sn9c102_attach_sensor(struct sn9c102_device* cam,
-                     struct sn9c102_sensor* sensor);
+                     const struct sn9c102_sensor* sensor);
 
 /*
    Read/write routines: they always return -1 on error, 0 or the read value
@@ -85,10 +85,11 @@ sn9c102_attach_sensor(struct sn9c102_device* cam,
 */
 
 /* The "try" I2C I/O versions are used when probing the sensor */
-extern int sn9c102_i2c_try_write(struct sn9c102_device*,struct sn9c102_sensor*,
-                                u8 address, u8 value);
-extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
-                               u8 address);
+extern int sn9c102_i2c_try_write(struct sn9c102_device*,
+                                const struct sn9c102_sensor*, u8 address,
+                                u8 value);
+extern int sn9c102_i2c_try_read(struct sn9c102_device*,
+                               const struct sn9c102_sensor*, u8 address);
 
 /*
    These must be used if and only if the sensor doesn't implement the standard
@@ -102,29 +103,31 @@ extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
    byte.
 */
 extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
-                                    struct sn9c102_sensor* sensor, u8 n,
+                                    const struct sn9c102_sensor* sensor, u8 n,
                                     u8 data0, u8 data1, u8 data2, u8 data3,
                                     u8 data4, u8 data5);
 extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
-                                   struct sn9c102_sensor* sensor, u8 data0,
-                                   u8 data1, u8 n, u8 buffer[]);
+                                   const struct sn9c102_sensor* sensor,
+                                   u8 data0, u8 data1, u8 n, u8 buffer[]);
 
 /* To be used after the sensor struct has been attached to the camera struct */
 extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
 extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
 
 /* I/O on registers in the bridge. Could be used by the sensor methods too */
+extern int sn9c102_read_reg(struct sn9c102_device*, u16 index);
 extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
 extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
 extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2],
                              int count);
 /*
- * Write multiple registers with constant values.  For example:
- * sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
- */
-#define sn9c102_write_const_regs(device, data...) \
-       ({ const static u8 _data[][2] = {data}; \
-       sn9c102_write_regs(device, _data, ARRAY_SIZE(_data)); })
+   Write multiple registers with constant values. For example:
+   sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
+   Register adresses must be < 256.
+*/
+#define sn9c102_write_const_regs(sn9c102_device, data...)                     \
+       ({ const static u8 _valreg[][2] = {data};                             \
+       sn9c102_write_regs(sn9c102_device, _valreg, ARRAY_SIZE(_valreg)); })
 
 /*****************************************************************************/
 
index 0e7ec8662c70cde24434a0b2e0c9a3aa12316eed..e7d2de2bace1096d837f16de2d03c39ce6c92f95 100644 (file)
@@ -88,7 +88,7 @@ static int tas5110c1b_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor tas5110c1b = {
+static const struct sn9c102_sensor tas5110c1b = {
        .name = "TAS5110C1B",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
index 83a39e8b5e717ae439a4145884b616107546edab..d32fdbccdc5eb3fbbcc8fe5f083887f8049d284f 100644 (file)
@@ -68,7 +68,7 @@ static int tas5110d_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor tas5110d = {
+static const struct sn9c102_sensor tas5110d = {
        .name = "TAS5110D",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
index 50406503fc40c4019194bfb46541608e53f435ec..56fb1d575a8a6fd74a247de569a5e3d323c97080 100644 (file)
@@ -89,7 +89,7 @@ static int tas5130d1b_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor tas5130d1b = {
+static const struct sn9c102_sensor tas5130d1b = {
        .name = "TAS5130D1B",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
index a0fd82b924f20780fb18c88eb3805e6e1a713f2d..e4cb99c1f94be8e930c4aa858ec4a5de69aab019 100644 (file)
@@ -3,7 +3,7 @@ config VIDEO_USBVIDEO
 
 config USB_VICAM
        tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)"
-       depends on USB && VIDEO_DEV && VIDEO_V4L1 && EXPERIMENTAL
+       depends on VIDEO_V4L1 && EXPERIMENTAL
        select VIDEO_USBVIDEO
        ---help---
          Say Y here if you have 3com homeconnect camera (vicam).
@@ -13,7 +13,7 @@ config USB_VICAM
 
 config USB_IBMCAM
        tristate "USB IBM (Xirlink) C-it Camera support"
-       depends on USB && VIDEO_DEV && VIDEO_V4L1
+       depends on VIDEO_V4L1
        select VIDEO_USBVIDEO
        ---help---
          Say Y here if you want to connect a IBM "C-It" camera, also known as
@@ -28,7 +28,7 @@ config USB_IBMCAM
 
 config USB_KONICAWC
        tristate "USB Konica Webcam support"
-       depends on USB && VIDEO_DEV && VIDEO_V4L1
+       depends on VIDEO_V4L1
        select VIDEO_USBVIDEO
        ---help---
          Say Y here if you want support for webcams based on a Konica
@@ -39,7 +39,7 @@ config USB_KONICAWC
 
 config USB_QUICKCAM_MESSENGER
        tristate "USB Logitech Quickcam Messenger"
-       depends on USB && VIDEO_DEV && VIDEO_V4L1
+       depends on VIDEO_V4L1
        select VIDEO_USBVIDEO
        ---help---
          Say Y or M here to enable support for the USB Logitech Quickcam
index c43a5d8990918bbffb510dbecfe47600360a392b..fc24ef05b3f31cf527b6fc850423cae317ad224b 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_USBVISION
        tristate "USB video devices based on Nogatech NT1003/1004/1005"
-       depends on I2C && VIDEO_V4L2 && USB
+       depends on I2C && VIDEO_V4L2
        select VIDEO_TUNER
        select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
        ---help---
index a861e150865e6c11ce5ff77264024124d0bc7b7d..ede8543818bfdfef8bdb3fa0bb86c0869cbf637a 100644 (file)
@@ -127,7 +127,7 @@ set_v4l_control(struct inode            *inode,
 
 /* ----------------------------------------------------------------- */
 
-static int palette2pixelformat[] = {
+const static unsigned int palette2pixelformat[] = {
        [VIDEO_PALETTE_GREY]    = V4L2_PIX_FMT_GREY,
        [VIDEO_PALETTE_RGB555]  = V4L2_PIX_FMT_RGB555,
        [VIDEO_PALETTE_RGB565]  = V4L2_PIX_FMT_RGB565,
@@ -145,7 +145,7 @@ static int palette2pixelformat[] = {
        [VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
 };
 
-static unsigned int
+static unsigned int __attribute_pure__
 palette_to_pixelformat(unsigned int palette)
 {
        if (palette < ARRAY_SIZE(palette2pixelformat))
@@ -154,8 +154,8 @@ palette_to_pixelformat(unsigned int palette)
                return 0;
 }
 
-static unsigned int
-pixelformat_to_palette(int pixelformat)
+static unsigned int __attribute_const__
+pixelformat_to_palette(unsigned int pixelformat)
 {
        int     palette = 0;
        switch (pixelformat)
@@ -616,6 +616,8 @@ v4l_compat_translate_ioctl(struct inode         *inode,
        case VIDIOCSPICT: /*  set tone controls & partial capture format  */
        {
                struct video_picture    *pict = arg;
+               int mem_err = 0, ovl_err = 0;
+
                memset(&fbuf2, 0, sizeof(fbuf2));
 
                set_v4l_control(inode, file,
@@ -628,33 +630,59 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                                V4L2_CID_SATURATION, pict->colour, drv);
                set_v4l_control(inode, file,
                                V4L2_CID_WHITENESS, pict->whiteness, drv);
+               /*
+                * V4L1 uses this ioctl to set both memory capture and overlay
+                * pixel format, while V4L2 has two different ioctls for this.
+                * Some cards may not support one or the other, and may support
+                * different pixel formats for memory vs overlay.
+                */
 
                fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
                fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                err = drv(inode, file, VIDIOC_G_FMT, fmt2);
-               if (err < 0)
+               /* If VIDIOC_G_FMT failed, then the driver likely doesn't
+                  support memory capture.  Trying to set the memory capture
+                  parameters would be pointless.  */
+               if (err < 0) {
                        dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err);
-               if (fmt2->fmt.pix.pixelformat !=
-                   palette_to_pixelformat(pict->palette)) {
+                       mem_err = -1000;  /* didn't even try */
+               } else if (fmt2->fmt.pix.pixelformat !=
+                        palette_to_pixelformat(pict->palette)) {
                        fmt2->fmt.pix.pixelformat = palette_to_pixelformat(
                                pict->palette);
-                       err = drv(inode, file, VIDIOC_S_FMT, fmt2);
-                       if (err < 0)
-                               dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",err);
+                       mem_err = drv(inode, file, VIDIOC_S_FMT, fmt2);
+                       if (mem_err < 0)
+                               dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",
+                                       mem_err);
                }
 
                err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
-               if (err < 0)
+               /* If VIDIOC_G_FBUF failed, then the driver likely doesn't
+                  support overlay.  Trying to set the overlay parameters
+                  would be quite pointless.  */
+               if (err < 0) {
                        dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err);
-               if (fbuf2.fmt.pixelformat !=
-                   palette_to_pixelformat(pict->palette)) {
+                       ovl_err = -1000;  /* didn't even try */
+               } else if (fbuf2.fmt.pixelformat !=
+                        palette_to_pixelformat(pict->palette)) {
                        fbuf2.fmt.pixelformat = palette_to_pixelformat(
                                pict->palette);
-                       err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
-                       if (err < 0)
-                               dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",err);
-                       err = 0; /* likely fails for non-root */
+                       ovl_err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
+                       if (ovl_err < 0)
+                               dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",
+                                       ovl_err);
                }
+               if (ovl_err < 0 && mem_err < 0)
+                       /* ioctl failed, couldn't set either parameter */
+                       if (mem_err != -1000) {
+                           err = mem_err;
+                       } else if (ovl_err == -EPERM) {
+                           err = 0;
+                       } else {
+                           err = ovl_err;
+                       }
+               else
+                       err = 0;
                break;
        }
        case VIDIOCGTUNER: /*  get tuner information  */
index 459786ff459a97df7bd3c56e3140a29ac0282d96..a32dfbe0585af96de2c9acc126e5fd0e6fb1edd8 100644 (file)
@@ -702,9 +702,7 @@ videobuf_qbuf(struct videobuf_queue *q,
                dprintk(1,"qbuf: memory type is wrong.\n");
                goto done;
        }
-       if (buf->state == STATE_QUEUED ||
-           buf->state == STATE_PREPARED ||
-           buf->state == STATE_ACTIVE) {
+       if (buf->state != STATE_NEEDS_INIT && buf->state != STATE_IDLE) {
                dprintk(1,"qbuf: buffer is already queued or active.\n");
                goto done;
        }
index 5263b50463e11372ea37de29f2e62b7d9de97faf..b876aca69c73673fadb42f5e9388488d030c3eb4 100644 (file)
@@ -433,13 +433,43 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
        int                  ret = -EINVAL;
 
        if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
-                               !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) {
+                               !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
                v4l_print_ioctl(vfd->name, cmd);
        }
 
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+       /***********************************************************
+        Handles calls to the obsoleted V4L1 API
+        Due to the nature of VIDIOCGMBUF, each driver that supports
+        V4L1 should implement its own handler for this ioctl.
+        ***********************************************************/
+
+       /* --- streaming capture ------------------------------------- */
+       if (cmd == VIDIOCGMBUF) {
+               struct video_mbuf *p=arg;
+
+               memset(p,0,sizeof(p));
+
+               if (!vfd->vidiocgmbuf)
+                       return ret;
+               ret=vfd->vidiocgmbuf(file, fh, p);
+               if (!ret)
+                       dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
+                                               p->size, p->frames,
+                                               (unsigned long)p->offsets);
+               return ret;
+       }
+
+       /********************************************************
+        All other V4L1 calls are handled by v4l1_compat module.
+        Those calls will be translated into V4L2 calls, and
+        __video_do_ioctl will be called again, with one or more
+        V4L2 ioctls.
+        ********************************************************/
        if (_IOC_TYPE(cmd)=='v')
                return v4l_compat_translate_ioctl(inode,file,cmd,arg,
                                                __video_do_ioctl);
+#endif
 
        switch(cmd) {
        /* --- capabilities ------------------------------------------ */
@@ -791,24 +821,6 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
                ret=vfd->vidioc_overlay(file, fh, *i);
                break;
        }
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-       /* --- streaming capture ------------------------------------- */
-       case VIDIOCGMBUF:
-       {
-               struct video_mbuf *p=arg;
-
-               memset(p,0,sizeof(p));
-
-               if (!vfd->vidiocgmbuf)
-                       break;
-               ret=vfd->vidiocgmbuf(file, fh, p);
-               if (!ret)
-                       dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
-                                               p->size, p->frames,
-                                               (unsigned long)p->offsets);
-               break;
-       }
-#endif
        case VIDIOC_G_FBUF:
        {
                struct v4l2_framebuffer *p=arg;
index a859a6920189e5cc62d64e864b6cfc79d995ca2d..47cd93f9c7de8555c7f181b0d17fc7a75793dbc6 100644 (file)
@@ -1,6 +1,6 @@
 config USB_ZC0301
        tristate "USB ZC0301[P] Image Processor and Control Chip support"
-       depends on USB && VIDEO_V4L1
+       depends on VIDEO_V4L1
        ---help---
          Say Y here if you want support for cameras based on the ZC0301 or
          ZC0301P Image Processors and Control Chips.
index 796bcf151a3abf3061b9c6fae3eec2ada0f68063..d3f4f5a38214bd31cee806b424faa97065b76bab 100644 (file)
@@ -58,6 +58,7 @@ struct saa7146_pgtable {
        unsigned long   offset;
        /* used for custom pagetables (used for example by budget dvb cards) */
        struct scatterlist *slist;
+       int             nents;
 };
 
 struct saa7146_pci_extension_data {
@@ -157,6 +158,7 @@ int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt);
 void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt);
 int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, struct scatterlist *list, int length );
 char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt);
+void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, char *mem, struct saa7146_pgtable *pt);
 void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data);
 int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop);
 
index 50e33b0e934984c543651bf4cb1fd8b3af550c87..cce20ed5cf6c221ab61360f05436fd399067d698 100644 (file)
@@ -216,6 +216,8 @@ void saa7146_set_gpio(struct saa7146_dev *saa, u8 pin, u8 data);
 extern struct saa7146_use_ops saa7146_video_uops;
 int saa7146_start_preview(struct saa7146_fh *fh);
 int saa7146_stop_preview(struct saa7146_fh *fh);
+int saa7146_video_do_ioctl(struct inode *inode, struct file *file,
+                          unsigned int cmd, void *arg);
 
 /* from saa7146_vbi.c */
 extern struct saa7146_use_ops saa7146_vbi_uops;