summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-28 23:32:00 +0200
committerIngo Molnar <mingo@elte.hu>2008-07-28 23:32:00 +0200
commit9e3ee1c39c0cc71222f9980ccbf87fe072897eef (patch)
tree99462000e6f0d4f907cb2fc690f19d4d441ba0f3 /drivers
parente56b3bc7942982ac2589c942fb345e38bc7a341a (diff)
parentf934fb19ef34730263e6afc01e8ec27a8a71470f (diff)
Merge branch 'linus' into cpus4096
Conflicts: kernel/stop_machine.c Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/processor_idle.c15
-rw-r--r--drivers/base/memory.c3
-rw-r--r--drivers/char/hw_random/intel-rng.c6
-rw-r--r--drivers/char/pcmcia/ipwireless/hardware.c275
-rw-r--r--drivers/char/pcmcia/ipwireless/hardware.h4
-rw-r--r--drivers/char/pcmcia/ipwireless/main.c86
-rw-r--r--drivers/char/pcmcia/ipwireless/main.h5
-rw-r--r--drivers/char/pcmcia/ipwireless/network.c58
-rw-r--r--drivers/char/pcmcia/ipwireless/network.h1
-rw-r--r--drivers/char/pcmcia/ipwireless/tty.c2
-rw-r--r--drivers/cpuidle/cpuidle.c2
-rw-r--r--drivers/i2c/busses/i2c-bfin-twi.c35
-rw-r--r--drivers/i2c/busses/i2c-gpio.c9
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c129
-rw-r--r--drivers/input/keyboard/sh_keysc.c27
-rw-r--r--drivers/input/misc/uinput.c1
-rw-r--r--drivers/input/serio/serio.c55
-rw-r--r--drivers/input/touchscreen/Kconfig12
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/ads7846.c16
-rw-r--r--drivers/input/touchscreen/atmel_tsadcc.c332
-rw-r--r--drivers/isdn/hardware/mISDN/Kconfig1
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c3
-rw-r--r--drivers/media/common/saa7146_fops.c2
-rw-r--r--drivers/media/common/saa7146_video.c19
-rw-r--r--drivers/media/common/tuners/Kconfig16
-rw-r--r--drivers/media/common/tuners/Makefile1
-rw-r--r--drivers/media/common/tuners/mt20xx.c3
-rw-r--r--drivers/media/common/tuners/mxl5007t.c1030
-rw-r--r--drivers/media/common/tuners/mxl5007t.h104
-rw-r--r--drivers/media/common/tuners/tda9887.c2
-rw-r--r--drivers/media/common/tuners/tuner-simple.c2
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig2
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig10
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h1
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c425
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.h9
-rw-r--r--drivers/media/dvb/frontends/Kconfig38
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/drx397xD.c1504
-rw-r--r--drivers/media/dvb/frontends/drx397xD.h130
-rw-r--r--drivers/media/dvb/frontends/drx397xD_fw.h40
-rw-r--r--drivers/media/dvb/frontends/z0194a.h97
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c14
-rw-r--r--drivers/media/dvb/siano/smsdvb.c4
-rw-r--r--drivers/media/dvb/ttpci/Kconfig4
-rw-r--r--drivers/media/dvb/ttusb-dec/Kconfig2
-rw-r--r--drivers/media/radio/dsbr100.c18
-rw-r--r--drivers/media/radio/miropcm20-radio.c3
-rw-r--r--drivers/media/radio/radio-aimslab.c14
-rw-r--r--drivers/media/radio/radio-aztech.c14
-rw-r--r--drivers/media/radio/radio-cadet.c14
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c13
-rw-r--r--drivers/media/radio/radio-gemtek.c13
-rw-r--r--drivers/media/radio/radio-maestro.c12
-rw-r--r--drivers/media/radio/radio-maxiradio.c15
-rw-r--r--drivers/media/radio/radio-rtrack2.c14
-rw-r--r--drivers/media/radio/radio-sf16fmi.c14
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c14
-rw-r--r--drivers/media/radio/radio-si470x.c22
-rw-r--r--drivers/media/radio/radio-terratec.c14
-rw-r--r--drivers/media/radio/radio-trust.c14
-rw-r--r--drivers/media/radio/radio-typhoon.c14
-rw-r--r--drivers/media/radio/radio-zoltrix.c14
-rw-r--r--drivers/media/video/Kconfig19
-rw-r--r--drivers/media/video/Makefile3
-rw-r--r--drivers/media/video/arv.c1
-rw-r--r--drivers/media/video/au0828/Kconfig1
-rw-r--r--drivers/media/video/au0828/au0828-cards.c12
-rw-r--r--drivers/media/video/au0828/au0828-cards.h1
-rw-r--r--drivers/media/video/au0828/au0828-dvb.c15
-rw-r--r--drivers/media/video/bt8xx/Kconfig2
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c58
-rw-r--r--drivers/media/video/bt8xx/bttv-risc.c1
-rw-r--r--drivers/media/video/bt8xx/bttv-vbi.c1
-rw-r--r--drivers/media/video/bw-qcam.c3
-rw-r--r--drivers/media/video/c-qcam.c3
-rw-r--r--drivers/media/video/cafe_ccic.c26
-rw-r--r--drivers/media/video/compat_ioctl32.c2
-rw-r--r--drivers/media/video/cpia.c2
-rw-r--r--drivers/media/video/cpia.h1
-rw-r--r--drivers/media/video/cpia2/cpia2_core.c1
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c5
-rw-r--r--drivers/media/video/cs5345.c2
-rw-r--r--drivers/media/video/cs53l32a.c2
-rw-r--r--drivers/media/video/cx18/Kconfig2
-rw-r--r--drivers/media/video/cx18/cx18-av-audio.c111
-rw-r--r--drivers/media/video/cx18/cx18-driver.h1
-rw-r--r--drivers/media/video/cx18/cx18-firmware.c54
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c92
-rw-r--r--drivers/media/video/cx18/cx18-streams.c5
-rw-r--r--drivers/media/video/cx23885/Kconfig2
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c19
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c54
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c147
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c19
-rw-r--r--drivers/media/video/cx25840/Kconfig2
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c2
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h2
-rw-r--r--drivers/media/video/cx88/Kconfig3
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c15
-rw-r--r--drivers/media/video/cx88/cx88-cards.c2
-rw-r--r--drivers/media/video/cx88/cx88-core.c3
-rw-r--r--drivers/media/video/cx88/cx88-video.c37
-rw-r--r--drivers/media/video/cx88/cx88.h4
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c977
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c13
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c61
-rw-r--r--drivers/media/video/em28xx/em28xx.h49
-rw-r--r--drivers/media/video/et61x251/et61x251_core.c5
-rw-r--r--drivers/media/video/gspca/conex.c9
-rw-r--r--drivers/media/video/gspca/etoms.c30
-rw-r--r--drivers/media/video/gspca/gspca.c43
-rw-r--r--drivers/media/video/gspca/mars.c9
-rw-r--r--drivers/media/video/gspca/ov519.c33
-rw-r--r--drivers/media/video/gspca/pac207.c29
-rw-r--r--drivers/media/video/gspca/pac7311.c22
-rw-r--r--drivers/media/video/gspca/sonixb.c484
-rw-r--r--drivers/media/video/gspca/sonixj.c492
-rw-r--r--drivers/media/video/gspca/spca500.c139
-rw-r--r--drivers/media/video/gspca/spca501.c75
-rw-r--r--drivers/media/video/gspca/spca505.c140
-rw-r--r--drivers/media/video/gspca/spca506.c121
-rw-r--r--drivers/media/video/gspca/spca508.c164
-rw-r--r--drivers/media/video/gspca/spca561.c62
-rw-r--r--drivers/media/video/gspca/stk014.c9
-rw-r--r--drivers/media/video/gspca/sunplus.c355
-rw-r--r--drivers/media/video/gspca/t613.c26
-rw-r--r--drivers/media/video/gspca/tv8532.c17
-rw-r--r--drivers/media/video/gspca/vc032x.c44
-rw-r--r--drivers/media/video/gspca/zc3xx.c486
-rw-r--r--drivers/media/video/ivtv/Kconfig2
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c5
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h1
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c130
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c7
-rw-r--r--drivers/media/video/m52790.c2
-rw-r--r--drivers/media/video/meye.c19
-rw-r--r--drivers/media/video/msp3400-driver.c2
-rw-r--r--drivers/media/video/msp3400-kthreads.c1
-rw-r--r--drivers/media/video/mt9m001.c2
-rw-r--r--drivers/media/video/ov511.c38
-rw-r--r--drivers/media/video/ov511.h1
-rw-r--r--drivers/media/video/planb.c2309
-rw-r--r--drivers/media/video/planb.h232
-rw-r--r--drivers/media/video/pms.c3
-rw-r--r--drivers/media/video/pvrusb2/Kconfig2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-context.h4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c11
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.h26
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c9
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c6
-rw-r--r--drivers/media/video/pwc/pwc-if.c16
-rw-r--r--drivers/media/video/pwc/pwc.h2
-rw-r--r--drivers/media/video/s2255drv.c130
-rw-r--r--drivers/media/video/saa5246a.c3
-rw-r--r--drivers/media/video/saa5249.c3
-rw-r--r--drivers/media/video/saa7134/Kconfig2
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c3
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c16
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c54
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c98
-rw-r--r--drivers/media/video/saa7134/saa7134.h7
-rw-r--r--drivers/media/video/saa717x.c1
-rw-r--r--drivers/media/video/saa7196.h117
-rw-r--r--drivers/media/video/se401.c2
-rw-r--r--drivers/media/video/se401.h1
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c1
-rw-r--r--drivers/media/video/sn9c102/sn9c102.h1
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c62
-rw-r--r--drivers/media/video/soc_camera.c68
-rw-r--r--drivers/media/video/stk-webcam.c69
-rw-r--r--drivers/media/video/stradis.c2
-rw-r--r--drivers/media/video/stv680.c52
-rw-r--r--drivers/media/video/tda7432.c3
-rw-r--r--drivers/media/video/tda9875.c2
-rw-r--r--drivers/media/video/tlv320aic23b.c2
-rw-r--r--drivers/media/video/tuner-core.c1
-rw-r--r--drivers/media/video/tveeprom.c122
-rw-r--r--drivers/media/video/tvp5150.c2
-rw-r--r--drivers/media/video/usbvideo/usbvideo.c4
-rw-r--r--drivers/media/video/usbvideo/usbvideo.h1
-rw-r--r--drivers/media/video/usbvideo/vicam.c3
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c2
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c113
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c15
-rw-r--r--drivers/media/video/uvc/uvc_driver.c4
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c1
-rw-r--r--drivers/media/video/v4l1-compat.c1
-rw-r--r--drivers/media/video/v4l2-common.c2
-rw-r--r--drivers/media/video/v4l2-dev.c422
-rw-r--r--drivers/media/video/v4l2-ioctl.c1875
-rw-r--r--drivers/media/video/videobuf-dma-contig.c8
-rw-r--r--drivers/media/video/videobuf-vmalloc.c2
-rw-r--r--drivers/media/video/videodev.c2262
-rw-r--r--drivers/media/video/vino.c4
-rw-r--r--drivers/media/video/vivi.c18
-rw-r--r--drivers/media/video/vp27smpx.c2
-rw-r--r--drivers/media/video/w9966.c5
-rw-r--r--drivers/media/video/w9968cf.c5
-rw-r--r--drivers/media/video/w9968cf.h2
-rw-r--r--drivers/media/video/wm8739.c2
-rw-r--r--drivers/media/video/wm8775.c2
-rw-r--r--drivers/media/video/zc0301/zc0301.h1
-rw-r--r--drivers/media/video/zc0301/zc0301_core.c2
-rw-r--r--drivers/media/video/zoran_card.c42
-rw-r--r--drivers/media/video/zoran_card.h2
-rw-r--r--drivers/media/video/zoran_driver.c7
-rw-r--r--drivers/media/video/zr364xx.c18
-rw-r--r--drivers/net/ibmveth.c8
-rw-r--r--drivers/of/Kconfig6
-rw-r--r--drivers/of/Makefile1
-rw-r--r--drivers/of/base.c88
-rw-r--r--drivers/of/of_i2c.c64
-rw-r--r--drivers/of/of_spi.c93
-rw-r--r--drivers/serial/sh-sci.c17
-rw-r--r--drivers/serial/sh-sci.h38
-rw-r--r--drivers/spi/spi.c139
222 files changed, 9990 insertions, 8361 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index b7f2963693a..283c08f5f4d 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -1332,9 +1332,15 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
if (!pr->flags.power_setup_done)
return -ENODEV;
- /* Fall back to the default idle loop */
- pm_idle = pm_idle_save;
- synchronize_sched(); /* Relies on interrupts forcing exit from idle. */
+ /*
+ * Fall back to the default idle loop, when pm_idle_save had
+ * been initialized.
+ */
+ if (pm_idle_save) {
+ pm_idle = pm_idle_save;
+ /* Relies on interrupts forcing exit from idle. */
+ synchronize_sched();
+ }
pr->flags.power = 0;
result = acpi_processor_get_power_info(pr);
@@ -1896,7 +1902,8 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
/* Unregister the idle handler when processor #0 is removed. */
if (pr->id == 0) {
- pm_idle = pm_idle_save;
+ if (pm_idle_save)
+ pm_idle = pm_idle_save;
/*
* We are about to unload the current idle thread pm callback
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 3ad49a00029..af0d175c025 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -103,7 +103,8 @@ static ssize_t show_mem_phys_index(struct sys_device *dev,
/*
* Show whether the section of memory is likely to be hot-removable
*/
-static ssize_t show_mem_removable(struct sys_device *dev, char *buf)
+static ssize_t show_mem_removable(struct sys_device *dev,
+ struct sysdev_attribute *attr, char *buf)
{
unsigned long start_pfn;
int ret;
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c
index 27fdc086649..8a2fce0756e 100644
--- a/drivers/char/hw_random/intel-rng.c
+++ b/drivers/char/hw_random/intel-rng.c
@@ -241,7 +241,7 @@ static int __init intel_rng_hw_init(void *_intel_rng_hw)
struct intel_rng_hw *intel_rng_hw = _intel_rng_hw;
u8 mfc, dvc;
- /* interrupts disabled in stop_machine_run call */
+ /* interrupts disabled in stop_machine call */
if (!(intel_rng_hw->fwh_dec_en1_val & FWH_F8_EN_MASK))
pci_write_config_byte(intel_rng_hw->dev,
@@ -365,10 +365,10 @@ static int __init mod_init(void)
* location with the Read ID command, all activity on the system
* must be stopped until the state is back to normal.
*
- * Use stop_machine_run because IPIs can be blocked by disabling
+ * Use stop_machine because IPIs can be blocked by disabling
* interrupts.
*/
- err = stop_machine_run(intel_rng_hw_init, intel_rng_hw, NR_CPUS);
+ err = stop_machine(intel_rng_hw_init, intel_rng_hw, NULL);
pci_dev_put(dev);
iounmap(intel_rng_hw->mem);
kfree(intel_rng_hw);
diff --git a/drivers/char/pcmcia/ipwireless/hardware.c b/drivers/char/pcmcia/ipwireless/hardware.c
index 929101ecbae..7d500f82195 100644
--- a/drivers/char/pcmcia/ipwireless/hardware.c
+++ b/drivers/char/pcmcia/ipwireless/hardware.c
@@ -30,11 +30,11 @@
static void ipw_send_setup_packet(struct ipw_hardware *hw);
static void handle_received_SETUP_packet(struct ipw_hardware *ipw,
unsigned int address,
- unsigned char *data, int len,
+ const unsigned char *data, int len,
int is_last);
static void ipwireless_setup_timer(unsigned long data);
static void handle_received_CTRL_packet(struct ipw_hardware *hw,
- unsigned int channel_idx, unsigned char *data, int len);
+ unsigned int channel_idx, const unsigned char *data, int len);
/*#define TIMING_DIAGNOSTICS*/
@@ -79,8 +79,7 @@ static void report_timing(void)
timing_stats.last_report_time = jiffies;
if (!first)
printk(KERN_INFO IPWIRELESS_PCCARD_NAME
- ": %u us elapsed - read %lu bytes in %u us, "
- "wrote %lu bytes in %u us\n",
+ ": %u us elapsed - read %lu bytes in %u us, wrote %lu bytes in %u us\n",
jiffies_to_usecs(since),
timing_stats.read_bytes,
jiffies_to_usecs(timing_stats.read_time),
@@ -133,29 +132,17 @@ enum {
#define NL_FOLLOWING_PACKET_HEADER_SIZE 1
struct nl_first_packet_header {
-#if defined(__BIG_ENDIAN_BITFIELD)
- unsigned char packet_rank:2;
- unsigned char address:3;
- unsigned char protocol:3;
-#else
unsigned char protocol:3;
unsigned char address:3;
unsigned char packet_rank:2;
-#endif
unsigned char length_lsb;
unsigned char length_msb;
};
struct nl_packet_header {
-#if defined(__BIG_ENDIAN_BITFIELD)
- unsigned char packet_rank:2;
- unsigned char address:3;
- unsigned char protocol:3;
-#else
unsigned char protocol:3;
unsigned char address:3;
unsigned char packet_rank:2;
-#endif
};
/* Value of 'packet_rank' above */
@@ -227,15 +214,12 @@ struct MEMINFREG {
unsigned short memreg_tx_new; /* TX2 (new) Register (R/W) */
};
-#define IODMADPR 0x00 /* DMA Data Port Register (R/W) */
-
#define CARD_PRESENT_VALUE (0xBEEFCAFEUL)
#define MEMTX_TX 0x0001
#define MEMRX_RX 0x0001
#define MEMRX_RX_DONE 0x0001
#define MEMRX_PCINTACKK 0x0001
-#define MEMRX_MEMSPURIOUSINT 0x0001
#define NL_NUM_OF_PRIORITIES 3
#define NL_NUM_OF_PROTOCOLS 3
@@ -245,7 +229,7 @@ struct ipw_hardware {
unsigned int base_port;
short hw_version;
unsigned short ll_mtu;
- spinlock_t spinlock;
+ spinlock_t lock;
int initializing;
int init_loops;
@@ -386,26 +370,52 @@ static void dump_data_bytes(const char *type, const unsigned char *data,
length < DUMP_MAX_BYTES ? length : DUMP_MAX_BYTES);
}
-static int do_send_fragment(struct ipw_hardware *hw, const unsigned char *data,
+static void swap_packet_bitfield_to_le(unsigned char *data)
+{
+#ifdef __BIG_ENDIAN_BITFIELD
+ unsigned char tmp = *data, ret = 0;
+
+ /*
+ * transform bits from aa.bbb.ccc to ccc.bbb.aa
+ */
+ ret |= tmp & 0xc0 >> 6;
+ ret |= tmp & 0x38 >> 1;
+ ret |= tmp & 0x07 << 5;
+ *data = ret & 0xff;
+#endif
+}
+
+static void swap_packet_bitfield_from_le(unsigned char *data)
+{
+#ifdef __BIG_ENDIAN_BITFIELD
+ unsigned char tmp = *data, ret = 0;
+
+ /*
+ * transform bits from ccc.bbb.aa to aa.bbb.ccc
+ */
+ ret |= tmp & 0xe0 >> 5;
+ ret |= tmp & 0x1c << 1;
+ ret |= tmp & 0x03 << 6;
+ *data = ret & 0xff;
+#endif
+}
+
+static void do_send_fragment(struct ipw_hardware *hw, unsigned char *data,
unsigned length)
{
- int i;
+ unsigned i;
unsigned long flags;
start_timing();
-
- if (length == 0)
- return 0;
-
- if (length > hw->ll_mtu)
- return -1;
+ BUG_ON(length > hw->ll_mtu);
if (ipwireless_debug)
dump_data_bytes("send", data, length);
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
hw->tx_ready = 0;
+ swap_packet_bitfield_to_le(data);
if (hw->hw_version == HW_VERSION_1) {
outw((unsigned short) length, hw->base_port + IODWR);
@@ -414,7 +424,7 @@ static int do_send_fragment(struct ipw_hardware *hw, const unsigned char *data,
unsigned short d = data[i];
__le16 raw_data;
- if (likely(i + 1 < length))
+ if (i + 1 < length)
d |= data[i + 1] << 8;
raw_data = cpu_to_le16(d);
outw(raw_data, hw->base_port + IODWR);
@@ -422,32 +432,30 @@ static int do_send_fragment(struct ipw_hardware *hw, const unsigned char *data,
outw(DCR_TXDONE, hw->base_port + IODCR);
} else if (hw->hw_version == HW_VERSION_2) {
- outw((unsigned short) length, hw->base_port + IODMADPR);
+ outw((unsigned short) length, hw->base_port);
for (i = 0; i < length; i += 2) {
unsigned short d = data[i];
__le16 raw_data;
- if ((i + 1 < length))
+ if (i + 1 < length)
d |= data[i + 1] << 8;
raw_data = cpu_to_le16(d);
- outw(raw_data, hw->base_port + IODMADPR);
+ outw(raw_data, hw->base_port);
}
while ((i & 3) != 2) {
- outw((unsigned short) 0xDEAD, hw->base_port + IODMADPR);
+ outw((unsigned short) 0xDEAD, hw->base_port);
i += 2;
}
writew(MEMRX_RX, &hw->memory_info_regs->memreg_rx);
}
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
end_write_timing(length);
-
- return 0;
}
-static int do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet)
+static void do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet)
{
unsigned short fragment_data_len;
unsigned short data_left = packet->length - packet->offset;
@@ -462,6 +470,10 @@ static int do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet)
if (data_left < fragment_data_len)
fragment_data_len = data_left;
+ /*
+ * hdr_first is now in machine bitfield order, which will be swapped
+ * to le just before it goes to hw
+ */
pkt.hdr_first.protocol = packet->protocol;
pkt.hdr_first.address = packet->dest_addr;
pkt.hdr_first.packet_rank = 0;
@@ -493,25 +505,23 @@ static int do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet)
*/
unsigned long flags;
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
list_add(&packet->queue, &hw->tx_queue[0]);
hw->tx_queued++;
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
} else {
if (packet->packet_callback)
packet->packet_callback(packet->callback_data,
packet->length);
kfree(packet);
}
-
- return 0;
}
static void ipw_setup_hardware(struct ipw_hardware *hw)
{
unsigned long flags;
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
if (hw->hw_version == HW_VERSION_1) {
/* Reset RX FIFO */
outw(DCR_RXRESET, hw->base_port + IODCR);
@@ -530,7 +540,7 @@ static void ipw_setup_hardware(struct ipw_hardware *hw)
csr |= 1;
writew(csr, &hw->memregs_CCR->reg_config_and_status);
}
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
}
/*
@@ -549,28 +559,23 @@ static struct ipw_rx_packet *pool_allocate(struct ipw_hardware *hw,
if (!packet) {
unsigned long flags;
- /*
- * If this is the first fragment, then we will need to fetch a
- * packet to put it in.
- */
- spin_lock_irqsave(&hw->spinlock, flags);
- /* If we have one in our pool, then pull it out. */
+ spin_lock_irqsave(&hw->lock, flags);
if (!list_empty(&hw->rx_pool)) {
packet = list_first_entry(&hw->rx_pool,
struct ipw_rx_packet, queue);
- list_del(&packet->queue);
hw->rx_pool_size--;
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
+ list_del(&packet->queue);
} else {
- /* Otherwise allocate a new one. */
- static int min_capacity = 256;
+ const int min_capacity =
+ ipwireless_ppp_mru(hw->network + 2);
int new_capacity;
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
new_capacity =
- minimum_free_space > min_capacity
- ? minimum_free_space
- : min_capacity;
+ (minimum_free_space > min_capacity
+ ? minimum_free_space
+ : min_capacity);
packet = kmalloc(sizeof(struct ipw_rx_packet)
+ new_capacity, GFP_ATOMIC);
if (!packet)
@@ -580,10 +585,6 @@ static struct ipw_rx_packet *pool_allocate(struct ipw_hardware *hw,
packet->length = 0;
}
- /*
- * If this packet does not have sufficient capacity for the data we
- * want to add, then make it bigger.
- */
if (packet->length + minimum_free_space > packet->capacity) {
struct ipw_rx_packet *old_packet = packet;
@@ -610,13 +611,15 @@ static void pool_free(struct ipw_hardware *hw, struct ipw_rx_packet *packet)
kfree(packet);
else {
hw->rx_pool_size++;
- list_add_tail(&packet->queue, &hw->rx_pool);
+ list_add(&packet->queue, &hw->rx_pool);
}
}
static void queue_received_packet(struct ipw_hardware *hw,
- unsigned int protocol, unsigned int address,
- unsigned char *data, int length, int is_last)
+ unsigned int protocol,
+ unsigned int address,
+ const unsigned char *data, int length,
+ int is_last)
{
unsigned int channel_idx = address - 1;
struct ipw_rx_packet *packet = NULL;
@@ -658,9 +661,9 @@ static void queue_received_packet(struct ipw_hardware *hw,
packet = *assem;
*assem = NULL;
/* Count queued DATA bytes only */
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
hw->rx_bytes_queued += packet->length;
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
}
} else {
/* If it's a CTRL packet, don't assemble, just queue it. */
@@ -682,13 +685,13 @@ static void queue_received_packet(struct ipw_hardware *hw,
* network layer.
*/
if (packet) {
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
list_add_tail(&packet->queue, &hw->rx_queue);
/* Block reception of incoming packets if queue is full. */
hw->blocking_rx =
- hw->rx_bytes_queued >= IPWIRELESS_RX_QUEUE_SIZE;
+ (hw->rx_bytes_queued >= IPWIRELESS_RX_QUEUE_SIZE);
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
schedule_work(&hw->work_rx);
}
}
@@ -702,7 +705,7 @@ static void ipw_receive_data_work(struct work_struct *work_rx)
container_of(work_rx, struct ipw_hardware, work_rx);
unsigned long flags;
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
while (!list_empty(&hw->rx_queue)) {
struct ipw_rx_packet *packet =
list_first_entry(&hw->rx_queue,
@@ -720,7 +723,7 @@ static void ipw_receive_data_work(struct work_struct *work_rx)
if (packet->protocol == TL_PROTOCOLID_COM_DATA) {
if (hw->network != NULL) {
/* If the network hasn't been disconnected. */
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
/*
* This must run unlocked due to tty processing
* and mutex locking
@@ -731,7 +734,7 @@ static void ipw_receive_data_work(struct work_struct *work_rx)
(unsigned char *)packet
+ sizeof(struct ipw_rx_packet),
packet->length);
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
}
/* Count queued DATA bytes only */
hw->rx_bytes_queued -= packet->length;
@@ -755,15 +758,15 @@ static void ipw_receive_data_work(struct work_struct *work_rx)
if (hw->shutting_down)
break;
}
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
}
static void handle_received_CTRL_packet(struct ipw_hardware *hw,
unsigned int channel_idx,
- unsigned char *data, int len)
+ const unsigned char *data, int len)
{
- struct ipw_control_packet_body *body =
- (struct ipw_control_packet_body *) data;
+ const struct ipw_control_packet_body *body =
+ (const struct ipw_control_packet_body *) data;
unsigned int changed_mask;
if (len != sizeof(struct ipw_control_packet_body)) {
@@ -805,13 +808,13 @@ static void handle_received_CTRL_packet(struct ipw_hardware *hw,
}
static void handle_received_packet(struct ipw_hardware *hw,
- union nl_packet *packet,
+ const union nl_packet *packet,
unsigned short len)
{
unsigned int protocol = packet->hdr.protocol;
unsigned int address = packet->hdr.address;
unsigned int header_length;
- unsigned char *data;
+ const unsigned char *data;
unsigned int data_len;
int is_last = packet->hdr.packet_rank & NL_LAST_PACKET;
@@ -850,7 +853,7 @@ static void acknowledge_data_read(struct ipw_hardware *hw)
static void do_receive_packet(struct ipw_hardware *hw)
{
unsigned len;
- unsigned int i;
+ unsigned i;
unsigned char pkt[LL_MTU_MAX];
start_timing();
@@ -859,8 +862,7 @@ static void do_receive_packet(struct ipw_hardware *hw)
len = inw(hw->base_port + IODRR);
if (len > hw->ll_mtu) {
printk(KERN_INFO IPWIRELESS_PCCARD_NAME
- ": received a packet of %u bytes - "
- "longer than the MTU!\n", len);
+ ": received a packet of %u bytes - longer than the MTU!\n", len);
outw(DCR_RXDONE | DCR_RXRESET, hw->base_port + IODCR);
return;
}
@@ -873,18 +875,17 @@ static void do_receive_packet(struct ipw_hardware *hw)
pkt[i + 1] = (unsigned char) (data >> 8);
}
} else {
- len = inw(hw->base_port + IODMADPR);
+ len = inw(hw->base_port);
if (len > hw->ll_mtu) {
printk(KERN_INFO IPWIRELESS_PCCARD_NAME
- ": received a packet of %u bytes - "
- "longer than the MTU!\n", len);
+ ": received a packet of %u bytes - longer than the MTU!\n", len);
writew(MEMRX_PCINTACKK,
&hw->memory_info_regs->memreg_pc_interrupt_ack);
return;
}
for (i = 0; i < len; i += 2) {
- __le16 raw_data = inw(hw->base_port + IODMADPR);
+ __le16 raw_data = inw(hw->base_port);
unsigned short data = le16_to_cpu(raw_data);
pkt[i] = (unsigned char) data;
@@ -892,13 +893,15 @@ static void do_receive_packet(struct ipw_hardware *hw)
}
while ((i & 3) != 2) {
- inw(hw->base_port + IODMADPR);
+ inw(hw->base_port);
i += 2;
}
}
acknowledge_data_read(hw);
+ swap_packet_bitfield_from_le(pkt);
+
if (ipwireless_debug)
dump_data_bytes("recv", pkt, len);
@@ -916,8 +919,7 @@ static int get_current_packet_priority(struct ipw_hardware *hw)
* until setup is complete.
*/
return (hw->to_setup || hw->initializing
- ? PRIO_SETUP + 1 :
- NL_NUM_OF_PRIORITIES);
+ ? PRIO_SETUP + 1 : NL_NUM_OF_PRIORITIES);
}
/*
@@ -928,17 +930,17 @@ static int get_packets_from_hw(struct ipw_hardware *hw)
int received = 0;
unsigned long flags;
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
while (hw->rx_ready && !hw->blocking_rx) {
received = 1;
hw->rx_ready--;
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
do_receive_packet(hw);
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
}
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
return received;
}
@@ -954,7 +956,7 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit)
int more_to_send = 0;
unsigned long flags;
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
if (hw->tx_queued && hw->tx_ready) {
int priority;
struct ipw_tx_packet *packet = NULL;
@@ -975,17 +977,17 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit)
}
if (!packet) {
hw->tx_queued = 0;
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
return 0;
}
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
/* Send */
do_send_packet(hw, packet);
/* Check if more to send */
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
for (priority = 0; priority < priority_limit; priority++)
if (!list_empty(&hw->tx_queue[priority])) {
more_to_send = 1;
@@ -995,7 +997,7 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit)
if (!more_to_send)
hw->tx_queued = 0;
}
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
return more_to_send;
}
@@ -1008,9 +1010,9 @@ static void ipwireless_do_tasklet(unsigned long hw_)
struct ipw_hardware *hw = (struct ipw_hardware *) hw_;
unsigned long flags;
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
if (hw->shutting_down) {
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
return;
}
@@ -1019,7 +1021,7 @@ static void ipwireless_do_tasklet(unsigned long hw_)
* Initial setup data sent to hardware
*/
hw->to_setup = 2;
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
ipw_setup_hardware(hw);
ipw_send_setup_packet(hw);
@@ -1030,7 +1032,7 @@ static void ipwireless_do_tasklet(unsigned long hw_)
int priority_limit = get_current_packet_priority(hw);
int again;
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
do {
again = send_pending_packet(hw, priority_limit);
@@ -1068,16 +1070,16 @@ static irqreturn_t ipwireless_handle_v1_interrupt(int irq,
/* Transmit complete. */
if (irqn & IR_TXINTR) {
ack |= IR_TXINTR;
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
hw->tx_ready = 1;
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
}
/* Received data */
if (irqn & IR_RXINTR) {
ack |= IR_RXINTR;
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
hw->rx_ready++;
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
}
if (ack != 0) {
outw(ack, hw->base_port + IOIR);
@@ -1128,9 +1130,8 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
} else {
return IRQ_NONE;
}
- } else {
+ } else
return IRQ_NONE;
- }
}
/*
@@ -1149,9 +1150,9 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
if (hw->serial_number_detected) {
if (memtx_serial != hw->last_memtx_serial) {
hw->last_memtx_serial = memtx_serial;
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
hw->rx_ready++;
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
rx = 1;
} else
/* Ignore 'Timer Recovery' duplicates. */
@@ -1166,18 +1167,18 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME
": memreg_tx serial num detected\n");
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
hw->rx_ready++;
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
}
rx = 1;
}
}
if (memrxdone & MEMRX_RX_DONE) {
writew(0, &hw->memory_info_regs->memreg_rx_done);
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
hw->tx_ready = 1;
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
tx = 1;
}
if (tx)
@@ -1195,8 +1196,7 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
": spurious interrupt - new_tx mode\n");
else {
printk(KERN_WARNING IPWIRELESS_PCCARD_NAME
- ": no valid memreg_tx value - "
- "switching to the old memreg_tx\n");
+ ": no valid memreg_tx value - switching to the old memreg_tx\n");
hw->memreg_tx =
&hw->memory_info_regs->memreg_tx_old;
try_mem_tx_old = 1;
@@ -1211,7 +1211,7 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
return IRQ_HANDLED;
}
-irqreturn_t ipwireless_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t ipwireless_interrupt(int irq, void *dev_id)
{
struct ipw_hardware *hw = dev_id;
@@ -1226,9 +1226,9 @@ static void flush_packets_to_hw(struct ipw_hardware *hw)
int priority_limit;
unsigned long flags;
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
priority_limit = get_current_packet_priority(hw);
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
while (send_pending_packet(hw, priority_limit));
}
@@ -1238,10 +1238,10 @@ static void send_packet(struct ipw_hardware *hw, int priority,
{
unsigned long flags;
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
list_add_tail(&packet->queue, &hw->tx_queue[priority]);
hw->tx_queued++;
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
flush_packets_to_hw(hw);
}
@@ -1291,21 +1291,20 @@ static void *alloc_ctrl_packet(int header_size,
}
int ipwireless_send_packet(struct ipw_hardware *hw, unsigned int channel_idx,
- unsigned char *data, unsigned int length,
+ const unsigned char *data, unsigned int length,
void (*callback) (void *cb, unsigned int length),
void *callback_data)
{
struct ipw_tx_packet *packet;
- packet = alloc_data_packet(length,
- (unsigned char) (channel_idx + 1),
- TL_PROTOCOLID_COM_DATA);
+ packet = alloc_data_packet(length, (channel_idx + 1),
+ TL_PROTOCOLID_COM_DATA);
if (!packet)
return -ENOMEM;
packet->packet_callback = callback;
packet->callback_data = callback_data;
- memcpy((unsigned char *) packet +
- sizeof(struct ipw_tx_packet), data, length);
+ memcpy((unsigned char *) packet + sizeof(struct ipw_tx_packet), data,
+ length);
send_packet(hw, PRIO_DATA, packet);
return 0;
@@ -1321,12 +1320,11 @@ static int set_control_line(struct ipw_hardware *hw, int prio,
protocolid = TL_PROTOCOLID_SETUP;
packet = alloc_ctrl_packet(sizeof(struct ipw_control_packet),
- (unsigned char) (channel_idx + 1),
- protocolid, line);
+ (channel_idx + 1), protocolid, line);
if (!packet)
return -ENOMEM;
packet->header.length = sizeof(struct ipw_control_packet_body);
- packet->body.value = (unsigned char) (state == 0 ? 0 : 1);
+ packet->body.value = (state == 0 ? 0 : 1);
send_packet(hw, prio, &packet->header);
return 0;
}
@@ -1504,8 +1502,7 @@ static void handle_setup_get_version_rsp(struct ipw_hardware *hw,
if (vers_no == TL_SETUP_VERSION)
__handle_setup_get_version_rsp(hw);
else
- printk(KERN_ERR
- IPWIRELESS_PCCARD_NAME
+ printk(KERN_ERR IPWIRELESS_PCCARD_NAME
": invalid hardware version no %u\n",
(unsigned int) vers_no);
}
@@ -1528,10 +1525,10 @@ static void ipw_send_setup_packet(struct ipw_hardware *hw)
static void handle_received_SETUP_packet(struct ipw_hardware *hw,
unsigned int address,
- unsigned char *data, int len,
+ const unsigned char *data, int len,
int is_last)
{
- union ipw_setup_rx_msg *rx_msg = (union ipw_setup_rx_msg *) data;
+ const union ipw_setup_rx_msg *rx_msg = (const union ipw_setup_rx_msg *) data;
if (address != ADDR_SETUP_PROT) {
printk(KERN_INFO IPWIRELESS_PCCARD_NAME
@@ -1629,7 +1626,7 @@ struct ipw_hardware *ipwireless_hardware_create(void)
INIT_LIST_HEAD(&hw->rx_queue);
INIT_LIST_HEAD(&hw->rx_pool);
- spin_lock_init(&hw->spinlock);
+ spin_lock_init(&hw->lock);
tasklet_init(&hw->tasklet, ipwireless_do_tasklet, (unsigned long) hw);
INIT_WORK(&hw->work_rx, ipw_receive_data_work);
setup_timer(&hw->setup_timer, ipwireless_setup_timer,
@@ -1651,8 +1648,8 @@ void ipwireless_init_hardware_v1(struct ipw_hardware *hw,
enable_irq(hw->irq);
}
hw->base_port = base_port;
- hw->hw_version = is_v2_card ? HW_VERSION_2 : HW_VERSION_1;
- hw->ll_mtu = hw->hw_version == HW_VERSION_1 ? LL_MTU_V1 : LL_MTU_V2;
+ hw->hw_version = (is_v2_card ? HW_VERSION_2 : HW_VERSION_1);
+ hw->ll_mtu = (hw->hw_version == HW_VERSION_1 ? LL_MTU_V1 : LL_MTU_V2);
hw->memregs_CCR = (struct MEMCCR __iomem *)
((unsigned short __iomem *) attr_memory + 0x200);
hw->memory_info_regs = (struct MEMINFREG __iomem *) common_memory;
@@ -1695,10 +1692,10 @@ static void ipwireless_setup_timer(unsigned long data)
if (is_card_present(hw)) {
unsigned long flags;
- spin_lock_irqsave(&hw->spinlock, flags);
+ spin_lock_irqsave(&hw->lock, flags);
hw->to_setup = 1;
hw->tx_ready = 1;
- spin_unlock_irqrestore(&hw->spinlock, flags);
+ spin_unlock_irqrestore(&hw->lock, flags);
tasklet_schedule(&hw->tasklet);
}
diff --git a/drivers/char/pcmcia/ipwireless/hardware.h b/drivers/char/pcmcia/ipwireless/hardware.h
index 19ce5eb266b..90a8590e43b 100644
--- a/drivers/char/pcmcia/ipwireless/hardware.h
+++ b/drivers/char/pcmcia/ipwireless/hardware.h
@@ -34,14 +34,14 @@ struct ipw_network;
struct ipw_hardware *ipwireless_hardware_create(void);
void ipwireless_hardware_free(struct ipw_hardware *hw);
-irqreturn_t ipwireless_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t ipwireless_interrupt(int irq, void *dev_id);
int ipwireless_set_DTR(struct ipw_hardware *hw, unsigned int channel_idx,
int state);
int ipwireless_set_RTS(struct ipw_hardware *hw, unsigned int channel_idx,
int state);
int ipwireless_send_packet(struct ipw_hardware *hw,
unsigned int channel_idx,
- unsigned char *data,
+ const unsigned char *data,
unsigned int length,
void (*packet_sent_callback) (void *cb,
unsigned int length),
diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c
index cc7dcea2d28..5eca7a99afe 100644
--- a/drivers/char/pcmcia/ipwireless/main.c
+++ b/drivers/char/pcmcia/ipwireless/main.c
@@ -49,7 +49,7 @@ static void ipwireless_detach(struct pcmcia_device *link);
/* Debug mode: more verbose, print sent/recv bytes */
int ipwireless_debug;
int ipwireless_loopback;
-int ipwireless_out_queue = 1;
+int ipwireless_out_queue = 10;
module_param_named(debug, ipwireless_debug, int, 0);
module_param_named(loopback, ipwireless_loopback, int, 0);
@@ -57,7 +57,7 @@ module_param_named(out_queue, ipwireless_out_queue, int, 0);
MODULE_PARM_DESC(debug, "switch on debug messages [0]");
MODULE_PARM_DESC(loopback,
"debug: enable ras_raw channel [0]");
-MODULE_PARM_DESC(out_queue, "debug: set size of outgoing queue [1]");
+MODULE_PARM_DESC(out_queue, "debug: set size of outgoing PPP queue [10]");
/* Executes in process context. */
static void signalled_reboot_work(struct work_struct *work_reboot)
@@ -88,8 +88,6 @@ static int config_ipwireless(struct ipw_dev *ipw)
unsigned short buf[64];
cisparse_t parse;
unsigned short cor_value;
- win_req_t request_attr_memory;
- win_req_t request_common_memory;
memreq_t memreq_attr_memory;
memreq_t memreq_common_memory;
@@ -188,6 +186,9 @@ static int config_ipwireless(struct ipw_dev *ipw)
goto exit0;
}
+ request_region(link->io.BasePort1, link->io.NumPorts1,
+ IPWIRELESS_PCCARD_NAME);
+
/* memory settings */
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
@@ -214,16 +215,16 @@ static int config_ipwireless(struct ipw_dev *ipw)
}
if (parse.cftable_entry.mem.nwin > 0) {
- request_common_memory.Attributes =
+ ipw->request_common_memory.Attributes =
WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
- request_common_memory.Base =
+ ipw->request_common_memory.Base =
parse.cftable_entry.mem.win[0].host_addr;
- request_common_memory.Size = parse.cftable_entry.mem.win[0].len;
- if (request_common_memory.Size < 0x1000)
- request_common_memory.Size = 0x1000;
- request_common_memory.AccessSpeed = 0;
+ ipw->request_common_memory.Size = parse.cftable_entry.mem.win[0].len;
+ if (ipw->request_common_memory.Size < 0x1000)
+ ipw->request_common_memory.Size = 0x1000;
+ ipw->request_common_memory.AccessSpeed = 0;
- ret = pcmcia_request_window(&link, &request_common_memory,
+ ret = pcmcia_request_window(&link, &ipw->request_common_memory,
&ipw->handle_common_memory);
if (ret != CS_SUCCESS) {
@@ -246,16 +247,18 @@ static int config_ipwireless(struct ipw_dev *ipw)
ipw->is_v2_card =
parse.cftable_entry.mem.win[0].len == 0x100;
- ipw->common_memory = ioremap(request_common_memory.Base,
- request_common_memory.Size);
+ ipw->common_memory = ioremap(ipw->request_common_memory.Base,
+ ipw->request_common_memory.Size);
+ request_mem_region(ipw->request_common_memory.Base,
+ ipw->request_common_memory.Size, IPWIRELESS_PCCARD_NAME);
- request_attr_memory.Attributes =
+ ipw->request_attr_memory.Attributes =
WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE;
- request_attr_memory.Base = 0;
- request_attr_memory.Size = 0; /* this used to be 0x1000 */
- request_attr_memory.AccessSpeed = 0;
+ ipw->request_attr_memory.Base = 0;
+ ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */
+ ipw->request_attr_memory.AccessSpeed = 0;
- ret = pcmcia_request_window(&link, &request_attr_memory,
+ ret = pcmcia_request_window(&link, &ipw->request_attr_memory,
&ipw->handle_attr_memory);
if (ret != CS_SUCCESS) {
@@ -274,8 +277,10 @@ static int config_ipwireless(struct ipw_dev *ipw)
goto exit2;
}
- ipw->attr_memory = ioremap(request_attr_memory.Base,
- request_attr_memory.Size);
+ ipw->attr_memory = ioremap(ipw->request_attr_memory.Base,
+ ipw->request_attr_memory.Size);
+ request_mem_region(ipw->request_attr_memory.Base, ipw->request_attr_memory.Size,
+ IPWIRELESS_PCCARD_NAME);
}
INIT_WORK(&ipw->work_reboot, signalled_reboot_work);
@@ -311,14 +316,13 @@ static int config_ipwireless(struct ipw_dev *ipw)
(unsigned int) link->irq.AssignedIRQ);
if (ipw->attr_memory && ipw->common_memory)
printk(KERN_INFO IPWIRELESS_PCCARD_NAME
- ": attr memory 0x%08lx-0x%08lx, "
- "common memory 0x%08lx-0x%08lx\n",
- request_attr_memory.Base,
- request_attr_memory.Base
- + request_attr_memory.Size - 1,
- request_common_memory.Base,
- request_common_memory.Base
- + request_common_memory.Size - 1);
+ ": attr memory 0x%08lx-0x%08lx, common memory 0x%08lx-0x%08lx\n",
+ ipw->request_attr_memory.Base,
+ ipw->request_attr_memory.Base
+ + ipw->request_attr_memory.Size - 1,
+ ipw->request_common_memory.Base,
+ ipw->request_common_memory.Base
+ + ipw->request_common_memory.Size - 1);
ipw->network = ipwireless_network_create(ipw->hardware);
if (!ipw->network)
@@ -350,12 +354,16 @@ exit4:
pcmcia_disable_device(link);
exit3:
if (ipw->attr_memory) {
+ release_mem_region(ipw->request_attr_memory.Base,
+ ipw->request_attr_memory.Size);
iounmap(ipw->attr_memory);
pcmcia_release_window(ipw->handle_attr_memory);
pcmcia_disable_device(link);
}
exit2:
if (ipw->common_memory) {
+ release_mem_region(ipw->request_common_memory.Base,
+ ipw->request_common_memory.Size);
iounmap(ipw->common_memory);
pcmcia_release_window(ipw->handle_common_memory);
}
@@ -367,19 +375,25 @@ exit0:
static void release_ipwireless(struct ipw_dev *ipw)
{
- struct pcmcia_device *link = ipw->link;
-
- pcmcia_disable_device(link);
+ pcmcia_disable_device(ipw->link);
- if (ipw->common_memory)
+ if (ipw->common_memory) {
+ release_mem_region(ipw->request_common_memory.Base,
+ ipw->request_common_memory.Size);
iounmap(ipw->common_memory);
- if (ipw->attr_memory)
+ }
+ if (ipw->attr_memory) {
+ release_mem_region(ipw->request_attr_memory.Base,
+ ipw->request_attr_memory.Size);
iounmap(ipw->attr_memory);
+ }
if (ipw->common_memory)
pcmcia_release_window(ipw->handle_common_memory);
if (ipw->attr_memory)
pcmcia_release_window(ipw->handle_attr_memory);
- pcmcia_disable_device(link);
+
+ /* Break the link with Card Services */
+ pcmcia_disable_device(ipw->link);
}
/*
@@ -437,10 +451,6 @@ static void ipwireless_detach(struct pcmcia_device *link)
release_ipwireless(ipw);
- /* Break the link with Card Services */
- if (link)
- pcmcia_disable_device(link);
-
if (ipw->tty != NULL)
ipwireless_tty_free(ipw->tty);
if (ipw->network != NULL)
diff --git a/drivers/char/pcmcia/ipwireless/main.h b/drivers/char/pcmcia/ipwireless/main.h
index 1bfdcc8d47d..0e0363af9ab 100644
--- a/drivers/char/pcmcia/ipwireless/main.h
+++ b/drivers/char/pcmcia/ipwireless/main.h
@@ -45,10 +45,15 @@ struct ipw_tty;
struct ipw_dev {
struct pcmcia_device *link;
int is_v2_card;
+
window_handle_t handle_attr_memory;
void __iomem *attr_memory;
+ win_req_t request_attr_memory;
+
window_handle_t handle_common_memory;
void __iomem *common_memory;
+ win_req_t request_common_memory;
+
dev_node_t nodes[2];
/* Reference to attribute memory, containing CIS data */
void *attribute_memory;
diff --git a/drivers/char/pcmcia/ipwireless/network.c b/drivers/char/pcmcia/ipwireless/network.c
index fe914d34f7f..590762a7f21 100644
--- a/drivers/char/pcmcia/ipwireless/network.c
+++ b/drivers/char/pcmcia/ipwireless/network.c
@@ -29,7 +29,6 @@
#include "main.h"
#include "tty.h"
-#define MAX_OUTGOING_PACKETS_QUEUED ipwireless_out_queue
#define MAX_ASSOCIATED_TTYS 2
#define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP)
@@ -46,7 +45,7 @@ struct ipw_network {
/* Number of packets queued up in hardware module. */
int outgoing_packets_queued;
/* Spinlock to avoid interrupts during shutdown */
- spinlock_t spinlock;
+ spinlock_t lock;
struct mutex close_lock;
/* PPP ioctl data, not actually used anywere */
@@ -68,20 +67,20 @@ static void notify_packet_sent(void *callback_data, unsigned int packet_length)
struct ipw_network *network = callback_data;
unsigned long flags;
- spin_lock_irqsave(&network->spinlock, flags);
+ spin_lock_irqsave(&network->lock, flags);
network->outgoing_packets_queued--;
if (network->ppp_channel != NULL) {
if (network->ppp_blocked) {
network->ppp_blocked = 0;
- spin_unlock_irqrestore(&network->spinlock, flags);
+ spin_unlock_irqrestore(&network->lock, flags);
ppp_output_wakeup(network->ppp_channel);
if (ipwireless_debug)
- printk(KERN_INFO IPWIRELESS_PCCARD_NAME
+ printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME
": ppp unblocked\n");
} else
- spin_unlock_irqrestore(&network->spinlock, flags);
+ spin_unlock_irqrestore(&network->lock, flags);
} else
- spin_unlock_irqrestore(&network->spinlock, flags);
+ spin_unlock_irqrestore(&network->lock, flags);
}
/*
@@ -93,8 +92,8 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel,
struct ipw_network *network = ppp_channel->private;
unsigned long flags;
- spin_lock_irqsave(&network->spinlock, flags);
- if (network->outgoing_packets_queued < MAX_OUTGOING_PACKETS_QUEUED) {
+ spin_lock_irqsave(&network->lock, flags);
+ if (network->outgoing_packets_queued < ipwireless_out_queue) {
unsigned char *buf;
static unsigned char header[] = {
PPP_ALLSTATIONS, /* 0xff */
@@ -103,7 +102,7 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel,
int ret;
network->outgoing_packets_queued++;
- spin_unlock_irqrestore(&network->spinlock, flags);
+ spin_unlock_irqrestore(&network->lock, flags);
/*
* If we have the requested amount of headroom in the skb we
@@ -144,7 +143,9 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel,
* needs to be unblocked once we are ready to send.
*/
network->ppp_blocked = 1;
- spin_unlock_irqrestore(&network->spinlock, flags);
+ spin_unlock_irqrestore(&network->lock, flags);
+ if (ipwireless_debug)
+ printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": ppp blocked\n");
return 0;
}
}
@@ -249,11 +250,11 @@ static void do_go_online(struct work_struct *work_go_online)
work_go_online);
unsigned long flags;
- spin_lock_irqsave(&network->spinlock, flags);
+ spin_lock_irqsave(&network->lock, flags);
if (!network->ppp_channel) {
struct ppp_channel *channel;
- spin_unlock_irqrestore(&network->spinlock, flags);
+ spin_unlock_irqrestore(&network->lock, flags);
channel = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL);
if (!channel) {
printk(KERN_ERR IPWIRELESS_PCCARD_NAME
@@ -273,10 +274,10 @@ static void do_go_online(struct work_struct *work_go_online)
network->xaccm[3] = 0x60000000U;
network->raccm = ~0U;
ppp_register_channel(channel);
- spin_lock_irqsave(&network->spinlock, flags);
+ spin_lock_irqsave(&network->lock, flags);
network->ppp_channel = channel;
}
- spin_unlock_irqrestore(&network->spinlock, flags);
+ spin_unlock_irqrestore(&network->lock, flags);
}
static void do_go_offline(struct work_struct *work_go_offline)
@@ -287,16 +288,16 @@ static void do_go_offline(struct work_struct *work_go_offline)
unsigned long flags;
mutex_lock(&network->close_lock);
- spin_lock_irqsave(&network->spinlock, flags);
+ spin_lock_irqsave(&network->lock, flags);
if (network->ppp_channel != NULL) {
struct ppp_channel *channel = network->ppp_channel;
network->ppp_channel = NULL;
- spin_unlock_irqrestore(&network->spinlock, flags);
+ spin_unlock_irqrestore(&network->lock, flags);
mutex_unlock(&network->close_lock);
ppp_unregister_channel(channel);
} else {
- spin_unlock_irqrestore(&network->spinlock, flags);
+ spin_unlock_irqrestore(&network->lock, flags);
mutex_unlock(&network->close_lock);
}
}
@@ -381,18 +382,18 @@ void ipwireless_network_packet_received(struct ipw_network *network,
* the PPP layer.
*/
mutex_lock(&network->close_lock);
- spin_lock_irqsave(&network->spinlock, flags);
+ spin_lock_irqsave(&network->lock, flags);
if (network->ppp_channel != NULL) {
struct sk_buff *skb;
- spin_unlock_irqrestore(&network->spinlock,
+ spin_unlock_irqrestore(&network->lock,
flags);
/* Send the data to the ppp_generic module. */
skb = ipw_packet_received_skb(data, length);
ppp_input(network->ppp_channel, skb);
} else
- spin_unlock_irqrestore(&network->spinlock,
+ spin_unlock_irqrestore(&network->lock,
flags);
mutex_unlock(&network->close_lock);
}
@@ -410,7 +411,7 @@ struct ipw_network *ipwireless_network_create(struct ipw_hardware *hw)
if (!network)
return NULL;
- spin_lock_init(&network->spinlock);
+ spin_lock_init(&network->lock);
mutex_init(&network->close_lock);
network->hardware = hw;
@@ -478,10 +479,10 @@ int ipwireless_ppp_channel_index(struct ipw_network *network)
int ret = -1;
unsigned long flags;
- spin_lock_irqsave(&network->spinlock, flags);
+ spin_lock_irqsave(&network->lock, flags);
if (network->ppp_channel != NULL)
ret = ppp_channel_index(network->ppp_channel);
- spin_unlock_irqrestore(&network->spinlock, flags);
+ spin_unlock_irqrestore(&network->lock, flags);
return ret;
}
@@ -491,10 +492,15 @@ int ipwireless_ppp_unit_number(struct ipw_network *network)
int ret = -1;
unsigned long flags;
- spin_lock_irqsave(&network->spinlock, flags);
+ spin_lock_irqsave(&network->lock, flags);
if (network->ppp_channel != NULL)
ret = ppp_unit_number(network->ppp_channel);
- spin_unlock_irqrestore(&network->spinlock, flags);
+ spin_unlock_irqrestore(&network->lock, flags);
return ret;
}
+
+int ipwireless_ppp_mru(const struct ipw_network *network)
+{
+ return network->mru;
+}
diff --git a/drivers/char/pcmcia/ipwireless/network.h b/drivers/char/pcmcia/ipwireless/network.h
index ccacd26fc7e..561f765b333 100644
--- a/drivers/char/pcmcia/ipwireless/network.h
+++ b/drivers/char/pcmcia/ipwireless/network.h
@@ -48,5 +48,6 @@ void ipwireless_ppp_open(struct ipw_network *net);
void ipwireless_ppp_close(struct ipw_network *net);
int ipwireless_ppp_channel_index(struct ipw_network *net);
int ipwireless_ppp_unit_number(struct ipw_network *net);
+int ipwireless_ppp_mru(const struct ipw_network *net);
#endif
diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c
index 42f3815c5ce..b1414507997 100644
--- a/drivers/char/pcmcia/ipwireless/tty.c
+++ b/drivers/char/pcmcia/ipwireless/tty.c
@@ -259,7 +259,7 @@ static int ipw_write(struct tty_struct *linux_tty,
}
ret = ipwireless_send_packet(tty->hardware, IPW_CHANNEL_RAS,
- (unsigned char *) buf, count,
+ buf, count,
ipw_write_packet_sent_callback, tty);
if (ret == -1) {
mutex_unlock(&tty->ipw_tty_mutex);
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 5405769020a..5ce07b517c5 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -94,7 +94,7 @@ void cpuidle_install_idle_handler(void)
*/
void cpuidle_uninstall_idle_handler(void)
{
- if (enabled_devices && (pm_idle != pm_idle_old)) {
+ if (enabled_devices && pm_idle_old && (pm_idle != pm_idle_old)) {
pm_idle = pm_idle_old;
cpuidle_kick_cpus();
}
diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c
index 48d084bdf7c..3c855ff2992 100644
--- a/drivers/i2c/busses/i2c-bfin-twi.c
+++ b/drivers/i2c/busses/i2c-bfin-twi.c
@@ -49,6 +49,8 @@ struct bfin_twi_iface {
struct i2c_msg *pmsg;
int msg_num;
int cur_msg;
+ u16 saved_clkdiv;
+ u16 saved_control;
void __iomem *regs_base;
};
@@ -565,32 +567,43 @@ static u32 bfin_twi_functionality(struct i2c_adapter *adap)
I2C_FUNC_I2C;
}
-
static struct i2c_algorithm bfin_twi_algorithm = {
.master_xfer = bfin_twi_master_xfer,
.smbus_xfer = bfin_twi_smbus_xfer,
.functionality = bfin_twi_functionality,
};
-
-static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state)
+static int i2c_bfin_twi_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct bfin_twi_iface *iface = platform_get_drvdata(dev);
+ struct bfin_twi_iface *iface = platform_get_drvdata(pdev);
+
+ iface->saved_clkdiv = read_CLKDIV(iface);
+ iface->saved_control = read_CONTROL(iface);
+
+ free_irq(iface->irq, iface);
/* Disable TWI */
- write_CONTROL(iface, read_CONTROL(iface) & ~TWI_ENA);
- SSYNC();
+ write_CONTROL(iface, iface->saved_control & ~TWI_ENA);
return 0;
}
-static int i2c_bfin_twi_resume(struct platform_device *dev)
+static int i2c_bfin_twi_resume(struct platform_device *pdev)
{
- struct bfin_twi_iface *iface = platform_get_drvdata(dev);
+ struct bfin_twi_iface *iface = platform_get_drvdata(pdev);
- /* Enable TWI */
- write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA);
- SSYNC();
+ int rc = request_irq(iface->irq, bfin_twi_interrupt_entry,
+ IRQF_DISABLED, pdev->name, iface);
+ if (rc) {
+ dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq);
+ return -ENODEV;
+ }
+
+ /* Resume TWI interface clock as specified */
+ write_CLKDIV(iface, iface->saved_clkdiv);
+
+ /* Resume TWI */
+ write_CONTROL(iface, iface->saved_control);
return 0;
}
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index 79b455a1f09..32104eac8d3 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -77,7 +77,7 @@ static int i2c_gpio_getscl(void *data)
return gpio_get_value(pdata->scl_pin);
}
-static int __init i2c_gpio_probe(struct platform_device *pdev)
+static int __devinit i2c_gpio_probe(struct platform_device *pdev)
{
struct i2c_gpio_platform_data *pdata;
struct i2c_algo_bit_data *bit_data;
@@ -174,7 +174,7 @@ err_alloc_adap:
return ret;
}
-static int __exit i2c_gpio_remove(struct platform_device *pdev)
+static int __devexit i2c_gpio_remove(struct platform_device *pdev)
{
struct i2c_gpio_platform_data *pdata;
struct i2c_adapter *adap;
@@ -196,14 +196,15 @@ static struct platform_driver i2c_gpio_driver = {
.name = "i2c-gpio",
.owner = THIS_MODULE,
},
- .remove = __exit_p(i2c_gpio_remove),
+ .probe = i2c_gpio_probe,
+ .remove = __devexit_p(i2c_gpio_remove),
};
static int __init i2c_gpio_init(void)
{
int ret;
- ret = platform_driver_probe(&i2c_gpio_driver, i2c_gpio_probe);
+ ret = platform_driver_register(&i2c_gpio_driver);
if (ret)
printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret);
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 007390ad981..4864723c742 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -33,6 +33,7 @@
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
+#include <linux/cpufreq.h>
#include <asm/hardware.h>
#include <asm/irq.h>
@@ -64,6 +65,7 @@ struct s3c24xx_i2c {
unsigned int tx_setup;
enum s3c24xx_i2c_state state;
+ unsigned long clkrate;
void __iomem *regs;
struct clk *clk;
@@ -71,6 +73,10 @@ struct s3c24xx_i2c {
struct resource *irq;
struct resource *ioarea;
struct i2c_adapter adap;
+
+#ifdef CONFIG_CPU_FREQ
+ struct notifier_block freq_transition;
+#endif
};
/* default platform data to use if not supplied in the platform_device
@@ -501,6 +507,9 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, struct i2c_msg *msgs, int
unsigned long timeout;
int ret;
+ if (!readl(i2c->regs + S3C2410_IICCON) & S3C2410_IICCON_IRQEN)
+ return -EIO;
+
ret = s3c24xx_i2c_set_master(i2c);
if (ret != 0) {
dev_err(i2c->dev, "cannot get bus (error %d)\n", ret);
@@ -636,27 +645,28 @@ static inline int freq_acceptable(unsigned int freq, unsigned int wanted)
return (diff >= -2 && diff <= 2);
}
-/* s3c24xx_i2c_getdivisor
+/* s3c24xx_i2c_clockrate
*
* work out a divisor for the user requested frequency setting,
* either by the requested frequency, or scanning the acceptable
* range of frequencies until something is found
*/
-static int s3c24xx_i2c_getdivisor(struct s3c24xx_i2c *i2c,
- struct s3c2410_platform_i2c *pdata,
- unsigned long *iicon,
- unsigned int *got)
+static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
{
+ struct s3c2410_platform_i2c *pdata;
unsigned long clkin = clk_get_rate(i2c->clk);
-
unsigned int divs, div1;
+ u32 iiccon;
int freq;
int start, end;
+ i2c->clkrate = clkin;
+
+ pdata = s3c24xx_i2c_get_platformdata(i2c->adap.dev.parent);
clkin /= 1000; /* clkin now in KHz */
- dev_dbg(i2c->dev, "pdata %p, freq %lu %lu..%lu\n",
+ dev_dbg(i2c->dev, "pdata %p, freq %lu %lu..%lu\n",
pdata, pdata->bus_freq, pdata->min_freq, pdata->max_freq);
if (pdata->bus_freq != 0) {
@@ -688,11 +698,79 @@ static int s3c24xx_i2c_getdivisor(struct s3c24xx_i2c *i2c,
found:
*got = freq;
- *iicon |= (divs-1);
- *iicon |= (div1 == 512) ? S3C2410_IICCON_TXDIV_512 : 0;
+
+ iiccon = readl(i2c->regs + S3C2410_IICCON);
+ iiccon &= ~(S3C2410_IICCON_SCALEMASK | S3C2410_IICCON_TXDIV_512);
+ iiccon |= (divs-1);
+
+ if (div1 == 512)
+ iiccon |= S3C2410_IICCON_TXDIV_512;
+
+ writel(iiccon, i2c->regs + S3C2410_IICCON);
+
+ return 0;
+}
+
+#ifdef CONFIG_CPU_FREQ
+
+#define freq_to_i2c(_n) container_of(_n, struct s3c24xx_i2c, freq_transition)
+
+static int s3c24xx_i2c_cpufreq_transition(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ struct s3c24xx_i2c *i2c = freq_to_i2c(nb);
+ unsigned long flags;
+ unsigned int got;
+ int delta_f;
+ int ret;
+
+ delta_f = clk_get_rate(i2c->clk) - i2c->clkrate;
+
+ /* if we're post-change and the input clock has slowed down
+ * or at pre-change and the clock is about to speed up, then
+ * adjust our clock rate. <0 is slow, >0 speedup.
+ */
+
+ if ((val == CPUFREQ_POSTCHANGE && delta_f < 0) ||
+ (val == CPUFREQ_PRECHANGE && delta_f > 0)) {
+ spin_lock_irqsave(&i2c->lock, flags);
+ ret = s3c24xx_i2c_clockrate(i2c, &got);
+ spin_unlock_irqrestore(&i2c->lock, flags);
+
+ if (ret < 0)
+ dev_err(i2c->dev, "cannot find frequency\n");
+ else
+ dev_info(i2c->dev, "setting freq %d\n", got);
+ }
+
+ return 0;
+}
+
+static inline int s3c24xx_i2c_register_cpufreq(struct s3c24xx_i2c *i2c)
+{
+ i2c->freq_transition.notifier_call = s3c24xx_i2c_cpufreq_transition;
+
+ return cpufreq_register_notifier(&i2c->freq_transition,
+ CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+static inline void s3c24xx_i2c_deregister_cpufreq(struct s3c24xx_i2c *i2c)
+{
+ cpufreq_unregister_notifier(&i2c->freq_transition,
+ CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+#else
+static inline int s3c24xx_i2c_register_cpufreq(struct s3c24xx_i2c *i2c)
+{
return 0;
}
+static inline void s3c24xx_i2c_deregister_cpufreq(struct s3c24xx_i2c *i2c)
+{
+}
+#endif
+
/* s3c24xx_i2c_init
*
* initialise the controller, set the IO lines and frequency
@@ -719,9 +797,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr);
+ writel(iicon, i2c->regs + S3C2410_IICCON);
+
/* we need to work out the divisors for the clock... */
- if (s3c24xx_i2c_getdivisor(i2c, pdata, &iicon, &freq) != 0) {
+ if (s3c24xx_i2c_clockrate(i2c, &freq) != 0) {
+ writel(0, i2c->regs + S3C2410_IICCON);
dev_err(i2c->dev, "cannot meet bus frequency required\n");
return -EINVAL;
}
@@ -730,8 +811,6 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq);
dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon);
-
- writel(iicon, i2c->regs + S3C2410_IICCON);
/* check for s3c2440 i2c controller */
@@ -752,9 +831,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
static int s3c24xx_i2c_probe(struct platform_device *pdev)
{
struct s3c24xx_i2c *i2c = &s3c24xx_i2c;
+ struct s3c2410_platform_i2c *pdata;
struct resource *res;
int ret;
+ pdata = s3c24xx_i2c_get_platformdata(&pdev->dev);
+
/* find the clock and enable it */
i2c->dev = &pdev->dev;
@@ -832,17 +914,34 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res,
(unsigned long)res->start);
- ret = i2c_add_adapter(&i2c->adap);
+ ret = s3c24xx_i2c_register_cpufreq(i2c);
if (ret < 0) {
- dev_err(&pdev->dev, "failed to add bus to i2c core\n");
+ dev_err(&pdev->dev, "failed to register cpufreq notifier\n");
goto err_irq;
}
+ /* Note, previous versions of the driver used i2c_add_adapter()
+ * to add the bus at any number. We now pass the bus number via
+ * the platform data, so if unset it will now default to always
+ * being bus 0.
+ */
+
+ i2c->adap.nr = pdata->bus_num;
+
+ ret = i2c_add_numbered_adapter(&i2c->adap);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to add bus to i2c core\n");
+ goto err_cpufreq;
+ }
+
platform_set_drvdata(pdev, i2c);
dev_info(&pdev->dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id);
return 0;
+ err_cpufreq:
+ s3c24xx_i2c_deregister_cpufreq(i2c);
+
err_irq:
free_irq(i2c->irq->start, i2c);
@@ -870,6 +969,8 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)
{
struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
+ s3c24xx_i2c_deregister_cpufreq(i2c);
+
i2c_del_adapter(&i2c->adap);
free_irq(i2c->irq->start, i2c);
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index 8486abc457e..c600ab7f93e 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -158,25 +158,18 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata));
pdata = &priv->pdata;
- res = request_mem_region(res->start, res_size(res), pdev->name);
- if (res == NULL) {
- dev_err(&pdev->dev, "failed to request I/O memory\n");
- error = -EBUSY;
- goto err1;
- }
-
priv->iomem_base = ioremap_nocache(res->start, res_size(res));
if (priv->iomem_base == NULL) {
dev_err(&pdev->dev, "failed to remap I/O memory\n");
error = -ENXIO;
- goto err2;
+ goto err1;
}
priv->input = input_allocate_device();
if (!priv->input) {
dev_err(&pdev->dev, "failed to allocate input device\n");
error = -ENOMEM;
- goto err3;
+ goto err2;
}
input = priv->input;
@@ -194,7 +187,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev);
if (error) {
dev_err(&pdev->dev, "failed to request IRQ\n");
- goto err4;
+ goto err3;
}
for (i = 0; i < SH_KEYSC_MAXKEYS; i++) {
@@ -206,7 +199,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
error = input_register_device(input);
if (error) {
dev_err(&pdev->dev, "failed to register input device\n");
- goto err5;
+ goto err4;
}
iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) |
@@ -214,14 +207,12 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
iowrite16(0, priv->iomem_base + KYOUTDR_OFFS);
iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS);
return 0;
- err5:
- free_irq(irq, pdev);
err4:
- input_free_device(input);
+ free_irq(irq, pdev);
err3:
- iounmap(priv->iomem_base);
+ input_free_device(input);
err2:
- release_mem_region(res->start, res_size(res));
+ iounmap(priv->iomem_base);
err1:
platform_set_drvdata(pdev, NULL);
kfree(priv);
@@ -232,7 +223,6 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
static int __devexit sh_keysc_remove(struct platform_device *pdev)
{
struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
- struct resource *res;
iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS);
@@ -240,9 +230,6 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev)
free_irq(platform_get_irq(pdev, 0), pdev);
iounmap(priv->iomem_base);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, res_size(res));
-
platform_set_drvdata(pdev, NULL);
kfree(priv);
return 0;
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 2bcfa0b3506..223d56d5555 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -37,7 +37,6 @@
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/uinput.h>
-#include <linux/smp_lock.h>
static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 78f2abb5c11..2f12d60eee3 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -63,8 +63,9 @@ static LIST_HEAD(serio_list);
static struct bus_type serio_bus;
static void serio_add_port(struct serio *serio);
-static void serio_reconnect_port(struct serio *serio);
+static int serio_reconnect_port(struct serio *serio);
static void serio_disconnect_port(struct serio *serio);
+static void serio_reconnect_chain(struct serio *serio);
static void serio_attach_driver(struct serio_driver *drv);
static int serio_connect_driver(struct serio *serio, struct serio_driver *drv)
@@ -161,6 +162,7 @@ static void serio_find_driver(struct serio *serio)
enum serio_event_type {
SERIO_RESCAN_PORT,
SERIO_RECONNECT_PORT,
+ SERIO_RECONNECT_CHAIN,
SERIO_REGISTER_PORT,
SERIO_ATTACH_DRIVER,
};
@@ -315,6 +317,10 @@ static void serio_handle_event(void)
serio_find_driver(event->object);
break;
+ case SERIO_RECONNECT_CHAIN:
+ serio_reconnect_chain(event->object);
+ break;
+
case SERIO_ATTACH_DRIVER:
serio_attach_driver(event->object);
break;
@@ -470,7 +476,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *
if (!strncmp(buf, "none", count)) {
serio_disconnect_port(serio);
} else if (!strncmp(buf, "reconnect", count)) {
- serio_reconnect_port(serio);
+ serio_reconnect_chain(serio);
} else if (!strncmp(buf, "rescan", count)) {
serio_disconnect_port(serio);
serio_find_driver(serio);
@@ -620,14 +626,30 @@ static void serio_destroy_port(struct serio *serio)
}
/*
+ * Reconnect serio port (re-initialize attached device).
+ * If reconnect fails (old device is no longer attached or
+ * there was no device to begin with) we do full rescan in
+ * hope of finding a driver for the port.
+ */
+static int serio_reconnect_port(struct serio *serio)
+{
+ int error = serio_reconnect_driver(serio);
+
+ if (error) {
+ serio_disconnect_port(serio);
+ serio_find_driver(serio);
+ }
+
+ return error;
+}
+
+/*
* Reconnect serio port and all its children (re-initialize attached devices)
*/
-static void serio_reconnect_port(struct serio *serio)
+static void serio_reconnect_chain(struct serio *serio)
{
do {
- if (serio_reconnect_driver(serio)) {
- serio_disconnect_port(serio);
- serio_find_driver(serio);
+ if (serio_reconnect_port(serio)) {
/* Ok, old children are now gone, we are done */
break;
}
@@ -673,7 +695,7 @@ void serio_rescan(struct serio *serio)
void serio_reconnect(struct serio *serio)
{
- serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT);
+ serio_queue_event(serio, NULL, SERIO_RECONNECT_CHAIN);
}
/*
@@ -927,19 +949,16 @@ static int serio_suspend(struct device *dev, pm_message_t state)
static int serio_resume(struct device *dev)
{
- struct serio *serio = to_serio_port(dev);
-
- if (dev->power.power_state.event != PM_EVENT_ON &&
- serio_reconnect_driver(serio)) {
- /*
- * Driver re-probing can take a while, so better let kseriod
- * deal with it.
- */
- serio_rescan(serio);
+ /*
+ * Driver reconnect can take a while, so better let kseriod
+ * deal with it.
+ */
+ if (dev->power.power_state.event != PM_EVENT_ON) {
+ dev->power.power_state = PMSG_ON;
+ serio_queue_event(to_serio_port(dev), NULL,
+ SERIO_RECONNECT_PORT);
}
- dev->power.power_state = PMSG_ON;
-
return 0;
}
#endif /* CONFIG_PM */
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index e5736652157..6e60a97a234 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -205,6 +205,18 @@ config TOUCHSCREEN_TOUCHWIN
To compile this driver as a module, choose M here: the
module will be called touchwin.
+config TOUCHSCREEN_ATMEL_TSADCC
+ tristate "Atmel Touchscreen Interface"
+ depends on ARCH_AT91SAM9RL
+ help
+ Say Y here if you have a 4-wire touchscreen connected to the
+ ADC Controller on your Atmel SoC (such as the AT91SAM9RL).
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called atmel_tsadcc.
+
config TOUCHSCREEN_UCB1400
tristate "Philips UCB1400 touchscreen"
select AC97_BUS
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 39a804cd80f..15cf2907948 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -7,6 +7,7 @@
wm97xx-ts-y := wm97xx-core.o
obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
+obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o
obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 907a45fe9d4..ce6f48c695f 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -517,7 +517,9 @@ static void ads7846_rx(void *ads)
if (x == MAX_12BIT)
x = 0;
- if (likely(x && z1)) {
+ if (ts->model == 7843) {
+ Rt = ts->pressure_max / 2;
+ } else if (likely(x && z1)) {
/* compute touch pressure resistance using equation #2 */
Rt = z2;
Rt -= z1;
@@ -525,11 +527,9 @@ static void ads7846_rx(void *ads)
Rt *= ts->x_plate_ohms;
Rt /= z1;
Rt = (Rt + 2047) >> 12;
- } else
+ } else {
Rt = 0;
-
- if (ts->model == 7843)
- Rt = ts->pressure_max / 2;
+ }
/* Sample found inconsistent by debouncing or pressure is beyond
* the maximum. Don't report it to user space, repeat at least
@@ -633,19 +633,17 @@ static void ads7846_rx_val(void *ads)
struct ads7846 *ts = ads;
struct spi_message *m;
struct spi_transfer *t;
- u16 *rx_val;
int val;
int action;
int status;
m = &ts->msg[ts->msg_idx];
t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
- rx_val = t->rx_buf;
/* adjust: on-wire is a must-ignore bit, a BE12 value, then padding;
* built from two 8 bit values written msb-first.
*/
- val = be16_to_cpu(*rx_val) >> 3;
+ val = be16_to_cpup((__be16 *)t->rx_buf) >> 3;
action = ts->filter(ts->filter_data, ts->msg_idx, &val);
switch (action) {
@@ -659,7 +657,7 @@ static void ads7846_rx_val(void *ads)
m = ts->last_msg;
break;
case ADS7846_FILTER_OK:
- *rx_val = val;
+ *(u16 *)t->rx_buf = val;
ts->tc.ignore = 0;
m = &ts->msg[++ts->msg_idx];
break;
diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c
new file mode 100644
index 00000000000..eee126b19e8
--- /dev/null
+++ b/drivers/input/touchscreen/atmel_tsadcc.c
@@ -0,0 +1,332 @@
+/*
+ * Atmel Touch Screen Driver
+ *
+ * Copyright (c) 2008 ATMEL
+ * Copyright (c) 2008 Dan Liang
+ * Copyright (c) 2008 TimeSys Corporation
+ * Copyright (c) 2008 Justin Waters
+ *
+ * Based on touchscreen code from Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+/* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */
+
+#define ATMEL_TSADCC_CR 0x00 /* Control register */
+#define ATMEL_TSADCC_SWRST (1 << 0) /* Software Reset*/
+#define ATMEL_TSADCC_START (1 << 1) /* Start conversion */
+
+#define ATMEL_TSADCC_MR 0x04 /* Mode register */
+#define ATMEL_TSADCC_TSAMOD (3 << 0) /* ADC mode */
+#define ATMEL_TSADCC_TSAMOD_ADC_ONLY_MODE (0x0) /* ADC Mode */
+#define ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE (0x1) /* Touch Screen Only Mode */
+#define ATMEL_TSADCC_LOWRES (1 << 4) /* Resolution selection */
+#define ATMEL_TSADCC_SLEEP (1 << 5) /* Sleep mode */
+#define ATMEL_TSADCC_PENDET (1 << 6) /* Pen Detect selection */
+#define ATMEL_TSADCC_PRESCAL (0x3f << 8) /* Prescalar Rate Selection */
+#define ATMEL_TSADCC_STARTUP (0x7f << 16) /* Start Up time */
+#define ATMEL_TSADCC_SHTIM (0xf << 24) /* Sample & Hold time */
+#define ATMEL_TSADCC_PENDBC (0xf << 28) /* Pen Detect debouncing time */
+
+#define ATMEL_TSADCC_TRGR 0x08 /* Trigger register */
+#define ATMEL_TSADCC_TRGMOD (7 << 0) /* Trigger mode */
+#define ATMEL_TSADCC_TRGMOD_NONE (0 << 0)
+#define ATMEL_TSADCC_TRGMOD_EXT_RISING (1 << 0)
+#define ATMEL_TSADCC_TRGMOD_EXT_FALLING (2 << 0)
+#define ATMEL_TSADCC_TRGMOD_EXT_ANY (3 << 0)
+#define ATMEL_TSADCC_TRGMOD_PENDET (4 << 0)
+#define ATMEL_TSADCC_TRGMOD_PERIOD (5 << 0)
+#define ATMEL_TSADCC_TRGMOD_CONTINUOUS (6 << 0)
+#define ATMEL_TSADCC_TRGPER (0xffff << 16) /* Trigger period */
+
+#define ATMEL_TSADCC_TSR 0x0C /* Touch Screen register */
+#define ATMEL_TSADCC_TSFREQ (0xf << 0) /* TS Frequency in Interleaved mode */
+#define ATMEL_TSADCC_TSSHTIM (0xf << 24) /* Sample & Hold time */
+
+#define ATMEL_TSADCC_CHER 0x10 /* Channel Enable register */
+#define ATMEL_TSADCC_CHDR 0x14 /* Channel Disable register */
+#define ATMEL_TSADCC_CHSR 0x18 /* Channel Status register */
+#define ATMEL_TSADCC_CH(n) (1 << (n)) /* Channel number */
+
+#define ATMEL_TSADCC_SR 0x1C /* Status register */
+#define ATMEL_TSADCC_EOC(n) (1 << ((n)+0)) /* End of conversion for channel N */
+#define ATMEL_TSADCC_OVRE(n) (1 << ((n)+8)) /* Overrun error for channel N */
+#define ATMEL_TSADCC_DRDY (1 << 16) /* Data Ready */
+#define ATMEL_TSADCC_GOVRE (1 << 17) /* General Overrun Error */
+#define ATMEL_TSADCC_ENDRX (1 << 18) /* End of RX Buffer */
+#define ATMEL_TSADCC_RXBUFF (1 << 19) /* TX Buffer full */
+#define ATMEL_TSADCC_PENCNT (1 << 20) /* Pen contact */
+#define ATMEL_TSADCC_NOCNT (1 << 21) /* No contact */
+
+#define ATMEL_TSADCC_LCDR 0x20 /* Last Converted Data register */
+#define ATMEL_TSADCC_DATA (0x3ff << 0) /* Channel data */
+
+#define ATMEL_TSADCC_IER 0x24 /* Interrupt Enable register */
+#define ATMEL_TSADCC_IDR 0x28 /* Interrupt Disable register */
+#define ATMEL_TSADCC_IMR 0x2C /* Interrupt Mask register */
+#define ATMEL_TSADCC_CDR0 0x30 /* Channel Data 0 */
+#define ATMEL_TSADCC_CDR1 0x34 /* Channel Data 1 */
+#define ATMEL_TSADCC_CDR2 0x38 /* Channel Data 2 */
+#define ATMEL_TSADCC_CDR3 0x3C /* Channel Data 3 */
+#define ATMEL_TSADCC_CDR4 0x40 /* Channel Data 4 */
+#define ATMEL_TSADCC_CDR5 0x44 /* Channel Data 5 */
+
+#define ADC_CLOCK 1000000
+
+struct atmel_tsadcc {
+ struct input_dev *input;
+ char phys[32];
+ struct clk *clk;
+ int irq;
+};
+
+static void __iomem *tsc_base;
+
+#define atmel_tsadcc_read(reg) __raw_readl(tsc_base + (reg))
+#define atmel_tsadcc_write(reg, val) __raw_writel((val), tsc_base + (reg))
+
+static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
+{
+ struct input_dev *input_dev = ((struct atmel_tsadcc *)dev)->input;
+
+ unsigned int absx;
+ unsigned int absy;
+ unsigned int status;
+ unsigned int reg;
+
+ status = atmel_tsadcc_read(ATMEL_TSADCC_SR);
+ status &= atmel_tsadcc_read(ATMEL_TSADCC_IMR);
+
+ if (status & ATMEL_TSADCC_NOCNT) {
+ /* Contact lost */
+ reg = atmel_tsadcc_read(ATMEL_TSADCC_MR) | ATMEL_TSADCC_PENDBC;
+
+ atmel_tsadcc_write(ATMEL_TSADCC_MR, reg);
+ atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE);
+ atmel_tsadcc_write(ATMEL_TSADCC_IDR,
+ ATMEL_TSADCC_EOC(3) | ATMEL_TSADCC_NOCNT);
+ atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
+
+ input_report_key(input_dev, BTN_TOUCH, 0);
+ input_sync(input_dev);
+
+ } else if (status & ATMEL_TSADCC_PENCNT) {
+ /* Pen detected */
+ reg = atmel_tsadcc_read(ATMEL_TSADCC_MR);
+ reg &= ~ATMEL_TSADCC_PENDBC;
+
+ atmel_tsadcc_write(ATMEL_TSADCC_IDR, ATMEL_TSADCC_PENCNT);
+ atmel_tsadcc_write(ATMEL_TSADCC_MR, reg);
+ atmel_tsadcc_write(ATMEL_TSADCC_IER,
+ ATMEL_TSADCC_EOC(3) | ATMEL_TSADCC_NOCNT);
+ atmel_tsadcc_write(ATMEL_TSADCC_TRGR,
+ ATMEL_TSADCC_TRGMOD_PERIOD | (0x0FFF << 16));
+
+ } else if (status & ATMEL_TSADCC_EOC(3)) {
+ /* Conversion finished */
+
+ absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10;
+ absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2);
+
+ absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10;
+ absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0);
+
+ input_report_abs(input_dev, ABS_X, absx);
+ input_report_abs(input_dev, ABS_Y, absy);
+ input_report_key(input_dev, BTN_TOUCH, 1);
+ input_sync(input_dev);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
+{
+ struct atmel_tsadcc *ts_dev;
+ struct input_dev *input_dev;
+ struct resource *res;
+ int err = 0;
+ unsigned int prsc;
+ unsigned int reg;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "no mmio resource defined.\n");
+ return -ENXIO;
+ }
+
+ /* Allocate memory for device */
+ ts_dev = kzalloc(sizeof(struct atmel_tsadcc), GFP_KERNEL);
+ if (!ts_dev) {
+ dev_err(&pdev->dev, "failed to allocate memory.\n");
+ return -ENOMEM;
+ }
+ platform_set_drvdata(pdev, ts_dev);
+
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ dev_err(&pdev->dev, "failed to allocate input device.\n");
+ err = -EBUSY;
+ goto err_free_mem;
+ }
+
+ ts_dev->irq = platform_get_irq(pdev, 0);
+ if (ts_dev->irq < 0) {
+ dev_err(&pdev->dev, "no irq ID is designated.\n");
+ err = -ENODEV;
+ goto err_free_dev;
+ }
+
+ if (!request_mem_region(res->start, res->end - res->start + 1,
+ "atmel tsadcc regs")) {
+ dev_err(&pdev->dev, "resources is unavailable.\n");
+ err = -EBUSY;
+ goto err_free_dev;
+ }
+
+ tsc_base = ioremap(res->start, res->end - res->start + 1);
+ if (!tsc_base) {
+ dev_err(&pdev->dev, "failed to map registers.\n");
+ err = -ENOMEM;
+ goto err_release_mem;
+ }
+
+ err = request_irq(ts_dev->irq, atmel_tsadcc_interrupt, IRQF_DISABLED,
+ pdev->dev.driver->name, ts_dev);
+ if (err) {
+ dev_err(&pdev->dev, "failed to allocate irq.\n");
+ goto err_unmap_regs;
+ }
+
+ ts_dev->clk = clk_get(&pdev->dev, "tsc_clk");
+ if (IS_ERR(ts_dev->clk)) {
+ dev_err(&pdev->dev, "failed to get ts_clk\n");
+ err = PTR_ERR(ts_dev->clk);
+ goto err_free_irq;
+ }
+
+ ts_dev->input = input_dev;
+
+ snprintf(ts_dev->phys, sizeof(ts_dev->phys),
+ "%s/input0", pdev->dev.bus_id);
+
+ input_dev->name = "atmel touch screen controller";
+ input_dev->phys = ts_dev->phys;
+ input_dev->dev.parent = &pdev->dev;
+
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+
+ input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0);
+
+ /* clk_enable() always returns 0, no need to check it */
+ clk_enable(ts_dev->clk);
+
+ prsc = clk_get_rate(ts_dev->clk);
+ dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc);
+
+ prsc = prsc / ADC_CLOCK / 2 - 1;
+
+ reg = ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE |
+ ((0x00 << 5) & ATMEL_TSADCC_SLEEP) | /* Normal Mode */
+ ((0x01 << 6) & ATMEL_TSADCC_PENDET) | /* Enable Pen Detect */
+ ((prsc << 8) & ATMEL_TSADCC_PRESCAL) | /* PRESCAL */
+ ((0x13 << 16) & ATMEL_TSADCC_STARTUP) | /* STARTUP */
+ ((0x0F << 28) & ATMEL_TSADCC_PENDBC); /* PENDBC */
+
+ atmel_tsadcc_write(ATMEL_TSADCC_CR, ATMEL_TSADCC_SWRST);
+ atmel_tsadcc_write(ATMEL_TSADCC_MR, reg);
+ atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE);
+ atmel_tsadcc_write(ATMEL_TSADCC_TSR, (0x3 << 24) & ATMEL_TSADCC_TSSHTIM);
+
+ atmel_tsadcc_read(ATMEL_TSADCC_SR);
+ atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
+
+ /* All went ok, so register to the input system */
+ err = input_register_device(input_dev);
+ if (err)
+ goto err_fail;
+
+ return 0;
+
+err_fail:
+ clk_disable(ts_dev->clk);
+ clk_put(ts_dev->clk);
+err_free_irq:
+ free_irq(ts_dev->irq, ts_dev);
+err_unmap_regs:
+ iounmap(tsc_base);
+err_release_mem:
+ release_mem_region(res->start, res->end - res->start + 1);
+err_free_dev:
+ input_free_device(ts_dev->input);
+err_free_mem:
+ kfree(ts_dev);
+ return err;
+}
+
+static int __devexit atmel_tsadcc_remove(struct platform_device *pdev)
+{
+ struct atmel_tsadcc *ts_dev = dev_get_drvdata(&pdev->dev);
+ struct resource *res;
+
+ free_irq(ts_dev->irq, ts_dev);
+
+ input_unregister_device(ts_dev->input);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ iounmap(tsc_base);
+ release_mem_region(res->start, res->end - res->start + 1);
+
+ clk_disable(ts_dev->clk);
+ clk_put(ts_dev->clk);
+
+ kfree(ts_dev);
+
+ return 0;
+}
+
+static struct platform_driver atmel_tsadcc_driver = {
+ .probe = atmel_tsadcc_probe,
+ .remove = __devexit_p(atmel_tsadcc_remove),
+ .driver = {
+ .name = "atmel_tsadcc",
+ },
+};
+
+static int __init atmel_tsadcc_init(void)
+{
+ return platform_driver_register(&atmel_tsadcc_driver);
+}
+
+static void __exit atmel_tsadcc_exit(void)
+{
+ platform_driver_unregister(&atmel_tsadcc_driver);
+}
+
+module_init(atmel_tsadcc_init);
+module_exit(atmel_tsadcc_exit);
+
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Atmel TouchScreen Driver");
+MODULE_AUTHOR("Dan Liang <dan.liang@atmel.com>");
+
diff --git a/drivers/isdn/hardware/mISDN/Kconfig b/drivers/isdn/hardware/mISDN/Kconfig
index 9cd5f5f6228..14793480c45 100644
--- a/drivers/isdn/hardware/mISDN/Kconfig
+++ b/drivers/isdn/hardware/mISDN/Kconfig
@@ -7,7 +7,6 @@ config MISDN_HFCPCI
tristate "Support for HFC PCI cards"
depends on MISDN
depends on PCI
- depends on VIRT_TO_BUS
help
Enable support for cards with Cologne Chip AG's
HFC PCI chip.
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index 917968530e1..3231814e7ef 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -1988,8 +1988,7 @@ setup_hw(struct hfc_pci *hc)
printk(KERN_INFO
"HFC-PCI: defined at mem %#lx fifo %#lx(%#lx) IRQ %d HZ %d\n",
(u_long) hc->hw.pci_io, (u_long) hc->hw.fifos,
- (u_long) virt_to_bus(hc->hw.fifos),
- hc->irq, HZ);
+ (u_long) hc->hw.dmahandle, hc->irq, HZ);
/* enable memory mapped ports, disable busmaster */
pci_write_config_word(hc->pdev, PCI_COMMAND, PCI_ENA_MEMIO);
hc->hw.int_m2 = 0;
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index 171afe7da6b..cf6a817d505 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -563,7 +563,7 @@ int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev
DEB_EE(("dev:%p\n",dev));
- if( VFL_TYPE_GRABBER == (*vid)->type ) {
+ if ((*vid)->vfl_type == VFL_TYPE_GRABBER) {
vv->video_minor = -1;
} else {
vv->vbi_minor = -1;
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index a5e62750eea..e8bc7abf240 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -656,7 +656,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu
/* if we have a user buffer, the first page may not be
aligned to a page boundary. */
- pt1->offset = list->offset;
+ pt1->offset = dma->sglist->offset;
pt2->offset = pt1->offset+o1;
pt3->offset = pt1->offset+o2;
@@ -958,21 +958,18 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
case VIDIOC_ENUM_FMT:
{
struct v4l2_fmtdesc *f = arg;
- int index;
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- case V4L2_BUF_TYPE_VIDEO_OVERLAY: {
- index = f->index;
- if (index < 0 || index >= NUM_FORMATS) {
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ if (f->index >= NUM_FORMATS)
return -EINVAL;
- }
- memset(f,0,sizeof(*f));
- f->index = index;
- strlcpy((char *)f->description,formats[index].name,sizeof(f->description));
- f->pixelformat = formats[index].pixelformat;
+ strlcpy((char *)f->description, formats[f->index].name,
+ sizeof(f->description));
+ f->pixelformat = formats[f->index].pixelformat;
+ f->flags = 0;
+ memset(f->reserved, 0, sizeof(f->reserved));
break;
- }
default:
return -EINVAL;
}
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 850d5689b14..6f92beaa5ac 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -21,9 +21,8 @@ config MEDIA_TUNER
tristate
default VIDEO_MEDIA && I2C
depends on VIDEO_MEDIA && I2C
- select FW_LOADER if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
- select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
- select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
+ select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE
select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE
select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE
select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE
@@ -138,8 +137,6 @@ config MEDIA_TUNER_QT1010
config MEDIA_TUNER_XC2028
tristate "XCeive xc2028/xc3028 tuners"
depends on VIDEO_MEDIA && I2C
- depends on HOTPLUG
- select FW_LOADER
default m if MEDIA_TUNER_CUSTOMIZE
help
Say Y here to include support for the xc2028/xc3028 tuners.
@@ -147,8 +144,6 @@ config MEDIA_TUNER_XC2028
config MEDIA_TUNER_XC5000
tristate "Xceive XC5000 silicon tuner"
depends on VIDEO_MEDIA && I2C
- depends on HOTPLUG
- select FW_LOADER
default m if DVB_FE_CUSTOMISE
help
A driver for the silicon tuner XC5000 from Xceive.
@@ -162,4 +157,11 @@ config MEDIA_TUNER_MXL5005S
help
A driver for the silicon tuner MXL5005S from MaxLinear.
+config MEDIA_TUNER_MXL5007T
+ tristate "MaxLinear MxL5007T silicon tuner"
+ depends on VIDEO_MEDIA && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A driver for the silicon tuner MxL5007T from MaxLinear.
+
endif # MEDIA_TUNER_CUSTOMIZE
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index 55f7e670629..4dfbe5b8264 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
+obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/common/tuners/mt20xx.c b/drivers/media/common/tuners/mt20xx.c
index fbcb2823373..35b763a16d5 100644
--- a/drivers/media/common/tuners/mt20xx.c
+++ b/drivers/media/common/tuners/mt20xx.c
@@ -148,7 +148,8 @@ static int mt2032_compute_freq(struct dvb_frontend *fe,
tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
- if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) {
+ if (lo1a > 7 || lo1n < 17 || lo1n > 48 || lo2a > 7 || lo2n < 17 ||
+ lo2n > 30) {
tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
lo1a, lo1n, lo2a,lo2n);
return(-1);
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c
new file mode 100644
index 00000000000..cb25e43502f
--- /dev/null
+++ b/drivers/media/common/tuners/mxl5007t.c
@@ -0,0 +1,1030 @@
+/*
+ * mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner
+ *
+ * Copyright (C) 2008 Michael Krufky <mkrufky@linuxtv.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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/i2c.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>
+#include "tuner-i2c.h"
+#include "mxl5007t.h"
+
+static DEFINE_MUTEX(mxl5007t_list_mutex);
+static LIST_HEAD(hybrid_tuner_instance_list);
+
+static int mxl5007t_debug;
+module_param_named(debug, mxl5007t_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level");
+
+/* ------------------------------------------------------------------------- */
+
+#define mxl_printk(kern, fmt, arg...) \
+ printk(kern "%s: " fmt "\n", __func__, ##arg)
+
+#define mxl_err(fmt, arg...) \
+ mxl_printk(KERN_ERR, "%d: " fmt, __LINE__, ##arg)
+
+#define mxl_warn(fmt, arg...) \
+ mxl_printk(KERN_WARNING, fmt, ##arg)
+
+#define mxl_info(fmt, arg...) \
+ mxl_printk(KERN_INFO, fmt, ##arg)
+
+#define mxl_debug(fmt, arg...) \
+({ \
+ if (mxl5007t_debug) \
+ mxl_printk(KERN_DEBUG, fmt, ##arg); \
+})
+
+#define mxl_fail(ret) \
+({ \
+ int __ret; \
+ __ret = (ret < 0); \
+ if (__ret) \
+ mxl_printk(KERN_ERR, "error %d on line %d", \
+ ret, __LINE__); \
+ __ret; \
+})
+
+/* ------------------------------------------------------------------------- */
+
+#define MHz 1000000
+
+enum mxl5007t_mode {
+ MxL_MODE_OTA_DVBT_ATSC = 0,
+ MxL_MODE_OTA_NTSC_PAL_GH = 1,
+ MxL_MODE_OTA_PAL_IB = 2,
+ MxL_MODE_OTA_PAL_D_SECAM_KL = 3,
+ MxL_MODE_OTA_ISDBT = 4,
+ MxL_MODE_CABLE_DIGITAL = 0x10,
+ MxL_MODE_CABLE_NTSC_PAL_GH = 0x11,
+ MxL_MODE_CABLE_PAL_IB = 0x12,
+ MxL_MODE_CABLE_PAL_D_SECAM_KL = 0x13,
+ MxL_MODE_CABLE_SCTE40 = 0x14,
+};
+
+enum mxl5007t_chip_version {
+ MxL_UNKNOWN_ID = 0x00,
+ MxL_5007_V1_F1 = 0x11,
+ MxL_5007_V1_F2 = 0x12,
+ MxL_5007_V2_100_F1 = 0x21,
+ MxL_5007_V2_100_F2 = 0x22,
+ MxL_5007_V2_200_F1 = 0x23,
+ MxL_5007_V2_200_F2 = 0x24,
+};
+
+struct reg_pair_t {
+ u8 reg;
+ u8 val;
+};
+
+/* ------------------------------------------------------------------------- */
+
+static struct reg_pair_t init_tab[] = {
+ { 0x0b, 0x44 }, /* XTAL */
+ { 0x0c, 0x60 }, /* IF */
+ { 0x10, 0x00 }, /* MISC */
+ { 0x12, 0xca }, /* IDAC */
+ { 0x16, 0x90 }, /* MODE */
+ { 0x32, 0x38 }, /* MODE Analog/Digital */
+ { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */
+ { 0x2c, 0x34 }, /* OVERRIDE */
+ { 0x4d, 0x40 }, /* OVERRIDE */
+ { 0x7f, 0x02 }, /* OVERRIDE */
+ { 0x9a, 0x52 }, /* OVERRIDE */
+ { 0x48, 0x5a }, /* OVERRIDE */
+ { 0x76, 0x1a }, /* OVERRIDE */
+ { 0x6a, 0x48 }, /* OVERRIDE */
+ { 0x64, 0x28 }, /* OVERRIDE */
+ { 0x66, 0xe6 }, /* OVERRIDE */
+ { 0x35, 0x0e }, /* OVERRIDE */
+ { 0x7e, 0x01 }, /* OVERRIDE */
+ { 0x83, 0x00 }, /* OVERRIDE */
+ { 0x04, 0x0b }, /* OVERRIDE */
+ { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */
+ { 0, 0 }
+};
+
+static struct reg_pair_t init_tab_cable[] = {
+ { 0x0b, 0x44 }, /* XTAL */
+ { 0x0c, 0x60 }, /* IF */
+ { 0x10, 0x00 }, /* MISC */
+ { 0x12, 0xca }, /* IDAC */
+ { 0x16, 0x90 }, /* MODE */
+ { 0x32, 0x38 }, /* MODE A/D */
+ { 0x71, 0x3f }, /* TOP1 */
+ { 0x72, 0x3f }, /* TOP2 */
+ { 0x74, 0x3f }, /* TOP3 */
+ { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */
+ { 0x2c, 0x34 }, /* OVERRIDE */
+ { 0x4d, 0x40 }, /* OVERRIDE */
+ { 0x7f, 0x02 }, /* OVERRIDE */
+ { 0x9a, 0x52 }, /* OVERRIDE */
+ { 0x48, 0x5a }, /* OVERRIDE */
+ { 0x76, 0x1a }, /* OVERRIDE */
+ { 0x6a, 0x48 }, /* OVERRIDE */
+ { 0x64, 0x28 }, /* OVERRIDE */
+ { 0x66, 0xe6 }, /* OVERRIDE */
+ { 0x35, 0x0e }, /* OVERRIDE */
+ { 0x7e, 0x01 }, /* OVERRIDE */
+ { 0x04, 0x0b }, /* OVERRIDE */
+ { 0x68, 0xb4 }, /* OVERRIDE */
+ { 0x36, 0x00 }, /* OVERRIDE */
+ { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */
+ { 0, 0 }
+};
+
+/* ------------------------------------------------------------------------- */
+
+static struct reg_pair_t reg_pair_rftune[] = {
+ { 0x11, 0x00 }, /* abort tune */
+ { 0x13, 0x15 },
+ { 0x14, 0x40 },
+ { 0x15, 0x0e },
+ { 0x11, 0x02 }, /* start tune */
+ { 0, 0 }
+};
+
+/* ------------------------------------------------------------------------- */
+
+struct mxl5007t_state {
+ struct list_head hybrid_tuner_instance_list;
+ struct tuner_i2c_props i2c_props;
+
+ struct mutex lock;
+
+ struct mxl5007t_config *config;
+
+ enum mxl5007t_chip_version chip_id;
+
+ struct reg_pair_t tab_init[ARRAY_SIZE(init_tab)];
+ struct reg_pair_t tab_init_cable[ARRAY_SIZE(init_tab_cable)];
+ struct reg_pair_t tab_rftune[ARRAY_SIZE(reg_pair_rftune)];
+
+ u32 frequency;
+ u32 bandwidth;
+};
+
+/* ------------------------------------------------------------------------- */
+
+/* called by _init and _rftun to manipulate the register arrays */
+
+static void set_reg_bits(struct reg_pair_t *reg_pair, u8 reg, u8 mask, u8 val)
+{
+ unsigned int i = 0;
+
+ while (reg_pair[i].reg || reg_pair[i].val) {
+ if (reg_pair[i].reg == reg) {
+ reg_pair[i].val &= ~mask;
+ reg_pair[i].val |= val;
+ }
+ i++;
+
+ }
+ return;
+}
+
+static void copy_reg_bits(struct reg_pair_t *reg_pair1,
+ struct reg_pair_t *reg_pair2)
+{
+ unsigned int i, j;
+
+ i = j = 0;
+
+ while (reg_pair1[i].reg || reg_pair1[i].val) {
+ while (reg_pair2[j].reg || reg_pair2[j].reg) {
+ if (reg_pair1[i].reg != reg_pair2[j].reg) {
+ j++;
+ continue;
+ }
+ reg_pair2[j].val = reg_pair1[i].val;
+ break;
+ }
+ i++;
+ }
+ return;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void mxl5007t_set_mode_bits(struct mxl5007t_state *state,
+ enum mxl5007t_mode mode,
+ s32 if_diff_out_level)
+{
+ switch (mode) {
+ case MxL_MODE_OTA_DVBT_ATSC:
+ set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06);
+ set_reg_bits(state->tab_init, 0x35, 0xff, 0x0e);
+ break;
+ case MxL_MODE_OTA_ISDBT:
+ set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06);
+ set_reg_bits(state->tab_init, 0x35, 0xff, 0x12);
+ break;
+ case MxL_MODE_OTA_NTSC_PAL_GH:
+ set_reg_bits(state->tab_init, 0x16, 0x70, 0x00);
+ set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
+ break;
+ case MxL_MODE_OTA_PAL_IB:
+ set_reg_bits(state->tab_init, 0x16, 0x70, 0x10);
+ set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
+ break;
+ case MxL_MODE_OTA_PAL_D_SECAM_KL:
+ set_reg_bits(state->tab_init, 0x16, 0x70, 0x20);
+ set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
+ break;
+ case MxL_MODE_CABLE_DIGITAL:
+ set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
+ set_reg_bits(state->tab_init_cable, 0x72, 0xff,
+ 8 - if_diff_out_level);
+ set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+ break;
+ case MxL_MODE_CABLE_NTSC_PAL_GH:
+ set_reg_bits(state->tab_init, 0x16, 0x70, 0x00);
+ set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
+ set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
+ set_reg_bits(state->tab_init_cable, 0x72, 0xff,
+ 8 - if_diff_out_level);
+ set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+ break;
+ case MxL_MODE_CABLE_PAL_IB:
+ set_reg_bits(state->tab_init, 0x16, 0x70, 0x10);
+ set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
+ set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
+ set_reg_bits(state->tab_init_cable, 0x72, 0xff,
+ 8 - if_diff_out_level);
+ set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+ break;
+ case MxL_MODE_CABLE_PAL_D_SECAM_KL:
+ set_reg_bits(state->tab_init, 0x16, 0x70, 0x20);
+ set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
+ set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
+ set_reg_bits(state->tab_init_cable, 0x72, 0xff,
+ 8 - if_diff_out_level);
+ set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+ break;
+ case MxL_MODE_CABLE_SCTE40:
+ set_reg_bits(state->tab_init_cable, 0x36, 0xff, 0x08);
+ set_reg_bits(state->tab_init_cable, 0x68, 0xff, 0xbc);
+ set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
+ set_reg_bits(state->tab_init_cable, 0x72, 0xff,
+ 8 - if_diff_out_level);
+ set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+ break;
+ default:
+ mxl_fail(-EINVAL);
+ }
+ return;
+}
+
+static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state,
+ enum mxl5007t_if_freq if_freq,
+ int invert_if)
+{
+ u8 val;
+
+ switch (if_freq) {
+ case MxL_IF_4_MHZ:
+ val = 0x00;
+ break;
+ case MxL_IF_4_5_MHZ:
+ val = 0x20;
+ break;
+ case MxL_IF_4_57_MHZ:
+ val = 0x30;
+ break;
+ case MxL_IF_5_MHZ:
+ val = 0x40;
+ break;
+ case MxL_IF_5_38_MHZ:
+ val = 0x50;
+ break;
+ case MxL_IF_6_MHZ:
+ val = 0x60;
+ break;
+ case MxL_IF_6_28_MHZ:
+ val = 0x70;
+ break;
+ case MxL_IF_9_1915_MHZ:
+ val = 0x80;
+ break;
+ case MxL_IF_35_25_MHZ:
+ val = 0x90;
+ break;
+ case MxL_IF_36_15_MHZ:
+ val = 0xa0;
+ break;
+ case MxL_IF_44_MHZ:
+ val = 0xb0;
+ break;
+ default:
+ mxl_fail(-EINVAL);
+ return;
+ }
+ set_reg_bits(state->tab_init, 0x0c, 0xf0, val);
+
+ /* set inverted IF or normal IF */
+ set_reg_bits(state->tab_init, 0x0c, 0x08, invert_if ? 0x08 : 0x00);
+
+ return;
+}
+
+static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state,
+ enum mxl5007t_xtal_freq xtal_freq)
+{
+ u8 val;
+
+ switch (xtal_freq) {
+ case MxL_XTAL_16_MHZ:
+ val = 0x00; /* select xtal freq & Ref Freq */
+ break;
+ case MxL_XTAL_20_MHZ:
+ val = 0x11;
+ break;
+ case MxL_XTAL_20_25_MHZ:
+ val = 0x22;
+ break;
+ case MxL_XTAL_20_48_MHZ:
+ val = 0x33;
+ break;
+ case MxL_XTAL_24_MHZ:
+ val = 0x44;
+ break;
+ case MxL_XTAL_25_MHZ:
+ val = 0x55;
+ break;
+ case MxL_XTAL_25_14_MHZ:
+ val = 0x66;
+ break;
+ case MxL_XTAL_27_MHZ:
+ val = 0x77;
+ break;
+ case MxL_XTAL_28_8_MHZ:
+ val = 0x88;
+ break;
+ case MxL_XTAL_32_MHZ:
+ val = 0x99;
+ break;
+ case MxL_XTAL_40_MHZ:
+ val = 0xaa;
+ break;
+ case MxL_XTAL_44_MHZ:
+ val = 0xbb;
+ break;
+ case MxL_XTAL_48_MHZ:
+ val = 0xcc;
+ break;
+ case MxL_XTAL_49_3811_MHZ:
+ val = 0xdd;
+ break;
+ default:
+ mxl_fail(-EINVAL);
+ return;
+ }
+ set_reg_bits(state->tab_init, 0x0b, 0xff, val);
+
+ return;
+}
+
+static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state,
+ enum mxl5007t_mode mode)
+{
+ struct mxl5007t_config *cfg = state->config;
+
+ memcpy(&state->tab_init, &init_tab, sizeof(init_tab));
+ memcpy(&state->tab_init_cable, &init_tab_cable, sizeof(init_tab_cable));
+
+ mxl5007t_set_mode_bits(state, mode, cfg->if_diff_out_level);
+ mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if);
+ mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz);
+
+ set_reg_bits(state->tab_init, 0x10, 0x40, cfg->loop_thru_enable << 6);
+
+ set_reg_bits(state->tab_init, 0xd8, 0x08, cfg->clk_out_enable << 3);
+
+ set_reg_bits(state->tab_init, 0x10, 0x07, cfg->clk_out_amp);
+
+ /* set IDAC to automatic mode control by AGC */
+ set_reg_bits(state->tab_init, 0x12, 0x80, 0x00);
+
+ if (mode >= MxL_MODE_CABLE_DIGITAL) {
+ copy_reg_bits(state->tab_init, state->tab_init_cable);
+ return state->tab_init_cable;
+ } else
+ return state->tab_init;
+}
+
+/* ------------------------------------------------------------------------- */
+
+enum mxl5007t_bw_mhz {
+ MxL_BW_6MHz = 6,
+ MxL_BW_7MHz = 7,
+ MxL_BW_8MHz = 8,
+};
+
+static void mxl5007t_set_bw_bits(struct mxl5007t_state *state,
+ enum mxl5007t_bw_mhz bw)
+{
+ u8 val;
+
+ switch (bw) {
+ case MxL_BW_6MHz:
+ val = 0x15; /* set DIG_MODEINDEX, DIG_MODEINDEX_A,
+ * and DIG_MODEINDEX_CSF */
+ break;
+ case MxL_BW_7MHz:
+ val = 0x21;
+ break;
+ case MxL_BW_8MHz:
+ val = 0x3f;
+ break;
+ default:
+ mxl_fail(-EINVAL);
+ return;
+ }
+ set_reg_bits(state->tab_rftune, 0x13, 0x3f, val);
+
+ return;
+}
+
+static struct
+reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state,
+ u32 rf_freq, enum mxl5007t_bw_mhz bw)
+{
+ u32 dig_rf_freq = 0;
+ u32 temp;
+ u32 frac_divider = 1000000;
+ unsigned int i;
+
+ memcpy(&state->tab_rftune, &reg_pair_rftune, sizeof(reg_pair_rftune));
+
+ mxl5007t_set_bw_bits(state, bw);
+
+ /* Convert RF frequency into 16 bits =>
+ * 10 bit integer (MHz) + 6 bit fraction */
+ dig_rf_freq = rf_freq / MHz;
+
+ temp = rf_freq % MHz;
+
+ for (i = 0; i < 6; i++) {
+ dig_rf_freq <<= 1;
+ frac_divider /= 2;
+ if (temp > frac_divider) {
+ temp -= frac_divider;
+ dig_rf_freq++;
+ }
+ }
+
+ /* add to have shift center point by 7.8124 kHz */
+ if (temp > 7812)
+ dig_rf_freq++;
+
+ set_reg_bits(state->tab_rftune, 0x14, 0xff, (u8)dig_rf_freq);
+ set_reg_bits(state->tab_rftune, 0x15, 0xff, (u8)(dig_rf_freq >> 8));
+
+ return state->tab_rftune;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_write_reg(struct mxl5007t_state *state, u8 reg, u8 val)
+{
+ u8 buf[] = { reg, val };
+ struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
+ .buf = buf, .len = 2 };
+ int ret;
+
+ ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
+ if (ret != 1) {
+ mxl_err("failed!");
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+static int mxl5007t_write_regs(struct mxl5007t_state *state,
+ struct reg_pair_t *reg_pair)
+{
+ unsigned int i = 0;
+ int ret = 0;
+
+ while ((ret == 0) && (reg_pair[i].reg || reg_pair[i].val)) {
+ ret = mxl5007t_write_reg(state,
+ reg_pair[i].reg, reg_pair[i].val);
+ i++;
+ }
+ return ret;
+}
+
+static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val)
+{
+ struct i2c_msg msg[] = {
+ { .addr = state->i2c_props.addr, .flags = 0,
+ .buf = &reg, .len = 1 },
+ { .addr = state->i2c_props.addr, .flags = I2C_M_RD,
+ .buf = val, .len = 1 },
+ };
+ int ret;
+
+ ret = i2c_transfer(state->i2c_props.adap, msg, 2);
+ if (ret != 2) {
+ mxl_err("failed!");
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+static int mxl5007t_soft_reset(struct mxl5007t_state *state)
+{
+ u8 d = 0xff;
+ struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
+ .buf = &d, .len = 1 };
+
+ int ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
+
+ if (ret != 1) {
+ mxl_err("failed!");
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+static int mxl5007t_tuner_init(struct mxl5007t_state *state,
+ enum mxl5007t_mode mode)
+{
+ struct reg_pair_t *init_regs;
+ int ret;
+
+ ret = mxl5007t_soft_reset(state);
+ if (mxl_fail(ret))
+ goto fail;
+
+ /* calculate initialization reg array */
+ init_regs = mxl5007t_calc_init_regs(state, mode);
+
+ ret = mxl5007t_write_regs(state, init_regs);
+ if (mxl_fail(ret))
+ goto fail;
+ mdelay(1);
+
+ ret = mxl5007t_write_reg(state, 0x2c, 0x35);
+ mxl_fail(ret);
+fail:
+ return ret;
+}
+
+static int mxl5007t_tuner_rf_tune(struct mxl5007t_state *state, u32 rf_freq_hz,
+ enum mxl5007t_bw_mhz bw)
+{
+ struct reg_pair_t *rf_tune_regs;
+ int ret;
+
+ /* calculate channel change reg array */
+ rf_tune_regs = mxl5007t_calc_rf_tune_regs(state, rf_freq_hz, bw);
+
+ ret = mxl5007t_write_regs(state, rf_tune_regs);
+ if (mxl_fail(ret))
+ goto fail;
+ msleep(3);
+fail:
+ return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_synth_lock_status(struct mxl5007t_state *state,
+ int *rf_locked, int *ref_locked)
+{
+ u8 d;
+ int ret;
+
+ *rf_locked = 0;
+ *ref_locked = 0;
+
+ ret = mxl5007t_read_reg(state, 0xcf, &d);
+ if (mxl_fail(ret))
+ goto fail;
+
+ if ((d & 0x0c) == 0x0c)
+ *rf_locked = 1;
+
+ if ((d & 0x03) == 0x03)
+ *ref_locked = 1;
+fail:
+ return ret;
+}
+
+static int mxl5007t_check_rf_input_power(struct mxl5007t_state *state,
+ s32 *rf_input_level)
+{
+ u8 d1, d2;
+ int ret;
+
+ ret = mxl5007t_read_reg(state, 0xb7, &d1);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl5007t_read_reg(state, 0xbf, &d2);
+ if (mxl_fail(ret))
+ goto fail;
+
+ d2 = d2 >> 4;
+ if (d2 > 7)
+ d2 += 0xf0;
+
+ *rf_input_level = (s32)(d1 + d2 - 113);
+fail:
+ return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
+{
+ struct mxl5007t_state *state = fe->tuner_priv;
+ int rf_locked, ref_locked;
+ s32 rf_input_level;
+ int ret;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ ret = mxl5007t_synth_lock_status(state, &rf_locked, &ref_locked);
+ if (mxl_fail(ret))
+ goto fail;
+ mxl_debug("%s%s", rf_locked ? "rf locked " : "",
+ ref_locked ? "ref locked" : "");
+
+ ret = mxl5007t_check_rf_input_power(state, &rf_input_level);
+ if (mxl_fail(ret))
+ goto fail;
+ mxl_debug("rf input power: %d", rf_input_level);
+fail:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct mxl5007t_state *state = fe->tuner_priv;
+ enum mxl5007t_bw_mhz bw;
+ enum mxl5007t_mode mode;
+ int ret;
+ u32 freq = params->frequency;
+
+ if (fe->ops.info.type == FE_ATSC) {
+ switch (params->u.vsb.modulation) {
+ case VSB_8:
+ case VSB_16:
+ mode = MxL_MODE_OTA_DVBT_ATSC;
+ break;
+ case QAM_64:
+ case QAM_256:
+ mode = MxL_MODE_CABLE_DIGITAL;
+ break;
+ default:
+ mxl_err("modulation not set!");
+ return -EINVAL;
+ }
+ bw = MxL_BW_6MHz;
+ } else if (fe->ops.info.type == FE_OFDM) {
+ switch (params->u.ofdm.bandwidth) {
+ case BANDWIDTH_6_MHZ:
+ bw = MxL_BW_6MHz;
+ break;
+ case BANDWIDTH_7_MHZ:
+ bw = MxL_BW_7MHz;
+ break;
+ case BANDWIDTH_8_MHZ:
+ bw = MxL_BW_8MHz;
+ break;
+ default:
+ mxl_err("bandwidth not set!");
+ return -EINVAL;
+ }
+ mode = MxL_MODE_OTA_DVBT_ATSC;
+ } else {
+ mxl_err("modulation type not supported!");
+ return -EINVAL;
+ }
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ mutex_lock(&state->lock);
+
+ ret = mxl5007t_tuner_init(state, mode);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl5007t_tuner_rf_tune(state, freq, bw);
+ if (mxl_fail(ret))
+ goto fail;
+
+ state->frequency = freq;
+ state->bandwidth = (fe->ops.info.type == FE_OFDM) ?
+ params->u.ofdm.bandwidth : 0;
+fail:
+ mutex_unlock(&state->lock);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return ret;
+}
+
+static int mxl5007t_set_analog_params(struct dvb_frontend *fe,
+ struct analog_parameters *params)
+{
+ struct mxl5007t_state *state = fe->tuner_priv;
+ enum mxl5007t_bw_mhz bw = 0; /* FIXME */
+ enum mxl5007t_mode cbl_mode;
+ enum mxl5007t_mode ota_mode;
+ char *mode_name;
+ int ret;
+ u32 freq = params->frequency * 62500;
+
+#define cable 1
+ if (params->std & V4L2_STD_MN) {
+ cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
+ ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
+ mode_name = "MN";
+ } else if (params->std & V4L2_STD_B) {
+ cbl_mode = MxL_MODE_CABLE_PAL_IB;
+ ota_mode = MxL_MODE_OTA_PAL_IB;
+ mode_name = "B";
+ } else if (params->std & V4L2_STD_GH) {
+ cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
+ ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
+ mode_name = "GH";
+ } else if (params->std & V4L2_STD_PAL_I) {
+ cbl_mode = MxL_MODE_CABLE_PAL_IB;
+ ota_mode = MxL_MODE_OTA_PAL_IB;
+ mode_name = "I";
+ } else if (params->std & V4L2_STD_DK) {
+ cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
+ ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
+ mode_name = "DK";
+ } else if (params->std & V4L2_STD_SECAM_L) {
+ cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
+ ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
+ mode_name = "L";
+ } else if (params->std & V4L2_STD_SECAM_LC) {
+ cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
+ ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
+ mode_name = "L'";
+ } else {
+ mode_name = "xx";
+ /* FIXME */
+ cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
+ ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
+ }
+ mxl_debug("setting mxl5007 to system %s", mode_name);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ mutex_lock(&state->lock);
+
+ ret = mxl5007t_tuner_init(state, cable ? cbl_mode : ota_mode);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl5007t_tuner_rf_tune(state, freq, bw);
+ if (mxl_fail(ret))
+ goto fail;
+
+ state->frequency = freq;
+ state->bandwidth = 0;
+fail:
+ mutex_unlock(&state->lock);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_init(struct dvb_frontend *fe)
+{
+ struct mxl5007t_state *state = fe->tuner_priv;
+ int ret;
+ u8 d;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ ret = mxl5007t_read_reg(state, 0x05, &d);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl5007t_write_reg(state, 0x05, d | 0x01);
+ mxl_fail(ret);
+fail:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return ret;
+}
+
+static int mxl5007t_sleep(struct dvb_frontend *fe)
+{
+ struct mxl5007t_state *state = fe->tuner_priv;
+ int ret;
+ u8 d;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ ret = mxl5007t_read_reg(state, 0x05, &d);
+ if (mxl_fail(ret))
+ goto fail;
+
+ ret = mxl5007t_write_reg(state, 0x05, d & ~0x01);
+ mxl_fail(ret);
+fail:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct mxl5007t_state *state = fe->tuner_priv;
+ *frequency = state->frequency;
+ return 0;
+}
+
+static int mxl5007t_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+ struct mxl5007t_state *state = fe->tuner_priv;
+ *bandwidth = state->bandwidth;
+ return 0;
+}
+
+static int mxl5007t_release(struct dvb_frontend *fe)
+{
+ struct mxl5007t_state *state = fe->tuner_priv;
+
+ mutex_lock(&mxl5007t_list_mutex);
+
+ if (state)
+ hybrid_tuner_release_state(state);
+
+ mutex_unlock(&mxl5007t_list_mutex);
+
+ fe->tuner_priv = NULL;
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static struct dvb_tuner_ops mxl5007t_tuner_ops = {
+ .info = {
+ .name = "MaxLinear MxL5007T",
+ },
+ .init = mxl5007t_init,
+ .sleep = mxl5007t_sleep,
+ .set_params = mxl5007t_set_params,
+ .set_analog_params = mxl5007t_set_analog_params,
+ .get_status = mxl5007t_get_status,
+ .get_frequency = mxl5007t_get_frequency,
+ .get_bandwidth = mxl5007t_get_bandwidth,
+ .release = mxl5007t_release,
+};
+
+static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
+{
+ char *name;
+ int ret;
+ u8 id;
+
+ ret = mxl5007t_read_reg(state, 0xd3, &id);
+ if (mxl_fail(ret))
+ goto fail;
+
+ switch (id) {
+ case MxL_5007_V1_F1:
+ name = "MxL5007.v1.f1";
+ break;
+ case MxL_5007_V1_F2:
+ name = "MxL5007.v1.f2";
+ break;
+ case MxL_5007_V2_100_F1:
+ name = "MxL5007.v2.100.f1";
+ break;
+ case MxL_5007_V2_100_F2:
+ name = "MxL5007.v2.100.f2";
+ break;
+ case MxL_5007_V2_200_F1:
+ name = "MxL5007.v2.200.f1";
+ break;
+ case MxL_5007_V2_200_F2:
+ name = "MxL5007.v2.200.f2";
+ break;
+ default:
+ name = "MxL5007T";
+ id = MxL_UNKNOWN_ID;
+ }
+ state->chip_id = id;
+ mxl_info("%s detected @ %d-%04x", name,
+ i2c_adapter_id(state->i2c_props.adap),
+ state->i2c_props.addr);
+ return 0;
+fail:
+ mxl_warn("unable to identify device @ %d-%04x",
+ i2c_adapter_id(state->i2c_props.adap),
+ state->i2c_props.addr);
+
+ state->chip_id = MxL_UNKNOWN_ID;
+ return ret;
+}
+
+struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 addr,
+ struct mxl5007t_config *cfg)
+{
+ struct mxl5007t_state *state = NULL;
+ int instance, ret;
+
+ mutex_lock(&mxl5007t_list_mutex);
+ instance = hybrid_tuner_request_state(struct mxl5007t_state, state,
+ hybrid_tuner_instance_list,
+ i2c, addr, "mxl5007");
+ switch (instance) {
+ case 0:
+ goto fail;
+ break;
+ case 1:
+ /* new tuner instance */
+ state->config = cfg;
+
+ mutex_init(&state->lock);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ ret = mxl5007t_get_chip_id(state);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ /* check return value of mxl5007t_get_chip_id */
+ if (mxl_fail(ret))
+ goto fail;
+ break;
+ default:
+ /* existing tuner instance */
+ break;
+ }
+ fe->tuner_priv = state;
+ mutex_unlock(&mxl5007t_list_mutex);
+
+ memcpy(&fe->ops.tuner_ops, &mxl5007t_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+
+ return fe;
+fail:
+ mutex_unlock(&mxl5007t_list_mutex);
+
+ mxl5007t_release(fe);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(mxl5007t_attach);
+MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver");
+MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/common/tuners/mxl5007t.h b/drivers/media/common/tuners/mxl5007t.h
new file mode 100644
index 00000000000..aa3eea0b526
--- /dev/null
+++ b/drivers/media/common/tuners/mxl5007t.h
@@ -0,0 +1,104 @@
+/*
+ * mxl5007t.h - driver for the MaxLinear MxL5007T silicon tuner
+ *
+ * Copyright (C) 2008 Michael Krufky <mkrufky@linuxtv.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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MXL5007T_H__
+#define __MXL5007T_H__
+
+#include "dvb_frontend.h"
+
+/* ------------------------------------------------------------------------- */
+
+enum mxl5007t_if_freq {
+ MxL_IF_4_MHZ, /* 4000000 */
+ MxL_IF_4_5_MHZ, /* 4500000 */
+ MxL_IF_4_57_MHZ, /* 4570000 */
+ MxL_IF_5_MHZ, /* 5000000 */
+ MxL_IF_5_38_MHZ, /* 5380000 */
+ MxL_IF_6_MHZ, /* 6000000 */
+ MxL_IF_6_28_MHZ, /* 6280000 */
+ MxL_IF_9_1915_MHZ, /* 9191500 */
+ MxL_IF_35_25_MHZ, /* 35250000 */
+ MxL_IF_36_15_MHZ, /* 36150000 */
+ MxL_IF_44_MHZ, /* 44000000 */
+};
+
+enum mxl5007t_xtal_freq {
+ MxL_XTAL_16_MHZ, /* 16000000 */
+ MxL_XTAL_20_MHZ, /* 20000000 */
+ MxL_XTAL_20_25_MHZ, /* 20250000 */
+ MxL_XTAL_20_48_MHZ, /* 20480000 */
+ MxL_XTAL_24_MHZ, /* 24000000 */
+ MxL_XTAL_25_MHZ, /* 25000000 */
+ MxL_XTAL_25_14_MHZ, /* 25140000 */
+ MxL_XTAL_27_MHZ, /* 27000000 */
+ MxL_XTAL_28_8_MHZ, /* 28800000 */
+ MxL_XTAL_32_MHZ, /* 32000000 */
+ MxL_XTAL_40_MHZ, /* 40000000 */
+ MxL_XTAL_44_MHZ, /* 44000000 */
+ MxL_XTAL_48_MHZ, /* 48000000 */
+ MxL_XTAL_49_3811_MHZ, /* 49381100 */
+};
+
+enum mxl5007t_clkout_amp {
+ MxL_CLKOUT_AMP_0_94V = 0,
+ MxL_CLKOUT_AMP_0_53V = 1,
+ MxL_CLKOUT_AMP_0_37V = 2,
+ MxL_CLKOUT_AMP_0_28V = 3,
+ MxL_CLKOUT_AMP_0_23V = 4,
+ MxL_CLKOUT_AMP_0_20V = 5,
+ MxL_CLKOUT_AMP_0_17V = 6,
+ MxL_CLKOUT_AMP_0_15V = 7,
+};
+
+struct mxl5007t_config {
+ s32 if_diff_out_level;
+ enum mxl5007t_clkout_amp clk_out_amp;
+ enum mxl5007t_xtal_freq xtal_freq_hz;
+ enum mxl5007t_if_freq if_freq_hz;
+ unsigned int invert_if:1;
+ unsigned int loop_thru_enable:1;
+ unsigned int clk_out_enable:1;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MXL5007T) || (defined(CONFIG_MEDIA_TUNER_MXL5007T_MODULE) && defined(MODULE))
+extern struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 addr,
+ struct mxl5007t_config *cfg);
+#else
+static inline struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c,
+ u8 addr,
+ struct mxl5007t_config *cfg)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif /* __MXL5007T_H__ */
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
+
diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c
index a0545ba957b..72abf0b7348 100644
--- a/drivers/media/common/tuners/tda9887.c
+++ b/drivers/media/common/tuners/tda9887.c
@@ -6,7 +6,7 @@
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/tuner.h>
#include "tuner-i2c.h"
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
index 266c255cf0d..597e47f5d69 100644
--- a/drivers/media/common/tuners/tuner-simple.c
+++ b/drivers/media/common/tuners/tuner-simple.c
@@ -6,7 +6,7 @@
*/
#include <linux/delay.h>
#include <linux/i2c.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/tuner.h>
#include <media/v4l2-common.h>
#include <media/tuner-types.h>
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index 7588db1319d..7e9c090fc04 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -1,7 +1,6 @@
config DVB_BT8XX
tristate "BT8xx based PCI cards"
depends on DVB_CORE && PCI && I2C && VIDEO_BT848
- depends on HOTPLUG # due to FW_LOADER
select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_SP887X if !DVB_FE_CUSTOMISE
select DVB_NXT6000 if !DVB_FE_CUSTOMISE
@@ -10,7 +9,6 @@ config DVB_BT8XX
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
- select FW_LOADER
help
Support for PCI cards based on the Bt8xx PCI bridge. Examples are
the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index a577c0f89f6..e84152b7576 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -1,8 +1,6 @@
config DVB_USB
tristate "Support for various USB DVB devices"
depends on DVB_CORE && USB && I2C && INPUT
- depends on HOTPLUG # due to FW_LOADER
- select FW_LOADER
help
By enabling this you will be able to choose the various supported
USB1.1 and USB2.0 DVB devices.
@@ -246,6 +244,14 @@ config DVB_USB_AF9005_REMOTE
Say Y here to support the default remote control decoding for the
Afatech AF9005 based receiver.
+config DVB_USB_DW2102
+ tristate "DvbWorld 2102 DVB-S USB2.0 receiver"
+ depends on DVB_USB
+ select DVB_STV0299 if !DVB_FE_CUSTOMISE
+ select DVB_PLL if !DVB_FE_CUSTOMISE
+ help
+ Say Y here to support the DvbWorld 2102 DVB-S USB2.0 receiver.
+
config DVB_USB_ANYSEE
tristate "Anysee DVB-T/C USB2.0 support"
depends on DVB_USB
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 44c11e45e56..e206f1ea002 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -64,6 +64,9 @@ obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o
dvb-usb-anysee-objs = anysee.o
obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
+dvb-usb-dw2102-objs = dw2102.o
+obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o
+
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
# due to tuner-xc3028
EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index adfd4fc82ef..2f408d2e1ef 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -43,7 +43,7 @@ module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-struct mutex anysee_usb_mutex;
+static struct mutex anysee_usb_mutex;
static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
u8 *rbuf, u8 rlen)
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index e5238b31e94..029b437caf9 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -204,5 +204,6 @@
#define USB_PID_ASUS_U3000 0x171f
#define USB_PID_ASUS_U3100 0x173f
#define USB_PID_YUAN_EC372S 0x1edc
+#define USB_PID_DW2102 0x2102
#endif
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
new file mode 100644
index 00000000000..a4d898b44e5
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -0,0 +1,425 @@
+/* DVB USB framework compliant Linux driver for the DVBWorld DVB-S 2102 Card
+*
+* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
+*
+* 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.
+*
+* see Documentation/dvb/README.dvb-usb for more information
+*/
+#include <linux/version.h>
+#include "dw2102.h"
+#include "stv0299.h"
+#include "z0194a.h"
+
+#ifndef USB_PID_DW2102
+#define USB_PID_DW2102 0x2102
+#endif
+
+#define DW2102_READ_MSG 0
+#define DW2102_WRITE_MSG 1
+
+#define REG_1F_SYMBOLRATE_BYTE0 0x1f
+#define REG_20_SYMBOLRATE_BYTE1 0x20
+#define REG_21_SYMBOLRATE_BYTE2 0x21
+
+#define DW2102_VOLTAGE_CTRL (0x1800)
+#define DW2102_RC_QUERY (0x1a00)
+
+struct dw2102_state {
+ u32 last_key_pressed;
+};
+struct dw2102_rc_keys {
+ u32 keycode;
+ u32 event;
+};
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int dw2102_op_rw(struct usb_device *dev, u8 request, u16 value,
+ u8 *data, u16 len, int flags)
+{
+ int ret;
+ u8 u8buf[len];
+
+ unsigned int pipe = (flags == DW2102_READ_MSG) ?
+ usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
+ u8 request_type = (flags == DW2102_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
+
+ if (flags == DW2102_WRITE_MSG)
+ memcpy(u8buf, data, len);
+ ret = usb_control_msg(dev, pipe, request,
+ request_type | USB_TYPE_VENDOR, value, 0 , u8buf, len, 2000);
+
+ if (flags == DW2102_READ_MSG)
+ memcpy(data, u8buf, len);
+ return ret;
+}
+
+/* I2C */
+
+static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ int num)
+{
+struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ int i = 0, ret = 0;
+ u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
+ u8 request;
+ u16 value;
+
+ if (!d)
+ return -ENODEV;
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ switch (num) {
+ case 2:
+ /* read stv0299 register */
+ request = 0xb5;
+ value = msg[0].buf[0];/* register */
+ for (i = 0; i < msg[1].len; i++) {
+ value = value + i;
+ ret = dw2102_op_rw(d->udev, 0xb5,
+ value, buf6, 2, DW2102_READ_MSG);
+ msg[1].buf[i] = buf6[0];
+
+ }
+ break;
+ case 1:
+ switch (msg[0].addr) {
+ case 0x68:
+ /* write to stv0299 register */
+ buf6[0] = 0x2a;
+ buf6[1] = msg[0].buf[0];
+ buf6[2] = msg[0].buf[1];
+ ret = dw2102_op_rw(d->udev, 0xb2,
+ 0, buf6, 3, DW2102_WRITE_MSG);
+ break;
+ case 0x60:
+ if (msg[0].flags == 0) {
+ /* write to tuner pll */
+ buf6[0] = 0x2c;
+ buf6[1] = 5;
+ buf6[2] = 0xc0;
+ buf6[3] = msg[0].buf[0];
+ buf6[4] = msg[0].buf[1];
+ buf6[5] = msg[0].buf[2];
+ buf6[6] = msg[0].buf[3];
+ ret = dw2102_op_rw(d->udev, 0xb2,
+ 0, buf6, 7, DW2102_WRITE_MSG);
+ } else {
+ /* write to tuner pll */
+ ret = dw2102_op_rw(d->udev, 0xb5,
+ 0, buf6, 1, DW2102_READ_MSG);
+ msg[0].buf[0] = buf6[0];
+ }
+ break;
+ case (DW2102_RC_QUERY):
+ ret = dw2102_op_rw(d->udev, 0xb8,
+ 0, buf6, 2, DW2102_READ_MSG);
+ msg[0].buf[0] = buf6[0];
+ msg[0].buf[1] = buf6[1];
+ break;
+ case (DW2102_VOLTAGE_CTRL):
+ buf6[0] = 0x30;
+ buf6[1] = msg[0].buf[0];
+ ret = dw2102_op_rw(d->udev, 0xb2,
+ 0, buf6, 2, DW2102_WRITE_MSG);
+ break;
+ }
+
+ break;
+ }
+
+ mutex_unlock(&d->i2c_mutex);
+ return num;
+}
+
+static u32 dw2102_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm dw2102_i2c_algo = {
+ .master_xfer = dw2102_i2c_transfer,
+ .functionality = dw2102_i2c_func,
+};
+
+static int dw2102_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+ static u8 command_13v[1] = {0x00};
+ static u8 command_18v[1] = {0x01};
+ struct i2c_msg msg[] = {
+ {.addr = DW2102_VOLTAGE_CTRL, .flags = 0,
+ .buf = command_13v, .len = 1},
+ };
+
+ struct dvb_usb_adapter *udev_adap =
+ (struct dvb_usb_adapter *)(fe->dvb->priv);
+ if (voltage == SEC_VOLTAGE_18)
+ msg[0].buf = command_18v;
+ i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
+ return 0;
+}
+
+static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
+{
+ d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
+ &d->dev->i2c_adap);
+ if (d->fe != NULL) {
+ d->fe->ops.set_voltage = dw2102_set_voltage;
+ info("Attached stv0299!\n");
+ return 0;
+ }
+ return -EIO;
+}
+
+static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ dvb_attach(dvb_pll_attach, adap->fe, 0x60,
+ &adap->dev->i2c_adap, DVB_PLL_OPERA1);
+ return 0;
+}
+
+static struct dvb_usb_rc_key dw2102_rc_keys[] = {
+ { 0xf8, 0x0a, KEY_Q }, /*power*/
+ { 0xf8, 0x0c, KEY_M }, /*mute*/
+ { 0xf8, 0x11, KEY_1 },
+ { 0xf8, 0x12, KEY_2 },
+ { 0xf8, 0x13, KEY_3 },
+ { 0xf8, 0x14, KEY_4 },
+ { 0xf8, 0x15, KEY_5 },
+ { 0xf8, 0x16, KEY_6 },
+ { 0xf8, 0x17, KEY_7 },
+ { 0xf8, 0x18, KEY_8 },
+ { 0xf8, 0x19, KEY_9 },
+ { 0xf8, 0x10, KEY_0 },
+ { 0xf8, 0x1c, KEY_PAGEUP }, /*ch+*/
+ { 0xf8, 0x0f, KEY_PAGEDOWN }, /*ch-*/
+ { 0xf8, 0x1a, KEY_O }, /*vol+*/
+ { 0xf8, 0x0e, KEY_Z }, /*vol-*/
+ { 0xf8, 0x04, KEY_R }, /*rec*/
+ { 0xf8, 0x09, KEY_D }, /*fav*/
+ { 0xf8, 0x08, KEY_BACKSPACE }, /*rewind*/
+ { 0xf8, 0x07, KEY_A }, /*fast*/
+ { 0xf8, 0x0b, KEY_P }, /*pause*/
+ { 0xf8, 0x02, KEY_ESC }, /*cancel*/
+ { 0xf8, 0x03, KEY_G }, /*tab*/
+ { 0xf8, 0x00, KEY_UP }, /*up*/
+ { 0xf8, 0x1f, KEY_ENTER }, /*ok*/
+ { 0xf8, 0x01, KEY_DOWN }, /*down*/
+ { 0xf8, 0x05, KEY_C }, /*cap*/
+ { 0xf8, 0x06, KEY_S }, /*stop*/
+ { 0xf8, 0x40, KEY_F }, /*full*/
+ { 0xf8, 0x1e, KEY_W }, /*tvmode*/
+ { 0xf8, 0x1b, KEY_B }, /*recall*/
+
+};
+
+
+
+static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+ struct dw2102_state *st = d->priv;
+ u8 key[2];
+ struct i2c_msg msg[] = {
+ {.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key,
+ .len = 2},
+ };
+ int i;
+
+ *state = REMOTE_NO_KEY_PRESSED;
+ if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) {
+ for (i = 0; i < ARRAY_SIZE(dw2102_rc_keys); i++) {
+ if (dw2102_rc_keys[i].data == msg[0].buf[0]) {
+ *state = REMOTE_KEY_PRESSED;
+ *event = dw2102_rc_keys[i].event;
+ st->last_key_pressed =
+ dw2102_rc_keys[i].event;
+ break;
+ }
+ st->last_key_pressed = 0;
+ }
+ }
+ /* info("key: %x %x\n",key[0],key[1]); */
+ return 0;
+}
+
+static struct usb_device_id dw2102_table[] = {
+ {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
+ {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
+ { }
+};
+
+MODULE_DEVICE_TABLE(usb, dw2102_table);
+
+static int dw2102_load_firmware(struct usb_device *dev,
+ const struct firmware *frmwr)
+{
+ u8 *b, *p;
+ int ret = 0, i;
+ u8 reset;
+ u8 reset16 [] = {0, 0, 0, 0, 0, 0, 0};
+ const struct firmware *fw;
+ const char *filename = "dvb-usb-dw2101.fw";
+ switch (dev->descriptor.idProduct) {
+ case 0x2101:
+ ret = request_firmware(&fw, filename, &dev->dev);
+ if (ret != 0) {
+ err("did not find the firmware file. (%s) "
+ "Please see linux/Documentation/dvb/ for more details "
+ "on firmware-problems.", filename);
+ return ret;
+ }
+ break;
+ case USB_PID_DW2102:
+ fw = frmwr;
+ break;
+ }
+ info("start downloading DW2102 firmware");
+ p = kmalloc(fw->size, GFP_KERNEL);
+ reset = 1;
+ /*stop the CPU*/
+ dw2102_op_rw(dev, 0xa0, 0x7f92, &reset, 1, DW2102_WRITE_MSG);
+ dw2102_op_rw(dev, 0xa0, 0xe600, &reset, 1, DW2102_WRITE_MSG);
+
+ if (p != NULL) {
+ memcpy(p, fw->data, fw->size);
+ for (i = 0; i < fw->size; i += 0x40) {
+ b = (u8 *) p + i;
+ if (dw2102_op_rw
+ (dev, 0xa0, i, b , 0x40,
+ DW2102_WRITE_MSG) != 0x40
+ ) {
+ err("error while transferring firmware");
+ ret = -EINVAL;
+ break;
+ }
+ }
+ /* restart the CPU */
+ reset = 0;
+ if (ret || dw2102_op_rw
+ (dev, 0xa0, 0x7f92, &reset, 1,
+ DW2102_WRITE_MSG) != 1) {
+ err("could not restart the USB controller CPU.");
+ ret = -EINVAL;
+ }
+ if (ret || dw2102_op_rw
+ (dev, 0xa0, 0xe600, &reset, 1,
+ DW2102_WRITE_MSG) != 1) {
+ err("could not restart the USB controller CPU.");
+ ret = -EINVAL;
+ }
+ /* init registers */
+ switch (dev->descriptor.idProduct) {
+ case USB_PID_DW2102:
+ dw2102_op_rw
+ (dev, 0xbf, 0x0040, &reset, 0,
+ DW2102_WRITE_MSG);
+ dw2102_op_rw
+ (dev, 0xb9, 0x0000, &reset16[0], 2,
+ DW2102_READ_MSG);
+ break;
+ case 0x2101:
+ dw2102_op_rw
+ (dev, 0xbc, 0x0030, &reset16[0], 2,
+ DW2102_READ_MSG);
+ dw2102_op_rw
+ (dev, 0xba, 0x0000, &reset16[0], 7,
+ DW2102_READ_MSG);
+ dw2102_op_rw
+ (dev, 0xba, 0x0000, &reset16[0], 7,
+ DW2102_READ_MSG);
+ dw2102_op_rw
+ (dev, 0xb9, 0x0000, &reset16[0], 2,
+ DW2102_READ_MSG);
+ break;
+ }
+ kfree(p);
+ }
+ return ret;
+}
+
+static struct dvb_usb_device_properties dw2102_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+ .usb_ctrl = DEVICE_SPECIFIC,
+ .firmware = "dvb-usb-dw2102.fw",
+ .size_of_priv = sizeof(struct dw2102_state),
+ .no_reconnect = 1,
+
+ .i2c_algo = &dw2102_i2c_algo,
+ .rc_key_map = dw2102_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(dw2102_rc_keys),
+ .rc_interval = 150,
+ .rc_query = dw2102_rc_query,
+
+ .generic_bulk_ctrl_endpoint = 0x81,
+ /* parameter for the MPEG2-data transfer */
+ .num_adapters = 1,
+ .download_firmware = dw2102_load_firmware,
+ .adapter = {
+ {
+ .frontend_attach = dw2102_frontend_attach,
+ .streaming_ctrl = NULL,
+ .tuner_attach = dw2102_tuner_attach,
+ .stream = {
+ .type = USB_BULK,
+ .count = 8,
+ .endpoint = 0x82,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+ }
+ },
+ .num_device_descs = 2,
+ .devices = {
+ {"DVBWorld DVB-S 2102 USB2.0",
+ {&dw2102_table[0], NULL},
+ {NULL},
+ },
+ {"DVBWorld DVB-S 2101 USB2.0",
+ {&dw2102_table[1], NULL},
+ {NULL},
+ },
+ }
+};
+
+static int dw2102_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return dvb_usb_device_init(intf, &dw2102_properties,
+ THIS_MODULE, NULL, adapter_nr);
+}
+
+static struct usb_driver dw2102_driver = {
+ .name = "dw2102",
+ .probe = dw2102_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = dw2102_table,
+};
+
+static int __init dw2102_module_init(void)
+{
+ int ret = usb_register(&dw2102_driver);
+ if (ret)
+ err("usb_register failed. Error number %d", ret);
+
+ return ret;
+}
+
+static void __exit dw2102_module_exit(void)
+{
+ usb_deregister(&dw2102_driver);
+}
+
+module_init(dw2102_module_init);
+module_exit(dw2102_module_exit);
+
+MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
+MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101 2102 USB2.0 device");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dw2102.h b/drivers/media/dvb/dvb-usb/dw2102.h
new file mode 100644
index 00000000000..7a310f90683
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dw2102.h
@@ -0,0 +1,9 @@
+#ifndef _DW2102_H_
+#define _DW2102_H_
+
+#define DVB_USB_LOG_PREFIX "dw2102"
+#include "dvb-usb.h"
+
+extern int dvb_usb_dw2102_debug;
+#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args)
+#endif
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index c20553c4da1..574dffe91b6 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -97,9 +97,8 @@ comment "DVB-T (terrestrial) frontends"
config DVB_SP8870
tristate "Spase sp8870 based"
- depends on DVB_CORE && I2C && HOTPLUG
+ depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
- select FW_LOADER
help
A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -110,9 +109,8 @@ config DVB_SP8870
config DVB_SP887X
tristate "Spase sp887x based"
- depends on DVB_CORE && I2C && HOTPLUG
+ depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
- select FW_LOADER
help
A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -135,6 +133,20 @@ config DVB_CX22702
help
A DVB-T tuner module. Say Y when you want to support this frontend.
+config DVB_DRX397XD
+ tristate "Micronas DRX3975D/DRX3977D based"
+ depends on DVB_CORE && I2C && HOTPLUG
+ default m if DVB_FE_CUSTOMISE
+ select FW_LOADER
+ help
+ A DVB-T tuner module. Say Y when you want to support this frontend.
+
+ TODO:
+ This driver needs external firmware. Please use the command
+ "<kerneldir>/Documentation/dvb/get_dvb_firmware drx397xD" to
+ download/extract them, and then copy them to /usr/lib/hotplug/firmware
+ or /lib/firmware (depending on configuration of firmware hotplug).
+
config DVB_L64781
tristate "LSI L64781"
depends on DVB_CORE && I2C
@@ -144,9 +156,8 @@ config DVB_L64781
config DVB_TDA1004X
tristate "Philips TDA10045H/TDA10046H based"
- depends on DVB_CORE && I2C && HOTPLUG
+ depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
- select FW_LOADER
help
A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -211,9 +222,8 @@ config DVB_DIB7000P
config DVB_TDA10048
tristate "Philips TDA10048HN based"
- depends on DVB_CORE && I2C && HOTPLUG
+ depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
- select FW_LOADER
help
A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -253,9 +263,8 @@ comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
config DVB_NXT200X
tristate "NxtWave Communications NXT2002/NXT2004 based"
- depends on DVB_CORE && I2C && HOTPLUG
+ depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
- select FW_LOADER
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
@@ -268,9 +277,8 @@ config DVB_NXT200X
config DVB_OR51211
tristate "Oren OR51211 based"
- depends on DVB_CORE && I2C && HOTPLUG
+ depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
- select FW_LOADER
help
An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
@@ -281,9 +289,8 @@ config DVB_OR51211
config DVB_OR51132
tristate "Oren OR51132 based"
- depends on DVB_CORE && I2C && HOTPLUG
+ depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
- select FW_LOADER
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
@@ -297,9 +304,8 @@ config DVB_OR51132
config DVB_BCM3510
tristate "Broadcom BCM3510"
- depends on DVB_CORE && I2C && HOTPLUG
+ depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
- select FW_LOADER
help
An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
support this frontend.
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index a89dc0fc4c6..028da55611c 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
obj-$(CONFIG_DVB_MT352) += mt352.o
obj-$(CONFIG_DVB_ZL10353) += zl10353.o
obj-$(CONFIG_DVB_CX22702) += cx22702.o
+obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o
obj-$(CONFIG_DVB_TDA10021) += tda10021.o
obj-$(CONFIG_DVB_TDA10023) += tda10023.o
obj-$(CONFIG_DVB_STV0297) += stv0297.o
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
new file mode 100644
index 00000000000..3cbed874a6f
--- /dev/null
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -0,0 +1,1504 @@
+/*
+ * Driver for Micronas drx397xD demodulator
+ *
+ * Copyright (C) 2007 Henk Vergonet <Henk.Vergonet@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DEBUG /* uncomment if you want debugging output */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/firmware.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "drx397xD.h"
+
+static const char mod_name[] = "drx397xD";
+
+#define MAX_CLOCK_DRIFT 200 /* maximal 200 PPM allowed */
+
+#define F_SET_0D0h 1
+#define F_SET_0D4h 2
+
+typedef enum fw_ix {
+#define _FW_ENTRY(a, b) b
+#include "drx397xD_fw.h"
+} fw_ix_t;
+
+/* chip specifics */
+struct drx397xD_state {
+ struct i2c_adapter *i2c;
+ struct dvb_frontend frontend;
+ struct drx397xD_config config;
+ fw_ix_t chip_rev;
+ int flags;
+ u32 bandwidth_parm; /* internal bandwidth conversions */
+ u32 f_osc; /* w90: actual osc frequency [Hz] */
+};
+
+/*******************************************************************************
+ * Firmware
+ ******************************************************************************/
+
+static const char *blob_name[] = {
+#define _BLOB_ENTRY(a, b) a
+#include "drx397xD_fw.h"
+};
+
+typedef enum blob_ix {
+#define _BLOB_ENTRY(a, b) b
+#include "drx397xD_fw.h"
+} blob_ix_t;
+
+static struct {
+ const char *name;
+ const struct firmware *file;
+ rwlock_t lock;
+ int refcnt;
+ const u8 *data[ARRAY_SIZE(blob_name)];
+} fw[] = {
+#define _FW_ENTRY(a, b) { \
+ .name = a, \
+ .file = 0, \
+ .lock = RW_LOCK_UNLOCKED, \
+ .refcnt = 0, \
+ .data = { } }
+#include "drx397xD_fw.h"
+};
+
+/* use only with writer lock aquired */
+static void _drx_release_fw(struct drx397xD_state *s, fw_ix_t ix)
+{
+ memset(&fw[ix].data[0], 0, sizeof(fw[0].data));
+ if (fw[ix].file)
+ release_firmware(fw[ix].file);
+}
+
+static void drx_release_fw(struct drx397xD_state *s)
+{
+ fw_ix_t ix = s->chip_rev;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ write_lock(&fw[ix].lock);
+ if (fw[ix].refcnt) {
+ fw[ix].refcnt--;
+ if (fw[ix].refcnt == 0)
+ _drx_release_fw(s, ix);
+ }
+ write_unlock(&fw[ix].lock);
+}
+
+static int drx_load_fw(struct drx397xD_state *s, fw_ix_t ix)
+{
+ const u8 *data;
+ size_t size, len;
+ int i = 0, j, rc = -EINVAL;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ if (ix < 0 || ix >= ARRAY_SIZE(fw))
+ return -EINVAL;
+ s->chip_rev = ix;
+
+ write_lock(&fw[ix].lock);
+ if (fw[ix].file) {
+ rc = 0;
+ goto exit_ok;
+ }
+ memset(&fw[ix].data[0], 0, sizeof(fw[0].data));
+
+ if (request_firmware(&fw[ix].file, fw[ix].name, &s->i2c->dev) != 0) {
+ printk(KERN_ERR "%s: Firmware \"%s\" not available\n",
+ mod_name, fw[ix].name);
+ rc = -ENOENT;
+ goto exit_err;
+ }
+
+ if (!fw[ix].file->data || fw[ix].file->size < 10)
+ goto exit_corrupt;
+
+ data = fw[ix].file->data;
+ size = fw[ix].file->size;
+
+ if (data[i++] != 2) /* check firmware version */
+ goto exit_corrupt;
+
+ do {
+ switch (data[i++]) {
+ case 0x00: /* bytecode */
+ if (i >= size)
+ break;
+ i += data[i];
+ case 0x01: /* reset */
+ case 0x02: /* sleep */
+ i++;
+ break;
+ case 0xfe: /* name */
+ len = strnlen(&data[i], size - i);
+ if (i + len + 1 >= size)
+ goto exit_corrupt;
+ if (data[i + len + 1] != 0)
+ goto exit_corrupt;
+ for (j = 0; j < ARRAY_SIZE(blob_name); j++) {
+ if (strcmp(blob_name[j], &data[i]) == 0) {
+ fw[ix].data[j] = &data[i + len + 1];
+ pr_debug("Loading %s\n", blob_name[j]);
+ }
+ }
+ i += len + 1;
+ break;
+ case 0xff: /* file terminator */
+ if (i == size) {
+ rc = 0;
+ goto exit_ok;
+ }
+ default:
+ goto exit_corrupt;
+ }
+ } while (i < size);
+ exit_corrupt:
+ printk(KERN_ERR "%s: Firmware is corrupt\n", mod_name);
+ exit_err:
+ _drx_release_fw(s, ix);
+ fw[ix].refcnt--;
+ exit_ok:
+ fw[ix].refcnt++;
+ write_unlock(&fw[ix].lock);
+ return rc;
+}
+
+/*******************************************************************************
+ * i2c bus IO
+ ******************************************************************************/
+
+static int write_fw(struct drx397xD_state *s, blob_ix_t ix)
+{
+ struct i2c_msg msg = {.addr = s->config.demod_address,.flags = 0 };
+ const u8 *data;
+ int len, rc = 0, i = 0;
+
+ if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) {
+ pr_debug("%s drx_fw_ix_t out of range\n", __FUNCTION__);
+ return -EINVAL;
+ }
+ pr_debug("%s %s\n", __FUNCTION__, blob_name[ix]);
+
+ read_lock(&fw[s->chip_rev].lock);
+ data = fw[s->chip_rev].data[ix];
+ if (!data) {
+ rc = -EINVAL;
+ goto exit_rc;
+ }
+
+ for (;;) {
+ switch (data[i++]) {
+ case 0: /* bytecode */
+ len = data[i++];
+ msg.len = len;
+ msg.buf = (__u8 *) &data[i];
+ if (i2c_transfer(s->i2c, &msg, 1) != 1) {
+ rc = -EIO;
+ goto exit_rc;
+ }
+ i += len;
+ break;
+ case 1: /* reset */
+ case 2: /* sleep */
+ i++;
+ break;
+ default:
+ goto exit_rc;
+ }
+ }
+ exit_rc:
+ read_unlock(&fw[s->chip_rev].lock);
+ return 0;
+}
+
+/* Function is not endian safe, use the RD16 wrapper below */
+static int _read16(struct drx397xD_state *s, u32 i2c_adr)
+{
+ int rc;
+ u8 a[4];
+ u16 v;
+ struct i2c_msg msg[2] = {
+ {
+ .addr = s->config.demod_address,
+ .flags = 0,
+ .buf = a,
+ .len = sizeof(a)
+ }
+ , {
+ .addr = s->config.demod_address,
+ .flags = I2C_M_RD,
+ .buf = (u8 *) & v,
+ .len = sizeof(v)
+ }
+ };
+
+ *(u32 *) a = i2c_adr;
+
+ rc = i2c_transfer(s->i2c, msg, 2);
+ if (rc != 2)
+ return -EIO;
+
+ return le16_to_cpu(v);
+}
+
+/* Function is not endian safe, use the WR16.. wrappers below */
+static int _write16(struct drx397xD_state *s, u32 i2c_adr, u16 val)
+{
+ u8 a[6];
+ int rc;
+ struct i2c_msg msg = {
+ .addr = s->config.demod_address,
+ .flags = 0,
+ .buf = a,
+ .len = sizeof(a)
+ };
+
+ *(u32 *) a = i2c_adr;
+ *(u16 *) & a[4] = val;
+
+ rc = i2c_transfer(s->i2c, &msg, 1);
+ if (rc != 1)
+ return -EIO;
+ return 0;
+}
+
+#define WR16(ss,adr, val) \
+ _write16(ss, I2C_ADR_C0(adr), cpu_to_le16(val))
+#define WR16_E0(ss,adr, val) \
+ _write16(ss, I2C_ADR_E0(adr), cpu_to_le16(val))
+#define RD16(ss,adr) \
+ _read16(ss, I2C_ADR_C0(adr))
+
+#define EXIT_RC( cmd ) if ( (rc = (cmd)) < 0) goto exit_rc
+
+/*******************************************************************************
+ * Tuner callback
+ ******************************************************************************/
+
+static int PLL_Set(struct drx397xD_state *s,
+ struct dvb_frontend_parameters *fep, int *df_tuner)
+{
+ struct dvb_frontend *fe = &s->frontend;
+ u32 f_tuner, f = fep->frequency;
+ int rc;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ if ((f > s->frontend.ops.tuner_ops.info.frequency_max) ||
+ (f < s->frontend.ops.tuner_ops.info.frequency_min))
+ return -EINVAL;
+
+ *df_tuner = 0;
+ if (!s->frontend.ops.tuner_ops.set_params ||
+ !s->frontend.ops.tuner_ops.get_frequency)
+ return -ENOSYS;
+
+ rc = s->frontend.ops.tuner_ops.set_params(fe, fep);
+ if (rc < 0)
+ return rc;
+
+ rc = s->frontend.ops.tuner_ops.get_frequency(fe, &f_tuner);
+ if (rc < 0)
+ return rc;
+
+ *df_tuner = f_tuner - f;
+ pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __FUNCTION__, f,
+ f_tuner);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Demodulator helper functions
+ ******************************************************************************/
+
+static int SC_WaitForReady(struct drx397xD_state *s)
+{
+ int cnt = 1000;
+ int rc;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ while (cnt--) {
+ rc = RD16(s, 0x820043);
+ if (rc == 0)
+ return 0;
+ }
+ return -1;
+}
+
+static int SC_SendCommand(struct drx397xD_state *s, int cmd)
+{
+ int rc;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ WR16(s, 0x820043, cmd);
+ SC_WaitForReady(s);
+ rc = RD16(s, 0x820042);
+ if ((rc & 0xffff) == 0xffff)
+ return -1;
+ return 0;
+}
+
+static int HI_Command(struct drx397xD_state *s, u16 cmd)
+{
+ int rc, cnt = 1000;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ rc = WR16(s, 0x420032, cmd);
+ if (rc < 0)
+ return rc;
+
+ do {
+ rc = RD16(s, 0x420032);
+ if (rc == 0) {
+ rc = RD16(s, 0x420031);
+ return rc;
+ }
+ if (rc < 0)
+ return rc;
+ } while (--cnt);
+ return rc;
+}
+
+static int HI_CfgCommand(struct drx397xD_state *s)
+{
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ WR16(s, 0x420033, 0x3973);
+ WR16(s, 0x420034, s->config.w50); // code 4, log 4
+ WR16(s, 0x420035, s->config.w52); // code 15, log 9
+ WR16(s, 0x420036, s->config.demod_address << 1);
+ WR16(s, 0x420037, s->config.w56); // code (set_i2c ?? initX 1 ), log 1
+// WR16(s, 0x420033, 0x3973);
+ if ((s->config.w56 & 8) == 0)
+ return HI_Command(s, 3);
+ return WR16(s, 0x420032, 0x3);
+}
+
+static const u8 fastIncrDecLUT_15273[] = {
+ 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18, 0x1a, 0x1b, 0x1c, 0x1d, 0x1f
+};
+
+static const u8 slowIncrDecLUT_15272[] = {
+ 3, 4, 4, 5, 6
+};
+
+static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc)
+{
+ u16 w06 = agc->w06;
+ u16 w08 = agc->w08;
+ u16 w0A = agc->w0A;
+ u16 w0C = agc->w0C;
+ int quot, rem, i, rc = -EINVAL;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ if (agc->w04 > 0x3ff)
+ goto exit_rc;
+
+ if (agc->d00 == 1) {
+ EXIT_RC(RD16(s, 0x0c20010));
+ rc &= ~0x10;
+ EXIT_RC(WR16(s, 0x0c20010, rc));
+ return WR16(s, 0x0c20030, agc->w04 & 0x7ff);
+ }
+
+ if (agc->d00 != 0)
+ goto exit_rc;
+ if (w0A < w08)
+ goto exit_rc;
+ if (w0A > 0x3ff)
+ goto exit_rc;
+ if (w0C > 0x3ff)
+ goto exit_rc;
+ if (w06 > 0x3ff)
+ goto exit_rc;
+
+ EXIT_RC(RD16(s, 0x0c20010));
+ rc |= 0x10;
+ EXIT_RC(WR16(s, 0x0c20010, rc));
+
+ EXIT_RC(WR16(s, 0x0c20025, (w06 >> 1) & 0x1ff));
+ EXIT_RC(WR16(s, 0x0c20031, (w0A - w08) >> 1));
+ EXIT_RC(WR16(s, 0x0c20032, ((w0A + w08) >> 1) - 0x1ff));
+
+ quot = w0C / 113;
+ rem = w0C % 113;
+ if (quot <= 8) {
+ quot = 8 - quot;
+ } else {
+ quot = 0;
+ rem += 113;
+ }
+
+ EXIT_RC(WR16(s, 0x0c20024, quot));
+
+ i = fastIncrDecLUT_15273[rem / 8];
+ EXIT_RC(WR16(s, 0x0c2002d, i));
+ EXIT_RC(WR16(s, 0x0c2002e, i));
+
+ i = slowIncrDecLUT_15272[rem / 28];
+ EXIT_RC(WR16(s, 0x0c2002b, i));
+ rc = WR16(s, 0x0c2002c, i);
+ exit_rc:
+ return rc;
+}
+
+static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc)
+{
+ u16 w04 = agc->w04;
+ u16 w06 = agc->w06;
+ int rc = -1;
+
+ pr_debug("%s %d 0x%x 0x%x\n", __FUNCTION__, agc->d00, w04, w06);
+
+ if (w04 > 0x3ff)
+ goto exit_rc;
+
+ switch (agc->d00) {
+ case 1:
+ if (w04 == 0x3ff)
+ w04 = 0x400;
+
+ EXIT_RC(WR16(s, 0x0c20036, w04));
+ s->config.w9C &= ~2;
+ EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
+ EXIT_RC(RD16(s, 0x0c20010));
+ rc &= 0xbfdf;
+ EXIT_RC(WR16(s, 0x0c20010, rc));
+ EXIT_RC(RD16(s, 0x0c20013));
+ rc &= ~2;
+ break;
+ case 0:
+ // loc_8000659
+ s->config.w9C &= ~2;
+ EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
+ EXIT_RC(RD16(s, 0x0c20010));
+ rc &= 0xbfdf;
+ rc |= 0x4000;
+ EXIT_RC(WR16(s, 0x0c20010, rc));
+ EXIT_RC(WR16(s, 0x0c20051, (w06 >> 4) & 0x3f));
+ EXIT_RC(RD16(s, 0x0c20013));
+ rc &= ~2;
+ break;
+ default:
+ s->config.w9C |= 2;
+ EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
+ EXIT_RC(RD16(s, 0x0c20010));
+ rc &= 0xbfdf;
+ EXIT_RC(WR16(s, 0x0c20010, rc));
+
+ EXIT_RC(WR16(s, 0x0c20036, 0));
+
+ EXIT_RC(RD16(s, 0x0c20013));
+ rc |= 2;
+ }
+ rc = WR16(s, 0x0c20013, rc);
+ exit_rc:
+ return rc;
+}
+
+static int GetLockStatus(struct drx397xD_state *s, int *lockstat)
+{
+ int rc;
+
+ *lockstat = 0;
+
+ rc = RD16(s, 0x082004b);
+ if (rc < 0)
+ return rc;
+
+ if (s->config.d60 != 2)
+ return 0;
+
+ if ((rc & 7) == 7)
+ *lockstat |= 1;
+ if ((rc & 3) == 3)
+ *lockstat |= 2;
+ if (rc & 1)
+ *lockstat |= 4;
+ return 0;
+}
+
+static int CorrectSysClockDeviation(struct drx397xD_state *s)
+{
+ int rc = -EINVAL;
+ int lockstat;
+ u32 clk, clk_limit;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ if (s->config.d5C == 0) {
+ EXIT_RC(WR16(s, 0x08200e8, 0x010));
+ EXIT_RC(WR16(s, 0x08200e9, 0x113));
+ s->config.d5C = 1;
+ return rc;
+ }
+ if (s->config.d5C != 1)
+ goto exit_rc;
+
+ rc = RD16(s, 0x0820048);
+
+ rc = GetLockStatus(s, &lockstat);
+ if (rc < 0)
+ goto exit_rc;
+ if ((lockstat & 1) == 0)
+ goto exit_rc;
+
+ EXIT_RC(WR16(s, 0x0420033, 0x200));
+ EXIT_RC(WR16(s, 0x0420034, 0xc5));
+ EXIT_RC(WR16(s, 0x0420035, 0x10));
+ EXIT_RC(WR16(s, 0x0420036, 0x1));
+ EXIT_RC(WR16(s, 0x0420037, 0xa));
+ EXIT_RC(HI_Command(s, 6));
+ EXIT_RC(RD16(s, 0x0420040));
+ clk = rc;
+ EXIT_RC(RD16(s, 0x0420041));
+ clk |= rc << 16;
+
+ if (clk <= 0x26ffff)
+ goto exit_rc;
+ if (clk > 0x610000)
+ goto exit_rc;
+
+ if (!s->bandwidth_parm)
+ return -EINVAL;
+
+ /* round & convert to Hz */
+ clk = ((u64) (clk + 0x800000) * s->bandwidth_parm + (1 << 20)) >> 21;
+ clk_limit = s->config.f_osc * MAX_CLOCK_DRIFT / 1000;
+
+ if (clk - s->config.f_osc * 1000 + clk_limit <= 2 * clk_limit) {
+ s->f_osc = clk;
+ pr_debug("%s: osc %d %d [Hz]\n", __FUNCTION__,
+ s->config.f_osc * 1000, clk - s->config.f_osc * 1000);
+ }
+ rc = WR16(s, 0x08200e8, 0);
+ exit_rc:
+ return rc;
+}
+
+static int ConfigureMPEGOutput(struct drx397xD_state *s, int type)
+{
+ int rc, si, bp;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ si = s->config.wA0;
+ if (s->config.w98 == 0) {
+ si |= 1;
+ bp = 0;
+ } else {
+ si &= ~1;
+ bp = 0x200;
+ }
+ if (s->config.w9A == 0) {
+ si |= 0x80;
+ } else {
+ si &= ~0x80;
+ }
+
+ EXIT_RC(WR16(s, 0x2150045, 0));
+ EXIT_RC(WR16(s, 0x2150010, si));
+ EXIT_RC(WR16(s, 0x2150011, bp));
+ rc = WR16(s, 0x2150012, (type == 0 ? 0xfff : 0));
+ exit_rc:
+ return rc;
+}
+
+static int drx_tune(struct drx397xD_state *s,
+ struct dvb_frontend_parameters *fep)
+{
+ u16 v22 = 0;
+ u16 v1C = 0;
+ u16 v1A = 0;
+ u16 v18 = 0;
+ u32 edi = 0, ebx = 0, ebp = 0, edx = 0;
+ u16 v20 = 0, v1E = 0, v16 = 0, v14 = 0, v12 = 0, v10 = 0, v0E = 0;
+
+ int rc, df_tuner;
+ int a, b, c, d;
+ pr_debug("%s %d\n", __FUNCTION__, s->config.d60);
+
+ if (s->config.d60 != 2)
+ goto set_tuner;
+ rc = CorrectSysClockDeviation(s);
+ if (rc < 0)
+ goto set_tuner;
+
+ s->config.d60 = 1;
+ rc = ConfigureMPEGOutput(s, 0);
+ if (rc < 0)
+ goto set_tuner;
+ set_tuner:
+
+ rc = PLL_Set(s, fep, &df_tuner);
+ if (rc < 0) {
+ printk(KERN_ERR "Error in pll_set\n");
+ goto exit_rc;
+ }
+ msleep(200);
+
+ a = rc = RD16(s, 0x2150016);
+ if (rc < 0)
+ goto exit_rc;
+ b = rc = RD16(s, 0x2150010);
+ if (rc < 0)
+ goto exit_rc;
+ c = rc = RD16(s, 0x2150034);
+ if (rc < 0)
+ goto exit_rc;
+ d = rc = RD16(s, 0x2150035);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2150014, c);
+ rc = WR16(s, 0x2150015, d);
+ rc = WR16(s, 0x2150010, 0);
+ rc = WR16(s, 0x2150000, 2);
+ rc = WR16(s, 0x2150036, 0x0fff);
+ rc = WR16(s, 0x2150016, a);
+
+ rc = WR16(s, 0x2150010, 2);
+ rc = WR16(s, 0x2150007, 0);
+ rc = WR16(s, 0x2150000, 1);
+ rc = WR16(s, 0x2110000, 0);
+ rc = WR16(s, 0x0800000, 0);
+ rc = WR16(s, 0x2800000, 0);
+ rc = WR16(s, 0x2110010, 0x664);
+
+ rc = write_fw(s, DRXD_ResetECRAM);
+ rc = WR16(s, 0x2110000, 1);
+
+ rc = write_fw(s, DRXD_InitSC);
+ if (rc < 0)
+ goto exit_rc;
+
+ rc = SetCfgIfAgc(s, &s->config.ifagc);
+ if (rc < 0)
+ goto exit_rc;
+
+ rc = SetCfgRfAgc(s, &s->config.rfagc);
+ if (rc < 0)
+ goto exit_rc;
+
+ if (fep->u.ofdm.transmission_mode != TRANSMISSION_MODE_2K)
+ v22 = 1;
+ switch (fep->u.ofdm.transmission_mode) {
+ case TRANSMISSION_MODE_8K:
+ edi = 1;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+
+ rc = WR16(s, 0x2010010, 0);
+ if (rc < 0)
+ break;
+ v1C = 0x63;
+ v1A = 0x53;
+ v18 = 0x43;
+ break;
+ default:
+ edi = 0;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+
+ rc = WR16(s, 0x2010010, 1);
+ if (rc < 0)
+ break;
+
+ v1C = 0x61;
+ v1A = 0x47;
+ v18 = 0x41;
+ }
+
+ switch (fep->u.ofdm.guard_interval) {
+ case GUARD_INTERVAL_1_4:
+ edi |= 0x0c;
+ break;
+ case GUARD_INTERVAL_1_8:
+ edi |= 0x08;
+ break;
+ case GUARD_INTERVAL_1_16:
+ edi |= 0x04;
+ break;
+ case GUARD_INTERVAL_1_32:
+ break;
+ default:
+ v22 |= 2;
+ }
+
+ ebx = 0;
+ ebp = 0;
+ v20 = 0;
+ v1E = 0;
+ v16 = 0;
+ v14 = 0;
+ v12 = 0;
+ v10 = 0;
+ v0E = 0;
+
+ switch (fep->u.ofdm.hierarchy_information) {
+ case HIERARCHY_1:
+ edi |= 0x40;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x1c10047, 1);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2010012, 1);
+ if (rc < 0)
+ goto exit_rc;
+ ebx = 0x19f;
+ ebp = 0x1fb;
+ v20 = 0x0c0;
+ v1E = 0x195;
+ v16 = 0x1d6;
+ v14 = 0x1ef;
+ v12 = 4;
+ v10 = 5;
+ v0E = 5;
+ break;
+ case HIERARCHY_2:
+ edi |= 0x80;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x1c10047, 2);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2010012, 2);
+ if (rc < 0)
+ goto exit_rc;
+ ebx = 0x08f;
+ ebp = 0x12f;
+ v20 = 0x0c0;
+ v1E = 0x11e;
+ v16 = 0x1d6;
+ v14 = 0x15e;
+ v12 = 4;
+ v10 = 5;
+ v0E = 5;
+ break;
+ case HIERARCHY_4:
+ edi |= 0xc0;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x1c10047, 3);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2010012, 3);
+ if (rc < 0)
+ goto exit_rc;
+ ebx = 0x14d;
+ ebp = 0x197;
+ v20 = 0x0c0;
+ v1E = 0x1ce;
+ v16 = 0x1d6;
+ v14 = 0x11a;
+ v12 = 4;
+ v10 = 6;
+ v0E = 5;
+ break;
+ default:
+ v22 |= 8;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x1c10047, 0);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2010012, 0);
+ if (rc < 0)
+ goto exit_rc;
+ // QPSK QAM16 QAM64
+ ebx = 0x19f; // 62
+ ebp = 0x1fb; // 15
+ v20 = 0x16a; // 62
+ v1E = 0x195; // 62
+ v16 = 0x1bb; // 15
+ v14 = 0x1ef; // 15
+ v12 = 5; // 16
+ v10 = 5; // 16
+ v0E = 5; // 16
+ }
+
+ switch (fep->u.ofdm.constellation) {
+ default:
+ v22 |= 4;
+ case QPSK:
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+
+ rc = WR16(s, 0x1c10046, 0);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2010011, 0);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001a, 0x10);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001b, 0);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001c, 0);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10062, v20);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c1002a, v1C);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10015, v16);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10016, v12);
+ if (rc < 0)
+ goto exit_rc;
+ break;
+ case QAM_16:
+ edi |= 0x10;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+
+ rc = WR16(s, 0x1c10046, 1);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2010011, 1);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001a, 0x10);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001b, 4);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001c, 0);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10062, v1E);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c1002a, v1A);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10015, v14);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10016, v10);
+ if (rc < 0)
+ goto exit_rc;
+ break;
+ case QAM_64:
+ edi |= 0x20;
+ rc = WR16(s, 0x1c10046, 2);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2010011, 2);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001a, 0x20);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001b, 8);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001c, 2);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10062, ebx);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c1002a, v18);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10015, ebp);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10016, v0E);
+ if (rc < 0)
+ goto exit_rc;
+ break;
+ }
+
+ if (s->config.s20d24 == 1) {
+ rc = WR16(s, 0x2010013, 0);
+ } else {
+ rc = WR16(s, 0x2010013, 1);
+ edi |= 0x1000;
+ }
+
+ switch (fep->u.ofdm.code_rate_HP) {
+ default:
+ v22 |= 0x10;
+ case FEC_1_2:
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x2090011, 0);
+ break;
+ case FEC_2_3:
+ edi |= 0x200;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x2090011, 1);
+ break;
+ case FEC_3_4:
+ edi |= 0x400;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x2090011, 2);
+ break;
+ case FEC_5_6: /* 5 */
+ edi |= 0x600;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x2090011, 3);
+ break;
+ case FEC_7_8: /* 7 */
+ edi |= 0x800;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x2090011, 4);
+ break;
+ };
+ if (rc < 0)
+ goto exit_rc;
+
+ switch (fep->u.ofdm.bandwidth) {
+ default:
+ rc = -EINVAL;
+ goto exit_rc;
+ case BANDWIDTH_8_MHZ: /* 0 */
+ case BANDWIDTH_AUTO:
+ rc = WR16(s, 0x0c2003f, 0x32);
+ s->bandwidth_parm = ebx = 0x8b8249; // 9142857
+ edx = 0;
+ break;
+ case BANDWIDTH_7_MHZ:
+ rc = WR16(s, 0x0c2003f, 0x3b);
+ s->bandwidth_parm = ebx = 0x7a1200; // 8000000
+ edx = 0x4807;
+ break;
+ case BANDWIDTH_6_MHZ:
+ rc = WR16(s, 0x0c2003f, 0x47);
+ s->bandwidth_parm = ebx = 0x68a1b6; // 6857142
+ edx = 0x0f07;
+ break;
+ };
+
+ if (rc < 0)
+ goto exit_rc;
+
+ rc = WR16(s, 0x08200ec, edx);
+ if (rc < 0)
+ goto exit_rc;
+
+ rc = RD16(s, 0x0820050);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x0820050, rc);
+
+ {
+ /* Configure bandwidth specific factor */
+ ebx = div64_u64(((u64) (s->f_osc) << 21) + (ebx >> 1),
+ (u64)ebx) - 0x800000;
+ EXIT_RC(WR16(s, 0x0c50010, ebx & 0xffff));
+ EXIT_RC(WR16(s, 0x0c50011, ebx >> 16));
+
+ /* drx397xD oscillator calibration */
+ ebx = div64_u64(((u64) (s->config.f_if + df_tuner) << 28) +
+ (s->f_osc >> 1), (u64)s->f_osc);
+ }
+ ebx &= 0xfffffff;
+ if (fep->inversion == INVERSION_ON)
+ ebx = 0x10000000 - ebx;
+
+ EXIT_RC(WR16(s, 0x0c30010, ebx & 0xffff));
+ EXIT_RC(WR16(s, 0x0c30011, ebx >> 16));
+
+ EXIT_RC(WR16(s, 0x0800000, 1));
+ EXIT_RC(RD16(s, 0x0800000));
+
+
+ EXIT_RC(SC_WaitForReady(s));
+ EXIT_RC(WR16(s, 0x0820042, 0));
+ EXIT_RC(WR16(s, 0x0820041, v22));
+ EXIT_RC(WR16(s, 0x0820040, edi));
+ EXIT_RC(SC_SendCommand(s, 3));
+
+ rc = RD16(s, 0x0800000);
+
+ SC_WaitForReady(s);
+ WR16(s, 0x0820042, 0);
+ WR16(s, 0x0820041, 1);
+ WR16(s, 0x0820040, 1);
+ SC_SendCommand(s, 1);
+
+// rc = WR16(s, 0x2150000, 1);
+// if (rc < 0) goto exit_rc;
+
+ rc = WR16(s, 0x2150000, 2);
+ rc = WR16(s, 0x2150016, a);
+ rc = WR16(s, 0x2150010, 4);
+ rc = WR16(s, 0x2150036, 0);
+ rc = WR16(s, 0x2150000, 1);
+ s->config.d60 = 2;
+ exit_rc:
+ return rc;
+}
+
+/*******************************************************************************
+ * DVB interface
+ ******************************************************************************/
+
+static int drx397x_init(struct dvb_frontend *fe)
+{
+ struct drx397xD_state *s = fe->demodulator_priv;
+ int rc;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ s->config.rfagc.d00 = 2; /* 0x7c */
+ s->config.rfagc.w04 = 0;
+ s->config.rfagc.w06 = 0x3ff;
+
+ s->config.ifagc.d00 = 0; /* 0x68 */
+ s->config.ifagc.w04 = 0;
+ s->config.ifagc.w06 = 140;
+ s->config.ifagc.w08 = 0;
+ s->config.ifagc.w0A = 0x3ff;
+ s->config.ifagc.w0C = 0x388;
+
+ /* for signal strenght calculations */
+ s->config.ss76 = 820;
+ s->config.ss78 = 2200;
+ s->config.ss7A = 150;
+
+ /* HI_CfgCommand */
+ s->config.w50 = 4;
+ s->config.w52 = 9; // 0xf;
+
+ s->config.f_if = 42800000; /* d14: intermediate frequency [Hz] */
+ s->config.f_osc = 48000; /* s66 : oscillator frequency [kHz] */
+ s->config.w92 = 12000; // 20000;
+
+ s->config.w9C = 0x000e;
+ s->config.w9E = 0x0000;
+
+ /* ConfigureMPEGOutput params */
+ s->config.wA0 = 4;
+ s->config.w98 = 1; // 0;
+ s->config.w9A = 1;
+
+ /* get chip revision */
+ rc = RD16(s, 0x2410019);
+ if (rc < 0)
+ return -ENODEV;
+
+ if (rc == 0) {
+ printk(KERN_INFO "%s: chip revision A2\n", mod_name);
+ rc = drx_load_fw(s, DRXD_FW_A2);
+ } else {
+
+ rc = (rc >> 12) - 3;
+ switch (rc) {
+ case 1:
+ s->flags |= F_SET_0D4h;
+ case 0:
+ case 4:
+ s->flags |= F_SET_0D0h;
+ break;
+ case 2:
+ case 5:
+ break;
+ case 3:
+ s->flags |= F_SET_0D4h;
+ break;
+ default:
+ return -ENODEV;
+ };
+ printk(KERN_INFO "%s: chip revision B1.%d\n", mod_name, rc);
+ rc = drx_load_fw(s, DRXD_FW_B1);
+ }
+ if (rc < 0)
+ goto error;
+
+ rc = WR16(s, 0x0420033, 0x3973);
+ if (rc < 0)
+ goto error;
+
+ rc = HI_Command(s, 2);
+
+ msleep(1);
+
+ if (s->chip_rev == DRXD_FW_A2) {
+ rc = WR16(s, 0x043012d, 0x47F);
+ if (rc < 0)
+ goto error;
+ }
+ rc = WR16_E0(s, 0x0400000, 0);
+ if (rc < 0)
+ goto error;
+
+ if (s->config.w92 > 20000 || s->config.w92 % 4000) {
+ printk(KERN_ERR "%s: invalid osc frequency\n", mod_name);
+ rc = -1;
+ goto error;
+ }
+
+ rc = WR16(s, 0x2410010, 1);
+ if (rc < 0)
+ goto error;
+ rc = WR16(s, 0x2410011, 0x15);
+ if (rc < 0)
+ goto error;
+ rc = WR16(s, 0x2410012, s->config.w92 / 4000);
+ if (rc < 0)
+ goto error;
+#ifdef ORIG_FW
+ rc = WR16(s, 0x2410015, 2);
+ if (rc < 0)
+ goto error;
+#endif
+ rc = WR16(s, 0x2410017, 0x3973);
+ if (rc < 0)
+ goto error;
+
+ s->f_osc = s->config.f_osc * 1000; /* initial estimator */
+
+ s->config.w56 = 1;
+
+ rc = HI_CfgCommand(s);
+ if (rc < 0)
+ goto error;
+
+ rc = write_fw(s, DRXD_InitAtomicRead);
+ if (rc < 0)
+ goto error;
+
+ if (s->chip_rev == DRXD_FW_A2) {
+ rc = WR16(s, 0x2150013, 0);
+ if (rc < 0)
+ goto error;
+ }
+
+ rc = WR16_E0(s, 0x0400002, 0);
+ if (rc < 0)
+ goto error;
+ rc = WR16(s, 0x0400002, 0);
+ if (rc < 0)
+ goto error;
+
+ if (s->chip_rev == DRXD_FW_A2) {
+ rc = write_fw(s, DRXD_ResetCEFR);
+ if (rc < 0)
+ goto error;
+ }
+ rc = write_fw(s, DRXD_microcode);
+ if (rc < 0)
+ goto error;
+
+ s->config.w9C = 0x0e;
+ if (s->flags & F_SET_0D0h) {
+ s->config.w9C = 0;
+ rc = RD16(s, 0x0c20010);
+ if (rc < 0)
+ goto write_DRXD_InitFE_1;
+
+ rc &= ~0x1000;
+ rc = WR16(s, 0x0c20010, rc);
+ if (rc < 0)
+ goto write_DRXD_InitFE_1;
+
+ rc = RD16(s, 0x0c20011);
+ if (rc < 0)
+ goto write_DRXD_InitFE_1;
+
+ rc &= ~0x8;
+ rc = WR16(s, 0x0c20011, rc);
+ if (rc < 0)
+ goto write_DRXD_InitFE_1;
+
+ rc = WR16(s, 0x0c20012, 1);
+ }
+
+ write_DRXD_InitFE_1:
+
+ rc = write_fw(s, DRXD_InitFE_1);
+ if (rc < 0)
+ goto error;
+
+ rc = 1;
+ if (s->chip_rev == DRXD_FW_B1) {
+ if (s->flags & F_SET_0D0h)
+ rc = 0;
+ } else {
+ if (s->flags & F_SET_0D0h)
+ rc = 4;
+ }
+
+ rc = WR16(s, 0x0C20012, rc);
+ if (rc < 0)
+ goto error;
+
+ rc = WR16(s, 0x0C20013, s->config.w9E);
+ if (rc < 0)
+ goto error;
+ rc = WR16(s, 0x0C20015, s->config.w9C);
+ if (rc < 0)
+ goto error;
+
+ rc = write_fw(s, DRXD_InitFE_2);
+ if (rc < 0)
+ goto error;
+ rc = write_fw(s, DRXD_InitFT);
+ if (rc < 0)
+ goto error;
+ rc = write_fw(s, DRXD_InitCP);
+ if (rc < 0)
+ goto error;
+ rc = write_fw(s, DRXD_InitCE);
+ if (rc < 0)
+ goto error;
+ rc = write_fw(s, DRXD_InitEQ);
+ if (rc < 0)
+ goto error;
+ rc = write_fw(s, DRXD_InitEC);
+ if (rc < 0)
+ goto error;
+ rc = write_fw(s, DRXD_InitSC);
+ if (rc < 0)
+ goto error;
+
+ rc = SetCfgIfAgc(s, &s->config.ifagc);
+ if (rc < 0)
+ goto error;
+
+ rc = SetCfgRfAgc(s, &s->config.rfagc);
+ if (rc < 0)
+ goto error;
+
+ rc = ConfigureMPEGOutput(s, 1);
+ rc = WR16(s, 0x08201fe, 0x0017);
+ rc = WR16(s, 0x08201ff, 0x0101);
+
+ s->config.d5C = 0;
+ s->config.d60 = 1;
+ s->config.d48 = 1;
+ error:
+ return rc;
+}
+
+static int drx397x_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ return 0;
+}
+
+static int drx397x_set_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct drx397xD_state *s = fe->demodulator_priv;
+
+ s->config.s20d24 = 1; // 0;
+ return drx_tune(s, params);
+}
+
+static int drx397x_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings
+ *fe_tune_settings)
+{
+ fe_tune_settings->min_delay_ms = 10000;
+ fe_tune_settings->step_size = 0;
+ fe_tune_settings->max_drift = 0;
+ return 0;
+}
+
+static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t * status)
+{
+ struct drx397xD_state *s = fe->demodulator_priv;
+ int lockstat;
+
+ GetLockStatus(s, &lockstat);
+ /* TODO */
+// if (lockstat & 1)
+// CorrectSysClockDeviation(s);
+
+ *status = 0;
+ if (lockstat & 2) {
+ CorrectSysClockDeviation(s);
+ ConfigureMPEGOutput(s, 1);
+ *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
+ }
+ if (lockstat & 4) {
+ *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+ }
+
+ return 0;
+}
+
+static int drx397x_read_ber(struct dvb_frontend *fe, unsigned int *ber)
+{
+ *ber = 0;
+ return 0;
+}
+
+static int drx397x_read_snr(struct dvb_frontend *fe, u16 * snr)
+{
+ *snr = 0;
+ return 0;
+}
+
+static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
+{
+ struct drx397xD_state *s = fe->demodulator_priv;
+ int rc;
+
+ if (s->config.ifagc.d00 == 2) {
+ *strength = 0xffff;
+ return 0;
+ }
+ rc = RD16(s, 0x0c20035);
+ if (rc < 0) {
+ *strength = 0;
+ return 0;
+ }
+ rc &= 0x3ff;
+ /* Signal strength is calculated using the following formula:
+ *
+ * a = 2200 * 150 / (2200 + 150);
+ * a = a * 3300 / (a + 820);
+ * b = 2200 * 3300 / (2200 + 820);
+ * c = (((b-a) * rc) >> 10 + a) << 4;
+ * strength = ~c & 0xffff;
+ *
+ * The following does the same but with less rounding errors:
+ */
+ *strength = ~(7720 + (rc * 30744 >> 10));
+ return 0;
+}
+
+static int drx397x_read_ucblocks(struct dvb_frontend *fe,
+ unsigned int *ucblocks)
+{
+ *ucblocks = 0;
+ return 0;
+}
+
+static int drx397x_sleep(struct dvb_frontend *fe)
+{
+ return 0;
+}
+
+static void drx397x_release(struct dvb_frontend *fe)
+{
+ struct drx397xD_state *s = fe->demodulator_priv;
+ printk(KERN_INFO "%s: release demodulator\n", mod_name);
+ if (s) {
+ drx_release_fw(s);
+ kfree(s);
+ }
+
+}
+
+static struct dvb_frontend_ops drx397x_ops = {
+
+ .info = {
+ .name = "Micronas DRX397xD DVB-T Frontend",
+ .type = FE_OFDM,
+ .frequency_min = 47125000,
+ .frequency_max = 855250000,
+ .frequency_stepsize = 166667,
+ .frequency_tolerance = 0,
+ .caps = /* 0x0C01B2EAE */
+ FE_CAN_FEC_1_2 | // = 0x2,
+ FE_CAN_FEC_2_3 | // = 0x4,
+ FE_CAN_FEC_3_4 | // = 0x8,
+ FE_CAN_FEC_5_6 | // = 0x20,
+ FE_CAN_FEC_7_8 | // = 0x80,
+ FE_CAN_FEC_AUTO | // = 0x200,
+ FE_CAN_QPSK | // = 0x400,
+ FE_CAN_QAM_16 | // = 0x800,
+ FE_CAN_QAM_64 | // = 0x2000,
+ FE_CAN_QAM_AUTO | // = 0x10000,
+ FE_CAN_TRANSMISSION_MODE_AUTO | // = 0x20000,
+ FE_CAN_GUARD_INTERVAL_AUTO | // = 0x80000,
+ FE_CAN_HIERARCHY_AUTO | // = 0x100000,
+ FE_CAN_RECOVER | // = 0x40000000,
+ FE_CAN_MUTE_TS // = 0x80000000
+ },
+
+ .release = drx397x_release,
+ .init = drx397x_init,
+ .sleep = drx397x_sleep,
+
+ .set_frontend = drx397x_set_frontend,
+ .get_tune_settings = drx397x_get_tune_settings,
+ .get_frontend = drx397x_get_frontend,
+
+ .read_status = drx397x_read_status,
+ .read_snr = drx397x_read_snr,
+ .read_signal_strength = drx397x_read_signal_strength,
+ .read_ber = drx397x_read_ber,
+ .read_ucblocks = drx397x_read_ucblocks,
+};
+
+struct dvb_frontend *drx397xD_attach(const struct drx397xD_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct drx397xD_state *s = NULL;
+
+ /* allocate memory for the internal state */
+ s = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL);
+ if (s == NULL)
+ goto error;
+
+ /* setup the state */
+ s->i2c = i2c;
+ memcpy(&s->config, config, sizeof(struct drx397xD_config));
+
+ /* check if the demod is there */
+ if (RD16(s, 0x2410019) < 0)
+ goto error;
+
+ /* create dvb_frontend */
+ memcpy(&s->frontend.ops, &drx397x_ops, sizeof(struct dvb_frontend_ops));
+ s->frontend.demodulator_priv = s;
+
+ return &s->frontend;
+ error:
+ kfree(s);
+ return NULL;
+}
+
+MODULE_DESCRIPTION("Micronas DRX397xD DVB-T Frontend");
+MODULE_AUTHOR("Henk Vergonet");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(drx397xD_attach);
diff --git a/drivers/media/dvb/frontends/drx397xD.h b/drivers/media/dvb/frontends/drx397xD.h
new file mode 100644
index 00000000000..ddc7a07971b
--- /dev/null
+++ b/drivers/media/dvb/frontends/drx397xD.h
@@ -0,0 +1,130 @@
+/*
+ * Driver for Micronas DVB-T drx397xD demodulator
+ *
+ * Copyright (C) 2007 Henk vergonet <Henk.Vergonet@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef _DRX397XD_H_INCLUDED
+#define _DRX397XD_H_INCLUDED
+
+#include <linux/dvb/frontend.h>
+
+#define DRX_F_STEPSIZE 166667
+#define DRX_F_OFFSET 36000000
+
+#define I2C_ADR_C0(x) \
+( (u32)cpu_to_le32( \
+ (u32)( \
+ (((u32)(x) & (u32)0x000000ffUL) ) | \
+ (((u32)(x) & (u32)0x0000ff00UL) << 16) | \
+ (((u32)(x) & (u32)0x0fff0000UL) >> 8) | \
+ ( (u32)0x00c00000UL) \
+ )) \
+)
+
+#define I2C_ADR_E0(x) \
+( (u32)cpu_to_le32( \
+ (u32)( \
+ (((u32)(x) & (u32)0x000000ffUL) ) | \
+ (((u32)(x) & (u32)0x0000ff00UL) << 16) | \
+ (((u32)(x) & (u32)0x0fff0000UL) >> 8) | \
+ ( (u32)0x00e00000UL) \
+ )) \
+)
+
+struct drx397xD_CfgRfAgc /* 0x7c */
+{
+ int d00; /* 2 */
+ u16 w04;
+ u16 w06;
+};
+
+struct drx397xD_CfgIfAgc /* 0x68 */
+{
+ int d00; /* 0 */
+ u16 w04; /* 0 */
+ u16 w06;
+ u16 w08;
+ u16 w0A;
+ u16 w0C;
+};
+
+struct drx397xD_s20 {
+ int d04;
+ u32 d18;
+ u32 d1C;
+ u32 d20;
+ u32 d14;
+ u32 d24;
+ u32 d0C;
+ u32 d08;
+};
+
+struct drx397xD_config
+{
+ /* demodulator's I2C address */
+ u8 demod_address; /* 0x0f */
+
+ struct drx397xD_CfgIfAgc ifagc; /* 0x68 */
+ struct drx397xD_CfgRfAgc rfagc; /* 0x7c */
+ u32 s20d24;
+
+ /* HI_CfgCommand parameters */
+ u16 w50, w52, /* w54, */ w56;
+
+ int d5C;
+ int d60;
+ int d48;
+ int d28;
+
+ u32 f_if; /* d14: intermediate frequency [Hz] */
+ /* 36000000 on Cinergy 2400i DT */
+ /* 42800000 on Pinnacle Hybrid PRO 330e */
+
+ u16 f_osc; /* s66: 48000 oscillator frequency [kHz] */
+
+ u16 w92; /* 20000 */
+
+ u16 wA0;
+ u16 w98;
+ u16 w9A;
+
+ u16 w9C; /* 0xe0 */
+ u16 w9E; /* 0x00 */
+
+ /* used for signal strength calculations in
+ drx397x_read_signal_strength
+ */
+ u16 ss78; // 2200
+ u16 ss7A; // 150
+ u16 ss76; // 820
+};
+
+#if defined(CONFIG_DVB_DRX397XD) || (defined(CONFIG_DVB_DRX397XD_MODULE) && defined(MODULE))
+extern struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config,
+ struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_DRX397XD */
+
+#endif /* _DRX397XD_H_INCLUDED */
diff --git a/drivers/media/dvb/frontends/drx397xD_fw.h b/drivers/media/dvb/frontends/drx397xD_fw.h
new file mode 100644
index 00000000000..01de02a81cd
--- /dev/null
+++ b/drivers/media/dvb/frontends/drx397xD_fw.h
@@ -0,0 +1,40 @@
+/*
+ * Firmware definitions for Micronas drx397xD
+ *
+ * Copyright (C) 2007 Henk Vergonet <Henk.Vergonet@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef _FW_ENTRY
+ _FW_ENTRY("drx397xD.A2.fw", DRXD_FW_A2 = 0 ),
+ _FW_ENTRY("drx397xD.B1.fw", DRXD_FW_B1 ),
+#undef _FW_ENTRY
+#endif /* _FW_ENTRY */
+
+#ifdef _BLOB_ENTRY
+ _BLOB_ENTRY("InitAtomicRead", DRXD_InitAtomicRead = 0 ),
+ _BLOB_ENTRY("InitCE", DRXD_InitCE ),
+ _BLOB_ENTRY("InitCP", DRXD_InitCP ),
+ _BLOB_ENTRY("InitEC", DRXD_InitEC ),
+ _BLOB_ENTRY("InitEQ", DRXD_InitEQ ),
+ _BLOB_ENTRY("InitFE_1", DRXD_InitFE_1 ),
+ _BLOB_ENTRY("InitFE_2", DRXD_InitFE_2 ),
+ _BLOB_ENTRY("InitFT", DRXD_InitFT ),
+ _BLOB_ENTRY("InitSC", DRXD_InitSC ),
+ _BLOB_ENTRY("ResetCEFR", DRXD_ResetCEFR ),
+ _BLOB_ENTRY("ResetECRAM", DRXD_ResetECRAM ),
+ _BLOB_ENTRY("microcode", DRXD_microcode ),
+#undef _BLOB_ENTRY
+#endif /* _BLOB_ENTRY */
diff --git a/drivers/media/dvb/frontends/z0194a.h b/drivers/media/dvb/frontends/z0194a.h
new file mode 100644
index 00000000000..d2876d2e176
--- /dev/null
+++ b/drivers/media/dvb/frontends/z0194a.h
@@ -0,0 +1,97 @@
+/* z0194a.h Sharp z0194a tuner support
+*
+* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
+*
+* 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.
+*
+* see Documentation/dvb/README.dvb-usb for more information
+*/
+
+#ifndef Z0194A
+#define Z0194A
+
+static int sharp_z0194a__set_symbol_rate(struct dvb_frontend *fe,
+ u32 srate, u32 ratio)
+{
+ u8 aclk = 0;
+ u8 bclk = 0;
+
+ if (srate < 1500000) {
+ aclk = 0xb7; bclk = 0x47; }
+ else if (srate < 3000000) {
+ aclk = 0xb7; bclk = 0x4b; }
+ else if (srate < 7000000) {
+ aclk = 0xb7; bclk = 0x4f; }
+ else if (srate < 14000000) {
+ aclk = 0xb7; bclk = 0x53; }
+ else if (srate < 30000000) {
+ aclk = 0xb6; bclk = 0x53; }
+ else if (srate < 45000000) {
+ aclk = 0xb4; bclk = 0x51; }
+
+ stv0299_writereg(fe, 0x13, aclk);
+ stv0299_writereg(fe, 0x14, bclk);
+ stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
+ stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
+ stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
+
+ return 0;
+}
+
+static u8 sharp_z0194a__inittab[] = {
+ 0x01, 0x15,
+ 0x02, 0x00,
+ 0x03, 0x00,
+ 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
+ 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
+ 0x06, 0x40, /* DAC not used, set to high impendance mode */
+ 0x07, 0x00, /* DAC LSB */
+ 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
+ 0x09, 0x00, /* FIFO */
+ 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
+ 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
+ 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
+ 0x10, 0x3f, /* AGC2 0x3d */
+ 0x11, 0x84,
+ 0x12, 0xb9,
+ 0x15, 0xc9, /* lock detector threshold */
+ 0x16, 0x00,
+ 0x17, 0x00,
+ 0x18, 0x00,
+ 0x19, 0x00,
+ 0x1a, 0x00,
+ 0x1f, 0x50,
+ 0x20, 0x00,
+ 0x21, 0x00,
+ 0x22, 0x00,
+ 0x23, 0x00,
+ 0x28, 0x00, /* out imp: normal out type: parallel FEC mode:0 */
+ 0x29, 0x1e, /* 1/2 threshold */
+ 0x2a, 0x14, /* 2/3 threshold */
+ 0x2b, 0x0f, /* 3/4 threshold */
+ 0x2c, 0x09, /* 5/6 threshold */
+ 0x2d, 0x05, /* 7/8 threshold */
+ 0x2e, 0x01,
+ 0x31, 0x1f, /* test all FECs */
+ 0x32, 0x19, /* viterbi and synchro search */
+ 0x33, 0xfc, /* rs control */
+ 0x34, 0x93, /* error control */
+ 0x0f, 0x52,
+ 0xff, 0xff
+};
+
+static struct stv0299_config sharp_z0194a_config = {
+ .demod_address = 0x68,
+ .inittab = sharp_z0194a__inittab,
+ .mclk = 88000000UL,
+ .invert = 1,
+ .skip_reinit = 0,
+ .lock_output = STV0299_LOCKOUTPUT_1,
+ .volt13_op0_op1 = STV0299_VOLT13_OP1,
+ .min_delay_ms = 100,
+ .set_symbol_rate = sharp_z0194a__set_symbol_rate,
+};
+
+#endif
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index b4b8ed795c9..c5f45fed69d 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -110,12 +110,12 @@ struct smscore_registry_entry_t {
enum sms_device_type_st type;
};
-struct list_head g_smscore_notifyees;
-struct list_head g_smscore_devices;
-struct mutex g_smscore_deviceslock;
+static struct list_head g_smscore_notifyees;
+static struct list_head g_smscore_devices;
+static struct mutex g_smscore_deviceslock;
-struct list_head g_smscore_registry;
-struct mutex g_smscore_registrylock;
+static struct list_head g_smscore_registry;
+static struct mutex g_smscore_registrylock;
static int default_mode = 4;
@@ -1187,7 +1187,7 @@ int smsclient_sendrequest(struct smscore_client_t *client,
}
-int smscore_module_init(void)
+static int __init smscore_module_init(void)
{
int rc = 0;
@@ -1209,7 +1209,7 @@ int smscore_module_init(void)
return rc;
}
-void smscore_module_exit(void)
+static void __exit smscore_module_exit(void)
{
kmutex_lock(&g_smscore_deviceslock);
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
index 6f9c1856386..229274a1411 100644
--- a/drivers/media/dvb/siano/smsdvb.c
+++ b/drivers/media/dvb/siano/smsdvb.c
@@ -27,8 +27,8 @@
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-struct list_head g_smsdvb_clients;
-struct mutex g_smsdvb_clientslock;
+static struct list_head g_smsdvb_clients;
+static struct mutex g_smsdvb_clientslock;
static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
{
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 87c973ac668..41b5a988b61 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -5,8 +5,6 @@ config TTPCI_EEPROM
config DVB_AV7110
tristate "AV7110 cards"
depends on DVB_CORE && PCI && I2C
- depends on HOTPLUG
- select FW_LOADER if !DVB_AV7110_FIRMWARE
select TTPCI_EEPROM
select VIDEO_SAA7146_VV
depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV
@@ -127,14 +125,12 @@ config DVB_BUDGET_AV
depends on DVB_BUDGET_CORE && I2C
select VIDEO_SAA7146_VV
depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV
- depends on HOTPLUG # dependency of FW_LOADER
select DVB_PLL if !DVB_FE_CUSTOMISE
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
select DVB_TDA10021 if !DVB_FE_CUSTOMISE
select DVB_TDA10023 if !DVB_FE_CUSTOMISE
select DVB_TUA6100 if !DVB_FE_CUSTOMISE
- select FW_LOADER
help
Support for simple SAA7146 based DVB cards
(so called Budget- or Nova-PCI cards) without onboard
diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig
index a23cc0aa17d..d5f48a3102b 100644
--- a/drivers/media/dvb/ttusb-dec/Kconfig
+++ b/drivers/media/dvb/ttusb-dec/Kconfig
@@ -1,8 +1,6 @@
config DVB_TTUSB_DEC
tristate "Technotrend/Hauppauge USB DEC devices"
depends on DVB_CORE && USB && INPUT
- depends on HOTPLUG # due to FW_LOADER
- select FW_LOADER
select CRC32
help
Support for external USB adapters designed by Technotrend and
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index 4e3f83e4e48..1ed88f3abe6 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -85,6 +85,7 @@
#include <linux/input.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/usb.h>
/*
@@ -444,14 +445,7 @@ static const struct file_operations usb_dsbr100_fops = {
.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,
+static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -466,6 +460,14 @@ static struct video_device dsbr100_videodev_template =
.vidioc_s_input = vidioc_s_input,
};
+/* V4L2 interface */
+static struct video_device dsbr100_videodev_template = {
+ .name = "D-Link DSB-R 100",
+ .fops = &usb_dsbr100_fops,
+ .ioctl_ops = &usb_dsbr100_ioctl_ops,
+ .release = video_device_release,
+};
+
/* check if the device is present and register with v4l and
usb if it is */
static int usb_dsbr100_probe(struct usb_interface *intf,
diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c
index 09fe6f1cdf1..7fd7ee2d32c 100644
--- a/drivers/media/radio/miropcm20-radio.c
+++ b/drivers/media/radio/miropcm20-radio.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include "oss/aci.h"
#include "miropcm20-rds-core.h"
@@ -228,9 +229,7 @@ static const struct file_operations pcm20_fops = {
};
static struct video_device pcm20_radio = {
- .owner = THIS_MODULE,
.name = "Miro PCM 20 radio",
- .type = VID_TYPE_TUNER,
.fops = &pcm20_fops,
.priv = &pcm20_unit
};
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 1ec18ed1a73..eba9209b302 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -36,6 +36,7 @@
#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#define RADIO_VERSION KERNEL_VERSION(0,0,2)
@@ -388,12 +389,7 @@ static const struct file_operations rtrack_fops = {
.llseek = no_llseek,
};
-static struct video_device rtrack_radio=
-{
- .owner = THIS_MODULE,
- .name = "RadioTrack radio",
- .type = VID_TYPE_TUNER,
- .fops = &rtrack_fops,
+static const struct v4l2_ioctl_ops rtrack_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -408,6 +404,12 @@ static struct video_device rtrack_radio=
.vidioc_s_ctrl = vidioc_s_ctrl,
};
+static struct video_device rtrack_radio = {
+ .name = "RadioTrack radio",
+ .fops = &rtrack_fops,
+ .ioctl_ops = &rtrack_ioctl_ops,
+};
+
static int __init rtrack_init(void)
{
if(io==-1)
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 46cdb549eac..3fe5504428c 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -33,6 +33,7 @@
#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#define RADIO_VERSION KERNEL_VERSION(0,0,2)
@@ -352,12 +353,7 @@ static const struct file_operations aztech_fops = {
.llseek = no_llseek,
};
-static struct video_device aztech_radio=
-{
- .owner = THIS_MODULE,
- .name = "Aztech radio",
- .type = VID_TYPE_TUNER,
- .fops = &aztech_fops,
+static const struct v4l2_ioctl_ops aztech_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -372,6 +368,12 @@ static struct video_device aztech_radio=
.vidioc_s_ctrl = vidioc_s_ctrl,
};
+static struct video_device aztech_radio = {
+ .name = "Aztech radio",
+ .fops = &aztech_fops,
+ .ioctl_ops = &aztech_ioctl_ops,
+};
+
module_param_named(debug,aztech_radio.debug, int, 0644);
MODULE_PARM_DESC(debug,"activates debug info");
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index b14db53ea45..6166e726ed7 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -39,6 +39,7 @@
#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* V4L2 API defs */
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/param.h>
#include <linux/pnp.h>
@@ -569,12 +570,7 @@ static const struct file_operations cadet_fops = {
.llseek = no_llseek,
};
-static struct video_device cadet_radio=
-{
- .owner = THIS_MODULE,
- .name = "Cadet radio",
- .type = VID_TYPE_TUNER,
- .fops = &cadet_fops,
+static const struct v4l2_ioctl_ops cadet_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -589,6 +585,12 @@ static struct video_device cadet_radio=
.vidioc_s_input = vidioc_s_input,
};
+static struct video_device cadet_radio = {
+ .name = "Cadet radio",
+ .fops = &cadet_fops,
+ .ioctl_ops = &cadet_ioctl_ops,
+};
+
#ifdef CONFIG_PNP
static struct pnp_device_id cadet_pnp_devices[] = {
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index de49be97148..36e754e3ffb 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -46,6 +46,7 @@
#include <linux/pci.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/errno.h>
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
@@ -374,11 +375,7 @@ static const struct file_operations gemtek_pci_fops = {
.llseek = no_llseek,
};
-static struct video_device vdev_template = {
- .owner = THIS_MODULE,
- .name = "Gemtek PCI Radio",
- .type = VID_TYPE_TUNER,
- .fops = &gemtek_pci_fops,
+static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -393,6 +390,12 @@ static struct video_device vdev_template = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
+static struct video_device vdev_template = {
+ .name = "Gemtek PCI Radio",
+ .fops = &gemtek_pci_fops,
+ .ioctl_ops = &gemtek_pci_ioctl_ops,
+};
+
static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id )
{
struct gemtek_pci_card *card;
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 81f6aeb1cd1..2b1a6221de6 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -23,6 +23,7 @@
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
+#include <media/v4l2-ioctl.h>
#include <media/v4l2-common.h>
#include <linux/spinlock.h>
@@ -552,11 +553,7 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
return 0;
}
-static struct video_device gemtek_radio = {
- .owner = THIS_MODULE,
- .name = "GemTek Radio card",
- .type = VID_TYPE_TUNER,
- .fops = &gemtek_fops,
+static const struct v4l2_ioctl_ops gemtek_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -571,6 +568,12 @@ static struct video_device gemtek_radio = {
.vidioc_s_ctrl = vidioc_s_ctrl
};
+static struct video_device gemtek_radio = {
+ .name = "GemTek Radio card",
+ .fops = &gemtek_fops,
+ .ioctl_ops = &gemtek_ioctl_ops,
+};
+
/*
* Initialization / cleanup related stuff.
*/
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index bddd3c409aa..0ada1c697e8 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -27,6 +27,7 @@
#include <linux/pci.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#define RADIO_VERSION KERNEL_VERSION(0,0,6)
@@ -354,10 +355,7 @@ static u16 __devinit radio_power_on(struct radio_device *dev)
return (ofreq == radio_bits_get(dev));
}
-static struct video_device maestro_radio = {
- .name = "Maestro radio",
- .type = VID_TYPE_TUNER,
- .fops = &maestro_fops,
+static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -372,6 +370,12 @@ static struct video_device maestro_radio = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
+static struct video_device maestro_radio = {
+ .name = "Maestro radio",
+ .fops = &maestro_fops,
+ .ioctl_ops = &maestro_ioctl_ops,
+};
+
static int __devinit maestro_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 0133ecf3e04..43c75497dc4 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -44,6 +44,7 @@
#include <linux/pci.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#define DRIVER_VERSION "0.77"
@@ -373,13 +374,7 @@ static int vidioc_s_ctrl (struct file *file, void *priv,
return -EINVAL;
}
-static struct video_device maxiradio_radio =
-{
- .owner = THIS_MODULE,
- .name = "Maxi Radio FM2000 radio",
- .type = VID_TYPE_TUNER,
- .fops = &maxiradio_fops,
-
+static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -394,6 +389,12 @@ static struct video_device maxiradio_radio =
.vidioc_s_ctrl = vidioc_s_ctrl,
};
+static struct video_device maxiradio_radio = {
+ .name = "Maxi Radio FM2000 radio",
+ .fops = &maxiradio_fops,
+ .ioctl_ops = &maxiradio_ioctl_ops,
+};
+
static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
if(!request_region(pci_resource_start(pdev, 0),
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index 070802103dc..e2dde080726 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -17,6 +17,7 @@
#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/spinlock.h>
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
@@ -294,12 +295,7 @@ static const struct file_operations rtrack2_fops = {
.llseek = no_llseek,
};
-static struct video_device rtrack2_radio=
-{
- .owner = THIS_MODULE,
- .name = "RadioTrack II radio",
- .type = VID_TYPE_TUNER,
- .fops = &rtrack2_fops,
+static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -314,6 +310,12 @@ static struct video_device rtrack2_radio=
.vidioc_s_input = vidioc_s_input,
};
+static struct video_device rtrack2_radio = {
+ .name = "RadioTrack II radio",
+ .fops = &rtrack2_fops,
+ .ioctl_ops = &rtrack2_ioctl_ops,
+};
+
static int __init rtrack2_init(void)
{
if(io==-1)
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 66e052fd390..bb5d92f104a 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -24,6 +24,7 @@
#include <linux/delay.h> /* udelay */
#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/isapnp.h>
#include <asm/io.h> /* outb, outb_p */
#include <asm/uaccess.h> /* copy to/from user */
@@ -294,12 +295,7 @@ static const struct file_operations fmi_fops = {
.llseek = no_llseek,
};
-static struct video_device fmi_radio=
-{
- .owner = THIS_MODULE,
- .name = "SF16FMx radio",
- .type = VID_TYPE_TUNER,
- .fops = &fmi_fops,
+static const struct v4l2_ioctl_ops fmi_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -314,6 +310,12 @@ static struct video_device fmi_radio=
.vidioc_s_ctrl = vidioc_s_ctrl,
};
+static struct video_device fmi_radio = {
+ .name = "SF16FMx radio",
+ .fops = &fmi_fops,
+ .ioctl_ops = &fmi_ioctl_ops,
+};
+
/* ladis: this is my card. does any other types exist? */
static struct isapnp_device_id id_table[] __devinitdata = {
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index b0ccf7cb595..6290553d24b 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -22,6 +22,7 @@
#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/mutex.h>
static struct mutex lock;
@@ -410,12 +411,7 @@ static const struct file_operations fmr2_fops = {
.llseek = no_llseek,
};
-static struct video_device fmr2_radio=
-{
- .owner = THIS_MODULE,
- .name = "SF16FMR2 radio",
- . type = VID_TYPE_TUNER,
- .fops = &fmr2_fops,
+static const struct v4l2_ioctl_ops fmr2_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -430,6 +426,12 @@ static struct video_device fmr2_radio=
.vidioc_s_ctrl = vidioc_s_ctrl,
};
+static struct video_device fmr2_radio = {
+ .name = "SF16FMR2 radio",
+ .fops = &fmr2_fops,
+ .ioctl_ops = &fmr2_ioctl_ops,
+};
+
static int __init fmr2_init(void)
{
fmr2_unit.port = io;
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index dc93a882b38..a4984ff87c9 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -133,6 +133,7 @@
#include <linux/videodev2.h>
#include <linux/mutex.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/rds.h>
#include <asm/unaligned.h>
@@ -1585,15 +1586,7 @@ done:
return retval;
}
-
-/*
- * si470x_viddev_tamples - video device interface
- */
-static struct video_device si470x_viddev_template = {
- .fops = &si470x_fops,
- .name = DRIVER_NAME,
- .type = VID_TYPE_TUNER,
- .release = video_device_release,
+static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
.vidioc_querycap = si470x_vidioc_querycap,
.vidioc_g_input = si470x_vidioc_g_input,
.vidioc_s_input = si470x_vidioc_s_input,
@@ -1607,7 +1600,16 @@ static struct video_device si470x_viddev_template = {
.vidioc_g_frequency = si470x_vidioc_g_frequency,
.vidioc_s_frequency = si470x_vidioc_s_frequency,
.vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek,
- .owner = THIS_MODULE,
+};
+
+/*
+ * si470x_viddev_tamples - video device interface
+ */
+static struct video_device si470x_viddev_template = {
+ .fops = &si470x_fops,
+ .ioctl_ops = &si470x_ioctl_ops,
+ .name = DRIVER_NAME,
+ .release = video_device_release,
};
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index acc32080e9b..cefa44fc5ae 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -32,6 +32,7 @@
#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/spinlock.h>
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
@@ -366,12 +367,7 @@ static const struct file_operations terratec_fops = {
.llseek = no_llseek,
};
-static struct video_device terratec_radio=
-{
- .owner = THIS_MODULE,
- .name = "TerraTec ActiveRadio",
- .type = VID_TYPE_TUNER,
- .fops = &terratec_fops,
+static const struct v4l2_ioctl_ops terratec_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -386,6 +382,12 @@ static struct video_device terratec_radio=
.vidioc_s_input = vidioc_s_input,
};
+static struct video_device terratec_radio = {
+ .name = "TerraTec ActiveRadio",
+ .fops = &terratec_fops,
+ .ioctl_ops = &terratec_ioctl_ops,
+};
+
static int __init terratec_init(void)
{
if(io==-1)
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index 4ebdfbadeb9..d70172d23ed 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -23,6 +23,7 @@
#include <asm/uaccess.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#define RADIO_VERSION KERNEL_VERSION(0,0,2)
@@ -346,12 +347,7 @@ static const struct file_operations trust_fops = {
.llseek = no_llseek,
};
-static struct video_device trust_radio=
-{
- .owner = THIS_MODULE,
- .name = "Trust FM Radio",
- .type = VID_TYPE_TUNER,
- .fops = &trust_fops,
+static const struct v4l2_ioctl_ops trust_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -366,6 +362,12 @@ static struct video_device trust_radio=
.vidioc_s_input = vidioc_s_input,
};
+static struct video_device trust_radio = {
+ .name = "Trust FM Radio",
+ .fops = &trust_fops,
+ .ioctl_ops = &trust_ioctl_ops,
+};
+
static int __init trust_init(void)
{
if(io == -1) {
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index 18f2abd7e25..f8d62cfea77 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -40,6 +40,7 @@
#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#define RADIO_VERSION KERNEL_VERSION(0,1,1)
@@ -344,12 +345,7 @@ static const struct file_operations typhoon_fops = {
.llseek = no_llseek,
};
-static struct video_device typhoon_radio =
-{
- .owner = THIS_MODULE,
- .name = "Typhoon Radio",
- .type = VID_TYPE_TUNER,
- .fops = &typhoon_fops,
+static const struct v4l2_ioctl_ops typhoon_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -364,6 +360,12 @@ static struct video_device typhoon_radio =
.vidioc_s_ctrl = vidioc_s_ctrl,
};
+static struct video_device typhoon_radio = {
+ .name = "Typhoon Radio",
+ .fops = &typhoon_fops,
+ .ioctl_ops = &typhoon_ioctl_ops,
+};
+
#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
static int typhoon_proc_show(struct seq_file *m, void *v)
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index 43773c56c62..9f17a332fa1 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -37,6 +37,7 @@
#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#define RADIO_VERSION KERNEL_VERSION(0,0,2)
@@ -407,12 +408,7 @@ static const struct file_operations zoltrix_fops =
.llseek = no_llseek,
};
-static struct video_device zoltrix_radio =
-{
- .owner = THIS_MODULE,
- .name = "Zoltrix Radio Plus",
- .type = VID_TYPE_TUNER,
- .fops = &zoltrix_fops,
+static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -427,6 +423,12 @@ static struct video_device zoltrix_radio =
.vidioc_s_ctrl = vidioc_s_ctrl,
};
+static struct video_device zoltrix_radio = {
+ .name = "Zoltrix Radio Plus",
+ .fops = &zoltrix_fops,
+ .ioctl_ops = &zoltrix_ioctl_ops,
+};
+
static int __init zoltrix_init(void)
{
if (io == -1) {
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index f606d2951fd..d4a6e56a713 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -487,17 +487,6 @@ config VIDEO_PMS
To compile this driver as a module, choose M here: the
module will be called pms.
-config VIDEO_PLANB
- tristate "PlanB Video-In on PowerMac"
- depends on PPC_PMAC && VIDEO_V4L1 && BROKEN
- help
- PlanB is the V4L driver for the PowerMac 7x00/8x00 series video
- input hardware. If you want to experiment with this, say Y.
- Otherwise, or if you don't understand a word, say N. See
- <http://www.cpu.lu/~mlan/linux/dev/planb.html> for more info.
-
- Saying M will compile this driver as a module (planb).
-
config VIDEO_BWQCAM
tristate "Quickcam BW Video For Linux"
depends on PARPORT && VIDEO_V4L1
@@ -806,13 +795,7 @@ menuconfig V4L_USB_DRIVERS
if V4L_USB_DRIVERS && USB
-config USB_VIDEO_CLASS
- tristate "USB Video Class (UVC)"
- ---help---
- Support for the USB Video Class (UVC). Currently only video
- input devices, such as webcams, are supported.
-
- For more information see: <http://linux-uvc.berlios.de/>
+source "drivers/media/video/uvc/Kconfig"
source "drivers/media/video/gspca/Kconfig"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 45d5db5abb1..bbc6f8b8229 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -10,6 +10,8 @@ msp3400-objs := msp3400-driver.o msp3400-kthreads.o
stkwebcam-objs := stk-webcam.o stk-sensor.o
+videodev-objs := v4l2-dev.o v4l2-ioctl.o
+
obj-$(CONFIG_VIDEO_DEV) += videodev.o compat_ioctl32.o v4l2-int-device.o
obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
@@ -55,7 +57,6 @@ obj-$(CONFIG_VIDEO_ZORAN_DC30) += zr36050.o zr36016.o
obj-$(CONFIG_VIDEO_ZORAN_ZR36060) += zr36060.o
obj-$(CONFIG_VIDEO_PMS) += pms.o
-obj-$(CONFIG_VIDEO_PLANB) += planb.o
obj-$(CONFIG_VIDEO_VINO) += vino.o indycam.o
obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
obj-$(CONFIG_VIDEO_CPIA) += cpia.o
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 8c7d1958856..56ebfd5ef6f 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -754,7 +754,6 @@ static const struct file_operations ar_fops = {
};
static struct video_device ar_template = {
- .owner = THIS_MODULE,
.name = "Colour AR VGA",
.type = VID_TYPE_CAPTURE,
.fops = &ar_fops,
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig
index 52b2491581a..ed9a50f189f 100644
--- a/drivers/media/video/au0828/Kconfig
+++ b/drivers/media/video/au0828/Kconfig
@@ -6,6 +6,7 @@ config VIDEO_AU0828
select VIDEO_TVEEPROM
select DVB_AU8522 if !DVB_FE_CUSTOMIZE
select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
+ select MEDIA_TUNER_MXL5007T if !DVB_FE_CUSTOMIZE
---help---
This is a video4linux driver for Auvitek's USB device.
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 898e12395e7..443e5900976 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -32,6 +32,9 @@ struct au0828_board au0828_boards[] = {
[AU0828_BOARD_HAUPPAUGE_HVR950Q] = {
.name = "Hauppauge HVR950Q",
},
+ [AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL] = {
+ .name = "Hauppauge HVR950Q rev xxF8",
+ },
[AU0828_BOARD_DVICO_FUSIONHDTV7] = {
.name = "DViCO FusionHDTV USB",
},
@@ -49,6 +52,7 @@ int au0828_tuner_callback(void *priv, int command, int arg)
switch (dev->board) {
case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q:
+ case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
case AU0828_BOARD_DVICO_FUSIONHDTV7:
if (command == 0) {
/* Tuner Reset Command from xc5000 */
@@ -110,6 +114,7 @@ void au0828_card_setup(struct au0828_dev *dev)
switch (dev->board) {
case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q:
+ case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
if (dev->i2c_rc == 0)
hauppauge_eeprom(dev, eeprom+0xa0);
break;
@@ -128,6 +133,7 @@ void au0828_gpio_setup(struct au0828_dev *dev)
switch (dev->board) {
case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q:
+ case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
/* GPIO's
* 4 - CS5340
* 5 - AU8522 Demodulator
@@ -193,6 +199,12 @@ struct usb_device_id au0828_usb_id_table [] = {
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ USB_DEVICE(0x0fd9, 0x0008),
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+ { USB_DEVICE(0x2040, 0x7201),
+ .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
+ { USB_DEVICE(0x2040, 0x7211),
+ .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
+ { USB_DEVICE(0x2040, 0x7281),
+ .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
{ },
};
diff --git a/drivers/media/video/au0828/au0828-cards.h b/drivers/media/video/au0828/au0828-cards.h
index e26f54a961d..c37f5fd0fa8 100644
--- a/drivers/media/video/au0828/au0828-cards.h
+++ b/drivers/media/video/au0828/au0828-cards.h
@@ -23,3 +23,4 @@
#define AU0828_BOARD_HAUPPAUGE_HVR950Q 1
#define AU0828_BOARD_HAUPPAUGE_HVR850 2
#define AU0828_BOARD_DVICO_FUSIONHDTV7 3
+#define AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL 4
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index c6d47059038..584a83a94a2 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -28,6 +28,7 @@
#include "au0828.h"
#include "au8522.h"
#include "xc5000.h"
+#include "mxl5007t.h"
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
@@ -45,6 +46,11 @@ static struct xc5000_config hauppauge_hvr950q_tunerconfig = {
.tuner_callback = au0828_tuner_callback
};
+static struct mxl5007t_config mxl5007t_hvr950q_config = {
+ .xtal_freq_hz = MxL_XTAL_24_MHZ,
+ .if_freq_hz = MxL_IF_6_MHZ,
+};
+
/*-------------------------------------------------------------------*/
static void urb_completion(struct urb *purb)
{
@@ -342,6 +348,15 @@ int au0828_dvb_register(struct au0828_dev *dev)
&dev->i2c_adap,
&hauppauge_hvr950q_tunerconfig, dev);
break;
+ case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
+ dvb->frontend = dvb_attach(au8522_attach,
+ &hauppauge_hvr950q_config,
+ &dev->i2c_adap);
+ if (dvb->frontend != NULL)
+ dvb_attach(mxl5007t_attach, dvb->frontend,
+ &dev->i2c_adap, 0x60,
+ &mxl5007t_hvr950q_config);
+ break;
default:
printk(KERN_WARNING "The frontend of your DVB/ATSC card "
"isn't supported yet\n");
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig
index 24a34fc1f2b..ce71e8e7b83 100644
--- a/drivers/media/video/bt8xx/Kconfig
+++ b/drivers/media/video/bt8xx/Kconfig
@@ -1,9 +1,7 @@
config VIDEO_BT848
tristate "BT848 Video For Linux"
depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT
- depends on HOTPLUG # due to FW_LOADER
select I2C_ALGOBIT
- select FW_LOADER
select VIDEO_BTCX
select VIDEOBUF_DMA_SG
select VIDEO_IR
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 0ea559a7fe5..85bf31ab878 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -45,6 +45,7 @@
#include <linux/kdev_t.h>
#include "bttvp.h"
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/tvaudio.h>
#include <media/msp3400.h>
@@ -163,8 +164,8 @@ MODULE_LICENSE("GPL");
static ssize_t show_card(struct device *cd,
struct device_attribute *attr, char *buf)
{
- struct video_device *vfd = container_of(cd, struct video_device, class_dev);
- struct bttv *btv = dev_get_drvdata(vfd->dev);
+ struct video_device *vfd = container_of(cd, struct video_device, dev);
+ struct bttv *btv = dev_get_drvdata(vfd->parent);
return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);
}
static DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
@@ -3357,10 +3358,7 @@ static const struct file_operations bttv_fops =
.poll = bttv_poll,
};
-static struct video_device bttv_video_template =
-{
- .fops = &bttv_fops,
- .minor = -1,
+static const struct v4l2_ioctl_ops bttv_ioctl_ops = {
.vidioc_querycap = bttv_querycap,
.vidioc_enum_fmt_vid_cap = bttv_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = bttv_g_fmt_vid_cap,
@@ -3411,8 +3409,14 @@ static struct video_device bttv_video_template =
.vidioc_g_register = bttv_g_register,
.vidioc_s_register = bttv_s_register,
#endif
- .tvnorms = BTTV_NORMS,
- .current_norm = V4L2_STD_PAL,
+};
+
+static struct video_device bttv_video_template = {
+ .fops = &bttv_fops,
+ .minor = -1,
+ .ioctl_ops = &bttv_ioctl_ops,
+ .tvnorms = BTTV_NORMS,
+ .current_norm = V4L2_STD_PAL,
};
/* ----------------------------------------------------------------------- */
@@ -3635,10 +3639,7 @@ static const struct file_operations radio_fops =
.poll = radio_poll,
};
-static struct video_device radio_template =
-{
- .fops = &radio_fops,
- .minor = -1,
+static const struct v4l2_ioctl_ops radio_ioctl_ops = {
.vidioc_querycap = radio_querycap,
.vidioc_g_tuner = radio_g_tuner,
.vidioc_enum_input = radio_enum_input,
@@ -3655,6 +3656,12 @@ static struct video_device radio_template =
.vidioc_s_frequency = bttv_s_frequency,
};
+static struct video_device radio_template = {
+ .fops = &radio_fops,
+ .minor = -1,
+ .ioctl_ops = &radio_ioctl_ops,
+};
+
/* ----------------------------------------------------------------------- */
/* some debug code */
@@ -4175,8 +4182,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id)
static struct video_device *vdev_init(struct bttv *btv,
const struct video_device *template,
- const char *type_name,
- const int type)
+ const char *type_name)
{
struct video_device *vfd;
@@ -4185,9 +4191,8 @@ static struct video_device *vdev_init(struct bttv *btv,
return NULL;
*vfd = *template;
vfd->minor = -1;
- vfd->dev = &btv->c.pci->dev;
+ vfd->parent = &btv->c.pci->dev;
vfd->release = video_device_release;
- vfd->type = type;
vfd->debug = bttv_debug;
snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
@@ -4223,20 +4228,11 @@ static void bttv_unregister_video(struct bttv *btv)
/* register video4linux devices */
static int __devinit bttv_register_video(struct bttv *btv)
{
- int video_type = VID_TYPE_CAPTURE |
- VID_TYPE_TUNER |
- VID_TYPE_CLIPPING|
- VID_TYPE_SCALES;
-
- if (no_overlay <= 0) {
- bttv_video_template.type |= VID_TYPE_OVERLAY;
- } else {
+ if (no_overlay > 0)
printk("bttv: Overlay support disabled.\n");
- }
/* video */
- btv->video_dev = vdev_init(btv, &bttv_video_template,
- "video", video_type);
+ btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
if (NULL == btv->video_dev)
goto err;
@@ -4244,7 +4240,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
goto err;
printk(KERN_INFO "bttv%d: registered device video%d\n",
btv->c.nr,btv->video_dev->minor & 0x1f);
- if (device_create_file(&btv->video_dev->class_dev,
+ if (device_create_file(&btv->video_dev->dev,
&dev_attr_card)<0) {
printk(KERN_ERR "bttv%d: device_create_file 'card' "
"failed\n", btv->c.nr);
@@ -4252,8 +4248,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
}
/* vbi */
- btv->vbi_dev = vdev_init(btv, &bttv_video_template,
- "vbi", VID_TYPE_TUNER | VID_TYPE_TELETEXT);
+ btv->vbi_dev = vdev_init(btv, &bttv_video_template, "vbi");
if (NULL == btv->vbi_dev)
goto err;
@@ -4265,8 +4260,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
if (!btv->has_radio)
return 0;
/* radio */
- btv->radio_dev = vdev_init(btv, &radio_template,
- "radio", VID_TYPE_TUNER);
+ btv->radio_dev = vdev_init(btv, &radio_template, "radio");
if (NULL == btv->radio_dev)
goto err;
if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c
index 0af586876e7..649682aac1a 100644
--- a/drivers/media/video/bt8xx/bttv-risc.c
+++ b/drivers/media/video/bt8xx/bttv-risc.c
@@ -31,6 +31,7 @@
#include <linux/interrupt.h>
#include <asm/page.h>
#include <asm/pgtable.h>
+#include <media/v4l2-ioctl.h>
#include "bttvp.h"
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c
index 68f28e5fa04..6819e21a377 100644
--- a/drivers/media/video/bt8xx/bttv-vbi.c
+++ b/drivers/media/video/bt8xx/bttv-vbi.c
@@ -29,6 +29,7 @@
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/kdev_t.h>
+#include <media/v4l2-ioctl.h>
#include <asm/io.h>
#include "bttvp.h"
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index b364adaae78..d3b3268bace 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -74,6 +74,7 @@ OTHER DEALINGS IN THE SOFTWARE.
#include <linux/sched.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
@@ -906,9 +907,7 @@ static const struct file_operations qcam_fops = {
};
static struct video_device qcam_template=
{
- .owner = THIS_MODULE,
.name = "Connectix Quickcam",
- .type = VID_TYPE_CAPTURE,
.fops = &qcam_fops,
};
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index fe1e67bb1ca..fe9379b282d 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -35,6 +35,7 @@
#include <linux/sched.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/mutex.h>
#include <linux/jiffies.h>
@@ -701,9 +702,7 @@ static const struct file_operations qcam_fops = {
static struct video_device qcam_template=
{
- .owner = THIS_MODULE,
.name = "Colour QuickCam",
- .type = VID_TYPE_CAPTURE,
.fops = &qcam_fops,
};
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index d99453faaab..c149b7d712e 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -25,6 +25,7 @@
#include <linux/spinlock.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/v4l2-chip-ident.h>
#include <linux/device.h>
#include <linux/wait.h>
@@ -1768,17 +1769,7 @@ static const struct file_operations cafe_v4l_fops = {
.llseek = no_llseek,
};
-static struct video_device cafe_v4l_template = {
- .name = "cafe",
- .type = VFL_TYPE_GRABBER,
- .type2 = VID_TYPE_CAPTURE,
- .minor = -1, /* Get one dynamically */
- .tvnorms = V4L2_STD_NTSC_M,
- .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */
-
- .fops = &cafe_v4l_fops,
- .release = cafe_v4l_dev_release,
-
+static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = {
.vidioc_querycap = cafe_vidioc_querycap,
.vidioc_enum_fmt_vid_cap = cafe_vidioc_enum_fmt_vid_cap,
.vidioc_try_fmt_vid_cap = cafe_vidioc_try_fmt_vid_cap,
@@ -1801,6 +1792,17 @@ static struct video_device cafe_v4l_template = {
.vidioc_s_parm = cafe_vidioc_s_parm,
};
+static struct video_device cafe_v4l_template = {
+ .name = "cafe",
+ .minor = -1, /* Get one dynamically */
+ .tvnorms = V4L2_STD_NTSC_M,
+ .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */
+
+ .fops = &cafe_v4l_fops,
+ .ioctl_ops = &cafe_v4l_ioctl_ops,
+ .release = cafe_v4l_dev_release,
+};
+
@@ -2157,7 +2159,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
cam->v4ldev = cafe_v4l_template;
cam->v4ldev.debug = 0;
// cam->v4ldev.debug = V4L2_DEBUG_IOCTL_ARG;
- cam->v4ldev.dev = &pdev->dev;
+ cam->v4ldev.parent = &pdev->dev;
ret = video_register_device(&cam->v4ldev, VFL_TYPE_GRABBER, -1);
if (ret)
goto out_smbus;
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c
index 54de0cd482e..bd5d9de5a00 100644
--- a/drivers/media/video/compat_ioctl32.c
+++ b/drivers/media/video/compat_ioctl32.c
@@ -17,7 +17,7 @@
#include <linux/videodev2.h>
#include <linux/module.h>
#include <linux/smp_lock.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#ifdef CONFIG_COMPAT
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index 2a81376ef50..dc8cc6115e2 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -3799,9 +3799,7 @@ static const struct file_operations cpia_fops = {
};
static struct video_device cpia_template = {
- .owner = THIS_MODULE,
.name = "CPiA Camera",
- .type = VID_TYPE_CAPTURE,
.fops = &cpia_fops,
};
diff --git a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h
index 5096058bf57..8f0cfee4b8a 100644
--- a/drivers/media/video/cpia.h
+++ b/drivers/media/video/cpia.h
@@ -46,6 +46,7 @@
#include <asm/uaccess.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/list.h>
#include <linux/mutex.h>
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c
index f2e8b1c82c6..af8b9ec8e35 100644
--- a/drivers/media/video/cpia2/cpia2_core.c
+++ b/drivers/media/video/cpia2/cpia2_core.c
@@ -32,6 +32,7 @@
#include "cpia2.h"
#include <linux/slab.h>
+#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/firmware.h>
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 7ce2789fa97..515c8b57a60 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -37,6 +37,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/init.h>
+#include <media/v4l2-ioctl.h>
#include "cpia2.h"
#include "cpia2dev.h"
@@ -1935,11 +1936,7 @@ static const struct file_operations fops_template = {
static struct video_device cpia2_template = {
/* I could not find any place for the old .initialize initializer?? */
- .owner= THIS_MODULE,
.name= "CPiA2 Camera",
- .type= VID_TYPE_CAPTURE,
- .type2 = V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_STREAMING,
.minor= -1,
.fops= &fops_template,
.release= video_device_release,
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 1c3fa3a7470..61d14d26686 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -111,7 +111,7 @@ static int cs5345_command(struct i2c_client *client, unsigned cmd, void *arg)
if (cmd == VIDIOC_DBG_G_REGISTER)
reg->val = cs5345_read(client, reg->reg & 0x1f);
else
- cs5345_write(client, reg->reg & 0x1f, reg->val & 0x1f);
+ cs5345_write(client, reg->reg & 0x1f, reg->val & 0xff);
break;
}
#endif
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index 645b339152d..e30a589c0e1 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -26,7 +26,7 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-i2c-drv-legacy.h>
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
index 9aefdc5ea79..ef48565de7f 100644
--- a/drivers/media/video/cx18/Kconfig
+++ b/drivers/media/video/cx18/Kconfig
@@ -2,9 +2,7 @@ config VIDEO_CX18
tristate "Conexant cx23418 MPEG encoder support"
depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
depends on INPUT # due to VIDEO_IR
- depends on HOTPLUG # due to FW_LOADER
select I2C_ALGOBIT
- select FW_LOADER
select VIDEO_IR
select VIDEO_TUNER
select VIDEO_TVEEPROM
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c
index c40a286de1b..0b55837880a 100644
--- a/drivers/media/video/cx18/cx18-av-audio.c
+++ b/drivers/media/video/cx18/cx18-av-audio.c
@@ -30,7 +30,6 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
if (freq != 32000 && freq != 44100 && freq != 48000)
return -EINVAL;
- /* common for all inputs and rates */
/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
cx18_av_write(cx, 0x127, 0x50);
@@ -38,15 +37,30 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
switch (freq) {
case 32000:
/* VID_PLL and AUX_PLL */
- cx18_av_write4(cx, 0x108, 0x1006040f);
+ cx18_av_write4(cx, 0x108, 0x1408040f);
/* AUX_PLL_FRAC */
- cx18_av_write4(cx, 0x110, 0x01bb39ee);
+ /* 0x8.9504318a * 28,636,363.636 / 0x14 = 32000 * 384 */
+ cx18_av_write4(cx, 0x110, 0x012a0863);
- /* src3/4/6_ctl = 0x0801f77f */
+ /* src3/4/6_ctl */
+ /* 0x1.f77f = (4 * 15734.26) / 32000 */
cx18_av_write4(cx, 0x900, 0x0801f77f);
cx18_av_write4(cx, 0x904, 0x0801f77f);
cx18_av_write4(cx, 0x90c, 0x0801f77f);
+
+ /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
+ cx18_av_write(cx, 0x127, 0x54);
+
+ /* AUD_COUNT = 0x2fff = 8 samples * 4 * 384 - 1 */
+ cx18_av_write4(cx, 0x12c, 0x11202fff);
+
+ /*
+ * EN_AV_LOCK = 1
+ * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
+ * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
+ */
+ cx18_av_write4(cx, 0x128, 0xa10d2ef8);
break;
case 44100:
@@ -54,12 +68,24 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
cx18_av_write4(cx, 0x108, 0x1009040f);
/* AUX_PLL_FRAC */
- cx18_av_write4(cx, 0x110, 0x00ec6bd6);
+ /* 0x9.7635e7 * 28,636,363.63 / 0x10 = 44100 * 384 */
+ cx18_av_write4(cx, 0x110, 0x00ec6bce);
- /* src3/4/6_ctl = 0x08016d59 */
+ /* src3/4/6_ctl */
+ /* 0x1.6d59 = (4 * 15734.26) / 44100 */
cx18_av_write4(cx, 0x900, 0x08016d59);
cx18_av_write4(cx, 0x904, 0x08016d59);
cx18_av_write4(cx, 0x90c, 0x08016d59);
+
+ /* AUD_COUNT = 0x92ff = 49 samples * 2 * 384 - 1 */
+ cx18_av_write4(cx, 0x12c, 0x112092ff);
+
+ /*
+ * EN_AV_LOCK = 1
+ * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
+ * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
+ */
+ cx18_av_write4(cx, 0x128, 0xa11d4bf8);
break;
case 48000:
@@ -67,12 +93,24 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
cx18_av_write4(cx, 0x108, 0x100a040f);
/* AUX_PLL_FRAC */
- cx18_av_write4(cx, 0x110, 0x0098d6e5);
+ /* 0xa.4c6b6ea * 28,636,363.63 / 0x10 = 48000 * 384 */
+ cx18_av_write4(cx, 0x110, 0x0098d6dd);
- /* src3/4/6_ctl = 0x08014faa */
+ /* src3/4/6_ctl */
+ /* 0x1.4faa = (4 * 15734.26) / 48000 */
cx18_av_write4(cx, 0x900, 0x08014faa);
cx18_av_write4(cx, 0x904, 0x08014faa);
cx18_av_write4(cx, 0x90c, 0x08014faa);
+
+ /* AUD_COUNT = 0x5fff = 4 samples * 16 * 384 - 1 */
+ cx18_av_write4(cx, 0x12c, 0x11205fff);
+
+ /*
+ * EN_AV_LOCK = 1
+ * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
+ * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
+ */
+ cx18_av_write4(cx, 0x128, 0xa11193f8);
break;
}
} else {
@@ -82,18 +120,31 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
cx18_av_write4(cx, 0x108, 0x1e08040f);
/* AUX_PLL_FRAC */
- cx18_av_write4(cx, 0x110, 0x012a0869);
+ /* 0x8.9504318 * 28,636,363.63 / 0x1e = 32000 * 256 */
+ cx18_av_write4(cx, 0x110, 0x012a0863);
- /* src1_ctl = 0x08010000 */
+ /* src1_ctl */
+ /* 0x1.0000 = 32000/32000 */
cx18_av_write4(cx, 0x8f8, 0x08010000);
- /* src3/4/6_ctl = 0x08020000 */
+ /* src3/4/6_ctl */
+ /* 0x2.0000 = 2 * (32000/32000) */
cx18_av_write4(cx, 0x900, 0x08020000);
cx18_av_write4(cx, 0x904, 0x08020000);
cx18_av_write4(cx, 0x90c, 0x08020000);
/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
cx18_av_write(cx, 0x127, 0x54);
+
+ /* AUD_COUNT = 0x1fff = 8 samples * 4 * 256 - 1 */
+ cx18_av_write4(cx, 0x12c, 0x11201fff);
+
+ /*
+ * EN_AV_LOCK = 1
+ * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 =
+ * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8
+ */
+ cx18_av_write4(cx, 0x128, 0xa10d2ef8);
break;
case 44100:
@@ -101,15 +152,28 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
cx18_av_write4(cx, 0x108, 0x1809040f);
/* AUX_PLL_FRAC */
- cx18_av_write4(cx, 0x110, 0x00ec6bd6);
+ /* 0x9.7635e74 * 28,636,363.63 / 0x18 = 44100 * 256 */
+ cx18_av_write4(cx, 0x110, 0x00ec6bce);
- /* src1_ctl = 0x08010000 */
+ /* src1_ctl */
+ /* 0x1.60cd = 44100/32000 */
cx18_av_write4(cx, 0x8f8, 0x080160cd);
- /* src3/4/6_ctl = 0x08020000 */
+ /* src3/4/6_ctl */
+ /* 0x1.7385 = 2 * (32000/44100) */
cx18_av_write4(cx, 0x900, 0x08017385);
cx18_av_write4(cx, 0x904, 0x08017385);
cx18_av_write4(cx, 0x90c, 0x08017385);
+
+ /* AUD_COUNT = 0x61ff = 49 samples * 2 * 256 - 1 */
+ cx18_av_write4(cx, 0x12c, 0x112061ff);
+
+ /*
+ * EN_AV_LOCK = 1
+ * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 =
+ * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8
+ */
+ cx18_av_write4(cx, 0x128, 0xa11d4bf8);
break;
case 48000:
@@ -117,15 +181,28 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
cx18_av_write4(cx, 0x108, 0x180a040f);
/* AUX_PLL_FRAC */
- cx18_av_write4(cx, 0x110, 0x0098d6e5);
+ /* 0xa.4c6b6ea * 28,636,363.63 / 0x18 = 48000 * 256 */
+ cx18_av_write4(cx, 0x110, 0x0098d6dd);
- /* src1_ctl = 0x08010000 */
+ /* src1_ctl */
+ /* 0x1.8000 = 48000/32000 */
cx18_av_write4(cx, 0x8f8, 0x08018000);
- /* src3/4/6_ctl = 0x08020000 */
+ /* src3/4/6_ctl */
+ /* 0x1.5555 = 2 * (32000/48000) */
cx18_av_write4(cx, 0x900, 0x08015555);
cx18_av_write4(cx, 0x904, 0x08015555);
cx18_av_write4(cx, 0x90c, 0x08015555);
+
+ /* AUD_COUNT = 0x3fff = 4 samples * 16 * 256 - 1 */
+ cx18_av_write4(cx, 0x12c, 0x11203fff);
+
+ /*
+ * EN_AV_LOCK = 1
+ * VID_COUNT = 0x1193f8 = 143999.000 * 8 =
+ * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8
+ */
+ cx18_av_write4(cx, 0x128, 0xa11193f8);
break;
}
}
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 45e31b04730..4801bc7fb5b 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -46,6 +46,7 @@
#include <linux/dvb/video.h>
#include <linux/dvb/audio.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/tuner.h>
#include "cx18-mailbox.h"
#include "cx18-av-core.h"
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c
index 2d630d9f749..78fadd2ada5 100644
--- a/drivers/media/video/cx18/cx18-firmware.c
+++ b/drivers/media/video/cx18/cx18-firmware.c
@@ -86,10 +86,6 @@
#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
-/* Encoder/decoder firmware sizes */
-#define CX18_FW_CPU_SIZE (158332)
-#define CX18_FW_APU_SIZE (141200)
-
#define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */
#define APU_ROM_SYNC2 0x72646548 /* "rdeH" */
@@ -100,35 +96,22 @@ struct cx18_apu_rom_seghdr {
u32 size;
};
-static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx, long size)
+static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
{
const struct firmware *fw = NULL;
- int retries = 3;
int i, j;
+ unsigned size;
u32 __iomem *dst = (u32 __iomem *)mem;
const u32 *src;
-retry:
- if (!retries || request_firmware(&fw, fn, &cx->dev->dev)) {
- CX18_ERR("Unable to open firmware %s (must be %ld bytes)\n",
- fn, size);
+ if (request_firmware(&fw, fn, &cx->dev->dev)) {
+ CX18_ERR("Unable to open firmware %s\n", fn);
CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
return -ENOMEM;
}
src = (const u32 *)fw->data;
- if (fw->size != size) {
- /* Due to race conditions in firmware loading (esp. with
- udev <0.95) the wrong file was sometimes loaded. So we check
- filesizes to see if at least the right-sized file was
- loaded. If not, then we retry. */
- CX18_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n",
- fn, size, fw->size);
- release_firmware(fw);
- retries--;
- goto retry;
- }
for (i = 0; i < fw->size; i += 4096) {
setup_page(i);
for (j = i; j < fw->size && j < i + 4096; j += 4) {
@@ -145,15 +128,16 @@ retry:
}
if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
+ size = fw->size;
release_firmware(fw);
return size;
}
-static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, long size)
+static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx)
{
const struct firmware *fw = NULL;
- int retries = 3;
int i, j;
+ unsigned size;
const u32 *src;
struct cx18_apu_rom_seghdr seghdr;
const u8 *vers;
@@ -161,10 +145,8 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
u32 apu_version = 0;
int sz;
-retry:
- if (!retries || request_firmware(&fw, fn, &cx->dev->dev)) {
- CX18_ERR("unable to open firmware %s (must be %ld bytes)\n",
- fn, size);
+ if (request_firmware(&fw, fn, &cx->dev->dev)) {
+ CX18_ERR("unable to open firmware %s\n", fn);
CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
return -ENOMEM;
}
@@ -173,19 +155,8 @@ retry:
vers = fw->data + sizeof(seghdr);
sz = fw->size;
- if (fw->size != size) {
- /* Due to race conditions in firmware loading (esp. with
- udev <0.95) the wrong file was sometimes loaded. So we check
- filesizes to see if at least the right-sized file was
- loaded. If not, then we retry. */
- CX18_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n",
- fn, size, fw->size);
- release_firmware(fw);
- retries--;
- goto retry;
- }
apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
- while (offset + sizeof(seghdr) < size) {
+ while (offset + sizeof(seghdr) < fw->size) {
/* TODO: byteswapping */
memcpy(&seghdr, src + offset / 4, sizeof(seghdr));
offset += sizeof(seghdr);
@@ -215,6 +186,7 @@ retry:
if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
fn, apu_version, fw->size);
+ size = fw->size;
release_firmware(fw);
/* Clear bit0 for APU to start from 0 */
write_reg(read_reg(0xc72030) & ~1, 0xc72030);
@@ -340,7 +312,7 @@ int cx18_firmware_init(struct cx18 *cx)
/* Only if the processor is not running */
if (read_reg(CX18_PROC_SOFT_RESET) & 8) {
int sz = load_apu_fw_direct("v4l-cx23418-apu.fw",
- cx->enc_mem, cx, CX18_FW_APU_SIZE);
+ cx->enc_mem, cx);
write_enc(0xE51FF004, 0);
write_enc(0xa00000, 4); /* todo: not hardcoded */
@@ -348,7 +320,7 @@ int cx18_firmware_init(struct cx18 *cx)
cx18_msleep_timeout(500, 0);
sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw",
- cx->enc_mem, cx, CX18_FW_CPU_SIZE);
+ cx->enc_mem, cx);
if (sz > 0) {
int retries = 0;
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 0d74e59e503..a7f839631d6 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -787,50 +787,54 @@ int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
return res;
}
-void cx18_set_funcs(struct video_device *vdev)
-{
- vdev->vidioc_querycap = cx18_querycap;
- vdev->vidioc_g_priority = cx18_g_priority;
- vdev->vidioc_s_priority = cx18_s_priority;
- vdev->vidioc_s_audio = cx18_s_audio;
- vdev->vidioc_g_audio = cx18_g_audio;
- vdev->vidioc_enumaudio = cx18_enumaudio;
- vdev->vidioc_enum_input = cx18_enum_input;
- vdev->vidioc_cropcap = cx18_cropcap;
- vdev->vidioc_s_crop = cx18_s_crop;
- vdev->vidioc_g_crop = cx18_g_crop;
- vdev->vidioc_g_input = cx18_g_input;
- vdev->vidioc_s_input = cx18_s_input;
- vdev->vidioc_g_frequency = cx18_g_frequency;
- vdev->vidioc_s_frequency = cx18_s_frequency;
- vdev->vidioc_s_tuner = cx18_s_tuner;
- vdev->vidioc_g_tuner = cx18_g_tuner;
- vdev->vidioc_g_enc_index = cx18_g_enc_index;
- vdev->vidioc_g_std = cx18_g_std;
- vdev->vidioc_s_std = cx18_s_std;
- vdev->vidioc_log_status = cx18_log_status;
- vdev->vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap;
- vdev->vidioc_encoder_cmd = cx18_encoder_cmd;
- vdev->vidioc_try_encoder_cmd = cx18_try_encoder_cmd;
- vdev->vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap;
- vdev->vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap;
- vdev->vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap;
- vdev->vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap;
- vdev->vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap;
- vdev->vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap;
- vdev->vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap;
- vdev->vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap;
- vdev->vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap;
- vdev->vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap;
- vdev->vidioc_g_chip_ident = cx18_g_chip_ident;
+static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
+ .vidioc_querycap = cx18_querycap,
+ .vidioc_g_priority = cx18_g_priority,
+ .vidioc_s_priority = cx18_s_priority,
+ .vidioc_s_audio = cx18_s_audio,
+ .vidioc_g_audio = cx18_g_audio,
+ .vidioc_enumaudio = cx18_enumaudio,
+ .vidioc_enum_input = cx18_enum_input,
+ .vidioc_cropcap = cx18_cropcap,
+ .vidioc_s_crop = cx18_s_crop,
+ .vidioc_g_crop = cx18_g_crop,
+ .vidioc_g_input = cx18_g_input,
+ .vidioc_s_input = cx18_s_input,
+ .vidioc_g_frequency = cx18_g_frequency,
+ .vidioc_s_frequency = cx18_s_frequency,
+ .vidioc_s_tuner = cx18_s_tuner,
+ .vidioc_g_tuner = cx18_g_tuner,
+ .vidioc_g_enc_index = cx18_g_enc_index,
+ .vidioc_g_std = cx18_g_std,
+ .vidioc_s_std = cx18_s_std,
+ .vidioc_log_status = cx18_log_status,
+ .vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap,
+ .vidioc_encoder_cmd = cx18_encoder_cmd,
+ .vidioc_try_encoder_cmd = cx18_try_encoder_cmd,
+ .vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap,
+ .vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap,
+ .vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap,
+ .vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap,
+ .vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap,
+ .vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap,
+ .vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap,
+ .vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap,
+ .vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap,
+ .vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap,
+ .vidioc_g_chip_ident = cx18_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
- vdev->vidioc_g_register = cx18_g_register;
- vdev->vidioc_s_register = cx18_s_register;
+ .vidioc_g_register = cx18_g_register,
+ .vidioc_s_register = cx18_s_register,
#endif
- vdev->vidioc_default = cx18_default;
- vdev->vidioc_queryctrl = cx18_queryctrl;
- vdev->vidioc_querymenu = cx18_querymenu;
- vdev->vidioc_g_ext_ctrls = cx18_g_ext_ctrls;
- vdev->vidioc_s_ext_ctrls = cx18_s_ext_ctrls;
- vdev->vidioc_try_ext_ctrls = cx18_try_ext_ctrls;
+ .vidioc_default = cx18_default,
+ .vidioc_queryctrl = cx18_queryctrl,
+ .vidioc_querymenu = cx18_querymenu,
+ .vidioc_g_ext_ctrls = cx18_g_ext_ctrls,
+ .vidioc_s_ext_ctrls = cx18_s_ext_ctrls,
+ .vidioc_try_ext_ctrls = cx18_try_ext_ctrls,
+};
+
+void cx18_set_funcs(struct video_device *vdev)
+{
+ vdev->ioctl_ops = &cx18_ioctl_ops;
}
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 1728b1d832a..0da57f583bf 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -187,14 +187,11 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
return -ENOMEM;
}
- s->v4l2dev->type =
- VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_TELETEXT |
- VID_TYPE_CLIPPING | VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER;
snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d",
cx->num);
s->v4l2dev->minor = minor;
- s->v4l2dev->dev = &cx->dev->dev;
+ s->v4l2dev->parent = &cx->dev->dev;
s->v4l2dev->fops = cx18_stream_info[type].fops;
s->v4l2dev->release = video_device_release;
s->v4l2dev->tvnorms = V4L2_STD_ALL;
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index 5cfb46bbdaa..e60bd31b51a 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -1,9 +1,7 @@
config VIDEO_CX23885
tristate "Conexant cx23885 (2388x successor) support"
depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
- depends on HOTPLUG # due to FW_LOADER
select I2C_ALGOBIT
- select FW_LOADER
select VIDEO_BTCX
select VIDEO_TUNER
select VIDEO_TVEEPROM
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index e7ef093265a..8118091568f 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -32,6 +32,7 @@
#include <linux/device.h>
#include <linux/firmware.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/cx2341x.h>
#include "cx23885.h"
@@ -1699,14 +1700,7 @@ static struct file_operations mpeg_fops = {
.llseek = no_llseek,
};
-static struct video_device cx23885_mpeg_template = {
- .name = "cx23885",
- .type = VID_TYPE_CAPTURE |
- VID_TYPE_TUNER |
- VID_TYPE_SCALES |
- VID_TYPE_MPEG_ENCODER,
- .fops = &mpeg_fops,
- .minor = -1,
+static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
.vidioc_s_std = vidioc_s_std,
.vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input = vidioc_g_input,
@@ -1735,6 +1729,13 @@ static struct video_device cx23885_mpeg_template = {
.vidioc_queryctrl = vidioc_queryctrl,
};
+static struct video_device cx23885_mpeg_template = {
+ .name = "cx23885",
+ .fops = &mpeg_fops,
+ .ioctl_ops = &mpeg_ioctl_ops,
+ .minor = -1,
+};
+
void cx23885_417_unregister(struct cx23885_dev *dev)
{
dprintk(1, "%s()\n", __func__);
@@ -1766,7 +1767,7 @@ static struct video_device *cx23885_video_dev_alloc(
vfd->minor = -1;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
type, cx23885_boards[tsport->dev->board].name);
- vfd->dev = &pci->dev;
+ vfd->parent = &pci->dev;
vfd->release = video_device_release;
return vfd;
}
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index fd7112c11d3..a19de850955 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -145,6 +145,7 @@ struct cx23885_board cx23885_boards[] = {
},
[CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP] = {
.name = "DViCO FusionHDTV7 Dual Express",
+ .portb = CX23885_MPEG_DVB,
.portc = CX23885_MPEG_DVB,
},
};
@@ -325,25 +326,41 @@ int cx23885_tuner_callback(void *priv, int command, int arg)
{
struct cx23885_i2c *bus = priv;
struct cx23885_dev *dev = bus->dev;
+ u32 bitmask = 0;
+
+ if (command != 0) {
+ printk(KERN_ERR "%s(): Unknown command 0x%x.\n",
+ __func__, command);
+ return -EINVAL;
+ }
switch(dev->board) {
case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
- if(command == 0) { /* Tuner Reset Command from xc5000 */
- /* Drive the tuner into reset and out */
- cx_clear(GP0_IO, 0x00000004);
- mdelay(200);
- cx_set(GP0_IO, 0x00000004);
- return 0;
- }
- else {
- printk(KERN_ERR
- "%s(): Unknow command.\n", __func__);
- return -EINVAL;
+ /* Tuner Reset Command from xc5000 */
+ if (command == 0)
+ bitmask = 0x04;
+ break;
+ case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
+ if (command == 0) {
+
+ /* Two identical tuners on two different i2c buses,
+ * we need to reset the correct gpio. */
+ if (bus->nr == 0)
+ bitmask = 0x01;
+ else if (bus->nr == 1)
+ bitmask = 0x04;
}
break;
}
- return 0; /* Should never be here */
+ if (bitmask) {
+ /* Drive the tuner into reset and back out */
+ cx_clear(GP0_IO, bitmask);
+ mdelay(200);
+ cx_set(GP0_IO, bitmask);
+ }
+
+ return 0;
}
void cx23885_gpio_setup(struct cx23885_dev *dev)
@@ -435,6 +452,19 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
mdelay(20);
cx_set(GP0_IO, 0x00050005);
break;
+ case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
+ /* GPIO-0 xc5000 tuner reset i2c bus 0 */
+ /* GPIO-1 s5h1409 demod reset i2c bus 0 */
+ /* GPIO-2 xc5000 tuner reset i2c bus 1 */
+ /* GPIO-3 s5h1409 demod reset i2c bus 0 */
+
+ /* Put the parts into reset and back */
+ cx_set(GP0_IO, 0x000f0000);
+ mdelay(20);
+ cx_clear(GP0_IO, 0x0000000f);
+ mdelay(20);
+ cx_set(GP0_IO, 0x000f000f);
+ break;
}
}
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index d17343ea0d3..6286a9cf957 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -76,6 +76,117 @@ LIST_HEAD(cx23885_devlist);
* 0x00010ea0 0x00010xxx Free
*/
+static struct sram_channel cx23885_sram_channels[] = {
+ [SRAM_CH01] = {
+ .name = "VID A",
+ .cmds_start = 0x10000,
+ .ctrl_start = 0x10380,
+ .cdt = 0x104c0,
+ .fifo_start = 0x40,
+ .fifo_size = 0x2800,
+ .ptr1_reg = DMA1_PTR1,
+ .ptr2_reg = DMA1_PTR2,
+ .cnt1_reg = DMA1_CNT1,
+ .cnt2_reg = DMA1_CNT2,
+ },
+ [SRAM_CH02] = {
+ .name = "ch2",
+ .cmds_start = 0x0,
+ .ctrl_start = 0x0,
+ .cdt = 0x0,
+ .fifo_start = 0x0,
+ .fifo_size = 0x0,
+ .ptr1_reg = DMA2_PTR1,
+ .ptr2_reg = DMA2_PTR2,
+ .cnt1_reg = DMA2_CNT1,
+ .cnt2_reg = DMA2_CNT2,
+ },
+ [SRAM_CH03] = {
+ .name = "TS1 B",
+ .cmds_start = 0x100A0,
+ .ctrl_start = 0x10400,
+ .cdt = 0x10580,
+ .fifo_start = 0x5000,
+ .fifo_size = 0x1000,
+ .ptr1_reg = DMA3_PTR1,
+ .ptr2_reg = DMA3_PTR2,
+ .cnt1_reg = DMA3_CNT1,
+ .cnt2_reg = DMA3_CNT2,
+ },
+ [SRAM_CH04] = {
+ .name = "ch4",
+ .cmds_start = 0x0,
+ .ctrl_start = 0x0,
+ .cdt = 0x0,
+ .fifo_start = 0x0,
+ .fifo_size = 0x0,
+ .ptr1_reg = DMA4_PTR1,
+ .ptr2_reg = DMA4_PTR2,
+ .cnt1_reg = DMA4_CNT1,
+ .cnt2_reg = DMA4_CNT2,
+ },
+ [SRAM_CH05] = {
+ .name = "ch5",
+ .cmds_start = 0x0,
+ .ctrl_start = 0x0,
+ .cdt = 0x0,
+ .fifo_start = 0x0,
+ .fifo_size = 0x0,
+ .ptr1_reg = DMA5_PTR1,
+ .ptr2_reg = DMA5_PTR2,
+ .cnt1_reg = DMA5_CNT1,
+ .cnt2_reg = DMA5_CNT2,
+ },
+ [SRAM_CH06] = {
+ .name = "TS2 C",
+ .cmds_start = 0x10140,
+ .ctrl_start = 0x10440,
+ .cdt = 0x105e0,
+ .fifo_start = 0x6000,
+ .fifo_size = 0x1000,
+ .ptr1_reg = DMA5_PTR1,
+ .ptr2_reg = DMA5_PTR2,
+ .cnt1_reg = DMA5_CNT1,
+ .cnt2_reg = DMA5_CNT2,
+ },
+ [SRAM_CH07] = {
+ .name = "ch7",
+ .cmds_start = 0x0,
+ .ctrl_start = 0x0,
+ .cdt = 0x0,
+ .fifo_start = 0x0,
+ .fifo_size = 0x0,
+ .ptr1_reg = DMA6_PTR1,
+ .ptr2_reg = DMA6_PTR2,
+ .cnt1_reg = DMA6_CNT1,
+ .cnt2_reg = DMA6_CNT2,
+ },
+ [SRAM_CH08] = {
+ .name = "ch8",
+ .cmds_start = 0x0,
+ .ctrl_start = 0x0,
+ .cdt = 0x0,
+ .fifo_start = 0x0,
+ .fifo_size = 0x0,
+ .ptr1_reg = DMA7_PTR1,
+ .ptr2_reg = DMA7_PTR2,
+ .cnt1_reg = DMA7_CNT1,
+ .cnt2_reg = DMA7_CNT2,
+ },
+ [SRAM_CH09] = {
+ .name = "ch9",
+ .cmds_start = 0x0,
+ .ctrl_start = 0x0,
+ .cdt = 0x0,
+ .fifo_start = 0x0,
+ .fifo_size = 0x0,
+ .ptr1_reg = DMA8_PTR1,
+ .ptr2_reg = DMA8_PTR2,
+ .cnt1_reg = DMA8_CNT1,
+ .cnt2_reg = DMA8_CNT2,
+ },
+};
+
static struct sram_channel cx23887_sram_channels[] = {
[SRAM_CH01] = {
.name = "VID A",
@@ -104,8 +215,8 @@ static struct sram_channel cx23887_sram_channels[] = {
[SRAM_CH03] = {
.name = "TS1 B",
.cmds_start = 0x100A0,
- .ctrl_start = 0x10780,
- .cdt = 0x10400,
+ .ctrl_start = 0x10630,
+ .cdt = 0x10870,
.fifo_start = 0x5000,
.fifo_size = 0x1000,
.ptr1_reg = DMA3_PTR1,
@@ -140,7 +251,7 @@ static struct sram_channel cx23887_sram_channels[] = {
[SRAM_CH06] = {
.name = "TS2 C",
.cmds_start = 0x10140,
- .ctrl_start = 0x10680,
+ .ctrl_start = 0x10670,
.cdt = 0x108d0,
.fifo_start = 0x6000,
.fifo_size = 0x1000,
@@ -460,6 +571,7 @@ static void cx23885_reset(struct cx23885_dev *dev)
cx_write(AUDIO_INT_INT_STAT, 0xffffffff);
cx_write(AUDIO_EXT_INT_STAT, 0xffffffff);
cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000);
+ cx_write(PAD_CTRL, 0x00500300);
mdelay(100);
@@ -625,7 +737,6 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
atomic_inc(&dev->refcount);
dev->nr = cx23885_devcount++;
- dev->sram_channels = cx23887_sram_channels;
sprintf(dev->name, "cx23885[%d]", dev->nr);
mutex_lock(&devlist);
@@ -637,11 +748,13 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
dev->bridge = CX23885_BRIDGE_887;
/* Apply a sensible clock frequency for the PCIe bridge */
dev->clk_freq = 25000000;
+ dev->sram_channels = cx23887_sram_channels;
} else
if(dev->pci->device == 0x8852) {
dev->bridge = CX23885_BRIDGE_885;
/* Apply a sensible clock frequency for the PCIe bridge */
dev->clk_freq = 28000000;
+ dev->sram_channels = cx23885_sram_channels;
} else
BUG();
@@ -1010,8 +1123,9 @@ static void cx23885_tsport_reg_dump(struct cx23885_tsport *port)
port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl));
dprintk(1, "%s() dma_ctl(0x%08X) 0x%08x\n", __func__,
port->reg_dma_ctl, cx_read(port->reg_dma_ctl));
- dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __func__,
- port->reg_src_sel, cx_read(port->reg_src_sel));
+ if (port->reg_src_sel)
+ dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __func__,
+ port->reg_src_sel, cx_read(port->reg_src_sel));
dprintk(1, "%s() lngth(0x%08X) 0x%08x\n", __func__,
port->reg_lngth, cx_read(port->reg_lngth));
dprintk(1, "%s() hw_sop_ctrl(0x%08X) 0x%08x\n", __func__,
@@ -1042,6 +1156,9 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__,
buf->vb.width, buf->vb.height, buf->vb.field);
+ /* Stop the fifo and risc engine for this port */
+ cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
+
/* setup fifo + format */
cx23885_sram_channel_setup(dev,
&dev->sram_channels[ port->sram_chno ],
@@ -1083,7 +1200,21 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
cx_write(port->reg_gpcnt_ctl, 3);
q->count = 1;
- if (cx23885_boards[dev->board].portb & CX23885_MPEG_ENCODER) {
+ /* Set VIDB pins to input */
+ if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) {
+ reg = cx_read(PAD_CTRL);
+ reg &= ~0x3; /* Clear TS1_OE & TS1_SOP_OE */
+ cx_write(PAD_CTRL, reg);
+ }
+
+ /* Set VIDC pins to input */
+ if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) {
+ reg = cx_read(PAD_CTRL);
+ reg &= ~0x4; /* Clear TS2_SOP_OE */
+ cx_write(PAD_CTRL, reg);
+ }
+
+ if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) {
reg = cx_read(PAD_CTRL);
reg = reg & ~0x1; /* Clear TS1_OE */
@@ -1133,7 +1264,7 @@ static int cx23885_stop_dma(struct cx23885_tsport *port)
cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val);
cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
- if (cx23885_boards[dev->board].portb & CX23885_MPEG_ENCODER) {
+ if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) {
reg = cx_read(PAD_CTRL);
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 043fc4e5c58..ad2235dab5b 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -33,6 +33,7 @@
#include "cx23885.h"
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#ifdef CONFIG_VIDEO_V4L1_COMPAT
/* Include V4L1 specific functions. Should be removed soon */
@@ -326,7 +327,7 @@ struct video_device *cx23885_vdev_init(struct cx23885_dev *dev,
return NULL;
*vfd = *template;
vfd->minor = -1;
- vfd->dev = &pci->dev;
+ vfd->parent = &pci->dev;
vfd->release = video_device_release;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
dev->name, type, cx23885_boards[dev->board].name);
@@ -1433,12 +1434,7 @@ static const struct file_operations video_fops = {
.llseek = no_llseek,
};
-static struct video_device cx23885_vbi_template;
-static struct video_device cx23885_video_template = {
- .name = "cx23885-video",
- .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES,
- .fops = &video_fops,
- .minor = -1,
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
@@ -1471,6 +1467,14 @@ static struct video_device cx23885_video_template = {
.vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register,
#endif
+};
+
+static struct video_device cx23885_vbi_template;
+static struct video_device cx23885_video_template = {
+ .name = "cx23885-video",
+ .fops = &video_fops,
+ .minor = -1,
+ .ioctl_ops = &video_ioctl_ops,
.tvnorms = CX23885_NORMS,
.current_norm = V4L2_STD_NTSC_M,
};
@@ -1512,7 +1516,6 @@ int cx23885_video_register(struct cx23885_dev *dev)
memcpy(&cx23885_vbi_template, &cx23885_video_template,
sizeof(cx23885_vbi_template));
strcpy(cx23885_vbi_template.name, "cx23885-vbi");
- cx23885_vbi_template.type = VID_TYPE_TELETEXT|VID_TYPE_TUNER;
dev->tvnorm = cx23885_video_template.current_norm;
diff --git a/drivers/media/video/cx25840/Kconfig b/drivers/media/video/cx25840/Kconfig
index 448f4cd0ce3..de515dadadc 100644
--- a/drivers/media/video/cx25840/Kconfig
+++ b/drivers/media/video/cx25840/Kconfig
@@ -1,8 +1,6 @@
config VIDEO_CX25840
tristate "Conexant CX2584x audio/video decoders"
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
- depends on HOTPLUG # due to FW_LOADER
- select FW_LOADER
---help---
Support for the Conexant CX2584x audio/video decoders.
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index e7bf4f4c131..209d3bcb5db 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -50,7 +50,7 @@ MODULE_LICENSE("GPL");
static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
-int cx25840_debug;
+static int cx25840_debug;
module_param_named(debug,cx25840_debug, int, 0644);
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index 72916ba975a..b87337e590b 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -24,8 +24,6 @@
#include <linux/videodev2.h>
#include <linux/i2c.h>
-extern int cx25840_debug;
-
/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
present in Hauppauge PVR-150 (and possibly PVR-500) cards that have
certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 10e20d8196d..9dd7bdf659b 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -33,9 +33,8 @@ config VIDEO_CX88_ALSA
config VIDEO_CX88_BLACKBIRD
tristate "Blackbird MPEG encoder support (cx2388x + cx23416)"
- depends on VIDEO_CX88 && HOTPLUG
+ depends on VIDEO_CX88
select VIDEO_CX2341X
- select FW_LOADER
---help---
This adds support for MPEG encoder cards based on the
Blackbird reference design, using the Conexant 2388x
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index bfdca584776..9a1374a38ec 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -33,6 +33,7 @@
#include <linux/device.h>
#include <linux/firmware.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/cx2341x.h>
#include "cx88.h"
@@ -1174,12 +1175,7 @@ static const struct file_operations mpeg_fops =
.llseek = no_llseek,
};
-static struct video_device cx8802_mpeg_template =
-{
- .name = "cx8802",
- .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES|VID_TYPE_MPEG_ENCODER,
- .fops = &mpeg_fops,
- .minor = -1,
+static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
.vidioc_querymenu = vidioc_querymenu,
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
@@ -1207,6 +1203,13 @@ static struct video_device cx8802_mpeg_template =
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_s_std = vidioc_s_std,
+};
+
+static struct video_device cx8802_mpeg_template = {
+ .name = "cx8802",
+ .fops = &mpeg_fops,
+ .ioctl_ops = &mpeg_ioctl_ops,
+ .minor = -1,
.tvnorms = CX88_NORMS,
.current_norm = V4L2_STD_NTSC_M,
};
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index fa6d398e97b..de199a206a1 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1348,7 +1348,7 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .audio_chip = AUDIO_CHIP_WM8775,
+ .audio_chip = V4L2_IDENT_WM8775,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 60eeda3057e..d656fec5901 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -40,6 +40,7 @@
#include "cx88.h"
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
@@ -1006,7 +1007,7 @@ struct video_device *cx88_vdev_init(struct cx88_core *core,
return NULL;
*vfd = *template;
vfd->minor = -1;
- vfd->dev = &pci->dev;
+ vfd->parent = &pci->dev;
vfd->release = video_device_release;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
core->name, type, core->board.name);
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 0fed5cd2cce..ef4d56ea002 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -39,6 +39,7 @@
#include "cx88.h"
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#ifdef CONFIG_VIDEO_V4L1_COMPAT
/* Include V4L1 specific functions. Should be removed soon */
@@ -447,7 +448,7 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
the initialization. Some boards may use different
routes for different inputs. HVR-1300 surely does */
if (core->board.audio_chip &&
- core->board.audio_chip == AUDIO_CHIP_WM8775) {
+ core->board.audio_chip == V4L2_IDENT_WM8775) {
struct v4l2_routing route;
route.input = INPUT(input).audioroute;
@@ -1682,13 +1683,7 @@ static const struct file_operations video_fops =
.llseek = no_llseek,
};
-static struct video_device cx8800_vbi_template;
-static struct video_device cx8800_video_template =
-{
- .name = "cx8800-video",
- .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES,
- .fops = &video_fops,
- .minor = -1,
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
@@ -1721,6 +1716,15 @@ static struct video_device cx8800_video_template =
.vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register,
#endif
+};
+
+static struct video_device cx8800_vbi_template;
+
+static struct video_device cx8800_video_template = {
+ .name = "cx8800-video",
+ .fops = &video_fops,
+ .minor = -1,
+ .ioctl_ops = &video_ioctl_ops,
.tvnorms = CX88_NORMS,
.current_norm = V4L2_STD_NTSC_M,
};
@@ -1735,12 +1739,7 @@ static const struct file_operations radio_fops =
.llseek = no_llseek,
};
-static struct video_device cx8800_radio_template =
-{
- .name = "cx8800-radio",
- .type = VID_TYPE_TUNER,
- .fops = &radio_fops,
- .minor = -1,
+static const struct v4l2_ioctl_ops radio_ioctl_ops = {
.vidioc_querycap = radio_querycap,
.vidioc_g_tuner = radio_g_tuner,
.vidioc_enum_input = radio_enum_input,
@@ -1759,6 +1758,13 @@ static struct video_device cx8800_radio_template =
#endif
};
+static struct video_device cx8800_radio_template = {
+ .name = "cx8800-radio",
+ .fops = &radio_fops,
+ .minor = -1,
+ .ioctl_ops = &radio_ioctl_ops,
+};
+
/* ----------------------------------------------------------- */
static void cx8800_unregister_video(struct cx8800_dev *dev)
@@ -1830,7 +1836,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
memcpy( &cx8800_vbi_template, &cx8800_video_template,
sizeof(cx8800_vbi_template) );
strcpy(cx8800_vbi_template.name,"cx8800-vbi");
- cx8800_vbi_template.type = VID_TYPE_TELETEXT|VID_TYPE_TUNER;
/* initialize driver struct */
spin_lock_init(&dev->slock);
@@ -1866,7 +1871,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
/* load and configure helper modules */
- if (core->board.audio_chip == AUDIO_CHIP_WM8775)
+ if (core->board.audio_chip == V4L2_IDENT_WM8775)
request_module("wm8775");
switch (core->boardnr) {
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 14ac173f407..54fe6509471 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -29,8 +29,8 @@
#include <media/tuner.h>
#include <media/tveeprom.h>
#include <media/videobuf-dma-sg.h>
+#include <media/v4l2-chip-ident.h>
#include <media/cx2341x.h>
-#include <media/audiochip.h>
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
#include <media/videobuf-dvb.h>
#endif
@@ -252,7 +252,7 @@ struct cx88_board {
struct cx88_input input[MAX_CX88_INPUT];
struct cx88_input radio;
enum cx88_board_type mpeg;
- enum audiochip audio_chip;
+ unsigned int audio_chip;
};
struct cx88_subid {
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 05f0d5a1505..476ae44a62d 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -32,8 +32,8 @@
#include <media/saa7115.h>
#include <media/tvp5150.h>
#include <media/tveeprom.h>
-#include <media/audiochip.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
#include "em28xx.h"
@@ -52,6 +52,15 @@ struct em28xx_hash_table {
};
struct em28xx_board em28xx_boards[] = {
+ [EM2750_BOARD_UNKNOWN] = {
+ .name = "Unknown EM2750/EM2751 webcam grabber",
+ .vchannels = 1,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 0,
+ } },
+ },
[EM2800_BOARD_UNKNOWN] = {
.name = "Unknown EM2800 video grabber",
.is_em2800 = 1,
@@ -73,6 +82,39 @@ struct em28xx_board em28xx_boards[] = {
.is_em2800 = 0,
.tuner_type = TUNER_ABSENT,
},
+ [EM2750_BOARD_DLCW_130] = {
+ /* Beijing Huaqi Information Digital Technology Co., Ltd */
+ .name = "Huaqi DLCW-130",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 1,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 0,
+ } },
+ },
+ [EM2800_BOARD_KWORLD_USB2800] = {
+ .name = "Kworld USB2800",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .is_em2800 = 1,
+ .vchannels = 3,
+ .tuner_type = TUNER_PHILIPS_FCV1236D,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
[EM2820_BOARD_KWORLD_PVRTV2800RF] = {
.name = "Kworld PVR TV 2800 RF",
.is_em2800 = 0,
@@ -151,6 +193,376 @@ struct em28xx_board em28xx_boards[] = {
MSP_DSP_IN_SCART, MSP_DSP_IN_SCART),
} },
},
+ [EM2820_BOARD_DLINK_USB_TV] = {
+ .name = "D-Link DUB-T210 TV Tuner",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .is_em2800 = 0,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2820_BOARD_HERCULES_SMART_TV_USB2] = {
+ .name = "Hercules Smart TV USB 2.0",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2820_BOARD_PINNACLE_USB_2_FM1216ME] = {
+ .name = "Pinnacle PCTV USB 2 (Philips FM1216ME)",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .is_em2800 = 0,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2820_BOARD_GADMEI_UTV310] = {
+ .name = "Gadmei UTV310",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_TNF_5335MF,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE] = {
+ .name = "Leadtek Winfast USB II Deluxe",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA7114,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = 2,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = 9,
+ .amux = 1,
+ } },
+ },
+ [EM2820_BOARD_PINNACLE_DVC_100] = {
+ .name = "Pinnacle Dazzle DVC 100",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
+ .name = "Videology 20K14XUSB USB2.0",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 1,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 0,
+ } },
+ },
+ [EM2821_BOARD_PROLINK_PLAYTV_USB2] = {
+ .name = "SIIG AVTuner-PVR/Prolink PlayTV USB 2.0",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .is_em2800 = 0,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC, /* unknown? */
+ .tda9887_conf = TDA9887_PRESENT, /* unknown? */
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2821_BOARD_SUPERCOMP_USB_2] = {
+ .name = "Supercomp USB 2.0 TV",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .is_em2800 = 0,
+ .tuner_type = TUNER_PHILIPS_FM1236_MK3,
+ .tda9887_conf = TDA9887_PRESENT |
+ TDA9887_PORT1_ACTIVE |
+ TDA9887_PORT2_ACTIVE,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2821_BOARD_USBGEAR_VD204] = {
+ .name = "Usbgear VD204v9",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 2,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2860_BOARD_NETGMBH_CAM] = {
+ /* Beijing Huaqi Information Digital Technology Co., Ltd */
+ .name = "NetGMBH Cam",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 1,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = 0,
+ } },
+ },
+ [EM2860_BOARD_TYPHOON_DVD_MAKER] = {
+ .name = "Typhoon DVD Maker",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 2,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2860_BOARD_GADMEI_UTV330] = {
+ .name = "Gadmei UTV330",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_TNF_5335MF,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
+ [EM2860_BOARD_TERRATEC_HYBRID_XS] = {
+ .name = "Terratec Cinergy A Hybrid XS",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2861_BOARD_KWORLD_PVRTV_300U] = {
+ .name = "KWorld PVRTV 300U",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2861_BOARD_YAKUMO_MOVIE_MIXER] = {
+ .name = "Yakumo MovieMixer",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 1,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2861_BOARD_PLEXTOR_PX_TV100U] = {
+ .name = "Plextor ConvertX PX-TV100U",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_TNF_5335MF,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2870_BOARD_TERRATEC_XS] = {
+ .name = "Terratec Cinergy T XS",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .tuner_type = TUNER_XC2028,
+ },
+ [EM2870_BOARD_TERRATEC_XS_MT2060] = {
+ .name = "Terratec Cinergy T XS (MT2060)",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .tuner_type = TUNER_ABSENT, /* MT2060 */
+ },
+ [EM2870_BOARD_KWORLD_350U] = {
+ .name = "Kworld 350 U DVB-T",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .tuner_type = TUNER_XC2028,
+ },
+ [EM2870_BOARD_KWORLD_355U] = {
+ .name = "Kworld 355 U DVB-T",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ },
+ [EM2870_BOARD_PINNACLE_PCTV_DVB] = {
+ .name = "Pinnacle PCTV DVB-T",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .tuner_type = TUNER_ABSENT, /* MT2060 */
+ },
+ [EM2870_BOARD_COMPRO_VIDEOMATE] = {
+ .name = "Compro, VideoMate U3",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .tuner_type = TUNER_ABSENT, /* MT2060 */
+ },
+ [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = {
+ .name = "Terratec Hybrid XS Secam",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .has_msp34xx = 1,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
[EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = {
.name = "Hauppauge WinTV HVR 900",
.vchannels = 3,
@@ -194,7 +606,7 @@ struct em28xx_board em28xx_boards[] = {
.amux = 1,
} },
},
- [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
+ [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
.name = "Hauppauge WinTV HVR 950",
.vchannels = 3,
.tda9887_conf = TDA9887_PRESENT,
@@ -240,12 +652,36 @@ struct em28xx_board em28xx_boards[] = {
.amux = 1,
} },
},
+ [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = {
+ .name = "AMD ATI TV Wonder HD 600",
+ .vchannels = 3,
+ .tda9887_conf = TDA9887_PRESENT,
+ .tuner_type = TUNER_XC2028,
+ .mts_firmware = 1,
+ .has_12mhz_i2s = 1,
+ .has_dvb = 1,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
[EM2880_BOARD_TERRATEC_HYBRID_XS] = {
.name = "Terratec Hybrid XS",
.vchannels = 3,
.tda9887_conf = TDA9887_PRESENT,
.tuner_type = TUNER_XC2028,
.decoder = EM28XX_TVP5150,
+ .has_dvb = 1,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
.vmux = TVP5150_COMPOSITE0,
@@ -328,6 +764,21 @@ struct em28xx_board em28xx_boards[] = {
.amux = 1,
} },
},
+ [EM2800_BOARD_GRABBEEX_USB2800] = {
+ .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
+ .is_em2800 = 1,
+ .vchannels = 2,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 1,
+ } },
+ },
[EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
.name = "Leadtek Winfast USB II",
.is_em2800 = 1,
@@ -439,13 +890,232 @@ struct em28xx_board em28xx_boards[] = {
.amux = 0,
} },
},
+ [EM2880_BOARD_MSI_DIGIVOX_AD] = {
+ .name = "MSI DigiVox A/D",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2880_BOARD_MSI_DIGIVOX_AD_II] = {
+ .name = "MSI DigiVox A/D II",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2880_BOARD_KWORLD_DVB_305U] = {
+ .name = "KWorld DVB-T 305U",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2880_BOARD_KWORLD_DVB_310U] = {
+ .name = "KWorld DVB-T 310U",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2881_BOARD_DNT_DA2_HYBRID] = {
+ .name = "DNT DA2 Hybrid",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2881_BOARD_PINNACLE_HYBRID_PRO] = {
+ .name = "Pinnacle Hybrid Pro",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2882_BOARD_PINNACLE_HYBRID_PRO] = {
+ .name = "Pinnacle Hybrid Pro (2)",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2882_BOARD_KWORLD_VS_DVBT] = {
+ .name = "Kworld VS-DVB-T 323UR",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2882_BOARD_TERRATEC_HYBRID_XS] = {
+ .name = "Terratec Hybrid XS (em2882)",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2883_BOARD_KWORLD_HYBRID_A316] = {
+ .name = "Kworld PlusTV HD Hybrid 330",
+ .valid = EM28XX_BOARD_NOT_VALIDATED,
+ .vchannels = 3,
+ .is_em2800 = 0,
+ .tuner_type = TUNER_XC2028,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
+ [EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
+ .name = "Compro VideoMate ForYou/Stereo",
+ .vchannels = 2,
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = EM28XX_AMUX_LINE_IN,
+ } },
+ },
};
const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
/* table of devices that work with this driver */
struct usb_device_id em28xx_id_table [] = {
{ USB_DEVICE(0xeb1a, 0x2750),
- .driver_info = EM2820_BOARD_UNKNOWN },
+ .driver_info = EM2750_BOARD_UNKNOWN },
+ { USB_DEVICE(0xeb1a, 0x2751),
+ .driver_info = EM2750_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0x2800),
.driver_info = EM2800_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0x2820),
@@ -462,36 +1132,78 @@ struct usb_device_id em28xx_id_table [] = {
.driver_info = EM2820_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0x2883),
.driver_info = EM2820_BOARD_UNKNOWN },
+ { USB_DEVICE(0xeb1a, 0xe300),
+ .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
+ { USB_DEVICE(0xeb1a, 0xe305),
+ .driver_info = EM2880_BOARD_KWORLD_DVB_305U },
+ { USB_DEVICE(0xeb1a, 0xe310),
+ .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD },
+ { USB_DEVICE(0xeb1a, 0xa316),
+ .driver_info = EM2883_BOARD_KWORLD_HYBRID_A316 },
+ { USB_DEVICE(0xeb1a, 0xe320),
+ .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II },
+ { USB_DEVICE(0xeb1a, 0xe323),
+ .driver_info = EM2882_BOARD_KWORLD_VS_DVBT },
+ { USB_DEVICE(0xeb1a, 0xe350),
+ .driver_info = EM2870_BOARD_KWORLD_350U },
+ { USB_DEVICE(0xeb1a, 0xe355),
+ .driver_info = EM2870_BOARD_KWORLD_355U },
+ { USB_DEVICE(0xeb1a, 0x2801),
+ .driver_info = EM2800_BOARD_GRABBEEX_USB2800 },
+ { USB_DEVICE(0xeb1a, 0xe357),
+ .driver_info = EM2870_BOARD_KWORLD_355U },
{ USB_DEVICE(0x0ccd, 0x0036),
.driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
- { USB_DEVICE(0x2304, 0x0208),
- .driver_info = EM2820_BOARD_PINNACLE_USB_2 },
+ { USB_DEVICE(0x0ccd, 0x004c),
+ .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS_FR },
+ { USB_DEVICE(0x0ccd, 0x004f),
+ .driver_info = EM2860_BOARD_TERRATEC_HYBRID_XS },
+ { USB_DEVICE(0x0ccd, 0x005e),
+ .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
+ { USB_DEVICE(0x0ccd, 0x0042),
+ .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
+ { USB_DEVICE(0x0ccd, 0x0043),
+ .driver_info = EM2870_BOARD_TERRATEC_XS },
+ { USB_DEVICE(0x0ccd, 0x0047),
+ .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS },
+ { USB_DEVICE(0x185b, 0x2870),
+ .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE },
+ { USB_DEVICE(0x185b, 0x2041),
+ .driver_info = EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU },
{ USB_DEVICE(0x2040, 0x4200),
.driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
{ USB_DEVICE(0x2040, 0x4201),
.driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
- { USB_DEVICE(0x2304, 0x0207),
- .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
- { USB_DEVICE(0x2304, 0x021a),
- .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
- { USB_DEVICE(0x2304, 0x0227),
- .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
{ USB_DEVICE(0x2040, 0x6500),
.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
{ USB_DEVICE(0x2040, 0x6502),
.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 },
{ USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */
- .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+ .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
{ USB_DEVICE(0x2040, 0x6517), /* HP HVR-950 */
- .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+ .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
{ USB_DEVICE(0x2040, 0x651b), /* RP HVR-950 */
- .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+ .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
{ USB_DEVICE(0x2040, 0x651f), /* HCW HVR-850 */
- .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
- { USB_DEVICE(0x0ccd, 0x0042),
- .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
- { USB_DEVICE(0x0ccd, 0x0047),
- .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS },
+ .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+ { USB_DEVICE(0x0438, 0xb002),
+ .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 },
+ { USB_DEVICE(0x2001, 0xf112),
+ .driver_info = EM2820_BOARD_DLINK_USB_TV },
+ { USB_DEVICE(0x2304, 0x0207),
+ .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
+ { USB_DEVICE(0x2304, 0x0208),
+ .driver_info = EM2820_BOARD_PINNACLE_USB_2 },
+ { USB_DEVICE(0x2304, 0x021a),
+ .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
+ { USB_DEVICE(0x2304, 0x0226),
+ .driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO },
+ { USB_DEVICE(0x2304, 0x0227),
+ .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
+ { USB_DEVICE(0x0413, 0x6023),
+ .driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII },
+ { USB_DEVICE(0x093b, 0xa005),
+ .driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U },
{ },
};
MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -500,6 +1212,18 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table);
* Reset sequences for analog/digital modes
*/
+/* Reset for the most [analog] boards */
+static struct em28xx_reg_seq default_analog[] = {
+ {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
+ { -1, -1, -1, -1},
+};
+
+/* Reset for the most [digital] boards */
+static struct em28xx_reg_seq default_digital[] = {
+ {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
+ { -1, -1, -1, -1},
+};
+
/* Board Hauppauge WinTV HVR 900 analog */
static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
{EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10},
@@ -515,14 +1239,42 @@ static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
{ -1, -1, -1, -1},
};
-/* Board Hauppauge WinTV HVR 900 tuner_callback */
-static struct em28xx_reg_seq hauppauge_wintv_hvr_900_tuner_callback[] = {
+/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
+static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
+ {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10},
+ { -1, -1, -1, -1},
+};
+
+/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
+static struct em28xx_reg_seq em2880_msi_digivox_ad_digital[] = {
+ {EM28XX_R08_GPIO, 0x6a, ~EM_GPIO_4, 10},
+ { -1, -1, -1, -1},
+};
+
+/* Board - EM2870 Kworld 355u
+ Analog - No input analog */
+static struct em28xx_reg_seq em2870_kworld_355u_digital[] = {
+ {EM2880_R04_GPO, 0x01, 0xff, 10},
+ { -1, -1, -1, -1},
+};
+
+/* Callback for the most boards */
+static struct em28xx_reg_seq default_callback[] = {
{EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
{EM28XX_R08_GPIO, 0, EM_GPIO_4, 10},
{EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
{ -1, -1, -1, -1},
};
+/* Callback for EM2882 TERRATEC HYBRID XS */
+static struct em28xx_reg_seq em2882_terratec_hybrid_xs_digital[] = {
+ {EM28XX_R08_GPIO, 0x2e, 0xff, 6},
+ {EM28XX_R08_GPIO, 0x3e, ~EM_GPIO_4, 6},
+ {EM2880_R04_GPO, 0x04, 0xff, 10},
+ {EM2880_R04_GPO, 0x0c, 0xff, 10},
+ { -1, -1, -1, -1},
+};
+
/*
* EEPROM hash table for devices with generic USB IDs
*/
@@ -569,6 +1321,7 @@ static void em28xx_set_model(struct em28xx *dev)
dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480;
dev->has_dvb = em28xx_boards[dev->model].has_dvb;
dev->has_snapshot_button = em28xx_boards[dev->model].has_snapshot_button;
+ dev->valid = em28xx_boards[dev->model].valid;
}
/* Since em28xx_pre_card_setup() requires a proper dev->model,
@@ -604,19 +1357,171 @@ void em28xx_pre_card_setup(struct em28xx *dev)
case EM2880_BOARD_TERRATEC_PRODIGY_XS:
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
- case EM2880_BOARD_TERRATEC_HYBRID_XS:
- case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
+ case EM2860_BOARD_TERRATEC_HYBRID_XS:
+ case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
+ case EM2882_BOARD_PINNACLE_HYBRID_PRO:
+ case EM2883_BOARD_KWORLD_HYBRID_A316:
+ case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ msleep(50);
+
+ /* Sets GPO/GPIO sequences for this device */
+ dev->analog_gpio = hauppauge_wintv_hvr_900_analog;
+ dev->digital_gpio = hauppauge_wintv_hvr_900_digital;
+ dev->tun_analog_gpio = default_callback;
+ dev->tun_digital_gpio = default_callback;
+ break;
+
+ case EM2882_BOARD_TERRATEC_HYBRID_XS:
em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
msleep(50);
+ /* should be added ir_codes here */
+
/* Sets GPO/GPIO sequences for this device */
dev->analog_gpio = hauppauge_wintv_hvr_900_analog;
dev->digital_gpio = hauppauge_wintv_hvr_900_digital;
- dev->tun_analog_gpio = hauppauge_wintv_hvr_900_tuner_callback;
- dev->tun_digital_gpio = hauppauge_wintv_hvr_900_tuner_callback;
+ dev->tun_analog_gpio = default_callback;
+ dev->tun_digital_gpio = em2882_terratec_hybrid_xs_digital;
+ break;
+
+ case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
+ case EM2880_BOARD_TERRATEC_HYBRID_XS:
+ case EM2870_BOARD_TERRATEC_XS:
+ case EM2881_BOARD_PINNACLE_HYBRID_PRO:
+ case EM2880_BOARD_KWORLD_DVB_310U:
+ case EM2870_BOARD_KWORLD_350U:
+ case EM2881_BOARD_DNT_DA2_HYBRID:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ msleep(50);
+
+ /* NOTE: EM2881_DNT_DA2_HYBRID spend 140 msleep for digital
+ and analog commands. If this commands doesn't work,
+ add this timer. */
+ /* Sets GPO/GPIO sequences for this device */
+ dev->analog_gpio = default_analog;
+ dev->digital_gpio = default_digital;
+ dev->tun_analog_gpio = default_callback;
+ dev->tun_digital_gpio = default_callback;
+ break;
+
+ case EM2880_BOARD_MSI_DIGIVOX_AD:
+ case EM2880_BOARD_MSI_DIGIVOX_AD_II:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ msleep(50);
+
+ /* Sets GPO/GPIO sequences for this device */
+ dev->analog_gpio = em2880_msi_digivox_ad_analog;
+ dev->digital_gpio = em2880_msi_digivox_ad_digital;
+ dev->tun_analog_gpio = default_callback;
+ dev->tun_digital_gpio = default_callback;
+ break;
+
+ case EM2750_BOARD_UNKNOWN:
+ case EM2750_BOARD_DLCW_130:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x0a", 1);
+ break;
+
+ case EM2861_BOARD_PLEXTOR_PX_TV100U:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ /* FIXME guess */
+ /* Turn on analog audio output */
+ em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1);
+ break;
+
+ case EM2861_BOARD_KWORLD_PVRTV_300U:
+ case EM2880_BOARD_KWORLD_DVB_305U:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x4c", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x08, "\x6d", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x08, "\x7d", 1);
+ msleep(10);
+ break;
+
+ case EM2870_BOARD_KWORLD_355U:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ msleep(50);
+
+ /* Sets GPO/GPIO sequences for this device */
+ dev->digital_gpio = em2870_kworld_355u_digital;
+ break;
+
+ case EM2870_BOARD_COMPRO_VIDEOMATE:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ /* TODO: someone can do some cleanup here...
+ not everything's needed */
+ em28xx_write_regs(dev, 0x04, "\x00", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x04, "\x01", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x08, "\xfd", 1);
+ mdelay(70);
+ em28xx_write_regs(dev, 0x08, "\xfc", 1);
+ mdelay(70);
+ em28xx_write_regs(dev, 0x08, "\xdc", 1);
+ mdelay(70);
+ em28xx_write_regs(dev, 0x08, "\xfc", 1);
+ mdelay(70);
+ break;
+
+ case EM2870_BOARD_TERRATEC_XS_MT2060:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ /* this device needs some gpio writes to get the DVB-T
+ demod work */
+ em28xx_write_regs(dev, 0x08, "\xfe", 1);
+ mdelay(70);
+ em28xx_write_regs(dev, 0x08, "\xde", 1);
+ mdelay(70);
+ dev->em28xx_write_regs(dev, 0x08, "\xfe", 1);
+ mdelay(70);
+ break;
+
+ case EM2870_BOARD_PINNACLE_PCTV_DVB:
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ /* this device needs some gpio writes to get the
+ DVB-T demod work */
+ em28xx_write_regs(dev, 0x08, "\xfe", 1);
+ mdelay(70);
+ em28xx_write_regs(dev, 0x08, "\xde", 1);
+ mdelay(70);
+ em28xx_write_regs(dev, 0x08, "\xfe", 1);
+ mdelay(70);
+ /* switch em2880 rc protocol */
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x22", 1);
+ /* should be added ir_codes here */
+ break;
+
+ case EM2820_BOARD_GADMEI_UTV310:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ /* Turn on analog audio output */
+ em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1);
+ break;
+
+ case EM2860_BOARD_GADMEI_UTV330:
+ /* Turn on IR */
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ /* should be added ir_codes here */
+ break;
+
+ case EM2820_BOARD_MSI_VOX_USB_2:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ /* enables audio for that device */
+ em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1);
break;
}
@@ -639,12 +1544,16 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
ctl->demod = XC3028_FE_ZARLINK456;
break;
+ case EM2880_BOARD_TERRATEC_HYBRID_XS:
+ ctl->demod = XC3028_FE_ZARLINK456;
+ break;
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
/* djh - Not sure which demod we need here */
ctl->demod = XC3028_FE_DEFAULT;
break;
- case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
+ case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
+ case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
/* FIXME: Better to specify the needed IF */
ctl->demod = XC3028_FE_DEFAULT;
break;
@@ -809,6 +1718,8 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
break;
case (EM2800_BOARD_KWORLD_USB2800):
break;
+ case (EM2800_BOARD_GRABBEEX_USB2800):
+ break;
}
}
@@ -823,7 +1734,7 @@ void em28xx_card_setup(struct em28xx *dev)
case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
- case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
+ case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
{
struct tveeprom tv;
#ifdef CONFIG_MODULES
@@ -836,7 +1747,7 @@ void em28xx_card_setup(struct em28xx *dev)
dev->tuner_type = tv.tuner_type;
- if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
+ if (tv.audio_processor == V4L2_IDENT_MSPX4XX) {
dev->i2s_speed = 2048000;
dev->has_msp34xx = 1;
}
@@ -854,11 +1765,21 @@ void em28xx_card_setup(struct em28xx *dev)
case EM2800_BOARD_UNKNOWN:
if (!em28xx_hint_board(dev))
em28xx_set_model(dev);
+ break;
}
if (dev->has_snapshot_button)
em28xx_register_snapshot_button(dev);
+ if (dev->valid == EM28XX_BOARD_NOT_VALIDATED) {
+ em28xx_errdev("\n\n");
+ em28xx_errdev("The support for this board weren't "
+ "valid yet.\n");
+ em28xx_errdev("Please send a report of having this working\n");
+ em28xx_errdev("not to V4L mailing list (and/or to other "
+ "addresses)\n\n");
+ }
+
/* Allow override tuner type by a module parameter */
if (tuner >= 0)
dev->tuner_type = tuner;
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index cc61cfb23a4..4b992bc0083 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -6,6 +6,7 @@
(c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com>
- Fixes for the driver to properly work with HVR-950
- Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick
+ - Fixes for the driver to properly work with AMD ATI TV Wonder HD 600
(c) 2008 Aidan Thornton <makosoft@googlemail.com>
@@ -409,8 +410,9 @@ static int dvb_init(struct em28xx *dev)
em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
/* init frontend */
switch (dev->model) {
- case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
+ case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
+ case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
dvb->frontend = dvb_attach(lgdt330x_attach,
&em2880_lgdt3303_dev,
&dev->i2c_adap);
@@ -441,6 +443,15 @@ static int dvb_init(struct em28xx *dev)
}
break;
#endif
+ case EM2880_BOARD_TERRATEC_HYBRID_XS:
+ dvb->frontend = dvb_attach(zl10353_attach,
+ &em28xx_zl10353_with_xc3028,
+ &dev->i2c_adap);
+ if (attach_xc3028(0x61, dev) < 0) {
+ result = -EINVAL;
+ goto out_free;
+ }
+ break;
default:
printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
" isn't supported yet\n",
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 2d9f14d2a00..49ab0629702 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -38,6 +38,7 @@
#include "em28xx.h"
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/msp3400.h>
#include <media/tuner.h>
@@ -1763,20 +1764,7 @@ static const struct file_operations em28xx_v4l_fops = {
.compat_ioctl = v4l_compat_ioctl32,
};
-static const struct file_operations radio_fops = {
- .owner = THIS_MODULE,
- .open = em28xx_v4l2_open,
- .release = em28xx_v4l2_close,
- .ioctl = video_ioctl2,
- .compat_ioctl = v4l_compat_ioctl32,
- .llseek = no_llseek,
-};
-
-static const struct video_device em28xx_video_template = {
- .fops = &em28xx_v4l_fops,
- .release = video_device_release,
-
- .minor = -1,
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
@@ -1814,16 +1802,29 @@ static const struct video_device em28xx_video_template = {
#ifdef CONFIG_VIDEO_V4L1_COMPAT
.vidiocgmbuf = vidiocgmbuf,
#endif
+};
+
+static const struct video_device em28xx_video_template = {
+ .fops = &em28xx_v4l_fops,
+ .release = video_device_release,
+ .ioctl_ops = &video_ioctl_ops,
+
+ .minor = -1,
.tvnorms = V4L2_STD_ALL,
.current_norm = V4L2_STD_PAL,
};
-static struct video_device em28xx_radio_template = {
- .name = "em28xx-radio",
- .type = VID_TYPE_TUNER,
- .fops = &radio_fops,
- .minor = -1,
+static const struct file_operations radio_fops = {
+ .owner = THIS_MODULE,
+ .open = em28xx_v4l2_open,
+ .release = em28xx_v4l2_close,
+ .ioctl = video_ioctl2,
+ .compat_ioctl = v4l_compat_ioctl32,
+ .llseek = no_llseek,
+};
+
+static const struct v4l2_ioctl_ops radio_ioctl_ops = {
.vidioc_querycap = radio_querycap,
.vidioc_g_tuner = radio_g_tuner,
.vidioc_enum_input = radio_enum_input,
@@ -1842,6 +1843,13 @@ static struct video_device em28xx_radio_template = {
#endif
};
+static struct video_device em28xx_radio_template = {
+ .name = "em28xx-radio",
+ .fops = &radio_fops,
+ .ioctl_ops = &radio_ioctl_ops,
+ .minor = -1,
+};
+
/******************************** usb interface ******************************/
@@ -1882,7 +1890,6 @@ EXPORT_SYMBOL(em28xx_unregister_extension);
static struct video_device *em28xx_vdev_init(struct em28xx *dev,
const struct video_device *template,
- const int type,
const char *type_name)
{
struct video_device *vfd;
@@ -1892,9 +1899,8 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
return NULL;
*vfd = *template;
vfd->minor = -1;
- vfd->dev = &dev->udev->dev;
+ vfd->parent = &dev->udev->dev;
vfd->release = video_device_release;
- vfd->type = type;
vfd->debug = video_debug;
snprintf(vfd->name, sizeof(vfd->name), "%s %s",
@@ -1972,14 +1978,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
list_add_tail(&dev->devlist, &em28xx_devlist);
/* allocate and fill video video_device struct */
- dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template,
- VID_TYPE_CAPTURE, "video");
+ dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
if (NULL == dev->vdev) {
em28xx_errdev("cannot allocate video_device.\n");
goto fail_unreg;
}
- if (dev->tuner_type != TUNER_ABSENT)
- dev->vdev->type |= VID_TYPE_TUNER;
/* register v4l2 video video_device */
retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
@@ -1991,8 +1994,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
}
/* Allocate and fill vbi video_device struct */
- dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template,
- VFL_TYPE_VBI, "vbi");
+ dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi");
/* register v4l2 vbi video_device */
if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
vbi_nr[dev->devno]) < 0) {
@@ -2002,8 +2004,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
}
if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
- dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
- VFL_TYPE_RADIO, "radio");
+ dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio");
if (NULL == dev->radio_dev) {
em28xx_errdev("cannot allocate video_device.\n");
goto fail_unreg;
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 89842c5d64a..9a331074868 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -54,15 +54,58 @@
#define EM2880_BOARD_TERRATEC_PRODIGY_XS 13
#define EM2820_BOARD_PROLINK_PLAYTV_USB2 14
#define EM2800_BOARD_VGEAR_POCKETTV 15
-#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 16
+#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 16
#define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17
#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18
#define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19
+#define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20
+#define EM2800_BOARD_GRABBEEX_USB2800 21
+#define EM2750_BOARD_UNKNOWN 22
+#define EM2750_BOARD_DLCW_130 23
+#define EM2820_BOARD_DLINK_USB_TV 24
+#define EM2820_BOARD_GADMEI_UTV310 25
+#define EM2820_BOARD_HERCULES_SMART_TV_USB2 26
+#define EM2820_BOARD_PINNACLE_USB_2_FM1216ME 27
+#define EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE 28
+#define EM2820_BOARD_PINNACLE_DVC_100 29
+#define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30
+#define EM2821_BOARD_USBGEAR_VD204 31
+#define EM2821_BOARD_SUPERCOMP_USB_2 32
+#define EM2821_BOARD_PROLINK_PLAYTV_USB2 33
+#define EM2860_BOARD_TERRATEC_HYBRID_XS 34
+#define EM2860_BOARD_TYPHOON_DVD_MAKER 35
+#define EM2860_BOARD_NETGMBH_CAM 36
+#define EM2860_BOARD_GADMEI_UTV330 37
+#define EM2861_BOARD_YAKUMO_MOVIE_MIXER 38
+#define EM2861_BOARD_KWORLD_PVRTV_300U 39
+#define EM2861_BOARD_PLEXTOR_PX_TV100U 40
+#define EM2870_BOARD_KWORLD_350U 41
+#define EM2870_BOARD_KWORLD_355U 42
+#define EM2870_BOARD_TERRATEC_XS 43
+#define EM2870_BOARD_TERRATEC_XS_MT2060 44
+#define EM2870_BOARD_PINNACLE_PCTV_DVB 45
+#define EM2870_BOARD_COMPRO_VIDEOMATE 46
+#define EM2880_BOARD_KWORLD_DVB_305U 47
+#define EM2880_BOARD_KWORLD_DVB_310U 48
+#define EM2880_BOARD_MSI_DIGIVOX_AD 49
+#define EM2880_BOARD_MSI_DIGIVOX_AD_II 50
+#define EM2880_BOARD_TERRATEC_HYBRID_XS_FR 51
+#define EM2881_BOARD_DNT_DA2_HYBRID 52
+#define EM2881_BOARD_PINNACLE_HYBRID_PRO 53
+#define EM2882_BOARD_KWORLD_VS_DVBT 54
+#define EM2882_BOARD_TERRATEC_HYBRID_XS 55
+#define EM2882_BOARD_PINNACLE_HYBRID_PRO 56
+#define EM2883_BOARD_KWORLD_HYBRID_A316 57
+#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
#define EM28XX_DEF_BUF 8
+/* Params for validated field */
+#define EM28XX_BOARD_NOT_VALIDATED 1
+#define EM28XX_BOARD_VALIDATED 0
+
/* maximum number of em28xx boards */
#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
@@ -251,6 +294,7 @@ struct em28xx_board {
unsigned int max_range_640_480:1;
unsigned int has_dvb:1;
unsigned int has_snapshot_button:1;
+ unsigned int valid:1;
enum em28xx_decoder decoder;
@@ -331,6 +375,7 @@ struct em28xx {
unsigned int max_range_640_480:1;
unsigned int has_dvb:1;
unsigned int has_snapshot_button:1;
+ unsigned int valid:1; /* report for validated boards */
/* Some older em28xx chips needs a waiting time after writing */
unsigned int wait_after_write;
@@ -360,7 +405,7 @@ struct em28xx {
v4l2_std_id norm; /* selected tv norm */
int ctl_freq; /* selected frequency */
unsigned int ctl_input; /* selected input */
- unsigned int ctl_ainput; /* slected audio input */
+ unsigned int ctl_ainput;/* selected audio input */
int mute;
int volume;
/* frame properties */
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index 15d037ae25c..2d170d101c2 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -34,6 +34,7 @@
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/page-flags.h>
+#include <media/v4l2-ioctl.h>
#include <asm/byteorder.h>
#include <asm/page.h>
#include <asm/uaccess.h>
@@ -985,7 +986,7 @@ static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
static int et61x251_create_sysfs(struct et61x251_device* cam)
{
- struct device *classdev = &(cam->v4ldev->class_dev);
+ struct device *classdev = &(cam->v4ldev->dev);
int err = 0;
if ((err = device_create_file(classdev, &dev_attr_reg)))
@@ -2584,8 +2585,6 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
}
strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera");
- cam->v4ldev->owner = THIS_MODULE;
- cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
cam->v4ldev->fops = &et61x251_fops;
cam->v4ldev->minor = video_nr[dev_nr];
cam->v4ldev->release = video_device_release;
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index 013d593b0c6..44b0bffeb20 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -25,9 +25,6 @@
#define CONEX_CAM 1 /* special JPEG header */
#include "jpeg.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
MODULE_LICENSE("GPL");
@@ -818,7 +815,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
@@ -1011,9 +1007,8 @@ static struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x0572, 0x0041), DVNM("Creative Notebook cx11646")},
+ {USB_DEVICE(0x0572, 0x0041)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -1038,7 +1033,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index 8ab4ea7201a..c8c2f02fcf0 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -22,9 +22,6 @@
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("Etoms USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -602,26 +599,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
- __u16 vendor;
- __u16 product;
-
- vendor = id->idVendor;
- product = id->idProduct;
-/* switch (vendor) { */
-/* case 0x102c: * Etoms */
- switch (product) {
- case 0x6151:
- sd->sensor = SENSOR_PAS106; /* Etoms61x151 */
- break;
- case 0x6251:
- sd->sensor = SENSOR_TAS5130CXX; /* Etoms61x251 */
- break;
-/* } */
-/* break; */
- }
+
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 1;
+ sd->sensor = id->driver_info;
if (sd->sensor == SENSOR_PAS106) {
cam->cam_mode = sif_mode;
cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
@@ -911,12 +892,11 @@ static struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static __devinitdata struct usb_device_id device_table[] = {
#ifndef CONFIG_USB_ET61X251
- {USB_DEVICE(0x102c, 0x6151), DVNM("Qcam Sangha CIF")},
+ {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
#endif
- {USB_DEVICE(0x102c, 0x6251), DVNM("Qcam xxxxxx VGA")},
+ {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
{}
};
@@ -942,7 +922,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 16e367cec76..3a051c925ff 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -32,6 +32,7 @@
#include <asm/page.h>
#include <linux/uaccess.h>
#include <linux/jiffies.h>
+#include <media/v4l2-ioctl.h>
#include "gspca.h"
@@ -42,8 +43,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("GSPCA USB Camera Driver");
MODULE_LICENSE("GPL");
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 2, 0)
static int video_nr = -1;
@@ -209,6 +209,8 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
&frame->v4l2_buf.timestamp);
frame->v4l2_buf.sequence = ++gspca_dev->sequence;
} else if (gspca_dev->last_packet_type == DISCARD_PACKET) {
+ if (packet_type == LAST_PACKET)
+ gspca_dev->last_packet_type = packet_type;
return frame;
}
@@ -399,7 +401,7 @@ static struct usb_host_endpoint *alt_isoc(struct usb_host_interface *alt,
* This routine may be called many times when the bandwidth is too small
* (the bandwidth is checked on urb submit).
*/
-struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev)
+static struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev)
{
struct usb_interface *intf;
struct usb_host_endpoint *ep;
@@ -832,7 +834,16 @@ static int vidioc_querycap(struct file *file, void *priv,
memset(cap, 0, sizeof *cap);
strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver);
- strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card);
+/* strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card); */
+ if (gspca_dev->dev->product != NULL) {
+ strncpy(cap->card, gspca_dev->dev->product,
+ sizeof cap->card);
+ } else {
+ snprintf(cap->card, sizeof cap->card,
+ "USB Camera (%04x:%04x)",
+ le16_to_cpu(gspca_dev->dev->descriptor.idVendor),
+ le16_to_cpu(gspca_dev->dev->descriptor.idProduct));
+ }
strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name,
sizeof cap->bus_info);
cap->version = DRIVER_VERSION_NUMBER;
@@ -1649,12 +1660,7 @@ static struct file_operations dev_fops = {
.poll = dev_poll,
};
-static struct video_device gspca_template = {
- .name = "gspca main driver",
- .type = VID_TYPE_CAPTURE,
- .fops = &dev_fops,
- .release = dev_release, /* mandatory */
- .minor = -1,
+static const struct v4l2_ioctl_ops dev_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_dqbuf = vidioc_dqbuf,
.vidioc_qbuf = vidioc_qbuf,
@@ -1683,6 +1689,14 @@ static struct video_device gspca_template = {
#endif
};
+static struct video_device gspca_template = {
+ .name = "gspca main driver",
+ .fops = &dev_fops,
+ .ioctl_ops = &dev_ioctl_ops,
+ .release = dev_release, /* mandatory */
+ .minor = -1,
+};
+
/*
* probe and create a new gspca device
*
@@ -1740,10 +1754,11 @@ int gspca_dev_probe(struct usb_interface *intf,
/* init video stuff */
memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
- gspca_dev->vdev.dev = &dev->dev;
+ gspca_dev->vdev.parent = &dev->dev;
memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops);
gspca_dev->vdev.fops = &gspca_dev->fops;
gspca_dev->fops.owner = module; /* module protection */
+ gspca_dev->present = 1;
ret = video_register_device(&gspca_dev->vdev,
VFL_TYPE_GRABBER,
video_nr);
@@ -1752,7 +1767,6 @@ int gspca_dev_probe(struct usb_interface *intf,
goto out;
}
- gspca_dev->present = 1;
usb_set_intfdata(intf, gspca_dev);
PDEBUG(D_PROBE, "probe ok");
return 0;
@@ -1885,7 +1899,10 @@ EXPORT_SYMBOL(gspca_auto_gain_n_exposure);
/* -- module insert / remove -- */
static int __init gspca_init(void)
{
- info("main v%s registered", version);
+ info("main v%d.%d.%d registered",
+ (DRIVER_VERSION_NUMBER >> 16) & 0xff,
+ (DRIVER_VERSION_NUMBER >> 8) & 0xff,
+ DRIVER_VERSION_NUMBER & 0xff);
return 0;
}
static void __exit gspca_exit(void)
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 88c2b02f380..21c4ee56a10 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -24,9 +24,6 @@
#include "gspca.h"
#include "jpeg.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -140,7 +137,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
@@ -424,9 +420,8 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x093a, 0x050f), DVNM("Mars-Semi Pc-Camera")},
+ {USB_DEVICE(0x093a, 0x050f)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -451,7 +446,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 08d99c3b78e..83139efc462 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -24,9 +24,6 @@
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("OV519 USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -1375,7 +1372,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = sif_mode;
cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
}
- cam->dev_name = (char *) id->driver_info;
sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
@@ -2129,21 +2125,20 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x041e, 0x4052), DVNM("Creative Live! VISTA IM")},
- {USB_DEVICE(0x041e, 0x405f), DVNM("Creative Live! VISTA VF0330")},
- {USB_DEVICE(0x041e, 0x4060), DVNM("Creative Live! VISTA VF0350")},
- {USB_DEVICE(0x041e, 0x4061), DVNM("Creative Live! VISTA VF0400")},
- {USB_DEVICE(0x041e, 0x4064), DVNM("Creative Live! VISTA VF0420")},
- {USB_DEVICE(0x041e, 0x4068), DVNM("Creative Live! VISTA VF0470")},
- {USB_DEVICE(0x045e, 0x028c), DVNM("Microsoft xbox cam")},
- {USB_DEVICE(0x054c, 0x0154), DVNM("Sonny toy4")},
- {USB_DEVICE(0x054c, 0x0155), DVNM("Sonny toy5")},
- {USB_DEVICE(0x05a9, 0x0519), DVNM("OmniVision")},
- {USB_DEVICE(0x05a9, 0x0530), DVNM("OmniVision")},
- {USB_DEVICE(0x05a9, 0x4519), DVNM("OmniVision")},
- {USB_DEVICE(0x05a9, 0x8519), DVNM("OmniVision")},
+ {USB_DEVICE(0x041e, 0x4052)},
+ {USB_DEVICE(0x041e, 0x405f)},
+ {USB_DEVICE(0x041e, 0x4060)},
+ {USB_DEVICE(0x041e, 0x4061)},
+ {USB_DEVICE(0x041e, 0x4064)},
+ {USB_DEVICE(0x041e, 0x4068)},
+ {USB_DEVICE(0x045e, 0x028c)},
+ {USB_DEVICE(0x054c, 0x0154)},
+ {USB_DEVICE(0x054c, 0x0155)},
+ {USB_DEVICE(0x05a9, 0x0519)},
+ {USB_DEVICE(0x05a9, 0x0530)},
+ {USB_DEVICE(0x05a9, 0x4519)},
+ {USB_DEVICE(0x05a9, 0x8519)},
{}
};
#undef DVNAME
@@ -2169,7 +2164,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index fa7abc41109..7ef18d57881 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -27,9 +27,6 @@
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>");
MODULE_DESCRIPTION("Pixart PAC207");
MODULE_LICENSE("GPL");
@@ -208,7 +205,7 @@ static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
}
-int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
+static int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
{
struct usb_device *udev = gspca_dev->dev;
int err;
@@ -223,8 +220,7 @@ int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
return err;
}
-
-int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
+static int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
{
struct usb_device *udev = gspca_dev->dev;
int res;
@@ -574,17 +570,16 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x041e, 0x4028), DVNM("Creative Webcam Vista Plus")},
- {USB_DEVICE(0x093a, 0x2460), DVNM("Q-Tec Webcam 100")},
- {USB_DEVICE(0x093a, 0x2463), DVNM("Philips spc200nc pac207")},
- {USB_DEVICE(0x093a, 0x2464), DVNM("Labtec Webcam 1200")},
- {USB_DEVICE(0x093a, 0x2468), DVNM("PAC207")},
- {USB_DEVICE(0x093a, 0x2470), DVNM("Genius GF112")},
- {USB_DEVICE(0x093a, 0x2471), DVNM("Genius VideoCam GE111")},
- {USB_DEVICE(0x093a, 0x2472), DVNM("Genius VideoCam GE110")},
- {USB_DEVICE(0x2001, 0xf115), DVNM("D-Link DSB-C120")},
+ {USB_DEVICE(0x041e, 0x4028)},
+ {USB_DEVICE(0x093a, 0x2460)},
+ {USB_DEVICE(0x093a, 0x2463)},
+ {USB_DEVICE(0x093a, 0x2464)},
+ {USB_DEVICE(0x093a, 0x2468)},
+ {USB_DEVICE(0x093a, 0x2470)},
+ {USB_DEVICE(0x093a, 0x2471)},
+ {USB_DEVICE(0x093a, 0x2472)},
+ {USB_DEVICE(0x2001, 0xf115)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -609,7 +604,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 5c052e31be4..ea3d7021f40 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -23,9 +23,6 @@
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
MODULE_DESCRIPTION("Pixart PAC7311");
MODULE_LICENSE("GPL");
@@ -266,7 +263,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x3e, 0x20);
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x05;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -713,16 +709,14 @@ static struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x093a, 0x2600), DVNM("Typhoon")},
- {USB_DEVICE(0x093a, 0x2601), DVNM("Philips SPC610NC")},
- {USB_DEVICE(0x093a, 0x2603), DVNM("PAC7312")},
- {USB_DEVICE(0x093a, 0x2608), DVNM("Trust WB-3300p")},
- {USB_DEVICE(0x093a, 0x260e), DVNM("Gigaware VGA PC Camera")},
- /* and also ', Trust WB-3350p, SIGMA cam 2350' */
- {USB_DEVICE(0x093a, 0x260f), DVNM("SnakeCam")},
- {USB_DEVICE(0x093a, 0x2621), DVNM("PAC731x")},
+ {USB_DEVICE(0x093a, 0x2600)},
+ {USB_DEVICE(0x093a, 0x2601)},
+ {USB_DEVICE(0x093a, 0x2603)},
+ {USB_DEVICE(0x093a, 0x2608)},
+ {USB_DEVICE(0x093a, 0x260e)},
+ {USB_DEVICE(0x093a, 0x260f)},
+ {USB_DEVICE(0x093a, 0x2621)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -747,7 +741,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index dbeebe8625c..e18748c5a14 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -24,9 +24,6 @@
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 8)
-static const char version[] = "2.1.8";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -44,25 +41,29 @@ struct sd {
unsigned char brightness;
unsigned char autogain;
unsigned char autogain_ignore_frames;
+ unsigned char frames_to_drop;
unsigned char freq; /* light freq filter setting */
- unsigned char saturation;
- unsigned char hue;
- unsigned char contrast;
unsigned char fr_h_sz; /* size of frame header */
char sensor; /* Type of image sensor chip */
#define SENSOR_HV7131R 0
#define SENSOR_OV6650 1
#define SENSOR_OV7630 2
-#define SENSOR_OV7630_3 3
-#define SENSOR_PAS106 4
-#define SENSOR_PAS202 5
-#define SENSOR_TAS5110 6
-#define SENSOR_TAS5130CXX 7
+#define SENSOR_PAS106 3
+#define SENSOR_PAS202 4
+#define SENSOR_TAS5110 5
+#define SENSOR_TAS5130CXX 6
char sensor_has_gain;
__u8 sensor_addr;
+ __u8 reg11;
};
+/* flags used in the device id table */
+#define F_GAIN 0x01 /* has gain */
+#define F_AUTO 0x02 /* has autogain */
+#define F_SIF 0x04 /* sif or vga */
+#define F_H18 0x08 /* long (18 b) or short (12 b) frame header */
+
#define COMP2 0x8f
#define COMP 0xc7 /* 0x87 //0x07 */
#define COMP1 0xc9 /* 0x89 //0x09 */
@@ -92,12 +93,6 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
static struct ctrl sd_ctrls[] = {
{
@@ -174,48 +169,6 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setfreq,
.get = sd_getfreq,
},
- {
- {
- .id = V4L2_CID_SATURATION,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Saturation",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
-#define SATURATION_DEF 127
- .default_value = SATURATION_DEF,
- },
- .set = sd_setsaturation,
- .get = sd_getsaturation,
- },
- {
- {
- .id = V4L2_CID_HUE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Hue",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
-#define HUE_DEF 127
- .default_value = HUE_DEF,
- },
- .set = sd_sethue,
- .get = sd_gethue,
- },
- {
- {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
-#define CONTRAST_DEF 127
- .default_value = CONTRAST_DEF,
- },
- .set = sd_setcontrast,
- .get = sd_getcontrast,
- },
};
static struct v4l2_pix_format vga_mode[] = {
@@ -248,8 +201,6 @@ static struct v4l2_pix_format sif_mode[] = {
.priv = 0},
};
-static const __u8 probe_ov7630[] = {0x08, 0x44};
-
static const __u8 initHv7131[] = {
0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
0x00, 0x00,
@@ -321,7 +272,7 @@ static const __u8 initOv7630_3[] = {
0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */
};
-static const __u8 ov7630_sensor_init_com[][8] = {
+static const __u8 ov7630_sensor_init[][8] = {
{0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
{0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
/* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
@@ -342,17 +293,6 @@ static const __u8 ov7630_sensor_init_com[][8] = {
{0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
{0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
};
-static const __u8 ov7630_sensor_init[][8] = {
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */
- {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10}, /* jfm */
- {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16},
- {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16},
- {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */
-};
-static const __u8 ov7630_sensor_init_3[][8] = {
- {0xa0, 0x21, 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x10},
- {0xa0, 0x21, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x10},
-};
static const __u8 initPas106[] = {
0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
@@ -542,7 +482,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
switch (sd->sensor) {
case SENSOR_OV6650:
- case SENSOR_OV7630_3:
case SENSOR_OV7630: {
__u8 i2cOV[] =
{0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
@@ -635,7 +574,7 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
case SENSOR_OV6650:
gain >>= 1;
/* fall thru */
- case SENSOR_OV7630_3: {
+ case SENSOR_OV7630: {
__u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
i2c[1] = sd->sensor_addr;
@@ -690,7 +629,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
break;
}
case SENSOR_OV6650:
- case SENSOR_OV7630_3: {
+ case SENSOR_OV7630: {
/* The ov6650 / ov7630 have 2 registers which both influence
exposure, register 11, whose low nibble sets the nr off fps
according to: fps = 30 / (low_nibble + 1)
@@ -705,16 +644,20 @@ static void setexposure(struct gspca_dev *gspca_dev)
The code maps our 0 - 510 ms exposure ctrl to these 2
registers, trying to keep fps as high as possible.
*/
- __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10};
- int reg10, reg11;
+ __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
+ int reg10, reg11, reg10_max;
+
/* ov6645 datasheet says reg10_max is 9a, but that uses
tline * 2 * reg10 as formula for calculating texpo, the
ov6650 probably uses the same formula as the 7730 which uses
tline * 4 * reg10, which explains why the reg10max we've
found experimentally for the ov6650 is exactly half that of
the ov6645. The ov7630 datasheet says the max is 0x41. */
- const int reg10_max = (sd->sensor == SENSOR_OV6650)
- ? 0x4d : 0x41;
+ if (sd->sensor == SENSOR_OV6650) {
+ reg10_max = 0x4d;
+ i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
+ } else
+ reg10_max = 0x41;
reg11 = (60 * sd->exposure + 999) / 1000;
if (reg11 < 1)
@@ -735,20 +678,23 @@ static void setexposure(struct gspca_dev *gspca_dev)
else if (reg10 > reg10_max)
reg10 = reg10_max;
+ /* In 640x480, if the reg11 has less than 3, the image is
+ unstable (not enough bandwidth). */
+ if (gspca_dev->width == 640 && reg11 < 3)
+ reg11 = 3;
+
/* Write reg 10 and reg11 low nibble */
i2c[1] = sd->sensor_addr;
i2c[3] = reg10;
i2c[4] |= reg11 - 1;
- if (sd->sensor == SENSOR_OV7630_3) {
- __u8 reg76 = reg10 & 0x03;
- __u8 i2c_reg76[] = {0xa0, 0x21, 0x76, 0x00,
- 0x00, 0x00, 0x00, 0x10};
- reg10 >>= 2;
- i2c_reg76[3] = reg76;
- if (i2c_w(gspca_dev, i2c_reg76) < 0)
- PDEBUG(D_ERR, "i2c error exposure");
- }
- if (i2c_w(gspca_dev, i2c) < 0)
+
+ /* If register 11 didn't change, don't change it */
+ if (sd->reg11 == reg11 )
+ i2c[0] = 0xa0;
+
+ if (i2c_w(gspca_dev, i2c) == 0)
+ sd->reg11 = reg11;
+ else
PDEBUG(D_ERR, "i2c error exposure");
break;
}
@@ -761,11 +707,11 @@ static void setfreq(struct gspca_dev *gspca_dev)
switch (sd->sensor) {
case SENSOR_OV6650:
- case SENSOR_OV7630_3: {
+ case SENSOR_OV7630: {
/* Framerate adjust register for artificial light 50 hz flicker
- compensation, identical to ov6630 0x2b register, see ov6630
- datasheet.
- 0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */
+ compensation, for the ov6650 this is identical to ov6630
+ 0x2b register, see ov6630 datasheet.
+ 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
__u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
switch (sd->freq) {
default:
@@ -786,69 +732,6 @@ static void setfreq(struct gspca_dev *gspca_dev)
}
}
-static void setsaturation(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->sensor) {
-/* case SENSOR_OV6650: */
- case SENSOR_OV7630_3:
- case SENSOR_OV7630: {
- __u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10};
- i2c[1] = sd->sensor_addr;
- i2c[3] = sd->saturation & 0xf0;
- if (i2c_w(gspca_dev, i2c) < 0)
- PDEBUG(D_ERR, "i2c error setsaturation");
- else
- PDEBUG(D_CONF, "saturation set to: %d",
- (int)sd->saturation);
- break;
- }
- }
-}
-
-static void sethue(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->sensor) {
-/* case SENSOR_OV6650: */
- case SENSOR_OV7630_3:
- case SENSOR_OV7630: {
- __u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10};
- i2c[1] = sd->sensor_addr;
- i2c[3] = 0x20 | (sd->hue >> 3);
- if (i2c_w(gspca_dev, i2c) < 0)
- PDEBUG(D_ERR, "i2c error setsaturation");
- else
- PDEBUG(D_CONF, "hue set to: %d", (int)sd->hue);
- break;
- }
- }
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->sensor) {
-/* case SENSOR_OV6650: */
- case SENSOR_OV7630_3:
- case SENSOR_OV7630: {
- __u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10};
- i2c[1] = sd->sensor_addr;
- i2c[3] = 0x20 | (sd->contrast >> 3);
- if (i2c_w(gspca_dev, i2c) < 0)
- PDEBUG(D_ERR, "i2c error setcontrast");
- else
- PDEBUG(D_CONF, "contrast set to: %d",
- (int)sd->contrast);
- break;
- }
- }
-}
-
-
static void do_autogain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -874,88 +757,32 @@ static int sd_config(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
- __u16 product;
int sif = 0;
/* nctrls depends upon the sensor, so we use a per cam copy */
memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc));
gspca_dev->sd_desc = &sd->sd_desc;
- sd->fr_h_sz = 12; /* default size of the frame header */
- sd->sd_desc.nctrls = 2; /* default nb of ctrls */
- sd->autogain = AUTOGAIN_DEF; /* default is autogain active */
-
- product = id->idProduct;
-/* switch (id->idVendor) { */
-/* case 0x0c45: * Sonix */
- switch (product) {
- case 0x6001: /* SN9C102 */
- case 0x6005: /* SN9C101 */
- case 0x6007: /* SN9C101 */
- sd->sensor = SENSOR_TAS5110;
- sd->sensor_has_gain = 1;
- sd->sd_desc.nctrls = 4;
- sd->sd_desc.dq_callback = do_autogain;
- sif = 1;
- break;
- case 0x6009: /* SN9C101 */
- case 0x600d: /* SN9C101 */
- case 0x6029: /* SN9C101 */
- sd->sensor = SENSOR_PAS106;
- sif = 1;
- break;
- case 0x6011: /* SN9C101 - SN9C101G */
- sd->sensor = SENSOR_OV6650;
- sd->sensor_has_gain = 1;
- sd->sensor_addr = 0x60;
- sd->sd_desc.nctrls = 5;
- sd->sd_desc.dq_callback = do_autogain;
- sif = 1;
- break;
- case 0x6019: /* SN9C101 */
- case 0x602c: /* SN9C102 */
- case 0x602e: /* SN9C102 */
- sd->sensor = SENSOR_OV7630;
- sd->sensor_addr = 0x21;
- break;
- case 0x60b0: /* SN9C103 */
- sd->sensor = SENSOR_OV7630_3;
- sd->sensor_addr = 0x21;
- sd->fr_h_sz = 18; /* size of frame header */
- sd->sensor_has_gain = 1;
- sd->sd_desc.nctrls = 8;
- sd->sd_desc.dq_callback = do_autogain;
- sd->autogain = 0;
- break;
- case 0x6024: /* SN9C102 */
- case 0x6025: /* SN9C102 */
- sd->sensor = SENSOR_TAS5130CXX;
- break;
- case 0x6028: /* SN9C102 */
- sd->sensor = SENSOR_PAS202;
- break;
- case 0x602d: /* SN9C102 */
- sd->sensor = SENSOR_HV7131R;
- break;
- case 0x60af: /* SN9C103 */
- sd->sensor = SENSOR_PAS202;
- sd->fr_h_sz = 18; /* size of frame header (?) */
- break;
- }
-/* break; */
-/* } */
+ /* copy the webcam info from the device id */
+ sd->sensor = (id->driver_info >> 24) & 0xff;
+ if (id->driver_info & (F_GAIN << 16))
+ sd->sensor_has_gain = 1;
+ if (id->driver_info & (F_AUTO << 16))
+ sd->sd_desc.dq_callback = do_autogain;
+ if (id->driver_info & (F_SIF << 16))
+ sif = 1;
+ if (id->driver_info & (F_H18 << 16))
+ sd->fr_h_sz = 18; /* size of frame header */
+ else
+ sd->fr_h_sz = 12;
+ sd->sd_desc.nctrls = (id->driver_info >> 8) & 0xff;
+ sd->sensor_addr = id->driver_info & 0xff;
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x01;
if (!sif) {
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
- if (sd->sensor == SENSOR_OV7630_3) {
- /* We only have 320x240 & 640x480 */
- cam->cam_mode++;
- cam->nmodes--;
- }
} else {
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
@@ -963,12 +790,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->brightness = BRIGHTNESS_DEF;
sd->gain = GAIN_DEF;
sd->exposure = EXPOSURE_DEF;
+ sd->autogain = AUTOGAIN_DEF;
sd->freq = FREQ_DEF;
- sd->contrast = CONTRAST_DEF;
- sd->saturation = SATURATION_DEF;
- sd->hue = HUE_DEF;
- if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */
- reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
+
return 0;
}
@@ -1002,9 +826,8 @@ static void pas106_i2cinit(struct gspca_dev *gspca_dev)
static void sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int mode, l;
+ int mode, l = 0x1f;
const __u8 *sn9c10x;
- __u8 reg01, reg17;
__u8 reg17_19[3];
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
@@ -1022,13 +845,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
reg17_19[2] = 0x20;
break;
case SENSOR_OV7630:
- sn9c10x = initOv7630;
- reg17_19[0] = 0x68;
- reg17_19[1] = (mode << 4) | COMP2;
- reg17_19[2] = MCK_INIT1;
- break;
- case SENSOR_OV7630_3:
- sn9c10x = initOv7630_3;
+ if (sd->fr_h_sz == 18) { /* SN9C103 */
+ sn9c10x = initOv7630_3;
+ l = sizeof initOv7630_3;
+ } else
+ sn9c10x = initOv7630;
reg17_19[0] = 0x68;
reg17_19[1] = (mode << 4) | COMP2;
reg17_19[2] = MCK_INIT1;
@@ -1059,30 +880,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
reg17_19[2] = mode ? 0x23 : 0x43;
break;
}
- switch (sd->sensor) {
- case SENSOR_OV7630:
- reg01 = 0x06;
- reg17 = 0x29;
- l = sizeof initOv7630;
- break;
- case SENSOR_OV7630_3:
- reg01 = 0x44;
- reg17 = 0x68;
- l = sizeof initOv7630_3;
- break;
- default:
- reg01 = sn9c10x[0];
- reg17 = sn9c10x[0x17 - 1];
- l = 0x1f;
- break;
- }
/* reg 0x01 bit 2 video transfert on */
- reg_w(gspca_dev, 0x01, &reg01, 1);
+ reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
/* reg 0x17 SensorClk enable inv Clk 0x60 */
- reg_w(gspca_dev, 0x17, &reg17, 1);
-/*fixme: for ov7630 102
- reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */
+ reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
/* Set the registers from the template */
reg_w_big(gspca_dev, 0x01, sn9c10x, l);
switch (sd->sensor) {
@@ -1095,17 +897,13 @@ static void sd_start(struct gspca_dev *gspca_dev)
sizeof ov6650_sensor_init);
break;
case SENSOR_OV7630:
- i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
- sizeof ov7630_sensor_init_com);
- msleep(200);
i2c_w_vector(gspca_dev, ov7630_sensor_init,
sizeof ov7630_sensor_init);
- break;
- case SENSOR_OV7630_3:
- i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
- sizeof ov7630_sensor_init_com);
- msleep(200);
- i2c_w(gspca_dev, ov7630_sensor_init_3[mode]);
+ if (sd->fr_h_sz == 18) { /* SN9C103 */
+ const __u8 i2c[] = { 0xa0, 0x21, 0x13, 0x80, 0x00,
+ 0x00, 0x00, 0x10 };
+ i2c_w(gspca_dev, i2c);
+ }
break;
case SENSOR_PAS106:
pas106_i2cinit(gspca_dev);
@@ -1145,14 +943,14 @@ static void sd_start(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
msleep(20);
+ sd->reg11 = -1;
+
setgain(gspca_dev);
setbrightness(gspca_dev);
setexposure(gspca_dev);
setfreq(gspca_dev);
- setsaturation(gspca_dev);
- sethue(gspca_dev);
- setcontrast(gspca_dev);
+ sd->frames_to_drop = 0;
sd->autogain_ignore_frames = 0;
atomic_set(&sd->avg_lum, -1);
}
@@ -1198,21 +996,31 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
&& data[3 + i] == 0xc4
&& data[4 + i] == 0xc4
&& data[5 + i] == 0x96) { /* start of frame */
- frame = gspca_frame_add(gspca_dev, LAST_PACKET,
- frame, data, 0);
+ int lum = -1;
+ int pkt_type = LAST_PACKET;
+
if (len - i < sd->fr_h_sz) {
- atomic_set(&sd->avg_lum, -1);
PDEBUG(D_STREAM, "packet too short to"
" get avg brightness");
} else if (sd->fr_h_sz == 12) {
- atomic_set(&sd->avg_lum,
- data[i + 8] +
- (data[i + 9] << 8));
+ lum = data[i + 8] + (data[i + 9] << 8);
} else {
- atomic_set(&sd->avg_lum,
- data[i + 9] +
- (data[i + 10] << 8));
+ lum = data[i + 9] +
+ (data[i + 10] << 8);
+ }
+ if (lum == 0) {
+ lum = -1;
+ sd->frames_to_drop = 2;
+ }
+ atomic_set(&sd->avg_lum, lum);
+
+ if (sd->frames_to_drop) {
+ sd->frames_to_drop--;
+ pkt_type = DISCARD_PACKET;
}
+
+ frame = gspca_frame_add(gspca_dev, pkt_type,
+ frame, data, 0);
data += i + sd->fr_h_sz;
len -= i + sd->fr_h_sz;
gspca_frame_add(gspca_dev, FIRST_PACKET,
@@ -1327,60 +1135,6 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
-static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->saturation = val;
- if (gspca_dev->streaming)
- setsaturation(gspca_dev);
- return 0;
-}
-
-static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->saturation;
- return 0;
-}
-
-static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->hue = val;
- if (gspca_dev->streaming)
- sethue(gspca_dev);
- return 0;
-}
-
-static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->hue;
- return 0;
-}
-
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->contrast = val;
- if (gspca_dev->streaming)
- setcontrast(gspca_dev);
- return 0;
-}
-
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->contrast;
- return 0;
-}
-
static int sd_querymenu(struct gspca_dev *gspca_dev,
struct v4l2_querymenu *menu)
{
@@ -1418,27 +1172,47 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
+#define SFCI(sensor, flags, nctrls, i2c_addr) \
+ .driver_info = (SENSOR_ ## sensor << 24) \
+ | ((flags) << 16) \
+ | ((nctrls) << 8) \
+ | (i2c_addr)
static __devinitdata struct usb_device_id device_table[] = {
#ifndef CONFIG_USB_SN9C102
- {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")},
- {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")},
- {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")},
- {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")},
- {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")},
+ {USB_DEVICE(0x0c45, 0x6001), /* SN9C102 */
+ SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
+ {USB_DEVICE(0x0c45, 0x6005), /* SN9C101 */
+ SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
+ {USB_DEVICE(0x0c45, 0x6007), /* SN9C101 */
+ SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
+ {USB_DEVICE(0x0c45, 0x6009), /* SN9C101 */
+ SFCI(PAS106, F_SIF, 2, 0)},
+ {USB_DEVICE(0x0c45, 0x600d), /* SN9C101 */
+ SFCI(PAS106, F_SIF, 2, 0)},
#endif
- {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")},
+ {USB_DEVICE(0x0c45, 0x6011), /* SN9C101 - SN9C101G */
+ SFCI(OV6650, F_GAIN|F_AUTO|F_SIF, 5, 0x60)},
#ifndef CONFIG_USB_SN9C102
- {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")},
- {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")},
- {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")},
- {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")},
- {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")},
- {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")},
- {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")},
- {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")},
- {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")},
- {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")},
+ {USB_DEVICE(0x0c45, 0x6019), /* SN9C101 */
+ SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
+ {USB_DEVICE(0x0c45, 0x6024), /* SN9C102 */
+ SFCI(TAS5130CXX, 0, 2, 0)},
+ {USB_DEVICE(0x0c45, 0x6025), /* SN9C102 */
+ SFCI(TAS5130CXX, 0, 2, 0)},
+ {USB_DEVICE(0x0c45, 0x6028), /* SN9C102 */
+ SFCI(PAS202, 0, 2, 0)},
+ {USB_DEVICE(0x0c45, 0x6029), /* SN9C101 */
+ SFCI(PAS106, F_SIF, 2, 0)},
+ {USB_DEVICE(0x0c45, 0x602c), /* SN9C102 */
+ SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
+ {USB_DEVICE(0x0c45, 0x602d), /* SN9C102 */
+ SFCI(HV7131R, 0, 2, 0)},
+ {USB_DEVICE(0x0c45, 0x602e), /* SN9C102 */
+ SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
+ {USB_DEVICE(0x0c45, 0x60af), /* SN9C103 */
+ SFCI(PAS202, F_H18, 2, 0)},
+ {USB_DEVICE(0x0c45, 0x60b0), /* SN9C103 */
+ SFCI(OV7630, F_GAIN|F_AUTO|F_H18, 5, 0x21)},
#endif
{}
};
@@ -1464,7 +1238,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 3e68b992695..33a3df1f691 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -24,9 +24,6 @@
#include "gspca.h"
#include "jpeg.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -361,6 +358,7 @@ static const __u8 mo4000_sensor_init[][8] = {
};
static const __u8 ov7660_sensor_init[][8] = {
{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
+/* (delay 20ms) */
{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
/* Outformat ?? rawRGB */
{0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
@@ -539,13 +537,31 @@ static void reg_r(struct gspca_dev *gspca_dev,
value, 0,
gspca_dev->usb_buf, len,
500);
+ PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
}
+static void reg_w1(struct gspca_dev *gspca_dev,
+ __u16 value,
+ __u8 data)
+{
+ PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
+ gspca_dev->usb_buf[0] = data;
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x08,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ value,
+ 0,
+ gspca_dev->usb_buf, 1,
+ 500);
+}
static void reg_w(struct gspca_dev *gspca_dev,
__u16 value,
const __u8 *buffer,
int len)
{
+ PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
+ value, buffer[0], buffer[1]);
if (len <= sizeof gspca_dev->usb_buf) {
memcpy(gspca_dev->usb_buf, buffer, len);
usb_control_msg(gspca_dev->dev,
@@ -571,31 +587,42 @@ static void reg_w(struct gspca_dev *gspca_dev,
}
}
-/* I2C write 2 bytes */
-static void i2c_w2(struct gspca_dev *gspca_dev,
- const __u8 *buffer)
+/* I2C write 1 byte */
+static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 mode[8];
- /* is i2c ready */
- mode[0] = 0x81 | (2 << 4);
- mode[1] = sd->i2c_base;
- mode[2] = buffer[0];
- mode[3] = buffer[1];
- mode[4] = 0;
- mode[5] = 0;
- mode[6] = 0;
- mode[7] = 0x10;
- reg_w(gspca_dev, 0x08, mode, 8);
+ PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
+ gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
+ gspca_dev->usb_buf[1] = sd->i2c_base;
+ gspca_dev->usb_buf[2] = reg;
+ gspca_dev->usb_buf[3] = val;
+ gspca_dev->usb_buf[4] = 0;
+ gspca_dev->usb_buf[5] = 0;
+ gspca_dev->usb_buf[6] = 0;
+ gspca_dev->usb_buf[7] = 0x10;
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x08,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ 0x08, /* value = i2c */
+ 0,
+ gspca_dev->usb_buf, 8,
+ 500);
}
/* I2C write 8 bytes */
static void i2c_w8(struct gspca_dev *gspca_dev,
const __u8 *buffer)
{
- reg_w(gspca_dev, 0x08, buffer, 8);
- msleep(1);
+ memcpy(gspca_dev->usb_buf, buffer, 8);
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x08,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ 0x08, 0, /* value, index */
+ gspca_dev->usb_buf, 8,
+ 500);
}
/* read 5 bytes in gspca_dev->usb_buf */
@@ -613,24 +640,21 @@ static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
mode[6] = 0;
mode[7] = 0x10;
i2c_w8(gspca_dev, mode);
+ msleep(2);
mode[0] = 0x81 | (5 << 4) | 0x02;
mode[2] = 0;
i2c_w8(gspca_dev, mode);
+ msleep(2);
reg_r(gspca_dev, 0x0a, 5);
}
static int probesensor(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 reg02;
- static const __u8 datasend[] = { 2, 0 };
- /* reg val1 val2 val3 val4 */
- i2c_w2(gspca_dev, datasend);
-/* should write 0xa1 0x11 0x02 0x00 0x00 0x00 0x00 the 0x10 is add by i2cw */
+ i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
msleep(10);
- reg02 = 0x66;
- reg_w(gspca_dev, 0x02, &reg02, 1); /* Gpio on */
+ reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
msleep(10);
i2c_r5(gspca_dev, 0); /* read sensor id */
if (gspca_dev->usb_buf[0] == 0x02
@@ -642,7 +666,7 @@ static int probesensor(struct gspca_dev *gspca_dev)
sd->sensor = SENSOR_HV7131R;
return SENSOR_HV7131R;
}
- PDEBUG(D_PROBE, "Find Sensor %d %d %d",
+ PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
gspca_dev->usb_buf[2]);
PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
@@ -653,8 +677,6 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
const __u8 *sn9c1xx)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 data;
- __u8 regF1;
const __u8 *reg9a;
static const __u8 reg9a_def[] =
{0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
@@ -663,15 +685,13 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
static const __u8 reg9a_sn9c325[] =
{0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
-
- regF1 = 0x00;
- reg_w(gspca_dev, 0xf1, &regF1, 1);
- reg_w(gspca_dev, 0x01, &sn9c1xx[0], 1); /*fixme:jfm was [1] en v1*/
+ reg_w1(gspca_dev, 0xf1, 0x00);
+ reg_w1(gspca_dev, 0x01, sn9c1xx[0]); /*fixme:jfm was [1] en v1*/
/* configure gpio */
reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
- reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm was 3 */
+ reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
switch (sd->bridge) {
case BRIDGE_SN9C325:
reg9a = reg9a_sn9c325;
@@ -685,35 +705,25 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
}
reg_w(gspca_dev, 0x9a, reg9a, 6);
- data = 0x60; /*fixme:jfm 60 00 00 (3) */
- reg_w(gspca_dev, 0xd4, &data, 1);
+ reg_w1(gspca_dev, 0xd4, 0x60); /*fixme:jfm 60 00 00 (3) ? */
reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
switch (sd->bridge) {
case BRIDGE_SN9C120: /* from win trace */
- data = 0x61;
- reg_w(gspca_dev, 0x01, &data, 1);
- data = 0x20;
- reg_w(gspca_dev, 0x17, &data, 1);
- data = 0x60;
- reg_w(gspca_dev, 0x01, &data, 1);
+ reg_w1(gspca_dev, 0x01, 0x61);
+ reg_w1(gspca_dev, 0x17, 0x20);
+ reg_w1(gspca_dev, 0x01, 0x60);
break;
case BRIDGE_SN9C325:
- data = 0x43;
- reg_w(gspca_dev, 0x01, &data, 1);
- data = 0xae;
- reg_w(gspca_dev, 0x17, &data, 1);
- data = 0x42;
- reg_w(gspca_dev, 0x01, &data, 1);
+ reg_w1(gspca_dev, 0x01, 0x43);
+ reg_w1(gspca_dev, 0x17, 0xae);
+ reg_w1(gspca_dev, 0x01, 0x42);
break;
default:
- data = 0x43;
- reg_w(gspca_dev, 0x01, &data, 1);
- data = 0x61;
- reg_w(gspca_dev, 0x17, &data, 1);
- data = 0x42;
- reg_w(gspca_dev, 0x01, &data, 1);
+ reg_w1(gspca_dev, 0x01, 0x43);
+ reg_w1(gspca_dev, 0x17, 0x61);
+ reg_w1(gspca_dev, 0x01, 0x42);
}
if (sd->sensor == SENSOR_HV7131R) {
@@ -770,6 +780,9 @@ static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
{
int i = 0;
+ i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
+ i++;
+ msleep(20);
while (ov7660_sensor_init[i][0]) {
i2c_w8(gspca_dev, ov7660_sensor_init[i]);
i++;
@@ -782,194 +795,16 @@ static int sd_config(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
- __u16 vendor;
- __u16 product;
-
- vendor = id->idVendor;
- product = id->idProduct;
- sd->sensor = -1;
- switch (vendor) {
- case 0x0458: /* Genius */
-/* switch (product) {
- case 0x7025: */
- sd->bridge = BRIDGE_SN9C120;
- sd->sensor = SENSOR_MI0360;
- sd->i2c_base = 0x5d;
-/* break;
- } */
- break;
- case 0x045e:
-/* switch (product) {
- case 0x00f5:
- case 0x00f7: */
- sd->bridge = BRIDGE_SN9C105;
- sd->sensor = SENSOR_OV7660;
- sd->i2c_base = 0x21;
-/* break;
- } */
- break;
- case 0x0471: /* Philips */
-/* switch (product) {
- case 0x0327:
- case 0x0328:
- case 0x0330: */
- sd->bridge = BRIDGE_SN9C105;
- sd->sensor = SENSOR_MI0360;
- sd->i2c_base = 0x5d;
-/* break;
- } */
- break;
- case 0x0c45: /* Sonix */
- switch (product) {
- case 0x6040:
- sd->bridge = BRIDGE_SN9C102P;
-/* sd->sensor = SENSOR_MI0360; * from BW600.inf */
-/*fixme: MI0360 base=5d ? */
- sd->sensor = SENSOR_HV7131R; /* gspcav1 value */
- sd->i2c_base = 0x11;
- break;
-/* case 0x607a: * from BW600.inf
- sd->bridge = BRIDGE_SN9C102P;
- sd->sensor = SENSOR_OV7648;
- sd->i2c_base = 0x??;
- break; */
- case 0x607c:
- sd->bridge = BRIDGE_SN9C102P;
- sd->sensor = SENSOR_HV7131R;
- sd->i2c_base = 0x11;
- break;
-/* case 0x607e: * from BW600.inf
- sd->bridge = BRIDGE_SN9C102P;
- sd->sensor = SENSOR_OV7630;
- sd->i2c_base = 0x??;
- break; */
- case 0x60c0:
- sd->bridge = BRIDGE_SN9C105;
- sd->sensor = SENSOR_MI0360;
- sd->i2c_base = 0x5d;
- break;
-/* case 0x60c8: * from BW600.inf
- sd->bridge = BRIDGE_SN9C105;
- sd->sensor = SENSOR_OM6801;
- sd->i2c_base = 0x??;
- break; */
-/* case 0x60cc: * from BW600.inf
- sd->bridge = BRIDGE_SN9C105;
- sd->sensor = SENSOR_HV7131GP;
- sd->i2c_base = 0x??;
- break; */
- case 0x60ec:
- sd->bridge = BRIDGE_SN9C105;
- sd->sensor = SENSOR_MO4000;
- sd->i2c_base = 0x21;
- break;
-/* case 0x60ef: * from BW600.inf
- sd->bridge = BRIDGE_SN9C105;
- sd->sensor = SENSOR_ICM105C;
- sd->i2c_base = 0x??;
- break; */
-/* case 0x60fa: * from BW600.inf
- sd->bridge = BRIDGE_SN9C105;
- sd->sensor = SENSOR_OV7648;
- sd->i2c_base = 0x??;
- break; */
- case 0x60fb:
- sd->bridge = BRIDGE_SN9C105;
- sd->sensor = SENSOR_OV7660;
- sd->i2c_base = 0x21;
- break;
- case 0x60fc:
- sd->bridge = BRIDGE_SN9C105;
- sd->sensor = SENSOR_HV7131R;
- sd->i2c_base = 0x11;
- break;
-/* case 0x60fe: * from BW600.inf
- sd->bridge = BRIDGE_SN9C105;
- sd->sensor = SENSOR_OV7630;
- sd->i2c_base = 0x??;
- break; */
-/* case 0x6108: * from BW600.inf
- sd->bridge = BRIDGE_SN9C120;
- sd->sensor = SENSOR_OM6801;
- sd->i2c_base = 0x??;
- break; */
-/* case 0x6122: * from BW600.inf
- sd->bridge = BRIDGE_SN9C110;
- sd->sensor = SENSOR_ICM105C;
- sd->i2c_base = 0x??;
- break; */
- case 0x612a:
-/* sd->bridge = BRIDGE_SN9C110; * in BW600.inf */
- sd->bridge = BRIDGE_SN9C325;
- sd->sensor = SENSOR_OV7648;
- sd->i2c_base = 0x21;
-/*fixme: sensor_init has base = 00 et 6e!*/
- break;
-/* case 0x6123: * from BW600.inf
- sd->bridge = BRIDGE_SN9C110;
- sd->sensor = SENSOR_SanyoCCD;
- sd->i2c_base = 0x??;
- break; */
- case 0x612c:
- sd->bridge = BRIDGE_SN9C110;
- sd->sensor = SENSOR_MO4000;
- sd->i2c_base = 0x21;
- break;
-/* case 0x612e: * from BW600.inf
- sd->bridge = BRIDGE_SN9C110;
- sd->sensor = SENSOR_OV7630;
- sd->i2c_base = 0x??;
- break; */
-/* case 0x612f: * from BW600.inf
- sd->bridge = BRIDGE_SN9C110;
- sd->sensor = SENSOR_ICM105C;
- sd->i2c_base = 0x??;
- break; */
- case 0x6130:
- sd->bridge = BRIDGE_SN9C120;
- sd->sensor = SENSOR_MI0360;
- sd->i2c_base = 0x5d;
- break;
- case 0x6138:
- sd->bridge = BRIDGE_SN9C120;
- sd->sensor = SENSOR_MO4000;
- sd->i2c_base = 0x21;
- break;
-/* case 0x613a: * from BW600.inf
- sd->bridge = BRIDGE_SN9C120;
- sd->sensor = SENSOR_OV7648;
- sd->i2c_base = 0x??;
- break; */
- case 0x613b:
- sd->bridge = BRIDGE_SN9C120;
- sd->sensor = SENSOR_OV7660;
- sd->i2c_base = 0x21;
- break;
- case 0x613c:
- sd->bridge = BRIDGE_SN9C120;
- sd->sensor = SENSOR_HV7131R;
- sd->i2c_base = 0x11;
- break;
-/* case 0x613e: * from BW600.inf
- sd->bridge = BRIDGE_SN9C120;
- sd->sensor = SENSOR_OV7630;
- sd->i2c_base = 0x??;
- break; */
- }
- break;
- }
- if (sd->sensor < 0) {
- PDEBUG(D_ERR, "Invalid vendor/product %04x:%04x",
- vendor, product);
- return -EINVAL;
- }
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
+ sd->bridge = id->driver_info >> 16;
+ sd->sensor = id->driver_info >> 8;
+ sd->i2c_base = id->driver_info;
+
sd->qindex = 4; /* set the quantization table */
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
@@ -983,34 +818,26 @@ static int sd_open(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
/* const __u8 *sn9c1xx; */
- __u8 regF1;
__u8 regGpio[] = { 0x29, 0x74 };
+ __u8 regF1;
/* setup a selector by bridge */
- regF1 = 0x01;
- reg_w(gspca_dev, 0xf1, &regF1, 1);
+ reg_w1(gspca_dev, 0xf1, 0x01);
reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */
- regF1 = gspca_dev->usb_buf[0];
- reg_w(gspca_dev, 0xf1, &regF1, 1);
+ reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
reg_r(gspca_dev, 0x00, 1);
regF1 = gspca_dev->usb_buf[0];
switch (sd->bridge) {
case BRIDGE_SN9C102P:
if (regF1 != 0x11)
return -ENODEV;
- reg_w(gspca_dev, 0x02, &regGpio[1], 1);
+ reg_w1(gspca_dev, 0x02, regGpio[1]);
break;
case BRIDGE_SN9C105:
if (regF1 != 0x11)
return -ENODEV;
reg_w(gspca_dev, 0x02, regGpio, 2);
break;
- case BRIDGE_SN9C110:
- if (regF1 != 0x12)
- return -ENODEV;
- regGpio[1] = 0x62;
- reg_w(gspca_dev, 0x02, &regGpio[1], 1);
- break;
case BRIDGE_SN9C120:
if (regF1 != 0x12)
return -ENODEV;
@@ -1018,16 +845,15 @@ static int sd_open(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x02, regGpio, 2);
break;
default:
+/* case BRIDGE_SN9C110: */
/* case BRIDGE_SN9C325: */
if (regF1 != 0x12)
return -ENODEV;
- regGpio[1] = 0x62;
- reg_w(gspca_dev, 0x02, &regGpio[1], 1);
+ reg_w1(gspca_dev, 0x02, 0x62);
break;
}
- regF1 = 0x01;
- reg_w(gspca_dev, 0xf1, &regF1, 1);
+ reg_w1(gspca_dev, 0xf1, 0x01);
return 0;
}
@@ -1123,7 +949,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
}
k2 = sd->brightness >> 10;
- reg_w(gspca_dev, 0x96, &k2, 1);
+ reg_w1(gspca_dev, 0x96, k2);
}
static void setcontrast(struct gspca_dev *gspca_dev)
@@ -1152,7 +978,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
data = (colour + 32) & 0x7f; /* blue */
else
data = (-colour + 32) & 0x7f; /* red */
- reg_w(gspca_dev, 0x05, &data, 1);
+ reg_w1(gspca_dev, 0x05, data);
}
/* -- start the camera -- */
@@ -1165,7 +991,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
__u8 reg17;
const __u8 *sn9c1xx;
int mode;
- static const __u8 DC29[] = { 0x6a, 0x50, 0x00, 0x00, 0x50, 0x3c };
static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
static const __u8 CA_sn9c120[] =
@@ -1179,21 +1004,20 @@ static void sd_start(struct gspca_dev *gspca_dev)
/*fixme:jfm this sequence should appear at end of sd_start */
/* with
- data = 0x44;
- reg_w(gspca_dev, 0x01, &data, 1); */
- reg_w(gspca_dev, 0x15, &sn9c1xx[0x15], 1);
- reg_w(gspca_dev, 0x16, &sn9c1xx[0x16], 1);
- reg_w(gspca_dev, 0x12, &sn9c1xx[0x12], 1);
- reg_w(gspca_dev, 0x13, &sn9c1xx[0x13], 1);
- reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1);
- reg_w(gspca_dev, 0xd2, &DC29[0], 1);
- reg_w(gspca_dev, 0xd3, &DC29[1], 1);
- reg_w(gspca_dev, 0xc6, &DC29[2], 1);
- reg_w(gspca_dev, 0xc7, &DC29[3], 1);
- reg_w(gspca_dev, 0xc8, &DC29[4], 1);
- reg_w(gspca_dev, 0xc9, &DC29[5], 1);
+ reg_w1(gspca_dev, 0x01, 0x44); */
+ reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
+ reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
+ reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
+ reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
+ reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
+ reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
+ reg_w1(gspca_dev, 0xd3, 0x50);
+ reg_w1(gspca_dev, 0xc6, 0x00);
+ reg_w1(gspca_dev, 0xc7, 0x00);
+ reg_w1(gspca_dev, 0xc8, 0x50);
+ reg_w1(gspca_dev, 0xc9, 0x3c);
/*fixme:jfm end of ending sequence */
- reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1);
+ reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
switch (sd->bridge) {
case BRIDGE_SN9C325:
data = 0xae;
@@ -1205,11 +1029,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
data = 0x60;
break;
}
- reg_w(gspca_dev, 0x17, &data, 1);
- reg_w(gspca_dev, 0x05, &sn9c1xx[5], 1);
- reg_w(gspca_dev, 0x07, &sn9c1xx[7], 1);
- reg_w(gspca_dev, 0x06, &sn9c1xx[6], 1);
- reg_w(gspca_dev, 0x14, &sn9c1xx[0x14], 1);
+ reg_w1(gspca_dev, 0x17, data);
+ reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
+ reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
+ reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
+ reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
switch (sd->bridge) {
case BRIDGE_SN9C325:
reg_w(gspca_dev, 0x20, regsn20_sn9c325,
@@ -1217,10 +1041,8 @@ static void sd_start(struct gspca_dev *gspca_dev)
for (i = 0; i < 8; i++)
reg_w(gspca_dev, 0x84, reg84_sn9c325,
sizeof reg84_sn9c325);
- data = 0x0a;
- reg_w(gspca_dev, 0x9a, &data, 1);
- data = 0x60;
- reg_w(gspca_dev, 0x99, &data, 1);
+ reg_w1(gspca_dev, 0x9a, 0x0a);
+ reg_w1(gspca_dev, 0x99, 0x60);
break;
case BRIDGE_SN9C120:
reg_w(gspca_dev, 0x20, regsn20_sn9c120,
@@ -1233,39 +1055,30 @@ static void sd_start(struct gspca_dev *gspca_dev)
sizeof reg84_sn9c120_2);
reg_w(gspca_dev, 0x84, reg84_sn9c120_3,
sizeof reg84_sn9c120_3);
- data = 0x05;
- reg_w(gspca_dev, 0x9a, &data, 1);
- data = 0x5b;
- reg_w(gspca_dev, 0x99, &data, 1);
+ reg_w1(gspca_dev, 0x9a, 0x05);
+ reg_w1(gspca_dev, 0x99, 0x5b);
break;
default:
reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
for (i = 0; i < 8; i++)
reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
- data = 0x08;
- reg_w(gspca_dev, 0x9a, &data, 1);
- data = 0x59;
- reg_w(gspca_dev, 0x99, &data, 1);
+ reg_w1(gspca_dev, 0x9a, 0x08);
+ reg_w1(gspca_dev, 0x99, 0x59);
break;
}
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
- reg1 = 0x02;
+ if (mode)
+ reg1 = 0x46; /* 320 clk 48Mhz */
+ else
+ reg1 = 0x06; /* 640 clk 24Mz */
reg17 = 0x61;
switch (sd->sensor) {
case SENSOR_HV7131R:
hv7131R_InitSensor(gspca_dev);
- if (mode)
- reg1 = 0x46; /* 320 clk 48Mhz */
- else
- reg1 = 0x06; /* 640 clk 24Mz */
break;
case SENSOR_MI0360:
mi0360_InitSensor(gspca_dev);
- if (mode)
- reg1 = 0x46; /* 320 clk 48Mhz */
- else
- reg1 = 0x06; /* 640 clk 24Mz */
break;
case SENSOR_MO4000:
mo4000_InitSensor(gspca_dev);
@@ -1274,13 +1087,13 @@ static void sd_start(struct gspca_dev *gspca_dev)
reg1 = 0x06; /* clk 24Mz */
} else {
reg17 = 0x22; /* 640 MCKSIZE */
- reg1 = 0x06; /* 640 clk 24Mz */
+/* reg1 = 0x06; * 640 clk 24Mz (done) */
}
break;
case SENSOR_OV7648:
+ ov7648_InitSensor(gspca_dev);
reg17 = 0xa2;
reg1 = 0x44;
- ov7648_InitSensor(gspca_dev);
/* if (mode)
; * 320x2...
else
@@ -1292,7 +1105,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
if (mode) {
/* reg17 = 0x21; * 320 */
/* reg1 = 0x44; */
- reg1 = 0x46;
+/* reg1 = 0x46; (done) */
} else {
reg17 = 0xa2; /* 640 */
reg1 = 0x40;
@@ -1321,16 +1134,16 @@ static void sd_start(struct gspca_dev *gspca_dev)
/* here change size mode 0 -> VGA; 1 -> CIF */
data = 0x40 | sn9c1xx[0x18] | (mode << 4);
- reg_w(gspca_dev, 0x18, &data, 1);
+ reg_w1(gspca_dev, 0x18, data);
reg_w(gspca_dev, 0x100, qtable4, 0x40);
reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
data = sn9c1xx[0x18] | (mode << 4);
- reg_w(gspca_dev, 0x18, &data, 1);
+ reg_w1(gspca_dev, 0x18, data);
- reg_w(gspca_dev, 0x17, &reg17, 1);
- reg_w(gspca_dev, 0x01, &reg1, 1);
+ reg_w1(gspca_dev, 0x17, reg17);
+ reg_w1(gspca_dev, 0x01, reg1);
setbrightness(gspca_dev);
setcontrast(gspca_dev);
}
@@ -1342,7 +1155,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
{ 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
static const __u8 stopmi0360[] =
{ 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
- __u8 regF1;
__u8 data;
const __u8 *sn9c1xx;
@@ -1366,12 +1178,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
break;
}
sn9c1xx = sn_tb[(int) sd->sensor];
- reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1);
- reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 1);
- reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1);
- reg_w(gspca_dev, 0x01, &data, 1);
- regF1 = 0x01;
- reg_w(gspca_dev, 0xf1, &regF1, 1);
+ reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
+ reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
+ reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
+ reg_w1(gspca_dev, 0x01, data);
+ reg_w1(gspca_dev, 0xf1, 0x01);
}
static void sd_stop0(struct gspca_dev *gspca_dev)
@@ -1610,30 +1421,53 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
+#define BSI(bridge, sensor, i2c_addr) \
+ .driver_info = (BRIDGE_ ## bridge << 16) \
+ | (SENSOR_ ## sensor << 8) \
+ | (i2c_addr)
static const __devinitdata struct usb_device_id device_table[] = {
#ifndef CONFIG_USB_SN9C102
- {USB_DEVICE(0x0458, 0x7025), DVNM("Genius Eye 311Q")},
- {USB_DEVICE(0x045e, 0x00f5), DVNM("MicroSoft VX3000")},
- {USB_DEVICE(0x045e, 0x00f7), DVNM("MicroSoft VX1000")},
- {USB_DEVICE(0x0471, 0x0327), DVNM("Philips SPC 600 NC")},
- {USB_DEVICE(0x0471, 0x0328), DVNM("Philips SPC 700 NC")},
+ {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
+ {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
+ {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
+ {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
+ {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
#endif
- {USB_DEVICE(0x0471, 0x0330), DVNM("Philips SPC 710NC")},
- {USB_DEVICE(0x0c45, 0x6040), DVNM("Speed NVC 350K")},
- {USB_DEVICE(0x0c45, 0x607c), DVNM("Sonix sn9c102p Hv7131R")},
- {USB_DEVICE(0x0c45, 0x60c0), DVNM("Sangha Sn535")},
- {USB_DEVICE(0x0c45, 0x60ec), DVNM("SN9C105+MO4000")},
- {USB_DEVICE(0x0c45, 0x60fb), DVNM("Surfer NoName")},
- {USB_DEVICE(0x0c45, 0x60fc), DVNM("LG-LIC300")},
- {USB_DEVICE(0x0c45, 0x612a), DVNM("Avant Camera")},
- {USB_DEVICE(0x0c45, 0x612c), DVNM("Typhoon Rasy Cam 1.3MPix")},
+ {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
+ {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
+/* bw600.inf:
+ {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
+/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
+/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
+ {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
+/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
+ {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
+/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
+/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
+ {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
+/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
+/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
+ {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
+ {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
+/* {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x??)}, */
+/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
+/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
+/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
+ {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C325, OV7648, 0x21)},
+/* bw600.inf:
+ {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, */
+ {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
+/* {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x??)}, */
+/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
#ifndef CONFIG_USB_SN9C102
- {USB_DEVICE(0x0c45, 0x6130), DVNM("Sonix Pccam")},
- {USB_DEVICE(0x0c45, 0x6138), DVNM("Sn9c120 Mo4000")},
- {USB_DEVICE(0x0c45, 0x613b), DVNM("Surfer SN-206")},
- {USB_DEVICE(0x0c45, 0x613c), DVNM("Sonix Pccam168")},
+ {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
+ {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
+/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
+ {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
+ {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
+/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
#endif
+ {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -1658,7 +1492,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- info("v%s registered", version);
+ info("registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 15620611879..17fe2c2a440 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -24,9 +24,6 @@
#include "gspca.h"
#include "jpeg.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -630,109 +627,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
- __u16 vendor;
- __u16 product;
-
- vendor = id->idVendor;
- product = id->idProduct;
- switch (vendor) {
- case 0x040a: /* Kodak cameras */
-/* switch (product) { */
-/* case 0x0300: */
- sd->subtype = KodakEZ200;
-/* break; */
-/* } */
- break;
- case 0x041e: /* Creative cameras */
-/* switch (product) { */
-/* case 0x400a: */
- sd->subtype = CreativePCCam300;
-/* break; */
-/* } */
- break;
- case 0x046d: /* Logitech Labtec */
- switch (product) {
- case 0x0890:
- sd->subtype = LogitechTraveler;
- break;
- case 0x0900:
- sd->subtype = LogitechClickSmart310;
- break;
- case 0x0901:
- sd->subtype = LogitechClickSmart510;
- break;
- }
- break;
- case 0x04a5: /* Benq */
-/* switch (product) { */
-/* case 0x300c: */
- sd->subtype = BenqDC1016;
-/* break; */
-/* } */
- break;
- case 0x04fc: /* SunPlus */
-/* switch (product) { */
-/* case 0x7333: */
- sd->subtype = PalmPixDC85;
-/* break; */
-/* } */
- break;
- case 0x055f: /* Mustek cameras */
- switch (product) {
- case 0xc200:
- sd->subtype = MustekGsmart300;
- break;
- case 0xc220:
- sd->subtype = Gsmartmini;
- break;
- }
- break;
- case 0x06bd: /* Agfa Cl20 */
-/* switch (product) { */
-/* case 0x0404: */
- sd->subtype = AgfaCl20;
-/* break; */
-/* } */
- break;
- case 0x06be: /* Optimedia */
-/* switch (product) { */
-/* case 0x0800: */
- sd->subtype = Optimedia;
-/* break; */
-/* } */
- break;
- case 0x084d: /* D-Link / Minton */
-/* switch (product) { */
-/* case 0x0003: * DSC-350 / S-Cam F5 */
- sd->subtype = DLinkDSC350;
-/* break; */
-/* } */
- break;
- case 0x08ca: /* Aiptek */
-/* switch (product) { */
-/* case 0x0103: */
- sd->subtype = AiptekPocketDV;
-/* break; */
-/* } */
- break;
- case 0x2899: /* ToptroIndustrial */
-/* switch (product) { */
-/* case 0x012c: */
- sd->subtype = ToptroIndus;
-/* break; */
-/* } */
- break;
- case 0x8086: /* Intel */
-/* switch (product) { */
-/* case 0x0630: * Pocket PC Camera */
- sd->subtype = IntelPocketPCCamera;
-/* break; */
-/* } */
- break;
- }
+
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x01;
+ sd->subtype = id->driver_info;
if (sd->subtype != LogitechClickSmart310) {
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
@@ -1162,23 +1060,22 @@ static struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")},
- {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")},
- {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")},
- {USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")},
- {USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")},
- {USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")},
- {USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")},
- {USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")},
- {USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")},
- {USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")},
- {USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")},
- {USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")},
- {USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")},
- {USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")},
- {USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")},
+ {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
+ {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
+ {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
+ {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
+ {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
+ {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
+ {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
+ {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
+ {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
+ {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
+ {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
+ {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
+ {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
+ {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
+ {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -1203,7 +1100,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index 50e929de020..51a3c3429ef 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -23,9 +23,6 @@
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SPCA501 USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -1923,63 +1920,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
- __u16 vendor;
- __u16 product;
-
- vendor = id->idVendor;
- product = id->idProduct;
- switch (vendor) {
- case 0x0000: /* Unknow Camera */
-/* switch (product) { */
-/* case 0x0000: */
- sd->subtype = MystFromOriUnknownCamera;
-/* break; */
-/* } */
- break;
- case 0x040a: /* Kodak cameras */
-/* switch (product) { */
-/* case 0x0002: */
- sd->subtype = KodakDVC325;
-/* break; */
-/* } */
- break;
- case 0x0497: /* Smile International */
-/* switch (product) { */
-/* case 0xc001: */
- sd->subtype = SmileIntlCamera;
-/* break; */
-/* } */
- break;
- case 0x0506: /* 3COM cameras */
-/* switch (product) { */
-/* case 0x00df: */
- sd->subtype = ThreeComHomeConnectLite;
-/* break; */
-/* } */
- break;
- case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */
- switch (product) {
- case 0x0401:
- sd->subtype = IntelCreateAndShare;
- break;
- case 0x0402:
- sd->subtype = ViewQuestM318B;
- break;
- }
- break;
- case 0x1776: /* Arowana */
-/* switch (product) { */
-/* case 0x501c: */
- sd->subtype = Arowana300KCMOSCamera;
-/* break; */
-/* } */
- break;
- }
+
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ sd->subtype = id->driver_info;
sd->brightness = sd_ctrls[MY_BRIGHTNESS].qctrl.default_value;
sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value;
sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value;
@@ -2183,15 +2129,14 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x040a, 0x0002), DVNM("Kodak DVC-325")},
- {USB_DEVICE(0x0497, 0xc001), DVNM("Smile International")},
- {USB_DEVICE(0x0506, 0x00df), DVNM("3Com HomeConnect Lite")},
- {USB_DEVICE(0x0733, 0x0401), DVNM("Intel Create and Share")},
- {USB_DEVICE(0x0733, 0x0402), DVNM("ViewQuest M318B")},
- {USB_DEVICE(0x1776, 0x501c), DVNM("Arowana 300K CMOS Camera")},
- {USB_DEVICE(0x0000, 0x0000), DVNM("MystFromOri Unknow Camera")},
+ {USB_DEVICE(0x040a, 0x0002), .driver_info = KodakDVC325},
+ {USB_DEVICE(0x0497, 0xc001), .driver_info = SmileIntlCamera},
+ {USB_DEVICE(0x0506, 0x00df), .driver_info = ThreeComHomeConnectLite},
+ {USB_DEVICE(0x0733, 0x0401), .driver_info = IntelCreateAndShare},
+ {USB_DEVICE(0x0733, 0x0402), .driver_info = ViewQuestM318B},
+ {USB_DEVICE(0x1776, 0x501c), .driver_info = Arowana300KCMOSCamera},
+ {USB_DEVICE(0x0000, 0x0000), .driver_info = MystFromOriUnknownCamera},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -2216,7 +2161,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index ddea6e140aa..3c2be80cbd6 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -23,9 +23,6 @@
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -34,10 +31,6 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- int buflen;
- unsigned char tmpbuf[640 * 480 * 3 / 2]; /* YYUV per line */
- unsigned char tmpbuf2[640 * 480 * 2]; /* YUYV */
-
unsigned char brightness;
char subtype;
@@ -67,29 +60,29 @@ static struct ctrl sd_ctrls[] = {
};
static struct v4l2_pix_format vga_mode[] = {
- {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 160 * 2,
- .sizeimage = 160 * 120 * 2,
+ {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+ .bytesperline = 160 * 3,
+ .sizeimage = 160 * 120 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 5},
- {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 176 * 2,
- .sizeimage = 176 * 144 * 2,
+ {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+ .bytesperline = 176 * 3,
+ .sizeimage = 176 * 144 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 4},
- {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 320 * 2,
- .sizeimage = 320 * 240 * 2,
+ {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+ .bytesperline = 320 * 3,
+ .sizeimage = 320 * 240 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 2},
- {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 352 * 2,
- .sizeimage = 352 * 288 * 2,
+ {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+ .bytesperline = 352 * 3,
+ .sizeimage = 352 * 288 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 1},
- {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 640 * 2,
- .sizeimage = 640 * 480 * 2,
+ {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+ .bytesperline = 640 * 3,
+ .sizeimage = 640 * 480 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 0},
};
@@ -641,33 +634,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
- __u16 vendor;
- __u16 product;
-
- vendor = id->idVendor;
- product = id->idProduct;
- switch (vendor) {
- case 0x041e: /* Creative cameras */
-/* switch (product) { */
-/* case 0x401d: * here505b */
- sd->subtype = Nxultra;
-/* break; */
-/* } */
- break;
- case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */
-/* switch (product) { */
-/* case 0x0430: */
-/* fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */
- sd->subtype = IntelPCCameraPro;
-/* break; */
-/* } */
- break;
- }
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
+ sd->subtype = id->driver_info;
if (sd->subtype != IntelPCCameraPro)
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
else /* no 640x480 for IntelPCCameraPro */
@@ -785,77 +756,30 @@ static void sd_close(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, 0x05, 0x11, 0xf);
}
-/* convert YYUV per line to YUYV (YUV 4:2:2) */
-static void yyuv_decode(unsigned char *out,
- unsigned char *in,
- int width,
- int height)
-{
- unsigned char *Ui, *Vi, *yi, *yi1;
- unsigned char *out1;
- int i, j;
-
- yi = in;
- for (i = height / 2; --i >= 0; ) {
- out1 = out + width * 2; /* next line */
- yi1 = yi + width;
- Ui = yi1 + width;
- Vi = Ui + width / 2;
- for (j = width / 2; --j >= 0; ) {
- *out++ = 128 + *yi++;
- *out++ = 128 + *Ui;
- *out++ = 128 + *yi++;
- *out++ = 128 + *Vi;
-
- *out1++ = 128 + *yi1++;
- *out1++ = 128 + *Ui++;
- *out1++ = 128 + *yi1++;
- *out1++ = 128 + *Vi++;
- }
- yi += width * 2;
- out = out1;
- }
-}
-
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
int len) /* iso packet length */
{
- struct sd *sd = (struct sd *) gspca_dev;
-
switch (data[0]) {
case 0: /* start of frame */
- if (gspca_dev->last_packet_type == FIRST_PACKET) {
- yyuv_decode(sd->tmpbuf2, sd->tmpbuf,
- gspca_dev->width,
- gspca_dev->height);
- frame = gspca_frame_add(gspca_dev,
- LAST_PACKET,
- frame,
- sd->tmpbuf2,
- gspca_dev->width
- * gspca_dev->height
- * 2);
- }
- gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
- data, 0);
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ data, 0);
data += SPCA50X_OFFSET_DATA;
len -= SPCA50X_OFFSET_DATA;
- if (len > 0)
- memcpy(sd->tmpbuf, data, len);
- else
- len = 0;
- sd->buflen = len;
- return;
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ data, len);
+ break;
case 0xff: /* drop */
/* gspca_dev->last_packet_type = DISCARD_PACKET; */
- return;
+ break;
+ default:
+ data += 1;
+ len -= 1;
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ data, len);
+ break;
}
- data += 1;
- len -= 1;
- memcpy(&sd->tmpbuf[sd->buflen], data, len);
- sd->buflen += len;
}
static void setbrightness(struct gspca_dev *gspca_dev)
@@ -910,10 +834,10 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x041e, 0x401d), DVNM("Creative Webcam NX ULTRA")},
- {USB_DEVICE(0x0733, 0x0430), DVNM("Intel PC Camera Pro")},
+ {USB_DEVICE(0x041e, 0x401d), .driver_info = Nxultra},
+ {USB_DEVICE(0x0733, 0x0430), .driver_info = IntelPCCameraPro},
+/*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -938,7 +862,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 143203c1fd9..6fe715c80ad 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -25,9 +25,6 @@
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -36,10 +33,6 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- int buflen;
- __u8 tmpbuf[640 * 480 * 3]; /* YYUV per line */
- __u8 tmpbuf2[640 * 480 * 2]; /* YUYV */
-
unsigned char brightness;
unsigned char contrast;
unsigned char colors;
@@ -118,29 +111,29 @@ static struct ctrl sd_ctrls[] = {
};
static struct v4l2_pix_format vga_mode[] = {
- {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 160 * 2,
- .sizeimage = 160 * 120 * 2,
+ {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+ .bytesperline = 160 * 3,
+ .sizeimage = 160 * 120 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 5},
- {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 176 * 2,
- .sizeimage = 176 * 144 * 2,
+ {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+ .bytesperline = 176 * 3,
+ .sizeimage = 176 * 144 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 4},
- {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 320 * 2,
- .sizeimage = 320 * 240 * 2,
+ {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+ .bytesperline = 320 * 3,
+ .sizeimage = 320 * 240 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 2},
- {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 352 * 2,
- .sizeimage = 352 * 288 * 2,
+ {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+ .bytesperline = 352 * 3,
+ .sizeimage = 352 * 288 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 1},
- {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 640 * 2,
- .sizeimage = 640 * 480 * 2,
+ {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
+ .bytesperline = 640 * 3,
+ .sizeimage = 640 * 480 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 0},
};
@@ -310,7 +303,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
@@ -576,77 +568,30 @@ static void sd_close(struct gspca_dev *gspca_dev)
{
}
-/* convert YYUV per line to YUYV (YUV 4:2:2) */
-static void yyuv_decode(unsigned char *out,
- unsigned char *in,
- int width,
- int height)
-{
- unsigned char *Ui, *Vi, *yi, *yi1;
- unsigned char *out1;
- int i, j;
-
- yi = in;
- for (i = height / 2; --i >= 0; ) {
- out1 = out + width * 2; /* next line */
- yi1 = yi + width;
- Ui = yi1 + width;
- Vi = Ui + width / 2;
- for (j = width / 2; --j >= 0; ) {
- *out++ = 128 + *yi++;
- *out++ = 128 + *Ui;
- *out++ = 128 + *yi++;
- *out++ = 128 + *Vi;
-
- *out1++ = 128 + *yi1++;
- *out1++ = 128 + *Ui++;
- *out1++ = 128 + *yi1++;
- *out1++ = 128 + *Vi++;
- }
- yi += width * 2;
- out = out1;
- }
-}
-
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
int len) /* iso packet length */
{
- struct sd *sd = (struct sd *) gspca_dev;
-
switch (data[0]) {
case 0: /* start of frame */
- if (gspca_dev->last_packet_type == FIRST_PACKET) {
- yyuv_decode(sd->tmpbuf2, sd->tmpbuf,
- gspca_dev->width,
- gspca_dev->height);
- frame = gspca_frame_add(gspca_dev,
- LAST_PACKET,
- frame,
- sd->tmpbuf2,
- gspca_dev->width
- * gspca_dev->height
- * 2);
- }
- gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
- data, 0);
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ data, 0);
data += SPCA50X_OFFSET_DATA;
len -= SPCA50X_OFFSET_DATA;
- if (len > 0)
- memcpy(sd->tmpbuf, data, len);
- else
- len = 0;
- sd->buflen = len;
- return;
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ data, len);
+ break;
case 0xff: /* drop */
/* gspca_dev->last_packet_type = DISCARD_PACKET; */
- return;
+ break;
+ default:
+ data += 1;
+ len -= 1;
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ data, len);
+ break;
}
- data += 1;
- len -= 1;
- memcpy(&sd->tmpbuf[sd->buflen], data, len);
- sd->buflen += len;
}
static void setbrightness(struct gspca_dev *gspca_dev)
@@ -804,12 +749,12 @@ static struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x06e1, 0xa190), DVNM("ADS Instant VCD")},
-/* {USB_DEVICE(0x0733, 0x0430), DVNM("UsbGrabber PV321c")}, */
- {USB_DEVICE(0x0734, 0x043b), DVNM("3DeMon USB Capture aka")},
- {USB_DEVICE(0x99fa, 0x8988), DVNM("Grandtec V.cap")},
+ {USB_DEVICE(0x06e1, 0xa190)},
+/*fixme: may be IntelPCCameraPro BRIDGE_SPCA505
+ {USB_DEVICE(0x0733, 0x0430)}, */
+ {USB_DEVICE(0x0734, 0x043b)},
+ {USB_DEVICE(0x99fa, 0x8988)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -834,7 +779,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index d8cd93866a4..b608a27ad11 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -22,9 +22,6 @@
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -33,10 +30,6 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- int buflen;
- unsigned char tmpbuf[352 * 288 * 3 / 2]; /* YUVY per line */
- unsigned char tmpbuf2[352 * 288 * 2]; /* YUYV */
-
unsigned char brightness;
char subtype;
@@ -71,23 +64,23 @@ static struct ctrl sd_ctrls[] = {
static struct v4l2_pix_format sif_mode[] = {
{160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 160 * 2,
- .sizeimage = 160 * 120 * 2,
+ .bytesperline = 160 * 3,
+ .sizeimage = 160 * 120 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 3},
{176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 176 * 2,
- .sizeimage = 176 * 144 * 2,
+ .bytesperline = 176 * 3,
+ .sizeimage = 176 * 144 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 2},
{320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 320 * 2,
- .sizeimage = 320 * 240 * 2,
+ .bytesperline = 320 * 3,
+ .sizeimage = 320 * 240 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 1},
{352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
- .bytesperline = 352 * 2,
- .sizeimage = 352 * 288 * 2,
+ .bytesperline = 352 * 3,
+ .sizeimage = 352 * 288 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 0},
};
@@ -1476,58 +1469,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
- __u16 product;
int data1, data2;
- product = id->idProduct;
- switch (id->idVendor) {
- case 0x0130: /* Clone webcam */
-/* switch (product) { */
-/* case 0x0130: */
- sd->subtype = HamaUSBSightcam; /* same as Hama 0010 */
-/* break; */
-/* } */
- break;
- case 0x041e: /* Creative cameras */
-/* switch (product) { */
-/* case 0x4018: */
- sd->subtype = CreativeVista;
-/* break; */
-/* } */
- break;
- case 0x0461: /* MicroInnovation */
-/* switch (product) { */
-/* case 0x0815: */
- sd->subtype = MicroInnovationIC200;
-/* break; */
-/* } */
- break;
- case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */
-/* switch (product) { */
-/* case 0x110: */
- sd->subtype = ViewQuestVQ110;
-/* break; */
-/* } */
- break;
- case 0x0af9: /* Hama cameras */
- switch (product) {
- case 0x0010:
- sd->subtype = HamaUSBSightcam;
- break;
- case 0x0011:
- sd->subtype = HamaUSBSightcam2;
- break;
- }
- break;
- case 0x8086: /* Intel */
-/* switch (product) { */
-/* case 0x0110: */
- sd->subtype = IntelEasyPCCamera;
-/* break; */
-/* } */
- break;
- }
-
/* Read from global register the USB product and vendor IDs, just to
* prove that we can communicate with the device. This works, which
* confirms at we are communicating properly and that the device
@@ -1544,10 +1487,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x01;
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
+
+ sd->subtype = id->driver_info;
sd->brightness = BRIGHTNESS_DEF;
switch (sd->subtype) {
@@ -1619,77 +1563,30 @@ static void sd_close(struct gspca_dev *gspca_dev)
{
}
-/* convert YUVY per line to YUYV (YUV 4:2:2) */
-static void yuvy_decode(unsigned char *out,
- unsigned char *in,
- int width,
- int height)
-{
- unsigned char *Ui, *Vi, *yi, *yi1;
- unsigned char *out1;
- int i, j;
-
- yi = in;
- for (i = height / 2; --i >= 0; ) {
- out1 = out + width * 2; /* next line */
- Ui = yi + width;
- Vi = Ui + width / 2;
- yi1 = Vi + width / 2;
- for (j = width / 2; --j >= 0; ) {
- *out++ = 128 + *yi++;
- *out++ = 128 + *Ui;
- *out++ = 128 + *yi++;
- *out++ = 128 + *Vi;
-
- *out1++ = 128 + *yi1++;
- *out1++ = 128 + *Ui++;
- *out1++ = 128 + *yi1++;
- *out1++ = 128 + *Vi++;
- }
- yi += width * 2;
- out = out1;
- }
-}
-
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
int len) /* iso packet length */
{
- struct sd *sd = (struct sd *) gspca_dev;
-
switch (data[0]) {
case 0: /* start of frame */
- if (gspca_dev->last_packet_type == FIRST_PACKET) {
- yuvy_decode(sd->tmpbuf2, sd->tmpbuf,
- gspca_dev->width,
- gspca_dev->height);
- frame = gspca_frame_add(gspca_dev,
- LAST_PACKET,
- frame,
- sd->tmpbuf2,
- gspca_dev->width
- * gspca_dev->height
- * 2);
- }
- gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
- data, 0);
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ data, 0);
data += SPCA508_OFFSET_DATA;
len -= SPCA508_OFFSET_DATA;
- if (len > 0)
- memcpy(sd->tmpbuf, data, len);
- else
- len = 0;
- sd->buflen = len;
- return;
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ data, len);
+ break;
case 0xff: /* drop */
/* gspca_dev->last_packet_type = DISCARD_PACKET; */
- return;
+ break;
+ default:
+ data += 1;
+ len -= 1;
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ data, len);
+ break;
}
- data += 1;
- len -= 1;
- memcpy(&sd->tmpbuf[sd->buflen], data, len);
- sd->buflen += len;
}
static void setbrightness(struct gspca_dev *gspca_dev)
@@ -1745,15 +1642,14 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x0130, 0x0130), DVNM("Clone Digital Webcam 11043")},
- {USB_DEVICE(0x041e, 0x4018), DVNM("Creative Webcam Vista (PD1100)")},
- {USB_DEVICE(0x0461, 0x0815), DVNM("Micro Innovation IC200")},
- {USB_DEVICE(0x0733, 0x0110), DVNM("ViewQuest VQ110")},
- {USB_DEVICE(0x0af9, 0x0010), DVNM("Hama USB Sightcam 100")},
- {USB_DEVICE(0x0af9, 0x0011), DVNM("Hama USB Sightcam 100")},
- {USB_DEVICE(0x8086, 0x0110), DVNM("Intel Easy PC Camera")},
+ {USB_DEVICE(0x0130, 0x0130), .driver_info = HamaUSBSightcam},
+ {USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista},
+ {USB_DEVICE(0x0461, 0x0815), .driver_info = MicroInnovationIC200},
+ {USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110},
+ {USB_DEVICE(0x0af9, 0x0010), .driver_info = HamaUSBSightcam},
+ {USB_DEVICE(0x0af9, 0x0011), .driver_info = HamaUSBSightcam2},
+ {USB_DEVICE(0x8086, 0x0110), .driver_info = IntelEasyPCCamera},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -1778,7 +1674,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index b659bd0f788..a26174508cb 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -24,9 +24,6 @@
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -582,35 +579,15 @@ static int sd_config(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "Bad vendor / product from device");
return -EINVAL;
}
- switch (product) {
- case 0x0928:
- case 0x0929:
- case 0x092a:
- case 0x092b:
- case 0x092c:
- case 0x092d:
- case 0x092e:
- case 0x092f:
- case 0x403b:
- sd->chip_revision = Rev012A;
- break;
- default:
-/* case 0x0561:
- case 0x0815: * ?? in spca508.c
- case 0x401a:
- case 0x7004:
- case 0x7e50:
- case 0xa001:
- case 0xcdee: */
- sd->chip_revision = Rev072A;
- break;
- }
+
cam = &gspca_dev->cam;
cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x01;
gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */
cam->cam_mode = sif_mode;
cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
+
+ sd->chip_revision = id->driver_info;
sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value;
@@ -997,23 +974,22 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x041e, 0x401a), DVNM("Creative Webcam Vista (PD1100)")},
- {USB_DEVICE(0x041e, 0x403b), DVNM("Creative Webcam Vista (VF0010)")},
- {USB_DEVICE(0x0458, 0x7004), DVNM("Genius VideoCAM Express V2")},
- {USB_DEVICE(0x046d, 0x0928), DVNM("Logitech QC Express Etch2")},
- {USB_DEVICE(0x046d, 0x0929), DVNM("Labtec Webcam Elch2")},
- {USB_DEVICE(0x046d, 0x092a), DVNM("Logitech QC for Notebook")},
- {USB_DEVICE(0x046d, 0x092b), DVNM("Labtec Webcam Plus")},
- {USB_DEVICE(0x046d, 0x092c), DVNM("Logitech QC chat Elch2")},
- {USB_DEVICE(0x046d, 0x092d), DVNM("Logitech QC Elch2")},
- {USB_DEVICE(0x046d, 0x092e), DVNM("Logitech QC Elch2")},
- {USB_DEVICE(0x046d, 0x092f), DVNM("Logitech QC Elch2")},
- {USB_DEVICE(0x04fc, 0x0561), DVNM("Flexcam 100")},
- {USB_DEVICE(0x060b, 0xa001), DVNM("Maxell Compact Pc PM3")},
- {USB_DEVICE(0x10fd, 0x7e50), DVNM("FlyCam Usb 100")},
- {USB_DEVICE(0xabcd, 0xcdee), DVNM("Petcam")},
+ {USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
+ {USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
+ {USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
+ {USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
+ {USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
+ {USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
+ {USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A},
+ {USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A},
+ {USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A},
+ {USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A},
+ {USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A},
+ {USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A},
+ {USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A},
+ {USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A},
+ {USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A},
{}
};
@@ -1039,7 +1015,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index c78ee0d3e59..16219cf6a6d 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -23,9 +23,6 @@
#include "gspca.h"
#include "jpeg.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -299,7 +296,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x02;
gspca_dev->cam.cam_mode = vga_mode;
gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
@@ -549,9 +545,8 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x05e1, 0x0893), DVNM("Syntek DV4000")},
+ {USB_DEVICE(0x05e1, 0x0893)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -576,7 +571,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- info("v%s registered", version);
+ info("registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index abd7bef9b3d..54efa48bee0 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -24,9 +24,6 @@
#include "gspca.h"
#include "jpeg.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 8)
-static const char version[] = "2.1.8";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -804,229 +801,29 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
struct cam *cam;
- __u16 vendor;
- __u16 product;
- __u8 fw;
-
- vendor = id->idVendor;
- product = id->idProduct;
- switch (vendor) {
- case 0x041e: /* Creative cameras */
-/* switch (product) { */
-/* case 0x400b: */
-/* case 0x4012: */
-/* case 0x4013: */
-/* sd->bridge = BRIDGE_SPCA504C; */
-/* break; */
-/* } */
- break;
- case 0x0458: /* Genius KYE cameras */
-/* switch (product) { */
-/* case 0x7006: */
- sd->bridge = BRIDGE_SPCA504B;
-/* break; */
-/* } */
- break;
- case 0x0461: /* MicroInnovation */
-/* switch (product) { */
-/* case 0x0821: */
- sd->bridge = BRIDGE_SPCA533;
-/* break; */
-/* } */
- break;
- case 0x046d: /* Logitech Labtec */
- switch (product) {
- case 0x0905:
- sd->subtype = LogitechClickSmart820;
- sd->bridge = BRIDGE_SPCA533;
- break;
- case 0x0960:
- sd->subtype = LogitechClickSmart420;
- sd->bridge = BRIDGE_SPCA504C;
- break;
- }
- break;
- case 0x0471: /* Philips */
-/* switch (product) { */
-/* case 0x0322: */
- sd->bridge = BRIDGE_SPCA504B;
-/* break; */
-/* } */
- break;
- case 0x04a5: /* Benq */
- switch (product) {
- case 0x3003:
- sd->bridge = BRIDGE_SPCA504B;
- break;
- case 0x3008:
- case 0x300a:
- sd->bridge = BRIDGE_SPCA533;
- break;
- }
- break;
- case 0x04f1: /* JVC */
-/* switch (product) { */
-/* case 0x1001: */
- sd->bridge = BRIDGE_SPCA504B;
-/* break; */
-/* } */
- break;
- case 0x04fc: /* SunPlus */
- switch (product) {
- case 0x500c:
- sd->bridge = BRIDGE_SPCA504B;
- break;
- case 0x504a:
+
+ cam = &gspca_dev->cam;
+ cam->epaddr = 0x01;
+
+ sd->bridge = id->driver_info >> 8;
+ sd->subtype = id->driver_info;
+
+ if (sd->subtype == AiptekMiniPenCam13) {
/* try to get the firmware as some cam answer 2.0.1.2.2
* and should be a spca504b then overwrite that setting */
- reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1);
- fw = gspca_dev->usb_buf[0];
- if (fw == 1) {
- sd->subtype = AiptekMiniPenCam13;
- sd->bridge = BRIDGE_SPCA504;
- } else if (fw == 2) {
- sd->bridge = BRIDGE_SPCA504B;
- } else
- return -ENODEV;
- break;
- case 0x504b:
- sd->bridge = BRIDGE_SPCA504B;
- break;
- case 0x5330:
- sd->bridge = BRIDGE_SPCA533;
- break;
- case 0x5360:
- sd->bridge = BRIDGE_SPCA536;
- break;
- case 0xffff:
- sd->bridge = BRIDGE_SPCA504B;
- break;
- }
- break;
- case 0x052b: /* ?? Megapix */
-/* switch (product) { */
-/* case 0x1513: */
- sd->subtype = MegapixV4;
- sd->bridge = BRIDGE_SPCA533;
-/* break; */
-/* } */
- break;
- case 0x0546: /* Polaroid */
- switch (product) {
- case 0x3155:
- sd->bridge = BRIDGE_SPCA533;
- break;
- case 0x3191:
- case 0x3273:
- sd->bridge = BRIDGE_SPCA504B;
- break;
- }
- break;
- case 0x055f: /* Mustek cameras */
- switch (product) {
- case 0xc211:
- sd->bridge = BRIDGE_SPCA536;
- break;
- case 0xc230:
- case 0xc232:
- sd->bridge = BRIDGE_SPCA533;
- break;
- case 0xc360:
- sd->bridge = BRIDGE_SPCA536;
- break;
- case 0xc420:
- sd->bridge = BRIDGE_SPCA504;
- break;
- case 0xc430:
- case 0xc440:
- sd->bridge = BRIDGE_SPCA533;
- break;
- case 0xc520:
- sd->bridge = BRIDGE_SPCA504;
- break;
- case 0xc530:
- case 0xc540:
- case 0xc630:
- case 0xc650:
- sd->bridge = BRIDGE_SPCA533;
- break;
- }
- break;
- case 0x05da: /* Digital Dream cameras */
-/* switch (product) { */
-/* case 0x1018: */
+ reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1);
+ switch (gspca_dev->usb_buf[0]) {
+ case 1:
+ break; /* (right bridge/subtype) */
+ case 2:
sd->bridge = BRIDGE_SPCA504B;
-/* break; */
-/* } */
- break;
- case 0x06d6: /* Trust */
-/* switch (product) { */
-/* case 0x0031: */
- sd->bridge = BRIDGE_SPCA533; /* SPCA533A */
-/* break; */
-/* } */
- break;
- case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */
- switch (product) {
- case 0x1311:
- case 0x1314:
- case 0x2211:
- case 0x2221:
- sd->bridge = BRIDGE_SPCA533;
- break;
- case 0x3261:
- case 0x3281:
- sd->bridge = BRIDGE_SPCA536;
- break;
- }
- break;
- case 0x08ca: /* Aiptek */
- switch (product) {
- case 0x0104:
- case 0x0106:
- sd->bridge = BRIDGE_SPCA533;
- break;
- case 0x2008:
- sd->bridge = BRIDGE_SPCA504B;
- break;
- case 0x2010:
- sd->bridge = BRIDGE_SPCA533;
- break;
- case 0x2016:
- case 0x2018:
- sd->bridge = BRIDGE_SPCA504B;
- break;
- case 0x2020:
- case 0x2022:
- sd->bridge = BRIDGE_SPCA533;
- break;
- case 0x2024:
- sd->bridge = BRIDGE_SPCA536;
- break;
- case 0x2028:
- sd->bridge = BRIDGE_SPCA533;
- break;
- case 0x2040:
- case 0x2042:
- case 0x2050:
- case 0x2060:
- sd->bridge = BRIDGE_SPCA536;
+ sd->subtype = 0;
break;
+ default:
+ return -ENODEV;
}
- break;
- case 0x0d64: /* SunPlus */
-/* switch (product) { */
-/* case 0x0303: */
- sd->bridge = BRIDGE_SPCA536;
-/* break; */
-/* } */
- break;
}
- cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
- cam->epaddr = 0x01;
-
switch (sd->bridge) {
default:
/* case BRIDGE_SPCA504B: */
@@ -1581,65 +1378,67 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
+#define BS(bridge, subtype) \
+ .driver_info = (BRIDGE_ ## bridge << 8) \
+ | (subtype)
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x041e, 0x400b), DVNM("Creative PC-CAM 600")},
- {USB_DEVICE(0x041e, 0x4012), DVNM("PC-Cam350")},
- {USB_DEVICE(0x041e, 0x4013), DVNM("Creative Pccam750")},
- {USB_DEVICE(0x0458, 0x7006), DVNM("Genius Dsc 1.3 Smart")},
- {USB_DEVICE(0x0461, 0x0821), DVNM("Fujifilm MV-1")},
- {USB_DEVICE(0x046d, 0x0905), DVNM("Logitech ClickSmart 820")},
- {USB_DEVICE(0x046d, 0x0960), DVNM("Logitech ClickSmart 420")},
- {USB_DEVICE(0x0471, 0x0322), DVNM("Philips DMVC1300K")},
- {USB_DEVICE(0x04a5, 0x3003), DVNM("Benq DC 1300")},
- {USB_DEVICE(0x04a5, 0x3008), DVNM("Benq DC 1500")},
- {USB_DEVICE(0x04a5, 0x300a), DVNM("Benq DC3410")},
- {USB_DEVICE(0x04f1, 0x1001), DVNM("JVC GC A50")},
- {USB_DEVICE(0x04fc, 0x500c), DVNM("Sunplus CA500C")},
- {USB_DEVICE(0x04fc, 0x504a), DVNM("Aiptek Mini PenCam 1.3")},
- {USB_DEVICE(0x04fc, 0x504b), DVNM("Maxell MaxPocket LE 1.3")},
- {USB_DEVICE(0x04fc, 0x5330), DVNM("Digitrex 2110")},
- {USB_DEVICE(0x04fc, 0x5360), DVNM("Sunplus Generic")},
- {USB_DEVICE(0x04fc, 0xffff), DVNM("Pure DigitalDakota")},
- {USB_DEVICE(0x052b, 0x1513), DVNM("Megapix V4")},
- {USB_DEVICE(0x0546, 0x3155), DVNM("Polaroid PDC3070")},
- {USB_DEVICE(0x0546, 0x3191), DVNM("Polaroid Ion 80")},
- {USB_DEVICE(0x0546, 0x3273), DVNM("Polaroid PDC2030")},
- {USB_DEVICE(0x055f, 0xc211), DVNM("Kowa Bs888e Microcamera")},
- {USB_DEVICE(0x055f, 0xc230), DVNM("Mustek Digicam 330K")},
- {USB_DEVICE(0x055f, 0xc232), DVNM("Mustek MDC3500")},
- {USB_DEVICE(0x055f, 0xc360), DVNM("Mustek DV4000 Mpeg4 ")},
- {USB_DEVICE(0x055f, 0xc420), DVNM("Mustek gSmart Mini 2")},
- {USB_DEVICE(0x055f, 0xc430), DVNM("Mustek Gsmart LCD 2")},
- {USB_DEVICE(0x055f, 0xc440), DVNM("Mustek DV 3000")},
- {USB_DEVICE(0x055f, 0xc520), DVNM("Mustek gSmart Mini 3")},
- {USB_DEVICE(0x055f, 0xc530), DVNM("Mustek Gsmart LCD 3")},
- {USB_DEVICE(0x055f, 0xc540), DVNM("Gsmart D30")},
- {USB_DEVICE(0x055f, 0xc630), DVNM("Mustek MDC4000")},
- {USB_DEVICE(0x055f, 0xc650), DVNM("Mustek MDC5500Z")},
- {USB_DEVICE(0x05da, 0x1018), DVNM("Digital Dream Enigma 1.3")},
- {USB_DEVICE(0x06d6, 0x0031), DVNM("Trust 610 LCD PowerC@m Zoom")},
- {USB_DEVICE(0x0733, 0x1311), DVNM("Digital Dream Epsilon 1.3")},
- {USB_DEVICE(0x0733, 0x1314), DVNM("Mercury 2.1MEG Deluxe Classic Cam")},
- {USB_DEVICE(0x0733, 0x2211), DVNM("Jenoptik jdc 21 LCD")},
- {USB_DEVICE(0x0733, 0x2221), DVNM("Mercury Digital Pro 3.1p")},
- {USB_DEVICE(0x0733, 0x3261), DVNM("Concord 3045 spca536a")},
- {USB_DEVICE(0x0733, 0x3281), DVNM("Cyberpix S550V")},
- {USB_DEVICE(0x08ca, 0x0104), DVNM("Aiptek PocketDVII 1.3")},
- {USB_DEVICE(0x08ca, 0x0106), DVNM("Aiptek Pocket DV3100+")},
- {USB_DEVICE(0x08ca, 0x2008), DVNM("Aiptek Mini PenCam 2 M")},
- {USB_DEVICE(0x08ca, 0x2010), DVNM("Aiptek PocketCam 3M")},
- {USB_DEVICE(0x08ca, 0x2016), DVNM("Aiptek PocketCam 2 Mega")},
- {USB_DEVICE(0x08ca, 0x2018), DVNM("Aiptek Pencam SD 2M")},
- {USB_DEVICE(0x08ca, 0x2020), DVNM("Aiptek Slim 3000F")},
- {USB_DEVICE(0x08ca, 0x2022), DVNM("Aiptek Slim 3200")},
- {USB_DEVICE(0x08ca, 0x2024), DVNM("Aiptek DV3500 Mpeg4 ")},
- {USB_DEVICE(0x08ca, 0x2028), DVNM("Aiptek PocketCam4M")},
- {USB_DEVICE(0x08ca, 0x2040), DVNM("Aiptek PocketDV4100M")},
- {USB_DEVICE(0x08ca, 0x2042), DVNM("Aiptek PocketDV5100")},
- {USB_DEVICE(0x08ca, 0x2050), DVNM("Medion MD 41437")},
- {USB_DEVICE(0x08ca, 0x2060), DVNM("Aiptek PocketDV5300")},
- {USB_DEVICE(0x0d64, 0x0303), DVNM("Sunplus FashionCam DXG")},
+ {USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)},
+ {USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)},
+ {USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)},
+ {USB_DEVICE(0x0458, 0x7006), BS(SPCA504B, 0)},
+ {USB_DEVICE(0x0461, 0x0821), BS(SPCA533, 0)},
+ {USB_DEVICE(0x046d, 0x0905), BS(SPCA533, LogitechClickSmart820)},
+ {USB_DEVICE(0x046d, 0x0960), BS(SPCA504C, LogitechClickSmart420)},
+ {USB_DEVICE(0x0471, 0x0322), BS(SPCA504B, 0)},
+ {USB_DEVICE(0x04a5, 0x3003), BS(SPCA504B, 0)},
+ {USB_DEVICE(0x04a5, 0x3008), BS(SPCA533, 0)},
+ {USB_DEVICE(0x04a5, 0x300a), BS(SPCA533, 0)},
+ {USB_DEVICE(0x04f1, 0x1001), BS(SPCA504B, 0)},
+ {USB_DEVICE(0x04fc, 0x500c), BS(SPCA504B, 0)},
+ {USB_DEVICE(0x04fc, 0x504a), BS(SPCA504, AiptekMiniPenCam13)},
+ {USB_DEVICE(0x04fc, 0x504b), BS(SPCA504B, 0)},
+ {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)},
+ {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
+ {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
+ {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
+ {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
+ {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)},
+ {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)},
+ {USB_DEVICE(0x055f, 0xc211), BS(SPCA536, 0)},
+ {USB_DEVICE(0x055f, 0xc230), BS(SPCA533, 0)},
+ {USB_DEVICE(0x055f, 0xc232), BS(SPCA533, 0)},
+ {USB_DEVICE(0x055f, 0xc360), BS(SPCA536, 0)},
+ {USB_DEVICE(0x055f, 0xc420), BS(SPCA504, 0)},
+ {USB_DEVICE(0x055f, 0xc430), BS(SPCA533, 0)},
+ {USB_DEVICE(0x055f, 0xc440), BS(SPCA533, 0)},
+ {USB_DEVICE(0x055f, 0xc520), BS(SPCA504, 0)},
+ {USB_DEVICE(0x055f, 0xc530), BS(SPCA533, 0)},
+ {USB_DEVICE(0x055f, 0xc540), BS(SPCA533, 0)},
+ {USB_DEVICE(0x055f, 0xc630), BS(SPCA533, 0)},
+ {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)},
+ {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)},
+ {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)},
+ {USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)},
+ {USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)},
+ {USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)},
+ {USB_DEVICE(0x0733, 0x2221), BS(SPCA533, 0)},
+ {USB_DEVICE(0x0733, 0x3261), BS(SPCA536, 0)},
+ {USB_DEVICE(0x0733, 0x3281), BS(SPCA536, 0)},
+ {USB_DEVICE(0x08ca, 0x0104), BS(SPCA533, 0)},
+ {USB_DEVICE(0x08ca, 0x0106), BS(SPCA533, 0)},
+ {USB_DEVICE(0x08ca, 0x2008), BS(SPCA504B, 0)},
+ {USB_DEVICE(0x08ca, 0x2010), BS(SPCA533, 0)},
+ {USB_DEVICE(0x08ca, 0x2016), BS(SPCA504B, 0)},
+ {USB_DEVICE(0x08ca, 0x2018), BS(SPCA504B, 0)},
+ {USB_DEVICE(0x08ca, 0x2020), BS(SPCA533, 0)},
+ {USB_DEVICE(0x08ca, 0x2022), BS(SPCA533, 0)},
+ {USB_DEVICE(0x08ca, 0x2024), BS(SPCA536, 0)},
+ {USB_DEVICE(0x08ca, 0x2028), BS(SPCA533, 0)},
+ {USB_DEVICE(0x08ca, 0x2040), BS(SPCA536, 0)},
+ {USB_DEVICE(0x08ca, 0x2042), BS(SPCA536, 0)},
+ {USB_DEVICE(0x08ca, 0x2050), BS(SPCA536, 0)},
+ {USB_DEVICE(0x08ca, 0x2060), BS(SPCA536, 0)},
+ {USB_DEVICE(0x0d64, 0x0303), BS(SPCA536, 0)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -1664,7 +1463,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 00f47e463a0..91b555c34c6 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -1,12 +1,4 @@
/*
- *Notes: * t613 + tas5130A
- * * Focus to light do not balance well as in win.
- * Quality in win is not good, but its kinda better.
- * * Fix some "extraneous bytes", most of apps will show the image anyway
- * * Gamma table, is there, but its really doing something?
- * * 7~8 Fps, its ok, max on win its 10.
- * Costantino Leandro
- *
* V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
*
* This program is free software; you can redistribute it and/or modify
@@ -22,16 +14,22 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *Notes: * t613 + tas5130A
+ * * Focus to light do not balance well as in win.
+ * Quality in win is not good, but its kinda better.
+ * * Fix some "extraneous bytes", most of apps will show the image anyway
+ * * Gamma table, is there, but its really doing something?
+ * * 7~8 Fps, its ok, max on win its 10.
+ * Costantino Leandro
*/
#define MODULE_NAME "t613"
+
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
#define MAX_GAMMA 0x10 /* 0 to 15 */
-/* From LUVCVIEW */
#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 3)
MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
@@ -424,7 +422,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x01;
cam->cam_mode = vga_mode_t16;
@@ -998,9 +995,8 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x17a1, 0x0128), DVNM("XPX Webcam")},
+ {USB_DEVICE(0x17a1, 0x0128)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -1025,7 +1021,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 0b793899095..1ff8ba2f7fe 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -22,9 +22,6 @@
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("TV8532 USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -249,7 +246,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
tv_8532WriteEEprom(gspca_dev);
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 1;
cam->cam_mode = sif_mode;
cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
@@ -624,13 +620,12 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x046d, 0x0920), DVNM("QC Express")},
- {USB_DEVICE(0x046d, 0x0921), DVNM("Labtec Webcam")},
- {USB_DEVICE(0x0545, 0x808b), DVNM("Veo Stingray")},
- {USB_DEVICE(0x0545, 0x8333), DVNM("Veo Stingray")},
- {USB_DEVICE(0x0923, 0x010f), DVNM("ICM532 cams")},
+ {USB_DEVICE(0x046d, 0x0920)},
+ {USB_DEVICE(0x046d, 0x0921)},
+ {USB_DEVICE(0x0545, 0x808b)},
+ {USB_DEVICE(0x0545, 0x8333)},
+ {USB_DEVICE(0x0923, 0x010f)},
{}
};
@@ -656,7 +651,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index fcf2c9e3257..a4221753e1b 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -24,9 +24,6 @@
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
MODULE_DESCRIPTION("GSPCA/VC032X USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -1419,30 +1416,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct usb_device *dev = gspca_dev->dev;
struct cam *cam;
int sensor;
- __u16 product;
-
- product = id->idProduct;
- sd->bridge = BRIDGE_VC0321;
- switch (id->idVendor) {
- case 0x0ac8: /* Vimicro z-star */
- switch (product) {
- case 0x0323:
- sd->bridge = BRIDGE_VC0323;
- break;
- }
- break;
- case 0x17ef: /* Lenovo */
-/* switch (product) { */
-/* case 0x4802: * Lenovo MI1310_SOC */
- sd->bridge = BRIDGE_VC0323;
-/* break; */
-/* } */
- break;
- }
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x02;
+ sd->bridge = id->driver_info;
if (sd->bridge == BRIDGE_VC0321) {
cam->cam_mode = vc0321_mode;
cam->nmodes = ARRAY_SIZE(vc0321_mode);
@@ -1771,16 +1748,15 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x046d, 0x0892), DVNM("Logitech Orbicam")},
- {USB_DEVICE(0x046d, 0x0896), DVNM("Logitech Orbicam")},
- {USB_DEVICE(0x0ac8, 0x0321), DVNM("Vimicro generic vc0321")},
- {USB_DEVICE(0x0ac8, 0x0323), DVNM("Vimicro Vc0323")},
- {USB_DEVICE(0x0ac8, 0x0328), DVNM("A4Tech PK-130MG")},
- {USB_DEVICE(0x0ac8, 0xc001), DVNM("Sony embedded vimicro")},
- {USB_DEVICE(0x0ac8, 0xc002), DVNM("Sony embedded vimicro")},
- {USB_DEVICE(0x17ef, 0x4802), DVNM("Lenovo Vc0323+MI1310_SOC")},
+ {USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321},
+ {USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321},
+ {USB_DEVICE(0x0ac8, 0x0321), .driver_info = BRIDGE_VC0321},
+ {USB_DEVICE(0x0ac8, 0x0323), .driver_info = BRIDGE_VC0323},
+ {USB_DEVICE(0x0ac8, 0x0328), .driver_info = BRIDGE_VC0321},
+ {USB_DEVICE(0x0ac8, 0xc001), .driver_info = BRIDGE_VC0321},
+ {USB_DEVICE(0x0ac8, 0xc002), .driver_info = BRIDGE_VC0321},
+ {USB_DEVICE(0x17ef, 0x4802), .driver_info = BRIDGE_VC0323},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -1805,7 +1781,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit sd_mod_exit(void)
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index b761b11c5c6..22a994ccb1d 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -24,9 +24,6 @@
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
-static const char version[] = "2.1.7";
-
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, "
"Serge A. Suchkov <Serge.A.S@tochka.ru>");
MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver");
@@ -49,7 +46,7 @@ struct sd {
__u8 sharpness;
char qindex;
- char sensor; /* Type of image sensor chip */
+ signed char sensor; /* Type of image sensor chip */
/* !! values used in different tables */
#define SENSOR_CS2102 0
#define SENSOR_CS2102K 1
@@ -2205,10 +2202,10 @@ static const struct usb_action hdcs2020xb_InitialScale[] = {
};
static const struct usb_action hdcs2020b_50HZ[] = {
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x13, 0x0018}, /* 00,13,18,aa */
- {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
- {0xaa, 0x0e, 0x0005}, /* 00,0e,05,aa */
- {0xaa, 0x19, 0x001f}, /* 00,19,1f,aa */
+ {0xaa, 0x13, 0x0018}, /* 00,13,18,aa */
+ {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
+ {0xaa, 0x0e, 0x0005}, /* 00,0e,05,aa */
+ {0xaa, 0x19, 0x001f}, /* 00,19,1f,aa */
{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
{0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */
{0xa0, 0x76, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,76,cc */
@@ -2226,10 +2223,10 @@ static const struct usb_action hdcs2020b_50HZ[] = {
};
static const struct usb_action hdcs2020b_60HZ[] = {
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x13, 0x0031}, /* 00,13,31,aa */
- {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
- {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */
- {0xaa, 0x19, 0x00cd}, /* 00,19,cd,aa */
+ {0xaa, 0x13, 0x0031}, /* 00,13,31,aa */
+ {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
+ {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */
+ {0xaa, 0x19, 0x00cd}, /* 00,19,cd,aa */
{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
{0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */
{0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,62,cc */
@@ -2247,10 +2244,10 @@ static const struct usb_action hdcs2020b_60HZ[] = {
};
static const struct usb_action hdcs2020b_NoFliker[] = {
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
- {0xaa, 0x13, 0x0010}, /* 00,13,10,aa */
- {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
- {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */
- {0xaa, 0x19, 0x0000}, /* 00,19,00,aa */
+ {0xaa, 0x13, 0x0010}, /* 00,13,10,aa */
+ {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
+ {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */
+ {0xaa, 0x19, 0x0000}, /* 00,19,00,aa */
{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
{0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */
{0xa0, 0x70, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,70,cc */
@@ -4102,27 +4099,27 @@ static const struct usb_action pas106b_Initial_com[] = {
static const struct usb_action pas106b_Initial[] = { /* 176x144 */
/* JPEG control */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
/* Sream and Sensor specific */
- {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT}, /* CMOSSensorSelect */
+ {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT},
/* Picture size */
- {0xa0, 0x00, ZC3XX_R003_FRAMEWIDTHHIGH}, /* FrameWidthHigh 00 */
- {0xa0, 0xb0, ZC3XX_R004_FRAMEWIDTHLOW}, /* FrameWidthLow B0 */
- {0xa0, 0x00, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* FrameHeightHigh 00 */
- {0xa0, 0x90, ZC3XX_R006_FRAMEHEIGHTLOW}, /* FrameHightLow 90 */
+ {0xa0, 0x00, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0xb0, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x00, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0x90, ZC3XX_R006_FRAMEHEIGHTLOW},
/* System */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* SystemOperating */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
/* Sream and Sensor specific */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
/* Sensor Interface */
- {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* Compatibily Mode */
+ {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
/* Window inside sensor array */
- {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, /* WinXStartLow */
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* FirstYLow */
- {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, /* FirstxLow */
- {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW}, /* WinHeightLow */
- {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW}, /* WinWidthLow */
+ {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW},
/* Init the sensor */
{0xaa, 0x02, 0x0004},
{0xaa, 0x08, 0x0000},
@@ -4135,40 +4132,40 @@ static const struct usb_action pas106b_Initial[] = { /* 176x144 */
{0xaa, 0x14, 0x0081},
/* Other registors */
- {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* SensorCorrection */
+ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
/* Frame retreiving */
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* AutoAdjustFPS */
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
/* Gains */
- {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN}, /* DigitalGain */
+ {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN},
/* Unknown */
{0xa0, 0x00, 0x01ad},
/* Sharpness */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* SharpnessMode */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* Sharpness05 */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
/* Other registors */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
/* Auto exposure and white balance */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
/*Dead pixels */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
/* EEPROM */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
/* JPEG control */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},
/* Other registers */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
/* Auto exposure and white balance */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
/*Dead pixels */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
/* EEPROM */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
/* JPEG control */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},
{0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
{0xa0, 0xf4, ZC3XX_R10B_RGB01},
@@ -4180,67 +4177,67 @@ static const struct usb_action pas106b_Initial[] = { /* 176x144 */
{0xa0, 0xf4, ZC3XX_R111_RGB21},
{0xa0, 0x58, ZC3XX_R112_RGB22},
/* Auto correction */
- {0xa0, 0x03, ZC3XX_R181_WINXSTART}, /* WinXstart */
- {0xa0, 0x08, ZC3XX_R182_WINXWIDTH}, /* WinXWidth */
- {0xa0, 0x16, ZC3XX_R183_WINXCENTER}, /* WinXCenter */
- {0xa0, 0x03, ZC3XX_R184_WINYSTART}, /* WinYStart */
- {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, /* WinYWidth */
- {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, /* WinYCenter */
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */
+ {0xa0, 0x03, ZC3XX_R181_WINXSTART},
+ {0xa0, 0x08, ZC3XX_R182_WINXWIDTH},
+ {0xa0, 0x16, ZC3XX_R183_WINXCENTER},
+ {0xa0, 0x03, ZC3XX_R184_WINYSTART},
+ {0xa0, 0x05, ZC3XX_R185_WINYWIDTH},
+ {0xa0, 0x14, ZC3XX_R186_WINYCENTER},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
/* Auto exposure and white balance */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* ExposureLimitHigh */
- {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* ExposureLimitMid */
- {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW}, /* ExposureLimitLow */
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* AntiFlickerHigh */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* AntiFlickerLow */
- {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, /* AntiFlickerLow */
- {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* AEBFreeze */
- {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* AEBUnfreeze */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
/* sensor on */
{0xaa, 0x07, 0x00b1},
{0xaa, 0x05, 0x0003},
{0xaa, 0x04, 0x0001},
{0xaa, 0x03, 0x003b},
/* Gains */
- {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* DigitalLimitDiff */
- {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* DigitalGainStep */
- {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */
+ {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
/* Auto correction */
- {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
{0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
/* Gains */
- {0xa0, 0x40, ZC3XX_R116_RGAIN}, /* RGain */
- {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* GGain */
- {0xa0, 0x40, ZC3XX_R118_BGAIN}, /* BGain */
+ {0xa0, 0x40, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x40, ZC3XX_R118_BGAIN},
{}
};
static const struct usb_action pas106b_InitialScale[] = { /* 352x288 */
/* JPEG control */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
/* Sream and Sensor specific */
- {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT}, /* CMOSSensorSelect */
+ {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT},
/* Picture size */
- {0xa0, 0x01, ZC3XX_R003_FRAMEWIDTHHIGH}, /* FrameWidthHigh */
- {0xa0, 0x60, ZC3XX_R004_FRAMEWIDTHLOW}, /* FrameWidthLow */
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* FrameHeightHigh */
- {0xa0, 0x20, ZC3XX_R006_FRAMEHEIGHTLOW}, /* FrameHightLow */
+ {0xa0, 0x01, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x60, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0x20, ZC3XX_R006_FRAMEHEIGHTLOW},
/* System */
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* SystemOperating */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
/* Sream and Sensor specific */
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
/* Sensor Interface */
- {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* Compatibily Mode */
+ {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
/* Window inside sensor array */
- {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, /* WinXStartLow */
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* FirstYLow */
- {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, /* FirstxLow */
- {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW}, /* WinHeightLow */
- {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW}, /* WinWidthLow */
+ {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW},
/* Init the sensor */
{0xaa, 0x02, 0x0004},
{0xaa, 0x08, 0x0000},
@@ -4253,41 +4250,41 @@ static const struct usb_action pas106b_InitialScale[] = { /* 352x288 */
{0xaa, 0x14, 0x0081},
/* Other registors */
- {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* SensorCorrection */
+ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
/* Frame retreiving */
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* AutoAdjustFPS */
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
/* Gains */
- {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN}, /* DigitalGain */
+ {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN},
/* Unknown */
{0xa0, 0x00, 0x01ad},
/* Sharpness */
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* SharpnessMode */
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* Sharpness05 */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
/* Other registors */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
/* Auto exposure and white balance */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */
- {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /* ????????? */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x80, ZC3XX_R18D_YTARGET},
/*Dead pixels */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
/* EEPROM */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
/* JPEG control */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},
/* Other registers */
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
/* Auto exposure and white balance */
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
/*Dead pixels */
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
/* EEPROM */
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
/* JPEG control */
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05},
{0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
{0xa0, 0xf4, ZC3XX_R10B_RGB01},
@@ -4299,43 +4296,43 @@ static const struct usb_action pas106b_InitialScale[] = { /* 352x288 */
{0xa0, 0xf4, ZC3XX_R111_RGB21},
{0xa0, 0x58, ZC3XX_R112_RGB22},
/* Auto correction */
- {0xa0, 0x03, ZC3XX_R181_WINXSTART}, /* WinXstart */
- {0xa0, 0x08, ZC3XX_R182_WINXWIDTH}, /* WinXWidth */
- {0xa0, 0x16, ZC3XX_R183_WINXCENTER}, /* WinXCenter */
- {0xa0, 0x03, ZC3XX_R184_WINYSTART}, /* WinYStart */
- {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, /* WinYWidth */
- {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, /* WinYCenter */
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */
+ {0xa0, 0x03, ZC3XX_R181_WINXSTART},
+ {0xa0, 0x08, ZC3XX_R182_WINXWIDTH},
+ {0xa0, 0x16, ZC3XX_R183_WINXCENTER},
+ {0xa0, 0x03, ZC3XX_R184_WINYSTART},
+ {0xa0, 0x05, ZC3XX_R185_WINYWIDTH},
+ {0xa0, 0x14, ZC3XX_R186_WINYCENTER},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
/* Auto exposure and white balance */
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* ExposureLimitHigh 0 */
- {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* ExposureLimitMid */
- {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW}, /* ExposureLimitLow 0xb1 */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* AntiFlickerHigh 0x00 */
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* AntiFlickerLow 0x00 */
- {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, /* AntiFlickerLow 0x87 */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* AEBFreeze 0x10 0x0c */
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* AEBUnfreeze 0x30 0x18 */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
/* sensor on */
{0xaa, 0x07, 0x00b1},
{0xaa, 0x05, 0x0003},
{0xaa, 0x04, 0x0001},
{0xaa, 0x03, 0x003b},
/* Gains */
- {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* DigitalLimitDiff */
- {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* DigitalGainStep */
- {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */
+ {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
/* Auto correction */
- {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
{0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
/* Gains */
- {0xa0, 0x40, ZC3XX_R116_RGAIN}, /* RGain */
- {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* GGain */
- {0xa0, 0x40, ZC3XX_R118_BGAIN}, /* BGain */
+ {0xa0, 0x40, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x40, ZC3XX_R118_BGAIN},
{0xa0, 0x00, 0x0007}, /* AutoCorrectEnable */
{0xa0, 0xff, ZC3XX_R018_FRAMELOST}, /* Frame adjust */
@@ -4459,8 +4456,8 @@ static const struct usb_action pb03303x_Initial[] = {
{0xa0, 0x50, ZC3XX_R112_RGB22},
{0xa1, 0x01, 0x0008},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00},
{0xa1, 0x01, 0x01c8},
{0xa1, 0x01, 0x01c9},
{0xa1, 0x01, 0x01ca},
@@ -5984,7 +5981,7 @@ static const struct usb_action tas5130c_vf0250_Initial[] = {
{0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */
{0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */
{0xaa, 0x15, 0x0004}, /* 00,15,04,aa */
- {0xaa, 0x01, 0x0000},
+/*?? {0xaa, 0x01, 0x0000}, */
{0xaa, 0x01, 0x0000},
{0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */
{0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */
@@ -6000,8 +5997,8 @@ static const struct usb_action tas5130c_vf0250_Initial[] = {
{0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */
{0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */
{0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */
- {0xa0, 0x00, 0x0039},
- {0xa1, 0x01, 0x0037},
+/*?? {0xa0, 0x00, 0x0039},
+ {0xa1, 0x01, 0x0037}, */
{0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */
{0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa, (e6 -> e8) */
{0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */
@@ -6272,7 +6269,7 @@ static void reg_w(struct usb_device *dev,
__u8 value,
__u16 index)
{
- PDEBUG(D_USBO, "reg w %02x -> [%04x]", value, index);
+ PDEBUG(D_USBO, "reg w [%04x] = %02x", index, value);
reg_w_i(dev, value, index);
}
@@ -6280,17 +6277,17 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev,
__u8 reg)
{
__u8 retbyte;
- __u8 retval[2];
+ __u16 retval;
reg_w_i(gspca_dev->dev, reg, 0x92);
reg_w_i(gspca_dev->dev, 0x02, 0x90); /* <- read command */
msleep(25);
retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
- retval[0] = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */
- retval[1] = reg_r_i(gspca_dev, 0x0096); /* read Hightbyte */
- PDEBUG(D_USBO, "i2c r [%02x] -> (%02x) %02x%02x",
- reg, retbyte, retval[1], retval[0]);
- return (retval[1] << 8) | retval[0];
+ retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */
+ retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */
+ PDEBUG(D_USBO, "i2c r [%02x] -> %04x (%02x)",
+ reg, retval, retbyte);
+ return retval;
}
static __u8 i2c_write(struct gspca_dev *gspca_dev,
@@ -6306,7 +6303,7 @@ static __u8 i2c_write(struct gspca_dev *gspca_dev,
reg_w_i(gspca_dev->dev, 0x01, 0x90); /* <- write command */
msleep(5);
retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
- PDEBUG(D_USBO, "i2c w [%02x] %02x%02x (%02x)",
+ PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)",
reg, valH, valL, retbyte);
return retbyte;
}
@@ -6349,6 +6346,8 @@ static void setmatrix(struct gspca_dev *gspca_dev)
{0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58};
static const __u8 po2030_matrix[9] =
{0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60};
+ static const __u8 vf0250_matrix[9] =
+ {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
switch (sd->sensor) {
case SENSOR_GC0305:
@@ -6363,8 +6362,9 @@ static void setmatrix(struct gspca_dev *gspca_dev)
case SENSOR_PO2030:
matrix = po2030_matrix;
break;
- case SENSOR_TAS5130C_VF0250: /* no matrix? */
- return;
+ case SENSOR_TAS5130C_VF0250:
+ matrix = vf0250_matrix;
+ break;
default: /* matrix already loaded */
return;
}
@@ -6744,7 +6744,7 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev)
return 0x04; /* CS2102 */
start_2wr_probe(dev, 0x06); /* OmniVision */
- reg_w(dev, 0x08, 0x8d);
+ reg_w(dev, 0x08, 0x008d);
i2c_write(gspca_dev, 0x11, 0xaa, 0x00);
retbyte = i2c_read(gspca_dev, 0x11);
if (retbyte != 0) {
@@ -6778,7 +6778,7 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev)
return 0x0c; /* ICM105A */
start_2wr_probe(dev, 0x0e); /* PAS202BCB */
- reg_w(dev, 0x08, 0x8d);
+ reg_w(dev, 0x08, 0x008d);
i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
msleep(500);
retbyte = i2c_read(gspca_dev, 0x03);
@@ -6830,7 +6830,6 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
{0x8001, 0x13},
{0x8000, 0x14}, /* CS2102K */
{0x8400, 0x15}, /* TAS5130K */
- {0, 0}
};
static int vga_3wr_probe(struct gspca_dev *gspca_dev)
@@ -6843,7 +6842,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
reg_w(dev, 0x02, 0x0010);
- reg_r(gspca_dev, 0x10);
+ reg_r(gspca_dev, 0x0010);
reg_w(dev, 0x01, 0x0000);
reg_w(dev, 0x00, 0x0010);
reg_w(dev, 0x01, 0x0001);
@@ -6869,17 +6868,15 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword);
reg_r(gspca_dev, 0x0010);
/* this is tested only once anyway */
- i = 0;
- while (chipset_revision_sensor[i].revision) {
+ for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
if (chipset_revision_sensor[i].revision == checkword) {
sd->chip_revision = checkword;
send_unknown(dev, SENSOR_PB0330);
return chipset_revision_sensor[i].internal_sensor_id;
}
- i++;
}
- reg_w(dev, 0x01, 0x0000);
+ reg_w(dev, 0x01, 0x0000); /* check ?? */
reg_w(dev, 0x01, 0x0001);
reg_w(dev, 0xdd, 0x008b);
reg_w(dev, 0x0a, 0x0010);
@@ -6901,8 +6898,11 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
retbyte = i2c_read(gspca_dev, 0x00);
if (retbyte != 0) {
PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte);
- send_unknown(dev, SENSOR_GC0305);
- return retbyte; /* 0x29 = gc0305 - should continue? */
+ if (retbyte == 0x11) /* VF0250 */
+ return 0x0250;
+ if (retbyte == 0x29) /* gc0305 */
+ send_unknown(dev, SENSOR_GC0305);
+ return retbyte;
}
reg_w(dev, 0x01, 0x0000); /* check OmniVision */
@@ -6918,18 +6918,18 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
return 0x06; /* OmniVision confirm ? */
}
- reg_w(dev, 0x01, 0x00);
- reg_w(dev, 0x00, 0x02);
- reg_w(dev, 0x01, 0x10);
- reg_w(dev, 0x01, 0x01);
- reg_w(dev, 0xee, 0x8b);
- reg_w(dev, 0x03, 0x12);
+ reg_w(dev, 0x01, 0x0000);
+ reg_w(dev, 0x00, 0x0002);
+ reg_w(dev, 0x01, 0x0010);
+ reg_w(dev, 0x01, 0x0001);
+ reg_w(dev, 0xee, 0x008b);
+ reg_w(dev, 0x03, 0x0012);
/* msleep(150); */
- reg_w(dev, 0x01, 0x12);
- reg_w(dev, 0x05, 0x12);
- retbyte = i2c_read(gspca_dev, 0x00); /* ID 0 */
+ reg_w(dev, 0x01, 0x0012);
+ reg_w(dev, 0x05, 0x0012);
+ retbyte = i2c_read(gspca_dev, 0x0000); /* ID 0 */
checkword = retbyte << 8;
- retbyte = i2c_read(gspca_dev, 0x01); /* ID 1 */
+ retbyte = i2c_read(gspca_dev, 0x0001); /* ID 1 */
checkword |= retbyte;
PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword);
if (checkword == 0x2030) {
@@ -6939,14 +6939,14 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
return checkword;
}
- reg_w(dev, 0x01, 0x00);
- reg_w(dev, 0x0a, 0x10);
- reg_w(dev, 0xd3, 0x8b);
- reg_w(dev, 0x01, 0x01);
- reg_w(dev, 0x03, 0x12);
- reg_w(dev, 0x01, 0x12);
- reg_w(dev, 0x05, 0x01);
- reg_w(dev, 0xd3, 0x8b);
+ reg_w(dev, 0x01, 0x0000);
+ reg_w(dev, 0x0a, 0x0010);
+ reg_w(dev, 0xd3, 0x008b);
+ reg_w(dev, 0x01, 0x0001);
+ reg_w(dev, 0x03, 0x0012);
+ reg_w(dev, 0x01, 0x0012);
+ reg_w(dev, 0x05, 0x0001);
+ reg_w(dev, 0xd3, 0x008b);
retbyte = i2c_read(gspca_dev, 0x01);
if (retbyte != 0) {
PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
@@ -6962,7 +6962,9 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
switch (sd->sensor) {
case SENSOR_MC501CB:
+ return -1; /* don't probe */
case SENSOR_TAS5130C_VF0250:
+ /* may probe but with write in reg 0x0010 */
return -1; /* don't probe */
}
sensor = vga_2wr_probe(gspca_dev);
@@ -7010,30 +7012,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* define some sensors from the vendor/product */
sd->sharpness = 2;
- switch (id->idVendor) {
- case 0x041e: /* Creative */
- switch (id->idProduct) {
- case 0x4051: /* zc301 chips */
- case 0x4053:
- sd->sensor = SENSOR_TAS5130C_VF0250;
- break;
- }
- break;
- case 0x046d: /* Logitech Labtec */
- switch (id->idProduct) {
- case 0x08dd:
- sd->sensor = SENSOR_MC501CB;
- break;
- }
- break;
- case 0x0ac8: /* Vimicro z-star */
- switch (id->idProduct) {
- case 0x305b:
- sd->sensor = SENSOR_TAS5130C_VF0250;
- break;
- }
- break;
- }
+ sd->sensor = id->driver_info;
sensor = zcxx_probeSensor(gspca_dev);
if (sensor >= 0)
PDEBUG(D_PROBE, "probe sensor -> %02x", sensor);
@@ -7119,6 +7098,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "Find Sensor GC0305");
sd->sensor = SENSOR_GC0305;
break;
+ case 0x0250:
+ PDEBUG(D_PROBE, "Sensor Tas5130 (VF0250)");
+ sd->sensor = SENSOR_TAS5130C_VF0250;
+ break;
case 0x2030:
PDEBUG(D_PROBE, "Find Sensor PO2030");
sd->sensor = SENSOR_PO2030;
@@ -7146,7 +7129,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
cam = &gspca_dev->cam;
- cam->dev_name = (char *) id->driver_info;
cam->epaddr = 0x01;
/*fixme:test*/
gspca_dev->nbalt--;
@@ -7235,6 +7217,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
case SENSOR_GC0305:
case SENSOR_OV7620:
case SENSOR_PO2030:
+ case SENSOR_TAS5130C_VF0250:
msleep(100); /* ?? */
reg_r(gspca_dev, 0x0002); /* --> 0x40 */
reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
@@ -7515,70 +7498,69 @@ static const struct sd_desc sd_desc = {
.querymenu = sd_querymenu,
};
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x041e, 0x041e), DVNM("Creative WebCam Live!")},
+ {USB_DEVICE(0x041e, 0x041e)},
#ifndef CONFIG_USB_ZC0301
- {USB_DEVICE(0x041e, 0x4017), DVNM("Creative Webcam Mobile PD1090")},
- {USB_DEVICE(0x041e, 0x401c), DVNM("Creative NX")},
- {USB_DEVICE(0x041e, 0x401e), DVNM("Creative Nx Pro")},
- {USB_DEVICE(0x041e, 0x401f), DVNM("Creative Webcam Notebook PD1171")},
+ {USB_DEVICE(0x041e, 0x4017)},
+ {USB_DEVICE(0x041e, 0x401c)},
+ {USB_DEVICE(0x041e, 0x401e)},
+ {USB_DEVICE(0x041e, 0x401f)},
#endif
- {USB_DEVICE(0x041e, 0x4029), DVNM("Creative WebCam Vista Pro")},
+ {USB_DEVICE(0x041e, 0x4029)},
#ifndef CONFIG_USB_ZC0301
- {USB_DEVICE(0x041e, 0x4034), DVNM("Creative Instant P0620")},
- {USB_DEVICE(0x041e, 0x4035), DVNM("Creative Instant P0620D")},
- {USB_DEVICE(0x041e, 0x4036), DVNM("Creative Live !")},
- {USB_DEVICE(0x041e, 0x403a), DVNM("Creative Nx Pro 2")},
+ {USB_DEVICE(0x041e, 0x4034)},
+ {USB_DEVICE(0x041e, 0x4035)},
+ {USB_DEVICE(0x041e, 0x4036)},
+ {USB_DEVICE(0x041e, 0x403a)},
#endif
- {USB_DEVICE(0x041e, 0x4051), DVNM("Creative Notebook Pro (VF0250)")},
- {USB_DEVICE(0x041e, 0x4053), DVNM("Creative Live!Cam Video IM")},
+ {USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_TAS5130C_VF0250},
+ {USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_TAS5130C_VF0250},
#ifndef CONFIG_USB_ZC0301
- {USB_DEVICE(0x0458, 0x7007), DVNM("Genius VideoCam V2")},
- {USB_DEVICE(0x0458, 0x700c), DVNM("Genius VideoCam V3")},
- {USB_DEVICE(0x0458, 0x700f), DVNM("Genius VideoCam Web V2")},
+ {USB_DEVICE(0x0458, 0x7007)},
+ {USB_DEVICE(0x0458, 0x700c)},
+ {USB_DEVICE(0x0458, 0x700f)},
#endif
- {USB_DEVICE(0x0461, 0x0a00), DVNM("MicroInnovation WebCam320")},
- {USB_DEVICE(0x046d, 0x08a0), DVNM("Logitech QC IM")},
- {USB_DEVICE(0x046d, 0x08a1), DVNM("Logitech QC IM 0x08A1 +sound")},
- {USB_DEVICE(0x046d, 0x08a2), DVNM("Labtec Webcam Pro")},
- {USB_DEVICE(0x046d, 0x08a3), DVNM("Logitech QC Chat")},
- {USB_DEVICE(0x046d, 0x08a6), DVNM("Logitech QCim")},
- {USB_DEVICE(0x046d, 0x08a7), DVNM("Logitech QuickCam Image")},
- {USB_DEVICE(0x046d, 0x08a9), DVNM("Logitech Notebook Deluxe")},
- {USB_DEVICE(0x046d, 0x08aa), DVNM("Labtec Webcam Notebook")},
- {USB_DEVICE(0x046d, 0x08ac), DVNM("Logitech QuickCam Cool")},
- {USB_DEVICE(0x046d, 0x08ad), DVNM("Logitech QCCommunicate STX")},
+ {USB_DEVICE(0x0461, 0x0a00)},
+ {USB_DEVICE(0x046d, 0x08a0)},
+ {USB_DEVICE(0x046d, 0x08a1)},
+ {USB_DEVICE(0x046d, 0x08a2)},
+ {USB_DEVICE(0x046d, 0x08a3)},
+ {USB_DEVICE(0x046d, 0x08a6)},
+ {USB_DEVICE(0x046d, 0x08a7)},
+ {USB_DEVICE(0x046d, 0x08a9)},
+ {USB_DEVICE(0x046d, 0x08aa)},
+ {USB_DEVICE(0x046d, 0x08ac)},
+ {USB_DEVICE(0x046d, 0x08ad)},
#ifndef CONFIG_USB_ZC0301
- {USB_DEVICE(0x046d, 0x08ae), DVNM("Logitech QuickCam for Notebooks")},
+ {USB_DEVICE(0x046d, 0x08ae)},
#endif
- {USB_DEVICE(0x046d, 0x08af), DVNM("Logitech QuickCam Cool")},
- {USB_DEVICE(0x046d, 0x08b9), DVNM("Logitech QC IM ???")},
- {USB_DEVICE(0x046d, 0x08d7), DVNM("Logitech QCam STX")},
- {USB_DEVICE(0x046d, 0x08d9), DVNM("Logitech QuickCam IM/Connect")},
- {USB_DEVICE(0x046d, 0x08d8), DVNM("Logitech Notebook Deluxe")},
- {USB_DEVICE(0x046d, 0x08da), DVNM("Logitech QuickCam Messenger")},
- {USB_DEVICE(0x046d, 0x08dd), DVNM("Logitech QuickCam for Notebooks")},
- {USB_DEVICE(0x0471, 0x0325), DVNM("Philips SPC 200 NC")},
- {USB_DEVICE(0x0471, 0x0326), DVNM("Philips SPC 300 NC")},
- {USB_DEVICE(0x0471, 0x032d), DVNM("Philips spc210nc")},
- {USB_DEVICE(0x0471, 0x032e), DVNM("Philips spc315nc")},
- {USB_DEVICE(0x055f, 0xc005), DVNM("Mustek Wcam300A")},
+ {USB_DEVICE(0x046d, 0x08af)},
+ {USB_DEVICE(0x046d, 0x08b9)},
+ {USB_DEVICE(0x046d, 0x08d7)},
+ {USB_DEVICE(0x046d, 0x08d9)},
+ {USB_DEVICE(0x046d, 0x08d8)},
+ {USB_DEVICE(0x046d, 0x08da)},
+ {USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB},
+ {USB_DEVICE(0x0471, 0x0325)},
+ {USB_DEVICE(0x0471, 0x0326)},
+ {USB_DEVICE(0x0471, 0x032d)},
+ {USB_DEVICE(0x0471, 0x032e)},
+ {USB_DEVICE(0x055f, 0xc005)},
#ifndef CONFIG_USB_ZC0301
- {USB_DEVICE(0x055f, 0xd003), DVNM("Mustek WCam300A")},
- {USB_DEVICE(0x055f, 0xd004), DVNM("Mustek WCam300 AN")},
+ {USB_DEVICE(0x055f, 0xd003)},
+ {USB_DEVICE(0x055f, 0xd004)},
#endif
- {USB_DEVICE(0x0698, 0x2003), DVNM("CTX M730V built in")},
- {USB_DEVICE(0x0ac8, 0x0302), DVNM("Z-star Vimicro zc0302")},
+ {USB_DEVICE(0x0698, 0x2003)},
+ {USB_DEVICE(0x0ac8, 0x0302)},
#ifndef CONFIG_USB_ZC0301
- {USB_DEVICE(0x0ac8, 0x301b), DVNM("Z-Star zc301b")},
- {USB_DEVICE(0x0ac8, 0x303b), DVNM("Vimicro 0x303b")},
+ {USB_DEVICE(0x0ac8, 0x301b)},
+ {USB_DEVICE(0x0ac8, 0x303b)},
#endif
- {USB_DEVICE(0x0ac8, 0x305b), DVNM("Z-star Vimicro zc0305b")},
+ {USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250},
#ifndef CONFIG_USB_ZC0301
- {USB_DEVICE(0x0ac8, 0x307b), DVNM("Z-Star 307b")},
- {USB_DEVICE(0x10fd, 0x0128), DVNM("Typhoon Webshot II 300k 0x0128")},
- {USB_DEVICE(0x10fd, 0x8050), DVNM("Typhoon Webshot II USB 300k")},
+ {USB_DEVICE(0x0ac8, 0x307b)},
+ {USB_DEVICE(0x10fd, 0x0128)},
+ {USB_DEVICE(0x10fd, 0x8050)},
#endif
{} /* end of entry */
};
@@ -7605,7 +7587,7 @@ static int __init sd_mod_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "v%s registered", version);
+ PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig
index 5d7ee8fcdd5..0069898bdda 100644
--- a/drivers/media/video/ivtv/Kconfig
+++ b/drivers/media/video/ivtv/Kconfig
@@ -2,9 +2,7 @@ config VIDEO_IVTV
tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support"
depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL
depends on INPUT # due to VIDEO_IR
- depends on HOTPLUG # due to FW_LOADER
select I2C_ALGOBIT
- select FW_LOADER
select VIDEO_IR
select VIDEO_TUNER
select VIDEO_TVEEPROM
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 41fd79279bb..aea1664948c 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -465,9 +465,8 @@ static void ivtv_process_eeprom(struct ivtv *itv)
if (itv->options.radio == -1)
itv->options.radio = (tv.has_radio != 0);
/* only enable newi2c if an IR blaster is present */
- /* FIXME: for 2.6.20 the test against 2 should be removed */
- if (itv->options.newi2c == -1 && tv.has_ir != -1 && tv.has_ir != 2) {
- itv->options.newi2c = (tv.has_ir & 2) ? 1 : 0;
+ if (itv->options.newi2c == -1 && tv.has_ir) {
+ itv->options.newi2c = (tv.has_ir & 4) ? 1 : 0;
if (itv->options.newi2c) {
IVTV_INFO("Reopen i2c bus for IR-blaster support\n");
exit_ivtv_i2c(itv);
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index a08bb3331cf..ab287b48fc2 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -60,6 +60,7 @@
#include <linux/dvb/video.h>
#include <linux/dvb/audio.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/tuner.h>
#include <media/cx2341x.h>
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 52e00a7f311..61030309d0a 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1842,69 +1842,73 @@ int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
return res;
}
-void ivtv_set_funcs(struct video_device *vdev)
-{
- vdev->vidioc_querycap = ivtv_querycap;
- vdev->vidioc_g_priority = ivtv_g_priority;
- vdev->vidioc_s_priority = ivtv_s_priority;
- vdev->vidioc_s_audio = ivtv_s_audio;
- vdev->vidioc_g_audio = ivtv_g_audio;
- vdev->vidioc_enumaudio = ivtv_enumaudio;
- vdev->vidioc_s_audout = ivtv_s_audout;
- vdev->vidioc_g_audout = ivtv_g_audout;
- vdev->vidioc_enum_input = ivtv_enum_input;
- vdev->vidioc_enum_output = ivtv_enum_output;
- vdev->vidioc_enumaudout = ivtv_enumaudout;
- vdev->vidioc_cropcap = ivtv_cropcap;
- vdev->vidioc_s_crop = ivtv_s_crop;
- vdev->vidioc_g_crop = ivtv_g_crop;
- vdev->vidioc_g_input = ivtv_g_input;
- vdev->vidioc_s_input = ivtv_s_input;
- vdev->vidioc_g_output = ivtv_g_output;
- vdev->vidioc_s_output = ivtv_s_output;
- vdev->vidioc_g_frequency = ivtv_g_frequency;
- vdev->vidioc_s_frequency = ivtv_s_frequency;
- vdev->vidioc_s_tuner = ivtv_s_tuner;
- vdev->vidioc_g_tuner = ivtv_g_tuner;
- vdev->vidioc_g_enc_index = ivtv_g_enc_index;
- vdev->vidioc_g_fbuf = ivtv_g_fbuf;
- vdev->vidioc_s_fbuf = ivtv_s_fbuf;
- vdev->vidioc_g_std = ivtv_g_std;
- vdev->vidioc_s_std = ivtv_s_std;
- vdev->vidioc_overlay = ivtv_overlay;
- vdev->vidioc_log_status = ivtv_log_status;
- vdev->vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap;
- vdev->vidioc_encoder_cmd = ivtv_encoder_cmd;
- vdev->vidioc_try_encoder_cmd = ivtv_try_encoder_cmd;
- vdev->vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out;
- vdev->vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap;
- vdev->vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap;
- vdev->vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap;
- vdev->vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out;
- vdev->vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay;
- vdev->vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out;
- vdev->vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap;
- vdev->vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap;
- vdev->vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap;
- vdev->vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out;
- vdev->vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay;
- vdev->vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out;
- vdev->vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap;
- vdev->vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap;
- vdev->vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap;
- vdev->vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out;
- vdev->vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay;
- vdev->vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out;
- vdev->vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap;
- vdev->vidioc_g_chip_ident = ivtv_g_chip_ident;
+static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
+ .vidioc_querycap = ivtv_querycap,
+ .vidioc_g_priority = ivtv_g_priority,
+ .vidioc_s_priority = ivtv_s_priority,
+ .vidioc_s_audio = ivtv_s_audio,
+ .vidioc_g_audio = ivtv_g_audio,
+ .vidioc_enumaudio = ivtv_enumaudio,
+ .vidioc_s_audout = ivtv_s_audout,
+ .vidioc_g_audout = ivtv_g_audout,
+ .vidioc_enum_input = ivtv_enum_input,
+ .vidioc_enum_output = ivtv_enum_output,
+ .vidioc_enumaudout = ivtv_enumaudout,
+ .vidioc_cropcap = ivtv_cropcap,
+ .vidioc_s_crop = ivtv_s_crop,
+ .vidioc_g_crop = ivtv_g_crop,
+ .vidioc_g_input = ivtv_g_input,
+ .vidioc_s_input = ivtv_s_input,
+ .vidioc_g_output = ivtv_g_output,
+ .vidioc_s_output = ivtv_s_output,
+ .vidioc_g_frequency = ivtv_g_frequency,
+ .vidioc_s_frequency = ivtv_s_frequency,
+ .vidioc_s_tuner = ivtv_s_tuner,
+ .vidioc_g_tuner = ivtv_g_tuner,
+ .vidioc_g_enc_index = ivtv_g_enc_index,
+ .vidioc_g_fbuf = ivtv_g_fbuf,
+ .vidioc_s_fbuf = ivtv_s_fbuf,
+ .vidioc_g_std = ivtv_g_std,
+ .vidioc_s_std = ivtv_s_std,
+ .vidioc_overlay = ivtv_overlay,
+ .vidioc_log_status = ivtv_log_status,
+ .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
+ .vidioc_encoder_cmd = ivtv_encoder_cmd,
+ .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
+ .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
+ .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
+ .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
+ .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
+ .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
+ .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
+ .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
+ .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
+ .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
+ .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
+ .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
+ .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
+ .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
+ .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
+ .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
+ .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
+ .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
+ .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
+ .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
+ .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
+ .vidioc_g_chip_ident = ivtv_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
- vdev->vidioc_g_register = ivtv_g_register;
- vdev->vidioc_s_register = ivtv_s_register;
+ .vidioc_g_register = ivtv_g_register,
+ .vidioc_s_register = ivtv_s_register,
#endif
- vdev->vidioc_default = ivtv_default;
- vdev->vidioc_queryctrl = ivtv_queryctrl;
- vdev->vidioc_querymenu = ivtv_querymenu;
- vdev->vidioc_g_ext_ctrls = ivtv_g_ext_ctrls;
- vdev->vidioc_s_ext_ctrls = ivtv_s_ext_ctrls;
- vdev->vidioc_try_ext_ctrls = ivtv_try_ext_ctrls;
+ .vidioc_default = ivtv_default,
+ .vidioc_queryctrl = ivtv_queryctrl,
+ .vidioc_querymenu = ivtv_querymenu,
+ .vidioc_g_ext_ctrls = ivtv_g_ext_ctrls,
+ .vidioc_s_ext_ctrls = ivtv_s_ext_ctrls,
+ .vidioc_try_ext_ctrls = ivtv_try_ext_ctrls,
+};
+
+void ivtv_set_funcs(struct video_device *vdev)
+{
+ vdev->ioctl_ops = &ivtv_ioctl_ops;
}
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index f8883b487f4..54d2023b26c 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -208,16 +208,11 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
return -ENOMEM;
}
- s->v4l2dev->type = VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_TELETEXT |
- VID_TYPE_CLIPPING | VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER;
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
- s->v4l2dev->type |= VID_TYPE_MPEG_DECODER;
- }
snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d %s",
itv->num, s->name);
s->v4l2dev->minor = minor;
- s->v4l2dev->dev = &itv->dev->dev;
+ s->v4l2dev->parent = &itv->dev->dev;
s->v4l2dev->fops = ivtv_stream_info[type].fops;
s->v4l2dev->release = video_device_release;
s->v4l2dev->tvnorms = V4L2_STD_ALL;
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
index 39bf6b114d5..89a781c6929 100644
--- a/drivers/media/video/m52790.c
+++ b/drivers/media/video/m52790.c
@@ -26,7 +26,7 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/m52790.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 2fb5854cf6f..7c8ef6ac6c3 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -31,6 +31,7 @@
#include <linux/init.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/delay.h>
@@ -1697,13 +1698,7 @@ static const struct file_operations meye_fops = {
.llseek = no_llseek,
};
-static struct video_device meye_template = {
- .owner = THIS_MODULE,
- .name = "meye",
- .type = VID_TYPE_CAPTURE,
- .fops = &meye_fops,
- .release = video_device_release,
- .minor = -1,
+static const struct v4l2_ioctl_ops meye_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input = vidioc_g_input,
@@ -1724,6 +1719,14 @@ static struct video_device meye_template = {
.vidioc_default = vidioc_default,
};
+static struct video_device meye_template = {
+ .name = "meye",
+ .fops = &meye_fops,
+ .ioctl_ops = &meye_ioctl_ops,
+ .release = video_device_release,
+ .minor = -1,
+};
+
#ifdef CONFIG_PM
static int meye_suspend(struct pci_dev *pdev, pm_message_t state)
{
@@ -1801,7 +1804,7 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
}
memcpy(meye.video_dev, &meye_template, sizeof(meye_template));
- meye.video_dev->dev = &meye.mchip_dev->dev;
+ meye.video_dev->parent = &meye.mchip_dev->dev;
if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) {
printk(KERN_ERR "meye: unable to power on the camera\n");
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 5691e019d19..3da74dcee90 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -51,9 +51,9 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
-#include <linux/videodev.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/v4l2-i2c-drv-legacy.h>
#include <media/tvaudio.h>
#include <media/msp3400.h>
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
index 1622f70e4dd..846a14a61fd 100644
--- a/drivers/media/video/msp3400-kthreads.c
+++ b/drivers/media/video/msp3400-kthreads.c
@@ -25,7 +25,6 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/freezer.h>
-#include <linux/videodev.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/msp3400.h>
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index ee43499544c..554d2295484 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -120,7 +120,7 @@ static int mt9m001_init(struct soc_camera_device *icd)
int ret;
/* Disable chip, synchronous option update */
- dev_dbg(icd->vdev->dev, "%s\n", __func__);
+ dev_dbg(icd->vdev->parent, "%s\n", __func__);
ret = reg_write(icd, MT9M001_RESET, 1);
if (ret >= 0)
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
index eafb0c7736e..9edaca4371d 100644
--- a/drivers/media/video/ov511.c
+++ b/drivers/media/video/ov511.c
@@ -4666,9 +4666,7 @@ static const struct file_operations ov511_fops = {
};
static struct video_device vdev_template = {
- .owner = THIS_MODULE,
.name = "OV511 USB Camera",
- .type = VID_TYPE_CAPTURE,
.fops = &ov511_fops,
.release = video_device_release,
.minor = -1,
@@ -5661,43 +5659,43 @@ static int ov_create_sysfs(struct video_device *vdev)
{
int rc;
- rc = video_device_create_file(vdev, &dev_attr_custom_id);
+ rc = device_create_file(&vdev->dev, &dev_attr_custom_id);
if (rc) goto err;
- rc = video_device_create_file(vdev, &dev_attr_model);
+ rc = device_create_file(&vdev->dev, &dev_attr_model);
if (rc) goto err_id;
- rc = video_device_create_file(vdev, &dev_attr_bridge);
+ rc = device_create_file(&vdev->dev, &dev_attr_bridge);
if (rc) goto err_model;
- rc = video_device_create_file(vdev, &dev_attr_sensor);
+ rc = device_create_file(&vdev->dev, &dev_attr_sensor);
if (rc) goto err_bridge;
- rc = video_device_create_file(vdev, &dev_attr_brightness);
+ rc = device_create_file(&vdev->dev, &dev_attr_brightness);
if (rc) goto err_sensor;
- rc = video_device_create_file(vdev, &dev_attr_saturation);
+ rc = device_create_file(&vdev->dev, &dev_attr_saturation);
if (rc) goto err_bright;
- rc = video_device_create_file(vdev, &dev_attr_contrast);
+ rc = device_create_file(&vdev->dev, &dev_attr_contrast);
if (rc) goto err_sat;
- rc = video_device_create_file(vdev, &dev_attr_hue);
+ rc = device_create_file(&vdev->dev, &dev_attr_hue);
if (rc) goto err_contrast;
- rc = video_device_create_file(vdev, &dev_attr_exposure);
+ rc = device_create_file(&vdev->dev, &dev_attr_exposure);
if (rc) goto err_hue;
return 0;
err_hue:
- video_device_remove_file(vdev, &dev_attr_hue);
+ device_remove_file(&vdev->dev, &dev_attr_hue);
err_contrast:
- video_device_remove_file(vdev, &dev_attr_contrast);
+ device_remove_file(&vdev->dev, &dev_attr_contrast);
err_sat:
- video_device_remove_file(vdev, &dev_attr_saturation);
+ device_remove_file(&vdev->dev, &dev_attr_saturation);
err_bright:
- video_device_remove_file(vdev, &dev_attr_brightness);
+ device_remove_file(&vdev->dev, &dev_attr_brightness);
err_sensor:
- video_device_remove_file(vdev, &dev_attr_sensor);
+ device_remove_file(&vdev->dev, &dev_attr_sensor);
err_bridge:
- video_device_remove_file(vdev, &dev_attr_bridge);
+ device_remove_file(&vdev->dev, &dev_attr_bridge);
err_model:
- video_device_remove_file(vdev, &dev_attr_model);
+ device_remove_file(&vdev->dev, &dev_attr_model);
err_id:
- video_device_remove_file(vdev, &dev_attr_custom_id);
+ device_remove_file(&vdev->dev, &dev_attr_custom_id);
err:
return rc;
}
@@ -5833,7 +5831,7 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
goto error;
memcpy(ov->vdev, &vdev_template, sizeof(*ov->vdev));
- ov->vdev->dev = &intf->dev;
+ ov->vdev->parent = &intf->dev;
video_set_drvdata(ov->vdev, ov);
for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) {
diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h
index 1010e51189b..baded1262ca 100644
--- a/drivers/media/video/ov511.h
+++ b/drivers/media/video/ov511.h
@@ -4,6 +4,7 @@
#include <asm/uaccess.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/usb.h>
#include <linux/mutex.h>
diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c
index 36047d4e70f..e69de29bb2d 100644
--- a/drivers/media/video/planb.c
+++ b/drivers/media/video/planb.c
@@ -1,2309 +0,0 @@
-/*
- planb - PlanB frame grabber driver
-
- PlanB is used in the 7x00/8x00 series of PowerMacintosh
- Computers as video input DMA controller.
-
- Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
-
- Based largely on the bttv driver by Ralph Metzler (rjkm@thp.uni-koeln.de)
-
- Additional debugging and coding by Takashi Oe (toe@unlserve.unl.edu)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* $Id: planb.c,v 1.18 1999/05/02 17:36:34 mlan Exp $ */
-
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/vmalloc.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
-#include <linux/wait.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/dbdma.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/irq.h>
-#include <linux/mutex.h>
-
-#include "planb.h"
-#include "saa7196.h"
-
-/* Would you mind for some ugly debugging? */
-#if 0
-#define DEBUG(x...) printk(KERN_DEBUG ## x) /* Debug driver */
-#else
-#define DEBUG(x...) /* Don't debug driver */
-#endif
-
-#if 0
-#define IDEBUG(x...) printk(KERN_DEBUG ## x) /* Debug interrupt part */
-#else
-#define IDEBUG(x...) /* Don't debug interrupt part */
-#endif
-
-/* Ever seen a Mac with more than 1 of these? */
-#define PLANB_MAX 1
-
-static int planb_num;
-static struct planb planbs[PLANB_MAX];
-static volatile struct planb_registers *planb_regs;
-
-static int def_norm = PLANB_DEF_NORM; /* default norm */
-static int video_nr = -1;
-
-module_param(def_norm, int, 0);
-MODULE_PARM_DESC(def_norm, "Default startup norm (0=PAL, 1=NTSC, 2=SECAM)");
-module_param(video_nr, int, 0);
-MODULE_LICENSE("GPL");
-
-
-/* ------------------ PlanB Exported Functions ------------------ */
-static long planb_write(struct video_device *, const char *, unsigned long, int);
-static long planb_read(struct video_device *, char *, unsigned long, int);
-static int planb_open(struct video_device *, int);
-static void planb_close(struct video_device *);
-static int planb_ioctl(struct video_device *, unsigned int, void *);
-static int planb_init_done(struct video_device *);
-static int planb_mmap(struct video_device *, const char *, unsigned long);
-static void release_planb(void);
-int init_planbs(struct video_init *);
-
-/* ------------------ PlanB Internal Functions ------------------ */
-static int planb_prepare_open(struct planb *);
-static void planb_prepare_close(struct planb *);
-static void saa_write_reg(unsigned char, unsigned char);
-static unsigned char saa_status(int, struct planb *);
-static void saa_set(unsigned char, unsigned char, struct planb *);
-static void saa_init_regs(struct planb *);
-static int grabbuf_alloc(struct planb *);
-static int vgrab(struct planb *, struct video_mmap *);
-static void add_clip(struct planb *, struct video_clip *);
-static void fill_cmd_buff(struct planb *);
-static void cmd_buff(struct planb *);
-static volatile struct dbdma_cmd *setup_grab_cmd(int, struct planb *);
-static void overlay_start(struct planb *);
-static void overlay_stop(struct planb *);
-static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *, unsigned short,
- unsigned int);
-static inline void tab_cmd_store(volatile struct dbdma_cmd *, unsigned int,
- unsigned int);
-static inline void tab_cmd_gen(volatile struct dbdma_cmd *, unsigned short,
- unsigned short, unsigned int, unsigned int);
-static int init_planb(struct planb *);
-static int find_planb(void);
-static void planb_pre_capture(int, int, struct planb *);
-static volatile struct dbdma_cmd *cmd_geo_setup(volatile struct dbdma_cmd *,
- int, int, int, int, int, struct planb *);
-static inline void planb_dbdma_stop(volatile struct dbdma_regs *);
-static unsigned int saa_geo_setup(int, int, int, int, struct planb *);
-static inline int overlay_is_active(struct planb *);
-
-/*******************************/
-/* Memory management functions */
-/*******************************/
-
-static int grabbuf_alloc(struct planb *pb)
-{
- int i, npage;
-
- npage = MAX_GBUFFERS * ((PLANB_MAX_FBUF / PAGE_SIZE + 1)
-#ifndef PLANB_GSCANLINE
- + MAX_LNUM
-#endif /* PLANB_GSCANLINE */
- );
- if ((pb->rawbuf = kmalloc(npage
- * sizeof(unsigned long), GFP_KERNEL)) == 0)
- return -ENOMEM;
- for (i = 0; i < npage; i++) {
- pb->rawbuf[i] = (unsigned char *)__get_free_pages(GFP_KERNEL
- |GFP_DMA, 0);
- if (!pb->rawbuf[i])
- break;
- SetPageReserved(virt_to_page(pb->rawbuf[i]));
- }
- if (i-- < npage) {
- printk(KERN_DEBUG "PlanB: init_grab: grab buffer not allocated\n");
- for (; i > 0; i--) {
- ClearPageReserved(virt_to_page(pb->rawbuf[i]));
- free_pages((unsigned long)pb->rawbuf[i], 0);
- }
- kfree(pb->rawbuf);
- return -ENOBUFS;
- }
- pb->rawbuf_size = npage;
- return 0;
-}
-
-/*****************************/
-/* Hardware access functions */
-/*****************************/
-
-static void saa_write_reg(unsigned char addr, unsigned char val)
-{
- planb_regs->saa_addr = addr; eieio();
- planb_regs->saa_regval = val; eieio();
- return;
-}
-
-/* return status byte 0 or 1: */
-static unsigned char saa_status(int byte, struct planb *pb)
-{
- saa_regs[pb->win.norm][SAA7196_STDC] =
- (saa_regs[pb->win.norm][SAA7196_STDC] & ~2) | ((byte & 1) << 1);
- saa_write_reg (SAA7196_STDC, saa_regs[pb->win.norm][SAA7196_STDC]);
-
- /* Let's wait 30msec for this one */
- msleep_interruptible(30);
-
- return (unsigned char)in_8 (&planb_regs->saa_status);
-}
-
-static void saa_set(unsigned char addr, unsigned char val, struct planb *pb)
-{
- if(saa_regs[pb->win.norm][addr] != val) {
- saa_regs[pb->win.norm][addr] = val;
- saa_write_reg (addr, val);
- }
- return;
-}
-
-static void saa_init_regs(struct planb *pb)
-{
- int i;
-
- for (i = 0; i < SAA7196_NUMREGS; i++)
- saa_write_reg (i, saa_regs[pb->win.norm][i]);
-}
-
-static unsigned int saa_geo_setup(int width, int height, int interlace, int bpp,
- struct planb *pb)
-{
- int ht, norm = pb->win.norm;
-
- switch(bpp) {
- case 2:
- /* RGB555+a 1x16-bit + 16-bit transparent */
- saa_regs[norm][SAA7196_FMTS] &= ~0x3;
- break;
- case 1:
- case 4:
- /* RGB888 1x24-bit + 8-bit transparent */
- saa_regs[norm][SAA7196_FMTS] &= ~0x1;
- saa_regs[norm][SAA7196_FMTS] |= 0x2;
- break;
- default:
- return -EINVAL;
- }
- ht = (interlace ? height / 2 : height);
- saa_regs[norm][SAA7196_OUTPIX] = (unsigned char) (width & 0x00ff);
- saa_regs[norm][SAA7196_HFILT] = (saa_regs[norm][SAA7196_HFILT] & ~0x3)
- | (width >> 8 & 0x3);
- saa_regs[norm][SAA7196_OUTLINE] = (unsigned char) (ht & 0xff);
- saa_regs[norm][SAA7196_VYP] = (saa_regs[norm][SAA7196_VYP] & ~0x3)
- | (ht >> 8 & 0x3);
- /* feed both fields if interlaced, or else feed only even fields */
- saa_regs[norm][SAA7196_FMTS] = (interlace) ?
- (saa_regs[norm][SAA7196_FMTS] & ~0x60)
- : (saa_regs[norm][SAA7196_FMTS] | 0x60);
- /* transparent mode; extended format enabled */
- saa_regs[norm][SAA7196_DPATH] |= 0x3;
-
- return 0;
-}
-
-/***************************/
-/* DBDMA support functions */
-/***************************/
-
-static inline void planb_dbdma_restart(volatile struct dbdma_regs *ch)
-{
- out_le32(&ch->control, PLANB_CLR(RUN));
- out_le32(&ch->control, PLANB_SET(RUN|WAKE) | PLANB_CLR(PAUSE));
-}
-
-static inline void planb_dbdma_stop(volatile struct dbdma_regs *ch)
-{
- int i = 0;
-
- out_le32(&ch->control, PLANB_CLR(RUN) | PLANB_SET(FLUSH));
- while((in_le32(&ch->status) == (ACTIVE | FLUSH)) && (i < 999)) {
- IDEBUG("PlanB: waiting for DMA to stop\n");
- i++;
- }
-}
-
-static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *ch,
- unsigned short command, unsigned int cmd_dep)
-{
- st_le16(&ch->command, command);
- st_le32(&ch->cmd_dep, cmd_dep);
-}
-
-static inline void tab_cmd_store(volatile struct dbdma_cmd *ch,
- unsigned int phy_addr, unsigned int cmd_dep)
-{
- st_le16(&ch->command, STORE_WORD | KEY_SYSTEM);
- st_le16(&ch->req_count, 4);
- st_le32(&ch->phy_addr, phy_addr);
- st_le32(&ch->cmd_dep, cmd_dep);
-}
-
-static inline void tab_cmd_gen(volatile struct dbdma_cmd *ch,
- unsigned short command, unsigned short req_count,
- unsigned int phy_addr, unsigned int cmd_dep)
-{
- st_le16(&ch->command, command);
- st_le16(&ch->req_count, req_count);
- st_le32(&ch->phy_addr, phy_addr);
- st_le32(&ch->cmd_dep, cmd_dep);
-}
-
-static volatile struct dbdma_cmd *cmd_geo_setup(
- volatile struct dbdma_cmd *c1, int width, int height, int interlace,
- int bpp, int clip, struct planb *pb)
-{
- int norm = pb->win.norm;
-
- if((saa_geo_setup(width, height, interlace, bpp, pb)) != 0)
- return (volatile struct dbdma_cmd *)NULL;
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
- SAA7196_FMTS);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
- saa_regs[norm][SAA7196_FMTS]);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
- SAA7196_DPATH);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
- saa_regs[norm][SAA7196_DPATH]);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->even),
- bpp | ((clip)? PLANB_CLIPMASK: 0));
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->odd),
- bpp | ((clip)? PLANB_CLIPMASK: 0));
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
- SAA7196_OUTPIX);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
- saa_regs[norm][SAA7196_OUTPIX]);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
- SAA7196_HFILT);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
- saa_regs[norm][SAA7196_HFILT]);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
- SAA7196_OUTLINE);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
- saa_regs[norm][SAA7196_OUTLINE]);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
- SAA7196_VYP);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
- saa_regs[norm][SAA7196_VYP]);
- return c1;
-}
-
-/******************************/
-/* misc. supporting functions */
-/******************************/
-
-static inline void planb_lock(struct planb *pb)
-{
- mutex_lock(&pb->lock);
-}
-
-static inline void planb_unlock(struct planb *pb)
-{
- mutex_unlock(&pb->lock);
-}
-
-/***************/
-/* Driver Core */
-/***************/
-
-static int planb_prepare_open(struct planb *pb)
-{
- int i, size;
-
- /* allocate memory for two plus alpha command buffers (size: max lines,
- plus 40 commands handling, plus 1 alignment), plus dummy command buf,
- plus clipmask buffer, plus frame grabbing status */
- size = (pb->tab_size*(2+MAX_GBUFFERS*TAB_FACTOR)+1+MAX_GBUFFERS
- * PLANB_DUMMY)*sizeof(struct dbdma_cmd)
- +(PLANB_MAXLINES*((PLANB_MAXPIXELS+7)& ~7))/8
- +MAX_GBUFFERS*sizeof(unsigned int);
- if ((pb->priv_space = kzalloc (size, GFP_KERNEL)) == 0)
- return -ENOMEM;
- pb->overlay_last1 = pb->ch1_cmd = (volatile struct dbdma_cmd *)
- DBDMA_ALIGN (pb->priv_space);
- pb->overlay_last2 = pb->ch2_cmd = pb->ch1_cmd + pb->tab_size;
- pb->ch1_cmd_phys = virt_to_bus(pb->ch1_cmd);
- pb->cap_cmd[0] = pb->ch2_cmd + pb->tab_size;
- pb->pre_cmd[0] = pb->cap_cmd[0] + pb->tab_size * TAB_FACTOR;
- for (i = 1; i < MAX_GBUFFERS; i++) {
- pb->cap_cmd[i] = pb->pre_cmd[i-1] + PLANB_DUMMY;
- pb->pre_cmd[i] = pb->cap_cmd[i] + pb->tab_size * TAB_FACTOR;
- }
- pb->frame_stat=(volatile unsigned int *)(pb->pre_cmd[MAX_GBUFFERS-1]
- + PLANB_DUMMY);
- pb->mask = (unsigned char *)(pb->frame_stat+MAX_GBUFFERS);
-
- pb->rawbuf = NULL;
- pb->rawbuf_size = 0;
- pb->grabbing = 0;
- for (i = 0; i < MAX_GBUFFERS; i++) {
- pb->frame_stat[i] = GBUFFER_UNUSED;
- pb->gwidth[i] = 0;
- pb->gheight[i] = 0;
- pb->gfmt[i] = 0;
- pb->gnorm_switch[i] = 0;
-#ifndef PLANB_GSCANLINE
- pb->lsize[i] = 0;
- pb->lnum[i] = 0;
-#endif /* PLANB_GSCANLINE */
- }
- pb->gcount = 0;
- pb->suspend = 0;
- pb->last_fr = -999;
- pb->prev_last_fr = -999;
-
- /* Reset DMA controllers */
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
-
- return 0;
-}
-
-static void planb_prepare_close(struct planb *pb)
-{
- int i;
-
- /* make sure the dma's are idle */
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
- /* free kernel memory of command buffers */
- if(pb->priv_space != 0) {
- kfree (pb->priv_space);
- pb->priv_space = 0;
- pb->cmd_buff_inited = 0;
- }
- if(pb->rawbuf) {
- for (i = 0; i < pb->rawbuf_size; i++) {
- ClearPageReserved(virt_to_page(pb->rawbuf[i]));
- free_pages((unsigned long)pb->rawbuf[i], 0);
- }
- kfree(pb->rawbuf);
- }
- pb->rawbuf = NULL;
-}
-
-/*****************************/
-/* overlay support functions */
-/*****************************/
-
-static inline int overlay_is_active(struct planb *pb)
-{
- unsigned int size = pb->tab_size * sizeof(struct dbdma_cmd);
- unsigned int caddr = (unsigned)in_le32(&pb->planb_base->ch1.cmdptr);
-
- return (in_le32(&pb->overlay_last1->cmd_dep) == pb->ch1_cmd_phys)
- && (caddr < (pb->ch1_cmd_phys + size))
- && (caddr >= (unsigned)pb->ch1_cmd_phys);
-}
-
-static void overlay_start(struct planb *pb)
-{
-
- DEBUG("PlanB: overlay_start()\n");
-
- if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
-
- DEBUG("PlanB: presumably, grabbing is in progress...\n");
-
- planb_dbdma_stop(&pb->planb_base->ch2);
- out_le32 (&pb->planb_base->ch2.cmdptr,
- virt_to_bus(pb->ch2_cmd));
- planb_dbdma_restart(&pb->planb_base->ch2);
- st_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
- tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->ch1_cmd));
- eieio();
- pb->prev_last_fr = pb->last_fr;
- pb->last_fr = -2;
- if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
- IDEBUG("PlanB: became inactive "
- "in the mean time... reactivating\n");
- planb_dbdma_stop(&pb->planb_base->ch1);
- out_le32 (&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->ch1_cmd));
- planb_dbdma_restart(&pb->planb_base->ch1);
- }
- } else {
-
- DEBUG("PlanB: currently idle, so can do whatever\n");
-
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
- st_le32 (&pb->planb_base->ch2.cmdptr,
- virt_to_bus(pb->ch2_cmd));
- st_le32 (&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->ch1_cmd));
- out_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
- planb_dbdma_restart(&pb->planb_base->ch2);
- planb_dbdma_restart(&pb->planb_base->ch1);
- pb->last_fr = -1;
- }
- return;
-}
-
-static void overlay_stop(struct planb *pb)
-{
- DEBUG("PlanB: overlay_stop()\n");
-
- if(pb->last_fr == -1) {
-
- DEBUG("PlanB: no grabbing, it seems...\n");
-
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
- pb->last_fr = -999;
- } else if(pb->last_fr == -2) {
- unsigned int cmd_dep;
- tab_cmd_dbdma(pb->cap_cmd[pb->prev_last_fr], DBDMA_STOP, 0);
- eieio();
- cmd_dep = (unsigned int)in_le32(&pb->overlay_last1->cmd_dep);
- if(overlay_is_active(pb)) {
-
- DEBUG("PlanB: overlay is currently active\n");
-
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
- if(cmd_dep != pb->ch1_cmd_phys) {
- out_le32(&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->overlay_last1));
- planb_dbdma_restart(&pb->planb_base->ch1);
- }
- }
- pb->last_fr = pb->prev_last_fr;
- pb->prev_last_fr = -999;
- }
- return;
-}
-
-static void suspend_overlay(struct planb *pb)
-{
- int fr = -1;
- struct dbdma_cmd last;
-
- DEBUG("PlanB: suspend_overlay: %d\n", pb->suspend);
-
- if(pb->suspend++)
- return;
- if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
- if(pb->last_fr == -2) {
- fr = pb->prev_last_fr;
- memcpy(&last, (void*)pb->last_cmd[fr], sizeof(last));
- tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
- }
- if(overlay_is_active(pb)) {
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
- pb->suspended.overlay = 1;
- pb->suspended.frame = fr;
- memcpy(&pb->suspended.cmd, &last, sizeof(last));
- return;
- }
- }
- pb->suspended.overlay = 0;
- pb->suspended.frame = fr;
- memcpy(&pb->suspended.cmd, &last, sizeof(last));
- return;
-}
-
-static void resume_overlay(struct planb *pb)
-{
-
- DEBUG("PlanB: resume_overlay: %d\n", pb->suspend);
-
- if(pb->suspend > 1)
- return;
- if(pb->suspended.frame != -1) {
- memcpy((void*)pb->last_cmd[pb->suspended.frame],
- &pb->suspended.cmd, sizeof(pb->suspended.cmd));
- }
- if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
- goto finish;
- }
- if(pb->suspended.overlay) {
-
- DEBUG("PlanB: overlay being resumed\n");
-
- st_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
- st_le16 (&pb->ch2_cmd->command, DBDMA_NOP);
- /* Set command buffer addresses */
- st_le32(&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->overlay_last1));
- out_le32(&pb->planb_base->ch2.cmdptr,
- virt_to_bus(pb->overlay_last2));
- /* Start the DMA controller */
- out_le32 (&pb->planb_base->ch2.control,
- PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
- out_le32 (&pb->planb_base->ch1.control,
- PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
- } else if(pb->suspended.frame != -1) {
- out_le32(&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->last_cmd[pb->suspended.frame]));
- out_le32 (&pb->planb_base->ch1.control,
- PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
- }
-
-finish:
- pb->suspend--;
- wake_up_interruptible(&pb->suspendq);
-}
-
-static void add_clip(struct planb *pb, struct video_clip *clip)
-{
- volatile unsigned char *base;
- int xc = clip->x, yc = clip->y;
- int wc = clip->width, hc = clip->height;
- int ww = pb->win.width, hw = pb->win.height;
- int x, y, xtmp1, xtmp2;
-
- DEBUG("PlanB: clip %dx%d+%d+%d\n", wc, hc, xc, yc);
-
- if(xc < 0) {
- wc += xc;
- xc = 0;
- }
- if(yc < 0) {
- hc += yc;
- yc = 0;
- }
- if(xc + wc > ww)
- wc = ww - xc;
- if(wc <= 0) /* Nothing to do */
- return;
- if(yc + hc > hw)
- hc = hw - yc;
-
- for (y = yc; y < yc+hc; y++) {
- xtmp1=xc>>3;
- xtmp2=(xc+wc)>>3;
- base = pb->mask + y*96;
- if(xc != 0 || wc >= 8)
- *(base + xtmp1) &= (unsigned char)(0x00ff &
- (0xff00 >> (xc&7)));
- for (x = xtmp1 + 1; x < xtmp2; x++) {
- *(base + x) = 0;
- }
- if(xc < (ww & ~0x7))
- *(base + xtmp2) &= (unsigned char)(0x00ff >>
- ((xc+wc) & 7));
- }
-
- return;
-}
-
-static void fill_cmd_buff(struct planb *pb)
-{
- int restore = 0;
- volatile struct dbdma_cmd last;
-
- DEBUG("PlanB: fill_cmd_buff()\n");
-
- if(pb->overlay_last1 != pb->ch1_cmd) {
- restore = 1;
- last = *(pb->overlay_last1);
- }
- memset ((void *) pb->ch1_cmd, 0, 2 * pb->tab_size
- * sizeof(struct dbdma_cmd));
- cmd_buff (pb);
- if(restore)
- *(pb->overlay_last1) = last;
- if(pb->suspended.overlay) {
- unsigned long jump_addr = in_le32(&pb->overlay_last1->cmd_dep);
- if(jump_addr != pb->ch1_cmd_phys) {
- int i;
-
- DEBUG("PlanB: adjusting ch1's jump address\n");
-
- for(i = 0; i < MAX_GBUFFERS; i++) {
- if(pb->need_pre_capture[i]) {
- if(jump_addr == virt_to_bus(pb->pre_cmd[i]))
- goto found;
- } else {
- if(jump_addr == virt_to_bus(pb->cap_cmd[i]))
- goto found;
- }
- }
-
- DEBUG("PlanB: not found...\n");
-
- goto out;
-found:
- if(pb->need_pre_capture[i])
- out_le32(&pb->pre_cmd[i]->phy_addr,
- virt_to_bus(pb->overlay_last1));
- else
- out_le32(&pb->cap_cmd[i]->phy_addr,
- virt_to_bus(pb->overlay_last1));
- }
- }
-out:
- pb->cmd_buff_inited = 1;
-
- return;
-}
-
-static void cmd_buff(struct planb *pb)
-{
- int i, bpp, count, nlines, stepsize, interlace;
- unsigned long base, jump, addr_com, addr_dep;
- volatile struct dbdma_cmd *c1 = pb->ch1_cmd;
- volatile struct dbdma_cmd *c2 = pb->ch2_cmd;
-
- interlace = pb->win.interlace;
- bpp = pb->win.bpp;
- count = (bpp * ((pb->win.x + pb->win.width > pb->win.swidth) ?
- (pb->win.swidth - pb->win.x) : pb->win.width));
- nlines = ((pb->win.y + pb->win.height > pb->win.sheight) ?
- (pb->win.sheight - pb->win.y) : pb->win.height);
-
- /* Do video in: */
-
- /* Preamble commands: */
- addr_com = virt_to_bus(c1);
- addr_dep = virt_to_bus(&c1->cmd_dep);
- tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
- jump = virt_to_bus(c1+16); /* 14 by cmd_geo_setup() and 2 for padding */
- if((c1 = cmd_geo_setup(c1, pb->win.width, pb->win.height, interlace,
- bpp, 1, pb)) == NULL) {
- printk(KERN_WARNING "PlanB: encountered serious problems\n");
- tab_cmd_dbdma(pb->ch1_cmd + 1, DBDMA_STOP, 0);
- tab_cmd_dbdma(pb->ch2_cmd + 1, DBDMA_STOP, 0);
- return;
- }
- tab_cmd_store(c1++, addr_com, (unsigned)(DBDMA_NOP | BR_ALWAYS) << 16);
- tab_cmd_store(c1++, addr_dep, jump);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
- PLANB_SET(FIELD_SYNC));
- /* (1) wait for field sync to be set */
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(ODD_FIELD));
- /* wait for field sync to be cleared */
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
- /* if not odd field, wait until field sync is set again */
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
- /* assert ch_sync to ch2 */
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control),
- PLANB_SET(CH_SYNC));
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(DMA_ABORT));
-
- base = (pb->frame_buffer_phys + pb->offset + pb->win.y * (pb->win.bpl
- + pb->win.pad) + pb->win.x * bpp);
-
- if (interlace) {
- stepsize = 2;
- jump = virt_to_bus(c1 + (nlines + 1) / 2);
- } else {
- stepsize = 1;
- jump = virt_to_bus(c1 + nlines);
- }
-
- /* even field data: */
- for (i=0; i < nlines; i += stepsize, c1++)
- tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET,
- count, base + i * (pb->win.bpl + pb->win.pad), jump);
-
- /* For non-interlaced, we use even fields only */
- if (!interlace)
- goto cmd_tab_data_end;
-
- /* Resync to odd field */
- /* (2) wait for field sync to be set */
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(ODD_FIELD));
- /* wait for field sync to be cleared */
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
- /* if not odd field, wait until field sync is set again */
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
- /* assert ch_sync to ch2 */
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control),
- PLANB_SET(CH_SYNC));
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(DMA_ABORT));
-
- /* odd field data: */
- jump = virt_to_bus(c1 + nlines / 2);
- for (i=1; i < nlines; i += stepsize, c1++)
- tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
- base + i * (pb->win.bpl + pb->win.pad), jump);
-
- /* And jump back to the start */
-cmd_tab_data_end:
- pb->overlay_last1 = c1; /* keep a pointer to the last command */
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch1_cmd));
-
- /* Clipmask command buffer */
-
- /* Preamble commands: */
- tab_cmd_dbdma(c2++, DBDMA_NOP, 0);
- tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel),
- PLANB_SET(CH_SYNC));
- /* wait until ch1 asserts ch_sync */
- tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0);
- /* clear ch_sync asserted by ch1 */
- tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.control),
- PLANB_CLR(CH_SYNC));
- tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel),
- PLANB_SET(FIELD_SYNC));
- tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
- PLANB_SET(ODD_FIELD));
-
- /* jump to end of even field if appropriate */
- /* this points to (interlace)? pos. C: pos. B */
- jump = (interlace) ? virt_to_bus(c2 + (nlines + 1) / 2 + 2):
- virt_to_bus(c2 + nlines + 2);
- /* if odd field, skip over to odd field clipmasking */
- tab_cmd_dbdma(c2++, DBDMA_NOP | BR_IFSET, jump);
-
- /* even field mask: */
- tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
- PLANB_SET(DMA_ABORT));
- /* this points to pos. B */
- jump = (interlace) ? virt_to_bus(c2 + nlines + 1):
- virt_to_bus(c2 + nlines);
- base = virt_to_bus(pb->mask);
- for (i=0; i < nlines; i += stepsize, c2++)
- tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96,
- base + i * 96, jump);
-
- /* For non-interlaced, we use only even fields */
- if(!interlace)
- goto cmd_tab_mask_end;
-
- /* odd field mask: */
-/* C */ tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
- PLANB_SET(DMA_ABORT));
- /* this points to pos. B */
- jump = virt_to_bus(c2 + nlines / 2);
- base = virt_to_bus(pb->mask);
- for (i=1; i < nlines; i += 2, c2++) /* abort if set */
- tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96,
- base + i * 96, jump);
-
- /* Inform channel 1 and jump back to start */
-cmd_tab_mask_end:
- /* ok, I just realized this is kind of flawed. */
- /* this part is reached only after odd field clipmasking. */
- /* wanna clean up? */
- /* wait for field sync to be set */
- /* corresponds to fsync (1) of ch1 */
-/* B */ tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0);
- /* restart ch1, meant to clear any dead bit or something */
- tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control),
- PLANB_CLR(RUN));
- tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control),
- PLANB_SET(RUN));
- pb->overlay_last2 = c2; /* keep a pointer to the last command */
- /* start over even field clipmasking */
- tab_cmd_dbdma(c2, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch2_cmd));
-
- eieio();
- return;
-}
-
-/*********************************/
-/* grabdisplay support functions */
-/*********************************/
-
-static int palette2fmt[] = {
- 0,
- PLANB_GRAY,
- 0,
- 0,
- 0,
- PLANB_COLOUR32,
- PLANB_COLOUR15,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
-};
-
-#define PLANB_PALETTE_MAX 15
-
-static int vgrab(struct planb *pb, struct video_mmap *mp)
-{
- unsigned int fr = mp->frame;
- unsigned int format;
-
- if(pb->rawbuf==NULL) {
- int err;
- if((err=grabbuf_alloc(pb)))
- return err;
- }
-
- IDEBUG("PlanB: grab %d: %dx%d(%u)\n", pb->grabbing,
- mp->width, mp->height, fr);
-
- if(pb->grabbing >= MAX_GBUFFERS)
- return -ENOBUFS;
- if(fr > (MAX_GBUFFERS - 1) || fr < 0)
- return -EINVAL;
- if(mp->height <= 0 || mp->width <= 0)
- return -EINVAL;
- if(mp->format < 0 || mp->format >= PLANB_PALETTE_MAX)
- return -EINVAL;
- if((format = palette2fmt[mp->format]) == 0)
- return -EINVAL;
- if (mp->height * mp->width * format > PLANB_MAX_FBUF) /* format = bpp */
- return -EINVAL;
-
- planb_lock(pb);
- if(mp->width != pb->gwidth[fr] || mp->height != pb->gheight[fr] ||
- format != pb->gfmt[fr] || (pb->gnorm_switch[fr])) {
- int i;
-#ifndef PLANB_GSCANLINE
- unsigned int osize = pb->gwidth[fr] * pb->gheight[fr]
- * pb->gfmt[fr];
- unsigned int nsize = mp->width * mp->height * format;
-#endif
-
- IDEBUG("PlanB: gwidth = %d, gheight = %d, mp->format = %u\n",
- mp->width, mp->height, mp->format);
-
-#ifndef PLANB_GSCANLINE
- if(pb->gnorm_switch[fr])
- nsize = 0;
- if (nsize < osize) {
- for(i = pb->gbuf_idx[fr]; osize > 0; i++) {
- memset((void *)pb->rawbuf[i], 0, PAGE_SIZE);
- osize -= PAGE_SIZE;
- }
- }
- for(i = pb->l_fr_addr_idx[fr]; i < pb->l_fr_addr_idx[fr]
- + pb->lnum[fr]; i++)
- memset((void *)pb->rawbuf[i], 0, PAGE_SIZE);
-#else
-/* XXX TODO */
-/*
- if(pb->gnorm_switch[fr])
- memset((void *)pb->gbuffer[fr], 0,
- pb->gbytes_per_line * pb->gheight[fr]);
- else {
- if(mp->
- for(i = 0; i < pb->gheight[fr]; i++) {
- memset((void *)(pb->gbuffer[fr]
- + pb->gbytes_per_line * i
- }
- }
-*/
-#endif
- pb->gwidth[fr] = mp->width;
- pb->gheight[fr] = mp->height;
- pb->gfmt[fr] = format;
- pb->last_cmd[fr] = setup_grab_cmd(fr, pb);
- planb_pre_capture(fr, pb->gfmt[fr], pb); /* gfmt = bpp */
- pb->need_pre_capture[fr] = 1;
- pb->gnorm_switch[fr] = 0;
- } else
- pb->need_pre_capture[fr] = 0;
- pb->frame_stat[fr] = GBUFFER_GRABBING;
- if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
-
- IDEBUG("PlanB: ch1 inactive, initiating grabbing\n");
-
- planb_dbdma_stop(&pb->planb_base->ch1);
- if(pb->need_pre_capture[fr]) {
-
- IDEBUG("PlanB: padding pre-capture sequence\n");
-
- out_le32 (&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->pre_cmd[fr]));
- } else {
- tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
- tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
- /* let's be on the safe side. here is not timing critical. */
- tab_cmd_dbdma((pb->cap_cmd[fr] + 1), DBDMA_NOP, 0);
- out_le32 (&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->cap_cmd[fr]));
- }
- planb_dbdma_restart(&pb->planb_base->ch1);
- pb->last_fr = fr;
- } else {
- int i;
-
- IDEBUG("PlanB: ch1 active, grabbing being queued\n");
-
- if((pb->last_fr == -1) || ((pb->last_fr == -2) &&
- overlay_is_active(pb))) {
-
- IDEBUG("PlanB: overlay is active, grabbing defered\n");
-
- tab_cmd_dbdma(pb->last_cmd[fr],
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->ch1_cmd));
- if(pb->need_pre_capture[fr]) {
-
- IDEBUG("PlanB: padding pre-capture sequence\n");
-
- tab_cmd_store(pb->pre_cmd[fr],
- virt_to_bus(&pb->overlay_last1->cmd_dep),
- virt_to_bus(pb->ch1_cmd));
- eieio();
- out_le32 (&pb->overlay_last1->cmd_dep,
- virt_to_bus(pb->pre_cmd[fr]));
- } else {
- tab_cmd_store(pb->cap_cmd[fr],
- virt_to_bus(&pb->overlay_last1->cmd_dep),
- virt_to_bus(pb->ch1_cmd));
- tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
- DBDMA_NOP, 0);
- eieio();
- out_le32 (&pb->overlay_last1->cmd_dep,
- virt_to_bus(pb->cap_cmd[fr]));
- }
- for(i = 0; overlay_is_active(pb) && i < 999; i++)
- IDEBUG("PlanB: waiting for overlay done\n");
- tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0);
- pb->prev_last_fr = fr;
- pb->last_fr = -2;
- } else if(pb->last_fr == -2) {
-
- IDEBUG("PlanB: mixed mode detected, grabbing"
- " will be done before activating overlay\n");
-
- tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0);
- if(pb->need_pre_capture[fr]) {
-
- IDEBUG("PlanB: padding pre-capture sequence\n");
-
- tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr],
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->pre_cmd[fr]));
- eieio();
- } else {
- tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
- if(pb->gwidth[pb->prev_last_fr] !=
- pb->gwidth[fr]
- || pb->gheight[pb->prev_last_fr] !=
- pb->gheight[fr]
- || pb->gfmt[pb->prev_last_fr] !=
- pb->gfmt[fr])
- tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
- DBDMA_NOP, 0);
- else
- tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->cap_cmd[fr] + 16));
- tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr],
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->cap_cmd[fr]));
- eieio();
- }
- tab_cmd_dbdma(pb->last_cmd[fr],
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->ch1_cmd));
- eieio();
- pb->prev_last_fr = fr;
- pb->last_fr = -2;
- } else {
-
- IDEBUG("PlanB: active grabbing session detected\n");
-
- if(pb->need_pre_capture[fr]) {
-
- IDEBUG("PlanB: padding pre-capture sequence\n");
-
- tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->pre_cmd[fr]));
- eieio();
- } else {
- tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
- tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
- if(pb->gwidth[pb->last_fr] != pb->gwidth[fr]
- || pb->gheight[pb->last_fr] !=
- pb->gheight[fr]
- || pb->gfmt[pb->last_fr] !=
- pb->gfmt[fr])
- tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
- DBDMA_NOP, 0);
- else
- tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->cap_cmd[fr] + 16));
- tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
- DBDMA_NOP | BR_ALWAYS,
- virt_to_bus(pb->cap_cmd[fr]));
- eieio();
- }
- pb->last_fr = fr;
- }
- if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
-
- IDEBUG("PlanB: became inactive in the mean time..."
- "reactivating\n");
-
- planb_dbdma_stop(&pb->planb_base->ch1);
- out_le32 (&pb->planb_base->ch1.cmdptr,
- virt_to_bus(pb->cap_cmd[fr]));
- planb_dbdma_restart(&pb->planb_base->ch1);
- }
- }
- pb->grabbing++;
- planb_unlock(pb);
-
- return 0;
-}
-
-static void planb_pre_capture(int fr, int bpp, struct planb *pb)
-{
- volatile struct dbdma_cmd *c1 = pb->pre_cmd[fr];
- int interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0;
-
- tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
- if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace,
- bpp, 0, pb)) == NULL) {
- printk(KERN_WARNING "PlanB: encountered some problems\n");
- tab_cmd_dbdma(pb->pre_cmd[fr] + 1, DBDMA_STOP, 0);
- return;
- }
- /* Sync to even field */
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
- PLANB_SET(FIELD_SYNC));
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(ODD_FIELD));
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
- tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(DMA_ABORT));
- /* For non-interlaced, we use even fields only */
- if (pb->gheight[fr] <= pb->maxlines/2)
- goto cmd_tab_data_end;
- /* Sync to odd field */
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(ODD_FIELD));
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(DMA_ABORT));
-cmd_tab_data_end:
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->cap_cmd[fr]));
-
- eieio();
-}
-
-static volatile struct dbdma_cmd *setup_grab_cmd(int fr, struct planb *pb)
-{
- int i, bpp, count, nlines, stepsize, interlace;
-#ifdef PLANB_GSCANLINE
- int scanline;
-#else
- int nlpp, leftover1;
- unsigned long base;
-#endif
- unsigned long jump;
- int pagei;
- volatile struct dbdma_cmd *c1;
- volatile struct dbdma_cmd *jump_addr;
-
- c1 = pb->cap_cmd[fr];
- interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0;
- bpp = pb->gfmt[fr]; /* gfmt = bpp */
- count = bpp * pb->gwidth[fr];
- nlines = pb->gheight[fr];
-#ifdef PLANB_GSCANLINE
- scanline = pb->gbytes_per_line;
-#else
- pb->lsize[fr] = count;
- pb->lnum[fr] = 0;
-#endif
-
- /* Do video in: */
-
- /* Preamble commands: */
- tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(c1 + 16)); c1++;
- if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace,
- bpp, 0, pb)) == NULL) {
- printk(KERN_WARNING "PlanB: encountered serious problems\n");
- tab_cmd_dbdma(pb->cap_cmd[fr] + 1, DBDMA_STOP, 0);
- return (pb->cap_cmd[fr] + 2);
- }
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
- PLANB_SET(FIELD_SYNC));
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(ODD_FIELD));
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
- tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(DMA_ABORT));
-
- if (interlace) {
- stepsize = 2;
- jump_addr = c1 + TAB_FACTOR * (nlines + 1) / 2;
- } else {
- stepsize = 1;
- jump_addr = c1 + TAB_FACTOR * nlines;
- }
- jump = virt_to_bus(jump_addr);
-
- /* even field data: */
-
- pagei = pb->gbuf_idx[fr];
-#ifdef PLANB_GSCANLINE
- for (i = 0; i < nlines; i += stepsize) {
- tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
- virt_to_bus(pb->rawbuf[pagei
- + i * scanline / PAGE_SIZE]), jump);
- }
-#else
- i = 0;
- leftover1 = 0;
- do {
- int j;
-
- base = virt_to_bus(pb->rawbuf[pagei]);
- nlpp = (PAGE_SIZE - leftover1) / count / stepsize;
- for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++)
- tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET,
- count, base + count * j * stepsize + leftover1, jump);
- if(i < nlines) {
- int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1;
-
- if(lov0 == 0)
- leftover1 = 0;
- else {
- if(lov0 >= count) {
- tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, base
- + count * nlpp * stepsize + leftover1, jump);
- } else {
- pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei]
- + count * nlpp * stepsize + leftover1;
- pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1;
- pb->l_to_next_size[fr][pb->lnum[fr]] = count - lov0;
- tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
- virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr]
- + pb->lnum[fr]]), jump);
- if(++pb->lnum[fr] > MAX_LNUM)
- pb->lnum[fr]--;
- }
- leftover1 = count * stepsize - lov0;
- i += stepsize;
- }
- }
- pagei++;
- } while(i < nlines);
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump);
- c1 = jump_addr;
-#endif /* PLANB_GSCANLINE */
-
- /* For non-interlaced, we use even fields only */
- if (!interlace)
- goto cmd_tab_data_end;
-
- /* Sync to odd field */
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(ODD_FIELD));
- tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
- PLANB_SET(DMA_ABORT));
-
- /* odd field data: */
- jump_addr = c1 + TAB_FACTOR * nlines / 2;
- jump = virt_to_bus(jump_addr);
-#ifdef PLANB_GSCANLINE
- for (i = 1; i < nlines; i += stepsize) {
- tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
- virt_to_bus(pb->rawbuf[pagei
- + i * scanline / PAGE_SIZE]), jump);
- }
-#else
- i = 1;
- leftover1 = 0;
- pagei = pb->gbuf_idx[fr];
- if(nlines <= 1)
- goto skip;
- do {
- int j;
-
- base = virt_to_bus(pb->rawbuf[pagei]);
- nlpp = (PAGE_SIZE - leftover1) / count / stepsize;
- if(leftover1 >= count) {
- tab_cmd_gen(c1++, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
- base + leftover1 - count, jump);
- i += stepsize;
- }
- for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++)
- tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
- base + count * (j * stepsize + 1) + leftover1, jump);
- if(i < nlines) {
- int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1;
-
- if(lov0 == 0)
- leftover1 = 0;
- else {
- if(lov0 > count) {
- pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei]
- + count * (nlpp * stepsize + 1) + leftover1;
- pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1;
- pb->l_to_next_size[fr][pb->lnum[fr]] = count * stepsize
- - lov0;
- tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
- virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr]
- + pb->lnum[fr]]), jump);
- if(++pb->lnum[fr] > MAX_LNUM)
- pb->lnum[fr]--;
- i += stepsize;
- }
- leftover1 = count * stepsize - lov0;
- }
- }
- pagei++;
- } while(i < nlines);
-skip:
- tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump);
- c1 = jump_addr;
-#endif /* PLANB_GSCANLINE */
-
-cmd_tab_data_end:
- tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->intr_stat),
- (fr << 9) | PLANB_FRM_IRQ | PLANB_GEN_IRQ);
- /* stop it */
- tab_cmd_dbdma(c1, DBDMA_STOP, 0);
-
- eieio();
- return c1;
-}
-
-static irqreturn_t planb_irq(int irq, void *dev_id)
-{
- unsigned int stat, astat;
- struct planb *pb = (struct planb *)dev_id;
-
- IDEBUG("PlanB: planb_irq()\n");
-
- /* get/clear interrupt status bits */
- eieio();
- stat = in_le32(&pb->planb_base->intr_stat);
- astat = stat & pb->intr_mask;
- out_le32(&pb->planb_base->intr_stat, PLANB_FRM_IRQ
- & ~astat & stat & ~PLANB_GEN_IRQ);
- IDEBUG("PlanB: stat = %X, astat = %X\n", stat, astat);
-
- if(astat & PLANB_FRM_IRQ) {
- unsigned int fr = stat >> 9;
-#ifndef PLANB_GSCANLINE
- int i;
-#endif
- IDEBUG("PlanB: PLANB_FRM_IRQ\n");
-
- pb->gcount++;
-
- IDEBUG("PlanB: grab %d: fr = %d, gcount = %d\n",
- pb->grabbing, fr, pb->gcount);
-#ifndef PLANB_GSCANLINE
- IDEBUG("PlanB: %d * %d bytes are being copied over\n",
- pb->lnum[fr], pb->lsize[fr]);
- for(i = 0; i < pb->lnum[fr]; i++) {
- int first = pb->lsize[fr] - pb->l_to_next_size[fr][i];
-
- memcpy(pb->l_to_addr[fr][i],
- pb->rawbuf[pb->l_fr_addr_idx[fr] + i],
- first);
- memcpy(pb->rawbuf[pb->l_to_next_idx[fr][i]],
- pb->rawbuf[pb->l_fr_addr_idx[fr] + i] + first,
- pb->l_to_next_size[fr][i]);
- }
-#endif
- pb->frame_stat[fr] = GBUFFER_DONE;
- pb->grabbing--;
- wake_up_interruptible(&pb->capq);
- return IRQ_HANDLED;
- }
- /* incorrect interrupts? */
- pb->intr_mask = PLANB_CLR_IRQ;
- out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
- printk(KERN_ERR "PlanB: IRQ lockup, cleared intrrupts"
- " unconditionally\n");
- return IRQ_HANDLED;
-}
-
-/*******************************
- * Device Operations functions *
- *******************************/
-
-static int planb_open(struct video_device *dev, int mode)
-{
- struct planb *pb = (struct planb *)dev;
-
- if (pb->user == 0) {
- int err;
- if((err = planb_prepare_open(pb)) != 0)
- return err;
- }
- pb->user++;
-
- DEBUG("PlanB: device opened\n");
- return 0;
-}
-
-static void planb_close(struct video_device *dev)
-{
- struct planb *pb = (struct planb *)dev;
-
- if(pb->user < 1) /* ??? */
- return;
- planb_lock(pb);
- if (pb->user == 1) {
- if (pb->overlay) {
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
- pb->overlay = 0;
- }
- planb_prepare_close(pb);
- }
- pb->user--;
- planb_unlock(pb);
-
- DEBUG("PlanB: device closed\n");
-}
-
-static long planb_read(struct video_device *v, char *buf, unsigned long count,
- int nonblock)
-{
- DEBUG("planb: read request\n");
- return -EINVAL;
-}
-
-static long planb_write(struct video_device *v, const char *buf,
- unsigned long count, int nonblock)
-{
- DEBUG("planb: write request\n");
- return -EINVAL;
-}
-
-static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- struct planb *pb=(struct planb *)dev;
-
- switch (cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability b;
-
- DEBUG("PlanB: IOCTL VIDIOCGCAP\n");
-
- strcpy (b.name, pb->video_dev.name);
- b.type = VID_TYPE_OVERLAY | VID_TYPE_CLIPPING |
- VID_TYPE_FRAMERAM | VID_TYPE_SCALES |
- VID_TYPE_CAPTURE;
- b.channels = 2; /* composite & svhs */
- b.audios = 0;
- b.maxwidth = PLANB_MAXPIXELS;
- b.maxheight = PLANB_MAXLINES;
- b.minwidth = 32; /* wild guess */
- b.minheight = 32;
- if (copy_to_user(arg,&b,sizeof(b)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSFBUF:
- {
- struct video_buffer v;
- unsigned short bpp;
- unsigned int fmt;
-
- DEBUG("PlanB: IOCTL VIDIOCSFBUF\n");
-
- if (!capable(CAP_SYS_ADMIN)
- || !capable(CAP_SYS_RAWIO))
- return -EPERM;
- if (copy_from_user(&v, arg,sizeof(v)))
- return -EFAULT;
- planb_lock(pb);
- switch(v.depth) {
- case 8:
- bpp = 1;
- fmt = PLANB_GRAY;
- break;
- case 15:
- case 16:
- bpp = 2;
- fmt = PLANB_COLOUR15;
- break;
- case 24:
- case 32:
- bpp = 4;
- fmt = PLANB_COLOUR32;
- break;
- default:
- planb_unlock(pb);
- return -EINVAL;
- }
- if (bpp * v.width > v.bytesperline) {
- planb_unlock(pb);
- return -EINVAL;
- }
- pb->win.bpp = bpp;
- pb->win.color_fmt = fmt;
- pb->frame_buffer_phys = (unsigned long) v.base;
- pb->win.sheight = v.height;
- pb->win.swidth = v.width;
- pb->picture.depth = pb->win.depth = v.depth;
- pb->win.bpl = pb->win.bpp * pb->win.swidth;
- pb->win.pad = v.bytesperline - pb->win.bpl;
-
- DEBUG("PlanB: Display at %p is %d by %d, bytedepth %d,"
- " bpl %d (+ %d)\n", v.base, v.width,v.height,
- pb->win.bpp, pb->win.bpl, pb->win.pad);
-
- pb->cmd_buff_inited = 0;
- if(pb->overlay) {
- suspend_overlay(pb);
- fill_cmd_buff(pb);
- resume_overlay(pb);
- }
- planb_unlock(pb);
- return 0;
- }
- case VIDIOCGFBUF:
- {
- struct video_buffer v;
-
- DEBUG("PlanB: IOCTL VIDIOCGFBUF\n");
-
- v.base = (void *)pb->frame_buffer_phys;
- v.height = pb->win.sheight;
- v.width = pb->win.swidth;
- v.depth = pb->win.depth;
- v.bytesperline = pb->win.bpl + pb->win.pad;
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCCAPTURE:
- {
- int i;
-
- if(copy_from_user(&i, arg, sizeof(i)))
- return -EFAULT;
- if(i==0) {
- DEBUG("PlanB: IOCTL VIDIOCCAPTURE Stop\n");
-
- if (!(pb->overlay))
- return 0;
- planb_lock(pb);
- pb->overlay = 0;
- overlay_stop(pb);
- planb_unlock(pb);
- } else {
- DEBUG("PlanB: IOCTL VIDIOCCAPTURE Start\n");
-
- if (pb->frame_buffer_phys == 0 ||
- pb->win.width == 0 ||
- pb->win.height == 0)
- return -EINVAL;
- if (pb->overlay)
- return 0;
- planb_lock(pb);
- pb->overlay = 1;
- if(!(pb->cmd_buff_inited))
- fill_cmd_buff(pb);
- overlay_start(pb);
- planb_unlock(pb);
- }
- return 0;
- }
- case VIDIOCGCHAN:
- {
- struct video_channel v;
-
- DEBUG("PlanB: IOCTL VIDIOCGCHAN\n");
-
- if(copy_from_user(&v, arg,sizeof(v)))
- return -EFAULT;
- v.flags = 0;
- v.tuners = 0;
- v.type = VIDEO_TYPE_CAMERA;
- v.norm = pb->win.norm;
- switch(v.channel)
- {
- case 0:
- strcpy(v.name,"Composite");
- break;
- case 1:
- strcpy(v.name,"SVHS");
- break;
- default:
- return -EINVAL;
- break;
- }
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
-
- return 0;
- }
- case VIDIOCSCHAN:
- {
- struct video_channel v;
-
- DEBUG("PlanB: IOCTL VIDIOCSCHAN\n");
-
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
-
- if (v.norm != pb->win.norm) {
- int i, maxlines;
-
- switch (v.norm)
- {
- case VIDEO_MODE_PAL:
- case VIDEO_MODE_SECAM:
- maxlines = PLANB_MAXLINES;
- break;
- case VIDEO_MODE_NTSC:
- maxlines = PLANB_NTSC_MAXLINES;
- break;
- default:
- return -EINVAL;
- break;
- }
- planb_lock(pb);
- /* empty the grabbing queue */
- wait_event(pb->capq, !pb->grabbing);
- pb->maxlines = maxlines;
- pb->win.norm = v.norm;
- /* Stop overlay if running */
- suspend_overlay(pb);
- for(i = 0; i < MAX_GBUFFERS; i++)
- pb->gnorm_switch[i] = 1;
- /* I know it's an overkill, but.... */
- fill_cmd_buff(pb);
- /* ok, now init it accordingly */
- saa_init_regs (pb);
- /* restart overlay if it was running */
- resume_overlay(pb);
- planb_unlock(pb);
- }
-
- switch(v.channel)
- {
- case 0: /* Composite */
- saa_set (SAA7196_IOCC,
- ((saa_regs[pb->win.norm][SAA7196_IOCC] &
- ~7) | 3), pb);
- break;
- case 1: /* SVHS */
- saa_set (SAA7196_IOCC,
- ((saa_regs[pb->win.norm][SAA7196_IOCC] &
- ~7) | 4), pb);
- break;
- default:
- return -EINVAL;
- break;
- }
-
- return 0;
- }
- case VIDIOCGPICT:
- {
- struct video_picture vp = pb->picture;
-
- DEBUG("PlanB: IOCTL VIDIOCGPICT\n");
-
- switch(pb->win.color_fmt) {
- case PLANB_GRAY:
- vp.palette = VIDEO_PALETTE_GREY;
- case PLANB_COLOUR15:
- vp.palette = VIDEO_PALETTE_RGB555;
- break;
- case PLANB_COLOUR32:
- vp.palette = VIDEO_PALETTE_RGB32;
- break;
- default:
- vp.palette = 0;
- break;
- }
-
- if(copy_to_user(arg,&vp,sizeof(vp)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSPICT:
- {
- struct video_picture vp;
-
- DEBUG("PlanB: IOCTL VIDIOCSPICT\n");
-
- if(copy_from_user(&vp,arg,sizeof(vp)))
- return -EFAULT;
- pb->picture = vp;
- /* Should we do sanity checks here? */
- saa_set (SAA7196_BRIG, (unsigned char)
- ((pb->picture.brightness) >> 8), pb);
- saa_set (SAA7196_HUEC, (unsigned char)
- ((pb->picture.hue) >> 8) ^ 0x80, pb);
- saa_set (SAA7196_CSAT, (unsigned char)
- ((pb->picture.colour) >> 9), pb);
- saa_set (SAA7196_CONT, (unsigned char)
- ((pb->picture.contrast) >> 9), pb);
-
- return 0;
- }
- case VIDIOCSWIN:
- {
- struct video_window vw;
- struct video_clip clip;
- int i;
-
- DEBUG("PlanB: IOCTL VIDIOCSWIN\n");
-
- if(copy_from_user(&vw,arg,sizeof(vw)))
- return -EFAULT;
-
- planb_lock(pb);
- /* Stop overlay if running */
- suspend_overlay(pb);
- pb->win.interlace = (vw.height > pb->maxlines/2)? 1: 0;
- if (pb->win.x != vw.x ||
- pb->win.y != vw.y ||
- pb->win.width != vw.width ||
- pb->win.height != vw.height ||
- !pb->cmd_buff_inited) {
- pb->win.x = vw.x;
- pb->win.y = vw.y;
- pb->win.width = vw.width;
- pb->win.height = vw.height;
- fill_cmd_buff(pb);
- }
- /* Reset clip mask */
- memset ((void *) pb->mask, 0xff, (pb->maxlines
- * ((PLANB_MAXPIXELS + 7) & ~7)) / 8);
- /* Add any clip rects */
- for (i = 0; i < vw.clipcount; i++) {
- if (copy_from_user(&clip, vw.clips + i,
- sizeof(struct video_clip)))
- return -EFAULT;
- add_clip(pb, &clip);
- }
- /* restart overlay if it was running */
- resume_overlay(pb);
- planb_unlock(pb);
- return 0;
- }
- case VIDIOCGWIN:
- {
- struct video_window vw;
-
- DEBUG("PlanB: IOCTL VIDIOCGWIN\n");
-
- vw.x=pb->win.x;
- vw.y=pb->win.y;
- vw.width=pb->win.width;
- vw.height=pb->win.height;
- vw.chromakey=0;
- vw.flags=0;
- if(pb->win.interlace)
- vw.flags|=VIDEO_WINDOW_INTERLACE;
- if(copy_to_user(arg,&vw,sizeof(vw)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSYNC: {
- int i;
-
- IDEBUG("PlanB: IOCTL VIDIOCSYNC\n");
-
- if(copy_from_user((void *)&i,arg,sizeof(int)))
- return -EFAULT;
-
- IDEBUG("PlanB: sync to frame %d\n", i);
-
- if(i > (MAX_GBUFFERS - 1) || i < 0)
- return -EINVAL;
-chk_grab:
- switch (pb->frame_stat[i]) {
- case GBUFFER_UNUSED:
- return -EINVAL;
- case GBUFFER_GRABBING:
- IDEBUG("PlanB: waiting for grab"
- " done (%d)\n", i);
- interruptible_sleep_on(&pb->capq);
- if(signal_pending(current))
- return -EINTR;
- goto chk_grab;
- case GBUFFER_DONE:
- pb->frame_stat[i] = GBUFFER_UNUSED;
- break;
- }
- return 0;
- }
-
- case VIDIOCMCAPTURE:
- {
- struct video_mmap vm;
- volatile unsigned int status;
-
- IDEBUG("PlanB: IOCTL VIDIOCMCAPTURE\n");
-
- if(copy_from_user((void *) &vm,(void *)arg,sizeof(vm)))
- return -EFAULT;
- status = pb->frame_stat[vm.frame];
- if (status != GBUFFER_UNUSED)
- return -EBUSY;
-
- return vgrab(pb, &vm);
- }
-
- case VIDIOCGMBUF:
- {
- int i;
- struct video_mbuf vm;
-
- DEBUG("PlanB: IOCTL VIDIOCGMBUF\n");
-
- memset(&vm, 0 , sizeof(vm));
- vm.size = PLANB_MAX_FBUF * MAX_GBUFFERS;
- vm.frames = MAX_GBUFFERS;
- for(i = 0; i<MAX_GBUFFERS; i++)
- vm.offsets[i] = PLANB_MAX_FBUF * i;
- if(copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
- return -EFAULT;
- return 0;
- }
-
- case PLANBIOCGSAAREGS:
- {
- struct planb_saa_regs preg;
-
- DEBUG("PlanB: IOCTL PLANBIOCGSAAREGS\n");
-
- if(copy_from_user(&preg, arg, sizeof(preg)))
- return -EFAULT;
- if(preg.addr >= SAA7196_NUMREGS)
- return -EINVAL;
- preg.val = saa_regs[pb->win.norm][preg.addr];
- if(copy_to_user((void *)arg, (void *)&preg,
- sizeof(preg)))
- return -EFAULT;
- return 0;
- }
-
- case PLANBIOCSSAAREGS:
- {
- struct planb_saa_regs preg;
-
- DEBUG("PlanB: IOCTL PLANBIOCSSAAREGS\n");
-
- if(copy_from_user(&preg, arg, sizeof(preg)))
- return -EFAULT;
- if(preg.addr >= SAA7196_NUMREGS)
- return -EINVAL;
- saa_set (preg.addr, preg.val, pb);
- return 0;
- }
-
- case PLANBIOCGSTAT:
- {
- struct planb_stat_regs pstat;
-
- DEBUG("PlanB: IOCTL PLANBIOCGSTAT\n");
-
- pstat.ch1_stat = in_le32(&pb->planb_base->ch1.status);
- pstat.ch2_stat = in_le32(&pb->planb_base->ch2.status);
- pstat.saa_stat0 = saa_status(0, pb);
- pstat.saa_stat1 = saa_status(1, pb);
-
- if(copy_to_user((void *)arg, (void *)&pstat,
- sizeof(pstat)))
- return -EFAULT;
- return 0;
- }
-
- case PLANBIOCSMODE: {
- int v;
-
- DEBUG("PlanB: IOCTL PLANBIOCSMODE\n");
-
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
-
- switch(v)
- {
- case PLANB_TV_MODE:
- saa_set (SAA7196_STDC,
- (saa_regs[pb->win.norm][SAA7196_STDC] &
- 0x7f), pb);
- break;
- case PLANB_VTR_MODE:
- saa_set (SAA7196_STDC,
- (saa_regs[pb->win.norm][SAA7196_STDC] |
- 0x80), pb);
- break;
- default:
- return -EINVAL;
- break;
- }
- pb->win.mode = v;
- return 0;
- }
- case PLANBIOCGMODE: {
- int v=pb->win.mode;
-
- DEBUG("PlanB: IOCTL PLANBIOCGMODE\n");
-
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
-#ifdef PLANB_GSCANLINE
- case PLANBG_GRAB_BPL: {
- int v=pb->gbytes_per_line;
-
- DEBUG("PlanB: IOCTL PLANBG_GRAB_BPL\n");
-
- if(copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
-#endif /* PLANB_GSCANLINE */
- case PLANB_INTR_DEBUG: {
- int i;
-
- DEBUG("PlanB: IOCTL PLANB_INTR_DEBUG\n");
-
- if(copy_from_user(&i, arg, sizeof(i)))
- return -EFAULT;
-
- /* avoid hang ups all together */
- for (i = 0; i < MAX_GBUFFERS; i++) {
- if(pb->frame_stat[i] == GBUFFER_GRABBING) {
- pb->frame_stat[i] = GBUFFER_DONE;
- }
- }
- if(pb->grabbing)
- pb->grabbing--;
- wake_up_interruptible(&pb->capq);
- return 0;
- }
- case PLANB_INV_REGS: {
- int i;
- struct planb_any_regs any;
-
- DEBUG("PlanB: IOCTL PLANB_INV_REGS\n");
-
- if(copy_from_user(&any, arg, sizeof(any)))
- return -EFAULT;
- if(any.offset < 0 || any.offset + any.bytes > 0x400)
- return -EINVAL;
- if(any.bytes > 128)
- return -EINVAL;
- for (i = 0; i < any.bytes; i++) {
- any.data[i] =
- in_8((unsigned char *)pb->planb_base
- + any.offset + i);
- }
- if(copy_to_user(arg,&any,sizeof(any)))
- return -EFAULT;
- return 0;
- }
- default:
- {
- DEBUG("PlanB: Unimplemented IOCTL\n");
- return -ENOIOCTLCMD;
- }
- /* Some IOCTLs are currently unsupported on PlanB */
- case VIDIOCGTUNER: {
- DEBUG("PlanB: IOCTL VIDIOCGTUNER\n");
- goto unimplemented; }
- case VIDIOCSTUNER: {
- DEBUG("PlanB: IOCTL VIDIOCSTUNER\n");
- goto unimplemented; }
- case VIDIOCSFREQ: {
- DEBUG("PlanB: IOCTL VIDIOCSFREQ\n");
- goto unimplemented; }
- case VIDIOCGFREQ: {
- DEBUG("PlanB: IOCTL VIDIOCGFREQ\n");
- goto unimplemented; }
- case VIDIOCKEY: {
- DEBUG("PlanB: IOCTL VIDIOCKEY\n");
- goto unimplemented; }
- case VIDIOCSAUDIO: {
- DEBUG("PlanB: IOCTL VIDIOCSAUDIO\n");
- goto unimplemented; }
- case VIDIOCGAUDIO: {
- DEBUG("PlanB: IOCTL VIDIOCGAUDIO\n");
- goto unimplemented; }
-unimplemented:
- DEBUG(" Unimplemented\n");
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static int planb_mmap(struct vm_area_struct *vma, struct video_device *dev, const char *adr, unsigned long size)
-{
- int i;
- struct planb *pb = (struct planb *)dev;
- unsigned long start = (unsigned long)adr;
-
- if (size > MAX_GBUFFERS * PLANB_MAX_FBUF)
- return -EINVAL;
- if (!pb->rawbuf) {
- int err;
- if((err=grabbuf_alloc(pb)))
- return err;
- }
- for (i = 0; i < pb->rawbuf_size; i++) {
- unsigned long pfn;
-
- pfn = virt_to_phys((void *)pb->rawbuf[i]) >> PAGE_SHIFT;
- if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
- return -EAGAIN;
- start += PAGE_SIZE;
- if (size <= PAGE_SIZE)
- break;
- size -= PAGE_SIZE;
- }
- return 0;
-}
-
-static struct video_device planb_template=
-{
- .owner = THIS_MODULE,
- .name = PLANB_DEVICE_NAME,
- .type = VID_TYPE_OVERLAY,
- .open = planb_open,
- .close = planb_close,
- .read = planb_read,
- .write = planb_write,
- .ioctl = planb_ioctl,
- .mmap = planb_mmap, /* mmap? */
-};
-
-static int init_planb(struct planb *pb)
-{
- unsigned char saa_rev;
- int i, result;
-
- memset ((void *) &pb->win, 0, sizeof (struct planb_window));
- /* Simple sanity check */
- if(def_norm >= NUM_SUPPORTED_NORM || def_norm < 0) {
- printk(KERN_ERR "PlanB: Option(s) invalid\n");
- return -2;
- }
- pb->win.norm = def_norm;
- pb->win.mode = PLANB_TV_MODE; /* TV mode */
- pb->win.interlace=1;
- pb->win.x=0;
- pb->win.y=0;
- pb->win.width=768; /* 640 */
- pb->win.height=576; /* 480 */
- pb->maxlines=576;
-#if 0
- btv->win.cropwidth=768; /* 640 */
- btv->win.cropheight=576; /* 480 */
- btv->win.cropx=0;
- btv->win.cropy=0;
-#endif
- pb->win.pad=0;
- pb->win.bpp=4;
- pb->win.depth=32;
- pb->win.color_fmt=PLANB_COLOUR32;
- pb->win.bpl=1024*pb->win.bpp;
- pb->win.swidth=1024;
- pb->win.sheight=768;
-#ifdef PLANB_GSCANLINE
- if((pb->gbytes_per_line = PLANB_MAXPIXELS * 4) > PAGE_SIZE
- || (pb->gbytes_per_line <= 0))
- return -3;
- else {
- /* page align pb->gbytes_per_line for DMA purpose */
- for(i = PAGE_SIZE; pb->gbytes_per_line < (i>>1);)
- i>>=1;
- pb->gbytes_per_line = i;
- }
-#endif
- pb->tab_size = PLANB_MAXLINES + 40;
- pb->suspend = 0;
- mutex_init(&pb->lock);
- pb->ch1_cmd = 0;
- pb->ch2_cmd = 0;
- pb->mask = 0;
- pb->priv_space = 0;
- pb->offset = 0;
- pb->user = 0;
- pb->overlay = 0;
- init_waitqueue_head(&pb->suspendq);
- pb->cmd_buff_inited = 0;
- pb->frame_buffer_phys = 0;
-
- /* Reset DMA controllers */
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
-
- saa_rev = (saa_status(0, pb) & 0xf0) >> 4;
- printk(KERN_INFO "PlanB: SAA7196 video processor rev. %d\n", saa_rev);
- /* Initialize the SAA registers in memory and on chip */
- saa_init_regs (pb);
-
- /* clear interrupt mask */
- pb->intr_mask = PLANB_CLR_IRQ;
-
- result = request_irq(pb->irq, planb_irq, 0, "PlanB", pb);
- if (result < 0) {
- if (result==-EINVAL)
- printk(KERN_ERR "PlanB: Bad irq number (%d) "
- "or handler\n", (int)pb->irq);
- else if (result==-EBUSY)
- printk(KERN_ERR "PlanB: I don't know why, "
- "but IRQ %d is busy\n", (int)pb->irq);
- return result;
- }
- disable_irq(pb->irq);
-
- /* Now add the template and register the device unit. */
- memcpy(&pb->video_dev,&planb_template,sizeof(planb_template));
-
- pb->picture.brightness=0x90<<8;
- pb->picture.contrast = 0x70 << 8;
- pb->picture.colour = 0x70<<8;
- pb->picture.hue = 0x8000;
- pb->picture.whiteness = 0;
- pb->picture.depth = pb->win.depth;
-
- pb->frame_stat=NULL;
- init_waitqueue_head(&pb->capq);
- for(i=0; i<MAX_GBUFFERS; i++) {
- pb->gbuf_idx[i] = PLANB_MAX_FBUF * i / PAGE_SIZE;
- pb->gwidth[i]=0;
- pb->gheight[i]=0;
- pb->gfmt[i]=0;
- pb->cap_cmd[i]=NULL;
-#ifndef PLANB_GSCANLINE
- pb->l_fr_addr_idx[i] = MAX_GBUFFERS * (PLANB_MAX_FBUF
- / PAGE_SIZE + 1) + MAX_LNUM * i;
- pb->lsize[i] = 0;
- pb->lnum[i] = 0;
-#endif
- }
- pb->rawbuf=NULL;
- pb->grabbing=0;
-
- /* enable interrupts */
- out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
- pb->intr_mask = PLANB_FRM_IRQ;
- enable_irq(pb->irq);
-
- if(video_register_device(&pb->video_dev, VFL_TYPE_GRABBER, video_nr)<0)
- return -1;
-
- return 0;
-}
-
-/*
- * Scan for a PlanB controller, request the irq and map the io memory
- */
-
-static int find_planb(void)
-{
- struct planb *pb;
- struct device_node *planb_devices;
- unsigned char dev_fn, confreg, bus;
- unsigned int old_base, new_base;
- unsigned int irq;
- struct pci_dev *pdev;
- int rc;
-
- if (!machine_is(powermac))
- return 0;
-
- planb_devices = of_find_node_by_name(NULL, "planb");
- if (planb_devices == 0) {
- planb_num=0;
- printk(KERN_WARNING "PlanB: no device found!\n");
- return planb_num;
- }
-
- if (planb_devices->next != NULL)
- printk(KERN_ERR "Warning: only using first PlanB device!\n");
- pb = &planbs[0];
- planb_num = 1;
-
- if (planb_devices->n_addrs != 1) {
- printk (KERN_WARNING "PlanB: expecting 1 address for planb "
- "(got %d)", planb_devices->n_addrs);
- of_node_put(planb_devices);
- return 0;
- }
-
- if (planb_devices->n_intrs == 0) {
- printk(KERN_WARNING "PlanB: no intrs for device %s\n",
- planb_devices->full_name);
- of_node_put(planb_devices);
- return 0;
- } else {
- irq = planb_devices->intrs[0].line;
- }
-
- /* Initialize PlanB's PCI registers */
-
- /* There is a bug with the way OF assigns addresses
- to the devices behind the chaos bridge.
- control needs only 0x1000 of space, but decodes only
- the upper 16 bits. It therefore occupies a full 64K.
- OF assigns the planb controller memory within this space;
- so we need to change that here in order to access planb. */
-
- /* We remap to 0xf1000000 in hope that nobody uses it ! */
-
- bus = (planb_devices->addrs[0].space >> 16) & 0xff;
- dev_fn = (planb_devices->addrs[0].space >> 8) & 0xff;
- confreg = planb_devices->addrs[0].space & 0xff;
- old_base = planb_devices->addrs[0].address;
- new_base = 0xf1000000;
- of_node_put(planb_devices);
-
- DEBUG("PlanB: Found on bus %d, dev %d, func %d, "
- "membase 0x%x (base reg. 0x%x)\n",
- bus, PCI_SLOT(dev_fn), PCI_FUNC(dev_fn), old_base, confreg);
-
- pdev = pci_get_bus_and_slot(bus, dev_fn);
- if (!pdev) {
- printk(KERN_ERR "planb: cannot find slot\n");
- goto err_out;
- }
-
- /* Enable response in memory space, bus mastering,
- use memory write and invalidate */
- rc = pci_enable_device(pdev);
- if (rc) {
- printk(KERN_ERR "planb: cannot enable PCI device %s\n",
- pci_name(pdev));
- goto err_out;
- }
- rc = pci_set_mwi(pdev);
- if (rc) {
- printk(KERN_ERR "planb: cannot enable MWI on PCI device %s\n",
- pci_name(pdev));
- goto err_out_disable;
- }
- pci_set_master(pdev);
-
- /* Set the new base address */
- pci_write_config_dword (pdev, confreg, new_base);
-
- planb_regs = (volatile struct planb_registers *)
- ioremap (new_base, 0x400);
- pb->planb_base = planb_regs;
- pb->planb_base_phys = (struct planb_registers *)new_base;
- pb->irq = irq;
- pb->dev = pdev;
-
- return planb_num;
-
-err_out_disable:
- pci_disable_device(pdev);
-err_out:
- /* FIXME handle error */ /* comment moved from pci_find_slot, above */
- pci_dev_put(pdev);
- return 0;
-}
-
-static void release_planb(void)
-{
- int i;
- struct planb *pb;
-
- for (i=0;i<planb_num; i++)
- {
- pb=&planbs[i];
-
- /* stop and flash DMAs unconditionally */
- planb_dbdma_stop(&pb->planb_base->ch2);
- planb_dbdma_stop(&pb->planb_base->ch1);
-
- /* clear and free interrupts */
- pb->intr_mask = PLANB_CLR_IRQ;
- out_le32 (&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
- free_irq(pb->irq, pb);
-
- /* make sure all allocated memory are freed */
- planb_prepare_close(pb);
-
- printk(KERN_INFO "PlanB: unregistering with v4l\n");
- video_unregister_device(&pb->video_dev);
-
- pci_dev_put(pb->dev);
-
- /* note that iounmap() does nothing on the PPC right now */
- iounmap ((void *)pb->planb_base);
- }
-}
-
-static int __init init_planbs(void)
-{
- int i;
-
- if (find_planb()<=0)
- return -EIO;
-
- for (i=0; i<planb_num; i++) {
- if (init_planb(&planbs[i])<0) {
- printk(KERN_ERR "PlanB: error registering device %d"
- " with v4l\n", i);
- release_planb();
- return -EIO;
- }
- printk(KERN_INFO "PlanB: registered device %d with v4l\n", i);
- }
- return 0;
-}
-
-static void __exit exit_planbs(void)
-{
- release_planb();
-}
-
-module_init(init_planbs);
-module_exit(exit_planbs);
diff --git a/drivers/media/video/planb.h b/drivers/media/video/planb.h
index e21b5735c10..e69de29bb2d 100644
--- a/drivers/media/video/planb.h
+++ b/drivers/media/video/planb.h
@@ -1,232 +0,0 @@
-/*
- planb - PlanB frame grabber driver
-
- PlanB is used in the 7x00/8x00 series of PowerMacintosh
- Computers as video input DMA controller.
-
- Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
-
- Based largely on the bttv driver by Ralph Metzler (rjkm@thp.uni-koeln.de)
-
- Additional debugging and coding by Takashi Oe (toe@unlserve.unl.edu)
-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* $Id: planb.h,v 1.13 1999/05/03 19:28:56 mlan Exp $ */
-
-#ifndef _PLANB_H_
-#define _PLANB_H_
-
-#ifdef __KERNEL__
-#include <asm/dbdma.h>
-#include "saa7196.h"
-#endif /* __KERNEL__ */
-
-#define PLANB_DEVICE_NAME "Apple PlanB Video-In"
-#define PLANB_REV "1.0"
-
-#ifdef __KERNEL__
-//#define PLANB_GSCANLINE /* use this if apps have the notion of */
- /* grab buffer scanline */
-/* This should be safe for both PAL and NTSC */
-#define PLANB_MAXPIXELS 768
-#define PLANB_MAXLINES 576
-#define PLANB_NTSC_MAXLINES 480
-
-/* Uncomment your preferred norm ;-) */
-#define PLANB_DEF_NORM VIDEO_MODE_PAL
-//#define PLANB_DEF_NORM VIDEO_MODE_NTSC
-//#define PLANB_DEF_NORM VIDEO_MODE_SECAM
-
-/* fields settings */
-#define PLANB_GRAY 0x1 /* 8-bit mono? */
-#define PLANB_COLOUR15 0x2 /* 16-bit mode */
-#define PLANB_COLOUR32 0x4 /* 32-bit mode */
-#define PLANB_CLIPMASK 0x8 /* hardware clipmasking */
-
-/* misc. flags for PlanB DMA operation */
-#define CH_SYNC 0x1 /* synchronize channels (set by ch1;
- cleared by ch2) */
-#define FIELD_SYNC 0x2 /* used for the start of each field
- (0 -> 1 -> 0 for ch1; 0 -> 1 for ch2) */
-#define EVEN_FIELD 0x0 /* even field is detected if unset */
-#define DMA_ABORT 0x2 /* error or just out of sync if set */
-#define ODD_FIELD 0x4 /* odd field is detected if set */
-
-/* for capture operations */
-#define MAX_GBUFFERS 2
-/* note PLANB_MAX_FBUF must be divisible by PAGE_SIZE */
-#ifdef PLANB_GSCANLINE
-#define PLANB_MAX_FBUF 0x240000 /* 576 * 1024 * 4 */
-#define TAB_FACTOR (1)
-#else
-#define PLANB_MAX_FBUF 0x1b0000 /* 576 * 768 * 4 */
-#define TAB_FACTOR (2)
-#endif
-#endif /* __KERNEL__ */
-
-struct planb_saa_regs {
- unsigned char addr;
- unsigned char val;
-};
-
-struct planb_stat_regs {
- unsigned int ch1_stat;
- unsigned int ch2_stat;
- unsigned char saa_stat0;
- unsigned char saa_stat1;
-};
-
-struct planb_any_regs {
- unsigned int offset;
- unsigned int bytes;
- unsigned char data[128];
-};
-
-/* planb private ioctls */
-#define PLANBIOCGSAAREGS _IOWR('v', BASE_VIDIOCPRIVATE, struct planb_saa_regs) /* Read a saa7196 reg value */
-#define PLANBIOCSSAAREGS _IOW('v', BASE_VIDIOCPRIVATE + 1, struct planb_saa_regs) /* Set a saa7196 reg value */
-#define PLANBIOCGSTAT _IOR('v', BASE_VIDIOCPRIVATE + 2, struct planb_stat_regs) /* Read planb status */
-#define PLANB_TV_MODE 1
-#define PLANB_VTR_MODE 2
-#define PLANBIOCGMODE _IOR('v', BASE_VIDIOCPRIVATE + 3, int) /* Get TV/VTR mode */
-#define PLANBIOCSMODE _IOW('v', BASE_VIDIOCPRIVATE + 4, int) /* Set TV/VTR mode */
-
-#ifdef PLANB_GSCANLINE
-#define PLANBG_GRAB_BPL _IOR('v', BASE_VIDIOCPRIVATE + 5, int) /* # of bytes per scanline in grab buffer */
-#endif
-
-/* call wake_up_interruptible() with appropriate actions */
-#define PLANB_INTR_DEBUG _IOW('v', BASE_VIDIOCPRIVATE + 20, int)
-/* investigate which reg does what */
-#define PLANB_INV_REGS _IOWR('v', BASE_VIDIOCPRIVATE + 21, struct planb_any_regs)
-
-#ifdef __KERNEL__
-
-/* Potentially useful macros */
-#define PLANB_SET(x) ((x) << 16 | (x))
-#define PLANB_CLR(x) ((x) << 16)
-
-/* This represents the physical register layout */
-struct planb_registers {
- volatile struct dbdma_regs ch1; /* 0x00: video in */
- volatile unsigned int even; /* 0x40: even field setting */
- volatile unsigned int odd; /* 0x44; odd field setting */
- unsigned int pad1[14]; /* empty? */
- volatile struct dbdma_regs ch2; /* 0x80: clipmask out */
- unsigned int pad2[16]; /* 0xc0: empty? */
- volatile unsigned int reg3; /* 0x100: ???? */
- volatile unsigned int intr_stat; /* 0x104: irq status */
-#define PLANB_CLR_IRQ 0x00 /* clear Plan B interrupt */
-#define PLANB_GEN_IRQ 0x01 /* assert Plan B interrupt */
-#define PLANB_FRM_IRQ 0x0100 /* end of frame */
- unsigned int pad3[1]; /* empty? */
- volatile unsigned int reg5; /* 0x10c: ??? */
- unsigned int pad4[60]; /* empty? */
- volatile unsigned char saa_addr; /* 0x200: SAA subadr */
- char pad5[3];
- volatile unsigned char saa_regval; /* SAA7196 write reg. val */
- char pad6[3];
- volatile unsigned char saa_status; /* SAA7196 status byte */
- /* There is more unused stuff here */
-};
-
-struct planb_window {
- int x, y;
- ushort width, height;
- ushort bpp, bpl, depth, pad;
- ushort swidth, sheight;
- int norm;
- int interlace;
- u32 color_fmt;
- int chromakey;
- int mode; /* used to switch between TV/VTR modes */
-};
-
-struct planb_suspend {
- int overlay;
- int frame;
- struct dbdma_cmd cmd;
-};
-
-struct planb {
- struct video_device video_dev;
- struct video_picture picture; /* Current picture params */
- struct video_audio audio_dev; /* Current audio params */
-
- volatile struct planb_registers *planb_base; /* virt base of planb */
- struct planb_registers *planb_base_phys; /* phys base of planb */
- void *priv_space; /* Org. alloc. mem for kfree */
- int user;
- unsigned int tab_size;
- int maxlines;
- struct mutex lock;
- unsigned int irq; /* interrupt number */
- volatile unsigned int intr_mask;
- struct pci_dev *dev; /* Our PCI device */
-
- int overlay; /* overlay running? */
- struct planb_window win;
- unsigned long frame_buffer_phys; /* We need phys for DMA */
- int offset; /* offset of pixel 1 */
- volatile struct dbdma_cmd *ch1_cmd; /* Video In DMA cmd buffer */
- volatile struct dbdma_cmd *ch2_cmd; /* Clip Out DMA cmd buffer */
- volatile struct dbdma_cmd *overlay_last1;
- volatile struct dbdma_cmd *overlay_last2;
- unsigned long ch1_cmd_phys;
- volatile unsigned char *mask; /* Clipmask buffer */
- int suspend;
- wait_queue_head_t suspendq;
- struct planb_suspend suspended;
- int cmd_buff_inited; /* cmd buffer inited? */
-
- int grabbing;
- unsigned int gcount;
- wait_queue_head_t capq;
- int last_fr;
- int prev_last_fr;
- unsigned char **rawbuf;
- int rawbuf_size;
- int gbuf_idx[MAX_GBUFFERS];
- volatile struct dbdma_cmd *cap_cmd[MAX_GBUFFERS];
- volatile struct dbdma_cmd *last_cmd[MAX_GBUFFERS];
- volatile struct dbdma_cmd *pre_cmd[MAX_GBUFFERS];
- int need_pre_capture[MAX_GBUFFERS];
-#define PLANB_DUMMY 40 /* # of command buf's allocated for pre-capture seq. */
- int gwidth[MAX_GBUFFERS], gheight[MAX_GBUFFERS];
- unsigned int gfmt[MAX_GBUFFERS];
- int gnorm_switch[MAX_GBUFFERS];
- volatile unsigned int *frame_stat;
-#define GBUFFER_UNUSED 0x00U
-#define GBUFFER_GRABBING 0x01U
-#define GBUFFER_DONE 0x02U
-#ifdef PLANB_GSCANLINE
- int gbytes_per_line;
-#else
-#define MAX_LNUM 431 /* change this if PLANB_MAXLINES or */
- /* PLANB_MAXPIXELS changes */
- int l_fr_addr_idx[MAX_GBUFFERS];
- unsigned char *l_to_addr[MAX_GBUFFERS][MAX_LNUM];
- int l_to_next_idx[MAX_GBUFFERS][MAX_LNUM];
- int l_to_next_size[MAX_GBUFFERS][MAX_LNUM];
- int lsize[MAX_GBUFFERS], lnum[MAX_GBUFFERS];
-#endif
-};
-
-#endif /* __KERNEL__ */
-
-#endif /* _PLANB_H_ */
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index 51b1461d8fb..00425d74365 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -30,6 +30,7 @@
#include <asm/io.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
@@ -894,9 +895,7 @@ static const struct file_operations pms_fops = {
static struct video_device pms_template=
{
- .owner = THIS_MODULE,
.name = "Mediavision PMS",
- .type = VID_TYPE_CAPTURE,
.fops = &pms_fops,
};
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
index 4482b2c72ce..19eb274c9cd 100644
--- a/drivers/media/video/pvrusb2/Kconfig
+++ b/drivers/media/video/pvrusb2/Kconfig
@@ -2,8 +2,6 @@ config VIDEO_PVRUSB2
tristate "Hauppauge WinTV-PVR USB2 support"
depends on VIDEO_V4L2 && I2C
depends on VIDEO_MEDIA # Avoids pvrusb = Y / DVB = M
- depends on HOTPLUG # due to FW_LOADER
- select FW_LOADER
select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_CX2341X
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.h b/drivers/media/video/pvrusb2/pvrusb2-context.h
index 61801291c2a..d657e53bbfa 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-context.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-context.h
@@ -16,8 +16,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-#ifndef __PVRUSB2_BASE_H
-#define __PVRUSB2_BASE_H
+#ifndef __PVRUSB2_CONTEXT_H
+#define __PVRUSB2_CONTEXT_H
#include <linux/mutex.h>
#include <linux/usb.h>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 5d036e7e3f0..88e17516843 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -97,13 +97,13 @@ static const struct pvr2_device_desc pvr2_device_24xxx = {
.flag_has_cx25840 = !0,
.flag_has_wm8775 = !0,
.flag_has_hauppauge_rom = !0,
- .flag_has_hauppauge_custom_ir = !0,
.flag_has_analogtuner = !0,
.flag_has_fmradio = !0,
.flag_has_composite = !0,
.flag_has_svideo = !0,
.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+ .ir_scheme = PVR2_IR_SCHEME_24XXX,
};
@@ -330,7 +330,7 @@ static const char *pvr2_fw1_names_73xxx[] = {
};
static const struct pvr2_device_desc pvr2_device_73xxx = {
- .description = "WinTV PVR USB2 Model Category 73xxx",
+ .description = "WinTV HVR-1900 Model Category 73xxx",
.shortname = "73xxx",
.client_modules.lst = pvr2_client_73xxx,
.client_modules.cnt = ARRAY_SIZE(pvr2_client_73xxx),
@@ -344,6 +344,7 @@ static const struct pvr2_device_desc pvr2_device_73xxx = {
.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+ .ir_scheme = PVR2_IR_SCHEME_ZILOG,
#ifdef CONFIG_VIDEO_PVRUSB2_DVB
.dvb_props = &pvr2_73xxx_dvb_props,
#endif
@@ -438,7 +439,7 @@ static const char *pvr2_fw1_names_75xxx[] = {
};
static const struct pvr2_device_desc pvr2_device_750xx = {
- .description = "WinTV PVR USB2 Model Category 750xx",
+ .description = "WinTV HVR-1950 Model Category 750xx",
.shortname = "750xx",
.client_modules.lst = pvr2_client_75xxx,
.client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx),
@@ -453,13 +454,14 @@ static const struct pvr2_device_desc pvr2_device_750xx = {
.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
.default_std_mask = V4L2_STD_NTSC_M,
.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+ .ir_scheme = PVR2_IR_SCHEME_ZILOG,
#ifdef CONFIG_VIDEO_PVRUSB2_DVB
.dvb_props = &pvr2_750xx_dvb_props,
#endif
};
static const struct pvr2_device_desc pvr2_device_751xx = {
- .description = "WinTV PVR USB2 Model Category 751xx",
+ .description = "WinTV HVR-1950 Model Category 751xx",
.shortname = "751xx",
.client_modules.lst = pvr2_client_75xxx,
.client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx),
@@ -474,6 +476,7 @@ static const struct pvr2_device_desc pvr2_device_751xx = {
.digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE,
.default_std_mask = V4L2_STD_NTSC_M,
.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+ .ir_scheme = PVR2_IR_SCHEME_ZILOG,
#ifdef CONFIG_VIDEO_PVRUSB2_DVB
.dvb_props = &pvr2_751xx_dvb_props,
#endif
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index e23ce1d2edd..cb3a33eb027 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -48,6 +48,10 @@ struct pvr2_string_table {
#define PVR2_LED_SCHEME_NONE 0
#define PVR2_LED_SCHEME_HAUPPAUGE 1
+#define PVR2_IR_SCHEME_NONE 0
+#define PVR2_IR_SCHEME_24XXX 1
+#define PVR2_IR_SCHEME_ZILOG 2
+
/* This describes a particular hardware type (except for the USB device ID
which must live in a separate structure due to environmental
constraints). See the top of pvrusb2-hdw.c for where this is
@@ -126,15 +130,19 @@ struct pvr2_device_desc {
ensure that it is found. */
unsigned int flag_has_wm8775:1;
- /* Device has IR hardware that can be faked into looking like a
- normal Hauppauge i2c IR receiver. This is currently very
- specific to the 24xxx device, where Hauppauge had replaced their
- 'standard' I2C IR receiver with a bunch of FPGA logic controlled
- directly via the FX2. Turning this on tells the pvrusb2 driver
- to virtualize the presence of the non-existant IR receiver chip and
- implement the virtual receiver in terms of appropriate FX2
- commands. */
- unsigned int flag_has_hauppauge_custom_ir:1;
+ /* Indicate any specialized IR scheme that might need to be
+ supported by this driver. If not set, then it is assumed that
+ IR can work without help from the driver (which is frequently
+ the case). This is otherwise set to one of
+ PVR2_IR_SCHEME_xxxx. For "xxxx", the value "24XXX" indicates a
+ Hauppauge 24xxx class device which has an FPGA-hosted IR
+ receiver that can only be reached via FX2 command codes. In
+ that case the pvrusb2 driver will emulate the behavior of the
+ older 29xxx device's IR receiver (a "virtual" I2C chip) in terms
+ of those command codes. For the value "ZILOG", we're dealing
+ with an IR chip that must be taken out of reset via another FX2
+ command code (which is the case for HVR-1950 devices). */
+ unsigned int ir_scheme:2;
/* These bits define which kinds of sources the device can handle.
Note: Digital tuner presence is inferred by the
diff --git a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h
index b58369e7f30..614755ea2ea 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h
@@ -24,6 +24,8 @@
#define FX2CMD_MEM_WRITE_DWORD 0x01u
#define FX2CMD_MEM_READ_DWORD 0x02u
+#define FX2CMD_HCW_ZILOG_RESET 0x10u /* 1=reset 0=release */
+
#define FX2CMD_MEM_READ_64BYTES 0x28u
#define FX2CMD_REG_WRITE 0x04u
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index a5217a2cf4c..f051c6aa7f1 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -250,6 +250,7 @@ struct pvr2_fx2cmd_descdef {
static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = {
{FX2CMD_MEM_WRITE_DWORD, "write encoder dword"},
{FX2CMD_MEM_READ_DWORD, "read encoder dword"},
+ {FX2CMD_HCW_ZILOG_RESET, "zilog IR reset control"},
{FX2CMD_MEM_READ_64BYTES, "read encoder 64bytes"},
{FX2CMD_REG_WRITE, "write encoder register"},
{FX2CMD_REG_READ, "read encoder register"},
@@ -1711,6 +1712,14 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
if (!pvr2_hdw_dev_ok(hdw)) return;
}
+ /* Take the IR chip out of reset, if appropriate */
+ if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_ZILOG) {
+ pvr2_issue_simple_cmd(hdw,
+ FX2CMD_HCW_ZILOG_RESET |
+ (1 << 8) |
+ ((0) << 16));
+ }
+
// This step MUST happen after the earlier powerup step.
pvr2_i2c_core_init(hdw);
if (!pvr2_hdw_dev_ok(hdw)) return;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 9d3c18b2474..e600576a6c4 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -979,7 +979,9 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
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_desc->flag_has_hauppauge_custom_ir) {
+ if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_24XXX) {
+ /* This comment is present PURELY to get
+ checkpatch.pl to STFU. Lovely, eh? */
hdw->i2c_func[0x18] = i2c_24xxx_ir;
}
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 0d72dc470fe..00306faeac0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -30,6 +30,7 @@
#include <linux/videodev2.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
struct pvr2_v4l2_dev;
struct pvr2_v4l2_fh;
@@ -1160,11 +1161,6 @@ static const struct file_operations vdev_fops = {
static struct video_device vdev_template = {
- .owner = THIS_MODULE,
- .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER,
- .type2 = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE
- | V4L2_CAP_TUNER | V4L2_CAP_AUDIO
- | V4L2_CAP_READWRITE),
.fops = &vdev_fops,
};
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 423fa7c2d0c..9aee7cb6f79 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -165,9 +165,7 @@ static const struct file_operations pwc_fops = {
.llseek = no_llseek,
};
static struct video_device pwc_template = {
- .owner = THIS_MODULE,
.name = "Philips Webcam", /* Filled in later */
- .type = VID_TYPE_CAPTURE,
.release = video_device_release,
.fops = &pwc_fops,
.minor = -1,
@@ -1048,19 +1046,20 @@ static int pwc_create_sysfs_files(struct video_device *vdev)
struct pwc_device *pdev = video_get_drvdata(vdev);
int rc;
- rc = video_device_create_file(vdev, &dev_attr_button);
+ rc = device_create_file(&vdev->dev, &dev_attr_button);
if (rc)
goto err;
if (pdev->features & FEATURE_MOTOR_PANTILT) {
- rc = video_device_create_file(vdev, &dev_attr_pan_tilt);
+ rc = device_create_file(&vdev->dev, &dev_attr_pan_tilt);
if (rc) goto err_button;
}
return 0;
err_button:
- video_device_remove_file(vdev, &dev_attr_button);
+ device_remove_file(&vdev->dev, &dev_attr_button);
err:
+ PWC_ERROR("Could not create sysfs files.\n");
return rc;
}
@@ -1068,8 +1067,8 @@ static void pwc_remove_sysfs_files(struct video_device *vdev)
{
struct pwc_device *pdev = video_get_drvdata(vdev);
if (pdev->features & FEATURE_MOTOR_PANTILT)
- video_device_remove_file(vdev, &dev_attr_pan_tilt);
- video_device_remove_file(vdev, &dev_attr_button);
+ device_remove_file(&vdev->dev, &dev_attr_pan_tilt);
+ device_remove_file(&vdev->dev, &dev_attr_button);
}
#ifdef CONFIG_USB_PWC_DEBUG
@@ -1767,9 +1766,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
return -ENOMEM;
}
memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template));
- pdev->vdev->dev = &(udev->dev);
+ pdev->vdev->parent = &(udev->dev);
strcpy(pdev->vdev->name, name);
- pdev->vdev->owner = THIS_MODULE;
video_set_drvdata(pdev->vdev, pdev);
pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 8e8e5b27e77..74178754b39 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -32,9 +32,11 @@
#include <linux/smp_lock.h>
#include <linux/version.h>
#include <linux/mutex.h>
+#include <linux/mm.h>
#include <asm/errno.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include "pwc-uncompress.h"
#include <media/pwc-ioctl.h>
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 04eb2c3fabd..b1d09d8e2b8 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -47,8 +47,10 @@
#include <linux/mutex.h>
#include <linux/videodev2.h>
#include <linux/version.h>
+#include <linux/mm.h>
#include <media/videobuf-vmalloc.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/vmalloc.h>
#include <linux/usb.h>
@@ -184,6 +186,7 @@ struct s2255_dmaqueue {
#define S2255_FW_LOADED_DSPWAIT 1
#define S2255_FW_SUCCESS 2
#define S2255_FW_FAILED 3
+#define S2255_FW_DISCONNECTING 4
struct s2255_fw {
int fw_loaded;
@@ -263,7 +266,6 @@ struct s2255_buffer {
struct s2255_fh {
struct s2255_dev *dev;
- unsigned int resources;
const struct s2255_fmt *fmt;
unsigned int width;
unsigned int height;
@@ -273,14 +275,9 @@ struct s2255_fh {
/* mode below is the desired mode.
mode in s2255_dev is the current mode that was last set */
struct s2255_mode mode;
+ int resources[MAX_CHANNELS];
};
-/*
- * TODO: fixme S2255_MAX_USERS. Do not limit open driver handles.
- * Limit V4L to one stream at a time.
- */
-#define S2255_MAX_USERS 1
-
#define CUR_USB_FWVER 774 /* current cypress EEPROM firmware version */
#define S2255_MAJOR_VERSION 1
#define S2255_MINOR_VERSION 13
@@ -476,10 +473,9 @@ static void s2255_timer(unsigned long user_data)
dprintk(100, "s2255 timer\n");
if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
printk(KERN_ERR "s2255: can't submit urb\n");
- if (data->fw) {
- release_firmware(data->fw);
- data->fw = NULL;
- }
+ atomic_set(&data->fw_state, S2255_FW_FAILED);
+ /* wake up anything waiting for the firmware */
+ wake_up(&data->wait_fw);
return;
}
}
@@ -509,13 +505,18 @@ static void s2255_fwchunk_complete(struct urb *urb)
struct usb_device *udev = urb->dev;
int len;
dprintk(100, "udev %p urb %p", udev, urb);
- /* TODO: fixme. reflect change in status */
if (urb->status) {
dev_err(&udev->dev, "URB failed with status %d", urb->status);
+ atomic_set(&data->fw_state, S2255_FW_FAILED);
+ /* wake up anything waiting for the firmware */
+ wake_up(&data->wait_fw);
return;
}
if (data->fw_urb == NULL) {
- dev_err(&udev->dev, "early disconncect\n");
+ dev_err(&udev->dev, "s2255 disconnected\n");
+ atomic_set(&data->fw_state, S2255_FW_FAILED);
+ /* wake up anything waiting for the firmware */
+ wake_up(&data->wait_fw);
return;
}
#define CHUNK_SIZE 512
@@ -789,7 +790,8 @@ static int res_get(struct s2255_dev *dev, struct s2255_fh *fh)
}
/* it's free, grab it */
dev->resources[fh->channel] = 1;
- dprintk(1, "res: get\n");
+ fh->resources[fh->channel] = 1;
+ dprintk(1, "s2255: res: get\n");
mutex_unlock(&dev->lock);
return 1;
}
@@ -799,9 +801,18 @@ static int res_locked(struct s2255_dev *dev, struct s2255_fh *fh)
return dev->resources[fh->channel];
}
+static int res_check(struct s2255_fh *fh)
+{
+ return fh->resources[fh->channel];
+}
+
+
static void res_free(struct s2255_dev *dev, struct s2255_fh *fh)
{
+ mutex_lock(&dev->lock);
dev->resources[fh->channel] = 0;
+ fh->resources[fh->channel] = 0;
+ mutex_unlock(&dev->lock);
dprintk(1, "res: put\n");
}
@@ -1232,7 +1243,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
}
if (!res_get(dev, fh)) {
- dev_err(&dev->udev->dev, "res get busy\n");
+ dev_err(&dev->udev->dev, "s2255: stream busy\n");
return -EBUSY;
}
@@ -1288,8 +1299,10 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
}
s2255_stop_acquire(dev, fh->channel);
res = videobuf_streamoff(&fh->vb_vidq);
+ if (res < 0)
+ return res;
res_free(dev, fh);
- return res;
+ return 0;
}
static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
@@ -1462,12 +1475,7 @@ static int s2255_open(struct inode *inode, struct file *file)
mutex_lock(&dev->open_lock);
dev->users[cur_channel]++;
- if (dev->users[cur_channel] > S2255_MAX_USERS) {
- dev->users[cur_channel]--;
- mutex_unlock(&dev->open_lock);
- printk(KERN_INFO "s2255drv: too many open handles!\n");
- return -EBUSY;
- }
+ dprintk(4, "s2255: open_handles %d\n", dev->users[cur_channel]);
if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_FAILED) {
err("2255 firmware load failed. retrying.\n");
@@ -1478,7 +1486,8 @@ static int s2255_open(struct inode *inode, struct file *file)
msecs_to_jiffies(S2255_LOAD_TIMEOUT));
if (atomic_read(&dev->fw_data->fw_state)
!= S2255_FW_SUCCESS) {
- printk(KERN_INFO "2255 FW load failed after 2 tries\n");
+ printk(KERN_INFO "2255 FW load failed.\n");
+ dev->users[cur_channel]--;
mutex_unlock(&dev->open_lock);
return -EFAULT;
}
@@ -1494,6 +1503,7 @@ static int s2255_open(struct inode *inode, struct file *file)
!= S2255_FW_SUCCESS) {
printk(KERN_INFO "2255 firmware not loaded"
"try again\n");
+ dev->users[cur_channel]--;
mutex_unlock(&dev->open_lock);
return -EBUSY;
}
@@ -1502,6 +1512,7 @@ static int s2255_open(struct inode *inode, struct file *file)
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh), GFP_KERNEL);
if (NULL == fh) {
+ dev->users[cur_channel]--;
mutex_unlock(&dev->open_lock);
return -ENOMEM;
}
@@ -1561,44 +1572,48 @@ static void s2255_destroy(struct kref *kref)
printk(KERN_ERR "s2255drv: kref problem\n");
return;
}
+
+ /*
+ * Wake up any firmware load waiting (only done in .open,
+ * which holds the open_lock mutex)
+ */
+ atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
+ wake_up(&dev->fw_data->wait_fw);
+
/* prevent s2255_disconnect from racing s2255_open */
mutex_lock(&dev->open_lock);
s2255_exit_v4l(dev);
- /* device unregistered so no longer possible to open. open_mutex
- can be unlocked */
+ /*
+ * device unregistered so no longer possible to open. open_mutex
+ * can be unlocked and timers deleted afterwards.
+ */
mutex_unlock(&dev->open_lock);
/* board shutdown stops the read pipe if it is running */
s2255_board_shutdown(dev);
/* make sure firmware still not trying to load */
+ del_timer(&dev->timer); /* only started in .probe and .open */
+
if (dev->fw_data->fw_urb) {
dprintk(2, "kill fw_urb\n");
usb_kill_urb(dev->fw_data->fw_urb);
usb_free_urb(dev->fw_data->fw_urb);
dev->fw_data->fw_urb = NULL;
}
+
/*
- * TODO: fixme(above, below): potentially leaving timers alive.
- * do not ignore timeout below if
- * it occurs.
+ * delete the dsp_wait timer, which sets the firmware
+ * state on completion. This is done before fw_data
+ * is freed below.
*/
- /* make sure we aren't waiting for the DSP */
- if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_LOADED_DSPWAIT) {
- /* if we are, wait for the wakeup for fw_success or timeout */
- wait_event_timeout(dev->fw_data->wait_fw,
- (atomic_read(&dev->fw_data->fw_state)
- == S2255_FW_SUCCESS),
- msecs_to_jiffies(S2255_LOAD_TIMEOUT));
- }
+ del_timer(&dev->fw_data->dsp_wait); /* only started in .open */
- if (dev->fw_data) {
- if (dev->fw_data->fw)
- release_firmware(dev->fw_data->fw);
- kfree(dev->fw_data->pfw_data);
- kfree(dev->fw_data);
- }
+ if (dev->fw_data->fw)
+ release_firmware(dev->fw_data->fw);
+ kfree(dev->fw_data->pfw_data);
+ kfree(dev->fw_data);
usb_put_dev(dev->udev);
dprintk(1, "%s", __func__);
@@ -1615,17 +1630,23 @@ static int s2255_close(struct inode *inode, struct file *file)
mutex_lock(&dev->open_lock);
- if (dev->b_acquire[fh->channel])
- s2255_stop_acquire(dev, fh->channel);
- res_free(dev, fh);
+ /* turn off stream */
+ if (res_check(fh)) {
+ if (dev->b_acquire[fh->channel])
+ s2255_stop_acquire(dev, fh->channel);
+ videobuf_streamoff(&fh->vb_vidq);
+ res_free(dev, fh);
+ }
+
videobuf_mmap_free(&fh->vb_vidq);
- kfree(fh);
dev->users[fh->channel]--;
+
mutex_unlock(&dev->open_lock);
kref_put(&dev->kref, s2255_destroy);
dprintk(1, "s2255: close called (minor=%d, users=%d)\n",
minor, dev->users[fh->channel]);
+ kfree(fh);
return 0;
}
@@ -1658,12 +1679,7 @@ static const struct file_operations s2255_fops_v4l = {
.llseek = no_llseek,
};
-static struct video_device template = {
- .name = "s2255v",
- .type = VID_TYPE_CAPTURE,
- .fops = &s2255_fops_v4l,
- .minor = -1,
- .release = video_device_release,
+static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
@@ -1685,6 +1701,14 @@ static struct video_device template = {
#ifdef CONFIG_VIDEO_V4L1_COMPAT
.vidiocgmbuf = vidioc_cgmbuf,
#endif
+};
+
+static struct video_device template = {
+ .name = "s2255v",
+ .fops = &s2255_fops_v4l,
+ .ioctl_ops = &s2255_ioctl_ops,
+ .minor = -1,
+ .release = video_device_release,
.tvnorms = S2255_NORMS,
.current_norm = V4L2_STD_NTSC_M,
};
@@ -1706,7 +1730,7 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
/* register 4 video devices */
dev->vdev[i] = video_device_alloc();
memcpy(dev->vdev[i], &template, sizeof(struct video_device));
- dev->vdev[i]->dev = &dev->interface->dev;
+ dev->vdev[i]->parent = &dev->interface->dev;
if (video_nr == -1)
ret = video_register_device(dev->vdev[i],
VFL_TYPE_GRABBER,
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index 03e772130b5..6ee63e69b36 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -46,6 +46,7 @@
#include <linux/videotext.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/mutex.h>
#include "saa5246a.h"
@@ -829,9 +830,7 @@ static const struct file_operations saa_fops = {
static struct video_device saa_template =
{
- .owner = THIS_MODULE,
.name = IF_NAME,
- .type = VID_TYPE_TELETEXT,
.fops = &saa_fops,
.release = video_device_release,
.minor = -1,
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index fde99d9ee71..0d639738d4e 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -57,6 +57,7 @@
#include <linux/videotext.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/mutex.h>
@@ -710,9 +711,7 @@ static const struct file_operations saa_fops = {
static struct video_device saa_template =
{
- .owner = THIS_MODULE,
.name = IF_NAME,
- .type = VID_TYPE_TELETEXT, /*| VID_TYPE_TUNER ?? */
.fops = &saa_fops,
};
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 83f076abce3..7021bbf5897 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -27,9 +27,7 @@ config VIDEO_SAA7134_ALSA
config VIDEO_SAA7134_DVB
tristate "DVB/ATSC Support for saa7134 based TV cards"
depends on VIDEO_SAA7134 && DVB_CORE
- depends on HOTPLUG # due to FW_LOADER
select VIDEOBUF_DVB
- select FW_LOADER
select DVB_PLL if !DVB_FE_CUSTOMISE
select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 6893f998d29..98364d171de 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5853,9 +5853,6 @@ int saa7134_board_init2(struct saa7134_dev *dev)
unsigned char buf;
int board;
- dev->tuner_type = saa7134_boards[dev->board].tuner_type;
- dev->tuner_addr = saa7134_boards[dev->board].tuner_addr;
-
switch (dev->board) {
case SAA7134_BOARD_BMK_MPEX_NOTUNER:
case SAA7134_BOARD_BMK_MPEX_TUNER:
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index cfee84ee7a8..75d618415f4 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -798,7 +798,7 @@ static struct video_device *vdev_init(struct saa7134_dev *dev,
return NULL;
*vfd = *template;
vfd->minor = -1;
- vfd->dev = &dev->pci->dev;
+ vfd->parent = &dev->pci->dev;
vfd->release = video_device_release;
vfd->debug = video_debug;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
@@ -945,11 +945,12 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
dev->board = SAA7134_BOARD_UNKNOWN;
}
dev->autodetected = card[dev->nr] != dev->board;
- dev->tuner_type = saa7134_boards[dev->board].tuner_type;
+ dev->tuner_type = saa7134_boards[dev->board].tuner_type;
+ dev->tuner_addr = saa7134_boards[dev->board].tuner_addr;
dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
if (UNSET != tuner[dev->nr])
dev->tuner_type = tuner[dev->nr];
- printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+ printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
dev->name,pci_dev->subsystem_vendor,
pci_dev->subsystem_device,saa7134_boards[dev->board].name,
dev->board, dev->autodetected ?
@@ -1007,11 +1008,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
v4l2_prio_init(&dev->prio);
/* register v4l devices */
- if (saa7134_no_overlay <= 0) {
- saa7134_video_template.type |= VID_TYPE_OVERLAY;
- } else {
- printk("%s: Overlay support disabled.\n",dev->name);
- }
+ if (saa7134_no_overlay > 0)
+ printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name);
+
dev->video_dev = vdev_init(dev,&saa7134_video_template,"video");
err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
video_nr[dev->nr]);
@@ -1024,7 +1023,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
dev->name,dev->video_dev->minor & 0x1f);
dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi");
- dev->vbi_dev->type = VID_TYPE_TUNER | VID_TYPE_TELETEXT;
err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
vbi_nr[dev->nr]);
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 2a5ab957542..c0c5d7509c2 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -89,14 +89,14 @@ static int ts_open(struct inode *inode, struct file *file)
err = -EBUSY;
if (!mutex_trylock(&dev->empress_tsq.vb_lock))
goto done;
- if (dev->empress_users)
+ if (atomic_read(&dev->empress_users))
goto done_up;
/* Unmute audio */
saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6));
- dev->empress_users++;
+ atomic_inc(&dev->empress_users);
file->private_data = dev;
err = 0;
@@ -110,8 +110,6 @@ static int ts_release(struct inode *inode, struct file *file)
{
struct saa7134_dev *dev = file->private_data;
- mutex_lock(&dev->empress_tsq.vb_lock);
-
videobuf_stop(&dev->empress_tsq);
videobuf_mmap_free(&dev->empress_tsq);
@@ -122,9 +120,7 @@ static int ts_release(struct inode *inode, struct file *file)
saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
- dev->empress_users--;
-
- mutex_unlock(&dev->empress_tsq.vb_lock);
+ atomic_dec(&dev->empress_users);
return 0;
}
@@ -333,6 +329,22 @@ static int empress_g_ext_ctrls(struct file *file, void *priv,
return saa7134_i2c_call_saa6752(dev, VIDIOC_G_EXT_CTRLS, ctrls);
}
+static int empress_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *c)
+{
+ struct saa7134_dev *dev = file->private_data;
+
+ return saa7134_g_ctrl_internal(dev, NULL, c);
+}
+
+static int empress_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *c)
+{
+ struct saa7134_dev *dev = file->private_data;
+
+ return saa7134_s_ctrl_internal(dev, NULL, c);
+}
+
static int empress_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *c)
{
@@ -400,16 +412,7 @@ static const struct file_operations ts_fops =
.llseek = no_llseek,
};
-/* ----------------------------------------------------------- */
-
-static struct video_device saa7134_empress_template =
-{
- .name = "saa7134-empress",
- .type = 0 /* FIXME */,
- .type2 = 0 /* FIXME */,
- .fops = &ts_fops,
- .minor = -1,
-
+static const struct v4l2_ioctl_ops ts_ioctl_ops = {
.vidioc_querycap = empress_querycap,
.vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap,
@@ -428,8 +431,17 @@ static struct video_device saa7134_empress_template =
.vidioc_queryctrl = empress_queryctrl,
.vidioc_querymenu = empress_querymenu,
- .vidioc_g_ctrl = saa7134_g_ctrl,
- .vidioc_s_ctrl = saa7134_s_ctrl,
+ .vidioc_g_ctrl = empress_g_ctrl,
+ .vidioc_s_ctrl = empress_s_ctrl,
+};
+
+/* ----------------------------------------------------------- */
+
+static struct video_device saa7134_empress_template = {
+ .name = "saa7134-empress",
+ .fops = &ts_fops,
+ .minor = -1,
+ .ioctl_ops = &ts_ioctl_ops,
.tvnorms = SAA7134_NORMS,
.current_norm = V4L2_STD_PAL,
@@ -445,7 +457,7 @@ static void empress_signal_update(struct work_struct *work)
ts_reset_encoder(dev);
} else {
dprintk("video signal acquired\n");
- if (dev->empress_users)
+ if (atomic_read(&dev->empress_users))
ts_init_encoder(dev);
}
}
@@ -465,7 +477,7 @@ static int empress_init(struct saa7134_dev *dev)
if (NULL == dev->empress_dev)
return -ENOMEM;
*(dev->empress_dev) = saa7134_empress_template;
- dev->empress_dev->dev = &dev->pci->dev;
+ dev->empress_dev->parent = &dev->pci->dev;
dev->empress_dev->release = video_device_release;
snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
"%s empress (%s)", dev->name,
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 1a5137550e7..68c26898186 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1112,10 +1112,8 @@ static struct videobuf_queue_ops video_qops = {
/* ------------------------------------------------------------------ */
-int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c)
+int saa7134_g_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c)
{
- struct saa7134_fh *fh = priv;
- struct saa7134_dev *dev = fh->dev;
const struct v4l2_queryctrl* ctrl;
ctrl = ctrl_by_id(c->id);
@@ -1160,20 +1158,31 @@ int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c)
}
return 0;
}
-EXPORT_SYMBOL_GPL(saa7134_g_ctrl);
+EXPORT_SYMBOL_GPL(saa7134_g_ctrl_internal);
+
+static int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c)
+{
+ struct saa7134_fh *fh = priv;
+
+ return saa7134_g_ctrl_internal(fh->dev, fh, c);
+}
-int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c)
+int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c)
{
const struct v4l2_queryctrl* ctrl;
- struct saa7134_fh *fh = f;
- struct saa7134_dev *dev = fh->dev;
unsigned long flags;
int restart_overlay = 0;
- int err = -EINVAL;
+ int err;
- err = v4l2_prio_check(&dev->prio, &fh->prio);
- if (0 != err)
- return err;
+ /* When called from the empress code fh == NULL.
+ That needs to be fixed somehow, but for now this is
+ good enough. */
+ if (fh) {
+ err = v4l2_prio_check(&dev->prio, &fh->prio);
+ if (0 != err)
+ return err;
+ }
+ err = -EINVAL;
mutex_lock(&dev->lock);
@@ -1274,7 +1283,14 @@ error:
mutex_unlock(&dev->lock);
return err;
}
-EXPORT_SYMBOL_GPL(saa7134_s_ctrl);
+EXPORT_SYMBOL_GPL(saa7134_s_ctrl_internal);
+
+static int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c)
+{
+ struct saa7134_fh *fh = f;
+
+ return saa7134_s_ctrl_internal(fh->dev, fh, c);
+}
/* ------------------------------------------------------------------ */
@@ -2353,26 +2369,7 @@ static const struct file_operations video_fops =
.llseek = no_llseek,
};
-static const struct file_operations radio_fops =
-{
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .ioctl = video_ioctl2,
- .compat_ioctl = v4l_compat_ioctl32,
- .llseek = no_llseek,
-};
-
-/* ----------------------------------------------------------- */
-/* exported stuff */
-
-struct video_device saa7134_video_template =
-{
- .name = "saa7134-video",
- .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER |
- VID_TYPE_CLIPPING|VID_TYPE_SCALES,
- .fops = &video_fops,
- .minor = -1,
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_querycap = saa7134_querycap,
.vidioc_enum_fmt_vid_cap = saa7134_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = saa7134_g_fmt_vid_cap,
@@ -2421,16 +2418,18 @@ struct video_device saa7134_video_template =
.vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register,
#endif
- .tvnorms = SAA7134_NORMS,
- .current_norm = V4L2_STD_PAL,
};
-struct video_device saa7134_radio_template =
-{
- .name = "saa7134-radio",
- .type = VID_TYPE_TUNER,
- .fops = &radio_fops,
- .minor = -1,
+static const struct file_operations radio_fops = {
+ .owner = THIS_MODULE,
+ .open = video_open,
+ .release = video_release,
+ .ioctl = video_ioctl2,
+ .compat_ioctl = v4l_compat_ioctl32,
+ .llseek = no_llseek,
+};
+
+static const struct v4l2_ioctl_ops radio_ioctl_ops = {
.vidioc_querycap = radio_querycap,
.vidioc_g_tuner = radio_g_tuner,
.vidioc_enum_input = radio_enum_input,
@@ -2447,6 +2446,25 @@ struct video_device saa7134_radio_template =
.vidioc_s_frequency = saa7134_s_frequency,
};
+/* ----------------------------------------------------------- */
+/* exported stuff */
+
+struct video_device saa7134_video_template = {
+ .name = "saa7134-video",
+ .fops = &video_fops,
+ .ioctl_ops = &video_ioctl_ops,
+ .minor = -1,
+ .tvnorms = SAA7134_NORMS,
+ .current_norm = V4L2_STD_PAL,
+};
+
+struct video_device saa7134_radio_template = {
+ .name = "saa7134-radio",
+ .fops = &radio_fops,
+ .ioctl_ops = &radio_ioctl_ops,
+ .minor = -1,
+};
+
int saa7134_video_init1(struct saa7134_dev *dev)
{
/* sanitycheck insmod options */
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 6927cbea862..a0884f639f6 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -34,6 +34,7 @@
#include <asm/io.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/tuner.h>
#include <media/ir-common.h>
#include <media/ir-kbd-i2c.h>
@@ -560,7 +561,7 @@ struct saa7134_dev {
/* SAA7134_MPEG_EMPRESS only */
struct video_device *empress_dev;
struct videobuf_queue empress_tsq;
- unsigned int empress_users;
+ atomic_t empress_users;
struct work_struct empress_workqueue;
int empress_started;
@@ -662,8 +663,8 @@ extern unsigned int video_debug;
extern struct video_device saa7134_video_template;
extern struct video_device saa7134_radio_template;
-int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c);
-int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c);
+int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c);
+int saa7134_g_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c);
int saa7134_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c);
int saa7134_videoport_init(struct saa7134_dev *dev);
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index 2220f956994..af60ede5310 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -35,7 +35,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/videodev.h>
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/v4l2-common.h>
diff --git a/drivers/media/video/saa7196.h b/drivers/media/video/saa7196.h
index cd4b6354a7b..e69de29bb2d 100644
--- a/drivers/media/video/saa7196.h
+++ b/drivers/media/video/saa7196.h
@@ -1,117 +0,0 @@
-/*
- Definitions for the Philips SAA7196 digital video decoder,
- scaler, and clock generator circuit (DESCpro), as used in
- the PlanB video input of the Powermac 7x00/8x00 series.
-
- Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
-
- The register defines are shamelessly copied from the meteor
- driver out of NetBSD (with permission),
- and are copyrighted (c) 1995 Mark Tinguely and Jim Lowe
- (Thanks !)
-
- Additional debugging and coding by Takashi Oe (toe@unlinfo.unl.edu)
-
- The default values used for PlanB are my mistakes.
-*/
-
-/* $Id: saa7196.h,v 1.5 1999/03/26 23:28:47 mlan Exp $ */
-
-#ifndef _SAA7196_H_
-#define _SAA7196_H_
-
-#define SAA7196_NUMREGS 0x31 /* Number of registers (used)*/
-#define NUM_SUPPORTED_NORM 3 /* Number of supported norms by PlanB */
-
-/* Decoder part: */
-#define SAA7196_IDEL 0x00 /* Increment delay */
-#define SAA7196_HSB5 0x01 /* H-sync begin; 50 hz */
-#define SAA7196_HSS5 0x02 /* H-sync stop; 50 hz */
-#define SAA7196_HCB5 0x03 /* H-clamp begin; 50 hz */
-#define SAA7196_HCS5 0x04 /* H-clamp stop; 50 hz */
-#define SAA7196_HSP5 0x05 /* H-sync after PHI1; 50 hz */
-#define SAA7196_LUMC 0x06 /* Luminance control */
-#define SAA7196_HUEC 0x07 /* Hue control */
-#define SAA7196_CKTQ 0x08 /* Colour Killer Threshold QAM (PAL, NTSC) */
-#define SAA7196_CKTS 0x09 /* Colour Killer Threshold SECAM */
-#define SAA7196_PALS 0x0a /* PAL switch sensitivity */
-#define SAA7196_SECAMS 0x0b /* SECAM switch sensitivity */
-#define SAA7196_CGAINC 0x0c /* Chroma gain control */
-#define SAA7196_STDC 0x0d /* Standard/Mode control */
-#define SAA7196_IOCC 0x0e /* I/O and Clock Control */
-#define SAA7196_CTRL1 0x0f /* Control #1 */
-#define SAA7196_CTRL2 0x10 /* Control #2 */
-#define SAA7196_CGAINR 0x11 /* Chroma Gain Reference */
-#define SAA7196_CSAT 0x12 /* Chroma Saturation */
-#define SAA7196_CONT 0x13 /* Luminance Contrast */
-#define SAA7196_HSB6 0x14 /* H-sync begin; 60 hz */
-#define SAA7196_HSS6 0x15 /* H-sync stop; 60 hz */
-#define SAA7196_HCB6 0x16 /* H-clamp begin; 60 hz */
-#define SAA7196_HCS6 0x17 /* H-clamp stop; 60 hz */
-#define SAA7196_HSP6 0x18 /* H-sync after PHI1; 60 hz */
-#define SAA7196_BRIG 0x19 /* Luminance Brightness */
-
-/* Scaler part: */
-#define SAA7196_FMTS 0x20 /* Formats and sequence */
-#define SAA7196_OUTPIX 0x21 /* Output data pixel/line */
-#define SAA7196_INPIX 0x22 /* Input data pixel/line */
-#define SAA7196_HWS 0x23 /* Horiz. window start */
-#define SAA7196_HFILT 0x24 /* Horiz. filter */
-#define SAA7196_OUTLINE 0x25 /* Output data lines/field */
-#define SAA7196_INLINE 0x26 /* Input data lines/field */
-#define SAA7196_VWS 0x27 /* Vertical window start */
-#define SAA7196_VYP 0x28 /* AFS/vertical Y processing */
-#define SAA7196_VBS 0x29 /* Vertical Bypass start */
-#define SAA7196_VBCNT 0x2a /* Vertical Bypass count */
-#define SAA7196_VBP 0x2b /* veritcal Bypass Polarity */
-#define SAA7196_VLOW 0x2c /* Colour-keying lower V limit */
-#define SAA7196_VHIGH 0x2d /* Colour-keying upper V limit */
-#define SAA7196_ULOW 0x2e /* Colour-keying lower U limit */
-#define SAA7196_UHIGH 0x2f /* Colour-keying upper U limit */
-#define SAA7196_DPATH 0x30 /* Data path setting */
-
-/* Initialization default values: */
-
-unsigned char saa_regs[NUM_SUPPORTED_NORM][SAA7196_NUMREGS] = {
-
-/* PAL, 768x576 (no scaling), composite video-in */
-/* Decoder: */
- { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x63, 0xff,
- 0xfe, 0xf0, 0xfe, 0xe0, 0x20, 0x06, 0x3b, 0x98,
- 0x00, 0x59, 0x41, 0x45, 0x34, 0x0a, 0xf4, 0xd2,
- 0xe9, 0xa2,
-/* Padding */
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-/* Scaler: */
- 0x72, 0x80, 0x00, 0x03, 0x8d, 0x20, 0x20, 0x12,
- 0xa5, 0x12, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
- 0x87 },
-
-/* NTSC, 640x480? (no scaling), composite video-in */
-/* Decoder: */
- { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x50, 0x00,
- 0xf8, 0xf0, 0xfe, 0xe0, 0x00, 0x06, 0x3b, 0x98,
- 0x00, 0x2c, 0x3d, 0x40, 0x34, 0x0a, 0xf4, 0xd2,
- 0xe9, 0x98,
-/* Padding */
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-/* Scaler: */
- 0x72, 0x80, 0x80, 0x03, 0x89, 0xf0, 0xf0, 0x0d,
- 0xa0, 0x0d, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
- 0x87 },
-
-/* SECAM, 768x576 (no scaling), composite video-in */
-/* Decoder: */
- { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x63, 0xff,
- 0xfe, 0xf0, 0xfe, 0xe0, 0x20, 0x07, 0x3b, 0x98,
- 0x00, 0x59, 0x41, 0x45, 0x34, 0x0a, 0xf4, 0xd2,
- 0xe9, 0xa2,
-/* Padding */
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-/* Scaler: */
- 0x72, 0x80, 0x00, 0x03, 0x8d, 0x20, 0x20, 0x12,
- 0xa5, 0x12, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
- 0x87 }
- };
-
-#endif /* _SAA7196_H_ */
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c
index 1cd629380f7..f481277892d 100644
--- a/drivers/media/video/se401.c
+++ b/drivers/media/video/se401.c
@@ -1230,9 +1230,7 @@ static const struct file_operations se401_fops = {
.llseek = no_llseek,
};
static struct video_device se401_template = {
- .owner = THIS_MODULE,
.name = "se401 USB camera",
- .type = VID_TYPE_CAPTURE,
.fops = &se401_fops,
};
diff --git a/drivers/media/video/se401.h b/drivers/media/video/se401.h
index 835ef872e80..2ce685db5d8 100644
--- a/drivers/media/video/se401.h
+++ b/drivers/media/video/se401.h
@@ -5,6 +5,7 @@
#include <asm/uaccess.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/mutex.h>
#define se401_DEBUG /* Turn on debug messages */
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 012005e1a77..f7ca3cb9340 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -91,6 +91,7 @@ struct sh_mobile_ceu_dev {
void __iomem *base;
unsigned long video_limit;
+ /* lock used to protect videobuf */
spinlock_t lock;
struct list_head capture;
struct videobuf_buffer *active;
diff --git a/drivers/media/video/sn9c102/sn9c102.h b/drivers/media/video/sn9c102/sn9c102.h
index 0c8d87d8d18..cbfc44433b9 100644
--- a/drivers/media/video/sn9c102/sn9c102.h
+++ b/drivers/media/video/sn9c102/sn9c102.h
@@ -25,6 +25,7 @@
#include <linux/usb.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/device.h>
#include <linux/list.h>
#include <linux/spinlock.h>
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 7f9c7bcf3c8..23408764d0e 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -1038,8 +1038,7 @@ static ssize_t sn9c102_show_reg(struct device* cd,
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
return -ERESTARTSYS;
- cam = video_get_drvdata(container_of(cd, struct video_device,
- class_dev));
+ cam = video_get_drvdata(container_of(cd, struct video_device, dev));
if (!cam) {
mutex_unlock(&sn9c102_sysfs_lock);
return -ENODEV;
@@ -1064,8 +1063,7 @@ sn9c102_store_reg(struct device* cd, struct device_attribute *attr,
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
return -ERESTARTSYS;
- cam = video_get_drvdata(container_of(cd, struct video_device,
- class_dev));
+ cam = video_get_drvdata(container_of(cd, struct video_device, dev));
if (!cam) {
mutex_unlock(&sn9c102_sysfs_lock);
return -ENODEV;
@@ -1098,8 +1096,7 @@ static ssize_t sn9c102_show_val(struct device* cd,
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
return -ERESTARTSYS;
- cam = video_get_drvdata(container_of(cd, struct video_device,
- class_dev));
+ cam = video_get_drvdata(container_of(cd, struct video_device, dev));
if (!cam) {
mutex_unlock(&sn9c102_sysfs_lock);
return -ENODEV;
@@ -1132,8 +1129,7 @@ sn9c102_store_val(struct device* cd, struct device_attribute *attr,
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
return -ERESTARTSYS;
- cam = video_get_drvdata(container_of(cd, struct video_device,
- class_dev));
+ cam = video_get_drvdata(container_of(cd, struct video_device, dev));
if (!cam) {
mutex_unlock(&sn9c102_sysfs_lock);
return -ENODEV;
@@ -1170,8 +1166,7 @@ static ssize_t sn9c102_show_i2c_reg(struct device* cd,
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
return -ERESTARTSYS;
- cam = video_get_drvdata(container_of(cd, struct video_device,
- class_dev));
+ cam = video_get_drvdata(container_of(cd, struct video_device, dev));
if (!cam) {
mutex_unlock(&sn9c102_sysfs_lock);
return -ENODEV;
@@ -1198,8 +1193,7 @@ sn9c102_store_i2c_reg(struct device* cd, struct device_attribute *attr,
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
return -ERESTARTSYS;
- cam = video_get_drvdata(container_of(cd, struct video_device,
- class_dev));
+ cam = video_get_drvdata(container_of(cd, struct video_device, dev));
if (!cam) {
mutex_unlock(&sn9c102_sysfs_lock);
return -ENODEV;
@@ -1232,8 +1226,7 @@ static ssize_t sn9c102_show_i2c_val(struct device* cd,
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
return -ERESTARTSYS;
- cam = video_get_drvdata(container_of(cd, struct video_device,
- class_dev));
+ cam = video_get_drvdata(container_of(cd, struct video_device, dev));
if (!cam) {
mutex_unlock(&sn9c102_sysfs_lock);
return -ENODEV;
@@ -1271,8 +1264,7 @@ sn9c102_store_i2c_val(struct device* cd, struct device_attribute *attr,
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
return -ERESTARTSYS;
- cam = video_get_drvdata(container_of(cd, struct video_device,
- class_dev));
+ cam = video_get_drvdata(container_of(cd, struct video_device, dev));
if (!cam) {
mutex_unlock(&sn9c102_sysfs_lock);
return -ENODEV;
@@ -1318,8 +1310,7 @@ sn9c102_store_green(struct device* cd, struct device_attribute *attr,
if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
return -ERESTARTSYS;
- cam = video_get_drvdata(container_of(cd, struct video_device,
- class_dev));
+ cam = video_get_drvdata(container_of(cd, struct video_device, dev));
if (!cam) {
mutex_unlock(&sn9c102_sysfs_lock);
return -ENODEV;
@@ -1400,8 +1391,7 @@ static ssize_t sn9c102_show_frame_header(struct device* cd,
struct sn9c102_device* cam;
ssize_t count;
- cam = video_get_drvdata(container_of(cd, struct video_device,
- class_dev));
+ cam = video_get_drvdata(container_of(cd, struct video_device, dev));
if (!cam)
return -ENODEV;
@@ -1428,49 +1418,49 @@ static DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL);
static int sn9c102_create_sysfs(struct sn9c102_device* cam)
{
- struct device *classdev = &(cam->v4ldev->class_dev);
+ struct device *dev = &(cam->v4ldev->dev);
int err = 0;
- if ((err = device_create_file(classdev, &dev_attr_reg)))
+ if ((err = device_create_file(dev, &dev_attr_reg)))
goto err_out;
- if ((err = device_create_file(classdev, &dev_attr_val)))
+ if ((err = device_create_file(dev, &dev_attr_val)))
goto err_reg;
- if ((err = device_create_file(classdev, &dev_attr_frame_header)))
+ if ((err = device_create_file(dev, &dev_attr_frame_header)))
goto err_val;
if (cam->sensor.sysfs_ops) {
- if ((err = device_create_file(classdev, &dev_attr_i2c_reg)))
+ if ((err = device_create_file(dev, &dev_attr_i2c_reg)))
goto err_frame_header;
- if ((err = device_create_file(classdev, &dev_attr_i2c_val)))
+ if ((err = device_create_file(dev, &dev_attr_i2c_val)))
goto err_i2c_reg;
}
if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
- if ((err = device_create_file(classdev, &dev_attr_green)))
+ if ((err = device_create_file(dev, &dev_attr_green)))
goto err_i2c_val;
} else {
- if ((err = device_create_file(classdev, &dev_attr_blue)))
+ if ((err = device_create_file(dev, &dev_attr_blue)))
goto err_i2c_val;
- if ((err = device_create_file(classdev, &dev_attr_red)))
+ if ((err = device_create_file(dev, &dev_attr_red)))
goto err_blue;
}
return 0;
err_blue:
- device_remove_file(classdev, &dev_attr_blue);
+ device_remove_file(dev, &dev_attr_blue);
err_i2c_val:
if (cam->sensor.sysfs_ops)
- device_remove_file(classdev, &dev_attr_i2c_val);
+ device_remove_file(dev, &dev_attr_i2c_val);
err_i2c_reg:
if (cam->sensor.sysfs_ops)
- device_remove_file(classdev, &dev_attr_i2c_reg);
+ device_remove_file(dev, &dev_attr_i2c_reg);
err_frame_header:
- device_remove_file(classdev, &dev_attr_frame_header);
+ device_remove_file(dev, &dev_attr_frame_header);
err_val:
- device_remove_file(classdev, &dev_attr_val);
+ device_remove_file(dev, &dev_attr_val);
err_reg:
- device_remove_file(classdev, &dev_attr_reg);
+ device_remove_file(dev, &dev_attr_reg);
err_out:
return err;
}
@@ -3319,8 +3309,6 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
}
strcpy(cam->v4ldev->name, "SN9C1xx PC Camera");
- cam->v4ldev->owner = THIS_MODULE;
- cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
cam->v4ldev->fops = &sn9c102_fops;
cam->v4ldev->minor = video_nr[dev_nr];
cam->v4ldev->release = video_device_release;
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index e39b98f1eca..b6be5ee678b 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -25,6 +25,7 @@
#include <linux/vmalloc.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/v4l2-dev.h>
#include <media/videobuf-core.h>
#include <media/soc_camera.h>
@@ -193,7 +194,7 @@ static int soc_camera_open(struct inode *inode, struct file *file)
mutex_lock(&video_lock);
vdev = video_devdata(file);
- icd = container_of(vdev->dev, struct soc_camera_device, dev);
+ icd = container_of(vdev->parent, struct soc_camera_device, dev);
ici = to_soc_camera_host(icd->dev.parent);
if (!try_module_get(icd->ops->owner)) {
@@ -258,7 +259,7 @@ static int soc_camera_close(struct inode *inode, struct file *file)
vfree(icf);
- dev_dbg(vdev->dev, "camera device close\n");
+ dev_dbg(vdev->parent, "camera device close\n");
return 0;
}
@@ -271,7 +272,7 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf,
struct video_device *vdev = icd->vdev;
int err = -EINVAL;
- dev_err(vdev->dev, "camera device read not implemented\n");
+ dev_err(vdev->parent, "camera device read not implemented\n");
return err;
}
@@ -861,6 +862,35 @@ void soc_camera_device_unregister(struct soc_camera_device *icd)
}
EXPORT_SYMBOL(soc_camera_device_unregister);
+static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
+ .vidioc_querycap = soc_camera_querycap,
+ .vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap,
+ .vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap,
+ .vidioc_enum_input = soc_camera_enum_input,
+ .vidioc_g_input = soc_camera_g_input,
+ .vidioc_s_input = soc_camera_s_input,
+ .vidioc_s_std = soc_camera_s_std,
+ .vidioc_reqbufs = soc_camera_reqbufs,
+ .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap,
+ .vidioc_querybuf = soc_camera_querybuf,
+ .vidioc_qbuf = soc_camera_qbuf,
+ .vidioc_dqbuf = soc_camera_dqbuf,
+ .vidioc_streamon = soc_camera_streamon,
+ .vidioc_streamoff = soc_camera_streamoff,
+ .vidioc_queryctrl = soc_camera_queryctrl,
+ .vidioc_g_ctrl = soc_camera_g_ctrl,
+ .vidioc_s_ctrl = soc_camera_s_ctrl,
+ .vidioc_cropcap = soc_camera_cropcap,
+ .vidioc_g_crop = soc_camera_g_crop,
+ .vidioc_s_crop = soc_camera_s_crop,
+ .vidioc_g_chip_ident = soc_camera_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_register = soc_camera_g_register,
+ .vidioc_s_register = soc_camera_s_register,
+#endif
+};
+
int soc_camera_video_start(struct soc_camera_device *icd)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
@@ -877,45 +907,19 @@ int soc_camera_video_start(struct soc_camera_device *icd)
strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
/* Maybe better &ici->dev */
- vdev->dev = &icd->dev;
- vdev->type = VID_TYPE_CAPTURE;
+ vdev->parent = &icd->dev;
vdev->current_norm = V4L2_STD_UNKNOWN;
vdev->fops = &soc_camera_fops;
+ vdev->ioctl_ops = &soc_camera_ioctl_ops;
vdev->release = video_device_release;
vdev->minor = -1;
vdev->tvnorms = V4L2_STD_UNKNOWN,
- vdev->vidioc_querycap = soc_camera_querycap;
- vdev->vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap;
- vdev->vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap;
- vdev->vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap;
- vdev->vidioc_enum_input = soc_camera_enum_input;
- vdev->vidioc_g_input = soc_camera_g_input;
- vdev->vidioc_s_input = soc_camera_s_input;
- vdev->vidioc_s_std = soc_camera_s_std;
- vdev->vidioc_reqbufs = soc_camera_reqbufs;
- vdev->vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap;
- vdev->vidioc_querybuf = soc_camera_querybuf;
- vdev->vidioc_qbuf = soc_camera_qbuf;
- vdev->vidioc_dqbuf = soc_camera_dqbuf;
- vdev->vidioc_streamon = soc_camera_streamon;
- vdev->vidioc_streamoff = soc_camera_streamoff;
- vdev->vidioc_queryctrl = soc_camera_queryctrl;
- vdev->vidioc_g_ctrl = soc_camera_g_ctrl;
- vdev->vidioc_s_ctrl = soc_camera_s_ctrl;
- vdev->vidioc_cropcap = soc_camera_cropcap;
- vdev->vidioc_g_crop = soc_camera_g_crop;
- vdev->vidioc_s_crop = soc_camera_s_crop;
- vdev->vidioc_g_chip_ident = soc_camera_g_chip_ident;
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- vdev->vidioc_g_register = soc_camera_g_register;
- vdev->vidioc_s_register = soc_camera_s_register;
-#endif
icd->current_fmt = &icd->formats[0];
err = video_register_device(vdev, VFL_TYPE_GRABBER, vdev->minor);
if (err < 0) {
- dev_err(vdev->dev, "video_register_device failed\n");
+ dev_err(vdev->parent, "video_register_device failed\n");
goto evidregd;
}
icd->vdev = vdev;
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index f308c38d744..ad36af30e09 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -34,6 +34,7 @@
#include <linux/vmalloc.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include "stk-webcam.h"
@@ -340,17 +341,19 @@ static int stk_create_sysfs_files(struct video_device *vdev)
{
int ret;
- ret = video_device_create_file(vdev, &dev_attr_brightness);
- ret += video_device_create_file(vdev, &dev_attr_hflip);
- ret += video_device_create_file(vdev, &dev_attr_vflip);
+ ret = device_create_file(&vdev->dev, &dev_attr_brightness);
+ ret += device_create_file(&vdev->dev, &dev_attr_hflip);
+ ret += device_create_file(&vdev->dev, &dev_attr_vflip);
+ if (ret)
+ STK_WARNING("Could not create sysfs files\n");
return ret;
}
static void stk_remove_sysfs_files(struct video_device *vdev)
{
- video_device_remove_file(vdev, &dev_attr_brightness);
- video_device_remove_file(vdev, &dev_attr_hflip);
- video_device_remove_file(vdev, &dev_attr_vflip);
+ device_remove_file(&vdev->dev, &dev_attr_brightness);
+ device_remove_file(&vdev->dev, &dev_attr_hflip);
+ device_remove_file(&vdev->dev, &dev_attr_vflip);
}
#else
@@ -442,18 +445,19 @@ static void stk_isoc_handler(struct urb *urb)
fb->v4lbuf.bytesused = 0;
fill = fb->buffer;
} else if (fb->v4lbuf.bytesused == dev->frame_size) {
- list_move_tail(dev->sio_avail.next,
- &dev->sio_full);
- wake_up(&dev->wait_frame);
- if (list_empty(&dev->sio_avail)) {
- (void) (printk_ratelimit() &&
- STK_ERROR("No buffer available\n"));
- goto resubmit;
+ if (list_is_singular(&dev->sio_avail)) {
+ /* Always reuse the last buffer */
+ fb->v4lbuf.bytesused = 0;
+ fill = fb->buffer;
+ } else {
+ list_move_tail(dev->sio_avail.next,
+ &dev->sio_full);
+ wake_up(&dev->wait_frame);
+ fb = list_first_entry(&dev->sio_avail,
+ struct stk_sio_buffer, list);
+ fb->v4lbuf.bytesused = 0;
+ fill = fb->buffer;
}
- fb = list_first_entry(&dev->sio_avail,
- struct stk_sio_buffer, list);
- fb->v4lbuf.bytesused = 0;
- fill = fb->buffer;
}
} else {
framelen -= 4;
@@ -1327,20 +1331,7 @@ static struct file_operations v4l_stk_fops = {
.llseek = no_llseek
};
-static void stk_v4l_dev_release(struct video_device *vd)
-{
-}
-
-static struct video_device stk_v4l_data = {
- .name = "stkwebcam",
- .type = VFL_TYPE_GRABBER,
- .type2 = VID_TYPE_CAPTURE,
- .minor = -1,
- .tvnorms = V4L2_STD_UNKNOWN,
- .current_norm = V4L2_STD_UNKNOWN,
- .fops = &v4l_stk_fops,
- .release = stk_v4l_dev_release,
-
+static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = {
.vidioc_querycap = stk_vidioc_querycap,
.vidioc_enum_fmt_vid_cap = stk_vidioc_enum_fmt_vid_cap,
.vidioc_try_fmt_vid_cap = stk_vidioc_try_fmt_vid_cap,
@@ -1362,6 +1353,20 @@ static struct video_device stk_v4l_data = {
.vidioc_g_parm = stk_vidioc_g_parm,
};
+static void stk_v4l_dev_release(struct video_device *vd)
+{
+}
+
+static struct video_device stk_v4l_data = {
+ .name = "stkwebcam",
+ .minor = -1,
+ .tvnorms = V4L2_STD_UNKNOWN,
+ .current_norm = V4L2_STD_UNKNOWN,
+ .fops = &v4l_stk_fops,
+ .ioctl_ops = &v4l_stk_ioctl_ops,
+ .release = stk_v4l_dev_release,
+};
+
static int stk_register_video_device(struct stk_camera *dev)
{
@@ -1369,7 +1374,7 @@ static int stk_register_video_device(struct stk_camera *dev)
dev->vdev = stk_v4l_data;
dev->vdev.debug = debug;
- dev->vdev.dev = &dev->interface->dev;
+ dev->vdev.parent = &dev->interface->dev;
dev->vdev.priv = dev;
err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1);
if (err)
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
index c109511f21e..276bded06ab 100644
--- a/drivers/media/video/stradis.c
+++ b/drivers/media/video/stradis.c
@@ -43,6 +43,7 @@
#include <linux/vmalloc.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include "saa7146.h"
#include "saa7146reg.h"
@@ -1918,7 +1919,6 @@ static const struct file_operations saa_fops = {
/* template for video_device-structure */
static struct video_device saa_template = {
.name = "SAA7146A",
- .type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY,
.fops = &saa_fops,
.minor = -1,
};
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c
index d7f130bedb5..56dc3d6b5b2 100644
--- a/drivers/media/video/stv680.c
+++ b/drivers/media/video/stv680.c
@@ -66,6 +66,7 @@
#include <linux/errno.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/usb.h>
#include <linux/mutex.h>
@@ -524,53 +525,54 @@ static int stv680_create_sysfs_files(struct video_device *vdev)
{
int rc;
- rc = video_device_create_file(vdev, &dev_attr_model);
+ rc = device_create_file(&vdev->dev, &dev_attr_model);
if (rc) goto err;
- rc = video_device_create_file(vdev, &dev_attr_in_use);
+ rc = device_create_file(&vdev->dev, &dev_attr_in_use);
if (rc) goto err_model;
- rc = video_device_create_file(vdev, &dev_attr_streaming);
+ rc = device_create_file(&vdev->dev, &dev_attr_streaming);
if (rc) goto err_inuse;
- rc = video_device_create_file(vdev, &dev_attr_palette);
+ rc = device_create_file(&vdev->dev, &dev_attr_palette);
if (rc) goto err_stream;
- rc = video_device_create_file(vdev, &dev_attr_frames_total);
+ rc = device_create_file(&vdev->dev, &dev_attr_frames_total);
if (rc) goto err_pal;
- rc = video_device_create_file(vdev, &dev_attr_frames_read);
+ rc = device_create_file(&vdev->dev, &dev_attr_frames_read);
if (rc) goto err_framtot;
- rc = video_device_create_file(vdev, &dev_attr_packets_dropped);
+ rc = device_create_file(&vdev->dev, &dev_attr_packets_dropped);
if (rc) goto err_framread;
- rc = video_device_create_file(vdev, &dev_attr_decoding_errors);
+ rc = device_create_file(&vdev->dev, &dev_attr_decoding_errors);
if (rc) goto err_dropped;
return 0;
err_dropped:
- video_device_remove_file(vdev, &dev_attr_packets_dropped);
+ device_remove_file(&vdev->dev, &dev_attr_packets_dropped);
err_framread:
- video_device_remove_file(vdev, &dev_attr_frames_read);
+ device_remove_file(&vdev->dev, &dev_attr_frames_read);
err_framtot:
- video_device_remove_file(vdev, &dev_attr_frames_total);
+ device_remove_file(&vdev->dev, &dev_attr_frames_total);
err_pal:
- video_device_remove_file(vdev, &dev_attr_palette);
+ device_remove_file(&vdev->dev, &dev_attr_palette);
err_stream:
- video_device_remove_file(vdev, &dev_attr_streaming);
+ device_remove_file(&vdev->dev, &dev_attr_streaming);
err_inuse:
- video_device_remove_file(vdev, &dev_attr_in_use);
+ device_remove_file(&vdev->dev, &dev_attr_in_use);
err_model:
- video_device_remove_file(vdev, &dev_attr_model);
+ device_remove_file(&vdev->dev, &dev_attr_model);
err:
+ PDEBUG(0, "STV(e): Could not create sysfs files");
return rc;
}
static void stv680_remove_sysfs_files(struct video_device *vdev)
{
- video_device_remove_file(vdev, &dev_attr_model);
- video_device_remove_file(vdev, &dev_attr_in_use);
- video_device_remove_file(vdev, &dev_attr_streaming);
- video_device_remove_file(vdev, &dev_attr_palette);
- video_device_remove_file(vdev, &dev_attr_frames_total);
- video_device_remove_file(vdev, &dev_attr_frames_read);
- video_device_remove_file(vdev, &dev_attr_packets_dropped);
- video_device_remove_file(vdev, &dev_attr_decoding_errors);
+ device_remove_file(&vdev->dev, &dev_attr_model);
+ device_remove_file(&vdev->dev, &dev_attr_in_use);
+ device_remove_file(&vdev->dev, &dev_attr_streaming);
+ device_remove_file(&vdev->dev, &dev_attr_palette);
+ device_remove_file(&vdev->dev, &dev_attr_frames_total);
+ device_remove_file(&vdev->dev, &dev_attr_frames_read);
+ device_remove_file(&vdev->dev, &dev_attr_packets_dropped);
+ device_remove_file(&vdev->dev, &dev_attr_decoding_errors);
}
/********************************************************************
@@ -1400,9 +1402,7 @@ static const struct file_operations stv680_fops = {
.llseek = no_llseek,
};
static struct video_device stv680_template = {
- .owner = THIS_MODULE,
.name = "STV0680 USB camera",
- .type = VID_TYPE_CAPTURE,
.fops = &stv680_fops,
.release = video_device_release,
.minor = -1,
@@ -1454,7 +1454,7 @@ static int stv680_probe (struct usb_interface *intf, const struct usb_device_id
goto error;
}
memcpy(stv680->vdev, &stv680_template, sizeof(stv680_template));
- stv680->vdev->dev = &intf->dev;
+ stv680->vdev->parent = &intf->dev;
video_set_drvdata(stv680->vdev, stv680);
memcpy (stv680->vdev->name, stv680->camera_name, strlen (stv680->camera_name));
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index ae75c187da7..4963d426488 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -44,10 +44,11 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/slab.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/i2c-addr.h>
#ifndef VIDEO_AUDIO_BALANCE
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 7a8ce8fb46d..792f0b07990 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -25,7 +25,7 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/slab.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <linux/i2c.h>
#include <linux/init.h>
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
index 9220378a563..281065b9dd2 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -29,7 +29,7 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/v4l2-i2c-drv-legacy.h>
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 93d879dc510..d806a3556ee 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -19,6 +19,7 @@
#include <media/tuner.h>
#include <media/tuner-types.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/v4l2-i2c-drv-legacy.h>
#include "mt20xx.h"
#include "tda8290.h"
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 9da0e1807ff..bcc32fa92a8 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -34,13 +34,13 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/tuner.h>
#include <media/tveeprom.h>
#include <media/v4l2-common.h>
-#include <media/audiochip.h>
+#include <media/v4l2-chip-ident.h>
MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
MODULE_AUTHOR("John Klar");
@@ -261,70 +261,72 @@ hauppauge_tuner[] =
{ TUNER_ABSENT, "MaxLinear MXL5005_v2"},
{ TUNER_PHILIPS_TDA8290, "Philips 18271_8295"},
/* 150-159 */
- { TUNER_ABSENT, "Xceive XC5000"},
+ { TUNER_ABSENT, "Xceive XC5000"},
};
+/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
+ * internal to a video chip, i.e. not a separate audio chip. */
static struct HAUPPAUGE_AUDIOIC
{
- enum audiochip id;
+ u32 id;
char *name;
}
audioIC[] =
{
/* 0-4 */
- {AUDIO_CHIP_NONE, "None"},
- {AUDIO_CHIP_TEA6300, "TEA6300"},
- {AUDIO_CHIP_TEA6300, "TEA6320"},
- {AUDIO_CHIP_TDA985X, "TDA9850"},
- {AUDIO_CHIP_MSP34XX, "MSP3400C"},
+ { V4L2_IDENT_NONE, "None" },
+ { V4L2_IDENT_UNKNOWN, "TEA6300" },
+ { V4L2_IDENT_UNKNOWN, "TEA6320" },
+ { V4L2_IDENT_UNKNOWN, "TDA9850" },
+ { V4L2_IDENT_MSPX4XX, "MSP3400C" },
/* 5-9 */
- {AUDIO_CHIP_MSP34XX, "MSP3410D"},
- {AUDIO_CHIP_MSP34XX, "MSP3415"},
- {AUDIO_CHIP_MSP34XX, "MSP3430"},
- {AUDIO_CHIP_MSP34XX, "MSP3438"},
- {AUDIO_CHIP_UNKNOWN, "CS5331"},
+ { V4L2_IDENT_MSPX4XX, "MSP3410D" },
+ { V4L2_IDENT_MSPX4XX, "MSP3415" },
+ { V4L2_IDENT_MSPX4XX, "MSP3430" },
+ { V4L2_IDENT_MSPX4XX, "MSP3438" },
+ { V4L2_IDENT_UNKNOWN, "CS5331" },
/* 10-14 */
- {AUDIO_CHIP_MSP34XX, "MSP3435"},
- {AUDIO_CHIP_MSP34XX, "MSP3440"},
- {AUDIO_CHIP_MSP34XX, "MSP3445"},
- {AUDIO_CHIP_MSP34XX, "MSP3411"},
- {AUDIO_CHIP_MSP34XX, "MSP3416"},
+ { V4L2_IDENT_MSPX4XX, "MSP3435" },
+ { V4L2_IDENT_MSPX4XX, "MSP3440" },
+ { V4L2_IDENT_MSPX4XX, "MSP3445" },
+ { V4L2_IDENT_MSPX4XX, "MSP3411" },
+ { V4L2_IDENT_MSPX4XX, "MSP3416" },
/* 15-19 */
- {AUDIO_CHIP_MSP34XX, "MSP3425"},
- {AUDIO_CHIP_MSP34XX, "MSP3451"},
- {AUDIO_CHIP_MSP34XX, "MSP3418"},
- {AUDIO_CHIP_UNKNOWN, "Type 0x12"},
- {AUDIO_CHIP_UNKNOWN, "OKI7716"},
+ { V4L2_IDENT_MSPX4XX, "MSP3425" },
+ { V4L2_IDENT_MSPX4XX, "MSP3451" },
+ { V4L2_IDENT_MSPX4XX, "MSP3418" },
+ { V4L2_IDENT_UNKNOWN, "Type 0x12" },
+ { V4L2_IDENT_UNKNOWN, "OKI7716" },
/* 20-24 */
- {AUDIO_CHIP_MSP34XX, "MSP4410"},
- {AUDIO_CHIP_MSP34XX, "MSP4420"},
- {AUDIO_CHIP_MSP34XX, "MSP4440"},
- {AUDIO_CHIP_MSP34XX, "MSP4450"},
- {AUDIO_CHIP_MSP34XX, "MSP4408"},
+ { V4L2_IDENT_MSPX4XX, "MSP4410" },
+ { V4L2_IDENT_MSPX4XX, "MSP4420" },
+ { V4L2_IDENT_MSPX4XX, "MSP4440" },
+ { V4L2_IDENT_MSPX4XX, "MSP4450" },
+ { V4L2_IDENT_MSPX4XX, "MSP4408" },
/* 25-29 */
- {AUDIO_CHIP_MSP34XX, "MSP4418"},
- {AUDIO_CHIP_MSP34XX, "MSP4428"},
- {AUDIO_CHIP_MSP34XX, "MSP4448"},
- {AUDIO_CHIP_MSP34XX, "MSP4458"},
- {AUDIO_CHIP_MSP34XX, "Type 0x1d"},
+ { V4L2_IDENT_MSPX4XX, "MSP4418" },
+ { V4L2_IDENT_MSPX4XX, "MSP4428" },
+ { V4L2_IDENT_MSPX4XX, "MSP4448" },
+ { V4L2_IDENT_MSPX4XX, "MSP4458" },
+ { V4L2_IDENT_MSPX4XX, "Type 0x1d" },
/* 30-34 */
- {AUDIO_CHIP_INTERNAL, "CX880"},
- {AUDIO_CHIP_INTERNAL, "CX881"},
- {AUDIO_CHIP_INTERNAL, "CX883"},
- {AUDIO_CHIP_INTERNAL, "CX882"},
- {AUDIO_CHIP_INTERNAL, "CX25840"},
+ { V4L2_IDENT_AMBIGUOUS, "CX880" },
+ { V4L2_IDENT_AMBIGUOUS, "CX881" },
+ { V4L2_IDENT_AMBIGUOUS, "CX883" },
+ { V4L2_IDENT_AMBIGUOUS, "CX882" },
+ { V4L2_IDENT_AMBIGUOUS, "CX25840" },
/* 35-39 */
- {AUDIO_CHIP_INTERNAL, "CX25841"},
- {AUDIO_CHIP_INTERNAL, "CX25842"},
- {AUDIO_CHIP_INTERNAL, "CX25843"},
- {AUDIO_CHIP_INTERNAL, "CX23418"},
- {AUDIO_CHIP_INTERNAL, "CX23885"},
+ { V4L2_IDENT_AMBIGUOUS, "CX25841" },
+ { V4L2_IDENT_AMBIGUOUS, "CX25842" },
+ { V4L2_IDENT_AMBIGUOUS, "CX25843" },
+ { V4L2_IDENT_AMBIGUOUS, "CX23418" },
+ { V4L2_IDENT_AMBIGUOUS, "CX23885" },
/* 40-44 */
- {AUDIO_CHIP_INTERNAL, "CX23888"},
- {AUDIO_CHIP_INTERNAL, "SAA7131"},
- {AUDIO_CHIP_INTERNAL, "CX23887"},
- {AUDIO_CHIP_INTERNAL, "SAA7164"},
- {AUDIO_CHIP_INTERNAL, "AU8522"},
+ { V4L2_IDENT_AMBIGUOUS, "CX23888" },
+ { V4L2_IDENT_AMBIGUOUS, "SAA7131" },
+ { V4L2_IDENT_AMBIGUOUS, "CX23887" },
+ { V4L2_IDENT_AMBIGUOUS, "SAA7164" },
+ { V4L2_IDENT_AMBIGUOUS, "AU8522" },
};
/* This list is supplied by Hauppauge. Thanks! */
@@ -483,7 +485,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
tvee->has_radio = eeprom_data[i+len-1];
/* old style tag, don't know how to detect
IR presence, mark as unknown. */
- tvee->has_ir = -1;
+ tvee->has_ir = 0;
tvee->model =
eeprom_data[i+8] +
(eeprom_data[i+9] << 8);
@@ -509,7 +511,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
if (audioic < ARRAY_SIZE(audioIC))
tvee->audio_processor = audioIC[audioic].id;
else
- tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
+ tvee->audio_processor = V4L2_IDENT_UNKNOWN;
break;
/* case 0x03: tag 'EEInfo' */
@@ -542,7 +544,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
if (audioic < ARRAY_SIZE(audioIC))
tvee->audio_processor = audioIC[audioic].id;
else
- tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
+ tvee->audio_processor = V4L2_IDENT_UNKNOWN;
break;
@@ -603,7 +605,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
case 0x0f:
/* tag 'IRInfo' */
- tvee->has_ir = eeprom_data[i+1];
+ tvee->has_ir = 1 | (eeprom_data[i+1] << 1);
break;
/* case 0x10: tag 'VBIInfo' */
@@ -690,7 +692,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
t_fmt_name2[6], t_fmt_name2[7], t_format2);
if (audioic < 0) {
tveeprom_info("audio processor is unknown (no idx)\n");
- tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
+ tvee->audio_processor = V4L2_IDENT_UNKNOWN;
} else {
if (audioic < ARRAY_SIZE(audioIC))
tveeprom_info("audio processor is %s (idx %d)\n",
@@ -703,14 +705,14 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
tveeprom_info("decoder processor is %s (idx %d)\n",
STRM(decoderIC, tvee->decoder_processor),
tvee->decoder_processor);
- if (tvee->has_ir == -1)
- tveeprom_info("has %sradio\n",
- tvee->has_radio ? "" : "no ");
- else
+ if (tvee->has_ir)
tveeprom_info("has %sradio, has %sIR receiver, has %sIR transmitter\n",
tvee->has_radio ? "" : "no ",
- (tvee->has_ir & 1) ? "" : "no ",
- (tvee->has_ir & 2) ? "" : "no ");
+ (tvee->has_ir & 2) ? "" : "no ",
+ (tvee->has_ir & 4) ? "" : "no ");
+ else
+ tveeprom_info("has %sradio\n",
+ tvee->has_radio ? "" : "no ");
}
EXPORT_SYMBOL(tveeprom_hauppauge_analog);
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 6a3af1005f0..28af5ce5560 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -6,7 +6,7 @@
*/
#include <linux/i2c.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/delay.h>
#include <linux/video_decoder.h>
#include <media/v4l2-common.h>
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c
index 4128ee20b64..bf1bc2f69b0 100644
--- a/drivers/media/video/usbvideo/usbvideo.c
+++ b/drivers/media/video/usbvideo/usbvideo.c
@@ -952,8 +952,6 @@ static const struct file_operations usbvideo_fops = {
.llseek = no_llseek,
};
static const struct video_device usbvideo_template = {
- .owner = THIS_MODULE,
- .type = VID_TYPE_CAPTURE,
.fops = &usbvideo_fops,
};
@@ -1040,7 +1038,7 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd)
err("%s: uvd->dev == NULL", __func__);
return -EINVAL;
}
- uvd->vdev.dev = &uvd->dev->dev;
+ uvd->vdev.parent = &uvd->dev->dev;
if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
err("%s: video_register_device failed", __func__);
return -EPIPE;
diff --git a/drivers/media/video/usbvideo/usbvideo.h b/drivers/media/video/usbvideo/usbvideo.h
index 051775d4c72..c66985beb8c 100644
--- a/drivers/media/video/usbvideo/usbvideo.h
+++ b/drivers/media/video/usbvideo/usbvideo.h
@@ -18,6 +18,7 @@
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/usb.h>
#include <linux/mutex.h>
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c
index 40d053e0d5b..b7792451a29 100644
--- a/drivers/media/video/usbvideo/vicam.c
+++ b/drivers/media/video/usbvideo/vicam.c
@@ -41,6 +41,7 @@
#include <linux/videodev.h>
#include <linux/usb.h>
#include <linux/vmalloc.h>
+#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/firmware.h>
@@ -791,9 +792,7 @@ static const struct file_operations vicam_fops = {
};
static struct video_device vicam_template = {
- .owner = THIS_MODULE,
.name = "ViCam-based USB Camera",
- .type = VID_TYPE_CAPTURE,
.fops = &vicam_fops,
.minor = -1,
};
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index abf685464b7..c317ed7a848 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -30,7 +30,6 @@
#include <linux/mm.h>
#include <linux/utsname.h>
#include <linux/highmem.h>
-#include <linux/videodev.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -43,7 +42,6 @@
#include <media/saa7115.h>
#include <media/v4l2-common.h>
#include <media/tuner.h>
-#include <media/audiochip.h>
#include <linux/workqueue.h>
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index cd6c41d6789..b977116a0dd 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -53,7 +53,6 @@
#include <linux/mm.h>
#include <linux/utsname.h>
#include <linux/highmem.h>
-#include <linux/videodev.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -65,8 +64,8 @@
#include <media/saa7115.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <media/tuner.h>
-#include <media/audiochip.h>
#include <linux/workqueue.h>
@@ -184,7 +183,7 @@ MODULE_ALIAS(DRIVER_ALIAS);
static inline struct usb_usbvision *cd_to_usbvision(struct device *cd)
{
struct video_device *vdev =
- container_of(cd, struct video_device, class_dev);
+ container_of(cd, struct video_device, dev);
return video_get_drvdata(vdev);
}
@@ -199,7 +198,7 @@ static ssize_t show_model(struct device *cd,
struct device_attribute *attr, char *buf)
{
struct video_device *vdev =
- container_of(cd, struct video_device, class_dev);
+ container_of(cd, struct video_device, dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
return sprintf(buf, "%s\n",
usbvision_device_data[usbvision->DevModel].ModelString);
@@ -210,7 +209,7 @@ static ssize_t show_hue(struct device *cd,
struct device_attribute *attr, char *buf)
{
struct video_device *vdev =
- container_of(cd, struct video_device, class_dev);
+ container_of(cd, struct video_device, dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_HUE;
@@ -225,7 +224,7 @@ static ssize_t show_contrast(struct device *cd,
struct device_attribute *attr, char *buf)
{
struct video_device *vdev =
- container_of(cd, struct video_device, class_dev);
+ container_of(cd, struct video_device, dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_CONTRAST;
@@ -240,7 +239,7 @@ static ssize_t show_brightness(struct device *cd,
struct device_attribute *attr, char *buf)
{
struct video_device *vdev =
- container_of(cd, struct video_device, class_dev);
+ container_of(cd, struct video_device, dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_BRIGHTNESS;
@@ -255,7 +254,7 @@ static ssize_t show_saturation(struct device *cd,
struct device_attribute *attr, char *buf)
{
struct video_device *vdev =
- container_of(cd, struct video_device, class_dev);
+ container_of(cd, struct video_device, dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_SATURATION;
@@ -270,7 +269,7 @@ static ssize_t show_streaming(struct device *cd,
struct device_attribute *attr, char *buf)
{
struct video_device *vdev =
- container_of(cd, struct video_device, class_dev);
+ container_of(cd, struct video_device, dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
return sprintf(buf, "%s\n",
YES_NO(usbvision->streaming==Stream_On?1:0));
@@ -281,7 +280,7 @@ static ssize_t show_compression(struct device *cd,
struct device_attribute *attr, char *buf)
{
struct video_device *vdev =
- container_of(cd, struct video_device, class_dev);
+ container_of(cd, struct video_device, dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
return sprintf(buf, "%s\n",
YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS));
@@ -292,7 +291,7 @@ static ssize_t show_device_bridge(struct device *cd,
struct device_attribute *attr, char *buf)
{
struct video_device *vdev =
- container_of(cd, struct video_device, class_dev);
+ container_of(cd, struct video_device, dev);
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
return sprintf(buf, "%d\n", usbvision->bridgeType);
}
@@ -304,40 +303,31 @@ static void usbvision_create_sysfs(struct video_device *vdev)
if (!vdev)
return;
do {
- res = device_create_file(&vdev->class_dev,
- &dev_attr_version);
+ res = device_create_file(&vdev->dev, &dev_attr_version);
if (res<0)
break;
- res = device_create_file(&vdev->class_dev,
- &dev_attr_model);
+ res = device_create_file(&vdev->dev, &dev_attr_model);
if (res<0)
break;
- res = device_create_file(&vdev->class_dev,
- &dev_attr_hue);
+ res = device_create_file(&vdev->dev, &dev_attr_hue);
if (res<0)
break;
- res = device_create_file(&vdev->class_dev,
- &dev_attr_contrast);
+ res = device_create_file(&vdev->dev, &dev_attr_contrast);
if (res<0)
break;
- res = device_create_file(&vdev->class_dev,
- &dev_attr_brightness);
+ res = device_create_file(&vdev->dev, &dev_attr_brightness);
if (res<0)
break;
- res = device_create_file(&vdev->class_dev,
- &dev_attr_saturation);
+ res = device_create_file(&vdev->dev, &dev_attr_saturation);
if (res<0)
break;
- res = device_create_file(&vdev->class_dev,
- &dev_attr_streaming);
+ res = device_create_file(&vdev->dev, &dev_attr_streaming);
if (res<0)
break;
- res = device_create_file(&vdev->class_dev,
- &dev_attr_compression);
+ res = device_create_file(&vdev->dev, &dev_attr_compression);
if (res<0)
break;
- res = device_create_file(&vdev->class_dev,
- &dev_attr_bridge);
+ res = device_create_file(&vdev->dev, &dev_attr_bridge);
if (res>=0)
return;
} while (0);
@@ -348,24 +338,15 @@ static void usbvision_create_sysfs(struct video_device *vdev)
static void usbvision_remove_sysfs(struct video_device *vdev)
{
if (vdev) {
- device_remove_file(&vdev->class_dev,
- &dev_attr_version);
- device_remove_file(&vdev->class_dev,
- &dev_attr_model);
- device_remove_file(&vdev->class_dev,
- &dev_attr_hue);
- device_remove_file(&vdev->class_dev,
- &dev_attr_contrast);
- device_remove_file(&vdev->class_dev,
- &dev_attr_brightness);
- device_remove_file(&vdev->class_dev,
- &dev_attr_saturation);
- device_remove_file(&vdev->class_dev,
- &dev_attr_streaming);
- device_remove_file(&vdev->class_dev,
- &dev_attr_compression);
- device_remove_file(&vdev->class_dev,
- &dev_attr_bridge);
+ device_remove_file(&vdev->dev, &dev_attr_version);
+ device_remove_file(&vdev->dev, &dev_attr_model);
+ device_remove_file(&vdev->dev, &dev_attr_hue);
+ device_remove_file(&vdev->dev, &dev_attr_contrast);
+ device_remove_file(&vdev->dev, &dev_attr_brightness);
+ device_remove_file(&vdev->dev, &dev_attr_saturation);
+ device_remove_file(&vdev->dev, &dev_attr_streaming);
+ device_remove_file(&vdev->dev, &dev_attr_compression);
+ device_remove_file(&vdev->dev, &dev_attr_bridge);
}
}
@@ -1388,13 +1369,8 @@ static const struct file_operations usbvision_fops = {
/* .poll = video_poll, */
.compat_ioctl = v4l_compat_ioctl32,
};
-static struct video_device usbvision_video_template = {
- .owner = THIS_MODULE,
- .type = VID_TYPE_TUNER | VID_TYPE_CAPTURE,
- .fops = &usbvision_fops,
- .name = "usbvision-video",
- .release = video_device_release,
- .minor = -1,
+
+static const struct v4l2_ioctl_ops usbvision_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
@@ -1426,6 +1402,14 @@ static struct video_device usbvision_video_template = {
.vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register,
#endif
+};
+
+static struct video_device usbvision_video_template = {
+ .fops = &usbvision_fops,
+ .ioctl_ops = &usbvision_ioctl_ops,
+ .name = "usbvision-video",
+ .release = video_device_release,
+ .minor = -1,
.tvnorms = USBVISION_NORMS,
.current_norm = V4L2_STD_PAL
};
@@ -1441,14 +1425,7 @@ static const struct file_operations usbvision_radio_fops = {
.compat_ioctl = v4l_compat_ioctl32,
};
-static struct video_device usbvision_radio_template=
-{
- .owner = THIS_MODULE,
- .type = VID_TYPE_TUNER,
- .fops = &usbvision_radio_fops,
- .name = "usbvision-radio",
- .release = video_device_release,
- .minor = -1,
+static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input = vidioc_g_input,
@@ -1462,6 +1439,14 @@ static struct video_device usbvision_radio_template=
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
+};
+
+static struct video_device usbvision_radio_template = {
+ .fops = &usbvision_radio_fops,
+ .name = "usbvision-radio",
+ .release = video_device_release,
+ .minor = -1,
+ .ioctl_ops = &usbvision_radio_ioctl_ops,
.tvnorms = USBVISION_NORMS,
.current_norm = V4L2_STD_PAL
@@ -1479,8 +1464,6 @@ static const struct file_operations usbvision_vbi_fops = {
static struct video_device usbvision_vbi_template=
{
- .owner = THIS_MODULE,
- .type = VID_TYPE_TUNER,
.fops = &usbvision_vbi_fops,
.release = video_device_release,
.name = "usbvision-vbi",
@@ -1506,7 +1489,7 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision,
}
*vdev = *vdev_template;
// vdev->minor = -1;
- vdev->dev = &usb_dev->dev;
+ vdev->parent = &usb_dev->dev;
snprintf(vdev->name, sizeof(vdev->name), "%s", name);
video_set_drvdata(vdev, usbvision);
return vdev;
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 3ae95512666..626f4ad7e87 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -195,8 +195,8 @@ static struct uvc_menu_info power_line_frequency_controls[] = {
};
static struct uvc_menu_info exposure_auto_controls[] = {
- { 1, "Manual Mode" },
{ 2, "Auto Mode" },
+ { 1, "Manual Mode" },
{ 4, "Shutter Priority Mode" },
{ 8, "Aperture Priority Mode" },
};
@@ -592,6 +592,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
if (ctrl == NULL)
return -EINVAL;
+ memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
v4l2_ctrl->id = mapping->id;
v4l2_ctrl->type = mapping->v4l2_type;
strncpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
@@ -608,7 +609,8 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
v4l2_ctrl->default_value = uvc_get_le_value(data, mapping);
}
- if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
+ switch (mapping->v4l2_type) {
+ case V4L2_CTRL_TYPE_MENU:
v4l2_ctrl->minimum = 0;
v4l2_ctrl->maximum = mapping->menu_count - 1;
v4l2_ctrl->step = 1;
@@ -622,6 +624,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
}
return 0;
+
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ v4l2_ctrl->minimum = 0;
+ v4l2_ctrl->maximum = 1;
+ v4l2_ctrl->step = 1;
+ return 0;
+
+ default:
+ break;
}
if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index f2b2983fe06..b3c4d75e849 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1458,9 +1458,7 @@ static int uvc_register_video(struct uvc_device *dev)
* unregistered before the reference is released, so we don't need to
* get another one.
*/
- vdev->dev = &dev->intf->dev;
- vdev->type = 0;
- vdev->type2 = 0;
+ vdev->parent = &dev->intf->dev;
vdev->minor = -1;
vdev->fops = &uvc_fops;
vdev->release = video_device_release;
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index b5a11eb8f9f..d7bd71be40a 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -23,6 +23,7 @@
#include <asm/atomic.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include "uvcvideo.h"
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index a0f6c60279e..79937d1031f 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -30,6 +30,7 @@
#include <linux/slab.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <asm/uaccess.h>
#include <asm/system.h>
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index e9dd996fd5d..88ca1310441 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -64,7 +64,7 @@
#include <linux/kmod.h>
#endif
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers");
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
new file mode 100644
index 00000000000..556615fe93d
--- /dev/null
+++ b/drivers/media/video/v4l2-dev.c
@@ -0,0 +1,422 @@
+/*
+ * Video capture interface for Linux version 2
+ *
+ * A generic video device interface for the LINUX operating system
+ * using a set of device structures/vectors for low level operations.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Authors: Alan Cox, <alan@redhat.com> (version 1)
+ * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
+ *
+ * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com>
+ * - Added procfs support
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kmod.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+#include <media/v4l2-common.h>
+
+#define VIDEO_NUM_DEVICES 256
+#define VIDEO_NAME "video4linux"
+
+/*
+ * sysfs stuff
+ */
+
+static ssize_t show_index(struct device *cd,
+ struct device_attribute *attr, char *buf)
+{
+ struct video_device *vfd = container_of(cd, struct video_device, dev);
+ return sprintf(buf, "%i\n", vfd->index);
+}
+
+static ssize_t show_name(struct device *cd,
+ struct device_attribute *attr, char *buf)
+{
+ struct video_device *vfd = container_of(cd, struct video_device, dev);
+ return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name);
+}
+
+static struct device_attribute video_device_attrs[] = {
+ __ATTR(name, S_IRUGO, show_name, NULL),
+ __ATTR(index, S_IRUGO, show_index, NULL),
+ __ATTR_NULL
+};
+
+struct video_device *video_device_alloc(void)
+{
+ struct video_device *vfd;
+
+ vfd = kzalloc(sizeof(*vfd), GFP_KERNEL);
+ return vfd;
+}
+EXPORT_SYMBOL(video_device_alloc);
+
+void video_device_release(struct video_device *vfd)
+{
+ kfree(vfd);
+}
+EXPORT_SYMBOL(video_device_release);
+
+static void video_release(struct device *cd)
+{
+ struct video_device *vfd = container_of(cd, struct video_device, dev);
+
+#if 1
+ /* needed until all drivers are fixed */
+ if (!vfd->release)
+ return;
+#endif
+ vfd->release(vfd);
+}
+
+static struct class video_class = {
+ .name = VIDEO_NAME,
+ .dev_attrs = video_device_attrs,
+ .dev_release = video_release,
+};
+
+/*
+ * Active devices
+ */
+
+static struct video_device *video_device[VIDEO_NUM_DEVICES];
+static DEFINE_MUTEX(videodev_lock);
+
+struct video_device *video_devdata(struct file *file)
+{
+ return video_device[iminor(file->f_path.dentry->d_inode)];
+}
+EXPORT_SYMBOL(video_devdata);
+
+/*
+ * Open a video device - FIXME: Obsoleted
+ */
+static int video_open(struct inode *inode, struct file *file)
+{
+ unsigned int minor = iminor(inode);
+ int err = 0;
+ struct video_device *vfl;
+ const struct file_operations *old_fops;
+
+ if (minor >= VIDEO_NUM_DEVICES)
+ return -ENODEV;
+ lock_kernel();
+ mutex_lock(&videodev_lock);
+ vfl = video_device[minor];
+ if (vfl == NULL) {
+ mutex_unlock(&videodev_lock);
+ request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
+ mutex_lock(&videodev_lock);
+ vfl = video_device[minor];
+ if (vfl == NULL) {
+ mutex_unlock(&videodev_lock);
+ unlock_kernel();
+ return -ENODEV;
+ }
+ }
+ old_fops = file->f_op;
+ file->f_op = fops_get(vfl->fops);
+ if (file->f_op->open)
+ err = file->f_op->open(inode, file);
+ if (err) {
+ fops_put(file->f_op);
+ file->f_op = fops_get(old_fops);
+ }
+ fops_put(old_fops);
+ mutex_unlock(&videodev_lock);
+ unlock_kernel();
+ return err;
+}
+
+/*
+ * open/release helper functions -- handle exclusive opens
+ * Should be removed soon
+ */
+int video_exclusive_open(struct inode *inode, struct file *file)
+{
+ struct video_device *vfl = video_devdata(file);
+ int retval = 0;
+
+ mutex_lock(&vfl->lock);
+ if (vfl->users)
+ retval = -EBUSY;
+ else
+ vfl->users++;
+ mutex_unlock(&vfl->lock);
+ return retval;
+}
+EXPORT_SYMBOL(video_exclusive_open);
+
+int video_exclusive_release(struct inode *inode, struct file *file)
+{
+ struct video_device *vfl = video_devdata(file);
+
+ vfl->users--;
+ return 0;
+}
+EXPORT_SYMBOL(video_exclusive_release);
+
+/**
+ * get_index - assign stream number based on parent device
+ * @vdev: video_device to assign index number to, vdev->dev should be assigned
+ * @num: -1 if auto assign, requested number otherwise
+ *
+ *
+ * returns -ENFILE if num is already in use, a free index number if
+ * successful.
+ */
+static int get_index(struct video_device *vdev, int num)
+{
+ u32 used = 0;
+ const int max_index = sizeof(used) * 8 - 1;
+ int i;
+
+ /* Currently a single v4l driver instance cannot create more than
+ 32 devices.
+ Increase to u64 or an array of u32 if more are needed. */
+ if (num > max_index) {
+ printk(KERN_ERR "videodev: %s num is too large\n", __func__);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
+ if (video_device[i] != NULL &&
+ video_device[i] != vdev &&
+ video_device[i]->parent == vdev->parent) {
+ used |= 1 << video_device[i]->index;
+ }
+ }
+
+ if (num >= 0) {
+ if (used & (1 << num))
+ return -ENFILE;
+ return num;
+ }
+
+ i = ffz(used);
+ return i > max_index ? -ENFILE : i;
+}
+
+static const struct file_operations video_fops;
+
+int video_register_device(struct video_device *vfd, int type, int nr)
+{
+ return video_register_device_index(vfd, type, nr, -1);
+}
+EXPORT_SYMBOL(video_register_device);
+
+/**
+ * video_register_device - register video4linux devices
+ * @vfd: video device structure we want to register
+ * @type: type of device to register
+ * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
+ * -1 == first free)
+ *
+ * The registration code assigns minor numbers based on the type
+ * requested. -ENFILE is returned in all the device slots for this
+ * category are full. If not then the minor field is set and the
+ * driver initialize function is called (if non %NULL).
+ *
+ * Zero is returned on success.
+ *
+ * Valid types are
+ *
+ * %VFL_TYPE_GRABBER - A frame grabber
+ *
+ * %VFL_TYPE_VTX - A teletext device
+ *
+ * %VFL_TYPE_VBI - Vertical blank data (undecoded)
+ *
+ * %VFL_TYPE_RADIO - A radio card
+ */
+
+int video_register_device_index(struct video_device *vfd, int type, int nr,
+ int index)
+{
+ int i = 0;
+ int base;
+ int end;
+ int ret;
+ char *name_base;
+
+ switch (type) {
+ case VFL_TYPE_GRABBER:
+ base = MINOR_VFL_TYPE_GRABBER_MIN;
+ end = MINOR_VFL_TYPE_GRABBER_MAX+1;
+ name_base = "video";
+ break;
+ case VFL_TYPE_VTX:
+ base = MINOR_VFL_TYPE_VTX_MIN;
+ end = MINOR_VFL_TYPE_VTX_MAX+1;
+ name_base = "vtx";
+ break;
+ case VFL_TYPE_VBI:
+ base = MINOR_VFL_TYPE_VBI_MIN;
+ end = MINOR_VFL_TYPE_VBI_MAX+1;
+ name_base = "vbi";
+ break;
+ case VFL_TYPE_RADIO:
+ base = MINOR_VFL_TYPE_RADIO_MIN;
+ end = MINOR_VFL_TYPE_RADIO_MAX+1;
+ name_base = "radio";
+ break;
+ default:
+ printk(KERN_ERR "%s called with unknown type: %d\n",
+ __func__, type);
+ return -1;
+ }
+
+ /* pick a minor number */
+ mutex_lock(&videodev_lock);
+ if (nr >= 0 && nr < end-base) {
+ /* use the one the driver asked for */
+ i = base + nr;
+ if (NULL != video_device[i]) {
+ mutex_unlock(&videodev_lock);
+ return -ENFILE;
+ }
+ } else {
+ /* use first free */
+ for (i = base; i < end; i++)
+ if (NULL == video_device[i])
+ break;
+ if (i == end) {
+ mutex_unlock(&videodev_lock);
+ return -ENFILE;
+ }
+ }
+ video_device[i] = vfd;
+ vfd->vfl_type = type;
+ vfd->minor = i;
+
+ ret = get_index(vfd, index);
+ vfd->index = ret;
+
+ mutex_unlock(&videodev_lock);
+
+ if (ret < 0) {
+ printk(KERN_ERR "%s: get_index failed\n", __func__);
+ goto fail_minor;
+ }
+
+ mutex_init(&vfd->lock);
+
+ /* sysfs class */
+ memset(&vfd->dev, 0x00, sizeof(vfd->dev));
+ vfd->dev.class = &video_class;
+ vfd->dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
+ if (vfd->parent)
+ vfd->dev.parent = vfd->parent;
+ sprintf(vfd->dev.bus_id, "%s%d", name_base, i - base);
+ ret = device_register(&vfd->dev);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: device_register failed\n", __func__);
+ goto fail_minor;
+ }
+
+#if 1
+ /* needed until all drivers are fixed */
+ if (!vfd->release)
+ printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
+ "Please fix your driver for proper sysfs support, see "
+ "http://lwn.net/Articles/36850/\n", vfd->name);
+#endif
+ return 0;
+
+fail_minor:
+ mutex_lock(&videodev_lock);
+ video_device[vfd->minor] = NULL;
+ vfd->minor = -1;
+ mutex_unlock(&videodev_lock);
+ return ret;
+}
+EXPORT_SYMBOL(video_register_device_index);
+
+/**
+ * video_unregister_device - unregister a video4linux device
+ * @vfd: the device to unregister
+ *
+ * This unregisters the passed device and deassigns the minor
+ * number. Future open calls will be met with errors.
+ */
+
+void video_unregister_device(struct video_device *vfd)
+{
+ mutex_lock(&videodev_lock);
+ if (video_device[vfd->minor] != vfd)
+ panic("videodev: bad unregister");
+
+ video_device[vfd->minor] = NULL;
+ device_unregister(&vfd->dev);
+ mutex_unlock(&videodev_lock);
+}
+EXPORT_SYMBOL(video_unregister_device);
+
+/*
+ * Video fs operations
+ */
+static const struct file_operations video_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .open = video_open,
+};
+
+/*
+ * Initialise video for linux
+ */
+
+static int __init videodev_init(void)
+{
+ int ret;
+
+ printk(KERN_INFO "Linux video capture interface: v2.00\n");
+ if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
+ printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
+ return -EIO;
+ }
+
+ ret = class_register(&video_class);
+ if (ret < 0) {
+ unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
+ printk(KERN_WARNING "video_dev: class_register failed\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static void __exit videodev_exit(void)
+{
+ class_unregister(&video_class);
+ unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
+}
+
+module_init(videodev_init)
+module_exit(videodev_exit)
+
+MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
+MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
+MODULE_LICENSE("GPL");
+
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
new file mode 100644
index 00000000000..fdfe7739c96
--- /dev/null
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -0,0 +1,1875 @@
+/*
+ * Video capture interface for Linux version 2
+ *
+ * A generic framework to process V4L2 ioctl commands.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Authors: Alan Cox, <alan@redhat.com> (version 1)
+ * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#define __OLD_VIDIOC_ /* To allow fixing old calls */
+#include <linux/videodev2.h>
+
+#ifdef CONFIG_VIDEO_V4L1
+#include <linux/videodev.h>
+#endif
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <linux/video_decoder.h>
+
+#define dbgarg(cmd, fmt, arg...) \
+ do { \
+ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \
+ printk(KERN_DEBUG "%s: ", vfd->name); \
+ v4l_printk_ioctl(cmd); \
+ printk(" " fmt, ## arg); \
+ } \
+ } while (0)
+
+#define dbgarg2(fmt, arg...) \
+ do { \
+ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
+ printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\
+ } while (0)
+
+struct std_descr {
+ v4l2_std_id std;
+ const char *descr;
+};
+
+static const struct std_descr standards[] = {
+ { V4L2_STD_NTSC, "NTSC" },
+ { V4L2_STD_NTSC_M, "NTSC-M" },
+ { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" },
+ { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" },
+ { V4L2_STD_NTSC_443, "NTSC-443" },
+ { V4L2_STD_PAL, "PAL" },
+ { V4L2_STD_PAL_BG, "PAL-BG" },
+ { V4L2_STD_PAL_B, "PAL-B" },
+ { V4L2_STD_PAL_B1, "PAL-B1" },
+ { V4L2_STD_PAL_G, "PAL-G" },
+ { V4L2_STD_PAL_H, "PAL-H" },
+ { V4L2_STD_PAL_I, "PAL-I" },
+ { V4L2_STD_PAL_DK, "PAL-DK" },
+ { V4L2_STD_PAL_D, "PAL-D" },
+ { V4L2_STD_PAL_D1, "PAL-D1" },
+ { V4L2_STD_PAL_K, "PAL-K" },
+ { V4L2_STD_PAL_M, "PAL-M" },
+ { V4L2_STD_PAL_N, "PAL-N" },
+ { V4L2_STD_PAL_Nc, "PAL-Nc" },
+ { V4L2_STD_PAL_60, "PAL-60" },
+ { V4L2_STD_SECAM, "SECAM" },
+ { V4L2_STD_SECAM_B, "SECAM-B" },
+ { V4L2_STD_SECAM_G, "SECAM-G" },
+ { V4L2_STD_SECAM_H, "SECAM-H" },
+ { V4L2_STD_SECAM_DK, "SECAM-DK" },
+ { V4L2_STD_SECAM_D, "SECAM-D" },
+ { V4L2_STD_SECAM_K, "SECAM-K" },
+ { V4L2_STD_SECAM_K1, "SECAM-K1" },
+ { V4L2_STD_SECAM_L, "SECAM-L" },
+ { V4L2_STD_SECAM_LC, "SECAM-Lc" },
+ { 0, "Unknown" }
+};
+
+/* video4linux standard ID conversion to standard name
+ */
+const char *v4l2_norm_to_name(v4l2_std_id id)
+{
+ u32 myid = id;
+ int i;
+
+ /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
+ 64 bit comparations. So, on that architecture, with some gcc
+ variants, compilation fails. Currently, the max value is 30bit wide.
+ */
+ BUG_ON(myid != id);
+
+ for (i = 0; standards[i].std; i++)
+ if (myid == standards[i].std)
+ break;
+ return standards[i].descr;
+}
+EXPORT_SYMBOL(v4l2_norm_to_name);
+
+/* Fill in the fields of a v4l2_standard structure according to the
+ 'id' and 'transmission' parameters. Returns negative on error. */
+int v4l2_video_std_construct(struct v4l2_standard *vs,
+ int id, const char *name)
+{
+ u32 index = vs->index;
+
+ memset(vs, 0, sizeof(struct v4l2_standard));
+ vs->index = index;
+ vs->id = id;
+ if (id & V4L2_STD_525_60) {
+ vs->frameperiod.numerator = 1001;
+ vs->frameperiod.denominator = 30000;
+ vs->framelines = 525;
+ } else {
+ vs->frameperiod.numerator = 1;
+ vs->frameperiod.denominator = 25;
+ vs->framelines = 625;
+ }
+ strlcpy(vs->name, name, sizeof(vs->name));
+ return 0;
+}
+EXPORT_SYMBOL(v4l2_video_std_construct);
+
+/* ----------------------------------------------------------------- */
+/* some arrays for pretty-printing debug messages of enum types */
+
+const char *v4l2_field_names[] = {
+ [V4L2_FIELD_ANY] = "any",
+ [V4L2_FIELD_NONE] = "none",
+ [V4L2_FIELD_TOP] = "top",
+ [V4L2_FIELD_BOTTOM] = "bottom",
+ [V4L2_FIELD_INTERLACED] = "interlaced",
+ [V4L2_FIELD_SEQ_TB] = "seq-tb",
+ [V4L2_FIELD_SEQ_BT] = "seq-bt",
+ [V4L2_FIELD_ALTERNATE] = "alternate",
+ [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
+ [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
+};
+EXPORT_SYMBOL(v4l2_field_names);
+
+const char *v4l2_type_names[] = {
+ [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap",
+ [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay",
+ [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out",
+ [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
+ [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
+ [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
+ [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
+ [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
+};
+EXPORT_SYMBOL(v4l2_type_names);
+
+static const char *v4l2_memory_names[] = {
+ [V4L2_MEMORY_MMAP] = "mmap",
+ [V4L2_MEMORY_USERPTR] = "userptr",
+ [V4L2_MEMORY_OVERLAY] = "overlay",
+};
+
+#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
+ arr[a] : "unknown")
+
+/* ------------------------------------------------------------------ */
+/* debug help functions */
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static const char *v4l1_ioctls[] = {
+ [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
+ [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
+ [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN",
+ [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER",
+ [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER",
+ [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT",
+ [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT",
+ [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE",
+ [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN",
+ [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN",
+ [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF",
+ [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF",
+ [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY",
+ [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ",
+ [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ",
+ [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO",
+ [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO",
+ [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC",
+ [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE",
+ [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF",
+ [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT",
+ [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE",
+ [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE",
+ [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE",
+ [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
+ [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO",
+ [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
+ [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT",
+ [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"
+};
+#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
+#endif
+
+static const char *v4l2_ioctls[] = {
+ [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
+ [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
+ [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
+ [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
+ [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
+ [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
+ [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
+ [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
+ [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
+ [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
+ [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
+ [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
+ [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
+ [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
+ [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
+ [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
+ [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
+ [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
+ [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
+ [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
+ [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
+ [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
+ [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
+ [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
+ [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
+ [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
+ [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
+ [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
+ [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
+ [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
+ [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
+ [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
+ [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
+ [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
+ [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
+ [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
+ [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
+ [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
+ [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
+ [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
+ [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
+ [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
+ [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
+ [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
+ [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
+ [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
+ [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
+ [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
+ [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
+ [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
+ [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
+ [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
+ [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
+ [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
+ [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS",
+#if 1
+ [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES",
+ [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
+ [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX",
+ [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
+ [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
+
+ [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
+ [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
+
+ [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT",
+ [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK",
+#endif
+};
+#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
+
+static const char *v4l2_int_ioctls[] = {
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES",
+ [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS",
+ [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM",
+ [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT",
+ [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT",
+ [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT",
+ [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE",
+ [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO",
+ [_IOC_NR(DECODER_INIT)] = "DECODER_INIT",
+ [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS",
+ [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP",
+#endif
+ [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO",
+
+ [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR",
+ [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
+ [_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG",
+
+ [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE",
+ [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET",
+ [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
+ [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE",
+ [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA",
+ [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA",
+ [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ",
+ [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY",
+ [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING",
+ [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING",
+ [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING",
+ [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING",
+ [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ",
+ [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT",
+ [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT",
+ [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT",
+};
+#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
+
+/* Common ioctl debug function. This function can be used by
+ external ioctl messages as well as internal V4L ioctl */
+void v4l_printk_ioctl(unsigned int cmd)
+{
+ char *dir, *type;
+
+ switch (_IOC_TYPE(cmd)) {
+ case 'd':
+ if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) {
+ type = "v4l2_int";
+ break;
+ }
+ printk("%s", v4l2_int_ioctls[_IOC_NR(cmd)]);
+ return;
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ case 'v':
+ if (_IOC_NR(cmd) >= V4L1_IOCTLS) {
+ type = "v4l1";
+ break;
+ }
+ printk("%s", v4l1_ioctls[_IOC_NR(cmd)]);
+ return;
+#endif
+ case 'V':
+ if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
+ type = "v4l2";
+ break;
+ }
+ printk("%s", v4l2_ioctls[_IOC_NR(cmd)]);
+ return;
+ default:
+ type = "unknown";
+ }
+
+ switch (_IOC_DIR(cmd)) {
+ case _IOC_NONE: dir = "--"; break;
+ case _IOC_READ: dir = "r-"; break;
+ case _IOC_WRITE: dir = "-w"; break;
+ case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
+ default: dir = "*ERR*"; break;
+ }
+ printk("%s ioctl '%c', dir=%s, #%d (0x%08x)",
+ type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
+}
+EXPORT_SYMBOL(v4l_printk_ioctl);
+
+/*
+ * helper function -- handles userspace copying for ioctl arguments
+ */
+
+#ifdef __OLD_VIDIOC_
+static unsigned int
+video_fix_command(unsigned int cmd)
+{
+ switch (cmd) {
+ case VIDIOC_OVERLAY_OLD:
+ cmd = VIDIOC_OVERLAY;
+ break;
+ case VIDIOC_S_PARM_OLD:
+ cmd = VIDIOC_S_PARM;
+ break;
+ case VIDIOC_S_CTRL_OLD:
+ cmd = VIDIOC_S_CTRL;
+ break;
+ case VIDIOC_G_AUDIO_OLD:
+ cmd = VIDIOC_G_AUDIO;
+ break;
+ case VIDIOC_G_AUDOUT_OLD:
+ cmd = VIDIOC_G_AUDOUT;
+ break;
+ case VIDIOC_CROPCAP_OLD:
+ cmd = VIDIOC_CROPCAP;
+ break;
+ }
+ return cmd;
+}
+#endif
+
+/*
+ * Obsolete usercopy function - Should be removed soon
+ */
+int
+video_usercopy(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg,
+ int (*func)(struct inode *inode, struct file *file,
+ unsigned int cmd, void *arg))
+{
+ char sbuf[128];
+ void *mbuf = NULL;
+ void *parg = NULL;
+ int err = -EINVAL;
+ int is_ext_ctrl;
+ size_t ctrls_size = 0;
+ void __user *user_ptr = NULL;
+
+#ifdef __OLD_VIDIOC_
+ cmd = video_fix_command(cmd);
+#endif
+ is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
+ cmd == VIDIOC_TRY_EXT_CTRLS);
+
+ /* Copy arguments into temp kernel buffer */
+ switch (_IOC_DIR(cmd)) {
+ case _IOC_NONE:
+ parg = NULL;
+ break;
+ case _IOC_READ:
+ case _IOC_WRITE:
+ case (_IOC_WRITE | _IOC_READ):
+ if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
+ parg = sbuf;
+ } else {
+ /* too big to allocate from stack */
+ mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
+ if (NULL == mbuf)
+ return -ENOMEM;
+ parg = mbuf;
+ }
+
+ err = -EFAULT;
+ if (_IOC_DIR(cmd) & _IOC_WRITE)
+ if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
+ goto out;
+ break;
+ }
+ if (is_ext_ctrl) {
+ struct v4l2_ext_controls *p = parg;
+
+ /* In case of an error, tell the caller that it wasn't
+ a specific control that caused it. */
+ p->error_idx = p->count;
+ user_ptr = (void __user *)p->controls;
+ if (p->count) {
+ ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
+ /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
+ mbuf = kmalloc(ctrls_size, GFP_KERNEL);
+ err = -ENOMEM;
+ if (NULL == mbuf)
+ goto out_ext_ctrl;
+ err = -EFAULT;
+ if (copy_from_user(mbuf, user_ptr, ctrls_size))
+ goto out_ext_ctrl;
+ p->controls = mbuf;
+ }
+ }
+
+ /* call driver */
+ err = func(inode, file, cmd, parg);
+ if (err == -ENOIOCTLCMD)
+ err = -EINVAL;
+ if (is_ext_ctrl) {
+ struct v4l2_ext_controls *p = parg;
+
+ p->controls = (void *)user_ptr;
+ if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
+ err = -EFAULT;
+ goto out_ext_ctrl;
+ }
+ if (err < 0)
+ goto out;
+
+out_ext_ctrl:
+ /* Copy results into user buffer */
+ switch (_IOC_DIR(cmd)) {
+ case _IOC_READ:
+ case (_IOC_WRITE | _IOC_READ):
+ if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
+ err = -EFAULT;
+ break;
+ }
+
+out:
+ kfree(mbuf);
+ return err;
+}
+EXPORT_SYMBOL(video_usercopy);
+
+static void dbgbuf(unsigned int cmd, struct video_device *vfd,
+ struct v4l2_buffer *p)
+{
+ struct v4l2_timecode *tc = &p->timecode;
+
+ dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
+ "bytesused=%d, flags=0x%08d, "
+ "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
+ p->timestamp.tv_sec / 3600,
+ (int)(p->timestamp.tv_sec / 60) % 60,
+ (int)(p->timestamp.tv_sec % 60),
+ p->timestamp.tv_usec,
+ p->index,
+ prt_names(p->type, v4l2_type_names),
+ p->bytesused, p->flags,
+ p->field, p->sequence,
+ prt_names(p->memory, v4l2_memory_names),
+ p->m.userptr, p->length);
+ dbgarg2("timecode=%02d:%02d:%02d type=%d, "
+ "flags=0x%08d, frames=%d, userbits=0x%08x\n",
+ tc->hours, tc->minutes, tc->seconds,
+ tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
+}
+
+static inline void dbgrect(struct video_device *vfd, char *s,
+ struct v4l2_rect *r)
+{
+ dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top,
+ r->width, r->height);
+};
+
+static inline void v4l_print_pix_fmt(struct video_device *vfd,
+ struct v4l2_pix_format *fmt)
+{
+ dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, "
+ "bytesperline=%d sizeimage=%d, colorspace=%d\n",
+ fmt->width, fmt->height,
+ (fmt->pixelformat & 0xff),
+ (fmt->pixelformat >> 8) & 0xff,
+ (fmt->pixelformat >> 16) & 0xff,
+ (fmt->pixelformat >> 24) & 0xff,
+ prt_names(fmt->field, v4l2_field_names),
+ fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
+};
+
+static inline void v4l_print_ext_ctrls(unsigned int cmd,
+ struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals)
+{
+ __u32 i;
+
+ if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG))
+ return;
+ dbgarg(cmd, "");
+ printk(KERN_CONT "class=0x%x", c->ctrl_class);
+ for (i = 0; i < c->count; i++) {
+ if (show_vals)
+ printk(KERN_CONT " id/val=0x%x/0x%x",
+ c->controls[i].id, c->controls[i].value);
+ else
+ printk(KERN_CONT " id=0x%x", c->controls[i].id);
+ }
+ printk(KERN_CONT "\n");
+};
+
+static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
+{
+ __u32 i;
+
+ /* zero the reserved fields */
+ c->reserved[0] = c->reserved[1] = 0;
+ for (i = 0; i < c->count; i++) {
+ c->controls[i].reserved2[0] = 0;
+ c->controls[i].reserved2[1] = 0;
+ }
+ /* V4L2_CID_PRIVATE_BASE cannot be used as control class
+ when using extended controls.
+ Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
+ is it allowed for backwards compatibility.
+ */
+ if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
+ return 0;
+ /* Check that all controls are from the same control class. */
+ for (i = 0; i < c->count; i++) {
+ if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) {
+ c->error_idx = i;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
+{
+ if (ops == NULL)
+ return -EINVAL;
+
+ switch (type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ if (ops->vidioc_try_fmt_vid_cap)
+ return 0;
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ if (ops->vidioc_try_fmt_vid_overlay)
+ return 0;
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ if (ops->vidioc_try_fmt_vid_out)
+ return 0;
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+ if (ops->vidioc_try_fmt_vid_out_overlay)
+ return 0;
+ break;
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ if (ops->vidioc_try_fmt_vbi_cap)
+ return 0;
+ break;
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ if (ops->vidioc_try_fmt_vbi_out)
+ return 0;
+ break;
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ if (ops->vidioc_try_fmt_sliced_vbi_cap)
+ return 0;
+ break;
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ if (ops->vidioc_try_fmt_sliced_vbi_out)
+ return 0;
+ break;
+ case V4L2_BUF_TYPE_PRIVATE:
+ if (ops->vidioc_try_fmt_type_private)
+ return 0;
+ break;
+ }
+ return -EINVAL;
+}
+
+static int __video_do_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, void *arg)
+{
+ struct video_device *vfd = video_devdata(file);
+ const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
+ void *fh = file->private_data;
+ int ret = -EINVAL;
+
+ if ((vfd->debug & V4L2_DEBUG_IOCTL) &&
+ !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
+ v4l_print_ioctl(vfd->name, cmd);
+ printk(KERN_CONT "\n");
+ }
+
+ if (ops == NULL) {
+ printk(KERN_WARNING "videodev: \"%s\" has no ioctl_ops.\n",
+ vfd->name);
+ return -EINVAL;
+ }
+
+#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 (!ops->vidiocgmbuf)
+ return ret;
+ ret = ops->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 ------------------------------------------ */
+ case VIDIOC_QUERYCAP:
+ {
+ struct v4l2_capability *cap = (struct v4l2_capability *)arg;
+ memset(cap, 0, sizeof(*cap));
+
+ if (!ops->vidioc_querycap)
+ break;
+
+ ret = ops->vidioc_querycap(file, fh, cap);
+ if (!ret)
+ dbgarg(cmd, "driver=%s, card=%s, bus=%s, "
+ "version=0x%08x, "
+ "capabilities=0x%08x\n",
+ cap->driver, cap->card, cap->bus_info,
+ cap->version,
+ cap->capabilities);
+ break;
+ }
+
+ /* --- priority ------------------------------------------ */
+ case VIDIOC_G_PRIORITY:
+ {
+ enum v4l2_priority *p = arg;
+
+ if (!ops->vidioc_g_priority)
+ break;
+ ret = ops->vidioc_g_priority(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "priority is %d\n", *p);
+ break;
+ }
+ case VIDIOC_S_PRIORITY:
+ {
+ enum v4l2_priority *p = arg;
+
+ if (!ops->vidioc_s_priority)
+ break;
+ dbgarg(cmd, "setting priority to %d\n", *p);
+ ret = ops->vidioc_s_priority(file, fh, *p);
+ break;
+ }
+
+ /* --- capture ioctls ---------------------------------------- */
+ case VIDIOC_ENUM_FMT:
+ {
+ struct v4l2_fmtdesc *f = arg;
+ enum v4l2_buf_type type;
+ unsigned int index;
+
+ index = f->index;
+ type = f->type;
+ memset(f, 0, sizeof(*f));
+ f->index = index;
+ f->type = type;
+
+ switch (type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ if (ops->vidioc_enum_fmt_vid_cap)
+ ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ if (ops->vidioc_enum_fmt_vid_overlay)
+ ret = ops->vidioc_enum_fmt_vid_overlay(file,
+ fh, f);
+ break;
+#if 1
+ /* V4L2_BUF_TYPE_VBI_CAPTURE should not support VIDIOC_ENUM_FMT
+ * according to the spec. The bttv and saa7134 drivers support
+ * it though, so just warn that this is deprecated and will be
+ * removed in the near future. */
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ if (ops->vidioc_enum_fmt_vbi_cap) {
+ printk(KERN_WARNING "vidioc_enum_fmt_vbi_cap will be removed in 2.6.28!\n");
+ ret = ops->vidioc_enum_fmt_vbi_cap(file, fh, f);
+ }
+ break;
+#endif
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ if (ops->vidioc_enum_fmt_vid_out)
+ ret = ops->vidioc_enum_fmt_vid_out(file, fh, f);
+ break;
+ case V4L2_BUF_TYPE_PRIVATE:
+ if (ops->vidioc_enum_fmt_type_private)
+ ret = ops->vidioc_enum_fmt_type_private(file,
+ fh, f);
+ break;
+ default:
+ break;
+ }
+ if (!ret)
+ dbgarg(cmd, "index=%d, type=%d, flags=%d, "
+ "pixelformat=%c%c%c%c, description='%s'\n",
+ f->index, f->type, f->flags,
+ (f->pixelformat & 0xff),
+ (f->pixelformat >> 8) & 0xff,
+ (f->pixelformat >> 16) & 0xff,
+ (f->pixelformat >> 24) & 0xff,
+ f->description);
+ break;
+ }
+ case VIDIOC_G_FMT:
+ {
+ struct v4l2_format *f = (struct v4l2_format *)arg;
+
+ memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data));
+
+ /* FIXME: Should be one dump per type */
+ dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
+
+ switch (f->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ if (ops->vidioc_g_fmt_vid_cap)
+ ret = ops->vidioc_g_fmt_vid_cap(file, fh, f);
+ if (!ret)
+ v4l_print_pix_fmt(vfd, &f->fmt.pix);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ if (ops->vidioc_g_fmt_vid_overlay)
+ ret = ops->vidioc_g_fmt_vid_overlay(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ if (ops->vidioc_g_fmt_vid_out)
+ ret = ops->vidioc_g_fmt_vid_out(file, fh, f);
+ if (!ret)
+ v4l_print_pix_fmt(vfd, &f->fmt.pix);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+ if (ops->vidioc_g_fmt_vid_out_overlay)
+ ret = ops->vidioc_g_fmt_vid_out_overlay(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ if (ops->vidioc_g_fmt_vbi_cap)
+ ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f);
+ break;
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ if (ops->vidioc_g_fmt_vbi_out)
+ ret = ops->vidioc_g_fmt_vbi_out(file, fh, f);
+ break;
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ if (ops->vidioc_g_fmt_sliced_vbi_cap)
+ ret = ops->vidioc_g_fmt_sliced_vbi_cap(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ if (ops->vidioc_g_fmt_sliced_vbi_out)
+ ret = ops->vidioc_g_fmt_sliced_vbi_out(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_PRIVATE:
+ if (ops->vidioc_g_fmt_type_private)
+ ret = ops->vidioc_g_fmt_type_private(file,
+ fh, f);
+ break;
+ }
+
+ break;
+ }
+ case VIDIOC_S_FMT:
+ {
+ struct v4l2_format *f = (struct v4l2_format *)arg;
+
+ /* FIXME: Should be one dump per type */
+ dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
+
+ switch (f->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ v4l_print_pix_fmt(vfd, &f->fmt.pix);
+ if (ops->vidioc_s_fmt_vid_cap)
+ ret = ops->vidioc_s_fmt_vid_cap(file, fh, f);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ if (ops->vidioc_s_fmt_vid_overlay)
+ ret = ops->vidioc_s_fmt_vid_overlay(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ v4l_print_pix_fmt(vfd, &f->fmt.pix);
+ if (ops->vidioc_s_fmt_vid_out)
+ ret = ops->vidioc_s_fmt_vid_out(file, fh, f);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+ if (ops->vidioc_s_fmt_vid_out_overlay)
+ ret = ops->vidioc_s_fmt_vid_out_overlay(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ if (ops->vidioc_s_fmt_vbi_cap)
+ ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f);
+ break;
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ if (ops->vidioc_s_fmt_vbi_out)
+ ret = ops->vidioc_s_fmt_vbi_out(file, fh, f);
+ break;
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ if (ops->vidioc_s_fmt_sliced_vbi_cap)
+ ret = ops->vidioc_s_fmt_sliced_vbi_cap(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ if (ops->vidioc_s_fmt_sliced_vbi_out)
+ ret = ops->vidioc_s_fmt_sliced_vbi_out(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_PRIVATE:
+ if (ops->vidioc_s_fmt_type_private)
+ ret = ops->vidioc_s_fmt_type_private(file,
+ fh, f);
+ break;
+ }
+ break;
+ }
+ case VIDIOC_TRY_FMT:
+ {
+ struct v4l2_format *f = (struct v4l2_format *)arg;
+
+ /* FIXME: Should be one dump per type */
+ dbgarg(cmd, "type=%s\n", prt_names(f->type,
+ v4l2_type_names));
+ switch (f->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ if (ops->vidioc_try_fmt_vid_cap)
+ ret = ops->vidioc_try_fmt_vid_cap(file, fh, f);
+ if (!ret)
+ v4l_print_pix_fmt(vfd, &f->fmt.pix);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ if (ops->vidioc_try_fmt_vid_overlay)
+ ret = ops->vidioc_try_fmt_vid_overlay(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ if (ops->vidioc_try_fmt_vid_out)
+ ret = ops->vidioc_try_fmt_vid_out(file, fh, f);
+ if (!ret)
+ v4l_print_pix_fmt(vfd, &f->fmt.pix);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+ if (ops->vidioc_try_fmt_vid_out_overlay)
+ ret = ops->vidioc_try_fmt_vid_out_overlay(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ if (ops->vidioc_try_fmt_vbi_cap)
+ ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f);
+ break;
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ if (ops->vidioc_try_fmt_vbi_out)
+ ret = ops->vidioc_try_fmt_vbi_out(file, fh, f);
+ break;
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ if (ops->vidioc_try_fmt_sliced_vbi_cap)
+ ret = ops->vidioc_try_fmt_sliced_vbi_cap(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ if (ops->vidioc_try_fmt_sliced_vbi_out)
+ ret = ops->vidioc_try_fmt_sliced_vbi_out(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_PRIVATE:
+ if (ops->vidioc_try_fmt_type_private)
+ ret = ops->vidioc_try_fmt_type_private(file,
+ fh, f);
+ break;
+ }
+
+ break;
+ }
+ /* FIXME: Those buf reqs could be handled here,
+ with some changes on videobuf to allow its header to be included at
+ videodev2.h or being merged at videodev2.
+ */
+ case VIDIOC_REQBUFS:
+ {
+ struct v4l2_requestbuffers *p = arg;
+
+ if (!ops->vidioc_reqbufs)
+ break;
+ ret = check_fmt(ops, p->type);
+ if (ret)
+ break;
+
+ ret = ops->vidioc_reqbufs(file, fh, p);
+ dbgarg(cmd, "count=%d, type=%s, memory=%s\n",
+ p->count,
+ prt_names(p->type, v4l2_type_names),
+ prt_names(p->memory, v4l2_memory_names));
+ break;
+ }
+ case VIDIOC_QUERYBUF:
+ {
+ struct v4l2_buffer *p = arg;
+
+ if (!ops->vidioc_querybuf)
+ break;
+ ret = check_fmt(ops, p->type);
+ if (ret)
+ break;
+
+ ret = ops->vidioc_querybuf(file, fh, p);
+ if (!ret)
+ dbgbuf(cmd, vfd, p);
+ break;
+ }
+ case VIDIOC_QBUF:
+ {
+ struct v4l2_buffer *p = arg;
+
+ if (!ops->vidioc_qbuf)
+ break;
+ ret = check_fmt(ops, p->type);
+ if (ret)
+ break;
+
+ ret = ops->vidioc_qbuf(file, fh, p);
+ if (!ret)
+ dbgbuf(cmd, vfd, p);
+ break;
+ }
+ case VIDIOC_DQBUF:
+ {
+ struct v4l2_buffer *p = arg;
+
+ if (!ops->vidioc_dqbuf)
+ break;
+ ret = check_fmt(ops, p->type);
+ if (ret)
+ break;
+
+ ret = ops->vidioc_dqbuf(file, fh, p);
+ if (!ret)
+ dbgbuf(cmd, vfd, p);
+ break;
+ }
+ case VIDIOC_OVERLAY:
+ {
+ int *i = arg;
+
+ if (!ops->vidioc_overlay)
+ break;
+ dbgarg(cmd, "value=%d\n", *i);
+ ret = ops->vidioc_overlay(file, fh, *i);
+ break;
+ }
+ case VIDIOC_G_FBUF:
+ {
+ struct v4l2_framebuffer *p = arg;
+
+ if (!ops->vidioc_g_fbuf)
+ break;
+ ret = ops->vidioc_g_fbuf(file, fh, arg);
+ if (!ret) {
+ dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
+ p->capability, p->flags,
+ (unsigned long)p->base);
+ v4l_print_pix_fmt(vfd, &p->fmt);
+ }
+ break;
+ }
+ case VIDIOC_S_FBUF:
+ {
+ struct v4l2_framebuffer *p = arg;
+
+ if (!ops->vidioc_s_fbuf)
+ break;
+ dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
+ p->capability, p->flags, (unsigned long)p->base);
+ v4l_print_pix_fmt(vfd, &p->fmt);
+ ret = ops->vidioc_s_fbuf(file, fh, arg);
+ break;
+ }
+ case VIDIOC_STREAMON:
+ {
+ enum v4l2_buf_type i = *(int *)arg;
+
+ if (!ops->vidioc_streamon)
+ break;
+ dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
+ ret = ops->vidioc_streamon(file, fh, i);
+ break;
+ }
+ case VIDIOC_STREAMOFF:
+ {
+ enum v4l2_buf_type i = *(int *)arg;
+
+ if (!ops->vidioc_streamoff)
+ break;
+ dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
+ ret = ops->vidioc_streamoff(file, fh, i);
+ break;
+ }
+ /* ---------- tv norms ---------- */
+ case VIDIOC_ENUMSTD:
+ {
+ struct v4l2_standard *p = arg;
+ v4l2_std_id id = vfd->tvnorms, curr_id = 0;
+ unsigned int index = p->index, i, j = 0;
+ const char *descr = "";
+
+ /* Return norm array in a canonical way */
+ for (i = 0; i <= index && id; i++) {
+ /* last std value in the standards array is 0, so this
+ while always ends there since (id & 0) == 0. */
+ while ((id & standards[j].std) != standards[j].std)
+ j++;
+ curr_id = standards[j].std;
+ descr = standards[j].descr;
+ j++;
+ if (curr_id == 0)
+ break;
+ if (curr_id != V4L2_STD_PAL &&
+ curr_id != V4L2_STD_SECAM &&
+ curr_id != V4L2_STD_NTSC)
+ id &= ~curr_id;
+ }
+ if (i <= index)
+ return -EINVAL;
+
+ v4l2_video_std_construct(p, curr_id, descr);
+ p->index = index;
+
+ dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
+ "framelines=%d\n", p->index,
+ (unsigned long long)p->id, p->name,
+ p->frameperiod.numerator,
+ p->frameperiod.denominator,
+ p->framelines);
+
+ ret = 0;
+ break;
+ }
+ case VIDIOC_G_STD:
+ {
+ v4l2_std_id *id = arg;
+
+ ret = 0;
+ /* Calls the specific handler */
+ if (ops->vidioc_g_std)
+ ret = ops->vidioc_g_std(file, fh, id);
+ else
+ *id = vfd->current_norm;
+
+ if (!ret)
+ dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
+ break;
+ }
+ case VIDIOC_S_STD:
+ {
+ v4l2_std_id *id = arg, norm;
+
+ dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id);
+
+ norm = (*id) & vfd->tvnorms;
+ if (vfd->tvnorms && !norm) /* Check if std is supported */
+ break;
+
+ /* Calls the specific handler */
+ if (ops->vidioc_s_std)
+ ret = ops->vidioc_s_std(file, fh, &norm);
+ else
+ ret = -EINVAL;
+
+ /* Updates standard information */
+ if (ret >= 0)
+ vfd->current_norm = norm;
+ break;
+ }
+ case VIDIOC_QUERYSTD:
+ {
+ v4l2_std_id *p = arg;
+
+ if (!ops->vidioc_querystd)
+ break;
+ ret = ops->vidioc_querystd(file, fh, arg);
+ if (!ret)
+ dbgarg(cmd, "detected std=%08Lx\n",
+ (unsigned long long)*p);
+ break;
+ }
+ /* ------ input switching ---------- */
+ /* FIXME: Inputs can be handled inside videodev2 */
+ case VIDIOC_ENUMINPUT:
+ {
+ struct v4l2_input *p = arg;
+ int i = p->index;
+
+ if (!ops->vidioc_enum_input)
+ break;
+ memset(p, 0, sizeof(*p));
+ p->index = i;
+
+ ret = ops->vidioc_enum_input(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "index=%d, name=%s, type=%d, "
+ "audioset=%d, "
+ "tuner=%d, std=%08Lx, status=%d\n",
+ p->index, p->name, p->type, p->audioset,
+ p->tuner,
+ (unsigned long long)p->std,
+ p->status);
+ break;
+ }
+ case VIDIOC_G_INPUT:
+ {
+ unsigned int *i = arg;
+
+ if (!ops->vidioc_g_input)
+ break;
+ ret = ops->vidioc_g_input(file, fh, i);
+ if (!ret)
+ dbgarg(cmd, "value=%d\n", *i);
+ break;
+ }
+ case VIDIOC_S_INPUT:
+ {
+ unsigned int *i = arg;
+
+ if (!ops->vidioc_s_input)
+ break;
+ dbgarg(cmd, "value=%d\n", *i);
+ ret = ops->vidioc_s_input(file, fh, *i);
+ break;
+ }
+
+ /* ------ output switching ---------- */
+ case VIDIOC_ENUMOUTPUT:
+ {
+ struct v4l2_output *p = arg;
+ int i = p->index;
+
+ if (!ops->vidioc_enum_output)
+ break;
+ memset(p, 0, sizeof(*p));
+ p->index = i;
+
+ ret = ops->vidioc_enum_output(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "index=%d, name=%s, type=%d, "
+ "audioset=0x%x, "
+ "modulator=%d, std=0x%08Lx\n",
+ p->index, p->name, p->type, p->audioset,
+ p->modulator, (unsigned long long)p->std);
+ break;
+ }
+ case VIDIOC_G_OUTPUT:
+ {
+ unsigned int *i = arg;
+
+ if (!ops->vidioc_g_output)
+ break;
+ ret = ops->vidioc_g_output(file, fh, i);
+ if (!ret)
+ dbgarg(cmd, "value=%d\n", *i);
+ break;
+ }
+ case VIDIOC_S_OUTPUT:
+ {
+ unsigned int *i = arg;
+
+ if (!ops->vidioc_s_output)
+ break;
+ dbgarg(cmd, "value=%d\n", *i);
+ ret = ops->vidioc_s_output(file, fh, *i);
+ break;
+ }
+
+ /* --- controls ---------------------------------------------- */
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl *p = arg;
+
+ if (!ops->vidioc_queryctrl)
+ break;
+ ret = ops->vidioc_queryctrl(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, "
+ "step=%d, default=%d, flags=0x%08x\n",
+ p->id, p->type, p->name,
+ p->minimum, p->maximum,
+ p->step, p->default_value, p->flags);
+ else
+ dbgarg(cmd, "id=0x%x\n", p->id);
+ break;
+ }
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *p = arg;
+
+ if (ops->vidioc_g_ctrl)
+ ret = ops->vidioc_g_ctrl(file, fh, p);
+ else if (ops->vidioc_g_ext_ctrls) {
+ struct v4l2_ext_controls ctrls;
+ struct v4l2_ext_control ctrl;
+
+ ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
+ ctrls.count = 1;
+ ctrls.controls = &ctrl;
+ ctrl.id = p->id;
+ ctrl.value = p->value;
+ if (check_ext_ctrls(&ctrls, 1)) {
+ ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
+ if (ret == 0)
+ p->value = ctrl.value;
+ }
+ } else
+ break;
+ if (!ret)
+ dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
+ else
+ dbgarg(cmd, "id=0x%x\n", p->id);
+ break;
+ }
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *p = arg;
+ struct v4l2_ext_controls ctrls;
+ struct v4l2_ext_control ctrl;
+
+ if (!ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls)
+ break;
+
+ dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
+
+ if (ops->vidioc_s_ctrl) {
+ ret = ops->vidioc_s_ctrl(file, fh, p);
+ break;
+ }
+ if (!ops->vidioc_s_ext_ctrls)
+ break;
+
+ ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
+ ctrls.count = 1;
+ ctrls.controls = &ctrl;
+ ctrl.id = p->id;
+ ctrl.value = p->value;
+ if (check_ext_ctrls(&ctrls, 1))
+ ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
+ break;
+ }
+ case VIDIOC_G_EXT_CTRLS:
+ {
+ struct v4l2_ext_controls *p = arg;
+
+ p->error_idx = p->count;
+ if (!ops->vidioc_g_ext_ctrls)
+ break;
+ if (check_ext_ctrls(p, 0))
+ ret = ops->vidioc_g_ext_ctrls(file, fh, p);
+ v4l_print_ext_ctrls(cmd, vfd, p, !ret);
+ break;
+ }
+ case VIDIOC_S_EXT_CTRLS:
+ {
+ struct v4l2_ext_controls *p = arg;
+
+ p->error_idx = p->count;
+ if (!ops->vidioc_s_ext_ctrls)
+ break;
+ v4l_print_ext_ctrls(cmd, vfd, p, 1);
+ if (check_ext_ctrls(p, 0))
+ ret = ops->vidioc_s_ext_ctrls(file, fh, p);
+ break;
+ }
+ case VIDIOC_TRY_EXT_CTRLS:
+ {
+ struct v4l2_ext_controls *p = arg;
+
+ p->error_idx = p->count;
+ if (!ops->vidioc_try_ext_ctrls)
+ break;
+ v4l_print_ext_ctrls(cmd, vfd, p, 1);
+ if (check_ext_ctrls(p, 0))
+ ret = ops->vidioc_try_ext_ctrls(file, fh, p);
+ break;
+ }
+ case VIDIOC_QUERYMENU:
+ {
+ struct v4l2_querymenu *p = arg;
+
+ if (!ops->vidioc_querymenu)
+ break;
+ ret = ops->vidioc_querymenu(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "id=0x%x, index=%d, name=%s\n",
+ p->id, p->index, p->name);
+ else
+ dbgarg(cmd, "id=0x%x, index=%d\n",
+ p->id, p->index);
+ break;
+ }
+ /* --- audio ---------------------------------------------- */
+ case VIDIOC_ENUMAUDIO:
+ {
+ struct v4l2_audio *p = arg;
+
+ if (!ops->vidioc_enumaudio)
+ break;
+ ret = ops->vidioc_enumaudio(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
+ "mode=0x%x\n", p->index, p->name,
+ p->capability, p->mode);
+ else
+ dbgarg(cmd, "index=%d\n", p->index);
+ break;
+ }
+ case VIDIOC_G_AUDIO:
+ {
+ struct v4l2_audio *p = arg;
+ __u32 index = p->index;
+
+ if (!ops->vidioc_g_audio)
+ break;
+
+ memset(p, 0, sizeof(*p));
+ p->index = index;
+ ret = ops->vidioc_g_audio(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
+ "mode=0x%x\n", p->index,
+ p->name, p->capability, p->mode);
+ else
+ dbgarg(cmd, "index=%d\n", p->index);
+ break;
+ }
+ case VIDIOC_S_AUDIO:
+ {
+ struct v4l2_audio *p = arg;
+
+ if (!ops->vidioc_s_audio)
+ break;
+ dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
+ "mode=0x%x\n", p->index, p->name,
+ p->capability, p->mode);
+ ret = ops->vidioc_s_audio(file, fh, p);
+ break;
+ }
+ case VIDIOC_ENUMAUDOUT:
+ {
+ struct v4l2_audioout *p = arg;
+
+ if (!ops->vidioc_enumaudout)
+ break;
+ dbgarg(cmd, "Enum for index=%d\n", p->index);
+ ret = ops->vidioc_enumaudout(file, fh, p);
+ if (!ret)
+ dbgarg2("index=%d, name=%s, capability=%d, "
+ "mode=%d\n", p->index, p->name,
+ p->capability, p->mode);
+ break;
+ }
+ case VIDIOC_G_AUDOUT:
+ {
+ struct v4l2_audioout *p = arg;
+
+ if (!ops->vidioc_g_audout)
+ break;
+ dbgarg(cmd, "Enum for index=%d\n", p->index);
+ ret = ops->vidioc_g_audout(file, fh, p);
+ if (!ret)
+ dbgarg2("index=%d, name=%s, capability=%d, "
+ "mode=%d\n", p->index, p->name,
+ p->capability, p->mode);
+ break;
+ }
+ case VIDIOC_S_AUDOUT:
+ {
+ struct v4l2_audioout *p = arg;
+
+ if (!ops->vidioc_s_audout)
+ break;
+ dbgarg(cmd, "index=%d, name=%s, capability=%d, "
+ "mode=%d\n", p->index, p->name,
+ p->capability, p->mode);
+
+ ret = ops->vidioc_s_audout(file, fh, p);
+ break;
+ }
+ case VIDIOC_G_MODULATOR:
+ {
+ struct v4l2_modulator *p = arg;
+
+ if (!ops->vidioc_g_modulator)
+ break;
+ ret = ops->vidioc_g_modulator(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "index=%d, name=%s, "
+ "capability=%d, rangelow=%d,"
+ " rangehigh=%d, txsubchans=%d\n",
+ p->index, p->name, p->capability,
+ p->rangelow, p->rangehigh,
+ p->txsubchans);
+ break;
+ }
+ case VIDIOC_S_MODULATOR:
+ {
+ struct v4l2_modulator *p = arg;
+
+ if (!ops->vidioc_s_modulator)
+ break;
+ dbgarg(cmd, "index=%d, name=%s, capability=%d, "
+ "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
+ p->index, p->name, p->capability, p->rangelow,
+ p->rangehigh, p->txsubchans);
+ ret = ops->vidioc_s_modulator(file, fh, p);
+ break;
+ }
+ case VIDIOC_G_CROP:
+ {
+ struct v4l2_crop *p = arg;
+
+ if (!ops->vidioc_g_crop)
+ break;
+ dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
+ ret = ops->vidioc_g_crop(file, fh, p);
+ if (!ret)
+ dbgrect(vfd, "", &p->c);
+ break;
+ }
+ case VIDIOC_S_CROP:
+ {
+ struct v4l2_crop *p = arg;
+
+ if (!ops->vidioc_s_crop)
+ break;
+ dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
+ dbgrect(vfd, "", &p->c);
+ ret = ops->vidioc_s_crop(file, fh, p);
+ break;
+ }
+ case VIDIOC_CROPCAP:
+ {
+ struct v4l2_cropcap *p = arg;
+
+ /*FIXME: Should also show v4l2_fract pixelaspect */
+ if (!ops->vidioc_cropcap)
+ break;
+ dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
+ ret = ops->vidioc_cropcap(file, fh, p);
+ if (!ret) {
+ dbgrect(vfd, "bounds ", &p->bounds);
+ dbgrect(vfd, "defrect ", &p->defrect);
+ }
+ break;
+ }
+ case VIDIOC_G_JPEGCOMP:
+ {
+ struct v4l2_jpegcompression *p = arg;
+
+ if (!ops->vidioc_g_jpegcomp)
+ break;
+ ret = ops->vidioc_g_jpegcomp(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "quality=%d, APPn=%d, "
+ "APP_len=%d, COM_len=%d, "
+ "jpeg_markers=%d\n",
+ p->quality, p->APPn, p->APP_len,
+ p->COM_len, p->jpeg_markers);
+ break;
+ }
+ case VIDIOC_S_JPEGCOMP:
+ {
+ struct v4l2_jpegcompression *p = arg;
+
+ if (!ops->vidioc_g_jpegcomp)
+ break;
+ dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, "
+ "COM_len=%d, jpeg_markers=%d\n",
+ p->quality, p->APPn, p->APP_len,
+ p->COM_len, p->jpeg_markers);
+ ret = ops->vidioc_s_jpegcomp(file, fh, p);
+ break;
+ }
+ case VIDIOC_G_ENC_INDEX:
+ {
+ struct v4l2_enc_idx *p = arg;
+
+ if (!ops->vidioc_g_enc_index)
+ break;
+ ret = ops->vidioc_g_enc_index(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "entries=%d, entries_cap=%d\n",
+ p->entries, p->entries_cap);
+ break;
+ }
+ case VIDIOC_ENCODER_CMD:
+ {
+ struct v4l2_encoder_cmd *p = arg;
+
+ if (!ops->vidioc_encoder_cmd)
+ break;
+ memset(&p->raw, 0, sizeof(p->raw));
+ ret = ops->vidioc_encoder_cmd(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
+ break;
+ }
+ case VIDIOC_TRY_ENCODER_CMD:
+ {
+ struct v4l2_encoder_cmd *p = arg;
+
+ if (!ops->vidioc_try_encoder_cmd)
+ break;
+ memset(&p->raw, 0, sizeof(p->raw));
+ ret = ops->vidioc_try_encoder_cmd(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
+ break;
+ }
+ case VIDIOC_G_PARM:
+ {
+ struct v4l2_streamparm *p = arg;
+ __u32 type = p->type;
+
+ memset(p, 0, sizeof(*p));
+ p->type = type;
+
+ if (ops->vidioc_g_parm) {
+ ret = ops->vidioc_g_parm(file, fh, p);
+ } else {
+ struct v4l2_standard s;
+
+ if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ v4l2_video_std_construct(&s, vfd->current_norm,
+ v4l2_norm_to_name(vfd->current_norm));
+
+ p->parm.capture.timeperframe = s.frameperiod;
+ ret = 0;
+ }
+
+ dbgarg(cmd, "type=%d\n", p->type);
+ break;
+ }
+ case VIDIOC_S_PARM:
+ {
+ struct v4l2_streamparm *p = arg;
+
+ if (!ops->vidioc_s_parm)
+ break;
+ dbgarg(cmd, "type=%d\n", p->type);
+ ret = ops->vidioc_s_parm(file, fh, p);
+ break;
+ }
+ case VIDIOC_G_TUNER:
+ {
+ struct v4l2_tuner *p = arg;
+ __u32 index = p->index;
+
+ if (!ops->vidioc_g_tuner)
+ break;
+
+ memset(p, 0, sizeof(*p));
+ p->index = index;
+
+ ret = ops->vidioc_g_tuner(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "index=%d, name=%s, type=%d, "
+ "capability=0x%x, rangelow=%d, "
+ "rangehigh=%d, signal=%d, afc=%d, "
+ "rxsubchans=0x%x, audmode=%d\n",
+ p->index, p->name, p->type,
+ p->capability, p->rangelow,
+ p->rangehigh, p->signal, p->afc,
+ p->rxsubchans, p->audmode);
+ break;
+ }
+ case VIDIOC_S_TUNER:
+ {
+ struct v4l2_tuner *p = arg;
+
+ if (!ops->vidioc_s_tuner)
+ break;
+ dbgarg(cmd, "index=%d, name=%s, type=%d, "
+ "capability=0x%x, rangelow=%d, "
+ "rangehigh=%d, signal=%d, afc=%d, "
+ "rxsubchans=0x%x, audmode=%d\n",
+ p->index, p->name, p->type,
+ p->capability, p->rangelow,
+ p->rangehigh, p->signal, p->afc,
+ p->rxsubchans, p->audmode);
+ ret = ops->vidioc_s_tuner(file, fh, p);
+ break;
+ }
+ case VIDIOC_G_FREQUENCY:
+ {
+ struct v4l2_frequency *p = arg;
+
+ if (!ops->vidioc_g_frequency)
+ break;
+
+ memset(p->reserved, 0, sizeof(p->reserved));
+
+ ret = ops->vidioc_g_frequency(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
+ p->tuner, p->type, p->frequency);
+ break;
+ }
+ case VIDIOC_S_FREQUENCY:
+ {
+ struct v4l2_frequency *p = arg;
+
+ if (!ops->vidioc_s_frequency)
+ break;
+ dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
+ p->tuner, p->type, p->frequency);
+ ret = ops->vidioc_s_frequency(file, fh, p);
+ break;
+ }
+ case VIDIOC_G_SLICED_VBI_CAP:
+ {
+ struct v4l2_sliced_vbi_cap *p = arg;
+ __u32 type = p->type;
+
+ if (!ops->vidioc_g_sliced_vbi_cap)
+ break;
+ memset(p, 0, sizeof(*p));
+ p->type = type;
+ dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
+ ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p);
+ if (!ret)
+ dbgarg2("service_set=%d\n", p->service_set);
+ break;
+ }
+ case VIDIOC_LOG_STATUS:
+ {
+ if (!ops->vidioc_log_status)
+ break;
+ ret = ops->vidioc_log_status(file, fh);
+ break;
+ }
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ case VIDIOC_DBG_G_REGISTER:
+ {
+ struct v4l2_register *p = arg;
+
+ if (!capable(CAP_SYS_ADMIN))
+ ret = -EPERM;
+ else if (ops->vidioc_g_register)
+ ret = ops->vidioc_g_register(file, fh, p);
+ break;
+ }
+ case VIDIOC_DBG_S_REGISTER:
+ {
+ struct v4l2_register *p = arg;
+
+ if (!capable(CAP_SYS_ADMIN))
+ ret = -EPERM;
+ else if (ops->vidioc_s_register)
+ ret = ops->vidioc_s_register(file, fh, p);
+ break;
+ }
+#endif
+ case VIDIOC_G_CHIP_IDENT:
+ {
+ struct v4l2_chip_ident *p = arg;
+
+ if (!ops->vidioc_g_chip_ident)
+ break;
+ ret = ops->vidioc_g_chip_ident(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
+ break;
+ }
+ case VIDIOC_S_HW_FREQ_SEEK:
+ {
+ struct v4l2_hw_freq_seek *p = arg;
+
+ if (!ops->vidioc_s_hw_freq_seek)
+ break;
+ dbgarg(cmd,
+ "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n",
+ p->tuner, p->type, p->seek_upward, p->wrap_around);
+ ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
+ break;
+ }
+ default:
+ {
+ if (!ops->vidioc_default)
+ break;
+ ret = ops->vidioc_default(file, fh, cmd, arg);
+ break;
+ }
+ } /* switch */
+
+ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
+ if (ret < 0) {
+ v4l_print_ioctl(vfd->name, cmd);
+ printk(KERN_CONT " error %d\n", ret);
+ }
+ }
+
+ return ret;
+}
+
+int video_ioctl2(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ char sbuf[128];
+ void *mbuf = NULL;
+ void *parg = NULL;
+ int err = -EINVAL;
+ int is_ext_ctrl;
+ size_t ctrls_size = 0;
+ void __user *user_ptr = NULL;
+
+#ifdef __OLD_VIDIOC_
+ cmd = video_fix_command(cmd);
+#endif
+ is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
+ cmd == VIDIOC_TRY_EXT_CTRLS);
+
+ /* Copy arguments into temp kernel buffer */
+ switch (_IOC_DIR(cmd)) {
+ case _IOC_NONE:
+ parg = NULL;
+ break;
+ case _IOC_READ:
+ case _IOC_WRITE:
+ case (_IOC_WRITE | _IOC_READ):
+ if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
+ parg = sbuf;
+ } else {
+ /* too big to allocate from stack */
+ mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
+ if (NULL == mbuf)
+ return -ENOMEM;
+ parg = mbuf;
+ }
+
+ err = -EFAULT;
+ if (_IOC_DIR(cmd) & _IOC_WRITE)
+ if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
+ goto out;
+ break;
+ }
+
+ if (is_ext_ctrl) {
+ struct v4l2_ext_controls *p = parg;
+
+ /* In case of an error, tell the caller that it wasn't
+ a specific control that caused it. */
+ p->error_idx = p->count;
+ user_ptr = (void __user *)p->controls;
+ if (p->count) {
+ ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
+ /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
+ mbuf = kmalloc(ctrls_size, GFP_KERNEL);
+ err = -ENOMEM;
+ if (NULL == mbuf)
+ goto out_ext_ctrl;
+ err = -EFAULT;
+ if (copy_from_user(mbuf, user_ptr, ctrls_size))
+ goto out_ext_ctrl;
+ p->controls = mbuf;
+ }
+ }
+
+ /* Handles IOCTL */
+ err = __video_do_ioctl(inode, file, cmd, parg);
+ if (err == -ENOIOCTLCMD)
+ err = -EINVAL;
+ if (is_ext_ctrl) {
+ struct v4l2_ext_controls *p = parg;
+
+ p->controls = (void *)user_ptr;
+ if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
+ err = -EFAULT;
+ goto out_ext_ctrl;
+ }
+ if (err < 0)
+ goto out;
+
+out_ext_ctrl:
+ /* Copy results into user buffer */
+ switch (_IOC_DIR(cmd)) {
+ case _IOC_READ:
+ case (_IOC_WRITE | _IOC_READ):
+ if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
+ err = -EFAULT;
+ break;
+ }
+
+out:
+ kfree(mbuf);
+ return err;
+}
+EXPORT_SYMBOL(video_ioctl2);
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index 03f20acb668..31944b11e6e 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -28,10 +28,10 @@ struct videobuf_dma_contig_memory {
};
#define MAGIC_DC_MEM 0x0733ac61
-#define MAGIC_CHECK(is, should) \
- if (unlikely((is) != (should))) { \
- pr_err("magic mismatch: %x expected %x\n", is, should); \
- BUG(); \
+#define MAGIC_CHECK(is, should) \
+ if (unlikely((is) != (should))) { \
+ pr_err("magic mismatch: %x expected %x\n", (is), (should)); \
+ BUG(); \
}
static void
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index a868b7ed75f..be65a2fb397 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -203,7 +203,7 @@ static int __videobuf_iolock (struct videobuf_queue* q,
return 0;
/* FIXME: to properly support USERPTR, remap should occur.
- The code bellow won't work, since mem->vma = NULL
+ The code below won't work, since mem->vma = NULL
*/
/* Try to remap memory */
rc = remap_vmalloc_range(mem->vma, (void *)vb->baddr, 0);
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 6616e657055..e69de29bb2d 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -1,2262 +0,0 @@
-/*
- * Video capture interface for Linux version 2
- *
- * A generic video device interface for the LINUX operating system
- * using a set of device structures/vectors for low level operations.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Authors: Alan Cox, <alan@redhat.com> (version 1)
- * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
- *
- * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com>
- * - Added procfs support
- */
-
-#define dbgarg(cmd, fmt, arg...) \
- do { \
- if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \
- printk(KERN_DEBUG "%s: ", vfd->name); \
- v4l_printk_ioctl(cmd); \
- printk(" " fmt, ## arg); \
- } \
- } while (0)
-
-#define dbgarg2(fmt, arg...) \
- do { \
- if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
- printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\
- } while (0)
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kmod.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#define __OLD_VIDIOC_ /* To allow fixing old calls*/
-#include <linux/videodev2.h>
-
-#ifdef CONFIG_VIDEO_V4L1
-#include <linux/videodev.h>
-#endif
-#include <media/v4l2-common.h>
-#include <linux/video_decoder.h>
-
-#define VIDEO_NUM_DEVICES 256
-#define VIDEO_NAME "video4linux"
-
-struct std_descr {
- v4l2_std_id std;
- const char *descr;
-};
-
-static const struct std_descr standards[] = {
- { V4L2_STD_NTSC, "NTSC" },
- { V4L2_STD_NTSC_M, "NTSC-M" },
- { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" },
- { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" },
- { V4L2_STD_NTSC_443, "NTSC-443" },
- { V4L2_STD_PAL, "PAL" },
- { V4L2_STD_PAL_BG, "PAL-BG" },
- { V4L2_STD_PAL_B, "PAL-B" },
- { V4L2_STD_PAL_B1, "PAL-B1" },
- { V4L2_STD_PAL_G, "PAL-G" },
- { V4L2_STD_PAL_H, "PAL-H" },
- { V4L2_STD_PAL_I, "PAL-I" },
- { V4L2_STD_PAL_DK, "PAL-DK" },
- { V4L2_STD_PAL_D, "PAL-D" },
- { V4L2_STD_PAL_D1, "PAL-D1" },
- { V4L2_STD_PAL_K, "PAL-K" },
- { V4L2_STD_PAL_M, "PAL-M" },
- { V4L2_STD_PAL_N, "PAL-N" },
- { V4L2_STD_PAL_Nc, "PAL-Nc" },
- { V4L2_STD_PAL_60, "PAL-60" },
- { V4L2_STD_SECAM, "SECAM" },
- { V4L2_STD_SECAM_B, "SECAM-B" },
- { V4L2_STD_SECAM_G, "SECAM-G" },
- { V4L2_STD_SECAM_H, "SECAM-H" },
- { V4L2_STD_SECAM_DK, "SECAM-DK" },
- { V4L2_STD_SECAM_D, "SECAM-D" },
- { V4L2_STD_SECAM_K, "SECAM-K" },
- { V4L2_STD_SECAM_K1, "SECAM-K1" },
- { V4L2_STD_SECAM_L, "SECAM-L" },
- { V4L2_STD_SECAM_LC, "SECAM-Lc" },
- { 0, "Unknown" }
-};
-
-/* video4linux standard ID conversion to standard name
- */
-const char *v4l2_norm_to_name(v4l2_std_id id)
-{
- u32 myid = id;
- int i;
-
- /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
- 64 bit comparations. So, on that architecture, with some gcc
- variants, compilation fails. Currently, the max value is 30bit wide.
- */
- BUG_ON(myid != id);
-
- for (i = 0; standards[i].std; i++)
- if (myid == standards[i].std)
- break;
- return standards[i].descr;
-}
-EXPORT_SYMBOL(v4l2_norm_to_name);
-
-/* Fill in the fields of a v4l2_standard structure according to the
- 'id' and 'transmission' parameters. Returns negative on error. */
-int v4l2_video_std_construct(struct v4l2_standard *vs,
- int id, const char *name)
-{
- u32 index = vs->index;
-
- memset(vs, 0, sizeof(struct v4l2_standard));
- vs->index = index;
- vs->id = id;
- if (id & V4L2_STD_525_60) {
- vs->frameperiod.numerator = 1001;
- vs->frameperiod.denominator = 30000;
- vs->framelines = 525;
- } else {
- vs->frameperiod.numerator = 1;
- vs->frameperiod.denominator = 25;
- vs->framelines = 625;
- }
- strlcpy(vs->name, name, sizeof(vs->name));
- return 0;
-}
-EXPORT_SYMBOL(v4l2_video_std_construct);
-
-/* ----------------------------------------------------------------- */
-/* some arrays for pretty-printing debug messages of enum types */
-
-const char *v4l2_field_names[] = {
- [V4L2_FIELD_ANY] = "any",
- [V4L2_FIELD_NONE] = "none",
- [V4L2_FIELD_TOP] = "top",
- [V4L2_FIELD_BOTTOM] = "bottom",
- [V4L2_FIELD_INTERLACED] = "interlaced",
- [V4L2_FIELD_SEQ_TB] = "seq-tb",
- [V4L2_FIELD_SEQ_BT] = "seq-bt",
- [V4L2_FIELD_ALTERNATE] = "alternate",
- [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
- [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
-};
-EXPORT_SYMBOL(v4l2_field_names);
-
-const char *v4l2_type_names[] = {
- [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap",
- [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay",
- [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out",
- [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
- [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
- [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
- [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
- [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
-};
-EXPORT_SYMBOL(v4l2_type_names);
-
-static const char *v4l2_memory_names[] = {
- [V4L2_MEMORY_MMAP] = "mmap",
- [V4L2_MEMORY_USERPTR] = "userptr",
- [V4L2_MEMORY_OVERLAY] = "overlay",
-};
-
-#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
- arr[a] : "unknown")
-
-/* ------------------------------------------------------------------ */
-/* debug help functions */
-
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static const char *v4l1_ioctls[] = {
- [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
- [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
- [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN",
- [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER",
- [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER",
- [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT",
- [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT",
- [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE",
- [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN",
- [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN",
- [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF",
- [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF",
- [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY",
- [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ",
- [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ",
- [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO",
- [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO",
- [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC",
- [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE",
- [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF",
- [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT",
- [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE",
- [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE",
- [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE",
- [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
- [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO",
- [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
- [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT",
- [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"
-};
-#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
-#endif
-
-static const char *v4l2_ioctls[] = {
- [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
- [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
- [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
- [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
- [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
- [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
- [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
- [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
- [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
- [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
- [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
- [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
- [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
- [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
- [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
- [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
- [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
- [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
- [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
- [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
- [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
- [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
- [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
- [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
- [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
- [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
- [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
- [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
- [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
- [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
- [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
- [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
- [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
- [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
- [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
- [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
- [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
- [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
- [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
- [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
- [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
- [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
- [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
- [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
- [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
- [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
- [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
- [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
- [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
- [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
- [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
- [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
- [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
- [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
- [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS",
-#if 1
- [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES",
- [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
- [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX",
- [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
- [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
-
- [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
- [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
-
- [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT",
- [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK",
-#endif
-};
-#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
-
-static const char *v4l2_int_ioctls[] = {
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES",
- [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS",
- [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM",
- [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT",
- [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT",
- [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT",
- [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE",
- [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO",
- [_IOC_NR(DECODER_INIT)] = "DECODER_INIT",
- [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS",
- [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP",
-#endif
- [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO",
-
- [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR",
- [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
- [_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG",
-
- [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE",
- [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET",
- [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
- [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE",
- [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA",
- [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA",
- [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ",
- [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY",
- [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING",
- [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING",
- [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING",
- [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING",
- [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ",
- [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT",
- [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT",
- [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT",
-};
-#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
-
-/* Common ioctl debug function. This function can be used by
- external ioctl messages as well as internal V4L ioctl */
-void v4l_printk_ioctl(unsigned int cmd)
-{
- char *dir, *type;
-
- switch (_IOC_TYPE(cmd)) {
- case 'd':
- if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) {
- type = "v4l2_int";
- break;
- }
- printk("%s", v4l2_int_ioctls[_IOC_NR(cmd)]);
- return;
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- case 'v':
- if (_IOC_NR(cmd) >= V4L1_IOCTLS) {
- type = "v4l1";
- break;
- }
- printk("%s", v4l1_ioctls[_IOC_NR(cmd)]);
- return;
-#endif
- case 'V':
- if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
- type = "v4l2";
- break;
- }
- printk("%s", v4l2_ioctls[_IOC_NR(cmd)]);
- return;
- default:
- type = "unknown";
- }
-
- switch (_IOC_DIR(cmd)) {
- case _IOC_NONE: dir = "--"; break;
- case _IOC_READ: dir = "r-"; break;
- case _IOC_WRITE: dir = "-w"; break;
- case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
- default: dir = "*ERR*"; break;
- }
- printk("%s ioctl '%c', dir=%s, #%d (0x%08x)",
- type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
-}
-EXPORT_SYMBOL(v4l_printk_ioctl);
-
-/*
- * sysfs stuff
- */
-
-static ssize_t show_index(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vfd = container_of(cd, struct video_device,
- class_dev);
- return sprintf(buf, "%i\n", vfd->index);
-}
-
-static ssize_t show_name(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct video_device *vfd = container_of(cd, struct video_device,
- class_dev);
- return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name);
-}
-
-static struct device_attribute video_device_attrs[] = {
- __ATTR(name, S_IRUGO, show_name, NULL),
- __ATTR(index, S_IRUGO, show_index, NULL),
- __ATTR_NULL
-};
-
-struct video_device *video_device_alloc(void)
-{
- struct video_device *vfd;
-
- vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
- return vfd;
-}
-EXPORT_SYMBOL(video_device_alloc);
-
-void video_device_release(struct video_device *vfd)
-{
- kfree(vfd);
-}
-EXPORT_SYMBOL(video_device_release);
-
-static void video_release(struct device *cd)
-{
- struct video_device *vfd = container_of(cd, struct video_device,
- class_dev);
-
-#if 1
- /* needed until all drivers are fixed */
- if (!vfd->release)
- return;
-#endif
- vfd->release(vfd);
-}
-
-static struct class video_class = {
- .name = VIDEO_NAME,
- .dev_attrs = video_device_attrs,
- .dev_release = video_release,
-};
-
-/*
- * Active devices
- */
-
-static struct video_device *video_device[VIDEO_NUM_DEVICES];
-static DEFINE_MUTEX(videodev_lock);
-
-struct video_device* video_devdata(struct file *file)
-{
- return video_device[iminor(file->f_path.dentry->d_inode)];
-}
-EXPORT_SYMBOL(video_devdata);
-
-/*
- * Open a video device - FIXME: Obsoleted
- */
-static int video_open(struct inode *inode, struct file *file)
-{
- unsigned int minor = iminor(inode);
- int err = 0;
- struct video_device *vfl;
- const struct file_operations *old_fops;
-
- if(minor>=VIDEO_NUM_DEVICES)
- return -ENODEV;
- lock_kernel();
- mutex_lock(&videodev_lock);
- vfl=video_device[minor];
- if(vfl==NULL) {
- mutex_unlock(&videodev_lock);
- request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
- mutex_lock(&videodev_lock);
- vfl=video_device[minor];
- if (vfl==NULL) {
- mutex_unlock(&videodev_lock);
- unlock_kernel();
- return -ENODEV;
- }
- }
- old_fops = file->f_op;
- file->f_op = fops_get(vfl->fops);
- if(file->f_op->open)
- err = file->f_op->open(inode,file);
- if (err) {
- fops_put(file->f_op);
- file->f_op = fops_get(old_fops);
- }
- fops_put(old_fops);
- mutex_unlock(&videodev_lock);
- unlock_kernel();
- return err;
-}
-
-/*
- * helper function -- handles userspace copying for ioctl arguments
- */
-
-#ifdef __OLD_VIDIOC_
-static unsigned int
-video_fix_command(unsigned int cmd)
-{
- switch (cmd) {
- case VIDIOC_OVERLAY_OLD:
- cmd = VIDIOC_OVERLAY;
- break;
- case VIDIOC_S_PARM_OLD:
- cmd = VIDIOC_S_PARM;
- break;
- case VIDIOC_S_CTRL_OLD:
- cmd = VIDIOC_S_CTRL;
- break;
- case VIDIOC_G_AUDIO_OLD:
- cmd = VIDIOC_G_AUDIO;
- break;
- case VIDIOC_G_AUDOUT_OLD:
- cmd = VIDIOC_G_AUDOUT;
- break;
- case VIDIOC_CROPCAP_OLD:
- cmd = VIDIOC_CROPCAP;
- break;
- }
- return cmd;
-}
-#endif
-
-/*
- * Obsolete usercopy function - Should be removed soon
- */
-int
-video_usercopy(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- int (*func)(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg))
-{
- char sbuf[128];
- void *mbuf = NULL;
- void *parg = NULL;
- int err = -EINVAL;
- int is_ext_ctrl;
- size_t ctrls_size = 0;
- void __user *user_ptr = NULL;
-
-#ifdef __OLD_VIDIOC_
- cmd = video_fix_command(cmd);
-#endif
- is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
- cmd == VIDIOC_TRY_EXT_CTRLS);
-
- /* Copy arguments into temp kernel buffer */
- switch (_IOC_DIR(cmd)) {
- case _IOC_NONE:
- parg = NULL;
- break;
- case _IOC_READ:
- case _IOC_WRITE:
- case (_IOC_WRITE | _IOC_READ):
- if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
- parg = sbuf;
- } else {
- /* too big to allocate from stack */
- mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
- if (NULL == mbuf)
- return -ENOMEM;
- parg = mbuf;
- }
-
- err = -EFAULT;
- if (_IOC_DIR(cmd) & _IOC_WRITE)
- if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
- goto out;
- break;
- }
- if (is_ext_ctrl) {
- struct v4l2_ext_controls *p = parg;
-
- /* In case of an error, tell the caller that it wasn't
- a specific control that caused it. */
- p->error_idx = p->count;
- user_ptr = (void __user *)p->controls;
- if (p->count) {
- ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
- /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
- mbuf = kmalloc(ctrls_size, GFP_KERNEL);
- err = -ENOMEM;
- if (NULL == mbuf)
- goto out_ext_ctrl;
- err = -EFAULT;
- if (copy_from_user(mbuf, user_ptr, ctrls_size))
- goto out_ext_ctrl;
- p->controls = mbuf;
- }
- }
-
- /* call driver */
- err = func(inode, file, cmd, parg);
- if (err == -ENOIOCTLCMD)
- err = -EINVAL;
- if (is_ext_ctrl) {
- struct v4l2_ext_controls *p = parg;
-
- p->controls = (void *)user_ptr;
- if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
- err = -EFAULT;
- goto out_ext_ctrl;
- }
- if (err < 0)
- goto out;
-
-out_ext_ctrl:
- /* Copy results into user buffer */
- switch (_IOC_DIR(cmd))
- {
- case _IOC_READ:
- case (_IOC_WRITE | _IOC_READ):
- if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
- err = -EFAULT;
- break;
- }
-
-out:
- kfree(mbuf);
- return err;
-}
-EXPORT_SYMBOL(video_usercopy);
-
-/*
- * open/release helper functions -- handle exclusive opens
- * Should be removed soon
- */
-int video_exclusive_open(struct inode *inode, struct file *file)
-{
- struct video_device *vfl = video_devdata(file);
- int retval = 0;
-
- mutex_lock(&vfl->lock);
- if (vfl->users) {
- retval = -EBUSY;
- } else {
- vfl->users++;
- }
- mutex_unlock(&vfl->lock);
- return retval;
-}
-EXPORT_SYMBOL(video_exclusive_open);
-
-int video_exclusive_release(struct inode *inode, struct file *file)
-{
- struct video_device *vfl = video_devdata(file);
-
- vfl->users--;
- return 0;
-}
-EXPORT_SYMBOL(video_exclusive_release);
-
-static void dbgbuf(unsigned int cmd, struct video_device *vfd,
- struct v4l2_buffer *p)
-{
- struct v4l2_timecode *tc=&p->timecode;
-
- dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
- "bytesused=%d, flags=0x%08d, "
- "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
- (p->timestamp.tv_sec/3600),
- (int)(p->timestamp.tv_sec/60)%60,
- (int)(p->timestamp.tv_sec%60),
- p->timestamp.tv_usec,
- p->index,
- prt_names(p->type, v4l2_type_names),
- p->bytesused, p->flags,
- p->field, p->sequence,
- prt_names(p->memory, v4l2_memory_names),
- p->m.userptr, p->length);
- dbgarg2("timecode=%02d:%02d:%02d type=%d, "
- "flags=0x%08d, frames=%d, userbits=0x%08x\n",
- tc->hours,tc->minutes,tc->seconds,
- tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
-}
-
-static inline void dbgrect(struct video_device *vfd, char *s,
- struct v4l2_rect *r)
-{
- dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top,
- r->width, r->height);
-};
-
-static inline void v4l_print_pix_fmt (struct video_device *vfd,
- struct v4l2_pix_format *fmt)
-{
- dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, "
- "bytesperline=%d sizeimage=%d, colorspace=%d\n",
- fmt->width,fmt->height,
- (fmt->pixelformat & 0xff),
- (fmt->pixelformat >> 8) & 0xff,
- (fmt->pixelformat >> 16) & 0xff,
- (fmt->pixelformat >> 24) & 0xff,
- prt_names(fmt->field, v4l2_field_names),
- fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
-};
-
-static inline void v4l_print_ext_ctrls(unsigned int cmd,
- struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals)
-{
- __u32 i;
-
- if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG))
- return;
- dbgarg(cmd, "");
- printk(KERN_CONT "class=0x%x", c->ctrl_class);
- for (i = 0; i < c->count; i++) {
- if (show_vals)
- printk(KERN_CONT " id/val=0x%x/0x%x",
- c->controls[i].id, c->controls[i].value);
- else
- printk(KERN_CONT " id=0x%x", c->controls[i].id);
- }
- printk(KERN_CONT "\n");
-};
-
-static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
-{
- __u32 i;
-
- /* zero the reserved fields */
- c->reserved[0] = c->reserved[1] = 0;
- for (i = 0; i < c->count; i++) {
- c->controls[i].reserved2[0] = 0;
- c->controls[i].reserved2[1] = 0;
- }
- /* V4L2_CID_PRIVATE_BASE cannot be used as control class
- when using extended controls.
- Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
- is it allowed for backwards compatibility.
- */
- if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
- return 0;
- /* Check that all controls are from the same control class. */
- for (i = 0; i < c->count; i++) {
- if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) {
- c->error_idx = i;
- return 0;
- }
- }
- return 1;
-}
-
-static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
-{
- switch (type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (vfd->vidioc_try_fmt_vid_cap)
- return (0);
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (vfd->vidioc_try_fmt_vid_overlay)
- return (0);
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (vfd->vidioc_try_fmt_vid_out)
- return (0);
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (vfd->vidioc_try_fmt_vid_out_overlay)
- return (0);
- break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (vfd->vidioc_try_fmt_vbi_cap)
- return (0);
- break;
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (vfd->vidioc_try_fmt_vbi_out)
- return (0);
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (vfd->vidioc_try_fmt_sliced_vbi_cap)
- return (0);
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (vfd->vidioc_try_fmt_sliced_vbi_out)
- return (0);
- break;
- case V4L2_BUF_TYPE_PRIVATE:
- if (vfd->vidioc_try_fmt_type_private)
- return (0);
- break;
- }
- return (-EINVAL);
-}
-
-static int __video_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- void *fh = file->private_data;
- int ret = -EINVAL;
-
- if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
- !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
- v4l_print_ioctl(vfd->name, cmd);
- printk("\n");
- }
-
-#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 ------------------------------------------ */
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *cap = (struct v4l2_capability*)arg;
- memset(cap, 0, sizeof(*cap));
-
- if (!vfd->vidioc_querycap)
- break;
-
- ret=vfd->vidioc_querycap(file, fh, cap);
- if (!ret)
- dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
- "version=0x%08x, "
- "capabilities=0x%08x\n",
- cap->driver,cap->card,cap->bus_info,
- cap->version,
- cap->capabilities);
- break;
- }
-
- /* --- priority ------------------------------------------ */
- case VIDIOC_G_PRIORITY:
- {
- enum v4l2_priority *p=arg;
-
- if (!vfd->vidioc_g_priority)
- break;
- ret=vfd->vidioc_g_priority(file, fh, p);
- if (!ret)
- dbgarg(cmd, "priority is %d\n", *p);
- break;
- }
- case VIDIOC_S_PRIORITY:
- {
- enum v4l2_priority *p=arg;
-
- if (!vfd->vidioc_s_priority)
- break;
- dbgarg(cmd, "setting priority to %d\n", *p);
- ret=vfd->vidioc_s_priority(file, fh, *p);
- break;
- }
-
- /* --- capture ioctls ---------------------------------------- */
- case VIDIOC_ENUM_FMT:
- {
- struct v4l2_fmtdesc *f = arg;
- enum v4l2_buf_type type;
- unsigned int index;
-
- index = f->index;
- type = f->type;
- memset(f,0,sizeof(*f));
- f->index = index;
- f->type = type;
-
- switch (type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (vfd->vidioc_enum_fmt_vid_cap)
- ret = vfd->vidioc_enum_fmt_vid_cap(file, fh, f);
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (vfd->vidioc_enum_fmt_vid_overlay)
- ret = vfd->vidioc_enum_fmt_vid_overlay(file,
- fh, f);
- break;
-#if 1
- /* V4L2_BUF_TYPE_VBI_CAPTURE should not support VIDIOC_ENUM_FMT
- * according to the spec. The bttv and saa7134 drivers support
- * it though, so just warn that this is deprecated and will be
- * removed in the near future. */
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (vfd->vidioc_enum_fmt_vbi_cap) {
- printk(KERN_WARNING "vidioc_enum_fmt_vbi_cap will be removed in 2.6.28!\n");
- ret = vfd->vidioc_enum_fmt_vbi_cap(file, fh, f);
- }
- break;
-#endif
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (vfd->vidioc_enum_fmt_vid_out)
- ret = vfd->vidioc_enum_fmt_vid_out(file, fh, f);
- break;
- case V4L2_BUF_TYPE_PRIVATE:
- if (vfd->vidioc_enum_fmt_type_private)
- ret = vfd->vidioc_enum_fmt_type_private(file,
- fh, f);
- break;
- default:
- break;
- }
- if (!ret)
- dbgarg (cmd, "index=%d, type=%d, flags=%d, "
- "pixelformat=%c%c%c%c, description='%s'\n",
- f->index, f->type, f->flags,
- (f->pixelformat & 0xff),
- (f->pixelformat >> 8) & 0xff,
- (f->pixelformat >> 16) & 0xff,
- (f->pixelformat >> 24) & 0xff,
- f->description);
- break;
- }
- case VIDIOC_G_FMT:
- {
- struct v4l2_format *f = (struct v4l2_format *)arg;
-
- memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data));
-
- /* FIXME: Should be one dump per type */
- dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (vfd->vidioc_g_fmt_vid_cap)
- ret = vfd->vidioc_g_fmt_vid_cap(file, fh, f);
- if (!ret)
- v4l_print_pix_fmt(vfd, &f->fmt.pix);
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (vfd->vidioc_g_fmt_vid_overlay)
- ret = vfd->vidioc_g_fmt_vid_overlay(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (vfd->vidioc_g_fmt_vid_out)
- ret = vfd->vidioc_g_fmt_vid_out(file, fh, f);
- if (!ret)
- v4l_print_pix_fmt(vfd, &f->fmt.pix);
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (vfd->vidioc_g_fmt_vid_out_overlay)
- ret = vfd->vidioc_g_fmt_vid_out_overlay(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (vfd->vidioc_g_fmt_vbi_cap)
- ret = vfd->vidioc_g_fmt_vbi_cap(file, fh, f);
- break;
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (vfd->vidioc_g_fmt_vbi_out)
- ret = vfd->vidioc_g_fmt_vbi_out(file, fh, f);
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (vfd->vidioc_g_fmt_sliced_vbi_cap)
- ret = vfd->vidioc_g_fmt_sliced_vbi_cap(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (vfd->vidioc_g_fmt_sliced_vbi_out)
- ret = vfd->vidioc_g_fmt_sliced_vbi_out(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_PRIVATE:
- if (vfd->vidioc_g_fmt_type_private)
- ret = vfd->vidioc_g_fmt_type_private(file,
- fh, f);
- break;
- }
-
- break;
- }
- case VIDIOC_S_FMT:
- {
- struct v4l2_format *f = (struct v4l2_format *)arg;
-
- /* FIXME: Should be one dump per type */
- dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- v4l_print_pix_fmt(vfd, &f->fmt.pix);
- if (vfd->vidioc_s_fmt_vid_cap)
- ret = vfd->vidioc_s_fmt_vid_cap(file, fh, f);
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (vfd->vidioc_s_fmt_vid_overlay)
- ret = vfd->vidioc_s_fmt_vid_overlay(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- v4l_print_pix_fmt(vfd, &f->fmt.pix);
- if (vfd->vidioc_s_fmt_vid_out)
- ret = vfd->vidioc_s_fmt_vid_out(file, fh, f);
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (vfd->vidioc_s_fmt_vid_out_overlay)
- ret = vfd->vidioc_s_fmt_vid_out_overlay(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (vfd->vidioc_s_fmt_vbi_cap)
- ret = vfd->vidioc_s_fmt_vbi_cap(file, fh, f);
- break;
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (vfd->vidioc_s_fmt_vbi_out)
- ret = vfd->vidioc_s_fmt_vbi_out(file, fh, f);
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (vfd->vidioc_s_fmt_sliced_vbi_cap)
- ret = vfd->vidioc_s_fmt_sliced_vbi_cap(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (vfd->vidioc_s_fmt_sliced_vbi_out)
- ret = vfd->vidioc_s_fmt_sliced_vbi_out(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_PRIVATE:
- if (vfd->vidioc_s_fmt_type_private)
- ret = vfd->vidioc_s_fmt_type_private(file,
- fh, f);
- break;
- }
- break;
- }
- case VIDIOC_TRY_FMT:
- {
- struct v4l2_format *f = (struct v4l2_format *)arg;
-
- /* FIXME: Should be one dump per type */
- dbgarg (cmd, "type=%s\n", prt_names(f->type,
- v4l2_type_names));
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (vfd->vidioc_try_fmt_vid_cap)
- ret = vfd->vidioc_try_fmt_vid_cap(file, fh, f);
- if (!ret)
- v4l_print_pix_fmt(vfd, &f->fmt.pix);
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (vfd->vidioc_try_fmt_vid_overlay)
- ret = vfd->vidioc_try_fmt_vid_overlay(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (vfd->vidioc_try_fmt_vid_out)
- ret = vfd->vidioc_try_fmt_vid_out(file, fh, f);
- if (!ret)
- v4l_print_pix_fmt(vfd, &f->fmt.pix);
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (vfd->vidioc_try_fmt_vid_out_overlay)
- ret = vfd->vidioc_try_fmt_vid_out_overlay(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (vfd->vidioc_try_fmt_vbi_cap)
- ret = vfd->vidioc_try_fmt_vbi_cap(file, fh, f);
- break;
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (vfd->vidioc_try_fmt_vbi_out)
- ret = vfd->vidioc_try_fmt_vbi_out(file, fh, f);
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (vfd->vidioc_try_fmt_sliced_vbi_cap)
- ret = vfd->vidioc_try_fmt_sliced_vbi_cap(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (vfd->vidioc_try_fmt_sliced_vbi_out)
- ret = vfd->vidioc_try_fmt_sliced_vbi_out(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_PRIVATE:
- if (vfd->vidioc_try_fmt_type_private)
- ret = vfd->vidioc_try_fmt_type_private(file,
- fh, f);
- break;
- }
-
- break;
- }
- /* FIXME: Those buf reqs could be handled here,
- with some changes on videobuf to allow its header to be included at
- videodev2.h or being merged at videodev2.
- */
- case VIDIOC_REQBUFS:
- {
- struct v4l2_requestbuffers *p=arg;
-
- if (!vfd->vidioc_reqbufs)
- break;
- ret = check_fmt (vfd, p->type);
- if (ret)
- break;
-
- ret=vfd->vidioc_reqbufs(file, fh, p);
- dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
- p->count,
- prt_names(p->type, v4l2_type_names),
- prt_names(p->memory, v4l2_memory_names));
- break;
- }
- case VIDIOC_QUERYBUF:
- {
- struct v4l2_buffer *p=arg;
-
- if (!vfd->vidioc_querybuf)
- break;
- ret = check_fmt (vfd, p->type);
- if (ret)
- break;
-
- ret=vfd->vidioc_querybuf(file, fh, p);
- if (!ret)
- dbgbuf(cmd,vfd,p);
- break;
- }
- case VIDIOC_QBUF:
- {
- struct v4l2_buffer *p=arg;
-
- if (!vfd->vidioc_qbuf)
- break;
- ret = check_fmt (vfd, p->type);
- if (ret)
- break;
-
- ret=vfd->vidioc_qbuf(file, fh, p);
- if (!ret)
- dbgbuf(cmd,vfd,p);
- break;
- }
- case VIDIOC_DQBUF:
- {
- struct v4l2_buffer *p=arg;
- if (!vfd->vidioc_dqbuf)
- break;
- ret = check_fmt (vfd, p->type);
- if (ret)
- break;
-
- ret=vfd->vidioc_dqbuf(file, fh, p);
- if (!ret)
- dbgbuf(cmd,vfd,p);
- break;
- }
- case VIDIOC_OVERLAY:
- {
- int *i = arg;
-
- if (!vfd->vidioc_overlay)
- break;
- dbgarg (cmd, "value=%d\n",*i);
- ret=vfd->vidioc_overlay(file, fh, *i);
- break;
- }
- case VIDIOC_G_FBUF:
- {
- struct v4l2_framebuffer *p = arg;
-
- if (!vfd->vidioc_g_fbuf)
- break;
- ret = vfd->vidioc_g_fbuf(file, fh, arg);
- if (!ret) {
- dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
- p->capability, p->flags,
- (unsigned long)p->base);
- v4l_print_pix_fmt(vfd, &p->fmt);
- }
- break;
- }
- case VIDIOC_S_FBUF:
- {
- struct v4l2_framebuffer *p = arg;
-
- if (!vfd->vidioc_s_fbuf)
- break;
- dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
- p->capability, p->flags, (unsigned long)p->base);
- v4l_print_pix_fmt(vfd, &p->fmt);
- ret = vfd->vidioc_s_fbuf(file, fh, arg);
- break;
- }
- case VIDIOC_STREAMON:
- {
- enum v4l2_buf_type i = *(int *)arg;
- if (!vfd->vidioc_streamon)
- break;
- dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
- ret=vfd->vidioc_streamon(file, fh,i);
- break;
- }
- case VIDIOC_STREAMOFF:
- {
- enum v4l2_buf_type i = *(int *)arg;
-
- if (!vfd->vidioc_streamoff)
- break;
- dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
- ret=vfd->vidioc_streamoff(file, fh, i);
- break;
- }
- /* ---------- tv norms ---------- */
- case VIDIOC_ENUMSTD:
- {
- struct v4l2_standard *p = arg;
- v4l2_std_id id = vfd->tvnorms, curr_id = 0;
- unsigned int index = p->index, i, j = 0;
- const char *descr = "";
-
- /* Return norm array in a canonical way */
- for (i = 0; i <= index && id; i++) {
- /* last std value in the standards array is 0, so this
- while always ends there since (id & 0) == 0. */
- while ((id & standards[j].std) != standards[j].std)
- j++;
- curr_id = standards[j].std;
- descr = standards[j].descr;
- j++;
- if (curr_id == 0)
- break;
- if (curr_id != V4L2_STD_PAL &&
- curr_id != V4L2_STD_SECAM &&
- curr_id != V4L2_STD_NTSC)
- id &= ~curr_id;
- }
- if (i <= index)
- return -EINVAL;
-
- v4l2_video_std_construct(p, curr_id, descr);
- p->index = index;
-
- dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
- "framelines=%d\n", p->index,
- (unsigned long long)p->id, p->name,
- p->frameperiod.numerator,
- p->frameperiod.denominator,
- p->framelines);
-
- ret = 0;
- break;
- }
- case VIDIOC_G_STD:
- {
- v4l2_std_id *id = arg;
-
- ret = 0;
- /* Calls the specific handler */
- if (vfd->vidioc_g_std)
- ret = vfd->vidioc_g_std(file, fh, id);
- else
- *id = vfd->current_norm;
-
- if (!ret)
- dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
- break;
- }
- case VIDIOC_S_STD:
- {
- v4l2_std_id *id = arg,norm;
-
- dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id);
-
- norm = (*id) & vfd->tvnorms;
- if ( vfd->tvnorms && !norm) /* Check if std is supported */
- break;
-
- /* Calls the specific handler */
- if (vfd->vidioc_s_std)
- ret=vfd->vidioc_s_std(file, fh, &norm);
- else
- ret=-EINVAL;
-
- /* Updates standard information */
- if (ret>=0)
- vfd->current_norm=norm;
-
- break;
- }
- case VIDIOC_QUERYSTD:
- {
- v4l2_std_id *p=arg;
-
- if (!vfd->vidioc_querystd)
- break;
- ret=vfd->vidioc_querystd(file, fh, arg);
- if (!ret)
- dbgarg (cmd, "detected std=%08Lx\n",
- (unsigned long long)*p);
- break;
- }
- /* ------ input switching ---------- */
- /* FIXME: Inputs can be handled inside videodev2 */
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *p=arg;
- int i=p->index;
-
- if (!vfd->vidioc_enum_input)
- break;
- memset(p, 0, sizeof(*p));
- p->index=i;
-
- ret=vfd->vidioc_enum_input(file, fh, p);
- if (!ret)
- dbgarg (cmd, "index=%d, name=%s, type=%d, "
- "audioset=%d, "
- "tuner=%d, std=%08Lx, status=%d\n",
- p->index,p->name,p->type,p->audioset,
- p->tuner,
- (unsigned long long)p->std,
- p->status);
- break;
- }
- case VIDIOC_G_INPUT:
- {
- unsigned int *i = arg;
-
- if (!vfd->vidioc_g_input)
- break;
- ret=vfd->vidioc_g_input(file, fh, i);
- if (!ret)
- dbgarg (cmd, "value=%d\n",*i);
- break;
- }
- case VIDIOC_S_INPUT:
- {
- unsigned int *i = arg;
-
- if (!vfd->vidioc_s_input)
- break;
- dbgarg (cmd, "value=%d\n",*i);
- ret=vfd->vidioc_s_input(file, fh, *i);
- break;
- }
-
- /* ------ output switching ---------- */
- case VIDIOC_ENUMOUTPUT:
- {
- struct v4l2_output *p = arg;
- int i = p->index;
-
- if (!vfd->vidioc_enum_output)
- break;
- memset(p, 0, sizeof(*p));
- p->index = i;
-
- ret = vfd->vidioc_enum_output(file, fh, p);
- if (!ret)
- dbgarg(cmd, "index=%d, name=%s, type=%d, "
- "audioset=0x%x, "
- "modulator=%d, std=0x%08Lx\n",
- p->index, p->name, p->type, p->audioset,
- p->modulator, (unsigned long long)p->std);
- break;
- }
- case VIDIOC_G_OUTPUT:
- {
- unsigned int *i = arg;
-
- if (!vfd->vidioc_g_output)
- break;
- ret=vfd->vidioc_g_output(file, fh, i);
- if (!ret)
- dbgarg (cmd, "value=%d\n",*i);
- break;
- }
- case VIDIOC_S_OUTPUT:
- {
- unsigned int *i = arg;
-
- if (!vfd->vidioc_s_output)
- break;
- dbgarg (cmd, "value=%d\n",*i);
- ret=vfd->vidioc_s_output(file, fh, *i);
- break;
- }
-
- /* --- controls ---------------------------------------------- */
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *p = arg;
-
- if (!vfd->vidioc_queryctrl)
- break;
- ret = vfd->vidioc_queryctrl(file, fh, p);
- if (!ret)
- dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, "
- "step=%d, default=%d, flags=0x%08x\n",
- p->id, p->type, p->name,
- p->minimum, p->maximum,
- p->step, p->default_value, p->flags);
- else
- dbgarg(cmd, "id=0x%x\n", p->id);
- break;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *p = arg;
-
- if (vfd->vidioc_g_ctrl)
- ret = vfd->vidioc_g_ctrl(file, fh, p);
- else if (vfd->vidioc_g_ext_ctrls) {
- struct v4l2_ext_controls ctrls;
- struct v4l2_ext_control ctrl;
-
- ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
- ctrls.count = 1;
- ctrls.controls = &ctrl;
- ctrl.id = p->id;
- ctrl.value = p->value;
- if (check_ext_ctrls(&ctrls, 1)) {
- ret = vfd->vidioc_g_ext_ctrls(file, fh, &ctrls);
- if (ret == 0)
- p->value = ctrl.value;
- }
- } else
- break;
- if (!ret)
- dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
- else
- dbgarg(cmd, "id=0x%x\n", p->id);
- break;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *p = arg;
- struct v4l2_ext_controls ctrls;
- struct v4l2_ext_control ctrl;
-
- if (!vfd->vidioc_s_ctrl && !vfd->vidioc_s_ext_ctrls)
- break;
-
- dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
-
- if (vfd->vidioc_s_ctrl) {
- ret = vfd->vidioc_s_ctrl(file, fh, p);
- break;
- }
- if (!vfd->vidioc_s_ext_ctrls)
- break;
-
- ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
- ctrls.count = 1;
- ctrls.controls = &ctrl;
- ctrl.id = p->id;
- ctrl.value = p->value;
- if (check_ext_ctrls(&ctrls, 1))
- ret = vfd->vidioc_s_ext_ctrls(file, fh, &ctrls);
- break;
- }
- case VIDIOC_G_EXT_CTRLS:
- {
- struct v4l2_ext_controls *p = arg;
-
- p->error_idx = p->count;
- if (!vfd->vidioc_g_ext_ctrls)
- break;
- if (check_ext_ctrls(p, 0))
- ret = vfd->vidioc_g_ext_ctrls(file, fh, p);
- v4l_print_ext_ctrls(cmd, vfd, p, !ret);
- break;
- }
- case VIDIOC_S_EXT_CTRLS:
- {
- struct v4l2_ext_controls *p = arg;
-
- p->error_idx = p->count;
- if (!vfd->vidioc_s_ext_ctrls)
- break;
- v4l_print_ext_ctrls(cmd, vfd, p, 1);
- if (check_ext_ctrls(p, 0))
- ret = vfd->vidioc_s_ext_ctrls(file, fh, p);
- break;
- }
- case VIDIOC_TRY_EXT_CTRLS:
- {
- struct v4l2_ext_controls *p = arg;
-
- p->error_idx = p->count;
- if (!vfd->vidioc_try_ext_ctrls)
- break;
- v4l_print_ext_ctrls(cmd, vfd, p, 1);
- if (check_ext_ctrls(p, 0))
- ret = vfd->vidioc_try_ext_ctrls(file, fh, p);
- break;
- }
- case VIDIOC_QUERYMENU:
- {
- struct v4l2_querymenu *p = arg;
-
- if (!vfd->vidioc_querymenu)
- break;
- ret = vfd->vidioc_querymenu(file, fh, p);
- if (!ret)
- dbgarg(cmd, "id=0x%x, index=%d, name=%s\n",
- p->id, p->index, p->name);
- else
- dbgarg(cmd, "id=0x%x, index=%d\n",
- p->id, p->index);
- break;
- }
- /* --- audio ---------------------------------------------- */
- case VIDIOC_ENUMAUDIO:
- {
- struct v4l2_audio *p = arg;
-
- if (!vfd->vidioc_enumaudio)
- break;
- ret = vfd->vidioc_enumaudio(file, fh, p);
- if (!ret)
- dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
- "mode=0x%x\n", p->index, p->name,
- p->capability, p->mode);
- else
- dbgarg(cmd, "index=%d\n", p->index);
- break;
- }
- case VIDIOC_G_AUDIO:
- {
- struct v4l2_audio *p = arg;
- __u32 index = p->index;
-
- if (!vfd->vidioc_g_audio)
- break;
-
- memset(p, 0, sizeof(*p));
- p->index = index;
- ret = vfd->vidioc_g_audio(file, fh, p);
- if (!ret)
- dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
- "mode=0x%x\n", p->index,
- p->name, p->capability, p->mode);
- else
- dbgarg(cmd, "index=%d\n", p->index);
- break;
- }
- case VIDIOC_S_AUDIO:
- {
- struct v4l2_audio *p = arg;
-
- if (!vfd->vidioc_s_audio)
- break;
- dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
- "mode=0x%x\n", p->index, p->name,
- p->capability, p->mode);
- ret = vfd->vidioc_s_audio(file, fh, p);
- break;
- }
- case VIDIOC_ENUMAUDOUT:
- {
- struct v4l2_audioout *p=arg;
-
- if (!vfd->vidioc_enumaudout)
- break;
- dbgarg(cmd, "Enum for index=%d\n", p->index);
- ret=vfd->vidioc_enumaudout(file, fh, p);
- if (!ret)
- dbgarg2("index=%d, name=%s, capability=%d, "
- "mode=%d\n", p->index, p->name,
- p->capability,p->mode);
- break;
- }
- case VIDIOC_G_AUDOUT:
- {
- struct v4l2_audioout *p=arg;
-
- if (!vfd->vidioc_g_audout)
- break;
- dbgarg(cmd, "Enum for index=%d\n", p->index);
- ret=vfd->vidioc_g_audout(file, fh, p);
- if (!ret)
- dbgarg2("index=%d, name=%s, capability=%d, "
- "mode=%d\n", p->index, p->name,
- p->capability,p->mode);
- break;
- }
- case VIDIOC_S_AUDOUT:
- {
- struct v4l2_audioout *p=arg;
-
- if (!vfd->vidioc_s_audout)
- break;
- dbgarg(cmd, "index=%d, name=%s, capability=%d, "
- "mode=%d\n", p->index, p->name,
- p->capability,p->mode);
-
- ret=vfd->vidioc_s_audout(file, fh, p);
- break;
- }
- case VIDIOC_G_MODULATOR:
- {
- struct v4l2_modulator *p=arg;
- if (!vfd->vidioc_g_modulator)
- break;
- ret=vfd->vidioc_g_modulator(file, fh, p);
- if (!ret)
- dbgarg(cmd, "index=%d, name=%s, "
- "capability=%d, rangelow=%d,"
- " rangehigh=%d, txsubchans=%d\n",
- p->index, p->name,p->capability,
- p->rangelow, p->rangehigh,
- p->txsubchans);
- break;
- }
- case VIDIOC_S_MODULATOR:
- {
- struct v4l2_modulator *p=arg;
- if (!vfd->vidioc_s_modulator)
- break;
- dbgarg(cmd, "index=%d, name=%s, capability=%d, "
- "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
- p->index, p->name,p->capability,p->rangelow,
- p->rangehigh,p->txsubchans);
- ret=vfd->vidioc_s_modulator(file, fh, p);
- break;
- }
- case VIDIOC_G_CROP:
- {
- struct v4l2_crop *p=arg;
- if (!vfd->vidioc_g_crop)
- break;
- dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
- ret=vfd->vidioc_g_crop(file, fh, p);
- if (!ret) {
- dbgrect(vfd, "", &p->c);
- }
- break;
- }
- case VIDIOC_S_CROP:
- {
- struct v4l2_crop *p=arg;
- if (!vfd->vidioc_s_crop)
- break;
- dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
- dbgrect(vfd, "", &p->c);
- ret=vfd->vidioc_s_crop(file, fh, p);
- break;
- }
- case VIDIOC_CROPCAP:
- {
- struct v4l2_cropcap *p = arg;
-
- /*FIXME: Should also show v4l2_fract pixelaspect */
- if (!vfd->vidioc_cropcap)
- break;
- dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
- ret = vfd->vidioc_cropcap(file, fh, p);
- if (!ret) {
- dbgrect(vfd, "bounds ", &p->bounds);
- dbgrect(vfd, "defrect ", &p->defrect);
- }
- break;
- }
- case VIDIOC_G_JPEGCOMP:
- {
- struct v4l2_jpegcompression *p=arg;
- if (!vfd->vidioc_g_jpegcomp)
- break;
- ret=vfd->vidioc_g_jpegcomp(file, fh, p);
- if (!ret)
- dbgarg (cmd, "quality=%d, APPn=%d, "
- "APP_len=%d, COM_len=%d, "
- "jpeg_markers=%d\n",
- p->quality,p->APPn,p->APP_len,
- p->COM_len,p->jpeg_markers);
- break;
- }
- case VIDIOC_S_JPEGCOMP:
- {
- struct v4l2_jpegcompression *p=arg;
- if (!vfd->vidioc_g_jpegcomp)
- break;
- dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
- "COM_len=%d, jpeg_markers=%d\n",
- p->quality,p->APPn,p->APP_len,
- p->COM_len,p->jpeg_markers);
- ret=vfd->vidioc_s_jpegcomp(file, fh, p);
- break;
- }
- case VIDIOC_G_ENC_INDEX:
- {
- struct v4l2_enc_idx *p=arg;
-
- if (!vfd->vidioc_g_enc_index)
- break;
- ret=vfd->vidioc_g_enc_index(file, fh, p);
- if (!ret)
- dbgarg (cmd, "entries=%d, entries_cap=%d\n",
- p->entries,p->entries_cap);
- break;
- }
- case VIDIOC_ENCODER_CMD:
- {
- struct v4l2_encoder_cmd *p = arg;
-
- if (!vfd->vidioc_encoder_cmd)
- break;
- memset(&p->raw, 0, sizeof(p->raw));
- ret = vfd->vidioc_encoder_cmd(file, fh, p);
- if (!ret)
- dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
- break;
- }
- case VIDIOC_TRY_ENCODER_CMD:
- {
- struct v4l2_encoder_cmd *p = arg;
-
- if (!vfd->vidioc_try_encoder_cmd)
- break;
- memset(&p->raw, 0, sizeof(p->raw));
- ret = vfd->vidioc_try_encoder_cmd(file, fh, p);
- if (!ret)
- dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
- break;
- }
- case VIDIOC_G_PARM:
- {
- struct v4l2_streamparm *p=arg;
- __u32 type=p->type;
-
- memset(p,0,sizeof(*p));
- p->type=type;
-
- if (vfd->vidioc_g_parm) {
- ret=vfd->vidioc_g_parm(file, fh, p);
- } else {
- struct v4l2_standard s;
-
- if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- v4l2_video_std_construct(&s, vfd->current_norm,
- v4l2_norm_to_name(vfd->current_norm));
-
- p->parm.capture.timeperframe = s.frameperiod;
- ret=0;
- }
-
- dbgarg (cmd, "type=%d\n", p->type);
- break;
- }
- case VIDIOC_S_PARM:
- {
- struct v4l2_streamparm *p=arg;
- if (!vfd->vidioc_s_parm)
- break;
- dbgarg (cmd, "type=%d\n", p->type);
- ret=vfd->vidioc_s_parm(file, fh, p);
- break;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *p = arg;
- __u32 index = p->index;
-
- if (!vfd->vidioc_g_tuner)
- break;
-
- memset(p, 0, sizeof(*p));
- p->index = index;
-
- ret = vfd->vidioc_g_tuner(file, fh, p);
- if (!ret)
- dbgarg(cmd, "index=%d, name=%s, type=%d, "
- "capability=0x%x, rangelow=%d, "
- "rangehigh=%d, signal=%d, afc=%d, "
- "rxsubchans=0x%x, audmode=%d\n",
- p->index, p->name, p->type,
- p->capability, p->rangelow,
- p->rangehigh, p->signal, p->afc,
- p->rxsubchans, p->audmode);
- break;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *p = arg;
-
- if (!vfd->vidioc_s_tuner)
- break;
- dbgarg(cmd, "index=%d, name=%s, type=%d, "
- "capability=0x%x, rangelow=%d, "
- "rangehigh=%d, signal=%d, afc=%d, "
- "rxsubchans=0x%x, audmode=%d\n",
- p->index, p->name, p->type,
- p->capability, p->rangelow,
- p->rangehigh, p->signal, p->afc,
- p->rxsubchans, p->audmode);
- ret = vfd->vidioc_s_tuner(file, fh, p);
- break;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *p = arg;
-
- if (!vfd->vidioc_g_frequency)
- break;
-
- memset(p->reserved, 0, sizeof(p->reserved));
-
- ret = vfd->vidioc_g_frequency(file, fh, p);
- if (!ret)
- dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
- p->tuner, p->type, p->frequency);
- break;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *p=arg;
- if (!vfd->vidioc_s_frequency)
- break;
- dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
- p->tuner,p->type,p->frequency);
- ret=vfd->vidioc_s_frequency(file, fh, p);
- break;
- }
- case VIDIOC_G_SLICED_VBI_CAP:
- {
- struct v4l2_sliced_vbi_cap *p = arg;
- __u32 type = p->type;
-
- if (!vfd->vidioc_g_sliced_vbi_cap)
- break;
- memset(p, 0, sizeof(*p));
- p->type = type;
- dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
- ret = vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
- if (!ret)
- dbgarg2("service_set=%d\n", p->service_set);
- break;
- }
- case VIDIOC_LOG_STATUS:
- {
- if (!vfd->vidioc_log_status)
- break;
- ret=vfd->vidioc_log_status(file, fh);
- break;
- }
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- case VIDIOC_DBG_G_REGISTER:
- {
- struct v4l2_register *p=arg;
- if (!capable(CAP_SYS_ADMIN))
- ret=-EPERM;
- else if (vfd->vidioc_g_register)
- ret=vfd->vidioc_g_register(file, fh, p);
- break;
- }
- case VIDIOC_DBG_S_REGISTER:
- {
- struct v4l2_register *p=arg;
- if (!capable(CAP_SYS_ADMIN))
- ret=-EPERM;
- else if (vfd->vidioc_s_register)
- ret=vfd->vidioc_s_register(file, fh, p);
- break;
- }
-#endif
- case VIDIOC_G_CHIP_IDENT:
- {
- struct v4l2_chip_ident *p=arg;
- if (!vfd->vidioc_g_chip_ident)
- break;
- ret=vfd->vidioc_g_chip_ident(file, fh, p);
- if (!ret)
- dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
- break;
- }
- default:
- {
- if (!vfd->vidioc_default)
- break;
- ret = vfd->vidioc_default(file, fh, cmd, arg);
- break;
- }
- case VIDIOC_S_HW_FREQ_SEEK:
- {
- struct v4l2_hw_freq_seek *p = arg;
- if (!vfd->vidioc_s_hw_freq_seek)
- break;
- dbgarg(cmd,
- "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n",
- p->tuner, p->type, p->seek_upward, p->wrap_around);
- ret = vfd->vidioc_s_hw_freq_seek(file, fh, p);
- break;
- }
- } /* switch */
-
- if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
- if (ret < 0) {
- v4l_print_ioctl(vfd->name, cmd);
- printk(KERN_CONT " error %d\n", ret);
- }
- }
-
- return ret;
-}
-
-int video_ioctl2 (struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- char sbuf[128];
- void *mbuf = NULL;
- void *parg = NULL;
- int err = -EINVAL;
- int is_ext_ctrl;
- size_t ctrls_size = 0;
- void __user *user_ptr = NULL;
-
-#ifdef __OLD_VIDIOC_
- cmd = video_fix_command(cmd);
-#endif
- is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
- cmd == VIDIOC_TRY_EXT_CTRLS);
-
- /* Copy arguments into temp kernel buffer */
- switch (_IOC_DIR(cmd)) {
- case _IOC_NONE:
- parg = NULL;
- break;
- case _IOC_READ:
- case _IOC_WRITE:
- case (_IOC_WRITE | _IOC_READ):
- if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
- parg = sbuf;
- } else {
- /* too big to allocate from stack */
- mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
- if (NULL == mbuf)
- return -ENOMEM;
- parg = mbuf;
- }
-
- err = -EFAULT;
- if (_IOC_DIR(cmd) & _IOC_WRITE)
- if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
- goto out;
- break;
- }
-
- if (is_ext_ctrl) {
- struct v4l2_ext_controls *p = parg;
-
- /* In case of an error, tell the caller that it wasn't
- a specific control that caused it. */
- p->error_idx = p->count;
- user_ptr = (void __user *)p->controls;
- if (p->count) {
- ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
- /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
- mbuf = kmalloc(ctrls_size, GFP_KERNEL);
- err = -ENOMEM;
- if (NULL == mbuf)
- goto out_ext_ctrl;
- err = -EFAULT;
- if (copy_from_user(mbuf, user_ptr, ctrls_size))
- goto out_ext_ctrl;
- p->controls = mbuf;
- }
- }
-
- /* Handles IOCTL */
- err = __video_do_ioctl(inode, file, cmd, parg);
- if (err == -ENOIOCTLCMD)
- err = -EINVAL;
- if (is_ext_ctrl) {
- struct v4l2_ext_controls *p = parg;
-
- p->controls = (void *)user_ptr;
- if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
- err = -EFAULT;
- goto out_ext_ctrl;
- }
- if (err < 0)
- goto out;
-
-out_ext_ctrl:
- /* Copy results into user buffer */
- switch (_IOC_DIR(cmd))
- {
- case _IOC_READ:
- case (_IOC_WRITE | _IOC_READ):
- if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
- err = -EFAULT;
- break;
- }
-
-out:
- kfree(mbuf);
- return err;
-}
-EXPORT_SYMBOL(video_ioctl2);
-
-/**
- * get_index - assign stream number based on parent device
- * @vdev: video_device to assign index number to, vdev->dev should be assigned
- * @num: -1 if auto assign, requested number otherwise
- *
- *
- * returns -ENFILE if num is already in use, a free index number if
- * successful.
- */
-static int get_index(struct video_device *vdev, int num)
-{
- u32 used = 0;
- const int max_index = sizeof(used) * 8 - 1;
- int i;
-
- /* Currently a single v4l driver instance cannot create more than
- 32 devices.
- Increase to u64 or an array of u32 if more are needed. */
- if (num > max_index) {
- printk(KERN_ERR "videodev: %s num is too large\n", __func__);
- return -EINVAL;
- }
-
- for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
- if (video_device[i] != NULL &&
- video_device[i] != vdev &&
- video_device[i]->dev == vdev->dev) {
- used |= 1 << video_device[i]->index;
- }
- }
-
- if (num >= 0) {
- if (used & (1 << num))
- return -ENFILE;
- return num;
- }
-
- i = ffz(used);
- return i > max_index ? -ENFILE : i;
-}
-
-static const struct file_operations video_fops;
-
-int video_register_device(struct video_device *vfd, int type, int nr)
-{
- return video_register_device_index(vfd, type, nr, -1);
-}
-EXPORT_SYMBOL(video_register_device);
-
-/**
- * video_register_device - register video4linux devices
- * @vfd: video device structure we want to register
- * @type: type of device to register
- * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
- * -1 == first free)
- *
- * The registration code assigns minor numbers based on the type
- * requested. -ENFILE is returned in all the device slots for this
- * category are full. If not then the minor field is set and the
- * driver initialize function is called (if non %NULL).
- *
- * Zero is returned on success.
- *
- * Valid types are
- *
- * %VFL_TYPE_GRABBER - A frame grabber
- *
- * %VFL_TYPE_VTX - A teletext device
- *
- * %VFL_TYPE_VBI - Vertical blank data (undecoded)
- *
- * %VFL_TYPE_RADIO - A radio card
- */
-
-int video_register_device_index(struct video_device *vfd, int type, int nr,
- int index)
-{
- int i=0;
- int base;
- int end;
- int ret;
- char *name_base;
-
- switch(type)
- {
- case VFL_TYPE_GRABBER:
- base=MINOR_VFL_TYPE_GRABBER_MIN;
- end=MINOR_VFL_TYPE_GRABBER_MAX+1;
- name_base = "video";
- break;
- case VFL_TYPE_VTX:
- base=MINOR_VFL_TYPE_VTX_MIN;
- end=MINOR_VFL_TYPE_VTX_MAX+1;
- name_base = "vtx";
- break;
- case VFL_TYPE_VBI:
- base=MINOR_VFL_TYPE_VBI_MIN;
- end=MINOR_VFL_TYPE_VBI_MAX+1;
- name_base = "vbi";
- break;
- case VFL_TYPE_RADIO:
- base=MINOR_VFL_TYPE_RADIO_MIN;
- end=MINOR_VFL_TYPE_RADIO_MAX+1;
- name_base = "radio";
- break;
- default:
- printk(KERN_ERR "%s called with unknown type: %d\n",
- __func__, type);
- return -1;
- }
-
- /* pick a minor number */
- mutex_lock(&videodev_lock);
- if (nr >= 0 && nr < end-base) {
- /* use the one the driver asked for */
- i = base+nr;
- if (NULL != video_device[i]) {
- mutex_unlock(&videodev_lock);
- return -ENFILE;
- }
- } else {
- /* use first free */
- for(i=base;i<end;i++)
- if (NULL == video_device[i])
- break;
- if (i == end) {
- mutex_unlock(&videodev_lock);
- return -ENFILE;
- }
- }
- video_device[i]=vfd;
- vfd->minor=i;
-
- ret = get_index(vfd, index);
- vfd->index = ret;
-
- mutex_unlock(&videodev_lock);
-
- if (ret < 0) {
- printk(KERN_ERR "%s: get_index failed\n", __func__);
- goto fail_minor;
- }
-
- mutex_init(&vfd->lock);
-
- /* sysfs class */
- memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
- vfd->class_dev.class = &video_class;
- vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
- if (vfd->dev)
- vfd->class_dev.parent = vfd->dev;
- sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base);
- ret = device_register(&vfd->class_dev);
- if (ret < 0) {
- printk(KERN_ERR "%s: device_register failed\n", __func__);
- goto fail_minor;
- }
-
-#if 1
- /* needed until all drivers are fixed */
- if (!vfd->release)
- printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
- "Please fix your driver for proper sysfs support, see "
- "http://lwn.net/Articles/36850/\n", vfd->name);
-#endif
- return 0;
-
-fail_minor:
- mutex_lock(&videodev_lock);
- video_device[vfd->minor] = NULL;
- vfd->minor = -1;
- mutex_unlock(&videodev_lock);
- return ret;
-}
-EXPORT_SYMBOL(video_register_device_index);
-
-/**
- * video_unregister_device - unregister a video4linux device
- * @vfd: the device to unregister
- *
- * This unregisters the passed device and deassigns the minor
- * number. Future open calls will be met with errors.
- */
-
-void video_unregister_device(struct video_device *vfd)
-{
- mutex_lock(&videodev_lock);
- if(video_device[vfd->minor]!=vfd)
- panic("videodev: bad unregister");
-
- video_device[vfd->minor]=NULL;
- device_unregister(&vfd->class_dev);
- mutex_unlock(&videodev_lock);
-}
-EXPORT_SYMBOL(video_unregister_device);
-
-/*
- * Video fs operations
- */
-static const struct file_operations video_fops=
-{
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .open = video_open,
-};
-
-/*
- * Initialise video for linux
- */
-
-static int __init videodev_init(void)
-{
- int ret;
-
- printk(KERN_INFO "Linux video capture interface: v2.00\n");
- if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
- printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
- return -EIO;
- }
-
- ret = class_register(&video_class);
- if (ret < 0) {
- unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
- printk(KERN_WARNING "video_dev: class_register failed\n");
- return -EIO;
- }
-
- return 0;
-}
-
-static void __exit videodev_exit(void)
-{
- class_unregister(&video_class);
- unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
-}
-
-module_init(videodev_init)
-module_exit(videodev_exit)
-
-MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
-MODULE_LICENSE("GPL");
-
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 01ea99c9bc1..3989b0eded2 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -38,7 +38,7 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-sgi.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <linux/video_decoder.h>
#include <linux/mutex.h>
@@ -4385,8 +4385,6 @@ static const struct file_operations vino_fops = {
static struct video_device v4l_device_template = {
.name = "NOT SET",
- /*.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE | */
- /* VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY */
.fops = &vino_fops,
.minor = -1,
};
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 059b01c11dc..3518af071a2 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -35,6 +35,7 @@
#include <linux/interrupt.h>
#include <media/videobuf-vmalloc.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/kthread.h>
#include <linux/highmem.h>
#include <linux/freezer.h>
@@ -1065,13 +1066,7 @@ static const struct file_operations vivi_fops = {
.llseek = no_llseek,
};
-static struct video_device vivi_template = {
- .name = "vivi",
- .type = VID_TYPE_CAPTURE,
- .fops = &vivi_fops,
- .minor = -1,
- .release = video_device_release,
-
+static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
@@ -1093,6 +1088,15 @@ static struct video_device vivi_template = {
#ifdef CONFIG_VIDEO_V4L1_COMPAT
.vidiocgmbuf = vidiocgmbuf,
#endif
+};
+
+static struct video_device vivi_template = {
+ .name = "vivi",
+ .fops = &vivi_fops,
+ .ioctl_ops = &vivi_ioctl_ops,
+ .minor = -1,
+ .release = video_device_release,
+
.tvnorms = V4L2_STD_525_60,
.current_norm = V4L2_STD_NTSC_M,
};
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c
index cbecb3cbbba..577956c5410 100644
--- a/drivers/media/video/vp27smpx.c
+++ b/drivers/media/video/vp27smpx.c
@@ -27,7 +27,7 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-i2c-drv.h>
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 33f702698a5..9402f40095b 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -57,8 +57,9 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/parport.h>
/*#define DEBUG*/ /* Undef me for production */
@@ -195,9 +196,7 @@ static const struct file_operations w9966_fops = {
.llseek = no_llseek,
};
static struct video_device w9966_template = {
- .owner = THIS_MODULE,
.name = W9966_DRIVERNAME,
- .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
.fops = &w9966_fops,
};
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index 840522442d0..168baabe465 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -42,6 +42,7 @@
#include <asm/page.h>
#include <asm/uaccess.h>
#include <linux/page-flags.h>
+#include <media/v4l2-ioctl.h>
#include "w9968cf.h"
#include "w9968cf_decoder.h"
@@ -3549,13 +3550,11 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
}
strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
- cam->v4ldev->owner = THIS_MODULE;
- cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
cam->v4ldev->fops = &w9968cf_fops;
cam->v4ldev->minor = video_nr[dev_nr];
cam->v4ldev->release = video_device_release;
video_set_drvdata(cam->v4ldev, cam);
- cam->v4ldev->dev = &cam->dev;
+ cam->v4ldev->parent = &cam->dev;
err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
video_nr[dev_nr]);
diff --git a/drivers/media/video/w9968cf.h b/drivers/media/video/w9968cf.h
index 3c95316bc03..30032e15e23 100644
--- a/drivers/media/video/w9968cf.h
+++ b/drivers/media/video/w9968cf.h
@@ -21,7 +21,7 @@
#ifndef _W9968CF_H_
#define _W9968CF_H_
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/usb.h>
#include <linux/i2c.h>
#include <linux/device.h>
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
index 7be47a25585..95c79ad8048 100644
--- a/drivers/media/video/wm8739.c
+++ b/drivers/media/video/wm8739.c
@@ -27,7 +27,7 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-i2c-drv.h>
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index c2ab70a04a7..48df661d4fc 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -31,7 +31,7 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-i2c-drv-legacy.h>
diff --git a/drivers/media/video/zc0301/zc0301.h b/drivers/media/video/zc0301/zc0301.h
index 7bbab541a30..b1b5cceb4ba 100644
--- a/drivers/media/video/zc0301/zc0301.h
+++ b/drivers/media/video/zc0301/zc0301.h
@@ -25,6 +25,7 @@
#include <linux/usb.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include <linux/device.h>
#include <linux/list.h>
#include <linux/spinlock.h>
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
index e5c4e9f5193..550ce7bd5c8 100644
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -1985,8 +1985,6 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
}
strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera");
- cam->v4ldev->owner = THIS_MODULE;
- cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
cam->v4ldev->fops = &zc0301_fops;
cam->v4ldev->minor = video_nr[dev_nr];
cam->v4ldev->release = video_device_release;
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c
index 0929edb2d4f..d842a7cb99d 100644
--- a/drivers/media/video/zoran_card.c
+++ b/drivers/media/video/zoran_card.c
@@ -161,7 +161,7 @@ static struct pci_device_id zr36067_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
int zoran_num; /* number of Buzs in use */
-struct zoran zoran[BUZ_MAX];
+struct zoran *zoran[BUZ_MAX];
/* videocodec bus functions ZR36060 */
static u32
@@ -355,9 +355,15 @@ i2cid_to_modulename (u16 i2c_id)
case I2C_DRIVERID_BT856:
name = "bt856";
break;
+ case I2C_DRIVERID_BT866:
+ name = "bt866";
+ break;
case I2C_DRIVERID_VPX3220:
name = "vpx3220";
break;
+ case I2C_DRIVERID_KS0127:
+ name = "ks0127";
+ break;
}
return name;
@@ -1164,7 +1170,7 @@ static void
zoran_release (struct zoran *zr)
{
if (!zr->initialized)
- return;
+ goto exit_free;
/* unregister videocodec bus */
if (zr->codec) {
struct videocodec_master *master = zr->codec->master_data;
@@ -1192,6 +1198,8 @@ zoran_release (struct zoran *zr)
iounmap(zr->zr36057_mem);
pci_disable_device(zr->pci_dev);
video_unregister_device(zr->video_dev);
+exit_free:
+ kfree(zr);
}
void
@@ -1269,8 +1277,14 @@ find_zr36057 (void)
while (zoran_num < BUZ_MAX &&
(dev = pci_get_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) {
card_num = card[zoran_num];
- zr = &zoran[zoran_num];
- memset(zr, 0, sizeof(struct zoran)); // Just in case if previous cycle failed
+ zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
+ if (!zr) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - kzalloc failed\n",
+ ZORAN_NAME);
+ continue;
+ }
zr->pci_dev = dev;
//zr->zr36057_mem = NULL;
zr->id = zoran_num;
@@ -1278,7 +1292,7 @@ find_zr36057 (void)
spin_lock_init(&zr->spinlock);
mutex_init(&zr->resource_lock);
if (pci_enable_device(dev))
- continue;
+ goto zr_free_mem;
zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0);
pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION,
&zr->revision);
@@ -1294,7 +1308,7 @@ find_zr36057 (void)
KERN_ERR
"%s: find_zr36057() - no card specified, please use the card=X insmod option\n",
ZR_DEVNAME(zr));
- continue;
+ goto zr_free_mem;
}
} else {
int i;
@@ -1333,7 +1347,7 @@ find_zr36057 (void)
KERN_ERR
"%s: find_zr36057() - unknown card\n",
ZR_DEVNAME(zr));
- continue;
+ goto zr_free_mem;
}
}
}
@@ -1343,7 +1357,7 @@ find_zr36057 (void)
KERN_ERR
"%s: find_zr36057() - invalid cardnum %d\n",
ZR_DEVNAME(zr), card_num);
- continue;
+ goto zr_free_mem;
}
/* even though we make this a non pointer and thus
@@ -1361,7 +1375,7 @@ find_zr36057 (void)
KERN_ERR
"%s: find_zr36057() - ioremap failed\n",
ZR_DEVNAME(zr));
- continue;
+ goto zr_free_mem;
}
result = request_irq(zr->pci_dev->irq,
@@ -1530,7 +1544,7 @@ find_zr36057 (void)
}
/* Success so keep the pci_dev referenced */
pci_dev_get(zr->pci_dev);
- zoran_num++;
+ zoran[zoran_num++] = zr;
continue;
// Init errors
@@ -1549,6 +1563,8 @@ find_zr36057 (void)
free_irq(zr->pci_dev->irq, zr);
zr_unmap:
iounmap(zr->zr36057_mem);
+ zr_free_mem:
+ kfree(zr);
continue;
}
if (dev) /* Clean up ref count on early exit */
@@ -1620,7 +1636,7 @@ init_dc10_cards (void)
/* take care of Natoma chipset and a revision 1 zr36057 */
for (i = 0; i < zoran_num; i++) {
- struct zoran *zr = &zoran[i];
+ struct zoran *zr = zoran[i];
if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
zr->jpg_buffers.need_contiguous = 1;
@@ -1632,7 +1648,7 @@ init_dc10_cards (void)
if (zr36057_init(zr) < 0) {
for (i = 0; i < zoran_num; i++)
- zoran_release(&zoran[i]);
+ zoran_release(zoran[i]);
return -EIO;
}
zoran_proc_init(zr);
@@ -1647,7 +1663,7 @@ unload_dc10_cards (void)
int i;
for (i = 0; i < zoran_num; i++)
- zoran_release(&zoran[i]);
+ zoran_release(zoran[i]);
}
module_init(init_dc10_cards);
diff --git a/drivers/media/video/zoran_card.h b/drivers/media/video/zoran_card.h
index 1b5c4171cf9..e4dc9d29b40 100644
--- a/drivers/media/video/zoran_card.h
+++ b/drivers/media/video/zoran_card.h
@@ -41,7 +41,7 @@ extern int zr36067_debug;
/* Anybody who uses more than four? */
#define BUZ_MAX 4
extern int zoran_num;
-extern struct zoran zoran[BUZ_MAX];
+extern struct zoran *zoran[BUZ_MAX];
extern struct video_device zoran_template;
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index c0675921fe2..ec6f59674b1 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -71,6 +71,7 @@
#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include "videocodec.h"
#include <asm/byteorder.h>
@@ -1212,8 +1213,8 @@ zoran_open (struct inode *inode,
/* find the device */
for (i = 0; i < zoran_num; i++) {
- if (zoran[i].video_dev->minor == minor) {
- zr = &zoran[i];
+ if (zoran[i]->video_dev->minor == minor) {
+ zr = zoran[i];
break;
}
}
@@ -4643,8 +4644,6 @@ static const struct file_operations zoran_fops = {
struct video_device zoran_template __devinitdata = {
.name = ZORAN_NAME,
- .type = ZORAN_VID_TYPE,
- .type2 = ZORAN_V4L2_VID_FLAGS,
.fops = &zoran_fops,
.release = &zoran_vdev_release,
.minor = -1
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index 485df2e3613..18d1c4ba79f 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -35,6 +35,7 @@
#include <linux/proc_fs.h>
#include <linux/highmem.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
/* Version Information */
@@ -761,14 +762,7 @@ static const struct file_operations zr364xx_fops = {
.llseek = no_llseek,
};
-static struct video_device zr364xx_template = {
- .owner = THIS_MODULE,
- .name = DRIVER_DESC,
- .type = VID_TYPE_CAPTURE,
- .fops = &zr364xx_fops,
- .release = video_device_release,
- .minor = -1,
-
+static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = {
.vidioc_querycap = zr364xx_vidioc_querycap,
.vidioc_enum_fmt_vid_cap = zr364xx_vidioc_enum_fmt_vid_cap,
.vidioc_try_fmt_vid_cap = zr364xx_vidioc_try_fmt_vid_cap,
@@ -784,6 +778,14 @@ static struct video_device zr364xx_template = {
.vidioc_s_ctrl = zr364xx_vidioc_s_ctrl,
};
+static struct video_device zr364xx_template = {
+ .name = DRIVER_DESC,
+ .fops = &zr364xx_fops,
+ .ioctl_ops = &zr364xx_ioctl_ops,
+ .release = video_device_release,
+ .minor = -1,
+};
+
/*******************/
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 91ec9fdc718..a03fe1fb61c 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -260,7 +260,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc
dma_addr = dma_map_single(&adapter->vdev->dev, skb->data,
pool->buff_size, DMA_FROM_DEVICE);
- if (dma_mapping_error((&adapter->vdev->dev, dma_addr))
+ if (dma_mapping_error(&adapter->vdev->dev, dma_addr))
goto failure;
pool->free_map[free_index] = IBM_VETH_INVALID_MAP;
@@ -294,7 +294,7 @@ failure:
pool->consumer_index = pool->size - 1;
else
pool->consumer_index--;
- if (!dma_mapping_error((&adapter->vdev->dev, dma_addr))
+ if (!dma_mapping_error(&adapter->vdev->dev, dma_addr))
dma_unmap_single(&adapter->vdev->dev,
pool->dma_addr[index], pool->buff_size,
DMA_FROM_DEVICE);
@@ -488,7 +488,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
&adapter->rx_buff_pool[i]);
if (adapter->bounce_buffer != NULL) {
- if (!dma_mapping_error(adapter->bounce_buffer_dma)) {
+ if (!dma_mapping_error(dev, adapter->bounce_buffer_dma)) {
dma_unmap_single(&adapter->vdev->dev,
adapter->bounce_buffer_dma,
adapter->netdev->mtu + IBMVETH_BUFF_OH,
@@ -924,7 +924,7 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
buf[1] = 0;
}
- if (dma_mapping_error((&adapter->vdev->dev, data_dma_addr)) {
+ if (dma_mapping_error(&adapter->vdev->dev, data_dma_addr)) {
if (!firmware_has_feature(FW_FEATURE_CMO))
ibmveth_error_printk("tx: unable to map xmit buffer\n");
skb_copy_from_linear_data(skb, adapter->bounce_buffer,
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 1d7ec312934..f821dbc952a 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -13,3 +13,9 @@ config OF_I2C
depends on PPC_OF && I2C
help
OpenFirmware I2C accessors
+
+config OF_SPI
+ def_tristate SPI
+ depends on OF && PPC_OF && SPI
+ help
+ OpenFirmware SPI accessors
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 548772e871f..4c3c6f8e36f 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -2,3 +2,4 @@ obj-y = base.o
obj-$(CONFIG_OF_DEVICE) += device.o platform.o
obj-$(CONFIG_OF_GPIO) += gpio.o
obj-$(CONFIG_OF_I2C) += of_i2c.o
+obj-$(CONFIG_OF_SPI) += of_spi.o
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 23ffb7c0caf..ad8ac1a8af2 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -385,3 +385,91 @@ struct device_node *of_find_matching_node(struct device_node *from,
return np;
}
EXPORT_SYMBOL(of_find_matching_node);
+
+/**
+ * of_modalias_table: Table of explicit compatible ==> modalias mappings
+ *
+ * This table allows particulare compatible property values to be mapped
+ * to modalias strings. This is useful for busses which do not directly
+ * understand the OF device tree but are populated based on data contained
+ * within the device tree. SPI and I2C are the two current users of this
+ * table.
+ *
+ * In most cases, devices do not need to be listed in this table because
+ * the modalias value can be derived directly from the compatible table.
+ * However, if for any reason a value cannot be derived, then this table
+ * provides a method to override the implicit derivation.
+ *
+ * At the moment, a single table is used for all bus types because it is
+ * assumed that the data size is small and that the compatible values
+ * should already be distinct enough to differentiate between SPI, I2C
+ * and other devices.
+ */
+struct of_modalias_table {
+ char *of_device;
+ char *modalias;
+};
+static struct of_modalias_table of_modalias_table[] = {
+ /* Empty for now; add entries as needed */
+};
+
+/**
+ * of_modalias_node - Lookup appropriate modalias for a device node
+ * @node: pointer to a device tree node
+ * @modalias: Pointer to buffer that modalias value will be copied into
+ * @len: Length of modalias value
+ *
+ * Based on the value of the compatible property, this routine will determine
+ * an appropriate modalias value for a particular device tree node. Three
+ * separate methods are used to derive a modalias value.
+ *
+ * First method is to lookup the compatible value in of_modalias_table.
+ * Second is to look for a "linux,<modalias>" entry in the compatible list
+ * and used that for modalias. Third is to strip off the manufacturer
+ * prefix from the first compatible entry and use the remainder as modalias
+ *
+ * This routine returns 0 on success
+ */
+int of_modalias_node(struct device_node *node, char *modalias, int len)
+{
+ int i, cplen;
+ const char *compatible;
+ const char *p;
+
+ /* 1. search for exception list entry */
+ for (i = 0; i < ARRAY_SIZE(of_modalias_table); i++) {
+ compatible = of_modalias_table[i].of_device;
+ if (!of_device_is_compatible(node, compatible))
+ continue;
+ strlcpy(modalias, of_modalias_table[i].modalias, len);
+ return 0;
+ }
+
+ compatible = of_get_property(node, "compatible", &cplen);
+ if (!compatible)
+ return -ENODEV;
+
+ /* 2. search for linux,<modalias> entry */
+ p = compatible;
+ while (cplen > 0) {
+ if (!strncmp(p, "linux,", 6)) {
+ p += 6;
+ strlcpy(modalias, p, len);
+ return 0;
+ }
+
+ i = strlen(p) + 1;
+ p += i;
+ cplen -= i;
+ }
+
+ /* 3. take first compatible entry and strip manufacturer */
+ p = strchr(compatible, ',');
+ if (!p)
+ return -ENODEV;
+ p++;
+ strlcpy(modalias, p, len);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_modalias_node);
+
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
index 344e1b03dd8..6a98dc8aa30 100644
--- a/drivers/of/of_i2c.c
+++ b/drivers/of/of_i2c.c
@@ -16,62 +16,6 @@
#include <linux/of_i2c.h>
#include <linux/module.h>
-struct i2c_driver_device {
- char *of_device;
- char *i2c_type;
-};
-
-static struct i2c_driver_device i2c_devices[] = {
-};
-
-static int of_find_i2c_driver(struct device_node *node,
- struct i2c_board_info *info)
-{
- int i, cplen;
- const char *compatible;
- const char *p;
-
- /* 1. search for exception list entry */
- for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
- if (!of_device_is_compatible(node, i2c_devices[i].of_device))
- continue;
- if (strlcpy(info->type, i2c_devices[i].i2c_type,
- I2C_NAME_SIZE) >= I2C_NAME_SIZE)
- return -ENOMEM;
-
- return 0;
- }
-
- compatible = of_get_property(node, "compatible", &cplen);
- if (!compatible)
- return -ENODEV;
-
- /* 2. search for linux,<i2c-type> entry */
- p = compatible;
- while (cplen > 0) {
- if (!strncmp(p, "linux,", 6)) {
- p += 6;
- if (strlcpy(info->type, p,
- I2C_NAME_SIZE) >= I2C_NAME_SIZE)
- return -ENOMEM;
- return 0;
- }
-
- i = strlen(p) + 1;
- p += i;
- cplen -= i;
- }
-
- /* 3. take fist compatible entry and strip manufacturer */
- p = strchr(compatible, ',');
- if (!p)
- return -ENODEV;
- p++;
- if (strlcpy(info->type, p, I2C_NAME_SIZE) >= I2C_NAME_SIZE)
- return -ENOMEM;
- return 0;
-}
-
void of_register_i2c_devices(struct i2c_adapter *adap,
struct device_node *adap_node)
{
@@ -83,6 +27,9 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
const u32 *addr;
int len;
+ if (of_modalias_node(node, info.type, sizeof(info.type)) < 0)
+ continue;
+
addr = of_get_property(node, "reg", &len);
if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
printk(KERN_ERR
@@ -92,11 +39,6 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
info.irq = irq_of_parse_and_map(node, 0);
- if (of_find_i2c_driver(node, &info) < 0) {
- irq_dispose_mapping(info.irq);
- continue;
- }
-
info.addr = *addr;
request_module(info.type);
diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c
new file mode 100644
index 00000000000..b01eec026f6
--- /dev/null
+++ b/drivers/of/of_spi.c
@@ -0,0 +1,93 @@
+/*
+ * SPI OF support routines
+ * Copyright (C) 2008 Secret Lab Technologies Ltd.
+ *
+ * Support routines for deriving SPI device attachments from the device
+ * tree.
+ */
+
+#include <linux/of.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/of_spi.h>
+
+/**
+ * of_register_spi_devices - Register child devices onto the SPI bus
+ * @master: Pointer to spi_master device
+ * @np: parent node of SPI device nodes
+ *
+ * Registers an spi_device for each child node of 'np' which has a 'reg'
+ * property.
+ */
+void of_register_spi_devices(struct spi_master *master, struct device_node *np)
+{
+ struct spi_device *spi;
+ struct device_node *nc;
+ const u32 *prop;
+ int rc;
+ int len;
+
+ for_each_child_of_node(np, nc) {
+ /* Alloc an spi_device */
+ spi = spi_alloc_device(master);
+ if (!spi) {
+ dev_err(&master->dev, "spi_device alloc error for %s\n",
+ nc->full_name);
+ spi_dev_put(spi);
+ continue;
+ }
+
+ /* Select device driver */
+ if (of_modalias_node(nc, spi->modalias,
+ sizeof(spi->modalias)) < 0) {
+ dev_err(&master->dev, "cannot find modalias for %s\n",
+ nc->full_name);
+ spi_dev_put(spi);
+ continue;
+ }
+
+ /* Device address */
+ prop = of_get_property(nc, "reg", &len);
+ if (!prop || len < sizeof(*prop)) {
+ dev_err(&master->dev, "%s has no 'reg' property\n",
+ nc->full_name);
+ spi_dev_put(spi);
+ continue;
+ }
+ spi->chip_select = *prop;
+
+ /* Mode (clock phase/polarity/etc.) */
+ if (of_find_property(nc, "spi-cpha", NULL))
+ spi->mode |= SPI_CPHA;
+ if (of_find_property(nc, "spi-cpol", NULL))
+ spi->mode |= SPI_CPOL;
+
+ /* Device speed */
+ prop = of_get_property(nc, "spi-max-frequency", &len);
+ if (!prop || len < sizeof(*prop)) {
+ dev_err(&master->dev, "%s has no 'spi-max-frequency' property\n",
+ nc->full_name);
+ spi_dev_put(spi);
+ continue;
+ }
+ spi->max_speed_hz = *prop;
+
+ /* IRQ */
+ spi->irq = irq_of_parse_and_map(nc, 0);
+
+ /* Store a pointer to the node in the device structure */
+ of_node_get(nc);
+ spi->dev.archdata.of_node = nc;
+
+ /* Register the new device */
+ request_module(spi->modalias);
+ rc = spi_add_device(spi);
+ if (rc) {
+ dev_err(&master->dev, "spi_device register error %s\n",
+ nc->full_name);
+ spi_dev_put(spi);
+ }
+
+ }
+}
+EXPORT_SYMBOL(of_register_spi_devices);
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 208e42ba945..3df2aaec829 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -410,7 +410,6 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
#endif
#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
- defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785)
static inline int scif_txroom(struct uart_port *port)
@@ -422,6 +421,22 @@ static inline int scif_rxroom(struct uart_port *port)
{
return sci_in(port, SCRFDR) & 0xff;
}
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
+static inline int scif_txroom(struct uart_port *port)
+{
+ if((port->mapbase == 0xffe00000) || (port->mapbase == 0xffe08000)) /* SCIF0/1*/
+ return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff);
+ else /* SCIF2 */
+ return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8);
+}
+
+static inline int scif_rxroom(struct uart_port *port)
+{
+ if((port->mapbase == 0xffe00000) || (port->mapbase == 0xffe08000)) /* SCIF0/1*/
+ return sci_in(port, SCRFDR) & 0xff;
+ else /* SCIF2 */
+ return sci_in(port, SCFDR) & SCIF2_RFDC_MASK;
+}
#else
static inline int scif_txroom(struct uart_port *port)
{
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index eb84833233f..cd728df6a01 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -123,8 +123,9 @@
#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
# define SCSPTR0 0xffe00024 /* 16 bit SCIF */
# define SCSPTR1 0xffe08024 /* 16 bit SCIF */
+# define SCSPTR2 0xffe10020 /* 16 bit SCIF/IRDA */
# define SCIF_ORER 0x0001 /* overrun error bit */
-# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
# define SCIF_ONLY
#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
# define SCSPTR0 0xff923020 /* 16 bit SCIF */
@@ -188,6 +189,7 @@
defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
defined(CONFIG_CPU_SUBTYPE_SH7751) || \
defined(CONFIG_CPU_SUBTYPE_SH7751R) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785) || \
defined(CONFIG_CPU_SUBTYPE_SHX3)
@@ -225,14 +227,21 @@
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721)
-#define SCIF_ORER 0x0200
-#define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
-#define SCIF_RFDC_MASK 0x007f
-#define SCIF_TXROOM_MAX 64
+# define SCIF_ORER 0x0200
+# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
+# define SCIF_RFDC_MASK 0x007f
+# define SCIF_TXROOM_MAX 64
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
+# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK )
+# define SCIF_RFDC_MASK 0x007f
+# define SCIF_TXROOM_MAX 64
+/* SH7763 SCIF2 support */
+# define SCIF2_RFDC_MASK 0x001f
+# define SCIF2_TXROOM_MAX 16
#else
-#define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
-#define SCIF_RFDC_MASK 0x001f
-#define SCIF_TXROOM_MAX 16
+# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
+# define SCIF_RFDC_MASK 0x001f
+# define SCIF_TXROOM_MAX 16
#endif
#if defined(SCI_ONLY)
@@ -445,11 +454,16 @@ SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16)
defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785)
-SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
SCIF_FNS(SCLSR, 0, 0, 0x28, 16)
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+/* SH7763 SCIF2 */
+SCIF_FNS(SCFDR, 0, 0, 0x1C, 16)
+SCIF_FNS(SCSPTR2, 0, 0, 0x20, 16)
+SCIF_FNS(SCLSR2, 0, 0, 0x24, 16)
+#endif /* CONFIG_CPU_SUBTYPE_SH7763 */
#else
SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
#if defined(CONFIG_CPU_SUBTYPE_SH7722)
@@ -652,6 +666,9 @@ static inline int sci_rxd_in(struct uart_port *port)
return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
if (port->mapbase == 0xffe08000)
return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xffe10000)
+ return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF/IRDA */
+
return 1;
}
#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
@@ -764,8 +781,7 @@ static inline int sci_rxd_in(struct uart_port *port)
* -- Mitch Davis - 15 Jul 2000
*/
-#if defined(CONFIG_CPU_SUBTYPE_SH7763) || \
- defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+#if defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785)
#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1)
#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index ecca4a6a6f9..964124b60db 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -178,6 +178,96 @@ struct boardinfo {
static LIST_HEAD(board_list);
static DEFINE_MUTEX(board_lock);
+/**
+ * spi_alloc_device - Allocate a new SPI device
+ * @master: Controller to which device is connected
+ * Context: can sleep
+ *
+ * Allows a driver to allocate and initialize a spi_device without
+ * registering it immediately. This allows a driver to directly
+ * fill the spi_device with device parameters before calling
+ * spi_add_device() on it.
+ *
+ * Caller is responsible to call spi_add_device() on the returned
+ * spi_device structure to add it to the SPI master. If the caller
+ * needs to discard the spi_device without adding it, then it should
+ * call spi_dev_put() on it.
+ *
+ * Returns a pointer to the new device, or NULL.
+ */
+struct spi_device *spi_alloc_device(struct spi_master *master)
+{
+ struct spi_device *spi;
+ struct device *dev = master->dev.parent;
+
+ if (!spi_master_get(master))
+ return NULL;
+
+ spi = kzalloc(sizeof *spi, GFP_KERNEL);
+ if (!spi) {
+ dev_err(dev, "cannot alloc spi_device\n");
+ spi_master_put(master);
+ return NULL;
+ }
+
+ spi->master = master;
+ spi->dev.parent = dev;
+ spi->dev.bus = &spi_bus_type;
+ spi->dev.release = spidev_release;
+ device_initialize(&spi->dev);
+ return spi;
+}
+EXPORT_SYMBOL_GPL(spi_alloc_device);
+
+/**
+ * spi_add_device - Add spi_device allocated with spi_alloc_device
+ * @spi: spi_device to register
+ *
+ * Companion function to spi_alloc_device. Devices allocated with
+ * spi_alloc_device can be added onto the spi bus with this function.
+ *
+ * Returns 0 on success; non-zero on failure
+ */
+int spi_add_device(struct spi_device *spi)
+{
+ struct device *dev = spi->master->dev.parent;
+ int status;
+
+ /* Chipselects are numbered 0..max; validate. */
+ if (spi->chip_select >= spi->master->num_chipselect) {
+ dev_err(dev, "cs%d >= max %d\n",
+ spi->chip_select,
+ spi->master->num_chipselect);
+ return -EINVAL;
+ }
+
+ /* Set the bus ID string */
+ snprintf(spi->dev.bus_id, sizeof spi->dev.bus_id,
+ "%s.%u", spi->master->dev.bus_id,
+ spi->chip_select);
+
+ /* drivers may modify this initial i/o setup */
+ status = spi->master->setup(spi);
+ if (status < 0) {
+ dev_err(dev, "can't %s %s, status %d\n",
+ "setup", spi->dev.bus_id, status);
+ return status;
+ }
+
+ /* driver core catches callers that misbehave by defining
+ * devices that already exist.
+ */
+ status = device_add(&spi->dev);
+ if (status < 0) {
+ dev_err(dev, "can't %s %s, status %d\n",
+ "add", spi->dev.bus_id, status);
+ return status;
+ }
+
+ dev_dbg(dev, "registered child %s\n", spi->dev.bus_id);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(spi_add_device);
/**
* spi_new_device - instantiate one new SPI device
@@ -197,7 +287,6 @@ struct spi_device *spi_new_device(struct spi_master *master,
struct spi_board_info *chip)
{
struct spi_device *proxy;
- struct device *dev = master->dev.parent;
int status;
/* NOTE: caller did any chip->bus_num checks necessary.
@@ -207,66 +296,28 @@ struct spi_device *spi_new_device(struct spi_master *master,
* suggests syslogged diagnostics are best here (ugh).
*/
- /* Chipselects are numbered 0..max; validate. */
- if (chip->chip_select >= master->num_chipselect) {
- dev_err(dev, "cs%d > max %d\n",
- chip->chip_select,
- master->num_chipselect);
- return NULL;
- }
-
- if (!spi_master_get(master))
+ proxy = spi_alloc_device(master);
+ if (!proxy)
return NULL;
WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias));
- proxy = kzalloc(sizeof *proxy, GFP_KERNEL);
- if (!proxy) {
- dev_err(dev, "can't alloc dev for cs%d\n",
- chip->chip_select);
- goto fail;
- }
- proxy->master = master;
proxy->chip_select = chip->chip_select;
proxy->max_speed_hz = chip->max_speed_hz;
proxy->mode = chip->mode;
proxy->irq = chip->irq;
strlcpy(proxy->modalias, chip->modalias, sizeof(proxy->modalias));
-
- snprintf(proxy->dev.bus_id, sizeof proxy->dev.bus_id,
- "%s.%u", master->dev.bus_id,
- chip->chip_select);
- proxy->dev.parent = dev;
- proxy->dev.bus = &spi_bus_type;
proxy->dev.platform_data = (void *) chip->platform_data;
proxy->controller_data = chip->controller_data;
proxy->controller_state = NULL;
- proxy->dev.release = spidev_release;
- /* drivers may modify this initial i/o setup */
- status = master->setup(proxy);
+ status = spi_add_device(proxy);
if (status < 0) {
- dev_err(dev, "can't %s %s, status %d\n",
- "setup", proxy->dev.bus_id, status);
- goto fail;
+ spi_dev_put(proxy);
+ return NULL;
}
- /* driver core catches callers that misbehave by defining
- * devices that already exist.
- */
- status = device_register(&proxy->dev);
- if (status < 0) {
- dev_err(dev, "can't %s %s, status %d\n",
- "add", proxy->dev.bus_id, status);
- goto fail;
- }
- dev_dbg(dev, "registered child %s\n", proxy->dev.bus_id);
return proxy;
-
-fail:
- spi_master_put(master);
- kfree(proxy);
- return NULL;
}
EXPORT_SYMBOL_GPL(spi_new_device);