[alsa-devel] [RFC 0/5] ASoC multi-component support : core
ASoC is now coming up to it's 5th birthday and is beginning to show it's age a little when it comes to supporting the next generation of smart phones and multimedia devices with it's current single CODEC and single DMA platform design.
Historically, ASoC is designed around an embedded sound card with a single CODEC and a single platform DMA driver (with multiple DAIs). This design works great for most of the current audio hardware in production, however we are now seeing hardware designs for the next generation of devices that can have many CODECs, DMAs, DSPs and a host of other audio peripherals connected to the audio subsystem.
So we now need ASoC to support new audio hardware architectures with multiple audio CODECs, DMA engines, DSPs, DAIs etc.
This patch series allows an ASoC sound card to support multiple components (CODECs, DAI and DMA) and is the first part in a series of work (other parts coming later in the year from Mark and I) designed to enhance ASoC for modern mobile audio hardware.
This patch series provides the following important features:-
1) Allow sound cards to have multiple CODECs and platform DMA controllers. 2) Allow CODEC drivers to support more than one CODEC device. 3) Allow all CODEC, platform DMA and DAI drivers to have platform data.
This is achieved by: -
1) Separating the component struct driver data from the component struct device data. 2) Making all components kernel devices.
(A side effect of this change is that we can now store all our component private data in struct device private data (like everyone else) and there is also now less pointer indirection for components.)
The change mainly affects only the probe() and remove() sections of component drivers and the component enumeration section of the core. The core also now handles setting up the CODEC data structs too (meaning CODEC drivers dont have to do this). All component PCM, DAPM and Kcontrol operations remain unchanged.
I've so far tested the new multi-component enumeration on the TI OMAP and Marvell PXA platforms with AC97, MFD and I2C based CODECs. I do however need ASoC platform maintainers to test on their systems (as I only have a subset of the hardware). Some ASOC platforms do need a little extra checking/fixups too :-
o Samsung platform: required the most work to untangle the components. o i.MX platform: required work to de-couple components. o Injenic J4740 platform: I do not have a toolchain to even build this arch so it will also need someone to build it too.
If you find your platform does not work then the most likely reason is that I'm missing a platform_device registration for your CODEC, DAI, etc. device in your arch board.c or device.c files. Please let me know or send a patch :)
All the multi-component code is in my multi-component branch here :-
git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6.git
This RFC post contains the changes to ASoC core only. I'll post the multi-component CODEC and platform changes as separate RFCs in order not to flood the list (as there are 38 patches in all). This patch series will eventually be rebased into a single patch for upstream so we dont break bisect. The subsequent patches for CODECs and platforms in this series can be found in the git branch above.
The intention is to upstream this for 2.6.36
Thanks
Liam
On 06/25/2010 07:24 AM, Liam Girdwood wrote:
If you find your platform does not work then the most likely reason is that I'm missing a platform_device registration for your CODEC, DAI, etc. device in your arch board.c or device.c files. Please let me know or send a patch :)
Hi Liam,
The following patch fixes the build errors and warnings for the ep93xx/Snapper CL15. However, I still get 'No soundcards found' during boot. The ep3xx-pcm-audio, ep93xx-i2s and soc-audio devices are all present under /sys/bus/platform/devices. Any ideas?
Signed-off-by: Ryan Mallon ryan@bluewatersys.com ---
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 67dc876..b5261d4 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -732,9 +732,15 @@ static struct platform_device ep93xx_i2s_device = { .resource = ep93xx_i2s_resource, };
+static struct platform_device ep93xx_pcm_device = { + .name = "ep93xx-pcm-audio", + .id = -1, +}; + void __init ep93xx_register_i2s(void) { platform_device_register(&ep93xx_i2s_device); + platform_device_register(&ep93xx_pcm_device); }
#define EP93XX_SYSCON_DEVCFG_I2S_MASK (EP93XX_SYSCON_DEVCFG_I2SONSSP | \ @@ -798,6 +804,4 @@ void __init ep93xx_init_devices(void) platform_device_register(&ep93xx_rtc_device); platform_device_register(&ep93xx_ohci_device); platform_device_register(&ep93xx_leds); - platform_device_register(&ep93xx_i2s_device); - platform_device_register(&ep93xx_pcm_device); } diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c index b40201f..6e0fa03 100644 --- a/sound/soc/ep93xx/ep93xx-i2s.c +++ b/sound/soc/ep93xx/ep93xx-i2s.c @@ -146,6 +146,7 @@ static int ep93xx_i2s_startup(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
snd_soc_dai_set_dma_data(cpu_dai, substream, &info->dma_params[substream->stream]); @@ -155,7 +156,6 @@ static int ep93xx_i2s_startup(struct snd_pcm_substream *substream, static void ep93xx_i2s_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
ep93xx_i2s_disable(info, substream->stream); @@ -241,7 +241,6 @@ static int ep93xx_i2s_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 ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); unsigned word_len, div, sdiv, lrdiv; int found = 0, err; diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c index 6495534..c34aa1f 100644 --- a/sound/soc/ep93xx/snappercl15.c +++ b/sound/soc/ep93xx/snappercl15.c @@ -30,8 +30,8 @@ static int snappercl15_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 *codec_dai = rtd->dai->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int err;
err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | @@ -77,8 +77,10 @@ static const struct snd_soc_dapm_route audio_map[] = { {"MICIN", NULL, "Mic Jack"}, };
-static int snappercl15_tlv320aic23_init(struct snd_soc_codec *codec) +static int snappercl15_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_codec *codec = rtd->codec; + snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, ARRAY_SIZE(tlv320aic23_dapm_widgets));
@@ -89,24 +91,19 @@ static int snappercl15_tlv320aic23_init(struct snd_soc_codec *codec) static struct snd_soc_dai_link snappercl15_dai = { .name = "tlv320aic23", .stream_name = "AIC23", - .cpu_dai = &ep93xx_i2s_dai, - .codec_dai = &tlv320aic23_dai, + .cpu_dai_drv = &ep93xx_i2s_dai, + .codec_dai_drv = &tlv320aic23_dai, + .platform_drv = &ep93xx_soc_platform, .init = snappercl15_tlv320aic23_init, .ops = &snappercl15_ops, };
static struct snd_soc_card snd_soc_snappercl15 = { .name = "Snapper CL15", - .platform = &ep93xx_soc_platform, .dai_link = &snappercl15_dai, .num_links = 1, };
-static struct snd_soc_device snappercl15_snd_devdata = { - .card = &snd_soc_snappercl15, - .codec_dev = &soc_codec_dev_tlv320aic23, -}; - static struct platform_device *snappercl15_snd_device;
static int __init snappercl15_init(void) @@ -126,8 +123,7 @@ static int __init snappercl15_init(void) if (!snappercl15_snd_device) return -ENOMEM; - platform_set_drvdata(snappercl15_snd_device, &snappercl15_snd_devdata); - snappercl15_snd_devdata.dev = &snappercl15_snd_device->dev; + platform_set_drvdata(snappercl15_snd_device, &snd_soc_snappercl15); ret = platform_device_add(snappercl15_snd_device); if (ret) platform_device_put(snappercl15_snd_device);
On 24 Jun 2010, at 22:36, Ryan Mallon wrote:
The following patch fixes the build errors and warnings for the ep93xx/Snapper CL15. However, I still get 'No soundcards found' during
Please provide a proper changelog for patches.
boot. The ep3xx-pcm-audio, ep93xx-i2s and soc-audio devices are all present under /sys/bus/platform/devices. Any ideas?
Do you actually see sound cards appearing? The log message at boot is purely informational, cards can probe at any time.
Define DEBUG at the top of soc-audio.c if the card never appears at all then look at the log messages - they will say why the card is not being instantiated.
On 06/25/2010 11:12 AM, Mark Brown wrote:
On 24 Jun 2010, at 22:36, Ryan Mallon wrote:
The following patch fixes the build errors and warnings for the ep93xx/Snapper CL15. However, I still get 'No soundcards found' during
Please provide a proper changelog for patches.
Sorry, changelog should be: "Fix build errors and warnings for ep93xx/snapper cl15 asoc multi-component support"
boot. The ep3xx-pcm-audio, ep93xx-i2s and soc-audio devices are all present under /sys/bus/platform/devices. Any ideas?
Do you actually see sound cards appearing? The log message at boot is purely informational, cards can probe at any time.
Define DEBUG at the top of soc-audio.c if the card never appears at all then look at the log messages - they will say why the card is not being instantiated.
Hmm. If I define DEBUG at the top of sound/soc/soc-core.c I get this (boots fine without DEBUG, but have no sound cards): ---
Uncompressing Linux... done, booting the kernel. Linux version 2.6.35-rc1-00115-g0682e62-dirty (ryan@okiwi) (gcc version 4.4.1 (Sourcery G++ Lite 2009q3-67) ) #713 Fri Jun 25 11:34:15 NZST 2010 CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177 CPU: VIVT data cache, VIVT instruction cache Machine: Bluewater Systems Snapper CL15 Memory policy: ECC disabled, Data cache writeback Built 1 zonelists in Zone order, mobility grouping on. Total pages: 15952 Kernel command line: console=ttyAM0,115200 lcd=sony baseboard=Rig200 snapper_baseboard=Rig200 baseboard_rev= ethaddr=00:50:C2:41:A5:41 ip=any nfsroot=/export/root,v3,rsize=1024,wsize=1024 PID hash table entries: 256 (order: -2, 1024 bytes) Dentry cache hash table entries: 8192 (order: 3, 32768 bytes) Inode-cache hash table entries: 4096 (order: 2, 16384 bytes) Memory: 8MB 8MB 8MB 8MB 8MB 8MB 8MB 8MB = 64MB total Memory: 61332k/61332k available, 4204k reserved, 0K highmem Virtual kernel memory layout: vector : 0xffff0000 - 0xffff1000 ( 4 kB) fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB) DMA : 0xffc00000 - 0xffe00000 ( 2 MB) vmalloc : 0xce000000 - 0xfe800000 ( 776 MB) lowmem : 0xc0000000 - 0xcd800000 ( 216 MB) modules : 0xbf000000 - 0xc0000000 ( 16 MB) .init : 0xc0008000 - 0xc0020000 ( 96 kB) .text : 0xc0020000 - 0xc0341000 (3204 kB) .data : 0xc035a000 - 0xc0378480 ( 122 kB) Hierarchical RCU implementation. RCU-based detection of stalled CPUs is disabled. Verbose stalled-CPUs detection is disabled. NR_IRQS:120 VIC @fefb0000: id 0x00041190, vendor 0x41 VIC @fefc0000: id 0x00041190, vendor 0x41 Calibrating delay loop... 99.73 BogoMIPS (lpj=498688) pid_max: default: 32768 minimum: 301 Mount-cache hash table entries: 512 CPU: Testing write buffer coherency: ok NET: Registered protocol family 16 ep93xx clock: PLL1 running at 199 MHz, PLL2 at 192 MHz ep93xx clock: FCLK 199 MHz, HCLK 99 MHz, PCLK 49 MHz ep93xx dma_m2p: M2P DMA subsystem initialized bio: create slab <bio-0> at 0 SCSI subsystem initialized usbcore: registered new interface driver usbfs usbcore: registered new interface driver hub usbcore: registered new device driver usb i2c-gpio i2c-gpio.0: using pins 49 (SDA) and 48 (SCL) Advanced Linux Sound Architecture Driver Version 1.0.23. NET: Registered protocol family 2 IP route cache hash table entries: 1024 (order: 0, 4096 bytes) TCP established hash table entries: 2048 (order: 2, 16384 bytes) TCP bind hash table entries: 2048 (order: 3, 40960 bytes) TCP: Hash tables configured (established 2048 bind 2048) TCP reno registered UDP hash table entries: 128 (order: 0, 6144 bytes) UDP-Lite hash table entries: 128 (order: 0, 6144 bytes) NET: Registered protocol family 1 RPC: Registered udp transport module. RPC: Registered tcp transport module. RPC: Registered tcp NFSv4.1 backchannel transport module. NetWinder Floating Point Emulator V0.97 (extended precision) JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc. msgmni has been set to 119 io scheduler noop registered io scheduler deadline registered (default) Serial: AMBA driver apb:uart1: ttyAM0 at MMIO 0x808c0000 (irq = 52) is a AMBA console [ttyAM0] enabled apb:uart2: ttyAM1 at MMIO 0x808d0000 (irq = 54) is a AMBA apb:uart3: ttyAM2 at MMIO 0x808e0000 (irq = 55) is a AMBA nbd: registered device at major 43 ep93xx-eth version 0.1 loading eth0: ep93xx on-chip ethernet, IRQ 39, 00:50:c2:41:a5:41 rtl8150: v0.6.2 (2004/08/27):rtl8150 based usb-ethernet driver usbcore: registered new interface driver rtl8150 ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver ep93xx-ohci ep93xx-ohci: EP93xx OHCI ep93xx-ohci ep93xx-ohci: new USB bus registered, assigned bus number 1 ep93xx-ohci ep93xx-ohci: irq 56, io mem 0x80020000 usb usb1: New USB device found, idVendor=1d6b, idProduct=0001 usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1 usb usb1: Product: EP93xx OHCI usb usb1: Manufacturer: Linux 2.6.35-rc1-00115-g0682e62-dirty ohci_hcd usb usb1: SerialNumber: ep93xx hub 1-0:1.0: USB hub found hub 1-0:1.0: 3 ports detected Initializing USB Mass Storage driver... usbcore: registered new interface driver usb-storage USB Mass Storage support registered. usbcore: registered new interface driver usbserial usbserial: USB Serial Driver core USB Serial support registered for pl2303 usbcore: registered new interface driver pl2303 pl2303: Prolific PL2303 USB to serial adaptor driver ep93xx-rtc ep93xx-rtc: rtc core: registered ep93xx-rtc as rtc0 i2c /dev entries driver ep93xx_wdt: EP93XX watchdog, driver version 0.3 Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = c0004000 [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] last sysfs file: Modules linked in: CPU: 0 Not tainted (2.6.35-rc1-00115-g0682e62-dirty #713) PC is at snd_soc_instantiate_cards+0x210/0x9b8 LR is at snd_soc_instantiate_cards+0x1f4/0x9b8 pc : [<c01d1a5c>] lr : [<c01d1a40>] psr: 60000013 sp : cd41be58 ip : 22222222 fp : cd54c328 r10: 00000000 r9 : 00000000 r8 : 00000000 r7 : cd555de0 r6 : 00000002 r5 : c0371164 r4 : c03710c8 r3 : 00000000 r2 : cd554740 r1 : c031de15 r0 : c031d7ee Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel Control: c000717f Table: c0004000 DAC: 00000017 Process swapper (pid: 1, stack limit = 0xcd41a270) Stack: (0xcd41be58 to 0xcd41c000) be40: c03674b0 00000000 be60: 00000000 cd405b24 c03710e0 c03674c0 cd41bec4 c01440a8 000000a5 cd40de60 be80: 00000000 c008a288 cd4080a0 000080d0 cd4080a0 000080d0 c03674a0 cd562b18 bea0: c0367478 c028981c cd400440 cd555dc0 c01d226c c0089edc 000000a5 cd400440 bec0: cd41bed0 c0370afc c0370afc c0289a84 22222222 22222222 22222222 c03710c8 bee0: c0370a60 c03710d8 c0370a74 00000000 00000000 00000000 00000000 c01d2308 bf00: cd54c328 cd54c328 00000000 c0168d08 c0168cf0 c0167e48 c0168e8c cd54c328 bf20: c0167f7c 00000000 00000000 c016743c cd429f28 cd563964 cd54c35c cd54c328 bf40: c036a940 c0168030 00000001 cd54c328 cd54c330 c0167274 cd54c328 c0165f18 bf60: cd54c330 00000000 00000000 00000000 00000000 c0145050 cd54c320 cd54c320 bf80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c01691b8 bfa0: ffffffff c0385aa4 00000000 00000000 00000000 c0015558 c0378520 c001550c bfc0: 00000000 c002038c c001550c c02f8205 c0378520 c001c0e0 c001c078 00000000 bfe0: 00000000 00000000 00000000 c0008570 00000000 c0021e94 114c33c4 338c33cc [<c01d1a5c>] (snd_soc_instantiate_cards+0x210/0x9b8) from [<c01d2308>] (soc_probe+0x104/0x180) [<c01d2308>] (soc_probe+0x104/0x180) from [<c0168d08>] (platform_drv_probe+0x18/0x1c) [<c0168d08>] (platform_drv_probe+0x18/0x1c) from [<c0167e48>] (driver_probe_device+0xb0/0x168) [<c0167e48>] (driver_probe_device+0xb0/0x168) from [<c016743c>] (bus_for_each_drv+0x48/0x84) [<c016743c>] (bus_for_each_drv+0x48/0x84) from [<c0168030>] (device_attach+0x50/0x68) [<c0168030>] (device_attach+0x50/0x68) from [<c0167274>] (bus_probe_device+0x24/0x40) [<c0167274>] (bus_probe_device+0x24/0x40) from [<c0165f18>] (device_add+0x3c8/0x50c) [<c0165f18>] (device_add+0x3c8/0x50c) from [<c01691b8>] (platform_device_add+0x104/0x15c) [<c01691b8>] (platform_device_add+0x104/0x15c) from [<c0015558>] (snappercl15_init+0x4c/0x70) [<c0015558>] (snappercl15_init+0x4c/0x70) from [<c002038c>] (do_one_initcall+0x5c/0x1b8) [<c002038c>] (do_one_initcall+0x5c/0x1b8) from [<c0008570>] (kernel_init+0x94/0x140) [<c0008570>] (kernel_init+0x94/0x140) from [<c0021e94>] (kernel_thread_exit+0x0/0x8) Code: e59f0754 e3520000 05932008 e5953024 (e5933000) ---[ end trace 6c9baca808808ee5 ]--- Kernel panic - not syncing: Attempted to kill init! [<c0026474>] (unwind_backtrace+0x0/0xec) from [<c028895c>] (panic+0x54/0xdc) [<c028895c>] (panic+0x54/0xdc) from [<c003fe30>] (do_exit+0x64/0x580) [<c003fe30>] (do_exit+0x64/0x580) from [<c0024858>] (die+0x190/0x1c0) [<c0024858>] (die+0x190/0x1c0) from [<c00274ac>] (__do_kernel_fault+0x64/0x84) [<c00274ac>] (__do_kernel_fault+0x64/0x84) from [<c002767c>] (do_page_fault+0x1b0/0x1c4) [<c002767c>] (do_page_fault+0x1b0/0x1c4) from [<c00202d0>] (do_DataAbort+0x34/0x94) [<c00202d0>] (do_DataAbort+0x34/0x94) from [<c0020a00>] (__dabt_svc+0x40/0x60) Exception stack(0xcd41be10 to 0xcd41be58) be00: c031d7ee c031de15 cd554740 00000000 be20: c03710c8 c0371164 00000002 cd555de0 00000000 00000000 00000000 cd54c328 be40: 22222222 cd41be58 c01d1a40 c01d1a5c 60000013 ffffffff [<c0020a00>] (__dabt_svc+0x40/0x60) from [<c01d1a5c>] (snd_soc_instantiate_cards+0x210/0x9b8) [<c01d1a5c>] (snd_soc_instantiate_cards+0x210/0x9b8) from [<c01d2308>] (soc_probe+0x104/0x180) [<c01d2308>] (soc_probe+0x104/0x180) from [<c0168d08>] (platform_drv_probe+0x18/0x1c) [<c0168d08>] (platform_drv_probe+0x18/0x1c) from [<c0167e48>] (driver_probe_device+0xb0/0x168) [<c0167e48>] (driver_probe_device+0xb0/0x168) from [<c016743c>] (bus_for_each_drv+0x48/0x84) [<c016743c>] (bus_for_each_drv+0x48/0x84) from [<c0168030>] (device_attach+0x50/0x68) [<c0168030>] (device_attach+0x50/0x68) from [<c0167274>] (bus_probe_device+0x24/0x40) [<c0167274>] (bus_probe_device+0x24/0x40) from [<c0165f18>] (device_add+0x3c8/0x50c) [<c0165f18>] (device_add+0x3c8/0x50c) from [<c01691b8>] (platform_device_add+0x104/0x15c) [<c01691b8>] (platform_device_add+0x104/0x15c) from [<c0015558>] (snappercl15_init+0x4c/0x70) [<c0015558>] (snappercl15_init+0x4c/0x70) from [<c002038c>] (do_one_initcall+0x5c/0x1b8) [<c002038c>] (do_one_initcall+0x5c/0x1b8) from [<c0008570>] (kernel_init+0x94/0x140) [<c0008570>] (kernel_init+0x94/0x140) from [<c0021e94>] (kernel_thread_exit+0x0/0x8)
On 06/25/2010 11:38 AM, Ryan Mallon wrote:
On 06/25/2010 11:12 AM, Mark Brown wrote:
Do you actually see sound cards appearing? The log message at boot is purely informational, cards can probe at any time.
Define DEBUG at the top of soc-audio.c if the card never appears at all then look at the log messages - they will say why the card is not being instantiated.
Hmm. If I define DEBUG at the top of sound/soc/soc-core.c I get this (boots fine without DEBUG, but have no sound cards):
The crash was caused because I wasn't setting codec_drv in the snd_soc_dai_link for the Snapper CL15 (updated patch below). I still have no sound cards. I get the following in dmesg:
tlv320aic23 0-001a: probe tlv320aic23 0-001a: codec register tlv320aic23 26 tlv320aic23 0-001a: dai register tlv320aic23 0 Registered DAI 'tlv320aic23.0' Registered codec 'tlv320aic23.26' i2c-core: driver [tlv320aic23] registered ep93xx-pcm-audio ep93xx-pcm-audio: platform register ep93xx-audio -1 Registered platform 'ep93xx-audio' ep93xx-i2s ep93xx-i2s: dai register ep93xx-i2s -1 Registered DAI 'ep93xx-i2s.-1' soc-audio soc-audio: CODEC tlv320aic23 not registered soc-audio soc-audio: Registered card 'Snapper CL15' ALSA device list: No soundcards found.
I don't understand why the tlv320 codec is not being registered. Any ideas?
~Ryan
--- Fix build errors and warnings for ep93xx/snapper cl15 asoc multi-component support
Signed-off-by: Ryan Mallon ryan@bluewatersys.com ---
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 67dc876..b5261d4 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -732,9 +732,15 @@ static struct platform_device ep93xx_i2s_device = { .resource = ep93xx_i2s_resource, };
+static struct platform_device ep93xx_pcm_device = { + .name = "ep93xx-pcm-audio", + .id = -1, +}; + void __init ep93xx_register_i2s(void) { platform_device_register(&ep93xx_i2s_device); + platform_device_register(&ep93xx_pcm_device); }
#define EP93XX_SYSCON_DEVCFG_I2S_MASK (EP93XX_SYSCON_DEVCFG_I2SONSSP | \ @@ -798,6 +804,4 @@ void __init ep93xx_init_devices(void) platform_device_register(&ep93xx_rtc_device); platform_device_register(&ep93xx_ohci_device); platform_device_register(&ep93xx_leds); - platform_device_register(&ep93xx_i2s_device); - platform_device_register(&ep93xx_pcm_device); } diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c index b40201f..6e0fa03 100644 --- a/sound/soc/ep93xx/ep93xx-i2s.c +++ b/sound/soc/ep93xx/ep93xx-i2s.c @@ -146,6 +146,7 @@ static int ep93xx_i2s_startup(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
snd_soc_dai_set_dma_data(cpu_dai, substream, &info->dma_params[substream->stream]); @@ -155,7 +156,6 @@ static int ep93xx_i2s_startup(struct snd_pcm_substream *substream, static void ep93xx_i2s_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
ep93xx_i2s_disable(info, substream->stream); @@ -241,7 +241,6 @@ static int ep93xx_i2s_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 ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); unsigned word_len, div, sdiv, lrdiv; int found = 0, err; diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c index 6495534..aeb822d 100644 --- a/sound/soc/ep93xx/snappercl15.c +++ b/sound/soc/ep93xx/snappercl15.c @@ -30,8 +30,8 @@ static int snappercl15_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 *codec_dai = rtd->dai->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int err;
err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | @@ -77,8 +77,10 @@ static const struct snd_soc_dapm_route audio_map[] = { {"MICIN", NULL, "Mic Jack"}, };
-static int snappercl15_tlv320aic23_init(struct snd_soc_codec *codec) +static int snappercl15_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_codec *codec = rtd->codec; + snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, ARRAY_SIZE(tlv320aic23_dapm_widgets));
@@ -89,24 +91,20 @@ static int snappercl15_tlv320aic23_init(struct snd_soc_codec *codec) static struct snd_soc_dai_link snappercl15_dai = { .name = "tlv320aic23", .stream_name = "AIC23", - .cpu_dai = &ep93xx_i2s_dai, - .codec_dai = &tlv320aic23_dai, + .cpu_dai_drv = &ep93xx_i2s_dai, + .codec_dai_drv = &tlv320aic23_dai, + .codec_drv = &soc_codec_dev_tlv320aic23, + .platform_drv = &ep93xx_soc_platform, .init = snappercl15_tlv320aic23_init, .ops = &snappercl15_ops, };
static struct snd_soc_card snd_soc_snappercl15 = { .name = "Snapper CL15", - .platform = &ep93xx_soc_platform, .dai_link = &snappercl15_dai, .num_links = 1, };
-static struct snd_soc_device snappercl15_snd_devdata = { - .card = &snd_soc_snappercl15, - .codec_dev = &soc_codec_dev_tlv320aic23, -}; - static struct platform_device *snappercl15_snd_device;
static int __init snappercl15_init(void) @@ -126,8 +124,7 @@ static int __init snappercl15_init(void) if (!snappercl15_snd_device) return -ENOMEM; - platform_set_drvdata(snappercl15_snd_device, &snappercl15_snd_devdata); - snappercl15_snd_devdata.dev = &snappercl15_snd_device->dev; + platform_set_drvdata(snappercl15_snd_device, &snd_soc_snappercl15); ret = platform_device_add(snappercl15_snd_device); if (ret) platform_device_put(snappercl15_snd_device);
On Fri, 2010-06-25 at 16:51 +1200, Ryan Mallon wrote:
On 06/25/2010 11:38 AM, Ryan Mallon wrote:
On 06/25/2010 11:12 AM, Mark Brown wrote:
Do you actually see sound cards appearing? The log message at boot is purely informational, cards can probe at any time.
Define DEBUG at the top of soc-audio.c if the card never appears at all then look at the log messages - they will say why the card is not being instantiated.
Hmm. If I define DEBUG at the top of sound/soc/soc-core.c I get this (boots fine without DEBUG, but have no sound cards):
The crash was caused because I wasn't setting codec_drv in the snd_soc_dai_link for the Snapper CL15 (updated patch below). I still have no sound cards. I get the following in dmesg:
tlv320aic23 0-001a: probe tlv320aic23 0-001a: codec register tlv320aic23 26 tlv320aic23 0-001a: dai register tlv320aic23 0 Registered DAI 'tlv320aic23.0' Registered codec 'tlv320aic23.26' i2c-core: driver [tlv320aic23] registered ep93xx-pcm-audio ep93xx-pcm-audio: platform register ep93xx-audio -1 Registered platform 'ep93xx-audio' ep93xx-i2s ep93xx-i2s: dai register ep93xx-i2s -1 Registered DAI 'ep93xx-i2s.-1' soc-audio soc-audio: CODEC tlv320aic23 not registered soc-audio soc-audio: Registered card 'Snapper CL15' ALSA device list: No soundcards found.
I don't understand why the tlv320 codec is not being registered. Any ideas?
Since we now support N codecs, some codecs will now require an ID field to distinguish them from others. e.g. a board with two WM8750 codecs would have codecs at I2C addresses 0x1a and 0x1b, hence will require each codec to be identified on the DAI link.
Can you try this patch below. From the output it looks like your tlv320aic23 is at I2C address 26.
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c index aeb822d..72b7913 100644 --- a/sound/soc/ep93xx/snappercl15.c +++ b/sound/soc/ep93xx/snappercl15.c @@ -94,6 +94,7 @@ static struct snd_soc_dai_link snappercl15_dai = { .cpu_dai_drv = &ep93xx_i2s_dai, .codec_dai_drv = &tlv320aic23_dai, .codec_drv = &soc_codec_dev_tlv320aic23, + .codec_id = 26, .platform_drv = &ep93xx_soc_platform, .init = snappercl15_tlv320aic23_init, .ops = &snappercl15_ops,
~Ryan
Fix build errors and warnings for ep93xx/snapper cl15 asoc multi-component support
Signed-off-by: Ryan Mallon ryan@bluewatersys.com
Thanks. Applied.
Liam
Liam Girdwood wrote:
On Fri, 2010-06-25 at 16:51 +1200, Ryan Mallon wrote:
On 06/25/2010 11:38 AM, Ryan Mallon wrote:
On 06/25/2010 11:12 AM, Mark Brown wrote:
Do you actually see sound cards appearing? The log message at boot is purely informational, cards can probe at any time.
Define DEBUG at the top of soc-audio.c if the card never appears at all then look at the log messages - they will say why the card is not being instantiated.
Hmm. If I define DEBUG at the top of sound/soc/soc-core.c I get this (boots fine without DEBUG, but have no sound cards):
The crash was caused because I wasn't setting codec_drv in the snd_soc_dai_link for the Snapper CL15 (updated patch below). I still have no sound cards. I get the following in dmesg:
tlv320aic23 0-001a: probe tlv320aic23 0-001a: codec register tlv320aic23 26 tlv320aic23 0-001a: dai register tlv320aic23 0 Registered DAI 'tlv320aic23.0' Registered codec 'tlv320aic23.26' i2c-core: driver [tlv320aic23] registered ep93xx-pcm-audio ep93xx-pcm-audio: platform register ep93xx-audio -1 Registered platform 'ep93xx-audio' ep93xx-i2s ep93xx-i2s: dai register ep93xx-i2s -1 Registered DAI 'ep93xx-i2s.-1' soc-audio soc-audio: CODEC tlv320aic23 not registered soc-audio soc-audio: Registered card 'Snapper CL15' ALSA device list: No soundcards found.
I don't understand why the tlv320 codec is not being registered. Any ideas?
Since we now support N codecs, some codecs will now require an ID field to distinguish them from others. e.g. a board with two WM8750 codecs would have codecs at I2C addresses 0x1a and 0x1b, hence will require each codec to be identified on the DAI link.
Can you try this patch below. From the output it looks like your tlv320aic23 is at I2C address 26.
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c index aeb822d..72b7913 100644 --- a/sound/soc/ep93xx/snappercl15.c +++ b/sound/soc/ep93xx/snappercl15.c @@ -94,6 +94,7 @@ static struct snd_soc_dai_link snappercl15_dai = { .cpu_dai_drv = &ep93xx_i2s_dai, .codec_dai_drv = &tlv320aic23_dai, .codec_drv = &soc_codec_dev_tlv320aic23,
.codec_id = 26, .platform_drv = &ep93xx_soc_platform, .init = snappercl15_tlv320aic23_init, .ops = &snappercl15_ops,
Ah, that makes sense. I will try the patch on Monday. One thing to note is that in arch/arm/mach-ep93xx/snappercl15.c there is already:
static struct i2c_board_info __initdata snappercl15_i2c_data[] = { { /* Audio codec */ I2C_BOARD_INFO("tlv320aic23", 0x1a), }, };
Is there a clean way to avoid hard-coding the i2c address of the tlv320 codec twice? Can I pass -1 to find any available codec? If not, can you change the patch to 0x1a rather than 26, since i2c addresses tend to be written in hex.
~Ryan
On Sat, 2010-06-26 at 10:38 +1200, Ryan Mallon wrote:
Liam Girdwood wrote:
On Fri, 2010-06-25 at 16:51 +1200, Ryan Mallon wrote:
I don't understand why the tlv320 codec is not being registered. Any ideas?
Since we now support N codecs, some codecs will now require an ID field to distinguish them from others. e.g. a board with two WM8750 codecs would have codecs at I2C addresses 0x1a and 0x1b, hence will require each codec to be identified on the DAI link.
Can you try this patch below. From the output it looks like your tlv320aic23 is at I2C address 26.
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c index aeb822d..72b7913 100644 --- a/sound/soc/ep93xx/snappercl15.c +++ b/sound/soc/ep93xx/snappercl15.c @@ -94,6 +94,7 @@ static struct snd_soc_dai_link snappercl15_dai = { .cpu_dai_drv = &ep93xx_i2s_dai, .codec_dai_drv = &tlv320aic23_dai, .codec_drv = &soc_codec_dev_tlv320aic23,
.codec_id = 26, .platform_drv = &ep93xx_soc_platform, .init = snappercl15_tlv320aic23_init, .ops = &snappercl15_ops,
Ah, that makes sense. I will try the patch on Monday. One thing to note is that in arch/arm/mach-ep93xx/snappercl15.c there is already:
static struct i2c_board_info __initdata snappercl15_i2c_data[] = { { /* Audio codec */ I2C_BOARD_INFO("tlv320aic23", 0x1a), }, };
Is there a clean way to avoid hard-coding the i2c address of the tlv320 codec twice? Can I pass -1 to find any available codec?
Yes, -1 should find any available codec.
If not, can you change the patch to 0x1a rather than 26, since i2c addresses tend to be written in hex.
I've changed to hex and pushed. My preference here is that we keep the hard coded value atm, as planned changes later on will depend on it. The future intention for dai_link is to remove the *_drv pointers and just have the dai_link created from unique IDs. e.g. we will eventually have something like :-
struct snd_soc_dai_link snappercl15_dai = { .cpu_dai_id = SND_SOC_CPU_DAI(EP93XX, I2S, 0), .codec_dai_id = SND_SOC_CODEC_DAI(TLV320AIC23, 0), .codec_id = SND_SOC_I2C_CODEC(TLV320AIC23, 0, 0x1a), .platform_id = SND_SOC_PLATFORM(EP93XX, 0), .init = snappercl15_tlv320aic23_init, .ops = &snappercl15_ops, };
Note: this format has not been decided on yet.
Thanks
Liam
2010/6/25 Liam Girdwood lrg@slimlogic.co.uk:
ASoC is now coming up to it's 5th birthday and is beginning to show it's age a little when it comes to supporting the next generation of smart phones and multimedia devices with it's current single CODEC and single DMA platform design.
Historically, ASoC is designed around an embedded sound card with a single CODEC and a single platform DMA driver (with multiple DAIs). This design works great for most of the current audio hardware in production, however we are now seeing hardware designs for the next generation of devices that can have many CODECs, DMAs, DSPs and a host of other audio peripherals connected to the audio subsystem.
So we now need ASoC to support new audio hardware architectures with multiple audio CODECs, DMA engines, DSPs, DAIs etc.
This patch series allows an ASoC sound card to support multiple components (CODECs, DAI and DMA) and is the first part in a series of work (other parts coming later in the year from Mark and I) designed to enhance ASoC for modern mobile audio hardware.
This patch series provides the following important features:-
1) Allow sound cards to have multiple CODECs and platform DMA controllers. 2) Allow CODEC drivers to support more than one CODEC device. 3) Allow all CODEC, platform DMA and DAI drivers to have platform data.
This is achieved by: -
1) Separating the component struct driver data from the component struct device data. 2) Making all components kernel devices.
(A side effect of this change is that we can now store all our component private data in struct device private data (like everyone else) and there is also now less pointer indirection for components.)
The change mainly affects only the probe() and remove() sections of component drivers and the component enumeration section of the core. The core also now handles setting up the CODEC data structs too (meaning CODEC drivers dont have to do this). All component PCM, DAPM and Kcontrol operations remain unchanged.
I've so far tested the new multi-component enumeration on the TI OMAP and Marvell PXA platforms with AC97, MFD and I2C based CODECs. I do however need ASoC platform maintainers to test on their systems (as I only have a subset of the hardware). Some ASOC platforms do need a little extra checking/fixups too :-
o Samsung platform: required the most work to untangle the components. o i.MX platform: required work to de-couple components. o Injenic J4740 platform: I do not have a toolchain to even build this arch so it will also need someone to build it too.
If you find your platform does not work then the most likely reason is that I'm missing a platform_device registration for your CODEC, DAI, etc. device in your arch board.c or device.c files. Please let me know or send a patch :)
All the multi-component code is in my multi-component branch here :-
git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6.git
I really want to test my nuc900 platform, but the git tree seems to base linux-2.6.31, where nuc900 most platform files not be merged. so I have to wait for 2.6.36 to update and test my driver?
This RFC post contains the changes to ASoC core only. I'll post the multi-component CODEC and platform changes as separate RFCs in order not to flood the list (as there are 38 patches in all). This patch series will eventually be rebased into a single patch for upstream so we dont break bisect. The subsequent patches for CODECs and platforms in this series can be found in the git branch above.
The intention is to upstream this for 2.6.36
Thanks
Liam
Freelance Developer, SlimLogic Ltd ASoC and Voltage Regulator Maintainer. http://www.slimlogic.co.uk
On Sat, 2010-06-26 at 10:25 +0800, Wan ZongShun wrote:
2010/6/25 Liam Girdwood lrg@slimlogic.co.uk:
All the multi-component code is in my multi-component branch here :-
git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6.git
I really want to test my nuc900 platform, but the git tree seems to base linux-2.6.31, where nuc900 most platform files not be merged. so I have to wait for 2.6.36 to update and test my driver?
The multi-component branch is up to date, it's just that the master branch on this tree is at an older version.
Liam
On Thu, 24 Jun 2010 20:24:27 +0100 Liam Girdwood lrg@slimlogic.co.uk wrote:
I've so far tested the new multi-component enumeration on the TI OMAP and Marvell PXA platforms with AC97, MFD and I2C based CODECs. I do however need ASoC platform maintainers to test on their systems (as I only have a subset of the hardware). Some ASOC platforms do need a little extra checking/fixups too :-
I wouldn't expect much problems from OMAPs. Beagle with TWL4030 works out of box and I would expect other boards using TWL4030 to work as well.
If some board doesn't work then fix is most probably just adding .codec_id = I2C address of the codec (or -1) to snd_soc_dai_link structure of that machine.
On Mon, Jun 28, 2010 at 10:16:21AM +0300, Jarkko Nikula wrote:
If some board doesn't work then fix is most probably just adding .codec_id = I2C address of the codec (or -1) to snd_soc_dai_link structure of that machine.
This issue appears to apply to the overwhelming majority of machine drivers.
I suspect that it'd be more straightforward to convert to using a dev_id with NULL as the wildcard match - this allows us to cope with deduping over multiple I2C buses, cope with non-numeric IDs and (more to the point here) will mean that we don't need to go through all the machine drivers initialising the codec_id.
This fixes sparse complaints about the bitfield being signed but only 1 bit wide (so not enough space to store the sign bit).
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com --- include/sound/soc.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index b3fe7a8..fb3093b 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -573,7 +573,7 @@ struct snd_soc_card { struct list_head list; struct mutex mutex;
- int instantiated:1; + bool instantiated;
int (*probe)(struct platform_device *pdev); int (*remove)(struct platform_device *pdev);
On Thu, 2010-07-01 at 20:55 +0100, Mark Brown wrote:
This fixes sparse complaints about the bitfield being signed but only 1 bit wide (so not enough space to store the sign bit).
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com
Applied.
Thanks
Liam
On Thu, Jun 24, 2010 at 08:24:27PM +0100, Liam Girdwood wrote:
ASoC is now coming up to it's 5th birthday and is beginning to show it's age a little when it comes to supporting the next generation of smart phones and multimedia devices with it's current single CODEC and single DMA platform design.
I've done a bit of very light testing here.
One issue I noticed is that most existing platforms don't have a driver registered for the DMA yet and the devices aren't being added when the driver is. I'm thinking that this could be fixed by adding registration of the devices in the driver files where the device is being added for the first time - we can then transition the registrations into the arch code properly later without having to block the merge. Does that sound sane to you?
Other than that I don't think I noticed anything that hasn't previously been reported.
participants (5)
-
Jarkko Nikula
-
Liam Girdwood
-
Mark Brown
-
Ryan Mallon
-
Wan ZongShun