From: zhengxing <[email protected]>
Hi,
These patches to add machine driver for rockchip platform.
We intended to use simple-card on the project, but it seem like that have
some issues(jack detection). We need the following features on the project,
but simple-card is temporarily unable to provide them:
1. We need dynamically recognize and select one codec from supported codecs
in dts.
2. Simple-card don't provide to call the codec jack detection callback via dts
description (ts3a227e_enable_jack_detect for max98090, rt5645_set_jack_detect
for rt5645/rt5650).
3. Simple-card support simple-widght only, but codec may use cunstom the name of
widget (rk_dapm_widgets: "Headset Mic", "Int Mic" in max98090).
Simple-card is good generic machine driver, but if we want to replace simple-card
in the exsiting work, it may bring other problems. Therefore, we want to upload
these functions that we need.
zhengxing (4):
ASoC: rockchip: add rockchip machine driver
ASoC: rockchip: add rockchip machine driver for max98090
ASoC: rockchip: add rockchip machine driver for rt5650/rt5645
ASoC: rockchip-audio-machine: add rockchip machine driver bindings
.../sound/rockchip,rockchip-audio-machine.txt | 38 ++++
sound/soc/rockchip/Kconfig | 26 +++
sound/soc/rockchip/Makefile | 9 +
sound/soc/rockchip/rockchip_machine_driver.c | 222 ++++++++++++++++++++
sound/soc/rockchip/rockchip_machine_driver.h | 41 ++++
sound/soc/rockchip/rockchip_max98090.c | 185 ++++++++++++++++
sound/soc/rockchip/rockchip_rt5645.c | 220 +++++++++++++++++++
7 files changed, 741 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/rockchip,rockchip-audio-machine.txt
create mode 100644 sound/soc/rockchip/rockchip_machine_driver.c
create mode 100644 sound/soc/rockchip/rockchip_machine_driver.h
create mode 100644 sound/soc/rockchip/rockchip_max98090.c
create mode 100644 sound/soc/rockchip/rockchip_rt5645.c
--
1.7.9.5
From: zhengxing <[email protected]>
In most cases, we maybe use simple-card as generic machine driver
on next kernel, but there are some issue that jack detection and
widgets extandable on simple-card.
Own machine drvier can select one valid codec from supported codecs,
and add needful function from dts on rockchip platform.
Signed-off-by: zhengxing <[email protected]>
---
sound/soc/rockchip/Kconfig | 7 +
sound/soc/rockchip/Makefile | 5 +
sound/soc/rockchip/rockchip_machine_driver.c | 210 ++++++++++++++++++++++++++
sound/soc/rockchip/rockchip_machine_driver.h | 30 ++++
4 files changed, 252 insertions(+)
create mode 100644 sound/soc/rockchip/rockchip_machine_driver.c
create mode 100644 sound/soc/rockchip/rockchip_machine_driver.h
diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig
index e181826..e3f51cf 100644
--- a/sound/soc/rockchip/Kconfig
+++ b/sound/soc/rockchip/Kconfig
@@ -14,3 +14,10 @@ config SND_SOC_ROCKCHIP_I2S
Say Y or M if you want to add support for I2S driver for
Rockchip I2S device. The device supports upto maximum of
8 channels each for play and record.
+
+config SND_SOC_ROCKCHIP_MACHINE
+ tristate "Rockchip Generic Machine Driver"
+ depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP
+ help
+ Say Y or M if you want to add support for Machine driver
+ for Rockchip I2S device.
diff --git a/sound/soc/rockchip/Makefile b/sound/soc/rockchip/Makefile
index b921909..47d7c84 100644
--- a/sound/soc/rockchip/Makefile
+++ b/sound/soc/rockchip/Makefile
@@ -2,3 +2,8 @@
snd-soc-i2s-objs := rockchip_i2s.o
obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-i2s.o
+
+# ROCKCHIP Machine Support
+snd-soc-rockchip-machine-objs := rockchip_machine_driver.o
+
+obj-$(CONFIG_SND_SOC_ROCKCHIP_MACHINE) += snd-soc-rockchip-machine.o
diff --git a/sound/soc/rockchip/rockchip_machine_driver.c b/sound/soc/rockchip/rockchip_machine_driver.c
new file mode 100644
index 0000000..34cae3f
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_machine_driver.c
@@ -0,0 +1,210 @@
+/*
+ * Rockchip machine ASoC driver for boards for multi-codecs.
+ *
+ * Copyright (c) 2015, ROCKCHIP CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/delay.h>
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "rockchip_i2s.h"
+#include "rockchip_machine_driver.h"
+
+#define DRV_NAME "rockchip-snd-machine"
+
+/* the sound cards of rockchp supports. */
+static struct rk_snd_soc_cards rk_snd_cards[] = {
+};
+
+static int snd_rk_mc_preinit(void)
+{
+ int id, ret;
+
+ for (id = 0; id < ARRAY_SIZE(rk_snd_cards); ++id) {
+ struct rk_snd_soc_cards *rk_snd_card = &rk_snd_cards[id];
+
+ ret = rk_snd_card->preinit(rk_snd_card);
+ if (ret < 0)
+ pr_warn("card: %s preinit failed!\n",
+ rk_snd_card->name);
+ }
+
+ return 0;
+}
+
+static int snd_rk_mc_probe(struct platform_device *pdev)
+{
+ struct rk_mc_private *drv;
+ struct snd_soc_card *card;
+ struct device_node *parent = pdev->dev.of_node;
+ struct device_node *node;
+ int found = 0;
+ int ret;
+
+ /* pre-init sound cards that rockchip supports. */
+ snd_rk_mc_preinit();
+
+ drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
+ if (!drv)
+ return -ENOMEM;
+
+ /* attach matched codec. */
+ for_each_available_child_of_node(parent, node) {
+ int id;
+
+ for (id = 0; id < ARRAY_SIZE(rk_snd_cards); ++id) {
+ struct rk_snd_soc_cards *rk_snd_card =
+ &rk_snd_cards[id];
+
+ ret = of_device_is_compatible(node,
+ rk_snd_card->compatible);
+ if (ret) {
+ /* match compatible. */
+ card = rk_snd_card->card;
+ if (!card || !card->dai_link) {
+ dev_err(&pdev->dev,
+ "card or dai_link is null!\n");
+ continue;
+ }
+
+ card->dev = &pdev->dev;
+ platform_set_drvdata(pdev, card);
+ snd_soc_card_set_drvdata(card, drv);
+
+ /* set dai link node. */
+ card->dai_link->codec_of_node =
+ of_parse_phandle(node,
+ "rockchip,audio-codec",
+ 0);
+ if (!card->dai_link->codec_of_node) {
+ dev_err(&pdev->dev,
+ "rockchip,audio-codec invalid\n");
+ continue;
+ }
+
+ card->dai_link->cpu_of_node =
+ of_parse_phandle(node,
+ "rockchip,i2s-controller",
+ 0);
+ if (!card->dai_link->cpu_of_node) {
+ dev_err(&pdev->dev,
+ "rockchip,i2s-controller invalid\n");
+ continue;
+ }
+
+ if (card->aux_dev) {
+ /* set aux_dev for max98090. */
+ card->aux_dev->codec_of_node =
+ of_parse_phandle(node,
+ "rockchip,headset-codec",
+ 0);
+ if (!card->aux_dev->codec_of_node) {
+ dev_err(&pdev->dev,
+ "rockchip,headset-codec invalid\n");
+ continue;
+ }
+ }
+
+ card->dai_link->platform_of_node =
+ card->dai_link->cpu_of_node;
+
+ ret = snd_soc_of_parse_card_name(card,
+ "rockchip,model");
+ if (ret)
+ continue;
+
+ /* register the soc card. */
+ ret = snd_soc_register_card(card);
+ if (!ret) {
+ /*
+ * register sound card ok,
+ * and found matched codec.
+ */
+ dev_info(&pdev->dev,
+ "card:[%s] register success!\n",
+ card->name);
+
+ found = 1;
+ goto found_codec;
+ } else {
+ /* register sound card failed */
+ dev_err(&pdev->dev,
+ "card:[%s] register failed(%d)!\n",
+ card->name, ret);
+
+ card->dev = NULL;
+ }
+ }
+ }
+ }
+
+ if (!found) {
+ dev_err(&pdev->dev,
+ "Not found matched codec!\n");
+ return -ENODEV;
+ }
+
+found_codec:
+ dev_info(&pdev->dev,
+ "Found matched codec: %s!\n",
+ card->name);
+
+ return 0;
+}
+
+static int snd_rk_mc_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ snd_soc_card_set_drvdata(card, NULL);
+ snd_soc_unregister_card(card);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id rockchip_machine_of_match[] = {
+ { .compatible = "rockchip,rockchip-audio-machine", },
+ {},
+};
+
+static struct platform_driver snd_rk_mc_driver = {
+ .probe = snd_rk_mc_probe,
+ .remove = snd_rk_mc_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = rockchip_machine_of_match,
+ },
+};
+
+module_platform_driver(snd_rk_mc_driver);
+
+MODULE_AUTHOR("Xing Zheng <[email protected]>");
+MODULE_DESCRIPTION("Rockchip general machine ASoC driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, rockchip_machine_of_match);
diff --git a/sound/soc/rockchip/rockchip_machine_driver.h b/sound/soc/rockchip/rockchip_machine_driver.h
new file mode 100644
index 0000000..39a7a77
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_machine_driver.h
@@ -0,0 +1,30 @@
+/*
+ * sound/soc/rockchip/rockchip_machine_driver.h
+ *
+ * ALSA SoC Audio Layer - Rockchip Machine driver
+ *
+ * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
+ * Author: Xing Zheng <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ROCKCHIP_MACHINE_DRIVER_H__
+#define __ROCKCHIP_MACHINE_DRIVER_H__
+
+struct rk_mc_private {
+ struct snd_soc_jack headphone_jack;
+ struct snd_soc_jack mic_jack;
+ struct snd_soc_jack btn_jack;
+};
+
+struct rk_snd_soc_cards {
+ char name[32];
+ char compatible[128];
+ struct snd_soc_card *card;
+ int (*preinit)(struct rk_snd_soc_cards *soc_card);
+};
+
+#endif /* __ROCKCHIP_MACHINE_DRIVER_H__ */
--
1.7.9.5
From: zhengxing <[email protected]>
The driver is used for rockchip board using a max98090.
Test on RK3288 with max98090.
Signed-off-by: zhengxing <[email protected]>
---
sound/soc/rockchip/Kconfig | 10 ++
sound/soc/rockchip/Makefile | 2 +
sound/soc/rockchip/rockchip_machine_driver.c | 6 +
sound/soc/rockchip/rockchip_machine_driver.h | 6 +
sound/soc/rockchip/rockchip_max98090.c | 185 ++++++++++++++++++++++++++
5 files changed, 209 insertions(+)
create mode 100644 sound/soc/rockchip/rockchip_max98090.c
diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig
index e3f51cf..057c457 100644
--- a/sound/soc/rockchip/Kconfig
+++ b/sound/soc/rockchip/Kconfig
@@ -21,3 +21,13 @@ config SND_SOC_ROCKCHIP_MACHINE
help
Say Y or M if you want to add support for Machine driver
for Rockchip I2S device.
+
+config SND_SOC_ROCKCHIP_MAX98090
+ tristate "ASoC support for Rockchip boards using a MAX98090 codec"
+ depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB
+ select SND_SOC_ROCKCHIP_I2S
+ select SND_SOC_MAX98090
+ select SND_SOC_TS3A227E
+ help
+ Say Y or M here if you want to add support for SoC audio on Rockchip
+ boards using the MAX98090 codec, such as Veyron.
diff --git a/sound/soc/rockchip/Makefile b/sound/soc/rockchip/Makefile
index 47d7c84..23e9b64 100644
--- a/sound/soc/rockchip/Makefile
+++ b/sound/soc/rockchip/Makefile
@@ -5,5 +5,7 @@ obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-i2s.o
# ROCKCHIP Machine Support
snd-soc-rockchip-machine-objs := rockchip_machine_driver.o
+snd-soc-rockchip-max98090-objs := rockchip_max98090.o
obj-$(CONFIG_SND_SOC_ROCKCHIP_MACHINE) += snd-soc-rockchip-machine.o
+obj-$(CONFIG_SND_SOC_ROCKCHIP_MAX98090) += snd-soc-rockchip-max98090.o
diff --git a/sound/soc/rockchip/rockchip_machine_driver.c b/sound/soc/rockchip/rockchip_machine_driver.c
index 34cae3f..ee09c62 100644
--- a/sound/soc/rockchip/rockchip_machine_driver.c
+++ b/sound/soc/rockchip/rockchip_machine_driver.c
@@ -36,6 +36,12 @@
/* the sound cards of rockchp supports. */
static struct rk_snd_soc_cards rk_snd_cards[] = {
+#ifdef CONFIG_SND_SOC_ROCKCHIP_MAX98090
+ {
+ .name = RK_SND_CARD_MAX98090,
+ .preinit = rk_machine_preinit_max98090,
+ },
+#endif
};
static int snd_rk_mc_preinit(void)
diff --git a/sound/soc/rockchip/rockchip_machine_driver.h b/sound/soc/rockchip/rockchip_machine_driver.h
index 39a7a77..903ed94 100644
--- a/sound/soc/rockchip/rockchip_machine_driver.h
+++ b/sound/soc/rockchip/rockchip_machine_driver.h
@@ -27,4 +27,10 @@ struct rk_snd_soc_cards {
int (*preinit)(struct rk_snd_soc_cards *soc_card);
};
+/* the sound cards of rockchp supports. */
+#ifdef CONFIG_SND_SOC_ROCKCHIP_MAX98090
+#define RK_SND_CARD_MAX98090 "rk_snd_max98090"
+int rk_machine_preinit_max98090(struct rk_snd_soc_cards *soc_card);
+#endif
+
#endif /* __ROCKCHIP_MACHINE_DRIVER_H__ */
diff --git a/sound/soc/rockchip/rockchip_max98090.c b/sound/soc/rockchip/rockchip_max98090.c
new file mode 100644
index 0000000..f56dc69c
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_max98090.c
@@ -0,0 +1,185 @@
+/*
+ * Rockchip machine ASoC driver for boards using a MAX90809 CODEC.
+ *
+ * Copyright (c) 2014, ROCKCHIP CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "rockchip_i2s.h"
+#include "../codecs/ts3a227e.h"
+#include "rockchip_machine_driver.h"
+
+static const struct snd_soc_dapm_widget rk_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Int Mic", NULL),
+ SND_SOC_DAPM_SPK("Speaker", NULL),
+};
+
+static const struct snd_soc_dapm_route rk_audio_map[] = {
+ {"IN34", NULL, "Headset Mic"},
+ {"IN34", NULL, "MICBIAS"},
+ {"MICBIAS", NULL, "Headset Mic"},
+ {"DMICL", NULL, "Int Mic"},
+ {"Headphone", NULL, "HPL"},
+ {"Headphone", NULL, "HPR"},
+ {"Speaker", NULL, "SPKL"},
+ {"Speaker", NULL, "SPKR"},
+};
+
+static const struct snd_kcontrol_new rk_mc_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+ SOC_DAPM_PIN_SWITCH("Int Mic"),
+ SOC_DAPM_PIN_SWITCH("Speaker"),
+};
+
+static int rk_aif1_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int mclk;
+
+ switch (params_rate(params)) {
+ case 48000:
+ mclk = 12288000;
+ break;
+ case 44100:
+ mclk = 11289600;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
+ SND_SOC_CLOCK_OUT);
+ if (ret < 0) {
+ dev_err(codec_dai->dev, "Can't set codec clock %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
+ SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(codec_dai->dev, "Can't set codec clock %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int rk_init(struct snd_soc_pcm_runtime *runtime)
+{
+ struct snd_soc_codec *codec = runtime->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ struct snd_soc_card *card = runtime->card;
+ struct rk_mc_private *drv = snd_soc_card_get_drvdata(card);
+
+ card->dapm.idle_bias_off = true;
+
+ snd_soc_dapm_enable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_enable_pin(dapm, "Headphone");
+ snd_soc_dapm_enable_pin(dapm, "Speaker");
+ snd_soc_dapm_enable_pin(dapm, "Int Mic");
+
+ snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
+
+ snd_soc_dapm_sync(dapm);
+
+ /* Enable headphone jack detection */
+ return snd_soc_card_jack_new(card, "Headset Jack",
+ SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3,
+ &drv->headphone_jack,
+ NULL,
+ 0);
+}
+
+static int rk_98090_headset_init(struct snd_soc_component *component)
+{
+ struct snd_soc_card *card = component->card;
+ struct rk_mc_private *drv = snd_soc_card_get_drvdata(card);
+
+ return ts3a227e_enable_jack_detect(component, &drv->headphone_jack);
+}
+
+static struct snd_soc_ops rk_aif1_ops = {
+ .hw_params = rk_aif1_hw_params,
+};
+
+static struct snd_soc_aux_dev rk_98090_headset_dev = {
+ .name = "Headset Chip",
+ .init = rk_98090_headset_init,
+};
+
+static struct snd_soc_dai_link rk_dailink = {
+ .name = "max98090",
+ .stream_name = "Audio",
+ .codec_dai_name = "HiFi",
+ .init = rk_init,
+ .ops = &rk_aif1_ops,
+ /* set max98090 as slave */
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+};
+
+/* rockchip machine driver for max98090 */
+static struct snd_soc_card snd_soc_card_rk = {
+ .name = "ROCKCHIP-I2S",
+ .dai_link = &rk_dailink,
+ .num_links = 1,
+ .aux_dev = &rk_98090_headset_dev,
+ .num_aux_devs = 1,
+ .dapm_widgets = rk_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(rk_dapm_widgets),
+ .dapm_routes = rk_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(rk_audio_map),
+ .controls = rk_mc_controls,
+ .num_controls = ARRAY_SIZE(rk_mc_controls),
+};
+
+int rk_machine_preinit_max98090(struct rk_snd_soc_cards *soc_card)
+{
+ if (soc_card && !strcmp(soc_card->name, RK_SND_CARD_MAX98090)) {
+ /* pre-init snd card info. */
+ soc_card->card = &snd_soc_card_rk;
+ strcpy(soc_card->compatible,
+ "rockchip,rockchip-audio-max98090");
+
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
+MODULE_AUTHOR("jianqun <[email protected]>");
+MODULE_AUTHOR("Xing Zheng <[email protected]>");
+MODULE_DESCRIPTION("Rockchip max98090 machine ASoC driver");
+MODULE_LICENSE("GPL v2");
--
1.7.9.5
From: zhengxing <[email protected]>
The driver is used for rockchip board using a rt5650/rt5645.
Test on RK3288 with rt5650.
Signed-off-by: zhengxing <[email protected]>
---
sound/soc/rockchip/Kconfig | 9 ++
sound/soc/rockchip/Makefile | 2 +
sound/soc/rockchip/rockchip_machine_driver.c | 6 +
sound/soc/rockchip/rockchip_machine_driver.h | 5 +
sound/soc/rockchip/rockchip_rt5645.c | 220 ++++++++++++++++++++++++++
5 files changed, 242 insertions(+)
create mode 100644 sound/soc/rockchip/rockchip_rt5645.c
diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig
index 057c457..bdf5ded 100644
--- a/sound/soc/rockchip/Kconfig
+++ b/sound/soc/rockchip/Kconfig
@@ -31,3 +31,12 @@ config SND_SOC_ROCKCHIP_MAX98090
help
Say Y or M here if you want to add support for SoC audio on Rockchip
boards using the MAX98090 codec, such as Veyron.
+
+config SND_SOC_ROCKCHIP_RT5645
+ tristate "ASoC support for Rockchip boards using a RT5645/RT5650 codec"
+ depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB
+ select SND_SOC_ROCKCHIP_I2S
+ select SND_SOC_RT5645
+ help
+ Say Y or M here if you want to add support for SoC audio on Rockchip
+ boards using the RT5645/RT5650 codec, such as Veyron.
diff --git a/sound/soc/rockchip/Makefile b/sound/soc/rockchip/Makefile
index 23e9b64..099732d 100644
--- a/sound/soc/rockchip/Makefile
+++ b/sound/soc/rockchip/Makefile
@@ -6,6 +6,8 @@ obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-i2s.o
# ROCKCHIP Machine Support
snd-soc-rockchip-machine-objs := rockchip_machine_driver.o
snd-soc-rockchip-max98090-objs := rockchip_max98090.o
+snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o
obj-$(CONFIG_SND_SOC_ROCKCHIP_MACHINE) += snd-soc-rockchip-machine.o
obj-$(CONFIG_SND_SOC_ROCKCHIP_MAX98090) += snd-soc-rockchip-max98090.o
+obj-$(CONFIG_SND_SOC_ROCKCHIP_RT5645) += snd-soc-rockchip-rt5645.o
diff --git a/sound/soc/rockchip/rockchip_machine_driver.c b/sound/soc/rockchip/rockchip_machine_driver.c
index ee09c62..7807d4e 100644
--- a/sound/soc/rockchip/rockchip_machine_driver.c
+++ b/sound/soc/rockchip/rockchip_machine_driver.c
@@ -36,6 +36,12 @@
/* the sound cards of rockchp supports. */
static struct rk_snd_soc_cards rk_snd_cards[] = {
+#ifdef CONFIG_SND_SOC_ROCKCHIP_RT5645
+ {
+ .name = RK_SND_CARD_RT5645,
+ .preinit = rk_machine_preinit_rt5645,
+ },
+#endif
#ifdef CONFIG_SND_SOC_ROCKCHIP_MAX98090
{
.name = RK_SND_CARD_MAX98090,
diff --git a/sound/soc/rockchip/rockchip_machine_driver.h b/sound/soc/rockchip/rockchip_machine_driver.h
index 903ed94..f4fd74e 100644
--- a/sound/soc/rockchip/rockchip_machine_driver.h
+++ b/sound/soc/rockchip/rockchip_machine_driver.h
@@ -28,6 +28,11 @@ struct rk_snd_soc_cards {
};
/* the sound cards of rockchp supports. */
+#ifdef CONFIG_SND_SOC_ROCKCHIP_RT5645
+#define RK_SND_CARD_RT5645 "rk_snd_rt5645"
+int rk_machine_preinit_rt5645(struct rk_snd_soc_cards *soc_card);
+#endif
+
#ifdef CONFIG_SND_SOC_ROCKCHIP_MAX98090
#define RK_SND_CARD_MAX98090 "rk_snd_max98090"
int rk_machine_preinit_max98090(struct rk_snd_soc_cards *soc_card);
diff --git a/sound/soc/rockchip/rockchip_rt5645.c b/sound/soc/rockchip/rockchip_rt5645.c
new file mode 100644
index 0000000..e2b8774
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_rt5645.c
@@ -0,0 +1,220 @@
+/*
+ * Rockchip machine ASoC driver for boards using a RT5645/RT5650 CODEC.
+ *
+ * Copyright (c) 2015, ROCKCHIP CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/delay.h>
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "rockchip_i2s.h"
+#include "rockchip_machine_driver.h"
+
+/* Jack detect via rt5645 driver. */
+extern int rt5645_set_jack_detect(struct snd_soc_codec *codec,
+ struct snd_soc_jack *hp_jack,
+ struct snd_soc_jack *mic_jack,
+ struct snd_soc_jack *btn_jack);
+
+/* For compatible. */
+int __weak rt5645_set_jack_detect(struct snd_soc_codec *codec,
+ struct snd_soc_jack *hp_jack,
+ struct snd_soc_jack *mic_jack,
+ struct snd_soc_jack *btn_jack)
+{
+ dev_warn(codec->dev, "Jack detect dummy, have no implement it?\n");
+
+ return 0;
+}
+
+static const struct snd_soc_dapm_widget rk_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Headphones", NULL),
+ SND_SOC_DAPM_SPK("Speakers", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Int Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route rk_audio_map[] = {
+ /* Input Lines */
+ {"DMIC L2", NULL, "Int Mic"},
+ {"DMIC R2", NULL, "Int Mic"},
+ {"RECMIXL", NULL, "Headset Mic"},
+ {"RECMIXR", NULL, "Headset Mic"},
+
+ /* Output Lines */
+ {"Headphones", NULL, "HPOR"},
+ {"Headphones", NULL, "HPOL"},
+ {"Speakers", NULL, "SPOL"},
+ {"Speakers", NULL, "SPOR"},
+};
+
+static const struct snd_kcontrol_new rk_mc_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphones"),
+ SOC_DAPM_PIN_SWITCH("Speakers"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+ SOC_DAPM_PIN_SWITCH("Int Mic"),
+};
+
+static int rk_aif1_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int mclk;
+
+ switch (params_rate(params)) {
+ case 48000:
+ mclk = 12288000;
+ break;
+ case 44100:
+ mclk = 11289600;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
+ SND_SOC_CLOCK_OUT);
+ if (ret < 0) {
+ dev_err(codec_dai->dev, "Can't set codec clock %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
+ SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(codec_dai->dev, "Can't set codec clock %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int rk_init(struct snd_soc_pcm_runtime *runtime)
+{
+ int ret = 0;
+ struct snd_soc_codec *codec = runtime->codec;
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ struct snd_soc_card *card = runtime->card;
+ struct rk_mc_private *drv = snd_soc_card_get_drvdata(card);
+
+ card->dapm.idle_bias_off = true;
+
+ snd_soc_dapm_enable_pin(dapm, "Headphones");
+ snd_soc_dapm_enable_pin(dapm, "Speakers");
+ snd_soc_dapm_enable_pin(dapm, "Headset Mic");
+ snd_soc_dapm_enable_pin(dapm, "Int Mic");
+
+ snd_soc_dapm_sync(dapm);
+
+ /* Enable Headset and 4 Buttons Jack detection */
+ ret = snd_soc_card_jack_new(card, "Headphone Jack",
+ SND_JACK_HEADPHONE | SND_JACK_MICROPHONE,
+ &drv->headphone_jack,
+ NULL,
+ 0);
+ if (ret < 0) {
+ dev_err(codec->dev, "Can't new Headphone Jack: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_card_jack_new(card, "Mic Jack",
+ SND_JACK_HEADPHONE | SND_JACK_MICROPHONE,
+ &drv->mic_jack,
+ NULL,
+ 0);
+ if (ret < 0) {
+ dev_err(codec->dev, "Can't new Mic Jack: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_card_jack_new(card, "Button Jack",
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3,
+ &drv->btn_jack,
+ NULL,
+ 0);
+ if (ret < 0) {
+ dev_err(codec->dev, "Can't new Button Jack: %d\n", ret);
+ return ret;
+ }
+
+ ret = rt5645_set_jack_detect(codec, &drv->headphone_jack,
+ &drv->mic_jack, &drv->btn_jack);
+ if (ret < 0) {
+ dev_err(codec->dev, "Set jack detect failed: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct snd_soc_ops rk_aif1_ops = {
+ .hw_params = rk_aif1_hw_params,
+};
+
+static struct snd_soc_dai_link rk_dailink = {
+ .name = "rt5645",
+ .stream_name = "rt5645 PCM",
+ .codec_dai_name = "rt5645-aif1",
+ .init = rk_init,
+ .ops = &rk_aif1_ops,
+ /* set rt5645 as slave */
+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBS_CFS,
+};
+
+/* rockchip machine driver for rt5650/rt5645 */
+static struct snd_soc_card snd_soc_card_rk = {
+ .name = "I2S-RT5650",
+ .dai_link = &rk_dailink,
+ .num_links = 1,
+ .dapm_widgets = rk_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(rk_dapm_widgets),
+ .dapm_routes = rk_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(rk_audio_map),
+ .controls = rk_mc_controls,
+ .num_controls = ARRAY_SIZE(rk_mc_controls),
+};
+
+int rk_machine_preinit_rt5645(struct rk_snd_soc_cards *soc_card)
+{
+ if (soc_card && !strcmp(soc_card->name, RK_SND_CARD_RT5645)) {
+ /* pre-init snd card info. */
+ soc_card->card = &snd_soc_card_rk;
+ strcpy(soc_card->compatible,
+ "rockchip,rockchip-audio-rt5645");
+
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
+MODULE_AUTHOR("Xing Zheng <[email protected]>");
+MODULE_DESCRIPTION("Rockchip rt5645 machine ASoC driver");
+MODULE_LICENSE("GPL v2");
--
1.7.9.5
From: zhengxing <[email protected]>
Add documentation to the machine driver of the device-tree
bindings for the soundcard of the Rockchip board.
Signed-off-by: zhengxing <[email protected]>
---
.../sound/rockchip,rockchip-audio-machine.txt | 38 ++++++++++++++++++++
1 file changed, 38 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/rockchip,rockchip-audio-machine.txt
diff --git a/Documentation/devicetree/bindings/sound/rockchip,rockchip-audio-machine.txt b/Documentation/devicetree/bindings/sound/rockchip,rockchip-audio-machine.txt
new file mode 100644
index 0000000..36864fd
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rockchip,rockchip-audio-machine.txt
@@ -0,0 +1,38 @@
+ROCKCHIP rk3288 audio complex, with AUDIO CODEC
+
+Required properties:
+- (machine) compatible : "rockchip,rockchip-audio-machine"
+- (codec) compatible : The child node name of compatible.
+- rockchip,model : The user-visible name of this sound complex.
+
+- rockchip,i2s-controller : The phandle of the Rockchip I2S controller that's
+ connected to the CODEC.
+- rockchip,audio-codec : The phandle of the audio codec.
+- rockchip,headset-codec : The phandle of the jack detection ic.
+
+Optional properties:
+- rockchip,hp-det-gpios : The GPIO that detect headphones are plugged in
+- rockchip,mic-det-gpios : The GPIO that detect microphones are plugged in
+
+Example:
+
+sound {
+ compatible = "rockchip,rockchip-audio-machine";
+
+ /* child node */
+ sound_rtl {
+ compatible = "rockchip,rockchip-audio-rt5645";
+ rockchip,model = "I2S-RT5650";
+ rockchip,i2s-controller = <&i2s>;
+ rockchip,audio-codec = <&rt5645>;
+ };
+
+ /* child node */
+ sound_maxim {
+ compatible = "rockchip,rockchip-audio-max98090";
+ rockchip,model = "ROCKCHIP-I2S";
+ rockchip,i2s-controller = <&i2s>;
+ rockchip,audio-codec = <&max98090>;
+ rockchip,headset-codec = <&headsetcodec>;
+ };
+};
\ No newline at end of file
--
1.7.9.5
On Tue, May 12, 2015 at 05:26:34PM +0800, Xing Zheng wrote:
> From: zhengxing <[email protected]>
>
> In most cases, we maybe use simple-card as generic machine driver
> on next kernel, but there are some issue that jack detection and
> widgets extandable on simple-card.
>
> Own machine drvier can select one valid codec from supported codecs,
> and add needful function from dts on rockchip platform.
Is it not possible to extend simple card to handle your use cases?
Given the very generic naming and the fact that things like jack
detection and so on should depend on the CODEC and board usually rather
than on the SoC it doesn't sound like this is Rockchip specific.
This also looks like you're reimplementing some device model enumeration
stuff which probably shouldn't be happening but let's understand the
problem you're trying to solve here before going too far into the code.
On Tue, May 12, 2015 at 05:26:35PM +0800, Xing Zheng wrote:
> sound/soc/rockchip/Kconfig | 10 ++
> sound/soc/rockchip/Makefile | 2 +
> sound/soc/rockchip/rockchip_machine_driver.c | 6 +
> sound/soc/rockchip/rockchip_machine_driver.h | 6 +
> sound/soc/rockchip/rockchip_max98090.c | 185 ++++++++++++++++++++++++++
This looks more like a normal and reasonable machine driver but then why
have you created the generic rockchip machine driver? It seems like
this should just be a regular machine driver like other platforms have,
were it not for that this would be mostly fine apart from a couple of
nitpicks below.
> +config SND_SOC_ROCKCHIP_MAX98090
> + tristate "ASoC support for Rockchip boards using a MAX98090 codec"
> + depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB
> + select SND_SOC_ROCKCHIP_I2S
> + select SND_SOC_MAX98090
> + select SND_SOC_TS3A227E
This looks like it's a driver specific to Chromebooks (possibly even
specific Chromeooks) and so should be named as such.
> + card->dapm.idle_bias_off = true;
Just set this when declaring the card, don't do it at runtime.
> + snd_soc_dapm_enable_pin(dapm, "Headset Mic");
> + snd_soc_dapm_enable_pin(dapm, "Headphone");
> + snd_soc_dapm_enable_pin(dapm, "Speaker");
> + snd_soc_dapm_enable_pin(dapm, "Int Mic");
No need to do this, all pins are enabled by default.
> + snd_soc_dapm_sync(dapm);
This has no effect during initialization.
On Tue, May 12, 2015 at 05:26:36PM +0800, Xing Zheng wrote:
> From: zhengxing <[email protected]>
>
> The driver is used for rockchip board using a rt5650/rt5645.
> Test on RK3288 with rt5650.
Similar comments to the Maxim driver plus...
> +/* Jack detect via rt5645 driver. */
> +extern int rt5645_set_jack_detect(struct snd_soc_codec *codec,
> + struct snd_soc_jack *hp_jack,
> + struct snd_soc_jack *mic_jack,
> + struct snd_soc_jack *btn_jack);
> +
> +/* For compatible. */
> +int __weak rt5645_set_jack_detect(struct snd_soc_codec *codec,
> + struct snd_soc_jack *hp_jack,
> + struct snd_soc_jack *mic_jack,
> + struct snd_soc_jack *btn_jack)
> +{
> + dev_warn(codec->dev, "Jack detect dummy, have no implement it?\n");
> +
> + return 0;
> +}
Don't do this - if the functionality isn't there in the CODEC driver get
it implemented before you use it. Make sure you're using the API the
CODEC actually ends up exporting.
> + /* Enable Headset and 4 Buttons Jack detection */
> + ret = snd_soc_card_jack_new(card, "Headphone Jack",
> + SND_JACK_HEADPHONE | SND_JACK_MICROPHONE,
> + ret = snd_soc_card_jack_new(card, "Mic Jack",
> +
> + ret = snd_soc_card_jack_new(card, "Button Jack",
No, don't do this - as discussed in another Chromebook review (I'm
guessing this is a Chromebook) the jacks should represent the physical
jacks in the system. It's possible you have separate headphone and
microphone jacks but I really expect microphone and button to be on the
same socket.
On 2015年05月13日 03:22, Mark Brown wrote:
> On Tue, May 12, 2015 at 05:26:34PM +0800, Xing Zheng wrote:
>> From: zhengxing<[email protected]>
>>
>> In most cases, we maybe use simple-card as generic machine driver
>> on next kernel, but there are some issue that jack detection and
>> widgets extandable on simple-card.
>>
>> Own machine drvier can select one valid codec from supported codecs,
>> and add needful function from dts on rockchip platform.
> Is it not possible to extend simple card to handle your use cases?
> Given the very generic naming and the fact that things like jack
> detection and so on should depend on the CODEC and board usually rather
> than on the SoC it doesn't sound like this is Rockchip specific.
>
> This also looks like you're reimplementing some device model enumeration
> stuff which probably shouldn't be happening but let's understand the
> problem you're trying to solve here before going too far into the code.
Dear Mark,
Thanks for your reply.
Because we are trying to bring rt5650 in the project, so we intend to
describe supported codecs with DTS via only a rockchip machine driver file,
others remain pre-implement(like max98090 / rt5645 that vendor machine
driver).
I communicated with Dylan, and he told me that the jack detection is an
issue in the simple-card, and suggested we are better to send them at
present.
Thanks.
On 2015年05月13日 03:26, Mark Brown wrote:
> On Tue, May 12, 2015 at 05:26:35PM +0800, Xing Zheng wrote:
>
>> sound/soc/rockchip/Kconfig | 10 ++
>> sound/soc/rockchip/Makefile | 2 +
>> sound/soc/rockchip/rockchip_machine_driver.c | 6 +
>> sound/soc/rockchip/rockchip_machine_driver.h | 6 +
>> sound/soc/rockchip/rockchip_max98090.c | 185 ++++++++++++++++++++++++++
> This looks more like a normal and reasonable machine driver but then why
> have you created the generic rockchip machine driver? It seems like
> this should just be a regular machine driver like other platforms have,
> were it not for that this would be mostly fine apart from a couple of
> nitpicks below.
We just use rockchip_machine_driver to describe the supported codecs base on
origianl way, vendor machine driver(rockchip_max98090) will achieve
functions.
>> +config SND_SOC_ROCKCHIP_MAX98090
>> + tristate "ASoC support for Rockchip boards using a MAX98090 codec"
>> + depends on SND_SOC_ROCKCHIP&& I2C&& GPIOLIB
>> + select SND_SOC_ROCKCHIP_I2S
>> + select SND_SOC_MAX98090
>> + select SND_SOC_TS3A227E
> This looks like it's a driver specific to Chromebooks (possibly even
> specific Chromeooks) and so should be named as such.
>
>> + card->dapm.idle_bias_off = true;
> Just set this when declaring the card, don't do it at runtime.
Thanks, I got it.
>> + snd_soc_dapm_enable_pin(dapm, "Headset Mic");
>> + snd_soc_dapm_enable_pin(dapm, "Headphone");
>> + snd_soc_dapm_enable_pin(dapm, "Speaker");
>> + snd_soc_dapm_enable_pin(dapm, "Int Mic");
> No need to do this, all pins are enabled by default.
Yes, I got it.
>> + snd_soc_dapm_sync(dapm);
> This has no effect during initialization.
Yes, I got it.
On Wed, May 13, 2015 at 09:23:01PM +0800, zhengxing wrote:
> On 2015年05月13日 03:22, Mark Brown wrote:
> >Is it not possible to extend simple card to handle your use cases?
> >Given the very generic naming and the fact that things like jack
> >detection and so on should depend on the CODEC and board usually rather
> >than on the SoC it doesn't sound like this is Rockchip specific.
> >This also looks like you're reimplementing some device model enumeration
> >stuff which probably shouldn't be happening but let's understand the
> >problem you're trying to solve here before going too far into the code.
> Because we are trying to bring rt5650 in the project, so we intend to
> describe supported codecs with DTS via only a rockchip machine driver file,
> others remain pre-implement(like max98090 / rt5645 that vendor machine
> driver).
I don't undertand what you're saying here, sorry - why is this not just
a case of writing multiple machine drivers?
> I communicated with Dylan, and he told me that the jack detection is an
> issue in the simple-card, and suggested we are better to send them at
> present.
But what are these issues?
On Wed, May 13, 2015 at 09:23:20PM +0800, zhengxing wrote:
> On 2015年05月13日 03:26, Mark Brown wrote:
> >This looks more like a normal and reasonable machine driver but then why
> >have you created the generic rockchip machine driver? It seems like
> >this should just be a regular machine driver like other platforms have,
> >were it not for that this would be mostly fine apart from a couple of
> >nitpicks below.
> We just use rockchip_machine_driver to describe the supported codecs base on
> origianl way, vendor machine driver(rockchip_max98090) will achieve
> functions.
Like I said in reply to the other message I just don't understand what
you're saying here - take a look at the various Tegra machine drivers
for example, they also have per-CODEC handling but they just use normal
machine drivers to do it.
On Wed, May 13, 2015 at 9:42 AM, Mark Brown <[email protected]> wrote:
> On Wed, May 13, 2015 at 09:23:01PM +0800, zhengxing wrote:
>> On 2015年05月13日 03:22, Mark Brown wrote:
>
>> >Is it not possible to extend simple card to handle your use cases?
>> >Given the very generic naming and the fact that things like jack
>> >detection and so on should depend on the CODEC and board usually rather
>> >than on the SoC it doesn't sound like this is Rockchip specific.
>
>> >This also looks like you're reimplementing some device model enumeration
>> >stuff which probably shouldn't be happening but let's understand the
>> >problem you're trying to solve here before going too far into the code.
>
>> Because we are trying to bring rt5650 in the project, so we intend to
>> describe supported codecs with DTS via only a rockchip machine driver file,
>> others remain pre-implement(like max98090 / rt5645 that vendor machine
>> driver).
>
> I don't undertand what you're saying here, sorry - why is this not just
> a case of writing multiple machine drivers?
I don't understand this either. I'd think the best solution is
simple-card, configured through DTS for each device.
>
>> I communicated with Dylan, and he told me that the jack detection is an
>> issue in the simple-card, and suggested we are better to send them at
>> present.
>
> But what are these issues?
The issue I was referring to when I spoke with rock chip was the need
to pass the jack simple-card creates to the headset chip or codec. We
need a way to specify a device like a tsa227e or rt5650 to pass the
jack to, which events are supported by the jack, and a generic API for
passing the jack.
On Wed, May 13, 2015 at 10:21 AM, Dylan Reid <[email protected]> wrote:
> On Wed, May 13, 2015 at 9:42 AM, Mark Brown <[email protected]> wrote:
>> On Wed, May 13, 2015 at 09:23:01PM +0800, zhengxing wrote:
>>> On 2015年05月13日 03:22, Mark Brown wrote:
>>
>>> >Is it not possible to extend simple card to handle your use cases?
>>> >Given the very generic naming and the fact that things like jack
>>> >detection and so on should depend on the CODEC and board usually rather
>>> >than on the SoC it doesn't sound like this is Rockchip specific.
>>
>>> >This also looks like you're reimplementing some device model enumeration
>>> >stuff which probably shouldn't be happening but let's understand the
>>> >problem you're trying to solve here before going too far into the code.
>>
>>> Because we are trying to bring rt5650 in the project, so we intend to
>>> describe supported codecs with DTS via only a rockchip machine driver file,
>>> others remain pre-implement(like max98090 / rt5645 that vendor machine
>>> driver).
>>
>> I don't undertand what you're saying here, sorry - why is this not just
>> a case of writing multiple machine drivers?
>
> I don't understand this either. I'd think the best solution is
> simple-card, configured through DTS for each device.
>
>>
>>> I communicated with Dylan, and he told me that the jack detection is an
>>> issue in the simple-card, and suggested we are better to send them at
>>> present.
>>
>> But what are these issues?
>
> The issue I was referring to when I spoke with rock chip was the need
> to pass the jack simple-card creates to the headset chip or codec. We
> need a way to specify a device like a tsa227e or rt5650 to pass the
> jack to, which events are supported by the jack, and a generic API for
> passing the jack.
I'm having some trouble envisioning how to pass the jack to the
headset chip in a generic way. A callback could be added to
snd_soc_component_driver, or a snd_soc_headset_driver could be added.
The headset_drive would fit the ts3a227e well, but not the rt5645
which is also a full blown codec.
On 2015年05月14日 07:11, Dylan Reid wrote:
> On Wed, May 13, 2015 at 10:21 AM, Dylan Reid<[email protected]> wrote:
>> On Wed, May 13, 2015 at 9:42 AM, Mark Brown<[email protected]> wrote:
>>> On Wed, May 13, 2015 at 09:23:01PM +0800, zhengxing wrote:
>>>> On 2015年05月13日 03:22, Mark Brown wrote:
>>>>> Is it not possible to extend simple card to handle your use cases?
>>>>> Given the very generic naming and the fact that things like jack
>>>>> detection and so on should depend on the CODEC and board usually rather
>>>>> than on the SoC it doesn't sound like this is Rockchip specific.
>>>>> This also looks like you're reimplementing some device model enumeration
>>>>> stuff which probably shouldn't be happening but let's understand the
>>>>> problem you're trying to solve here before going too far into the code.
>>>> Because we are trying to bring rt5650 in the project, so we intend to
>>>> describe supported codecs with DTS via only a rockchip machine driver file,
>>>> others remain pre-implement(like max98090 / rt5645 that vendor machine
>>>> driver).
>>> I don't undertand what you're saying here, sorry - why is this not just
>>> a case of writing multiple machine drivers?
>> I don't understand this either. I'd think the best solution is
>> simple-card, configured through DTS for each device.
Hi Mark, Dylan,
I tried to use simple-card and had some trouble that jack detection. So
my idea is simply:
/-- rockchip_max98090
(to configure max98090, and no need to via DTS)
rockchip_machine_driver |-- rockchip_rt5645 (to configure
rt5650/rt5645, and no need to via DTS)
(supported codecs via DTS) \-- rockchip_(maybe other codecs)
It is right that it is base on original rockchip_max98090, but the old
rockchip_max98090 used DTS.
I tried to explain my ideas. Your kind suggestions will be highly
appreciated.
Thanks.
On 05/14/2015 01:11 AM, Dylan Reid wrote:
> On Wed, May 13, 2015 at 10:21 AM, Dylan Reid <[email protected]> wrote:
>> On Wed, May 13, 2015 at 9:42 AM, Mark Brown <[email protected]> wrote:
>>> On Wed, May 13, 2015 at 09:23:01PM +0800, zhengxing wrote:
>>>> On 2015年05月13日 03:22, Mark Brown wrote:
>>>
>>>>> Is it not possible to extend simple card to handle your use cases?
>>>>> Given the very generic naming and the fact that things like jack
>>>>> detection and so on should depend on the CODEC and board usually rather
>>>>> than on the SoC it doesn't sound like this is Rockchip specific.
>>>
>>>>> This also looks like you're reimplementing some device model enumeration
>>>>> stuff which probably shouldn't be happening but let's understand the
>>>>> problem you're trying to solve here before going too far into the code.
>>>
>>>> Because we are trying to bring rt5650 in the project, so we intend to
>>>> describe supported codecs with DTS via only a rockchip machine driver file,
>>>> others remain pre-implement(like max98090 / rt5645 that vendor machine
>>>> driver).
>>>
>>> I don't undertand what you're saying here, sorry - why is this not just
>>> a case of writing multiple machine drivers?
>>
>> I don't understand this either. I'd think the best solution is
>> simple-card, configured through DTS for each device.
>>
>>>
>>>> I communicated with Dylan, and he told me that the jack detection is an
>>>> issue in the simple-card, and suggested we are better to send them at
>>>> present.
>>>
>>> But what are these issues?
>>
>> The issue I was referring to when I spoke with rock chip was the need
>> to pass the jack simple-card creates to the headset chip or codec. We
>> need a way to specify a device like a tsa227e or rt5650 to pass the
>> jack to, which events are supported by the jack, and a generic API for
>> passing the jack.
>
> I'm having some trouble envisioning how to pass the jack to the
> headset chip in a generic way. A callback could be added to
> snd_soc_component_driver, or a snd_soc_headset_driver could be added.
> The headset_drive would fit the ts3a227e well, but not the rt5645
> which is also a full blown codec.
Yea, our current jack detection code is quite rudimentary when it comes to
writing generic code.
I think the proper way to support this is come up with the concept of jack
detection providers and consumers. A component can register a jack detection
provider just like it can register a DAI. And then in the board driver you'd
just link the jack detection logic to the jack using the usual approach,
which is also used for DAIs (e.g. of node or device name). The core would
then take care of calling a enable callback or whatever is required to setup
the jack detection logic in the driver.
This would also nicely solve the issue with the GPIO jack detectors, where
we currently can't really handle -EPROBE_DEFER. The GPIO would be requested
by a jack detection provider which can request them before the card is
registered rather than having to do the requesting in the card's init callback.
- Lars
On Fri, May 15, 2015 at 10:40:59PM +0200, Lars-Peter Clausen wrote:
> I think the proper way to support this is come up with the concept of jack
> detection providers and consumers. A component can register a jack detection
> provider just like it can register a DAI. And then in the board driver you'd
> just link the jack detection logic to the jack using the usual approach,
> which is also used for DAIs (e.g. of node or device name). The core would
> then take care of calling a enable callback or whatever is required to setup
> the jack detection logic in the driver.
Yes, nobody has really cared about it since we started pushing things
out of the card init into the device level. We would also need to add a
way to force microphone biases on for devices where that's not a part of
the jack detection IP.
> This would also nicely solve the issue with the GPIO jack detectors, where
> we currently can't really handle -EPROBE_DEFER. The GPIO would be requested
> by a jack detection provider which can request them before the card is
> registered rather than having to do the requesting in the card's init
> callback.
Cards should be able to do their requesting in their probe function
prior to registering with the core even without anything else, though
that needs a bit or refactoring too.
On Tue, May 19, 2015 at 4:16 AM, Mark Brown <[email protected]> wrote:
> On Fri, May 15, 2015 at 10:40:59PM +0200, Lars-Peter Clausen wrote:
>
>> I think the proper way to support this is come up with the concept of jack
>> detection providers and consumers. A component can register a jack detection
>> provider just like it can register a DAI. And then in the board driver you'd
>> just link the jack detection logic to the jack using the usual approach,
>> which is also used for DAIs (e.g. of node or device name). The core would
>> then take care of calling a enable callback or whatever is required to setup
>> the jack detection logic in the driver.
>
> Yes, nobody has really cared about it since we started pushing things
> out of the card init into the device level. We would also need to add a
> way to force microphone biases on for devices where that's not a part of
> the jack detection IP.
>
Can the jacks can each be an aux_dev? The jack driver would create
the jack at probe time and register it with the card in aux_dev->init.
cht_bsw_max98090_ti.c is already doing something similar, although all
contained in the machine driver.
If the jack detection circuit is integrated with a full codec, then
the codec driver can also create the jack and register it with the
card.
Then simple-card can have an optional property to specify aux devs. A
GPIO jack device could handle simple switch-based jack detection.
On Tue, May 19, 2015 at 09:37:58AM -0700, Dylan Reid wrote:
> Can the jacks can each be an aux_dev? The jack driver would create
> the jack at probe time and register it with the card in aux_dev->init.
> cht_bsw_max98090_ti.c is already doing something similar, although all
> contained in the machine driver.
Yes, that's just a CODEC driver registered without any DAIs connected so
it'd just be another CODEC driver.
> Then simple-card can have an optional property to specify aux devs. A
> GPIO jack device could handle simple switch-based jack detection.
That's useful anyway for external headphone/speaker drivers.