diff options
Diffstat (limited to 'linux/drivers/media/dvb')
-rw-r--r-- | linux/drivers/media/dvb/b2c2/flexcop-hw-filter.c | 1 | ||||
-rw-r--r-- | linux/drivers/media/dvb/b2c2/flexcop-pci.c | 75 | ||||
-rw-r--r-- | linux/drivers/media/dvb/b2c2/flexcop.c | 3 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dm1105/dm1105.c | 233 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dmxdev.c | 16 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_demux.c | 16 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvbdev.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/Kconfig | 1 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/af9015.c | 43 | ||||
-rw-r--r-- | linux/drivers/media/dvb/frontends/cx24113.c | 2 | ||||
-rw-r--r-- | linux/drivers/media/dvb/frontends/cx24116.c | 5 | ||||
-rw-r--r-- | linux/drivers/media/dvb/frontends/cx24123.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/dvb/frontends/lgdt3304.c | 1 | ||||
-rw-r--r-- | linux/drivers/media/dvb/frontends/s921_module.c | 1 | ||||
-rw-r--r-- | linux/drivers/media/dvb/frontends/tda1004x.c | 30 |
15 files changed, 231 insertions, 204 deletions
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/linux/drivers/media/dvb/b2c2/flexcop-hw-filter.c index b386cc66c..451974ba3 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-hw-filter.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-hw-filter.c @@ -192,6 +192,7 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d return 0; } +EXPORT_SYMBOL(flexcop_pid_feed_control); void flexcop_hw_filter_init(struct flexcop_device *fc) { diff --git a/linux/drivers/media/dvb/b2c2/flexcop-pci.c b/linux/drivers/media/dvb/b2c2/flexcop-pci.c index 853a3ccff..5baf9ded9 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-pci.c @@ -13,9 +13,9 @@ static int enable_pid_filtering = 1; module_param(enable_pid_filtering, int, 0444); MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1"); -static int irq_chk_intv; +static int irq_chk_intv = 100; module_param(irq_chk_intv, int, 0644); -MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently just debugging)."); +MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog."); #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG #define dprintk(level,args...) \ @@ -34,7 +34,9 @@ MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently jus static int debug; module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debug level (1=info,2=regs,4=TS,8=irqdma (|-able))." DEBSTATUS); +MODULE_PARM_DESC(debug, + "set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))." + DEBSTATUS); #define DRIVER_VERSION "0.1" #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver" @@ -58,6 +60,8 @@ struct flexcop_pci { int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */ u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */ int count; + int count_prev; + int stream_problem; spinlock_t irq_lock; @@ -115,18 +119,44 @@ static void flexcop_pci_irq_check_work(struct work_struct *work) #endif struct flexcop_device *fc = fc_pci->fc_dev; - flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714); - - flexcop_dump_reg(fc_pci->fc_dev,dma1_000,4); + if (fc->feedcount) { +#if 0 + flexcop_ibi_value v = fc->read_ibi_reg(fc, sram_dest_reg_714); + deb_chk("net_ovflow_error: %d, media_ovflow_error: %d," + "cai_ovflow_error: %d, cao_ovflow_error: %d, " + "sram_dma: %d, maximumfill: %d\n", + v.sram_dest_reg_714.net_ovflow_error, + v.sram_dest_reg_714.media_ovflow_error, + v.sram_dest_reg_714.cai_ovflow_error, + v.sram_dest_reg_714.cao_ovflow_error, + v.sram_dest_reg_714.ctrl_sramdma, + v.sram_dest_reg_714.ctrl_maximumfill); +#endif - if (v.sram_dest_reg_714.net_ovflow_error) - deb_chk("sram net_ovflow_error\n"); - if (v.sram_dest_reg_714.media_ovflow_error) - deb_chk("sram media_ovflow_error\n"); - if (v.sram_dest_reg_714.cai_ovflow_error) - deb_chk("sram cai_ovflow_error\n"); - if (v.sram_dest_reg_714.cai_ovflow_error) - deb_chk("sram cai_ovflow_error\n"); + if (fc_pci->count == fc_pci->count_prev) { + deb_chk("no IRQ since the last check\n"); + if (fc_pci->stream_problem++ == 3) { + struct dvb_demux_feed *feed; + + spin_lock_irq(&fc->demux.lock); + list_for_each_entry(feed, &fc->demux.feed_list, + list_head) { + flexcop_pid_feed_control(fc, feed, 0); + } + + list_for_each_entry(feed, &fc->demux.feed_list, + list_head) { + flexcop_pid_feed_control(fc, feed, 1); + } + spin_unlock_irq(&fc->demux.lock); + + fc_pci->stream_problem = 0; + } + } else { + fc_pci->stream_problem = 0; + fc_pci->count_prev = fc_pci->count; + } + } schedule_delayed_work(&fc_pci->irq_check_work, msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); @@ -232,16 +262,12 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff) flexcop_dma_control_timer_irq(fc,FC_DMA_1,1); deb_irq("IRQ enabled\n"); + fc_pci->count_prev = fc_pci->count; + // fc_pci->active_dma1_addr = 0; // flexcop_dma_control_size_irq(fc,FC_DMA_1,1); - if (irq_chk_intv > 0) - schedule_delayed_work(&fc_pci->irq_check_work, - msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); } else { - if (irq_chk_intv > 0) - cancel_delayed_work(&fc_pci->irq_check_work); - flexcop_dma_control_timer_irq(fc,FC_DMA_1,0); deb_irq("IRQ disabled\n"); @@ -315,8 +341,6 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci) IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0) goto err_pci_iounmap; - - fc_pci->init_state |= FC_PCI_INIT; return ret; @@ -395,6 +419,10 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work); #endif + if (irq_chk_intv > 0) + schedule_delayed_work(&fc_pci->irq_check_work, + msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); + return ret; err_fc_exit: @@ -413,6 +441,9 @@ static void flexcop_pci_remove(struct pci_dev *pdev) { struct flexcop_pci *fc_pci = pci_get_drvdata(pdev); + if (irq_chk_intv > 0) + cancel_delayed_work(&fc_pci->irq_check_work); + flexcop_pci_dma_exit(fc_pci); flexcop_device_exit(fc_pci->fc_dev); flexcop_pci_exit(fc_pci); diff --git a/linux/drivers/media/dvb/b2c2/flexcop.c b/linux/drivers/media/dvb/b2c2/flexcop.c index 676413a91..91068952b 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop.c +++ b/linux/drivers/media/dvb/b2c2/flexcop.c @@ -212,8 +212,7 @@ void flexcop_reset_block_300(struct flexcop_device *fc) v210.sw_reset_210.Block_reset_enable = 0xb2; fc->write_ibi_reg(fc,sw_reset_210,v210); - msleep(1); - + udelay(1000); fc->write_ibi_reg(fc,ctrl_208,v208_save); } diff --git a/linux/drivers/media/dvb/dm1105/dm1105.c b/linux/drivers/media/dvb/dm1105/dm1105.c index b054d056d..5d8afefca 100644 --- a/linux/drivers/media/dvb/dm1105/dm1105.c +++ b/linux/drivers/media/dvb/dm1105/dm1105.c @@ -156,46 +156,12 @@ MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -static u16 ir_codes_dm1105_nec[128] = { - [0x0a] = KEY_Q, /*power*/ - [0x0c] = KEY_M, /*mute*/ - [0x11] = KEY_1, - [0x12] = KEY_2, - [0x13] = KEY_3, - [0x14] = KEY_4, - [0x15] = KEY_5, - [0x16] = KEY_6, - [0x17] = KEY_7, - [0x18] = KEY_8, - [0x19] = KEY_9, - [0x10] = KEY_0, - [0x1c] = KEY_PAGEUP, /*ch+*/ - [0x0f] = KEY_PAGEDOWN, /*ch-*/ - [0x1a] = KEY_O, /*vol+*/ - [0x0e] = KEY_Z, /*vol-*/ - [0x04] = KEY_R, /*rec*/ - [0x09] = KEY_D, /*fav*/ - [0x08] = KEY_BACKSPACE, /*rewind*/ - [0x07] = KEY_A, /*fast*/ - [0x0b] = KEY_P, /*pause*/ - [0x02] = KEY_ESC, /*cancel*/ - [0x03] = KEY_G, /*tab*/ - [0x00] = KEY_UP, /*up*/ - [0x1f] = KEY_ENTER, /*ok*/ - [0x01] = KEY_DOWN, /*down*/ - [0x05] = KEY_C, /*cap*/ - [0x06] = KEY_S, /*stop*/ - [0x40] = KEY_F, /*full*/ - [0x1e] = KEY_W, /*tvmode*/ - [0x1b] = KEY_B, /*recall*/ -}; - /* infrared remote control */ struct infrared { - u16 key_map[128]; struct input_dev *input_dev; + struct ir_input_state ir; char input_phys[32]; - struct tasklet_struct ir_tasklet; + struct work_struct work; u32 ir_command; }; @@ -220,10 +186,14 @@ struct dm1105dvb { /* i2c */ struct i2c_adapter i2c_adap; + /* irq */ + struct work_struct work; + /* dma */ dma_addr_t dma_addr; unsigned char *ts_buf; u32 wrp; + u32 nextwrp; u32 buffer_size; unsigned int PacketErrorCount; unsigned int dmarst; @@ -233,8 +203,6 @@ struct dm1105dvb { #define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg])) -static struct dm1105dvb *dm1105dvb_local; - static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { @@ -410,28 +378,72 @@ static int dm1105dvb_stop_feed(struct dvb_demux_feed *f) return 0; } -/* ir tasklet */ -static void dm1105_emit_key(unsigned long parm) +/* ir work handler */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void dm1105_emit_key(void *parm) +#else +static void dm1105_emit_key(struct work_struct *work) +#endif { - struct infrared *ir = (struct infrared *) parm; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + struct infrared *ir = parm; +#else + struct infrared *ir = container_of(work, struct infrared, work); +#endif u32 ircom = ir->ir_command; u8 data; - u16 keycode; + + if (ir_debug) + printk(KERN_INFO "%s: received byte 0x%04x\n", __func__, ircom); data = (ircom >> 8) & 0x7f; - input_event(ir->input_dev, EV_MSC, MSC_RAW, (0x0000f8 << 16) | data); - input_event(ir->input_dev, EV_MSC, MSC_SCAN, data); - keycode = ir->key_map[data]; + ir_input_keydown(ir->input_dev, &ir->ir, data, data); + ir_input_nokey(ir->input_dev, &ir->ir); +} - if (!keycode) - return; +/* work handler */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) +static void dm1105_dmx_buffer(void *_dm1105dvb) +#else +static void dm1105_dmx_buffer(struct work_struct *work) +#endif +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + struct dm1105dvb *dm1105dvb = _dm1105dvb; +#else + struct dm1105dvb *dm1105dvb = + container_of(work, struct dm1105dvb, work); +#endif + unsigned int nbpackets; + u32 oldwrp = dm1105dvb->wrp; + u32 nextwrp = dm1105dvb->nextwrp; + + if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) && + (dm1105dvb->ts_buf[oldwrp + 188] == 0x47) && + (dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) { + dm1105dvb->PacketErrorCount++; + /* bad packet found */ + if ((dm1105dvb->PacketErrorCount >= 2) && + (dm1105dvb->dmarst == 0)) { + outb(1, dm_io_mem(DM1105_RST)); + dm1105dvb->wrp = 0; + dm1105dvb->PacketErrorCount = 0; + dm1105dvb->dmarst = 0; + return; + } + } - input_event(ir->input_dev, EV_KEY, keycode, 1); - input_sync(ir->input_dev); - input_event(ir->input_dev, EV_KEY, keycode, 0); - input_sync(ir->input_dev); + if (nextwrp < oldwrp) { + memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size, + dm1105dvb->ts_buf, nextwrp); + nbpackets = ((dm1105dvb->buffer_size - oldwrp) + nextwrp) / 188; + } else + nbpackets = (nextwrp - oldwrp) / 188; + dm1105dvb->wrp = nextwrp; + dvb_dmx_swfilter_packets(&dm1105dvb->demux, + &dm1105dvb->ts_buf[oldwrp], nbpackets); } #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) @@ -441,11 +453,6 @@ static irqreturn_t dm1105dvb_irq(int irq, void *dev_id) #endif { struct dm1105dvb *dm1105dvb = dev_id; - unsigned int piece; - unsigned int nbpackets; - u32 command; - u32 nextwrp; - u32 oldwrp; /* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */ unsigned int intsts = inb(dm_io_mem(DM1105_INTSTS)); @@ -454,71 +461,25 @@ static irqreturn_t dm1105dvb_irq(int irq, void *dev_id) switch (intsts) { case INTSTS_TSIRQ: case (INTSTS_TSIRQ | INTSTS_IR): - nextwrp = inl(dm_io_mem(DM1105_WRP)) - - inl(dm_io_mem(DM1105_STADR)) ; - oldwrp = dm1105dvb->wrp; - spin_lock(&dm1105dvb->lock); - if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) && - (dm1105dvb->ts_buf[oldwrp + 188] == 0x47) && - (dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) { - dm1105dvb->PacketErrorCount++; - /* bad packet found */ - if ((dm1105dvb->PacketErrorCount >= 2) && - (dm1105dvb->dmarst == 0)) { - outb(1, dm_io_mem(DM1105_RST)); - dm1105dvb->wrp = 0; - dm1105dvb->PacketErrorCount = 0; - dm1105dvb->dmarst = 0; - spin_unlock(&dm1105dvb->lock); - return IRQ_HANDLED; - } - } - if (nextwrp < oldwrp) { - piece = dm1105dvb->buffer_size - oldwrp; - memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size, dm1105dvb->ts_buf, nextwrp); - nbpackets = (piece + nextwrp)/188; - } else { - nbpackets = (nextwrp - oldwrp)/188; - } - dvb_dmx_swfilter_packets(&dm1105dvb->demux, &dm1105dvb->ts_buf[oldwrp], nbpackets); - dm1105dvb->wrp = nextwrp; - spin_unlock(&dm1105dvb->lock); + dm1105dvb->nextwrp = inl(dm_io_mem(DM1105_WRP)) - + inl(dm_io_mem(DM1105_STADR)); + schedule_work(&dm1105dvb->work); break; case INTSTS_IR: - command = inl(dm_io_mem(DM1105_IRCODE)); - if (ir_debug) - printk("dm1105: received byte 0x%04x\n", command); - - dm1105dvb->ir.ir_command = command; - tasklet_schedule(&dm1105dvb->ir.ir_tasklet); + dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE)); + schedule_work(&dm1105dvb->ir.work); break; } - return IRQ_HANDLED; - - -} - -/* register with input layer */ -static void input_register_keys(struct infrared *ir) -{ - int i; - - memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit)); - for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) - set_bit(ir->key_map[i], ir->input_dev->keybit); - - ir->input_dev->keycode = ir->key_map; - ir->input_dev->keycodesize = sizeof(ir->key_map[0]); - ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map); + return IRQ_HANDLED; } int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) { struct input_dev *input_dev; - int err; - - dm1105dvb_local = dm1105; + IR_KEYTAB_TYPE *ir_codes = ir_codes_dm1105_nec; + int ir_type = IR_TYPE_OTHER; + int err = -ENOMEM; input_dev = input_allocate_device(); if (!input_dev) @@ -528,12 +489,11 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys), "pci-%s/ir0", pci_name(dm1105->pdev)); - input_dev->evbit[0] = BIT(EV_KEY); + ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes); input_dev->name = "DVB on-card IR receiver"; - input_dev->phys = dm1105->ir.input_phys; input_dev->id.bustype = BUS_PCI; - input_dev->id.version = 2; + input_dev->id.version = 1; if (dm1105->pdev->subsystem_vendor) { input_dev->id.vendor = dm1105->pdev->subsystem_vendor; input_dev->id.product = dm1105->pdev->subsystem_device; @@ -541,25 +501,31 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) input_dev->id.vendor = dm1105->pdev->vendor; input_dev->id.product = dm1105->pdev->device; } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) input_dev->dev.parent = &dm1105->pdev->dev; - /* initial keymap */ - memcpy(dm1105->ir.key_map, ir_codes_dm1105_nec, sizeof dm1105->ir.key_map); - input_register_keys(&dm1105->ir); +#else + input_dev->cdev.dev = &dm1105->pdev->dev; +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + INIT_WORK(&dm1105->ir.work, dm1105_emit_key, + (unsigned long) &dm1105->ir); +#else + INIT_WORK(&dm1105->ir.work, dm1105_emit_key); +#endif + err = input_register_device(input_dev); if (err) { input_free_device(input_dev); return err; } - tasklet_init(&dm1105->ir.ir_tasklet, dm1105_emit_key, (unsigned long) &dm1105->ir); - return 0; } - void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105) { - tasklet_kill(&dm1105->ir.ir_tasklet); input_unregister_device(dm1105->ir.input_dev); } @@ -717,7 +683,7 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL); if (!dm1105dvb) - goto out; + return -ENOMEM; dm1105dvb->pdev = pdev; dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES; @@ -747,13 +713,9 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, spin_lock_init(&dm1105dvb->lock); pci_set_drvdata(pdev, dm1105dvb); - ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, DRIVER_NAME, dm1105dvb); - if (ret < 0) - goto err_pci_iounmap; - ret = dm1105dvb_hw_init(dm1105dvb); if (ret < 0) - goto err_free_irq; + goto err_pci_iounmap; /* i2c */ i2c_set_adapdata(&dm1105dvb->i2c_adap, dm1105dvb); @@ -820,8 +782,19 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, dvb_net_init(dvb_adapter, &dm1105dvb->dvbnet, dmx); dm1105_ir_init(dm1105dvb); -out: - return ret; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) + INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer, dm1105dvb); +#else + INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer); +#endif + + ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, + DRIVER_NAME, dm1105dvb); + if (ret < 0) + goto err_free_irq; + + return 0; err_disconnect_frontend: dmx->disconnect_frontend(dmx); @@ -850,7 +823,7 @@ err_pci_disable_device: err_kfree: pci_set_drvdata(pdev, NULL); kfree(dm1105dvb); - goto out; + return ret; } static void __devexit dm1105_remove(struct pci_dev *pdev) diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c index cc143929a..c35fbb8d8 100644 --- a/linux/drivers/media/dvb/dvb-core/dmxdev.c +++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c @@ -364,16 +364,15 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, enum dmx_success success) { struct dmxdev_filter *dmxdevfilter = filter->priv; - unsigned long flags; int ret; if (dmxdevfilter->buffer.error) { wake_up(&dmxdevfilter->buffer.queue); return 0; } - spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); + spin_lock(&dmxdevfilter->dev->lock); if (dmxdevfilter->state != DMXDEV_STATE_GO) { - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); return 0; } del_timer(&dmxdevfilter->timer); @@ -392,7 +391,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, } if (dmxdevfilter->params.sec.flags & DMX_ONESHOT) dmxdevfilter->state = DMXDEV_STATE_DONE; - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); wake_up(&dmxdevfilter->buffer.queue); return 0; } @@ -404,12 +403,11 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, { struct dmxdev_filter *dmxdevfilter = feed->priv; struct dvb_ringbuffer *buffer; - unsigned long flags; int ret; - spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); + spin_lock(&dmxdevfilter->dev->lock); if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) { - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); return 0; } @@ -419,7 +417,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, else buffer = &dmxdevfilter->dev->dvr_buffer; if (buffer->error) { - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); wake_up(&buffer->queue); return 0; } @@ -430,7 +428,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, dvb_ringbuffer_flush(buffer); buffer->error = ret; } - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); wake_up(&buffer->queue); return 0; } diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.c b/linux/drivers/media/dvb/dvb-core/dvb_demux.c index a2c1fd5d2..e2eca0b1f 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.c @@ -399,9 +399,7 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count) { - unsigned long flags; - - spin_lock_irqsave(&demux->lock, flags); + spin_lock(&demux->lock); while (count--) { if (buf[0] == 0x47) @@ -409,17 +407,16 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, buf += 188; } - spin_unlock_irqrestore(&demux->lock, flags); + spin_unlock(&demux->lock); } EXPORT_SYMBOL(dvb_dmx_swfilter_packets); void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) { - unsigned long flags; int p = 0, i, j; - spin_lock_irqsave(&demux->lock, flags); + spin_lock(&demux->lock); if (demux->tsbufp) { i = demux->tsbufp; @@ -452,18 +449,17 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) } bailout: - spin_unlock_irqrestore(&demux->lock, flags); + spin_unlock(&demux->lock); } EXPORT_SYMBOL(dvb_dmx_swfilter); void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) { - unsigned long flags; int p = 0, i, j; u8 tmppack[188]; - spin_lock_irqsave(&demux->lock, flags); + spin_lock(&demux->lock); if (demux->tsbufp) { i = demux->tsbufp; @@ -504,7 +500,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) } bailout: - spin_unlock_irqrestore(&demux->lock, flags); + spin_unlock(&demux->lock); } EXPORT_SYMBOL(dvb_dmx_swfilter_204); diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c index 4609e3ebd..f6084e19d 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c @@ -83,7 +83,11 @@ static int dvb_device_open(struct inode *inode, struct file *file) file->private_data = dvbdev; old_fops = file->f_op; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17) file->f_op = fops_get(dvbdev->fops); +#else + file->f_op = (struct file_operations *)fops_get(dvbdev->fops); +#endif if (file->f_op == NULL) { file->f_op = old_fops; goto fail; diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index 49f7b20c2..bbddc9fb6 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -297,5 +297,6 @@ config DVB_USB_AF9015 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE help Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index e518d47fe..ca7609583 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -27,9 +27,7 @@ #include "qt1010.h" #include "tda18271.h" #include "mxl5005s.h" -#if 0 /* keep */ -#include "mc44s80x.h" -#endif +#include "mc44s803.h" static int dvb_usb_af9015_debug; module_param_named(debug, dvb_usb_af9015_debug, int, 0644); @@ -280,6 +278,21 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. req.data = &msg[i+1].buf[0]; ret = af9015_ctrl_msg(d, &req); i += 2; + } else if (msg[i].flags & I2C_M_RD) { + ret = -EINVAL; + if (msg[i].addr == + af9015_af9013_config[0].demod_address) + goto error; + else + req.cmd = READ_I2C; + req.i2c_addr = msg[i].addr; + req.addr = addr; + req.mbox = mbox; + req.addr_len = addr_len; + req.data_len = msg[i].len; + req.data = &msg[i].buf[0]; + ret = af9015_ctrl_msg(d, &req); + i += 1; } else { if (msg[i].addr == af9015_af9013_config[0].demod_address) @@ -942,7 +955,6 @@ static int af9015_read_config(struct usb_device *udev) switch (val) { case AF9013_TUNER_ENV77H11D5: case AF9013_TUNER_MT2060: - case AF9013_TUNER_MC44S803: case AF9013_TUNER_QT1010: case AF9013_TUNER_UNKNOWN: case AF9013_TUNER_MT2060_2: @@ -955,6 +967,10 @@ static int af9015_read_config(struct usb_device *udev) case AF9013_TUNER_MXL5005R: af9015_af9013_config[i].rf_spec_inv = 0; break; + case AF9013_TUNER_MC44S803: + af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO; + af9015_af9013_config[i].rf_spec_inv = 1; + break; default: warn("tuner id:%d not supported, please report!", val); return -ENODEV; @@ -1142,6 +1158,11 @@ static struct mxl5005s_config af9015_mxl5005_config = { .AgcMasterByte = 0x00, }; +static struct mc44s803_config af9015_mc44s803_config = { + .i2c_address = 0xc0, + .dig_out = 1, +}; + static int af9015_tuner_attach(struct dvb_usb_adapter *adap) { struct af9015_state *state = adap->dev->priv; @@ -1186,15 +1207,8 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) DVB_PLL_TDA665X) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_MC44S803: -#if 0 /* keep */ - ret = dvb_attach(mc44s80x_attach, adap->fe, i2c_adap) - == NULL ? -ENODEV : 0; -#else - ret = -ENODEV; - info("Freescale MC44S803 tuner found but no driver for that" \ - "tuner. Look at the Linuxtv.org for tuner driver" \ - "status."); -#endif + ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap, + &af9015_mc44s803_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_UNKNOWN: default: @@ -1493,9 +1507,6 @@ static void af9015_usb_device_exit(struct usb_interface *intf) /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver af9015_usb_driver = { -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 15) - .owner = THIS_MODULE, -#endif .name = "dvb_usb_af9015", .probe = af9015_usb_probe, .disconnect = af9015_usb_device_exit, diff --git a/linux/drivers/media/dvb/frontends/cx24113.c b/linux/drivers/media/dvb/frontends/cx24113.c index f6e7b0380..e4fd533a4 100644 --- a/linux/drivers/media/dvb/frontends/cx24113.c +++ b/linux/drivers/media/dvb/frontends/cx24113.c @@ -559,7 +559,7 @@ struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe, kzalloc(sizeof(struct cx24113_state), GFP_KERNEL); int rc; if (state == NULL) { - err("Unable to kmalloc\n"); + err("Unable to kzalloc\n"); goto error; } diff --git a/linux/drivers/media/dvb/frontends/cx24116.c b/linux/drivers/media/dvb/frontends/cx24116.c index 8301a9865..b5ff0b6a8 100644 --- a/linux/drivers/media/dvb/frontends/cx24116.c +++ b/linux/drivers/media/dvb/frontends/cx24116.c @@ -1112,13 +1112,10 @@ struct dvb_frontend *cx24116_attach(const struct cx24116_config *config, dprintk("%s\n", __func__); /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL); + state = kzalloc(sizeof(struct cx24116_state), GFP_KERNEL); if (state == NULL) goto error1; - /* setup the state */ - memset(state, 0, sizeof(struct cx24116_state)); - state->config = config; state->i2c = i2c; diff --git a/linux/drivers/media/dvb/frontends/cx24123.c b/linux/drivers/media/dvb/frontends/cx24123.c index c9cfc8393..f431f0c56 100644 --- a/linux/drivers/media/dvb/frontends/cx24123.c +++ b/linux/drivers/media/dvb/frontends/cx24123.c @@ -1084,13 +1084,13 @@ static struct dvb_frontend_ops cx24123_ops; struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, struct i2c_adapter *i2c) { + /* allocate memory for the internal state */ struct cx24123_state *state = kzalloc(sizeof(struct cx24123_state), GFP_KERNEL); dprintk("\n"); - /* allocate memory for the internal state */ if (state == NULL) { - err("Unable to kmalloc\n"); + err("Unable to kzalloc\n"); goto error; } diff --git a/linux/drivers/media/dvb/frontends/lgdt3304.c b/linux/drivers/media/dvb/frontends/lgdt3304.c index d56a799d3..3a4a18970 100644 --- a/linux/drivers/media/dvb/frontends/lgdt3304.c +++ b/linux/drivers/media/dvb/frontends/lgdt3304.c @@ -383,7 +383,6 @@ struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, struct lgdt3304_state *state; state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL); - memset(state, 0x0, sizeof(struct lgdt3304_state)); state->addr = config->i2c_address; state->i2c = i2c; diff --git a/linux/drivers/media/dvb/frontends/s921_module.c b/linux/drivers/media/dvb/frontends/s921_module.c index 8ae0676a5..4a673c184 100644 --- a/linux/drivers/media/dvb/frontends/s921_module.c +++ b/linux/drivers/media/dvb/frontends/s921_module.c @@ -233,7 +233,6 @@ struct dvb_frontend* s921_attach(const struct s921_config *config, struct s921_state *state; state = kzalloc(sizeof(struct s921_state), GFP_KERNEL); - memset(state, 0x0, sizeof(struct s921_state)); state->addr = config->i2c_address; state->i2c = i2c; diff --git a/linux/drivers/media/dvb/frontends/tda1004x.c b/linux/drivers/media/dvb/frontends/tda1004x.c index 1465ff77b..4981cef8b 100644 --- a/linux/drivers/media/dvb/frontends/tda1004x.c +++ b/linux/drivers/media/dvb/frontends/tda1004x.c @@ -162,7 +162,7 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg) if (ret != 2) { dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret); - return -1; + return -EINVAL; } dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__, @@ -481,16 +481,18 @@ static void tda10046_init_plls(struct dvb_frontend* fe) static int tda10046_fwupload(struct dvb_frontend* fe) { struct tda1004x_state* state = fe->demodulator_priv; - int ret; + int ret, confc4; const struct firmware *fw; /* reset + wake up chip */ if (state->config->xtal_freq == TDA10046_XTAL_4M) { - tda1004x_write_byteI(state, TDA1004X_CONFC4, 0); + confc4 = 0; } else { dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__); - tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80); + confc4 = 0x80; } + tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4); + tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); /* set GPIO 1 and 3 */ if (state->config->gpio_config != TDA10046_GPTRI) { @@ -508,13 +510,29 @@ static int tda10046_fwupload(struct dvb_frontend* fe) if (tda1004x_check_upload_ok(state) == 0) return 0; + /* + For i2c normal work, we need to slow down the bus speed. + However, the slow down breaks the eeprom firmware load. + So, use normal speed for eeprom booting and then restore the + i2c speed after that. Tested with MSI TV @nyware A/D board, + that comes with firmware version 29 inside their eeprom. + + It should also be noticed that no other I2C transfer should + be in course while booting from eeprom, otherwise, tda10046 + goes into an instable state. So, proper locking are needed + at the i2c bus master. + */ printk(KERN_INFO "tda1004x: trying to boot from eeprom\n"); - tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); + tda1004x_write_byteI(state, TDA1004X_CONFC4, 4); msleep(300); - /* don't re-upload unless necessary */ + tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4); + + /* Checks if eeprom firmware went without troubles */ if (tda1004x_check_upload_ok(state) == 0) return 0; + /* eeprom firmware didn't work. Load one manually. */ + if (state->config->request_firmware != NULL) { /* request the firmware, this will block until someone uploads it */ printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); |