313 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * (c) 1997-1998 Grant R. Guenther <grant@torque.net>4 *5 * epia.c is a low-level protocol driver for Shuttle Technologies6 * EPIA parallel to IDE adapter chip. This device is now obsolete7 * and has been replaced with the EPAT chip, which is supported8 * by epat.c, however, some devices based on EPIA are still9 * available.10 */11 12#include <linux/module.h>13#include <linux/init.h>14#include <linux/delay.h>15#include <linux/kernel.h>16#include <linux/types.h>17#include <linux/wait.h>18#include <asm/io.h>19#include "pata_parport.h"20 21/*22 * mode codes: 0 nybble reads on port 1, 8-bit writes23 * 1 5/3 reads on ports 1 & 2, 8-bit writes24 * 2 8-bit reads and writes25 * 3 8-bit EPP mode26 * 4 16-bit EPP27 * 5 32-bit EPP28 */29 30#define j44(a, b) (((a >> 4) & 0x0f) + (b & 0xf0))31#define j53(a, b) (((a >> 3) & 0x1f) + ((b << 4) & 0xe0))32 33/*34 * cont = 0 IDE register file35 * cont = 1 IDE control registers36 */37static int cont_map[2] = { 0, 0x80 };38 39static int epia_read_regr(struct pi_adapter *pi, int cont, int regr)40{41 int a, b, r;42 43 regr += cont_map[cont];44 45 switch (pi->mode) {46 case 0:47 r = regr ^ 0x39;48 w0(r); w2(1); w2(3); w0(r);49 a = r1(); w2(1); b = r1(); w2(4);50 return j44(a, b);51 case 1:52 r = regr ^ 0x31;53 w0(r); w2(1); w0(r & 0x37);54 w2(3); w2(5); w0(r | 0xf0);55 a = r1(); b = r2(); w2(4);56 return j53(a, b);57 case 2:58 r = regr^0x29;59 w0(r); w2(1); w2(0X21); w2(0x23);60 a = r0(); w2(4);61 return a;62 case 3:63 case 4:64 case 5:65 w3(regr); w2(0x24); a = r4(); w2(4);66 return a;67 }68 69 return -1;70}71 72static void epia_write_regr(struct pi_adapter *pi, int cont, int regr, int val)73{74 int r;75 76 regr += cont_map[cont];77 78 switch (pi->mode) {79 case 0:80 case 1:81 case 2:82 r = regr ^ 0x19;83 w0(r); w2(1); w0(val); w2(3); w2(4);84 break;85 case 3:86 case 4:87 case 5:88 r = regr ^ 0x40;89 w3(r); w4(val); w2(4);90 break;91 }92}93 94#define WR(r, v) epia_write_regr(pi, 0, r, v)95#define RR(r) epia_read_regr(pi, 0, r)96 97/*98 * The use of register 0x84 is entirely unclear - it seems to control99 * some EPP counters ... currently we know about 3 different block100 * sizes: the standard 512 byte reads and writes, 12 byte writes and101 * 2048 byte reads (the last two being used in the CDrom drivers.102 */103static void epia_connect(struct pi_adapter *pi)104{105 pi->saved_r0 = r0();106 pi->saved_r2 = r2();107 108 w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0);109 w2(1); w2(4);110 if (pi->mode >= 3) {111 w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4);112 w2(0x24); w2(0x26); w2(4);113 }114 WR(0x86, 8);115}116 117static void epia_disconnect(struct pi_adapter *pi)118{119 /* WR(0x84,0x10); */120 w0(pi->saved_r0);121 w2(1); w2(4);122 w0(pi->saved_r0);123 w2(pi->saved_r2);124}125 126static void epia_read_block(struct pi_adapter *pi, char *buf, int count)127 128{129 int k, ph, a, b;130 131 switch (pi->mode) {132 case 0:133 w0(0x81); w2(1); w2(3); w0(0xc1);134 ph = 1;135 for (k = 0; k < count; k++) {136 w2(2+ph); a = r1();137 w2(4+ph); b = r1();138 buf[k] = j44(a, b);139 ph = 1 - ph;140 }141 w0(0); w2(4);142 break;143 case 1:144 w0(0x91); w2(1); w0(0x10); w2(3);145 w0(0x51); w2(5); w0(0xd1);146 ph = 1;147 for (k = 0; k < count; k++) {148 w2(4 + ph);149 a = r1(); b = r2();150 buf[k] = j53(a, b);151 ph = 1 - ph;152 }153 w0(0); w2(4);154 break;155 case 2:156 w0(0x89); w2(1); w2(0x23); w2(0x21);157 ph = 1;158 for (k = 0; k < count; k++) {159 w2(0x24 + ph);160 buf[k] = r0();161 ph = 1 - ph;162 }163 w2(6); w2(4);164 break;165 case 3:166 if (count > 512)167 WR(0x84, 3);168 w3(0); w2(0x24);169 for (k = 0; k < count; k++)170 buf[k] = r4();171 w2(4); WR(0x84, 0);172 break;173 case 4:174 if (count > 512)175 WR(0x84, 3);176 w3(0); w2(0x24);177 for (k = 0; k < count / 2; k++)178 ((u16 *)buf)[k] = r4w();179 w2(4); WR(0x84, 0);180 break;181 case 5:182 if (count > 512)183 WR(0x84, 3);184 w3(0); w2(0x24);185 for (k = 0; k < count / 4; k++)186 ((u32 *)buf)[k] = r4l();187 w2(4); WR(0x84, 0);188 break;189 }190}191 192static void epia_write_block(struct pi_adapter *pi, char *buf, int count)193{194 int ph, k, last, d;195 196 switch (pi->mode) {197 case 0:198 case 1:199 case 2:200 w0(0xa1); w2(1); w2(3); w2(1); w2(5);201 ph = 0; last = 0x8000;202 for (k = 0; k < count; k++) {203 d = buf[k];204 if (d != last) {205 last = d;206 w0(d);207 }208 w2(4 + ph);209 ph = 1 - ph;210 }211 w2(7); w2(4);212 break;213 case 3:214 if (count < 512)215 WR(0x84, 1);216 w3(0x40);217 for (k = 0; k < count; k++)218 w4(buf[k]);219 if (count < 512)220 WR(0x84, 0);221 break;222 case 4:223 if (count < 512)224 WR(0x84, 1);225 w3(0x40);226 for (k = 0; k < count / 2; k++)227 w4w(((u16 *)buf)[k]);228 if (count < 512)229 WR(0x84, 0);230 break;231 case 5:232 if (count < 512)233 WR(0x84, 1);234 w3(0x40);235 for (k = 0; k < count / 4; k++)236 w4l(((u32 *)buf)[k]);237 if (count < 512)238 WR(0x84, 0);239 break;240 }241}242 243static int epia_test_proto(struct pi_adapter *pi)244{245 int j, k, f;246 int e[2] = { 0, 0 };247 char scratch[512];248 249 epia_connect(pi);250 for (j = 0; j < 2; j++) {251 WR(6, 0xa0 + j * 0x10);252 for (k = 0; k < 256; k++) {253 WR(2, k ^ 0xaa);254 WR(3, k ^ 0x55);255 if (RR(2) != (k ^ 0xaa))256 e[j]++;257 }258 WR(2, 1); WR(3, 1);259 }260 epia_disconnect(pi);261 262 f = 0;263 epia_connect(pi);264 WR(0x84, 8);265 epia_read_block(pi, scratch, 512);266 for (k = 0; k < 256; k++) {267 if ((scratch[2 * k] & 0xff) != ((k + 1) & 0xff))268 f++;269 if ((scratch[2 * k + 1] & 0xff) != ((-2 - k) & 0xff))270 f++;271 }272 WR(0x84, 0);273 epia_disconnect(pi);274 275 dev_dbg(&pi->dev, "epia: port 0x%x, mode %d, test=(%d,%d,%d)\n",276 pi->port, pi->mode, e[0], e[1], f);277 278 return (e[0] && e[1]) || f;279}280 281 282static void epia_log_adapter(struct pi_adapter *pi)283{284 char *mode[6] = { "4-bit", "5/3", "8-bit", "EPP-8", "EPP-16", "EPP-32"};285 286 dev_info(&pi->dev,287 "Shuttle EPIA at 0x%x, mode %d (%s), delay %d\n",288 pi->port, pi->mode, mode[pi->mode], pi->delay);289}290 291static struct pi_protocol epia = {292 .owner = THIS_MODULE,293 .name = "epia",294 .max_mode = 6,295 .epp_first = 3,296 .default_delay = 1,297 .max_units = 1,298 .write_regr = epia_write_regr,299 .read_regr = epia_read_regr,300 .write_block = epia_write_block,301 .read_block = epia_read_block,302 .connect = epia_connect,303 .disconnect = epia_disconnect,304 .test_proto = epia_test_proto,305 .log_adapter = epia_log_adapter,306};307 308MODULE_LICENSE("GPL");309MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");310MODULE_DESCRIPTION("Shuttle Technologies EPIA parallel port IDE adapter "311 "protocol driver");312module_pata_parport_driver(epia);313