Lines Matching +full:pcm +full:- +full:clock +full:- +full:mode

1 /*-
2 * Copyright (c) 2014-2016 Jared D. McNeill <jmcneill@invisible.ca>
42 #include <dev/sound/pcm/sound.h>
84 #define AC_DAC_DPC(_sc) ((_sc)->cfg->DPC)
86 #define AC_DAC_FIFOC(_sc) ((_sc)->cfg->DAC_FIFOC)
110 #define AC_DAC_FIFOS(_sc) ((_sc)->cfg->DAC_FIFOS)
111 #define AC_DAC_TXDATA(_sc) ((_sc)->cfg->DAC_TXDATA)
112 #define AC_ADC_FIFOC(_sc) ((_sc)->cfg->ADC_FIFOC)
124 #define AC_ADC_FIFOS(_sc) ((_sc)->cfg->ADC_FIFOS)
125 #define AC_ADC_RXDATA(_sc) ((_sc)->cfg->ADC_RXDATA)
126 #define AC_DAC_CNT(_sc) ((_sc)->cfg->DAC_CNT)
127 #define AC_ADC_CNT(_sc) ((_sc)->cfg->ADC_CNT)
175 { -1, 0 }
178 #define CODEC_ANALOG_READ(sc, reg) bus_read_4((sc)->res[1], (reg))
179 #define CODEC_ANALOG_WRITE(sc, reg, val) bus_write_4((sc)->res[1], (reg), (val))
181 #define CODEC_READ(sc, reg) bus_read_4((sc)->res[0], (reg))
182 #define CODEC_WRITE(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val))
284 case SOUND_MASK_LINE: /* line-in */ in a10_mixer_setrecsrc()
423 /* De-assert reset */ in h3_pr_read()
427 /* Read mode */ in h3_pr_read()
448 /* De-assert reset */ in h3_pr_write()
462 /* Write mode */ in h3_pr_write()
485 if (OF_getencprop(ofw_bus_get_node(sc->dev), "allwinner,codec-analog-controls", in h3_mixer_init()
495 sc->res[1] = bus_alloc_resource(sc->dev, SYS_RES_MEMORY, &rid, reg[0], in h3_mixer_init()
498 if (sc->res[1] == NULL) { in h3_mixer_init()
507 pcm_setflags(sc->dev, pcm_getflags(sc->dev) | SD_F_SOFTPCMVOL); in h3_mixer_init()
561 if ((src & SOUND_MASK_LINE) != 0) /* line-in */ in h3_mixer_setrecsrc()
628 ch->physaddr = segs[0].ds_addr; in a10codec_dmamap_cb()
637 if (ch->dir == PCMDIR_PLAY) { in a10codec_transfer()
638 src = ch->physaddr + ch->pos; in a10codec_transfer()
639 dst = ch->fifo; in a10codec_transfer()
641 src = ch->fifo; in a10codec_transfer()
642 dst = ch->physaddr + ch->pos; in a10codec_transfer()
645 error = SUNXI_DMA_TRANSFER(ch->dmac, ch->dmachan, src, dst, in a10codec_transfer()
646 ch->blocksize); in a10codec_transfer()
648 ch->run = 0; in a10codec_transfer()
649 device_printf(ch->parent->dev, "DMA transfer failed: %d\n", in a10codec_transfer()
657 struct a10codec_info *sc = ch->parent; in a10codec_dmaconfig()
664 if (ch->dir == PCMDIR_PLAY) { in a10codec_dmaconfig()
666 conf.src_drqtype = sc->cfg->drqtype_sdram; in a10codec_dmaconfig()
667 conf.dst_drqtype = sc->cfg->drqtype_codec; in a10codec_dmaconfig()
670 conf.src_drqtype = sc->cfg->drqtype_codec; in a10codec_dmaconfig()
671 conf.dst_drqtype = sc->cfg->drqtype_sdram; in a10codec_dmaconfig()
674 SUNXI_DMA_SET_CONFIG(ch->dmac, ch->dmachan, &conf); in a10codec_dmaconfig()
683 bufsize = sndbuf_getsize(ch->buffer); in a10codec_dmaintr()
685 ch->pos += ch->blocksize; in a10codec_dmaintr()
686 if (ch->pos >= bufsize) in a10codec_dmaintr()
687 ch->pos -= bufsize; in a10codec_dmaintr()
689 if (ch->run) { in a10codec_dmaintr()
690 chn_intr(ch->channel); in a10codec_dmaintr()
698 switch (ch->speed) { in a10codec_fs()
723 struct a10codec_info *sc = ch->parent; in a10codec_start()
726 ch->pos = 0; in a10codec_start()
728 if (ch->dir == PCMDIR_PLAY) { in a10codec_start()
737 sc->cfg->mute(sc, 0, ch->dir); in a10codec_start()
744 (AFMT_CHANNEL(ch->format) == 1 ? DAC_FIFOC_MONO_EN : 0) | in a10codec_start()
763 sc->cfg->mute(sc, 0, ch->dir); in a10codec_start()
772 (AFMT_CHANNEL(ch->format) == 1 ? ADC_FIFOC_MONO_EN : 0) | in a10codec_start()
789 struct a10codec_info *sc = ch->parent; in a10codec_stop()
792 SUNXI_DMA_HALT(ch->dmac, ch->dmachan); in a10codec_stop()
794 sc->cfg->mute(sc, 1, ch->dir); in a10codec_stop()
796 if (ch->dir == PCMDIR_PLAY) { in a10codec_stop()
810 struct a10codec_chinfo *ch = dir == PCMDIR_PLAY ? &sc->play : &sc->rec; in a10codec_chan_init()
815 error = ofw_bus_parse_xref_list_alloc(ofw_bus_get_node(sc->dev), in a10codec_chan_init()
816 "dmas", "#dma-cells", dir == PCMDIR_PLAY ? 1 : 0, in a10codec_chan_init()
819 device_printf(sc->dev, "cannot parse 'dmas' property\n"); in a10codec_chan_init()
824 ch->parent = sc; in a10codec_chan_init()
825 ch->channel = c; in a10codec_chan_init()
826 ch->buffer = b; in a10codec_chan_init()
827 ch->dir = dir; in a10codec_chan_init()
828 ch->fifo = rman_get_start(sc->res[0]) + in a10codec_chan_init()
831 ch->dmac = OF_device_from_xref(xref); in a10codec_chan_init()
832 if (ch->dmac == NULL) { in a10codec_chan_init()
833 device_printf(sc->dev, "cannot find DMA controller\n"); in a10codec_chan_init()
834 device_printf(sc->dev, "xref = 0x%x\n", (u_int)xref); in a10codec_chan_init()
837 ch->dmachan = SUNXI_DMA_ALLOC(ch->dmac, false, a10codec_dmaintr, ch); in a10codec_chan_init()
838 if (ch->dmachan == NULL) { in a10codec_chan_init()
839 device_printf(sc->dev, "cannot allocate DMA channel\n"); in a10codec_chan_init()
843 error = bus_dmamem_alloc(sc->dmat, &ch->dmaaddr, in a10codec_chan_init()
844 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &ch->dmamap); in a10codec_chan_init()
846 device_printf(sc->dev, "cannot allocate channel buffer\n"); in a10codec_chan_init()
849 error = bus_dmamap_load(sc->dmat, ch->dmamap, ch->dmaaddr, in a10codec_chan_init()
850 sc->dmasize, a10codec_dmamap_cb, ch, BUS_DMA_NOWAIT); in a10codec_chan_init()
852 device_printf(sc->dev, "cannot load DMA map\n"); in a10codec_chan_init()
855 memset(ch->dmaaddr, 0, sc->dmasize); in a10codec_chan_init()
857 if (sndbuf_setup(ch->buffer, ch->dmaaddr, sc->dmasize) != 0) { in a10codec_chan_init()
858 device_printf(sc->dev, "cannot setup sndbuf\n"); in a10codec_chan_init()
869 struct a10codec_info *sc = ch->parent; in a10codec_chan_free()
871 SUNXI_DMA_FREE(ch->dmac, ch->dmachan); in a10codec_chan_free()
872 bus_dmamap_unload(sc->dmat, ch->dmamap); in a10codec_chan_free()
873 bus_dmamem_free(sc->dmat, ch->dmaaddr, ch->dmamap); in a10codec_chan_free()
883 ch->format = format; in a10codec_chan_setformat()
895 * use the same source clock (PLL2). Limit the available speeds to in a10codec_chan_setspeed()
905 ch->speed = speed; in a10codec_chan_setspeed()
909 /* 96 KHz / 192 KHz mode only supported for playback */ in a10codec_chan_setspeed()
910 if (ch->dir == PCMDIR_PLAY) { in a10codec_chan_setspeed()
911 ch->speed = speed; in a10codec_chan_setspeed()
913 ch->speed = 48000; in a10codec_chan_setspeed()
917 ch->speed = 48000; in a10codec_chan_setspeed()
920 ch->speed = 24000; in a10codec_chan_setspeed()
923 ch->speed = 12000; in a10codec_chan_setspeed()
926 ch->speed = 48000; in a10codec_chan_setspeed()
930 return (ch->speed); in a10codec_chan_setspeed()
938 ch->blocksize = blocksize & ~3; in a10codec_chan_setblocksize()
940 return (ch->blocksize); in a10codec_chan_setblocksize()
947 struct a10codec_info *sc = ch->parent; in a10codec_chan_trigger()
952 snd_mtxlock(sc->lock); in a10codec_chan_trigger()
955 ch->run = 1; in a10codec_chan_trigger()
961 ch->run = 0; in a10codec_chan_trigger()
967 snd_mtxunlock(sc->lock); in a10codec_chan_trigger()
977 return (ch->pos); in a10codec_chan_getptr()
985 if (ch->dir == PCMDIR_PLAY) { in a10codec_chan_getcaps()
1042 { "allwinner,sun4i-a10-codec", (uintptr_t)&a10_config },
1043 { "allwinner,sun7i-a20-codec", (uintptr_t)&a10_config },
1044 { "allwinner,sun8i-h3-codec", (uintptr_t)&h3_config },
1054 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) in a10codec_probe()
1076 sc->cfg = (void *)ofw_bus_search_compatible(dev, compat_data)->ocd_data; in a10codec_attach()
1077 sc->dev = dev; in a10codec_attach()
1078 sc->lock = snd_mtxcreate(device_get_nameunit(dev), "a10codec softc"); in a10codec_attach()
1080 if (bus_alloc_resources(dev, a10codec_spec, sc->res)) { in a10codec_attach()
1086 sc->dmasize = 131072; in a10codec_attach()
1089 4, sc->dmasize, /* alignment, boundary */ in a10codec_attach()
1093 sc->dmasize, 1, /* maxsize, nsegs */ in a10codec_attach()
1094 sc->dmasize, 0, /* maxsegsize, flags */ in a10codec_attach()
1096 &sc->dmat); in a10codec_attach()
1105 device_printf(dev, "cannot find bus clock\n"); in a10codec_attach()
1109 device_printf(dev, "cannot find codec clock\n"); in a10codec_attach()
1113 /* Gating bus clock for codec */ in a10codec_attach()
1115 device_printf(dev, "cannot enable bus clock\n"); in a10codec_attach()
1118 /* Activate audio codec clock. According to the A10 and A20 user in a10codec_attach()
1120 * audio sampling rates require an 24.576MHz input clock with the in a10codec_attach()
1122 * both capture and playback use the same clock source so to in a10codec_attach()
1124 * 24.576MHz clock source and don't advertise native support for in a10codec_attach()
1129 device_printf(dev, "cannot set codec clock frequency\n"); in a10codec_attach()
1132 /* Enable audio codec clock */ in a10codec_attach()
1135 device_printf(dev, "cannot enable codec clock\n"); in a10codec_attach()
1139 /* De-assert hwreset */ in a10codec_attach()
1143 device_printf(dev, "cannot de-assert reset\n"); in a10codec_attach()
1153 if (mixer_init(dev, sc->cfg->mixer_class, sc)) { in a10codec_attach()
1159 if (gpio_pin_get_by_ofw_property(dev, node, "allwinner,pa-gpios", in a10codec_attach()
1182 bus_release_resources(dev, a10codec_spec, sc->res); in a10codec_attach()
1183 snd_mtxfree(sc->lock); in a10codec_attach()
1198 "pcm",