Commit e44d520e authored by Gerd Knorr's avatar Gerd Knorr Committed by Linus Torvalds

[PATCH] v4l: cx88 driver update

Finally the big cx88 driver update which makes the cx88-dvb driver compile and
work for some cards.  A number of changes accumulated over time ...

 * various new tv cards added / fixed.
 * added support for infrared remote controls.
 * some fixes in the blackbird (mpeg encoder) driver,
   starts working now.
 * configurarion for analog hauppauge cards now uses
   the tveeprom module.
 * kconfig fixups.
 * powermanagement fixups.
 * lot of tweaks for tv audio (make NICAM decoding work).
 * lot of changes in the dvb driver, still not working
   for all cards though as some more changes in the dvb
   subsystem are needed.
Signed-off-by: default avatarGerd Knorr <kraxel@bytesex.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0d3430ba
......@@ -307,11 +307,14 @@ config VIDEO_HEXIUM_GEMINI
config VIDEO_CX88
tristate "Conexant 2388x (bt878 successor) support"
depends on VIDEO_DEV && PCI && EXPERIMENTAL
depends on VIDEO_DEV && PCI && I2C && EXPERIMENTAL
select I2C_ALGOBIT
select FW_LOADER
select VIDEO_BTCX
select VIDEO_BUF
select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_IR
---help---
This is a video4linux driver for Conexant 2388x based
TV cards.
......@@ -321,10 +324,11 @@ config VIDEO_CX88
config VIDEO_CX88_DVB
tristate "DVB Support for cx2388x based TV cards"
depends on VIDEO_CX88 && DVB_CORE && BROKEN
depends on VIDEO_CX88 && DVB_CORE
select VIDEO_BUF_DVB
select DVB_MT352
---help---
This adds support for DVB cards based on the
This adds support for DVB/ATSC cards based on the
Connexant 2388x chip.
config VIDEO_OVCAMCHIP
......
cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o
cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \
cx88-input.o
cx8800-objs := cx88-video.o cx88-vbi.o
cx8802-objs := cx88-mpeg.o
......
/*
* $Id: cx88-blackbird.c,v 1.17 2004/11/07 13:17:15 kraxel Exp $
* $Id: cx88-blackbird.c,v 1.26 2005/03/07 15:58:05 kraxel Exp $
*
* Support for a cx23416 mpeg encoder via cx2388x host port.
* "blackbird" reference design.
......@@ -25,6 +25,7 @@
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/delay.h>
......@@ -207,10 +208,6 @@ static int register_write(struct cx88_core *core, u32 address, u32 value)
cx_read(P1_RADDR0);
return wait_ready_gpio0_bit1(core,1);
#if 0
udelay(1000); /* without this, things don't go right (subsequent memory_write()'s don't get through */
/* ? would this be safe here? set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); */
#endif
}
......@@ -283,7 +280,7 @@ static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command,
timeout = jiffies + msecs_to_jiffies(10);
for (;;) {
memory_read(dev->core, dev->mailbox, &flag);
if (0 == (flag & 4))
if (0 != (flag & 4))
break;
if (time_after(jiffies,timeout)) {
dprintk(0, "ERROR: API Mailbox timeout\n");
......@@ -324,7 +321,7 @@ static int blackbird_find_mailbox(struct cx8802_dev *dev)
signaturecnt = 0;
if (4 == signaturecnt) {
dprintk(1, "Mailbox signature found\n");
return i;
return i+1;
}
}
dprintk(0, "Mailbox signature values not found!\n");
......@@ -427,7 +424,8 @@ static void blackbird_codec_settings(struct cx8802_dev *dev)
blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAMERATE, 1, 0, 0);
/* assign frame size */
blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_SIZE, 2, 0, 480, 720);
blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_SIZE, 2, 0,
dev->height, dev->width);
/* assign aspect ratio */
blackbird_api_cmd(dev, IVTV_API_ASSIGN_ASPECT_RATIO, 1, 0, 2);
......@@ -629,8 +627,8 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
memset(f,0,sizeof(*f));
f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.width = 720;
f->fmt.pix.height = 576;
f->fmt.pix.width = dev->width;
f->fmt.pix.height = dev->height;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = 1024 * 512 /* FIXME: BUFFER_SIZE */;
}
......@@ -694,6 +692,10 @@ static int mpeg_open(struct inode *inode, struct file *file)
file->private_data = fh;
fh->dev = dev;
/* FIXME: locking against other video device */
cx88_set_scale(dev->core, dev->width, dev->height,
V4L2_FIELD_INTERLACED);
videobuf_queue_init(&fh->mpegq, &blackbird_qops,
dev->pci, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
......@@ -715,6 +717,7 @@ static int mpeg_release(struct inode *inode, struct file *file)
if (fh->mpegq.reading)
videobuf_read_stop(&fh->mpegq);
videobuf_mmap_free(&fh->mpegq);
file->private_data = NULL;
kfree(fh);
return 0;
......@@ -821,6 +824,8 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
memset(dev,0,sizeof(*dev));
dev->pci = pci_dev;
dev->core = core;
dev->width = 720;
dev->height = 480;
err = cx8802_init_common(dev);
if (0 != err)
......@@ -852,6 +857,8 @@ static void __devexit blackbird_remove(struct pci_dev *pci_dev)
/* common */
cx8802_fini_common(dev);
cx88_core_put(dev->core,dev->pci);
kfree(dev);
}
static struct pci_device_id cx8802_pci_tbl[] = {
......
This diff is collapsed.
/*
* $Id: cx88-core.c,v 1.15 2004/10/25 11:26:36 kraxel Exp $
* $Id: cx88-core.c,v 1.24 2005/01/19 12:01:55 kraxel Exp $
*
* device driver for Conexant 2388x based TV cards
* driver core
......@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/kmod.h>
......@@ -62,6 +63,10 @@ static unsigned int nicam = 0;
module_param(nicam,int,0644);
MODULE_PARM_DESC(nicam,"tv audio is nicam");
static unsigned int nocomb = 0;
module_param(nocomb,int,0644);
MODULE_PARM_DESC(nocomb,"disable comb filter");
#define dprintk(level,fmt, arg...) if (core_debug >= level) \
printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
......@@ -462,6 +467,7 @@ int cx88_risc_decode(u32 risc)
return incr[risc >> 28] ? incr[risc >> 28] : 1;
}
#if 0 /* currently unused, but useful for debugging */
void cx88_risc_disasm(struct cx88_core *core,
struct btcx_riscmem *risc)
{
......@@ -479,6 +485,7 @@ void cx88_risc_disasm(struct cx88_core *core,
break;
}
}
#endif
void cx88_sram_channel_dump(struct cx88_core *core,
struct sram_channel *ch)
......@@ -579,10 +586,19 @@ void cx88_print_irqbits(char *name, char *tag, char **strings,
/* ------------------------------------------------------------------ */
void cx88_irq(struct cx88_core *core, u32 status, u32 mask)
int cx88_core_irq(struct cx88_core *core, u32 status)
{
cx88_print_irqbits(core->name, "irq pci",
cx88_pci_irqs, status, mask);
int handled = 0;
if (status & (1<<18)) {
cx88_ir_irq(core);
handled++;
}
if (!handled)
cx88_print_irqbits(core->name, "irq pci",
cx88_pci_irqs, status,
core->pci_irqmask);
return handled;
}
void cx88_wakeup(struct cx88_core *core,
......@@ -800,6 +816,8 @@ int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int heig
value |= (1 << 0); // 3-tap interpolation
if (width < 193)
value |= (1 << 1); // 5-tap interpolation
if (nocomb)
value |= (3 << 5); // disable comb filter
cx_write(MO_FILTER_EVEN, value);
cx_write(MO_FILTER_ODD, value);
......@@ -887,8 +905,8 @@ static int set_tvaudio(struct cx88_core *core)
cx88_set_tvaudio(core);
// cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO);
cx_write(MO_AUDD_LNGTH, 128/8); /* fifo size */
cx_write(MO_AUDR_LNGTH, 128/8); /* fifo size */
cx_write(MO_AUDD_LNGTH, 128); /* fifo size */
cx_write(MO_AUDR_LNGTH, 128); /* fifo size */
cx_write(MO_AUD_DMACNTRL, 0x03); /* need audio fifo */
return 0;
}
......@@ -969,6 +987,9 @@ int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm)
cx_write(MO_VBI_PACKET, ((1 << 11) | /* (norm_vdelay(norm) << 11) | */
norm_vbipack(norm)));
// this is needed as well to set all tvnorm parameter
cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
// audio
set_tvaudio(core);
......@@ -1105,9 +1126,10 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
goto fail_unlock;
memset(core,0,sizeof(*core));
atomic_inc(&core->refcount);
core->pci_bus = pci->bus->number;
core->pci_slot = PCI_SLOT(pci->devfn);
atomic_inc(&core->refcount);
core->pci_irqmask = 0x00fc00;
core->nr = cx88_devcount++;
sprintf(core->name,"cx88[%d]",core->nr);
......@@ -1150,6 +1172,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
cx88_reset(core);
cx88_i2c_init(core,pci);
cx88_card_setup(core);
cx88_ir_init(core,pci);
up(&devlist);
return core;
......@@ -1170,6 +1193,7 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
return;
down(&devlist);
cx88_ir_fini(core);
if (0 == core->i2c_rc)
i2c_bit_del_bus(&core->i2c_adap);
list_del(&core->devlist);
......@@ -1187,7 +1211,7 @@ EXPORT_SYMBOL(cx88_vid_irqs);
EXPORT_SYMBOL(cx88_mpeg_irqs);
EXPORT_SYMBOL(cx88_print_irqbits);
EXPORT_SYMBOL(cx88_irq);
EXPORT_SYMBOL(cx88_core_irq);
EXPORT_SYMBOL(cx88_wakeup);
EXPORT_SYMBOL(cx88_reset);
EXPORT_SYMBOL(cx88_shutdown);
......@@ -1197,8 +1221,6 @@ EXPORT_SYMBOL(cx88_risc_databuffer);
EXPORT_SYMBOL(cx88_risc_stopper);
EXPORT_SYMBOL(cx88_free_buffer);
EXPORT_SYMBOL(cx88_risc_disasm);
EXPORT_SYMBOL(cx88_sram_channels);
EXPORT_SYMBOL(cx88_sram_channel_setup);
EXPORT_SYMBOL(cx88_sram_channel_dump);
......
/*
* $Id: cx88-dvb.c,v 1.19 2004/11/07 14:44:59 kraxel Exp $
* $Id: cx88-dvb.c,v 1.31 2005/03/07 15:58:05 kraxel Exp $
*
* device driver for Conexant 2388x based TV cards
* MPEG Transport Stream (DVB) routines
......@@ -30,10 +30,20 @@
#include <linux/file.h>
#include <linux/suspend.h>
/* those two frontends need merging via linuxtv cvs ... */
#define HAVE_CX22702 0
#define HAVE_OR51132 0
#include "cx88.h"
#include "cx22702.h"
#include "dvb-pll.h"
#include "mt352.h"
#include "mt352_priv.h" /* FIXME */
#include "mt352_priv.h"
#if HAVE_CX22702
# include "cx22702.h"
#endif
#if HAVE_OR51132
# include "or51132.h"
#endif
MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
......@@ -110,111 +120,144 @@ static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
return 0;
}
#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
static int lg_z201_pll_set(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params, u8* pllbuf)
static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
{
u32 div;
unsigned char cp = 0;
unsigned char bs = 0;
div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
static u8 clock_config [] = { 0x89, 0x38, 0x39 };
static u8 reset [] = { 0x50, 0x80 };
static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
0x00, 0xFF, 0x00, 0x40, 0x40 };
static u8 dntv_extra[] = { 0xB5, 0x7A };
static u8 capt_range_cfg[] = { 0x75, 0x32 };
if (params->frequency < 542000000) cp = 0xbc;
else if (params->frequency < 830000000) cp = 0xf4;
else cp = 0xfc;
if (params->frequency == 0) bs = 0x03;
else if (params->frequency < 157500000) bs = 0x01;
else if (params->frequency < 443250000) bs = 0x02;
else bs = 0x04;
mt352_write(fe, clock_config, sizeof(clock_config));
udelay(2000);
mt352_write(fe, reset, sizeof(reset));
mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
pllbuf[0] = 0xC2; /* Note: non-linux standard PLL I2C address */
pllbuf[1] = div >> 8;
pllbuf[2] = div & 0xff;
pllbuf[3] = cp;
pllbuf[4] = bs;
mt352_write(fe, agc_cfg, sizeof(agc_cfg));
udelay(2000);
mt352_write(fe, dntv_extra, sizeof(dntv_extra));
mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
return 0;
}
static int thomson_dtt7579_pll_set(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params,
u8* pllbuf)
static int mt352_pll_set(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params,
u8* pllbuf)
{
u32 div;
unsigned char cp = 0;
unsigned char bs = 0;
div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
if (params->frequency < 542000000) cp = 0xb4;
else if (params->frequency < 771000000) cp = 0xbc;
else cp = 0xf4;
if (params->frequency == 0) bs = 0x03;
else if (params->frequency < 443250000) bs = 0x02;
else bs = 0x08;
pllbuf[0] = 0xc0; // Note: non-linux standard PLL i2c address
pllbuf[1] = div >> 8;
pllbuf[2] = div & 0xff;
pllbuf[3] = cp;
pllbuf[4] = bs;
struct cx8802_dev *dev= fe->dvb->priv;
pllbuf[0] = dev->core->pll_addr << 1;
dvb_pll_configure(dev->core->pll_desc, pllbuf+1,
params->frequency,
params->u.ofdm.bandwidth);
return 0;
}
struct mt352_config dvico_fusionhdtv_dvbt1 = {
static struct mt352_config dvico_fusionhdtv = {
.demod_address = 0x0F,
.demod_init = dvico_fusionhdtv_demod_init,
.pll_set = lg_z201_pll_set,
.pll_set = mt352_pll_set,
};
struct mt352_config dvico_fusionhdtv_dvbt_plus = {
.demod_address = 0x0F,
.demod_init = dvico_fusionhdtv_demod_init,
.pll_set = thomson_dtt7579_pll_set,
static struct mt352_config dntv_live_dvbt_config = {
.demod_address = 0x0f,
.demod_init = dntv_live_dvbt_demod_init,
.pll_set = mt352_pll_set,
};
#if HAVE_CX22702
static struct cx22702_config connexant_refboard_config = {
.demod_address = 0x43,
.pll_address = 0x60,
.pll_desc = &dvb_pll_thomson_dtt7579,
};
static struct cx22702_config hauppauge_novat_config = {
.demod_address = 0x43,
.pll_address = 0x61,
.pll_desc = &dvb_pll_thomson_dtt759x,
};
#endif
#if HAVE_OR51132
static int or51132_set_ts_param(struct dvb_frontend* fe,
int is_punctured)
{
struct cx8802_dev *dev= fe->dvb->priv;
dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
return 0;
}
struct or51132_config pchdtv_hd3000 = {
.demod_address = 0x15,
.pll_address = 0x61,
.pll_desc = &dvb_pll_thomson_dtt7610,
.set_ts_params = or51132_set_ts_param,
};
#endif
static int dvb_register(struct cx8802_dev *dev)
{
/* init struct videobuf_dvb */
dev->dvb.name = dev->core->name;
dev->ts_gen_cntrl = 0x0c;
/* init frontend */
switch (dev->core->board) {
#if HAVE_CX22702
case CX88_BOARD_HAUPPAUGE_DVB_T1:
dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config,
&dev->core->i2c_adap);
break;
case CX88_BOARD_CONEXANT_DVB_T1:
dev->dvb.frontend = cx22702_create(&dev->core->i2c_adap,
dev->core->pll_addr,
dev->core->pll_type,
dev->core->demod_addr);
dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
&dev->core->i2c_adap);
break;
#endif
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dvbt1,
dev->core->pll_addr = 0x61;
dev->core->pll_desc = &dvb_pll_lg_z201;
dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
&dev->core->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops->info.frequency_min = 174000000;
dev->dvb.frontend->ops->info.frequency_max = 862000000;
}
break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dvbt_plus,
dev->core->pll_addr = 0x60;
dev->core->pll_desc = &dvb_pll_thomson_dtt7579;
dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
&dev->core->i2c_adap);
break;
case CX88_BOARD_KWORLD_DVB_T:
case CX88_BOARD_DNTV_LIVE_DVB_T:
dev->core->pll_addr = 0x61;
dev->core->pll_desc = &dvb_pll_unknown_1;
dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
&dev->core->i2c_adap);
break;
#if HAVE_OR51132
case CX88_BOARD_PCHDTV_HD3000:
dev->dvb.frontend = or51132_attach(&pchdtv_hd3000,
&dev->core->i2c_adap);
if (dev->dvb.frontend) {
dev->dvb.frontend->ops->info.frequency_min = 174000000;
dev->dvb.frontend->ops->info.frequency_max = 862000000;
}
break;
#endif
default:
printk("%s: FIXME: frontend handling not here yet ...\n",
dev->core->name);
printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n"
"%s: you might want to look out for patches here:\n"
"%s: http://dl.bytesex.org/patches/\n",
dev->core->name, dev->core->name, dev->core->name);
break;
}
if (NULL == dev->dvb.frontend)
if (NULL == dev->dvb.frontend) {
printk("%s: frontend initialization failed\n",dev->core->name);
return -1;
}
if (dev->core->pll_desc) {
dev->dvb.frontend->ops->info.frequency_min = dev->core->pll_desc->min;
dev->dvb.frontend->ops->info.frequency_max = dev->core->pll_desc->max;
}
/* Copy the board name into the DVB structure */
strlcpy(dev->dvb.frontend->ops->info.name,
......@@ -222,7 +265,7 @@ static int dvb_register(struct cx8802_dev *dev)
sizeof(dev->dvb.frontend->ops->info.name));
/* register everything */
return videobuf_dvb_register(&dev->dvb);
return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
}
/* ----------------------------------------------------------- */
......
/*
$Id: cx88-i2c.c,v 1.18 2004/10/13 10:39:00 kraxel Exp $
$Id: cx88-i2c.c,v 1.20 2005/02/15 15:59:35 kraxel Exp $
cx88-i2c.c -- all the i2c code is here
......@@ -25,6 +25,7 @@
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <asm/io.h>
......
This diff is collapsed.
/*
* $Id: cx88-mpeg.c,v 1.14 2004/10/25 11:26:36 kraxel Exp $
* $Id: cx88-mpeg.c,v 1.25 2005/03/07 14:18:00 kraxel Exp $
*
* Support for the mpeg transport stream transfers
* PCI function #2 of the cx2388x.
......@@ -24,6 +24,7 @@
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/interrupt.h>
......@@ -68,8 +69,14 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
* also: move to cx88-blackbird + cx88-dvb source files? */
if (cx88_boards[core->board].dvb) {
/* Setup TS portion of chip */
cx_write(TS_GEN_CNTRL, 0x0c);
/* negedge driven & software reset */
cx_write(TS_GEN_CNTRL, 0x40);
udelay(100);
cx_write(MO_PINMUX_IO, 0x00);
cx_write(TS_HW_SOP_CNTRL,47<<16|188<<4|0x00);
cx_write(TS_SOP_STAT,0x00);
cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl);
udelay(100);
}
if (cx88_boards[core->board].blackbird) {
......@@ -93,7 +100,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
q->count = 1;
/* enable irqs */
cx_set(MO_PCI_INTMSK, 0x00fc04);
cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04);
cx_write(MO_TS_INTMSK, 0x1f0011);
/* start dma */
......@@ -292,19 +299,18 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
{
struct cx8802_dev *dev = dev_id;
struct cx88_core *core = dev->core;
u32 status, mask;
u32 status;
int loop, handled = 0;
for (loop = 0; loop < 10; loop++) {
status = cx_read(MO_PCI_INTSTAT) & (~0x1f | 0x04);
mask = cx_read(MO_PCI_INTMSK);
if (0 == (status & mask))
status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04);
if (0 == status)
goto out;
handled = 1;
cx_write(MO_PCI_INTSTAT, status);
if (status & mask & ~0x1f)
cx88_irq(core,status,mask);
if (status & core->pci_irqmask)
cx88_core_irq(core,status);
if (status & 0x04)
cx8802_mpeg_irq(dev);
};
......@@ -323,6 +329,7 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
int cx8802_init_common(struct cx8802_dev *dev)
{
struct cx88_core *core = dev->core;
int err;
/* pci init */
......@@ -354,11 +361,6 @@ int cx8802_init_common(struct cx8802_dev *dev)
cx88_risc_stopper(dev->pci,&dev->mpegq.stopper,
MO_TS_DMACNTRL,0x11,0x00);
#if 0 /* FIXME */
/* initialize hardware */
cx8802_reset(dev);
#endif
/* get irq */
err = request_irq(dev->pci->irq, cx8802_irq,
SA_SHIRQ | SA_INTERRUPT, dev->core->name, dev);
......@@ -367,11 +369,7 @@ int cx8802_init_common(struct cx8802_dev *dev)
dev->core->name, dev->pci->irq);
return err;
}
#if 0 /* FIXME */
/* register i2c bus + load i2c helpers */
cx88_card_setup(dev);
#endif
cx_set(MO_PCI_INTMSK, core->pci_irqmask);
/* everything worked */
pci_set_drvdata(dev->pci,dev);
......@@ -393,7 +391,7 @@ void cx8802_fini_common(struct cx8802_dev *dev)
/* ----------------------------------------------------------- */
int cx8802_suspend_common(struct pci_dev *pci_dev, u32 state)
int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
{
struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
struct cx88_core *core = dev->core;
......@@ -413,7 +411,7 @@ int cx8802_suspend_common(struct pci_dev *pci_dev, u32 state)
#endif
pci_save_state(pci_dev);
if (0 != pci_set_power_state(pci_dev, state)) {
if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
pci_disable_device(pci_dev);
dev->state.disabled = 1;
}
......@@ -429,7 +427,7 @@ int cx8802_resume_common(struct pci_dev *pci_dev)
pci_enable_device(pci_dev);
dev->state.disabled = 0;
}
pci_set_power_state(pci_dev, 0);
pci_set_power_state(pci_dev, PCI_D0);
pci_restore_state(pci_dev);
#if 1
......
This diff is collapsed.
/*
* $Id: cx88-vbi.c,v 1.14 2004/11/07 13:17:15 kraxel Exp $
* $Id: cx88-vbi.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/slab.h>
......@@ -64,7 +65,7 @@ int cx8800_start_vbi_dma(struct cx8800_dev *dev,
q->count = 1;
/* enable irqs */
cx_set(MO_PCI_INTMSK, 0x00fc01);
cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x01);
cx_set(MO_VID_INTMSK, 0x0f0088);
/* enable capture */
......
/*
* $Id: cx88-video.c,v 1.46 2004/11/07 14:44:59 kraxel Exp $
* $Id: cx88-video.c,v 1.58 2005/03/07 15:58:05 kraxel Exp $
*
* device driver for Conexant 2388x based TV cards
* video4linux video interface
......@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kmod.h>
#include <linux/kernel.h>
#include <linux/slab.h>
......@@ -428,7 +429,7 @@ static int start_video_dma(struct cx8800_dev *dev,
q->count = 1;
/* enable irqs */
cx_set(MO_PCI_INTMSK, 0x00fc01);
cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x01);
cx_set(MO_VID_INTMSK, 0x0f0011);
/* enable capture */
......@@ -994,7 +995,7 @@ static int video_open(struct inode *inode, struct file *file)
cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3);
dev->core->tvaudio = WW_FM;
cx88_set_tvaudio(core);
cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO);
cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
cx88_call_i2c_clients(dev->core,AUDC_SET_RADIO,NULL);
}
......@@ -1002,7 +1003,7 @@ static int video_open(struct inode *inode, struct file *file)
}
static ssize_t
video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
video_read(struct file *file, char *data, size_t count, loff_t *ppos)
{
struct cx8800_fh *fh = file->private_data;
......@@ -1083,6 +1084,8 @@ static int video_release(struct inode *inode, struct file *file)
res_free(dev,fh,RESOURCE_VBI);
}
videobuf_mmap_free(&fh->vidq);
videobuf_mmap_free(&fh->vbiq);
file->private_data = NULL;
kfree(fh);
return 0;
......@@ -1338,7 +1341,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
0;
if (UNSET != core->tuner_type)
cap->capabilities |= V4L2_CAP_TUNER;
return 0;
}
......@@ -1429,6 +1431,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
if (*i >= 4)
return -EINVAL;
down(&dev->lock);
cx88_newstation(core);
video_mux(dev,*i);
up(&dev->lock);
return 0;
......@@ -1560,7 +1563,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
return -EINVAL;
if (0 != t->index)
return -EINVAL;
cx88_set_stereo(core, t->audmode);
cx88_set_stereo(core, t->audmode, 1);
return 0;
}
case VIDIOC_G_FREQUENCY:
......@@ -1590,6 +1593,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
return -EINVAL;
down(&dev->lock);
dev->freq = f->frequency;
cx88_newstation(core);
#ifdef V4L2_I2C_CLIENTS
cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f);
#else
......@@ -1880,19 +1884,18 @@ static irqreturn_t cx8800_irq(int irq, void *dev_id, struct pt_regs *regs)
{
struct cx8800_dev *dev = dev_id;
struct cx88_core *core = dev->core;
u32 status, mask;
u32 status;
int loop, handled = 0;
for (loop = 0; loop < 10; loop++) {
status = cx_read(MO_PCI_INTSTAT) & (~0x1f | 0x01);
mask = cx_read(MO_PCI_INTMSK);
if (0 == (status & mask))
status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x01);
if (0 == status)
goto out;
cx_write(MO_PCI_INTSTAT, status);
handled = 1;
if (status & mask & ~0x1f)
cx88_irq(core,status,mask);
if (status & core->pci_irqmask)
cx88_core_irq(core,status);
if (status & 0x01)
cx8800_vid_irq(dev);
};
......@@ -2055,6 +2058,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
core->name,pci_dev->irq);
goto fail_core;
}
cx_set(MO_PCI_INTMSK, core->pci_irqmask);
/* load and configure helper modules */
if (TUNER_ABSENT != core->tuner_type)
......@@ -2156,7 +2160,7 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
kfree(dev);
}
static int cx8800_suspend(struct pci_dev *pci_dev, u32 state)
static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
{
struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
struct cx88_core *core = dev->core;
......@@ -2181,7 +2185,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, u32 state)
#endif
pci_save_state(pci_dev);
if (0 != pci_set_power_state(pci_dev, state)) {
if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
pci_disable_device(pci_dev);
dev->state.disabled = 1;
}
......@@ -2197,7 +2201,7 @@ static int cx8800_resume(struct pci_dev *pci_dev)
pci_enable_device(pci_dev);
dev->state.disabled = 0;
}
pci_set_power_state(pci_dev, 0);
pci_set_power_state(pci_dev, PCI_D0);
pci_restore_state(pci_dev);
#if 1
......
/*
* $Id: cx88.h,v 1.40 2004/11/03 09:04:51 kraxel Exp $
* $Id: cx88.h,v 1.56 2005/03/04 09:12:23 kraxel Exp $
*
* v4l2 device driver for cx2388x based TV cards
*
......@@ -27,6 +27,7 @@
#include <linux/kdev_t.h>
#include <media/tuner.h>
#include <media/tveeprom.h>
#include <media/audiochip.h>
#include <media/video-buf.h>
#include <media/video-buf-dvb.h>
......@@ -139,7 +140,7 @@ extern struct sram_channel cx88_sram_channels[];
#define CX88_BOARD_GDI 2
#define CX88_BOARD_PIXELVIEW 3
#define CX88_BOARD_ATI_WONDER_PRO 4
#define CX88_BOARD_WINFAST2000XP 5
#define CX88_BOARD_WINFAST2000XP_EXPERT 5
#define CX88_BOARD_AVERTV_303 6
#define CX88_BOARD_MSI_TVANYWHERE_MASTER 7
#define CX88_BOARD_WINFAST_DV2000 8
......@@ -156,6 +157,11 @@ extern struct sram_channel cx88_sram_channels[];
#define CX88_BOARD_CONEXANT_DVB_T1 19
#define CX88_BOARD_PROVIDEO_PV259 20
#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS 21
#define CX88_BOARD_PCHDTV_HD3000 22
#define CX88_BOARD_DNTV_LIVE_DVB_T 23
#define CX88_BOARD_HAUPPAUGE_ROSLYN 24
#define CX88_BOARD_DIGITALLOGIC_MEC 25
#define CX88_BOARD_IODATA_GVBCTV7E 26
enum cx88_itype {
CX88_VMUX_COMPOSITE1 = 1,
......@@ -238,6 +244,7 @@ struct cx88_core {
u32 __iomem *lmmio;
u8 __iomem *bmmio;
u32 shadow[SHADOW_MAX];
int pci_irqmask;
/* i2c i/o */
struct i2c_adapter i2c_adap;
......@@ -252,16 +259,20 @@ struct cx88_core {
unsigned int has_radio;
/* config info -- dvb */
unsigned int pll_type;
struct dvb_pll_desc *pll_desc;
unsigned int pll_addr;
unsigned int demod_addr;
/* state info */
struct task_struct *kthread;
struct cx88_tvnorm *tvnorm;
u32 tvaudio;
u32 audiomode_manual;
u32 audiomode_current;
u32 input;
u32 astat;
/* IR remote control state */
struct cx88_IR *ir;
};
struct cx8800_dev;
......@@ -371,11 +382,16 @@ struct cx8802_dev {
struct list_head devlist;
struct video_device *mpeg_dev;
u32 mailbox;
int width;
int height;
/* for dvb only */
struct videobuf_dvb dvb;
void* fe_handle;
int (*fe_release)(void *handle);
/* for switching modulation types */
unsigned char ts_gen_cntrl;
};
/* ----------------------------------------------------------- */
......@@ -411,7 +427,7 @@ extern void cx88_print_irqbits(char *name, char *tag, char **strings,
u32 bits, u32 mask);
extern void cx88_print_ioctl(char *name, unsigned int cmd);
extern void cx88_irq(struct cx88_core *core, u32 status, u32 mask);
extern int cx88_core_irq(struct cx88_core *core, u32 status);
extern void cx88_wakeup(struct cx88_core *core,
struct cx88_dmaqueue *q, u32 count);
extern void cx88_shutdown(struct cx88_core *core);
......@@ -503,10 +519,18 @@ extern void cx88_card_setup(struct cx88_core *core);
#define WW_FM 12
void cx88_set_tvaudio(struct cx88_core *core);
void cx88_newstation(struct cx88_core *core);
void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t);
void cx88_set_stereo(struct cx88_core *core, u32 mode);
void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual);
int cx88_audio_thread(void *data);
/* ----------------------------------------------------------- */
/* cx88-input.c */
int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci);
int cx88_ir_fini(struct cx88_core *core);
void cx88_ir_irq(struct cx88_core *core);
/* ----------------------------------------------------------- */
/* cx88-mpeg.c */
......@@ -517,7 +541,7 @@ void cx8802_cancel_buffers(struct cx8802_dev *dev);
int cx8802_init_common(struct cx8802_dev *dev);
void cx8802_fini_common(struct cx8802_dev *dev);
int cx8802_suspend_common(struct pci_dev *pci_dev, u32 state);
int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state);
int cx8802_resume_common(struct pci_dev *pci_dev);
/*
......
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