1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 Mantis PCI bridge driver 4 5 Copyright (C) Manu Abraham (abraham.manu@gmail.com) 6 7 */ 8 9 #include <linux/module.h> 10 #include <linux/kernel.h> 11 #include <linux/pci.h> 12 #include <linux/slab.h> 13 #include <asm/irq.h> 14 #include <linux/interrupt.h> 15 #include <media/rc-map.h> 16 17 #include <media/dmxdev.h> 18 #include <media/dvbdev.h> 19 #include <media/dvb_demux.h> 20 #include <media/dvb_frontend.h> 21 #include <media/dvb_net.h> 22 23 #include "mantis_common.h" 24 25 #include "mantis_vp1033.h" 26 #include "mantis_vp1034.h" 27 #include "mantis_vp1041.h" 28 #include "mantis_vp2033.h" 29 #include "mantis_vp2040.h" 30 #include "mantis_vp3030.h" 31 32 #include "mantis_dma.h" 33 #include "mantis_ca.h" 34 #include "mantis_dvb.h" 35 #include "mantis_uart.h" 36 #include "mantis_ioc.h" 37 #include "mantis_pci.h" 38 #include "mantis_i2c.h" 39 #include "mantis_reg.h" 40 #include "mantis_input.h" 41 42 static unsigned int verbose; 43 module_param(verbose, int, 0644); 44 MODULE_PARM_DESC(verbose, "verbose startup messages, default is 0 (no)"); 45 46 static int devs; 47 48 #define DRIVER_NAME "Mantis" 49 50 static char *label[10] = { 51 "DMA", 52 "IRQ-0", 53 "IRQ-1", 54 "OCERR", 55 "PABRT", 56 "RIPRR", 57 "PPERR", 58 "FTRGT", 59 "RISCI", 60 "RACK" 61 }; 62 63 static irqreturn_t mantis_irq_handler(int irq, void *dev_id) 64 { 65 u32 stat = 0, mask = 0; 66 u32 rst_stat = 0, rst_mask = 0; 67 68 struct mantis_pci *mantis; 69 struct mantis_ca *ca; 70 71 mantis = (struct mantis_pci *) dev_id; 72 if (unlikely(mantis == NULL)) { 73 dprintk(MANTIS_ERROR, 1, "Mantis == NULL"); 74 return IRQ_NONE; 75 } 76 ca = mantis->mantis_ca; 77 78 stat = mmread(MANTIS_INT_STAT); 79 mask = mmread(MANTIS_INT_MASK); 80 if (!(stat & mask)) 81 return IRQ_NONE; 82 83 rst_mask = MANTIS_GPIF_WRACK | 84 MANTIS_GPIF_OTHERR | 85 MANTIS_SBUF_WSTO | 86 MANTIS_GPIF_EXTIRQ; 87 88 rst_stat = mmread(MANTIS_GPIF_STATUS); 89 rst_stat &= rst_mask; 90 mmwrite(rst_stat, MANTIS_GPIF_STATUS); 91 92 mantis->mantis_int_stat = stat; 93 mantis->mantis_int_mask = mask; 94 dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask); 95 if (stat & MANTIS_INT_RISCEN) { 96 dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]); 97 } 98 if (stat & MANTIS_INT_IRQ0) { 99 dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]); 100 mantis->gpif_status = rst_stat; 101 wake_up(&ca->hif_write_wq); 102 schedule_work(&ca->hif_evm_work); 103 } 104 if (stat & MANTIS_INT_IRQ1) { 105 dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); 106 spin_lock(&mantis->intmask_lock); 107 mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ1, 108 MANTIS_INT_MASK); 109 spin_unlock(&mantis->intmask_lock); 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->busy_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 mantis_pci_probe(struct pci_dev *pdev, 156 const struct pci_device_id *pci_id) 157 { 158 struct mantis_pci_drvdata *drvdata; 159 struct mantis_pci *mantis; 160 struct mantis_hwconfig *config; 161 int err; 162 163 mantis = kzalloc(sizeof(*mantis), GFP_KERNEL); 164 if (!mantis) 165 return -ENOMEM; 166 167 drvdata = (void *)pci_id->driver_data; 168 mantis->num = devs; 169 mantis->verbose = verbose; 170 mantis->pdev = pdev; 171 config = drvdata->hwconfig; 172 config->irq_handler = &mantis_irq_handler; 173 mantis->hwconfig = config; 174 mantis->rc_map_name = drvdata->rc_map_name; 175 176 spin_lock_init(&mantis->intmask_lock); 177 178 err = mantis_pci_init(mantis); 179 if (err) { 180 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err); 181 goto err_free_mantis; 182 } 183 184 err = mantis_stream_control(mantis, STREAM_TO_HIF); 185 if (err < 0) { 186 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err); 187 goto err_pci_exit; 188 } 189 190 err = mantis_i2c_init(mantis); 191 if (err < 0) { 192 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err); 193 goto err_pci_exit; 194 } 195 196 err = mantis_get_mac(mantis); 197 if (err < 0) { 198 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err); 199 goto err_i2c_exit; 200 } 201 202 err = mantis_dma_init(mantis); 203 if (err < 0) { 204 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err); 205 goto err_i2c_exit; 206 } 207 208 err = mantis_dvb_init(mantis); 209 if (err < 0) { 210 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err); 211 goto err_dma_exit; 212 } 213 214 err = mantis_input_init(mantis); 215 if (err < 0) { 216 dprintk(MANTIS_ERROR, 1, 217 "ERROR: Mantis DVB initialization failed <%d>", err); 218 goto err_dvb_exit; 219 } 220 221 err = mantis_uart_init(mantis); 222 if (err < 0) { 223 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART initialization failed <%d>", err); 224 goto err_input_exit; 225 } 226 227 devs++; 228 229 return 0; 230 231 err_input_exit: 232 mantis_input_exit(mantis); 233 234 err_dvb_exit: 235 mantis_dvb_exit(mantis); 236 237 err_dma_exit: 238 mantis_dma_exit(mantis); 239 240 err_i2c_exit: 241 mantis_i2c_exit(mantis); 242 243 err_pci_exit: 244 mantis_pci_exit(mantis); 245 246 err_free_mantis: 247 kfree(mantis); 248 249 return err; 250 } 251 252 static void mantis_pci_remove(struct pci_dev *pdev) 253 { 254 struct mantis_pci *mantis = pci_get_drvdata(pdev); 255 256 if (mantis) { 257 258 mantis_uart_exit(mantis); 259 mantis_input_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 const struct pci_device_id mantis_pci_table[] = { 270 MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config, 271 RC_MAP_TECHNISAT_TS35), 272 MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config, 273 NULL), 274 MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_20, &vp1041_config, 275 NULL), 276 MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2040_config, 277 RC_MAP_TERRATEC_CINERGY_C_PCI), 278 MAKE_ENTRY(TERRATEC, CINERGY_S2_PCI_HD, &vp1041_config, 279 RC_MAP_TERRATEC_CINERGY_S2_HD), 280 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1033_DVB_S, &vp1033_config, 281 NULL), 282 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1034_DVB_S, &vp1034_config, 283 NULL), 284 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1041_DVB_S2, &vp1041_config, 285 RC_MAP_TWINHAN_DTV_CAB_CI), 286 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config, 287 RC_MAP_TWINHAN_DTV_CAB_CI), 288 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config, 289 NULL), 290 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config, 291 NULL), 292 { } 293 }; 294 295 MODULE_DEVICE_TABLE(pci, mantis_pci_table); 296 297 static struct pci_driver mantis_pci_driver = { 298 .name = DRIVER_NAME, 299 .id_table = mantis_pci_table, 300 .probe = mantis_pci_probe, 301 .remove = mantis_pci_remove, 302 }; 303 304 module_pci_driver(mantis_pci_driver); 305 306 MODULE_DESCRIPTION("MANTIS driver"); 307 MODULE_AUTHOR("Manu Abraham"); 308 MODULE_LICENSE("GPL"); 309