Message ID | 20220727160051.3373125-1-sbinding@opensource.cirrus.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [v2] ASoC: Intel: cirrus-common: Use UID to map correct amp to prefix | expand |
> +/* > + * Expected UIDs are integers (stored as strings). > + * UID Mapping is fixed: > + * UID 0x0 -> WL > + * UID 0x1 -> WR > + * UID 0x2 -> TL > + * UID 0x3 -> TR > + * Note: If there are less than 4 Amps, UIDs still map to WL/WR/TL/TR. Dynamic code will only create > + * dai links for UIDs which exist, and ignore non-existant ones. is this intentional to support all variations of 1,2,3 and 4 amplifiers being present? Or is the intent to really support 2 or 4? > + * Return number of codecs found. > + */ > +static int cs35l41_compute_codec_conf(void) > +{ > + const char * const uid_strings[] = { "0", "1", "2", "3" }; > + unsigned int uid, sz = 0; > + struct acpi_device *adev; > + struct device *physdev; > + > + for (uid = 0; uid < CS35L41_MAX_AMPS; uid++) { > + adev = acpi_dev_get_first_match_dev(CS35L41_HID, uid_strings[uid], -1); > + if (!adev) { > + pr_warn("Cannot find match for HID %s UID %u (%s)\n", CS35L41_HID, uid, > + cs35l41_name_prefixes[uid]); A warning is a bit strong if some valid configurations don't expose all 4 codecs. > + continue; > + } > + physdev = get_device(acpi_get_first_physical_node(adev)); > + cs35l41_components[sz].name = dev_name(physdev); > + cs35l41_components[sz].dai_name = CS35L41_CODEC_DAI; > + cs35l41_codec_conf[sz].dlc.name = dev_name(physdev); > + cs35l41_codec_conf[sz].name_prefix = cs35l41_name_prefixes[uid]; > + acpi_dev_put(adev); > + sz++; > + } > + return sz;
Hi, > -----Original Message----- > From: Alsa-devel <alsa-devel-bounces@alsa-project.org> On Behalf Of > Pierre-Louis Bossart > Sent: 27 July 2022 17:37 > To: Stefan Binding <sbinding@opensource.cirrus.com>; Mark Brown > <broonie@kernel.org>; Liam Girdwood <lgirdwood@gmail.com>; > Brent Lu <brent.lu@intel.com>; xliu <xiang.liu@cirrus.com> > Cc: Vitaly Rodionov <vitalyr@opensource.cirrus.com>; > patches@opensource.cirrus.com; alsa-devel@alsa-project.org; linux- > kernel@vger.kernel.org > Subject: Re: [PATCH v2] ASoC: Intel: cirrus-common: Use UID to map > correct amp to prefix > > > > > > +/* > > + * Expected UIDs are integers (stored as strings). > > + * UID Mapping is fixed: > > + * UID 0x0 -> WL > > + * UID 0x1 -> WR > > + * UID 0x2 -> TL > > + * UID 0x3 -> TR > > + * Note: If there are less than 4 Amps, UIDs still map to > WL/WR/TL/TR. Dynamic code will only create > > + * dai links for UIDs which exist, and ignore non-existant ones. > > is this intentional to support all variations of 1,2,3 and 4 amplifiers > being present? > > Or is the intent to really support 2 or 4? The intent was to support 2 or 4, rather than any number of amps, in case something was released with 2 amps. > > > + * Return number of codecs found. > > + */ > > +static int cs35l41_compute_codec_conf(void) > > +{ > > + const char * const uid_strings[] = { "0", "1", "2", "3" }; > > + unsigned int uid, sz = 0; > > + struct acpi_device *adev; > > + struct device *physdev; > > + > > + for (uid = 0; uid < CS35L41_MAX_AMPS; uid++) { > > + adev = acpi_dev_get_first_match_dev(CS35L41_HID, > uid_strings[uid], -1); > > + if (!adev) { > > + pr_warn("Cannot find match for HID %s UID > %u (%s)\n", CS35L41_HID, uid, > > + cs35l41_name_prefixes[uid]); > > A warning is a bit strong if some valid configurations don't expose all > 4 codecs. I'll change this to a debug message, but also add an error if there is not 2 or 4 amps found. > > > + continue; > > + } > > + physdev = > get_device(acpi_get_first_physical_node(adev)); > > + cs35l41_components[sz].name = dev_name(physdev); > > + cs35l41_components[sz].dai_name = > CS35L41_CODEC_DAI; > > + cs35l41_codec_conf[sz].dlc.name = > dev_name(physdev); > > + cs35l41_codec_conf[sz].name_prefix = > cs35l41_name_prefixes[uid]; > > + acpi_dev_put(adev); > > + sz++; > > + } > > + return sz; Thanks, Stefan
diff --git a/sound/soc/intel/boards/sof_cirrus_common.c b/sound/soc/intel/boards/sof_cirrus_common.c index f4192df962d6..e74c4adbf2a5 100644 --- a/sound/soc/intel/boards/sof_cirrus_common.c +++ b/sound/soc/intel/boards/sof_cirrus_common.c @@ -10,6 +10,9 @@ #include "../../codecs/cs35l41.h" #include "sof_cirrus_common.h" +#define CS35L41_HID "CSC3541" +#define CS35L41_MAX_AMPS 4 + /* * Cirrus Logic CS35L41/CS35L53 */ @@ -35,50 +38,12 @@ static const struct snd_soc_dapm_route cs35l41_dapm_routes[] = { {"TR Spk", NULL, "TR SPK"}, }; -static struct snd_soc_dai_link_component cs35l41_components[] = { - { - .name = CS35L41_DEV0_NAME, - .dai_name = CS35L41_CODEC_DAI, - }, - { - .name = CS35L41_DEV1_NAME, - .dai_name = CS35L41_CODEC_DAI, - }, - { - .name = CS35L41_DEV2_NAME, - .dai_name = CS35L41_CODEC_DAI, - }, - { - .name = CS35L41_DEV3_NAME, - .dai_name = CS35L41_CODEC_DAI, - }, -}; +static struct snd_soc_dai_link_component cs35l41_components[CS35L41_MAX_AMPS]; /* * Mapping between ACPI instance id and speaker position. - * - * Four speakers: - * 0: Tweeter left, 1: Woofer left - * 2: Tweeter right, 3: Woofer right */ -static struct snd_soc_codec_conf cs35l41_codec_conf[] = { - { - .dlc = COMP_CODEC_CONF(CS35L41_DEV0_NAME), - .name_prefix = "TL", - }, - { - .dlc = COMP_CODEC_CONF(CS35L41_DEV1_NAME), - .name_prefix = "WL", - }, - { - .dlc = COMP_CODEC_CONF(CS35L41_DEV2_NAME), - .name_prefix = "TR", - }, - { - .dlc = COMP_CODEC_CONF(CS35L41_DEV3_NAME), - .name_prefix = "WR", - }, -}; +static struct snd_soc_codec_conf cs35l41_codec_conf[CS35L41_MAX_AMPS]; static int cs35l41_init(struct snd_soc_pcm_runtime *rtd) { @@ -117,10 +82,10 @@ static int cs35l41_init(struct snd_soc_pcm_runtime *rtd) static const struct { unsigned int rx[2]; } cs35l41_channel_map[] = { - {.rx = {0, 1}}, /* TL */ {.rx = {0, 1}}, /* WL */ - {.rx = {1, 0}}, /* TR */ {.rx = {1, 0}}, /* WR */ + {.rx = {0, 1}}, /* TL */ + {.rx = {1, 0}}, /* TR */ }; static int cs35l41_hw_params(struct snd_pcm_substream *substream, @@ -175,10 +140,48 @@ static const struct snd_soc_ops cs35l41_ops = { .hw_params = cs35l41_hw_params, }; +static const char * const cs35l41_name_prefixes[] = { "WL", "WR", "TL", "TR" }; + +/* + * Expected UIDs are integers (stored as strings). + * UID Mapping is fixed: + * UID 0x0 -> WL + * UID 0x1 -> WR + * UID 0x2 -> TL + * UID 0x3 -> TR + * Note: If there are less than 4 Amps, UIDs still map to WL/WR/TL/TR. Dynamic code will only create + * dai links for UIDs which exist, and ignore non-existant ones. + * Return number of codecs found. + */ +static int cs35l41_compute_codec_conf(void) +{ + const char * const uid_strings[] = { "0", "1", "2", "3" }; + unsigned int uid, sz = 0; + struct acpi_device *adev; + struct device *physdev; + + for (uid = 0; uid < CS35L41_MAX_AMPS; uid++) { + adev = acpi_dev_get_first_match_dev(CS35L41_HID, uid_strings[uid], -1); + if (!adev) { + pr_warn("Cannot find match for HID %s UID %u (%s)\n", CS35L41_HID, uid, + cs35l41_name_prefixes[uid]); + continue; + } + physdev = get_device(acpi_get_first_physical_node(adev)); + cs35l41_components[sz].name = dev_name(physdev); + cs35l41_components[sz].dai_name = CS35L41_CODEC_DAI; + cs35l41_codec_conf[sz].dlc.name = dev_name(physdev); + cs35l41_codec_conf[sz].name_prefix = cs35l41_name_prefixes[uid]; + acpi_dev_put(adev); + sz++; + } + return sz; +} + void cs35l41_set_dai_link(struct snd_soc_dai_link *link) { + link->num_codecs = cs35l41_compute_codec_conf(); link->codecs = cs35l41_components; - link->num_codecs = ARRAY_SIZE(cs35l41_components); link->init = cs35l41_init; link->ops = &cs35l41_ops; }