aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-10-24 06:24:08 -0400
committerMark Brown <broonie@linaro.org>2013-10-24 06:24:08 -0400
commit07797e9bb67f801c04d47b323f631ff16bf2bc7e (patch)
tree65b56689a2bc13bd104ba392765c838259bd3407
parented87aabf6078ee1169c04ee9da54f03e10cbd8a3 (diff)
parentbb7838d4f13c50df8ef7324f5fd4aeb729269e22 (diff)
Merge remote-tracking branch 'asoc/topic/mc13783' into asoc-next
-rw-r--r--drivers/mfd/mc13xxx-core.c5
-rw-r--r--drivers/mfd/mc13xxx-spi.c5
-rw-r--r--include/linux/mfd/mc13xxx.h7
-rw-r--r--sound/soc/codecs/mc13783.c135
4 files changed, 91 insertions, 61 deletions
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index 2a9b100c4825..dbbf8ee3f592 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -158,8 +158,6 @@ int mc13xxx_reg_read(struct mc13xxx *mc13xxx, unsigned int offset, u32 *val)
158{ 158{
159 int ret; 159 int ret;
160 160
161 BUG_ON(!mutex_is_locked(&mc13xxx->lock));
162
163 if (offset > MC13XXX_NUMREGS) 161 if (offset > MC13XXX_NUMREGS)
164 return -EINVAL; 162 return -EINVAL;
165 163
@@ -172,8 +170,6 @@ EXPORT_SYMBOL(mc13xxx_reg_read);
172 170
173int mc13xxx_reg_write(struct mc13xxx *mc13xxx, unsigned int offset, u32 val) 171int mc13xxx_reg_write(struct mc13xxx *mc13xxx, unsigned int offset, u32 val)
174{ 172{
175 BUG_ON(!mutex_is_locked(&mc13xxx->lock));
176
177 dev_vdbg(mc13xxx->dev, "[0x%02x] <- 0x%06x\n", offset, val); 173 dev_vdbg(mc13xxx->dev, "[0x%02x] <- 0x%06x\n", offset, val);
178 174
179 if (offset > MC13XXX_NUMREGS || val > 0xffffff) 175 if (offset > MC13XXX_NUMREGS || val > 0xffffff)
@@ -186,7 +182,6 @@ EXPORT_SYMBOL(mc13xxx_reg_write);
186int mc13xxx_reg_rmw(struct mc13xxx *mc13xxx, unsigned int offset, 182int mc13xxx_reg_rmw(struct mc13xxx *mc13xxx, unsigned int offset,
187 u32 mask, u32 val) 183 u32 mask, u32 val)
188{ 184{
189 BUG_ON(!mutex_is_locked(&mc13xxx->lock));
190 BUG_ON(val & ~mask); 185 BUG_ON(val & ~mask);
191 dev_vdbg(mc13xxx->dev, "[0x%02x] <- 0x%06x (mask: 0x%06x)\n", 186 dev_vdbg(mc13xxx->dev, "[0x%02x] <- 0x%06x (mask: 0x%06x)\n",
192 offset, val, mask); 187 offset, val, mask);
diff --git a/drivers/mfd/mc13xxx-spi.c b/drivers/mfd/mc13xxx-spi.c
index 77189daadf1e..5f14ef6693c2 100644
--- a/drivers/mfd/mc13xxx-spi.c
+++ b/drivers/mfd/mc13xxx-spi.c
@@ -94,10 +94,15 @@ static int mc13xxx_spi_write(void *context, const void *data, size_t count)
94{ 94{
95 struct device *dev = context; 95 struct device *dev = context;
96 struct spi_device *spi = to_spi_device(dev); 96 struct spi_device *spi = to_spi_device(dev);
97 const char *reg = data;
97 98
98 if (count != 4) 99 if (count != 4)
99 return -ENOTSUPP; 100 return -ENOTSUPP;
100 101
102 /* include errata fix for spi audio problems */
103 if (*reg == MC13783_AUDIO_CODEC || *reg == MC13783_AUDIO_DAC)
104 spi_write(spi, data, count);
105
101 return spi_write(spi, data, count); 106 return spi_write(spi, data, count);
102} 107}
103 108
diff --git a/include/linux/mfd/mc13xxx.h b/include/linux/mfd/mc13xxx.h
index 41ed59276c00..67c17b5a6f44 100644
--- a/include/linux/mfd/mc13xxx.h
+++ b/include/linux/mfd/mc13xxx.h
@@ -41,6 +41,13 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx,
41 unsigned int mode, unsigned int channel, 41 unsigned int mode, unsigned int channel,
42 u8 ato, bool atox, unsigned int *sample); 42 u8 ato, bool atox, unsigned int *sample);
43 43
44#define MC13783_AUDIO_RX0 36
45#define MC13783_AUDIO_RX1 37
46#define MC13783_AUDIO_TX 38
47#define MC13783_SSI_NETWORK 39
48#define MC13783_AUDIO_CODEC 40
49#define MC13783_AUDIO_DAC 41
50
44#define MC13XXX_IRQ_ADCDONE 0 51#define MC13XXX_IRQ_ADCDONE 0
45#define MC13XXX_IRQ_ADCBISDONE 1 52#define MC13XXX_IRQ_ADCBISDONE 1
46#define MC13XXX_IRQ_TS 2 53#define MC13XXX_IRQ_TS 2
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index ea141e1d6f28..f5472adee674 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -30,16 +30,10 @@
30#include <sound/soc.h> 30#include <sound/soc.h>
31#include <sound/initval.h> 31#include <sound/initval.h>
32#include <sound/soc-dapm.h> 32#include <sound/soc-dapm.h>
33#include <linux/regmap.h>
33 34
34#include "mc13783.h" 35#include "mc13783.h"
35 36
36#define MC13783_AUDIO_RX0 36
37#define MC13783_AUDIO_RX1 37
38#define MC13783_AUDIO_TX 38
39#define MC13783_SSI_NETWORK 39
40#define MC13783_AUDIO_CODEC 40
41#define MC13783_AUDIO_DAC 41
42
43#define AUDIO_RX0_ALSPEN (1 << 5) 37#define AUDIO_RX0_ALSPEN (1 << 5)
44#define AUDIO_RX0_ALSPSEL (1 << 7) 38#define AUDIO_RX0_ALSPSEL (1 << 7)
45#define AUDIO_RX0_ADDCDC (1 << 21) 39#define AUDIO_RX0_ADDCDC (1 << 21)
@@ -95,45 +89,12 @@
95 89
96struct mc13783_priv { 90struct mc13783_priv {
97 struct mc13xxx *mc13xxx; 91 struct mc13xxx *mc13xxx;
92 struct regmap *regmap;
98 93
99 enum mc13783_ssi_port adc_ssi_port; 94 enum mc13783_ssi_port adc_ssi_port;
100 enum mc13783_ssi_port dac_ssi_port; 95 enum mc13783_ssi_port dac_ssi_port;
101}; 96};
102 97
103static unsigned int mc13783_read(struct snd_soc_codec *codec,
104 unsigned int reg)
105{
106 struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
107 unsigned int value = 0;
108
109 mc13xxx_lock(priv->mc13xxx);
110
111 mc13xxx_reg_read(priv->mc13xxx, reg, &value);
112
113 mc13xxx_unlock(priv->mc13xxx);
114
115 return value;
116}
117
118static int mc13783_write(struct snd_soc_codec *codec,
119 unsigned int reg, unsigned int value)
120{
121 struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
122 int ret;
123
124 mc13xxx_lock(priv->mc13xxx);
125
126 ret = mc13xxx_reg_write(priv->mc13xxx, reg, value);
127
128 /* include errata fix for spi audio problems */
129 if (reg == MC13783_AUDIO_CODEC || reg == MC13783_AUDIO_DAC)
130 ret = mc13xxx_reg_write(priv->mc13xxx, reg, value);
131
132 mc13xxx_unlock(priv->mc13xxx);
133
134 return ret;
135}
136
137/* Mapping between sample rates and register value */ 98/* Mapping between sample rates and register value */
138static unsigned int mc13783_rates[] = { 99static unsigned int mc13783_rates[] = {
139 8000, 11025, 12000, 16000, 100 8000, 11025, 12000, 16000,
@@ -466,6 +427,29 @@ static const struct snd_kcontrol_new right_input_mux =
466static const struct snd_kcontrol_new samp_ctl = 427static const struct snd_kcontrol_new samp_ctl =
467 SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 3, 1, 0); 428 SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 3, 1, 0);
468 429
430static const char * const speaker_amp_source_text[] = {
431 "CODEC", "Right"
432};
433static const SOC_ENUM_SINGLE_DECL(speaker_amp_source, MC13783_AUDIO_RX0, 4,
434 speaker_amp_source_text);
435static const struct snd_kcontrol_new speaker_amp_source_mux =
436 SOC_DAPM_ENUM("Speaker Amp Source MUX", speaker_amp_source);
437
438static const char * const headset_amp_source_text[] = {
439 "CODEC", "Mixer"
440};
441
442static const SOC_ENUM_SINGLE_DECL(headset_amp_source, MC13783_AUDIO_RX0, 11,
443 headset_amp_source_text);
444static const struct snd_kcontrol_new headset_amp_source_mux =
445 SOC_DAPM_ENUM("Headset Amp Source MUX", headset_amp_source);
446
447static const struct snd_kcontrol_new cdcout_ctl =
448 SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 18, 1, 0);
449
450static const struct snd_kcontrol_new adc_bypass_ctl =
451 SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_CODEC, 16, 1, 0);
452
469static const struct snd_kcontrol_new lamp_ctl = 453static const struct snd_kcontrol_new lamp_ctl =
470 SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 5, 1, 0); 454 SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 5, 1, 0);
471 455
@@ -503,12 +487,22 @@ static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = {
503 SND_SOC_DAPM_VIRT_MUX("PGA Right Input Mux", SND_SOC_NOPM, 0, 0, 487 SND_SOC_DAPM_VIRT_MUX("PGA Right Input Mux", SND_SOC_NOPM, 0, 0,
504 &right_input_mux), 488 &right_input_mux),
505 489
490 SND_SOC_DAPM_MUX("Speaker Amp Source MUX", SND_SOC_NOPM, 0, 0,
491 &speaker_amp_source_mux),
492
493 SND_SOC_DAPM_MUX("Headset Amp Source MUX", SND_SOC_NOPM, 0, 0,
494 &headset_amp_source_mux),
495
506 SND_SOC_DAPM_PGA("PGA Left Input", SND_SOC_NOPM, 0, 0, NULL, 0), 496 SND_SOC_DAPM_PGA("PGA Left Input", SND_SOC_NOPM, 0, 0, NULL, 0),
507 SND_SOC_DAPM_PGA("PGA Right Input", SND_SOC_NOPM, 0, 0, NULL, 0), 497 SND_SOC_DAPM_PGA("PGA Right Input", SND_SOC_NOPM, 0, 0, NULL, 0),
508 498
509 SND_SOC_DAPM_ADC("ADC", "Capture", MC13783_AUDIO_CODEC, 11, 0), 499 SND_SOC_DAPM_ADC("ADC", "Capture", MC13783_AUDIO_CODEC, 11, 0),
510 SND_SOC_DAPM_SUPPLY("ADC_Reset", MC13783_AUDIO_CODEC, 15, 0, NULL, 0), 500 SND_SOC_DAPM_SUPPLY("ADC_Reset", MC13783_AUDIO_CODEC, 15, 0, NULL, 0),
511 501
502 SND_SOC_DAPM_PGA("Voice CODEC PGA", MC13783_AUDIO_RX1, 0, 0, NULL, 0),
503 SND_SOC_DAPM_SWITCH("Voice CODEC Bypass", MC13783_AUDIO_CODEC, 16, 0,
504 &adc_bypass_ctl),
505
512/* Output */ 506/* Output */
513 SND_SOC_DAPM_SUPPLY("DAC_E", MC13783_AUDIO_DAC, 11, 0, NULL, 0), 507 SND_SOC_DAPM_SUPPLY("DAC_E", MC13783_AUDIO_DAC, 11, 0, NULL, 0),
514 SND_SOC_DAPM_SUPPLY("DAC_Reset", MC13783_AUDIO_DAC, 15, 0, NULL, 0), 508 SND_SOC_DAPM_SUPPLY("DAC_Reset", MC13783_AUDIO_DAC, 15, 0, NULL, 0),
@@ -516,10 +510,15 @@ static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = {
516 SND_SOC_DAPM_OUTPUT("RXOUTR"), 510 SND_SOC_DAPM_OUTPUT("RXOUTR"),
517 SND_SOC_DAPM_OUTPUT("HSL"), 511 SND_SOC_DAPM_OUTPUT("HSL"),
518 SND_SOC_DAPM_OUTPUT("HSR"), 512 SND_SOC_DAPM_OUTPUT("HSR"),
513 SND_SOC_DAPM_OUTPUT("LSPL"),
519 SND_SOC_DAPM_OUTPUT("LSP"), 514 SND_SOC_DAPM_OUTPUT("LSP"),
520 SND_SOC_DAPM_OUTPUT("SP"), 515 SND_SOC_DAPM_OUTPUT("SP"),
516 SND_SOC_DAPM_OUTPUT("CDCOUT"),
521 517
522 SND_SOC_DAPM_SWITCH("Speaker Amp", MC13783_AUDIO_RX0, 3, 0, &samp_ctl), 518 SND_SOC_DAPM_SWITCH("CDCOUT Switch", MC13783_AUDIO_RX0, 18, 0,
519 &cdcout_ctl),
520 SND_SOC_DAPM_SWITCH("Speaker Amp Switch", MC13783_AUDIO_RX0, 3, 0,
521 &samp_ctl),
523 SND_SOC_DAPM_SWITCH("Loudspeaker Amp", SND_SOC_NOPM, 0, 0, &lamp_ctl), 522 SND_SOC_DAPM_SWITCH("Loudspeaker Amp", SND_SOC_NOPM, 0, 0, &lamp_ctl),
524 SND_SOC_DAPM_SWITCH("Headset Amp Left", MC13783_AUDIO_RX0, 10, 0, 523 SND_SOC_DAPM_SWITCH("Headset Amp Left", MC13783_AUDIO_RX0, 10, 0,
525 &hlamp_ctl), 524 &hlamp_ctl),
@@ -554,20 +553,28 @@ static struct snd_soc_dapm_route mc13783_routes[] = {
554 { "ADC", NULL, "PGA Right Input"}, 553 { "ADC", NULL, "PGA Right Input"},
555 { "ADC", NULL, "ADC_Reset"}, 554 { "ADC", NULL, "ADC_Reset"},
556 555
556 { "Voice CODEC PGA", "Voice CODEC Bypass", "ADC" },
557
558 { "Speaker Amp Source MUX", "CODEC", "Voice CODEC PGA"},
559 { "Speaker Amp Source MUX", "Right", "DAC PGA"},
560
561 { "Headset Amp Source MUX", "CODEC", "Voice CODEC PGA"},
562 { "Headset Amp Source MUX", "Mixer", "DAC PGA"},
563
557/* Output */ 564/* Output */
558 { "HSL", NULL, "Headset Amp Left" }, 565 { "HSL", NULL, "Headset Amp Left" },
559 { "HSR", NULL, "Headset Amp Right"}, 566 { "HSR", NULL, "Headset Amp Right"},
560 { "RXOUTL", NULL, "Line out Amp Left"}, 567 { "RXOUTL", NULL, "Line out Amp Left"},
561 { "RXOUTR", NULL, "Line out Amp Right"}, 568 { "RXOUTR", NULL, "Line out Amp Right"},
562 { "SP", NULL, "Speaker Amp"}, 569 { "SP", "Speaker Amp Switch", "Speaker Amp Source MUX"},
563 { "Speaker Amp", NULL, "DAC PGA"}, 570 { "LSP", "Loudspeaker Amp", "Speaker Amp Source MUX"},
564 { "LSP", NULL, "DAC PGA"}, 571 { "HSL", "Headset Amp Left", "Headset Amp Source MUX"},
565 { "Headset Amp Left", NULL, "DAC PGA"}, 572 { "HSR", "Headset Amp Right", "Headset Amp Source MUX"},
566 { "Headset Amp Right", NULL, "DAC PGA"},
567 { "Line out Amp Left", NULL, "DAC PGA"}, 573 { "Line out Amp Left", NULL, "DAC PGA"},
568 { "Line out Amp Right", NULL, "DAC PGA"}, 574 { "Line out Amp Right", NULL, "DAC PGA"},
569 { "DAC PGA", NULL, "DAC"}, 575 { "DAC PGA", NULL, "DAC"},
570 { "DAC", NULL, "DAC_E"}, 576 { "DAC", NULL, "DAC_E"},
577 { "CDCOUT", "CDCOUT Switch", "Voice CODEC PGA"},
571}; 578};
572 579
573static const char * const mc13783_3d_mixer[] = {"Stereo", "Phase Mix", 580static const char * const mc13783_3d_mixer[] = {"Stereo", "Phase Mix",
@@ -580,15 +587,39 @@ static const struct soc_enum mc13783_enum_3d_mixer =
580static struct snd_kcontrol_new mc13783_control_list[] = { 587static struct snd_kcontrol_new mc13783_control_list[] = {
581 SOC_SINGLE("Loudspeaker enable", MC13783_AUDIO_RX0, 5, 1, 0), 588 SOC_SINGLE("Loudspeaker enable", MC13783_AUDIO_RX0, 5, 1, 0),
582 SOC_SINGLE("PCM Playback Volume", MC13783_AUDIO_RX1, 6, 15, 0), 589 SOC_SINGLE("PCM Playback Volume", MC13783_AUDIO_RX1, 6, 15, 0),
590 SOC_SINGLE("PCM Playback Switch", MC13783_AUDIO_RX1, 5, 1, 0),
583 SOC_DOUBLE("PCM Capture Volume", MC13783_AUDIO_TX, 19, 14, 31, 0), 591 SOC_DOUBLE("PCM Capture Volume", MC13783_AUDIO_TX, 19, 14, 31, 0),
584 SOC_ENUM("3D Control", mc13783_enum_3d_mixer), 592 SOC_ENUM("3D Control", mc13783_enum_3d_mixer),
593
594 SOC_SINGLE("CDCOUT Switch", MC13783_AUDIO_RX0, 18, 1, 0),
595 SOC_SINGLE("Earpiece Amp Switch", MC13783_AUDIO_RX0, 3, 1, 0),
596 SOC_DOUBLE("Headset Amp Switch", MC13783_AUDIO_RX0, 10, 9, 1, 0),
597 SOC_DOUBLE("Line out Amp Switch", MC13783_AUDIO_RX0, 16, 15, 1, 0),
598
599 SOC_SINGLE("PCM Capture Mixin Switch", MC13783_AUDIO_RX0, 22, 1, 0),
600 SOC_SINGLE("Line in Capture Mixin Switch", MC13783_AUDIO_RX0, 23, 1, 0),
601
602 SOC_SINGLE("CODEC Capture Volume", MC13783_AUDIO_RX1, 1, 15, 0),
603 SOC_SINGLE("CODEC Capture Mixin Switch", MC13783_AUDIO_RX0, 21, 1, 0),
604
605 SOC_SINGLE("Line in Capture Volume", MC13783_AUDIO_RX1, 12, 15, 0),
606 SOC_SINGLE("Line in Capture Switch", MC13783_AUDIO_RX1, 10, 1, 0),
607
608 SOC_SINGLE("MC1 Capture Bias Switch", MC13783_AUDIO_TX, 0, 1, 0),
609 SOC_SINGLE("MC2 Capture Bias Switch", MC13783_AUDIO_TX, 1, 1, 0),
585}; 610};
586 611
587static int mc13783_probe(struct snd_soc_codec *codec) 612static int mc13783_probe(struct snd_soc_codec *codec)
588{ 613{
589 struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); 614 struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
615 int ret;
590 616
591 mc13xxx_lock(priv->mc13xxx); 617 codec->control_data = dev_get_regmap(codec->dev->parent, NULL);
618 ret = snd_soc_codec_set_cache_io(codec, 8, 24, SND_SOC_REGMAP);
619 if (ret != 0) {
620 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
621 return ret;
622 }
592 623
593 /* these are the reset values */ 624 /* these are the reset values */
594 mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893); 625 mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893);
@@ -612,8 +643,6 @@ static int mc13783_probe(struct snd_soc_codec *codec)
612 mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC, 643 mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC,
613 0, AUDIO_SSI_SEL); 644 0, AUDIO_SSI_SEL);
614 645
615 mc13xxx_unlock(priv->mc13xxx);
616
617 return 0; 646 return 0;
618} 647}
619 648
@@ -621,13 +650,9 @@ static int mc13783_remove(struct snd_soc_codec *codec)
621{ 650{
622 struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); 651 struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
623 652
624 mc13xxx_lock(priv->mc13xxx);
625
626 /* Make sure VAUDIOON is off */ 653 /* Make sure VAUDIOON is off */
627 mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_RX0, 0x3, 0); 654 mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_RX0, 0x3, 0);
628 655
629 mc13xxx_unlock(priv->mc13xxx);
630
631 return 0; 656 return 0;
632} 657}
633 658
@@ -717,8 +742,6 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = {
717static struct snd_soc_codec_driver soc_codec_dev_mc13783 = { 742static struct snd_soc_codec_driver soc_codec_dev_mc13783 = {
718 .probe = mc13783_probe, 743 .probe = mc13783_probe,
719 .remove = mc13783_remove, 744 .remove = mc13783_remove,
720 .read = mc13783_read,
721 .write = mc13783_write,
722 .controls = mc13783_control_list, 745 .controls = mc13783_control_list,
723 .num_controls = ARRAY_SIZE(mc13783_control_list), 746 .num_controls = ARRAY_SIZE(mc13783_control_list),
724 .dapm_widgets = mc13783_dapm_widgets, 747 .dapm_widgets = mc13783_dapm_widgets,