gcscaudio.c revision 1.16.2.1 1 /* $NetBSD: gcscaudio.c,v 1.16.2.1 2019/04/21 05:11:22 isaki Exp $ */
2
3 /*-
4 * Copyright (c) 2008 SHIMIZU Ryo <ryo (at) nerv.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: gcscaudio.c,v 1.16.2.1 2019/04/21 05:11:22 isaki Exp $");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/kmem.h>
35 #include <sys/device.h>
36 #include <sys/queue.h>
37
38 #include <dev/pci/pcidevs.h>
39 #include <dev/pci/pcivar.h>
40
41 #include <sys/audioio.h>
42 #include <dev/audio_if.h>
43 #include <dev/mulaw.h>
44 #include <dev/auconv.h>
45 #include <dev/ic/ac97reg.h>
46 #include <dev/ic/ac97var.h>
47
48 #include <dev/pci/gcscaudioreg.h>
49
50
51 #define GCSCAUDIO_NPRDTABLE 256 /* including a JMP-PRD for loop */
52 #define GCSCAUDIO_PRD_SIZE_MAX 65532 /* limited by CS5536 Controller */
53 #define GCSCAUDIO_BUFSIZE_MAX (GCSCAUDIO_PRD_SIZE_MAX * (GCSCAUDIO_NPRDTABLE - 1))
54
55 struct gcscaudio_prd {
56 /* PRD table for play/rec */
57 struct gcscaudio_prdtables {
58 #define PRD_TABLE_FRONT 0
59 #define PRD_TABLE_SURR 1
60 #define PRD_TABLE_CENTER 2
61 #define PRD_TABLE_LFE 3
62 #define PRD_TABLE_REC 4
63 #define PRD_TABLE_MAX 5
64 struct acc_prd prdtbl[PRD_TABLE_MAX][GCSCAUDIO_NPRDTABLE];
65 } *p_prdtables;
66 bus_dmamap_t p_prdmap;
67 bus_dma_segment_t p_prdsegs[1];
68 int p_prdnseg;
69 };
70
71 struct gcscaudio_dma {
72 LIST_ENTRY(gcscaudio_dma) list;
73 bus_dmamap_t map;
74 void *addr;
75 size_t size;
76 bus_dma_segment_t segs[1];
77 int nseg;
78 };
79
80 struct gcscaudio_softc_ch {
81 void (*ch_intr)(void *);
82 void *ch_intr_arg;
83 struct audio_params ch_params;
84 };
85
86 struct gcscaudio_softc {
87 device_t sc_dev;
88 kmutex_t sc_lock;
89 kmutex_t sc_intr_lock;
90 pci_chipset_tag_t sc_pc;
91 pcitag_t sc_pt;
92 void *sc_ih;
93 bus_space_tag_t sc_iot;
94 bus_space_handle_t sc_ioh;
95 bus_size_t sc_ios;
96 bus_dma_tag_t sc_dmat;
97
98 /* allocated DMA buffer list */
99 LIST_HEAD(, gcscaudio_dma) sc_dmalist;
100
101 #define GCSCAUDIO_MAXFORMATS 4
102 struct audio_format sc_formats[GCSCAUDIO_MAXFORMATS];
103 int sc_nformats;
104 struct audio_encoding_set *sc_encodings;
105
106 /* AC97 codec */
107 struct ac97_host_if host_if;
108 struct ac97_codec_if *codec_if;
109
110 /* input, output channels */
111 struct gcscaudio_softc_ch sc_play;
112 struct gcscaudio_softc_ch sc_rec;
113 struct gcscaudio_prd sc_prd;
114
115 /* multi channel splitter work; {4,6}ch stream to {2,4} DMA buffers */
116 void *sc_mch_split_buf;
117 void *sc_mch_split_start;
118 int sc_mch_split_off;
119 int sc_mch_split_size;
120 int sc_mch_split_blksize;
121 void (*sc_mch_splitter)(void *, void *, int, int);
122 bool sc_spdif;
123 };
124
125 /* for cfattach */
126 static int gcscaudio_match(device_t, cfdata_t, void *);
127 static void gcscaudio_attach(device_t, device_t, void *);
128
129 /* for audio_hw_if */
130 static int gcscaudio_open(void *, int);
131 static void gcscaudio_close(void *);
132 static int gcscaudio_query_encoding(void *, struct audio_encoding *);
133 static int gcscaudio_set_params(void *, int, int, audio_params_t *,
134 audio_params_t *, stream_filter_list_t *,
135 stream_filter_list_t *);
136 static int gcscaudio_round_blocksize(void *, int, int, const audio_params_t *);
137 static int gcscaudio_halt_output(void *);
138 static int gcscaudio_halt_input(void *);
139 static int gcscaudio_getdev(void *, struct audio_device *);
140 static int gcscaudio_set_port(void *, mixer_ctrl_t *);
141 static int gcscaudio_get_port(void *, mixer_ctrl_t *);
142 static int gcscaudio_query_devinfo(void *, mixer_devinfo_t *);
143 static void *gcscaudio_malloc(void *, int, size_t);
144 static void gcscaudio_free(void *, void *, size_t);
145 static size_t gcscaudio_round_buffersize(void *, int, size_t);
146 static paddr_t gcscaudio_mappage(void *, void *, off_t, int);
147 static int gcscaudio_get_props(void *);
148 static int gcscaudio_trigger_output(void *, void *, void *, int,
149 void (*)(void *), void *,
150 const audio_params_t *);
151 static int gcscaudio_trigger_input(void *, void *, void *, int,
152 void (*)(void *), void *,
153 const audio_params_t *);
154 static void gcscaudio_get_locks(void *, kmutex_t **, kmutex_t **);
155 static bool gcscaudio_resume(device_t, const pmf_qual_t *);
156 static int gcscaudio_intr(void *);
157
158 /* for codec_if */
159 static int gcscaudio_attach_codec(void *, struct ac97_codec_if *);
160 static int gcscaudio_write_codec(void *, uint8_t, uint16_t);
161 static int gcscaudio_read_codec(void *, uint8_t, uint16_t *);
162 static int gcscaudio_reset_codec(void *);
163 static void gcscaudio_spdif_event_codec(void *, bool);
164
165 /* misc */
166 static int gcscaudio_append_formats(struct gcscaudio_softc *,
167 const struct audio_format *);
168 static int gcscaudio_wait_ready_codec(struct gcscaudio_softc *sc, const char *);
169 static int gcscaudio_set_params_ch(struct gcscaudio_softc *,
170 struct gcscaudio_softc_ch *, int,
171 audio_params_t *, stream_filter_list_t *);
172 static int gcscaudio_allocate_dma(struct gcscaudio_softc *, size_t, void **,
173 bus_dma_segment_t *, int, int *,
174 bus_dmamap_t *);
175
176
177 CFATTACH_DECL_NEW(gcscaudio, sizeof (struct gcscaudio_softc),
178 gcscaudio_match, gcscaudio_attach, NULL, NULL);
179
180
181 static struct audio_device gcscaudio_device = {
182 "AMD Geode CS5536",
183 "",
184 "gcscaudio"
185 };
186
187 static const struct audio_hw_if gcscaudio_hw_if = {
188 .open = gcscaudio_open,
189 .close = gcscaudio_close,
190 .drain = NULL,
191 .query_encoding = gcscaudio_query_encoding,
192 .set_params = gcscaudio_set_params,
193 .round_blocksize = gcscaudio_round_blocksize,
194 .commit_settings = NULL,
195 .init_output = NULL,
196 .init_input = NULL,
197 .start_output = NULL,
198 .start_input = NULL,
199 .halt_output = gcscaudio_halt_output,
200 .halt_input = gcscaudio_halt_input,
201 .speaker_ctl = NULL,
202 .getdev = gcscaudio_getdev,
203 .setfd = NULL,
204 .set_port = gcscaudio_set_port,
205 .get_port = gcscaudio_get_port,
206 .query_devinfo = gcscaudio_query_devinfo,
207 .allocm = gcscaudio_malloc,
208 .freem = gcscaudio_free,
209 .round_buffersize = gcscaudio_round_buffersize,
210 .mappage = gcscaudio_mappage,
211 .get_props = gcscaudio_get_props,
212 .trigger_output = gcscaudio_trigger_output,
213 .trigger_input = gcscaudio_trigger_input,
214 .dev_ioctl = NULL,
215 .get_locks = gcscaudio_get_locks,
216 };
217
218 #define GCSCAUDIO_FORMAT(aumode, ch, chmask) \
219 { \
220 .mode = (aumode), \
221 .encoding = AUDIO_ENCODING_SLINEAR_LE, \
222 .validbits = 16, \
223 .precision = 16, \
224 .channels = (ch), \
225 .channel_mask = (chmask), \
226 .frequency_type = 0, \
227 .frequency = { 8000, 48000 }, \
228 }
229 static const struct audio_format gcscaudio_formats_2ch =
230 GCSCAUDIO_FORMAT(AUMODE_PLAY | AUMODE_RECORD, 2, AUFMT_STEREO);
231
232 static const struct audio_format gcscaudio_formats_4ch =
233 GCSCAUDIO_FORMAT(AUMODE_PLAY , 4, AUFMT_SURROUND4);
234
235 static const struct audio_format gcscaudio_formats_6ch =
236 GCSCAUDIO_FORMAT(AUMODE_PLAY , 6, AUFMT_DOLBY_5_1);
237
238 static int
239 gcscaudio_match(device_t parent, cfdata_t match, void *aux)
240 {
241 struct pci_attach_args *pa;
242
243 pa = (struct pci_attach_args *)aux;
244 if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD) &&
245 (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_CS5536_AUDIO))
246 return 1;
247
248 return 0;
249 }
250
251 static int
252 gcscaudio_append_formats(struct gcscaudio_softc *sc,
253 const struct audio_format *format)
254 {
255 if (sc->sc_nformats >= GCSCAUDIO_MAXFORMATS) {
256 aprint_error_dev(sc->sc_dev, "too many formats\n");
257 return EINVAL;
258 }
259 sc->sc_formats[sc->sc_nformats++] = *format;
260 return 0;
261 }
262
263 static void
264 gcscaudio_attach(device_t parent, device_t self, void *aux)
265 {
266 struct gcscaudio_softc *sc;
267 struct pci_attach_args *pa;
268 const char *intrstr;
269 pci_intr_handle_t ih;
270 int rc, i;
271 char intrbuf[PCI_INTRSTR_LEN];
272
273 sc = device_private(self);
274
275 sc->sc_dev = self;
276
277 aprint_naive(": Audio controller\n");
278
279 pa = aux;
280 sc->sc_pc = pa->pa_pc;
281 sc->sc_pt = pa->pa_tag;
282 sc->sc_dmat = pa->pa_dmat;
283 LIST_INIT(&sc->sc_dmalist);
284 sc->sc_mch_split_buf = NULL;
285 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
286 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO);
287
288 aprint_normal(": AMD Geode CS5536 Audio\n");
289
290 if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_IO, 0,
291 &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_ios)) {
292 aprint_error_dev(sc->sc_dev, "can't map i/o space\n");
293 return;
294 }
295
296 if (pci_intr_map(pa, &ih)) {
297 aprint_error_dev(sc->sc_dev, "couldn't map interrupt\n");
298 goto attach_failure_unmap;
299 }
300 intrstr = pci_intr_string(sc->sc_pc, ih, intrbuf, sizeof(intrbuf));
301
302 sc->sc_ih = pci_intr_establish_xname(sc->sc_pc, ih, IPL_AUDIO,
303 gcscaudio_intr, sc, device_xname(self));
304 if (sc->sc_ih == NULL) {
305 aprint_error_dev(sc->sc_dev, "couldn't establish interrupt");
306 if (intrstr != NULL)
307 aprint_error(" at %s", intrstr);
308 aprint_error("\n");
309 goto attach_failure_unmap;
310 }
311
312 aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);
313
314
315 if (gcscaudio_allocate_dma(sc, sizeof(*sc->sc_prd.p_prdtables),
316 (void **)&(sc->sc_prd.p_prdtables), sc->sc_prd.p_prdsegs, 1,
317 &(sc->sc_prd.p_prdnseg), &(sc->sc_prd.p_prdmap)) != 0)
318 goto attach_failure_intr;
319
320 sc->host_if.arg = sc;
321 sc->host_if.attach = gcscaudio_attach_codec;
322 sc->host_if.read = gcscaudio_read_codec;
323 sc->host_if.write = gcscaudio_write_codec;
324 sc->host_if.reset = gcscaudio_reset_codec;
325 sc->host_if.spdif_event = gcscaudio_spdif_event_codec;
326
327 if ((rc = ac97_attach(&sc->host_if, self, &sc->sc_lock)) != 0) {
328 aprint_error_dev(sc->sc_dev,
329 "can't attach codec (error=%d)\n", rc);
330 goto attach_failure_intr;
331 }
332
333 if (!pmf_device_register(self, NULL, gcscaudio_resume))
334 aprint_error_dev(self, "couldn't establish power handler\n");
335
336
337 sc->sc_nformats = 0;
338 gcscaudio_append_formats(sc, &gcscaudio_formats_2ch);
339
340 mutex_enter(&sc->sc_lock);
341 if (AC97_IS_4CH(sc->codec_if))
342 gcscaudio_append_formats(sc, &gcscaudio_formats_4ch);
343 if (AC97_IS_6CH(sc->codec_if))
344 gcscaudio_append_formats(sc, &gcscaudio_formats_6ch);
345 if (AC97_IS_FIXED_RATE(sc->codec_if)) {
346 for (i = 0; i < sc->sc_nformats; i++) {
347 sc->sc_formats[i].frequency_type = 1;
348 sc->sc_formats[i].frequency[0] = 48000;
349 }
350 }
351 mutex_exit(&sc->sc_lock);
352
353 if ((rc = auconv_create_encodings(sc->sc_formats, sc->sc_nformats,
354 &sc->sc_encodings)) != 0) {
355 aprint_error_dev(self,
356 "auconv_create_encoding: error=%d\n", rc);
357 goto attach_failure_codec;
358 }
359
360 audio_attach_mi(&gcscaudio_hw_if, sc, sc->sc_dev);
361 return;
362
363 attach_failure_codec:
364 sc->codec_if->vtbl->detach(sc->codec_if);
365 attach_failure_intr:
366 pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
367 attach_failure_unmap:
368 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
369 return;
370 }
371
372 static int
373 gcscaudio_attach_codec(void *arg, struct ac97_codec_if *codec_if)
374 {
375 struct gcscaudio_softc *sc;
376
377 sc = (struct gcscaudio_softc *)arg;
378 sc->codec_if = codec_if;
379 return 0;
380 }
381
382 static int
383 gcscaudio_reset_codec(void *arg)
384 {
385 struct gcscaudio_softc *sc;
386 sc = (struct gcscaudio_softc *)arg;
387
388 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_CODEC_CNTL,
389 ACC_CODEC_CNTL_LNK_WRM_RST |
390 ACC_CODEC_CNTL_CMD_NEW);
391
392 if (gcscaudio_wait_ready_codec(sc, "reset timeout\n"))
393 return 1;
394
395 return 0;
396 }
397
398 static void
399 gcscaudio_spdif_event_codec(void *arg, bool flag)
400 {
401 struct gcscaudio_softc *sc;
402
403 sc = (struct gcscaudio_softc *)arg;
404 sc->sc_spdif = flag;
405 }
406
407 static int
408 gcscaudio_wait_ready_codec(struct gcscaudio_softc *sc, const char *timeout_msg)
409 {
410 int i;
411
412 #define GCSCAUDIO_WAIT_READY_CODEC_TIMEOUT 500
413 for (i = GCSCAUDIO_WAIT_READY_CODEC_TIMEOUT; (i >= 0) &&
414 (bus_space_read_4(sc->sc_iot, sc->sc_ioh, ACC_CODEC_CNTL) &
415 ACC_CODEC_CNTL_CMD_NEW); i--)
416 delay(1);
417
418 if (i < 0) {
419 aprint_error_dev(sc->sc_dev, "%s", timeout_msg);
420 return 1;
421 }
422
423 return 0;
424 }
425
426 static int
427 gcscaudio_write_codec(void *arg, uint8_t reg, uint16_t val)
428 {
429 struct gcscaudio_softc *sc;
430
431 sc = (struct gcscaudio_softc *)arg;
432
433 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_CODEC_CNTL,
434 ACC_CODEC_CNTL_WRITE_CMD |
435 ACC_CODEC_CNTL_CMD_NEW |
436 ACC_CODEC_REG2ADDR(reg) |
437 (val & ACC_CODEC_CNTL_CMD_DATA_MASK));
438
439 if (gcscaudio_wait_ready_codec(sc, "codec write timeout\n"))
440 return 1;
441
442 #ifdef GCSCAUDIO_CODEC_DEBUG
443 aprint_error_dev(sc->sc_dev, "codec write: reg=0x%02x, val=0x%04x\n",
444 reg, val);
445 #endif
446
447 return 0;
448 }
449
450 static int
451 gcscaudio_read_codec(void *arg, uint8_t reg, uint16_t *val)
452 {
453 struct gcscaudio_softc *sc;
454 uint32_t v;
455 int i;
456
457 sc = (struct gcscaudio_softc *)arg;
458 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_CODEC_CNTL,
459 ACC_CODEC_CNTL_READ_CMD | ACC_CODEC_CNTL_CMD_NEW |
460 ACC_CODEC_REG2ADDR(reg));
461
462 if (gcscaudio_wait_ready_codec(sc, "codec write timeout for reading"))
463 return 1;
464
465 #define GCSCAUDIO_READ_CODEC_TIMEOUT 50
466 for (i = GCSCAUDIO_READ_CODEC_TIMEOUT; i >= 0; i--) {
467 v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, ACC_CODEC_STATUS);
468 if ((v & ACC_CODEC_STATUS_STS_NEW) &&
469 (ACC_CODEC_ADDR2REG(v) == reg))
470 break;
471
472 delay(10);
473 }
474
475 if (i < 0) {
476 aprint_error_dev(sc->sc_dev, "codec read timeout\n");
477 return 1;
478 }
479
480 #ifdef GCSCAUDIO_CODEC_DEBUG
481 aprint_error_dev(sc->sc_dev, "codec read: reg=0x%02x, val=0x%04x\n",
482 reg, v & ACC_CODEC_STATUS_STS_DATA_MASK);
483 #endif
484
485 *val = v;
486 return 0;
487 }
488
489 static int
490 gcscaudio_open(void *arg, int flags)
491 {
492 struct gcscaudio_softc *sc;
493
494 sc = (struct gcscaudio_softc *)arg;
495 sc->codec_if->vtbl->lock(sc->codec_if);
496 return 0;
497 }
498
499 static void
500 gcscaudio_close(void *arg)
501 {
502 struct gcscaudio_softc *sc;
503
504 sc = (struct gcscaudio_softc *)arg;
505 sc->codec_if->vtbl->unlock(sc->codec_if);
506 }
507
508 static int
509 gcscaudio_query_encoding(void *arg, struct audio_encoding *fp)
510 {
511 struct gcscaudio_softc *sc;
512
513 sc = (struct gcscaudio_softc *)arg;
514 return auconv_query_encoding(sc->sc_encodings, fp);
515 }
516
517 static int
518 gcscaudio_set_params_ch(struct gcscaudio_softc *sc,
519 struct gcscaudio_softc_ch *ch, int mode,
520 audio_params_t *p, stream_filter_list_t *fil)
521 {
522 int error, idx;
523
524 if ((p->sample_rate < 8000) || (p->sample_rate > 48000))
525 return EINVAL;
526
527 if (p->precision != 8 && p->precision != 16)
528 return EINVAL;
529
530 if ((idx = auconv_set_converter(sc->sc_formats, sc->sc_nformats,
531 mode, p, TRUE, fil)) < 0)
532 return EINVAL;
533
534 if (fil->req_size > 0)
535 p = &fil->filters[0].param;
536
537 if (mode == AUMODE_PLAY) {
538 if (!AC97_IS_FIXED_RATE(sc->codec_if)) {
539 /* setup rate of DAC */
540 if ((error = sc->codec_if->vtbl->set_rate(sc->codec_if,
541 AC97_REG_PCM_FRONT_DAC_RATE, &p->sample_rate)) != 0)
542 return error;
543
544 /* additional rate of DAC for Surround */
545 if ((p->channels >= 4) &&
546 (error = sc->codec_if->vtbl->set_rate(sc->codec_if,
547 AC97_REG_PCM_SURR_DAC_RATE, &p->sample_rate)) != 0)
548 return error;
549
550 /* additional rate of DAC for LowFrequencyEffect */
551 if ((p->channels == 6) &&
552 (error = sc->codec_if->vtbl->set_rate(sc->codec_if,
553 AC97_REG_PCM_LFE_DAC_RATE, &p->sample_rate)) != 0)
554 return error;
555 }
556 }
557
558 if (mode == AUMODE_RECORD) {
559 if (!AC97_IS_FIXED_RATE(sc->codec_if)) {
560 /* setup rate of ADC */
561 if ((error = sc->codec_if->vtbl->set_rate(sc->codec_if,
562 AC97_REG_PCM_LR_ADC_RATE, &p->sample_rate)) != 0)
563 return error;
564 }
565 }
566
567 ch->ch_params = *p;
568 return 0;
569 }
570
571 static int
572 gcscaudio_set_params(void *arg, int setmode, int usemode,
573 audio_params_t *play, audio_params_t *rec,
574 stream_filter_list_t *pfil, stream_filter_list_t *rfil)
575 {
576 struct gcscaudio_softc *sc;
577 int error;
578
579 sc = (struct gcscaudio_softc *)arg;
580
581 if (setmode & AUMODE_PLAY) {
582 if ((error = gcscaudio_set_params_ch(sc, &sc->sc_play,
583 AUMODE_PLAY, play, pfil)) != 0)
584 return error;
585 }
586 if (setmode & AUMODE_RECORD) {
587 if ((error = gcscaudio_set_params_ch(sc, &sc->sc_rec,
588 AUMODE_RECORD, rec, rfil)) != 0)
589 return error;
590 }
591
592 return 0;
593 }
594
595 static int
596 gcscaudio_round_blocksize(void *arg, int blk, int mode,
597 const audio_params_t *param)
598 {
599 blk &= -4;
600 if (blk > GCSCAUDIO_PRD_SIZE_MAX)
601 blk = GCSCAUDIO_PRD_SIZE_MAX;
602
603 return blk;
604 }
605
606 static int
607 gcscaudio_halt_output(void *arg)
608 {
609 struct gcscaudio_softc *sc;
610
611 sc = (struct gcscaudio_softc *)arg;
612 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM0_CMD,
613 ACC_BMx_CMD_BM_CTL_DISABLE);
614 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM4_CMD,
615 ACC_BMx_CMD_BM_CTL_DISABLE);
616 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM6_CMD,
617 ACC_BMx_CMD_BM_CTL_DISABLE);
618 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM7_CMD,
619 ACC_BMx_CMD_BM_CTL_DISABLE);
620 sc->sc_play.ch_intr = NULL;
621
622 /* channel splitter */
623 sc->sc_mch_splitter = NULL;
624 if (sc->sc_mch_split_buf)
625 gcscaudio_free(sc, sc->sc_mch_split_buf, sc->sc_mch_split_size);
626 sc->sc_mch_split_buf = NULL;
627
628 return 0;
629 }
630
631 static int
632 gcscaudio_halt_input(void *arg)
633 {
634 struct gcscaudio_softc *sc;
635
636 sc = (struct gcscaudio_softc *)arg;
637 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM1_CMD,
638 ACC_BMx_CMD_BM_CTL_DISABLE);
639 sc->sc_rec.ch_intr = NULL;
640 return 0;
641 }
642
643 static int
644 gcscaudio_getdev(void *addr, struct audio_device *retp)
645 {
646 *retp = gcscaudio_device;
647 return 0;
648 }
649
650 static int
651 gcscaudio_set_port(void *addr, mixer_ctrl_t *cp)
652 {
653 struct gcscaudio_softc *sc;
654
655 sc = addr;
656 return sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp);
657 }
658
659 static int
660 gcscaudio_get_port(void *addr, mixer_ctrl_t *cp)
661 {
662 struct gcscaudio_softc *sc;
663
664 sc = addr;
665 return sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp);
666 }
667
668 static int
669 gcscaudio_query_devinfo(void *addr, mixer_devinfo_t *dip)
670 {
671 struct gcscaudio_softc *sc;
672
673 sc = addr;
674 return sc->codec_if->vtbl->query_devinfo(sc->codec_if, dip);
675 }
676
677 static void *
678 gcscaudio_malloc(void *arg, int direction, size_t size)
679 {
680 struct gcscaudio_softc *sc;
681 struct gcscaudio_dma *p;
682 int error;
683
684 sc = (struct gcscaudio_softc *)arg;
685
686 p = kmem_alloc(sizeof(*p), KM_SLEEP);
687 p->size = size;
688
689 error = gcscaudio_allocate_dma(sc, size, &p->addr,
690 p->segs, sizeof(p->segs)/sizeof(p->segs[0]), &p->nseg, &p->map);
691 if (error) {
692 kmem_free(p, sizeof(*p));
693 return NULL;
694 }
695
696 LIST_INSERT_HEAD(&sc->sc_dmalist, p, list);
697 return p->addr;
698 }
699
700 static void
701 gcscaudio_free(void *arg, void *ptr, size_t size)
702 {
703 struct gcscaudio_softc *sc;
704 struct gcscaudio_dma *p;
705
706 sc = (struct gcscaudio_softc *)arg;
707
708 LIST_FOREACH(p, &sc->sc_dmalist, list) {
709 if (p->addr == ptr) {
710 bus_dmamap_unload(sc->sc_dmat, p->map);
711 bus_dmamap_destroy(sc->sc_dmat, p->map);
712 bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size);
713 bus_dmamem_free(sc->sc_dmat, p->segs, p->nseg);
714
715 LIST_REMOVE(p, list);
716 kmem_free(p, sizeof(*p));
717 break;
718 }
719 }
720 }
721
722 static paddr_t
723 gcscaudio_mappage(void *arg, void *mem, off_t off, int prot)
724 {
725 struct gcscaudio_softc *sc;
726 struct gcscaudio_dma *p;
727
728 if (off < 0)
729 return -1;
730
731 sc = (struct gcscaudio_softc *)arg;
732 LIST_FOREACH(p, &sc->sc_dmalist, list) {
733 if (p->addr == mem) {
734 return bus_dmamem_mmap(sc->sc_dmat, p->segs, p->nseg,
735 off, prot, BUS_DMA_WAITOK);
736 }
737 }
738
739 return -1;
740 }
741
742 static size_t
743 gcscaudio_round_buffersize(void *addr, int direction, size_t size)
744 {
745 if (size > GCSCAUDIO_BUFSIZE_MAX)
746 size = GCSCAUDIO_BUFSIZE_MAX;
747
748 return size;
749 }
750
751 static int
752 gcscaudio_get_props(void *addr)
753 {
754 struct gcscaudio_softc *sc;
755 int props;
756
757 sc = (struct gcscaudio_softc *)addr;
758 props = AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX;
759 /*
760 * Even if the codec is fixed-rate, set_param() succeeds for any sample
761 * rate because of aurateconv. Applications can't know what rate the
762 * device can process in the case of mmap().
763 */
764 if (!AC97_IS_FIXED_RATE(sc->codec_if))
765 props |= AUDIO_PROP_MMAP;
766 return props;
767 }
768
769 static int
770 build_prdtables(struct gcscaudio_softc *sc, int prdidx,
771 void *addr, size_t size, int blksize, int blklen, int blkoff)
772 {
773 struct gcscaudio_dma *p;
774 struct acc_prd *prdp;
775 bus_addr_t paddr;
776 int i;
777
778 /* get physical address of start */
779 paddr = (bus_addr_t)0;
780 LIST_FOREACH(p, &sc->sc_dmalist, list) {
781 if (p->addr == addr) {
782 paddr = p->map->dm_segs[0].ds_addr;
783 break;
784 }
785 }
786 if (!paddr) {
787 aprint_error_dev(sc->sc_dev, "bad addr %p\n", addr);
788 return EINVAL;
789 }
790
791 #define PRDADDR(prdidx,idx) \
792 (sc->sc_prd.p_prdmap->dm_segs[0].ds_addr) + sizeof(struct acc_prd) * \
793 (((prdidx) * GCSCAUDIO_NPRDTABLE) + (idx))
794
795 /*
796 * build PRD table
797 * prdtbl[] = <PRD0>, <PRD1>, <PRD2>, ..., <PRDn>, <jmp to PRD0>
798 */
799 prdp = sc->sc_prd.p_prdtables->prdtbl[prdidx];
800 for (i = 0; size > 0; size -= blksize, i++) {
801 prdp[i].address = paddr + blksize * i + blkoff;
802 prdp[i].ctrlsize =
803 (size < blklen ? size : blklen) | ACC_BMx_PRD_CTRL_EOP;
804 }
805 prdp[i].address = PRDADDR(prdidx, 0);
806 prdp[i].ctrlsize = ACC_BMx_PRD_CTRL_JMP;
807
808 bus_dmamap_sync(sc->sc_dmat, sc->sc_prd.p_prdmap, 0,
809 sizeof(struct acc_prd) * i, BUS_DMASYNC_PREWRITE);
810
811 return 0;
812 }
813
814 static void
815 split_buffer_4ch(void *dst, void *src, int size, int blksize)
816 {
817 int left, i;
818 uint16_t *s, *d;
819
820 /*
821 * src[blk0]: L,R,SL,SR,L,R,SL,SR,L,R,SL,SR,....
822 * src[blk1]: L,R,SL,SR,L,R,SL,SR,L,R,SL,SR,....
823 * src[blk2]: L,R,SL,SR,L,R,SL,SR,L,R,SL,SR,....
824 * :
825 *
826 * rearrange to
827 *
828 * src[blk0]: L,R,L,R,L,R,L,R,..
829 * src[blk1]: L,R,L,R,L,R,L,R,..
830 * src[blk2]: L,R,L,R,L,R,L,R,..
831 * :
832 * dst[blk0]: SL,SR,SL,SR,SL,SR,SL,SR,..
833 * dst[blk1]: SL,SR,SL,SR,SL,SR,SL,SR,..
834 * dst[blk2]: SL,SR,SL,SR,SL,SR,SL,SR,..
835 * :
836 */
837 for (left = size; left > 0; left -= blksize) {
838 s = (uint16_t *)src;
839 d = (uint16_t *)dst;
840 for (i = 0; i < blksize / sizeof(uint16_t) / 4; i++) {
841 /* L,R,SL,SR -> SL,SR */
842 s++;
843 s++;
844 *d++ = *s++;
845 *d++ = *s++;
846 }
847
848 s = (uint16_t *)src;
849 d = (uint16_t *)src;
850 for (i = 0; i < blksize / sizeof(uint16_t) / 2 / 2; i++) {
851 /* L,R,SL,SR -> L,R */
852 *d++ = *s++;
853 *d++ = *s++;
854 s++;
855 s++;
856 }
857
858 src = (char *)src + blksize;
859 dst = (char *)dst + blksize;
860 }
861 }
862
863 static void
864 split_buffer_6ch(void *dst, void *src, int size, int blksize)
865 {
866 int left, i;
867 uint16_t *s, *d, *dc, *dl;
868
869 /*
870 * by default, treat as WAV style 5.1ch order
871 * 5.1ch(WAV): L R C LFE SL SR
872 * 5.1ch(AAC): C L R SL SR LFE
873 * :
874 */
875
876 /*
877 * src[blk0]: L,R,C,LFE,SL,SR,L,R,C,LFE,SL,SR,...
878 * src[blk1]: L,R,C,LFE,SL,SR,L,R,C,LFE,SL,SR,...
879 * src[blk2]: L,R,C,LFE,SL,SR,L,R,C,LFE,SL,SR,...
880 * :
881 * src[N-1] : L,R,C,LFE,SL,SR,L,R,C,LFE,SL,SR,...
882 *
883 * rearrange to
884 *
885 * src[blk0]: L,R,L,R,..
886 * src[blk1]: L,R,L,R,..
887 * src[blk2]: L,R,L,R,..
888 * :
889 *
890 * dst[blk0]: SL,SR,SL,SR,..
891 * dst[blk1]: SL,SR,SL,SR,..
892 * dst[blk2]: SL,SR,SL,SR,..
893 * :
894 *
895 * dst[N/2+0]: C,C,C,..
896 * dst[N/2+1]: C,C,C,..
897 * :
898 *
899 * dst[N/2+N/4+0]: LFE,LFE,LFE,..
900 * dst[N/2+N/4+1]: LFE,LFE,LFE,..
901 * :
902 */
903
904 for (left = size; left > 0; left -= blksize) {
905 s = (uint16_t *)src;
906 d = (uint16_t *)dst;
907 dc = (uint16_t *)((char *)dst + blksize / 2);
908 dl = (uint16_t *)((char *)dst + blksize / 2 + blksize / 4);
909 for (i = 0; i < blksize / sizeof(uint16_t) / 6; i++) {
910 #ifdef GCSCAUDIO_5_1CH_AAC_ORDER
911 /*
912 * AAC: [C,L,R,SL,SR,LFE]
913 * => [SL,SR]
914 * => [C]
915 * => [LFE]
916 */
917 *dc++ = s[0]; /* C */
918 *dl++ = s[5]; /* LFE */
919 *d++ = s[3]; /* SL */
920 *d++ = s[4]; /* SR */
921 #else
922 /*
923 * WAV: [L,R,C,LFE,SL,SR]
924 * => [SL,SR]
925 * => [C]
926 * => [LFE]
927 */
928 *dc++ = s[2]; /* C */
929 *dl++ = s[3]; /* LFE */
930 *d++ = s[4]; /* SL */
931 *d++ = s[5]; /* SR */
932 #endif
933 s += 6;
934 }
935
936 s = (uint16_t *)src;
937 d = (uint16_t *)src;
938 for (i = 0; i < blksize / sizeof(uint16_t) / 2 / 2; i++) {
939 #ifdef GCSCAUDIO_5_1CH_AAC_ORDER
940 /* AAC: [C,L,R,SL,SR,LFE] => [L,R] */
941 *d++ = s[1];
942 *d++ = s[2];
943 #else
944 /* WAV: [L,R,C,LFE,SL,SR] => [L,R] */
945 *d++ = s[0];
946 *d++ = s[1];
947 #endif
948 s += 6;
949 }
950
951 src = (char *)src + blksize;
952 dst = (char *)dst + blksize;
953 }
954 }
955
956 static void
957 channel_splitter(struct gcscaudio_softc *sc)
958 {
959 int splitsize, left;
960 void *src, *dst;
961
962 if (sc->sc_mch_splitter == NULL)
963 return;
964
965 left = sc->sc_mch_split_size - sc->sc_mch_split_off;
966 splitsize = sc->sc_mch_split_blksize;
967 if (left < splitsize)
968 splitsize = left;
969
970 src = (char *)sc->sc_mch_split_start + sc->sc_mch_split_off;
971 dst = (char *)sc->sc_mch_split_buf + sc->sc_mch_split_off;
972
973 sc->sc_mch_splitter(dst, src, splitsize, sc->sc_mch_split_blksize);
974
975 sc->sc_mch_split_off += sc->sc_mch_split_blksize;
976 if (sc->sc_mch_split_off >= sc->sc_mch_split_size)
977 sc->sc_mch_split_off = 0;
978 }
979
980 static int
981 gcscaudio_trigger_output(void *addr, void *start, void *end, int blksize,
982 void (*intr)(void *), void *arg,
983 const audio_params_t *param)
984 {
985 struct gcscaudio_softc *sc;
986 size_t size;
987
988 sc = (struct gcscaudio_softc *)addr;
989 sc->sc_play.ch_intr = intr;
990 sc->sc_play.ch_intr_arg = arg;
991 size = (char *)end - (char *)start;
992
993 switch (sc->sc_play.ch_params.channels) {
994 case 2:
995 if (build_prdtables(sc, PRD_TABLE_FRONT, start, size, blksize,
996 blksize, 0))
997 return EINVAL;
998
999 if (!AC97_IS_4CH(sc->codec_if)) {
1000 /*
1001 * output 2ch PCM to FRONT.LR(BM0)
1002 *
1003 * 2ch: L,R,L,R,L,R,L,R,... => BM0: L,R,L,R,L,R,L,R,...
1004 *
1005 */
1006 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM0_PRD,
1007 PRDADDR(PRD_TABLE_FRONT, 0));
1008
1009 /* start DMA transfer */
1010 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM0_CMD,
1011 ACC_BMx_CMD_WRITE |
1012 ACC_BMx_CMD_BYTE_ORD_EL |
1013 ACC_BMx_CMD_BM_CTL_ENABLE);
1014 } else {
1015 /*
1016 * output same PCM to FRONT.LR(BM0) and SURROUND.LR(BM6).
1017 * CENTER(BM4) and LFE(BM7) doesn't sound.
1018 *
1019 * 2ch: L,R,L,R,L,R,L,R,... => BM0: L,R,L,R,L,R,L,R,...
1020 * BM6: (same of BM0)
1021 * BM4: none
1022 * BM7: none
1023 */
1024 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM0_PRD,
1025 PRDADDR(PRD_TABLE_FRONT, 0));
1026 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM6_PRD,
1027 PRDADDR(PRD_TABLE_FRONT, 0));
1028
1029 /* start DMA transfer */
1030 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM0_CMD,
1031 ACC_BMx_CMD_WRITE |
1032 ACC_BMx_CMD_BYTE_ORD_EL |
1033 ACC_BMx_CMD_BM_CTL_ENABLE);
1034 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM6_CMD,
1035 ACC_BMx_CMD_WRITE |
1036 ACC_BMx_CMD_BYTE_ORD_EL |
1037 ACC_BMx_CMD_BM_CTL_ENABLE);
1038 }
1039 break;
1040 case 4:
1041 /*
1042 * output 4ch PCM split to FRONT.LR(BM0) and SURROUND.LR(BM6).
1043 * CENTER(BM4) and LFE(BM7) doesn't sound.
1044 *
1045 * rearrange ordered channel to continuous per channel
1046 *
1047 * 4ch: L,R,SL,SR,L,R,SL,SR,... => BM0: L,R,L,R,...
1048 * BM6: SL,SR,SL,SR,...
1049 * BM4: none
1050 * BM7: none
1051 */
1052 if (sc->sc_mch_split_buf)
1053 gcscaudio_free(sc, sc->sc_mch_split_buf,
1054 sc->sc_mch_split_size);
1055
1056 if ((sc->sc_mch_split_buf = gcscaudio_malloc(sc, AUMODE_PLAY,
1057 size)) == NULL)
1058 return ENOMEM;
1059
1060 /*
1061 * 1st and 2nd blocks are split immediately.
1062 * Other blocks will be split synchronous with intr.
1063 */
1064 split_buffer_4ch(sc->sc_mch_split_buf, start, blksize * 2,
1065 blksize);
1066
1067 sc->sc_mch_split_start = start;
1068 sc->sc_mch_split_size = size;
1069 sc->sc_mch_split_blksize = blksize;
1070 sc->sc_mch_split_off = (blksize * 2) % size;
1071 sc->sc_mch_splitter = split_buffer_4ch; /* split function */
1072
1073 if (build_prdtables(sc, PRD_TABLE_FRONT, start, size, blksize,
1074 blksize / 2, 0))
1075 return EINVAL;
1076 if (build_prdtables(sc, PRD_TABLE_SURR, sc->sc_mch_split_buf,
1077 size, blksize, blksize / 2, 0))
1078 return EINVAL;
1079
1080 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM0_PRD,
1081 PRDADDR(PRD_TABLE_FRONT, 0));
1082 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM6_PRD,
1083 PRDADDR(PRD_TABLE_SURR, 0));
1084
1085 /* start DMA transfer */
1086 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM0_CMD,
1087 ACC_BMx_CMD_WRITE |
1088 ACC_BMx_CMD_BYTE_ORD_EL |
1089 ACC_BMx_CMD_BM_CTL_ENABLE);
1090 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM6_CMD,
1091 ACC_BMx_CMD_WRITE |
1092 ACC_BMx_CMD_BYTE_ORD_EL |
1093 ACC_BMx_CMD_BM_CTL_ENABLE);
1094 break;
1095 case 6:
1096 /*
1097 * output 6ch PCM split to
1098 * FRONT.LR(BM0), SURROUND.LR(BM6), CENTER(BM4) and LFE(BM7)
1099 *
1100 * rearrange ordered channel to continuous per channel
1101 *
1102 * 5.1ch: L,R,C,LFE,SL,SR,... => BM0: L,R,...
1103 * BM4: C,...
1104 * BM6: SL,SR,...
1105 * BM7: LFE,...
1106 *
1107 */
1108 if (sc->sc_mch_split_buf)
1109 gcscaudio_free(sc, sc->sc_mch_split_buf,
1110 sc->sc_mch_split_size);
1111
1112 if ((sc->sc_mch_split_buf = gcscaudio_malloc(sc, AUMODE_PLAY,
1113 size)) == NULL)
1114 return ENOMEM;
1115
1116 /*
1117 * 1st and 2nd blocks are split immediately.
1118 * Other block will be split synchronous with intr.
1119 */
1120 split_buffer_6ch(sc->sc_mch_split_buf, start, blksize * 2,
1121 blksize);
1122
1123 sc->sc_mch_split_start = start;
1124 sc->sc_mch_split_size = size;
1125 sc->sc_mch_split_blksize = blksize;
1126 sc->sc_mch_split_off = (blksize * 2) % size;
1127 sc->sc_mch_splitter = split_buffer_6ch; /* split function */
1128
1129 if (build_prdtables(sc, PRD_TABLE_FRONT, start, size, blksize,
1130 blksize / 3, 0))
1131 return EINVAL;
1132 if (build_prdtables(sc, PRD_TABLE_CENTER, sc->sc_mch_split_buf,
1133 size, blksize, blksize / 3, blksize / 2))
1134 return EINVAL;
1135 if (build_prdtables(sc, PRD_TABLE_SURR, sc->sc_mch_split_buf,
1136 size, blksize, blksize / 3, 0))
1137 return EINVAL;
1138 if (build_prdtables(sc, PRD_TABLE_LFE, sc->sc_mch_split_buf,
1139 size, blksize, blksize / 3, blksize / 2 + blksize / 4))
1140 return EINVAL;
1141
1142 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM0_PRD,
1143 PRDADDR(PRD_TABLE_FRONT, 0));
1144 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM4_PRD,
1145 PRDADDR(PRD_TABLE_CENTER, 0));
1146 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM6_PRD,
1147 PRDADDR(PRD_TABLE_SURR, 0));
1148 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM7_PRD,
1149 PRDADDR(PRD_TABLE_LFE, 0));
1150
1151 /* start DMA transfer */
1152 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM0_CMD,
1153 ACC_BMx_CMD_WRITE | ACC_BMx_CMD_BYTE_ORD_EL |
1154 ACC_BMx_CMD_BM_CTL_ENABLE);
1155 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM4_CMD,
1156 ACC_BMx_CMD_WRITE | ACC_BMx_CMD_BYTE_ORD_EL |
1157 ACC_BMx_CMD_BM_CTL_ENABLE);
1158 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM6_CMD,
1159 ACC_BMx_CMD_WRITE | ACC_BMx_CMD_BYTE_ORD_EL |
1160 ACC_BMx_CMD_BM_CTL_ENABLE);
1161 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM7_CMD,
1162 ACC_BMx_CMD_WRITE | ACC_BMx_CMD_BYTE_ORD_EL |
1163 ACC_BMx_CMD_BM_CTL_ENABLE);
1164 break;
1165 }
1166
1167 return 0;
1168 }
1169
1170 static int
1171 gcscaudio_trigger_input(void *addr, void *start, void *end, int blksize,
1172 void (*intr)(void *), void *arg,
1173 const audio_params_t *param)
1174 {
1175 struct gcscaudio_softc *sc;
1176 size_t size;
1177
1178 sc = (struct gcscaudio_softc *)addr;
1179 sc->sc_rec.ch_intr = intr;
1180 sc->sc_rec.ch_intr_arg = arg;
1181 size = (char *)end - (char *)start;
1182
1183 if (build_prdtables(sc, PRD_TABLE_REC, start, size, blksize, blksize, 0))
1184 return EINVAL;
1185
1186 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM1_PRD,
1187 PRDADDR(PRD_TABLE_REC, 0));
1188
1189 /* start transfer */
1190 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM1_CMD,
1191 ACC_BMx_CMD_READ |
1192 ACC_BMx_CMD_BYTE_ORD_EL |
1193 ACC_BMx_CMD_BM_CTL_ENABLE);
1194
1195 return 0;
1196 }
1197
1198 static void
1199 gcscaudio_get_locks(void *arg, kmutex_t **intr, kmutex_t **thread)
1200 {
1201 struct gcscaudio_softc *sc;
1202
1203 sc = (struct gcscaudio_softc *)arg;
1204
1205 *intr = &sc->sc_intr_lock;
1206 *thread = &sc->sc_lock;
1207 }
1208
1209 static int
1210 gcscaudio_intr(void *arg)
1211 {
1212 struct gcscaudio_softc *sc;
1213 uint16_t intr;
1214 uint8_t bmstat;
1215 int nintr;
1216
1217 nintr = 0;
1218 sc = (struct gcscaudio_softc *)arg;
1219
1220 mutex_spin_enter(&sc->sc_intr_lock);
1221
1222 intr = bus_space_read_2(sc->sc_iot, sc->sc_ioh, ACC_IRQ_STATUS);
1223 if (intr == 0)
1224 goto done;
1225
1226 /* Front output */
1227 if (intr & ACC_IRQ_STATUS_BM0_IRQ_STS) {
1228 bmstat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ACC_BM0_STATUS);
1229 if (bmstat & ACC_BMx_STATUS_BM_EOP_ERR)
1230 aprint_normal_dev(sc->sc_dev, "BM0: Bus Master Error\n");
1231 if (!(bmstat & ACC_BMx_STATUS_EOP))
1232 aprint_normal_dev(sc->sc_dev, "BM0: NO End of Page?\n");
1233
1234 if (sc->sc_play.ch_intr) {
1235 sc->sc_play.ch_intr(sc->sc_play.ch_intr_arg);
1236 channel_splitter(sc);
1237 }
1238 nintr++;
1239 }
1240
1241 /* Center output */
1242 if (intr & ACC_IRQ_STATUS_BM4_IRQ_STS) {
1243 bmstat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ACC_BM4_STATUS);
1244 if (bmstat & ACC_BMx_STATUS_BM_EOP_ERR)
1245 aprint_normal_dev(sc->sc_dev, "BM4: Bus Master Error\n");
1246 if (!(bmstat & ACC_BMx_STATUS_EOP))
1247 aprint_normal_dev(sc->sc_dev, "BM4: NO End of Page?\n");
1248
1249 nintr++;
1250 }
1251
1252 /* Surround output */
1253 if (intr & ACC_IRQ_STATUS_BM6_IRQ_STS) {
1254 bmstat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ACC_BM6_STATUS);
1255 if (bmstat & ACC_BMx_STATUS_BM_EOP_ERR)
1256 aprint_normal_dev(sc->sc_dev, "BM6: Bus Master Error\n");
1257 if (!(bmstat & ACC_BMx_STATUS_EOP))
1258 aprint_normal_dev(sc->sc_dev, "BM6: NO End of Page?\n");
1259
1260 nintr++;
1261 }
1262
1263 /* LowFrequencyEffect output */
1264 if (intr & ACC_IRQ_STATUS_BM7_IRQ_STS) {
1265 bmstat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ACC_BM7_STATUS);
1266 if (bmstat & ACC_BMx_STATUS_BM_EOP_ERR)
1267 aprint_normal_dev(sc->sc_dev, "BM7: Bus Master Error\n");
1268 if (!(bmstat & ACC_BMx_STATUS_EOP))
1269 aprint_normal_dev(sc->sc_dev, "BM7: NO End of Page?\n");
1270
1271 nintr++;
1272 }
1273
1274 /* record */
1275 if (intr & ACC_IRQ_STATUS_BM1_IRQ_STS) {
1276 bmstat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ACC_BM1_STATUS);
1277 if (bmstat & ACC_BMx_STATUS_BM_EOP_ERR)
1278 aprint_normal_dev(sc->sc_dev, "BM1: Bus Master Error\n");
1279 if (!(bmstat & ACC_BMx_STATUS_EOP))
1280 aprint_normal_dev(sc->sc_dev, "BM1: NO End of Page?\n");
1281
1282 if (sc->sc_rec.ch_intr) {
1283 sc->sc_rec.ch_intr(sc->sc_rec.ch_intr_arg);
1284 }
1285 nintr++;
1286 }
1287
1288 #ifdef GCSCAUDIO_DEBUG
1289 if (intr & ACC_IRQ_STATUS_IRQ_STS)
1290 aprint_normal_dev(sc->sc_dev, "Codec GPIO IRQ Status\n");
1291 if (intr & ACC_IRQ_STATUS_WU_IRQ_STS)
1292 aprint_normal_dev(sc->sc_dev, "Codec GPIO Wakeup IRQ Status\n");
1293 if (intr & ACC_IRQ_STATUS_BM2_IRQ_STS)
1294 aprint_normal_dev(sc->sc_dev, "Audio Bus Master 2 IRQ Status\n");
1295 if (intr & ACC_IRQ_STATUS_BM3_IRQ_STS)
1296 aprint_normal_dev(sc->sc_dev, "Audio Bus Master 3 IRQ Status\n");
1297 if (intr & ACC_IRQ_STATUS_BM5_IRQ_STS)
1298 aprint_normal_dev(sc->sc_dev, "Audio Bus Master 5 IRQ Status\n");
1299 #endif
1300
1301 done:
1302 mutex_spin_exit(&sc->sc_intr_lock);
1303
1304 return nintr ? 1 : 0;
1305 }
1306
1307 static bool
1308 gcscaudio_resume(device_t dv, const pmf_qual_t *qual)
1309 {
1310 struct gcscaudio_softc *sc = device_private(dv);
1311
1312 gcscaudio_reset_codec(sc);
1313 DELAY(1000);
1314 (sc->codec_if->vtbl->restore_ports)(sc->codec_if);
1315
1316 return true;
1317 }
1318
1319 static int
1320 gcscaudio_allocate_dma(struct gcscaudio_softc *sc, size_t size, void **addrp,
1321 bus_dma_segment_t *seglist, int nseg, int *rsegp,
1322 bus_dmamap_t *mapp)
1323 {
1324 int error;
1325
1326 if ((error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, seglist,
1327 nseg, rsegp, BUS_DMA_WAITOK)) != 0) {
1328 aprint_error_dev(sc->sc_dev,
1329 "unable to allocate DMA buffer, error=%d\n", error);
1330 goto fail_alloc;
1331 }
1332
1333 if ((error = bus_dmamem_map(sc->sc_dmat, seglist, nseg, size, addrp,
1334 BUS_DMA_WAITOK | BUS_DMA_COHERENT)) != 0) {
1335 aprint_error_dev(sc->sc_dev,
1336 "unable to map DMA buffer, error=%d\n",
1337 error);
1338 goto fail_map;
1339 }
1340
1341 if ((error = bus_dmamap_create(sc->sc_dmat, size, nseg, size, 0,
1342 BUS_DMA_WAITOK, mapp)) != 0) {
1343 aprint_error_dev(sc->sc_dev,
1344 "unable to create DMA map, error=%d\n", error);
1345 goto fail_create;
1346 }
1347
1348 if ((error = bus_dmamap_load(sc->sc_dmat, *mapp, *addrp, size, NULL,
1349 BUS_DMA_WAITOK)) != 0) {
1350 aprint_error_dev(sc->sc_dev,
1351 "unable to load DMA map, error=%d\n", error);
1352 goto fail_load;
1353 }
1354
1355 return 0;
1356
1357 fail_load:
1358 bus_dmamap_destroy(sc->sc_dmat, *mapp);
1359 fail_create:
1360 bus_dmamem_unmap(sc->sc_dmat, *addrp, size);
1361 fail_map:
1362 bus_dmamem_free(sc->sc_dmat, seglist, nseg);
1363 fail_alloc:
1364 return error;
1365 }
1366