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