|
1 | | -/* |
2 | | - friq.c (c) 1998 Grant R. Guenther <grant@torque.net> |
3 | | - Under the terms of the GNU General Public License |
4 | | -
|
5 | | - friq.c is a low-level protocol driver for the Freecom "IQ" |
6 | | - parallel port IDE adapter. Early versions of this adapter |
7 | | - use the 'frpw' protocol. |
8 | | - |
9 | | - Freecom uses this adapter in a battery powered external |
10 | | - CD-ROM drive. It is also used in LS-120 drives by |
11 | | - Maxell and Panasonic, and other devices. |
12 | | -
|
13 | | - The battery powered drive requires software support to |
14 | | - control the power to the drive. This module enables the |
15 | | - drive power when the high level driver (pcd) is loaded |
16 | | - and disables it when the module is unloaded. Note, if |
17 | | - the friq module is built in to the kernel, the power |
18 | | - will never be switched off, so other means should be |
19 | | - used to conserve battery power. |
20 | | -
|
21 | | -*/ |
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | +/* |
| 3 | + * (c) 1998 Grant R. Guenther <grant@torque.net> |
| 4 | + * |
| 5 | + * friq.c is a low-level protocol driver for the Freecom "IQ" |
| 6 | + * parallel port IDE adapter. Early versions of this adapter |
| 7 | + * use the 'frpw' protocol. |
| 8 | + * |
| 9 | + * Freecom uses this adapter in a battery powered external |
| 10 | + * CD-ROM drive. It is also used in LS-120 drives by |
| 11 | + * Maxell and Panasonic, and other devices. |
| 12 | + * |
| 13 | + * The battery powered drive requires software support to |
| 14 | + * control the power to the drive. This module enables the |
| 15 | + * drive power when the high level driver (pcd) is loaded |
| 16 | + * and disables it when the module is unloaded. Note, if |
| 17 | + * the friq module is built in to the kernel, the power |
| 18 | + * will never be switched off, so other means should be |
| 19 | + * used to conserve battery power. |
| 20 | + */ |
22 | 21 |
|
23 | 22 | #include <linux/module.h> |
24 | 23 | #include <linux/init.h> |
|
29 | 28 | #include <asm/io.h> |
30 | 29 | #include "pata_parport.h" |
31 | 30 |
|
32 | | -#define CMD(x) w2(4);w0(0xff);w0(0xff);w0(0x73);w0(0x73);\ |
33 | | - w0(0xc9);w0(0xc9);w0(0x26);w0(0x26);w0(x);w0(x); |
| 31 | +#define CMD(x) \ |
| 32 | + do { \ |
| 33 | + w2(4); w0(0xff); w0(0xff); w0(0x73); w0(0x73); \ |
| 34 | + w0(0xc9); w0(0xc9); w0(0x26); \ |
| 35 | + w0(0x26); w0(x); w0(x); \ |
| 36 | + } while (0) |
34 | 37 |
|
35 | | -#define j44(l,h) (((l>>4)&0x0f)|(h&0xf0)) |
| 38 | +#define j44(l, h) (((l >> 4) & 0x0f) | (h & 0xf0)) |
36 | 39 |
|
37 | | -/* cont = 0 - access the IDE register file |
38 | | - cont = 1 - access the IDE command set |
39 | | -*/ |
40 | | - |
41 | | -static int cont_map[2] = { 0x08, 0x10 }; |
| 40 | +/* |
| 41 | + * cont = 0 - access the IDE register file |
| 42 | + * cont = 1 - access the IDE command set |
| 43 | + */ |
| 44 | +static int cont_map[2] = { 0x08, 0x10 }; |
42 | 45 |
|
43 | 46 | static int friq_read_regr(struct pi_adapter *pi, int cont, int regr) |
44 | | - |
45 | | -{ int h,l,r; |
| 47 | +{ |
| 48 | + int h, l, r; |
46 | 49 |
|
47 | 50 | r = regr + cont_map[cont]; |
48 | 51 |
|
49 | 52 | CMD(r); |
50 | 53 | w2(6); l = r1(); |
51 | 54 | w2(4); h = r1(); |
52 | | - w2(4); |
53 | | - |
54 | | - return j44(l,h); |
| 55 | + w2(4); |
55 | 56 |
|
| 57 | + return j44(l, h); |
56 | 58 | } |
57 | 59 |
|
58 | 60 | static void friq_write_regr(struct pi_adapter *pi, int cont, int regr, int val) |
59 | | - |
60 | | -{ int r; |
61 | | - |
62 | | - r = regr + cont_map[cont]; |
| 61 | +{ |
| 62 | + int r = regr + cont_map[cont]; |
63 | 63 |
|
64 | 64 | CMD(r); |
65 | 65 | w0(val); |
66 | | - w2(5);w2(7);w2(5);w2(4); |
| 66 | + w2(5); w2(7); w2(5); w2(4); |
67 | 67 | } |
68 | 68 |
|
69 | 69 | static void friq_read_block_int(struct pi_adapter *pi, char *buf, int count, int regr) |
| 70 | +{ |
| 71 | + int h, l, k, ph; |
70 | 72 |
|
71 | | -{ int h, l, k, ph; |
72 | | - |
73 | | - switch(pi->mode) { |
74 | | - |
75 | | - case 0: CMD(regr); |
76 | | - for (k=0;k<count;k++) { |
77 | | - w2(6); l = r1(); |
78 | | - w2(4); h = r1(); |
79 | | - buf[k] = j44(l,h); |
80 | | - } |
81 | | - w2(4); |
82 | | - break; |
83 | | - |
84 | | - case 1: ph = 2; |
85 | | - CMD(regr+0xc0); |
86 | | - w0(0xff); |
87 | | - for (k=0;k<count;k++) { |
88 | | - w2(0xa4 + ph); |
89 | | - buf[k] = r0(); |
90 | | - ph = 2 - ph; |
91 | | - } |
92 | | - w2(0xac); w2(0xa4); w2(4); |
93 | | - break; |
94 | | - |
95 | | - case 2: CMD(regr+0x80); |
96 | | - for (k=0;k<count-2;k++) buf[k] = r4(); |
| 73 | + switch (pi->mode) { |
| 74 | + case 0: |
| 75 | + CMD(regr); |
| 76 | + for (k = 0; k < count; k++) { |
| 77 | + w2(6); l = r1(); |
| 78 | + w2(4); h = r1(); |
| 79 | + buf[k] = j44(l, h); |
| 80 | + } |
| 81 | + w2(4); |
| 82 | + break; |
| 83 | + case 1: |
| 84 | + ph = 2; |
| 85 | + CMD(regr + 0xc0); |
| 86 | + w0(0xff); |
| 87 | + for (k = 0; k < count; k++) { |
| 88 | + w2(0xa4 + ph); |
| 89 | + buf[k] = r0(); |
| 90 | + ph = 2 - ph; |
| 91 | + } |
| 92 | + w2(0xac); w2(0xa4); w2(4); |
| 93 | + break; |
| 94 | + case 2: |
| 95 | + CMD(regr + 0x80); |
| 96 | + for (k = 0; k < count - 2; k++) |
| 97 | + buf[k] = r4(); |
97 | 98 | w2(0xac); w2(0xa4); |
98 | | - buf[count-2] = r4(); |
99 | | - buf[count-1] = r4(); |
| 99 | + buf[count - 2] = r4(); |
| 100 | + buf[count - 1] = r4(); |
100 | 101 | w2(4); |
101 | 102 | break; |
102 | | - |
103 | | - case 3: CMD(regr+0x80); |
104 | | - for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w(); |
105 | | - w2(0xac); w2(0xa4); |
106 | | - buf[count-2] = r4(); |
107 | | - buf[count-1] = r4(); |
108 | | - w2(4); |
109 | | - break; |
110 | | - |
111 | | - case 4: CMD(regr+0x80); |
112 | | - for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l(); |
113 | | - buf[count-4] = r4(); |
114 | | - buf[count-3] = r4(); |
115 | | - w2(0xac); w2(0xa4); |
116 | | - buf[count-2] = r4(); |
117 | | - buf[count-1] = r4(); |
118 | | - w2(4); |
119 | | - break; |
120 | | - |
121 | | - } |
| 103 | + case 3: |
| 104 | + CMD(regr + 0x80); |
| 105 | + for (k = 0; k < count / 2 - 1; k++) |
| 106 | + ((u16 *)buf)[k] = r4w(); |
| 107 | + w2(0xac); w2(0xa4); |
| 108 | + buf[count - 2] = r4(); |
| 109 | + buf[count - 1] = r4(); |
| 110 | + w2(4); |
| 111 | + break; |
| 112 | + case 4: |
| 113 | + CMD(regr + 0x80); |
| 114 | + for (k = 0; k < count / 4 - 1; k++) |
| 115 | + ((u32 *)buf)[k] = r4l(); |
| 116 | + buf[count - 4] = r4(); |
| 117 | + buf[count - 3] = r4(); |
| 118 | + w2(0xac); w2(0xa4); |
| 119 | + buf[count - 2] = r4(); |
| 120 | + buf[count - 1] = r4(); |
| 121 | + w2(4); |
| 122 | + break; |
| 123 | + } |
122 | 124 | } |
123 | 125 |
|
124 | 126 | static void friq_read_block(struct pi_adapter *pi, char *buf, int count) |
125 | | - |
126 | | -{ friq_read_block_int(pi,buf,count,0x08); |
| 127 | +{ |
| 128 | + friq_read_block_int(pi, buf, count, 0x08); |
127 | 129 | } |
128 | 130 |
|
129 | 131 | static void friq_write_block(struct pi_adapter *pi, char *buf, int count) |
130 | | - |
131 | | -{ int k; |
132 | | - |
133 | | - switch(pi->mode) { |
| 132 | +{ |
| 133 | + int k; |
134 | 134 |
|
| 135 | + switch (pi->mode) { |
135 | 136 | case 0: |
136 | | - case 1: CMD(8); w2(5); |
137 | | - for (k=0;k<count;k++) { |
| 137 | + case 1: |
| 138 | + CMD(8); w2(5); |
| 139 | + for (k = 0; k < count; k++) { |
138 | 140 | w0(buf[k]); |
139 | | - w2(7);w2(5); |
| 141 | + w2(7); w2(5); |
140 | 142 | } |
141 | 143 | w2(4); |
142 | 144 | break; |
143 | | - |
144 | | - case 2: CMD(0xc8); w2(5); |
145 | | - for (k=0;k<count;k++) w4(buf[k]); |
| 145 | + case 2: |
| 146 | + CMD(0xc8); w2(5); |
| 147 | + for (k = 0; k < count; k++) |
| 148 | + w4(buf[k]); |
| 149 | + w2(4); |
| 150 | + break; |
| 151 | + case 3: |
| 152 | + CMD(0xc8); w2(5); |
| 153 | + for (k = 0; k < count / 2; k++) |
| 154 | + w4w(((u16 *)buf)[k]); |
| 155 | + w2(4); |
| 156 | + break; |
| 157 | + case 4: |
| 158 | + CMD(0xc8); w2(5); |
| 159 | + for (k = 0; k < count / 4; k++) |
| 160 | + w4l(((u32 *)buf)[k]); |
146 | 161 | w2(4); |
147 | 162 | break; |
148 | | - |
149 | | - case 3: CMD(0xc8); w2(5); |
150 | | - for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]); |
151 | | - w2(4); |
152 | | - break; |
153 | | - |
154 | | - case 4: CMD(0xc8); w2(5); |
155 | | - for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]); |
156 | | - w2(4); |
157 | | - break; |
158 | | - } |
| 163 | +} |
159 | 164 | } |
160 | 165 |
|
161 | 166 | static void friq_connect(struct pi_adapter *pi) |
162 | | - |
163 | | -{ pi->saved_r0 = r0(); |
164 | | - pi->saved_r2 = r2(); |
| 167 | +{ |
| 168 | + pi->saved_r0 = r0(); |
| 169 | + pi->saved_r2 = r2(); |
165 | 170 | w2(4); |
166 | 171 | } |
167 | 172 |
|
168 | 173 | static void friq_disconnect(struct pi_adapter *pi) |
169 | | - |
170 | | -{ CMD(0x20); |
| 174 | +{ |
| 175 | + CMD(0x20); |
171 | 176 | w0(pi->saved_r0); |
172 | | - w2(pi->saved_r2); |
173 | | -} |
| 177 | + w2(pi->saved_r2); |
| 178 | +} |
174 | 179 |
|
175 | 180 | static int friq_test_proto(struct pi_adapter *pi) |
176 | | - |
177 | | -{ int j, k, r; |
178 | | - int e[2] = {0,0}; |
| 181 | +{ |
| 182 | + int j, k, r; |
| 183 | + int e[2] = { 0, 0 }; |
179 | 184 | char scratch[512]; |
180 | 185 |
|
181 | | - pi->saved_r0 = r0(); |
| 186 | + pi->saved_r0 = r0(); |
182 | 187 | w0(0xff); udelay(20); CMD(0x3d); /* turn the power on */ |
183 | 188 | udelay(500); |
184 | 189 | w0(pi->saved_r0); |
185 | 190 |
|
186 | 191 | friq_connect(pi); |
187 | | - for (j=0;j<2;j++) { |
188 | | - friq_write_regr(pi,0,6,0xa0+j*0x10); |
189 | | - for (k=0;k<256;k++) { |
190 | | - friq_write_regr(pi,0,2,k^0xaa); |
191 | | - friq_write_regr(pi,0,3,k^0x55); |
192 | | - if (friq_read_regr(pi,0,2) != (k^0xaa)) e[j]++; |
193 | | - } |
194 | | - } |
| 192 | + for (j = 0; j < 2; j++) { |
| 193 | + friq_write_regr(pi, 0, 6, 0xa0 + j * 0x10); |
| 194 | + for (k = 0; k < 256; k++) { |
| 195 | + friq_write_regr(pi, 0, 2, k ^ 0xaa); |
| 196 | + friq_write_regr(pi, 0, 3, k ^ 0x55); |
| 197 | + if (friq_read_regr(pi, 0, 2) != (k ^ 0xaa)) |
| 198 | + e[j]++; |
| 199 | + } |
| 200 | + } |
195 | 201 | friq_disconnect(pi); |
196 | 202 |
|
197 | 203 | friq_connect(pi); |
198 | | - friq_read_block_int(pi,scratch,512,0x10); |
199 | | - r = 0; |
200 | | - for (k=0;k<128;k++) if (scratch[k] != k) r++; |
| 204 | + friq_read_block_int(pi, scratch, 512, 0x10); |
| 205 | + r = 0; |
| 206 | + for (k = 0; k < 128; k++) { |
| 207 | + if (scratch[k] != k) |
| 208 | + r++; |
| 209 | + } |
201 | 210 | friq_disconnect(pi); |
202 | 211 |
|
203 | | - dev_dbg(&pi->dev, "friq: port 0x%x, mode %d, test=(%d,%d,%d)\n", |
204 | | - pi->port, pi->mode, e[0], e[1], r); |
| 212 | + dev_dbg(&pi->dev, |
| 213 | + "friq: port 0x%x, mode %d, test=(%d,%d,%d)\n", |
| 214 | + pi->port, pi->mode, e[0], e[1], r); |
205 | 215 |
|
206 | | - return (r || (e[0] && e[1])); |
| 216 | + return r || (e[0] && e[1]); |
207 | 217 | } |
208 | 218 |
|
209 | | - |
210 | 219 | static void friq_log_adapter(struct pi_adapter *pi) |
| 220 | +{ |
| 221 | + char *mode_string[6] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32"}; |
211 | 222 |
|
212 | | -{ char *mode_string[6] = {"4-bit","8-bit", |
213 | | - "EPP-8","EPP-16","EPP-32"}; |
214 | | - |
215 | | - dev_info(&pi->dev, "Freecom IQ ASIC-2 adapter at 0x%x, mode %d (%s), delay %d\n", |
216 | | - pi->port, pi->mode, mode_string[pi->mode], pi->delay); |
| 223 | + dev_info(&pi->dev, |
| 224 | + "Freecom IQ ASIC-2 adapter at 0x%x, mode %d (%s), delay %d\n", |
| 225 | + pi->port, pi->mode, mode_string[pi->mode], pi->delay); |
217 | 226 |
|
218 | 227 | pi->private = 1; |
219 | 228 | friq_connect(pi); |
220 | 229 | CMD(0x9e); /* disable sleep timer */ |
221 | 230 | friq_disconnect(pi); |
222 | | - |
223 | 231 | } |
224 | 232 |
|
225 | 233 | static void friq_release_proto(struct pi_adapter *pi) |
|
0 commit comments