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