1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * (c) 1997-1998 Grant R. Guenther <grant@torque.net> |
4 | * |
5 | * This is a low-level driver for the KBIC-951A and KBIC-971A |
6 | * parallel to IDE adapter chips from KingByte Information Systems. |
7 | * |
8 | * The chips are almost identical, however, the wakeup code |
9 | * required for the 971A interferes with the correct operation of |
10 | * the 951A, so this driver registers itself twice, once for |
11 | * each chip. |
12 | */ |
13 | |
14 | #include <linux/module.h> |
15 | #include <linux/init.h> |
16 | #include <linux/delay.h> |
17 | #include <linux/kernel.h> |
18 | #include <linux/types.h> |
19 | #include <linux/wait.h> |
20 | #include <asm/io.h> |
21 | #include "pata_parport.h" |
22 | |
23 | #define r12w() (delay_p, inw(pi->port + 1) & 0xffff) |
24 | |
25 | #define j44(a, b) ((((a >> 4) & 0x0f) | (b & 0xf0)) ^ 0x88) |
26 | #define j53(w) (((w >> 3) & 0x1f) | ((w >> 4) & 0xe0)) |
27 | |
28 | |
29 | /* |
30 | * cont = 0 - access the IDE register file |
31 | * cont = 1 - access the IDE command set |
32 | */ |
33 | static int cont_map[2] = { 0x80, 0x40 }; |
34 | |
35 | static int kbic_read_regr(struct pi_adapter *pi, int cont, int regr) |
36 | { |
37 | int a, b, s; |
38 | |
39 | s = cont_map[cont]; |
40 | |
41 | switch (pi->mode) { |
42 | case 0: |
43 | w0(regr | 0x18 | s); w2(4); w2(6); w2(4); w2(1); w0(8); |
44 | a = r1(); w0(0x28); b = r1(); w2(4); |
45 | return j44(a, b); |
46 | case 1: |
47 | w0(regr|0x38 | s); w2(4); w2(6); w2(4); w2(5); w0(8); |
48 | a = r12w(); w2(4); |
49 | return j53(a); |
50 | case 2: |
51 | w0(regr | 0x08 | s); w2(4); w2(6); w2(4); w2(0xa5); w2(0xa1); |
52 | a = r0(); w2(4); |
53 | return a; |
54 | case 3: |
55 | case 4: |
56 | case 5: |
57 | w0(0x20 | s); w2(4); w2(6); w2(4); w3(regr); |
58 | a = r4(); b = r4(); w2(4); w2(0); w2(4); |
59 | return a; |
60 | } |
61 | |
62 | return -1; |
63 | } |
64 | |
65 | static void kbic_write_regr(struct pi_adapter *pi, int cont, int regr, int val) |
66 | { |
67 | int s = cont_map[cont]; |
68 | |
69 | switch (pi->mode) { |
70 | case 0: |
71 | case 1: |
72 | case 2: |
73 | w0(regr | 0x10 | s); w2(4); w2(6); w2(4); |
74 | w0(val); w2(5); w2(4); |
75 | break; |
76 | case 3: |
77 | case 4: |
78 | case 5: |
79 | w0(0x20 | s); w2(4); w2(6); w2(4); w3(regr); |
80 | w4(val); w4(val); |
81 | w2(4); w2(0); w2(4); |
82 | break; |
83 | } |
84 | } |
85 | |
86 | static void k951_connect(struct pi_adapter *pi) |
87 | { |
88 | pi->saved_r0 = r0(); |
89 | pi->saved_r2 = r2(); |
90 | w2(4); |
91 | } |
92 | |
93 | static void k951_disconnect(struct pi_adapter *pi) |
94 | { |
95 | w0(pi->saved_r0); |
96 | w2(pi->saved_r2); |
97 | } |
98 | |
99 | #define CCP(x) \ |
100 | do { \ |
101 | w2(0xc4); w0(0xaa); w0(0x55); \ |
102 | w0(0); w0(0xff); w0(0x87); \ |
103 | w0(0x78); w0(x); w2(0xc5); \ |
104 | w2(0xc4); w0(0xff); \ |
105 | } while (0) |
106 | |
107 | static void k971_connect(struct pi_adapter *pi) |
108 | { |
109 | pi->saved_r0 = r0(); |
110 | pi->saved_r2 = r2(); |
111 | CCP(0x20); |
112 | w2(4); |
113 | } |
114 | |
115 | static void k971_disconnect(struct pi_adapter *pi) |
116 | { |
117 | CCP(0x30); |
118 | w0(pi->saved_r0); |
119 | w2(pi->saved_r2); |
120 | } |
121 | |
122 | /* |
123 | * count must be congruent to 0 MOD 4, but all known applications |
124 | *have this property. |
125 | */ |
126 | static void kbic_read_block(struct pi_adapter *pi, char *buf, int count) |
127 | { |
128 | int k, a, b; |
129 | |
130 | switch (pi->mode) { |
131 | case 0: |
132 | w0(0x98); w2(4); w2(6); w2(4); |
133 | for (k = 0; k < count / 2; k++) { |
134 | w2(1); w0(8); |
135 | a = r1(); |
136 | w0(0x28); |
137 | b = r1(); |
138 | buf[2 * k] = j44(a, b); |
139 | w2(5); |
140 | b = r1(); |
141 | w0(8); |
142 | a = r1(); |
143 | buf[2 * k + 1] = j44(a, b); |
144 | w2(4); |
145 | } |
146 | break; |
147 | case 1: |
148 | w0(0xb8); w2(4); w2(6); w2(4); |
149 | for (k = 0; k < count / 4; k++) { |
150 | w0(0xb8); |
151 | w2(4); w2(5); |
152 | w0(8); |
153 | buf[4 * k] = j53(r12w()); |
154 | w0(0xb8); |
155 | buf[4 * k + 1] = j53(r12w()); |
156 | w2(4); w2(5); |
157 | buf[4 * k + 3] = j53(r12w()); |
158 | w0(8); |
159 | buf[4 * k + 2] = j53(r12w()); |
160 | } |
161 | w2(4); |
162 | break; |
163 | case 2: |
164 | w0(0x88); w2(4); w2(6); w2(4); |
165 | for (k = 0; k < count / 2; k++) { |
166 | w2(0xa0); w2(0xa1); |
167 | buf[2 * k] = r0(); |
168 | w2(0xa5); |
169 | buf[2 * k + 1] = r0(); |
170 | } |
171 | w2(4); |
172 | break; |
173 | case 3: |
174 | w0(0xa0); w2(4); w2(6); w2(4); w3(0); |
175 | for (k = 0; k < count; k++) |
176 | buf[k] = r4(); |
177 | w2(4); w2(0); w2(4); |
178 | break; |
179 | case 4: |
180 | w0(0xa0); w2(4); w2(6); w2(4); w3(0); |
181 | for (k = 0; k < count / 2; k++) |
182 | ((u16 *)buf)[k] = r4w(); |
183 | w2(4); w2(0); w2(4); |
184 | break; |
185 | case 5: |
186 | w0(0xa0); w2(4); w2(6); w2(4); w3(0); |
187 | for (k = 0; k < count / 4; k++) |
188 | ((u32 *)buf)[k] = r4l(); |
189 | w2(4); w2(0); w2(4); |
190 | break; |
191 | } |
192 | } |
193 | |
194 | static void kbic_write_block(struct pi_adapter *pi, char *buf, int count) |
195 | { |
196 | int k; |
197 | |
198 | switch (pi->mode) { |
199 | case 0: |
200 | case 1: |
201 | case 2: |
202 | w0(0x90); w2(4); w2(6); w2(4); |
203 | for (k = 0; k < count / 2; k++) { |
204 | w0(buf[2 * k + 1]); |
205 | w2(0); w2(4); |
206 | w0(buf[2 * k]); |
207 | w2(5); w2(4); |
208 | } |
209 | break; |
210 | case 3: |
211 | w0(0xa0); w2(4); w2(6); w2(4); w3(0); |
212 | for (k = 0; k < count / 2; k++) { |
213 | w4(buf[2 * k + 1]); |
214 | w4(buf[2 * k]); |
215 | } |
216 | w2(4); w2(0); w2(4); |
217 | break; |
218 | case 4: |
219 | w0(0xa0); w2(4); w2(6); w2(4); w3(0); |
220 | for (k = 0; k < count / 2; k++) |
221 | w4w(swab16(((u16 *)buf)[k])); |
222 | w2(4); w2(0); w2(4); |
223 | break; |
224 | case 5: |
225 | w0(0xa0); w2(4); w2(6); w2(4); w3(0); |
226 | for (k = 0; k < count / 4; k++) |
227 | w4l(swab16(((u16 *)buf)[2 * k]) | |
228 | swab16(((u16 *)buf)[2 * k + 1]) << 16); |
229 | w2(4); w2(0); w2(4); |
230 | break; |
231 | } |
232 | } |
233 | |
234 | static void kbic_log_adapter(struct pi_adapter *pi, char *chip) |
235 | { |
236 | char *mode[6] = { "4-bit" , "5/3" , "8-bit" , "EPP-8" , "EPP_16" , "EPP-32" }; |
237 | |
238 | dev_info(&pi->dev, "KingByte %s at 0x%x, mode %d (%s), delay %d\n" , |
239 | chip, pi->port, pi->mode, mode[pi->mode], pi->delay); |
240 | } |
241 | |
242 | static void k951_log_adapter(struct pi_adapter *pi) |
243 | { |
244 | kbic_log_adapter(pi, chip: "KBIC-951A" ); |
245 | } |
246 | |
247 | static void k971_log_adapter(struct pi_adapter *pi) |
248 | { |
249 | kbic_log_adapter(pi, chip: "KBIC-971A" ); |
250 | } |
251 | |
252 | static struct pi_protocol k951 = { |
253 | .owner = THIS_MODULE, |
254 | .name = "k951" , |
255 | .max_mode = 6, |
256 | .epp_first = 3, |
257 | .default_delay = 1, |
258 | .max_units = 1, |
259 | .write_regr = kbic_write_regr, |
260 | .read_regr = kbic_read_regr, |
261 | .write_block = kbic_write_block, |
262 | .read_block = kbic_read_block, |
263 | .connect = k951_connect, |
264 | .disconnect = k951_disconnect, |
265 | .log_adapter = k951_log_adapter, |
266 | }; |
267 | |
268 | static struct pi_protocol k971 = { |
269 | .owner = THIS_MODULE, |
270 | .name = "k971" , |
271 | .max_mode = 6, |
272 | .epp_first = 3, |
273 | .default_delay = 1, |
274 | .max_units = 1, |
275 | .write_regr = kbic_write_regr, |
276 | .read_regr = kbic_read_regr, |
277 | .write_block = kbic_write_block, |
278 | .read_block = kbic_read_block, |
279 | .connect = k971_connect, |
280 | .disconnect = k971_disconnect, |
281 | .log_adapter = k971_log_adapter, |
282 | }; |
283 | |
284 | static int __init kbic_init(void) |
285 | { |
286 | int rv; |
287 | |
288 | rv = pata_parport_register_driver(pr: &k951); |
289 | if (rv < 0) |
290 | return rv; |
291 | rv = pata_parport_register_driver(pr: &k971); |
292 | if (rv < 0) |
293 | pata_parport_unregister_driver(pr: &k951); |
294 | return rv; |
295 | } |
296 | |
297 | static void __exit kbic_exit(void) |
298 | { |
299 | pata_parport_unregister_driver(pr: &k951); |
300 | pata_parport_unregister_driver(pr: &k971); |
301 | } |
302 | |
303 | MODULE_LICENSE("GPL" ); |
304 | MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>" ); |
305 | MODULE_DESCRIPTION("KingByte Information Systems KBIC-951A and KBIC-971A " |
306 | "parallel port IDE adapter protocol driver" ); |
307 | module_init(kbic_init) |
308 | module_exit(kbic_exit) |
309 | |