diff options
author | Chao Jiang <chaoj@nvidia.com> | 2010-12-12 22:54:31 +0900 |
---|---|---|
committer | Bharat Nihalani <bnihalani@nvidia.com> | 2010-12-14 21:09:51 -0800 |
commit | d35f2aa8d201d82a53249493072204deaed1d469 (patch) | |
tree | dbb6c3ae8a7225ff436999378bdf8f99a475c5e4 /sound | |
parent | 3f5b985d676191a5e47ef3847e93fcbd6935af4b (diff) |
[misc] convert dos newline to unix format
Linux kernel source code usually use Unix newline.
Change-Id: I24ffca15ebe0eb03b8af1023b552ee17e2c090e0
Reviewed-on: http://git-master/r/12676
Reviewed-by: David Schalig <dschalig@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Tested-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/tegra/Kconfig | 36 | ||||
-rw-r--r-- | sound/soc/tegra/Makefile | 12 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_i2s.c | 604 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_soc.c | 634 |
4 files changed, 643 insertions, 643 deletions
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index 88b54d890f98..3fd917d0297e 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig @@ -1,18 +1,18 @@ -config TEGRA_ALSA
- tristate "Tegra ALSA SoC support"
- select TEGRA_PCM
- select TEGRA_I2S
- select TEGRA_IEC
- select SND_SOC_WM8903
- help
- Say Y if you for ALSA SoC support
-
-config TEGRA_PCM
- tristate "Tegra ALSA pcm callbacks"
-
-config TEGRA_I2S
- tristate "Tegra I2S"
-
-config TEGRA_IEC
- tristate "Tegra IEC"
-
+config TEGRA_ALSA + tristate "Tegra ALSA SoC support" + select TEGRA_PCM + select TEGRA_I2S + select TEGRA_IEC + select SND_SOC_WM8903 + help + Say Y if you for ALSA SoC support + +config TEGRA_PCM + tristate "Tegra ALSA pcm callbacks" + +config TEGRA_I2S + tristate "Tegra I2S" + +config TEGRA_IEC + tristate "Tegra IEC" + diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile index 23652208b893..b1bc3d02109c 100644 --- a/sound/soc/tegra/Makefile +++ b/sound/soc/tegra/Makefile @@ -1,6 +1,6 @@ -ccflags-y += -DNV_DEBUG=0
-obj-$(CONFIG_TEGRA_PCM) += tegra_pcm.o
-obj-$(CONFIG_TEGRA_I2S) += tegra_i2s.o
-obj-$(CONFIG_TEGRA_ALSA) += tegra_soc.o
-
-
+ccflags-y += -DNV_DEBUG=0 +obj-$(CONFIG_TEGRA_PCM) += tegra_pcm.o +obj-$(CONFIG_TEGRA_I2S) += tegra_i2s.o +obj-$(CONFIG_TEGRA_ALSA) += tegra_soc.o + + diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c index d824544d6188..69e07b0c5181 100644 --- a/sound/soc/tegra/tegra_i2s.c +++ b/sound/soc/tegra/tegra_i2s.c @@ -1,302 +1,302 @@ -/*
- * tegra_i2s.c -- ALSA Soc Audio Layer
- *
- * (c) 2010 Nvidia Graphics Pvt. Ltd.
- * http://www.nvidia.com
- *
- * (c) 2006 Wolfson Microelectronics PLC.
- * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
- *
- * (c) 2004-2005 Simtec Electronics
- * http://armlinux.simtec.co.uk/
- * Ben Dooks <ben@simtec.co.uk>
- *
- * 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 "tegra_soc.h"
-
-static void *das_base = IO_ADDRESS(TEGRA_APB_MISC_BASE);
-
-static inline unsigned long das_readl(unsigned long offset)
-{
- return readl(das_base + offset);
-}
-
-static inline void das_writel(unsigned long value, unsigned long offset)
-{
- writel(value, das_base + offset);
-}
-
-static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct tegra_runtime_data *prtd = runtime->private_data;
- int ret=0;
- int val;
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S16_LE:
- val = I2S_BIT_SIZE_16;
- break;
- case SNDRV_PCM_FORMAT_S24_LE:
- val = I2S_BIT_SIZE_24;
- break;
- case SNDRV_PCM_FORMAT_S32_LE:
- val = I2S_BIT_SIZE_32;
- break;
- default:
- ret =-EINVAL;
- goto err;
- }
-
- i2s_set_bit_size(I2S_IFC, val);
-
- switch (params_rate(params)) {
- case 8000:
- case 32000:
- case 44100:
- case 48000:
- case 88200:
- case 96000:
- val = params_rate(params);
- break;
- default:
- ret = -EINVAL;
- goto err;
- }
-
- i2s_set_channel_bit_count(I2S_IFC, val, clk_get_rate(prtd->i2s_clk));
-
- return 0;
-
-err:
- return ret;
-}
-
-
-static int tegra_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
- unsigned int fmt)
-{
- int val1;
- int val2;
-
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
- val1 = 1;
- break;
- case SND_SOC_DAIFMT_CBM_CFM:
- val1= 0;
- break;
- case SND_SOC_DAIFMT_CBS_CFM:
- case SND_SOC_DAIFMT_CBM_CFS:
- /* Tegra does not support different combinations of
- * master and slave for FSYNC and BCLK */
- default:
- return -EINVAL;
- }
-
- i2s_set_master(I2S_IFC, val1);
-
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- val1 = I2S_BIT_FORMAT_DSP;
- val2 = 0;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- val1 = I2S_BIT_FORMAT_DSP;
- val2 = 1;
- break;
- case SND_SOC_DAIFMT_I2S:
- val1 = I2S_BIT_FORMAT_I2S;
- val2 = 0;
- break;
- case SND_SOC_DAIFMT_RIGHT_J:
- val1 = I2S_BIT_FORMAT_RJM;
- val2 = 0;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- val1 = I2S_BIT_FORMAT_LJM;
- val2 = 0;
- break;
- default:
- return -EINVAL;
- }
-
- i2s_set_bit_format(I2S_IFC,val1);
- i2s_set_left_right_control_polarity(I2S_IFC,val2);
-
- /* Clock inversion */
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_DSP_A:
- case SND_SOC_DAIFMT_DSP_B:
- /* frame inversion not valid for DSP modes */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_NF:
- /* aif1 |= WM8903_AIF_BCLK_INV; */
- break;
- default:
- return -EINVAL;
- }
- break;
- case SND_SOC_DAIFMT_I2S:
- case SND_SOC_DAIFMT_RIGHT_J:
- case SND_SOC_DAIFMT_LEFT_J:
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
- break;
- case SND_SOC_DAIFMT_IB_IF:
- /* aif1 |= WM8903_AIF_BCLK_INV |
- * WM8903_AIF_LRCLK_INV; */
- break;
- case SND_SOC_DAIFMT_IB_NF:
- /* aif1 |= WM8903_AIF_BCLK_INV; */
- break;
- case SND_SOC_DAIFMT_NB_IF:
- /* aif1 |= WM8903_AIF_LRCLK_INV; */
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int tegra_i2s_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
- int clk_id, unsigned int freq, int dir)
-{
- return 0;
-}
-
-static int tegra_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- int ret = 0;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int tegra_i2s_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- return 0;
-}
-
-static void tegra_i2s_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
-}
-
-static int tegra_i2s_probe(struct platform_device *pdev,
- struct snd_soc_dai *dai)
-{
- /* DAC1 -> DAP1, DAC1 master, DAP2 bypass */
- das_writel(0, APB_MISC_DAS_DAP_CTRL_SEL_0);
- das_writel(0, APB_MISC_DAS_DAC_INPUT_DATA_CLK_SEL_0);
- i2s_enable_fifos(I2S_IFC, 0);
- i2s_set_left_right_control_polarity(I2S_IFC, 0); /* default */
- i2s_set_master(I2S_IFC, 1); /* set as master */
- i2s_set_fifo_mode(I2S_IFC, FIFO1, 1); /* FIFO1 is TX */
- i2s_set_fifo_mode(I2S_IFC, FIFO2, 0); /* FIFO2 is RX */
- i2s_set_bit_format(I2S_IFC, I2S_BIT_FORMAT_I2S);
- i2s_set_bit_size(I2S_IFC, I2S_BIT_SIZE_16);
- i2s_set_fifo_format(I2S_IFC, I2S_FIFO_PACKED);
- return 0;
-}
-
-static struct snd_soc_dai_ops tegra_i2s_dai_ops = {
- .startup = tegra_i2s_startup,
- .shutdown = tegra_i2s_shutdown,
- .trigger = tegra_i2s_trigger,
- .hw_params = tegra_i2s_hw_params,
- .set_fmt = tegra_i2s_set_dai_fmt,
- .set_sysclk = tegra_i2s_set_dai_sysclk,
-};
-
-struct snd_soc_dai tegra_i2s_dai = {
- .name = "tegra-i2s",
- .id = 0,
- .probe = tegra_i2s_probe,
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = TEGRA_SAMPLE_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = TEGRA_SAMPLE_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- },
- .ops = &tegra_i2s_dai_ops,
-};
-EXPORT_SYMBOL_GPL(tegra_i2s_dai);
-
-static int tegra_i2s_driver_probe(struct platform_device *dev)
-{
- int ret;
-
- tegra_i2s_dai.dev = &dev->dev;
- tegra_i2s_dai.private_data = NULL;
- ret = snd_soc_register_dai(&tegra_i2s_dai);
- return ret;
-}
-
-
-static int __devexit tegra_i2s_driver_remove(struct platform_device *dev)
-{
- snd_soc_unregister_dai(&tegra_i2s_dai);
- return 0;
-}
-
-static struct platform_driver tegra_i2s_driver = {
- .probe = tegra_i2s_driver_probe,
- .remove = __devexit_p(tegra_i2s_driver_remove),
- .driver = {
- .name = "i2s",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init tegra_i2s_init(void)
-{
- int ret = 0;
-
- ret = platform_driver_register(&tegra_i2s_driver);
- return ret;
-}
-module_init(tegra_i2s_init);
-
-static void __exit tegra_i2s_exit(void)
-{
- platform_driver_unregister(&tegra_i2s_driver);
-}
-module_exit(tegra_i2s_exit);
-
-/* Module information */
-MODULE_DESCRIPTION("Tegra I2S SoC interface");
-MODULE_LICENSE("GPL");
+/* + * tegra_i2s.c -- ALSA Soc Audio Layer + * + * (c) 2010 Nvidia Graphics Pvt. Ltd. + * http://www.nvidia.com + * + * (c) 2006 Wolfson Microelectronics PLC. + * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * (c) 2004-2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks <ben@simtec.co.uk> + * + * 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 "tegra_soc.h" + +static void *das_base = IO_ADDRESS(TEGRA_APB_MISC_BASE); + +static inline unsigned long das_readl(unsigned long offset) +{ + return readl(das_base + offset); +} + +static inline void das_writel(unsigned long value, unsigned long offset) +{ + writel(value, das_base + offset); +} + +static int tegra_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct tegra_runtime_data *prtd = runtime->private_data; + int ret=0; + int val; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + val = I2S_BIT_SIZE_16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + val = I2S_BIT_SIZE_24; + break; + case SNDRV_PCM_FORMAT_S32_LE: + val = I2S_BIT_SIZE_32; + break; + default: + ret =-EINVAL; + goto err; + } + + i2s_set_bit_size(I2S_IFC, val); + + switch (params_rate(params)) { + case 8000: + case 32000: + case 44100: + case 48000: + case 88200: + case 96000: + val = params_rate(params); + break; + default: + ret = -EINVAL; + goto err; + } + + i2s_set_channel_bit_count(I2S_IFC, val, clk_get_rate(prtd->i2s_clk)); + + return 0; + +err: + return ret; +} + + +static int tegra_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, + unsigned int fmt) +{ + int val1; + int val2; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + val1 = 1; + break; + case SND_SOC_DAIFMT_CBM_CFM: + val1= 0; + break; + case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBM_CFS: + /* Tegra does not support different combinations of + * master and slave for FSYNC and BCLK */ + default: + return -EINVAL; + } + + i2s_set_master(I2S_IFC, val1); + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + val1 = I2S_BIT_FORMAT_DSP; + val2 = 0; + break; + case SND_SOC_DAIFMT_DSP_B: + val1 = I2S_BIT_FORMAT_DSP; + val2 = 1; + break; + case SND_SOC_DAIFMT_I2S: + val1 = I2S_BIT_FORMAT_I2S; + val2 = 0; + break; + case SND_SOC_DAIFMT_RIGHT_J: + val1 = I2S_BIT_FORMAT_RJM; + val2 = 0; + break; + case SND_SOC_DAIFMT_LEFT_J: + val1 = I2S_BIT_FORMAT_LJM; + val2 = 0; + break; + default: + return -EINVAL; + } + + i2s_set_bit_format(I2S_IFC,val1); + i2s_set_left_right_control_polarity(I2S_IFC,val2); + + /* Clock inversion */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + case SND_SOC_DAIFMT_DSP_B: + /* frame inversion not valid for DSP modes */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + /* aif1 |= WM8903_AIF_BCLK_INV; */ + break; + default: + return -EINVAL; + } + break; + case SND_SOC_DAIFMT_I2S: + case SND_SOC_DAIFMT_RIGHT_J: + case SND_SOC_DAIFMT_LEFT_J: + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + /* aif1 |= WM8903_AIF_BCLK_INV | + * WM8903_AIF_LRCLK_INV; */ + break; + case SND_SOC_DAIFMT_IB_NF: + /* aif1 |= WM8903_AIF_BCLK_INV; */ + break; + case SND_SOC_DAIFMT_NB_IF: + /* aif1 |= WM8903_AIF_LRCLK_INV; */ + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + return 0; +} + +static int tegra_i2s_set_dai_sysclk(struct snd_soc_dai *cpu_dai, + int clk_id, unsigned int freq, int dir) +{ + return 0; +} + +static int tegra_i2s_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + int ret = 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static int tegra_i2s_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + return 0; +} + +static void tegra_i2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ +} + +static int tegra_i2s_probe(struct platform_device *pdev, + struct snd_soc_dai *dai) +{ + /* DAC1 -> DAP1, DAC1 master, DAP2 bypass */ + das_writel(0, APB_MISC_DAS_DAP_CTRL_SEL_0); + das_writel(0, APB_MISC_DAS_DAC_INPUT_DATA_CLK_SEL_0); + i2s_enable_fifos(I2S_IFC, 0); + i2s_set_left_right_control_polarity(I2S_IFC, 0); /* default */ + i2s_set_master(I2S_IFC, 1); /* set as master */ + i2s_set_fifo_mode(I2S_IFC, FIFO1, 1); /* FIFO1 is TX */ + i2s_set_fifo_mode(I2S_IFC, FIFO2, 0); /* FIFO2 is RX */ + i2s_set_bit_format(I2S_IFC, I2S_BIT_FORMAT_I2S); + i2s_set_bit_size(I2S_IFC, I2S_BIT_SIZE_16); + i2s_set_fifo_format(I2S_IFC, I2S_FIFO_PACKED); + return 0; +} + +static struct snd_soc_dai_ops tegra_i2s_dai_ops = { + .startup = tegra_i2s_startup, + .shutdown = tegra_i2s_shutdown, + .trigger = tegra_i2s_trigger, + .hw_params = tegra_i2s_hw_params, + .set_fmt = tegra_i2s_set_dai_fmt, + .set_sysclk = tegra_i2s_set_dai_sysclk, +}; + +struct snd_soc_dai tegra_i2s_dai = { + .name = "tegra-i2s", + .id = 0, + .probe = tegra_i2s_probe, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = TEGRA_SAMPLE_RATES, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = TEGRA_SAMPLE_RATES, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = &tegra_i2s_dai_ops, +}; +EXPORT_SYMBOL_GPL(tegra_i2s_dai); + +static int tegra_i2s_driver_probe(struct platform_device *dev) +{ + int ret; + + tegra_i2s_dai.dev = &dev->dev; + tegra_i2s_dai.private_data = NULL; + ret = snd_soc_register_dai(&tegra_i2s_dai); + return ret; +} + + +static int __devexit tegra_i2s_driver_remove(struct platform_device *dev) +{ + snd_soc_unregister_dai(&tegra_i2s_dai); + return 0; +} + +static struct platform_driver tegra_i2s_driver = { + .probe = tegra_i2s_driver_probe, + .remove = __devexit_p(tegra_i2s_driver_remove), + .driver = { + .name = "i2s", + .owner = THIS_MODULE, + }, +}; + +static int __init tegra_i2s_init(void) +{ + int ret = 0; + + ret = platform_driver_register(&tegra_i2s_driver); + return ret; +} +module_init(tegra_i2s_init); + +static void __exit tegra_i2s_exit(void) +{ + platform_driver_unregister(&tegra_i2s_driver); +} +module_exit(tegra_i2s_exit); + +/* Module information */ +MODULE_DESCRIPTION("Tegra I2S SoC interface"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/tegra/tegra_soc.c b/sound/soc/tegra/tegra_soc.c index 306a31138733..5dbf3c8eb478 100644 --- a/sound/soc/tegra/tegra_soc.c +++ b/sound/soc/tegra/tegra_soc.c @@ -1,41 +1,41 @@ -/*
- * tegra_soc.c -- SoC audio for tegra
- *
- * (c) 2010 Nvidia Graphics Pvt. Ltd.
- * http://www.nvidia.com
- *
- * Copyright 2007 Wolfson Microelectronics PLC.
- * Author: Graeme Gregory
- * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
- *
- * 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 "../codecs/wm8903.h"
-#include "tegra_soc.h"
-#include <mach/audio.h>
-
-static struct platform_device *tegra_snd_device;
-static int tegra_jack_func;
-static int tegra_spk_func;
-
-#define TEGRA_HP 0
-#define TEGRA_MIC 1
-#define TEGRA_LINE 2
-#define TEGRA_HEADSET 3
-#define TEGRA_HP_OFF 4
-#define TEGRA_SPK_ON 0
-#define TEGRA_SPK_OFF 1
-
-/* codec register values */
+/* + * tegra_soc.c -- SoC audio for tegra + * + * (c) 2010 Nvidia Graphics Pvt. Ltd. + * http://www.nvidia.com + * + * Copyright 2007 Wolfson Microelectronics PLC. + * Author: Graeme Gregory + * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * 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 "../codecs/wm8903.h" +#include "tegra_soc.h" +#include <mach/audio.h> + +static struct platform_device *tegra_snd_device; +static int tegra_jack_func; +static int tegra_spk_func; + +#define TEGRA_HP 0 +#define TEGRA_MIC 1 +#define TEGRA_LINE 2 +#define TEGRA_HEADSET 3 +#define TEGRA_HP_OFF 4 +#define TEGRA_SPK_ON 0 +#define TEGRA_SPK_OFF 1 + +/* codec register values */ #define B07_INEMUTE 7 #define B06_VOL_M3DB 6 #define B00_IN_VOL 0 -#define B00_INR_ENA 0
+#define B00_INR_ENA 0 #define B01_INL_ENA 1 #define R06_MICBIAS_CTRL_0 6 #define B07_MICDET_HYST_ENA 7 @@ -51,103 +51,103 @@ static int tegra_spk_func; #define B06_IN_CM_ENA 6 #define B04_IP_SEL_N 4 #define B02_IP_SEL_P 2 -#define B00_MODE 0
-#define B06_AIF_ADCL 7
+#define B00_MODE 0 +#define B06_AIF_ADCL 7 #define B06_AIF_ADCR 6 #define B05_ADC_HPF_CUT 5 #define B04_ADC_HPF_ENA 4 #define B01_ADCL_DATINV 1 -#define B00_ADCR_DATINV 0
-#define R20_SIDETONE_CTRL 32
+#define B00_ADCR_DATINV 0 +#define R20_SIDETONE_CTRL 32 #define R29_DRC_1 41 -#define SET_REG_VAL(r,m,l,v) (((r)&(~((m)<<(l))))|(((v)&(m))<<(l)))
-
-
-static void tegra_ext_control(struct snd_soc_codec *codec)
-{
- /* set up jack connection */
- switch (tegra_jack_func) {
- case TEGRA_HP:
- /* set = unmute headphone */
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
- snd_soc_dapm_enable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
- break;
- case TEGRA_MIC:
- /* reset = mute headphone */
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
- break;
- case TEGRA_LINE:
- snd_soc_dapm_disable_pin(codec, "Mic Jack");
- snd_soc_dapm_enable_pin(codec, "Line Jack");
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_disable_pin(codec, "Headset Jack");
- break;
- case TEGRA_HEADSET:
- snd_soc_dapm_enable_pin(codec, "Mic Jack");
- snd_soc_dapm_disable_pin(codec, "Line Jack");
- snd_soc_dapm_disable_pin(codec, "Headphone Jack");
- snd_soc_dapm_enable_pin(codec, "Headset Jack");
- break;
- }
-
- if (tegra_spk_func == TEGRA_SPK_ON) {
- snd_soc_dapm_enable_pin(codec, "Ext Spk");
- } else {
- snd_soc_dapm_disable_pin(codec, "Ext Spk");
- }
- /* signal a DAPM event */
- snd_soc_dapm_sync(codec);
-}
-
-static int tegra_hifi_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;
- struct snd_soc_codec *codec = codec_dai->codec;
+#define SET_REG_VAL(r,m,l,v) (((r)&(~((m)<<(l))))|(((v)&(m))<<(l))) + + +static void tegra_ext_control(struct snd_soc_codec *codec) +{ + /* set up jack connection */ + switch (tegra_jack_func) { + case TEGRA_HP: + /* set = unmute headphone */ + snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_disable_pin(codec, "Line Jack"); + snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(codec, "Headset Jack"); + break; + case TEGRA_MIC: + /* reset = mute headphone */ + snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_disable_pin(codec, "Line Jack"); + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(codec, "Headset Jack"); + break; + case TEGRA_LINE: + snd_soc_dapm_disable_pin(codec, "Mic Jack"); + snd_soc_dapm_enable_pin(codec, "Line Jack"); + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(codec, "Headset Jack"); + break; + case TEGRA_HEADSET: + snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_disable_pin(codec, "Line Jack"); + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(codec, "Headset Jack"); + break; + } + + if (tegra_spk_func == TEGRA_SPK_ON) { + snd_soc_dapm_enable_pin(codec, "Ext Spk"); + } else { + snd_soc_dapm_disable_pin(codec, "Ext Spk"); + } + /* signal a DAPM event */ + snd_soc_dapm_sync(codec); +} + +static int tegra_hifi_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; + struct snd_soc_codec *codec = codec_dai->codec; int CtrlReg = 0; int VolumeCtrlReg = 0; int SidetoneCtrlReg = 0; - int SideToneAtenuation = 0;
-
- err = snd_soc_dai_set_fmt(codec_dai,
- SND_SOC_DAIFMT_I2S | \
- SND_SOC_DAIFMT_NB_NF | \
- SND_SOC_DAIFMT_CBS_CFS);
- if (err < 0) {
- printk(KERN_ERR "codec_dai fmt not set \n");
- return err;
- }
-
- err = snd_soc_dai_set_fmt(cpu_dai,
- SND_SOC_DAIFMT_I2S | \
- SND_SOC_DAIFMT_NB_NF | \
- SND_SOC_DAIFMT_CBS_CFS);
- if (err < 0) {
- printk(KERN_ERR "cpu_dai fmt not set \n");
- return err;
- }
- err = snd_soc_dai_set_sysclk(codec_dai, 0, I2S_CLK, SND_SOC_CLOCK_IN);
-
- if (err<0) {
- printk(KERN_ERR "codec_dai clock not set\n");
- return err;
- }
- err = snd_soc_dai_set_sysclk(cpu_dai, 0, I2S_CLK, SND_SOC_CLOCK_IN);
-
- if (err<0) {
- printk(KERN_ERR "cpu_dai clock not set\n");
- return err;
- }
-
- if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) {
+ int SideToneAtenuation = 0; + + err = snd_soc_dai_set_fmt(codec_dai, + SND_SOC_DAIFMT_I2S | \ + SND_SOC_DAIFMT_NB_NF | \ + SND_SOC_DAIFMT_CBS_CFS); + if (err < 0) { + printk(KERN_ERR "codec_dai fmt not set \n"); + return err; + } + + err = snd_soc_dai_set_fmt(cpu_dai, + SND_SOC_DAIFMT_I2S | \ + SND_SOC_DAIFMT_NB_NF | \ + SND_SOC_DAIFMT_CBS_CFS); + if (err < 0) { + printk(KERN_ERR "cpu_dai fmt not set \n"); + return err; + } + err = snd_soc_dai_set_sysclk(codec_dai, 0, I2S_CLK, SND_SOC_CLOCK_IN); + + if (err<0) { + printk(KERN_ERR "codec_dai clock not set\n"); + return err; + } + err = snd_soc_dai_set_sysclk(cpu_dai, 0, I2S_CLK, SND_SOC_CLOCK_IN); + + if (err<0) { + printk(KERN_ERR "cpu_dai clock not set\n"); + return err; + } + + if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) { snd_soc_write(codec, WM8903_ANALOGUE_LEFT_INPUT_0, 0X7); snd_soc_write(codec, WM8903_ANALOGUE_RIGHT_INPUT_0, 0X7); // Mic Bias enable @@ -159,16 +159,16 @@ static int tegra_hifi_hw_params(struct snd_pcm_substream *substream, snd_soc_write(codec, WM8903_DRC_0, CtrlReg); // Single Ended Mic CtrlReg = (0x0<<B06_IN_CM_ENA) | - (0x0<<B00_MODE) | (0x0<<B04_IP_SEL_N)
+ (0x0<<B00_MODE) | (0x0<<B04_IP_SEL_N) | (0x1<<B02_IP_SEL_P); VolumeCtrlReg = (0x5 << B00_IN_VOL); // Mic Setting snd_soc_write(codec, WM8903_ANALOGUE_LEFT_INPUT_1, CtrlReg); snd_soc_write(codec, WM8903_ANALOGUE_RIGHT_INPUT_1, CtrlReg); // voulme for single ended mic - snd_soc_write(codec, WM8903_ANALOGUE_LEFT_INPUT_0,
+ snd_soc_write(codec, WM8903_ANALOGUE_LEFT_INPUT_0, VolumeCtrlReg); - snd_soc_write(codec, WM8903_ANALOGUE_RIGHT_INPUT_0,
+ snd_soc_write(codec, WM8903_ANALOGUE_RIGHT_INPUT_0, VolumeCtrlReg); // replicate mic setting on both channels CtrlReg = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_0); @@ -191,194 +191,194 @@ static int tegra_hifi_hw_params(struct snd_pcm_substream *substream, // Enable Sidetone SidetoneCtrlReg = (0x1<<2) | (0x2<<0); SideToneAtenuation = 12 ; // sidetone 0 db - SidetoneCtrlReg |= (SideToneAtenuation<<8)
+ SidetoneCtrlReg |= (SideToneAtenuation<<8) | (SideToneAtenuation<<4); - snd_soc_write(codec, R20_SIDETONE_CTRL, SidetoneCtrlReg);
- CtrlReg = snd_soc_read(codec, R29_DRC_1);
- CtrlReg |= 0x3; //mic volume 18 db
- snd_soc_write(codec, R29_DRC_1, CtrlReg);
- }
-
- return 0;
-}
-
-static struct snd_soc_ops tegra_hifi_ops = {
- .hw_params = tegra_hifi_hw_params,
-};
-
-
-static int tegra_get_jack(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = tegra_jack_func;
- return 0;
-}
-
-static int tegra_set_jack(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-
- if (tegra_jack_func == ucontrol->value.integer.value[0])
- return 0;
-
- tegra_jack_func = ucontrol->value.integer.value[0];
- tegra_ext_control(codec);
- return 1;
-}
-
-static int tegra_get_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.integer.value[0] = tegra_spk_func;
- return 0;
-}
-
-static int tegra_set_spk(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-
-
- if (tegra_spk_func == ucontrol->value.integer.value[0])
- return 0;
-
- tegra_spk_func = ucontrol->value.integer.value[0];
- tegra_ext_control(codec);
- return 1;
-}
-
-/*tegra machine dapm widgets */
-static const struct snd_soc_dapm_widget wm8903_dapm_widgets[] = {
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_MIC("Mic Jack", NULL),
- SND_SOC_DAPM_SPK("Ext Spk", NULL),
- SND_SOC_DAPM_LINE("Line Jack", NULL),
- SND_SOC_DAPM_HP("Headset Jack", NULL),
-};
-
-/* Tegra machine audio map (connections to the codec pins) */
-static const struct snd_soc_dapm_route audio_map[] = {
-
- /* headset Jack - in = micin, out = LHPOUT*/
- {"Headset Jack", NULL, "HPOUTL"},
-
- /* headphone connected to LHPOUT1, RHPOUT1 */
- {"Headphone Jack", NULL, "HPOUTR"}, {"Headphone Jack", NULL, "HPOUTL"},
-
- /* speaker connected to LOUT, ROUT */
- {"Ext Spk", NULL, "LINEOUTR"}, {"Ext Spk", NULL, "LINEOUTL"},
-
- /* mic is connected to MICIN (via right channel of headphone jack) */
- {"IN1L", NULL, "Mic Jack"},
-
- /* Same as the above but no mic bias for line signals */
- {"IN2L", NULL, "Line Jack"},
-};
-
-static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset",
- "Off"
- };
-static const char *spk_function[] = {"On", "Off"};
-static const struct soc_enum tegra_enum[] = {
- SOC_ENUM_SINGLE_EXT(5, jack_function),
- SOC_ENUM_SINGLE_EXT(2, spk_function),
-};
-
-static const struct snd_kcontrol_new wm8903_tegra_controls[] = {
- SOC_ENUM_EXT("Jack Function", tegra_enum[0], tegra_get_jack,
- tegra_set_jack),
- SOC_ENUM_EXT("Speaker Function", tegra_enum[1], tegra_get_spk,
- tegra_set_spk),
-};
-
-
-static int tegra_codec_init(struct snd_soc_codec *codec)
-{
- int err;
-
- /* Add tegra specific controls */
- err = snd_soc_add_controls(codec, wm8903_tegra_controls,
- ARRAY_SIZE(wm8903_tegra_controls));
- if (err < 0)
- return err;
-
- /* Add tegra specific widgets */
- snd_soc_dapm_new_controls(codec, wm8903_dapm_widgets,
- ARRAY_SIZE(wm8903_dapm_widgets));
-
- /* Set up tegra specific audio path audio_map */
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
-
- /* Default to HP output */
- tegra_jack_func = TEGRA_HP;
- tegra_spk_func = TEGRA_SPK_ON;
- tegra_ext_control(codec);
-
- snd_soc_dapm_sync(codec);
-
- return 0;
-}
-
-extern struct snd_soc_dai tegra_i2s_dai;
-extern struct snd_soc_platform tegra_soc_platform;
-
-static struct snd_soc_dai_link tegra_soc_dai = {
- .name = "WM8903",
- .stream_name = "WM8903 HiFi",
- .cpu_dai = &tegra_i2s_dai,
- .codec_dai = &wm8903_dai,
- .init = tegra_codec_init,
- .ops = &tegra_hifi_ops,
-};
-
-static struct snd_soc_card tegra_snd_soc = {
- .name = "tegra",
- .platform = &tegra_soc_platform,
- .dai_link = &tegra_soc_dai,
- .num_links = 1,
-};
-
-struct tegra_setup_data {
- int i2c_bus;
- unsigned short i2c_address;
-};
-
-static struct snd_soc_device tegra_snd_devdata = {
- .card = &tegra_snd_soc,
- .codec_dev = &soc_codec_dev_wm8903,
-};
-
-static int __init tegra_init(void)
-{
- int ret;
- struct tegra_setup_data tegra_setup;
-
- tegra_snd_device = platform_device_alloc("soc-audio", -1);
- if (!tegra_snd_device)
- return -ENOMEM;
-
- memset(&tegra_setup,0,sizeof(struct tegra_setup_data));
- platform_set_drvdata(tegra_snd_device, &tegra_snd_devdata);
- tegra_snd_devdata.dev = &tegra_snd_device->dev;
- ret = platform_device_add(tegra_snd_device);
- if (ret) {
- printk(KERN_ERR "audio device could not be added \n");
- platform_device_put(tegra_snd_device);
- return ret;
- }
-
- return ret;
-}
-
-static void __exit tegra_exit(void)
-{
- platform_device_unregister(tegra_snd_device);
-}
-
-module_init(tegra_init);
-module_exit(tegra_exit);
-
-/* Module information */
-MODULE_DESCRIPTION("Tegra ALSA SoC");
-MODULE_LICENSE("GPL");
+ snd_soc_write(codec, R20_SIDETONE_CTRL, SidetoneCtrlReg); + CtrlReg = snd_soc_read(codec, R29_DRC_1); + CtrlReg |= 0x3; //mic volume 18 db + snd_soc_write(codec, R29_DRC_1, CtrlReg); + } + + return 0; +} + +static struct snd_soc_ops tegra_hifi_ops = { + .hw_params = tegra_hifi_hw_params, +}; + + +static int tegra_get_jack(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = tegra_jack_func; + return 0; +} + +static int tegra_set_jack(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + + if (tegra_jack_func == ucontrol->value.integer.value[0]) + return 0; + + tegra_jack_func = ucontrol->value.integer.value[0]; + tegra_ext_control(codec); + return 1; +} + +static int tegra_get_spk(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = tegra_spk_func; + return 0; +} + +static int tegra_set_spk(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + + + if (tegra_spk_func == ucontrol->value.integer.value[0]) + return 0; + + tegra_spk_func = ucontrol->value.integer.value[0]; + tegra_ext_control(codec); + return 1; +} + +/*tegra machine dapm widgets */ +static const struct snd_soc_dapm_widget wm8903_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), + SND_SOC_DAPM_SPK("Ext Spk", NULL), + SND_SOC_DAPM_LINE("Line Jack", NULL), + SND_SOC_DAPM_HP("Headset Jack", NULL), +}; + +/* Tegra machine audio map (connections to the codec pins) */ +static const struct snd_soc_dapm_route audio_map[] = { + + /* headset Jack - in = micin, out = LHPOUT*/ + {"Headset Jack", NULL, "HPOUTL"}, + + /* headphone connected to LHPOUT1, RHPOUT1 */ + {"Headphone Jack", NULL, "HPOUTR"}, {"Headphone Jack", NULL, "HPOUTL"}, + + /* speaker connected to LOUT, ROUT */ + {"Ext Spk", NULL, "LINEOUTR"}, {"Ext Spk", NULL, "LINEOUTL"}, + + /* mic is connected to MICIN (via right channel of headphone jack) */ + {"IN1L", NULL, "Mic Jack"}, + + /* Same as the above but no mic bias for line signals */ + {"IN2L", NULL, "Line Jack"}, +}; + +static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset", + "Off" + }; +static const char *spk_function[] = {"On", "Off"}; +static const struct soc_enum tegra_enum[] = { + SOC_ENUM_SINGLE_EXT(5, jack_function), + SOC_ENUM_SINGLE_EXT(2, spk_function), +}; + +static const struct snd_kcontrol_new wm8903_tegra_controls[] = { + SOC_ENUM_EXT("Jack Function", tegra_enum[0], tegra_get_jack, + tegra_set_jack), + SOC_ENUM_EXT("Speaker Function", tegra_enum[1], tegra_get_spk, + tegra_set_spk), +}; + + +static int tegra_codec_init(struct snd_soc_codec *codec) +{ + int err; + + /* Add tegra specific controls */ + err = snd_soc_add_controls(codec, wm8903_tegra_controls, + ARRAY_SIZE(wm8903_tegra_controls)); + if (err < 0) + return err; + + /* Add tegra specific widgets */ + snd_soc_dapm_new_controls(codec, wm8903_dapm_widgets, + ARRAY_SIZE(wm8903_dapm_widgets)); + + /* Set up tegra specific audio path audio_map */ + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + + /* Default to HP output */ + tegra_jack_func = TEGRA_HP; + tegra_spk_func = TEGRA_SPK_ON; + tegra_ext_control(codec); + + snd_soc_dapm_sync(codec); + + return 0; +} + +extern struct snd_soc_dai tegra_i2s_dai; +extern struct snd_soc_platform tegra_soc_platform; + +static struct snd_soc_dai_link tegra_soc_dai = { + .name = "WM8903", + .stream_name = "WM8903 HiFi", + .cpu_dai = &tegra_i2s_dai, + .codec_dai = &wm8903_dai, + .init = tegra_codec_init, + .ops = &tegra_hifi_ops, +}; + +static struct snd_soc_card tegra_snd_soc = { + .name = "tegra", + .platform = &tegra_soc_platform, + .dai_link = &tegra_soc_dai, + .num_links = 1, +}; + +struct tegra_setup_data { + int i2c_bus; + unsigned short i2c_address; +}; + +static struct snd_soc_device tegra_snd_devdata = { + .card = &tegra_snd_soc, + .codec_dev = &soc_codec_dev_wm8903, +}; + +static int __init tegra_init(void) +{ + int ret; + struct tegra_setup_data tegra_setup; + + tegra_snd_device = platform_device_alloc("soc-audio", -1); + if (!tegra_snd_device) + return -ENOMEM; + + memset(&tegra_setup,0,sizeof(struct tegra_setup_data)); + platform_set_drvdata(tegra_snd_device, &tegra_snd_devdata); + tegra_snd_devdata.dev = &tegra_snd_device->dev; + ret = platform_device_add(tegra_snd_device); + if (ret) { + printk(KERN_ERR "audio device could not be added \n"); + platform_device_put(tegra_snd_device); + return ret; + } + + return ret; +} + +static void __exit tegra_exit(void) +{ + platform_device_unregister(tegra_snd_device); +} + +module_init(tegra_init); +module_exit(tegra_exit); + +/* Module information */ +MODULE_DESCRIPTION("Tegra ALSA SoC"); +MODULE_LICENSE("GPL"); |