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); }
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; }