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; 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 if (!(stat & mask)) 84 return IRQ_NONE; 85 86 rst_mask = MANTIS_GPIF_WRACK | 87 MANTIS_GPIF_OTHERR | 88 MANTIS_SBUF_WSTO | 89 MANTIS_GPIF_EXTIRQ; 90 91 rst_stat = mmread(MANTIS_GPIF_STATUS); 92 rst_stat &= rst_mask; 93 mmwrite(rst_stat, MANTIS_GPIF_STATUS); 94 95 mantis->mantis_int_stat = stat; 96 mantis->mantis_int_mask = mask; 97 dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask); 98 if (stat & MANTIS_INT_RISCEN) { 99 dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]); 100 } 101 if (stat & MANTIS_INT_IRQ0) { 102 dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]); 103 mantis->gpif_status = rst_stat; 104 wake_up(&ca->hif_write_wq); 105 schedule_work(&ca->hif_evm_work); 106 } 107 if (stat & MANTIS_INT_IRQ1) { 108 dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); 109 spin_lock(&mantis->intmask_lock); 110 mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ1, 111 MANTIS_INT_MASK); 112 spin_unlock(&mantis->intmask_lock); 113 schedule_work(&mantis->uart_work); 114 } 115 if (stat & MANTIS_INT_OCERR) { 116 dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]); 117 } 118 if (stat & MANTIS_INT_PABORT) { 119 dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]); 120 } 121 if (stat & MANTIS_INT_RIPERR) { 122 dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]); 123 } 124 if (stat & MANTIS_INT_PPERR) { 125 dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]); 126 } 127 if (stat & MANTIS_INT_FTRGT) { 128 dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]); 129 } 130 if (stat & MANTIS_INT_RISCI) { 131 dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); 132 mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28; 133 tasklet_schedule(&mantis->tasklet); 134 } 135 if (stat & MANTIS_INT_I2CDONE) { 136 dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]); 137 wake_up(&mantis->i2c_wq); 138 } 139 mmwrite(stat, MANTIS_INT_STAT); 140 stat &= ~(MANTIS_INT_RISCEN | MANTIS_INT_I2CDONE | 141 MANTIS_INT_I2CRACK | MANTIS_INT_PCMCIA7 | 142 MANTIS_INT_PCMCIA6 | MANTIS_INT_PCMCIA5 | 143 MANTIS_INT_PCMCIA4 | MANTIS_INT_PCMCIA3 | 144 MANTIS_INT_PCMCIA2 | MANTIS_INT_PCMCIA1 | 145 MANTIS_INT_PCMCIA0 | MANTIS_INT_IRQ1 | 146 MANTIS_INT_IRQ0 | MANTIS_INT_OCERR | 147 MANTIS_INT_PABORT | MANTIS_INT_RIPERR | 148 MANTIS_INT_PPERR | MANTIS_INT_FTRGT | 149 MANTIS_INT_RISCI); 150 151 if (stat) 152 dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask); 153 154 dprintk(MANTIS_DEBUG, 0, "\n"); 155 return IRQ_HANDLED; 156 } 157 158 static int hopper_pci_probe(struct pci_dev *pdev, 159 const struct pci_device_id *pci_id) 160 { 161 struct mantis_pci_drvdata *drvdata; 162 struct mantis_pci *mantis; 163 struct mantis_hwconfig *config; 164 int err = 0; 165 166 mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL); 167 if (mantis == NULL) { 168 printk(KERN_ERR "%s ERROR: Out of memory\n", __func__); 169 err = -ENOMEM; 170 goto fail0; 171 } 172 173 drvdata = (void *)pci_id->driver_data; 174 mantis->num = devs; 175 mantis->verbose = verbose; 176 mantis->pdev = pdev; 177 config = drvdata->hwconfig; 178 config->irq_handler = &hopper_irq_handler; 179 mantis->hwconfig = config; 180 mantis->rc_map_name = drvdata->rc_map_name; 181 182 spin_lock_init(&mantis->intmask_lock); 183 184 err = mantis_pci_init(mantis); 185 if (err) { 186 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err); 187 goto fail1; 188 } 189 190 err = mantis_stream_control(mantis, STREAM_TO_HIF); 191 if (err < 0) { 192 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err); 193 goto fail1; 194 } 195 196 err = mantis_i2c_init(mantis); 197 if (err < 0) { 198 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err); 199 goto fail2; 200 } 201 202 err = mantis_get_mac(mantis); 203 if (err < 0) { 204 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err); 205 goto fail2; 206 } 207 208 err = mantis_dma_init(mantis); 209 if (err < 0) { 210 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err); 211 goto fail3; 212 } 213 214 err = mantis_dvb_init(mantis); 215 if (err < 0) { 216 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err); 217 goto fail4; 218 } 219 devs++; 220 221 return err; 222 223 fail4: 224 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err); 225 mantis_dma_exit(mantis); 226 227 fail3: 228 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err); 229 mantis_i2c_exit(mantis); 230 231 fail2: 232 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err); 233 mantis_pci_exit(mantis); 234 235 fail1: 236 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err); 237 kfree(mantis); 238 239 fail0: 240 return err; 241 } 242 243 static void hopper_pci_remove(struct pci_dev *pdev) 244 { 245 struct mantis_pci *mantis = pci_get_drvdata(pdev); 246 247 if (mantis) { 248 mantis_dvb_exit(mantis); 249 mantis_dma_exit(mantis); 250 mantis_i2c_exit(mantis); 251 mantis_pci_exit(mantis); 252 kfree(mantis); 253 } 254 return; 255 256 } 257 258 static struct pci_device_id hopper_pci_table[] = { 259 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config, 260 NULL), 261 { } 262 }; 263 264 MODULE_DEVICE_TABLE(pci, hopper_pci_table); 265 266 static struct pci_driver hopper_pci_driver = { 267 .name = DRIVER_NAME, 268 .id_table = hopper_pci_table, 269 .probe = hopper_pci_probe, 270 .remove = hopper_pci_remove, 271 }; 272 273 module_pci_driver(hopper_pci_driver); 274 275 MODULE_DESCRIPTION("HOPPER driver"); 276 MODULE_AUTHOR("Manu Abraham"); 277 MODULE_LICENSE("GPL"); 278