xref: /netbsd-src/sys/arch/arm/s3c2xx0/s3c2440_spi.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
177b78cdcSnisimura /*-
277b78cdcSnisimura  * Copyright (c) 2012 The NetBSD Foundation, Inc.
377b78cdcSnisimura  * All rights reserved.
477b78cdcSnisimura  *
577b78cdcSnisimura  * This code is derived from software contributed to The NetBSD Foundation
677b78cdcSnisimura  * by Paul Fleischer <paul@xpg.dk>
777b78cdcSnisimura  *
877b78cdcSnisimura  * Redistribution and use in source and binary forms, with or without
977b78cdcSnisimura  * modification, are permitted provided that the following conditions
1077b78cdcSnisimura  * are met:
1177b78cdcSnisimura  * 1. Redistributions of source code must retain the above copyright
1277b78cdcSnisimura  *    notice, this list of conditions and the following disclaimer.
1377b78cdcSnisimura  * 2. Redistributions in binary form must reproduce the above copyright
1477b78cdcSnisimura  *    notice, this list of conditions and the following disclaimer in the
1577b78cdcSnisimura  *    documentation and/or other materials provided with the distribution.
1677b78cdcSnisimura  *
1777b78cdcSnisimura  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1877b78cdcSnisimura  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1977b78cdcSnisimura  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2077b78cdcSnisimura  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2177b78cdcSnisimura  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2277b78cdcSnisimura  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2377b78cdcSnisimura  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2477b78cdcSnisimura  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2577b78cdcSnisimura  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2677b78cdcSnisimura  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2777b78cdcSnisimura  * POSSIBILITY OF SUCH DAMAGE.
2877b78cdcSnisimura  */
2977b78cdcSnisimura 
3077b78cdcSnisimura /* Derived from s3c2410_spi.c */
3177b78cdcSnisimura 
3277b78cdcSnisimura /*
3377b78cdcSnisimura  * Copyright (c) 2004  Genetec Corporation.  All rights reserved.
3477b78cdcSnisimura  * Written by Hiroyuki Bessho for Genetec Corporation.
3577b78cdcSnisimura  *
3677b78cdcSnisimura  * Redistribution and use in source and binary forms, with or without
3777b78cdcSnisimura  * modification, are permitted provided that the following conditions
3877b78cdcSnisimura  * are met:
3977b78cdcSnisimura  * 1. Redistributions of source code must retain the above copyright
4077b78cdcSnisimura  *    notice, this list of conditions and the following disclaimer.
4177b78cdcSnisimura  * 2. Redistributions in binary form must reproduce the above copyright
4277b78cdcSnisimura  *    notice, this list of conditions and the following disclaimer in the
4377b78cdcSnisimura  *    documentation and/or other materials provided with the distribution.
4477b78cdcSnisimura  * 3. The name of Genetec Corporation may not be used to endorse or
4577b78cdcSnisimura  *    promote products derived from this software without specific prior
4677b78cdcSnisimura  *    written permission.
4777b78cdcSnisimura  *
4877b78cdcSnisimura  * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
4977b78cdcSnisimura  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
5077b78cdcSnisimura  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5177b78cdcSnisimura  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
5277b78cdcSnisimura  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
5377b78cdcSnisimura  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
5477b78cdcSnisimura  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5577b78cdcSnisimura  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
5677b78cdcSnisimura  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5777b78cdcSnisimura  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
5877b78cdcSnisimura  * POSSIBILITY OF SUCH DAMAGE.
5977b78cdcSnisimura  */
6077b78cdcSnisimura 
6177b78cdcSnisimura /*
6277b78cdcSnisimura  * Support S3C2440's SPI dirver.
6377b78cdcSnisimura  * Real works are done by drivers attached to SPI ports.
6477b78cdcSnisimura  */
6577b78cdcSnisimura 
6677b78cdcSnisimura #include <sys/cdefs.h>
67*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: s3c2440_spi.c,v 1.4 2021/08/07 16:18:45 thorpej Exp $");
6877b78cdcSnisimura 
6977b78cdcSnisimura #include <sys/param.h>
7077b78cdcSnisimura #include <sys/systm.h>
7177b78cdcSnisimura #include <sys/conf.h>
7277b78cdcSnisimura 
7377b78cdcSnisimura #include <sys/mutex.h>
7477b78cdcSnisimura #include <sys/condvar.h>
7577b78cdcSnisimura 
7677b78cdcSnisimura #include <sys/bus.h>
7777b78cdcSnisimura #include <machine/cpu.h>
7877b78cdcSnisimura 
7977b78cdcSnisimura #include <arm/s3c2xx0/s3c24x0var.h>
8077b78cdcSnisimura #include <arm/s3c2xx0/s3c24x0reg.h>
8177b78cdcSnisimura #include <arm/s3c2xx0/s3c2440reg.h>
8277b78cdcSnisimura 
8377b78cdcSnisimura #include <arm/s3c2xx0/s3c24x0_spi.h>
8477b78cdcSnisimura 
8577b78cdcSnisimura #include "locators.h"
8677b78cdcSnisimura 
8777b78cdcSnisimura struct ssspi_softc {
8877b78cdcSnisimura 	bus_space_tag_t		iot;
8977b78cdcSnisimura 	bus_space_handle_t	ioh;
9077b78cdcSnisimura 	short			index;
9177b78cdcSnisimura 
9277b78cdcSnisimura 	void			*sc_ih;
9377b78cdcSnisimura 	struct kmutex		sc_intr_mtx;
9477b78cdcSnisimura 	struct kcondvar		sc_intr_cv;
9577b78cdcSnisimura 	uint8_t			sc_rxbyte;
9677b78cdcSnisimura 	bool			sc_received;
9777b78cdcSnisimura };
9877b78cdcSnisimura 
9977b78cdcSnisimura 
10077b78cdcSnisimura /* prototypes */
101cbab9cadSchs static int	ssspi_match(device_t, cfdata_t, void *);
102cbab9cadSchs static void	ssspi_attach(device_t, device_t, void *);
103cbab9cadSchs static int	ssspi_search(device_t, cfdata_t, const int *, void *);
10477b78cdcSnisimura static int	ssspi_print(void *, const char *);
10577b78cdcSnisimura  int	ssspi_intr(void *arg);
10677b78cdcSnisimura 
10777b78cdcSnisimura /* attach structures */
108cbab9cadSchs CFATTACH_DECL_NEW(ssspi, sizeof(struct ssspi_softc), ssspi_match, ssspi_attach,
10977b78cdcSnisimura     NULL, NULL);
11077b78cdcSnisimura 
11177b78cdcSnisimura 
11277b78cdcSnisimura static int
ssspi_print(void * aux,const char * name)11377b78cdcSnisimura ssspi_print(void *aux, const char *name)
11477b78cdcSnisimura {
11577b78cdcSnisimura 	struct ssspi_attach_args *spia = aux;
11677b78cdcSnisimura 
11777b78cdcSnisimura 	if (spia->spia_aux_intr != SSSPICF_INTR_DEFAULT)
11877b78cdcSnisimura 		printf(" intr %d", spia->spia_aux_intr);
11977b78cdcSnisimura 	return (UNCONF);
12077b78cdcSnisimura }
12177b78cdcSnisimura 
12277b78cdcSnisimura int
ssspi_match(device_t parent,cfdata_t match,void * aux)123cbab9cadSchs ssspi_match(device_t parent, cfdata_t match, void *aux)
12477b78cdcSnisimura {
12577b78cdcSnisimura 	struct s3c2xx0_attach_args *sa = aux;
12677b78cdcSnisimura 
12777b78cdcSnisimura 	/* S3C2440 have only two SPIs */
12877b78cdcSnisimura 	switch (sa->sa_index) {
12977b78cdcSnisimura 	case 0:
13077b78cdcSnisimura 	case 1:
13177b78cdcSnisimura 		break;
13277b78cdcSnisimura 	default:
13377b78cdcSnisimura 		return 0;
13477b78cdcSnisimura 	}
13577b78cdcSnisimura 
13677b78cdcSnisimura 	return 1;
13777b78cdcSnisimura }
13877b78cdcSnisimura 
13977b78cdcSnisimura void
ssspi_attach(device_t parent,device_t self,void * aux)140cbab9cadSchs ssspi_attach(device_t parent, device_t self, void *aux)
14177b78cdcSnisimura {
142cbab9cadSchs 	struct ssspi_softc *sc = device_private(self);
143cbab9cadSchs 	struct s3c2xx0_attach_args *sa = aux;
14477b78cdcSnisimura 	bus_space_tag_t iot = sa->sa_iot;
14577b78cdcSnisimura 
14677b78cdcSnisimura 	static bus_space_handle_t spi_ioh = 0;
14777b78cdcSnisimura 
14877b78cdcSnisimura 	/* we map all registers for SPI0 and SPI1 at once, then
14977b78cdcSnisimura 	   use subregions */
15077b78cdcSnisimura 	if (spi_ioh == 0) {
15177b78cdcSnisimura 		if (bus_space_map(iot, S3C2440_SPI0_BASE,
15277b78cdcSnisimura 				  2 * S3C24X0_SPI_SIZE,
15377b78cdcSnisimura 				  0, &spi_ioh)) {
15477b78cdcSnisimura 			aprint_error(": can't map registers\n");
15577b78cdcSnisimura 			return;
15677b78cdcSnisimura 		}
15777b78cdcSnisimura 	}
15877b78cdcSnisimura 
15977b78cdcSnisimura 	aprint_normal("\n");
16077b78cdcSnisimura 
16177b78cdcSnisimura 	sc->index = sa->sa_index;
16277b78cdcSnisimura 	sc->iot = iot;
16377b78cdcSnisimura 
16477b78cdcSnisimura 	bus_space_subregion(iot, spi_ioh, sc->index == 0 ? 0 : S3C24X0_SPI_SIZE,
16577b78cdcSnisimura 	    S3C24X0_SPI_SIZE, &sc->ioh);
16677b78cdcSnisimura 
16777b78cdcSnisimura 	mutex_init(&sc->sc_intr_mtx, MUTEX_DEFAULT, IPL_BIO);
16877b78cdcSnisimura 	cv_init(&sc->sc_intr_cv, "S3C2440_spiintr");
16977b78cdcSnisimura 
17077b78cdcSnisimura 	/*
17177b78cdcSnisimura 	 *  Attach child devices
17277b78cdcSnisimura 	 */
1732685996bSthorpej 	config_search(self, NULL,
174*c7fb772bSthorpej 	    CFARGS(.search = ssspi_search));
17577b78cdcSnisimura }
17677b78cdcSnisimura 
17777b78cdcSnisimura int
ssspi_search(device_t parent,cfdata_t cf,const int * ldesc,void * aux)178cbab9cadSchs ssspi_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
17977b78cdcSnisimura {
180cbab9cadSchs 	struct ssspi_softc *sc = device_private(parent);
18177b78cdcSnisimura 	struct ssspi_attach_args spia;
18277b78cdcSnisimura 	static const unsigned char intr[] = { S3C24X0_INT_SPI0,
18377b78cdcSnisimura 					      S3C2440_INT_SPI1 };
18477b78cdcSnisimura 
18577b78cdcSnisimura 	KASSERT(sc->index == 0 || sc->index == 1);
18677b78cdcSnisimura 
18777b78cdcSnisimura 	spia.spia_iot = sc->iot;
18877b78cdcSnisimura 	spia.spia_ioh = sc->ioh;
18977b78cdcSnisimura 	spia.spia_gpioh = s3c2xx0_softc->sc_gpio_ioh;
19077b78cdcSnisimura 	spia.spia_index = sc->index;
19177b78cdcSnisimura 	spia.spia_intr = intr[sc->index];
19277b78cdcSnisimura 	spia.spia_aux_intr = cf->cf_loc[SSSPICF_INTR];
19377b78cdcSnisimura 	spia.spia_dmat = s3c2xx0_softc->sc_dmat;
19477b78cdcSnisimura 
1952685996bSthorpej 	if (config_probe(parent, cf, &spia))
196*c7fb772bSthorpej 		config_attach(parent, cf, &spia, ssspi_print, CFARGS_NONE);
19777b78cdcSnisimura 
19877b78cdcSnisimura 	return 0;
19977b78cdcSnisimura }
20077b78cdcSnisimura 
20177b78cdcSnisimura /*
20277b78cdcSnisimura  * Intiialze SPI port. called by child devices.
20377b78cdcSnisimura  */
20477b78cdcSnisimura int
s3c24x0_spi_setup(struct ssspi_softc * sc,uint32_t mode,int bps,int use_ss)20577b78cdcSnisimura s3c24x0_spi_setup(struct ssspi_softc *sc, uint32_t mode, int bps, int use_ss)
20677b78cdcSnisimura {
20777b78cdcSnisimura 	int pclk = s3c2xx0_softc->sc_pclk;
20877b78cdcSnisimura 	int prescaler;
20977b78cdcSnisimura 	uint32_t pgcon, pecon, peup;
21077b78cdcSnisimura 	bus_space_handle_t gpioh = s3c2xx0_softc->sc_gpio_ioh;
21177b78cdcSnisimura 	bus_space_tag_t iot = sc->iot;
21277b78cdcSnisimura 
21377b78cdcSnisimura 	if (bps > 1) {
21477b78cdcSnisimura 		prescaler = pclk / 2 / bps - 1;
21577b78cdcSnisimura 
21677b78cdcSnisimura 		if (prescaler <= 0 || 0xff < prescaler)
21777b78cdcSnisimura 			return -1;
21877b78cdcSnisimura 		bus_space_write_1(sc->iot, sc->ioh, SPI_SPPRE, prescaler);
21977b78cdcSnisimura 	}
22077b78cdcSnisimura 
22177b78cdcSnisimura 	if (sc->index == 0) {
22277b78cdcSnisimura 		pecon = bus_space_read_4(iot, gpioh, GPIO_PECON);
22377b78cdcSnisimura 
22477b78cdcSnisimura 		if (use_ss) {
22577b78cdcSnisimura 			pgcon = bus_space_read_4(iot, gpioh, GPIO_PGCON);
22677b78cdcSnisimura 			pgcon = GPIO_SET_FUNC(pgcon, 2, PCON_ALTFUN2);
22777b78cdcSnisimura 			bus_space_write_4(iot, gpioh, GPIO_PGCON, pgcon);
22877b78cdcSnisimura 		}
22977b78cdcSnisimura 
23077b78cdcSnisimura 		pecon = GPIO_SET_FUNC(pecon, 11, PCON_ALTFUN); /* SPIMISO0 */
23177b78cdcSnisimura 		pecon = GPIO_SET_FUNC(pecon, 12, PCON_ALTFUN); /* SPIMOSI0 */
23277b78cdcSnisimura 		pecon = GPIO_SET_FUNC(pecon, 13, PCON_ALTFUN); /* SPICL0 */
23377b78cdcSnisimura 
23477b78cdcSnisimura 		bus_space_write_4(iot, gpioh, GPIO_PECON, pecon);
23577b78cdcSnisimura 
23677b78cdcSnisimura 		/* Enable pull-up for pin 11, 12, and 13*/
23777b78cdcSnisimura 		peup = bus_space_read_4(iot, gpioh, GPIO_PEUP);
23877b78cdcSnisimura 		peup &= ~(1<<11);
23977b78cdcSnisimura 		peup &= ~(1<<12);
24077b78cdcSnisimura 		peup &= ~(1<<13);
24177b78cdcSnisimura 		bus_space_write_4(iot, gpioh, GPIO_PEUP, peup);
24277b78cdcSnisimura 
24377b78cdcSnisimura 		sc->sc_ih = s3c24x0_intr_establish(S3C24X0_INT_SPI0, IPL_BIO,
24477b78cdcSnisimura 						   IST_EDGE_RISING, ssspi_intr,
24577b78cdcSnisimura 						   sc);
24677b78cdcSnisimura 		printf("ih: %p\n", sc->sc_ih);
24777b78cdcSnisimura 	} else {
24877b78cdcSnisimura 		pgcon = bus_space_read_4(iot, gpioh, GPIO_PGCON);
24977b78cdcSnisimura 
25077b78cdcSnisimura 		if (use_ss)
25177b78cdcSnisimura 			pgcon = GPIO_SET_FUNC(pgcon, 3, PCON_ALTFUN2);
25277b78cdcSnisimura 
25377b78cdcSnisimura 		pgcon = GPIO_SET_FUNC(pgcon, 5, PCON_ALTFUN2); /* SPIMISO1 */
25477b78cdcSnisimura 		pgcon = GPIO_SET_FUNC(pgcon, 6, PCON_ALTFUN2); /* SPIMOSI1 */
25577b78cdcSnisimura 		pgcon = GPIO_SET_FUNC(pgcon, 7, PCON_ALTFUN2); /* SPICLK1 */
25677b78cdcSnisimura 
25777b78cdcSnisimura 		bus_space_write_4(iot, gpioh, GPIO_PGCON, pgcon);
25877b78cdcSnisimura 
25977b78cdcSnisimura 		/* Enable pull-up for pin 5, 6, and 7*/
26077b78cdcSnisimura 		peup = bus_space_read_4(iot, gpioh, GPIO_PGUP);
26177b78cdcSnisimura 		peup &= ~(1<<5);
26277b78cdcSnisimura 		peup &= ~(1<<6);
26377b78cdcSnisimura 		peup &= ~(1<<7);
26477b78cdcSnisimura 		bus_space_write_4(iot, gpioh, GPIO_PGUP, peup);
26577b78cdcSnisimura 
26677b78cdcSnisimura 	}
26777b78cdcSnisimura 
26877b78cdcSnisimura 	bus_space_write_4(iot, sc->ioh, SPI_SPCON, mode);
26977b78cdcSnisimura 
27077b78cdcSnisimura 	return 0;
27177b78cdcSnisimura }
27277b78cdcSnisimura 
27377b78cdcSnisimura int
s3c24x0_spi_master_send(struct ssspi_softc * sc,uint8_t value)27477b78cdcSnisimura s3c24x0_spi_master_send(struct ssspi_softc *sc, uint8_t value)
27577b78cdcSnisimura {
27677b78cdcSnisimura 	sc->sc_received = FALSE;
27777b78cdcSnisimura 	bus_space_write_1(sc->iot, sc->ioh, SPI_SPTDAT, value);
27877b78cdcSnisimura 
27977b78cdcSnisimura 	return 0;
28077b78cdcSnisimura }
28177b78cdcSnisimura 
28277b78cdcSnisimura void
s3c24x0_spi_spin_wait(struct ssspi_softc * sc)28377b78cdcSnisimura s3c24x0_spi_spin_wait(struct ssspi_softc *sc)
28477b78cdcSnisimura {
28577b78cdcSnisimura 	uint32_t reg;
28677b78cdcSnisimura 	do {
28777b78cdcSnisimura 		reg = bus_space_read_4(sc->iot, sc->ioh, SPI_SPSTA);
28877b78cdcSnisimura 	} while(! (reg & SPSTA_REDY));
28977b78cdcSnisimura }
29077b78cdcSnisimura 
29177b78cdcSnisimura int
s3c24x0_spi_wait(struct ssspi_softc * sc,uint8_t * valPtr)29277b78cdcSnisimura s3c24x0_spi_wait(struct ssspi_softc *sc, uint8_t *valPtr)
29377b78cdcSnisimura {
29477b78cdcSnisimura #if 0
29577b78cdcSnisimura 	uint32_t reg;
29677b78cdcSnisimura 	do {
29777b78cdcSnisimura 		reg = bus_space_read_4(sc->iot, sc->ioh, SPI_SPSTA);
29877b78cdcSnisimura 	} while(!(reg & SPSTA_REDY));
29977b78cdcSnisimura 
30077b78cdcSnisimura #else
30177b78cdcSnisimura 	mutex_enter(&sc->sc_intr_mtx);
30277b78cdcSnisimura 	while( sc->sc_received == FALSE) {
30377b78cdcSnisimura 		cv_wait(&sc->sc_intr_cv, &sc->sc_intr_mtx);
30477b78cdcSnisimura 	}
30577b78cdcSnisimura 	mutex_exit(&sc->sc_intr_mtx);
30677b78cdcSnisimura #endif
30777b78cdcSnisimura 
30877b78cdcSnisimura 	if (valPtr != NULL) {
30977b78cdcSnisimura 		//	*valPtr = bus_space_read_1(sc->iot, sc->ioh, SPI_SPRDAT);
31077b78cdcSnisimura 		*valPtr = sc->sc_rxbyte;
31177b78cdcSnisimura 	}
31277b78cdcSnisimura 
31377b78cdcSnisimura 	return 0;
31477b78cdcSnisimura }
31577b78cdcSnisimura 
31677b78cdcSnisimura int
s3c24x0_spi_bps(struct ssspi_softc * sc,int bps)31777b78cdcSnisimura s3c24x0_spi_bps(struct ssspi_softc *sc, int bps)
31877b78cdcSnisimura {
31977b78cdcSnisimura 	int pclk = s3c2xx0_softc->sc_pclk;
32077b78cdcSnisimura 	int prescaler;
32177b78cdcSnisimura 
32277b78cdcSnisimura 	if (bps > 1) {
32377b78cdcSnisimura 		prescaler = pclk / 2 / bps - 1;
32477b78cdcSnisimura 
32577b78cdcSnisimura 		if (prescaler <= 0 || 0xff < prescaler)
32677b78cdcSnisimura 			return -1;
32777b78cdcSnisimura 		bus_space_write_1(sc->iot, sc->ioh, SPI_SPPRE, prescaler);
32877b78cdcSnisimura 	}
32977b78cdcSnisimura 
33077b78cdcSnisimura 	return 0;
33177b78cdcSnisimura }
33277b78cdcSnisimura 
33377b78cdcSnisimura int
ssspi_intr(void * arg)33477b78cdcSnisimura ssspi_intr(void *arg)
33577b78cdcSnisimura {
33677b78cdcSnisimura #if 1
33777b78cdcSnisimura 	uint32_t reg;
33877b78cdcSnisimura 	struct ssspi_softc *sc;
33977b78cdcSnisimura 
34077b78cdcSnisimura 	sc = (struct ssspi_softc*)arg;
34177b78cdcSnisimura 
34277b78cdcSnisimura 	reg = bus_space_read_4(sc->iot, sc->ioh, SPI_SPSTA);
34377b78cdcSnisimura 	if (reg & SPSTA_REDY) {
34477b78cdcSnisimura 		sc->sc_rxbyte = bus_space_read_1(sc->iot, sc->ioh, SPI_SPRDAT);
34577b78cdcSnisimura 
34677b78cdcSnisimura 		mutex_enter(&sc->sc_intr_mtx);
34777b78cdcSnisimura 		sc->sc_received = TRUE;
34877b78cdcSnisimura 		cv_broadcast(&sc->sc_intr_cv);
34977b78cdcSnisimura 		mutex_exit(&sc->sc_intr_mtx);
35077b78cdcSnisimura 	}
35177b78cdcSnisimura #endif
35277b78cdcSnisimura 	return 1;
35377b78cdcSnisimura }
354