示例#1
0
static int s3c24xx_pcm_mmap(struct snd_pcm_substream *substream,
                            struct vm_area_struct *vma)
{
    struct snd_pcm_runtime *runtime = substream->runtime;

    s3cdbg("Entered %s\n", __FUNCTION__);

    return dma_mmap_writecombine(substream->pcm->card->dev, vma,
                                 runtime->dma_area,
                                 runtime->dma_addr,
                                 runtime->dma_bytes);
}
示例#2
0
/*
 * Set S3C24xx I2S DAI format
 */
static int s3c_i2s_v50_set_fmt(struct snd_soc_dai *cpu_dai,
		unsigned int fmt)
{
	u32 iismod;

	s3cdbg("Entered %s: fmt = %d\n", __FUNCTION__, fmt);

	iismod = readl(s5pc1xx_i2s.regs + S3C64XX_IIS0MOD);

	return 0;

}
示例#3
0
static int s5p_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct s5p_runtime_data *prtd = substream->runtime->private_data;
	int ret = 0;

	s3cdbg("Entered %s\n", __FUNCTION__);

	spin_lock(&prtd->lock);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_RESUME:
		if(s3c_pcm_pdat.lp_mode){
			prtd->state |= ST_RUNNING;
			s3ci2s_func->dma_ctrl(S3C_I2SDMA_RESUME);
			break;
		}
		s5p_pcm_enqueue(substream);
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		prtd->state |= ST_RUNNING;
		if(s3c_pcm_pdat.lp_mode)
		   s3ci2s_func->dma_ctrl(S3C_I2SDMA_START);
		else
		   s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START);
		break;

	case SNDRV_PCM_TRIGGER_SUSPEND:
		if(s3c_pcm_pdat.lp_mode){
		   prtd->state &= ~ST_RUNNING;
		   s3ci2s_func->dma_ctrl(S3C_I2SDMA_SUSPEND);
		   break;
		}
		if(prtd->dma_loaded)
		   prtd->dma_loaded--; /* we may never get buffdone callback */
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		prtd->state &= ~ST_RUNNING;
		if(s3c_pcm_pdat.lp_mode)
		   s3ci2s_func->dma_ctrl(S3C_I2SDMA_STOP);
		else
		   s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP);
		break;

	default:
		ret = -EINVAL;
		break;
	}

	spin_unlock(&prtd->lock);

	return ret;
}
示例#4
0
static int s3c_i2s_v50_resume(struct platform_device *pdev,
	struct snd_soc_dai *dai)
{
	s3cdbg("Entered %s\n", __FUNCTION__);
	clk_enable(s5pc1xx_i2s.iis_clk);

	writel(s5pc1xx_i2s.iiscon, s5pc1xx_i2s.regs + S3C64XX_IIS0CON);
	writel(s5pc1xx_i2s.iismod, s5pc1xx_i2s.regs + S3C64XX_IIS0MOD);
	writel(s5pc1xx_i2s.iisfic, s5pc1xx_i2s.regs + S3C64XX_IIS0FIC);
	writel(s5pc1xx_i2s.iispsr, s5pc1xx_i2s.regs + S3C64XX_IIS0PSR);

	return 0;
}
示例#5
0
static int smdk6410_set_cs(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
	s3cdbg("%s\n", __FUNCTION__);

	if(smdk6410_rec_opt == ucontrol->value.integer.value[0])
		return 0;

	smdk6410_rec_opt = ucontrol->value.integer.value[0];
	smdk6410_ext_control(codec);
	return 1;
}
示例#6
0
static int s3c_i2s_v50_suspend(struct platform_device *dev,
	struct snd_soc_dai *dai)
{
	s3cdbg("Entered %s\n", __FUNCTION__);
	s5pc1xx_i2s.iiscon = readl(s5pc1xx_i2s.regs + S3C64XX_IIS0CON);
	s5pc1xx_i2s.iismod = readl(s5pc1xx_i2s.regs + S3C64XX_IIS0MOD);	
	s5pc1xx_i2s.iisfic = readl(s5pc1xx_i2s.regs + S3C64XX_IIS0FIC);
	s5pc1xx_i2s.iispsr = readl(s5pc1xx_i2s.regs + S3C64XX_IIS0PSR);
	       
	clk_disable(s5pc1xx_i2s.iis_clk);

