From 49106c729053b3c7c963a988aeaf00aa2424a7aa Mon Sep 17 00:00:00 2001 From: "apatard@mandriva.com" Date: Mon, 31 May 2010 13:49:12 +0200 Subject: orion/kirkwood: add audio functions. This patch add audio related definitions and functions Signed-off-by: Arnaud Patard Acked-by: Nicolas Pitre Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- arch/arm/mach-kirkwood/common.c | 38 ++++++++++++++++++++++++++ arch/arm/mach-kirkwood/common.h | 2 ++ arch/arm/mach-kirkwood/include/mach/kirkwood.h | 3 ++ arch/arm/plat-orion/include/plat/audio.h | 11 ++++++++ 4 files changed, 54 insertions(+) create mode 100644 arch/arm/plat-orion/include/plat/audio.h (limited to 'arch') diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 6072eaa5e66a..e1f3efedbcf1 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -864,6 +865,42 @@ struct sys_timer kirkwood_timer = { .init = kirkwood_timer_init, }; +/***************************************************************************** + * Audio + ****************************************************************************/ +static struct resource kirkwood_i2s_resources[] = { + [0] = { + .start = AUDIO_PHYS_BASE, + .end = AUDIO_PHYS_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_KIRKWOOD_I2S, + .end = IRQ_KIRKWOOD_I2S, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct kirkwood_asoc_platform_data kirkwood_i2s_data = { + .dram = &kirkwood_mbus_dram_info, + .burst = 128, +}; + +static struct platform_device kirkwood_i2s_device = { + .name = "kirkwood-i2s", + .id = -1, + .num_resources = ARRAY_SIZE(kirkwood_i2s_resources), + .resource = kirkwood_i2s_resources, + .dev = { + .platform_data = &kirkwood_i2s_data, + }, +}; + +void __init kirkwood_audio_init(void) +{ + kirkwood_clk_ctrl |= CGC_AUDIO; + platform_device_register(&kirkwood_i2s_device); +} /***************************************************************************** * General @@ -923,6 +960,7 @@ void __init kirkwood_init(void) kirkwood_spi_plat_data.tclk = kirkwood_tclk; kirkwood_uart0_data[0].uartclk = kirkwood_tclk; kirkwood_uart1_data[0].uartclk = kirkwood_tclk; + kirkwood_i2s_data.tclk = kirkwood_tclk; /* * Disable propagation of mbus errors to the CPU local bus, diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index 05e8a8a5692e..c9ab1cb3b39f 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h @@ -17,6 +17,7 @@ struct mv_sata_platform_data; struct mvsdio_platform_data; struct mtd_partition; struct mtd_info; +struct kirkwood_asoc_platform_data; /* * Basic Kirkwood init functions used early by machine-setup. @@ -43,6 +44,7 @@ void kirkwood_uart0_init(void); void kirkwood_uart1_init(void); void kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, int delay); void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, int (*dev_ready)(struct mtd_info *)); +void kirkwood_audio_init(void); extern int kirkwood_tclk; extern struct sys_timer kirkwood_timer; diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h index a15cf0ee22bd..838151d0744b 100644 --- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h +++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h @@ -96,6 +96,9 @@ #define SDIO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x90000) +#define AUDIO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0xA0000) +#define AUDIO_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0xA0000) + /* * Supported devices and revisions. */ diff --git a/arch/arm/plat-orion/include/plat/audio.h b/arch/arm/plat-orion/include/plat/audio.h new file mode 100644 index 000000000000..9cf1f781329b --- /dev/null +++ b/arch/arm/plat-orion/include/plat/audio.h @@ -0,0 +1,11 @@ +#ifndef __PLAT_AUDIO_H +#define __PLAT_AUDIO_H + +#include + +struct kirkwood_asoc_platform_data { + u32 tclk; + struct mbus_dram_target_info *dram; + int burst; +}; +#endif -- cgit v1.2.3 From 492e2bf141478e2c1ce3abfda381f73d1f2108f5 Mon Sep 17 00:00:00 2001 From: "apatard@mandriva.com" Date: Mon, 31 May 2010 13:49:13 +0200 Subject: openrd-client: initialise audio This patch is reponsible for enabling audio on the openrd client board Signed-off-by: Arnaud Patard Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- arch/arm/mach-kirkwood/openrd-setup.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c index ad3f1ec33796..e36067ad3aca 100644 --- a/arch/arm/mach-kirkwood/openrd-setup.c +++ b/arch/arm/mach-kirkwood/openrd-setup.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -60,6 +61,12 @@ static unsigned int openrd_mpp_config[] __initdata = { 0 }; +static struct i2c_board_info i2c_board_info[] __initdata = { + { + I2C_BOARD_INFO("cs42l51", 0x4a), + }, +}; + static void __init openrd_init(void) { /* @@ -80,6 +87,12 @@ static void __init openrd_init(void) kirkwood_sdio_init(&openrd_mvsdio_data); kirkwood_i2c_init(); + + if (machine_is_openrd_client()) { + i2c_register_board_info(0, i2c_board_info, + ARRAY_SIZE(i2c_board_info)); + kirkwood_audio_init(); + } } static int __init openrd_pci_init(void) -- cgit v1.2.3 From 0acce82b3dd792c85079ca1f4f7ffd8c82427e0a Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 3 Jun 2010 07:39:32 +0300 Subject: OMAP: McBSP: Function to query the FIFO size Users of McBSP can use the omap_mcbsp_get_fifo_size function to query the size of the McBSP FIFO. The function will return the FIFO size in words (the HW maximum). Signed-off-by: Peter Ujfalusi Acked-by: Jarkko Nikula Acked-by: Mark Brown Acked-by: Tony Lindgren Signed-off-by: Liam Girdwood --- arch/arm/plat-omap/include/plat/mcbsp.h | 2 ++ arch/arm/plat-omap/mcbsp.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) (limited to 'arch') diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h index 975744f10a58..b4ff6a11a8f2 100644 --- a/arch/arm/plat-omap/include/plat/mcbsp.h +++ b/arch/arm/plat-omap/include/plat/mcbsp.h @@ -473,6 +473,7 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); u16 omap_mcbsp_get_max_tx_threshold(unsigned int id); u16 omap_mcbsp_get_max_rx_threshold(unsigned int id); +u16 omap_mcbsp_get_fifo_size(unsigned int id); u16 omap_mcbsp_get_tx_delay(unsigned int id); u16 omap_mcbsp_get_rx_delay(unsigned int id); int omap_mcbsp_get_dma_op_mode(unsigned int id); @@ -483,6 +484,7 @@ static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) { } static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; } static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; } +static inline u16 omap_mcbsp_get_fifo_size(unsigned int id) { return 0; } static inline u16 omap_mcbsp_get_tx_delay(unsigned int id) { return 0; } static inline u16 omap_mcbsp_get_rx_delay(unsigned int id) { return 0; } static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; } diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 7e669c9744d8..8bab0b28b7a3 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -560,6 +560,20 @@ u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) } EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold); +u16 omap_mcbsp_get_fifo_size(unsigned int id) +{ + struct omap_mcbsp *mcbsp; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + mcbsp = id_to_mcbsp_ptr(id); + + return mcbsp->pdata->buffer_size; +} +EXPORT_SYMBOL(omap_mcbsp_get_fifo_size); + #define MCBSP2_FIFO_SIZE 0x500 /* 1024 + 256 locations */ #define MCBSP1345_FIFO_SIZE 0x80 /* 128 locations */ /* -- cgit v1.2.3 From 451fd82dc148bd5ac9ed5b19b6915a1afe32b9cb Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 3 Jun 2010 07:39:33 +0300 Subject: OMAP3: McBSP: Change the way how the FIFO is handled Use the actual FIFO size in words as buffer_size on OMAP3. Change the threshold configuration to use 1 based numbering, when specifying the allowed threshold maximum or the McBSP threshold value. Set the default maximum threshold to (buffer_size - 0x10) intialy. >From users of McBSP, now it is expected to use this method. Asking for threshold 1 means that the value written to threshold registers are going to be 0, which means 1 word threshold. Signed-off-by: Peter Ujfalusi Acked-by: Jarkko Nikula Acked-by: Mark Brown Acked-by: Tony Lindgren Signed-off-by: Liam Girdwood --- arch/arm/mach-omap2/mcbsp.c | 10 +++++----- arch/arm/plat-omap/mcbsp.c | 30 ++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index c29337074ad3..8fb5e5345557 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -133,7 +133,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP1_IRQ_RX, .tx_irq = INT_24XX_MCBSP1_IRQ_TX, .ops = &omap2_mcbsp_ops, - .buffer_size = 0x6F, + .buffer_size = 0x80, /* The FIFO has 128 locations */ }, { .phys_base = OMAP34XX_MCBSP2_BASE, @@ -143,7 +143,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP2_IRQ_RX, .tx_irq = INT_24XX_MCBSP2_IRQ_TX, .ops = &omap2_mcbsp_ops, - .buffer_size = 0x3FF, + .buffer_size = 0x500, /* The FIFO has 1024 + 256 locations */ }, { .phys_base = OMAP34XX_MCBSP3_BASE, @@ -153,7 +153,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP3_IRQ_RX, .tx_irq = INT_24XX_MCBSP3_IRQ_TX, .ops = &omap2_mcbsp_ops, - .buffer_size = 0x6F, + .buffer_size = 0x80, /* The FIFO has 128 locations */ }, { .phys_base = OMAP34XX_MCBSP4_BASE, @@ -162,7 +162,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP4_IRQ_RX, .tx_irq = INT_24XX_MCBSP4_IRQ_TX, .ops = &omap2_mcbsp_ops, - .buffer_size = 0x6F, + .buffer_size = 0x80, /* The FIFO has 128 locations */ }, { .phys_base = OMAP34XX_MCBSP5_BASE, @@ -171,7 +171,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { .rx_irq = INT_24XX_MCBSP5_IRQ_RX, .tx_irq = INT_24XX_MCBSP5_IRQ_TX, .ops = &omap2_mcbsp_ops, - .buffer_size = 0x6F, + .buffer_size = 0x80, /* The FIFO has 128 locations */ }, }; #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 8bab0b28b7a3..4ef46047b787 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -481,9 +481,9 @@ int omap_st_is_enabled(unsigned int id) EXPORT_SYMBOL(omap_st_is_enabled); /* - * omap_mcbsp_set_tx_threshold configures how to deal - * with transmit threshold. the threshold value and handler can be - * configure in here. + * omap_mcbsp_set_rx_threshold configures the transmit threshold in words. + * The threshold parameter is 1 based, and it is converted (threshold - 1) + * for the THRSH2 register. */ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) { @@ -498,14 +498,15 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) } mcbsp = id_to_mcbsp_ptr(id); - MCBSP_WRITE(mcbsp, THRSH2, threshold); + if (threshold && threshold <= mcbsp->max_tx_thres) + MCBSP_WRITE(mcbsp, THRSH2, threshold - 1); } EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold); /* - * omap_mcbsp_set_rx_threshold configures how to deal - * with receive threshold. the threshold value and handler can be - * configure in here. + * omap_mcbsp_set_rx_threshold configures the receive threshold in words. + * The threshold parameter is 1 based, and it is converted (threshold - 1) + * for the THRSH1 register. */ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) { @@ -520,7 +521,8 @@ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) } mcbsp = id_to_mcbsp_ptr(id); - MCBSP_WRITE(mcbsp, THRSH1, threshold); + if (threshold && threshold <= mcbsp->max_rx_thres) + MCBSP_WRITE(mcbsp, THRSH1, threshold - 1); } EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold); @@ -1697,8 +1699,16 @@ static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) { mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT; if (cpu_is_omap34xx()) { - mcbsp->max_tx_thres = max_thres(mcbsp); - mcbsp->max_rx_thres = max_thres(mcbsp); + /* + * Initially configure the maximum thresholds to a safe value. + * The McBSP FIFO usage with these values should not go under + * 16 locations. + * If the whole FIFO without safety buffer is used, than there + * is a possibility that the DMA will be not able to push the + * new data on time, causing channel shifts in runtime. + */ + mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10; + mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10; /* * REVISIT: Set dmap_op_mode to THRESHOLD as default * for mcbsp2 instances. -- cgit v1.2.3 From f10b8ad15f9531b6d58edabccf05e9eb738c4409 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 3 Jun 2010 07:39:34 +0300 Subject: OMAP3: McBSP: Use the port's buffer_size when calculating tx delay Sicne the platform data's buffer_size now holds the full size of the FIFO, there is no longer need to handle the ports differently. Signed-off-by: Peter Ujfalusi Acked-by: Jarkko Nikula Acked-by: Mark Brown Acked-by: Tony Lindgren Signed-off-by: Liam Girdwood --- arch/arm/plat-omap/mcbsp.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 4ef46047b787..e31496e35b0f 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -576,8 +576,6 @@ u16 omap_mcbsp_get_fifo_size(unsigned int id) } EXPORT_SYMBOL(omap_mcbsp_get_fifo_size); -#define MCBSP2_FIFO_SIZE 0x500 /* 1024 + 256 locations */ -#define MCBSP1345_FIFO_SIZE 0x80 /* 128 locations */ /* * omap_mcbsp_get_tx_delay returns the number of used slots in the McBSP FIFO */ @@ -596,10 +594,7 @@ u16 omap_mcbsp_get_tx_delay(unsigned int id) buffstat = MCBSP_READ(mcbsp, XBUFFSTAT); /* Number of slots are different in McBSP ports */ - if (mcbsp->id == 2) - return MCBSP2_FIFO_SIZE - buffstat; - else - return MCBSP1345_FIFO_SIZE - buffstat; + return mcbsp->pdata->buffer_size - buffstat; } EXPORT_SYMBOL(omap_mcbsp_get_tx_delay); -- cgit v1.2.3 From 0e79612012e1da66133e3c8499bc7c020f006c89 Mon Sep 17 00:00:00 2001 From: Eric Bénard Date: Thu, 27 May 2010 10:58:54 +0200 Subject: ASoC: imx-ssi.c: add new choices to platform configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * introduce 3 new flags to allow a more detailed configuration of the SSI link : IMX_SSI_NET : enable Network Mode IMX_SSI_SYN : enable Synchronous Mode IMX_SSI_USE_I2S_SLAVE : enable I2S Slave Mode * new platform can use these settings without breaking actual platforms. Signed-off-by: Eric Bénard Acked-by: Sascha Hauer Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- arch/arm/plat-mxc/include/mach/ssi.h | 3 +++ sound/soc/imx/imx-ssi.c | 11 +++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-mxc/include/mach/ssi.h b/arch/arm/plat-mxc/include/mach/ssi.h index c34ded523f10..63f3c2804239 100644 --- a/arch/arm/plat-mxc/include/mach/ssi.h +++ b/arch/arm/plat-mxc/include/mach/ssi.h @@ -10,6 +10,9 @@ struct imx_ssi_platform_data { unsigned int flags; #define IMX_SSI_DMA (1 << 0) #define IMX_SSI_USE_AC97 (1 << 1) +#define IMX_SSI_NET (1 << 2) +#define IMX_SSI_SYN (1 << 3) +#define IMX_SSI_USE_I2S_SLAVE (1 << 4) void (*ac97_reset) (struct snd_ac97 *ac97); void (*ac97_warm_reset)(struct snd_ac97 *ac97); }; diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 80b4fee2442b..50f51624c535 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c @@ -83,8 +83,6 @@ static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, /* * SSI DAI format configuration. * Should only be called when port is inactive (i.e. SSIEN = 0). - * Note: We don't use the I2S modes but instead manually configure the - * SSI for I2S because the I2S mode is only a register preset. */ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { @@ -99,6 +97,10 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) /* data on rising edge of bclk, frame low 1clk before data */ strcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0; scr |= SSI_SCR_NET; + if (ssi->flags & IMX_SSI_USE_I2S_SLAVE) { + scr &= ~SSI_I2S_MODE_MASK; + scr |= SSI_SCR_I2S_MODE_SLAVE; + } break; case SND_SOC_DAIFMT_LEFT_J: /* data on rising edge of bclk, frame high with data */ @@ -143,6 +145,11 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) strcr |= SSI_STCR_TFEN0; + if (ssi->flags & IMX_SSI_NET) + scr |= SSI_SCR_NET; + if (ssi->flags & IMX_SSI_SYN) + scr |= SSI_SCR_SYN; + writel(strcr, ssi->base + SSI_STCR); writel(strcr, ssi->base + SSI_SRCR); writel(scr, ssi->base + SSI_SCR); -- cgit v1.2.3 From ed67ea82c0d9a163458dc6a69a7a3123db1a8b3b Mon Sep 17 00:00:00 2001 From: Ryan Mallon Date: Tue, 8 Jun 2010 22:01:10 +1200 Subject: EP93xx: Add i2s core support Add core support for EP93xx i2s audio Signed-off-by: Ryan Mallon Acked-by: H Hartley Sweeten Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- arch/arm/mach-ep93xx/clock.c | 67 ++++++++++++++++++++++++- arch/arm/mach-ep93xx/core.c | 67 +++++++++++++++++++++++++ arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h | 10 ++++ arch/arm/mach-ep93xx/include/mach/platform.h | 3 ++ 4 files changed, 146 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index 5f80092b6ace..e782af18ffb7 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c @@ -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,29 @@ 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, + .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 +210,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 +423,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) diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 90fb591cbffa..005af0fba334 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -617,6 +617,73 @@ 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(void) +{ + platform_device_register(&ep93xx_i2s_device); +} + +#define EP93XX_SYSCON_DEVCFG_I2S_MASK (EP93XX_SYSCON_DEVCFG_I2SONSSP | \ + EP93XX_SYSCON_DEVCFG_I2SONAC97) + +#define EP93XX_I2SCLKDIV_MASK (EP93XX_SYSCON_I2SCLKDIV_ORIDE | \ + EP93XX_SYSCON_I2SCLKDIV_SPOL) + +int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config) +{ + unsigned val; + + /* Sanity check */ + if (i2s_pins & ~EP93XX_SYSCON_DEVCFG_I2S_MASK) + return -EINVAL; + if (i2s_config & ~EP93XX_I2SCLKDIV_MASK) + return -EINVAL; + + /* Must have only one of I2SONSSP/I2SONAC97 set */ + if ((i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONSSP) == + (i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONAC97)) + return -EINVAL; + + ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2S_MASK); + ep93xx_devcfg_set_bits(i2s_pins); + + /* + * This is potentially racy with the clock api for i2s_mclk, sclk and + * lrclk. Since the i2s driver is the only user of those clocks we + * rely on it to prevent parallel use of this function and the + * clock api for the i2s clocks. + */ + val = __raw_readl(EP93XX_SYSCON_I2SCLKDIV); + val &= ~EP93XX_I2SCLKDIV_MASK; + val |= i2s_config; + ep93xx_syscon_swlocked_write(val, EP93XX_SYSCON_I2SCLKDIV); + + return 0; +} +EXPORT_SYMBOL(ep93xx_i2s_acquire); + +void ep93xx_i2s_release(void) +{ + ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2S_MASK); +} +EXPORT_SYMBOL(ep93xx_i2s_release); extern void ep93xx_gpio_init(void); diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h index 93e2ecc79ceb..3fbb095be6e9 100644 --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h @@ -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) diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index c6dc14dbca18..0f2822d7ec8b 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h @@ -43,6 +43,9 @@ 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(void); +int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config); +void ep93xx_i2s_release(void); void ep93xx_init_devices(void); extern struct sys_timer ep93xx_timer; -- cgit v1.2.3 From 315f7da6314e01322cae8bce9a90850060c041ea Mon Sep 17 00:00:00 2001 From: Ryan Mallon Date: Tue, 8 Jun 2010 22:01:12 +1200 Subject: ASoC: EP93xx: Add Snapper CL15 i2s audio support Add support for i2s audio on Bluewater Systems Snapper CL15 module Signed-off-by: Ryan Mallon Acked-by: H Hartley Sweeten Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- arch/arm/mach-ep93xx/snappercl15.c | 1 + sound/soc/ep93xx/Kconfig | 9 +++ sound/soc/ep93xx/Makefile | 3 + sound/soc/ep93xx/snappercl15.c | 150 +++++++++++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+) create mode 100644 sound/soc/ep93xx/snappercl15.c (limited to 'arch') diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c index 38deaee40397..a12c89301297 100644 --- a/arch/arm/mach-ep93xx/snappercl15.c +++ b/arch/arm/mach-ep93xx/snappercl15.c @@ -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(); platform_device_register(&snappercl15_nand_device); } diff --git a/sound/soc/ep93xx/Kconfig b/sound/soc/ep93xx/Kconfig index ba66ac8e1419..f617f560f46b 100644 --- a/sound/soc/ep93xx/Kconfig +++ b/sound/soc/ep93xx/Kconfig @@ -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. diff --git a/sound/soc/ep93xx/Makefile b/sound/soc/ep93xx/Makefile index 0239da36cea3..272e60f57b9a 100644 --- a/sound/soc/ep93xx/Makefile +++ b/sound/soc/ep93xx/Makefile @@ -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 diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c new file mode 100644 index 000000000000..64955340ff75 --- /dev/null +++ b/sound/soc/ep93xx/snappercl15.c @@ -0,0 +1,150 @@ +/* + * snappercl15.c -- SoC audio for Bluewater Systems Snapper CL15 module + * + * Copyright (C) 2008 Bluewater Systems Ltd + * Author: Ryan Mallon + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "../codecs/tlv320aic23.h" +#include "ep93xx-pcm.h" +#include "ep93xx-i2s.h" + +#define CODEC_CLOCK 5644800 + +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; + int err; + + err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_IF | + SND_SOC_DAIFMT_CBS_CFS); + + err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_IF | + SND_SOC_DAIFMT_CBS_CFS); + if (err) + return err; + + err = snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, + SND_SOC_CLOCK_IN); + if (err) + return err; + + err = snd_soc_dai_set_sysclk(cpu_dai, 0, CODEC_CLOCK, + SND_SOC_CLOCK_OUT); + if (err) + return err; + + return 0; +} + +static struct snd_soc_ops snappercl15_ops = { + .hw_params = snappercl15_hw_params, +}; + +static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_LINE("Line In", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), +}; + +static const struct snd_soc_dapm_route audio_map[] = { + {"Headphone Jack", NULL, "LHPOUT"}, + {"Headphone Jack", NULL, "RHPOUT"}, + + {"LLINEIN", NULL, "Line In"}, + {"RLINEIN", NULL, "Line In"}, + + {"MICIN", NULL, "Mic Jack"}, +}; + +static int snappercl15_tlv320aic23_init(struct snd_soc_codec *codec) +{ + snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, + ARRAY_SIZE(tlv320aic23_dapm_widgets)); + + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + return 0; +} + +static struct snd_soc_dai_link snappercl15_dai = { + .name = "tlv320aic23", + .stream_name = "AIC23", + .cpu_dai = &ep93xx_i2s_dai, + .codec_dai = &tlv320aic23_dai, + .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) +{ + int ret; + + if (!machine_is_snapper_cl15()) + return -ENODEV; + + ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, + EP93XX_SYSCON_I2SCLKDIV_ORIDE | + EP93XX_SYSCON_I2SCLKDIV_SPOL); + if (ret) + return ret; + + snappercl15_snd_device = platform_device_alloc("soc-audio", -1); + if (!snappercl15_snd_device) + return -ENOMEM; + + platform_set_drvdata(snappercl15_snd_device, &snappercl15_snd_devdata); + snappercl15_snd_devdata.dev = &snappercl15_snd_device->dev; + ret = platform_device_add(snappercl15_snd_device); + if (ret) + platform_device_put(snappercl15_snd_device); + + return ret; +} + +static void __exit snappercl15_exit(void) +{ + platform_device_unregister(snappercl15_snd_device); + ep93xx_i2s_release(); +} + +module_init(snappercl15_init); +module_exit(snappercl15_exit); + +MODULE_AUTHOR("Ryan Mallon "); +MODULE_DESCRIPTION("ALSA SoC Snapper CL15"); +MODULE_LICENSE("GPL"); + -- cgit v1.2.3 From ec6375533748806a1a49dad7ce124cc02886854a Mon Sep 17 00:00:00 2001 From: Raffaele Recalcati Date: Tue, 6 Jul 2010 10:39:03 +0200 Subject: ASoC: DaVinci: Added selection of clk input pin for McBSP When McBSP peripheral gets the clock from an external pin, there are three possible chooses, MCBSP_CLKX, MCBSP_CLKR and MCBSP_CLKS. evm-dm365 uses MCBSP_CLKR, instead in bmx board I have a different hardware connection and I use MCBSP_CLKS, so I have added this possibility. This patch has been developed against the: http://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci.git git tree and has been tested on bmx board (similar to dm365 evm) Signed-off-by: Raffaele Recalcati Signed-off-by: Davide Bonfanti Acked-by: Liam Girdwood Acked-by: Sudhakar Rajashekhara Signed-off-by: Mark Brown --- arch/arm/mach-davinci/include/mach/asp.h | 15 +++++++++++++++ sound/soc/davinci/davinci-i2s.c | 29 ++++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/include/mach/asp.h b/arch/arm/mach-davinci/include/mach/asp.h index 834725f1e81d..0847d2144f1f 100644 --- a/arch/arm/mach-davinci/include/mach/asp.h +++ b/arch/arm/mach-davinci/include/mach/asp.h @@ -63,6 +63,16 @@ struct snd_platform_data { unsigned sram_size_playback; unsigned sram_size_capture; + /* + * If McBSP peripheral gets the clock from an external pin, + * there are three chooses, that are MCBSP_CLKX, MCBSP_CLKR + * and MCBSP_CLKS. + * Depending on different hardware connections it is possible + * to use this setting to change the behaviour of McBSP + * driver. The dm365_clk_input_pin enum is available for dm365 + */ + int clk_input_pin; + /* McASP specific fields */ int tdm_slots; u8 op_mode; @@ -78,6 +88,11 @@ enum { MCASP_VERSION_2, /* DA8xx/OMAPL1x */ }; +enum dm365_clk_input_pin { + MCBSP_CLKR = 0, /* DM365 */ + MCBSP_CLKS, +}; + #define INACTIVE_MODE 0 #define TX_MODE 1 #define RX_MODE 2 diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index c8f038cb4c5e..ba5644b5fbbf 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c @@ -122,6 +122,7 @@ static const unsigned char double_fmt[SNDRV_PCM_FORMAT_S32_LE + 1] = { }; struct davinci_mcbsp_dev { + struct device *dev; struct davinci_pcm_dma_params dma_params[2]; void __iomem *base; #define MOD_DSP_A 0 @@ -153,6 +154,7 @@ struct davinci_mcbsp_dev { unsigned int fmt; int clk_div; + int clk_input_pin; }; static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev, @@ -279,11 +281,26 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, DAVINCI_MCBSP_PCR_CLKRM; break; case SND_SOC_DAIFMT_CBM_CFS: - /* McBSP CLKR pin is the input for the Sample Rate Generator. - * McBSP FSR and FSX are driven by the Sample Rate Generator. */ - pcr = DAVINCI_MCBSP_PCR_SCLKME | - DAVINCI_MCBSP_PCR_FSXM | - DAVINCI_MCBSP_PCR_FSRM; + pcr = DAVINCI_MCBSP_PCR_FSRM | DAVINCI_MCBSP_PCR_FSXM; + /* + * Selection of the clock input pin that is the + * input for the Sample Rate Generator. + * McBSP FSR and FSX are driven by the Sample Rate + * Generator. + */ + switch (dev->clk_input_pin) { + case MCBSP_CLKS: + pcr |= DAVINCI_MCBSP_PCR_CLKXM | + DAVINCI_MCBSP_PCR_CLKRM; + break; + case MCBSP_CLKR: + pcr |= DAVINCI_MCBSP_PCR_SCLKME; + break; + default: + dev_err(dev->dev, "bad clk_input_pin\n"); + return -EINVAL; + } + break; case SND_SOC_DAIFMT_CBM_CFM: /* codec is master */ @@ -644,6 +661,7 @@ static int davinci_i2s_probe(struct platform_device *pdev) pdata->sram_size_playback; dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].sram_size = pdata->sram_size_capture; + dev->clk_input_pin = pdata->clk_input_pin; } dev->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(dev->clk)) { @@ -676,6 +694,7 @@ static int davinci_i2s_probe(struct platform_device *pdev) goto err_free_mem; } dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; + dev->dev = &pdev->dev; davinci_i2s_dai.private_data = dev; davinci_i2s_dai.capture.dma_data = dev->dma_params; -- cgit v1.2.3 From d9823ed9fa3126097dfd2bbce6dc33957c1be728 Mon Sep 17 00:00:00 2001 From: Raffaele Recalcati Date: Tue, 6 Jul 2010 10:39:04 +0200 Subject: ASoC: DaVinci: More accurate continuous serial clock for McBSP (I2S) i2s_accurate_sck switch can be used to have a better approximate sampling frequency. The clock is an externally visible bit clock and it is named i2s continuous serial clock (I2S_SCK). The trade off is between more accurate clock (fast clock) and less accurate clock (slow clock). The waveform will be not symmetric. Probably it is possible to get a better algorithm for calculating the divider, trying to keep a slower clock as possible. This patch has been developed against the http://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci.git git tree and has been tested on bmx board (similar to dm365 evm, but using uda1345 as external audio codec). Signed-off-by: Raffaele Recalcati Signed-off-by: Davide Bonfanti Acked-by: Liam Girdwood Acked-by: Sudhakar Rajashekhara Signed-off-by: Mark Brown --- arch/arm/mach-davinci/include/mach/asp.h | 33 ++++++++++++++++++++++++++++++++ sound/soc/davinci/davinci-i2s.c | 24 ++++++++++++++++++----- 2 files changed, 52 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/include/mach/asp.h b/arch/arm/mach-davinci/include/mach/asp.h index 0847d2144f1f..b12c69edeea5 100644 --- a/arch/arm/mach-davinci/include/mach/asp.h +++ b/arch/arm/mach-davinci/include/mach/asp.h @@ -73,6 +73,39 @@ struct snd_platform_data { */ int clk_input_pin; + /* + * This flag works when both clock and FS are outputs for the cpu + * and makes clock more accurate (FS is not symmetrical and the + * clock is very fast. + * The clock becoming faster is named + * i2s continuous serial clock (I2S_SCK) and it is an externally + * visible bit clock. + * + * first line : WordSelect + * second line : ContinuousSerialClock + * third line: SerialData + * + * SYMMETRICAL APPROACH: + * _______________________ LEFT + * _| RIGHT |______________________| + * _ _ _ _ _ _ _ _ + * _| |_| |_ x16 _| |_| |_| |_| |_ x16 _| |_| |_ + * _ _ _ _ _ _ _ _ + * _/ \_/ \_ ... _/ \_/ \_/ \_/ \_ ... _/ \_/ \_ + * \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ + * + * ACCURATE CLOCK APPROACH: + * ______________ LEFT + * _| RIGHT |_______________________________| + * _ _ _ _ _ _ _ _ _ + * _| |_ x16 _| |_| |_ x16 _| |_| |_| |_| |_| |_| | + * _ _ _ _ dummy cycles + * _/ \_ ... _/ \_/ \_ ... _/ \__________________ + * \_/ \_/ \_/ \_/ + * + */ + bool i2s_accurate_sck; + /* McASP specific fields */ int tdm_slots; u8 op_mode; diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index ba5644b5fbbf..b251bc9a9812 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c @@ -155,6 +155,7 @@ struct davinci_mcbsp_dev { unsigned int fmt; int clk_div; int clk_input_pin; + bool i2s_accurate_sck; }; static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev, @@ -447,11 +448,23 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, DAVINCI_MCBSP_SRGR_CLKSM; srgr |= DAVINCI_MCBSP_SRGR_FWID(mcbsp_word_length * 8 - 1); - /* symmetric waveforms */ - clk_div = freq / (mcbsp_word_length * 16) / - params->rate_num * params->rate_den; - srgr |= DAVINCI_MCBSP_SRGR_FPER(mcbsp_word_length * - 16 - 1); + if (dev->i2s_accurate_sck) { + clk_div = 256; + do { + framesize = (freq / (--clk_div)) / + params->rate_num * + params->rate_den; + } while (((framesize < 33) || (framesize > 4095)) && + (clk_div)); + clk_div--; + srgr |= DAVINCI_MCBSP_SRGR_FPER(framesize - 1); + } else { + /* symmetric waveforms */ + clk_div = freq / (mcbsp_word_length * 16) / + params->rate_num * params->rate_den; + srgr |= DAVINCI_MCBSP_SRGR_FPER(mcbsp_word_length * + 16 - 1); + } clk_div &= 0xFF; srgr |= clk_div; break; @@ -662,6 +675,7 @@ static int davinci_i2s_probe(struct platform_device *pdev) dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].sram_size = pdata->sram_size_capture; dev->clk_input_pin = pdata->clk_input_pin; + dev->i2s_accurate_sck = pdata->i2s_accurate_sck; } dev->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(dev->clk)) { -- cgit v1.2.3 From 90dc763fef4c869e60b2a7ad92e1a7dab68575ea Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sun, 11 Jul 2010 12:16:36 +0200 Subject: sound: push BKL into open functions This moves the lock_kernel() call from soundcore_open to the individual OSS device drivers, where we can deal with it one driver at a time if needed, or just kill off the drivers. All core components in ALSA already provide adequate locking in their open()-functions and do not require the big kernel lock, so there is no need to add the BKL there. Signed-off-by: Arnd Bergmann Signed-off-by: Takashi Iwai --- arch/um/drivers/hostaudio_kern.c | 6 ++++++ sound/oss/au1550_ac97.c | 26 +++++++++++++++++--------- sound/oss/dmasound/dmasound_core.c | 28 ++++++++++++++++++++++------ sound/oss/msnd_pinnacle.c | 10 +++++++--- sound/oss/sh_dac_audio.c | 9 +++++++-- sound/oss/soundcard.c | 20 +++++++++++--------- sound/oss/swarm_cs4297a.c | 17 ++++++++++++++++- sound/oss/vwsnd.c | 8 ++++++++ sound/sound_core.c | 6 +----- 9 files changed, 95 insertions(+), 35 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index ae42695c3597..68142df76608 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c @@ -8,6 +8,7 @@ #include "linux/slab.h" #include "linux/sound.h" #include "linux/soundcard.h" +#include "linux/smp_lock.h" #include "asm/uaccess.h" #include "init.h" #include "os.h" @@ -198,7 +199,10 @@ static int hostaudio_open(struct inode *inode, struct file *file) if (file->f_mode & FMODE_WRITE) w = 1; + lock_kernel(); ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); + unlock_kernel(); + if (ret < 0) { kfree(state); return ret; @@ -254,7 +258,9 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file) if (file->f_mode & FMODE_WRITE) w = 1; + lock_kernel(); ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); + unlock_kernel(); if (ret < 0) { printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', " diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c index c1070e33b32f..fb913e568de1 100644 --- a/sound/oss/au1550_ac97.c +++ b/sound/oss/au1550_ac97.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -807,7 +808,9 @@ au1550_llseek(struct file *file, loff_t offset, int origin) static int au1550_open_mixdev(struct inode *inode, struct file *file) { + lock_kernel(); file->private_data = &au1550_state; + unlock_kernel(); return 0; } @@ -1797,21 +1800,22 @@ au1550_open(struct inode *inode, struct file *file) #endif file->private_data = s; + lock_kernel(); /* wait for device to become free */ mutex_lock(&s->open_mutex); while (s->open_mode & file->f_mode) { - if (file->f_flags & O_NONBLOCK) { - mutex_unlock(&s->open_mutex); - return -EBUSY; - } + ret = -EBUSY; + if (file->f_flags & O_NONBLOCK) + goto out; add_wait_queue(&s->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); mutex_unlock(&s->open_mutex); schedule(); remove_wait_queue(&s->open_wait, &wait); set_current_state(TASK_RUNNING); + ret = -ERESTARTSYS; if (signal_pending(current)) - return -ERESTARTSYS; + goto out2; mutex_lock(&s->open_mutex); } @@ -1840,17 +1844,21 @@ au1550_open(struct inode *inode, struct file *file) if (file->f_mode & FMODE_READ) { if ((ret = prog_dmabuf_adc(s))) - return ret; + goto out; } if (file->f_mode & FMODE_WRITE) { if ((ret = prog_dmabuf_dac(s))) - return ret; + goto out; } s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); - mutex_unlock(&s->open_mutex); mutex_init(&s->sem); - return 0; + ret = 0; +out: + mutex_unlock(&s->open_mutex); +out2: + unlock_kernel(); + return ret; } static int diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index 3f3c3f71db4b..5a4f38c0f480 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -323,9 +323,13 @@ static struct { static int mixer_open(struct inode *inode, struct file *file) { - if (!try_module_get(dmasound.mach.owner)) + lock_kernel(); + if (!try_module_get(dmasound.mach.owner)) { + unlock_kernel(); return -ENODEV; + } mixer.busy = 1; + unlock_kernel(); return 0; } @@ -737,8 +741,11 @@ static int sq_open(struct inode *inode, struct file *file) { int rc; - if (!try_module_get(dmasound.mach.owner)) + lock_kernel(); + if (!try_module_get(dmasound.mach.owner)) { + unlock_kernel(); return -ENODEV; + } rc = write_sq_open(file); /* checks the f_mode */ if (rc) @@ -781,10 +788,11 @@ static int sq_open(struct inode *inode, struct file *file) sound_set_format(AFMT_MU_LAW); } #endif - + unlock_kernel(); return 0; out: module_put(dmasound.mach.owner); + unlock_kernel(); return rc; } @@ -1226,12 +1234,17 @@ static int state_open(struct inode *inode, struct file *file) { char *buffer = state.buf; int len = 0; + int ret; + lock_kernel(); + ret = -EBUSY; if (state.busy) - return -EBUSY; + goto out; + ret = -ENODEV; if (!try_module_get(dmasound.mach.owner)) - return -ENODEV; + goto out; + state.ptr = 0; state.busy = 1; @@ -1293,7 +1306,10 @@ printk("dmasound: stat buffer used %d bytes\n", len) ; printk(KERN_ERR "dmasound_core: stat buffer overflowed!\n"); state.len = len; - return 0; + ret = 0; +out: + unlock_kernel(); + return ret; } static int state_release(struct inode *inode, struct file *file) diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c index a1e3f9671bea..153d822bf9a3 100644 --- a/sound/oss/msnd_pinnacle.c +++ b/sound/oss/msnd_pinnacle.c @@ -756,12 +756,15 @@ static int dev_open(struct inode *inode, struct file *file) int minor = iminor(inode); int err = 0; + lock_kernel(); if (minor == dev.dsp_minor) { if ((file->f_mode & FMODE_WRITE && test_bit(F_AUDIO_WRITE_INUSE, &dev.flags)) || (file->f_mode & FMODE_READ && - test_bit(F_AUDIO_READ_INUSE, &dev.flags))) - return -EBUSY; + test_bit(F_AUDIO_READ_INUSE, &dev.flags))) { + err = -EBUSY; + goto out; + } if ((err = dsp_open(file)) >= 0) { dev.nresets = 0; @@ -782,7 +785,8 @@ static int dev_open(struct inode *inode, struct file *file) /* nothing */ } else err = -EINVAL; - +out: + unlock_kernel(); return err; } diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c index 4153752507e3..8f0be4053a5a 100644 --- a/sound/oss/sh_dac_audio.c +++ b/sound/oss/sh_dac_audio.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -216,13 +217,17 @@ static int dac_audio_open(struct inode *inode, struct file *file) { if (file->f_mode & FMODE_READ) return -ENODEV; - if (in_use) + + lock_kernel(); + if (in_use) { + unlock_kernel(); return -EBUSY; + } in_use = 1; dac_audio_start(); - + unlock_kernel(); return 0; } diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c index 2d9c51312622..92aa762ffb7e 100644 --- a/sound/oss/soundcard.c +++ b/sound/oss/soundcard.c @@ -210,42 +210,44 @@ static int sound_open(struct inode *inode, struct file *file) printk(KERN_ERR "Invalid minor device %d\n", dev); return -ENXIO; } + lock_kernel(); switch (dev & 0x0f) { case SND_DEV_CTL: dev >>= 4; if (dev >= 0 && dev < MAX_MIXER_DEV && mixer_devs[dev] == NULL) { request_module("mixer%d", dev); } + retval = -ENXIO; if (dev && (dev >= num_mixers || mixer_devs[dev] == NULL)) - return -ENXIO; + break; if (!try_module_get(mixer_devs[dev]->owner)) - return -ENXIO; + break; + + retval = 0; break; case SND_DEV_SEQ: case SND_DEV_SEQ2: - if ((retval = sequencer_open(dev, file)) < 0) - return retval; + retval = sequencer_open(dev, file); break; case SND_DEV_MIDIN: - if ((retval = MIDIbuf_open(dev, file)) < 0) - return retval; + retval = MIDIbuf_open(dev, file); break; case SND_DEV_DSP: case SND_DEV_DSP16: case SND_DEV_AUDIO: - if ((retval = audio_open(dev, file)) < 0) - return retval; + retval = audio_open(dev, file); break; default: printk(KERN_ERR "Invalid minor device %d\n", dev); - return -ENXIO; + retval = -ENXIO; } + unlock_kernel(); return 0; } diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c index 3136c88eacdf..34b0838793a6 100644 --- a/sound/oss/swarm_cs4297a.c +++ b/sound/oss/swarm_cs4297a.c @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -1534,6 +1535,7 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file) CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4, printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()+\n")); + lock_kernel(); list_for_each(entry, &cs4297a_devs) { s = list_entry(entry, struct cs4297a_state, list); @@ -1544,6 +1546,8 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file) { CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2, printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- -ENODEV\n")); + + unlock_kernel(); return -ENODEV; } VALIDATE_STATE(s); @@ -1551,6 +1555,7 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file) CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4, printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- 0\n")); + unlock_kernel(); return nonseekable_open(inode, file); } @@ -2369,7 +2374,7 @@ static int cs4297a_release(struct inode *inode, struct file *file) return 0; } -static int cs4297a_open(struct inode *inode, struct file *file) +static int cs4297a_locked_open(struct inode *inode, struct file *file) { int minor = iminor(inode); struct cs4297a_state *s=NULL; @@ -2486,6 +2491,16 @@ static int cs4297a_open(struct inode *inode, struct file *file) return nonseekable_open(inode, file); } +static int cs4297a_open(struct inode *inode, struct file *file) +{ + int ret; + + lock_kernel(); + ret = cs4297a_open(inode, file); + unlock_kernel(); + + return ret; +} // ****************************************************************************************** // Wave (audio) file operations struct. diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c index 20b3b325aa80..99c94c48558c 100644 --- a/sound/oss/vwsnd.c +++ b/sound/oss/vwsnd.c @@ -2921,6 +2921,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file) DBGE("(inode=0x%p, file=0x%p)\n", inode, file); + lock_kernel(); INC_USE_COUNT; for (devc = vwsnd_dev_list; devc; devc = devc->next_dev) if ((devc->audio_minor & ~0x0F) == (minor & ~0x0F)) @@ -2928,6 +2929,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file) if (devc == NULL) { DEC_USE_COUNT; + unlock_kernel(); return -ENODEV; } @@ -2936,11 +2938,13 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file) mutex_unlock(&devc->open_mutex); if (file->f_flags & O_NONBLOCK) { DEC_USE_COUNT; + unlock_kernel(); return -EBUSY; } interruptible_sleep_on(&devc->open_wait); if (signal_pending(current)) { DEC_USE_COUNT; + unlock_kernel(); return -ERESTARTSYS; } mutex_lock(&devc->open_mutex); @@ -2993,6 +2997,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file) file->private_data = devc; DBGRV(); + unlock_kernel(); return 0; } @@ -3062,15 +3067,18 @@ static int vwsnd_mixer_open(struct inode *inode, struct file *file) DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); INC_USE_COUNT; + lock_kernel(); for (devc = vwsnd_dev_list; devc; devc = devc->next_dev) if (devc->mixer_minor == iminor(inode)) break; if (devc == NULL) { DEC_USE_COUNT; + unlock_kernel(); return -ENODEV; } file->private_data = devc; + unlock_kernel(); return 0; } diff --git a/sound/sound_core.c b/sound/sound_core.c index c8627fcd4900..cb61317df509 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c @@ -629,12 +629,8 @@ static int soundcore_open(struct inode *inode, struct file *file) file->f_op = new_fops; spin_unlock(&sound_loader_lock); - if (file->f_op->open) { - /* TODO: push down BKL into indivial open functions */ - lock_kernel(); + if (file->f_op->open) err = file->f_op->open(inode,file); - unlock_kernel(); - } if (err) { fops_put(file->f_op); -- cgit v1.2.3 From 48519f0ae03bc7e86b3dc93e56f1334d53803770 Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Mon, 19 Jul 2010 12:31:16 +0530 Subject: ASoC: davinci: let platform data define edma queue numbers Currently the EDMA queue to be used by for servicing ASP through internal RAM is fixed to EDMAQ_0 and that to service internal RAM from external RAM is fixed to EDMAQ_1. This may not be the desirable configuration on all platforms. For example, on DM365, queue 0 has large fifo size and is more suitable for video transfers. Having audio and video transfers on the same queue may lead to starvation on audio side. platform data as defined currently passes a queue number to the driver but that remains unused inside the driver. Fix this by defining one queue each for ASP and RAM transfers in the platform data and using it inside the driver. Since EDMAQ_0 maps to 0, thats the queue that will be used if the asp queue number is not initialized. None of the platforms currently utilize ping-pong transfers through internal RAM so that functionality remains unchanged too. This patch has been tested on DM644x and OMAP-L138 EVMs. Signed-off-by: Sekhar Nori Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- arch/arm/mach-davinci/board-da830-evm.c | 2 +- arch/arm/mach-davinci/board-da850-evm.c | 2 +- arch/arm/mach-davinci/board-dm646x-evm.c | 4 ++-- arch/arm/mach-davinci/include/mach/asp.h | 3 ++- sound/soc/davinci/davinci-i2s.c | 10 ++++++++++ sound/soc/davinci/davinci-mcasp.c | 6 ++++-- sound/soc/davinci/davinci-pcm.c | 5 +++-- sound/soc/davinci/davinci-pcm.h | 3 ++- 8 files changed, 25 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index 212d97084bd7..bc384d3561da 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -208,7 +208,7 @@ static struct snd_platform_data da830_evm_snd_data = { .num_serializer = ARRAY_SIZE(da830_iis_serializer_direction), .tdm_slots = 2, .serial_dir = da830_iis_serializer_direction, - .eventq_no = EVENTQ_0, + .asp_chan_q = EVENTQ_0, .version = MCASP_VERSION_2, .txnumevt = 1, .rxnumevt = 1, diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 2ec3095ffb7b..d4ec18d0b4a4 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -342,7 +342,7 @@ static struct snd_platform_data da850_evm_snd_data = { .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), .tdm_slots = 2, .serial_dir = da850_iis_serializer_direction, - .eventq_no = EVENTQ_1, + .asp_chan_q = EVENTQ_1, .version = MCASP_VERSION_2, .txnumevt = 1, .rxnumevt = 1, diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 6d8889342c9f..87521f2d69c7 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -323,7 +323,7 @@ static struct snd_platform_data dm646x_evm_snd_data[] = { .num_serializer = ARRAY_SIZE(dm646x_iis_serializer_direction), .tdm_slots = 2, .serial_dir = dm646x_iis_serializer_direction, - .eventq_no = EVENTQ_0, + .asp_chan_q = EVENTQ_0, }, { .tx_dma_offset = 0x400, @@ -332,7 +332,7 @@ static struct snd_platform_data dm646x_evm_snd_data[] = { .num_serializer = ARRAY_SIZE(dm646x_dit_serializer_direction), .tdm_slots = 32, .serial_dir = dm646x_dit_serializer_direction, - .eventq_no = EVENTQ_0, + .asp_chan_q = EVENTQ_0, }, }; diff --git a/arch/arm/mach-davinci/include/mach/asp.h b/arch/arm/mach-davinci/include/mach/asp.h index b12c69edeea5..9aa240909a2c 100644 --- a/arch/arm/mach-davinci/include/mach/asp.h +++ b/arch/arm/mach-davinci/include/mach/asp.h @@ -52,7 +52,8 @@ struct snd_platform_data { u32 tx_dma_offset; u32 rx_dma_offset; - enum dma_event_q eventq_no; /* event queue number */ + enum dma_event_q asp_chan_q; /* event queue number for ASP channel */ + enum dma_event_q ram_chan_q; /* event queue number for RAM channel */ unsigned int codec_fmt; /* * Allowing this is more efficient and eliminates left and right swaps diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index b251bc9a9812..9e8932abf158 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c @@ -648,6 +648,8 @@ static int davinci_i2s_probe(struct platform_device *pdev) struct snd_platform_data *pdata = pdev->dev.platform_data; struct davinci_mcbsp_dev *dev; struct resource *mem, *ioarea, *res; + enum dma_event_q asp_chan_q = EVENTQ_0; + enum dma_event_q ram_chan_q = EVENTQ_1; int ret; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -676,7 +678,15 @@ static int davinci_i2s_probe(struct platform_device *pdev) pdata->sram_size_capture; dev->clk_input_pin = pdata->clk_input_pin; dev->i2s_accurate_sck = pdata->i2s_accurate_sck; + asp_chan_q = pdata->asp_chan_q; + ram_chan_q = pdata->ram_chan_q; } + + dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].asp_chan_q = asp_chan_q; + dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].ram_chan_q = ram_chan_q; + dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].asp_chan_q = asp_chan_q; + dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].ram_chan_q = ram_chan_q; + dev->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(dev->clk)) { ret = -ENODEV; diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index d3955096d872..b24720894af6 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -890,7 +890,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev) dev->rxnumevt = pdata->rxnumevt; dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; - dma_data->eventq_no = pdata->eventq_no; + dma_data->asp_chan_q = pdata->asp_chan_q; + dma_data->ram_chan_q = pdata->ram_chan_q; dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + io_v2p(dev->base)); @@ -904,7 +905,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev) dma_data->channel = res->start; dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; - dma_data->eventq_no = pdata->eventq_no; + dma_data->asp_chan_q = pdata->asp_chan_q; + dma_data->ram_chan_q = pdata->ram_chan_q; dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + io_v2p(dev->base)); diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index def454e42fcb..a7124116d2e0 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c @@ -381,7 +381,7 @@ static int request_ping_pong(struct snd_pcm_substream *substream, /* Request ram master channel */ link = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, davinci_pcm_dma_irq, substream, - EVENTQ_1); + prtd->params->ram_chan_q); if (link < 0) goto exit1; @@ -477,7 +477,8 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) /* Request asp master DMA channel */ link = prtd->asp_channel = edma_alloc_channel(params->channel, - davinci_pcm_dma_irq, substream, EVENTQ_0); + davinci_pcm_dma_irq, substream, + prtd->params->asp_chan_q); if (link < 0) goto exit1; diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h index 0764944cf10f..b799a02333d8 100644 --- a/sound/soc/davinci/davinci-pcm.h +++ b/sound/soc/davinci/davinci-pcm.h @@ -21,7 +21,8 @@ struct davinci_pcm_dma_params { unsigned short acnt; dma_addr_t dma_addr; /* device physical address for DMA */ unsigned sram_size; - enum dma_event_q eventq_no; /* event queue number */ + enum dma_event_q asp_chan_q; /* event queue number for ASP channel */ + enum dma_event_q ram_chan_q; /* event queue number for RAM channel */ unsigned char data_type; /* xfer data type */ unsigned char convert_mono_stereo; unsigned int fifo_level; -- cgit v1.2.3