add i2s codec pcm driver
author林辉辉 <lhh@rock-chips.com>
Fri, 28 May 2010 14:51:36 +0000 (14:51 +0000)
committer黄涛 <huangtao@rock-chips.com>
Mon, 21 Jun 2010 05:35:19 +0000 (13:35 +0800)
arch/arm/include/asm/dma.h
arch/arm/mach-rk2818/board-midsdk.c
arch/arm/mach-rk2818/clock.c
arch/arm/mach-rk2818/devices.c
arch/arm/mach-rk2818/devices.h
arch/arm/mach-rk2818/dma.c
arch/arm/mach-rk2818/include/mach/board.h
sound/soc/Kconfig
sound/soc/Makefile
sound/soc/codecs/wm8988.c

index b0f667faf601ddb3b238bed0c753975b79fbaf77..008b67fb4297287d6691bfb73e3414e99a1f1260 100644 (file)
@@ -97,7 +97,9 @@ extern void set_dma_sg(unsigned int chan, struct scatterlist *sg, int nr_sg);
  */
 extern void __set_dma_addr(unsigned int chan, void *addr);
 #define set_dma_addr(chan, addr)                               \
-       __set_dma_addr(chan, bus_to_virt(addr))
+       __set_dma_addr(chan, addr)      
+       //__set_dma_addr(chan, bus_to_virt(addr))
+       
 
 /* Set the DMA byte count for this channel
  *
@@ -132,4 +134,5 @@ extern int  get_dma_residue(unsigned int chan);
  */
 extern void set_dma_handler (unsigned int chan, void (*irq_handler) (int, void *), void *data);
 
+extern int dma_getposition(unsigned int  channel, dma_addr_t *src, dma_addr_t *dst);
 #endif /* __ASM_ARM_DMA_H */
index 91c7fd467acccad179efb0e9bc87fc898aa309b1..75b94bd1677a0eec6db50e1e8b6c949f67f0dec0 100644 (file)
@@ -300,7 +300,13 @@ static struct i2c_board_info __initdata board_i2c0_devices[] = {
                .flags                  = 0,
        },
 #endif
