static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var, unsigned int val, int dir) { int changed; if (hw_is_mask(var)) { struct snd_mask *m = hw_param_mask(params, var); if (val == 0 && dir < 0) { changed = -EINVAL; snd_mask_none(m); } else { if (dir > 0) val++; else if (dir < 0) val--; changed = snd_mask_refine_set( hw_param_mask(params, var), val); } } else if (hw_is_interval(var)) { struct snd_interval *i = hw_param_interval(params, var); if (val == 0 && dir < 0) { changed = -EINVAL; snd_interval_none(i); } else if (dir == 0) changed = snd_interval_refine_set(i, val); else { struct snd_interval t; t.openmin = 1; t.openmax = 1; t.empty = 0; t.integer = 0; if (dir < 0) { t.min = val - 1; t.max = val; } else { t.min = val; t.max = val+1; } changed = snd_interval_refine(i, &t); } } else { return -EINVAL; } if (changed) { params->cmask |= 1 << var; params->rmask |= 1 << var; } return changed; }
static void compr_config_hw_params(struct snd_pcm_hw_params *params, struct snd_compr_params *compr_params) { u64 fmt; int acodec_rate = 48000; pr_debug("%s\n", __func__); fmt = ffs(SNDRV_PCM_FMTBIT_S16_LE) - 1; snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), fmt); hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min = 16; hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS)->min = 32; hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min = 2; #ifdef CONFIG_SND_ESA_SA_EFFECT acodec_rate = esa_compr_get_sample_rate(); if (!acodec_rate) acodec_rate = 48000; #endif pr_info("%s input_SR %d PCM_HW_PARAM_RATE %d \n", __func__, compr_params->codec.sample_rate, acodec_rate); hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min = acodec_rate; }
static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct imx_priv *priv = &card_priv; hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min = priv->fe_output_rate; hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max = priv->fe_output_rate; snd_mask_none(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT)); if (priv->fe_output_width == 16) snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), SNDRV_PCM_FORMAT_S16_LE); else snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), SNDRV_PCM_FORMAT_S24_LE); return 0; }
static int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var, unsigned int val, int dir) { int changed; int open = 0; if (dir) { if (dir > 0) { open = 1; } else if (dir < 0) { if (val > 0) { open = 1; val--; } } } if (hw_is_mask(var)) changed = snd_mask_refine_min(hw_param_mask(params, var), val + !!open); else if (hw_is_interval(var)) changed = snd_interval_refine_min(hw_param_interval(params, var), val, open); else return -EINVAL; if (changed) { params->cmask |= 1 << var; params->rmask |= 1 << var; } return changed; }
static int snd_pmac_hw_rule_format(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) { struct snd_pmac *chip = rule->private; struct pmac_stream *rec = snd_pmac_get_stream(chip, rule->deps[0]); if (! rec) return -EINVAL; return snd_mask_refine_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), rec->cur_formats); }
static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var, const struct snd_mask *val) { int changed; changed = snd_mask_refine(hw_param_mask(params, var), val); if (changed) { params->cmask |= 1 << var; params->rmask |= 1 << var; } return changed; }
static int rule_format(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) { struct snd_pcm_hardware *hw = rule->private; struct snd_mask *maskp = hw_param_mask(params, rule->var); maskp->bits[0] &= (u_int32_t)hw->formats; maskp->bits[1] &= (u_int32_t)(hw->formats >> 32); memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); if (! maskp->bits[0] && ! maskp->bits[1]) return -EINVAL; return 0; }
static int sdm845_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); rate->min = rate->max = DEFAULT_SAMPLE_RATE_48K; channels->min = channels->max = 2; snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); return 0; }
static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); struct snd_interval *rate; struct snd_mask *mask; rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); rate->max = rate->min = priv->asrc_rate; mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); snd_mask_none(mask); snd_mask_set(mask, priv->asrc_format); return 0; }
static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct imx_priv *priv = &card_priv; struct snd_interval *rate; struct snd_mask *mask; if (!priv->asrc_pdev) return -EINVAL; rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); rate->max = rate->min = priv->asrc_rate; mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); snd_mask_none(mask); snd_mask_set(mask, priv->asrc_format); return 0; }
static int snd_pcm_ioplug_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { int change = 0, change1, change2, err; ioplug_priv_t *io = pcm->private_data; struct snd_ext_parm *p; unsigned int i; /* access, format */ for (i = SND_PCM_IOPLUG_HW_ACCESS; i <= SND_PCM_IOPLUG_HW_FORMAT; i++) { err = snd_ext_parm_mask_refine(hw_param_mask(params, hw_params_type[i]), io->params, i); if (err < 0) return err; change |= err; } /* channels, rate */ for (; i <= SND_PCM_IOPLUG_HW_RATE; i++) { err = snd_ext_parm_interval_refine(hw_param_interval(params, hw_params_type[i]), io->params, i); if (err < 0) return err; change |= err; } if (params->rmask & ((1 << SND_PCM_HW_PARAM_ACCESS) | (1 << SND_PCM_HW_PARAM_FORMAT) | (1 << SND_PCM_HW_PARAM_SUBFORMAT) | (1 << SND_PCM_HW_PARAM_CHANNELS) | (1 << SND_PCM_HW_PARAM_RATE))) { err = snd_pcm_hw_refine_soft(pcm, params); if (err < 0) return err; change |= err; } change1 = refine_time_and_size(params, SND_PCM_HW_PARAM_PERIOD_TIME, SND_PCM_HW_PARAM_PERIOD_SIZE, SND_PCM_HW_PARAM_PERIOD_BYTES); if (change1 < 0) return change1; err = snd_ext_parm_interval_refine(hw_param_interval(params, SND_PCM_HW_PARAM_PERIOD_BYTES), io->params, SND_PCM_IOPLUG_HW_PERIOD_BYTES); if (err < 0) return err; change1 |= err; if (change1) { change |= change1; err = refine_back_time_and_size(params, SND_PCM_HW_PARAM_PERIOD_TIME, SND_PCM_HW_PARAM_PERIOD_SIZE, SND_PCM_HW_PARAM_PERIOD_BYTES); if (err < 0) return err; } change1 = refine_time_and_size(params, SND_PCM_HW_PARAM_BUFFER_TIME, SND_PCM_HW_PARAM_BUFFER_SIZE, SND_PCM_HW_PARAM_BUFFER_BYTES); if (change1 < 0) return change1; change |= change1; do { change2 = 0; err = snd_ext_parm_interval_refine(hw_param_interval(params, SND_PCM_HW_PARAM_BUFFER_BYTES), io->params, SND_PCM_IOPLUG_HW_BUFFER_BYTES); if (err < 0) return err; change2 |= err; /* periods = buffer_bytes / period_bytes */ err = rule_div(params, SND_PCM_HW_PARAM_PERIODS, SND_PCM_HW_PARAM_BUFFER_BYTES, SND_PCM_HW_PARAM_PERIOD_BYTES); if (err < 0) return err; change2 |= err; err = snd_ext_parm_interval_refine(hw_param_interval(params, SND_PCM_HW_PARAM_PERIODS), io->params, SND_PCM_IOPLUG_HW_PERIODS); if (err < 0) return err; change2 |= err; /* buffer_bytes = periods * period_bytes */ err = rule_mul(params, SND_PCM_HW_PARAM_BUFFER_BYTES, SND_PCM_HW_PARAM_PERIOD_BYTES, SND_PCM_HW_PARAM_PERIODS); if (err < 0) return err; change2 |= err; change1 |= change2; } while (change2); change |= change1; if (change1) { err = refine_back_time_and_size(params, SND_PCM_HW_PARAM_BUFFER_TIME, SND_PCM_HW_PARAM_BUFFER_SIZE, SND_PCM_HW_PARAM_BUFFER_BYTES); if (err < 0) return err; } /* period_bytes = buffer_bytes / periods */ err = rule_div(params, SND_PCM_HW_PARAM_PERIOD_BYTES, SND_PCM_HW_PARAM_BUFFER_BYTES, SND_PCM_HW_PARAM_PERIODS); if (err < 0) return err; if (err) { /* update period_size and period_time */ change |= err; err = snd_ext_parm_interval_refine(hw_param_interval(params, SND_PCM_HW_PARAM_PERIOD_BYTES), io->params, SND_PCM_IOPLUG_HW_PERIOD_BYTES); if (err < 0) return err; err = refine_back_time_and_size(params, SND_PCM_HW_PARAM_PERIOD_TIME, SND_PCM_HW_PARAM_PERIOD_SIZE, SND_PCM_HW_PARAM_PERIOD_BYTES); if (err < 0) return err; } params->info = SND_PCM_INFO_BLOCK_TRANSFER; p = &io->params[SND_PCM_IOPLUG_HW_ACCESS]; if (p->active) { for (i = 0; i < p->num_list; i++) switch (p->list[i]) { case SND_PCM_ACCESS_MMAP_INTERLEAVED: case SND_PCM_ACCESS_RW_INTERLEAVED: params->info |= SND_PCM_INFO_INTERLEAVED; break; case SND_PCM_ACCESS_MMAP_NONINTERLEAVED: case SND_PCM_ACCESS_RW_NONINTERLEAVED: params->info |= SND_PCM_INFO_NONINTERLEAVED; break; } } if (io->data->callback->pause) params->info |= SND_PCM_INFO_PAUSE; if (io->data->callback->resume) params->info |= SND_PCM_INFO_RESUME; #if 0 fprintf(stderr, "XXX\n"); dump_parm(params); #endif return change; }