Received: by 2002:a05:6520:4d:b0:139:a872:a4c9 with SMTP id i13csp108943lkm; Wed, 8 Sep 2021 16:02:18 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxiKzjCcGZjFVemPdnNUZM3XqK3WmU6LSfxyYbHPtlg6RRiD0j0cTc+mvpMv9GQnplYJ8kG X-Received: by 2002:a05:6402:1352:: with SMTP id y18mr707301edw.122.1631142137981; Wed, 08 Sep 2021 16:02:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631142137; cv=none; d=google.com; s=arc-20160816; b=SgHaCHr2w+Y9hX1iTClILxZ0KIY97+bWm/tpiOYmXlIwtJ22ThWqi0tZUl3u9VlG04 S4zxOHWpAp954/A+4Ra+D4y2jJDRw4izA3PtXdBGLECybpOMweD9D6aMPEXMoKJiW4Yk xe0wkEhlzW0eZWgLAkacMOyZhRioxvKQhnUi+jbg1wTQbN6BiNM2ah61cFEh54vnVxCg qE+fpkXQcS7tjTsTA5v/TzSX8rta2yRe69ZtEm7Umlpa8KIxVxH8ADEfL+/kgWbcUsz6 UnUj+MPhM70lJ8x7ReFUiCuRafEQirdEMJhSwhuWwb64Uhlgjbh6QwQXmaVb8KNJeAWi pKyA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:to:subject:message-id:date:user-agent:from :references:in-reply-to:mime-version:dkim-signature; bh=VqW5+bekt6QQoJuxceGB6Gpgo1qlpGgrwjlTJ2fvXwI=; b=fkbN5vucu1HeBXWPRnKc8M1AtMM0PI6UdT7zGMdqiqKxgR6ULO/o1+NQ3D3Xe2ns0q dZVnR21QeA1Q4AOXCx6H1yaLRSKO/r7tBRE/2CYmPWAhJ2tCg9aYR3AkiVYCHoAkuP1/ osV2hzv2YQxFS/REaXQwYlkbcKB75jaJNbShnMb1K4YKDHe9o9Ren5/fG9FDG8pqF6K3 KykIrWRIoHrXCOlpLtdpyS+nWdoaLa+eVjEjF8FfslZ1WPdcVmf5VCQX6WaL/YXSFNOe q2p/h5CKjB+4bT8YA9tKgqWqKLQdxhH+evxXCcavqG3OhazoClhR/zkDYK8b7fRh6p2T zJdg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=Hqc3NBf8; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id nc27si419459ejc.640.2021.09.08.16.01.53; Wed, 08 Sep 2021 16:02:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=Hqc3NBf8; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240269AbhIHWoA (ORCPT + 99 others); Wed, 8 Sep 2021 18:44:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59058 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344767AbhIHWn7 (ORCPT ); Wed, 8 Sep 2021 18:43:59 -0400 Received: from mail-oi1-x22e.google.com (mail-oi1-x22e.google.com [IPv6:2607:f8b0:4864:20::22e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 32CE5C06175F for ; Wed, 8 Sep 2021 15:42:51 -0700 (PDT) Received: by mail-oi1-x22e.google.com with SMTP id 6so2445oiy.8 for ; Wed, 08 Sep 2021 15:42:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:in-reply-to:references:from:user-agent:date:message-id :subject:to; bh=VqW5+bekt6QQoJuxceGB6Gpgo1qlpGgrwjlTJ2fvXwI=; b=Hqc3NBf8JTg7GipE1wzXwn/flNwn+MY+VUUhGnKThL3LCKzu4VSfdnz2yAhquXyZbL fbXUWc9mnrAWY4bWGcj424gvueEJhW1/FkTORFr9yjK0zj9i86hTh3GouPwxVCoCmZPk +GIMaN5NsD32W27XGzxpYN1vBdSVe+jpmcrZY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:in-reply-to:references:from :user-agent:date:message-id:subject:to; bh=VqW5+bekt6QQoJuxceGB6Gpgo1qlpGgrwjlTJ2fvXwI=; b=bCLV1wzkobXoz04WVzvaY1JgTukQhjc1EHd5i3bmQXZttaqESoILBUtrtNXu1F5+Gz VeJceBOjnpgvf7JPO18FqHNwAUJnpKqUFMl8XwKEAFR+0TA4jXYORp7ncONEsQSUVDXP 4WiQZ9ws8WVXaEI/5JnNW8b1SZgh2yFVHa8Yw+vl9Ge+9g5nPpnfcJe3w8sydqP/t/ro YBqct6GBlNjWGt6cZ8ic2F5A5ii/2gSjk2Ya6HnRk6G5SK/T87TepzXRorHzsMg4ULyo 2RyRsmCjClyxht+HU4+KzRF+cddwTgO6sDTmgohY2wEaN8OtEf3QXXYi8a7Pqeh/E7H2 j0bg== X-Gm-Message-State: AOAM533Kw8o8yuo6gz7mTEjmhrzNUcDW5V+A4xCkn5owRXFaqqTkvmAW xTNrHrR8dtKJiJnZnEXxR7DZSrES10xT/0+zzay/TQ== X-Received: by 2002:aca:2310:: with SMTP id e16mr319666oie.64.1631140970485; Wed, 08 Sep 2021 15:42:50 -0700 (PDT) Received: from 753933720722 named unknown by gmailapi.google.com with HTTPREST; Wed, 8 Sep 2021 15:42:50 -0700 MIME-Version: 1.0 In-Reply-To: <1631124057-17155-3-git-send-email-srivasam@codeaurora.org> References: <1631124057-17155-1-git-send-email-srivasam@codeaurora.org> <1631124057-17155-3-git-send-email-srivasam@codeaurora.org> From: Stephen Boyd User-Agent: alot/0.9.1 Date: Wed, 8 Sep 2021 15:42:50 -0700 Message-ID: Subject: Re: [PATCH 2/2] ASoC: qcom: SC7280: Add machine driver To: Srinivasa Rao Mandadapu , agross@kernel.org, alsa-devel@alsa-project.org, bgoswami@codeaurora.org, bjorn.andersson@linaro.org, broonie@kernel.org, devicetree@vger.kernel.org, judyhsiao@chromium.org, lgirdwood@gmail.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, perex@perex.cz, plai@codeaurora.org, robh+dt@kernel.org, rohitkr@codeaurora.org, srinivas.kandagatla@linaro.org, tiwai@suse.com Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Quoting Srinivasa Rao Mandadapu (2021-09-08 11:00:57) > diff --git a/sound/soc/qcom/sc7280.c b/sound/soc/qcom/sc7280.c > new file mode 100644 > index 0000000..1ab29f6 > --- /dev/null > +++ b/sound/soc/qcom/sc7280.c > @@ -0,0 +1,347 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +// > +// Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. > +// > +// sc7280.c -- ALSA SoC Machine driver for sc7280 > + > +#include > +#include Can these come after the linux/sound includes? > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include Is this include used? > + > +#include "../codecs/wcd938x.h" > +#include "common.h" > +#include "lpass.h" > + > +#define DRIVER_NAME "SC7280" Is this useful? Why not just inline it in the one place it is used so we don't have to jump to the define to figure out what it is? > +#define LPASS_MAX_PORTS (LPASS_CDC_DMA_VA_TX8 + 1) > + > + > +struct sc7280_snd_data { > + bool stream_prepared[LPASS_MAX_PORTS]; > + struct snd_soc_card card; > + struct sdw_stream_runtime *sruntime[LPASS_MAX_PORTS]; > + struct snd_soc_jack hs_jack; > + struct snd_soc_jack hdmi_jack; > + bool jack_setup; > +}; > + > +static void sc7280_jack_free(struct snd_jack *jack) > +{ > + struct snd_soc_component *component = jack->private_data; > + > + snd_soc_component_set_jack(component, NULL, NULL); > +} > + > +static int sc7280_headset_init(struct snd_soc_pcm_runtime *rtd) > +{ > + struct snd_soc_card *card = rtd->card; > + struct sc7280_snd_data *pdata = snd_soc_card_get_drvdata(card); > + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); > + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); > + struct snd_soc_component *component = codec_dai->component; > + struct snd_jack *jack; > + int rval, i; > + > + if (!pdata->jack_setup) { > + rval = snd_soc_card_jack_new(card, "Headset Jack", > + SND_JACK_HEADSET | SND_JACK_LINEOUT | > + SND_JACK_MECHANICAL | > + SND_JACK_BTN_0 | SND_JACK_BTN_1 | > + SND_JACK_BTN_2 | SND_JACK_BTN_3 | > + SND_JACK_BTN_4 | SND_JACK_BTN_5, > + &pdata->hs_jack, NULL, 0); > + > + if (rval < 0) { > + dev_err(card->dev, "Unable to add Headset Jack\n"); > + return rval; > + } > + > + jack = pdata->hs_jack.jack; > + > + snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_MEDIA); > + snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); > + snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP); > + snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); > + > + jack->private_data = component; > + jack->private_free = sc7280_jack_free; > + pdata->jack_setup = true; > + } > + switch (cpu_dai->id) { > + case LPASS_CDC_DMA_RX0: > + case LPASS_CDC_DMA_TX3: > + for_each_rtd_codec_dais(rtd, i, codec_dai) { > + rval = snd_soc_component_set_jack(component, &pdata->hs_jack, NULL); > + if (rval != 0 && rval != -EOPNOTSUPP) { > + dev_warn(card->dev, "Failed to set jack: %d\n", rval); Why not dev_err? > + return rval; > + } > + } > + > + break; > + default: > + break; > + } > + > + return 0; > +} > + > +static int sc7280_hdmi_init(struct snd_soc_pcm_runtime *rtd) > +{ > + struct snd_soc_card *card = rtd->card; > + struct sc7280_snd_data *pdata = snd_soc_card_get_drvdata(card); > + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); > + struct snd_soc_component *component = codec_dai->component; > + struct snd_jack *jack; > + int rval; > + > + rval = snd_soc_card_jack_new( > + card, "HDMI Jack", > + SND_JACK_LINEOUT, > + &pdata->hdmi_jack, NULL, 0); > + > + if (rval < 0) { > + dev_err(card->dev, "Unable to add HDMI Jack\n"); > + return rval; > + } > + > + jack = pdata->hdmi_jack.jack; > + jack->private_data = component; > + jack->private_free = sc7280_jack_free; > + > + return snd_soc_component_set_jack(component, &pdata->hdmi_jack, NULL); > +} > + > +static int sc7280_init(struct snd_soc_pcm_runtime *rtd) > +{ > + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); > + > + switch (cpu_dai->id) { > + case LPASS_CDC_DMA_TX3: > + return sc7280_headset_init(rtd); > + case LPASS_CDC_DMA_RX0: > + case LPASS_CDC_DMA_VA_TX0: > + case MI2S_SECONDARY: > + return 0; > + case LPASS_DP_RX: > + return sc7280_hdmi_init(rtd); > + default: > + dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__, cpu_dai->id); > + return -EINVAL; > + } Nitpick: Add newline. > + return 0; Can we even get here? Maybe remove return from default above and make this a return -EINVAL. > +} > + > +static int sc7280_snd_startup(struct snd_pcm_substream *substream) > +{ > + struct snd_soc_pcm_runtime *rtd = substream->private_data; > + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); > + > + switch (cpu_dai->id) { > + case LPASS_CDC_DMA_RX0: > + case LPASS_CDC_DMA_TX3: > + case LPASS_CDC_DMA_VA_TX0: > + break; > + case MI2S_SECONDARY: > + break; > + case LPASS_DP_RX: > + break; > + default: > + dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__, cpu_dai->id); > + return -EINVAL; > + } Nitpick: Add newline. > + return 0; > +} > + > +static int sc7280_snd_hw_params(struct snd_pcm_substream *substream, > + struct snd_pcm_hw_params *params) > +{ > + struct snd_pcm_runtime *runtime = substream->runtime; > + struct snd_soc_pcm_runtime *rtd = substream->private_data; > + struct snd_soc_dai *codec_dai; > + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); const? > + struct sc7280_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card); > + struct sdw_stream_runtime *sruntime; > + int i; > + > + snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); > + snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, 48000, 48000); > + > + switch (cpu_dai->id) { > + case LPASS_CDC_DMA_TX3: > + case LPASS_CDC_DMA_RX0: > + for_each_rtd_codec_dais(rtd, i, codec_dai) { > + sruntime = snd_soc_dai_get_sdw_stream(codec_dai, substream->stream); > + if (sruntime != ERR_PTR(-EOPNOTSUPP)) > + pdata->sruntime[cpu_dai->id] = sruntime; > + } > + break; > + } > + > + return 0; > + Nitpick: Drop newline. > +} > + > +static int sc7280_snd_swr_prepare(struct snd_pcm_substream *substream) > +{ > + struct snd_soc_pcm_runtime *rtd = substream->private_data; > + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); const? > + struct sc7280_snd_data *data = snd_soc_card_get_drvdata(rtd->card); > + struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; > + int ret; > + > + if (!sruntime) > + return 0; > + > + if (data->stream_prepared[cpu_dai->id]) { > + sdw_disable_stream(sruntime); > + sdw_deprepare_stream(sruntime); > + data->stream_prepared[cpu_dai->id] = false; > + } > + > + ret = sdw_prepare_stream(sruntime); > + if (ret) > + return ret; > + > + ret = sdw_enable_stream(sruntime); > + if (ret) { > + sdw_deprepare_stream(sruntime); > + return ret; > + } > + data->stream_prepared[cpu_dai->id] = true; Why two spaces after ]? > + > + return ret; > +} > + > + > +static int sc7280_snd_prepare(struct snd_pcm_substream *substream) > +{ > + struct snd_soc_pcm_runtime *rtd = substream->private_data; > + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); const? > + > + switch (cpu_dai->id) { > + case LPASS_CDC_DMA_RX0: > + case LPASS_CDC_DMA_TX3: > + return sc7280_snd_swr_prepare(substream); > + default: > + break; > + } > + > + return 0; > +} > + > +static int sc7280_snd_hw_free(struct snd_pcm_substream *substream) > +{ > + struct snd_soc_pcm_runtime *rtd = substream->private_data; > + struct sc7280_snd_data *data = snd_soc_card_get_drvdata(rtd->card); > + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); const? > + struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; > + > + switch (cpu_dai->id) { > + case LPASS_CDC_DMA_RX0: > + case LPASS_CDC_DMA_TX3: > + if (sruntime && data->stream_prepared[cpu_dai->id]) { > + sdw_disable_stream(sruntime); > + sdw_deprepare_stream(sruntime); > + data->stream_prepared[cpu_dai->id] = false; > + } > + break; > + default: > + break; > + } > + return 0; > +} > + > +static void sc7280_snd_shutdown(struct snd_pcm_substream *substream) > +{ > + struct snd_soc_pcm_runtime *rtd = substream->private_data; > + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); > + > + switch (cpu_dai->id) { > + case LPASS_CDC_DMA_RX0: > + case LPASS_CDC_DMA_TX3: > + case LPASS_CDC_DMA_VA_TX0: > + break; > + case MI2S_SECONDARY: > + break; > + case LPASS_DP_RX: > + break; > + default: > + dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__, cpu_dai->id); Can use %#x to skip the 0x part. > + break; > + } > +} > + > +static const struct snd_soc_ops sc7280_ops = { > + .startup = sc7280_snd_startup, > + .shutdown = sc7280_snd_shutdown, > + .hw_params = sc7280_snd_hw_params, > + .hw_free = sc7280_snd_hw_free, > + .prepare = sc7280_snd_prepare, > +}; > + > +static const struct snd_soc_dapm_widget sc7280_snd_widgets[] = { > + SND_SOC_DAPM_HP("Headphone Jack", NULL), > + SND_SOC_DAPM_MIC("Headset Mic", NULL), > +}; > + > +static int sc7280_snd_platform_probe(struct platform_device *pdev) > +{ > + struct snd_soc_card *card; > + struct sc7280_snd_data *data; > + struct device *dev = &pdev->dev; > + struct snd_soc_dai_link *link; > + int ret, i; > + > + /* Allocate the private data */ > + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); > + if (!data) > + return -ENOMEM; > + > + card = &data->card; > + data->jack_setup = false; Isn't that implicit via kzalloc above? This can be dropped. > + snd_soc_card_set_drvdata(card, data); > + > + card->owner = THIS_MODULE; > + card->driver_name = DRIVER_NAME; > + card->dev = dev; > + > + ret = qcom_snd_parse_of(card); > + if (ret) > + return ret; > + > + for_each_card_prelinks(card, i, link) { > + link->init = sc7280_init; > + link->ops = &sc7280_ops; > + } > + ret = devm_snd_soc_register_card(dev, card); > + return ret; Nitpick: return devm_snd_soc_register_card(dev, card) > +} > + > +static const struct of_device_id sc7280_snd_device_id[] = { > + {.compatible = "google,sc7280-herobrine"}, > + {}, Nitpick: Drop comma here so nothing can come after without causing a compile error. > +}; > +MODULE_DEVICE_TABLE(of, sc7280_snd_device_id); > +