Exemple #1
0
static int s6000_i2s_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
{
	struct s6000_i2s_dev *dev = dai->private_data;

	if (!div || (div & 1) || div > (S6_I2S_DIV_MASK + 1) * 2)
		return -EINVAL;

	s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(div_id),
		       S6_I2S_DIV_MASK, div / 2 - 1);
	return 0;
}
Exemple #2
0
static int s6000_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
				   unsigned int fmt)
{
	struct s6000_i2s_dev *dev = cpu_dai->private_data;
	u32 w;

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBM_CFM:
		w = S6_I2S_SCK_IN | S6_I2S_WS_IN;
		break;
	case SND_SOC_DAIFMT_CBS_CFM:
		w = S6_I2S_SCK_OUT | S6_I2S_WS_IN;
		break;
	case SND_SOC_DAIFMT_CBM_CFS:
		w = S6_I2S_SCK_IN | S6_I2S_WS_OUT;
		break;
	case SND_SOC_DAIFMT_CBS_CFS:
		w = S6_I2S_SCK_OUT | S6_I2S_WS_OUT;
		break;
	default:
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		w |= S6_I2S_LEFT_FIRST;
		break;
	case SND_SOC_DAIFMT_NB_IF:
		w |= S6_I2S_RIGHT_FIRST;
		break;
	default:
		return -EINVAL;
	}

	s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(0),
		       S6_I2S_FIRST | S6_I2S_WS_DIR | S6_I2S_SCK_DIR, w);
	s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(1),
		       S6_I2S_FIRST | S6_I2S_WS_DIR | S6_I2S_SCK_DIR, w);

	return 0;
}
Exemple #3
0
static int s6000_i2s_hw_params(struct snd_pcm_substream *substream,
			       struct snd_pcm_hw_params *params,
			       struct snd_soc_dai *dai)
{
	struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
	int interf;
	u32 w = 0;

	if (dev->wide)
		interf = 0;
	else {
		w |= (((params_channels(params) - 2) / 2)
		      << S6_I2S_CHANNELS_SHIFT) & S6_I2S_CHANNELS_MASK;
		interf = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
				? dev->channel_out : dev->channel_in;
	}

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		w |= S6_I2S_16BIT | S6_I2S_MEM_16BIT;
		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		w |= S6_I2S_32BIT | S6_I2S_MEM_32BIT;
		break;
	default:
#ifdef CONFIG_DEBUG_PRINTK
		printk(KERN_WARNING "s6000-i2s: unsupported PCM format %x\n",
		       params_format(params));
#else
		;
#endif
		return -EINVAL;
	}

	if (s6_i2s_read_reg(dev, S6_I2S_INTERFACE_CFG(interf))
	     & S6_I2S_IS_ENABLED) {
		printk(KERN_ERR "s6000-i2s: interface already enabled\n");
		return -EBUSY;
	}

	s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(interf),
		       S6_I2S_CHANNELS_MASK|S6_I2S_MEM_MASK|S6_I2S_BITS_MASK,
		       w);

	return 0;
}