@@ -17600,6 +17600,7 @@ ROCKCHIP RK3308 SOUND CARD DRIVER
M: Luca Ceresoli <luca.ceresoli@bootlin.com>
S: Maintained
F: Documentation/devicetree/bindings/sound/rockchip,rk3308-audio-graph-card.yaml
+F: sound/soc/rockchip/rockchip_rk3308_card.c
ROCKCHIP VIDEO DECODER DRIVER
M: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
@@ -45,6 +45,20 @@ config SND_SOC_ROCKCHIP_SPDIF
Say Y or M if you want to add support for SPDIF driver for
Rockchip SPDIF transceiver device.
+config SND_SOC_ROCKCHIP_RK3308_INTERNAL_CODEC
+ tristate "ASoC sound card based on the internal RK3308 codec"
+ depends on HAVE_CLK && SND_SOC_ROCKCHIP
+ depends on SND_AUDIO_GRAPH_CARD
+ select SND_SOC_ROCKCHIP_I2S_TDM
+ select SND_SOC_GENERIC_DMAENGINE_PCM
+ help
+ ASoC sound card driver for the RK3308 internal audio codec.
+
+ The Rockchip RK3308 SoC has a built-in audio codec that is
+ connected internally to one out of a selection of the internal
+ I2S controllers. This driver implements an audio card using these
+ components.
+
config SND_SOC_ROCKCHIP_MAX98090
tristate "ASoC support for Rockchip boards using a MAX98090 codec"
depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK
@@ -15,6 +15,7 @@ snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o
snd-soc-rk3288-hdmi-analog-objs := rk3288_hdmi_analog.o
snd-soc-rk3399-gru-sound-objs := rk3399_gru_sound.o
+obj-$(CONFIG_SND_SOC_ROCKCHIP_RK3308_INTERNAL_CODEC) += rockchip_rk3308_card.o
obj-$(CONFIG_SND_SOC_ROCKCHIP_MAX98090) += snd-soc-rockchip-max98090.o
obj-$(CONFIG_SND_SOC_ROCKCHIP_RT5645) += snd-soc-rockchip-rt5645.o
obj-$(CONFIG_SND_SOC_RK3288_HDMI_ANALOG) += snd-soc-rk3288-hdmi-analog.o
new file mode 100644
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Audio card using the RK3308 internal I2S
+//
+// Allows driving the I2S peripheral with both the RX and TX clocks. This
+// is useful to use the RK3308 internal audio codec.
+//
+// Copyright (c) 2022, Vivax-Metrotech Ltd
+//
+// Based on sound/soc/generic/audio-graph-card.c
+
+#include <linux/module.h>
+#include <linux/of_clk.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <sound/graph_card.h>
+
+static int rk3308_audio_asoc_simple_init_dai(struct snd_soc_dai *dai,
+ struct asoc_simple_dai *simple_dai)
+{
+ const int nclks = 2; /* The sysclks are clk_id 0 and 1 for the RK3308 driver */
+ int err;
+ int i;
+
+ if (!simple_dai || !simple_dai->sysclk)
+ return 0;
+
+ /* Can be extended to get two different sysclk values via device tree */
+ for (i = 0; i < nclks; i++) {
+ err = snd_soc_dai_set_sysclk(dai, i, simple_dai->sysclk,
+ simple_dai->clk_direction);
+ if (err && err != -ENOTSUPP)
+ return dev_err_probe(dai->dev, err, "simple-card: set_sysclk error\n");
+ }
+
+ return 0;
+}
+
+static int rk3308_audio_asoc_simple_dai_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct simple_dai_props *props = simple_priv_to_props(priv, rtd->num);
+ struct asoc_simple_dai *dai;
+ int i, ret;
+
+ for_each_prop_dai_codec(props, i, dai) {
+ ret = rk3308_audio_asoc_simple_init_dai(asoc_rtd_to_codec(rtd, i), dai);
+ if (ret < 0)
+ return ret;
+ }
+ for_each_prop_dai_cpu(props, i, dai) {
+ ret = rk3308_audio_asoc_simple_init_dai(asoc_rtd_to_cpu(rtd, i), dai);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rk3308_audio_graph_probe(struct platform_device *pdev)
+{
+ struct asoc_simple_priv *priv;
+ struct device *dev = &pdev->dev;
+ struct snd_soc_card *card;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ card = simple_priv_to_card(priv);
+ card->driver_name = "rk3308-audio-graph-card";
+ card->probe = asoc_graph_card_probe;
+ priv->init = rk3308_audio_asoc_simple_dai_init;
+
+ return audio_graph_parse_of(priv, dev);
+}
+
+static const struct of_device_id graph_of_rk3308_card_match[] = {
+ { .compatible = "rockchip,rk3308-audio-graph-card" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, graph_of_rk3308_card_match);
+
+static struct platform_driver rk3308_audio_graph_card = {
+ .driver = {
+ .name = "rk3308-audio-graph-card",
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = graph_of_rk3308_card_match,
+ },
+ .probe = rk3308_audio_graph_probe,
+ .remove = asoc_simple_remove,
+};
+module_platform_driver(rk3308_audio_graph_card);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ASoC Audio Graph Card for Rockchip RK3308");
+MODULE_AUTHOR("Luca Ceresoli <luca.ceresoli@bootlin.com>");