brintos

brintos / linux-shallow public Read only

0
0
Text · 4.1 KiB · 94b8d35 Raw
206 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * (c) 1997-1998  Grant R. Guenther <grant@torque.net>4 *5 * comm.c is a low-level protocol driver for some older models of the DataStor6 * "Commuter" parallel to IDE adapter. Some of the parallel port devices7 * marketed by Arista currently use this adapter.8 */9 10#include <linux/module.h>11#include <linux/init.h>12#include <linux/delay.h>13#include <linux/kernel.h>14#include <linux/types.h>15#include <linux/wait.h>16#include <asm/io.h>17#include "pata_parport.h"18 19/*20 * mode codes:  0  nybble reads, 8-bit writes21 *              1  8-bit reads and writes22 *              2  8-bit EPP mode23 */24 25#define j44(a, b)	(((a >> 3) & 0x0f) | ((b << 1) & 0xf0))26 27#define P1	w2(5);w2(0xd);w2(0xd);w2(5);w2(4);28#define P2	w2(5);w2(7);w2(7);w2(5);w2(4);29 30/*31 * cont = 0 - access the IDE register file32 * cont = 1 - access the IDE command set33 */34static int  cont_map[2] = { 0x08, 0x10 };35 36static int comm_read_regr(struct pi_adapter *pi, int cont, int regr)37{38	int l, h, r;39 40	r = regr + cont_map[cont];41 42	switch (pi->mode) {43	case 0:44		w0(r); P1; w0(0);45		w2(6); l = r1(); w0(0x80); h = r1(); w2(4);46		return j44(l, h);47 48	case 1:49		w0(r+0x20); P1;50		w0(0); w2(0x26); h = r0(); w2(4);51		return h;52 53	case 2:54	case 3:55	case 4:56		w3(r+0x20); (void)r1();57		w2(0x24); h = r4(); w2(4);58		return h;59	}60 61	return -1;62}63 64static void comm_write_regr(struct pi_adapter *pi, int cont, int regr, int val)65{66	int r = regr + cont_map[cont];67 68	switch (pi->mode) {69	case 0:70	case 1:71		w0(r); P1; w0(val); P2;72		break;73	case 2:74	case 3:75	case 4:76		w3(r); (void)r1(); w4(val);77		break;78	}79}80 81static void comm_connect(struct pi_adapter *pi)82{83	pi->saved_r0 = r0();84	pi->saved_r2 = r2();85	w2(4); w0(0xff); w2(6);86	w2(4); w0(0xaa); w2(6);87	w2(4); w0(0x00); w2(6);88	w2(4); w0(0x87); w2(6);89	w2(4); w0(0xe0); w2(0xc); w2(0xc); w2(4);90}91 92static void comm_disconnect(struct pi_adapter *pi)93{94	w2(0); w2(0); w2(0); w2(4);95	w0(pi->saved_r0);96	w2(pi->saved_r2);97}98 99static void comm_read_block(struct pi_adapter *pi, char *buf, int count)100{101	int i, l, h;102 103	switch (pi->mode) {104	case 0:105		w0(0x48); P1;106		for (i = 0; i < count; i++) {107			w0(0); w2(6); l = r1();108			w0(0x80); h = r1(); w2(4);109			buf[i] = j44(l, h);110		}111		break;112	case 1:113		w0(0x68); P1; w0(0);114		for (i = 0; i < count; i++) {115			w2(0x26);116			buf[i] = r0();117			w2(0x24);118		}119		w2(4);120		break;121	case 2:122		w3(0x68); (void)r1(); w2(0x24);123		for (i = 0; i < count; i++)124			buf[i] = r4();125		w2(4);126		break;127	case 3:128		w3(0x68); (void)r1(); w2(0x24);129		for (i = 0; i < count / 2; i++)130			((u16 *)buf)[i] = r4w();131		w2(4);132		break;133	case 4:134		w3(0x68); (void)r1(); w2(0x24);135		for (i = 0; i < count / 4; i++)136			((u32 *)buf)[i] = r4l();137		w2(4);138		break;139	}140}141 142/* NB: Watch out for the byte swapped writes ! */143static void comm_write_block(struct pi_adapter *pi, char *buf, int count)144{145	int k;146 147	switch (pi->mode) {148	case 0:149	case 1:150		w0(0x68); P1;151		for (k = 0; k < count; k++) {152			w2(5);153			w0(buf[k ^ 1]);154			w2(7);155		}156		w2(5); w2(4);157		break;158	case 2:159		w3(0x48); (void)r1();160		for (k = 0; k < count; k++)161			w4(buf[k ^ 1]);162		break;163	case 3:164		w3(0x48); (void)r1();165		for (k = 0; k < count / 2; k++)166			w4w(swab16(((u16 *)buf)[k]));167		break;168	case 4:169		w3(0x48); (void)r1();170		for (k = 0; k < count / 4; k++)171			w4l(swab16(((u16 *)buf)[2 * k]) |172			    swab16(((u16 *)buf)[2 * k + 1]) << 16);173		break;174	}175}176 177static void comm_log_adapter(struct pi_adapter *pi)178{179	char *mode_string[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" };180 181	dev_info(&pi->dev,182		 "DataStor Commuter at 0x%x, mode %d (%s), delay %d\n",183		 pi->port, pi->mode, mode_string[pi->mode], pi->delay);184}185 186static struct pi_protocol comm = {187	.owner		= THIS_MODULE,188	.name		= "comm",189	.max_mode	= 5,190	.epp_first	= 2,191	.default_delay	= 1,192	.max_units	= 1,193	.write_regr	= comm_write_regr,194	.read_regr	= comm_read_regr,195	.write_block	= comm_write_block,196	.read_block	= comm_read_block,197	.connect	= comm_connect,198	.disconnect	= comm_disconnect,199	.log_adapter	= comm_log_adapter,200};201 202MODULE_LICENSE("GPL");203MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");204MODULE_DESCRIPTION("DataStor Commuter parallel port IDE adapter protocol driver");205module_pata_parport_driver(comm);206