xref: /netbsd-src/sys/arch/hpcarm/dev/uda1341.c (revision d48f14661dda8638fee055ba15d35bdfb29b9fa8)
1 /*	$NetBSD: uda1341.c,v 1.10 2006/03/25 15:26:51 peter 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  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *	This product includes software developed by the NetBSD
20  *	Foundation, Inc. and its contributors.
21  * 4. Neither the name of The NetBSD Foundation nor the names of its
22  *    contributors may be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
26  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: uda1341.c,v 1.10 2006/03/25 15:26:51 peter Exp $");
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/types.h>
44 #include <sys/conf.h>
45 #include <sys/file.h>
46 #include <sys/device.h>
47 #include <sys/kernel.h>
48 #include <sys/kthread.h>
49 #include <sys/malloc.h>
50 
51 #include <machine/bus.h>
52 
53 #include <hpcarm/dev/ipaq_saipvar.h>
54 #include <hpcarm/dev/ipaq_gpioreg.h>
55 #include <hpcarm/dev/uda1341.h>
56 
57 #include <arm/sa11x0/sa11x0_gpioreg.h>
58 #include <arm/sa11x0/sa11x0_sspreg.h>
59 
60 struct uda1341_softc {
61 	struct device		sc_dev;
62 	bus_space_tag_t		sc_iot;
63 	bus_space_handle_t	sc_ioh;
64 	struct ipaq_softc	*sc_parent;
65 };
66 
67 static	int	uda1341_match(struct device *, struct cfdata *, void *);
68 static	void	uda1341_attach(struct device *, struct device *, void *);
69 static	int	uda1341_print(void *, const char *);
70 static	int	uda1341_search(struct device *, struct cfdata *,
71 			       const int *, void *);
72 
73 static	void	uda1341_output_high(struct uda1341_softc *);
74 static	void	uda1341_output_low(struct uda1341_softc *);
75 static	void	uda1341_L3_init(struct uda1341_softc *);
76 static	void	uda1341_init(struct uda1341_softc *);
77 static	void	uda1341_reset(struct uda1341_softc *);
78 static	void	uda1341_reginit(struct uda1341_softc *);
79 
80 static	int	L3_getbit(struct uda1341_softc *);
81 static	void	L3_sendbit(struct uda1341_softc *, int);
82 static	uint8_t L3_getbyte(struct uda1341_softc *, int);
83 static	void	L3_sendbyte(struct uda1341_softc *, uint8_t, int);
84 static	int	L3_read(struct uda1341_softc *, uint8_t, uint8_t *, int);
85 static	int	L3_write(struct uda1341_softc *, uint8_t, uint8_t *, int);
86 
87 CFATTACH_DECL(uda, sizeof(struct uda1341_softc),
88     uda1341_match, uda1341_attach, NULL, NULL);
89 
90 /*
91  * Philips L3 bus support.
92  * GPIO lines are used for clock, data and mode pins.
93  */
94 #define L3_DATA		GPIO_H3600_L3_DATA
95 #define L3_MODE		GPIO_H3600_L3_MODE
96 #define L3_CLK		GPIO_H3600_L3_CLK
97 
98 static struct {
99 	uint8_t data0;	/* direct addressing register */
100 } DIRECT_REG = {0};
101 
102 static struct {
103 	uint8_t data0;	/* extended addressing register 1 */
104 	uint8_t data1;	/* extended addressing register 2 */
105 } EXTEND_REG = {0, 0};
106 
107 /*
108  * register space access macros
109  */
110 #define GPIO_WRITE(sc, reg, val) \
111 	bus_space_write_4(sc->sc_iot, sc->sc_parent->sc_gpioh, reg, val)
112 #define GPIO_READ(sc, reg) \
113 	bus_space_read_4(sc->sc_iot, sc->sc_parent->sc_gpioh, reg)
114 #define EGPIO_WRITE(sc) \
115 	bus_space_write_2(sc->sc_iot, sc->sc_parent->sc_egpioh, \
116 			  0, sc->sc_parent->ipaq_egpio)
117 #define SSP_WRITE(sc, reg, val) \
118 	bus_space_write_4(sc->sc_iot, sc->sc_parent->sc_ssph, reg, val)
119 
120 static int
121 uda1341_match(parent, cf, aux)
122 	struct device *parent;
123 	struct cfdata *cf;
124 	void *aux;
125 {
126 	return (1);
127 }
128 
129 static void
130 uda1341_attach(parent, self, aux)
131 	struct device *parent;
132 	struct device *self;
133 	void *aux;
134 {
135 	struct uda1341_softc *sc = (struct uda1341_softc *)self;
136 	struct ipaq_softc *psc = (struct ipaq_softc *)parent;
137 
138 	printf("\n");
139 	printf("%s: UDA1341 CODEC\n",  sc->sc_dev.dv_xname);
140 
141 	sc->sc_iot = psc->sc_iot;
142 	sc->sc_ioh = psc->sc_ioh;
143 	sc->sc_parent = (struct ipaq_softc *)parent;
144 
145 	uda1341_L3_init(sc);
146 	uda1341_init(sc);
147 
148 	uda1341_reset(sc);
149 
150 	uda1341_reginit(sc);
151 
152 
153 	/*
154 	 *  Attach each devices
155 	 */
156 
157 	config_search_ia(uda1341_search, self, "udaif", NULL);
158 }
159 
160 static int
161 uda1341_search(parent, cf, ldesc, aux)
162 	struct device *parent;
163 	struct cfdata *cf;
164 	const int *ldesc;
165 	void *aux;
166 {
167 	if (config_match(parent, cf, NULL) > 0)
168 		config_attach(parent, cf, NULL, uda1341_print);
169 	return 0;
170 }
171 
172 
173 static int
174 uda1341_print(aux, name)
175 	void *aux;
176 	const char *name;
177 {
178 	return (UNCONF);
179 }
180 
181 static void
182 uda1341_output_high(sc)
183 	struct uda1341_softc *sc;
184 {
185 	int cr;
186 
187 	GPIO_WRITE(sc, SAGPIO_PSR, (L3_DATA | L3_MODE | L3_CLK));
188 	cr = GPIO_READ(sc, SAGPIO_PDR) | (L3_DATA | L3_MODE | L3_CLK);
189 	GPIO_WRITE(sc, SAGPIO_PDR, cr);
190 }
191 
192 static void
193 uda1341_output_low(sc)
194 	struct uda1341_softc *sc;
195 {
196 	int cr;
197 
198 	cr = GPIO_READ(sc, SAGPIO_PDR);
199 	cr &= ~(L3_DATA | L3_MODE | L3_CLK);
200 	GPIO_WRITE(sc, SAGPIO_PDR, cr);
201 }
202 
203 static void
204 uda1341_L3_init(sc)
205 	struct uda1341_softc *sc;
206 {
207 	int cr;
208 
209 	cr = GPIO_READ(sc, SAGPIO_AFR);
210 	cr &= ~(L3_DATA | L3_MODE | L3_CLK);
211 	GPIO_WRITE(sc, SAGPIO_AFR, cr);
212 
213 	uda1341_output_low(sc);
214 }
215 
216 static void
217 uda1341_init(sc)
218 	struct uda1341_softc *sc;
219 {
220 	int cr;
221 
222 	/* GPIO initialize */
223 	cr = GPIO_READ(sc, SAGPIO_AFR);
224 	cr &= ~(GPIO_ALT_SSP_TXD | GPIO_ALT_SSP_RXD | GPIO_ALT_SSP_SCLK |
225 		GPIO_ALT_SSP_SFRM);
226 	cr |= GPIO_ALT_SSP_CLK;
227 	GPIO_WRITE(sc, SAGPIO_AFR, cr);
228 
229 	cr = GPIO_READ(sc, SAGPIO_PDR);
230 	cr &= ~GPIO_ALT_SSP_CLK;
231 	GPIO_WRITE(sc, SAGPIO_PDR, cr);
232 
233 	/* SSP initialize & enable */
234 	SSP_WRITE(sc, SASSP_CR1, CR1_ECS);
235 	cr = 0xF | (CR0_FRF_MASK & (1<<4)) | (CR0_SCR_MASK & (3<<8)) | CR0_SSE;
236 	SSP_WRITE(sc, SASSP_CR0, cr);
237 
238 	/* Enable the audio power */
239 	sc->sc_parent->ipaq_egpio |=
240 			(EGPIO_H3600_AUD_PWRON | EGPIO_H3600_AUD_ON);
241 	sc->sc_parent->ipaq_egpio &=
242 			~(EGPIO_H3600_CODEC_RESET | EGPIO_H3600_QMUTE);
243 	EGPIO_WRITE(sc);
244 
245 	/* external clock configured for 44100 samples/sec */
246 	cr = GPIO_READ(sc, SAGPIO_PDR);
247 	cr |= (GPIO_H3600_CLK_SET0 | GPIO_H3600_CLK_SET1);
248 	GPIO_WRITE(sc, SAGPIO_PDR, cr);
249 	GPIO_WRITE(sc, SAGPIO_PSR, GPIO_H3600_CLK_SET0);
250 	GPIO_WRITE(sc, SAGPIO_PCR, GPIO_H3600_CLK_SET1);
251 
252 	/* wait for power on */
253 	delay(100*1000);
254 	sc->sc_parent->ipaq_egpio |= EGPIO_H3600_CODEC_RESET;
255 	EGPIO_WRITE(sc);
256 
257 	/* Wait for the UDA1341 to wake up */
258 	delay(100*1000);
259 }
260 
261 static void
262 uda1341_reset(sc)
263 	struct uda1341_softc *sc;
264 {
265 	uint8_t command;
266 
267 	command = (L3_ADDRESS_COM << 2) | L3_ADDRESS_STATUS;
268 	DIRECT_REG.data0 = STATUS0_RST | STATUS0_SC_256 | STATUS0_IF_LSB16;
269 	L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1);
270 
271 	sc->sc_parent->ipaq_egpio &= ~EGPIO_H3600_CODEC_RESET;
272 	EGPIO_WRITE(sc);
273 	sc->sc_parent->ipaq_egpio |= EGPIO_H3600_CODEC_RESET;
274 	EGPIO_WRITE(sc);
275 
276 	DIRECT_REG.data0 &= ~STATUS0_RST;
277 	L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1);
278 }
279 
280 static void
281 uda1341_reginit(sc)
282 	struct uda1341_softc *sc;
283 {
284 	uint8_t command;
285 
286 	/* STATUS 0 */
287 	command = (L3_ADDRESS_COM << 2) | L3_ADDRESS_STATUS;
288 	DIRECT_REG.data0 = STATUS0_SC_256 | STATUS0_IF_LSB16;
289 	L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1);
290 
291 	/* STATUS 1 */
292 	DIRECT_REG.data0 = STATUS1_OGS | STATUS1_IGS | (1<<7);
293 	L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1);
294 
295 	/* DATA 0 */
296 	command = (L3_ADDRESS_COM << 2) | L3_ADDRESS_DATA0;
297 	DIRECT_REG.data0 = DATA0_VC(100) | DATA0_COMMON;
298 	L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1);
299 
300 	/* DATA 1 */
301 	DIRECT_REG.data0 = DATA1_BB(0) | DATA1_TR(0) | DATA1_COMMON;
302 	L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1);
303 
304 	/* DATA 2*/
305 	DIRECT_REG.data0 = DATA2_PP | DATA2_COMMON;
306 	L3_write(sc, command, (uint8_t *) &DIRECT_REG, 1);
307 
308 	/* Extended DATA 0 */
309 	EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E0;
310 	EXTEND_REG.data1 = EXT_DATA_COMMN | 0x4 ;
311 	L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2);
312 
313 	/* Extended DATA 1 */
314 	EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E1;
315 	EXTEND_REG.data1 = EXT_DATA_COMMN | 0x4 ;
316 	L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2);
317 
318 	/* Extended DATA 2 */
319 	EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E2;
320 	EXTEND_REG.data1 = EXT_DATA_COMMN | DATA_E2_MS(30);
321 	L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2);
322 
323 	/* Extended DATA 3 */
324 	EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E3;
325 	EXTEND_REG.data1 = EXT_DATA_COMMN | DATA_E3_IG_L(0);
326 	L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2);
327 
328 	/* Extended DATA 4 */
329 	EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E4;
330 	EXTEND_REG.data1 = EXT_DATA_COMMN | DATA_E4_IG_H(0);
331 	L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2);
332 
333 	/* Extended DATA 5 */
334 	EXTEND_REG.data0 = EXT_ADDR_COMMON | EXT_ADDR_E5;
335 	EXTEND_REG.data1 = EXT_DATA_COMMN;
336 	L3_write(sc, command, (uint8_t *) &EXTEND_REG, 2);
337 }
338 
339 static int
340 L3_getbit(sc)
341 	struct uda1341_softc *sc;
342 {
343 	int cr, data;
344 
345 	GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK);	/* Clock down */
346 	delay(L3_CLK_LOW);
347 
348 	cr = GPIO_READ(sc, SAGPIO_PLR);
349 	data = (cr & L3_DATA) ? 1 : 0;
350 
351 	GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK);	/* Clock up */
352 	delay(L3_CLK_HIGH);
353 
354 	return (data);
355 }
356 
357 static void
358 L3_sendbit(sc, bit)
359 	struct uda1341_softc *sc;
360 	int bit;
361 {
362 	GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK);	/* Clock down */
363 
364 	if (bit & 0x01)
365 		GPIO_WRITE(sc, SAGPIO_PSR, L3_DATA);
366 	else
367 		GPIO_WRITE(sc, SAGPIO_PCR, L3_DATA);
368 
369 	delay(L3_CLK_LOW);
370 	GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK);     /* Clock up */
371 	delay(L3_CLK_HIGH);
372 }
373 
374 static uint8_t
375 L3_getbyte(sc, mode)
376 	struct uda1341_softc *sc;
377 	int mode;
378 {
379 	int i;
380 	uint8_t data;
381 
382 	switch (mode) {
383 	case 0:		/* Address mode */
384 	case 1:		/* First data byte */
385 		break;
386 	default:	/* second data byte via halt-Time */
387 		GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK);     /* Clock down */
388 		delay(L3_HALT);
389 		GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK);	/* Clock up */
390 		break;
391 	}
392 
393 	delay(L3_MODE_SETUP);
394 
395 	for (i = 0; i < 8; i++)
396 		data |= (L3_getbit(sc) << i);
397 
398 	delay(L3_MODE_HOLD);
399 
400 	return (data);
401 }
402 
403 static void
404 L3_sendbyte(sc, data, mode)
405 	struct uda1341_softc *sc;
406 	uint8_t data;
407 	int mode;
408 {
409 	int i;
410 
411 	switch (mode) {
412 	case 0:		/* Address mode */
413 		GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK);	/* Clock down */
414 		break;
415 	case 1:		/* First data byte */
416 		break;
417 	default:	/* second data byte via halt-Time */
418 		GPIO_WRITE(sc, SAGPIO_PCR, L3_CLK);     /* Clock down */
419 		delay(L3_HALT);
420 		GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK);	/* Clock up */
421 		break;
422 	}
423 
424 	delay(L3_MODE_SETUP);
425 
426 	for (i = 0; i < 8; i++)
427 		L3_sendbit(sc, data >> i);
428 
429 	if (mode == 0)		/* Address mode */
430 		GPIO_WRITE(sc, SAGPIO_PSR, L3_CLK);	/* Clock up */
431 
432 	delay(L3_MODE_HOLD);
433 }
434 
435 static int
436 L3_read(sc, addr, data, len)
437 	struct uda1341_softc *sc;
438 	uint8_t addr, *data;
439         int len;
440 {
441 	int cr, mode;
442 	mode = 0;
443 
444 	uda1341_output_high(sc);
445 	L3_sendbyte(sc, addr, mode++);
446 
447 	cr = GPIO_READ(sc, SAGPIO_PDR);
448 	cr &= ~(L3_DATA);
449 	GPIO_WRITE(sc, SAGPIO_PDR, cr);
450 
451 	while(len--)
452 		*data++ = L3_getbyte(sc, mode++);
453 	uda1341_output_low(sc);
454 
455 	return len;
456 }
457 
458 static int
459 L3_write(sc, addr, data, len)
460 	struct uda1341_softc *sc;
461 	uint8_t addr, *data;
462 	int len;
463 {
464 	int mode = 0;
465 
466 	uda1341_output_high(sc);
467 	L3_sendbyte(sc, addr, mode++);
468 	while(len--)
469 		L3_sendbyte(sc, *data++, mode++);
470 	uda1341_output_low(sc);
471 
472 	return len;
473 }
474