diff options
author | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
---|---|---|
committer | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
commit | 871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch) | |
tree | 8718f573808810c2a1e8cb8fb6ac469093ca2784 /ANDROID_3.4.5/sound/soc/wmt | |
parent | 9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff) | |
download | FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2 FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip |
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized.
Changes are basically to make it look like kernel structure.
Diffstat (limited to 'ANDROID_3.4.5/sound/soc/wmt')
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/Kconfig | 65 | ||||
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/Makefile | 12 | ||||
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/wmt-i2s.c | 1105 | ||||
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.c | 419 | ||||
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.h | 122 | ||||
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.c | 597 | ||||
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.h | 35 | ||||
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/wmt-pcm.c | 767 | ||||
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/wmt-pcm.h | 46 | ||||
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/wmt-soc.c | 321 | ||||
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/wmt-soc.h | 53 | ||||
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.c | 259 | ||||
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.h | 55 | ||||
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.c | 101 | ||||
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.h | 33 | ||||
-rwxr-xr-x | ANDROID_3.4.5/sound/soc/wmt/wmt_wm8994.c | 304 |
16 files changed, 0 insertions, 4294 deletions
diff --git a/ANDROID_3.4.5/sound/soc/wmt/Kconfig b/ANDROID_3.4.5/sound/soc/wmt/Kconfig deleted file mode 100755 index 344ec73d..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/Kconfig +++ /dev/null @@ -1,65 +0,0 @@ -config SND_WMT_SOC - bool "SoC Audio for the WMT chip" - depends on ARCH_WMT && SND && SND_SOC - help - Say Y or M if you want to add support for codecs attached to - the WMT AC97, I2S interface. You will also need - to select the audio interfaces to support below. - -# -# WMT ALSA I2S driver -# -config SND_WMT_SOC_I2S - bool "SoC I2S Audio support for WMT" - depends on SND_WMT_SOC - ---help--- - Say Y or M if you want to add support for codecs attached to - the WMT I2S interface. - -config SND_WMT_SOC_PDM - bool "SoC PDM Audio Interface support for WMT" - depends on SND_WMT_SOC - ---help--- - Say Y or M if you want to add support for codecs attached to - the WMT PDM interface. - -config I2S_HW_DAC - bool "HW_DAC" - depends on SND_WMT_SOC_I2S - select SND_SOC_HWDAC - ---help--- - Say Y here if you want to use HW DAC. - -config I2S_CODEC_VT1602 - bool "VT1602" - depends on SND_WMT_SOC_I2S - select SND_SOC_VT1602 - ---help--- - Say Y here if you want to use VT1602 as the I2S Codec. - -config I2S_CODEC_WM8900 - bool "WM8900" - depends on SND_WMT_SOC_I2S - select SND_SOC_WM8900 - ---help--- - Say Y here if you want to use WM8900 as the I2S Codec. - -config I2S_CODEC_WM8994 - bool "WM8994" - depends on SND_WMT_SOC_I2S - select SND_SOC_WM8994 - ---help--- - Say Y here if you want to use WM8994 as the I2S Codec. - -config I2S_CODEC_VT1603 - bool "VT1603" - depends on SND_WMT_SOC_I2S - select SND_SOC_VT1603 - ---help--- - Say Y here if you want to use VT1603 as the I2S Codec. - -config ECHO_CANCELLATION_FM34 - tristate "FM34" - select SND_SOC_WMT_FM34 - ---help--- - Say Y here if you want to use fm34 to echo cancallation. diff --git a/ANDROID_3.4.5/sound/soc/wmt/Makefile b/ANDROID_3.4.5/sound/soc/wmt/Makefile deleted file mode 100755 index bf4a07ef..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -## Makefile for ALSA WMT -# -# -# WMT SOC Support -snd-soc-wmt-i2s-objs := wmt-i2s.o wmt_swmixer.o -snd-soc-wmt-objs := wmt-soc.o wmt-pcm.o wmt_wm8994.o wmt_hwdep.o - -snd-soc-wmt-pdm-objs := wmt-pcm-controller.o wmt-pcm-dma.o -obj-$(CONFIG_SND_WMT_SOC_I2S) += snd-soc-wmt-i2s.o -obj-$(CONFIG_SND_WMT_SOC) += snd-soc-wmt.o -obj-$(CONFIG_SND_WMT_SOC_PDM) += snd-soc-wmt-pdm.o diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-i2s.c b/ANDROID_3.4.5/sound/soc/wmt/wmt-i2s.c deleted file mode 100755 index 643d25e2..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/wmt-i2s.c +++ /dev/null @@ -1,1105 +0,0 @@ -/*++ - * linux/sound/soc/wmt/wmt-i2s.c - * WonderMedia I2S audio driver for ALSA - * - * Copyright c 2010 WonderMedia Technologies, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * WonderMedia Technologies, Inc. - * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C ---*/ - - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/interrupt.h> -#include <asm/irq.h> -#include <linux/delay.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/initval.h> -#include <sound/soc.h> - -#include <linux/gpio.h> -#include <mach/wmt_iomux.h> -#include <linux/suspend.h> - -#include <mach/hardware.h> -#include <asm/dma.h> -#include "wmt-soc.h" -#include "wmt-pcm.h" - -#define NULL_DMA ((dmach_t)(-1)) -#define AUD_SPDIF_ENABLE 1 - -static int wmt_i2s_output = 0; //hdmi enable or not 2013-9-3 //maybe can remove it 2013-10-24 -static int wmt_codec_wm8994 = 0; //env set 2013-9-3 - -static int gpio_pa = -1; -static int gpio_active = 0; -extern int wmt_gpio_setpull(unsigned int gpio, enum wmt_gpio_pulltype pull); -/* - * Debug - */ -#define AUDIO_NAME "WMT_I2S" -//#define WMT_I2S_DEBUG 1 -//#define WMT_I2S_DEBUG_DETAIL 1 - -#ifdef WMT_I2S_DEBUG -#define DPRINTK(format, arg...) \ - printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg) -#else -#define DPRINTK(format, arg...) do {} while (0) -#endif - -#ifdef WMT_I2S_DEBUG_DETAIL -#define DBG_DETAIL(format, arg...) \ - printk(KERN_INFO AUDIO_NAME ": [%s]" format "\n" , __FUNCTION__, ## arg) -#else -#define DBG_DETAIL(format, arg...) do {} while (0) -#endif - -#define err(format, arg...) \ - printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg) -#define info(format, arg...) \ - printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg) -#define warn(format, arg...) \ - printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg) - -struct wmt_i2s_asoc_data { - int stream_id; - unsigned int bus_id; - struct i2s_s i2s; - /* - * Flags indicating is the bus already activated and configured by - * another substream - */ - unsigned char HDMI_and_DAC0; //new env set to determine - unsigned char HDMI_aud_enable; //same with global wmt_i2s_output - - int active; - int configured; - unsigned char CH_SEL_NUM; - unsigned char HDMI_SPDIF_STATE; - /*struct timer_list delay_timer;*/ - struct audio_stream_a s[2]; -}; -static struct timer_list pa_timer; - -static int audio_interface_mode = 0;//add 2014-6-24 i2s left right - -static int wmt_pdm_module_enable = 0; -extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen); - -#define to_i2s_data(priv) container_of((priv), struct wmt_i2s_asoc_data, bus_id) -#define SNDRV_PCM_STREAM_ALL 2 - -static void i2s_init(int mode); -static void i2s_exit(void); - -#ifdef CONFIG_FB_WMT -extern int vpp_set_audio(int format, int sample_rate, int channel); -#endif - - -static struct wmt_i2s_asoc_data i2s_data[NUM_LINKS] = { - { - .bus_id = 0, //?? 2 SNDRV_PCM_STREAM_ALL - .i2s = { - /* interrupt counters */ - {0, 0, 0, 0, 0, 0, 0, 0}, - /* irq number*/ - 0, - /* reference counter */ - 0, - /* channels */ - 0, - /* format */ - 0, - /* fragment size */ - 0, - /* sample rate */ - 0, - i2s_init, - i2s_exit, - }, - .s = { - { - .id = "WMT I2S out", - .stream_id = SNDRV_PCM_STREAM_PLAYBACK, - .dmach = NULL_DMA, - .dma_dev = AHB1_AUD_DMA_REQ_1, - /*.dma_cfg = dma_device_cfg_table[I2S_TX_DMA_REQ],*/ - }, - { - .id = "WMT I2S in", - .stream_id = SNDRV_PCM_STREAM_CAPTURE, - .dmach = NULL_DMA, - .dma_dev = AHB1_AUD_DMA_REQ_0, - /*.dma_cfg = dma_device_cfg_table[I2S_RX_DMA_REQ],*/ - }, - }, - .HDMI_aud_enable = 0, - .HDMI_and_DAC0 = 0, - .CH_SEL_NUM = 2, - .HDMI_SPDIF_STATE = 6,//hdmi spdif play at sametime - }, -}; - - -/* for HDMI Audio status */ -int hd_audio_flag = 0; - - - -#ifdef CONFIG_WMT_I2S_INT -/* wmt_i2s_interrupt() - * - * It's only interrupt counter now, might be useful to - * debug or benchmark. - */ -static irqreturn_t -wmt_i2s_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - DBG_DETAIL(); - - return IRQ_HANDLED; -} -#endif - -#if 0 -static void delay_timer_handler(unsigned long data) -{ - DBG_DETAIL(); -} -#endif - -static void pa_timer_handler(unsigned long data) -{ - printk("%s\n", __func__); - if (gpio_pa >= 0) - { - - gpio_direction_output(gpio_pa, gpio_active); - } -} - -void wmt_i2s_ch_config(void) -{ - /* CH_SEL_NUM = 0, mesns output L to SPDIF&DAC's L and R - 1, mesns output R to SPDIF&DAC's L and R - 2, means normal stereo output to SPDIF&DAC */ - switch (i2s_data->CH_SEL_NUM) { - case 0: - ASMPFCHCFG0_VAL = 0x10100000; - ASMPF2HDACHCFG_VAL = 0x76543200; - break; - case 1: - ASMPFCHCFG0_VAL = 0x10101111; - ASMPF2HDACHCFG_VAL = 0x76543211; - break; - case 2: - ASMPFCHCFG0_VAL = 0x10101010; - ASMPF2HDACHCFG_VAL = 0x76543210; - break; - } - - if (i2s_data->i2s.channels == 0x01) { - ASMPFCHCFG0_VAL = 0x10100000; - ASMPF2HDACHCFG_VAL = 0x76543200; - } - - if (i2s_data->HDMI_aud_enable) { - /* disable DAC#0, if HDMI Audio is enabled */ - ASMPFCHCFG0_VAL &= 0xFFFF00FF; - ASMPFCHCFG0_VAL |= 0x00009800; - } - - /* HDMI_SPDIF_STATE = 3, means disable HDMI&SPDIF - 4, means enable HDMI only - 5, means enable SPDIF only - 6, means enable HDMI&SPDIF as normal */ - switch (i2s_data->HDMI_SPDIF_STATE) { - case 3: - ASMPFCHCFG0_VAL &= 0xFFFFFF00; - ASMPFCHCFG0_VAL |= 0x00000098; - ASMPF2HDACHCFG_VAL &= 0xFFFFFF00; - ASMPF2HDACHCFG_VAL |= 0x00000076; - break; - case 4: - ASMPFCHCFG0_VAL &= 0xFFFFFF00; - ASMPFCHCFG0_VAL |= 0x00000098; - break; - case 5: - ASMPF2HDACHCFG_VAL &= 0xFFFFFF00; - ASMPF2HDACHCFG_VAL |= 0x00000076; - break; - } -} - - -void wmt_i2s_dac0_ctrl(int HDMI_audio_enable) -{ - /* check if output to HDMI audio and DAC0 at same time */ - if (i2s_data->HDMI_and_DAC0) - return; - - if (HDMI_audio_enable) { - i2s_data->HDMI_aud_enable = 1; - info("HDMI Audio is enabled, disable dac0 of I2S"); - } - else { - i2s_data->HDMI_aud_enable = 0; - info("HDMI Audio is disabled, enable dac0 of I2S"); - } - - wmt_i2s_ch_config(); - - info("CHCFG0=0x%x, HDACHCFG=0x%x", ASMPFCHCFG0_VAL, ASMPF2HDACHCFG_VAL); -} -EXPORT_SYMBOL(wmt_i2s_dac0_ctrl); -void wmt_i2s_ch_sel(int ch_sel_num) -{ - if (ch_sel_num < 3) - i2s_data->CH_SEL_NUM = ch_sel_num; - else - i2s_data->HDMI_SPDIF_STATE = ch_sel_num; - - wmt_i2s_ch_config(); - - - info("SEL: CHCFG0=0x%x, HDACHCFG=0x%x", ASMPFCHCFG0_VAL, ASMPF2HDACHCFG_VAL); -} -EXPORT_SYMBOL(wmt_i2s_ch_sel); - -static void i2s_disable(void) -{ - DBG_DETAIL(); - - DACCFG_VAL &= ~DACITF_ENABLE; - ASMPFCFG_VAL &=~ASMPF_ENABLE; - HDACKGEN_VAL &= ~HDACKGEN_ENABLE; - -#ifdef AUD_SPDIF_ENABLE - DGOCFG_VAL &= ~DGOITF_ENABLE; -#endif - - AADCF0CFG_VAL &= ~(AADCITF_ENABLE | AADCF_ENABLE); -} - -static void i2s_enable(void) -{ - DBG_DETAIL(); - - AADCF0CFG_VAL |= (AADCITF_ENABLE | AADCF_ENABLE); - ASMPFCFG_VAL |= (ASMPF_ENABLE); - -#ifdef AUD_SPDIF_ENABLE - DGOCFG_VAL |= DGOITF_ENABLE; -#endif - - DACCFG_VAL |= DACITF_ENABLE; - - if (hd_audio_flag) - HDACKGEN_VAL |= HDACKGEN_ENABLE; -} - -static void aud_audprf_setting(unsigned char smp_rate_index) -{ - unsigned long cfg_tbl[] = {0x00002001, 0x00002001, 0x00002001, - 0x00002001, 0x00002001, 0x00002001, 0x00002001, 0x00002001, - 0x00002001, 0x00002001, 0x00002001, 0x00002001, - 0x00000001, 0x00000001, 0x00000001 - }; - unsigned int dgo_tbl[] = {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00}; - unsigned int sysclk_tbl[] = {4096, 5632, 6144, 8192, 11264, 12288, 16384, - 22579, 24576, 32768, 45056, 49152, 16384, 22528, 24576}; -#ifdef AUD_SPDIF_ENABLE - unsigned int dgocs_tbl[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x02, 0x00, 0x08, 0x0A, 0x00, 0x0C, 0x0E}; -#endif - //unsigned int clock = 0; - unsigned long aud_reg_val; - - DBG_DETAIL(); - - ADCCFG_VAL = cfg_tbl[smp_rate_index]; - - aud_reg_val = dgo_tbl[smp_rate_index]; - DGOCFG_VAL = aud_reg_val; - HDACKGEN_VAL = aud_reg_val; - -#ifdef AUD_SPDIF_ENABLE - /* set ADGO channel status */ - aud_reg_val = dgocs_tbl[smp_rate_index] << 24; - DGOCS0A_VAL = aud_reg_val; - DGOCS1A_VAL = aud_reg_val; - //info("%s : DGOCS01A_VAL=0x%x", __func__, (unsigned int)aud_reg_val); -#endif - - DACCFG_VAL = cfg_tbl[smp_rate_index]; - - auto_pll_divisor(DEV_I2S, CLK_ENABLE , 0, 0); - auto_pll_divisor(DEV_I2S, SET_PLLDIV, 1, sysclk_tbl[smp_rate_index]); - /*clock = auto_pll_divisor(DEV_I2S, GET_FREQ , 0, 0); - info("%s : clock=%d", __func__, clock);*/ -} - -static unsigned char aud_smp_rate_convert(unsigned int smp_rate) -{ - unsigned char i = 0; - unsigned int smp_rate_tbl[] = {8000, 11025, 12000, 16000, 22050, 24000, 32000, - 44100, 48000, 64000, 88200, 96000, 128000, 176000, 192000}; - - DBG_DETAIL(); - - /* boundary checking */ - if (smp_rate < 8000) { - i = 0x00; - } - else if (smp_rate > 192000) { - i = 0x0E; - } - else { - for (i = 0; i < 0x1F; i++) { - if (smp_rate == smp_rate_tbl[i]) { - break; - } - else if (smp_rate < smp_rate_tbl[i + 1]) { - if (smp_rate < (smp_rate_tbl[i] + ((smp_rate_tbl[i + 1] - smp_rate_tbl[i]) / 2))) { - break; - } - else { - i++; - break; - } - } - } - } - - return i; - -} - -static void i2s_sample_rate(unsigned int rate) -{ - unsigned char rate_index; - - DBG_DETAIL("rate=%d", rate); - - if (rate == i2s_data->i2s.rate) - return; - - i2s_data->i2s.rate = rate; - - rate_index = aud_smp_rate_convert(rate); - - aud_audprf_setting(rate_index); - -#ifdef CONFIG_FB_WMT - /* pass information of audio to HDMI Audio */ - hd_audio_flag = vpp_set_audio(16, rate, 2); -#endif -} - -static int i2sdacdat_gpio = -1;//means don't touch GP10 bit0-3 i2sDacDat0-3 - -void wmt_set_i2s_share_pin(void) -{ - int pwren_num,active_level,gpio_int_num; - char buf[256]; - int varlen = 256; - static int gpio26_mux = -1; - unsigned int gpval = 0x0; - - if(gpio26_mux == -1){ - if(wmt_getsyspara("wmt.bt.mtk6622",buf,&varlen) == 0) - { - sscanf(buf,"%d:%d:%d",&pwren_num,&active_level,&gpio_int_num); - printk("use customized value:p%d,a%d,i%d\n",pwren_num,active_level,gpio_int_num); - if(pwren_num == 62){ - gpio26_mux = 0x01; - }else{ - gpio26_mux = 0x00; - } - - }else{ - gpio26_mux = 0x00; - } - } - printk("%s gpio26_mux:%d\n",__func__,gpio26_mux); - if(!gpio26_mux){ - /* disable GPIO and enable Pull Down mode */ - gpval &= ~0xff; - //GPIO_CTRL_GP10_I2S_BYTE_VAL &= ~0xFF; // 0xFF bit1 - }else{ - gpval &= ~0xF7; - //GPIO_CTRL_GP10_I2S_BYTE_VAL &= ~0xF7; - } - - // configure I2SDACDAT1/2/3 as GPIO function but mmax-wm8994 that configured as I2SADCLRC/I2SADCBLCK - if (!wmt_codec_wm8994) - { - gpval |= (BIT1 | BIT2 | BIT3); - //GPIO_CTRL_GP10_I2S_BYTE_VAL |= (BIT1 | BIT2 | BIT3); - - } - - //add for mainly i2sdacdat1 work as gpio to control led 2014-8-15 so here just keep it specific func - //tp driver will use it as gpio - switch (i2sdacdat_gpio) - { - case 1: - gpval |= BIT1; - //GPIO_CTRL_GP10_I2S_BYTE_VAL |= BIT1; // i2sdacdat1 work as gpio - break; - case 2: - gpval |= BIT2; - //GPIO_CTRL_GP10_I2S_BYTE_VAL |= BIT2; - break; - case 3: - gpval |= BIT3; - //GPIO_CTRL_GP10_I2S_BYTE_VAL |= BIT3; - break; - - } - GPIO_CTRL_GP10_I2S_BYTE_VAL = gpval; - - GPIO_CTRL_GP11_I2S_BYTE_VAL &= ~(BIT0 | BIT1 | BIT2); - - if(!gpio26_mux){ - PULL_EN_GP10_I2S_BYTE_VAL |= 0xFF; - }else{ - PULL_EN_GP10_I2S_BYTE_VAL |= 0xF7; - } - PULL_EN_GP11_I2S_BYTE_VAL |= (BIT0 | BIT1 | BIT2); - - if(!gpio26_mux){ - /* set to 2ch input, 2ch output */ - PIN_SHARING_SEL_4BYTE_VAL &= ~(BIT15 | BIT17 | BIT19 | BIT20); - PIN_SHARING_SEL_4BYTE_VAL |= (BIT1 | BIT16 | BIT18); - }else{ - PIN_SHARING_SEL_4BYTE_VAL &= ~(BIT15 | BIT17 | BIT20); - PIN_SHARING_SEL_4BYTE_VAL |= (BIT1 | BIT16); - } -} -EXPORT_SYMBOL(wmt_set_i2s_share_pin); - -static void i2s_init(int mode) -{ -#ifdef DEBUG - int ret; -#endif - int temp ; - //unsigned int clock = 0; - - DPRINTK("i2s_ref = %d ", i2s_data->i2s.ref); - - if (++i2s_data->i2s.ref > 1) - return; - - DBG_DETAIL(); - - if (!mode) { - /* set to 24.576MHz */ - auto_pll_divisor(DEV_I2S, CLK_ENABLE , 0, 0); - auto_pll_divisor(DEV_I2S, SET_PLLDIV, 1, 24576); - /*clock = auto_pll_divisor(DEV_I2S, GET_FREQ , 0, 0); - info("%s : clock=%d \n" , __func__, clock);*/ - - /* Enable BIT4:ARFP clock, BIT3:ARF clock */ - PMCEU_VAL |= (BIT4 | BIT3); - - /* Enable BIT2:AUD clock */ - PMCE3_VAL |= BIT2; - - wmt_set_i2s_share_pin(); - } - - /* connect DZDRQ8 to ADC0 FIFO, DZDRQ9 to DAC FIFO and DZDRQA to ADC1 FIFO */ - DZDRQ8_CFG_VAL = 0x0; - DZDRQ9_CFG_VAL = 0x1; - DZDRQA_CFG_VAL = 0x2; - - DACCFG_VAL = 0x0; - ADCCFG_VAL = 0x0; - - /* little endian, signed format, enable sample FIFO, 16bit sample, 2 channel */ - ASMPFCFG_VAL = 0x52; - - /* assign ch0 to DAC#0_L, DAC#1_L, DAC#2_L, SPDIF_L, - ch1 to DAC#0_R, DAC#1_R, DAC#2_R, SPDIF_R */ - ASMPFCHCFG0_VAL = 0x10101010; - - /* assign ch0 to DAC#3_L, ch1 to DAC#3_R */ - ASMPFCHCFG1_VAL = 0x10; - - /* select ADCDAT0, 16 bits mode, enable AADCFIFO and AADCITF */ - AADCF0CFG_VAL = (AADCITF_ENABLE | AADCF16_ENABLE | AADCF_ENABLE); - - /* the sequence must be ARF_ADCCFG first then ARF_DGOCFG, finally ARF_DACCFG while slave mode, - otherwise will generate noise when record function is active */ - - /* ADC slave mode, 48K sample rate, I2S mode */ - ADCCFG_VAL = 0x2001; - - i2s_data->i2s.rate = 48000; - i2s_data->i2s.channels = 2; - i2s_data->i2s.format = SNDRV_PCM_FORMAT_S16_LE; - -#ifdef AUD_SPDIF_ENABLE - /* B1: 0 -> PCM, 1 -> Bitstream - B24 ~ B27: sample rate */ - /* set ADGO channel status for 48K sample rate */ - DGOCS0A_VAL = 0x02 << 24; - DGOCS1A_VAL = 0x02 << 24; - - /* enable ADGOITF and ADGOCKGEN for 48K sample rate */ - DGOCFG_VAL = 0x82; -#endif - - /* enable ADACITF and ADACCKGEN for 44.1K sample rate, I2S mode */ - DACCFG_VAL = 0x402001; - if (audio_interface_mode == 1) - { - printk("<<<<<%s left justified!\n", __func__); - //left justified bit20: 0->i2s, 1->l/r clock polarity - DACCFG_VAL |= 0x1 << 20; - //bit7:0 padding added to dac serial data output - //0 = LJ - //1 = I2S - //others = RJ (depends on Bit 11:8) - - DACCFG_VAL &= ~(0x1<<0); - - } - - /* enable HD Audio clock for 48K sample rate or not*/ - HDACKGEN_VAL = 0x12; - -#ifdef CONFIG_FB_WMT - /* pass information of audio to HDMI Audio */ - hd_audio_flag = vpp_set_audio(16, i2s_data->i2s.rate, i2s_data->i2s.channels); - ASMPF2HDACHCFG_VAL = 0x76543210; -#endif - - if (!hd_audio_flag) - HDACKGEN_VAL = 0; - - /* audio peri reset */ - temp = AUDPRFRST_VAL; - -#ifdef AUD_SPDIF_ENABLE - temp |= (ASMPF_RESET | DACITF_RESET | ADCITF_RESET | DGOITF_RESET); -#else - temp |= (ASMPF_RESET | DACITF_RESET | ADCITF_RESET); -#endif - - AUDPRFRST_VAL = temp; - - /* - request irq - */ -#ifdef CONFIG_WMT_I2S_INT - ret = request_irq(i2s_data->i2s.irq, - wmt_i2s_interrupt, - SA_INTERRUPT, - "wmt_alsa_vt1602", - NULL); - if (ret) - printk("%s : unable to request IRQ \n" , __func__); -#endif -} - -static void i2s_exit(void) -{ - DBG_DETAIL(); - - if (--i2s_data->i2s.ref) - return; - - DPRINTK("Do i2s_exit "); - -#ifdef CONFIG_WMT_I2S_INT - free_irq(i2s_data->i2s.irq, NULL); -#endif - - /* Reset counter.*/ - memset(&i2s_data->i2s.ints, 0, sizeof(struct i2s_ints_s)); - return; -} - -static int wmt_i2s_dai_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int stream_id = substream->pstr->stream; - struct audio_stream_a *s = &i2s_data->s[0]; - - DBG_DETAIL(); - - s[stream_id].stream = substream; - - runtime->private_data = s; - - return 0; -} - -static void wmt_i2s_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) -{ - DBG_DETAIL(); -} - -static int wmt_i2s_dai_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - int err = 0; - int stream_id = substream->pstr->stream; - - DBG_DETAIL(); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { - ASMPFCFG_VAL |= ASMPF_ENABLE; - } - else if (stream_id == SNDRV_PCM_STREAM_CAPTURE) { - AADCF0CFG_VAL |= AADCF_ENABLE; - } - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { - ASMPFCFG_VAL &= ~ASMPF_ENABLE; - } - else if (stream_id == SNDRV_PCM_STREAM_CAPTURE) { - AADCF0CFG_VAL &= ~AADCF_ENABLE; - } - - /* - mod_timer(&i2s_data->delay_timer, jiffies + HZ / 100); - */ - break; - default: - err = -EINVAL; - } - - return err; -} - -static int wmt_i2s_dai_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) -{ - DBG_DETAIL(); - return 0; -} - -static int wmt_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned int channel, byte; - int stream_id = substream->pstr->stream; - -#ifdef CONFIG_SND_OSSEMUL - //info("oss.rate=%d, oss.channels=%d", runtime->oss.rate, runtime->oss.channels); -#else - DBG_DETAIL(); -#endif - - byte = (runtime->sample_bits)/8; - channel = runtime->channels; - - DPRINTK("snd_wmt_alsa_prepare byte = %d, channels = %d", byte, runtime->channels); - - - if ((runtime->rate != i2s_data->i2s.rate) || (runtime->format != i2s_data->i2s.format) || - (runtime->channels != i2s_data->i2s.channels) || (stream_id != i2s_data->stream_id)) { - info("*** stream_id=%d, rate=%d, format=0x%x channels=%d ***", - stream_id, runtime->rate, runtime->format, runtime->channels); - i2s_data->i2s.format = runtime->format; - i2s_data->i2s.channels = runtime->channels; - i2s_data->stream_id = stream_id; - } - else { - return 0; - } - - i2s_disable(); - - /* format setting */ - if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { - /* little or big endian check */ - switch (runtime->format) { - case SNDRV_PCM_FORMAT_S16_BE: - case SNDRV_PCM_FORMAT_U16_BE: - case SNDRV_PCM_FORMAT_S24_BE: - case SNDRV_PCM_FORMAT_U24_BE: - case SNDRV_PCM_FORMAT_S32_BE: - case SNDRV_PCM_FORMAT_U32_BE: - ASMPFCFG_VAL |= ASMPF_EXCH_ENDIAN; - break; - default: - ASMPFCFG_VAL &= ~ASMPF_EXCH_ENDIAN; - break; - } - - /* unsigned or signed check */ - switch (runtime->format) { - case SNDRV_PCM_FORMAT_U8: - case SNDRV_PCM_FORMAT_U16_LE: - case SNDRV_PCM_FORMAT_U16_BE: - case SNDRV_PCM_FORMAT_U24_LE: - case SNDRV_PCM_FORMAT_U24_BE: - case SNDRV_PCM_FORMAT_U32_LE: - case SNDRV_PCM_FORMAT_U32_BE: - ASMPFCFG_VAL |= ASMPF_EXCH_FMT; - break; - default: - ASMPFCFG_VAL &= ~ASMPF_EXCH_FMT; - break; - } - - /* sample quantization check */ - ASMPFCFG_VAL &= ~(BIT4 | BIT5); - switch (runtime->format) { - case SNDRV_PCM_FORMAT_S8: - case SNDRV_PCM_FORMAT_U8: - ASMPFCFG_VAL |= ASMPF_8BIT_SMP; - break; - case SNDRV_PCM_FORMAT_S16_LE: - case SNDRV_PCM_FORMAT_S16_BE: - case SNDRV_PCM_FORMAT_U16_LE: - case SNDRV_PCM_FORMAT_U16_BE: - ASMPFCFG_VAL |= ASMPF_16BIT_SMP; - break; - case SNDRV_PCM_FORMAT_S32_LE: - case SNDRV_PCM_FORMAT_S32_BE: - case SNDRV_PCM_FORMAT_U32_LE: - case SNDRV_PCM_FORMAT_U32_BE: - ASMPFCFG_VAL |= ASMPF_32BIT_SMP; - break; - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S24_BE: - case SNDRV_PCM_FORMAT_U24_LE: - case SNDRV_PCM_FORMAT_U24_BE: - info("*** Not Supported: fmt=24Bit ***"); - default: - break; - } - - /* channel number check */ - ASMPFCFG_VAL &= ~(BIT0 | BIT1 | BIT2 | BIT3); - ASMPFCFG_VAL |= runtime->channels; - - wmt_i2s_ch_config(); - info("Prepare: CHCFG0=0x%x, HDACHCFG=0x%x", ASMPFCHCFG0_VAL, ASMPF2HDACHCFG_VAL); - } - - /* sample rate setting */ -#ifdef CONFIG_SND_OSSEMUL - if (runtime->oss.rate) { - i2s_sample_rate(runtime->oss.rate); - } - else { - i2s_sample_rate(runtime->rate); - } -#else - i2s_sample_rate(runtime->rate); -#endif - - i2s_enable(); - - /* - printk("avail_max=%d, rate=%d, channels=%d, period_size=%d, periods=%d, buffer_size=%d, tick_time=%d, \ - min_align=%d, byte_align=%d, frame_bits=%d, sample_bits=%d, sleep_min=%d, xfer_align=%d, boundary=%d\n", - runtime->avail_max, runtime->rate, runtime->channels, runtime->period_size, runtime->periods, - runtime->buffer_size, runtime->tick_time, runtime->min_align, runtime->byte_align, - runtime->frame_bits, runtime->sample_bits, - runtime->sleep_min, runtime->xfer_align, runtime->boundary); - */ - return 0; -} - -/* - * This must be called before _set_clkdiv and _set_sysclk since McBSP register - * cache is initialized here - */ -static int wmt_i2s_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, - unsigned int fmt) -{ - DBG_DETAIL(); - return 0; //add rambo 2013-3-13 - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - break; - default: - /* Unsupported data format */ - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - break; - case SND_SOC_DAIFMT_CBM_CFM: - break; - default: - return -EINVAL; - } - - /* Set bit clock (CLKX/CLKR) and FS polarities */ - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - /* - * Normal BCLK + FS. - * FS active low. TX data driven on falling edge of bit clock - * and RX data sampled on rising edge of bit clock. - */ - break; - case SND_SOC_DAIFMT_NB_IF: - break; - case SND_SOC_DAIFMT_IB_NF: - break; - case SND_SOC_DAIFMT_IB_IF: - break; - default: - return -EINVAL; - } - - return 0; -} - -#ifdef CONFIG_PM -static int wmt_i2s_suspend(struct snd_soc_dai *cpu_dai) -{ - printk("%s!\n", __func__); - - DBG_DETAIL(); - - i2s_data->i2s.ref = 0; -#if 1 - if (gpio_pa >= 0) - { - gpio_direction_output(gpio_pa, !gpio_active); - } -#endif - return 0; -} - -static int wmt_i2s_resume(struct snd_soc_dai *cpu_dai) -{ - printk("%s!\n", __func__); - - DBG_DETAIL(); - - i2s_init(1); - - wmt_i2s_ch_config(); -#if 1 - if (gpio_pa >= 0) - { - gpio_direction_output(gpio_pa, gpio_active); - mdelay(50); - } -#endif - info("Resume: CHCFG0=0x%x, HDACHCFG=0x%x", ASMPFCHCFG0_VAL, ASMPF2HDACHCFG_VAL); - return 0; -} -#else -#define wmt_i2s_suspend NULL -#define wmt_i2s_resume NULL -#endif - -static struct snd_soc_dai_ops wmt_i2s_dai_ops = { - .startup = wmt_i2s_dai_startup, - .prepare = wmt_i2s_prepare, - .shutdown = wmt_i2s_dai_shutdown, - .trigger = wmt_i2s_dai_trigger, - .hw_params = wmt_i2s_dai_hw_params, - .set_fmt = wmt_i2s_dai_set_dai_fmt, -}; - -struct snd_soc_dai_driver wmt_i2s_dai = { - .suspend = wmt_i2s_suspend, - .resume = wmt_i2s_resume, - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_FLOAT, - }, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .ops = &wmt_i2s_dai_ops, -}; - -static int wmt_i2s_probe(struct platform_device *pdev) -{ - int ret; - char buf[64]; - int varlen = 64; - - DBG_DETAIL(); - - ret = wmt_getsyspara("wmt.audio.pcm", buf, &varlen); - if (ret == 0) { - sscanf(buf, "%d", &wmt_pdm_module_enable); - } - - ret = wmt_getsyspara("wmt.audio.i2s", buf, &varlen); - if (ret == 0) { - if (!strncmp(buf, "wm8994", strlen("wm8994"))) - wmt_codec_wm8994 = 1; - } - memset(buf, 0, sizeof(buf)); - ret = wmt_getsyspara("wmt.audio.codechdmi", buf, &varlen); - if (ret == 0) { - sscanf(buf, "%d", &i2s_data[0].HDMI_and_DAC0); - printk("<<<%s codec and hdmi:%d\n", __FUNCTION__, i2s_data[0].HDMI_and_DAC0); - } - - memset(buf, 0, sizeof(buf)); - //0:i2sdacdat0(usually use i2s function!!) 1:i2sdacdat1 2:i2sdacdat2 3:i2sdacdat3 - ret = wmt_getsyspara("wmt.audio.dacdat.gpio", buf, &varlen); - if (ret == 0) { - sscanf(buf, "%d", &i2sdacdat_gpio); - printk("<<<%s i2sdacdat_gpio:%d\n", __FUNCTION__, i2sdacdat_gpio); - } - - - memset(buf, 0, sizeof(buf)); - ret = wmt_getsyspara("wmt.audio.interface.mode", buf, &varlen); - if (ret == 0) { // 0:i2s 1:left justified 2:right justified - sscanf(buf, "%d", &audio_interface_mode); - printk("<<<%s audio_interface_mode:%d\n", __FUNCTION__, audio_interface_mode); - } - - memset(buf, 0, sizeof(buf)); - ret = wmt_getsyspara("wmt.audio.pa", buf, &varlen); - if (ret == 0) { // gpio nr:active---> 1:0 - sscanf(buf, "%d:%d", &gpio_pa, &gpio_active); - - } - printk("%s audio pa:%d:%d\n", __FUNCTION__, gpio_pa, gpio_active); - if (gpio_pa >= 0) - { - ret = gpio_request(gpio_pa, "audio pa"); - if (ret) - { - printk("%s gpio %d request error!\n", __func__, gpio_pa); - return ret; - } - #if 0 - if (gpio_active) - wmt_gpio_setpull(gpio_pa, WMT_GPIO_PULL_DOWN); - else - wmt_gpio_setpull(gpio_pa, WMT_GPIO_PULL_UP); - msleep(10); - gpio_direction_output(gpio_pa, !gpio_active); //???pop??? - printk("%s shutdown pa!\n", __func__); - msleep(100); - #endif - - - init_timer(&pa_timer); - pa_timer.function = pa_timer_handler; - } - i2s_data->s[0].dma_cfg = dma_device_cfg_table[AHB1_AUD_DMA_REQ_1]; - i2s_data->s[1].dma_cfg = dma_device_cfg_table[AHB1_AUD_DMA_REQ_0]; - /*init i2s controller*/ - i2s_data->i2s.init(0); - - spin_lock_init(&i2s_data->s[0].dma_lock); - spin_lock_init(&i2s_data->s[1].dma_lock); - /*init_timer(&i2s_data->delay_timer); - i2s_data->delay_timer.function = delay_timer_handler;*/ - - /* register with the ASoC layers */ - ret = snd_soc_register_dai(&pdev->dev, &wmt_i2s_dai); - if (ret) { - pr_err("Failed to register DAI: %d\n", ret); - return ret; - } - - if (gpio_pa >= 0) - { - mod_timer(&pa_timer, jiffies+msecs_to_jiffies(10000)); - } - return 0; -} - -static int __devexit wmt_i2s_remove(struct platform_device *pdev) -{ - DBG_DETAIL(); - - snd_soc_unregister_dai(&pdev->dev); - - return 0; -} - -static void wmt_i2s_plat_shutdown(struct platform_device *pdev) -{ - printk("%s!\n", __func__); - if (gpio_pa >= 0) - { - gpio_direction_output(gpio_pa, !gpio_active); - } -} - -static struct platform_driver wmt_i2s_driver = { - .probe = wmt_i2s_probe, - .remove = __devexit_p(wmt_i2s_remove), - //.suspend = wmt_i2s_plat_suspend, - //.resume = wmt_i2s_plat_resume, - .shutdown = wmt_i2s_plat_shutdown, - .driver = { - .name = "wmt-i2s", - .owner = THIS_MODULE, - }, -}; - - -static int __init wmt_i2s_init(void) -{ - DBG_DETAIL(); - - return platform_driver_register(&wmt_i2s_driver); -} - -static void __exit wmt_i2s_exit(void) -{ - DBG_DETAIL(); - - platform_driver_unregister(&wmt_i2s_driver); -} - -module_init(wmt_i2s_init); -module_exit(wmt_i2s_exit); - -MODULE_AUTHOR("WonderMedia Technologies, Inc."); -MODULE_DESCRIPTION("WMT [ALSA SoC] driver"); -MODULE_LICENSE("GPL"); - diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.c b/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.c deleted file mode 100755 index dccb82c6..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.c +++ /dev/null @@ -1,419 +0,0 @@ -/*++ - * linux/sound/soc/wmt/wmt-pdm-if.c - * WonderMedia I2S audio driver for ALSA - * - * Copyright c 2010 WonderMedia Technologies, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * WonderMedia Technologies, Inc. - * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C ---*/ - - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/interrupt.h> -#include <asm/irq.h> -#include <linux/delay.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/initval.h> -#include <sound/soc.h> - -#include <mach/hardware.h> -#include <asm/dma.h> -#include "wmt-soc.h" -#include "wmt-pcm-controller.h" - -#define PCM_IS_MASTER_MODE -#define NULL_DMA ((dmach_t)(-1)) - -static int wmt_pcm_module_enable = 0; -extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen); - -static struct audio_stream_a wmt_pcm_controller_data[] = { - { - .id = "WMT PCM out", - .stream_id = SNDRV_PCM_STREAM_PLAYBACK, - .dmach = NULL_DMA, - .dma_dev = PCM_TX_DMA_REQ, - /*.dma_cfg = dma_device_cfg_table[I2S_TX_DMA_REQ],*/ - }, - { - .id = "WMT PCM in", - .stream_id = SNDRV_PCM_STREAM_CAPTURE, - .dmach = NULL_DMA, - .dma_dev = PCM_RX_DMA_REQ, - /*.dma_cfg = dma_device_cfg_table[I2S_RX_DMA_REQ],*/ - }, -}; - -struct wmt_pcm_controller -{ - int irq_no; - int pcm_clk_src; - int pcm_enable; -}; - -static struct wmt_pcm_controller wmt_pcm_controller; - -static irqreturn_t -wmt_pcm_controller_irq_handler(int irq, void *dev_id) -{ - if (PCMSR_VAL & PCMSR_TXUND) { - printk("-->PCMSR_TXUND\n"); - } - else if (PCMSR_VAL & PCMSR_RXOVR) { - printk("-->PCMSR_RXOVR\n"); - } - - PCMSR_VAL = 0x7F; //write clear all intr - return IRQ_HANDLED; -} - -static void wmt_pcm_controller_enable(void) -{ - PCMCR_VAL |= (PCMCR_PCM_ENABLE | PCMCR_DMA_EN); -} - -static void wmt_pcm_controller_disable(void) -{ - PCMCR_VAL &= ~(PCMCR_PCM_ENABLE | PCMCR_DMA_EN); -} - -static int wmt_pcm_controller_init(void) -{ - wmt_pcm_controller.irq_no = IRQ_PCM; - - // Before control pcm-module, enable pcm clock first - CLOCKEN(27); - - // set pcm_clk_source = 62464khz - //auto_pll_divisor(DEV_PCM0, CLK_ENABLE, 0, 0); - //auto_pll_divisor(DEV_PCM0, SET_PLLDIV, 1, 83333); - - wmt_pcm_controller.pcm_clk_src = auto_pll_divisor(DEV_PCM0, GET_FREQ, 0, 0); - wmt_pcm_controller.pcm_clk_src /= 1000; - wmt_pcm_controller.pcm_enable = 0; - printk("wmt_pcm_controller_init: pcm_clk_src=%d \n\r", wmt_pcm_controller.pcm_clk_src); - - // Note: you should config PIN_SHARING_SEL_4BYTE_VAL if using pcm function!!! Loon mark at 2013/4/10 - if (wmt_pcm_module_enable) { - printk("begin to configure pcm pin\n"); - /* disable GPIO and Pull Down mode */ - /* Bit1:I2SDACDAT1=PCMSYNC, Bit2:I2SDACDAT2=PCMCLK, Bit3:I2SDACDAT3=PCMIN, Bit4:I2SADCMCLK=PCMOUT */ - GPIO_CTRL_GP10_I2S_BYTE_VAL &= ~(BIT1 | BIT2 | BIT3 | BIT4); - GPIO_CTRL_GP11_I2S_BYTE_VAL &= ~(BIT1); - /*disable pull enable*/ - PULL_EN_GP10_I2S_BYTE_VAL &= ~(BIT1 | BIT2 | BIT3 | BIT4); - PULL_EN_GP11_I2S_BYTE_VAL &= ~(BIT1); - - /* set to pcm mode */ - // select PCMMCLK[bit0], PCMSYNC[bit17:16], PCMCLK[19:18], PCMIN[20], PCMOUT[22:21] - //GPIO_PIN_SHARING_SEL_4BYTE_VAL &= ~(BIT21); - GPIO_PIN_SHARING_SEL_4BYTE_VAL |= (BIT15 | BIT16 | BIT17 | BIT18 | BIT19 |BIT20); - } - - // set pcm control register - PCMCR_VAL |= (PCMCR_TXFF_RST | PCMCR_RXFF_RST); - //PCMCR_VAL |= 0x00880000; // TX/RX Fifo Threshold A - PCMCR_VAL &= ~(PCMCR_BCLK_SEL); - PCMCR_VAL &= ~PCMCR_SLAVE; // master mode - PCMCR_VAL |= PCMCR_SYNC_MODE;//short frame sync - - // set pcm format register - PCMDFCR_VAL = 0; - PCMDFCR_VAL |= (PCMDFCR_WR_AL | PCMDFCR_TX_AL | PCMDFCR_RX_AL | PCMDFCR_RD_AL); - PCMDFCR_VAL |= (PCMDFCR_TX_SZ_14 | PCMDFCR_RX_SZ_14); - //PCMDFCR_VAL |= (PCMDFCR_TX_SZ_08 | PCMDFCR_RX_SZ_08); - - // - // request irq - // - /*if (request_irq(wmt_pcm_controller.irq_no, &wmt_pcm_controller_irq_handler, IRQF_DISABLED, "wmt_pcm_controller", NULL)){ - printk(KERN_ERR "PCM_IRQ Request Failed!\n"); - } - PCMCR_VAL |= (PCMCR_IRQ_EN | PCMCR_TXUND_EN | PCMCR_RXOVR_EN); - */ - printk("fun:%s,line:%d\n",__func__,__LINE__); - return 0 ; -} - - -static int wmt_pcm_controller_dai_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int stream_id = substream->pstr->stream; - struct audio_stream_a *s = &wmt_pcm_controller_data[0]; - //dump_stack(); - s[stream_id].stream = substream; - runtime->private_data = s; - - return 0; -} - -static void wmt_pcm_controller_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) -{ - //dump_stack(); -} - -static int wmt_pcm_controller_dai_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - int err = 0; - int stream_id = substream->pstr->stream; - //dump_stack(); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { - PCMCR_VAL |= PCMCR_TXFF_RST; // reset txfifo - PCMDFCR_VAL |= PCMDFCR_TXFM_EN; - } - else if (stream_id == SNDRV_PCM_STREAM_CAPTURE) { - PCMCR_VAL |= PCMCR_RXFF_RST; // reset rxfifo - PCMDFCR_VAL |= PCMDFCR_RXFM_EN; - } - //wmt_pcm_controller_enable(); - wmt_pcm_controller.pcm_enable++; - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { - PCMDFCR_VAL &= ~PCMDFCR_TXFM_EN; - } - else if (stream_id == SNDRV_PCM_STREAM_CAPTURE) { - PCMDFCR_VAL &= ~PCMDFCR_RXFM_EN; - } - //wmt_pcm_controller_disable(); - wmt_pcm_controller.pcm_enable--; - break; - default: - err = -EINVAL; - break; - } - - if (wmt_pcm_controller.pcm_enable) - wmt_pcm_controller_enable(); - else - wmt_pcm_controller_disable(); - - return err; -} - -static int wmt_pcm_controller_dai_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) -{ - //dump_stack(); - return 0; -} - -static int wmt_pcm_controller_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned int channel, byte; - int stream_id = substream->pstr->stream; - - byte = (runtime->sample_bits)/8; - channel = runtime->channels; - - printk(KERN_INFO "wmt_pcm_controller_dai_prepare byte = %d, channels = %d\n", byte, runtime->channels); - - /* format setting */ - if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { - /* little or big endian check */ - switch (runtime->format) { - case SNDRV_PCM_FORMAT_S16_LE: - break; - default: - break; - } - - /* channel number check */ - switch (runtime->channels) { - case 1: - break; - case 2: - break; - default: - break; - } - } - else if (stream_id == SNDRV_PCM_STREAM_CAPTURE) { - /* little or big endian check */ - switch (runtime->format) { - case SNDRV_PCM_FORMAT_S16_LE: - break; - default: - break; - } - - /* channel number check */ - switch (runtime->channels) { - case 1: - break; - case 2: - break; - default: - break; - } - } - - switch (runtime->rate) { - case 16000: - PCMDIVR_VAL &= ~PCMCLK_DIV_MASK; - PCMDIVR_VAL |= (wmt_pcm_controller.pcm_clk_src / PCMCLK_256K); - break; - case 8000: - PCMDIVR_VAL &= ~PCMCLK_DIV_MASK; - PCMDIVR_VAL |= (wmt_pcm_controller.pcm_clk_src / PCMCLK_128K); - break; - default : - printk(KERN_ERR "not supported fs: %d \n\r", runtime->rate); - break; - } - - return 0; -} - -/* - * This must be called before _set_clkdiv and _set_sysclk since McBSP register - * cache is initialized here - */ -static int wmt_pcm_controller_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, - unsigned int fmt) -{ - return 0; -} - -#ifdef CONFIG_PM -static int wmt_pcm_controller_suspend(struct snd_soc_dai *cpu_dai) -{ - return 0; -} - -static int wmt_pcm_controller_resume(struct snd_soc_dai *cpu_dai) -{ - int ret = wmt_pcm_controller_init(); - if (ret) { - pr_err("Failed to init pcm module: %d\n", ret); - return ret; - } - return 0; -} -#else -#define wmt_pcm_controller_suspend NULL -#define wmt_pcm_controller_resume NULL -#endif - -static struct snd_soc_dai_ops wmt_pcm_controller_dai_ops = { - .startup = wmt_pcm_controller_dai_startup, - .prepare = wmt_pcm_controller_dai_prepare, - .shutdown = wmt_pcm_controller_dai_shutdown, - .trigger = wmt_pcm_controller_dai_trigger, - .hw_params = wmt_pcm_controller_dai_hw_params, - .set_fmt = wmt_pcm_controller_dai_set_dai_fmt, -}; - -struct snd_soc_dai_driver wmt_pcm_controller_dai = { - .suspend = wmt_pcm_controller_suspend, - .resume = wmt_pcm_controller_resume, - .playback = { - .channels_min = 1, - .channels_max = 1, - .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .capture = { - .channels_min = 1, - .channels_max = 1, - .rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .ops = &wmt_pcm_controller_dai_ops, -}; - -static int wmt_pcm_controller_probe(struct platform_device *pdev) -{ - int ret = 0; - char buf[64]; - int varlen = 64; - - ret = wmt_getsyspara("wmt.audio.pcm", buf, &varlen); - if (ret == 0) { - sscanf(buf, "%d", &wmt_pcm_module_enable); - } - - ret = wmt_pcm_controller_init(); - if (ret) { - pr_err("Failed to init pcm module: %d\n", ret); - return ret; - } - - /* register with the ASoC layers */ - ret = snd_soc_register_dai(&pdev->dev, &wmt_pcm_controller_dai); - if (ret) { - pr_err("Failed to register DAI: %d\n", ret); - return ret; - } - - wmt_pcm_controller_data[0].dma_cfg = dma_device_cfg_table[PCM_TX_DMA_REQ]; - wmt_pcm_controller_data[1].dma_cfg = dma_device_cfg_table[PCM_RX_DMA_REQ]; - - spin_lock_init(&wmt_pcm_controller_data[0].dma_lock); - spin_lock_init(&wmt_pcm_controller_data[1].dma_lock); - - return 0; -} - -static int __devexit wmt_pcm_controller_remove(struct platform_device *pdev) -{ - snd_soc_unregister_dai(&pdev->dev); - return 0; -} - -static struct platform_driver wmt_pcm_controller_driver = { - .probe = wmt_pcm_controller_probe, - .remove = __devexit_p(wmt_pcm_controller_remove), - .driver = { - .name = "wmt-pcm-controller", - .owner = THIS_MODULE, - }, -}; - - -static int __init wmt_pcm_controller_module_init(void) -{ - return platform_driver_register(&wmt_pcm_controller_driver); -} - -static void __exit wmt_pcm_controller_module_exit(void) -{ - platform_driver_unregister(&wmt_pcm_controller_driver); -} - -module_init(wmt_pcm_controller_module_init); -module_exit(wmt_pcm_controller_module_exit); - -MODULE_AUTHOR("WonderMedia Technologies, Inc."); -MODULE_DESCRIPTION("WMT [ALSA SoC] driver"); -MODULE_LICENSE("GPL"); - diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.h b/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.h deleted file mode 100755 index 58e94f23..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-controller.h +++ /dev/null @@ -1,122 +0,0 @@ -/*++ -linux/include/asm-arm/arch-wmt/wmt_pcm.h - -Copyright (c) 2008 WonderMedia Technologies, Inc. - -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. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License along with -this program. If not, see <http://www.gnu.org/licenses/>. - -WonderMedia Technologies, Inc. -10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C. ---*/ - -/* Be sure that virtual mapping is defined right */ - -#ifndef __WMT_PCM_CONTROLLER_H -#define __WMT_PCM_CONTROLLER_H - -/* - * Address - */ -#define PCM_CR_ADDR (0x0000+PCM_BASE_ADDR) -#define PCM_SR_ADDR (0x0004+PCM_BASE_ADDR) -/* Reserved 0x0008 ~ 0x000F */ -#define PCM_DFCR_ADDR (0x0008+PCM_BASE_ADDR) -#define PCM_DIVR_ADDR (0x000C+PCM_BASE_ADDR) -/* Reserved 0x0020 ~ 0x007F */ -#define PCM_TFIFO_ADDR (0x0010+PCM_BASE_ADDR) -#define PCM_TFIFO_1_ADDR (0x0014+PCM_BASE_ADDR) - -#define PCM_RFIFO_ADDR (0x0030+PCM_BASE_ADDR) -#define PCM_RFIFO_1_ADDR (0x0034+PCM_BASE_ADDR) -/* Reserved 0x0100 ~ 0xFFFF */ - -/* - * Value - */ -#define PCMCR_VAL (REG32_VAL(PCM_CR_ADDR)) -#define PCMSR_VAL (REG32_VAL(PCM_SR_ADDR)) -#define PCMDFCR_VAL (REG32_VAL(PCM_DFCR_ADDR)) -#define PCMDIVR_VAL (REG32_VAL(PCM_DIVR_ADDR)) -#define GPIO_PIN_SHARING_SEL_4BYTE_VAL (REG32_VAL(SHARE_PIN_SELEC)) - -#define PCMCLK_DIV_MASK 0x7FF -#define PLL_B_DIVF_MASK 0xFF0000 -#define PLL_B_DIVR_MASK 0x1F00 -#define PLL_B_DIVQ_MASK 0x07 -#define OSC_25M 25000 -#define PCMCLK_128K 128 -#define PCMCLK_256K 256 - - -//============================================================================= -// -// PCMCR PCM Control Register -// -//============================================================================= -#define PCMCR_PCM_ENABLE (BIT0) /* PCM Interface Enable */ -#define PCMCR_SLAVE (BIT1) /* Master/Slave Mode */ - -#define PCMCR_BCLK_SEL (BIT3) /* PCM_CLK Select */ -#define PCMCR_SYNC_MODE (BIT4) /* Frame Sync Mode: 0-long, 1-Short */ -#define PCMCR_DMA_EN (BIT5) /* DMA Enable */ -#define PCMCR_SYNC_OFF (BIT6) /* Sync Disable */ -#define PCMCR_MUTE (BIT7) /* Mute Enable */ -#define PCMCR_IRQ_EN (BIT8) /* Interrupt Enable */ -#define PCMCR_DMA_IRQ_SEL (BIT9) /* Threshold DMA/IRQ Select */ -#define PCMCR_RXFE_EN (BIT10) /* RX FIFO Empty Interrupt Enable */ -#define PCMCR_RXFF_EN (BIT11) /* RX FIFO Full Interrupt Enable */ -#define PCMCR_RXOVR_EN (BIT12) /* RX FIFO Overrun Interrupt Enable */ -#define PCMCR_TXFE_EN (BIT13) /* TX FIFO Empty Interrupt Enable */ -#define PCMCR_TXUND_EN (BIT14) /* TX FIFO Underrun Interrupt Enable */ - -#define PCMCR_TXFF_RST (BIT24) /* TX FIFO Reset */ -#define PCMCR_RXFF_RST (BIT25) /* RX FIFO Reset */ - - -//============================================================================= -// -// PCMSR PCM Status Register -// -//============================================================================= -#define PCMSR_RXFE (BIT0) /* RX FIFO Empty Status */ -#define PCMSR_RXFF (BIT1) /* RX FIFO Full Status */ -#define PCMSR_RXOVR (BIT2) /* RX FIFO Overrun Status */ -#define PCMSR_TXFE (BIT3) /* TX FIFO Empty Status */ -#define PCMSR_TXUND (BIT4) /* TX FIFO Underrun Status */ -#define PCMSR_TXFAE (BIT5) /* TX FIFO Almost Empty Status */ -#define PCMSR_RXFAF (BIT6) /* RX FIFO Almost Full Status */ - - -//============================================================================= -// -// PCMDFCR PCM Data Format Control Register -// -//============================================================================= -#define PCMDFCR_TXFM_EN (BIT0) /* TX Data Format Enable */ -#define PCMDFCR_TX_SZ_13 0x00 /* TX Input Data Size 13 bits wide */ -#define PCMDFCR_TX_SZ_14 0x02 /* TX Input Data Size 14 bits wide */ -#define PCMDFCR_TX_SZ_08 0x04 /* TX Input Data Size 8 bits wide */ -#define PCMDFCR_WR_AL (BIT3) /* TX Write Data Alignment Setup */ -#define PCMDFCR_TX_AL (BIT4) /* PCM_OUT Alignment Control */ -#define PCMDFCR_TX_PAD (BIT5) /* PCM_OUT Padding Control */ -#define PCMDFCR_TX_MSB (BIT6) /* PCM_OUT First Bit Select */ - -#define PCMDFCR_RXFM_EN (BIT8) /* RX Data Format Enable */ -#define PCMDFCR_RX_SZ_13 0x0000 /* RCM_IN Data Size 13 bits wide */ -#define PCMDFCR_RX_SZ_14 0x0200 /* RCM_IN Data Size 14 bits wide */ -#define PCMDFCR_RX_SZ_08 0x0400 /* RCM_IN Data Size 8 bits wide */ -#define PCMDFCR_RX_AL (BIT11) /* RCM_IN Data Alignment Setup */ -#define PCMDFCR_RD_AL (BIT12) /* PX FIFO Alignment Control */ -#define PCMDFCR_RX_PAD (BIT13) /* PX FIFO Padding Control */ -#define PCMDFCR_RX_MSB (BIT14) /* RX FIFO First Bit Select */ - - -#endif /* __WMT_PCM_CONTROLLER_H */ diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.c b/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.c deleted file mode 100755 index 27a66bea..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.c +++ /dev/null @@ -1,597 +0,0 @@ -/*++ - * linux/sound/soc/wmt/wmt-pcm.c - * WonderMedia audio driver for ALSA - * - * Copyright c 2010 WonderMedia Technologies, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * WonderMedia Technologies, Inc. - * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C ---*/ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/platform_device.h> - -#include <linux/dma-mapping.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> -#include <linux/delay.h> - -#include <asm/dma.h> -#include "wmt-pcm-dma.h" -#include "wmt-soc.h" - -#define NULL_DMA ((dmach_t)(-1)) - -/* - * Debug - */ -#define AUDIO_NAME "WMT_PCM_DMA" -//#define WMT_PCM_DEBUG 1 -//#define WMT_PCM_DEBUG_DETAIL 1 - -#ifdef WMT_PCM_DEBUG -#define DPRINTK(format, arg...) \ - printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg) -#else -#define DPRINTK(format, arg...) do {} while (0) -#endif - -#ifdef WMT_PCM_DEBUG_DETAIL -#define DBG_DETAIL(format, arg...) \ - printk(KERN_INFO AUDIO_NAME ": [%s]" format "\n" , __FUNCTION__, ## arg) -#else -#define DBG_DETAIL(format, arg...) do {} while (0) -#endif - -#define err(format, arg...) \ - printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg) -#define info(format, arg...) \ - printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg) -#define warn(format, arg...) \ - printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg) - -static const struct snd_pcm_hardware wmt_pcm_dma_hardware = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_RESUME, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rate_min = 8000, - .rate_max = 16000, - .period_bytes_min = 32, - .period_bytes_max = 4 * 1024, - .periods_min = 1, - .periods_max = 32, - .buffer_bytes_max = 16 * 1024, -}; - -static int audio_dma_free(struct audio_stream_a *s); - -/* - * Main dma routine, requests dma according where you are in main alsa buffer - */ -static void audio_process_dma(struct audio_stream_a *s) -{ - struct snd_pcm_substream *substream = s->stream; - struct snd_pcm_runtime *runtime; - unsigned int dma_size; - unsigned int offset; - dma_addr_t dma_base; - int ret = 0; - - DPRINTK("s: %d, dmach: %d. active: %d", (int)s, s->dmach, s->active); - - if (s->active) { - substream = s->stream; - runtime = substream->runtime; - dma_size = frames_to_bytes(runtime, runtime->period_size); - - if (dma_size > MAX_DMA_SIZE) - dma_size = CUT_DMA_SIZE; - offset = dma_size * s->period; - - dma_base = __virt_to_phys((dma_addr_t)runtime->dma_area); - - if ((runtime->channels == 2 || runtime->channels == 1) && - (runtime->format == SNDRV_PCM_FORMAT_S16_LE)) { - ret = wmt_start_dma(s->dmach, runtime->dma_addr + offset, 0, dma_size); - } - - if (ret) { - printk(KERN_ERR "audio_process_dma: cannot queue DMA buffer (%i) \n", ret); - return; - } - - s->period++; - s->period %= runtime->periods; - s->periods++; - s->offset = offset; - } -} - -/* - * This is called when dma IRQ occurs at the end of each transmited block - */ -static void audio_dma_callback(void *data) -{ - struct audio_stream_a *s = data; - - //DBG_DETAIL(); - - /* - * If we are getting a callback for an active stream then we inform - * the PCM middle layer we've finished a period - */ - if (s->active) - snd_pcm_period_elapsed(s->stream); - - spin_lock(&s->dma_lock); - if (s->periods > 0) - s->periods--; - - audio_process_dma(s); - spin_unlock(&s->dma_lock); -} - -static int audio_dma_request(struct audio_stream_a *s, void (*callback) (void *)) -{ - int err; - err = 0; - - DBG_DETAIL(); - - //DPRINTK("s pointer: %d, dmach: %d, id: %s, dma_dev: %d", (int)s, s->dmach, s->id, s->dma_dev); - err = wmt_request_dma(&s->dmach, s->id, s->dma_dev, callback, s); - if (err < 0) - printk(KERN_ERR "Unable to grab audio dma 0x%x\n", s->dmach); - - return err; -} - -static void audio_setup_dma(struct audio_stream_a *s, int stream_id) -{ - struct snd_pcm_runtime *runtime = s->stream->runtime; - - if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { - /* From memory to device */ - switch (runtime->channels * runtime->format) { - case 1: - s->dma_cfg.DefaultCCR = PCM_TX_DMA_8BITS_CFG; /* setup 1 bytes*/ - break ; - case 2: - s->dma_cfg.DefaultCCR = PCM_TX_DMA_16BITS_CFG; /* setup 2 bytes*/ - break ; - case 4: - s->dma_cfg.DefaultCCR = PCM_TX_DMA_32BITS_CFG; /* setup 4 byte*/ - break ; - } - } - else { - /* From device to memory */ - switch (runtime->channels * runtime->format) { - case 1: - s->dma_cfg.DefaultCCR = PCM_RX_DMA_8BITS_CFG ; /* setup 1 bytes*/ - break ; - case 2: - s->dma_cfg.DefaultCCR = PCM_RX_DMA_16BITS_CFG ; /* setup 2 bytes*/ - break ; - case 4: - s->dma_cfg.DefaultCCR = PCM_RX_DMA_32BITS_CFG ; /* setup 4 byte*/ - break ; - } - } - - s->dma_cfg.ChunkSize = 1; - - wmt_setup_dma(s->dmach, s->dma_cfg) ; -} - -static int audio_dma_free(struct audio_stream_a *s) -{ - int err = 0; - DBG_DETAIL(); - wmt_free_dma(s->dmach); - s->dmach = NULL_DMA; - return err; -} - -/* - * this stops the dma and clears the dma ptrs - */ -static void audio_stop_dma(struct audio_stream_a *s) -{ - //dump_stack(); - unsigned long flags; - DBG_DETAIL(); - local_irq_save(flags); - s->active = 0; - s->period = 0; - s->periods = 0; - s->offset = 0; - wmt_stop_dma(s->dmach); - wmt_clear_dma(s->dmach); - local_irq_restore(flags); -} - -/* this may get called several times by oss emulation */ -static int wmt_pcm_dma_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - //dump_stack(); - struct snd_pcm_runtime *runtime = substream->runtime; - int err = 0; - DBG_DETAIL(); - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - runtime->dma_bytes = params_buffer_bytes(params); - return err; -} - -static int wmt_pcm_dma_hw_free(struct snd_pcm_substream *substream) -{ - DBG_DETAIL(); - snd_pcm_set_runtime_buffer(substream, NULL); - return 0; -} - -static int wmt_pcm_dma_prepare(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int stream_id = substream->pstr->stream; - struct audio_stream_a *prtd = runtime->private_data; - struct audio_stream_a *s = &prtd[stream_id]; - //dump_stack(); - DBG_DETAIL(); - - s->period = 0; - s->periods = 0; - s->offset = 0; - audio_setup_dma(s, stream_id); - - return 0; -} - -static int wmt_pcm_dma_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int stream_id = substream->pstr->stream; - struct audio_stream_a *prtd = runtime->private_data; - struct audio_stream_a *s = &prtd[stream_id]; - int ret = 0; - - DPRINTK("Enter, cmd=%d", cmd); - //dump_stack(); - spin_lock(&s->dma_lock); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - s->active = 1; - audio_process_dma(s); - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - s->active = 0; - audio_stop_dma(s); - break; - default: - ret = -EINVAL; - } - spin_unlock(&s->dma_lock); - - return ret; -} - -static snd_pcm_uframes_t wmt_pcm_dma_pointer(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct audio_stream_a *prtd = runtime->private_data; - int stream_id = substream->pstr->stream; - struct audio_stream_a *s = &prtd[stream_id]; - dma_addr_t ptr; - snd_pcm_uframes_t offset = 0; - //dump_stack(); - ptr = wmt_get_dma_pos(s->dmach); - - if ((runtime->channels == 1 || runtime->channels == 2) && (runtime->format == SNDRV_PCM_FORMAT_S16_LE)) { - offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); - } - - if (offset >= runtime->buffer_size) - offset = 0; - - spin_lock(&s->dma_lock); - - if (s->periods > 0 && s->periods < 2) { - if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { - if (snd_pcm_playback_hw_avail(runtime) >= 2 * runtime->period_size) - audio_process_dma(s); - } - else { - if (snd_pcm_capture_hw_avail(runtime) >= 2* runtime->period_size) - audio_process_dma(s); - } - - } - spin_unlock(&s->dma_lock); - - return offset; -} - -static int wmt_pcm_dma_open(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_pcm_runtime *runtime = substream->runtime; - struct audio_stream_a *s = runtime->private_data; - int ret; - - DBG_DETAIL(); - - if (!cpu_dai->active) { - audio_dma_request(&s[0], audio_dma_callback); - audio_dma_request(&s[1], audio_dma_callback); - } - //dump_stack(); - snd_soc_set_runtime_hwparams(substream, &wmt_pcm_dma_hardware); - - /* 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) - goto out; - -out: - return ret; -} - -static int wmt_pcm_dma_close(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_pcm_runtime *runtime = substream->runtime; - struct audio_stream_a *s = runtime->private_data; - - DBG_DETAIL(); - //dump_stack(); - if (!cpu_dai->active) { - audio_dma_free(&s[0]); - audio_dma_free(&s[1]); - } - - return 0; -} - -static int wmt_pcm_dma_mmap(struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - DBG_DETAIL(); - //dump_stack(); - return dma_mmap_writecombine(substream->pcm->card->dev, vma, - runtime->dma_area, - runtime->dma_addr, - runtime->dma_bytes); -} - -static struct snd_pcm_ops wmt_pcm_dma_ops = { - .open = wmt_pcm_dma_open, - .close = wmt_pcm_dma_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = wmt_pcm_dma_hw_params, - .hw_free = wmt_pcm_dma_hw_free, - .prepare = wmt_pcm_dma_prepare, - .trigger = wmt_pcm_dma_trigger, - .pointer = wmt_pcm_dma_pointer, - .mmap = wmt_pcm_dma_mmap, -}; - -static u64 wmt_pcm_dma_dmamask = DMA_BIT_MASK(32); - -static int wmt_pcm_dma_preallocate_dma_buffer(struct snd_pcm *pcm, - int stream) -{ - struct snd_pcm_substream *substream = pcm->streams[stream].substream; - struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = wmt_pcm_dma_hardware.buffer_bytes_max; - - DBG_DETAIL(); - - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = pcm->card->dev; - buf->private_data = NULL; - buf->area = dma_alloc_writecombine(pcm->card->dev, size, - &buf->addr, GFP_KERNEL); - - DPRINTK("buf_area = %x, buf_addr = %x", (unsigned int)buf->area, buf->addr); - if (!buf->area) - return -ENOMEM; - - buf->bytes = size; - - return 0; -} - -static void wmt_pcm_dma_free_dma_buffers(struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - int stream; - - DBG_DETAIL(); - - for (stream = 0; stream < 2; stream++) { - substream = pcm->streams[stream].substream; - if (!substream) - continue; - - buf = &substream->dma_buffer; - if (!buf->area) - continue; - - dma_free_writecombine(pcm->card->dev, buf->bytes, buf->area, buf->addr); - - buf->area = NULL; - } -} - -static int wmt_pcm_dma_new(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_card *card = rtd->card->snd_card; - struct snd_pcm *pcm = rtd->pcm; - int ret = 0; - - DBG_DETAIL(); - - if (!card->dev->dma_mask) - card->dev->dma_mask = &wmt_pcm_dma_dmamask; - if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - - if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { - ret = wmt_pcm_dma_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - if (ret) - goto out; - } - - if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { - ret = wmt_pcm_dma_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) - goto out; - } - -out: - /* free preallocated buffers in case of error */ - if (ret) - wmt_pcm_dma_free_dma_buffers(pcm); - - return ret; -} - -#ifdef CONFIG_PM -static int wmt_pcm_dma_suspend(struct snd_soc_dai *dai) -{ - struct snd_pcm_runtime *runtime = dai->runtime; - struct audio_stream_a *prtd; - struct audio_stream_a *s; - - DBG_DETAIL(); - - if (!runtime) - return 0; - - prtd = runtime->private_data; - s = &prtd[SNDRV_PCM_STREAM_PLAYBACK]; - - if (s->active) { - udelay(5); - wmt_stop_dma(s->dmach); - /* - wmt_clear_dma(s->dmach); - audio_stop_dma(s); - */ - } - - s = &prtd[SNDRV_PCM_STREAM_CAPTURE]; - - if (s->active) { - udelay(5); - wmt_stop_dma(s->dmach); - /* - wmt_clear_dma(s->dmach); - audio_stop_dma(s); - */ - } - - return 0; -} - -static int wmt_pcm_dma_resume(struct snd_soc_dai *dai) -{ - struct snd_pcm_runtime *runtime = dai->runtime; - struct audio_stream_a *prtd; - struct audio_stream_a *s; - - DBG_DETAIL(); - - if (!runtime) - return 0; - - prtd = runtime->private_data; - s = &prtd[SNDRV_PCM_STREAM_PLAYBACK]; - audio_setup_dma(s, SNDRV_PCM_STREAM_PLAYBACK); - - if (s->active) { - wmt_resume_dma(s->dmach) ; - } - - s = &prtd[SNDRV_PCM_STREAM_CAPTURE]; - audio_setup_dma(s, SNDRV_PCM_STREAM_CAPTURE); - - if (s->active) { - wmt_resume_dma(s->dmach) ; - } - - return 0; -} -#else -#define wmt_pcm_dma_suspend NULL -#define wmt_pcm_dma_resume NULL -#endif - -static struct snd_soc_platform_driver wmt_soc_platform = { - .ops = &wmt_pcm_dma_ops, - .pcm_new = wmt_pcm_dma_new, - .pcm_free = wmt_pcm_dma_free_dma_buffers, - .suspend = wmt_pcm_dma_suspend, - .resume = wmt_pcm_dma_resume, -}; - -static int __devinit wmt_pcm_dma_platform_probe(struct platform_device *pdev) -{ - DBG_DETAIL(); - return snd_soc_register_platform(&pdev->dev, &wmt_soc_platform); -} - -static int __devexit wmt_pcm_dma_platform_remove(struct platform_device *pdev) -{ - DBG_DETAIL(); - snd_soc_unregister_platform(&pdev->dev); - return 0; -} - -static struct platform_driver wmt_pcm_dma_driver = { - .driver = { - .name = "wmt-pcm-dma", - .owner = THIS_MODULE, - }, - - .probe = wmt_pcm_dma_platform_probe, - .remove = __devexit_p(wmt_pcm_dma_platform_remove), -}; - -module_platform_driver(wmt_pcm_dma_driver); - -MODULE_AUTHOR("WonderMedia Technologies, Inc."); -MODULE_DESCRIPTION("WMT [ALSA SoC/pcm dma] driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.h b/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.h deleted file mode 100755 index 88f246b2..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm-dma.h +++ /dev/null @@ -1,35 +0,0 @@ -/*++ - * linux/sound/soc/wmt/wmt-pcm.h - * WonderMedia audio driver for ALSA - * - * Copyright c 2010 WonderMedia Technologies, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * WonderMedia Technologies, Inc. - * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C ---*/ - - -#ifndef __WMT_PCM_DMA_H__ -#define __WMT_PCM_DMA_H__ - -struct wmt_pcm_dma_data { - char *name; /* stream identifier */ - int dma_req; /* DMA request line */ - unsigned long port_addr; /* transmit/receive register */ - struct dma_device_cfg_s *dma_cfg; -}; - -#endif /* __WMT_PDM_PCM_H__ */ diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm.c b/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm.c deleted file mode 100755 index 848ea5a1..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm.c +++ /dev/null @@ -1,767 +0,0 @@ -/*++ - * linux/sound/soc/wmt/wmt-pcm.c - * WonderMedia audio driver for ALSA - * - * Copyright c 2010 WonderMedia Technologies, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * WonderMedia Technologies, Inc. - * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C ---*/ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/platform_device.h> - -#include <linux/dma-mapping.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> -#include <linux/delay.h> - -#include <asm/dma.h> -#include "wmt-pcm.h" -#include "wmt-soc.h" - -#define NULL_DMA ((dmach_t)(-1)) - -#define AUDIO_NAME "WMT_PCM" -//#define WMT_PCM_DEBUG 1 -//#define WMT_PCM_DEBUG_DETAIL 1 - -#ifdef WMT_PCM_DEBUG -#define DPRINTK(format, arg...) \ - printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg) -#else -#define DPRINTK(format, arg...) do {} while (0) -#endif - -#ifdef WMT_PCM_DEBUG_DETAIL -#define DBG_DETAIL(format, arg...) \ - printk(KERN_INFO AUDIO_NAME ": [%s]" format "\n" , __FUNCTION__, ## arg) -#else -#define DBG_DETAIL(format, arg...) do {} while (0) -#endif - -#define err(format, arg...) \ - printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg) -#define info(format, arg...) \ - printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg) -#define warn(format, arg...) \ - printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg) - -static const struct snd_pcm_hardware wmt_pcm_hardware = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_RESUME, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rate_min = 8000, - .rate_max = 96000, - .period_bytes_min = 4*1024,//32, - .period_bytes_max = 8*1024,//4 * 1024, - .periods_min = 1,//2, - .periods_max = 16,//128, - .buffer_bytes_max = 64 * 1024, - .fifo_size = 32,// -}; - -struct wmt_runtime_data { - spinlock_t lock; - struct wmt_pcm_dma_data *dma_data; - int dma_ch; - int period_index; -}; - -struct snd_wfd_buffer { - struct device *dev; - unsigned char *area; /* virtual pointer */ - dma_addr_t addr; /* physical address */ - size_t bytes; /* buffer size in bytes */ - size_t valuable_sz; /* valuable size in wfd buffer */ - unsigned char *wr_ptr; - unsigned char *rd_ptr; - int enable; -}; -static struct snd_wfd_buffer wfd_audbuf; - -static int audio_dma_free(struct audio_stream_a *s); - -dmach_t pcm_out_dmach = 0xFF; -struct dma_device_cfg_s *pcm_out_dma_cfg = NULL; - -void wmt_pcm_wfd_start(void) -{ - /* allocate buffer for WFD support */ - wfd_audbuf.area = dma_alloc_writecombine(wfd_audbuf.dev, wfd_audbuf.bytes, - &wfd_audbuf.addr, GFP_KERNEL); - - if (!wfd_audbuf.area) { - err("WFD_Aud allocate buffer fail"); - } - else { - info("*WFD_Aud enable"); - wfd_audbuf.enable = 1; - } - - memset(wfd_audbuf.area, 0x0, wfd_audbuf.bytes); - //info("&wfd_audbuf.addr=0x%x wfd_audbuf.addr=0x%x", &wfd_audbuf.addr, (unsigned int)wfd_audbuf.addr); -} -EXPORT_SYMBOL(wmt_pcm_wfd_start); - -unsigned int wmt_pcm_wfd_get_buf(void) -{ - wfd_audbuf.valuable_sz = 0; - wfd_audbuf.wr_ptr = wfd_audbuf.rd_ptr = wfd_audbuf.area; - return (unsigned int)&wfd_audbuf.addr; -} -EXPORT_SYMBOL(wmt_pcm_wfd_get_buf); - -void wmt_pcm_wfd_stop(void) -{ - wfd_audbuf.wr_ptr = wfd_audbuf.area; - wfd_audbuf.enable = 0; - - dma_free_writecombine(wfd_audbuf.dev, wfd_audbuf.bytes, - wfd_audbuf.area, wfd_audbuf.addr); - info("*WFD_Aud disable"); - return; -} -EXPORT_SYMBOL(wmt_pcm_wfd_stop); - -int wmt_pcm_wfd_get_strm(WFDStrmInfo_t *info) -{ - if ((info->req_sz > wfd_audbuf.bytes) || (!wfd_audbuf.valuable_sz)) { - //info("WFD read size=%d, Too Large!", info->req_sz); - info->avail_sz = 0; - return (int)info; - } - else if (wfd_audbuf.valuable_sz > info->req_sz) { - info->avail_sz = info->req_sz; - wfd_audbuf.valuable_sz -= info->req_sz; - } - else { - info->avail_sz = wfd_audbuf.valuable_sz; - wfd_audbuf.valuable_sz = 0; - } - - info->buf_offset = wfd_audbuf.rd_ptr - wfd_audbuf.area; - wfd_audbuf.rd_ptr += info->avail_sz; - - if (wfd_audbuf.rd_ptr >= wfd_audbuf.area + wfd_audbuf.bytes) - wfd_audbuf.rd_ptr = wfd_audbuf.rd_ptr - wfd_audbuf.bytes; - - return (int)info; -} -EXPORT_SYMBOL(wmt_pcm_wfd_get_strm); - -void wmt_pcm_wfd_update(char *src_buf, unsigned int chunksize) -{ - //info("wmt_pcm_wfd_update, 0x%x", src_buf[1024]); - memcpy(wfd_audbuf.wr_ptr, src_buf, chunksize); - wfd_audbuf.wr_ptr += chunksize; - - if (wfd_audbuf.wr_ptr == wfd_audbuf.area + wfd_audbuf.bytes) - wfd_audbuf.wr_ptr = wfd_audbuf.area; - - wfd_audbuf.valuable_sz += chunksize; - if (wfd_audbuf.valuable_sz >= wfd_audbuf.bytes) { - wfd_audbuf.valuable_sz = wfd_audbuf.bytes; - wfd_audbuf.rd_ptr = wfd_audbuf.wr_ptr; - } -} - -/* - * Main dma routine, requests dma according where you are in main alsa buffer - */ -static void audio_process_dma(struct audio_stream_a *s) -{ - struct snd_pcm_substream *substream = s->stream; - struct snd_pcm_runtime *runtime; - unsigned int dma_size; - unsigned int offset; - dma_addr_t dma_base; - int ret = 0; - - //DBG_DETAIL(); - DPRINTK("s: %d, dmach: %d. active: %d", (int)s, s->dmach, s->active); - - if (s->active) { - substream = s->stream; - runtime = substream->runtime; - dma_size = frames_to_bytes(runtime, runtime->period_size); - /*DPRINTK("frame_bits=%d, period_size=%d, dma_size 1=%d", - runtime->frame_bits, (int)runtime->period_size, dma_size);*/ - if (dma_size > MAX_DMA_SIZE) - dma_size = CUT_DMA_SIZE; - offset = dma_size * s->period; - - /*DPRINTK("offset: 0x%x, ->dma_area: 0x%x, ->dma_addr: 0x%x, final addr: 0x%x", - offset, (unsigned int)runtime->dma_area, runtime->dma_addr, runtime->dma_addr+offset);*/ - - dma_base = __virt_to_phys((dma_addr_t)runtime->dma_area); - - //DPRINTK("dma address: 0x%x", dma_base+offset); - /*DPRINTK("hw_ptr_interrupt: 0x%x, state: %d, hwptr: %u, applptr: %u, avail_min: %u", - (unsigned int)runtime->hw_ptr_interrupt, runtime->status->state, (unsigned int)runtime->status->hw_ptr, - (unsigned int)runtime->control->appl_ptr, (unsigned int)runtime->control->avail_min);*/ - //DPRINTK("dmach: %u, dma_addr: %x, dma_size: %u", s->dmach, dma_base+offset, dma_size); - - if ((runtime->channels == 2 || runtime->channels == 1) && - (runtime->format == SNDRV_PCM_FORMAT_S16_LE)) { - ret = wmt_start_dma(s->dmach, runtime->dma_addr + offset, 0, dma_size); - } - - if (ret) { - printk(KERN_ERR "audio_process_dma: cannot queue DMA buffer (%i) \n", ret); - return; - } - - s->period++; - s->period %= runtime->periods; - s->periods++; - s->offset = offset; - } -} - -/* - * This is called when dma IRQ occurs at the end of each transmited block - */ -static void audio_dma_callback(void *data) -{ - struct audio_stream_a *s = data; - struct snd_pcm_substream *substream; - struct snd_pcm_runtime *runtime; - unsigned int dma_size; - unsigned int offset; - int stream_id; - - //DBG_DETAIL(); - - substream = s->stream; - runtime = substream->runtime; - dma_size = frames_to_bytes(runtime, runtime->period_size); - stream_id = substream->pstr->stream; - - if (s->period > 0) - offset = dma_size * (s->period - 1); - else - offset = dma_size * (s->periods - 1); - - if ((stream_id == SNDRV_PCM_STREAM_PLAYBACK) && (wfd_audbuf.enable)) { - wmt_pcm_wfd_update(runtime->dma_area + offset, dma_size); - } - - /* - * If we are getting a callback for an active stream then we inform - * the PCM middle layer we've finished a period - */ - if (s->active) - snd_pcm_period_elapsed(s->stream); - - spin_lock(&s->dma_lock); - if (s->periods > 0) - s->periods--; - - audio_process_dma(s); - spin_unlock(&s->dma_lock); -} - -static int audio_dma_request(struct audio_stream_a *s, void (*callback) (void *)) -{ - int err; - err = 0; - - DBG_DETAIL(); - - //DPRINTK("s pointer: %d, dmach: %d, id: %s, dma_dev: %d", (int)s, s->dmach, s->id, s->dma_dev); - err = wmt_request_dma(&s->dmach, s->id, s->dma_dev, callback, s); - if (err < 0) - printk(KERN_ERR "Unable to grab audio dma 0x%x\n", s->dmach); - - if (!strcmp(s->id, "WMT I2S out")) { - pcm_out_dmach = s->dmach; - } - return err; -} - -static void audio_setup_dma(struct audio_stream_a *s, int stream_id) -{ - struct snd_pcm_runtime *runtime = s->stream->runtime; - - if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { - /* From memory to device */ - switch (runtime->channels * runtime->format) { - #if 0 //comment 2014-1-3 tinyplay mono pattern abnormal - case 1: - s->dma_cfg.DefaultCCR = I2S_TX_DMA_8BITS_CFG; /* setup 1 bytes*/ - break ; - case 2: - s->dma_cfg.DefaultCCR = I2S_TX_DMA_16BITS_CFG; /* setup 2 bytes*/ - break ; - case 4: - #endif - default : - s->dma_cfg.DefaultCCR = I2S_TX_DMA_32BITS_CFG; /* setup 4 byte*/ - break ; - } - } - else { - /* From device to memory */ - switch (runtime->channels * runtime->format) { - case 1: - s->dma_cfg.DefaultCCR = I2S_RX_DMA_8BITS_CFG ; /* setup 1 bytes*/ - break ; - case 2: - s->dma_cfg.DefaultCCR = I2S_RX_DMA_16BITS_CFG ; /* setup 2 bytes*/ - break ; - case 4: - s->dma_cfg.DefaultCCR = I2S_RX_DMA_32BITS_CFG ; /* setup 4 byte*/ - break ; - } - } - - s->dma_cfg.ChunkSize = 1; - if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { - pcm_out_dma_cfg = &s->dma_cfg; - } - - //DPRINTK("s pointer: %d. audio dma %d cfg.DefaultCCR 0x%x ", (int)s, s->dmach, (unsigned int)s->dma_cfg.DefaultCCR); - //DPRINTK("cfg.ChunkSize 0x%x ", s->dma_cfg.ChunkSize); - wmt_setup_dma(s->dmach, s->dma_cfg) ; -} - -static int audio_dma_free(struct audio_stream_a *s) -{ - int err = 0; - DBG_DETAIL(); - wmt_free_dma(s->dmach); - s->dmach = NULL_DMA; - pcm_out_dma_cfg = NULL; - return err; -} - -/* - * this stops the dma and clears the dma ptrs - */ -static void audio_stop_dma(struct audio_stream_a *s) -{ - unsigned long flags; - DBG_DETAIL(); - local_irq_save(flags); - s->active = 0; - s->period = 0; - s->periods = 0; - s->offset = 0; - s->last_offset = 0; - wmt_stop_dma(s->dmach); - wmt_clear_dma(s->dmach); - local_irq_restore(flags); -} - -/* this may get called several times by oss emulation */ -static int wmt_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int err = 0; - DBG_DETAIL(); - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - runtime->dma_bytes = params_buffer_bytes(params); - return err; -} - -static int wmt_pcm_hw_free(struct snd_pcm_substream *substream) -{ - DBG_DETAIL(); - snd_pcm_set_runtime_buffer(substream, NULL); - return 0; -} - -static int wmt_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int stream_id = substream->pstr->stream; - struct audio_stream_a *prtd = runtime->private_data; - struct audio_stream_a *s = &prtd[stream_id]; - - DBG_DETAIL(); - - s->period = 0; - s->periods = 0; - s->offset = 0; - s->last_offset = 0; - audio_setup_dma(s, stream_id); - - return 0; -} - -static int wmt_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int stream_id = substream->pstr->stream; - struct audio_stream_a *prtd = runtime->private_data; - struct audio_stream_a *s = &prtd[stream_id]; - int ret = 0; - - DPRINTK("wmt_pcm_trigger Enter, cmd=%d", cmd); - - spin_lock(&s->dma_lock); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - s->active = 1; - audio_process_dma(s); - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - s->active = 0; - audio_stop_dma(s); - break; - default: - ret = -EINVAL; - } - spin_unlock(&s->dma_lock); - - return ret; -} - -static snd_pcm_uframes_t wmt_pcm_pointer(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct audio_stream_a *prtd = runtime->private_data; - int stream_id = substream->pstr->stream; - struct audio_stream_a *s = &prtd[stream_id]; - dma_addr_t ptr; - snd_pcm_uframes_t offset = 0; - - ptr = wmt_get_dma_pos(s->dmach); - - if ((runtime->channels == 1 || runtime->channels == 2) && (runtime->format == SNDRV_PCM_FORMAT_S16_LE)) { - offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); - } - - if ((offset < s->last_offset) && ((s->last_offset - offset) < runtime->period_size) && - (s->last_offset != runtime->buffer_size)) { - snd_pcm_uframes_t old_offset = offset; - if (s->last_offset < runtime->period_size) - offset = runtime->period_size; - else { - offset = runtime->period_size * - ((s->last_offset / runtime->period_size) + 1); - } - printk("last_offset %d, old offset %d, new offset %d\n", (int)s->last_offset, (int)old_offset, (int)offset); - } - s->last_offset = offset; - - if (offset >= runtime->buffer_size) - offset = 0; - - spin_lock(&s->dma_lock); - - if (s->periods > 0 && s->periods < 3) { - if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { - if (snd_pcm_playback_hw_avail(runtime) >= 3 * runtime->period_size) - audio_process_dma(s); - } - else { - if (snd_pcm_capture_hw_avail(runtime) >= 3* runtime->period_size) - audio_process_dma(s); - } - - } - spin_unlock(&s->dma_lock); - - //DPRINTK("offset = %x", (unsigned int)offset); - return offset; -} - -static int wmt_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_pcm_runtime *runtime = substream->runtime; - struct audio_stream_a *s = runtime->private_data; - int ret; - - DBG_DETAIL(); - - if (!cpu_dai->active) { - audio_dma_request(&s[0], audio_dma_callback); - audio_dma_request(&s[1], audio_dma_callback); - } - - snd_soc_set_runtime_hwparams(substream, &wmt_pcm_hardware); - - /* 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) - goto out; - -out: - return ret; -} - -static int wmt_pcm_close(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_pcm_runtime *runtime = substream->runtime; - struct audio_stream_a *s = runtime->private_data; - - DBG_DETAIL(); - - if (!cpu_dai->active) { - audio_dma_free(&s[0]); - audio_dma_free(&s[1]); - } - - return 0; -} - -static int wmt_pcm_mmap(struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - DBG_DETAIL(); - - return dma_mmap_writecombine(substream->pcm->card->dev, vma, - runtime->dma_area, - runtime->dma_addr, - runtime->dma_bytes); -} - -static struct snd_pcm_ops wmt_pcm_ops = { - .open = wmt_pcm_open, - .close = wmt_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = wmt_pcm_hw_params, - .hw_free = wmt_pcm_hw_free, - .prepare = wmt_pcm_prepare, - .trigger = wmt_pcm_trigger, - .pointer = wmt_pcm_pointer, - .mmap = wmt_pcm_mmap, -}; - -static u64 wmt_pcm_dmamask = DMA_BIT_MASK(32); - -static int wmt_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, - int stream) -{ - struct snd_pcm_substream *substream = pcm->streams[stream].substream; - struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = wmt_pcm_hardware.buffer_bytes_max; - - DBG_DETAIL(); - - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = pcm->card->dev; - buf->private_data = NULL; - buf->area = dma_alloc_writecombine(pcm->card->dev, size, - &buf->addr, GFP_KERNEL); - - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - info("stream = %d, buf_addr = %x", stream, buf->addr); - - wfd_audbuf.bytes = size; - wfd_audbuf.dev = pcm->card->dev; - wfd_audbuf.enable = 0; - } - - if (!buf->area) - return -ENOMEM; - - buf->bytes = size; - - return 0; -} - -static void wmt_pcm_free_dma_buffers(struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - int stream; - - DBG_DETAIL(); - - for (stream = 0; stream < 2; stream++) { - substream = pcm->streams[stream].substream; - if (!substream) - continue; - - buf = &substream->dma_buffer; - if (!buf->area) - continue; - - dma_free_writecombine(pcm->card->dev, buf->bytes, buf->area, buf->addr); - - buf->area = NULL; - } -} - -int wmt_pcm_new(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_card *card = rtd->card->snd_card; - struct snd_pcm *pcm = rtd->pcm; - int ret = 0; - - DBG_DETAIL(); - - if (!card->dev->dma_mask) - card->dev->dma_mask = &wmt_pcm_dmamask; - if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - - if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { - ret = wmt_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - if (ret) - goto out; - } - - if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { - ret = wmt_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) - goto out; - } - -out: - /* free preallocated buffers in case of error */ - if (ret) - wmt_pcm_free_dma_buffers(pcm); - - return ret; -} - -#ifdef CONFIG_PM -static int wmt_pcm_suspend(struct snd_soc_dai *dai) -{ - struct snd_pcm_runtime *runtime = dai->runtime; - struct audio_stream_a *prtd; - struct audio_stream_a *s; - - DBG_DETAIL(); - - if (!runtime) - return 0; - - prtd = runtime->private_data; - s = &prtd[SNDRV_PCM_STREAM_PLAYBACK]; - - if (s->active) { - udelay(5); - wmt_stop_dma(s->dmach); - /* - wmt_clear_dma(s->dmach); - audio_stop_dma(s); - */ - } - - s = &prtd[SNDRV_PCM_STREAM_CAPTURE]; - - if (s->active) { - udelay(5); - wmt_stop_dma(s->dmach); - /* - wmt_clear_dma(s->dmach); - audio_stop_dma(s); - */ - } - - return 0; -} - -static int wmt_pcm_resume(struct snd_soc_dai *dai) -{ - struct snd_pcm_runtime *runtime = dai->runtime; - struct audio_stream_a *prtd; - struct audio_stream_a *s; - - DBG_DETAIL(); - - if (!runtime) { - if ((pcm_out_dmach != 0xFF) && (pcm_out_dma_cfg != NULL)) { - wmt_setup_dma(pcm_out_dmach, *pcm_out_dma_cfg); - } - return 0; - } - - prtd = runtime->private_data; - s = &prtd[SNDRV_PCM_STREAM_PLAYBACK]; - audio_setup_dma(s, SNDRV_PCM_STREAM_PLAYBACK); - - if (s->active) { - wmt_resume_dma(s->dmach) ; - } - - s = &prtd[SNDRV_PCM_STREAM_CAPTURE]; - audio_setup_dma(s, SNDRV_PCM_STREAM_CAPTURE); - - if (s->active) { - wmt_resume_dma(s->dmach) ; - } - - return 0; -} -#else -#define wmt_pcm_suspend NULL -#define wmt_pcm_resume NULL -#endif - -static struct snd_soc_platform_driver wmt_soc_platform = { - .ops = &wmt_pcm_ops, - .pcm_new = wmt_pcm_new, - .pcm_free = wmt_pcm_free_dma_buffers, - .suspend = wmt_pcm_suspend, - .resume = wmt_pcm_resume, -}; - -static int __devinit wmt_pcm_platform_probe(struct platform_device *pdev) -{ - DBG_DETAIL(); - - return snd_soc_register_platform(&pdev->dev, &wmt_soc_platform); -} - -static int __devexit wmt_pcm_platform_remove(struct platform_device *pdev) -{ - DBG_DETAIL(); - - snd_soc_unregister_platform(&pdev->dev); - return 0; -} - -static struct platform_driver wmt_pcm_driver = { - .driver = { - .name = "wmt-audio-pcm", - .owner = THIS_MODULE, - }, - - .probe = wmt_pcm_platform_probe, - .remove = __devexit_p(wmt_pcm_platform_remove), -}; - -module_platform_driver(wmt_pcm_driver); - -MODULE_AUTHOR("WonderMedia Technologies, Inc."); -MODULE_DESCRIPTION("WMT [ALSA SoC/pcm] driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm.h b/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm.h deleted file mode 100755 index 90ad7747..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/wmt-pcm.h +++ /dev/null @@ -1,46 +0,0 @@ -/*++ - * linux/sound/soc/wmt/wmt-pcm.h - * WonderMedia audio driver for ALSA - * - * Copyright c 2010 WonderMedia Technologies, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * WonderMedia Technologies, Inc. - * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C ---*/ - - -#ifndef __WMT_PCM_H__ -#define __WMT_PCM_H__ - -struct wmt_pcm_dma_data { - char *name; /* stream identifier */ - int dma_req; /* DMA request line */ - unsigned long port_addr; /* transmit/receive register */ - struct dma_device_cfg_s *dma_cfg; -}; - -typedef struct WFDStrmInfo { - unsigned int req_sz; - unsigned int avail_sz; - unsigned int buf_offset; -} WFDStrmInfo_t; - -extern void wmt_pcm_wfd_start(void); -extern unsigned int wmt_pcm_wfd_get_buf(void); -extern void wmt_pcm_wfd_stop(void); -extern int wmt_pcm_wfd_get_strm(WFDStrmInfo_t *info); - -#endif diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-soc.c b/ANDROID_3.4.5/sound/soc/wmt/wmt-soc.c deleted file mode 100755 index f62e993d..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/wmt-soc.c +++ /dev/null @@ -1,321 +0,0 @@ -/*++ - * linux/sound/soc/wmt/wmt-soc.c - * WonderMedia audio driver for ALSA - * - * Copyright c 2010 WonderMedia Technologies, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * WonderMedia Technologies, Inc. - * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C ---*/ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/device.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> -#include <sound/soc-dapm.h> -#include <sound/hwdep.h> - -#include <asm/mach-types.h> -#include <mach/hardware.h> - -#include "wmt-soc.h" -#include "wmt-pcm.h" -#include "wmt_hwdep.h" -#include "../codecs/wmt_vt1602.h" -#include "../codecs/vt1603.h" - -extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen); -extern void wmt_set_i2s_share_pin(); -char wmt_codec_name[80]; -char wmt_dai_name[80]; -char wmt_rate[10]; - -#define AUDIO_NAME "WMT_SOC" -//#define WMT_SOC_DEBUG 1 -//#define WMT_SOC_DEBUG_DETAIL 1 - -#ifdef WMT_SOC_DEBUG -#define DPRINTK(format, arg...) \ - printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg) -#else -#define DPRINTK(format, arg...) do {} while (0) -#endif - -#ifdef WMT_SOC_DEBUG_DETAIL -#define DBG_DETAIL(format, arg...) \ - printk(KERN_INFO AUDIO_NAME ": [%s]" format "\n" , __FUNCTION__, ## arg) -#else -#define DBG_DETAIL(format, arg...) do {} while (0) -#endif - -#define err(format, arg...) \ - printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg) -#define info(format, arg...) \ - printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg) -#define warn(format, arg...) \ - printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg) - -#define WMT_I2S_RATES SNDRV_PCM_RATE_8000_96000 - -static struct snd_soc_card snd_soc_machine_wmt; - -static int wmt_soc_primary_startup(struct snd_pcm_substream *substream) -{ - DBG_DETAIL(); - return 0; -} - -static void wmt_soc_primary_shutdown(struct snd_pcm_substream *substream) -{ - DBG_DETAIL(); -} - -static int wmt_soc_primary_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 ret = 0; - - DBG_DETAIL(); - - if (strcmp(wmt_codec_name, "hwdac")) { - /* Set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_CBS_CFS | - SND_SOC_DAIFMT_I2S |SND_SOC_DAIFMT_NB_NF); - if (ret < 0) - return ret; - } - - - /* Set cpu DAI configuration for I2S */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S - |SND_SOC_DAIFMT_MASTER_MASK | SND_SOC_DAIFMT_NB_NF); - if (ret < 0) - return ret; - - if ((!strcmp(wmt_codec_name, "vt1602")) || (!strcmp(wmt_codec_name, "vt1603"))) { - /* Set the codec system clock for DAC and ADC */ - if (!(params_rate(params) % 11025)) { - ret = snd_soc_dai_set_sysclk(codec_dai, 0, 11289600, - SND_SOC_CLOCK_IN); - } - else { - ret = snd_soc_dai_set_sysclk(codec_dai, 0, 12288000, - SND_SOC_CLOCK_IN); - } - } - - return ret; -} - -static int wmt_soc_second_startup(struct snd_pcm_substream *substream) -{ - //dump_stack(); - DBG_DETAIL(); - return 0; -} - -static void wmt_soc_second_shutdown(struct snd_pcm_substream *substream) -{ - //dump_stack(); - DBG_DETAIL(); -} - -static int wmt_soc_second_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - //dump_stack(); - DBG_DETAIL(); - return 0; -} - -static int wmt_soc_dai_init(struct snd_soc_pcm_runtime *rtd) -{ - DBG_DETAIL(); - wmt_soc_hwdep_new(rtd->codec); - return 0; -} - -static int wmt_suspend_pre(struct snd_soc_card *card) -{ - snd_soc_dapm_disable_pin(&card->rtd->codec->dapm, "Left HP"); - snd_soc_dapm_disable_pin(&card->rtd->codec->dapm, "Right HP"); - snd_soc_dapm_disable_pin(&card->rtd->codec->dapm, "Left SPK"); - snd_soc_dapm_disable_pin(&card->rtd->codec->dapm, "Right SPK"); -} - -static int wmt_suspend_post(struct snd_soc_card *card) -{ - DBG_DETAIL(); - - /* Disable BIT15:I2S clock, BIT4:ARFP clock, BIT3:ARF clock */ - PMCEU_VAL &= ~(BIT15 | BIT4 | BIT3); - - snd_soc_dapm_enable_pin(&card->rtd->codec->dapm, "Left HP"); - snd_soc_dapm_enable_pin(&card->rtd->codec->dapm, "Right HP"); - snd_soc_dapm_enable_pin(&card->rtd->codec->dapm, "Left SPK"); - snd_soc_dapm_enable_pin(&card->rtd->codec->dapm, "Right SPK"); - - return 0; -} - -static int wmt_resume_pre(struct snd_soc_card *card) -{ - /* Enable MCLK before VT1602 codec enable, otherwise the codec will be disabled. */ - - /* set to 24.576MHz */ - auto_pll_divisor(DEV_I2S, CLK_ENABLE , 0, 0); - auto_pll_divisor(DEV_I2S, SET_PLLDIV, 1, 24576); - /* Enable BIT4:ARFP clock, BIT3:ARF clock */ - PMCEU_VAL |= (BIT4 | BIT3); - /* Enable BIT2:AUD clock */ - PMCE3_VAL |= BIT2; - - wmt_set_i2s_share_pin(); - return 0; -} - -static struct snd_soc_ops wmt_soc_primary_ops = { - .startup = wmt_soc_primary_startup, - .hw_params = wmt_soc_primary_hw_params, - .shutdown = wmt_soc_primary_shutdown, -}; - -static struct snd_soc_ops wmt_soc_second_ops = { - .startup = wmt_soc_second_startup, - .hw_params = wmt_soc_second_hw_params, - .shutdown = wmt_soc_second_shutdown, -}; - -/* Digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link wmt_dai[] = { - { - .name = "HiFi", - .stream_name = "HiFi", - .platform_name = "wmt-audio-pcm.0", - .init = wmt_soc_dai_init, - .ops = &wmt_soc_primary_ops, - }, - { - .name = "Voice", - .stream_name = "Voice", - .platform_name = "wmt-pcm-dma.0", - .cpu_dai_name = "wmt-pcm-controller.0", - .codec_dai_name = "HWDAC", - .codec_name = "wmt-i2s-hwdac.0", - .ops = &wmt_soc_second_ops, - }, -}; - -/* Audio machine driver */ -static struct snd_soc_card snd_soc_machine_wmt = { - .name = "WMT_VT1609", - .dai_link = wmt_dai, - .num_links = ARRAY_SIZE(wmt_dai), - .suspend_pre = wmt_suspend_pre, - .suspend_post = wmt_suspend_post, - .resume_pre = wmt_resume_pre, -}; - -static struct platform_device *wmt_snd_device; - -static int __init wmt_soc_init(void) -{ - int ret, i; - char buf[64]; - int len = ARRAY_SIZE(buf); - - if (wmt_getsyspara("wmt.audio.i2s", buf, &len) != 0) { - strcpy(wmt_dai_name, "null"); - strcpy(wmt_codec_name, "null"); - } - else { - strcpy(wmt_dai_name, "i2s"); - } - - if (strcmp(wmt_dai_name, "null")) { - for (i = 0; i < 80; ++i) { - if (buf[i] == ':') - break; - else - wmt_codec_name[i] = buf[i]; - } - } - else { - return -EINVAL; - } - - // is wm8994, return and load wmt_wm8994 module - if (strcmp(wmt_codec_name, "wm8994") == 0) - return -ENODEV; - - info("dai_name=%s, codec_name=%s", wmt_dai_name, wmt_codec_name); - - - wmt_i2s_dai.playback.rates = (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000); - wmt_i2s_dai.capture.rates = (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000); - wmt_dai[0].cpu_dai_name = "wmt-i2s.0"; - - if (!strcmp(wmt_codec_name, "vt1602")) { - wmt_dai[0].codec_dai_name = "VT1602"; - wmt_dai[0].codec_name = "vt1602.1-001a"; - } - else if (!strcmp(wmt_codec_name, "hwdac")) { - wmt_dai[0].codec_dai_name = "HWDAC"; - wmt_dai[0].codec_name = "wmt-i2s-hwdac.0"; - } - else if (!strcmp(wmt_codec_name, "vt1603")) { - wmt_dai[0].codec_dai_name = "VT1603"; - wmt_dai[0].codec_name = "vt1603-codec"; - } - - /* Doing register process after plug-in */ - wmt_snd_device = platform_device_alloc("soc-audio", -1); - if (!wmt_snd_device) - return -ENOMEM; - - platform_set_drvdata(wmt_snd_device, &snd_soc_machine_wmt); - - ret = platform_device_add(wmt_snd_device); - if (ret) - goto err1; - - return 0; - -err1: - platform_device_put(wmt_snd_device); - return ret; - -} - -static void __exit wmt_soc_exit(void) -{ - DBG_DETAIL(); - - platform_device_unregister(wmt_snd_device); -} - -module_init(wmt_soc_init); -module_exit(wmt_soc_exit); - -MODULE_AUTHOR("WonderMedia Technologies, Inc."); -MODULE_DESCRIPTION("WMT [ALSA SoC/Machine] driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt-soc.h b/ANDROID_3.4.5/sound/soc/wmt/wmt-soc.h deleted file mode 100755 index f49a2764..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/wmt-soc.h +++ /dev/null @@ -1,53 +0,0 @@ -/*++ - * linux/sound/soc/wmt/wmt-soc.h - * WonderMedia audio driver for ALSA - * - * Copyright c 2010 WonderMedia Technologies, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * WonderMedia Technologies, Inc. - * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C ---*/ - - -#ifndef __WMT_ASOC_H__ -#define __WMT_ASOC_H__ -#include <mach/dma.h> - -struct audio_stream_a { - char *id; /* identification string */ - int stream_id; /* numeric identification */ - dmach_t dmach; /* DMA channel number */ - struct dma_device_cfg_s dma_cfg; /* DMA device config */ - int dma_dev; /* dma number of that device */ - int dma_q_head; /* DMA Channel Q Head */ - int dma_q_tail; /* DMA Channel Q Tail */ - char dma_q_count; /* DMA Channel Q Count */ - int active:1; /* we are using this stream for transfer now */ - int period; /* current transfer period */ - int periods; /* current count of periods registerd in the DMA engine */ - spinlock_t dma_lock; /* for locking in DMA operations */ - struct snd_pcm_substream *stream; /* the pcm stream */ - unsigned linked:1; /* dma channels linked */ - int offset; /* store start position of the last period in the alsa buffer */ - snd_pcm_uframes_t last_offset; -}; - -#define NUM_LINKS 1 - -extern struct snd_soc_dai_driver wmt_i2s_dai; - - -#endif diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.c b/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.c deleted file mode 100755 index 8a6d374e..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.c +++ /dev/null @@ -1,259 +0,0 @@ -/*++ - * linux/sound/soc/wmt/wmt_hwdep.c - * WonderMedia I2S audio driver for ALSA - * - * Copyright c 2010 WonderMedia Technologies, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * WonderMedia Technologies, Inc. - * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C ---*/ - -#include <sound/soc.h> -#include <sound/jack.h> - -#include <asm/mach-types.h> -#include <mach/gpio.h> - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/device.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc-dapm.h> -#include <sound/hwdep.h> - -#include <asm/mach-types.h> -#include <mach/hardware.h> - -#include "wmt_hwdep.h" -#include "wmt-pcm.h" - -int WFD_flag = 0; -static int gmode = 2; -static char gstring[3] = "LR"; - -static char gSpdHdm[6] = "BOTH"; -static int gSpHd = 6; - -extern void wmt_i2s_dac0_ctrl(int HDMI_audio_enable); - -static int wmt_hwdep_open(struct snd_hwdep *hw, struct file *file) -{ - if ((file->f_flags & O_RDWR) && (WFD_flag)) { - return -EBUSY; - } - else if (file->f_flags & O_SYNC) { - WFD_flag = 1; - } - return 0; -} - -static int wmt_hwdep_release(struct snd_hwdep *hw, struct file *file) -{ - WFD_flag = 0; - return 0; -} - -static int wmt_hwdep_mmap(struct snd_hwdep *hw, struct file *file, struct vm_area_struct *vma) -{ - vma->vm_flags |= VM_IO | VM_RESERVED; - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - if (remap_pfn_range(vma, vma->vm_start, (vma->vm_pgoff), - vma->vm_end - vma->vm_start, vma->vm_page_prot)) { - printk("*E* remap page range failed: vm_pgoff=0x%x ", (unsigned int)vma->vm_pgoff); - return -EAGAIN; - } - return 0; -} - -static int wmt_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg) -{ - int *value; - WFDStrmInfo_t *info; - struct wmt_soc_vt1603_info vt1603_info; - int ret = 0; - - switch (cmd) { - case WMT_SOC_IOCTL_HDMI: - value = (int __user *)arg; - - if (*value > 1) { - printk("Not supported status for HDMI Audio %d", *value); - return 0; - } - wmt_i2s_dac0_ctrl(*value); - return 0; - - case WMT_SOC_IOCTL_WFD_START: - wmt_pcm_wfd_start(); - return copy_to_user( (void *)arg, (const void __user *) wmt_pcm_wfd_get_buf(), sizeof(unsigned int)); - - case WMT_SOC_IOCTL_GET_STRM: - info = (WFDStrmInfo_t *)wmt_pcm_wfd_get_strm((WFDStrmInfo_t *)arg); - return __put_user((int)info, (unsigned int __user *) arg); - - case WMT_SOC_IOCTL_WFD_STOP: - wmt_pcm_wfd_stop(); - return 0; - - case WMT_SOC_IOCTL_VT1603_RD: - ret = copy_from_user(&vt1603_info, (void __user *)arg, sizeof(vt1603_info)); - - if (ret == 0) { - vt1603_info.reg_value = vt1603_hwdep_ioctl(0, vt1603_info.reg_offset, vt1603_info.reg_value); - printk("<<<%s read reg 0x%x val 0x%x\n", __FUNCTION__, vt1603_info.reg_offset, vt1603_info.reg_value); - ret = copy_to_user((void __user *)arg, &vt1603_info, sizeof(vt1603_info)); - } - return ret; - case WMT_SOC_IOCTL_VT1603_WR: - ret = copy_from_user(&vt1603_info, (void __user *)arg, sizeof(vt1603_info)); - printk("<<<%s write reg 0x%x val 0x%x\n", __FUNCTION__, vt1603_info.reg_offset, vt1603_info.reg_value); - if (ret == 0) - vt1603_hwdep_ioctl(1, vt1603_info.reg_offset, vt1603_info.reg_value); - return ret; - - case WMT_SOC_IOCTL_CH_SEL: - value = (int __user *)arg; - - if (*value > 2) { - printk("Not supported for CH select %d", *value); - return 0; - } - wmt_i2s_ch_sel(*value); - return 0; - - default: - break; - } - - printk("Not supported ioctl for WMT-HWDEP"); - return -ENOIOCTLCMD; -} - -static long wmt_hwdep_write(struct snd_hwdep *hw, const char __user *buf, - long count, loff_t *offset) -{ - char string[3]; - //int mode; - memset(string, 0, sizeof(string)); - copy_from_user(&string, buf, sizeof(string)); - printk("<<<%s %s\n", __FUNCTION__, string); - if (!memcmp(string, "LL", 2)) { - gmode = 0; - } - else if (!memcmp(string, "RR", 2)) { - gmode = 1; - } - else if (!memcmp(string, "LR", 2)) { - gmode = 2; - } - else { - printk("Not supported for CH select"); - return count; - } - - memset(gstring, 0, sizeof(gstring)); - strncpy(gstring, string, sizeof(string)); - wmt_i2s_ch_sel(gmode); - return count; -} - -static long wmt_hwdep_read(struct snd_hwdep *hw, char __user *buf, - long count, loff_t *offset) -{ - int len = 0; - printk("%s string %s --> mode %d\n", __FUNCTION__, gstring, gmode); - len = copy_to_user(buf, gstring, sizeof(gstring)); - - return sizeof(gstring); -} - -static long wmt_hwdep_write_1(struct snd_hwdep *hw, const char __user *buf, - long count, loff_t *offset) -{ - char string[5]; - //int mode; - - copy_from_user(&string, buf, sizeof(string)); - printk("<<<%s %s\n", __FUNCTION__, string); - if (!memcmp(string, "NONE", 4)) { - gSpHd = 3; - } - else if (!memcmp(string, "HDMI", 4)) { - gSpHd = 4; - } - else if (!memcmp(string, "SPDIF", 5)) { - gSpHd = 5; - } - else if (!memcmp(string, "BOTH", 4)) { - gSpHd = 6; - } - else { - printk("Not supported for SPDIF/HDMI switch"); - return count; - } - - memset(gSpdHdm, 0, sizeof(gSpdHdm)); - strncpy(gSpdHdm, string, sizeof(string)); - - wmt_i2s_ch_sel(gSpHd); - return count; -} - - -static long wmt_hwdep_read_1(struct snd_hwdep *hw, char __user *buf, - long count, loff_t *offset) -{ - int len = 0; - printk("%s string %s --> mode %d\n", __FUNCTION__, gSpdHdm, gSpHd); - len = copy_to_user(buf, gSpdHdm, sizeof(gSpdHdm)); - - return sizeof(gstring); -} - -void wmt_soc_hwdep_new(struct snd_soc_codec *codec) -{ - struct snd_hwdep *hwdep; - struct snd_hwdep *hwdep_1; - if (snd_hwdep_new(codec->card->snd_card, "WMT-HWDEP", 0, &hwdep) < 0) { - printk("create WMT-HWDEP_0 fail"); - return; - } - - sprintf(hwdep->name, "WMT-HWDEP %d", 0); - - hwdep->iface = SNDRV_HWDEP_IFACE_WMT; - hwdep->ops.open = wmt_hwdep_open; - hwdep->ops.ioctl = wmt_hwdep_ioctl; - hwdep->ops.release = wmt_hwdep_release; - hwdep->ops.mmap = wmt_hwdep_mmap; - hwdep->ops.write = wmt_hwdep_write; - hwdep->ops.read = wmt_hwdep_read; - - if (snd_hwdep_new(codec->card->snd_card, "WMT-HWDEP", 1, &hwdep_1) < 0) { - printk("create WMT-HWDEP_1 fail"); - return; - } - - sprintf(hwdep_1->name, "WMT-HWDEP %d", 1); - printk("create %s success", hwdep_1->name); - - hwdep_1->iface = SNDRV_HWDEP_IFACE_WMT; - hwdep_1->ops.write = wmt_hwdep_write_1; - hwdep_1->ops.read = wmt_hwdep_read_1; -} - diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.h b/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.h deleted file mode 100755 index c95d5e9e..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/wmt_hwdep.h +++ /dev/null @@ -1,55 +0,0 @@ -/*++ - * linux/sound/soc/wmt/wmt_hwdep.h - * WonderMedia I2S audio driver for ALSA - * - * Copyright c 2010 WonderMedia Technologies, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * WonderMedia Technologies, Inc. - * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C ---*/ - -/* - * ioctls for Hardware Dependant Interface - */ -#ifndef __WMT_HWDEP_H__ -#define __WMT_HWDEP_H__ - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> -#include <sound/soc-dapm.h> -#include <sound/hwdep.h> - -#include <asm/mach-types.h> -#include <mach/hardware.h> - -struct wmt_soc_vt1603_info { - u16 reg_offset; - u16 reg_value; -};//add 2013-9-2 for vt1603 eq apk - -#define WMT_SOC_IOCTL_HDMI _IOWR('H', 0x10, int) -#define WMT_SOC_IOCTL_WFD_START _IOWR('H', 0x20, int) -#define WMT_SOC_IOCTL_GET_STRM _IOWR('H', 0x30, int) -#define WMT_SOC_IOCTL_WFD_STOP _IOWR('H', 0x40, int) -#define WMT_SOC_IOCTL_VT1603_RD _IOWR('H', 0x50, int) -#define WMT_SOC_IOCTL_VT1603_WR _IOWR('H', 0x60, int) -#define WMT_SOC_IOCTL_CH_SEL _IOWR('H', 0x70, int) -void wmt_soc_hwdep_new(struct snd_soc_codec *codec); - -extern int vt1603_hwdep_ioctl(u8 rw_flag, u16 offset, u16 value); -extern void wmt_i2s_ch_sel(int ch_sel_num); -#endif diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.c b/ANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.c deleted file mode 100755 index 4d92a81f..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.c +++ /dev/null @@ -1,101 +0,0 @@ -/*++ - * linux/sound/soc/wmt/wmt_swmixer.c - * WonderMedia I2S audio driver for ALSA - * - * Copyright c 2010 WonderMedia Technologies, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * WonderMedia Technologies, Inc. - * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C ---*/ - - -#include "wmt_swmixer.h" -#include <sound/asound.h> - - - -void wmt_sw_u2s(int fmt, char *buffer, unsigned int chunksize) -{ - unsigned int index; - if (fmt == SNDRV_PCM_FORMAT_U8) { - for (index = 0; index < chunksize; ++index) - *(buffer + index) ^= 0x80; - } - -} - - -void wmt_pcm_fmt_trans(int fmt, int channel, char *src_buf, char *dst_buf, unsigned int chunksize) -{ - unsigned int index = 0; - float_data_t f_data; - unsigned short data; - - /* always convert to 2ch, s16le (4 bytes) */ - if ((fmt == SNDRV_PCM_FORMAT_S16_LE) && (channel == 1)) { - /* transfer from 1ch s16le(2 bytes) to 2ch s16le(4 bytes) */ - for (index = 0; index < (chunksize / 2); ++index) { - *((unsigned int *)dst_buf + index) = (*((unsigned short *)src_buf + index) << 16 | - *((unsigned short *)src_buf + index)); - } - } - else if ((fmt == SNDRV_PCM_FORMAT_U8) && (channel == 1)) { - /* transfer from 1ch U8(1 bytes) to 2ch s16le(4 bytes) */ - for (index = 0; index < chunksize; ++index) { - /* padding zero to byte 0 & byte 2 */ - *((unsigned int *)dst_buf + index) = (*((unsigned char *)src_buf + index) << 24 | - *((unsigned char *)src_buf + index) << 8); - } - } - else if ((fmt == SNDRV_PCM_FORMAT_U8) && (channel == 2)) { - /* transfer from 2ch U8(2 bytes) to 2ch s16le(4 bytes) */ - for (index = 0; index < chunksize; ++index) { - /* padding zero to byte 0 */ - *((unsigned short *)dst_buf + index) = *((unsigned char *)src_buf + index) << 8; - } - } - else if ((fmt == SNDRV_PCM_FORMAT_FLOAT) && (channel == 2)) { - /* transfer from 2ch float(8 bytes) to 2ch s16le(4 bytes) */ - for (index = 0; index < (chunksize / 4); ++index) { - f_data = *((float_data_t *)src_buf + index); - - if (!f_data.sign) { - data = (f_data.frac + 0x800000) >> (8 - (f_data.exp - 127)); - } - else { - data = ~((f_data.frac + 0x800000) >> (8 - (f_data.exp - 127))) + 1; - } - - *((unsigned short *)dst_buf + index) = data; - } - } - else if ((fmt == SNDRV_PCM_FORMAT_FLOAT) && (channel == 1)) { - /* transfer from 1ch float(4 bytes) to 2ch s16le(4 bytes) */ - for (index = 0; index < (chunksize / 4); ++index) { - f_data = *((float_data_t *)src_buf + index); - - if (!f_data.sign) { - data = (unsigned short)((f_data.frac + 0x800000) >> (8 - (f_data.exp - 127))); - } - else { - data = (unsigned short)(~((f_data.frac + 0x800000) >> (8 - (f_data.exp - 127))) + 1); - } - - *((unsigned int *)dst_buf + index) = (data << 16) | data; - } - } -} - diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.h b/ANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.h deleted file mode 100755 index 3163e5af..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/wmt_swmixer.h +++ /dev/null @@ -1,33 +0,0 @@ -/*++ - * linux/sound/soc/wmt/wmt_swmixer.h - * WonderMedia I2S audio driver for ALSA - * - * Copyright c 2010 WonderMedia Technologies, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * WonderMedia Technologies, Inc. - * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C ---*/ - - -typedef struct float_data { - unsigned long frac : 23; - unsigned long exp : 8; - unsigned long sign : 1; -} float_data_t; - -void wmt_sw_u2s(int fmt, char *buffer, unsigned int chunksize); -void wmt_pcm_fmt_trans(int fmt, int channel, char *src_buf, char *dst_buf, unsigned int chunksize); - diff --git a/ANDROID_3.4.5/sound/soc/wmt/wmt_wm8994.c b/ANDROID_3.4.5/sound/soc/wmt/wmt_wm8994.c deleted file mode 100755 index 8d4cebf9..00000000 --- a/ANDROID_3.4.5/sound/soc/wmt/wmt_wm8994.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * wmt_wm8994.c - * - * Copyright (C) 2010 Samsung Electronics Co.Ltd - * Author: Chanwoo Choi <cw00.choi@samsung.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 <sound/soc.h> -#include <sound/jack.h> - -#include <asm/mach-types.h> -#include <mach/gpio.h> - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/device.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc-dapm.h> -#include <sound/hwdep.h> - -#include <asm/mach-types.h> -#include <mach/hardware.h> - -#include "wmt-soc.h" -#include "wmt-pcm.h" -#include "wmt_hwdep.h" -#include "../codecs/wm8994.h" -#include <linux/mfd/wm8994/registers.h> -#include <linux/mfd/wm8994/core.h> - -#include <linux/i2c.h> - -static struct snd_soc_card wmt; -static struct platform_device *wmt_snd_device; -static int wmt_incall = 0; - -extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen); -extern void wmt_set_i2s_share_pin(void); - -static const struct snd_pcm_hardware wmt_voice_hardware = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_RESUME, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rate_min = 8000, - .rate_max = 8000, - .period_bytes_min = 16, - .period_bytes_max = 4 * 1024, - .periods_min = 2, - .periods_max = 16, - .buffer_bytes_max = 16 * 1024, -}; - -static int wmt_snd_suspend_post(struct snd_soc_card *card) -{ - /* Disable BIT15:I2S clock, BIT4:ARFP clock, BIT3:ARF clock */ - PMCEU_VAL &= ~(BIT15 | BIT4 | BIT3); - return 0; -} - -static int wmt_snd_resume_pre(struct snd_soc_card *card) -{ - /* Enable MCLK before VT1602 codec enable, otherwise the codec will be disabled. */ - - /* set to 24.576MHz */ - auto_pll_divisor(DEV_I2S, CLK_ENABLE , 0, 0); - auto_pll_divisor(DEV_I2S, SET_PLLDIV, 1, 24576); - /* Enable BIT4:ARFP clock, BIT3:ARF clock */ - PMCEU_VAL |= (BIT4 | BIT3); - /* Enable BIT2:AUD clock */ - PMCE3_VAL |= BIT2; - - wmt_set_i2s_share_pin(); - - return 0; -} - -static int wmt_wm8994_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_dai *codec_dai = rtd->codec_dai; - int ret = 0; - unsigned int pll_in = 48000; - unsigned int pll_out = 12000000; - - /* Set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_LRCLK, - pll_in, pll_out); - if (ret < 0) - return ret; - ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, pll_out, - SND_SOC_CLOCK_IN); - - wmt_soc_hwdep_new(rtd->codec); - - return 0; -} - -static int wmt_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->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret = 0; - unsigned int pll_in = 48000; - unsigned int pll_out = 12000000; - - /* Set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF); - if (ret< 0) { - printk("<<ret:%d snd_soc_dai_set_fmt(codec) hifi\n", ret); - return ret; - } - - /* Set cpu DAI configuration for I2S */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S); - if (ret < 0) { - printk("<<ret:%d snd_soc_dai_set_fmt(cpu) hifi\n", ret); - return ret; - } - - /* Set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_LRCLK, - pll_in, pll_out); - if (ret < 0) { - printk("<<ret:%d snd_soc_dai_set_pll hifi\n", ret); - return ret; - } - ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, pll_out, - SND_SOC_CLOCK_IN); - if (ret < 0) - printk("<<ret:%d snd_soc_dai_set_sysclk hifi\n", ret); - - if (!wmt_incall) - snd_soc_update_bits(codec_dai->codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, 0); - - return 0; -} - -static int wmt_voice_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int ret; - - ret = snd_soc_set_runtime_hwparams(substream, &wmt_voice_hardware); - - /* Ensure that buffer size is a multiple of period size */ - ret = snd_pcm_hw_constraint_integer(runtime,SNDRV_PCM_HW_PARAM_PERIODS); - return ret; -} - -static int wmt_voice_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; - int ret = 0; - unsigned int pll_in = 2048000; - unsigned int pll_out = 12288000; - - if (params_rate(params) != 8000) - return -EINVAL; - - /* Set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A | - SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) { - printk("<<ret:%d snd_soc_dai_set_fmt voice\n", ret); - return ret; - } - - /* Set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, WM8994_FLL_SRC_BCLK, - pll_in, pll_out); - if (ret < 0) { - printk("<<ret:%d snd_soc_dai_set_pll voice\n", ret); - return ret; - } - ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2, pll_out, - SND_SOC_CLOCK_IN); - if (ret < 0) - printk("<<ret:%d snd_soc_dai_set_sysclk voice\n", ret); - - wmt_incall = 1; - return ret; -} - -static int wmt_voice_hw_free(struct snd_pcm_substream *substream) -{ - wmt_incall = 0; - return 0; -} - -static struct snd_soc_ops wmt_hifi_ops = { - .hw_params = wmt_hifi_hw_params, -}; - -static struct snd_soc_ops wmt_voice_ops = { - .startup = wmt_voice_startup, - .hw_params = wmt_voice_hw_params, - .hw_free = wmt_voice_hw_free, -}; - -static struct snd_soc_dai_driver voice_dai[] = { - { - .name = "wmt-voice-dai", - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - }, -}; - -static struct snd_soc_dai_link wmt_dai[] = { - { - .name = "WM8994", - .stream_name = "WM8994 HiFi", - .cpu_dai_name = "wmt-i2s.0", - .codec_dai_name = "wm8994-aif1", - .platform_name = "wmt-audio-pcm.0", - .codec_name = "wm8994-codec", - .init = wmt_wm8994_init, - .ops = &wmt_hifi_ops, - }, - { - .name = "WM8994 Voice", - .stream_name = "Voice", - .cpu_dai_name = "wmt-voice-dai", - .codec_dai_name = "wm8994-aif2", - .codec_name = "wm8994-codec", - .ops = &wmt_voice_ops, - }, -}; - -static struct snd_soc_card wmt = { - .name = "WMT_WM8994", - .dai_link = wmt_dai, - .num_links = ARRAY_SIZE(wmt_dai), - .suspend_post = wmt_snd_suspend_post, - .resume_pre = wmt_snd_resume_pre, -}; - -static int __init wmt_init(void) -{ - int ret; - char buf[128]; - int len = ARRAY_SIZE(buf); - - if (wmt_getsyspara("wmt.audio.i2s", buf, &len) != 0) - return -EINVAL; - - if (strncmp(buf, "wm8994", strlen("wm8994"))) - return -ENODEV; - - wmt_snd_device = platform_device_alloc("soc-audio", -1); - if (!wmt_snd_device) - return -ENOMEM; - - /* register voice DAI here */ - ret = snd_soc_register_dais(&wmt_snd_device->dev, voice_dai, ARRAY_SIZE(voice_dai)); - if (ret) { - platform_device_put(wmt_snd_device); - return ret; - } - - platform_set_drvdata(wmt_snd_device, &wmt); - ret = platform_device_add(wmt_snd_device); - - if (ret) { - snd_soc_unregister_dai(&wmt_snd_device->dev); - platform_device_put(wmt_snd_device); - } - - return ret; -} - -static void __exit wmt_exit(void) -{ - snd_soc_unregister_dai(&wmt_snd_device->dev); - platform_device_unregister(wmt_snd_device); -} - -module_init(wmt_init); -module_exit(wmt_exit); - -MODULE_DESCRIPTION("ALSA SoC WM8994 WMT(wm8950)"); -MODULE_AUTHOR("Loonzhong <Loonzhong@wondermedia.com.cn>"); -MODULE_LICENSE("GPL"); |