	return 0;
}
示例#7
0
static void s5pc1xx_snd_rxctrl(int on)
{
	u32 iisfcon;
	u32 iiscon;
	u32 iismod;

	s3cdbg("Entered %s: on = %d\n", __FUNCTION__, on);

	iisfcon = readl(s5pc1xx_i2s.regs + S3C64XX_IIS0FIC);
	iiscon  = readl(s5pc1xx_i2s.regs + S3C64XX_IIS0CON);
	iismod  = readl(s5pc1xx_i2s.regs + S3C64XX_IIS0MOD);

	s3cdbg("r: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon);

	if (on) {
		iiscon |= S3C64XX_IIS0CON_I2SACTIVE;

		writel(iismod,  s5pc1xx_i2s.regs + S3C64XX_IIS0MOD);
		writel(iisfcon, s5pc1xx_i2s.regs + S3C64XX_IIS0FIC);
		writel(iiscon,  s5pc1xx_i2s.regs + S3C64XX_IIS0CON);
	} else {
		/* note, we have to disable the FIFOs otherwise bad things
		 * seem to happen when the DMA stops. According to the
		 * Samsung supplied kernel, this should allow the DMA
		 * engine and FIFOs to reset. If this isn't allowed, the
		 * DMA engine will simply freeze randomly.
		 */

		iiscon &= ~S3C64XX_IIS0CON_I2SACTIVE;
		iismod &= ~S3C64XX_IIS0MOD_RXMODE;

		writel(iisfcon, s5pc1xx_i2s.regs + S3C64XX_IIS0FIC);
		writel(iiscon,  s5pc1xx_i2s.regs + S3C64XX_IIS0CON);
		writel(iismod,  s5pc1xx_i2s.regs + S3C64XX_IIS0MOD);

	}
	s3cdbg("w: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon);
}
/* power down chip */
static int spdif_remove(struct platform_device *pdev)
{
	
	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
	struct snd_soc_codec *codec = socdev->codec;

	s3cdbg("Entered %s\n", __FUNCTION__);
	
	snd_soc_free_pcms(socdev);
	//snd_soc_dapm_free(socdev);
	kfree(codec->private_data);
	kfree(codec);
	return 0;
}
示例#9
0
static int s3c_i2s_probe(struct platform_device *pdev)
{
	s3cdbg("Entered %s\n", __FUNCTION__);

#if defined CONFIG_SND_SOC_I2S_V32
	s3c24xx_i2s.regs = ioremap(S3C2450_PA_IIS_1, 0x100);
	if (s3c24xx_i2s.regs == NULL)
		return -ENXIO;
#elif defined CONFIG_SND_SOC_I2S_V40
	s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100);
	if (s3c24xx_i2s.regs == NULL)
		return -ENXIO;
#endif

	s3c24xx_i2s.iis_clk=clk_get(&pdev->dev, "iis");
	if (s3c24xx_i2s.iis_clk == NULL) {
		s3cdbg("failed to get iis_clock\n");
		return -ENODEV;
	}
	clk_enable(s3c24xx_i2s.iis_clk);

	return 0;
}
示例#10
0
/* s5p_pcm_enqueue
 *
 * place a dma buffer onto the queue for the dma system
 * to handle.
 */
static void s5p_pcm_enqueue(struct snd_pcm_substream *substream)
{
	struct s5p_runtime_data *prtd = substream->runtime->private_data;
	dma_addr_t pos = prtd->dma_pos;
	unsigned long len = prtd->dma_period;
	int ret;

	s3cdbg("Entered %s\n", __FUNCTION__);

	/* By Jung */

	s3cdbg("dma_loaded: %d\n",prtd->dma_loaded);

	if ((pos + len) > prtd->dma_end) {
		len  = prtd->dma_end - pos;
		s3cdbg(KERN_DEBUG "%s: corrected dma len %ld\n", __FUNCTION__, len);
	}

	s3cdbg("enqing at %x, %d bytes\n", pos, len);
	ret = s3c2410_dma_enqueue(prtd->params->channel, substream, pos, len);

	prtd->dma_pos = pos;
}
示例#11
0
static int s3c24xx_pcm_close(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct s3c24xx_runtime_data *prtd = runtime->private_data;

	s3cdbg("Entered %s, prtd = %p\n", __FUNCTION__, prtd);

	if (prtd)
		kfree(prtd);
	else
		printk("s3c24xx_pcm_close called with prtd == NULL\n");

	return 0;
}
示例#12
0
static snd_pcm_uframes_t 
	s3c24xx_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct s3c24xx_runtime_data *prtd = runtime->private_data;
	unsigned long res;

	s3cdbg("Entered %s\n", __FUNCTION__);

	spin_lock(&prtd->lock);

#if defined (CONFIG_CPU_S3C6400) || defined (CONFIG_CPU_S3C6410)
	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)  
		res = prtd->dma_pos - prtd->dma_start;
	else 
		res = prtd->dma_pos - prtd->dma_start;	
