summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
authorpboettcher@dibcom68.dibcom.fr <pboettcher@dibcom68.dibcom.fr>2006-04-07 09:31:51 +0200
committerpboettcher@dibcom68.dibcom.fr <pboettcher@dibcom68.dibcom.fr>2006-04-07 09:31:51 +0200
commitf62b12acad6cf4c6e78bc2dd7e3e445f2d239d24 (patch)
treea73819bc4ad336cafcf90648613eabd96cc23f7f /linux
parent3cdabc5516eb8974b43dc1febf8010d550c1de65 (diff)
parent2fec184983c06bf36e79ddae3c2ddf2d8ab61f2d (diff)
downloadmediapointer-dvb-s2-f62b12acad6cf4c6e78bc2dd7e3e445f2d239d24.tar.gz
mediapointer-dvb-s2-f62b12acad6cf4c6e78bc2dd7e3e445f2d239d24.tar.bz2
merge: from main
From: Patrick Boettcher <pb@linuxtv.org> merge: from main Signed-off-by: Patrick Boettcher <pb@linuxtv.org>
Diffstat (limited to 'linux')
-rw-r--r--linux/drivers/media/common/ir-functions.c1
-rw-r--r--linux/drivers/media/common/ir-keymaps.c1
-rw-r--r--linux/drivers/media/dvb/dvb-core/dmxdev.c3
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvbdev.c8
-rw-r--r--linux/drivers/media/dvb/frontends/Kconfig2
-rw-r--r--linux/drivers/media/dvb/frontends/or51132.c102
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-ci.c105
-rw-r--r--linux/drivers/media/video/Kconfig14
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-cards.c2
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-driver.c170
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-risc.c14
-rw-r--r--linux/drivers/media/video/cx25840/cx25840-vbi.c6
-rw-r--r--linux/drivers/media/video/cx88/Kconfig13
-rw-r--r--linux/drivers/media/video/cx88/cx88-alsa.c4
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-cards.c82
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-core.c2
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-i2c.c2
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-input.c2
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-video.c55
-rw-r--r--linux/drivers/media/video/em28xx/em28xx.h2
-rw-r--r--linux/drivers/media/video/ir-kbd-i2c.c3
-rw-r--r--linux/drivers/media/video/msp3400-driver.c97
-rw-r--r--linux/drivers/media/video/msp3400-driver.h6
-rw-r--r--linux/drivers/media/video/msp3400-kthreads.c135
-rw-r--r--linux/drivers/media/video/pvrusb2/Kconfig45
-rw-r--r--linux/drivers/media/video/pvrusb2/Makefile13
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-audio.c33
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c116
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.h1
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c14
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h125
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c1006
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h200
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c4
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c30
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c15
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-main.c10
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c134
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c405
-rw-r--r--linux/drivers/media/video/saa7115.c85
-rw-r--r--linux/drivers/media/video/tea5761.c2
-rw-r--r--linux/drivers/media/video/tea5767.c2
-rw-r--r--linux/drivers/media/video/tuner-core.c8
-rw-r--r--linux/drivers/media/video/tvp5150.c177
-rw-r--r--linux/drivers/media/video/v4l2-common.c15
-rw-r--r--linux/drivers/media/video/videodev.c4
-rw-r--r--linux/include/linux/dvb/dmx.h26
-rw-r--r--linux/include/linux/i2c-id.h4
-rw-r--r--linux/include/linux/videodev2.h21
-rw-r--r--linux/include/media/cx2341x.h (renamed from linux/drivers/media/video/cx2341x.h)0
-rw-r--r--linux/include/media/msp3400.h60
-rw-r--r--linux/include/media/saa7115.h11
-rw-r--r--linux/include/media/tvp5150.h34
-rw-r--r--linux/include/media/v4l2-common.h11
54 files changed, 1994 insertions, 1448 deletions
diff --git a/linux/drivers/media/common/ir-functions.c b/linux/drivers/media/common/ir-functions.c
index 8b7dd6e3e..3b988b012 100644
--- a/linux/drivers/media/common/ir-functions.c
+++ b/linux/drivers/media/common/ir-functions.c
@@ -278,4 +278,3 @@ EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
* c-basic-offset: 8
* End:
*/
-
diff --git a/linux/drivers/media/common/ir-keymaps.c b/linux/drivers/media/common/ir-keymaps.c
index 03c4a7c50..1cdd5b0df 100644
--- a/linux/drivers/media/common/ir-keymaps.c
+++ b/linux/drivers/media/common/ir-keymaps.c
@@ -1476,4 +1476,3 @@ IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = {
};
EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new);
-
diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c
index 04578df3f..988499dfd 100644
--- a/linux/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c
@@ -872,9 +872,6 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
mutex_unlock(&dmxdevfilter->mutex);
break;
- case DMX_GET_EVENT:
- break;
-
case DMX_GET_PES_PIDS:
if (!dmxdev->demux->get_pes_pids) {
ret = -EINVAL;
diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c
index 123ea8344..041ed7fd1 100644
--- a/linux/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c
@@ -93,7 +93,11 @@ static int dvb_device_open(struct inode *inode, struct file *file)
if (dvbdev && dvbdev->fops) {
int err = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
+ const struct file_operations *old_fops;
+#else
struct file_operations *old_fops;
+#endif
file->private_data = dvbdev;
old_fops = file->f_op;
@@ -226,8 +230,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
return -ENOMEM;
}
- mutex_unlock(&dvbdev_register_lock);
-
memcpy(dvbdev, template, sizeof(struct dvb_device));
dvbdev->type = type;
dvbdev->id = id;
@@ -238,6 +240,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
list_add_tail (&dvbdev->list_head, &adap->device_list);
+ mutex_unlock(&dvbdev_register_lock);
+
devfs_mk_cdev(MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
S_IFCHR | S_IRUSR | S_IWUSR,
"dvb/adapter%d/%s%d", adap->num, dnames[type], id);
diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig
index 37d5e0af1..6d90ff3f7 100644
--- a/linux/drivers/media/dvb/frontends/Kconfig
+++ b/linux/drivers/media/dvb/frontends/Kconfig
@@ -157,7 +157,7 @@ config DVB_STV0297
help
A DVB-C tuner module. Say Y when you want to support this frontend.
-comment "ATSC (North American/Korean Terresterial DTV) frontends"
+comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
depends on DVB_CORE
config DVB_NXT200X
diff --git a/linux/drivers/media/dvb/frontends/or51132.c b/linux/drivers/media/dvb/frontends/or51132.c
index 80e0f2812..619856b07 100644
--- a/linux/drivers/media/dvb/frontends/or51132.c
+++ b/linux/drivers/media/dvb/frontends/or51132.c
@@ -106,9 +106,8 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
{
struct or51132_state* state = fe->demodulator_priv;
static u8 run_buf[] = {0x7F,0x01};
- static u8 get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00};
- u8 rec_buf[14];
- u8 cmd_buf[14];
+ u8 rec_buf[8];
+ u8 cmd_buf[3];
u32 firmwareAsize, firmwareBsize;
int i,ret;
@@ -157,7 +156,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
cmd_buf[0] = 0x10;
cmd_buf[1] = 0x10;
cmd_buf[2] = 0x00;
- cmd_buf[3] = 0x00;
msleep(20); /* 20ms */
if ((ret = i2c_writebytes(state,state->config->demod_address,
cmd_buf,3))) {
@@ -167,8 +165,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
cmd_buf[0] = 0x04;
cmd_buf[1] = 0x17;
- cmd_buf[2] = 0x00;
- cmd_buf[3] = 0x00;
msleep(20); /* 20ms */
if ((ret = i2c_writebytes(state,state->config->demod_address,
cmd_buf,2))) {
@@ -178,8 +174,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
cmd_buf[0] = 0x00;
cmd_buf[1] = 0x00;
- cmd_buf[2] = 0x00;
- cmd_buf[3] = 0x00;
msleep(20); /* 20ms */
if ((ret = i2c_writebytes(state,state->config->demod_address,
cmd_buf,2))) {
@@ -189,7 +183,11 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
for(i=0;i<4;i++) {
msleep(20); /* 20ms */
- get_ver_buf[4] = i+1;
+ /* Once upon a time, this command might have had something
+ to do with getting the firmware version, but it's
+ not used anymore:
+ {0x04,0x00,0x30,0x00,i+1} */
+ /* Read 8 bytes, two bytes at a time */
if ((ret = i2c_readbytes(state,state->config->demod_address,
&rec_buf[i*2],2))) {
printk(KERN_WARNING
@@ -208,7 +206,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
cmd_buf[0] = 0x10;
cmd_buf[1] = 0x00;
cmd_buf[2] = 0x00;
- cmd_buf[3] = 0x00;
msleep(20); /* 20ms */
if ((ret = i2c_writebytes(state,state->config->demod_address,
cmd_buf,3))) {
@@ -243,7 +240,7 @@ static int or51132_sleep(struct dvb_frontend* fe)
static int or51132_setmode(struct dvb_frontend* fe)
{
struct or51132_state* state = fe->demodulator_priv;
- unsigned char cmd_buf[4];
+ unsigned char cmd_buf[3];
dprintk("setmode %d\n",(int)state->current_modulation);
/* set operation mode in Receiver 1 register; */
@@ -263,7 +260,6 @@ static int or51132_setmode(struct dvb_frontend* fe)
default:
printk("setmode:Modulation set to unsupported value\n");
};
- cmd_buf[3] = 0x00;
if (i2c_writebytes(state,state->config->demod_address,
cmd_buf,3)) {
printk(KERN_WARNING "or51132: set_mode error 1\n");
@@ -301,7 +297,6 @@ static int or51132_setmode(struct dvb_frontend* fe)
default:
printk("setmode: Modulation set to unsupported value\n");
};
- cmd_buf[3] = 0x00;
msleep(20); /* 20ms */
if (i2c_writebytes(state,state->config->demod_address,
cmd_buf,3)) {
@@ -313,6 +308,25 @@ static int or51132_setmode(struct dvb_frontend* fe)
return 0;
}
+/* Some modulations use the same firmware. This classifies modulations
+ by the firmware they use. */
+#define MOD_FWCLASS_UNKNOWN 0
+#define MOD_FWCLASS_VSB 1
+#define MOD_FWCLASS_QAM 2
+static int modulation_fw_class(fe_modulation_t modulation)
+{
+ switch(modulation) {
+ case VSB_8:
+ return MOD_FWCLASS_VSB;
+ case QAM_AUTO:
+ case QAM_64:
+ case QAM_256:
+ return MOD_FWCLASS_QAM;
+ default:
+ return MOD_FWCLASS_UNKNOWN;
+ }
+}
+
static int or51132_set_parameters(struct dvb_frontend* fe,
struct dvb_frontend_parameters *param)
{
@@ -320,45 +334,40 @@ static int or51132_set_parameters(struct dvb_frontend* fe,
u8 buf[4];
struct or51132_state* state = fe->demodulator_priv;
const struct firmware *fw;
-
- /* Change only if we are actually changing the modulation */
- if (state->current_modulation != param->u.vsb.modulation) {
- switch(param->u.vsb.modulation) {
- case VSB_8:
+ const char *fwname;
+ int clock_mode;
+
+ /* Upload new firmware only if we need a different one */
+ if (modulation_fw_class(state->current_modulation) !=
+ modulation_fw_class(param->u.vsb.modulation)) {
+ switch(modulation_fw_class(param->u.vsb.modulation)) {
+ case MOD_FWCLASS_VSB:
dprintk("set_parameters VSB MODE\n");
- printk("or51132: Waiting for firmware upload(%s)...\n",
- OR51132_VSB_FIRMWARE);
- ret = request_firmware(&fw, OR51132_VSB_FIRMWARE,
- &state->i2c->dev);
- if (ret){
- printk(KERN_WARNING "or51132: No firmware up"
- "loaded(timeout or file not found?)\n");
- return ret;
- }
+ fwname = OR51132_VSB_FIRMWARE;
+
/* Set non-punctured clock for VSB */
- state->config->set_ts_params(fe, 0);
+ clock_mode = 0;
break;
- case QAM_AUTO:
- case QAM_64:
- case QAM_256:
+ case MOD_FWCLASS_QAM:
dprintk("set_parameters QAM MODE\n");
- printk("or51132: Waiting for firmware upload(%s)...\n",
- OR51132_QAM_FIRMWARE);
- ret = request_firmware(&fw, OR51132_QAM_FIRMWARE,
- &state->i2c->dev);
- if (ret){
- printk(KERN_WARNING "or51132: No firmware up"
- "loaded(timeout or file not found?)\n");
- return ret;
- }
+ fwname = OR51132_QAM_FIRMWARE;
+
/* Set punctured clock for QAM */
- state->config->set_ts_params(fe, 1);
+ clock_mode = 1;
break;
default:
- printk("or51132:Modulation type(%d) UNSUPPORTED\n",
+ printk("or51132: Modulation type(%d) UNSUPPORTED\n",
param->u.vsb.modulation);
return -1;
- };
+ }
+ printk("or51132: Waiting for firmware upload(%s)...\n",
+ fwname);
+ ret = request_firmware(&fw, fwname, &state->i2c->dev);
+ if (ret) {
+ printk(KERN_WARNING "or51132: No firmware up"
+ "loaded(timeout or file not found?)\n");
+ return ret;
+ }
ret = or51132_load_firmware(fe, fw);
release_firmware(fw);
if (ret) {
@@ -367,7 +376,10 @@ static int or51132_set_parameters(struct dvb_frontend* fe,
return ret;
}
printk("or51132: Firmware upload complete.\n");
-
+ state->config->set_ts_params(fe, clock_mode);
+ }
+ /* Change only if we are actually changing the modulation */
+ if (state->current_modulation != param->u.vsb.modulation) {
state->current_modulation = param->u.vsb.modulation;
or51132_setmode(fe);
}
@@ -376,7 +388,7 @@ static int or51132_set_parameters(struct dvb_frontend* fe,
param->frequency, 0);
dprintk("set_parameters tuner bytes: 0x%02x 0x%02x "
"0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]);
- if (i2c_writebytes(state, state->config->pll_address ,buf, 4))
+ if (i2c_writebytes(state, state->config->pll_address, buf, 4))
printk(KERN_WARNING "or51132: set_parameters error "
"writing to tuner\n");
diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c
index 5f91036f5..e64a609cf 100644
--- a/linux/drivers/media/dvb/ttpci/budget-ci.c
+++ b/linux/drivers/media/dvb/ttpci/budget-ci.c
@@ -71,6 +71,7 @@ struct budget_ci {
struct tasklet_struct msp430_irq_tasklet;
struct tasklet_struct ciintf_irq_tasklet;
int slot_status;
+ int ci_irq;
struct dvb_ca_en50221 ca;
char ir_dev_name[50];
u8 tuner_pll_address; /* used for philips_tdm1316l configs */
@@ -276,8 +277,10 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
if (slot != 0)
return -EINVAL;
- // trigger on RISING edge during reset so we know when READY is re-asserted
- saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
+ if (budget_ci->ci_irq) {
+ // trigger on RISING edge during reset so we know when READY is re-asserted
+ saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
+ }
budget_ci->slot_status = SLOTSTATUS_RESET;
ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
msleep(1);
@@ -370,11 +373,50 @@ static void ciintf_interrupt(unsigned long data)
}
}
+static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
+{
+ struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
+ unsigned int flags;
+
+ // ensure we don't get spurious IRQs during initialisation
+ if (!budget_ci->budget.ci_present)
+ return -EINVAL;
+
+ // read the CAM status
+ flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
+ if (flags & CICONTROL_CAMDETECT) {
+ // mark it as present if it wasn't before
+ if (budget_ci->slot_status & SLOTSTATUS_NONE) {
+ budget_ci->slot_status = SLOTSTATUS_PRESENT;
+ }
+
+ // during a RESET, we check if we can read from IO memory to see when CAM is ready
+ if (budget_ci->slot_status & SLOTSTATUS_RESET) {
+ if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) {
+ budget_ci->slot_status = SLOTSTATUS_READY;
+ }
+ }
+ } else {
+ budget_ci->slot_status = SLOTSTATUS_NONE;
+ }
+
+ if (budget_ci->slot_status != SLOTSTATUS_NONE) {
+ if (budget_ci->slot_status & SLOTSTATUS_READY) {
+ return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
+ }
+ return DVB_CA_EN50221_POLL_CAM_PRESENT;
+ }
+
+ return 0;
+}
+
static int ciintf_init(struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
int flags;
int result;
+ int ci_version;
+ int ca_flags;
memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
@@ -382,16 +424,29 @@ static int ciintf_init(struct budget_ci *budget_ci)
saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);
// test if it is there
- if ((ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0) & 0xa0) != 0xa0) {
+ ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0);
+ if ((ci_version & 0xa0) != 0xa0) {
result = -ENODEV;
goto error;
}
+
// determine whether a CAM is present or not
flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
budget_ci->slot_status = SLOTSTATUS_NONE;
if (flags & CICONTROL_CAMDETECT)
budget_ci->slot_status = SLOTSTATUS_PRESENT;
+ // version 0xa2 of the CI firmware doesn't generate interrupts
+ if (ci_version == 0xa2) {
+ ca_flags = 0;
+ budget_ci->ci_irq = 0;
+ } else {
+ ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
+ DVB_CA_EN50221_FLAG_IRQ_FR |
+ DVB_CA_EN50221_FLAG_IRQ_DA;
+ budget_ci->ci_irq = 1;
+ }
+
// register CI interface
budget_ci->ca.owner = THIS_MODULE;
budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
@@ -401,23 +456,27 @@ static int ciintf_init(struct budget_ci *budget_ci)
budget_ci->ca.slot_reset = ciintf_slot_reset;
budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
+ budget_ci->ca.poll_slot_status = ciintf_poll_slot_status;
budget_ci->ca.data = budget_ci;
if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
&budget_ci->ca,
- DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
- DVB_CA_EN50221_FLAG_IRQ_FR |
- DVB_CA_EN50221_FLAG_IRQ_DA, 1)) != 0) {
+ ca_flags, 1)) != 0) {
printk("budget_ci: CI interface detected, but initialisation failed.\n");
goto error;
}
+
// Setup CI slot IRQ
- tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
- if (budget_ci->slot_status != SLOTSTATUS_NONE) {
- saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
- } else {
- saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
+ if (budget_ci->ci_irq) {
+ tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
+ if (budget_ci->slot_status != SLOTSTATUS_NONE) {
+ saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
+ } else {
+ saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
+ }
+ saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03);
}
- saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03);
+
+ // enable interface
ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
CICONTROL_RESET, 1, 0);
@@ -426,10 +485,12 @@ static int ciintf_init(struct budget_ci *budget_ci)
budget_ci->budget.ci_present = 1;
// forge a fake CI IRQ so the CAM state is setup correctly
- flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
- if (budget_ci->slot_status != SLOTSTATUS_NONE)
- flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
- dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
+ if (budget_ci->ci_irq) {
+ flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
+ if (budget_ci->slot_status != SLOTSTATUS_NONE)
+ flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
+ dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
+ }
return 0;
@@ -443,9 +504,13 @@ static void ciintf_deinit(struct budget_ci *budget_ci)
struct saa7146_dev *saa = budget_ci->budget.dev;
// disable CI interrupts
- saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03);
- saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
- tasklet_kill(&budget_ci->ciintf_irq_tasklet);
+ if (budget_ci->ci_irq) {
+ saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03);
+ saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
+ tasklet_kill(&budget_ci->ciintf_irq_tasklet);
+ }
+
+ // reset interface
ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
msleep(1);
ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
@@ -473,7 +538,7 @@ static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
if (*isr & MASK_10)
ttpci_budget_irq10_handler(dev, isr);
- if ((*isr & MASK_03) && (budget_ci->budget.ci_present))
+ if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq))
tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
}
diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig
index 911da5210..98f7201cd 100644
--- a/linux/drivers/media/video/Kconfig
+++ b/linux/drivers/media/video/Kconfig
@@ -439,8 +439,8 @@ config USB_OV511
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.
+ computer's USB port. See <file:Documentation/video4linux/ov511.txt>
+ for more information and for a list of supported cameras.
To compile this driver as a module, choose M here: the
module will be called ov511.
@@ -450,8 +450,8 @@ config USB_SE401
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.
+ computer's USB port. See <file:Documentation/video4linux/se401.txt>
+ for more information and for a list of supported cameras.
To compile this driver as a module, choose M here: the
module will be called se401.
@@ -464,8 +464,8 @@ config USB_STV680
---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.
+ See <file:Documentation/video4linux/stv680.txt> for more information
+ and for a list of supported cameras.
To compile this driver as a module, choose M here: the
module will be called stv680.
@@ -483,7 +483,7 @@ config USB_W9968CF
resolutions and framerates, but cannot be included in the official
Linux kernel for performance purposes.
- See <file:Documentation/usb/w9968cf.txt> for more informations.
+ See <file:Documentation/video4linux/w9968cf.txt> for more info.
To compile this driver as a module, choose M here: the
module will be called w9968cf.
diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c
index 51e47b7cc..f3e3c624d 100644
--- a/linux/drivers/media/video/bt8xx/bttv-cards.c
+++ b/linux/drivers/media/video/bt8xx/bttv-cards.c
@@ -2786,7 +2786,7 @@ struct tvcard bttv_tvcards[] = {
},
/* ---- card 0x88---------------------------------- */
[BTTV_BOARD_ACORP_Y878F] = {
- /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */
+ /* Mauro Carvalho Chehab <mchehab@infradead.org> */
.name = "Acorp Y878F",
.video_inputs = 3,
.audio_inputs = 1,
diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c
index 0e1aae5d0..9586f91e3 100644
--- a/linux/drivers/media/video/bt8xx/bttv-driver.c
+++ b/linux/drivers/media/video/bt8xx/bttv-driver.c
@@ -994,12 +994,12 @@ audio_mux(struct bttv *btv, int input, int mute)
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);
+ route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
+ MSP_DSP_IN_SCART, MSP_DSP_IN_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);
+ route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
+ MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
break;
case TVAUDIO_INPUT_INTERN:
/* Yes, this is the same input as for RADIO. I doubt
@@ -1007,8 +1007,8 @@ audio_mux(struct bttv *btv, int input, int mute)
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);
+ route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
+ MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
break;
case TVAUDIO_INPUT_TUNER:
default:
@@ -1044,14 +1044,11 @@ audio_input(struct bttv *btv, int input)
static void
i2c_vidiocschan(struct bttv *btv)
{
- struct video_channel c;
+ v4l2_std_id std = bttv_tvnorms[btv->tvnorm].v4l2_id;
- memset(&c,0,sizeof(c));
- c.norm = btv->tvnorm;
- c.channel = btv->input;
- bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c);
+ bttv_call_i2c_clients(btv, VIDIOC_S_STD, &std);
if (btv->c.type == BTTV_BOARD_VOODOOTV_FM)
- bttv_tda9880_setnorm(btv,c.norm);
+ bttv_tda9880_setnorm(btv,btv->tvnorm);
}
static int
@@ -1210,11 +1207,27 @@ static int get_control(struct bttv *btv, struct v4l2_control *c)
break;
if (i == BTTV_CTLS)
return -EINVAL;
- if (i >= 4 && i <= 8) {
+ if (btv->audio_hook && i >= 4 && i <= 8) {
memset(&va,0,sizeof(va));
- bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
- if (btv->audio_hook)
- btv->audio_hook(btv,&va,0);
+ btv->audio_hook(btv,&va,0);
+ switch (c->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ c->value = (VIDEO_AUDIO_MUTE & va.flags) ? 1 : 0;
+ break;
+ case V4L2_CID_AUDIO_VOLUME:
+ c->value = va.volume;
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ c->value = va.balance;
+ break;
+ case V4L2_CID_AUDIO_BASS:
+ c->value = va.bass;
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ c->value = va.treble;
+ break;
+ }
+ return 0;
}
switch (c->id) {
case V4L2_CID_BRIGHTNESS:
@@ -1231,19 +1244,11 @@ static int get_control(struct bttv *btv, struct v4l2_control *c)
break;
case V4L2_CID_AUDIO_MUTE:
- c->value = (VIDEO_AUDIO_MUTE & va.flags) ? 1 : 0;
- break;
case V4L2_CID_AUDIO_VOLUME:
- c->value = va.volume;
- break;
case V4L2_CID_AUDIO_BALANCE:
- c->value = va.balance;
- break;
case V4L2_CID_AUDIO_BASS:
- c->value = va.bass;
- break;
case V4L2_CID_AUDIO_TREBLE:
- c->value = va.treble;
+ bttv_call_i2c_clients(btv,VIDIOC_G_CTRL,c);
break;
case V4L2_CID_PRIVATE_CHROMA_AGC:
@@ -1295,11 +1300,35 @@ static int set_control(struct bttv *btv, struct v4l2_control *c)
break;
if (i == BTTV_CTLS)
return -EINVAL;
- if (i >= 4 && i <= 8) {
+ if (btv->audio_hook && i >= 4 && i <= 8) {
memset(&va,0,sizeof(va));
- bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
- if (btv->audio_hook)
- btv->audio_hook(btv,&va,0);
+ btv->audio_hook(btv,&va,0);
+ switch (c->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (c->value) {
+ va.flags |= VIDEO_AUDIO_MUTE;
+ audio_mute(btv, 1);
+ } else {
+ va.flags &= ~VIDEO_AUDIO_MUTE;
+ audio_mute(btv, 0);
+ }
+ break;
+
+ case V4L2_CID_AUDIO_VOLUME:
+ va.volume = c->value;
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ va.balance = c->value;
+ break;
+ case V4L2_CID_AUDIO_BASS:
+ va.bass = c->value;
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ va.treble = c->value;
+ break;
+ }
+ btv->audio_hook(btv,&va,1);
+ return 0;
}
switch (c->id) {
case V4L2_CID_BRIGHTNESS:
@@ -1315,26 +1344,13 @@ static int set_control(struct bttv *btv, struct v4l2_control *c)
bt848_sat(btv,c->value);
break;
case V4L2_CID_AUDIO_MUTE:
- if (c->value) {
- va.flags |= VIDEO_AUDIO_MUTE;
- audio_mute(btv, 1);
- } else {
- va.flags &= ~VIDEO_AUDIO_MUTE;
- audio_mute(btv, 0);
- }
- break;
-
+ audio_mute(btv, c->value);
+ /* fall through */
case V4L2_CID_AUDIO_VOLUME:
- va.volume = c->value;
- break;
case V4L2_CID_AUDIO_BALANCE:
- va.balance = c->value;
- break;
case V4L2_CID_AUDIO_BASS:
- va.bass = c->value;
- break;
case V4L2_CID_AUDIO_TREBLE:
- va.treble = c->value;
+ bttv_call_i2c_clients(btv,VIDIOC_S_CTRL,c);
break;
case V4L2_CID_PRIVATE_CHROMA_AGC:
@@ -1390,11 +1406,6 @@ static int set_control(struct bttv *btv, struct v4l2_control *c)
default:
return -EINVAL;
}
- if (i >= 4 && i <= 8) {
- bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va);
- if (btv->audio_hook)
- btv->audio_hook(btv,&va,1);
- }
return 0;
}
@@ -1617,12 +1628,16 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
}
case VIDIOCSFREQ:
{
- unsigned long *freq = arg;
+ struct v4l2_frequency freq;
+
+ memset(&freq, 0, sizeof(freq));
+ freq.frequency = *(unsigned long *)arg;
mutex_lock(&btv->lock);
- btv->freq=*freq;
- bttv_call_i2c_clients(btv,VIDIOCSFREQ,freq);
+ freq.type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+ btv->freq = *(unsigned long *)arg;
+ bttv_call_i2c_clients(btv,VIDIOC_S_FREQUENCY,&freq);
if (btv->has_matchbox && btv->radio_user)
- tea5757_set_freq(btv,*freq);
+ tea5757_set_freq(btv,*(unsigned long *)arg);
mutex_unlock(&btv->lock);
return 0;
}
@@ -1853,33 +1868,26 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
return -EINVAL;
mutex_lock(&btv->lock);
memset(t,0,sizeof(*t));
+ t->rxsubchans = V4L2_TUNER_SUB_MONO;
+ bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t);
strcpy(t->name, "Television");
- t->type = V4L2_TUNER_ANALOG_TV;
t->capability = V4L2_TUNER_CAP_NORM;
- t->rxsubchans = V4L2_TUNER_SUB_MONO;
+ t->type = V4L2_TUNER_ANALOG_TV;
if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC)
t->signal = 0xffff;
- {
- struct video_tuner tuner;
-
- memset(&tuner, 0, sizeof (tuner));
- tuner.rangehigh = 0xffffffffUL;
- bttv_call_i2c_clients(btv, VIDIOCGTUNER, &tuner);
- t->rangelow = tuner.rangelow;
- t->rangehigh = tuner.rangehigh;
- }
- {
+
+ if (btv->audio_hook) {
/* Hmmm ... */
struct video_audio va;
memset(&va, 0, sizeof(struct video_audio));
- bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
- if (btv->audio_hook)
- btv->audio_hook(btv,&va,0);
+ btv->audio_hook(btv,&va,0);
+ t->audmode = V4L2_TUNER_MODE_MONO;
+ t->rxsubchans = V4L2_TUNER_SUB_MONO;
if(va.mode & VIDEO_SOUND_STEREO) {
- t->audmode = V4L2_TUNER_MODE_STEREO;
- t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
+ t->audmode = V4L2_TUNER_MODE_STEREO;
+ t->rxsubchans = V4L2_TUNER_SUB_STEREO;
}
- if(va.mode & VIDEO_SOUND_LANG1) {
+ if(va.mode & VIDEO_SOUND_LANG2) {
t->audmode = V4L2_TUNER_MODE_LANG1;
t->rxsubchans = V4L2_TUNER_SUB_LANG1
| V4L2_TUNER_SUB_LANG2;
@@ -1898,10 +1906,10 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
if (0 != t->index)
return -EINVAL;
mutex_lock(&btv->lock);
- {
+ bttv_call_i2c_clients(btv, VIDIOC_S_TUNER, t);
+ if (btv->audio_hook) {
struct video_audio va;
memset(&va, 0, sizeof(struct video_audio));
- 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 ||
@@ -1911,9 +1919,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
va.mode = VIDEO_SOUND_LANG1;
else if (t->audmode == V4L2_TUNER_MODE_LANG2)
va.mode = VIDEO_SOUND_LANG2;
- bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va);
- if (btv->audio_hook)
- btv->audio_hook(btv,&va,1);
+ btv->audio_hook(btv,&va,1);
}
mutex_unlock(&btv->lock);
return 0;
@@ -1938,7 +1944,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
return -EINVAL;
mutex_lock(&btv->lock);
btv->freq = f->frequency;
- bttv_call_i2c_clients(btv,VIDIOCSFREQ,&btv->freq);
+ bttv_call_i2c_clients(btv,VIDIOC_S_FREQUENCY,f);
if (btv->has_matchbox && btv->radio_user)
tea5757_set_freq(btv,btv->freq);
mutex_unlock(&btv->lock);
@@ -1946,7 +1952,9 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
}
case VIDIOC_LOG_STATUS:
{
+ printk(KERN_INFO "bttv%d: ================= START STATUS CARD #%d =================\n", btv->c.nr, btv->c.nr);
bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, NULL);
+ printk(KERN_INFO "bttv%d: ================== END STATUS CARD #%d ==================\n", btv->c.nr, btv->c.nr);
return 0;
}
@@ -2896,12 +2904,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
return 0;
}
*c = bttv_ctls[i];
- if (i >= 4 && i <= 8) {
+ if (btv->audio_hook && i >= 4 && i <= 8) {
struct video_audio va;
memset(&va,0,sizeof(va));
- bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
- if (btv->audio_hook)
- btv->audio_hook(btv,&va,0);
+ btv->audio_hook(btv,&va,0);
switch (bttv_ctls[i].id) {
case V4L2_CID_AUDIO_VOLUME:
if (!(va.flags & VIDEO_AUDIO_VOLUME))
diff --git a/linux/drivers/media/video/bt8xx/bttv-risc.c b/linux/drivers/media/video/bt8xx/bttv-risc.c
index 53dfe0f4d..4401d7320 100644
--- a/linux/drivers/media/video/bt8xx/bttv-risc.c
+++ b/linux/drivers/media/video/bt8xx/bttv-risc.c
@@ -234,7 +234,7 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
const struct bttv_format *fmt, struct bttv_overlay *ov,
int skip_even, int skip_odd)
{
- int instructions,rc,line,maxy,start,end,skip,nskips;
+ int dwords,rc,line,maxy,start,end,skip,nskips;
struct btcx_skiplist *skips;
u32 *rp,ri,ra;
u32 addr;
@@ -243,12 +243,12 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
return -ENOMEM;
- /* estimate risc mem: worst case is (clip+1) * lines instructions
+ /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
+ sync + jump (all 2 dwords) */
- instructions = (ov->nclips + 1) *
- ((skip_even || skip_odd) ? ov->w.height>>1 : ov->w.height);
- instructions += 2;
- if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) {
+ dwords = (3 * ov->nclips + 2) *
+ ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height);
+ dwords += 4;
+ if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
kfree(skips);
return rc;
}
@@ -277,8 +277,6 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
if (line > maxy)
btcx_calc_skips(line, ov->w.width, &maxy,
skips, &nskips, ov->clips, ov->nclips);
- else
- nskips = 0;
/* write out risc code */
for (start = 0, skip = 0; start < ov->w.width; start = end) {
diff --git a/linux/drivers/media/video/cx25840/cx25840-vbi.c b/linux/drivers/media/video/cx25840/cx25840-vbi.c
index e16be5b2e..658fcb260 100644
--- a/linux/drivers/media/video/cx25840/cx25840-vbi.c
+++ b/linux/drivers/media/video/cx25840/cx25840-vbi.c
@@ -153,7 +153,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
case VIDIOC_G_FMT:
{
static u16 lcr2vbi[] = {
- 0, V4L2_SLICED_TELETEXT_PAL_B, 0, /* 1 */
+ 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
0, V4L2_SLICED_WSS_625, 0, /* 4 */
V4L2_SLICED_CAPTION_525, /* 6 */
0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
@@ -233,7 +233,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
for (i = 7; i <= 23; i++) {
for (x = 0; x <= 1; x++) {
switch (svbi->service_lines[1-x][i]) {
- case V4L2_SLICED_TELETEXT_PAL_B:
+ case V4L2_SLICED_TELETEXT_B:
lcr[i] |= 1 << (4 * x);
break;
case V4L2_SLICED_WSS_625:
@@ -284,7 +284,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
switch (id2) {
case 1:
- id2 = V4L2_SLICED_TELETEXT_PAL_B;
+ id2 = V4L2_SLICED_TELETEXT_B;
break;
case 4:
id2 = V4L2_SLICED_WSS_625;
diff --git a/linux/drivers/media/video/cx88/Kconfig b/linux/drivers/media/video/cx88/Kconfig
index 2c586f903..630273992 100644
--- a/linux/drivers/media/video/cx88/Kconfig
+++ b/linux/drivers/media/video/cx88/Kconfig
@@ -1,3 +1,7 @@
+config VIDEO_CX88_VP3054
+ tristate
+ depends on VIDEO_CX88_DVB && DVB_MT352
+
config VIDEO_CX88
tristate "Conexant 2388x (bt878 successor) support"
depends on VIDEO_DEV && PCI && I2C
@@ -73,10 +77,11 @@ config VIDEO_CX88_DVB_MT352
This adds DVB-T support for cards based on the
Connexant 2388x chip and the MT352 demodulator.
-config VIDEO_CX88_VP3054
- tristate "VP-3054 Secondary I2C Bus Support"
- default m
- depends on DVB_MT352
+config VIDEO_CX88_DVB_VP3054
+ bool "VP-3054 Secondary I2C Bus Support"
+ default y
+ depends on VIDEO_CX88_DVB_MT352
+ select VIDEO_CX88_VP3054
---help---
This adds DVB-T support for cards based on the
Connexant 2388x chip and the MT352 demodulator,
diff --git a/linux/drivers/media/video/cx88/cx88-alsa.c b/linux/drivers/media/video/cx88/cx88-alsa.c
index 80aef2421..df82e8251 100644
--- a/linux/drivers/media/video/cx88/cx88-alsa.c
+++ b/linux/drivers/media/video/cx88/cx88-alsa.c
@@ -5,7 +5,7 @@
* PCI function #1 of the cx2388x.
*
* (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org>
- * (c) 2005 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+ * (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org>
* Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org>
* Based on dummy.c by Jaroslav Kysela <perex@suse.cz>
*
@@ -137,7 +137,7 @@ MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s).");
MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards");
MODULE_AUTHOR("Ricardo Cerqueira");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@brturbo.com.br>");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Conexant,23881},"
"{{Conexant,23882},"
diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c
index 3622019e3..84b764b7d 100644
--- a/linux/drivers/media/video/em28xx/em28xx-cards.c
+++ b/linux/drivers/media/video/em28xx/em28xx-cards.c
@@ -3,7 +3,7 @@
Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
Markus Rechberger <mrechberger@gmail.com>
- Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+ Mauro Carvalho Chehab <mchehab@infradead.org>
Sascha Sommer <saschasommer@freenet.de>
This program is free software; you can redistribute it and/or modify
@@ -30,6 +30,8 @@
#include "compat.h"
#include <media/tuner.h>
#include <media/msp3400.h>
+#include <media/saa7115.h>
+#include <media/tvp5150.h>
#include <media/tveeprom.h>
#include <media/audiochip.h>
#include <media/v4l2-common.h>
@@ -47,11 +49,11 @@ struct em28xx_board em28xx_boards[] = {
.decoder = EM28XX_SAA7113,
.input = {{
.type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 0,
+ .vmux = SAA7115_COMPOSITE0,
.amux = 1,
},{
.type = EM28XX_VMUX_SVIDEO,
- .vmux = 9,
+ .vmux = SAA7115_SVIDEO3,
.amux = 1,
}},
},
@@ -65,11 +67,11 @@ struct em28xx_board em28xx_boards[] = {
.decoder = EM28XX_SAA7113,
.input = {{
.type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 0,
+ .vmux = SAA7115_COMPOSITE0,
.amux = 1,
},{
.type = EM28XX_VMUX_SVIDEO,
- .vmux = 9,
+ .vmux = SAA7115_SVIDEO3,
.amux = 1,
}},
},
@@ -83,11 +85,11 @@ struct em28xx_board em28xx_boards[] = {
.decoder = EM28XX_SAA7113,
.input = {{
.type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 0,
+ .vmux = SAA7115_COMPOSITE0,
.amux = 1,
},{
.type = EM28XX_VMUX_SVIDEO,
- .vmux = 9,
+ .vmux = SAA7115_SVIDEO3,
.amux = 1,
}},
},
@@ -101,15 +103,15 @@ struct em28xx_board em28xx_boards[] = {
.decoder = EM28XX_SAA7113,
.input = {{
.type = EM28XX_VMUX_TELEVISION,
- .vmux = 2,
+ .vmux = SAA7115_COMPOSITE2,
.amux = 1,
},{
.type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 0,
+ .vmux = SAA7115_COMPOSITE0,
.amux = 1,
},{
.type = EM28XX_VMUX_SVIDEO,
- .vmux = 9,
+ .vmux = SAA7115_SVIDEO3,
.amux = 1,
}},
},
@@ -123,15 +125,15 @@ struct em28xx_board em28xx_boards[] = {
.decoder = EM28XX_SAA7113,
.input = {{
.type = EM28XX_VMUX_TELEVISION,
- .vmux = 2,
+ .vmux = SAA7115_COMPOSITE2,
.amux = 0,
},{
.type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 0,
+ .vmux = SAA7115_COMPOSITE0,
.amux = 1,
},{
.type = EM28XX_VMUX_SVIDEO,
- .vmux = 9,
+ .vmux = SAA7115_SVIDEO3,
.amux = 1,
}},
},
@@ -147,13 +149,13 @@ struct em28xx_board em28xx_boards[] = {
/*FIXME: S-Video not tested */
.input = {{
.type = EM28XX_VMUX_TELEVISION,
- .vmux = 0,
+ .vmux = TVP5150_COMPOSITE0,
.amux = MSP_INPUT_DEFAULT,
},{
.type = EM28XX_VMUX_SVIDEO,
- .vmux = 2,
- .amux = MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1,
- MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART),
+ .vmux = TVP5150_SVIDEO,
+ .amux = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
+ MSP_DSP_IN_SCART, MSP_DSP_IN_SCART),
}},
},
#ifdef CONFIG_XC3028
@@ -167,15 +169,15 @@ struct em28xx_board em28xx_boards[] = {
.decoder = EM28XX_TVP5150,
.input = {{
.type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 2,
+ .vmux = TVP5150_COMPOSITE1,
.amux = 1,
},{
.type = EM28XX_VMUX_TELEVISION,
- .vmux = 0,
+ .vmux = TVP5150_COMPOSITE0,
.amux = 0,
},{
.type = EM28XX_VMUX_SVIDEO,
- .vmux = 9,
+ .vmux = TVP5150_SVIDEO,
.amux = 1,
}},
},
@@ -189,15 +191,15 @@ struct em28xx_board em28xx_boards[] = {
.decoder = EM28XX_TVP5150,
.input = {{
.type = EM28XX_VMUX_TELEVISION,
- .vmux = 0,
+ .vmux = TVP5150_COMPOSITE0,
.amux = 0,
},{
.type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 2,
+ .vmux = TVP5150_COMPOSITE1,
.amux = 1,
},{
.type = EM28XX_VMUX_SVIDEO,
- .vmux = 9,
+ .vmux = TVP5150_SVIDEO,
.amux = 1,
}},
},
@@ -213,15 +215,15 @@ struct em28xx_board em28xx_boards[] = {
.decoder = EM28XX_TVP5150,
.input = {{
.type = EM28XX_VMUX_TELEVISION,
- .vmux = 0,
+ .vmux = TVP5150_COMPOSITE0,
.amux = 0,
},{
.type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 2,
+ .vmux = TVP5150_COMPOSITE1,
.amux = 1,
},{
.type = EM28XX_VMUX_SVIDEO,
- .vmux = 9,
+ .vmux = TVP5150_SVIDEO,
.amux = 1,
}},
},
@@ -236,15 +238,15 @@ struct em28xx_board em28xx_boards[] = {
.decoder = EM28XX_SAA7114,
.input = {{
.type = EM28XX_VMUX_TELEVISION,
- .vmux = 4,
+ .vmux = SAA7115_COMPOSITE4,
.amux = 0,
},{
.type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 0,
+ .vmux = SAA7115_COMPOSITE0,
.amux = 1,
},{
.type = EM28XX_VMUX_SVIDEO,
- .vmux = 9,
+ .vmux = SAA7115_SVIDEO3,
.amux = 1,
}},
},
@@ -259,15 +261,15 @@ struct em28xx_board em28xx_boards[] = {
.decoder = EM28XX_SAA7113,
.input = {{
.type = EM28XX_VMUX_TELEVISION,
- .vmux = 2,
+ .vmux = SAA7115_COMPOSITE2,
.amux = 0,
},{
.type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 0,
+ .vmux = SAA7115_COMPOSITE0,
.amux = 1,
},{
.type = EM28XX_VMUX_SVIDEO,
- .vmux = 9,
+ .vmux = SAA7115_SVIDEO3,
.amux = 1,
}},
},
@@ -282,15 +284,15 @@ struct em28xx_board em28xx_boards[] = {
.decoder = EM28XX_SAA7113,
.input = {{
.type = EM28XX_VMUX_TELEVISION,
- .vmux = 2,
+ .vmux = SAA7115_COMPOSITE2,
.amux = 0,
},{
.type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 0,
+ .vmux = SAA7115_COMPOSITE0,
.amux = 1,
},{
.type = EM28XX_VMUX_SVIDEO,
- .vmux = 9,
+ .vmux = SAA7115_SVIDEO3,
.amux = 1,
}},
},
@@ -305,15 +307,15 @@ struct em28xx_board em28xx_boards[] = {
.decoder = EM28XX_SAA7113,
.input = {{
.type = EM28XX_VMUX_TELEVISION,
- .vmux = 2,
+ .vmux = SAA7115_COMPOSITE2,
.amux = 0,
},{
.type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 0,
+ .vmux = SAA7115_COMPOSITE0,
.amux = 1,
},{
.type = EM28XX_VMUX_SVIDEO,
- .vmux = 9,
+ .vmux = SAA7115_SVIDEO3,
.amux = 1,
}},
},
@@ -325,11 +327,11 @@ struct em28xx_board em28xx_boards[] = {
.decoder = EM28XX_SAA7113,
.input = {{
.type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 0,
+ .vmux = SAA7115_COMPOSITE0,
.amux = 1,
},{
.type = EM28XX_VMUX_SVIDEO,
- .vmux = 9,
+ .vmux = SAA7115_SVIDEO3,
.amux = 1,
}},
},
diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c
index febf1188e..91422b642 100644
--- a/linux/drivers/media/video/em28xx/em28xx-core.c
+++ b/linux/drivers/media/video/em28xx/em28xx-core.c
@@ -3,7 +3,7 @@
Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
Markus Rechberger <mrechberger@gmail.com>
- Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+ Mauro Carvalho Chehab <mchehab@infradead.org>
Sascha Sommer <saschasommer@freenet.de>
This program is free software; you can redistribute it and/or modify
diff --git a/linux/drivers/media/video/em28xx/em28xx-i2c.c b/linux/drivers/media/video/em28xx/em28xx-i2c.c
index b531f2839..c077c39c2 100644
--- a/linux/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/linux/drivers/media/video/em28xx/em28xx-i2c.c
@@ -3,7 +3,7 @@
Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
Markus Rechberger <mrechberger@gmail.com>
- Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+ Mauro Carvalho Chehab <mchehab@infradead.org>
Sascha Sommer <saschasommer@freenet.de>
This program is free software; you can redistribute it and/or modify
diff --git a/linux/drivers/media/video/em28xx/em28xx-input.c b/linux/drivers/media/video/em28xx/em28xx-input.c
index a8d3cd4b0..38fe35da8 100644
--- a/linux/drivers/media/video/em28xx/em28xx-input.c
+++ b/linux/drivers/media/video/em28xx/em28xx-input.c
@@ -3,7 +3,7 @@
Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
Markus Rechberger <mrechberger@gmail.com>
- Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+ Mauro Carvalho Chehab <mchehab@infradead.org>
Sascha Sommer <saschasommer@freenet.de>
This program is free software; you can redistribute it and/or modify
diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c
index 748fd6200..1093a68f0 100644
--- a/linux/drivers/media/video/em28xx/em28xx-video.c
+++ b/linux/drivers/media/video/em28xx/em28xx-video.c
@@ -3,7 +3,7 @@
Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
Markus Rechberger <mrechberger@gmail.com>
- Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+ Mauro Carvalho Chehab <mchehab@infradead.org>
Sascha Sommer <saschasommer@freenet.de>
Some parts based on SN9C10x PC Camera Controllers GPL driver made
@@ -49,7 +49,7 @@
#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
"Markus Rechberger <mrechberger@gmail.com>, " \
- "Mauro Carvalho Chehab <mchehab@brturbo.com.br>, " \
+ "Mauro Carvalho Chehab <mchehab@infradead.org>, " \
"Sascha Sommer <saschasommer@freenet.de>"
#define DRIVER_NAME "em28xx"
@@ -192,8 +192,12 @@ static int em28xx_config(struct em28xx *dev)
static void em28xx_config_i2c(struct em28xx *dev)
{
struct v4l2_frequency f;
+ struct v4l2_routing route;
+
+ route.input = INPUT(dev->ctl_input)->vmux;
+ route.output = 0;
em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, NULL);
- em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &dev->ctl_input);
+ em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL);
/* configure tuner */
@@ -231,23 +235,23 @@ static void em28xx_empty_framequeues(struct em28xx *dev)
static void video_mux(struct em28xx *dev, int index)
{
- int input, ainput;
+ int ainput;
+ struct v4l2_routing route;
- input = INPUT(index)->vmux;
+ route.input = INPUT(index)->vmux;
+ route.output = 0;
dev->ctl_input = index;
dev->ctl_ainput = INPUT(index)->amux;
- em28xx_i2c_call_clients(dev, VIDIOC_S_INPUT, &input);
+ em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
- em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput);
+ em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,route.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);
route.input = dev->ctl_ainput;
- route.output = MSP_OUTPUT(MSP_OUT_SCART1_DA);
+ route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
/* Note: this is msp3400 specific */
em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route);
ainput = EM28XX_AUDIO_SRC_TUNER;
@@ -1207,26 +1211,16 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
case VIDIOC_G_TUNER:
{
struct v4l2_tuner *t = arg;
- int status = 0;
if (0 != t->index)
return -EINVAL;
memset(t, 0, sizeof(*t));
strcpy(t->name, "Tuner");
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM;
- t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */
-/* t->signal = 0xffff;*/
-/* em28xx_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/
- /* No way to get signal strength? */
mutex_lock(&dev->lock);
- em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
- &status);
+ /* let clients fill in the remainder of this struct */
+ em28xx_i2c_call_clients(dev, cmd, t);
mutex_unlock(&dev->lock);
- t->signal =
- (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
-
em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal,
t->afc);
return 0;
@@ -1234,26 +1228,13 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
case VIDIOC_S_TUNER:
{
struct v4l2_tuner *t = arg;
- int status = 0;
if (0 != t->index)
return -EINVAL;
- memset(t, 0, sizeof(*t));
- strcpy(t->name, "Tuner");
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM;
- t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */
-/* t->signal = 0xffff; */
- /* No way to get signal strength? */
mutex_lock(&dev->lock);
- em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
- &status);
+ /* let clients handle this */
+ em28xx_i2c_call_clients(dev, cmd, t);
mutex_unlock(&dev->lock);
- t->signal =
- (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
-
- em28xx_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n",
- t->signal, t->afc);
return 0;
}
case VIDIOC_G_FREQUENCY:
diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h
index c560ab329..97744214b 100644
--- a/linux/drivers/media/video/em28xx/em28xx.h
+++ b/linux/drivers/media/video/em28xx/em28xx.h
@@ -3,7 +3,7 @@
Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
Ludovico Cavedon <cavedon@sssup.it>
- Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+ Mauro Carvalho Chehab <mchehab@infradead.org>
Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de>
diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c
index ab1c47648..15ce0ff08 100644
--- a/linux/drivers/media/video/ir-kbd-i2c.c
+++ b/linux/drivers/media/video/ir-kbd-i2c.c
@@ -410,7 +410,6 @@ static int ir_probe(struct i2c_adapter *adap)
*/
static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
- static const int probe_cx2341x[] = { 0x18, 0x7a, -1};
static const int probe_saa7134[] = { 0x7a, 0x47, -1 };
static const int probe_em28XX[] = { 0x30, 0x47, -1 };
const int *probe = NULL;
@@ -423,7 +422,7 @@ static int ir_probe(struct i2c_adapter *adap)
probe = probe_bttv;
break;
case I2C_HW_B_CX2341X:
- probe = probe_cx2341x;
+ probe = probe_bttv;
break;
case I2C_HW_SAA7134:
probe = probe_saa7134;
diff --git a/linux/drivers/media/video/msp3400-driver.c b/linux/drivers/media/video/msp3400-driver.c
index b52e5bdea..837894adb 100644
--- a/linux/drivers/media/video/msp3400-driver.c
+++ b/linux/drivers/media/video/msp3400-driver.c
@@ -302,35 +302,24 @@ void msp_set_scart(struct i2c_client *client, int in, int out)
msp_write_dem(client, 0x40, state->i2s_mode);
}
-void msp_set_mute(struct i2c_client *client)
-{
- struct msp_state *state = i2c_get_clientdata(client);
-
- v4l_dbg(1, msp_debug, client, "mute audio\n");
- msp_write_dsp(client, 0x0000, 0);
- msp_write_dsp(client, 0x0007, 1);
- if (state->has_scart2_out_volume)
- msp_write_dsp(client, 0x0040, 1);
- if (state->has_headphones)
- msp_write_dsp(client, 0x0006, 0);
-}
-
void msp_set_audio(struct i2c_client *client)
{
struct msp_state *state = i2c_get_clientdata(client);
int bal = 0, bass, treble, loudness;
int val = 0;
+ int reallymuted = state->muted | state->scan_in_progress;
- if (!state->muted)
+ if (!reallymuted)
val = (state->volume * 0x7f / 65535) << 8;
- v4l_dbg(1, msp_debug, client, "mute=%s volume=%d\n",
- state->muted ? "on" : "off", state->volume);
+ v4l_dbg(1, msp_debug, client, "mute=%s scanning=%s volume=%d\n",
+ state->muted ? "on" : "off", state->scan_in_progress ? "yes" : "no",
+ state->volume);
msp_write_dsp(client, 0x0000, val);
- msp_write_dsp(client, 0x0007, state->muted ? 0x1 : (val | 0x1));
+ msp_write_dsp(client, 0x0007, reallymuted ? 0x1 : (val | 0x1));
if (state->has_scart2_out_volume)
- msp_write_dsp(client, 0x0040, state->muted ? 0x1 : (val | 0x1));
+ msp_write_dsp(client, 0x0040, reallymuted ? 0x1 : (val | 0x1));
if (state->has_headphones)
msp_write_dsp(client, 0x0006, val);
if (!state->has_sound_processing)
@@ -383,7 +372,6 @@ static void msp_wake_thread(struct i2c_client *client)
if (NULL == state->kthread)
return;
- msp_set_mute(client);
state->watch_stereo = 0;
state->restart = 1;
wake_up_interruptible(&state->wq);
@@ -427,19 +415,15 @@ int msp_sleep(struct msp_state *state, int timeout)
/* ------------------------------------------------------------------------ */
-static int msp_mode_v4l2_to_v4l1(int rxsubchans)
+static int msp_mode_v4l2_to_v4l1(int rxsubchans, int audmode)
{
- int mode = 0;
-
- if (rxsubchans & V4L2_TUNER_SUB_STEREO)
- mode |= VIDEO_SOUND_STEREO;
- if (rxsubchans & V4L2_TUNER_SUB_LANG2)
- mode |= VIDEO_SOUND_LANG2 | VIDEO_SOUND_STEREO;
- if (rxsubchans & V4L2_TUNER_SUB_LANG1)
- mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_STEREO;
- if (mode == 0)
- mode |= VIDEO_SOUND_MONO;
- return mode;
+ if (rxsubchans == V4L2_TUNER_SUB_MONO)
+ return VIDEO_SOUND_MONO;
+ if (rxsubchans == V4L2_TUNER_SUB_STEREO)
+ return VIDEO_SOUND_STEREO;
+ if (audmode == V4L2_TUNER_MODE_LANG2)
+ return VIDEO_SOUND_LANG2;
+ return VIDEO_SOUND_LANG1;
}
static int msp_mode_v4l1_to_v4l2(int mode)
@@ -658,7 +642,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
break;
if (state->opmode == OPMODE_AUTOSELECT)
msp_detect_stereo(client);
- va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans);
+ va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans, state->audmode);
break;
}
@@ -673,7 +657,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
state->treble = va->treble;
msp_set_audio(client);
- if (va->mode != 0 && state->radio == 0) {
+ if (va->mode != 0 && state->radio == 0 &&
+ state->audmode != msp_mode_v4l1_to_v4l2(va->mode)) {
state->audmode = msp_mode_v4l1_to_v4l2(va->mode);
msp_set_audmode(client);
}
@@ -740,20 +725,31 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
int sc_in = rt->input & 0x7;
int sc1_out = rt->output & 0xf;
int sc2_out = (rt->output >> 4) & 0xf;
- u16 val;
+ u16 val, reg;
+ int i;
+ int extern_input = 1;
+ if (state->routing.input == rt->input &&
+ state->routing.output == rt->output)
+ break;
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));
+ /* check if the tuner input is used */
+ for (i = 0; i < 5; i++) {
+ if (((rt->input >> (4 + i * 4)) & 0xf) == 0)
+ extern_input = 0;
}
+ if (extern_input)
+ state->mode = MSP_MODE_EXTERN;
+ else
+ state->mode = MSP_MODE_AM_DETECT;
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);
+ reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb;
+ val = msp_read_dem(client, reg);
+ msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8));
+ /* wake thread when a new input is chosen */
msp_wake_thread(client);
break;
}
@@ -768,7 +764,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
msp_detect_stereo(client);
vt->audmode = state->audmode;
vt->rxsubchans = state->rxsubchans;
- vt->capability = V4L2_TUNER_CAP_STEREO |
+ vt->capability |= V4L2_TUNER_CAP_STEREO |
V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
break;
}
@@ -779,6 +775,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
if (state->radio) /* TODO: add mono/stereo support for radio */
break;
+ if (state->audmode == vt->audmode)
+ break;
state->audmode = vt->audmode;
/* only set audmode */
msp_set_audmode(client);
@@ -857,7 +855,9 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
case MSP_MODE_EXTERN: p = "External input"; break;
default: p = "unknown"; break;
}
- if (state->opmode == OPMODE_MANUAL) {
+ if (state->mode == MSP_MODE_EXTERN) {
+ v4l_info(client, "Mode: %s\n", p);
+ } else if (state->opmode == OPMODE_MANUAL) {
v4l_info(client, "Mode: %s (%s%s)\n", p,
(state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
(state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
@@ -962,7 +962,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
memset(state, 0, sizeof(*state));
state->v4l2_std = V4L2_STD_NTSC;
- state->audmode = V4L2_TUNER_MODE_LANG1;
+ state->audmode = V4L2_TUNER_MODE_STEREO;
state->volume = 58880; /* 0db gain */
state->balance = 32768; /* 0db gain */
state->bass = 32768;
@@ -1010,13 +1010,16 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
state->has_radio = msp_revision >= 'G';
/* Has headphones output: not for stripped down products */
state->has_headphones = msp_prod_lo < 5;
+ /* Has scart2 input: not in stripped down products of the '3' family */
+ state->has_scart2 = msp_family >= 4 || msp_prod_lo < 7;
+ /* Has scart3 input: not in stripped down products of the '3' family */
+ state->has_scart3 = msp_family >= 4 || msp_prod_lo < 5;
/* Has scart4 input: not in pre D revisions, not in stripped D revs */
state->has_scart4 = msp_family >= 4 || (msp_revision >= 'D' && msp_prod_lo < 5);
- /* Has scart2 and scart3 inputs and scart2 output: not in stripped
- down products of the '3' family */
- state->has_scart23_in_scart2_out = msp_family >= 4 || msp_prod_lo < 5;
+ /* Has scart2 output: not in stripped down products of the '3' family */
+ state->has_scart2_out = msp_family >= 4 || msp_prod_lo < 5;
/* Has scart2 a volume control? Not in pre-D revisions. */
- state->has_scart2_out_volume = msp_revision > 'C' && state->has_scart23_in_scart2_out;
+ state->has_scart2_out_volume = msp_revision > 'C' && state->has_scart2_out;
/* Has a configurable i2s out? */
state->has_i2s_conf = msp_revision >= 'G' && msp_prod_lo < 7;
/* Has subwoofer output: not in pre-D revs and not in stripped down products */
diff --git a/linux/drivers/media/video/msp3400-driver.h b/linux/drivers/media/video/msp3400-driver.h
index 1b03cc5a9..3e26d7b4d 100644
--- a/linux/drivers/media/video/msp3400-driver.h
+++ b/linux/drivers/media/video/msp3400-driver.h
@@ -55,8 +55,10 @@ struct msp_state {
u8 has_radio;
u8 has_headphones;
u8 has_ntsc_jp_d_k3;
+ u8 has_scart2;
+ u8 has_scart3;
u8 has_scart4;
- u8 has_scart23_in_scart2_out;
+ u8 has_scart2_out;
u8 has_scart2_out_volume;
u8 has_i2s_conf;
u8 has_subwoofer;
@@ -84,6 +86,7 @@ struct msp_state {
int volume, muted;
int balance, loudness;
int bass, treble;
+ int scan_in_progress;
/* thread */
struct task_struct *kthread;
@@ -103,7 +106,6 @@ int msp_read_dem(struct i2c_client *client, int addr);
int msp_read_dsp(struct i2c_client *client, int addr);
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_sleep(struct msp_state *state, int timeout);
diff --git a/linux/drivers/media/video/msp3400-kthreads.c b/linux/drivers/media/video/msp3400-kthreads.c
index 4b0d6340a..20702d71a 100644
--- a/linux/drivers/media/video/msp3400-kthreads.c
+++ b/linux/drivers/media/video/msp3400-kthreads.c
@@ -176,7 +176,7 @@ static void msp_set_source(struct i2c_client *client, u16 src)
msp_write_dsp(client, 0x000a, src);
msp_write_dsp(client, 0x000b, src);
msp_write_dsp(client, 0x000c, src);
- if (state->has_scart23_in_scart2_out)
+ if (state->has_scart2_out)
msp_write_dsp(client, 0x0041, src);
}
@@ -246,16 +246,25 @@ 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;
+ /* Note: for the C and D revs no NTSC stereo + SAP is possible as
+ the hardware does not support SAP. So the rxsubchans combination
+ of STEREO | LANG2 does not occur. */
+
+ if (state->mode != MSP_MODE_EXTERN) {
+ /* switch to mono if only mono is available */
+ if (state->rxsubchans == V4L2_TUNER_SUB_MONO)
+ audmode = V4L2_TUNER_MODE_MONO;
+ /* if bilingual */
+ else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) {
+ /* and mono or stereo, then fallback to lang1 */
+ if (audmode == V4L2_TUNER_MODE_MONO ||
+ audmode == V4L2_TUNER_MODE_STEREO)
+ audmode = V4L2_TUNER_MODE_LANG1;
+ }
+ /* if stereo, and audmode is not mono, then switch to stereo */
+ else if (audmode != V4L2_TUNER_MODE_MONO)
+ audmode = V4L2_TUNER_MODE_STEREO;
+ }
/* switch demodulator */
switch (state->mode) {
@@ -314,6 +323,7 @@ static void msp3400c_set_audmode(struct i2c_client *client)
}
/* switch audio */
+ v4l_dbg(1, msp_debug, client, "set audmode %d\n", audmode);
switch (audmode) {
case V4L2_TUNER_MODE_STEREO:
case V4L2_TUNER_MODE_LANG1_LANG2:
@@ -381,7 +391,7 @@ static int msp3400c_detect_stereo(struct i2c_client *client)
if (val > 32767)
val -= 65536;
v4l_dbg(2, msp_debug, client, "stereo detect register: %d\n", val);
- if (val > 4096) {
+ if (val > 8192) {
rxsubchans = V4L2_TUNER_SUB_STEREO;
} else if (val < -4096) {
rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
@@ -485,19 +495,23 @@ int msp3400c_thread(void *data)
if (state->radio || MSP_MODE_EXTERN == state->mode) {
/* no carrier scan, just unmute */
v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n");
+ state->scan_in_progress = 0;
+ state->rxsubchans = V4L2_TUNER_SUB_STEREO;
msp_set_audio(client);
continue;
}
- /* mute */
- msp_set_mute(client);
+ /* mute audio */
+ state->scan_in_progress = 1;
+ msp_set_audio(client);
+
msp3400c_set_mode(client, MSP_MODE_AM_DETECT);
val1 = val2 = 0;
max1 = max2 = -1;
state->watch_stereo = 0;
state->nicam_on = 0;
- /* some time for the tuner to sync */
+ /* wait for tuner to settle down after a channel change */
if (msp_sleep(state, 200))
goto restart;
@@ -573,7 +587,6 @@ int msp3400c_thread(void *data)
/* B/G NICAM */
state->second = msp3400c_carrier_detect_55[max2].cdo;
msp3400c_set_mode(client, MSP_MODE_FM_NICAM1);
- msp3400c_set_carrier(client, state->second, state->main);
state->nicam_on = 1;
state->watch_stereo = 1;
} else {
@@ -584,7 +597,6 @@ int msp3400c_thread(void *data)
/* PAL I NICAM */
state->second = MSP_CARRIER(6.552);
msp3400c_set_mode(client, MSP_MODE_FM_NICAM2);
- msp3400c_set_carrier(client, state->second, state->main);
state->nicam_on = 1;
state->watch_stereo = 1;
break;
@@ -598,13 +610,11 @@ int msp3400c_thread(void *data)
/* L NICAM or AM-mono */
state->second = msp3400c_carrier_detect_65[max2].cdo;
msp3400c_set_mode(client, MSP_MODE_AM_NICAM);
- msp3400c_set_carrier(client, state->second, state->main);
state->watch_stereo = 1;
} else if (max2 == 0 && state->has_nicam) {
/* D/K NICAM */
state->second = msp3400c_carrier_detect_65[max2].cdo;
msp3400c_set_mode(client, MSP_MODE_FM_NICAM1);
- msp3400c_set_carrier(client, state->second, state->main);
state->nicam_on = 1;
state->watch_stereo = 1;
} else {
@@ -616,26 +626,26 @@ int msp3400c_thread(void *data)
no_second:
state->second = msp3400c_carrier_detect_main[max1].cdo;
msp3400c_set_mode(client, MSP_MODE_FM_TERRA);
- msp3400c_set_carrier(client, state->second, state->main);
- state->rxsubchans = V4L2_TUNER_SUB_MONO;
break;
}
+ msp3400c_set_carrier(client, state->second, state->main);
/* unmute */
- msp_set_audio(client);
+ state->scan_in_progress = 0;
msp3400c_set_audmode(client);
+ msp_set_audio(client);
if (msp_debug)
msp3400c_print_mode(client);
/* monitor tv audio mode, the first time don't wait
so long to get a quick stereo/bilingual result */
- if (msp_sleep(state, 1000))
- goto restart;
+ count = 3;
while (state->watch_stereo) {
- watch_stereo(client);
- if (msp_sleep(state, 5000))
+ if (msp_sleep(state, count ? 1000 : 5000))
goto restart;
+ if (count) count--;
+ watch_stereo(client);
}
}
v4l_dbg(1, msp_debug, client, "thread: exit\n");
@@ -653,7 +663,7 @@ int msp3410d_thread(void *data)
{
struct i2c_client *client = data;
struct msp_state *state = i2c_get_clientdata(client);
- int val, i, std;
+ int val, i, std, count;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
msp_setup_thread(state);
@@ -678,16 +688,14 @@ int msp3410d_thread(void *data)
if (state->mode == MSP_MODE_EXTERN) {
/* no carrier scan needed, just unmute */
v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n");
+ state->scan_in_progress = 0;
msp_set_audio(client);
continue;
}
- /* put into sane state (and mute) */
- msp_reset(client);
-
- /* some time for the tuner to sync */
- if (msp_sleep(state,200))
- goto restart;
+ /* mute audio */
+ state->scan_in_progress = 1;
+ msp_set_audio(client);
/* start autodetect. Note: autodetect is not supported for
NTSC-M and radio, hence we force the standard in those cases. */
@@ -698,6 +706,10 @@ int msp3410d_thread(void *data)
state->watch_stereo = 0;
state->nicam_on = 0;
+ /* wait for tuner to settle down after a channel change */
+ if (msp_sleep(state, 200))
+ goto restart;
+
if (msp_debug)
v4l_dbg(2, msp_debug, client, "setting standard: %s (0x%04x)\n",
msp_standard_std_name(std), std);
@@ -727,6 +739,7 @@ int msp3410d_thread(void *data)
state->main = msp_stdlist[i].main;
state->second = msp_stdlist[i].second;
state->std = val;
+ state->rxsubchans = V4L2_TUNER_SUB_MONO;
if (msp_amsound && !state->radio && (state->v4l2_std & V4L2_STD_SECAM) &&
(val != 0x0009)) {
@@ -748,20 +761,17 @@ int msp3410d_thread(void *data)
else
state->mode = MSP_MODE_FM_NICAM1;
/* just turn on stereo */
- state->rxsubchans = V4L2_TUNER_SUB_STEREO;
state->nicam_on = 1;
state->watch_stereo = 1;
break;
case 0x0009:
state->mode = MSP_MODE_AM_NICAM;
- state->rxsubchans = V4L2_TUNER_SUB_MONO;
state->nicam_on = 1;
state->watch_stereo = 1;
break;
case 0x0020: /* BTSC */
/* The pre-'G' models only have BTSC-mono */
state->mode = MSP_MODE_BTSC;
- state->rxsubchans = V4L2_TUNER_SUB_MONO;
break;
case 0x0040: /* FM radio */
state->mode = MSP_MODE_FM_RADIO;
@@ -771,15 +781,12 @@ int msp3410d_thread(void *data)
msp3400c_set_mode(client, MSP_MODE_FM_RADIO);
msp3400c_set_carrier(client, MSP_CARRIER(10.7),
MSP_CARRIER(10.7));
- /* 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:
state->mode = MSP_MODE_FM_TERRA;
- state->rxsubchans = V4L2_TUNER_SUB_MONO;
state->watch_stereo = 1;
break;
}
@@ -793,20 +800,19 @@ int msp3410d_thread(void *data)
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);
+ /* unmute */
msp3400c_set_audmode(client);
+ state->scan_in_progress = 0;
+ msp_set_audio(client);
/* monitor tv audio mode, the first time don't wait
so long to get a quick stereo/bilingual result */
- if (msp_sleep(state, 1000))
- goto restart;
+ count = 3;
while (state->watch_stereo) {
- watch_stereo(client);
- if (msp_sleep(state, 5000))
+ if (msp_sleep(state, count ? 1000 : 5000))
goto restart;
+ if (count) count--;
+ watch_stereo(client);
}
}
v4l_dbg(1, msp_debug, client, "thread: exit\n");
@@ -869,27 +875,27 @@ static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
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;
+ case V4L2_TUNER_MODE_STEREO:
+ case V4L2_TUNER_MODE_LANG1:
+ default:
+ source = 3; /* stereo or A */
+ matrix = 0x00;
+ break;
}
- if (in == MSP_DSP_OUT_TUNER)
+ if (in == MSP_DSP_IN_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)
+ else if (in >= MSP_DSP_IN_MAIN_AVC && state->has_dolby_pro_logic)
source = ((in + 1) << 8) | matrix;
else
source = (in << 8) | matrix;
@@ -909,7 +915,7 @@ static void msp34xxg_set_sources(struct i2c_client *client)
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)
+ if (state->has_scart2_out)
msp34xxg_set_source(client, 0x0041, (in >> 16) & 0xf);
msp34xxg_set_source(client, 0x000b, (in >> 20) & 0xf);
}
@@ -927,10 +933,6 @@ static void msp34xxg_reset(struct i2c_client *client)
msp_reset(client);
- /* make sure that input/output is muted (paranoid mode) */
- /* ACB, mute DSP input, mute SCART 1 */
- msp_write_dsp(client, 0x13, 0x0f20);
-
if (state->has_i2s_conf)
msp_write_dem(client, 0x40, state->i2s_mode);
@@ -987,6 +989,14 @@ int msp34xxg_thread(void *data)
#endif
break;
+ if (state->mode == MSP_MODE_EXTERN) {
+ /* no carrier scan needed, just unmute */
+ v4l_dbg(1, msp_debug, client, "thread: no carrier scan\n");
+ state->scan_in_progress = 0;
+ msp_set_audio(client);
+ continue;
+ }
+
/* setup the chip*/
msp34xxg_reset(client);
state->std = state->radio ? 0x40 : msp_standard;
@@ -1018,6 +1028,11 @@ int msp34xxg_thread(void *data)
v4l_dbg(1, msp_debug, client, "detected standard: %s (0x%04x)\n",
msp_standard_std_name(state->std), state->std);
+ if (state->std == 9) {
+ /* AM NICAM mode */
+ msp_write_dsp(client, 0x0e, 0x7c00);
+ }
+
/* unmute: dispatch sound to scart output, set scart volume */
msp_set_audio(client);
diff --git a/linux/drivers/media/video/pvrusb2/Kconfig b/linux/drivers/media/video/pvrusb2/Kconfig
index 9824ad267..629dc4e05 100644
--- a/linux/drivers/media/video/pvrusb2/Kconfig
+++ b/linux/drivers/media/video/pvrusb2/Kconfig
@@ -12,3 +12,48 @@ config VIDEO_PVRUSB2
To compile this driver as a module, choose M here: the
module will be called pvrusb2
+
+config VIDEO_PVRUSB2_24XXX
+ bool "Hauppauge WinTV-PVR USB2 support for 24xxx model series"
+ depends on VIDEO_PVRUSB2 && EXPERIMENTAL
+ ---help---
+ This option enables inclusion of additional logic to operate
+ newer WinTV-PVR USB2 devices whose model number is of the
+ form "24xxx" (leading prefix of "24" followed by 3 digits).
+ To see if you may need this option, examine the white
+ sticker on the underside of your device. Enabling this
+ option will not harm support for older devices, however it
+ is a separate option because of the experimental nature of
+ this new feature.
+
+ If you are in doubt, say N.
+
+ Note: This feature is _very_ experimental. You have been
+ warned.
+
+config VIDEO_PVRUSB2_SYSFS
+ bool "pvrusb2 sysfs support"
+ default y
+ depends on VIDEO_PVRUSB2 && SYSFS && EXPERIMENTAL
+ ---help---
+ This option enables the operation of a sysfs based
+ interface for query and control of the pvrusb2 driver.
+
+ This is not generally needed for v4l applications,
+ although certain applications are optimized to take
+ advantage of this feature.
+
+ If you are in doubt, say Y.
+
+ Note: This feature is experimental and subject to change.
+
+config VIDEO_PVRUSB2_DEBUGIFC
+ bool "pvrusb2 debug interface"
+ depends on VIDEO_PVRUSB2_SYSFS
+ ---help---
+ This option enables the inclusion of a debug interface
+ in the pvrusb2 driver, hosted through sysfs.
+
+ You do not need to select this option unless you plan
+ on debugging the driver or performing a manual firmware
+ extraction.
diff --git a/linux/drivers/media/video/pvrusb2/Makefile b/linux/drivers/media/video/pvrusb2/Makefile
index 4a37fe723..53fccce4f 100644
--- a/linux/drivers/media/video/pvrusb2/Makefile
+++ b/linux/drivers/media/video/pvrusb2/Makefile
@@ -1,11 +1,18 @@
+obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o
+obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o
+
+obj-pvrusb2-24xxx-$(CONFIG_VIDEO_PVRUSB2_24XXX) := \
+ pvrusb2-cx2584x-v4l.o \
+ pvrusb2-wm8775.o
+
pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \
pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \
pvrusb2-encoder.o pvrusb2-video-v4l.o \
pvrusb2-eeprom.o pvrusb2-tuner.o pvrusb2-demod.o \
pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \
- pvrusb2-sysfs.o pvrusb2-context.o pvrusb2-io.o \
- pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \
- pvrusb2-ioread.o pvrusb2-debugifc.o
+ pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \
+ $(obj-pvrusb2-24xxx-y) \
+ $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y)
obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c b/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c
index 79395d540..7f29a8821 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -37,26 +37,6 @@ struct pvr2_msp3400_handler {
};
-static int xlat_audiomode_to_v4l2(int id)
-{
- switch (id) {
- case PVR2_CVAL_AUDIOMODE_MONO:
- return V4L2_TUNER_MODE_MONO;
- case PVR2_CVAL_AUDIOMODE_STEREO:
- return V4L2_TUNER_MODE_STEREO;
- case PVR2_CVAL_AUDIOMODE_SAP:
- return V4L2_TUNER_MODE_SAP;
- case PVR2_CVAL_AUDIOMODE_LANG1:
- return V4L2_TUNER_MODE_LANG1;
- case PVR2_CVAL_AUDIOMODE_LANG2:
- return V4L2_TUNER_MODE_LANG2;
- case PVR2_CVAL_AUDIOMODE_LANG1_LANG2:
- return V4L2_TUNER_MODE_LANG1_LANG2;
- }
- return V4L2_TUNER_MODE_STEREO;
-}
-
-
/* This function selects the correct audio input source */
static void set_stereo(struct pvr2_msp3400_handler *ctxt)
{
@@ -68,13 +48,12 @@ static void set_stereo(struct pvr2_msp3400_handler *ctxt)
if (hdw->controls[PVR2_CID_INPUT].value == PVR2_CVAL_INPUT_TV) {
struct v4l2_tuner vt;
memset(&vt,0,sizeof(vt));
- vt.audmode = xlat_audiomode_to_v4l2(
- hdw->controls[PVR2_CID_AUDIOMODE].value);
+ vt.audmode = hdw->controls[PVR2_CID_AUDIOMODE].value;
pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_TUNER,&vt);
}
route.input = MSP_INPUT_DEFAULT;
- route.output = MSP_OUTPUT(MSP_OUT_SCART1_DA);
+ route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
switch (hdw->controls[PVR2_CID_INPUT].value) {
case PVR2_CVAL_INPUT_TV:
break;
@@ -83,14 +62,14 @@ static void set_stereo(struct pvr2_msp3400_handler *ctxt)
we're still using the tuner. */
/* HV: actually it is more likely to be the SCART2 input if
the ivtv experience is any indication. */
- route.input = MSP_INPUT(MSP_IN_SCART_2, MSP_IN_TUNER_1,
- MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART);
+ route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
+ MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
break;
case PVR2_CVAL_INPUT_SVIDEO:
case PVR2_CVAL_INPUT_COMPOSITE:
/* SCART 1 input */
- route.input = MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1,
- MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART);
+ route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
+ MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
break;
}
pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
index 60ee45ca2..78bc968c0 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
@@ -27,56 +27,7 @@
#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__)
-/*
-
- isely@pobox.com 16-Oct-2005 - There are two method by which we can
- theoretically retrieve information from the device's eeprom:
-
- Method #1: We expect tveeprom to attach to our I2C adapter as a
- client, in which case we send it a command to tell us what it
- knows about the device. This is the "indirect" method.
-
- Method #2: We retrieve the eeprom contents ourselves and call into
- tveeprom_hauppauge_analog() to parse the data and tell us what
- it knows about the device. This is the "direct" method.
-
- Unfortunately it isn't perfectly clear which method is the best.
- They each have pros and cons:
-
- #1 is simpler & more portable and has an API which is more stable.
-
- #1 doesn't provide as much information as #2 does. For example, we
- can't retrieve the device's serial number with method #1.
-
- #1 requires that tveeprom.ko autonomously detect the eeprom chip on
- its own; we can't help it out here. Worse still, it seems that
- the eeprom in some PVR USB2 devices (like mine) can't be detected
- correctly (I don't see an ack on a zero length write which is
- what the I2C core attempts).
-
- #2 uses an unstable API. Current the ivtv implementation of #2 uses
- a completely different tveeprom struct than the v4l
- implementation of #2. This causes a usability nightmare.
-
- Since I can't decide, both methods are implemented below. Method #2
- (direct) is the default choice, but if you want to try method #1,
- then define PVR2_EEPROM_INDIRECT and cross your fingers...
- If you use method #1, please be aware that you won't have a serial
- number for the device and thus the sysfs interface may be a little
- different. In addition, if tveeprom.ko fails to detect the eeprom
- you may have to force it using standard i2c module options (try
- force=-1,80). FINALLY (and this may foreclose this option for you
- completely), the PVR USB2 eeprom seems to have valid data only in
- the upper 128 bytes - the lower 128 bytes causes tveeprom.ko to
- abort. In method #2 we only read the upper 128 bytes...
-
- */
-
-
-
-
-/* Stuff common to direct approach of operation tveeprom */
/*
@@ -121,7 +72,7 @@ static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw)
/* FX2 documentation states that a 16bit-addressed eeprom is
expected if the I2C address is an odd number (yeah, this is
- strange bit it's what they do) */
+ strange but it's what they do) */
mode16 = (addr & 1);
eepromSize = (mode16 ? 4096 : 256);
trace_eeprom("Examining %d byte eeprom at location 0x%x"
@@ -165,15 +116,7 @@ static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw)
}
-/*VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV*/
-/* BEGIN DIRECT METHOD, V4L ONLY */
-
-
-/* Directly call eeprom analysis function within tveeprom. This
- version directly assumes it is talking to the V4L version of
- tveeprom.ko and does not attempt anything ugly to maintain
- backwards compatibility. */
-
+/* Directly call eeprom analysis function within tveeprom. */
int pvr2_eeprom_analyze(struct pvr2_hdw *hdw)
{
u8 *eeprom;
@@ -204,66 +147,13 @@ int pvr2_eeprom_analyze(struct pvr2_hdw *hdw)
trace_eeprom("rev_str=%s",tvdata.rev_str);
hdw->tuner_type = tvdata.tuner_type;
hdw->serial_number = tvdata.serial_number;
- hdw->video_standards = tvdata.tuner_formats;
+ pvr2_hdw_internal_set_std_avail(hdw,tvdata.tuner_formats);
kfree(eeprom);
return 0;
}
-
-
-/* END DIRECT METHOD, V4L ONLY */
-/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
-
-
-
-
-
-
-
-static v4l2_std_id std_choices[] = {
- [PVR2_CVAL_VIDEOSTANDARD_NTSC_M] = V4L2_STD_NTSC_M,
- [PVR2_CVAL_VIDEOSTANDARD_PAL_BG] = V4L2_STD_PAL_BG,
- [PVR2_CVAL_VIDEOSTANDARD_PAL_I] = V4L2_STD_PAL_I,
- [PVR2_CVAL_VIDEOSTANDARD_PAL_DK] = V4L2_STD_PAL_DK,
- [PVR2_CVAL_VIDEOSTANDARD_SECAM_L] = V4L2_STD_SECAM_L,
- [PVR2_CVAL_VIDEOSTANDARD_PAL_M] = V4L2_STD_PAL_M,
-};
-
-void pvr2_eeprom_set_default_standard(struct pvr2_hdw *hdw)
-{
- int vstd_value = 0;
- int vstd_found = 0;
- unsigned int idx;
- v4l2_std_id vs = (v4l2_std_id)hdw->video_standards;
-
- for (idx = 0; idx < sizeof(std_choices)/sizeof(std_choices[0]);
- idx++) {
- if (!(vs & std_choices[idx])) continue;
- trace_eeprom("Detected video standard %s (from eeprom)",
- pvr2_hdw_get_ctl_value_name(
- hdw,PVR2_CID_VIDEOSTANDARD,idx));
- if (vstd_found) continue;
- vstd_value = idx;
- vstd_found = !0;
- }
-
- if (!vstd_found) {
- trace_eeprom("eeprom unable to recognize"
- " a known video standard");
- return;
- }
-
- trace_eeprom("Setting initial video standard to %s"
- " (detected from eeprom)",
- pvr2_hdw_get_ctl_value_name(hdw,
- PVR2_CID_VIDEOSTANDARD,
- vstd_value));
- pvr2_hdw_set_ctl_value_internal(hdw,PVR2_CID_VIDEOSTANDARD,vstd_value);
-}
-
-
/*
Stuff for Emacs to see, in order to encourage consistent editing style:
*** Local Variables: ***
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.h b/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
index 061cecd91..84242975d 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
@@ -26,7 +26,6 @@
struct pvr2_hdw;
int pvr2_eeprom_analyze(struct pvr2_hdw *);
-void pvr2_eeprom_set_default_standard(struct pvr2_hdw *);
#endif /* __PVRUSB2_EEPROM_H */
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index 553bd2d7b..2a93bcc96 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -22,7 +22,7 @@
#include <linux/device.h> // for linux/firmware.h
#include <linux/firmware.h>
-#include "cx2341x.h"
+#include <media/cx2341x.h>
#include "pvrusb2-util.h"
#include "pvrusb2-encoder.h"
#include "pvrusb2-hdw-internal.h"
@@ -268,26 +268,22 @@ static int pvr2_write_encoder_vcmd (struct pvr2_hdw *hdw, u8 cmd,
int pvr2_encoder_configure(struct pvr2_hdw *hdw)
{
int ret = 0, audio, i;
- int vd_std = hdw->controls[PVR2_CID_VIDEOSTANDARD].value;
+ int vd_std = hdw->controls[PVR2_CID_STDCUR].value;
int height = hdw->controls[PVR2_CID_VRES].value;
int width = hdw->controls[PVR2_CID_HRES].value;
int height_full = !hdw->controls[PVR2_CID_INTERLACE].value;
int is_30fps, is_ntsc;
- switch (vd_std) {
- case PVR2_CVAL_VIDEOSTANDARD_NTSC_M:
+ if (vd_std & V4L2_STD_NTSC) {
is_ntsc=1;
is_30fps=1;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_M:
+ } else if (vd_std & V4L2_STD_PAL_M) {
is_ntsc=0;
is_30fps=1;
- break;
- default:
+ } else {
is_ntsc=0;
is_30fps=0;
- break;
}
pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure");
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index 05e44385b..9c5f0f74c 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -45,6 +45,83 @@
#include "pvrusb2-hdw.h"
#include "pvrusb2-io.h"
+
+/* Definition of state variables that we can inspect & change. Numbers are
+ assigned from zero counting up with no gaps. */
+#define PVR2_CID_BRIGHTNESS 0
+#define PVR2_CID_CONTRAST 1
+#define PVR2_CID_SATURATION 2
+#define PVR2_CID_HUE 3
+#define PVR2_CID_VOLUME 4
+#define PVR2_CID_BALANCE 5
+#define PVR2_CID_BASS 6
+#define PVR2_CID_TREBLE 7
+#define PVR2_CID_MUTE 8
+#define PVR2_CID_SRATE 9
+#define PVR2_CID_AUDIOBITRATE 10
+#define PVR2_CID_AUDIOCRC 11
+#define PVR2_CID_AUDIOEMPHASIS 12
+#define PVR2_CID_VBR 13
+#define PVR2_CID_AVERAGEVIDEOBITRATE 14
+#define PVR2_CID_PEAKVIDEOBITRATE 15
+#define PVR2_CID_STDAVAIL 16 // V4L2 video standard bit mask
+#define PVR2_CID_INPUT 17
+#define PVR2_CID_AUDIOMODE 18 // V4L2 standard audio mode enum
+#define PVR2_CID_FREQUENCY 19 // Units of Hz
+#define PVR2_CID_HRES 20
+#define PVR2_CID_VRES 21
+#define PVR2_CID_INTERLACE 22
+#define PVR2_CID_AUDIOLAYER 23
+#define PVR2_CID_CHANNEL 24
+#define PVR2_CID_CHANPROG_ID 25
+#define PVR2_CID_CHANPROG_FREQ 26
+#define PVR2_CID_SIGNAL_PRESENT 27
+#define PVR2_CID_STREAMING_ENABLED 28
+#define PVR2_CID_HSM 29
+#define PVR2_CID_SUBSYS_MASK 30
+#define PVR2_CID_SUBSYS_STREAM_MASK 31
+#define PVR2_CID_STDCUR 32 // V4L2 video standard bit mask
+#define PVR2_CID_STDNAME 33 // Enumeration of available standards
+
+/* Legal values for the SRATE state variable */
+#define PVR2_CVAL_SRATE_48 0
+#define PVR2_CVAL_SRATE_44_1 1
+#define PVR2_CVAL_SRATE_MIN PVR2_CVAL_SRATE_48
+#define PVR2_CVAL_SRATE_MAX PVR2_CVAL_SRATE_44_1
+
+/* Legal values for the AUDIOBITRATE state variable */
+#define PVR2_CVAL_AUDIOBITRATE_384 0
+#define PVR2_CVAL_AUDIOBITRATE_320 1
+#define PVR2_CVAL_AUDIOBITRATE_256 2
+#define PVR2_CVAL_AUDIOBITRATE_224 3
+#define PVR2_CVAL_AUDIOBITRATE_192 4
+#define PVR2_CVAL_AUDIOBITRATE_160 5
+#define PVR2_CVAL_AUDIOBITRATE_128 6
+#define PVR2_CVAL_AUDIOBITRATE_112 7
+#define PVR2_CVAL_AUDIOBITRATE_96 8
+#define PVR2_CVAL_AUDIOBITRATE_80 9
+#define PVR2_CVAL_AUDIOBITRATE_64 10
+#define PVR2_CVAL_AUDIOBITRATE_56 11
+#define PVR2_CVAL_AUDIOBITRATE_48 12
+#define PVR2_CVAL_AUDIOBITRATE_32 13
+#define PVR2_CVAL_AUDIOBITRATE_VBR 14
+#define PVR2_CVAL_AUDIOBITRATE_MIN PVR2_CVAL_AUDIOBITRATE_384
+#define PVR2_CVAL_AUDIOBITRATE_MAX PVR2_CVAL_AUDIOBITRATE_VBR
+
+/* Legal values for the AUDIOEMPHASIS state variable */
+#define PVR2_CVAL_AUDIOEMPHASIS_NONE 0
+#define PVR2_CVAL_AUDIOEMPHASIS_50_15 1
+#define PVR2_CVAL_AUDIOEMPHASIS_CCITT 2
+#define PVR2_CVAL_AUDIOEMPHASIS_MIN PVR2_CVAL_AUDIOEMPHASIS_NONE
+#define PVR2_CVAL_AUDIOEMPHASIS_MAX PVR2_CVAL_AUDIOEMPHASIS_CCITT
+
+/* Legal values for PVR2_CID_HSM */
+#define PVR2_CVAL_HSM_FAIL 0
+#define PVR2_CVAL_HSM_FULL 1
+#define PVR2_CVAL_HSM_HIGH 2
+#define PVR2_CVAL_HSM_MIN PVR2_CVAL_HSM_FAIL
+#define PVR2_CVAL_HSM_MAX PVR2_CVAL_HSM_HIGH
+
#define PVR2_VID_ENDPOINT 0x84
#define PVR2_UNK_ENDPOINT 0x86 /* maybe raw yuv ? */
#define PVR2_VBI_ENDPOINT 0x88
@@ -58,7 +135,33 @@
struct pvr2_decoder;
-struct pvr2_ctl_state {
+struct pvr2_ctl_def;
+struct pvr2_ctrl;
+
+typedef int (*pvr2_ctl_set_func)(struct pvr2_ctrl *,int val);
+typedef int (*pvr2_ctl_get_func)(struct pvr2_ctrl *);
+
+struct pvr2_ctl_def {
+ int id;
+ const char *name;
+ const char *desc;
+ pvr2_ctl_set_func set_func;
+ pvr2_ctl_get_func get_func;
+ int mask_value;
+ int max_value;
+ int min_value;
+ int skip_init;
+ int default_value;
+ int is_valid;
+ const char **value_defs_ptr;
+ unsigned int value_defs_count;
+};
+
+
+struct pvr2_ctrl {
+ struct pvr2_hdw *hdw;
+ const struct pvr2_ctl_def *ctl_def;
+ int is_valid;
int value;
int dirty;
};
@@ -96,7 +199,9 @@ struct pvr2_decoder_ctrl {
/* Known major hardware variants, keyed from device ID */
#define PVR2_HDW_TYPE_29XXX 0
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
#define PVR2_HDW_TYPE_24XXX 1
+#endif
/* This structure contains all state data directly needed to
manipulate the hardware (as opposed to complying with a kernel
@@ -191,7 +296,13 @@ struct pvr2_hdw {
/* Tuner / frequency control stuff */
unsigned int tuner_type;
int tuner_updated;
- unsigned long video_standards;
+ v4l2_std_id video_std_avail;
+ v4l2_std_id video_std_cur;
+ struct pvr2_ctl_def video_std_enum;
+ struct v4l2_standard *std_defs;
+ const char **video_std_names;
+ unsigned int std_cnt;
+ int std_id;
int unit_number; /* ID for driver instance */
unsigned long serial_number; /* ID for hardware itself */
@@ -211,13 +322,17 @@ struct pvr2_hdw {
struct pvr2_audio_stat *audio_stat;
/* Every last bit of controllable state */
- struct pvr2_ctl_state controls[PVR2_CID_COUNT];
+ struct pvr2_ctrl *controls;
};
-int pvr2_hdw_set_ctl_value_internal(struct pvr2_hdw *hdw,
- unsigned int ctl_id,int value);
int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw);
+int pvr2_ctrl_internal_set_value(struct pvr2_ctrl *cptr,int val);
+int pvr2_ctrl_internal_get_value(struct pvr2_ctrl *cptr);
+
+int pvr2_hdw_internal_set_stdenum_cur(struct pvr2_hdw *hdw,int val);
+void pvr2_hdw_internal_set_std_cur(struct pvr2_hdw *hdw,int msk);
+void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw,int msk);
#endif /* __PVRUSB2_HDW_INTERNAL_H */
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index ec2b5eeae..f0de1e154 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -24,6 +24,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/firmware.h>
+#include <linux/videodev2.h>
#include <asm/semaphore.h>
#include "pvrusb2.h"
#include "pvrusb2-util.h"
@@ -37,7 +38,9 @@
struct usb_device_id pvr2_device_table[] = {
[PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) },
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
[PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) },
+#endif
{ }
};
@@ -45,7 +48,9 @@ MODULE_DEVICE_TABLE(usb, pvr2_device_table);
static const char *pvr2_device_names[] = {
[PVR2_HDW_TYPE_29XXX] = "WinTV PVR USB2 Model Category 29xxxx",
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
[PVR2_HDW_TYPE_24XXX] = "WinTV PVR USB2 Model Category 24xxxx",
+#endif
};
static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = 0};
@@ -86,22 +91,6 @@ MODULE_PARM_DESC(tolerance,"specify stream error tolerance");
/* size of a firmware chunk */
#define FIRMWARE_CHUNK_SIZE 0x2000
-typedef int (*pvr2_ctl_set_func)(struct pvr2_hdw *,int ctl_id,int val);
-typedef int (*pvr2_ctl_get_func)(struct pvr2_hdw *,int ctl_id);
-
-struct pvr2_ctl_def {
- const char *name;
- pvr2_ctl_set_func set_func;
- pvr2_ctl_get_func get_func;
- int max_value;
- int min_value;
- int skip_init;
- int default_value;
- const char **value_defs_ptr;
- unsigned int value_defs_count;
-};
-
-
static const char *control_values_srate[] = {
[PVR2_CVAL_SRATE_48] = "48KHz",
[PVR2_CVAL_SRATE_44_1] = "44.1KHz",
@@ -135,12 +124,35 @@ static const char *control_values_audioemphasis[] = {
static const char *control_values_videostandard[] = {
- [PVR2_CVAL_VIDEOSTANDARD_NTSC_M] = "NTSC-M",
- [PVR2_CVAL_VIDEOSTANDARD_SECAM_L] = "SECAM-L",
- [PVR2_CVAL_VIDEOSTANDARD_PAL_BG] = "PAL-BG",
- [PVR2_CVAL_VIDEOSTANDARD_PAL_I] = "PAL-I",
- [PVR2_CVAL_VIDEOSTANDARD_PAL_DK] = "PAL-DK",
- [PVR2_CVAL_VIDEOSTANDARD_PAL_M] = "PAL-M",
+ "PAL-B",
+ "PAL-B1",
+ "PAL-G",
+ "PAL-H",
+
+ "PAL-I",
+ "PAL-D",
+ "PAL-D1",
+ "PAL-K",
+
+ "PAL-M",
+ "PAL-N",
+ "PAL-Nc",
+ "PAL-60",
+
+ "NTSC-M",
+ "NTSC-M-JP",
+ "NTSC-443",
+ 0,
+
+ "SECAM-B",
+ "SECAM-D",
+ "SECAM-G",
+ "SECAM-H",
+
+ "SECAM-K",
+ "SECAM-K1",
+ "SECAM-L",
+ "SECAM-LC",
};
@@ -153,12 +165,11 @@ static const char *control_values_input[] = {
static const char *control_values_audiomode[] = {
- [PVR2_CVAL_AUDIOMODE_MONO] = "Mono",
- [PVR2_CVAL_AUDIOMODE_STEREO] = "Stereo",
- [PVR2_CVAL_AUDIOMODE_SAP] = "SAP",
- [PVR2_CVAL_AUDIOMODE_LANG1] = "Lang1",
- [PVR2_CVAL_AUDIOMODE_LANG2] = "Lang2",
- [PVR2_CVAL_AUDIOMODE_LANG1_LANG2] = "Lang1+Lang2",
+ [V4L2_TUNER_MODE_MONO] = "Mono",
+ [V4L2_TUNER_MODE_STEREO] = "Stereo",
+ [V4L2_TUNER_MODE_LANG1] = "Lang1",
+ [V4L2_TUNER_MODE_LANG2] = "Lang2",
+ [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2",
};
@@ -173,183 +184,265 @@ static const char *control_values_hsm[] = {
.value_defs_ptr = x, \
.value_defs_count = (sizeof(x)/sizeof(x[0]))
-static int pvr2_ctl_set_chanprog_id(struct pvr2_hdw *hdw,int ctl_id,int value);
-static int pvr2_ctl_get_chanprog_id(struct pvr2_hdw *hdw,int ctl_id);
-static int pvr2_ctl_get_signal(struct pvr2_hdw *hdw,int ctl_id);
-static int pvr2_ctl_get_streaming(struct pvr2_hdw *hdw,int ctl_id);
-static int pvr2_ctl_get_hsm(struct pvr2_hdw *hdw,int ctl_id);
-static int pvr2_ctl_get_subsys_mask(struct pvr2_hdw *hdw,int ctl_id);
-static int pvr2_ctl_set_subsys_mask(struct pvr2_hdw *hdw,int ctl_id,int val);
-static int pvr2_ctl_get_subsys_stream_mask(struct pvr2_hdw *hdw,int ctl_id);
-static int pvr2_ctl_set_subsys_stream_mask(struct pvr2_hdw *hdw,int ctl_id,
- int val);
-
-static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] =
+static int pvr2_ctl_set_chanprog_id(struct pvr2_ctrl *cptr,int value);
+static int pvr2_ctl_get_chanprog_id(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_get_signal(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_get_streaming(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_get_hsm(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_get_subsys_mask(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_set_subsys_mask(struct pvr2_ctrl *cptr,int val);
+static int pvr2_ctl_get_subsys_stream_mask(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_set_subsys_stream_mask(struct pvr2_ctrl *cptr,int val);
+static int pvr2_ctl_set_stdcur(struct pvr2_ctrl *cptr,int val);
+static int pvr2_ctl_get_stdcur(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_get_stdavail(struct pvr2_ctrl *cptr);
+static int pvr2_ctl_set_stdenumcur(struct pvr2_ctrl *cptr,int val);
+static int pvr2_ctl_get_stdenumcur(struct pvr2_ctrl *cptr);
+
+static struct pvr2_ctl_def control_defs[] =
{
[PVR2_CID_BRIGHTNESS] = {
- .name = "Brightness",
+ .id = V4L2_CID_BRIGHTNESS,
+ .is_valid = !0,
+ .desc = "Brightness",
+ .name = "brightness",
.min_value = 0,
.max_value = 255,
.default_value = 128,
},
[PVR2_CID_CONTRAST] = {
- .name = "Contrast",
+ .id = V4L2_CID_CONTRAST,
+ .is_valid = !0,
+ .desc = "Contrast",
+ .name = "contrast",
.min_value = 0,
.max_value = 127,
.default_value = 68,
},
[PVR2_CID_SATURATION] = {
- .name = "Saturation",
+ .id = V4L2_CID_SATURATION,
+ .is_valid = !0,
+ .desc = "Saturation",
+ .name = "saturation",
.min_value = 0,
.max_value = 127,
.default_value = 64,
},
[PVR2_CID_HUE] = {
- .name = "Hue",
+ .id = V4L2_CID_HUE,
+ .is_valid = !0,
+ .desc = "Hue",
+ .name = "hue",
.min_value = -128,
.max_value = 127,
.default_value = 0,
},
[PVR2_CID_VOLUME] = {
- .name = "Volume",
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .is_valid = !0,
+ .desc = "Volume",
+ .name = "volume",
.min_value = 0,
.max_value = 65535,
.default_value = 65535,
},
[PVR2_CID_BALANCE] = {
- .name = "Balance",
+ .id = V4L2_CID_AUDIO_BALANCE,
+ .is_valid = !0,
+ .desc = "Balance",
+ .name = "balance",
.min_value = -32768,
.max_value = 32767,
.default_value = 0,
},
[PVR2_CID_BASS] = {
- .name = "Bass",
+ .id = V4L2_CID_AUDIO_BASS,
+ .is_valid = !0,
+ .desc = "Bass",
+ .name = "bass",
.min_value = -32768,
.max_value = 32767,
.default_value = 0,
},
[PVR2_CID_TREBLE] = {
- .name = "Treble",
+ .id = V4L2_CID_AUDIO_TREBLE,
+ .is_valid = !0,
+ .desc = "Treble",
+ .name = "treble",
.min_value = -32768,
.max_value = 32767,
.default_value = 0,
},
[PVR2_CID_MUTE] = {
- .name = "Mute",
+ .id = V4L2_CID_AUDIO_MUTE,
+ .is_valid = !0,
+ .desc = "Mute",
+ .name = "mute",
.min_value = 0,
.max_value = 1,
.default_value = 0,
},
[PVR2_CID_SRATE] = {
- .name = "Sample rate",
+ .id = V4L2_CID_PVR_SRATE,
+ .is_valid = !0,
+ .desc = "Sample rate",
+ .name = "srate",
.min_value = PVR2_CVAL_SRATE_MIN,
.max_value = PVR2_CVAL_SRATE_MAX,
.default_value = PVR2_CVAL_SRATE_48,
VDEF(control_values_srate),
},
[PVR2_CID_AUDIOBITRATE] = {
- .name = "Audio Bitrate",
+ .id = V4L2_CID_PVR_AUDIOBITRATE,
+ .is_valid = !0,
+ .desc = "Audio Bitrate",
+ .name = "audio_bitrate",
.min_value = PVR2_CVAL_AUDIOBITRATE_MIN,
.max_value = PVR2_CVAL_AUDIOBITRATE_MAX,
.default_value = PVR2_CVAL_AUDIOBITRATE_224,
VDEF(control_values_audiobitrate),
},
[PVR2_CID_AUDIOCRC] = {
- .name = "Audio CRC",
+ .id = V4L2_CID_PVR_AUDIOCRC,
+ .is_valid = !0,
+ .desc = "Audio CRC",
+ .name = "audio_crc",
.min_value = 0,
.max_value = 1,
.default_value = 1,
},
[PVR2_CID_AUDIOEMPHASIS] = {
- .name = "Audio Emphasis",
+ .id = V4L2_CID_PVR_AUDIOEMPHASIS,
+ .is_valid = !0,
+ .desc = "Audio Emphasis",
+ .name = "audio_emphasis",
.min_value = PVR2_CVAL_AUDIOEMPHASIS_MIN,
.max_value = PVR2_CVAL_AUDIOEMPHASIS_MAX,
.default_value = PVR2_CVAL_AUDIOEMPHASIS_NONE,
VDEF(control_values_audioemphasis),
},
[PVR2_CID_VBR] = {
- .name = "Variable video bitrate",
+ .id = V4L2_CID_PVR_VBR,
+ .is_valid = !0,
+ .desc = "Variable video bitrate",
+ .name = "vbr",
.min_value = 0,
.max_value = 1,
.default_value = 0,
},
[PVR2_CID_AVERAGEVIDEOBITRATE] = {
- .name = "Average video bitrate",
+ .id = V4L2_CID_PVR_VIDEOBITRATE,
+ .is_valid = !0,
+ .desc = "Average video bitrate",
+ .name = "video_average_bitrate",
.min_value = 1,
.max_value = 20000000,
.default_value = 6000000,
},
[PVR2_CID_PEAKVIDEOBITRATE] = {
- .name = "Peak video bitrate",
+ .id = V4L2_CID_PVR_VIDEOPEAK,
+ .is_valid = !0,
+ .desc = "Peak video bitrate",
+ .name = "video_peak_bitrate",
.min_value = 1,
.max_value = 20000000,
.default_value = 6000000,
},
- [PVR2_CID_VIDEOSTANDARD] = {
- .name = "Video Standard",
- .min_value = PVR2_CVAL_VIDEOSTANDARD_MIN,
- .max_value = PVR2_CVAL_VIDEOSTANDARD_MAX,
- .default_value = PVR2_CVAL_VIDEOSTANDARD_NTSC_M,
+ [PVR2_CID_STDAVAIL] = {
+ .is_valid = !0,
+ .desc = "Video Standards Available Mask",
+ .name = "video_standard_mask_available",
+ .min_value = 0,
+ .max_value = 0,
+ .default_value = (int)V4L2_STD_UNKNOWN,
+ .mask_value = (int)V4L2_STD_ALL,
+ .get_func = pvr2_ctl_get_stdavail,
VDEF(control_values_videostandard),
},
[PVR2_CID_INPUT] = {
- .name = "Video Source",
+ .id = V4L2_CID_PVR_INPUT,
+ .is_valid = !0,
+ .desc = "Video Source",
+ .name = "input",
.min_value = PVR2_CVAL_INPUT_MIN,
.max_value = PVR2_CVAL_INPUT_MAX,
.default_value = PVR2_CVAL_INPUT_TV,
VDEF(control_values_input),
},
[PVR2_CID_AUDIOMODE] = {
- .name = "Audio Mode",
- .min_value = PVR2_CVAL_AUDIOMODE_MIN,
- .max_value = PVR2_CVAL_AUDIOMODE_MAX,
- .default_value = PVR2_CVAL_AUDIOMODE_STEREO,
+ .id = V4L2_CID_PVR_AUDIOMODE,
+ .is_valid = !0,
+ .desc = "Audio Mode",
+ .name = "audio_mode",
+ .min_value = V4L2_TUNER_MODE_MONO,
+ .max_value = V4L2_TUNER_MODE_LANG1_LANG2,
+ .default_value = V4L2_TUNER_MODE_STEREO,
VDEF(control_values_audiomode),
},
[PVR2_CID_FREQUENCY] = {
- .name = "Tuner Frequency (Hz)",
+ .id = V4L2_CID_PVR_FREQUENCY,
+ .is_valid = !0,
+ .desc = "Tuner Frequency (Hz)",
+ .name = "frequency",
.min_value = 55250000L,
.max_value = 850000000L,
.default_value = 175250000L,
},
[PVR2_CID_HRES] = {
- .name = "Horizontal capture resolution",
+ .id = V4L2_CID_PVR_HRES,
+ .is_valid = !0,
+ .desc = "Horizontal capture resolution",
+ .name = "resolution_hor",
.min_value = 320,
.max_value = 720,
.default_value = 720,
},
[PVR2_CID_VRES] = {
- .name = "Vertical capture resolution",
+ .id = V4L2_CID_PVR_VRES,
+ .is_valid = !0,
+ .desc = "Vertical capture resolution",
+ .name = "resolution_ver",
.min_value = 200,
.max_value = 625,
.default_value = 480,
},
[PVR2_CID_INTERLACE] = {
- .name = "Interlace mode",
+ .id = V4L2_CID_PVR_INTERLACE,
+ .is_valid = !0,
+ .desc = "Interlace mode",
+ .name = "interlace",
.min_value = 0,
.max_value = 1,
.default_value = 0,
},
[PVR2_CID_AUDIOLAYER] = {
- .name = "Audio Layer",
+ .is_valid = !0,
+ .desc = "Audio Layer",
+ .name = "audio_layer",
.min_value = 0, /* This is all a wild guess */
.max_value = 3,
.default_value = 2, /* Appears to be all that is supported */
},
[PVR2_CID_CHANNEL] = {
- .name = "Channel",
+ .is_valid = !0,
+ .desc = "Channel",
+ .name = "channel",
.min_value = 0,
.max_value = FREQTABLE_SIZE,
.default_value = 0,
},
[PVR2_CID_CHANPROG_ID] = {
- .name = "Channel Program ID",
+ .is_valid = !0,
+ .desc = "Channel Program ID",
+ .name = "freq_table_channel",
.min_value = 0,
.max_value = FREQTABLE_SIZE,
.default_value = 0,
},
[PVR2_CID_CHANPROG_FREQ] = {
- .name = "Channel Program Frequency",
+ .is_valid = !0,
+ .desc = "Channel Program Frequency",
+ .name = "freq_table_value",
.min_value = 55250000L,
.max_value = 850000000L,
.skip_init = !0,
@@ -357,26 +450,34 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] =
.get_func = pvr2_ctl_get_chanprog_id,
},
[PVR2_CID_SIGNAL_PRESENT] = {
- .name = "Signal Present",
+ .is_valid = !0,
+ .desc = "Signal Present",
+ .name = "signal_present",
.min_value = 0,
.max_value = 1,
.get_func = pvr2_ctl_get_signal,
},
[PVR2_CID_STREAMING_ENABLED] = {
- .name = "Streaming Enabled",
+ .is_valid = !0,
+ .desc = "Streaming Enabled",
+ .name = "streaming_enabled",
.min_value = 0,
.max_value = 1,
.get_func = pvr2_ctl_get_streaming,
},
[PVR2_CID_HSM] = {
- .name = "USB Speed",
+ .is_valid = !0,
+ .desc = "USB Speed",
+ .name = "usb_speed",
.min_value = PVR2_CVAL_HSM_MIN,
.max_value = PVR2_CVAL_HSM_MAX,
.get_func = pvr2_ctl_get_hsm,
VDEF(control_values_hsm),
},
[PVR2_CID_SUBSYS_MASK] = {
- .name = "Subsystem enabled mask",
+ .is_valid = !0,
+ .desc = "Subsystem enabled mask",
+ .name = "debug_subsys_mask",
.min_value = 0,
.max_value = 0x7fffffff,
.skip_init = !0,
@@ -384,17 +485,34 @@ static struct pvr2_ctl_def control_defs[PVR2_CID_COUNT] =
.set_func = pvr2_ctl_set_subsys_mask,
},
[PVR2_CID_SUBSYS_STREAM_MASK] = {
- .name = "Subsystem stream mask",
+ .is_valid = !0,
+ .desc = "Subsystem stream mask",
+ .name = "debug_subsys_stream_mask",
.min_value = 0,
.max_value = 0x7fffffff,
.skip_init = !0,
.get_func = pvr2_ctl_get_subsys_stream_mask,
.set_func = pvr2_ctl_set_subsys_stream_mask,
},
+ [PVR2_CID_STDCUR] = {
+ .id = V4L2_CID_PVR_STDCUR,
+ .is_valid = !0,
+ .desc = "Video Standard In Use Mask",
+ .name = "video_standard_mask_active",
+ .min_value = 0,
+ .max_value = 0,
+ .default_value = (int)V4L2_STD_UNKNOWN,
+ .mask_value = (int)V4L2_STD_ALL,
+ .set_func = pvr2_ctl_set_stdcur,
+ .get_func = pvr2_ctl_get_stdcur,
+ VDEF(control_values_videostandard),
+ },
};
#undef VDEF
+#define CTRL_DEF_COUNT (sizeof(control_defs)/sizeof(control_defs[0]))
+#define CTRL_COUNT CTRL_DEF_COUNT+1
const char *pvr2_config_get_name(enum pvr2_config cfg)
{
@@ -511,9 +629,11 @@ int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
static const char *fw_files_29xxx[] = {
"v4l-pvrusb2-29xxx-01.fw",
};
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
static const char *fw_files_24xxx[] = {
"v4l-pvrusb2-24xxx-01.fw",
};
+#endif
static const struct {
const char **lst;
unsigned int cnt;
@@ -522,10 +642,12 @@ int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
fw_files_29xxx,
sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]),
},
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
[PVR2_HDW_TYPE_24XXX] = {
fw_files_24xxx,
sizeof(fw_files_24xxx)/sizeof(fw_files_24xxx[0]),
},
+#endif
};
hdw->fw1_state = FW1_STATE_FAILED; // default result
@@ -944,9 +1066,9 @@ void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw,
}
-static int pvr2_ctl_get_streaming(struct pvr2_hdw *hdw,int ctl_id)
+static int pvr2_ctl_get_streaming(struct pvr2_ctrl *cptr)
{
- return hdw->flag_streaming_enabled != 0;
+ return cptr->hdw->flag_streaming_enabled != 0;
}
@@ -1061,6 +1183,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
{
int ret;
unsigned int idx;
+ struct pvr2_ctrl *cptr;
int reloadFl = 0;
if (!reloadFl) {
reloadFl = (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
@@ -1106,14 +1229,17 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
pvr2_i2c_core_init(hdw);
if (!pvr2_hdw_dev_ok(hdw)) return;
- for (idx = 0; idx < PVR2_CID_COUNT; idx++) {
- if (control_defs[idx].skip_init) continue;
- pvr2_hdw_set_ctl_value_internal(
- hdw,idx,control_defs[idx].default_value);
+ for (idx = 0; idx < CTRL_COUNT; idx++) {
+ cptr = hdw->controls + idx;
+ if (!pvr2_ctrl_is_valid(cptr)) continue;
+ if (cptr->ctl_def->skip_init) continue;
+ pvr2_ctrl_internal_set_value(cptr,
+ cptr->ctl_def->default_value);
}
- pvr2_reset_ctl_endpoints(hdw);
- if (!pvr2_hdw_dev_ok(hdw)) return;
+ // Do not use pvr2_reset_ctl_endpoints() here. It is not
+ // thread-safe against the normal pvr2_send_request() mechanism.
+ // (We should make it thread safe).
ret = pvr2_hdw_get_eeprom_addr(hdw);
if (!pvr2_hdw_dev_ok(hdw)) return;
@@ -1138,7 +1264,21 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
if (!pvr2_hdw_dev_ok(hdw)) return;
- pvr2_eeprom_set_default_standard(hdw);
+ for (idx = 0; idx < hdw->std_cnt; idx++) {
+ pvr2_trace(PVR2_TRACE_EEPROM,
+ "Detected video standard %s (from eeprom)",
+ hdw->std_defs[idx].name);
+ }
+ if (hdw->std_cnt) {
+ pvr2_trace(PVR2_TRACE_EEPROM,
+ "Initial video standard set to %s"
+ " (detected from eeprom)",
+ hdw->std_defs[hdw->std_id].name);
+ } else {
+ pvr2_trace(PVR2_TRACE_EEPROM,
+ "Unable to select a viable video standard");
+ }
+
if (!pvr2_hdw_dev_ok(hdw)) return;
pvr2_hdw_commit_ctl_internal(hdw);
@@ -1259,8 +1399,35 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw,pvr2_device_names[hdw_type]);
if (!hdw) goto fail;
memset(hdw,0,sizeof(*hdw));
+
+ // Initialize video standard enum dynamic control
+ hdw->video_std_enum.name = "video_standard";
+ hdw->video_std_enum.desc = "Video Standard Name";
+ hdw->video_std_enum.id = 0; // ?????
+ hdw->video_std_enum.set_func = pvr2_ctl_set_stdenumcur;
+ hdw->video_std_enum.get_func = pvr2_ctl_get_stdenumcur;
+ hdw->video_std_enum.mask_value = 0;
+ hdw->video_std_enum.max_value = 0;
+ hdw->video_std_enum.min_value = 0;
+ hdw->video_std_enum.default_value = 0;
+ hdw->video_std_enum.is_valid = !0;
+
+ hdw->controls = kmalloc(sizeof(struct pvr2_ctrl) * CTRL_COUNT,
+ GFP_KERNEL);
+ if (!hdw->controls) goto fail;
+ memset(hdw->controls,0,sizeof(struct pvr2_ctrl) * CTRL_COUNT);
hdw->hdw_type = hdw_type;
+ for (idx = 0; idx < CTRL_DEF_COUNT; idx++) {
+ hdw->controls[idx].hdw = hdw;
+ hdw->controls[idx].ctl_def = control_defs + idx;
+ hdw->controls[idx].is_valid =
+ hdw->controls[idx].ctl_def->is_valid;
+ }
+ hdw->controls[PVR2_CID_STDNAME].hdw = hdw;
+ hdw->controls[PVR2_CID_STDNAME].ctl_def = &hdw->video_std_enum;
+ hdw->controls[PVR2_CID_STDNAME].is_valid = !0;
+
hdw->eeprom_addr = -1;
hdw->unit_number = -1;
hdw->v4l_minor_number = -1;
@@ -1322,6 +1489,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
if (hdw->ctl_write_urb) usb_free_urb(hdw->ctl_write_urb);
if (hdw->ctl_read_buffer) kfree(hdw->ctl_read_buffer);
if (hdw->ctl_write_buffer) kfree(hdw->ctl_write_buffer);
+ if (hdw->controls) kfree(hdw->controls);
kfree(hdw);
}
return 0;
@@ -1386,6 +1554,9 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
unit_pointers[hdw->unit_number] = 0;
}
} while (0); up(&pvr2_unit_sem);
+ kfree(hdw->controls);
+ if (hdw->std_defs) kfree(hdw->std_defs);
+ if (hdw->video_std_names) kfree(hdw->video_std_names);
kfree(hdw);
}
@@ -1414,10 +1585,11 @@ void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
}
-static int pvr2_ctl_set_chanprog_id(struct pvr2_hdw *hdw,int ctl_id,int value)
+static int pvr2_ctl_set_chanprog_id(struct pvr2_ctrl *cptr,int value)
{
/* This is a special case; the value to store is to an array, and
the element to select is determined by PVR_CID_CHANPROG_ID. */
+ struct pvr2_hdw *hdw = cptr->hdw;
int id = hdw->controls[PVR2_CID_CHANPROG_ID].value;
if ((id < 1) || (id > FREQTABLE_SIZE)) return 0;
hdw->freqTable[id-1] = value;
@@ -1431,120 +1603,581 @@ static int pvr2_ctl_set_chanprog_id(struct pvr2_hdw *hdw,int ctl_id,int value)
}
-static int pvr2_ctl_get_chanprog_id(struct pvr2_hdw *hdw,int ctl_id)
+static int pvr2_ctl_get_chanprog_id(struct pvr2_ctrl *cptr)
{
/* This is a special case; the value to return is from an array,
and the element to select is determined by
PVR_CID_CHANPROG_ID. */
+ struct pvr2_hdw *hdw = cptr->hdw;
int id = hdw->controls[PVR2_CID_CHANPROG_ID].value;
if ((id < 1) || (id > FREQTABLE_SIZE)) return 0;
return hdw->freqTable[id-1];
}
+// Template data for possible enumerated video standards
+static struct v4l2_standard pvr_standards[] = {
+ {
+ .id = V4L2_STD_PAL_BG,
+ .frameperiod =
+ {
+ .numerator = 1,
+ .denominator= 25
+ },
+ .framelines = 625,
+ .reserved = {0,0,0,0}
+ }, {
+ .id = V4L2_STD_PAL_I,
+ .frameperiod =
+ {
+ .numerator = 1,
+ .denominator= 25
+ },
+ .framelines = 625,
+ .reserved = {0,0,0,0}
+ }, {
+ .id = V4L2_STD_PAL_DK,
+ .frameperiod =
+ {
+ .numerator = 1,
+ .denominator= 25
+ },
+ .framelines = 625,
+ .reserved = {0,0,0,0}
+ }, {
+ .id = V4L2_STD_SECAM,
+ .frameperiod =
+ {
+ .numerator = 1,
+ .denominator= 25
+ },
+ .framelines = 625,
+ .reserved = {0,0,0,0}
+ }, {
+ .id = V4L2_STD_NTSC_M,
+ .frameperiod =
+ {
+ .numerator = 1001,
+ .denominator= 30000
+ },
+ .framelines = 525,
+ .reserved = {0,0,0,0}
+ }, {
+ .id = V4L2_STD_PAL_M,
+ .frameperiod =
+ {
+ .numerator = 1001,
+ .denominator= 30000
+ },
+ .framelines = 525,
+ .reserved = {0,0,0,0}
+ }
+};
+
+#define pvr_standards_cnt (sizeof(pvr_standards)/sizeof(pvr_standards[0]))
-/* Retrieve current value for a given control */
-int pvr2_hdw_get_ctl_value(struct pvr2_hdw *hdw,unsigned int ctl_id)
+
+struct name_data {
+ struct v4l2_standard *std;
+ unsigned int bcnt;
+ unsigned int scnt;
+};
+
+static void name_build(struct name_data *dp,const char *str)
{
- int ret = 0;
+ if (!dp->bcnt) {
+ dp->bcnt = scnprintf(dp->std->name,
+ sizeof(dp->std->name)-1,"%s",str);
+ dp->scnt = 0;
+ return;
+ }
- if (ctl_id >= PVR2_CID_COUNT) return 0;
- LOCK_TAKE(hdw->big_lock); do {
- if (control_defs[ctl_id].get_func) {
- ret = control_defs[ctl_id].get_func(hdw,ctl_id);
- break;
+ dp->bcnt += scnprintf(dp->std->name+dp->bcnt,
+ sizeof(dp->std->name)-(1+dp->bcnt),
+ "%s%s",
+ (dp->scnt ? "/" : "-"),str);
+ (dp->scnt)++;
+}
+
+// Generate a descriptive name for a given standard
+static void name_bucket(struct v4l2_standard *std)
+{
+ struct name_data nd;
+ nd.std = std;
+ nd.bcnt = 0;
+ if (std->id & (V4L2_STD_PAL_B|
+ V4L2_STD_PAL_B1|
+ V4L2_STD_PAL_G|
+ V4L2_STD_PAL_H|
+ V4L2_STD_PAL_I|
+ V4L2_STD_PAL_D|
+ V4L2_STD_PAL_D1|
+ V4L2_STD_PAL_K)) {
+ name_build(&nd,"PAL");
+ if (std->id & V4L2_STD_PAL_B) name_build(&nd,"B");
+ if (std->id & V4L2_STD_PAL_B1) name_build(&nd,"B1");
+ if (std->id & V4L2_STD_PAL_D) name_build(&nd,"D");
+ if (std->id & V4L2_STD_PAL_D1) name_build(&nd,"D1");
+ if (std->id & V4L2_STD_PAL_G) name_build(&nd,"G");
+ if (std->id & V4L2_STD_PAL_H) name_build(&nd,"H");
+ if (std->id & V4L2_STD_PAL_I) name_build(&nd,"I");
+ if (std->id & V4L2_STD_PAL_K) name_build(&nd,"K");
+ if (std->id & V4L2_STD_PAL_M) name_build(&nd,"M");
+ if (std->id & V4L2_STD_PAL_N) name_build(&nd,"N");
+ if (std->id & V4L2_STD_PAL_Nc) name_build(&nd,"Nc");
+ if (std->id & V4L2_STD_PAL_60) name_build(&nd,"60");
+ std->name[nd.bcnt] = 0;
+ return;
+ }
+ if (std->id & (V4L2_STD_NTSC_M|
+ V4L2_STD_NTSC_M_JP|
+ V4L2_STD_NTSC_443)) {
+ name_build(&nd,"NTSC");
+ if (std->id & V4L2_STD_NTSC_M) name_build(&nd,"M");
+ if (std->id & V4L2_STD_NTSC_M_JP) name_build(&nd,"Mjp");
+ if (std->id & V4L2_STD_NTSC_443) name_build(&nd,"443");
+ std->name[nd.bcnt] = 0;
+ return;
+ }
+ if (std->id & (V4L2_STD_SECAM_B|
+ V4L2_STD_SECAM_D|
+ V4L2_STD_SECAM_G|
+ V4L2_STD_SECAM_H|
+ V4L2_STD_SECAM_K|
+ V4L2_STD_SECAM_K1|
+ V4L2_STD_SECAM_L|
+ V4L2_STD_SECAM_LC)) {
+ name_build(&nd,"SECAM");
+ if (std->id & V4L2_STD_SECAM_B) name_build(&nd,"B");
+ if (std->id & V4L2_STD_SECAM_D) name_build(&nd,"D");
+ if (std->id & V4L2_STD_SECAM_G) name_build(&nd,"G");
+ if (std->id & V4L2_STD_SECAM_H) name_build(&nd,"H");
+ if (std->id & V4L2_STD_SECAM_K) name_build(&nd,"K");
+ if (std->id & V4L2_STD_SECAM_K1) name_build(&nd,"K1");
+ if (std->id & V4L2_STD_SECAM_L) name_build(&nd,"L");
+ if (std->id & V4L2_STD_SECAM_LC) name_build(&nd,"LC");
+ std->name[nd.bcnt] = 0;
+ return;
+ }
+ std->name[0] = 0;
+}
+
+
+// Given a mask of viable video standards to choose from, generate an
+// appropriate array of v4l2_standard data that corresponds to it and set
+// up related state in the driver to match.
+void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw,int arg)
+{
+ v4l2_std_id buckets[pvr_standards_cnt];
+ unsigned int idx1,idx2,std_cnt;
+ v4l2_std_id mmsk,amsk;
+
+ amsk = (v4l2_std_id)arg;
+
+ // Figure out which standard groups we can work with
+ std_cnt = 0;
+ mmsk = 0;
+ for (idx1 = 0; idx1 < pvr_standards_cnt; idx1++) {
+ buckets[idx1] = pvr_standards[idx1].id & amsk;
+ if (!buckets[idx1]) continue;
+ mmsk |= buckets[idx1];
+ amsk &= ~buckets[idx1];
+ std_cnt++;
+ }
+
+ if (amsk) {
+ pvr2_trace(
+ PVR2_TRACE_ERROR_LEGS,
+ "Failed to bucketize the following standards: 0x%llx",
+ amsk);
+ }
+
+ if (hdw->std_defs) {
+ kfree(hdw->std_defs);
+ hdw->std_defs = 0;
+ }
+ if (hdw->video_std_names) {
+ kfree(hdw->video_std_names);
+ hdw->video_std_names = 0;
+ }
+ hdw->std_cnt = 0;
+
+ if (!std_cnt) {
+ pvr2_trace(
+ PVR2_TRACE_ERROR_LEGS,
+ "Failed to identify any viable standard groups");
+ hdw->video_std_avail = 0;
+ pvr2_hdw_internal_set_std_cur(hdw,0);
+ return;
+ }
+
+ if (std_cnt) {
+ // Allocate new video standard array
+ hdw->std_defs = kmalloc(sizeof(struct v4l2_standard) * std_cnt,
+ GFP_KERNEL);
+ hdw->std_cnt = std_cnt;
+ memset(hdw->std_defs,0,sizeof(struct v4l2_standard) * std_cnt);
+ hdw->video_std_names = kmalloc(sizeof(char *) * std_cnt,
+ GFP_KERNEL);
+ memset(hdw->video_std_names,0,sizeof(char *) * std_cnt);
+ idx2 = 0;
+
+ // Initialize video standard array
+ for (idx1 = 0; idx1 < pvr_standards_cnt; idx1++) {
+ if (!buckets[idx1]) continue;
+ memcpy(hdw->std_defs + idx2,
+ pvr_standards + idx1,
+ sizeof(struct v4l2_standard));
+ hdw->std_defs[idx2].id = buckets[idx1];
+ idx2++;
}
- ret = hdw->controls[ctl_id].value;
- } while(0); LOCK_GIVE(hdw->big_lock);
- return ret;
+
+ // Generate a name for each known video standard
+ for (idx1 = 0; idx1 < std_cnt; idx1++) {
+ name_bucket(hdw->std_defs + idx1);
+ hdw->video_std_names[idx1] =
+ hdw->std_defs[idx1].name;
+ }
+
+ // Set up the dynamic control for this standard
+ hdw->video_std_enum.value_defs_ptr = hdw->video_std_names;
+ hdw->video_std_enum.value_defs_count = std_cnt;
+ }
+
+ hdw->video_std_avail = mmsk;
+ if (!(hdw->video_std_avail & hdw->video_std_cur)) {
+ // Reselect standard if there isn't one that matches...
+ pvr2_hdw_internal_set_stdenum_cur(hdw,0);
+ }
}
-/* Return true if control is writable */
-int pvr2_hdw_get_ctl_rw(struct pvr2_hdw *hdw,unsigned int ctl_id)
+unsigned int pvr2_hdw_get_stdenum_count(struct pvr2_hdw *hdw)
{
- if (ctl_id >= PVR2_CID_COUNT) return 0;
- if (control_defs[ctl_id].get_func && !control_defs[ctl_id].set_func) {
- return 0;
+ return hdw->std_cnt;
+}
+
+
+const struct v4l2_standard *pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
+ unsigned int idx)
+{
+ if (idx >= hdw->std_cnt) return 0;
+ return hdw->std_defs + idx;
+}
+
+
+int pvr2_hdw_internal_set_stdenum_cur(struct pvr2_hdw *hdw,int val)
+{
+ if (val < 0) return -EINVAL;
+ if (val >= hdw->std_cnt) return -EINVAL;
+ pvr2_hdw_internal_set_std_cur(hdw,hdw->std_defs[val].id);
+ return 0;
+}
+
+
+void pvr2_hdw_internal_set_std_cur(struct pvr2_hdw *hdw,int val)
+{
+ unsigned int idx;
+ v4l2_std_id msk,id;
+
+ id = (v4l2_std_id)val;
+ // Only select from available standards
+ id &= hdw->video_std_avail;
+
+ // Only select a single bit
+ for (idx = 0, msk = 1; msk; idx++, msk <<= 1) {
+ if (!(id & msk)) continue;
+ id = msk;
+ break;
}
- return !0;
+
+ // Get out if nothing found
+ if (!msk) return;
+
+ // Fix up standard group now
+ hdw->video_std_cur = id;
+ hdw->controls[PVR2_CID_STDCUR].value = id;
+ hdw->controls[PVR2_CID_STDCUR].dirty = !0;
+ for (idx = 0; idx < hdw->std_cnt; idx++) {
+ if (hdw->std_defs[idx].id & id) {
+ hdw->std_id = idx;
+ return;
+ }
+ }
+
+ // Should never really get here, but just in case...
+ hdw->std_id = 0;
}
-/* Retrieve legal minimum value for a given control */
-int pvr2_hdw_get_ctl_min_value(struct pvr2_hdw *hdw,unsigned int ctl_id)
+static int pvr2_ctl_set_stdcur(struct pvr2_ctrl *cptr,int val)
{
- if (ctl_id >= PVR2_CID_COUNT) return 0;
- return control_defs[ctl_id].min_value;
+ pvr2_hdw_internal_set_std_cur(cptr->hdw,val);
+ return 0;
+}
+
+
+static int pvr2_ctl_get_stdcur(struct pvr2_ctrl *cptr)
+{
+ return (int)(cptr->hdw->video_std_cur);
+}
+
+
+static int pvr2_ctl_set_stdenumcur(struct pvr2_ctrl *cptr,int val)
+{
+ if (val < 0) return -EINVAL;
+ if (val >= cptr->hdw->std_cnt) return -EINVAL;
+ cptr->hdw->std_id = val;
+ pvr2_hdw_internal_set_std_cur(cptr->hdw,
+ cptr->hdw->std_id);
+ return 0;
+}
+
+
+static int pvr2_ctl_get_stdenumcur(struct pvr2_ctrl *cptr)
+{
+ return cptr->hdw->std_id;
+}
+
+
+static int pvr2_ctl_get_stdavail(struct pvr2_ctrl *cptr)
+{
+ return (int)(cptr->hdw->video_std_avail);
+}
+
+
+/* Get the number of defined controls */
+unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
+{
+ return CTRL_COUNT;
+}
+
+
+/* Retrieve a control handle given its index (0..count-1) */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw,
+ unsigned int idx)
+{
+ if (idx < 0) return 0;
+ if (idx >= CTRL_COUNT) return 0;
+ return hdw->controls + idx;
}
-/* Retrieve legal maximum value for a given control */
-int pvr2_hdw_get_ctl_max_value(struct pvr2_hdw *hdw,unsigned int ctl_id)
+/* Given an ID, retrieve the control structure associated with it. */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl(struct pvr2_hdw *hdw,unsigned int ctl_id)
{
- if (ctl_id >= PVR2_CID_COUNT) return 0;
- return control_defs[ctl_id].max_value;
+ struct pvr2_ctrl *cptr;
+ unsigned int idx;
+ int i;
+
+ /* This could be made a lot more efficient, but for now... */
+ for (idx = 0; idx < CTRL_COUNT; idx++) {
+ cptr = hdw->controls + idx;
+ i = cptr->ctl_def->id;
+ if (i && (i == ctl_id)) return cptr;
+ }
+
+ return 0;
}
-/* Set current value for given control - normally this is just stored and
- the hardware isn't updated until the commit function is called. */
-int pvr2_hdw_set_ctl_value_internal(struct pvr2_hdw *hdw,
- unsigned int ctl_id,int value)
+/* Set the current value of a given control. This assumes we are already
+ inside our critical region. */
+int pvr2_ctrl_internal_set_value(struct pvr2_ctrl *cptr,int value)
{
+ const struct pvr2_ctl_def *dptr;
int ret;
- if (ctl_id >= PVR2_CID_COUNT) return -EINVAL;
- if (value < control_defs[ctl_id].min_value) return -EINVAL;
- if (value > control_defs[ctl_id].max_value) return -EINVAL;
- if (control_defs[ctl_id].set_func) {
- ret = control_defs[ctl_id].set_func(hdw,ctl_id,value);
- pvr2_i2c_core_check_stale(hdw);
- pvr2_i2c_core_sync(hdw);
+ if (!cptr) return -EINVAL;
+ if (!cptr->is_valid) return -EINVAL;
+ dptr = cptr->ctl_def;
+ if (!dptr->is_valid) return -EINVAL;
+ if (value < dptr->min_value) return -EINVAL;
+ if (value > dptr->max_value) return -EINVAL;
+ if (dptr->set_func) {
+ ret = dptr->set_func(cptr,value);
+ pvr2_i2c_core_check_stale(cptr->hdw);
+ pvr2_i2c_core_sync(cptr->hdw);
return ret;
- } else if (control_defs[ctl_id].get_func) {
+ } else if (dptr->get_func) {
/* If there's no "set" function yet there is still a "get"
function, then treat this as a read-only value. */
return -EINVAL;
}
- if ((hdw->controls[ctl_id].value != value) || (ctlchg != 0)) {
- hdw->controls[ctl_id].value = value;
- hdw->controls[ctl_id].dirty = !0;
+ if ((cptr->value != value) || (ctlchg != 0)) {
+ cptr->value = value;
+ cptr->dirty = !0;
}
return 0;
}
-/* Set current value for given control - this is just stored; the hardware
- isn't updated until the commit function is called. */
-int pvr2_hdw_set_ctl_value(struct pvr2_hdw *hdw,unsigned int ctl_id,int value)
+/* Get the current value of a given control. This assumes that we are
+ already inside our critical region. */
+int pvr2_ctrl_internal_get_value(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ if (!cptr->is_valid) return 0;
+ dptr = cptr->ctl_def;
+ if (!dptr->is_valid) return 0;
+ if (dptr->get_func) {
+ return dptr->get_func(cptr);
+ }
+
+ return cptr->value;
+}
+
+
+/* Set the current value of the given control. */
+int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val)
{
int ret;
- LOCK_TAKE(hdw->big_lock); do {
- ret = pvr2_hdw_set_ctl_value_internal(hdw,ctl_id,value);
- } while (0); LOCK_GIVE(hdw->big_lock);
+ if (!cptr) return -EINVAL;
+ LOCK_TAKE(cptr->hdw->big_lock); do {
+ ret = pvr2_ctrl_internal_set_value(cptr,val);
+ } while(0); LOCK_GIVE(cptr->hdw->big_lock);
return ret;
}
-/* Retrieve string name for a given control value (returns a null pointer
- for any invalid combinations). */
-const char *pvr2_hdw_get_ctl_value_name(struct pvr2_hdw *hdw,
- unsigned int ctl_id,
- int value)
+/* Get the current value of the given control. */
+int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr)
{
- struct pvr2_ctl_def *cdef;
- if (ctl_id >= PVR2_CID_COUNT) return 0;
- cdef = control_defs + ctl_id;
- if (! cdef->value_defs_ptr) return 0;
- if (value >= cdef->value_defs_count) return 0;
- return cdef->value_defs_ptr[value];
+ int ret;
+ if (!cptr) return -EINVAL;
+ LOCK_TAKE(cptr->hdw->big_lock); do {
+ ret = pvr2_ctrl_internal_get_value(cptr);
+ } while(0); LOCK_GIVE(cptr->hdw->big_lock);
+ return ret;
}
-/* Retrieve string name for given control */
-const char *pvr2_hdw_get_ctl_name(struct pvr2_hdw *hdw,unsigned int ctl_id)
+/* Return the type of the given control (int, enum, or bit mask). */
+int pvr2_ctrl_get_type(struct pvr2_ctrl *cptr)
{
- if (ctl_id >= PVR2_CID_COUNT) return 0;
- return control_defs[ctl_id].name;
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return PVR2_CTRL_TYPE_INVALID;
+ dptr = cptr->ctl_def;
+ if (dptr->mask_value) {
+ return PVR2_CTRL_TYPE_BITMASK;
+ }
+ if (dptr->value_defs_ptr) {
+ return PVR2_CTRL_TYPE_ENUM;
+ }
+ return PVR2_CTRL_TYPE_INT;
+}
+
+
+/* Return the minimum legal value for a given control. This command is
+ only relevant for int or enum types. */
+int pvr2_ctrl_get_min_value(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ return dptr->min_value;
+}
+
+
+/* Return the maximum legal value for a given control. This command is
+ only relevant for int or enum types. */
+int pvr2_ctrl_get_max_value(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ return dptr->max_value;
+}
+
+
+/* Return the default value for a given control. */
+int pvr2_ctrl_get_default_value(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ return dptr->default_value;
+}
+
+
+/* Return a mask of which bits are used within the bit mask of a given
+ control. This command is only relevant for bit mask types. */
+int pvr2_ctrl_get_mask_value(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ return dptr->mask_value;
+}
+
+
+/* Return true if this is a valid control. */
+int pvr2_ctrl_is_valid(struct pvr2_ctrl *cptr)
+{
+ if (!cptr) return 0;
+ return cptr->is_valid;
+}
+
+
+/* Return true if the control can be set (otherwise it may only be read,
+ assuming that it is valid). */
+int pvr2_ctrl_is_writeable(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ if (!dptr->is_valid) return 0;
+ if (dptr->set_func) return !0;
+ if (dptr->get_func) return 0;
+ return !0;
+}
+
+
+/* Return the control's name, or null if there isn't a name or the control
+ isn't otherwise valid. */
+const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ return dptr->name;
+}
+
+
+/* Return the control's description, or null if there isn't a name or the
+ control isn't otherwise valid. */
+const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr)
+{
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ return dptr->desc;
+}
+
+
+/* Return the name for an enumeration value or bit mask position for the
+ given control. If the control is not an enumeration or bit mask type,
+ then return null. */
+const char *pvr2_ctrl_get_value_name(struct pvr2_ctrl *cptr,int val)
+{
+ int msk,idx;
+ const struct pvr2_ctl_def *dptr;
+ if (!cptr) return 0;
+ dptr = cptr->ctl_def;
+ if (dptr->mask_value) {
+ for (idx = 0, msk = 1;
+ (idx < dptr->value_defs_count) && msk;
+ idx++, msk <<= 1) {
+ if (val & msk) {
+ return dptr->value_defs_ptr[idx];
+ }
+ }
+ } else {
+ val -= dptr->min_value;
+ if (val < 0) return 0;
+ if (val >= dptr->value_defs_count) return 0;
+ return dptr->value_defs_ptr[val];
+ }
+ return 0;
}
@@ -1560,6 +2193,8 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
unsigned long saved_subsys_mask = hdw->subsys_enabled_mask;
unsigned long stale_subsys_mask = 0;
unsigned int idx;
+ const struct pvr2_ctl_def *dptr;
+ struct pvr2_ctrl *cptr;
int value;
const char *ctl_name;
const char *ctl_value;
@@ -1595,17 +2230,18 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
}
}
- for (idx = 0; idx < PVR2_CID_COUNT; idx++) {
- if (!hdw->controls[idx].dirty) continue;
+ for (idx = 0; idx < CTRL_COUNT; idx++) {
+ cptr = hdw->controls + idx;
+ if (!cptr->dirty) continue;
if (!commit_flag) {
commit_flag = !0;
}
- value = hdw->controls[idx].value;
- ctl_name = control_defs[idx].name;
- if (control_defs[idx].value_defs_ptr) {
- if (value < control_defs[idx].value_defs_count) {
- ctl_value =
- control_defs[idx].value_defs_ptr[value];
+ value = cptr->value;
+ dptr = cptr->ctl_def;
+ ctl_name = dptr->name;
+ if (dptr->value_defs_ptr) {
+ if (value < dptr->value_defs_count) {
+ ctl_value = dptr->value_defs_ptr[value];
} else {
ctl_value = "<out of range>";
}
@@ -1625,16 +2261,13 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
/* When video standard changes, reset the hres and vres values -
but if the user has pending changes there, then let the changes
take priority. */
- if (hdw->controls[PVR2_CID_VIDEOSTANDARD].dirty) {
+ if (hdw->controls[PVR2_CID_STDCUR].dirty) {
/* Rewrite the vertical resolution to be appropriate to the
video standard that has been selected. */
- int nvres = hdw->controls[PVR2_CID_VRES].value;
- switch (hdw->controls[PVR2_CID_VIDEOSTANDARD].value) {
- case PVR2_CVAL_VIDEOSTANDARD_NTSC_M:
- case PVR2_CVAL_VIDEOSTANDARD_PAL_M:
+ int nvres;
+ if (hdw->video_std_cur & V4L2_STD_525_60) {
nvres = 480;
- break;
- default:
+ } else {
nvres = 576;
}
if (nvres != hdw->controls[PVR2_CID_VRES].value) {
@@ -1647,7 +2280,7 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
}
}
- if (hdw->controls[PVR2_CID_VIDEOSTANDARD].dirty ||
+ if (hdw->controls[PVR2_CID_STDCUR].dirty ||
hdw->controls[PVR2_CID_VRES].dirty ||
hdw->controls[PVR2_CID_HRES].dirty ||
hdw->controls[PVR2_CID_INTERLACE].dirty ||
@@ -1671,8 +2304,9 @@ int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
the client drivers in order to keep everything in sync */
pvr2_i2c_core_check_stale(hdw);
- for (idx = 0; idx < PVR2_CID_COUNT; idx++) {
- hdw->controls[idx].dirty = 0;
+ for (idx = 0; idx < CTRL_COUNT; idx++) {
+ cptr = hdw->controls + idx;
+ cptr->dirty = 0;
}
/* Now execute i2c core update */
@@ -1729,14 +2363,6 @@ void pvr2_hdw_poll_trigger(struct pvr2_hdw *hdw)
}
-/* Find out how many controls there are. Legal ids are numbered from 1
- through this value. */
-unsigned int pvr2_hdw_get_ctl_count(struct pvr2_hdw *hdw)
-{
- return PVR2_CID_COUNT;
-}
-
-
/* Return name for this driver instance */
const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
{
@@ -1772,36 +2398,36 @@ unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw)
}
-static int pvr2_ctl_get_subsys_mask(struct pvr2_hdw *hdw,int ctl_id)
+static int pvr2_ctl_get_subsys_mask(struct pvr2_ctrl *cptr)
{
- return hdw->subsys_enabled_mask;
+ return cptr->hdw->subsys_enabled_mask;
}
-static int pvr2_ctl_set_subsys_mask(struct pvr2_hdw *hdw,int ctl_id,int val)
+static int pvr2_ctl_set_subsys_mask(struct pvr2_ctrl *cptr,int val)
{
- pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,val);
+ pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,~0,val);
return 0;
}
-static int pvr2_ctl_get_subsys_stream_mask(struct pvr2_hdw *hdw,int ctl_id)
+static int pvr2_ctl_get_subsys_stream_mask(struct pvr2_ctrl *cptr)
{
- return hdw->subsys_stream_mask;
+ return cptr->hdw->subsys_stream_mask;
}
-static int pvr2_ctl_set_subsys_stream_mask(struct pvr2_hdw *hdw,int ctl_id,
+static int pvr2_ctl_set_subsys_stream_mask(struct pvr2_ctrl *cptr,
int val)
{
- pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,~0,val);
+ pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,~0,val);
return 0;
}
-static int pvr2_ctl_get_hsm(struct pvr2_hdw *hdw,int ctl_id)
+static int pvr2_ctl_get_hsm(struct pvr2_ctrl *cptr)
{
- int result = pvr2_hdw_is_hsm(hdw);
+ int result = pvr2_hdw_is_hsm(cptr->hdw);
if (result < 0) return PVR2_CVAL_HSM_FAIL;
if (result) return PVR2_CVAL_HSM_HIGH;
return PVR2_CVAL_HSM_FULL;
@@ -1823,10 +2449,10 @@ int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
}
-static int pvr2_ctl_get_signal(struct pvr2_hdw *hdw,int ctl_id)
+static int pvr2_ctl_get_signal(struct pvr2_ctrl *cptr)
{
- return ((pvr2_hdw_get_signal_status_internal(hdw) & PVR2_SIGNAL_OK) ?
- 1 : 0);
+ return ((pvr2_hdw_get_signal_status_internal(cptr->hdw) &
+ PVR2_SIGNAL_OK) ? 1 : 0);
}
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index aa6d9029a..4101f4097 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -21,89 +21,37 @@
#ifndef __PVRUSB2_HDW_H
#define __PVRUSB2_HDW_H
+#include "compat.h"
#include <linux/usb.h>
+#include <linux/videodev2.h>
#include "pvrusb2-io.h"
-/* Definition of state variables that we can inspect & change. Numbers are
- assigned from zero counting up with no gaps. */
-#define PVR2_CID_BRIGHTNESS 0
-#define PVR2_CID_CONTRAST 1
-#define PVR2_CID_SATURATION 2
-#define PVR2_CID_HUE 3
-#define PVR2_CID_VOLUME 4
-#define PVR2_CID_BALANCE 5
-#define PVR2_CID_BASS 6
-#define PVR2_CID_TREBLE 7
-#define PVR2_CID_MUTE 8
-#define PVR2_CID_SRATE 9
-#define PVR2_CID_AUDIOBITRATE 10
-#define PVR2_CID_AUDIOCRC 11
-#define PVR2_CID_AUDIOEMPHASIS 12
-#define PVR2_CID_VBR 13
-#define PVR2_CID_AVERAGEVIDEOBITRATE 14
-#define PVR2_CID_PEAKVIDEOBITRATE 15
-#define PVR2_CID_VIDEOSTANDARD 16
-#define PVR2_CID_INPUT 17
-#define PVR2_CID_AUDIOMODE 18
-#define PVR2_CID_FREQUENCY 19 // Units of Hz
-#define PVR2_CID_HRES 20
-#define PVR2_CID_VRES 21
-#define PVR2_CID_INTERLACE 22
-#define PVR2_CID_AUDIOLAYER 23
-#define PVR2_CID_CHANNEL 24
-#define PVR2_CID_CHANPROG_ID 25
-#define PVR2_CID_CHANPROG_FREQ 26
-#define PVR2_CID_SIGNAL_PRESENT 27
-#define PVR2_CID_STREAMING_ENABLED 28
-#define PVR2_CID_HSM 29
-#define PVR2_CID_SUBSYS_MASK 30
-#define PVR2_CID_SUBSYS_STREAM_MASK 31
-
-/* Number of state variables */
-#define PVR2_CID_COUNT 32
-
-/* Legal values for the SRATE state variable */
-#define PVR2_CVAL_SRATE_48 0
-#define PVR2_CVAL_SRATE_44_1 1
-#define PVR2_CVAL_SRATE_MIN PVR2_CVAL_SRATE_48
-#define PVR2_CVAL_SRATE_MAX PVR2_CVAL_SRATE_44_1
-
-/* Legal values for the AUDIOBITRATE state variable */
-#define PVR2_CVAL_AUDIOBITRATE_384 0
-#define PVR2_CVAL_AUDIOBITRATE_320 1
-#define PVR2_CVAL_AUDIOBITRATE_256 2
-#define PVR2_CVAL_AUDIOBITRATE_224 3
-#define PVR2_CVAL_AUDIOBITRATE_192 4
-#define PVR2_CVAL_AUDIOBITRATE_160 5
-#define PVR2_CVAL_AUDIOBITRATE_128 6
-#define PVR2_CVAL_AUDIOBITRATE_112 7
-#define PVR2_CVAL_AUDIOBITRATE_96 8
-#define PVR2_CVAL_AUDIOBITRATE_80 9
-#define PVR2_CVAL_AUDIOBITRATE_64 10
-#define PVR2_CVAL_AUDIOBITRATE_56 11
-#define PVR2_CVAL_AUDIOBITRATE_48 12
-#define PVR2_CVAL_AUDIOBITRATE_32 13
-#define PVR2_CVAL_AUDIOBITRATE_VBR 14
-#define PVR2_CVAL_AUDIOBITRATE_MIN PVR2_CVAL_AUDIOBITRATE_384
-#define PVR2_CVAL_AUDIOBITRATE_MAX PVR2_CVAL_AUDIOBITRATE_VBR
-
-/* Legal values for the AUDIOEMPHASIS state variable */
-#define PVR2_CVAL_AUDIOEMPHASIS_NONE 0
-#define PVR2_CVAL_AUDIOEMPHASIS_50_15 1
-#define PVR2_CVAL_AUDIOEMPHASIS_CCITT 2
-#define PVR2_CVAL_AUDIOEMPHASIS_MIN PVR2_CVAL_AUDIOEMPHASIS_NONE
-#define PVR2_CVAL_AUDIOEMPHASIS_MAX PVR2_CVAL_AUDIOEMPHASIS_CCITT
-
-/* Legal values for the VIDEOSTANDARD state variable */
-#define PVR2_CVAL_VIDEOSTANDARD_NTSC_M 0
-#define PVR2_CVAL_VIDEOSTANDARD_PAL_BG 1
-#define PVR2_CVAL_VIDEOSTANDARD_PAL_I 2
-#define PVR2_CVAL_VIDEOSTANDARD_PAL_DK 3
-#define PVR2_CVAL_VIDEOSTANDARD_PAL_M 4
-#define PVR2_CVAL_VIDEOSTANDARD_SECAM_L 5
-
-#define PVR2_CVAL_VIDEOSTANDARD_MIN PVR2_CVAL_VIDEOSTANDARD_NTSC_M
-#define PVR2_CVAL_VIDEOSTANDARD_MAX PVR2_CVAL_VIDEOSTANDARD_SECAM_L
+#define PVR2_CTRL_TYPE_INVALID 0
+#define PVR2_CTRL_TYPE_ENUM 1
+#define PVR2_CTRL_TYPE_INT 2
+#define PVR2_CTRL_TYPE_BITMASK 3
+
+/* Private V4L2-compatible controls available in this driver */
+#define V4L2_CID_PVR_SRATE (V4L2_CID_PRIVATE_BASE)
+#define V4L2_CID_PVR_AUDIOBITRATE (V4L2_CID_PRIVATE_BASE+1)
+#define V4L2_CID_PVR_AUDIOCRC (V4L2_CID_PRIVATE_BASE+2)
+#define V4L2_CID_PVR_AUDIOEMPHASIS (V4L2_CID_PRIVATE_BASE+3)
+#define V4L2_CID_PVR_VBR (V4L2_CID_PRIVATE_BASE+4)
+#define V4L2_CID_PVR_VIDEOBITRATE (V4L2_CID_PRIVATE_BASE+5)
+#define V4L2_CID_PVR_VIDEOPEAK (V4L2_CID_PRIVATE_BASE+6)
+#define V4L2_CID_PVR_VIDEOSTANDARD (V4L2_CID_PRIVATE_BASE+7)
+
+/* Deliberate gap for CIDs we don't want apps to discover */
+#define V4L2_CID_PVR_GAP (V4L2_CID_PRIVATE_BASE+8)
+
+/* Additional explicit controls needed by V4L2 ioctl implementation */
+#define V4L2_CID_PVR_STDCUR (V4L2_CID_PVR_GAP+1)
+#define V4L2_CID_PVR_INPUT (V4L2_CID_PVR_GAP+2)
+#define V4L2_CID_PVR_AUDIOMODE (V4L2_CID_PVR_GAP+3)
+#define V4L2_CID_PVR_FREQUENCY (V4L2_CID_PVR_GAP+4)
+#define V4L2_CID_PVR_HRES (V4L2_CID_PVR_GAP+5)
+#define V4L2_CID_PVR_VRES (V4L2_CID_PVR_GAP+6)
+#define V4L2_CID_PVR_INTERLACE (V4L2_CID_PVR_GAP+7)
/* Legal values for the INPUT state variable */
#define PVR2_CVAL_INPUT_TV 0
@@ -113,27 +61,11 @@
#define PVR2_CVAL_INPUT_MIN PVR2_CVAL_INPUT_TV
#define PVR2_CVAL_INPUT_MAX PVR2_CVAL_INPUT_RADIO
-/* Legal values for the AUDIOMODE state variable */
-#define PVR2_CVAL_AUDIOMODE_MONO 0
-#define PVR2_CVAL_AUDIOMODE_STEREO 1
-#define PVR2_CVAL_AUDIOMODE_SAP 2
-#define PVR2_CVAL_AUDIOMODE_LANG1 3
-#define PVR2_CVAL_AUDIOMODE_LANG2 4
-#define PVR2_CVAL_AUDIOMODE_LANG1_LANG2 5
-#define PVR2_CVAL_AUDIOMODE_MIN PVR2_CVAL_AUDIOMODE_MONO
-#define PVR2_CVAL_AUDIOMODE_MAX PVR2_CVAL_AUDIOMODE_LANG1_LANG2
-
/* Values that pvr2_hdw_get_signal_status() returns */
#define PVR2_SIGNAL_OK 0x0001
#define PVR2_SIGNAL_STEREO 0x0002
#define PVR2_SIGNAL_SAP 0x0004
-/* Legal values for PVR2_CID_HSM */
-#define PVR2_CVAL_HSM_FAIL 0
-#define PVR2_CVAL_HSM_FULL 1
-#define PVR2_CVAL_HSM_HIGH 2
-#define PVR2_CVAL_HSM_MIN PVR2_CVAL_HSM_FAIL
-#define PVR2_CVAL_HSM_MAX PVR2_CVAL_HSM_HIGH
/* Subsystem definitions - these are various pieces that can be
independently stopped / started. Usually you don't want to mess with
@@ -167,6 +99,8 @@ const char *pvr2_config_get_name(enum pvr2_config);
struct pvr2_hdw;
+struct pvr2_ctrl;
+
/* Create and return a structure for interacting with the underlying
hardware */
struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
@@ -215,37 +149,69 @@ unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *);
/* Called when hardware has been unplugged */
void pvr2_hdw_disconnect(struct pvr2_hdw *);
-/* Retrieve current value for a given control */
-int pvr2_hdw_get_ctl_value(struct pvr2_hdw *,unsigned int ctl_id);
+/* Get the number of defined controls */
+unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *);
+
+/* Retrieve a control handle given its index (0..count-1) */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *,unsigned int);
+
+/* Retrieve a control handle given its well known ID */
+struct pvr2_ctrl *pvr2_hdw_get_ctrl(struct pvr2_hdw *,unsigned int ctl_id);
+
+/* Set the current value of the given control. */
+int pvr2_ctrl_set_value(struct pvr2_ctrl *,int val);
+
+/* Get the current value of the given control. */
+int pvr2_ctrl_get_value(struct pvr2_ctrl *);
+
+/* Return the type of the given control (int, enum, or bit mask). */
+int pvr2_ctrl_get_type(struct pvr2_ctrl *);
-/* Return true if control is writable */
-int pvr2_hdw_get_ctl_rw(struct pvr2_hdw *,unsigned int ctl_id);
+/* Return the minimum legal value for a given control. This command is
+ only relevant for int or enum types. */
+int pvr2_ctrl_get_min_value(struct pvr2_ctrl *);
-/* Retrieve legal minimum value for a given control */
-int pvr2_hdw_get_ctl_min_value(struct pvr2_hdw *,unsigned int ctl_id);
+/* Return the maximum legal value for a given control. This command is
+ only relevant for int or enum types. */
+int pvr2_ctrl_get_max_value(struct pvr2_ctrl *);
-/* Retrieve legal maximum value for a given control */
-int pvr2_hdw_get_ctl_max_value(struct pvr2_hdw *,unsigned int ctl_id);
+/* Return a mask of which bits are used within the bit mask of a given
+ control. This command is only relevant for bit mask types. */
+int pvr2_ctrl_get_mask_value(struct pvr2_ctrl *);
-/* Set current value for given control - this is just stored; the hardware
- isn't updated until the commit function is called. */
-int pvr2_hdw_set_ctl_value(struct pvr2_hdw *,unsigned int ctl_id,int value);
+/* Return the default value for a given control. */
+int pvr2_ctrl_get_default_value(struct pvr2_ctrl *);
-/* Retrieve string name for given control */
-const char *pvr2_hdw_get_ctl_name(struct pvr2_hdw *,unsigned int ctl_id);
+/* Return true if this is a valid control. */
+int pvr2_ctrl_is_valid(struct pvr2_ctrl *);
-/* Retrieve string name for a given control value (returns a null pointer
- for any invalid combinations). */
-const char *pvr2_hdw_get_ctl_value_name(struct pvr2_hdw *,
- unsigned int ctl_id,int value);
+/* Return true if the control can be set (otherwise it may only be read,
+ assuming that it is valid). */
+int pvr2_ctrl_is_writeable(struct pvr2_ctrl *);
+
+/* Return the control's name, or null if there isn't a name or the control
+ isn't otherwise valid. */
+const char *pvr2_ctrl_get_name(struct pvr2_ctrl *);
+
+/* Return the control's description, or null if there isn't a name or the
+ control isn't otherwise valid. */
+const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *);
+
+/* Return the name for an enumeration value or bit mask position for the
+ given control. If the control is not an enumeration or bit mask type,
+ then return null. */
+const char *pvr2_ctrl_get_value_name(struct pvr2_ctrl *,int val);
+
+/* Return the number of support standard groups */
+unsigned int pvr2_hdw_get_stdenum_count(struct pvr2_hdw *);
+
+/* Return a pointer to a v4l2 standard descriptor for a given group */
+const struct v4l2_standard *pvr2_hdw_get_stdenum_value(struct pvr2_hdw *,
+ unsigned int idx);
/* Commit all control changes made up to this point */
int pvr2_hdw_commit_ctl(struct pvr2_hdw *);
-/* Find out how many controls there are. Legal ids are numbered from 0
- through this value - 1. */
-unsigned int pvr2_hdw_get_ctl_count(struct pvr2_hdw *);
-
/* Return name for this driver instance */
const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *);
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
index fc9d76792..89d0da053 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
@@ -28,8 +28,10 @@
#include "pvrusb2-tuner.h"
#include "pvrusb2-demod.h"
#include "pvrusb2-video-v4l.h"
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
#include "pvrusb2-cx2584x-v4l.h"
#include "pvrusb2-wm8775.h"
+#endif
#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
@@ -71,6 +73,7 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
return;
}
}
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
if (id == I2C_DRIVERID_CX25840) {
if (pvr2_i2c_cx2584x_v4l_setup(hdw,cp)) {
return;
@@ -81,6 +84,7 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
return;
}
}
+#endif
if (id == I2C_DRIVERID_SAA711X) {
if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) {
return;
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
index 000c26911..b3d2ce926 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
@@ -24,43 +24,23 @@
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-debug.h"
#include <linux/videodev.h>
+#include <linux/videodev2.h>
static void set_standard(struct pvr2_hdw *hdw)
{
- int cvstd = hdw->controls[PVR2_CID_VIDEOSTANDARD].value;
v4l2_std_id vs;
+ vs = hdw->controls[PVR2_CID_STDCUR].value;
pvr2_trace(PVR2_TRACE_CHIPS,
- "i2c v4l2 set_standard(%d)",cvstd);
-
- switch (cvstd) {
- default:
- case PVR2_CVAL_VIDEOSTANDARD_NTSC_M:
- vs = V4L2_STD_NTSC_M;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_SECAM_L:
- vs = V4L2_STD_SECAM;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_BG:
- vs = V4L2_STD_PAL_BG;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_I:
- vs = V4L2_STD_PAL_I;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_DK:
- vs = V4L2_STD_PAL_DK;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_M:
- vs = V4L2_STD_PAL_M;
- break;
- }
+ "i2c v4l2 set_standard(0x%llx)",(__u64)vs);
+
pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs);
}
static int check_standard(struct pvr2_hdw *hdw)
{
- return hdw->controls[PVR2_CID_VIDEOSTANDARD].dirty != 0;
+ return hdw->controls[PVR2_CID_STDCUR].dirty != 0;
}
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 2f7946195..9a96273f2 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -262,18 +262,29 @@ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
done:
if (pvrusb2_debug & PVR2_TRACE_I2C_TRAF) {
- unsigned int idx;
+ unsigned int idx,offs,cnt;
for (idx = 0; idx < num; idx++) {
+ cnt = msgs[idx].len;
printk(KERN_INFO
"pvrusb2 i2c xfer %u/%u:"
" addr=0x%x len=%d %s%s",
idx+1,num,
msgs[idx].addr,
- msgs[idx].len,
+ cnt,
(msgs[idx].flags & I2C_M_RD ?
"read" : "write"),
(msgs[idx].flags & I2C_M_NOSTART ?
" nostart" : ""));
+ if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) {
+ if (cnt > 8) cnt = 8;
+ printk(" [");
+ for (offs = 0; offs < (cnt>8?8:cnt); offs++) {
+ if (offs) printk(" ");
+ printk("%02x",msgs[idx].buf[offs]);
+ }
+ if (offs < cnt) printk(" ...");
+ printk("]");
+ }
if (idx+1 == num) {
printk(" result=%d",ret);
}
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-main.c b/linux/drivers/media/video/pvrusb2/pvrusb2-main.c
index c070fc195..40fb6ae41 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -35,7 +35,9 @@
#include "pvrusb2-context.h"
#include "pvrusb2-debug.h"
#include "pvrusb2-v4l2.h"
+#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
#include "pvrusb2-sysfs.h"
+#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
#define DRIVER_AUTHOR "Mike Isely <isely@pobox.com>"
#define DRIVER_DESC "Hauppauge WinTV-PVR-USB2 MPEG2 Encoder/Tuner"
@@ -60,13 +62,17 @@ int pvrusb2_debug = DEFAULT_DEBUG_MASK;
module_param_named(debug,pvrusb2_debug,int,S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(debug, "Debug trace mask");
+#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
static struct pvr2_sysfs_class *class_ptr = 0;
+#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
static void pvr_setup_attach(struct pvr2_context *pvr)
{
/* Create association with v4l layer */
pvr2_v4l2_create(pvr);
+#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
pvr2_sysfs_create(pvr,class_ptr);
+#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
}
static int pvr_probe(struct usb_interface *intf,
@@ -138,7 +144,9 @@ static int __init pvr_init(void)
request_module("tda9887");
request_module("wm8775");
+#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
class_ptr = pvr2_sysfs_class_create();
+#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
ret = usb_register(&pvr_driver);
@@ -155,7 +163,9 @@ static void __exit pvr_exit(void)
pvr2_trace(PVR2_TRACE_INIT,"pvr_exit");
+#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
pvr2_sysfs_class_destroy(class_ptr);
+#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
usb_deregister(&pvr_driver);
}
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index f82fd643c..053c0b24c 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -26,49 +26,18 @@
#include "pvrusb2-sysfs.h"
#include "pvrusb2-hdw.h"
#include "pvrusb2-debug.h"
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
#include "pvrusb2-debugifc.h"
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
#define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__)
-static char *item_names[PVR2_CID_COUNT] = {
- [PVR2_CID_BRIGHTNESS] = "ctl_brightness",
- [PVR2_CID_CONTRAST] = "ctl_contrast",
- [PVR2_CID_SATURATION] = "ctl_saturation",
- [PVR2_CID_HUE] = "ctl_hue",
- [PVR2_CID_VOLUME] = "ctl_volume",
- [PVR2_CID_BALANCE] = "ctl_balance",
- [PVR2_CID_BASS] = "ctl_bass",
- [PVR2_CID_TREBLE] = "ctl_treble",
- [PVR2_CID_MUTE] = "ctl_mute",
- [PVR2_CID_SRATE] = "ctl_srate",
- [PVR2_CID_AUDIOBITRATE] = "ctl_audio_bitrate",
- [PVR2_CID_AUDIOCRC] = "ctl_audio_crc",
- [PVR2_CID_AUDIOEMPHASIS] = "ctl_audio_emphasis",
- [PVR2_CID_VBR] = "ctl_vbr",
- [PVR2_CID_AVERAGEVIDEOBITRATE] = "ctl_video_average_bitrate",
- [PVR2_CID_PEAKVIDEOBITRATE] = "ctl_video_peak_bitrate",
- [PVR2_CID_VIDEOSTANDARD] = "ctl_video_standard",
- [PVR2_CID_INPUT] = "ctl_input",
- [PVR2_CID_AUDIOMODE] = "ctl_audio_mode",
- [PVR2_CID_FREQUENCY] = "ctl_frequency",
- [PVR2_CID_HRES] = "ctl_resolution_hor",
- [PVR2_CID_VRES] = "ctl_resolution_ver",
- [PVR2_CID_INTERLACE] = "ctl_interlace",
- [PVR2_CID_AUDIOLAYER] = "ctl_audio_layer",
- [PVR2_CID_CHANNEL] = "ctl_channel",
- [PVR2_CID_CHANPROG_ID] = "ctl_freq_table_channel",
- [PVR2_CID_CHANPROG_FREQ] = "ctl_freq_table_value",
- [PVR2_CID_SIGNAL_PRESENT] = "ctl_signal_present",
- [PVR2_CID_STREAMING_ENABLED] = "ctl_streaming_enabled",
- [PVR2_CID_HSM] = "ctl_usb_speed",
- [PVR2_CID_SUBSYS_MASK] = "ctl_debug_subsys_mask",
- [PVR2_CID_SUBSYS_STREAM_MASK] = "ctl_debug_subsys_stream_mask",
-};
-
struct pvr2_sysfs {
struct pvr2_channel channel;
struct class_device *class_dev;
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
struct pvr2_sysfs_debugifc *debugifc;
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
struct pvr2_sysfs_ctl_item *item_first;
struct pvr2_sysfs_ctl_item *item_last;
struct sysfs_ops kops;
@@ -77,10 +46,12 @@ struct pvr2_sysfs {
struct class_device_attribute attr_unit_number;
};
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
struct pvr2_sysfs_debugifc {
struct class_device_attribute attr_debugcmd;
struct class_device_attribute attr_debuginfo;
};
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
struct pvr2_sysfs_ctl_item {
struct class_device_attribute attr_name;
@@ -88,11 +59,12 @@ struct pvr2_sysfs_ctl_item {
struct class_device_attribute attr_max;
struct class_device_attribute attr_enum;
struct class_device_attribute attr_val;
- int attr_id;
+ struct pvr2_ctrl *cptr;
struct pvr2_sysfs *chptr;
struct pvr2_sysfs_ctl_item *item_next;
struct attribute *attr_gen[5];
struct attribute_group grp;
+ char name[80];
};
struct pvr2_sysfs_class {
@@ -101,13 +73,16 @@ struct pvr2_sysfs_class {
static ssize_t show_name(int id,struct class_device *class_dev,char *buf)
{
+ struct pvr2_ctrl *cptr;
struct pvr2_sysfs *sfp;
const char *name;
sfp = (struct pvr2_sysfs *)class_dev->class_data;
if (!sfp) return -EINVAL;
- name = pvr2_hdw_get_ctl_name(sfp->channel.hdw,id);
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+ if (!pvr2_ctrl_is_valid(cptr)) return -EINVAL;
+ name = pvr2_ctrl_get_desc(cptr);
pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",sfp,id,name);
if (!name) return -EINVAL;
@@ -117,13 +92,15 @@ static ssize_t show_name(int id,struct class_device *class_dev,char *buf)
static ssize_t show_min(int id,struct class_device *class_dev,char *buf)
{
+ struct pvr2_ctrl *cptr;
struct pvr2_sysfs *sfp;
int val;
sfp = (struct pvr2_sysfs *)class_dev->class_data;
if (!sfp) return -EINVAL;
- val = pvr2_hdw_get_ctl_min_value(sfp->channel.hdw,id);
-
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+ if (!pvr2_ctrl_is_valid(cptr)) return -EINVAL;
+ val = pvr2_ctrl_get_min_value(cptr);
pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %d",sfp,id,val);
return scnprintf(buf,PAGE_SIZE,"%d\n",val);
@@ -131,12 +108,15 @@ static ssize_t show_min(int id,struct class_device *class_dev,char *buf)
static ssize_t show_max(int id,struct class_device *class_dev,char *buf)
{
+ struct pvr2_ctrl *cptr;
struct pvr2_sysfs *sfp;
int val;
sfp = (struct pvr2_sysfs *)class_dev->class_data;
if (!sfp) return -EINVAL;
- val = pvr2_hdw_get_ctl_max_value(sfp->channel.hdw,id);
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+ if (!pvr2_ctrl_is_valid(cptr)) return -EINVAL;
+ val = pvr2_ctrl_get_max_value(cptr);
pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %d",sfp,id,val);
@@ -145,12 +125,15 @@ static ssize_t show_max(int id,struct class_device *class_dev,char *buf)
static ssize_t show_val_int(int id,struct class_device *class_dev,char *buf)
{
+ struct pvr2_ctrl *cptr;
struct pvr2_sysfs *sfp;
int val;
sfp = (struct pvr2_sysfs *)class_dev->class_data;
if (!sfp) return -EINVAL;
- val = pvr2_hdw_get_ctl_value(sfp->channel.hdw,id);
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+ if (!pvr2_ctrl_is_valid(cptr)) return -EINVAL;
+ val = pvr2_ctrl_get_value(cptr);
pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_int(cid=%d) is %d",
sfp,id,val);
@@ -160,15 +143,18 @@ static ssize_t show_val_int(int id,struct class_device *class_dev,char *buf)
static ssize_t show_val_enum(int id,struct class_device *class_dev,char *buf)
{
+ struct pvr2_ctrl *cptr;
struct pvr2_sysfs *sfp;
int val;
const char *name;
sfp = (struct pvr2_sysfs *)class_dev->class_data;
if (!sfp) return -EINVAL;
- val = pvr2_hdw_get_ctl_value(sfp->channel.hdw,id);
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+ if (!pvr2_ctrl_is_valid(cptr)) return -EINVAL;
- name = pvr2_hdw_get_ctl_value_name(sfp->channel.hdw,id,val);
+ val = pvr2_ctrl_get_value(cptr);
+ name = pvr2_ctrl_get_value_name(cptr,val);
pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_enum(cid=%d) is %s (%d)",
sfp,id,name,val);
@@ -178,6 +164,7 @@ static ssize_t show_val_enum(int id,struct class_device *class_dev,char *buf)
static ssize_t show_enum(int id,struct class_device *class_dev,char *buf)
{
+ struct pvr2_ctrl *cptr;
struct pvr2_sysfs *sfp;
int minval,maxval,val;
const char *name;
@@ -185,10 +172,12 @@ static ssize_t show_enum(int id,struct class_device *class_dev,char *buf)
sfp = (struct pvr2_sysfs *)class_dev->class_data;
if (!sfp) return -EINVAL;
- minval = pvr2_hdw_get_ctl_min_value(sfp->channel.hdw,id);
- maxval = pvr2_hdw_get_ctl_max_value(sfp->channel.hdw,id);
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+ if (!pvr2_ctrl_is_valid(cptr)) return -EINVAL;
+ minval = pvr2_ctrl_get_min_value(cptr);
+ maxval = pvr2_ctrl_get_max_value(cptr);
for (val = minval; val <= maxval; val++) {
- name = pvr2_hdw_get_ctl_value_name(sfp->channel.hdw,id,val);
+ name = pvr2_ctrl_get_value_name(cptr,val);
cnt += scnprintf(buf+cnt,PAGE_SIZE-cnt,"%s\n",name);
}
pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",sfp,id);
@@ -198,6 +187,7 @@ static ssize_t show_enum(int id,struct class_device *class_dev,char *buf)
static int store_val_any(int id,struct pvr2_sysfs *sfp,
const char *buf,unsigned int count)
{
+ struct pvr2_ctrl *cptr;
int val,minval,maxval;
int ch,ret;
const char *nv;
@@ -217,11 +207,14 @@ static int store_val_any(int id,struct pvr2_sysfs *sfp,
count--;
}
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
+ if (!pvr2_ctrl_is_valid(cptr)) return -EINVAL;
+
/* Is this an enum? Look for a string value */
- minval = pvr2_hdw_get_ctl_min_value(sfp->channel.hdw,id);
- maxval = pvr2_hdw_get_ctl_max_value(sfp->channel.hdw,id);
+ minval = pvr2_ctrl_get_min_value(cptr);
+ maxval = pvr2_ctrl_get_max_value(cptr);
for (val = minval; val <= maxval; val++) {
- nv = pvr2_hdw_get_ctl_value_name(sfp->channel.hdw,id,val);
+ nv = pvr2_ctrl_get_value_name(cptr,val);
if ((!nv) && (val == minval)) break; /* Not an enum */
pvr2_sysfs_trace("pvr2_sysfs(%p) trying ctl_id %d val %d",
sfp,id,val);
@@ -246,7 +239,7 @@ static int store_val_any(int id,struct pvr2_sysfs *sfp,
pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_any(cid=%d)"
" is enum %s",
sfp,id,nv);
- ret = pvr2_hdw_set_ctl_value(sfp->channel.hdw,id,val);
+ ret = pvr2_ctrl_set_value(cptr,val);
pvr2_hdw_commit_ctl(sfp->channel.hdw);
return 0;
}
@@ -284,7 +277,7 @@ static int store_val_any(int id,struct pvr2_sysfs *sfp,
" int is %d",
sfp,id,val);
- ret = pvr2_hdw_set_ctl_value(sfp->channel.hdw,id,val);
+ ret = pvr2_ctrl_set_value(cptr,val);
pvr2_hdw_commit_ctl(sfp->channel.hdw);
return ret;
}
@@ -395,6 +388,8 @@ CREATE_BATCH(28)
CREATE_BATCH(29)
CREATE_BATCH(30)
CREATE_BATCH(31)
+CREATE_BATCH(32)
+CREATE_BATCH(33)
struct pvr2_sysfs_func_set {
ssize_t (*show_name)(struct class_device *,char *);
@@ -454,6 +449,8 @@ static struct pvr2_sysfs_func_set funcs[] = {
INIT_BATCH(29),
INIT_BATCH(30),
INIT_BATCH(31),
+ INIT_BATCH(32),
+ INIT_BATCH(33),
};
@@ -461,19 +458,23 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
{
struct pvr2_sysfs_ctl_item *cip;
struct pvr2_sysfs_func_set *fp;
+ struct pvr2_ctrl *cptr;
+ unsigned int cnt;
if ((ctl_id < 0) || (ctl_id >= (sizeof(funcs)/sizeof(funcs[0])))) {
return;
}
fp = funcs + ctl_id;
+ cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id);
+ if (!cptr) return;
cip = kmalloc(sizeof(*cip),GFP_KERNEL);
if (!cip) return;
memset(cip,0,sizeof(*cip));
pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip);
- cip->attr_id = ctl_id;
+ cip->cptr = cptr;
cip->chptr = sfp;
cip->item_next = 0;
@@ -508,15 +509,13 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
cip->attr_enum.attr.mode = S_IRUGO;
cip->attr_enum.show = fp->show_enum;
- if (pvr2_hdw_get_ctl_rw(sfp->channel.hdw,ctl_id)) {
+ if (pvr2_ctrl_is_writeable(cptr)) {
cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP;
}
cip->attr_gen[0] = &cip->attr_name.attr;
cip->attr_gen[1] = &cip->attr_val.attr;
- if (pvr2_hdw_get_ctl_value_name(
- sfp->channel.hdw,ctl_id,
- pvr2_hdw_get_ctl_min_value(sfp->channel.hdw,ctl_id))) {
+ if (pvr2_ctrl_get_type(cptr) == PVR2_CTRL_TYPE_ENUM) {
// Control is an enumeration
cip->attr_gen[2] = &cip->attr_enum.attr;
cip->attr_val.show = fp->show_val_enum;
@@ -529,12 +528,16 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
cip->attr_gen[3] = &cip->attr_max.attr;
}
- cip->grp.name = item_names[ctl_id];
+ cnt = scnprintf(cip->name,sizeof(cip->name)-1,"ctl_%s",
+ pvr2_ctrl_get_name(cptr));
+ cip->name[cnt] = 0;
+ cip->grp.name = cip->name;
cip->grp.attrs = cip->attr_gen;
sysfs_create_group(&sfp->class_dev->kobj,&cip->grp);
}
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
static ssize_t debuginfo_show(struct class_device *,char *);
static ssize_t debugcmd_show(struct class_device *,char *);
static ssize_t debugcmd_store(struct class_device *,const char *,size_t count);
@@ -569,16 +572,15 @@ static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp)
kfree(sfp->debugifc);
sfp->debugifc = 0;
}
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
static void pvr2_sysfs_add_controls(struct pvr2_sysfs *sfp)
{
- unsigned int ctl_id;
-
- for (ctl_id = 0;
- ctl_id < (sizeof(item_names)/sizeof(item_names[0])); ctl_id++) {
- if (!item_names[ctl_id]) continue;
- pvr2_sysfs_add_control(sfp,ctl_id);
+ unsigned int idx,cnt;
+ cnt = pvr2_hdw_get_ctrl_count(sfp->channel.hdw);
+ for (idx = 0; idx < cnt; idx++) {
+ pvr2_sysfs_add_control(sfp,idx);
}
}
@@ -614,7 +616,9 @@ static void pvr2_sysfs_release(struct class_device *class_dev)
static void class_dev_destroy(struct pvr2_sysfs *sfp)
{
if (!sfp->class_dev) return;
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
pvr2_sysfs_tear_down_debugifc(sfp);
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
pvr2_sysfs_tear_down_controls(sfp);
class_device_remove_file(sfp->class_dev,&sfp->attr_v4l_minor_number);
class_device_remove_file(sfp->class_dev,&sfp->attr_unit_number);
@@ -690,7 +694,9 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
class_device_create_file(sfp->class_dev,&sfp->attr_unit_number);
pvr2_sysfs_add_controls(sfp);
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
pvr2_sysfs_add_debugifc(sfp);
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
}
@@ -761,6 +767,7 @@ void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp)
}
+#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
static ssize_t debuginfo_show(struct class_device *class_dev,char *buf)
{
struct pvr2_sysfs *sfp;
@@ -793,6 +800,7 @@ static ssize_t debugcmd_store(struct class_device *class_dev,
if (ret < 0) return ret;
return count;
}
+#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
/*
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index dd207fae4..56d15c10d 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -80,22 +80,6 @@ static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
module_param_array(video_nr, int, NULL, 0444);
MODULE_PARM_DESC(video_nr, "Offset for device's minor");
-#define V4L2_CID_PVR_SRATE (V4L2_CID_PRIVATE_BASE)
-#define V4L2_CID_PVR_AUDIOBITRATE (V4L2_CID_PRIVATE_BASE+1)
-#define V4L2_CID_PVR_AUDIOCRC (V4L2_CID_PRIVATE_BASE+2)
-#define V4L2_CID_PVR_AUDIOEMPHASIS (V4L2_CID_PRIVATE_BASE+3)
-#define V4L2_CID_PVR_VBR (V4L2_CID_PRIVATE_BASE+4)
-#define V4L2_CID_PVR_VIDEOBITRATE (V4L2_CID_PRIVATE_BASE+5)
-#define V4L2_CID_PVR_VIDEOPEAK (V4L2_CID_PRIVATE_BASE+6)
-#define V4L2_CID_PVR_VIDEOSTANDARD (V4L2_CID_PRIVATE_BASE+7)
-#define V4L2_CID_PVR_INPUT (V4L2_CID_PRIVATE_BASE+8)
-#define V4L2_CID_PVR_AUDIOMODE (V4L2_CID_PRIVATE_BASE+9)
-#define V4L2_CID_PVR_FREQUENCY (V4L2_CID_PRIVATE_BASE+10)
-#define V4L2_CID_PVR_HRES (V4L2_CID_PRIVATE_BASE+11)
-#define V4L2_CID_PVR_VRES (V4L2_CID_PRIVATE_BASE+12)
-
-#define V4L2_CID_PVR_MAX (V4L2_CID_PRIVATE_BASE+12)
-
struct v4l2_capability pvr_capability ={
.driver = "pvrusb2",
.card = "Hauppauge WinTV pvr-usb2",
@@ -141,69 +125,6 @@ static struct v4l2_tuner pvr_v4l2_tuners[]= {
#endif
};
-struct v4l2_standard pvr_standards[] = {
- [PVR2_CVAL_VIDEOSTANDARD_PAL_BG] = {
- .id = V4L2_STD_PAL_BG,
- .frameperiod =
- {
- .numerator = 1,
- .denominator= 25
- },
- .framelines = 625,
- .reserved = {0,0,0,0}
- },
- [PVR2_CVAL_VIDEOSTANDARD_PAL_I] = {
- .id = V4L2_STD_PAL_I,
- .frameperiod =
- {
- .numerator = 1,
- .denominator= 25
- },
- .framelines = 625,
- .reserved = {0,0,0,0}
- },
- [PVR2_CVAL_VIDEOSTANDARD_PAL_DK] = {
- .id = V4L2_STD_PAL_DK,
- .frameperiod =
- {
- .numerator = 1,
- .denominator= 25
- },
- .framelines = 625,
- .reserved = {0,0,0,0}
- },
- [PVR2_CVAL_VIDEOSTANDARD_SECAM_L] = {
- .id = V4L2_STD_SECAM,
- .frameperiod =
- {
- .numerator = 1,
- .denominator= 25
- },
- .framelines = 625,
- .reserved = {0,0,0,0}
- },
- [PVR2_CVAL_VIDEOSTANDARD_NTSC_M] = {
- .id = V4L2_STD_NTSC_M,
- .frameperiod =
- {
- .numerator = 1001,
- .denominator= 30000
- },
- .framelines = 525,
- .reserved = {0,0,0,0}
- },
- [PVR2_CVAL_VIDEOSTANDARD_PAL_M] = {
- .id = V4L2_STD_PAL_M,
- .frameperiod =
- {
- .numerator = 1001,
- .denominator= 30000
- },
- .framelines = 525,
- .reserved = {0,0,0,0}
- }
-};
-
struct v4l2_fmtdesc pvr_fmtdesc [] = {
{
.index = 0,
@@ -257,84 +178,6 @@ struct v4l2_format pvr_format [] = {
}
};
-static int cnv_cid_v4l2_pvr2(int id)
-{
- switch (id) {
- case V4L2_CID_BRIGHTNESS:
- return PVR2_CID_BRIGHTNESS;
- case V4L2_CID_SATURATION:
- return PVR2_CID_SATURATION;
- case V4L2_CID_CONTRAST:
- return PVR2_CID_CONTRAST;
- case V4L2_CID_HUE:
- return PVR2_CID_HUE;
- case V4L2_CID_AUDIO_VOLUME:
- return PVR2_CID_VOLUME;
- case V4L2_CID_AUDIO_BALANCE:
- return PVR2_CID_BALANCE;
- case V4L2_CID_AUDIO_BASS:
- return PVR2_CID_BASS;
- case V4L2_CID_AUDIO_TREBLE:
- return PVR2_CID_TREBLE;
- case V4L2_CID_AUDIO_MUTE:
- return PVR2_CID_MUTE;
- case V4L2_CID_PVR_SRATE:
- return PVR2_CID_SRATE;
- case V4L2_CID_PVR_AUDIOBITRATE:
- return PVR2_CID_AUDIOBITRATE;
- case V4L2_CID_PVR_AUDIOCRC:
- return PVR2_CID_AUDIOCRC;
- case V4L2_CID_PVR_AUDIOEMPHASIS:
- return PVR2_CID_AUDIOEMPHASIS;
- case V4L2_CID_PVR_VBR:
- return PVR2_CID_VBR;
- case V4L2_CID_PVR_VIDEOBITRATE:
- return PVR2_CID_AVERAGEVIDEOBITRATE;
- case V4L2_CID_PVR_VIDEOPEAK:
- return PVR2_CID_PEAKVIDEOBITRATE;
- case V4L2_CID_PVR_INPUT:
- return PVR2_CID_INPUT;
- case V4L2_CID_PVR_AUDIOMODE:
- return PVR2_CID_AUDIOMODE;
- case V4L2_CID_PVR_FREQUENCY:
- return PVR2_CID_FREQUENCY;
- case V4L2_CID_PVR_HRES:
- return PVR2_CID_HRES;
- case V4L2_CID_PVR_VRES:
- return PVR2_CID_VRES;
- }
- return -1;
-}
-
-#if 0
-static int cnv_cid_pvr2_v4l2(int id)
-{
- switch (id) {
- case PVR2_CID_BRIGHTNESS:
- return V4L2_CID_BRIGHTNESS;
- case PVR2_CID_SATURATION:
- return V4L2_CID_SATURATION;
- case PVR2_CID_CONTRAST:
- return V4L2_CID_CONTRAST;
- case PVR2_CID_HUE:
- return V4L2_CID_HUE;
- case PVR2_CID_VOLUME:
- return V4L2_CID_AUDIO_VOLUME;
- case PVR2_CID_BALANCE:
- return V4L2_CID_AUDIO_BALANCE;
- case PVR2_CID_BASS:
- return V4L2_CID_AUDIO_BASS;
- case PVR2_CID_TREBLE:
- return V4L2_CID_AUDIO_TREBLE;
- case PVR2_CID_MUTE:
- return V4L2_CID_AUDIO_MUTE;
-
- return id + V4L2_CID_PRIVATE_BASE;
- }
- return -1;
-}
-#endif
-
/*
* pvr_ioctl()
*
@@ -402,22 +245,15 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_ENUMSTD:
{
-
struct v4l2_standard *vs = (struct v4l2_standard *)arg;
+ const struct v4l2_standard *src;
int idx = vs->index;
- if ((vs->index < PVR2_CVAL_VIDEOSTANDARD_MIN) ||
- (vs->index > PVR2_CVAL_VIDEOSTANDARD_MAX)) {
- break;
- }
+ src = pvr2_hdw_get_stdenum_value(hdw,idx);
+ if (!src) break;
- memcpy(vs, &pvr_standards[idx], sizeof(struct v4l2_standard));
+ memcpy(vs, src, sizeof(struct v4l2_standard));
vs->index = idx;
- strlcpy(vs->name,
- pvr2_hdw_get_ctl_value_name(hdw,
- PVR2_CID_VIDEOSTANDARD,
- idx),
- sizeof(vs->name));
ret = 0;
break;
@@ -425,59 +261,37 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_G_STD:
{
+ struct pvr2_ctrl *cptr;
v4l2_std_id *vs = (v4l2_std_id *)arg;
-
- switch (pvr2_hdw_get_ctl_value(hdw,PVR2_CID_VIDEOSTANDARD)) {
- default:
- case PVR2_CVAL_VIDEOSTANDARD_NTSC_M:
- *vs = V4L2_STD_NTSC_M;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_M:
- *vs = V4L2_STD_PAL_M;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_SECAM_L:
- *vs = V4L2_STD_SECAM;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_BG:
- *vs = V4L2_STD_PAL_BG;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_I:
- *vs = V4L2_STD_PAL_I;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_DK:
- *vs = V4L2_STD_PAL_DK;
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_STDCUR);
+ if (!pvr2_ctrl_is_valid(cptr)) {
+ ret = -EINVAL;
break;
}
+
+ *vs = pvr2_ctrl_get_value(cptr);
ret = 0;
break;
}
case VIDIOC_S_STD:
{
+ struct pvr2_ctrl *cptr;
v4l2_std_id *vs = (v4l2_std_id *)arg;
- int val = PVR2_CVAL_VIDEOSTANDARD_NTSC_M;
-
- if (*vs & V4L2_STD_NTSC_M){
- val = PVR2_CVAL_VIDEOSTANDARD_NTSC_M;
- } else if (*vs & V4L2_STD_PAL_BG){
- val = PVR2_CVAL_VIDEOSTANDARD_PAL_BG;
- } else if (*vs & V4L2_STD_PAL_I){
- val = PVR2_CVAL_VIDEOSTANDARD_PAL_I;
- } else if (*vs & V4L2_STD_PAL_DK){
- val = PVR2_CVAL_VIDEOSTANDARD_PAL_DK;
- } else if (*vs & V4L2_STD_SECAM){
- val = PVR2_CVAL_VIDEOSTANDARD_SECAM_L;
- } else if (*vs & V4L2_STD_PAL_M){
- val = PVR2_CVAL_VIDEOSTANDARD_PAL_M;
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_STDCUR);
+ if (!pvr2_ctrl_is_valid(cptr)) {
+ ret = -EINVAL;
+ break;
}
- pvr2_hdw_set_ctl_value(hdw,PVR2_CID_VIDEOSTANDARD,val);
-
+ pvr2_ctrl_set_value(cptr,*vs);
+ ret = 0;
break;
}
case VIDIOC_ENUMINPUT:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_input *vi = (struct v4l2_input *)arg;
struct v4l2_input tmp;
@@ -486,6 +300,8 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
break;
}
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_INPUT);
+
memset(&tmp,0,sizeof(tmp));
tmp.index = vi->index;
switch (vi->index) {
@@ -500,8 +316,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
}
strlcpy(tmp.name,
- pvr2_hdw_get_ctl_value_name(hdw,PVR2_CID_INPUT,
- vi->index),
+ pvr2_ctrl_get_value_name(cptr,vi->index),
sizeof(tmp.name));
/* Don't bother with audioset, since this driver currently
@@ -522,17 +337,31 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_G_INPUT:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_input *vi = (struct v4l2_input *)arg;
- vi->index = pvr2_hdw_get_ctl_value(hdw,PVR2_CID_INPUT);
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_INPUT);
+ if (!pvr2_ctrl_is_valid(cptr)) {
+ ret = -EINVAL;
+ break;
+ }
+
+ vi->index = pvr2_ctrl_get_value(cptr);
ret = 0;
break;
}
case VIDIOC_S_INPUT:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_input *vi = (struct v4l2_input *)arg;
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_INPUT);
+ if (!pvr2_ctrl_is_valid(cptr)) {
+ ret = -EINVAL;
+ break;
+ }
+
ret = 0;
- if (pvr2_hdw_set_ctl_value(hdw,PVR2_CID_INPUT,vi->index)) {
+ if (pvr2_ctrl_set_value(cptr,vi->index)) {
ret = -EINVAL;
}
break;
@@ -557,6 +386,7 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
}
case VIDIOC_G_TUNER:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
unsigned int status_mask;
if (vt->index !=0) break;
@@ -580,26 +410,8 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
vt->signal = 65535;
}
- switch (pvr2_hdw_get_ctl_value(hdw,PVR2_CID_AUDIOMODE)) {
- case PVR2_CVAL_AUDIOMODE_MONO:
- vt->audmode = V4L2_TUNER_MODE_MONO;
- break;
- case PVR2_CVAL_AUDIOMODE_STEREO:
- vt->audmode = V4L2_TUNER_MODE_STEREO;
- break;
- case PVR2_CVAL_AUDIOMODE_LANG1:
- vt->audmode = V4L2_TUNER_MODE_LANG1;
- break;
- case PVR2_CVAL_AUDIOMODE_LANG2:
- vt->audmode = V4L2_TUNER_MODE_LANG2;
- break;
- case PVR2_CVAL_AUDIOMODE_LANG1_LANG2:
- vt->audmode = V4L2_TUNER_MODE_LANG1_LANG2;
- break;
- case PVR2_CVAL_AUDIOMODE_SAP:
- vt->audmode = V4L2_TUNER_MODE_SAP;
- break;
- }
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_AUDIOMODE);
+ vt->audmode = pvr2_ctrl_get_value(cptr);
ret = 0;
break;
@@ -607,40 +419,34 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_S_TUNER:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_tuner *vt=(struct v4l2_tuner *)arg;
- int val = PVR2_CVAL_AUDIOMODE_STEREO;
if (vt->index != 0)
break;
- switch (vt->audmode) {
- case V4L2_TUNER_MODE_MONO:
- val = PVR2_CVAL_AUDIOMODE_MONO;
- break;
- case V4L2_TUNER_MODE_STEREO:
- val = PVR2_CVAL_AUDIOMODE_STEREO;
- break;
- case V4L2_TUNER_MODE_LANG1:
- val = PVR2_CVAL_AUDIOMODE_LANG1;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- val = PVR2_CVAL_AUDIOMODE_LANG1_LANG2;
- break;
- case V4L2_TUNER_MODE_SAP: // Also LANG2
- val = PVR2_CVAL_AUDIOMODE_SAP;
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_AUDIOMODE);
+ if (!pvr2_ctrl_is_valid(cptr)) {
+ ret = -EINVAL;
break;
}
- pvr2_hdw_set_ctl_value(hdw,PVR2_CID_AUDIOMODE,val);
+ pvr2_ctrl_set_value(cptr,vt->audmode);
ret = 0;
}
case VIDIOC_S_FREQUENCY:
{
+ struct pvr2_ctrl *cptr;
const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
- pvr2_hdw_set_ctl_value(hdw,PVR2_CID_FREQUENCY,
- vf->frequency * 62500);
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_FREQUENCY);
+ if (!pvr2_ctrl_is_valid(cptr)) {
+ ret = -EINVAL;
+ break;
+ }
+
+ pvr2_ctrl_set_value(cptr,vf->frequency * 62500);
ret = 0;
break;
@@ -648,10 +454,17 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_G_FREQUENCY:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
int val;
- val = pvr2_hdw_get_ctl_value(hdw,PVR2_CID_FREQUENCY);
+ cptr = pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_FREQUENCY);
+ if (!pvr2_ctrl_is_valid(cptr)) {
+ ret = -EINVAL;
+ break;
+ }
+
+ val = pvr2_ctrl_get_value(cptr);
val /= 62500;
vf->frequency = val;
@@ -682,12 +495,18 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
sizeof(struct v4l2_format));
vf->fmt.pix.width =
- pvr2_hdw_get_ctl_value(hdw,PVR2_CID_HRES);
- if (pvr2_hdw_get_ctl_value(hdw,PVR2_CID_INTERLACE)) {
+ pvr2_ctrl_get_value(
+ pvr2_hdw_get_ctrl(hdw,
+ V4L2_CID_PVR_HRES));
+ if (pvr2_ctrl_get_value(
+ pvr2_hdw_get_ctrl(
+ hdw,V4L2_CID_PVR_INTERLACE))) {
vf->fmt.pix.width /= 2;
}
vf->fmt.pix.height =
- pvr2_hdw_get_ctl_value(hdw,PVR2_CID_VRES);
+ pvr2_ctrl_get_value(
+ pvr2_hdw_get_ctrl(hdw,
+ V4L2_CID_PVR_VRES));
ret = 0;
break;
case V4L2_BUF_TYPE_VBI_CAPTURE:
@@ -713,16 +532,12 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
int w = vf->fmt.pix.width;
int vd_std, hf, hh;
- vd_std = pvr2_hdw_get_ctl_value(hdw,
- PVR2_CID_VIDEOSTANDARD);
- switch (vd_std) {
- case PVR2_CVAL_VIDEOSTANDARD_NTSC_M:
- case PVR2_CVAL_VIDEOSTANDARD_PAL_M:
+ vd_std = pvr2_ctrl_get_value(
+ pvr2_hdw_get_ctrl(hdw,V4L2_CID_PVR_STDCUR));
+ if (vd_std & V4L2_STD_525_60) {
hf=480;
- break;
- default:
+ } else {
hf=576;
- break;
}
hh = (int) (hf / 2);
@@ -734,15 +549,18 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
vf->fmt.pix.height = (h > hh) ? hf : hh;
if (cmd == VIDIOC_S_FMT){
- pvr2_hdw_set_ctl_value(
- hdw,PVR2_CID_HRES,
+ pvr2_ctrl_set_value(
+ pvr2_hdw_get_ctrl(hdw,
+ V4L2_CID_PVR_HRES),
vf->fmt.pix.width);
- pvr2_hdw_set_ctl_value(
- hdw,PVR2_CID_VRES,
+ pvr2_ctrl_set_value(
+ pvr2_hdw_get_ctrl(hdw,
+ V4L2_CID_PVR_VRES),
vf->fmt.pix.height);
- pvr2_hdw_set_ctl_value(
- hdw,PVR2_CID_INTERLACE,
- (vf->fmt.pix.height != hf));
+ pvr2_ctrl_set_value(
+ pvr2_hdw_get_ctrl(
+ hdw,V4L2_CID_PVR_INTERLACE),
+ vf->fmt.pix.height != hf);
}
} break;
case V4L2_BUF_TYPE_VBI_CAPTURE:
@@ -772,22 +590,31 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_QUERYCTRL:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg;
- int pvr2_id = cnv_cid_v4l2_pvr2(vc->id);
- if (pvr2_id < 0) {
+ cptr = pvr2_hdw_get_ctrl(hdw,vc->id);
+
+ if (!pvr2_ctrl_is_valid(cptr)) {
ret = -EINVAL;
break;
}
- if (pvr2_hdw_get_ctl_value_name(hdw,pvr2_id,0)) {
+ switch (pvr2_ctrl_get_type(cptr)) {
+ case PVR2_CTRL_TYPE_ENUM:
vc->type = V4L2_CTRL_TYPE_MENU;
- } else {
+ break;
+ case PVR2_CTRL_TYPE_INT:
vc->type = V4L2_CTRL_TYPE_INTEGER;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
}
- strlcpy(vc->name,pvr2_hdw_get_ctl_name(hdw,pvr2_id),
- sizeof(vc->name));
- vc->minimum = pvr2_hdw_get_ctl_min_value(hdw,pvr2_id);
- vc->maximum = pvr2_hdw_get_ctl_max_value(hdw,pvr2_id);
+
+ strlcpy(vc->name,pvr2_ctrl_get_desc(cptr),sizeof(vc->name));
+ vc->minimum = pvr2_ctrl_get_min_value(cptr);
+ vc->maximum = pvr2_ctrl_get_max_value(cptr);
+ vc->default_value = pvr2_ctrl_get_default_value(cptr);
vc->step = 1;
ret = 0;
break;
@@ -795,16 +622,15 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_QUERYMENU:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_querymenu *vm = (struct v4l2_querymenu *)arg;
- int pvr2_id = cnv_cid_v4l2_pvr2(vm->id);
const char *value_name;
- if (pvr2_id < 0) {
+ cptr = pvr2_hdw_get_ctrl(hdw,vm->id);
+ if (!pvr2_ctrl_is_valid(cptr)) {
ret = -EINVAL;
break;
}
-
- value_name = pvr2_hdw_get_ctl_value_name(hdw,pvr2_id,
- vm->index);
+ value_name = pvr2_ctrl_get_value_name(cptr,vm->index);
if (value_name) {
strlcpy(vm->name,value_name,sizeof(vm->name));
ret = 0;
@@ -817,37 +643,42 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_G_CTRL:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_control *vc = (struct v4l2_control *)arg;
- int pvr2_id;
- pvr2_id = cnv_cid_v4l2_pvr2(vc->id);
- if (pvr2_id < 0) {
+ cptr = pvr2_hdw_get_ctrl(hdw,vc->id);
+ if (!pvr2_ctrl_is_valid(cptr)) {
ret = -EINVAL;
break;
}
ret = 0;
- vc->value = pvr2_hdw_get_ctl_value(hdw,pvr2_id);
+ vc->value = pvr2_ctrl_get_value(cptr);
break;
}
case VIDIOC_S_CTRL:
{
+ struct pvr2_ctrl *cptr;
struct v4l2_control *vc = (struct v4l2_control *)arg;
- int pvr2_id;
- pvr2_id = cnv_cid_v4l2_pvr2(vc->id);
- if (pvr2_id < 0) {
+ cptr = pvr2_hdw_get_ctrl(hdw,vc->id);
+ if (!pvr2_ctrl_is_valid(cptr)) {
ret = -EINVAL;
break;
}
- ret = pvr2_hdw_set_ctl_value(hdw,pvr2_id,vc->value);
+ ret = pvr2_ctrl_set_value(cptr,vc->value);
break;
}
case VIDIOC_LOG_STATUS:
{
+ int nr = pvr2_hdw_get_unit_number(hdw);
+
+ printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
pvr2_hdw_trigger_module_log(hdw);
+ printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
+ ret = 0;
break;
}
diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c
index 8992de807..ea7c7c65b 100644
--- a/linux/drivers/media/video/saa7115.c
+++ b/linux/drivers/media/video/saa7115.c
@@ -83,6 +83,10 @@ struct saa7115_state {
int sat;
enum v4l2_chip_ident ident;
u32 audclk_freq;
+ u32 crystal_freq;
+ u8 ucgc;
+ u8 cgcdiv;
+ u8 apll;
};
/* ----------------------------------------------------------------------- */
@@ -388,10 +392,6 @@ static const unsigned char saa7113_init_auto_input[] = {
#endif
static const unsigned char saa7115_init_misc[] = {
- 0x38, 0x03, /* audio stuff */
- 0x39, 0x10,
- 0x3a, 0x08,
-
0x81, 0x01, /* reg 0x15,0x16 define blanking window */
0x82, 0x00,
0x83, 0x01, /* I port settings */
@@ -597,6 +597,7 @@ static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq)
u32 acni;
u32 hz;
u64 f;
+ u8 acc = 0; /* reg 0x3a, audio clock control */
v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq);
@@ -604,18 +605,34 @@ static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq)
if (freq < 32000 || freq > 48000)
return -EINVAL;
+ /* The saa7113 has no audio clock */
+ if (state->ident == V4L2_IDENT_SAA7113)
+ return 0;
+
/* hz is the refresh rate times 100 */
hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
/* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
acpf = (25600 * freq) / hz;
/* acni = (256 * freq * 2^23) / crystal_frequency =
(freq * 2^(8+23)) / crystal_frequency =
- (freq << 31) / 32.11 MHz */
+ (freq << 31) / crystal_frequency */
f = freq;
f = f << 31;
- do_div(f, 32110000);
+ do_div(f, state->crystal_freq);
acni = f;
+ if (state->ucgc) {
+ acpf = acpf * state->cgcdiv / 16;
+ acni = acni * state->cgcdiv / 16;
+ acc = 0x80;
+ if (state->cgcdiv == 3)
+ acc |= 0x40;
+ }
+ if (state->apll)
+ acc |= 0x08;
+ saa7115_write(client, 0x38, 0x03);
+ saa7115_write(client, 0x39, 0x10);
+ saa7115_write(client, 0x3a, acc);
saa7115_write(client, 0x30, acpf & 0xff);
saa7115_write(client, 0x31, (acpf >> 8) & 0xff);
saa7115_write(client, 0x32, (acpf >> 16) & 0x03);
@@ -865,7 +882,7 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo
case 0:
lcr[i] |= 0xf << (4 * x);
break;
- case V4L2_SLICED_TELETEXT_PAL_B:
+ case V4L2_SLICED_TELETEXT_B:
lcr[i] |= 1 << (4 * x);
break;
case V4L2_SLICED_CAPTION_525:
@@ -894,7 +911,7 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo
static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
{
static u16 lcr2vbi[] = {
- 0, V4L2_SLICED_TELETEXT_PAL_B, 0, /* 1 */
+ 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
0, V4L2_SLICED_CAPTION_525, /* 4 */
V4L2_SLICED_WSS_625, 0, /* 5 */
V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */
@@ -1059,7 +1076,7 @@ static void saa7115_decode_vbi_line(struct i2c_client *client,
/* decode payloads */
switch (id2) {
case 1:
- vbi->type = V4L2_SLICED_TELETEXT_PAL_B;
+ vbi->type = V4L2_SLICED_TELETEXT_B;
break;
case 4:
if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1]))
@@ -1234,34 +1251,6 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
break;
}
- case VIDIOC_G_INPUT:
- *(int *)arg = state->input;
- break;
-
- case VIDIOC_S_INPUT:
- v4l_dbg(1, debug, client, "decoder set input %d\n", *iarg);
- /* inputs from 0-9 are available */
- if (*iarg < 0 || *iarg > 9) {
- return -EINVAL;
- }
-
- if (state->input == *iarg)
- break;
- v4l_dbg(1, debug, client, "now setting %s input\n",
- *iarg >= 6 ? "S-Video" : "Composite");
- state->input = *iarg;
-
- /* select mode */
- saa7115_write(client, 0x02,
- (saa7115_read(client, 0x02) & 0xf0) |
- state->input);
-
- /* bypass chrominance trap for modes 6..9 */
- saa7115_write(client, 0x09,
- (saa7115_read(client, 0x09) & 0x7f) |
- (state->input < 6 ? 0x0 : 0x80));
- break;
-
case VIDIOC_STREAMON:
case VIDIOC_STREAMOFF:
v4l_dbg(1, debug, client, "%s output\n",
@@ -1273,6 +1262,21 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
}
break;
+ case VIDIOC_INT_S_CRYSTAL_FREQ:
+ {
+ struct v4l2_crystal_freq *freq = arg;
+
+ if (freq->freq != SAA7115_FREQ_32_11_MHZ &&
+ freq->freq != SAA7115_FREQ_24_576_MHZ)
+ return -EINVAL;
+ state->crystal_freq = freq->freq;
+ state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
+ state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
+ state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
+ saa7115_set_audio_clock_freq(client, state->audclk_freq);
+ break;
+ }
+
case VIDIOC_INT_DECODE_VBI_LINE:
saa7115_decode_vbi_line(client, arg);
break;
@@ -1422,10 +1426,13 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
v4l_dbg(1, debug, client, "writing init values\n");
/* init to 60hz/48khz */
- if (state->ident == V4L2_IDENT_SAA7113)
+ if (state->ident == V4L2_IDENT_SAA7113) {
+ state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
saa7115_writeregs(client, saa7113_init_auto_input);
- else
+ } else {
+ state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
saa7115_writeregs(client, saa7115_init_auto_input);
+ }
saa7115_writeregs(client, saa7115_init_misc);
saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
diff --git a/linux/drivers/media/video/tea5761.c b/linux/drivers/media/video/tea5761.c
index 785cd105d..a0f075ed7 100644
--- a/linux/drivers/media/video/tea5761.c
+++ b/linux/drivers/media/video/tea5761.c
@@ -4,7 +4,7 @@
*
* $Id: tea5761.c,v 1.5 2006/01/11 21:01:01 hverkuil Exp $
*
- * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
+ * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org)
* This code is placed under the terms of the GNU General Public License
*
*/
diff --git a/linux/drivers/media/video/tea5767.c b/linux/drivers/media/video/tea5767.c
index e8bf32ec1..43fe70fec 100644
--- a/linux/drivers/media/video/tea5767.c
+++ b/linux/drivers/media/video/tea5767.c
@@ -4,7 +4,7 @@
*
* $Id: tea5767.c,v 1.36 2006/01/15 17:04:52 hverkuil Exp $
*
- * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
+ * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org)
* This code is placed under the terms of the GNU General Public License
*
* tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c
index 87581654f..35ba614c0 100644
--- a/linux/drivers/media/video/tuner-core.c
+++ b/linux/drivers/media/video/tuner-core.c
@@ -615,10 +615,16 @@ static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode,
static inline int check_v4l2(struct tuner *t)
{
+ /* bttv still uses both v4l1 and v4l2 calls to the tuner (v4l2 for
+ TV, v4l1 for radio), until that is fixed this code is disabled.
+ Otherwise the radio (v4l1) wouldn't tune after using the TV (v4l2)
+ first. */
+#if 0
if (t->using_v4l2) {
tuner_dbg ("ignore v4l1 call\n");
return EINVAL;
}
+#endif
return 0;
}
@@ -801,6 +807,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
switch_v4l2();
tuner->type = t->mode;
+ if (t->mode == V4L2_TUNER_ANALOG_TV)
+ tuner->capability |= V4L2_TUNER_CAP_NORM;
if (t->mode != V4L2_TUNER_RADIO) {
tuner->rangelow = tv_range[0] * 16;
tuner->rangehigh = tv_range[1] * 16;
diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c
index 8a6c5c0d0..7cafcd52b 100644
--- a/linux/drivers/media/video/tvp5150.c
+++ b/linux/drivers/media/video/tvp5150.c
@@ -11,6 +11,7 @@
#include <linux/delay.h>
#include <linux/video_decoder.h>
#include <media/v4l2-common.h>
+#include <media/tvp5150.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -116,7 +117,7 @@ struct tvp5150 {
struct i2c_client *client;
v4l2_std_id norm; /* Current set standard */
- int input;
+ struct v4l2_routing route;
int enable;
int bright;
int contrast;
@@ -314,29 +315,26 @@ static void dump_reg(struct i2c_client *c)
/****************************************************************************
Basic functions
****************************************************************************/
-enum tvp5150_input {
- TVP5150_ANALOG_CH0 = 0,
- TVP5150_SVIDEO = 1,
- TVP5150_ANALOG_CH1 = 2,
- TVP5150_BLACK_SCREEN = 8
-};
-static inline void tvp5150_selmux(struct i2c_client *c,
- enum tvp5150_input input)
+static inline void tvp5150_selmux(struct i2c_client *c)
{
int opmode=0;
-
struct tvp5150 *decoder = i2c_get_clientdata(c);
+ int input = 0;
- if (!decoder->enable)
- input |= TVP5150_BLACK_SCREEN;
+ if ((decoder->route.output & TVP5150_BLACK_SCREEN) || !decoder->enable)
+ input = 8;
switch (input) {
- case TVP5150_ANALOG_CH0:
- case TVP5150_ANALOG_CH1:
+ case TVP5150_COMPOSITE1:
+ input |= 2;
+ /* fall through */
+ case TVP5150_COMPOSITE0:
opmode=0x30; /* TV Mode */
break;
+ case TVP5150_SVIDEO:
default:
+ input |= 1;
opmode=0; /* Auto Mode */
break;
}
@@ -531,16 +529,21 @@ struct i2c_vbi_ram_value {
static struct i2c_vbi_ram_value vbi_ram_default[] =
{
+ /* FIXME: Current api doesn't handle all VBI types, those not
+ yet supported are placed under #if 0 */
+#if 0 /* keep */
{0x010, /* Teletext, SECAM, WST System A */
{V4L2_SLICED_TELETEXT_SECAM,6,23,1},
{ 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26,
0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 }
},
+#endif
{0x030, /* Teletext, PAL, WST System B */
- {V4L2_SLICED_TELETEXT_PAL_B,6,22,1},
+ {V4L2_SLICED_TELETEXT_B,6,22,1},
{ 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b,
0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 }
},
+#if 0 /* keep */
{0x050, /* Teletext, PAL, WST System C */
{V4L2_SLICED_TELETEXT_PAL_C,6,22,1},
{ 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22,
@@ -566,6 +569,7 @@ static struct i2c_vbi_ram_value vbi_ram_default[] =
{ 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 }
},
+#endif
{0x0f0, /* Closed Caption, NTSC */
{V4L2_SLICED_CAPTION_525,21,21,1},
{ 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
@@ -576,6 +580,7 @@ static struct i2c_vbi_ram_value vbi_ram_default[] =
{ 0x5b, 0x55, 0xc5, 0xff, 0x00, 0x71, 0x6e, 0x42,
0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 }
},
+#if 0 /* keep */
{0x130, /* Wide Screen Signal, NTSC C */
{V4L2_SLICED_WSS_525,20,20,1},
{ 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43,
@@ -591,6 +596,7 @@ static struct i2c_vbi_ram_value vbi_ram_default[] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49,
0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 }
},
+#endif
{0x190, /* Video Program System (VPS), PAL */
{V4L2_SLICED_VPS,16,16,0},
{ 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d,
@@ -831,7 +837,7 @@ static inline void tvp5150_reset(struct i2c_client *c)
tvp5150_vdp_init(c, vbi_ram_default);
/* Selects decoder input */
- tvp5150_selmux(c, decoder->input);
+ tvp5150_selmux(c);
/* Initializes TVP5150 to stream enabled values */
tvp5150_write_inittab(c, tvp5150_init_enable);
@@ -899,9 +905,23 @@ static int tvp5150_command(struct i2c_client *c,
case 0:
case VIDIOC_INT_RESET:
- case DECODER_INIT:
tvp5150_reset(c);
break;
+ case VIDIOC_INT_G_VIDEO_ROUTING:
+ {
+ struct v4l2_routing *route = arg;
+
+ *route = decoder->route;
+ break;
+ }
+ case VIDIOC_INT_S_VIDEO_ROUTING:
+ {
+ struct v4l2_routing *route = arg;
+
+ decoder->route = *route;
+ tvp5150_selmux(c);
+ break;
+ }
case VIDIOC_S_STD:
if (decoder->norm == *(v4l2_std_id *)arg)
break;
@@ -1045,99 +1065,15 @@ static int tvp5150_command(struct i2c_client *c,
#endif
case VIDIOC_LOG_STATUS:
- case DECODER_DUMP:
dump_reg(c);
break;
- case DECODER_GET_CAPABILITIES:
+ case VIDIOC_G_TUNER:
{
- struct video_decoder_capability *cap = arg;
-
- cap->flags = VIDEO_DECODER_PAL |
- VIDEO_DECODER_NTSC |
- VIDEO_DECODER_SECAM |
- VIDEO_DECODER_AUTO | VIDEO_DECODER_CCIR;
- cap->inputs = 3;
- cap->outputs = 1;
- break;
- }
- case DECODER_GET_STATUS:
- {
- int *iarg = arg;
- int status;
- int res=0;
- status = tvp5150_read(c, 0x88);
- if(status&0x08){
- res |= DECODER_STATUS_COLOR;
- }
- if(status&0x04 && status&0x02){
- res |= DECODER_STATUS_GOOD;
- }
- *iarg=res;
- break;
- }
-
- case DECODER_SET_GPIO:
- break;
-
- case DECODER_SET_VBI_BYPASS:
- break;
-
- case DECODER_SET_NORM:
- {
- int *iarg = arg;
-
- switch (*iarg) {
-
- case VIDEO_MODE_NTSC:
- break;
-
- case VIDEO_MODE_PAL:
- break;
-
- case VIDEO_MODE_SECAM:
- break;
-
- case VIDEO_MODE_AUTO:
- break;
-
- default:
- return -EINVAL;
-
- }
- decoder->norm = *iarg;
- break;
- }
- case DECODER_SET_INPUT:
- {
- int *iarg = arg;
- if (*iarg < 0 || *iarg > 3) {
- return -EINVAL;
- }
-
- decoder->input = *iarg;
- tvp5150_selmux(c, decoder->input);
-
- break;
- }
- case DECODER_SET_OUTPUT:
- {
- int *iarg = arg;
-
- /* not much choice of outputs */
- if (*iarg != 0) {
- return -EINVAL;
- }
- break;
- }
- case DECODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
-
- decoder->enable = (*iarg != 0);
-
- tvp5150_selmux(c, decoder->input);
+ struct v4l2_tuner *vt = arg;
+ int status = tvp5150_read(c, 0x88);
+ vt->signal = ((status & 0x04) && (status & 0x02)) ? 0xffff : 0x0;
break;
}
case VIDIOC_QUERYCTRL:
@@ -1183,35 +1119,6 @@ static int tvp5150_command(struct i2c_client *c,
return -EINVAL;
}
- case DECODER_SET_PICTURE:
- {
- struct video_picture *pic = arg;
- if (decoder->bright != pic->brightness) {
- /* We want 0 to 255 we get 0-65535 */
- decoder->bright = pic->brightness;
- tvp5150_write(c, TVP5150_BRIGHT_CTL,
- decoder->bright >> 8);
- }
- if (decoder->contrast != pic->contrast) {
- /* We want 0 to 255 we get 0-65535 */
- decoder->contrast = pic->contrast;
- tvp5150_write(c, TVP5150_CONTRAST_CTL,
- decoder->contrast >> 8);
- }
- if (decoder->sat != pic->colour) {
- /* We want 0 to 255 we get 0-65535 */
- decoder->sat = pic->colour;
- tvp5150_write(c, TVP5150_SATURATION_CTL,
- decoder->contrast >> 8);
- }
- if (decoder->hue != pic->hue) {
- /* We want -128 to 127 we get 0-65535 */
- decoder->hue = pic->hue;
- tvp5150_write(c, TVP5150_HUE_CTL,
- (decoder->hue - 32768) >> 8);
- }
- break;
- }
default:
return -EINVAL;
}
@@ -1273,7 +1180,7 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter,
rv = i2c_attach_client(c);
core->norm = V4L2_STD_ALL; /* Default is autodetect */
- core->input = 2;
+ core->route.input = TVP5150_COMPOSITE1;
core->enable = 1;
core->bright = 32768;
core->contrast = 32768;
diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c
index ae5538212..4b7ef8350 100644
--- a/linux/drivers/media/video/v4l2-common.c
+++ b/linux/drivers/media/video/v4l2-common.c
@@ -337,6 +337,7 @@ static const char *v4l2_int_ioctls[] = {
[_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
[_IOC_NR(TDA9887_SET_CONFIG)] = "TDA9887_SET_CONFIG",
+ [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE",
[_IOC_NR(VIDIOC_INT_S_REGISTER)] = "VIDIOC_INT_S_REGISTER",
[_IOC_NR(VIDIOC_INT_G_REGISTER)] = "VIDIOC_INT_G_REGISTER",
[_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET",
@@ -345,7 +346,13 @@ static const char *v4l2_int_ioctls[] = {
[_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA",
[_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA",
[_IOC_NR(VIDIOC_INT_G_CHIP_IDENT)] = "VIDIOC_INT_G_CHIP_IDENT",
- [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ"
+ [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ",
+ [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY",
+ [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING",
+ [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING",
+ [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING",
+ [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING",
+ [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ"
};
#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
@@ -692,6 +699,12 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg)
printk ("%s: input=0x%x, output=0x%x\n", s, p->input, p->output);
break;
}
+ case VIDIOC_INT_S_CRYSTAL_FREQ:
+ {
+ struct v4l2_crystal_freq *p=arg;
+ printk ("%s: freq=%u, flags=0x%x\n", s, p->freq, p->flags);
+ break;
+ }
case VIDIOC_G_SLICED_VBI_CAP:
{
struct v4l2_sliced_vbi_cap *p=arg;
diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c
index 8747de34a..c6d0825c8 100644
--- a/linux/drivers/media/video/videodev.c
+++ b/linux/drivers/media/video/videodev.c
@@ -111,7 +111,11 @@ static int video_open(struct inode *inode, struct file *file)
unsigned int minor = iminor(inode);
int err = 0;
struct video_device *vfl;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
+ const struct file_operations *old_fops;
+#else
struct file_operations *old_fops;
+#endif
if(minor>=VIDEO_NUM_DEVICES)
return -ENODEV;
diff --git a/linux/include/linux/dvb/dmx.h b/linux/include/linux/dvb/dmx.h
index 2787b8a22..c6a2353c4 100644
--- a/linux/include/linux/dvb/dmx.h
+++ b/linux/include/linux/dvb/dmx.h
@@ -88,20 +88,6 @@ typedef enum
#define DMX_PES_PCR DMX_PES_PCR0
-typedef enum
-{
- DMX_SCRAMBLING_EV,
- DMX_FRONTEND_EV
-} dmx_event_t;
-
-
-typedef enum
-{
- DMX_SCRAMBLING_OFF,
- DMX_SCRAMBLING_ON
-} dmx_scrambling_status_t;
-
-
typedef struct dmx_filter
{
__u8 filter[DMX_FILTER_SIZE];
@@ -132,17 +118,6 @@ struct dmx_pes_filter_params
__u32 flags;
};
-
-struct dmx_event
-{
- dmx_event_t event;
- time_t timeStamp;
- union
- {
- dmx_scrambling_status_t scrambling;
- } u;
-};
-
typedef struct dmx_caps {
__u32 caps;
int num_decoders;
@@ -171,7 +146,6 @@ struct dmx_stc {
#define DMX_SET_FILTER _IOW('o', 43, struct dmx_sct_filter_params)
#define DMX_SET_PES_FILTER _IOW('o', 44, struct dmx_pes_filter_params)
#define DMX_SET_BUFFER_SIZE _IO('o', 45)
-#define DMX_GET_EVENT _IOR('o', 46, struct dmx_event)
#define DMX_GET_PES_PIDS _IOR('o', 47, __u16[5])
#define DMX_GET_CAPS _IOR('o', 48, dmx_caps_t)
#define DMX_SET_SOURCE _IOW('o', 49, dmx_source_t)
diff --git a/linux/include/linux/i2c-id.h b/linux/include/linux/i2c-id.h
index 679b46a6a..c8b81f419 100644
--- a/linux/include/linux/i2c-id.h
+++ b/linux/include/linux/i2c-id.h
@@ -108,6 +108,10 @@
#define I2C_DRIVERID_UPD64083 78 /* upd64083 video processor */
#define I2C_DRIVERID_UPD64031A 79 /* upd64031a video processor */
#define I2C_DRIVERID_SAA717X 80 /* saa717x video encoder */
+#define I2C_DRIVERID_DS1672 81 /* Dallas/Maxim DS1672 RTC */
+#define I2C_DRIVERID_X1205 82 /* Xicor/Intersil X1205 RTC */
+#define I2C_DRIVERID_PCF8563 83 /* Philips PCF8563 RTC */
+#define I2C_DRIVERID_RS5C372 84 /* Ricoh RS5C372 RTC */
#define I2C_DRIVERID_I2CDEV 900
#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */
diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h
index bd2e07390..54b8aca85 100644
--- a/linux/include/linux/videodev2.h
+++ b/linux/include/linux/videodev2.h
@@ -84,7 +84,11 @@ struct video_device
int minor;
/* device ops + callbacks */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
+ const struct file_operations *fops;
+#else
struct file_operations *fops;
+#endif
void (*release)(struct video_device *vfd);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
@@ -998,6 +1002,22 @@ struct v4l2_sliced_vbi_format
/* Teletext World System Teletext
(WST), defined on ITU-R BT.653-2 */
+#define V4L2_SLICED_TELETEXT_B (0x0001)
+/* Video Program System, defined on ETS 300 231*/
+#define V4L2_SLICED_VPS (0x0400)
+/* Closed Caption, defined on EIA-608 */
+#define V4L2_SLICED_CAPTION_525 (0x1000)
+/* Wide Screen System, defined on ITU-R BT1119.1 */
+#define V4L2_SLICED_WSS_625 (0x4000)
+
+#define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525)
+#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625)
+
+#if 0
+/* FIXME: Currently unused defines, needs to be discussed further */
+
+/* Teletext World System Teletext
+ (WST), defined on ITU-R BT.653-2 */
#define V4L2_SLICED_TELETEXT_PAL_B (0x000001)
#define V4L2_SLICED_TELETEXT_PAL_C (0x000002)
#define V4L2_SLICED_TELETEXT_NTSC_B (0x000010)
@@ -1058,6 +1078,7 @@ struct v4l2_sliced_vbi_format
V4L2_SLICED_CAPTION_625 |\
V4L2_SLICED_WSS_625 |\
V4l2_SLICED_VITC_625)
+#endif
struct v4l2_sliced_vbi_cap
{
diff --git a/linux/drivers/media/video/cx2341x.h b/linux/include/media/cx2341x.h
index 7e7dcc072..7e7dcc072 100644
--- a/linux/drivers/media/video/cx2341x.h
+++ b/linux/include/media/cx2341x.h
diff --git a/linux/include/media/msp3400.h b/linux/include/media/msp3400.h
index 0be61a021..6ab854931 100644
--- a/linux/include/media/msp3400.h
+++ b/linux/include/media/msp3400.h
@@ -80,16 +80,16 @@
*/
/* SCART input to DSP selection */
-#define MSP_IN_SCART_1 0 /* Pin SC1_IN */
-#define MSP_IN_SCART_2 1 /* Pin SC2_IN */
-#define MSP_IN_SCART_3 2 /* Pin SC3_IN */
-#define MSP_IN_SCART_4 3 /* Pin SC4_IN */
+#define MSP_IN_SCART1 0 /* Pin SC1_IN */
+#define MSP_IN_SCART2 1 /* Pin SC2_IN */
+#define MSP_IN_SCART3 2 /* Pin SC3_IN */
+#define MSP_IN_SCART4 3 /* Pin SC4_IN */
#define MSP_IN_MONO 6 /* Pin MONO_IN */
#define MSP_IN_MUTE 7 /* Mute DSP input */
#define MSP_SCART_TO_DSP(in) (in)
/* Tuner input to demodulator and DSP selection */
-#define MSP_IN_TUNER_1 0 /* Analog Sound IF input pin ANA_IN1 */
-#define MSP_IN_TUNER_2 1 /* Analog Sound IF input pin ANA_IN2 */
+#define MSP_IN_TUNER1 0 /* Analog Sound IF input pin ANA_IN1 */
+#define MSP_IN_TUNER2 1 /* Analog Sound IF input pin ANA_IN2 */
#define MSP_TUNER_TO_DSP(in) ((in) << 3)
/* The msp has up to 5 DSP outputs, each output can independently select
@@ -109,14 +109,14 @@
DSP. This is currently not implemented. Also not implemented is the
multi-channel capable I2S3 input of the 44x0G. If someone can demonstrate
a need for one of those features then additional support can be added. */
-#define MSP_DSP_OUT_TUNER 0 /* Tuner output */
-#define MSP_DSP_OUT_SCART 2 /* SCART output */
-#define MSP_DSP_OUT_I2S1 5 /* I2S1 output */
-#define MSP_DSP_OUT_I2S2 6 /* I2S2 output */
-#define MSP_DSP_OUT_I2S3 7 /* I2S3 output */
-#define MSP_DSP_OUT_MAIN_AVC 11 /* MAIN AVC processed output */
-#define MSP_DSP_OUT_MAIN 12 /* MAIN output */
-#define MSP_DSP_OUT_AUX 13 /* AUX output */
+#define MSP_DSP_IN_TUNER 0 /* Tuner DSP input */
+#define MSP_DSP_IN_SCART 2 /* SCART DSP input */
+#define MSP_DSP_IN_I2S1 5 /* I2S1 DSP input */
+#define MSP_DSP_IN_I2S2 6 /* I2S2 DSP input */
+#define MSP_DSP_IN_I2S3 7 /* I2S3 DSP input */
+#define MSP_DSP_IN_MAIN_AVC 11 /* MAIN AVC processed DSP input */
+#define MSP_DSP_IN_MAIN 12 /* MAIN DSP input */
+#define MSP_DSP_IN_AUX 13 /* AUX DSP input */
#define MSP_DSP_TO_MAIN(in) ((in) << 4)
#define MSP_DSP_TO_AUX(in) ((in) << 8)
#define MSP_DSP_TO_SCART1(in) ((in) << 12)
@@ -125,16 +125,16 @@
/* Output SCART select: the SCART outputs can select which input
to use. */
-#define MSP_OUT_SCART1 0 /* SCART1 input, bypassing the DSP */
-#define MSP_OUT_SCART2 1 /* SCART2 input, bypassing the DSP */
-#define MSP_OUT_SCART3 2 /* SCART3 input, bypassing the DSP */
-#define MSP_OUT_SCART4 3 /* SCART4 input, bypassing the DSP */
-#define MSP_OUT_SCART1_DA 4 /* DSP SCART1 output */
-#define MSP_OUT_SCART2_DA 5 /* DSP SCART2 output */
-#define MSP_OUT_MONO 6 /* MONO input, bypassing the DSP */
-#define MSP_OUT_MUTE 7 /* MUTE output */
-#define MSP_OUT_TO_SCART1(in) (in)
-#define MSP_OUT_TO_SCART2(in) ((in) << 4)
+#define MSP_SC_IN_SCART1 0 /* SCART1 input, bypassing the DSP */
+#define MSP_SC_IN_SCART2 1 /* SCART2 input, bypassing the DSP */
+#define MSP_SC_IN_SCART3 2 /* SCART3 input, bypassing the DSP */
+#define MSP_SC_IN_SCART4 3 /* SCART4 input, bypassing the DSP */
+#define MSP_SC_IN_DSP_SCART1 4 /* DSP SCART1 input */
+#define MSP_SC_IN_DSP_SCART2 5 /* DSP SCART2 input */
+#define MSP_SC_IN_MONO 6 /* MONO input, bypassing the DSP */
+#define MSP_SC_IN_MUTE 7 /* MUTE output */
+#define MSP_SC_TO_SCART1(in) (in)
+#define MSP_SC_TO_SCART2(in) ((in) << 4)
/* Shortcut macros */
#define MSP_INPUT(sc, t, main_aux_src, sc_i2s_src) \
@@ -145,14 +145,14 @@
MSP_DSP_TO_SCART1(sc_i2s_src) | \
MSP_DSP_TO_SCART2(sc_i2s_src) | \
MSP_DSP_TO_I2S(sc_i2s_src))
-#define MSP_INPUT_DEFAULT MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1, \
- MSP_DSP_OUT_TUNER, MSP_DSP_OUT_TUNER)
+#define MSP_INPUT_DEFAULT MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, \
+ MSP_DSP_IN_TUNER, MSP_DSP_IN_TUNER)
#define MSP_OUTPUT(sc) \
- (MSP_OUT_TO_SCART1(sc) | \
- MSP_OUT_TO_SCART2(sc))
+ (MSP_SC_TO_SCART1(sc) | \
+ MSP_SC_TO_SCART2(sc))
/* This equals the RESET position of the msp3400 ACB register */
-#define MSP_OUTPUT_DEFAULT (MSP_OUT_TO_SCART1(MSP_OUT_SCART3) | \
- MSP_OUT_TO_SCART2(MSP_OUT_SCART1_DA))
+#define MSP_OUTPUT_DEFAULT (MSP_SC_TO_SCART1(MSP_SC_IN_SCART3) | \
+ MSP_SC_TO_SCART2(MSP_SC_IN_DSP_SCART1))
/* Tuner inputs vs. msp version */
/* Chip TUNER_1 TUNER_2
diff --git a/linux/include/media/saa7115.h b/linux/include/media/saa7115.h
index 6b4836f3f..9f0e2285a 100644
--- a/linux/include/media/saa7115.h
+++ b/linux/include/media/saa7115.h
@@ -1,5 +1,5 @@
/*
- saa7115.h - definition for saa7113/4/5 inputs
+ saa7115.h - definition for saa7113/4/5 inputs and frequency flags
Copyright (C) 2006 Hans Verkuil (hverkuil@xs4all.nl)
@@ -33,5 +33,14 @@
#define SAA7115_SVIDEO2 8
#define SAA7115_SVIDEO3 9
+/* SAA7115 v4l2_crystal_freq frequency values */
+#define SAA7115_FREQ_32_11_MHZ 32110000 /* 32.11 MHz crystal, SAA7114/5 only */
+#define SAA7115_FREQ_24_576_MHZ 24576000 /* 24.576 MHz crystal */
+
+/* SAA7115 v4l2_crystal_freq audio clock control flags */
+#define SAA7115_FREQ_FL_UCGC (1 << 0) /* SA 3A[7], UCGC, SAA7115 only */
+#define SAA7115_FREQ_FL_CGCDIV (1 << 1) /* SA 3A[6], CGCDIV, SAA7115 only */
+#define SAA7115_FREQ_FL_APLL (1 << 2) /* SA 3A[3], APLL, SAA7114/5 only */
+
#endif
diff --git a/linux/include/media/tvp5150.h b/linux/include/media/tvp5150.h
new file mode 100644
index 000000000..72bd2a2b8
--- /dev/null
+++ b/linux/include/media/tvp5150.h
@@ -0,0 +1,34 @@
+/*
+ tvp5150.h - definition for tvp5150 inputs
+
+ Copyright (C) 2006 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.
+*/
+
+#ifndef _TVP5150_H_
+#define _TVP5150_H_
+
+/* TVP5150 HW inputs */
+#define TVP5150_COMPOSITE0 0
+#define TVP5150_COMPOSITE1 1
+#define TVP5150_SVIDEO 2
+
+/* TVP5150 HW outputs */
+#define TVP5150_NORMAL 0
+#define TVP5150_BLACK_SCREEN 1
+
+#endif
+
diff --git a/linux/include/media/v4l2-common.h b/linux/include/media/v4l2-common.h
index 60c0bc91e..6ffa8eabb 100644
--- a/linux/include/media/v4l2-common.h
+++ b/linux/include/media/v4l2-common.h
@@ -217,4 +217,15 @@ struct v4l2_routing {
#define VIDIOC_INT_S_VIDEO_ROUTING _IOW ('d', 111, struct v4l2_routing)
#define VIDIOC_INT_G_VIDEO_ROUTING _IOR ('d', 112, struct v4l2_routing)
+struct v4l2_crystal_freq {
+ u32 freq; /* frequency in Hz of the crystal */
+ u32 flags; /* device specific flags */
+};
+
+/* Sets the frequency of the crystal used to generate the clocks.
+ An extra flags field allows device specific configuration regarding
+ clock frequency dividers, etc. If not used, then set flags to 0.
+ If the frequency is not supported, then -EINVAL is returned. */
+#define VIDIOC_INT_S_CRYSTAL_FREQ _IOW ('d', 113, struct v4l2_crystal_freq)
+
#endif /* V4L2_COMMON_H_ */