diff options
Diffstat (limited to 'drivers/media/pci/mantis')
44 files changed, 5358 insertions, 0 deletions
diff --git a/drivers/media/pci/mantis/Kconfig b/drivers/media/pci/mantis/Kconfig new file mode 100644 index 000000000000..a13a50503134 --- /dev/null +++ b/drivers/media/pci/mantis/Kconfig | |||
@@ -0,0 +1,38 @@ | |||
1 | config MANTIS_CORE | ||
2 | tristate "Mantis/Hopper PCI bridge based devices" | ||
3 | depends on PCI && I2C && INPUT && RC_CORE | ||
4 | |||
5 | help | ||
6 | Support for PCI cards based on the Mantis and Hopper PCi bridge. | ||
7 | |||
8 | Say Y if you own such a device and want to use it. | ||
9 | |||
10 | config DVB_MANTIS | ||
11 | tristate "MANTIS based cards" | ||
12 | depends on MANTIS_CORE && DVB_CORE && PCI && I2C | ||
13 | select DVB_MB86A16 if !DVB_FE_CUSTOMISE | ||
14 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | ||
15 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | ||
16 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE | ||
17 | select DVB_STB0899 if !DVB_FE_CUSTOMISE | ||
18 | select DVB_STB6100 if !DVB_FE_CUSTOMISE | ||
19 | select DVB_TDA665x if !DVB_FE_CUSTOMISE | ||
20 | select DVB_TDA10021 if !DVB_FE_CUSTOMISE | ||
21 | select DVB_TDA10023 if !DVB_FE_CUSTOMISE | ||
22 | select DVB_PLL | ||
23 | help | ||
24 | Support for PCI cards based on the Mantis PCI bridge. | ||
25 | Say Y when you have a Mantis based DVB card and want to use it. | ||
26 | |||
27 | If unsure say N. | ||
28 | |||
29 | config DVB_HOPPER | ||
30 | tristate "HOPPER based cards" | ||
31 | depends on MANTIS_CORE && DVB_CORE && PCI && I2C | ||
32 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | ||
33 | select DVB_PLL | ||
34 | help | ||
35 | Support for PCI cards based on the Hopper PCI bridge. | ||
36 | Say Y when you have a Hopper based DVB card and want to use it. | ||
37 | |||
38 | If unsure say N | ||
diff --git a/drivers/media/pci/mantis/Makefile b/drivers/media/pci/mantis/Makefile new file mode 100644 index 000000000000..f715051e4453 --- /dev/null +++ b/drivers/media/pci/mantis/Makefile | |||
@@ -0,0 +1,28 @@ | |||
1 | mantis_core-objs := mantis_ioc.o \ | ||
2 | mantis_uart.o \ | ||
3 | mantis_dma.o \ | ||
4 | mantis_pci.o \ | ||
5 | mantis_i2c.o \ | ||
6 | mantis_dvb.o \ | ||
7 | mantis_evm.o \ | ||
8 | mantis_hif.o \ | ||
9 | mantis_ca.o \ | ||
10 | mantis_pcmcia.o \ | ||
11 | mantis_input.o | ||
12 | |||
13 | mantis-objs := mantis_cards.o \ | ||
14 | mantis_vp1033.o \ | ||
15 | mantis_vp1034.o \ | ||
16 | mantis_vp1041.o \ | ||
17 | mantis_vp2033.o \ | ||
18 | mantis_vp2040.o \ | ||
19 | mantis_vp3030.o | ||
20 | |||
21 | hopper-objs := hopper_cards.o \ | ||
22 | hopper_vp3028.o | ||
23 | |||
24 | obj-$(CONFIG_MANTIS_CORE) += mantis_core.o | ||
25 | obj-$(CONFIG_DVB_MANTIS) += mantis.o | ||
26 | obj-$(CONFIG_DVB_HOPPER) += hopper.o | ||
27 | |||
28 | ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/ | ||
diff --git a/drivers/media/pci/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c new file mode 100644 index 000000000000..cc0251e01077 --- /dev/null +++ b/drivers/media/pci/mantis/hopper_cards.c | |||
@@ -0,0 +1,277 @@ | |||
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 | 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 | |||
154 | static int __devinit hopper_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | ||
155 | { | ||
156 | struct mantis_pci *mantis; | ||
157 | struct mantis_hwconfig *config; | ||
158 | int err = 0; | ||
159 | |||
160 | mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL); | ||
161 | if (mantis == NULL) { | ||
162 | printk(KERN_ERR "%s ERROR: Out of memory\n", __func__); | ||
163 | err = -ENOMEM; | ||
164 | goto fail0; | ||
165 | } | ||
166 | |||
167 | mantis->num = devs; | ||
168 | mantis->verbose = verbose; | ||
169 | mantis->pdev = pdev; | ||
170 | config = (struct mantis_hwconfig *) pci_id->driver_data; | ||
171 | config->irq_handler = &hopper_irq_handler; | ||
172 | mantis->hwconfig = config; | ||
173 | |||
174 | err = mantis_pci_init(mantis); | ||
175 | if (err) { | ||
176 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err); | ||
177 | goto fail1; | ||
178 | } | ||
179 | |||
180 | err = mantis_stream_control(mantis, STREAM_TO_HIF); | ||
181 | if (err < 0) { | ||
182 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err); | ||
183 | goto fail1; | ||
184 | } | ||
185 | |||
186 | err = mantis_i2c_init(mantis); | ||
187 | if (err < 0) { | ||
188 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err); | ||
189 | goto fail2; | ||
190 | } | ||
191 | |||
192 | err = mantis_get_mac(mantis); | ||
193 | if (err < 0) { | ||
194 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err); | ||
195 | goto fail2; | ||
196 | } | ||
197 | |||
198 | err = mantis_dma_init(mantis); | ||
199 | if (err < 0) { | ||
200 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err); | ||
201 | goto fail3; | ||
202 | } | ||
203 | |||
204 | err = mantis_dvb_init(mantis); | ||
205 | if (err < 0) { | ||
206 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err); | ||
207 | goto fail4; | ||
208 | } | ||
209 | devs++; | ||
210 | |||
211 | return err; | ||
212 | |||
213 | fail4: | ||
214 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err); | ||
215 | mantis_dma_exit(mantis); | ||
216 | |||
217 | fail3: | ||
218 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err); | ||
219 | mantis_i2c_exit(mantis); | ||
220 | |||
221 | fail2: | ||
222 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err); | ||
223 | mantis_pci_exit(mantis); | ||
224 | |||
225 | fail1: | ||
226 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err); | ||
227 | kfree(mantis); | ||
228 | |||
229 | fail0: | ||
230 | return err; | ||
231 | } | ||
232 | |||
233 | static void __devexit hopper_pci_remove(struct pci_dev *pdev) | ||
234 | { | ||
235 | struct mantis_pci *mantis = pci_get_drvdata(pdev); | ||
236 | |||
237 | if (mantis) { | ||
238 | mantis_dvb_exit(mantis); | ||
239 | mantis_dma_exit(mantis); | ||
240 | mantis_i2c_exit(mantis); | ||
241 | mantis_pci_exit(mantis); | ||
242 | kfree(mantis); | ||
243 | } | ||
244 | return; | ||
245 | |||
246 | } | ||
247 | |||
248 | static struct pci_device_id hopper_pci_table[] = { | ||
249 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config), | ||
250 | { } | ||
251 | }; | ||
252 | |||
253 | MODULE_DEVICE_TABLE(pci, hopper_pci_table); | ||
254 | |||
255 | static struct pci_driver hopper_pci_driver = { | ||
256 | .name = DRIVER_NAME, | ||
257 | .id_table = hopper_pci_table, | ||
258 | .probe = hopper_pci_probe, | ||
259 | .remove = hopper_pci_remove, | ||
260 | }; | ||
261 | |||
262 | static int __devinit hopper_init(void) | ||
263 | { | ||
264 | return pci_register_driver(&hopper_pci_driver); | ||
265 | } | ||
266 | |||
267 | static void __devexit hopper_exit(void) | ||
268 | { | ||
269 | return pci_unregister_driver(&hopper_pci_driver); | ||
270 | } | ||
271 | |||
272 | module_init(hopper_init); | ||
273 | module_exit(hopper_exit); | ||
274 | |||
275 | MODULE_DESCRIPTION("HOPPER driver"); | ||
276 | MODULE_AUTHOR("Manu Abraham"); | ||
277 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/pci/mantis/hopper_vp3028.c b/drivers/media/pci/mantis/hopper_vp3028.c new file mode 100644 index 000000000000..68a29f8bdf73 --- /dev/null +++ b/drivers/media/pci/mantis/hopper_vp3028.c | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | Hopper VP-3028 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/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "zl10353.h" | ||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_ioc.h" | ||
34 | #include "mantis_dvb.h" | ||
35 | #include "hopper_vp3028.h" | ||
36 | |||
37 | struct zl10353_config hopper_vp3028_config = { | ||
38 | .demod_address = 0x0f, | ||
39 | }; | ||
40 | |||
41 | #define MANTIS_MODEL_NAME "VP-3028" | ||
42 | #define MANTIS_DEV_TYPE "DVB-T" | ||
43 | |||
44 | static int vp3028_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
45 | { | ||
46 | struct i2c_adapter *adapter = &mantis->adapter; | ||
47 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
48 | int err = 0; | ||
49 | |||
50 | mantis_gpio_set_bits(mantis, config->reset, 0); | ||
51 | msleep(100); | ||
52 | err = mantis_frontend_power(mantis, POWER_ON); | ||
53 | msleep(100); | ||
54 | mantis_gpio_set_bits(mantis, config->reset, 1); | ||
55 | |||
56 | err = mantis_frontend_power(mantis, POWER_ON); | ||
57 | if (err == 0) { | ||
58 | msleep(250); | ||
59 | dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)"); | ||
60 | fe = dvb_attach(zl10353_attach, &hopper_vp3028_config, adapter); | ||
61 | |||
62 | if (!fe) | ||
63 | return -1; | ||
64 | } else { | ||
65 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
66 | adapter->name, | ||
67 | err); | ||
68 | |||
69 | return -EIO; | ||
70 | } | ||
71 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | struct mantis_hwconfig vp3028_config = { | ||
77 | .model_name = MANTIS_MODEL_NAME, | ||
78 | .dev_type = MANTIS_DEV_TYPE, | ||
79 | .ts_size = MANTIS_TS_188, | ||
80 | |||
81 | .baud_rate = MANTIS_BAUD_9600, | ||
82 | .parity = MANTIS_PARITY_NONE, | ||
83 | .bytes = 0, | ||
84 | |||
85 | .frontend_init = vp3028_frontend_init, | ||
86 | .power = GPIF_A00, | ||
87 | .reset = GPIF_A03, | ||
88 | }; | ||
diff --git a/drivers/media/pci/mantis/hopper_vp3028.h b/drivers/media/pci/mantis/hopper_vp3028.h new file mode 100644 index 000000000000..57239498bc87 --- /dev/null +++ b/drivers/media/pci/mantis/hopper_vp3028.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | Hopper VP-3028 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 | #ifndef __MANTIS_VP3028_H | ||
22 | #define __MANTIS_VP3028_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_3028_DVB_T 0x0028 | ||
27 | |||
28 | extern struct mantis_hwconfig vp3028_config; | ||
29 | |||
30 | #endif /* __MANTIS_VP3028_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_ca.c b/drivers/media/pci/mantis/mantis_ca.c new file mode 100644 index 000000000000..3d7046909009 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_ca.c | |||
@@ -0,0 +1,209 @@ | |||
1 | /* | ||
2 | Mantis 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/signal.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/sched.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <asm/io.h> | ||
26 | |||
27 | #include "dmxdev.h" | ||
28 | #include "dvbdev.h" | ||
29 | #include "dvb_demux.h" | ||
30 | #include "dvb_frontend.h" | ||
31 | #include "dvb_net.h" | ||
32 | |||
33 | #include "mantis_common.h" | ||
34 | #include "mantis_link.h" | ||
35 | #include "mantis_hif.h" | ||
36 | #include "mantis_reg.h" | ||
37 | |||
38 | #include "mantis_ca.h" | ||
39 | |||
40 | static int mantis_ca_read_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr) | ||
41 | { | ||
42 | struct mantis_ca *ca = en50221->data; | ||
43 | struct mantis_pci *mantis = ca->ca_priv; | ||
44 | |||
45 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Read", slot); | ||
46 | |||
47 | if (slot != 0) | ||
48 | return -EINVAL; | ||
49 | |||
50 | return mantis_hif_read_mem(ca, addr); | ||
51 | } | ||
52 | |||
53 | static int mantis_ca_write_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr, u8 data) | ||
54 | { | ||
55 | struct mantis_ca *ca = en50221->data; | ||
56 | struct mantis_pci *mantis = ca->ca_priv; | ||
57 | |||
58 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Write", slot); | ||
59 | |||
60 | if (slot != 0) | ||
61 | return -EINVAL; | ||
62 | |||
63 | return mantis_hif_write_mem(ca, addr, data); | ||
64 | } | ||
65 | |||
66 | static int mantis_ca_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr) | ||
67 | { | ||
68 | struct mantis_ca *ca = en50221->data; | ||
69 | struct mantis_pci *mantis = ca->ca_priv; | ||
70 | |||
71 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Read", slot); | ||
72 | |||
73 | if (slot != 0) | ||
74 | return -EINVAL; | ||
75 | |||
76 | return mantis_hif_read_iom(ca, addr); | ||
77 | } | ||
78 | |||
79 | static int mantis_ca_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr, u8 data) | ||
80 | { | ||
81 | struct mantis_ca *ca = en50221->data; | ||
82 | struct mantis_pci *mantis = ca->ca_priv; | ||
83 | |||
84 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Write", slot); | ||
85 | |||
86 | if (slot != 0) | ||
87 | return -EINVAL; | ||
88 | |||
89 | return mantis_hif_write_iom(ca, addr, data); | ||
90 | } | ||
91 | |||
92 | static int mantis_ca_slot_reset(struct dvb_ca_en50221 *en50221, int slot) | ||
93 | { | ||
94 | struct mantis_ca *ca = en50221->data; | ||
95 | struct mantis_pci *mantis = ca->ca_priv; | ||
96 | |||
97 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot RESET", slot); | ||
98 | udelay(500); /* Wait.. */ | ||
99 | mmwrite(0xda, MANTIS_PCMCIA_RESET); /* Leading edge assert */ | ||
100 | udelay(500); | ||
101 | mmwrite(0x00, MANTIS_PCMCIA_RESET); /* Trailing edge deassert */ | ||
102 | msleep(1000); | ||
103 | dvb_ca_en50221_camready_irq(&ca->en50221, 0); | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static int mantis_ca_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot) | ||
109 | { | ||
110 | struct mantis_ca *ca = en50221->data; | ||
111 | struct mantis_pci *mantis = ca->ca_priv; | ||
112 | |||
113 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot shutdown", slot); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static int mantis_ts_control(struct dvb_ca_en50221 *en50221, int slot) | ||
119 | { | ||
120 | struct mantis_ca *ca = en50221->data; | ||
121 | struct mantis_pci *mantis = ca->ca_priv; | ||
122 | |||
123 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): TS control", slot); | ||
124 | /* mantis_set_direction(mantis, 1); */ /* Enable TS through CAM */ | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int mantis_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open) | ||
130 | { | ||
131 | struct mantis_ca *ca = en50221->data; | ||
132 | struct mantis_pci *mantis = ca->ca_priv; | ||
133 | |||
134 | dprintk(MANTIS_DEBUG, 1, "Slot(%d): Poll Slot status", slot); | ||
135 | |||
136 | if (ca->slot_state == MODULE_INSERTED) { | ||
137 | dprintk(MANTIS_DEBUG, 1, "CA Module present and ready"); | ||
138 | return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; | ||
139 | } else { | ||
140 | dprintk(MANTIS_DEBUG, 1, "CA Module not present or not ready"); | ||
141 | } | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | int mantis_ca_init(struct mantis_pci *mantis) | ||
147 | { | ||
148 | struct dvb_adapter *dvb_adapter = &mantis->dvb_adapter; | ||
149 | struct mantis_ca *ca; | ||
150 | int ca_flags = 0, result; | ||
151 | |||
152 | dprintk(MANTIS_DEBUG, 1, "Initializing Mantis CA"); | ||
153 | ca = kzalloc(sizeof(struct mantis_ca), GFP_KERNEL); | ||
154 | if (!ca) { | ||
155 | dprintk(MANTIS_ERROR, 1, "Out of memory!, exiting .."); | ||
156 | result = -ENOMEM; | ||
157 | goto err; | ||
158 | } | ||
159 | |||
160 | ca->ca_priv = mantis; | ||
161 | mantis->mantis_ca = ca; | ||
162 | ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE; | ||
163 | /* register CA interface */ | ||
164 | ca->en50221.owner = THIS_MODULE; | ||
165 | ca->en50221.read_attribute_mem = mantis_ca_read_attr_mem; | ||
166 | ca->en50221.write_attribute_mem = mantis_ca_write_attr_mem; | ||
167 | ca->en50221.read_cam_control = mantis_ca_read_cam_ctl; | ||
168 | ca->en50221.write_cam_control = mantis_ca_write_cam_ctl; | ||
169 | ca->en50221.slot_reset = mantis_ca_slot_reset; | ||
170 | ca->en50221.slot_shutdown = mantis_ca_slot_shutdown; | ||
171 | ca->en50221.slot_ts_enable = mantis_ts_control; | ||
172 | ca->en50221.poll_slot_status = mantis_slot_status; | ||
173 | ca->en50221.data = ca; | ||
174 | |||
175 | mutex_init(&ca->ca_lock); | ||
176 | |||
177 | init_waitqueue_head(&ca->hif_data_wq); | ||
178 | init_waitqueue_head(&ca->hif_opdone_wq); | ||
179 | init_waitqueue_head(&ca->hif_write_wq); | ||
180 | |||
181 | dprintk(MANTIS_ERROR, 1, "Registering EN50221 device"); | ||
182 | result = dvb_ca_en50221_init(dvb_adapter, &ca->en50221, ca_flags, 1); | ||
183 | if (result != 0) { | ||
184 | dprintk(MANTIS_ERROR, 1, "EN50221: Initialization failed <%d>", result); | ||
185 | goto err; | ||
186 | } | ||
187 | dprintk(MANTIS_ERROR, 1, "Registered EN50221 device"); | ||
188 | mantis_evmgr_init(ca); | ||
189 | return 0; | ||
190 | err: | ||
191 | kfree(ca); | ||
192 | return result; | ||
193 | } | ||
194 | EXPORT_SYMBOL_GPL(mantis_ca_init); | ||
195 | |||
196 | void mantis_ca_exit(struct mantis_pci *mantis) | ||
197 | { | ||
198 | struct mantis_ca *ca = mantis->mantis_ca; | ||
199 | |||
200 | dprintk(MANTIS_DEBUG, 1, "Mantis CA exit"); | ||
201 | |||
202 | mantis_evmgr_exit(ca); | ||
203 | dprintk(MANTIS_ERROR, 1, "Unregistering EN50221 device"); | ||
204 | if (ca) | ||
205 | dvb_ca_en50221_release(&ca->en50221); | ||
206 | |||
207 | kfree(ca); | ||
208 | } | ||
209 | EXPORT_SYMBOL_GPL(mantis_ca_exit); | ||
diff --git a/drivers/media/pci/mantis/mantis_ca.h b/drivers/media/pci/mantis/mantis_ca.h new file mode 100644 index 000000000000..dc63e55f7eca --- /dev/null +++ b/drivers/media/pci/mantis/mantis_ca.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | Mantis 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 | #ifndef __MANTIS_CA_H | ||
22 | #define __MANTIS_CA_H | ||
23 | |||
24 | extern int mantis_ca_init(struct mantis_pci *mantis); | ||
25 | extern void mantis_ca_exit(struct mantis_pci *mantis); | ||
26 | |||
27 | #endif /* __MANTIS_CA_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c new file mode 100644 index 000000000000..0207d1f064e0 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_cards.c | |||
@@ -0,0 +1,307 @@ | |||
1 | /* | ||
2 | Mantis 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 | |||
37 | #include "mantis_vp1033.h" | ||
38 | #include "mantis_vp1034.h" | ||
39 | #include "mantis_vp1041.h" | ||
40 | #include "mantis_vp2033.h" | ||
41 | #include "mantis_vp2040.h" | ||
42 | #include "mantis_vp3030.h" | ||
43 | |||
44 | #include "mantis_dma.h" | ||
45 | #include "mantis_ca.h" | ||
46 | #include "mantis_dvb.h" | ||
47 | #include "mantis_uart.h" | ||
48 | #include "mantis_ioc.h" | ||
49 | #include "mantis_pci.h" | ||
50 | #include "mantis_i2c.h" | ||
51 | #include "mantis_reg.h" | ||
52 | |||
53 | static unsigned int verbose; | ||
54 | module_param(verbose, int, 0644); | ||
55 | MODULE_PARM_DESC(verbose, "verbose startup messages, default is 0 (no)"); | ||
56 | |||
57 | static int devs; | ||
58 | |||
59 | #define DRIVER_NAME "Mantis" | ||
60 | |||
61 | static char *label[10] = { | ||
62 | "DMA", | ||
63 | "IRQ-0", | ||
64 | "IRQ-1", | ||
65 | "OCERR", | ||
66 | "PABRT", | ||
67 | "RIPRR", | ||
68 | "PPERR", | ||
69 | "FTRGT", | ||
70 | "RISCI", | ||
71 | "RACK" | ||
72 | }; | ||
73 | |||
74 | static irqreturn_t mantis_irq_handler(int irq, void *dev_id) | ||
75 | { | ||
76 | u32 stat = 0, mask = 0; | ||
77 | u32 rst_stat = 0, rst_mask = 0; | ||
78 | |||
79 | struct mantis_pci *mantis; | ||
80 | struct mantis_ca *ca; | ||
81 | |||
82 | mantis = (struct mantis_pci *) dev_id; | ||
83 | if (unlikely(mantis == NULL)) { | ||
84 | dprintk(MANTIS_ERROR, 1, "Mantis == NULL"); | ||
85 | return IRQ_NONE; | ||
86 | } | ||
87 | ca = mantis->mantis_ca; | ||
88 | |||
89 | stat = mmread(MANTIS_INT_STAT); | ||
90 | mask = mmread(MANTIS_INT_MASK); | ||
91 | if (!(stat & mask)) | ||
92 | return IRQ_NONE; | ||
93 | |||
94 | rst_mask = MANTIS_GPIF_WRACK | | ||
95 | MANTIS_GPIF_OTHERR | | ||
96 | MANTIS_SBUF_WSTO | | ||
97 | MANTIS_GPIF_EXTIRQ; | ||
98 | |||
99 | rst_stat = mmread(MANTIS_GPIF_STATUS); | ||
100 | rst_stat &= rst_mask; | ||
101 | mmwrite(rst_stat, MANTIS_GPIF_STATUS); | ||
102 | |||
103 | mantis->mantis_int_stat = stat; | ||
104 | mantis->mantis_int_mask = mask; | ||
105 | dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask); | ||
106 | if (stat & MANTIS_INT_RISCEN) { | ||
107 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]); | ||
108 | } | ||
109 | if (stat & MANTIS_INT_IRQ0) { | ||
110 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]); | ||
111 | mantis->gpif_status = rst_stat; | ||
112 | wake_up(&ca->hif_write_wq); | ||
113 | schedule_work(&ca->hif_evm_work); | ||
114 | } | ||
115 | if (stat & MANTIS_INT_IRQ1) { | ||
116 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]); | ||
117 | schedule_work(&mantis->uart_work); | ||
118 | } | ||
119 | if (stat & MANTIS_INT_OCERR) { | ||
120 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]); | ||
121 | } | ||
122 | if (stat & MANTIS_INT_PABORT) { | ||
123 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]); | ||
124 | } | ||
125 | if (stat & MANTIS_INT_RIPERR) { | ||
126 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]); | ||
127 | } | ||
128 | if (stat & MANTIS_INT_PPERR) { | ||
129 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]); | ||
130 | } | ||
131 | if (stat & MANTIS_INT_FTRGT) { | ||
132 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]); | ||
133 | } | ||
134 | if (stat & MANTIS_INT_RISCI) { | ||
135 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); | ||
136 | mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28; | ||
137 | tasklet_schedule(&mantis->tasklet); | ||
138 | } | ||
139 | if (stat & MANTIS_INT_I2CDONE) { | ||
140 | dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]); | ||
141 | wake_up(&mantis->i2c_wq); | ||
142 | } | ||
143 | mmwrite(stat, MANTIS_INT_STAT); | ||
144 | stat &= ~(MANTIS_INT_RISCEN | MANTIS_INT_I2CDONE | | ||
145 | MANTIS_INT_I2CRACK | MANTIS_INT_PCMCIA7 | | ||
146 | MANTIS_INT_PCMCIA6 | MANTIS_INT_PCMCIA5 | | ||
147 | MANTIS_INT_PCMCIA4 | MANTIS_INT_PCMCIA3 | | ||
148 | MANTIS_INT_PCMCIA2 | MANTIS_INT_PCMCIA1 | | ||
149 | MANTIS_INT_PCMCIA0 | MANTIS_INT_IRQ1 | | ||
150 | MANTIS_INT_IRQ0 | MANTIS_INT_OCERR | | ||
151 | MANTIS_INT_PABORT | MANTIS_INT_RIPERR | | ||
152 | MANTIS_INT_PPERR | MANTIS_INT_FTRGT | | ||
153 | MANTIS_INT_RISCI); | ||
154 | |||
155 | if (stat) | ||
156 | dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask); | ||
157 | |||
158 | dprintk(MANTIS_DEBUG, 0, "\n"); | ||
159 | return IRQ_HANDLED; | ||
160 | } | ||
161 | |||
162 | static int __devinit mantis_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | ||
163 | { | ||
164 | struct mantis_pci *mantis; | ||
165 | struct mantis_hwconfig *config; | ||
166 | int err = 0; | ||
167 | |||
168 | mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL); | ||
169 | if (mantis == NULL) { | ||
170 | printk(KERN_ERR "%s ERROR: Out of memory\n", __func__); | ||
171 | err = -ENOMEM; | ||
172 | goto fail0; | ||
173 | } | ||
174 | |||
175 | mantis->num = devs; | ||
176 | mantis->verbose = verbose; | ||
177 | mantis->pdev = pdev; | ||
178 | config = (struct mantis_hwconfig *) pci_id->driver_data; | ||
179 | config->irq_handler = &mantis_irq_handler; | ||
180 | mantis->hwconfig = config; | ||
181 | |||
182 | err = mantis_pci_init(mantis); | ||
183 | if (err) { | ||
184 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err); | ||
185 | goto fail1; | ||
186 | } | ||
187 | |||
188 | err = mantis_stream_control(mantis, STREAM_TO_HIF); | ||
189 | if (err < 0) { | ||
190 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err); | ||
191 | goto fail1; | ||
192 | } | ||
193 | |||
194 | err = mantis_i2c_init(mantis); | ||
195 | if (err < 0) { | ||
196 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err); | ||
197 | goto fail2; | ||
198 | } | ||
199 | |||
200 | err = mantis_get_mac(mantis); | ||
201 | if (err < 0) { | ||
202 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err); | ||
203 | goto fail2; | ||
204 | } | ||
205 | |||
206 | err = mantis_dma_init(mantis); | ||
207 | if (err < 0) { | ||
208 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err); | ||
209 | goto fail3; | ||
210 | } | ||
211 | |||
212 | err = mantis_dvb_init(mantis); | ||
213 | if (err < 0) { | ||
214 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err); | ||
215 | goto fail4; | ||
216 | } | ||
217 | err = mantis_uart_init(mantis); | ||
218 | if (err < 0) { | ||
219 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART initialization failed <%d>", err); | ||
220 | goto fail6; | ||
221 | } | ||
222 | |||
223 | devs++; | ||
224 | |||
225 | return err; | ||
226 | |||
227 | |||
228 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART exit! <%d>", err); | ||
229 | mantis_uart_exit(mantis); | ||
230 | |||
231 | fail6: | ||
232 | fail4: | ||
233 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err); | ||
234 | mantis_dma_exit(mantis); | ||
235 | |||
236 | fail3: | ||
237 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err); | ||
238 | mantis_i2c_exit(mantis); | ||
239 | |||
240 | fail2: | ||
241 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err); | ||
242 | mantis_pci_exit(mantis); | ||
243 | |||
244 | fail1: | ||
245 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err); | ||
246 | kfree(mantis); | ||
247 | |||
248 | fail0: | ||
249 | return err; | ||
250 | } | ||
251 | |||
252 | static void __devexit 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_dvb_exit(mantis); | ||
260 | mantis_dma_exit(mantis); | ||
261 | mantis_i2c_exit(mantis); | ||
262 | mantis_pci_exit(mantis); | ||
263 | kfree(mantis); | ||
264 | } | ||
265 | return; | ||
266 | } | ||
267 | |||
268 | static struct pci_device_id mantis_pci_table[] = { | ||
269 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1033_DVB_S, &vp1033_config), | ||
270 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1034_DVB_S, &vp1034_config), | ||
271 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1041_DVB_S2, &vp1041_config), | ||
272 | MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config), | ||
273 | MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_20, &vp1041_config), | ||
274 | MAKE_ENTRY(TERRATEC, CINERGY_S2_PCI_HD, &vp1041_config), | ||
275 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config), | ||
276 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config), | ||
277 | MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config), | ||
278 | MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2040_config), | ||
279 | MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config), | ||
280 | { } | ||
281 | }; | ||
282 | |||
283 | MODULE_DEVICE_TABLE(pci, mantis_pci_table); | ||
284 | |||
285 | static struct pci_driver mantis_pci_driver = { | ||
286 | .name = DRIVER_NAME, | ||
287 | .id_table = mantis_pci_table, | ||
288 | .probe = mantis_pci_probe, | ||
289 | .remove = mantis_pci_remove, | ||
290 | }; | ||
291 | |||
292 | static int __devinit mantis_init(void) | ||
293 | { | ||
294 | return pci_register_driver(&mantis_pci_driver); | ||
295 | } | ||
296 | |||
297 | static void __devexit mantis_exit(void) | ||
298 | { | ||
299 | return pci_unregister_driver(&mantis_pci_driver); | ||
300 | } | ||
301 | |||
302 | module_init(mantis_init); | ||
303 | module_exit(mantis_exit); | ||
304 | |||
305 | MODULE_DESCRIPTION("MANTIS driver"); | ||
306 | MODULE_AUTHOR("Manu Abraham"); | ||
307 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/pci/mantis/mantis_common.h b/drivers/media/pci/mantis/mantis_common.h new file mode 100644 index 000000000000..f2410cf0a6bf --- /dev/null +++ b/drivers/media/pci/mantis/mantis_common.h | |||
@@ -0,0 +1,179 @@ | |||
1 | /* | ||
2 | Mantis 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 | #ifndef __MANTIS_COMMON_H | ||
22 | #define __MANTIS_COMMON_H | ||
23 | |||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/mutex.h> | ||
26 | #include <linux/workqueue.h> | ||
27 | |||
28 | #include "mantis_uart.h" | ||
29 | |||
30 | #include "mantis_link.h" | ||
31 | |||
32 | #define MANTIS_ERROR 0 | ||
33 | #define MANTIS_NOTICE 1 | ||
34 | #define MANTIS_INFO 2 | ||
35 | #define MANTIS_DEBUG 3 | ||
36 | #define MANTIS_TMG 9 | ||
37 | |||
38 | #define dprintk(y, z, format, arg...) do { \ | ||
39 | if (z) { \ | ||
40 | if ((mantis->verbose > MANTIS_ERROR) && (mantis->verbose > y)) \ | ||
41 | printk(KERN_ERR "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
42 | else if ((mantis->verbose > MANTIS_NOTICE) && (mantis->verbose > y)) \ | ||
43 | printk(KERN_NOTICE "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
44 | else if ((mantis->verbose > MANTIS_INFO) && (mantis->verbose > y)) \ | ||
45 | printk(KERN_INFO "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
46 | else if ((mantis->verbose > MANTIS_DEBUG) && (mantis->verbose > y)) \ | ||
47 | printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
48 | else if ((mantis->verbose > MANTIS_TMG) && (mantis->verbose > y)) \ | ||
49 | printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \ | ||
50 | } else { \ | ||
51 | if (mantis->verbose > y) \ | ||
52 | printk(format , ##arg); \ | ||
53 | } \ | ||
54 | } while(0) | ||
55 | |||
56 | #define mwrite(dat, addr) writel((dat), addr) | ||
57 | #define mread(addr) readl(addr) | ||
58 | |||
59 | #define mmwrite(dat, addr) mwrite((dat), (mantis->mmio + (addr))) | ||
60 | #define mmread(addr) mread(mantis->mmio + (addr)) | ||
61 | |||
62 | #define MANTIS_TS_188 0 | ||
63 | #define MANTIS_TS_204 1 | ||
64 | |||
65 | #define TWINHAN_TECHNOLOGIES 0x1822 | ||
66 | #define MANTIS 0x4e35 | ||
67 | |||
68 | #define TECHNISAT 0x1ae4 | ||
69 | #define TERRATEC 0x153b | ||
70 | |||
71 | #define MAKE_ENTRY(__subven, __subdev, __configptr) { \ | ||
72 | .vendor = TWINHAN_TECHNOLOGIES, \ | ||
73 | .device = MANTIS, \ | ||
74 | .subvendor = (__subven), \ | ||
75 | .subdevice = (__subdev), \ | ||
76 | .driver_data = (unsigned long) (__configptr) \ | ||
77 | } | ||
78 | |||
79 | enum mantis_i2c_mode { | ||
80 | MANTIS_PAGE_MODE = 0, | ||
81 | MANTIS_BYTE_MODE, | ||
82 | }; | ||
83 | |||
84 | struct mantis_pci; | ||
85 | |||
86 | struct mantis_hwconfig { | ||
87 | char *model_name; | ||
88 | char *dev_type; | ||
89 | u32 ts_size; | ||
90 | |||
91 | enum mantis_baud baud_rate; | ||
92 | enum mantis_parity parity; | ||
93 | u32 bytes; | ||
94 | |||
95 | irqreturn_t (*irq_handler)(int irq, void *dev_id); | ||
96 | int (*frontend_init)(struct mantis_pci *mantis, struct dvb_frontend *fe); | ||
97 | |||
98 | u8 power; | ||
99 | u8 reset; | ||
100 | |||
101 | enum mantis_i2c_mode i2c_mode; | ||
102 | }; | ||
103 | |||
104 | struct mantis_pci { | ||
105 | unsigned int verbose; | ||
106 | |||
107 | /* PCI stuff */ | ||
108 | u16 vendor_id; | ||
109 | u16 device_id; | ||
110 | u16 subsystem_vendor; | ||
111 | u16 subsystem_device; | ||
112 | |||
113 | u8 latency; | ||
114 | |||
115 | struct pci_dev *pdev; | ||
116 | |||
117 | unsigned long mantis_addr; | ||
118 | void __iomem *mmio; | ||
119 | |||
120 | u8 irq; | ||
121 | u8 revision; | ||
122 | |||
123 | unsigned int num; | ||
124 | |||
125 | /* RISC Core */ | ||
126 | u32 busy_block; | ||
127 | u32 last_block; | ||
128 | u8 *buf_cpu; | ||
129 | dma_addr_t buf_dma; | ||
130 | u32 *risc_cpu; | ||
131 | dma_addr_t risc_dma; | ||
132 | |||
133 | struct tasklet_struct tasklet; | ||
134 | |||
135 | struct i2c_adapter adapter; | ||
136 | int i2c_rc; | ||
137 | wait_queue_head_t i2c_wq; | ||
138 | struct mutex i2c_lock; | ||
139 | |||
140 | /* DVB stuff */ | ||
141 | struct dvb_adapter dvb_adapter; | ||
142 | struct dvb_frontend *fe; | ||
143 | struct dvb_demux demux; | ||
144 | struct dmxdev dmxdev; | ||
145 | struct dmx_frontend fe_hw; | ||
146 | struct dmx_frontend fe_mem; | ||
147 | struct dvb_net dvbnet; | ||
148 | |||
149 | u8 feeds; | ||
150 | |||
151 | struct mantis_hwconfig *hwconfig; | ||
152 | |||
153 | u32 mantis_int_stat; | ||
154 | u32 mantis_int_mask; | ||
155 | |||
156 | /* board specific */ | ||
157 | u8 mac_address[8]; | ||
158 | u32 sub_vendor_id; | ||
159 | u32 sub_device_id; | ||
160 | |||
161 | /* A12 A13 A14 */ | ||
162 | u32 gpio_status; | ||
163 | |||
164 | u32 gpif_status; | ||
165 | |||
166 | struct mantis_ca *mantis_ca; | ||
167 | |||
168 | wait_queue_head_t uart_wq; | ||
169 | struct work_struct uart_work; | ||
170 | spinlock_t uart_lock; | ||
171 | |||
172 | struct rc_dev *rc; | ||
173 | char input_name[80]; | ||
174 | char input_phys[80]; | ||
175 | }; | ||
176 | |||
177 | #define MANTIS_HIF_STATUS (mantis->gpio_status) | ||
178 | |||
179 | #endif /* __MANTIS_COMMON_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_core.c b/drivers/media/pci/mantis/mantis_core.c new file mode 100644 index 000000000000..684d9061fe2a --- /dev/null +++ b/drivers/media/pci/mantis/mantis_core.c | |||
@@ -0,0 +1,235 @@ | |||
1 | /* | ||
2 | Mantis 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 "mantis_common.h" | ||
22 | #include "mantis_core.h" | ||
23 | #include "mantis_vp1033.h" | ||
24 | #include "mantis_vp1034.h" | ||
25 | #include "mantis_vp1041.h" | ||
26 | #include "mantis_vp2033.h" | ||
27 | #include "mantis_vp2040.h" | ||
28 | #include "mantis_vp3030.h" | ||
29 | |||
30 | static int read_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length) | ||
31 | { | ||
32 | int err; | ||
33 | struct i2c_msg msg[] = { | ||
34 | { | ||
35 | .addr = 0x50, | ||
36 | .flags = 0, | ||
37 | .buf = data, | ||
38 | .len = 1 | ||
39 | }, { | ||
40 | .addr = 0x50, | ||
41 | .flags = I2C_M_RD, | ||
42 | .buf = data, | ||
43 | .len = length | ||
44 | }, | ||
45 | }; | ||
46 | |||
47 | err = i2c_transfer(&mantis->adapter, msg, 2); | ||
48 | if (err < 0) { | ||
49 | dprintk(verbose, MANTIS_ERROR, 1, | ||
50 | "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >", | ||
51 | err, data[0], data[1]); | ||
52 | |||
53 | return err; | ||
54 | } | ||
55 | |||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static int write_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length) | ||
60 | { | ||
61 | int err; | ||
62 | |||
63 | struct i2c_msg msg = { | ||
64 | .addr = 0x50, | ||
65 | .flags = 0, | ||
66 | .buf = data, | ||
67 | .len = length | ||
68 | }; | ||
69 | |||
70 | err = i2c_transfer(&mantis->adapter, &msg, 1); | ||
71 | if (err < 0) { | ||
72 | dprintk(verbose, MANTIS_ERROR, 1, | ||
73 | "ERROR: i2c write: < err=%i length=0x%02x d0=0x%02x, d1=0x%02x >", | ||
74 | err, length, data[0], data[1]); | ||
75 | |||
76 | return err; | ||
77 | } | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static int get_mac_address(struct mantis_pci *mantis) | ||
83 | { | ||
84 | int err; | ||
85 | |||
86 | mantis->mac_address[0] = 0x08; | ||
87 | err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6); | ||
88 | if (err < 0) { | ||
89 | dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error"); | ||
90 | |||
91 | return err; | ||
92 | } | ||
93 | dprintk(verbose, MANTIS_ERROR, 0, | ||
94 | " MAC Address=[%pM]\n", mantis->mac_address); | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | #define MANTIS_MODEL_UNKNOWN "UNKNOWN" | ||
100 | #define MANTIS_DEV_UNKNOWN "UNKNOWN" | ||
101 | |||
102 | struct mantis_hwconfig unknown_device = { | ||
103 | .model_name = MANTIS_MODEL_UNKNOWN, | ||
104 | .dev_type = MANTIS_DEV_UNKNOWN, | ||
105 | }; | ||
106 | |||
107 | static void mantis_load_config(struct mantis_pci *mantis) | ||
108 | { | ||
109 | switch (mantis->subsystem_device) { | ||
110 | case MANTIS_VP_1033_DVB_S: /* VP-1033 */ | ||
111 | mantis->hwconfig = &vp1033_mantis_config; | ||
112 | break; | ||
113 | case MANTIS_VP_1034_DVB_S: /* VP-1034 */ | ||
114 | mantis->hwconfig = &vp1034_mantis_config; | ||
115 | break; | ||
116 | case MANTIS_VP_1041_DVB_S2: /* VP-1041 */ | ||
117 | case TECHNISAT_SKYSTAR_HD2: | ||
118 | mantis->hwconfig = &vp1041_mantis_config; | ||
119 | break; | ||
120 | case MANTIS_VP_2033_DVB_C: /* VP-2033 */ | ||
121 | mantis->hwconfig = &vp2033_mantis_config; | ||
122 | break; | ||
123 | case MANTIS_VP_2040_DVB_C: /* VP-2040 */ | ||
124 | case CINERGY_C: /* VP-2040 clone */ | ||
125 | case TECHNISAT_CABLESTAR_HD2: | ||
126 | mantis->hwconfig = &vp2040_mantis_config; | ||
127 | break; | ||
128 | case MANTIS_VP_3030_DVB_T: /* VP-3030 */ | ||
129 | mantis->hwconfig = &vp3030_mantis_config; | ||
130 | break; | ||
131 | default: | ||
132 | mantis->hwconfig = &unknown_device; | ||
133 | break; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | int mantis_core_init(struct mantis_pci *mantis) | ||
138 | { | ||
139 | int err = 0; | ||
140 | |||
141 | mantis_load_config(mantis); | ||
142 | dprintk(verbose, MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n", | ||
143 | mantis->hwconfig->model_name, mantis->hwconfig->dev_type, | ||
144 | mantis->pdev->bus->number, PCI_SLOT(mantis->pdev->devfn), PCI_FUNC(mantis->pdev->devfn)); | ||
145 | dprintk(verbose, MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ", | ||
146 | mantis->revision, | ||
147 | mantis->subsystem_vendor, mantis->subsystem_device); | ||
148 | dprintk(verbose, MANTIS_ERROR, 0, | ||
149 | "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n", | ||
150 | mantis->pdev->irq, mantis->latency, | ||
151 | mantis->mantis_addr, mantis->mantis_mmio); | ||
152 | |||
153 | err = mantis_i2c_init(mantis); | ||
154 | if (err < 0) { | ||
155 | dprintk(verbose, MANTIS_ERROR, 1, "Mantis I2C init failed"); | ||
156 | return err; | ||
157 | } | ||
158 | err = get_mac_address(mantis); | ||
159 | if (err < 0) { | ||
160 | dprintk(verbose, MANTIS_ERROR, 1, "get MAC address failed"); | ||
161 | return err; | ||
162 | } | ||
163 | err = mantis_dma_init(mantis); | ||
164 | if (err < 0) { | ||
165 | dprintk(verbose, MANTIS_ERROR, 1, "Mantis DMA init failed"); | ||
166 | return err; | ||
167 | } | ||
168 | err = mantis_dvb_init(mantis); | ||
169 | if (err < 0) { | ||
170 | dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed"); | ||
171 | return err; | ||
172 | } | ||
173 | err = mantis_uart_init(mantis); | ||
174 | if (err < 0) { | ||
175 | dprintk(verbose, MANTIS_DEBUG, 1, "Mantis UART init failed"); | ||
176 | return err; | ||
177 | } | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | int mantis_core_exit(struct mantis_pci *mantis) | ||
183 | { | ||
184 | mantis_dma_stop(mantis); | ||
185 | dprintk(verbose, MANTIS_ERROR, 1, "DMA engine stopping"); | ||
186 | |||
187 | mantis_uart_exit(mantis); | ||
188 | dprintk(verbose, MANTIS_ERROR, 1, "UART exit failed"); | ||
189 | |||
190 | if (mantis_dma_exit(mantis) < 0) | ||
191 | dprintk(verbose, MANTIS_ERROR, 1, "DMA exit failed"); | ||
192 | if (mantis_dvb_exit(mantis) < 0) | ||
193 | dprintk(verbose, MANTIS_ERROR, 1, "DVB exit failed"); | ||
194 | if (mantis_i2c_exit(mantis) < 0) | ||
195 | dprintk(verbose, MANTIS_ERROR, 1, "I2C adapter delete.. failed"); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | /* Turn the given bit on or off. */ | ||
201 | void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value) | ||
202 | { | ||
203 | u32 cur; | ||
204 | |||
205 | cur = mmread(MANTIS_GPIF_ADDR); | ||
206 | if (value) | ||
207 | mantis->gpio_status = cur | (1 << bitpos); | ||
208 | else | ||
209 | mantis->gpio_status = cur & (~(1 << bitpos)); | ||
210 | |||
211 | mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR); | ||
212 | mmwrite(0x00, MANTIS_GPIF_DOUT); | ||
213 | udelay(100); | ||
214 | } | ||
215 | |||
216 | /* direction = 0 , no CI passthrough ; 1 , CI passthrough */ | ||
217 | void mantis_set_direction(struct mantis_pci *mantis, int direction) | ||
218 | { | ||
219 | u32 reg; | ||
220 | |||
221 | reg = mmread(0x28); | ||
222 | dprintk(verbose, MANTIS_DEBUG, 1, "TS direction setup"); | ||
223 | if (direction == 0x01) { | ||
224 | /* to CI */ | ||
225 | reg |= 0x04; | ||
226 | mmwrite(reg, 0x28); | ||
227 | reg &= 0xff - 0x04; | ||
228 | mmwrite(reg, 0x28); | ||
229 | } else { | ||
230 | reg &= 0xff - 0x04; | ||
231 | mmwrite(reg, 0x28); | ||
232 | reg |= 0x04; | ||
233 | mmwrite(reg, 0x28); | ||
234 | } | ||
235 | } | ||
diff --git a/drivers/media/pci/mantis/mantis_core.h b/drivers/media/pci/mantis/mantis_core.h new file mode 100644 index 000000000000..833ee42e694e --- /dev/null +++ b/drivers/media/pci/mantis/mantis_core.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | Mantis 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 | #ifndef __MANTIS_CORE_H | ||
22 | #define __MANTIS_CORE_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | |||
27 | #define FE_TYPE_SAT 0 | ||
28 | #define FE_TYPE_CAB 1 | ||
29 | #define FE_TYPE_TER 2 | ||
30 | |||
31 | #define FE_TYPE_TS204 0 | ||
32 | #define FE_TYPE_TS188 1 | ||
33 | |||
34 | |||
35 | struct vendorname { | ||
36 | u8 *sub_vendor_name; | ||
37 | u32 sub_vendor_id; | ||
38 | }; | ||
39 | |||
40 | struct devicetype { | ||
41 | u8 *sub_device_name; | ||
42 | u32 sub_device_id; | ||
43 | u8 device_type; | ||
44 | u32 type_flags; | ||
45 | }; | ||
46 | |||
47 | |||
48 | extern int mantis_dma_init(struct mantis_pci *mantis); | ||
49 | extern int mantis_dma_exit(struct mantis_pci *mantis); | ||
50 | extern void mantis_dma_start(struct mantis_pci *mantis); | ||
51 | extern void mantis_dma_stop(struct mantis_pci *mantis); | ||
52 | extern int mantis_i2c_init(struct mantis_pci *mantis); | ||
53 | extern int mantis_i2c_exit(struct mantis_pci *mantis); | ||
54 | extern int mantis_core_init(struct mantis_pci *mantis); | ||
55 | extern int mantis_core_exit(struct mantis_pci *mantis); | ||
56 | |||
57 | #endif /* __MANTIS_CORE_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_dma.c b/drivers/media/pci/mantis/mantis_dma.c new file mode 100644 index 000000000000..566c407175a4 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_dma.c | |||
@@ -0,0 +1,230 @@ | |||
1 | /* | ||
2 | Mantis 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/kernel.h> | ||
22 | #include <asm/page.h> | ||
23 | #include <linux/vmalloc.h> | ||
24 | #include <linux/pci.h> | ||
25 | |||
26 | #include <asm/irq.h> | ||
27 | #include <linux/signal.h> | ||
28 | #include <linux/sched.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | |||
31 | #include "dmxdev.h" | ||
32 | #include "dvbdev.h" | ||
33 | #include "dvb_demux.h" | ||
34 | #include "dvb_frontend.h" | ||
35 | #include "dvb_net.h" | ||
36 | |||
37 | #include "mantis_common.h" | ||
38 | #include "mantis_reg.h" | ||
39 | #include "mantis_dma.h" | ||
40 | |||
41 | #define RISC_WRITE (0x01 << 28) | ||
42 | #define RISC_JUMP (0x07 << 28) | ||
43 | #define RISC_IRQ (0x01 << 24) | ||
44 | |||
45 | #define RISC_STATUS(status) ((((~status) & 0x0f) << 20) | ((status & 0x0f) << 16)) | ||
46 | #define RISC_FLUSH(risc_pos) (risc_pos = 0) | ||
47 | #define RISC_INSTR(risc_pos, opcode) (mantis->risc_cpu[risc_pos++] = cpu_to_le32(opcode)) | ||
48 | |||
49 | #define MANTIS_BUF_SIZE (64 * 1024) | ||
50 | #define MANTIS_BLOCK_BYTES (MANTIS_BUF_SIZE / 4) | ||
51 | #define MANTIS_DMA_TR_BYTES (2 * 1024) /* upper limit: 4095 bytes. */ | ||
52 | #define MANTIS_BLOCK_COUNT (MANTIS_BUF_SIZE / MANTIS_BLOCK_BYTES) | ||
53 | |||
54 | #define MANTIS_DMA_TR_UNITS (MANTIS_BLOCK_BYTES / MANTIS_DMA_TR_BYTES) | ||
55 | /* MANTIS_BUF_SIZE / MANTIS_DMA_TR_UNITS must not exceed MANTIS_RISC_SIZE (4k RISC cmd buffer) */ | ||
56 | #define MANTIS_RISC_SIZE PAGE_SIZE /* RISC program must fit here. */ | ||
57 | |||
58 | int mantis_dma_exit(struct mantis_pci *mantis) | ||
59 | { | ||
60 | if (mantis->buf_cpu) { | ||
61 | dprintk(MANTIS_ERROR, 1, | ||
62 | "DMA=0x%lx cpu=0x%p size=%d", | ||
63 | (unsigned long) mantis->buf_dma, | ||
64 | mantis->buf_cpu, | ||
65 | MANTIS_BUF_SIZE); | ||
66 | |||
67 | pci_free_consistent(mantis->pdev, MANTIS_BUF_SIZE, | ||
68 | mantis->buf_cpu, mantis->buf_dma); | ||
69 | |||
70 | mantis->buf_cpu = NULL; | ||
71 | } | ||
72 | if (mantis->risc_cpu) { | ||
73 | dprintk(MANTIS_ERROR, 1, | ||
74 | "RISC=0x%lx cpu=0x%p size=%lx", | ||
75 | (unsigned long) mantis->risc_dma, | ||
76 | mantis->risc_cpu, | ||
77 | MANTIS_RISC_SIZE); | ||
78 | |||
79 | pci_free_consistent(mantis->pdev, MANTIS_RISC_SIZE, | ||
80 | mantis->risc_cpu, mantis->risc_dma); | ||
81 | |||
82 | mantis->risc_cpu = NULL; | ||
83 | } | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | EXPORT_SYMBOL_GPL(mantis_dma_exit); | ||
88 | |||
89 | static inline int mantis_alloc_buffers(struct mantis_pci *mantis) | ||
90 | { | ||
91 | if (!mantis->buf_cpu) { | ||
92 | mantis->buf_cpu = pci_alloc_consistent(mantis->pdev, | ||
93 | MANTIS_BUF_SIZE, | ||
94 | &mantis->buf_dma); | ||
95 | if (!mantis->buf_cpu) { | ||
96 | dprintk(MANTIS_ERROR, 1, | ||
97 | "DMA buffer allocation failed"); | ||
98 | |||
99 | goto err; | ||
100 | } | ||
101 | dprintk(MANTIS_ERROR, 1, | ||
102 | "DMA=0x%lx cpu=0x%p size=%d", | ||
103 | (unsigned long) mantis->buf_dma, | ||
104 | mantis->buf_cpu, MANTIS_BUF_SIZE); | ||
105 | } | ||
106 | if (!mantis->risc_cpu) { | ||
107 | mantis->risc_cpu = pci_alloc_consistent(mantis->pdev, | ||
108 | MANTIS_RISC_SIZE, | ||
109 | &mantis->risc_dma); | ||
110 | |||
111 | if (!mantis->risc_cpu) { | ||
112 | dprintk(MANTIS_ERROR, 1, | ||
113 | "RISC program allocation failed"); | ||
114 | |||
115 | mantis_dma_exit(mantis); | ||
116 | |||
117 | goto err; | ||
118 | } | ||
119 | dprintk(MANTIS_ERROR, 1, | ||
120 | "RISC=0x%lx cpu=0x%p size=%lx", | ||
121 | (unsigned long) mantis->risc_dma, | ||
122 | mantis->risc_cpu, MANTIS_RISC_SIZE); | ||
123 | } | ||
124 | |||
125 | return 0; | ||
126 | err: | ||
127 | dprintk(MANTIS_ERROR, 1, "Out of memory (?) ....."); | ||
128 | return -ENOMEM; | ||
129 | } | ||
130 | |||
131 | int mantis_dma_init(struct mantis_pci *mantis) | ||
132 | { | ||
133 | int err = 0; | ||
134 | |||
135 | dprintk(MANTIS_DEBUG, 1, "Mantis DMA init"); | ||
136 | if (mantis_alloc_buffers(mantis) < 0) { | ||
137 | dprintk(MANTIS_ERROR, 1, "Error allocating DMA buffer"); | ||
138 | |||
139 | /* Stop RISC Engine */ | ||
140 | mmwrite(0, MANTIS_DMA_CTL); | ||
141 | |||
142 | goto err; | ||
143 | } | ||
144 | |||
145 | return 0; | ||
146 | err: | ||
147 | return err; | ||
148 | } | ||
149 | EXPORT_SYMBOL_GPL(mantis_dma_init); | ||
150 | |||
151 | static inline void mantis_risc_program(struct mantis_pci *mantis) | ||
152 | { | ||
153 | u32 buf_pos = 0; | ||
154 | u32 line, step; | ||
155 | u32 risc_pos; | ||
156 | |||
157 | dprintk(MANTIS_DEBUG, 1, "Mantis create RISC program"); | ||
158 | RISC_FLUSH(risc_pos); | ||
159 | |||
160 | dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u, bytes per DMA tr %u", | ||
161 | MANTIS_BLOCK_COUNT, MANTIS_BLOCK_BYTES, MANTIS_DMA_TR_BYTES); | ||
162 | |||
163 | for (line = 0; line < MANTIS_BLOCK_COUNT; line++) { | ||
164 | for (step = 0; step < MANTIS_DMA_TR_UNITS; step++) { | ||
165 | dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d], step=[%d]", line, step); | ||
166 | if (step == 0) { | ||
167 | RISC_INSTR(risc_pos, RISC_WRITE | | ||
168 | RISC_IRQ | | ||
169 | RISC_STATUS(line) | | ||
170 | MANTIS_DMA_TR_BYTES); | ||
171 | } else { | ||
172 | RISC_INSTR(risc_pos, RISC_WRITE | MANTIS_DMA_TR_BYTES); | ||
173 | } | ||
174 | RISC_INSTR(risc_pos, mantis->buf_dma + buf_pos); | ||
175 | buf_pos += MANTIS_DMA_TR_BYTES; | ||
176 | } | ||
177 | } | ||
178 | RISC_INSTR(risc_pos, RISC_JUMP); | ||
179 | RISC_INSTR(risc_pos, mantis->risc_dma); | ||
180 | } | ||
181 | |||
182 | void mantis_dma_start(struct mantis_pci *mantis) | ||
183 | { | ||
184 | dprintk(MANTIS_DEBUG, 1, "Mantis Start DMA engine"); | ||
185 | |||
186 | mantis_risc_program(mantis); | ||
187 | mmwrite(mantis->risc_dma, MANTIS_RISC_START); | ||
188 | mmwrite(mmread(MANTIS_GPIF_ADDR) | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); | ||
189 | |||
190 | mmwrite(0, MANTIS_DMA_CTL); | ||
191 | mantis->last_block = mantis->busy_block = 0; | ||
192 | |||
193 | mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_RISCI, MANTIS_INT_MASK); | ||
194 | |||
195 | mmwrite(MANTIS_FIFO_EN | MANTIS_DCAP_EN | ||
196 | | MANTIS_RISC_EN, MANTIS_DMA_CTL); | ||
197 | |||
198 | } | ||
199 | |||
200 | void mantis_dma_stop(struct mantis_pci *mantis) | ||
201 | { | ||
202 | dprintk(MANTIS_DEBUG, 1, "Mantis Stop DMA engine"); | ||
203 | |||
204 | mmwrite((mmread(MANTIS_GPIF_ADDR) & (~(MANTIS_GPIF_HIFRDWRN))), MANTIS_GPIF_ADDR); | ||
205 | |||
206 | mmwrite((mmread(MANTIS_DMA_CTL) & ~(MANTIS_FIFO_EN | | ||
207 | MANTIS_DCAP_EN | | ||
208 | MANTIS_RISC_EN)), MANTIS_DMA_CTL); | ||
209 | |||
210 | mmwrite(mmread(MANTIS_INT_STAT), MANTIS_INT_STAT); | ||
211 | |||
212 | mmwrite(mmread(MANTIS_INT_MASK) & ~(MANTIS_INT_RISCI | | ||
213 | MANTIS_INT_RISCEN), MANTIS_INT_MASK); | ||
214 | } | ||
215 | |||
216 | |||
217 | void mantis_dma_xfer(unsigned long data) | ||
218 | { | ||
219 | struct mantis_pci *mantis = (struct mantis_pci *) data; | ||
220 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
221 | |||
222 | while (mantis->last_block != mantis->busy_block) { | ||
223 | dprintk(MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]", | ||
224 | mantis->last_block, mantis->busy_block); | ||
225 | |||
226 | (config->ts_size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter) | ||
227 | (&mantis->demux, &mantis->buf_cpu[mantis->last_block * MANTIS_BLOCK_BYTES], MANTIS_BLOCK_BYTES); | ||
228 | mantis->last_block = (mantis->last_block + 1) % MANTIS_BLOCK_COUNT; | ||
229 | } | ||
230 | } | ||
diff --git a/drivers/media/pci/mantis/mantis_dma.h b/drivers/media/pci/mantis/mantis_dma.h new file mode 100644 index 000000000000..6be00fa82094 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_dma.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | Mantis 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 | #ifndef __MANTIS_DMA_H | ||
22 | #define __MANTIS_DMA_H | ||
23 | |||
24 | extern int mantis_dma_init(struct mantis_pci *mantis); | ||
25 | extern int mantis_dma_exit(struct mantis_pci *mantis); | ||
26 | extern void mantis_dma_start(struct mantis_pci *mantis); | ||
27 | extern void mantis_dma_stop(struct mantis_pci *mantis); | ||
28 | extern void mantis_dma_xfer(unsigned long data); | ||
29 | |||
30 | #endif /* __MANTIS_DMA_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_dvb.c b/drivers/media/pci/mantis/mantis_dvb.c new file mode 100644 index 000000000000..5d15c6b74d9b --- /dev/null +++ b/drivers/media/pci/mantis/mantis_dvb.c | |||
@@ -0,0 +1,301 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the Free Software | ||
17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/bitops.h> | ||
22 | |||
23 | #include <linux/signal.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/pci.h> | ||
27 | #include <linux/i2c.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 "mantis_dma.h" | ||
37 | #include "mantis_ca.h" | ||
38 | #include "mantis_ioc.h" | ||
39 | #include "mantis_dvb.h" | ||
40 | |||
41 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
42 | |||
43 | int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power) | ||
44 | { | ||
45 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
46 | |||
47 | switch (power) { | ||
48 | case POWER_ON: | ||
49 | dprintk(MANTIS_DEBUG, 1, "Power ON"); | ||
50 | mantis_gpio_set_bits(mantis, config->power, POWER_ON); | ||
51 | msleep(100); | ||
52 | mantis_gpio_set_bits(mantis, config->power, POWER_ON); | ||
53 | msleep(100); | ||
54 | break; | ||
55 | |||
56 | case POWER_OFF: | ||
57 | dprintk(MANTIS_DEBUG, 1, "Power OFF"); | ||
58 | mantis_gpio_set_bits(mantis, config->power, POWER_OFF); | ||
59 | msleep(100); | ||
60 | break; | ||
61 | |||
62 | default: | ||
63 | dprintk(MANTIS_DEBUG, 1, "Unknown state <%02x>", power); | ||
64 | return -1; | ||
65 | } | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | EXPORT_SYMBOL_GPL(mantis_frontend_power); | ||
70 | |||
71 | void mantis_frontend_soft_reset(struct mantis_pci *mantis) | ||
72 | { | ||
73 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
74 | |||
75 | dprintk(MANTIS_DEBUG, 1, "Frontend RESET"); | ||
76 | mantis_gpio_set_bits(mantis, config->reset, 0); | ||
77 | msleep(100); | ||
78 | mantis_gpio_set_bits(mantis, config->reset, 0); | ||
79 | msleep(100); | ||
80 | mantis_gpio_set_bits(mantis, config->reset, 1); | ||
81 | msleep(100); | ||
82 | mantis_gpio_set_bits(mantis, config->reset, 1); | ||
83 | msleep(100); | ||
84 | |||
85 | return; | ||
86 | } | ||
87 | EXPORT_SYMBOL_GPL(mantis_frontend_soft_reset); | ||
88 | |||
89 | static int mantis_frontend_shutdown(struct mantis_pci *mantis) | ||
90 | { | ||
91 | int err; | ||
92 | |||
93 | mantis_frontend_soft_reset(mantis); | ||
94 | err = mantis_frontend_power(mantis, POWER_OFF); | ||
95 | if (err != 0) { | ||
96 | dprintk(MANTIS_ERROR, 1, "Frontend POWER OFF failed! <%d>", err); | ||
97 | return 1; | ||
98 | } | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
104 | { | ||
105 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
106 | struct mantis_pci *mantis = dvbdmx->priv; | ||
107 | |||
108 | dprintk(MANTIS_DEBUG, 1, "Mantis DVB Start feed"); | ||
109 | if (!dvbdmx->dmx.frontend) { | ||
110 | dprintk(MANTIS_DEBUG, 1, "no frontend ?"); | ||
111 | return -EINVAL; | ||
112 | } | ||
113 | |||
114 | mantis->feeds++; | ||
115 | dprintk(MANTIS_DEBUG, 1, "mantis start feed, feeds=%d", mantis->feeds); | ||
116 | |||
117 | if (mantis->feeds == 1) { | ||
118 | dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma"); | ||
119 | mantis_dma_start(mantis); | ||
120 | tasklet_enable(&mantis->tasklet); | ||
121 | } | ||
122 | |||
123 | return mantis->feeds; | ||
124 | } | ||
125 | |||
126 | static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
127 | { | ||
128 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
129 | struct mantis_pci *mantis = dvbdmx->priv; | ||
130 | |||
131 | dprintk(MANTIS_DEBUG, 1, "Mantis DVB Stop feed"); | ||
132 | if (!dvbdmx->dmx.frontend) { | ||
133 | dprintk(MANTIS_DEBUG, 1, "no frontend ?"); | ||
134 | return -EINVAL; | ||
135 | } | ||
136 | |||
137 | mantis->feeds--; | ||
138 | if (mantis->feeds == 0) { | ||
139 | dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma"); | ||
140 | tasklet_disable(&mantis->tasklet); | ||
141 | mantis_dma_stop(mantis); | ||
142 | } | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | int __devinit mantis_dvb_init(struct mantis_pci *mantis) | ||
148 | { | ||
149 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
150 | int result = -1; | ||
151 | |||
152 | dprintk(MANTIS_DEBUG, 1, "dvb_register_adapter"); | ||
153 | |||
154 | result = dvb_register_adapter(&mantis->dvb_adapter, | ||
155 | "Mantis DVB adapter", | ||
156 | THIS_MODULE, | ||
157 | &mantis->pdev->dev, | ||
158 | adapter_nr); | ||
159 | |||
160 | if (result < 0) { | ||
161 | |||
162 | dprintk(MANTIS_ERROR, 1, "Error registering adapter"); | ||
163 | return -ENODEV; | ||
164 | } | ||
165 | |||
166 | mantis->dvb_adapter.priv = mantis; | ||
167 | mantis->demux.dmx.capabilities = DMX_TS_FILTERING | | ||
168 | DMX_SECTION_FILTERING | | ||
169 | DMX_MEMORY_BASED_FILTERING; | ||
170 | |||
171 | mantis->demux.priv = mantis; | ||
172 | mantis->demux.filternum = 256; | ||
173 | mantis->demux.feednum = 256; | ||
174 | mantis->demux.start_feed = mantis_dvb_start_feed; | ||
175 | mantis->demux.stop_feed = mantis_dvb_stop_feed; | ||
176 | mantis->demux.write_to_decoder = NULL; | ||
177 | |||
178 | dprintk(MANTIS_DEBUG, 1, "dvb_dmx_init"); | ||
179 | result = dvb_dmx_init(&mantis->demux); | ||
180 | if (result < 0) { | ||
181 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
182 | |||
183 | goto err0; | ||
184 | } | ||
185 | |||
186 | mantis->dmxdev.filternum = 256; | ||
187 | mantis->dmxdev.demux = &mantis->demux.dmx; | ||
188 | mantis->dmxdev.capabilities = 0; | ||
189 | dprintk(MANTIS_DEBUG, 1, "dvb_dmxdev_init"); | ||
190 | |||
191 | result = dvb_dmxdev_init(&mantis->dmxdev, &mantis->dvb_adapter); | ||
192 | if (result < 0) { | ||
193 | |||
194 | dprintk(MANTIS_ERROR, 1, "dvb_dmxdev_init failed, ERROR=%d", result); | ||
195 | goto err1; | ||
196 | } | ||
197 | |||
198 | mantis->fe_hw.source = DMX_FRONTEND_0; | ||
199 | result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
200 | if (result < 0) { | ||
201 | |||
202 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
203 | goto err2; | ||
204 | } | ||
205 | |||
206 | mantis->fe_mem.source = DMX_MEMORY_FE; | ||
207 | result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_mem); | ||
208 | if (result < 0) { | ||
209 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
210 | goto err3; | ||
211 | } | ||
212 | |||
213 | result = mantis->demux.dmx.connect_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
214 | if (result < 0) { | ||
215 | dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); | ||
216 | goto err4; | ||
217 | } | ||
218 | |||
219 | dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx); | ||
220 | tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis); | ||
221 | tasklet_disable(&mantis->tasklet); | ||
222 | if (mantis->hwconfig) { | ||
223 | result = config->frontend_init(mantis, mantis->fe); | ||
224 | if (result < 0) { | ||
225 | dprintk(MANTIS_ERROR, 1, "!!! NO Frontends found !!!"); | ||
226 | goto err5; | ||
227 | } else { | ||
228 | if (mantis->fe == NULL) { | ||
229 | dprintk(MANTIS_ERROR, 1, "FE <NULL>"); | ||
230 | goto err5; | ||
231 | } | ||
232 | |||
233 | if (dvb_register_frontend(&mantis->dvb_adapter, mantis->fe)) { | ||
234 | dprintk(MANTIS_ERROR, 1, "ERROR: Frontend registration failed"); | ||
235 | |||
236 | if (mantis->fe->ops.release) | ||
237 | mantis->fe->ops.release(mantis->fe); | ||
238 | |||
239 | mantis->fe = NULL; | ||
240 | goto err5; | ||
241 | } | ||
242 | } | ||
243 | } | ||
244 | |||
245 | return 0; | ||
246 | |||
247 | /* Error conditions .. */ | ||
248 | err5: | ||
249 | tasklet_kill(&mantis->tasklet); | ||
250 | dvb_net_release(&mantis->dvbnet); | ||
251 | if (mantis->fe) { | ||
252 | dvb_unregister_frontend(mantis->fe); | ||
253 | dvb_frontend_detach(mantis->fe); | ||
254 | } | ||
255 | err4: | ||
256 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); | ||
257 | |||
258 | err3: | ||
259 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
260 | |||
261 | err2: | ||
262 | dvb_dmxdev_release(&mantis->dmxdev); | ||
263 | |||
264 | err1: | ||
265 | dvb_dmx_release(&mantis->demux); | ||
266 | |||
267 | err0: | ||
268 | dvb_unregister_adapter(&mantis->dvb_adapter); | ||
269 | |||
270 | return result; | ||
271 | } | ||
272 | EXPORT_SYMBOL_GPL(mantis_dvb_init); | ||
273 | |||
274 | int __devexit mantis_dvb_exit(struct mantis_pci *mantis) | ||
275 | { | ||
276 | int err; | ||
277 | |||
278 | if (mantis->fe) { | ||
279 | /* mantis_ca_exit(mantis); */ | ||
280 | err = mantis_frontend_shutdown(mantis); | ||
281 | if (err != 0) | ||
282 | dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err); | ||
283 | dvb_unregister_frontend(mantis->fe); | ||
284 | dvb_frontend_detach(mantis->fe); | ||
285 | } | ||
286 | |||
287 | tasklet_kill(&mantis->tasklet); | ||
288 | dvb_net_release(&mantis->dvbnet); | ||
289 | |||
290 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); | ||
291 | mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw); | ||
292 | |||
293 | dvb_dmxdev_release(&mantis->dmxdev); | ||
294 | dvb_dmx_release(&mantis->demux); | ||
295 | |||
296 | dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter"); | ||
297 | dvb_unregister_adapter(&mantis->dvb_adapter); | ||
298 | |||
299 | return 0; | ||
300 | } | ||
301 | EXPORT_SYMBOL_GPL(mantis_dvb_exit); | ||
diff --git a/drivers/media/pci/mantis/mantis_dvb.h b/drivers/media/pci/mantis/mantis_dvb.h new file mode 100644 index 000000000000..464199db304e --- /dev/null +++ b/drivers/media/pci/mantis/mantis_dvb.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | Mantis 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 | #ifndef __MANTIS_DVB_H | ||
22 | #define __MANTIS_DVB_H | ||
23 | |||
24 | enum mantis_power { | ||
25 | POWER_OFF = 0, | ||
26 | POWER_ON = 1 | ||
27 | }; | ||
28 | |||
29 | extern int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power); | ||
30 | extern void mantis_frontend_soft_reset(struct mantis_pci *mantis); | ||
31 | |||
32 | extern int mantis_dvb_init(struct mantis_pci *mantis); | ||
33 | extern int mantis_dvb_exit(struct mantis_pci *mantis); | ||
34 | |||
35 | #endif /* __MANTIS_DVB_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_evm.c b/drivers/media/pci/mantis/mantis_evm.c new file mode 100644 index 000000000000..71ce52875c38 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_evm.c | |||
@@ -0,0 +1,117 @@ | |||
1 | /* | ||
2 | Mantis 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/kernel.h> | ||
22 | |||
23 | #include <linux/signal.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <asm/io.h> | ||
27 | |||
28 | #include "dmxdev.h" | ||
29 | #include "dvbdev.h" | ||
30 | #include "dvb_demux.h" | ||
31 | #include "dvb_frontend.h" | ||
32 | #include "dvb_net.h" | ||
33 | |||
34 | #include "mantis_common.h" | ||
35 | #include "mantis_link.h" | ||
36 | #include "mantis_hif.h" | ||
37 | #include "mantis_reg.h" | ||
38 | |||
39 | static void mantis_hifevm_work(struct work_struct *work) | ||
40 | { | ||
41 | struct mantis_ca *ca = container_of(work, struct mantis_ca, hif_evm_work); | ||
42 | struct mantis_pci *mantis = ca->ca_priv; | ||
43 | |||
44 | u32 gpif_stat; | ||
45 | |||
46 | gpif_stat = mmread(MANTIS_GPIF_STATUS); | ||
47 | |||
48 | if (gpif_stat & MANTIS_GPIF_DETSTAT) { | ||
49 | if (gpif_stat & MANTIS_CARD_PLUGIN) { | ||
50 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Plugin", mantis->num); | ||
51 | mmwrite(0xdada0000, MANTIS_CARD_RESET); | ||
52 | mantis_event_cam_plugin(ca); | ||
53 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
54 | 0, | ||
55 | DVB_CA_EN50221_CAMCHANGE_INSERTED); | ||
56 | } | ||
57 | } else { | ||
58 | if (gpif_stat & MANTIS_CARD_PLUGOUT) { | ||
59 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Unplug", mantis->num); | ||
60 | mmwrite(0xdada0000, MANTIS_CARD_RESET); | ||
61 | mantis_event_cam_unplug(ca); | ||
62 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
63 | 0, | ||
64 | DVB_CA_EN50221_CAMCHANGE_REMOVED); | ||
65 | } | ||
66 | } | ||
67 | |||
68 | if (mantis->gpif_status & MANTIS_GPIF_EXTIRQ) | ||
69 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Ext IRQ", mantis->num); | ||
70 | |||
71 | if (mantis->gpif_status & MANTIS_SBUF_WSTO) | ||
72 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Timeout", mantis->num); | ||
73 | |||
74 | if (mantis->gpif_status & MANTIS_GPIF_OTHERR) | ||
75 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Alignment Error", mantis->num); | ||
76 | |||
77 | if (gpif_stat & MANTIS_SBUF_OVFLW) | ||
78 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Overflow", mantis->num); | ||
79 | |||
80 | if (gpif_stat & MANTIS_GPIF_BRRDY) | ||
81 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Read Ready", mantis->num); | ||
82 | |||
83 | if (gpif_stat & MANTIS_GPIF_INTSTAT) | ||
84 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): GPIF IRQ", mantis->num); | ||
85 | |||
86 | if (gpif_stat & MANTIS_SBUF_EMPTY) | ||
87 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Empty", mantis->num); | ||
88 | |||
89 | if (gpif_stat & MANTIS_SBUF_OPDONE) { | ||
90 | dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer operation complete", mantis->num); | ||
91 | ca->sbuf_status = MANTIS_SBUF_DATA_AVAIL; | ||
92 | ca->hif_event = MANTIS_SBUF_OPDONE; | ||
93 | wake_up(&ca->hif_opdone_wq); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | int mantis_evmgr_init(struct mantis_ca *ca) | ||
98 | { | ||
99 | struct mantis_pci *mantis = ca->ca_priv; | ||
100 | |||
101 | dprintk(MANTIS_DEBUG, 1, "Initializing Mantis Host I/F Event manager"); | ||
102 | INIT_WORK(&ca->hif_evm_work, mantis_hifevm_work); | ||
103 | mantis_pcmcia_init(ca); | ||
104 | schedule_work(&ca->hif_evm_work); | ||
105 | mantis_hif_init(ca); | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | void mantis_evmgr_exit(struct mantis_ca *ca) | ||
110 | { | ||
111 | struct mantis_pci *mantis = ca->ca_priv; | ||
112 | |||
113 | dprintk(MANTIS_DEBUG, 1, "Mantis Host I/F Event manager exiting"); | ||
114 | flush_work_sync(&ca->hif_evm_work); | ||
115 | mantis_hif_exit(ca); | ||
116 | mantis_pcmcia_exit(ca); | ||
117 | } | ||
diff --git a/drivers/media/pci/mantis/mantis_hif.c b/drivers/media/pci/mantis/mantis_hif.c new file mode 100644 index 000000000000..10c68df7e16f --- /dev/null +++ b/drivers/media/pci/mantis/mantis_hif.c | |||
@@ -0,0 +1,239 @@ | |||
1 | /* | ||
2 | Mantis 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/kernel.h> | ||
22 | #include <linux/signal.h> | ||
23 | #include <linux/sched.h> | ||
24 | |||
25 | #include <linux/interrupt.h> | ||
26 | #include <asm/io.h> | ||
27 | |||
28 | #include "dmxdev.h" | ||
29 | #include "dvbdev.h" | ||
30 | #include "dvb_demux.h" | ||
31 | #include "dvb_frontend.h" | ||
32 | #include "dvb_net.h" | ||
33 | |||
34 | #include "mantis_common.h" | ||
35 | |||
36 | #include "mantis_hif.h" | ||
37 | #include "mantis_link.h" /* temporary due to physical layer stuff */ | ||
38 | |||
39 | #include "mantis_reg.h" | ||
40 | |||
41 | |||
42 | static int mantis_hif_sbuf_opdone_wait(struct mantis_ca *ca) | ||
43 | { | ||
44 | struct mantis_pci *mantis = ca->ca_priv; | ||
45 | int rc = 0; | ||
46 | |||
47 | if (wait_event_timeout(ca->hif_opdone_wq, | ||
48 | ca->hif_event & MANTIS_SBUF_OPDONE, | ||
49 | msecs_to_jiffies(500)) == -ERESTARTSYS) { | ||
50 | |||
51 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Smart buffer operation timeout !", mantis->num); | ||
52 | rc = -EREMOTEIO; | ||
53 | } | ||
54 | dprintk(MANTIS_DEBUG, 1, "Smart Buffer Operation complete"); | ||
55 | ca->hif_event &= ~MANTIS_SBUF_OPDONE; | ||
56 | return rc; | ||
57 | } | ||
58 | |||
59 | static int mantis_hif_write_wait(struct mantis_ca *ca) | ||
60 | { | ||
61 | struct mantis_pci *mantis = ca->ca_priv; | ||
62 | u32 opdone = 0, timeout = 0; | ||
63 | int rc = 0; | ||
64 | |||
65 | if (wait_event_timeout(ca->hif_write_wq, | ||
66 | mantis->gpif_status & MANTIS_GPIF_WRACK, | ||
67 | msecs_to_jiffies(500)) == -ERESTARTSYS) { | ||
68 | |||
69 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write ACK timed out !", mantis->num); | ||
70 | rc = -EREMOTEIO; | ||
71 | } | ||
72 | dprintk(MANTIS_DEBUG, 1, "Write Acknowledged"); | ||
73 | mantis->gpif_status &= ~MANTIS_GPIF_WRACK; | ||
74 | while (!opdone) { | ||
75 | opdone = (mmread(MANTIS_GPIF_STATUS) & MANTIS_SBUF_OPDONE); | ||
76 | udelay(500); | ||
77 | timeout++; | ||
78 | if (timeout > 100) { | ||
79 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write operation timed out!", mantis->num); | ||
80 | rc = -ETIMEDOUT; | ||
81 | break; | ||
82 | } | ||
83 | } | ||
84 | dprintk(MANTIS_DEBUG, 1, "HIF Write success"); | ||
85 | return rc; | ||
86 | } | ||
87 | |||
88 | |||
89 | int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr) | ||
90 | { | ||
91 | struct mantis_pci *mantis = ca->ca_priv; | ||
92 | u32 hif_addr = 0, data, count = 4; | ||
93 | |||
94 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Read", mantis->num); | ||
95 | mutex_lock(&ca->ca_lock); | ||
96 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
97 | hif_addr &= ~MANTIS_GPIF_PCMCIAIOM; | ||
98 | hif_addr |= MANTIS_HIF_STATUS; | ||
99 | hif_addr |= addr; | ||
100 | |||
101 | mmwrite(hif_addr, MANTIS_GPIF_BRADDR); | ||
102 | mmwrite(count, MANTIS_GPIF_BRBYTES); | ||
103 | udelay(20); | ||
104 | mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); | ||
105 | |||
106 | if (mantis_hif_sbuf_opdone_wait(ca) != 0) { | ||
107 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): GPIF Smart Buffer operation failed", mantis->num); | ||
108 | mutex_unlock(&ca->ca_lock); | ||
109 | return -EREMOTEIO; | ||
110 | } | ||
111 | data = mmread(MANTIS_GPIF_DIN); | ||
112 | mutex_unlock(&ca->ca_lock); | ||
113 | dprintk(MANTIS_DEBUG, 1, "Mem Read: 0x%02x", data); | ||
114 | return (data >> 24) & 0xff; | ||
115 | } | ||
116 | |||
117 | int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data) | ||
118 | { | ||
119 | struct mantis_slot *slot = ca->slot; | ||
120 | struct mantis_pci *mantis = ca->ca_priv; | ||
121 | u32 hif_addr = 0; | ||
122 | |||
123 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Write", mantis->num); | ||
124 | mutex_lock(&ca->ca_lock); | ||
125 | hif_addr &= ~MANTIS_GPIF_HIFRDWRN; | ||
126 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
127 | hif_addr &= ~MANTIS_GPIF_PCMCIAIOM; | ||
128 | hif_addr |= MANTIS_HIF_STATUS; | ||
129 | hif_addr |= addr; | ||
130 | |||
131 | mmwrite(slot->slave_cfg, MANTIS_GPIF_CFGSLA); /* Slot0 alone for now */ | ||
132 | mmwrite(hif_addr, MANTIS_GPIF_ADDR); | ||
133 | mmwrite(data, MANTIS_GPIF_DOUT); | ||
134 | |||
135 | if (mantis_hif_write_wait(ca) != 0) { | ||
136 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); | ||
137 | mutex_unlock(&ca->ca_lock); | ||
138 | return -EREMOTEIO; | ||
139 | } | ||
140 | dprintk(MANTIS_DEBUG, 1, "Mem Write: (0x%02x to 0x%02x)", data, addr); | ||
141 | mutex_unlock(&ca->ca_lock); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr) | ||
147 | { | ||
148 | struct mantis_pci *mantis = ca->ca_priv; | ||
149 | u32 data, hif_addr = 0; | ||
150 | |||
151 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Read", mantis->num); | ||
152 | mutex_lock(&ca->ca_lock); | ||
153 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
154 | hif_addr |= MANTIS_GPIF_PCMCIAIOM; | ||
155 | hif_addr |= MANTIS_HIF_STATUS; | ||
156 | hif_addr |= addr; | ||
157 | |||
158 | mmwrite(hif_addr, MANTIS_GPIF_BRADDR); | ||
159 | mmwrite(1, MANTIS_GPIF_BRBYTES); | ||
160 | udelay(20); | ||
161 | mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); | ||
162 | |||
163 | if (mantis_hif_sbuf_opdone_wait(ca) != 0) { | ||
164 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); | ||
165 | mutex_unlock(&ca->ca_lock); | ||
166 | return -EREMOTEIO; | ||
167 | } | ||
168 | data = mmread(MANTIS_GPIF_DIN); | ||
169 | dprintk(MANTIS_DEBUG, 1, "I/O Read: 0x%02x", data); | ||
170 | udelay(50); | ||
171 | mutex_unlock(&ca->ca_lock); | ||
172 | |||
173 | return (u8) data; | ||
174 | } | ||
175 | |||
176 | int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data) | ||
177 | { | ||
178 | struct mantis_pci *mantis = ca->ca_priv; | ||
179 | u32 hif_addr = 0; | ||
180 | |||
181 | dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Write", mantis->num); | ||
182 | mutex_lock(&ca->ca_lock); | ||
183 | hif_addr &= ~MANTIS_GPIF_PCMCIAREG; | ||
184 | hif_addr &= ~MANTIS_GPIF_HIFRDWRN; | ||
185 | hif_addr |= MANTIS_GPIF_PCMCIAIOM; | ||
186 | hif_addr |= MANTIS_HIF_STATUS; | ||
187 | hif_addr |= addr; | ||
188 | |||
189 | mmwrite(hif_addr, MANTIS_GPIF_ADDR); | ||
190 | mmwrite(data, MANTIS_GPIF_DOUT); | ||
191 | |||
192 | if (mantis_hif_write_wait(ca) != 0) { | ||
193 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); | ||
194 | mutex_unlock(&ca->ca_lock); | ||
195 | return -EREMOTEIO; | ||
196 | } | ||
197 | dprintk(MANTIS_DEBUG, 1, "I/O Write: (0x%02x to 0x%02x)", data, addr); | ||
198 | mutex_unlock(&ca->ca_lock); | ||
199 | udelay(50); | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | int mantis_hif_init(struct mantis_ca *ca) | ||
205 | { | ||
206 | struct mantis_slot *slot = ca->slot; | ||
207 | struct mantis_pci *mantis = ca->ca_priv; | ||
208 | u32 irqcfg; | ||
209 | |||
210 | slot[0].slave_cfg = 0x70773028; | ||
211 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Initializing Mantis Host Interface", mantis->num); | ||
212 | |||
213 | mutex_lock(&ca->ca_lock); | ||
214 | irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
215 | irqcfg = MANTIS_MASK_BRRDY | | ||
216 | MANTIS_MASK_WRACK | | ||
217 | MANTIS_MASK_EXTIRQ | | ||
218 | MANTIS_MASK_WSTO | | ||
219 | MANTIS_MASK_OTHERR | | ||
220 | MANTIS_MASK_OVFLW; | ||
221 | |||
222 | mmwrite(irqcfg, MANTIS_GPIF_IRQCFG); | ||
223 | mutex_unlock(&ca->ca_lock); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | void mantis_hif_exit(struct mantis_ca *ca) | ||
229 | { | ||
230 | struct mantis_pci *mantis = ca->ca_priv; | ||
231 | u32 irqcfg; | ||
232 | |||
233 | dprintk(MANTIS_ERROR, 1, "Adapter(%d) Exiting Mantis Host Interface", mantis->num); | ||
234 | mutex_lock(&ca->ca_lock); | ||
235 | irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
236 | irqcfg &= ~MANTIS_MASK_BRRDY; | ||
237 | mmwrite(irqcfg, MANTIS_GPIF_IRQCFG); | ||
238 | mutex_unlock(&ca->ca_lock); | ||
239 | } | ||
diff --git a/drivers/media/pci/mantis/mantis_hif.h b/drivers/media/pci/mantis/mantis_hif.h new file mode 100644 index 000000000000..9094f9ed2362 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_hif.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | Mantis 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 | #ifndef __MANTIS_HIF_H | ||
22 | #define __MANTIS_HIF_H | ||
23 | |||
24 | #define MANTIS_HIF_MEMRD 1 | ||
25 | #define MANTIS_HIF_MEMWR 2 | ||
26 | #define MANTIS_HIF_IOMRD 3 | ||
27 | #define MANTIS_HIF_IOMWR 4 | ||
28 | |||
29 | #endif /* __MANTIS_HIF_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_i2c.c b/drivers/media/pci/mantis/mantis_i2c.c new file mode 100644 index 000000000000..e7794517fe26 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_i2c.c | |||
@@ -0,0 +1,266 @@ | |||
1 | /* | ||
2 | Mantis 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 <asm/io.h> | ||
22 | #include <linux/ioport.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/i2c.h> | ||
25 | |||
26 | #include "dmxdev.h" | ||
27 | #include "dvbdev.h" | ||
28 | #include "dvb_demux.h" | ||
29 | #include "dvb_frontend.h" | ||
30 | #include "dvb_net.h" | ||
31 | |||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_reg.h" | ||
34 | #include "mantis_i2c.h" | ||
35 | |||
36 | #define TRIALS 10000 | ||
37 | |||
38 | static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg) | ||
39 | { | ||
40 | u32 rxd, i, stat, trials; | ||
41 | |||
42 | dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <R>[ ", | ||
43 | __func__, msg->addr); | ||
44 | |||
45 | for (i = 0; i < msg->len; i++) { | ||
46 | rxd = (msg->addr << 25) | (1 << 24) | ||
47 | | MANTIS_I2C_RATE_3 | ||
48 | | MANTIS_I2C_STOP | ||
49 | | MANTIS_I2C_PGMODE; | ||
50 | |||
51 | if (i == (msg->len - 1)) | ||
52 | rxd &= ~MANTIS_I2C_STOP; | ||
53 | |||
54 | mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT); | ||
55 | mmwrite(rxd, MANTIS_I2CDATA_CTL); | ||
56 | |||
57 | /* wait for xfer completion */ | ||
58 | for (trials = 0; trials < TRIALS; trials++) { | ||
59 | stat = mmread(MANTIS_INT_STAT); | ||
60 | if (stat & MANTIS_INT_I2CDONE) | ||
61 | break; | ||
62 | } | ||
63 | |||
64 | dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials); | ||
65 | |||
66 | /* wait for xfer completion */ | ||
67 | for (trials = 0; trials < TRIALS; trials++) { | ||
68 | stat = mmread(MANTIS_INT_STAT); | ||
69 | if (stat & MANTIS_INT_I2CRACK) | ||
70 | break; | ||
71 | } | ||
72 | |||
73 | dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials); | ||
74 | |||
75 | rxd = mmread(MANTIS_I2CDATA_CTL); | ||
76 | msg->buf[i] = (u8)((rxd >> 8) & 0xFF); | ||
77 | dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]); | ||
78 | } | ||
79 | dprintk(MANTIS_INFO, 0, "]\n"); | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg) | ||
85 | { | ||
86 | int i; | ||
87 | u32 txd = 0, stat, trials; | ||
88 | |||
89 | dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <W>[ ", | ||
90 | __func__, msg->addr); | ||
91 | |||
92 | for (i = 0; i < msg->len; i++) { | ||
93 | dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]); | ||
94 | txd = (msg->addr << 25) | (msg->buf[i] << 8) | ||
95 | | MANTIS_I2C_RATE_3 | ||
96 | | MANTIS_I2C_STOP | ||
97 | | MANTIS_I2C_PGMODE; | ||
98 | |||
99 | if (i == (msg->len - 1)) | ||
100 | txd &= ~MANTIS_I2C_STOP; | ||
101 | |||
102 | mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT); | ||
103 | mmwrite(txd, MANTIS_I2CDATA_CTL); | ||
104 | |||
105 | /* wait for xfer completion */ | ||
106 | for (trials = 0; trials < TRIALS; trials++) { | ||
107 | stat = mmread(MANTIS_INT_STAT); | ||
108 | if (stat & MANTIS_INT_I2CDONE) | ||
109 | break; | ||
110 | } | ||
111 | |||
112 | dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials); | ||
113 | |||
114 | /* wait for xfer completion */ | ||
115 | for (trials = 0; trials < TRIALS; trials++) { | ||
116 | stat = mmread(MANTIS_INT_STAT); | ||
117 | if (stat & MANTIS_INT_I2CRACK) | ||
118 | break; | ||
119 | } | ||
120 | |||
121 | dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials); | ||
122 | } | ||
123 | dprintk(MANTIS_INFO, 0, "]\n"); | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) | ||
129 | { | ||
130 | int ret = 0, i = 0, trials; | ||
131 | u32 stat, data, txd; | ||
132 | struct mantis_pci *mantis; | ||
133 | struct mantis_hwconfig *config; | ||
134 | |||
135 | mantis = i2c_get_adapdata(adapter); | ||
136 | BUG_ON(!mantis); | ||
137 | config = mantis->hwconfig; | ||
138 | BUG_ON(!config); | ||
139 | |||
140 | dprintk(MANTIS_DEBUG, 1, "Messages:%d", num); | ||
141 | mutex_lock(&mantis->i2c_lock); | ||
142 | |||
143 | while (i < num) { | ||
144 | /* Byte MODE */ | ||
145 | if ((config->i2c_mode & MANTIS_BYTE_MODE) && | ||
146 | ((i + 1) < num) && | ||
147 | (msgs[i].len < 2) && | ||
148 | (msgs[i + 1].len < 2) && | ||
149 | (msgs[i + 1].flags & I2C_M_RD)) { | ||
150 | |||
151 | dprintk(MANTIS_DEBUG, 0, " Byte MODE:\n"); | ||
152 | |||
153 | /* Read operation */ | ||
154 | txd = msgs[i].addr << 25 | (0x1 << 24) | ||
155 | | (msgs[i].buf[0] << 16) | ||
156 | | MANTIS_I2C_RATE_3; | ||
157 | |||
158 | mmwrite(txd, MANTIS_I2CDATA_CTL); | ||
159 | /* wait for xfer completion */ | ||
160 | for (trials = 0; trials < TRIALS; trials++) { | ||
161 | stat = mmread(MANTIS_INT_STAT); | ||
162 | if (stat & MANTIS_INT_I2CDONE) | ||
163 | break; | ||
164 | } | ||
165 | |||
166 | /* check for xfer completion */ | ||
167 | if (stat & MANTIS_INT_I2CDONE) { | ||
168 | /* check xfer was acknowledged */ | ||
169 | if (stat & MANTIS_INT_I2CRACK) { | ||
170 | data = mmread(MANTIS_I2CDATA_CTL); | ||
171 | msgs[i + 1].buf[0] = (data >> 8) & 0xff; | ||
172 | dprintk(MANTIS_DEBUG, 0, " Byte <%d> RXD=0x%02x [%02x]\n", 0x0, data, msgs[i + 1].buf[0]); | ||
173 | } else { | ||
174 | /* I/O error */ | ||
175 | dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__); | ||
176 | ret = -EIO; | ||
177 | break; | ||
178 | } | ||
179 | } else { | ||
180 | /* I/O error */ | ||
181 | dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__); | ||
182 | ret = -EIO; | ||
183 | break; | ||
184 | } | ||
185 | i += 2; /* Write/Read operation in one go */ | ||
186 | } | ||
187 | |||
188 | if (i < num) { | ||
189 | if (msgs[i].flags & I2C_M_RD) | ||
190 | ret = mantis_i2c_read(mantis, &msgs[i]); | ||
191 | else | ||
192 | ret = mantis_i2c_write(mantis, &msgs[i]); | ||
193 | |||
194 | i++; | ||
195 | if (ret < 0) | ||
196 | goto bail_out; | ||
197 | } | ||
198 | |||
199 | } | ||
200 | |||
201 | mutex_unlock(&mantis->i2c_lock); | ||
202 | |||
203 | return num; | ||
204 | |||
205 | bail_out: | ||
206 | mutex_unlock(&mantis->i2c_lock); | ||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | static u32 mantis_i2c_func(struct i2c_adapter *adapter) | ||
211 | { | ||
212 | return I2C_FUNC_SMBUS_EMUL; | ||
213 | } | ||
214 | |||
215 | static struct i2c_algorithm mantis_algo = { | ||
216 | .master_xfer = mantis_i2c_xfer, | ||
217 | .functionality = mantis_i2c_func, | ||
218 | }; | ||
219 | |||
220 | int __devinit mantis_i2c_init(struct mantis_pci *mantis) | ||
221 | { | ||
222 | u32 intstat, intmask; | ||
223 | struct i2c_adapter *i2c_adapter = &mantis->adapter; | ||
224 | struct pci_dev *pdev = mantis->pdev; | ||
225 | |||
226 | init_waitqueue_head(&mantis->i2c_wq); | ||
227 | mutex_init(&mantis->i2c_lock); | ||
228 | strncpy(i2c_adapter->name, "Mantis I2C", sizeof(i2c_adapter->name)); | ||
229 | i2c_set_adapdata(i2c_adapter, mantis); | ||
230 | |||
231 | i2c_adapter->owner = THIS_MODULE; | ||
232 | i2c_adapter->algo = &mantis_algo; | ||
233 | i2c_adapter->algo_data = NULL; | ||
234 | i2c_adapter->timeout = 500; | ||
235 | i2c_adapter->retries = 3; | ||
236 | i2c_adapter->dev.parent = &pdev->dev; | ||
237 | |||
238 | mantis->i2c_rc = i2c_add_adapter(i2c_adapter); | ||
239 | if (mantis->i2c_rc < 0) | ||
240 | return mantis->i2c_rc; | ||
241 | |||
242 | dprintk(MANTIS_DEBUG, 1, "Initializing I2C .."); | ||
243 | |||
244 | intstat = mmread(MANTIS_INT_STAT); | ||
245 | intmask = mmread(MANTIS_INT_MASK); | ||
246 | mmwrite(intstat, MANTIS_INT_STAT); | ||
247 | dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); | ||
248 | intmask = mmread(MANTIS_INT_MASK); | ||
249 | mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK); | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | EXPORT_SYMBOL_GPL(mantis_i2c_init); | ||
254 | |||
255 | int mantis_i2c_exit(struct mantis_pci *mantis) | ||
256 | { | ||
257 | u32 intmask; | ||
258 | |||
259 | dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); | ||
260 | intmask = mmread(MANTIS_INT_MASK); | ||
261 | mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK); | ||
262 | |||
263 | dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter"); | ||
264 | return i2c_del_adapter(&mantis->adapter); | ||
265 | } | ||
266 | EXPORT_SYMBOL_GPL(mantis_i2c_exit); | ||
diff --git a/drivers/media/pci/mantis/mantis_i2c.h b/drivers/media/pci/mantis/mantis_i2c.h new file mode 100644 index 000000000000..1342df2faed8 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_i2c.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | Mantis 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 | #ifndef __MANTIS_I2C_H | ||
22 | #define __MANTIS_I2C_H | ||
23 | |||
24 | #define I2C_STOP (1 << 0) | ||
25 | #define I2C_READ (1 << 1) | ||
26 | |||
27 | extern int mantis_i2c_init(struct mantis_pci *mantis); | ||
28 | extern int mantis_i2c_exit(struct mantis_pci *mantis); | ||
29 | |||
30 | #endif /* __MANTIS_I2C_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_input.c b/drivers/media/pci/mantis/mantis_input.c new file mode 100644 index 000000000000..db6d54d3fec0 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_input.c | |||
@@ -0,0 +1,159 @@ | |||
1 | /* | ||
2 | Mantis 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 <media/rc-core.h> | ||
22 | #include <linux/pci.h> | ||
23 | |||
24 | #include "dmxdev.h" | ||
25 | #include "dvbdev.h" | ||
26 | #include "dvb_demux.h" | ||
27 | #include "dvb_frontend.h" | ||
28 | #include "dvb_net.h" | ||
29 | |||
30 | #include "mantis_common.h" | ||
31 | #include "mantis_reg.h" | ||
32 | #include "mantis_uart.h" | ||
33 | |||
34 | #define MODULE_NAME "mantis_core" | ||
35 | #define RC_MAP_MANTIS "rc-mantis" | ||
36 | |||
37 | static struct rc_map_table mantis_ir_table[] = { | ||
38 | { 0x29, KEY_POWER }, | ||
39 | { 0x28, KEY_FAVORITES }, | ||
40 | { 0x30, KEY_TEXT }, | ||
41 | { 0x17, KEY_INFO }, /* Preview */ | ||
42 | { 0x23, KEY_EPG }, | ||
43 | { 0x3b, KEY_F22 }, /* Record List */ | ||
44 | { 0x3c, KEY_1 }, | ||
45 | { 0x3e, KEY_2 }, | ||
46 | { 0x39, KEY_3 }, | ||
47 | { 0x36, KEY_4 }, | ||
48 | { 0x22, KEY_5 }, | ||
49 | { 0x20, KEY_6 }, | ||
50 | { 0x32, KEY_7 }, | ||
51 | { 0x26, KEY_8 }, | ||
52 | { 0x24, KEY_9 }, | ||
53 | { 0x2a, KEY_0 }, | ||
54 | |||
55 | { 0x33, KEY_CANCEL }, | ||
56 | { 0x2c, KEY_BACK }, | ||
57 | { 0x15, KEY_CLEAR }, | ||
58 | { 0x3f, KEY_TAB }, | ||
59 | { 0x10, KEY_ENTER }, | ||
60 | { 0x14, KEY_UP }, | ||
61 | { 0x0d, KEY_RIGHT }, | ||
62 | { 0x0e, KEY_DOWN }, | ||
63 | { 0x11, KEY_LEFT }, | ||
64 | |||
65 | { 0x21, KEY_VOLUMEUP }, | ||
66 | { 0x35, KEY_VOLUMEDOWN }, | ||
67 | { 0x3d, KEY_CHANNELDOWN }, | ||
68 | { 0x3a, KEY_CHANNELUP }, | ||
69 | { 0x2e, KEY_RECORD }, | ||
70 | { 0x2b, KEY_PLAY }, | ||
71 | { 0x13, KEY_PAUSE }, | ||
72 | { 0x25, KEY_STOP }, | ||
73 | |||
74 | { 0x1f, KEY_REWIND }, | ||
75 | { 0x2d, KEY_FASTFORWARD }, | ||
76 | { 0x1e, KEY_PREVIOUS }, /* Replay |< */ | ||
77 | { 0x1d, KEY_NEXT }, /* Skip >| */ | ||
78 | |||
79 | { 0x0b, KEY_CAMERA }, /* Capture */ | ||
80 | { 0x0f, KEY_LANGUAGE }, /* SAP */ | ||
81 | { 0x18, KEY_MODE }, /* PIP */ | ||
82 | { 0x12, KEY_ZOOM }, /* Full screen */ | ||
83 | { 0x1c, KEY_SUBTITLE }, | ||
84 | { 0x2f, KEY_MUTE }, | ||
85 | { 0x16, KEY_F20 }, /* L/R */ | ||
86 | { 0x38, KEY_F21 }, /* Hibernate */ | ||
87 | |||
88 | { 0x37, KEY_SWITCHVIDEOMODE }, /* A/V */ | ||
89 | { 0x31, KEY_AGAIN }, /* Recall */ | ||
90 | { 0x1a, KEY_KPPLUS }, /* Zoom+ */ | ||
91 | { 0x19, KEY_KPMINUS }, /* Zoom- */ | ||
92 | { 0x27, KEY_RED }, | ||
93 | { 0x0C, KEY_GREEN }, | ||
94 | { 0x01, KEY_YELLOW }, | ||
95 | { 0x00, KEY_BLUE }, | ||
96 | }; | ||
97 | |||
98 | static struct rc_map_list ir_mantis_map = { | ||
99 | .map = { | ||
100 | .scan = mantis_ir_table, | ||
101 | .size = ARRAY_SIZE(mantis_ir_table), | ||
102 | .rc_type = RC_TYPE_UNKNOWN, | ||
103 | .name = RC_MAP_MANTIS, | ||
104 | } | ||
105 | }; | ||
106 | |||
107 | int mantis_input_init(struct mantis_pci *mantis) | ||
108 | { | ||
109 | struct rc_dev *dev; | ||
110 | int err; | ||
111 | |||
112 | err = rc_map_register(&ir_mantis_map); | ||
113 | if (err) | ||
114 | goto out; | ||
115 | |||
116 | dev = rc_allocate_device(); | ||
117 | if (!dev) { | ||
118 | dprintk(MANTIS_ERROR, 1, "Remote device allocation failed"); | ||
119 | err = -ENOMEM; | ||
120 | goto out_map; | ||
121 | } | ||
122 | |||
123 | sprintf(mantis->input_name, "Mantis %s IR receiver", mantis->hwconfig->model_name); | ||
124 | sprintf(mantis->input_phys, "pci-%s/ir0", pci_name(mantis->pdev)); | ||
125 | |||
126 | dev->input_name = mantis->input_name; | ||
127 | dev->input_phys = mantis->input_phys; | ||
128 | dev->input_id.bustype = BUS_PCI; | ||
129 | dev->input_id.vendor = mantis->vendor_id; | ||
130 | dev->input_id.product = mantis->device_id; | ||
131 | dev->input_id.version = 1; | ||
132 | dev->driver_name = MODULE_NAME; | ||
133 | dev->map_name = RC_MAP_MANTIS; | ||
134 | dev->dev.parent = &mantis->pdev->dev; | ||
135 | |||
136 | err = rc_register_device(dev); | ||
137 | if (err) { | ||
138 | dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err); | ||
139 | goto out_dev; | ||
140 | } | ||
141 | |||
142 | mantis->rc = dev; | ||
143 | return 0; | ||
144 | |||
145 | out_dev: | ||
146 | rc_free_device(dev); | ||
147 | out_map: | ||
148 | rc_map_unregister(&ir_mantis_map); | ||
149 | out: | ||
150 | return err; | ||
151 | } | ||
152 | |||
153 | int mantis_exit(struct mantis_pci *mantis) | ||
154 | { | ||
155 | rc_unregister_device(mantis->rc); | ||
156 | rc_map_unregister(&ir_mantis_map); | ||
157 | return 0; | ||
158 | } | ||
159 | |||
diff --git a/drivers/media/pci/mantis/mantis_ioc.c b/drivers/media/pci/mantis/mantis_ioc.c new file mode 100644 index 000000000000..24fcdc63d6d5 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_ioc.c | |||
@@ -0,0 +1,124 @@ | |||
1 | /* | ||
2 | Mantis 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/kernel.h> | ||
22 | #include <linux/i2c.h> | ||
23 | |||
24 | #include <linux/signal.h> | ||
25 | #include <linux/sched.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <asm/io.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 "mantis_reg.h" | ||
37 | #include "mantis_ioc.h" | ||
38 | |||
39 | static int read_eeprom_bytes(struct mantis_pci *mantis, u8 reg, u8 *data, u8 length) | ||
40 | { | ||
41 | struct i2c_adapter *adapter = &mantis->adapter; | ||
42 | int err; | ||
43 | u8 buf = reg; | ||
44 | |||
45 | struct i2c_msg msg[] = { | ||
46 | { .addr = 0x50, .flags = 0, .buf = &buf, .len = 1 }, | ||
47 | { .addr = 0x50, .flags = I2C_M_RD, .buf = data, .len = length }, | ||
48 | }; | ||
49 | |||
50 | err = i2c_transfer(adapter, msg, 2); | ||
51 | if (err < 0) { | ||
52 | dprintk(MANTIS_ERROR, 1, "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >", | ||
53 | err, data[0], data[1]); | ||
54 | |||
55 | return err; | ||
56 | } | ||
57 | |||
58 | return 0; | ||
59 | } | ||
60 | int mantis_get_mac(struct mantis_pci *mantis) | ||
61 | { | ||
62 | int err; | ||
63 | u8 mac_addr[6] = {0}; | ||
64 | |||
65 | err = read_eeprom_bytes(mantis, 0x08, mac_addr, 6); | ||
66 | if (err < 0) { | ||
67 | dprintk(MANTIS_ERROR, 1, "ERROR: Mantis EEPROM read error <%d>", err); | ||
68 | |||
69 | return err; | ||
70 | } | ||
71 | |||
72 | dprintk(MANTIS_ERROR, 0, " MAC Address=[%pM]\n", mac_addr); | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | EXPORT_SYMBOL_GPL(mantis_get_mac); | ||
77 | |||
78 | /* Turn the given bit on or off. */ | ||
79 | void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value) | ||
80 | { | ||
81 | u32 cur; | ||
82 | |||
83 | dprintk(MANTIS_DEBUG, 1, "Set Bit <%d> to <%d>", bitpos, value); | ||
84 | cur = mmread(MANTIS_GPIF_ADDR); | ||
85 | if (value) | ||
86 | mantis->gpio_status = cur | (1 << bitpos); | ||
87 | else | ||
88 | mantis->gpio_status = cur & (~(1 << bitpos)); | ||
89 | |||
90 | dprintk(MANTIS_DEBUG, 1, "GPIO Value <%02x>", mantis->gpio_status); | ||
91 | mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR); | ||
92 | mmwrite(0x00, MANTIS_GPIF_DOUT); | ||
93 | } | ||
94 | EXPORT_SYMBOL_GPL(mantis_gpio_set_bits); | ||
95 | |||
96 | int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl) | ||
97 | { | ||
98 | u32 reg; | ||
99 | |||
100 | reg = mmread(MANTIS_CONTROL); | ||
101 | switch (stream_ctl) { | ||
102 | case STREAM_TO_HIF: | ||
103 | dprintk(MANTIS_DEBUG, 1, "Set stream to HIF"); | ||
104 | reg &= 0xff - MANTIS_BYPASS; | ||
105 | mmwrite(reg, MANTIS_CONTROL); | ||
106 | reg |= MANTIS_BYPASS; | ||
107 | mmwrite(reg, MANTIS_CONTROL); | ||
108 | break; | ||
109 | |||
110 | case STREAM_TO_CAM: | ||
111 | dprintk(MANTIS_DEBUG, 1, "Set stream to CAM"); | ||
112 | reg |= MANTIS_BYPASS; | ||
113 | mmwrite(reg, MANTIS_CONTROL); | ||
114 | reg &= 0xff - MANTIS_BYPASS; | ||
115 | mmwrite(reg, MANTIS_CONTROL); | ||
116 | break; | ||
117 | default: | ||
118 | dprintk(MANTIS_ERROR, 1, "Unknown MODE <%02x>", stream_ctl); | ||
119 | return -1; | ||
120 | } | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | EXPORT_SYMBOL_GPL(mantis_stream_control); | ||
diff --git a/drivers/media/pci/mantis/mantis_ioc.h b/drivers/media/pci/mantis/mantis_ioc.h new file mode 100644 index 000000000000..d56e002b2955 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_ioc.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | Mantis 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 | #ifndef __MANTIS_IOC_H | ||
22 | #define __MANTIS_IOC_H | ||
23 | |||
24 | #define GPIF_A00 0x00 | ||
25 | #define GPIF_A01 0x01 | ||
26 | #define GPIF_A02 0x02 | ||
27 | #define GPIF_A03 0x03 | ||
28 | #define GPIF_A04 0x04 | ||
29 | #define GPIF_A05 0x05 | ||
30 | #define GPIF_A06 0x06 | ||
31 | #define GPIF_A07 0x07 | ||
32 | #define GPIF_A08 0x08 | ||
33 | #define GPIF_A09 0x09 | ||
34 | #define GPIF_A10 0x0a | ||
35 | #define GPIF_A11 0x0b | ||
36 | |||
37 | #define GPIF_A12 0x0c | ||
38 | #define GPIF_A13 0x0d | ||
39 | #define GPIF_A14 0x0e | ||
40 | |||
41 | enum mantis_stream_control { | ||
42 | STREAM_TO_HIF = 0, | ||
43 | STREAM_TO_CAM | ||
44 | }; | ||
45 | |||
46 | extern int mantis_get_mac(struct mantis_pci *mantis); | ||
47 | extern void mantis_gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value); | ||
48 | |||
49 | extern int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl); | ||
50 | |||
51 | #endif /* __MANTIS_IOC_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_link.h b/drivers/media/pci/mantis/mantis_link.h new file mode 100644 index 000000000000..2a814774a001 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_link.h | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | Mantis 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 | #ifndef __MANTIS_LINK_H | ||
22 | #define __MANTIS_LINK_H | ||
23 | |||
24 | #include <linux/mutex.h> | ||
25 | #include <linux/workqueue.h> | ||
26 | #include "dvb_ca_en50221.h" | ||
27 | |||
28 | enum mantis_sbuf_status { | ||
29 | MANTIS_SBUF_DATA_AVAIL = 1, | ||
30 | MANTIS_SBUF_DATA_EMPTY = 2, | ||
31 | MANTIS_SBUF_DATA_OVFLW = 3 | ||
32 | }; | ||
33 | |||
34 | struct mantis_slot { | ||
35 | u32 timeout; | ||
36 | u32 slave_cfg; | ||
37 | u32 bar; | ||
38 | }; | ||
39 | |||
40 | /* Physical layer */ | ||
41 | enum mantis_slot_state { | ||
42 | MODULE_INSERTED = 3, | ||
43 | MODULE_XTRACTED = 4 | ||
44 | }; | ||
45 | |||
46 | struct mantis_ca { | ||
47 | struct mantis_slot slot[4]; | ||
48 | |||
49 | struct work_struct hif_evm_work; | ||
50 | |||
51 | u32 hif_event; | ||
52 | wait_queue_head_t hif_opdone_wq; | ||
53 | wait_queue_head_t hif_brrdyw_wq; | ||
54 | wait_queue_head_t hif_data_wq; | ||
55 | wait_queue_head_t hif_write_wq; /* HIF Write op */ | ||
56 | |||
57 | enum mantis_sbuf_status sbuf_status; | ||
58 | |||
59 | enum mantis_slot_state slot_state; | ||
60 | |||
61 | void *ca_priv; | ||
62 | |||
63 | struct dvb_ca_en50221 en50221; | ||
64 | struct mutex ca_lock; | ||
65 | }; | ||
66 | |||
67 | /* CA */ | ||
68 | extern void mantis_event_cam_plugin(struct mantis_ca *ca); | ||
69 | extern void mantis_event_cam_unplug(struct mantis_ca *ca); | ||
70 | extern int mantis_pcmcia_init(struct mantis_ca *ca); | ||
71 | extern void mantis_pcmcia_exit(struct mantis_ca *ca); | ||
72 | extern int mantis_evmgr_init(struct mantis_ca *ca); | ||
73 | extern void mantis_evmgr_exit(struct mantis_ca *ca); | ||
74 | |||
75 | /* HIF */ | ||
76 | extern int mantis_hif_init(struct mantis_ca *ca); | ||
77 | extern void mantis_hif_exit(struct mantis_ca *ca); | ||
78 | extern int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr); | ||
79 | extern int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data); | ||
80 | extern int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr); | ||
81 | extern int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data); | ||
82 | |||
83 | #endif /* __MANTIS_LINK_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_pci.c b/drivers/media/pci/mantis/mantis_pci.c new file mode 100644 index 000000000000..371558af2d96 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_pci.c | |||
@@ -0,0 +1,170 @@ | |||
1 | /* | ||
2 | Mantis 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 <asm/io.h> | ||
25 | #include <asm/page.h> | ||
26 | #include <linux/kmod.h> | ||
27 | #include <linux/vmalloc.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/device.h> | ||
30 | #include <linux/pci.h> | ||
31 | |||
32 | #include <asm/irq.h> | ||
33 | #include <linux/signal.h> | ||
34 | #include <linux/sched.h> | ||
35 | #include <linux/interrupt.h> | ||
36 | |||
37 | #include "dmxdev.h" | ||
38 | #include "dvbdev.h" | ||
39 | #include "dvb_demux.h" | ||
40 | #include "dvb_frontend.h" | ||
41 | #include "dvb_net.h" | ||
42 | |||
43 | #include "mantis_common.h" | ||
44 | #include "mantis_reg.h" | ||
45 | #include "mantis_pci.h" | ||
46 | |||
47 | #define DRIVER_NAME "Mantis Core" | ||
48 | |||
49 | int __devinit mantis_pci_init(struct mantis_pci *mantis) | ||
50 | { | ||
51 | u8 latency; | ||
52 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
53 | struct pci_dev *pdev = mantis->pdev; | ||
54 | int err, ret = 0; | ||
55 | |||
56 | dprintk(MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n", | ||
57 | config->model_name, | ||
58 | config->dev_type, | ||
59 | mantis->pdev->bus->number, | ||
60 | PCI_SLOT(mantis->pdev->devfn), | ||
61 | PCI_FUNC(mantis->pdev->devfn)); | ||
62 | |||
63 | err = pci_enable_device(pdev); | ||
64 | if (err != 0) { | ||
65 | ret = -ENODEV; | ||
66 | dprintk(MANTIS_ERROR, 1, "ERROR: PCI enable failed <%i>", err); | ||
67 | goto fail0; | ||
68 | } | ||
69 | |||
70 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
71 | if (err != 0) { | ||
72 | dprintk(MANTIS_ERROR, 1, "ERROR: Unable to obtain 32 bit DMA <%i>", err); | ||
73 | ret = -ENOMEM; | ||
74 | goto fail1; | ||
75 | } | ||
76 | |||
77 | pci_set_master(pdev); | ||
78 | |||
79 | if (!request_mem_region(pci_resource_start(pdev, 0), | ||
80 | pci_resource_len(pdev, 0), | ||
81 | DRIVER_NAME)) { | ||
82 | |||
83 | dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 Request failed !"); | ||
84 | ret = -ENODEV; | ||
85 | goto fail1; | ||
86 | } | ||
87 | |||
88 | mantis->mmio = ioremap(pci_resource_start(pdev, 0), | ||
89 | pci_resource_len(pdev, 0)); | ||
90 | |||
91 | if (!mantis->mmio) { | ||
92 | dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 remap failed !"); | ||
93 | ret = -ENODEV; | ||
94 | goto fail2; | ||
95 | } | ||
96 | |||
97 | pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency); | ||
98 | mantis->latency = latency; | ||
99 | mantis->revision = pdev->revision; | ||
100 | |||
101 | dprintk(MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ", | ||
102 | mantis->revision, | ||
103 | mantis->pdev->subsystem_vendor, | ||
104 | mantis->pdev->subsystem_device); | ||
105 | |||
106 | dprintk(MANTIS_ERROR, 0, | ||
107 | "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n", | ||
108 | mantis->pdev->irq, | ||
109 | mantis->latency, | ||
110 | mantis->mantis_addr, | ||
111 | mantis->mmio); | ||
112 | |||
113 | err = request_irq(pdev->irq, | ||
114 | config->irq_handler, | ||
115 | IRQF_SHARED, | ||
116 | DRIVER_NAME, | ||
117 | mantis); | ||
118 | |||
119 | if (err != 0) { | ||
120 | |||
121 | dprintk(MANTIS_ERROR, 1, "ERROR: IRQ registration failed ! <%d>", err); | ||
122 | ret = -ENODEV; | ||
123 | goto fail3; | ||
124 | } | ||
125 | |||
126 | pci_set_drvdata(pdev, mantis); | ||
127 | return ret; | ||
128 | |||
129 | /* Error conditions */ | ||
130 | fail3: | ||
131 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> I/O unmap", ret); | ||
132 | if (mantis->mmio) | ||
133 | iounmap(mantis->mmio); | ||
134 | |||
135 | fail2: | ||
136 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> releasing regions", ret); | ||
137 | release_mem_region(pci_resource_start(pdev, 0), | ||
138 | pci_resource_len(pdev, 0)); | ||
139 | |||
140 | fail1: | ||
141 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> disabling device", ret); | ||
142 | pci_disable_device(pdev); | ||
143 | |||
144 | fail0: | ||
145 | dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret); | ||
146 | pci_set_drvdata(pdev, NULL); | ||
147 | return ret; | ||
148 | } | ||
149 | EXPORT_SYMBOL_GPL(mantis_pci_init); | ||
150 | |||
151 | void mantis_pci_exit(struct mantis_pci *mantis) | ||
152 | { | ||
153 | struct pci_dev *pdev = mantis->pdev; | ||
154 | |||
155 | dprintk(MANTIS_NOTICE, 1, " mem: 0x%p", mantis->mmio); | ||
156 | free_irq(pdev->irq, mantis); | ||
157 | if (mantis->mmio) { | ||
158 | iounmap(mantis->mmio); | ||
159 | release_mem_region(pci_resource_start(pdev, 0), | ||
160 | pci_resource_len(pdev, 0)); | ||
161 | } | ||
162 | |||
163 | pci_disable_device(pdev); | ||
164 | pci_set_drvdata(pdev, NULL); | ||
165 | } | ||
166 | EXPORT_SYMBOL_GPL(mantis_pci_exit); | ||
167 | |||
168 | MODULE_DESCRIPTION("Mantis PCI DTV bridge driver"); | ||
169 | MODULE_AUTHOR("Manu Abraham"); | ||
170 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/pci/mantis/mantis_pci.h b/drivers/media/pci/mantis/mantis_pci.h new file mode 100644 index 000000000000..65f004519086 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_pci.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | Mantis 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 | #ifndef __MANTIS_PCI_H | ||
22 | #define __MANTIS_PCI_H | ||
23 | |||
24 | extern int mantis_pci_init(struct mantis_pci *mantis); | ||
25 | extern void mantis_pci_exit(struct mantis_pci *mantis); | ||
26 | |||
27 | #endif /* __MANTIS_PCI_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_pcmcia.c b/drivers/media/pci/mantis/mantis_pcmcia.c new file mode 100644 index 000000000000..2f188c089666 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_pcmcia.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | Mantis 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/kernel.h> | ||
22 | |||
23 | #include <linux/signal.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <asm/io.h> | ||
27 | |||
28 | #include "dmxdev.h" | ||
29 | #include "dvbdev.h" | ||
30 | #include "dvb_demux.h" | ||
31 | #include "dvb_frontend.h" | ||
32 | #include "dvb_net.h" | ||
33 | |||
34 | #include "mantis_common.h" | ||
35 | #include "mantis_link.h" /* temporary due to physical layer stuff */ | ||
36 | #include "mantis_reg.h" | ||
37 | |||
38 | /* | ||
39 | * If Slot state is already PLUG_IN event and we are called | ||
40 | * again, definitely it is jitter alone | ||
41 | */ | ||
42 | void mantis_event_cam_plugin(struct mantis_ca *ca) | ||
43 | { | ||
44 | struct mantis_pci *mantis = ca->ca_priv; | ||
45 | |||
46 | u32 gpif_irqcfg; | ||
47 | |||
48 | if (ca->slot_state == MODULE_XTRACTED) { | ||
49 | dprintk(MANTIS_DEBUG, 1, "Event: CAM Plugged IN: Adapter(%d) Slot(0)", mantis->num); | ||
50 | udelay(50); | ||
51 | mmwrite(0xda000000, MANTIS_CARD_RESET); | ||
52 | gpif_irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
53 | gpif_irqcfg |= MANTIS_MASK_PLUGOUT; | ||
54 | gpif_irqcfg &= ~MANTIS_MASK_PLUGIN; | ||
55 | mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG); | ||
56 | udelay(500); | ||
57 | ca->slot_state = MODULE_INSERTED; | ||
58 | } | ||
59 | udelay(100); | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * If Slot state is already UN_PLUG event and we are called | ||
64 | * again, definitely it is jitter alone | ||
65 | */ | ||
66 | void mantis_event_cam_unplug(struct mantis_ca *ca) | ||
67 | { | ||
68 | struct mantis_pci *mantis = ca->ca_priv; | ||
69 | |||
70 | u32 gpif_irqcfg; | ||
71 | |||
72 | if (ca->slot_state == MODULE_INSERTED) { | ||
73 | dprintk(MANTIS_DEBUG, 1, "Event: CAM Unplugged: Adapter(%d) Slot(0)", mantis->num); | ||
74 | udelay(50); | ||
75 | mmwrite(0x00da0000, MANTIS_CARD_RESET); | ||
76 | gpif_irqcfg = mmread(MANTIS_GPIF_IRQCFG); | ||
77 | gpif_irqcfg |= MANTIS_MASK_PLUGIN; | ||
78 | gpif_irqcfg &= ~MANTIS_MASK_PLUGOUT; | ||
79 | mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG); | ||
80 | udelay(500); | ||
81 | ca->slot_state = MODULE_XTRACTED; | ||
82 | } | ||
83 | udelay(100); | ||
84 | } | ||
85 | |||
86 | int mantis_pcmcia_init(struct mantis_ca *ca) | ||
87 | { | ||
88 | struct mantis_pci *mantis = ca->ca_priv; | ||
89 | |||
90 | u32 gpif_stat, card_stat; | ||
91 | |||
92 | mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_IRQ0, MANTIS_INT_MASK); | ||
93 | gpif_stat = mmread(MANTIS_GPIF_STATUS); | ||
94 | card_stat = mmread(MANTIS_GPIF_IRQCFG); | ||
95 | |||
96 | if (gpif_stat & MANTIS_GPIF_DETSTAT) { | ||
97 | dprintk(MANTIS_DEBUG, 1, "CAM found on Adapter(%d) Slot(0)", mantis->num); | ||
98 | mmwrite(card_stat | MANTIS_MASK_PLUGOUT, MANTIS_GPIF_IRQCFG); | ||
99 | ca->slot_state = MODULE_INSERTED; | ||
100 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
101 | 0, | ||
102 | DVB_CA_EN50221_CAMCHANGE_INSERTED); | ||
103 | } else { | ||
104 | dprintk(MANTIS_DEBUG, 1, "Empty Slot on Adapter(%d) Slot(0)", mantis->num); | ||
105 | mmwrite(card_stat | MANTIS_MASK_PLUGIN, MANTIS_GPIF_IRQCFG); | ||
106 | ca->slot_state = MODULE_XTRACTED; | ||
107 | dvb_ca_en50221_camchange_irq(&ca->en50221, | ||
108 | 0, | ||
109 | DVB_CA_EN50221_CAMCHANGE_REMOVED); | ||
110 | } | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | void mantis_pcmcia_exit(struct mantis_ca *ca) | ||
116 | { | ||
117 | struct mantis_pci *mantis = ca->ca_priv; | ||
118 | |||
119 | mmwrite(mmread(MANTIS_GPIF_STATUS) & (~MANTIS_CARD_PLUGOUT | ~MANTIS_CARD_PLUGIN), MANTIS_GPIF_STATUS); | ||
120 | mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ0, MANTIS_INT_MASK); | ||
121 | } | ||
diff --git a/drivers/media/pci/mantis/mantis_reg.h b/drivers/media/pci/mantis/mantis_reg.h new file mode 100644 index 000000000000..7761f9dc7fe0 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_reg.h | |||
@@ -0,0 +1,197 @@ | |||
1 | /* | ||
2 | Mantis 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 | #ifndef __MANTIS_REG_H | ||
22 | #define __MANTIS_REG_H | ||
23 | |||
24 | /* Interrupts */ | ||
25 | #define MANTIS_INT_STAT 0x00 | ||
26 | #define MANTIS_INT_MASK 0x04 | ||
27 | |||
28 | #define MANTIS_INT_RISCSTAT (0x0f << 28) | ||
29 | #define MANTIS_INT_RISCEN (0x01 << 27) | ||
30 | #define MANTIS_INT_I2CRACK (0x01 << 26) | ||
31 | |||
32 | /* #define MANTIS_INT_GPIF (0xff << 12) */ | ||
33 | |||
34 | #define MANTIS_INT_PCMCIA7 (0x01 << 19) | ||
35 | #define MANTIS_INT_PCMCIA6 (0x01 << 18) | ||
36 | #define MANTIS_INT_PCMCIA5 (0x01 << 17) | ||
37 | #define MANTIS_INT_PCMCIA4 (0x01 << 16) | ||
38 | #define MANTIS_INT_PCMCIA3 (0x01 << 15) | ||
39 | #define MANTIS_INT_PCMCIA2 (0x01 << 14) | ||
40 | #define MANTIS_INT_PCMCIA1 (0x01 << 13) | ||
41 | #define MANTIS_INT_PCMCIA0 (0x01 << 12) | ||
42 | #define MANTIS_INT_IRQ1 (0x01 << 11) | ||
43 | #define MANTIS_INT_IRQ0 (0x01 << 10) | ||
44 | #define MANTIS_INT_OCERR (0x01 << 8) | ||
45 | #define MANTIS_INT_PABORT (0x01 << 7) | ||
46 | #define MANTIS_INT_RIPERR (0x01 << 6) | ||
47 | #define MANTIS_INT_PPERR (0x01 << 5) | ||
48 | #define MANTIS_INT_FTRGT (0x01 << 3) | ||
49 | #define MANTIS_INT_RISCI (0x01 << 1) | ||
50 | #define MANTIS_INT_I2CDONE (0x01 << 0) | ||
51 | |||
52 | /* DMA */ | ||
53 | #define MANTIS_DMA_CTL 0x08 | ||
54 | #define MANTIS_GPIF_RD (0xff << 24) | ||
55 | #define MANTIS_GPIF_WR (0xff << 16) | ||
56 | #define MANTIS_CPU_DO (0x01 << 10) | ||
57 | #define MANTIS_DRV_DO (0x01 << 9) | ||
58 | #define MANTIS_I2C_RD (0x01 << 7) | ||
59 | #define MANTIS_I2C_WR (0x01 << 6) | ||
60 | #define MANTIS_DCAP_MODE (0x01 << 5) | ||
61 | #define MANTIS_FIFO_TP_4 (0x00 << 3) | ||
62 | #define MANTIS_FIFO_TP_8 (0x01 << 3) | ||
63 | #define MANTIS_FIFO_TP_16 (0x02 << 3) | ||
64 | #define MANTIS_FIFO_EN (0x01 << 2) | ||
65 | #define MANTIS_DCAP_EN (0x01 << 1) | ||
66 | #define MANTIS_RISC_EN (0x01 << 0) | ||
67 | |||
68 | /* DEBUG */ | ||
69 | #define MANTIS_DEBUGREG 0x0c | ||
70 | #define MANTIS_DATINV (0x0e << 7) | ||
71 | #define MANTIS_TOP_DEBUGSEL (0x07 << 4) | ||
72 | #define MANTIS_PCMCIA_DEBUGSEL (0x0f << 0) | ||
73 | |||
74 | #define MANTIS_RISC_START 0x10 | ||
75 | #define MANTIS_RISC_PC 0x14 | ||
76 | |||
77 | /* I2C */ | ||
78 | #define MANTIS_I2CDATA_CTL 0x18 | ||
79 | #define MANTIS_I2C_RATE_1 (0x00 << 6) | ||
80 | #define MANTIS_I2C_RATE_2 (0x01 << 6) | ||
81 | #define MANTIS_I2C_RATE_3 (0x02 << 6) | ||
82 | #define MANTIS_I2C_RATE_4 (0x03 << 6) | ||
83 | #define MANTIS_I2C_STOP (0x01 << 5) | ||
84 | #define MANTIS_I2C_PGMODE (0x01 << 3) | ||
85 | |||
86 | /* DATA */ | ||
87 | #define MANTIS_CMD_DATA_R1 0x20 | ||
88 | #define MANTIS_CMD_DATA_3 (0xff << 24) | ||
89 | #define MANTIS_CMD_DATA_2 (0xff << 16) | ||
90 | #define MANTIS_CMD_DATA_1 (0xff << 8) | ||
91 | #define MANTIS_CMD_DATA_0 (0xff << 0) | ||
92 | |||
93 | #define MANTIS_CMD_DATA_R2 0x24 | ||
94 | #define MANTIS_CMD_DATA_7 (0xff << 24) | ||
95 | #define MANTIS_CMD_DATA_6 (0xff << 16) | ||
96 | #define MANTIS_CMD_DATA_5 (0xff << 8) | ||
97 | #define MANTIS_CMD_DATA_4 (0xff << 0) | ||
98 | |||
99 | #define MANTIS_CONTROL 0x28 | ||
100 | #define MANTIS_DET (0x01 << 7) | ||
101 | #define MANTIS_DAT_CF_EN (0x01 << 6) | ||
102 | #define MANTIS_ACS (0x03 << 4) | ||
103 | #define MANTIS_VCCEN (0x01 << 3) | ||
104 | #define MANTIS_BYPASS (0x01 << 2) | ||
105 | #define MANTIS_MRST (0x01 << 1) | ||
106 | #define MANTIS_CRST_INT (0x01 << 0) | ||
107 | |||
108 | #define MANTIS_GPIF_CFGSLA 0x84 | ||
109 | #define MANTIS_GPIF_WAITSMPL (0x07 << 28) | ||
110 | #define MANTIS_GPIF_BYTEADDRSUB (0x01 << 25) | ||
111 | #define MANTIS_GPIF_WAITPOL (0x01 << 24) | ||
112 | #define MANTIS_GPIF_NCDELAY (0x07 << 20) | ||
113 | #define MANTIS_GPIF_RW2CSDELAY (0x07 << 16) | ||
114 | #define MANTIS_GPIF_SLFTIMEDMODE (0x01 << 15) | ||
115 | #define MANTIS_GPIF_SLFTIMEDDELY (0x7f << 8) | ||
116 | #define MANTIS_GPIF_DEVTYPE (0x07 << 4) | ||
117 | #define MANTIS_GPIF_BIGENDIAN (0x01 << 3) | ||
118 | #define MANTIS_GPIF_FETCHCMD (0x03 << 1) | ||
119 | #define MANTIS_GPIF_HWORDDEV (0x01 << 0) | ||
120 | |||
121 | #define MANTIS_GPIF_WSTOPER 0x90 | ||
122 | #define MANTIS_GPIF_WSTOPERWREN3 (0x01 << 31) | ||
123 | #define MANTIS_GPIF_PARBOOTN (0x01 << 29) | ||
124 | #define MANTIS_GPIF_WSTOPERSLID3 (0x1f << 24) | ||
125 | #define MANTIS_GPIF_WSTOPERWREN2 (0x01 << 23) | ||
126 | #define MANTIS_GPIF_WSTOPERSLID2 (0x1f << 16) | ||
127 | #define MANTIS_GPIF_WSTOPERWREN1 (0x01 << 15) | ||
128 | #define MANTIS_GPIF_WSTOPERSLID1 (0x1f << 8) | ||
129 | #define MANTIS_GPIF_WSTOPERWREN0 (0x01 << 7) | ||
130 | #define MANTIS_GPIF_WSTOPERSLID0 (0x1f << 0) | ||
131 | |||
132 | #define MANTIS_GPIF_CS2RW 0x94 | ||
133 | #define MANTIS_GPIF_CS2RWWREN3 (0x01 << 31) | ||
134 | #define MANTIS_GPIF_CS2RWDELY3 (0x3f << 24) | ||
135 | #define MANTIS_GPIF_CS2RWWREN2 (0x01 << 23) | ||
136 | #define MANTIS_GPIF_CS2RWDELY2 (0x3f << 16) | ||
137 | #define MANTIS_GPIF_CS2RWWREN1 (0x01 << 15) | ||
138 | #define MANTIS_GPIF_CS2RWDELY1 (0x3f << 8) | ||
139 | #define MANTIS_GPIF_CS2RWWREN0 (0x01 << 7) | ||
140 | #define MANTIS_GPIF_CS2RWDELY0 (0x3f << 0) | ||
141 | |||
142 | #define MANTIS_GPIF_IRQCFG 0x98 | ||
143 | #define MANTIS_GPIF_IRQPOL (0x01 << 8) | ||
144 | #define MANTIS_MASK_WRACK (0x01 << 7) | ||
145 | #define MANTIS_MASK_BRRDY (0x01 << 6) | ||
146 | #define MANTIS_MASK_OVFLW (0x01 << 5) | ||
147 | #define MANTIS_MASK_OTHERR (0x01 << 4) | ||
148 | #define MANTIS_MASK_WSTO (0x01 << 3) | ||
149 | #define MANTIS_MASK_EXTIRQ (0x01 << 2) | ||
150 | #define MANTIS_MASK_PLUGIN (0x01 << 1) | ||
151 | #define MANTIS_MASK_PLUGOUT (0x01 << 0) | ||
152 | |||
153 | #define MANTIS_GPIF_STATUS 0x9c | ||
154 | #define MANTIS_SBUF_KILLOP (0x01 << 15) | ||
155 | #define MANTIS_SBUF_OPDONE (0x01 << 14) | ||
156 | #define MANTIS_SBUF_EMPTY (0x01 << 13) | ||
157 | #define MANTIS_GPIF_DETSTAT (0x01 << 9) | ||
158 | #define MANTIS_GPIF_INTSTAT (0x01 << 8) | ||
159 | #define MANTIS_GPIF_WRACK (0x01 << 7) | ||
160 | #define MANTIS_GPIF_BRRDY (0x01 << 6) | ||
161 | #define MANTIS_SBUF_OVFLW (0x01 << 5) | ||
162 | #define MANTIS_GPIF_OTHERR (0x01 << 4) | ||
163 | #define MANTIS_SBUF_WSTO (0x01 << 3) | ||
164 | #define MANTIS_GPIF_EXTIRQ (0x01 << 2) | ||
165 | #define MANTIS_CARD_PLUGIN (0x01 << 1) | ||
166 | #define MANTIS_CARD_PLUGOUT (0x01 << 0) | ||
167 | |||
168 | #define MANTIS_GPIF_BRADDR 0xa0 | ||
169 | #define MANTIS_GPIF_PCMCIAREG (0x01 << 27) | ||
170 | #define MANTIS_GPIF_PCMCIAIOM (0x01 << 26) | ||
171 | #define MANTIS_GPIF_BR_ADDR (0xfffffff << 0) | ||
172 | |||
173 | #define MANTIS_GPIF_BRBYTES 0xa4 | ||
174 | #define MANTIS_GPIF_BRCNT (0xfff << 0) | ||
175 | |||
176 | #define MANTIS_PCMCIA_RESET 0xa8 | ||
177 | #define MANTIS_PCMCIA_RSTVAL (0xff << 0) | ||
178 | |||
179 | #define MANTIS_CARD_RESET 0xac | ||
180 | |||
181 | #define MANTIS_GPIF_ADDR 0xb0 | ||
182 | #define MANTIS_GPIF_HIFRDWRN (0x01 << 31) | ||
183 | #define MANTIS_GPIF_PCMCIAREG (0x01 << 27) | ||
184 | #define MANTIS_GPIF_PCMCIAIOM (0x01 << 26) | ||
185 | #define MANTIS_GPIF_HIFADDR (0xfffffff << 0) | ||
186 | |||
187 | #define MANTIS_GPIF_DOUT 0xb4 | ||
188 | #define MANTIS_GPIF_HIFDOUT (0xfffffff << 0) | ||
189 | |||
190 | #define MANTIS_GPIF_DIN 0xb8 | ||
191 | #define MANTIS_GPIF_HIFDIN (0xfffffff << 0) | ||
192 | |||
193 | #define MANTIS_GPIF_SPARE 0xbc | ||
194 | #define MANTIS_GPIF_LOGICRD (0xffff << 16) | ||
195 | #define MANTIS_GPIF_LOGICRW (0xffff << 0) | ||
196 | |||
197 | #endif /* __MANTIS_REG_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_uart.c b/drivers/media/pci/mantis/mantis_uart.c new file mode 100644 index 000000000000..18340dafa426 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_uart.c | |||
@@ -0,0 +1,188 @@ | |||
1 | /* | ||
2 | Mantis 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/kernel.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | #include <asm/io.h> | ||
24 | |||
25 | #include <linux/signal.h> | ||
26 | #include <linux/sched.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 "mantis_reg.h" | ||
37 | #include "mantis_uart.h" | ||
38 | |||
39 | struct mantis_uart_params { | ||
40 | enum mantis_baud baud_rate; | ||
41 | enum mantis_parity parity; | ||
42 | }; | ||
43 | |||
44 | static struct { | ||
45 | char string[7]; | ||
46 | } rates[5] = { | ||
47 | { "9600" }, | ||
48 | { "19200" }, | ||
49 | { "38400" }, | ||
50 | { "57600" }, | ||
51 | { "115200" } | ||
52 | }; | ||
53 | |||
54 | static struct { | ||
55 | char string[5]; | ||
56 | } parity[3] = { | ||
57 | { "NONE" }, | ||
58 | { "ODD" }, | ||
59 | { "EVEN" } | ||
60 | }; | ||
61 | |||
62 | #define UART_MAX_BUF 16 | ||
63 | |||
64 | int mantis_uart_read(struct mantis_pci *mantis, u8 *data) | ||
65 | { | ||
66 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
67 | u32 stat = 0, i; | ||
68 | |||
69 | /* get data */ | ||
70 | for (i = 0; i < (config->bytes + 1); i++) { | ||
71 | |||
72 | stat = mmread(MANTIS_UART_STAT); | ||
73 | |||
74 | if (stat & MANTIS_UART_RXFIFO_FULL) { | ||
75 | dprintk(MANTIS_ERROR, 1, "RX Fifo FULL"); | ||
76 | } | ||
77 | data[i] = mmread(MANTIS_UART_RXD) & 0x3f; | ||
78 | |||
79 | dprintk(MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f); | ||
80 | |||
81 | if (data[i] & (1 << 7)) { | ||
82 | dprintk(MANTIS_ERROR, 1, "UART framing error"); | ||
83 | return -EINVAL; | ||
84 | } | ||
85 | if (data[i] & (1 << 6)) { | ||
86 | dprintk(MANTIS_ERROR, 1, "UART parity error"); | ||
87 | return -EINVAL; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static void mantis_uart_work(struct work_struct *work) | ||
95 | { | ||
96 | struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work); | ||
97 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
98 | u8 buf[16]; | ||
99 | int i; | ||
100 | |||
101 | mantis_uart_read(mantis, buf); | ||
102 | |||
103 | for (i = 0; i < (config->bytes + 1); i++) | ||
104 | dprintk(MANTIS_INFO, 1, "UART BUF:%d <%02x> ", i, buf[i]); | ||
105 | |||
106 | dprintk(MANTIS_DEBUG, 0, "\n"); | ||
107 | } | ||
108 | |||
109 | static int mantis_uart_setup(struct mantis_pci *mantis, | ||
110 | struct mantis_uart_params *params) | ||
111 | { | ||
112 | u32 reg; | ||
113 | |||
114 | mmwrite((mmread(MANTIS_UART_CTL) | (params->parity & 0x3)), MANTIS_UART_CTL); | ||
115 | |||
116 | reg = mmread(MANTIS_UART_BAUD); | ||
117 | |||
118 | switch (params->baud_rate) { | ||
119 | case MANTIS_BAUD_9600: | ||
120 | reg |= 0xd8; | ||
121 | break; | ||
122 | case MANTIS_BAUD_19200: | ||
123 | reg |= 0x6c; | ||
124 | break; | ||
125 | case MANTIS_BAUD_38400: | ||
126 | reg |= 0x36; | ||
127 | break; | ||
128 | case MANTIS_BAUD_57600: | ||
129 | reg |= 0x23; | ||
130 | break; | ||
131 | case MANTIS_BAUD_115200: | ||
132 | reg |= 0x11; | ||
133 | break; | ||
134 | default: | ||
135 | return -EINVAL; | ||
136 | } | ||
137 | |||
138 | mmwrite(reg, MANTIS_UART_BAUD); | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | int mantis_uart_init(struct mantis_pci *mantis) | ||
144 | { | ||
145 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
146 | struct mantis_uart_params params; | ||
147 | |||
148 | /* default parity: */ | ||
149 | params.baud_rate = config->baud_rate; | ||
150 | params.parity = config->parity; | ||
151 | dprintk(MANTIS_INFO, 1, "Initializing UART @ %sbps parity:%s", | ||
152 | rates[params.baud_rate].string, | ||
153 | parity[params.parity].string); | ||
154 | |||
155 | init_waitqueue_head(&mantis->uart_wq); | ||
156 | spin_lock_init(&mantis->uart_lock); | ||
157 | |||
158 | INIT_WORK(&mantis->uart_work, mantis_uart_work); | ||
159 | |||
160 | /* disable interrupt */ | ||
161 | mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL); | ||
162 | |||
163 | mantis_uart_setup(mantis, ¶ms); | ||
164 | |||
165 | /* default 1 byte */ | ||
166 | mmwrite((mmread(MANTIS_UART_BAUD) | (config->bytes << 8)), MANTIS_UART_BAUD); | ||
167 | |||
168 | /* flush buffer */ | ||
169 | mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL); | ||
170 | |||
171 | /* enable interrupt */ | ||
172 | mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK); | ||
173 | mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL); | ||
174 | |||
175 | schedule_work(&mantis->uart_work); | ||
176 | dprintk(MANTIS_DEBUG, 1, "UART successfully initialized"); | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | EXPORT_SYMBOL_GPL(mantis_uart_init); | ||
181 | |||
182 | void mantis_uart_exit(struct mantis_pci *mantis) | ||
183 | { | ||
184 | /* disable interrupt */ | ||
185 | mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL); | ||
186 | flush_work_sync(&mantis->uart_work); | ||
187 | } | ||
188 | EXPORT_SYMBOL_GPL(mantis_uart_exit); | ||
diff --git a/drivers/media/pci/mantis/mantis_uart.h b/drivers/media/pci/mantis/mantis_uart.h new file mode 100644 index 000000000000..ffb62a0a5a13 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_uart.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | Mantis 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 | #ifndef __MANTIS_UART_H | ||
22 | #define __MANTIS_UART_H | ||
23 | |||
24 | #define MANTIS_UART_CTL 0xe0 | ||
25 | #define MANTIS_UART_RXINT (1 << 4) | ||
26 | #define MANTIS_UART_RXFLUSH (1 << 2) | ||
27 | |||
28 | #define MANTIS_UART_RXD 0xe8 | ||
29 | #define MANTIS_UART_BAUD 0xec | ||
30 | |||
31 | #define MANTIS_UART_STAT 0xf0 | ||
32 | #define MANTIS_UART_RXFIFO_DATA (1 << 7) | ||
33 | #define MANTIS_UART_RXFIFO_EMPTY (1 << 6) | ||
34 | #define MANTIS_UART_RXFIFO_FULL (1 << 3) | ||
35 | #define MANTIS_UART_FRAME_ERR (1 << 2) | ||
36 | #define MANTIS_UART_PARITY_ERR (1 << 1) | ||
37 | #define MANTIS_UART_RXTHRESH_INT (1 << 0) | ||
38 | |||
39 | enum mantis_baud { | ||
40 | MANTIS_BAUD_9600 = 0, | ||
41 | MANTIS_BAUD_19200, | ||
42 | MANTIS_BAUD_38400, | ||
43 | MANTIS_BAUD_57600, | ||
44 | MANTIS_BAUD_115200 | ||
45 | }; | ||
46 | |||
47 | enum mantis_parity { | ||
48 | MANTIS_PARITY_NONE = 0, | ||
49 | MANTIS_PARITY_EVEN, | ||
50 | MANTIS_PARITY_ODD, | ||
51 | }; | ||
52 | |||
53 | struct mantis_pci; | ||
54 | |||
55 | extern int mantis_uart_init(struct mantis_pci *mantis); | ||
56 | extern void mantis_uart_exit(struct mantis_pci *mantis); | ||
57 | |||
58 | #endif /* __MANTIS_UART_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_vp1033.c b/drivers/media/pci/mantis/mantis_vp1033.c new file mode 100644 index 000000000000..ad013e93ed11 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_vp1033.c | |||
@@ -0,0 +1,212 @@ | |||
1 | /* | ||
2 | Mantis VP-1033 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/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "stv0299.h" | ||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_ioc.h" | ||
34 | #include "mantis_dvb.h" | ||
35 | #include "mantis_vp1033.h" | ||
36 | #include "mantis_reg.h" | ||
37 | |||
38 | u8 lgtdqcs001f_inittab[] = { | ||
39 | 0x01, 0x15, | ||
40 | 0x02, 0x30, | ||
41 | 0x03, 0x00, | ||
42 | 0x04, 0x2a, | ||
43 | 0x05, 0x85, | ||
44 | 0x06, 0x02, | ||
45 | 0x07, 0x00, | ||
46 | 0x08, 0x00, | ||
47 | 0x0c, 0x01, | ||
48 | 0x0d, 0x81, | ||
49 | 0x0e, 0x44, | ||
50 | 0x0f, 0x94, | ||
51 | 0x10, 0x3c, | ||
52 | 0x11, 0x84, | ||
53 | 0x12, 0xb9, | ||
54 | 0x13, 0xb5, | ||
55 | 0x14, 0x4f, | ||
56 | 0x15, 0xc9, | ||
57 | 0x16, 0x80, | ||
58 | 0x17, 0x36, | ||
59 | 0x18, 0xfb, | ||
60 | 0x19, 0xcf, | ||
61 | 0x1a, 0xbc, | ||
62 | 0x1c, 0x2b, | ||
63 | 0x1d, 0x27, | ||
64 | 0x1e, 0x00, | ||
65 | 0x1f, 0x0b, | ||
66 | 0x20, 0xa1, | ||
67 | 0x21, 0x60, | ||
68 | 0x22, 0x00, | ||
69 | 0x23, 0x00, | ||
70 | 0x28, 0x00, | ||
71 | 0x29, 0x28, | ||
72 | 0x2a, 0x14, | ||
73 | 0x2b, 0x0f, | ||
74 | 0x2c, 0x09, | ||
75 | 0x2d, 0x05, | ||
76 | 0x31, 0x1f, | ||
77 | 0x32, 0x19, | ||
78 | 0x33, 0xfc, | ||
79 | 0x34, 0x13, | ||
80 | 0xff, 0xff, | ||
81 | }; | ||
82 | |||
83 | #define MANTIS_MODEL_NAME "VP-1033" | ||
84 | #define MANTIS_DEV_TYPE "DVB-S/DSS" | ||
85 | |||
86 | int lgtdqcs001f_tuner_set(struct dvb_frontend *fe) | ||
87 | { | ||
88 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
89 | struct mantis_pci *mantis = fe->dvb->priv; | ||
90 | struct i2c_adapter *adapter = &mantis->adapter; | ||
91 | |||
92 | u8 buf[4]; | ||
93 | u32 div; | ||
94 | |||
95 | |||
96 | struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf)}; | ||
97 | |||
98 | div = p->frequency / 250; | ||
99 | |||
100 | buf[0] = (div >> 8) & 0x7f; | ||
101 | buf[1] = div & 0xff; | ||
102 | buf[2] = 0x83; | ||
103 | buf[3] = 0xc0; | ||
104 | |||
105 | if (p->frequency < 1531000) | ||
106 | buf[3] |= 0x04; | ||
107 | else | ||
108 | buf[3] &= ~0x04; | ||
109 | if (i2c_transfer(adapter, &msg, 1) < 0) { | ||
110 | dprintk(MANTIS_ERROR, 1, "Write: I2C Transfer failed"); | ||
111 | return -EIO; | ||
112 | } | ||
113 | msleep_interruptible(100); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | int lgtdqcs001f_set_symbol_rate(struct dvb_frontend *fe, | ||
119 | u32 srate, u32 ratio) | ||
120 | { | ||
121 | u8 aclk = 0; | ||
122 | u8 bclk = 0; | ||
123 | |||
124 | if (srate < 1500000) { | ||
125 | aclk = 0xb7; | ||
126 | bclk = 0x47; | ||
127 | } else if (srate < 3000000) { | ||
128 | aclk = 0xb7; | ||
129 | bclk = 0x4b; | ||
130 | } else if (srate < 7000000) { | ||
131 | aclk = 0xb7; | ||
132 | bclk = 0x4f; | ||
133 | } else if (srate < 14000000) { | ||
134 | aclk = 0xb7; | ||
135 | bclk = 0x53; | ||
136 | } else if (srate < 30000000) { | ||
137 | aclk = 0xb6; | ||
138 | bclk = 0x53; | ||
139 | } else if (srate < 45000000) { | ||
140 | aclk = 0xb4; | ||
141 | bclk = 0x51; | ||
142 | } | ||
143 | stv0299_writereg(fe, 0x13, aclk); | ||
144 | stv0299_writereg(fe, 0x14, bclk); | ||
145 | |||
146 | stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); | ||
147 | stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); | ||
148 | stv0299_writereg(fe, 0x21, ratio & 0xf0); | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | struct stv0299_config lgtdqcs001f_config = { | ||
154 | .demod_address = 0x68, | ||
155 | .inittab = lgtdqcs001f_inittab, | ||
156 | .mclk = 88000000UL, | ||
157 | .invert = 0, | ||
158 | .skip_reinit = 0, | ||
159 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | ||
160 | .min_delay_ms = 100, | ||
161 | .set_symbol_rate = lgtdqcs001f_set_symbol_rate, | ||
162 | }; | ||
163 | |||
164 | static int vp1033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
165 | { | ||
166 | struct i2c_adapter *adapter = &mantis->adapter; | ||
167 | |||
168 | int err = 0; | ||
169 | |||
170 | err = mantis_frontend_power(mantis, POWER_ON); | ||
171 | if (err == 0) { | ||
172 | mantis_frontend_soft_reset(mantis); | ||
173 | msleep(250); | ||
174 | |||
175 | dprintk(MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)"); | ||
176 | fe = dvb_attach(stv0299_attach, &lgtdqcs001f_config, adapter); | ||
177 | |||
178 | if (fe) { | ||
179 | fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set; | ||
180 | dprintk(MANTIS_ERROR, 1, "found STV0299 DVB-S frontend @ 0x%02x", | ||
181 | lgtdqcs001f_config.demod_address); | ||
182 | |||
183 | dprintk(MANTIS_ERROR, 1, "Mantis DVB-S STV0299 frontend attach success"); | ||
184 | } else { | ||
185 | return -1; | ||
186 | } | ||
187 | } else { | ||
188 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
189 | adapter->name, | ||
190 | err); | ||
191 | |||
192 | return -EIO; | ||
193 | } | ||
194 | mantis->fe = fe; | ||
195 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | struct mantis_hwconfig vp1033_config = { | ||
201 | .model_name = MANTIS_MODEL_NAME, | ||
202 | .dev_type = MANTIS_DEV_TYPE, | ||
203 | .ts_size = MANTIS_TS_204, | ||
204 | |||
205 | .baud_rate = MANTIS_BAUD_9600, | ||
206 | .parity = MANTIS_PARITY_NONE, | ||
207 | .bytes = 0, | ||
208 | |||
209 | .frontend_init = vp1033_frontend_init, | ||
210 | .power = GPIF_A12, | ||
211 | .reset = GPIF_A13, | ||
212 | }; | ||
diff --git a/drivers/media/pci/mantis/mantis_vp1033.h b/drivers/media/pci/mantis/mantis_vp1033.h new file mode 100644 index 000000000000..7daaa1bf127d --- /dev/null +++ b/drivers/media/pci/mantis/mantis_vp1033.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | Mantis VP-1033 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 | #ifndef __MANTIS_VP1033_H | ||
22 | #define __MANTIS_VP1033_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_1033_DVB_S 0x0016 | ||
27 | |||
28 | extern struct mantis_hwconfig vp1033_config; | ||
29 | |||
30 | #endif /* __MANTIS_VP1033_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_vp1034.c b/drivers/media/pci/mantis/mantis_vp1034.c new file mode 100644 index 000000000000..430ae84ce528 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_vp1034.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | Mantis VP-1034 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/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <asm/io.h> | ||
25 | |||
26 | #include "dmxdev.h" | ||
27 | #include "dvbdev.h" | ||
28 | #include "dvb_demux.h" | ||
29 | #include "dvb_frontend.h" | ||
30 | #include "dvb_net.h" | ||
31 | |||
32 | #include "mb86a16.h" | ||
33 | #include "mantis_common.h" | ||
34 | #include "mantis_ioc.h" | ||
35 | #include "mantis_dvb.h" | ||
36 | #include "mantis_vp1034.h" | ||
37 | #include "mantis_reg.h" | ||
38 | |||
39 | struct mb86a16_config vp1034_mb86a16_config = { | ||
40 | .demod_address = 0x08, | ||
41 | .set_voltage = vp1034_set_voltage, | ||
42 | }; | ||
43 | |||
44 | #define MANTIS_MODEL_NAME "VP-1034" | ||
45 | #define MANTIS_DEV_TYPE "DVB-S/DSS" | ||
46 | |||
47 | int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
48 | { | ||
49 | struct mantis_pci *mantis = fe->dvb->priv; | ||
50 | |||
51 | switch (voltage) { | ||
52 | case SEC_VOLTAGE_13: | ||
53 | dprintk(MANTIS_ERROR, 1, "Polarization=[13V]"); | ||
54 | mantis_gpio_set_bits(mantis, 13, 1); | ||
55 | mantis_gpio_set_bits(mantis, 14, 0); | ||
56 | break; | ||
57 | case SEC_VOLTAGE_18: | ||
58 | dprintk(MANTIS_ERROR, 1, "Polarization=[18V]"); | ||
59 | mantis_gpio_set_bits(mantis, 13, 1); | ||
60 | mantis_gpio_set_bits(mantis, 14, 1); | ||
61 | break; | ||
62 | case SEC_VOLTAGE_OFF: | ||
63 | dprintk(MANTIS_ERROR, 1, "Frontend (dummy) POWERDOWN"); | ||
64 | break; | ||
65 | default: | ||
66 | dprintk(MANTIS_ERROR, 1, "Invalid = (%d)", (u32) voltage); | ||
67 | return -EINVAL; | ||
68 | } | ||
69 | mmwrite(0x00, MANTIS_GPIF_DOUT); | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static int vp1034_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
75 | { | ||
76 | struct i2c_adapter *adapter = &mantis->adapter; | ||
77 | |||
78 | int err = 0; | ||
79 | |||
80 | err = mantis_frontend_power(mantis, POWER_ON); | ||
81 | if (err == 0) { | ||
82 | mantis_frontend_soft_reset(mantis); | ||
83 | msleep(250); | ||
84 | |||
85 | dprintk(MANTIS_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)"); | ||
86 | fe = dvb_attach(mb86a16_attach, &vp1034_mb86a16_config, adapter); | ||
87 | if (fe) { | ||
88 | dprintk(MANTIS_ERROR, 1, | ||
89 | "found MB86A16 DVB-S/DSS frontend @0x%02x", | ||
90 | vp1034_mb86a16_config.demod_address); | ||
91 | |||
92 | } else { | ||
93 | return -1; | ||
94 | } | ||
95 | } else { | ||
96 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
97 | adapter->name, | ||
98 | err); | ||
99 | |||
100 | return -EIO; | ||
101 | } | ||
102 | mantis->fe = fe; | ||
103 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | struct mantis_hwconfig vp1034_config = { | ||
109 | .model_name = MANTIS_MODEL_NAME, | ||
110 | .dev_type = MANTIS_DEV_TYPE, | ||
111 | .ts_size = MANTIS_TS_204, | ||
112 | |||
113 | .baud_rate = MANTIS_BAUD_9600, | ||
114 | .parity = MANTIS_PARITY_NONE, | ||
115 | .bytes = 0, | ||
116 | |||
117 | .frontend_init = vp1034_frontend_init, | ||
118 | .power = GPIF_A12, | ||
119 | .reset = GPIF_A13, | ||
120 | }; | ||
diff --git a/drivers/media/pci/mantis/mantis_vp1034.h b/drivers/media/pci/mantis/mantis_vp1034.h new file mode 100644 index 000000000000..323f38ef8e3d --- /dev/null +++ b/drivers/media/pci/mantis/mantis_vp1034.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | Mantis VP-1034 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 | #ifndef __MANTIS_VP1034_H | ||
22 | #define __MANTIS_VP1034_H | ||
23 | |||
24 | #include "dvb_frontend.h" | ||
25 | #include "mantis_common.h" | ||
26 | |||
27 | |||
28 | #define MANTIS_VP_1034_DVB_S 0x0014 | ||
29 | |||
30 | extern struct mantis_hwconfig vp1034_config; | ||
31 | extern int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage); | ||
32 | |||
33 | #endif /* __MANTIS_VP1034_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_vp1041.c b/drivers/media/pci/mantis/mantis_vp1041.c new file mode 100644 index 000000000000..07aa887a4b4a --- /dev/null +++ b/drivers/media/pci/mantis/mantis_vp1041.c | |||
@@ -0,0 +1,357 @@ | |||
1 | /* | ||
2 | Mantis VP-1041 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/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "mantis_common.h" | ||
32 | #include "mantis_ioc.h" | ||
33 | #include "mantis_dvb.h" | ||
34 | #include "mantis_vp1041.h" | ||
35 | #include "stb0899_reg.h" | ||
36 | #include "stb0899_drv.h" | ||
37 | #include "stb0899_cfg.h" | ||
38 | #include "stb6100_cfg.h" | ||
39 | #include "stb6100.h" | ||
40 | #include "lnbp21.h" | ||
41 | |||
42 | #define MANTIS_MODEL_NAME "VP-1041" | ||
43 | #define MANTIS_DEV_TYPE "DSS/DVB-S/DVB-S2" | ||
44 | |||
45 | static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = { | ||
46 | |||
47 | /* 0x0000000b, *//* SYSREG */ | ||
48 | { STB0899_DEV_ID , 0x30 }, | ||
49 | { STB0899_DISCNTRL1 , 0x32 }, | ||
50 | { STB0899_DISCNTRL2 , 0x80 }, | ||
51 | { STB0899_DISRX_ST0 , 0x04 }, | ||
52 | { STB0899_DISRX_ST1 , 0x00 }, | ||
53 | { STB0899_DISPARITY , 0x00 }, | ||
54 | { STB0899_DISSTATUS , 0x20 }, | ||
55 | { STB0899_DISF22 , 0x99 }, | ||
56 | { STB0899_DISF22RX , 0xa8 }, | ||
57 | /* SYSREG ? */ | ||
58 | { STB0899_ACRPRESC , 0x11 }, | ||
59 | { STB0899_ACRDIV1 , 0x0a }, | ||
60 | { STB0899_ACRDIV2 , 0x05 }, | ||
61 | { STB0899_DACR1 , 0x00 }, | ||
62 | { STB0899_DACR2 , 0x00 }, | ||
63 | { STB0899_OUTCFG , 0x00 }, | ||
64 | { STB0899_MODECFG , 0x00 }, | ||
65 | { STB0899_IRQSTATUS_3 , 0xfe }, | ||
66 | { STB0899_IRQSTATUS_2 , 0x03 }, | ||
67 | { STB0899_IRQSTATUS_1 , 0x7c }, | ||
68 | { STB0899_IRQSTATUS_0 , 0xf4 }, | ||
69 | { STB0899_IRQMSK_3 , 0xf3 }, | ||
70 | { STB0899_IRQMSK_2 , 0xfc }, | ||
71 | { STB0899_IRQMSK_1 , 0xff }, | ||
72 | { STB0899_IRQMSK_0 , 0xff }, | ||
73 | { STB0899_IRQCFG , 0x00 }, | ||
74 | { STB0899_I2CCFG , 0x88 }, | ||
75 | { STB0899_I2CRPT , 0x58 }, | ||
76 | { STB0899_IOPVALUE5 , 0x00 }, | ||
77 | { STB0899_IOPVALUE4 , 0x33 }, | ||
78 | { STB0899_IOPVALUE3 , 0x6d }, | ||
79 | { STB0899_IOPVALUE2 , 0x90 }, | ||
80 | { STB0899_IOPVALUE1 , 0x60 }, | ||
81 | { STB0899_IOPVALUE0 , 0x00 }, | ||
82 | { STB0899_GPIO00CFG , 0x82 }, | ||
83 | { STB0899_GPIO01CFG , 0x82 }, | ||
84 | { STB0899_GPIO02CFG , 0x82 }, | ||
85 | { STB0899_GPIO03CFG , 0x82 }, | ||
86 | { STB0899_GPIO04CFG , 0x82 }, | ||
87 | { STB0899_GPIO05CFG , 0x82 }, | ||
88 | { STB0899_GPIO06CFG , 0x82 }, | ||
89 | { STB0899_GPIO07CFG , 0x82 }, | ||
90 | { STB0899_GPIO08CFG , 0x82 }, | ||
91 | { STB0899_GPIO09CFG , 0x82 }, | ||
92 | { STB0899_GPIO10CFG , 0x82 }, | ||
93 | { STB0899_GPIO11CFG , 0x82 }, | ||
94 | { STB0899_GPIO12CFG , 0x82 }, | ||
95 | { STB0899_GPIO13CFG , 0x82 }, | ||
96 | { STB0899_GPIO14CFG , 0x82 }, | ||
97 | { STB0899_GPIO15CFG , 0x82 }, | ||
98 | { STB0899_GPIO16CFG , 0x82 }, | ||
99 | { STB0899_GPIO17CFG , 0x82 }, | ||
100 | { STB0899_GPIO18CFG , 0x82 }, | ||
101 | { STB0899_GPIO19CFG , 0x82 }, | ||
102 | { STB0899_GPIO20CFG , 0x82 }, | ||
103 | { STB0899_SDATCFG , 0xb8 }, | ||
104 | { STB0899_SCLTCFG , 0xba }, | ||
105 | { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ | ||
106 | { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ | ||
107 | { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ | ||
108 | { STB0899_DIRCLKCFG , 0x82 }, | ||
109 | { STB0899_CLKOUT27CFG , 0x7e }, | ||
110 | { STB0899_STDBYCFG , 0x82 }, | ||
111 | { STB0899_CS0CFG , 0x82 }, | ||
112 | { STB0899_CS1CFG , 0x82 }, | ||
113 | { STB0899_DISEQCOCFG , 0x20 }, | ||
114 | { STB0899_GPIO32CFG , 0x82 }, | ||
115 | { STB0899_GPIO33CFG , 0x82 }, | ||
116 | { STB0899_GPIO34CFG , 0x82 }, | ||
117 | { STB0899_GPIO35CFG , 0x82 }, | ||
118 | { STB0899_GPIO36CFG , 0x82 }, | ||
119 | { STB0899_GPIO37CFG , 0x82 }, | ||
120 | { STB0899_GPIO38CFG , 0x82 }, | ||
121 | { STB0899_GPIO39CFG , 0x82 }, | ||
122 | { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ | ||
123 | { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ | ||
124 | { STB0899_FILTCTRL , 0x00 }, | ||
125 | { STB0899_SYSCTRL , 0x01 }, | ||
126 | { STB0899_STOPCLK1 , 0x20 }, | ||
127 | { STB0899_STOPCLK2 , 0x00 }, | ||
128 | { STB0899_INTBUFSTATUS , 0x00 }, | ||
129 | { STB0899_INTBUFCTRL , 0x0a }, | ||
130 | { 0xffff , 0xff }, | ||
131 | }; | ||
132 | |||
133 | static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = { | ||
134 | { STB0899_DEMOD , 0x00 }, | ||
135 | { STB0899_RCOMPC , 0xc9 }, | ||
136 | { STB0899_AGC1CN , 0x01 }, | ||
137 | { STB0899_AGC1REF , 0x10 }, | ||
138 | { STB0899_RTC , 0x23 }, | ||
139 | { STB0899_TMGCFG , 0x4e }, | ||
140 | { STB0899_AGC2REF , 0x34 }, | ||
141 | { STB0899_TLSR , 0x84 }, | ||
142 | { STB0899_CFD , 0xf7 }, | ||
143 | { STB0899_ACLC , 0x87 }, | ||
144 | { STB0899_BCLC , 0x94 }, | ||
145 | { STB0899_EQON , 0x41 }, | ||
146 | { STB0899_LDT , 0xf1 }, | ||
147 | { STB0899_LDT2 , 0xe3 }, | ||
148 | { STB0899_EQUALREF , 0xb4 }, | ||
149 | { STB0899_TMGRAMP , 0x10 }, | ||
150 | { STB0899_TMGTHD , 0x30 }, | ||
151 | { STB0899_IDCCOMP , 0xfd }, | ||
152 | { STB0899_QDCCOMP , 0xff }, | ||
153 | { STB0899_POWERI , 0x0c }, | ||
154 | { STB0899_POWERQ , 0x0f }, | ||
155 | { STB0899_RCOMP , 0x6c }, | ||
156 | { STB0899_AGCIQIN , 0x80 }, | ||
157 | { STB0899_AGC2I1 , 0x06 }, | ||
158 | { STB0899_AGC2I2 , 0x00 }, | ||
159 | { STB0899_TLIR , 0x30 }, | ||
160 | { STB0899_RTF , 0x7f }, | ||
161 | { STB0899_DSTATUS , 0x00 }, | ||
162 | { STB0899_LDI , 0xbc }, | ||
163 | { STB0899_CFRM , 0xea }, | ||
164 | { STB0899_CFRL , 0x31 }, | ||
165 | { STB0899_NIRM , 0x2b }, | ||
166 | { STB0899_NIRL , 0x80 }, | ||
167 | { STB0899_ISYMB , 0x1d }, | ||
168 | { STB0899_QSYMB , 0xa6 }, | ||
169 | { STB0899_SFRH , 0x2f }, | ||
170 | { STB0899_SFRM , 0x68 }, | ||
171 | { STB0899_SFRL , 0x40 }, | ||
172 | { STB0899_SFRUPH , 0x2f }, | ||
173 | { STB0899_SFRUPM , 0x68 }, | ||
174 | { STB0899_SFRUPL , 0x40 }, | ||
175 | { STB0899_EQUAI1 , 0x02 }, | ||
176 | { STB0899_EQUAQ1 , 0xff }, | ||
177 | { STB0899_EQUAI2 , 0x04 }, | ||
178 | { STB0899_EQUAQ2 , 0x05 }, | ||
179 | { STB0899_EQUAI3 , 0x02 }, | ||
180 | { STB0899_EQUAQ3 , 0xfd }, | ||
181 | { STB0899_EQUAI4 , 0x03 }, | ||
182 | { STB0899_EQUAQ4 , 0x07 }, | ||
183 | { STB0899_EQUAI5 , 0x08 }, | ||
184 | { STB0899_EQUAQ5 , 0xf5 }, | ||
185 | { STB0899_DSTATUS2 , 0x00 }, | ||
186 | { STB0899_VSTATUS , 0x00 }, | ||
187 | { STB0899_VERROR , 0x86 }, | ||
188 | { STB0899_IQSWAP , 0x2a }, | ||
189 | { STB0899_ECNT1M , 0x00 }, | ||
190 | { STB0899_ECNT1L , 0x00 }, | ||
191 | { STB0899_ECNT2M , 0x00 }, | ||
192 | { STB0899_ECNT2L , 0x00 }, | ||
193 | { STB0899_ECNT3M , 0x0a }, | ||
194 | { STB0899_ECNT3L , 0xad }, | ||
195 | { STB0899_FECAUTO1 , 0x06 }, | ||
196 | { STB0899_FECM , 0x01 }, | ||
197 | { STB0899_VTH12 , 0xb0 }, | ||
198 | { STB0899_VTH23 , 0x7a }, | ||
199 | { STB0899_VTH34 , 0x58 }, | ||
200 | { STB0899_VTH56 , 0x38 }, | ||
201 | { STB0899_VTH67 , 0x34 }, | ||
202 | { STB0899_VTH78 , 0x24 }, | ||
203 | { STB0899_PRVIT , 0xff }, | ||
204 | { STB0899_VITSYNC , 0x19 }, | ||
205 | { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ | ||
206 | { STB0899_TSULC , 0x42 }, | ||
207 | { STB0899_RSLLC , 0x41 }, | ||
208 | { STB0899_TSLPL , 0x12 }, | ||
209 | { STB0899_TSCFGH , 0x0c }, | ||
210 | { STB0899_TSCFGM , 0x00 }, | ||
211 | { STB0899_TSCFGL , 0x00 }, | ||
212 | { STB0899_TSOUT , 0x69 }, /* 0x0d for CAM */ | ||
213 | { STB0899_RSSYNCDEL , 0x00 }, | ||
214 | { STB0899_TSINHDELH , 0x02 }, | ||
215 | { STB0899_TSINHDELM , 0x00 }, | ||
216 | { STB0899_TSINHDELL , 0x00 }, | ||
217 | { STB0899_TSLLSTKM , 0x1b }, | ||
218 | { STB0899_TSLLSTKL , 0xb3 }, | ||
219 | { STB0899_TSULSTKM , 0x00 }, | ||
220 | { STB0899_TSULSTKL , 0x00 }, | ||
221 | { STB0899_PCKLENUL , 0xbc }, | ||
222 | { STB0899_PCKLENLL , 0xcc }, | ||
223 | { STB0899_RSPCKLEN , 0xbd }, | ||
224 | { STB0899_TSSTATUS , 0x90 }, | ||
225 | { STB0899_ERRCTRL1 , 0xb6 }, | ||
226 | { STB0899_ERRCTRL2 , 0x95 }, | ||
227 | { STB0899_ERRCTRL3 , 0x8d }, | ||
228 | { STB0899_DMONMSK1 , 0x27 }, | ||
229 | { STB0899_DMONMSK0 , 0x03 }, | ||
230 | { STB0899_DEMAPVIT , 0x5c }, | ||
231 | { STB0899_PLPARM , 0x19 }, | ||
232 | { STB0899_PDELCTRL , 0x48 }, | ||
233 | { STB0899_PDELCTRL2 , 0x00 }, | ||
234 | { STB0899_BBHCTRL1 , 0x00 }, | ||
235 | { STB0899_BBHCTRL2 , 0x00 }, | ||
236 | { STB0899_HYSTTHRESH , 0x77 }, | ||
237 | { STB0899_MATCSTM , 0x00 }, | ||
238 | { STB0899_MATCSTL , 0x00 }, | ||
239 | { STB0899_UPLCSTM , 0x00 }, | ||
240 | { STB0899_UPLCSTL , 0x00 }, | ||
241 | { STB0899_DFLCSTM , 0x00 }, | ||
242 | { STB0899_DFLCSTL , 0x00 }, | ||
243 | { STB0899_SYNCCST , 0x00 }, | ||
244 | { STB0899_SYNCDCSTM , 0x00 }, | ||
245 | { STB0899_SYNCDCSTL , 0x00 }, | ||
246 | { STB0899_ISI_ENTRY , 0x00 }, | ||
247 | { STB0899_ISI_BIT_EN , 0x00 }, | ||
248 | { STB0899_MATSTRM , 0xf0 }, | ||
249 | { STB0899_MATSTRL , 0x02 }, | ||
250 | { STB0899_UPLSTRM , 0x45 }, | ||
251 | { STB0899_UPLSTRL , 0x60 }, | ||
252 | { STB0899_DFLSTRM , 0xe3 }, | ||
253 | { STB0899_DFLSTRL , 0x00 }, | ||
254 | { STB0899_SYNCSTR , 0x47 }, | ||
255 | { STB0899_SYNCDSTRM , 0x05 }, | ||
256 | { STB0899_SYNCDSTRL , 0x18 }, | ||
257 | { STB0899_CFGPDELSTATUS1 , 0x19 }, | ||
258 | { STB0899_CFGPDELSTATUS2 , 0x2b }, | ||
259 | { STB0899_BBFERRORM , 0x00 }, | ||
260 | { STB0899_BBFERRORL , 0x01 }, | ||
261 | { STB0899_UPKTERRORM , 0x00 }, | ||
262 | { STB0899_UPKTERRORL , 0x00 }, | ||
263 | { 0xffff , 0xff }, | ||
264 | }; | ||
265 | |||
266 | struct stb0899_config vp1041_stb0899_config = { | ||
267 | .init_dev = vp1041_stb0899_s1_init_1, | ||
268 | .init_s2_demod = stb0899_s2_init_2, | ||
269 | .init_s1_demod = vp1041_stb0899_s1_init_3, | ||
270 | .init_s2_fec = stb0899_s2_init_4, | ||
271 | .init_tst = stb0899_s1_init_5, | ||
272 | |||
273 | .demod_address = 0x68, /* 0xd0 >> 1 */ | ||
274 | |||
275 | .xtal_freq = 27000000, | ||
276 | .inversion = IQ_SWAP_ON, /* 1 */ | ||
277 | |||
278 | .lo_clk = 76500000, | ||
279 | .hi_clk = 99000000, | ||
280 | |||
281 | .esno_ave = STB0899_DVBS2_ESNO_AVE, | ||
282 | .esno_quant = STB0899_DVBS2_ESNO_QUANT, | ||
283 | .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE, | ||
284 | .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE, | ||
285 | .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD, | ||
286 | .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ, | ||
287 | .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK, | ||
288 | .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF, | ||
289 | .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT, | ||
290 | |||
291 | .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS, | ||
292 | .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET, | ||
293 | .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS, | ||
294 | .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER, | ||
295 | |||
296 | .tuner_get_frequency = stb6100_get_frequency, | ||
297 | .tuner_set_frequency = stb6100_set_frequency, | ||
298 | .tuner_set_bandwidth = stb6100_set_bandwidth, | ||
299 | .tuner_get_bandwidth = stb6100_get_bandwidth, | ||
300 | .tuner_set_rfsiggain = NULL, | ||
301 | }; | ||
302 | |||
303 | struct stb6100_config vp1041_stb6100_config = { | ||
304 | .tuner_address = 0x60, | ||
305 | .refclock = 27000000, | ||
306 | }; | ||
307 | |||
308 | static int vp1041_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
309 | { | ||
310 | struct i2c_adapter *adapter = &mantis->adapter; | ||
311 | |||
312 | int err = 0; | ||
313 | |||
314 | err = mantis_frontend_power(mantis, POWER_ON); | ||
315 | if (err == 0) { | ||
316 | mantis_frontend_soft_reset(mantis); | ||
317 | msleep(250); | ||
318 | mantis->fe = dvb_attach(stb0899_attach, &vp1041_stb0899_config, adapter); | ||
319 | if (mantis->fe) { | ||
320 | dprintk(MANTIS_ERROR, 1, | ||
321 | "found STB0899 DVB-S/DVB-S2 frontend @0x%02x", | ||
322 | vp1041_stb0899_config.demod_address); | ||
323 | |||
324 | if (dvb_attach(stb6100_attach, mantis->fe, &vp1041_stb6100_config, adapter)) { | ||
325 | if (!dvb_attach(lnbp21_attach, mantis->fe, adapter, 0, 0)) | ||
326 | dprintk(MANTIS_ERROR, 1, "No LNBP21 found!"); | ||
327 | } | ||
328 | } else { | ||
329 | return -EREMOTEIO; | ||
330 | } | ||
331 | } else { | ||
332 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
333 | adapter->name, | ||
334 | err); | ||
335 | |||
336 | return -EIO; | ||
337 | } | ||
338 | |||
339 | |||
340 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
341 | |||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | struct mantis_hwconfig vp1041_config = { | ||
346 | .model_name = MANTIS_MODEL_NAME, | ||
347 | .dev_type = MANTIS_DEV_TYPE, | ||
348 | .ts_size = MANTIS_TS_188, | ||
349 | |||
350 | .baud_rate = MANTIS_BAUD_9600, | ||
351 | .parity = MANTIS_PARITY_NONE, | ||
352 | .bytes = 0, | ||
353 | |||
354 | .frontend_init = vp1041_frontend_init, | ||
355 | .power = GPIF_A12, | ||
356 | .reset = GPIF_A13, | ||
357 | }; | ||
diff --git a/drivers/media/pci/mantis/mantis_vp1041.h b/drivers/media/pci/mantis/mantis_vp1041.h new file mode 100644 index 000000000000..1ae5b3de8081 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_vp1041.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | Mantis VP-1041 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 | #ifndef __MANTIS_VP1041_H | ||
22 | #define __MANTIS_VP1041_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_1041_DVB_S2 0x0031 | ||
27 | #define SKYSTAR_HD2_10 0x0001 | ||
28 | #define SKYSTAR_HD2_20 0x0003 | ||
29 | #define CINERGY_S2_PCI_HD 0x1179 | ||
30 | |||
31 | extern struct mantis_hwconfig vp1041_config; | ||
32 | |||
33 | #endif /* __MANTIS_VP1041_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_vp2033.c b/drivers/media/pci/mantis/mantis_vp2033.c new file mode 100644 index 000000000000..1ca6837fbe46 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_vp2033.c | |||
@@ -0,0 +1,188 @@ | |||
1 | /* | ||
2 | Mantis VP-2033 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/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "tda1002x.h" | ||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_ioc.h" | ||
34 | #include "mantis_dvb.h" | ||
35 | #include "mantis_vp2033.h" | ||
36 | |||
37 | #define MANTIS_MODEL_NAME "VP-2033" | ||
38 | #define MANTIS_DEV_TYPE "DVB-C" | ||
39 | |||
40 | struct tda1002x_config vp2033_tda1002x_cu1216_config = { | ||
41 | .demod_address = 0x18 >> 1, | ||
42 | .invert = 1, | ||
43 | }; | ||
44 | |||
45 | struct tda10023_config vp2033_tda10023_cu1216_config = { | ||
46 | .demod_address = 0x18 >> 1, | ||
47 | .invert = 1, | ||
48 | }; | ||
49 | |||
50 | static u8 read_pwm(struct mantis_pci *mantis) | ||
51 | { | ||
52 | struct i2c_adapter *adapter = &mantis->adapter; | ||
53 | |||
54 | u8 b = 0xff; | ||
55 | u8 pwm; | ||
56 | struct i2c_msg msg[] = { | ||
57 | {.addr = 0x50, .flags = 0, .buf = &b, .len = 1}, | ||
58 | {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} | ||
59 | }; | ||
60 | |||
61 | if ((i2c_transfer(adapter, msg, 2) != 2) | ||
62 | || (pwm == 0xff)) | ||
63 | pwm = 0x48; | ||
64 | |||
65 | return pwm; | ||
66 | } | ||
67 | |||
68 | static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe) | ||
69 | { | ||
70 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
71 | struct mantis_pci *mantis = fe->dvb->priv; | ||
72 | struct i2c_adapter *adapter = &mantis->adapter; | ||
73 | |||
74 | u8 buf[6]; | ||
75 | struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)}; | ||
76 | int i; | ||
77 | |||
78 | #define CU1216_IF 36125000 | ||
79 | #define TUNER_MUL 62500 | ||
80 | |||
81 | u32 div = (p->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; | ||
82 | |||
83 | buf[0] = (div >> 8) & 0x7f; | ||
84 | buf[1] = div & 0xff; | ||
85 | buf[2] = 0xce; | ||
86 | buf[3] = (p->frequency < 150000000 ? 0x01 : | ||
87 | p->frequency < 445000000 ? 0x02 : 0x04); | ||
88 | buf[4] = 0xde; | ||
89 | buf[5] = 0x20; | ||
90 | |||
91 | if (fe->ops.i2c_gate_ctrl) | ||
92 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
93 | |||
94 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
95 | return -EIO; | ||
96 | |||
97 | /* wait for the pll lock */ | ||
98 | msg.flags = I2C_M_RD; | ||
99 | msg.len = 1; | ||
100 | for (i = 0; i < 20; i++) { | ||
101 | if (fe->ops.i2c_gate_ctrl) | ||
102 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
103 | |||
104 | if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40)) | ||
105 | break; | ||
106 | |||
107 | msleep(10); | ||
108 | } | ||
109 | |||
110 | /* switch the charge pump to the lower current */ | ||
111 | msg.flags = 0; | ||
112 | msg.len = 2; | ||
113 | msg.buf = &buf[2]; | ||
114 | buf[2] &= ~0x40; | ||
115 | if (fe->ops.i2c_gate_ctrl) | ||
116 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
117 | |||
118 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
119 | return -EIO; | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
125 | { | ||
126 | struct i2c_adapter *adapter = &mantis->adapter; | ||
127 | |||
128 | int err = 0; | ||
129 | |||
130 | err = mantis_frontend_power(mantis, POWER_ON); | ||
131 | if (err == 0) { | ||
132 | mantis_frontend_soft_reset(mantis); | ||
133 | msleep(250); | ||
134 | |||
135 | dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)"); | ||
136 | fe = dvb_attach(tda10021_attach, &vp2033_tda1002x_cu1216_config, | ||
137 | adapter, | ||
138 | read_pwm(mantis)); | ||
139 | |||
140 | if (fe) { | ||
141 | dprintk(MANTIS_ERROR, 1, | ||
142 | "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x", | ||
143 | vp2033_tda1002x_cu1216_config.demod_address); | ||
144 | } else { | ||
145 | fe = dvb_attach(tda10023_attach, &vp2033_tda10023_cu1216_config, | ||
146 | adapter, | ||
147 | read_pwm(mantis)); | ||
148 | |||
149 | if (fe) { | ||
150 | dprintk(MANTIS_ERROR, 1, | ||
151 | "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x", | ||
152 | vp2033_tda1002x_cu1216_config.demod_address); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | if (fe) { | ||
157 | fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set; | ||
158 | dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success"); | ||
159 | } else { | ||
160 | return -1; | ||
161 | } | ||
162 | } else { | ||
163 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
164 | adapter->name, | ||
165 | err); | ||
166 | |||
167 | return -EIO; | ||
168 | } | ||
169 | |||
170 | mantis->fe = fe; | ||
171 | dprintk(MANTIS_DEBUG, 1, "Done!"); | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | struct mantis_hwconfig vp2033_config = { | ||
177 | .model_name = MANTIS_MODEL_NAME, | ||
178 | .dev_type = MANTIS_DEV_TYPE, | ||
179 | .ts_size = MANTIS_TS_204, | ||
180 | |||
181 | .baud_rate = MANTIS_BAUD_9600, | ||
182 | .parity = MANTIS_PARITY_NONE, | ||
183 | .bytes = 0, | ||
184 | |||
185 | .frontend_init = vp2033_frontend_init, | ||
186 | .power = GPIF_A12, | ||
187 | .reset = GPIF_A13, | ||
188 | }; | ||
diff --git a/drivers/media/pci/mantis/mantis_vp2033.h b/drivers/media/pci/mantis/mantis_vp2033.h new file mode 100644 index 000000000000..c55242b79d54 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_vp2033.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | Mantis VP-2033 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 | #ifndef __MANTIS_VP2033_H | ||
22 | #define __MANTIS_VP2033_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_2033_DVB_C 0x0008 | ||
27 | |||
28 | extern struct mantis_hwconfig vp2033_config; | ||
29 | |||
30 | #endif /* __MANTIS_VP2033_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_vp2040.c b/drivers/media/pci/mantis/mantis_vp2040.c new file mode 100644 index 000000000000..d480741afd78 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_vp2040.c | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | Mantis VP-2040 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/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "tda1002x.h" | ||
32 | #include "mantis_common.h" | ||
33 | #include "mantis_ioc.h" | ||
34 | #include "mantis_dvb.h" | ||
35 | #include "mantis_vp2040.h" | ||
36 | |||
37 | #define MANTIS_MODEL_NAME "VP-2040" | ||
38 | #define MANTIS_DEV_TYPE "DVB-C" | ||
39 | |||
40 | struct tda1002x_config vp2040_tda1002x_cu1216_config = { | ||
41 | .demod_address = 0x18 >> 1, | ||
42 | .invert = 1, | ||
43 | }; | ||
44 | |||
45 | struct tda10023_config vp2040_tda10023_cu1216_config = { | ||
46 | .demod_address = 0x18 >> 1, | ||
47 | .invert = 1, | ||
48 | }; | ||
49 | |||
50 | static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe) | ||
51 | { | ||
52 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
53 | struct mantis_pci *mantis = fe->dvb->priv; | ||
54 | struct i2c_adapter *adapter = &mantis->adapter; | ||
55 | |||
56 | u8 buf[6]; | ||
57 | struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)}; | ||
58 | int i; | ||
59 | |||
60 | #define CU1216_IF 36125000 | ||
61 | #define TUNER_MUL 62500 | ||
62 | |||
63 | u32 div = (p->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; | ||
64 | |||
65 | buf[0] = (div >> 8) & 0x7f; | ||
66 | buf[1] = div & 0xff; | ||
67 | buf[2] = 0xce; | ||
68 | buf[3] = (p->frequency < 150000000 ? 0x01 : | ||
69 | p->frequency < 445000000 ? 0x02 : 0x04); | ||
70 | buf[4] = 0xde; | ||
71 | buf[5] = 0x20; | ||
72 | |||
73 | if (fe->ops.i2c_gate_ctrl) | ||
74 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
75 | |||
76 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
77 | return -EIO; | ||
78 | |||
79 | /* wait for the pll lock */ | ||
80 | msg.flags = I2C_M_RD; | ||
81 | msg.len = 1; | ||
82 | for (i = 0; i < 20; i++) { | ||
83 | if (fe->ops.i2c_gate_ctrl) | ||
84 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
85 | |||
86 | if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40)) | ||
87 | break; | ||
88 | |||
89 | msleep(10); | ||
90 | } | ||
91 | |||
92 | /* switch the charge pump to the lower current */ | ||
93 | msg.flags = 0; | ||
94 | msg.len = 2; | ||
95 | msg.buf = &buf[2]; | ||
96 | buf[2] &= ~0x40; | ||
97 | if (fe->ops.i2c_gate_ctrl) | ||
98 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
99 | |||
100 | if (i2c_transfer(adapter, &msg, 1) != 1) | ||
101 | return -EIO; | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static u8 read_pwm(struct mantis_pci *mantis) | ||
107 | { | ||
108 | struct i2c_adapter *adapter = &mantis->adapter; | ||
109 | |||
110 | u8 b = 0xff; | ||
111 | u8 pwm; | ||
112 | struct i2c_msg msg[] = { | ||
113 | {.addr = 0x50, .flags = 0, .buf = &b, .len = 1}, | ||
114 | {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} | ||
115 | }; | ||
116 | |||
117 | if ((i2c_transfer(adapter, msg, 2) != 2) | ||
118 | || (pwm == 0xff)) | ||
119 | pwm = 0x48; | ||
120 | |||
121 | return pwm; | ||
122 | } | ||
123 | |||
124 | static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
125 | { | ||
126 | struct i2c_adapter *adapter = &mantis->adapter; | ||
127 | |||
128 | int err = 0; | ||
129 | |||
130 | err = mantis_frontend_power(mantis, POWER_ON); | ||
131 | if (err == 0) { | ||
132 | mantis_frontend_soft_reset(mantis); | ||
133 | msleep(250); | ||
134 | |||
135 | dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)"); | ||
136 | fe = dvb_attach(tda10021_attach, &vp2040_tda1002x_cu1216_config, | ||
137 | adapter, | ||
138 | read_pwm(mantis)); | ||
139 | |||
140 | if (fe) { | ||
141 | dprintk(MANTIS_ERROR, 1, | ||
142 | "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x", | ||
143 | vp2040_tda1002x_cu1216_config.demod_address); | ||
144 | } else { | ||
145 | fe = dvb_attach(tda10023_attach, &vp2040_tda10023_cu1216_config, | ||
146 | adapter, | ||
147 | read_pwm(mantis)); | ||
148 | |||
149 | if (fe) { | ||
150 | dprintk(MANTIS_ERROR, 1, | ||
151 | "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x", | ||
152 | vp2040_tda1002x_cu1216_config.demod_address); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | if (fe) { | ||
157 | fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set; | ||
158 | dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success"); | ||
159 | } else { | ||
160 | return -1; | ||
161 | } | ||
162 | } else { | ||
163 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
164 | adapter->name, | ||
165 | err); | ||
166 | |||
167 | return -EIO; | ||
168 | } | ||
169 | mantis->fe = fe; | ||
170 | dprintk(MANTIS_DEBUG, 1, "Done!"); | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | struct mantis_hwconfig vp2040_config = { | ||
176 | .model_name = MANTIS_MODEL_NAME, | ||
177 | .dev_type = MANTIS_DEV_TYPE, | ||
178 | .ts_size = MANTIS_TS_204, | ||
179 | |||
180 | .baud_rate = MANTIS_BAUD_9600, | ||
181 | .parity = MANTIS_PARITY_NONE, | ||
182 | .bytes = 0, | ||
183 | |||
184 | .frontend_init = vp2040_frontend_init, | ||
185 | .power = GPIF_A12, | ||
186 | .reset = GPIF_A13, | ||
187 | }; | ||
diff --git a/drivers/media/pci/mantis/mantis_vp2040.h b/drivers/media/pci/mantis/mantis_vp2040.h new file mode 100644 index 000000000000..d125e219b685 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_vp2040.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | Mantis VP-2040 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 | #ifndef __MANTIS_VP2040_H | ||
22 | #define __MANTIS_VP2040_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_2040_DVB_C 0x0043 | ||
27 | #define CINERGY_C 0x1178 | ||
28 | #define CABLESTAR_HD2 0x0002 | ||
29 | |||
30 | extern struct mantis_hwconfig vp2040_config; | ||
31 | |||
32 | #endif /* __MANTIS_VP2040_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_vp3028.c b/drivers/media/pci/mantis/mantis_vp3028.c new file mode 100644 index 000000000000..4155c838a18a --- /dev/null +++ b/drivers/media/pci/mantis/mantis_vp3028.c | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | Mantis VP-3028 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 "mantis_common.h" | ||
22 | #include "mantis_vp3028.h" | ||
23 | |||
24 | struct zl10353_config mantis_vp3028_config = { | ||
25 | .demod_address = 0x0f, | ||
26 | }; | ||
27 | |||
28 | #define MANTIS_MODEL_NAME "VP-3028" | ||
29 | #define MANTIS_DEV_TYPE "DVB-T" | ||
30 | |||
31 | struct mantis_hwconfig vp3028_mantis_config = { | ||
32 | .model_name = MANTIS_MODEL_NAME, | ||
33 | .dev_type = MANTIS_DEV_TYPE, | ||
34 | .ts_size = MANTIS_TS_188, | ||
35 | .baud_rate = MANTIS_BAUD_9600, | ||
36 | .parity = MANTIS_PARITY_NONE, | ||
37 | .bytes = 0, | ||
38 | }; | ||
diff --git a/drivers/media/pci/mantis/mantis_vp3028.h b/drivers/media/pci/mantis/mantis_vp3028.h new file mode 100644 index 000000000000..b07be6adc522 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_vp3028.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | Mantis VP-3028 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 | #ifndef __MANTIS_VP3028_H | ||
22 | #define __MANTIS_VP3028_H | ||
23 | |||
24 | #include "dvb_frontend.h" | ||
25 | #include "mantis_common.h" | ||
26 | #include "zl10353.h" | ||
27 | |||
28 | #define MANTIS_VP_3028_DVB_T 0x0028 | ||
29 | |||
30 | extern struct zl10353_config mantis_vp3028_config; | ||
31 | extern struct mantis_hwconfig vp3028_mantis_config; | ||
32 | |||
33 | #endif /* __MANTIS_VP3028_H */ | ||
diff --git a/drivers/media/pci/mantis/mantis_vp3030.c b/drivers/media/pci/mantis/mantis_vp3030.c new file mode 100644 index 000000000000..c09308cd3ac6 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_vp3030.c | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | Mantis VP-3030 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/signal.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | |||
25 | #include "dmxdev.h" | ||
26 | #include "dvbdev.h" | ||
27 | #include "dvb_demux.h" | ||
28 | #include "dvb_frontend.h" | ||
29 | #include "dvb_net.h" | ||
30 | |||
31 | #include "zl10353.h" | ||
32 | #include "tda665x.h" | ||
33 | #include "mantis_common.h" | ||
34 | #include "mantis_ioc.h" | ||
35 | #include "mantis_dvb.h" | ||
36 | #include "mantis_vp3030.h" | ||
37 | |||
38 | struct zl10353_config mantis_vp3030_config = { | ||
39 | .demod_address = 0x0f, | ||
40 | }; | ||
41 | |||
42 | struct tda665x_config env57h12d5_config = { | ||
43 | .name = "ENV57H12D5 (ET-50DT)", | ||
44 | .addr = 0x60, | ||
45 | .frequency_min = 47000000, | ||
46 | .frequency_max = 862000000, | ||
47 | .frequency_offst = 3616667, | ||
48 | .ref_multiplier = 6, /* 1/6 MHz */ | ||
49 | .ref_divider = 100000, /* 1/6 MHz */ | ||
50 | }; | ||
51 | |||
52 | #define MANTIS_MODEL_NAME "VP-3030" | ||
53 | #define MANTIS_DEV_TYPE "DVB-T" | ||
54 | |||
55 | |||
56 | static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) | ||
57 | { | ||
58 | struct i2c_adapter *adapter = &mantis->adapter; | ||
59 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
60 | int err = 0; | ||
61 | |||
62 | mantis_gpio_set_bits(mantis, config->reset, 0); | ||
63 | msleep(100); | ||
64 | err = mantis_frontend_power(mantis, POWER_ON); | ||
65 | msleep(100); | ||
66 | mantis_gpio_set_bits(mantis, config->reset, 1); | ||
67 | |||
68 | if (err == 0) { | ||
69 | msleep(250); | ||
70 | dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)"); | ||
71 | fe = dvb_attach(zl10353_attach, &mantis_vp3030_config, adapter); | ||
72 | |||
73 | if (!fe) | ||
74 | return -1; | ||
75 | |||
76 | dvb_attach(tda665x_attach, fe, &env57h12d5_config, adapter); | ||
77 | } else { | ||
78 | dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", | ||
79 | adapter->name, | ||
80 | err); | ||
81 | |||
82 | return -EIO; | ||
83 | |||
84 | } | ||
85 | mantis->fe = fe; | ||
86 | dprintk(MANTIS_ERROR, 1, "Done!"); | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | struct mantis_hwconfig vp3030_config = { | ||
92 | .model_name = MANTIS_MODEL_NAME, | ||
93 | .dev_type = MANTIS_DEV_TYPE, | ||
94 | .ts_size = MANTIS_TS_188, | ||
95 | |||
96 | .baud_rate = MANTIS_BAUD_9600, | ||
97 | .parity = MANTIS_PARITY_NONE, | ||
98 | .bytes = 0, | ||
99 | |||
100 | .frontend_init = vp3030_frontend_init, | ||
101 | .power = GPIF_A12, | ||
102 | .reset = GPIF_A13, | ||
103 | |||
104 | .i2c_mode = MANTIS_BYTE_MODE | ||
105 | }; | ||
diff --git a/drivers/media/pci/mantis/mantis_vp3030.h b/drivers/media/pci/mantis/mantis_vp3030.h new file mode 100644 index 000000000000..5f12c4266277 --- /dev/null +++ b/drivers/media/pci/mantis/mantis_vp3030.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | Mantis VP-3030 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 | #ifndef __MANTIS_VP3030_H | ||
22 | #define __MANTIS_VP3030_H | ||
23 | |||
24 | #include "mantis_common.h" | ||
25 | |||
26 | #define MANTIS_VP_3030_DVB_T 0x0024 | ||
27 | |||
28 | extern struct mantis_hwconfig vp3030_config; | ||
29 | |||
30 | #endif /* __MANTIS_VP3030_H */ | ||