Lines Matching +full:pcm +full:- +full:clock +full:- +full:mode
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2012-2016 Ruslan Bukin <br@bsdpad.com>
5 * Copyright (c) 2023-2024 Florian Walpen <dev@submerge.ch>
38 #include <dev/sound/pcm/sound.h>
52 &hdspe_unified_pcm, 0, "Combine physical ports in one unified pcm device");
122 snd_mtxlock(sc->lock);
126 if ((err = device_get_children(sc->dev, &devlist, &devcount)) != 0)
131 if (scp->ih != NULL)
132 scp->ih(scp);
139 snd_mtxunlock(sc->lock);
146 device_printf(sc->dev, "hdspe_dmapsetmap()\n");
155 sc->csid = PCIR_BAR(0);
156 sc->cs = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY,
157 &sc->csid, RF_ACTIVE);
159 if (!sc->cs) {
160 device_printf(sc->dev, "Unable to map SYS_RES_MEMORY.\n");
164 sc->cst = rman_get_bustag(sc->cs);
165 sc->csh = rman_get_bushandle(sc->cs);
168 sc->irqid = 0;
169 sc->irq = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, &sc->irqid,
172 if (!sc->irq ||
173 bus_setup_intr(sc->dev, sc->irq, INTR_MPSAFE | INTR_TYPE_AV,
174 NULL, hdspe_intr, sc, &sc->ih)) {
175 device_printf(sc->dev, "Unable to alloc interrupt resource.\n");
180 if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(sc->dev),
193 /*dmatag*/&sc->dmat) != 0) {
194 device_printf(sc->dev, "Unable to create dma tag.\n");
198 sc->bufsize = HDSPE_DMASEGSIZE;
201 if (bus_dmamem_alloc(sc->dmat, (void **)&sc->pbuf, BUS_DMA_WAITOK,
202 &sc->pmap)) {
203 device_printf(sc->dev, "Can't alloc pbuf.\n");
207 if (bus_dmamap_load(sc->dmat, sc->pmap, sc->pbuf, sc->bufsize,
209 device_printf(sc->dev, "Can't load pbuf.\n");
214 if (bus_dmamem_alloc(sc->dmat, (void **)&sc->rbuf, BUS_DMA_WAITOK,
215 &sc->rmap)) {
216 device_printf(sc->dev, "Can't alloc rbuf.\n");
220 if (bus_dmamap_load(sc->dmat, sc->rmap, sc->rbuf, sc->bufsize,
222 device_printf(sc->dev, "Can't load rbuf.\n");
226 bzero(sc->pbuf, sc->bufsize);
227 bzero(sc->rbuf, sc->bufsize);
238 paddr = vtophys(sc->pbuf);
239 raddr = vtophys(sc->rbuf);
258 return ("-10dBV");
273 sc = oidp->oid_arg1;
276 if (sc->type != HDSPE_AIO)
280 settings = sc->settings_register & HDSPE_INPUT_LEVEL_MASK;
287 if (error != 0 || req->newptr == NULL)
303 if (settings != (sc->settings_register & HDSPE_INPUT_LEVEL_MASK)) {
304 snd_mtxlock(sc->lock);
305 sc->settings_register &= ~HDSPE_INPUT_LEVEL_MASK;
306 sc->settings_register |= settings;
307 hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register);
308 snd_mtxunlock(sc->lock);
322 return ("-10dBV");
337 sc = oidp->oid_arg1;
340 if (sc->type != HDSPE_AIO)
344 settings = sc->settings_register & HDSPE_OUTPUT_LEVEL_MASK;
351 if (error != 0 || req->newptr == NULL)
367 if (settings != (sc->settings_register & HDSPE_OUTPUT_LEVEL_MASK)) {
368 snd_mtxlock(sc->lock);
369 sc->settings_register &= ~HDSPE_OUTPUT_LEVEL_MASK;
370 sc->settings_register |= settings;
371 hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register);
372 snd_mtxunlock(sc->lock);
386 return ("-10dBV");
401 sc = oidp->oid_arg1;
404 if (sc->type != HDSPE_AIO)
408 settings = sc->settings_register & HDSPE_PHONES_LEVEL_MASK;
415 if (error != 0 || req->newptr == NULL)
431 if (settings != (sc->settings_register & HDSPE_PHONES_LEVEL_MASK)) {
432 snd_mtxlock(sc->lock);
433 sc->settings_register &= ~HDSPE_PHONES_LEVEL_MASK;
434 sc->settings_register |= settings;
435 hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register);
436 snd_mtxunlock(sc->lock);
444 struct sc_info *sc = oidp->oid_arg1;
448 speed = sc->force_speed;
452 if (error != 0 || req->newptr == NULL)
455 /* Speed from 32000 to 192000, 0 falls back to pcm speed setting. */
456 sc->force_speed = 0;
465 sc->force_speed = 32000 * multiplier;
467 sc->force_speed = 44100 * multiplier;
469 sc->force_speed = 48000 * multiplier;
479 struct sc_info *sc = oidp->oid_arg1;
483 period = sc->force_period;
487 if (error != 0 || req->newptr == NULL)
490 /* Period is from 2^5 to 2^14, 0 falls back to pcm latency settings. */
491 sc->force_period = 0;
493 sc->force_period = 32;
494 while (sc->force_period < period && sc->force_period < 4096)
495 sc->force_period <<= 1;
505 struct hdspe_clock_source *clock_table, *clock;
510 sc = oidp->oid_arg1;
513 if (sc->type == HDSPE_AIO)
515 else if (sc->type == HDSPE_RAYDAT)
520 /* Extract preferred clock source from settings register. */
521 setting = sc->settings_register & HDSPE_SETTING_CLOCK_MASK;
522 for (clock = clock_table; clock->name != NULL; ++clock) {
523 if (clock->setting == setting)
526 if (clock->name != NULL)
527 strlcpy(buf, clock->name, sizeof(buf));
531 if (error != 0 || req->newptr == NULL)
534 /* Find clock source matching the sysctl string. */
535 for (clock = clock_table; clock->name != NULL; ++clock) {
536 if (strncasecmp(buf, clock->name, sizeof(buf)) == 0)
540 /* Set preferred clock source in settings register. */
541 if (clock->name != NULL) {
542 setting = clock->setting & HDSPE_SETTING_CLOCK_MASK;
543 snd_mtxlock(sc->lock);
544 sc->settings_register &= ~HDSPE_SETTING_CLOCK_MASK;
545 sc->settings_register |= setting;
546 hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register);
547 snd_mtxunlock(sc->lock);
556 struct hdspe_clock_source *clock_table, *clock;
560 sc = oidp->oid_arg1;
563 if (sc->type == HDSPE_AIO)
565 else if (sc->type == HDSPE_RAYDAT)
570 /* Read current (autosync) clock source from status register. */
571 snd_mtxlock(sc->lock);
574 snd_mtxunlock(sc->lock);
576 /* Translate status register value to clock source. */
577 for (clock = clock_table; clock->name != NULL; ++clock) {
578 /* In clock master mode, override with internal clock source. */
579 if (sc->settings_register & HDSPE_SETTING_MASTER) {
580 if (clock->setting & HDSPE_SETTING_MASTER)
582 } else if (clock->status == status)
587 if (clock->name != NULL)
588 strlcpy(buf, clock->name, sizeof(buf));
596 struct hdspe_clock_source *clock_table, *clock;
600 sc = oidp->oid_arg1;
603 /* Select clock source table for device type. */
604 if (sc->type == HDSPE_AIO)
606 else if (sc->type == HDSPE_RAYDAT)
611 /* List available clock sources. */
613 for (clock = clock_table; clock->name != NULL; ++clock) {
615 n += strlcpy(buf + n, ",", sizeof(buf) - n);
616 n += strlcpy(buf + n, clock->name, sizeof(buf) - n);
625 struct hdspe_clock_source *clock_table, *clock;
631 sc = oidp->oid_arg1;
635 if (sc->type == HDSPE_AIO)
637 else if (sc->type == HDSPE_RAYDAT)
643 snd_mtxlock(sc->lock);
645 snd_mtxunlock(sc->lock);
647 /* List clock sources with lock and sync state. */
648 for (clock = clock_table; clock->name != NULL; ++clock) {
649 if (clock->sync_bit != 0) {
651 n += strlcpy(buf + n, ",", sizeof(buf) - n);
653 if ((clock->sync_bit & status) != 0)
655 else if ((clock->lock_bit & status) != 0)
657 n += snprintf(buf + n, sizeof(buf) - n, "%s(%s)",
658 clock->name, state);
692 sc->period = 32;
694 * The pcm channel latency settings propagate unreliable blocksizes,
699 sc->force_period = 256;
700 sc->ctrl_register = hdspe_encode_latency(7);
703 sc->speed = HDSPE_SPEED_DEFAULT;
704 sc->force_speed = 0;
705 sc->ctrl_register &= ~HDSPE_FREQ_MASK;
706 sc->ctrl_register |= HDSPE_FREQ_MASK_DEFAULT;
707 hdspe_write_4(sc, HDSPE_CONTROL_REG, sc->ctrl_register);
709 switch (sc->type) {
719 period /= sc->speed;
723 sc->settings_register = 0;
726 sc->settings_register &= ~HDSPE_INPUT_LEVEL_MASK;
727 sc->settings_register |= HDSPE_INPUT_LEVEL_LOWGAIN;
728 sc->settings_register &= ~HDSPE_OUTPUT_LEVEL_MASK;
729 sc->settings_register |= HDSPE_OUTPUT_LEVEL_MINUS10DBV;
730 sc->settings_register &= ~HDSPE_PHONES_LEVEL_MASK;
731 sc->settings_register |= HDSPE_PHONES_LEVEL_MINUS10DBV;
733 hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register);
752 sc->lock = snd_mtxcreate(device_get_nameunit(dev),
754 sc->dev = dev;
760 sc->type = HDSPE_AIO;
764 sc->type = HDSPE_RAYDAT;
783 scp->hc = &chan_map[i];
784 scp->sc = sc;
785 scp->dev = device_add_child(dev, "pcm", DEVICE_UNIT_ANY);
786 device_set_ivars(scp->dev, scp);
795 "List clock source signal lock and sync status");
801 "Currently effective clock source");
807 "Set 'internal' (master) or preferred autosync clock source");
813 "List of supported clock sources");
827 if (sc->type == HDSPE_AIO) {
832 "Phones output level ('HighGain', '+4dBU', '-10dBV')");
838 "Analog output level ('HighGain', '+4dBU', '-10dBV')");
844 "Analog input level ('LowGain', '+4dBU', '-10dBV')");
861 bus_dmamap_unload(sc->dmat, sc->rmap);
862 bus_dmamap_unload(sc->dmat, sc->pmap);
863 bus_dmamem_free(sc->dmat, sc->rbuf, sc->rmap);
864 bus_dmamem_free(sc->dmat, sc->pbuf, sc->pmap);
865 sc->rbuf = sc->pbuf = NULL;
886 if (sc->ih)
887 bus_teardown_intr(dev, sc->irq, sc->ih);
888 if (sc->dmat)
889 bus_dma_tag_destroy(sc->dmat);
890 if (sc->irq)
891 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
892 if (sc->cs)
893 bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->cs);
894 if (sc->lock)
895 snd_mtxfree(sc->lock);