From d3f7f65607b1201adad8a2edd5d9e5e95eb01d25 Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Thu, 5 May 2011 11:18:52 +0200 Subject: Ux500 ASoC: Adaptations in the AB8500-parts for U8500. Support added for more channels and more formats and configuration possibilities. Added controls in AB8500-codec for fsbitclk and master generator. Change-Id: I2ea60c54c3892340b4a0d1771a1efdb504cc2495 Signed-off-by: Ola Lilja Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/18279 Tested-by: Ola LILJA2 Reviewed-by: Roger NILSSON1 Conflicts: arch/arm/mach-ux500/board-mop500.c --- sound/soc/codecs/ab8500.c | 208 ++++++++++++++++++++++++++++++++-------- sound/soc/codecs/ab8500.h | 3 + sound/soc/codecs/cg29xx.c | 6 +- sound/soc/ux500/ux500_ab8500.c | 110 +++++++++++++-------- sound/soc/ux500/ux500_av8100.c | 12 ++- sound/soc/ux500/ux500_msp_dai.c | 4 +- sound/soc/ux500/ux500_pcm.c | 17 ++-- 7 files changed, 263 insertions(+), 97 deletions(-) diff --git a/sound/soc/codecs/ab8500.c b/sound/soc/codecs/ab8500.c index 2d2142082a7..b9685518ae1 100644 --- a/sound/soc/codecs/ab8500.c +++ b/sound/soc/codecs/ab8500.c @@ -1059,6 +1059,7 @@ static DECLARE_TLV_DB_SCALE(lin2hs_gain_tlv, -3800, 200, 1); static const char *enum_ena_dis[] = {"Enabled", "Disabled"}; static const char *enum_dis_ena[] = {"Disabled", "Enabled"}; + static SOC_ENUM_SINGLE_DECL(soc_enum_hshpen, REG_ANACONF1, REG_ANACONF1_HSHPEN, enum_dis_ena); static SOC_ENUM_SINGLE_DECL(soc_enum_hslowpow, @@ -1145,7 +1146,14 @@ static const char *enum_fadespeed[] = {"1ms", "4ms", "8ms", "16ms"}; static SOC_ENUM_SINGLE_DECL(soc_enum_fadespeed, REG_HSRDIGGAIN, REG_HSRDIGGAIN_FADESPEED, enum_fadespeed); -/* XXX move to DAPM */ +static SOC_ENUM_SINGLE_DECL(soc_enum_mastgen, + REG_DIGIFCONF1, REG_DIGIFCONF1_ENMASTGEN, enum_dis_ena); +static SOC_ENUM_SINGLE_DECL(soc_enum_fsbitclk0, + REG_DIGIFCONF1, REG_DIGIFCONF1_ENFSBITCLK0, enum_dis_ena); +static SOC_ENUM_SINGLE_DECL(soc_enum_fsbitclk1, + REG_DIGIFCONF1, REG_DIGIFCONF1_ENFSBITCLK1, enum_dis_ena); + +/* TODO: move to DAPM */ static SOC_ENUM_SINGLE_DECL(soc_enum_enfirsids, REG_SIDFIRCONF, REG_SIDFIRCONF_ENFIRSIDS, enum_dis_ena); static SOC_ENUM_SINGLE_DECL(soc_enum_parlhf, @@ -1220,7 +1228,7 @@ static struct snd_kcontrol_new ab8500_snd_controls[] = { REG_PWMGENCONFX_PWMVIBXDUTCYC, REG_PWMGENCONFX_PWMVIBXDUTCYC_MAX, NORMAL), - /* XXX move to DAPM */ + /* TODO: move to DAPM */ SOC_ENUM("Sidetone Playback Switch", soc_enum_enfirsids), SOC_ENUM("IHF L and R Bridge Playback Route", soc_enum_parlhf), SOC_ENUM("Vibra 1 and 2 Bridge Playback Route", soc_enum_parlvib), @@ -1280,6 +1288,10 @@ static struct snd_kcontrol_new ab8500_snd_controls[] = { REG_DIGLINHSLGAIN, REG_DIGLINHSRGAIN, REG_DIGLINHSXGAIN_LINTOHSXGAIN, REG_DIGLINHSXGAIN_LINTOHSXGAIN_MAX, INVERT, lin2hs_gain_tlv), + + SOC_ENUM("Digital Interface Master Generator Switch", soc_enum_mastgen), + SOC_ENUM("Digital Interface 0 Bit-clock Switch", soc_enum_fsbitclk0), + SOC_ENUM("Digital Interface 1 Bit-clock Switch", soc_enum_fsbitclk1), }; static int ab8500_add_widgets(struct snd_soc_codec *codec) @@ -1305,6 +1317,63 @@ static int ab8500_add_widgets(struct snd_soc_codec *codec) return 0; } +int ab8500_set_word_length(struct snd_soc_dai *dai, unsigned int wl) +{ + unsigned int clear_mask; + unsigned int set_mask = 0; + struct snd_soc_codec *codec = dai->codec; + + clear_mask = BMASK(REG_DIGIFCONF2_IF0WL0) | BMASK(REG_DIGIFCONF2_IF0WL1); + + switch (wl) { + case 16: + break; + case 20: + set_mask |= BMASK(REG_DIGIFCONF2_IF0WL0); + break; + case 24: + set_mask |= BMASK(REG_DIGIFCONF2_IF0WL1); + break; + case 32: + set_mask |= BMASK(REG_DIGIFCONF2_IF0WL1) | + BMASK(REG_DIGIFCONF2_IF0WL0); + break; + default: + pr_err("%s: Unsupporter word-length 0x%x\n", __func__, wl); + return -EINVAL; + } + + pr_debug("%s: Word-length: %d bits.\n", __func__, wl); + ab8500_update_audio_reg(codec, REG_DIGIFCONF2, clear_mask, set_mask); + + return 0; +} + +int ab8500_set_bit_delay(struct snd_soc_dai *dai, unsigned int delay) +{ + unsigned int clear_mask; + unsigned int set_mask = 0; + struct snd_soc_codec *codec = dai->codec; + + clear_mask = BMASK(REG_DIGIFCONF2_IF0DEL); + + switch (delay) { + case 0: + break; + case 1: + set_mask |= BMASK(REG_DIGIFCONF2_IF0DEL); + break; + default: + pr_err("%s: Unsupported bit-delay (0x%x)!\n", __func__, delay); + return -EINVAL; + } + + pr_debug("%s: Bit-delay: %d bits.\n", __func__, delay); + ab8500_update_audio_reg(codec, REG_DIGIFCONF2, clear_mask, set_mask); + + return 0; +} + static int ab8500_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai) { @@ -1388,16 +1457,16 @@ static int set_dai_clock_gate(struct snd_soc_codec *codec, unsigned int fmt) clear_mask = BMASK(REG_DIGIFCONF1_ENMASTGEN) | BMASK(REG_DIGIFCONF1_ENFSBITCLK0); - set_mask = 0; + + set_mask = BMASK(REG_DIGIFCONF1_ENMASTGEN); switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { case SND_SOC_DAIFMT_CONT: /* continuous clock */ - pr_info("- Clock is not gated\n"); - set_mask |= BMASK(REG_DIGIFCONF1_ENMASTGEN); + pr_info("- Clock is continous.\n"); set_mask |= BMASK(REG_DIGIFCONF1_ENFSBITCLK0); break; case SND_SOC_DAIFMT_GATED: /* clock is gated */ - pr_info("- Clock IS gated\n"); + pr_info("- Clock is gated.\n"); break; default: pr_err("Unsupporter clock mask 0x%x\n", @@ -1435,22 +1504,26 @@ static int ab8500_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) } /* Setting data transfer format */ - clear_mask = REG_MASK_ALL; + clear_mask = BMASK(REG_DIGIFCONF2_IF0FORMAT0) | + BMASK(REG_DIGIFCONF2_IF0FORMAT1) | + BMASK(REG_DIGIFCONF2_FSYNC0P) | + BMASK(REG_DIGIFCONF2_BITCLK0P); + set_mask = 0; switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: /* I2S mode */ pr_info("- FORMAT I2S\n"); set_mask |= BMASK(REG_DIGIFCONF2_IF0FORMAT1); - set_mask |= BMASK(REG_DIGIFCONF2_IF0DEL); - /* 32 bit */ - set_mask |= BMASK(REG_DIGIFCONF2_IF0WL1) | - BMASK(REG_DIGIFCONF2_IF0WL0); + /* 32 bit, 0 delay */ + ab8500_set_word_length(dai, 32); + ab8500_set_bit_delay(dai, 0); + break; case SND_SOC_DAIFMT_DSP_A: /* L data MSB after FRM LRC */ pr_info("- FORMAT DSP A\n"); - set_mask |= BMASK(REG_DIGIFCONF2_IF0FORMAT0); + set_mask |= BMASK(REG_DIGIFCONF2_IF0FORMAT1); break; case SND_SOC_DAIFMT_DSP_B: /* L data MSB during FRM LRC */ pr_info("- FORMAT DSP B\n"); @@ -1496,9 +1569,8 @@ static int ab8500_set_dai_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) { - int data; struct snd_soc_codec *codec = dai->codec; - unsigned int clear_mask; + unsigned int set_mask, clear_mask, slots_active; /* Only 16 bit slot width is supported at the moment in TDM mode */ if (slot_width != 16) { @@ -1507,48 +1579,98 @@ static int ab8500_set_dai_tdm_slot(struct snd_soc_dai *dai, return -EINVAL; } - /* Set the TDM clocking according to slot count */ + /* Setup TDM clocking according to slot count */ + pr_debug("%s: Slots, total: %d\n", __func__, slots); + clear_mask = BMASK(REG_DIGIFCONF1_IF0BITCLKOS0) | + BMASK(REG_DIGIFCONF1_IF0BITCLKOS1); switch (slots) { case 2: - data = REG_MASK_NONE; + set_mask = REG_MASK_NONE; break; case 4: - data = BMASK(REG_DIGIFCONF1_IF0BITCLKOS0); + set_mask = BMASK(REG_DIGIFCONF1_IF0BITCLKOS0); break; case 8: - data = BMASK(REG_DIGIFCONF1_IF0BITCLKOS1); + set_mask = BMASK(REG_DIGIFCONF1_IF0BITCLKOS1); break; case 16: - data = BMASK(REG_DIGIFCONF1_IF0BITCLKOS0) | + set_mask = BMASK(REG_DIGIFCONF1_IF0BITCLKOS0) | BMASK(REG_DIGIFCONF1_IF0BITCLKOS1); break; default: - pr_err("%s: Unsupported slots %d.\n", __func__, slots); + pr_err("%s: Unsupported number of slots (%d)!\n", __func__, slots); return -EINVAL; } + ab8500_update_audio_reg(codec, REG_DIGIFCONF1, clear_mask, set_mask); - ab8500_update_audio_reg(codec, REG_DIGIFCONF1, - BMASK(REG_DIGIFCONF1_IF0BITCLKOS0) | - BMASK(REG_DIGIFCONF1_IF0BITCLKOS1), - data); - - /* XXX Make slot configuration as a control */ - + /* Setup TDM DA according to active tx slots */ clear_mask = REG_DASLOTCONFX_SLTODAX_MASK; + slots_active = hweight32(tx_mask); + pr_debug("%s: Slots, active, TX: %d\n", __func__, slots_active); + switch (slots_active) { + case 0: + break; + case 1: + /* Slot 9 -> DA_IN1 & DA_IN3 */ + ab8500_update_audio_reg(codec, REG_DASLOTCONF1, clear_mask, 9); + ab8500_update_audio_reg(codec, REG_DASLOTCONF3, clear_mask, 9); + break; + case 2: + /* Slot 9 -> DA_IN1 & DA_IN3, Slot 11 -> DA_IN2 & DA_IN4 */ + ab8500_update_audio_reg(codec, REG_DASLOTCONF1, clear_mask, 9); + ab8500_update_audio_reg(codec, REG_DASLOTCONF3, clear_mask, 9); + ab8500_update_audio_reg(codec, REG_DASLOTCONF2, clear_mask, 11); + ab8500_update_audio_reg(codec, REG_DASLOTCONF4, clear_mask, 11); - /* DA_IN1/3/5 receives slot 9, DA_IN2/4/6 receives slot 11 */ - ab8500_update_audio_reg(codec, REG_DASLOTCONF1, clear_mask, 9); - ab8500_update_audio_reg(codec, REG_DASLOTCONF2, clear_mask, 11); - ab8500_update_audio_reg(codec, REG_DASLOTCONF3, clear_mask, 9); - ab8500_update_audio_reg(codec, REG_DASLOTCONF4, clear_mask, 11); - ab8500_update_audio_reg(codec, REG_DASLOTCONF5, clear_mask, 9); - ab8500_update_audio_reg(codec, REG_DASLOTCONF6, clear_mask, 11); + break; + case 8: + /* Slot 8-15 -> DA_IN1-DA_IN8 */ + ab8500_update_audio_reg(codec, REG_DASLOTCONF1, clear_mask, 8); + ab8500_update_audio_reg(codec, REG_DASLOTCONF2, clear_mask, 9); + ab8500_update_audio_reg(codec, REG_DASLOTCONF3, clear_mask, 10); + ab8500_update_audio_reg(codec, REG_DASLOTCONF4, clear_mask, 11); + ab8500_update_audio_reg(codec, REG_DASLOTCONF5, clear_mask, 12); + ab8500_update_audio_reg(codec, REG_DASLOTCONF6, clear_mask, 13); + ab8500_update_audio_reg(codec, REG_DASLOTCONF7, clear_mask, 14); + ab8500_update_audio_reg(codec, REG_DASLOTCONF8, clear_mask, 15); - /* AD_OUT3 transmits slots 0 & 1 */ - ab8500_update_audio_reg(codec, REG_ADSLOTSEL1, + break; + default: + pr_err("%s: Unsupported number of active TX-slots (%d)!\n", __func__, slots_active); + return -EINVAL; + } + + /* Setup TDM AD according to active RX-slots */ + slots_active = hweight32(rx_mask); + pr_debug("%s: Slots, active, RX: %d\n", __func__, slots_active); + switch (slots_active) { + case 0: + break; + case 1: + /* AD_OUT3 -> slot 0 & 1 */ + ab8500_update_audio_reg(codec, REG_ADSLOTSEL1, REG_MASK_ALL, BMASK(REG_ADSLOTSELX_ODDX_1) | BMASK(REG_ADSLOTSELX_EVENX_1)); + break; + case 2: + /* AD_OUT3 -> slot 0, AD_OUT2 -> slot 1 */ + ab8500_update_audio_reg(codec, REG_ADSLOTSEL1, + REG_MASK_ALL, + BMASK(REG_ADSLOTSELX_ODDX_0) | + BMASK(REG_ADSLOTSELX_EVENX_1)); + break; + case 8: + /* AD_OUT3 -> slot 0, AD_OUT2 -> slot 1 */ + ab8500_update_audio_reg(codec, REG_ADSLOTSEL1, + REG_MASK_ALL, + BMASK(REG_ADSLOTSELX_ODDX_0) | + BMASK(REG_ADSLOTSELX_EVENX_1)); + break; + default: + pr_err("%s: Unsupported number of active RX-slots (%d)!\n", __func__, slots_active); + return -EINVAL; + } return 0; } @@ -1560,7 +1682,7 @@ struct snd_soc_dai_driver ab8500_codec_dai[] = { .playback = { .stream_name = "ab8500_0p", .channels_min = 1, - .channels_max = 2, + .channels_max = 8, .rates = AB8500_SUPPORTED_RATE, .formats = AB8500_SUPPORTED_FMT, }, @@ -1583,7 +1705,7 @@ struct snd_soc_dai_driver ab8500_codec_dai[] = { .capture = { .stream_name = "ab8500_0c", .channels_min = 1, - .channels_max = 1, + .channels_max = 8, .rates = AB8500_SUPPORTED_RATE, .formats = AB8500_SUPPORTED_FMT, }, @@ -1720,12 +1842,16 @@ struct snd_soc_codec_driver ab8500_codec_drv = { .reg_cache_default = ab8500_reg_cache, }; -static int __devinit ab8500_codec_drv_probe(struct platform_device *pdev) +static int ab8500_codec_drv_probe(struct platform_device *pdev) { int err; + struct ab8500_codec_dai_data *dai_data; pr_debug("%s: Enter.\n", __func__); + platform_set_drvdata(pdev, dai_data); + + pr_info("%s: Register codec.\n", __func__); err = snd_soc_register_codec(&pdev->dev, &ab8500_codec_drv, ab8500_codec_dai, @@ -1739,7 +1865,7 @@ static int __devinit ab8500_codec_drv_probe(struct platform_device *pdev) return err; } -static int __devexit ab8500_codec_drv_remove(struct platform_device *pdev) +static int ab8500_codec_drv_remove(struct platform_device *pdev) { pr_debug("%s Enter.\n", __func__); @@ -1769,7 +1895,7 @@ static struct platform_driver ab8500_codec_platform_drv = { .owner = THIS_MODULE, }, .probe = ab8500_codec_drv_probe, - .remove = __devexit_p(ab8500_codec_drv_remove), + .remove = ab8500_codec_drv_remove, .suspend = ab8500_codec_drv_suspend, .resume = ab8500_codec_drv_resume, }; diff --git a/sound/soc/codecs/ab8500.h b/sound/soc/codecs/ab8500.h index 415d73a87a5..ef3e4907878 100644 --- a/sound/soc/codecs/ab8500.h +++ b/sound/soc/codecs/ab8500.h @@ -22,6 +22,9 @@ extern struct snd_soc_codec_driver soc_codec_dev_ab8500; #define AB8500_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE) +int ab8500_set_word_length(struct snd_soc_dai *dai, unsigned int wl); +int ab8500_set_bit_delay(struct snd_soc_dai *dai, unsigned int delay); + /* AB8500 audio bank (0x0d) register definitions */ #define REG_POWERUP 0x00 diff --git a/sound/soc/codecs/cg29xx.c b/sound/soc/codecs/cg29xx.c index 56b23be8e97..272f8f9287b 100644 --- a/sound/soc/codecs/cg29xx.c +++ b/sound/soc/codecs/cg29xx.c @@ -651,7 +651,7 @@ struct snd_soc_codec_driver cg29xx_codec_drv = { .write = cg29xx_codec_write, }; -static __devinit int cg29xx_codec_drv_probe(struct platform_device *pdev) +static int cg29xx_codec_drv_probe(struct platform_device *pdev) { int ret; struct cg29xx_codec_dai_data *dai_data; @@ -714,7 +714,7 @@ static __devinit int cg29xx_codec_drv_probe(struct platform_device *pdev) return 0; } -static int __devexit cg29xx_codec_drv_remove(struct platform_device *pdev) +static int cg29xx_codec_drv_remove(struct platform_device *pdev) { (void)cg2900_audio_close(&codec_private.session); @@ -741,7 +741,7 @@ static struct platform_driver cg29xx_codec_platform_drv = { .owner = THIS_MODULE, }, .probe = cg29xx_codec_drv_probe, - .remove = __devexit_p(cg29xx_codec_drv_remove), + .remove = cg29xx_codec_drv_remove, .suspend = cg29xx_codec_drv_suspend, .resume = cg29xx_codec_drv_resume, }; diff --git a/sound/soc/ux500/ux500_ab8500.c b/sound/soc/ux500/ux500_ab8500.c index 6cb36b43904..44b1164a75a 100644 --- a/sound/soc/ux500/ux500_ab8500.c +++ b/sound/soc/ux500/ux500_ab8500.c @@ -28,20 +28,19 @@ #include "ux500_msp_dai.h" #include "../codecs/ab8500.h" -#define AB8500_DAIFMT_TDM_MASTER \ - (SND_SOC_DAIFMT_DSP_B | \ - SND_SOC_DAIFMT_CBM_CFM | \ - SND_SOC_DAIFMT_NB_NF | \ - SND_SOC_DAIFMT_CONT) - #define TX_SLOT_MONO 0x0008 #define TX_SLOT_STEREO 0x000a #define RX_SLOT_MONO 0x0001 #define RX_SLOT_STEREO 0x0003 +#define TX_SLOT_8CH 0x00FF +#define RX_SLOT_8CH 0x00FF #define DEF_TX_SLOTS TX_SLOT_STEREO #define DEF_RX_SLOTS RX_SLOT_MONO +#define DRIVERMODE_NORMAL 0 +#define DRIVERMODE_CODEC_ONLY 1 + static struct snd_soc_jack jack; /* Slot configuration */ @@ -155,11 +154,13 @@ int ux500_ab8500_hw_params( struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int channels, ret = 0; + unsigned int fmt; + int channels, ret = 0, slots, slot_width, driver_mode; + bool streamIsPlayback; - pr_info("%s: Enter\n", __func__); + pr_debug("%s: Enter\n", __func__); - pr_info("%s: substream->pcm->name = %s\n" + pr_debug("%s: substream->pcm->name = %s\n" "substream->pcm->id = %s.\n" "substream->name = %s.\n" "substream->number = %d.\n", @@ -169,49 +170,80 @@ int ux500_ab8500_hw_params( substream->name, substream->number); - ret = snd_soc_dai_set_fmt(codec_dai, AB8500_DAIFMT_TDM_MASTER); + channels = params_channels(params); + + /* Setup codec depending on driver-mode */ + driver_mode = (channels == 8) ? + DRIVERMODE_CODEC_ONLY : DRIVERMODE_NORMAL; + pr_debug("%s: Driver-mode: %s.\n", + __func__, + (driver_mode == DRIVERMODE_NORMAL) ? "NORMAL" : "CODEC_ONLY"); + if (driver_mode == DRIVERMODE_NORMAL) { + ab8500_set_bit_delay(codec_dai, 0); + ab8500_set_word_length(codec_dai, 16); + fmt = SND_SOC_DAIFMT_DSP_B | + SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CONT; + } else { + ab8500_set_bit_delay(codec_dai, 1); + ab8500_set_word_length(codec_dai, 20); + fmt = SND_SOC_DAIFMT_DSP_B | + SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_GATED; + } + + ret = snd_soc_dai_set_fmt(codec_dai, fmt); if (ret < 0) { - pr_err("%s: snd_soc_dai_set_fmt failed codec_dai %d.\n", - __func__, ret); + pr_err("%s: snd_soc_dai_set_fmt failed for codec_dai (ret = %d).\n", + __func__, + ret); return ret; } - ret = snd_soc_dai_set_fmt(cpu_dai, AB8500_DAIFMT_TDM_MASTER); + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); if (ret < 0) { - pr_err("%s: snd_soc_dai_set_fmt cpu_dai %d.\n", - __func__, ret); + pr_err("%s: snd_soc_dai_set_fmt for cpu_dai (ret = %d).\n", + __func__, + ret); return ret; } - channels = params_channels(params); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (channels == 1) - tx_slots = TX_SLOT_MONO; - else if (channels == 2) - tx_slots = TX_SLOT_STEREO; - else - return -EINVAL; - } else { - if (channels == 1) - rx_slots = RX_SLOT_MONO; - else if (channels == 2) - rx_slots = RX_SLOT_STEREO; - else - return -EINVAL; + /* Setup TDM-slots */ + + streamIsPlayback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); + switch (channels) { + case 1: + slots = 16; + slot_width = 16; + tx_slots = (streamIsPlayback) ? TX_SLOT_MONO : 0; + rx_slots = (streamIsPlayback) ? 0 : RX_SLOT_MONO; + break; + case 2: + slots = 16; + slot_width = 16; + tx_slots = (streamIsPlayback) ? TX_SLOT_STEREO : 0; + rx_slots = (streamIsPlayback) ? 0 : RX_SLOT_STEREO; + break; + case 8: + slots = 16; + slot_width = 16; + tx_slots = (streamIsPlayback) ? TX_SLOT_8CH : 0; + rx_slots = (streamIsPlayback) ? 0 : RX_SLOT_8CH; + break; + default: + return -EINVAL; } - pr_info("%s: CPU-DAI TDM: TX=0x%04X RX=0x%04x\n", + pr_debug("%s: CPU-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__, tx_slots, rx_slots); - ret = snd_soc_dai_set_tdm_slot(cpu_dai, - tx_slots, rx_slots, - 16, 16); + ret = snd_soc_dai_set_tdm_slot(cpu_dai, tx_slots, rx_slots, + slots, slot_width); - pr_info("%s: CODEC-DAI TDM: TX=0x%04X RX=0x%04x\n", + pr_debug("%s: CODEC-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__, tx_slots, rx_slots); - ret += snd_soc_dai_set_tdm_slot(codec_dai, - tx_slots, rx_slots, - 16, 16); + ret += snd_soc_dai_set_tdm_slot(codec_dai, tx_slots, rx_slots, slots, slot_width); return ret; } diff --git a/sound/soc/ux500/ux500_av8100.c b/sound/soc/ux500/ux500_av8100.c index 9497b7b6636..5c7213001a0 100644 --- a/sound/soc/ux500/ux500_av8100.c +++ b/sound/soc/ux500/ux500_av8100.c @@ -16,20 +16,28 @@ #include "ux500_av8100.h" #include "ux500_msp_dai.h" +static const char *stream_str(struct snd_pcm_substream *substream) +{ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + return "Playback"; + else + return "Capture"; +} + static int ux500_av8100_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->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int channels = params_channels(params); + int channels = params_channels(params); unsigned int tx_mask, fmt; enum hdmi_channel_allocation hdmi_ca; enum hdmi_audio_channel_count hdmi_cc; struct hdmi_audio_settings as; int ret; - pr_debug("%s: Enter.\n", __func__); + pr_debug("%s: Enter (%s).\n", __func__, stream_str(substream)); pr_debug("%s: substream->pcm->name = %s.\n", __func__, substream->pcm->name); pr_debug("%s: substream->pcm->id = %s.\n", __func__, substream->pcm->id); pr_debug("%s: substream->name = %s.\n", __func__, substream->name); diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index d145c54e654..06f71a173d4 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c @@ -891,7 +891,7 @@ static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = { }; EXPORT_SYMBOL(ux500_msp_dai_drv); -static int __devinit ux500_msp_drv_probe(struct i2s_device *i2s_dev) +static int ux500_msp_drv_probe(struct i2s_device *i2s_dev) { int ret = 0; struct ux500_platform_drvdata *drvdata; @@ -966,7 +966,7 @@ static struct i2s_driver i2sdrv_i2s_v1 = { .owner = THIS_MODULE, }, .probe = ux500_msp_drv_probe, - .remove = __devexit_p(ux500_msp_drv_remove), + .remove = ux500_msp_drv_remove, .id_table = dev_id_table_v1, }; diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index 491cfef0c00..6ad088d8028 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -136,7 +136,6 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream) else snd_soc_set_runtime_hwparams(substream, &ux500_pcm_hw_capture); - /* ensure that buffer size is a multiple of period size */ ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) { @@ -171,9 +170,8 @@ static int ux500_pcm_close(struct snd_pcm_substream *substream) return 0; } -static int ux500_pcm_hw_params( - struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) +static int ux500_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_dma_buffer *buf = runtime->dma_buffer_p; @@ -369,7 +367,7 @@ struct snd_soc_platform_driver ux500_pcm_soc_drv = { }; EXPORT_SYMBOL(ux500_pcm_soc_drv); -static int __devinit ux500_pcm_drv_probe(struct platform_device *pdev) +static int ux500_pcm_drv_probe(struct platform_device *pdev) { int ret; @@ -386,7 +384,7 @@ static int __devinit ux500_pcm_drv_probe(struct platform_device *pdev) return 0; } -static int __devexit ux500_pcm_drv_remove(struct platform_device *pdev) +static int ux500_pcm_drv_remove(struct platform_device *pdev) { pr_debug("%s: Unregister ux500-pcm SoC platform driver.\n", __func__); snd_soc_unregister_platform(&pdev->dev); @@ -396,12 +394,12 @@ static int __devexit ux500_pcm_drv_remove(struct platform_device *pdev) static struct platform_driver ux500_pcm_drv = { .driver = { - .name = "ux500-pcm", - .owner = THIS_MODULE, + .name = "ux500-pcm", + .owner = THIS_MODULE, }, .probe = ux500_pcm_drv_probe, - .remove = __devexit_p(ux500_pcm_drv_remove), + .remove = ux500_pcm_drv_remove, }; static int __init ux500_pcm_drv_init(void) @@ -411,7 +409,6 @@ static int __init ux500_pcm_drv_init(void) return platform_driver_register(&ux500_pcm_drv); } - static void __exit ux500_pcm_drv_exit(void) { pr_debug("%s: Unregister ux500-pcm platform driver.\n", __func__); -- cgit v1.2.3