summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb/ttpci
diff options
context:
space:
mode:
authorAndrew de Quincy <devnull@localhost>2004-03-11 18:40:44 +0000
committerAndrew de Quincy <devnull@localhost>2004-03-11 18:40:44 +0000
commit4881f248a09885725d1ad51ec35339ff4db2d81c (patch)
treef28e1ee6e7e472092c1a2a5e9ea55825c61f7c04 /linux/drivers/media/dvb/ttpci
parent455c6bb685dcf96d46dc80361513fc6476d541e7 (diff)
downloadmediapointer-dvb-s2-4881f248a09885725d1ad51ec35339ff4db2d81c.tar.gz
mediapointer-dvb-s2-4881f248a09885725d1ad51ec35339ff4db2d81c.tar.bz2
Checked in experimental frontend patch
Also some minimal budget-ci CI support implemented (just detection+IRQs)
Diffstat (limited to 'linux/drivers/media/dvb/ttpci')
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-ci.c136
1 files changed, 122 insertions, 14 deletions
diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c
index 601109de8..21162885b 100644
--- a/linux/drivers/media/dvb/ttpci/budget-ci.c
+++ b/linux/drivers/media/dvb/ttpci/budget-ci.c
@@ -6,6 +6,8 @@
* msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM>
* partially based on the Siemens DVB driver by Ralph+Marcus Metzler
*
+ * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
+ *
* 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
@@ -34,44 +36,86 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/input.h>
+#include <linux/spinlock.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
#include "input_fake.h"
#endif
+#define DEBIADDR_IR 0x1234
+#define DEBIADDR_CICONTROL 0x0000
+#define DEBIADDR_CIVERSION 0x4000
+#define DEBIADDR_CIIRQCONTROL 0x4000
+
struct budget_ci {
struct budget budget;
struct input_dev input_dev;
struct tasklet_struct msp430_irq_tasklet;
+ spinlock_t debilock;
+ int ci_present;
char ir_dev_name[50];
};
-static u32 budget_debiread4 (struct saa7146_dev *saa, u32 config, int addr, int count)
+static u32 budget_debiread (struct budget_ci* budget_ci, u32 config, int addr, int count)
{
- u32 result = 0;
-
+ struct saa7146_dev *saa = budget_ci->budget.dev;
+ u32 result = 0;
+
if (count > 4 || count <= 0)
return 0;
- if (saa7146_wait_for_debi_done(saa) < 0)
+ spin_lock(budget_ci->debilock);
+
+ if (saa7146_wait_for_debi_done(saa) < 0) {
+ spin_unlock(&budget_ci->debilock);
return 0;
-
+ }
+
saa7146_write (saa, DEBI_COMMAND,
(count << 17) | 0x10000 | (addr & 0xffff));
-
saa7146_write(saa, DEBI_CONFIG, config);
+ saa7146_write(saa, DEBI_PAGE, 0);
saa7146_write(saa, MC2, (2 << 16) | 2);
-
+
saa7146_wait_for_debi_done(saa);
- result = saa7146_read(saa, DEBI_AD);
+ result = saa7146_read(saa, 0x88);
result &= (0xffffffffUL >> ((4 - count) * 8));
+ spin_unlock(&budget_ci->debilock);
return result;
}
+static u8 budget_debiwrite (struct budget_ci* budget_ci, u32 config, int addr, int count, u32 value)
+{
+ struct saa7146_dev *saa = budget_ci->budget.dev;
+
+ if (count > 4 || count <= 0)
+ return 0;
+
+ spin_lock(&budget_ci->debilock);
+
+ if (saa7146_wait_for_debi_done(saa) < 0) {
+ spin_unlock(&budget_ci->debilock);
+ return 0;
+ }
+
+ saa7146_write (saa, DEBI_COMMAND,
+ (count << 17) | 0x00000 | (addr & 0xffff));
+ saa7146_write(saa, DEBI_CONFIG, config);
+ saa7146_write(saa, DEBI_PAGE, 0);
+ saa7146_write(saa, DEBI_AD, value);
+ saa7146_write(saa, MC2, (2 << 16) | 2);
+
+ saa7146_wait_for_debi_done(saa);
+
+ spin_unlock(&budget_ci->debilock);
+ return 0;
+}
+
+
/* from reading the following remotes:
Zenith Universal 7 / TV Mode 807 / VCR Mode 837
Hauppauge (from NOVA-CI-s box product)
@@ -147,9 +191,8 @@ static void msp430_ir_debounce (unsigned long data)
static void msp430_ir_interrupt (unsigned long data)
{
struct budget_ci *budget_ci = (struct budget_ci*) data;
- struct saa7146_dev *saa = budget_ci->budget.dev;
struct input_dev *dev = &budget_ci->input_dev;
- unsigned int code = budget_debiread4(saa, DEBINOSWAP, 0x1234, 2) >> 8;
+ unsigned int code = budget_debiread(budget_ci, DEBINOSWAP, DEBIADDR_IR, 2) >> 8;
if (code & 0x40) {
code &= 0x3f;
@@ -217,7 +260,6 @@ static void msp430_ir_deinit (struct budget_ci *budget_ci)
saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
- saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
if (del_timer(&dev->timer))
input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
@@ -225,6 +267,58 @@ static void msp430_ir_deinit (struct budget_ci *budget_ci)
input_unregister_device(dev);
}
+static int ciintf_init(struct budget_ci* budget_ci)
+{
+ struct saa7146_dev *saa = budget_ci->budget.dev;
+
+ // enable DEBI pins +transfers
+ saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x880 << 16) | 0x880);
+
+ // test if it is there
+ if ((budget_debiread(budget_ci, DEBICICTL, DEBIADDR_CIVERSION, 1) & 0xa0) != 0xa0) {
+ saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x880 << 16));
+ return -ENODEV;
+ }
+
+ // reset CI interface
+ budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, 0);
+ dvb_delay(1);
+ budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, 1);
+
+ // clear any CI interrupt status
+ budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CIIRQCONTROL, 1, 0xC0);
+
+ // FIXME: register CI slot
+
+ // Setup CI slot IRQ
+ saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
+ saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03);
+ budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, 0xc1);
+
+ // FIXME: route TS data out to CI interface
+// saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
+
+ // success!
+ printk("budget_ci: CI interface detected\n");
+ budget_ci->ci_present = 1;
+ return 0;
+}
+
+static void ciintf_deinit(struct budget_ci* budget_ci)
+{
+ struct saa7146_dev *saa = budget_ci->budget.dev;
+
+ // disable CI interrupts
+ budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, 0x1);
+ saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03);
+ saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
+
+ // FIXME: disable TS data stream to CI interface
+ saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
+
+ // disable DEBI pins+transfers again
+ saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x880 << 16));
+}
static void budget_ci_irq (struct saa7146_dev *dev, u32 *isr)
{
@@ -237,6 +331,9 @@ static void budget_ci_irq (struct saa7146_dev *dev, u32 *isr)
if (*isr & MASK_10)
ttpci_budget_irq10_handler (dev, isr);
+
+ if (*isr & MASK_03)
+ printk("CI IRQ!!\n");
}
@@ -252,6 +349,9 @@ static int budget_ci_attach (struct saa7146_dev* dev,
DEB_EE(("budget_ci: %p\n", budget_ci));
+ spin_lock_init(budget_ci->debilock);
+ budget_ci->ci_present = 0;
+
if ((err = ttpci_budget_init (&budget_ci->budget, dev, info))) {
kfree (budget_ci);
return err;
@@ -263,6 +363,8 @@ static int budget_ci_attach (struct saa7146_dev* dev,
(unsigned long) budget_ci);
msp430_ir_init (budget_ci);
+
+ ciintf_init(budget_ci);
return 0;
}
@@ -272,7 +374,8 @@ static int budget_ci_attach (struct saa7146_dev* dev,
static int budget_ci_detach (struct saa7146_dev* dev)
{
struct budget_ci *budget_ci = (struct budget_ci*) dev->ext_priv;
- int err;
+ struct saa7146_dev *saa = budget_ci->budget.dev;
+ int err;
err = ttpci_budget_deinit (&budget_ci->budget);
@@ -280,6 +383,11 @@ static int budget_ci_detach (struct saa7146_dev* dev)
msp430_ir_deinit (budget_ci);
+ if (budget_ci->ci_present) ciintf_deinit(budget_ci);
+
+ // disable frontend and CI interface
+ saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
+
kfree (budget_ci);
return err;
@@ -312,7 +420,7 @@ static struct saa7146_extension budget_extension = {
.attach = budget_ci_attach,
.detach = budget_ci_detach,
- .irq_mask = MASK_06 | MASK_10,
+ .irq_mask = MASK_03 | MASK_06 | MASK_10,
.irq_func = budget_ci_irq,
};
@@ -333,7 +441,7 @@ module_init(budget_ci_init);
module_exit(budget_ci_exit);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Michael Hunold, Jack Thomasson, others");
+MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
"budget PCI DVB cards w/ CI-module produced by "
"Siemens, Technotrend, Hauppauge");