diff options
Diffstat (limited to 'drivers/media/pci/mantis/mantis_hif.c')
-rw-r--r-- | drivers/media/pci/mantis/mantis_hif.c | 239 |
1 files changed, 239 insertions, 0 deletions
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 | } | ||