Skip to content

Commit 22f9324

Browse files
author
Fox Snowpatch
committed
1 parent a2f7734 commit 22f9324

3 files changed

Lines changed: 158 additions & 49 deletions

File tree

sound/soc/fsl/fsl_easrc.c

Lines changed: 78 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol,
5454
unsigned int regval = ucontrol->value.integer.value[0];
5555
int ret;
5656

57+
if (regval < EASRC_WIDTH_16_BIT || regval > EASRC_WIDTH_24_BIT)
58+
return -EINVAL;
59+
5760
ret = (easrc_priv->bps_iec958[mc->regbase] != regval);
5861

5962
easrc_priv->bps_iec958[mc->regbase] = regval;
@@ -70,8 +73,16 @@ static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol,
7073
struct soc_mreg_control *mc =
7174
(struct soc_mreg_control *)kcontrol->private_value;
7275

73-
ucontrol->value.enumerated.item[0] = easrc_priv->bps_iec958[mc->regbase];
76+
ucontrol->value.integer.value[0] = easrc_priv->bps_iec958[mc->regbase];
77+
78+
return 0;
79+
}
7480

81+
static int fsl_easrc_iec958_info(struct snd_kcontrol *kcontrol,
82+
struct snd_ctl_elem_info *uinfo)
83+
{
84+
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
85+
uinfo->count = 1;
7586
return 0;
7687
}
7788

@@ -81,11 +92,33 @@ static int fsl_easrc_get_reg(struct snd_kcontrol *kcontrol,
8192
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
8293
struct soc_mreg_control *mc =
8394
(struct soc_mreg_control *)kcontrol->private_value;
84-
unsigned int regval;
95+
struct fsl_asrc *easrc = snd_soc_component_get_drvdata(component);
96+
unsigned int *regval = (unsigned int *)ucontrol->value.iec958.status;
97+
int ret;
98+
99+
ret = regmap_read(easrc->regmap, REG_EASRC_CS0(mc->regbase), &regval[0]);
100+
if (ret)
101+
return ret;
102+
103+
ret = regmap_read(easrc->regmap, REG_EASRC_CS1(mc->regbase), &regval[1]);
104+
if (ret)
105+
return ret;
106+
107+
ret = regmap_read(easrc->regmap, REG_EASRC_CS2(mc->regbase), &regval[2]);
108+
if (ret)
109+
return ret;
110+
111+
ret = regmap_read(easrc->regmap, REG_EASRC_CS3(mc->regbase), &regval[3]);
112+
if (ret)
113+
return ret;
85114

86-
regval = snd_soc_component_read(component, mc->regbase);
115+
ret = regmap_read(easrc->regmap, REG_EASRC_CS4(mc->regbase), &regval[4]);
116+
if (ret)
117+
return ret;
87118

88-
ucontrol->value.integer.value[0] = regval;
119+
ret = regmap_read(easrc->regmap, REG_EASRC_CS5(mc->regbase), &regval[5]);
120+
if (ret)
121+
return ret;
89122

90123
return 0;
91124
}
@@ -97,22 +130,52 @@ static int fsl_easrc_set_reg(struct snd_kcontrol *kcontrol,
97130
struct soc_mreg_control *mc =
98131
(struct soc_mreg_control *)kcontrol->private_value;
99132
struct fsl_asrc *easrc = snd_soc_component_get_drvdata(component);
100-
unsigned int regval = ucontrol->value.integer.value[0];
101-
bool changed;
133+
unsigned int *regval = (unsigned int *)ucontrol->value.iec958.status;
102134
int ret;
103135

104-
ret = regmap_update_bits_check(easrc->regmap, mc->regbase,
105-
GENMASK(31, 0), regval, &changed);
106-
if (ret != 0)
136+
ret = pm_runtime_resume_and_get(component->dev);
137+
if (ret)
107138
return ret;
108139

109-
return changed;
140+
ret = regmap_update_bits(easrc->regmap, REG_EASRC_CS0(mc->regbase),
141+
GENMASK(31, 0), regval[0]);
142+
if (ret != 0)
143+
goto err;
144+
145+
ret = regmap_update_bits(easrc->regmap, REG_EASRC_CS1(mc->regbase),
146+
GENMASK(31, 0), regval[1]);
147+
if (ret != 0)
148+
goto err;
149+
150+
ret = regmap_update_bits(easrc->regmap, REG_EASRC_CS2(mc->regbase),
151+
GENMASK(31, 0), regval[2]);
152+
if (ret != 0)
153+
goto err;
154+
155+
ret = regmap_update_bits(easrc->regmap, REG_EASRC_CS3(mc->regbase),
156+
GENMASK(31, 0), regval[3]);
157+
if (ret != 0)
158+
goto err;
159+
160+
ret = regmap_update_bits(easrc->regmap, REG_EASRC_CS4(mc->regbase),
161+
GENMASK(31, 0), regval[4]);
162+
if (ret != 0)
163+
goto err;
164+
165+
ret = regmap_update_bits(easrc->regmap, REG_EASRC_CS5(mc->regbase),
166+
GENMASK(31, 0), regval[5]);
167+
if (ret != 0)
168+
goto err;
169+
err:
170+
pm_runtime_put_autosuspend(component->dev);
171+
172+
return ret;
110173
}
111174

