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:
Linus Torvalds 2007-05-11 12:57:16 -07:00
Родитель 2a383c63ff bbe2486fe3
Коммит 57a44415be
65 изменённых файлов: 1609 добавлений и 871 удалений

Просмотреть файл

@ -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;