summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2006-03-30 22:46:49 -0600
committerMike Isely <isely@pobox.com>2006-03-30 22:46:49 -0600
commit4a70d7bbda936a5e93a2d6f6061800327491cc69 (patch)
treee7734e7cfedf5a03d71471826f116e45df37272d /linux
parent012c447c3dd586921468215450cb6cce65052a3c (diff)
parentb03dad0db6b312169fd2e16c18187703b23ecd38 (diff)
downloadmediapointer-dvb-s2-4a70d7bbda936a5e93a2d6f6061800327491cc69.tar.gz
mediapointer-dvb-s2-4a70d7bbda936a5e93a2d6f6061800327491cc69.tar.bz2
Merge from master
From: Mike Isely <isely@pobox.com> Signed-off-by: Mike Isely <isely@pobox.com>
Diffstat (limited to 'linux')
-rw-r--r--linux/drivers/media/dvb/dvb-core/dmxdev.c12
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.c18
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.h2
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dtt200u.c47
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h2
-rw-r--r--linux/drivers/media/dvb/frontends/Kconfig12
-rw-r--r--linux/drivers/media/dvb/frontends/tda1004x.c12
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110.c8
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110_av.c2
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-av.c13
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-core.c78
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-patch.c24
-rw-r--r--linux/drivers/media/dvb/ttpci/budget.h13
-rw-r--r--linux/drivers/media/video/Kconfig219
-rw-r--r--linux/drivers/media/video/Makefile6
-rw-r--r--linux/drivers/media/video/cpia2/cpia2.h2
-rw-r--r--linux/drivers/media/video/cx88/Kconfig2
-rw-r--r--linux/drivers/media/video/dpc7146.c3
-rw-r--r--linux/drivers/media/video/hexium_gemini.c3
-rw-r--r--linux/drivers/media/video/hexium_orion.c5
-rw-r--r--linux/drivers/media/video/msp3400-driver.c3
-rw-r--r--linux/drivers/media/video/msp3400-kthreads.c24
-rw-r--r--linux/drivers/media/video/mxb.c9
-rw-r--r--linux/drivers/media/video/saa711x.c1
-rw-r--r--linux/drivers/media/video/tea6420.c4
-rw-r--r--linux/drivers/media/video/upd64031a.c323
-rw-r--r--linux/drivers/media/video/upd64083.c299
-rw-r--r--linux/drivers/media/video/wm8739.c396
-rw-r--r--linux/include/linux/i2c-id.h1
-rw-r--r--linux/include/media/upd64031a.h40
-rw-r--r--linux/include/media/upd64083.h58
31 files changed, 1392 insertions, 249 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c
index 09e96e9dd..04578df3f 100644
--- a/linux/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c
@@ -141,12 +141,18 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
}
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
- void *mem = vmalloc(DVR_BUFFER_SIZE);
+ void *mem;
+ if (!dvbdev->readers) {
+ mutex_unlock(&dmxdev->mutex);
+ return -EBUSY;
+ }
+ mem = vmalloc(DVR_BUFFER_SIZE);
if (!mem) {
mutex_unlock(&dmxdev->mutex);
return -ENOMEM;
}
dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
+ dvbdev->readers--;
}
if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
@@ -184,6 +190,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
dmxdev->dvr_orig_fe);
}
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+ dvbdev->readers++;
if (dmxdev->dvr_buffer.data) {
void *mem = dmxdev->dvr_buffer.data;
mb();
@@ -1029,8 +1036,7 @@ static struct file_operations dvb_dvr_fops = {
static struct dvb_device dvbdev_dvr = {
.priv = NULL,
- .users = 1,
- .writers = 1,
+ .readers = 1,
.fops = &dvb_dvr_fops
};
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
index 55a91bb18..875033330 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -105,6 +105,7 @@ struct dvb_frontend_private {
fe_status_t status;
unsigned long tune_mode_flags;
unsigned int delay;
+ unsigned int reinitialise;
/* swzigzag values */
unsigned int state;
@@ -121,6 +122,7 @@ struct dvb_frontend_private {
unsigned int check_wrapped;
};
+static void dvb_frontend_wakeup(struct dvb_frontend *fe);
static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
{
@@ -213,6 +215,15 @@ static void dvb_frontend_init(struct dvb_frontend *fe)
fe->ops->init(fe);
}
+void dvb_frontend_reinitialise(struct dvb_frontend *fe)
+{
+ struct dvb_frontend_private *fepriv = fe->frontend_priv;
+
+ fepriv->reinitialise = 1;
+ dvb_frontend_wakeup(fe);
+}
+EXPORT_SYMBOL(dvb_frontend_reinitialise);
+
static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked)
{
int q2;
@@ -505,8 +516,8 @@ static int dvb_frontend_thread(void *data)
fepriv->quality = 0;
fepriv->delay = 3*HZ;
fepriv->status = 0;
- dvb_frontend_init(fe);
fepriv->wakeup = 0;
+ fepriv->reinitialise = 1;
while (1) {
up(&fepriv->sem); /* is locked when we enter the thread... */
@@ -530,6 +541,11 @@ static int dvb_frontend_thread(void *data)
if (down_interruptible(&fepriv->sem))
break;
+ if (fepriv->reinitialise) {
+ dvb_frontend_init(fe);
+ fepriv->reinitialise = 0;
+ }
+
/* do an iteration of the tuning loop */
if (fe->ops->tune) {
/* have we been asked to retune? */
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
index d5aee5ad6..5926a3b74 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -112,6 +112,8 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb,
extern int dvb_unregister_frontend(struct dvb_frontend* fe);
+extern void dvb_frontend_reinitialise(struct dvb_frontend *fe);
+
extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);
diff --git a/linux/drivers/media/dvb/dvb-usb/dtt200u.c b/linux/drivers/media/dvb/dvb-usb/dtt200u.c
index b25f65238..b225297d7 100644
--- a/linux/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/linux/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -94,12 +94,14 @@ static int dtt200u_frontend_attach(struct dvb_usb_device *d)
static struct dvb_usb_properties dtt200u_properties;
static struct dvb_usb_properties wt220u_properties;
+static struct dvb_usb_properties wt220u_zl0353_properties;
static int dtt200u_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE,NULL) == 0 ||
- dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE,NULL) == 0)
+ dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE,NULL) == 0 ||
+ dvb_usb_device_init(intf,&wt220u_zl0353_properties,THIS_MODULE,NULL) == 0)
return 0;
return -ENODEV;
@@ -110,6 +112,8 @@ static struct usb_device_id dtt200u_usb_table [] = {
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) },
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_COLD) },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_WARM) },
{ 0 },
};
MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
@@ -196,6 +200,47 @@ static struct dvb_usb_properties wt220u_properties = {
}
};
+static struct dvb_usb_properties wt220u_zl0353_properties = {
+ .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
+ .pid_filter_count = 15,
+
+ .usb_ctrl = CYPRESS_FX2,
+ .firmware = "dvb-usb-wt220u-zl0353-01.fw",
+
+ .power_ctrl = dtt200u_power_ctrl,
+ .streaming_ctrl = dtt200u_streaming_ctrl,
+ .pid_filter = dtt200u_pid_filter,
+ .frontend_attach = dtt200u_frontend_attach,
+
+ .rc_interval = 300,
+ .rc_key_map = dtt200u_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
+ .rc_query = dtt200u_rc_query,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x02,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+
+ .num_device_descs = 1,
+ .devices = {
+ { .name = "WideView WT-220U PenType Receiver (based on ZL353)",
+ .cold_ids = { &dtt200u_usb_table[4], NULL },
+ .warm_ids = { &dtt200u_usb_table[5], NULL },
+ },
+ { NULL },
+ }
+};
+
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver dtt200u_usb_driver = {
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 4a1b9e77e..cb239049b 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -83,6 +83,8 @@
#define USB_PID_DTT200U_WARM 0x0301
#define USB_PID_WT220U_COLD 0x0222
#define USB_PID_WT220U_WARM 0x0221
+#define USB_PID_WT220U_ZL0353_COLD 0x022a
+#define USB_PID_WT220U_ZL0353_WARM 0x022b
#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
#define USB_PID_NEBULA_DIGITV 0x0201
diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig
index 94233168d..37d5e0af1 100644
--- a/linux/drivers/media/dvb/frontends/Kconfig
+++ b/linux/drivers/media/dvb/frontends/Kconfig
@@ -181,6 +181,11 @@ config DVB_OR51211
help
An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
+ This driver needs external firmware. Please use the command
+ "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to
+ download it, and then copy it to /usr/lib/hotplug/firmware
+ or /lib/firmware (depending on configuration of firmware hotplug).
+
config DVB_OR51132
tristate "Oren OR51132 based"
depends on DVB_CORE
@@ -189,6 +194,13 @@ config DVB_OR51132
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
+ This driver needs external firmware. Please use the commands
+ "<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_vsb" and/or
+ "<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_qam" to
+ download firmwares for 8VSB and QAM64/256, respectively. Copy them to
+ /usr/lib/hotplug/firmware or /lib/firmware (depending on
+ configuration of firmware hotplug).
+
config DVB_BCM3510
tristate "Broadcom BCM3510"
depends on DVB_CORE
diff --git a/linux/drivers/media/dvb/frontends/tda1004x.c b/linux/drivers/media/dvb/frontends/tda1004x.c
index 8e8df7b4c..b83dafa4e 100644
--- a/linux/drivers/media/dvb/frontends/tda1004x.c
+++ b/linux/drivers/media/dvb/frontends/tda1004x.c
@@ -52,7 +52,6 @@ struct tda1004x_state {
struct dvb_frontend frontend;
/* private demod data */
- u8 initialised;
enum tda1004x_demod demod_type;
};
@@ -594,9 +593,6 @@ static int tda10045_init(struct dvb_frontend* fe)
dprintk("%s\n", __FUNCTION__);
- if (state->initialised)
- return 0;
-
if (tda10045_fwupload(fe)) {
printk("tda1004x: firmware upload failed\n");
return -EIO;
@@ -626,7 +622,6 @@ static int tda10045_init(struct dvb_frontend* fe)
tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk);
- state->initialised = 1;
return 0;
}
@@ -635,9 +630,6 @@ static int tda10046_init(struct dvb_frontend* fe)
struct tda1004x_state* state = fe->demodulator_priv;
dprintk("%s\n", __FUNCTION__);
- if (state->initialised)
- return 0;
-
if (tda10046_fwupload(fe)) {
printk("tda1004x: firmware upload failed\n");
return -EIO;
@@ -697,7 +689,6 @@ static int tda10046_init(struct dvb_frontend* fe)
// tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes
tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
- state->initialised = 1;
return 0;
}
@@ -1207,7 +1198,6 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
break;
}
- state->initialised = 0;
return 0;
}
@@ -1271,7 +1261,6 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
state->config = config;
state->i2c = i2c;
memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops));
- state->initialised = 0;
state->demod_type = TDA1004X_DEMOD_TDA10045;
/* check if the demod is there */
@@ -1330,7 +1319,6 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
state->config = config;
state->i2c = i2c;
memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
- state->initialised = 0;
state->demod_type = TDA1004X_DEMOD_TDA10046;
/* check if the demod is there */
diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c
index 87741cf17..940b05439 100644
--- a/linux/drivers/media/dvb/ttpci/av7110.c
+++ b/linux/drivers/media/dvb/ttpci/av7110.c
@@ -87,6 +87,7 @@ static int volume = 255;
static int budgetpatch;
static int wss_cfg_4_3 = 0x4008;
static int wss_cfg_16_9 = 0x0007;
+static int tv_standard;
module_param_named(debug, av7110_debug, int, 0644);
MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
@@ -109,6 +110,8 @@ module_param(wss_cfg_4_3, int, 0444);
MODULE_PARM_DESC(wss_cfg_4_3, "WSS 4:3 - default 0x4008 - bit 15: disable, 14: burst mode, 13..0: wss data");
module_param(wss_cfg_16_9, int, 0444);
MODULE_PARM_DESC(wss_cfg_16_9, "WSS 16:9 - default 0x0007 - bit 15: disable, 14: burst mode, 13..0: wss data");
+module_param(tv_standard, int, 0444);
+MODULE_PARM_DESC(tv_standard, "TV standard: 0 PAL (default), 1 NTSC");
static void restart_feeds(struct av7110 *av7110);
@@ -2123,7 +2126,7 @@ static int frontend_init(struct av7110 *av7110)
read_pwm(av7110));
break;
case 0x0003:
- /* Haupauge DVB-C 2.1 VES1820/ALPS TDBE2 */
+ /* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */
av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap,
read_pwm(av7110));
break;
@@ -2543,6 +2546,9 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
av7110->osdwin = 1;
mutex_init(&av7110->osd_mutex);
+ /* TV standard */
+ av7110->vidmode = tv_standard == 1 ? VIDEO_MODE_NTSC : VIDEO_MODE_PAL;
+
/* ARM "watchdog" */
init_waitqueue_head(&av7110->arm_wait);
av7110->arm_thread = NULL;
diff --git a/linux/drivers/media/dvb/ttpci/av7110_av.c b/linux/drivers/media/dvb/ttpci/av7110_av.c
index 400facec7..2eff09f63 100644
--- a/linux/drivers/media/dvb/ttpci/av7110_av.c
+++ b/linux/drivers/media/dvb/ttpci/av7110_av.c
@@ -1479,8 +1479,6 @@ int av7110_av_init(struct av7110 *av7110)
void (*play[])(u8 *, int, void *) = { play_audio_cb, play_video_cb };
int i, ret;
- av7110->vidmode = VIDEO_MODE_PAL;
-
for (i = 0; i < 2; i++) {
struct ipack *ipack = av7110->ipack + i;
diff --git a/linux/drivers/media/dvb/ttpci/budget-av.c b/linux/drivers/media/dvb/ttpci/budget-av.c
index 9dd4745f5..8efe3ce5f 100644
--- a/linux/drivers/media/dvb/ttpci/budget-av.c
+++ b/linux/drivers/media/dvb/ttpci/budget-av.c
@@ -60,11 +60,11 @@ struct budget_av {
struct dvb_ca_en50221 ca;
};
-/* GPIO CI Connections:
- * 0 - Vcc/Reset (Reset is controlled by capacitor)
- * 1 - Attribute Memory
- * 2 - Card Enable (Active Low)
- * 3 - Card Detect
+/* GPIO Connections:
+ * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*!
+ * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory
+ * 2 - CI Card Enable (Active Low)
+ * 3 - CI Card Detect
*/
/****************************************************************************
@@ -214,6 +214,9 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d)
msleep(100);
+ /* reinitialise the frontend */
+ dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
+
if (timeout <= 0)
{
printk(KERN_ERR "budget-av: cam reset failed (timeout).\n");
diff --git a/linux/drivers/media/dvb/ttpci/budget-core.c b/linux/drivers/media/dvb/ttpci/budget-core.c
index 633e68c34..ea2066d46 100644
--- a/linux/drivers/media/dvb/ttpci/budget-core.c
+++ b/linux/drivers/media/dvb/ttpci/budget-core.c
@@ -39,9 +39,21 @@
#include "budget.h"
#include "ttpci-eeprom.h"
+#define TS_WIDTH (2 * TS_SIZE)
+#define TS_WIDTH_ACTIVY TS_SIZE
+#define TS_HEIGHT_MASK 0xf00
+#define TS_HEIGHT_MASK_ACTIVY 0xc00
+#define TS_MIN_BUFSIZE_K 188
+#define TS_MAX_BUFSIZE_K 1410
+#define TS_MAX_BUFSIZE_K_ACTIVY 564
+#define BUFFER_WARNING_WAIT (30*HZ)
+
int budget_debug;
+static int dma_buffer_size = TS_MIN_BUFSIZE_K;
module_param_named(debug, budget_debug, int, 0644);
+module_param_named(bufsize, dma_buffer_size, int, 0444);
MODULE_PARM_DESC(debug, "Turn on/off budget debugging (default:off).");
+MODULE_PARM_DESC(bufsize, "DMA buffer size in KB, default: 188, min: 188, max: 1410 (Activy: 564)");
/****************************************************************************
* TT budget / WinTV Nova
@@ -70,11 +82,10 @@ static int start_ts_capture(struct budget *budget)
saa7146_write(dev, MC1, MASK_20); // DMA3 off
- memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH);
+ memset(budget->grabbing, 0x00, budget->buffer_size);
saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, PCI_BT_V1) & ~0x001f0000));
- budget->tsf = 0xff;
budget->ttbp = 0;
/*
@@ -115,16 +126,12 @@ static int start_ts_capture(struct budget *budget)
saa7146_write(dev, BASE_ODD3, 0);
saa7146_write(dev, BASE_EVEN3, 0);
- saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
+ saa7146_write(dev, PROT_ADDR3, budget->buffer_size);
saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90);
- if (budget->card->type == BUDGET_FS_ACTIVY) {
- saa7146_write(dev, PITCH3, TS_WIDTH / 2);
- saa7146_write(dev, NUM_LINE_BYTE3, ((TS_HEIGHT * 2) << 16) | (TS_WIDTH / 2));
- } else {
- saa7146_write(dev, PITCH3, TS_WIDTH);
- saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
- }
+ saa7146_write(dev, PITCH3, budget->buffer_width);
+ saa7146_write(dev, NUM_LINE_BYTE3,
+ (budget->buffer_height << 16) | budget->buffer_width);
saa7146_write(dev, MC2, (MASK_04 | MASK_20));
@@ -141,11 +148,12 @@ static void vpeirq(unsigned long data)
u8 *mem = (u8 *) (budget->grabbing);
u32 olddma = budget->ttbp;
u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
+ u32 count;
/* nearest lower position divisible by 188 */
newdma -= newdma % 188;
- if (newdma >= TS_BUFLEN)
+ if (newdma >= budget->buffer_size)
return;
budget->ttbp = newdma;
@@ -154,11 +162,24 @@ static void vpeirq(unsigned long data)
return;
if (newdma > olddma) { /* no wraparound, dump olddma..newdma */
- dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, (newdma - olddma) / 188);
+ count = newdma - olddma;
+ dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188);
} else { /* wraparound, dump olddma..buflen and 0..newdma */
- dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, (TS_BUFLEN - olddma) / 188);
+ count = budget->buffer_size - olddma;
+ dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188);
+ count += newdma;
dvb_dmx_swfilter_packets(&budget->demux, mem, newdma / 188);
}
+
+ if (count > budget->buffer_warning_threshold)
+ budget->buffer_warnings++;
+
+ if (budget->buffer_warnings && time_after(jiffies, budget->buffer_warning_time)) {
+ printk("%s %s: used %d times >80%% of buffer (%u bytes now)\n",
+ budget->dev->name, __FUNCTION__, budget->buffer_warnings, count);
+ budget->buffer_warning_time = jiffies + BUFFER_WARNING_WAIT;
+ budget->buffer_warnings = 0;
+ }
}
@@ -341,9 +362,10 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
struct saa7146_pci_extension_data *info,
struct module *owner)
{
- int length = TS_WIDTH * TS_HEIGHT;
int ret = 0;
struct budget_info *bi = info->ext_priv;
+ int max_bufsize;
+ int height_mask;
memset(budget, 0, sizeof(struct budget));
@@ -352,6 +374,32 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
budget->card = bi;
budget->dev = (struct saa7146_dev *) dev;
+ if (budget->card->type == BUDGET_FS_ACTIVY) {
+ budget->buffer_width = TS_WIDTH_ACTIVY;
+ max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY;
+ height_mask = TS_HEIGHT_MASK_ACTIVY;
+ } else {
+ budget->buffer_width = TS_WIDTH;
+ max_bufsize = TS_MAX_BUFSIZE_K;
+ height_mask = TS_HEIGHT_MASK;
+ }
+
+ if (dma_buffer_size < TS_MIN_BUFSIZE_K)
+ dma_buffer_size = TS_MIN_BUFSIZE_K;
+ else if (dma_buffer_size > max_bufsize)
+ dma_buffer_size = max_bufsize;
+
+ budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width;
+ budget->buffer_height &= height_mask;
+ budget->buffer_size = budget->buffer_height * budget->buffer_width;
+ budget->buffer_warning_threshold = budget->buffer_size * 80/100;
+ budget->buffer_warnings = 0;
+ budget->buffer_warning_time = jiffies;
+
+ dprintk(2, "%s: width = %d, height = %d\n",
+ budget->dev->name, budget->buffer_width, budget->buffer_height);
+ printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size);
+
dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner);
/* set dd1 stream a & b */
@@ -392,7 +440,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac);
if (NULL ==
- (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, length, &budget->pt))) {
+ (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt))) {
ret = -ENOMEM;
goto err;
}
diff --git a/linux/drivers/media/dvb/ttpci/budget-patch.c b/linux/drivers/media/dvb/ttpci/budget-patch.c
index 5ea95da4f..25e40fc1f 100644
--- a/linux/drivers/media/dvb/ttpci/budget-patch.c
+++ b/linux/drivers/media/dvb/ttpci/budget-patch.c
@@ -577,6 +577,17 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte
saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
// Set RPS1 Address register to point to RPS code (r108 p42)
saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
+
+ if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
+ return -ENOMEM;
+
+ dprintk(2, "budget: %p\n", budget);
+
+ if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
+ kfree (budget);
+ return err;
+ }
+
// Set Source Line Counter Threshold, using BRS (rCC p43)
// It generates HS event every TS_HEIGHT lines
// this is related to TS_WIDTH set in register
@@ -585,24 +596,13 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte
//,then RPS_THRESH1
// should be set to trigger every TS_HEIGHT (512) lines.
//
- saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
+ saa7146_write(dev, RPS_THRESH1, budget->buffer_height | MASK_12 );
// saa7146_write(dev, RPS_THRESH0, ((TS_HEIGHT/2)<<16) |MASK_28| (TS_HEIGHT/2) |MASK_12 );
// Enable RPS1 (rFC p33)
saa7146_write(dev, MC1, (MASK_13 | MASK_29));
- if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
- return -ENOMEM;
-
- dprintk(2, "budget: %p\n", budget);
-
- if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
- kfree (budget);
- return err;
- }
-
-
dev->ext_priv = budget;
budget->dvb_adapter.priv = budget;
diff --git a/linux/drivers/media/dvb/ttpci/budget.h b/linux/drivers/media/dvb/ttpci/budget.h
index 30f74b416..c5c226d4f 100644
--- a/linux/drivers/media/dvb/ttpci/budget.h
+++ b/linux/drivers/media/dvb/ttpci/budget.h
@@ -70,7 +70,13 @@ struct budget {
int ci_present;
int video_port;
- u8 tsf;
+ u32 buffer_width;
+ u32 buffer_height;
+ u32 buffer_size;
+ u32 buffer_warning_threshold;
+ u32 buffer_warnings;
+ unsigned long buffer_warning_time;
+
u32 ttbp;
int feeding;
@@ -91,11 +97,6 @@ static struct saa7146_pci_extension_data x_var = { \
.ext_priv = &x_var ## _info, \
.ext = &budget_extension };
-#define TS_WIDTH (376)
-#define TS_HEIGHT (512)
-#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
-#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE)
-
#define BUDGET_TT 0
#define BUDGET_TT_HW_DISEQC 1
#define BUDGET_PATCH 3
diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig
index 62e71b527..911da5210 100644
--- a/linux/drivers/media/video/Kconfig
+++ b/linux/drivers/media/video/Kconfig
@@ -300,7 +300,7 @@ config VIDEO_OVCAMCHIP
camera drivers.
To compile this driver as a module, choose M here: the
- module will be called ovcamchip
+ module will be called ovcamchip.
config VIDEO_M32R_AR
tristate "AR devices"
@@ -316,6 +316,13 @@ config VIDEO_M32R_AR_M64278
Say Y here to use the Renesas M64278E-800 camera module,
which supports VGA(640x480 pixcels) size of images.
+#
+# Encoder / Decoder module configuration
+#
+
+menu "Encoders and Decoders"
+ depends on VIDEO_DEV
+
config VIDEO_MSP3400
tristate "Micronas MSP34xx audio decoders"
depends on VIDEO_DEV && I2C
@@ -323,7 +330,7 @@ config VIDEO_MSP3400
Support for the Micronas MSP34xx series of audio decoders.
To compile this driver as a module, choose M here: the
- module will be called msp3400
+ module will be called msp3400.
config VIDEO_CS53L32A
tristate "Cirrus Logic CS53L32A audio ADC"
@@ -333,17 +340,27 @@ config VIDEO_CS53L32A
stereo A/D converter.
To compile this driver as a module, choose M here: the
- module will be called cs53l32a
+ module will be called cs53l32a.
config VIDEO_WM8775
- tristate "Wolfson Microelectronics WM8775 audio ADC"
+ tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer"
depends on VIDEO_DEV && I2C && EXPERIMENTAL
---help---
- Support for the Wolfson Microelectronics WM8775
- high performance stereo A/D Converter.
+ Support for the Wolfson Microelectronics WM8775 high
+ performance stereo A/D Converter with a 4 channel input mixer.
To compile this driver as a module, choose M here: the
- module will be called wm8775
+ module will be called wm8775.
+
+config VIDEO_WM8739
+ tristate "Wolfson Microelectronics WM8739 stereo audio ADC"
+ depends on VIDEO_DEV && I2C && EXPERIMENTAL
+ ---help---
+ Support for the Wolfson Microelectronics WM8739
+ stereo A/D Converter.
+
+ To compile this driver as a module, choose M here: the
+ module will be called wm8739.
source "drivers/media/video/cx25840/Kconfig"
@@ -354,7 +371,7 @@ config VIDEO_SAA711X
Support for the Philips SAA7113/4/5 video decoders.
To compile this driver as a module, choose M here: the
- module will be called saa7115
+ module will be called saa7115.
config VIDEO_SAA7127
tristate "Philips SAA7127/9 digital video encoders"
@@ -363,7 +380,32 @@ config VIDEO_SAA7127
Support for the Philips SAA7127/9 digital video encoders.
To compile this driver as a module, choose M here: the
- module will be called saa7127
+ module will be called saa7127.
+
+config VIDEO_UPD64031A
+ tristate "NEC Electronics uPD64031A Ghost Reduction"
+ depends on VIDEO_DEV && I2C && EXPERIMENTAL
+ ---help---
+ Support for the NEC Electronics uPD64031A Ghost Reduction
+ video chip. It is most often found in NTSC TV cards made for
+ Japan and is used to reduce the 'ghosting' effect that can
+ be present in analog TV broadcasts.
+
+ To compile this driver as a module, choose M here: the
+ module will be called upd64031a.
+
+config VIDEO_UPD64083
+ tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation"
+ depends on VIDEO_DEV && I2C && EXPERIMENTAL
+ ---help---
+ Support for the NEC Electronics uPD64083 3-Dimensional Y/C
+ separation video chip. It is used to improve the quality of
+ the colors of a composite signal.
+
+ To compile this driver as a module, choose M here: the
+ module will be called upd64083.
+
+endmenu # encoder / decoder chips
#
# USB Multimedia device configuration
@@ -376,20 +418,6 @@ source "drivers/media/video/pvrusb2/Kconfig"
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
@@ -399,66 +427,12 @@ config USB_DSBR
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.
+source "drivers/media/video/usbvideo/Kconfig"
-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.
+source "drivers/media/video/et61x251/Kconfig"
config USB_OV511
tristate "USB OV511 Camera support"
@@ -468,11 +442,6 @@ config USB_OV511
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.
@@ -484,28 +453,10 @@ config USB_SE401
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.
+source "drivers/media/video/sn9c102/Kconfig"
config USB_STV680
tristate "USB STV680 (Pencam) Camera support"
@@ -516,17 +467,13 @@ config USB_STV680
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
+ depends on USB && VIDEO_DEV && I2C
+ select 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.
@@ -538,62 +485,12 @@ config USB_W9968CF
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>.
+source "drivers/media/video/zc0301/Kconfig"
- To compile this driver as a module, choose M here: the
- module will be called pwc.
+source "drivers/media/video/pwc/Kconfig"
endmenu # V4L USB devices
diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile
index 289ef1abf..6bb050173 100644
--- a/linux/drivers/media/video/Makefile
+++ b/linux/drivers/media/video/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
+obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
obj-$(CONFIG_VIDEO_MXB) += saa7111.o tda9840.o tea6415c.o tea6420.o mxb.o
@@ -65,9 +66,8 @@ obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
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_VIDEO_UPD64031A) += upd64031a.o
+obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
obj-$(CONFIG_USB_DABUSB) += dabusb.o
obj-$(CONFIG_USB_DSBR) += dsbr100.o
diff --git a/linux/drivers/media/video/cpia2/cpia2.h b/linux/drivers/media/video/cpia2/cpia2.h
index a53056c82..7480c1827 100644
--- a/linux/drivers/media/video/cpia2/cpia2.h
+++ b/linux/drivers/media/video/cpia2/cpia2.h
@@ -462,7 +462,7 @@ int cpia2_init_camera(struct camera_data *cam);
int cpia2_allocate_buffers(struct camera_data *cam);
void cpia2_free_buffers(struct camera_data *cam);
long cpia2_read(struct camera_data *cam,
- char *buf, unsigned long count, int noblock);
+ char __user *buf, unsigned long count, int noblock);
unsigned int cpia2_poll(struct camera_data *cam,
struct file *filp, poll_table *wait);
int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma);
diff --git a/linux/drivers/media/video/cx88/Kconfig b/linux/drivers/media/video/cx88/Kconfig
index ff0f72340..2c586f903 100644
--- a/linux/drivers/media/video/cx88/Kconfig
+++ b/linux/drivers/media/video/cx88/Kconfig
@@ -25,7 +25,7 @@ config VIDEO_CX88_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
+ If supported, you should see 14f1:8801 or 14f1:8811
PCI device.
To compile this driver as a module, choose M here: the
diff --git a/linux/drivers/media/video/dpc7146.c b/linux/drivers/media/video/dpc7146.c
index 5cce40af6..3ee2cc6e3 100644
--- a/linux/drivers/media/video/dpc7146.c
+++ b/linux/drivers/media/video/dpc7146.c
@@ -95,12 +95,11 @@ static int dpc_probe(struct saa7146_dev* dev)
struct i2c_client *client;
struct list_head *item;
- dpc = (struct dpc*)kmalloc(sizeof(struct dpc), GFP_KERNEL);
+ dpc = kzalloc(sizeof(struct dpc), GFP_KERNEL);
if( NULL == dpc ) {
printk("dpc_v4l2.o: dpc_probe: not enough kernel memory.\n");
return -ENOMEM;
}
- memset(dpc, 0x0, sizeof(struct dpc));
/* FIXME: enable i2c-port pins, video-port-pins
video port pins should be enabled here ?! */
diff --git a/linux/drivers/media/video/hexium_gemini.c b/linux/drivers/media/video/hexium_gemini.c
index 24ae47cff..6cc7ca99d 100644
--- a/linux/drivers/media/video/hexium_gemini.c
+++ b/linux/drivers/media/video/hexium_gemini.c
@@ -241,12 +241,11 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
DEB_EE((".\n"));
- hexium = (struct hexium *) kmalloc(sizeof(struct hexium), GFP_KERNEL);
+ hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
if (NULL == hexium) {
printk("hexium_gemini: not enough kernel memory in hexium_attach().\n");
return -ENOMEM;
}
- memset(hexium, 0x0, sizeof(struct hexium));
dev->ext_priv = hexium;
/* enable i2c-port pins */
diff --git a/linux/drivers/media/video/hexium_orion.c b/linux/drivers/media/video/hexium_orion.c
index 776eeea1b..59ed0dfd2 100644
--- a/linux/drivers/media/video/hexium_orion.c
+++ b/linux/drivers/media/video/hexium_orion.c
@@ -225,12 +225,11 @@ static int hexium_probe(struct saa7146_dev *dev)
return -EFAULT;
}
- hexium = (struct hexium *) kmalloc(sizeof(struct hexium), GFP_KERNEL);
+ hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
if (NULL == hexium) {
printk("hexium_orion: hexium_probe: not enough kernel memory.\n");
return -ENOMEM;
}
- memset(hexium, 0x0, sizeof(struct hexium));
/* enable i2c-port pins */
saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
@@ -486,7 +485,7 @@ static struct saa7146_ext_vv vv_data = {
};
static struct saa7146_extension extension = {
- .name = "hexium HV-PCI6/Orion",
+ .name = "hexium HV-PCI6 Orion",
.flags = 0, // SAA7146_USE_I2C_IRQ,
.pci_tbl = &pci_tbl[0],
diff --git a/linux/drivers/media/video/msp3400-driver.c b/linux/drivers/media/video/msp3400-driver.c
index 65c99edd8..b52e5bdea 100644
--- a/linux/drivers/media/video/msp3400-driver.c
+++ b/linux/drivers/media/video/msp3400-driver.c
@@ -298,7 +298,8 @@ void msp_set_scart(struct i2c_client *client, int in, int out)
msp_write_dsp(client, 0x13, state->acb);
/* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */
- msp_write_dem(client, 0x40, state->i2s_mode);
+ if (state->has_i2s_conf)
+ msp_write_dem(client, 0x40, state->i2s_mode);
}
void msp_set_mute(struct i2c_client *client)
diff --git a/linux/drivers/media/video/msp3400-kthreads.c b/linux/drivers/media/video/msp3400-kthreads.c
index 0a9b4a2ba..4b0d6340a 100644
--- a/linux/drivers/media/video/msp3400-kthreads.c
+++ b/linux/drivers/media/video/msp3400-kthreads.c
@@ -234,6 +234,7 @@ static void msp3400c_set_audmode(struct i2c_client *client)
char *modestr = (state->audmode >= 0 && state->audmode < 5) ?
strmode[state->audmode] : "unknown";
int src = 0; /* channel source: FM/AM, nicam or SCART */
+ int audmode = state->audmode;
if (state->opmode == OPMODE_AUTOSELECT) {
/* this method would break everything, let's make sure
@@ -245,11 +246,22 @@ static void msp3400c_set_audmode(struct i2c_client *client)
return;
}
+ /* If no second language is available, switch to the first language */
+ if ((audmode == V4L2_TUNER_MODE_LANG2 ||
+ audmode == V4L2_TUNER_MODE_LANG1_LANG2) &&
+ !(state->rxsubchans & V4L2_TUNER_SUB_LANG2))
+ audmode = V4L2_TUNER_MODE_LANG1;
+ /* switch to stereo for stereo transmission, otherwise
+ keep first language */
+ if (audmode == V4L2_TUNER_MODE_LANG1 &&
+ (state->rxsubchans & V4L2_TUNER_SUB_STEREO))
+ audmode = V4L2_TUNER_MODE_STEREO;
+
/* switch demodulator */
switch (state->mode) {
case MSP_MODE_FM_TERRA:
v4l_dbg(1, msp_debug, client, "FM set_audmode: %s\n", modestr);
- switch (state->audmode) {
+ switch (audmode) {
case V4L2_TUNER_MODE_STEREO:
msp_write_dsp(client, 0x000e, 0x3001);
break;
@@ -263,7 +275,7 @@ static void msp3400c_set_audmode(struct i2c_client *client)
break;
case MSP_MODE_FM_SAT:
v4l_dbg(1, msp_debug, client, "SAT set_audmode: %s\n", modestr);
- switch (state->audmode) {
+ switch (audmode) {
case V4L2_TUNER_MODE_MONO:
msp3400c_set_carrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
break;
@@ -302,7 +314,7 @@ static void msp3400c_set_audmode(struct i2c_client *client)
}
/* switch audio */
- switch (state->audmode) {
+ switch (audmode) {
case V4L2_TUNER_MODE_STEREO:
case V4L2_TUNER_MODE_LANG1_LANG2:
src |= 0x0020;
@@ -320,10 +332,6 @@ static void msp3400c_set_audmode(struct i2c_client *client)
src = 0x0030;
break;
case V4L2_TUNER_MODE_LANG1:
- /* switch to stereo for stereo transmission, otherwise
- keep first language */
- if (state->rxsubchans & V4L2_TUNER_SUB_STEREO)
- src |= 0x0020;
break;
case V4L2_TUNER_MODE_LANG2:
src |= 0x0010;
@@ -625,9 +633,9 @@ int msp3400c_thread(void *data)
if (msp_sleep(state, 1000))
goto restart;
while (state->watch_stereo) {
+ watch_stereo(client);
if (msp_sleep(state, 5000))
goto restart;
- watch_stereo(client);
}
}
v4l_dbg(1, msp_debug, client, "thread: exit\n");
diff --git a/linux/drivers/media/video/mxb.c b/linux/drivers/media/video/mxb.c
index 615cc0a1d..37d3f33b7 100644
--- a/linux/drivers/media/video/mxb.c
+++ b/linux/drivers/media/video/mxb.c
@@ -26,8 +26,8 @@
#include "compat.h"
#include <media/saa7146_vv.h>
#include <media/tuner.h>
-#include <media/v4l2-common.h>
#include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
#include "mxb.h"
#include "tea6415c.h"
@@ -178,12 +178,11 @@ static int mxb_probe(struct saa7146_dev* dev)
return -ENODEV;
}
- mxb = (struct mxb*)kmalloc(sizeof(struct mxb), GFP_KERNEL);
+ mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
if( NULL == mxb ) {
DEB_D(("not enough kernel memory.\n"));
return -ENOMEM;
}
- memset(mxb, 0x0, sizeof(struct mxb));
mxb->i2c_adapter = (struct i2c_adapter) {
.class = I2C_CLASS_TV_ANALOG,
@@ -631,9 +630,9 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
}
/* fixme: locke das setzen des inputs mit hilfe des mutexes
- down(&dev->lock);
+ mutex_lock(&dev->lock);
video_mux(dev,*i);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
*/
/* fixme: check if streaming capture
diff --git a/linux/drivers/media/video/saa711x.c b/linux/drivers/media/video/saa711x.c
index f51cd9442..59425506e 100644
--- a/linux/drivers/media/video/saa711x.c
+++ b/linux/drivers/media/video/saa711x.c
@@ -46,7 +46,6 @@ MODULE_AUTHOR("Dave Perks, Jose Ignacio Gijon, Joerg Heckenbach, Mark McClelland
MODULE_LICENSE("GPL");
#include <linux/i2c.h>
-#include <linux/i2c-dev.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#include "i2c-compat.h"
#endif
diff --git a/linux/drivers/media/video/tea6420.c b/linux/drivers/media/video/tea6420.c
index 74af061b2..9896661da 100644
--- a/linux/drivers/media/video/tea6420.c
+++ b/linux/drivers/media/video/tea6420.c
@@ -38,6 +38,7 @@ static int debug = 0; /* insmod parameter */
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)
+#define dprintk(args...) \
do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0)
#else
#define dprintk(args...) \
@@ -108,11 +109,10 @@ static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind)
}
/* allocate memory for client structure */
- client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (0 == client) {
return -ENOMEM;
}
- memset(client, 0x0, sizeof(struct i2c_client));
/* fill client structure */
memcpy(client, &client_template, sizeof(struct i2c_client));
diff --git a/linux/drivers/media/video/upd64031a.c b/linux/drivers/media/video/upd64031a.c
new file mode 100644
index 000000000..66254bad4
--- /dev/null
+++ b/linux/drivers/media/video/upd64031a.c
@@ -0,0 +1,323 @@
+/*
+ * upd64031A - NEC Electronics Ghost Reduction for NTSC in Japan
+ *
+ * 2003 by T.Adachi <tadachi@tadachi-net.com>
+ * 2003 by Takeru KOMORIYA <komoriya@paken.org>
+ * 2006 by Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "compat.h"
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <media/upd64031a.h>
+
+// --------------------- read registers functions define -----------------------
+
+/* bit masks */
+#define GR_MODE_MASK 0xc0
+#define DIRECT_3DYCS_CONNECT_MASK 0xc0
+#define SYNC_CIRCUIT_MASK 0xa0
+
+// -----------------------------------------------------------------------------
+
+MODULE_DESCRIPTION("uPD64031A driver");
+MODULE_AUTHOR("T. Adachi, Takeru KOMORIYA, Hans Verkuil");
+MODULE_LICENSE("GPL");
+
+static int debug = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+module_param(debug, int, 0644);
+#else
+MODULE_PARM(debug, "i");
+#endif
+
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
+static unsigned short normal_i2c[] = { 0x24 >> 1, 0x26 >> 1, I2C_CLIENT_END };
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
+static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
+#endif
+
+I2C_CLIENT_INSMOD;
+
+enum {
+ R00 = 0, R01, R02, R03, R04,
+ R05, R06, R07, R08, R09,
+ R0A, R0B, R0C, R0D, R0E, R0F,
+ /* unused registers
+ R10, R11, R12, R13, R14,
+ R15, R16, R17,
+ */
+ TOT_REGS
+};
+
+struct upd64031a_state {
+ u8 regs[TOT_REGS];
+ u8 gr_mode;
+ u8 direct_3dycs_connect;
+ u8 ext_comp_sync;
+ u8 ext_vert_sync;
+};
+
+static u8 upd64031a_init[] = {
+ 0x00, 0xb8, 0x48, 0xd2, 0xe6,
+ 0x03, 0x10, 0x0b, 0xaf, 0x7f,
+ 0x00, 0x00, 0x1d, 0x5e, 0x00,
+ 0xd0
+};
+
+/* ------------------------------------------------------------------------ */
+
+static u8 upd64031a_read(struct i2c_client *client, u8 reg)
+{
+ u8 buf[2];
+
+ if (reg >= sizeof(buf))
+ return 0xff;
+ i2c_master_recv(client, buf, 2);
+ return buf[reg];
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void upd64031a_write(struct i2c_client *client, u8 reg, u8 val)
+{
+ u8 buf[2];
+
+ buf[0] = reg;
+ buf[1] = val;
+ v4l_dbg(1, debug, client, "writing reg addr: %02X val: %02X\n", reg, val);
+ if (i2c_master_send(client, buf, 2) != 2)
+ v4l_err(client, "I/O error write 0x%02x/0x%02x\n", reg, val);
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* The input changed due to new input or channel changed */
+static void upd64031a_change(struct i2c_client *client)
+{
+ struct upd64031a_state *state = i2c_get_clientdata(client);
+ u8 reg = state->regs[R00];
+
+ v4l_dbg(1, debug, client, "changed input or channel\n");
+ upd64031a_write(client, R00, reg | 0x10);
+ upd64031a_write(client, R00, reg & ~0x10);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int upd64031a_command(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+ struct upd64031a_state *state = i2c_get_clientdata(client);
+ struct v4l2_routing *route = arg;
+
+ switch (cmd) {
+ case VIDIOC_S_FREQUENCY:
+ upd64031a_change(client);
+ break;
+
+ case VIDIOC_INT_G_VIDEO_ROUTING:
+ route->input = (state->gr_mode >> 6) |
+ (state->direct_3dycs_connect >> 4) |
+ (state->ext_comp_sync >> 1) |
+ (state->ext_vert_sync >> 2);
+ route->output = 0;
+ break;
+
+ case VIDIOC_INT_S_VIDEO_ROUTING:
+ {
+ u8 r00, r05, r08;
+
+ state->gr_mode = (route->input & 3) << 6;
+ state->direct_3dycs_connect = (route->input & 0xc) << 4;
+ state->ext_comp_sync = (route->input & UPD64031A_COMPOSITE_EXTERNAL) << 1;
+ state->ext_vert_sync = (route->input & UPD64031A_VERTICAL_EXTERNAL) << 2;
+ r00 = (state->regs[R00] & ~GR_MODE_MASK) | state->gr_mode;
+ r05 = (state->regs[R00] & ~SYNC_CIRCUIT_MASK) |
+ state->ext_comp_sync | state->ext_vert_sync;
+ r08 = (state->regs[R08] & ~DIRECT_3DYCS_CONNECT_MASK) |
+ state->direct_3dycs_connect;
+ upd64031a_write(client, R00, r00);
+ upd64031a_write(client, R05, r05);
+ upd64031a_write(client, R08, r08);
+ upd64031a_change(client);
+ break;
+ }
+
+ case VIDIOC_LOG_STATUS:
+ v4l_info(client, "Status: SA00=0x%02x SA01=0x%02x\n",
+ upd64031a_read(client, 0), upd64031a_read(client, 1));
+ break;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ case VIDIOC_INT_G_REGISTER:
+ {
+ struct v4l2_register *reg = arg;
+
+ if (reg->i2c_id != I2C_DRIVERID_UPD64031A)
+ return -EINVAL;
+ reg->val = upd64031a_read(client, reg->reg & 0xff);
+ break;
+ }
+
+ case VIDIOC_INT_S_REGISTER:
+ {
+ struct v4l2_register *reg = arg;
+ u8 addr = reg->reg & 0xff;
+ u8 val = reg->val & 0xff;
+
+ if (reg->i2c_id != I2C_DRIVERID_UPD64031A)
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ upd64031a_write(client, addr, val);
+ break;
+ }
+#endif
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* i2c implementation */
+
+static struct i2c_driver i2c_driver;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+static int upd64031a_attach(struct i2c_adapter *adapter, int address, int kind)
+#else
+static int upd64031a_attach(struct i2c_adapter *adapter, int address,
+ unsigned short flags, int kind)
+#endif
+{
+ struct i2c_client *client;
+ struct upd64031a_state *state;
+ int i;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return 0;
+
+ client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == NULL) {
+ return -ENOMEM;
+ }
+
+ client->addr = address;
+ client->adapter = adapter;
+ client->driver = &i2c_driver;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)
+ client->flags = I2C_CLIENT_ALLOW_USE;
+#endif
+ snprintf(client->name, sizeof(client->name) - 1, "uPD64031A");
+
+ v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name);
+
+ state = kmalloc(sizeof(struct upd64031a_state), GFP_KERNEL);
+ if (state == NULL) {
+ kfree(client);
+ return -ENOMEM;
+ }
+ i2c_set_clientdata(client, state);
+ memcpy(state->regs, upd64031a_init, sizeof(state->regs));
+ state->gr_mode = UPD64031A_GR_ON << 6;
+ state->direct_3dycs_connect = UPD64031A_3DYCS_COMPOSITE << 4;
+ state->ext_comp_sync = state->ext_vert_sync = 0;
+ for (i = 0; i < TOT_REGS; i++) {
+ upd64031a_write(client, i, state->regs[i]);
+ }
+
+ i2c_attach_client(client);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ MOD_INC_USE_COUNT;
+#endif
+ return 0;
+}
+
+static int upd64031a_probe(struct i2c_adapter *adapter)
+{
+#ifdef I2C_CLASS_TV_ANALOG
+ if (adapter->class & I2C_CLASS_TV_ANALOG)
+#else
+ if (adapter->id == I2C_HW_B_BT848)
+#endif
+ return i2c_probe(adapter, &addr_data, upd64031a_attach);
+ return 0;
+}
+
+static int upd64031a_detach(struct i2c_client *client)
+{
+ int err;
+
+ err = i2c_detach_client(client);
+ if (err)
+ return err;
+
+ kfree(client);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ MOD_DEC_USE_COUNT;
+#endif
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* i2c implementation */
+static struct i2c_driver i2c_driver = {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)
+ .owner = THIS_MODULE,
+#endif
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)
+ .name = "upd64031a",
+ .flags = I2C_DF_NOTIFY,
+#else
+ .driver = {
+ .name = "upd64031a",
+ },
+#endif
+ .id = I2C_DRIVERID_UPD64031A,
+ .attach_adapter = upd64031a_probe,
+ .detach_client = upd64031a_detach,
+ .command = upd64031a_command,
+};
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+EXPORT_NO_SYMBOLS;
+#endif
+
+static int __init upd64031a_init_module(void)
+{
+ return i2c_add_driver(&i2c_driver);
+}
+
+static void __exit upd64031a_exit_module(void)
+{
+ i2c_del_driver(&i2c_driver);
+}
+
+module_init(upd64031a_init_module);
+module_exit(upd64031a_exit_module);
diff --git a/linux/drivers/media/video/upd64083.c b/linux/drivers/media/video/upd64083.c
new file mode 100644
index 000000000..861d9b114
--- /dev/null
+++ b/linux/drivers/media/video/upd64083.c
@@ -0,0 +1,299 @@
+/*
+ * upd6408x - NEC Electronics 3-Dimensional Y/C separation driver
+ *
+ * 2003 by T.Adachi (tadachi@tadachi-net.com)
+ * 2003 by Takeru KOMORIYA <komoriya@paken.org>
+ * 2006 by Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "compat.h"
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <media/upd64083.h>
+
+MODULE_DESCRIPTION("uPD64083 driver");
+MODULE_AUTHOR("T. Adachi, Takeru KOMORIYA, Hans Verkuil");
+MODULE_LICENSE("GPL");
+
+static int debug = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+module_param(debug, bool, 0644);
+#else
+MODULE_PARM(debug, "i");
+#endif
+
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
+static unsigned short normal_i2c[] = { 0xb8 >> 1, 0xba >> 1, I2C_CLIENT_END };
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
+static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
+#endif
+
+I2C_CLIENT_INSMOD;
+
+enum {
+ R00 = 0, R01, R02, R03, R04,
+ R05, R06, R07, R08, R09,
+ R0A, R0B, R0C, R0D, R0E, R0F,
+ R10, R11, R12, R13, R14,
+ R15, R16,
+ TOT_REGS
+};
+
+struct upd64083_state {
+ u8 mode;
+ u8 ext_y_adc;
+ u8 regs[TOT_REGS];
+};
+
+/* Initial values when used in combination with the
+ NEC upd64031a ghost reduction chip. */
+static u8 upd64083_init[] = {
+ 0x1f, 0x01, 0xa0, 0x2d, 0x29, /* we use EXCSS=0 */
+ 0x36, 0xdd, 0x05, 0x56, 0x48,
+ 0x00, 0x3a, 0xa0, 0x05, 0x08,
+ 0x44, 0x60, 0x08, 0x52, 0xf8,
+ 0x53, 0x60, 0x10
+};
+
+/* ------------------------------------------------------------------------ */
+
+static void upd64083_log_status(struct i2c_client *client)
+{
+ u8 buf[7];
+
+ i2c_master_recv(client, buf, 7);
+ v4l_info(client, "Status: SA00=%02x SA01=%02x SA02=%02x SA03=%02x "
+ "SA04=%02x SA05=%02x SA06=%02x\n",
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void upd64083_write(struct i2c_client *client, u8 reg, u8 val)
+{
+ u8 buf[2];
+
+ buf[0] = reg;
+ buf[1] = val;
+ v4l_dbg(1, debug, client, "writing reg addr: %02x val: %02x\n", reg, val);
+ if (i2c_master_send(client, buf, 2) != 2)
+ v4l_err(client, "I/O error write 0x%02x/0x%02x\n", reg, val);
+}
+
+/* ------------------------------------------------------------------------ */
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static u8 upd64083_read(struct i2c_client *client, u8 reg)
+{
+ u8 buf[7];
+
+ if (reg >= sizeof(buf))
+ return 0xff;
+ i2c_master_recv(client, buf, sizeof(buf));
+ return buf[reg];
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static int upd64083_command(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+ struct upd64083_state *state = i2c_get_clientdata(client);
+ struct v4l2_routing *route = arg;
+
+ switch (cmd) {
+ case VIDIOC_INT_G_VIDEO_ROUTING:
+ route->input = (state->mode >> 6) | (state->ext_y_adc >> 3);
+ route->output = 0;
+ break;
+
+ case VIDIOC_INT_S_VIDEO_ROUTING:
+ {
+ u8 r00, r02;
+
+ if (route->input > 7 || (route->input & 6) == 6)
+ return -EINVAL;
+ state->mode = (route->input & 3) << 6;
+ state->ext_y_adc = (route->input & UPD64083_EXT_Y_ADC) << 3;
+ r00 = (state->regs[R00] & ~(3 << 6)) | state->mode;
+ r02 = (state->regs[R02] & ~(1 << 5)) | state->ext_y_adc;
+ upd64083_write(client, R00, r00);
+ upd64083_write(client, R02, r02);
+ break;
+ }
+
+ case VIDIOC_LOG_STATUS:
+ upd64083_log_status(client);
+ break;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ case VIDIOC_INT_G_REGISTER:
+ {
+ struct v4l2_register *reg = arg;
+
+ if (reg->i2c_id != I2C_DRIVERID_UPD64083)
+ return -EINVAL;
+ reg->val = upd64083_read(client, reg->reg & 0xff);
+ break;
+ }
+
+ case VIDIOC_INT_S_REGISTER:
+ {
+ struct v4l2_register *reg = arg;
+ u8 addr = reg->reg & 0xff;
+ u8 val = reg->val & 0xff;
+
+ if (reg->i2c_id != I2C_DRIVERID_UPD64083)
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ upd64083_write(client, addr, val);
+ break;
+ }
+#endif
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* i2c implementation */
+
+static struct i2c_driver i2c_driver;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+static int upd64083_attach(struct i2c_adapter *adapter, int address, int kind)
+#else
+static int upd64083_attach(struct i2c_adapter *adapter, int address,
+ unsigned short flags, int kind)
+#endif
+{
+ struct i2c_client *client;
+ struct upd64083_state *state;
+ int i;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return 0;
+
+ client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == NULL) {
+ return -ENOMEM;
+ }
+
+ client->addr = address;
+ client->adapter = adapter;
+ client->driver = &i2c_driver;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)
+ client->flags = I2C_CLIENT_ALLOW_USE;
+#endif
+ snprintf(client->name, sizeof(client->name) - 1, "uPD64083");
+
+ v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name);
+
+ state = kmalloc(sizeof(struct upd64083_state), GFP_KERNEL);
+ if (state == NULL) {
+ kfree(client);
+ return -ENOMEM;
+ }
+ i2c_set_clientdata(client, state);
+ /* Initially assume that a ghost reduction chip is present */
+ state->mode = 0; /* YCS mode */
+ state->ext_y_adc = (1 << 5);
+ memcpy(state->regs, upd64083_init, TOT_REGS);
+ for (i = 0; i < TOT_REGS; i++) {
+ upd64083_write(client, i, state->regs[i]);
+ }
+ i2c_attach_client(client);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ MOD_INC_USE_COUNT;
+#endif
+ return 0;
+}
+
+static int upd64083_probe(struct i2c_adapter *adapter)
+{
+#ifdef I2C_CLASS_TV_ANALOG
+ if (adapter->class & I2C_CLASS_TV_ANALOG)
+#else
+ if (adapter->id == I2C_HW_B_BT848)
+#endif
+ return i2c_probe(adapter, &addr_data, upd64083_attach);
+ return 0;
+}
+
+static int upd64083_detach(struct i2c_client *client)
+{
+ int err;
+
+ err = i2c_detach_client(client);
+ if (err)
+ return err;
+
+ kfree(client);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ MOD_DEC_USE_COUNT;
+#endif
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* i2c implementation */
+static struct i2c_driver i2c_driver = {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)
+ .owner = THIS_MODULE,
+#endif
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)
+ .name = "upd64083",
+ .flags = I2C_DF_NOTIFY,
+#else
+ .driver = {
+ .name = "upd64083",
+ },
+#endif
+ .id = I2C_DRIVERID_UPD64083,
+ .attach_adapter = upd64083_probe,
+ .detach_client = upd64083_detach,
+ .command = upd64083_command,
+};
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+EXPORT_NO_SYMBOLS;
+#endif
+
+static int __init upd64083_init_module(void)
+{
+ return i2c_add_driver(&i2c_driver);
+}
+
+static void __exit upd64083_exit_module(void)
+{
+ i2c_del_driver(&i2c_driver);
+}
+
+module_init(upd64083_init_module);
+module_exit(upd64083_exit_module);
diff --git a/linux/drivers/media/video/wm8739.c b/linux/drivers/media/video/wm8739.c
new file mode 100644
index 000000000..79394f205
--- /dev/null
+++ b/linux/drivers/media/video/wm8739.c
@@ -0,0 +1,396 @@
+/*
+ * wm8739
+ *
+ * Copyright (C) 2005 T. Adachi <tadachi@tadachi-net.com>
+ *
+ * Copyright (C) 2005 Hans Verkuil <hverkuil@xs4all.nl>
+ * - Cleanup
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "compat.h"
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/uaccess.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/videodev.h>
+#include <media/v4l2-common.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#include "i2c-compat.h"
+#include <linux/slab.h>
+#endif
+
+MODULE_DESCRIPTION("wm8739 driver");
+MODULE_AUTHOR("T. Adachi, Hans Verkuil");
+MODULE_LICENSE("GPL");
+
+static int debug = 0;
+static unsigned short normal_i2c[] = { 0x34 >> 1, 0x36 >> 1, I2C_CLIENT_END };
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+module_param(debug, int, 0644);
+#else
+MODULE_PARM(debug, "i");
+#endif
+
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
+static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
+#endif
+
+I2C_CLIENT_INSMOD;
+
+/* ------------------------------------------------------------------------ */
+
+enum {
+ R0 = 0, R1,
+ R5 = 5, R6, R7, R8, R9, R15 = 15,
+ TOT_REGS
+};
+
+struct wm8739_state {
+ u32 clock_freq;
+ u8 muted;
+ u16 volume;
+ u16 balance;
+ u8 vol_l; /* +12dB to -34.5dB 1.5dB step (5bit) def:0dB */
+ u8 vol_r; /* +12dB to -34.5dB 1.5dB step (5bit) def:0dB */
+};
+
+/* ------------------------------------------------------------------------ */
+
+static int wm8739_write(struct i2c_client *client, int reg, u16 val)
+{
+ int i;
+
+ if (reg < 0 || reg >= TOT_REGS) {
+ v4l_err(client, "Invalid register R%d\n", reg);
+ return -1;
+ }
+
+ v4l_dbg(1, debug, client, "write: %02x %02x\n", reg, val);
+
+ for (i = 0; i < 3; i++) {
+ if (i2c_smbus_write_byte_data(client, (reg << 1) |
+ (val >> 8), val & 0xff) == 0) {
+ return 0;
+ }
+ }
+ v4l_err(client, "I2C: cannot write %03x to register R%d\n", val, reg);
+ return -1;
+}
+
+/* write regs to set audio volume etc */
+static void wm8739_set_audio(struct i2c_client *client)
+{
+ struct wm8739_state *state = i2c_get_clientdata(client);
+ u16 mute = state->muted ? 0x80 : 0;
+
+ /* Volume setting: bits 0-4, 0x1f = 12 dB, 0x00 = -34.5 dB
+ * Default setting: 0x17 = 0 dB
+ */
+ wm8739_write(client, R0, (state->vol_l & 0x1f) | mute);
+ wm8739_write(client, R1, (state->vol_r & 0x1f) | mute);
+}
+
+static int wm8739_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+{
+ struct wm8739_state *state = i2c_get_clientdata(client);
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = state->muted;
+ break;
+
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = state->volume;
+ break;
+
+ case V4L2_CID_AUDIO_BALANCE:
+ ctrl->value = state->balance;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int wm8739_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+{
+ struct wm8739_state *state = i2c_get_clientdata(client);
+ unsigned int work_l, work_r;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ state->muted = ctrl->value;
+ break;
+
+ case V4L2_CID_AUDIO_VOLUME:
+ state->volume = ctrl->value;
+ break;
+
+ case V4L2_CID_AUDIO_BALANCE:
+ state->balance = ctrl->value;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ /* normalize ( 65535 to 0 -> 31 to 0 (12dB to -34.5dB) ) */
+ work_l = (min(65536 - state->balance, 32768) * state->volume) / 32768;
+ work_r = (min(state->balance, (u16)32768) * state->volume) / 32768;
+
+ state->vol_l = (long)work_l * 31 / 65535;
+ state->vol_r = (long)work_r * 31 / 65535;
+
+ /* set audio volume etc. */
+ wm8739_set_audio(client);
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static struct v4l2_queryctrl wm8739_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .name = "Volume",
+ .minimum = 0,
+ .maximum = 65535,
+ .step = 65535/100,
+ .default_value = 58880,
+ .flags = 0,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ },{
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+ .flags = 0,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ },{
+ .id = V4L2_CID_AUDIO_BALANCE,
+ .name = "Balance",
+ .minimum = 0,
+ .maximum = 65535,
+ .step = 65535/100,
+ .default_value = 32768,
+ .flags = 0,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ }
+};
+
+/* ------------------------------------------------------------------------ */
+
+static int wm8739_command(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+ struct wm8739_state *state = i2c_get_clientdata(client);
+
+ switch (cmd) {
+ case VIDIOC_INT_AUDIO_CLOCK_FREQ:
+ {
+ u32 audiofreq = *(u32 *)arg;
+
+ state->clock_freq = audiofreq;
+ wm8739_write(client, R9, 0x000); /* de-activate */
+ switch (audiofreq) {
+ case 44100:
+ wm8739_write(client, R8, 0x020); /* 256fps, fs=44.1k */
+ break;
+ case 48000:
+ wm8739_write(client, R8, 0x000); /* 256fps, fs=48k */
+ break;
+ case 32000:
+ wm8739_write(client, R8, 0x018); /* 256fps, fs=32k */
+ break;
+ default:
+ break;
+ }
+ wm8739_write(client, R9, 0x001); /* activate */
+ break;
+ }
+
+ case VIDIOC_G_CTRL:
+ return wm8739_get_ctrl(client, arg);
+
+ case VIDIOC_S_CTRL:
+ return wm8739_set_ctrl(client, arg);
+
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl *qc = arg;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(wm8739_qctrl); i++)
+ if (qc->id && qc->id == wm8739_qctrl[i].id) {
+ memcpy(qc, &wm8739_qctrl[i], sizeof(*qc));
+ return 0;
+ }
+ return -EINVAL;
+ }
+
+ case VIDIOC_LOG_STATUS:
+ v4l_info(client, "Frequency: %u Hz\n", state->clock_freq);
+ v4l_info(client, "Volume L: %02x%s\n", state->vol_l & 0x1f,
+ state->muted ? " (muted)" : "");
+ v4l_info(client, "Volume R: %02x%s\n", state->vol_r & 0x1f,
+ state->muted ? " (muted)" : "");
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* i2c implementation */
+
+static struct i2c_driver i2c_driver;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+static int wm8739_attach(struct i2c_adapter *adapter, int address, int kind)
+#else
+static int wm8739_attach(struct i2c_adapter *adapter, int address,
+ unsigned short flags, int kind)
+#endif
+{
+ struct i2c_client *client;
+ struct wm8739_state *state;
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return 0;
+
+ client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == NULL)
+ return -ENOMEM;
+
+ client->addr = address;
+ client->adapter = adapter;
+ client->driver = &i2c_driver;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)
+ client->flags = I2C_CLIENT_ALLOW_USE;
+#endif
+ snprintf(client->name, sizeof(client->name) - 1, "wm8739");
+
+ v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name);
+
+ state = kmalloc(sizeof(struct wm8739_state), GFP_KERNEL);
+ if (state == NULL) {
+ kfree(client);
+ return -ENOMEM;
+ }
+ state->vol_l = 0x17; /* 0dB */
+ state->vol_r = 0x17; /* 0dB */
+ state->muted = 0;
+ state->balance = 32768;
+ /* normalize (12dB(31) to -34.5dB(0) [0dB(23)] -> 65535 to 0) */
+ state->volume = ((long)state->vol_l + 1) * 65535 / 31;
+ state->clock_freq = 48000;
+ i2c_set_clientdata(client, state);
+
+ /* initialize wm8739 */
+ wm8739_write(client, R15, 0x00); /* reset */
+ wm8739_write(client, R5, 0x000); /* filter setting, high path, offet clear */
+ wm8739_write(client, R6, 0x000); /* ADC, OSC, Power Off mode Disable */
+ wm8739_write(client, R7, 0x049); /* Digital Audio interface format */
+ /* Enable Master mode */
+ /* 24 bit, MSB first/left justified */
+ wm8739_write(client, R8, 0x000); /* sampling control */
+ /* normal, 256fs, 48KHz sampling rate */
+ wm8739_write(client, R9, 0x001); /* activate */
+ wm8739_set_audio(client); /* set volume/mute */
+
+ i2c_attach_client(client);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ MOD_INC_USE_COUNT;
+#endif
+ return 0;
+}
+
+static int wm8739_probe(struct i2c_adapter *adapter)
+{
+#ifdef I2C_CLASS_TV_ANALOG
+ if (adapter->class & I2C_CLASS_TV_ANALOG)
+#else
+ if (adapter->id == I2C_HW_B_CX2341X)
+#endif
+ return i2c_probe(adapter, &addr_data, wm8739_attach);
+ return 0;
+}
+
+static int wm8739_detach(struct i2c_client *client)
+{
+ int err;
+
+ err = i2c_detach_client(client);
+ if (err)
+ return err;
+
+ kfree(client);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ MOD_DEC_USE_COUNT;
+#endif
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* i2c implementation */
+static struct i2c_driver i2c_driver = {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)
+ .owner = THIS_MODULE,
+#endif
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)
+ .name = "wm8739",
+ .flags = I2C_DF_NOTIFY,
+#else
+ .driver = {
+ .name = "wm8739",
+ },
+#endif
+ .id = I2C_DRIVERID_WM8739,
+ .attach_adapter = wm8739_probe,
+ .detach_client = wm8739_detach,
+ .command = wm8739_command,
+};
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+EXPORT_NO_SYMBOLS;
+#endif
+
+static int __init wm8739_init_module(void)
+{
+ return i2c_add_driver(&i2c_driver);
+}
+
+static void __exit wm8739_cleanup_module(void)
+{
+ i2c_del_driver(&i2c_driver);
+}
+
+module_init(wm8739_init_module);
+module_exit(wm8739_cleanup_module);
diff --git a/linux/include/linux/i2c-id.h b/linux/include/linux/i2c-id.h
index 6625e4aa2..679b46a6a 100644
--- a/linux/include/linux/i2c-id.h
+++ b/linux/include/linux/i2c-id.h
@@ -172,7 +172,6 @@
#define I2C_HW_B_RIVA 0x010010 /* Riva based graphics cards */
#define I2C_HW_B_IOC 0x010011 /* IOC bit-wiggling */
#define I2C_HW_B_TSUNA 0x010012 /* DEC Tsunami chipset */
-#define I2C_HW_B_FRODO 0x010013 /* 2d3D SA-1110 Development Board */
#define I2C_HW_B_OMAHA 0x010014 /* Omaha I2C interface (ARM) */
#define I2C_HW_B_GUIDE 0x010015 /* Guide bit-basher */
#define I2C_HW_B_IXP2000 0x010016 /* GPIO on IXP2000 systems */
diff --git a/linux/include/media/upd64031a.h b/linux/include/media/upd64031a.h
new file mode 100644
index 000000000..3ad6a32e1
--- /dev/null
+++ b/linux/include/media/upd64031a.h
@@ -0,0 +1,40 @@
+/*
+ * upd64031a - NEC Electronics Ghost Reduction input defines
+ *
+ * 2006 by Hans Verkuil (hverkuil@xs4all.nl)
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _UPD64031A_H_
+#define _UPD64031A_H_
+
+/* Ghost reduction modes */
+#define UPD64031A_GR_ON 0
+#define UPD64031A_GR_OFF 1
+#define UPD64031A_GR_THROUGH 3
+
+/* Direct 3D/YCS Connection */
+#define UPD64031A_3DYCS_DISABLE (0 << 2)
+#define UPD64031A_3DYCS_COMPOSITE (2 << 2)
+#define UPD64031A_3DYCS_SVIDEO (3 << 2)
+
+/* Composite sync digital separation circuit */
+#define UPD64031A_COMPOSITE_EXTERNAL (1 << 4)
+
+/* Vertical sync digital separation circuit */
+#define UPD64031A_VERTICAL_EXTERNAL (1 << 5)
+
+#endif
diff --git a/linux/include/media/upd64083.h b/linux/include/media/upd64083.h
new file mode 100644
index 000000000..59b6f32ba
--- /dev/null
+++ b/linux/include/media/upd64083.h
@@ -0,0 +1,58 @@
+/*
+ * upd6408x - NEC Electronics 3-Dimensional Y/C separation input defines
+ *
+ * 2006 by Hans Verkuil (hverkuil@xs4all.nl)
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _UPD64083_H_
+#define _UPD64083_H_
+
+/* There are two bits of information that the driver needs in order
+ to select the correct routing: the operating mode and the selection
+ of the Y input (external or internal).
+
+ The first two operating modes expect a composite signal on the Y input,
+ the second two operating modes use both the Y and C inputs.
+
+ Normally YCS_MODE is used for tuner and composite inputs, and the
+ YCNR mode is used for S-Video inputs.
+
+ The external Y-ADC is selected when the composite input comes from a
+ upd64031a ghost reduction device. If this device is not present, or
+ the input is a S-Video signal, then the internal Y-ADC input should
+ be used. */
+
+/* Operating modes: */
+
+/* YCS mode: Y/C separation (burst locked clocking) */
+#define UPD64083_YCS_MODE 0
+/* YCS+ mode: 2D Y/C separation and YCNR (burst locked clocking) */
+#define UPD64083_YCS_PLUS_MODE 1
+
+/* Note: the following two modes cannot be used in combination with the
+ external Y-ADC. */
+/* MNNR mode: frame comb type YNR+C delay (line locked clocking) */
+#define UPD64083_MNNR_MODE 2
+/* YCNR mode: frame recursive YCNR (burst locked clocking) */
+#define UPD64083_YCNR_MODE 3
+
+/* Select external Y-ADC: this should be set if this device is used in
+ combination with the upd64031a ghost reduction device.
+ Otherwise leave at 0 (use internal Y-ADC). */
+#define UPD64083_EXT_Y_ADC (1 << 2)
+
+#endif