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