Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit e905bc7

Browse files
rfvirgilgregkh
authored andcommitted
ASoC: cs35l56: Load tunings for the correct speaker models
[ Upstream commit 245eeff ] If the "spk-id-gpios" property is present it points to GPIOs whose value must be used to select the correct bin file to match the speakers. Some manufacturers use multiple sources of speakers, which need different tunings for best performance. On these models the type of speaker fitted is indicated by the values of one or more GPIOs. The number formed by the GPIOs identifies the tuning required. The speaker ID must be used in combination with the subsystem ID (either from PCI SSID or cirrus,firmware-uid property), because the GPIOs can only indicate variants of a specific model. Signed-off-by: Richard Fitzgerald <[email protected]> Fixes: 1a1c3d7 ("ASoC: cs35l56: Use PCI SSID as the firmware UID") Link: https://msgid.link/r/[email protected] Signed-off-by: Mark Brown <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 9790a7a commit e905bc7

File tree

4 files changed

+65
-5
lines changed

4 files changed

+65
-5
lines changed

include/sound/cs35l56.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base);
287287
int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_soundwire);
288288
void cs35l56_init_cs_dsp(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp);
289289
int cs35l56_hw_init(struct cs35l56_base *cs35l56_base);
290+
int cs35l56_get_speaker_id(struct cs35l56_base *cs35l56_base);
290291
int cs35l56_get_bclk_freq_id(unsigned int freq);
291292
void cs35l56_fill_supply_names(struct regulator_bulk_data *data);
292293

sound/soc/codecs/cs35l56-shared.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// Copyright (C) 2023 Cirrus Logic, Inc. and
66
// Cirrus Logic International Semiconductor Ltd.
77

8+
#include <linux/gpio/consumer.h>
89
#include <linux/regmap.h>
910
#include <linux/regulator/consumer.h>
1011
#include <linux/types.h>
@@ -695,6 +696,41 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
695696
}
696697
EXPORT_SYMBOL_NS_GPL(cs35l56_hw_init, SND_SOC_CS35L56_SHARED);
697698

699+
int cs35l56_get_speaker_id(struct cs35l56_base *cs35l56_base)
700+
{
701+
struct gpio_descs *descs;
702+
int speaker_id;
703+
int i, ret;
704+
705+
/* Read the speaker type qualifier from the motherboard GPIOs */
706+
descs = gpiod_get_array_optional(cs35l56_base->dev, "spk-id", GPIOD_IN);
707+
if (!descs) {
708+
return -ENOENT;
709+
} else if (IS_ERR(descs)) {
710+
ret = PTR_ERR(descs);
711+
return dev_err_probe(cs35l56_base->dev, ret, "Failed to get spk-id-gpios\n");
712+
}
713+
714+
speaker_id = 0;
715+
for (i = 0; i < descs->ndescs; i++) {
716+
ret = gpiod_get_value_cansleep(descs->desc[i]);
717+
if (ret < 0) {
718+
dev_err_probe(cs35l56_base->dev, ret, "Failed to read spk-id[%d]\n", i);
719+
goto err;
720+
}
721+
722+
speaker_id |= (ret << i);
723+
}
724+
725+
dev_dbg(cs35l56_base->dev, "Speaker ID = %d\n", speaker_id);
726+
ret = speaker_id;
727+
err:
728+
gpiod_put_array(descs);
729+
730+
return ret;
731+
}
732+
EXPORT_SYMBOL_NS_GPL(cs35l56_get_speaker_id, SND_SOC_CS35L56_SHARED);
733+
698734
static const u32 cs35l56_bclk_valid_for_pll_freq_table[] = {
699735
[0x0C] = 128000,
700736
[0x0F] = 256000,

sound/soc/codecs/cs35l56.c

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -941,10 +941,19 @@ static int cs35l56_component_probe(struct snd_soc_component *component)
941941

942942
if (!cs35l56->dsp.system_name &&
943943
(snd_soc_card_get_pci_ssid(component->card, &vendor, &device) == 0)) {
944-
cs35l56->dsp.system_name = devm_kasprintf(cs35l56->base.dev,
945-
GFP_KERNEL,
946-
"%04x%04x",
947-
vendor, device);
944+
/* Append a speaker qualifier if there is a speaker ID */
945+
if (cs35l56->speaker_id >= 0) {
946+
cs35l56->dsp.system_name = devm_kasprintf(cs35l56->base.dev,
947+
GFP_KERNEL,
948+
"%04x%04x-spkid%d",
949+
vendor, device,
950+
cs35l56->speaker_id);
951+
} else {
952+
cs35l56->dsp.system_name = devm_kasprintf(cs35l56->base.dev,
953+
GFP_KERNEL,
954+
"%04x%04x",
955+
vendor, device);
956+
}
948957
if (!cs35l56->dsp.system_name)
949958
return -ENOMEM;
950959
}
@@ -1230,7 +1239,13 @@ static int cs35l56_get_firmware_uid(struct cs35l56_private *cs35l56)
12301239
if (ret < 0)
12311240
return 0;
12321241

1233-
cs35l56->dsp.system_name = devm_kstrdup(dev, prop, GFP_KERNEL);
1242+
/* Append a speaker qualifier if there is a speaker ID */
1243+
if (cs35l56->speaker_id >= 0)
1244+
cs35l56->dsp.system_name = devm_kasprintf(dev, GFP_KERNEL, "%s-spkid%d",
1245+
prop, cs35l56->speaker_id);
1246+
else
1247+
cs35l56->dsp.system_name = devm_kstrdup(dev, prop, GFP_KERNEL);
1248+
12341249
if (cs35l56->dsp.system_name == NULL)
12351250
return -ENOMEM;
12361251

@@ -1245,6 +1260,7 @@ int cs35l56_common_probe(struct cs35l56_private *cs35l56)
12451260

12461261
init_completion(&cs35l56->init_completion);
12471262
mutex_init(&cs35l56->base.irq_lock);
1263+
cs35l56->speaker_id = -ENOENT;
12481264

12491265
dev_set_drvdata(cs35l56->base.dev, cs35l56);
12501266

@@ -1281,6 +1297,12 @@ int cs35l56_common_probe(struct cs35l56_private *cs35l56)
12811297
gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 1);
12821298
}
12831299

1300+
ret = cs35l56_get_speaker_id(&cs35l56->base);
1301+
if ((ret < 0) && (ret != -ENOENT))
1302+
goto err;
1303+
1304+
cs35l56->speaker_id = ret;
1305+
12841306
ret = cs35l56_get_firmware_uid(cs35l56);
12851307
if (ret != 0)
12861308
goto err;

sound/soc/codecs/cs35l56.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ struct cs35l56_private {
4444
bool sdw_attached;
4545
struct completion init_completion;
4646

47+
int speaker_id;
4748
u32 rx_mask;
4849
u32 tx_mask;
4950
u8 asp_slot_width;

0 commit comments

Comments
 (0)