V4L/DVB (13795): [Mantis/Hopper] Code overhaul, add Hopper devices into the PCI ID...
[linux-2.6-block.git] / drivers / media / dvb / mantis / hopper_cards.c
CommitLineData
b3b96144
MA
1#include <linux/module.h>
2#include <linux/moduleparam.h>
3#include <linux/kernel.h>
4#include <linux/pci.h>
5#include <asm/irq.h>
6#include <linux/interrupt.h>
7
8#include "dmxdev.h"
9#include "dvbdev.h"
10#include "dvb_demux.h"
11#include "dvb_frontend.h"
12#include "dvb_net.h"
13
14#include "mantis_common.h"
15#include "hopper_vp3028.h"
16#include "mantis_dma.h"
17#include "mantis_dvb.h"
18#include "mantis_uart.h"
19#include "mantis_ioc.h"
20#include "mantis_pci.h"
21#include "mantis_i2c.h"
22#include "mantis_reg.h"
23
24static unsigned int verbose;
25module_param(verbose, int, 0644);
26MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
27
28#define DRIVER_NAME "Hopper"
29
30static char *label[10] = {
31 "DMA",
32 "IRQ-0",
33 "IRQ-1",
34 "OCERR",
35 "PABRT",
36 "RIPRR",
37 "PPERR",
38 "FTRGT",
39 "RISCI",
40 "RACK"
41};
42
43static int devs;
44
45static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
46{
47 u32 stat = 0, mask = 0, lstat = 0, mstat = 0;
48 u32 rst_stat = 0, rst_mask = 0;
49
50 struct mantis_pci *mantis;
51 struct mantis_ca *ca;
52
53 mantis = (struct mantis_pci *) dev_id;
54 if (unlikely(mantis == NULL)) {
55 dprintk(MANTIS_ERROR, 1, "Mantis == NULL");
56 return IRQ_NONE;
57 }
58 ca = mantis->mantis_ca;
59
60 stat = mmread(MANTIS_INT_STAT);
61 mask = mmread(MANTIS_INT_MASK);
62 mstat = lstat = stat & ~MANTIS_INT_RISCSTAT;
63 if (!(stat & mask))
64 return IRQ_NONE;
65
66 rst_mask = MANTIS_GPIF_WRACK |
67 MANTIS_GPIF_OTHERR |
68 MANTIS_SBUF_WSTO |
69 MANTIS_GPIF_EXTIRQ;
70
71 rst_stat = mmread(MANTIS_GPIF_STATUS);
72 rst_stat &= rst_mask;
73 mmwrite(rst_stat, MANTIS_GPIF_STATUS);
74
75 mantis->mantis_int_stat = stat;
76 mantis->mantis_int_mask = mask;
77 dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask);
78 if (stat & MANTIS_INT_RISCEN) {
79 dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]);
80 }
81 if (stat & MANTIS_INT_IRQ0) {
82 dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]);
83 mantis->gpif_status = rst_stat;
84 wake_up(&ca->hif_write_wq);
85 schedule_work(&ca->hif_evm_work);
86 }
87 if (stat & MANTIS_INT_IRQ1) {
88 dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]);
89 schedule_work(&mantis->uart_work);
90 }
91 if (stat & MANTIS_INT_OCERR) {
92 dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]);
93 }
94 if (stat & MANTIS_INT_PABORT) {
95 dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]);
96 }
97 if (stat & MANTIS_INT_RIPERR) {
98 dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]);
99 }
100 if (stat & MANTIS_INT_PPERR) {
101 dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]);
102 }
103 if (stat & MANTIS_INT_FTRGT) {
104 dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]);
105 }
106 if (stat & MANTIS_INT_RISCI) {
107 dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
108 mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
109 tasklet_schedule(&mantis->tasklet);
110 }
111 if (stat & MANTIS_INT_I2CDONE) {
112 dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]);
113 wake_up(&mantis->i2c_wq);
114 }
115 mmwrite(stat, MANTIS_INT_STAT);
116 stat &= ~(MANTIS_INT_RISCEN | MANTIS_INT_I2CDONE |
117 MANTIS_INT_I2CRACK | MANTIS_INT_PCMCIA7 |
118 MANTIS_INT_PCMCIA6 | MANTIS_INT_PCMCIA5 |
119 MANTIS_INT_PCMCIA4 | MANTIS_INT_PCMCIA3 |
120 MANTIS_INT_PCMCIA2 | MANTIS_INT_PCMCIA1 |
121 MANTIS_INT_PCMCIA0 | MANTIS_INT_IRQ1 |
122 MANTIS_INT_IRQ0 | MANTIS_INT_OCERR |
123 MANTIS_INT_PABORT | MANTIS_INT_RIPERR |
124 MANTIS_INT_PPERR | MANTIS_INT_FTRGT |
125 MANTIS_INT_RISCI);
126
127 if (stat)
128 dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask);
129
130 dprintk(MANTIS_DEBUG, 0, "\n");
131 return IRQ_HANDLED;
132}
133
134static int __devinit hopper_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
135{
136 struct mantis_pci *mantis;
137 struct mantis_hwconfig *config;
138 int err = 0;
139
140 mantis = kzalloc(sizeof (struct mantis_pci), GFP_KERNEL);
141 if (mantis == NULL) {
142 printk(KERN_ERR "%s ERROR: Out of memory\n", __func__);
143 err = -ENOMEM;
144 goto fail0;
145 }
146
147 mantis->num = devs;
148 mantis->verbose = verbose;
149 mantis->pdev = pdev;
150 config = (struct mantis_hwconfig *) pci_id->driver_data;
151 config->irq_handler = &hopper_irq_handler;
152 mantis->hwconfig = config;
153
154 err = mantis_pci_init(mantis);
155 if (err) {
156 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err);
157 goto fail1;
158 }
159
160 err = mantis_stream_control(mantis, STREAM_TO_HIF);
161 if (err < 0) {
162 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err);
163 goto fail1;
164 }
165
166 err = mantis_i2c_init(mantis);
167 if (err < 0) {
168 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err);
169 goto fail2;
170 }
171
172 err = mantis_get_mac(mantis);
173 if (err < 0) {
174 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err);
175 goto fail2;
176 }
177
178 err = mantis_dma_init(mantis);
179 if (err < 0) {
180 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err);
181 goto fail3;
182 }
183
184 err = mantis_dvb_init(mantis);
185 if (err < 0) {
186 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err);
187 goto fail4;
188 }
189 devs++;
190
191 return err;
192
193fail5:
194 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB exit! <%d>", err);
195 mantis_dvb_exit(mantis);
196
197fail4:
198 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err);
199 mantis_dma_exit(mantis);
200
201fail3:
202 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err);
203 mantis_i2c_exit(mantis);
204
205fail2:
206 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err);
207 mantis_pci_exit(mantis);
208
209fail1:
210 dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err);
211 kfree(mantis);
212
213fail0:
214 return err;
215}
216
217static void __devexit hopper_pci_remove(struct pci_dev *pdev)
218{
219 struct mantis_pci *mantis = pci_get_drvdata(pdev);
220
221 if (mantis) {
222// mantis_uart_exit(mantis);
223 mantis_dvb_exit(mantis);
224 mantis_dma_exit(mantis);
225 mantis_i2c_exit(mantis);
226 mantis_pci_exit(mantis);
227 kfree(mantis);
228 }
229 return;
230
231}
232
233static struct pci_device_id hopper_pci_table[] = {
234 MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config),
235 { }
236};
237
238static struct pci_driver hopper_pci_driver = {
239 .name = DRIVER_NAME,
240 .id_table = hopper_pci_table,
241 .probe = hopper_pci_probe,
242 .remove = hopper_pci_remove,
243};
244
245static int __devinit hopper_init(void)
246{
247 return pci_register_driver(&hopper_pci_driver);
248}
249
250static void __devexit hopper_exit(void)
251{
252 return pci_unregister_driver(&hopper_pci_driver);
253}
254
255module_init(hopper_init);
256module_exit(hopper_exit);
257
258MODULE_DESCRIPTION("HOPPER driver");
259MODULE_AUTHOR("Manu Abraham");
260MODULE_LICENSE("GPL");