mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-04 16:15:11 +00:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (33 commits) V4L/DVB (3604): V4l printk fix V4L/DVB (3599c): Whitespace cleanups under Documentation/video4linux V4L/DVB (3599b): Whitespace cleanups under drivers/media V4L/DVB (3599a): Move drivers/usb/media to drivers/media/video V4L/DVB (3599): Implement new routing commands for wm8775 and cs53l32a. V4L/DVB (3598): Add bit algorithm adapter for the Conexant CX2341X boards. V4L/DVB (3597): Vivi: fix warning: implicit declaration of function 'in_interrupt' V4L/DVB (3588): Remove VIDIOC_G/S_AUDOUT from msp3400 V4L/DVB (3587): Always wake thread after routing change. V4L/DVB (3584): Implement V4L2_TUNER_MODE_LANG1_LANG2 audio mode V4L/DVB (3582): Implement correct msp3400 input/output routing V4L/DVB (3581): Add new media/msp3400.h header containing the routing macros V4L/DVB (3580): Last round of msp3400 cleanups before adding routing commands V4L/DVB (3579): Move msp_modus to msp3400-kthreads, add JP and KR std detection V4L/DVB (3578): Make scart definitions easier to handle V4L/DVB (3577): Cleanup audio input handling V4L/DVB (3575): Cxusb: fix i2c debug messages for bluebird devices V4L/DVB (3574): Cxusb: fix debug messages V4L/DVB (3573): Cxusb: remove FIXME: comment in bluebird_patch_dvico_firmware_download V4L/DVB (3572): Cxusb: conditionalize gpio write for the medion box ...
This commit is contained in:
commit
368d17e068
206 changed files with 7248 additions and 4786 deletions
|
@ -50,5 +50,19 @@ config VIDEO_IR
|
|||
config VIDEO_TVEEPROM
|
||||
tristate
|
||||
|
||||
config USB_DABUSB
|
||||
tristate "DABUSB driver"
|
||||
depends on USB
|
||||
---help---
|
||||
A Digital Audio Broadcasting (DAB) Receiver for USB and Linux
|
||||
brought to you by the DAB-Team
|
||||
<http://wwwbode.cs.tum.edu/Par/arch/dab/>. This driver can be taken
|
||||
as an example for URB-based bulk, control, and isochronous
|
||||
transactions. URB's are explained in
|
||||
<Documentation/usb/URB.txt>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called dabusb.
|
||||
|
||||
endmenu
|
||||
|
||||
|
|
|
@ -50,14 +50,15 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
|
|||
/********************************************************************************/
|
||||
/* common dma functions */
|
||||
|
||||
void saa7146_dma_free(struct saa7146_dev *dev,struct saa7146_buf *buf)
|
||||
void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q,
|
||||
struct saa7146_buf *buf)
|
||||
{
|
||||
DEB_EE(("dev:%p, buf:%p\n",dev,buf));
|
||||
|
||||
BUG_ON(in_interrupt());
|
||||
|
||||
videobuf_waiton(&buf->vb,0,0);
|
||||
videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma);
|
||||
videobuf_dma_unmap(q, &buf->vb.dma);
|
||||
videobuf_dma_free(&buf->vb.dma);
|
||||
buf->vb.state = STATE_NEEDS_INIT;
|
||||
}
|
||||
|
|
|
@ -236,7 +236,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e
|
|||
}
|
||||
|
||||
if (buf->vb.size != size)
|
||||
saa7146_dma_free(dev,buf);
|
||||
saa7146_dma_free(dev,q,buf);
|
||||
|
||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||
buf->vb.width = llength;
|
||||
|
@ -247,7 +247,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e
|
|||
saa7146_pgtable_free(dev->pci, &buf->pt[2]);
|
||||
saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
|
||||
|
||||
err = videobuf_iolock(dev->pci,&buf->vb, NULL);
|
||||
err = videobuf_iolock(q,&buf->vb, NULL);
|
||||
if (err)
|
||||
goto oops;
|
||||
err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2], buf->vb.dma.sglist, buf->vb.dma.sglen);
|
||||
|
@ -261,7 +261,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e
|
|||
|
||||
oops:
|
||||
DEB_VBI(("error out.\n"));
|
||||
saa7146_dma_free(dev,buf);
|
||||
saa7146_dma_free(dev,q,buf);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
|||
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
|
||||
|
||||
DEB_VBI(("vb:%p\n",vb));
|
||||
saa7146_dma_free(dev,buf);
|
||||
saa7146_dma_free(dev,q,buf);
|
||||
}
|
||||
|
||||
static struct videobuf_queue_ops vbi_qops = {
|
||||
|
|
|
@ -1275,7 +1275,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
|||
buf->vb.field != field ||
|
||||
buf->vb.field != fh->video_fmt.field ||
|
||||
buf->fmt != &fh->video_fmt) {
|
||||
saa7146_dma_free(dev,buf);
|
||||
saa7146_dma_free(dev,q,buf);
|
||||
}
|
||||
|
||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||
|
@ -1304,7 +1304,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
|||
saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
|
||||
}
|
||||
|
||||
err = videobuf_iolock(dev->pci,&buf->vb, &vv->ov_fb);
|
||||
err = videobuf_iolock(q,&buf->vb, &vv->ov_fb);
|
||||
if (err)
|
||||
goto oops;
|
||||
err = saa7146_pgtable_build(dev,buf);
|
||||
|
@ -1318,7 +1318,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
|||
|
||||
oops:
|
||||
DEB_D(("error out.\n"));
|
||||
saa7146_dma_free(dev,buf);
|
||||
saa7146_dma_free(dev,q,buf);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -1363,7 +1363,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
|||
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
|
||||
|
||||
DEB_CAP(("vbuf:%p\n",vb));
|
||||
saa7146_dma_free(dev,buf);
|
||||
saa7146_dma_free(dev,q,buf);
|
||||
}
|
||||
|
||||
static struct videobuf_queue_ops video_qops = {
|
||||
|
|
|
@ -541,6 +541,7 @@ static struct usb_device_id flexcop_usb_table [] = {
|
|||
{ USB_DEVICE(0x0af7, 0x0101) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE (usb, flexcop_usb_table);
|
||||
|
||||
/* usb specific object needed to register this driver with the usb subsystem */
|
||||
static struct usb_driver flexcop_usb_driver = {
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
|
||||
|
||||
EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends
|
||||
EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video/bt8xx -Idrivers/media/dvb/frontends
|
||||
|
|
|
@ -81,10 +81,11 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
|
|||
return -EAGAIN;
|
||||
|
||||
if (num > 2)
|
||||
warn("more than 2 i2c messages at a time is not handled yet. TODO.");
|
||||
warn("more than two i2c messages at a time is not handled yet. TODO.");
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
|
||||
if (d->udev->descriptor.idVendor == USB_VID_MEDION)
|
||||
switch (msg[i].addr) {
|
||||
case 0x63:
|
||||
cxusb_gpio_tuner(d,0);
|
||||
|
@ -108,7 +109,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
|
|||
break;
|
||||
|
||||
if (ibuf[0] != 0x08)
|
||||
deb_info("i2c read could have been failed\n");
|
||||
deb_i2c("i2c read may have failed\n");
|
||||
|
||||
memcpy(msg[i+1].buf,&ibuf[1],msg[i+1].len);
|
||||
|
||||
|
@ -122,7 +123,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
|
|||
if (cxusb_ctrl_msg(d,CMD_I2C_WRITE, obuf, 2+msg[i].len, &ibuf,1) < 0)
|
||||
break;
|
||||
if (ibuf != 0x08)
|
||||
deb_info("i2c write could have been failed\n");
|
||||
deb_i2c("i2c write may have failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -410,7 +411,6 @@ static int bluebird_patch_dvico_firmware_download(struct usb_device *udev, const
|
|||
if (fw->data[BLUEBIRD_01_ID_OFFSET] == (USB_VID_DVICO & 0xff) &&
|
||||
fw->data[BLUEBIRD_01_ID_OFFSET + 1] == USB_VID_DVICO >> 8) {
|
||||
|
||||
/* FIXME: are we allowed to change the fw-data ? */
|
||||
fw->data[BLUEBIRD_01_ID_OFFSET + 2] = udev->descriptor.idProduct + 1;
|
||||
fw->data[BLUEBIRD_01_ID_OFFSET + 3] = udev->descriptor.idProduct >> 8;
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
extern int dvb_usb_cxusb_debug;
|
||||
#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args)
|
||||
#define deb_i2c(args...) if (d->udev->descriptor.idVendor == USB_VID_MEDION) \
|
||||
dprintk(dvb_usb_cxusb_debug,0x01,args)
|
||||
|
||||
/* usb commands - some of it are guesses, don't have a reference yet */
|
||||
#define CMD_I2C_WRITE 0x08
|
||||
|
|
|
@ -369,6 +369,11 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
|
|||
fm_matrix = 0x3001; // stereo
|
||||
src = 0x0020;
|
||||
break;
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n");
|
||||
fm_matrix = 0x3000; // bilingual
|
||||
src = 0x0020;
|
||||
break;
|
||||
case V4L2_TUNER_MODE_LANG1:
|
||||
dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
|
||||
fm_matrix = 0x3000; // mono
|
||||
|
|
|
@ -16,31 +16,7 @@ config VIDEO_ADV_DEBUG
|
|||
V4L devices.
|
||||
In doubt, say N.
|
||||
|
||||
config VIDEO_BT848
|
||||
tristate "BT848 Video For Linux"
|
||||
depends on VIDEO_DEV && PCI && I2C
|
||||
select I2C_ALGOBIT
|
||||
select FW_LOADER
|
||||
select VIDEO_BTCX
|
||||
select VIDEO_BUF
|
||||
select VIDEO_IR
|
||||
select VIDEO_TUNER
|
||||
select VIDEO_TVEEPROM
|
||||
select VIDEO_MSP3400
|
||||
---help---
|
||||
Support for BT848 based frame grabber/overlay boards. This includes
|
||||
the Miro, Hauppauge and STB boards. Please read the material in
|
||||
<file:Documentation/video4linux/bttv/> for more information.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called bttv.
|
||||
|
||||
config VIDEO_BT848_DVB
|
||||
bool "DVB/ATSC Support for bt878 based TV cards"
|
||||
depends on VIDEO_BT848 && DVB_CORE
|
||||
select DVB_BT8XX
|
||||
---help---
|
||||
This adds support for DVB/ATSC cards based on the BT878 chip.
|
||||
source "drivers/media/video/bt8xx/Kconfig"
|
||||
|
||||
config VIDEO_SAA6588
|
||||
tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
|
||||
|
@ -315,8 +291,6 @@ config VIDEO_HEXIUM_GEMINI
|
|||
|
||||
source "drivers/media/video/cx88/Kconfig"
|
||||
|
||||
source "drivers/media/video/em28xx/Kconfig"
|
||||
|
||||
config VIDEO_OVCAMCHIP
|
||||
tristate "OmniVision Camera Chip support"
|
||||
depends on VIDEO_DEV && I2C
|
||||
|
@ -391,4 +365,234 @@ config VIDEO_SAA7127
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called saa7127
|
||||
|
||||
#
|
||||
# USB Multimedia device configuration
|
||||
#
|
||||
|
||||
menu "V4L USB devices"
|
||||
depends on USB && VIDEO_DEV
|
||||
|
||||
source "drivers/media/video/em28xx/Kconfig"
|
||||
|
||||
config USB_VICAM
|
||||
tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)"
|
||||
depends on USB && VIDEO_DEV && EXPERIMENTAL
|
||||
---help---
|
||||
Say Y here if you have 3com homeconnect camera (vicam).
|
||||
|
||||
This driver uses the Video For Linux API. You must say Y or M to
|
||||
"Video For Linux" (under Multimedia Devices) to use this driver.
|
||||
Information on this API and pointers to "v4l" programs may be found
|
||||
at <file:Documentation/video4linux/API.html>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called vicam.
|
||||
|
||||
config USB_DSBR
|
||||
tristate "D-Link USB FM radio support (EXPERIMENTAL)"
|
||||
depends on USB && VIDEO_DEV && EXPERIMENTAL
|
||||
---help---
|
||||
Say Y here if you want to connect this type of radio to your
|
||||
computer's USB port. Note that the audio is not digital, and
|
||||
you must connect the line out connector to a sound card or a
|
||||
set of speakers.
|
||||
|
||||
This driver uses the Video For Linux API. You must enable
|
||||
(Y or M in config) Video For Linux (under Character Devices)
|
||||
to use this driver. Information on this API and pointers to
|
||||
"v4l" programs may be found at
|
||||
<file:Documentation/video4linux/API.html>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called dsbr100.
|
||||
|
||||
config USB_ET61X251
|
||||
tristate "USB ET61X[12]51 PC Camera Controller support"
|
||||
depends on USB && VIDEO_DEV
|
||||
---help---
|
||||
Say Y here if you want support for cameras based on Etoms ET61X151
|
||||
or ET61X251 PC Camera Controllers.
|
||||
|
||||
See <file:Documentation/usb/et61x251.txt> for more informations.
|
||||
|
||||
This driver uses the Video For Linux API. You must say Y or M to
|
||||
"Video For Linux" to use this driver.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called et61x251.
|
||||
|
||||
config USB_IBMCAM
|
||||
tristate "USB IBM (Xirlink) C-it Camera support"
|
||||
depends on USB && VIDEO_DEV
|
||||
---help---
|
||||
Say Y here if you want to connect a IBM "C-It" camera, also known as
|
||||
"Xirlink PC Camera" to your computer's USB port. For more
|
||||
information, read <file:Documentation/usb/ibmcam.txt>.
|
||||
|
||||
This driver uses the Video For Linux API. You must enable
|
||||
(Y or M in config) Video For Linux (under Character Devices)
|
||||
to use this driver. Information on this API and pointers to
|
||||
"v4l" programs may be found at
|
||||
<file:Documentation/video4linux/API.html>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ibmcam.
|
||||
|
||||
This camera has several configuration options which
|
||||
can be specified when you load the module. Read
|
||||
<file:Documentation/usb/ibmcam.txt> to learn more.
|
||||
|
||||
config USB_KONICAWC
|
||||
tristate "USB Konica Webcam support"
|
||||
depends on USB && VIDEO_DEV
|
||||
---help---
|
||||
Say Y here if you want support for webcams based on a Konica
|
||||
chipset. This is known to work with the Intel YC76 webcam.
|
||||
|
||||
This driver uses the Video For Linux API. You must enable
|
||||
(Y or M in config) Video For Linux (under Character Devices)
|
||||
to use this driver. Information on this API and pointers to
|
||||
"v4l" programs may be found at
|
||||
<file:Documentation/video4linux/API.html>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called konicawc.
|
||||
|
||||
config USB_OV511
|
||||
tristate "USB OV511 Camera support"
|
||||
depends on USB && VIDEO_DEV
|
||||
---help---
|
||||
Say Y here if you want to connect this type of camera to your
|
||||
computer's USB port. See <file:Documentation/usb/ov511.txt> for more
|
||||
information and for a list of supported cameras.
|
||||
|
||||
This driver uses the Video For Linux API. You must say Y or M to
|
||||
"Video For Linux" (under Character Devices) to use this driver.
|
||||
Information on this API and pointers to "v4l" programs may be found
|
||||
at <file:Documentation/video4linux/API.html>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ov511.
|
||||
|
||||
config USB_SE401
|
||||
tristate "USB SE401 Camera support"
|
||||
depends on USB && VIDEO_DEV
|
||||
---help---
|
||||
Say Y here if you want to connect this type of camera to your
|
||||
computer's USB port. See <file:Documentation/usb/se401.txt> for more
|
||||
information and for a list of supported cameras.
|
||||
|
||||
This driver uses the Video For Linux API. You must say Y or M to
|
||||
"Video For Linux" (under Multimedia Devices) to use this driver.
|
||||
Information on this API and pointers to "v4l" programs may be found
|
||||
at <file:Documentation/video4linux/API.html>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called se401.
|
||||
|
||||
config USB_SN9C102
|
||||
tristate "USB SN9C10x PC Camera Controller support"
|
||||
depends on USB && VIDEO_DEV
|
||||
---help---
|
||||
Say Y here if you want support for cameras based on SONiX SN9C101,
|
||||
SN9C102 or SN9C103 PC Camera Controllers.
|
||||
|
||||
See <file:Documentation/usb/sn9c102.txt> for more informations.
|
||||
|
||||
This driver uses the Video For Linux API. You must say Y or M to
|
||||
"Video For Linux" to use this driver.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called sn9c102.
|
||||
|
||||
config USB_STV680
|
||||
tristate "USB STV680 (Pencam) Camera support"
|
||||
depends on USB && VIDEO_DEV
|
||||
---help---
|
||||
Say Y here if you want to connect this type of camera to your
|
||||
computer's USB port. This includes the Pencam line of cameras.
|
||||
See <file:Documentation/usb/stv680.txt> for more information and for
|
||||
a list of supported cameras.
|
||||
|
||||
This driver uses the Video For Linux API. You must say Y or M to
|
||||
"Video For Linux" (under Multimedia Devices) to use this driver.
|
||||
Information on this API and pointers to "v4l" programs may be found
|
||||
at <file:Documentation/video4linux/API.html>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called stv680.
|
||||
|
||||
config USB_W9968CF
|
||||
tristate "USB W996[87]CF JPEG Dual Mode Camera support"
|
||||
depends on USB && VIDEO_DEV && I2C && VIDEO_OVCAMCHIP
|
||||
---help---
|
||||
Say Y here if you want support for cameras based on OV681 or
|
||||
Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips.
|
||||
|
||||
This driver has an optional plugin, which is distributed as a
|
||||
separate module only (released under GPL). It allows to use higher
|
||||
resolutions and framerates, but cannot be included in the official
|
||||
Linux kernel for performance purposes.
|
||||
|
||||
See <file:Documentation/usb/w9968cf.txt> for more informations.
|
||||
|
||||
This driver uses the Video For Linux and the I2C APIs. It needs the
|
||||
OmniVision Camera Chip support as well. You must say Y or M to
|
||||
"Video For Linux", "I2C Support" and "OmniVision Camera Chip
|
||||
support" to use this driver.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called w9968cf.
|
||||
|
||||
config USB_ZC0301
|
||||
tristate "USB ZC0301 Image Processor and Control Chip support"
|
||||
depends on USB && VIDEO_DEV
|
||||
---help---
|
||||
Say Y here if you want support for cameras based on the ZC0301
|
||||
Image Processor and Control Chip.
|
||||
|
||||
See <file:Documentation/usb/zc0301.txt> for more informations.
|
||||
|
||||
This driver uses the Video For Linux API. You must say Y or M to
|
||||
"Video For Linux" to use this driver.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called zc0301.
|
||||
|
||||
config USB_PWC
|
||||
tristate "USB Philips Cameras"
|
||||
depends on USB && VIDEO_DEV
|
||||
---help---
|
||||
Say Y or M here if you want to use one of these Philips & OEM
|
||||
webcams:
|
||||
* Philips PCA645, PCA646
|
||||
* Philips PCVC675, PCVC680, PCVC690
|
||||
* Philips PCVC720/40, PCVC730, PCVC740, PCVC750
|
||||
* Askey VC010
|
||||
* Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro'
|
||||
and 'Orbit'/'Sphere'
|
||||
* Samsung MPC-C10, MPC-C30
|
||||
* Creative Webcam 5, Pro Ex
|
||||
* SOTEC Afina Eye
|
||||
* Visionite VCS-UC300, VCS-UM100
|
||||
|
||||
The PCA635, PCVC665 and PCVC720/20 are not supported by this driver
|
||||
and never will be, but the 665 and 720/20 are supported by other
|
||||
drivers.
|
||||
|
||||
See <file:Documentation/usb/philips.txt> for more information and
|
||||
installation instructions.
|
||||
|
||||
The built-in microphone is enabled by selecting USB Audio support.
|
||||
|
||||
This driver uses the Video For Linux API. You must say Y or M to
|
||||
"Video For Linux" (under Character Devices) to use this driver.
|
||||
Information on this API and pointers to "v4l" programs may be found
|
||||
at <file:Documentation/video4linux/API.html>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called pwc.
|
||||
|
||||
endmenu # V4L USB devices
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
# Makefile for the video capture/playback device drivers.
|
||||
#
|
||||
|
||||
bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
|
||||
bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \
|
||||
bttv-input.o
|
||||
zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
|
||||
zr36067-objs := zoran_procfs.o zoran_device.o \
|
||||
zoran_driver.o zoran_card.o
|
||||
|
@ -15,8 +12,8 @@ msp3400-objs := msp3400-driver.o msp3400-kthreads.o
|
|||
|
||||
obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl32.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_BT848) += bttv.o tvaudio.o \
|
||||
tda7432.o tda9875.o ir-kbd-i2c.o
|
||||
obj-$(CONFIG_VIDEO_BT848) += bt8xx/
|
||||
obj-$(CONFIG_VIDEO_BT848) += tvaudio.o tda7432.o tda9875.o ir-kbd-i2c.o
|
||||
obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
|
||||
|
@ -68,4 +65,23 @@ obj-$(CONFIG_VIDEO_CX25840) += cx25840/
|
|||
obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o
|
||||
obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
|
||||
|
||||
et61x251-objs := et61x251_core.o et61x251_tas5130d1b.o
|
||||
zc0301-objs := zc0301_core.o zc0301_pas202bcb.o
|
||||
|
||||
obj-$(CONFIG_USB_DABUSB) += dabusb.o
|
||||
obj-$(CONFIG_USB_DSBR) += dsbr100.o
|
||||
obj-$(CONFIG_USB_OV511) += ov511.o
|
||||
obj-$(CONFIG_USB_SE401) += se401.o
|
||||
obj-$(CONFIG_USB_STV680) += stv680.o
|
||||
obj-$(CONFIG_USB_W9968CF) += w9968cf.o
|
||||
|
||||
obj-$(CONFIG_USB_SN9C102) += sn9c102/
|
||||
obj-$(CONFIG_USB_ET61X251) += et61x251/
|
||||
obj-$(CONFIG_USB_PWC) += pwc/
|
||||
obj-$(CONFIG_USB_ZC0301) += zc0301/
|
||||
|
||||
obj-$(CONFIG_USB_IBMCAM) += usbvideo/
|
||||
obj-$(CONFIG_USB_KONICAWC) += usbvideo/
|
||||
obj-$(CONFIG_USB_VICAM) += usbvideo/
|
||||
|
||||
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
|
||||
|
|
25
drivers/media/video/bt8xx/Kconfig
Normal file
25
drivers/media/video/bt8xx/Kconfig
Normal file
|
@ -0,0 +1,25 @@
|
|||
config VIDEO_BT848
|
||||
tristate "BT848 Video For Linux"
|
||||
depends on VIDEO_DEV && PCI && I2C
|
||||
select I2C_ALGOBIT
|
||||
select FW_LOADER
|
||||
select VIDEO_BTCX
|
||||
select VIDEO_BUF
|
||||
select VIDEO_IR
|
||||
select VIDEO_TUNER
|
||||
select VIDEO_TVEEPROM
|
||||
select VIDEO_MSP3400
|
||||
---help---
|
||||
Support for BT848 based frame grabber/overlay boards. This includes
|
||||
the Miro, Hauppauge and STB boards. Please read the material in
|
||||
<file:Documentation/video4linux/bttv/> for more information.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called bttv.
|
||||
|
||||
config VIDEO_BT848_DVB
|
||||
bool "DVB/ATSC Support for bt878 based TV cards"
|
||||
depends on VIDEO_BT848 && DVB_CORE
|
||||
select DVB_BT8XX
|
||||
---help---
|
||||
This adds support for DVB/ATSC cards based on the BT878 chip.
|
12
drivers/media/video/bt8xx/Makefile
Normal file
12
drivers/media/video/bt8xx/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
#
|
||||
# Makefile for the video capture/playback device drivers.
|
||||
#
|
||||
|
||||
bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
|
||||
bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \
|
||||
bttv-input.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_BT848) += bttv.o
|
||||
|
||||
EXTRA_CFLAGS += -I$(src)/..
|
||||
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
|
|
@ -30,7 +30,6 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/v4l2-common.h>
|
||||
|
||||
#include "bttv.h"
|
||||
|
@ -39,7 +38,7 @@
|
|||
MODULE_LICENSE("GPL");
|
||||
|
||||
/* Addresses to scan */
|
||||
static unsigned short normal_i2c[] = { I2C_BT832_ALT1>>1, I2C_BT832_ALT2>>1,
|
||||
static unsigned short normal_i2c[] = { I2C_ADDR_BT832_ALT1>>1, I2C_ADDR_BT832_ALT2>>1,
|
||||
I2C_CLIENT_END };
|
||||
I2C_CLIENT_INSMOD;
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -36,13 +36,15 @@
|
|||
#include <linux/kdev_t.h>
|
||||
#include "bttvp.h"
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/tvaudio.h>
|
||||
#include <media/msp3400.h>
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#include "rds.h"
|
||||
#include <media/rds.h>
|
||||
|
||||
|
||||
unsigned int bttv_num; /* number of Bt848s in use */
|
||||
|
@ -926,43 +928,96 @@ video_mux(struct bttv *btv, unsigned int input)
|
|||
|
||||
static char *audio_modes[] = {
|
||||
"audio: tuner", "audio: radio", "audio: extern",
|
||||
"audio: intern", "audio: off"
|
||||
"audio: intern", "audio: mute"
|
||||
};
|
||||
|
||||
static int
|
||||
audio_mux(struct bttv *btv, int mode)
|
||||
audio_mux(struct bttv *btv, int input, int mute)
|
||||
{
|
||||
int val,mux,i2c_mux,signal;
|
||||
int gpio_val, signal;
|
||||
struct v4l2_control ctrl;
|
||||
struct i2c_client *c;
|
||||
|
||||
gpio_inout(bttv_tvcards[btv->c.type].gpiomask,
|
||||
bttv_tvcards[btv->c.type].gpiomask);
|
||||
signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC;
|
||||
|
||||
switch (mode) {
|
||||
case AUDIO_MUTE:
|
||||
btv->audio |= AUDIO_MUTE;
|
||||
break;
|
||||
case AUDIO_UNMUTE:
|
||||
btv->audio &= ~AUDIO_MUTE;
|
||||
break;
|
||||
case AUDIO_TUNER:
|
||||
case AUDIO_RADIO:
|
||||
case AUDIO_EXTERN:
|
||||
case AUDIO_INTERN:
|
||||
btv->audio &= AUDIO_MUTE;
|
||||
btv->audio |= mode;
|
||||
}
|
||||
i2c_mux = mux = (btv->audio & AUDIO_MUTE) ? AUDIO_OFF : btv->audio;
|
||||
if (btv->opt_automute && !signal && !btv->radio_user)
|
||||
mux = AUDIO_OFF;
|
||||
btv->mute = mute;
|
||||
btv->audio = input;
|
||||
|
||||
val = bttv_tvcards[btv->c.type].audiomux[mux];
|
||||
gpio_bits(bttv_tvcards[btv->c.type].gpiomask,val);
|
||||
/* automute */
|
||||
mute = mute || (btv->opt_automute && !signal && !btv->radio_user);
|
||||
|
||||
if (mute)
|
||||
gpio_val = bttv_tvcards[btv->c.type].gpiomute;
|
||||
else
|
||||
gpio_val = bttv_tvcards[btv->c.type].gpiomux[input];
|
||||
|
||||
gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val);
|
||||
if (bttv_gpio)
|
||||
bttv_gpio_tracking(btv,audio_modes[mux]);
|
||||
if (!in_interrupt())
|
||||
bttv_call_i2c_clients(btv,AUDC_SET_INPUT,&(i2c_mux));
|
||||
bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]);
|
||||
if (in_interrupt())
|
||||
return 0;
|
||||
|
||||
ctrl.id = V4L2_CID_AUDIO_MUTE;
|
||||
ctrl.value = btv->mute;
|
||||
bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, &ctrl);
|
||||
c = btv->i2c_msp34xx_client;
|
||||
if (c) {
|
||||
struct v4l2_routing route;
|
||||
|
||||
/* Note: the inputs tuner/radio/extern/intern are translated
|
||||
to msp routings. This assumes common behavior for all msp3400
|
||||
based TV cards. When this assumption fails, then the
|
||||
specific MSP routing must be added to the card table.
|
||||
For now this is sufficient. */
|
||||
switch (input) {
|
||||
case TVAUDIO_INPUT_RADIO:
|
||||
route.input = MSP_INPUT(MSP_IN_SCART_2, MSP_IN_TUNER_1,
|
||||
MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART);
|
||||
break;
|
||||
case TVAUDIO_INPUT_EXTERN:
|
||||
route.input = MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1,
|
||||
MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART);
|
||||
break;
|
||||
case TVAUDIO_INPUT_INTERN:
|
||||
/* Yes, this is the same input as for RADIO. I doubt
|
||||
if this is ever used. The only board with an INTERN
|
||||
input is the BTTV_BOARD_AVERMEDIA98. I wonder how
|
||||
that was tested. My guess is that the whole INTERN
|
||||
input does not work. */
|
||||
route.input = MSP_INPUT(MSP_IN_SCART_2, MSP_IN_TUNER_1,
|
||||
MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART);
|
||||
break;
|
||||
case TVAUDIO_INPUT_TUNER:
|
||||
default:
|
||||
route.input = MSP_INPUT_DEFAULT;
|
||||
break;
|
||||
}
|
||||
route.output = MSP_OUTPUT_DEFAULT;
|
||||
c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
|
||||
}
|
||||
c = btv->i2c_tvaudio_client;
|
||||
if (c) {
|
||||
struct v4l2_routing route;
|
||||
|
||||
route.input = input;
|
||||
route.output = 0;
|
||||
c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
audio_mute(struct bttv *btv, int mute)
|
||||
{
|
||||
return audio_mux(btv, btv->audio, mute);
|
||||
}
|
||||
|
||||
static inline int
|
||||
audio_input(struct bttv *btv, int input)
|
||||
{
|
||||
return audio_mux(btv, input, btv->mute);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1023,8 +1078,8 @@ set_input(struct bttv *btv, unsigned int input)
|
|||
} else {
|
||||
video_mux(btv,input);
|
||||
}
|
||||
audio_mux(btv,(input == bttv_tvcards[btv->c.type].tuner ?
|
||||
AUDIO_TUNER : AUDIO_EXTERN));
|
||||
audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ?
|
||||
TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN));
|
||||
set_tvnorm(btv,btv->tvnorm);
|
||||
i2c_vidiocschan(btv);
|
||||
}
|
||||
|
@ -1236,10 +1291,10 @@ static int set_control(struct bttv *btv, struct v4l2_control *c)
|
|||
case V4L2_CID_AUDIO_MUTE:
|
||||
if (c->value) {
|
||||
va.flags |= VIDEO_AUDIO_MUTE;
|
||||
audio_mux(btv, AUDIO_MUTE);
|
||||
audio_mute(btv, 1);
|
||||
} else {
|
||||
va.flags &= ~VIDEO_AUDIO_MUTE;
|
||||
audio_mux(btv, AUDIO_UNMUTE);
|
||||
audio_mute(btv, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1397,7 +1452,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
|
|||
free_btres(btv,fh,RESOURCE_OVERLAY);
|
||||
if (NULL != old) {
|
||||
dprintk("switch_overlay: old=%p state is %d\n",old,old->vb.state);
|
||||
bttv_dma_free(btv, old);
|
||||
bttv_dma_free(&fh->cap,btv, old);
|
||||
kfree(old);
|
||||
}
|
||||
dprintk("switch_overlay: done\n");
|
||||
|
@ -1407,7 +1462,8 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
|
|||
/* ----------------------------------------------------------------------- */
|
||||
/* video4linux (1) interface */
|
||||
|
||||
static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
|
||||
static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv,
|
||||
struct bttv_buffer *buf,
|
||||
const struct bttv_format *fmt,
|
||||
unsigned int width, unsigned int height,
|
||||
enum v4l2_field field)
|
||||
|
@ -1450,7 +1506,7 @@ static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
|
|||
/* alloc risc memory */
|
||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||
redo_dma_risc = 1;
|
||||
if (0 != (rc = videobuf_iolock(btv->c.pci,&buf->vb,&btv->fbuf)))
|
||||
if (0 != (rc = videobuf_iolock(q,&buf->vb,&btv->fbuf)))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -1462,7 +1518,7 @@ static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
|
|||
return 0;
|
||||
|
||||
fail:
|
||||
bttv_dma_free(btv,buf);
|
||||
bttv_dma_free(q,btv,buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -1486,7 +1542,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
|||
struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
|
||||
struct bttv_fh *fh = q->priv_data;
|
||||
|
||||
return bttv_prepare_buffer(fh->btv, buf, fh->fmt,
|
||||
return bttv_prepare_buffer(q,fh->btv, buf, fh->fmt,
|
||||
fh->width, fh->height, field);
|
||||
}
|
||||
|
||||
|
@ -1510,7 +1566,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
|||
struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
|
||||
struct bttv_fh *fh = q->priv_data;
|
||||
|
||||
bttv_dma_free(fh->btv,buf);
|
||||
bttv_dma_free(&fh->cap,fh->btv,buf);
|
||||
}
|
||||
|
||||
static struct videobuf_queue_ops bttv_video_qops = {
|
||||
|
@ -1653,7 +1709,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
|
|||
return -EINVAL;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
audio_mux(btv, (v->flags&VIDEO_AUDIO_MUTE) ? AUDIO_MUTE : AUDIO_UNMUTE);
|
||||
audio_mute(btv, (v->flags&VIDEO_AUDIO_MUTE) ? 1 : 0);
|
||||
bttv_call_i2c_clients(btv,cmd,v);
|
||||
|
||||
/* card specific hooks */
|
||||
|
@ -1822,7 +1878,8 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
|
|||
bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
|
||||
if (t->audmode == V4L2_TUNER_MODE_MONO)
|
||||
va.mode = VIDEO_SOUND_MONO;
|
||||
else if (t->audmode == V4L2_TUNER_MODE_STEREO)
|
||||
else if (t->audmode == V4L2_TUNER_MODE_STEREO ||
|
||||
t->audmode == V4L2_TUNER_MODE_LANG1_LANG2)
|
||||
va.mode = VIDEO_SOUND_STEREO;
|
||||
else if (t->audmode == V4L2_TUNER_MODE_LANG1)
|
||||
va.mode = VIDEO_SOUND_LANG1;
|
||||
|
@ -2496,7 +2553,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
|
|||
field = (vm->height > bttv_tvnorms[btv->tvnorm].sheight/2)
|
||||
? V4L2_FIELD_INTERLACED
|
||||
: V4L2_FIELD_BOTTOM;
|
||||
retval = bttv_prepare_buffer(btv,buf,
|
||||
retval = bttv_prepare_buffer(&fh->cap,btv,buf,
|
||||
format_by_palette(vm->format),
|
||||
vm->width,vm->height,field);
|
||||
if (0 != retval)
|
||||
|
@ -2528,8 +2585,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
|
|||
retval = -EIO;
|
||||
/* fall through */
|
||||
case STATE_DONE:
|
||||
videobuf_dma_pci_sync(btv->c.pci,&buf->vb.dma);
|
||||
bttv_dma_free(btv,buf);
|
||||
videobuf_dma_sync(&fh->cap,&buf->vb.dma);
|
||||
bttv_dma_free(&fh->cap,btv,buf);
|
||||
break;
|
||||
default:
|
||||
retval = -EINVAL;
|
||||
|
@ -3162,8 +3219,8 @@ static int radio_open(struct inode *inode, struct file *file)
|
|||
|
||||
file->private_data = btv;
|
||||
|
||||
bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
|
||||
audio_mux(btv,AUDIO_RADIO);
|
||||
bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL);
|
||||
audio_input(btv,TVAUDIO_INPUT_RADIO);
|
||||
|
||||
mutex_unlock(&btv->lock);
|
||||
return 0;
|
||||
|
@ -3749,7 +3806,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
|
|||
bttv_irq_switch_video(btv);
|
||||
|
||||
if ((astat & BT848_INT_HLOCK) && btv->opt_automute)
|
||||
audio_mux(btv, -1);
|
||||
audio_mute(btv, btv->mute); /* trigger automute */
|
||||
|
||||
if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) {
|
||||
printk(KERN_INFO "bttv%d: %s%s @ %08x,",btv->c.nr,
|
||||
|
@ -4050,7 +4107,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
|
|||
bt848_contrast(btv,32768);
|
||||
bt848_hue(btv,32768);
|
||||
bt848_sat(btv,32768);
|
||||
audio_mux(btv,AUDIO_MUTE);
|
||||
audio_mute(btv, 1);
|
||||
set_input(btv,0);
|
||||
}
|
||||
|
|
@ -302,6 +302,10 @@ static int attach_inform(struct i2c_client *client)
|
|||
if (!client->driver->command)
|
||||
return 0;
|
||||
|
||||
if (client->driver->id == I2C_DRIVERID_MSP3400)
|
||||
btv->i2c_msp34xx_client = client;
|
||||
if (client->driver->id == I2C_DRIVERID_TVAUDIO)
|
||||
btv->i2c_tvaudio_client = client;
|
||||
if (btv->tuner_type != UNSET) {
|
||||
struct tuner_setup tun_setup;
|
||||
|
|
@ -509,11 +509,11 @@ bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
|
|||
}
|
||||
|
||||
void
|
||||
bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf)
|
||||
bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
|
||||
{
|
||||
BUG_ON(in_interrupt());
|
||||
videobuf_waiton(&buf->vb,0,0);
|
||||
videobuf_dma_pci_unmap(btv->c.pci, &buf->vb.dma);
|
||||
videobuf_dma_unmap(q, &buf->vb.dma);
|
||||
videobuf_dma_free(&buf->vb.dma);
|
||||
btcx_riscmem_free(btv->c.pci,&buf->bottom);
|
||||
btcx_riscmem_free(btv->c.pci,&buf->top);
|
|
@ -96,7 +96,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q,
|
|||
return -EINVAL;
|
||||
|
||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||
if (0 != (rc = videobuf_iolock(btv->c.pci, &buf->vb, NULL)))
|
||||
if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL)))
|
||||
goto fail;
|
||||
if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines)))
|
||||
goto fail;
|
||||
|
@ -109,7 +109,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q,
|
|||
return 0;
|
||||
|
||||
fail:
|
||||
bttv_dma_free(btv,buf);
|
||||
bttv_dma_free(q,btv,buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -136,7 +136,7 @@ static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer
|
|||
struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
|
||||
|
||||
dprintk("free %p\n",vb);
|
||||
bttv_dma_free(fh->btv,buf);
|
||||
bttv_dma_free(&fh->cap,fh->btv,buf);
|
||||
}
|
||||
|
||||
struct videobuf_queue_ops bttv_vbi_qops = {
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/i2c.h>
|
||||
#include <media/ir-common.h>
|
||||
#include <media/ir-kbd-i2c.h>
|
||||
#include <media/i2c-addr.h>
|
||||
|
||||
/* ---------------------------------------------------------- */
|
||||
/* exported by bttv-cards.c */
|
||||
|
@ -168,25 +169,6 @@
|
|||
#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f
|
||||
#define BTTV_BOARD_MACHTV_MAGICTV 0x90
|
||||
|
||||
/* i2c address list */
|
||||
#define I2C_TSA5522 0xc2
|
||||
#define I2C_TDA7432 0x8a
|
||||
#define I2C_BT832_ALT1 0x88
|
||||
#define I2C_BT832_ALT2 0x8a // alternate setting
|
||||
#define I2C_TDA8425 0x82
|
||||
#define I2C_TDA9840 0x84
|
||||
#define I2C_TDA9850 0xb6 /* also used by 9855,9873 */
|
||||
#define I2C_TDA9874 0xb0 /* also used by 9875 */
|
||||
#define I2C_TDA9875 0xb0
|
||||
#define I2C_HAUPEE 0xa0
|
||||
#define I2C_STBEE 0xae
|
||||
#define I2C_VHX 0xc0
|
||||
#define I2C_MSP3400 0x80
|
||||
#define I2C_MSP3400_ALT 0x88
|
||||
#define I2C_TEA6300 0x80 /* also used by 6320 */
|
||||
#define I2C_DPL3518 0x84
|
||||
#define I2C_TDA9887 0x86
|
||||
|
||||
/* more card-specific defines */
|
||||
#define PT2254_L_CHANNEL 0x10
|
||||
#define PT2254_R_CHANNEL 0x08
|
||||
|
@ -252,7 +234,8 @@ struct tvcard
|
|||
unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
|
||||
u32 gpiomask;
|
||||
u32 muxsel[16];
|
||||
u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
|
||||
u32 gpiomux[4]; /* Tuner, Radio, external, internal */
|
||||
u32 gpiomute; /* GPIO mute setting */
|
||||
u32 gpiomask2; /* GPIO MUX mask */
|
||||
|
||||
/* i2c audio flags */
|
|
@ -41,7 +41,6 @@
|
|||
|
||||
#include <linux/device.h>
|
||||
#include <media/video-buf.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/tuner.h>
|
||||
#include <media/tveeprom.h>
|
||||
#include <media/ir-common.h>
|
||||
|
@ -190,7 +189,8 @@ int bttv_buffer_activate_video(struct bttv *btv,
|
|||
struct bttv_buffer_set *set);
|
||||
int bttv_buffer_activate_vbi(struct bttv *btv,
|
||||
struct bttv_buffer *vbi);
|
||||
void bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf);
|
||||
void bttv_dma_free(struct videobuf_queue *q, struct bttv *btv,
|
||||
struct bttv_buffer *buf);
|
||||
|
||||
/* overlay handling */
|
||||
int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov,
|
||||
|
@ -298,6 +298,8 @@ struct bttv {
|
|||
int i2c_state, i2c_rc;
|
||||
int i2c_done;
|
||||
wait_queue_head_t i2c_queue;
|
||||
struct i2c_client *i2c_msp34xx_client;
|
||||
struct i2c_client *i2c_tvaudio_client;
|
||||
|
||||
/* video4linux (1) */
|
||||
struct video_device *video_dev;
|
||||
|
@ -320,6 +322,7 @@ struct bttv {
|
|||
/* video state */
|
||||
unsigned int input;
|
||||
unsigned int audio;
|
||||
unsigned int mute;
|
||||
unsigned long freq;
|
||||
int tvnorm,hue,contrast,bright,saturation;
|
||||
struct v4l2_framebuffer fbuf;
|
|
@ -381,7 +381,7 @@ struct cpia2_fh {
|
|||
|
||||
struct camera_data {
|
||||
/* locks */
|
||||
struct semaphore busy_lock; /* guard against SMP multithreading */
|
||||
struct mutex busy_lock; /* guard against SMP multithreading */
|
||||
struct v4l2_prio_state prio;
|
||||
|
||||
/* camera status */
|
||||
|
|
|
@ -2238,7 +2238,7 @@ struct camera_data *cpia2_init_camera_struct(void)
|
|||
memset(cam, 0, sizeof(struct camera_data));
|
||||
|
||||
cam->present = 1;
|
||||
init_MUTEX(&cam->busy_lock);
|
||||
mutex_init(&cam->busy_lock);
|
||||
init_waitqueue_head(&cam->wq_stream);
|
||||
|
||||
return cam;
|
||||
|
@ -2371,12 +2371,12 @@ long cpia2_read(struct camera_data *cam,
|
|||
}
|
||||
|
||||
/* make this _really_ smp and multithread-safe */
|
||||
if (down_interruptible(&cam->busy_lock))
|
||||
if (mutex_lock_interruptible(&cam->busy_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (!cam->present) {
|
||||
LOG("%s: camera removed\n",__FUNCTION__);
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return 0; /* EOF */
|
||||
}
|
||||
|
||||
|
@ -2389,34 +2389,34 @@ long cpia2_read(struct camera_data *cam,
|
|||
/* Copy cam->curbuff in case it changes while we're processing */
|
||||
frame = cam->curbuff;
|
||||
if (noblock && frame->status != FRAME_READY) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if(frame->status != FRAME_READY) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
wait_event_interruptible(cam->wq_stream,
|
||||
!cam->present ||
|
||||
(frame = cam->curbuff)->status == FRAME_READY);
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
/* make this _really_ smp and multithread-safe */
|
||||
if (down_interruptible(&cam->busy_lock)) {
|
||||
if (mutex_lock_interruptible(&cam->busy_lock)) {
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
if(!cam->present) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* copy data to user space */
|
||||
if (frame->length > count) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
if (copy_to_user(buf, frame->data, frame->length)) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -2424,7 +2424,7 @@ long cpia2_read(struct camera_data *cam,
|
|||
|
||||
frame->status = FRAME_EMPTY;
|
||||
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -2443,10 +2443,10 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
|
|||
return POLLERR;
|
||||
}
|
||||
|
||||
down(&cam->busy_lock);
|
||||
mutex_lock(&cam->busy_lock);
|
||||
|
||||
if(!cam->present) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return POLLHUP;
|
||||
}
|
||||
|
||||
|
@ -2456,16 +2456,16 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
|
|||
cam->params.camera_state.stream_mode);
|
||||
}
|
||||
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
poll_wait(filp, &cam->wq_stream, wait);
|
||||
down(&cam->busy_lock);
|
||||
mutex_lock(&cam->busy_lock);
|
||||
|
||||
if(!cam->present)
|
||||
status = POLLHUP;
|
||||
else if(cam->curbuff->status == FRAME_READY)
|
||||
status = POLLIN | POLLRDNORM;
|
||||
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -2488,18 +2488,18 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
|
|||
DBG("mmap offset:%ld size:%ld\n", start_offset, size);
|
||||
|
||||
/* make this _really_ smp-safe */
|
||||
if (down_interruptible(&cam->busy_lock))
|
||||
if (mutex_lock_interruptible(&cam->busy_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (!cam->present) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (size > cam->frame_size*cam->num_frames ||
|
||||
(start_offset % cam->frame_size) != 0 ||
|
||||
(start_offset+size > cam->frame_size*cam->num_frames)) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -2507,7 +2507,7 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
|
|||
while (size > 0) {
|
||||
page = kvirt_to_pa(pos);
|
||||
if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED)) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -EAGAIN;
|
||||
}
|
||||
start += PAGE_SIZE;
|
||||
|
@ -2519,7 +2519,7 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
|
|||
}
|
||||
|
||||
cam->mmapped = true;
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -255,7 +255,7 @@ static int cpia2_open(struct inode *inode, struct file *file)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
if(down_interruptible(&cam->busy_lock))
|
||||
if(mutex_lock_interruptible(&cam->busy_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if(!cam->present) {
|
||||
|
@ -299,7 +299,7 @@ static int cpia2_open(struct inode *inode, struct file *file)
|
|||
cpia2_dbg_dump_registers(cam);
|
||||
|
||||
err_return:
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -314,7 +314,7 @@ static int cpia2_close(struct inode *inode, struct file *file)
|
|||
struct camera_data *cam = video_get_drvdata(dev);
|
||||
struct cpia2_fh *fh = file->private_data;
|
||||
|
||||
down(&cam->busy_lock);
|
||||
mutex_lock(&cam->busy_lock);
|
||||
|
||||
if (cam->present &&
|
||||
(cam->open_count == 1
|
||||
|
@ -347,7 +347,7 @@ static int cpia2_close(struct inode *inode, struct file *file)
|
|||
}
|
||||
}
|
||||
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -523,11 +523,11 @@ static int sync(struct camera_data *cam, int frame_nr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
wait_event_interruptible(cam->wq_stream,
|
||||
!cam->streaming ||
|
||||
frame->status == FRAME_READY);
|
||||
down(&cam->busy_lock);
|
||||
mutex_lock(&cam->busy_lock);
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
if(!cam->present)
|
||||
|
@ -1544,11 +1544,11 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file)
|
|||
if(frame < 0) {
|
||||
/* Wait for a frame to become available */
|
||||
struct framebuf *cb=cam->curbuff;
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
wait_event_interruptible(cam->wq_stream,
|
||||
!cam->present ||
|
||||
(cb=cam->curbuff)->status == FRAME_READY);
|
||||
down(&cam->busy_lock);
|
||||
mutex_lock(&cam->busy_lock);
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
if(!cam->present)
|
||||
|
@ -1591,11 +1591,11 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
|
|||
return -ENOTTY;
|
||||
|
||||
/* make this _really_ smp-safe */
|
||||
if (down_interruptible(&cam->busy_lock))
|
||||
if (mutex_lock_interruptible(&cam->busy_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (!cam->present) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -1608,7 +1608,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
|
|||
struct cpia2_fh *fh = file->private_data;
|
||||
retval = v4l2_prio_check(&cam->prio, &fh->prio);
|
||||
if(retval) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return retval;
|
||||
}
|
||||
break;
|
||||
|
@ -1618,7 +1618,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
|
|||
{
|
||||
struct cpia2_fh *fh = file->private_data;
|
||||
if(fh->prio != V4L2_PRIORITY_RECORD) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
break;
|
||||
|
@ -1847,7 +1847,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
|
|||
break;
|
||||
}
|
||||
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -1931,6 +1931,7 @@ static struct file_operations fops_template = {
|
|||
.poll = cpia2_v4l_poll,
|
||||
.ioctl = cpia2_ioctl,
|
||||
.llseek = no_llseek,
|
||||
.compat_ioctl = v4l_compat_ioctl32,
|
||||
.mmap = cpia2_mmap,
|
||||
};
|
||||
|
||||
|
|
|
@ -59,25 +59,25 @@ static int cs53l32a_read(struct i2c_client *client, u8 reg)
|
|||
static int cs53l32a_command(struct i2c_client *client, unsigned int cmd,
|
||||
void *arg)
|
||||
{
|
||||
struct v4l2_audio *input = arg;
|
||||
struct v4l2_routing *route = arg;
|
||||
struct v4l2_control *ctrl = arg;
|
||||
|
||||
switch (cmd) {
|
||||
case VIDIOC_S_AUDIO:
|
||||
case VIDIOC_INT_G_AUDIO_ROUTING:
|
||||
route->input = (cs53l32a_read(client, 0x01) >> 4) & 3;
|
||||
route->output = 0;
|
||||
break;
|
||||
|
||||
case VIDIOC_INT_S_AUDIO_ROUTING:
|
||||
/* There are 2 physical inputs, but the second input can be
|
||||
placed in two modes, the first mode bypasses the PGA (gain),
|
||||
the second goes through the PGA. Hence there are three
|
||||
possible inputs to choose from. */
|
||||
if (input->index > 2) {
|
||||
v4l_err(client, "Invalid input %d.\n", input->index);
|
||||
if (route->input > 2) {
|
||||
v4l_err(client, "Invalid input %d.\n", route->input);
|
||||
return -EINVAL;
|
||||
}
|
||||
cs53l32a_write(client, 0x01, 0x01 + (input->index << 4));
|
||||
break;
|
||||
|
||||
case VIDIOC_G_AUDIO:
|
||||
memset(input, 0, sizeof(*input));
|
||||
input->index = (cs53l32a_read(client, 0x01) >> 4) & 3;
|
||||
cs53l32a_write(client, 0x01, 0x01 + (route->input << 4));
|
||||
break;
|
||||
|
||||
case VIDIOC_G_CTRL:
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/v4l2-common.h>
|
||||
|
||||
#include "cx25840.h"
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/v4l2-common.h>
|
||||
|
||||
#include "cx25840.h"
|
||||
|
@ -176,9 +175,9 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw)
|
|||
cx25840_write(client, 0x4a5, 0x00);
|
||||
cx25840_write(client, 0x402, 0x00);
|
||||
/* 8. */
|
||||
cx25840_write(client, 0x401, 0x18);
|
||||
cx25840_write(client, 0x4a2, 0x10);
|
||||
cx25840_write(client, 0x402, 0x04);
|
||||
cx25840_and_or(client, 0x401, ~0x18, 0);
|
||||
cx25840_and_or(client, 0x4a2, ~0x10, 0x10);
|
||||
/* steps 8c and 8d are done in change_input() */
|
||||
/* 10. */
|
||||
cx25840_write(client, 0x8d3, 0x1f);
|
||||
cx25840_write(client, 0x8e3, 0x03);
|
||||
|
@ -209,6 +208,17 @@ static void input_change(struct i2c_client *client)
|
|||
struct cx25840_state *state = i2c_get_clientdata(client);
|
||||
v4l2_std_id std = cx25840_get_v4lstd(client);
|
||||
|
||||
/* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */
|
||||
if (std & V4L2_STD_SECAM) {
|
||||
cx25840_write(client, 0x402, 0);
|
||||
}
|
||||
else {
|
||||
cx25840_write(client, 0x402, 0x04);
|
||||
cx25840_write(client, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
|
||||
}
|
||||
cx25840_and_or(client, 0x401, ~0x60, 0);
|
||||
cx25840_and_or(client, 0x401, ~0x60, 0x60);
|
||||
|
||||
/* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC
|
||||
instead of V4L2_STD_PAL. Someone needs to test this. */
|
||||
if (std & V4L2_STD_PAL) {
|
||||
|
@ -343,6 +353,15 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
|
|||
}
|
||||
}
|
||||
|
||||
/* Follow step 9 of section 3.16 in the cx25840 datasheet.
|
||||
Without this PAL may display a vertical ghosting effect.
|
||||
This happens for example with the Yuan MPC622. */
|
||||
if (fmt >= 4 && fmt < 8) {
|
||||
/* Set format to NTSC-M */
|
||||
cx25840_and_or(client, 0x400, ~0xf, 1);
|
||||
/* Turn off LCOMB */
|
||||
cx25840_and_or(client, 0x47b, ~6, 0);
|
||||
}
|
||||
cx25840_and_or(client, 0x400, ~0xf, fmt);
|
||||
cx25840_vbi_setup(client);
|
||||
return 0;
|
||||
|
@ -359,7 +378,14 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
|
|||
}
|
||||
|
||||
switch (fmt) {
|
||||
case 0x1: return V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR;
|
||||
case 0x1:
|
||||
{
|
||||
/* if the audio std is A2-M, then this is the South Korean
|
||||
NTSC standard */
|
||||
if (cx25840_read(client, 0x805) == 2)
|
||||
return V4L2_STD_NTSC_M_KR;
|
||||
return V4L2_STD_NTSC_M;
|
||||
}
|
||||
case 0x2: return V4L2_STD_NTSC_M_JP;
|
||||
case 0x3: return V4L2_STD_NTSC_443;
|
||||
case 0x4: return V4L2_STD_PAL;
|
||||
|
@ -737,16 +763,6 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
|
|||
return set_input(client, state->vid_input, input->index);
|
||||
}
|
||||
|
||||
case VIDIOC_G_AUDIO:
|
||||
{
|
||||
struct v4l2_audio *input = arg;
|
||||
|
||||
memset(input, 0, sizeof(*input));
|
||||
input->index = state->aud_input;
|
||||
input->capability = V4L2_AUDCAP_STEREO;
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOC_S_FREQUENCY:
|
||||
input_change(client);
|
||||
break;
|
||||
|
@ -794,13 +810,14 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
|
|||
bilingual -> lang1 */
|
||||
cx25840_and_or(client, 0x809, ~0xf, 0x00);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
case V4L2_TUNER_MODE_LANG1:
|
||||
/* mono -> mono
|
||||
stereo -> stereo
|
||||
bilingual -> lang1 */
|
||||
cx25840_and_or(client, 0x809, ~0xf, 0x04);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
/* mono -> mono
|
||||
stereo -> stereo
|
||||
bilingual -> lang1/lang2 */
|
||||
|
|
|
@ -16,12 +16,13 @@ config VIDEO_CX88
|
|||
module will be called cx8800
|
||||
|
||||
config VIDEO_CX88_ALSA
|
||||
tristate "ALSA DMA audio support"
|
||||
tristate "Conexant 2388x DMA audio support"
|
||||
depends on VIDEO_CX88 && SND && EXPERIMENTAL
|
||||
select SND_PCM
|
||||
---help---
|
||||
This is a video4linux driver for direct (DMA) audio on
|
||||
Conexant 2388x based TV cards.
|
||||
Conexant 2388x based TV cards using ALSA.
|
||||
|
||||
It only works with boards with function 01 enabled.
|
||||
To check if your board supports, use lspci -n.
|
||||
If supported, you should see 1471:8801 or 1471:8811
|
||||
|
|
|
@ -303,7 +303,7 @@ static int dsp_buffer_free(snd_cx88_card_t *chip)
|
|||
BUG_ON(!chip->dma_size);
|
||||
|
||||
dprintk(2,"Freeing buffer\n");
|
||||
videobuf_dma_pci_unmap(chip->pci, &chip->dma_risc);
|
||||
videobuf_pci_dma_unmap(chip->pci, &chip->dma_risc);
|
||||
videobuf_dma_free(&chip->dma_risc);
|
||||
btcx_riscmem_free(chip->pci,&chip->buf->risc);
|
||||
kfree(chip->buf);
|
||||
|
@ -429,7 +429,7 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream,
|
|||
videobuf_dma_init_kernel(&buf->vb.dma,PCI_DMA_FROMDEVICE,
|
||||
(PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT));
|
||||
|
||||
videobuf_dma_pci_map(chip->pci,&buf->vb.dma);
|
||||
videobuf_pci_dma_map(chip->pci,&buf->vb.dma);
|
||||
|
||||
|
||||
cx88_risc_databuffer(chip->pci, &buf->risc,
|
||||
|
|
|
@ -1341,7 +1341,7 @@ bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
|||
enum v4l2_field field)
|
||||
{
|
||||
struct cx8802_fh *fh = q->priv_data;
|
||||
return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb, field);
|
||||
return cx8802_buf_prepare(q, fh->dev, (struct cx88_buffer*)vb, field);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1354,8 +1354,7 @@ bb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
|||
static void
|
||||
bb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||
{
|
||||
struct cx8802_fh *fh = q->priv_data;
|
||||
cx88_free_buffer(fh->dev->pci, (struct cx88_buffer*)vb);
|
||||
cx88_free_buffer(q, (struct cx88_buffer*)vb);
|
||||
}
|
||||
|
||||
static struct videobuf_queue_ops blackbird_qops = {
|
||||
|
|
|
@ -213,13 +213,13 @@ int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
|
|||
}
|
||||
|
||||
void
|
||||
cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf)
|
||||
cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
|
||||
{
|
||||
BUG_ON(in_interrupt());
|
||||
videobuf_waiton(&buf->vb,0,0);
|
||||
videobuf_dma_pci_unmap(pci, &buf->vb.dma);
|
||||
videobuf_dma_unmap(q, &buf->vb.dma);
|
||||
videobuf_dma_free(&buf->vb.dma);
|
||||
btcx_riscmem_free(pci, &buf->risc);
|
||||
btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc);
|
||||
buf->vb.state = STATE_NEEDS_INIT;
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
|||
enum v4l2_field field)
|
||||
{
|
||||
struct cx8802_dev *dev = q->priv_data;
|
||||
return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb,field);
|
||||
return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field);
|
||||
}
|
||||
|
||||
static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||
|
@ -101,8 +101,7 @@ static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
|||
|
||||
static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||
{
|
||||
struct cx8802_dev *dev = q->priv_data;
|
||||
cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb);
|
||||
cx88_free_buffer(q, (struct cx88_buffer*)vb);
|
||||
}
|
||||
|
||||
static struct videobuf_queue_ops dvb_qops = {
|
||||
|
|
|
@ -163,8 +163,8 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
|
|||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
|
||||
enum v4l2_field field)
|
||||
int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev,
|
||||
struct cx88_buffer *buf, enum v4l2_field field)
|
||||
{
|
||||
int size = dev->ts_packet_size * dev->ts_packet_count;
|
||||
int rc;
|
||||
|
@ -179,7 +179,7 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
|
|||
buf->vb.size = size;
|
||||
buf->vb.field = field /*V4L2_FIELD_TOP*/;
|
||||
|
||||
if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
|
||||
if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
|
||||
goto fail;
|
||||
cx88_risc_databuffer(dev->pci, &buf->risc,
|
||||
buf->vb.dma.sglist,
|
||||
|
@ -189,36 +189,36 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
|
|||
return 0;
|
||||
|
||||
fail:
|
||||
cx88_free_buffer(dev->pci,buf);
|
||||
cx88_free_buffer(q,buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
|
||||
{
|
||||
struct cx88_buffer *prev;
|
||||
struct cx88_dmaqueue *q = &dev->mpegq;
|
||||
struct cx88_dmaqueue *cx88q = &dev->mpegq;
|
||||
|
||||
dprintk( 1, "cx8802_buf_queue\n" );
|
||||
/* add jump to stopper */
|
||||
buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
|
||||
buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
|
||||
buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma);
|
||||
|
||||
if (list_empty(&q->active)) {
|
||||
if (list_empty(&cx88q->active)) {
|
||||
dprintk( 0, "queue is empty - first active\n" );
|
||||
list_add_tail(&buf->vb.queue,&q->active);
|
||||
cx8802_start_dma(dev, q, buf);
|
||||
list_add_tail(&buf->vb.queue,&cx88q->active);
|
||||
cx8802_start_dma(dev, cx88q, buf);
|
||||
buf->vb.state = STATE_ACTIVE;
|
||||
buf->count = q->count++;
|
||||
mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
|
||||
buf->count = cx88q->count++;
|
||||
mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT);
|
||||
dprintk(0,"[%p/%d] %s - first active\n",
|
||||
buf, buf->vb.i, __FUNCTION__);
|
||||
|
||||
} else {
|
||||
dprintk( 1, "queue is not empty - append to active\n" );
|
||||
prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
|
||||
list_add_tail(&buf->vb.queue,&q->active);
|
||||
prev = list_entry(cx88q->active.prev, struct cx88_buffer, vb.queue);
|
||||
list_add_tail(&buf->vb.queue,&cx88q->active);
|
||||
buf->vb.state = STATE_ACTIVE;
|
||||
buf->count = q->count++;
|
||||
buf->count = cx88q->count++;
|
||||
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
|
||||
dprintk( 1, "[%p/%d] %s - append to active\n",
|
||||
buf, buf->vb.i, __FUNCTION__);
|
||||
|
|
|
@ -885,6 +885,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
|
|||
set_audio_standard_BTSC(core, 1, EN_BTSC_FORCE_SAP);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
set_audio_standard_BTSC(core, 0, EN_BTSC_FORCE_STEREO);
|
||||
break;
|
||||
}
|
||||
|
@ -905,6 +906,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
|
|||
EN_NICAM_FORCE_MONO2);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
set_audio_standard_NICAM(core,
|
||||
EN_NICAM_FORCE_STEREO);
|
||||
break;
|
||||
|
@ -926,6 +928,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
|
|||
EN_A2_FORCE_MONO2);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
set_audio_standard_A2(core,
|
||||
EN_A2_FORCE_STEREO);
|
||||
break;
|
||||
|
|
|
@ -175,7 +175,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
|||
buf->vb.size = size;
|
||||
buf->vb.field = V4L2_FIELD_SEQ_TB;
|
||||
|
||||
if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
|
||||
if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
|
||||
goto fail;
|
||||
cx88_risc_buffer(dev->pci, &buf->risc,
|
||||
buf->vb.dma.sglist,
|
||||
|
@ -187,7 +187,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
|||
return 0;
|
||||
|
||||
fail:
|
||||
cx88_free_buffer(dev->pci,buf);
|
||||
cx88_free_buffer(q,buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -227,9 +227,8 @@ vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
|
|||
static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||
{
|
||||
struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
|
||||
struct cx8800_fh *fh = q->priv_data;
|
||||
|
||||
cx88_free_buffer(fh->dev->pci,buf);
|
||||
cx88_free_buffer(q,buf);
|
||||
}
|
||||
|
||||
struct videobuf_queue_ops cx8800_vbi_qops = {
|
||||
|
|
|
@ -564,7 +564,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
|||
|
||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||
init_buffer = 1;
|
||||
if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
|
||||
if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -614,7 +614,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
|||
return 0;
|
||||
|
||||
fail:
|
||||
cx88_free_buffer(dev->pci,buf);
|
||||
cx88_free_buffer(q,buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -671,9 +671,8 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
|
|||
static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||
{
|
||||
struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
|
||||
struct cx8800_fh *fh = q->priv_data;
|
||||
|
||||
cx88_free_buffer(fh->dev->pci,buf);
|
||||
cx88_free_buffer(q,buf);
|
||||
}
|
||||
|
||||
static struct videobuf_queue_ops cx8800_video_qops = {
|
||||
|
@ -1251,10 +1250,18 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
|
|||
{
|
||||
int err;
|
||||
|
||||
dprintk(2, "CORE IOCTL: 0x%x\n", cmd );
|
||||
if (video_debug > 1)
|
||||
if (video_debug) {
|
||||
if (video_debug > 1) {
|
||||
if (_IOC_DIR(cmd) & _IOC_WRITE)
|
||||
v4l_printk_ioctl_arg("cx88(w)",cmd, arg);
|
||||
else if (!_IOC_DIR(cmd) & _IOC_READ) {
|
||||
v4l_print_ioctl("cx88", cmd);
|
||||
}
|
||||
} else
|
||||
v4l_print_ioctl(core->name,cmd);
|
||||
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
/* ---------- tv norms ---------- */
|
||||
case VIDIOC_ENUMSTD:
|
||||
|
@ -1460,7 +1467,19 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
|
|||
static int video_ioctl(struct inode *inode, struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
return video_usercopy(inode, file, cmd, arg, video_do_ioctl);
|
||||
int retval;
|
||||
|
||||
retval=video_usercopy(inode, file, cmd, arg, video_do_ioctl);
|
||||
|
||||
if (video_debug > 1) {
|
||||
if (retval < 0) {
|
||||
v4l_print_ioctl("cx88(err)", cmd);
|
||||
printk(KERN_DEBUG "cx88(err): errcode=%d\n",retval);
|
||||
} else if (_IOC_DIR(cmd) & _IOC_READ)
|
||||
v4l_printk_ioctl_arg("cx88(r)",cmd, (void *)arg);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------- */
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
#include <media/tuner.h>
|
||||
#include <media/tveeprom.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/video-buf.h>
|
||||
#include <media/video-buf-dvb.h>
|
||||
|
||||
|
@ -485,7 +484,7 @@ extern int
|
|||
cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
|
||||
u32 reg, u32 mask, u32 value);
|
||||
extern void
|
||||
cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf);
|
||||
cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf);
|
||||
|
||||
extern void cx88_risc_disasm(struct cx88_core *core,
|
||||
struct btcx_riscmem *risc);
|
||||
|
@ -577,8 +576,8 @@ void cx88_ir_irq(struct cx88_core *core);
|
|||
/* ----------------------------------------------------------- */
|
||||
/* cx88-mpeg.c */
|
||||
|
||||
int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
|
||||
enum v4l2_field field);
|
||||
int cx8802_buf_prepare(struct videobuf_queue *q,struct cx8802_dev *dev,
|
||||
struct cx88_buffer *buf, enum v4l2_field field);
|
||||
void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf);
|
||||
void cx8802_cancel_buffers(struct cx8802_dev *dev);
|
||||
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
#include <linux/i2c.h>
|
||||
#include <linux/usb.h>
|
||||
#include <media/tuner.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/msp3400.h>
|
||||
#include <media/tveeprom.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include "msp3400.h"
|
||||
|
||||
#include "em28xx.h"
|
||||
|
||||
|
@ -147,11 +147,12 @@ struct em28xx_board em28xx_boards[] = {
|
|||
.input = {{
|
||||
.type = EM28XX_VMUX_TELEVISION,
|
||||
.vmux = 0,
|
||||
.amux = 6,
|
||||
.amux = MSP_INPUT_DEFAULT,
|
||||
},{
|
||||
.type = EM28XX_VMUX_SVIDEO,
|
||||
.vmux = 2,
|
||||
.amux = 1,
|
||||
.amux = MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1,
|
||||
MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART),
|
||||
}},
|
||||
},
|
||||
[EM2820_BOARD_MSI_VOX_USB_2] = {
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "em28xx.h"
|
||||
#include <media/tuner.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/msp3400.h>
|
||||
|
||||
#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
|
||||
"Markus Rechberger <mrechberger@gmail.com>, " \
|
||||
|
@ -216,9 +217,14 @@ static void video_mux(struct em28xx *dev, int index)
|
|||
em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput);
|
||||
|
||||
if (dev->has_msp34xx) {
|
||||
struct v4l2_routing route;
|
||||
|
||||
if (dev->i2s_speed)
|
||||
em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed);
|
||||
em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput);
|
||||
route.input = dev->ctl_ainput;
|
||||
route.output = MSP_OUTPUT(MSP_OUT_SCART1_DA);
|
||||
/* Note: this is msp3400 specific */
|
||||
em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route);
|
||||
ainput = EM28XX_AUDIO_SRC_TUNER;
|
||||
em28xx_audio_source(dev, ainput);
|
||||
} else {
|
||||
|
|
4
drivers/media/video/et61x251/Makefile
Normal file
4
drivers/media/video/et61x251/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
et61x251-objs := et61x251_core.o et61x251_tas5130d1b.o
|
||||
|
||||
obj-$(CONFIG_USB_ET61X251) += et61x251.o
|
||||
|
407
drivers/media/video/font.h
Normal file
407
drivers/media/video/font.h
Normal file
|
@ -0,0 +1,407 @@
|
|||
static unsigned char rom8x16_bits[] = {
|
||||
/* Character 0 (0x30):
|
||||
ht=16, width=8
|
||||
+--------+
|
||||
| |
|
||||
| |
|
||||
| ***** |
|
||||
|** ** |
|
||||
|** ** |
|
||||
|** *** |
|
||||
|** **** |
|
||||
|**** ** |
|
||||
|*** ** |
|
||||
|** ** |
|
||||
|** ** |
|
||||
| ***** |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+--------+ */
|
||||
0x00,
|
||||
0x00,
|
||||
0x7c,
|
||||
0xc6,
|
||||
0xc6,
|
||||
0xce,
|
||||
0xde,
|
||||
0xf6,
|
||||
0xe6,
|
||||
0xc6,
|
||||
0xc6,
|
||||
0x7c,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
|
||||
/* Character 1 (0x31):
|
||||
ht=16, width=8
|
||||
+--------+
|
||||
| |
|
||||
| |
|
||||
| ** |
|
||||
| **** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ****** |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+--------+ */
|
||||
0x00,
|
||||
0x00,
|
||||
0x18,
|
||||
0x78,
|
||||
0x18,
|
||||
0x18,
|
||||
0x18,
|
||||
0x18,
|
||||
0x18,
|
||||
0x18,
|
||||
0x18,
|
||||
0x7e,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
|
||||
/* Character 2 (0x32):
|
||||
ht=16, width=8
|
||||
+--------+
|
||||
| |
|
||||
| |
|
||||
| ***** |
|
||||
|** ** |
|
||||
|** ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
|** ** |
|
||||
|******* |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+--------+ */
|
||||
0x00,
|
||||
0x00,
|
||||
0x7c,
|
||||
0xc6,
|
||||
0xc6,
|
||||
0x06,
|
||||
0x0c,
|
||||
0x18,
|
||||
0x30,
|
||||
0x60,
|
||||
0xc6,
|
||||
0xfe,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
|
||||
/* Character 3 (0x33):
|
||||
ht=16, width=8
|
||||
+--------+
|
||||
| |
|
||||
| |
|
||||
| ***** |
|
||||
|** ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| **** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
|** ** |
|
||||
| ***** |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+--------+ */
|
||||
0x00,
|
||||
0x00,
|
||||
0x7c,
|
||||
0xc6,
|
||||
0x06,
|
||||
0x06,
|
||||
0x3c,
|
||||
0x06,
|
||||
0x06,
|
||||
0x06,
|
||||
0xc6,
|
||||
0x7c,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
|
||||
/* Character 4 (0x34):
|
||||
ht=16, width=8
|
||||
+--------+
|
||||
| |
|
||||
| |
|
||||
| ** |
|
||||
| *** |
|
||||
| **** |
|
||||
| ** ** |
|
||||
|** ** |
|
||||
|** ** |
|
||||
|******* |
|
||||
| ** |
|
||||
| ** |
|
||||
| **** |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+--------+ */
|
||||
0x00,
|
||||
0x00,
|
||||
0x0c,
|
||||
0x1c,
|
||||
0x3c,
|
||||
0x6c,
|
||||
0xcc,
|
||||
0xcc,
|
||||
0xfe,
|
||||
0x0c,
|
||||
0x0c,
|
||||
0x1e,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
|
||||
/* Character 5 (0x35):
|
||||
ht=16, width=8
|
||||
+--------+
|
||||
| |
|
||||
| |
|
||||
|******* |
|
||||
|** |
|
||||
|** |
|
||||
|** |
|
||||
|****** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
|** ** |
|
||||
| ***** |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+--------+ */
|
||||
0x00,
|
||||
0x00,
|
||||
0xfe,
|
||||
0xc0,
|
||||
0xc0,
|
||||
0xc0,
|
||||
0xfc,
|
||||
0x06,
|
||||
0x06,
|
||||
0x06,
|
||||
0xc6,
|
||||
0x7c,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
|
||||
/* Character 6 (0x36):
|
||||
ht=16, width=8
|
||||
+--------+
|
||||
| |
|
||||
| |
|
||||
| ***** |
|
||||
|** ** |
|
||||
|** |
|
||||
|** |
|
||||
|****** |
|
||||
|** ** |
|
||||
|** ** |
|
||||
|** ** |
|
||||
|** ** |
|
||||
| ***** |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+--------+ */
|
||||
0x00,
|
||||
0x00,
|
||||
0x7c,
|
||||
0xc6,
|
||||
0xc0,
|
||||
0xc0,
|
||||
0xfc,
|
||||
0xc6,
|
||||
0xc6,
|
||||
0xc6,
|
||||
0xc6,
|
||||
0x7c,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
|
||||
/* Character 7 (0x37):
|
||||
ht=16, width=8
|
||||
+--------+
|
||||
| |
|
||||
| |
|
||||
|******* |
|
||||
|** ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| ** |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+--------+ */
|
||||
0x00,
|
||||
0x00,
|
||||
0xfe,
|
||||
0xc6,
|
||||
0x06,
|
||||
0x0c,
|
||||
0x18,
|
||||
0x30,
|
||||
0x30,
|
||||
0x30,
|
||||
0x30,
|
||||
0x30,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
|
||||
/* Character 8 (0x38):
|
||||
ht=16, width=8
|
||||
+--------+
|
||||
| |
|
||||
| |
|
||||
| ***** |
|
||||
|** ** |
|
||||
|** ** |
|
||||
|** ** |
|
||||
| ***** |
|
||||
|** ** |
|
||||
|** ** |
|
||||
|** ** |
|
||||
|** ** |
|
||||
| ***** |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+--------+ */
|
||||
0x00,
|
||||
0x00,
|
||||
0x7c,
|
||||
0xc6,
|
||||
0xc6,
|
||||
0xc6,
|
||||
0x7c,
|
||||
0xc6,
|
||||
0xc6,
|
||||
0xc6,
|
||||
0xc6,
|
||||
0x7c,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
|
||||
/* Character 9 (0x39):
|
||||
ht=16, width=8
|
||||
+--------+
|
||||
| |
|
||||
| |
|
||||
| ***** |
|
||||
|** ** |
|
||||
|** ** |
|
||||
|** ** |
|
||||
|** ** |
|
||||
| ****** |
|
||||
| ** |
|
||||
| ** |
|
||||
|** ** |
|
||||
| ***** |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+--------+ */
|
||||
0x00,
|
||||
0x00,
|
||||
0x7c,
|
||||
0xc6,
|
||||
0xc6,
|
||||
0xc6,
|
||||
0xc6,
|
||||
0x7e,
|
||||
0x06,
|
||||
0x06,
|
||||
0xc6,
|
||||
0x7c,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
/* Character : (0x3a):
|
||||
ht=16, width=8
|
||||
+--------+
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| ** |
|
||||
| ** |
|
||||
| |
|
||||
| |
|
||||
| ** |
|
||||
| ** |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+--------+ */
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x0c,
|
||||
0x0c,
|
||||
0x00,
|
||||
0x00,
|
||||
0x0c,
|
||||
0x0c,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
|
@ -53,10 +53,11 @@
|
|||
#include <linux/videodev.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/tvaudio.h>
|
||||
#include <media/msp3400.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/suspend.h>
|
||||
#include "msp3400.h"
|
||||
#include "msp3400-driver.h"
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
|
@ -245,17 +246,17 @@ int msp_write_dsp(struct i2c_client *client, int addr, int val)
|
|||
* ----------------------------------------------------------------------- */
|
||||
|
||||
static int scarts[3][9] = {
|
||||
/* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */
|
||||
/* MASK IN1 IN2 IN3 IN4 IN1_DA IN2_DA MONO MUTE */
|
||||
/* SCART DSP Input select */
|
||||
{ 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 },
|
||||
{ 0x0320, 0x0000, 0x0200, 0x0300, 0x0020, -1, -1, 0x0100, 0x0320 },
|
||||
/* SCART1 Output select */
|
||||
{ 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
|
||||
{ 0x0c40, 0x0440, 0x0400, 0x0000, 0x0840, 0x0c00, 0x0040, 0x0800, 0x0c40 },
|
||||
/* SCART2 Output select */
|
||||
{ 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
|
||||
{ 0x3080, 0x1000, 0x1080, 0x2080, 0x3080, 0x0000, 0x0080, 0x2000, 0x3000 },
|
||||
};
|
||||
|
||||
static char *scart_names[] = {
|
||||
"mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
|
||||
"in1", "in2", "in3", "in4", "in1 da", "in2 da", "mono", "mute"
|
||||
};
|
||||
|
||||
void msp_set_scart(struct i2c_client *client, int in, int out)
|
||||
|
@ -264,12 +265,12 @@ void msp_set_scart(struct i2c_client *client, int in, int out)
|
|||
|
||||
state->in_scart = in;
|
||||
|
||||
if (in >= 1 && in <= 8 && out >= 0 && out <= 2) {
|
||||
if (-1 == scarts[out][in])
|
||||
if (in >= 0 && in <= 7 && out >= 0 && out <= 2) {
|
||||
if (-1 == scarts[out][in + 1])
|
||||
return;
|
||||
|
||||
state->acb &= ~scarts[out][SCART_MASK];
|
||||
state->acb |= scarts[out][in];
|
||||
state->acb &= ~scarts[out][0];
|
||||
state->acb |= scarts[out][in + 1];
|
||||
} else
|
||||
state->acb = 0xf60; /* Mute Input and SCART 1 Output */
|
||||
|
||||
|
@ -336,37 +337,6 @@ void msp_set_audio(struct i2c_client *client)
|
|||
msp_write_dsp(client, 0x0033, loudness);
|
||||
}
|
||||
|
||||
int msp_modus(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
|
||||
if (state->radio) {
|
||||
v4l_dbg(1, msp_debug, client, "video mode selected to Radio\n");
|
||||
return 0x0003;
|
||||
}
|
||||
|
||||
if (state->v4l2_std & V4L2_STD_PAL) {
|
||||
v4l_dbg(1, msp_debug, client, "video mode selected to PAL\n");
|
||||
|
||||
#if 1
|
||||
/* experimental: not sure this works with all chip versions */
|
||||
return 0x7003;
|
||||
#else
|
||||
/* previous value, try this if it breaks ... */
|
||||
return 0x1003;
|
||||
#endif
|
||||
}
|
||||
if (state->v4l2_std & V4L2_STD_NTSC) {
|
||||
v4l_dbg(1, msp_debug, client, "video mode selected to NTSC\n");
|
||||
return 0x2003;
|
||||
}
|
||||
if (state->v4l2_std & V4L2_STD_SECAM) {
|
||||
v4l_dbg(1, msp_debug, client, "video mode selected to SECAM\n");
|
||||
return 0x0003;
|
||||
}
|
||||
return 0x0003;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
||||
|
@ -585,51 +555,11 @@ static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
|
|||
static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
u16 *sarg = arg;
|
||||
int scart = 0;
|
||||
|
||||
if (msp_debug >= 2)
|
||||
v4l_i2c_print_ioctl(client, cmd);
|
||||
|
||||
switch (cmd) {
|
||||
case AUDC_SET_INPUT:
|
||||
if (*sarg == state->input)
|
||||
break;
|
||||
state->input = *sarg;
|
||||
switch (*sarg) {
|
||||
case AUDIO_RADIO:
|
||||
/* Hauppauge uses IN2 for the radio */
|
||||
state->mode = MSP_MODE_FM_RADIO;
|
||||
scart = SCART_IN2;
|
||||
break;
|
||||
case AUDIO_EXTERN_1:
|
||||
/* IN1 is often used for external input ... */
|
||||
state->mode = MSP_MODE_EXTERN;
|
||||
scart = SCART_IN1;
|
||||
break;
|
||||
case AUDIO_EXTERN_2:
|
||||
/* ... sometimes it is IN2 through ;) */
|
||||
state->mode = MSP_MODE_EXTERN;
|
||||
scart = SCART_IN2;
|
||||
break;
|
||||
case AUDIO_TUNER:
|
||||
state->mode = -1;
|
||||
break;
|
||||
default:
|
||||
if (*sarg & AUDIO_MUTE)
|
||||
msp_set_scart(client, SCART_MUTE, 0);
|
||||
break;
|
||||
}
|
||||
if (scart) {
|
||||
state->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
||||
msp_set_scart(client, scart, 0);
|
||||
msp_write_dsp(client, 0x000d, 0x1900);
|
||||
if (state->opmode != OPMODE_AUTOSELECT)
|
||||
msp_set_audmode(client);
|
||||
}
|
||||
msp_wake_thread(client);
|
||||
break;
|
||||
|
||||
case AUDC_SET_RADIO:
|
||||
if (state->radio)
|
||||
return 0;
|
||||
|
@ -692,6 +622,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
|||
|
||||
if (va->mode != 0 && state->radio == 0) {
|
||||
state->audmode = msp_mode_v4l1_to_v4l2(va->mode);
|
||||
msp_set_audmode(client);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -728,15 +659,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
|||
break;
|
||||
}
|
||||
|
||||
/* msp34xx specific */
|
||||
case MSP_SET_MATRIX:
|
||||
{
|
||||
struct msp_matrix *mspm = arg;
|
||||
|
||||
msp_set_scart(client, mspm->input, mspm->output);
|
||||
break;
|
||||
}
|
||||
|
||||
/* --- v4l2 ioctls --- */
|
||||
case VIDIOC_S_STD:
|
||||
{
|
||||
|
@ -750,90 +672,34 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
case VIDIOC_ENUMINPUT:
|
||||
case VIDIOC_INT_G_AUDIO_ROUTING:
|
||||
{
|
||||
struct v4l2_input *i = arg;
|
||||
struct v4l2_routing *rt = arg;
|
||||
|
||||
if (i->index != 0)
|
||||
return -EINVAL;
|
||||
|
||||
i->type = V4L2_INPUT_TYPE_TUNER;
|
||||
switch (i->index) {
|
||||
case AUDIO_RADIO:
|
||||
strcpy(i->name, "Radio");
|
||||
*rt = state->routing;
|
||||
break;
|
||||
case AUDIO_EXTERN_1:
|
||||
strcpy(i->name, "Extern 1");
|
||||
break;
|
||||
case AUDIO_EXTERN_2:
|
||||
strcpy(i->name, "Extern 2");
|
||||
break;
|
||||
case AUDIO_TUNER:
|
||||
strcpy(i->name, "Television");
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case VIDIOC_G_AUDIO:
|
||||
case VIDIOC_INT_S_AUDIO_ROUTING:
|
||||
{
|
||||
struct v4l2_audio *a = arg;
|
||||
struct v4l2_routing *rt = arg;
|
||||
int tuner = (rt->input >> 3) & 1;
|
||||
int sc_in = rt->input & 0x7;
|
||||
int sc1_out = rt->output & 0xf;
|
||||
int sc2_out = (rt->output >> 4) & 0xf;
|
||||
u16 val;
|
||||
|
||||
memset(a, 0, sizeof(*a));
|
||||
|
||||
switch (a->index) {
|
||||
case AUDIO_RADIO:
|
||||
strcpy(a->name, "Radio");
|
||||
break;
|
||||
case AUDIO_EXTERN_1:
|
||||
strcpy(a->name, "Extern 1");
|
||||
break;
|
||||
case AUDIO_EXTERN_2:
|
||||
strcpy(a->name, "Extern 2");
|
||||
break;
|
||||
case AUDIO_TUNER:
|
||||
strcpy(a->name, "Television");
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
a->capability = V4L2_AUDCAP_STEREO;
|
||||
a->mode = 0; /* TODO: add support for AVL */
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOC_S_AUDIO:
|
||||
{
|
||||
struct v4l2_audio *sarg = arg;
|
||||
|
||||
switch (sarg->index) {
|
||||
case AUDIO_RADIO:
|
||||
/* Hauppauge uses IN2 for the radio */
|
||||
state->mode = MSP_MODE_FM_RADIO;
|
||||
scart = SCART_IN2;
|
||||
break;
|
||||
case AUDIO_EXTERN_1:
|
||||
/* IN1 is often used for external input ... */
|
||||
state->mode = MSP_MODE_EXTERN;
|
||||
scart = SCART_IN1;
|
||||
break;
|
||||
case AUDIO_EXTERN_2:
|
||||
/* ... sometimes it is IN2 through ;) */
|
||||
state->mode = MSP_MODE_EXTERN;
|
||||
scart = SCART_IN2;
|
||||
break;
|
||||
case AUDIO_TUNER:
|
||||
state->mode = -1;
|
||||
break;
|
||||
}
|
||||
if (scart) {
|
||||
state->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
||||
msp_set_scart(client, scart, 0);
|
||||
msp_write_dsp(client, 0x000d, 0x1900);
|
||||
state->routing = *rt;
|
||||
if (state->opmode == OPMODE_AUTOSELECT) {
|
||||
val = msp_read_dem(client, 0x30) & ~0x100;
|
||||
msp_write_dem(client, 0x30, val | (tuner ? 0x100 : 0));
|
||||
} else {
|
||||
val = msp_read_dem(client, 0xbb) & ~0x100;
|
||||
msp_write_dem(client, 0xbb, val | (tuner ? 0x100 : 0));
|
||||
}
|
||||
msp_set_scart(client, sc_in, 0);
|
||||
msp_set_scart(client, sc1_out, 1);
|
||||
msp_set_scart(client, sc2_out, 2);
|
||||
msp_set_audmode(client);
|
||||
msp_wake_thread(client);
|
||||
break;
|
||||
|
@ -866,42 +732,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
|||
break;
|
||||
}
|
||||
|
||||
case VIDIOC_G_AUDOUT:
|
||||
{
|
||||
struct v4l2_audioout *a = (struct v4l2_audioout *)arg;
|
||||
int idx = a->index;
|
||||
|
||||
memset(a, 0, sizeof(*a));
|
||||
|
||||
switch (idx) {
|
||||
case 0:
|
||||
strcpy(a->name, "Scart1 Out");
|
||||
break;
|
||||
case 1:
|
||||
strcpy(a->name, "Scart2 Out");
|
||||
break;
|
||||
case 2:
|
||||
strcpy(a->name, "I2S Out");
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOC_S_AUDOUT:
|
||||
{
|
||||
struct v4l2_audioout *a = (struct v4l2_audioout *)arg;
|
||||
|
||||
if (a->index < 0 || a->index > 2)
|
||||
return -EINVAL;
|
||||
|
||||
v4l_dbg(1, msp_debug, client, "Setting audio out on msp34xx to input %i\n", a->index);
|
||||
msp_set_scart(client, state->in_scart, a->index + 1);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOC_INT_I2S_CLOCK_FREQ:
|
||||
{
|
||||
u32 *a = (u32 *)arg;
|
||||
|
@ -979,12 +809,16 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
|||
(state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
|
||||
(state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
|
||||
} else {
|
||||
if (state->opmode == OPMODE_AUTODETECT)
|
||||
v4l_info(client, "Mode: %s\n", p);
|
||||
v4l_info(client, "Standard: %s (%s%s)\n",
|
||||
msp_standard_std_name(state->std),
|
||||
(state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
|
||||
(state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
|
||||
}
|
||||
v4l_info(client, "Audmode: 0x%04x\n", state->audmode);
|
||||
v4l_info(client, "Routing: 0x%08x (input) 0x%08x (output)\n",
|
||||
state->routing.input, state->routing.output);
|
||||
v4l_info(client, "ACB: 0x%04x\n", state->acb);
|
||||
break;
|
||||
}
|
||||
|
@ -1063,6 +897,9 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
|
|||
state->muted = 0;
|
||||
state->i2s_mode = 0;
|
||||
init_waitqueue_head(&state->wq);
|
||||
/* These are the reset input/output positions */
|
||||
state->routing.input = MSP_INPUT_DEFAULT;
|
||||
state->routing.output = MSP_OUTPUT_DEFAULT;
|
||||
|
||||
state->rev1 = msp_read_dsp(client, 0x1e);
|
||||
if (state->rev1 != -1)
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
*/
|
||||
|
||||
#ifndef MSP3400_H
|
||||
#define MSP3400_H
|
||||
#ifndef MSP3400_DRIVER_H
|
||||
#define MSP3400_DRIVER_H
|
||||
|
||||
#include <media/msp3400.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
|
@ -20,15 +22,14 @@
|
|||
#define MSP_MODE_BTSC 8
|
||||
#define MSP_MODE_EXTERN 9
|
||||
|
||||
#define SCART_MASK 0
|
||||
#define SCART_IN1 1
|
||||
#define SCART_IN2 2
|
||||
#define SCART_IN1_DA 3
|
||||
#define SCART_IN2_DA 4
|
||||
#define SCART_IN3 5
|
||||
#define SCART_IN4 6
|
||||
#define SCART_MONO 7
|
||||
#define SCART_MUTE 8
|
||||
#define SCART_IN1 0
|
||||
#define SCART_IN2 1
|
||||
#define SCART_IN3 2
|
||||
#define SCART_IN4 3
|
||||
#define SCART_IN1_DA 4
|
||||
#define SCART_IN2_DA 5
|
||||
#define SCART_MONO 6
|
||||
#define SCART_MUTE 7
|
||||
|
||||
#define SCART_DSP_IN 0
|
||||
#define SCART1_OUT 1
|
||||
|
@ -73,7 +74,7 @@ struct msp_state {
|
|||
int i2s_mode;
|
||||
int main, second; /* sound carrier */
|
||||
int input;
|
||||
int source; /* see msp34xxg_set_source */
|
||||
struct v4l2_routing routing;
|
||||
|
||||
/* v4l2 */
|
||||
int audmode;
|
||||
|
@ -99,17 +100,16 @@ int msp_reset(struct i2c_client *client);
|
|||
void msp_set_scart(struct i2c_client *client, int in, int out);
|
||||
void msp_set_mute(struct i2c_client *client);
|
||||
void msp_set_audio(struct i2c_client *client);
|
||||
int msp_modus(struct i2c_client *client);
|
||||
int msp_sleep(struct msp_state *state, int timeout);
|
||||
|
||||
/* msp3400-kthreads.c */
|
||||
const char *msp_standard_std_name(int std);
|
||||
void msp_set_audmode(struct i2c_client *client);
|
||||
void msp_detect_stereo(struct i2c_client *client);
|
||||
int msp_detect_stereo(struct i2c_client *client);
|
||||
int msp3400c_thread(void *data);
|
||||
int msp3410d_thread(void *data);
|
||||
int msp34xxg_thread(void *data);
|
||||
void msp3400c_set_mode(struct i2c_client *client, int mode);
|
||||
void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2);
|
||||
|
||||
#endif /* MSP3400_H */
|
||||
#endif /* MSP3400_DRIVER_H */
|
|
@ -26,10 +26,10 @@
|
|||
#include <linux/videodev.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/msp3400.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/suspend.h>
|
||||
#include "msp3400.h"
|
||||
#include "msp3400-driver.h"
|
||||
|
||||
/* this one uses the automatic sound standard detection of newer msp34xx
|
||||
chip versions */
|
||||
|
@ -45,11 +45,13 @@ static struct {
|
|||
{ 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" },
|
||||
{ 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" },
|
||||
{ 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" },
|
||||
{ 0x0007, MSP_CARRIER(6.5), MSP_CARRIER(5.7421875), "6.5/5.74 D/K3 Dual FM-Stereo" },
|
||||
{ 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" },
|
||||
{ 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" },
|
||||
{ 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" },
|
||||
{ 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" },
|
||||
{ 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" },
|
||||
{ 0x000d, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV3)" },
|
||||
{ 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" },
|
||||
{ 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" },
|
||||
{ 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" },
|
||||
|
@ -185,13 +187,14 @@ void msp3400c_set_mode(struct i2c_client *client, int mode)
|
|||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode];
|
||||
int tuner = (state->routing.input >> 3) & 1;
|
||||
int i;
|
||||
|
||||
v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode);
|
||||
state->mode = mode;
|
||||
state->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
|
||||
msp_write_dem(client, 0x00bb, data->ad_cv);
|
||||
msp_write_dem(client, 0x00bb, data->ad_cv | (tuner ? 0x100 : 0));
|
||||
|
||||
for (i = 5; i >= 0; i--) /* fir 1 */
|
||||
msp_write_dem(client, 0x0001, data->fir1[i]);
|
||||
|
@ -207,21 +210,22 @@ void msp3400c_set_mode(struct i2c_client *client, int mode)
|
|||
msp3400c_set_carrier(client, data->cdo1, data->cdo2);
|
||||
|
||||
msp_set_source(client, data->dsp_src);
|
||||
msp_write_dsp(client, 0x000e, data->dsp_matrix);
|
||||
/* set prescales */
|
||||
|
||||
if (state->has_nicam) {
|
||||
/* nicam prescale */
|
||||
msp_write_dsp(client, 0x0010, 0x5a00); /* was: 0x3000 */
|
||||
}
|
||||
/* volume prescale for SCART (AM mono input) */
|
||||
msp_write_dsp(client, 0x000d, 0x1900);
|
||||
msp_write_dsp(client, 0x000e, data->dsp_matrix);
|
||||
if (state->has_nicam) /* nicam prescale */
|
||||
msp_write_dsp(client, 0x0010, 0x5a00);
|
||||
}
|
||||
|
||||
/* Set audio mode. Note that the pre-'G' models do not support BTSC+SAP,
|
||||
nor do they support stereo BTSC. */
|
||||
static void msp3400c_set_audmode(struct i2c_client *client)
|
||||
{
|
||||
static char *strmode[] = { "mono", "stereo", "lang2", "lang1" };
|
||||
static char *strmode[] = { "mono", "stereo", "lang2", "lang1", "lang1+lang2" };
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
char *modestr = (state->audmode >= 0 && state->audmode < 4) ?
|
||||
char *modestr = (state->audmode >= 0 && state->audmode < 5) ?
|
||||
strmode[state->audmode] : "unknown";
|
||||
int src = 0; /* channel source: FM/AM, nicam or SCART */
|
||||
|
||||
|
@ -246,6 +250,7 @@ static void msp3400c_set_audmode(struct i2c_client *client)
|
|||
case V4L2_TUNER_MODE_MONO:
|
||||
case V4L2_TUNER_MODE_LANG1:
|
||||
case V4L2_TUNER_MODE_LANG2:
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
msp_write_dsp(client, 0x000e, 0x3000);
|
||||
break;
|
||||
}
|
||||
|
@ -257,6 +262,7 @@ static void msp3400c_set_audmode(struct i2c_client *client)
|
|||
msp3400c_set_carrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
msp3400c_set_carrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
|
||||
break;
|
||||
case V4L2_TUNER_MODE_LANG1:
|
||||
|
@ -271,7 +277,6 @@ static void msp3400c_set_audmode(struct i2c_client *client)
|
|||
case MSP_MODE_FM_NICAM2:
|
||||
case MSP_MODE_AM_NICAM:
|
||||
v4l_dbg(1, msp_debug, client, "NICAM set_audmode: %s\n",modestr);
|
||||
msp3400c_set_carrier(client, state->second, state->main);
|
||||
if (state->nicam_on)
|
||||
src = 0x0100; /* NICAM */
|
||||
break;
|
||||
|
@ -293,6 +298,7 @@ static void msp3400c_set_audmode(struct i2c_client *client)
|
|||
/* switch audio */
|
||||
switch (state->audmode) {
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
src |= 0x0020;
|
||||
break;
|
||||
case V4L2_TUNER_MODE_MONO:
|
||||
|
@ -427,8 +433,8 @@ static void watch_stereo(struct i2c_client *client)
|
|||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
|
||||
if (msp3400c_detect_stereo(client)) {
|
||||
msp3400c_set_audmode(client);
|
||||
if (msp_detect_stereo(client)) {
|
||||
msp_set_audmode(client);
|
||||
}
|
||||
|
||||
if (msp_once)
|
||||
|
@ -464,7 +470,7 @@ int msp3400c_thread(void *data)
|
|||
|
||||
/* mute */
|
||||
msp_set_mute(client);
|
||||
msp3400c_set_mode(client, MSP_MODE_AM_DETECT /* +1 */ );
|
||||
msp3400c_set_mode(client, MSP_MODE_AM_DETECT);
|
||||
val1 = val2 = 0;
|
||||
max1 = max2 = -1;
|
||||
state->watch_stereo = 0;
|
||||
|
@ -572,8 +578,6 @@ int msp3400c_thread(void *data)
|
|||
state->second = msp3400c_carrier_detect_65[max2].cdo;
|
||||
msp3400c_set_mode(client, MSP_MODE_AM_NICAM);
|
||||
msp3400c_set_carrier(client, state->second, state->main);
|
||||
/* volume prescale for SCART (AM mono input) */
|
||||
msp_write_dsp(client, 0x000d, 0x1900);
|
||||
state->watch_stereo = 1;
|
||||
} else if (max2 == 0 && state->has_nicam) {
|
||||
/* D/K NICAM */
|
||||
|
@ -651,7 +655,8 @@ int msp3410d_thread(void *data)
|
|||
if (msp_sleep(state,200))
|
||||
goto restart;
|
||||
|
||||
/* start autodetect */
|
||||
/* start autodetect. Note: autodetect is not supported for
|
||||
NTSC-M and radio, hence we force the standard in those cases. */
|
||||
if (state->radio)
|
||||
std = 0x40;
|
||||
else
|
||||
|
@ -695,23 +700,19 @@ int msp3410d_thread(void *data)
|
|||
v4l_dbg(1, msp_debug, client, "autodetection failed,"
|
||||
" switching to backup standard: %s (0x%04x)\n",
|
||||
msp_stdlist[8].name ? msp_stdlist[8].name : "unknown",val);
|
||||
val = 0x0009;
|
||||
state->std = val = 0x0009;
|
||||
msp_write_dem(client, 0x20, val);
|
||||
}
|
||||
|
||||
/* set various prescales */
|
||||
msp_write_dsp(client, 0x0d, 0x1900); /* scart */
|
||||
msp_write_dsp(client, 0x0e, 0x2403); /* FM */
|
||||
msp_write_dsp(client, 0x10, 0x5a00); /* nicam */
|
||||
|
||||
/* set stereo */
|
||||
switch (val) {
|
||||
case 0x0008: /* B/G NICAM */
|
||||
case 0x000a: /* I NICAM */
|
||||
if (val == 0x0008)
|
||||
state->mode = MSP_MODE_FM_NICAM1;
|
||||
else
|
||||
case 0x000b: /* D/K NICAM */
|
||||
if (val == 0x000a)
|
||||
state->mode = MSP_MODE_FM_NICAM2;
|
||||
else
|
||||
state->mode = MSP_MODE_FM_NICAM1;
|
||||
/* just turn on stereo */
|
||||
state->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
||||
state->nicam_on = 1;
|
||||
|
@ -739,6 +740,7 @@ int msp3410d_thread(void *data)
|
|||
/* scart routing (this doesn't belong here I think) */
|
||||
msp_set_scart(client,SCART_IN2,0);
|
||||
break;
|
||||
case 0x0002:
|
||||
case 0x0003:
|
||||
case 0x0004:
|
||||
case 0x0005:
|
||||
|
@ -748,12 +750,19 @@ int msp3410d_thread(void *data)
|
|||
break;
|
||||
}
|
||||
|
||||
/* unmute, restore misc registers */
|
||||
msp_set_audio(client);
|
||||
msp_write_dsp(client, 0x13, state->acb);
|
||||
/* set various prescales */
|
||||
msp_write_dsp(client, 0x0d, 0x1900); /* scart */
|
||||
msp_write_dsp(client, 0x0e, 0x3000); /* FM */
|
||||
if (state->has_nicam)
|
||||
msp_write_dsp(client, 0x10, 0x5a00); /* nicam */
|
||||
|
||||
if (state->has_i2s_conf)
|
||||
msp_write_dem(client, 0x40, state->i2s_mode);
|
||||
|
||||
/* unmute, restore misc registers */
|
||||
msp_set_audio(client);
|
||||
|
||||
msp_write_dsp(client, 0x13, state->acb);
|
||||
msp3400c_set_audmode(client);
|
||||
|
||||
/* monitor tv audio mode, the first time don't wait
|
||||
|
@ -772,97 +781,154 @@ int msp3410d_thread(void *data)
|
|||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/* msp34xxG + (autoselect no-thread) */
|
||||
/* this one uses both automatic standard detection and automatic sound */
|
||||
/* select which are available in the newer G versions */
|
||||
/* struct msp: only norm, acb and source are really used in this mode */
|
||||
|
||||
/* set the same 'source' for the loudspeaker, scart and quasi-peak detector
|
||||
* the value for source is the same as bit 15:8 of DSP registers 0x08,
|
||||
* 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B
|
||||
*
|
||||
* this function replaces msp3400c_set_audmode
|
||||
/* msp34xxG + (autoselect no-thread)
|
||||
* this one uses both automatic standard detection and automatic sound
|
||||
* select which are available in the newer G versions
|
||||
* struct msp: only norm, acb and source are really used in this mode
|
||||
*/
|
||||
static void msp34xxg_set_source(struct i2c_client *client, int source)
|
||||
|
||||
static int msp34xxg_modus(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
|
||||
/* fix matrix mode to stereo and let the msp choose what
|
||||
* to output according to 'source', as recommended
|
||||
* for MONO (source==0) downmixing set bit[7:0] to 0x30
|
||||
*/
|
||||
int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20);
|
||||
|
||||
v4l_dbg(1, msp_debug, client, "set source to %d (0x%x)\n", source, value);
|
||||
msp_set_source(client, value);
|
||||
/*
|
||||
* set identification threshold. Personally, I
|
||||
* I set it to a higher value that the default
|
||||
* of 0x190 to ignore noisy stereo signals.
|
||||
* this needs tuning. (recommended range 0x00a0-0x03c0)
|
||||
* 0x7f0 = forced mono mode
|
||||
*/
|
||||
/* a2 threshold for stereo/bilingual */
|
||||
msp_write_dem(client, 0x22, msp_stereo_thresh);
|
||||
state->source = source;
|
||||
if (state->radio) {
|
||||
v4l_dbg(1, msp_debug, client, "selected radio modus\n");
|
||||
return 0x0001;
|
||||
}
|
||||
|
||||
/* (re-)initialize the msp34xxg, according to the current norm in state->norm
|
||||
* return 0 if it worked, -1 if it failed
|
||||
*/
|
||||
static int msp34xxg_reset(struct i2c_client *client)
|
||||
if (state->v4l2_std & V4L2_STD_PAL) {
|
||||
v4l_dbg(1, msp_debug, client, "selected PAL modus\n");
|
||||
return 0x7001;
|
||||
}
|
||||
if (state->v4l2_std == V4L2_STD_NTSC_M_JP) {
|
||||
v4l_dbg(1, msp_debug, client, "selected M (EIA-J) modus\n");
|
||||
return 0x4001;
|
||||
}
|
||||
if (state->v4l2_std == V4L2_STD_NTSC_M_KR) {
|
||||
v4l_dbg(1, msp_debug, client, "selected M (A2) modus\n");
|
||||
return 0x0001;
|
||||
}
|
||||
if (state->v4l2_std & V4L2_STD_MN) {
|
||||
v4l_dbg(1, msp_debug, client, "selected M (BTSC) modus\n");
|
||||
return 0x2001;
|
||||
}
|
||||
if (state->v4l2_std & V4L2_STD_SECAM) {
|
||||
v4l_dbg(1, msp_debug, client, "selected SECAM modus\n");
|
||||
return 0x6001;
|
||||
}
|
||||
return 0x0001;
|
||||
}
|
||||
|
||||
static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
int modus, std;
|
||||
int source, matrix;
|
||||
|
||||
if (msp_reset(client))
|
||||
return -1;
|
||||
switch (state->audmode) {
|
||||
case V4L2_TUNER_MODE_MONO:
|
||||
source = 0; /* mono only */
|
||||
matrix = 0x30;
|
||||
break;
|
||||
case V4L2_TUNER_MODE_LANG1:
|
||||
source = 3; /* stereo or A */
|
||||
matrix = 0x00;
|
||||
break;
|
||||
case V4L2_TUNER_MODE_LANG2:
|
||||
source = 4; /* stereo or B */
|
||||
matrix = 0x10;
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
default:
|
||||
source = 1; /* stereo or A|B */
|
||||
matrix = 0x20;
|
||||
break;
|
||||
}
|
||||
|
||||
if (in == MSP_DSP_OUT_TUNER)
|
||||
source = (source << 8) | 0x20;
|
||||
/* the msp34x2g puts the MAIN_AVC, MAIN and AUX sources in 12, 13, 14
|
||||
instead of 11, 12, 13. So we add one for that msp version. */
|
||||
else if (in >= MSP_DSP_OUT_MAIN_AVC && state->has_dolby_pro_logic)
|
||||
source = ((in + 1) << 8) | matrix;
|
||||
else
|
||||
source = (in << 8) | matrix;
|
||||
|
||||
v4l_dbg(1, msp_debug, client, "set source to %d (0x%x) for output %02x\n",
|
||||
in, source, reg);
|
||||
msp_write_dsp(client, reg, source);
|
||||
}
|
||||
|
||||
static void msp34xxg_set_sources(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
u32 in = state->routing.input;
|
||||
|
||||
msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf);
|
||||
/* quasi-peak detector is set to same input as the loudspeaker (MAIN) */
|
||||
msp34xxg_set_source(client, 0x000c, (in >> 4) & 0xf);
|
||||
msp34xxg_set_source(client, 0x0009, (in >> 8) & 0xf);
|
||||
msp34xxg_set_source(client, 0x000a, (in >> 12) & 0xf);
|
||||
if (state->has_scart23_in_scart2_out)
|
||||
msp34xxg_set_source(client, 0x0041, (in >> 16) & 0xf);
|
||||
msp34xxg_set_source(client, 0x000b, (in >> 20) & 0xf);
|
||||
}
|
||||
|
||||
/* (re-)initialize the msp34xxg */
|
||||
static void msp34xxg_reset(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
int tuner = (state->routing.input >> 3) & 1;
|
||||
int modus;
|
||||
|
||||
/* initialize std to 1 (autodetect) to signal that no standard is
|
||||
selected yet. */
|
||||
state->std = 1;
|
||||
|
||||
msp_reset(client);
|
||||
|
||||
/* make sure that input/output is muted (paranoid mode) */
|
||||
/* ACB, mute DSP input, mute SCART 1 */
|
||||
if (msp_write_dsp(client, 0x13, 0x0f20))
|
||||
return -1;
|
||||
msp_write_dsp(client, 0x13, 0x0f20);
|
||||
|
||||
if (state->has_i2s_conf)
|
||||
msp_write_dem(client, 0x40, state->i2s_mode);
|
||||
|
||||
/* step-by-step initialisation, as described in the manual */
|
||||
modus = msp_modus(client);
|
||||
if (state->radio)
|
||||
std = 0x40;
|
||||
else
|
||||
std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1;
|
||||
modus &= ~0x03; /* STATUS_CHANGE = 0 */
|
||||
modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION = 1 */
|
||||
if (msp_write_dem(client, 0x30, modus))
|
||||
return -1;
|
||||
if (msp_write_dem(client, 0x20, std))
|
||||
return -1;
|
||||
modus = msp34xxg_modus(client);
|
||||
modus |= tuner ? 0x100 : 0;
|
||||
msp_write_dem(client, 0x30, modus);
|
||||
|
||||
/* write the dsps that may have an influence on
|
||||
standard/audio autodetection right now */
|
||||
msp34xxg_set_source(client, state->source);
|
||||
msp34xxg_set_sources(client);
|
||||
|
||||
/* AM/FM Prescale [15:8] 75khz deviation */
|
||||
if (msp_write_dsp(client, 0x0e, 0x3000))
|
||||
return -1;
|
||||
msp_write_dsp(client, 0x0d, 0x1900); /* scart */
|
||||
msp_write_dsp(client, 0x0e, 0x3000); /* FM */
|
||||
if (state->has_nicam)
|
||||
msp_write_dsp(client, 0x10, 0x5a00); /* nicam */
|
||||
|
||||
/* NICAM Prescale 9db gain (as recommended) */
|
||||
if (msp_write_dsp(client, 0x10, 0x5a00))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
/* set identification threshold. Personally, I
|
||||
* I set it to a higher value than the default
|
||||
* of 0x190 to ignore noisy stereo signals.
|
||||
* this needs tuning. (recommended range 0x00a0-0x03c0)
|
||||
* 0x7f0 = forced mono mode
|
||||
*
|
||||
* a2 threshold for stereo/bilingual.
|
||||
* Note: this register is part of the Manual/Compatibility mode.
|
||||
* It is supported by all 'G'-family chips.
|
||||
*/
|
||||
msp_write_dem(client, 0x22, msp_stereo_thresh);
|
||||
}
|
||||
|
||||
int msp34xxg_thread(void *data)
|
||||
{
|
||||
struct i2c_client *client = data;
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
int val, std, i;
|
||||
int val, i;
|
||||
|
||||
v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n");
|
||||
|
||||
state->source = 1; /* default */
|
||||
for (;;) {
|
||||
v4l_dbg(2, msp_debug, client, "msp34xxg thread: sleep\n");
|
||||
msp_sleep(state, -1);
|
||||
|
@ -876,12 +942,14 @@ int msp34xxg_thread(void *data)
|
|||
|
||||
/* setup the chip*/
|
||||
msp34xxg_reset(client);
|
||||
std = msp_standard;
|
||||
if (std != 0x01)
|
||||
state->std = state->radio ? 0x40 : msp_standard;
|
||||
if (state->std != 1)
|
||||
goto unmute;
|
||||
/* start autodetect */
|
||||
msp_write_dem(client, 0x20, state->std);
|
||||
|
||||
/* watch autodetect */
|
||||
v4l_dbg(1, msp_debug, client, "triggered autodetect, waiting for result\n");
|
||||
v4l_dbg(1, msp_debug, client, "started autodetect, waiting for result\n");
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (msp_sleep(state, 100))
|
||||
goto restart;
|
||||
|
@ -889,20 +957,19 @@ int msp34xxg_thread(void *data)
|
|||
/* check results */
|
||||
val = msp_read_dem(client, 0x7e);
|
||||
if (val < 0x07ff) {
|
||||
std = val;
|
||||
state->std = val;
|
||||
break;
|
||||
}
|
||||
v4l_dbg(2, msp_debug, client, "detection still in progress\n");
|
||||
}
|
||||
if (std == 1) {
|
||||
if (state->std == 1) {
|
||||
v4l_dbg(1, msp_debug, client, "detection still in progress after 10 tries. giving up.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
unmute:
|
||||
state->std = std;
|
||||
v4l_dbg(1, msp_debug, client, "current standard: %s (0x%04x)\n",
|
||||
msp_standard_std_name(std), std);
|
||||
v4l_dbg(1, msp_debug, client, "detected standard: %s (0x%04x)\n",
|
||||
msp_standard_std_name(state->std), state->std);
|
||||
|
||||
/* unmute: dispatch sound to scart output, set scart volume */
|
||||
msp_set_audio(client);
|
||||
|
@ -911,20 +978,33 @@ int msp34xxg_thread(void *data)
|
|||
if (msp_write_dsp(client, 0x13, state->acb))
|
||||
return -1;
|
||||
|
||||
if (state->has_i2s_conf)
|
||||
msp_write_dem(client, 0x40, state->i2s_mode);
|
||||
/* the periodic stereo/SAP check is only relevant for
|
||||
the 0x20 standard (BTSC) */
|
||||
if (state->std != 0x20)
|
||||
continue;
|
||||
|
||||
state->watch_stereo = 1;
|
||||
|
||||
/* monitor tv audio mode, the first time don't wait
|
||||
in order to get a quick stereo/SAP update */
|
||||
watch_stereo(client);
|
||||
while (state->watch_stereo) {
|
||||
watch_stereo(client);
|
||||
if (msp_sleep(state, 5000))
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
v4l_dbg(1, msp_debug, client, "thread: exit\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void msp34xxg_detect_stereo(struct i2c_client *client)
|
||||
static int msp34xxg_detect_stereo(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
|
||||
int status = msp_read_dem(client, 0x0200);
|
||||
int is_bilingual = status & 0x100;
|
||||
int is_stereo = status & 0x40;
|
||||
int oldrx = state->rxsubchans;
|
||||
|
||||
state->rxsubchans = 0;
|
||||
if (is_stereo)
|
||||
|
@ -932,42 +1012,31 @@ static void msp34xxg_detect_stereo(struct i2c_client *client)
|
|||
else
|
||||
state->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
if (is_bilingual) {
|
||||
if (state->std == 0x20)
|
||||
state->rxsubchans |= V4L2_TUNER_SUB_SAP;
|
||||
else
|
||||
state->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
|
||||
/* I'm supposed to check whether it's SAP or not
|
||||
* and set only LANG2/SAP in this case. Yet, the MSP
|
||||
* does a lot of work to hide this and handle everything
|
||||
* the same way. I don't want to work around it so unless
|
||||
* this is a problem, I'll handle SAP just like lang1/lang2.
|
||||
*/
|
||||
}
|
||||
v4l_dbg(1, msp_debug, client, "status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
|
||||
status, is_stereo, is_bilingual, state->rxsubchans);
|
||||
return (oldrx != state->rxsubchans);
|
||||
}
|
||||
|
||||
static void msp34xxg_set_audmode(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
int source;
|
||||
|
||||
switch (state->audmode) {
|
||||
case V4L2_TUNER_MODE_MONO:
|
||||
source = 0; /* mono only */
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
source = 1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */
|
||||
/* problem: that could also mean 2 (scart input) */
|
||||
break;
|
||||
case V4L2_TUNER_MODE_LANG1:
|
||||
source = 3; /* stereo or A */
|
||||
break;
|
||||
case V4L2_TUNER_MODE_LANG2:
|
||||
source = 4; /* stereo or B */
|
||||
break;
|
||||
default:
|
||||
source = 1;
|
||||
break;
|
||||
if (state->std == 0x20) {
|
||||
if ((state->rxsubchans & V4L2_TUNER_SUB_SAP) &&
|
||||
(state->audmode == V4L2_TUNER_MODE_STEREO ||
|
||||
state->audmode == V4L2_TUNER_MODE_LANG2)) {
|
||||
msp_write_dem(client, 0x20, 0x21);
|
||||
} else {
|
||||
msp_write_dem(client, 0x20, 0x20);
|
||||
}
|
||||
msp34xxg_set_source(client, source);
|
||||
}
|
||||
|
||||
msp34xxg_set_sources(client);
|
||||
}
|
||||
|
||||
void msp_set_audmode(struct i2c_client *client)
|
||||
|
@ -977,7 +1046,6 @@ void msp_set_audmode(struct i2c_client *client)
|
|||
switch (state->opmode) {
|
||||
case OPMODE_MANUAL:
|
||||
case OPMODE_AUTODETECT:
|
||||
state->watch_stereo = 0;
|
||||
msp3400c_set_audmode(client);
|
||||
break;
|
||||
case OPMODE_AUTOSELECT:
|
||||
|
@ -986,18 +1054,17 @@ void msp_set_audmode(struct i2c_client *client)
|
|||
}
|
||||
}
|
||||
|
||||
void msp_detect_stereo(struct i2c_client *client)
|
||||
int msp_detect_stereo(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
|
||||
switch (state->opmode) {
|
||||
case OPMODE_MANUAL:
|
||||
case OPMODE_AUTODETECT:
|
||||
msp3400c_detect_stereo(client);
|
||||
break;
|
||||
return msp3400c_detect_stereo(client);
|
||||
case OPMODE_AUTOSELECT:
|
||||
msp34xxg_detect_stereo(client);
|
||||
break;
|
||||
return msp34xxg_detect_stereo(client);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -198,13 +198,13 @@ static int mxb_probe(struct saa7146_dev* dev)
|
|||
/* loop through all i2c-devices on the bus and look who is there */
|
||||
list_for_each(item,&mxb->i2c_adapter.clients) {
|
||||
client = list_entry(item, struct i2c_client, list);
|
||||
if( I2C_TEA6420_1 == client->addr )
|
||||
if( I2C_ADDR_TEA6420_1 == client->addr )
|
||||
mxb->tea6420_1 = client;
|
||||
if( I2C_TEA6420_2 == client->addr )
|
||||
if( I2C_ADDR_TEA6420_2 == client->addr )
|
||||
mxb->tea6420_2 = client;
|
||||
if( I2C_TEA6415C_2 == client->addr )
|
||||
mxb->tea6415c = client;
|
||||
if( I2C_TDA9840 == client->addr )
|
||||
if( I2C_ADDR_TDA9840 == client->addr )
|
||||
mxb->tda9840 = client;
|
||||
if( I2C_SAA7111 == client->addr )
|
||||
mxb->saa7111a = client;
|
||||
|
@ -790,6 +790,12 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
|
|||
DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
|
||||
break;
|
||||
}
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2: {
|
||||
mxb->cur_mode = V4L2_TUNER_MODE_LANG1_LANG2;
|
||||
byte = TDA9840_SET_BOTH;
|
||||
DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n"));
|
||||
break;
|
||||
}
|
||||
case V4L2_TUNER_MODE_LANG1: {
|
||||
mxb->cur_mode = V4L2_TUNER_MODE_LANG1;
|
||||
byte = TDA9840_SET_LANG1;
|
||||
|
|
318
drivers/media/video/pwc/pwc-kiara.c
Normal file
318
drivers/media/video/pwc/pwc-kiara.c
Normal file
|
@ -0,0 +1,318 @@
|
|||
/* Linux driver for Philips webcam
|
||||
(C) 2004 Luc Saillard (luc@saillard.org)
|
||||
|
||||
NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
|
||||
driver and thus may have bugs that are not present in the original version.
|
||||
Please send bug reports and support requests to <luc@saillard.org>.
|
||||
The decompression routines have been implemented by reverse-engineering the
|
||||
Nemosoft binary pwcx module. Caveat emptor.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
/* This tables contains entries for the 730/740/750 (Kiara) camera, with
|
||||
4 different qualities (no compression, low, medium, high).
|
||||
It lists the bandwidth requirements for said mode by its alternate interface
|
||||
number. An alternate of 0 means that the mode is unavailable.
|
||||
|
||||
There are 6 * 4 * 4 entries:
|
||||
6 different resolutions subqcif, qsif, qcif, sif, cif, vga
|
||||
6 framerates: 5, 10, 15, 20, 25, 30
|
||||
4 compression modi: none, low, medium, high
|
||||
|
||||
When an uncompressed mode is not available, the next available compressed mode
|
||||
will be chosen (unless the decompressor is absent). Sometimes there are only
|
||||
1 or 2 compressed modes available; in that case entries are duplicated.
|
||||
*/
|
||||
|
||||
|
||||
#include "pwc-kiara.h"
|
||||
#include "pwc-uncompress.h"
|
||||
|
||||
const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] =
|
||||
{
|
||||
/* SQCIF */
|
||||
{
|
||||
/* 5 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 10 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 15 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 20 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 25 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 30 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
},
|
||||
/* QSIF */
|
||||
{
|
||||
/* 5 fps */
|
||||
{
|
||||
{1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
|
||||
{1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
|
||||
{1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
|
||||
{1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
|
||||
},
|
||||
/* 10 fps */
|
||||
{
|
||||
{2, 291, 0, {0x1C, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0x01, 0x80}},
|
||||
{1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
|
||||
{1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
|
||||
{1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
|
||||
},
|
||||
/* 15 fps */
|
||||
{
|
||||
{3, 437, 0, {0x1B, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x01, 0x80}},
|
||||
{2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
|
||||
{2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
|
||||
{1, 192, 420, {0x13, 0xF4, 0x30, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
|
||||
},
|
||||
/* 20 fps */
|
||||
{
|
||||
{4, 589, 0, {0x1A, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4D, 0x02, 0x80}},
|
||||
{3, 448, 730, {0x12, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xC0, 0x01, 0x80}},
|
||||
{2, 292, 476, {0x12, 0xF4, 0x30, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0x01, 0x80}},
|
||||
{1, 192, 312, {0x12, 0xF4, 0x50, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
|
||||
},
|
||||
/* 25 fps */
|
||||
{
|
||||
{5, 703, 0, {0x19, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x02, 0x80}},
|
||||
{3, 447, 610, {0x11, 0xF4, 0x30, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x28, 0xBF, 0x01, 0x80}},
|
||||
{2, 292, 398, {0x11, 0xF4, 0x50, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x28, 0x24, 0x01, 0x80}},
|
||||
{1, 193, 262, {0x11, 0xF4, 0x50, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x28, 0xC1, 0x00, 0x80}},
|
||||
},
|
||||
/* 30 fps */
|
||||
{
|
||||
{8, 874, 0, {0x18, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x6A, 0x03, 0x80}},
|
||||
{5, 704, 730, {0x10, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x28, 0xC0, 0x02, 0x80}},
|
||||
{3, 448, 492, {0x10, 0xF4, 0x30, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x28, 0xC0, 0x01, 0x80}},
|
||||
{2, 292, 320, {0x10, 0xF4, 0x50, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x28, 0x24, 0x01, 0x80}},
|
||||
},
|
||||
},
|
||||
/* QCIF */
|
||||
{
|
||||
/* 5 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 10 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 15 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 20 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 25 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 30 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
},
|
||||
/* SIF */
|
||||
{
|
||||
/* 5 fps */
|
||||
{
|
||||
{4, 582, 0, {0x0D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x02, 0x80}},
|
||||
{3, 387, 1276, {0x05, 0xF4, 0x30, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x01, 0x80}},
|
||||
{2, 291, 960, {0x05, 0xF4, 0x30, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0x01, 0x80}},
|
||||
{1, 191, 630, {0x05, 0xF4, 0x50, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x18, 0xBF, 0x00, 0x80}},
|
||||
},
|
||||
/* 10 fps */
|
||||
{
|
||||
{0, },
|
||||
{6, 775, 1278, {0x04, 0xF4, 0x30, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x03, 0x80}},
|
||||
{3, 447, 736, {0x04, 0xF4, 0x30, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x28, 0xBF, 0x01, 0x80}},
|
||||
{2, 292, 480, {0x04, 0xF4, 0x70, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x28, 0x24, 0x01, 0x80}},
|
||||
},
|
||||
/* 15 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 955, 1050, {0x03, 0xF4, 0x30, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x03, 0x80}},
|
||||
{4, 592, 650, {0x03, 0xF4, 0x30, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x50, 0x02, 0x80}},
|
||||
{3, 448, 492, {0x03, 0xF4, 0x50, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x38, 0xC0, 0x01, 0x80}},
|
||||
},
|
||||
/* 20 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 958, 782, {0x02, 0xF4, 0x30, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x03, 0x80}},
|
||||
{5, 703, 574, {0x02, 0xF4, 0x50, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x02, 0x80}},
|
||||
{3, 446, 364, {0x02, 0xF4, 0x90, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x38, 0xBE, 0x01, 0x80}},
|
||||
},
|
||||
/* 25 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 958, 654, {0x01, 0xF4, 0x30, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x03, 0x80}},
|
||||
{6, 776, 530, {0x01, 0xF4, 0x50, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x03, 0x80}},
|
||||
{4, 592, 404, {0x01, 0xF4, 0x70, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x48, 0x50, 0x02, 0x80}},
|
||||
},
|
||||
/* 30 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 957, 526, {0x00, 0xF4, 0x50, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x03, 0x80}},
|
||||
{6, 775, 426, {0x00, 0xF4, 0x70, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x03, 0x80}},
|
||||
{4, 590, 324, {0x00, 0x7A, 0x88, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x50, 0x4E, 0x02, 0x80}},
|
||||
},
|
||||
},
|
||||
/* CIF */
|
||||
{
|
||||
/* 5 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 10 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 15 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 20 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 25 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 30 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
},
|
||||
/* VGA */
|
||||
{
|
||||
/* 5 fps */
|
||||
{
|
||||
{0, },
|
||||
{6, 773, 1272, {0x25, 0xF4, 0x30, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}},
|
||||
{4, 592, 976, {0x25, 0xF4, 0x50, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x02, 0x80}},
|
||||
{3, 448, 738, {0x25, 0xF4, 0x90, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x01, 0x80}},
|
||||
},
|
||||
/* 10 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 956, 788, {0x24, 0xF4, 0x70, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x03, 0x80}},
|
||||
{6, 776, 640, {0x24, 0xF4, 0xB0, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x03, 0x80}},
|
||||
{4, 592, 488, {0x24, 0x7A, 0xE8, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x02, 0x80}},
|
||||
},
|
||||
/* 15 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
|
||||
{9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
|
||||
{8, 895, 492, {0x23, 0x7A, 0xE8, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x03, 0x80}},
|
||||
},
|
||||
/* 20 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 25 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 30 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
316
drivers/media/video/pwc/pwc-timon.c
Normal file
316
drivers/media/video/pwc/pwc-timon.c
Normal file
|
@ -0,0 +1,316 @@
|
|||
/* Linux driver for Philips webcam
|
||||
(C) 2004 Luc Saillard (luc@saillard.org)
|
||||
|
||||
NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
|
||||
driver and thus may have bugs that are not present in the original version.
|
||||
Please send bug reports and support requests to <luc@saillard.org>.
|
||||
The decompression routines have been implemented by reverse-engineering the
|
||||
Nemosoft binary pwcx module. Caveat emptor.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
/* This tables contains entries for the 675/680/690 (Timon) camera, with
|
||||
4 different qualities (no compression, low, medium, high).
|
||||
It lists the bandwidth requirements for said mode by its alternate interface
|
||||
number. An alternate of 0 means that the mode is unavailable.
|
||||
|
||||
There are 6 * 4 * 4 entries:
|
||||
6 different resolutions subqcif, qsif, qcif, sif, cif, vga
|
||||
6 framerates: 5, 10, 15, 20, 25, 30
|
||||
4 compression modi: none, low, medium, high
|
||||
|
||||
When an uncompressed mode is not available, the next available compressed mode
|
||||
will be chosen (unless the decompressor is absent). Sometimes there are only
|
||||
1 or 2 compressed modes available; in that case entries are duplicated.
|
||||
*/
|
||||
|
||||
#include "pwc-timon.h"
|
||||
|
||||
const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] =
|
||||
{
|
||||
/* SQCIF */
|
||||
{
|
||||
/* 5 fps */
|
||||
{
|
||||
{1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
|
||||
{1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
|
||||
{1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
|
||||
{1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
|
||||
},
|
||||
/* 10 fps */
|
||||
{
|
||||
{2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
|
||||
{2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
|
||||
{2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
|
||||
{2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
|
||||
},
|
||||
/* 15 fps */
|
||||
{
|
||||
{3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
|
||||
{3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
|
||||
{3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
|
||||
{3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
|
||||
},
|
||||
/* 20 fps */
|
||||
{
|
||||
{4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
|
||||
{4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
|
||||
{4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
|
||||
{4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
|
||||
},
|
||||
/* 25 fps */
|
||||
{
|
||||
{5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
|
||||
{5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
|
||||
{5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
|
||||
{5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
|
||||
},
|
||||
/* 30 fps */
|
||||
{
|
||||
{7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
|
||||
{7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
|
||||
{7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
|
||||
{7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
|
||||
},
|
||||
},
|
||||
/* QSIF */
|
||||
{
|
||||
/* 5 fps */
|
||||
{
|
||||
{1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
|
||||
{1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
|
||||
{1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
|
||||
{1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
|
||||
},
|
||||
/* 10 fps */
|
||||
{
|
||||
{2, 291, 0, {0x2C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0xA1, 0xC0, 0x02}},
|
||||
{1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
|
||||
{1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
|
||||
{1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
|
||||
},
|
||||
/* 15 fps */
|
||||
{
|
||||
{3, 437, 0, {0x2B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x6D, 0xC0, 0x02}},
|
||||
{2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
|
||||
{2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
|
||||
{1, 191, 420, {0x2B, 0xF4, 0x0D, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
|
||||
},
|
||||
/* 20 fps */
|
||||
{
|
||||
{4, 588, 0, {0x2A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4C, 0x52, 0xC0, 0x02}},
|
||||
{3, 447, 730, {0x2A, 0xF4, 0x05, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
|
||||
{2, 292, 476, {0x2A, 0xF4, 0x0D, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
|
||||
{1, 192, 312, {0x2A, 0xF4, 0x1D, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}},
|
||||
},
|
||||
/* 25 fps */
|
||||
{
|
||||
{5, 703, 0, {0x29, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x42, 0xC0, 0x02}},
|
||||
{3, 447, 610, {0x29, 0xF4, 0x05, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
|
||||
{2, 292, 398, {0x29, 0xF4, 0x0D, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
|
||||
{1, 192, 262, {0x29, 0xF4, 0x25, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}},
|
||||
},
|
||||
/* 30 fps */
|
||||
{
|
||||
{8, 873, 0, {0x28, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x69, 0x37, 0xC0, 0x02}},
|
||||
{5, 704, 774, {0x28, 0xF4, 0x05, 0x18, 0x21, 0x17, 0x59, 0x0F, 0x18, 0xC0, 0x42, 0xC0, 0x02}},
|
||||
{3, 448, 492, {0x28, 0xF4, 0x05, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x18, 0xC0, 0x69, 0xC0, 0x02}},
|
||||
{2, 291, 320, {0x28, 0xF4, 0x1D, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}},
|
||||
},
|
||||
},
|
||||
/* QCIF */
|
||||
{
|
||||
/* 5 fps */
|
||||
{
|
||||
{1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
|
||||
{1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
|
||||
{1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
|
||||
{1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
|
||||
},
|
||||
/* 10 fps */
|
||||
{
|
||||
{3, 385, 0, {0x0C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x81, 0x79, 0xC0, 0x02}},
|
||||
{2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
|
||||
{2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
|
||||
{1, 194, 532, {0x0C, 0xF4, 0x05, 0x10, 0x9A, 0x0F, 0xBE, 0x1B, 0x08, 0xC2, 0xF0, 0xC0, 0x02}},
|
||||
},
|
||||
/* 15 fps */
|
||||
{
|
||||
{4, 577, 0, {0x0B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x41, 0x52, 0xC0, 0x02}},
|
||||
{3, 447, 818, {0x0B, 0xF4, 0x05, 0x19, 0x89, 0x18, 0xAD, 0x0F, 0x10, 0xBF, 0x69, 0xC0, 0x02}},
|
||||
{2, 292, 534, {0x0B, 0xF4, 0x05, 0x10, 0xA3, 0x0F, 0xC7, 0x19, 0x10, 0x24, 0xA1, 0xC0, 0x02}},
|
||||
{1, 195, 356, {0x0B, 0xF4, 0x15, 0x0B, 0x11, 0x0A, 0x35, 0x1E, 0x10, 0xC3, 0xF0, 0xC0, 0x02}},
|
||||
},
|
||||
/* 20 fps */
|
||||
{
|
||||
{6, 776, 0, {0x0A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x08, 0x3F, 0xC0, 0x02}},
|
||||
{4, 591, 804, {0x0A, 0xF4, 0x05, 0x19, 0x1E, 0x18, 0x42, 0x0F, 0x18, 0x4F, 0x4E, 0xC0, 0x02}},
|
||||
{3, 447, 608, {0x0A, 0xF4, 0x05, 0x12, 0xFD, 0x12, 0x21, 0x15, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
|
||||
{2, 291, 396, {0x0A, 0xF4, 0x15, 0x0C, 0x5E, 0x0B, 0x82, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}},
|
||||
},
|
||||
/* 25 fps */
|
||||
{
|
||||
{9, 928, 0, {0x09, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xA0, 0x33, 0xC0, 0x02}},
|
||||
{5, 703, 800, {0x09, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x10, 0x18, 0xBF, 0x42, 0xC0, 0x02}},
|
||||
{3, 447, 508, {0x09, 0xF4, 0x0D, 0x0F, 0xD2, 0x0E, 0xF6, 0x1B, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
|
||||
{2, 292, 332, {0x09, 0xF4, 0x1D, 0x0A, 0x5A, 0x09, 0x7E, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
|
||||
},
|
||||
/* 30 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 956, 876, {0x08, 0xF4, 0x05, 0x1B, 0x58, 0x1A, 0x7C, 0x0E, 0x20, 0xBC, 0x33, 0x10, 0x02}},
|
||||
{4, 592, 542, {0x08, 0xF4, 0x05, 0x10, 0xE4, 0x10, 0x08, 0x17, 0x20, 0x50, 0x4E, 0x10, 0x02}},
|
||||
{2, 291, 266, {0x08, 0xF4, 0x25, 0x08, 0x48, 0x07, 0x6C, 0x1E, 0x20, 0x23, 0xA1, 0x10, 0x02}},
|
||||
},
|
||||
},
|
||||
/* SIF */
|
||||
{
|
||||
/* 5 fps */
|
||||
{
|
||||
{4, 582, 0, {0x35, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x52, 0x60, 0x02}},
|
||||
{3, 387, 1276, {0x35, 0xF4, 0x05, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x79, 0x60, 0x02}},
|
||||
{2, 291, 960, {0x35, 0xF4, 0x0D, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0xA1, 0x60, 0x02}},
|
||||
{1, 191, 630, {0x35, 0xF4, 0x1D, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x08, 0xBF, 0xF4, 0x60, 0x02}},
|
||||
},
|
||||
/* 10 fps */
|
||||
{
|
||||
{0, },
|
||||
{6, 775, 1278, {0x34, 0xF4, 0x05, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x3F, 0x10, 0x02}},
|
||||
{3, 447, 736, {0x34, 0xF4, 0x15, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x18, 0xBF, 0x69, 0x10, 0x02}},
|
||||
{2, 291, 480, {0x34, 0xF4, 0x2D, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x18, 0x23, 0xA1, 0x10, 0x02}},
|
||||
},
|
||||
/* 15 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 955, 1050, {0x33, 0xF4, 0x05, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x33, 0x10, 0x02}},
|
||||
{4, 591, 650, {0x33, 0xF4, 0x15, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x4F, 0x4E, 0x10, 0x02}},
|
||||
{3, 448, 492, {0x33, 0xF4, 0x25, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x28, 0xC0, 0x69, 0x10, 0x02}},
|
||||
},
|
||||
/* 20 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 958, 782, {0x32, 0xF4, 0x0D, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x33, 0xD0, 0x02}},
|
||||
{5, 703, 574, {0x32, 0xF4, 0x1D, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x42, 0xD0, 0x02}},
|
||||
{3, 446, 364, {0x32, 0xF4, 0x3D, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x30, 0xBE, 0x69, 0xD0, 0x02}},
|
||||
},
|
||||
/* 25 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 958, 654, {0x31, 0xF4, 0x15, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x33, 0x90, 0x02}},
|
||||
{6, 776, 530, {0x31, 0xF4, 0x25, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x3F, 0x90, 0x02}},
|
||||
{4, 592, 404, {0x31, 0xF4, 0x35, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x38, 0x50, 0x4E, 0x90, 0x02}},
|
||||
},
|
||||
/* 30 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 957, 526, {0x30, 0xF4, 0x25, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x33, 0x60, 0x02}},
|
||||
{6, 775, 426, {0x30, 0xF4, 0x35, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x3F, 0x60, 0x02}},
|
||||
{4, 590, 324, {0x30, 0x7A, 0x4B, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x40, 0x4E, 0x52, 0x60, 0x02}},
|
||||
},
|
||||
},
|
||||
/* CIF */
|
||||
{
|
||||
/* 5 fps */
|
||||
{
|
||||
{6, 771, 0, {0x15, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x3F, 0x80, 0x02}},
|
||||
{4, 465, 1278, {0x15, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x03, 0x18, 0xD1, 0x65, 0x80, 0x02}},
|
||||
{2, 291, 800, {0x15, 0xF4, 0x15, 0x18, 0xF4, 0x17, 0x3C, 0x05, 0x18, 0x23, 0xA1, 0x80, 0x02}},
|
||||
{1, 193, 528, {0x15, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x18, 0xC1, 0xF4, 0x80, 0x02}},
|
||||
},
|
||||
/* 10 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 932, 1278, {0x14, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x04, 0x30, 0xA4, 0x33, 0x10, 0x02}},
|
||||
{4, 591, 812, {0x14, 0xF4, 0x15, 0x19, 0x56, 0x17, 0x9E, 0x06, 0x28, 0x4F, 0x4E, 0x10, 0x02}},
|
||||
{2, 291, 400, {0x14, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x28, 0x23, 0xA1, 0x10, 0x02}},
|
||||
},
|
||||
/* 15 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 956, 876, {0x13, 0xF4, 0x0D, 0x1B, 0x58, 0x19, 0xA0, 0x05, 0x38, 0xBC, 0x33, 0x60, 0x02}},
|
||||
{5, 703, 644, {0x13, 0xF4, 0x1D, 0x14, 0x1C, 0x12, 0x64, 0x08, 0x38, 0xBF, 0x42, 0x60, 0x02}},
|
||||
{3, 448, 410, {0x13, 0xF4, 0x3D, 0x0C, 0xC4, 0x0B, 0x0C, 0x0E, 0x38, 0xC0, 0x69, 0x60, 0x02}},
|
||||
},
|
||||
/* 20 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 956, 650, {0x12, 0xF4, 0x1D, 0x14, 0x4A, 0x12, 0x92, 0x09, 0x48, 0xBC, 0x33, 0x10, 0x03}},
|
||||
{6, 776, 528, {0x12, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x40, 0x08, 0x3F, 0x10, 0x03}},
|
||||
{4, 591, 402, {0x12, 0xF4, 0x3D, 0x0C, 0x8F, 0x0A, 0xD7, 0x0E, 0x40, 0x4F, 0x4E, 0x10, 0x03}},
|
||||
},
|
||||
/* 25 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 956, 544, {0x11, 0xF4, 0x25, 0x10, 0xF4, 0x0F, 0x3C, 0x0A, 0x48, 0xBC, 0x33, 0xC0, 0x02}},
|
||||
{7, 840, 478, {0x11, 0xF4, 0x2D, 0x0E, 0xEB, 0x0D, 0x33, 0x0B, 0x48, 0x48, 0x3B, 0xC0, 0x02}},
|
||||
{5, 703, 400, {0x11, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x48, 0xBF, 0x42, 0xC0, 0x02}},
|
||||
},
|
||||
/* 30 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 956, 438, {0x10, 0xF4, 0x35, 0x0D, 0xAC, 0x0B, 0xF4, 0x0D, 0x50, 0xBC, 0x33, 0x10, 0x02}},
|
||||
{7, 838, 384, {0x10, 0xF4, 0x45, 0x0B, 0xFD, 0x0A, 0x45, 0x0F, 0x50, 0x46, 0x3B, 0x10, 0x02}},
|
||||
{6, 773, 354, {0x10, 0x7A, 0x4B, 0x0B, 0x0C, 0x09, 0x80, 0x10, 0x50, 0x05, 0x3F, 0x10, 0x02}},
|
||||
},
|
||||
},
|
||||
/* VGA */
|
||||
{
|
||||
/* 5 fps */
|
||||
{
|
||||
{0, },
|
||||
{6, 773, 1272, {0x1D, 0xF4, 0x15, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x3F, 0x10, 0x02}},
|
||||
{4, 592, 976, {0x1D, 0xF4, 0x25, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x4E, 0x10, 0x02}},
|
||||
{3, 448, 738, {0x1D, 0xF4, 0x3D, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x69, 0x10, 0x02}},
|
||||
},
|
||||
/* 10 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 956, 788, {0x1C, 0xF4, 0x35, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x33, 0x10, 0x02}},
|
||||
{6, 776, 640, {0x1C, 0x7A, 0x53, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x3F, 0x10, 0x02}},
|
||||
{4, 592, 488, {0x1C, 0x7A, 0x6B, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x4E, 0x10, 0x02}},
|
||||
},
|
||||
/* 15 fps */
|
||||
{
|
||||
{0, },
|
||||
{9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}},
|
||||
{9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}},
|
||||
{8, 895, 492, {0x1B, 0x7A, 0x6B, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x37, 0x80, 0x02}},
|
||||
},
|
||||
/* 20 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 25 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
/* 30 fps */
|
||||
{
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
{0, },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
#include <asm/uaccess.h>
|
||||
|
||||
|
||||
#include "rds.h"
|
||||
#include <media/rds.h>
|
||||
|
||||
/* Addresses to scan */
|
||||
static unsigned short normal_i2c[] = {
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include <linux/i2c.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
MODULE_DESCRIPTION("Philips SAA7113/SAA7114/SAA7115 video decoder driver");
|
||||
|
|
|
@ -507,7 +507,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
|
|||
/* release the old buffer */
|
||||
if (substream->runtime->dma_area) {
|
||||
saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
|
||||
videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
|
||||
videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma);
|
||||
dsp_buffer_free(dev);
|
||||
substream->runtime->dma_area = NULL;
|
||||
}
|
||||
|
@ -523,12 +523,12 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
|
|||
return err;
|
||||
}
|
||||
|
||||
if (0 != (err = videobuf_dma_pci_map(dev->pci, &dev->dmasound.dma))) {
|
||||
if (0 != (err = videobuf_pci_dma_map(dev->pci, &dev->dmasound.dma))) {
|
||||
dsp_buffer_free(dev);
|
||||
return err;
|
||||
}
|
||||
if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) {
|
||||
videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
|
||||
videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma);
|
||||
dsp_buffer_free(dev);
|
||||
return err;
|
||||
}
|
||||
|
@ -537,7 +537,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
|
|||
dev->dmasound.dma.sglen,
|
||||
0))) {
|
||||
saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
|
||||
videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
|
||||
videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma);
|
||||
dsp_buffer_free(dev);
|
||||
return err;
|
||||
}
|
||||
|
@ -571,7 +571,7 @@ static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream)
|
|||
|
||||
if (substream->runtime->dma_area) {
|
||||
saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
|
||||
videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
|
||||
videobuf_pci_dma_unmap(dev->pci, &dev->dmasound.dma);
|
||||
dsp_buffer_free(dev);
|
||||
substream->runtime->dma_area = NULL;
|
||||
}
|
||||
|
|
|
@ -254,12 +254,12 @@ void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt)
|
|||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf)
|
||||
void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf)
|
||||
{
|
||||
BUG_ON(in_interrupt());
|
||||
|
||||
videobuf_waiton(&buf->vb,0,0);
|
||||
videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma);
|
||||
videobuf_dma_unmap(q, &buf->vb.dma);
|
||||
videobuf_dma_free(&buf->vb.dma);
|
||||
buf->vb.state = STATE_NEEDS_INIT;
|
||||
}
|
||||
|
@ -960,7 +960,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
|
|||
if (saa7134_no_overlay <= 0) {
|
||||
saa7134_video_template.type |= VID_TYPE_OVERLAY;
|
||||
} else {
|
||||
printk("bttv: Overlay support disabled.\n");
|
||||
printk("%s: Overlay support disabled.\n",dev->name);
|
||||
}
|
||||
dev->video_dev = vdev_init(dev,&saa7134_video_template,"video");
|
||||
err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
|
||||
|
|
|
@ -124,7 +124,7 @@ static int dsp_rec_start(struct saa7134_dev *dev)
|
|||
unsigned long flags;
|
||||
|
||||
/* prepare buffer */
|
||||
if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma)))
|
||||
if (0 != (err = videobuf_pci_dma_map(dev->pci,&dev->dmasound.dma)))
|
||||
return err;
|
||||
if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt)))
|
||||
goto fail1;
|
||||
|
@ -213,7 +213,7 @@ static int dsp_rec_start(struct saa7134_dev *dev)
|
|||
fail2:
|
||||
saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
|
||||
fail1:
|
||||
videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
|
||||
videobuf_pci_dma_unmap(dev->pci,&dev->dmasound.dma);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -231,7 +231,7 @@ static int dsp_rec_stop(struct saa7134_dev *dev)
|
|||
|
||||
/* unlock buffer */
|
||||
saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
|
||||
videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
|
||||
videobuf_pci_dma_unmap(dev->pci,&dev->dmasound.dma);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
|||
return -EINVAL;
|
||||
|
||||
if (buf->vb.size != size) {
|
||||
saa7134_dma_free(dev,buf);
|
||||
saa7134_dma_free(q,buf);
|
||||
}
|
||||
|
||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||
|
@ -98,7 +98,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
|||
buf->vb.size = size;
|
||||
buf->pt = &dev->ts.pt_ts;
|
||||
|
||||
err = videobuf_iolock(dev->pci,&buf->vb,NULL);
|
||||
err = videobuf_iolock(q,&buf->vb,NULL);
|
||||
if (err)
|
||||
goto oops;
|
||||
err = saa7134_pgtable_build(dev->pci,buf->pt,
|
||||
|
@ -126,7 +126,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
|||
return 0;
|
||||
|
||||
oops:
|
||||
saa7134_dma_free(dev,buf);
|
||||
saa7134_dma_free(q,buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -152,10 +152,9 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
|||
|
||||
static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||
{
|
||||
struct saa7134_dev *dev = q->priv_data;
|
||||
struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
|
||||
|
||||
saa7134_dma_free(dev,buf);
|
||||
saa7134_dma_free(q,buf);
|
||||
}
|
||||
|
||||
struct videobuf_queue_ops saa7134_ts_qops = {
|
||||
|
|
|
@ -482,12 +482,14 @@ static int tvaudio_setstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au
|
|||
[ V4L2_TUNER_MODE_STEREO ] = "stereo",
|
||||
[ V4L2_TUNER_MODE_LANG1 ] = "lang1",
|
||||
[ V4L2_TUNER_MODE_LANG2 ] = "lang2",
|
||||
[ V4L2_TUNER_MODE_LANG1_LANG2 ] = "lang1+lang2",
|
||||
};
|
||||
static u32 fm[] = {
|
||||
[ V4L2_TUNER_MODE_MONO ] = 0x00, /* ch1 */
|
||||
[ V4L2_TUNER_MODE_STEREO ] = 0x80, /* auto */
|
||||
[ V4L2_TUNER_MODE_LANG1 ] = 0x00, /* ch1 */
|
||||
[ V4L2_TUNER_MODE_LANG2 ] = 0x01, /* ch2 */
|
||||
[ V4L2_TUNER_MODE_LANG1_LANG2 ] = 0x80, /* auto */
|
||||
};
|
||||
u32 reg;
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
|||
return -EINVAL;
|
||||
|
||||
if (buf->vb.size != size)
|
||||
saa7134_dma_free(dev,buf);
|
||||
saa7134_dma_free(q,buf);
|
||||
|
||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||
buf->vb.width = llength;
|
||||
|
@ -143,7 +143,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
|||
buf->vb.size = size;
|
||||
buf->pt = &fh->pt_vbi;
|
||||
|
||||
err = videobuf_iolock(dev->pci,&buf->vb,NULL);
|
||||
err = videobuf_iolock(q,&buf->vb,NULL);
|
||||
if (err)
|
||||
goto oops;
|
||||
err = saa7134_pgtable_build(dev->pci,buf->pt,
|
||||
|
@ -159,7 +159,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
|||
return 0;
|
||||
|
||||
oops:
|
||||
saa7134_dma_free(dev,buf);
|
||||
saa7134_dma_free(q,buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -190,11 +190,9 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
|||
|
||||
static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||
{
|
||||
struct saa7134_fh *fh = q->priv_data;
|
||||
struct saa7134_dev *dev = fh->dev;
|
||||
struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
|
||||
|
||||
saa7134_dma_free(dev,buf);
|
||||
saa7134_dma_free(q,buf);
|
||||
}
|
||||
|
||||
struct videobuf_queue_ops saa7134_vbi_qops = {
|
||||
|
|
|
@ -993,7 +993,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
|||
buf->vb.size != size ||
|
||||
buf->vb.field != field ||
|
||||
buf->fmt != fh->fmt) {
|
||||
saa7134_dma_free(dev,buf);
|
||||
saa7134_dma_free(q,buf);
|
||||
}
|
||||
|
||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||
|
@ -1004,7 +1004,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
|||
buf->fmt = fh->fmt;
|
||||
buf->pt = &fh->pt_cap;
|
||||
|
||||
err = videobuf_iolock(dev->pci,&buf->vb,&dev->ovbuf);
|
||||
err = videobuf_iolock(q,&buf->vb,&dev->ovbuf);
|
||||
if (err)
|
||||
goto oops;
|
||||
err = saa7134_pgtable_build(dev->pci,buf->pt,
|
||||
|
@ -1019,7 +1019,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
|||
return 0;
|
||||
|
||||
oops:
|
||||
saa7134_dma_free(dev,buf);
|
||||
saa7134_dma_free(q,buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1045,10 +1045,9 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
|||
|
||||
static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||
{
|
||||
struct saa7134_fh *fh = q->priv_data;
|
||||
struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
|
||||
|
||||
saa7134_dma_free(fh->dev,buf);
|
||||
saa7134_dma_free(q,buf);
|
||||
}
|
||||
|
||||
static struct videobuf_queue_ops video_qops = {
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include <asm/io.h>
|
||||
|
||||
#include <media/tuner.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/ir-common.h>
|
||||
#include <media/ir-kbd-i2c.h>
|
||||
#include <media/video-buf.h>
|
||||
|
@ -579,7 +578,7 @@ void saa7134_buffer_finish(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
|
|||
unsigned int state);
|
||||
void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);
|
||||
void saa7134_buffer_timeout(unsigned long data);
|
||||
void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf);
|
||||
void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf);
|
||||
|
||||
int saa7134_set_dmabits(struct saa7134_dev *dev);
|
||||
|
||||
|
|
7
drivers/media/video/sn9c102/Makefile
Normal file
7
drivers/media/video/sn9c102/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o \
|
||||
sn9c102_ov7630.o sn9c102_pas106b.o sn9c102_pas202bca.o \
|
||||
sn9c102_pas202bcb.o sn9c102_tas5110c1b.o \
|
||||
sn9c102_tas5130d1b.o
|
||||
|
||||
obj-$(CONFIG_USB_SN9C102) += sn9c102.o
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue