Merge remote-tracking branches 'asoc/fix/alc5632', 'asoc/fix/cs42l52', 'asoc/fix...
[cascardo/linux.git] / sound / soc / codecs / max98090.c
index 51f9b3d..f7b0b37 100644 (file)
@@ -336,6 +336,7 @@ static bool max98090_readable_register(struct device *dev, unsigned int reg)
        case M98090_REG_RECORD_TDM_SLOT:
        case M98090_REG_SAMPLE_RATE:
        case M98090_REG_DMIC34_BIQUAD_BASE ... M98090_REG_DMIC34_BIQUAD_BASE + 0x0E:
+       case M98090_REG_REVISION_ID:
                return true;
        default:
                return false;
@@ -512,65 +513,75 @@ static const char *max98090_perf_pwr_text[] =
 static const char *max98090_pwr_perf_text[] =
        { "Low Power", "High Performance" };
 
-static const struct soc_enum max98090_vcmbandgap_enum =
-       SOC_ENUM_SINGLE(M98090_REG_BIAS_CONTROL, M98090_VCM_MODE_SHIFT,
-               ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text);
+static SOC_ENUM_SINGLE_DECL(max98090_vcmbandgap_enum,
+                           M98090_REG_BIAS_CONTROL,
+                           M98090_VCM_MODE_SHIFT,
+                           max98090_pwr_perf_text);
 
 static const char *max98090_osr128_text[] = { "64*fs", "128*fs" };
 
-static const struct soc_enum max98090_osr128_enum =
-       SOC_ENUM_SINGLE(M98090_REG_ADC_CONTROL, M98090_OSR128_SHIFT,
-               ARRAY_SIZE(max98090_osr128_text), max98090_osr128_text);
+static SOC_ENUM_SINGLE_DECL(max98090_osr128_enum,
+                           M98090_REG_ADC_CONTROL,
+                           M98090_OSR128_SHIFT,
+                           max98090_osr128_text);
 
 static const char *max98090_mode_text[] = { "Voice", "Music" };
 
-static const struct soc_enum max98090_mode_enum =
-       SOC_ENUM_SINGLE(M98090_REG_FILTER_CONFIG, M98090_MODE_SHIFT,
-               ARRAY_SIZE(max98090_mode_text), max98090_mode_text);
+static SOC_ENUM_SINGLE_DECL(max98090_mode_enum,
+                           M98090_REG_FILTER_CONFIG,
+                           M98090_MODE_SHIFT,
+                           max98090_mode_text);
 
-static const struct soc_enum max98090_filter_dmic34mode_enum =
-       SOC_ENUM_SINGLE(M98090_REG_FILTER_CONFIG,
-               M98090_FLT_DMIC34MODE_SHIFT,
-               ARRAY_SIZE(max98090_mode_text), max98090_mode_text);
+static SOC_ENUM_SINGLE_DECL(max98090_filter_dmic34mode_enum,
+                           M98090_REG_FILTER_CONFIG,
+                           M98090_FLT_DMIC34MODE_SHIFT,
+                           max98090_mode_text);
 
 static const char *max98090_drcatk_text[] =
        { "0.5ms", "1ms", "5ms", "10ms", "25ms", "50ms", "100ms", "200ms" };
 
-static const struct soc_enum max98090_drcatk_enum =
-       SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCATK_SHIFT,
-               ARRAY_SIZE(max98090_drcatk_text), max98090_drcatk_text);
+static SOC_ENUM_SINGLE_DECL(max98090_drcatk_enum,
+                           M98090_REG_DRC_TIMING,
+                           M98090_DRCATK_SHIFT,
+                           max98090_drcatk_text);
 
 static const char *max98090_drcrls_text[] =
        { "8s", "4s", "2s", "1s", "0.5s", "0.25s", "0.125s", "0.0625s" };
 
-static const struct soc_enum max98090_drcrls_enum =
-       SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCRLS_SHIFT,
-               ARRAY_SIZE(max98090_drcrls_text), max98090_drcrls_text);
+static SOC_ENUM_SINGLE_DECL(max98090_drcrls_enum,
+                           M98090_REG_DRC_TIMING,
+                           M98090_DRCRLS_SHIFT,
+                           max98090_drcrls_text);
 
 static const char *max98090_alccmp_text[] =
        { "1:1", "1:1.5", "1:2", "1:4", "1:INF" };
 
-static const struct soc_enum max98090_alccmp_enum =
-       SOC_ENUM_SINGLE(M98090_REG_DRC_COMPRESSOR, M98090_DRCCMP_SHIFT,
-               ARRAY_SIZE(max98090_alccmp_text), max98090_alccmp_text);
+static SOC_ENUM_SINGLE_DECL(max98090_alccmp_enum,
+                           M98090_REG_DRC_COMPRESSOR,
+                           M98090_DRCCMP_SHIFT,
+                           max98090_alccmp_text);
 
 static const char *max98090_drcexp_text[] = { "1:1", "2:1", "3:1" };
 
