xref: /openbmc/linux/drivers/ata/pata_parport/bpck6.c (revision e9090fd6)
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 	return ppc6_rd_port(pi, cont?reg|8:reg);
25 }
26 
27 static void bpck6_write_regr(struct pi_adapter *pi, int cont, int reg, int val)
28 {
29 	ppc6_wr_port(pi, cont?reg|8:reg, val);
30 }
31 
32 static void bpck6_write_block(struct pi_adapter *pi, char *buf, int len)
33 {
34 	ppc6_wr_port16_blk(pi, ATA_REG_DATA, buf, (u32)len>>1);
35 }
36 
37 static void bpck6_read_block(struct pi_adapter *pi, char *buf, int len)
38 {
39 	ppc6_rd_port16_blk(pi, ATA_REG_DATA, buf, (u32)len>>1);
40 }
41 
42 static void bpck6_connect(struct pi_adapter *pi)
43 {
44 	dev_dbg(&pi->dev, "connect\n");
45 
46 	ppc6_open(pi);
47 	ppc6_wr_extout(pi, 0x3);
48 }
49 
50 static void bpck6_disconnect(struct pi_adapter *pi)
51 {
52 	dev_dbg(&pi->dev, "disconnect\n");
53 	ppc6_wr_extout(pi, 0x0);
54 	ppc6_close(pi);
55 }
56 
57 static int bpck6_test_port(struct pi_adapter *pi)   /* check for 8-bit port */
58 {
59 	dev_dbg(&pi->dev, "PARPORT indicates modes=%x for lp=0x%lx\n",
60 		pi->pardev->port->modes, pi->pardev->port->base);
61 
62 	/* look at the parport device to see what modes we can use */
63 	if (pi->pardev->port->modes & PARPORT_MODE_EPP)
64 		return 5; /* Can do EPP */
65 	if (pi->pardev->port->modes & PARPORT_MODE_TRISTATE)
66 		return 2;
67 	return 1; /* Just flat SPP */
68 }
69 
70 static int bpck6_probe_unit(struct pi_adapter *pi)
71 {
72 	int out, saved_mode;
73 
74 	dev_dbg(&pi->dev, "PROBE UNIT %x on port:%x\n", pi->unit, pi->port);
75 
76 	saved_mode = pi->mode;
77 	/*LOWER DOWN TO UNIDIRECTIONAL*/
78 	pi->mode = 0;
79 
80 	out = ppc6_open(pi);
81 
82 	dev_dbg(&pi->dev, "ppc_open returned %2x\n", out);
83 
84   	if(out)
85  	{
86 		ppc6_close(pi);
87 		dev_dbg(&pi->dev, "leaving probe\n");
88 		pi->mode = saved_mode;
89                return(1);
90 	}
91   	else
92   	{
93 		dev_dbg(&pi->dev, "Failed open\n");
94 		pi->mode = saved_mode;
95     		return(0);
96   	}
97 }
98 
99 static void bpck6_log_adapter(struct pi_adapter *pi)
100 {
101 	char *mode_string[5]=
102 		{"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
103 
104 	dev_info(&pi->dev, "Micro Solutions BACKPACK Drive unit %d at 0x%x, mode:%d (%s), delay %d\n",
105 		pi->unit, pi->port, pi->mode, mode_string[pi->mode], pi->delay);
106 }
107 
108 static struct pi_protocol bpck6 = {
109 	.owner		= THIS_MODULE,
110 	.name		= "bpck6",
111 	.max_mode	= 5,
112 	.epp_first	= 2, /* 2-5 use epp (need 8 ports) */
113 	.max_units	= 255,
114 	.write_regr	= bpck6_write_regr,
115 	.read_regr	= bpck6_read_regr,
116 	.write_block	= bpck6_write_block,
117 	.read_block	= bpck6_read_block,
118 	.connect	= bpck6_connect,
119 	.disconnect	= bpck6_disconnect,
120 	.test_port	= bpck6_test_port,
121 	.probe_unit	= bpck6_probe_unit,
122 	.log_adapter	= bpck6_log_adapter,
123 };
124 
125 MODULE_LICENSE("GPL");
126 MODULE_AUTHOR("Micro Solutions Inc.");
127 MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
128 module_pata_parport_driver(bpck6);
129