#else
	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
		res = dst - prtd->dma_start;
	else
		res = src - prtd->dma_start;
#endif

	spin_unlock(&prtd->lock);

	/* we seem to be getting the odd error from the pcm library due
	 * to out-of-bounds pointers. this is maybe due to the dma engine
	 * not having loaded the new values for the channel before being
	 * callled... (todo - fix )
	 */
	
	/* Playback mode */	
	if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {	
		if (res >= (snd_pcm_lib_buffer_bytes(substream) * ANDROID_BUF_NUM)) {
			if (res == (snd_pcm_lib_buffer_bytes(substream) * ANDROID_BUF_NUM))
				res = 0;
		}
	}

	/* Capture mode */	
	else {	
		if (res >= (snd_pcm_lib_buffer_bytes(substream))) {
			if (res == (snd_pcm_lib_buffer_bytes(substream)))
				res = 0;
		}
	}

	return bytes_to_frames(substream->runtime, res);
}
示例#13
0
void iis_clock_control(bool enable)
{
	u32 clk_gate_D1_5,clk_gate_D2_0, clk_gate_sclk1;
	s3cdbg("Entered %s but will not do anything\n", __FUNCTION__);
	if(!enable)
	{
		/*Audio CLK gating start*/
	
		// PCLK gating for IIS1 
		clk_gate_D1_5 = readl(S5P_CLKGATE_D15);
		clk_gate_D1_5 &= ~S5P_CLKGATE_D15_IIS0; // IIS0 Mask
		clk_gate_D1_5 |= S5P_CLKGATE_D15_IIS1; // IIS1 Mask
		clk_gate_D1_5 &= ~S5P_CLKGATE_D15_IIS2; // IIS2 Mask
		clk_gate_D1_5 &= ~S5P_CLKGATE_D15_AC97; // AC97 Mask
		clk_gate_D1_5 &= ~S5P_CLKGATE_D15_PCM0; // PCM0 Mask
	
		writel(clk_gate_D1_5,S5P_CLKGATE_D15);
		s3cdbg("GATE D1_5 : %x\n",readl(S5P_CLKGATE_D15));
	
		// IIS0 Block Clk Mask
		clk_gate_D2_0 = readl(S5P_CLKGATE_D20);
		clk_gate_D2_0 &= ~S5P_CLKGATE_D20_HCLKD2; // IIS0 HCLK D2 Mask
		clk_gate_D2_0 &= ~S5P_CLKGATE_D20_I2SD2; // IIS0CLK D2 Mask
		writel(clk_gate_D2_0,S5P_CLKGATE_D20);
		s3cdbg("HCLKD2 Gate : %x\n",readl(S5P_CLKGATE_D20));
	
		// SCLK Gateing Audio1
		clk_gate_sclk1 = readl(S5P_SCLKGATE1);
		clk_gate_sclk1 &= ~S5P_CLKGATE_SCLK1_AUDIO0; // IIS0 SCLK Mask
		clk_gate_sclk1 |= S5P_CLKGATE_SCLK1_AUDIO1; // IIS1 SCLK Mask
		clk_gate_sclk1 &= ~S5P_CLKGATE_SCLK1_AUDIO2; // IIS2 SCLK Mask
		writel(clk_gate_sclk1,S5P_SCLKGATE1);
		s3cdbg("S5P_SCLKGATE1 : %x\n",readl(S5P_SCLKGATE1));
	}
//	s5p_power_gating(S5PC100_POWER_DOMAIN_AUDIO,DOMAIN_LP_MODE);
}
示例#14
0
static snd_pcm_uframes_t 
	s3c24xx_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct s3c24xx_runtime_data *prtd = runtime->private_data;
	unsigned long res;
	dma_addr_t src, dst;

	s3cdbg("Entered %s\n", __FUNCTION__);

	spin_lock(&prtd->lock);

	s3c2410_dma_getposition(prtd->params->channel, &src, &dst);

	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
		res = dst - prtd->dma_start;
	else
		res = src - prtd->dma_start;

	spin_unlock(&prtd->lock);

	s3cdbg("Pointer %x %x\n",src,dst);

	/* we seem to be getting the odd error from the pcm library due
	 * to out-of-bounds pointers. this is maybe due to the dma engine
	 * not having loaded the new values for the channel before being
	 * callled... (todo - fix )
	 */

	if (res >= snd_pcm_lib_buffer_bytes(substream)) {
		if (res == snd_pcm_lib_buffer_bytes(substream))
			res = 0;
	}

	return bytes_to_frames(substream->runtime, res);
}
示例#15
0
static int s5p_pcm_hw_free_nm(struct snd_pcm_substream *substream)
{
	struct s5p_runtime_data *prtd = substream->runtime->private_data;

	s3cdbg("Entered %s\n", __FUNCTION__);

	/* TODO - do we need to ensure DMA flushed */
	snd_pcm_set_runtime_buffer(substream, NULL);

	if (prtd->params) {
		s3c2410_dma_free(prtd->params->channel, prtd->params->client);
		prtd->params = NULL;
	}

	return 0;
}
示例#16
0
static int adau1761_dapm_mic_event(struct snd_soc_dapm_widget *w,
	struct snd_kcontrol *k, int event)
{
	struct snd_soc_codec	*codec = w->codec;
	struct adau1761_priv	*cpriv = codec->private_data;
//	adau1761_platform_t	*pdata = cpriv->pdata;
	s3cdbg("%s(%d) event=%d\n", __func__, __LINE__, event);
	if (SND_SOC_DAPM_EVENT_ON(event)) {
//		pdata->mic_stdby_n( 1 );
	} else if (SND_SOC_DAPM_EVENT_OFF(event)) {
//		pdata->mic_stdby_n( 0 );
	} else {
		printk("%s(%d): Unknown event #%d\n", __func__, __LINE__, event);
	}
	return 0;
}
示例#17
0
static int s3c24xx_pcm_open(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct s3c24xx_runtime_data *prtd;

	s3cdbg("Entered %s\n", __FUNCTION__);

	snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware);

	prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL);
	if (prtd == NULL)
		return -ENOMEM;

	spin_lock_init(&prtd->lock);

	runtime->private_data = prtd;
	return 0;
}
示例#18
0
static int s3c24xx_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 = s3c24xx_pcm_hardware.buffer_bytes_max;

	s3cdbg("Entered %s\n", __FUNCTION__);

	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 (!buf->area)
		return -ENOMEM;
	buf->bytes = size;
	return 0;
}
/*
 * Wait for the LR signal to allow synchronisation to the L/R clock
 * from the codec. May only be needed for slave mode.
 */
