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