summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb/ttpci-budget/budget.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/dvb/ttpci-budget/budget.c')
-rw-r--r--linux/drivers/media/dvb/ttpci-budget/budget.c198
1 files changed, 173 insertions, 25 deletions
diff --git a/linux/drivers/media/dvb/ttpci-budget/budget.c b/linux/drivers/media/dvb/ttpci-budget/budget.c
index 699dae456..545101f44 100644
--- a/linux/drivers/media/dvb/ttpci-budget/budget.c
+++ b/linux/drivers/media/dvb/ttpci-budget/budget.c
@@ -34,12 +34,177 @@
#define KBUILD_MODNAME budget
#endif
+
+
+static inline void ddelay(int i)
+{
+ current->state=TASK_INTERRUPTIBLE;
+ schedule_timeout((HZ*i)/100);
+}
+
+
+static
+void Set22K (struct budget *budget, int state)
+{
+ struct saa7146_dev *dev=budget->dev;
+ DEB_EE(("budget: %p\n",budget));
+ saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
+}
+
+
+/* Diseqc functions only for TT Budget card */
+/* taken from the Skyvision DVB driver by
+ Ralph Metzler <rjkm@metzlerbros.de> */
+
+static
+void DiseqcSendBit (struct budget *budget, int data)
+{
+ struct saa7146_dev *dev=budget->dev;
+ DEB_EE(("budget: %p\n",budget));
+
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+ udelay(data ? 500 : 1000);
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+ udelay(data ? 1000 : 500);
+}
+
+
+static
+void DiseqcSendByte (struct budget *budget, int data)
+{
+ int i, par=1, d;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ for (i=7; i>=0; i--) {
+ d = (data>>i)&1;
+ par ^= d;
+ DiseqcSendBit(budget, d);
+ }
+
+ DiseqcSendBit(budget, par);
+}
+
+
+static
+int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, int burst)
+{
+ struct saa7146_dev *dev=budget->dev;
+ int i;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+ mdelay(16);
+
+ for (i=0; i<len; i++)
+ DiseqcSendByte(budget, msg[i]);
+
+ mdelay(16);
+
+ if (burst!=-1) {
+ if (burst)
+ DiseqcSendByte(budget, 0xff);
+ else {
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+ udelay(12500);
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+ }
+ ddelay(2);
+ }
+
+ return 0;
+}
+
+
+int budget_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
+{
+ struct budget *budget = fe->before_after_data;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ switch (cmd) {
+ case FE_SET_TONE:
+ switch ((fe_sec_tone_mode_t) arg) {
+ case SEC_TONE_ON:
+ Set22K (budget, 1);
+ break;
+ case SEC_TONE_OFF:
+ Set22K (budget, 0);
+ break;
+ default:
+ return -EINVAL;
+ };
+ break;
+
+ case FE_DISEQC_SEND_MASTER_CMD:
+ {
+ struct dvb_diseqc_master_cmd *cmd = arg;
+
+ SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
+ break;
+ }
+
+ case FE_DISEQC_SEND_BURST:
+ SendDiSEqCMsg (budget, 0, NULL, (int) arg);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ };
+
+ return 0;
+}
+
+
+static
+int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
+{
+ struct budget *budget;
+ int err;
+
+ if (!(budget = kmalloc (sizeof(struct budget), GFP_KERNEL)))
+ return -ENOMEM;
+
+ DEB_EE(("budget: %p\n",budget));
+
+ if ((err = ttpci_budget_init (budget, dev, info))) {
+ kfree (budget);
+ return err;
+ }
+
+ dvb_add_frontend_ioctls (budget->dvb_adapter,
+ budget_diseqc_ioctl, NULL, budget);
+
+ dev->ext_priv = budget;
+
+ return 0;
+}
+
+
+static
+int budget_detach (struct saa7146_dev* dev)
+{
+ struct budget *budget = (struct budget*) dev->ext_priv;
+ int err;
+
+ dvb_remove_frontend_ioctls (budget->dvb_adapter,
+ budget_diseqc_ioctl, NULL);
+
+ err = ttpci_budget_deinit (budget);
+
+ kfree (budget);
+
+ return err;
+}
+
+
+
static struct saa7146_extension budget_extension;
MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT);
MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT);
MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
-MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC);
/* Uncomment for Budget Patch */
/*MAKE_BUDGET_INFO(fs_1_3,"Siemens/Technotrend/Hauppauge PCI rev1.3+Budget_Patch", BUDGET_PATCH);*/
@@ -51,31 +216,13 @@ struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003),
MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004),
MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005),
- MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
- MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
{
.vendor = 0,
}
};
-static
-int this_budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
-{
- struct budget_s *budget = NULL;
- DEB_EE(("budget: %p\n",budget));
- if( 0 != budget_attach(dev,info)) {
- return -1;
- }
- budget = (struct budget_s*)dev->ext_priv;
-
- // FIXME: cope with error here!
- budget_register(budget);
- printk(KERN_INFO "budget: found budget card '%s'.\n",budget->card->name);
-
- return 0;
-}
static
struct saa7146_extension budget_extension = {
@@ -84,12 +231,12 @@ struct saa7146_extension budget_extension = {
.ext_vv_data = NULL,
.module = THIS_MODULE,
- .pci_tbl = &pci_tbl[0],
- .attach = this_budget_attach,
+ .pci_tbl = pci_tbl,
+ .attach = budget_attach,
.detach = budget_detach,
.irq_mask = MASK_10,
- .irq_func = budget_irq,
+ .irq_func = ttpci_budget_irq10_handler,
};
@@ -113,7 +260,8 @@ void __exit budget_exit(void)
module_init(budget_init);
module_exit(budget_exit);
-MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB cards by "
- "Siemens, Technotrend, Hauppauge");
-MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
+MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
+ "budget PCI DVB cards by Siemens, Technotrend, Hauppauge");
+