static int s3c24xx_snd_lrsync(void)
{
	u32 iiscon;
	unsigned long timeout = jiffies + msecs_to_jiffies(5);

	s3cdbg("Entered %s\n", __FUNCTION__);

	while (1) {
		iiscon = readl(s3c24xx_i2s.regs + S3C64XX_IIS0CON);
		if (iiscon & S3C64XX_IISCON_LRINDEX)
			break;

		if (timeout < jiffies)
			return -ETIMEDOUT;
	}

	return 0;
}
示例#20
0
static int __init smdk6410_init(void)
{
	int ret;
	u32 val;
	s3cdbg("%s\n", __FUNCTION__);

	val = __raw_readl(S3C64XX_GPCPUD);
	val &= ~((3<<8) | (3<<10) | (3<<14));
	val |= ((0<<8) | (0<<10) | (0<<14));
	__raw_writel(val, S3C64XX_GPCPUD);

	val = __raw_readl(S3C64XX_GPCCON);
	val &= ~((0xf<<16) | (0xf<<20) | (0xf<<28));
	val |= (5<<16) | (5<<20) | (5<<28);
	__raw_writel(val, S3C64XX_GPCCON);

	val = __raw_readl(S3C64XX_GPHPUD);
	val &= ~((3<<12) | (3<<14) | (3<<16) | (3<<18));
	val |= ((0<<12) | (1<<14) | (0<<16) | (0<18));
	__raw_writel(val, S3C64XX_GPHPUD);

	val = __raw_readl(S3C64XX_GPHCON0);
	val &= ~((0xf<<24) | (0xf<<28));
	val |= (5<<24) | (5<<28);
	__raw_writel(val, S3C64XX_GPHCON0);

	val = __raw_readl(S3C64XX_GPHCON1);
	val &= ~((0xf<<0) | (0xf<<4));
	val |= (5<<0) | (5<<4);
	__raw_writel(val, S3C64XX_GPHCON1);

	smdk6410_snd_device = platform_device_alloc("soc-audio", 0);
	if (!smdk6410_snd_device)
		return -ENOMEM;

	platform_set_drvdata(smdk6410_snd_device, &smdk6410_snd_devdata);
	smdk6410_snd_devdata.dev = &smdk6410_snd_device->dev;
	ret = platform_device_add(smdk6410_snd_device);

	if (ret)
		platform_device_put(smdk6410_snd_device);
	
	return ret;
}
示例#21
0
static int s5p_pcm_mmap(struct snd_pcm_substream *substream,
	struct vm_area_struct *vma)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	unsigned long size, offset;
	int ret;

	s3cdbg("Entered %s\n", __FUNCTION__);

	if(s3c_pcm_pdat.lp_mode){
		/* From snd_pcm_lib_mmap_iomem */
		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
		vma->vm_flags |= VM_IO;
		size = vma->vm_end - vma->vm_start;
		offset = vma->vm_pgoff << PAGE_SHIFT;
		ret = io_remap_pfn_range(vma, vma->vm_start,
				(runtime->dma_addr + offset) >> PAGE_SHIFT,
				size, vma->vm_page_prot);
	}else{
/*
 * Set S3C24xx I2S DAI format
 */
static int s3c_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
		unsigned int fmt)
{
#if 0
	u32 iismod;

	s3cdbg("Entered %s: fmt = %d\n", __FUNCTION__, fmt);

	iismod = readl(s3c24xx_i2s.regs + S3C64XX_IIS0MOD);

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
#if !defined (CONFIG_CPU_S3C6400) && !defined (CONFIG_CPU_S3C6410)
		iismod |= S3C64XX_IISMOD_SLAVE;
#else
		iismod |= S3C2410_IISMOD_MASTER;
#endif
		break;
	case SND_SOC_DAIFMT_CBS_CFS:
		break;
	default:
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_LEFT_J:
#if !defined (CONFIG_CPU_S3C6400) && !defined (CONFIG_CPU_S3C6410)
		iismod |= S3C2410_IISMOD_MSB;
#else
		iismod |= S3C_IIS0MOD_MSB;
#endif
		break;
	case SND_SOC_DAIFMT_I2S:
		break;
	default:
		return -EINVAL;
	}

	writel(iismod, s3c24xx_i2s.regs + S3C64XX_IIS0MOD);
