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