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
  18static const char *const max9867_spmode[] = {
  19        "Stereo Diff", "Mono Diff",
  20        "Stereo Cap", "Mono Cap",
  21        "Stereo Single", "Mono Single",
  22        "Stereo Single Fast", "Mono Single Fast"
  23};
  24static const char *const max9867_filter_text[] = {"IIR", "FIR"};
  25
  26static SOC_ENUM_SINGLE_DECL(max9867_filter, MAX9867_CODECFLTR, 7,
  27        max9867_filter_text);
  28static SOC_ENUM_SINGLE_DECL(max9867_spkmode, MAX9867_MODECONFIG, 0,
  29        max9867_spmode);
  30static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max9867_master_tlv,
  31         0,  2, TLV_DB_SCALE_ITEM(-8600, 200, 1),
  32         3, 17, TLV_DB_SCALE_ITEM(-7800, 400, 0),
  33        18, 25, TLV_DB_SCALE_ITEM(-2000, 200, 0),
  34        26, 34, TLV_DB_SCALE_ITEM( -500, 100, 0),
  35        35, 40, TLV_DB_SCALE_ITEM(  350,  50, 0),
  36);
  37static DECLARE_TLV_DB_SCALE(max9867_mic_tlv, 0, 100, 0);
  38static DECLARE_TLV_DB_SCALE(max9867_line_tlv, -600, 200, 0);
  39static DECLARE_TLV_DB_SCALE(max9867_adc_tlv, -1200, 100, 0);
  40static DECLARE_TLV_DB_SCALE(max9867_dac_tlv, -1500, 100, 0);
  41static DECLARE_TLV_DB_SCALE(max9867_dacboost_tlv, 0, 600, 0);
  42static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max9867_micboost_tlv,
  43        0, 2, TLV_DB_SCALE_ITEM(-2000, 2000, 1),
  44        3, 3, TLV_DB_SCALE_ITEM(3000, 0, 0),
  45);
  46
  47static const struct snd_kcontrol_new max9867_snd_controls[] = {
  48        SOC_DOUBLE_R_TLV("Master Playback Volume", MAX9867_LEFTVOL,
  49                        MAX9867_RIGHTVOL, 0, 41, 1, max9867_master_tlv),
  50        SOC_DOUBLE_R_TLV("Line Capture Volume", MAX9867_LEFTLINELVL,
  51                        MAX9867_RIGHTLINELVL, 0, 15, 1, max9867_line_tlv),
  52        SOC_DOUBLE_R_TLV("Mic Capture Volume", MAX9867_LEFTMICGAIN,
  53                        MAX9867_RIGHTMICGAIN, 0, 20, 1, max9867_mic_tlv),
  54        SOC_DOUBLE_R_TLV("Mic Boost Capture Volume", MAX9867_LEFTMICGAIN,
  55                        MAX9867_RIGHTMICGAIN, 5, 4, 0, max9867_micboost_tlv),
  56        SOC_SINGLE("Digital Sidetone Volume", MAX9867_SIDETONE, 0, 31, 1),
  57        SOC_SINGLE_TLV("Digital Playback Volume", MAX9867_DACLEVEL, 0, 15, 1,
  58                        max9867_dac_tlv),
  59        SOC_SINGLE_TLV("Digital Boost Playback Volume", MAX9867_DACLEVEL, 4, 3, 0,
  60                        max9867_dacboost_tlv),
  61        SOC_DOUBLE_TLV("Digital Capture Volume", MAX9867_ADCLEVEL, 0, 4, 15, 1,
  62                        max9867_adc_tlv),
  63        SOC_ENUM("Speaker Mode", max9867_spkmode),
  64        SOC_SINGLE("Volume Smoothing Switch", MAX9867_MODECONFIG, 6, 1, 0),
  65        SOC_SINGLE("Line ZC Switch", MAX9867_MODECONFIG, 5, 1, 0),
  66        SOC_ENUM("DSP Filter", max9867_filter),
  67};
  68
  69/* Input mixer */
  70static const struct snd_kcontrol_new max9867_input_mixer_controls[] = {
  71        SOC_DAPM_DOUBLE("Line Capture Switch", MAX9867_INPUTCONFIG, 7, 5, 1, 0),
  72        SOC_DAPM_DOUBLE("Mic Capture Switch", MAX9867_INPUTCONFIG, 6, 4, 1, 0),
  73};
  74
  75/* Output mixer */
  76static const struct snd_kcontrol_new max9867_output_mixer_controls[] = {
  77        SOC_DAPM_DOUBLE_R("Line Bypass Switch",
  78                          MAX9867_LEFTLINELVL, MAX9867_RIGHTLINELVL, 6, 1, 1),
  79};
  80
  81/* Sidetone mixer */
  82static const struct snd_kcontrol_new max9867_sidetone_mixer_controls[] = {
  83        SOC_DAPM_DOUBLE("Sidetone Switch", MAX9867_SIDETONE, 6, 7, 1, 0),
  84};
  85
  86/* Line out switch */
  87static const struct snd_kcontrol_new max9867_line_out_control =
  88        SOC_DAPM_DOUBLE_R("Switch",
  89                          MAX9867_LEFTVOL, MAX9867_RIGHTVOL, 6, 1, 1);
  90
  91
  92static const struct snd_soc_dapm_widget max9867_dapm_widgets[] = {
  93        SND_SOC_DAPM_INPUT("MICL"),
  94        SND_SOC_DAPM_INPUT("MICR"),
  95        SND_SOC_DAPM_INPUT("LINL"),
  96        SND_SOC_DAPM_INPUT("LINR"),
  97
  98        SND_SOC_DAPM_PGA("Left Line Input", MAX9867_PWRMAN, 6, 0, NULL, 0),
  99        SND_SOC_DAPM_PGA("Right Line Input", MAX9867_PWRMAN, 5, 0, NULL, 0),
 100        SND_SOC_DAPM_MIXER_NAMED_CTL("Input Mixer", SND_SOC_NOPM, 0, 0,
 101                                     max9867_input_mixer_controls,
 102                                     ARRAY_SIZE(max9867_input_mixer_controls)),
 103        SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", MAX9867_PWRMAN, 1, 0),
 104        SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", MAX9867_PWRMAN, 0, 0),
 105
 106        SND_SOC_DAPM_MIXER("Digital", SND_SOC_NOPM, 0, 0,
 107                           max9867_sidetone_mixer_controls,
 108                           ARRAY_SIZE(max9867_sidetone_mixer_controls)),
 109        SND_SOC_DAPM_MIXER_NAMED_CTL("Output Mixer", SND_SOC_NOPM, 0, 0,
 110                                     max9867_output_mixer_controls,
 111                                     ARRAY_SIZE(max9867_output_mixer_controls)),
 112        SND_SOC_DAPM_DAC("DACL", "HiFi Playback", MAX9867_PWRMAN, 3, 0),
 113        SND_SOC_DAPM_DAC("DACR", "HiFi Playback", MAX9867_PWRMAN, 2, 0),
 114        SND_SOC_DAPM_SWITCH("Master Playback", SND_SOC_NOPM, 0, 0,
 115                            &max9867_line_out_control),
 116        SND_SOC_DAPM_OUTPUT("LOUT"),
 117        SND_SOC_DAPM_OUTPUT("ROUT"),
 118};
 119
 120static const struct snd_soc_dapm_route max9867_audio_map[] = {
 121        {"Left Line Input", NULL, "LINL"},
 122        {"Right Line Input", NULL, "LINR"},
 123        {"Input Mixer", "Mic Capture Switch", "MICL"},
 124        {"Input Mixer", "Mic Capture Switch", "MICR"},
 125        {"Input Mixer", "Line Capture Switch", "Left Line Input"},
 126        {"Input Mixer", "Line Capture Switch", "Right Line Input"},
 127        {"ADCL", NULL, "Input Mixer"},
 128        {"ADCR", NULL, "Input Mixer"},
 129
 130        {"Digital", "Sidetone Switch", "ADCL"},
 131        {"Digital", "Sidetone Switch", "ADCR"},
 132        {"DACL", NULL, "Digital"},
 133        {"DACR", NULL, "Digital"},
 134
 135        {"Output Mixer", "Line Bypass Switch", "Left Line Input"},
 136        {"Output Mixer", "Line Bypass Switch", "Right Line Input"},
 137        {"Output Mixer", NULL, "DACL"},
 138        {"Output Mixer", NULL, "DACR"},
 139        {"Master Playback", "Switch", "Output Mixer"},
 140        {"LOUT", NULL, "Master Playback"},
 141        {"ROUT", NULL, "Master Playback"},
 142};
 143
 144static const unsigned int max9867_rates_44k1[] = {
 145        11025, 22050, 44100,
 146};
 147
 148static const struct snd_pcm_hw_constraint_list max9867_constraints_44k1 = {
 149        .list = max9867_rates_44k1,
 150        .count = ARRAY_SIZE(max9867_rates_44k1),
 151};
 152
 153static const unsigned int max9867_rates_48k[] = {
 154        8000, 16000, 32000, 48000,
 155};
 156
 157static const struct snd_pcm_hw_constraint_list max9867_constraints_48k = {
 158        .list = max9867_rates_48k,
 159        .count = ARRAY_SIZE(max9867_rates_48k),
 160};
 161
 162struct max9867_priv {
 163        struct regmap *regmap;
 164        const struct snd_pcm_hw_constraint_list *constraints;
 165        unsigned int sysclk, pclk;
 166        bool master, dsp_a;
 167};
 168
 169static int max9867_startup(struct snd_pcm_substream *substream,
 170                           struct snd_soc_dai *dai)
 171{
 172        struct max9867_priv *max9867 =
 173                snd_soc_component_get_drvdata(dai->component);
 174
 175        if (max9867->constraints)
 176                snd_pcm_hw_constraint_list(substream->runtime, 0,
 177                        SNDRV_PCM_HW_PARAM_RATE, max9867->constraints);
 178
 179        return 0;
 180}
 181
 182static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
 183                struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 184{
 185        int value;
 186        unsigned long int rate, ratio;
 187        struct snd_soc_component *component = dai->component;
 188        struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 189        unsigned int ni = DIV_ROUND_CLOSEST_ULL(96ULL * 0x10000 * params_rate(params),
 190                                                max9867->pclk);
 191
 192        /* set up the ni value */
 193        regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKHIGH,
 194                MAX9867_NI_HIGH_MASK, (0xFF00 & ni) >> 8);
 195        regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKLOW,
 196                MAX9867_NI_LOW_MASK, 0x00FF & ni);
 197        if (max9867->master) {
 198                if (max9867->dsp_a) {
 199                        value = MAX9867_IFC1B_48X;
 200                } else {
 201                        rate = params_rate(params) * 2 * params_width(params);
 202                        ratio = max9867->pclk / rate;
 203                        switch (params_width(params)) {
 204                        case 8:
 205                        case 16:
 206                                switch (ratio) {
 207                                case 2:
 208                                        value = MAX9867_IFC1B_PCLK_2;
 209                                        break;
 210                                case 4:
 211                                        value = MAX9867_IFC1B_PCLK_4;
 212                                        break;
 213                                case 8:
 214                                        value = MAX9867_IFC1B_PCLK_8;
 215                                        break;
 216                                case 16:
 217                                        value = MAX9867_IFC1B_PCLK_16;
 218                                        break;
 219                                default:
 220                                        return -EINVAL;
 221                                }
 222                                break;
 223                        case 24:
 224                                value = MAX9867_IFC1B_48X;
 225                                break;
 226                        case 32:
 227                                value = MAX9867_IFC1B_64X;
 228                                break;
 229                        default:
 230                                return -EINVAL;
 231                        }
 232                }
 233                regmap_update_bits(max9867->regmap, MAX9867_IFC1B,
 234                        MAX9867_IFC1B_BCLK_MASK, value);
 235        } else {
 236                /*
 237                 * digital pll locks on to any externally supplied LRCLK signal
 238                 * and also enable rapid lock mode.
 239                 */
 240                regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKLOW,
 241                        MAX9867_RAPID_LOCK, MAX9867_RAPID_LOCK);
 242                regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKHIGH,
 243                        MAX9867_PLL, MAX9867_PLL);
 244        }
 245        return 0;
 246}
 247
 248static int max9867_mute(struct snd_soc_dai *dai, int mute)
 249{
 250        struct snd_soc_component *component = dai->component;
 251        struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 252
 253        return regmap_update_bits(max9867->regmap, MAX9867_DACLEVEL,
 254                                  1 << 6, !!mute << 6);
 255}
 256
 257static int max9867_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 258                int clk_id, unsigned int freq, int dir)
 259{
 260        struct snd_soc_component *component = codec_dai->component;
 261        struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 262        int value = 0;
 263
 264        /* Set the prescaler based on the master clock frequency*/
 265        if (freq >= 10000000 && freq <= 20000000) {
 266                value |= MAX9867_PSCLK_10_20;
 267                max9867->pclk = freq;
 268        } else if (freq >= 20000000 && freq <= 40000000) {
 269                value |= MAX9867_PSCLK_20_40;
 270                max9867->pclk = freq / 2;
 271        } else if (freq >= 40000000 && freq <= 60000000) {
 272                value |= MAX9867_PSCLK_40_60;
 273                max9867->pclk = freq / 4;
 274        } else {
 275                dev_err(component->dev,
 276                        "Invalid clock frequency %uHz (required 10-60MHz)\n",
 277                        freq);
 278                return -EINVAL;
 279        }
 280        if (freq % 48000 == 0)
 281                max9867->constraints = &max9867_constraints_48k;
 282        else if (freq % 44100 == 0)
 283                max9867->constraints = &max9867_constraints_44k1;
 284        else
 285                dev_warn(component->dev,
 286                         "Unable to set exact rate with %uHz clock frequency\n",
 287                         freq);
 288        max9867->sysclk = freq;
 289        value = value << MAX9867_PSCLK_SHIFT;
 290        /* exact integer mode is not supported */
 291        value &= ~MAX9867_FREQ_MASK;
 292        regmap_update_bits(max9867->regmap, MAX9867_SYSCLK,
 293                        MAX9867_PSCLK_MASK, value);
 294        return 0;
 295}
 296
 297static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
 298                unsigned int fmt)
 299{
 300        struct snd_soc_component *component = codec_dai->component;
 301        struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 302        u8 iface1A, iface1B;
 303
 304        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 305        case SND_SOC_DAIFMT_CBM_CFM:
 306                max9867->master = true;
 307                iface1A = MAX9867_MASTER;
 308                iface1B = MAX9867_IFC1B_48X;
 309                break;
 310        case SND_SOC_DAIFMT_CBS_CFS:
 311                max9867->master = false;
 312                iface1A = iface1B = 0;
 313                break;
 314        default:
 315                return -EINVAL;
 316        }
 317
 318        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 319        case SND_SOC_DAIFMT_I2S:
 320                max9867->dsp_a = false;
 321                iface1A |= MAX9867_I2S_DLY;
 322                break;
 323        case SND_SOC_DAIFMT_DSP_A:
 324                max9867->dsp_a = true;
 325                iface1A |= MAX9867_TDM_MODE | MAX9867_SDOUT_HIZ;
 326                break;
 327        default:
 328                return -EINVAL;
 329        }
 330
 331        /* Clock inversion bits, BCI and WCI */
 332        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 333        case SND_SOC_DAIFMT_NB_NF:
 334                break;
 335        case SND_SOC_DAIFMT_IB_IF:
 336                iface1A |= MAX9867_WCI_MODE | MAX9867_BCI_MODE;
 337                break;
 338        case SND_SOC_DAIFMT_IB_NF:
 339                iface1A |= MAX9867_BCI_MODE;
 340                break;
 341        case SND_SOC_DAIFMT_NB_IF:
 342                iface1A |= MAX9867_WCI_MODE;
 343                break;
 344        default:
 345                return -EINVAL;
 346        }
 347
 348        regmap_write(max9867->regmap, MAX9867_IFC1A, iface1A);
 349        regmap_write(max9867->regmap, MAX9867_IFC1B, iface1B);
 350
 351        return 0;
 352}
 353
 354static const struct snd_soc_dai_ops max9867_dai_ops = {
 355        .set_sysclk     = max9867_set_dai_sysclk,
 356        .set_fmt        = max9867_dai_set_fmt,
 357        .digital_mute   = max9867_mute,
 358        .startup        = max9867_startup,
 359        .hw_params      = max9867_dai_hw_params,
 360};
 361
 362static struct snd_soc_dai_driver max9867_dai[] = {
 363        {
 364        .name = "max9867-aif1",
 365        .playback = {
 366                .stream_name = "HiFi Playback",
 367                .channels_min = 2,
 368                .channels_max = 2,
 369                .rates = SNDRV_PCM_RATE_8000_48000,
 370                .formats = SNDRV_PCM_FMTBIT_S16_LE,
 371        },
 372        .capture = {
 373                .stream_name = "HiFi Capture",
 374                .channels_min = 2,
 375                .channels_max = 2,
 376                .rates = SNDRV_PCM_RATE_8000_48000,
 377                .formats = SNDRV_PCM_FMTBIT_S16_LE,
 378        },
 379        .ops = &max9867_dai_ops,
 380        .symmetric_rates = 1,
 381        }
 382};
 383
 384#ifdef CONFIG_PM
 385static int max9867_suspend(struct snd_soc_component *component)
 386{
 387        snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 388
 389        return 0;
 390}
 391
 392static int max9867_resume(struct snd_soc_component *component)
 393{
 394        snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 395
 396        return 0;
 397}
 398#else
 399#define max9867_suspend NULL
 400#define max9867_resume  NULL
 401#endif
 402
 403static int max9867_set_bias_level(struct snd_soc_component *component,
 404                                  enum snd_soc_bias_level level)
 405{
 406        int err;
 407        struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 408
 409        switch (level) {
 410        case SND_SOC_BIAS_STANDBY:
 411                if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
 412                        err = regcache_sync(max9867->regmap);
 413                        if (err)
 414                                return err;
 415
 416                        err = regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
 417                                                 MAX9867_SHTDOWN, MAX9867_SHTDOWN);
 418                        if (err)
 419                                return err;
 420                }
 421                break;
 422        case SND_SOC_BIAS_OFF:
 423                err = regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
 424                                         MAX9867_SHTDOWN, 0);
 425                if (err)
 426                        return err;
 427
 428                regcache_mark_dirty(max9867->regmap);
 429                break;
 430        default:
 431                break;
 432        }
 433
 434        return 0;
 435}
 436
 437static const struct snd_soc_component_driver max9867_component = {
 438        .controls               = max9867_snd_controls,
 439        .num_controls           = ARRAY_SIZE(max9867_snd_controls),
 440        .dapm_routes            = max9867_audio_map,
 441        .num_dapm_routes        = ARRAY_SIZE(max9867_audio_map),
 442        .dapm_widgets           = max9867_dapm_widgets,
 443        .num_dapm_widgets       = ARRAY_SIZE(max9867_dapm_widgets),
 444        .suspend                = max9867_suspend,
 445        .resume                 = max9867_resume,
 446        .set_bias_level         = max9867_set_bias_level,
 447        .idle_bias_on           = 1,
 448        .use_pmdown_time        = 1,
 449        .endianness             = 1,
 450        .non_legacy_dai_naming  = 1,
 451};
 452
 453static bool max9867_volatile_register(struct device *dev, unsigned int reg)
 454{
 455        switch (reg) {
 456        case MAX9867_STATUS:
 457        case MAX9867_JACKSTATUS:
 458        case MAX9867_AUXHIGH:
 459        case MAX9867_AUXLOW:
 460                return true;
 461        default:
 462                return false;
 463        }
 464}
 465
 466static const struct reg_default max9867_reg[] = {
 467        { 0x04, 0x00 },
 468        { 0x05, 0x00 },
 469        { 0x06, 0x00 },
 470        { 0x07, 0x00 },
 471        { 0x08, 0x00 },
 472        { 0x09, 0x00 },
 473        { 0x0A, 0x00 },
 474        { 0x0B, 0x00 },
 475        { 0x0C, 0x00 },
 476        { 0x0D, 0x00 },
 477        { 0x0E, 0x40 },
 478        { 0x0F, 0x40 },
 479        { 0x10, 0x00 },
 480        { 0x11, 0x00 },
 481        { 0x12, 0x00 },
 482        { 0x13, 0x00 },
 483        { 0x14, 0x00 },
 484        { 0x15, 0x00 },
 485        { 0x16, 0x00 },
 486        { 0x17, 0x00 },
 487};
 488
 489static const struct regmap_config max9867_regmap = {
 490        .reg_bits       = 8,
 491        .val_bits       = 8,
 492        .max_register   = MAX9867_REVISION,
 493        .reg_defaults   = max9867_reg,
 494        .num_reg_defaults = ARRAY_SIZE(max9867_reg),
 495        .volatile_reg   = max9867_volatile_register,
 496        .cache_type     = REGCACHE_RBTREE,
 497};
 498
 499static int max9867_i2c_probe(struct i2c_client *i2c,
 500                const struct i2c_device_id *id)
 501{
 502        struct max9867_priv *max9867;
 503        int ret, reg;
 504
 505        max9867 = devm_kzalloc(&i2c->dev, sizeof(*max9867), GFP_KERNEL);
 506        if (!max9867)
 507                return -ENOMEM;
 508
 509        i2c_set_clientdata(i2c, max9867);
 510        max9867->regmap = devm_regmap_init_i2c(i2c, &max9867_regmap);
 511        if (IS_ERR(max9867->regmap)) {
 512                ret = PTR_ERR(max9867->regmap);
 513                dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
 514                return ret;
 515        }
 516        ret = regmap_read(max9867->regmap, MAX9867_REVISION, &reg);
 517        if (ret < 0) {
 518                dev_err(&i2c->dev, "Failed to read: %d\n", ret);
 519                return ret;
 520        }
 521        dev_info(&i2c->dev, "device revision: %x\n", reg);
 522        ret = devm_snd_soc_register_component(&i2c->dev, &max9867_component,
 523                        max9867_dai, ARRAY_SIZE(max9867_dai));
 524        if (ret < 0)
 525                dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
 526        return ret;
 527}
 528
 529static const struct i2c_device_id max9867_i2c_id[] = {
 530        { "max9867", 0 },
 531        { }
 532};
 533MODULE_DEVICE_TABLE(i2c, max9867_i2c_id);
 534
 535static const struct of_device_id max9867_of_match[] = {
 536        { .compatible = "maxim,max9867", },
 537        { }
 538};
 539MODULE_DEVICE_TABLE(of, max9867_of_match);
 540
 541static struct i2c_driver max9867_i2c_driver = {
 542        .driver = {
 543                .name = "max9867",
 544                .of_match_table = of_match_ptr(max9867_of_match),
 545        },
 546        .probe  = max9867_i2c_probe,
 547        .id_table = max9867_i2c_id,
 548};
 549
 550module_i2c_driver(max9867_i2c_driver);
 551
 552MODULE_AUTHOR("Ladislav Michl <ladis@linux-mips.org>");
 553MODULE_DESCRIPTION("ASoC MAX9867 driver");
 554MODULE_LICENSE("GPL");
 555