1ff80aa57SRussell King /*
2ff80aa57SRussell King  * linux/drivers/pcmcia/sa1100_neponset.c
3ff80aa57SRussell King  *
4ff80aa57SRussell King  * Neponset PCMCIA specific routines
5ff80aa57SRussell King  */
6ff80aa57SRussell King #include <linux/module.h>
7ff80aa57SRussell King #include <linux/kernel.h>
8ff80aa57SRussell King #include <linux/device.h>
9ff80aa57SRussell King #include <linux/errno.h>
10ff80aa57SRussell King #include <linux/init.h>
11ff80aa57SRussell King 
12ff80aa57SRussell King #include <mach/hardware.h>
13ff80aa57SRussell King #include <asm/mach-types.h>
14ff80aa57SRussell King #include <mach/neponset.h>
15ff80aa57SRussell King #include <asm/hardware/sa1111.h>
16ff80aa57SRussell King 
17ff80aa57SRussell King #include "sa1111_generic.h"
18ff80aa57SRussell King 
19ff80aa57SRussell King /*
20ff80aa57SRussell King  * Neponset uses the Maxim MAX1600, with the following connections:
21ff80aa57SRussell King  *
22ff80aa57SRussell King  *   MAX1600      Neponset
23ff80aa57SRussell King  *
24ff80aa57SRussell King  *    A0VCC        SA-1111 GPIO A<1>
25ff80aa57SRussell King  *    A1VCC        SA-1111 GPIO A<0>
26ff80aa57SRussell King  *    A0VPP        CPLD NCR A0VPP
27ff80aa57SRussell King  *    A1VPP        CPLD NCR A1VPP
28ff80aa57SRussell King  *    B0VCC        SA-1111 GPIO A<2>
29ff80aa57SRussell King  *    B1VCC        SA-1111 GPIO A<3>
30ff80aa57SRussell King  *    B0VPP        ground (slot B is CF)
31ff80aa57SRussell King  *    B1VPP        ground (slot B is CF)
32ff80aa57SRussell King  *
33ff80aa57SRussell King  *     VX          VCC (5V)
34ff80aa57SRussell King  *     VY          VCC3_3 (3.3V)
35ff80aa57SRussell King  *     12INA       12V
36ff80aa57SRussell King  *     12INB       ground (slot B is CF)
37ff80aa57SRussell King  *
38ff80aa57SRussell King  * The MAX1600 CODE pin is tied to ground, placing the device in
39ff80aa57SRussell King  * "Standard Intel code" mode. Refer to the Maxim data sheet for
40ff80aa57SRussell King  * the corresponding truth table.
41ff80aa57SRussell King  */
42ff80aa57SRussell King 
43ff80aa57SRussell King static int
44ff80aa57SRussell King neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
45ff80aa57SRussell King {
46ff80aa57SRussell King 	struct sa1111_pcmcia_socket *s = to_skt(skt);
47ff80aa57SRussell King 	unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
48ff80aa57SRussell King 	int ret;
49ff80aa57SRussell King 
50ff80aa57SRussell King 	switch (skt->nr) {
51ff80aa57SRussell King 	case 0:
52ff80aa57SRussell King 		pa_dwr_mask = GPIO_A0 | GPIO_A1;
53ff80aa57SRussell King 		ncr_mask = NCR_A0VPP | NCR_A1VPP;
54ff80aa57SRussell King 
55ff80aa57SRussell King 		if (state->Vpp == 0)
56ff80aa57SRussell King 			ncr_set = 0;
57ff80aa57SRussell King 		else if (state->Vpp == 120)
58ff80aa57SRussell King 			ncr_set = NCR_A1VPP;
59ff80aa57SRussell King 		else if (state->Vpp == state->Vcc)
60ff80aa57SRussell King 			ncr_set = NCR_A0VPP;
61ff80aa57SRussell King 		else {
62ff80aa57SRussell King 			printk(KERN_ERR "%s(): unrecognized VPP %u\n",
63ff80aa57SRussell King 			       __func__, state->Vpp);
64ff80aa57SRussell King 			return -1;
65ff80aa57SRussell King 		}
66ff80aa57SRussell King 		break;
67ff80aa57SRussell King 
68ff80aa57SRussell King 	case 1:
69ff80aa57SRussell King 		pa_dwr_mask = GPIO_A2 | GPIO_A3;
70ff80aa57SRussell King 		ncr_mask = 0;
71ff80aa57SRussell King 		ncr_set = 0;
72ff80aa57SRussell King 
73ff80aa57SRussell King 		if (state->Vpp != state->Vcc && state->Vpp != 0) {
74ff80aa57SRussell King 			printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
75ff80aa57SRussell King 			       __func__, state->Vpp);
76ff80aa57SRussell King 			return -1;
77ff80aa57SRussell King 		}
78ff80aa57SRussell King 		break;
79ff80aa57SRussell King 
80ff80aa57SRussell King 	default:
81ff80aa57SRussell King 		return -1;
82ff80aa57SRussell King 	}
83ff80aa57SRussell King 
84ff80aa57SRussell King 	/*
85ff80aa57SRussell King 	 * pa_dwr_set is the mask for selecting Vcc on both sockets.
86ff80aa57SRussell King 	 * pa_dwr_mask selects which bits (and therefore socket) we change.
87ff80aa57SRussell King 	 */
88ff80aa57SRussell King 	switch (state->Vcc) {
89ff80aa57SRussell King 	default:
90ff80aa57SRussell King 	case 0:  pa_dwr_set = 0;		break;
91ff80aa57SRussell King 	case 33: pa_dwr_set = GPIO_A1|GPIO_A2;	break;
92ff80aa57SRussell King 	case 50: pa_dwr_set = GPIO_A0|GPIO_A3;	break;
93ff80aa57SRussell King 	}
94ff80aa57SRussell King 
95ff80aa57SRussell King 	ret = sa1111_pcmcia_configure_socket(skt, state);
96ff80aa57SRussell King 	if (ret == 0) {
979e4db1c3SLinus Torvalds 		neponset_ncr_frob(ncr_mask, ncr_set);
98ff80aa57SRussell King 		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
99ff80aa57SRussell King 	}
100ff80aa57SRussell King 
101ff80aa57SRussell King 	return ret;
102ff80aa57SRussell King }
103ff80aa57SRussell King 
104ff80aa57SRussell King static struct pcmcia_low_level neponset_pcmcia_ops = {
105ff80aa57SRussell King 	.owner			= THIS_MODULE,
106ff80aa57SRussell King 	.configure_socket	= neponset_pcmcia_configure_socket,
107ff80aa57SRussell King 	.first			= 0,
108ff80aa57SRussell King 	.nr			= 2,
109ff80aa57SRussell King };
110ff80aa57SRussell King 
111ff80aa57SRussell King int pcmcia_neponset_init(struct sa1111_dev *sadev)
112ff80aa57SRussell King {
113ff80aa57SRussell King 	int ret = -ENODEV;
114ff80aa57SRussell King 
115ff80aa57SRussell King 	if (machine_is_assabet()) {
116ff80aa57SRussell King 		/*
117ff80aa57SRussell King 		 * Set GPIO_A<3:0> to be outputs for the MAX1600,
118ff80aa57SRussell King 		 * and switch to standby mode.
119ff80aa57SRussell King 		 */
120ff80aa57SRussell King 		sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
121ff80aa57SRussell King 		sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
122ff80aa57SRussell King 		sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
123ff80aa57SRussell King 		sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
124ff80aa57SRussell King 		ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
125ff80aa57SRussell King 				sa11xx_drv_pcmcia_add_one);
126ff80aa57SRussell King 	}
127ff80aa57SRussell King 
128ff80aa57SRussell King 	return ret;
129ff80aa57SRussell King }
130