From patchwork Fri Jun 10 09:45:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 9169475 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 E5119604DB for ; Fri, 10 Jun 2016 11:00:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D68901FF45 for ; Fri, 10 Jun 2016 11:00:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CAEFD2835A; Fri, 10 Jun 2016 11:00:26 +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=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 53F041FF45 for ; Fri, 10 Jun 2016 11:00:26 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D39A36ECFB; Fri, 10 Jun 2016 11:00:15 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm0-x230.google.com (mail-wm0-x230.google.com [IPv6:2a00:1450:400c:c09::230]) by gabe.freedesktop.org (Postfix) with ESMTPS id 11CDE6ECCC for ; Fri, 10 Jun 2016 09:46:07 +0000 (UTC) Received: by mail-wm0-x230.google.com with SMTP id v199so141228558wmv.0 for ; Fri, 10 Jun 2016 02:46:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=rnDDrdLNaxitkgrOoV21XS3B02LbY9oOL/tkPfAIIEw=; b=E3vmrkIv6OTsrrtI+pzDq5MQ39BrBK3HAhh3RekGP8EiVq8R5ATHVr8pCABZsquKE3 6GAV3bX2abCkB/64YuGAHuNyQYoVnm9KonTgHuqXQl/gAUH0g62kVR3hCRLbODkZS9AC 1AYveQ1nX+3X+/ERpOeyxkyscBPpXeq+ELxb0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=rnDDrdLNaxitkgrOoV21XS3B02LbY9oOL/tkPfAIIEw=; b=lXHiYwjocCXyxyVNRzzbPxC9ZnaQg/MnHeGAo0wkpJhlIHZpQBGWT7IWmKX63W/Fbr sGqrTYdNf3qdOxQ+68i6ieKFAdMnqrF1sUOML4U5dPTVFy8wzK0ak10Kknd4hXvZiCZG TaIYOwE5HD2pxCqxvMAGKAeOnozG+ObqcFwnBm3YqEuiq3nmgRPr41veZecc/Bytc2Jv LllMh9tEE6Cy1utTH5DDgulumUz1GP1dRCvhtRm9h8aLu9dPS+o1xyrYpiVhL29ZuI31 WXpEdRyyZE0Cn6HPHc2XYjS/iA0EbTBc6k+HIugeJqe43pNPK8zQKur/Oxz3M0g5iTQ4 cydw== X-Gm-Message-State: ALyK8tIPR15TlZb+e/oRS6Sj3ZPngqzFE/jlXtKBqOFQQAte6QKh/cybsRr9vVgH/MgjuM17 X-Received: by 10.28.169.66 with SMTP id s63mr12857965wme.87.1465551965156; Fri, 10 Jun 2016 02:46:05 -0700 (PDT) Received: from localhost.localdomain (host-92-17-247-99.as13285.net. [92.17.247.99]) by smtp.gmail.com with ESMTPSA id kq9sm11440051wjc.26.2016.06.10.02.46.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 10 Jun 2016 02:46:04 -0700 (PDT) From: Srinivas Kandagatla To: Rob Clark , dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, alsa-devel@alsa-project.org Subject: [PATCH v2] drm: msm: Add ASoC generic hdmi audio codec support. Date: Fri, 10 Jun 2016 10:45:56 +0100 Message-Id: <1465551956-21736-1-git-send-email-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.7.4 X-Mailman-Approved-At: Fri, 10 Jun 2016 11:00:14 +0000 Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, jsarha@ti.com, broonie@kernel.org, Srinivas Kandagatla X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch adds support to generic audio codec via ASoC hdmi-codec infrastucture which is merged recently. Signed-off-by: Srinivas Kandagatla --- Changes since v1: -Fixed typo for 44.1Kz case spotted by Jyri Sarha drivers/gpu/drm/msm/Kconfig | 1 + drivers/gpu/drm/msm/hdmi/hdmi.c | 120 +++++++++++++++++++++++++++++++++++++++- drivers/gpu/drm/msm/hdmi/hdmi.h | 14 +++++ 3 files changed, 134 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 167a497..7c7a031 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -10,6 +10,7 @@ config DRM_MSM select SHMEM select TMPFS select QCOM_SCM + select SND_SOC_HDMI_CODEC if SND_SOC default y help DRM/KMS driver for MSM/snapdragon. diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 51b9ea5..aada355 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -19,6 +19,7 @@ #include #include +#include #include "hdmi.h" void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on) @@ -434,6 +435,114 @@ static int msm_hdmi_get_gpio(struct device_node *of_node, const char *name) return gpio; } +/* + * HDMI audio codec callbacks + */ +static int msm_hdmi_audio_hw_params(struct device *dev, + struct hdmi_codec_daifmt *daifmt, + struct hdmi_codec_params *params) +{ + struct hdmi *hdmi = dev_get_drvdata(dev); + unsigned int chan; + unsigned int channel_allocation = 0; + unsigned int rate; + unsigned int level_shift = 0; /* 0dB */ + bool down_mix = false; + + dev_dbg(dev, "%u Hz, %d bit, %d channels\n", params->sample_rate, + params->sample_width, params->cea.channels); + + switch (params->cea.channels) { + case 2: + /* FR and FL speakers */ + channel_allocation = 0; + chan = MSM_HDMI_AUDIO_CHANNEL_2; + break; + case 4: + /* FC, LFE, FR and FL speakers */ + channel_allocation = 0x3; + chan = MSM_HDMI_AUDIO_CHANNEL_4; + break; + case 6: + /* RR, RL, FC, LFE, FR and FL speakers */ + channel_allocation = 0x0B; + chan = MSM_HDMI_AUDIO_CHANNEL_6; + break; + case 8: + /* FRC, FLC, RR, RL, FC, LFE, FR and FL speakers */ + channel_allocation = 0x1F; + chan = MSM_HDMI_AUDIO_CHANNEL_8; + break; + default: + return -EINVAL; + } + + switch (params->sample_rate) { + case 32000: + rate = HDMI_SAMPLE_RATE_32KHZ; + break; + case 44100: + rate = HDMI_SAMPLE_RATE_44_1KHZ; + break; + case 48000: + rate = HDMI_SAMPLE_RATE_48KHZ; + break; + case 88200: + rate = HDMI_SAMPLE_RATE_88_2KHZ; + break; + case 96000: + rate = HDMI_SAMPLE_RATE_96KHZ; + break; + case 176400: + rate = HDMI_SAMPLE_RATE_176_4KHZ; + break; + case 192000: + rate = HDMI_SAMPLE_RATE_192KHZ; + break; + default: + dev_err(dev, "rate[%d] not supported!\n", + params->sample_rate); + return -EINVAL; + } + + msm_hdmi_audio_set_sample_rate(hdmi, rate); + msm_hdmi_audio_info_setup(hdmi, 1, chan, channel_allocation, + level_shift, down_mix); + + return 0; +} + +static void msm_hdmi_audio_shutdown(struct device *dev) +{ + struct hdmi *hdmi = dev_get_drvdata(dev); + + msm_hdmi_audio_info_setup(hdmi, 0, 0, 0, 0, 0); +} + +static const struct hdmi_codec_ops msm_hdmi_audio_codec_ops = { + .hw_params = msm_hdmi_audio_hw_params, + .audio_shutdown = msm_hdmi_audio_shutdown, +}; + +static struct hdmi_codec_pdata codec_data = { + .ops = &msm_hdmi_audio_codec_ops, + .max_i2s_channels = 8, + .i2s = 1, +}; + +static int msm_hdmi_register_audio_driver(struct hdmi *hdmi, struct device *dev) +{ + hdmi->audio_pdev = platform_device_register_data(dev, + HDMI_CODEC_DRV_NAME, + PLATFORM_DEVID_AUTO, + &codec_data, + sizeof(codec_data)); + if (IS_ERR(hdmi->audio_pdev)) + return PTR_ERR(hdmi->audio_pdev); + + return 0; +} + static int msm_hdmi_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = dev_get_drvdata(master); @@ -441,7 +550,7 @@ static int msm_hdmi_bind(struct device *dev, struct device *master, void *data) static struct hdmi_platform_config *hdmi_cfg; struct hdmi *hdmi; struct device_node *of_node = dev->of_node; - int i; + int i, err; hdmi_cfg = (struct hdmi_platform_config *) of_device_get_match_data(dev); @@ -468,6 +577,12 @@ static int msm_hdmi_bind(struct device *dev, struct device *master, void *data) return PTR_ERR(hdmi); priv->hdmi = hdmi; + err = msm_hdmi_register_audio_driver(hdmi, dev); + if (err) { + DRM_ERROR("Failed to attach an audio codec %d\n", err); + hdmi->audio_pdev = NULL; + } + return 0; } @@ -477,6 +592,9 @@ static void msm_hdmi_unbind(struct device *dev, struct device *master, struct drm_device *drm = dev_get_drvdata(master); struct msm_drm_private *priv = drm->dev_private; if (priv->hdmi) { + if (priv->hdmi->audio_pdev) + platform_device_unregister(priv->hdmi->audio_pdev); + msm_hdmi_destroy(priv->hdmi); priv->hdmi = NULL; } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index bc7ba0b..accc9a6 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -50,6 +50,7 @@ struct hdmi_hdcp_ctrl; struct hdmi { struct drm_device *dev; struct platform_device *pdev; + struct platform_device *audio_pdev; const struct hdmi_platform_config *config; @@ -210,6 +211,19 @@ static inline int msm_hdmi_pll_8996_init(struct platform_device *pdev) /* * audio: */ +/* Supported HDMI Audio channels and rates */ +#define MSM_HDMI_AUDIO_CHANNEL_2 0 +#define MSM_HDMI_AUDIO_CHANNEL_4 1 +#define MSM_HDMI_AUDIO_CHANNEL_6 2 +#define MSM_HDMI_AUDIO_CHANNEL_8 3 + +#define HDMI_SAMPLE_RATE_32KHZ 0 +#define HDMI_SAMPLE_RATE_44_1KHZ 1 +#define HDMI_SAMPLE_RATE_48KHZ 2 +#define HDMI_SAMPLE_RATE_88_2KHZ 3 +#define HDMI_SAMPLE_RATE_96KHZ 4 +#define HDMI_SAMPLE_RATE_176_4KHZ 5 +#define HDMI_SAMPLE_RATE_192KHZ 6 int msm_hdmi_audio_update(struct hdmi *hdmi); int msm_hdmi_audio_info_setup(struct hdmi *hdmi, bool enabled,