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