From patchwork Fri Jul 27 02:37:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Katsuhiro Suzuki X-Patchwork-Id: 143006 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp280984ljj; Thu, 26 Jul 2018 19:37:40 -0700 (PDT) X-Google-Smtp-Source: AAOMgpcKcKtMIHJjbvDdA9l/l/mhpWTjjtrJV4+woPzKKmMiSvJh/bIOGb6j3r5aBjMTMSsFyocD X-Received: by 2002:a17:902:b40c:: with SMTP id x12-v6mr4282109plr.163.1532659060180; Thu, 26 Jul 2018 19:37:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532659060; cv=none; d=google.com; s=arc-20160816; b=GT11VS3cYP3I/Ew3NHMC/iVdfm4xzj8yT5Djj9i9uHfZF1k7UvCd0QPhZPHSmXexjA ZoCZtp3owJ0F0XpxE+cXYoQHkonFOHHC0MGPA3T+TNQBCXFYv8+V8N0pTwm817OEEOEw /vaZkCMtt05/Rzs4DmZVecUtTKr28r3dgMUMIoLncTYMAftA5QftOlcMOlMVlZ9LDq2H b2CK/FngXFR5cZ+Od4hU85bOvt8aSs0BovJWl1nT+vtNwagM9HiY93jMLEBEWdRT994P Yig1g4fcA4UXuTKXGRGUDK5SHeM5N0XNcNHPg27pvFsMg77ieJbEAwPacN1xcMCWQYqu Eh4w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :arc-authentication-results; bh=mLEaiVtw3U4UV8Xtl3/bZwI5WQzeiGJkIOXPnaWV6+U=; b=U8EcfDFLF7KujVvCICwbO4d17CoMNjXoUdCLj91Jpm4cjSSgj+Ymf8FAVC8nuqn92B dK8PC2QQQ0ZGOKb8ENtmvYwZ0NKUzy5oKNj5gQtmG5cCwTxCy76RoihIyfJEUcHdRTra t7I80vc9ZR4oIdE7lNQ8k7Uo0zIePTZHAfcUlBWTmgj2iA8c5YLDeCTqYDLBtzhVutUj yyITR/G9/EqY+LNGpVxIA2BGe1H3nkYDm5TbJGp+6wu95UB8PWaLQoaDFfDSDveMZ32d iRwieEnP9f4o1eC+MaR6r+qM/YLpMvshFkPrDUcTmirWkID5u5u4l79DvHRmFW5uCsY6 UN0g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n38-v6si2828735pgb.536.2018.07.26.19.37.39; Thu, 26 Jul 2018 19:37:40 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732085AbeG0D5N (ORCPT + 31 others); Thu, 26 Jul 2018 23:57:13 -0400 Received: from mx.socionext.com ([202.248.49.38]:23194 "EHLO mx.socionext.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731974AbeG0D5M (ORCPT ); Thu, 26 Jul 2018 23:57:12 -0400 Received: from unknown (HELO iyokan-ex.css.socionext.com) ([172.31.9.54]) by mx.socionext.com with ESMTP; 27 Jul 2018 11:37:35 +0900 Received: from mail.mfilter.local (m-filter-1 [10.213.24.61]) by iyokan-ex.css.socionext.com (Postfix) with ESMTP id 4641560034; Fri, 27 Jul 2018 11:37:35 +0900 (JST) Received: from 172.31.9.53 (172.31.9.53) by m-FILTER with ESMTP; Fri, 27 Jul 2018 11:37:35 +0900 Received: from yuzu.css.socionext.com (yuzu [172.31.8.45]) by iyokan.css.socionext.com (Postfix) with ESMTP id 1354740176; Fri, 27 Jul 2018 11:37:35 +0900 (JST) Received: from aegis.e01.socionext.com (unknown [10.213.134.210]) by yuzu.css.socionext.com (Postfix) with ESMTP id E1B36120448; Fri, 27 Jul 2018 11:37:34 +0900 (JST) From: Katsuhiro Suzuki To: Mark Brown , alsa-devel@alsa-project.org Cc: Masami Hiramatsu , Jassi Brar , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Katsuhiro Suzuki Subject: [PATCH] ASoC: uniphier: add support for multichannel output Date: Fri, 27 Jul 2018 11:37:28 +0900 Message-Id: <20180727023728.7810-1-suzuki.katsuhiro@socionext.com> X-Mailer: git-send-email 2.18.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds multichannel PCM output support for LD11/LD20. Currently driver tested and supported only 2ch, 6ch, and 8ch. Signed-off-by: Katsuhiro Suzuki --- sound/soc/uniphier/aio-core.c | 78 ++++++++++++++++++++++++++++++++--- sound/soc/uniphier/aio-ld11.c | 2 +- sound/soc/uniphier/aio-reg.h | 1 + sound/soc/uniphier/aio.h | 3 ++ 4 files changed, 78 insertions(+), 6 deletions(-) -- 2.18.0 diff --git a/sound/soc/uniphier/aio-core.c b/sound/soc/uniphier/aio-core.c index 638cb3fc5f7b..8b09bbb0f8d0 100644 --- a/sound/soc/uniphier/aio-core.c +++ b/sound/soc/uniphier/aio-core.c @@ -264,6 +264,57 @@ void aio_port_reset(struct uniphier_aio_sub *sub) } } +/** + * aio_port_set_ch - set channels of LPCM + * @sub: the AIO substream pointer, PCM substream only + * @ch : count of channels + * + * Set suitable slot selecting to input/output port block of AIO. + * + * This function may return error if non-PCM substream. + * + * Return: Zero if successful, otherwise a negative value on error. + */ +static int aio_port_set_ch(struct uniphier_aio_sub *sub) +{ + struct regmap *r = sub->aio->chip->regmap; + u32 slotsel_2ch[] = { + 0, 0, 0, 0, 0, + }; + u32 slotsel_multi[] = { + OPORTMXTYSLOTCTR_SLOTSEL_SLOT0, + OPORTMXTYSLOTCTR_SLOTSEL_SLOT1, + OPORTMXTYSLOTCTR_SLOTSEL_SLOT2, + OPORTMXTYSLOTCTR_SLOTSEL_SLOT3, + OPORTMXTYSLOTCTR_SLOTSEL_SLOT4, + }; + u32 mode, *slotsel; + int i; + + switch (params_channels(&sub->params)) { + case 8: + case 6: + mode = OPORTMXTYSLOTCTR_MODE; + slotsel = slotsel_multi; + break; + case 2: + mode = 0; + slotsel = slotsel_2ch; + break; + default: + return -EINVAL; + } + + for (i = 0; i < AUD_MAX_SLOTSEL; i++) { + regmap_update_bits(r, OPORTMXTYSLOTCTR(sub->swm->oport.map, i), + OPORTMXTYSLOTCTR_MODE, mode); + regmap_update_bits(r, OPORTMXTYSLOTCTR(sub->swm->oport.map, i), + OPORTMXTYSLOTCTR_SLOTSEL_MASK, slotsel[i]); + } + + return 0; +} + /** * aio_port_set_rate - set sampling rate of LPCM * @sub: the AIO substream pointer, PCM substream only @@ -575,6 +626,10 @@ int aio_port_set_param(struct uniphier_aio_sub *sub, int pass_through, rate = params_rate(params); } + ret = aio_port_set_ch(sub); + if (ret) + return ret; + ret = aio_port_set_rate(sub, rate); if (ret) return ret; @@ -731,15 +786,28 @@ void aio_port_set_volume(struct uniphier_aio_sub *sub, int vol) int aio_if_set_param(struct uniphier_aio_sub *sub, int pass_through) { struct regmap *r = sub->aio->chip->regmap; - u32 v; + u32 memfmt, v; if (sub->swm->dir == PORT_DIR_OUTPUT) { - if (pass_through) + if (pass_through) { v = PBOUTMXCTR0_ENDIAN_0123 | PBOUTMXCTR0_MEMFMT_STREAM; - else - v = PBOUTMXCTR0_ENDIAN_3210 | - PBOUTMXCTR0_MEMFMT_2CH; + } else { + switch (params_channels(&sub->params)) { + case 2: + memfmt = PBOUTMXCTR0_MEMFMT_2CH; + break; + case 6: + memfmt = PBOUTMXCTR0_MEMFMT_6CH; + break; + case 8: + memfmt = PBOUTMXCTR0_MEMFMT_8CH; + break; + default: + return -EINVAL; + } + v = PBOUTMXCTR0_ENDIAN_3210 | memfmt; + } regmap_write(r, PBOUTMXCTR0(sub->swm->oif.map), v); regmap_write(r, PBOUTMXCTR1(sub->swm->oif.map), 0); diff --git a/sound/soc/uniphier/aio-ld11.c b/sound/soc/uniphier/aio-ld11.c index ab04d3331be9..de962df245ba 100644 --- a/sound/soc/uniphier/aio-ld11.c +++ b/sound/soc/uniphier/aio-ld11.c @@ -286,7 +286,7 @@ static struct snd_soc_dai_driver uniphier_aio_dai_ld11[] = { .formats = SNDRV_PCM_FMTBIT_S32_LE, .rates = SNDRV_PCM_RATE_48000, .channels_min = 2, - .channels_max = 2, + .channels_max = 8, }, .ops = &uniphier_aio_i2s_ops, }, diff --git a/sound/soc/uniphier/aio-reg.h b/sound/soc/uniphier/aio-reg.h index 45fdc6ae358a..734395dbcffb 100644 --- a/sound/soc/uniphier/aio-reg.h +++ b/sound/soc/uniphier/aio-reg.h @@ -374,6 +374,7 @@ #define OPORTMXTYVOLGAINSTATUS(n, m) (0x42108 + 0x400 * (n) + 0x20 * (m)) #define OPORTMXTYVOLGAINSTATUS_CUR_MASK GENMASK(15, 0) #define OPORTMXTYSLOTCTR(n, m) (0x42114 + 0x400 * (n) + 0x20 * (m)) +#define OPORTMXTYSLOTCTR_MODE BIT(15) #define OPORTMXTYSLOTCTR_SLOTSEL_MASK GENMASK(11, 8) #define OPORTMXTYSLOTCTR_SLOTSEL_SLOT0 (0x8 << 8) #define OPORTMXTYSLOTCTR_SLOTSEL_SLOT1 (0x9 << 8) diff --git a/sound/soc/uniphier/aio.h b/sound/soc/uniphier/aio.h index aa89c2f6fa24..23a5c3c68658 100644 --- a/sound/soc/uniphier/aio.h +++ b/sound/soc/uniphier/aio.h @@ -141,6 +141,9 @@ enum IEC61937_PC { #define AUD_MIN_FRAGMENT_SIZE (4 * 1024) #define AUD_MAX_FRAGMENT_SIZE (16 * 1024) +/* max 5 slots, 10 channels, 2 channel in 1 slot */ +#define AUD_MAX_SLOTSEL 5 + /* * This is a selector for virtual register map of AIO. *