-static const struct soc_enum max98090_drcexp_enum =
-       SOC_ENUM_SINGLE(M98090_REG_DRC_EXPANDER, M98090_DRCEXP_SHIFT,
-               ARRAY_SIZE(max98090_drcexp_text), max98090_drcexp_text);
+static SOC_ENUM_SINGLE_DECL(max98090_drcexp_enum,
+                           M98090_REG_DRC_EXPANDER,
+                           M98090_DRCEXP_SHIFT,
+                           max98090_drcexp_text);
 
-static const struct soc_enum max98090_dac_perfmode_enum =
-       SOC_ENUM_SINGLE(M98090_REG_DAC_CONTROL, M98090_PERFMODE_SHIFT,
-               ARRAY_SIZE(max98090_perf_pwr_text), max98090_perf_pwr_text);
+static SOC_ENUM_SINGLE_DECL(max98090_dac_perfmode_enum,
+                           M98090_REG_DAC_CONTROL,
+                           M98090_PERFMODE_SHIFT,
+                           max98090_perf_pwr_text);
 
-static const struct soc_enum max98090_dachp_enum =
-       SOC_ENUM_SINGLE(M98090_REG_DAC_CONTROL, M98090_DACHP_SHIFT,
-               ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text);
+static SOC_ENUM_SINGLE_DECL(max98090_dachp_enum,
+                           M98090_REG_DAC_CONTROL,
+                           M98090_DACHP_SHIFT,
+                           max98090_pwr_perf_text);
 
-static const struct soc_enum max98090_adchp_enum =
-       SOC_ENUM_SINGLE(M98090_REG_ADC_CONTROL, M98090_ADCHP_SHIFT,
-               ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text);
+static SOC_ENUM_SINGLE_DECL(max98090_adchp_enum,
+                           M98090_REG_ADC_CONTROL,
+                           M98090_ADCHP_SHIFT,
+                           max98090_pwr_perf_text);
 
 static const struct snd_kcontrol_new max98090_snd_controls[] = {
        SOC_ENUM("MIC Bias VCM Bandgap", max98090_vcmbandgap_enum),
@@ -841,39 +852,42 @@ static int max98090_micinput_event(struct snd_soc_dapm_widget *w,
 
 static const char *mic1_mux_text[] = { "IN12", "IN56" };
 
-static const struct soc_enum mic1_mux_enum =
-       SOC_ENUM_SINGLE(M98090_REG_INPUT_MODE, M98090_EXTMIC1_SHIFT,
-               ARRAY_SIZE(mic1_mux_text), mic1_mux_text);
+static SOC_ENUM_SINGLE_DECL(mic1_mux_enum,
+                           M98090_REG_INPUT_MODE,
+                           M98090_EXTMIC1_SHIFT,
+                           mic1_mux_text);
 
 static const struct snd_kcontrol_new max98090_mic1_mux =
        SOC_DAPM_ENUM("MIC1 Mux", mic1_mux_enum);
 
 static const char *mic2_mux_text[] = { "IN34", "IN56" };
 
-static const struct soc_enum mic2_mux_enum =
-       SOC_ENUM_SINGLE(M98090_REG_INPUT_MODE, M98090_EXTMIC2_SHIFT,
-               ARRAY_SIZE(mic2_mux_text), mic2_mux_text);
+static SOC_ENUM_SINGLE_DECL(mic2_mux_enum,
+                           M98090_REG_INPUT_MODE,
+                           M98090_EXTMIC2_SHIFT,
+                           mic2_mux_text);
 
 static const struct snd_kcontrol_new max98090_mic2_mux =
        SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum);
 
 static const char *dmic_mux_text[] = { "ADC", "DMIC" };
 
-static const struct soc_enum dmic_mux_enum =
-       SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dmic_mux_text), dmic_mux_text);
+static SOC_ENUM_SINGLE_VIRT_DECL(dmic_mux_enum, dmic_mux_text);
 
 static const struct snd_kcontrol_new max98090_dmic_mux =
        SOC_DAPM_ENUM_VIRT("DMIC Mux", dmic_mux_enum);
 
 static const char *max98090_micpre_text[] = { "Off", "On" };
 
