Commit b45009b0 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab Committed by Linus Torvalds

[PATCH] v4l: CX88 cards update

This patch adds support for various CX88 cards and allows specifying
card addresses.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@brturbo.com.br>
Signed-off-by: default avatarMichael Krufky <mkrufky@m1k.net>
Signed-off-by: default avatarcybercide@f2s.com <cybercide@f2s.com>
Signed-off-by: default avatarCatalin Climov <catalin@climov.com>
Signed-off-by: default avatarNickolay V Shmyrev <nshmyrev@yandex.ru>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 2d03e289
This diff is collapsed.
This diff is collapsed.
/* /*
* $Id: cx88-core.c,v 1.24 2005/01/19 12:01:55 kraxel Exp $ * $Id: cx88-core.c,v 1.28 2005/06/12 04:19:19 mchehab Exp $
* *
* device driver for Conexant 2388x based TV cards * device driver for Conexant 2388x based TV cards
* driver core * driver core
...@@ -51,12 +51,15 @@ module_param(latency,int,0444); ...@@ -51,12 +51,15 @@ module_param(latency,int,0444);
MODULE_PARM_DESC(latency,"pci latency timer"); MODULE_PARM_DESC(latency,"pci latency timer");
static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
module_param_array(tuner, int, NULL, 0444); module_param_array(tuner, int, NULL, 0444);
module_param_array(radio, int, NULL, 0444);
module_param_array(card, int, NULL, 0444); module_param_array(card, int, NULL, 0444);
MODULE_PARM_DESC(tuner,"tuner type"); MODULE_PARM_DESC(tuner,"tuner type");
MODULE_PARM_DESC(radio,"radio tuner type");
MODULE_PARM_DESC(card,"card type"); MODULE_PARM_DESC(card,"card type");
static unsigned int nicam = 0; static unsigned int nicam = 0;
...@@ -429,7 +432,7 @@ int cx88_sram_channel_setup(struct cx88_core *core, ...@@ -429,7 +432,7 @@ int cx88_sram_channel_setup(struct cx88_core *core,
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* debug helper code */ /* debug helper code */
static int cx88_risc_decode(u32 risc) int cx88_risc_decode(u32 risc)
{ {
static char *instr[16] = { static char *instr[16] = {
[ RISC_SYNC >> 28 ] = "sync", [ RISC_SYNC >> 28 ] = "sync",
...@@ -1173,8 +1176,20 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci) ...@@ -1173,8 +1176,20 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
"insmod option" : "autodetected"); "insmod option" : "autodetected");
core->tuner_type = tuner[core->nr]; core->tuner_type = tuner[core->nr];
core->radio_type = radio[core->nr];
if (UNSET == core->tuner_type) if (UNSET == core->tuner_type)
core->tuner_type = cx88_boards[core->board].tuner_type; core->tuner_type = cx88_boards[core->board].tuner_type;
if (UNSET == core->radio_type)
core->radio_type = cx88_boards[core->board].radio_type;
if (!core->tuner_addr)
core->tuner_addr = cx88_boards[core->board].tuner_addr;
if (!core->radio_addr)
core->radio_addr = cx88_boards[core->board].radio_addr;
printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n",
core->tuner_type, core->tuner_addr<<1,
core->radio_type, core->radio_addr<<1);
core->tda9887_conf = cx88_boards[core->board].tda9887_conf; core->tda9887_conf = cx88_boards[core->board].tda9887_conf;
/* init hardware */ /* init hardware */
......
/* /*
* $Id: cx88-dvb.c,v 1.31 2005/03/07 15:58:05 kraxel Exp $ * $Id: cx88-dvb.c,v 1.33 2005/06/12 04:19:19 mchehab Exp $
* *
* device driver for Conexant 2388x based TV cards * device driver for Conexant 2388x based TV cards
* MPEG Transport Stream (DVB) routines * MPEG Transport Stream (DVB) routines
......
/* /*
$Id: cx88-i2c.c,v 1.20 2005/02/15 15:59:35 kraxel Exp $ $Id: cx88-i2c.c,v 1.23 2005/06/12 04:19:19 mchehab Exp $
cx88-i2c.c -- all the i2c code is here cx88-i2c.c -- all the i2c code is here
...@@ -91,6 +91,7 @@ static int cx8800_bit_getsda(void *data) ...@@ -91,6 +91,7 @@ static int cx8800_bit_getsda(void *data)
static int attach_inform(struct i2c_client *client) static int attach_inform(struct i2c_client *client)
{ {
struct tuner_addr tun_addr;
struct cx88_core *core = i2c_get_adapdata(client->adapter); struct cx88_core *core = i2c_get_adapdata(client->adapter);
dprintk(1, "i2c attach [addr=0x%x,client=%s]\n", dprintk(1, "i2c attach [addr=0x%x,client=%s]\n",
...@@ -98,8 +99,19 @@ static int attach_inform(struct i2c_client *client) ...@@ -98,8 +99,19 @@ static int attach_inform(struct i2c_client *client)
if (!client->driver->command) if (!client->driver->command)
return 0; return 0;
if (core->tuner_type != UNSET) if (core->radio_type != UNSET) {
client->driver->command(client, TUNER_SET_TYPE, &core->tuner_type); tun_addr.v4l2_tuner = V4L2_TUNER_RADIO;
tun_addr.type = core->radio_type;
tun_addr.addr = core->radio_addr;
client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_addr);
}
if (core->tuner_type != UNSET) {
tun_addr.v4l2_tuner = V4L2_TUNER_ANALOG_TV;
tun_addr.type = core->tuner_type;
tun_addr.addr = core->tuner_addr;
client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_addr);
}
if (core->tda9887_conf) if (core->tda9887_conf)
client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf); client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf);
return 0; return 0;
......
/* /*
* $Id: cx88-input.c,v 1.9 2005/03/04 09:12:23 kraxel Exp $ * $Id: cx88-input.c,v 1.11 2005/05/22 20:57:56 nsh Exp $
* *
* Device driver for GPIO attached remote control interfaces * Device driver for GPIO attached remote control interfaces
* on Conexant 2388x based TV/DVB cards. * on Conexant 2388x based TV/DVB cards.
...@@ -235,6 +235,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ...@@ -235,6 +235,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
/* detect & configure */ /* detect & configure */
switch (core->board) { switch (core->board) {
case CX88_BOARD_DNTV_LIVE_DVB_T: case CX88_BOARD_DNTV_LIVE_DVB_T:
case CX88_BOARD_KWORLD_DVB_T:
ir_codes = ir_codes_dntv_live_dvb_t; ir_codes = ir_codes_dntv_live_dvb_t;
ir->gpio_addr = MO_GP1_IO; ir->gpio_addr = MO_GP1_IO;
ir->mask_keycode = 0x1f; ir->mask_keycode = 0x1f;
...@@ -269,6 +270,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ...@@ -269,6 +270,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
ir->polling = 1; // ms ir->polling = 1; // ms
break; break;
} }
if (NULL == ir_codes) { if (NULL == ir_codes) {
kfree(ir); kfree(ir);
return -ENODEV; return -ENODEV;
......
/* /*
* $Id: cx88-mpeg.c,v 1.25 2005/03/07 14:18:00 kraxel Exp $ * $Id: cx88-mpeg.c,v 1.26 2005/06/03 13:31:51 mchehab Exp $
* *
* Support for the mpeg transport stream transfers * Support for the mpeg transport stream transfers
* PCI function #2 of the cx2388x. * PCI function #2 of the cx2388x.
...@@ -55,7 +55,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev, ...@@ -55,7 +55,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
{ {
struct cx88_core *core = dev->core; struct cx88_core *core = dev->core;
dprintk(1, "cx8802_start_mpegport_dma %d\n", buf->vb.width); dprintk(0, "cx8802_start_dma %d\n", buf->vb.width);
/* setup fifo + format */ /* setup fifo + format */
cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
...@@ -100,18 +100,21 @@ static int cx8802_start_dma(struct cx8802_dev *dev, ...@@ -100,18 +100,21 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
q->count = 1; q->count = 1;
/* enable irqs */ /* enable irqs */
dprintk( 0, "setting the interrupt mask\n" );
cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04); cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04);
cx_write(MO_TS_INTMSK, 0x1f0011); cx_set(MO_TS_INTMSK, 0x1f0011);
//cx_write(MO_TS_INTMSK, 0x0f0011);
/* start dma */ /* start dma */
cx_write(MO_DEV_CNTRL2, (1<<5)); /* FIXME: s/write/set/ ??? */ cx_set(MO_DEV_CNTRL2, (1<<5));
cx_write(MO_TS_DMACNTRL, 0x11); cx_set(MO_TS_DMACNTRL, 0x11);
return 0; return 0;
} }
static int cx8802_stop_dma(struct cx8802_dev *dev) static int cx8802_stop_dma(struct cx8802_dev *dev)
{ {
struct cx88_core *core = dev->core; struct cx88_core *core = dev->core;
dprintk( 0, "cx8802_stop_dma\n" );
/* stop dma */ /* stop dma */
cx_clear(MO_TS_DMACNTRL, 0x11); cx_clear(MO_TS_DMACNTRL, 0x11);
...@@ -131,8 +134,12 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, ...@@ -131,8 +134,12 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
struct cx88_buffer *buf; struct cx88_buffer *buf;
struct list_head *item; struct list_head *item;
dprintk( 0, "cx8802_restart_queue\n" );
if (list_empty(&q->active)) if (list_empty(&q->active))
{
dprintk( 0, "cx8802_restart_queue: queue is empty\n" );
return 0; return 0;
}
buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
dprintk(2,"restart_queue [%p/%d]: restart dma\n", dprintk(2,"restart_queue [%p/%d]: restart dma\n",
...@@ -182,27 +189,32 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) ...@@ -182,27 +189,32 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
struct cx88_buffer *prev; struct cx88_buffer *prev;
struct cx88_dmaqueue *q = &dev->mpegq; struct cx88_dmaqueue *q = &dev->mpegq;
dprintk( 1, "cx8802_buf_queue\n" );
/* add jump to stopper */ /* add jump to stopper */
buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
if (list_empty(&q->active)) { if (list_empty(&q->active)) {
dprintk( 0, "queue is empty - first active\n" );
list_add_tail(&buf->vb.queue,&q->active); list_add_tail(&buf->vb.queue,&q->active);
cx8802_start_dma(dev, q, buf); cx8802_start_dma(dev, q, buf);
buf->vb.state = STATE_ACTIVE; buf->vb.state = STATE_ACTIVE;
buf->count = q->count++; buf->count = q->count++;
mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
dprintk(2,"[%p/%d] %s - first active\n", dprintk(0,"[%p/%d] %s - first active\n",
buf, buf->vb.i, __FUNCTION__); buf, buf->vb.i, __FUNCTION__);
//udelay(100);
} else { } else {
dprintk( 1, "queue is not empty - append to active\n" );
prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue); prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
list_add_tail(&buf->vb.queue,&q->active); list_add_tail(&buf->vb.queue,&q->active);
buf->vb.state = STATE_ACTIVE; buf->vb.state = STATE_ACTIVE;
buf->count = q->count++; buf->count = q->count++;
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
dprintk(2,"[%p/%d] %s - append to active\n", dprintk( 1, "[%p/%d] %s - append to active\n",
buf, buf->vb.i, __FUNCTION__); buf, buf->vb.i, __FUNCTION__);
//udelay(100);
} }
} }
...@@ -224,7 +236,10 @@ static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart) ...@@ -224,7 +236,10 @@ static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart)
buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
} }
if (restart) if (restart)
{
dprintk(0, "restarting queue\n" );
cx8802_restart_queue(dev,q); cx8802_restart_queue(dev,q);
}
spin_unlock_irqrestore(&dev->slock,flags); spin_unlock_irqrestore(&dev->slock,flags);
} }
...@@ -232,6 +247,7 @@ void cx8802_cancel_buffers(struct cx8802_dev *dev) ...@@ -232,6 +247,7 @@ void cx8802_cancel_buffers(struct cx8802_dev *dev)
{ {
struct cx88_dmaqueue *q = &dev->mpegq; struct cx88_dmaqueue *q = &dev->mpegq;
dprintk( 1, "cx8802_cancel_buffers" );
del_timer_sync(&q->timeout); del_timer_sync(&q->timeout);
cx8802_stop_dma(dev); cx8802_stop_dma(dev);
do_cancel_buffers(dev,"cancel",0); do_cancel_buffers(dev,"cancel",0);
...@@ -241,7 +257,7 @@ static void cx8802_timeout(unsigned long data) ...@@ -241,7 +257,7 @@ static void cx8802_timeout(unsigned long data)
{ {
struct cx8802_dev *dev = (struct cx8802_dev*)data; struct cx8802_dev *dev = (struct cx8802_dev*)data;
dprintk(1, "%s\n",__FUNCTION__); dprintk(0, "%s\n",__FUNCTION__);
if (debug) if (debug)
cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]); cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
...@@ -254,12 +270,17 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) ...@@ -254,12 +270,17 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
struct cx88_core *core = dev->core; struct cx88_core *core = dev->core;
u32 status, mask, count; u32 status, mask, count;
dprintk( 1, "cx8802_mpeg_irq\n" );
status = cx_read(MO_TS_INTSTAT); status = cx_read(MO_TS_INTSTAT);
mask = cx_read(MO_TS_INTMSK); mask = cx_read(MO_TS_INTMSK);
if (0 == (status & mask)) if (0 == (status & mask))
return; return;
cx_write(MO_TS_INTSTAT, status); cx_write(MO_TS_INTSTAT, status);
#if 0
cx88_print_irqbits(core->name, "irq mpeg ",
cx88_mpeg_irqs, status, mask);
#endif
if (debug || (status & mask & ~0xff)) if (debug || (status & mask & ~0xff))
cx88_print_irqbits(core->name, "irq mpeg ", cx88_print_irqbits(core->name, "irq mpeg ",
cx88_mpeg_irqs, status, mask); cx88_mpeg_irqs, status, mask);
...@@ -273,6 +294,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) ...@@ -273,6 +294,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
/* risc1 y */ /* risc1 y */
if (status & 0x01) { if (status & 0x01) {
dprintk( 1, "wake up\n" );
spin_lock(&dev->slock); spin_lock(&dev->slock);
count = cx_read(MO_TS_GPCNT); count = cx_read(MO_TS_GPCNT);
cx88_wakeup(dev->core, &dev->mpegq, count); cx88_wakeup(dev->core, &dev->mpegq, count);
...@@ -288,6 +310,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) ...@@ -288,6 +310,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
/* other general errors */ /* other general errors */
if (status & 0x1f0100) { if (status & 0x1f0100) {
dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 );
spin_lock(&dev->slock); spin_lock(&dev->slock);
cx8802_stop_dma(dev); cx8802_stop_dma(dev);
cx8802_restart_queue(dev,&dev->mpegq); cx8802_restart_queue(dev,&dev->mpegq);
...@@ -295,6 +318,8 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) ...@@ -295,6 +318,8 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
} }
} }
#define MAX_IRQ_LOOP 10
static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct cx8802_dev *dev = dev_id; struct cx8802_dev *dev = dev_id;
...@@ -302,10 +327,13 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -302,10 +327,13 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
u32 status; u32 status;
int loop, handled = 0; int loop, handled = 0;
for (loop = 0; loop < 10; loop++) { for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04); status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04);
if (0 == status) if (0 == status)
goto out; goto out;
dprintk( 1, "cx8802_irq\n" );
dprintk( 1, " loop: %d/%d\n", loop, MAX_IRQ_LOOP );
dprintk( 1, " status: %d\n", status );
handled = 1; handled = 1;
cx_write(MO_PCI_INTSTAT, status); cx_write(MO_PCI_INTSTAT, status);
...@@ -314,7 +342,8 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -314,7 +342,8 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
if (status & 0x04) if (status & 0x04)
cx8802_mpeg_irq(dev); cx8802_mpeg_irq(dev);
}; };
if (10 == loop) { if (MAX_IRQ_LOOP == loop) {
dprintk( 0, "clearing mask\n" );
printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n", printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",
core->name); core->name);
cx_write(MO_PCI_INTMSK,0); cx_write(MO_PCI_INTMSK,0);
...@@ -378,6 +407,7 @@ int cx8802_init_common(struct cx8802_dev *dev) ...@@ -378,6 +407,7 @@ int cx8802_init_common(struct cx8802_dev *dev)
void cx8802_fini_common(struct cx8802_dev *dev) void cx8802_fini_common(struct cx8802_dev *dev)
{ {
dprintk( 2, "cx8802_fini_common\n" );
cx8802_stop_dma(dev); cx8802_stop_dma(dev);
pci_disable_device(dev->pci); pci_disable_device(dev->pci);
...@@ -399,6 +429,7 @@ int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) ...@@ -399,6 +429,7 @@ int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
/* stop mpeg dma */ /* stop mpeg dma */
spin_lock(&dev->slock); spin_lock(&dev->slock);
if (!list_empty(&dev->mpegq.active)) { if (!list_empty(&dev->mpegq.active)) {
dprintk( 2, "suspend\n" );
printk("%s: suspend mpeg\n", core->name); printk("%s: suspend mpeg\n", core->name);
cx8802_stop_dma(dev); cx8802_stop_dma(dev);
del_timer(&dev->mpegq.timeout); del_timer(&dev->mpegq.timeout);
...@@ -463,4 +494,5 @@ EXPORT_SYMBOL(cx8802_resume_common); ...@@ -463,4 +494,5 @@ EXPORT_SYMBOL(cx8802_resume_common);
* Local variables: * Local variables:
* c-basic-offset: 8 * c-basic-offset: 8
* End: * End:
* kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
*/ */
/* /*
$Id: cx88-reg.h,v 1.6 2004/10/13 10:39:00 kraxel Exp $ $Id: cx88-reg.h,v 1.7 2005/06/03 13:31:51 mchehab Exp $
cx88x-hw.h - CX2388x register offsets cx88x-hw.h - CX2388x register offsets
...@@ -397,6 +397,7 @@ ...@@ -397,6 +397,7 @@
#define AUD_RATE_ADJ4 0x3205e4 #define AUD_RATE_ADJ4 0x3205e4
#define AUD_RATE_ADJ5 0x3205e8 #define AUD_RATE_ADJ5 0x3205e8
#define AUD_APB_IN_RATE_ADJ 0x3205ec #define AUD_APB_IN_RATE_ADJ 0x3205ec
#define AUD_I2SCNTL 0x3205ec
#define AUD_PHASE_FIX_CTL 0x3205f0 #define AUD_PHASE_FIX_CTL 0x3205f0
#define AUD_PLL_PRESCALE 0x320600 #define AUD_PLL_PRESCALE 0x320600
#define AUD_PLL_DDS 0x320604 #define AUD_PLL_DDS 0x320604
......
/* /*
$Id: cx88-tvaudio.c,v 1.34 2005/03/07 16:10:51 kraxel Exp $ $Id: cx88-tvaudio.c,v 1.36 2005/06/05 05:53:45 mchehab Exp $
cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver
...@@ -127,7 +127,8 @@ static void set_audio_start(struct cx88_core *core, ...@@ -127,7 +127,8 @@ static void set_audio_start(struct cx88_core *core,
cx_write(AUD_VOL_CTL, (1 << 6)); cx_write(AUD_VOL_CTL, (1 << 6));
// increase level of input by 12dB // increase level of input by 12dB
cx_write(AUD_AFE_12DB_EN, 0x0001); // cx_write(AUD_AFE_12DB_EN, 0x0001);
cx_write(AUD_AFE_12DB_EN, 0x0000);
// start programming // start programming
cx_write(AUD_CTL, 0x0000); cx_write(AUD_CTL, 0x0000);
...@@ -143,9 +144,15 @@ static void set_audio_finish(struct cx88_core *core) ...@@ -143,9 +144,15 @@ static void set_audio_finish(struct cx88_core *core)
u32 volume; u32 volume;
if (cx88_boards[core->board].blackbird) { if (cx88_boards[core->board].blackbird) {
// sets sound input from external adc
cx_set(AUD_CTL, EN_I2SIN_ENABLE);
//cx_write(AUD_I2SINPUTCNTL, 0);
cx_write(AUD_I2SINPUTCNTL, 4);
cx_write(AUD_BAUDRATE, 1);
// 'pass-thru mode': this enables the i2s output to the mpeg encoder // 'pass-thru mode': this enables the i2s output to the mpeg encoder
cx_set(AUD_CTL, 0x2000); cx_set(AUD_CTL, EN_I2SOUT_ENABLE);
cx_write(AUD_I2SOUTPUTCNTL, 1); cx_write(AUD_I2SOUTPUTCNTL, 1);
cx_write(AUD_I2SCNTL, 0);
//cx_write(AUD_APB_IN_RATE_ADJ, 0); //cx_write(AUD_APB_IN_RATE_ADJ, 0);
} }
...@@ -707,50 +714,65 @@ static void set_audio_standard_EIAJ(struct cx88_core *core) ...@@ -707,50 +714,65 @@ static void set_audio_standard_EIAJ(struct cx88_core *core)
set_audio_finish(core); set_audio_finish(core);
} }
static void set_audio_standard_FM(struct cx88_core *core) static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph)
{ {
#if 0 /* FIXME */ static const struct rlist fm_deemph_50[] = {
switch (dev->audio_properties.FM_deemphasis) { AUD_DEEMPH0_G0, 0x0C45 },
{ { AUD_DEEMPH0_A0, 0x6262 },
case WW_FM_DEEMPH_50: { AUD_DEEMPH0_B0, 0x1C29 },
//Set De-emphasis filter coefficients for 50 usec { AUD_DEEMPH0_A1, 0x3FC66},
cx_write(AUD_DEEMPH0_G0, 0x0C45); { AUD_DEEMPH0_B1, 0x399A },
cx_write(AUD_DEEMPH0_A0, 0x6262);
cx_write(AUD_DEEMPH0_B0, 0x1C29); { AUD_DEEMPH1_G0, 0x0D80 },
cx_write(AUD_DEEMPH0_A1, 0x3FC66); { AUD_DEEMPH1_A0, 0x6262 },
cx_write(AUD_DEEMPH0_B1, 0x399A); { AUD_DEEMPH1_B0, 0x1C29 },
{ AUD_DEEMPH1_A1, 0x3FC66},
cx_write(AUD_DEEMPH1_G0, 0x0D80); { AUD_DEEMPH1_B1, 0x399A},
cx_write(AUD_DEEMPH1_A0, 0x6262);
cx_write(AUD_DEEMPH1_B0, 0x1C29); { AUD_POLYPH80SCALEFAC, 0x0003},
cx_write(AUD_DEEMPH1_A1, 0x3FC66); { /* end of list */ },
cx_write(AUD_DEEMPH1_B1, 0x399A); };
static const struct rlist fm_deemph_75[] = {
{ AUD_DEEMPH0_G0, 0x091B },
{ AUD_DEEMPH0_A0, 0x6B68 },
{ AUD_DEEMPH0_B0, 0x11EC },
{ AUD_DEEMPH0_A1, 0x3FC66},
{ AUD_DEEMPH0_B1, 0x399A },
{ AUD_DEEMPH1_G0, 0x0AA0 },
{ AUD_DEEMPH1_A0, 0x6B68 },
{ AUD_DEEMPH1_B0, 0x11EC },
{ AUD_DEEMPH1_A1, 0x3FC66},
{ AUD_DEEMPH1_B1, 0x399A},
{ AUD_POLYPH80SCALEFAC, 0x0003},
{ /* end of list */ },
};
break; /* It is enough to leave default values? */
static const struct rlist fm_no_deemph[] = {
case WW_FM_DEEMPH_75: { AUD_POLYPH80SCALEFAC, 0x0003},
//Set De-emphasis filter coefficients for 75 usec { /* end of list */ },
cx_write(AUD_DEEMPH0_G0, 0x91B ); };
cx_write(AUD_DEEMPH0_A0, 0x6B68);
cx_write(AUD_DEEMPH0_B0, 0x11EC);
cx_write(AUD_DEEMPH0_A1, 0x3FC66);
cx_write(AUD_DEEMPH0_B1, 0x399A);
cx_write(AUD_DEEMPH1_G0, 0xAA0 ); dprintk("%s (status: unknown)\n",__FUNCTION__);
cx_write(AUD_DEEMPH1_A0, 0x6B68); set_audio_start(core, 0x0020, EN_FMRADIO_AUTO_STEREO);
cx_write(AUD_DEEMPH1_B0, 0x11EC);
cx_write(AUD_DEEMPH1_A1, 0x3FC66);
cx_write(AUD_DEEMPH1_B1, 0x399A);
switch (deemph)
{
case FM_NO_DEEMPH:
set_audio_registers(core, fm_no_deemph);
break; break;
}
#endif
dprintk("%s (status: unknown)\n",__FUNCTION__); case FM_DEEMPH_50:
set_audio_start(core, 0x0020, EN_FMRADIO_AUTO_STEREO); set_audio_registers(core, fm_deemph_50);
break;
// AB: 10/2/01: this register is not being reset appropriately on occasion. case FM_DEEMPH_75:
cx_write(AUD_POLYPH80SCALEFAC,3); set_audio_registers(core, fm_deemph_75);
break;
}
set_audio_finish(core); set_audio_finish(core);
} }
...@@ -778,7 +800,7 @@ void cx88_set_tvaudio(struct cx88_core *core) ...@@ -778,7 +800,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
set_audio_standard_EIAJ(core); set_audio_standard_EIAJ(core);
break; break;
case WW_FM: case WW_FM:
set_audio_standard_FM(core); set_audio_standard_FM(core,FM_NO_DEEMPH);
break; break;
case WW_SYSTEM_L_AM: case WW_SYSTEM_L_AM:
set_audio_standard_NICAM_L(core, 1); set_audio_standard_NICAM_L(core, 1);
...@@ -1029,4 +1051,5 @@ EXPORT_SYMBOL(cx88_audio_thread); ...@@ -1029,4 +1051,5 @@ EXPORT_SYMBOL(cx88_audio_thread);
* Local variables: * Local variables:
* c-basic-offset: 8 * c-basic-offset: 8
* End: * End:
* kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
*/ */
/* /*
* $Id: cx88-vbi.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $ * $Id: cx88-vbi.c,v 1.17 2005/06/12 04:19:19 mchehab Exp $
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
......
/* /*
* $Id: cx88-video.c,v 1.58 2005/03/07 15:58:05 kraxel Exp $ * $Id: cx88-video.c,v 1.63 2005/06/12 04:19:19 mchehab Exp $
* *
* device driver for Conexant 2388x based TV cards * device driver for Conexant 2388x based TV cards
* video4linux video interface * video4linux video interface
...@@ -1187,9 +1187,24 @@ static void init_controls(struct cx8800_dev *dev) ...@@ -1187,9 +1187,24 @@ static void init_controls(struct cx8800_dev *dev)
.id = V4L2_CID_AUDIO_VOLUME, .id = V4L2_CID_AUDIO_VOLUME,
.value = 0x3f, .value = 0x3f,
}; };
static struct v4l2_control hue = {
.id = V4L2_CID_HUE,
.value = 0x80,
};
static struct v4l2_control contrast = {
.id = V4L2_CID_CONTRAST,
.value = 0x80,
};
static struct v4l2_control brightness = {
.id = V4L2_CID_BRIGHTNESS,
.value = 0x80,
};
set_control(dev,&mute); set_control(dev,&mute);
set_control(dev,&volume); set_control(dev,&volume);
set_control(dev,&hue);
set_control(dev,&contrast);
set_control(dev,&brightness);
} }
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
...@@ -1335,6 +1350,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file, ...@@ -1335,6 +1350,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
V4L2_CAP_READWRITE | V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING | V4L2_CAP_STREAMING |
V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VBI_CAPTURE |
#if 0
V4L2_TUNER_CAP_LOW |
#endif
#if 0 #if 0
V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OVERLAY |
#endif #endif
...@@ -1696,7 +1714,11 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, ...@@ -1696,7 +1714,11 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
sizeof(cap->card)); sizeof(cap->card));
sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci)); sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci));
cap->version = CX88_VERSION_CODE; cap->version = CX88_VERSION_CODE;
cap->capabilities = V4L2_CAP_TUNER; cap->capabilities = V4L2_CAP_TUNER
#if 0
| V4L2_TUNER_CAP_LOW
#endif
;
return 0; return 0;
} }
case VIDIOC_G_TUNER: case VIDIOC_G_TUNER:
...@@ -1992,6 +2014,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, ...@@ -1992,6 +2014,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
{ {
struct cx8800_dev *dev; struct cx8800_dev *dev;
struct cx88_core *core; struct cx88_core *core;
struct tuner_addr tun_addr;
int err; int err;
dev = kmalloc(sizeof(*dev),GFP_KERNEL); dev = kmalloc(sizeof(*dev),GFP_KERNEL);
...@@ -2065,8 +2088,19 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, ...@@ -2065,8 +2088,19 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
request_module("tuner"); request_module("tuner");
if (core->tda9887_conf) if (core->tda9887_conf)
request_module("tda9887"); request_module("tda9887");
if (core->tuner_type != UNSET) if (core->radio_type != UNSET) {
cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE,&core->tuner_type); tun_addr.v4l2_tuner = V4L2_TUNER_RADIO;
tun_addr.type = core->radio_type;
tun_addr.addr = core->radio_addr;
cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE_ADDR, &tun_addr);
}
if (core->tuner_type != UNSET) {
tun_addr.v4l2_tuner = V4L2_TUNER_ANALOG_TV;
tun_addr.type = core->tuner_type;
tun_addr.addr = core->tuner_addr;
cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE_ADDR, &tun_addr);
}
if (core->tda9887_conf) if (core->tda9887_conf)
cx88_call_i2c_clients(dev->core,TDA9887_SET_CONFIG,&core->tda9887_conf); cx88_call_i2c_clients(dev->core,TDA9887_SET_CONFIG,&core->tda9887_conf);
...@@ -2274,4 +2308,5 @@ module_exit(cx8800_fini); ...@@ -2274,4 +2308,5 @@ module_exit(cx8800_fini);
* Local variables: * Local variables:
* c-basic-offset: 8 * c-basic-offset: 8
* End: * End:
* kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
*/ */
/* /*
* $Id: cx88.h,v 1.56 2005/03/04 09:12:23 kraxel Exp $ * $Id: cx88.h,v 1.62 2005/06/12 04:19:19 mchehab Exp $
* *
* v4l2 device driver for cx2388x based TV cards * v4l2 device driver for cx2388x based TV cards
* *
...@@ -64,6 +64,13 @@ ...@@ -64,6 +64,13 @@
#define SHADOW_AUD_BAL_CTL 2 #define SHADOW_AUD_BAL_CTL 2
#define SHADOW_MAX 2 #define SHADOW_MAX 2
/* FM Radio deemphasis type */
enum cx88_deemph_type {
FM_NO_DEEMPH = 0,
FM_DEEMPH_50,
FM_DEEMPH_75
};
/* ----------------------------------------------------------- */ /* ----------------------------------------------------------- */
/* tv norms */ /* tv norms */
...@@ -187,6 +194,9 @@ struct cx88_input { ...@@ -187,6 +194,9 @@ struct cx88_input {
struct cx88_board { struct cx88_board {
char *name; char *name;
unsigned int tuner_type; unsigned int tuner_type;
unsigned int radio_type;
unsigned char tuner_addr;
unsigned char radio_addr;
int tda9887_conf; int tda9887_conf;
struct cx88_input input[8]; struct cx88_input input[8];
struct cx88_input radio; struct cx88_input radio;
...@@ -257,6 +267,9 @@ struct cx88_core { ...@@ -257,6 +267,9 @@ struct cx88_core {
/* config info -- analog */ /* config info -- analog */
unsigned int board; unsigned int board;
unsigned int tuner_type; unsigned int tuner_type;
unsigned int radio_type;
unsigned char tuner_addr;
unsigned char radio_addr;
unsigned int tda9887_conf; unsigned int tda9887_conf;
unsigned int has_radio; unsigned int has_radio;
...@@ -422,6 +435,7 @@ struct cx8802_dev { ...@@ -422,6 +435,7 @@ struct cx8802_dev {
/* ----------------------------------------------------------- */ /* ----------------------------------------------------------- */
/* cx88-core.c */ /* cx88-core.c */
extern char *cx88_pci_irqs[32];
extern char *cx88_vid_irqs[32]; extern char *cx88_vid_irqs[32];
extern char *cx88_mpeg_irqs[32]; extern char *cx88_mpeg_irqs[32];
extern void cx88_print_irqbits(char *name, char *tag, char **strings, extern void cx88_print_irqbits(char *name, char *tag, char **strings,
...@@ -473,6 +487,11 @@ extern void cx88_core_put(struct cx88_core *core, ...@@ -473,6 +487,11 @@ extern void cx88_core_put(struct cx88_core *core,
/* cx88-vbi.c */ /* cx88-vbi.c */
void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f); void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f);
/*
int cx8800_start_vbi_dma(struct cx8800_dev *dev,
struct cx88_dmaqueue *q,
struct cx88_buffer *buf);
*/
int cx8800_stop_vbi_dma(struct cx8800_dev *dev); int cx8800_stop_vbi_dma(struct cx8800_dev *dev);
int cx8800_restart_vbi_queue(struct cx8800_dev *dev, int cx8800_restart_vbi_queue(struct cx8800_dev *dev,
struct cx88_dmaqueue *q); struct cx88_dmaqueue *q);
......
/* /*
* $Id: ir-kbd-gpio.c,v 1.12 2005/02/22 12:28:40 kraxel Exp $ * $Id: ir-kbd-gpio.c,v 1.13 2005/05/15 19:01:26 mchehab Exp $
* *
* Copyright (c) 2003 Gerd Knorr * Copyright (c) 2003 Gerd Knorr
* Copyright (c) 2003 Pavel Machek * Copyright (c) 2003 Pavel Machek
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment