Home | History | Annotate | Line # | Download | only in dev
wzero3_ssp.c revision 1.4.12.1
      1  1.4.12.1    yamt /*	$NetBSD: wzero3_ssp.c,v 1.4.12.1 2012/04/17 00:06:24 yamt Exp $	*/
      2       1.1  nonaka 
      3  1.4.12.1    yamt /*-
      4  1.4.12.1    yamt  * Copyright (C) 2010 NONAKA Kimihiro <nonaka (at) netbsd.org>
      5       1.1  nonaka  * All rights reserved.
      6       1.1  nonaka  *
      7       1.1  nonaka  * Redistribution and use in source and binary forms, with or without
      8       1.1  nonaka  * modification, are permitted provided that the following conditions
      9       1.1  nonaka  * are met:
     10       1.1  nonaka  * 1. Redistributions of source code must retain the above copyright
     11       1.1  nonaka  *    notice, this list of conditions and the following disclaimer.
     12       1.1  nonaka  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1  nonaka  *    notice, this list of conditions and the following disclaimer in the
     14       1.1  nonaka  *    documentation and/or other materials provided with the distribution.
     15       1.1  nonaka  *
     16  1.4.12.1    yamt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  1.4.12.1    yamt  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  1.4.12.1    yamt  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  1.4.12.1    yamt  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  1.4.12.1    yamt  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  1.4.12.1    yamt  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  1.4.12.1    yamt  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  1.4.12.1    yamt  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  1.4.12.1    yamt  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  1.4.12.1    yamt  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26       1.1  nonaka  */
     27       1.1  nonaka 
     28       1.1  nonaka #include <sys/cdefs.h>
     29  1.4.12.1    yamt __KERNEL_RCSID(0, "$NetBSD: wzero3_ssp.c,v 1.4.12.1 2012/04/17 00:06:24 yamt Exp $");
     30       1.1  nonaka 
     31       1.1  nonaka #include <sys/param.h>
     32       1.1  nonaka #include <sys/systm.h>
     33       1.1  nonaka #include <sys/device.h>
     34       1.1  nonaka #include <sys/mutex.h>
     35       1.1  nonaka #include <sys/pmf.h>
     36       1.1  nonaka #include <sys/bus.h>
     37       1.1  nonaka 
     38       1.1  nonaka #include <machine/bootinfo.h>
     39       1.1  nonaka #include <machine/platid.h>
     40       1.1  nonaka #include <machine/platid_mask.h>
     41       1.1  nonaka 
     42       1.1  nonaka #include <arm/xscale/pxa2x0reg.h>
     43       1.1  nonaka #include <arm/xscale/pxa2x0var.h>
     44       1.1  nonaka #include <arm/xscale/pxa2x0_gpio.h>
     45       1.1  nonaka 
     46       1.1  nonaka #include <hpcarm/dev/wzero3_reg.h>
     47       1.1  nonaka #include <hpcarm/dev/wzero3_sspvar.h>
     48       1.1  nonaka 
     49       1.2  nonaka #define WS003SH_SSCR0_MAX1233	0x0000048f	/* 16bit/SPI/div by 5 */
     50       1.2  nonaka #define WS007SH_SSCR0_ADS7846	0x000006ab	/* 12bit/Microwire/div by 7 */
     51       1.3  nonaka #define WS011SH_SSCR0_AK4184_TP 0x0010068f	/* 32bit/SPI/div by 7 */
     52       1.4  nonaka #define WS011SH_SSCR0_AK4184_KEYPAD 0x0000068f	/* 16bit/SPI/div by 7 */
     53       1.1  nonaka 
     54       1.2  nonaka struct wzero3ssp_model;
     55       1.1  nonaka struct wzero3ssp_softc {
     56       1.1  nonaka 	device_t sc_dev;
     57       1.1  nonaka 	bus_space_tag_t sc_iot;
     58       1.1  nonaka 	bus_space_handle_t sc_ioh;
     59       1.1  nonaka 	kmutex_t sc_mtx;
     60       1.2  nonaka 	const struct wzero3ssp_model *sc_model;
     61       1.1  nonaka };
     62       1.1  nonaka 
     63       1.1  nonaka static int	wzero3ssp_match(device_t, cfdata_t, void *);
     64       1.1  nonaka static void	wzero3ssp_attach(device_t, device_t, void *);
     65       1.1  nonaka 
     66       1.1  nonaka CFATTACH_DECL_NEW(wzero3ssp, sizeof(struct wzero3ssp_softc),
     67       1.1  nonaka 	wzero3ssp_match, wzero3ssp_attach, NULL, NULL);
     68       1.1  nonaka 
     69       1.1  nonaka static void	wzero3ssp_init(struct wzero3ssp_softc *);
     70       1.1  nonaka static bool	wzero3ssp_resume(device_t dv, const pmf_qual_t *);
     71       1.2  nonaka static uint32_t	wzero3ssp_read_ads7846(struct wzero3ssp_softc *, uint32_t);
     72       1.2  nonaka static uint32_t	wzero3ssp_read_max1233(struct wzero3ssp_softc *, uint32_t,
     73       1.2  nonaka 		    uint32_t);
     74       1.4  nonaka static uint32_t	wzero3ssp_read_ak4184_tp(struct wzero3ssp_softc *, uint32_t);
     75       1.4  nonaka static uint16_t	wzero3ssp_read_ak4184_keypad(struct wzero3ssp_softc *, uint32_t,
     76       1.4  nonaka 		    uint32_t);
     77       1.1  nonaka 
     78       1.1  nonaka static struct wzero3ssp_softc *wzero3ssp_sc;
     79       1.1  nonaka 
     80       1.1  nonaka static const struct wzero3ssp_model {
     81       1.1  nonaka 	platid_mask_t *platid;
     82       1.2  nonaka 	u_long sspaddr;
     83       1.1  nonaka } wzero3ssp_table[] = {
     84       1.1  nonaka 	/* WS003SH */
     85       1.1  nonaka 	{
     86       1.1  nonaka 		&platid_mask_MACH_SHARP_WZERO3_WS003SH,
     87       1.2  nonaka 		PXA2X0_SSP2_BASE,
     88       1.1  nonaka 	},
     89       1.1  nonaka 	/* WS004SH */
     90       1.1  nonaka 	{
     91       1.1  nonaka 		&platid_mask_MACH_SHARP_WZERO3_WS004SH,
     92       1.2  nonaka 		PXA2X0_SSP2_BASE,
     93       1.1  nonaka 	},
     94       1.1  nonaka 	/* WS007SH */
     95       1.1  nonaka 	{
     96       1.1  nonaka 		&platid_mask_MACH_SHARP_WZERO3_WS007SH,
     97       1.2  nonaka 		PXA2X0_SSP1_BASE,
     98       1.1  nonaka 	},
     99       1.1  nonaka 	/* WS011SH */
    100       1.1  nonaka 	{
    101       1.1  nonaka 		&platid_mask_MACH_SHARP_WZERO3_WS011SH,
    102       1.2  nonaka 		PXA2X0_SSP1_BASE,
    103       1.1  nonaka 	},
    104       1.2  nonaka #if 0
    105       1.1  nonaka 	/* WS0020H */
    106       1.1  nonaka 	{
    107       1.1  nonaka 		&platid_mask_MACH_SHARP_WZERO3_WS020SH,
    108       1.2  nonaka 		PXA2X0_SSP1_BASE,
    109       1.1  nonaka 	},
    110       1.1  nonaka #endif
    111       1.1  nonaka 	{
    112       1.2  nonaka 		NULL, 0,
    113       1.1  nonaka 	},
    114       1.1  nonaka };
    115       1.1  nonaka 
    116       1.1  nonaka static const struct wzero3ssp_model *
    117       1.1  nonaka wzero3ssp_lookup(void)
    118       1.1  nonaka {
    119       1.1  nonaka 	const struct wzero3ssp_model *model;
    120       1.1  nonaka 
    121       1.1  nonaka 	for (model = wzero3ssp_table; model->platid != NULL; model++) {
    122       1.1  nonaka 		if (platid_match(&platid, model->platid)) {
    123       1.1  nonaka 			return model;
    124       1.1  nonaka 		}
    125       1.1  nonaka 	}
    126       1.1  nonaka 	return NULL;
    127       1.1  nonaka }
    128       1.1  nonaka 
    129       1.1  nonaka static int
    130       1.1  nonaka wzero3ssp_match(device_t parent, cfdata_t cf, void *aux)
    131       1.1  nonaka {
    132       1.1  nonaka 
    133       1.1  nonaka 	if (strcmp(cf->cf_name, "wzero3ssp") != 0)
    134       1.1  nonaka 		return 0;
    135       1.1  nonaka 	if (wzero3ssp_lookup() == NULL)
    136       1.1  nonaka 		return 0;
    137       1.1  nonaka 	if (wzero3ssp_sc != NULL)
    138       1.1  nonaka 		return 0;
    139       1.1  nonaka 	return 1;
    140       1.1  nonaka }
    141       1.1  nonaka 
    142       1.1  nonaka static void
    143       1.1  nonaka wzero3ssp_attach(device_t parent, device_t self, void *aux)
    144       1.1  nonaka {
    145       1.1  nonaka 	struct wzero3ssp_softc *sc = device_private(self);
    146       1.1  nonaka 
    147       1.1  nonaka 	sc->sc_dev = self;
    148       1.1  nonaka 	wzero3ssp_sc = sc;
    149       1.1  nonaka 
    150       1.1  nonaka 	aprint_normal("\n");
    151       1.1  nonaka 	aprint_naive("\n");
    152       1.1  nonaka 
    153       1.2  nonaka 	sc->sc_model = wzero3ssp_lookup();
    154       1.2  nonaka 	if (sc->sc_model == NULL) {
    155       1.2  nonaka 		aprint_error_dev(self, "unknown model\n");
    156       1.2  nonaka 		return;
    157       1.2  nonaka 	}
    158       1.2  nonaka 
    159       1.1  nonaka 	mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_TTY);
    160       1.1  nonaka 
    161       1.1  nonaka 	sc->sc_iot = &pxa2x0_bs_tag;
    162       1.2  nonaka 	if (bus_space_map(sc->sc_iot, sc->sc_model->sspaddr, PXA2X0_SSP_SIZE, 0,
    163       1.1  nonaka 	     &sc->sc_ioh)) {
    164       1.1  nonaka 		aprint_error_dev(sc->sc_dev, "can't map bus space\n");
    165       1.1  nonaka 		return;
    166       1.1  nonaka 	}
    167       1.1  nonaka 
    168       1.1  nonaka 	if (!pmf_device_register(sc->sc_dev, NULL, wzero3ssp_resume))
    169       1.1  nonaka 		aprint_error_dev(sc->sc_dev,
    170       1.1  nonaka 		    "couldn't establish power handler\n");
    171       1.1  nonaka 
    172       1.1  nonaka 	wzero3ssp_init(sc);
    173       1.1  nonaka }
    174       1.1  nonaka 
    175       1.1  nonaka /*
    176       1.1  nonaka  * Initialize the dedicated SSP unit and disable all chip selects.
    177       1.1  nonaka  * This function is called with interrupts disabled.
    178       1.1  nonaka  */
    179       1.1  nonaka static void
    180       1.1  nonaka wzero3ssp_init(struct wzero3ssp_softc *sc)
    181       1.1  nonaka {
    182       1.1  nonaka 
    183       1.2  nonaka 	if (sc->sc_model->sspaddr == PXA2X0_SSP1_BASE)
    184       1.2  nonaka 		pxa2x0_clkman_config(CKEN_SSP2, 1);
    185       1.2  nonaka 	else if (sc->sc_model->sspaddr == PXA2X0_SSP2_BASE)
    186       1.2  nonaka 		pxa2x0_clkman_config(CKEN_SSP3, 1);
    187       1.1  nonaka 
    188       1.1  nonaka 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
    189       1.1  nonaka 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR1, 0);
    190       1.1  nonaka 
    191       1.2  nonaka 	/* XXX */
    192       1.2  nonaka 	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS003SH)
    193       1.2  nonaka 	 || platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS004SH)) {
    194       1.2  nonaka 		pxa2x0_gpio_set_function(39/*GPIO_WS003SH_XXX*/,
    195       1.2  nonaka 		    GPIO_OUT|GPIO_SET);
    196       1.2  nonaka 		pxa2x0_gpio_set_function(GPIO_WS003SH_MAX1233_CS,
    197       1.2  nonaka 		    GPIO_OUT|GPIO_SET);
    198       1.2  nonaka 	}
    199       1.2  nonaka 	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS007SH)) {
    200       1.2  nonaka 		pxa2x0_gpio_set_function(GPIO_WS007SH_ADS7846_CS,
    201       1.2  nonaka 		    GPIO_OUT|GPIO_SET);
    202       1.2  nonaka 	}
    203       1.3  nonaka 	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH)) {
    204       1.3  nonaka 		pxa2x0_gpio_set_function(GPIO_WS011SH_AK4184_CS,
    205       1.3  nonaka 		    GPIO_OUT|GPIO_SET);
    206       1.3  nonaka 	}
    207       1.1  nonaka }
    208       1.1  nonaka 
    209       1.1  nonaka static bool
    210       1.1  nonaka wzero3ssp_resume(device_t dv, const pmf_qual_t *qual)
    211       1.1  nonaka {
    212       1.1  nonaka 	struct wzero3ssp_softc *sc = device_private(dv);
    213       1.1  nonaka 
    214       1.1  nonaka 	mutex_enter(&sc->sc_mtx);
    215       1.1  nonaka 	wzero3ssp_init(sc);
    216       1.1  nonaka 	mutex_exit(&sc->sc_mtx);
    217       1.1  nonaka 
    218       1.1  nonaka 	return true;
    219       1.1  nonaka }
    220       1.1  nonaka 
    221       1.1  nonaka /*
    222       1.1  nonaka  * Transmit a single data word to one of the ICs, keep the chip selected
    223       1.1  nonaka  * afterwards, and don't wait for data to be returned in SSDR.  Interrupts
    224       1.1  nonaka  * must be held off until wzero3ssp_ic_stop() gets called.
    225       1.1  nonaka  */
    226       1.1  nonaka void
    227       1.1  nonaka wzero3ssp_ic_start(int ic, uint32_t cmd)
    228       1.1  nonaka {
    229       1.1  nonaka 	struct wzero3ssp_softc *sc;
    230       1.1  nonaka 
    231       1.1  nonaka 	KASSERT(wzero3ssp_sc != NULL);
    232       1.1  nonaka 	sc = wzero3ssp_sc;
    233       1.1  nonaka 
    234       1.1  nonaka 	mutex_enter(&sc->sc_mtx);
    235       1.1  nonaka 
    236       1.1  nonaka 	/* disable other ICs */
    237       1.1  nonaka 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
    238       1.3  nonaka 	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS007SH)) {
    239       1.3  nonaka 		if (ic != WZERO3_SSP_IC_ADS7846)
    240       1.3  nonaka 			pxa2x0_gpio_set_bit(GPIO_WS007SH_ADS7846_CS);
    241       1.3  nonaka 	}
    242       1.3  nonaka 	if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH)) {
    243       1.4  nonaka 		if (ic != WZERO3_SSP_IC_AK4184_TP
    244       1.4  nonaka 		 && ic != WZERO3_SSP_IC_AK4184_KEYPAD)
    245       1.3  nonaka 			pxa2x0_gpio_set_bit(GPIO_WS011SH_AK4184_CS);
    246       1.3  nonaka 	}
    247       1.1  nonaka 
    248       1.1  nonaka 	/* activate the chosen one */
    249       1.1  nonaka 	switch (ic) {
    250       1.1  nonaka 	case WZERO3_SSP_IC_ADS7846:
    251       1.1  nonaka 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
    252       1.1  nonaka 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0,
    253       1.1  nonaka 		    WS007SH_SSCR0_ADS7846);
    254       1.1  nonaka 		pxa2x0_gpio_clear_bit(GPIO_WS007SH_ADS7846_CS);
    255       1.1  nonaka 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd);
    256       1.1  nonaka 		while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
    257       1.1  nonaka 		    & SSSR_TNF) != SSSR_TNF)
    258       1.1  nonaka 			continue;	/* poll */
    259       1.1  nonaka 		break;
    260       1.4  nonaka 	case WZERO3_SSP_IC_AK4184_TP:
    261       1.3  nonaka 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
    262       1.3  nonaka 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0,
    263       1.3  nonaka 		    WS011SH_SSCR0_AK4184_TP);
    264       1.3  nonaka 		pxa2x0_gpio_clear_bit(GPIO_WS011SH_AK4184_CS);
    265       1.3  nonaka 		(void) bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
    266       1.3  nonaka 		while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
    267       1.3  nonaka 		    & SSSR_TNF))
    268       1.3  nonaka 			continue;	/* poll */
    269       1.3  nonaka 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd << 16);
    270       1.3  nonaka 		while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
    271       1.3  nonaka 		    & SSSR_BUSY)
    272       1.3  nonaka 			continue;	/* poll */
    273       1.3  nonaka 		break;
    274       1.2  nonaka 	case WZERO3_SSP_IC_MAX1233:
    275       1.4  nonaka 	case WZERO3_SSP_IC_AK4184_KEYPAD:
    276       1.2  nonaka 	case WZERO3_SSP_IC_NUM:
    277       1.2  nonaka 	default:
    278       1.2  nonaka 		break;
    279       1.1  nonaka 	}
    280       1.1  nonaka }
    281       1.1  nonaka 
    282       1.1  nonaka /*
    283       1.1  nonaka  * Read the last value from SSDR and deactivate all chip-selects.
    284       1.1  nonaka  */
    285       1.1  nonaka uint32_t
    286       1.1  nonaka wzero3ssp_ic_stop(int ic)
    287       1.1  nonaka {
    288       1.1  nonaka 	struct wzero3ssp_softc *sc;
    289       1.1  nonaka 	uint32_t rv;
    290       1.1  nonaka 
    291       1.1  nonaka 	KASSERT(wzero3ssp_sc != NULL);
    292       1.1  nonaka 	sc = wzero3ssp_sc;
    293       1.1  nonaka 
    294       1.1  nonaka 	switch (ic) {
    295       1.1  nonaka 	case WZERO3_SSP_IC_ADS7846:
    296       1.1  nonaka 		/* read result of last command */
    297       1.1  nonaka 		while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
    298       1.1  nonaka 		    & SSSR_RNE) != SSSR_RNE)
    299       1.1  nonaka 			continue;	/* poll */
    300       1.1  nonaka 		rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
    301       1.2  nonaka 		pxa2x0_gpio_set_bit(GPIO_WS007SH_ADS7846_CS);
    302       1.1  nonaka 		break;
    303       1.4  nonaka 	case WZERO3_SSP_IC_AK4184_TP:
    304       1.3  nonaka 		/* read result of last command */
    305       1.3  nonaka 		while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
    306       1.3  nonaka 		    & SSSR_RNE) != SSSR_RNE)
    307       1.3  nonaka 			continue;	/* poll */
    308       1.3  nonaka 		rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
    309       1.3  nonaka 		pxa2x0_gpio_set_bit(GPIO_WS011SH_AK4184_CS);
    310       1.3  nonaka 		break;
    311       1.2  nonaka 	case WZERO3_SSP_IC_MAX1233:
    312       1.4  nonaka 	case WZERO3_SSP_IC_AK4184_KEYPAD:
    313       1.2  nonaka 	case WZERO3_SSP_IC_NUM:
    314       1.1  nonaka 	default:
    315       1.1  nonaka 		rv = 0;
    316       1.1  nonaka 		break;
    317       1.1  nonaka 	}
    318       1.1  nonaka 
    319       1.1  nonaka 	mutex_exit(&sc->sc_mtx);
    320       1.1  nonaka 
    321       1.1  nonaka 	return rv;
    322       1.1  nonaka }
    323       1.1  nonaka 
    324       1.1  nonaka /*
    325       1.1  nonaka  * Activate one of the chip-select lines, transmit one word value in
    326       1.1  nonaka  * each direction, and deactivate the chip-select again.
    327       1.1  nonaka  */
    328       1.1  nonaka uint32_t
    329       1.2  nonaka wzero3ssp_ic_send(int ic, uint32_t data, uint32_t data2)
    330       1.1  nonaka {
    331       1.2  nonaka 	struct wzero3ssp_softc *sc;
    332       1.2  nonaka 
    333       1.2  nonaka 	if (wzero3ssp_sc == NULL) {
    334       1.2  nonaka 		aprint_error("%s: not configured\n", __func__);
    335       1.2  nonaka 		return 0;
    336       1.2  nonaka 	}
    337       1.2  nonaka 	sc = wzero3ssp_sc;
    338       1.1  nonaka 
    339       1.1  nonaka 	switch (ic) {
    340       1.1  nonaka 	case WZERO3_SSP_IC_ADS7846:
    341       1.2  nonaka 		return wzero3ssp_read_ads7846(sc, data);
    342       1.2  nonaka 	case WZERO3_SSP_IC_MAX1233:
    343       1.2  nonaka 		return wzero3ssp_read_max1233(sc, data, data2);
    344       1.4  nonaka 	case WZERO3_SSP_IC_AK4184_TP:
    345       1.4  nonaka 		return wzero3ssp_read_ak4184_tp(sc, data);
    346       1.4  nonaka 	case WZERO3_SSP_IC_AK4184_KEYPAD:
    347       1.4  nonaka 		return wzero3ssp_read_ak4184_keypad(sc, data, data2);
    348       1.2  nonaka 	case WZERO3_SSP_IC_NUM:
    349       1.1  nonaka 	default:
    350       1.2  nonaka 		aprint_error("%s: invalid IC %d\n", __func__, ic);
    351       1.1  nonaka 		return 0;
    352       1.1  nonaka 	}
    353       1.1  nonaka }
    354       1.1  nonaka 
    355       1.1  nonaka static uint32_t
    356       1.2  nonaka wzero3ssp_read_ads7846(struct wzero3ssp_softc *sc, uint32_t cmd)
    357       1.1  nonaka {
    358       1.1  nonaka 	uint32_t rv;
    359       1.1  nonaka 
    360       1.1  nonaka 	mutex_enter(&sc->sc_mtx);
    361       1.1  nonaka 
    362       1.1  nonaka 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
    363       1.1  nonaka 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0,
    364       1.1  nonaka 	    WS007SH_SSCR0_ADS7846);
    365       1.1  nonaka 
    366       1.1  nonaka 	pxa2x0_gpio_clear_bit(GPIO_WS007SH_ADS7846_CS);
    367       1.1  nonaka 
    368       1.1  nonaka 	/* send cmd */
    369       1.2  nonaka 	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF))
    370       1.2  nonaka 		continue;	/* poll */
    371       1.1  nonaka 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd);
    372       1.2  nonaka 	while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY)
    373       1.1  nonaka 		continue;	/* poll */
    374       1.2  nonaka 
    375       1.2  nonaka 	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE))
    376       1.1  nonaka 		continue;	/* poll */
    377       1.1  nonaka 	rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
    378       1.1  nonaka 
    379       1.1  nonaka 	pxa2x0_gpio_set_bit(GPIO_WS007SH_ADS7846_CS);
    380       1.1  nonaka 
    381       1.1  nonaka 	mutex_exit(&sc->sc_mtx);
    382       1.1  nonaka 
    383       1.1  nonaka 	return rv;
    384       1.1  nonaka }
    385       1.2  nonaka 
    386       1.2  nonaka static uint32_t
    387       1.2  nonaka wzero3ssp_read_max1233(struct wzero3ssp_softc *sc, uint32_t cmd, uint32_t data)
    388       1.2  nonaka {
    389       1.2  nonaka 	uint32_t rv;
    390       1.2  nonaka 
    391       1.2  nonaka 	mutex_enter(&sc->sc_mtx);
    392       1.2  nonaka 
    393       1.2  nonaka 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
    394       1.2  nonaka 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0,
    395       1.2  nonaka 	    WS003SH_SSCR0_MAX1233);
    396       1.2  nonaka 
    397       1.2  nonaka 	pxa2x0_gpio_set_bit(39/*GPIO_WS003SH_XXX*/);
    398       1.2  nonaka 	pxa2x0_gpio_clear_bit(GPIO_WS003SH_MAX1233_CS);
    399       1.2  nonaka 
    400       1.2  nonaka 	/* send cmd */
    401       1.2  nonaka 	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF))
    402       1.2  nonaka 		continue;	/* poll */
    403       1.2  nonaka 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd);
    404       1.2  nonaka 	while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY)
    405       1.2  nonaka 		continue;	/* poll */
    406       1.2  nonaka 	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE))
    407       1.2  nonaka 		continue;	/* poll */
    408       1.2  nonaka 	(void)bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
    409       1.2  nonaka 
    410       1.2  nonaka 	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF))
    411       1.2  nonaka 		continue;	/* poll */
    412       1.2  nonaka 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, data);
    413       1.2  nonaka 	while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY)
    414       1.2  nonaka 		continue;	/* poll */
    415       1.2  nonaka 	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE))
    416       1.2  nonaka 		continue;	/* poll */
    417       1.2  nonaka 	rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
    418       1.2  nonaka 
    419       1.2  nonaka 	pxa2x0_gpio_set_bit(GPIO_WS003SH_MAX1233_CS);
    420       1.2  nonaka 
    421       1.2  nonaka 	mutex_exit(&sc->sc_mtx);
    422       1.2  nonaka 
    423       1.2  nonaka 	return rv;
    424       1.2  nonaka }
    425       1.3  nonaka 
    426       1.3  nonaka static uint32_t
    427       1.4  nonaka wzero3ssp_read_ak4184_tp(struct wzero3ssp_softc *sc, uint32_t cmd)
    428       1.3  nonaka {
    429       1.3  nonaka 	uint32_t rv;
    430       1.3  nonaka 
    431       1.3  nonaka 	mutex_enter(&sc->sc_mtx);
    432       1.3  nonaka 
    433       1.3  nonaka 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
    434       1.3  nonaka 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0,
    435       1.3  nonaka 	    WS011SH_SSCR0_AK4184_TP);
    436       1.3  nonaka 
    437       1.3  nonaka 	pxa2x0_gpio_clear_bit(GPIO_WS011SH_AK4184_CS);
    438       1.3  nonaka 
    439       1.4  nonaka 	/* clear rx fifo */
    440       1.3  nonaka 	(void) bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
    441       1.3  nonaka 
    442       1.3  nonaka 	/* send cmd */
    443       1.3  nonaka 	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF))
    444       1.3  nonaka 		continue;	/* poll */
    445       1.3  nonaka 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd << 16);
    446       1.3  nonaka 	while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY)
    447       1.3  nonaka 		continue;	/* poll */
    448       1.3  nonaka 
    449       1.3  nonaka 	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE))
    450       1.3  nonaka 		continue;	/* poll */
    451       1.3  nonaka 	rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
    452       1.3  nonaka 
    453       1.3  nonaka 	pxa2x0_gpio_set_bit(GPIO_WS011SH_AK4184_CS);
    454       1.3  nonaka 
    455       1.3  nonaka 	mutex_exit(&sc->sc_mtx);
    456       1.3  nonaka 
    457       1.3  nonaka 	return rv;
    458       1.3  nonaka }
    459       1.4  nonaka 
    460       1.4  nonaka static uint16_t
    461       1.4  nonaka wzero3ssp_read_ak4184_keypad(struct wzero3ssp_softc *sc, uint32_t cmd,
    462       1.4  nonaka     uint32_t data)
    463       1.4  nonaka {
    464       1.4  nonaka 	uint16_t rv;
    465       1.4  nonaka 
    466       1.4  nonaka 	mutex_enter(&sc->sc_mtx);
    467       1.4  nonaka 
    468       1.4  nonaka 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
    469       1.4  nonaka 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0,
    470       1.4  nonaka 	    WS011SH_SSCR0_AK4184_KEYPAD);
    471       1.4  nonaka 
    472       1.4  nonaka 	pxa2x0_gpio_clear_bit(GPIO_WS011SH_AK4184_CS);
    473       1.4  nonaka 
    474       1.4  nonaka 	/* clear rx fifo */
    475       1.4  nonaka 	(void) bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
    476       1.4  nonaka 
    477       1.4  nonaka 	/* send cmd */
    478       1.4  nonaka 	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF))
    479       1.4  nonaka 		continue;	/* poll */
    480       1.4  nonaka 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, SSP_SSDR, (uint16_t)cmd);
    481       1.4  nonaka 	while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY)
    482       1.4  nonaka 		continue;	/* poll */
    483       1.4  nonaka 	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE))
    484       1.4  nonaka 		continue;	/* poll */
    485       1.4  nonaka 	(void) bus_space_read_2(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
    486       1.4  nonaka 
    487       1.4  nonaka 	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF))
    488       1.4  nonaka 		continue;	/* poll */
    489       1.4  nonaka 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, SSP_SSDR, (uint16_t)data);
    490       1.4  nonaka 	while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY)
    491       1.4  nonaka 		continue;	/* poll */
    492       1.4  nonaka 	while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE))
    493       1.4  nonaka 		continue;	/* poll */
    494       1.4  nonaka 	rv = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
    495       1.4  nonaka 
    496       1.4  nonaka 	pxa2x0_gpio_set_bit(GPIO_WS011SH_AK4184_CS);
    497       1.4  nonaka 
    498       1.4  nonaka 	mutex_exit(&sc->sc_mtx);
    499       1.4  nonaka 
    500       1.4  nonaka 	return rv;
    501       1.4  nonaka }
    502