-static const struct soc_enum max98090_pa1en_enum =
-       SOC_ENUM_SINGLE(M98090_REG_MIC1_INPUT_LEVEL, M98090_MIC_PA1EN_SHIFT,
-               ARRAY_SIZE(max98090_micpre_text), max98090_micpre_text);
+static SOC_ENUM_SINGLE_DECL(max98090_pa1en_enum,
+                           M98090_REG_MIC1_INPUT_LEVEL,
+                           M98090_MIC_PA1EN_SHIFT,
+                           max98090_micpre_text);
 
-static const struct soc_enum max98090_pa2en_enum =
-       SOC_ENUM_SINGLE(M98090_REG_MIC2_INPUT_LEVEL, M98090_MIC_PA2EN_SHIFT,
-               ARRAY_SIZE(max98090_micpre_text), max98090_micpre_text);
+static SOC_ENUM_SINGLE_DECL(max98090_pa2en_enum,
+                           M98090_REG_MIC2_INPUT_LEVEL,
+                           M98090_MIC_PA2EN_SHIFT,
+                           max98090_micpre_text);
 
 /* LINEA mixer switch */
 static const struct snd_kcontrol_new max98090_linea_mixer_controls[] = {
@@ -937,13 +951,15 @@ static const struct snd_kcontrol_new max98090_right_adc_mixer_controls[] = {
 
 static const char *lten_mux_text[] = { "Normal", "Loopthrough" };
 
-static const struct soc_enum ltenl_mux_enum =
-       SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LTEN_SHIFT,
-               ARRAY_SIZE(lten_mux_text), lten_mux_text);
+static SOC_ENUM_SINGLE_DECL(ltenl_mux_enum,
+                           M98090_REG_IO_CONFIGURATION,
+                           M98090_LTEN_SHIFT,
+                           lten_mux_text);
 
-static const struct soc_enum ltenr_mux_enum =
-       SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LTEN_SHIFT,
-               ARRAY_SIZE(lten_mux_text), lten_mux_text);
+static SOC_ENUM_SINGLE_DECL(ltenr_mux_enum,
+                           M98090_REG_IO_CONFIGURATION,
+                           M98090_LTEN_SHIFT,
+                           lten_mux_text);
 
 static const struct snd_kcontrol_new max98090_ltenl_mux =
        SOC_DAPM_ENUM("LTENL Mux", ltenl_mux_enum);
@@ -953,13 +969,15 @@ static const struct snd_kcontrol_new max98090_ltenr_mux =
 
 static const char *lben_mux_text[] = { "Normal", "Loopback" };
 
-static const struct soc_enum lbenl_mux_enum =
-       SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LBEN_SHIFT,
-               ARRAY_SIZE(lben_mux_text), lben_mux_text);
+static SOC_ENUM_SINGLE_DECL(lbenl_mux_enum,
+                           M98090_REG_IO_CONFIGURATION,
+                           M98090_LBEN_SHIFT,
+                           lben_mux_text);
 
-static const struct soc_enum lbenr_mux_enum =
-       SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LBEN_SHIFT,
-               ARRAY_SIZE(lben_mux_text), lben_mux_text);
+static SOC_ENUM_SINGLE_DECL(lbenr_mux_enum,
+                           M98090_REG_IO_CONFIGURATION,
+                           M98090_LBEN_SHIFT,
+                           lben_mux_text);
 
 static const struct snd_kcontrol_new max98090_lbenl_mux =
        SOC_DAPM_ENUM("LBENL Mux", lbenl_mux_enum);
@@ -971,13 +989,15 @@ static const char *stenl_mux_text[] = { "Normal", "Sidetone Left" };
 
 static const char *stenr_mux_text[] = { "Normal", "Sidetone Right" };
 
-static const struct soc_enum stenl_mux_enum =
-       SOC_ENUM_SINGLE(M98090_REG_ADC_SIDETONE, M98090_DSTSL_SHIFT,
-               ARRAY_SIZE(stenl_mux_text), stenl_mux_text);
+static SOC_ENUM_SINGLE_DECL(stenl_mux_enum,
+                           M98090_REG_ADC_SIDETONE,
+                           M98090_DSTSL_SHIFT,
+                           stenl_mux_text);
 
-static const struct soc_enum stenr_mux_enum =
-       SOC_ENUM_SINGLE(M98090_REG_ADC_SIDETONE, M98090_DSTSR_SHIFT,
-               ARRAY_SIZE(stenr_mux_text), stenr_mux_text);
+static SOC_ENUM_SINGLE_DECL(stenr_mux_enum,
+                           M98090_REG_ADC_SIDETONE,
+                           M98090_DSTSR_SHIFT,
+                           stenr_mux_text);
 
 static const struct snd_kcontrol_new max98090_stenl_mux =
        SOC_DAPM_ENUM("STENL Mux", stenl_mux_enum);
