xref: /openbmc/linux/drivers/ata/pata_parport/bpck6.c (revision 4e21c863)
1 /*
2 	backpack.c (c) 2001 Micro Solutions Inc.
3 		Released under the terms of the GNU General Public license
4 
5 	backpack.c is a low-level protocol driver for the Micro Solutions
6 		"BACKPACK" parallel port IDE adapter
7 		(Works on Series 6 drives)
8 
9 	Written by: Ken Hahn     (linux-dev@micro-solutions.com)
10 	            Clive Turvey (linux-dev@micro-solutions.com)
11 
12 */
13 
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/kernel.h>
17 #include <linux/types.h>
18 #include <linux/parport.h>
19 #include "pata_parport.h"
20 #include "ppc6lnx.c"
21 
22 static int bpck6_read_regr(struct pi_adapter *pi, int cont, int reg)
23 {
24 	u8 port = cont ? reg | 8 : reg;
25 
26 	ppc6_send_cmd(pi, port | ACCESS_PORT | ACCESS_READ);
27 	return ppc6_rd_data_byte(pi);
28 }
29 
30 static void bpck6_write_regr(struct pi_adapter *pi, int cont, int reg, int val)
31 {
32 	u8 port = cont ? reg | 8 : reg;
33 
34 	ppc6_send_cmd(pi, port | ACCESS_PORT | ACCESS_WRITE);
35 	ppc6_wr_data_byte(pi, val);
36 }
37 
38 static void bpck6_write_block(struct pi_adapter *pi, char *buf, int len)
39 {
40 	ppc6_send_cmd(pi, REG_BLKSIZE | ACCESS_REG | ACCESS_WRITE);
41 	ppc6_wr_data_byte(pi, (u8)len);
42 	ppc6_wr_data_byte(pi, (u8)(len >> 8));
43 	ppc6_wr_data_byte(pi, 0);
44 
45 	ppc6_send_cmd(pi, CMD_PREFIX_SET | PREFIX_IO16 | PREFIX_BLK);
46 	ppc6_send_cmd(pi, ATA_REG_DATA | ACCESS_PORT | ACCESS_WRITE);
47 	ppc6_wr_data_blk(pi, buf, len);
48 	ppc6_send_cmd(pi, CMD_PREFIX_RESET | PREFIX_IO16 | PREFIX_BLK);
49 }
50 
51 static void bpck6_read_block(struct pi_adapter *pi, char *buf, int len)
52 {
53 	ppc6_send_cmd(pi, REG_BLKSIZE | ACCESS_REG | ACCESS_WRITE);
54 	ppc6_wr_data_byte(pi, (u8)len);
55 	ppc6_wr_data_byte(pi, (u8)(len >> 8));
56 	ppc6_wr_data_byte(pi, 0);
57 
58 	ppc6_send_cmd(pi, CMD_PREFIX_SET | PREFIX_IO16 | PREFIX_BLK);
59 	ppc6_send_cmd(pi, ATA_REG_DATA | ACCESS_PORT | ACCESS_READ);
60 	ppc6_rd_data_blk(pi, buf, len);
61 	ppc6_send_cmd(pi, CMD_PREFIX_RESET | PREFIX_IO16 | PREFIX_BLK);
62 }
63 
64 static void bpck6_connect(struct pi_adapter *pi)
65 {
66 	dev_dbg(&pi->dev, "connect\n");
67 
68 	ppc6_open(pi);
69 	ppc6_wr_extout(pi, 0x3);
70 }
71 
72 static void bpck6_disconnect(struct pi_adapter *pi)
73 {
74 	dev_dbg(&pi->dev, "disconnect\n");
75 	ppc6_wr_extout(pi, 0x0);
76 	ppc6_deselect(pi);
77 }
78 
79 static int bpck6_test_port(struct pi_adapter *pi)   /* check for 8-bit port */
80 {
81 	dev_dbg(&pi->dev, "PARPORT indicates modes=%x for lp=0x%lx\n",
82 		pi->pardev->port->modes, pi->pardev->port->base);
83 
84 	/* look at the parport device to see what modes we can use */
85 	if (pi->pardev->port->modes & PARPORT_MODE_EPP)
86 		return 5; /* Can do EPP */
87 	if (pi->pardev->port->modes & PARPORT_MODE_TRISTATE)
88 		return 2;
89 	return 1; /* Just flat SPP */
90 }
91 
92 static int bpck6_probe_unit(struct pi_adapter *pi)
93 {
94 	int out, saved_mode;
95 
96 	dev_dbg(&pi->dev, "PROBE UNIT %x on port:%x\n", pi->unit, pi->port);
97 
98 	saved_mode = pi->mode;
99 	/*LOWER DOWN TO UNIDIRECTIONAL*/
100 	pi->mode = 0;
101 
102 	out = ppc6_open(pi);
103 
104 	dev_dbg(&pi->dev, "ppc_open returned %2x\n", out);
105 
106   	if(out)
107  	{
108 		ppc6_deselect(pi);
109 		dev_dbg(&pi->dev, "leaving probe\n");
110 		pi->mode = saved_mode;
111                return(1);
112 	}
113   	else
114   	{
115 		dev_dbg(&pi->dev, "Failed open\n");
116 		pi->mode = saved_mode;
117     		return(0);
118   	}
119 }
120 
121 static void bpck6_log_adapter(struct pi_adapter *pi)
122 {
123 	char *mode_string[5]=
124 		{"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
125 
126 	dev_info(&pi->dev, "Micro Solutions BACKPACK Drive unit %d at 0x%x, mode:%d (%s), delay %d\n",
127 		pi->unit, pi->port, pi->mode, mode_string[pi->mode], pi->delay);
128 }
129 
130 static struct pi_protocol bpck6 = {
131 	.owner		= THIS_MODULE,
132 	.name		= "bpck6",
133 	.max_mode	= 5,
134 	.epp_first	= 2, /* 2-5 use epp (need 8 ports) */
135 	.max_units	= 255,
136 	.write_regr	= bpck6_write_regr,
137 	.read_regr	= bpck6_read_regr,
138 	.write_block	= bpck6_write_block,
139 	.read_block	= bpck6_read_block,
140 	.connect	= bpck6_connect,
141 	.disconnect	= bpck6_disconnect,
142 	.test_port	= bpck6_test_port,
143 	.probe_unit	= bpck6_probe_unit,
144 	.log_adapter	= bpck6_log_adapter,
145 };
146 
147 MODULE_LICENSE("GPL");
148 MODULE_AUTHOR("Micro Solutions Inc.");
149 MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
150 module_pata_parport_driver(bpck6);
151