Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm/allwinner/a10_codec.c
Show First 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#include <dev/sound/pcm/sound.h> | #include <dev/sound/pcm/sound.h> | ||||
#include <dev/sound/chip.h> | #include <dev/sound/chip.h> | ||||
#include <dev/ofw/ofw_bus.h> | #include <dev/ofw/ofw_bus.h> | ||||
#include <dev/ofw/ofw_bus_subr.h> | #include <dev/ofw/ofw_bus_subr.h> | ||||
#include <arm/allwinner/a10_clk.h> | #include <dev/extres/clk/clk.h> | ||||
#include "sunxi_dma_if.h" | #include "sunxi_dma_if.h" | ||||
#include "mixer_if.h" | #include "mixer_if.h" | ||||
#include "gpio_if.h" | #include "gpio_if.h" | ||||
#define TX_TRIG_LEVEL 0xf | #define TX_TRIG_LEVEL 0xf | ||||
#define RX_TRIG_LEVEL 0x7 | #define RX_TRIG_LEVEL 0x7 | ||||
#define DRQ_CLR_CNT 0x3 | #define DRQ_CLR_CNT 0x3 | ||||
▲ Show 20 Lines • Show All 671 Lines • ▼ Show 20 Lines | a10codec_probe(device_t dev) | ||||
return (BUS_PROBE_DEFAULT); | return (BUS_PROBE_DEFAULT); | ||||
} | } | ||||
static int | static int | ||||
a10codec_attach(device_t dev) | a10codec_attach(device_t dev) | ||||
{ | { | ||||
struct a10codec_info *sc; | struct a10codec_info *sc; | ||||
char status[SND_STATUSLEN]; | char status[SND_STATUSLEN]; | ||||
clk_t clk_apb, clk_codec; | |||||
uint32_t val; | uint32_t val; | ||||
int error; | int error; | ||||
sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); | sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); | ||||
sc->dev = dev; | sc->dev = dev; | ||||
sc->lock = snd_mtxcreate(device_get_nameunit(dev), "a10codec softc"); | sc->lock = snd_mtxcreate(device_get_nameunit(dev), "a10codec softc"); | ||||
if (bus_alloc_resources(dev, a10codec_spec, sc->res)) { | if (bus_alloc_resources(dev, a10codec_spec, sc->res)) { | ||||
Show All 24 Lines | error = bus_dma_tag_create( | ||||
sc->dmasize, 0, /* maxsegsize, flags */ | sc->dmasize, 0, /* maxsegsize, flags */ | ||||
NULL, NULL, /* lockfunc, lockarg */ | NULL, NULL, /* lockfunc, lockarg */ | ||||
&sc->dmat); | &sc->dmat); | ||||
if (error != 0) { | if (error != 0) { | ||||
device_printf(dev, "cannot create DMA tag\n"); | device_printf(dev, "cannot create DMA tag\n"); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
/* Get clocks */ | |||||
error = clk_get_by_ofw_name(dev, "apb", &clk_apb); | |||||
if (error != 0) { | |||||
device_printf(dev, "cannot find apb clock\n"); | |||||
goto fail; | |||||
} | |||||
error = clk_get_by_ofw_name(dev, "codec", &clk_codec); | |||||
if (error != 0) { | |||||
device_printf(dev, "cannot find codec clock\n"); | |||||
goto fail; | |||||
} | |||||
/* Gating APB clock for codec */ | |||||
error = clk_enable(clk_apb); | |||||
if (error != 0) { | |||||
device_printf(dev, "cannot enable apb clock\n"); | |||||
goto fail; | |||||
} | |||||
/* Activate audio codec clock. According to the A10 and A20 user | /* Activate audio codec clock. According to the A10 and A20 user | ||||
* manuals, Audio_pll can be either 24.576MHz or 22.5792MHz. Most | * manuals, Audio_pll can be either 24.576MHz or 22.5792MHz. Most | ||||
* audio sampling rates require an 24.576MHz input clock with the | * audio sampling rates require an 24.576MHz input clock with the | ||||
* exception of 44.1kHz, 22.05kHz, and 11.025kHz. Unfortunately, | * exception of 44.1kHz, 22.05kHz, and 11.025kHz. Unfortunately, | ||||
* both capture and playback use the same clock source so to | * both capture and playback use the same clock source so to | ||||
* safely support independent full duplex operation, we use a fixed | * safely support independent full duplex operation, we use a fixed | ||||
* 24.576MHz clock source and don't advertise native support for | * 24.576MHz clock source and don't advertise native support for | ||||
* the three sampling rates that require a 22.5792MHz input. | * the three sampling rates that require a 22.5792MHz input. | ||||
*/ | */ | ||||
a10_clk_codec_activate(24576000); | error = clk_set_freq(clk_codec, 24576000, CLK_SET_ROUND_DOWN); | ||||
if (error != 0) { | |||||
device_printf(dev, "cannot set codec clock frequency\n"); | |||||
goto fail; | |||||
} | |||||
/* Enable audio codec clock */ | |||||
error = clk_enable(clk_codec); | |||||
if (error != 0) { | |||||
device_printf(dev, "cannot enable codec clock\n"); | |||||
goto fail; | |||||
} | |||||
/* Enable DAC */ | /* Enable DAC */ | ||||
val = CODEC_READ(sc, AC_DAC_DPC); | val = CODEC_READ(sc, AC_DAC_DPC); | ||||
val |= DAC_DPC_EN_DA; | val |= DAC_DPC_EN_DA; | ||||
CODEC_WRITE(sc, AC_DAC_DPC, val); | CODEC_WRITE(sc, AC_DAC_DPC, val); | ||||
#ifdef notdef | #ifdef notdef | ||||
error = snd_setup_intr(dev, sc->irq, INTR_MPSAFE, a10codec_intr, sc, | error = snd_setup_intr(dev, sc->irq, INTR_MPSAFE, a10codec_intr, sc, | ||||
▲ Show 20 Lines • Show All 52 Lines • Show Last 20 Lines |