summaryrefslogtreecommitdiff
path: root/drivers/ata/pata_parport/bpck6.c
blob: dc0f71cc305eeb7d3540d69818eff7fd23d05988 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
	backpack.c (c) 2001 Micro Solutions Inc.
		Released under the terms of the GNU General Public license

	backpack.c is a low-level protocol driver for the Micro Solutions
		"BACKPACK" parallel port IDE adapter
		(Works on Series 6 drives)

	Written by: Ken Hahn     (linux-dev@micro-solutions.com)
	            Clive Turvey (linux-dev@micro-solutions.com)

*/

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
#include <linux/parport.h>
#include "pata_parport.h"
#include "ppc6lnx.c"

static int bpck6_read_regr(struct pi_adapter *pi, int cont, int reg)
{
	return ppc6_rd_port(pi, cont?reg|8:reg);
}

static void bpck6_write_regr(struct pi_adapter *pi, int cont, int reg, int val)
{
	ppc6_wr_port(pi, cont?reg|8:reg, val);
}

static void bpck6_write_block(struct pi_adapter *pi, char *buf, int len)
{
	ppc6_wr_port16_blk(pi, ATA_REG_DATA, buf, (u32)len>>1);
}

static void bpck6_read_block(struct pi_adapter *pi, char *buf, int len)
{
	ppc6_rd_port16_blk(pi, ATA_REG_DATA, buf, (u32)len>>1);
}

static void bpck6_connect(struct pi_adapter *pi)
{
	dev_dbg(&pi->dev, "connect\n");

	ppc6_open(pi);
	ppc6_wr_extout(pi, 0x3);
}

static void bpck6_disconnect(struct pi_adapter *pi)
{
	dev_dbg(&pi->dev, "disconnect\n");
	ppc6_wr_extout(pi, 0x0);
	ppc6_close(pi);
}

static int bpck6_test_port(struct pi_adapter *pi)   /* check for 8-bit port */
{
	dev_dbg(&pi->dev, "PARPORT indicates modes=%x for lp=0x%lx\n",
		pi->pardev->port->modes, pi->pardev->port->base);

	/* look at the parport device to see what modes we can use */
	if (pi->pardev->port->modes & PARPORT_MODE_EPP)
		return 5; /* Can do EPP */
	if (pi->pardev->port->modes & PARPORT_MODE_TRISTATE)
		return 2;
	return 1; /* Just flat SPP */
}

static int bpck6_probe_unit(struct pi_adapter *pi)
{
	int out, saved_mode;

	dev_dbg(&pi->dev, "PROBE UNIT %x on port:%x\n", pi->unit, pi->port);

	saved_mode = pi->mode;
	/*LOWER DOWN TO UNIDIRECTIONAL*/
	pi->mode = 0;

	out = ppc6_open(pi);

	dev_dbg(&pi->dev, "ppc_open returned %2x\n", out);

  	if(out)
 	{
		ppc6_close(pi);
		dev_dbg(&pi->dev, "leaving probe\n");
		pi->mode = saved_mode;
               return(1);
	}
  	else
  	{
		dev_dbg(&pi->dev, "Failed open\n");
		pi->mode = saved_mode;
    		return(0);
  	}
}

static void bpck6_log_adapter(struct pi_adapter *pi)
{
	char *mode_string[5]=
		{"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};

	dev_info(&pi->dev, "Micro Solutions BACKPACK Drive unit %d at 0x%x, mode:%d (%s), delay %d\n",
		pi->unit, pi->port, pi->mode, mode_string[pi->mode], pi->delay);
}

static struct pi_protocol bpck6 = {
	.owner		= THIS_MODULE,
	.name		= "bpck6",
	.max_mode	= 5,
	.epp_first	= 2, /* 2-5 use epp (need 8 ports) */
	.max_units	= 255,
	.write_regr	= bpck6_write_regr,
	.read_regr	= bpck6_read_regr,
	.write_block	= bpck6_write_block,
	.read_block	= bpck6_read_block,
	.connect	= bpck6_connect,
	.disconnect	= bpck6_disconnect,
	.test_port	= bpck6_test_port,
	.probe_unit	= bpck6_probe_unit,
	.log_adapter	= bpck6_log_adapter,
};

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Micro Solutions Inc.");
MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
module_pata_parport_driver(bpck6);