#endif
	return 0;

}
示例#23
0
static snd_pcm_uframes_t 
	s5p_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct s5p_runtime_data *prtd = runtime->private_data;
	unsigned long res;
	dma_addr_t src, dst;

	spin_lock(&prtd->lock);

	if(s3c_pcm_pdat.lp_mode)
	   s3ci2s_func->dma_getpos(&src, &dst);
	
	/* By Jung */
	res = prtd->dma_pos - prtd->dma_start;

	spin_unlock(&prtd->lock);

	s3cdbg("Pointer %x %x\n", src, dst);

	/* we seem to be getting the odd error from the pcm library due
	 * to out-of-bounds pointers. this is maybe due to the dma engine
	 * not having loaded the new values for the channel before being
	 * callled... (todo - fix )
	 */
	
	/* By Jung */
	if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		if (res >= snd_pcm_lib_buffer_bytes(substream) * ANDROID_BUF_NUM) {
			if (res == snd_pcm_lib_buffer_bytes(substream) * ANDROID_BUF_NUM)
				res = 0;
		}
	} else {
		if (res >= snd_pcm_lib_buffer_bytes(substream)) {
			if (res == snd_pcm_lib_buffer_bytes(substream))
				res = 0;
		}
	}

	return bytes_to_frames(substream->runtime, res);
}
示例#24
0
/*
 * Wait for the LR signal to allow synchronisation to the L/R clock
 * from the codec. May only be needed for slave mode.
 */
