Skip to contentSkip to conversation

ASoC multi-component support : core

RFC In review Liam Girdwood 5 participants 15 messages Jun 24, 2010 – Jul 5, 2010

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

cover 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

Signature · 3 lines
Freelance Developer, SlimLogic Ltd
ASoC and Voltage Regulator Maintainer.
http://www.slimlogic.co.uk
#1 lore raw
Quoted 5 lines · Liam Girdwood

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?

---

arch/arm/mach-ep93xx/core.c +6 -2
index 67dc876..b5261d4 100644
@@ -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);
 }
sound/soc/ep93xx/ep93xx-i2s.c +1 -2
index b40201f..6e0fa03 100644
@@ -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;
sound/soc/ep93xx/snappercl15.c +9 -13
index 6495534..c34aa1f 100644
@@ -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);
#2 lore raw
Quoted 2 lines · Ryan Mallon

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.

Quoted 2 lines

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.

#3 lore raw
Quoted 9 lines · Mark Brown
Quoted 3 lines · Ryan Mallon

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"

Quoted 11 lines
Quoted 3 lines

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)

#4 lore raw
Quoted 5 lines · Ryan Mallon
Quoted 3 lines · Mark Brown

Do you actually see sound cards appearing? The log message at boot is purely informational, cards can probe at any time.

Quoted 8 lines
Quoted 5 lines

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

---

arch/arm/mach-ep93xx/core.c +6 -2
index 67dc876..b5261d4 100644
@@ -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);
 }
sound/soc/ep93xx/ep93xx-i2s.c +1 -2
index b40201f..6e0fa03 100644
@@ -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;
sound/soc/ep93xx/snappercl15.c +10 -13
index 6495534..aeb822d 100644
@@ -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);
#5 lore raw
Quoted 35 lines · Ryan Mallon
Quoted 5 lines · Ryan Mallon
Quoted 3 lines · Mark Brown

Do you actually see sound cards appearing? The log message at boot is purely informational, cards can probe at any time.

Quoted 8 lines
Quoted 5 lines

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.

Quoted 2 lines

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.

sound/soc/ep93xx/snappercl15.c +1 -0
index aeb822d..72b7913 100644
@@ -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,
Quoted 8 lines

~Ryan

---
Fix build errors and warnings for ep93xx/snapper cl15 asoc multi-component support

---

Thanks. Applied.

Liam

Signature · 3 lines
Freelance Developer, SlimLogic Ltd
ASoC and Voltage Regulator Maintainer.
http://www.slimlogic.co.uk
#6 lore raw
Quoted 53 lines · Liam Girdwood
Quoted 34 lines · Ryan Mallon
Quoted 5 lines · Ryan Mallon
Quoted 3 lines · Mark Brown

Do you actually see sound cards appearing? The log message at boot is purely informational, cards can probe at any time.

Quoted 8 lines
Quoted 5 lines

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.

Quoted 2 lines

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.

sound/soc/ep93xx/snappercl15.c +0 -0
index aeb822d..72b7913 100644

sound/soc/ep93xx/snappercl15.c static struct snd_soc_dai_link snappercl15_dai = { · line 100

Quoted 7 lines
sound/soc/ep93xx/snappercl15.c +1 -0
@@ -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

#7 lore raw
Quoted 39 lines · Ryan Mallon
Quoted 20 lines · Liam Girdwood
Quoted 2 lines · Ryan Mallon

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.

sound/soc/ep93xx/snappercl15.c +0 -0
index aeb822d..72b7913 100644

sound/soc/ep93xx/snappercl15.c static struct snd_soc_dai_link snappercl15_dai = { · line 100

Quoted 7 lines
sound/soc/ep93xx/snappercl15.c +1 -0
@@ -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),
        },
};
Quoted 2 lines

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.

Quoted 3 lines

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

Signature · 3 lines
Freelance Developer, SlimLogic Ltd
ASoC and Voltage Regulator Maintainer.
http://www.slimlogic.co.uk
#8 lore raw
In reply to Liam Girdwood

2010/6/25 Liam Girdwood <[email protected]>:

Quoted 56 lines

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.

Quoted 9 lines

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?

Quoted 18 lines

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

Signature · 14 lines
*linux-arm-kernel mailing list
mail addr:[email protected]
you can subscribe by:
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

* linux-arm-NUC900 mailing list
mail addr:[email protected]
main web: https://groups.google.com/group/NUC900
you can subscribe it by sending me mail:
[email protected]
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
#9 lore raw
Quoted 11 lines · Wan ZongShun

2010/6/25 Liam Girdwood <[email protected]>:

Quoted 4 lines

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

Signature · 3 lines
Freelance Developer, SlimLogic Ltd
ASoC and Voltage Regulator Maintainer.
http://www.slimlogic.co.uk
#10 lore raw
In reply to Liam Girdwood
Quoted 6 lines · On Thu, 24 Jun 2010 20:24:27 +0100 Liam Girdwood <[email protected]> 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.

Signature · 1 line
Jarkko
#11 lore raw
Quoted 3 lines · Jarkko Nikula

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.

#12 lore raw

PATCH 1/1 ASoC: Use bool rather than 1 bit bitfield in multi-component

In reply to Liam Girdwood

This fixes sparse complaints about the bitfield being signed but only 1 bit wide (so not enough space to store the sign bit).

---
 include/sound/soc.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
include/sound/soc.h +1 -1
index b3fe7a8..fb3093b 100644
@@ -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);
Signature · 1 line
1.7.1
author Applied
#13 lore raw

Re: [PATCH] ASoC: Use bool rather than 1 bit bitfield in multi-component

Quoted 4 lines · Mark Brown

This fixes sparse complaints about the bitfield being signed but only 1 bit wide (so not enough space to store the sign bit).

Applied.

Thanks

Liam

Signature · 3 lines
Freelance Developer, SlimLogic Ltd
ASoC and Voltage Regulator Maintainer.
http://www.slimlogic.co.uk
#14 lore raw
In reply to Liam Girdwood
Quoted 4 lines · Liam Girdwood

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.