summaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-dapm.c
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2014-04-22 07:23:13 -0400
committerMark Brown <broonie@linaro.org>2014-04-22 08:23:35 -0400
commite2c330b9b5665006c99327c05bc22f7a8e471043 (patch)
tree2cee0640f32ee9ceeaeb3939ecad1fe127db9ba7 /sound/soc/soc-dapm.c
parent2b17ef4071d37ef5e357a4ec75686315cfa9d3e6 (diff)
ASoC: Move IO abstraction to the component level
We currently have two very similar IO abstractions in ASoC, one for CODECs, the other for platforms. Moving this to the component level will allow us to unify those two. It will also enable us to move the standard kcontrol helpers as well as DAPM support to the component level. The new component level abstraction layer is primarily build around regmap. There is a per component pointer for the regmap instance for the underlying device. There are four new function snd_soc_component_read(), snd_soc_component_write(), snd_soc_component_update_bits() and snd_soc_component_update_bits_async(). They have the same signature as their regmap counter-part and will internally forward the call one-to-one to regmap. If the component it not using regmap it will fallback to using the custom IO callbacks. This is done to be able to support drivers that haven't been converted to regmap yet, but it is expected that this will eventually be removed in the future once all component drivers have been converted to regmap. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r--sound/soc/soc-dapm.c84
1 files changed, 11 insertions, 73 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index f4ba7b40a6ab..da266e1e61b0 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -379,86 +379,24 @@ static void dapm_reset(struct snd_soc_card *card)
379static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg, 379static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg,
380 unsigned int *value) 380 unsigned int *value)
381{ 381{
382 if (w->codec) { 382 if (!w->dapm->component)
383 *value = snd_soc_read(w->codec, reg); 383 return -EIO;
384 return 0; 384 return snd_soc_component_read(w->dapm->component, reg, value);
385 } else if (w->platform) {
386 *value = snd_soc_platform_read(w->platform, reg);
387 return 0;
388 }
389
390 dev_err(w->dapm->dev, "ASoC: no valid widget read method\n");
391 return -1;
392}
393
394static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg,
395 unsigned int val)
396{
397 if (w->codec)
398 return snd_soc_write(w->codec, reg, val);
399 else if (w->platform)
400 return snd_soc_platform_write(w->platform, reg, val);
401
402 dev_err(w->dapm->dev, "ASoC: no valid widget write method\n");
403 return -1;
404}
405
406static inline void soc_widget_lock(struct snd_soc_dapm_widget *w)
407{
408 if (w->codec && !w->codec->using_regmap)
409 mutex_lock(&w->codec->mutex);
410 else if (w->platform)
411 mutex_lock(&w->platform->mutex);
412} 385}
413 386
414static inline void soc_widget_unlock(struct snd_soc_dapm_widget *w) 387static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w,
388 int reg, unsigned int mask, unsigned int value)
415{ 389{
416 if (w->codec && !w->codec->using_regmap) 390 if (!w->dapm->component)
417 mutex_unlock(&w->codec->mutex); 391 return -EIO;
418 else if (w->platform) 392 return snd_soc_component_update_bits_async(w->dapm->component, reg,
419 mutex_unlock(&w->platform->mutex); 393 mask, value);
420} 394}
421 395
422static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm) 396static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm)
423{ 397{
424 if (dapm->codec && dapm->codec->using_regmap) 398 if (dapm->component)
425 regmap_async_complete(dapm->codec->control_data); 399 snd_soc_component_async_complete(dapm->component);
426}
427
428static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w,
429 int reg, unsigned int mask, unsigned int value)
430{
431 bool change;
432 unsigned int old, new;
433 int ret;
434
435 if (w->codec && w->codec->using_regmap) {
436 ret = regmap_update_bits_check_async(w->codec->control_data,
437 reg, mask, value,
438 &change);
439 if (ret != 0)
440 return ret;
441 } else {
442 soc_widget_lock(w);
443 ret = soc_widget_read(w, reg, &old);
444 if (ret < 0) {
445 soc_widget_unlock(w);
446 return ret;
447 }
448
449 new = (old & ~mask) | (value & mask);
450 change = old != new;
451 if (change) {
452 ret = soc_widget_write(w, reg, new);
453 if (ret < 0) {
454 soc_widget_unlock(w);
455 return ret;
456 }
457 }
458 soc_widget_unlock(w);
459 }
460
461 return change;
462} 400}
463 401
464/** 402/**