From c1690ba494c0dbdd068459295e981559bd728190 Mon Sep 17 00:00:00 2001 From: Robbe Derks Date: Wed, 13 Nov 2024 16:08:45 +0100 Subject: [PATCH] Generic codec (#63) --- arch/arm64/boot/dts/qcom/comma_common.dtsi | 16 ++- arch/arm64/boot/dts/qcom/comma_mici.dts | 5 + arch/arm64/configs/tici_defconfig | 3 +- sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/generic-codec.c | 107 +++++++++++++++++++++ sound/soc/soc-core.c | 10 +- techpack/audio/asoc/sdm845.c | 15 ++- techpack/audio/dsp/q6afe.c | 2 +- 9 files changed, 141 insertions(+), 23 deletions(-) create mode 100644 sound/soc/codecs/generic-codec.c diff --git a/arch/arm64/boot/dts/qcom/comma_common.dtsi b/arch/arm64/boot/dts/qcom/comma_common.dtsi index 774d523d5c34..214e39e54af2 100644 --- a/arch/arm64/boot/dts/qcom/comma_common.dtsi +++ b/arch/arm64/boot/dts/qcom/comma_common.dtsi @@ -65,15 +65,6 @@ /* value is 30mOhm, measured in uohms */ shunt-resistor = <30000>; }; - - max98089@10 { - compatible = "maxim,max98089"; - reg = <0x10>; /* slave address 0x20 for write, 0x21 for read */ - mic-left-digital; - mic-right-digital; - clock-names = "mclk"; - clocks = <&clock_audio_lnbb AUDIO_PMIC_LNBB_CLK>; - }; }; /* IMU bus */ @@ -147,6 +138,13 @@ pinctrl-names = "default"; pinctrl-0 = <&usb2_vbus_det_default>; }; + + generic_codec: generic-codec { + status = "ok"; + compatible = "generic-codec"; + clock-names = "mclk"; + clocks = <&clock_audio_lnbb AUDIO_PMIC_LNBB_CLK>; + }; }; &labibb { diff --git a/arch/arm64/boot/dts/qcom/comma_mici.dts b/arch/arm64/boot/dts/qcom/comma_mici.dts index e1d3d5a9c90b..e65f6f31f2bc 100644 --- a/arch/arm64/boot/dts/qcom/comma_mici.dts +++ b/arch/arm64/boot/dts/qcom/comma_mici.dts @@ -127,6 +127,11 @@ status = "ok"; }; }; +&dai_mi2s1 { + qcom,msm-mi2s-rx-lines = <2>; + qcom,msm-mi2s-tx-lines = <1>; +}; + /* Board definition */ / { model = "comma mici"; diff --git a/arch/arm64/configs/tici_defconfig b/arch/arm64/configs/tici_defconfig index e425c7649a94..e78bda9cf782 100644 --- a/arch/arm64/configs/tici_defconfig +++ b/arch/arm64/configs/tici_defconfig @@ -5699,7 +5699,8 @@ CONFIG_QMI_ENCDEC=y # sound card CONFIG_SND_SOC_MACHINE_SDM845=y #CONFIG_SND_SOC_MACHINE_SDM845_MAX98089=y -CONFIG_SND_SOC_MAX98088=y +#CONFIG_SND_SOC_MAX98088=y +CONFIG_SND_SOC_GENERIC_CODEC=y CONFIG_NFS_FS=y CONFIG_NFS_V4=y diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index b143243e651d..ff09fef2857c 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -70,6 +70,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_DMIC select SND_SOC_ES8328_SPI if SPI_MASTER select SND_SOC_ES8328_I2C if I2C + select SND_SOC_GENERIC_CODEC select SND_SOC_GTM601 select SND_SOC_HDAC_HDMI select SND_SOC_ICS43432 @@ -523,6 +524,9 @@ config SND_SOC_ES8328_SPI tristate select SND_SOC_ES8328 +config SND_SOC_GENERIC_CODEC + tristate 'Generic ASoC CODEC' + config SND_SOC_GTM601 tristate 'GTM601 UMTS modem audio codec' diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 958cd4912fbc..d8fe2939e2f2 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -64,6 +64,7 @@ snd-soc-dmic-objs := dmic.o snd-soc-es8328-objs := es8328.o snd-soc-es8328-i2c-objs := es8328-i2c.o snd-soc-es8328-spi-objs := es8328-spi.o +snd-soc-generic-codec-objs := generic-codec.o snd-soc-gtm601-objs := gtm601.o snd-soc-hdac-hdmi-objs := hdac_hdmi.o snd-soc-ics43432-objs := ics43432.o @@ -289,6 +290,7 @@ obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o +obj-$(CONFIG_SND_SOC_GENERIC_CODEC) += snd-soc-generic-codec.o obj-$(CONFIG_SND_SOC_GTM601) += snd-soc-gtm601.o obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-soc-hdac-hdmi.o obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o diff --git a/sound/soc/codecs/generic-codec.c b/sound/soc/codecs/generic-codec.c new file mode 100644 index 000000000000..3e2646800857 --- /dev/null +++ b/sound/soc/codecs/generic-codec.c @@ -0,0 +1,107 @@ +/* + * Generic I2S codec driver + * + * Copyright (C) 2024 comma.ai + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +// Only supports 48kHz, 16-bit audio +static struct snd_soc_dai_driver generic_dai = { + .name = "HiFi", + .playback = { + .stream_name = "HiFi Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .capture = { + .stream_name = "HiFi Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, +}; + +static const struct snd_soc_dapm_widget generic_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("IN_L"), + SND_SOC_DAPM_INPUT("IN_R"), + + SND_SOC_DAPM_OUTPUT("OUT_L"), + SND_SOC_DAPM_OUTPUT("OUT_R"), +}; + +static const struct snd_soc_dapm_route generic_dapm_routes[] = { + { "HiFi Playback", NULL, "IN_L" }, + { "HiFi Playback", NULL, "IN_R" }, + + { "OUT_L", NULL, "HiFi Capture" }, + { "OUT_R", NULL, "HiFi Capture" }, +}; + +static struct snd_soc_codec_driver soc_generic_codec = { + .component_driver = { + .dapm_widgets = generic_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(generic_dapm_widgets), + .dapm_routes = generic_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(generic_dapm_routes), + }, +}; + +static int generic_codec_dev_probe(struct platform_device *pdev) +{ + int ret; + ret = snd_soc_register_codec(&pdev->dev, &soc_generic_codec, &generic_dai, 1); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to register generic codec: %d\n", ret); + return ret; + } + + dev_err(&pdev->dev, "Registered generic codec\n"); + return 0; +} + +static int generic_codec_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_codec(&pdev->dev); + return 0; +} + +static const struct of_device_id generic_codec_of_match[] = { + { .compatible = "generic-codec", }, + {}, +}; +MODULE_DEVICE_TABLE(of, generic_codec_of_match); + +static struct platform_driver generic_codec_driver = { + .driver = { + .name = "generic-codec", + .of_match_table = of_match_ptr(generic_codec_of_match), + }, + .probe = generic_codec_dev_probe, + .remove = generic_codec_dev_remove, +}; + +module_platform_driver(generic_codec_driver); + +MODULE_DESCRIPTION("Generic codec driver"); +MODULE_AUTHOR("Robbe Derks "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:generic-codec"); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b76176127ba2..770d6a33f774 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -974,14 +974,16 @@ struct snd_soc_dai *snd_soc_find_dai( if (!component_of_node && component->dev->parent) component_of_node = component->dev->parent->of_node; - if (dlc->of_node && component_of_node != dlc->of_node) + if (dlc->of_node && component_of_node != dlc->of_node) { continue; - if (dlc->name && strcmp(component->name, dlc->name)) + } + if (dlc->name && strcmp(component->name, dlc->name)) { continue; + } list_for_each_entry(dai, &component->dai_list, list) { - if (dlc->dai_name && strcmp(dai->name, dlc->dai_name)) + if (dlc->dai_name && strcmp(dai->name, dlc->dai_name)){ continue; - + } return dai; } } diff --git a/techpack/audio/asoc/sdm845.c b/techpack/audio/asoc/sdm845.c index 9e8b43da7299..100687b2d710 100644 --- a/techpack/audio/asoc/sdm845.c +++ b/techpack/audio/asoc/sdm845.c @@ -3922,11 +3922,11 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) //tavil_codec_info_create_codec_entry(pdata->codec_root, codec); // enable mclk - mclk = clk_get(codec->dev, "mclk"); - if (IS_ERR(mclk)) { + mclk = clk_get(codec->dev, "mclk"); + if (IS_ERR(mclk)) { return -1; } - + ret = clk_prepare_enable(mclk); if (ret) { return -1; @@ -5945,7 +5945,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .platform_name = "msm-pcm-routing", /*.codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-rx",*/ - .codec_name = "max98088.0-0010", + .codec_name = "vendor:generic-codec", .codec_dai_name = "HiFi", .no_pcm = 1, .dpcm_playback = 1, @@ -5963,7 +5963,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .platform_name = "msm-pcm-routing", /*.codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-tx",*/ - .codec_name = "max98088.0-0010", + .codec_name = "vendor:generic-codec", .codec_dai_name = "HiFi", .no_pcm = 1, .dpcm_capture = 1, @@ -5972,7 +5972,6 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .ops = &msm_mi2s_be_ops, .ignore_suspend = 1, }, - // max98088 is connected here! { .name = LPASS_BE_TERT_MI2S_RX, .stream_name = "Tertiary MI2S Playback", @@ -5980,7 +5979,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .platform_name = "msm-pcm-routing", /*.codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-rx",*/ - .codec_name = "max98088.0-0010", + .codec_name = "vendor:generic-codec", .codec_dai_name = "HiFi", .no_pcm = 1, .dpcm_playback = 1, @@ -5997,7 +5996,7 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = { .platform_name = "msm-pcm-routing", /*.codec_name = "msm-stub-codec.1", .codec_dai_name = "msm-stub-tx",*/ - .codec_name = "max98088.0-0010", + .codec_name = "vendor:generic-codec", .codec_dai_name = "HiFi", .no_pcm = 1, .dpcm_capture = 1, diff --git a/techpack/audio/dsp/q6afe.c b/techpack/audio/dsp/q6afe.c index aa0287e02c59..5442b98a1299 100644 --- a/techpack/audio/dsp/q6afe.c +++ b/techpack/audio/dsp/q6afe.c @@ -1738,7 +1738,7 @@ static int afe_send_codec_reg_page_config( static int afe_send_codec_reg_config( struct afe_param_cdc_reg_cfg_data *cdc_reg_cfg) { - int i, j, ret = -EINVAL; + int i, j, ret = 0; int pkt_size, payload_size, reg_per_pkt, num_pkts, num_regs; struct afe_svc_cmd_cdc_reg_cfg *config; struct afe_svc_cmd_set_param *param;