aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Hsu <KCHSU0@nuvoton.com>2016-05-30 23:57:41 -0400
committerMark Brown <broonie@kernel.org>2016-05-31 13:38:59 -0400
commit18d8306d7e8bef79db87c3f9351eea6ae6bd3224 (patch)
tree202495b841d971db0d3357ce1e047d3e7c75ca73
parentffd72505b08ff4538db6eca9a9a498fbb1bb3679 (diff)
ASoC: nau8825: add programmable biquad filter control
Add programmable biquad filter configuration control for user space. The filter is configurable for low pass filters, high pass filters, Notch filter, etc in the ADC and DAC path. Signed-off-by: John Hsu <KCHSU0@nuvoton.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/codecs/nau8825.c53
-rw-r--r--sound/soc/codecs/nau8825.h8
2 files changed, 61 insertions, 0 deletions
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
index e988f89ef715..88e01f937657 100644
--- a/sound/soc/codecs/nau8825.c
+++ b/sound/soc/codecs/nau8825.c
@@ -217,6 +217,7 @@ static bool nau8825_volatile_reg(struct device *dev, unsigned int reg)
217 case NAU8825_REG_SARDOUT_RAM_STATUS: 217 case NAU8825_REG_SARDOUT_RAM_STATUS:
218 case NAU8825_REG_CHARGE_PUMP_INPUT_READ: 218 case NAU8825_REG_CHARGE_PUMP_INPUT_READ:
219 case NAU8825_REG_GENERAL_STATUS: 219 case NAU8825_REG_GENERAL_STATUS:
220 case NAU8825_REG_BIQ_CTRL ... NAU8825_REG_BIQ_COF10:
220 return true; 221 return true;
221 default: 222 default:
222 return false; 223 return false;
@@ -293,6 +294,54 @@ static int nau8825_output_dac_event(struct snd_soc_dapm_widget *w,
293 return 0; 294 return 0;
294} 295}
295 296
297static int nau8825_biq_coeff_get(struct snd_kcontrol *kcontrol,
298 struct snd_ctl_elem_value *ucontrol)
299{
300 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
301 struct soc_bytes_ext *params = (void *)kcontrol->private_value;
302
303 if (!component->regmap)
304 return -EINVAL;
305
306 regmap_raw_read(component->regmap, NAU8825_REG_BIQ_COF1,
307 ucontrol->value.bytes.data, params->max);
308 return 0;
309}
310
311static int nau8825_biq_coeff_put(struct snd_kcontrol *kcontrol,
312 struct snd_ctl_elem_value *ucontrol)
313{
314 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
315 struct soc_bytes_ext *params = (void *)kcontrol->private_value;
316 void *data;
317
318 if (!component->regmap)
319 return -EINVAL;
320
321 data = kmemdup(ucontrol->value.bytes.data,
322 params->max, GFP_KERNEL | GFP_DMA);
323 if (!data)
324 return -ENOMEM;
325
326 regmap_update_bits(component->regmap, NAU8825_REG_BIQ_CTRL,
327 NAU8825_BIQ_WRT_EN, 0);
328 regmap_raw_write(component->regmap, NAU8825_REG_BIQ_COF1,
329 data, params->max);
330 regmap_update_bits(component->regmap, NAU8825_REG_BIQ_CTRL,
331 NAU8825_BIQ_WRT_EN, NAU8825_BIQ_WRT_EN);
332
333 kfree(data);
334 return 0;
335}
336
337static const char * const nau8825_biq_path[] = {
338 "ADC", "DAC"
339};
340
341static const struct soc_enum nau8825_biq_path_enum =
342 SOC_ENUM_SINGLE(NAU8825_REG_BIQ_CTRL, NAU8825_BIQ_PATH_SFT,
343 ARRAY_SIZE(nau8825_biq_path), nau8825_biq_path);
344
296static const char * const nau8825_adc_decimation[] = { 345static const char * const nau8825_adc_decimation[] = {
297 "32", "64", "128", "256" 346 "32", "64", "128", "256"
298}; 347};
@@ -329,6 +378,10 @@ static const struct snd_kcontrol_new nau8825_controls[] = {
329 378
330 SOC_ENUM("ADC Decimation Rate", nau8825_adc_decimation_enum), 379 SOC_ENUM("ADC Decimation Rate", nau8825_adc_decimation_enum),
331 SOC_ENUM("DAC Oversampling Rate", nau8825_dac_oversampl_enum), 380 SOC_ENUM("DAC Oversampling Rate", nau8825_dac_oversampl_enum),
381 /* programmable biquad filter */
382 SOC_ENUM("BIQ Path Select", nau8825_biq_path_enum),
383 SND_SOC_BYTES_EXT("BIQ Coefficeints", 20,
384 nau8825_biq_coeff_get, nau8825_biq_coeff_put),
332}; 385};
333 386
334/* DAC Mux 0x33[9] and 0x34[9] */ 387/* DAC Mux 0x33[9] and 0x34[9] */
diff --git a/sound/soc/codecs/nau8825.h b/sound/soc/codecs/nau8825.h
index 9e6cb6262bf2..1293d1bf80eb 100644
--- a/sound/soc/codecs/nau8825.h
+++ b/sound/soc/codecs/nau8825.h
@@ -231,6 +231,14 @@
231#define NAU8825_I2S_MS_MASTER (1 << NAU8825_I2S_MS_SFT) 231#define NAU8825_I2S_MS_MASTER (1 << NAU8825_I2S_MS_SFT)
232#define NAU8825_I2S_MS_SLAVE (0 << NAU8825_I2S_MS_SFT) 232#define NAU8825_I2S_MS_SLAVE (0 << NAU8825_I2S_MS_SFT)
233 233
234/* BIQ_CTRL (0x20) */
235#define NAU8825_BIQ_WRT_SFT 4
236#define NAU8825_BIQ_WRT_EN (1 << NAU8825_BIQ_WRT_SFT)
237#define NAU8825_BIQ_PATH_SFT 0
238#define NAU8825_BIQ_PATH_MASK (1 << NAU8825_BIQ_PATH_SFT)
239#define NAU8825_BIQ_PATH_ADC (0 << NAU8825_BIQ_PATH_SFT)
240#define NAU8825_BIQ_PATH_DAC (1 << NAU8825_BIQ_PATH_SFT)
241
234/* ADC_RATE (0x2b) */ 242/* ADC_RATE (0x2b) */
235#define NAU8825_ADC_SYNC_DOWN_SFT 0 243#define NAU8825_ADC_SYNC_DOWN_SFT 0
236#define NAU8825_ADC_SYNC_DOWN_MASK 0x3 244#define NAU8825_ADC_SYNC_DOWN_MASK 0x3