Home | History | Annotate | Line # | Download | only in dev
uda1341.c revision 1.7
      1 /*	$NetBSD: uda1341.c,v 1.7 2005/08/26 13:19:36 drochner Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2001 The NetBSD Foundation, Inc.  All rights reserved.
      5  *
      6  * This code is derived from software contributed to The NetBSD Foundation
      7  * by Ichiro FUKUHARA (ichiro (at) ichiro.org).
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. All advertising materials mentioning features or use of this software
     18  *    must display the following acknowledgement:
     19  *	This product includes software developed by the NetBSD
     20  *	Foundation, Inc. and its contributors.
     21  * 4. Neither the name of The NetBSD Foundation nor the names of its
     22  *    contributors may be used to endorse or promote products derived
     23  *    from this software without specific prior written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     26  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  * POSSIBILITY OF SUCH DAMAGE.
     36  */
     37 
     38 #include <sys/cdefs.h>
     39 __KERNEL_RCSID(0, "$NetBSD: uda1341.c,v 1.7 2005/08/26 13:19:36 drochner Exp $");
     40 
     41 #include <sys/param.h>
     42 #include <sys/systm.h>
     43 #include <sys/types.h>
     44 #include <sys/conf.h>
     45 #include <sys/file.h>
     46 #include <sys/device.h>
     47 #include <sys/kernel.h>
     48 #include <sys/kthread.h>
     49 #include <sys/malloc.h>
     50 
     51 #include <machine/bus.h>
     52 
     53 #include <hpcarm/dev/ipaq_saipvar.h>
     54 #include <hpcarm/dev/ipaq_gpioreg.h>
     55 #include <hpcarm/dev/uda1341.h>
     56 #include <hpcarm/sa11x0/sa11x0_gpioreg.h>
     57 #include <hpcarm/sa11x0/sa11x0_sspreg.h>
     58 
     59 struct uda1341_softc {
     60 	struct device		sc_dev;
     61 	bus_space_tag_t		sc_iot;
     62 	bus_space_handle_t	sc_ioh;
     63 	struct ipaq_softc	*sc_parent;
     64 };
     65 
     66 static	int	uda1341_match(struct device *, struct cfdata *, void *);
     67 static	void	uda1341_attach(struct device *, struct device *, void *);
     68 static	int	uda1341_print(void *, const char *);
     69 static	int	uda1341_search(struct device *, struct cfdata *,
     70 			       const int *, void *);
     71 
     72 static	void	uda1341_output_high(struct uda1341_softc *);
     73 static	void	uda1341_output_low(struct uda1341_softc *);
     74 static	void	uda1341_L3_init(struct uda1341_softc *);
     75 static	void	uda1341_init(struct uda1341_softc *);
     76 static	void	uda1341_reset(struct uda1341_softc *);
     77 static	void	uda1341_reginit(struct uda1341_softc *);
     78 
     79 static	int	L3_getbit(struct uda1341_softc *);
     80 static	void	L3_sendbit(struct uda1341_softc *, int);
     81 static	u_int8_t L3_getbyte(struct uda1341_softc *, int);
     82 static	void	L3_sendbyte(struct uda1341_softc *, u_int8_t, int);
     83 static	int	L3_read(struct uda1341_softc *, u_int8_t, u_int8_t *, int);
     84 static	int	L3_write(struct uda1341_softc *, u_int8_t, u_int8_t *, int);
     85 
     86 CFATTACH_DECL(uda, sizeof(struct uda1341_softc),
     87     uda1341_match, uda1341_attach, NULL, NULL);
     88 
     89 /*
     90  * Philips L3 bus support.
     91  * GPIO lines are used for clock, data and mode pins.
     92  */
     93 #define L3_DATA		GPIO_H3600_L3_DATA
     94 #define L3_MODE		GPIO_H3600_L3_MODE
     95 #define L3_CLK		GPIO_H3600_L3_CLK
     96 
     97 static struct {
     98 	u_int8_t data0;	/* direct addressing register */
     99 } DIRECT_REG = {0};
    100 
    101 static struct {
    102 	u_int8_t data0;	/* extended addressing register 1 */
    103 	u_int8_t data1;	/* extended addressing register 2 */
    104 } EXTEND_REG = {0, 0};
    105 
    106 /*
    107  * register space access macros
    108  */
    109 #define GPIO_WRITE(sc, reg, val) \
    110 	bus_space_write_4(sc->sc_iot, sc->sc_parent->sc_gpioh, reg, val)
    111 #define GPIO_READ(sc, reg) \
    112 	bus_space_read_4(sc->sc_iot, sc->sc_parent->sc_gpioh, reg)
    113 #define EGPIO_WRITE(sc) \
    114 	bus_space_write_2(sc->sc_iot, sc->sc_parent->sc_egpioh, \
    115 			  0, sc->sc_parent->ipaq_egpio)
    116 #define SSP_WRITE(sc, reg, val) \
    117 	bus_space_write_4(sc->sc_iot, sc->sc_parent->sc_ssph, reg, val)
    118 
    119 static int
    120 uda1341_match(parent, cf, aux)
    121 	struct device *parent;
    122 	struct cfdata *cf;
    123 	void *aux;
    124 {
    125 	return (1);
    126 }
    127 
    128 static void
    129 uda1341_attach(parent, self, aux)
    130 	struct device *parent;
    131 	struct device *self;
    132 	void *aux;
    133 {
    134 	struct uda1341_softc *sc = (struct uda1341_softc *)self;
    135 	struct ipaq_softc *psc = (struct ipaq_softc *)parent;
    136 
    137 	printf("\n");
    138 	printf("%s: UDA1341 CODEC\n",  sc->sc_dev.dv_xname);
    139 
    140 	sc->sc_iot = psc->sc_iot;
    141 	sc->sc_ioh = psc->sc_ioh;
    142 	sc->sc_parent = (struct ipaq_softc *)parent;
    143 
    144 	uda1341_L3_init(sc);
    145 	uda1341_init(sc);
    146 
    147 	uda1341_reset(sc);
    148 
    149 	uda1341_reginit(sc);
    150 
    151 
    152 	/*
    153 	 *  Attach each devices
    154 	 */
    155 
    156 	config_search_ia(uda1341_search, self, "udaif", NULL);
    157 }
    158 
    159 static int
    160 uda1341_search(parent, cf, ldesc, aux)
    161 	struct device *parent;
    162 	struct cfdata *cf;
    163 	const int *ldesc;
    164 	void *aux;
    165 {
    166 	if (config_match(parent, cf, NULL) > 0)
    167 		config_attach(parent, cf, NULL, uda1341_print);
    168 	return 0;
    169 }
    170 
    171 
    172 static int
    173 uda1341_print(aux, name)
    174 	void *aux;
    175 	const char *name;
    176 {
    177 	return (UNCONF);
    178 }
    179 
    180 static void
    181 uda1341_output_high(sc)
    182 	struct uda1341_softc *sc;
    183 {
    184 	int cr;
    185 
    186 	GPIO_WRITE(sc, SAGPIO_PSR, (L3_DATA | L3_MODE | L3_CLK));
    187 	cr = GPIO_READ(sc, SAGPIO_PDR) | (L3_DATA | L3_MODE | L3_CLK);
    188 	GPIO_WRITE(sc, SAGPIO_PDR, cr);
    189 }
    190 
    191 static void
    192 uda1341_output_low(sc)
    193 	struct uda1341_softc *sc;
    194 {
    195 	int cr;
    196 
    197 	cr = GPIO_READ(sc, SAGPIO_PDR);
    198 	cr &= ~(L3_DATA | L3_MODE | L3_CLK);
    199 	GPIO_WRITE(sc, SAGPIO_PDR, cr);
    200 }
    201 
    202 static void
    203 uda1341_L3_init(sc)
    204 	struct uda1341_softc *sc;
    205 {
    206 	int cr;
    207 
    208 	cr = GPIO_READ(sc, SAGPIO_AFR);
    209 	cr &= ~(L3_DATA | L3_MODE | L3_CLK);
    210 	GPIO_WRITE(sc, SAGPIO_AFR, cr);
    211 
    212 	uda1341_output_low(sc);
    213 }
    214 
    215 static void
    216 uda1341_init(sc)
    217 	struct uda1341_softc *sc;
    218 {
    219 	int cr;
    220 
    221 	/* GPIO initialize */
    222 	cr = GPIO_READ(sc, SAGPIO_AFR);
    223 	cr &= ~(GPIO_ALT_SSP_TXD | GPIO_ALT_SSP_RXD | GPIO_ALT_SSP_SCLK |
    224 		GPIO_ALT_SSP_SFRM);
    225 	cr |= GPIO_ALT_SSP_CLK;
    226 	GPIO_WRITE(sc, SAGPIO_AFR, cr);
    227 
    228 	cr = GPIO_READ(sc, SAGPIO_PDR);
    229 	cr &= ~GPIO_ALT_SSP_CLK;
    230 	GPIO_WRITE(sc, SAGPIO_PDR, cr);
    231 
    232 	/* SSP initialize & enable */
    233 	SSP_WRITE(sc, SASSP_CR1, CR1_ECS);
    234 	cr = 0xF | (CR0_FRF_MASK & (1<<4)) | (CR0_SCR_MASK & (3<<8)) | CR0_SSE;
    235 	SSP_WRITE(sc, SASSP_CR0, cr);
    236 
    237 	/* Enable the audio power */
    238 	sc->sc_parent->ipaq_egpio |=
    239 			(EGPIO_H3600_AUD_PWRON | EGPIO_H3600_AUD_ON);
    240 	sc->sc_parent->ipaq_egpio &=
    241 			~(EGPIO_H3600_CODEC_RESET | EGPIO_H3600_QMUTE);
    242 	EGPIO_WRITE(sc);
    243 
    244 	/* external clock configured for 44100 samples/sec */
    245 	cr = GPIO_READ(sc, SAGPIO_PDR);
    246 	cr |= (GPIO_H3600_CLK_SET0 | GPIO_H3600_CLK_SET1);
    247 	GPIO_WRITE(sc, SAGPIO_PDR, cr);
    248 	GPIO_WRITE(sc, SAGPIO_PSR, GPIO_H3600_CLK_SET0);
    249 	GPIO_WRITE(sc, SAGPIO_PCR, GPIO_H3600_CLK_SET1);
    250 
    251 	/* wait for power on */
    252 	delay(100*1000);
    253 	sc->sc_parent->ipaq_egpio |= EGPIO_H3600_CODEC_RESET;
    254 	EGPIO_WRITE(sc);
    255 
    256 	/* Wait for the UDA1341 to wake up */
    257 	delay(100*1000);
    258 }
    259 
    260 static void
    261 uda1341_reset(sc)
    262 	struct uda1341_softc *sc;
    263 {
    264 	u_int8_t command;
    265 
    266 	command = (L3_ADDRESS_COM << 2) | L3_ADDRESS_STATUS;
    267 	DIRECT_REG.data0 = STATUS0_RST | STATUS0_SC_256 | STATUS0_IF_LSB16;
    268 	L3_write(sc, command, (u_int8_t *) &DIRECT_REG, 1);
    269 
    270 	sc->sc_parent->ipaq_egpio &= ~EGPIO_H3600_CODEC_RESET;
    271 	EGPIO_WRITE(sc);
    272 	sc->sc_parent->ipaq_egpio |= EGPIO_H3600_CODEC_RESET;
    273 	EGPIO_WRITE(sc);
    274 
    275 	DIRECT_REG.data0 &= ~STATUS0_RST;
    276 	L3_write(sc, command, (u_int8_t *) &DIRECT_REG, 1);
    277 }
    278 
    279 static void
    280 uda1341_reginit(sc)
    281 	struct uda1341_softc *sc;
    282 {
    283 	u_int8_t command;
    284 
    285 	/* STATUS 0 */
    286 	command = (L3_ADDRESS_COM << 2) | L3_ADDRESS_STATUS;
    287 	DIRECT_REG.data0 = STATUS0_SC_256 | STATUS0_IF_LSB16;
    288 	L3_write(sc, command, (u_int8_t *) &DIRECT_REG, 1);
    289 
    290 	/* STATUS 1 */
    291 	DIRECT_REG.data0 = STATUS1_OGS | STATUS1_IGS | (1<<7);
    292 	L3_write(sc, command, (u_int8_t *) &DIRECT_REG, 1);
    293 
    294 	/* DATA 0 */
    295 	command = (L3_ADDRESS_COM << 2) | L3_ADDRESS_DATA0;
    296 	DIRECT_REG.data0 = DATA0_VC(100) | DATA0_COMMON;
    297 	L3_write(sc, command, (u_int8_t *) &DIRECT_REG, 1);
    298 
    299 	/* DATA 1 */
    300 	DIRECT_REG.data0 = DATA1_BB(0) | DATA1_TR(0) | DATA1_COMMON;
    301 	L3_write(sc, command, (u_int8_t *) &DIRECT_REG, 1);
    302 
    303 	/* DATA 2*/
    304 	DIRECT_REG.data0 = DATA2_PP | DATA2_COMMON;
    305 	L3_write(sc, command, (u_int8_t *) &DIRECT_REG, 1);
    306 
    307 	/* Extended DATA 0 */
    308 	EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E0;
    309 	EXTEND_REG.data1 = EXT_DATA_COMMN | 0x4 ;
    310 	L3_write(sc, command, (u_int8_t *) &EXTEND_REG, 2);
    311 
    312 	/* Extended DATA 1 */
    313 	EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E1;
    314 	EXTEND_REG.data1 = EXT_DATA_COMMN | 0x4 ;
    315 	L3_write(sc, command, (u_int8_t *) &EXTEND_REG, 2);
    316 
    317 	/* Extended DATA 2 */
    318 	EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E2;
    319 	EXTEND_REG.data1 = EXT_DATA_COMMN | DATA_E2_MS(30);
    320 	L3_write(sc, command, (u_int8_t *) &EXTEND_REG, 2);
    321 
    322 	/* Extended DATA 3 */
    323 	EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E3;
    324 	EXTEND_REG.data1 = EXT_DATA_COMMN | DATA_E3_IG_L(0);
    325 	L3_write(sc, command, (u_int8_t *) &EXTEND_REG, 2);
    326 
    327 	/* Extended DATA 4 */
    328 	EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E4;
    329 	EXTEND_REG.data1 = EXT_DATA_COMMN | DATA_E4_IG_H(0);
    330 	L3_write(sc, command, (u_int8_t *) &EXTEND_REG, 2);
    331 
    332 	/* Extended DATA 5 */
    333 	EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E5;
    334 	EXTEND_REG.data1 = EXT_DATA_COMMN;
    335 	L3_write(sc, command, (u_int8_t *) &EXTEND_REG, 2);
    336 }
    337 
    338 static int
    339 L3_getbit(sc)
    340 	struct uda1341_softc *sc;
    341 {
    342 	int cr, data;
    343 
    344 	GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK);	/* Clock down */
    345 	delay(L3_CLK_LOW);
    346 
    347 	cr = GPIO_READ(sc, SAGPIO_PLR);
    348 	data = (cr & L3_DATA) ? 1 : 0;
    349 
    350 	GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK);	/* Clock up */
    351 	delay(L3_CLK_HIGH);
    352 
    353 	return (data);
    354 }
    355 
    356 static void
    357 L3_sendbit(sc, bit)
    358 	struct uda1341_softc *sc;
    359 	int bit;
    360 {
    361 	GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK);	/* Clock down */
    362 
    363 	if (bit & 0x01)
    364 		GPIO_WRITE(sc, SAGPIO_PSR, L3_DATA);
    365 	else
    366 		GPIO_WRITE(sc, SAGPIO_PCR, L3_DATA);
    367 
    368 	delay(L3_CLK_LOW);
    369 	GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK);     /* Clock up */
    370 	delay(L3_CLK_HIGH);
    371 }
    372 
    373 static u_int8_t
    374 L3_getbyte(sc, mode)
    375 	struct uda1341_softc *sc;
    376 	int mode;
    377 {
    378 	int i;
    379 	u_int8_t data;
    380 
    381 	switch (mode) {
    382 	case 0:		/* Address mode */
    383 	case 1:		/* First data byte */
    384 		break;
    385 	default:	/* second data byte via halt-Time */
    386 		GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK);     /* Clock down */
    387 		delay(L3_HALT);
    388 		GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK);	/* Clock up */
    389 		break;
    390 	}
    391 
    392 	delay(L3_MODE_SETUP);
    393 
    394 	for (i = 0; i < 8; i++)
    395 		data |= (L3_getbit(sc) << i);
    396 
    397 	delay(L3_MODE_HOLD);
    398 
    399 	return (data);
    400 }
    401 
    402 static void
    403 L3_sendbyte(sc, data, mode)
    404 	struct uda1341_softc *sc;
    405 	u_int8_t data;
    406 	int mode;
    407 {
    408 	int i;
    409 
    410 	switch (mode) {
    411 	case 0:		/* Address mode */
    412 		GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK);	/* Clock down */
    413 		break;
    414 	case 1:		/* First data byte */
    415 		break;
    416 	default:	/* second data byte via halt-Time */
    417 		GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK);     /* Clock down */
    418 		delay(L3_HALT);
    419 		GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK);	/* Clock up */
    420 		break;
    421 	}
    422 
    423 	delay(L3_MODE_SETUP);
    424 
    425 	for (i = 0; i < 8; i++)
    426 		L3_sendbit(sc, data >> i);
    427 
    428 	if (mode == 0)		/* Address mode */
    429 		GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK);	/* Clock up */
    430 
    431 	delay(L3_MODE_HOLD);
    432 }
    433 
    434 static int
    435 L3_read(sc, addr, data, len)
    436 	struct uda1341_softc *sc;
    437 	u_int8_t addr, *data;
    438         int len;
    439 {
    440 	int cr, mode;
    441 	mode = 0;
    442 
    443 	uda1341_output_high(sc);
    444 	L3_sendbyte(sc, addr, mode++);
    445 
    446 	cr = GPIO_READ(sc, SAGPIO_PDR);
    447 	cr &= ~(L3_DATA);
    448 	GPIO_WRITE(sc, SAGPIO_PDR, cr);
    449 
    450 	while(len--)
    451 		*data++ = L3_getbyte(sc, mode++);
    452 	uda1341_output_low(sc);
    453 
    454 	return len;
    455 }
    456 
    457 static int
    458 L3_write(sc, addr, data, len)
    459 	struct uda1341_softc *sc;
    460 	u_int8_t addr, *data;
    461 	int len;
    462 {
    463 	int mode = 0;
    464 
    465 	uda1341_output_high(sc);
    466 	L3_sendbyte(sc, addr, mode++);
    467 	while(len--)
    468 		L3_sendbyte(sc, *data++, mode++);
    469 	uda1341_output_low(sc);
    470 
    471 	return len;
    472 }
    473