diff options
| author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
|---|---|---|
| committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
| commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
| tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/media/dvb/mantis | |
| parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) | |
Diffstat (limited to 'drivers/media/dvb/mantis')
44 files changed, 5387 insertions, 0 deletions
diff --git a/drivers/media/dvb/mantis/Kconfig b/drivers/media/dvb/mantis/Kconfig new file mode 100644 index 00000000000..a13a5050313 --- /dev/null +++ b/drivers/media/dvb/mantis/Kconfig | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | config MANTIS_CORE | ||
| 2 | tristate "Mantis/Hopper PCI bridge based devices" | ||
| 3 | depends on PCI && I2C && INPUT && RC_CORE | ||
| 4 | |||
| 5 | help | ||
| 6 | Support for PCI cards based on the Mantis and Hopper PCi bridge. | ||
| 7 | |||
| 8 | Say Y if you own such a device and want to use it. | ||
| 9 | |||
| 10 | config DVB_MANTIS | ||
| 11 | tristate "MANTIS based cards" | ||
| 12 | depends on MANTIS_CORE && DVB_CORE && PCI && I2C | ||
| 13 | select DVB_MB86A16 if !DVB_FE_CUSTOMISE | ||
| 14 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | ||
| 15 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | ||
| 16 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE | ||
| 17 | select DVB_STB0899 if !DVB_FE_CUSTOMISE | ||
| 18 | select DVB_STB6100 if !DVB_FE_CUSTOMISE | ||
| 19 | select DVB_TDA665x if !DVB_FE_CUSTOMISE | ||
| 20 | select DVB_TDA10021 if !DVB_FE_CUSTOMISE | ||
| 21 | select DVB_TDA10023 if !DVB_FE_CUSTOMISE | ||
| 22 | select DVB_PLL | ||
| 23 | help | ||
| 24 | Support for PCI cards based on the Mantis PCI bridge. | ||
| 25 | Say Y when you have a Mantis based DVB card and want to use it. | ||
| 26 | |||
| 27 | If unsure say N. | ||
| 28 | |||
| 29 | config DVB_HOPPER | ||
| 30 | tristate "HOPPER based cards" | ||
| 31 | depends on MANTIS_CORE && DVB_CORE && PCI && I2C | ||
| 32 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | ||
| 33 | select DVB_PLL | ||
| 34 | help | ||
| 35 | Support for PCI cards based on the Hopper PCI bridge. | ||
| 36 | Say Y when you have a Hopper based DVB card and want to use it. | ||
| 37 | |||
| 38 | If unsure say N | ||
diff --git a/drivers/media/dvb/mantis/Makefile b/drivers/media/dvb/mantis/Makefile new file mode 100644 index 00000000000..98dc5cd258a --- /dev/null +++ b/drivers/media/dvb/mantis/Makefile | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | mantis_core-objs := mantis_ioc.o \ | ||
| 2 | mantis_uart.o \ | ||
| 3 | mantis_dma.o \ | ||
| 4 | mantis_pci.o \ | ||
| 5 | mantis_i2c.o \ | ||
| 6 | mantis_dvb.o \ | ||
| 7 | mantis_evm.o \ | ||
| 8 | mantis_hif.o \ | ||
| 9 | mantis_ca.o \ | ||
| 10 | mantis_pcmcia.o \ | ||
| 11 | mantis_input.o | ||
| 12 | |||
| 13 | mantis-objs := mantis_cards.o \ | ||
| 14 | mantis_vp1033.o \ | ||
| 15 | mantis_vp1034.o \ | ||
| 16 | mantis_vp1041.o \ | ||
| 17 | mantis_vp2033.o \ | ||
| 18 | mantis_vp2040.o \ | ||
| 19 | mantis_vp3030.o | ||
| 20 | |||
| 21 | hopper-objs := hopper_cards.o \ | ||
| 22 | hopper_vp3028.o | ||
| 23 | |||
| 24 | obj-$(CONFIG_MANTIS_CORE) += mantis_core.o | ||
| 25 | obj-$(CONFIG_DVB_MANTIS) += mantis.o | ||
| 26 | obj-$(CONFIG_DVB_HOPPER) += hopper.o | ||
| 27 | |||
| 28 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | ||
diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/dvb/mantis/hopper_cards.c new file mode 100644 index 00000000000..1402062f2c8 --- /dev/null +++ b/drivers/media/dvb/mantis/hopper_cards.c | |||
| @@ -0,0 +1,278 @@ | |||
| 1 | /* | ||
| 2 | Hopper PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/moduleparam.h> | ||
| 23 | #include <linux/kernel.h> | ||
| 24 | #include <linux/pci.h> | ||
| 25 | #include <linux/slab.h> | ||
| 26 | #include <asm/irq.h> | ||
| 27 | #include <linux/interrupt.h> | ||
| 28 | |||
| 29 | #include "dmxdev.h" | ||
| 30 | #include "dvbdev.h" | ||
| 31 | #include "dvb_demux.h" | ||
| 32 | #include "dvb_frontend.h" | ||
| 33 | #include "dvb_net.h" | ||
| 34 | |||
| 35 | #include "mantis_common.h" | ||
| 36 | #include "hopper_vp3028.h" | ||
| 37 | #include "mantis_dma.h" | ||
| 38 | #include "mantis_dvb.h" | ||
| 39 | #include "mantis_uart.h" | ||
| 40 | #include "mantis_ioc.h" | ||
| 41 | #include "mantis_pci.h" | ||
| 42 | #include "mantis_i2c.h" | ||
| 43 | #include "mantis_reg.h" | ||
| 44 | |||
| 45 | static unsigned int verbose; | ||
| 46 | module_param(verbose, int, 0644); | ||
| 47 | MODULE_PARM_DESC(verbose, "verbose startup messages, default is 0 (no)"); | ||
| 48 | |||
| 49 | #define DRIVER_NAME "Hopper" | ||
| 50 | |||
| 51 | static char *label[10] = { | ||
| 52 | "DMA", | ||
| 53 | "IRQ-0", | ||
| 54 | "IRQ-1", | ||
| 55 | "OCERR", | ||
| 56 | "PABRT", | ||
| 57 | "RIPRR", | ||
| 58 | "PPERR", | ||
| 59 | "FTRGT", | ||
| 60 | "RISCI", | ||
| 61 | "RACK" | ||
| 62 | }; | ||
| 63 | |||
| 64 | static int devs; | ||
| 65 | |||
| 66 | static irqreturn_t hopper_irq_handler(int irq, void *dev_id) | ||
| 67 | { | ||
| 68 | u32 stat = 0, mask = 0, lstat = 0, mstat = 0; | ||
| 69 | u32 rst_stat = 0, rst_mask = 0; | ||
| 70 | |||
| 71 | struct mantis_pci *mantis; | ||
| 72 | struct mantis_ca *ca; | ||
| 73 | |||
| 74 | mantis = (struct mantis_pci *) dev_id; | ||
| 75 | if (unlikely(mantis == NULL)) { | ||
| 76 | dprintk(MANTIS_ERROR, 1, "Mantis == NULL"); | ||
| 77 | return IRQ_NONE; | ||
| 78 | } | ||
| 79 | ca = mantis->mantis_ca; | ||
| 80 | |||
| 81 | stat = mmread(MANTIS_INT_STAT); | ||
| 82 | mask = mmread(MANTIS_INT_MASK); | ||
| 83 | mstat = lstat = stat & ~MANTIS_INT_RISCSTAT; | ||
| 84 | if (!(stat & mask)) | ||
| 85 | return IRQ_NONE; | ||
| 86 | |||
| 87 | rst_mask = MANTIS_GPIF_WRACK | | ||
| 88 | MANTIS_GPIF_OTHERR | | ||
| 89 | MANTIS_SBUF_WSTO | | ||
| 90 | MANTIS_GPIF_EXTIRQ; | ||
| 91 | |||
| 92 | rst_stat = mmread(MANTIS_GPIF_STATUS); | ||
| 93 | rst_stat &= rst_mask; | ||
| 94 | mmwrite(rst_stat, MANTIS_GPIF_STATUS); | ||
| 95 | |||
| 96 | mantis->mantis_int_stat = stat; | ||
| 97 | mantis->mantis_int_mask = mask; | ||
| 98 | dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask); | ||
| 99 | if (stat & MANTIS_INT_RISCEN) { | ||
| 100 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]); | ||
| 101 | } | ||
| 102 | if (stat & MANTIS_INT_IRQ0) { | ||
| 103 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]); | ||
| 104 | mantis->gpif_status = rst_stat; | ||
| 105 | wake_up(&ca->hif_write_wq); | ||
| 106 | schedule_work(&ca->hif_evm_work); | ||
| 107 | } | ||
| 108 | if (stat & MANTIS_INT_IRQ1) { | ||
| 109 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); | ||
| 110 | schedule_work(&mantis->uart_work); | ||
| 111 | } | ||
| 112 | if (stat & MANTIS_INT_OCERR) { | ||
| 113 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]); | ||
| 114 | } | ||
| 115 | if (stat & MANTIS_INT_PABORT) { | ||
| 116 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]); | ||
| 117 | } | ||
| 118 | if (stat & MANTIS_INT_RIPERR) { | ||
| 119 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]); | ||
| 120 | } | ||
| 121 | if (stat & MANTIS_INT_PPERR) { | ||
| 122 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]); | ||
| 123 | } | ||
| 124 | if (stat & MANTIS_INT_FTRGT) { | ||
| 125 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]); | ||
| 126 | } | ||
| 127 | if (stat & MANTIS_INT_RISCI) { | ||
| 128 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); | ||
| 129 | mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28; | ||
| 130 | tasklet_schedule(&mantis->tasklet); | ||
| 131 | } | ||
| 132 | if (stat & MANTIS_INT_I2CDONE) { | ||
| 133 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]); | ||
| 134 | wake_up(&mantis->i2c_wq); | ||
| 135 | } | ||
| 136 | mmwrite(stat, MANTIS_INT_STAT); | ||
| 137 | stat &= ~(MANTIS_INT_RISCEN | MANTIS_INT_I2CDONE | | ||
| 138 | MANTIS_INT_I2CRACK | MANTIS_INT_PCMCIA7 | | ||
| 139 | MANTIS_INT_PCMCIA6 | MANTIS_INT_PCMCIA5 | | ||
| 140 | MANTIS_INT_PCMCIA4 | MANTIS_INT_PCMCIA3 | | ||
| 141 | MANTIS_INT_PCMCIA2 | MANTIS_INT_PCMCIA1 | | ||
| 142 | MANTIS_INT_PCMCIA0 | MANTIS_INT_IRQ1 | | ||
| 143 | MANTIS_INT_IRQ0 | MANTIS_INT_OCERR | | ||
| 144 | MANTIS_INT_PABORT | MANTIS_INT_RIPERR | | ||
| 145 | MANTIS_INT_PPERR | MANTIS_INT_FTRGT | | ||
| 146 | MANTIS_INT_RISCI); | ||
| 147 | |||
| 148 | if (stat) | ||
| 149 | dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask); | ||
| 150 | |||
| 151 | dprintk(MANTIS_DEBUG, 0, "\n"); | ||
| 152 | return IRQ_HANDLED; | ||
| 153 | } | ||
| 154 | |||
| 155 | static int __devinit hopper_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | ||
| 156 | { | ||
| 157 | struct mantis_pci *mantis; | ||
| 158 | struct mantis_hwconfig *config; | ||
| 159 | int err = 0; | ||
| 160 | |||
| 161 | mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL); | ||
| 162 | if (mantis == NULL) { | ||
| 163 | printk(KERN_ERR "%s ERROR: Out of memory\n", __func__); | ||
| 164 | err = -ENOMEM; | ||
| 165 | goto fail0; | ||
| 166 | } | ||
| 167 | |||
| 168 | mantis->num = devs; | ||
| 169 | mantis->verbose = verbose; | ||
| 170 | mantis->pdev = pdev; | ||
| 171 | config = (struct mantis_hwconfig *) pci_id->driver_data; | ||
| 172 | config->irq_handler = &hopper_irq_handler; | ||
| 173 | mantis->hwconfig = config; | ||
| 174 | |||
| 175 | err = mantis_pci_init(mantis); | ||
| 176 | if (err) { | ||
| 177 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err); | ||
| 178 | goto fail1; | ||
| 179 | } | ||
| 180 | |||
| 181 | err = mantis_stream_control(mantis, STREAM_TO_HIF); | ||
| 182 | if (err < 0) { | ||
| 183 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err); | ||
| 184 | goto fail1; | ||
| 185 | } | ||
| 186 | |||
| 187 | err = mantis_i2c_init(mantis); | ||
| 188 | if (err < 0) { | ||
| 189 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err); | ||
| 190 | goto fail2; | ||
| 191 | } | ||
| 192 | |||
| 193 | err = mantis_get_mac(mantis); | ||
| 194 | if (err < 0) { | ||
| 195 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err); | ||
| 196 | goto fail2; | ||
| 197 | } | ||
| 198 | |||
| 199 | err = mantis_dma_init(mantis); | ||
| 200 | if (err < 0) { | ||
| 201 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err); | ||
| 202 | goto fail3; | ||
| 203 | } | ||
| 204 | |||
| 205 | err = mantis_dvb_init(mantis); | ||
| 206 | if (err < 0) { | ||
| 207 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err); | ||
| 208 | goto fail4; | ||
| 209 | } | ||
| 210 | devs++; | ||
| 211 | |||
| 212 | return err; | ||
| 213 | |||
| 214 | fail4: | ||
| 215 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err); | ||
| 216 | mantis_dma_exit(mantis); | ||
| 217 | |||
| 218 | fail3: | ||
| 219 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err); | ||
| 220 | mantis_i2c_exit(mantis); | ||
| 221 | |||
| 222 | fail2: | ||
| 223 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err); | ||
| 224 | mantis_pci_exit(mantis); | ||
| 225 | |||
| 226 | fail1: | ||
| 227 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err); | ||
| 228 | kfree(mantis); | ||
| 229 | |||
| 230 | fail0: | ||
| 231 | return err; | ||
| 232 | } | ||
| 233 | |||
| 234 | static void __devexit hopper_pci_remove(struct pci_dev *pdev) | ||
| 235 | { | ||
| 236 | struct mantis_pci *mantis = pci_get_drvdata(pdev); | ||
| 237 | |||
| 238 | if (mantis) { | ||
| 239 | mantis_dvb_exit(mantis); | ||
| 240 | mantis_dma_exit(mantis); | ||
| 241 | mantis_i2c_exit(mantis); | ||
| 242 | mantis_pci_exit(mantis); | ||
| 243 | kfree(mantis); | ||
| 244 | } | ||
| 245 | return; | ||
| 246 | |||
| 247 | } | ||
| 248 | |||
| 249 | static struct pci_device_id hopper_pci_table[] = { | ||
| 250 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config), | ||
| 251 | { } | ||
| 252 | }; | ||
| 253 | |||
| 254 | MODULE_DEVICE_TABLE(pci, hopper_pci_table); | ||
| 255 | |||
| 256 | static struct pci_driver hopper_pci_driver = { | ||
| 257 | .name = DRIVER_NAME, | ||
| 258 | .id_table = hopper_pci_table, | ||
| 259 | .probe = hopper_pci_probe, | ||
| 260 | .remove = hopper_pci_remove, | ||
| 261 | }; | ||
| 262 | |||
| 263 | static int __devinit hopper_init(void) | ||
| 264 | { | ||
| 265 | return pci_register_driver(&hopper_pci_driver); | ||
| 266 | } | ||
| 267 | |||
| 268 | static void __devexit hopper_exit(void) | ||
| 269 | { | ||
| 270 | return pci_unregister_driver(&hopper_pci_driver); | ||
| 271 | } | ||
| 272 | |||
| 273 | module_init(hopper_init); | ||
| 274 | module_exit(hopper_exit); | ||
| 275 | |||
| 276 | MODULE_DESCRIPTION("HOPPER driver"); | ||
| 277 | MODULE_AUTHOR("Manu Abraham"); | ||
| 278 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/mantis/hopper_vp3028.c b/drivers/media/dvb/mantis/hopper_vp3028.c new file mode 100644 index 00000000000..68a29f8bdf7 --- /dev/null +++ b/drivers/media/dvb/mantis/hopper_vp3028.c | |||
| @@ -0,0 +1,88 @@ | |||
| 1 | /* | ||
| 2 | Hopper VP-3028 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/signal.h> | ||
| 22 | #include <linux/sched.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | |||
| 25 | #include "dmxdev.h" | ||
| 26 | #include "dvbdev.h" | ||
| 27 | #include "dvb_demux.h" | ||
| 28 | #include "dvb_frontend.h" | ||
| 29 | #include "dvb_net.h" | ||
| 30 | |||
| 31 | #include "zl10353.h" | ||
| 32 | #include "mantis_common.h" | ||
| 33 | #include "mantis_ioc.h" | ||
| 34 | #include "mantis_dvb.h" | ||
| 35 | #include "hopper_vp3028.h" | ||
| 36 | |||
| 37 | struct zl10353_config hopper_vp3028_config = { | ||
| 38 | .demod_address = 0x0f, | ||
| 39 | }; | ||
| 40 | |||
| 41 | #define MANTIS_MODEL_NAME "VP-3028" | ||
| 42 | #define MANTIS_DEV_TYPE "DVB-T" | ||
| 43 | |||
| 44 | static int vp3028_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
| 45 | { | ||
| 46 | struct i2c_adapter *adapter = &mantis->adapter; | ||
| 47 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
| 48 | int err = 0; | ||
| 49 | |||
| 50 | mantis_gpio_set_bits(mantis, config->reset, 0); | ||
| 51 | msleep(100); | ||
| 52 | err = mantis_frontend_power(mantis, POWER_ON); | ||
| 53 | msleep(100); | ||
| 54 | mantis_gpio_set_bits(mantis, config->reset, 1); | ||
| 55 | |||
| 56 | err = mantis_frontend_power(mantis, POWER_ON); | ||
| 57 | if (err == 0) { | ||
| 58 | msleep(250); | ||
| 59 | dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)"); | ||
| 60 | fe = dvb_attach(zl10353_attach, &hopper_vp3028_config, adapter); | ||
| 61 | |||
| 62 | if (!fe) | ||
| 63 | return -1; | ||
| 64 | } else { | ||
| 65 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
| 66 | adapter->name, | ||
| 67 | err); | ||
| 68 | |||
| 69 | return -EIO; | ||
| 70 | } | ||
| 71 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
| 72 | |||
| 73 | return 0; | ||
| 74 | } | ||
| 75 | |||
| 76 | struct mantis_hwconfig vp3028_config = { | ||
| 77 | .model_name = MANTIS_MODEL_NAME, | ||
| 78 | .dev_type = MANTIS_DEV_TYPE, | ||
| 79 | .ts_size = MANTIS_TS_188, | ||
| 80 | |||
| 81 | .baud_rate = MANTIS_BAUD_9600, | ||
| 82 | .parity = MANTIS_PARITY_NONE, | ||
| 83 | .bytes = 0, | ||
| 84 | |||
| 85 | .frontend_init = vp3028_frontend_init, | ||
| 86 | .power = GPIF_A00, | ||
| 87 | .reset = GPIF_A03, | ||
| 88 | }; | ||
diff --git a/drivers/media/dvb/mantis/hopper_vp3028.h b/drivers/media/dvb/mantis/hopper_vp3028.h new file mode 100644 index 00000000000..57239498bc8 --- /dev/null +++ b/drivers/media/dvb/mantis/hopper_vp3028.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | Hopper VP-3028 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_VP3028_H | ||
| 22 | #define __MANTIS_VP3028_H | ||
| 23 | |||
| 24 | #include "mantis_common.h" | ||
| 25 | |||
| 26 | #define MANTIS_VP_3028_DVB_T 0x0028 | ||
| 27 | |||
| 28 | extern struct mantis_hwconfig vp3028_config; | ||
| 29 | |||
| 30 | #endif /* __MANTIS_VP3028_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_ca.c b/drivers/media/dvb/mantis/mantis_ca.c new file mode 100644 index 00000000000..3d704690900 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_ca.c | |||
| @@ -0,0 +1,209 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/signal.h> | ||
| 22 | #include <linux/slab.h> | ||
| 23 | #include <linux/sched.h> | ||
| 24 | #include <linux/interrupt.h> | ||
| 25 | #include <asm/io.h> | ||
| 26 | |||
| 27 | #include "dmxdev.h" | ||
| 28 | #include "dvbdev.h" | ||
| 29 | #include "dvb_demux.h" | ||
| 30 | #include "dvb_frontend.h" | ||
| 31 | #include "dvb_net.h" | ||
| 32 | |||
| 33 | #include "mantis_common.h" | ||
| 34 | #include "mantis_link.h" | ||
| 35 | #include "mantis_hif.h" | ||
| 36 | #include "mantis_reg.h" | ||
| 37 | |||
| 38 | #include "mantis_ca.h" | ||
| 39 | |||
| 40 | static int mantis_ca_read_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr) | ||
| 41 | { | ||
| 42 | struct mantis_ca *ca = en50221->data; | ||
| 43 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 44 | |||
| 45 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Read", slot); | ||
| 46 | |||
| 47 | if (slot != 0) | ||
| 48 | return -EINVAL; | ||
| 49 | |||
| 50 | return mantis_hif_read_mem(ca, addr); | ||
| 51 | } | ||
| 52 | |||
| 53 | static int mantis_ca_write_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr, u8 data) | ||
| 54 | { | ||
| 55 | struct mantis_ca *ca = en50221->data; | ||
| 56 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 57 | |||
| 58 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Write", slot); | ||
| 59 | |||
| 60 | if (slot != 0) | ||
| 61 | return -EINVAL; | ||
| 62 | |||
| 63 | return mantis_hif_write_mem(ca, addr, data); | ||
| 64 | } | ||
| 65 | |||
| 66 | static int mantis_ca_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr) | ||
| 67 | { | ||
| 68 | struct mantis_ca *ca = en50221->data; | ||
| 69 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 70 | |||
| 71 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Read", slot); | ||
| 72 | |||
| 73 | if (slot != 0) | ||
| 74 | return -EINVAL; | ||
| 75 | |||
| 76 | return mantis_hif_read_iom(ca, addr); | ||
| 77 | } | ||
| 78 | |||
| 79 | static int mantis_ca_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr, u8 data) | ||
| 80 | { | ||
| 81 | struct mantis_ca *ca = en50221->data; | ||
| 82 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 83 | |||
| 84 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Write", slot); | ||
| 85 | |||
| 86 | if (slot != 0) | ||
| 87 | return -EINVAL; | ||
| 88 | |||
| 89 | return mantis_hif_write_iom(ca, addr, data); | ||
| 90 | } | ||
| 91 | |||
| 92 | static int mantis_ca_slot_reset(struct dvb_ca_en50221 *en50221, int slot) | ||
| 93 | { | ||
| 94 | struct mantis_ca *ca = en50221->data; | ||
| 95 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 96 | |||
| 97 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot RESET", slot); | ||
| 98 | udelay(500); /* Wait.. */ | ||
| 99 | mmwrite(0xda, MANTIS_PCMCIA_RESET); /* Leading edge assert */ | ||
| 100 | udelay(500); | ||
| 101 | mmwrite(0x00, MANTIS_PCMCIA_RESET); /* Trailing edge deassert */ | ||
| 102 | msleep(1000); | ||
| 103 | dvb_ca_en50221_camready_irq(&ca->en50221, 0); | ||
| 104 | |||
| 105 | return 0; | ||
| 106 | } | ||
| 107 | |||
| 108 | static int mantis_ca_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot) | ||
| 109 | { | ||
| 110 | struct mantis_ca *ca = en50221->data; | ||
| 111 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 112 | |||
| 113 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot shutdown", slot); | ||
| 114 | |||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | |||
| 118 | static int mantis_ts_control(struct dvb_ca_en50221 *en50221, int slot) | ||
| 119 | { | ||
| 120 | struct mantis_ca *ca = en50221->data; | ||
| 121 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 122 | |||
| 123 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): TS control", slot); | ||
| 124 | /* mantis_set_direction(mantis, 1); */ /* Enable TS through CAM */ | ||
| 125 | |||
| 126 | return 0; | ||
| 127 | } | ||
| 128 | |||
| 129 | static int mantis_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open) | ||
| 130 | { | ||
| 131 | struct mantis_ca *ca = en50221->data; | ||
| 132 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 133 | |||
| 134 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Poll Slot status", slot); | ||
| 135 | |||
| 136 | if (ca->slot_state == MODULE_INSERTED) { | ||
| 137 | dprintk(MANTIS_DEBUG, 1, "CA Module present and ready"); | ||
| 138 | return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; | ||
| 139 | } else { | ||
| 140 | dprintk(MANTIS_DEBUG, 1, "CA Module not present or not ready"); | ||
| 141 | } | ||
| 142 | |||
| 143 | return 0; | ||
| 144 | } | ||
| 145 | |||
| 146 | int mantis_ca_init(struct mantis_pci *mantis) | ||
| 147 | { | ||
| 148 | struct dvb_adapter *dvb_adapter = &mantis->dvb_adapter; | ||
| 149 | struct mantis_ca *ca; | ||
| 150 | int ca_flags = 0, result; | ||
| 151 | |||
| 152 | dprintk(MANTIS_DEBUG, 1, "Initializing Mantis CA"); | ||
| 153 | ca = kzalloc(sizeof(struct mantis_ca), GFP_KERNEL); | ||
| 154 | if (!ca) { | ||
| 155 | dprintk(MANTIS_ERROR, 1, "Out of memory!, exiting .."); | ||
| 156 | result = -ENOMEM; | ||
| 157 | goto err; | ||
| 158 | } | ||
| 159 | |||
| 160 | ca->ca_priv = mantis; | ||
| 161 | mantis->mantis_ca = ca; | ||
| 162 | ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE; | ||
| 163 | /* register CA interface */ | ||
| 164 | ca->en50221.owner = THIS_MODULE; | ||
| 165 | ca->en50221.read_attribute_mem = mantis_ca_read_attr_mem; | ||
| 166 | ca->en50221.write_attribute_mem = mantis_ca_write_attr_mem; | ||
| 167 | ca->en50221.read_cam_control = mantis_ca_read_cam_ctl; | ||
| 168 | ca->en50221.write_cam_control = mantis_ca_write_cam_ctl; | ||
| 169 | ca->en50221.slot_reset = mantis_ca_slot_reset; | ||
| 170 | ca->en50221.slot_shutdown = mantis_ca_slot_shutdown; | ||
| 171 | ca->en50221.slot_ts_enable = mantis_ts_control; | ||
| 172 | ca->en50221.poll_slot_status = mantis_slot_status; | ||
| 173 | ca->en50221.data = ca; | ||
| 174 | |||
| 175 | mutex_init(&ca->ca_lock); | ||
| 176 | |||
| 177 | init_waitqueue_head(&ca->hif_data_wq); | ||
| 178 | init_waitqueue_head(&ca->hif_opdone_wq); | ||
| 179 | init_waitqueue_head(&ca->hif_write_wq); | ||
| 180 | |||
| 181 | dprintk(MANTIS_ERROR, 1, "Registering EN50221 device"); | ||
| 182 | result = dvb_ca_en50221_init(dvb_adapter, &ca->en50221, ca_flags, 1); | ||
| 183 | if (result != 0) { | ||
| 184 | dprintk(MANTIS_ERROR, 1, "EN50221: Initialization failed <%d>", result); | ||
| 185 | goto err; | ||
| 186 | } | ||
| 187 | dprintk(MANTIS_ERROR, 1, "Registered EN50221 device"); | ||
| 188 | mantis_evmgr_init(ca); | ||
| 189 | return 0; | ||
| 190 | err: | ||
| 191 | kfree(ca); | ||
| 192 | return result; | ||
| 193 | } | ||
| 194 | EXPORT_SYMBOL_GPL(mantis_ca_init); | ||
| 195 | |||
| 196 | void mantis_ca_exit(struct mantis_pci *mantis) | ||
| 197 | { | ||
| 198 | struct mantis_ca *ca = mantis->mantis_ca; | ||
| 199 | |||
| 200 | dprintk(MANTIS_DEBUG, 1, "Mantis CA exit"); | ||
| 201 | |||
| 202 | mantis_evmgr_exit(ca); | ||
| 203 | dprintk(MANTIS_ERROR, 1, "Unregistering EN50221 device"); | ||
| 204 | if (ca) | ||
| 205 | dvb_ca_en50221_release(&ca->en50221); | ||
| 206 | |||
| 207 | kfree(ca); | ||
| 208 | } | ||
| 209 | EXPORT_SYMBOL_GPL(mantis_ca_exit); | ||
diff --git a/drivers/media/dvb/mantis/mantis_ca.h b/drivers/media/dvb/mantis/mantis_ca.h new file mode 100644 index 00000000000..dc63e55f7ec --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_ca.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_CA_H | ||
| 22 | #define __MANTIS_CA_H | ||
| 23 | |||
| 24 | extern int mantis_ca_init(struct mantis_pci *mantis); | ||
| 25 | extern void mantis_ca_exit(struct mantis_pci *mantis); | ||
| 26 | |||
| 27 | #endif /* __MANTIS_CA_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/dvb/mantis/mantis_cards.c new file mode 100644 index 00000000000..05cbb9d9572 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_cards.c | |||
| @@ -0,0 +1,308 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/moduleparam.h> | ||
| 23 | #include <linux/kernel.h> | ||
| 24 | #include <linux/pci.h> | ||
| 25 | #include <linux/slab.h> | ||
| 26 | #include <asm/irq.h> | ||
| 27 | #include <linux/interrupt.h> | ||
| 28 | |||
| 29 | #include "dmxdev.h" | ||
| 30 | #include "dvbdev.h" | ||
| 31 | #include "dvb_demux.h" | ||
| 32 | #include "dvb_frontend.h" | ||
| 33 | #include "dvb_net.h" | ||
| 34 | |||
| 35 | #include "mantis_common.h" | ||
| 36 | |||
| 37 | #include "mantis_vp1033.h" | ||
| 38 | #include "mantis_vp1034.h" | ||
| 39 | #include "mantis_vp1041.h" | ||
| 40 | #include "mantis_vp2033.h" | ||
| 41 | #include "mantis_vp2040.h" | ||
| 42 | #include "mantis_vp3030.h" | ||
| 43 | |||
| 44 | #include "mantis_dma.h" | ||
| 45 | #include "mantis_ca.h" | ||
| 46 | #include "mantis_dvb.h" | ||
| 47 | #include "mantis_uart.h" | ||
| 48 | #include "mantis_ioc.h" | ||
| 49 | #include "mantis_pci.h" | ||
| 50 | #include "mantis_i2c.h" | ||
| 51 | #include "mantis_reg.h" | ||
| 52 | |||
| 53 | static unsigned int verbose; | ||
| 54 | module_param(verbose, int, 0644); | ||
| 55 | MODULE_PARM_DESC(verbose, "verbose startup messages, default is 0 (no)"); | ||
| 56 | |||
| 57 | static int devs; | ||
| 58 | |||
| 59 | #define DRIVER_NAME "Mantis" | ||
| 60 | |||
| 61 | static char *label[10] = { | ||
| 62 | "DMA", | ||
| 63 | "IRQ-0", | ||
| 64 | "IRQ-1", | ||
| 65 | "OCERR", | ||
| 66 | "PABRT", | ||
| 67 | "RIPRR", | ||
| 68 | "PPERR", | ||
| 69 | "FTRGT", | ||
| 70 | "RISCI", | ||
| 71 | "RACK" | ||
| 72 | }; | ||
| 73 | |||
| 74 | static irqreturn_t mantis_irq_handler(int irq, void *dev_id) | ||
| 75 | { | ||
| 76 | u32 stat = 0, mask = 0, lstat = 0, mstat = 0; | ||
| 77 | u32 rst_stat = 0, rst_mask = 0; | ||
| 78 | |||
| 79 | struct mantis_pci *mantis; | ||
| 80 | struct mantis_ca *ca; | ||
| 81 | |||
| 82 | mantis = (struct mantis_pci *) dev_id; | ||
| 83 | if (unlikely(mantis == NULL)) { | ||
| 84 | dprintk(MANTIS_ERROR, 1, "Mantis == NULL"); | ||
| 85 | return IRQ_NONE; | ||
| 86 | } | ||
| 87 | ca = mantis->mantis_ca; | ||
| 88 | |||
| 89 | stat = mmread(MANTIS_INT_STAT); | ||
| 90 | mask = mmread(MANTIS_INT_MASK); | ||
| 91 | mstat = lstat = stat & ~MANTIS_INT_RISCSTAT; | ||
| 92 | if (!(stat & mask)) | ||
| 93 | return IRQ_NONE; | ||
| 94 | |||
| 95 | rst_mask = MANTIS_GPIF_WRACK | | ||
| 96 | MANTIS_GPIF_OTHERR | | ||
| 97 | MANTIS_SBUF_WSTO | | ||
| 98 | MANTIS_GPIF_EXTIRQ; | ||
| 99 | |||
| 100 | rst_stat = mmread(MANTIS_GPIF_STATUS); | ||
| 101 | rst_stat &= rst_mask; | ||
| 102 | mmwrite(rst_stat, MANTIS_GPIF_STATUS); | ||
| 103 | |||
| 104 | mantis->mantis_int_stat = stat; | ||
| 105 | mantis->mantis_int_mask = mask; | ||
| 106 | dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask); | ||
| 107 | if (stat & MANTIS_INT_RISCEN) { | ||
| 108 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]); | ||
| 109 | } | ||
| 110 | if (stat & MANTIS_INT_IRQ0) { | ||
| 111 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]); | ||
| 112 | mantis->gpif_status = rst_stat; | ||
| 113 | wake_up(&ca->hif_write_wq); | ||
| 114 | schedule_work(&ca->hif_evm_work); | ||
| 115 | } | ||
| 116 | if (stat & MANTIS_INT_IRQ1) { | ||
| 117 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); | ||
| 118 | schedule_work(&mantis->uart_work); | ||
| 119 | } | ||
| 120 | if (stat & MANTIS_INT_OCERR) { | ||
| 121 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]); | ||
| 122 | } | ||
| 123 | if (stat & MANTIS_INT_PABORT) { | ||
| 124 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]); | ||
| 125 | } | ||
| 126 | if (stat & MANTIS_INT_RIPERR) { | ||
| 127 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]); | ||
| 128 | } | ||
| 129 | if (stat & MANTIS_INT_PPERR) { | ||
| 130 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]); | ||
| 131 | } | ||
| 132 | if (stat & MANTIS_INT_FTRGT) { | ||
| 133 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]); | ||
| 134 | } | ||
| 135 | if (stat & MANTIS_INT_RISCI) { | ||
| 136 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); | ||
| 137 | mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28; | ||
| 138 | tasklet_schedule(&mantis->tasklet); | ||
| 139 | } | ||
| 140 | if (stat & MANTIS_INT_I2CDONE) { | ||
| 141 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]); | ||
| 142 | wake_up(&mantis->i2c_wq); | ||
| 143 | } | ||
| 144 | mmwrite(stat, MANTIS_INT_STAT); | ||
| 145 | stat &= ~(MANTIS_INT_RISCEN | MANTIS_INT_I2CDONE | | ||
| 146 | MANTIS_INT_I2CRACK | MANTIS_INT_PCMCIA7 | | ||
| 147 | MANTIS_INT_PCMCIA6 | MANTIS_INT_PCMCIA5 | | ||
| 148 | MANTIS_INT_PCMCIA4 | MANTIS_INT_PCMCIA3 | | ||
| 149 | MANTIS_INT_PCMCIA2 | MANTIS_INT_PCMCIA1 | | ||
| 150 | MANTIS_INT_PCMCIA0 | MANTIS_INT_IRQ1 | | ||
| 151 | MANTIS_INT_IRQ0 | MANTIS_INT_OCERR | | ||
| 152 | MANTIS_INT_PABORT | MANTIS_INT_RIPERR | | ||
| 153 | MANTIS_INT_PPERR | MANTIS_INT_FTRGT | | ||
| 154 | MANTIS_INT_RISCI); | ||
| 155 | |||
| 156 | if (stat) | ||
| 157 | dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask); | ||
| 158 | |||
| 159 | dprintk(MANTIS_DEBUG, 0, "\n"); | ||
| 160 | return IRQ_HANDLED; | ||
| 161 | } | ||
| 162 | |||
| 163 | static int __devinit mantis_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | ||
| 164 | { | ||
| 165 | struct mantis_pci *mantis; | ||
| 166 | struct mantis_hwconfig *config; | ||
| 167 | int err = 0; | ||
| 168 | |||
| 169 | mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL); | ||
| 170 | if (mantis == NULL) { | ||
| 171 | printk(KERN_ERR "%s ERROR: Out of memory\n", __func__); | ||
| 172 | err = -ENOMEM; | ||
| 173 | goto fail0; | ||
| 174 | } | ||
| 175 | |||
| 176 | mantis->num = devs; | ||
| 177 | mantis->verbose = verbose; | ||
| 178 | mantis->pdev = pdev; | ||
| 179 | config = (struct mantis_hwconfig *) pci_id->driver_data; | ||
| 180 | config->irq_handler = &mantis_irq_handler; | ||
| 181 | mantis->hwconfig = config; | ||
| 182 | |||
| 183 | err = mantis_pci_init(mantis); | ||
| 184 | if (err) { | ||
| 185 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err); | ||
| 186 | goto fail1; | ||
| 187 | } | ||
| 188 | |||
| 189 | err = mantis_stream_control(mantis, STREAM_TO_HIF); | ||
| 190 | if (err < 0) { | ||
| 191 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err); | ||
| 192 | goto fail1; | ||
| 193 | } | ||
| 194 | |||
| 195 | err = mantis_i2c_init(mantis); | ||
| 196 | if (err < 0) { | ||
| 197 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err); | ||
| 198 | goto fail2; | ||
| 199 | } | ||
| 200 | |||
| 201 | err = mantis_get_mac(mantis); | ||
| 202 | if (err < 0) { | ||
| 203 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err); | ||
| 204 | goto fail2; | ||
| 205 | } | ||
| 206 | |||
| 207 | err = mantis_dma_init(mantis); | ||
| 208 | if (err < 0) { | ||
| 209 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err); | ||
| 210 | goto fail3; | ||
| 211 | } | ||
| 212 | |||
| 213 | err = mantis_dvb_init(mantis); | ||
| 214 | if (err < 0) { | ||
| 215 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err); | ||
| 216 | goto fail4; | ||
| 217 | } | ||
| 218 | err = mantis_uart_init(mantis); | ||
| 219 | if (err < 0) { | ||
| 220 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART initialization failed <%d>", err); | ||
| 221 | goto fail6; | ||
| 222 | } | ||
| 223 | |||
| 224 | devs++; | ||
| 225 | |||
| 226 | return err; | ||
| 227 | |||
| 228 | |||
| 229 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART exit! <%d>", err); | ||
| 230 | mantis_uart_exit(mantis); | ||
| 231 | |||
| 232 | fail6: | ||
| 233 | fail4: | ||
| 234 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err); | ||
| 235 | mantis_dma_exit(mantis); | ||
| 236 | |||
| 237 | fail3: | ||
| 238 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err); | ||
| 239 | mantis_i2c_exit(mantis); | ||
| 240 | |||
| 241 | fail2: | ||
| 242 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err); | ||
| 243 | mantis_pci_exit(mantis); | ||
| 244 | |||
| 245 | fail1: | ||
| 246 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err); | ||
| 247 | kfree(mantis); | ||
| 248 | |||
| 249 | fail0: | ||
| 250 | return err; | ||
| 251 | } | ||
| 252 | |||
| 253 | static void __devexit mantis_pci_remove(struct pci_dev *pdev) | ||
| 254 | { | ||
| 255 | struct mantis_pci *mantis = pci_get_drvdata(pdev); | ||
| 256 | |||
| 257 | if (mantis) { | ||
| 258 | |||
| 259 | mantis_uart_exit(mantis); | ||
| 260 | mantis_dvb_exit(mantis); | ||
| 261 | mantis_dma_exit(mantis); | ||
| 262 | mantis_i2c_exit(mantis); | ||
| 263 | mantis_pci_exit(mantis); | ||
| 264 | kfree(mantis); | ||
| 265 | } | ||
| 266 | return; | ||
| 267 | } | ||
| 268 | |||
| 269 | static struct pci_device_id mantis_pci_table[] = { | ||
| 270 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1033_DVB_S, &vp1033_config), | ||
| 271 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1034_DVB_S, &vp1034_config), | ||
| 272 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1041_DVB_S2, &vp1041_config), | ||
| 273 | MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config), | ||
| 274 | MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_20, &vp1041_config), | ||
| 275 | MAKE_ENTRY(TERRATEC, CINERGY_S2_PCI_HD, &vp1041_config), | ||
| 276 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config), | ||
| 277 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config), | ||
| 278 | MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config), | ||
| 279 | MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2033_config), | ||
| 280 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config), | ||
| 281 | { } | ||
| 282 | }; | ||
| 283 | |||
| 284 | MODULE_DEVICE_TABLE(pci, mantis_pci_table); | ||
| 285 | |||
| 286 | static struct pci_driver mantis_pci_driver = { | ||
| 287 | .name = DRIVER_NAME, | ||
| 288 | .id_table = mantis_pci_table, | ||
| 289 | .probe = mantis_pci_probe, | ||
| 290 | .remove = mantis_pci_remove, | ||
| 291 | }; | ||
| 292 | |||
| 293 | static int __devinit mantis_init(void) | ||
| 294 | { | ||
| 295 | return pci_register_driver(&mantis_pci_driver); | ||
| 296 | } | ||
| 297 | |||
| 298 | static void __devexit mantis_exit(void) | ||
| 299 | { | ||
| 300 | return pci_unregister_driver(&mantis_pci_driver); | ||
| 301 | } | ||
| 302 | |||
| 303 | module_init(mantis_init); | ||
| 304 | module_exit(mantis_exit); | ||
| 305 | |||
| 306 | MODULE_DESCRIPTION("MANTIS driver"); | ||
| 307 | MODULE_AUTHOR("Manu Abraham"); | ||
| 308 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/mantis/mantis_common.h b/drivers/media/dvb/mantis/mantis_common.h new file mode 100644 index 00000000000..49dbca145bb --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_common.h | |||
| @@ -0,0 +1,182 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_COMMON_H | ||
| 22 | #define __MANTIS_COMMON_H | ||
| 23 | |||
| 24 | #include <linux/interrupt.h> | ||
| 25 | #include <linux/mutex.h> | ||
| 26 | #include <linux/workqueue.h> | ||
| 27 | |||
| 28 | #include "mantis_uart.h" | ||
| 29 | |||
| 30 | #include "mantis_link.h" | ||
| 31 | |||
| 32 | #define MANTIS_ERROR 0 | ||
| 33 | #define MANTIS_NOTICE 1 | ||
| 34 | #define MANTIS_INFO 2 | ||
| 35 | #define MANTIS_DEBUG 3 | ||
| 36 | #define MANTIS_TMG 9 | ||
| 37 | |||
| 38 | #define dprintk(y, z, format, arg...) do { \ | ||
| 39 | if (z) { \ | ||
| 40 | if ((mantis->verbose > MANTIS_ERROR) && (mantis->verbose > y)) \ | ||
| 41 | printk(KERN_ERR "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
| 42 | else if ((mantis->verbose > MANTIS_NOTICE) && (mantis->verbose > y)) \ | ||
| 43 | printk(KERN_NOTICE "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
| 44 | else if ((mantis->verbose > MANTIS_INFO) && (mantis->verbose > y)) \ | ||
| 45 | printk(KERN_INFO "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
| 46 | else if ((mantis->verbose > MANTIS_DEBUG) && (mantis->verbose > y)) \ | ||
| 47 | printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
| 48 | else if ((mantis->verbose > MANTIS_TMG) && (mantis->verbose > y)) \ | ||
| 49 | printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
| 50 | } else { \ | ||
| 51 | if (mantis->verbose > y) \ | ||
| 52 | printk(format , ##arg); \ | ||
| 53 | } \ | ||
| 54 | } while(0) | ||
| 55 | |||
| 56 | #define mwrite(dat, addr) writel((dat), addr) | ||
| 57 | #define mread(addr) readl(addr) | ||
| 58 | |||
| 59 | #define mmwrite(dat, addr) mwrite((dat), (mantis->mmio + (addr))) | ||
| 60 | #define mmread(addr) mread(mantis->mmio + (addr)) | ||
| 61 | |||
| 62 | #define MANTIS_TS_188 0 | ||
| 63 | #define MANTIS_TS_204 1 | ||
| 64 | |||
| 65 | #define TWINHAN_TECHNOLOGIES 0x1822 | ||
| 66 | #define MANTIS 0x4e35 | ||
| 67 | |||
| 68 | #define TECHNISAT 0x1ae4 | ||
| 69 | #define TERRATEC 0x153b | ||
| 70 | |||
| 71 | #define MAKE_ENTRY(__subven, __subdev, __configptr) { \ | ||
| 72 | .vendor = TWINHAN_TECHNOLOGIES, \ | ||
| 73 | .device = MANTIS, \ | ||
| 74 | .subvendor = (__subven), \ | ||
| 75 | .subdevice = (__subdev), \ | ||
| 76 | .driver_data = (unsigned long) (__configptr) \ | ||
| 77 | } | ||
| 78 | |||
| 79 | enum mantis_i2c_mode { | ||
| 80 | MANTIS_PAGE_MODE = 0, | ||
| 81 | MANTIS_BYTE_MODE, | ||
| 82 | }; | ||
| 83 | |||
| 84 | struct mantis_pci; | ||
| 85 | |||
| 86 | struct mantis_hwconfig { | ||
| 87 | char *model_name; | ||
| 88 | char *dev_type; | ||
| 89 | u32 ts_size; | ||
| 90 | |||
| 91 | enum mantis_baud baud_rate; | ||
| 92 | enum mantis_parity parity; | ||
| 93 | u32 bytes; | ||
| 94 | |||
| 95 | irqreturn_t (*irq_handler)(int irq, void *dev_id); | ||
| 96 | int (*frontend_init)(struct mantis_pci *mantis, struct dvb_frontend *fe); | ||
| 97 | |||
| 98 | u8 power; | ||
| 99 | u8 reset; | ||
| 100 | |||
| 101 | enum mantis_i2c_mode i2c_mode; | ||
| 102 | }; | ||
| 103 | |||
| 104 | struct mantis_pci { | ||
| 105 | unsigned int verbose; | ||
| 106 | |||
| 107 | /* PCI stuff */ | ||
| 108 | u16 vendor_id; | ||
| 109 | u16 device_id; | ||
| 110 | u16 subsystem_vendor; | ||
| 111 | u16 subsystem_device; | ||
| 112 | |||
| 113 | u8 latency; | ||
| 114 | |||
| 115 | struct pci_dev *pdev; | ||
| 116 | |||
| 117 | unsigned long mantis_addr; | ||
| 118 | void __iomem *mmio; | ||
| 119 | |||
| 120 | u8 irq; | ||
| 121 | u8 revision; | ||
| 122 | |||
| 123 | unsigned int num; | ||
| 124 | |||
| 125 | /* RISC Core */ | ||
| 126 | u32 finished_block; | ||
| 127 | u32 last_block; | ||
| 128 | u32 line_bytes; | ||
| 129 | u32 line_count; | ||
| 130 | u32 risc_pos; | ||
| 131 | u8 *buf_cpu; | ||
| 132 | dma_addr_t buf_dma; | ||
| 133 | u32 *risc_cpu; | ||
| 134 | dma_addr_t risc_dma; | ||
| 135 | |||
| 136 | struct tasklet_struct tasklet; | ||
| 137 | |||
| 138 | struct i2c_adapter adapter; | ||
| 139 | int i2c_rc; | ||
| 140 | wait_queue_head_t i2c_wq; | ||
| 141 | struct mutex i2c_lock; | ||
| 142 | |||
| 143 | /* DVB stuff */ | ||
| 144 | struct dvb_adapter dvb_adapter; | ||
| 145 | struct dvb_frontend *fe; | ||
| 146 | struct dvb_demux demux; | ||
| 147 | struct dmxdev dmxdev; | ||
| 148 | struct dmx_frontend fe_hw; | ||
| 149 | struct dmx_frontend fe_mem; | ||
| 150 | struct dvb_net dvbnet; | ||
| 151 | |||
| 152 | u8 feeds; | ||
| 153 | |||
| 154 | struct mantis_hwconfig *hwconfig; | ||
| 155 | |||
| 156 | u32 mantis_int_stat; | ||
| 157 | u32 mantis_int_mask; | ||
| 158 | |||
| 159 | /* board specific */ | ||
| 160 | u8 mac_address[8]; | ||
| 161 | u32 sub_vendor_id; | ||
| 162 | u32 sub_device_id; | ||
| 163 | |||
| 164 | /* A12 A13 A14 */ | ||
| 165 | u32 gpio_status; | ||
| 166 | |||
| 167 | u32 gpif_status; | ||
| 168 | |||
| 169 | struct mantis_ca *mantis_ca; | ||
| 170 | |||
| 171 | wait_queue_head_t uart_wq; | ||
| 172 | struct work_struct uart_work; | ||
| 173 | spinlock_t uart_lock; | ||
| 174 | |||
| 175 | struct rc_dev *rc; | ||
| 176 | char input_name[80]; | ||
| 177 | char input_phys[80]; | ||
| 178 | }; | ||
| 179 | |||
| 180 | #define MANTIS_HIF_STATUS (mantis->gpio_status) | ||
| 181 | |||
| 182 | #endif /* __MANTIS_COMMON_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_core.c b/drivers/media/dvb/mantis/mantis_core.c new file mode 100644 index 00000000000..22524a8e6f6 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_core.c | |||
| @@ -0,0 +1,235 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include "mantis_common.h" | ||
| 22 | #include "mantis_core.h" | ||
| 23 | #include "mantis_vp1033.h" | ||
| 24 | #include "mantis_vp1034.h" | ||
| 25 | #include "mantis_vp1041.h" | ||
| 26 | #include "mantis_vp2033.h" | ||
| 27 | #include "mantis_vp2040.h" | ||
| 28 | #include "mantis_vp3030.h" | ||
| 29 | |||
| 30 | static int read_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length) | ||
| 31 | { | ||
| 32 | int err; | ||
| 33 | struct i2c_msg msg[] = { | ||
| 34 | { | ||
| 35 | .addr = 0x50, | ||
| 36 | .flags = 0, | ||
| 37 | .buf = data, | ||
| 38 | .len = 1 | ||
| 39 | }, { | ||
| 40 | .addr = 0x50, | ||
| 41 | .flags = I2C_M_RD, | ||
| 42 | .buf = data, | ||
| 43 | .len = length | ||
| 44 | }, | ||
| 45 | }; | ||
| 46 | |||
| 47 | err = i2c_transfer(&mantis->adapter, msg, 2); | ||
| 48 | if (err < 0) { | ||
| 49 | dprintk(verbose, MANTIS_ERROR, 1, | ||
| 50 | "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >", | ||
| 51 | err, data[0], data[1]); | ||
| 52 | |||
| 53 | return err; | ||
| 54 | } | ||
| 55 | |||
| 56 | return 0; | ||
| 57 | } | ||
| 58 | |||
| 59 | static int write_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length) | ||
| 60 | { | ||
| 61 | int err; | ||
| 62 | |||
| 63 | struct i2c_msg msg = { | ||
| 64 | .addr = 0x50, | ||
| 65 | .flags = 0, | ||
| 66 | .buf = data, | ||
| 67 | .len = length | ||
| 68 | }; | ||
| 69 | |||
| 70 | err = i2c_transfer(&mantis->adapter, &msg, 1); | ||
| 71 | if (err < 0) { | ||
| 72 | dprintk(verbose, MANTIS_ERROR, 1, | ||
| 73 | "ERROR: i2c write: < err=%i length=0x%02x d0=0x%02x, d1=0x%02x >", | ||
| 74 | err, length, data[0], data[1]); | ||
| 75 | |||
| 76 | return err; | ||
| 77 | } | ||
| 78 | |||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | |||
| 82 | static int get_mac_address(struct mantis_pci *mantis) | ||
| 83 | { | ||
| 84 | int err; | ||
| 85 | |||
| 86 | mantis->mac_address[0] = 0x08; | ||
| 87 | err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6); | ||
| 88 | if (err < 0) { | ||
| 89 | dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error"); | ||
| 90 | |||
| 91 | return err; | ||
| 92 | } | ||
| 93 | dprintk(verbose, MANTIS_ERROR, 0, | ||
| 94 | " MAC Address=[%pM]\n", mantis->mac_address); | ||
| 95 | |||
| 96 | return 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | #define MANTIS_MODEL_UNKNOWN "UNKNOWN" | ||
| 100 | #define MANTIS_DEV_UNKNOWN "UNKNOWN" | ||
| 101 | |||
| 102 | struct mantis_hwconfig unknown_device = { | ||
| 103 | .model_name = MANTIS_MODEL_UNKNOWN, | ||
| 104 | .dev_type = MANTIS_DEV_UNKNOWN, | ||
| 105 | }; | ||
| 106 | |||
| 107 | static void mantis_load_config(struct mantis_pci *mantis) | ||
| 108 | { | ||
| 109 | switch (mantis->subsystem_device) { | ||
| 110 | case MANTIS_VP_1033_DVB_S: /* VP-1033 */ | ||
| 111 | mantis->hwconfig = &vp1033_mantis_config; | ||
| 112 | break; | ||
| 113 | case MANTIS_VP_1034_DVB_S: /* VP-1034 */ | ||
| 114 | mantis->hwconfig = &vp1034_mantis_config; | ||
| 115 | break; | ||
| 116 | case MANTIS_VP_1041_DVB_S2: /* VP-1041 */ | ||
| 117 | case TECHNISAT_SKYSTAR_HD2: | ||
| 118 | mantis->hwconfig = &vp1041_mantis_config; | ||
| 119 | break; | ||
| 120 | case MANTIS_VP_2033_DVB_C: /* VP-2033 */ | ||
| 121 | mantis->hwconfig = &vp2033_mantis_config; | ||
| 122 | break; | ||
| 123 | case MANTIS_VP_2040_DVB_C: /* VP-2040 */ | ||
| 124 | case TERRATEC_CINERGY_C_PCI: /* VP-2040 clone */ | ||
| 125 | case TECHNISAT_CABLESTAR_HD2: | ||
| 126 | mantis->hwconfig = &vp2040_mantis_config; | ||
| 127 | break; | ||
| 128 | case MANTIS_VP_3030_DVB_T: /* VP-3030 */ | ||
| 129 | mantis->hwconfig = &vp3030_mantis_config; | ||
| 130 | break; | ||
| 131 | default: | ||
| 132 | mantis->hwconfig = &unknown_device; | ||
| 133 | break; | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 137 | int mantis_core_init(struct mantis_pci *mantis) | ||
| 138 | { | ||
| 139 | int err = 0; | ||
| 140 | |||
| 141 | mantis_load_config(mantis); | ||
| 142 | dprintk(verbose, MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n", | ||
| 143 | mantis->hwconfig->model_name, mantis->hwconfig->dev_type, | ||
| 144 | mantis->pdev->bus->number, PCI_SLOT(mantis->pdev->devfn), PCI_FUNC(mantis->pdev->devfn)); | ||
| 145 | dprintk(verbose, MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ", | ||
| 146 | mantis->revision, | ||
| 147 | mantis->subsystem_vendor, mantis->subsystem_device); | ||
| 148 | dprintk(verbose, MANTIS_ERROR, 0, | ||
| 149 | "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n", | ||
| 150 | mantis->pdev->irq, mantis->latency, | ||
| 151 | mantis->mantis_addr, mantis->mantis_mmio); | ||
| 152 | |||
| 153 | err = mantis_i2c_init(mantis); | ||
| 154 | if (err < 0) { | ||
| 155 | dprintk(verbose, MANTIS_ERROR, 1, "Mantis I2C init failed"); | ||
| 156 | return err; | ||
| 157 | } | ||
| 158 | err = get_mac_address(mantis); | ||
| 159 | if (err < 0) { | ||
| 160 | dprintk(verbose, MANTIS_ERROR, 1, "get MAC address failed"); | ||
| 161 | return err; | ||
| 162 | } | ||
| 163 | err = mantis_dma_init(mantis); | ||
| 164 | if (err < 0) { | ||
| 165 | dprintk(verbose, MANTIS_ERROR, 1, "Mantis DMA init failed"); | ||
| 166 | return err; | ||
| 167 | } | ||
| 168 | err = mantis_dvb_init(mantis); | ||
| 169 | if (err < 0) { | ||
| 170 | dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed"); | ||
| 171 | return err; | ||
| 172 | } | ||
| 173 | err = mantis_uart_init(mantis); | ||
| 174 | if (err < 0) { | ||
| 175 | dprintk(verbose, MANTIS_DEBUG, 1, "Mantis UART init failed"); | ||
| 176 | return err; | ||
| 177 | } | ||
| 178 | |||
| 179 | return 0; | ||
| 180 | } | ||
| 181 | |||
| 182 | int mantis_core_exit(struct mantis_pci *mantis) | ||
| 183 | { | ||
| 184 | mantis_dma_stop(mantis); | ||
| 185 | dprintk(verbose, MANTIS_ERROR, 1, "DMA engine stopping"); | ||
| 186 | |||
| 187 | mantis_uart_exit(mantis); | ||
| 188 | dprintk(verbose, MANTIS_ERROR, 1, "UART exit failed"); | ||
| 189 | |||
| 190 | if (mantis_dma_exit(mantis) < 0) | ||
| 191 | dprintk(verbose, MANTIS_ERROR, 1, "DMA exit failed"); | ||
| 192 | if (mantis_dvb_exit(mantis) < 0) | ||
| 193 | dprintk(verbose, MANTIS_ERROR, 1, "DVB exit failed"); | ||
| 194 | if (mantis_i2c_exit(mantis) < 0) | ||
| 195 | dprintk(verbose, MANTIS_ERROR, 1, "I2C adapter delete.. failed"); | ||
| 196 | |||
| 197 | return 0; | ||
| 198 | } | ||
| 199 | |||
| 200 | /* Turn the given bit on or off. */ | ||
| 201 | void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value) | ||
| 202 | { | ||
| 203 | u32 cur; | ||
| 204 | |||
| 205 | cur = mmread(MANTIS_GPIF_ADDR); | ||
| 206 | if (value) | ||
| 207 | mantis->gpio_status = cur | (1 << bitpos); | ||
| 208 | else | ||
| 209 | mantis->gpio_status = cur & (~(1 << bitpos)); | ||
| 210 | |||
| 211 | mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR); | ||
| 212 | mmwrite(0x00, MANTIS_GPIF_DOUT); | ||
| 213 | udelay(100); | ||
| 214 | } | ||
| 215 | |||
| 216 | /* direction = 0 , no CI passthrough ; 1 , CI passthrough */ | ||
| 217 | void mantis_set_direction(struct mantis_pci *mantis, int direction) | ||
| 218 | { | ||
| 219 | u32 reg; | ||
| 220 | |||
| 221 | reg = mmread(0x28); | ||
| 222 | dprintk(verbose, MANTIS_DEBUG, 1, "TS direction setup"); | ||
| 223 | if (direction == 0x01) { | ||
| 224 | /* to CI */ | ||
| 225 | reg |= 0x04; | ||
| 226 | mmwrite(reg, 0x28); | ||
| 227 | reg &= 0xff - 0x04; | ||
| 228 | mmwrite(reg, 0x28); | ||
| 229 | } else { | ||
| 230 | reg &= 0xff - 0x04; | ||
| 231 | mmwrite(reg, 0x28); | ||
| 232 | reg |= 0x04; | ||
| 233 | mmwrite(reg, 0x28); | ||
| 234 | } | ||
| 235 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_core.h b/drivers/media/dvb/mantis/mantis_core.h new file mode 100644 index 00000000000..833ee42e694 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_core.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_CORE_H | ||
| 22 | #define __MANTIS_CORE_H | ||
| 23 | |||
| 24 | #include "mantis_common.h" | ||
| 25 | |||
| 26 | |||
| 27 | #define FE_TYPE_SAT 0 | ||
| 28 | #define FE_TYPE_CAB 1 | ||
| 29 | #define FE_TYPE_TER 2 | ||
| 30 | |||
| 31 | #define FE_TYPE_TS204 0 | ||
| 32 | #define FE_TYPE_TS188 1 | ||
| 33 | |||
| 34 | |||
| 35 | struct vendorname { | ||
| 36 | u8 *sub_vendor_name; | ||
| 37 | u32 sub_vendor_id; | ||
| 38 | }; | ||
| 39 | |||
| 40 | struct devicetype { | ||
| 41 | u8 *sub_device_name; | ||
| 42 | u32 sub_device_id; | ||
| 43 | u8 device_type; | ||
| 44 | u32 type_flags; | ||
| 45 | }; | ||
| 46 | |||
| 47 | |||
| 48 | extern int mantis_dma_init(struct mantis_pci *mantis); | ||
| 49 | extern int mantis_dma_exit(struct mantis_pci *mantis); | ||
| 50 | extern void mantis_dma_start(struct mantis_pci *mantis); | ||
| 51 | extern void mantis_dma_stop(struct mantis_pci *mantis); | ||
| 52 | extern int mantis_i2c_init(struct mantis_pci *mantis); | ||
| 53 | extern int mantis_i2c_exit(struct mantis_pci *mantis); | ||
| 54 | extern int mantis_core_init(struct mantis_pci *mantis); | ||
| 55 | extern int mantis_core_exit(struct mantis_pci *mantis); | ||
| 56 | |||
| 57 | #endif /* __MANTIS_CORE_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_dma.c b/drivers/media/dvb/mantis/mantis_dma.c new file mode 100644 index 00000000000..46202a4012a --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_dma.c | |||
| @@ -0,0 +1,256 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/kernel.h> | ||
| 22 | #include <asm/page.h> | ||
| 23 | #include <linux/vmalloc.h> | ||
| 24 | #include <linux/pci.h> | ||
| 25 | |||
| 26 | #include <asm/irq.h> | ||
| 27 | #include <linux/signal.h> | ||
| 28 | #include <linux/sched.h> | ||
| 29 | #include <linux/interrupt.h> | ||
| 30 | |||
| 31 | #include "dmxdev.h" | ||
| 32 | #include "dvbdev.h" | ||
| 33 | #include "dvb_demux.h" | ||
| 34 | #include "dvb_frontend.h" | ||
| 35 | #include "dvb_net.h" | ||
| 36 | |||
| 37 | #include "mantis_common.h" | ||
| 38 | #include "mantis_reg.h" | ||
| 39 | #include "mantis_dma.h" | ||
| 40 | |||
| 41 | #define RISC_WRITE (0x01 << 28) | ||
| 42 | #define RISC_JUMP (0x07 << 28) | ||
| 43 | #define RISC_IRQ (0x01 << 24) | ||
| 44 | |||
| 45 | #define RISC_STATUS(status) ((((~status) & 0x0f) << 20) | ((status & 0x0f) << 16)) | ||
| 46 | #define RISC_FLUSH() (mantis->risc_pos = 0) | ||
| 47 | #define RISC_INSTR(opcode) (mantis->risc_cpu[mantis->risc_pos++] = cpu_to_le32(opcode)) | ||
| 48 | |||
| 49 | #define MANTIS_BUF_SIZE (64 * 1024) | ||
| 50 | #define MANTIS_BLOCK_BYTES (MANTIS_BUF_SIZE >> 4) | ||
| 51 | #define MANTIS_BLOCK_COUNT (1 << 4) | ||
| 52 | #define MANTIS_RISC_SIZE PAGE_SIZE | ||
| 53 | |||
| 54 | int mantis_dma_exit(struct mantis_pci *mantis) | ||
| 55 | { | ||
| 56 | if (mantis->buf_cpu) { | ||
| 57 | dprintk(MANTIS_ERROR, 1, | ||
| 58 | "DMA=0x%lx cpu=0x%p size=%d", | ||
| 59 | (unsigned long) mantis->buf_dma, | ||
| 60 | mantis->buf_cpu, | ||
| 61 | MANTIS_BUF_SIZE); | ||
| 62 | |||
| 63 | pci_free_consistent(mantis->pdev, MANTIS_BUF_SIZE, | ||
| 64 | mantis->buf_cpu, mantis->buf_dma); | ||
| 65 | |||
| 66 | mantis->buf_cpu = NULL; | ||
| 67 | } | ||
| 68 | if (mantis->risc_cpu) { | ||
| 69 | dprintk(MANTIS_ERROR, 1, | ||
| 70 | "RISC=0x%lx cpu=0x%p size=%lx", | ||
| 71 | (unsigned long) mantis->risc_dma, | ||
| 72 | mantis->risc_cpu, | ||
| 73 | MANTIS_RISC_SIZE); | ||
| 74 | |||
| 75 | pci_free_consistent(mantis->pdev, MANTIS_RISC_SIZE, | ||
| 76 | mantis->risc_cpu, mantis->risc_dma); | ||
| 77 | |||
| 78 | mantis->risc_cpu = NULL; | ||
| 79 | } | ||
| 80 | |||
| 81 | return 0; | ||
| 82 | } | ||
| 83 | EXPORT_SYMBOL_GPL(mantis_dma_exit); | ||
| 84 | |||
| 85 | static inline int mantis_alloc_buffers(struct mantis_pci *mantis) | ||
| 86 | { | ||
| 87 | if (!mantis->buf_cpu) { | ||
| 88 | mantis->buf_cpu = pci_alloc_consistent(mantis->pdev, | ||
| 89 | MANTIS_BUF_SIZE, | ||
| 90 | &mantis->buf_dma); | ||
| 91 | if (!mantis->buf_cpu) { | ||
| 92 | dprintk(MANTIS_ERROR, 1, | ||
| 93 | "DMA buffer allocation failed"); | ||
| 94 | |||
| 95 | goto err; | ||
| 96 | } | ||
| 97 | dprintk(MANTIS_ERROR, 1, | ||
| 98 | "DMA=0x%lx cpu=0x%p size=%d", | ||
| 99 | (unsigned long) mantis->buf_dma, | ||
| 100 | mantis->buf_cpu, MANTIS_BUF_SIZE); | ||
| 101 | } | ||
| 102 | if (!mantis->risc_cpu) { | ||
| 103 | mantis->risc_cpu = pci_alloc_consistent(mantis->pdev, | ||
| 104 | MANTIS_RISC_SIZE, | ||
| 105 | &mantis->risc_dma); | ||
| 106 | |||
| 107 | if (!mantis->risc_cpu) { | ||
| 108 | dprintk(MANTIS_ERROR, 1, | ||
| 109 | "RISC program allocation failed"); | ||
| 110 | |||
| 111 | mantis_dma_exit(mantis); | ||
| 112 | |||
| 113 | goto err; | ||
| 114 | } | ||
| 115 | dprintk(MANTIS_ERROR, 1, | ||
| 116 | "RISC=0x%lx cpu=0x%p size=%lx", | ||
| 117 | (unsigned long) mantis->risc_dma, | ||
| 118 | mantis->risc_cpu, MANTIS_RISC_SIZE); | ||
| 119 | } | ||
| 120 | |||
| 121 | return 0; | ||
| 122 | err: | ||
| 123 | dprintk(MANTIS_ERROR, 1, "Out of memory (?) ....."); | ||
| 124 | return -ENOMEM; | ||
| 125 | } | ||
| 126 | |||
| 127 | static inline int mantis_calc_lines(struct mantis_pci *mantis) | ||
| 128 | { | ||
| 129 | mantis->line_bytes = MANTIS_BLOCK_BYTES; | ||
| 130 | mantis->line_count = MANTIS_BLOCK_COUNT; | ||
| 131 | |||
| 132 | while (mantis->line_bytes > 4095) { | ||
| 133 | mantis->line_bytes >>= 1; | ||
| 134 | mantis->line_count <<= 1; | ||
| 135 | } | ||
| 136 | |||
| 137 | dprintk(MANTIS_DEBUG, 1, "Mantis RISC block bytes=[%d], line bytes=[%d], line count=[%d]", | ||
| 138 | MANTIS_BLOCK_BYTES, mantis->line_bytes, mantis->line_count); | ||
| 139 | |||
| 140 | if (mantis->line_count > 255) { | ||
| 141 | dprintk(MANTIS_ERROR, 1, "Buffer size error"); | ||
| 142 | return -EINVAL; | ||
| 143 | } | ||
| 144 | |||
| 145 | return 0; | ||
| 146 | } | ||
| 147 | |||
| 148 | int mantis_dma_init(struct mantis_pci *mantis) | ||
| 149 | { | ||
| 150 | int err = 0; | ||
| 151 | |||
| 152 | dprintk(MANTIS_DEBUG, 1, "Mantis DMA init"); | ||
| 153 | if (mantis_alloc_buffers(mantis) < 0) { | ||
| 154 | dprintk(MANTIS_ERROR, 1, "Error allocating DMA buffer"); | ||
| 155 | |||
| 156 | /* Stop RISC Engine */ | ||
| 157 | mmwrite(0, MANTIS_DMA_CTL); | ||
| 158 | |||
| 159 | goto err; | ||
| 160 | } | ||
| 161 | err = mantis_calc_lines(mantis); | ||
| 162 | if (err < 0) { | ||
| 163 | dprintk(MANTIS_ERROR, 1, "Mantis calc lines failed"); | ||
| 164 | |||
| 165 | goto err; | ||
| 166 | } | ||
| 167 | |||
| 168 | return 0; | ||
| 169 | err: | ||
| 170 | return err; | ||
| 171 | } | ||
| 172 | EXPORT_SYMBOL_GPL(mantis_dma_init); | ||
| 173 | |||
| 174 | static inline void mantis_risc_program(struct mantis_pci *mantis) | ||
| 175 | { | ||
| 176 | u32 buf_pos = 0; | ||
| 177 | u32 line; | ||
| 178 | |||
| 179 | dprintk(MANTIS_DEBUG, 1, "Mantis create RISC program"); | ||
| 180 | RISC_FLUSH(); | ||
| 181 | |||
| 182 | dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u", | ||
| 183 | mantis->line_count, mantis->line_bytes); | ||
| 184 | |||
| 185 | for (line = 0; line < mantis->line_count; line++) { | ||
| 186 | dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d]", line); | ||
| 187 | if (!(buf_pos % MANTIS_BLOCK_BYTES)) { | ||
| 188 | RISC_INSTR(RISC_WRITE | | ||
| 189 | RISC_IRQ | | ||
| 190 | RISC_STATUS(((buf_pos / MANTIS_BLOCK_BYTES) + | ||
| 191 | (MANTIS_BLOCK_COUNT - 1)) % | ||
| 192 | MANTIS_BLOCK_COUNT) | | ||
| 193 | mantis->line_bytes); | ||
| 194 | } else { | ||
| 195 | RISC_INSTR(RISC_WRITE | mantis->line_bytes); | ||
| 196 | } | ||
| 197 | RISC_INSTR(mantis->buf_dma + buf_pos); | ||
| 198 | buf_pos += mantis->line_bytes; | ||
| 199 | } | ||
| 200 | RISC_INSTR(RISC_JUMP); | ||
| 201 | RISC_INSTR(mantis->risc_dma); | ||
| 202 | } | ||
| 203 | |||
| 204 | void mantis_dma_start(struct mantis_pci *mantis) | ||
| 205 | { | ||
| 206 | dprintk(MANTIS_DEBUG, 1, "Mantis Start DMA engine"); | ||
| 207 | |||
| 208 | mantis_risc_program(mantis); | ||
| 209 | mmwrite(mantis->risc_dma, MANTIS_RISC_START); | ||
| 210 | mmwrite(mmread(MANTIS_GPIF_ADDR) | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); | ||
| 211 | |||
| 212 | mmwrite(0, MANTIS_DMA_CTL); | ||
| 213 | mantis->last_block = mantis->finished_block = 0; | ||
| 214 | |||
| 215 | mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_RISCI, MANTIS_INT_MASK); | ||
| 216 | |||
| 217 | mmwrite(MANTIS_FIFO_EN | MANTIS_DCAP_EN | ||
| 218 | | MANTIS_RISC_EN, MANTIS_DMA_CTL); | ||
| 219 | |||
| 220 | } | ||
| 221 | |||
| 222 | void mantis_dma_stop(struct mantis_pci *mantis) | ||
| 223 | { | ||
| 224 | u32 stat = 0, mask = 0; | ||
| 225 | |||
| 226 | stat = mmread(MANTIS_INT_STAT); | ||
| 227 | mask = mmread(MANTIS_INT_MASK); | ||
| 228 | dprintk(MANTIS_DEBUG, 1, "Mantis Stop DMA engine"); | ||
| 229 | |||
| 230 | mmwrite((mmread(MANTIS_GPIF_ADDR) & (~(MANTIS_GPIF_HIFRDWRN))), MANTIS_GPIF_ADDR); | ||
| 231 | |||
| 232 | mmwrite((mmread(MANTIS_DMA_CTL) & ~(MANTIS_FIFO_EN | | ||
| 233 | MANTIS_DCAP_EN | | ||
| 234 | MANTIS_RISC_EN)), MANTIS_DMA_CTL); | ||
| 235 | |||
| 236 | mmwrite(mmread(MANTIS_INT_STAT), MANTIS_INT_STAT); | ||
| 237 | |||
| 238 | mmwrite(mmread(MANTIS_INT_MASK) & ~(MANTIS_INT_RISCI | | ||
| 239 | MANTIS_INT_RISCEN), MANTIS_INT_MASK); | ||
| 240 | } | ||
| 241 | |||
| 242 | |||
| 243 | void mantis_dma_xfer(unsigned long data) | ||
| 244 | { | ||
| 245 | struct mantis_pci *mantis = (struct mantis_pci *) data; | ||
| 246 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
| 247 | |||
| 248 | while (mantis->last_block != mantis->finished_block) { | ||
| 249 | dprintk(MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]", | ||
| 250 | mantis->last_block, mantis->finished_block); | ||
| 251 | |||
| 252 | (config->ts_size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter) | ||
| 253 | (&mantis->demux, &mantis->buf_cpu[mantis->last_block * MANTIS_BLOCK_BYTES], MANTIS_BLOCK_BYTES); | ||
| 254 | mantis->last_block = (mantis->last_block + 1) % MANTIS_BLOCK_COUNT; | ||
| 255 | } | ||
| 256 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_dma.h b/drivers/media/dvb/mantis/mantis_dma.h new file mode 100644 index 00000000000..6be00fa8209 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_dma.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_DMA_H | ||
| 22 | #define __MANTIS_DMA_H | ||
| 23 | |||
| 24 | extern int mantis_dma_init(struct mantis_pci *mantis); | ||
| 25 | extern int mantis_dma_exit(struct mantis_pci *mantis); | ||
| 26 | extern void mantis_dma_start(struct mantis_pci *mantis); | ||
| 27 | extern void mantis_dma_stop(struct mantis_pci *mantis); | ||
| 28 | extern void mantis_dma_xfer(unsigned long data); | ||
| 29 | |||
| 30 | #endif /* __MANTIS_DMA_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_dvb.c b/drivers/media/dvb/mantis/mantis_dvb.c new file mode 100644 index 00000000000..e5180e45d31 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_dvb.c | |||
| @@ -0,0 +1,299 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the Free Software | ||
| 17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/kernel.h> | ||
| 21 | #include <linux/bitops.h> | ||
| 22 | |||
| 23 | #include <linux/signal.h> | ||
| 24 | #include <linux/sched.h> | ||
| 25 | #include <linux/interrupt.h> | ||
| 26 | #include <linux/pci.h> | ||
| 27 | #include <linux/i2c.h> | ||
| 28 | |||
| 29 | #include "dmxdev.h" | ||
| 30 | #include "dvbdev.h" | ||
| 31 | #include "dvb_demux.h" | ||
| 32 | #include "dvb_frontend.h" | ||
| 33 | #include "dvb_net.h" | ||
| 34 | |||
| 35 | #include "mantis_common.h" | ||
| 36 | #include "mantis_dma.h" | ||
| 37 | #include "mantis_ca.h" | ||
| 38 | #include "mantis_ioc.h" | ||
| 39 | #include "mantis_dvb.h" | ||
| 40 | |||
| 41 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
| 42 | |||
| 43 | int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power) | ||
| 44 | { | ||
| 45 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
| 46 | |||
| 47 | switch (power) { | ||
| 48 | case POWER_ON: | ||
| 49 | dprintk(MANTIS_DEBUG, 1, "Power ON"); | ||
| 50 | mantis_gpio_set_bits(mantis, config->power, POWER_ON); | ||
| 51 | msleep(100); | ||
| 52 | mantis_gpio_set_bits(mantis, config->power, POWER_ON); | ||
| 53 | msleep(100); | ||
| 54 | break; | ||
| 55 | |||
| 56 | case POWER_OFF: | ||
| 57 | dprintk(MANTIS_DEBUG, 1, "Power OFF"); | ||
| 58 | mantis_gpio_set_bits(mantis, config->power, POWER_OFF); | ||
| 59 | msleep(100); | ||
| 60 | break; | ||
| 61 | |||
| 62 | default: | ||
| 63 | dprintk(MANTIS_DEBUG, 1, "Unknown state <%02x>", power); | ||
| 64 | return -1; | ||
| 65 | } | ||
| 66 | |||
| 67 | return 0; | ||
| 68 | } | ||
| 69 | EXPORT_SYMBOL_GPL(mantis_frontend_power); | ||
| 70 | |||
| 71 | void mantis_frontend_soft_reset(struct mantis_pci *mantis) | ||
| 72 | { | ||
| 73 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
| 74 | |||
| 75 | dprintk(MANTIS_DEBUG, 1, "Frontend RESET"); | ||
| 76 | mantis_gpio_set_bits(mantis, config->reset, 0); | ||
| 77 | msleep(100); | ||
| 78 | mantis_gpio_set_bits(mantis, config->reset, 0); | ||
| 79 | msleep(100); | ||
| 80 | mantis_gpio_set_bits(mantis, config->reset, 1); | ||
| 81 | msleep(100); | ||
| 82 | mantis_gpio_set_bits(mantis, config->reset, 1); | ||
| 83 | msleep(100); | ||
| 84 | |||
| 85 | return; | ||
| 86 | } | ||
| 87 | EXPORT_SYMBOL_GPL(mantis_frontend_soft_reset); | ||
| 88 | |||
| 89 | static int mantis_frontend_shutdown(struct mantis_pci *mantis) | ||
| 90 | { | ||
| 91 | int err; | ||
| 92 | |||
| 93 | mantis_frontend_soft_reset(mantis); | ||
| 94 | err = mantis_frontend_power(mantis, POWER_OFF); | ||
| 95 | if (err != 0) { | ||
| 96 | dprintk(MANTIS_ERROR, 1, "Frontend POWER OFF failed! <%d>", err); | ||
| 97 | return 1; | ||
| 98 | } | ||
| 99 | |||
| 100 | return 0; | ||
| 101 | } | ||
| 102 | |||
| 103 | static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
| 104 | { | ||
| 105 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
| 106 | struct mantis_pci *mantis = dvbdmx->priv; | ||
| 107 | |||
| 108 | dprintk(MANTIS_DEBUG, 1, "Mantis DVB Start feed"); | ||
| 109 | if (!dvbdmx->dmx.frontend) { | ||
| 110 | dprintk(MANTIS_DEBUG, 1, "no frontend ?"); | ||
| 111 | return -EINVAL; | ||
| 112 | } | ||
| 113 | |||
| 114 | mantis->feeds++; | ||
| 115 | dprintk(MANTIS_DEBUG, 1, "mantis start feed, feeds=%d", mantis->feeds); | ||
| 116 | |||
| 117 | if (mantis->feeds == 1) { | ||
| 118 | dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma"); | ||
| 119 | mantis_dma_start(mantis); | ||
| 120 | tasklet_enable(&mantis->tasklet); | ||
| 121 | } | ||
| 122 | |||
| 123 | return mantis->feeds; | ||
| 124 | } | ||
| 125 | |||
| 126 | static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
| 127 | { | ||
| 128 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
| 129 | struct mantis_pci *mantis = dvbdmx->priv; | ||
| 130 | |||
| 131 | dprintk(MANTIS_DEBUG, 1, "Mantis DVB Stop feed"); | ||
| 132 | if (!dvbdmx->dmx.frontend) { | ||
| 133 | dprintk(MANTIS_DEBUG, 1, "no frontend ?"); | ||
| 134 | return -EINVAL; | ||
| 135 | } | ||
| 136 | |||
| 137 | mantis->feeds--; | ||
| 138 | if (mantis->feeds == 0) { | ||
| 139 | dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma"); | ||
| 140 | tasklet_disable(&mantis->tasklet); | ||
| 141 | mantis_dma_stop(mantis); | ||
| 142 | } | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | int __devinit mantis_dvb_init(struct mantis_pci *mantis) | ||
| 148 | { | ||
| 149 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
| 150 | int result = -1; | ||
| 151 | |||
| 152 | dprintk(MANTIS_DEBUG, 1, "dvb_register_adapter"); | ||
| 153 | |||
| 154 | result = dvb_register_adapter(&mantis->dvb_adapter, | ||
| 155 | "Mantis DVB adapter", | ||
| 156 | THIS_MODULE, | ||
| 157 | &mantis->pdev->dev, | ||
| 158 | adapter_nr); | ||
| 159 | |||
| 160 | if (result < 0) { | ||
| 161 | |||
| 162 | dprintk(MANTIS_ERROR, 1, "Error registering adapter"); | ||
| 163 | return -ENODEV; | ||
| 164 | } | ||
| 165 | |||
| 166 | mantis->dvb_adapter.priv = mantis; | ||
| 167 | mantis->demux.dmx.capabilities = DMX_TS_FILTERING | | ||
| 168 | DMX_SECTION_FILTERING | | ||
| 169 | DMX_MEMORY_BASED_FILTERING; | ||
| 170 | |||
| 171 | mantis->demux.priv = mantis; | ||
| 172 | mantis->demux.filternum = 256; | ||
| 173 | mantis->demux.feednum = 256; | ||
| 174 | mantis->demux.start_feed = mantis_dvb_start_feed; | ||
| 175 | mantis->demux.stop_feed = mantis_dvb_stop_feed; | ||
| 176 | mantis->demux.write_to_decoder = NULL; | ||
| 177 | |||
| 178 | dprintk(MANTIS_DEBUG, 1, "dvb_dmx_init"); | ||
| 179 | result = dvb_dmx_init(&mantis->demux); | ||
| 180 | if (result < 0) { | ||
| 181 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
| 182 | |||
| 183 | goto err0; | ||
| 184 | } | ||
| 185 | |||
| 186 | mantis->dmxdev.filternum = 256; | ||
| 187 | mantis->dmxdev.demux = &mantis->demux.dmx; | ||
| 188 | mantis->dmxdev.capabilities = 0; | ||
| 189 | dprintk(MANTIS_DEBUG, 1, "dvb_dmxdev_init"); | ||
| 190 | |||
| 191 | result = dvb_dmxdev_init(&mantis->dmxdev, &mantis->dvb_adapter); | ||
| 192 | if (result < 0) { | ||
| 193 | |||
| 194 | dprintk(MANTIS_ERROR, 1, "dvb_dmxdev_init failed, ERROR=%d", result); | ||
| 195 | goto err1; | ||
| 196 | } | ||
| 197 | |||
| 198 | mantis->fe_hw.source = DMX_FRONTEND_0; | ||
| 199 | result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
| 200 | if (result < 0) { | ||
| 201 | |||
| 202 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
| 203 | goto err2; | ||
| 204 | } | ||
| 205 | |||
| 206 | mantis->fe_mem.source = DMX_MEMORY_FE; | ||
| 207 | result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_mem); | ||
| 208 | if (result < 0) { | ||
| 209 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
| 210 | goto err3; | ||
| 211 | } | ||
| 212 | |||
| 213 | result = mantis->demux.dmx.connect_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
| 214 | if (result < 0) { | ||
| 215 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
| 216 | goto err4; | ||
| 217 | } | ||
| 218 | |||
| 219 | dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx); | ||
| 220 | tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis); | ||
| 221 | tasklet_disable(&mantis->tasklet); | ||
| 222 | if (mantis->hwconfig) { | ||
| 223 | result = config->frontend_init(mantis, mantis->fe); | ||
| 224 | if (result < 0) { | ||
| 225 | dprintk(MANTIS_ERROR, 1, "!!! NO Frontends found !!!"); | ||
| 226 | goto err5; | ||
| 227 | } else { | ||
| 228 | if (mantis->fe == NULL) { | ||
| 229 | dprintk(MANTIS_ERROR, 1, "FE <NULL>"); | ||
| 230 | goto err5; | ||
| 231 | } | ||
| 232 | |||
| 233 | if (dvb_register_frontend(&mantis->dvb_adapter, mantis->fe)) { | ||
| 234 | dprintk(MANTIS_ERROR, 1, "ERROR: Frontend registration failed"); | ||
| 235 | |||
| 236 | if (mantis->fe->ops.release) | ||
| 237 | mantis->fe->ops.release(mantis->fe); | ||
| 238 | |||
| 239 | mantis->fe = NULL; | ||
| 240 | goto err5; | ||
| 241 | } | ||
| 242 | } | ||
| 243 | } | ||
| 244 | |||
| 245 | return 0; | ||
| 246 | |||
| 247 | /* Error conditions .. */ | ||
| 248 | err5: | ||
| 249 | tasklet_kill(&mantis->tasklet); | ||
| 250 | dvb_net_release(&mantis->dvbnet); | ||
| 251 | dvb_unregister_frontend(mantis->fe); | ||
| 252 | dvb_frontend_detach(mantis->fe); | ||
| 253 | err4: | ||
| 254 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); | ||
| 255 | |||
| 256 | err3: | ||
| 257 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
| 258 | |||
| 259 | err2: | ||
| 260 | dvb_dmxdev_release(&mantis->dmxdev); | ||
| 261 | |||
| 262 | err1: | ||
| 263 | dvb_dmx_release(&mantis->demux); | ||
| 264 | |||
| 265 | err0: | ||
| 266 | dvb_unregister_adapter(&mantis->dvb_adapter); | ||
| 267 | |||
| 268 | return result; | ||
| 269 | } | ||
| 270 | EXPORT_SYMBOL_GPL(mantis_dvb_init); | ||
| 271 | |||
| 272 | int __devexit mantis_dvb_exit(struct mantis_pci *mantis) | ||
| 273 | { | ||
| 274 | int err; | ||
| 275 | |||
| 276 | if (mantis->fe) { | ||
| 277 | /* mantis_ca_exit(mantis); */ | ||
| 278 | err = mantis_frontend_shutdown(mantis); | ||
| 279 | if (err != 0) | ||
| 280 | dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err); | ||
| 281 | dvb_unregister_frontend(mantis->fe); | ||
| 282 | dvb_frontend_detach(mantis->fe); | ||
| 283 | } | ||
| 284 | |||
| 285 | tasklet_kill(&mantis->tasklet); | ||
| 286 | dvb_net_release(&mantis->dvbnet); | ||
| 287 | |||
| 288 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); | ||
| 289 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
| 290 | |||
| 291 | dvb_dmxdev_release(&mantis->dmxdev); | ||
| 292 | dvb_dmx_release(&mantis->demux); | ||
| 293 | |||
| 294 | dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter"); | ||
| 295 | dvb_unregister_adapter(&mantis->dvb_adapter); | ||
| 296 | |||
| 297 | return 0; | ||
| 298 | } | ||
| 299 | EXPORT_SYMBOL_GPL(mantis_dvb_exit); | ||
diff --git a/drivers/media/dvb/mantis/mantis_dvb.h b/drivers/media/dvb/mantis/mantis_dvb.h new file mode 100644 index 00000000000..464199db304 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_dvb.h | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_DVB_H | ||
| 22 | #define __MANTIS_DVB_H | ||
| 23 | |||
| 24 | enum mantis_power { | ||
| 25 | POWER_OFF = 0, | ||
| 26 | POWER_ON = 1 | ||
| 27 | }; | ||
| 28 | |||
| 29 | extern int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power); | ||
| 30 | extern void mantis_frontend_soft_reset(struct mantis_pci *mantis); | ||
| 31 | |||
| 32 | extern int mantis_dvb_init(struct mantis_pci *mantis); | ||
| 33 | extern int mantis_dvb_exit(struct mantis_pci *mantis); | ||
| 34 | |||
| 35 | #endif /* __MANTIS_DVB_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_evm.c b/drivers/media/dvb/mantis/mantis_evm.c new file mode 100644 index 00000000000..36f2256ebb0 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_evm.c | |||
| @@ -0,0 +1,118 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/kernel.h> | ||
| 22 | |||
| 23 | #include <linux/signal.h> | ||
| 24 | #include <linux/sched.h> | ||
| 25 | #include <linux/interrupt.h> | ||
| 26 | #include <asm/io.h> | ||
| 27 | |||
| 28 | #include "dmxdev.h" | ||
| 29 | #include "dvbdev.h" | ||
| 30 | #include "dvb_demux.h" | ||
| 31 | #include "dvb_frontend.h" | ||
| 32 | #include "dvb_net.h" | ||
| 33 | |||
| 34 | #include "mantis_common.h" | ||
| 35 | #include "mantis_link.h" | ||
| 36 | #include "mantis_hif.h" | ||
| 37 | #include "mantis_reg.h" | ||
| 38 | |||
| 39 | static void mantis_hifevm_work(struct work_struct *work) | ||
| 40 | { | ||
| 41 | struct mantis_ca *ca = container_of(work, struct mantis_ca, hif_evm_work); | ||
| 42 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 43 | |||
| 44 | u32 gpif_stat, gpif_mask; | ||
| 45 | |||
| 46 | gpif_stat = mmread(MANTIS_GPIF_STATUS); | ||
| 47 | gpif_mask = mmread(MANTIS_GPIF_IRQCFG); | ||
| 48 | |||
| 49 | if (gpif_stat & MANTIS_GPIF_DETSTAT) { | ||
| 50 | if (gpif_stat & MANTIS_CARD_PLUGIN) { | ||
| 51 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Plugin", mantis->num); | ||
| 52 | mmwrite(0xdada0000, MANTIS_CARD_RESET); | ||
| 53 | mantis_event_cam_plugin(ca); | ||
| 54 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
| 55 | 0, | ||
| 56 | DVB_CA_EN50221_CAMCHANGE_INSERTED); | ||
| 57 | } | ||
| 58 | } else { | ||
| 59 | if (gpif_stat & MANTIS_CARD_PLUGOUT) { | ||
| 60 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Unplug", mantis->num); | ||
| 61 | mmwrite(0xdada0000, MANTIS_CARD_RESET); | ||
| 62 | mantis_event_cam_unplug(ca); | ||
| 63 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
| 64 | 0, | ||
| 65 | DVB_CA_EN50221_CAMCHANGE_REMOVED); | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | if (mantis->gpif_status & MANTIS_GPIF_EXTIRQ) | ||
| 70 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Ext IRQ", mantis->num); | ||
| 71 | |||
| 72 | if (mantis->gpif_status & MANTIS_SBUF_WSTO) | ||
| 73 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Timeout", mantis->num); | ||
| 74 | |||
| 75 | if (mantis->gpif_status & MANTIS_GPIF_OTHERR) | ||
| 76 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Alignment Error", mantis->num); | ||
| 77 | |||
| 78 | if (gpif_stat & MANTIS_SBUF_OVFLW) | ||
| 79 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Overflow", mantis->num); | ||
| 80 | |||
| 81 | if (gpif_stat & MANTIS_GPIF_BRRDY) | ||
| 82 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Read Ready", mantis->num); | ||
| 83 | |||
| 84 | if (gpif_stat & MANTIS_GPIF_INTSTAT) | ||
| 85 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): GPIF IRQ", mantis->num); | ||
| 86 | |||
| 87 | if (gpif_stat & MANTIS_SBUF_EMPTY) | ||
| 88 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Empty", mantis->num); | ||
| 89 | |||
| 90 | if (gpif_stat & MANTIS_SBUF_OPDONE) { | ||
| 91 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer operation complete", mantis->num); | ||
| 92 | ca->sbuf_status = MANTIS_SBUF_DATA_AVAIL; | ||
| 93 | ca->hif_event = MANTIS_SBUF_OPDONE; | ||
| 94 | wake_up(&ca->hif_opdone_wq); | ||
| 95 | } | ||
| 96 | } | ||
| 97 | |||
| 98 | int mantis_evmgr_init(struct mantis_ca *ca) | ||
| 99 | { | ||
| 100 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 101 | |||
| 102 | dprintk(MANTIS_DEBUG, 1, "Initializing Mantis Host I/F Event manager"); | ||
| 103 | INIT_WORK(&ca->hif_evm_work, mantis_hifevm_work); | ||
| 104 | mantis_pcmcia_init(ca); | ||
| 105 | schedule_work(&ca->hif_evm_work); | ||
| 106 | mantis_hif_init(ca); | ||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 110 | void mantis_evmgr_exit(struct mantis_ca *ca) | ||
| 111 | { | ||
| 112 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 113 | |||
| 114 | dprintk(MANTIS_DEBUG, 1, "Mantis Host I/F Event manager exiting"); | ||
| 115 | flush_work_sync(&ca->hif_evm_work); | ||
| 116 | mantis_hif_exit(ca); | ||
| 117 | mantis_pcmcia_exit(ca); | ||
| 118 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_hif.c b/drivers/media/dvb/mantis/mantis_hif.c new file mode 100644 index 00000000000..672cf4d2462 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_hif.c | |||
| @@ -0,0 +1,239 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/kernel.h> | ||
| 22 | #include <linux/signal.h> | ||
| 23 | #include <linux/sched.h> | ||
| 24 | |||
| 25 | #include <linux/interrupt.h> | ||
| 26 | #include <asm/io.h> | ||
| 27 | |||
| 28 | #include "dmxdev.h" | ||
| 29 | #include "dvbdev.h" | ||
| 30 | #include "dvb_demux.h" | ||
| 31 | #include "dvb_frontend.h" | ||
| 32 | #include "dvb_net.h" | ||
| 33 | |||
| 34 | #include "mantis_common.h" | ||
| 35 | |||
| 36 | #include "mantis_hif.h" | ||
| 37 | #include "mantis_link.h" /* temporary due to physical layer stuff */ | ||
| 38 | |||
| 39 | #include "mantis_reg.h" | ||
| 40 | |||
| 41 | |||
| 42 | static int mantis_hif_sbuf_opdone_wait(struct mantis_ca *ca) | ||
| 43 | { | ||
| 44 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 45 | int rc = 0; | ||
| 46 | |||
| 47 | if (wait_event_timeout(ca->hif_opdone_wq, | ||
| 48 | ca->hif_event & MANTIS_SBUF_OPDONE, | ||
| 49 | msecs_to_jiffies(500)) == -ERESTARTSYS) { | ||
| 50 | |||
| 51 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Smart buffer operation timeout !", mantis->num); | ||
| 52 | rc = -EREMOTEIO; | ||
| 53 | } | ||
| 54 | dprintk(MANTIS_DEBUG, 1, "Smart Buffer Operation complete"); | ||
| 55 | ca->hif_event &= ~MANTIS_SBUF_OPDONE; | ||
| 56 | return rc; | ||
| 57 | } | ||
| 58 | |||
| 59 | static int mantis_hif_write_wait(struct mantis_ca *ca) | ||
| 60 | { | ||
| 61 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 62 | u32 opdone = 0, timeout = 0; | ||
| 63 | int rc = 0; | ||
| 64 | |||
| 65 | if (wait_event_timeout(ca->hif_write_wq, | ||
| 66 | mantis->gpif_status & MANTIS_GPIF_WRACK, | ||
| 67 | msecs_to_jiffies(500)) == -ERESTARTSYS) { | ||
| 68 | |||
| 69 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write ACK timed out !", mantis->num); | ||
| 70 | rc = -EREMOTEIO; | ||
| 71 | } | ||
| 72 | dprintk(MANTIS_DEBUG, 1, "Write Acknowledged"); | ||
| 73 | mantis->gpif_status &= ~MANTIS_GPIF_WRACK; | ||
| 74 | while (!opdone) { | ||
| 75 | opdone = (mmread(MANTIS_GPIF_STATUS) & MANTIS_SBUF_OPDONE); | ||
| 76 | udelay(500); | ||
| 77 | timeout++; | ||
| 78 | if (timeout > 100) { | ||
| 79 | dprintk(MANTIS_ERROR, 1, "Adater(%d) Slot(0): Write operation timed out!", mantis->num); | ||
| 80 | rc = -ETIMEDOUT; | ||
| 81 | break; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | dprintk(MANTIS_DEBUG, 1, "HIF Write success"); | ||
| 85 | return rc; | ||
| 86 | } | ||
| 87 | |||
| 88 | |||
| 89 | int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr) | ||
| 90 | { | ||
| 91 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 92 | u32 hif_addr = 0, data, count = 4; | ||
| 93 | |||
| 94 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Read", mantis->num); | ||
| 95 | mutex_lock(&ca->ca_lock); | ||
| 96 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
| 97 | hif_addr &= ~MANTIS_GPIF_PCMCIAIOM; | ||
| 98 | hif_addr |= MANTIS_HIF_STATUS; | ||
| 99 | hif_addr |= addr; | ||
| 100 | |||
| 101 | mmwrite(hif_addr, MANTIS_GPIF_BRADDR); | ||
| 102 | mmwrite(count, MANTIS_GPIF_BRBYTES); | ||
| 103 | udelay(20); | ||
| 104 | mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); | ||
| 105 | |||
| 106 | if (mantis_hif_sbuf_opdone_wait(ca) != 0) { | ||
| 107 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): GPIF Smart Buffer operation failed", mantis->num); | ||
| 108 | mutex_unlock(&ca->ca_lock); | ||
| 109 | return -EREMOTEIO; | ||
| 110 | } | ||
| 111 | data = mmread(MANTIS_GPIF_DIN); | ||
| 112 | mutex_unlock(&ca->ca_lock); | ||
| 113 | dprintk(MANTIS_DEBUG, 1, "Mem Read: 0x%02x", data); | ||
| 114 | return (data >> 24) & 0xff; | ||
| 115 | } | ||
| 116 | |||
| 117 | int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data) | ||
| 118 | { | ||
| 119 | struct mantis_slot *slot = ca->slot; | ||
| 120 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 121 | u32 hif_addr = 0; | ||
| 122 | |||
| 123 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Write", mantis->num); | ||
| 124 | mutex_lock(&ca->ca_lock); | ||
| 125 | hif_addr &= ~MANTIS_GPIF_HIFRDWRN; | ||
| 126 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
| 127 | hif_addr &= ~MANTIS_GPIF_PCMCIAIOM; | ||
| 128 | hif_addr |= MANTIS_HIF_STATUS; | ||
| 129 | hif_addr |= addr; | ||
| 130 | |||
| 131 | mmwrite(slot->slave_cfg, MANTIS_GPIF_CFGSLA); /* Slot0 alone for now */ | ||
| 132 | mmwrite(hif_addr, MANTIS_GPIF_ADDR); | ||
| 133 | mmwrite(data, MANTIS_GPIF_DOUT); | ||
| 134 | |||
| 135 | if (mantis_hif_write_wait(ca) != 0) { | ||
| 136 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); | ||
| 137 | mutex_unlock(&ca->ca_lock); | ||
| 138 | return -EREMOTEIO; | ||
| 139 | } | ||
| 140 | dprintk(MANTIS_DEBUG, 1, "Mem Write: (0x%02x to 0x%02x)", data, addr); | ||
| 141 | mutex_unlock(&ca->ca_lock); | ||
| 142 | |||
| 143 | return 0; | ||
| 144 | } | ||
| 145 | |||
| 146 | int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr) | ||
| 147 | { | ||
| 148 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 149 | u32 data, hif_addr = 0; | ||
| 150 | |||
| 151 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Read", mantis->num); | ||
| 152 | mutex_lock(&ca->ca_lock); | ||
| 153 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
| 154 | hif_addr |= MANTIS_GPIF_PCMCIAIOM; | ||
| 155 | hif_addr |= MANTIS_HIF_STATUS; | ||
| 156 | hif_addr |= addr; | ||
| 157 | |||
| 158 | mmwrite(hif_addr, MANTIS_GPIF_BRADDR); | ||
| 159 | mmwrite(1, MANTIS_GPIF_BRBYTES); | ||
| 160 | udelay(20); | ||
| 161 | mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); | ||
| 162 | |||
| 163 | if (mantis_hif_sbuf_opdone_wait(ca) != 0) { | ||
| 164 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); | ||
| 165 | mutex_unlock(&ca->ca_lock); | ||
| 166 | return -EREMOTEIO; | ||
| 167 | } | ||
| 168 | data = mmread(MANTIS_GPIF_DIN); | ||
| 169 | dprintk(MANTIS_DEBUG, 1, "I/O Read: 0x%02x", data); | ||
| 170 | udelay(50); | ||
| 171 | mutex_unlock(&ca->ca_lock); | ||
| 172 | |||
| 173 | return (u8) data; | ||
| 174 | } | ||
| 175 | |||
| 176 | int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data) | ||
| 177 | { | ||
| 178 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 179 | u32 hif_addr = 0; | ||
| 180 | |||
| 181 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Write", mantis->num); | ||
| 182 | mutex_lock(&ca->ca_lock); | ||
| 183 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
| 184 | hif_addr &= ~MANTIS_GPIF_HIFRDWRN; | ||
| 185 | hif_addr |= MANTIS_GPIF_PCMCIAIOM; | ||
| 186 | hif_addr |= MANTIS_HIF_STATUS; | ||
| 187 | hif_addr |= addr; | ||
| 188 | |||
| 189 | mmwrite(hif_addr, MANTIS_GPIF_ADDR); | ||
| 190 | mmwrite(data, MANTIS_GPIF_DOUT); | ||
| 191 | |||
| 192 | if (mantis_hif_write_wait(ca) != 0) { | ||
| 193 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); | ||
| 194 | mutex_unlock(&ca->ca_lock); | ||
| 195 | return -EREMOTEIO; | ||
| 196 | } | ||
| 197 | dprintk(MANTIS_DEBUG, 1, "I/O Write: (0x%02x to 0x%02x)", data, addr); | ||
| 198 | mutex_unlock(&ca->ca_lock); | ||
| 199 | udelay(50); | ||
| 200 | |||
| 201 | return 0; | ||
| 202 | } | ||
| 203 | |||
| 204 | int mantis_hif_init(struct mantis_ca *ca) | ||
| 205 | { | ||
| 206 | struct mantis_slot *slot = ca->slot; | ||
| 207 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 208 | u32 irqcfg; | ||
| 209 | |||
| 210 | slot[0].slave_cfg = 0x70773028; | ||
| 211 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Initializing Mantis Host Interface", mantis->num); | ||
| 212 | |||
| 213 | mutex_lock(&ca->ca_lock); | ||
| 214 | irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
| 215 | irqcfg = MANTIS_MASK_BRRDY | | ||
| 216 | MANTIS_MASK_WRACK | | ||
| 217 | MANTIS_MASK_EXTIRQ | | ||
| 218 | MANTIS_MASK_WSTO | | ||
| 219 | MANTIS_MASK_OTHERR | | ||
| 220 | MANTIS_MASK_OVFLW; | ||
| 221 | |||
| 222 | mmwrite(irqcfg, MANTIS_GPIF_IRQCFG); | ||
| 223 | mutex_unlock(&ca->ca_lock); | ||
| 224 | |||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | |||
| 228 | void mantis_hif_exit(struct mantis_ca *ca) | ||
| 229 | { | ||
| 230 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 231 | u32 irqcfg; | ||
| 232 | |||
| 233 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Exiting Mantis Host Interface", mantis->num); | ||
| 234 | mutex_lock(&ca->ca_lock); | ||
| 235 | irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
| 236 | irqcfg &= ~MANTIS_MASK_BRRDY; | ||
| 237 | mmwrite(irqcfg, MANTIS_GPIF_IRQCFG); | ||
| 238 | mutex_unlock(&ca->ca_lock); | ||
| 239 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_hif.h b/drivers/media/dvb/mantis/mantis_hif.h new file mode 100644 index 00000000000..9094f9ed236 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_hif.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_HIF_H | ||
| 22 | #define __MANTIS_HIF_H | ||
| 23 | |||
| 24 | #define MANTIS_HIF_MEMRD 1 | ||
| 25 | #define MANTIS_HIF_MEMWR 2 | ||
| 26 | #define MANTIS_HIF_IOMRD 3 | ||
| 27 | #define MANTIS_HIF_IOMWR 4 | ||
| 28 | |||
| 29 | #endif /* __MANTIS_HIF_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_i2c.c b/drivers/media/dvb/mantis/mantis_i2c.c new file mode 100644 index 00000000000..e7794517fe2 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_i2c.c | |||
| @@ -0,0 +1,266 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <asm/io.h> | ||
| 22 | #include <linux/ioport.h> | ||
| 23 | #include <linux/pci.h> | ||
| 24 | #include <linux/i2c.h> | ||
| 25 | |||
| 26 | #include "dmxdev.h" | ||
| 27 | #include "dvbdev.h" | ||
| 28 | #include "dvb_demux.h" | ||
| 29 | #include "dvb_frontend.h" | ||
| 30 | #include "dvb_net.h" | ||
| 31 | |||
| 32 | #include "mantis_common.h" | ||
| 33 | #include "mantis_reg.h" | ||
| 34 | #include "mantis_i2c.h" | ||
| 35 | |||
| 36 | #define TRIALS 10000 | ||
| 37 | |||
| 38 | static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg) | ||
| 39 | { | ||
| 40 | u32 rxd, i, stat, trials; | ||
| 41 | |||
| 42 | dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <R>[ ", | ||
| 43 | __func__, msg->addr); | ||
| 44 | |||
| 45 | for (i = 0; i < msg->len; i++) { | ||
| 46 | rxd = (msg->addr << 25) | (1 << 24) | ||
| 47 | | MANTIS_I2C_RATE_3 | ||
| 48 | | MANTIS_I2C_STOP | ||
| 49 | | MANTIS_I2C_PGMODE; | ||
| 50 | |||
| 51 | if (i == (msg->len - 1)) | ||
| 52 | rxd &= ~MANTIS_I2C_STOP; | ||
| 53 | |||
| 54 | mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT); | ||
| 55 | mmwrite(rxd, MANTIS_I2CDATA_CTL); | ||
| 56 | |||
| 57 | /* wait for xfer completion */ | ||
| 58 | for (trials = 0; trials < TRIALS; trials++) { | ||
| 59 | stat = mmread(MANTIS_INT_STAT); | ||
| 60 | if (stat & MANTIS_INT_I2CDONE) | ||
| 61 | break; | ||
| 62 | } | ||
| 63 | |||
| 64 | dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials); | ||
| 65 | |||
| 66 | /* wait for xfer completion */ | ||
| 67 | for (trials = 0; trials < TRIALS; trials++) { | ||
| 68 | stat = mmread(MANTIS_INT_STAT); | ||
| 69 | if (stat & MANTIS_INT_I2CRACK) | ||
| 70 | break; | ||
| 71 | } | ||
| 72 | |||
| 73 | dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials); | ||
| 74 | |||
| 75 | rxd = mmread(MANTIS_I2CDATA_CTL); | ||
| 76 | msg->buf[i] = (u8)((rxd >> 8) & 0xFF); | ||
| 77 | dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]); | ||
| 78 | } | ||
| 79 | dprintk(MANTIS_INFO, 0, "]\n"); | ||
| 80 | |||
| 81 | return 0; | ||
| 82 | } | ||
| 83 | |||
| 84 | static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg) | ||
| 85 | { | ||
| 86 | int i; | ||
| 87 | u32 txd = 0, stat, trials; | ||
| 88 | |||
| 89 | dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <W>[ ", | ||
| 90 | __func__, msg->addr); | ||
| 91 | |||
| 92 | for (i = 0; i < msg->len; i++) { | ||
| 93 | dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]); | ||
| 94 | txd = (msg->addr << 25) | (msg->buf[i] << 8) | ||
| 95 | | MANTIS_I2C_RATE_3 | ||
| 96 | | MANTIS_I2C_STOP | ||
| 97 | | MANTIS_I2C_PGMODE; | ||
| 98 | |||
| 99 | if (i == (msg->len - 1)) | ||
| 100 | txd &= ~MANTIS_I2C_STOP; | ||
| 101 | |||
| 102 | mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT); | ||
| 103 | mmwrite(txd, MANTIS_I2CDATA_CTL); | ||
| 104 | |||
| 105 | /* wait for xfer completion */ | ||
| 106 | for (trials = 0; trials < TRIALS; trials++) { | ||
| 107 | stat = mmread(MANTIS_INT_STAT); | ||
| 108 | if (stat & MANTIS_INT_I2CDONE) | ||
| 109 | break; | ||
| 110 | } | ||
| 111 | |||
| 112 | dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials); | ||
| 113 | |||
| 114 | /* wait for xfer completion */ | ||
| 115 | for (trials = 0; trials < TRIALS; trials++) { | ||
| 116 | stat = mmread(MANTIS_INT_STAT); | ||
| 117 | if (stat & MANTIS_INT_I2CRACK) | ||
| 118 | break; | ||
| 119 | } | ||
| 120 | |||
| 121 | dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials); | ||
| 122 | } | ||
| 123 | dprintk(MANTIS_INFO, 0, "]\n"); | ||
| 124 | |||
| 125 | return 0; | ||
| 126 | } | ||
| 127 | |||
| 128 | static int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) | ||
| 129 | { | ||
| 130 | int ret = 0, i = 0, trials; | ||
| 131 | u32 stat, data, txd; | ||
| 132 | struct mantis_pci *mantis; | ||
| 133 | struct mantis_hwconfig *config; | ||
| 134 | |||
| 135 | mantis = i2c_get_adapdata(adapter); | ||
| 136 | BUG_ON(!mantis); | ||
| 137 | config = mantis->hwconfig; | ||
| 138 | BUG_ON(!config); | ||
| 139 | |||
| 140 | dprintk(MANTIS_DEBUG, 1, "Messages:%d", num); | ||
| 141 | mutex_lock(&mantis->i2c_lock); | ||
| 142 | |||
| 143 | while (i < num) { | ||
| 144 | /* Byte MODE */ | ||
| 145 | if ((config->i2c_mode & MANTIS_BYTE_MODE) && | ||
| 146 | ((i + 1) < num) && | ||
| 147 | (msgs[i].len < 2) && | ||
| 148 | (msgs[i + 1].len < 2) && | ||
| 149 | (msgs[i + 1].flags & I2C_M_RD)) { | ||
| 150 | |||
| 151 | dprintk(MANTIS_DEBUG, 0, " Byte MODE:\n"); | ||
| 152 | |||
| 153 | /* Read operation */ | ||
| 154 | txd = msgs[i].addr << 25 | (0x1 << 24) | ||
| 155 | | (msgs[i].buf[0] << 16) | ||
| 156 | | MANTIS_I2C_RATE_3; | ||
| 157 | |||
| 158 | mmwrite(txd, MANTIS_I2CDATA_CTL); | ||
| 159 | /* wait for xfer completion */ | ||
| 160 | for (trials = 0; trials < TRIALS; trials++) { | ||
| 161 | stat = mmread(MANTIS_INT_STAT); | ||
| 162 | if (stat & MANTIS_INT_I2CDONE) | ||
| 163 | break; | ||
| 164 | } | ||
| 165 | |||
| 166 | /* check for xfer completion */ | ||
| 167 | if (stat & MANTIS_INT_I2CDONE) { | ||
| 168 | /* check xfer was acknowledged */ | ||
| 169 | if (stat & MANTIS_INT_I2CRACK) { | ||
| 170 | data = mmread(MANTIS_I2CDATA_CTL); | ||
| 171 | msgs[i + 1].buf[0] = (data >> 8) & 0xff; | ||
| 172 | dprintk(MANTIS_DEBUG, 0, " Byte <%d> RXD=0x%02x [%02x]\n", 0x0, data, msgs[i + 1].buf[0]); | ||
| 173 | } else { | ||
| 174 | /* I/O error */ | ||
| 175 | dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__); | ||
| 176 | ret = -EIO; | ||
| 177 | break; | ||
| 178 | } | ||
| 179 | } else { | ||
| 180 | /* I/O error */ | ||
| 181 | dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__); | ||
| 182 | ret = -EIO; | ||
| 183 | break; | ||
| 184 | } | ||
| 185 | i += 2; /* Write/Read operation in one go */ | ||
| 186 | } | ||
| 187 | |||
| 188 | if (i < num) { | ||
| 189 | if (msgs[i].flags & I2C_M_RD) | ||
| 190 | ret = mantis_i2c_read(mantis, &msgs[i]); | ||
| 191 | else | ||
| 192 | ret = mantis_i2c_write(mantis, &msgs[i]); | ||
| 193 | |||
| 194 | i++; | ||
| 195 | if (ret < 0) | ||
| 196 | goto bail_out; | ||
| 197 | } | ||
| 198 | |||
| 199 | } | ||
| 200 | |||
| 201 | mutex_unlock(&mantis->i2c_lock); | ||
| 202 | |||
| 203 | return num; | ||
| 204 | |||
| 205 | bail_out: | ||
| 206 | mutex_unlock(&mantis->i2c_lock); | ||
| 207 | return ret; | ||
| 208 | } | ||
| 209 | |||
| 210 | static u32 mantis_i2c_func(struct i2c_adapter *adapter) | ||
| 211 | { | ||
| 212 | return I2C_FUNC_SMBUS_EMUL; | ||
| 213 | } | ||
| 214 | |||
| 215 | static struct i2c_algorithm mantis_algo = { | ||
| 216 | .master_xfer = mantis_i2c_xfer, | ||
| 217 | .functionality = mantis_i2c_func, | ||
| 218 | }; | ||
| 219 | |||
| 220 | int __devinit mantis_i2c_init(struct mantis_pci *mantis) | ||
| 221 | { | ||
| 222 | u32 intstat, intmask; | ||
| 223 | struct i2c_adapter *i2c_adapter = &mantis->adapter; | ||
| 224 | struct pci_dev *pdev = mantis->pdev; | ||
| 225 | |||
| 226 | init_waitqueue_head(&mantis->i2c_wq); | ||
| 227 | mutex_init(&mantis->i2c_lock); | ||
| 228 | strncpy(i2c_adapter->name, "Mantis I2C", sizeof(i2c_adapter->name)); | ||
| 229 | i2c_set_adapdata(i2c_adapter, mantis); | ||
| 230 | |||
| 231 | i2c_adapter->owner = THIS_MODULE; | ||
| 232 | i2c_adapter->algo = &mantis_algo; | ||
| 233 | i2c_adapter->algo_data = NULL; | ||
| 234 | i2c_adapter->timeout = 500; | ||
| 235 | i2c_adapter->retries = 3; | ||
| 236 | i2c_adapter->dev.parent = &pdev->dev; | ||
| 237 | |||
| 238 | mantis->i2c_rc = i2c_add_adapter(i2c_adapter); | ||
| 239 | if (mantis->i2c_rc < 0) | ||
| 240 | return mantis->i2c_rc; | ||
| 241 | |||
| 242 | dprintk(MANTIS_DEBUG, 1, "Initializing I2C .."); | ||
| 243 | |||
| 244 | intstat = mmread(MANTIS_INT_STAT); | ||
| 245 | intmask = mmread(MANTIS_INT_MASK); | ||
| 246 | mmwrite(intstat, MANTIS_INT_STAT); | ||
| 247 | dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); | ||
| 248 | intmask = mmread(MANTIS_INT_MASK); | ||
| 249 | mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK); | ||
| 250 | |||
| 251 | return 0; | ||
| 252 | } | ||
| 253 | EXPORT_SYMBOL_GPL(mantis_i2c_init); | ||
| 254 | |||
| 255 | int mantis_i2c_exit(struct mantis_pci *mantis) | ||
| 256 | { | ||
| 257 | u32 intmask; | ||
| 258 | |||
| 259 | dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); | ||
| 260 | intmask = mmread(MANTIS_INT_MASK); | ||
| 261 | mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK); | ||
| 262 | |||
| 263 | dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter"); | ||
| 264 | return i2c_del_adapter(&mantis->adapter); | ||
| 265 | } | ||
| 266 | EXPORT_SYMBOL_GPL(mantis_i2c_exit); | ||
diff --git a/drivers/media/dvb/mantis/mantis_i2c.h b/drivers/media/dvb/mantis/mantis_i2c.h new file mode 100644 index 00000000000..1342df2faed --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_i2c.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_I2C_H | ||
| 22 | #define __MANTIS_I2C_H | ||
| 23 | |||
| 24 | #define I2C_STOP (1 << 0) | ||
| 25 | #define I2C_READ (1 << 1) | ||
| 26 | |||
| 27 | extern int mantis_i2c_init(struct mantis_pci *mantis); | ||
| 28 | extern int mantis_i2c_exit(struct mantis_pci *mantis); | ||
| 29 | |||
| 30 | #endif /* __MANTIS_I2C_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_input.c b/drivers/media/dvb/mantis/mantis_input.c new file mode 100644 index 00000000000..db6d54d3fec --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_input.c | |||
| @@ -0,0 +1,159 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <media/rc-core.h> | ||
| 22 | #include <linux/pci.h> | ||
| 23 | |||
| 24 | #include "dmxdev.h" | ||
| 25 | #include "dvbdev.h" | ||
| 26 | #include "dvb_demux.h" | ||
| 27 | #include "dvb_frontend.h" | ||
| 28 | #include "dvb_net.h" | ||
| 29 | |||
| 30 | #include "mantis_common.h" | ||
| 31 | #include "mantis_reg.h" | ||
| 32 | #include "mantis_uart.h" | ||
| 33 | |||
| 34 | #define MODULE_NAME "mantis_core" | ||
| 35 | #define RC_MAP_MANTIS "rc-mantis" | ||
| 36 | |||
| 37 | static struct rc_map_table mantis_ir_table[] = { | ||
| 38 | { 0x29, KEY_POWER }, | ||
| 39 | { 0x28, KEY_FAVORITES }, | ||
| 40 | { 0x30, KEY_TEXT }, | ||
| 41 | { 0x17, KEY_INFO }, /* Preview */ | ||
| 42 | { 0x23, KEY_EPG }, | ||
| 43 | { 0x3b, KEY_F22 }, /* Record List */ | ||
| 44 | { 0x3c, KEY_1 }, | ||
| 45 | { 0x3e, KEY_2 }, | ||
| 46 | { 0x39, KEY_3 }, | ||
| 47 | { 0x36, KEY_4 }, | ||
| 48 | { 0x22, KEY_5 }, | ||
| 49 | { 0x20, KEY_6 }, | ||
| 50 | { 0x32, KEY_7 }, | ||
| 51 | { 0x26, KEY_8 }, | ||
| 52 | { 0x24, KEY_9 }, | ||
| 53 | { 0x2a, KEY_0 }, | ||
| 54 | |||
| 55 | { 0x33, KEY_CANCEL }, | ||
| 56 | { 0x2c, KEY_BACK }, | ||
| 57 | { 0x15, KEY_CLEAR }, | ||
| 58 | { 0x3f, KEY_TAB }, | ||
| 59 | { 0x10, KEY_ENTER }, | ||
| 60 | { 0x14, KEY_UP }, | ||
| 61 | { 0x0d, KEY_RIGHT }, | ||
| 62 | { 0x0e, KEY_DOWN }, | ||
| 63 | { 0x11, KEY_LEFT }, | ||
| 64 | |||
| 65 | { 0x21, KEY_VOLUMEUP }, | ||
| 66 | { 0x35, KEY_VOLUMEDOWN }, | ||
| 67 | { 0x3d, KEY_CHANNELDOWN }, | ||
| 68 | { 0x3a, KEY_CHANNELUP }, | ||
| 69 | { 0x2e, KEY_RECORD }, | ||
| 70 | { 0x2b, KEY_PLAY }, | ||
| 71 | { 0x13, KEY_PAUSE }, | ||
| 72 | { 0x25, KEY_STOP }, | ||
| 73 | |||
| 74 | { 0x1f, KEY_REWIND }, | ||
| 75 | { 0x2d, KEY_FASTFORWARD }, | ||
| 76 | { 0x1e, KEY_PREVIOUS }, /* Replay |< */ | ||
| 77 | { 0x1d, KEY_NEXT }, /* Skip >| */ | ||
| 78 | |||
| 79 | { 0x0b, KEY_CAMERA }, /* Capture */ | ||
| 80 | { 0x0f, KEY_LANGUAGE }, /* SAP */ | ||
| 81 | { 0x18, KEY_MODE }, /* PIP */ | ||
| 82 | { 0x12, KEY_ZOOM }, /* Full screen */ | ||
| 83 | { 0x1c, KEY_SUBTITLE }, | ||
| 84 | { 0x2f, KEY_MUTE }, | ||
| 85 | { 0x16, KEY_F20 }, /* L/R */ | ||
| 86 | { 0x38, KEY_F21 }, /* Hibernate */ | ||
| 87 | |||
| 88 | { 0x37, KEY_SWITCHVIDEOMODE }, /* A/V */ | ||
| 89 | { 0x31, KEY_AGAIN }, /* Recall */ | ||
| 90 | { 0x1a, KEY_KPPLUS }, /* Zoom+ */ | ||
| 91 | { 0x19, KEY_KPMINUS }, /* Zoom- */ | ||
| 92 | { 0x27, KEY_RED }, | ||
| 93 | { 0x0C, KEY_GREEN }, | ||
| 94 | { 0x01, KEY_YELLOW }, | ||
| 95 | { 0x00, KEY_BLUE }, | ||
| 96 | }; | ||
| 97 | |||
| 98 | static struct rc_map_list ir_mantis_map = { | ||
| 99 | .map = { | ||
| 100 | .scan = mantis_ir_table, | ||
| 101 | .size = ARRAY_SIZE(mantis_ir_table), | ||
| 102 | .rc_type = RC_TYPE_UNKNOWN, | ||
| 103 | .name = RC_MAP_MANTIS, | ||
| 104 | } | ||
| 105 | }; | ||
| 106 | |||
| 107 | int mantis_input_init(struct mantis_pci *mantis) | ||
| 108 | { | ||
| 109 | struct rc_dev *dev; | ||
| 110 | int err; | ||
| 111 | |||
| 112 | err = rc_map_register(&ir_mantis_map); | ||
| 113 | if (err) | ||
| 114 | goto out; | ||
| 115 | |||
| 116 | dev = rc_allocate_device(); | ||
| 117 | if (!dev) { | ||
| 118 | dprintk(MANTIS_ERROR, 1, "Remote device allocation failed"); | ||
| 119 | err = -ENOMEM; | ||
| 120 | goto out_map; | ||
| 121 | } | ||
| 122 | |||
| 123 | sprintf(mantis->input_name, "Mantis %s IR receiver", mantis->hwconfig->model_name); | ||
| 124 | sprintf(mantis->input_phys, "pci-%s/ir0", pci_name(mantis->pdev)); | ||
| 125 | |||
| 126 | dev->input_name = mantis->input_name; | ||
| 127 | dev->input_phys = mantis->input_phys; | ||
| 128 | dev->input_id.bustype = BUS_PCI; | ||
| 129 | dev->input_id.vendor = mantis->vendor_id; | ||
| 130 | dev->input_id.product = mantis->device_id; | ||
| 131 | dev->input_id.version = 1; | ||
| 132 | dev->driver_name = MODULE_NAME; | ||
| 133 | dev->map_name = RC_MAP_MANTIS; | ||
| 134 | dev->dev.parent = &mantis->pdev->dev; | ||
| 135 | |||
| 136 | err = rc_register_device(dev); | ||
| 137 | if (err) { | ||
| 138 | dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err); | ||
| 139 | goto out_dev; | ||
| 140 | } | ||
| 141 | |||
| 142 | mantis->rc = dev; | ||
| 143 | return 0; | ||
| 144 | |||
| 145 | out_dev: | ||
| 146 | rc_free_device(dev); | ||
| 147 | out_map: | ||
| 148 | rc_map_unregister(&ir_mantis_map); | ||
| 149 | out: | ||
| 150 | return err; | ||
| 151 | } | ||
| 152 | |||
| 153 | int mantis_exit(struct mantis_pci *mantis) | ||
| 154 | { | ||
| 155 | rc_unregister_device(mantis->rc); | ||
| 156 | rc_map_unregister(&ir_mantis_map); | ||
| 157 | return 0; | ||
| 158 | } | ||
| 159 | |||
diff --git a/drivers/media/dvb/mantis/mantis_ioc.c b/drivers/media/dvb/mantis/mantis_ioc.c new file mode 100644 index 00000000000..24fcdc63d6d --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_ioc.c | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/kernel.h> | ||
| 22 | #include <linux/i2c.h> | ||
| 23 | |||
| 24 | #include <linux/signal.h> | ||
| 25 | #include <linux/sched.h> | ||
| 26 | #include <linux/interrupt.h> | ||
| 27 | #include <asm/io.h> | ||
| 28 | |||
| 29 | #include "dmxdev.h" | ||
| 30 | #include "dvbdev.h" | ||
| 31 | #include "dvb_demux.h" | ||
| 32 | #include "dvb_frontend.h" | ||
| 33 | #include "dvb_net.h" | ||
| 34 | |||
| 35 | #include "mantis_common.h" | ||
| 36 | #include "mantis_reg.h" | ||
| 37 | #include "mantis_ioc.h" | ||
| 38 | |||
| 39 | static int read_eeprom_bytes(struct mantis_pci *mantis, u8 reg, u8 *data, u8 length) | ||
| 40 | { | ||
| 41 | struct i2c_adapter *adapter = &mantis->adapter; | ||
| 42 | int err; | ||
| 43 | u8 buf = reg; | ||
| 44 | |||
| 45 | struct i2c_msg msg[] = { | ||
| 46 | { .addr = 0x50, .flags = 0, .buf = &buf, .len = 1 }, | ||
| 47 | { .addr = 0x50, .flags = I2C_M_RD, .buf = data, .len = length }, | ||
| 48 | }; | ||
| 49 | |||
| 50 | err = i2c_transfer(adapter, msg, 2); | ||
| 51 | if (err < 0) { | ||
| 52 | dprintk(MANTIS_ERROR, 1, "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >", | ||
| 53 | err, data[0], data[1]); | ||
| 54 | |||
| 55 | return err; | ||
| 56 | } | ||
| 57 | |||
| 58 | return 0; | ||
| 59 | } | ||
| 60 | int mantis_get_mac(struct mantis_pci *mantis) | ||
| 61 | { | ||
| 62 | int err; | ||
| 63 | u8 mac_addr[6] = {0}; | ||
| 64 | |||
| 65 | err = read_eeprom_bytes(mantis, 0x08, mac_addr, 6); | ||
| 66 | if (err < 0) { | ||
| 67 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis EEPROM read error <%d>", err); | ||
| 68 | |||
| 69 | return err; | ||
| 70 | } | ||
| 71 | |||
| 72 | dprintk(MANTIS_ERROR, 0, " MAC Address=[%pM]\n", mac_addr); | ||
| 73 | |||
| 74 | return 0; | ||
| 75 | } | ||
| 76 | EXPORT_SYMBOL_GPL(mantis_get_mac); | ||
| 77 | |||
| 78 | /* Turn the given bit on or off. */ | ||
| 79 | void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value) | ||
| 80 | { | ||
| 81 | u32 cur; | ||
| 82 | |||
| 83 | dprintk(MANTIS_DEBUG, 1, "Set Bit <%d> to <%d>", bitpos, value); | ||
| 84 | cur = mmread(MANTIS_GPIF_ADDR); | ||
| 85 | if (value) | ||
| 86 | mantis->gpio_status = cur | (1 << bitpos); | ||
| 87 | else | ||
| 88 | mantis->gpio_status = cur & (~(1 << bitpos)); | ||
| 89 | |||
| 90 | dprintk(MANTIS_DEBUG, 1, "GPIO Value <%02x>", mantis->gpio_status); | ||
| 91 | mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR); | ||
| 92 | mmwrite(0x00, MANTIS_GPIF_DOUT); | ||
| 93 | } | ||
| 94 | EXPORT_SYMBOL_GPL(mantis_gpio_set_bits); | ||
| 95 | |||
| 96 | int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl) | ||
| 97 | { | ||
| 98 | u32 reg; | ||
| 99 | |||
| 100 | reg = mmread(MANTIS_CONTROL); | ||
| 101 | switch (stream_ctl) { | ||
| 102 | case STREAM_TO_HIF: | ||
| 103 | dprintk(MANTIS_DEBUG, 1, "Set stream to HIF"); | ||
| 104 | reg &= 0xff - MANTIS_BYPASS; | ||
| 105 | mmwrite(reg, MANTIS_CONTROL); | ||
| 106 | reg |= MANTIS_BYPASS; | ||
| 107 | mmwrite(reg, MANTIS_CONTROL); | ||
| 108 | break; | ||
| 109 | |||
| 110 | case STREAM_TO_CAM: | ||
| 111 | dprintk(MANTIS_DEBUG, 1, "Set stream to CAM"); | ||
| 112 | reg |= MANTIS_BYPASS; | ||
| 113 | mmwrite(reg, MANTIS_CONTROL); | ||
| 114 | reg &= 0xff - MANTIS_BYPASS; | ||
| 115 | mmwrite(reg, MANTIS_CONTROL); | ||
| 116 | break; | ||
| 117 | default: | ||
| 118 | dprintk(MANTIS_ERROR, 1, "Unknown MODE <%02x>", stream_ctl); | ||
| 119 | return -1; | ||
| 120 | } | ||
| 121 | |||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | EXPORT_SYMBOL_GPL(mantis_stream_control); | ||
diff --git a/drivers/media/dvb/mantis/mantis_ioc.h b/drivers/media/dvb/mantis/mantis_ioc.h new file mode 100644 index 00000000000..d56e002b295 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_ioc.h | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_IOC_H | ||
| 22 | #define __MANTIS_IOC_H | ||
| 23 | |||
| 24 | #define GPIF_A00 0x00 | ||
| 25 | #define GPIF_A01 0x01 | ||
| 26 | #define GPIF_A02 0x02 | ||
| 27 | #define GPIF_A03 0x03 | ||
| 28 | #define GPIF_A04 0x04 | ||
| 29 | #define GPIF_A05 0x05 | ||
| 30 | #define GPIF_A06 0x06 | ||
| 31 | #define GPIF_A07 0x07 | ||
| 32 | #define GPIF_A08 0x08 | ||
| 33 | #define GPIF_A09 0x09 | ||
| 34 | #define GPIF_A10 0x0a | ||
| 35 | #define GPIF_A11 0x0b | ||
| 36 | |||
| 37 | #define GPIF_A12 0x0c | ||
| 38 | #define GPIF_A13 0x0d | ||
| 39 | #define GPIF_A14 0x0e | ||
| 40 | |||
| 41 | enum mantis_stream_control { | ||
| 42 | STREAM_TO_HIF = 0, | ||
| 43 | STREAM_TO_CAM | ||
| 44 | }; | ||
| 45 | |||
| 46 | extern int mantis_get_mac(struct mantis_pci *mantis); | ||
| 47 | extern void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value); | ||
| 48 | |||
| 49 | extern int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl); | ||
| 50 | |||
| 51 | #endif /* __MANTIS_IOC_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_link.h b/drivers/media/dvb/mantis/mantis_link.h new file mode 100644 index 00000000000..2a814774a00 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_link.h | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_LINK_H | ||
| 22 | #define __MANTIS_LINK_H | ||
| 23 | |||
| 24 | #include <linux/mutex.h> | ||
| 25 | #include <linux/workqueue.h> | ||
| 26 | #include "dvb_ca_en50221.h" | ||
| 27 | |||
| 28 | enum mantis_sbuf_status { | ||
| 29 | MANTIS_SBUF_DATA_AVAIL = 1, | ||
| 30 | MANTIS_SBUF_DATA_EMPTY = 2, | ||
| 31 | MANTIS_SBUF_DATA_OVFLW = 3 | ||
| 32 | }; | ||
| 33 | |||
| 34 | struct mantis_slot { | ||
| 35 | u32 timeout; | ||
| 36 | u32 slave_cfg; | ||
| 37 | u32 bar; | ||
| 38 | }; | ||
| 39 | |||
| 40 | /* Physical layer */ | ||
| 41 | enum mantis_slot_state { | ||
| 42 | MODULE_INSERTED = 3, | ||
| 43 | MODULE_XTRACTED = 4 | ||
| 44 | }; | ||
| 45 | |||
| 46 | struct mantis_ca { | ||
| 47 | struct mantis_slot slot[4]; | ||
| 48 | |||
| 49 | struct work_struct hif_evm_work; | ||
| 50 | |||
| 51 | u32 hif_event; | ||
| 52 | wait_queue_head_t hif_opdone_wq; | ||
| 53 | wait_queue_head_t hif_brrdyw_wq; | ||
| 54 | wait_queue_head_t hif_data_wq; | ||
| 55 | wait_queue_head_t hif_write_wq; /* HIF Write op */ | ||
| 56 | |||
| 57 | enum mantis_sbuf_status sbuf_status; | ||
| 58 | |||
| 59 | enum mantis_slot_state slot_state; | ||
| 60 | |||
| 61 | void *ca_priv; | ||
| 62 | |||
| 63 | struct dvb_ca_en50221 en50221; | ||
| 64 | struct mutex ca_lock; | ||
| 65 | }; | ||
| 66 | |||
| 67 | /* CA */ | ||
| 68 | extern void mantis_event_cam_plugin(struct mantis_ca *ca); | ||
| 69 | extern void mantis_event_cam_unplug(struct mantis_ca *ca); | ||
| 70 | extern int mantis_pcmcia_init(struct mantis_ca *ca); | ||
| 71 | extern void mantis_pcmcia_exit(struct mantis_ca *ca); | ||
| 72 | extern int mantis_evmgr_init(struct mantis_ca *ca); | ||
| 73 | extern void mantis_evmgr_exit(struct mantis_ca *ca); | ||
| 74 | |||
| 75 | /* HIF */ | ||
| 76 | extern int mantis_hif_init(struct mantis_ca *ca); | ||
| 77 | extern void mantis_hif_exit(struct mantis_ca *ca); | ||
| 78 | extern int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr); | ||
| 79 | extern int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data); | ||
| 80 | extern int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr); | ||
| 81 | extern int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data); | ||
| 82 | |||
| 83 | #endif /* __MANTIS_LINK_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_pci.c b/drivers/media/dvb/mantis/mantis_pci.c new file mode 100644 index 00000000000..371558af2d9 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_pci.c | |||
| @@ -0,0 +1,170 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/moduleparam.h> | ||
| 23 | #include <linux/kernel.h> | ||
| 24 | #include <asm/io.h> | ||
| 25 | #include <asm/page.h> | ||
| 26 | #include <linux/kmod.h> | ||
| 27 | #include <linux/vmalloc.h> | ||
| 28 | #include <linux/init.h> | ||
| 29 | #include <linux/device.h> | ||
| 30 | #include <linux/pci.h> | ||
| 31 | |||
| 32 | #include <asm/irq.h> | ||
| 33 | #include <linux/signal.h> | ||
| 34 | #include <linux/sched.h> | ||
| 35 | #include <linux/interrupt.h> | ||
| 36 | |||
| 37 | #include "dmxdev.h" | ||
| 38 | #include "dvbdev.h" | ||
| 39 | #include "dvb_demux.h" | ||
| 40 | #include "dvb_frontend.h" | ||
| 41 | #include "dvb_net.h" | ||
| 42 | |||
| 43 | #include "mantis_common.h" | ||
| 44 | #include "mantis_reg.h" | ||
| 45 | #include "mantis_pci.h" | ||
| 46 | |||
| 47 | #define DRIVER_NAME "Mantis Core" | ||
| 48 | |||
| 49 | int __devinit mantis_pci_init(struct mantis_pci *mantis) | ||
| 50 | { | ||
| 51 | u8 latency; | ||
| 52 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
| 53 | struct pci_dev *pdev = mantis->pdev; | ||
| 54 | int err, ret = 0; | ||
| 55 | |||
| 56 | dprintk(MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n", | ||
| 57 | config->model_name, | ||
| 58 | config->dev_type, | ||
| 59 | mantis->pdev->bus->number, | ||
| 60 | PCI_SLOT(mantis->pdev->devfn), | ||
| 61 | PCI_FUNC(mantis->pdev->devfn)); | ||
| 62 | |||
| 63 | err = pci_enable_device(pdev); | ||
| 64 | if (err != 0) { | ||
| 65 | ret = -ENODEV; | ||
| 66 | dprintk(MANTIS_ERROR, 1, "ERROR: PCI enable failed <%i>", err); | ||
| 67 | goto fail0; | ||
| 68 | } | ||
| 69 | |||
| 70 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
| 71 | if (err != 0) { | ||
| 72 | dprintk(MANTIS_ERROR, 1, "ERROR: Unable to obtain 32 bit DMA <%i>", err); | ||
| 73 | ret = -ENOMEM; | ||
| 74 | goto fail1; | ||
| 75 | } | ||
| 76 | |||
| 77 | pci_set_master(pdev); | ||
| 78 | |||
| 79 | if (!request_mem_region(pci_resource_start(pdev, 0), | ||
| 80 | pci_resource_len(pdev, 0), | ||
| 81 | DRIVER_NAME)) { | ||
| 82 | |||
| 83 | dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 Request failed !"); | ||
| 84 | ret = -ENODEV; | ||
| 85 | goto fail1; | ||
| 86 | } | ||
| 87 | |||
| 88 | mantis->mmio = ioremap(pci_resource_start(pdev, 0), | ||
| 89 | pci_resource_len(pdev, 0)); | ||
| 90 | |||
| 91 | if (!mantis->mmio) { | ||
| 92 | dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 remap failed !"); | ||
| 93 | ret = -ENODEV; | ||
| 94 | goto fail2; | ||
| 95 | } | ||
| 96 | |||
| 97 | pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency); | ||
| 98 | mantis->latency = latency; | ||
| 99 | mantis->revision = pdev->revision; | ||
| 100 | |||
| 101 | dprintk(MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ", | ||
| 102 | mantis->revision, | ||
| 103 | mantis->pdev->subsystem_vendor, | ||
| 104 | mantis->pdev->subsystem_device); | ||
| 105 | |||
| 106 | dprintk(MANTIS_ERROR, 0, | ||
| 107 | "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n", | ||
| 108 | mantis->pdev->irq, | ||
| 109 | mantis->latency, | ||
| 110 | mantis->mantis_addr, | ||
| 111 | mantis->mmio); | ||
| 112 | |||
| 113 | err = request_irq(pdev->irq, | ||
| 114 | config->irq_handler, | ||
| 115 | IRQF_SHARED, | ||
| 116 | DRIVER_NAME, | ||
| 117 | mantis); | ||
| 118 | |||
| 119 | if (err != 0) { | ||
| 120 | |||
| 121 | dprintk(MANTIS_ERROR, 1, "ERROR: IRQ registration failed ! <%d>", err); | ||
| 122 | ret = -ENODEV; | ||
| 123 | goto fail3; | ||
| 124 | } | ||
| 125 | |||
| 126 | pci_set_drvdata(pdev, mantis); | ||
| 127 | return ret; | ||
| 128 | |||
| 129 | /* Error conditions */ | ||
| 130 | fail3: | ||
| 131 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> I/O unmap", ret); | ||
| 132 | if (mantis->mmio) | ||
| 133 | iounmap(mantis->mmio); | ||
| 134 | |||
| 135 | fail2: | ||
| 136 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> releasing regions", ret); | ||
| 137 | release_mem_region(pci_resource_start(pdev, 0), | ||
| 138 | pci_resource_len(pdev, 0)); | ||
| 139 | |||
| 140 | fail1: | ||
| 141 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> disabling device", ret); | ||
| 142 | pci_disable_device(pdev); | ||
| 143 | |||
| 144 | fail0: | ||
| 145 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret); | ||
| 146 | pci_set_drvdata(pdev, NULL); | ||
| 147 | return ret; | ||
| 148 | } | ||
| 149 | EXPORT_SYMBOL_GPL(mantis_pci_init); | ||
| 150 | |||
| 151 | void mantis_pci_exit(struct mantis_pci *mantis) | ||
| 152 | { | ||
| 153 | struct pci_dev *pdev = mantis->pdev; | ||
| 154 | |||
| 155 | dprintk(MANTIS_NOTICE, 1, " mem: 0x%p", mantis->mmio); | ||
| 156 | free_irq(pdev->irq, mantis); | ||
| 157 | if (mantis->mmio) { | ||
| 158 | iounmap(mantis->mmio); | ||
| 159 | release_mem_region(pci_resource_start(pdev, 0), | ||
| 160 | pci_resource_len(pdev, 0)); | ||
| 161 | } | ||
| 162 | |||
| 163 | pci_disable_device(pdev); | ||
| 164 | pci_set_drvdata(pdev, NULL); | ||
| 165 | } | ||
| 166 | EXPORT_SYMBOL_GPL(mantis_pci_exit); | ||
| 167 | |||
| 168 | MODULE_DESCRIPTION("Mantis PCI DTV bridge driver"); | ||
| 169 | MODULE_AUTHOR("Manu Abraham"); | ||
| 170 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/mantis/mantis_pci.h b/drivers/media/dvb/mantis/mantis_pci.h new file mode 100644 index 00000000000..65f00451908 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_pci.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_PCI_H | ||
| 22 | #define __MANTIS_PCI_H | ||
| 23 | |||
| 24 | extern int mantis_pci_init(struct mantis_pci *mantis); | ||
| 25 | extern void mantis_pci_exit(struct mantis_pci *mantis); | ||
| 26 | |||
| 27 | #endif /* __MANTIS_PCI_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_pcmcia.c b/drivers/media/dvb/mantis/mantis_pcmcia.c new file mode 100644 index 00000000000..2f188c08966 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_pcmcia.c | |||
| @@ -0,0 +1,121 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/kernel.h> | ||
| 22 | |||
| 23 | #include <linux/signal.h> | ||
| 24 | #include <linux/sched.h> | ||
| 25 | #include <linux/interrupt.h> | ||
| 26 | #include <asm/io.h> | ||
| 27 | |||
| 28 | #include "dmxdev.h" | ||
| 29 | #include "dvbdev.h" | ||
| 30 | #include "dvb_demux.h" | ||
| 31 | #include "dvb_frontend.h" | ||
| 32 | #include "dvb_net.h" | ||
| 33 | |||
| 34 | #include "mantis_common.h" | ||
| 35 | #include "mantis_link.h" /* temporary due to physical layer stuff */ | ||
| 36 | #include "mantis_reg.h" | ||
| 37 | |||
| 38 | /* | ||
| 39 | * If Slot state is already PLUG_IN event and we are called | ||
| 40 | * again, definitely it is jitter alone | ||
| 41 | */ | ||
| 42 | void mantis_event_cam_plugin(struct mantis_ca *ca) | ||
| 43 | { | ||
| 44 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 45 | |||
| 46 | u32 gpif_irqcfg; | ||
| 47 | |||
| 48 | if (ca->slot_state == MODULE_XTRACTED) { | ||
| 49 | dprintk(MANTIS_DEBUG, 1, "Event: CAM Plugged IN: Adapter(%d) Slot(0)", mantis->num); | ||
| 50 | udelay(50); | ||
| 51 | mmwrite(0xda000000, MANTIS_CARD_RESET); | ||
| 52 | gpif_irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
| 53 | gpif_irqcfg |= MANTIS_MASK_PLUGOUT; | ||
| 54 | gpif_irqcfg &= ~MANTIS_MASK_PLUGIN; | ||
| 55 | mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG); | ||
| 56 | udelay(500); | ||
| 57 | ca->slot_state = MODULE_INSERTED; | ||
| 58 | } | ||
| 59 | udelay(100); | ||
| 60 | } | ||
| 61 | |||
| 62 | /* | ||
| 63 | * If Slot state is already UN_PLUG event and we are called | ||
| 64 | * again, definitely it is jitter alone | ||
| 65 | */ | ||
| 66 | void mantis_event_cam_unplug(struct mantis_ca *ca) | ||
| 67 | { | ||
| 68 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 69 | |||
| 70 | u32 gpif_irqcfg; | ||
| 71 | |||
| 72 | if (ca->slot_state == MODULE_INSERTED) { | ||
| 73 | dprintk(MANTIS_DEBUG, 1, "Event: CAM Unplugged: Adapter(%d) Slot(0)", mantis->num); | ||
| 74 | udelay(50); | ||
| 75 | mmwrite(0x00da0000, MANTIS_CARD_RESET); | ||
| 76 | gpif_irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
| 77 | gpif_irqcfg |= MANTIS_MASK_PLUGIN; | ||
| 78 | gpif_irqcfg &= ~MANTIS_MASK_PLUGOUT; | ||
| 79 | mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG); | ||
| 80 | udelay(500); | ||
| 81 | ca->slot_state = MODULE_XTRACTED; | ||
| 82 | } | ||
| 83 | udelay(100); | ||
| 84 | } | ||
| 85 | |||
| 86 | int mantis_pcmcia_init(struct mantis_ca *ca) | ||
| 87 | { | ||
| 88 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 89 | |||
| 90 | u32 gpif_stat, card_stat; | ||
| 91 | |||
| 92 | mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_IRQ0, MANTIS_INT_MASK); | ||
| 93 | gpif_stat = mmread(MANTIS_GPIF_STATUS); | ||
| 94 | card_stat = mmread(MANTIS_GPIF_IRQCFG); | ||
| 95 | |||
| 96 | if (gpif_stat & MANTIS_GPIF_DETSTAT) { | ||
| 97 | dprintk(MANTIS_DEBUG, 1, "CAM found on Adapter(%d) Slot(0)", mantis->num); | ||
| 98 | mmwrite(card_stat | MANTIS_MASK_PLUGOUT, MANTIS_GPIF_IRQCFG); | ||
| 99 | ca->slot_state = MODULE_INSERTED; | ||
| 100 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
| 101 | 0, | ||
| 102 | DVB_CA_EN50221_CAMCHANGE_INSERTED); | ||
| 103 | } else { | ||
| 104 | dprintk(MANTIS_DEBUG, 1, "Empty Slot on Adapter(%d) Slot(0)", mantis->num); | ||
| 105 | mmwrite(card_stat | MANTIS_MASK_PLUGIN, MANTIS_GPIF_IRQCFG); | ||
| 106 | ca->slot_state = MODULE_XTRACTED; | ||
| 107 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
| 108 | 0, | ||
| 109 | DVB_CA_EN50221_CAMCHANGE_REMOVED); | ||
| 110 | } | ||
| 111 | |||
| 112 | return 0; | ||
| 113 | } | ||
| 114 | |||
| 115 | void mantis_pcmcia_exit(struct mantis_ca *ca) | ||
| 116 | { | ||
| 117 | struct mantis_pci *mantis = ca->ca_priv; | ||
| 118 | |||
| 119 | mmwrite(mmread(MANTIS_GPIF_STATUS) & (~MANTIS_CARD_PLUGOUT | ~MANTIS_CARD_PLUGIN), MANTIS_GPIF_STATUS); | ||
| 120 | mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ0, MANTIS_INT_MASK); | ||
| 121 | } | ||
diff --git a/drivers/media/dvb/mantis/mantis_reg.h b/drivers/media/dvb/mantis/mantis_reg.h new file mode 100644 index 00000000000..7761f9dc7fe --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_reg.h | |||
| @@ -0,0 +1,197 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_REG_H | ||
| 22 | #define __MANTIS_REG_H | ||
| 23 | |||
| 24 | /* Interrupts */ | ||
| 25 | #define MANTIS_INT_STAT 0x00 | ||
| 26 | #define MANTIS_INT_MASK 0x04 | ||
| 27 | |||
| 28 | #define MANTIS_INT_RISCSTAT (0x0f << 28) | ||
| 29 | #define MANTIS_INT_RISCEN (0x01 << 27) | ||
| 30 | #define MANTIS_INT_I2CRACK (0x01 << 26) | ||
| 31 | |||
| 32 | /* #define MANTIS_INT_GPIF (0xff << 12) */ | ||
| 33 | |||
| 34 | #define MANTIS_INT_PCMCIA7 (0x01 << 19) | ||
| 35 | #define MANTIS_INT_PCMCIA6 (0x01 << 18) | ||
| 36 | #define MANTIS_INT_PCMCIA5 (0x01 << 17) | ||
| 37 | #define MANTIS_INT_PCMCIA4 (0x01 << 16) | ||
| 38 | #define MANTIS_INT_PCMCIA3 (0x01 << 15) | ||
| 39 | #define MANTIS_INT_PCMCIA2 (0x01 << 14) | ||
| 40 | #define MANTIS_INT_PCMCIA1 (0x01 << 13) | ||
| 41 | #define MANTIS_INT_PCMCIA0 (0x01 << 12) | ||
| 42 | #define MANTIS_INT_IRQ1 (0x01 << 11) | ||
| 43 | #define MANTIS_INT_IRQ0 (0x01 << 10) | ||
| 44 | #define MANTIS_INT_OCERR (0x01 << 8) | ||
| 45 | #define MANTIS_INT_PABORT (0x01 << 7) | ||
| 46 | #define MANTIS_INT_RIPERR (0x01 << 6) | ||
| 47 | #define MANTIS_INT_PPERR (0x01 << 5) | ||
| 48 | #define MANTIS_INT_FTRGT (0x01 << 3) | ||
| 49 | #define MANTIS_INT_RISCI (0x01 << 1) | ||
| 50 | #define MANTIS_INT_I2CDONE (0x01 << 0) | ||
| 51 | |||
| 52 | /* DMA */ | ||
| 53 | #define MANTIS_DMA_CTL 0x08 | ||
| 54 | #define MANTIS_GPIF_RD (0xff << 24) | ||
| 55 | #define MANTIS_GPIF_WR (0xff << 16) | ||
| 56 | #define MANTIS_CPU_DO (0x01 << 10) | ||
| 57 | #define MANTIS_DRV_DO (0x01 << 9) | ||
| 58 | #define MANTIS_I2C_RD (0x01 << 7) | ||
| 59 | #define MANTIS_I2C_WR (0x01 << 6) | ||
| 60 | #define MANTIS_DCAP_MODE (0x01 << 5) | ||
| 61 | #define MANTIS_FIFO_TP_4 (0x00 << 3) | ||
| 62 | #define MANTIS_FIFO_TP_8 (0x01 << 3) | ||
| 63 | #define MANTIS_FIFO_TP_16 (0x02 << 3) | ||
| 64 | #define MANTIS_FIFO_EN (0x01 << 2) | ||
| 65 | #define MANTIS_DCAP_EN (0x01 << 1) | ||
| 66 | #define MANTIS_RISC_EN (0x01 << 0) | ||
| 67 | |||
| 68 | /* DEBUG */ | ||
| 69 | #define MANTIS_DEBUGREG 0x0c | ||
| 70 | #define MANTIS_DATINV (0x0e << 7) | ||
| 71 | #define MANTIS_TOP_DEBUGSEL (0x07 << 4) | ||
| 72 | #define MANTIS_PCMCIA_DEBUGSEL (0x0f << 0) | ||
| 73 | |||
| 74 | #define MANTIS_RISC_START 0x10 | ||
| 75 | #define MANTIS_RISC_PC 0x14 | ||
| 76 | |||
| 77 | /* I2C */ | ||
| 78 | #define MANTIS_I2CDATA_CTL 0x18 | ||
| 79 | #define MANTIS_I2C_RATE_1 (0x00 << 6) | ||
| 80 | #define MANTIS_I2C_RATE_2 (0x01 << 6) | ||
| 81 | #define MANTIS_I2C_RATE_3 (0x02 << 6) | ||
| 82 | #define MANTIS_I2C_RATE_4 (0x03 << 6) | ||
| 83 | #define MANTIS_I2C_STOP (0x01 << 5) | ||
| 84 | #define MANTIS_I2C_PGMODE (0x01 << 3) | ||
| 85 | |||
| 86 | /* DATA */ | ||
| 87 | #define MANTIS_CMD_DATA_R1 0x20 | ||
| 88 | #define MANTIS_CMD_DATA_3 (0xff << 24) | ||
| 89 | #define MANTIS_CMD_DATA_2 (0xff << 16) | ||
| 90 | #define MANTIS_CMD_DATA_1 (0xff << 8) | ||
| 91 | #define MANTIS_CMD_DATA_0 (0xff << 0) | ||
| 92 | |||
| 93 | #define MANTIS_CMD_DATA_R2 0x24 | ||
| 94 | #define MANTIS_CMD_DATA_7 (0xff << 24) | ||
| 95 | #define MANTIS_CMD_DATA_6 (0xff << 16) | ||
| 96 | #define MANTIS_CMD_DATA_5 (0xff << 8) | ||
| 97 | #define MANTIS_CMD_DATA_4 (0xff << 0) | ||
| 98 | |||
| 99 | #define MANTIS_CONTROL 0x28 | ||
| 100 | #define MANTIS_DET (0x01 << 7) | ||
| 101 | #define MANTIS_DAT_CF_EN (0x01 << 6) | ||
| 102 | #define MANTIS_ACS (0x03 << 4) | ||
| 103 | #define MANTIS_VCCEN (0x01 << 3) | ||
| 104 | #define MANTIS_BYPASS (0x01 << 2) | ||
| 105 | #define MANTIS_MRST (0x01 << 1) | ||
| 106 | #define MANTIS_CRST_INT (0x01 << 0) | ||
| 107 | |||
| 108 | #define MANTIS_GPIF_CFGSLA 0x84 | ||
| 109 | #define MANTIS_GPIF_WAITSMPL (0x07 << 28) | ||
| 110 | #define MANTIS_GPIF_BYTEADDRSUB (0x01 << 25) | ||
| 111 | #define MANTIS_GPIF_WAITPOL (0x01 << 24) | ||
| 112 | #define MANTIS_GPIF_NCDELAY (0x07 << 20) | ||
| 113 | #define MANTIS_GPIF_RW2CSDELAY (0x07 << 16) | ||
| 114 | #define MANTIS_GPIF_SLFTIMEDMODE (0x01 << 15) | ||
| 115 | #define MANTIS_GPIF_SLFTIMEDDELY (0x7f << 8) | ||
| 116 | #define MANTIS_GPIF_DEVTYPE (0x07 << 4) | ||
| 117 | #define MANTIS_GPIF_BIGENDIAN (0x01 << 3) | ||
| 118 | #define MANTIS_GPIF_FETCHCMD (0x03 << 1) | ||
| 119 | #define MANTIS_GPIF_HWORDDEV (0x01 << 0) | ||
| 120 | |||
| 121 | #define MANTIS_GPIF_WSTOPER 0x90 | ||
| 122 | #define MANTIS_GPIF_WSTOPERWREN3 (0x01 << 31) | ||
| 123 | #define MANTIS_GPIF_PARBOOTN (0x01 << 29) | ||
| 124 | #define MANTIS_GPIF_WSTOPERSLID3 (0x1f << 24) | ||
| 125 | #define MANTIS_GPIF_WSTOPERWREN2 (0x01 << 23) | ||
| 126 | #define MANTIS_GPIF_WSTOPERSLID2 (0x1f << 16) | ||
| 127 | #define MANTIS_GPIF_WSTOPERWREN1 (0x01 << 15) | ||
| 128 | #define MANTIS_GPIF_WSTOPERSLID1 (0x1f << 8) | ||
| 129 | #define MANTIS_GPIF_WSTOPERWREN0 (0x01 << 7) | ||
| 130 | #define MANTIS_GPIF_WSTOPERSLID0 (0x1f << 0) | ||
| 131 | |||
| 132 | #define MANTIS_GPIF_CS2RW 0x94 | ||
| 133 | #define MANTIS_GPIF_CS2RWWREN3 (0x01 << 31) | ||
| 134 | #define MANTIS_GPIF_CS2RWDELY3 (0x3f << 24) | ||
| 135 | #define MANTIS_GPIF_CS2RWWREN2 (0x01 << 23) | ||
| 136 | #define MANTIS_GPIF_CS2RWDELY2 (0x3f << 16) | ||
| 137 | #define MANTIS_GPIF_CS2RWWREN1 (0x01 << 15) | ||
| 138 | #define MANTIS_GPIF_CS2RWDELY1 (0x3f << 8) | ||
| 139 | #define MANTIS_GPIF_CS2RWWREN0 (0x01 << 7) | ||
| 140 | #define MANTIS_GPIF_CS2RWDELY0 (0x3f << 0) | ||
| 141 | |||
| 142 | #define MANTIS_GPIF_IRQCFG 0x98 | ||
| 143 | #define MANTIS_GPIF_IRQPOL (0x01 << 8) | ||
| 144 | #define MANTIS_MASK_WRACK (0x01 << 7) | ||
| 145 | #define MANTIS_MASK_BRRDY (0x01 << 6) | ||
| 146 | #define MANTIS_MASK_OVFLW (0x01 << 5) | ||
| 147 | #define MANTIS_MASK_OTHERR (0x01 << 4) | ||
| 148 | #define MANTIS_MASK_WSTO (0x01 << 3) | ||
| 149 | #define MANTIS_MASK_EXTIRQ (0x01 << 2) | ||
| 150 | #define MANTIS_MASK_PLUGIN (0x01 << 1) | ||
| 151 | #define MANTIS_MASK_PLUGOUT (0x01 << 0) | ||
| 152 | |||
| 153 | #define MANTIS_GPIF_STATUS 0x9c | ||
| 154 | #define MANTIS_SBUF_KILLOP (0x01 << 15) | ||
| 155 | #define MANTIS_SBUF_OPDONE (0x01 << 14) | ||
| 156 | #define MANTIS_SBUF_EMPTY (0x01 << 13) | ||
| 157 | #define MANTIS_GPIF_DETSTAT (0x01 << 9) | ||
| 158 | #define MANTIS_GPIF_INTSTAT (0x01 << 8) | ||
| 159 | #define MANTIS_GPIF_WRACK (0x01 << 7) | ||
| 160 | #define MANTIS_GPIF_BRRDY (0x01 << 6) | ||
| 161 | #define MANTIS_SBUF_OVFLW (0x01 << 5) | ||
| 162 | #define MANTIS_GPIF_OTHERR (0x01 << 4) | ||
| 163 | #define MANTIS_SBUF_WSTO (0x01 << 3) | ||
| 164 | #define MANTIS_GPIF_EXTIRQ (0x01 << 2) | ||
| 165 | #define MANTIS_CARD_PLUGIN (0x01 << 1) | ||
| 166 | #define MANTIS_CARD_PLUGOUT (0x01 << 0) | ||
| 167 | |||
| 168 | #define MANTIS_GPIF_BRADDR 0xa0 | ||
| 169 | #define MANTIS_GPIF_PCMCIAREG (0x01 << 27) | ||
| 170 | #define MANTIS_GPIF_PCMCIAIOM (0x01 << 26) | ||
| 171 | #define MANTIS_GPIF_BR_ADDR (0xfffffff << 0) | ||
| 172 | |||
| 173 | #define MANTIS_GPIF_BRBYTES 0xa4 | ||
| 174 | #define MANTIS_GPIF_BRCNT (0xfff << 0) | ||
| 175 | |||
| 176 | #define MANTIS_PCMCIA_RESET 0xa8 | ||
| 177 | #define MANTIS_PCMCIA_RSTVAL (0xff << 0) | ||
| 178 | |||
| 179 | #define MANTIS_CARD_RESET 0xac | ||
| 180 | |||
| 181 | #define MANTIS_GPIF_ADDR 0xb0 | ||
| 182 | #define MANTIS_GPIF_HIFRDWRN (0x01 << 31) | ||
| 183 | #define MANTIS_GPIF_PCMCIAREG (0x01 << 27) | ||
| 184 | #define MANTIS_GPIF_PCMCIAIOM (0x01 << 26) | ||
| 185 | #define MANTIS_GPIF_HIFADDR (0xfffffff << 0) | ||
| 186 | |||
| 187 | #define MANTIS_GPIF_DOUT 0xb4 | ||
| 188 | #define MANTIS_GPIF_HIFDOUT (0xfffffff << 0) | ||
| 189 | |||
| 190 | #define MANTIS_GPIF_DIN 0xb8 | ||
| 191 | #define MANTIS_GPIF_HIFDIN (0xfffffff << 0) | ||
| 192 | |||
| 193 | #define MANTIS_GPIF_SPARE 0xbc | ||
| 194 | #define MANTIS_GPIF_LOGICRD (0xffff << 16) | ||
| 195 | #define MANTIS_GPIF_LOGICRW (0xffff << 0) | ||
| 196 | |||
| 197 | #endif /* __MANTIS_REG_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_uart.c b/drivers/media/dvb/mantis/mantis_uart.c new file mode 100644 index 00000000000..18340dafa42 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_uart.c | |||
| @@ -0,0 +1,188 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/kernel.h> | ||
| 22 | #include <linux/spinlock.h> | ||
| 23 | #include <asm/io.h> | ||
| 24 | |||
| 25 | #include <linux/signal.h> | ||
| 26 | #include <linux/sched.h> | ||
| 27 | #include <linux/interrupt.h> | ||
| 28 | |||
| 29 | #include "dmxdev.h" | ||
| 30 | #include "dvbdev.h" | ||
| 31 | #include "dvb_demux.h" | ||
| 32 | #include "dvb_frontend.h" | ||
| 33 | #include "dvb_net.h" | ||
| 34 | |||
| 35 | #include "mantis_common.h" | ||
| 36 | #include "mantis_reg.h" | ||
| 37 | #include "mantis_uart.h" | ||
| 38 | |||
| 39 | struct mantis_uart_params { | ||
| 40 | enum mantis_baud baud_rate; | ||
| 41 | enum mantis_parity parity; | ||
| 42 | }; | ||
| 43 | |||
| 44 | static struct { | ||
| 45 | char string[7]; | ||
| 46 | } rates[5] = { | ||
| 47 | { "9600" }, | ||
| 48 | { "19200" }, | ||
| 49 | { "38400" }, | ||
| 50 | { "57600" }, | ||
| 51 | { "115200" } | ||
| 52 | }; | ||
| 53 | |||
| 54 | static struct { | ||
| 55 | char string[5]; | ||
| 56 | } parity[3] = { | ||
| 57 | { "NONE" }, | ||
| 58 | { "ODD" }, | ||
| 59 | { "EVEN" } | ||
| 60 | }; | ||
| 61 | |||
| 62 | #define UART_MAX_BUF 16 | ||
| 63 | |||
| 64 | int mantis_uart_read(struct mantis_pci *mantis, u8 *data) | ||
| 65 | { | ||
| 66 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
| 67 | u32 stat = 0, i; | ||
| 68 | |||
| 69 | /* get data */ | ||
| 70 | for (i = 0; i < (config->bytes + 1); i++) { | ||
| 71 | |||
| 72 | stat = mmread(MANTIS_UART_STAT); | ||
| 73 | |||
| 74 | if (stat & MANTIS_UART_RXFIFO_FULL) { | ||
| 75 | dprintk(MANTIS_ERROR, 1, "RX Fifo FULL"); | ||
| 76 | } | ||
| 77 | data[i] = mmread(MANTIS_UART_RXD) & 0x3f; | ||
| 78 | |||
| 79 | dprintk(MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f); | ||
| 80 | |||
| 81 | if (data[i] & (1 << 7)) { | ||
| 82 | dprintk(MANTIS_ERROR, 1, "UART framing error"); | ||
| 83 | return -EINVAL; | ||
| 84 | } | ||
| 85 | if (data[i] & (1 << 6)) { | ||
| 86 | dprintk(MANTIS_ERROR, 1, "UART parity error"); | ||
| 87 | return -EINVAL; | ||
| 88 | } | ||
| 89 | } | ||
| 90 | |||
| 91 | return 0; | ||
| 92 | } | ||
| 93 | |||
| 94 | static void mantis_uart_work(struct work_struct *work) | ||
| 95 | { | ||
| 96 | struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work); | ||
| 97 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
| 98 | u8 buf[16]; | ||
| 99 | int i; | ||
| 100 | |||
| 101 | mantis_uart_read(mantis, buf); | ||
| 102 | |||
| 103 | for (i = 0; i < (config->bytes + 1); i++) | ||
| 104 | dprintk(MANTIS_INFO, 1, "UART BUF:%d <%02x> ", i, buf[i]); | ||
| 105 | |||
| 106 | dprintk(MANTIS_DEBUG, 0, "\n"); | ||
| 107 | } | ||
| 108 | |||
| 109 | static int mantis_uart_setup(struct mantis_pci *mantis, | ||
| 110 | struct mantis_uart_params *params) | ||
| 111 | { | ||
| 112 | u32 reg; | ||
| 113 | |||
| 114 | mmwrite((mmread(MANTIS_UART_CTL) | (params->parity & 0x3)), MANTIS_UART_CTL); | ||
| 115 | |||
| 116 | reg = mmread(MANTIS_UART_BAUD); | ||
| 117 | |||
| 118 | switch (params->baud_rate) { | ||
| 119 | case MANTIS_BAUD_9600: | ||
| 120 | reg |= 0xd8; | ||
| 121 | break; | ||
| 122 | case MANTIS_BAUD_19200: | ||
| 123 | reg |= 0x6c; | ||
| 124 | break; | ||
| 125 | case MANTIS_BAUD_38400: | ||
| 126 | reg |= 0x36; | ||
| 127 | break; | ||
| 128 | case MANTIS_BAUD_57600: | ||
| 129 | reg |= 0x23; | ||
| 130 | break; | ||
| 131 | case MANTIS_BAUD_115200: | ||
| 132 | reg |= 0x11; | ||
| 133 | break; | ||
| 134 | default: | ||
| 135 | return -EINVAL; | ||
| 136 | } | ||
| 137 | |||
| 138 | mmwrite(reg, MANTIS_UART_BAUD); | ||
| 139 | |||
| 140 | return 0; | ||
| 141 | } | ||
| 142 | |||
| 143 | int mantis_uart_init(struct mantis_pci *mantis) | ||
| 144 | { | ||
| 145 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
| 146 | struct mantis_uart_params params; | ||
| 147 | |||
| 148 | /* default parity: */ | ||
| 149 | params.baud_rate = config->baud_rate; | ||
| 150 | params.parity = config->parity; | ||
| 151 | dprintk(MANTIS_INFO, 1, "Initializing UART @ %sbps parity:%s", | ||
| 152 | rates[params.baud_rate].string, | ||
| 153 | parity[params.parity].string); | ||
| 154 | |||
| 155 | init_waitqueue_head(&mantis->uart_wq); | ||
| 156 | spin_lock_init(&mantis->uart_lock); | ||
| 157 | |||
| 158 | INIT_WORK(&mantis->uart_work, mantis_uart_work); | ||
| 159 | |||
| 160 | /* disable interrupt */ | ||
| 161 | mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL); | ||
| 162 | |||
| 163 | mantis_uart_setup(mantis, ¶ms); | ||
| 164 | |||
| 165 | /* default 1 byte */ | ||
| 166 | mmwrite((mmread(MANTIS_UART_BAUD) | (config->bytes << 8)), MANTIS_UART_BAUD); | ||
| 167 | |||
| 168 | /* flush buffer */ | ||
| 169 | mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL); | ||
| 170 | |||
| 171 | /* enable interrupt */ | ||
| 172 | mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK); | ||
| 173 | mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL); | ||
| 174 | |||
| 175 | schedule_work(&mantis->uart_work); | ||
| 176 | dprintk(MANTIS_DEBUG, 1, "UART successfully initialized"); | ||
| 177 | |||
| 178 | return 0; | ||
| 179 | } | ||
| 180 | EXPORT_SYMBOL_GPL(mantis_uart_init); | ||
| 181 | |||
| 182 | void mantis_uart_exit(struct mantis_pci *mantis) | ||
| 183 | { | ||
| 184 | /* disable interrupt */ | ||
| 185 | mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL); | ||
| 186 | flush_work_sync(&mantis->uart_work); | ||
| 187 | } | ||
| 188 | EXPORT_SYMBOL_GPL(mantis_uart_exit); | ||
diff --git a/drivers/media/dvb/mantis/mantis_uart.h b/drivers/media/dvb/mantis/mantis_uart.h new file mode 100644 index 00000000000..ffb62a0a5a1 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_uart.h | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | /* | ||
| 2 | Mantis PCI bridge driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_UART_H | ||
| 22 | #define __MANTIS_UART_H | ||
| 23 | |||
| 24 | #define MANTIS_UART_CTL 0xe0 | ||
| 25 | #define MANTIS_UART_RXINT (1 << 4) | ||
| 26 | #define MANTIS_UART_RXFLUSH (1 << 2) | ||
| 27 | |||
| 28 | #define MANTIS_UART_RXD 0xe8 | ||
| 29 | #define MANTIS_UART_BAUD 0xec | ||
| 30 | |||
| 31 | #define MANTIS_UART_STAT 0xf0 | ||
| 32 | #define MANTIS_UART_RXFIFO_DATA (1 << 7) | ||
| 33 | #define MANTIS_UART_RXFIFO_EMPTY (1 << 6) | ||
| 34 | #define MANTIS_UART_RXFIFO_FULL (1 << 3) | ||
| 35 | #define MANTIS_UART_FRAME_ERR (1 << 2) | ||
| 36 | #define MANTIS_UART_PARITY_ERR (1 << 1) | ||
| 37 | #define MANTIS_UART_RXTHRESH_INT (1 << 0) | ||
| 38 | |||
| 39 | enum mantis_baud { | ||
| 40 | MANTIS_BAUD_9600 = 0, | ||
| 41 | MANTIS_BAUD_19200, | ||
| 42 | MANTIS_BAUD_38400, | ||
| 43 | MANTIS_BAUD_57600, | ||
| 44 | MANTIS_BAUD_115200 | ||
| 45 | }; | ||
| 46 | |||
| 47 | enum mantis_parity { | ||
| 48 | MANTIS_PARITY_NONE = 0, | ||
| 49 | MANTIS_PARITY_EVEN, | ||
| 50 | MANTIS_PARITY_ODD, | ||
| 51 | }; | ||
| 52 | |||
| 53 | struct mantis_pci; | ||
| 54 | |||
| 55 | extern int mantis_uart_init(struct mantis_pci *mantis); | ||
| 56 | extern void mantis_uart_exit(struct mantis_pci *mantis); | ||
| 57 | |||
| 58 | #endif /* __MANTIS_UART_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1033.c b/drivers/media/dvb/mantis/mantis_vp1033.c new file mode 100644 index 00000000000..2ae0afa7756 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp1033.c | |||
| @@ -0,0 +1,212 @@ | |||
| 1 | /* | ||
| 2 | Mantis VP-1033 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/signal.h> | ||
| 22 | #include <linux/sched.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | |||
| 25 | #include "dmxdev.h" | ||
| 26 | #include "dvbdev.h" | ||
| 27 | #include "dvb_demux.h" | ||
| 28 | #include "dvb_frontend.h" | ||
| 29 | #include "dvb_net.h" | ||
| 30 | |||
| 31 | #include "stv0299.h" | ||
| 32 | #include "mantis_common.h" | ||
| 33 | #include "mantis_ioc.h" | ||
| 34 | #include "mantis_dvb.h" | ||
| 35 | #include "mantis_vp1033.h" | ||
| 36 | #include "mantis_reg.h" | ||
| 37 | |||
| 38 | u8 lgtdqcs001f_inittab[] = { | ||
| 39 | 0x01, 0x15, | ||
| 40 | 0x02, 0x30, | ||
| 41 | 0x03, 0x00, | ||
| 42 | 0x04, 0x2a, | ||
| 43 | 0x05, 0x85, | ||
| 44 | 0x06, 0x02, | ||
| 45 | 0x07, 0x00, | ||
| 46 | 0x08, 0x00, | ||
| 47 | 0x0c, 0x01, | ||
| 48 | 0x0d, 0x81, | ||
| 49 | 0x0e, 0x44, | ||
| 50 | 0x0f, 0x94, | ||
| 51 | 0x10, 0x3c, | ||
| 52 | 0x11, 0x84, | ||
| 53 | 0x12, 0xb9, | ||
| 54 | 0x13, 0xb5, | ||
| 55 | 0x14, 0x4f, | ||
| 56 | 0x15, 0xc9, | ||
| 57 | 0x16, 0x80, | ||
| 58 | 0x17, 0x36, | ||
| 59 | 0x18, 0xfb, | ||
| 60 | 0x19, 0xcf, | ||
| 61 | 0x1a, 0xbc, | ||
| 62 | 0x1c, 0x2b, | ||
| 63 | 0x1d, 0x27, | ||
| 64 | 0x1e, 0x00, | ||
| 65 | 0x1f, 0x0b, | ||
| 66 | 0x20, 0xa1, | ||
| 67 | 0x21, 0x60, | ||
| 68 | 0x22, 0x00, | ||
| 69 | 0x23, 0x00, | ||
| 70 | 0x28, 0x00, | ||
| 71 | 0x29, 0x28, | ||
| 72 | 0x2a, 0x14, | ||
| 73 | 0x2b, 0x0f, | ||
| 74 | 0x2c, 0x09, | ||
| 75 | 0x2d, 0x05, | ||
| 76 | 0x31, 0x1f, | ||
| 77 | 0x32, 0x19, | ||
| 78 | 0x33, 0xfc, | ||
| 79 | 0x34, 0x13, | ||
| 80 | 0xff, 0xff, | ||
| 81 | }; | ||
| 82 | |||
| 83 | #define MANTIS_MODEL_NAME "VP-1033" | ||
| 84 | #define MANTIS_DEV_TYPE "DVB-S/DSS" | ||
| 85 | |||
| 86 | int lgtdqcs001f_tuner_set(struct dvb_frontend *fe, | ||
| 87 | struct dvb_frontend_parameters *params) | ||
| 88 | { | ||
| 89 | struct mantis_pci *mantis = fe->dvb->priv; | ||
| 90 | struct i2c_adapter *adapter = &mantis->adapter; | ||
| 91 | |||
| 92 | u8 buf[4]; | ||
| 93 | u32 div; | ||
| 94 | |||
| 95 | |||
| 96 | struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf)}; | ||
| 97 | |||
| 98 | div = params->frequency / 250; | ||
| 99 | |||
| 100 | buf[0] = (div >> 8) & 0x7f; | ||
| 101 | buf[1] = div & 0xff; | ||
| 102 | buf[2] = 0x83; | ||
| 103 | buf[3] = 0xc0; | ||
| 104 | |||
| 105 | if (params->frequency < 1531000) | ||
| 106 | buf[3] |= 0x04; | ||
| 107 | else | ||
| 108 | buf[3] &= ~0x04; | ||
| 109 | if (i2c_transfer(adapter, &msg, 1) < 0) { | ||
| 110 | dprintk(MANTIS_ERROR, 1, "Write: I2C Transfer failed"); | ||
| 111 | return -EIO; | ||
| 112 | } | ||
| 113 | msleep_interruptible(100); | ||
| 114 | |||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | |||
| 118 | int lgtdqcs001f_set_symbol_rate(struct dvb_frontend *fe, | ||
| 119 | u32 srate, u32 ratio) | ||
| 120 | { | ||
| 121 | u8 aclk = 0; | ||
| 122 | u8 bclk = 0; | ||
| 123 | |||
| 124 | if (srate < 1500000) { | ||
| 125 | aclk = 0xb7; | ||
| 126 | bclk = 0x47; | ||
| 127 | } else if (srate < 3000000) { | ||
| 128 | aclk = 0xb7; | ||
| 129 | bclk = 0x4b; | ||
| 130 | } else if (srate < 7000000) { | ||
| 131 | aclk = 0xb7; | ||
| 132 | bclk = 0x4f; | ||
| 133 | } else if (srate < 14000000) { | ||
| 134 | aclk = 0xb7; | ||
| 135 | bclk = 0x53; | ||
| 136 | } else if (srate < 30000000) { | ||
| 137 | aclk = 0xb6; | ||
| 138 | bclk = 0x53; | ||
| 139 | } else if (srate < 45000000) { | ||
| 140 | aclk = 0xb4; | ||
| 141 | bclk = 0x51; | ||
| 142 | } | ||
| 143 | stv0299_writereg(fe, 0x13, aclk); | ||
| 144 | stv0299_writereg(fe, 0x14, bclk); | ||
| 145 | |||
| 146 | stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); | ||
| 147 | stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); | ||
| 148 | stv0299_writereg(fe, 0x21, ratio & 0xf0); | ||
| 149 | |||
| 150 | return 0; | ||
| 151 | } | ||
| 152 | |||
| 153 | struct stv0299_config lgtdqcs001f_config = { | ||
| 154 | .demod_address = 0x68, | ||
| 155 | .inittab = lgtdqcs001f_inittab, | ||
| 156 | .mclk = 88000000UL, | ||
| 157 | .invert = 0, | ||
| 158 | .skip_reinit = 0, | ||
| 159 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | ||
| 160 | .min_delay_ms = 100, | ||
| 161 | .set_symbol_rate = lgtdqcs001f_set_symbol_rate, | ||
| 162 | }; | ||
| 163 | |||
| 164 | static int vp1033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
| 165 | { | ||
| 166 | struct i2c_adapter *adapter = &mantis->adapter; | ||
| 167 | |||
| 168 | int err = 0; | ||
| 169 | |||
| 170 | err = mantis_frontend_power(mantis, POWER_ON); | ||
| 171 | if (err == 0) { | ||
| 172 | mantis_frontend_soft_reset(mantis); | ||
| 173 | msleep(250); | ||
| 174 | |||
| 175 | dprintk(MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)"); | ||
| 176 | fe = dvb_attach(stv0299_attach, &lgtdqcs001f_config, adapter); | ||
| 177 | |||
| 178 | if (fe) { | ||
| 179 | fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set; | ||
| 180 | dprintk(MANTIS_ERROR, 1, "found STV0299 DVB-S frontend @ 0x%02x", | ||
| 181 | lgtdqcs001f_config.demod_address); | ||
| 182 | |||
| 183 | dprintk(MANTIS_ERROR, 1, "Mantis DVB-S STV0299 frontend attach success"); | ||
| 184 | } else { | ||
| 185 | return -1; | ||
| 186 | } | ||
| 187 | } else { | ||
| 188 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
| 189 | adapter->name, | ||
| 190 | err); | ||
| 191 | |||
| 192 | return -EIO; | ||
| 193 | } | ||
| 194 | mantis->fe = fe; | ||
| 195 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
| 196 | |||
| 197 | return 0; | ||
| 198 | } | ||
| 199 | |||
| 200 | struct mantis_hwconfig vp1033_config = { | ||
| 201 | .model_name = MANTIS_MODEL_NAME, | ||
| 202 | .dev_type = MANTIS_DEV_TYPE, | ||
| 203 | .ts_size = MANTIS_TS_204, | ||
| 204 | |||
| 205 | .baud_rate = MANTIS_BAUD_9600, | ||
| 206 | .parity = MANTIS_PARITY_NONE, | ||
| 207 | .bytes = 0, | ||
| 208 | |||
| 209 | .frontend_init = vp1033_frontend_init, | ||
| 210 | .power = GPIF_A12, | ||
| 211 | .reset = GPIF_A13, | ||
| 212 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1033.h b/drivers/media/dvb/mantis/mantis_vp1033.h new file mode 100644 index 00000000000..7daaa1bf127 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp1033.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | Mantis VP-1033 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_VP1033_H | ||
| 22 | #define __MANTIS_VP1033_H | ||
| 23 | |||
| 24 | #include "mantis_common.h" | ||
| 25 | |||
| 26 | #define MANTIS_VP_1033_DVB_S 0x0016 | ||
| 27 | |||
| 28 | extern struct mantis_hwconfig vp1033_config; | ||
| 29 | |||
| 30 | #endif /* __MANTIS_VP1033_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1034.c b/drivers/media/dvb/mantis/mantis_vp1034.c new file mode 100644 index 00000000000..430ae84ce52 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp1034.c | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | /* | ||
| 2 | Mantis VP-1034 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/signal.h> | ||
| 22 | #include <linux/sched.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | #include <asm/io.h> | ||
| 25 | |||
| 26 | #include "dmxdev.h" | ||
| 27 | #include "dvbdev.h" | ||
| 28 | #include "dvb_demux.h" | ||
| 29 | #include "dvb_frontend.h" | ||
| 30 | #include "dvb_net.h" | ||
| 31 | |||
| 32 | #include "mb86a16.h" | ||
| 33 | #include "mantis_common.h" | ||
| 34 | #include "mantis_ioc.h" | ||
| 35 | #include "mantis_dvb.h" | ||
| 36 | #include "mantis_vp1034.h" | ||
| 37 | #include "mantis_reg.h" | ||
| 38 | |||
| 39 | struct mb86a16_config vp1034_mb86a16_config = { | ||
| 40 | .demod_address = 0x08, | ||
| 41 | .set_voltage = vp1034_set_voltage, | ||
| 42 | }; | ||
| 43 | |||
| 44 | #define MANTIS_MODEL_NAME "VP-1034" | ||
| 45 | #define MANTIS_DEV_TYPE "DVB-S/DSS" | ||
| 46 | |||
| 47 | int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
| 48 | { | ||
| 49 | struct mantis_pci *mantis = fe->dvb->priv; | ||
| 50 | |||
| 51 | switch (voltage) { | ||
| 52 | case SEC_VOLTAGE_13: | ||
| 53 | dprintk(MANTIS_ERROR, 1, "Polarization=[13V]"); | ||
| 54 | mantis_gpio_set_bits(mantis, 13, 1); | ||
| 55 | mantis_gpio_set_bits(mantis, 14, 0); | ||
| 56 | break; | ||
| 57 | case SEC_VOLTAGE_18: | ||
| 58 | dprintk(MANTIS_ERROR, 1, "Polarization=[18V]"); | ||
| 59 | mantis_gpio_set_bits(mantis, 13, 1); | ||
| 60 | mantis_gpio_set_bits(mantis, 14, 1); | ||
| 61 | break; | ||
| 62 | case SEC_VOLTAGE_OFF: | ||
| 63 | dprintk(MANTIS_ERROR, 1, "Frontend (dummy) POWERDOWN"); | ||
| 64 | break; | ||
| 65 | default: | ||
| 66 | dprintk(MANTIS_ERROR, 1, "Invalid = (%d)", (u32) voltage); | ||
| 67 | return -EINVAL; | ||
| 68 | } | ||
| 69 | mmwrite(0x00, MANTIS_GPIF_DOUT); | ||
| 70 | |||
| 71 | return 0; | ||
| 72 | } | ||
| 73 | |||
| 74 | static int vp1034_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
| 75 | { | ||
| 76 | struct i2c_adapter *adapter = &mantis->adapter; | ||
| 77 | |||
| 78 | int err = 0; | ||
| 79 | |||
| 80 | err = mantis_frontend_power(mantis, POWER_ON); | ||
| 81 | if (err == 0) { | ||
| 82 | mantis_frontend_soft_reset(mantis); | ||
| 83 | msleep(250); | ||
| 84 | |||
| 85 | dprintk(MANTIS_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)"); | ||
| 86 | fe = dvb_attach(mb86a16_attach, &vp1034_mb86a16_config, adapter); | ||
| 87 | if (fe) { | ||
| 88 | dprintk(MANTIS_ERROR, 1, | ||
| 89 | "found MB86A16 DVB-S/DSS frontend @0x%02x", | ||
| 90 | vp1034_mb86a16_config.demod_address); | ||
| 91 | |||
| 92 | } else { | ||
| 93 | return -1; | ||
| 94 | } | ||
| 95 | } else { | ||
| 96 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
| 97 | adapter->name, | ||
| 98 | err); | ||
| 99 | |||
| 100 | return -EIO; | ||
| 101 | } | ||
| 102 | mantis->fe = fe; | ||
| 103 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
| 104 | |||
| 105 | return 0; | ||
| 106 | } | ||
| 107 | |||
| 108 | struct mantis_hwconfig vp1034_config = { | ||
| 109 | .model_name = MANTIS_MODEL_NAME, | ||
| 110 | .dev_type = MANTIS_DEV_TYPE, | ||
| 111 | .ts_size = MANTIS_TS_204, | ||
| 112 | |||
| 113 | .baud_rate = MANTIS_BAUD_9600, | ||
| 114 | .parity = MANTIS_PARITY_NONE, | ||
| 115 | .bytes = 0, | ||
| 116 | |||
| 117 | .frontend_init = vp1034_frontend_init, | ||
| 118 | .power = GPIF_A12, | ||
| 119 | .reset = GPIF_A13, | ||
| 120 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1034.h b/drivers/media/dvb/mantis/mantis_vp1034.h new file mode 100644 index 00000000000..323f38ef8e3 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp1034.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* | ||
| 2 | Mantis VP-1034 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_VP1034_H | ||
| 22 | #define __MANTIS_VP1034_H | ||
| 23 | |||
| 24 | #include "dvb_frontend.h" | ||
| 25 | #include "mantis_common.h" | ||
| 26 | |||
| 27 | |||
| 28 | #define MANTIS_VP_1034_DVB_S 0x0014 | ||
| 29 | |||
| 30 | extern struct mantis_hwconfig vp1034_config; | ||
| 31 | extern int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage); | ||
| 32 | |||
| 33 | #endif /* __MANTIS_VP1034_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1041.c b/drivers/media/dvb/mantis/mantis_vp1041.c new file mode 100644 index 00000000000..38a436ca2fd --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp1041.c | |||
| @@ -0,0 +1,358 @@ | |||
| 1 | /* | ||
| 2 | Mantis VP-1041 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/signal.h> | ||
| 22 | #include <linux/sched.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | |||
| 25 | #include "dmxdev.h" | ||
| 26 | #include "dvbdev.h" | ||
| 27 | #include "dvb_demux.h" | ||
| 28 | #include "dvb_frontend.h" | ||
| 29 | #include "dvb_net.h" | ||
| 30 | |||
| 31 | #include "mantis_common.h" | ||
| 32 | #include "mantis_ioc.h" | ||
| 33 | #include "mantis_dvb.h" | ||
| 34 | #include "mantis_vp1041.h" | ||
| 35 | #include "stb0899_reg.h" | ||
| 36 | #include "stb0899_drv.h" | ||
| 37 | #include "stb0899_cfg.h" | ||
| 38 | #include "stb6100_cfg.h" | ||
| 39 | #include "stb6100.h" | ||
| 40 | #include "lnbp21.h" | ||
| 41 | |||
| 42 | #define MANTIS_MODEL_NAME "VP-1041" | ||
| 43 | #define MANTIS_DEV_TYPE "DSS/DVB-S/DVB-S2" | ||
| 44 | |||
| 45 | static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = { | ||
| 46 | |||
| 47 | /* 0x0000000b, *//* SYSREG */ | ||
| 48 | { STB0899_DEV_ID , 0x30 }, | ||
| 49 | { STB0899_DISCNTRL1 , 0x32 }, | ||
| 50 | { STB0899_DISCNTRL2 , 0x80 }, | ||
| 51 | { STB0899_DISRX_ST0 , 0x04 }, | ||
| 52 | { STB0899_DISRX_ST1 , 0x00 }, | ||
| 53 | { STB0899_DISPARITY , 0x00 }, | ||
| 54 | { STB0899_DISFIFO , 0x00 }, | ||
| 55 | { STB0899_DISSTATUS , 0x20 }, | ||
| 56 | { STB0899_DISF22 , 0x99 }, | ||
| 57 | { STB0899_DISF22RX , 0xa8 }, | ||
| 58 | /* SYSREG ? */ | ||
| 59 | { STB0899_ACRPRESC , 0x11 }, | ||
| 60 | { STB0899_ACRDIV1 , 0x0a }, | ||
| 61 | { STB0899_ACRDIV2 , 0x05 }, | ||
| 62 | { STB0899_DACR1 , 0x00 }, | ||
| 63 | { STB0899_DACR2 , 0x00 }, | ||
| 64 | { STB0899_OUTCFG , 0x00 }, | ||
| 65 | { STB0899_MODECFG , 0x00 }, | ||
| 66 | { STB0899_IRQSTATUS_3 , 0xfe }, | ||
| 67 | { STB0899_IRQSTATUS_2 , 0x03 }, | ||
| 68 | { STB0899_IRQSTATUS_1 , 0x7c }, | ||
| 69 | { STB0899_IRQSTATUS_0 , 0xf4 }, | ||
| 70 | { STB0899_IRQMSK_3 , 0xf3 }, | ||
| 71 | { STB0899_IRQMSK_2 , 0xfc }, | ||
| 72 | { STB0899_IRQMSK_1 , 0xff }, | ||
| 73 | { STB0899_IRQMSK_0 , 0xff }, | ||
| 74 | { STB0899_IRQCFG , 0x00 }, | ||
| 75 | { STB0899_I2CCFG , 0x88 }, | ||
| 76 | { STB0899_I2CRPT , 0x58 }, | ||
| 77 | { STB0899_IOPVALUE5 , 0x00 }, | ||
| 78 | { STB0899_IOPVALUE4 , 0x33 }, | ||
| 79 | { STB0899_IOPVALUE3 , 0x6d }, | ||
| 80 | { STB0899_IOPVALUE2 , 0x90 }, | ||
| 81 | { STB0899_IOPVALUE1 , 0x60 }, | ||
| 82 | { STB0899_IOPVALUE0 , 0x00 }, | ||
| 83 | { STB0899_GPIO00CFG , 0x82 }, | ||
| 84 | { STB0899_GPIO01CFG , 0x82 }, | ||
| 85 | { STB0899_GPIO02CFG , 0x82 }, | ||
| 86 | { STB0899_GPIO03CFG , 0x82 }, | ||
| 87 | { STB0899_GPIO04CFG , 0x82 }, | ||
| 88 | { STB0899_GPIO05CFG , 0x82 }, | ||
| 89 | { STB0899_GPIO06CFG , 0x82 }, | ||
| 90 | { STB0899_GPIO07CFG , 0x82 }, | ||
| 91 | { STB0899_GPIO08CFG , 0x82 }, | ||
| 92 | { STB0899_GPIO09CFG , 0x82 }, | ||
| 93 | { STB0899_GPIO10CFG , 0x82 }, | ||
| 94 | { STB0899_GPIO11CFG , 0x82 }, | ||
| 95 | { STB0899_GPIO12CFG , 0x82 }, | ||
| 96 | { STB0899_GPIO13CFG , 0x82 }, | ||
| 97 | { STB0899_GPIO14CFG , 0x82 }, | ||
| 98 | { STB0899_GPIO15CFG , 0x82 }, | ||
| 99 | { STB0899_GPIO16CFG , 0x82 }, | ||
| 100 | { STB0899_GPIO17CFG , 0x82 }, | ||
| 101 | { STB0899_GPIO18CFG , 0x82 }, | ||
| 102 | { STB0899_GPIO19CFG , 0x82 }, | ||
| 103 | { STB0899_GPIO20CFG , 0x82 }, | ||
| 104 | { STB0899_SDATCFG , 0xb8 }, | ||
| 105 | { STB0899_SCLTCFG , 0xba }, | ||
| 106 | { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ | ||
| 107 | { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ | ||
| 108 | { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ | ||
| 109 | { STB0899_DIRCLKCFG , 0x82 }, | ||
| 110 | { STB0899_CLKOUT27CFG , 0x7e }, | ||
| 111 | { STB0899_STDBYCFG , 0x82 }, | ||
| 112 | { STB0899_CS0CFG , 0x82 }, | ||
| 113 | { STB0899_CS1CFG , 0x82 }, | ||
| 114 | { STB0899_DISEQCOCFG , 0x20 }, | ||
| 115 | { STB0899_GPIO32CFG , 0x82 }, | ||
| 116 | { STB0899_GPIO33CFG , 0x82 }, | ||
| 117 | { STB0899_GPIO34CFG , 0x82 }, | ||
| 118 | { STB0899_GPIO35CFG , 0x82 }, | ||
| 119 | { STB0899_GPIO36CFG , 0x82 }, | ||
| 120 | { STB0899_GPIO37CFG , 0x82 }, | ||
| 121 | { STB0899_GPIO38CFG , 0x82 }, | ||
| 122 | { STB0899_GPIO39CFG , 0x82 }, | ||
| 123 | { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ | ||
| 124 | { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ | ||
| 125 | { STB0899_FILTCTRL , 0x00 }, | ||
| 126 | { STB0899_SYSCTRL , 0x01 }, | ||
| 127 | { STB0899_STOPCLK1 , 0x20 }, | ||
| 128 | { STB0899_STOPCLK2 , 0x00 }, | ||
| 129 | { STB0899_INTBUFSTATUS , 0x00 }, | ||
| 130 | { STB0899_INTBUFCTRL , 0x0a }, | ||
| 131 | { 0xffff , 0xff }, | ||
| 132 | }; | ||
| 133 | |||
| 134 | static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = { | ||
| 135 | { STB0899_DEMOD , 0x00 }, | ||
| 136 | { STB0899_RCOMPC , 0xc9 }, | ||
| 137 | { STB0899_AGC1CN , 0x01 }, | ||
| 138 | { STB0899_AGC1REF , 0x10 }, | ||
| 139 | { STB0899_RTC , 0x23 }, | ||
| 140 | { STB0899_TMGCFG , 0x4e }, | ||
| 141 | { STB0899_AGC2REF , 0x34 }, | ||
| 142 | { STB0899_TLSR , 0x84 }, | ||
| 143 | { STB0899_CFD , 0xf7 }, | ||
| 144 | { STB0899_ACLC , 0x87 }, | ||
| 145 | { STB0899_BCLC , 0x94 }, | ||
| 146 | { STB0899_EQON , 0x41 }, | ||
| 147 | { STB0899_LDT , 0xf1 }, | ||
| 148 | { STB0899_LDT2 , 0xe3 }, | ||
| 149 | { STB0899_EQUALREF , 0xb4 }, | ||
| 150 | { STB0899_TMGRAMP , 0x10 }, | ||
| 151 | { STB0899_TMGTHD , 0x30 }, | ||
| 152 | { STB0899_IDCCOMP , 0xfd }, | ||
| 153 | { STB0899_QDCCOMP , 0xff }, | ||
| 154 | { STB0899_POWERI , 0x0c }, | ||
| 155 | { STB0899_POWERQ , 0x0f }, | ||
| 156 | { STB0899_RCOMP , 0x6c }, | ||
| 157 | { STB0899_AGCIQIN , 0x80 }, | ||
| 158 | { STB0899_AGC2I1 , 0x06 }, | ||
| 159 | { STB0899_AGC2I2 , 0x00 }, | ||
| 160 | { STB0899_TLIR , 0x30 }, | ||
| 161 | { STB0899_RTF , 0x7f }, | ||
| 162 | { STB0899_DSTATUS , 0x00 }, | ||
| 163 | { STB0899_LDI , 0xbc }, | ||
| 164 | { STB0899_CFRM , 0xea }, | ||
| 165 | { STB0899_CFRL , 0x31 }, | ||
| 166 | { STB0899_NIRM , 0x2b }, | ||
| 167 | { STB0899_NIRL , 0x80 }, | ||
| 168 | { STB0899_ISYMB , 0x1d }, | ||
| 169 | { STB0899_QSYMB , 0xa6 }, | ||
| 170 | { STB0899_SFRH , 0x2f }, | ||
| 171 | { STB0899_SFRM , 0x68 }, | ||
| 172 | { STB0899_SFRL , 0x40 }, | ||
| 173 | { STB0899_SFRUPH , 0x2f }, | ||
| 174 | { STB0899_SFRUPM , 0x68 }, | ||
| 175 | { STB0899_SFRUPL , 0x40 }, | ||
| 176 | { STB0899_EQUAI1 , 0x02 }, | ||
| 177 | { STB0899_EQUAQ1 , 0xff }, | ||
| 178 | { STB0899_EQUAI2 , 0x04 }, | ||
| 179 | { STB0899_EQUAQ2 , 0x05 }, | ||
| 180 | { STB0899_EQUAI3 , 0x02 }, | ||
| 181 | { STB0899_EQUAQ3 , 0xfd }, | ||
| 182 | { STB0899_EQUAI4 , 0x03 }, | ||
| 183 | { STB0899_EQUAQ4 , 0x07 }, | ||
| 184 | { STB0899_EQUAI5 , 0x08 }, | ||
| 185 | { STB0899_EQUAQ5 , 0xf5 }, | ||
| 186 | { STB0899_DSTATUS2 , 0x00 }, | ||
| 187 | { STB0899_VSTATUS , 0x00 }, | ||
| 188 | { STB0899_VERROR , 0x86 }, | ||
| 189 | { STB0899_IQSWAP , 0x2a }, | ||
| 190 | { STB0899_ECNT1M , 0x00 }, | ||
| 191 | { STB0899_ECNT1L , 0x00 }, | ||
| 192 | { STB0899_ECNT2M , 0x00 }, | ||
| 193 | { STB0899_ECNT2L , 0x00 }, | ||
| 194 | { STB0899_ECNT3M , 0x0a }, | ||
| 195 | { STB0899_ECNT3L , 0xad }, | ||
| 196 | { STB0899_FECAUTO1 , 0x06 }, | ||
| 197 | { STB0899_FECM , 0x01 }, | ||
| 198 | { STB0899_VTH12 , 0xb0 }, | ||
| 199 | { STB0899_VTH23 , 0x7a }, | ||
| 200 | { STB0899_VTH34 , 0x58 }, | ||
| 201 | { STB0899_VTH56 , 0x38 }, | ||
| 202 | { STB0899_VTH67 , 0x34 }, | ||
| 203 | { STB0899_VTH78 , 0x24 }, | ||
| 204 | { STB0899_PRVIT , 0xff }, | ||
| 205 | { STB0899_VITSYNC , 0x19 }, | ||
| 206 | { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ | ||
| 207 | { STB0899_TSULC , 0x42 }, | ||
| 208 | { STB0899_RSLLC , 0x41 }, | ||
| 209 | { STB0899_TSLPL , 0x12 }, | ||
| 210 | { STB0899_TSCFGH , 0x0c }, | ||
| 211 | { STB0899_TSCFGM , 0x00 }, | ||
| 212 | { STB0899_TSCFGL , 0x00 }, | ||
| 213 | { STB0899_TSOUT , 0x69 }, /* 0x0d for CAM */ | ||
| 214 | { STB0899_RSSYNCDEL , 0x00 }, | ||
| 215 | { STB0899_TSINHDELH , 0x02 }, | ||
| 216 | { STB0899_TSINHDELM , 0x00 }, | ||
| 217 | { STB0899_TSINHDELL , 0x00 }, | ||
| 218 | { STB0899_TSLLSTKM , 0x1b }, | ||
| 219 | { STB0899_TSLLSTKL , 0xb3 }, | ||
| 220 | { STB0899_TSULSTKM , 0x00 }, | ||
| 221 | { STB0899_TSULSTKL , 0x00 }, | ||
| 222 | { STB0899_PCKLENUL , 0xbc }, | ||
| 223 | { STB0899_PCKLENLL , 0xcc }, | ||
| 224 | { STB0899_RSPCKLEN , 0xbd }, | ||
| 225 | { STB0899_TSSTATUS , 0x90 }, | ||
| 226 | { STB0899_ERRCTRL1 , 0xb6 }, | ||
| 227 | { STB0899_ERRCTRL2 , 0x95 }, | ||
| 228 | { STB0899_ERRCTRL3 , 0x8d }, | ||
| 229 | { STB0899_DMONMSK1 , 0x27 }, | ||
| 230 | { STB0899_DMONMSK0 , 0x03 }, | ||
| 231 | { STB0899_DEMAPVIT , 0x5c }, | ||
| 232 | { STB0899_PLPARM , 0x19 }, | ||
| 233 | { STB0899_PDELCTRL , 0x48 }, | ||
| 234 | { STB0899_PDELCTRL2 , 0x00 }, | ||
| 235 | { STB0899_BBHCTRL1 , 0x00 }, | ||
| 236 | { STB0899_BBHCTRL2 , 0x00 }, | ||
| 237 | { STB0899_HYSTTHRESH , 0x77 }, | ||
| 238 | { STB0899_MATCSTM , 0x00 }, | ||
| 239 | { STB0899_MATCSTL , 0x00 }, | ||
| 240 | { STB0899_UPLCSTM , 0x00 }, | ||
| 241 | { STB0899_UPLCSTL , 0x00 }, | ||
| 242 | { STB0899_DFLCSTM , 0x00 }, | ||
| 243 | { STB0899_DFLCSTL , 0x00 }, | ||
| 244 | { STB0899_SYNCCST , 0x00 }, | ||
| 245 | { STB0899_SYNCDCSTM , 0x00 }, | ||
| 246 | { STB0899_SYNCDCSTL , 0x00 }, | ||
| 247 | { STB0899_ISI_ENTRY , 0x00 }, | ||
| 248 | { STB0899_ISI_BIT_EN , 0x00 }, | ||
| 249 | { STB0899_MATSTRM , 0xf0 }, | ||
| 250 | { STB0899_MATSTRL , 0x02 }, | ||
| 251 | { STB0899_UPLSTRM , 0x45 }, | ||
| 252 | { STB0899_UPLSTRL , 0x60 }, | ||
| 253 | { STB0899_DFLSTRM , 0xe3 }, | ||
| 254 | { STB0899_DFLSTRL , 0x00 }, | ||
| 255 | { STB0899_SYNCSTR , 0x47 }, | ||
| 256 | { STB0899_SYNCDSTRM , 0x05 }, | ||
| 257 | { STB0899_SYNCDSTRL , 0x18 }, | ||
| 258 | { STB0899_CFGPDELSTATUS1 , 0x19 }, | ||
| 259 | { STB0899_CFGPDELSTATUS2 , 0x2b }, | ||
| 260 | { STB0899_BBFERRORM , 0x00 }, | ||
| 261 | { STB0899_BBFERRORL , 0x01 }, | ||
| 262 | { STB0899_UPKTERRORM , 0x00 }, | ||
| 263 | { STB0899_UPKTERRORL , 0x00 }, | ||
| 264 | { 0xffff , 0xff }, | ||
| 265 | }; | ||
| 266 | |||
| 267 | struct stb0899_config vp1041_stb0899_config = { | ||
| 268 | .init_dev = vp1041_stb0899_s1_init_1, | ||
| 269 | .init_s2_demod = stb0899_s2_init_2, | ||
| 270 | .init_s1_demod = vp1041_stb0899_s1_init_3, | ||
| 271 | .init_s2_fec = stb0899_s2_init_4, | ||
| 272 | .init_tst = stb0899_s1_init_5, | ||
| 273 | |||
| 274 | .demod_address = 0x68, /* 0xd0 >> 1 */ | ||
| 275 | |||
| 276 | .xtal_freq = 27000000, | ||
| 277 | .inversion = IQ_SWAP_ON, /* 1 */ | ||
| 278 | |||
| 279 | .lo_clk = 76500000, | ||
| 280 | .hi_clk = 99000000, | ||
| 281 | |||
| 282 | .esno_ave = STB0899_DVBS2_ESNO_AVE, | ||
| 283 | .esno_quant = STB0899_DVBS2_ESNO_QUANT, | ||
| 284 | .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE, | ||
| 285 | .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE, | ||
| 286 | .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD, | ||
| 287 | .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ, | ||
| 288 | .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK, | ||
| 289 | .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF, | ||
| 290 | .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT, | ||
| 291 | |||
| 292 | .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS, | ||
| 293 | .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET, | ||
| 294 | .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS, | ||
| 295 | .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER, | ||
| 296 | |||
| 297 | .tuner_get_frequency = stb6100_get_frequency, | ||
| 298 | .tuner_set_frequency = stb6100_set_frequency, | ||
| 299 | .tuner_set_bandwidth = stb6100_set_bandwidth, | ||
| 300 | .tuner_get_bandwidth = stb6100_get_bandwidth, | ||
| 301 | .tuner_set_rfsiggain = NULL, | ||
| 302 | }; | ||
| 303 | |||
| 304 | struct stb6100_config vp1041_stb6100_config = { | ||
| 305 | .tuner_address = 0x60, | ||
| 306 | .refclock = 27000000, | ||
| 307 | }; | ||
| 308 | |||
| 309 | static int vp1041_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
| 310 | { | ||
| 311 | struct i2c_adapter *adapter = &mantis->adapter; | ||
| 312 | |||
| 313 | int err = 0; | ||
| 314 | |||
| 315 | err = mantis_frontend_power(mantis, POWER_ON); | ||
| 316 | if (err == 0) { | ||
| 317 | mantis_frontend_soft_reset(mantis); | ||
| 318 | msleep(250); | ||
| 319 | mantis->fe = dvb_attach(stb0899_attach, &vp1041_stb0899_config, adapter); | ||
| 320 | if (mantis->fe) { | ||
| 321 | dprintk(MANTIS_ERROR, 1, | ||
| 322 | "found STB0899 DVB-S/DVB-S2 frontend @0x%02x", | ||
| 323 | vp1041_stb0899_config.demod_address); | ||
| 324 | |||
| 325 | if (dvb_attach(stb6100_attach, mantis->fe, &vp1041_stb6100_config, adapter)) { | ||
| 326 | if (!dvb_attach(lnbp21_attach, mantis->fe, adapter, 0, 0)) | ||
| 327 | dprintk(MANTIS_ERROR, 1, "No LNBP21 found!"); | ||
| 328 | } | ||
| 329 | } else { | ||
| 330 | return -EREMOTEIO; | ||
| 331 | } | ||
| 332 | } else { | ||
| 333 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
| 334 | adapter->name, | ||
| 335 | err); | ||
| 336 | |||
| 337 | return -EIO; | ||
| 338 | } | ||
| 339 | |||
| 340 | |||
| 341 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
| 342 | |||
| 343 | return 0; | ||
| 344 | } | ||
| 345 | |||
| 346 | struct mantis_hwconfig vp1041_config = { | ||
| 347 | .model_name = MANTIS_MODEL_NAME, | ||
| 348 | .dev_type = MANTIS_DEV_TYPE, | ||
| 349 | .ts_size = MANTIS_TS_188, | ||
| 350 | |||
| 351 | .baud_rate = MANTIS_BAUD_9600, | ||
| 352 | .parity = MANTIS_PARITY_NONE, | ||
| 353 | .bytes = 0, | ||
| 354 | |||
| 355 | .frontend_init = vp1041_frontend_init, | ||
| 356 | .power = GPIF_A12, | ||
| 357 | .reset = GPIF_A13, | ||
| 358 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp1041.h b/drivers/media/dvb/mantis/mantis_vp1041.h new file mode 100644 index 00000000000..1ae5b3de808 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp1041.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* | ||
| 2 | Mantis VP-1041 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_VP1041_H | ||
| 22 | #define __MANTIS_VP1041_H | ||
| 23 | |||
| 24 | #include "mantis_common.h" | ||
| 25 | |||
| 26 | #define MANTIS_VP_1041_DVB_S2 0x0031 | ||
| 27 | #define SKYSTAR_HD2_10 0x0001 | ||
| 28 | #define SKYSTAR_HD2_20 0x0003 | ||
| 29 | #define CINERGY_S2_PCI_HD 0x1179 | ||
| 30 | |||
| 31 | extern struct mantis_hwconfig vp1041_config; | ||
| 32 | |||
| 33 | #endif /* __MANTIS_VP1041_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp2033.c b/drivers/media/dvb/mantis/mantis_vp2033.c new file mode 100644 index 00000000000..06da0ddf05a --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp2033.c | |||
| @@ -0,0 +1,187 @@ | |||
| 1 | /* | ||
| 2 | Mantis VP-2033 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/signal.h> | ||
| 22 | #include <linux/sched.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | |||
| 25 | #include "dmxdev.h" | ||
| 26 | #include "dvbdev.h" | ||
| 27 | #include "dvb_demux.h" | ||
| 28 | #include "dvb_frontend.h" | ||
| 29 | #include "dvb_net.h" | ||
| 30 | |||
| 31 | #include "tda1002x.h" | ||
| 32 | #include "mantis_common.h" | ||
| 33 | #include "mantis_ioc.h" | ||
| 34 | #include "mantis_dvb.h" | ||
| 35 | #include "mantis_vp2033.h" | ||
| 36 | |||
| 37 | #define MANTIS_MODEL_NAME "VP-2033" | ||
| 38 | #define MANTIS_DEV_TYPE "DVB-C" | ||
| 39 | |||
| 40 | struct tda1002x_config vp2033_tda1002x_cu1216_config = { | ||
| 41 | .demod_address = 0x18 >> 1, | ||
| 42 | .invert = 1, | ||
| 43 | }; | ||
| 44 | |||
| 45 | struct tda10023_config vp2033_tda10023_cu1216_config = { | ||
| 46 | .demod_address = 0x18 >> 1, | ||
| 47 | .invert = 1, | ||
| 48 | }; | ||
| 49 | |||
| 50 | static u8 read_pwm(struct mantis_pci *mantis) | ||
| 51 | { | ||
| 52 | struct i2c_adapter *adapter = &mantis->adapter; | ||
| 53 | |||
| 54 | u8 b = 0xff; | ||
| 55 | u8 pwm; | ||
| 56 | struct i2c_msg msg[] = { | ||
| 57 | {.addr = 0x50, .flags = 0, .buf = &b, .len = 1}, | ||
| 58 | {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} | ||
| 59 | }; | ||
| 60 | |||
| 61 | if ((i2c_transfer(adapter, msg, 2) != 2) | ||
| 62 | || (pwm == 0xff)) | ||
| 63 | pwm = 0x48; | ||
| 64 | |||
| 65 | return pwm; | ||
| 66 | } | ||
| 67 | |||
| 68 | static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
| 69 | { | ||
| 70 | struct mantis_pci *mantis = fe->dvb->priv; | ||
| 71 | struct i2c_adapter *adapter = &mantis->adapter; | ||
| 72 | |||
| 73 | u8 buf[6]; | ||
| 74 | struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)}; | ||
| 75 | int i; | ||
| 76 | |||
| 77 | #define CU1216_IF 36125000 | ||
| 78 | #define TUNER_MUL 62500 | ||
| 79 | |||
| 80 | u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; | ||
| 81 | |||
| 82 | buf[0] = (div >> 8) & 0x7f; | ||
| 83 | buf[1] = div & 0xff; | ||
| 84 | buf[2] = 0xce; | ||
| 85 | buf[3] = (params->frequency < 150000000 ? 0x01 : | ||
| 86 | params->frequency < 445000000 ? 0x02 : 0x04); | ||
| 87 | buf[4] = 0xde; | ||
| 88 | buf[5] = 0x20; | ||
| 89 | |||
| 90 | if (fe->ops.i2c_gate_ctrl) | ||
| 91 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 92 | |||
| 93 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
| 94 | return -EIO; | ||
| 95 | |||
| 96 | /* wait for the pll lock */ | ||
| 97 | msg.flags = I2C_M_RD; | ||
| 98 | msg.len = 1; | ||
| 99 | for (i = 0; i < 20; i++) { | ||
| 100 | if (fe->ops.i2c_gate_ctrl) | ||
| 101 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 102 | |||
| 103 | if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40)) | ||
| 104 | break; | ||
| 105 | |||
| 106 | msleep(10); | ||
| 107 | } | ||
| 108 | |||
| 109 | /* switch the charge pump to the lower current */ | ||
| 110 | msg.flags = 0; | ||
| 111 | msg.len = 2; | ||
| 112 | msg.buf = &buf[2]; | ||
| 113 | buf[2] &= ~0x40; | ||
| 114 | if (fe->ops.i2c_gate_ctrl) | ||
| 115 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 116 | |||
| 117 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
| 118 | return -EIO; | ||
| 119 | |||
| 120 | return 0; | ||
| 121 | } | ||
| 122 | |||
| 123 | static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
| 124 | { | ||
| 125 | struct i2c_adapter *adapter = &mantis->adapter; | ||
| 126 | |||
| 127 | int err = 0; | ||
| 128 | |||
| 129 | err = mantis_frontend_power(mantis, POWER_ON); | ||
| 130 | if (err == 0) { | ||
| 131 | mantis_frontend_soft_reset(mantis); | ||
| 132 | msleep(250); | ||
| 133 | |||
| 134 | dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)"); | ||
| 135 | fe = dvb_attach(tda10021_attach, &vp2033_tda1002x_cu1216_config, | ||
| 136 | adapter, | ||
| 137 | read_pwm(mantis)); | ||
| 138 | |||
| 139 | if (fe) { | ||
| 140 | dprintk(MANTIS_ERROR, 1, | ||
| 141 | "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x", | ||
| 142 | vp2033_tda1002x_cu1216_config.demod_address); | ||
| 143 | } else { | ||
| 144 | fe = dvb_attach(tda10023_attach, &vp2033_tda10023_cu1216_config, | ||
| 145 | adapter, | ||
| 146 | read_pwm(mantis)); | ||
| 147 | |||
| 148 | if (fe) { | ||
| 149 | dprintk(MANTIS_ERROR, 1, | ||
| 150 | "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x", | ||
| 151 | vp2033_tda1002x_cu1216_config.demod_address); | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | if (fe) { | ||
| 156 | fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set; | ||
| 157 | dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success"); | ||
| 158 | } else { | ||
| 159 | return -1; | ||
| 160 | } | ||
| 161 | } else { | ||
| 162 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
| 163 | adapter->name, | ||
| 164 | err); | ||
| 165 | |||
| 166 | return -EIO; | ||
| 167 | } | ||
| 168 | |||
| 169 | mantis->fe = fe; | ||
| 170 | dprintk(MANTIS_DEBUG, 1, "Done!"); | ||
| 171 | |||
| 172 | return 0; | ||
| 173 | } | ||
| 174 | |||
| 175 | struct mantis_hwconfig vp2033_config = { | ||
| 176 | .model_name = MANTIS_MODEL_NAME, | ||
| 177 | .dev_type = MANTIS_DEV_TYPE, | ||
| 178 | .ts_size = MANTIS_TS_204, | ||
| 179 | |||
| 180 | .baud_rate = MANTIS_BAUD_9600, | ||
| 181 | .parity = MANTIS_PARITY_NONE, | ||
| 182 | .bytes = 0, | ||
| 183 | |||
| 184 | .frontend_init = vp2033_frontend_init, | ||
| 185 | .power = GPIF_A12, | ||
| 186 | .reset = GPIF_A13, | ||
| 187 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp2033.h b/drivers/media/dvb/mantis/mantis_vp2033.h new file mode 100644 index 00000000000..c55242b79d5 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp2033.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | Mantis VP-2033 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_VP2033_H | ||
| 22 | #define __MANTIS_VP2033_H | ||
| 23 | |||
| 24 | #include "mantis_common.h" | ||
| 25 | |||
| 26 | #define MANTIS_VP_2033_DVB_C 0x0008 | ||
| 27 | |||
| 28 | extern struct mantis_hwconfig vp2033_config; | ||
| 29 | |||
| 30 | #endif /* __MANTIS_VP2033_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp2040.c b/drivers/media/dvb/mantis/mantis_vp2040.c new file mode 100644 index 00000000000..f72b137b765 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp2040.c | |||
| @@ -0,0 +1,186 @@ | |||
| 1 | /* | ||
| 2 | Mantis VP-2040 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/signal.h> | ||
| 22 | #include <linux/sched.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | |||
| 25 | #include "dmxdev.h" | ||
| 26 | #include "dvbdev.h" | ||
| 27 | #include "dvb_demux.h" | ||
| 28 | #include "dvb_frontend.h" | ||
| 29 | #include "dvb_net.h" | ||
| 30 | |||
| 31 | #include "tda1002x.h" | ||
| 32 | #include "mantis_common.h" | ||
| 33 | #include "mantis_ioc.h" | ||
| 34 | #include "mantis_dvb.h" | ||
| 35 | #include "mantis_vp2040.h" | ||
| 36 | |||
| 37 | #define MANTIS_MODEL_NAME "VP-2040" | ||
| 38 | #define MANTIS_DEV_TYPE "DVB-C" | ||
| 39 | |||
| 40 | struct tda1002x_config vp2040_tda1002x_cu1216_config = { | ||
| 41 | .demod_address = 0x18 >> 1, | ||
| 42 | .invert = 1, | ||
| 43 | }; | ||
| 44 | |||
| 45 | struct tda10023_config vp2040_tda10023_cu1216_config = { | ||
| 46 | .demod_address = 0x18 >> 1, | ||
| 47 | .invert = 1, | ||
| 48 | }; | ||
| 49 | |||
| 50 | static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
| 51 | { | ||
| 52 | struct mantis_pci *mantis = fe->dvb->priv; | ||
| 53 | struct i2c_adapter *adapter = &mantis->adapter; | ||
| 54 | |||
| 55 | u8 buf[6]; | ||
| 56 | struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)}; | ||
| 57 | int i; | ||
| 58 | |||
| 59 | #define CU1216_IF 36125000 | ||
| 60 | #define TUNER_MUL 62500 | ||
| 61 | |||
| 62 | u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; | ||
| 63 | |||
| 64 | buf[0] = (div >> 8) & 0x7f; | ||
| 65 | buf[1] = div & 0xff; | ||
| 66 | buf[2] = 0xce; | ||
| 67 | buf[3] = (params->frequency < 150000000 ? 0x01 : | ||
| 68 | params->frequency < 445000000 ? 0x02 : 0x04); | ||
| 69 | buf[4] = 0xde; | ||
| 70 | buf[5] = 0x20; | ||
| 71 | |||
| 72 | if (fe->ops.i2c_gate_ctrl) | ||
| 73 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 74 | |||
| 75 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
| 76 | return -EIO; | ||
| 77 | |||
| 78 | /* wait for the pll lock */ | ||
| 79 | msg.flags = I2C_M_RD; | ||
| 80 | msg.len = 1; | ||
| 81 | for (i = 0; i < 20; i++) { | ||
| 82 | if (fe->ops.i2c_gate_ctrl) | ||
| 83 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 84 | |||
| 85 | if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40)) | ||
| 86 | break; | ||
| 87 | |||
| 88 | msleep(10); | ||
| 89 | } | ||
| 90 | |||
| 91 | /* switch the charge pump to the lower current */ | ||
| 92 | msg.flags = 0; | ||
| 93 | msg.len = 2; | ||
| 94 | msg.buf = &buf[2]; | ||
| 95 | buf[2] &= ~0x40; | ||
| 96 | if (fe->ops.i2c_gate_ctrl) | ||
| 97 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 98 | |||
| 99 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
| 100 | return -EIO; | ||
| 101 | |||
| 102 | return 0; | ||
| 103 | } | ||
| 104 | |||
| 105 | static u8 read_pwm(struct mantis_pci *mantis) | ||
| 106 | { | ||
| 107 | struct i2c_adapter *adapter = &mantis->adapter; | ||
| 108 | |||
| 109 | u8 b = 0xff; | ||
| 110 | u8 pwm; | ||
| 111 | struct i2c_msg msg[] = { | ||
| 112 | {.addr = 0x50, .flags = 0, .buf = &b, .len = 1}, | ||
| 113 | {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} | ||
| 114 | }; | ||
| 115 | |||
| 116 | if ((i2c_transfer(adapter, msg, 2) != 2) | ||
| 117 | || (pwm == 0xff)) | ||
| 118 | pwm = 0x48; | ||
| 119 | |||
| 120 | return pwm; | ||
| 121 | } | ||
| 122 | |||
| 123 | static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
| 124 | { | ||
| 125 | struct i2c_adapter *adapter = &mantis->adapter; | ||
| 126 | |||
| 127 | int err = 0; | ||
| 128 | |||
| 129 | err = mantis_frontend_power(mantis, POWER_ON); | ||
| 130 | if (err == 0) { | ||
| 131 | mantis_frontend_soft_reset(mantis); | ||
| 132 | msleep(250); | ||
| 133 | |||
| 134 | dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)"); | ||
| 135 | fe = dvb_attach(tda10021_attach, &vp2040_tda1002x_cu1216_config, | ||
| 136 | adapter, | ||
| 137 | read_pwm(mantis)); | ||
| 138 | |||
| 139 | if (fe) { | ||
| 140 | dprintk(MANTIS_ERROR, 1, | ||
| 141 | "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x", | ||
| 142 | vp2040_tda1002x_cu1216_config.demod_address); | ||
| 143 | } else { | ||
| 144 | fe = dvb_attach(tda10023_attach, &vp2040_tda10023_cu1216_config, | ||
| 145 | adapter, | ||
| 146 | read_pwm(mantis)); | ||
| 147 | |||
| 148 | if (fe) { | ||
| 149 | dprintk(MANTIS_ERROR, 1, | ||
| 150 | "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x", | ||
| 151 | vp2040_tda1002x_cu1216_config.demod_address); | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | if (fe) { | ||
| 156 | fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set; | ||
| 157 | dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success"); | ||
| 158 | } else { | ||
| 159 | return -1; | ||
| 160 | } | ||
| 161 | } else { | ||
| 162 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
| 163 | adapter->name, | ||
| 164 | err); | ||
| 165 | |||
| 166 | return -EIO; | ||
| 167 | } | ||
| 168 | mantis->fe = fe; | ||
| 169 | dprintk(MANTIS_DEBUG, 1, "Done!"); | ||
| 170 | |||
| 171 | return 0; | ||
| 172 | } | ||
| 173 | |||
| 174 | struct mantis_hwconfig vp2040_config = { | ||
| 175 | .model_name = MANTIS_MODEL_NAME, | ||
| 176 | .dev_type = MANTIS_DEV_TYPE, | ||
| 177 | .ts_size = MANTIS_TS_204, | ||
| 178 | |||
| 179 | .baud_rate = MANTIS_BAUD_9600, | ||
| 180 | .parity = MANTIS_PARITY_NONE, | ||
| 181 | .bytes = 0, | ||
| 182 | |||
| 183 | .frontend_init = vp2040_frontend_init, | ||
| 184 | .power = GPIF_A12, | ||
| 185 | .reset = GPIF_A13, | ||
| 186 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp2040.h b/drivers/media/dvb/mantis/mantis_vp2040.h new file mode 100644 index 00000000000..d125e219b68 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp2040.h | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* | ||
| 2 | Mantis VP-2040 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_VP2040_H | ||
| 22 | #define __MANTIS_VP2040_H | ||
| 23 | |||
| 24 | #include "mantis_common.h" | ||
| 25 | |||
| 26 | #define MANTIS_VP_2040_DVB_C 0x0043 | ||
| 27 | #define CINERGY_C 0x1178 | ||
| 28 | #define CABLESTAR_HD2 0x0002 | ||
| 29 | |||
| 30 | extern struct mantis_hwconfig vp2040_config; | ||
| 31 | |||
| 32 | #endif /* __MANTIS_VP2040_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp3028.c b/drivers/media/dvb/mantis/mantis_vp3028.c new file mode 100644 index 00000000000..4155c838a18 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp3028.c | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* | ||
| 2 | Mantis VP-3028 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include "mantis_common.h" | ||
| 22 | #include "mantis_vp3028.h" | ||
| 23 | |||
| 24 | struct zl10353_config mantis_vp3028_config = { | ||
| 25 | .demod_address = 0x0f, | ||
| 26 | }; | ||
| 27 | |||
| 28 | #define MANTIS_MODEL_NAME "VP-3028" | ||
| 29 | #define MANTIS_DEV_TYPE "DVB-T" | ||
| 30 | |||
| 31 | struct mantis_hwconfig vp3028_mantis_config = { | ||
| 32 | .model_name = MANTIS_MODEL_NAME, | ||
| 33 | .dev_type = MANTIS_DEV_TYPE, | ||
| 34 | .ts_size = MANTIS_TS_188, | ||
| 35 | .baud_rate = MANTIS_BAUD_9600, | ||
| 36 | .parity = MANTIS_PARITY_NONE, | ||
| 37 | .bytes = 0, | ||
| 38 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp3028.h b/drivers/media/dvb/mantis/mantis_vp3028.h new file mode 100644 index 00000000000..b07be6adc52 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp3028.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* | ||
| 2 | Mantis VP-3028 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_VP3028_H | ||
| 22 | #define __MANTIS_VP3028_H | ||
| 23 | |||
| 24 | #include "dvb_frontend.h" | ||
| 25 | #include "mantis_common.h" | ||
| 26 | #include "zl10353.h" | ||
| 27 | |||
| 28 | #define MANTIS_VP_3028_DVB_T 0x0028 | ||
| 29 | |||
| 30 | extern struct zl10353_config mantis_vp3028_config; | ||
| 31 | extern struct mantis_hwconfig vp3028_mantis_config; | ||
| 32 | |||
| 33 | #endif /* __MANTIS_VP3028_H */ | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.c b/drivers/media/dvb/mantis/mantis_vp3030.c new file mode 100644 index 00000000000..c09308cd3ac --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp3030.c | |||
| @@ -0,0 +1,105 @@ | |||
| 1 | /* | ||
| 2 | Mantis VP-3030 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/signal.h> | ||
| 22 | #include <linux/sched.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | |||
| 25 | #include "dmxdev.h" | ||
| 26 | #include "dvbdev.h" | ||
| 27 | #include "dvb_demux.h" | ||
| 28 | #include "dvb_frontend.h" | ||
| 29 | #include "dvb_net.h" | ||
| 30 | |||
| 31 | #include "zl10353.h" | ||
| 32 | #include "tda665x.h" | ||
| 33 | #include "mantis_common.h" | ||
| 34 | #include "mantis_ioc.h" | ||
| 35 | #include "mantis_dvb.h" | ||
| 36 | #include "mantis_vp3030.h" | ||
| 37 | |||
| 38 | struct zl10353_config mantis_vp3030_config = { | ||
| 39 | .demod_address = 0x0f, | ||
| 40 | }; | ||
| 41 | |||
| 42 | struct tda665x_config env57h12d5_config = { | ||
| 43 | .name = "ENV57H12D5 (ET-50DT)", | ||
| 44 | .addr = 0x60, | ||
| 45 | .frequency_min = 47000000, | ||
| 46 | .frequency_max = 862000000, | ||
| 47 | .frequency_offst = 3616667, | ||
| 48 | .ref_multiplier = 6, /* 1/6 MHz */ | ||
| 49 | .ref_divider = 100000, /* 1/6 MHz */ | ||
| 50 | }; | ||
| 51 | |||
| 52 | #define MANTIS_MODEL_NAME "VP-3030" | ||
| 53 | #define MANTIS_DEV_TYPE "DVB-T" | ||
| 54 | |||
| 55 | |||
| 56 | static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
| 57 | { | ||
| 58 | struct i2c_adapter *adapter = &mantis->adapter; | ||
| 59 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
| 60 | int err = 0; | ||
| 61 | |||
| 62 | mantis_gpio_set_bits(mantis, config->reset, 0); | ||
| 63 | msleep(100); | ||
| 64 | err = mantis_frontend_power(mantis, POWER_ON); | ||
| 65 | msleep(100); | ||
| 66 | mantis_gpio_set_bits(mantis, config->reset, 1); | ||
| 67 | |||
| 68 | if (err == 0) { | ||
| 69 | msleep(250); | ||
| 70 | dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)"); | ||
| 71 | fe = dvb_attach(zl10353_attach, &mantis_vp3030_config, adapter); | ||
| 72 | |||
| 73 | if (!fe) | ||
| 74 | return -1; | ||
| 75 | |||
| 76 | dvb_attach(tda665x_attach, fe, &env57h12d5_config, adapter); | ||
| 77 | } else { | ||
| 78 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
| 79 | adapter->name, | ||
| 80 | err); | ||
| 81 | |||
| 82 | return -EIO; | ||
| 83 | |||
| 84 | } | ||
| 85 | mantis->fe = fe; | ||
| 86 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
| 87 | |||
| 88 | return 0; | ||
| 89 | } | ||
| 90 | |||
| 91 | struct mantis_hwconfig vp3030_config = { | ||
| 92 | .model_name = MANTIS_MODEL_NAME, | ||
| 93 | .dev_type = MANTIS_DEV_TYPE, | ||
| 94 | .ts_size = MANTIS_TS_188, | ||
| 95 | |||
| 96 | .baud_rate = MANTIS_BAUD_9600, | ||
| 97 | .parity = MANTIS_PARITY_NONE, | ||
| 98 | .bytes = 0, | ||
| 99 | |||
| 100 | .frontend_init = vp3030_frontend_init, | ||
| 101 | .power = GPIF_A12, | ||
| 102 | .reset = GPIF_A13, | ||
| 103 | |||
| 104 | .i2c_mode = MANTIS_BYTE_MODE | ||
| 105 | }; | ||
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.h b/drivers/media/dvb/mantis/mantis_vp3030.h new file mode 100644 index 00000000000..5f12c426627 --- /dev/null +++ b/drivers/media/dvb/mantis/mantis_vp3030.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | Mantis VP-3030 driver | ||
| 3 | |||
| 4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MANTIS_VP3030_H | ||
| 22 | #define __MANTIS_VP3030_H | ||
| 23 | |||
| 24 | #include "mantis_common.h" | ||
| 25 | |||
| 26 | #define MANTIS_VP_3030_DVB_T 0x0024 | ||
| 27 | |||
| 28 | extern struct mantis_hwconfig vp3030_config; | ||
| 29 | |||
| 30 | #endif /* __MANTIS_VP3030_H */ | ||
