From patchwork Thu Dec 10 01:52:10 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: libin.yang@linux.intel.com X-Patchwork-Id: 7814071 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id CD9BBBEEE1 for ; Thu, 10 Dec 2015 01:57:22 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E90FA20555 for ; Thu, 10 Dec 2015 01:57:21 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 9D7EB20551 for ; Thu, 10 Dec 2015 01:57:20 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id BC96B261AD0; Thu, 10 Dec 2015 02:57:18 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 190D7261ADA; Thu, 10 Dec 2015 02:54:52 +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 4B5C22614F4; Thu, 10 Dec 2015 02:54:49 +0100 (CET) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by alsa0.perex.cz (Postfix) with ESMTP id 76339261537 for ; Thu, 10 Dec 2015 02:54:40 +0100 (CET) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga101.jf.intel.com with ESMTP; 09 Dec 2015 17:54:39 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,406,1444719600"; d="scan'208";a="615551572" Received: from younglee-grantley.sh.intel.com ([10.239.159.137]) by FMSMGA003.fm.intel.com with ESMTP; 09 Dec 2015 17:54:37 -0800 From: libin.yang@linux.intel.com To: alsa-devel@alsa-project.org, tiwai@suse.de Date: Thu, 10 Dec 2015 09:52:10 +0800 Message-Id: <1449712332-106365-4-git-send-email-libin.yang@linux.intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1449712332-106365-1-git-send-email-libin.yang@linux.intel.com> References: <1449712332-106365-1-git-send-email-libin.yang@linux.intel.com> Cc: libin.yang@intel.com, mengdong.lin@intel.com, Libin Yang Subject: [alsa-devel] [PATCH v3 3/5] ALSA: hda - hdmi operate spdif based on pcm 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: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP From: Libin Yang Currently, the driver operates the spdif based on pin. This is ok for the current driver as pcm is statically bound to the pin. However, if the driver uses dynamically pcm assignment, this will cause confusion for user space. The patch changes spdif operation from pin based to pcm based. Signed-off-by: Libin Yang --- sound/pci/hda/patch_hdmi.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 670db50..8b16dff 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -137,6 +137,7 @@ struct hdmi_spec { struct snd_array pins; /* struct hdmi_spec_per_pin */ struct hda_pcm *pcm_rec[16]; struct mutex pcm_lock; + int pcm_used; /* counter of pcm_rec[] */ unsigned int channels_max; /* max over all cvts */ struct hdmi_eld temp_eld; @@ -379,6 +380,20 @@ static int pin_nid_to_pin_index(struct hda_codec *codec, hda_nid_t pin_nid) return -EINVAL; } +static int hinfo_to_pcm_index(struct hda_codec *codec, + struct hda_pcm_stream *hinfo) +{ + struct hdmi_spec *spec = codec->spec; + int pcm_idx; + + for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) + if (get_pcm_rec(spec, pcm_idx)->stream == hinfo) + return pcm_idx; + + codec_warn(codec, "HDMI: hinfo %p not registered\n", hinfo); + return -EINVAL; +} + static int hinfo_to_pin_index(struct hda_codec *codec, struct hda_pcm_stream *hinfo) { @@ -1540,13 +1555,17 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, { struct hdmi_spec *spec = codec->spec; struct snd_pcm_runtime *runtime = substream->runtime; - int pin_idx, cvt_idx, mux_idx = 0; + int pin_idx, cvt_idx, pcm_idx, mux_idx = 0; struct hdmi_spec_per_pin *per_pin; struct hdmi_eld *eld; struct hdmi_spec_per_cvt *per_cvt = NULL; int err; /* Validate hinfo */ + pcm_idx = hinfo_to_pcm_index(codec, hinfo); + if (pcm_idx < 0) + return -EINVAL; + mutex_lock(&spec->pcm_lock); pin_idx = hinfo_to_pin_index(codec, hinfo); if (!spec->dyn_pcm_assign) { @@ -1588,7 +1607,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, if (is_haswell_plus(codec) || is_valleyview_plus(codec)) intel_not_share_assigned_cvt(codec, per_pin->pin_nid, mux_idx); - snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid); + snd_hda_spdif_ctls_assign(codec, pcm_idx, per_cvt->cvt_nid); /* Initially set the converter's capabilities */ hinfo->channels_min = per_cvt->channels_min; @@ -1605,7 +1624,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, !hinfo->rates || !hinfo->formats) { per_cvt->assigned = 0; hinfo->nid = 0; - snd_hda_spdif_ctls_unassign(codec, pin_idx); + snd_hda_spdif_ctls_unassign(codec, pcm_idx); mutex_unlock(&spec->pcm_lock); return -ENODEV; } @@ -1998,12 +2017,15 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, struct snd_pcm_substream *substream) { struct hdmi_spec *spec = codec->spec; - int cvt_idx, pin_idx; + int cvt_idx, pin_idx, pcm_idx; struct hdmi_spec_per_cvt *per_cvt; struct hdmi_spec_per_pin *per_pin; int pinctl; if (hinfo->nid) { + pcm_idx = hinfo_to_pcm_index(codec, hinfo); + if (snd_BUG_ON(pcm_idx < 0)) + return -EINVAL; cvt_idx = cvt_nid_to_cvt_index(codec, hinfo->nid); if (snd_BUG_ON(cvt_idx < 0)) return -EINVAL; @@ -2034,7 +2056,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, pinctl & ~PIN_OUT); } - snd_hda_spdif_ctls_unassign(codec, pin_idx); + snd_hda_spdif_ctls_unassign(codec, pcm_idx); mutex_lock(&per_pin->lock); per_pin->chmap_set = false; @@ -2232,6 +2254,7 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) per_pin->pcm = info; } spec->pcm_rec[pin_idx] = info; + spec->pcm_used++; info->pcm_type = HDA_PCM_TYPE_HDMI; info->own_chmap = true; @@ -2282,6 +2305,7 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) HDA_PCM_TYPE_HDMI); if (err < 0) return err; + /* pin number is the same with pcm number so far */ snd_hda_spdif_ctls_unassign(codec, pin_idx); /* add control for ELD Bytes */