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