int s5p_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* We don't configure clocks from this Sec i/f. * So, we simply wait enough time for LRSYNC to * get synced and not check return 'error' */ s5p_snd_lrsync(); s5p_snd_txctrl(1); i2s_trigger_stop = 0; break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: i2s_trigger_stop = 1; s5p_snd_txctrl(0); break; } return 0; }
void s5p_i2s_sec_init(void *regs, dma_addr_t phys_base) { u32 val; #ifdef CONFIG_ARCH_S5PV210 /* S5PC110 or S5PV210 */ //#include <plat/map.h> #define S3C_VA_AUDSS S3C_ADDR(0x01600000) /* Audio SubSystem */ #include <mach/regs-audss.h> /* We use I2SCLK for rate generation, so set EPLLout as * the parent of I2SCLK. */ val = readl(S5P_CLKSRC_AUDSS); val &= ~(0x3<<2); val |= (1<<0); writel(val, S5P_CLKSRC_AUDSS); val = readl(S5P_CLKGATE_AUDSS); val |= (0x7f<<0); writel(val, S5P_CLKGATE_AUDSS); #else #error INITIALIZE HERE! #endif s5p_i2s0_regs = regs; s5p_i2s_sec_pcm_out.dma_addr = phys_base + S5P_IISTXDS; s5p_snd_rxctrl(0); s5p_snd_txctrl(0); s5p_idma_init(regs); }
void s5p_i2s_sec_init(void *regs, dma_addr_t phys_base) { #ifdef CONFIG_ARCH_S5PV210 /* S5PC110 or S5PV210 */ #define S3C_VA_AUDSS S3C_ADDR(0x01600000) /* Audio SubSystem */ #include <mach/regs-audss.h> /* We use I2SCLK for rate generation, so set EPLLout as * the parent of I2SCLK. */ u32 val; val = readl(S5P_CLKSRC_AUDSS); val &= ~(0x3<<2); val |= (1<<0); writel(val, S5P_CLKSRC_AUDSS); val = readl(S5P_CLKGATE_AUDSS); val |= (0x7f<<0); writel(val, S5P_CLKGATE_AUDSS); #elif defined(CONFIG_ARCH_S5PV310) || defined(CONFIG_ARCH_S5PC210) u32 val; #if defined(CONFIG_SND_SOC_SMDK_WM8994_MASTER) || defined(CONFIG_SND_SOC_C1_MC1N2) /* I2S ratio for Codec master (3+1) = EPLL/4 = 181/4 = 45MHz */ val = 0x300; #else /* I2S ratio for AP master (0+1) = EPLL/1 = 181/1 = 181MHz */ val = 0x000; #endif /* SRP ratio (15+1)= EPLL/16 = 181/16 = 11MHz BUS ratio (1+1) = SRP/2 = 11/2 = 5MHz */ val |= 0x01F; writel(val, S5P_CLKDIV_AUDSS); writel(0x001, S5P_CLKSRC_AUDSS); /* I2S=Main CLK, ASS=FOUT_EPLL*/ /* CLKGATE should not be controled in here writel(0x1FF, S5P_CLKGATE_AUDSS); */ #else #error INITIALIZE HERE! #endif s5p_i2s0_regs = regs; s5p_i2s_startup(0); s5p_snd_txctrl(0); s5p_idma_init(regs); }
int s5p_i2s_startup(struct snd_soc_dai *dai) { u32 iiscon, iisfic; u32 iismod, iisahb; iiscon = readl(s5p_i2s0_regs + S3C2412_IISCON); iismod = readl(s5p_i2s0_regs + S3C2412_IISMOD); iisahb = readl(s5p_i2s0_regs + S5P_IISAHB); iisahb |= (S5P_IISAHB_DMARLD | S5P_IISAHB_DISRLDINT); iismod |= S5P_IISMOD_TXSLP; writel(iisahb, s5p_i2s0_regs + S5P_IISAHB); writel(iismod, s5p_i2s0_regs + S3C2412_IISMOD); s5p_snd_txctrl(0); //s5p_snd_rxctrl(0);//Don't turn-off RX setting as recording may b active during playback startup /* FIFOs must be flushed before enabling PSR and other MOD bits, so we do it here. */ if (iiscon & S5P_IISCON_TXSDMACTIVE) return 0; iisfic = readl(s5p_i2s0_regs + S5P_IISFICS); iisfic |= S3C2412_IISFIC_TXFLUSH; writel(iisfic, s5p_i2s0_regs + S5P_IISFICS); do { cpu_relax(); } while ((__raw_readl(s5p_i2s0_regs + S5P_IISFICS) >> 8) & 0x7f); iisfic = readl(s5p_i2s0_regs + S5P_IISFICS); iisfic &= ~S3C2412_IISFIC_TXFLUSH; writel(iisfic, s5p_i2s0_regs + S5P_IISFICS); return 0; }