1 /* $NetBSD: uda1341.c,v 1.11 2008/04/28 20:23:21 martin 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.11 2008/04/28 20:23:21 martin 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(parent, cf, aux) 115 struct device *parent; 116 struct cfdata *cf; 117 void *aux; 118 { 119 return (1); 120 } 121 122 static void 123 uda1341_attach(parent, self, aux) 124 struct device *parent; 125 struct device *self; 126 void *aux; 127 { 128 struct uda1341_softc *sc = (struct uda1341_softc *)self; 129 struct ipaq_softc *psc = (struct ipaq_softc *)parent; 130 131 printf("\n"); 132 printf("%s: UDA1341 CODEC\n", sc->sc_dev.dv_xname); 133 134 sc->sc_iot = psc->sc_iot; 135 sc->sc_ioh = psc->sc_ioh; 136 sc->sc_parent = (struct ipaq_softc *)parent; 137 138 uda1341_L3_init(sc); 139 uda1341_init(sc); 140 141 uda1341_reset(sc); 142 143 uda1341_reginit(sc); 144 145 146 /* 147 * Attach each devices 148 */ 149 150 config_search_ia(uda1341_search, self, "udaif", NULL); 151 } 152 153 static int 154 uda1341_search(parent, cf, ldesc, aux) 155 struct device *parent; 156 struct cfdata *cf; 157 const int *ldesc; 158 void *aux; 159 { 160 if (config_match(parent, cf, NULL) > 0) 161 config_attach(parent, cf, NULL, uda1341_print); 162 return 0; 163 } 164 165 166 static int 167 uda1341_print(aux, name) 168 void *aux; 169 const char *name; 170 { 171 return (UNCONF); 172 } 173 174 static void 175 uda1341_output_high(sc) 176 struct uda1341_softc *sc; 177 { 178 int cr; 179 180 GPIO_WRITE(sc, SAGPIO_PSR, (L3_DATA | L3_MODE | L3_CLK)); 181 cr = GPIO_READ(sc, SAGPIO_PDR) | (L3_DATA | L3_MODE | L3_CLK); 182 GPIO_WRITE(sc, SAGPIO_PDR, cr); 183 } 184 185 static void 186 uda1341_output_low(sc) 187 struct uda1341_softc *sc; 188 { 189 int cr; 190 191 cr = GPIO_READ(sc, SAGPIO_PDR); 192 cr &= ~(L3_DATA | L3_MODE | L3_CLK); 193 GPIO_WRITE(sc, SAGPIO_PDR, cr); 194 } 195 196 static void 197 uda1341_L3_init(sc) 198 struct uda1341_softc *sc; 199 { 200 int cr; 201 202 cr = GPIO_READ(sc, SAGPIO_AFR); 203 cr &= ~(L3_DATA | L3_MODE | L3_CLK); 204 GPIO_WRITE(sc, SAGPIO_AFR, cr); 205 206 uda1341_output_low(sc); 207 } 208 209 static void 210 uda1341_init(sc) 211 struct uda1341_softc *sc; 212 { 213 int cr; 214 215 /* GPIO initialize */ 216 cr = GPIO_READ(sc, SAGPIO_AFR); 217 cr &= ~(GPIO_ALT_SSP_TXD | GPIO_ALT_SSP_RXD | GPIO_ALT_SSP_SCLK | 218 GPIO_ALT_SSP_SFRM); 219 cr |= GPIO_ALT_SSP_CLK; 220 GPIO_WRITE(sc, SAGPIO_AFR, cr); 221 222 cr = GPIO_READ(sc, SAGPIO_PDR); 223 cr &= ~GPIO_ALT_SSP_CLK; 224 GPIO_WRITE(sc, SAGPIO_PDR, cr); 225 226 /* SSP initialize & enable */ 227 SSP_WRITE(sc, SASSP_CR1, CR1_ECS); 228 cr = 0xF | (CR0_FRF_MASK & (1<<4)) | (CR0_SCR_MASK & (3<<8)) | CR0_SSE; 229 SSP_WRITE(sc, SASSP_CR0, cr); 230 231 /* Enable the audio power */ 232 sc->sc_parent->ipaq_egpio |= 233 (EGPIO_H3600_AUD_PWRON | EGPIO_H3600_AUD_ON); 234 sc->sc_parent->ipaq_egpio &= 235 ~(EGPIO_H3600_CODEC_RESET | EGPIO_H3600_QMUTE); 236 EGPIO_WRITE(sc); 237 238 /* external clock configured for 44100 samples/sec */ 239 cr = GPIO_READ(sc, SAGPIO_PDR); 240 cr |= (GPIO_H3600_CLK_SET0 | GPIO_H3600_CLK_SET1); 241 GPIO_WRITE(sc, SAGPIO_PDR, cr); 242 GPIO_WRITE(sc, SAGPIO_PSR, GPIO_H3600_CLK_SET0); 243 GPIO_WRITE(sc, SAGPIO_PCR, GPIO_H3600_CLK_SET1); 244 245 /* wait for power on */ 246 delay(100*1000); 247 sc->sc_parent->ipaq_egpio |= EGPIO_H3600_CODEC_RESET; 248 EGPIO_WRITE(sc); 249 250 /* Wait for the UDA1341 to wake up */ 251 delay(100*1000); 252 } 253 254 static void 255 uda1341_reset(sc) 256 struct uda1341_softc *sc; 257 { 258 uint8_t command; 259 260 command = (L3_ADDRESS_COM << 2) | L3_ADDRESS_STATUS; 261 DIRECT_REG.data0 = STATUS0_RST | STATUS0_SC_256 | STATUS0_IF_LSB16; 262 L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1); 263 264 sc->sc_parent->ipaq_egpio &= ~EGPIO_H3600_CODEC_RESET; 265 EGPIO_WRITE(sc); 266 sc->sc_parent->ipaq_egpio |= EGPIO_H3600_CODEC_RESET; 267 EGPIO_WRITE(sc); 268 269 DIRECT_REG.data0 &= ~STATUS0_RST; 270 L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1); 271 } 272 273 static void 274 uda1341_reginit(sc) 275 struct uda1341_softc *sc; 276 { 277 uint8_t command; 278 279 /* STATUS 0 */ 280 command = (L3_ADDRESS_COM << 2) | L3_ADDRESS_STATUS; 281 DIRECT_REG.data0 = STATUS0_SC_256 | STATUS0_IF_LSB16; 282 L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1); 283 284 /* STATUS 1 */ 285 DIRECT_REG.data0 = STATUS1_OGS | STATUS1_IGS | (1<<7); 286 L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1); 287 288 /* DATA 0 */ 289 command = (L3_ADDRESS_COM << 2) | L3_ADDRESS_DATA0; 290 DIRECT_REG.data0 = DATA0_VC(100) | DATA0_COMMON; 291 L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1); 292 293 /* DATA 1 */ 294 DIRECT_REG.data0 = DATA1_BB(0) | DATA1_TR(0) | DATA1_COMMON; 295 L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1); 296 297 /* DATA 2*/ 298 DIRECT_REG.data0 = DATA2_PP | DATA2_COMMON; 299 L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1); 300 301 /* Extended DATA 0 */ 302 EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E0; 303 EXTEND_REG.data1 = EXT_DATA_COMMN | 0x4 ; 304 L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2); 305 306 /* Extended DATA 1 */ 307 EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E1; 308 EXTEND_REG.data1 = EXT_DATA_COMMN | 0x4 ; 309 L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2); 310 311 /* Extended DATA 2 */ 312 EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E2; 313 EXTEND_REG.data1 = EXT_DATA_COMMN | DATA_E2_MS(30); 314 L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2); 315 316 /* Extended DATA 3 */ 317 EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E3; 318 EXTEND_REG.data1 = EXT_DATA_COMMN | DATA_E3_IG_L(0); 319 L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2); 320 321 /* Extended DATA 4 */ 322 EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E4; 323 EXTEND_REG.data1 = EXT_DATA_COMMN | DATA_E4_IG_H(0); 324 L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2); 325 326 /* Extended DATA 5 */ 327 EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E5; 328 EXTEND_REG.data1 = EXT_DATA_COMMN; 329 L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2); 330 } 331 332 static int 333 L3_getbit(sc) 334 struct uda1341_softc *sc; 335 { 336 int cr, data; 337 338 GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK); /* Clock down */ 339 delay(L3_CLK_LOW); 340 341 cr = GPIO_READ(sc, SAGPIO_PLR); 342 data = (cr & L3_DATA) ? 1 : 0; 343 344 GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK); /* Clock up */ 345 delay(L3_CLK_HIGH); 346 347 return (data); 348 } 349 350 static void 351 L3_sendbit(sc, bit) 352 struct uda1341_softc *sc; 353 int bit; 354 { 355 GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK); /* Clock down */ 356 357 if (bit & 0x01) 358 GPIO_WRITE(sc, SAGPIO_PSR, L3_DATA); 359 else 360 GPIO_WRITE(sc, SAGPIO_PCR, L3_DATA); 361 362 delay(L3_CLK_LOW); 363 GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK); /* Clock up */ 364 delay(L3_CLK_HIGH); 365 } 366 367 static uint8_t 368 L3_getbyte(sc, mode) 369 struct uda1341_softc *sc; 370 int mode; 371 { 372 int i; 373 uint8_t data; 374 375 switch (mode) { 376 case 0: /* Address mode */ 377 case 1: /* First data byte */ 378 break; 379 default: /* second data byte via halt-Time */ 380 GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK); /* Clock down */ 381 delay(L3_HALT); 382 GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK); /* Clock up */ 383 break; 384 } 385 386 delay(L3_MODE_SETUP); 387 388 for (i = 0; i < 8; i++) 389 data |= (L3_getbit(sc) << i); 390 391 delay(L3_MODE_HOLD); 392 393 return (data); 394 } 395 396 static void 397 L3_sendbyte(sc, data, mode) 398 struct uda1341_softc *sc; 399 uint8_t data; 400 int mode; 401 { 402 int i; 403 404 switch (mode) { 405 case 0: /* Address mode */ 406 GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK); /* Clock down */ 407 break; 408 case 1: /* First data byte */ 409 break; 410 default: /* second data byte via halt-Time */ 411 GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK); /* Clock down */ 412 delay(L3_HALT); 413 GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK); /* Clock up */ 414 break; 415 } 416 417 delay(L3_MODE_SETUP); 418 419 for (i = 0; i < 8; i++) 420 L3_sendbit(sc, data >> i); 421 422 if (mode == 0) /* Address mode */ 423 GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK); /* Clock up */ 424 425 delay(L3_MODE_HOLD); 426 } 427 428 static int 429 L3_read(sc, addr, data, len) 430 struct uda1341_softc *sc; 431 uint8_t addr, *data; 432 int len; 433 { 434 int cr, mode; 435 mode = 0; 436 437 uda1341_output_high(sc); 438 L3_sendbyte(sc, addr, mode++); 439 440 cr = GPIO_READ(sc, SAGPIO_PDR); 441 cr &= ~(L3_DATA); 442 GPIO_WRITE(sc, SAGPIO_PDR, cr); 443 444 while(len--) 445 *data++ = L3_getbyte(sc, mode++); 446 uda1341_output_low(sc); 447 448 return len; 449 } 450 451 static int 452 L3_write(sc, addr, data, len) 453 struct uda1341_softc *sc; 454 uint8_t addr, *data; 455 int len; 456 { 457 int mode = 0; 458 459 uda1341_output_high(sc); 460 L3_sendbyte(sc, addr, mode++); 461 while(len--) 462 L3_sendbyte(sc, *data++, mode++); 463 uda1341_output_low(sc); 464 465 return len; 466 } 467