1 /* $NetBSD: uda1341.c,v 1.14 2009/05/29 14:15:45 rjs 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.14 2009/05/29 14:15:45 rjs 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 device_t 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(device_t, cfdata_t, void *); 61 static void uda1341_attach(device_t, device_t, void *); 62 static int uda1341_print(void *, const char *); 63 static int uda1341_search(device_t, cfdata_t, const int *, void *); 64 65 static void uda1341_output_high(struct uda1341_softc *); 66 static void uda1341_output_low(struct uda1341_softc *); 67 static void uda1341_L3_init(struct uda1341_softc *); 68 static void uda1341_init(struct uda1341_softc *); 69 static void uda1341_reset(struct uda1341_softc *); 70 static void uda1341_reginit(struct uda1341_softc *); 71 72 #if 0 73 static int L3_getbit(struct uda1341_softc *); 74 #endif 75 static void L3_sendbit(struct uda1341_softc *, int); 76 #if 0 77 static uint8_t L3_getbyte(struct uda1341_softc *, int); 78 #endif 79 static void L3_sendbyte(struct uda1341_softc *, uint8_t, int); 80 #if 0 81 static int L3_read(struct uda1341_softc *, uint8_t, uint8_t *, int); 82 #endif 83 static int L3_write(struct uda1341_softc *, uint8_t, uint8_t *, int); 84 85 CFATTACH_DECL_NEW(uda, sizeof(struct uda1341_softc), 86 uda1341_match, uda1341_attach, NULL, NULL); 87 88 /* 89 * Philips L3 bus support. 90 * GPIO lines are used for clock, data and mode pins. 91 */ 92 #define L3_DATA GPIO_H3600_L3_DATA 93 #define L3_MODE GPIO_H3600_L3_MODE 94 #define L3_CLK GPIO_H3600_L3_CLK 95 96 static struct { 97 uint8_t data0; /* direct addressing register */ 98 } DIRECT_REG = {0}; 99 100 static struct { 101 uint8_t data0; /* extended addressing register 1 */ 102 uint8_t data1; /* extended addressing register 2 */ 103 } EXTEND_REG = {0, 0}; 104 105 /* 106 * register space access macros 107 */ 108 #define GPIO_WRITE(sc, reg, val) \ 109 bus_space_write_4(sc->sc_iot, sc->sc_parent->sc_gpioh, reg, val) 110 #define GPIO_READ(sc, reg) \ 111 bus_space_read_4(sc->sc_iot, sc->sc_parent->sc_gpioh, reg) 112 #define EGPIO_WRITE(sc) \ 113 bus_space_write_2(sc->sc_iot, sc->sc_parent->sc_egpioh, \ 114 0, sc->sc_parent->ipaq_egpio) 115 #define SSP_WRITE(sc, reg, val) \ 116 bus_space_write_4(sc->sc_iot, sc->sc_parent->sc_ssph, reg, val) 117 118 static int 119 uda1341_match(device_t parent, cfdata_t cf, void *aux) 120 { 121 return (1); 122 } 123 124 static void 125 uda1341_attach(device_t parent, device_t self, void *aux) 126 { 127 struct uda1341_softc *sc = device_private(self); 128 struct ipaq_softc *psc = device_private(parent); 129 130 aprint_normal("\n"); 131 aprint_normal_dev(self, "UDA1341 CODEC\n"); 132 133 sc->sc_dev = self; 134 sc->sc_iot = psc->sc_iot; 135 sc->sc_ioh = psc->sc_ioh; 136 sc->sc_parent = psc; 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(device_t parent, cfdata_t cf, const int *ldesc, void *aux) 155 { 156 if (config_match(parent, cf, NULL) > 0) 157 config_attach(parent, cf, NULL, uda1341_print); 158 return 0; 159 } 160 161 162 static int 163 uda1341_print(void *aux, const char *name) 164 { 165 return (UNCONF); 166 } 167 168 static void 169 uda1341_output_high(struct uda1341_softc *sc) 170 { 171 int cr; 172 173 GPIO_WRITE(sc, SAGPIO_PSR, (L3_DATA | L3_MODE | L3_CLK)); 174 cr = GPIO_READ(sc, SAGPIO_PDR) | (L3_DATA | L3_MODE | L3_CLK); 175 GPIO_WRITE(sc, SAGPIO_PDR, cr); 176 } 177 178 static void 179 uda1341_output_low(struct uda1341_softc *sc) 180 { 181 int cr; 182 183 cr = GPIO_READ(sc, SAGPIO_PDR); 184 cr &= ~(L3_DATA | L3_MODE | L3_CLK); 185 GPIO_WRITE(sc, SAGPIO_PDR, cr); 186 } 187 188 static void 189 uda1341_L3_init(struct uda1341_softc *sc) 190 { 191 int cr; 192 193 cr = GPIO_READ(sc, SAGPIO_AFR); 194 cr &= ~(L3_DATA | L3_MODE | L3_CLK); 195 GPIO_WRITE(sc, SAGPIO_AFR, cr); 196 197 uda1341_output_low(sc); 198 } 199 200 static void 201 uda1341_init(struct uda1341_softc *sc) 202 { 203 int cr; 204 205 /* GPIO initialize */ 206 cr = GPIO_READ(sc, SAGPIO_AFR); 207 cr &= ~(GPIO_ALT_SSP_TXD | GPIO_ALT_SSP_RXD | GPIO_ALT_SSP_SCLK | 208 GPIO_ALT_SSP_SFRM); 209 cr |= GPIO_ALT_SSP_CLK; 210 GPIO_WRITE(sc, SAGPIO_AFR, cr); 211 212 cr = GPIO_READ(sc, SAGPIO_PDR); 213 cr &= ~GPIO_ALT_SSP_CLK; 214 GPIO_WRITE(sc, SAGPIO_PDR, cr); 215 216 /* SSP initialize & enable */ 217 SSP_WRITE(sc, SASSP_CR1, CR1_ECS); 218 cr = 0xF | (CR0_FRF_MASK & (1<<4)) | (CR0_SCR_MASK & (3<<8)) | CR0_SSE; 219 SSP_WRITE(sc, SASSP_CR0, cr); 220 221 /* Enable the audio power */ 222 sc->sc_parent->ipaq_egpio |= 223 (EGPIO_H3600_AUD_PWRON | EGPIO_H3600_AUD_ON); 224 sc->sc_parent->ipaq_egpio &= 225 ~(EGPIO_H3600_CODEC_RESET | EGPIO_H3600_QMUTE); 226 EGPIO_WRITE(sc); 227 228 /* external clock configured for 44100 samples/sec */ 229 cr = GPIO_READ(sc, SAGPIO_PDR); 230 cr |= (GPIO_H3600_CLK_SET0 | GPIO_H3600_CLK_SET1); 231 GPIO_WRITE(sc, SAGPIO_PDR, cr); 232 GPIO_WRITE(sc, SAGPIO_PSR, GPIO_H3600_CLK_SET0); 233 GPIO_WRITE(sc, SAGPIO_PCR, GPIO_H3600_CLK_SET1); 234 235 /* wait for power on */ 236 delay(100*1000); 237 sc->sc_parent->ipaq_egpio |= EGPIO_H3600_CODEC_RESET; 238 EGPIO_WRITE(sc); 239 240 /* Wait for the UDA1341 to wake up */ 241 delay(100*1000); 242 } 243 244 static void 245 uda1341_reset(struct uda1341_softc *sc) 246 { 247 uint8_t command; 248 249 command = (L3_ADDRESS_COM << 2) | L3_ADDRESS_STATUS; 250 DIRECT_REG.data0 = STATUS0_RST | STATUS0_SC_256 | STATUS0_IF_LSB16; 251 L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1); 252 253 sc->sc_parent->ipaq_egpio &= ~EGPIO_H3600_CODEC_RESET; 254 EGPIO_WRITE(sc); 255 sc->sc_parent->ipaq_egpio |= EGPIO_H3600_CODEC_RESET; 256 EGPIO_WRITE(sc); 257 258 DIRECT_REG.data0 &= ~STATUS0_RST; 259 L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1); 260 } 261 262 static void 263 uda1341_reginit(struct uda1341_softc *sc) 264 { 265 uint8_t command; 266 267 /* STATUS 0 */ 268 command = (L3_ADDRESS_COM << 2) | L3_ADDRESS_STATUS; 269 DIRECT_REG.data0 = STATUS0_SC_256 | STATUS0_IF_LSB16; 270 L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1); 271 272 /* STATUS 1 */ 273 DIRECT_REG.data0 = STATUS1_OGS | STATUS1_IGS | (1<<7); 274 L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1); 275 276 /* DATA 0 */ 277 command = (L3_ADDRESS_COM << 2) | L3_ADDRESS_DATA0; 278 DIRECT_REG.data0 = DATA0_VC(100) | DATA0_COMMON; 279 L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1); 280 281 /* DATA 1 */ 282 DIRECT_REG.data0 = DATA1_BB(0) | DATA1_TR(0) | DATA1_COMMON; 283 L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1); 284 285 /* DATA 2*/ 286 DIRECT_REG.data0 = DATA2_PP | DATA2_COMMON; 287 L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1); 288 289 /* Extended DATA 0 */ 290 EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E0; 291 EXTEND_REG.data1 = EXT_DATA_COMMN | 0x4 ; 292 L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2); 293 294 /* Extended DATA 1 */ 295 EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E1; 296 EXTEND_REG.data1 = EXT_DATA_COMMN | 0x4 ; 297 L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2); 298 299 /* Extended DATA 2 */ 300 EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E2; 301 EXTEND_REG.data1 = EXT_DATA_COMMN | DATA_E2_MS(30); 302 L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2); 303 304 /* Extended DATA 3 */ 305 EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E3; 306 EXTEND_REG.data1 = EXT_DATA_COMMN | DATA_E3_IG_L(0); 307 L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2); 308 309 /* Extended DATA 4 */ 310 EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E4; 311 EXTEND_REG.data1 = EXT_DATA_COMMN | DATA_E4_IG_H(0); 312 L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2); 313 314 /* Extended DATA 5 */ 315 EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E5; 316 EXTEND_REG.data1 = EXT_DATA_COMMN; 317 L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2); 318 } 319 320 #if 0 321 static int 322 L3_getbit(struct uda1341_softc *sc) 323 { 324 int cr, data; 325 326 GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK); /* Clock down */ 327 delay(L3_CLK_LOW); 328 329 cr = GPIO_READ(sc, SAGPIO_PLR); 330 data = (cr & L3_DATA) ? 1 : 0; 331 332 GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK); /* Clock up */ 333 delay(L3_CLK_HIGH); 334 335 return (data); 336 } 337 #endif 338 339 static void 340 L3_sendbit(struct uda1341_softc *sc, int bit) 341 { 342 GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK); /* Clock down */ 343 344 if (bit & 0x01) 345 GPIO_WRITE(sc, SAGPIO_PSR, L3_DATA); 346 else 347 GPIO_WRITE(sc, SAGPIO_PCR, L3_DATA); 348 349 delay(L3_CLK_LOW); 350 GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK); /* Clock up */ 351 delay(L3_CLK_HIGH); 352 } 353 354 #if 0 355 static uint8_t 356 L3_getbyte(struct uda1341_softc *sc, int mode) 357 { 358 int i; 359 uint8_t data; 360 361 switch (mode) { 362 case 0: /* Address mode */ 363 case 1: /* First data byte */ 364 break; 365 default: /* second data byte via halt-Time */ 366 GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK); /* Clock down */ 367 delay(L3_HALT); 368 GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK); /* Clock up */ 369 break; 370 } 371 372 delay(L3_MODE_SETUP); 373 374 for (i = 0; i < 8; i++) 375 data |= (L3_getbit(sc) << i); 376 377 delay(L3_MODE_HOLD); 378 379 return (data); 380 } 381 #endif 382 383 static void 384 L3_sendbyte(struct uda1341_softc *sc, uint8_t data, int mode) 385 { 386 int i; 387 388 switch (mode) { 389 case 0: /* Address mode */ 390 GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK); /* Clock down */ 391 break; 392 case 1: /* First data byte */ 393 break; 394 default: /* second data byte via halt-Time */ 395 GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK); /* Clock down */ 396 delay(L3_HALT); 397 GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK); /* Clock up */ 398 break; 399 } 400 401 delay(L3_MODE_SETUP); 402 403 for (i = 0; i < 8; i++) 404 L3_sendbit(sc, data >> i); 405 406 if (mode == 0) /* Address mode */ 407 GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK); /* Clock up */ 408 409 delay(L3_MODE_HOLD); 410 } 411 412 #if 0 413 static int 414 L3_read(struct uda1341_softc *sc, uint8_t addr, uint8_t *data, int len) 415 { 416 int cr, mode; 417 mode = 0; 418 419 uda1341_output_high(sc); 420 L3_sendbyte(sc, addr, mode++); 421 422 cr = GPIO_READ(sc, SAGPIO_PDR); 423 cr &= ~(L3_DATA); 424 GPIO_WRITE(sc, SAGPIO_PDR, cr); 425 426 while(len--) 427 *data++ = L3_getbyte(sc, mode++); 428 uda1341_output_low(sc); 429 430 return len; 431 } 432 #endif 433 434 static int 435 L3_write(struct uda1341_softc *sc, uint8_t addr, uint8_t *data, int len) 436 { 437 int mode = 0; 438 439 uda1341_output_high(sc); 440 L3_sendbyte(sc, addr, mode++); 441 while(len--) 442 L3_sendbyte(sc, *data++, mode++); 443 uda1341_output_low(sc); 444 445 return len; 446 } 447