diff options
Diffstat (limited to 'linux/drivers/media/dvb/ttpci')
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110.c | 29 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110.h | 2 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110_ir.c | 24 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110_v4l.c | 30 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/budget-av.c | 3 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/budget-ci.c | 48 |
6 files changed, 83 insertions, 53 deletions
diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c index 8440fd655..04c442286 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.c +++ b/linux/drivers/media/dvb/ttpci/av7110.c @@ -51,6 +51,7 @@ #include <linux/firmware.h> #include <linux/crc32.h> #include <linux/i2c.h> +#include <linux/kthread.h> #include <asm/system.h> @@ -223,11 +224,10 @@ static void recover_arm(struct av7110 *av7110) static void av7110_arm_sync(struct av7110 *av7110) { - av7110->arm_rmmod = 1; - wake_up_interruptible(&av7110->arm_wait); + if (av7110->arm_thread) + kthread_stop(av7110->arm_thread); - while (av7110->arm_thread) - msleep(1); + av7110->arm_thread = NULL; } static int arm_thread(void *data) @@ -238,17 +238,11 @@ static int arm_thread(void *data) dprintk(4, "%p\n",av7110); - lock_kernel(); - daemonize("arm_mon"); - sigfillset(¤t->blocked); - unlock_kernel(); - - av7110->arm_thread = current; - for (;;) { timeout = wait_event_interruptible_timeout(av7110->arm_wait, - av7110->arm_rmmod, 5 * HZ); - if (-ERESTARTSYS == timeout || av7110->arm_rmmod) { + kthread_should_stop(), 5 * HZ); + + if (-ERESTARTSYS == timeout || kthread_should_stop()) { /* got signal or told to quit*/ break; } @@ -276,7 +270,6 @@ static int arm_thread(void *data) av7110->arm_errors = 0; } - av7110->arm_thread = NULL; return 0; } @@ -2338,6 +2331,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, const int length = TS_WIDTH * TS_HEIGHT; struct pci_dev *pdev = dev->pci; struct av7110 *av7110; + struct task_struct *thread; int ret, count = 0; dprintk(4, "dev: %p\n", dev); @@ -2622,9 +2616,12 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. " "System might be unstable!\n", FW_VERSION(av7110->arm_app)); - ret = kernel_thread(arm_thread, (void *) av7110, 0); - if (ret < 0) + thread = kthread_run(arm_thread, (void *) av7110, "arm_mon"); + if (IS_ERR(thread)) { + ret = PTR_ERR(thread); goto err_stop_arm_9; + } + av7110->arm_thread = thread; /* set initial volume in mixer struct */ av7110->mixer.volume_left = volume; diff --git a/linux/drivers/media/dvb/ttpci/av7110.h b/linux/drivers/media/dvb/ttpci/av7110.h index c1fe289d3..cfec01b36 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.h +++ b/linux/drivers/media/dvb/ttpci/av7110.h @@ -39,7 +39,6 @@ #define ANALOG_TUNER_VES1820 1 #define ANALOG_TUNER_STV0297 2 -#define ANALOG_TUNER_VBI 0x100 extern int av7110_debug; @@ -221,7 +220,6 @@ struct av7110 { struct task_struct *arm_thread; wait_queue_head_t arm_wait; u16 arm_loops; - int arm_rmmod; void *debi_virt; dma_addr_t debi_bus; diff --git a/linux/drivers/media/dvb/ttpci/av7110_ir.c b/linux/drivers/media/dvb/ttpci/av7110_ir.c index e4544ea2b..54460acab 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_ir.c +++ b/linux/drivers/media/dvb/ttpci/av7110_ir.c @@ -4,6 +4,7 @@ #include <linux/moduleparam.h> #include <linux/input.h> #include <linux/proc_fs.h> +#include <linux/kernel.h> #include <asm/bitops.h> #include "av7110.h" @@ -16,6 +17,7 @@ static int av_cnt; static struct av7110 *av_list[4]; static struct input_dev *input_dev; +static char input_phys[32]; static u8 delay_timer_finished; @@ -217,7 +219,7 @@ int __devinit av7110_ir_init(struct av7110 *av7110) static struct proc_dir_entry *e; int err; - if (av_cnt >= sizeof av_list/sizeof av_list[0]) + if (av_cnt >= ARRAY_SIZE(av_list)) return -ENOSPC; av7110_setup_irc_config(av7110, 0x0001); @@ -231,8 +233,28 @@ int __devinit av7110_ir_init(struct av7110 *av7110) if (!input_dev) return -ENOMEM; + snprintf(input_phys, sizeof(input_phys), + "pci-%s/ir0", pci_name(av7110->dev->pci)); + input_dev->name = "DVB on-card IR receiver"; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + input_dev->phys = input_phys; + input_dev->id.bustype = BUS_PCI; + input_dev->id.version = 1; + if (av7110->dev->pci->subsystem_vendor) { + input_dev->id.vendor = av7110->dev->pci->subsystem_vendor; + input_dev->id.product = av7110->dev->pci->subsystem_device; + } else { + input_dev->id.vendor = av7110->dev->pci->vendor; + input_dev->id.product = av7110->dev->pci->device; + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) + input_dev->cdev.dev = &av7110->dev->pci->dev; +#else + input_dev->dev = &av7110->dev->pci->dev; +#endif +#endif set_bit(EV_KEY, input_dev->evbit); set_bit(EV_REP, input_dev->evbit); input_register_keys(); diff --git a/linux/drivers/media/dvb/ttpci/av7110_v4l.c b/linux/drivers/media/dvb/ttpci/av7110_v4l.c index 10cfe3131..3795432ad 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/linux/drivers/media/dvb/ttpci/av7110_v4l.c @@ -141,17 +141,6 @@ static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data) return 0; } -static int stv0297_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data) -{ - u8 buf [] = { reg, data }; - struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 2 }; - - if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1)) - return -1; - return 0; -} - - static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4]) { struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 }; @@ -194,6 +183,7 @@ static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq) static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq) { + struct av7110 *av7110 = (struct av7110*)dev->ext_priv; u32 div; u8 data[4]; @@ -214,8 +204,8 @@ static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq) else return -EINVAL; - stv0297_writereg(dev, 0x1C, 0x87, 0x78); - stv0297_writereg(dev, 0x1C, 0x86, 0xc8); + if (av7110->fe->ops.i2c_gate_ctrl) + av7110->fe->ops.i2c_gate_ctrl(av7110->fe, 1); return tuner_write(dev, 0x63, data); } @@ -818,20 +808,20 @@ int av7110_init_v4l(struct av7110 *av7110) saa7146_vv_release(dev); return -ENODEV; } - if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) { + if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) ERR(("cannot register vbi v4l2 device. skipping.\n")); - } else { - if (av7110->analog_tuner_flags) - av7110->analog_tuner_flags |= ANALOG_TUNER_VBI; - } return 0; } int av7110_exit_v4l(struct av7110 *av7110) { + struct saa7146_dev* dev = av7110->dev; + saa7146_unregister_device(&av7110->v4l_dev, av7110->dev); - if (av7110->analog_tuner_flags & ANALOG_TUNER_VBI) - saa7146_unregister_device(&av7110->vbi_dev, av7110->dev); + saa7146_unregister_device(&av7110->vbi_dev, av7110->dev); + + saa7146_vv_release(dev); + return 0; } diff --git a/linux/drivers/media/dvb/ttpci/budget-av.c b/linux/drivers/media/dvb/ttpci/budget-av.c index 89ab4b591..3035b224c 100644 --- a/linux/drivers/media/dvb/ttpci/budget-av.c +++ b/linux/drivers/media/dvb/ttpci/budget-av.c @@ -1089,6 +1089,8 @@ static int budget_av_detach(struct saa7146_dev *dev) msleep(200); saa7146_unregister_device(&budget_av->vd, dev); + + saa7146_vv_release(dev); } if (budget_av->budget.ci_present) @@ -1145,6 +1147,7 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) { /* fixme: proper cleanup here */ ERR(("cannot register capture v4l2 device.\n")); + saa7146_vv_release(dev); return err; } diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index b100cb485..7cb60e37b 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -29,8 +29,6 @@ * the project's page is at http://www.linuxtv.org/dvb/ */ -#include "budget.h" - #include <linux/module.h> #include <linux/errno.h> #include <linux/slab.h> @@ -39,6 +37,8 @@ #include <linux/spinlock.h> #include <media/ir-common.h> +#include "budget.h" + #include "dvb_ca_en50221.h" #include "stv0299.h" #include "stv0297.h" @@ -130,6 +130,7 @@ static void msp430_ir_interrupt(unsigned long data) int toggle; static int prev_toggle = -1; static u32 ir_key; + static int state = 0; u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; /* @@ -138,21 +139,34 @@ static void msp430_ir_interrupt(unsigned long data) * type1: X1CCCCCC, C = command bits (0 - 63) * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit * - * More than one command byte may be generated before the device byte - * Only when we have both, a correct keypress is generated + * Each signal from the remote control can generate one or more command + * bytes and one or more device bytes. For the repeated bytes, the + * highest bit (X) is set. The first command byte is always generated + * before the first device byte. Other than that, no specific order + * seems to apply. + * + * Only when we have a command and device byte, a keypress is + * generated. */ + if (ir_debug) + printk("budget_ci: received byte 0x%02x\n", command); + + /* Is this a repeated byte? */ + if (command & 0x80) + return; + /* Is this a RC5 command byte? */ if (command & 0x40) { - if (ir_debug) - printk("budget_ci: received command byte 0x%02x\n", command); + state = 1; ir_key = command & 0x3f; return; } /* It's a RC5 device byte */ - if (ir_debug) - printk("budget_ci: received device byte 0x%02x\n", command); + if (!state) + return; + state = 0; device = command & 0x1f; toggle = command & 0x20; @@ -267,15 +281,11 @@ static int msp430_ir_init(struct budget_ci *budget_ci) input_dev->timer.function = msp430_ir_keyup; input_dev->timer.data = (unsigned long) &budget_ci->ir; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) error = input_register_device(input_dev); if (error) { printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); goto out2; } -#else - input_register_device(input_dev); -#endif tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, (unsigned long) budget_ci); @@ -888,6 +898,17 @@ static struct tda1004x_config philips_tdm1316l_config = { .request_firmware = philips_tdm1316l_request_firmware, }; +static struct tda1004x_config philips_tdm1316l_config_invert = { + + .demod_address = 0x8, + .invert = 1, + .invert_oclk = 0, + .xtal_freq = TDA10046_XTAL_4M, + .agc_config = TDA10046_AGC_DEFAULT, + .if_freq = TDA10046_FREQ_3617, + .request_firmware = philips_tdm1316l_request_firmware, +}; + static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; @@ -1111,9 +1132,8 @@ static void frontend_init(struct budget_ci *budget_ci) case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt)) budget_ci->tuner_pll_address = 0x60; - philips_tdm1316l_config.invert = 1; budget_ci->budget.dvb_frontend = - dvb_attach(tda10046_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap); + dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap); if (budget_ci->budget.dvb_frontend) { budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init; budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; |