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