xref: /freebsd/sys/dev/gpio/gpiospi.c (revision 79af8f72b3aff993703778423e83320df0953a37)
1 /*-
2  * Copyright (c) 2011, Aleksandr Rybalko <ray@dlink.ua>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice unmodified, this list of conditions, and the following
10  *    disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/cdefs.h>
29 #include "opt_gpio.h"
30 
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 
34 #include <sys/bus.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/rman.h>
38 #include <sys/sysctl.h>
39 
40 #include <sys/gpio.h>
41 #include "gpiobus_if.h"
42 
43 #include <dev/gpio/gpiobusvar.h>
44 
45 #include <dev/spibus/spi.h>
46 #include <dev/spibus/spibusvar.h>
47 #include "spibus_if.h"
48 
49 #ifdef	GPIO_SPI_DEBUG
50 #define	dprintf printf
51 #else
52 #define	dprintf(x, arg...)
53 #endif	/* GPIO_SPI_DEBUG */
54 
55 struct gpio_spi_softc {
56 	device_t	sc_dev;
57 	device_t	sc_busdev;
58 	int		sc_freq;
59 	uint8_t		sc_sclk;
60 	uint8_t		sc_miso;
61 	uint8_t		sc_mosi;
62 	uint8_t		sc_cs0;
63 	uint8_t		sc_cs1;
64 	uint8_t		sc_cs2;
65 	uint8_t		sc_cs3;
66 };
67 
68 static void gpio_spi_chip_activate(struct gpio_spi_softc *, int);
69 static void gpio_spi_chip_deactivate(struct gpio_spi_softc *, int);
70 
71 static int
gpio_spi_probe(device_t dev)72 gpio_spi_probe(device_t dev)
73 {
74 	device_set_desc(dev, "GPIO SPI bit-banging driver");
75 	return (0);
76 }
77 
78 static void
gpio_delay(struct gpio_spi_softc * sc)79 gpio_delay(struct gpio_spi_softc *sc)
80 {
81 	int d;
82 
83 	d = sc->sc_freq / 1000000;
84 	if (d == 0)
85 		d = 1;
86 
87 	DELAY(d);
88 }
89 
90 static int
gpio_spi_attach(device_t dev)91 gpio_spi_attach(device_t dev)
92 {
93 	uint32_t value;
94 	struct gpio_spi_softc *sc;
95 
96 	sc = device_get_softc(dev);
97 	sc->sc_dev = dev;
98 	sc->sc_busdev = device_get_parent(dev);
99 
100 	/* Required variables */
101 	if (resource_int_value(device_get_name(dev),
102 	    device_get_unit(dev), "sclk", &value))
103 		 return (ENXIO);
104 	sc->sc_sclk = value & 0xff;
105 
106 	if (resource_int_value(device_get_name(dev),
107 	    device_get_unit(dev), "mosi", &value))
108 		 return (ENXIO);
109 	sc->sc_mosi = value & 0xff;
110 
111 	/* Handle no miso; we just never read back from the device */
112 	if (resource_int_value(device_get_name(dev),
113 	    device_get_unit(dev), "miso", &value))
114 		 value = 0xff;
115 	sc->sc_miso = value & 0xff;
116 
117 	if (resource_int_value(device_get_name(dev),
118 	    device_get_unit(dev), "cs0", &value))
119 		 return (ENXIO);
120 	sc->sc_cs0 = value & 0xff;
121 
122 	/* Optional variables */
123 	if (resource_int_value(device_get_name(dev),
124 	    device_get_unit(dev), "cs1", &value))
125 		value = 0xff;
126 	sc->sc_cs1 = value & 0xff;
127 
128 	if (resource_int_value(device_get_name(dev),
129 	    device_get_unit(dev), "cs2", &value))
130 		value = 0xff;
131 	sc->sc_cs2 = value & 0xff;
132 
133 	if (resource_int_value(device_get_name(dev),
134 	    device_get_unit(dev), "cs3", &value))
135 		value = 0xff;
136 	sc->sc_cs3 = value & 0xff;
137 
138 	/* Default to 100KHz */
139 	if (resource_int_value(device_get_name(dev),
140 	    device_get_unit(dev), "freq", &value)) {
141 		value = 100000;
142 	}
143 	sc->sc_freq = value;
144 
145 	if (bootverbose) {
146 		device_printf(dev, "frequency: %d Hz\n",
147 		    sc->sc_freq);
148 		device_printf(dev,
149 		    "Use GPIO pins: sclk=%d, mosi=%d, miso=%d, "
150 		    "cs0=%d, cs1=%d, cs2=%d, cs3=%d\n",
151 		    sc->sc_sclk, sc->sc_mosi, sc->sc_miso,
152 		    sc->sc_cs0, sc->sc_cs1, sc->sc_cs2, sc->sc_cs3);
153 	}
154 
155 	/* Set directions */
156 	GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sc_sclk,
157 	    GPIO_PIN_OUTPUT|GPIO_PIN_PULLDOWN);
158 	GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sc_mosi,
159 	    GPIO_PIN_OUTPUT|GPIO_PIN_PULLDOWN);
160 	if (sc->sc_miso != 0xff) {
161 		GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sc_miso,
162 		    GPIO_PIN_INPUT|GPIO_PIN_PULLDOWN);
163 	}
164 
165 	GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sc_cs0,
166 	    GPIO_PIN_OUTPUT|GPIO_PIN_PULLUP);
167 
168 	if (sc->sc_cs1 != 0xff)
169 		GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sc_cs1,
170 		    GPIO_PIN_OUTPUT|GPIO_PIN_PULLUP);
171 	if (sc->sc_cs2 != 0xff)
172 		GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sc_cs2,
173 		    GPIO_PIN_OUTPUT|GPIO_PIN_PULLUP);
174 	if (sc->sc_cs3 != 0xff)
175 		GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sc_cs3,
176 		    GPIO_PIN_OUTPUT|GPIO_PIN_PULLUP);
177 
178 	gpio_spi_chip_deactivate(sc, -1);
179 
180 	device_add_child(dev, "spibus", DEVICE_UNIT_ANY);
181 	return (bus_generic_attach(dev));
182 }
183 
184 static int
gpio_spi_detach(device_t dev)185 gpio_spi_detach(device_t dev)
186 {
187 
188 	return (0);
189 }
190 
191 static void
gpio_spi_chip_activate(struct gpio_spi_softc * sc,int cs)192 gpio_spi_chip_activate(struct gpio_spi_softc *sc, int cs)
193 {
194 
195 	/* called with locked gpiobus */
196 	switch (cs) {
197 	case 0:
198 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
199 		    sc->sc_cs0, 0);
200 		break;
201 	case 1:
202 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
203 		    sc->sc_cs1, 0);
204 		break;
205 	case 2:
206 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
207 		    sc->sc_cs2, 0);
208 		break;
209 	case 3:
210 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
211 		    sc->sc_cs3, 0);
212 		break;
213 	default:
214 		device_printf(sc->sc_dev, "don't have CS%d\n", cs);
215 	}
216 
217 	gpio_delay(sc);
218 }
219 
220 static void
gpio_spi_chip_deactivate(struct gpio_spi_softc * sc,int cs)221 gpio_spi_chip_deactivate(struct gpio_spi_softc *sc, int cs)
222 {
223 
224 	/* called wth locked gpiobus */
225 	/*
226 	 * Put CSx to high
227 	 */
228 	switch (cs) {
229 	case -1:
230 		/* All CS */
231 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
232 		    sc->sc_cs0, 1);
233 		if (sc->sc_cs1 == 0xff) break;
234 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
235 		    sc->sc_cs1, 1);
236 		if (sc->sc_cs2 == 0xff) break;
237 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
238 		    sc->sc_cs2, 1);
239 		if (sc->sc_cs3 == 0xff) break;
240 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
241 		    sc->sc_cs3, 1);
242 		break;
243 	case 0:
244 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
245 		    sc->sc_cs0, 1);
246 		break;
247 	case 1:
248 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
249 		    sc->sc_cs1, 1);
250 		break;
251 	case 2:
252 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
253 		    sc->sc_cs2, 1);
254 		break;
255 	case 3:
256 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
257 		    sc->sc_cs3, 1);
258 		break;
259 	default:
260 		device_printf(sc->sc_dev, "don't have CS%d\n", cs);
261 	}
262 }
263 
264 static uint8_t
gpio_spi_txrx(struct gpio_spi_softc * sc,int cs,int mode,uint8_t data)265 gpio_spi_txrx(struct gpio_spi_softc *sc, int cs, int mode, uint8_t data)
266 {
267 	uint32_t mask, out = 0;
268 	unsigned int bit;
269 
270 
271 	/* called with locked gpiobus */
272 
273 	for (mask = 0x80; mask > 0; mask >>= 1) {
274 		if ((mode == SPIBUS_MODE_CPOL) ||
275 		    (mode == SPIBUS_MODE_CPHA)) {
276 			/* If mode 1 or 2 */
277 
278 			/* first step */
279 			GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
280 			    sc->sc_mosi, (data & mask)?1:0);
281 			GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
282 			    sc->sc_sclk, 0);
283 			gpio_delay(sc);
284 			/* second step */
285 			if (sc->sc_miso != 0xff) {
286 				GPIOBUS_PIN_GET(sc->sc_busdev, sc->sc_dev,
287 				    sc->sc_miso, &bit);
288 				out |= bit?mask:0;
289 			}
290 			/* Data captured */
291 			gpio_delay(sc);
292 			GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
293 			    sc->sc_sclk, 1);
294 			gpio_delay(sc);
295 		} else {
296 			/* If mode 0 or 3 */
297 
298 			/* first step */
299 			GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
300 			    sc->sc_mosi, (data & mask)?1:0);
301 			GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
302 			    sc->sc_sclk, 1);
303 			gpio_delay(sc);
304 			/* second step */
305 			if (sc->sc_miso != 0xff) {
306 				GPIOBUS_PIN_GET(sc->sc_busdev, sc->sc_dev,
307 				    sc->sc_miso, &bit);
308 				out |= bit?mask:0;
309 			}
310 			 /* Data captured */
311 			gpio_delay(sc);
312 			GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
313 			    sc->sc_sclk, 0);
314 			gpio_delay(sc);
315 		}
316 	}
317 
318 	return (out & 0xff);
319 }
320 
321 static int
gpio_spi_transfer(device_t dev,device_t child,struct spi_command * cmd)322 gpio_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
323 {
324 	struct gpio_spi_softc *sc;
325 	uint8_t *buf_in, *buf_out;
326 	struct spibus_ivar *devi = SPIBUS_IVAR(child);
327 	int i;
328 
329 	sc = device_get_softc(dev);
330 
331 	KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,
332 	    ("TX/RX command sizes should be equal"));
333 	KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
334 	    ("TX/RX data sizes should be equal"));
335 
336 	gpio_spi_chip_activate(sc, devi->cs);
337 
338 	/* Preset pins */
339 	if ((devi->mode == SPIBUS_MODE_CPOL) ||
340 	    (devi->mode == SPIBUS_MODE_CPHA)) {
341 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
342 		    sc->sc_sclk, 1);
343 	} else {
344 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
345 		    sc->sc_sclk, 0);
346 	}
347 
348 	/*
349 	 * Transfer command
350 	 */
351 	buf_out = (uint8_t *)cmd->tx_cmd;
352 	buf_in = (uint8_t *)cmd->rx_cmd;
353 
354 	for (i = 0; i < cmd->tx_cmd_sz; i++)
355 		buf_in[i] = gpio_spi_txrx(sc, devi->cs, devi->mode, buf_out[i]);
356 
357 	/*
358 	 * Receive/transmit data (depends on command)
359 	 */
360 	buf_out = (uint8_t *)cmd->tx_data;
361 	buf_in = (uint8_t *)cmd->rx_data;
362 	for (i = 0; i < cmd->tx_data_sz; i++)
363 		buf_in[i] = gpio_spi_txrx(sc, devi->cs, devi->mode, buf_out[i]);
364 
365 	/* Return pins to mode default */
366 	if ((devi->mode == SPIBUS_MODE_CPOL) ||
367 	    (devi->mode == SPIBUS_MODE_CPHA)) {
368 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
369 		    sc->sc_sclk, 1);
370 	} else {
371 		GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
372 		    sc->sc_sclk, 0);
373 	}
374 
375 	gpio_spi_chip_deactivate(sc, devi->cs);
376 
377 	return (0);
378 }
379 
380 static device_method_t gpio_spi_methods[] = {
381 	/* Device interface */
382 	DEVMETHOD(device_probe,		gpio_spi_probe),
383 	DEVMETHOD(device_attach,	gpio_spi_attach),
384 	DEVMETHOD(device_detach,	gpio_spi_detach),
385 
386 	DEVMETHOD(spibus_transfer,	gpio_spi_transfer),
387 
388 	{0, 0}
389 };
390 
391 static driver_t gpio_spi_driver = {
392 	"gpiospi",
393 	gpio_spi_methods,
394 	sizeof(struct gpio_spi_softc),
395 };
396 
397 DRIVER_MODULE(gpiospi, gpiobus, gpio_spi_driver, 0, 0);
398 DRIVER_MODULE(spibus, gpiospi, spibus_driver, 0, 0);
399 MODULE_DEPEND(gpiospi, spibus, 1, 1, 1);
400 MODULE_DEPEND(gpiospi, gpiobus, 1, 1, 1);
401