Re: [alsa-devel] [PATCH v5] sound/soc/lapis: add machine driver for ML7213 Carrier Board
On Tue, Mar 06, 2012 at 02:49:24PM +0900, Tomoya MORINAGA wrote:
2012年3月2日22:05 Mark Brown broonie@opensource.wolfsonmicro.com:
You're also missing a blank line between this and the previous stanza.
Sorry, I can't understand your saying.
Your file should look like other similar files in the kernel.
Use snd_soc_register_card() and a real device.
OK. As a matter of interest, why do you recommend me to use snd_soc_register_card() ?
It's been the standard since 2.6.38.
On Tue, Mar 6, 2012 at 8:54 PM, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
You're also missing a blank line between this and the previous stanza.
Sorry, I can't understand your saying.
Your file should look like other similar files in the kernel.
Aha, I could understand. Need to add blank line before "config SND_SOC_ML7213_MACHINE" line.
thanks.
This machine driver is for LAPIS Semiconductor ML7213 Carrier Board.
Signed-off-by: Tomoya MORINAGA tomoya.rohm@gmail.com --- V6 - Add master/slave settings - Use snd_soc_register_card - Move set_clkdiv to dai_hw_params --- sound/soc/lapis/Kconfig | 7 ++ sound/soc/lapis/Makefile | 2 + sound/soc/lapis/ml7213ioh-machine.c | 179 +++++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+), 0 deletions(-) create mode 100644 sound/soc/lapis/ml7213ioh-machine.c
diff --git a/sound/soc/lapis/Kconfig b/sound/soc/lapis/Kconfig index 551e385..9bc1b4d 100644 --- a/sound/soc/lapis/Kconfig +++ b/sound/soc/lapis/Kconfig @@ -2,3 +2,10 @@ config SND_SOC_ML7213_PLATFORM tristate "ML7213 IOH ASoC platform driver" help This option enables support for the AC Link Controllers in ML7213 IOH SoC. + +config SND_SOC_ML7213_MACHINE + tristate "ML7213 IOH ASoC machine driver" + select SND_SOC_ML7213_PLATFORM + select SND_SOC_ML26124 + help + This is ASoC machine driver for ML7213 IOH diff --git a/sound/soc/lapis/Makefile b/sound/soc/lapis/Makefile index aba1630..7ec4bea 100644 --- a/sound/soc/lapis/Makefile +++ b/sound/soc/lapis/Makefile @@ -1,4 +1,6 @@ # Platform +snd-soc-ml7213-machine-objs := ml7213ioh-machine.o snd-soc-ml7213-plat-objs := ml7213ioh-plat.o
obj-$(CONFIG_SND_SOC_ML7213_PLATFORM) += snd-soc-ml7213-plat.o +obj-$(CONFIG_SND_SOC_ML7213_MACHINE) += snd-soc-ml7213-machine.o diff --git a/sound/soc/lapis/ml7213ioh-machine.c b/sound/soc/lapis/ml7213ioh-machine.c new file mode 100644 index 0000000..eab7e70 --- /dev/null +++ b/sound/soc/lapis/ml7213ioh-machine.c @@ -0,0 +1,179 @@ +/* + * ml7213ioh-machine.c -- SoC Audio for LAPIS Semiconductor ML7213 IOH CRB + * + * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/module.h> +#include <linux/platform_device.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/soc.h> +#include <sound/pcm_params.h> +#include <linux/i2c.h> +#include "../codecs/ml26124.h" +#include "ioh_i2s.h" + +static const struct snd_soc_dapm_widget ml7213_dapm_widgets[] = { + SND_SOC_DAPM_SPK("Speaker", NULL), + SND_SOC_DAPM_LINE("LINEOUT", NULL), + SND_SOC_DAPM_LINE("LINEIN", NULL), + SND_SOC_DAPM_MIC("AnalogMIC", NULL), + SND_SOC_DAPM_MIC("DigitalMIC", NULL), +}; + +static const struct snd_soc_dapm_route ml7213_routes[] = { + {"Speaker", NULL, "SPOUT"}, + {"LINEOUT", NULL, "LOUT"}, + {"MIN", NULL, "AnalogMIC"}, + {"MDIN", NULL, "DigitalMIC"}, + {"MIN", NULL, "LINEIN"}, +}; + +static int ml7213_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + int bclkfs; + int mclkfs; + unsigned int clk; + int ret; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + unsigned int channel_map[] = {5, 0, 1, 2, 3, 4}; + + /* set cpu DAI channel mapping */ + ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map), + channel_map, ARRAY_SIZE(channel_map), channel_map); + if (ret < 0) + return ret; + + switch (params_rate(hw_params)) { + case 16000: + case 32000: + case 48000: + clk = 12288000; + break; + default: + return -EINVAL; + } + + mclkfs = clk / params_rate(hw_params); + + switch (params_format(hw_params)) { + case SNDRV_PCM_FORMAT_U8: + case SNDRV_PCM_FORMAT_S16_LE: + bclkfs = 32; + break; + case SNDRV_PCM_FORMAT_S32_LE: + bclkfs = 64; + break; + default: + pr_err("%s: Failed not support format\n", __func__); + return -EINVAL; + break; + } + + /* set the codec system clock for DAC and ADC */ + ret = snd_soc_dai_set_sysclk(codec_dai, ML26124_USE_PLL, clk, + SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* set cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_ops ml7213_ops = { + .hw_params = ml7213_hw_params, +}; + +static struct snd_soc_dai_link ml7213crb_dai = { + .name = "ml26124", + .stream_name = "ML26124", + .cpu_dai_name = "ml7213ioh", + .codec_dai_name = "ml26124-hifi", + .platform_name = "ml7213-i2s-audio", + .codec_name = "ml26124.1-001a", + .ops = &ml7213_ops, +}; + +static struct snd_soc_card ml7213crb_card = { + .name = "LAPIS Semiconductor ML7213CRB", + .dai_link = &ml7213crb_dai, + .num_links = 1, + .dapm_widgets = ml7213_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(ml7213_dapm_widgets), + .dapm_routes = ml7213_routes, + .num_dapm_routes = ARRAY_SIZE(ml7213_routes), +}; + +static int __devinit lapis_ml7213_ml26124_probe(struct platform_device *pdev) +{ + int ret; + + ml7213crb_card.dev = &pdev->dev; + ret = snd_soc_register_card(&ml7213crb_card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret); + return ret; + } + + return 0; +} + +static int __devexit lapis_ml7213_ml26124_remove(struct platform_device *pdev) +{ + snd_soc_unregister_card(&ml7213crb_card); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static struct platform_driver snd_ml7213crb_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "lapis-ml7213ioh-CRB", + }, + .probe = lapis_ml7213_ml26124_probe, + .remove = __devexit_p(lapis_ml7213_ml26124_remove), +}; + +static int __init lapis_ml7213_ml26124_init(void) +{ + return platform_driver_register(&snd_ml7213crb_driver); +} +module_init(lapis_ml7213_ml26124_init); + +static void __exit lapis_ml7213_ml26124_exit(void) +{ + platform_driver_unregister(&snd_ml7213crb_driver); +} +module_exit(lapis_ml7213_ml26124_exit); + +MODULE_AUTHOR("Tomoya MORINAGA tomoya.rohm@gmail.com"); +MODULE_DESCRIPTION("LAPIS Semiconductor ML7213 IOH ALSA SoC machine driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform: lapis-ml7213ioh-CRB");
On Fri, Mar 09, 2012 at 03:38:11PM +0900, Tomoya MORINAGA wrote:
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
return ret;
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
This looks very broken, you're setting the two ends of the link to different configurations. If this is needed it should be documented why.
Also, this should be set in the dai_link structure as data rather than set each time.
On Wed, Mar 14, 2012 at 11:45 PM, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
On Fri, Mar 09, 2012 at 03:38:11PM +0900, Tomoya MORINAGA wrote:
- /* set codec DAI configuration */
- ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
- if (ret < 0)
- return ret;
- /* set cpu DAI configuration */
- ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
This looks very broken, you're setting the two ends of the link to different configurations. If this is needed it should be documented why.
Also, this should be set in the dai_link structure as data rather than set each time.
OK. codec is slave, i2s controller is master. So, I'll use SND_SOC_DAIFMT_CBS_CFM.
thanks.
On Thu, Mar 15, 2012 at 01:50:48PM +0900, Tomoya MORINAGA wrote:
OK. codec is slave, i2s controller is master. So, I'll use SND_SOC_DAIFMT_CBS_CFM.
That means "Codec bit clock master frame clock slave". Are you sure that's what you want?
On Thu, Mar 15, 2012 at 7:50 PM, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
On Thu, Mar 15, 2012 at 01:50:48PM +0900, Tomoya MORINAGA wrote:
OK. codec is slave, i2s controller is master. So, I'll use SND_SOC_DAIFMT_CBS_CFM.
That means "Codec bit clock master frame clock slave". Are you sure that's what you want?
Let me clarify the above. Does the above "frame clock" mean "data line" of I2S? If yes, I should have used 'SND_SOC_DAIFMT_CBS_CFS'.
thanks.
On Fri, Mar 16, 2012 at 01:07:03PM +0900, Tomoya MORINAGA wrote:
On Thu, Mar 15, 2012 at 7:50 PM, Mark Brown
That means "Codec bit clock master frame clock slave". Are you sure that's what you want?
Let me clarify the above. Does the above "frame clock" mean "data line" of I2S? If yes, I should have used 'SND_SOC_DAIFMT_CBS_CFS'.
No, it means the clock which runs at sample rate (usually called the frame clock or LRCLK).
On Sat, Mar 17, 2012 at 4:06 AM, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
That means "Codec bit clock master frame clock slave". Are you sure that's what you want?
Let me clarify the above. Does the above "frame clock" mean "data line" of I2S? If yes, I should have used 'SND_SOC_DAIFMT_CBS_CFS'.
No, it means the clock which runs at sample rate (usually called the frame clock or LRCLK).
I could understand it. The LRCLK is also the same as bit clock for ML26124. So, I'll use 'SND_SOC_DAIFMT_CBS_CFS'.
thanks
This machine driver is for LAPIS Semiconductor ML7213 Carrier Board + ML26124 Reference Board
Signed-off-by: Tomoya MORINAGA tomoya.rohm@gmail.com --- v7 - Modify codec master/slave setting - Add MICBIAS setting - Add some snd_soc_dapm_enable_pin settings --- sound/soc/lapis/Kconfig | 7 ++ sound/soc/lapis/Makefile | 2 + sound/soc/lapis/ml7213ioh-machine.c | 186 +++++++++++++++++++++++++++++++++++ 3 files changed, 195 insertions(+), 0 deletions(-) create mode 100644 sound/soc/lapis/ml7213ioh-machine.c
diff --git a/sound/soc/lapis/Kconfig b/sound/soc/lapis/Kconfig index 551e385..9bc1b4d 100644 --- a/sound/soc/lapis/Kconfig +++ b/sound/soc/lapis/Kconfig @@ -2,3 +2,10 @@ config SND_SOC_ML7213_PLATFORM tristate "ML7213 IOH ASoC platform driver" help This option enables support for the AC Link Controllers in ML7213 IOH SoC. + +config SND_SOC_ML7213_MACHINE + tristate "ML7213 IOH ASoC machine driver" + select SND_SOC_ML7213_PLATFORM + select SND_SOC_ML26124 + help + This is ASoC machine driver for ML7213 IOH diff --git a/sound/soc/lapis/Makefile b/sound/soc/lapis/Makefile index aba1630..7ec4bea 100644 --- a/sound/soc/lapis/Makefile +++ b/sound/soc/lapis/Makefile @@ -1,4 +1,6 @@ # Platform +snd-soc-ml7213-machine-objs := ml7213ioh-machine.o snd-soc-ml7213-plat-objs := ml7213ioh-plat.o
obj-$(CONFIG_SND_SOC_ML7213_PLATFORM) += snd-soc-ml7213-plat.o +obj-$(CONFIG_SND_SOC_ML7213_MACHINE) += snd-soc-ml7213-machine.o diff --git a/sound/soc/lapis/ml7213ioh-machine.c b/sound/soc/lapis/ml7213ioh-machine.c new file mode 100644 index 0000000..e51b1de --- /dev/null +++ b/sound/soc/lapis/ml7213ioh-machine.c @@ -0,0 +1,186 @@ +/* + * ml7213ioh-machine.c -- SoC Audio for LAPIS Semiconductor ML7213 IOH CRB + * + * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/module.h> +#include <linux/platform_device.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/soc.h> +#include <sound/pcm_params.h> +#include <linux/i2c.h> +#include "../codecs/ml26124.h" +#include "ioh_i2s.h" + +static const struct snd_soc_dapm_widget ml7213_dapm_widgets[] = { + SND_SOC_DAPM_SPK("Speaker", NULL), + SND_SOC_DAPM_LINE("LINEOUT", NULL), + SND_SOC_DAPM_LINE("LINEIN", NULL), + SND_SOC_DAPM_MIC("AnalogMIC", NULL), + SND_SOC_DAPM_MIC("DigitalMIC", NULL), +}; + +static const struct snd_soc_dapm_route ml7213_routes[] = { + {"Speaker", NULL, "SPOUT"}, + {"LINEOUT", NULL, "LOUT"}, + {"AnalogMIC", NULL, "MICBIAS"}, + {"MIN", NULL, "AnalogMIC"}, + {"MDIN", NULL, "DigitalMIC"}, + {"MIN", NULL, "LINEIN"}, +}; + +static int ml7213_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + int bclkfs; + int mclkfs; + unsigned int clk; + int ret; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + unsigned int channel_map[] = {5, 0, 1, 2, 3, 4}; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + + /* set cpu DAI channel mapping */ + ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map), + channel_map, ARRAY_SIZE(channel_map), channel_map); + if (ret < 0) + return ret; + + switch (params_rate(hw_params)) { + case 16000: + case 32000: + case 48000: + clk = 12288000; + break; + default: + return -EINVAL; + } + + mclkfs = clk / params_rate(hw_params); + + switch (params_format(hw_params)) { + case SNDRV_PCM_FORMAT_U8: + case SNDRV_PCM_FORMAT_S16_LE: + bclkfs = 32; + break; + case SNDRV_PCM_FORMAT_S32_LE: + bclkfs = 64; + break; + default: + pr_err("%s: Failed not support format\n", __func__); + return -EINVAL; + break; + } + + /* set the codec system clock for DAC and ADC */ + ret = snd_soc_dai_set_sysclk(codec_dai, ML26124_USE_PLLOUT, clk, + SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* set cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + snd_soc_dapm_enable_pin(dapm, "Speaker"); + snd_soc_dapm_enable_pin(dapm, "AnalogMIC"); + snd_soc_dapm_enable_pin(dapm, "MICBIAS"); + + return 0; +} + +static struct snd_soc_ops ml7213_ops = { + .hw_params = ml7213_hw_params, +}; + +static struct snd_soc_dai_link ml7213crb_dai = { + .name = "ml26124", + .stream_name = "ML26124", + .cpu_dai_name = "ml7213ioh", + .codec_dai_name = "ml26124-hifi", + .platform_name = "ml7213-i2s-audio", + .codec_name = "ml26124.1-001a", + .ops = &ml7213_ops, +}; + +static struct snd_soc_card ml7213crb_card = { + .name = "LAPIS Semiconductor ML7213CRB", + .dai_link = &ml7213crb_dai, + .num_links = 1, + .dapm_widgets = ml7213_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(ml7213_dapm_widgets), + .dapm_routes = ml7213_routes, + .num_dapm_routes = ARRAY_SIZE(ml7213_routes), +}; + +static int __devinit lapis_ml7213_ml26124_probe(struct platform_device *pdev) +{ + int ret; + + ml7213crb_card.dev = &pdev->dev; + ret = snd_soc_register_card(&ml7213crb_card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret); + return ret; + } + + return 0; +} + +static int __devexit lapis_ml7213_ml26124_remove(struct platform_device *pdev) +{ + snd_soc_unregister_card(&ml7213crb_card); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static struct platform_driver snd_ml7213crb_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "lapis-ml7213ioh-CRB", + }, + .probe = lapis_ml7213_ml26124_probe, + .remove = __devexit_p(lapis_ml7213_ml26124_remove), +}; + +static int __init lapis_ml7213_ml26124_init(void) +{ + return platform_driver_register(&snd_ml7213crb_driver); +} +module_init(lapis_ml7213_ml26124_init); + +static void __exit lapis_ml7213_ml26124_exit(void) +{ + platform_driver_unregister(&snd_ml7213crb_driver); +} +module_exit(lapis_ml7213_ml26124_exit); + +MODULE_AUTHOR("Tomoya MORINAGA tomoya.rohm@gmail.com"); +MODULE_DESCRIPTION("LAPIS Semiconductor ML7213 IOH ALSA SoC machine driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform: lapis-ml7213ioh-CRB");
On Mon, Mar 19, 2012 at 09:02:05PM +0900, Tomoya MORINAGA wrote:
+static int ml7213_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
+{
- default:
pr_err("%s: Failed not support format\n", __func__);
return -EINVAL;
break;
No need for the break.
- snd_soc_dapm_enable_pin(dapm, "Speaker");
- snd_soc_dapm_enable_pin(dapm, "AnalogMIC");
- snd_soc_dapm_enable_pin(dapm, "MICBIAS");
Why are you doing thiS? You never disable these things so if this were needed you may as well do it on init, but since the default state is enabled anyway this shouldn't be doing anytihng.
+static int __init lapis_ml7213_ml26124_init(void) +{
- return platform_driver_register(&snd_ml7213crb_driver);
+} +module_init(lapis_ml7213_ml26124_init);
module_platform_driver().
+MODULE_ALIAS("platform: lapis-ml7213ioh-CRB");
No space after the colon.
On Tue, Mar 20, 2012 at 4:21 AM, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
- snd_soc_dapm_enable_pin(dapm, "Speaker");
- snd_soc_dapm_enable_pin(dapm, "AnalogMIC");
- snd_soc_dapm_enable_pin(dapm, "MICBIAS");
Why are you doing thiS? You never disable these things so if this were needed you may as well do it on init, but since the default state is enabled anyway this shouldn't be doing anytihng.
OK. I've confirmed if deleting these lines, both playback/capture work well. So, I'll delete these.
thanks.
participants (2)
-
Mark Brown
-
Tomoya MORINAGA