linux/drivers/media/pci/mantis/hopper_cards.c
<<
>>
Prefs
   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
  45static unsigned int verbose;
  46module_param(verbose, int, 0644);
  47MODULE_PARM_DESC(verbose, "verbose startup messages, default is 0 (no)");
  48
  49#define DRIVER_NAME     "Hopper"
  50
  51static 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
  64static int devs;
  65
  66static 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                schedule_work(&mantis->uart_work);
 110        }
 111        if (stat & MANTIS_INT_OCERR) {
 112                dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]);
 113        }
 114        if (stat & MANTIS_INT_PABORT) {
 115                dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]);
 116        }
 117        if (stat & MANTIS_INT_RIPERR) {
 118                dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]);
 119        }
 120        if (stat & MANTIS_INT_PPERR) {
 121                dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]);
 122        }
 123        if (stat & MANTIS_INT_FTRGT) {
 124                dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]);
 125        }
 126        if (stat & MANTIS_INT_RISCI) {
 127                dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
 128                mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
 129                tasklet_schedule(&mantis->tasklet);
 130        }
 131        if (stat & MANTIS_INT_I2CDONE) {
 132                dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]);
 133                wake_up(&mantis->i2c_wq);
 134        }
 135        mmwrite(stat, MANTIS_INT_STAT);
 136        stat &= ~(MANTIS_INT_RISCEN   | MANTIS_INT_I2CDONE |
 137                  MANTIS_INT_I2CRACK  | MANTIS_INT_PCMCIA7 |
 138                  MANTIS_INT_PCMCIA6  | MANTIS_INT_PCMCIA5 |
 139                  MANTIS_INT_PCMCIA4  | MANTIS_INT_PCMCIA3 |
 140                  MANTIS_INT_PCMCIA2  | MANTIS_INT_PCMCIA1 |
 141                  MANTIS_INT_PCMCIA0  | MANTIS_INT_IRQ1    |
 142                  MANTIS_INT_IRQ0     | MANTIS_INT_OCERR   |
 143                  MANTIS_INT_PABORT   | MANTIS_INT_RIPERR  |
 144                  MANTIS_INT_PPERR    | MANTIS_INT_FTRGT   |
 145                  MANTIS_INT_RISCI);
 146
 147        if (stat)
 148                dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask);
 149
 150        dprintk(MANTIS_DEBUG, 0, "\n");
 151        return IRQ_HANDLED;
 152}
 153
 154static int hopper_pci_probe(struct pci_dev *pdev,
 155                            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
 214fail4:
 215        dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err);
 216        mantis_dma_exit(mantis);
 217
 218fail3:
 219        dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err);
 220        mantis_i2c_exit(mantis);
 221
 222fail2:
 223        dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err);
 224        mantis_pci_exit(mantis);
 225
 226fail1:
 227        dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err);
 228        kfree(mantis);
 229
 230fail0:
 231        return err;
 232}
 233
 234static void 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
 249static struct pci_device_id hopper_pci_table[] = {
 250        MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config),
 251        { }
 252};
 253
 254MODULE_DEVICE_TABLE(pci, hopper_pci_table);
 255
 256static 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
 263static int hopper_init(void)
 264{
 265        return pci_register_driver(&hopper_pci_driver);
 266}
 267
 268static void hopper_exit(void)
 269{
 270        return pci_unregister_driver(&hopper_pci_driver);
 271}
 272
 273module_init(hopper_init);
 274module_exit(hopper_exit);
 275
 276MODULE_DESCRIPTION("HOPPER driver");
 277MODULE_AUTHOR("Manu Abraham");
 278MODULE_LICENSE("GPL");
 279