112175
#define SOC_SINGLE_REG_RW(xname, xreg) \
113176
{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = (xname), \
114177
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
115-
.info = snd_soc_info_xr_sx, .get = fsl_easrc_get_reg, \
178+
.info = fsl_easrc_iec958_info, .get = fsl_easrc_get_reg, \
116179
.put = fsl_easrc_set_reg, \
117180
.private_value = (unsigned long)&(struct soc_mreg_control) \
118181
{ .regbase = xreg, .regcount = 1, .nbits = 32, \
@@ -143,30 +206,10 @@ static const struct snd_kcontrol_new fsl_easrc_snd_controls[] = {
143206
SOC_SINGLE_VAL_RW("Context 2 IEC958 Bits Per Sample", 2),
144207
SOC_SINGLE_VAL_RW("Context 3 IEC958 Bits Per Sample", 3),
145208

146-
SOC_SINGLE_REG_RW("Context 0 IEC958 CS0", REG_EASRC_CS0(0)),
147-
SOC_SINGLE_REG_RW("Context 1 IEC958 CS0", REG_EASRC_CS0(1)),
148-
SOC_SINGLE_REG_RW("Context 2 IEC958 CS0", REG_EASRC_CS0(2)),
149-
SOC_SINGLE_REG_RW("Context 3 IEC958 CS0", REG_EASRC_CS0(3)),
150-
SOC_SINGLE_REG_RW("Context 0 IEC958 CS1", REG_EASRC_CS1(0)),
151-
SOC_SINGLE_REG_RW("Context 1 IEC958 CS1", REG_EASRC_CS1(1)),
152-
SOC_SINGLE_REG_RW("Context 2 IEC958 CS1", REG_EASRC_CS1(2)),
153-
SOC_SINGLE_REG_RW("Context 3 IEC958 CS1", REG_EASRC_CS1(3)),
154-
SOC_SINGLE_REG_RW("Context 0 IEC958 CS2", REG_EASRC_CS2(0)),
155-
SOC_SINGLE_REG_RW("Context 1 IEC958 CS2", REG_EASRC_CS2(1)),
156-
SOC_SINGLE_REG_RW("Context 2 IEC958 CS2", REG_EASRC_CS2(2)),
157-
SOC_SINGLE_REG_RW("Context 3 IEC958 CS2", REG_EASRC_CS2(3)),
158-
SOC_SINGLE_REG_RW("Context 0 IEC958 CS3", REG_EASRC_CS3(0)),
159-
SOC_SINGLE_REG_RW("Context 1 IEC958 CS3", REG_EASRC_CS3(1)),
160-
SOC_SINGLE_REG_RW("Context 2 IEC958 CS3", REG_EASRC_CS3(2)),
161-
SOC_SINGLE_REG_RW("Context 3 IEC958 CS3", REG_EASRC_CS3(3)),
162-
SOC_SINGLE_REG_RW("Context 0 IEC958 CS4", REG_EASRC_CS4(0)),
163-
SOC_SINGLE_REG_RW("Context 1 IEC958 CS4", REG_EASRC_CS4(1)),
164-
SOC_SINGLE_REG_RW("Context 2 IEC958 CS4", REG_EASRC_CS4(2)),
165-
SOC_SINGLE_REG_RW("Context 3 IEC958 CS4", REG_EASRC_CS4(3)),
166-
SOC_SINGLE_REG_RW("Context 0 IEC958 CS5", REG_EASRC_CS5(0)),
167-
SOC_SINGLE_REG_RW("Context 1 IEC958 CS5", REG_EASRC_CS5(1)),
168-
SOC_SINGLE_REG_RW("Context 2 IEC958 CS5", REG_EASRC_CS5(2)),
169-
SOC_SINGLE_REG_RW("Context 3 IEC958 CS5", REG_EASRC_CS5(3)),
209+
SOC_SINGLE_REG_RW("Context 0 IEC958 CS", 0),
210+
SOC_SINGLE_REG_RW("Context 1 IEC958 CS", 1),
211+
SOC_SINGLE_REG_RW("Context 2 IEC958 CS", 2),
212+
SOC_SINGLE_REG_RW("Context 3 IEC958 CS", 3),
170213
};
171214

172215
/*

sound/soc/fsl/fsl_micfil.c

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -210,15 +210,23 @@ static int micfil_range_set(struct snd_kcontrol *kcontrol,
210210
(struct soc_mixer_control *)kcontrol->private_value;
211211
unsigned int shift = mc->shift;
212212
int max_range, new_range;
213+
int ret;
213214

214215
new_range = ucontrol->value.integer.value[0];
215216
max_range = micfil_get_max_range(micfil);
216217
if (new_range > max_range)
217218
dev_warn(&micfil->pdev->dev, "range makes channel %d data unreliable\n", shift / 4);
218219

219-
regmap_update_bits(micfil->regmap, REG_MICFIL_OUT_CTRL, 0xF << shift, new_range << shift);
220+
ret = pm_runtime_resume_and_get(cmpnt->dev);
221+
if (ret)
222+
return ret;
220223

221-
return 0;
224+
ret = snd_soc_component_update_bits(cmpnt, REG_MICFIL_OUT_CTRL, 0xF << shift,
225+
new_range << shift);
226+
227+
pm_runtime_put_autosuspend(cmpnt->dev);
228+
229+
return ret;
222230
}
223231

224232
static int micfil_set_quality(struct fsl_micfil *micfil)
@@ -281,10 +289,34 @@ static int micfil_quality_set(struct snd_kcontrol *kcontrol,
281289
{
282290
struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
283291
struct fsl_micfil *micfil = snd_soc_component_get_drvdata(cmpnt);
292+
int val = ucontrol->value.integer.value[0];
293+
bool change = false;
294+
int old_val;
295+
int ret;
296+
297+
if (val < QUALITY_HIGH || val > QUALITY_VLOW2)
298+
return -EINVAL;
299+
300+
if (micfil->quality != val) {
301+
ret = pm_runtime_resume_and_get(cmpnt->dev);
302+
if (ret)
303+
return ret;
304+
305+
old_val = micfil->quality;
306+
micfil->quality = val;
307+
ret = micfil_set_quality(micfil);
284308

285-
micfil->quality = ucontrol->value.integer.value[0];
309+
pm_runtime_put_autosuspend(cmpnt->dev);
310+
311+
if (ret) {
312+
micfil->quality = old_val;
313+
return ret;
314+
}
286315

287-
return micfil_set_quality(micfil);
316+
change = true;
317+
}
318+
319+
return change;
288320
}
289321

290322
static const char * const micfil_hwvad_enable[] = {
@@ -343,6 +375,10 @@ static int micfil_put_dc_remover_state(struct snd_kcontrol *kcontrol,
343375
if (val < 0 || val > 3)
344376
return -EINVAL;
345377

378+
ret = pm_runtime_resume_and_get(comp->dev);
379+
if (ret)
380+
return ret;
381+
346382
micfil->dc_remover = val;
347383

348384
/* Calculate total value for all channels */
@@ -352,10 +388,10 @@ static int micfil_put_dc_remover_state(struct snd_kcontrol *kcontrol,
352388
/* Update DC Remover mode for all channels */
353389
ret = snd_soc_component_update_bits(comp, REG_MICFIL_DC_CTRL,
354390
MICFIL_DC_CTRL_CONFIG, reg_val);
355-
if (ret < 0)
356-
return ret;
357391

358-
return 0;
392+
pm_runtime_put_autosuspend(comp->dev);
393+
394+
return ret;
359395
}
360396

361397
static int micfil_get_dc_remover_state(struct snd_kcontrol *kcontrol,
@@ -377,10 +413,15 @@ static int hwvad_put_enable(struct snd_kcontrol *kcontrol,
377413
unsigned int *item = ucontrol->value.enumerated.item;
378414
struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
379415
int val = snd_soc_enum_item_to_val(e, item[0]);
416+
bool change = false;
417+
418+
if (val < 0 || val > 1)
419+
return -EINVAL;
380420

421+
change = (micfil->vad_enabled != val);
381422
micfil->vad_enabled = val;
382423

383-
return 0;
424+
return change;
384425
}
385426

386427
static int hwvad_get_enable(struct snd_kcontrol *kcontrol,
@@ -402,13 +443,18 @@ static int hwvad_put_init_mode(struct snd_kcontrol *kcontrol,
402443
unsigned int *item = ucontrol->value.enumerated.item;
403444
struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp);
404445
int val = snd_soc_enum_item_to_val(e, item[0]);
446+
bool change = false;
447+
448+
if (val < MICFIL_HWVAD_ENVELOPE_MODE || val > MICFIL_HWVAD_ENERGY_MODE)
449+
return -EINVAL;
405450

406451
/* 0 - Envelope-based Mode
407452
* 1 - Energy-based Mode
408453
*/
454+
change = (micfil->vad_init_mode != val);
409455
micfil->vad_init_mode = val;
410456

411-
return 0;
457+
return change;
412458
}
413459

414460
static int hwvad_get_init_mode(struct snd_kcontrol *kcontrol,
@@ -503,7 +549,13 @@ static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
503549
SOC_SINGLE("HWVAD ZCD Adjustment", REG_MICFIL_VAD0_ZCD, 8, 15, 0),
504550
SOC_SINGLE("HWVAD ZCD And Behavior Switch",
505551
REG_MICFIL_VAD0_ZCD, 4, 1, 0),
506-
SOC_SINGLE_BOOL_EXT("VAD Detected", 0, hwvad_detected, NULL),
552+
{
553+
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
554+
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
555+
.name = "VAD Detected",
556+
.info = snd_soc_info_bool_ext,
557+
.get = hwvad_detected,
558+
},
507559
};
508560

509561
static int fsl_micfil_use_verid(struct device *dev)

sound/soc/fsl/fsl_xcvr.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,17 @@ static int fsl_xcvr_arc_mode_put(struct snd_kcontrol *kcontrol,
115115
struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
116116
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
117117
unsigned int *item = ucontrol->value.enumerated.item;
118+
int val = snd_soc_enum_item_to_val(e, item[0]);
119+
int ret;
118120

119-
xcvr->arc_mode = snd_soc_enum_item_to_val(e, item[0]);
121+
if (val < 0 || val > 1)
122+
return -EINVAL;
120123

121-
return 0;
124+
ret = (xcvr->arc_mode != val);
125+
126+
xcvr->arc_mode = val;
127+
128+
return ret;
122129
}
123130

124131
static int fsl_xcvr_arc_mode_get(struct snd_kcontrol *kcontrol,
@@ -218,10 +225,17 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol,
218225
struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
219226
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
220227
unsigned int *item = ucontrol->value.enumerated.item;
228+
int val = snd_soc_enum_item_to_val(e, item[0]);
221229
struct snd_soc_card *card = dai->component->card;
222230
struct snd_soc_pcm_runtime *rtd;
231+
int ret;
232+
233+
if (val < FSL_XCVR_MODE_SPDIF || val > FSL_XCVR_MODE_EARC)
234+
return -EINVAL;
223235

224-
xcvr->mode = snd_soc_enum_item_to_val(e, item[0]);
236+
ret = (xcvr->mode != val);
237+
238+
xcvr->mode = val;
225239

226240
fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name,
227241
(xcvr->mode == FSL_XCVR_MODE_ARC));
@@ -231,7 +245,7 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol,
231245
rtd = snd_soc_get_pcm_runtime(card, card->dai_link);
232246
rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count =
233247
(xcvr->mode == FSL_XCVR_MODE_SPDIF ? 1 : 0);
234-
return 0;
248+
return ret;
235249
}
236250

237251
static int fsl_xcvr_mode_get(struct snd_kcontrol *kcontrol,

0 commit comments

Comments
 (0)