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:
Linus Torvalds 2006-03-25 08:37:36 -08:00
commit 368d17e068
206 changed files with 7248 additions and 4786 deletions

View file

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

View file

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

View file

@ -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 = {

View file

@ -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 = {

View file

@ -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 = {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View 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.

View 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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 = {

View file

@ -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 */

View file

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

View file

@ -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 */

View file

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

View file

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

View file

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

View file

@ -18,7 +18,6 @@
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/audiochip.h>
#include <media/v4l2-common.h>
#include "cx25840.h"

View file

@ -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 */

View file

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

View file

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

View file

@ -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 = {

View file

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

View file

@ -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 = {

View file

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

View file

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

View file

@ -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 = {

View file

@ -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;
}
/* ----------------------------------------------------------- */

View file

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

View file

@ -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] = {

View file

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

View 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
View 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,
};

View file

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

View file

@ -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 */

View file

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

View file

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

View 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, },
},
},
};

View 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, },
},
},
};

View file

@ -32,7 +32,7 @@
#include <asm/uaccess.h>
#include "rds.h"
#include <media/rds.h>
/* Addresses to scan */
static unsigned short normal_i2c[] = {

View file

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

View file

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

View file

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

View file

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

View file

@ -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 = {

View file

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

View file

@ -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 = {

View file

@ -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 = {

View file

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

View 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