-       {}
+#if defined (CONFIG_SND_SOC_WM8988)
+       {
+               .type                   = "wm8988",
+               .addr           = 0x1a,
+               .flags                  = 0,
+       }
+#endif 
 };
 static struct i2c_board_info __initdata board_i2c1_devices[] = {
 #if defined (CONFIG_RTC_HYM8563)
@@ -400,6 +406,7 @@ static struct platform_device *devices[] __initdata = {
        &rk2818_device_sdmmc1,
 #endif
        &rk2818_device_spim,
+       &rk2818_device_i2s,
 #if defined(CONFIG_ANDROID_PMEM)
        &rk2818_device_pmem,
 #endif
index 9298ec18d1f5424c374751e6536dff6e5fb6e7b4..1607ebb414f05d10d780275f8f7b0d2f14a74be1 100644 (file)
@@ -911,7 +911,7 @@ static struct clk_lookup clks[] = {
        CLK1(deblocking_rv),
        CLK1(lcdc),
        CLK1(vip),
-       CLK1(i2s),
+       CLK("rk2818_i2s","i2s",&i2s_clk),
        CLK("rk2818_sdmmc.0", "sdmmc", &sdmmc0_clk),
        CLK1(ebrom),
        CLK1(gpio0),
index 638e9c0eec4c5fd4ceb3e5c03269d5849d90fd23..0b9130859cf3b997ed1a61f05cc26a7a36baa9ff 100644 (file)
@@ -325,13 +325,33 @@ struct platform_device rk2818_device_adckey = {
        .id             = -1,
        .dev.parent     = &rk2818_device_adc.dev,
 };
+/*
+ *rk2818 i2s
+ */
+static struct resource resources_i2s[] = {
+       {
+               .start  = IRQ_NR_I2S,
+               .end    = IRQ_NR_I2S,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = RK2818_I2S_PHYS,
+               .end    = RK2818_I2S_PHYS + SZ_8K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+struct platform_device rk2818_device_i2s = {
+       .name   = "rk2818_i2s",
+       .id     = 0,
+       .num_resources  = ARRAY_SIZE(resources_i2s),
+       .resource       = resources_i2s,
+};
 
 struct platform_device rk2818_device_battery = {
                .name   = "rk2818-battery",
                .id     = -1,
 };
 
-
 /*
  * rk2818 dsp device
  */
index 2affc341bee4bd448632a6bde9b666c75f81aeff..4eca8fe1406f012df266d5f3a96ea37fda28f899 100644 (file)
@@ -31,6 +31,7 @@ extern struct platform_device rk2818_device_sdmmc1;
 extern struct rk2818_sdmmc_platform_data default_sdmmc0_data;
 extern struct rk2818_sdmmc_platform_data default_sdmmc1_data;
 extern struct platform_device rk2818_device_dm9k;
+extern struct platform_device rk2818_device_i2s;
 extern struct platform_device rk2818_device_pmem;
 extern struct platform_device rk2818_device_fb;
 extern struct platform_device rk2818_device_adc;
index 684e221e181e6087011209e4f28def09671c6b9c..fb0b3ab014a9deec68c87d7ad4a4e869ff2d601e 100644 (file)
@@ -631,6 +631,18 @@ static irqreturn_t rk28_dma_irq_handler(int irq, void *dev_id)
 }
 
 
+int dma_getposition(unsigned int  channel, dma_addr_t *src, dma_addr_t *dst)
+{
+       u32 phy_ch = channel;
+    if (src != NULL)
+        *src = read_dma_reg(DWDMA_SAR(phy_ch));
+    if (dst != NULL)     
+        *dst = read_dma_reg(DWDMA_DAR(phy_ch)); 
+    
+       return 0;
+}
+EXPORT_SYMBOL(dma_getposition);
+
 static struct dma_ops rk2818_dma_ops = {
     .request = rk28_dma_request,
     .free = rk28_dma_free,
index ed9651f27cf7d4def852bcd14d8a2429264bdfa7..aaac178001c82ee534640c82c40d0256ebd2b52e 100644 (file)
 /* platform device data structures */
 struct platform_device;
 struct i2c_client;
-struct RK2818_mddi_platform_data
-{
-       void (*panel_power)(int on);
-       unsigned has_vsync_irq:1;
-};
 struct rk2818_sdmmc_platform_data {
        unsigned int host_caps;
        unsigned int host_ocr_avail;
index b1749bc679794ba7910ab0a55d880ee4d7db0e1a..36258a0b546b5b8b3fc8016af66b12e89ce9d926 100644 (file)
@@ -36,7 +36,7 @@ source "sound/soc/s3c24xx/Kconfig"
 source "sound/soc/s6000/Kconfig"
 source "sound/soc/sh/Kconfig"
 source "sound/soc/txx9/Kconfig"
-
+source "sound/soc/rk2818/Kconfig"
 # Supported codecs
 source "sound/soc/codecs/Kconfig"
 
index 0c5eac01bf2e5ffbc8d4691987c7097b90dce90a..6adaa55b42e93642c975ecc92f2728e6eaa6cbfc 100644 (file)
@@ -14,3 +14,4 @@ obj-$(CONFIG_SND_SOC) += s3c24xx/
 obj-$(CONFIG_SND_SOC)  += s6000/
 obj-$(CONFIG_SND_SOC)  += sh/
 obj-$(CONFIG_SND_SOC)  += txx9/
+obj-$(CONFIG_SND_SOC)  += rk2818/
index 3f530f8a972af3547a9da579e4db2f8f519e4e58..ca5b56d0fb8b58b04587944e1cf4d6abce08a08c 100644 (file)
 #include <sound/soc-dapm.h>
 #include <sound/initval.h>
 
+#include <mach/iomux.h>
+#include <mach/gpio.h>
+
 #include "wm8988.h"
 
+
+#if 0
+#define DBG(x...) printk(KERN_INFO x)
+#else
+#define DBG(x...) do { } while (0)
+#endif
+
 /*
  * wm8988 register cache
  * We can't read the WM8988 register space when we
@@ -191,6 +201,8 @@ static int wm8988_lrc_control(struct snd_soc_dapm_widget *w,
        else
                adctl2 |= 0x4;
 
+       DBG("Enter::%s----%d, adctl2 = %x\n",__FUNCTION__,__LINE__,adctl2);
+       
        return snd_soc_write(codec, WM8988_ADCTL2, adctl2);
 }
 
@@ -495,7 +507,9 @@ static int wm8988_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 {
        struct snd_soc_codec *codec = codec_dai->codec;
        struct wm8988_priv *wm8988 = codec->private_data;
-
+       
+    DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
+               
        switch (freq) {
        case 11289600:
        case 18432000:
@@ -576,6 +590,7 @@ static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
+       DBG("Enter::%s----%d  iface=%x\n",__FUNCTION__,__LINE__,iface);
        snd_soc_write(codec, WM8988_IFACE, iface);
        return 0;
 }
@@ -585,10 +600,11 @@ static int wm8988_pcm_startup(struct snd_pcm_substream *substream,
 {
        struct snd_soc_codec *codec = dai->codec;
        struct wm8988_priv *wm8988 = codec->private_data;
-
+       
        /* The set of sample rates that can be supported depends on the
         * MCLK supplied to the CODEC - enforce this.
         */
+       DBG("Enter::%s----%d  wm8988->sysclk=%d\n",__FUNCTION__,__LINE__,wm8988->sysclk); 
        if (!wm8988->sysclk) {
                dev_err(codec->dev,
                        "No MCLK configured, call set_sysclk() on init\n");
@@ -613,7 +629,7 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
        u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3;
        u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180;
        int coeff;
-
+       
        coeff = get_coeff(wm8988->sysclk, params_rate(params));
        if (coeff < 0) {
                coeff = get_coeff(wm8988->sysclk / 2, params_rate(params));
@@ -640,6 +656,7 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
                iface |= 0x000c;
                break;
        }
+       DBG("Enter::%s----%d  iface=%x srate =%x rate=%d\n",__FUNCTION__,__LINE__,iface,srate,params_rate(params));
 
        /* set iface & srate */
        snd_soc_write(codec, WM8988_IFACE, iface);
@@ -654,7 +671,7 @@ static int wm8988_mute(struct snd_soc_dai *dai, int mute)
 {
        struct snd_soc_codec *codec = dai->codec;
        u16 mute_reg = snd_soc_read(codec, WM8988_ADCDAC) & 0xfff7;
-
+       DBG("Enter::%s----%d--mute=%d\n",__FUNCTION__,__LINE__,mute);
        if (mute)
                snd_soc_write(codec, WM8988_ADCDAC, mute_reg | 0x8);
        else
@@ -666,7 +683,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
                                 enum snd_soc_bias_level level)
 {
        u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1;
-
+       DBG("Enter::%s----%d level =%d\n",__FUNCTION__,__LINE__,level);
        switch (level) {
        case SND_SOC_BIAS_ON:
                break;
@@ -735,7 +752,7 @@ static int wm8988_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
        struct snd_soc_codec *codec = socdev->card->codec;
-
+       DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
        wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
        return 0;
 }
@@ -747,7 +764,7 @@ static int wm8988_resume(struct platform_device *pdev)
        int i;
        u8 data[2];
        u16 *cache = codec->reg_cache;
-
+       DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
        /* Sync reg_cache with the hardware */
        for (i = 0; i < WM8988_NUM_REG; i++) {
                if (i == WM8988_RESET)
@@ -866,7 +883,13 @@ static int wm8988_register(struct wm8988_priv *wm8988,
                dev_err(codec->dev, "Failed to issue reset\n");
                goto err;
        }
-
+#if 1
+               /*disable speaker */
+               gpio_request(RK2818_PIN_PF7, "WM8988"); 
+               rk2818_mux_api_set(GPIOE_SPI1_FLASH_SEL_NAME, IOMUXA_GPIO1_A3B7);
+               gpio_direction_output(RK2818_PIN_PF7,GPIO_HIGH);
+               
+#endif
        /* set the update bits (we always update left then right) */
        reg = snd_soc_read(codec, WM8988_RADC);
        snd_soc_write(codec, WM8988_RADC, reg | 0x100);
@@ -877,7 +900,22 @@ static int wm8988_register(struct wm8988_priv *wm8988,
        reg = snd_soc_read(codec, WM8988_ROUT2V);
        snd_soc_write(codec, WM8988_ROUT2V, reg | 0x0100);
        reg = snd_soc_read(codec, WM8988_RINVOL);
-       snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100);
+       snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100); 
+       
+       snd_soc_write(codec, WM8988_LOUTM1, 0x120); 
+    snd_soc_write(codec, WM8988_ROUTM2, 0x120);  
+       snd_soc_write(codec, WM8988_LOUTM2, 0x0070);
+       snd_soc_write(codec, WM8988_ROUTM1, 0x0070);
+       
+       snd_soc_write(codec, WM8988_LOUT1V, 0x017f); 
+       snd_soc_write(codec, WM8988_ROUT1V, 0x017f);
+       snd_soc_write(codec, WM8988_LDAC, 0xff);  
+       snd_soc_write(codec, WM8988_RDAC, 0x1ff);//vol set 
+       
+       snd_soc_write(codec, WM8988_SRATE,0x100);  ///SET MCLK/8
+       snd_soc_write(codec, WM8988_PWR1, 0x1cc);  ///(0x80|0x40|0x20|0x08|0x04|0x10|0x02));
+       snd_soc_write(codec, WM8988_PWR2, 0x1e0);  //power r l out1
+
 
        wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_STANDBY);