Subject: [patch] cx88 update FIXME: description Signed-off-by: Gerd Knorr Index: linux-2004-12-16/drivers/media/video/cx88/cx88-cards.c =================================================================== --- linux-2004-12-16.orig/drivers/media/video/cx88/cx88-cards.c 2004-12-17 12:09:01.000000000 +0100 +++ linux-2004-12-16/drivers/media/video/cx88/cx88-cards.c 2004-12-17 12:47:15.117293538 +0100 @@ -1,5 +1,5 @@ /* - * $Id: cx88-cards.c,v 1.47 2004/11/03 09:04:50 kraxel Exp $ + * $Id: cx88-cards.c,v 1.53 2004/12/14 15:33:30 kraxel Exp $ * * device driver for Conexant 2388x based TV cards * card-specific stuff. @@ -32,7 +32,8 @@ #include "cx88.h" #ifdef WITH_DVB -#include "cx22702.h" +# include "dvb-pll.h" +# include "cx22702.h" #endif /* ------------------------------------------------------------------ */ @@ -91,7 +92,7 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_PIXELVIEW] = { .name = "PixelView", - .tuner_type = UNSET, + .tuner_type = 5, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, @@ -223,20 +224,26 @@ struct cx88_board cx88_boards[] = { }, }, [CX88_BOARD_LEADTEK_PVR2000] = { + // gpio values for PAL version from regspy by DScaler .name = "Leadtek PVR 2000", .tuner_type = 38, + .tda9887_conf = TDA9887_PRESENT, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, + .gpio0 = 0x0000bde6, },{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, + .gpio0 = 0x0000bde6, },{ .type = CX88_VMUX_SVIDEO, .vmux = 2, + .gpio0 = 0x0000bde6, }}, .radio = { .type = CX88_RADIO, + .gpio0 = 0x0000bd62, }, .blackbird = 1, }, @@ -452,6 +459,22 @@ struct cx88_board cx88_boards[] = { }}, .dvb = 1, }, + [CX88_BOARD_DNTV_LIVE_DVB_T] = { + .name = "digitalnow DNTV Live! DVB-T", + .tuner_type = TUNER_ABSENT, + .input = {{ + .type = CX88_VMUX_COMPOSITE1, + .vmux = 1, + .gpio0 = 0x00000700, + .gpio2 = 0x00000101, + },{ + .type = CX88_VMUX_SVIDEO, + .vmux = 2, + .gpio0 = 0x00000700, + .gpio2 = 0x00000101, + }}, + .dvb = 1, + }, }; const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); @@ -543,6 +566,18 @@ struct cx88_subid cx88_subids[] = { .subvendor = 0x18AC, .subdevice = 0xDB10, .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, + },{ + .subvendor = 0x1554, + .subdevice = 0x4811, + .card = CX88_BOARD_PIXELVIEW, + },{ + .subvendor = 0x7063, + .subdevice = 0x3000, /* HD-3000 card */ + .card = CX88_BOARD_PCHDTV_HD3000, + },{ + .subvendor = 0x17DE, + .subdevice = 0xA8A6, + .card = CX88_BOARD_DNTV_LIVE_DVB_T, } }; const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); @@ -632,11 +667,13 @@ static struct { { TUNER_LG_PAL_FM, "LG TPI8PSB01D"}, { TUNER_LG_PAL, "LG TPI8PSB11D"}, { TUNER_LG_PAL_I_FM, "LG TAPC-I001D"}, - { TUNER_LG_PAL_I, "LG TAPC-I701D"} + { TUNER_LG_PAL_I, "LG TAPC-I701D"}, + { TUNER_THOMSON_DTT7610, "DTT-7610"} }; static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) { +#if 0 unsigned int blk2,tuner,radio,model; if (eeprom_data[0] != 0x84 || eeprom_data[2] != 0) { @@ -663,6 +700,13 @@ static void hauppauge_eeprom(struct cx88 core->name, model, (tuner < ARRAY_SIZE(hauppauge_tuner) ? hauppauge_tuner[tuner].name : "?"), core->tuner_type, radio ? "yes" : "no"); +#else + struct tveeprom tv; + + tveeprom_hauppauge_analog(&tv, eeprom_data); + core->tuner_type = tv.tuner_type; + core->has_radio = tv.has_radio; +#endif } #ifdef WITH_DVB @@ -670,7 +714,6 @@ static int hauppauge_eeprom_dvb(struct c { int model; int tuner; - char *tname; /* Make sure we support the board model */ model = ee[0x1f] << 24 | ee[0x1e] << 16 | ee[0x1d] << 8 | ee[0x1c]; @@ -689,23 +732,20 @@ static int hauppauge_eeprom_dvb(struct c /* Make sure we support the tuner */ tuner = ee[0x2d]; switch(tuner) { - case 0x4B: - tname = "Thomson DTT 7595"; - core->pll_type = PLLTYPE_DTT7595; - break; - case 0x4C: - tname = "Thomson DTT 7592"; - core->pll_type = PLLTYPE_DTT7592; + case 0x4B: /* ddt 7595 */ + case 0x4C: /* dtt 7592 */ + core->pll_desc = &dvb_pll_thomson_dtt759x; break; default: printk("%s: error: unknown hauppauge tuner 0x%02x\n", core->name, tuner); return -ENODEV; } - printk(KERN_INFO "%s: hauppauge eeprom: model=%d, tuner=%s (%d)\n", - core->name, model, tname, tuner); + printk(KERN_INFO "%s: hauppauge eeprom: model=%d, tuner=%d (%s)\n", + core->name, model, tuner, + core->pll_desc ? core->pll_desc->name : "UNKNOWN"); - core->pll_addr = 0x61; + core->pll_addr = 0x61; core->demod_addr = 0x43; } #endif @@ -763,36 +803,6 @@ static void gdi_eeprom(struct cx88_core /* ----------------------------------------------------------------------- */ -static int -i2c_eeprom(struct i2c_client *c, unsigned char *eedata, int len) -{ - unsigned char buf; - int err; - - c->addr = 0xa0 >> 1; - buf = 0; - if (1 != (err = i2c_master_send(c,&buf,1))) { - printk(KERN_INFO "cx88: Huh, no eeprom present (err=%d)?\n", - err); - return -1; - } - if (len != (err = i2c_master_recv(c,eedata,len))) { - printk(KERN_WARNING "cx88: i2c eeprom read error (err=%d)\n", - err); - return -1; - } -#if 0 - for (i = 0; i < len; i++) { - if (0 == (i % 16)) - printk(KERN_INFO "cx88 ee: %02x:",i); - printk(" %02x",eedata[i]); - if (15 == (i % 16)) - printk("\n"); - } -#endif - return 0; -} - void cx88_card_list(struct cx88_core *core, struct pci_dev *pci) { int i; @@ -823,21 +833,33 @@ void cx88_card_setup(struct cx88_core *c { static u8 eeprom[128]; + if (0 == core->i2c_rc) { + core->i2c_client.addr = 0xa0 >> 1; + tveeprom_read(&core->i2c_client,eeprom,sizeof(eeprom)); + } + switch (core->board) { case CX88_BOARD_HAUPPAUGE: if (0 == core->i2c_rc) - i2c_eeprom(&core->i2c_client,eeprom,sizeof(eeprom)); - hauppauge_eeprom(core,eeprom+8); + hauppauge_eeprom(core,eeprom+8); break; case CX88_BOARD_GDI: if (0 == core->i2c_rc) - i2c_eeprom(&core->i2c_client,eeprom,sizeof(eeprom)); - gdi_eeprom(core,eeprom); + gdi_eeprom(core,eeprom); break; case CX88_BOARD_WINFAST2000XP: if (0 == core->i2c_rc) - i2c_eeprom(&core->i2c_client,eeprom,sizeof(eeprom)); - leadtek_eeprom(core,eeprom); + leadtek_eeprom(core,eeprom); + break; +#ifdef WITH_DVB + case CX88_BOARD_HAUPPAUGE_DVB_T1: + if (0 == core->i2c_rc) + hauppauge_eeprom_dvb(core,eeprom); + break; + case CX88_BOARD_CONEXANT_DVB_T1: + core->pll_desc = &dvb_pll_thomson_dtt7579; + core->pll_addr = 0x60; + core->demod_addr = 0x43; break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: /* Tuner reset is hooked to the tuner out of reset */ @@ -845,17 +867,22 @@ void cx88_card_setup(struct cx88_core *c cx_clear(MO_GP0_IO, 0x00000001); msleep(1); cx_set(MO_GP0_IO, 0x00000101); + core->pll_addr = 0x61; + core->pll_desc = &dvb_pll_lg_z201; break; -#ifdef WITH_DVB - case CX88_BOARD_HAUPPAUGE_DVB_T1: - if (0 == core->i2c_rc) - i2c_eeprom(&core->i2c_client,eeprom,sizeof(eeprom)); - hauppauge_eeprom_dvb(core,eeprom); + case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: + core->pll_addr = 0x60; + core->pll_desc = &dvb_pll_thomson_dtt7579; break; - case CX88_BOARD_CONEXANT_DVB_T1: - core->pll_type = PLLTYPE_DTT7579; - core->pll_addr = 0x60; - core->demod_addr = 0x43; + case CX88_BOARD_DNTV_LIVE_DVB_T: + cx_set(MO_GP0_IO, 0x00000707); + cx_set(MO_GP2_IO, 0x00000101); + cx_clear(MO_GP2_IO, 0x00000001); + msleep(1); + cx_clear(MO_GP0_IO, 0x00000007); + cx_set(MO_GP2_IO, 0x00000101); + core->pll_addr = 0x61; + core->pll_desc = &dvb_pll_unknown_1; break; #endif } Index: linux-2004-12-16/drivers/media/video/cx88/cx88-core.c =================================================================== --- linux-2004-12-16.orig/drivers/media/video/cx88/cx88-core.c 2004-12-17 12:07:24.000000000 +0100 +++ linux-2004-12-16/drivers/media/video/cx88/cx88-core.c 2004-12-17 12:47:15.126291846 +0100 @@ -1,5 +1,5 @@ /* - * $Id: cx88-core.c,v 1.15 2004/10/25 11:26:36 kraxel Exp $ + * $Id: cx88-core.c,v 1.21 2004/12/10 12:33:39 kraxel Exp $ * * device driver for Conexant 2388x based TV cards * driver core @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -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(nicam,"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 * 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 /* ------------------------------------------------------------------ */ -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 *cor 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); @@ -969,6 +987,9 @@ int cx88_set_tvnorm(struct cx88_core *co 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 p 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,8 @@ struct cx88_core* cx88_core_get(struct p cx88_reset(core); cx88_i2c_init(core,pci); cx88_card_setup(core); + cx88_ir_init(core,pci); + cx_write(MO_PCI_INTMSK, core->pci_irqmask); up(&devlist); return core; @@ -1170,6 +1194,7 @@ void cx88_core_put(struct cx88_core *cor 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 +1212,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 +1222,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); Index: linux-2004-12-16/drivers/media/video/cx88/cx88-blackbird.c =================================================================== --- linux-2004-12-16.orig/drivers/media/video/cx88/cx88-blackbird.c 2004-12-17 12:09:05.000000000 +0100 +++ linux-2004-12-16/drivers/media/video/cx88/cx88-blackbird.c 2004-12-17 12:47:15.136289964 +0100 @@ -1,5 +1,5 @@ /* - * $Id: cx88-blackbird.c,v 1.17 2004/11/07 13:17:15 kraxel Exp $ + * $Id: cx88-blackbird.c,v 1.23 2004/12/10 12:33:39 kraxel Exp $ * * Support for a cx23416 mpeg encoder via cx2388x host port. * "blackbird" reference design. @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -207,10 +208,6 @@ static int register_write(struct cx88_co 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 cx88 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 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(str 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 *i 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 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 *in 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(str 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) Index: linux-2004-12-16/drivers/media/video/Kconfig =================================================================== --- linux-2004-12-16.orig/drivers/media/video/Kconfig 2004-12-17 12:47:08.871468650 +0100 +++ linux-2004-12-16/drivers/media/video/Kconfig 2004-12-17 12:47:43.205009038 +0100 @@ -309,6 +309,7 @@ config VIDEO_CX88 select VIDEO_BTCX select VIDEO_BUF select VIDEO_TUNER + select VIDEO_TVEEPROM ---help--- This is a video4linux driver for Conexant 2388x based TV cards. @@ -318,7 +319,7 @@ 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 ---help--- This adds support for DVB cards based on the Index: linux-2004-12-16/drivers/media/video/cx88/cx88-video.c =================================================================== --- linux-2004-12-16.orig/drivers/media/video/cx88/cx88-video.c 2004-12-17 12:08:16.000000000 +0100 +++ linux-2004-12-16/drivers/media/video/cx88/cx88-video.c 2004-12-17 12:47:15.148287707 +0100 @@ -1,5 +1,5 @@ /* - * $Id: cx88-video.c,v 1.46 2004/11/07 14:44:59 kraxel Exp $ + * $Id: cx88-video.c,v 1.50 2004/12/10 12:33:39 kraxel Exp $ * * device driver for Conexant 2388x based TV cards * video4linux video interface @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -428,7 +429,7 @@ static int start_video_dma(struct cx8800 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 */ @@ -1002,7 +1003,7 @@ static int video_open(struct inode *inod } 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 *i res_free(dev,fh,RESOURCE_VBI); } + videobuf_mmap_free(&fh->vidq); + videobuf_mmap_free(&fh->vbiq); file->private_data = NULL; kfree(fh); return 0; @@ -1880,19 +1883,18 @@ static irqreturn_t cx8800_irq(int irq, v { 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); }; Index: linux-2004-12-16/drivers/media/video/cx88/cx88-mpeg.c =================================================================== --- linux-2004-12-16.orig/drivers/media/video/cx88/cx88-mpeg.c 2004-12-17 12:09:55.000000000 +0100 +++ linux-2004-12-16/drivers/media/video/cx88/cx88-mpeg.c 2004-12-17 12:47:15.150287331 +0100 @@ -1,5 +1,5 @@ /* - * $Id: cx88-mpeg.c,v 1.14 2004/10/25 11:26:36 kraxel Exp $ + * $Id: cx88-mpeg.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $ * * Support for the mpeg transport stream transfers * PCI function #2 of the cx2388x. @@ -24,6 +24,7 @@ */ #include +#include #include #include #include @@ -93,7 +94,7 @@ static int cx8802_start_dma(struct cx880 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 +293,18 @@ static irqreturn_t cx8802_irq(int irq, v { 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); }; Index: linux-2004-12-16/drivers/media/video/cx88/cx88-tvaudio.c =================================================================== --- linux-2004-12-16.orig/drivers/media/video/cx88/cx88-tvaudio.c 2004-12-17 12:07:52.000000000 +0100 +++ linux-2004-12-16/drivers/media/video/cx88/cx88-tvaudio.c 2004-12-17 12:47:15.155286390 +0100 @@ -1,5 +1,5 @@ /* - $Id: cx88-tvaudio.c,v 1.24 2004/10/25 11:51:00 kraxel Exp $ + $Id: cx88-tvaudio.c,v 1.26 2004/12/10 12:33:39 kraxel Exp $ cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver @@ -37,6 +37,7 @@ */ #include +#include #include #include #include Index: linux-2004-12-16/drivers/media/video/cx88/cx88-dvb.c =================================================================== --- linux-2004-12-16.orig/drivers/media/video/cx88/cx88-dvb.c 2004-12-17 12:08:32.000000000 +0100 +++ linux-2004-12-16/drivers/media/video/cx88/cx88-dvb.c 2004-12-17 12:47:15.164284697 +0100 @@ -1,5 +1,5 @@ /* - * $Id: cx88-dvb.c,v 1.19 2004/11/07 14:44:59 kraxel Exp $ + * $Id: cx88-dvb.c,v 1.21 2004/12/09 12:51:35 kraxel Exp $ * * device driver for Conexant 2388x based TV cards * MPEG Transport Stream (DVB) routines @@ -31,6 +31,7 @@ #include #include "cx88.h" +#include "dvb-pll.h" #include "cx22702.h" #include "mt352.h" #include "mt352_priv.h" /* FIXME */ @@ -110,72 +111,52 @@ static int dvico_fusionhdtv_demod_init(s 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; - - 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; - - pllbuf[0] = 0xC2; /* Note: non-linux standard PLL I2C address */ - pllbuf[1] = div >> 8; - pllbuf[2] = div & 0xff; - pllbuf[3] = cp; - pllbuf[4] = bs; + 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 }; + + 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)); + + 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) -{ - 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; - +static int mt352_pll_set(struct dvb_frontend* fe, + struct dvb_frontend_parameters* params, + u8* pllbuf) +{ + 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, }; static int dvb_register(struct cx8802_dev *dev) @@ -189,32 +170,32 @@ static int dvb_register(struct cx8802_de 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->pll_desc, dev->core->demod_addr); break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: - dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dvbt1, + case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: + 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, + case CX88_BOARD_DNTV_LIVE_DVB_T: + dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config, &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; default: printk("%s: FIXME: frontend handling not here yet ...\n", 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 +203,7 @@ static int dvb_register(struct cx8802_de sizeof(dev->dvb.frontend->ops->info.name)); /* register everything */ - return videobuf_dvb_register(&dev->dvb); + return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); } /* ----------------------------------------------------------- */ Index: linux-2004-12-16/drivers/media/video/cx88/cx88-input.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2004-12-16/drivers/media/video/cx88/cx88-input.c 2004-12-17 12:47:15.165284509 +0100 @@ -0,0 +1,394 @@ +/* + * $Id: cx88-input.c,v 1.3 2004/12/10 12:33:39 kraxel Exp $ + * + * Device driver for GPIO attached remote control interfaces + * on Conexant 2388x based TV/DVB cards. + * + * Copyright (c) 2003 Pavel Machek + * Copyright (c) 2004 Gerd Knorr + * Copyright (c) 2004 Chris Pascoe + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "cx88.h" + +/* ---------------------------------------------------------------------- */ + +/* DigitalNow DNTV Live DVB-T Remote */ +static IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = { + [ 0x00 ] = KEY_ESC, // 'go up a level?' + [ 0x01 ] = KEY_KP1, // '1' + [ 0x02 ] = KEY_KP2, // '2' + [ 0x03 ] = KEY_KP3, // '3' + [ 0x04 ] = KEY_KP4, // '4' + [ 0x05 ] = KEY_KP5, // '5' + [ 0x06 ] = KEY_KP6, // '6' + [ 0x07 ] = KEY_KP7, // '7' + [ 0x08 ] = KEY_KP8, // '8' + [ 0x09 ] = KEY_KP9, // '9' + [ 0x0a ] = KEY_KP0, // '0' + [ 0x0b ] = KEY_TUNER, // 'tv/fm' + [ 0x0c ] = KEY_SEARCH, // 'scan' + [ 0x0d ] = KEY_STOP, // 'stop' + [ 0x0e ] = KEY_PAUSE, // 'pause' + [ 0x0f ] = KEY_LIST, // 'source' + + [ 0x10 ] = KEY_MUTE, // 'mute' + [ 0x11 ] = KEY_REWIND, // 'backward <<' + [ 0x12 ] = KEY_POWER, // 'power' + [ 0x13 ] = KEY_S, // 'snap' + [ 0x14 ] = KEY_AUDIO, // 'stereo' + [ 0x15 ] = KEY_CLEAR, // 'reset' + [ 0x16 ] = KEY_PLAY, // 'play' + [ 0x17 ] = KEY_ENTER, // 'enter' + [ 0x18 ] = KEY_ZOOM, // 'full screen' + [ 0x19 ] = KEY_FASTFORWARD, // 'forward >>' + [ 0x1a ] = KEY_CHANNELUP, // 'channel +' + [ 0x1b ] = KEY_VOLUMEUP, // 'volume +' + [ 0x1c ] = KEY_INFO, // 'preview' + [ 0x1d ] = KEY_RECORD, // 'record' + [ 0x1e ] = KEY_CHANNELDOWN, // 'channel -' + [ 0x1f ] = KEY_VOLUMEDOWN, // 'volume -' +}; + +/* ---------------------------------------------------------------------- */ + +struct cx88_IR { + struct cx88_core *core; + struct input_dev input; + struct ir_input_state ir; + char name[32]; + char phys[32]; + + /* sample from gpio pin 16 */ + int sampling; + u32 samples[16]; + int scount; + unsigned long release; + + /* poll external decoder */ + int polling; + struct work_struct work; + struct timer_list timer; + u32 gpio_addr; + u32 last_gpio; + u32 mask_keycode; + u32 mask_keydown; + u32 mask_keyup; +}; + +static int ir_debug = 0; +module_param(ir_debug, int, 0644); /* debug level [IR] */ +MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); + +#define ir_dprintk(fmt, arg...) if (ir_debug) \ + printk(KERN_DEBUG "%s IR: " fmt , ir->core->name, ## arg) + +/* ---------------------------------------------------------------------- */ + +static void cx88_ir_handle_key(struct cx88_IR *ir) +{ + struct cx88_core *core = ir->core; + u32 gpio, data; + + /* read gpio value */ + gpio = cx_read(ir->gpio_addr); + if (ir->polling) { + if (ir->last_gpio == gpio) + return; + ir->last_gpio = gpio; + } + + /* extract data */ + data = ir_extract_bits(gpio, ir->mask_keycode); + ir_dprintk("irq gpio=0x%x code=%d | %s%s%s\n", + gpio, data, + ir->polling ? "poll" : "irq", + (gpio & ir->mask_keydown) ? " down" : "", + (gpio & ir->mask_keyup) ? " up" : ""); + + if (ir->mask_keydown) { + /* bit set on keydown */ + if (gpio & ir->mask_keydown) { + ir_input_keydown(&ir->input,&ir->ir,data,data); + } else { + ir_input_nokey(&ir->input,&ir->ir); + } + + } else if (ir->mask_keyup) { + /* bit cleared on keydown */ + if (0 == (gpio & ir->mask_keyup)) { + ir_input_keydown(&ir->input,&ir->ir,data,data); + } else { + ir_input_nokey(&ir->input,&ir->ir); + } + + } else { + /* can't disturgissh keydown/up :-/ */ + ir_input_keydown(&ir->input,&ir->ir,data,data); + ir_input_nokey(&ir->input,&ir->ir); + } +} + +static void ir_timer(unsigned long data) +{ + struct cx88_IR *ir = (struct cx88_IR*)data; + + schedule_work(&ir->work); +} + +static void cx88_ir_work(void *data) +{ + struct cx88_IR *ir = data; + unsigned long timeout; + + cx88_ir_handle_key(ir); + timeout = jiffies + (ir->polling * HZ / 1000); + mod_timer(&ir->timer, timeout); +} + +/* ---------------------------------------------------------------------- */ + +int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) +{ + struct cx88_IR *ir; + IR_KEYTAB_TYPE *ir_codes = NULL; + int ir_type = IR_TYPE_OTHER; + + ir = kmalloc(sizeof(*ir),GFP_KERNEL); + if (NULL == ir) + return -ENOMEM; + memset(ir,0,sizeof(*ir)); + + /* detect & configure */ + switch (core->board) { + case CX88_BOARD_DNTV_LIVE_DVB_T: + ir_codes = ir_codes_dntv_live_dvb_t; + ir->gpio_addr = MO_GP1_IO; + ir->mask_keycode = 0x1f; + ir->mask_keyup = 0x60; + ir->polling = 50; // ms + break; + case CX88_BOARD_HAUPPAUGE: + case CX88_BOARD_HAUPPAUGE_DVB_T1: + ir_codes = ir_codes_rc5_tv; + ir_type = IR_TYPE_RC5; + ir->sampling = 1; + break; + } + if (NULL == ir_codes) { + kfree(ir); + return -ENODEV; + } + + /* init input device */ + snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", + cx88_boards[core->board].name); + snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", + pci_name(pci)); + + ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes); + ir->input.name = ir->name; + ir->input.phys = ir->phys; + ir->input.id.bustype = BUS_PCI; + ir->input.id.version = 1; + if (pci->subsystem_vendor) { + ir->input.id.vendor = pci->subsystem_vendor; + ir->input.id.product = pci->subsystem_device; + } else { + ir->input.id.vendor = pci->vendor; + ir->input.id.product = pci->device; + } + + /* record handles to ourself */ + ir->core = core; + core->ir = ir; + + if (ir->polling) { + INIT_WORK(&ir->work, cx88_ir_work, ir); + init_timer(&ir->timer); + ir->timer.function = ir_timer; + ir->timer.data = (unsigned long)ir; + schedule_work(&ir->work); + } + if (ir->sampling) { + core->pci_irqmask |= (1<<18); // IR_SMP_INT + cx_write(MO_DDS_IO, 0xa80a80); // 4 kHz sample rate + cx_write(MO_DDSCFG_IO, 0x5); // enable + } + + /* all done */ + input_register_device(&ir->input); + printk("%s: registered IR remote control\n", core->name); + + return 0; +} + +int cx88_ir_fini(struct cx88_core *core) +{ + struct cx88_IR *ir = core->ir; + + /* skip detach on non attached boards */ + if (NULL == ir) + return 0; + + if (ir->polling) { + del_timer(&ir->timer); + flush_scheduled_work(); + } + + input_unregister_device(&ir->input); + kfree(ir); + + /* done */ + core->ir = NULL; + return 0; +} + +/* ---------------------------------------------------------------------- */ + +static int inline getbit(u32 *samples, int bit) +{ + return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0; +} + +static int dump_samples(u32 *samples, int count) +{ + int i, bit, start; + + printk(KERN_DEBUG "ir samples @ 4kHz: "); + start = 0; + for (i = 0; i < count * 32; i++) { + bit = getbit(samples,i); + if (bit) + start = 1; + if (0 == start) + continue; + printk("%s", bit ? "#" : "_"); + } + printk("\n"); +} + +static int ir_decode_biphase(u32 *samples, int count, int low, int high) +{ + int i,last,bit,len,flips; + u32 value; + + /* find start bit (1) */ + for (i = 0; i < 32; i++) { + bit = getbit(samples,i); + if (bit) + break; + } + + /* go decoding */ + len = 0; + flips = 0; + value = 1; + for (; i < count * 32; i++) { + if (len > high) + break; + if (flips > 1) + break; + last = bit; + bit = getbit(samples,i); + if (last == bit) { + len++; + continue; + } + if (len < low) { + len++; + flips++; + continue; + } + value <<= 1; + value |= bit; + flips = 0; + len = 1; + } + return value; +} + +void cx88_ir_irq(struct cx88_core *core) +{ + struct cx88_IR *ir = core->ir; + u32 samples,rc5; + int i; + + if (NULL == ir) + return; + if (!ir->sampling) + return; + + samples = cx_read(MO_SAMPLE_IO); + if (0 != samples && 0xffffffff != samples) { + /* record sample data */ + if (ir->scount < ARRAY_SIZE(ir->samples)) + ir->samples[ir->scount++] = samples; + return; + } + if (!ir->scount) { + /* nothing to sample */ + if (ir->ir.keypressed && time_after(jiffies,ir->release)) + ir_input_nokey(&ir->input,&ir->ir); + return; + } + + /* have a complete sample */ + if (ir->scount < ARRAY_SIZE(ir->samples)) + ir->samples[ir->scount++] = samples; + for (i = 0; i < ir->scount; i++) + ir->samples[i] = ~ir->samples[i]; + if (ir_debug) + dump_samples(ir->samples,ir->scount); + + /* decode it */ + switch (core->board) { + case CX88_BOARD_HAUPPAUGE: + case CX88_BOARD_HAUPPAUGE_DVB_T1: + rc5 = ir_decode_biphase(ir->samples,ir->scount,5,7); + ir_dprintk("biphase decoded: %x\n",rc5); + if ((rc5 & 0xfffff000) != 0x3000) + break; + ir_input_keydown(&ir->input, &ir->ir, rc5 & 0x3f, rc5); + ir->release = jiffies + msecs_to_jiffies(120); + break; + } + + ir->scount = 0; + return; +} + +/* ---------------------------------------------------------------------- */ + +MODULE_AUTHOR("Gerd Knorr, Pavel Machek, Chris Pascoe"); +MODULE_DESCRIPTION("input driver for cx88 GPIO-based IR remote controls"); +MODULE_LICENSE("GPL"); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ Index: linux-2004-12-16/drivers/media/video/cx88/cx88-vbi.c =================================================================== --- linux-2004-12-16.orig/drivers/media/video/cx88/cx88-vbi.c 2004-12-17 12:08:00.000000000 +0100 +++ linux-2004-12-16/drivers/media/video/cx88/cx88-vbi.c 2004-12-17 12:47:15.166284321 +0100 @@ -1,8 +1,9 @@ /* - * $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 #include +#include #include #include @@ -64,7 +65,7 @@ int cx8800_start_vbi_dma(struct cx8800_d 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 */ Index: linux-2004-12-16/drivers/media/video/cx88/cx88.h =================================================================== --- linux-2004-12-16.orig/drivers/media/video/cx88/cx88.h 2004-12-17 12:09:48.000000000 +0100 +++ linux-2004-12-16/drivers/media/video/cx88/cx88.h 2004-12-17 12:47:15.169283757 +0100 @@ -1,5 +1,5 @@ /* - * $Id: cx88.h,v 1.40 2004/11/03 09:04:51 kraxel Exp $ + * $Id: cx88.h,v 1.47 2004/12/14 15:33:30 kraxel Exp $ * * v4l2 device driver for cx2388x based TV cards * @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -156,6 +157,8 @@ extern struct sram_channel cx88_sram_cha #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 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, @@ -238,6 +241,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,7 +256,7 @@ 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; @@ -262,6 +266,9 @@ struct cx88_core { u32 tvaudio; u32 input; u32 astat; + + /* IR remote control state */ + struct cx88_IR *ir; }; struct cx8800_dev; @@ -371,6 +378,8 @@ 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; @@ -411,7 +420,7 @@ extern void cx88_print_irqbits(char *nam 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); @@ -508,6 +517,13 @@ void cx88_set_stereo(struct cx88_core *c 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 */ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf); Index: linux-2004-12-16/drivers/media/video/cx88/Makefile =================================================================== --- linux-2004-12-16.orig/drivers/media/video/cx88/Makefile 2004-12-17 12:07:11.000000000 +0100 +++ linux-2004-12-16/drivers/media/video/cx88/Makefile 2004-12-17 12:47:15.177282252 +0100 @@ -1,4 +1,5 @@ -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 Index: linux-2004-12-16/drivers/media/video/cx88/cx88-i2c.c =================================================================== --- linux-2004-12-16.orig/drivers/media/video/cx88/cx88-i2c.c 2004-12-17 12:07:37.000000000 +0100 +++ linux-2004-12-16/drivers/media/video/cx88/cx88-i2c.c 2004-12-17 12:47:15.184280935 +0100 @@ -1,5 +1,5 @@ /* - $Id: cx88-i2c.c,v 1.18 2004/10/13 10:39:00 kraxel Exp $ + $Id: cx88-i2c.c,v 1.19 2004/12/10 12:33:39 kraxel Exp $ cx88-i2c.c -- all the i2c code is here @@ -25,6 +25,7 @@ */ #include +#include #include #include