static int s5pc1xx_snd_lrsync(struct s3c_i2sv2_info *i2s)
{
	u32 iiscon;
//	unsigned long timeout = jiffies + msecs_to_jiffies(5);
	int timeout = 50; /* 5ms */

	s3cdbg("Entered %s\n", __FUNCTION__);

	while (1) {
	iiscon = readl(i2s->regs + S5PC1XX_IISCON);

		if (iiscon & S5PC1XX_IISCON_LRI)
			break;

		if (timeout < jiffies) 
			return -ETIMEDOUT;
		
	}

	return 0;
}
/*
 * Set S3C24xx Clock source
 */
static int s3c_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
	int clk_id, unsigned int freq, int dir)
{
	u32 iismod = readl(s3c24xx_i2s.regs + S3C64XX_IIS0MOD);

	s3cdbg("Entered %s : clk_id = %d\n", __FUNCTION__, clk_id);

	iismod &= ~S3C64XX_IISMOD_MPLL;

	switch (clk_id) {
	case S3C24XX_CLKSRC_PCLK:
		break;
	case S3C24XX_CLKSRC_MPLL:
		iismod |= S3C64XX_IISMOD_MPLL;
		break;
	default:
		return -EINVAL;
	}

	writel(iismod, s3c24xx_i2s.regs + S3C64XX_IIS0MOD);
	return 0;
}
示例#26
0
static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
{
	struct snd_pcm_substream *substream;
	struct snd_dma_buffer *buf;
	int stream;

	s3cdbg("Entered %s\n", __FUNCTION__);

	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;
	}
}
/*
 * Set S3C24xx Clock dividers
 */
static int s3c_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
	int div_id, int div)
{
	u32 reg;

	s3cdbg("Entered %s : div_id = %d, div = %d\n", __FUNCTION__, div_id, div);

	switch (div_id) {
	case S3C24XX_DIV_MCLK:
		break;
	case S3C24XX_DIV_BCLK:
		reg = readl(s3c24xx_i2s.regs + S3C64XX_IIS0MOD) & ~(S3C64XX_IISMOD_384FS);
		writel(reg | div, s3c24xx_i2s.regs + S3C64XX_IIS0MOD);
		break;
	case S3C24XX_DIV_PRESCALER:
		writel(div|(1<<15),s3c24xx_i2s.regs + S3C64XX_IIS0PSR);
		break;
	default:
		return -EINVAL;
	}
	
	return 0;
}
示例#28
0
static void s3c24xx_snd_rxctrl(int on)
{
	u32 iiscon;

	s3cdbg("Entered %s: on = %d\n", __FUNCTION__, on);

	iiscon  = readl(s3c24xx_i2s.regs + S3C2410_IISCON);

	if (on) {
		iiscon  |= S3C_IIS0CON_I2SACTIVE;
		writel(iiscon,  s3c24xx_i2s.regs + S3C2410_IISCON);
	} else {
		/* note, we have to disable the FIFOs otherwise bad things
		 * seem to happen when the DMA stops. According to the
		 * Samsung supplied kernel, this should allow the DMA
		 * engine and FIFOs to reset. If this isn't allowed, the
		 * DMA engine will simply freeze randomly.
		 */
		iiscon  &= ~S3C_IIS0CON_I2SACTIVE;

		writel(iiscon,  s3c24xx_i2s.regs + S3C2410_IISCON);
	}
}
static int s3c_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
{
	int ret = 0;

	s3cdbg("Entered %s: cmd = %d\n", __FUNCTION__, cmd);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		if (!s3c24xx_snd_is_clkmaster()) {
			ret = s3c24xx_snd_lrsync();
			if (ret)
				goto exit_err;
		}

		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
			s3c24xx_snd_rxctrl(1);
		else
			s3c24xx_snd_txctrl(1);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
			s3c24xx_snd_rxctrl(0);
		else
			s3c24xx_snd_txctrl(0);
		break;
	default:
		ret = -EINVAL;
		break;
	}

exit_err:
	return ret;
}
示例#30
0
static int s3c24xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
	int ret = 0;

	s3cdbg("Entered %s\n", __FUNCTION__);

	spin_lock(&prtd->lock);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		prtd->state |= ST_RUNNING;
		
		s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START);
#if !defined (CONFIG_CPU_S3C6400) && !defined (CONFIG_CPU_S3C6410) && !defined (CONFIG_CPU_S5P6440)
		s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STARTED);
#endif		
		break;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		prtd->state &= ~ST_RUNNING;
		s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP);
		break;

	default:
		ret = -EINVAL;
		break;
	}

	spin_unlock(&prtd->lock);

	return ret;
}