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