linux/sound/soc/codecs/max9867.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// MAX9867 ALSA SoC codec driver
   4//
   5// Copyright 2013-2015 Maxim Integrated Products
   6// Copyright 2018 Ladislav Michl <ladis@linux-mips.org>
   7//
   8
   9#include <linux/delay.h>
  10#include <linux/i2c.h>
  11#include <linux/module.h>
  12#include <linux/regmap.h>
  13#include <sound/pcm_params.h>
  14#include <sound/soc.h>
  15#include <sound/tlv.h>
  16#include "max9867.h"
  17
  18struct max9867_priv {
  19        struct regmap *regmap;
  20        const struct snd_pcm_hw_constraint_list *constraints;
  21        unsigned int sysclk, pclk;
  22        bool master, dsp_a;
  23        unsigned int adc_dac_active;
  24};
  25
  26static const char *const max9867_spmode[] = {
  27        "Stereo Diff", "Mono Diff",
  28        "Stereo Cap", "Mono Cap",
  29        "Stereo Single", "Mono Single",
  30        "Stereo Single Fast", "Mono Single Fast"
  31};
  32static const char *const max9867_filter_text[] = {"IIR", "FIR"};
  33
  34static const char *const max9867_adc_dac_filter_text[] = {
  35        "Disabled",
  36        "Elliptical/16/256",
  37        "Butterworth/16/500",
  38        "Elliptical/8/256",
  39        "Butterworth/8/500",
  40        "Butterworth/8-24"
  41};
  42
  43enum max9867_adc_dac {
  44        MAX9867_ADC_LEFT,
  45        MAX9867_ADC_RIGHT,
  46        MAX9867_DAC_LEFT,
  47        MAX9867_DAC_RIGHT,
  48};
  49
  50static int max9867_adc_dac_event(struct snd_soc_dapm_widget *w,
  51        struct snd_kcontrol *kcontrol, int event)
  52{
  53        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  54        struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
  55        enum max9867_adc_dac adc_dac;
  56
  57        if (!strcmp(w->name, "ADCL"))
  58                adc_dac = MAX9867_ADC_LEFT;
  59        else if (!strcmp(w->name, "ADCR"))
  60                adc_dac = MAX9867_ADC_RIGHT;
  61        else if (!strcmp(w->name, "DACL"))
  62                adc_dac = MAX9867_DAC_LEFT;
  63        else if (!strcmp(w->name, "DACR"))
  64                adc_dac = MAX9867_DAC_RIGHT;
  65        else
  66                return 0;
  67
  68        if (SND_SOC_DAPM_EVENT_ON(event))
  69                max9867->adc_dac_active |= BIT(adc_dac);
  70        else if (SND_SOC_DAPM_EVENT_OFF(event))
  71                max9867->adc_dac_active &= ~BIT(adc_dac);
  72
  73        return 0;
  74}
  75
  76static int max9867_filter_get(struct snd_kcontrol *kcontrol,
  77                              struct snd_ctl_elem_value *ucontrol)
  78{
  79        struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
  80        struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
  81        unsigned int reg;
  82        int ret;
  83
  84        ret = regmap_read(max9867->regmap, MAX9867_CODECFLTR, &reg);
  85        if (ret)
  86                return -EINVAL;
  87
  88        if (reg & MAX9867_CODECFLTR_MODE)
  89                ucontrol->value.enumerated.item[0] = 1;
  90        else
  91                ucontrol->value.enumerated.item[0] = 0;
  92
  93        return 0;
  94}
  95
  96static int max9867_filter_set(struct snd_kcontrol *kcontrol,
  97                              struct snd_ctl_elem_value *ucontrol)
  98{
  99        struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 100        struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 101        unsigned int reg, mode = ucontrol->value.enumerated.item[0];
 102        int ret;
 103
 104        if (mode > 1)
 105                return -EINVAL;
 106
 107        /* don't allow change if ADC/DAC active */
 108        if (max9867->adc_dac_active)
 109                return -EBUSY;
 110
 111        /* read current filter mode */
 112        ret = regmap_read(max9867->regmap, MAX9867_CODECFLTR, &reg);
 113        if (ret)
 114                return -EINVAL;
 115
 116        if (mode)
 117                mode = MAX9867_CODECFLTR_MODE;
 118
 119        /* check if change is needed */
 120        if ((reg & MAX9867_CODECFLTR_MODE) == mode)
 121                return 0;
 122
 123        /* shutdown codec before switching filter mode */
 124        regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
 125                MAX9867_PWRMAN_SHDN, 0);
 126
 127        /* switch filter mode */
 128        regmap_update_bits(max9867->regmap, MAX9867_CODECFLTR,
 129                MAX9867_CODECFLTR_MODE, mode);
 130
 131        /* out of shutdown now */
 132        regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
 133                MAX9867_PWRMAN_SHDN, MAX9867_PWRMAN_SHDN);
 134
 135        return 0;
 136}
 137
 138static SOC_ENUM_SINGLE_EXT_DECL(max9867_filter, max9867_filter_text);
 139static SOC_ENUM_SINGLE_DECL(max9867_dac_filter, MAX9867_CODECFLTR, 0,
 140        max9867_adc_dac_filter_text);
 141static SOC_ENUM_SINGLE_DECL(max9867_adc_filter, MAX9867_CODECFLTR, 4,
 142        max9867_adc_dac_filter_text);
 143static SOC_ENUM_SINGLE_DECL(max9867_spkmode, MAX9867_MODECONFIG, 0,
 144        max9867_spmode);
 145static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max9867_master_tlv,
 146         0,  2, TLV_DB_SCALE_ITEM(-8600, 200, 1),
 147         3, 17, TLV_DB_SCALE_ITEM(-7800, 400, 0),
 148        18, 25, TLV_DB_SCALE_ITEM(-2000, 200, 0),
 149        26, 34, TLV_DB_SCALE_ITEM( -500, 100, 0),
 150        35, 40, TLV_DB_SCALE_ITEM(  350,  50, 0),
 151);
 152static DECLARE_TLV_DB_SCALE(max9867_mic_tlv, 0, 100, 0);
 153static DECLARE_TLV_DB_SCALE(max9867_line_tlv, -600, 200, 0);
 154static DECLARE_TLV_DB_SCALE(max9867_adc_tlv, -1200, 100, 0);
 155static DECLARE_TLV_DB_SCALE(max9867_dac_tlv, -1500, 100, 0);
 156static DECLARE_TLV_DB_SCALE(max9867_dacboost_tlv, 0, 600, 0);
 157static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max9867_micboost_tlv,
 158        0, 2, TLV_DB_SCALE_ITEM(-2000, 2000, 1),
 159        3, 3, TLV_DB_SCALE_ITEM(3000, 0, 0),
 160);
 161
 162static const struct snd_kcontrol_new max9867_snd_controls[] = {
 163        SOC_DOUBLE_R_TLV("Master Playback Volume", MAX9867_LEFTVOL,
 164                        MAX9867_RIGHTVOL, 0, 40, 1, max9867_master_tlv),
 165        SOC_DOUBLE_R_TLV("Line Capture Volume", MAX9867_LEFTLINELVL,
 166                        MAX9867_RIGHTLINELVL, 0, 15, 1, max9867_line_tlv),
 167        SOC_DOUBLE_R_TLV("Mic Capture Volume", MAX9867_LEFTMICGAIN,
 168                        MAX9867_RIGHTMICGAIN, 0, 20, 1, max9867_mic_tlv),
 169        SOC_DOUBLE_R_TLV("Mic Boost Capture Volume", MAX9867_LEFTMICGAIN,
 170                        MAX9867_RIGHTMICGAIN, 5, 3, 0, max9867_micboost_tlv),
 171        SOC_SINGLE("Digital Sidetone Volume", MAX9867_SIDETONE, 0, 31, 1),
 172        SOC_SINGLE_TLV("Digital Playback Volume", MAX9867_DACLEVEL, 0, 15, 1,
 173                        max9867_dac_tlv),
 174        SOC_SINGLE_TLV("Digital Boost Playback Volume", MAX9867_DACLEVEL, 4, 3, 0,
 175                        max9867_dacboost_tlv),
 176        SOC_DOUBLE_TLV("Digital Capture Volume", MAX9867_ADCLEVEL, 4, 0, 15, 1,
 177                        max9867_adc_tlv),
 178        SOC_ENUM("Speaker Mode", max9867_spkmode),
 179        SOC_SINGLE("Volume Smoothing Switch", MAX9867_MODECONFIG, 6, 1, 0),
 180        SOC_SINGLE("Line ZC Switch", MAX9867_MODECONFIG, 5, 1, 0),
 181        SOC_ENUM_EXT("DSP Filter", max9867_filter, max9867_filter_get, max9867_filter_set),
 182        SOC_ENUM("ADC Filter", max9867_adc_filter),
 183        SOC_ENUM("DAC Filter", max9867_dac_filter),
 184        SOC_SINGLE("Mono Playback Switch", MAX9867_IFC1B, 3, 1, 0),
 185};
 186
 187/* Input mixer */
 188static const struct snd_kcontrol_new max9867_input_mixer_controls[] = {
 189        SOC_DAPM_DOUBLE("Line Capture Switch", MAX9867_INPUTCONFIG, 7, 5, 1, 0),
 190        SOC_DAPM_DOUBLE("Mic Capture Switch", MAX9867_INPUTCONFIG, 6, 4, 1, 0),
 191};
 192
 193/* Output mixer */
 194static const struct snd_kcontrol_new max9867_output_mixer_controls[] = {
 195        SOC_DAPM_DOUBLE_R("Line Bypass Switch",
 196                          MAX9867_LEFTLINELVL, MAX9867_RIGHTLINELVL, 6, 1, 1),
 197};
 198
 199/* Sidetone mixer */
 200static const struct snd_kcontrol_new max9867_sidetone_mixer_controls[] = {
 201        SOC_DAPM_DOUBLE("Sidetone Switch", MAX9867_SIDETONE, 6, 7, 1, 0),
 202};
 203
 204/* Line out switch */
 205static const struct snd_kcontrol_new max9867_line_out_control =
 206        SOC_DAPM_DOUBLE_R("Switch",
 207                          MAX9867_LEFTVOL, MAX9867_RIGHTVOL, 6, 1, 1);
 208
 209/* DMIC mux */
 210static const char *const dmic_mux_text[] = {
 211        "ADC", "DMIC"
 212};
 213static SOC_ENUM_SINGLE_DECL(left_dmic_mux_enum,
 214                            MAX9867_MICCONFIG, 5, dmic_mux_text);
 215static SOC_ENUM_SINGLE_DECL(right_dmic_mux_enum,
 216                            MAX9867_MICCONFIG, 4, dmic_mux_text);
 217static const struct snd_kcontrol_new max9867_left_dmic_mux =
 218        SOC_DAPM_ENUM("DMICL Mux", left_dmic_mux_enum);
 219static const struct snd_kcontrol_new max9867_right_dmic_mux =
 220        SOC_DAPM_ENUM("DMICR Mux", right_dmic_mux_enum);
 221
 222static const struct snd_soc_dapm_widget max9867_dapm_widgets[] = {
 223        SND_SOC_DAPM_INPUT("MICL"),
 224        SND_SOC_DAPM_INPUT("MICR"),
 225        SND_SOC_DAPM_INPUT("DMICL"),
 226        SND_SOC_DAPM_INPUT("DMICR"),
 227        SND_SOC_DAPM_INPUT("LINL"),
 228        SND_SOC_DAPM_INPUT("LINR"),
 229
 230        SND_SOC_DAPM_PGA("Left Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
 231        SND_SOC_DAPM_PGA("Right Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
 232        SND_SOC_DAPM_MIXER_NAMED_CTL("Input Mixer", SND_SOC_NOPM, 0, 0,
 233                                     max9867_input_mixer_controls,
 234                                     ARRAY_SIZE(max9867_input_mixer_controls)),
 235        SND_SOC_DAPM_MUX("DMICL Mux", SND_SOC_NOPM, 0, 0,
 236                         &max9867_left_dmic_mux),
 237        SND_SOC_DAPM_MUX("DMICR Mux", SND_SOC_NOPM, 0, 0,
 238                         &max9867_right_dmic_mux),
 239        SND_SOC_DAPM_ADC_E("ADCL", "HiFi Capture", SND_SOC_NOPM, 0, 0,
 240                           max9867_adc_dac_event,
 241                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 242        SND_SOC_DAPM_ADC_E("ADCR", "HiFi Capture", SND_SOC_NOPM, 0, 0,
 243                           max9867_adc_dac_event,
 244                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 245
 246        SND_SOC_DAPM_MIXER("Digital", SND_SOC_NOPM, 0, 0,
 247                           max9867_sidetone_mixer_controls,
 248                           ARRAY_SIZE(max9867_sidetone_mixer_controls)),
 249        SND_SOC_DAPM_MIXER_NAMED_CTL("Output Mixer", SND_SOC_NOPM, 0, 0,
 250                                     max9867_output_mixer_controls,
 251                                     ARRAY_SIZE(max9867_output_mixer_controls)),
 252        SND_SOC_DAPM_DAC_E("DACL", "HiFi Playback", SND_SOC_NOPM, 0, 0,
 253                           max9867_adc_dac_event,
 254                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 255        SND_SOC_DAPM_DAC_E("DACR", "HiFi Playback", SND_SOC_NOPM, 0, 0,
 256                           max9867_adc_dac_event,
 257                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 258        SND_SOC_DAPM_SWITCH("Master Playback", SND_SOC_NOPM, 0, 0,
 259                            &max9867_line_out_control),
 260        SND_SOC_DAPM_OUTPUT("LOUT"),
 261        SND_SOC_DAPM_OUTPUT("ROUT"),
 262};
 263
 264static const struct snd_soc_dapm_route max9867_audio_map[] = {
 265        {"Left Line Input", NULL, "LINL"},
 266        {"Right Line Input", NULL, "LINR"},
 267        {"Input Mixer", "Mic Capture Switch", "MICL"},
 268        {"Input Mixer", "Mic Capture Switch", "MICR"},
 269        {"Input Mixer", "Line Capture Switch", "Left Line Input"},
 270        {"Input Mixer", "Line Capture Switch", "Right Line Input"},
 271        {"DMICL Mux", "DMIC", "DMICL"},
 272        {"DMICR Mux", "DMIC", "DMICR"},
 273        {"DMICL Mux", "ADC", "Input Mixer"},
 274        {"DMICR Mux", "ADC", "Input Mixer"},
 275        {"ADCL", NULL, "DMICL Mux"},
 276        {"ADCR", NULL, "DMICR Mux"},
 277
 278        {"Digital", "Sidetone Switch", "ADCL"},
 279        {"Digital", "Sidetone Switch", "ADCR"},
 280        {"DACL", NULL, "Digital"},
 281        {"DACR", NULL, "Digital"},
 282
 283        {"Output Mixer", "Line Bypass Switch", "Left Line Input"},
 284        {"Output Mixer", "Line Bypass Switch", "Right Line Input"},
 285        {"Output Mixer", NULL, "DACL"},
 286        {"Output Mixer", NULL, "DACR"},
 287        {"Master Playback", "Switch", "Output Mixer"},
 288        {"LOUT", NULL, "Master Playback"},
 289        {"ROUT", NULL, "Master Playback"},
 290};
 291
 292static const unsigned int max9867_rates_44k1[] = {
 293        11025, 22050, 44100,
 294};
 295
 296static const struct snd_pcm_hw_constraint_list max9867_constraints_44k1 = {
 297        .list = max9867_rates_44k1,
 298        .count = ARRAY_SIZE(max9867_rates_44k1),
 299};
 300
 301static const unsigned int max9867_rates_48k[] = {
 302        8000, 16000, 32000, 48000,
 303};
 304
 305static const struct snd_pcm_hw_constraint_list max9867_constraints_48k = {
 306        .list = max9867_rates_48k,
 307        .count = ARRAY_SIZE(max9867_rates_48k),
 308};
 309
 310static int max9867_startup(struct snd_pcm_substream *substream,
 311                           struct snd_soc_dai *dai)
 312{
 313        struct max9867_priv *max9867 =
 314                snd_soc_component_get_drvdata(dai->component);
 315
 316        if (max9867->constraints)
 317                snd_pcm_hw_constraint_list(substream->runtime, 0,
 318                        SNDRV_PCM_HW_PARAM_RATE, max9867->constraints);
 319
 320        return 0;
 321}
 322
 323static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
 324                struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 325{
 326        int value;
 327        unsigned long int rate, ratio;
 328        struct snd_soc_component *component = dai->component;
 329        struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 330        unsigned int ni = DIV_ROUND_CLOSEST_ULL(96ULL * 0x10000 * params_rate(params),
 331                                                max9867->pclk);
 332
 333        /* set up the ni value */
 334        regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKHIGH,
 335                MAX9867_NI_HIGH_MASK, (0xFF00 & ni) >> 8);
 336        regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKLOW,
 337                MAX9867_NI_LOW_MASK, 0x00FF & ni);
 338        if (max9867->master) {
 339                if (max9867->dsp_a) {
 340                        value = MAX9867_IFC1B_48X;
 341                } else {
 342                        rate = params_rate(params) * 2 * params_width(params);
 343                        ratio = max9867->pclk / rate;
 344                        switch (params_width(params)) {
 345                        case 8:
 346                        case 16:
 347                                switch (ratio) {
 348                                case 2:
 349                                        value = MAX9867_IFC1B_PCLK_2;
 350                                        break;
 351                                case 4:
 352                                        value = MAX9867_IFC1B_PCLK_4;
 353                                        break;
 354                                case 8:
 355                                        value = MAX9867_IFC1B_PCLK_8;
 356                                        break;
 357                                case 16:
 358                                        value = MAX9867_IFC1B_PCLK_16;
 359                                        break;
 360                                default:
 361                                        return -EINVAL;
 362                                }
 363                                break;
 364                        case 24:
 365                                value = MAX9867_IFC1B_48X;
 366                                break;
 367                        case 32:
 368                                value = MAX9867_IFC1B_64X;
 369                                break;
 370                        default:
 371                                return -EINVAL;
 372                        }
 373                }
 374                regmap_update_bits(max9867->regmap, MAX9867_IFC1B,
 375                        MAX9867_IFC1B_BCLK_MASK, value);
 376        } else {
 377                /*
 378                 * digital pll locks on to any externally supplied LRCLK signal
 379                 * and also enable rapid lock mode.
 380                 */
 381                regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKLOW,
 382                        MAX9867_RAPID_LOCK, MAX9867_RAPID_LOCK);
 383                regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKHIGH,
 384                        MAX9867_PLL, MAX9867_PLL);
 385        }
 386        return 0;
 387}
 388
 389static int max9867_mute(struct snd_soc_dai *dai, int mute, int direction)
 390{
 391        struct snd_soc_component *component = dai->component;
 392        struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 393
 394        return regmap_update_bits(max9867->regmap, MAX9867_DACLEVEL,
 395                                  1 << 6, !!mute << 6);
 396}
 397
 398static int max9867_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 399                int clk_id, unsigned int freq, int dir)
 400{
 401        struct snd_soc_component *component = codec_dai->component;
 402        struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 403        int value = 0;
 404
 405        /* Set the prescaler based on the master clock frequency*/
 406        if (freq >= 10000000 && freq <= 20000000) {
 407                value |= MAX9867_PSCLK_10_20;
 408                max9867->pclk = freq;
 409        } else if (freq >= 20000000 && freq <= 40000000) {
 410                value |= MAX9867_PSCLK_20_40;
 411                max9867->pclk = freq / 2;
 412        } else if (freq >= 40000000 && freq <= 60000000) {
 413                value |= MAX9867_PSCLK_40_60;
 414                max9867->pclk = freq / 4;
 415        } else {
 416                dev_err(component->dev,
 417                        "Invalid clock frequency %uHz (required 10-60MHz)\n",
 418                        freq);
 419                return -EINVAL;
 420        }
 421        if (freq % 48000 == 0)
 422                max9867->constraints = &max9867_constraints_48k;
 423        else if (freq % 44100 == 0)
 424                max9867->constraints = &max9867_constraints_44k1;
 425        else
 426                dev_warn(component->dev,
 427                         "Unable to set exact rate with %uHz clock frequency\n",
 428                         freq);
 429        max9867->sysclk = freq;
 430        value = value << MAX9867_PSCLK_SHIFT;
 431        /* exact integer mode is not supported */
 432        value &= ~MAX9867_FREQ_MASK;
 433        regmap_update_bits(max9867->regmap, MAX9867_SYSCLK,
 434                        MAX9867_PSCLK_MASK, value);
 435        return 0;
 436}
 437
 438static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
 439                unsigned int fmt)
 440{
 441        struct snd_soc_component *component = codec_dai->component;
 442        struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 443        u8 iface1A, iface1B;
 444
 445        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 446        case SND_SOC_DAIFMT_CBM_CFM:
 447                max9867->master = true;
 448                iface1A = MAX9867_MASTER;
 449                iface1B = MAX9867_IFC1B_48X;
 450                break;
 451        case SND_SOC_DAIFMT_CBS_CFS:
 452                max9867->master = false;
 453                iface1A = iface1B = 0;
 454                break;
 455        default:
 456                return -EINVAL;
 457        }
 458
 459        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 460        case SND_SOC_DAIFMT_I2S:
 461                max9867->dsp_a = false;
 462                iface1A |= MAX9867_I2S_DLY;
 463                break;
 464        case SND_SOC_DAIFMT_DSP_A:
 465                max9867->dsp_a = true;
 466                iface1A |= MAX9867_TDM_MODE | MAX9867_SDOUT_HIZ;
 467                break;
 468        default:
 469                return -EINVAL;
 470        }
 471
 472        /* Clock inversion bits, BCI and WCI */
 473        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 474        case SND_SOC_DAIFMT_NB_NF:
 475                break;
 476        case SND_SOC_DAIFMT_IB_IF:
 477                iface1A |= MAX9867_WCI_MODE | MAX9867_BCI_MODE;
 478                break;
 479        case SND_SOC_DAIFMT_IB_NF:
 480                iface1A |= MAX9867_BCI_MODE;
 481                break;
 482        case SND_SOC_DAIFMT_NB_IF:
 483                iface1A |= MAX9867_WCI_MODE;
 484                break;
 485        default:
 486                return -EINVAL;
 487        }
 488
 489        regmap_write(max9867->regmap, MAX9867_IFC1A, iface1A);
 490        regmap_update_bits(max9867->regmap, MAX9867_IFC1B,
 491                           MAX9867_IFC1B_BCLK_MASK, iface1B);
 492
 493        return 0;
 494}
 495
 496static const struct snd_soc_dai_ops max9867_dai_ops = {
 497        .set_sysclk     = max9867_set_dai_sysclk,
 498        .set_fmt        = max9867_dai_set_fmt,
 499        .mute_stream    = max9867_mute,
 500        .startup        = max9867_startup,
 501        .hw_params      = max9867_dai_hw_params,
 502        .no_capture_mute = 1,
 503};
 504
 505static struct snd_soc_dai_driver max9867_dai[] = {
 506        {
 507        .name = "max9867-aif1",
 508        .playback = {
 509                .stream_name = "HiFi Playback",
 510                .channels_min = 2,
 511                .channels_max = 2,
 512                .rates = SNDRV_PCM_RATE_8000_48000,
 513                .formats = SNDRV_PCM_FMTBIT_S16_LE,
 514        },
 515        .capture = {
 516                .stream_name = "HiFi Capture",
 517                .channels_min = 2,
 518                .channels_max = 2,
 519                .rates = SNDRV_PCM_RATE_8000_48000,
 520                .formats = SNDRV_PCM_FMTBIT_S16_LE,
 521        },
 522        .ops = &max9867_dai_ops,
 523        .symmetric_rate = 1,
 524        }
 525};
 526
 527#ifdef CONFIG_PM
 528static int max9867_suspend(struct snd_soc_component *component)
 529{
 530        snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 531
 532        return 0;
 533}
 534
 535static int max9867_resume(struct snd_soc_component *component)
 536{
 537        snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 538
 539        return 0;
 540}
 541#else
 542#define max9867_suspend NULL
 543#define max9867_resume  NULL
 544#endif
 545
 546static int max9867_set_bias_level(struct snd_soc_component *component,
 547                                  enum snd_soc_bias_level level)
 548{
 549        int err;
 550        struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 551
 552        switch (level) {
 553        case SND_SOC_BIAS_STANDBY:
 554                if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 555                        err = regcache_sync(max9867->regmap);
 556                        if (err)
 557                                return err;
 558
 559                        err = regmap_write(max9867->regmap,
 560                                           MAX9867_PWRMAN, 0xff);
 561                        if (err)
 562                                return err;
 563                }
 564                break;
 565        case SND_SOC_BIAS_OFF:
 566                err = regmap_write(max9867->regmap, MAX9867_PWRMAN, 0);
 567                if (err)
 568                        return err;
 569
 570                regcache_mark_dirty(max9867->regmap);
 571                break;
 572        default:
 573                break;
 574        }
 575
 576        return 0;
 577}
 578
 579static const struct snd_soc_component_driver max9867_component = {
 580        .controls               = max9867_snd_controls,
 581        .num_controls           = ARRAY_SIZE(max9867_snd_controls),
 582        .dapm_routes            = max9867_audio_map,
 583        .num_dapm_routes        = ARRAY_SIZE(max9867_audio_map),
 584        .dapm_widgets           = max9867_dapm_widgets,
 585        .num_dapm_widgets       = ARRAY_SIZE(max9867_dapm_widgets),
 586        .suspend                = max9867_suspend,
 587        .resume                 = max9867_resume,
 588        .set_bias_level         = max9867_set_bias_level,
 589        .idle_bias_on           = 1,
 590        .use_pmdown_time        = 1,
 591        .endianness             = 1,
 592        .non_legacy_dai_naming  = 1,
 593};
 594
 595static bool max9867_volatile_register(struct device *dev, unsigned int reg)
 596{
 597        switch (reg) {
 598        case MAX9867_STATUS:
 599        case MAX9867_JACKSTATUS:
 600        case MAX9867_AUXHIGH:
 601        case MAX9867_AUXLOW:
 602                return true;
 603        default:
 604                return false;
 605        }
 606}
 607
 608static const struct regmap_config max9867_regmap = {
 609        .reg_bits       = 8,
 610        .val_bits       = 8,
 611        .max_register   = MAX9867_REVISION,
 612        .volatile_reg   = max9867_volatile_register,
 613        .cache_type     = REGCACHE_RBTREE,
 614};
 615
 616static int max9867_i2c_probe(struct i2c_client *i2c,
 617                const struct i2c_device_id *id)
 618{
 619        struct max9867_priv *max9867;
 620        int ret, reg;
 621
 622        max9867 = devm_kzalloc(&i2c->dev, sizeof(*max9867), GFP_KERNEL);
 623        if (!max9867)
 624                return -ENOMEM;
 625
 626        i2c_set_clientdata(i2c, max9867);
 627        max9867->regmap = devm_regmap_init_i2c(i2c, &max9867_regmap);
 628        if (IS_ERR(max9867->regmap)) {
 629                ret = PTR_ERR(max9867->regmap);
 630                dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
 631                return ret;
 632        }
 633        ret = regmap_read(max9867->regmap, MAX9867_REVISION, &reg);
 634        if (ret < 0) {
 635                dev_err(&i2c->dev, "Failed to read: %d\n", ret);
 636                return ret;
 637        }
 638        dev_info(&i2c->dev, "device revision: %x\n", reg);
 639        ret = devm_snd_soc_register_component(&i2c->dev, &max9867_component,
 640                        max9867_dai, ARRAY_SIZE(max9867_dai));
 641        if (ret < 0)
 642                dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
 643        return ret;
 644}
 645
 646static const struct i2c_device_id max9867_i2c_id[] = {
 647        { "max9867", 0 },
 648        { }
 649};
 650MODULE_DEVICE_TABLE(i2c, max9867_i2c_id);
 651
 652#ifdef CONFIG_OF
 653static const struct of_device_id max9867_of_match[] = {
 654        { .compatible = "maxim,max9867", },
 655        { }
 656};
 657MODULE_DEVICE_TABLE(of, max9867_of_match);
 658#endif
 659
 660static struct i2c_driver max9867_i2c_driver = {
 661        .driver = {
 662                .name = "max9867",
 663                .of_match_table = of_match_ptr(max9867_of_match),
 664        },
 665        .probe  = max9867_i2c_probe,
 666        .id_table = max9867_i2c_id,
 667};
 668
 669module_i2c_driver(max9867_i2c_driver);
 670
 671MODULE_AUTHOR("Ladislav Michl <ladis@linux-mips.org>");
 672MODULE_DESCRIPTION("ASoC MAX9867 driver");
 673MODULE_LICENSE("GPL");
 674