xref: /netbsd-src/sys/arch/hpcarm/dev/uda1341.c (revision 404fbe5fb94ca1e054339640cabb2801ce52dd30)
1 /*	$NetBSD: uda1341.c,v 1.11 2008/04/28 20:23:21 martin 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  *
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.11 2008/04/28 20:23:21 martin 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