1*cbab9cadSchs /* $Id: mpcsa_spi.c,v 1.3 2012/10/27 17:17:48 chs Exp $ */
2*cbab9cadSchs /* $NetBSD: mpcsa_spi.c,v 1.3 2012/10/27 17:17:48 chs Exp $ */
3c62a0ac4Smatt
4c62a0ac4Smatt /*
5c62a0ac4Smatt * Copyright (c) 2007 Embedtronics Oy. All rights reserved.
6c62a0ac4Smatt *
7c62a0ac4Smatt * Redistribution and use in source and binary forms, with or without
8c62a0ac4Smatt * modification, are permitted provided that the following conditions
9c62a0ac4Smatt * are met:
10c62a0ac4Smatt * 1. Redistributions of source code must retain the above copyright
11c62a0ac4Smatt * notice, this list of conditions and the following disclaimer.
12c62a0ac4Smatt * 2. Redistributions in binary form must reproduce the above copyright
13c62a0ac4Smatt * notice, this list of conditions and the following disclaimer in the
14c62a0ac4Smatt * documentation and/or other materials provided with the distribution.
15c62a0ac4Smatt *
16c62a0ac4Smatt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17c62a0ac4Smatt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18c62a0ac4Smatt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19c62a0ac4Smatt * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20c62a0ac4Smatt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21c62a0ac4Smatt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22c62a0ac4Smatt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23c62a0ac4Smatt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24c62a0ac4Smatt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25c62a0ac4Smatt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26c62a0ac4Smatt * SUCH DAMAGE.
27c62a0ac4Smatt */
28c62a0ac4Smatt
29c62a0ac4Smatt #include <sys/cdefs.h>
30*cbab9cadSchs __KERNEL_RCSID(0, "$NetBSD: mpcsa_spi.c,v 1.3 2012/10/27 17:17:48 chs Exp $");
31c62a0ac4Smatt
32c62a0ac4Smatt #include <sys/param.h>
33c62a0ac4Smatt #include <sys/systm.h>
34c62a0ac4Smatt #include <sys/kernel.h>
35c62a0ac4Smatt #include <sys/device.h>
36c62a0ac4Smatt #include <sys/lock.h>
37c62a0ac4Smatt #include <arm/at91/at91reg.h>
38c62a0ac4Smatt #include <arm/at91/at91var.h>
39c62a0ac4Smatt #include <arm/at91/at91spivar.h>
40c62a0ac4Smatt #include <arm/at91/at91piovar.h>
41c62a0ac4Smatt
42c62a0ac4Smatt #ifdef MPCSA_SPI_DEBUG
43c62a0ac4Smatt int mpcsa_spi_debug = MPCSA_SPI_DEBUG;
44c62a0ac4Smatt #define DPRINTFN(n,x) if (mpcsa_spi_debug>(n)) printf x;
45c62a0ac4Smatt #else
46c62a0ac4Smatt #define DPRINTFN(n,x)
47c62a0ac4Smatt #endif
48c62a0ac4Smatt
49c62a0ac4Smatt struct at91pio_softc;
50c62a0ac4Smatt
51c62a0ac4Smatt struct mpcsa_spi_softc {
52*cbab9cadSchs struct at91spi_softc sc_at91spi;
53c62a0ac4Smatt struct at91pio_softc *sc_pioa, *sc_piod;
54c62a0ac4Smatt };
55c62a0ac4Smatt
56*cbab9cadSchs static int mpcsa_spi_match(device_t, cfdata_t, void *);
57*cbab9cadSchs static void mpcsa_spi_attach(device_t, device_t, void *);
58c62a0ac4Smatt
59*cbab9cadSchs CFATTACH_DECL_NEW(mpcsa_spi, sizeof(struct mpcsa_spi_softc),
60c62a0ac4Smatt mpcsa_spi_match, mpcsa_spi_attach, NULL, NULL);
61c62a0ac4Smatt
62c62a0ac4Smatt static int mpcsa_spi_select(void *self, int sel);
63c62a0ac4Smatt
64c62a0ac4Smatt struct at91spi_machdep mpcsa_spi_tag = {
65c62a0ac4Smatt mpcsa_spi_select
66c62a0ac4Smatt };
67c62a0ac4Smatt
68c62a0ac4Smatt static int
mpcsa_spi_match(device_t parent,cfdata_t match,void * aux)69*cbab9cadSchs mpcsa_spi_match(device_t parent, cfdata_t match, void *aux)
70c62a0ac4Smatt {
71c62a0ac4Smatt if (strcmp(match->cf_name, "at91spi") == 0 && strcmp(match->cf_atname, "mpcsa_spi") == 0)
72c62a0ac4Smatt return 2;
73c62a0ac4Smatt return 0;
74c62a0ac4Smatt }
75c62a0ac4Smatt
76c62a0ac4Smatt #define GPIO_SPICS0(func) (func)(sc->sc_pioa, 3)
77c62a0ac4Smatt #define GPIO_SPICS1(func) (func)(sc->sc_pioa, 4)
78c62a0ac4Smatt #define GPIO_SPICS2(func) (func)(sc->sc_piod, 19)
79c62a0ac4Smatt
80c62a0ac4Smatt
81c62a0ac4Smatt static void
mpcsa_spi_attach(device_t parent,device_t self,void * aux)82*cbab9cadSchs mpcsa_spi_attach(device_t parent, device_t self, void *aux)
83c62a0ac4Smatt {
84*cbab9cadSchs struct mpcsa_spi_softc *sc = device_private(self);
85c62a0ac4Smatt
86c62a0ac4Smatt // do some checks
87c62a0ac4Smatt if ((sc->sc_pioa = at91pio_sc(AT91_PIOA)) == NULL) {
88c62a0ac4Smatt printf("no PIOA!\n");
89c62a0ac4Smatt return;
90c62a0ac4Smatt }
91c62a0ac4Smatt if ((sc->sc_piod = at91pio_sc(AT91_PIOD)) == NULL) {
92c62a0ac4Smatt printf("no PIOD!\n");
93c62a0ac4Smatt return;
94c62a0ac4Smatt }
95c62a0ac4Smatt
96c62a0ac4Smatt // initialize softc
97*cbab9cadSchs sc->sc_at91spi.sc_spi.sct_nslaves = 3; // number of slaves
98c62a0ac4Smatt
99c62a0ac4Smatt // configure GPIO
100c62a0ac4Smatt GPIO_SPICS0(at91pio_out); GPIO_SPICS0(at91pio_set);
101c62a0ac4Smatt GPIO_SPICS1(at91pio_out); GPIO_SPICS1(at91pio_set);
102c62a0ac4Smatt GPIO_SPICS2(at91pio_out); GPIO_SPICS2(at91pio_set);
103c62a0ac4Smatt
104c62a0ac4Smatt // and call common routine
105c62a0ac4Smatt at91spi_attach_common(parent, self, aux, &mpcsa_spi_tag);
106c62a0ac4Smatt }
107c62a0ac4Smatt
mpcsa_spi_select(void * self,int sel)108c62a0ac4Smatt static int mpcsa_spi_select(void *self, int sel)
109c62a0ac4Smatt {
110*cbab9cadSchs struct mpcsa_spi_softc *sc = device_private(self);
111c62a0ac4Smatt
112c62a0ac4Smatt /* first deselect everything */
113c62a0ac4Smatt GPIO_SPICS0(at91pio_set);
114c62a0ac4Smatt GPIO_SPICS1(at91pio_set);
115c62a0ac4Smatt GPIO_SPICS2(at91pio_set);
116c62a0ac4Smatt
117c62a0ac4Smatt /* then select wanted target */
118c62a0ac4Smatt switch (sel) {
119c62a0ac4Smatt case -1:
120c62a0ac4Smatt break;
121c62a0ac4Smatt case 0:
122c62a0ac4Smatt GPIO_SPICS0(at91pio_clear);
123c62a0ac4Smatt break;
124c62a0ac4Smatt case 1:
125c62a0ac4Smatt GPIO_SPICS2(at91pio_clear);
126c62a0ac4Smatt break;
127c62a0ac4Smatt case 2:
128c62a0ac4Smatt GPIO_SPICS2(at91pio_clear);
129c62a0ac4Smatt break;
130c62a0ac4Smatt default:
131c62a0ac4Smatt return EINVAL;
132c62a0ac4Smatt }
133c62a0ac4Smatt
134c62a0ac4Smatt return 0;
135c62a0ac4Smatt }
136