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