audio_mini2440.c revision 1.1.4.2 1 1.1.4.2 yamt /*-
2 1.1.4.2 yamt * Copyright (c) 2012 The NetBSD Foundation, Inc.
3 1.1.4.2 yamt * All rights reserved.
4 1.1.4.2 yamt *
5 1.1.4.2 yamt * This code is derived from software contributed to The NetBSD Foundation
6 1.1.4.2 yamt * by Paul Fleischer <paul (at) xpg.dk>
7 1.1.4.2 yamt *
8 1.1.4.2 yamt * Redistribution and use in source and binary forms, with or without
9 1.1.4.2 yamt * modification, are permitted provided that the following conditions
10 1.1.4.2 yamt * are met:
11 1.1.4.2 yamt * 1. Redistributions of source code must retain the above copyright
12 1.1.4.2 yamt * notice, this list of conditions and the following disclaimer.
13 1.1.4.2 yamt * 2. Redistributions in binary form must reproduce the above copyright
14 1.1.4.2 yamt * notice, this list of conditions and the following disclaimer in the
15 1.1.4.2 yamt * documentation and/or other materials provided with the distribution.
16 1.1.4.2 yamt *
17 1.1.4.2 yamt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 1.1.4.2 yamt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 1.1.4.2 yamt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 1.1.4.2 yamt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 1.1.4.2 yamt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 1.1.4.2 yamt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 1.1.4.2 yamt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 1.1.4.2 yamt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 1.1.4.2 yamt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 1.1.4.2 yamt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 1.1.4.2 yamt * POSSIBILITY OF SUCH DAMAGE.
28 1.1.4.2 yamt */
29 1.1.4.2 yamt
30 1.1.4.2 yamt #include <sys/cdefs.h>
31 1.1.4.2 yamt #include <sys/param.h>
32 1.1.4.2 yamt #include <sys/device.h>
33 1.1.4.2 yamt #include <sys/malloc.h>
34 1.1.4.2 yamt #include <sys/fcntl.h>
35 1.1.4.2 yamt #include <sys/audioio.h>
36 1.1.4.2 yamt
37 1.1.4.2 yamt #include <sys/bus.h>
38 1.1.4.2 yamt
39 1.1.4.2 yamt #include <dev/audio_if.h>
40 1.1.4.2 yamt
41 1.1.4.2 yamt
42 1.1.4.2 yamt #include <dev/ic/uda1341var.h>
43 1.1.4.2 yamt
44 1.1.4.2 yamt #include <arch/arm/s3c2xx0/s3c2440reg.h>
45 1.1.4.2 yamt #include <arch/arm/s3c2xx0/s3c2440var.h>
46 1.1.4.2 yamt
47 1.1.4.2 yamt #include <arch/arm/s3c2xx0/s3c2440_dma.h>
48 1.1.4.2 yamt #include <arch/arm/s3c2xx0/s3c2440_i2s.h>
49 1.1.4.2 yamt
50 1.1.4.2 yamt /*#define AUDIO_MINI2440_DEBUG*/
51 1.1.4.2 yamt
52 1.1.4.2 yamt #ifdef AUDIO_MINI2440_DEBUG
53 1.1.4.2 yamt #define DPRINTF(x) do {printf x; } while (/*CONSTCOND*/0)
54 1.1.4.2 yamt #else
55 1.1.4.2 yamt #define DPRINTF(s) do {} while (/*CONSTCOND*/0)
56 1.1.4.2 yamt #endif
57 1.1.4.2 yamt
58 1.1.4.2 yamt struct uda_softc {
59 1.1.4.2 yamt device_t sc_dev;
60 1.1.4.2 yamt kmutex_t sc_lock;
61 1.1.4.2 yamt kmutex_t sc_intr_lock;
62 1.1.4.2 yamt
63 1.1.4.2 yamt struct uda1341_softc sc_uda1341;
64 1.1.4.2 yamt
65 1.1.4.2 yamt s3c2440_i2s_buf_t sc_play_buf;
66 1.1.4.2 yamt s3c2440_i2s_buf_t sc_rec_buf;
67 1.1.4.2 yamt
68 1.1.4.2 yamt void *sc_i2s_handle;
69 1.1.4.2 yamt
70 1.1.4.2 yamt bool sc_open;
71 1.1.4.2 yamt };
72 1.1.4.2 yamt
73 1.1.4.2 yamt int uda_ssio_open(void *, int);
74 1.1.4.2 yamt void uda_ssio_close(void *);
75 1.1.4.2 yamt int uda_ssio_set_params(void *, int, int, audio_params_t *, audio_params_t *,
76 1.1.4.2 yamt stream_filter_list_t *, stream_filter_list_t *);
77 1.1.4.2 yamt int uda_ssio_round_blocksize(void *, int, int, const audio_params_t *);
78 1.1.4.2 yamt int uda_ssio_start_output(void *, void *, int, void (*)(void *),
79 1.1.4.2 yamt void *);
80 1.1.4.2 yamt int uda_ssio_start_input(void *, void *, int, void (*)(void *),
81 1.1.4.2 yamt void *);
82 1.1.4.2 yamt int uda_ssio_halt_output(void *);
83 1.1.4.2 yamt int uda_ssio_halt_input(void *);
84 1.1.4.2 yamt int uda_ssio_getdev(void *, struct audio_device *ret);
85 1.1.4.2 yamt void* uda_ssio_allocm(void *, int, size_t);
86 1.1.4.2 yamt void uda_ssio_freem(void *, void *, size_t);
87 1.1.4.2 yamt size_t uda_ssio_round_buffersize(void *, int, size_t);
88 1.1.4.2 yamt int uda_ssio_getprops(void *);
89 1.1.4.2 yamt void uda_ssio_get_locks(void *, kmutex_t**, kmutex_t**);
90 1.1.4.2 yamt
91 1.1.4.2 yamt struct audio_hw_if uda1341_hw_if = {
92 1.1.4.2 yamt uda_ssio_open,
93 1.1.4.2 yamt uda_ssio_close,
94 1.1.4.2 yamt NULL,
95 1.1.4.2 yamt uda1341_query_encodings,
96 1.1.4.2 yamt uda_ssio_set_params,
97 1.1.4.2 yamt uda_ssio_round_blocksize,
98 1.1.4.2 yamt NULL, /* commit_settings*/
99 1.1.4.2 yamt NULL,
100 1.1.4.2 yamt NULL,
101 1.1.4.2 yamt uda_ssio_start_output,
102 1.1.4.2 yamt uda_ssio_start_input,
103 1.1.4.2 yamt uda_ssio_halt_output,
104 1.1.4.2 yamt uda_ssio_halt_input,
105 1.1.4.2 yamt NULL,
106 1.1.4.2 yamt uda_ssio_getdev,
107 1.1.4.2 yamt NULL,
108 1.1.4.2 yamt uda1341_set_port,
109 1.1.4.2 yamt uda1341_get_port,
110 1.1.4.2 yamt uda1341_query_devinfo,
111 1.1.4.2 yamt uda_ssio_allocm,
112 1.1.4.2 yamt uda_ssio_freem,
113 1.1.4.2 yamt uda_ssio_round_buffersize,
114 1.1.4.2 yamt NULL, /* mappage */
115 1.1.4.2 yamt uda_ssio_getprops,
116 1.1.4.2 yamt NULL,
117 1.1.4.2 yamt NULL,
118 1.1.4.2 yamt NULL,
119 1.1.4.2 yamt uda_ssio_get_locks
120 1.1.4.2 yamt };
121 1.1.4.2 yamt
122 1.1.4.2 yamt static struct audio_device uda1341_device = {
123 1.1.4.2 yamt "MINI2240-UDA1341",
124 1.1.4.2 yamt "0.1",
125 1.1.4.2 yamt "uda_ssio"
126 1.1.4.2 yamt };
127 1.1.4.2 yamt
128 1.1.4.2 yamt void uda_ssio_l3_write(void *,int mode, int value);
129 1.1.4.2 yamt
130 1.1.4.2 yamt int uda_ssio_match(device_t, cfdata_t, void*);
131 1.1.4.2 yamt void uda_ssio_attach(device_t, device_t, void*);
132 1.1.4.2 yamt
133 1.1.4.2 yamt CFATTACH_DECL_NEW(udassio, sizeof(struct uda_softc),
134 1.1.4.2 yamt uda_ssio_match, uda_ssio_attach, NULL, NULL);
135 1.1.4.2 yamt
136 1.1.4.2 yamt int
137 1.1.4.2 yamt uda_ssio_match(device_t parent, cfdata_t match, void *aux)
138 1.1.4.2 yamt {
139 1.1.4.2 yamt DPRINTF(("%s\n", __func__));
140 1.1.4.2 yamt /* Not quite sure how we can detect the UDA1341 chip */
141 1.1.4.2 yamt return 1;
142 1.1.4.2 yamt }
143 1.1.4.2 yamt
144 1.1.4.2 yamt void
145 1.1.4.2 yamt uda_ssio_attach(device_t parent, device_t self, void *aux)
146 1.1.4.2 yamt {
147 1.1.4.2 yamt /* struct s3c2xx0_attach_args *sa = aux;*/
148 1.1.4.2 yamt struct uda_softc *sc = device_private(self);
149 1.1.4.2 yamt struct s3c2xx0_softc *s3sc = s3c2xx0_softc; /* Shortcut */
150 1.1.4.2 yamt struct s3c2440_i2s_attach_args *aa = aux;
151 1.1.4.2 yamt uint32_t reg;
152 1.1.4.2 yamt
153 1.1.4.2 yamt sc->sc_dev = self;
154 1.1.4.2 yamt
155 1.1.4.2 yamt sc->sc_play_buf = NULL;
156 1.1.4.2 yamt sc->sc_i2s_handle = aa->i2sa_handle;
157 1.1.4.2 yamt sc->sc_open = false;
158 1.1.4.2 yamt
159 1.1.4.2 yamt mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
160 1.1.4.2 yamt mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
161 1.1.4.2 yamt
162 1.1.4.2 yamt s3c2440_i2s_set_intr_lock(aa->i2sa_handle, &sc->sc_intr_lock);
163 1.1.4.2 yamt
164 1.1.4.2 yamt /* arch/arm/s3c2xx0/s3c2440.c initializes the I2S subsystem for us */
165 1.1.4.2 yamt
166 1.1.4.2 yamt /* Setup GPIO pins to output for L3 communication.
167 1.1.4.2 yamt GPB3 (L3DATA) will have to be switched to input when reading
168 1.1.4.2 yamt from the L3 bus.
169 1.1.4.2 yamt
170 1.1.4.2 yamt GPB2 - L3MODE
171 1.1.4.2 yamt GPB3 - L3DATA
172 1.1.4.2 yamt GPB4 - L3CLOCK
173 1.1.4.2 yamt TODO: Make this configurable
174 1.1.4.2 yamt */
175 1.1.4.2 yamt reg = bus_space_read_4(s3sc->sc_iot, s3sc->sc_gpio_ioh, GPIO_PBCON);
176 1.1.4.2 yamt reg = GPIO_SET_FUNC(reg, 2, 1);
177 1.1.4.2 yamt reg = GPIO_SET_FUNC(reg, 3, 1);
178 1.1.4.2 yamt reg = GPIO_SET_FUNC(reg, 4, 1);
179 1.1.4.2 yamt bus_space_write_4(s3sc->sc_iot, s3sc->sc_gpio_ioh, GPIO_PBCON, reg);
180 1.1.4.2 yamt
181 1.1.4.2 yamt reg = bus_space_read_4(s3sc->sc_iot, s3sc->sc_gpio_ioh, GPIO_PBDAT);
182 1.1.4.2 yamt reg = GPIO_SET_DATA(reg, 4, 1);
183 1.1.4.2 yamt reg = GPIO_SET_DATA(reg, 3, 0);
184 1.1.4.2 yamt reg = GPIO_SET_DATA(reg, 2, 1);
185 1.1.4.2 yamt bus_space_write_4(s3sc->sc_iot, s3sc->sc_gpio_ioh, GPIO_PBDAT, reg);
186 1.1.4.2 yamt
187 1.1.4.2 yamt printf("\n");
188 1.1.4.2 yamt
189 1.1.4.2 yamt /* uda1341_attach resets the uda1341 sc, so it has to be called before
190 1.1.4.2 yamt attributes are set on the sc.*/
191 1.1.4.2 yamt uda1341_attach(&sc->sc_uda1341);
192 1.1.4.2 yamt
193 1.1.4.2 yamt /* Configure the UDA1341 Codec */
194 1.1.4.2 yamt sc->sc_uda1341.parent = sc;
195 1.1.4.2 yamt sc->sc_uda1341.sc_l3_write = uda_ssio_l3_write;
196 1.1.4.2 yamt sc->sc_uda1341.sc_bus_format = UDA1341_BUS_MSB;
197 1.1.4.2 yamt
198 1.1.4.2 yamt /* Configure I2S controller */
199 1.1.4.2 yamt s3c2440_i2s_set_bus_format(sc->sc_i2s_handle, S3C2440_I2S_BUS_MSB);
200 1.1.4.2 yamt // Attach
201 1.1.4.2 yamt audio_attach_mi(&uda1341_hw_if, &sc->sc_uda1341, self);
202 1.1.4.2 yamt }
203 1.1.4.2 yamt
204 1.1.4.2 yamt int
205 1.1.4.2 yamt uda_ssio_open(void *handle, int flags)
206 1.1.4.2 yamt {
207 1.1.4.2 yamt struct uda1341_softc *uc = handle;
208 1.1.4.2 yamt struct uda_softc *sc = uc->parent;
209 1.1.4.2 yamt int retval;
210 1.1.4.2 yamt
211 1.1.4.2 yamt DPRINTF(("%s\n", __func__));
212 1.1.4.2 yamt
213 1.1.4.2 yamt if (sc->sc_open)
214 1.1.4.2 yamt return EBUSY;
215 1.1.4.2 yamt
216 1.1.4.2 yamt /* We only support write operations */
217 1.1.4.2 yamt if (!(flags & FREAD) && !(flags & FWRITE))
218 1.1.4.2 yamt return EINVAL;
219 1.1.4.2 yamt
220 1.1.4.2 yamt /* We can't do much more at this point than to
221 1.1.4.2 yamt ask the UDA1341 codec to initialize itself
222 1.1.4.2 yamt (for an unknown system clock)
223 1.1.4.2 yamt */
224 1.1.4.2 yamt retval = uda1341_open(handle, flags);
225 1.1.4.2 yamt if (retval != 0) {
226 1.1.4.2 yamt return retval;
227 1.1.4.2 yamt }
228 1.1.4.2 yamt
229 1.1.4.2 yamt sc->sc_open = true;
230 1.1.4.2 yamt
231 1.1.4.2 yamt return 0; /* SUCCESS */
232 1.1.4.2 yamt }
233 1.1.4.2 yamt
234 1.1.4.2 yamt void
235 1.1.4.2 yamt uda_ssio_close(void *handle)
236 1.1.4.2 yamt {
237 1.1.4.2 yamt struct uda1341_softc *uc = handle;
238 1.1.4.2 yamt struct uda_softc *sc = uc->parent;
239 1.1.4.2 yamt DPRINTF(("%s\n", __func__));
240 1.1.4.2 yamt
241 1.1.4.2 yamt uda1341_close(handle);
242 1.1.4.2 yamt sc->sc_open = false;
243 1.1.4.2 yamt }
244 1.1.4.2 yamt
245 1.1.4.2 yamt int
246 1.1.4.2 yamt uda_ssio_set_params(void *handle, int setmode, int usemode,
247 1.1.4.2 yamt audio_params_t *play, audio_params_t *rec,
248 1.1.4.2 yamt stream_filter_list_t *pfil, stream_filter_list_t *rfil)
249 1.1.4.2 yamt {
250 1.1.4.2 yamt struct uda1341_softc *uc = handle;
251 1.1.4.2 yamt struct uda_softc *sc = uc->parent;
252 1.1.4.2 yamt const struct audio_format *selected_format;
253 1.1.4.2 yamt audio_params_t *params;
254 1.1.4.2 yamt stream_filter_list_t *fil;
255 1.1.4.2 yamt int retval;
256 1.1.4.2 yamt
257 1.1.4.2 yamt DPRINTF(("%s: setmode: %d\n", __func__, setmode));
258 1.1.4.2 yamt DPRINTF(("%s: usemode: %d\n", __func__, usemode));
259 1.1.4.2 yamt
260 1.1.4.2 yamt if (setmode == 0)
261 1.1.4.2 yamt setmode = usemode;
262 1.1.4.2 yamt
263 1.1.4.2 yamt if (setmode & AUMODE_PLAY) {
264 1.1.4.2 yamt params = play;
265 1.1.4.2 yamt fil = pfil;
266 1.1.4.2 yamt } else if (setmode == AUMODE_RECORD) {
267 1.1.4.2 yamt params = rec;
268 1.1.4.2 yamt fil = rfil;
269 1.1.4.2 yamt } else {
270 1.1.4.2 yamt return EINVAL;
271 1.1.4.2 yamt }
272 1.1.4.2 yamt
273 1.1.4.2 yamt DPRINTF(("%s: %dHz, encoding: %d, precision: %d, channels: %d\n",
274 1.1.4.2 yamt __func__, params->sample_rate, params->encoding, play->precision,
275 1.1.4.2 yamt params->channels));
276 1.1.4.2 yamt
277 1.1.4.2 yamt if (params->sample_rate != 8000 &&
278 1.1.4.2 yamt params->sample_rate != 11025 &&
279 1.1.4.2 yamt params->sample_rate != 22050 &&
280 1.1.4.2 yamt params->sample_rate != 32000 &&
281 1.1.4.2 yamt params->sample_rate != 44100 &&
282 1.1.4.2 yamt params->sample_rate != 48000) {
283 1.1.4.2 yamt return EINVAL;
284 1.1.4.2 yamt }
285 1.1.4.2 yamt
286 1.1.4.2 yamt retval = auconv_set_converter(uda1341_formats, UDA1341_NFORMATS,
287 1.1.4.2 yamt setmode, params, true, fil);
288 1.1.4.2 yamt if (retval < 0) {
289 1.1.4.2 yamt printf("Could not find valid format\n");
290 1.1.4.2 yamt return EINVAL;
291 1.1.4.2 yamt }
292 1.1.4.2 yamt
293 1.1.4.2 yamt selected_format = &uda1341_formats[retval];
294 1.1.4.2 yamt
295 1.1.4.2 yamt if (setmode == AUMODE_PLAY) {
296 1.1.4.2 yamt s3c2440_i2s_set_direction(sc->sc_i2s_handle,
297 1.1.4.2 yamt S3C2440_I2S_TRANSMIT);
298 1.1.4.2 yamt } else {
299 1.1.4.2 yamt s3c2440_i2s_set_direction(sc->sc_i2s_handle,
300 1.1.4.2 yamt S3C2440_I2S_RECEIVE);
301 1.1.4.2 yamt }
302 1.1.4.2 yamt
303 1.1.4.2 yamt s3c2440_i2s_set_sample_rate(sc->sc_i2s_handle, params->sample_rate);
304 1.1.4.2 yamt s3c2440_i2s_set_sample_width(sc->sc_i2s_handle,
305 1.1.4.2 yamt selected_format->precision);
306 1.1.4.2 yamt
307 1.1.4.2 yamt /* It is vital that sc_system_clock is set PRIOR to calling
308 1.1.4.2 yamt uda1341_set_params. */
309 1.1.4.2 yamt switch (s3c2440_i2s_get_master_clock(sc->sc_i2s_handle)) {
310 1.1.4.2 yamt case 384:
311 1.1.4.2 yamt uc->sc_system_clock = UDA1341_CLOCK_384;
312 1.1.4.2 yamt break;
313 1.1.4.2 yamt case 256:
314 1.1.4.2 yamt uc->sc_system_clock = UDA1341_CLOCK_256;
315 1.1.4.2 yamt break;
316 1.1.4.2 yamt default:
317 1.1.4.2 yamt return EINVAL;
318 1.1.4.2 yamt }
319 1.1.4.2 yamt
320 1.1.4.2 yamt retval = uda1341_set_params(handle, setmode, usemode,
321 1.1.4.2 yamt play, rec, pfil, rfil);
322 1.1.4.2 yamt if (retval != 0) {
323 1.1.4.2 yamt return retval;
324 1.1.4.2 yamt }
325 1.1.4.2 yamt
326 1.1.4.2 yamt /* Setup and enable I2S controller */
327 1.1.4.2 yamt retval = s3c2440_i2s_commit(sc->sc_i2s_handle);
328 1.1.4.2 yamt if (retval != 0) {
329 1.1.4.2 yamt printf("Failed to setup I2S controller\n");
330 1.1.4.2 yamt return retval;
331 1.1.4.2 yamt }
332 1.1.4.2 yamt
333 1.1.4.2 yamt return 0;
334 1.1.4.2 yamt }
335 1.1.4.2 yamt
336 1.1.4.2 yamt int
337 1.1.4.2 yamt uda_ssio_round_blocksize(void *handle, int bs, int mode,
338 1.1.4.2 yamt const audio_params_t *param)
339 1.1.4.2 yamt {
340 1.1.4.2 yamt int out_bs;
341 1.1.4.2 yamt DPRINTF(("%s: %d\n", __func__, bs));
342 1.1.4.2 yamt
343 1.1.4.2 yamt out_bs = (bs + 0x03) & ~0x03;
344 1.1.4.2 yamt DPRINTF(("%s: out_bs: %d\n", __func__, out_bs));
345 1.1.4.2 yamt return out_bs;
346 1.1.4.2 yamt }
347 1.1.4.2 yamt
348 1.1.4.2 yamt int
349 1.1.4.2 yamt uda_ssio_start_output(void *handle, void *block, int bsize,
350 1.1.4.2 yamt void (*intr)(void *), void *intrarg)
351 1.1.4.2 yamt {
352 1.1.4.2 yamt struct uda1341_softc *uc = handle;
353 1.1.4.2 yamt struct uda_softc *sc = uc->parent;
354 1.1.4.2 yamt
355 1.1.4.2 yamt return s3c2440_i2s_output(sc->sc_play_buf, block, bsize, intr, intrarg);
356 1.1.4.2 yamt }
357 1.1.4.2 yamt
358 1.1.4.2 yamt int
359 1.1.4.2 yamt uda_ssio_start_input(void *handle, void *block, int bsize,
360 1.1.4.2 yamt void (*intr)(void *), void *intrarg)
361 1.1.4.2 yamt {
362 1.1.4.2 yamt struct uda1341_softc *uc = handle;
363 1.1.4.2 yamt struct uda_softc *sc = uc->parent;
364 1.1.4.2 yamt
365 1.1.4.2 yamt return s3c2440_i2s_input(sc->sc_rec_buf, block, bsize, intr, intrarg);
366 1.1.4.2 yamt }
367 1.1.4.2 yamt
368 1.1.4.2 yamt int
369 1.1.4.2 yamt uda_ssio_halt_output(void *handle)
370 1.1.4.2 yamt {
371 1.1.4.2 yamt struct uda1341_softc *uc = handle;
372 1.1.4.2 yamt struct uda_softc *sc = uc->parent;
373 1.1.4.2 yamt
374 1.1.4.2 yamt return s3c2440_i2s_halt_output(sc->sc_play_buf);
375 1.1.4.2 yamt }
376 1.1.4.2 yamt
377 1.1.4.2 yamt int
378 1.1.4.2 yamt uda_ssio_halt_input(void *handle)
379 1.1.4.2 yamt {
380 1.1.4.2 yamt DPRINTF(("%s\n", __func__));
381 1.1.4.2 yamt return 0;
382 1.1.4.2 yamt }
383 1.1.4.2 yamt
384 1.1.4.2 yamt int
385 1.1.4.2 yamt uda_ssio_getdev(void *handle, struct audio_device *ret)
386 1.1.4.2 yamt {
387 1.1.4.2 yamt *ret = uda1341_device;
388 1.1.4.2 yamt return 0;
389 1.1.4.2 yamt }
390 1.1.4.2 yamt
391 1.1.4.2 yamt void *
392 1.1.4.2 yamt uda_ssio_allocm(void *handle, int direction, size_t size)
393 1.1.4.2 yamt {
394 1.1.4.2 yamt struct uda1341_softc *uc = handle;
395 1.1.4.2 yamt struct uda_softc *sc = uc->parent;
396 1.1.4.2 yamt void *retval = NULL;
397 1.1.4.2 yamt
398 1.1.4.2 yamt DPRINTF(("%s\n", __func__));
399 1.1.4.2 yamt
400 1.1.4.2 yamt if (direction == AUMODE_PLAY ) {
401 1.1.4.2 yamt if (sc->sc_play_buf != NULL)
402 1.1.4.2 yamt return NULL;
403 1.1.4.2 yamt
404 1.1.4.2 yamt s3c2440_i2s_alloc(sc->sc_i2s_handle, direction, size, 0x00, &sc->sc_play_buf);
405 1.1.4.2 yamt DPRINTF(("%s: addr of ring buffer: %p\n", __func__, sc->sc_play_buf->i2b_addr));
406 1.1.4.2 yamt retval = sc->sc_play_buf->i2b_addr;
407 1.1.4.2 yamt } else if (direction == AUMODE_RECORD) {
408 1.1.4.2 yamt if (sc->sc_rec_buf != NULL)
409 1.1.4.2 yamt return NULL;
410 1.1.4.2 yamt
411 1.1.4.2 yamt s3c2440_i2s_alloc(sc->sc_i2s_handle, direction, size, 0x00, &sc->sc_rec_buf);
412 1.1.4.2 yamt DPRINTF(("%s: addr of ring buffer: %p\n", __func__, sc->sc_rec_buf->i2b_addr));
413 1.1.4.2 yamt retval = sc->sc_rec_buf->i2b_addr;
414 1.1.4.2 yamt }
415 1.1.4.2 yamt
416 1.1.4.2 yamt DPRINTF(("buffer: %p", retval));
417 1.1.4.2 yamt
418 1.1.4.2 yamt return retval;
419 1.1.4.2 yamt }
420 1.1.4.2 yamt
421 1.1.4.2 yamt void
422 1.1.4.2 yamt uda_ssio_freem(void *handle, void *ptr, size_t size)
423 1.1.4.2 yamt {
424 1.1.4.2 yamt struct uda1341_softc *uc = handle;
425 1.1.4.2 yamt struct uda_softc *sc = uc->parent;
426 1.1.4.2 yamt DPRINTF(("%s\n", __func__));
427 1.1.4.2 yamt
428 1.1.4.2 yamt if (ptr == sc->sc_play_buf->i2b_addr)
429 1.1.4.2 yamt s3c2440_i2s_free(sc->sc_play_buf);
430 1.1.4.2 yamt else if (ptr == sc->sc_rec_buf->i2b_addr)
431 1.1.4.2 yamt s3c2440_i2s_free(sc->sc_rec_buf);
432 1.1.4.2 yamt }
433 1.1.4.2 yamt
434 1.1.4.2 yamt size_t
435 1.1.4.2 yamt uda_ssio_round_buffersize(void *handle, int direction, size_t bufsize)
436 1.1.4.2 yamt {
437 1.1.4.2 yamt DPRINTF(("%s: %d\n", __func__, (int)bufsize));
438 1.1.4.2 yamt return bufsize;
439 1.1.4.2 yamt }
440 1.1.4.2 yamt
441 1.1.4.2 yamt int
442 1.1.4.2 yamt uda_ssio_getprops(void *handle)
443 1.1.4.2 yamt {
444 1.1.4.2 yamt return AUDIO_PROP_PLAYBACK | AUDIO_PROP_CAPTURE;
445 1.1.4.2 yamt }
446 1.1.4.2 yamt
447 1.1.4.2 yamt void
448 1.1.4.2 yamt uda_ssio_get_locks(void *handle, kmutex_t **intr, kmutex_t **thread)
449 1.1.4.2 yamt {
450 1.1.4.2 yamt struct uda1341_softc *uc = handle;
451 1.1.4.2 yamt struct uda_softc *sc = uc->parent;
452 1.1.4.2 yamt //struct uda_softc *sc = handle;
453 1.1.4.2 yamt
454 1.1.4.2 yamt *intr = &sc->sc_intr_lock;
455 1.1.4.2 yamt *thread = &sc->sc_lock;
456 1.1.4.2 yamt }
457 1.1.4.2 yamt
458 1.1.4.2 yamt void
459 1.1.4.2 yamt uda_ssio_l3_write(void *cookie, int mode, int value)
460 1.1.4.2 yamt {
461 1.1.4.2 yamt struct s3c2xx0_softc *s3sc = s3c2xx0_softc; /* Shortcut */
462 1.1.4.2 yamt uint32_t reg;
463 1.1.4.2 yamt
464 1.1.4.2 yamt /* GPB2: L3MODE
465 1.1.4.2 yamt GPB3: L2DATA
466 1.1.4.2 yamt GPB4: L3CLOCK */
467 1.1.4.2 yamt #define L3MODE 2
468 1.1.4.2 yamt #define L3DATA 3
469 1.1.4.2 yamt #define L3CLOCK 4
470 1.1.4.2 yamt #define READ_GPIO() bus_space_read_4(s3sc->sc_iot, s3sc->sc_gpio_ioh, GPIO_PBDAT)
471 1.1.4.2 yamt #define WRITE_GPIO(val) bus_space_write_4(s3sc->sc_iot, s3sc->sc_gpio_ioh, GPIO_PBDAT, val)
472 1.1.4.2 yamt
473 1.1.4.2 yamt #define DELAY_TIME 1
474 1.1.4.2 yamt
475 1.1.4.2 yamt reg = READ_GPIO();
476 1.1.4.2 yamt reg = GPIO_SET_DATA(reg, L3CLOCK, 1);
477 1.1.4.2 yamt reg = GPIO_SET_DATA(reg, L3MODE, mode);
478 1.1.4.2 yamt reg = GPIO_SET_DATA(reg, L3DATA, 0);
479 1.1.4.2 yamt WRITE_GPIO(reg);
480 1.1.4.2 yamt
481 1.1.4.2 yamt if (mode == 1 ) {
482 1.1.4.2 yamt reg = READ_GPIO();
483 1.1.4.2 yamt reg = GPIO_SET_DATA(reg, L3MODE, 1);
484 1.1.4.2 yamt WRITE_GPIO(reg);
485 1.1.4.2 yamt }
486 1.1.4.2 yamt
487 1.1.4.2 yamt DELAY(1); /* L3MODE setup time: min 190ns */
488 1.1.4.2 yamt
489 1.1.4.2 yamt for(int i = 0; i<8; i++) {
490 1.1.4.2 yamt char bval = (value >> i) & 0x1;
491 1.1.4.2 yamt
492 1.1.4.2 yamt reg = READ_GPIO();
493 1.1.4.2 yamt reg = GPIO_SET_DATA(reg, L3CLOCK, 0);
494 1.1.4.2 yamt reg = GPIO_SET_DATA(reg, L3DATA, bval);
495 1.1.4.2 yamt WRITE_GPIO(reg);
496 1.1.4.2 yamt
497 1.1.4.2 yamt DELAY(DELAY_TIME);
498 1.1.4.2 yamt
499 1.1.4.2 yamt reg = READ_GPIO();
500 1.1.4.2 yamt reg = GPIO_SET_DATA(reg, L3CLOCK, 1);
501 1.1.4.2 yamt reg = GPIO_SET_DATA(reg, L3DATA, bval);
502 1.1.4.2 yamt WRITE_GPIO(reg);
503 1.1.4.2 yamt
504 1.1.4.2 yamt DELAY(DELAY_TIME);
505 1.1.4.2 yamt }
506 1.1.4.2 yamt
507 1.1.4.2 yamt reg = READ_GPIO();
508 1.1.4.2 yamt reg = GPIO_SET_DATA(reg, L3MODE, 1);
509 1.1.4.2 yamt reg = GPIO_SET_DATA(reg, L3CLOCK, 1);
510 1.1.4.2 yamt reg = GPIO_SET_DATA(reg, L3DATA, 0);
511 1.1.4.2 yamt WRITE_GPIO(reg);
512 1.1.4.2 yamt
513 1.1.4.2 yamt #undef L3MODE
514 1.1.4.2 yamt #undef L3DATA
515 1.1.4.2 yamt #undef L3CLOCK
516 1.1.4.2 yamt #undef DELAY_TIME
517 1.1.4.2 yamt #undef READ_GPIO
518 1.1.4.2 yamt #undef WRITE_GPIO
519 1.1.4.2 yamt }
520