ep93xx i2s audio
Subsystems (5)
v3 cover ep93xx i2s audio
The following patch series adds support for i2s audio on the ep93xx, with the Snapper CL15 used as an example implementation.
This version fixes a number of things from the previous round:
- Removed unused #defines
- Set symmetric rates for the cpu dai
- Fixed the sdiv/lrdiv calculation loop
- Moved the cpu dai registration
- Removed empty ep93xx_pcm_prepare callback
- Fixed enable/disable when both capture and playback are running
Capture still does not work. The dma is running, but the captured data is all zeros (tested used arecord and loopback). I have a 2.6.20 kernel with ep93xx i2s audio working an capture works there on the same hardware. I have spent sometime looking into this, but can't see the problem. Would appreciate if someone can lend some insight as to what I have done wrong.
Ryan Mallon (3):
ep93xx i2s core support
ep93xx i2s audio driver
Snapper cl15 audio support
arch/arm/mach-ep93xx/clock.c | 69 ++++- arch/arm/mach-ep93xx/core.c | 31 ++ arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h | 10 + arch/arm/mach-ep93xx/include/mach/platform.h | 1 + arch/arm/mach-ep93xx/snappercl15.c | 1 + sound/soc/Kconfig | 1 + sound/soc/Makefile | 1 + sound/soc/ep93xx/Kconfig | 18 + sound/soc/ep93xx/Makefile | 11 + sound/soc/ep93xx/ep93xx-i2s.c | 487 +++++++++++++++++++++++ sound/soc/ep93xx/ep93xx-i2s.h | 18 + sound/soc/ep93xx/ep93xx-pcm.c | 319 +++++++++++++++ sound/soc/ep93xx/ep93xx-pcm.h | 22 + sound/soc/ep93xx/snappercl15.c | 143 +++++++ 14 files changed, 1131 insertions(+), 1 deletions(-) create mode 100644 sound/soc/ep93xx/Kconfig create mode 100644 sound/soc/ep93xx/Makefile create mode 100644 sound/soc/ep93xx/ep93xx-i2s.c create mode 100644 sound/soc/ep93xx/ep93xx-i2s.h create mode 100644 sound/soc/ep93xx/ep93xx-pcm.c create mode 100644 sound/soc/ep93xx/ep93xx-pcm.h create mode 100644 sound/soc/ep93xx/snappercl15.c
RFC PATCH v3 1/3 ep93xx i2s core support
Add ep93xx core support for i2s audio
--- arch/arm/mach-ep93xx/clock.c | 69 ++++++++++++++++++++++- arch/arm/mach-ep93xx/core.c | 31 ++++++++++ arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h | 10 +++ arch/arm/mach-ep93xx/include/mach/platform.h | 1 + 4 files changed, 110 insertions(+), 1 deletions(-)
arch/arm/mach-ep93xx/clock.c +68 -1
@@ -43,7 +43,8 @@ static unsigned long get_uart_rate(struct clk *clk);static int set_keytchclk_rate (struct clk *clk,unsigned long rate);static int set_div_rate (struct clk *clk,unsigned long rate); - +static int set_i2s_sclk_rate (struct clk *clk,unsigned long rate); +static int set_i2s_lrclk_rate (struct clk *clk,unsigned long rate);static struct clk clk_xtali = { .rate =EP93XX_EXT_CLK_RATE ,
@@ -108,6 +109,31 @@ static struct clk clk_video = { .set_rate = set_div_rate, }; +static struct clk clk_i2s_mclk = { + .sw_locked =1 , + .enable_reg =EP93XX_SYSCON_I2SCLKDIV , + .enable_mask = (EP93XX_SYSCON_CLKDIV_ENABLE | +EP93XX_SYSCON_I2SCLKDIV_SPOL | +EP93XX_SYSCON_I2SCLKDIV_ORIDE ), + .set_rate = set_div_rate, +}; + +static struct clk clk_i2s_sclk = { + .sw_locked =1 , + .parent = &clk_i2s_mclk, + .enable_reg =EP93XX_SYSCON_I2SCLKDIV , + .enable_mask =EP93XX_SYSCON_I2SCLKDIV_SENA , + .set_rate = set_i2s_sclk_rate, +}; + +static struct clk clk_i2s_lrclk = { + .sw_locked =1 , + .parent = &clk_i2s_sclk, + .enable_reg =EP93XX_SYSCON_I2SCLKDIV , + .enable_mask =EP93XX_SYSCON_I2SCLKDIV_SENA , + .set_rate = set_i2s_lrclk_rate, +}; +/* DMA Clocks */ static struct clk clk_m2p0 = { .parent = &clk_h,
@@ -186,6 +212,9 @@ static struct clk_lookup clocks[] = {INIT_CK ("ep93xx-ohci" ,NULL , &clk_usb_host),INIT_CK ("ep93xx-keypad" ,NULL , &clk_keypad),INIT_CK ("ep93xx-fb" ,NULL , &clk_video), +INIT_CK ("ep93xx-i2s" ,"mclk" , &clk_i2s_mclk), +INIT_CK ("ep93xx-i2s" ,"sclk" , &clk_i2s_sclk), +INIT_CK ("ep93xx-i2s" ,"lrclk" , &clk_i2s_lrclk),INIT_CK (NULL ,"pwm_clk" , &clk_pwm),INIT_CK (NULL ,"m2p0" , &clk_m2p0), INIT_CK(NULL, "m2p1", &clk_m2p1),
@@ -396,6 +425,44 @@ static int set_div_rate(struct clk *clk, unsigned long rate)return 0 ; } +static int set_i2s_sclk_rate (struct clk *clk,unsigned long rate) +{ +unsigned val =__raw_readl (clk->enable_reg); + +if (rate == clk_i2s_mclk.rate /2 ) +ep93xx_syscon_swlocked_write (val & ~EP93XX_I2SCLKDIV_SDIV , + clk->enable_reg); +else if (rate == clk_i2s_mclk.rate /4 ) +ep93xx_syscon_swlocked_write (val |EP93XX_I2SCLKDIV_SDIV , + clk->enable_reg); +else +return -EINVAL ; + + clk_i2s_sclk.rate = rate; +return 0 ; +} + +static int set_i2s_lrclk_rate (struct clk *clk,unsigned long rate) +{ +unsigned val =__raw_readl (clk->enable_reg) & + ~EP93XX_I2SCLKDIV_LRDIV_MASK ; + +if (rate == clk_i2s_sclk.rate /32 ) +ep93xx_syscon_swlocked_write (val |EP93XX_I2SCLKDIV_LRDIV32 , + clk->enable_reg); +else if (rate == clk_i2s_sclk.rate /64 ) +ep93xx_syscon_swlocked_write (val |EP93XX_I2SCLKDIV_LRDIV64 , + clk->enable_reg); +else if (rate == clk_i2s_sclk.rate /128 ) +ep93xx_syscon_swlocked_write (val |EP93XX_I2SCLKDIV_LRDIV128 , + clk->enable_reg); +else +return -EINVAL ; + + clk_i2s_lrclk.rate = rate; +return 0 ; +} +int clk_set_rate (struct clk *clk,unsigned long rate) {if (clk->set_rate)
arch/arm/mach-ep93xx/core.c +31 -0
@@ -617,6 +617,37 @@ void ep93xx_keypad_release_gpio(struct platform_device *pdev) }EXPORT_SYMBOL (ep93xx_keypad_release_gpio); +/************************************************************************* +* EP93xx I2S audio peripheral handling +*************************************************************************/ +static struct resource ep93xx_i2s_resource[] = { + { + .start =EP93XX_I2S_PHYS_BASE , + .end =EP93XX_I2S_PHYS_BASE +0x100 -1 , + .flags =IORESOURCE_MEM , + }, +}; + +static struct platform_device ep93xx_i2s_device = { + .name ="ep93xx-i2s" , + .id =-1 , + .num_resources =ARRAY_SIZE (ep93xx_i2s_resource), + .resource = ep93xx_i2s_resource, +}; + +void __init ep93xx_register_i2s (unsigned pins) +{ +if (pins !=EP93XX_SYSCON_DEVCFG_I2SONSSP && + pins !=EP93XX_SYSCON_DEVCFG_I2SONAC97 ) { +pr_err ("Invalid I2S pin configuration - not registering\n" ); +return ; + } + +ep93xx_devcfg_clear_bits (EP93XX_SYSCON_DEVCFG_I2SONSSP | +EP93XX_SYSCON_DEVCFG_I2SONAC97 ); +ep93xx_devcfg_set_bits (pins); +platform_device_register (&ep93xx_i2s_device); +}extern void ep93xx_gpio_init (void );
arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +10 -0
@@ -93,6 +93,7 @@/* APB peripherals */ #define EP93XX_TIMER_BASE EP93XX_APB_IOMEM(0x00010000) +#define EP93XX_I2S_PHYS_BASE EP93XX_APB_PHYS(0x00020000)#define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000)#define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000)
@@ -193,6 +194,15 @@#define EP93XX_SYSCON_CLKDIV_ESEL (1<<14)#define EP93XX_SYSCON_CLKDIV_PSEL (1<<13)#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT 8 +#define EP93XX_SYSCON_I2SCLKDIV EP93XX_SYSCON_REG(0x8c) +#define EP93XX_SYSCON_I2SCLKDIV_SENA (1<<31) +#define EP93XX_SYSCON_I2SCLKDIV_ORIDE (1<<29) +#define EP93XX_SYSCON_I2SCLKDIV_SPOL (1<<19) +#define EP93XX_I2SCLKDIV_SDIV (1 << 16) +#define EP93XX_I2SCLKDIV_LRDIV32 (0 << 17) +#define EP93XX_I2SCLKDIV_LRDIV64 (1 << 17) +#define EP93XX_I2SCLKDIV_LRDIV128 (2 << 17) +#define EP93XX_I2SCLKDIV_LRDIV_MASK (3 << 17)#define EP93XX_SYSCON_KEYTCHCLKDIV EP93XX_SYSCON_REG(0x90)#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN (1<<31)#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16)
arch/arm/mach-ep93xx/include/mach/platform.h +1 -0
@@ -43,6 +43,7 @@ void ep93xx_pwm_release_gpio(struct platform_device *pdev);void ep93xx_register_keypad (struct ep93xx_keypad_platform_data *data);int ep93xx_keypad_acquire_gpio (struct platform_device *pdev);void ep93xx_keypad_release_gpio (struct platform_device *pdev); +void ep93xx_register_i2s (unsigned pins);void ep93xx_init_devices (void );extern struct sys_timer ep93xx_timer;
Signature · 1 line
1.5.5.1
RFC PATCH v3 2/3 ep93xx i2s audio driver
Add ep93xx i2s audio driver
--- sound/soc/Kconfig | 1 + sound/soc/Makefile | 1 + sound/soc/ep93xx/Kconfig | 9 + sound/soc/ep93xx/Makefile | 8 + sound/soc/ep93xx/ep93xx-i2s.c | 487 +++++++++++++++++++++++++++++++++++++++++ sound/soc/ep93xx/ep93xx-i2s.h | 18 ++ sound/soc/ep93xx/ep93xx-pcm.c | 319 +++++++++++++++++++++++++++ sound/soc/ep93xx/ep93xx-pcm.h | 22 ++ 8 files changed, 865 insertions(+), 0 deletions(-) create mode 100644 sound/soc/ep93xx/Kconfig create mode 100644 sound/soc/ep93xx/Makefile create mode 100644 sound/soc/ep93xx/ep93xx-i2s.c create mode 100644 sound/soc/ep93xx/ep93xx-i2s.h create mode 100644 sound/soc/ep93xx/ep93xx-pcm.c create mode 100644 sound/soc/ep93xx/ep93xx-pcm.h
sound/soc/Kconfig +1 -0
@@ -28,6 +28,7 @@ source "sound/soc/atmel/Kconfig" source "sound/soc/au1x/Kconfig" source "sound/soc/blackfin/Kconfig" source "sound/soc/davinci/Kconfig" +source "sound/soc/ep93xx/Kconfig" source "sound/soc/fsl/Kconfig" source "sound/soc/imx/Kconfig" source "sound/soc/omap/Kconfig"
sound/soc/Makefile +1 -0
@@ -6,6 +6,7 @@ obj-$(CONFIG_SND_SOC) += atmel/ obj-$(CONFIG_SND_SOC) += au1x/ obj-$(CONFIG_SND_SOC) += blackfin/ obj-$(CONFIG_SND_SOC) += davinci/ +obj-$(CONFIG_SND_SOC) += ep93xx/ obj-$(CONFIG_SND_SOC) += fsl/ obj-$(CONFIG_SND_SOC) += imx/ obj-$(CONFIG_SND_SOC) += omap/
sound/soc/ep93xx/Kconfig new file +9 -0
@@ -0,0 +1,9 @@ +config SND_EP93XX_SOC + tristate "SoC Audio support for the Cirrus Logic EP93xx series" + depends on ARCH_EP93XX && SND_SOC + help + Say Y or M if you want to add support for codecs attached to + the EP93xx I2S interface. + +config SND_EP93XX_SOC_I2S + tristate
sound/soc/ep93xx/Makefile new file +8 -0
@@ -0,0 +1,8 @@ +# EP93xx Platform Support +snd-soc-ep93xx-objs := ep93xx-pcm.o +snd-soc-ep93xx-i2s-objs := ep93xx-i2s.o + +obj-$(CONFIG_SND_EP93XX_SOC) += snd-soc-ep93xx.o +obj-$(CONFIG_SND_EP93XX_SOC_I2S) += snd-soc-ep93xx-i2s.o + +# EP93XX Machine Support
sound/soc/ep93xx/ep93xx-i2s.c new file +487 -0
487 lines not on this page · raw message
sound/soc/ep93xx/ep93xx-i2s.h new file +18 -0
@@ -0,0 +1,18 @@ +/* +* linux/sound/soc/ep93xx-i2s.h +* EP93xx I2S driver +* +* Copyright (C) 2010 Ryan Mallon <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +*/ + +#ifndef _EP93XX_SND_SOC_I2S_H +#define _EP93XX_SND_SOC_I2S_H + +extern struct snd_soc_dai ep93xx_i2s_dai; + +#endif /* _EP93XX_SND_SOC_I2S_H */
sound/soc/ep93xx/ep93xx-pcm.c new file +319 -0
319 lines not on this page · raw message
sound/soc/ep93xx/ep93xx-pcm.h new file +22 -0
@@ -0,0 +1,22 @@ +/* +* sound/soc/ep93xx/ep93xx-pcm.h - EP93xx ALSA PCM interface +* +* Copyright (C) 2006 Lennert Buytenhek <[email protected]> +* Copyright (C) 2006 Applied Data Systems +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef _EP93XX_SND_SOC_PCM_H +#define _EP93XX_SND_SOC_PCM_H + +struct ep93xx_pcm_dma_params { +char *name; +int dma_port; +}; + +extern struct snd_soc_platform ep93xx_soc_platform; + +#endif /* _EP93XX_SND_SOC_PCM_H */
Signature · 1 line
1.5.5.1
RFC PATCH v3 3/3 Snapper cl15 audio support
Added Snapper CL15 i2s audio support
--- arch/arm/mach-ep93xx/snappercl15.c | 1 + sound/soc/ep93xx/Kconfig | 9 ++ sound/soc/ep93xx/Makefile | 3 + sound/soc/ep93xx/snappercl15.c | 143 ++++++++++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 0 deletions(-) create mode 100644 sound/soc/ep93xx/snappercl15.c
arch/arm/mach-ep93xx/snappercl15.c +1 -0
@@ -157,6 +157,7 @@ static void __init snappercl15_init_machine(void)ep93xx_register_i2c (&snappercl15_i2c_gpio_data, snappercl15_i2c_data,ARRAY_SIZE (snappercl15_i2c_data));ep93xx_register_fb (&snappercl15_fb_info); +ep93xx_register_i2s (EP93XX_SYSCON_DEVCFG_I2SONAC97 );platform_device_register (&snappercl15_nand_device); }
sound/soc/ep93xx/Kconfig +9 -0
@@ -7,3 +7,12 @@ config SND_EP93XX_SOC config SND_EP93XX_SOC_I2S tristate + +config SND_EP93XX_SOC_SNAPPERCL15 + tristate "SoC Audio support for Bluewater Systems Snapper CL15 module" + depends on SND_EP93XX_SOC && MACH_SNAPPER_CL15 + select SND_EP93XX_SOC_I2S + select SND_SOC_TLV320AIC23 + help + Say Y or M here if you want to add support for I2S audio on the + Bluewater Systems Snapper CL15 module.
sound/soc/ep93xx/Makefile +3 -0
@@ -6,3 +6,6 @@ obj-$(CONFIG_SND_EP93XX_SOC) += snd-soc-ep93xx.o obj-$(CONFIG_SND_EP93XX_SOC_I2S) += snd-soc-ep93xx-i2s.o # EP93XX Machine Support +snd-soc-snappercl15-objs := snappercl15.o + +obj-$(CONFIG_SND_EP93XX_SOC_SNAPPERCL15) += snd-soc-snappercl15.o
sound/soc/ep93xx/snappercl15.c new file +143 -0
143 lines not on this page · raw message
Signature · 1 line
1.5.5.1
RE: [RFC PATCH v3 1/3] ep93xx i2s core support
In reply to Ryan MallonQuoted 25 lines · Ryan Mallon
Add ep93xx core support for i2s audio
Signed-off-by Ryan Mallon <[email protected]>--- arch/arm/mach-ep93xx/clock.c | 69 ++++++++++++++++++++++- arch/arm/mach-ep93xx/core.c | 31 ++++++++++ arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h | 10 +++ arch/arm/mach-ep93xx/include/mach/platform.h | 1 + 4 files changed, 110 insertions(+), 1 deletions(-)arch/arm/mach-ep93xx/clock.c +2
-1@@ -43,7 +43,8 @@ static unsigned long get_uart_rate(struct clk *clk);static int set_keytchclk_rate (struct clk *clk,unsigned long rate);static int set_div_rate (struct clk *clk,unsigned long rate); - +static int set_i2s_sclk_rate (struct clk *clk,unsigned long rate); +static int set_i2s_lrclk_rate (struct clk *clk,unsigned long rate);static struct clk clk_xtali = { .rate =EP93XX_EXT_CLK_RATE ,
arch/arm/mach-ep93xx/clock.c static struct clk clk_video = { · line 117
Quoted 9 lines
arch/arm/mach-ep93xx/clock.c +6
-0@@ -108,6 +109,31 @@ static struct clk clk_video = { .set_rate = set_div_rate, }; +static struct clk clk_i2s_mclk = { + .sw_locked =1 , + .enable_reg =EP93XX_SYSCON_I2SCLKDIV , + .enable_mask = (EP93XX_SYSCON_CLKDIV_ENABLE | +EP93XX_SYSCON_I2SCLKDIV_SPOL | +EP93XX_SYSCON_I2SCLKDIV_ORIDE ),
Setting the SPOL and ORIDE bits here might cause problems in the future. Granted, your i2s driver is currently the only user so its probably ok for now.
But, you might want to move the setting of those two bits along with the SLAVE and DROP bits to the core registration function. The clock support should only be enabling/disabling and setting the rates for the clocks.
arch/arm/mach-ep93xx/clock.c static struct clk clk_video = { · line 118
Quoted 1 line
arch/arm/mach-ep93xx/clock.c +1
-0+ .set_rate = set_div_rate,
By calling the set_div_rate routine your only updating the master clock rate. Should the new rate be pushed down to the children? Actually the new rates for the children will be established automatically when the master clock rate is changed. But a clk_get_rate for the children will return an incorrect value. Maybe just add a get_rate method for the children?
Quoted 151 lines
arch/arm/mach-ep93xx/clock.c +59
-0+}; + +static struct clk clk_i2s_sclk = { + .sw_locked =1 , + .parent = &clk_i2s_mclk, + .enable_reg =EP93XX_SYSCON_I2SCLKDIV , + .enable_mask =EP93XX_SYSCON_I2SCLKDIV_SENA , + .set_rate = set_i2s_sclk_rate, +}; + +static struct clk clk_i2s_lrclk = { + .sw_locked =1 , + .parent = &clk_i2s_sclk, + .enable_reg =EP93XX_SYSCON_I2SCLKDIV , + .enable_mask =EP93XX_SYSCON_I2SCLKDIV_SENA , + .set_rate = set_i2s_lrclk_rate, +}; +/* DMA Clocks */ static struct clk clk_m2p0 = { .parent = &clk_h,@@ -186,6 +212,9 @@ static struct clk_lookup clocks[] = {INIT_CK ("ep93xx-ohci" ,NULL , &clk_usb_host),INIT_CK ("ep93xx-keypad" ,NULL , &clk_keypad),INIT_CK ("ep93xx-fb" ,NULL , &clk_video), +INIT_CK ("ep93xx-i2s" ,"mclk" , &clk_i2s_mclk), +INIT_CK ("ep93xx-i2s" ,"sclk" , &clk_i2s_sclk), +INIT_CK ("ep93xx-i2s" ,"lrclk" , &clk_i2s_lrclk),INIT_CK (NULL ,"pwm_clk" , &clk_pwm),INIT_CK (NULL ,"m2p0" , &clk_m2p0), INIT_CK(NULL, "m2p1", &clk_m2p1),@@ -396,6 +425,44 @@ static int set_div_rate(struct clk *clk, unsigned long rate)return 0 ; } +static int set_i2s_sclk_rate (struct clk *clk,unsigned long rate) +{ +unsigned val =__raw_readl (clk->enable_reg); + +if (rate == clk_i2s_mclk.rate /2 ) +ep93xx_syscon_swlocked_write (val & ~EP93XX_I2SCLKDIV_SDIV , + clk->enable_reg); +else if (rate == clk_i2s_mclk.rate /4 ) +ep93xx_syscon_swlocked_write (val |EP93XX_I2SCLKDIV_SDIV , + clk->enable_reg); +else +return -EINVAL ; + + clk_i2s_sclk.rate = rate; +return 0 ; +} + +static int set_i2s_lrclk_rate (struct clk *clk,unsigned long rate) +{ +unsigned val =__raw_readl (clk->enable_reg) & + ~EP93XX_I2SCLKDIV_LRDIV_MASK ; + +if (rate == clk_i2s_sclk.rate /32 ) +ep93xx_syscon_swlocked_write (val |EP93XX_I2SCLKDIV_LRDIV32 , + clk->enable_reg); +else if (rate == clk_i2s_sclk.rate /64 ) +ep93xx_syscon_swlocked_write (val |EP93XX_I2SCLKDIV_LRDIV64 , + clk->enable_reg); +else if (rate == clk_i2s_sclk.rate /128 ) +ep93xx_syscon_swlocked_write (val |EP93XX_I2SCLKDIV_LRDIV128 , + clk->enable_reg); +else +return -EINVAL ; + + clk_i2s_lrclk.rate = rate; +return 0 ; +} +int clk_set_rate (struct clk *clk,unsigned long rate) {if (clk->set_rate)arch/arm/mach-ep93xx/core.c +31
-0@@ -617,6 +617,37 @@ void ep93xx_keypad_release_gpio(struct platform_device *pdev) }EXPORT_SYMBOL (ep93xx_keypad_release_gpio); +/************************************************************************* +* EP93xx I2S audio peripheral handling +*************************************************************************/ +static struct resource ep93xx_i2s_resource[] = { + { + .start =EP93XX_I2S_PHYS_BASE , + .end =EP93XX_I2S_PHYS_BASE +0x100 -1 , + .flags =IORESOURCE_MEM , + }, +}; + +static struct platform_device ep93xx_i2s_device = { + .name ="ep93xx-i2s" , + .id =-1 , + .num_resources =ARRAY_SIZE (ep93xx_i2s_resource), + .resource = ep93xx_i2s_resource, +}; + +void __init ep93xx_register_i2s (unsigned pins) +{ +if (pins !=EP93XX_SYSCON_DEVCFG_I2SONSSP && + pins !=EP93XX_SYSCON_DEVCFG_I2SONAC97 ) { +pr_err ("Invalid I2S pin configuration - not registering\n" ); +return ; + } + +ep93xx_devcfg_clear_bits (EP93XX_SYSCON_DEVCFG_I2SONSSP | +EP93XX_SYSCON_DEVCFG_I2SONAC97 ); +ep93xx_devcfg_set_bits (pins); +platform_device_register (&ep93xx_i2s_device); +}extern void ep93xx_gpio_init (void );arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +10
-0@@ -93,6 +93,7 @@/* APB peripherals */ #define EP93XX_TIMER_BASE EP93XX_APB_IOMEM(0x00010000) +#define EP93XX_I2S_PHYS_BASE EP93XX_APB_PHYS(0x00020000)#define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000)#define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000)@@ -193,6 +194,15 @@#define EP93XX_SYSCON_CLKDIV_ESEL (1<<14)#define EP93XX_SYSCON_CLKDIV_PSEL (1<<13)#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT 8 +#define EP93XX_SYSCON_I2SCLKDIV EP93XX_SYSCON_REG(0x8c) +#define EP93XX_SYSCON_I2SCLKDIV_SENA (1<<31) +#define EP93XX_SYSCON_I2SCLKDIV_ORIDE (1<<29) +#define EP93XX_SYSCON_I2SCLKDIV_SPOL (1<<19) +#define EP93XX_I2SCLKDIV_SDIV (1 << 16) +#define EP93XX_I2SCLKDIV_LRDIV32 (0 << 17) +#define EP93XX_I2SCLKDIV_LRDIV64 (1 << 17) +#define EP93XX_I2SCLKDIV_LRDIV128 (2 << 17) +#define EP93XX_I2SCLKDIV_LRDIV_MASK (3 << 17)#define EP93XX_SYSCON_KEYTCHCLKDIV EP93XX_SYSCON_REG(0x90)#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN (1<<31)#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16)arch/arm/mach-ep93xx/include/mach/platform.h +0
-0
arch/arm/mach-ep93xx/include/mach/platform.h void ep93xx_pwm_release_gpio(struct platform_device *pdev); · line 49
Quoted 7 lines
arch/arm/mach-ep93xx/include/mach/platform.h +1
-0@@ -43,6 +43,7 @@ void ep93xx_pwm_release_gpio(struct platform_device *pdev);void ep93xx_register_keypad (struct ep93xx_keypad_platform_data *data);int ep93xx_keypad_acquire_gpio (struct platform_device *pdev);void ep93xx_keypad_release_gpio (struct platform_device *pdev); +void ep93xx_register_i2s (unsigned pins);void ep93xx_init_devices (void );extern struct sys_timer ep93xx_timer;
Other than the comments above I'm ok with this.
Re: [RFC PATCH v3 1/3] ep93xx i2s core support
Quoted 40 lines · H Hartley Sweeten
Quoted 25 lines · Ryan Mallon
Add ep93xx core support for i2s audio
Signed-off-by Ryan Mallon <[email protected]>--- arch/arm/mach-ep93xx/clock.c | 69 ++++++++++++++++++++++- arch/arm/mach-ep93xx/core.c | 31 ++++++++++ arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h | 10 +++ arch/arm/mach-ep93xx/include/mach/platform.h | 1 + 4 files changed, 110 insertions(+), 1 deletions(-)arch/arm/mach-ep93xx/clock.c +2
-1@@ -43,7 +43,8 @@ static unsigned long get_uart_rate(struct clk *clk);static int set_keytchclk_rate (struct clk *clk,unsigned long rate);static int set_div_rate (struct clk *clk,unsigned long rate); - +static int set_i2s_sclk_rate (struct clk *clk,unsigned long rate); +static int set_i2s_lrclk_rate (struct clk *clk,unsigned long rate);static struct clk clk_xtali = { .rate =EP93XX_EXT_CLK_RATE ,arch/arm/mach-ep93xx/clock.c static struct clk clk_video = { · line 117
Quoted 9 lines
arch/arm/mach-ep93xx/clock.c +6
-0@@ -108,6 +109,31 @@ static struct clk clk_video = { .set_rate = set_div_rate, }; +static struct clk clk_i2s_mclk = { + .sw_locked =1 , + .enable_reg =EP93XX_SYSCON_I2SCLKDIV , + .enable_mask = (EP93XX_SYSCON_CLKDIV_ENABLE | +EP93XX_SYSCON_I2SCLKDIV_SPOL | +EP93XX_SYSCON_I2SCLKDIV_ORIDE ),Setting the SPOL and ORIDE bits here might cause problems in the future. Granted, your i2s driver is currently the only user so its probably ok for now.
Quoted 3 lines
But, you might want to move the setting of those two bits along with the SLAVE and DROP bits to the core registration function. The clock support should only be enabling/disabling and setting the rates for the clocks.
Okay, sounds sensible. Possibly I should add acquire/release functions in addition to the register, something like:
void __init ep93xx_register_i2s(void)
{
platform_device_register(&ep93xx_i2s_device);
}int ep93xx_i2s_acquire(unsigned pins, int override, int sclk_falling)
{
unsigned set_bits = pins,
clear_bits = EP93XX_SYSCON_DEVCFG_I2SONSSP |
EP93XX_SYSCON_DEVCFG_I2SONAC97;
if (pins != EP93XX_SYSCON_DEVCFG_I2SONSSP &&
pins != EP93XX_SYSCON_DEVCFG_I2SONAC97)
return -EINVAL;
if (override)
set_bits |= EP93XX_SYSCON_I2SCLKDIV_ORIDE;
else
clear_bits |= EP93XX_SYSCON_I2SCLKDIV_ORIDE;
if (sclk_falling)
set_bits |= EP93XX_SYSCON_I2SCLKDIV_SPOL;
else
clear_bits |= EP93XX_SYSCON_I2SCLKDIV_SPOL;
ep93xx_devcfg_clear_bits(clear_bits);
ep93xx_devcfg_set_bits(set_bits);
return 0;
}Quoted 8 lines
arch/arm/mach-ep93xx/clock.c static struct clk clk_video = { · line 118
Quoted 1 line
arch/arm/mach-ep93xx/clock.c +1
-0+ .set_rate = set_div_rate,By calling the
set_div_rateroutine your only updating the master clock rate. Should the new rate be pushed down to the children? Actually the new rates for the children will be established automatically when the master clock rate is changed. But aclk_get_ratefor the children will return an incorrect value. Maybe just add aget_ratemethod for the children?
The code basically assumes that the clocks will always be set in the
order: mclk, sclk, lrclk. Since the i2s driver is the only user, this should be a valid assumption. Possibly a comment should be put in to state that this assumption is made.
~Ryan
Signature · 7 lines
Bluewater Systems Ltd - ARM Technology Solution Centre Ryan Mallon 5 Amuri Park, 404 Barbadoes St ryan at bluewatersys.com PO Box 13 889, Christchurch 8013 http://www.bluewatersys.com New Zealand Phone: +64 3 3779127 Freecall: Australia 1800 148 751 Fax: +64 3 3779135 USA 1800 261 2934
Quoted 18 lines · Ryan Mallon
The following patch series adds support for i2s audio on the ep93xx, with the Snapper CL15 used as an example implementation.
This version fixes a number of things from the previous round:
- Removed unused #defines
- Set symmetric rates for the cpu dai
- Fixed the sdiv/lrdiv calculation loop
- Moved the cpu dai registration
- Removed emptyep93xx_pcm_preparecallback
- Fixed enable/disable when both capture and playback are runningCapture still does not work. The dma is running, but the captured data is all zeros (tested used arecord and loopback). I have a 2.6.20 kernel with ep93xx i2s audio working an capture works there on the same hardware. I have spent sometime looking into this, but can't see the problem. Would appreciate if someone can lend some insight as to what I have done wrong.
Quoted 4 lines
Ryan Mallon (3):
ep93xx i2s core support
ep93xx i2s audio driver
Snapper cl15 audio support
All
Signature · 3 lines
Freelance Developer, SlimLogic Ltd ASoC and Voltage Regulator Maintainer. http://www.slimlogic.co.uk
Quoted 19 lines · Liam Girdwood
Quoted 18 lines · Ryan Mallon
The following patch series adds support for i2s audio on the ep93xx, with the Snapper CL15 used as an example implementation.
This version fixes a number of things from the previous round:
- Removed unused #defines
- Set symmetric rates for the cpu dai
- Fixed the sdiv/lrdiv calculation loop
- Moved the cpu dai registration
- Removed emptyep93xx_pcm_preparecallback
- Fixed enable/disable when both capture and playback are runningCapture still does not work. The dma is running, but the captured data is all zeros (tested used arecord and loopback). I have a 2.6.20 kernel with ep93xx i2s audio working an capture works there on the same hardware. I have spent sometime looking into this, but can't see the problem. Would appreciate if someone can lend some insight as to what I have done wrong.
Quoted 8 lines
Quoted 4 lines
Ryan Mallon (3):
ep93xx i2s core support
ep93xx i2s audio driver
Snapper cl15 audio supportAll
Acked-by Liam Girdwood <[email protected]>
Russell, Mark has picked up patch 2/3 via the alsa tree. Should I submit 1/3 and 3/3 via the arm patch system with Liam's ack?
Thanks,
~Ryan
Signature · 7 lines
Bluewater Systems Ltd - ARM Technology Solution Centre Ryan Mallon 5 Amuri Park, 404 Barbadoes St ryan at bluewatersys.com PO Box 13 889, Christchurch 8013 http://www.bluewatersys.com New Zealand Phone: +64 3 3779127 Freecall: Australia 1800 148 751 Fax: +64 3 3779135 USA 1800 261 2934
Quoted 2 lines · Ryan Mallon
Russell, Mark has picked up patch 2/3 via the alsa tree. Should I submit 1/3 and 3/3 via the arm patch system with Liam's ack?
At least 3/3 needs to go via the ASoC tree since it depends on 2/3. It may make sense for all of them to go that way, or perhaps 1/3 could go separately via the ARM tree (in which case I'd ack it too).
Quoted 6 lines · Mark Brown
Quoted 2 lines · Ryan Mallon
Russell, Mark has picked up patch 2/3 via the alsa tree. Should I submit 1/3 and 3/3 via the arm patch system with Liam's ack?
At least 3/3 needs to go via the ASoC tree since it depends on 2/3. It may make sense for all of them to go that way, or perhaps 1/3 could go separately via the ARM tree (in which case I'd ack it too).
I really don't mind either way, unless Russell has objections to the core patches going via the alsa tree.
I want to make a couple of changes suggested by Hartley to patches 1/3 and 3/3 which will cleanup the registration interface a little. I will repost the patches hopefully later today.
~Ryan
Signature · 7 lines
Bluewater Systems Ltd - ARM Technology Solution Centre Ryan Mallon 5 Amuri Park, 404 Barbadoes St ryan at bluewatersys.com PO Box 13 889, Christchurch 8013 http://www.bluewatersys.com New Zealand Phone: +64 3 3779127 Freecall: Australia 1800 148 751 Fax: +64 3 3779135 USA 1800 261 2934
Quoted 2 lines · Ryan Mallon
The following patch series adds support for i2s audio on the ep93xx, with the Snapper CL15 used as an example implementation.
Please do remember to CC maintainers on patches. I've had to remind you about this before, it's really not helpful to drop the people you're expecting to review the patches - it'll tend to delay things or lead to the patches getting missed. From a code point of view this looks fine but we'll need an arch maintainer to sign off on that bit of the code. I've applied 2/3 since that has no arch/arm elements.
Quoted 10 lines · Mark Brown
Quoted 2 lines · Ryan Mallon
The following patch series adds support for i2s audio on the ep93xx, with the Snapper CL15 used as an example implementation.
Please do remember to CC maintainers on patches. I've had to remind you about this before, it's really not helpful to drop the people you're expecting to review the patches - it'll tend to delay things or lead to the patches getting missed. From a code point of view this looks fine but we'll need an arch maintainer to sign off on that bit of the code. I've applied 2/3 since that has no
arch/armelements.
Sorry, again. I copied the CC list from the last series I sent. I must have missed you accidentally.
Thanks for picking this up.
~Ryan
Signature · 7 lines
Bluewater Systems Ltd - ARM Technology Solution Centre Ryan Mallon 5 Amuri Park, 404 Barbadoes St ryan at bluewatersys.com PO Box 13 889, Christchurch 8013 http://www.bluewatersys.com New Zealand Phone: +64 3 3779127 Freecall: Australia 1800 148 751 Fax: +64 3 3779135 USA 1800 261 2934