From patchwork Wed Nov 9 17:14:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Fitzgerald X-Patchwork-Id: 9420215 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A182B601C0 for ; Wed, 9 Nov 2016 22:09:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 899B429424 for ; Wed, 9 Nov 2016 22:09:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7C62829427; Wed, 9 Nov 2016 22:09:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9604729424 for ; Wed, 9 Nov 2016 22:09:29 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 15E4D26657F; Wed, 9 Nov 2016 23:09:28 +0100 (CET) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 2049E26664E; Wed, 9 Nov 2016 23:07:09 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 435E2267135; Wed, 9 Nov 2016 18:14:25 +0100 (CET) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) by alsa0.perex.cz (Postfix) with ESMTP id BAD9E2670FC for ; Wed, 9 Nov 2016 18:14:22 +0100 (CET) Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id uA9HEKd7016457; Wed, 9 Nov 2016 11:14:21 -0600 Authentication-Results: ppops.net; spf=none smtp.mailfrom=rf@opensource.wolfsonmicro.com Received: from mail2.cirrus.com (mail1.cirrus.com [141.131.3.20]) by mx0a-001ae601.pphosted.com with ESMTP id 26hcu0gq55-1; Wed, 09 Nov 2016 11:14:21 -0600 Received: from EX17.ad.cirrus.com (unknown [172.20.9.81]) by mail2.cirrus.com (Postfix) with ESMTP id 9C559611C8B2; Wed, 9 Nov 2016 11:14:20 -0600 (CST) Received: from imbe.wolfsonmicro.main (198.61.95.81) by EX17.ad.cirrus.com (172.20.9.81) with Microsoft SMTP Server id 14.3.301.0; Wed, 9 Nov 2016 17:14:19 +0000 Received: from rf-debian.wolfsonmicro.main ([172.22.20.124]) by imbe.wolfsonmicro.main (8.14.4/8.14.4) with ESMTP id uA9HDvVe005569; Wed, 9 Nov 2016 17:13:58 GMT From: Richard Fitzgerald To: Date: Wed, 9 Nov 2016 17:14:18 +0000 Message-ID: <1478711658-23696-5-git-send-email-rf@opensource.wolfsonmicro.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1478711658-23696-1-git-send-email-rf@opensource.wolfsonmicro.com> References: <1478711658-23696-1-git-send-email-rf@opensource.wolfsonmicro.com> MIME-Version: 1.0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1609300000 definitions=main-1611090318 Cc: alsa-devel@alsa-project.org, patches@opensource.wolfsonmicro.com, linux-kernel@vger.kernel.org Subject: [alsa-devel] [PATCH 5/5] ASoC: wm_adsp: Support acknowledged controls X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP This patch handles publishing acknowledged controls through ALSA. These controls allow user-side to send events to the firmware and wait for the firmware to acknowledge it. Note that although acked controls only operate in the direction host->firmware, and therefore they are write-only as seen from user- side code, we have to make them readable to account for all the code out there that assumes that ALSA controls are always readable (amixer for example.) Signed-off-by: Richard Fitzgerald --- sound/soc/codecs/wm_adsp.c | 89 +++++++++++++++++++++++++++++++++++++++++----- sound/soc/codecs/wmfw.h | 1 + 2 files changed, 82 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index bdbcc44..4fb6e2f 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -164,6 +164,8 @@ #define WM_ADSP_ACKED_CTL_TIMEOUT_MS 100 #define WM_ADSP_ACKED_CTL_N_QUICKPOLLS 10 +#define WM_ADSP_ACKED_CTL_MIN_VALUE 0 +#define WM_ADSP_ACKED_CTL_MAX_VALUE 0xFFFFFF /* * Event control messages @@ -779,8 +781,20 @@ static int wm_coeff_info(struct snd_kcontrol *kctl, (struct soc_bytes_ext *)kctl->private_value; struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); - uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; - uinfo->count = ctl->len; + switch (ctl->type) { + case WMFW_CTL_TYPE_ACKED: + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->value.integer.min = WM_ADSP_ACKED_CTL_MIN_VALUE; + uinfo->value.integer.max = WM_ADSP_ACKED_CTL_MAX_VALUE; + uinfo->value.integer.step = 1; + uinfo->count = 1; + break; + default: + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = ctl->len; + break; + } + return 0; } @@ -920,6 +934,30 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl, return ret; } +static int wm_coeff_put_acked(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_bytes_ext *bytes_ext = + (struct soc_bytes_ext *)kctl->private_value; + struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); + unsigned int val = ucontrol->value.integer.value[0]; + int ret; + + if (val == 0) + return 0; /* 0 means no event */ + + mutex_lock(&ctl->dsp->pwr_lock); + + if (ctl->enabled) + ret = wm_coeff_write_acked_control(ctl, val); + else + ret = -EPERM; + + mutex_unlock(&ctl->dsp->pwr_lock); + + return ret; +} + static int wm_coeff_read_control(struct wm_coeff_ctl *ctl, void *buf, size_t len) { @@ -1007,6 +1045,21 @@ static int wm_coeff_tlv_get(struct snd_kcontrol *kctl, return ret; } +static int wm_coeff_get_acked(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* + * Although it's not useful to read an acked control, we must satisfy + * user-side assumptions that all controls are readable and that a + * write of the same value should be filtered out (it's valid to send + * the same event number again to the firmware). We therefore return 0, + * meaning "no event" so valid event numbers will always be a change + */ + ucontrol->value.integer.value[0] = 0; + + return 0; +} + struct wmfw_ctl_work { struct wm_adsp *dsp; struct wm_coeff_ctl *ctl; @@ -1059,17 +1112,25 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) kcontrol->name = ctl->name; kcontrol->info = wm_coeff_info; - kcontrol->get = wm_coeff_get; - kcontrol->put = wm_coeff_put; kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER; kcontrol->tlv.c = snd_soc_bytes_tlv_callback; kcontrol->private_value = (unsigned long)&ctl->bytes_ext; + kcontrol->access = wmfw_convert_flags(ctl->flags, ctl->len); - ctl->bytes_ext.max = ctl->len; - ctl->bytes_ext.get = wm_coeff_tlv_get; - ctl->bytes_ext.put = wm_coeff_tlv_put; + switch (ctl->type) { + case WMFW_CTL_TYPE_ACKED: + kcontrol->get = wm_coeff_get_acked; + kcontrol->put = wm_coeff_put_acked; + break; + default: + kcontrol->get = wm_coeff_get; + kcontrol->put = wm_coeff_put; - kcontrol->access = wmfw_convert_flags(ctl->flags, ctl->len); + ctl->bytes_ext.max = ctl->len; + ctl->bytes_ext.get = wm_coeff_tlv_get; + ctl->bytes_ext.put = wm_coeff_tlv_put; + break; + } ret = snd_soc_add_card_controls(dsp->card, kcontrol, 1); if (ret < 0) @@ -1431,6 +1492,18 @@ static int wm_adsp_parse_coeff(struct wm_adsp *dsp, switch (coeff_blk.ctl_type) { case SNDRV_CTL_ELEM_TYPE_BYTES: break; + case WMFW_CTL_TYPE_ACKED: + if (coeff_blk.flags & WMFW_CTL_FLAG_SYS) + continue; /* ignore */ + + ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk, + WMFW_CTL_FLAG_VOLATILE | + WMFW_CTL_FLAG_WRITEABLE | + WMFW_CTL_FLAG_READABLE, + 0); + if (ret) + return -EINVAL; + break; case WMFW_CTL_TYPE_HOSTEVENT: ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk, WMFW_CTL_FLAG_SYS | diff --git a/sound/soc/codecs/wmfw.h b/sound/soc/codecs/wmfw.h index 892fc74..ec78b9d 100644 --- a/sound/soc/codecs/wmfw.h +++ b/sound/soc/codecs/wmfw.h @@ -27,6 +27,7 @@ #define WMFW_CTL_FLAG_READABLE 0x0001 /* Non-ALSA coefficient types start at 0x1000 */ +#define WMFW_CTL_TYPE_ACKED 0x1000 /* acked control */ #define WMFW_CTL_TYPE_HOSTEVENT 0x1001 /* event control */ struct wmfw_header {