Skip to content

Commit

Permalink
MLK-24422: sound: soc: fsl: imx pdm: over sampling ratio control
Browse files Browse the repository at this point in the history
Add Over sample ratio kcontrol interface, allow user
to specify over sample ratio

amixer -c1 cget numid=1
numid=1,iface=MIXER,name='over sampling ratio'
  ; type=ENUMERATED,access=rw------,values=1,items=5
  ; Item #0 'OSR_4x12'
  ; Item #1 'OSR_4x16'
  ; Item #2 'OSR_4x24'
  ; Item #3 'OSR_4x32'
  ; Item #4 'OSR_4x48'
  : values=0

Set different OSR
amixer -c1 cset numid=1 2

Signed-off-by: Adrian Alonso <[email protected]>
Reviewed-by: Viorel Suman <[email protected]>
  • Loading branch information
Adrian Alonso committed Jul 20, 2020
1 parent e48d080 commit de79414
Showing 1 changed file with 88 additions and 0 deletions.
88 changes: 88 additions & 0 deletions sound/soc/fsl/imx-pdm.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct imx_pdm_data {
struct snd_soc_dai_link dai;
struct snd_soc_card card;
unsigned int decimation;
int osr_id;
};

static const struct imx_pdm_mic_fs_mul {
Expand All @@ -40,6 +41,84 @@ static const unsigned int imx_pdm_mic_rates[] = {
8000, 11025, 16000, 22050,
32000, 44100, 48000, 64000,
};

static const struct imx_pdm_mic_osr_map {
int id;
unsigned int osr;
} osr_map[] = {
{ .id = 0, .osr = 48 }, /* 4x12 */
{ .id = 1, .osr = 64 }, /* 4x16 */
{ .id = 2, .osr = 96 }, /* 4x24 */
{ .id = 3, .osr = 128 }, /* 4x32 */
{ .id = 4, .osr = 192 }, /* 4x48 */
};

static int imx_pdm_mic_get_osr_id(int decimation)
{
int i;

for (i = 0; i < ARRAY_SIZE(osr_map); i++) {
if (osr_map[i].osr == decimation)
return osr_map[i].id;
}

return -EINVAL;
}

static unsigned int imx_pdm_mic_get_osr_rate(int osr_id)
{
int i;

for (i = 0; ARRAY_SIZE(osr_map); i++) {
if (osr_map[i].id == osr_id)
return osr_map[i].osr;
}

return -EINVAL;
}

static const char *const osr_rate_text[] = {
"OSR_4x12",
"OSR_4x16",
"OSR_4x24",
"OSR_4x32",
"OSR_4x48"
};

static int osr_rate_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
struct imx_pdm_data *data = snd_soc_card_get_drvdata(card);

ucontrol->value.enumerated.item[0] = data->osr_id;

return 0;
}

static int osr_rate_set(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
struct imx_pdm_data *data = snd_soc_card_get_drvdata(card);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int *item = ucontrol->value.enumerated.item;
int osr = snd_soc_enum_item_to_val(e, item[0]);

data->decimation = imx_pdm_mic_get_osr_rate(osr);
data->osr_id = osr;

return 0;
}

static const struct soc_enum osr_rate_enum =
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(osr_rate_text), osr_rate_text);

const struct snd_kcontrol_new imx_pdm_mic_snd_ctrls[] = {
SOC_ENUM_EXT("over sampling ratio", osr_rate_enum,
osr_rate_get, osr_rate_set),
};

static struct snd_pcm_hw_constraint_list imx_pdm_mic_rate_constrains = {
.count = ARRAY_SIZE(imx_pdm_mic_rates),
.list = imx_pdm_mic_rates,
Expand All @@ -64,6 +143,7 @@ static unsigned long imx_pdm_mic_mclk_freq(unsigned int decimation,
return 0;
}


static int imx_pdm_mic_startup(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
Expand Down Expand Up @@ -180,6 +260,12 @@ static int imx_pdm_mic_probe(struct platform_device *pdev)
goto fail;
}

data->osr_id = imx_pdm_mic_get_osr_id(data->decimation);
if (data->osr_id < 0) {
ret = -EINVAL;
goto fail;
}

data->dai.cpus = &dlc[0];
data->dai.num_cpus = 1;
data->dai.platforms = &dlc[1];
Expand Down Expand Up @@ -207,6 +293,8 @@ static int imx_pdm_mic_probe(struct platform_device *pdev)

data->card.num_links = 1;
data->card.dai_link = &data->dai;
data->card.controls = imx_pdm_mic_snd_ctrls;
data->card.num_controls = ARRAY_SIZE(imx_pdm_mic_snd_ctrls);

platform_set_drvdata(pdev, &data->card);
snd_soc_card_set_drvdata(&data->card, data);
Expand Down

0 comments on commit de79414

Please sign in to comment.