spi.c revision 1.17.2.2 1 /* $NetBSD: spi.c,v 1.17.2.2 2021/06/17 04:46:30 thorpej Exp $ */
2
3 /*-
4 * Copyright (c) 2006 Urbana-Champaign Independent Media Center.
5 * Copyright (c) 2006 Garrett D'Amore.
6 * All rights reserved.
7 *
8 * Portions of this code were written by Garrett D'Amore for the
9 * Champaign-Urbana Community Wireless Network Project.
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer in the documentation and/or other materials provided
19 * with the distribution.
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgements:
22 * This product includes software developed by the Urbana-Champaign
23 * Independent Media Center.
24 * This product includes software developed by Garrett D'Amore.
25 * 4. Urbana-Champaign Independent Media Center's name and Garrett
26 * D'Amore's name may not be used to endorse or promote products
27 * derived from this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE URBANA-CHAMPAIGN INDEPENDENT
30 * MEDIA CENTER AND GARRETT D'AMORE ``AS IS'' AND ANY EXPRESS OR
31 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE URBANA-CHAMPAIGN INDEPENDENT
34 * MEDIA CENTER OR GARRETT D'AMORE BE LIABLE FOR ANY DIRECT, INDIRECT,
35 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: spi.c,v 1.17.2.2 2021/06/17 04:46:30 thorpej Exp $");
46
47 #include "locators.h"
48
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/device.h>
52 #include <sys/conf.h>
53 #include <sys/kmem.h>
54 #include <sys/mutex.h>
55 #include <sys/condvar.h>
56 #include <sys/errno.h>
57
58 #include <dev/spi/spivar.h>
59 #include <dev/spi/spi_io.h>
60
61 #include "ioconf.h"
62 #include "locators.h"
63
64 struct spi_softc {
65 device_t sc_dev;
66 struct spi_controller sc_controller;
67 int sc_mode;
68 int sc_speed;
69 int sc_slave;
70 int sc_nslaves;
71 struct spi_handle *sc_slaves;
72 kmutex_t sc_slave_state_lock;
73 kmutex_t sc_lock;
74 kcondvar_t sc_cv;
75 kmutex_t sc_dev_lock;
76 int sc_flags;
77 #define SPIC_BUSY 1
78 };
79
80 static dev_type_open(spi_open);
81 static dev_type_close(spi_close);
82 static dev_type_ioctl(spi_ioctl);
83
84 const struct cdevsw spi_cdevsw = {
85 .d_open = spi_open,
86 .d_close = spi_close,
87 .d_read = noread,
88 .d_write = nowrite,
89 .d_ioctl = spi_ioctl,
90 .d_stop = nostop,
91 .d_tty = notty,
92 .d_poll = nopoll,
93 .d_mmap = nommap,
94 .d_kqfilter = nokqfilter,
95 .d_discard = nodiscard,
96 .d_flag = D_OTHER | D_MPSAFE
97 };
98
99 /*
100 * SPI slave device. We have one of these per slave.
101 */
102 struct spi_handle {
103 struct spi_softc *sh_sc; /* static */
104 struct spi_controller *sh_controller; /* static */
105 int sh_slave; /* static */
106 int sh_mode; /* locked by owning child */
107 int sh_speed; /* locked by owning child */
108 int sh_flags; /* ^^ slave_state_lock ^^ */
109 #define SPIH_ATTACHED __BIT(0)
110 #define SPIH_DIRECT __BIT(1)
111 };
112
113 #define SPI_MAXDATA 4096
114
115 /*
116 * API for bus drivers.
117 */
118
119 int
120 spibus_print(void *aux, const char *pnp)
121 {
122
123 if (pnp != NULL)
124 aprint_normal("spi at %s", pnp);
125
126 return (UNCONF);
127 }
128
129
130 static int
131 spi_match(device_t parent, cfdata_t cf, void *aux)
132 {
133
134 return 1;
135 }
136
137 static int
138 spi_print_direct(void *aux, const char *pnp)
139 {
140 struct spi_attach_args *sa = aux;
141
142 if (pnp != NULL) {
143 aprint_normal("%s%s%s%s at %s slave %d",
144 sa->sa_name ? sa->sa_name : "(unknown)",
145 sa->sa_clist ? " (" : "",
146 sa->sa_clist ? sa->sa_clist : "",
147 sa->sa_clist ? ")" : "",
148 pnp, sa->sa_handle->sh_slave);
149 } else {
150 aprint_normal(" slave %d", sa->sa_handle->sh_slave);
151 }
152
153 return UNCONF;
154 }
155
156 static int
157 spi_print(void *aux, const char *pnp)
158 {
159 struct spi_attach_args *sa = aux;
160
161 aprint_normal(" slave %d", sa->sa_handle->sh_slave);
162
163 return UNCONF;
164 }
165
166 /*
167 * Direct and indrect for SPI are pretty similar, so we can collapse
168 * them into a single function.
169 */
170 static void
171 spi_attach_child(struct spi_softc *sc, struct spi_attach_args *sa,
172 int chip_select, cfdata_t cf)
173 {
174 struct spi_handle *sh;
175 device_t newdev = NULL;
176 bool is_direct = cf == NULL;
177 const int skip_flags = is_direct ? SPIH_ATTACHED
178 : (SPIH_ATTACHED | SPIH_DIRECT);
179 const int claim_flags = skip_flags ^ SPIH_DIRECT;
180 int locs[SPICF_NLOCS] = { 0 };
181
182 if (chip_select < 0 ||
183 chip_select >= sc->sc_controller.sct_nslaves) {
184 return;
185 }
186
187 sh = &sc->sc_slaves[chip_select];
188
189 mutex_enter(&sc->sc_slave_state_lock);
190 if (ISSET(sh->sh_flags, skip_flags)) {
191 mutex_exit(&sc->sc_slave_state_lock);
192 return;
193 }
194
195 /* Keep others off of this chip select. */
196 SET(sh->sh_flags, claim_flags);
197 mutex_exit(&sc->sc_slave_state_lock);
198
199 locs[SPICF_SLAVE] = chip_select;
200 sa->sa_handle = sh;
201
202 if (is_direct) {
203 newdev = config_found(sc->sc_dev, sa, spi_print_direct,
204 /* CFARG_SUBMATCH, config_stdsubmatch, XXX */
205 CFARG_LOCATORS, locs,
206 CFARG_DEVHANDLE, sa->sa_devhandle,
207 CFARG_EOL);
208 } else {
209 if (config_probe(sc->sc_dev, cf, &sa)) {
210 newdev = config_attach(sc->sc_dev, cf, &sa, spi_print,
211 CFARG_LOCATORS, locs,
212 CFARG_EOL);
213 }
214 }
215
216 if (newdev == NULL) {
217 /*
218 * Clear our claim on this chip select (yes, just
219 * the ATTACHED flag; we want to keep indirects off
220 * of chip selects for which there is a device tree
221 * node).
222 */
223 mutex_enter(&sc->sc_slave_state_lock);
224 CLR(sh->sh_flags, SPIH_ATTACHED);
225 mutex_exit(&sc->sc_slave_state_lock);
226 }
227 }
228
229 static int
230 spi_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
231 {
232 struct spi_softc *sc = device_private(parent);
233 struct spi_attach_args sa;
234
235 if (cf->cf_loc[SPICF_SLAVE] == SPICF_SLAVE_DEFAULT) {
236 /* No wildcards for indirect on SPI. */
237 return 0;
238 }
239
240 memset(&sa, 0, sizeof(sa));
241 spi_attach_child(sc, &sa, cf->cf_loc[SPICF_SLAVE], cf);
242
243 return 0;
244 }
245
246 static bool
247 spi_enumerate_devices_callback(device_t self,
248 struct spi_enumerate_devices_args *args)
249 {
250 struct spi_softc *sc = device_private(self);
251
252 spi_attach_child(sc, args->sa, args->chip_select, NULL);
253
254 return true; /* keep enumerating */
255 }
256
257 int
258 spi_compatible_match(const struct spi_attach_args *sa, const cfdata_t cf,
259 const struct device_compatible_entry *compats)
260 {
261 if (sa->sa_clist != NULL) {
262 return device_compatible_match_strlist(sa->sa_clist,
263 sa->sa_clist_size, compats);
264 }
265
266 /*
267 * In this case, we're using indirect configuration, but SPI
268 * has no real addressing system, and we've filtered out
269 * wildcarded chip selects in spi_search(), so we have no
270 * choice but to trust the user-specified config.
271 */
272 return 1;
273 }
274
275 static void
276 spi_attach(device_t parent, device_t self, void *aux)
277 {
278 struct spi_softc *sc = device_private(self);
279 struct spibus_attach_args *sba = aux;
280 int i;
281
282 sc->sc_dev = self;
283
284 aprint_naive(": SPI bus\n");
285 aprint_normal(": SPI bus\n");
286
287 mutex_init(&sc->sc_dev_lock, MUTEX_DEFAULT, IPL_NONE);
288 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
289 mutex_init(&sc->sc_slave_state_lock, MUTEX_DEFAULT, IPL_NONE);
290 cv_init(&sc->sc_cv, "spictl");
291
292 sc->sc_controller = *sba->sba_controller;
293 sc->sc_nslaves = sba->sba_controller->sct_nslaves;
294
295 /* allocate slave structures */
296 sc->sc_slaves = kmem_zalloc(sizeof(*sc->sc_slaves) * sc->sc_nslaves,
297 KM_SLEEP);
298
299 sc->sc_speed = 0;
300 sc->sc_mode = -1;
301 sc->sc_slave = -1;
302
303 /*
304 * Initialize slave handles
305 */
306 for (i = 0; i < sc->sc_nslaves; i++) {
307 sc->sc_slaves[i].sh_slave = i;
308 sc->sc_slaves[i].sh_sc = sc;
309 sc->sc_slaves[i].sh_controller = &sc->sc_controller;
310 }
311
312 /*
313 * Attempt to enumerate the devices on the bus using the
314 * platform device tree.
315 */
316 struct spi_attach_args sa = { 0 };
317 struct spi_enumerate_devices_args enumargs = {
318 .sa = &sa,
319 .callback = spi_enumerate_devices_callback,
320 };
321 device_call(self, "spi-enumerate-devices", &enumargs);
322
323 /* Then do any other devices the user may have manually wired */
324 config_search(self, NULL,
325 CFARG_SEARCH, spi_search,
326 CFARG_EOL);
327 }
328
329 CFATTACH_DECL_NEW(spi, sizeof(struct spi_softc),
330 spi_match, spi_attach, NULL, NULL);
331
332 static int
333 spi_open(dev_t dev, int flag, int fmt, lwp_t *l)
334 {
335 struct spi_softc *sc = device_lookup_private(&spi_cd, minor(dev));
336
337 if (sc == NULL)
338 return ENXIO;
339
340 return 0;
341 }
342
343 static int
344 spi_close(dev_t dev, int flag, int fmt, lwp_t *l)
345 {
346
347 return 0;
348 }
349
350 static int
351 spi_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l)
352 {
353 struct spi_softc *sc = device_lookup_private(&spi_cd, minor(dev));
354 struct spi_handle *sh;
355 spi_ioctl_configure_t *sic;
356 spi_ioctl_transfer_t *sit;
357 uint8_t *sbuf, *rbuf;
358 int error;
359
360 if (sc == NULL)
361 return ENXIO;
362
363 mutex_enter(&sc->sc_dev_lock);
364
365 switch (cmd) {
366 case SPI_IOCTL_CONFIGURE:
367 sic = (spi_ioctl_configure_t *)data;
368 if (sic->sic_addr < 0 || sic->sic_addr >= sc->sc_nslaves) {
369 error = EINVAL;
370 break;
371 }
372 sh = &sc->sc_slaves[sic->sic_addr];
373 error = spi_configure(sh, sic->sic_mode, sic->sic_speed);
374 break;
375 case SPI_IOCTL_TRANSFER:
376 sit = (spi_ioctl_transfer_t *)data;
377 if (sit->sit_addr < 0 || sit->sit_addr >= sc->sc_nslaves) {
378 error = EINVAL;
379 break;
380 }
381 if ((sit->sit_send && sit->sit_sendlen == 0)
382 || (sit->sit_recv && sit->sit_recv == 0)) {
383 error = EINVAL;
384 break;
385 }
386 sh = &sc->sc_slaves[sit->sit_addr];
387 sbuf = rbuf = NULL;
388 error = 0;
389 if (sit->sit_send && sit->sit_sendlen <= SPI_MAXDATA) {
390 sbuf = kmem_alloc(sit->sit_sendlen, KM_SLEEP);
391 error = copyin(sit->sit_send, sbuf, sit->sit_sendlen);
392 }
393 if (sit->sit_recv && sit->sit_recvlen <= SPI_MAXDATA) {
394 rbuf = kmem_alloc(sit->sit_recvlen, KM_SLEEP);
395 }
396 if (error == 0) {
397 if (sbuf && rbuf)
398 error = spi_send_recv(sh,
399 sit->sit_sendlen, sbuf,
400 sit->sit_recvlen, rbuf);
401 else if (sbuf)
402 error = spi_send(sh,
403 sit->sit_sendlen, sbuf);
404 else if (rbuf)
405 error = spi_recv(sh,
406 sit->sit_recvlen, rbuf);
407 }
408 if (rbuf) {
409 if (error == 0)
410 error = copyout(rbuf, sit->sit_recv,
411 sit->sit_recvlen);
412 kmem_free(rbuf, sit->sit_recvlen);
413 }
414 if (sbuf) {
415 kmem_free(sbuf, sit->sit_sendlen);
416 }
417 break;
418 default:
419 error = ENODEV;
420 break;
421 }
422
423 mutex_exit(&sc->sc_dev_lock);
424
425 return error;
426 }
427
428 /*
429 * API for device drivers.
430 *
431 * We provide wrapper routines to decouple the ABI for the SPI
432 * device drivers from the ABI for the SPI bus drivers.
433 */
434
435 /*
436 * Configure. This should be the first thing that the SPI driver
437 * should do, to configure which mode (e.g. SPI_MODE_0, which is the
438 * same as Philips Microwire mode), and speed. If the bus driver
439 * cannot run fast enough, then it should just configure the fastest
440 * mode that it can support. If the bus driver cannot run slow
441 * enough, then the device is incompatible and an error should be
442 * returned.
443 */
444 int
445 spi_configure(struct spi_handle *sh, int mode, int speed)
446 {
447
448 sh->sh_mode = mode;
449 sh->sh_speed = speed;
450 return 0;
451 }
452
453 /*
454 * Acquire controller
455 */
456 static void
457 spi_acquire(struct spi_handle *sh)
458 {
459 struct spi_softc *sc = sh->sh_sc;
460
461 mutex_enter(&sc->sc_lock);
462 while ((sc->sc_flags & SPIC_BUSY) != 0)
463 cv_wait(&sc->sc_cv, &sc->sc_lock);
464 sc->sc_flags |= SPIC_BUSY;
465 mutex_exit(&sc->sc_lock);
466 }
467
468 /*
469 * Release controller
470 */
471 static void
472 spi_release(struct spi_handle *sh)
473 {
474 struct spi_softc *sc = sh->sh_sc;
475
476 mutex_enter(&sc->sc_lock);
477 sc->sc_flags &= ~SPIC_BUSY;
478 cv_broadcast(&sc->sc_cv);
479 mutex_exit(&sc->sc_lock);
480 }
481
482 void
483 spi_transfer_init(struct spi_transfer *st)
484 {
485
486 mutex_init(&st->st_lock, MUTEX_DEFAULT, IPL_VM);
487 cv_init(&st->st_cv, "spixfr");
488
489 st->st_flags = 0;
490 st->st_errno = 0;
491 st->st_done = NULL;
492 st->st_chunks = NULL;
493 st->st_private = NULL;
494 st->st_slave = -1;
495 }
496
497 void
498 spi_chunk_init(struct spi_chunk *chunk, int cnt, const uint8_t *wptr,
499 uint8_t *rptr)
500 {
501
502 chunk->chunk_write = chunk->chunk_wptr = wptr;
503 chunk->chunk_read = chunk->chunk_rptr = rptr;
504 chunk->chunk_rresid = chunk->chunk_wresid = chunk->chunk_count = cnt;
505 chunk->chunk_next = NULL;
506 }
507
508 void
509 spi_transfer_add(struct spi_transfer *st, struct spi_chunk *chunk)
510 {
511 struct spi_chunk **cpp;
512
513 /* this is an O(n) insert -- perhaps we should use a simpleq? */
514 for (cpp = &st->st_chunks; *cpp; cpp = &(*cpp)->chunk_next);
515 *cpp = chunk;
516 }
517
518 int
519 spi_transfer(struct spi_handle *sh, struct spi_transfer *st)
520 {
521 struct spi_softc *sc = sh->sh_sc;
522 struct spi_controller *tag = sh->sh_controller;
523 struct spi_chunk *chunk;
524 int error;
525
526 /*
527 * Initialize "resid" counters and pointers, so that callers
528 * and bus drivers don't have to.
529 */
530 for (chunk = st->st_chunks; chunk; chunk = chunk->chunk_next) {
531 chunk->chunk_wresid = chunk->chunk_rresid = chunk->chunk_count;
532 chunk->chunk_wptr = chunk->chunk_write;
533 chunk->chunk_rptr = chunk->chunk_read;
534 }
535
536 /*
537 * Match slave and parameters to handle
538 */
539 st->st_slave = sh->sh_slave;
540
541 /*
542 * Reserve controller during transaction
543 */
544 spi_acquire(sh);
545
546 st->st_spiprivate = (void *)sh;
547
548 /*
549 * Reconfigure controller
550 *
551 * XXX backends don't configure per-slave parameters
552 * Whenever we switch slaves or change mode or speed, we
553 * need to tell the backend.
554 */
555 if (sc->sc_slave != sh->sh_slave
556 || sc->sc_mode != sh->sh_mode
557 || sc->sc_speed != sh->sh_speed) {
558 error = (*tag->sct_configure)(tag->sct_cookie,
559 sh->sh_slave, sh->sh_mode, sh->sh_speed);
560 if (error)
561 return error;
562 }
563 sc->sc_mode = sh->sh_mode;
564 sc->sc_speed = sh->sh_speed;
565 sc->sc_slave = sh->sh_slave;
566
567 error = (*tag->sct_transfer)(tag->sct_cookie, st);
568
569 return error;
570 }
571
572 void
573 spi_wait(struct spi_transfer *st)
574 {
575 struct spi_handle *sh = st->st_spiprivate;
576
577 mutex_enter(&st->st_lock);
578 while (!(st->st_flags & SPI_F_DONE)) {
579 cv_wait(&st->st_cv, &st->st_lock);
580 }
581 mutex_exit(&st->st_lock);
582 cv_destroy(&st->st_cv);
583 mutex_destroy(&st->st_lock);
584
585 /*
586 * End transaction
587 */
588 spi_release(sh);
589 }
590
591 void
592 spi_done(struct spi_transfer *st, int err)
593 {
594
595 mutex_enter(&st->st_lock);
596 if ((st->st_errno = err) != 0) {
597 st->st_flags |= SPI_F_ERROR;
598 }
599 st->st_flags |= SPI_F_DONE;
600 if (st->st_done != NULL) {
601 (*st->st_done)(st);
602 } else {
603 cv_broadcast(&st->st_cv);
604 }
605 mutex_exit(&st->st_lock);
606 }
607
608 /*
609 * Some convenience routines. These routines block until the work
610 * is done.
611 *
612 * spi_recv - receives data from the bus
613 *
614 * spi_send - sends data to the bus
615 *
616 * spi_send_recv - sends data to the bus, and then receives. Note that this is
617 * done synchronously, i.e. send a command and get the response. This is
618 * not full duplex. If you wnat full duplex, you can't use these convenience
619 * wrappers.
620 */
621 int
622 spi_recv(struct spi_handle *sh, int cnt, uint8_t *data)
623 {
624 struct spi_transfer trans;
625 struct spi_chunk chunk;
626
627 spi_transfer_init(&trans);
628 spi_chunk_init(&chunk, cnt, NULL, data);
629 spi_transfer_add(&trans, &chunk);
630
631 /* enqueue it and wait for it to complete */
632 spi_transfer(sh, &trans);
633 spi_wait(&trans);
634
635 if (trans.st_flags & SPI_F_ERROR)
636 return trans.st_errno;
637
638 return 0;
639 }
640
641 int
642 spi_send(struct spi_handle *sh, int cnt, const uint8_t *data)
643 {
644 struct spi_transfer trans;
645 struct spi_chunk chunk;
646
647 spi_transfer_init(&trans);
648 spi_chunk_init(&chunk, cnt, data, NULL);
649 spi_transfer_add(&trans, &chunk);
650
651 /* enqueue it and wait for it to complete */
652 spi_transfer(sh, &trans);
653 spi_wait(&trans);
654
655 if (trans.st_flags & SPI_F_ERROR)
656 return trans.st_errno;
657
658 return 0;
659 }
660
661 int
662 spi_send_recv(struct spi_handle *sh, int scnt, const uint8_t *snd,
663 int rcnt, uint8_t *rcv)
664 {
665 struct spi_transfer trans;
666 struct spi_chunk chunk1, chunk2;
667
668 spi_transfer_init(&trans);
669 spi_chunk_init(&chunk1, scnt, snd, NULL);
670 spi_chunk_init(&chunk2, rcnt, NULL, rcv);
671 spi_transfer_add(&trans, &chunk1);
672 spi_transfer_add(&trans, &chunk2);
673
674 /* enqueue it and wait for it to complete */
675 spi_transfer(sh, &trans);
676 spi_wait(&trans);
677
678 if (trans.st_flags & SPI_F_ERROR)
679 return trans.st_errno;
680
681 return 0;
682 }
683