uda1341.c revision 1.10.64.1 1 /* $NetBSD: uda1341.c,v 1.10.64.1 2008/05/18 12:32:02 yamt 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 (at) 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.10.64.1 2008/05/18 12:32:02 yamt 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