[alsa-devel] ASoC: WM8804: fsi-wm8804
Hi, I'm trying to use the wm8804 codec in my SH4-based system (Renesas SH7724 to be precise). I have used the latest kernel 2.6.37-rc1 where there is the codec driver for wm8804. However, I have to write my own fsi-wm8804.c (like e.g. fsi-da7210.c). My code attached below. After compiling it with the rest of the kernel sources or compiling as an external module my alsa still does not see any soundcards. However, by running i2cdetect I can see that the device is correctly taken by the codec driver so the problem is somewhere with my fsi-wm8804 probably. Could you take a look at this ? Did I miss something from new ASoC api so that this module could correctly talk with wm8804 codec driver ? Also (when compiled as modules) after loading and doing lsmod I could see that the wm8804 module is not used by fsi-wm8804 module (as it was when I was playing with wm8940 on previous kernel versions).
best regards, Greg
#include <linux/platform_device.h> #include <sound/sh_fsi.h>
static int fsi_wm8804_init(struct snd_soc_codec *codec) {
return 0; }
static int fsi_wm8804_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *dai = rtd->codec_dai;
printk("%s\n", __FUNCTION__);
if(substream->stream == SNDRV_PCM_STREAM_CAPTURE) { snd_soc_dai_set_pll(dai, 0, 0, 12000000, 94310400); } else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { snd_soc_dai_set_pll(dai, 0, 0, 12000000, 98304000); }
snd_soc_dai_set_fmt(dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
return 0; }
static struct snd_soc_ops fsi_wm8804_ops = { .hw_params = fsi_wm8804_hw_params, };
static struct snd_soc_dai_link fsi_wm8804_dai = { .name = "WM8804", .stream_name = "WM8804", .cpu_dai_name = "fsib-dai", /* FSI B */ .codec_dai_name = "wm8804-spdif", .platform_name = "sh_fsi.0", .codec_name = "wm8804.0-003a", /*0x3a is codec I2C addr*/ .init = fsi_wm8804_init, .ops = &fsi_wm8804_ops, };
static struct snd_soc_card fsi_soc_card = { .name = "FSI (WM8804)", .dai_link = &fsi_wm8804_dai, .num_links = 1, };
static struct platform_device *fsi_wm8804_snd_device;
static int __init fsi_wm8804_sound_init(void) { int ret;
printk("%s\n", __FUNCTION__);
fsi_wm8804_snd_device = platform_device_alloc("soc-audio", FSI_PORT_B); if (!fsi_wm8804_snd_device) return -ENOMEM;
platform_set_drvdata(fsi_wm8804_snd_device, &fsi_soc_card); ret = platform_device_add(fsi_wm8804_snd_device); if (ret) platform_device_put(fsi_wm8804_snd_device);
return ret; }
static void __exit fsi_wm8804_sound_exit(void) { printk("%s\n", __FUNCTION__);
platform_device_unregister(fsi_wm8804_snd_device); }
module_init(fsi_wm8804_sound_init); module_exit(fsi_wm8804_sound_exit);
/* Module information */ MODULE_DESCRIPTION("ALSA SoC FSI WM8804"); MODULE_LICENSE("GPL")
On Mon, Nov 15, 2010 at 01:26:37PM +0100, Grzegorz Daniluk wrote:
I'm trying to use the wm8804 codec in my SH4-based system (Renesas SH7724 to be precise). I have used the latest kernel 2.6.37-rc1 where there is the codec driver for wm8804. However, I have to write my own fsi-wm8804.c (like e.g. fsi-da7210.c). My code attached below. After compiling it with the rest of the kernel sources or compiling as an external module my alsa still does not see any soundcards. However, by running i2cdetect I can see that the device is correctly taken by the codec driver so the problem is somewhere with my fsi-wm8804 probably.
Did you register the I2C device for the CODEC with the I2C subsystem? If that's not the issue could you please provide a kernel log with #define DEBUG at the top of soc-core.c?
static int fsi_wm8804_init(struct snd_soc_codec *codec) {
return 0;
}
Remove unused functions.
if(substream->stream == SNDRV_PCM_STREAM_CAPTURE) { snd_soc_dai_set_pll(dai, 0, 0, 12000000, 94310400); } else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { snd_soc_dai_set_pll(dai, 0, 0, 12000000, 98304000); }
This is going to prevent simultaneous playback and record; this may not be an issue in your system but I wanted to be sure you were aware of it.
Mark Brown wrote:
Did you register the I2C device for the CODEC with the I2C subsystem?
I believe that is done in wm8804 codec driver (i2c_add_driver() call in wm8804_modinit() function).
If that's not the issue could you please provide a kernel log with #define DEBUG at the top of soc-core.c?
I'm sending the full kern.log as an attachment to this email.
if(substream->stream == SNDRV_PCM_STREAM_CAPTURE) { snd_soc_dai_set_pll(dai, 0, 0, 12000000, 94310400); } else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { snd_soc_dai_set_pll(dai, 0, 0, 12000000, 98304000); }
This is going to prevent simultaneous playback and record; this may not be an issue in your system but I wanted to be sure you were aware of it.
Yes, I'm aware of that. However, in my system it is not going to be a problem.
Thank you for your help.
best regards, Greg
On Mon, Nov 15, 2010 at 02:46:55PM +0100, Grzegorz Daniluk wrote:
Mark Brown wrote:
Did you register the I2C device for the CODEC with the I2C subsystem?
I believe that is done in wm8804 codec driver (i2c_add_driver() call in wm8804_modinit() function).
This is adding the driver not the device. You need to register both - the device will generally be registered by your arch/ file for the board.
If that's not the issue could you please provide a kernel log with #define DEBUG at the top of soc-core.c?
I'm sending the full kern.log as an attachment to this email.
Could you please verify that you have enabled the debug logging requested? I cannot see any of the additional logging that would be generated if this was enabled.
Mark Brown wrote:
You need to register both - the device will generally be registered by your arch/ file for the board.
Yes, I have done this too.
Could you please verify that you have enabled the debug logging requested? I cannot see any of the additional logging that would be generated if this was enabled.
If I understood correctly my sound/soc/soc-core.c looks as following (added #define ...): .... #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/soc-dapm.h> #include <sound/initval.h>
#define NAME_SIZE 32
/*my code*/ #define CONFIG_DEBUG_FS #define DEBUG /*end of my code*/
static DEFINE_MUTEX(pcm_mutex); static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
#ifdef CONFIG_DEBUG_FS static struct dentry *debugfs_root; #endif
static DEFINE_MUTEX(client_mutex); static LIST_HEAD(card_list); ....
best regards, Greg
On Mon, Nov 15, 2010 at 03:03:52PM +0100, Grzegorz Daniluk wrote:
Mark Brown wrote:
Could you please verify that you have enabled the debug logging requested? I cannot see any of the additional logging that would be generated if this was enabled.
If I understood correctly my sound/soc/soc-core.c looks as following (added #define ...): .... #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/soc-dapm.h> #include <sound/initval.h>
#define NAME_SIZE 32
/*my code*/ #define CONFIG_DEBUG_FS
This should be selected via Kconfig; doing this here is going to be actively harmful.
#define DEBUG /*end of my code*/
You need to enable this at the *top* of the file rather than part way through it - in particular, it needs to be before any #includes.
Mark Brown wrote:
You need to enable this at the *top* of the file rather than part way through it - in particular, it needs to be before any #includes.
Sorry about that, now it tells much more :) So what I did wrong was the .codec_name in snd_soc_dai_link structure. I have defined it as "wm8804.0-003a" while it should be "wm8804.1-003a". Btw. I know that 003a represents the I2C address of the codec, but what this '1' or '0' stands for (that I had mistaken) ?
best regards, Greg
(...) Nov 15 14:24:15 ecovec kernel: wm8804 1-003a: codec register 1-003a Nov 15 14:24:15 ecovec kernel: wm8804 1-003a: dai register 1-003a #1 Nov 15 14:24:15 ecovec kernel: Registered DAI 'wm8804-spdif' Nov 15 14:24:15 ecovec kernel: Registered codec 'wm8804.1-003a' (....) Nov 15 14:24:15 ecovec kernel: Registered platform 'sh_fsi.0' Nov 15 14:24:15 ecovec kernel: fsi-pcm-audio sh_fsi.0: dai register sh_fsi.0 #2 Nov 15 14:24:15 ecovec kernel: Registered DAI 'fsia-dai' Nov 15 14:24:15 ecovec kernel: Registered DAI 'fsib-dai' Nov 15 14:24:15 ecovec kernel: fsi_wm8804_sound_init Nov 15 14:24:15 ecovec kernel: soc-audio soc-audio.1: binding WM8804 at idx 0 Nov 15 14:24:15 ecovec kernel: soc-audio soc-audio.1: CODEC wm8804.0-003a not registered Nov 15 14:24:15 ecovec kernel: soc-audio soc-audio.1: Registered card 'FSI (WM8804)' (...)
On Mon, Nov 15, 2010 at 03:54:14PM +0100, Grzegorz Daniluk wrote:
Sorry about that, now it tells much more :) So what I did wrong was
Good to hear.
the .codec_name in snd_soc_dai_link structure. I have defined it as "wm8804.0-003a" while it should be "wm8804.1-003a". Btw. I know that 003a represents the I2C address of the codec, but what this '1' or '0' stands for (that I had mistaken) ?
It's the I2C bus number - many platforms have multiple I2C buses so we need to distinguish between them.
participants (2)
-
Grzegorz Daniluk
-
Mark Brown