[alsa-devel] [RFC][PATCH 0/3] ASoC: FSI - codecs settings
![](https://secure.gravatar.com/avatar/2ea1ea42072986bc3dd023464d0c2de6.jpg?s=120&d=mm&r=g)
Dear Mark, Liam
These patches are FSI - codecs settings
Kuninori Morimoto (3): ASoC: ak4642: make sure snd_soc_codec value for ak4642 ASoC: da7210: make sure snd_soc_codec value for da7210 ASoC: Add fsi-codec support
But I'm not sure this type of fix is correct or not. So, please check and teach me.
Now, FSI driver has 2 connections like below.
fsi - ak4642 fsi - da7210
In future, I will send "fsi - HDMI" pair.
On AP4 board, I would like to use "fsi - ak4642" and "fsi - HDMI" in same time.
To use it, I guess I should modify snd_soc_card :: dai_link correct ? I expected this is correct, I tried to use "fsi - ak4642" and "fsi - da7210" in same time for test.
But when I used "soc_codec_dev_ak4642" for snd_soc_device :: codec_dev, da7210 didn't work. because i2c address of ak4642 is used for da7210. Same things happen on "soc_codec_dev_da7210" - ak4642.
My patches solve above issue for me. But I'm not sure this is correct way.
Best regards -- Kuninori Morimoto
![](https://secure.gravatar.com/avatar/2ea1ea42072986bc3dd023464d0c2de6.jpg?s=120&d=mm&r=g)
If snd_soc_card has some dai_link, there is a possibility that the snd_coc_codec value which came from function is not ak4642's codec. This patch make sure it for ak4642
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/codecs/ak4642.c | 29 +++++++++++++++++++++-------- 1 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 60b83b4..fb44787 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -150,7 +150,11 @@ static const u16 ak4642_reg[AK4642_CACHEREGNUM] = { static inline unsigned int ak4642_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg) { - u16 *cache = codec->reg_cache; + u16 *cache; + + codec = ak4642_codec; + cache = codec->reg_cache; + if (reg >= AK4642_CACHEREGNUM) return -1; return cache[reg]; @@ -162,7 +166,10 @@ static inline unsigned int ak4642_read_reg_cache(struct snd_soc_codec *codec, static inline void ak4642_write_reg_cache(struct snd_soc_codec *codec, u16 reg, unsigned int value) { - u16 *cache = codec->reg_cache; + u16 *cache; + + codec = ak4642_codec; + cache = codec->reg_cache; if (reg >= AK4642_CACHEREGNUM) return;
@@ -177,6 +184,8 @@ static int ak4642_write(struct snd_soc_codec *codec, unsigned int reg, { u8 data[2];
+ codec = ak4642_codec; + /* data is * D15..D8 AK4642 register offset * D7...D0 register data @@ -193,9 +202,12 @@ static int ak4642_write(struct snd_soc_codec *codec, unsigned int reg,
static int ak4642_sync(struct snd_soc_codec *codec) { - u16 *cache = codec->reg_cache; + u16 *cache; int i, r = 0;
+ codec = ak4642_codec; + cache = codec->reg_cache; + for (i = 0; i < AK4642_CACHEREGNUM; i++) r |= ak4642_write(codec, i, cache[i]);
@@ -206,7 +218,7 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_codec *codec = ak4642_codec;
if (is_play) { /* @@ -256,7 +268,7 @@ static void ak4642_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_codec *codec = ak4642_codec;
if (is_play) { /* stop headphone output */ @@ -276,7 +288,8 @@ static void ak4642_dai_shutdown(struct snd_pcm_substream *substream, static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { - struct snd_soc_codec *codec = codec_dai->codec; + struct snd_soc_codec *codec = ak4642_codec; + u8 pll;
switch (freq) { @@ -308,7 +321,7 @@ static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai,
static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_codec *codec = ak4642_codec; u8 data; u8 bcko;
@@ -336,7 +349,7 @@ static int ak4642_dai_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_codec *codec = ak4642_codec; u8 rate;
switch (params_rate(params)) {
![](https://secure.gravatar.com/avatar/d28dfe03ea754ea1153719f4ced12649.jpg?s=120&d=mm&r=g)
On Wed, Jul 14, 2010 at 09:59:31AM +0900, Kuninori Morimoto wrote:
If snd_soc_card has some dai_link, there is a possibility that the snd_coc_codec value which came from function is not ak4642's codec. This patch make sure it for ak4642
Could you be more specific about what you're trying to do here? This patch adds additional uses of the global variable for finding the codec which is pretty much the opposite direction to where we want to go. Is it possible you need multi-codec support?
![](https://secure.gravatar.com/avatar/2ea1ea42072986bc3dd023464d0c2de6.jpg?s=120&d=mm&r=g)
Dear Mark
Thank you for checking patch
Could you be more specific about what you're trying to do here? This patch adds additional uses of the global variable for finding the codec which is pretty much the opposite direction to where we want to go. Is it possible you need multi-codec support?
Now, I would like to use 2 codecs (ak4642/da7210) in same time. But if I select both 2 on .config (fsi-ak4642 / fsi-da7210), kernel say WARNING which say I can not use 2 soc-audio (or can I select both ?)
So, I modified snd_soc_card :: dai_link But, if I use "soc_codec_dev_ak4642" for snd_soc_device :: codec_dev, snd_soc_codec of function parameter of "da7210" was ak4642's codec. This mean register access of da7210 use ak4642's i2c address. -> o da7210 doesn't work o ak4642 register will be broken
I would like to do here is use correct i2c access for ak4642/da7210. snd_soc_codec :: hw_write -> i2c_master_send snd_soc_codec :: control_data -> i2c_client (i2c address)
I'm not goot at detail of soc-audio. what should I do in this case ?
Best regards -- Kuninori Morimoto
![](https://secure.gravatar.com/avatar/d28dfe03ea754ea1153719f4ced12649.jpg?s=120&d=mm&r=g)
On Thu, Jul 15, 2010 at 09:23:33AM +0900, Kuninori Morimoto wrote:
Could you be more specific about what you're trying to do here? This patch adds additional uses of the global variable for finding the codec which is pretty much the opposite direction to where we want to go. Is it possible you need multi-codec support?
Now, I would like to use 2 codecs (ak4642/da7210) in same time. But if I select both 2 on .config (fsi-ak4642 / fsi-da7210), kernel say WARNING which say I can not use 2 soc-audio (or can I select both ?)
You need to give them both different device numbers - soc-audio.0 and soc-audio.1 - rather than giving them both -1.
So, I modified snd_soc_card :: dai_link But, if I use "soc_codec_dev_ak4642" for snd_soc_device :: codec_dev, snd_soc_codec of function parameter of "da7210" was ak4642's codec. This mean register access of da7210 use ak4642's i2c address. -> o da7210 doesn't work o ak4642 register will be broken
Having more than one CODEC in the same card is not currently supported, you need the multi-component work Liam is doing (which will hopefully be merged in the next week or two).
I'm not goot at detail of soc-audio. what should I do in this case ?
Are the two CODECs connected in any way on the board or do you essentially have two separate sound cards on the board? If it's the former you should use multi-component. If it's the latter you should just create two separate sound cards.
![](https://secure.gravatar.com/avatar/2ea1ea42072986bc3dd023464d0c2de6.jpg?s=120&d=mm&r=g)
If snd_soc_card has some dai_link, there is a possibility that the snd_coc_codec value which came from function is not da7210's codec. This patch make sure it for da7210
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/codecs/da7210.c | 21 ++++++++++++++------- 1 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index a83aa18..2b1c65e 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -172,7 +172,11 @@ static const u8 da7210_reg[] = { */ static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg) { - u8 *cache = codec->reg_cache; + u8 *cache; + + codec = da7210_codec; + cache = codec->reg_cache; + BUG_ON(reg >= ARRAY_SIZE(da7210_reg)); return cache[reg]; } @@ -182,9 +186,12 @@ static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg) */ static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value) { - u8 *cache = codec->reg_cache; + u8 *cache; u8 data[2];
+ codec = da7210_codec; + cache = codec->reg_cache; + BUG_ON(codec->volatile_register);
data[0] = reg & 0xff; @@ -205,6 +212,8 @@ static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value) */ static inline u32 da7210_read(struct snd_soc_codec *codec, u32 reg) { + codec = da7210_codec; + if (DA7210_STATUS == reg) return i2c_smbus_read_byte_data(codec->control_data, reg);
@@ -215,7 +224,7 @@ static int da7210_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - struct snd_soc_codec *codec = dai->codec; + struct snd_soc_codec *codec = da7210_codec;
if (is_play) { /* PlayBack Volume 40 */ @@ -246,9 +255,7 @@ static int da7210_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->card->codec; + struct snd_soc_codec *codec = da7210_codec; u32 dai_cfg1; u32 hpf_reg, hpf_mask, hpf_value; u32 fs, bypass; @@ -362,7 +369,7 @@ static int da7210_hw_params(struct snd_pcm_substream *substream, */ static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt) { - struct snd_soc_codec *codec = codec_dai->codec; + struct snd_soc_codec *codec = da7210_codec; u32 dai_cfg1; u32 dai_cfg3;
![](https://secure.gravatar.com/avatar/2ea1ea42072986bc3dd023464d0c2de6.jpg?s=120&d=mm&r=g)
fsi-codec which support some dai_link is used instead of fsi-ak4642 / fsi-da7210, because there is a possibility that SuperH board has some codecs for sound.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/Makefile | 6 +- sound/soc/sh/fsi-ak4642.c | 82 --------------------------- sound/soc/sh/fsi-codec.c | 137 +++++++++++++++++++++++++++++++++++++++++++++ sound/soc/sh/fsi-da7210.c | 74 ------------------------ 4 files changed, 139 insertions(+), 160 deletions(-) delete mode 100644 sound/soc/sh/fsi-ak4642.c create mode 100644 sound/soc/sh/fsi-codec.c delete mode 100644 sound/soc/sh/fsi-da7210.c
diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile index 8a5a192..3811c9d 100644 --- a/sound/soc/sh/Makefile +++ b/sound/soc/sh/Makefile @@ -14,11 +14,9 @@ obj-$(CONFIG_SND_SOC_SH4_SIU) += snd-soc-siu.o
## boards snd-soc-sh7760-ac97-objs := sh7760-ac97.o -snd-soc-fsi-ak4642-objs := fsi-ak4642.o -snd-soc-fsi-da7210-objs := fsi-da7210.o +snd-soc-fsi-codec-objs := fsi-codec.o snd-soc-migor-objs := migor.o
obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o -obj-$(CONFIG_SND_FSI_AK4642) += snd-soc-fsi-ak4642.o -obj-$(CONFIG_SND_FSI_DA7210) += snd-soc-fsi-da7210.o +obj-$(CONFIG_SND_SOC_SH4_FSI) += snd-soc-fsi-codec.o obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c deleted file mode 100644 index 2871a20..0000000 --- a/sound/soc/sh/fsi-ak4642.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * FSI-AK464x sound support for ms7724se - * - * Copyright (C) 2009 Renesas Solutions Corp. - * Kuninori Morimoto morimoto.kuninori@renesas.com - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ - -#include <linux/platform_device.h> -#include <sound/sh_fsi.h> -#include <../sound/soc/codecs/ak4642.h> - -static int fsi_ak4642_dai_init(struct snd_soc_codec *codec) -{ - int ret; - - ret = snd_soc_dai_set_fmt(&ak4642_dai, SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_sysclk(&ak4642_dai, 0, 11289600, 0); - - return ret; -} - -static struct snd_soc_dai_link fsi_dai_link = { - .name = "AK4642", - .stream_name = "AK4642", - .cpu_dai = &fsi_soc_dai[0], /* fsi */ - .codec_dai = &ak4642_dai, - .init = fsi_ak4642_dai_init, - .ops = NULL, -}; - -static struct snd_soc_card fsi_soc_card = { - .name = "FSI", - .platform = &fsi_soc_platform, - .dai_link = &fsi_dai_link, - .num_links = 1, -}; - -static struct snd_soc_device fsi_snd_devdata = { - .card = &fsi_soc_card, - .codec_dev = &soc_codec_dev_ak4642, -}; - -static struct platform_device *fsi_snd_device; - -static int __init fsi_ak4642_init(void) -{ - int ret = -ENOMEM; - - fsi_snd_device = platform_device_alloc("soc-audio", -1); - if (!fsi_snd_device) - goto out; - - platform_set_drvdata(fsi_snd_device, - &fsi_snd_devdata); - fsi_snd_devdata.dev = &fsi_snd_device->dev; - ret = platform_device_add(fsi_snd_device); - - if (ret) - platform_device_put(fsi_snd_device); - -out: - return ret; -} - -static void __exit fsi_ak4642_exit(void) -{ - platform_device_unregister(fsi_snd_device); -} - -module_init(fsi_ak4642_init); -module_exit(fsi_ak4642_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Generic SH4 FSI-AK4642 sound card"); -MODULE_AUTHOR("Kuninori Morimoto morimoto.kuninori@renesas.com"); diff --git a/sound/soc/sh/fsi-codec.c b/sound/soc/sh/fsi-codec.c new file mode 100644 index 0000000..33b901f --- /dev/null +++ b/sound/soc/sh/fsi-codec.c @@ -0,0 +1,137 @@ +/* + * FSI - codecs sound support + * + * Copyright (C) 2010 Renesas Solutions Corp. + * Kuninori Morimoto kuninori.morimoto.gx@renesas.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/platform_device.h> +#include <sound/sh_fsi.h> + +/************************************************************************ + + + FSI - AK4642 + + +************************************************************************/ +#ifdef CONFIG_SND_FSI_AK4642 +#include <../sound/soc/codecs/ak4642.h> + +static int fsi_ak4642_dai_init(struct snd_soc_codec *codec) +{ + int ret; + + ret = snd_soc_dai_set_fmt(&ak4642_dai, SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_sysclk(&ak4642_dai, 0, 11289600, 0); + + return ret; +} + +#undef CODEC_DEV +#define CODEC_DEV &soc_codec_dev_ak4642 +#endif + +/************************************************************************ + + + FSI - da7210 + + +************************************************************************/ +#ifdef CONFIG_SND_FSI_DA7210 +#include "../codecs/da7210.h" + +static int fsi_da7210_init(struct snd_soc_codec *codec) +{ + return snd_soc_dai_set_fmt(&da7210_dai, + SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM); +} + +#undef CODEC_DEV +#define CODEC_DEV &soc_codec_dev_da7210 +#endif + +/************************************************************************ + + + FSI dai link + + +************************************************************************/ +static struct snd_soc_dai_link fsi_dai_link[] = { +#ifdef CONFIG_SND_FSI_AK4642 + { + .name = "AK4642", + .stream_name = "AK4642", + .cpu_dai = &fsi_soc_dai[0], /* FSI A */ + .codec_dai = &ak4642_dai, + .init = fsi_ak4642_dai_init, + }, +#endif +#ifdef CONFIG_SND_FSI_DA7210 + { + .name = "DA7210", + .stream_name = "DA7210", + .cpu_dai = &fsi_soc_dai[1], /* FSI B */ + .codec_dai = &da7210_dai, + .init = fsi_da7210_init, + }, +#endif +}; + +static struct snd_soc_card fsi_soc_card = { + .name = "FSI", + .platform = &fsi_soc_platform, + .dai_link = fsi_dai_link, + .num_links = ARRAY_SIZE(fsi_dai_link), +}; + +static struct snd_soc_device fsi_snd_devdata = { + .card = &fsi_soc_card, + .codec_dev = CODEC_DEV, +}; + +static struct platform_device *fsi_snd_device; + +static int __init fsi_codec_init(void) +{ + int ret = -ENOMEM; + + fsi_snd_device = platform_device_alloc("soc-audio", -1); + if (!fsi_snd_device) + goto out; + + platform_set_drvdata(fsi_snd_device, + &fsi_snd_devdata); + fsi_snd_devdata.dev = &fsi_snd_device->dev; + ret = platform_device_add(fsi_snd_device); + + if (ret) + platform_device_put(fsi_snd_device); + else + dev_info(fsi_snd_devdata.dev, "FSI common codec\n"); + +out: + return ret; +} + +static void __exit fsi_codec_exit(void) +{ + platform_device_unregister(fsi_snd_device); +} + +module_init(fsi_codec_init); +module_exit(fsi_codec_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Generic FSI - codec sound card"); +MODULE_AUTHOR("Kuninori Morimoto kuninori.morimoto.gx@renesas.com"); diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c deleted file mode 100644 index 4d4fd77..0000000 --- a/sound/soc/sh/fsi-da7210.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * fsi-da7210.c - * - * Copyright (C) 2009 Renesas Solutions Corp. - * Kuninori Morimoto morimoto.kuninori@renesas.com - * - * 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; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/platform_device.h> -#include <sound/sh_fsi.h> -#include "../codecs/da7210.h" - -static int fsi_da7210_init(struct snd_soc_codec *codec) -{ - return snd_soc_dai_set_fmt(&da7210_dai, - SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); -} - -static struct snd_soc_dai_link fsi_da7210_dai = { - .name = "DA7210", - .stream_name = "DA7210", - .cpu_dai = &fsi_soc_dai[1], /* FSI B */ - .codec_dai = &da7210_dai, - .init = fsi_da7210_init, -}; - -static struct snd_soc_card fsi_soc_card = { - .name = "FSI", - .platform = &fsi_soc_platform, - .dai_link = &fsi_da7210_dai, - .num_links = 1, -}; - -static struct snd_soc_device fsi_da7210_snd_devdata = { - .card = &fsi_soc_card, - .codec_dev = &soc_codec_dev_da7210, -}; - -static struct platform_device *fsi_da7210_snd_device; - -static int __init fsi_da7210_sound_init(void) -{ - int ret; - - fsi_da7210_snd_device = platform_device_alloc("soc-audio", -1); - if (!fsi_da7210_snd_device) - return -ENOMEM; - - platform_set_drvdata(fsi_da7210_snd_device, &fsi_da7210_snd_devdata); - fsi_da7210_snd_devdata.dev = &fsi_da7210_snd_device->dev; - ret = platform_device_add(fsi_da7210_snd_device); - if (ret) - platform_device_put(fsi_da7210_snd_device); - - return ret; -} - -static void __exit fsi_da7210_sound_exit(void) -{ - platform_device_unregister(fsi_da7210_snd_device); -} - -module_init(fsi_da7210_sound_init); -module_exit(fsi_da7210_sound_exit); - -/* Module information */ -MODULE_DESCRIPTION("ALSA SoC FSI DA2710"); -MODULE_AUTHOR("Kuninori Morimoto morimoto.kuninori@renesas.com"); -MODULE_LICENSE("GPL");
participants (2)
-
Kuninori Morimoto
-
Mark Brown