本文整理汇总了C++中params_channels函数的典型用法代码示例。如果您正苦于以下问题:C++ params_channels函数的具体用法?C++ params_channels怎么用?C++ params_channels使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了params_channels函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: pcm512x_hw_params
static int pcm512x_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
int alen;
int gpio;
int clock_output;
int master_mode;
int ret;
dev_dbg(codec->dev, "hw_params %u Hz, %u channels\n",
params_rate(params),
params_channels(params));
switch (snd_pcm_format_width(params_format(params))) {
case 16:
alen = PCM512x_ALEN_16;
break;
case 20:
alen = PCM512x_ALEN_20;
break;
case 24:
alen = PCM512x_ALEN_24;
break;
case 32:
alen = PCM512x_ALEN_32;
break;
default:
dev_err(codec->dev, "Bad frame size: %d\n",
snd_pcm_format_width(params_format(params)));
return -EINVAL;
}
switch (pcm512x->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
ret = regmap_update_bits(pcm512x->regmap,
PCM512x_BCLK_LRCLK_CFG,
PCM512x_BCKP
| PCM512x_BCKO | PCM512x_LRKO,
0);
if (ret != 0) {
dev_err(codec->dev,
"Failed to enable slave mode: %d\n", ret);
return ret;
}
ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT,
PCM512x_DCAS, 0);
if (ret != 0) {
dev_err(codec->dev,
"Failed to enable clock divider autoset: %d\n",
ret);
return ret;
}
return 0;
case SND_SOC_DAIFMT_CBM_CFM:
clock_output = PCM512x_BCKO | PCM512x_LRKO;
master_mode = PCM512x_RLRK | PCM512x_RBCK;
break;
case SND_SOC_DAIFMT_CBM_CFS:
clock_output = PCM512x_BCKO;
master_mode = PCM512x_RBCK;
break;
default:
return -EINVAL;
}
ret = regmap_update_bits(pcm512x->regmap, PCM512x_I2S_1,
PCM512x_ALEN, alen);
if (ret != 0) {
dev_err(codec->dev, "Failed to set frame size: %d\n", ret);
return ret;
}
if (pcm512x->pll_out) {
ret = regmap_write(pcm512x->regmap, PCM512x_FLEX_A, 0x11);
if (ret != 0) {
dev_err(codec->dev, "Failed to set FLEX_A: %d\n", ret);
return ret;
}
ret = regmap_write(pcm512x->regmap, PCM512x_FLEX_B, 0xff);
if (ret != 0) {
dev_err(codec->dev, "Failed to set FLEX_B: %d\n", ret);
return ret;
}
ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT,
PCM512x_IDFS | PCM512x_IDBK
| PCM512x_IDSK | PCM512x_IDCH
| PCM512x_IDCM | PCM512x_DCAS
| PCM512x_IPLK,
PCM512x_IDFS | PCM512x_IDBK
| PCM512x_IDSK | PCM512x_IDCH
| PCM512x_DCAS);
if (ret != 0) {
dev_err(codec->dev,
"Failed to ignore auto-clock failures: %d\n",
//.........这里部分代码省略.........
示例2: msm8960_slimbus_2_hw_params
static int msm8960_slimbus_2_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;
int ret = 0;
unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0;
unsigned int num_tx_ch = 0;
unsigned int num_rx_ch = 0;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
num_rx_ch = params_channels(params);
pr_info("%s: %s rx_dai_id = %d num_ch = %d\n", __func__,
codec_dai->name, codec_dai->id, num_rx_ch);
ret = snd_soc_dai_get_channel_map(codec_dai,
&tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
if (ret < 0) {
pr_err("%s: failed to get codec chan map\n", __func__);
goto end;
}
ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
num_rx_ch, rx_ch);
if (ret < 0) {
pr_err("%s: failed to set cpu chan map\n", __func__);
goto end;
}
ret = snd_soc_dai_set_channel_map(codec_dai, 0, 0,
num_rx_ch, rx_ch);
if (ret < 0) {
pr_err("%s: failed to set codec channel map\n",
__func__);
goto end;
}
} else {
num_tx_ch = params_channels(params);
pr_info("%s: %s tx_dai_id = %d num_ch = %d\n", __func__,
codec_dai->name, codec_dai->id, num_tx_ch);
ret = snd_soc_dai_get_channel_map(codec_dai,
&tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
if (ret < 0) {
pr_err("%s: failed to get codec chan map\n", __func__);
goto end;
}
ret = snd_soc_dai_set_channel_map(cpu_dai,
num_tx_ch, tx_ch, 0 , 0);
if (ret < 0) {
pr_err("%s: failed to set cpu chan map\n", __func__);
goto end;
}
ret = snd_soc_dai_set_channel_map(codec_dai,
num_tx_ch, tx_ch, 0, 0);
if (ret < 0) {
pr_err("%s: failed to set codec channel map\n",
__func__);
goto end;
}
}
end:
return ret;
}
示例3: s3c_pcmdev_hw_params
static int s3c_pcmdev_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
u32 value, clk_rate;
u32 bfs, rfs, sclk_div, sync_div, clk_div;
u32 audioclk, tmp;
struct clk *clk;
debug_msg("%s\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
snd_soc_dai_set_dma_data(rtd->dai->cpu_dai,
substream, &s3c_pcmdev_pcm_stereo_out);
else
snd_soc_dai_set_dma_data(rtd->dai->cpu_dai,
substream, &s3c_pcmdev_pcm_stereo_in);
switch (params_channels(params)) {
case 1:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
s3c_pcmdev_pcm_stereo_out.dma_size = 2;
else
s3c_pcmdev_pcm_stereo_in.dma_size = 2;
break;
case 2:
break;
default:
break;
}
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S8:
bfs = 16;
rfs = 256;
break;
case SNDRV_PCM_FORMAT_S16_LE:
bfs = 32;
rfs = 256;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
case SNDRV_PCM_FORMAT_S24_LE:
/* B'coz 48-BFS needs atleast 512-RFS acc to *S5P6440* UserManual */
bfs = 48;
rfs = 512;
break;
/* Impossible, as the AP doesn't support 64fs or more BFS */
case SNDRV_PCM_FORMAT_S32_LE:
default:
printk(KERN_ERR
"Inside function %s..\
Default format not supported..\n", __func__);
return -EINVAL;
}
/* Enable the interrupts */
value = readl(s3c_pcmdev.regs + S3C_PCM_IRQ_CTL);
value |= S3C_PCMIRQSTAT_TXFIFO_ALMOST_EMPTY;
value |= S3C_PCMIRQ_EN_IRQ_TO_ARM;
/*..for using interrupt mode*/
/* writel(value, s3c_pcmdev.regs + S3C_PCM_IRQ_CTL);*/
clk = clk_get(NULL, RATESRCCLK);
if (IS_ERR(clk)) {
printk(KERN_ERR
"failed to get %s\n", RATESRCCLK);
return -EBUSY;
}
clk_disable(clk);
clk_div = readl(S5P_CLK_DIV6);
clk_div &= ~(0xF<<4);
switch (params_rate(params)) {
case 8000:
case 16000:
case 32000:
clk_set_rate(clk, 49152000);
audioclk = 49152000;
break;
case 48000:
case 96000:
clk_set_rate(clk, 73728000);
audioclk = 73728000;
break;
case 11025:
case 22050:
case 44100:
case 88200:
clk_set_rate(clk, 67738000);
audioclk = 67738000;
break;
default:
printk(KERN_ERR
"Required Rate =%d..not supported\n",
params_rate(params));
return -EINVAL;
//.........这里部分代码省略.........
示例4: rockchip_i2s_hw_params
static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
struct rk30_i2s_info *i2s = to_info(dai);
u32 iismod;
u32 dmarc;
unsigned long flags;
struct hdmi_audio hdmi_audio_cfg;
I2S_DBG("Enter %s, %d \n", __func__, __LINE__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
dai->playback_dma_data = &i2s->playback_dma_data;
else
dai->capture_dma_data = &i2s->capture_dma_data;
spin_lock_irqsave(&lock, flags);
/* Working copies of register */
iismod = readl(&(pheadi2s->I2S_TXCR));
iismod &= (~((1<<5)-1));
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S8:
iismod |= SAMPLE_DATA_8bit;
break;
case SNDRV_PCM_FORMAT_S16_LE:
iismod |= I2S_DATA_WIDTH(15);
break;
case SNDRV_PCM_FORMAT_S20_3LE:
iismod |= I2S_DATA_WIDTH(19);
break;
case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_S24_3LE:
iismod |= I2S_DATA_WIDTH(23);
break;
case SNDRV_PCM_FORMAT_S32_LE:
iismod |= I2S_DATA_WIDTH(31);
break;
}
iismod &= ~CHANNLE_4_EN;
switch (params_channels(params)) {
case 8:
iismod |= CHANNLE_4_EN;
break;
case 6:
iismod |= CHANNEL_3_EN;
break;
case 4:
iismod |= CHANNEL_2_EN;
break;
case 2:
iismod |= CHANNEL_1_EN;
break;
default:
I2S_DBG("%d channels not supported\n", params_channels(params));
return -EINVAL;
}
//set hdmi codec params
if(HW_PARAMS_FLAG_NLPCM == params->flags)
hdmi_audio_cfg.type = HDMI_AUDIO_NLPCM;
else
hdmi_audio_cfg.type = HDMI_AUDIO_LPCM;
//printk("i2s: hdmi_audio_cfg.type: %d\n", hdmi_audio_cfg.type);
hdmi_audio_cfg.channel = params_channels(params);
hdmi_audio_cfg.rate = SR2FS(params_rate(params));
hdmi_audio_cfg.word_length = HDMI_AUDIO_WORD_LENGTH_16bit;
hdmi_config_audio(&hdmi_audio_cfg);
// writel((16<<24) |(16<<18)|(16<<12)|(16<<6)|16, &(pheadi2s->I2S_FIFOLR));
dmarc = readl(&(pheadi2s->I2S_DMACR));
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
dmarc = ((dmarc & 0xFFFFFE00) | 16);
else
dmarc = ((dmarc & 0xFE00FFFF) | 16<<16);
writel(dmarc, &(pheadi2s->I2S_DMACR));
I2S_DBG("Enter %s, %d I2S_TXCR=0x%08X\n", __func__, __LINE__, iismod);
writel(iismod, &(pheadi2s->I2S_TXCR));
iismod = iismod & 0x00007FFF;
writel(iismod, &(pheadi2s->I2S_RXCR));
spin_unlock_irqrestore(&lock, flags);
return 0;
}
示例5: atmel_ssc_hw_params
/*
* Configure the SSC.
*/
static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
int id = dai->id;
struct atmel_ssc_info *ssc_p = &ssc_info[id];
struct atmel_pcm_dma_params *dma_params;
int dir, channels, bits;
u32 tfmr, rfmr, tcmr, rcmr;
int start_event;
int ret;
/*
* Currently, there is only one set of dma params for
* each direction. If more are added, this code will
* have to be changed to select the proper set.
*/
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
dir = 0;
else
dir = 1;
dma_params = ssc_p->dma_params[dir];
channels = params_channels(params);
/*
* Determine sample size in bits and the PDC increment.
*/
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S8:
bits = 8;
dma_params->pdc_xfer_size = 1;
break;
case SNDRV_PCM_FORMAT_S16_LE:
bits = 16;
dma_params->pdc_xfer_size = 2;
break;
case SNDRV_PCM_FORMAT_S24_LE:
bits = 24;
dma_params->pdc_xfer_size = 4;
break;
case SNDRV_PCM_FORMAT_S32_LE:
bits = 32;
dma_params->pdc_xfer_size = 4;
break;
default:
printk(KERN_WARNING "atmel_ssc_dai: unsupported PCM format");
return -EINVAL;
}
/*
* The SSC only supports up to 16-bit samples in I2S format, due
* to the size of the Frame Mode Register FSLEN field.
*/
if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
&& bits > 16) {
printk(KERN_WARNING
"atmel_ssc_dai: sample size %d "
"is too large for I2S\n", bits);
return -EINVAL;
}
/*
* Compute SSC register settings.
*/
switch (ssc_p->daifmt
& (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
/*
* I2S format, SSC provides BCLK and LRC clocks.
*
* The SSC transmit and receive clocks are generated
* from the MCK divider, and the BCLK signal
* is output on the SSC TK line.
*/
rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
| SSC_BF(RCMR_STTDLY, START_DELAY)
| SSC_BF(RCMR_START, SSC_START_FALLING_RF)
| SSC_BF(RCMR_CKI, SSC_CKI_RISING)
| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
| SSC_BF(RCMR_CKS, SSC_CKS_DIV);
rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
| SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE)
| SSC_BF(RFMR_FSLEN, (bits - 1))
| SSC_BF(RFMR_DATNB, (channels - 1))
| SSC_BIT(RFMR_MSBF)
| SSC_BF(RFMR_LOOP, 0)
| SSC_BF(RFMR_DATLEN, (bits - 1));
tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period)
| SSC_BF(TCMR_STTDLY, START_DELAY)
| SSC_BF(TCMR_START, SSC_START_FALLING_RF)
| SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
| SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
//.........这里部分代码省略.........
示例6: mop500_ab8500_hw_params
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_dai_set_fmt(codec_dai, fmt);
if (ret < 0) {
dev_err(dev,
"%s: ERROR: snd_soc_dai_set_fmt failed for codec_dai (ret = %d)!\n",
__func__, ret);
return ret;
}
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
if (ret < 0) {
dev_err(dev,
"%s: ERROR: snd_soc_dai_set_fmt failed for cpu_dai (ret = %d)!\n",
__func__, 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;
//.........这里部分代码省略.........
示例7: aic32x4_hw_params
static int aic32x4_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
u8 data;
int i;
i = aic32x4_get_divs(aic32x4->sysclk, params_rate(params));
if (i < 0) {
printk(KERN_ERR "aic32x4: sampling rate not supported\n");
return i;
}
/* Use PLL as CODEC_CLKIN and DAC_MOD_CLK as BDIV_CLKIN */
snd_soc_write(codec, AIC32X4_CLKMUX, AIC32X4_PLLCLKIN);
snd_soc_write(codec, AIC32X4_IFACE3, AIC32X4_DACMOD2BCLK);
/* We will fix R value to 1 and will make P & J=K.D as varialble */
data = snd_soc_read(codec, AIC32X4_PLLPR);
data &= ~(7 << 4);
snd_soc_write(codec, AIC32X4_PLLPR,
(data | (aic32x4_divs[i].p_val << 4) | 0x01));
snd_soc_write(codec, AIC32X4_PLLJ, aic32x4_divs[i].pll_j);
snd_soc_write(codec, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8));
snd_soc_write(codec, AIC32X4_PLLDLSB,
(aic32x4_divs[i].pll_d & 0xff));
/* NDAC divider value */
data = snd_soc_read(codec, AIC32X4_NDAC);
data &= ~(0x7f);
snd_soc_write(codec, AIC32X4_NDAC, data | aic32x4_divs[i].ndac);
/* MDAC divider value */
data = snd_soc_read(codec, AIC32X4_MDAC);
data &= ~(0x7f);
snd_soc_write(codec, AIC32X4_MDAC, data | aic32x4_divs[i].mdac);
/* DOSR MSB & LSB values */
snd_soc_write(codec, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8);
snd_soc_write(codec, AIC32X4_DOSRLSB,
(aic32x4_divs[i].dosr & 0xff));
/* NADC divider value */
data = snd_soc_read(codec, AIC32X4_NADC);
data &= ~(0x7f);
snd_soc_write(codec, AIC32X4_NADC, data | aic32x4_divs[i].nadc);
/* MADC divider value */
data = snd_soc_read(codec, AIC32X4_MADC);
data &= ~(0x7f);
snd_soc_write(codec, AIC32X4_MADC, data | aic32x4_divs[i].madc);
/* AOSR value */
snd_soc_write(codec, AIC32X4_AOSR, aic32x4_divs[i].aosr);
/* BCLK N divider */
data = snd_soc_read(codec, AIC32X4_BCLKN);
data &= ~(0x7f);
snd_soc_write(codec, AIC32X4_BCLKN, data | aic32x4_divs[i].blck_N);
data = snd_soc_read(codec, AIC32X4_IFACE1);
data = data & ~(3 << 4);
switch (params_width(params)) {
case 16:
break;
case 20:
data |= (AIC32X4_WORD_LEN_20BITS << AIC32X4_DOSRMSB_SHIFT);
break;
case 24:
data |= (AIC32X4_WORD_LEN_24BITS << AIC32X4_DOSRMSB_SHIFT);
break;
case 32:
data |= (AIC32X4_WORD_LEN_32BITS << AIC32X4_DOSRMSB_SHIFT);
break;
}
snd_soc_write(codec, AIC32X4_IFACE1, data);
if (params_channels(params) == 1) {
data = AIC32X4_RDAC2LCHN | AIC32X4_LDAC2LCHN;
} else {
if (aic32x4->swapdacs)
data = AIC32X4_RDAC2LCHN | AIC32X4_LDAC2RCHN;
else
data = AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN;
}
snd_soc_update_bits(codec, AIC32X4_DACSETUP, AIC32X4_DAC_CHAN_MASK,
data);
return 0;
}
示例8: lpass_cpu_daiops_hw_params
static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
snd_pcm_format_t format = params_format(params);
unsigned int channels = params_channels(params);
unsigned int rate = params_rate(params);
unsigned int regval;
int bitwidth, ret;
bitwidth = snd_pcm_format_width(format);
if (bitwidth < 0) {
dev_err(dai->dev, "%s() invalid bit width given: %d\n",
__func__, bitwidth);
return bitwidth;
}
regval = LPAIF_I2SCTL_LOOPBACK_DISABLE |
LPAIF_I2SCTL_WSSRC_INTERNAL;
switch (bitwidth) {
case 16:
regval |= LPAIF_I2SCTL_BITWIDTH_16;
break;
case 24:
regval |= LPAIF_I2SCTL_BITWIDTH_24;
break;
case 32:
regval |= LPAIF_I2SCTL_BITWIDTH_32;
break;
default:
dev_err(dai->dev, "%s() invalid bitwidth given: %d\n",
__func__, bitwidth);
return -EINVAL;
}
switch (channels) {
case 1:
regval |= LPAIF_I2SCTL_SPKMODE_SD0;
regval |= LPAIF_I2SCTL_SPKMONO_MONO;
break;
case 2:
regval |= LPAIF_I2SCTL_SPKMODE_SD0;
regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
break;
case 4:
regval |= LPAIF_I2SCTL_SPKMODE_QUAD01;
regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
break;
case 6:
regval |= LPAIF_I2SCTL_SPKMODE_6CH;
regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
break;
case 8:
regval |= LPAIF_I2SCTL_SPKMODE_8CH;
regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
break;
default:
dev_err(dai->dev, "%s() invalid channels given: %u\n",
__func__, channels);
return -EINVAL;
}
ret = regmap_write(drvdata->lpaif_map,
LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id),
regval);
if (ret) {
dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
__func__, ret);
return ret;
}
ret = clk_set_rate(drvdata->mi2s_bit_clk[dai->driver->id],
rate * bitwidth * 2);
if (ret) {
dev_err(dai->dev, "%s() error setting mi2s bitclk to %u: %d\n",
__func__, rate * bitwidth * 2, ret);
return ret;
}
return 0;
}
示例9: hdmi_dai_hw_params
//.........这里部分代码省略.........
* fill the IEC-60958 channel status word
*/
/* initialize the word bytes */
memset(iec->status, 0, sizeof(iec->status));
/* specify IEC-60958-3 (commercial use) */
iec->status[0] &= ~IEC958_AES0_PROFESSIONAL;
/* specify that the audio is LPCM*/
iec->status[0] &= ~IEC958_AES0_NONAUDIO;
iec->status[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
iec->status[0] |= IEC958_AES0_CON_EMPHASIS_NONE;
iec->status[0] |= IEC958_AES1_PRO_MODE_NOTID;
iec->status[1] = IEC958_AES1_CON_GENERAL;
iec->status[2] |= IEC958_AES2_CON_SOURCE_UNSPEC;
iec->status[2] |= IEC958_AES2_CON_CHANNEL_UNSPEC;
switch (params_rate(params)) {
case 32000:
iec->status[3] |= IEC958_AES3_CON_FS_32000;
break;
case 44100:
iec->status[3] |= IEC958_AES3_CON_FS_44100;
break;
case 48000:
iec->status[3] |= IEC958_AES3_CON_FS_48000;
break;
case 88200:
iec->status[3] |= IEC958_AES3_CON_FS_88200;
break;
case 96000:
iec->status[3] |= IEC958_AES3_CON_FS_96000;
break;
case 176400:
iec->status[3] |= IEC958_AES3_CON_FS_176400;
break;
case 192000:
iec->status[3] |= IEC958_AES3_CON_FS_192000;
break;
default:
dev_err(dai->dev, "rate not supported!\n");
return -EINVAL;
}
/* specify the clock accuracy */
iec->status[3] |= IEC958_AES3_CON_CLOCK_1000PPM;
/*
* specify the word length. The same word length value can mean
* two different lengths. Hence, we need to specify the maximum
* word length as well.
*/
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
iec->status[4] |= IEC958_AES4_CON_WORDLEN_20_16;
iec->status[4] &= ~IEC958_AES4_CON_MAX_WORDLEN_24;
break;
case SNDRV_PCM_FORMAT_S24_LE:
iec->status[4] |= IEC958_AES4_CON_WORDLEN_24_20;
iec->status[4] |= IEC958_AES4_CON_MAX_WORDLEN_24;
break;
default:
dev_err(dai->dev, "format not supported!\n");
return -EINVAL;
}
/*
* Fill the CEA-861 audio infoframe (see spec for details)
*/
cea->db1_ct_cc = (params_channels(params) - 1)
& CEA861_AUDIO_INFOFRAME_DB1CC;
cea->db1_ct_cc |= CEA861_AUDIO_INFOFRAME_DB1CT_FROM_STREAM;
cea->db2_sf_ss = CEA861_AUDIO_INFOFRAME_DB2SF_FROM_STREAM;
cea->db2_sf_ss |= CEA861_AUDIO_INFOFRAME_DB2SS_FROM_STREAM;
cea->db3 = 0; /* not used, all zeros */
/*
* The OMAP HDMI IP requires to use the 8-channel channel code when
* transmitting more than two channels.
*/
if (params_channels(params) == 2)
cea->db4_ca = 0x0;
else
cea->db4_ca = 0x13;
cea->db5_dminh_lsv = CEA861_AUDIO_INFOFRAME_DB5_DM_INH_PROHIBITED;
/* the expression is trivial but makes clear what we are doing */
cea->db5_dminh_lsv |= (0 & CEA861_AUDIO_INFOFRAME_DB5_LSV);
return ad->ops->audio_config(ad->dssdev, &ad->dss_audio);
}
示例10: sst_byt_pcm_hw_params
/* this may get called several times by oss emulation */
static int sst_byt_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct sst_byt_priv_data *pdata =
snd_soc_platform_get_drvdata(rtd->platform);
struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
struct sst_byt *byt = pdata->byt;
u32 rate, bits;
u8 channels;
int ret, playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
dev_dbg(rtd->dev, "PCM: hw_params, pcm_data %p\n", pcm_data);
ret = sst_byt_stream_type(byt, pcm_data->stream,
1, 1, !playback);
if (ret < 0) {
dev_err(rtd->dev, "failed to set stream format %d\n", ret);
return ret;
}
rate = params_rate(params);
ret = sst_byt_stream_set_rate(byt, pcm_data->stream, rate);
if (ret < 0) {
dev_err(rtd->dev, "could not set rate %d\n", rate);
return ret;
}
bits = snd_pcm_format_width(params_format(params));
ret = sst_byt_stream_set_bits(byt, pcm_data->stream, bits);
if (ret < 0) {
dev_err(rtd->dev, "could not set formats %d\n",
params_rate(params));
return ret;
}
channels = (u8)(params_channels(params) & 0xF);
ret = sst_byt_stream_set_channels(byt, pcm_data->stream, channels);
if (ret < 0) {
dev_err(rtd->dev, "could not set channels %d\n",
params_rate(params));
return ret;
}
snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
ret = sst_byt_stream_buffer(byt, pcm_data->stream,
substream->dma_buffer.addr,
params_buffer_bytes(params));
if (ret < 0) {
dev_err(rtd->dev, "PCM: failed to set DMA buffer %d\n", ret);
return ret;
}
ret = sst_byt_stream_commit(byt, pcm_data->stream);
if (ret < 0) {
dev_err(rtd->dev, "PCM: failed stream commit %d\n", ret);
return ret;
}
return 0;
}
示例11: max98371_dai_hw_params
static int max98371_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
struct max98371_priv *max98371 = snd_soc_codec_get_drvdata(codec);
int blr_clk_ratio, ch_size, channels = params_channels(params);
int rate = params_rate(params);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S8:
regmap_update_bits(max98371->regmap, MAX98371_FMT,
MAX98371_FMT_MASK, MAX98371_DAI_CHANSZ_16);
ch_size = 8;
break;
case SNDRV_PCM_FORMAT_S16_LE:
regmap_update_bits(max98371->regmap, MAX98371_FMT,
MAX98371_FMT_MASK, MAX98371_DAI_CHANSZ_16);
ch_size = 16;
break;
case SNDRV_PCM_FORMAT_S24_LE:
regmap_update_bits(max98371->regmap, MAX98371_FMT,
MAX98371_FMT_MASK, MAX98371_DAI_CHANSZ_32);
ch_size = 24;
break;
case SNDRV_PCM_FORMAT_S32_LE:
regmap_update_bits(max98371->regmap, MAX98371_FMT,
MAX98371_FMT_MASK, MAX98371_DAI_CHANSZ_32);
ch_size = 32;
break;
default:
return -EINVAL;
}
/* BCLK/LRCLK ratio calculation */
blr_clk_ratio = channels * ch_size;
switch (blr_clk_ratio) {
case 32:
regmap_update_bits(max98371->regmap,
MAX98371_DAI_CLK,
MAX98371_DAI_BSEL_MASK, MAX98371_DAI_BSEL_32);
break;
case 48:
regmap_update_bits(max98371->regmap,
MAX98371_DAI_CLK,
MAX98371_DAI_BSEL_MASK, MAX98371_DAI_BSEL_48);
break;
case 64:
regmap_update_bits(max98371->regmap,
MAX98371_DAI_CLK,
MAX98371_DAI_BSEL_MASK, MAX98371_DAI_BSEL_64);
break;
default:
return -EINVAL;
}
switch (rate) {
case 32000:
regmap_update_bits(max98371->regmap,
MAX98371_SPK_SR,
MAX98371_SPK_SR_MASK, MAX98371_SPK_SR_32);
break;
case 44100:
regmap_update_bits(max98371->regmap,
MAX98371_SPK_SR,
MAX98371_SPK_SR_MASK, MAX98371_SPK_SR_44);
break;
case 48000:
regmap_update_bits(max98371->regmap,
MAX98371_SPK_SR,
MAX98371_SPK_SR_MASK, MAX98371_SPK_SR_48);
break;
case 88200:
regmap_update_bits(max98371->regmap,
MAX98371_SPK_SR,
MAX98371_SPK_SR_MASK, MAX98371_SPK_SR_88);
break;
case 96000:
regmap_update_bits(max98371->regmap,
MAX98371_SPK_SR,
MAX98371_SPK_SR_MASK, MAX98371_SPK_SR_96);
break;
default:
return -EINVAL;
}
/* enabling both the RX channels*/
regmap_update_bits(max98371->regmap, MAX98371_MONOMIX_SRC,
MAX98371_MONOMIX_SRC_MASK, MONOMIX_RX_0_1);
regmap_update_bits(max98371->regmap, MAX98371_DAI_CHANNEL,
MAX98371_CHANNEL_MASK, MAX98371_CHANNEL_MASK);
return 0;
}
示例12: s3c_pcm_hw_params
static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *socdai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai_link *dai = rtd->dai;
struct s3c_pcm_info *pcm = to_info(dai->cpu_dai);
struct s3c_dma_params *dma_data;
void __iomem *regs = pcm->regs;
struct clk *clk;
int sclk_div, sync_div;
unsigned long flags;
u32 clkctl;
u32 dma_tsfr_size = 0;
/* added by LiXueZhong on 2013.09.25 */
unsigned long srcrate;
unsigned long rate;
dev_dbg(pcm->dev, "Entered %s\n", __func__);
switch (params_channels(params)) {
case 1:
dma_tsfr_size = 2;
break;
case 2:
dma_tsfr_size = 4;
break;
case 4:
break;
case 6:
break;
default:
break;
}
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
pcm->dma_playback->dma_size = dma_tsfr_size;
dma_data = pcm->dma_playback;
} else {
pcm->dma_capture->dma_size = dma_tsfr_size;
dma_data = pcm->dma_capture;
}
snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data);
/* Strictly check for sample size */
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
break;
default:
return -EINVAL;
}
spin_lock_irqsave(&pcm->lock, flags);
/* Get hold of the PCMSOURCE_CLK */
clkctl = readl(regs + S3C_PCM_CLKCTL);
if (clkctl & S3C_PCM_CLKCTL_SERCLKSEL_PCLK)
clk = pcm->pclk;
else
clk = pcm->cclk;
/* Set the SCLK divider */
//////////////////////////////////////////
/* modified by LiXueZhong on 2013.09.25 */
srcrate = clk_get_rate(clk);
DBG("--- CLK = %u ---\n", srcrate);
rate = pcm->sclk_per_fs * params_rate(params) * 2;
sclk_div = srcrate / rate;
if (srcrate % rate)
sclk_div++;
--sclk_div;
///////////////////////////////////////////
clkctl &= ~(S3C_PCM_CLKCTL_SCLKDIV_MASK
<< S3C_PCM_CLKCTL_SCLKDIV_SHIFT);
clkctl |= ((sclk_div & S3C_PCM_CLKCTL_SCLKDIV_MASK)
<< S3C_PCM_CLKCTL_SCLKDIV_SHIFT);
/* Set the SYNC divider */
sync_div = pcm->sclk_per_fs - 1;
clkctl &= ~(S3C_PCM_CLKCTL_SYNCDIV_MASK
<< S3C_PCM_CLKCTL_SYNCDIV_SHIFT);
clkctl |= ((sync_div & S3C_PCM_CLKCTL_SYNCDIV_MASK)
<< S3C_PCM_CLKCTL_SYNCDIV_SHIFT);
writel(clkctl, regs + S3C_PCM_CLKCTL);
spin_unlock_irqrestore(&pcm->lock, flags);
/*
dev_dbg(pcm->dev, "SOURCE_CLK-%lu SCLK=%ufs SCLK_DIV=%d SYNC_DIV=%d\n",
clk_get_rate(clk), pcm->sclk_per_fs,
sclk_div, sync_div);
*/
DBG("--- SOURCE_CLK-%lu SCLK=%ufs SCLK_DIV=%d SYNC_DIV=%d ---\n",
clk_get_rate(clk), pcm->sclk_per_fs,
sclk_div, sync_div);
return 0;
}
示例13: omap_mcbsp_dai_hw_params
static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *cpu_dai)
{
struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
struct snd_dmaengine_dai_dma_data *dma_data;
int wlen, channels, wpf;
int pkt_size = 0;
unsigned int format, div, framesize, master;
dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
channels = params_channels(params);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
wlen = 16;
break;
case SNDRV_PCM_FORMAT_S32_LE:
wlen = 32;
break;
default:
return -EINVAL;
}
if (mcbsp->pdata->buffer_size) {
if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
int period_words, max_thrsh;
int divider = 0;
period_words = params_period_bytes(params) / (wlen / 8);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
max_thrsh = mcbsp->max_tx_thres;
else
max_thrsh = mcbsp->max_rx_thres;
/*
* Use sDMA packet mode if McBSP is in threshold mode:
* If period words less than the FIFO size the packet
* size is set to the number of period words, otherwise
* Look for the biggest threshold value which divides
* the period size evenly.
*/
divider = period_words / max_thrsh;
if (period_words % max_thrsh)
divider++;
while (period_words % divider &&
divider < period_words)
divider++;
if (divider == period_words)
return -EINVAL;
pkt_size = period_words / divider;
} else if (channels > 1) {
/* Use packet mode for non mono streams */
pkt_size = channels;
}
omap_mcbsp_set_threshold(substream, pkt_size);
}
dma_data->maxburst = pkt_size;
if (mcbsp->configured) {
/* McBSP already configured by another stream */
return 0;
}
regs->rcr2 &= ~(RPHASE | RFRLEN2(0x7f) | RWDLEN2(7));
regs->xcr2 &= ~(RPHASE | XFRLEN2(0x7f) | XWDLEN2(7));
regs->rcr1 &= ~(RFRLEN1(0x7f) | RWDLEN1(7));
regs->xcr1 &= ~(XFRLEN1(0x7f) | XWDLEN1(7));
format = mcbsp->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
wpf = channels;
if (channels == 2 && (format == SND_SOC_DAIFMT_I2S ||
format == SND_SOC_DAIFMT_LEFT_J)) {
/* Use dual-phase frames */
regs->rcr2 |= RPHASE;
regs->xcr2 |= XPHASE;
/* Set 1 word per (McBSP) frame for phase1 and phase2 */
wpf--;
regs->rcr2 |= RFRLEN2(wpf - 1);
regs->xcr2 |= XFRLEN2(wpf - 1);
}
regs->rcr1 |= RFRLEN1(wpf - 1);
regs->xcr1 |= XFRLEN1(wpf - 1);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
/* Set word lengths */
regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_16);
regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_16);
regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_16);
regs->xcr1 |= XWDLEN1(OMAP_MCBSP_WORD_16);
break;
case SNDRV_PCM_FORMAT_S32_LE:
/* Set word lengths */
regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_32);
regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_32);
regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_32);
regs->xcr1 |= XWDLEN1(OMAP_MCBSP_WORD_32);
break;
//.........这里部分代码省略.........
示例14: dw_i2s_hw_params
static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
struct i2s_clk_config_data *config = &dev->config;
int ret;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
config->data_width = 16;
dev->ccr = 0x00;
dev->xfer_resolution = 0x02;
break;
case SNDRV_PCM_FORMAT_S24_LE:
config->data_width = 24;
dev->ccr = 0x08;
dev->xfer_resolution = 0x04;
break;
case SNDRV_PCM_FORMAT_S32_LE:
config->data_width = 32;
dev->ccr = 0x10;
dev->xfer_resolution = 0x05;
break;
default:
dev_err(dev->dev, "designware-i2s: unsupported PCM fmt");
return -EINVAL;
}
config->chan_nr = params_channels(params);
switch (config->chan_nr) {
case EIGHT_CHANNEL_SUPPORT:
case SIX_CHANNEL_SUPPORT:
case FOUR_CHANNEL_SUPPORT:
case TWO_CHANNEL_SUPPORT:
break;
default:
dev_err(dev->dev, "channel not supported\n");
return -EINVAL;
}
dw_i2s_config(dev, substream->stream);
i2s_write_reg(dev->i2s_base, CCR, dev->ccr);
config->sample_rate = params_rate(params);
if (dev->capability & DW_I2S_MASTER) {
if (dev->i2s_clk_cfg) {
ret = dev->i2s_clk_cfg(config);
if (ret < 0) {
dev_err(dev->dev, "runtime audio clk config fail\n");
return ret;
}
} else {
u32 bitclk = config->sample_rate *
config->data_width * 2;
ret = clk_set_rate(dev->clk, bitclk);
if (ret) {
dev_err(dev->dev, "Can't set I2S clock rate: %d\n",
ret);
return ret;
}
}
}
return 0;
}
示例15: tegra_wm8903_hw_params
static int tegra_wm8903_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 snd_soc_codec *codec = rtd->codec;
struct snd_soc_card *card = codec->card;
struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
int srate, mclk, i2s_daifmt;
int err;
struct clk *clk_m;
int rate;
srate = params_rate(params);
switch (srate) {
case 64000:
case 88200:
case 96000:
mclk = 128 * srate;
break;
default:
mclk = 256 * srate;
break;
}
clk_m = clk_get_sys(NULL, "clk_m");
if (IS_ERR(clk_m)) {
dev_err(card->dev, "Can't retrieve clk clk_m\n");
err = PTR_ERR(clk_m);
return err;
}
rate = clk_get_rate(clk_m);
printk("extern1 rate=%d\n",rate);
#if TEGRA30_I2S_MASTER_PLAYBACK
/* FIXME: Codec only requires >= 3MHz if OSR==0 */
while (mclk < 6000000)
mclk *= 2;
i2s_daifmt = SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS;
#else
mclk = rate;
i2s_daifmt = SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM;
#endif
err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
if (err < 0) {
if (!(machine->util_data.set_mclk % mclk))
mclk = machine->util_data.set_mclk;
else {
dev_err(card->dev, "Can't configure clocks\n");
return err;
}
}
tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
/* Use DSP mode for mono on Tegra20 */
if ((params_channels(params) != 2) &&
(machine_is_ventana() || machine_is_harmony() ||
machine_is_kaen() || machine_is_aebl()))
i2s_daifmt |= SND_SOC_DAIFMT_DSP_A;
else
i2s_daifmt |= SND_SOC_DAIFMT_I2S;
err = snd_soc_dai_set_fmt(codec_dai, i2s_daifmt);
if (err < 0) {
dev_err(card->dev, "codec_dai fmt not set\n");
return err;
}
err = snd_soc_dai_set_fmt(cpu_dai, i2s_daifmt);
if (err < 0) {
dev_err(card->dev, "cpu_dai fmt not set\n");
return err;
}
err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev, "codec_dai clock not set\n");
return err;
}
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
err = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAP_SEL_DAC1,
TEGRA20_DAS_DAP_ID_1);
if (err < 0) {
dev_err(card->dev, "failed to set dap-dac path\n");
return err;
}
err = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_1,
//.........这里部分代码省略.........