ASoC: intel: add support for specifying PCM format

With this machines can configure the PCM format applied on SSP port using
the set_fmt API

Signed-off-by: Praveen Diwakar <praveen.diwakar@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Vinod Koul
2015-05-06 22:06:43 +05:30
committed by Mark Brown
부모 711bc9476b
커밋 0b44e34549
3개의 변경된 파일115개의 추가작업 그리고 0개의 파일을 삭제

파일 보기

@@ -774,8 +774,107 @@ int sst_handle_vb_timer(struct snd_soc_dai *dai, bool enable)
return ret;
}
static int sst_get_frame_sync_polarity(struct snd_soc_dai *dai,
unsigned int fmt)
{
int format;
format = fmt & SND_SOC_DAIFMT_INV_MASK;
dev_dbg(dai->dev, "Enter:%s, format=%x\n", __func__, format);
switch (format) {
case SND_SOC_DAIFMT_NB_NF:
return SSP_FS_ACTIVE_LOW;
case SND_SOC_DAIFMT_NB_IF:
return SSP_FS_ACTIVE_HIGH;
case SND_SOC_DAIFMT_IB_IF:
return SSP_FS_ACTIVE_LOW;
case SND_SOC_DAIFMT_IB_NF:
return SSP_FS_ACTIVE_HIGH;
default:
dev_err(dai->dev, "Invalid frame sync polarity %d\n", format);
}
return -EINVAL;
}
static int sst_get_ssp_mode(struct snd_soc_dai *dai, unsigned int fmt)
{
int format;
format = (fmt & SND_SOC_DAIFMT_MASTER_MASK);
dev_dbg(dai->dev, "Enter:%s, format=%x\n", __func__, format);
switch (format) {
case SND_SOC_DAIFMT_CBS_CFS:
return SSP_MODE_MASTER;
case SND_SOC_DAIFMT_CBM_CFM:
return SSP_MODE_SLAVE;
default:
dev_err(dai->dev, "Invalid ssp protocol: %d\n", format);
}
return -EINVAL;
}
int sst_fill_ssp_config(struct snd_soc_dai *dai, unsigned int fmt)
{
unsigned int mode;
int fs_polarity;
struct sst_data *ctx = snd_soc_dai_get_drvdata(dai);
mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
switch (mode) {
case SND_SOC_DAIFMT_DSP_B:
ctx->ssp_cmd.ssp_protocol = SSP_MODE_PCM;
ctx->ssp_cmd.mode = sst_get_ssp_mode(dai, fmt) | (SSP_PCM_MODE_NETWORK << 1);
ctx->ssp_cmd.start_delay = 0;
ctx->ssp_cmd.data_polarity = 1;
ctx->ssp_cmd.frame_sync_width = 1;
break;
case SND_SOC_DAIFMT_DSP_A:
ctx->ssp_cmd.ssp_protocol = SSP_MODE_PCM;
ctx->ssp_cmd.mode = sst_get_ssp_mode(dai, fmt) | (SSP_PCM_MODE_NETWORK << 1);
ctx->ssp_cmd.start_delay = 1;
ctx->ssp_cmd.data_polarity = 1;
ctx->ssp_cmd.frame_sync_width = 1;
break;
case SND_SOC_DAIFMT_I2S:
ctx->ssp_cmd.ssp_protocol = SSP_MODE_I2S;
ctx->ssp_cmd.mode = sst_get_ssp_mode(dai, fmt) | (SSP_PCM_MODE_NORMAL << 1);
ctx->ssp_cmd.start_delay = 1;
ctx->ssp_cmd.data_polarity = 0;
ctx->ssp_cmd.frame_sync_width = ctx->ssp_cmd.nb_bits_per_slots;
break;
case SND_SOC_DAIFMT_LEFT_J:
ctx->ssp_cmd.ssp_protocol = SSP_MODE_I2S;
ctx->ssp_cmd.mode = sst_get_ssp_mode(dai, fmt) | (SSP_PCM_MODE_NORMAL << 1);
ctx->ssp_cmd.start_delay = 0;
ctx->ssp_cmd.data_polarity = 0;
ctx->ssp_cmd.frame_sync_width = ctx->ssp_cmd.nb_bits_per_slots;
break;
default:
dev_dbg(dai->dev, "using default ssp configs\n");
}
fs_polarity = sst_get_frame_sync_polarity(dai, fmt);
if (fs_polarity < 0)
return fs_polarity;
ctx->ssp_cmd.frame_sync_polarity = fs_polarity;
return 0;
}
/**
* sst_ssp_config - contains SSP configuration for media UC
* this can be overwritten by set_dai_xxx APIs
*/
static const struct sst_ssp_config sst_ssp_configs = {
.ssp_id = SSP_CODEC,