Esempio n. 1
0
static int omap_twl4030_hw_params(struct snd_pcm_substream *substream,
                                  struct snd_pcm_hw_params *params)
{
    struct snd_soc_pcm_runtime *rtd = substream->private_data;
    unsigned int fmt;

    switch (params_channels(params)) {
    case 2: /* Stereo I2S mode */
        fmt =	SND_SOC_DAIFMT_I2S |
                SND_SOC_DAIFMT_NB_NF |
                SND_SOC_DAIFMT_CBM_CFM;
        break;
    case 4: /* Four channel TDM mode */
        fmt =	SND_SOC_DAIFMT_DSP_A |
                SND_SOC_DAIFMT_IB_NF |
                SND_SOC_DAIFMT_CBM_CFM;
        break;
    default:
        return -EINVAL;
    }

    return snd_soc_runtime_set_dai_fmt(rtd, fmt);
}
Esempio n. 2
0
static int mop500_ab8500_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;
	struct device *dev = rtd->card->dev;
	unsigned int fmt;
	int channels, ret = 0, driver_mode, slots;
	unsigned int sw_codec, sw_cpu;
	bool is_playback;

	dev_dbg(dev, "%s: Enter\n", __func__);

	dev_dbg(dev, "%s: substream->pcm->name = %s\n"
		"substream->pcm->id = %s.\n"
		"substream->name = %s.\n"
		"substream->number = %d.\n",
		__func__,
		substream->pcm->name,
		substream->pcm->id,
		substream->name,
		substream->number);

	/* Ensure configuration consistency between DAIs */
	mutex_lock(&mop500_ab8500_params_lock);
	if (mop500_ab8500_usage) {
		if (mop500_ab8500_rate != params_rate(params) ||
		    mop500_ab8500_channels != params_channels(params)) {
			mutex_unlock(&mop500_ab8500_params_lock);
			return -EBUSY;
		}
	} else {
		mop500_ab8500_rate = params_rate(params);
		mop500_ab8500_channels = params_channels(params);
	}
	__set_bit(cpu_dai->id, &mop500_ab8500_usage);
	mutex_unlock(&mop500_ab8500_params_lock);

	channels = params_channels(params);

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S32_LE:
		sw_cpu = 32;
		break;

	case SNDRV_PCM_FORMAT_S16_LE:
		sw_cpu = 16;
		break;

	default:
		return -EINVAL;
	}

	/* Setup codec depending on driver-mode */
	if (channels == 8)
		driver_mode = DRIVERMODE_CODEC_ONLY;
	else
		driver_mode = DRIVERMODE_NORMAL;
	dev_dbg(dev, "%s: Driver-mode: %s.\n", __func__,
		(driver_mode == DRIVERMODE_NORMAL) ? "NORMAL" : "CODEC_ONLY");

	/* Setup format */

	if (driver_mode == DRIVERMODE_NORMAL) {
		fmt = SND_SOC_DAIFMT_DSP_A |
			SND_SOC_DAIFMT_CBM_CFM |
			SND_SOC_DAIFMT_NB_NF |
			SND_SOC_DAIFMT_CONT;
	} else {
		fmt = SND_SOC_DAIFMT_DSP_A |
			SND_SOC_DAIFMT_CBM_CFM |
			SND_SOC_DAIFMT_NB_NF |
			SND_SOC_DAIFMT_GATED;
	}

	ret = snd_soc_runtime_set_dai_fmt(rtd, fmt);
	if (ret)
		return ret;

	/* Setup TDM-slots */

	is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
	switch (channels) {
	case 1:
		slots = 16;
		tx_slots = (is_playback) ? TX_SLOT_MONO : 0;
		rx_slots = (is_playback) ? 0 : RX_SLOT_MONO;
		break;
	case 2:
		slots = 16;
		tx_slots = (is_playback) ? TX_SLOT_STEREO : 0;
		rx_slots = (is_playback) ? 0 : RX_SLOT_STEREO;
		break;
	case 8:
		slots = 16;
		tx_slots = (is_playback) ? TX_SLOT_8CH : 0;
		rx_slots = (is_playback) ? 0 : RX_SLOT_8CH;
		break;
	default:
		return -EINVAL;
	}

	if (driver_mode == DRIVERMODE_NORMAL)
		sw_codec = sw_cpu;
	else
		sw_codec = 20;

	dev_dbg(dev, "%s: CPU-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__,
		tx_slots, rx_slots);
	ret = snd_soc_dai_set_tdm_slot(cpu_dai, tx_slots, rx_slots, slots,
				sw_cpu);
	if (ret)
		return ret;

	dev_dbg(dev, "%s: CODEC-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__,
		tx_slots, rx_slots);
	ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_slots, rx_slots, slots,
				sw_codec);
	if (ret)
		return ret;

	return 0;
}