2 Mantis PCI bridge driver
4 Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.com)
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.
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.
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.
22 #include <asm/pgtable.h>
24 #include <linux/kmod.h>
25 #include <linux/vmalloc.h>
26 #include <linux/init.h>
27 #include <linux/device.h>
28 #include "mantis_common.h"
29 #include "mantis_core.h"
32 #include <linux/signal.h>
33 #include <linux/sched.h>
34 #include <linux/interrupt.h>
36 unsigned int verbose
= 1;
37 module_param(verbose
, int, 0644);
38 MODULE_PARM_DESC(verbose
, "verbose startup messages, default is 1 (yes)");
42 #define PCI_VENDOR_ID_MANTIS 0x1822
43 #define PCI_DEVICE_ID_MANTIS_R11 0x4e35
44 #define DRIVER_NAME "Mantis"
46 static struct pci_device_id mantis_pci_table
[] = {
47 { PCI_DEVICE(PCI_VENDOR_ID_MANTIS
, PCI_DEVICE_ID_MANTIS_R11
) },
51 MODULE_DEVICE_TABLE(pci
, mantis_pci_table
);
53 static irqreturn_t
mantis_pci_irq(int irq
, void *dev_id
)
55 u32 stat
= 0, mask
= 0, lstat
= 0, mstat
= 0;
56 u32 rst_stat
= 0, rst_mask
= 0;
58 struct mantis_pci
*mantis
;
61 mantis
= (struct mantis_pci
*) dev_id
;
62 if (unlikely(mantis
== NULL
)) {
63 dprintk(verbose
, MANTIS_ERROR
, 1, "Mantis == NULL");
66 ca
= mantis
->mantis_ca
;
68 stat
= mmread(MANTIS_INT_STAT
);
69 mask
= mmread(MANTIS_INT_MASK
);
70 mstat
= lstat
= stat
& ~MANTIS_INT_RISCSTAT
;
74 rst_mask
= MANTIS_GPIF_WRACK
|
79 rst_stat
= mmread(MANTIS_GPIF_STATUS
);
81 mmwrite(rst_stat
, MANTIS_GPIF_STATUS
);
83 mantis
->mantis_int_stat
= stat
;
84 mantis
->mantis_int_mask
= mask
;
85 dprintk(verbose
, MANTIS_DEBUG
, 0, "=== Interrupts[%04x/%04x]= [", stat
, mask
);
86 if (stat
& MANTIS_INT_RISCEN
) {
87 dprintk(verbose
, MANTIS_DEBUG
, 0, "* DMA enabl *");
89 if (stat
& MANTIS_INT_IRQ0
) {
90 dprintk(verbose
, MANTIS_DEBUG
, 0, "* INT IRQ-0 *");
91 mantis
->gpif_status
= rst_stat
;
92 wake_up(&ca
->hif_write_wq
);
93 schedule_work(&ca
->hif_evm_work
);
95 if (stat
& MANTIS_INT_IRQ1
) {
96 dprintk(verbose
, MANTIS_DEBUG
, 0, "* INT IRQ-1 *");
98 if (stat
& MANTIS_INT_OCERR
) {
99 dprintk(verbose
, MANTIS_DEBUG
, 0, "* INT OCERR *");
101 if (stat
& MANTIS_INT_PABORT
) {
102 dprintk(verbose
, MANTIS_DEBUG
, 0, "* INT PABRT *");
104 if (stat
& MANTIS_INT_RIPERR
) {
105 dprintk(verbose
, MANTIS_DEBUG
, 0, "* INT RIPRR *");
107 if (stat
& MANTIS_INT_PPERR
) {
108 dprintk(verbose
, MANTIS_DEBUG
, 0, "* INT PPERR *");
110 if (stat
& MANTIS_INT_FTRGT
) {
111 dprintk(verbose
, MANTIS_DEBUG
, 0, "* INT FTRGT *");
113 if (stat
& MANTIS_INT_RISCI
) {
114 dprintk(verbose
, MANTIS_DEBUG
, 0, "* INT RISCI *");
115 mantis
->finished_block
= (stat
& MANTIS_INT_RISCSTAT
) >> 28;
116 tasklet_schedule(&mantis
->tasklet
);
118 if (stat
& MANTIS_INT_I2CDONE
) {
119 dprintk(verbose
, MANTIS_DEBUG
, 0, "* I2C DONE *");
120 wake_up(&mantis
->i2c_wq
);
122 mmwrite(stat
, MANTIS_INT_STAT
);
123 stat
&= ~(MANTIS_INT_RISCEN
| MANTIS_INT_I2CDONE
|
124 MANTIS_INT_I2CRACK
| MANTIS_INT_PCMCIA7
|
125 MANTIS_INT_PCMCIA6
| MANTIS_INT_PCMCIA5
|
126 MANTIS_INT_PCMCIA4
| MANTIS_INT_PCMCIA3
|
127 MANTIS_INT_PCMCIA2
| MANTIS_INT_PCMCIA1
|
128 MANTIS_INT_PCMCIA0
| MANTIS_INT_IRQ1
|
129 MANTIS_INT_IRQ0
| MANTIS_INT_OCERR
|
130 MANTIS_INT_PABORT
| MANTIS_INT_RIPERR
|
131 MANTIS_INT_PPERR
| MANTIS_INT_FTRGT
|
135 dprintk(verbose
, MANTIS_DEBUG
, 0, "* Unknown [%04x] *", stat
);
137 dprintk(verbose
, MANTIS_DEBUG
, 0, "] ===\n");
143 static int __devinit
mantis_pci_probe(struct pci_dev
*pdev
,
144 const struct pci_device_id
*mantis_pci_table
)
146 u8 revision
, latency
;
147 struct mantis_pci
*mantis
;
150 mantis
= kmalloc(sizeof (struct mantis_pci
), GFP_KERNEL
);
151 if (mantis
== NULL
) {
152 printk("%s: Out of memory\n", __func__
);
156 memset(mantis
, 0, sizeof (struct mantis_pci
));
160 if (pci_enable_device(pdev
)) {
161 dprintk(verbose
, MANTIS_ERROR
, 1, "Mantis PCI enable failed");
165 mantis
->mantis_addr
= pci_resource_start(pdev
, 0);
166 if (!request_mem_region(pci_resource_start(pdev
, 0),
167 pci_resource_len(pdev
, 0), DRIVER_NAME
)) {
172 mantis
->mantis_mmio
= ioremap(pci_resource_start(pdev
, 0),
173 pci_resource_len(pdev
, 0));
175 if (!mantis
->mantis_mmio
) {
176 dprintk(verbose
, MANTIS_ERROR
, 1, "IO remap failed");
181 // Clear and disable all interrupts at startup
182 // to avoid lockup situations
183 mmwrite(0x00, MANTIS_INT_MASK
);
184 if (request_irq(pdev
->irq
,
190 dprintk(verbose
, MANTIS_ERROR
, 1, "Mantis IRQ reg failed");
194 pci_set_master(pdev
);
195 pci_set_drvdata(pdev
, mantis
);
196 pci_read_config_byte(pdev
, PCI_LATENCY_TIMER
, &latency
);
197 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
198 mantis
->latency
= latency
;
199 mantis
->revision
= revision
;
201 mantis
->subsystem_vendor
= pdev
->subsystem_vendor
;
202 mantis
->subsystem_device
= pdev
->subsystem_device
;
203 init_waitqueue_head(&mantis
->i2c_wq
);
205 mantis_set_direction(mantis
, 0); /* CAM bypass */
208 pci_write_config_byte(pdev
, PCI_LATENCY_TIMER
, 32);
210 dprintk(verbose
, MANTIS_ERROR
, 0,
211 "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n",
212 pdev
->irq
, mantis
->latency
,
213 mantis
->mantis_addr
, mantis
->mantis_mmio
);
215 // No more PCI specific stuff !
216 if (mantis_core_init(mantis
) < 0) {
217 dprintk(verbose
, MANTIS_ERROR
, 1, "Mantis core init failed");
224 // Error conditions ..
226 dprintk(verbose
, MANTIS_DEBUG
, 1, "Err: IO Unmap");
227 if (mantis
->mantis_mmio
)
228 iounmap(mantis
->mantis_mmio
);
230 dprintk(verbose
, MANTIS_DEBUG
, 1, "Err: Release regions");
231 release_mem_region(pci_resource_start(pdev
, 0),
232 pci_resource_len(pdev
, 0));
233 pci_disable_device(pdev
);
235 dprintk(verbose
, MANTIS_DEBUG
, 1, "Err: Free");
238 dprintk(verbose
, MANTIS_DEBUG
, 1, "Err:");
242 static void __devexit
mantis_pci_remove(struct pci_dev
*pdev
)
244 struct mantis_pci
*mantis
= pci_get_drvdata(pdev
);
246 if (mantis
== NULL
) {
247 dprintk(verbose
, MANTIS_ERROR
, 1, "Aeio, Mantis NULL ptr");
250 mantis_core_exit(mantis
);
251 dprintk(verbose
, MANTIS_ERROR
, 1, "Removing -->Mantis irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p",
252 pdev
->irq
, mantis
->latency
, mantis
->mantis_addr
,
253 mantis
->mantis_mmio
);
255 free_irq(pdev
->irq
, mantis
);
256 pci_release_regions(pdev
);
257 if (mantis_dma_exit(mantis
) < 0)
258 dprintk(verbose
, MANTIS_ERROR
, 1, "DMA exit failed");
260 pci_set_drvdata(pdev
, NULL
);
261 pci_disable_device(pdev
);
265 static struct pci_driver mantis_pci_driver
= {
267 .id_table
= mantis_pci_table
,
268 .probe
= mantis_pci_probe
,
269 .remove
= mantis_pci_remove
,
272 static int __devinit
mantis_pci_init(void)
274 return pci_register_driver(&mantis_pci_driver
);
277 static void __devexit
mantis_pci_exit(void)
279 pci_unregister_driver(&mantis_pci_driver
);
282 module_init(mantis_pci_init
);
283 module_exit(mantis_pci_exit
);
285 MODULE_DESCRIPTION("Mantis PCI DTV bridge driver");
286 MODULE_AUTHOR("Manu Abraham");
287 MODULE_LICENSE("GPL");