From b3b408316c0c250acc3230d63b21a70cbe45c49c Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Fri, 6 May 2011 10:07:20 +0200 Subject: Ux500 ASoC: The MSP DAI driver now implements set_sysclk. The cg2900 machine driver does now set the sysclk frequency that drives the MSP. The bitclock will now be correct when the MSP is master. Change-Id: I1134d00cf4b5600997b683977076815fd864ca04 Signed-off-by: roger nilsson Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/19615 Reviewed-by: Ola LILJA2 Conflicts: sound/soc/ux500/ux500_msp_dai.h --- sound/soc/ux500/ux500_cg29xx.c | 14 ++++++++++++++ sound/soc/ux500/ux500_msp_dai.c | 42 ++++++++++++++++++++++++++++++++++++----- sound/soc/ux500/ux500_msp_dai.h | 7 ++++++- 3 files changed, 57 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/soc/ux500/ux500_cg29xx.c b/sound/soc/ux500/ux500_cg29xx.c index 6cc77820a62..e83a6869c5a 100644 --- a/sound/soc/ux500/ux500_cg29xx.c +++ b/sound/soc/ux500/ux500_cg29xx.c @@ -14,7 +14,9 @@ #include #include "../codecs/cg29xx.h" +#include "ux500_msp_dai.h" +#define UX500_CG29XX_MSP_CLOCK_FREQ 18900000 #define UX500_CG29XX_DAI_SLOT_WIDTH 16 #define UX500_CG29XX_DAI_SLOTS 2 #define UX500_CG29XX_DAI_ACTIVE_SLOTS 0x01 @@ -71,6 +73,18 @@ int ux500_cg29xx_hw_params(struct snd_pcm_substream *substream, goto out_err; } + err = snd_soc_dai_set_sysclk(cpu_dai, + UX500_MSP_MASTER_CLOCK, + UX500_CG29XX_MSP_CLOCK_FREQ, + 0); + + if (err) { + pr_err("%s: snd_soc_dai_set_sysclk(cpu_dai) failed with %d.\n", + __func__, + err); + goto out_err; + } + err = snd_soc_dai_set_tdm_slot(cpu_dai, UX500_CG29XX_DAI_ACTIVE_SLOTS, UX500_CG29XX_DAI_ACTIVE_SLOTS, diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index 06f71a173d4..b1fdfa779f2 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c @@ -36,6 +36,7 @@ static struct ux500_platform_drvdata platform_drvdata[UX500_NBR_OF_DAI] = { .capture_active = false, .configured = 0, .data_delay = MSP_DELAY_0, + .master_clk = UX500_MSP_INTERNAL_CLOCK_FREQ, }, { .i2s = NULL, @@ -48,6 +49,7 @@ static struct ux500_platform_drvdata platform_drvdata[UX500_NBR_OF_DAI] = { .capture_active = false, .configured = 0, .data_delay = MSP_DELAY_0, + .master_clk = UX500_MSP_INTERNAL_CLOCK_FREQ, }, { .i2s = NULL, @@ -60,6 +62,7 @@ static struct ux500_platform_drvdata platform_drvdata[UX500_NBR_OF_DAI] = { .capture_active = false, .configured = 0, .data_delay = MSP_DELAY_0, + .master_clk = UX500_MSP_INTERNAL_CLOCK_FREQ, }, { .i2s = NULL, @@ -72,6 +75,7 @@ static struct ux500_platform_drvdata platform_drvdata[UX500_NBR_OF_DAI] = { .capture_active = false, .configured = 0, .data_delay = MSP_DELAY_0, + .master_clk = UX500_MSP_INTERNAL_CLOCK_FREQ, }, }; @@ -452,7 +456,7 @@ static void ux500_msp_dai_compile_msp_config(struct snd_pcm_substream *substream memset(msp_config, 0, sizeof(*msp_config)); - msp_config->input_clock_freq = UX500_MSP_INTERNAL_CLOCK_FREQ; + msp_config->input_clock_freq = private->master_clk; msp_config->tx_fifo_config = TX_FIFO_ENABLE; msp_config->rx_fifo_config = RX_FIFO_ENABLE; msp_config->spi_clk_mode = SPI_CLK_MODE_NORMAL; @@ -730,6 +734,34 @@ static int ux500_msp_dai_set_tdm_slot(struct snd_soc_dai *dai, return 0; } +static int ux500_msp_dai_set_dai_sysclk(struct snd_soc_dai *dai, + int clk_id, + unsigned int freq, + int dir) +{ + struct ux500_platform_drvdata *drvdata = &platform_drvdata[dai->id]; + + pr_debug("%s: MSP %d: Enter. Clk id: %d, freq: %u.\n", + __func__, + dai->id, + clk_id, + freq); + + switch (clk_id) { + case UX500_MSP_MASTER_CLOCK: + drvdata->master_clk = freq; + break; + + default: + pr_err("%s: MSP %d: Invalid clkid: %d.\n", + __func__, + dai->id, + clk_id); + } + + return 0; +} + static int ux500_msp_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) @@ -787,7 +819,7 @@ static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = { }, .ops = (struct snd_soc_dai_ops[]) { { - .set_sysclk = NULL, + .set_sysclk = ux500_msp_dai_set_dai_sysclk, .set_fmt = ux500_msp_dai_set_dai_fmt, .set_tdm_slot = ux500_msp_dai_set_tdm_slot, .startup = ux500_msp_dai_startup, @@ -817,7 +849,7 @@ static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = { }, .ops = (struct snd_soc_dai_ops[]) { { - .set_sysclk = NULL, + .set_sysclk = ux500_msp_dai_set_dai_sysclk, .set_fmt = ux500_msp_dai_set_dai_fmt, .set_tdm_slot = ux500_msp_dai_set_tdm_slot, .startup = ux500_msp_dai_startup, @@ -847,7 +879,7 @@ static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = { }, .ops = (struct snd_soc_dai_ops[]) { { - .set_sysclk = NULL, + .set_sysclk = ux500_msp_dai_set_dai_sysclk, .set_fmt = ux500_msp_dai_set_dai_fmt, .set_tdm_slot = ux500_msp_dai_set_tdm_slot, .startup = ux500_msp_dai_startup, @@ -877,7 +909,7 @@ static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = { }, .ops = (struct snd_soc_dai_ops[]) { { - .set_sysclk = NULL, + .set_sysclk = ux500_msp_dai_set_dai_sysclk, .set_fmt = ux500_msp_dai_set_dai_fmt, .set_tdm_slot = ux500_msp_dai_set_tdm_slot, .startup = ux500_msp_dai_startup, diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h index 73be99bb5ab..a26159bf174 100644 --- a/sound/soc/ux500/ux500_msp_dai.h +++ b/sound/soc/ux500/ux500_msp_dai.h @@ -38,7 +38,7 @@ #ifdef STE_PLATFORM_U5500 #define UX500_MSP_INTERNAL_CLOCK_FREQ 13000000 #else -#define UX500_MSP_INTERNAL_CLOCK_FREQ 38400000 +#define UX500_MSP_INTERNAL_CLOCK_FREQ 40000000 #endif #define UX500_MSP_MIN_CHANNELS 1 @@ -47,6 +47,10 @@ #define PLAYBACK_CONFIGURED 1 #define CAPTURE_CONFIGURED 2 +enum ux500_msp_clock_id { + UX500_MSP_MASTER_CLOCK, +}; + struct ux500_platform_drvdata { struct i2s_device *i2s; unsigned int fmt; @@ -58,6 +62,7 @@ struct ux500_platform_drvdata { bool capture_active; u8 configured; int data_delay; + unsigned int master_clk; }; extern struct snd_soc_dai ux500_msp_dai[UX500_NBR_OF_DAI]; -- cgit v1.2.3