@@ -1085,9 +1105,10 @@ static const struct snd_kcontrol_new max98090_right_rcv_mixer_controls[] = {
 
 static const char *linmod_mux_text[] = { "Left Only", "Left and Right" };
 
-static const struct soc_enum linmod_mux_enum =
-       SOC_ENUM_SINGLE(M98090_REG_LOUTR_MIXER, M98090_LINMOD_SHIFT,
-               ARRAY_SIZE(linmod_mux_text), linmod_mux_text);
+static SOC_ENUM_SINGLE_DECL(linmod_mux_enum,
+                           M98090_REG_LOUTR_MIXER,
+                           M98090_LINMOD_SHIFT,
+                           linmod_mux_text);
 
 static const struct snd_kcontrol_new max98090_linmod_mux =
        SOC_DAPM_ENUM("LINMOD Mux", linmod_mux_enum);
@@ -1097,16 +1118,18 @@ static const char *mixhpsel_mux_text[] = { "DAC Only", "HP Mixer" };
 /*
  * This is a mux as it selects the HP output, but to DAPM it is a Mixer enable
  */
-static const struct soc_enum mixhplsel_mux_enum =
-       SOC_ENUM_SINGLE(M98090_REG_HP_CONTROL, M98090_MIXHPLSEL_SHIFT,
-               ARRAY_SIZE(mixhpsel_mux_text), mixhpsel_mux_text);
+static SOC_ENUM_SINGLE_DECL(mixhplsel_mux_enum,
+                           M98090_REG_HP_CONTROL,
+                           M98090_MIXHPLSEL_SHIFT,
+                           mixhpsel_mux_text);
 
 static const struct snd_kcontrol_new max98090_mixhplsel_mux =
        SOC_DAPM_ENUM("MIXHPLSEL Mux", mixhplsel_mux_enum);
 
-static const struct soc_enum mixhprsel_mux_enum =
-       SOC_ENUM_SINGLE(M98090_REG_HP_CONTROL, M98090_MIXHPRSEL_SHIFT,
-               ARRAY_SIZE(mixhpsel_mux_text), mixhpsel_mux_text);
+static SOC_ENUM_SINGLE_DECL(mixhprsel_mux_enum,
+                           M98090_REG_HP_CONTROL,
+                           M98090_MIXHPRSEL_SHIFT,
+                           mixhpsel_mux_text);
 
 static const struct snd_kcontrol_new max98090_mixhprsel_mux =
        SOC_DAPM_ENUM("MIXHPRSEL Mux", mixhprsel_mux_enum);
@@ -1769,16 +1792,6 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
 
        switch (level) {
        case SND_SOC_BIAS_ON:
-               if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
-                       ret = regcache_sync(max98090->regmap);
-
-                       if (ret != 0) {
-                               dev_err(codec->dev,
-                                       "Failed to sync cache: %d\n", ret);
-                               return ret;
-                       }
-               }
-
                if (max98090->jack_state == M98090_JACK_STATE_HEADSET) {
                        /*
                         * Set to normal bias level.
@@ -1792,6 +1805,16 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
+               if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+                       ret = regcache_sync(max98090->regmap);
+                       if (ret != 0) {
+                               dev_err(codec->dev,
+                                       "Failed to sync cache: %d\n", ret);
+                               return ret;
+                       }
+               }
+               break;
+
        case SND_SOC_BIAS_OFF:
                /* Set internal pull-up to lowest power mode */
                snd_soc_update_bits(codec, M98090_REG_JACK_DETECT,
@@ -2195,14 +2218,6 @@ static int max98090_probe(struct snd_soc_codec *codec)
 
        max98090->codec = codec;
 
-       codec->control_data = max98090->regmap;
-
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        /* Reset the codec, the DSP core, and disable all interrupts */
        max98090_reset(max98090);
 
@@ -2328,7 +2343,6 @@ static int max98090_i2c_probe(struct i2c_client *i2c,
 
        max98090->devtype = id->driver_data;
        i2c_set_clientdata(i2c, max98090);
-       max98090->control_data = i2c;
        max98090->pdata = i2c->dev.platform_data;
        max98090->irq = i2c->irq;
 
@@ -2385,11 +2399,18 @@ static const struct i2c_device_id max98090_i2c_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, max98090_i2c_id);
 
+static const struct of_device_id max98090_of_match[] = {
+       { .compatible = "maxim,max98090", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, max98090_of_match);
+
 static struct i2c_driver max98090_i2c_driver = {
        .driver = {
                .name = "max98090",
                .owner = THIS_MODULE,
                .pm = &max98090_pm,
+               .of_match_table = of_match_ptr(max98090_of_match),
        },
        .probe  = max98090_i2c_probe,
        .remove = max98090_i2c_remove,