From owner-svn-src-all@freebsd.org Wed Apr 17 21:45:20 2019 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 84473157AA74; Wed, 17 Apr 2019 21:45:20 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 26715953E7; Wed, 17 Apr 2019 21:45:20 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 14B29D446; Wed, 17 Apr 2019 21:45:20 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x3HLjJSt035505; Wed, 17 Apr 2019 21:45:19 GMT (envelope-from manu@FreeBSD.org) Received: (from manu@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x3HLjJ22035504; Wed, 17 Apr 2019 21:45:19 GMT (envelope-from manu@FreeBSD.org) Message-Id: <201904172145.x3HLjJ22035504@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: manu set sender to manu@FreeBSD.org using -f From: Emmanuel Vadot Date: Wed, 17 Apr 2019 21:45:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r346334 - head/sys/arm/allwinner X-SVN-Group: head X-SVN-Commit-Author: manu X-SVN-Commit-Paths: head/sys/arm/allwinner X-SVN-Commit-Revision: 346334 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 26715953E7 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.96 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.96)[-0.964,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-1.000,0] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Apr 2019 21:45:20 -0000 Author: manu Date: Wed Apr 17 21:45:19 2019 New Revision: 346334 URL: https://svnweb.freebsd.org/changeset/base/346334 Log: arm: allwinner: Fix audio for Allwinner H3/H5 Due to three conditions the codec driver for Allwinner A10/A20 and H3/H5 did not work properly here: Wrong bit position for the analog audio reset Hardware Reset of codec was not de-asserted correctly Linux DTS file did not contain the address of the analog register the way as the driver was expecting it. This patch proposes fixes for those three parts. Submitted by: freebsdnewbie@freenet.de (Manuel Stühn) MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D19910 Modified: head/sys/arm/allwinner/a10_codec.c Modified: head/sys/arm/allwinner/a10_codec.c ============================================================================== --- head/sys/arm/allwinner/a10_codec.c Wed Apr 17 20:16:48 2019 (r346333) +++ head/sys/arm/allwinner/a10_codec.c Wed Apr 17 21:45:19 2019 (r346334) @@ -164,7 +164,7 @@ struct a10codec_chinfo { struct a10codec_info { device_t dev; - struct resource *res[3]; + struct resource *res[2]; struct mtx *lock; bus_dma_tag_t dmat; unsigned dmasize; @@ -178,11 +178,12 @@ struct a10codec_info { static struct resource_spec a10codec_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { SYS_RES_MEMORY, 1, RF_ACTIVE | RF_OPTIONAL }, - { SYS_RES_IRQ, 0, RF_ACTIVE }, { -1, 0 } }; +#define CODEC_ANALOG_READ(sc, reg) bus_read_4((sc)->res[1], (reg)) +#define CODEC_ANALOG_WRITE(sc, reg, val) bus_write_4((sc)->res[1], (reg), (val)) + #define CODEC_READ(sc, reg) bus_read_4((sc)->res[0], (reg)) #define CODEC_WRITE(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val)) @@ -372,7 +373,7 @@ MIXER_DECLARE(a10_mixer); */ #define H3_PR_CFG 0x00 -#define H3_AC_PR_RST (1 << 18) +#define H3_AC_PR_RST (1 << 28) #define H3_AC_PR_RW (1 << 24) #define H3_AC_PR_ADDR_SHIFT 16 #define H3_AC_PR_ADDR_MASK (0x1f << H3_AC_PR_ADDR_SHIFT) @@ -424,23 +425,23 @@ h3_pr_read(struct a10codec_info *sc, u_int addr) uint32_t val; /* Read current value */ - val = bus_read_4(sc->res[1], H3_PR_CFG); + val = CODEC_ANALOG_READ(sc, H3_PR_CFG); /* De-assert reset */ val |= H3_AC_PR_RST; - bus_write_4(sc->res[1], H3_PR_CFG, val); + CODEC_ANALOG_WRITE(sc, H3_PR_CFG, val); /* Read mode */ val &= ~H3_AC_PR_RW; - bus_write_4(sc->res[1], H3_PR_CFG, val); + CODEC_ANALOG_WRITE(sc, H3_PR_CFG, val); /* Set address */ val &= ~H3_AC_PR_ADDR_MASK; val |= (addr << H3_AC_PR_ADDR_SHIFT); - bus_write_4(sc->res[1], H3_PR_CFG, val); + CODEC_ANALOG_WRITE(sc, H3_PR_CFG, val); /* Read data */ - return (bus_read_4(sc->res[1], H3_PR_CFG) & H3_ACDA_PR_RDAT_MASK); + return (CODEC_ANALOG_READ(sc , H3_PR_CFG) & H3_ACDA_PR_RDAT_MASK); } static void @@ -449,25 +450,25 @@ h3_pr_write(struct a10codec_info *sc, u_int addr, u_in uint32_t val; /* Read current value */ - val = bus_read_4(sc->res[1], H3_PR_CFG); + val = CODEC_ANALOG_READ(sc, H3_PR_CFG); /* De-assert reset */ val |= H3_AC_PR_RST; - bus_write_4(sc->res[1], H3_PR_CFG, val); + CODEC_ANALOG_WRITE(sc, H3_PR_CFG, val); /* Set address */ val &= ~H3_AC_PR_ADDR_MASK; val |= (addr << H3_AC_PR_ADDR_SHIFT); - bus_write_4(sc->res[1], H3_PR_CFG, val); + CODEC_ANALOG_WRITE(sc, H3_PR_CFG, val); /* Write data */ val &= ~H3_ACDA_PR_WDAT_MASK; val |= (data << H3_ACDA_PR_WDAT_SHIFT); - bus_write_4(sc->res[1], H3_PR_CFG, val); + CODEC_ANALOG_WRITE(sc, H3_PR_CFG, val); /* Write mode */ val |= H3_AC_PR_RW; - bus_write_4(sc->res[1], H3_PR_CFG, val); + CODEC_ANALOG_WRITE(sc, H3_PR_CFG, val); } static void @@ -483,8 +484,28 @@ h3_pr_set_clear(struct a10codec_info *sc, u_int addr, static int h3_mixer_init(struct snd_mixer *m) { + int rid=1; + pcell_t reg[2]; + phandle_t analogref; struct a10codec_info *sc = mix_getdevinfo(m); + if (OF_getencprop(ofw_bus_get_node(sc->dev), "allwinner,codec-analog-controls", + &analogref, sizeof(analogref)) <= 0) { + return (ENXIO); + } + + if (OF_getencprop(OF_node_from_xref(analogref), "reg", + reg, sizeof(reg)) <= 0) { + return (ENXIO); + } + + sc->res[1] = bus_alloc_resource(sc->dev, SYS_RES_MEMORY, &rid, reg[0], + reg[0]+reg[1], reg[1], RF_ACTIVE ); + + if (sc->res[1] == NULL) { + return (ENXIO); + } + mix_setdevs(m, SOUND_MASK_PCM | SOUND_MASK_VOLUME | SOUND_MASK_RECLEV | SOUND_MASK_MIC | SOUND_MASK_LINE | SOUND_MASK_LINE1); mix_setrecdevs(m, SOUND_MASK_MIC | SOUND_MASK_LINE | SOUND_MASK_LINE1 | @@ -940,6 +961,7 @@ a10codec_chan_trigger(kobj_t obj, void *data, int go) switch (go) { case PCMTRIG_START: ch->run = 1; + a10codec_stop(ch); a10codec_start(ch); break; case PCMTRIG_STOP: @@ -1124,8 +1146,7 @@ a10codec_attach(device_t dev) } /* De-assert hwreset */ - if (hwreset_get_by_ofw_name(dev, 0, "apb", &rst) == 0 || - hwreset_get_by_ofw_name(dev, 0, "ahb", &rst) == 0) { + if (hwreset_get_by_ofw_idx(dev, 0, 0, &rst) == 0) { error = hwreset_deassert(rst); if (error != 0) { device_printf(dev, "cannot de-assert reset\n"); @@ -1137,15 +1158,6 @@ a10codec_attach(device_t dev) val = CODEC_READ(sc, AC_DAC_DPC(sc)); val |= DAC_DPC_EN_DA; CODEC_WRITE(sc, AC_DAC_DPC(sc), val); - -#ifdef notdef - error = snd_setup_intr(dev, sc->irq, INTR_MPSAFE, a10codec_intr, sc, - &sc->ih); - if (error != 0) { - device_printf(dev, "could not setup interrupt handler\n"); - goto fail; - } -#endif if (mixer_init(dev, sc->cfg->mixer_class, sc)) { device_printf(dev, "mixer_init failed\n");