[alsa-devel] Writing an AT91SAM9260-EK Dumb Codec Driver
Hello all:
I am working on a driver for a dumb codec to work with the SSC as a PCM on the AT91SAM9260. I have, with the gracious help of Frank Mandarino, have the glue code written without too many problems. However, I need some guidance on getting a few things configured correctly for my codec and then getting it to compile and load correctly.
For configuration, I am using the Winbond W6811. For this, I am going to use a 256kHz BCLK and an 8kHz frame. Each sample consists of 8-bit u-law PCM, MSB first. When I execute a read from the codec to the processor, I need to make the reads on the falling edge of the BCLK at each sync pulse. When executing a write from the processor to the codec I need to write on the rising edge at each sync pulse. I think I the timing correct in my driver with:
cmr_div = 187; /* PCM_CLK = ~96MHz/(2*187) = 256kHz */ period = 15; /* PCM_SYNC = PCM_CLK/(2*(15+1)) = 8000Hz */
However, I am not sure how to get the following correct for my needs:
#define W6811_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE)
Now to making the driver once the code is done. I am relatively new to writing linux drivers. In the 6 or so that I have written, I usually cross-compile them as modules and then insmod them. I have tried that here and am getting a strange warning that I am unsure of. I have a pretty simple Makefile and when I execute it, I get:
make ARCH=arm CROSS_COMPILE=arm-linux- make -C ~/Linux_Builds/linux-2.6.21.5M=/home/grhuser/Door_Access_System/Remotes/Driver/sound modules make[1]: Entering directory `/home/grhuser/Linux_Builds/linux- 2.6.21.5' CC [M] /home/grhuser/Door_Access_System/Remotes/Driver/sound/grh_ek_w6811.o Building modules, stage 2. MODPOST 1 modules WARNING: "at91_ssc_dai" [/home/grhuser/Door_Access_System/Remotes/Driver/sound/grh_ek_w6811.ko] undefined! CC /home/grhuser/Door_Access_System/Remotes/Driver/sound/grh_ek_w6811.mod.o LD [M] /home/grhuser/Door_Access_System/Remotes/Driver/sound/grh_ek_w6811.ko make[1]: Leaving directory `/home/grhuser/Linux_Builds/linux- 2.6.21.5'
As you can see, I am using linux-2.6.21.5 I have ALSA checked and AT91-SoC checked in my .config file. For this attempt to build the driver, I have a separate folder than contains: at91-ssc.h and at91-pcm.h. If there is a more correct way to do this and be able to debug it, please let me know.
I have attached copies of my driver. I would appreciate any and all feedback and assistance on getting this running.
On Fri, 2007-06-15 at 13:46 -0500, Paul Kavan wrote:
Now to making the driver once the code is done. I am relatively new to writing linux drivers. In the 6 or so that I have written, I usually cross-compile them as modules and then insmod them. I have tried that here and am getting a strange warning that I am unsure of. I have a pretty simple Makefile and when I execute it, I get:
make ARCH=arm CROSS_COMPILE=arm-linux- make -C ~/Linux_Builds/linux-2.6.21.5M=/home/grhuser/Door_Access_System/Remotes/Driver/sound modules make[1]: Entering directory `/home/grhuser/Linux_Builds/linux- 2.6.21.5' CC [M] /home/grhuser/Door_Access_System/Remotes/Driver/sound/grh_ek_w6811.o Building modules, stage 2. MODPOST 1 modules WARNING: "at91_ssc_dai" [/home/grhuser/Door_Access_System/Remotes/Driver/sound/grh_ek_w6811.ko] undefined! CC /home/grhuser/Door_Access_System/Remotes/Driver/sound/grh_ek_w6811.mod.o LD [M] /home/grhuser/Door_Access_System/Remotes/Driver/sound/grh_ek_w6811.ko make[1]: Leaving directory `/home/grhuser/Linux_Builds/linux- 2.6.21.5'
It looks like the AT91 platform code is not being built. i.e. at91-ssc, at91-pcm.
As you can see, I am using linux-2.6.21.5 I have ALSA checked and AT91-SoC checked in my .config file. For this attempt to build the driver, I have a separate folder than contains: at91-ssc.h and at91-pcm.h. If there is a more correct way to do this and be able to debug it, please let me know.
It's probably going to be easier in the long run to copy your driver code to linux/sound/soc/at91 and then add an entry for your driver in the linux/sound/soc/at91/ Makefile & Kconfig
e.g. for Kconfig
config SND_AT91_SOC_ETI_B1_WM8731 tristate "SoC Audio support for WM8731-based Endrelia ETI-B1 boards" depends on SND_AT91_SOC && (MACH_ETI_B1 || MACH_ETI_C1) select SND_AT91_SOC_SSC select SND_SOC_WM8731 help Say Y if you want to add support for SoC audio on WM8731-based Endrelia Technologies Inc ETI-B1 or ETI-C1 boards.
This can then tell the build system (via the select keyword above) that your board driver depends on the AT91 platform driver and your codec.
Liam
Liam:
It's probably going to be easier in the long run to copy your driver
code to linux/sound/soc/at91 and then add an entry for your driver in the linux/sound/soc/at91/ Makefile & Kconfig
e.g. for Kconfig
config SND_AT91_SOC_ETI_B1_WM8731 tristate "SoC Audio support for WM8731-based Endrelia ETI-B1 boards" depends on SND_AT91_SOC && (MACH_ETI_B1 || MACH_ETI_C1) select SND_AT91_SOC_SSC select SND_SOC_WM8731 help Say Y if you want to add support for SoC audio on WM8731-based Endrelia Technologies Inc ETI-B1 or ETI-C1 boards.
This can then tell the build system (via the select keyword above) that your board driver depends on the AT91 platform driver and your codec.
Liam
Thanks for the tips. I have rewritten my Kconfig file so that it looks like this:
config SND_AT91_SOC tristate "SoC Audio for the Atmel AT91 System-on-Chip" depends on ARCH_AT91 && SND_SOC help Say Y or M if you want to add support for codecs attached to the AT91 SSC interface. You will also need to select the audio interfaces to support below.
config SND_AT91_SOC_SSC tristate
config SND_AT91_SOC_AT91SAM9260_EK_W6811 tristate "SoC Audio support for at91sam9260ek boards with W6811 codec" depends on SND_AT91_SOC && MACH_AT91SAM9260EK select SND_AT91_SOC_SSC select SND_SOC_W6811 help Say Y if you want to add support for SoC audio on AT91SAM9260EK boards with a W6811 codec.
config SND_AT91_SOC_ETI_SLAVE bool "Run codec in slave Mode on AT91SAM9260EK" depends on SND_AT91_SOC_AT91SAM9260EK_W6811 default n help Say Y if you want to run with the AT91 SSC generating the BCLK and LRC signals.
...and my Makefile so that it looks like this:
# AT91 Platform Support snd-soc-at91-objs := at91-pcm.o snd-soc-at91-ssc-objs := at91-ssc.o
obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o obj-$(CONFIG_SND_AT91_SOC_SSC) += snd-soc-at91-ssc.o
# AT91 Machine Support snd-soc-at91sam9260ek-w6811-objs := at91sam9260ek-w6811.o
obj-$(CONFIG_SND_AT91_SOC_ETI_B1_WM8731) += snd-soc-at91sam9260ek-w6811.o
...and I renamed the source to reflect what I think you have done. The source now lives in /linux- 2.6.22-rc1/sound/soc/at91/. I did a make clean and a at91sam9260ek_defconfig. Then in menuconfig my new option comes up.
I have selected it and then compiled the kernel. Now, when I go to boot the board with 2.6.22-rc1 I get:
## Booting image at 22100000 ... Image Name: Linux-2.6.22-rc1 Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 1068884 Bytes = 1 MB Load Address: 20008000 Entry Point: 20008000 Verifying Checksum ... OK OK
Starting kernel ...
Uncompressing Linux...................................................................... done, boo.
and it hangs here, which is probably more related to the kernel than to my new config stuff. I will have to solve this so I can see what I get when the system fully boots.
Anything above that you see as an obvious error?
Thanks.
Paul
I think I have my driver compiling and such with the kernel. I had an error in my last Kconfig and Makefile, which I hope I have fixed. It appears to be making correctly. I will attach the three files if anyone would like to view them.
I am still working on getting linux2.6.22-rc1 booting correctly. Once I have that, I should be able to evaluate the driver a little better.
I also believe I am going to need alsa-libs. I will try to locate those and get them cross-compiled asap.
If anyone has pointers on my Kconfig, Makefile, or driver--or on how to get linux booting, please feel free to give them to me.
Thanks.
Paul
I now have the linux-2.6.22-rc1 kernel booting correctly without the aSoC driver activated in .config. However, when I rebuild with the aSoC and then boot, I get the following crash:
.snip. Advanced Linux Sound Architecture Driver Version 1.0.14rc4 (Wed May 09 09:51:39 2007 UTC). ASoC version 0.13.0 Unable to handle kernel NULL pointer dereference at virtual address 00000001 pgd = c0004000 [00000001] *pgd=00000000 Internal error: Oops: 801 [#1] Modules linked in: CPU: 0 PC is at grh_ek_w6811_init+0x4c/0x11c LR is at __arm_ioremap_pfn+0x2cc/0x2ec pc : [<c0019c44>] lr : [<c00285f4>] Not tainted sp : c02e1f74 ip : 00000000 fp : c02e1f8c r10: 00000000 r9 : 00000000 r8 : c02e0000 r7 : 00000000 r6 : c001d54c r5 : 00000000 r4 : 00000001 r3 : 00000000 r2 : 00000004 r1 : fffbf000 r0 : c4830000 Flags: NzCv IRQs on FIQs on Mode SVC_32 Segment kernel Control: 5317F Table: 20004000 DAC: 00000017 Process swapper (pid: 1, stack limit = 0xc02e0258) Stack: (0xc02e1f74 to 0xc02e2000) 1f60: c001e404 00000000 c001d54c 1f80: c02e1ff4 c02e1f90 c0008924 c0019c08 00000000 73f7f554 00000000 00000000 1fa0: 00000000 c02e1fb0 c0021ec4 c0032f70 00000000 00000000 c000886c c0038d30 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 1fe0: 00000000 00000000 00000000 c02e1ff8 c0038d30 c000887c 0987e45b 736275d9 Backtrace: [<c0019bf8>] (grh_ek_w6811_init+0x0/0x11c) from [<c0008924>] (kernel_init+0xb8/0x284) r6:c001d54c r5:00000000 r4:c001e404 [<c000886c>] (kernel_init+0x0/0x284) from [<c0038d30>] (do_exit+0x0/0x7b4) Code: e3a01901 e3a02000 eb003a74 e3500000 (e5840000) Kernel panic - not syncing: Attempted to kill init! .snip.
I am not the best at deciphering these, but I believe the error is in my driver init function...and probably something to do with memory. Is anyone better at analyzing these?
Thanks.
Paul
On Mon, 2007-06-18 at 12:07 -0500, Paul Kavan wrote:
I now have the linux-2.6.22-rc1 kernel booting correctly without the aSoC driver activated in .config. However, when I rebuild with the aSoC and then boot, I get the following crash:
.snip. Advanced Linux Sound Architecture Driver Version 1.0.14rc4 (Wed May 09 09:51:39 2007 UTC). ASoC version 0.13.0 Unable to handle kernel NULL pointer dereference at virtual address 00000001 pgd = c0004000 [00000001] *pgd=00000000 Internal error: Oops: 801 [#1] Modules linked in: CPU: 0 PC is at grh_ek_w6811_init+0x4c/0x11c LR is at __arm_ioremap_pfn+0x2cc/0x2ec
You have a NULL pointer dereference in grh_ek_w6811_init(), most likely to be ssc as the dai private data wont be set yet. i.e.
struct at91_ssc_periph *ssc = grh_ek_w6811_dai.cpu_dai->private_data;
Liam
On Mon, 2007-06-18 at 18:15 +0100, Liam Girdwood wrote:
On Mon, 2007-06-18 at 12:07 -0500, Paul Kavan wrote:
I now have the linux-2.6.22-rc1 kernel booting correctly without the aSoC driver activated in .config. However, when I rebuild with the aSoC and then boot, I get the following crash:
.snip. Advanced Linux Sound Architecture Driver Version 1.0.14rc4 (Wed May 09 09:51:39 2007 UTC). ASoC version 0.13.0 Unable to handle kernel NULL pointer dereference at virtual address 00000001 pgd = c0004000 [00000001] *pgd=00000000 Internal error: Oops: 801 [#1] Modules linked in: CPU: 0 PC is at grh_ek_w6811_init+0x4c/0x11c LR is at __arm_ioremap_pfn+0x2cc/0x2ec
You have a NULL pointer dereference in grh_ek_w6811_init(), most likely to be ssc as the dai private data wont be set yet. i.e.
struct at91_ssc_periph *ssc = grh_ek_w6811_dai.cpu_dai->private_data;
Forgot to add the deref itself :-
ssc->base = ioremap(AT91SAM9260_BASE_SSC, SZ_16K);
ssc is probably NULL.
Liam
participants (2)
-
Liam Girdwood
-
Paul Kavan