1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2017, Maxim Integrated
4 #include <linux/acpi.h>
5 #include <linux/delay.h>
7 #include <linux/module.h>
8 #include <linux/mod_devicetable.h>
11 #include <linux/regmap.h>
12 #include <linux/slab.h>
13 #include <linux/cdev.h>
14 #include <sound/pcm.h>
15 #include <sound/pcm_params.h>
16 #include <sound/soc.h>
17 #include <sound/tlv.h>
20 static const u32 max98373_i2c_cache_reg
[] = {
21 MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK
,
22 MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK
,
23 MAX98373_R20B6_BDE_CUR_STATE_READBACK
,
26 static struct reg_default max98373_reg
[] = {
27 {MAX98373_R2000_SW_RESET
, 0x00},
28 {MAX98373_R2001_INT_RAW1
, 0x00},
29 {MAX98373_R2002_INT_RAW2
, 0x00},
30 {MAX98373_R2003_INT_RAW3
, 0x00},
31 {MAX98373_R2004_INT_STATE1
, 0x00},
32 {MAX98373_R2005_INT_STATE2
, 0x00},
33 {MAX98373_R2006_INT_STATE3
, 0x00},
34 {MAX98373_R2007_INT_FLAG1
, 0x00},
35 {MAX98373_R2008_INT_FLAG2
, 0x00},
36 {MAX98373_R2009_INT_FLAG3
, 0x00},
37 {MAX98373_R200A_INT_EN1
, 0x00},
38 {MAX98373_R200B_INT_EN2
, 0x00},
39 {MAX98373_R200C_INT_EN3
, 0x00},
40 {MAX98373_R200D_INT_FLAG_CLR1
, 0x00},
41 {MAX98373_R200E_INT_FLAG_CLR2
, 0x00},
42 {MAX98373_R200F_INT_FLAG_CLR3
, 0x00},
43 {MAX98373_R2010_IRQ_CTRL
, 0x00},
44 {MAX98373_R2014_THERM_WARN_THRESH
, 0x10},
45 {MAX98373_R2015_THERM_SHDN_THRESH
, 0x27},
46 {MAX98373_R2016_THERM_HYSTERESIS
, 0x01},
47 {MAX98373_R2017_THERM_FOLDBACK_SET
, 0xC0},
48 {MAX98373_R2018_THERM_FOLDBACK_EN
, 0x00},
49 {MAX98373_R201E_PIN_DRIVE_STRENGTH
, 0x55},
50 {MAX98373_R2020_PCM_TX_HIZ_EN_1
, 0xFE},
51 {MAX98373_R2021_PCM_TX_HIZ_EN_2
, 0xFF},
52 {MAX98373_R2022_PCM_TX_SRC_1
, 0x00},
53 {MAX98373_R2023_PCM_TX_SRC_2
, 0x00},
54 {MAX98373_R2024_PCM_DATA_FMT_CFG
, 0xC0},
55 {MAX98373_R2025_AUDIO_IF_MODE
, 0x00},
56 {MAX98373_R2026_PCM_CLOCK_RATIO
, 0x04},
57 {MAX98373_R2027_PCM_SR_SETUP_1
, 0x08},
58 {MAX98373_R2028_PCM_SR_SETUP_2
, 0x88},
59 {MAX98373_R2029_PCM_TO_SPK_MONO_MIX_1
, 0x00},
60 {MAX98373_R202A_PCM_TO_SPK_MONO_MIX_2
, 0x00},
61 {MAX98373_R202B_PCM_RX_EN
, 0x00},
62 {MAX98373_R202C_PCM_TX_EN
, 0x00},
63 {MAX98373_R202E_ICC_RX_CH_EN_1
, 0x00},
64 {MAX98373_R202F_ICC_RX_CH_EN_2
, 0x00},
65 {MAX98373_R2030_ICC_TX_HIZ_EN_1
, 0xFF},
66 {MAX98373_R2031_ICC_TX_HIZ_EN_2
, 0xFF},
67 {MAX98373_R2032_ICC_LINK_EN_CFG
, 0x30},
68 {MAX98373_R2034_ICC_TX_CNTL
, 0x00},
69 {MAX98373_R2035_ICC_TX_EN
, 0x00},
70 {MAX98373_R2036_SOUNDWIRE_CTRL
, 0x05},
71 {MAX98373_R203D_AMP_DIG_VOL_CTRL
, 0x00},
72 {MAX98373_R203E_AMP_PATH_GAIN
, 0x08},
73 {MAX98373_R203F_AMP_DSP_CFG
, 0x02},
74 {MAX98373_R2040_TONE_GEN_CFG
, 0x00},
75 {MAX98373_R2041_AMP_CFG
, 0x03},
76 {MAX98373_R2042_AMP_EDGE_RATE_CFG
, 0x00},
77 {MAX98373_R2043_AMP_EN
, 0x00},
78 {MAX98373_R2046_IV_SENSE_ADC_DSP_CFG
, 0x04},
79 {MAX98373_R2047_IV_SENSE_ADC_EN
, 0x00},
80 {MAX98373_R2051_MEAS_ADC_SAMPLING_RATE
, 0x00},
81 {MAX98373_R2052_MEAS_ADC_PVDD_FLT_CFG
, 0x00},
82 {MAX98373_R2053_MEAS_ADC_THERM_FLT_CFG
, 0x00},
83 {MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK
, 0x00},
84 {MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK
, 0x00},
85 {MAX98373_R2056_MEAS_ADC_PVDD_CH_EN
, 0x00},
86 {MAX98373_R2090_BDE_LVL_HOLD
, 0x00},
87 {MAX98373_R2091_BDE_GAIN_ATK_REL_RATE
, 0x00},
88 {MAX98373_R2092_BDE_CLIPPER_MODE
, 0x00},
89 {MAX98373_R2097_BDE_L1_THRESH
, 0x00},
90 {MAX98373_R2098_BDE_L2_THRESH
, 0x00},
91 {MAX98373_R2099_BDE_L3_THRESH
, 0x00},
92 {MAX98373_R209A_BDE_L4_THRESH
, 0x00},
93 {MAX98373_R209B_BDE_THRESH_HYST
, 0x00},
94 {MAX98373_R20A8_BDE_L1_CFG_1
, 0x00},
95 {MAX98373_R20A9_BDE_L1_CFG_2
, 0x00},
96 {MAX98373_R20AA_BDE_L1_CFG_3
, 0x00},
97 {MAX98373_R20AB_BDE_L2_CFG_1
, 0x00},
98 {MAX98373_R20AC_BDE_L2_CFG_2
, 0x00},
99 {MAX98373_R20AD_BDE_L2_CFG_3
, 0x00},
100 {MAX98373_R20AE_BDE_L3_CFG_1
, 0x00},
101 {MAX98373_R20AF_BDE_L3_CFG_2
, 0x00},
102 {MAX98373_R20B0_BDE_L3_CFG_3
, 0x00},
103 {MAX98373_R20B1_BDE_L4_CFG_1
, 0x00},
104 {MAX98373_R20B2_BDE_L4_CFG_2
, 0x00},
105 {MAX98373_R20B3_BDE_L4_CFG_3
, 0x00},
106 {MAX98373_R20B4_BDE_INFINITE_HOLD_RELEASE
, 0x00},
107 {MAX98373_R20B5_BDE_EN
, 0x00},
108 {MAX98373_R20B6_BDE_CUR_STATE_READBACK
, 0x00},
109 {MAX98373_R20D1_DHT_CFG
, 0x01},
110 {MAX98373_R20D2_DHT_ATTACK_CFG
, 0x02},
111 {MAX98373_R20D3_DHT_RELEASE_CFG
, 0x03},
112 {MAX98373_R20D4_DHT_EN
, 0x00},
113 {MAX98373_R20E0_LIMITER_THRESH_CFG
, 0x00},
114 {MAX98373_R20E1_LIMITER_ATK_REL_RATES
, 0x00},
115 {MAX98373_R20E2_LIMITER_EN
, 0x00},
116 {MAX98373_R20FE_DEVICE_AUTO_RESTART_CFG
, 0x00},
117 {MAX98373_R20FF_GLOBAL_SHDN
, 0x00},
118 {MAX98373_R21FF_REV_ID
, 0x42},
121 static int max98373_dai_set_fmt(struct snd_soc_dai
*codec_dai
, unsigned int fmt
)
123 struct snd_soc_component
*component
= codec_dai
->component
;
124 struct max98373_priv
*max98373
= snd_soc_component_get_drvdata(component
);
125 unsigned int format
= 0;
126 unsigned int invert
= 0;
128 dev_dbg(component
->dev
, "%s: fmt 0x%08X\n", __func__
, fmt
);
130 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
131 case SND_SOC_DAIFMT_NB_NF
:
133 case SND_SOC_DAIFMT_IB_NF
:
134 invert
= MAX98373_PCM_MODE_CFG_PCM_BCLKEDGE
;
137 dev_err(component
->dev
, "DAI invert mode unsupported\n");
141 regmap_update_bits(max98373
->regmap
,
142 MAX98373_R2026_PCM_CLOCK_RATIO
,
143 MAX98373_PCM_MODE_CFG_PCM_BCLKEDGE
,
146 /* interface format */
147 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
148 case SND_SOC_DAIFMT_I2S
:
149 format
= MAX98373_PCM_FORMAT_I2S
;
151 case SND_SOC_DAIFMT_LEFT_J
:
152 format
= MAX98373_PCM_FORMAT_LJ
;
154 case SND_SOC_DAIFMT_DSP_A
:
155 format
= MAX98373_PCM_FORMAT_TDM_MODE1
;
157 case SND_SOC_DAIFMT_DSP_B
:
158 format
= MAX98373_PCM_FORMAT_TDM_MODE0
;
164 regmap_update_bits(max98373
->regmap
,
165 MAX98373_R2024_PCM_DATA_FMT_CFG
,
166 MAX98373_PCM_MODE_CFG_FORMAT_MASK
,
167 format
<< MAX98373_PCM_MODE_CFG_FORMAT_SHIFT
);
172 /* BCLKs per LRCLK */
173 static const int bclk_sel_table
[] = {
174 32, 48, 64, 96, 128, 192, 256, 384, 512, 320,
177 static int max98373_get_bclk_sel(int bclk
)
180 /* match BCLKs per LRCLK */
181 for (i
= 0; i
< ARRAY_SIZE(bclk_sel_table
); i
++) {
182 if (bclk_sel_table
[i
] == bclk
)
188 static int max98373_set_clock(struct snd_soc_component
*component
,
189 struct snd_pcm_hw_params
*params
)
191 struct max98373_priv
*max98373
= snd_soc_component_get_drvdata(component
);
192 /* BCLK/LRCLK ratio calculation */
193 int blr_clk_ratio
= params_channels(params
) * max98373
->ch_size
;
196 if (!max98373
->tdm_mode
) {
197 /* BCLK configuration */
198 value
= max98373_get_bclk_sel(blr_clk_ratio
);
200 dev_err(component
->dev
, "format unsupported %d\n",
201 params_format(params
));
205 regmap_update_bits(max98373
->regmap
,
206 MAX98373_R2026_PCM_CLOCK_RATIO
,
207 MAX98373_PCM_CLK_SETUP_BSEL_MASK
,
213 static int max98373_dai_hw_params(struct snd_pcm_substream
*substream
,
214 struct snd_pcm_hw_params
*params
,
215 struct snd_soc_dai
*dai
)
217 struct snd_soc_component
*component
= dai
->component
;
218 struct max98373_priv
*max98373
= snd_soc_component_get_drvdata(component
);
219 unsigned int sampling_rate
= 0;
220 unsigned int chan_sz
= 0;
222 /* pcm mode configuration */
223 switch (snd_pcm_format_width(params_format(params
))) {
225 chan_sz
= MAX98373_PCM_MODE_CFG_CHANSZ_16
;
228 chan_sz
= MAX98373_PCM_MODE_CFG_CHANSZ_24
;
231 chan_sz
= MAX98373_PCM_MODE_CFG_CHANSZ_32
;
234 dev_err(component
->dev
, "format unsupported %d\n",
235 params_format(params
));
239 max98373
->ch_size
= snd_pcm_format_width(params_format(params
));
241 regmap_update_bits(max98373
->regmap
,
242 MAX98373_R2024_PCM_DATA_FMT_CFG
,
243 MAX98373_PCM_MODE_CFG_CHANSZ_MASK
, chan_sz
);
245 dev_dbg(component
->dev
, "format supported %d",
246 params_format(params
));
248 /* sampling rate configuration */
249 switch (params_rate(params
)) {
251 sampling_rate
= MAX98373_PCM_SR_SET1_SR_8000
;
254 sampling_rate
= MAX98373_PCM_SR_SET1_SR_11025
;
257 sampling_rate
= MAX98373_PCM_SR_SET1_SR_12000
;
260 sampling_rate
= MAX98373_PCM_SR_SET1_SR_16000
;
263 sampling_rate
= MAX98373_PCM_SR_SET1_SR_22050
;
266 sampling_rate
= MAX98373_PCM_SR_SET1_SR_24000
;
269 sampling_rate
= MAX98373_PCM_SR_SET1_SR_32000
;
272 sampling_rate
= MAX98373_PCM_SR_SET1_SR_44100
;
275 sampling_rate
= MAX98373_PCM_SR_SET1_SR_48000
;
278 sampling_rate
= MAX98373_PCM_SR_SET1_SR_88200
;
281 sampling_rate
= MAX98373_PCM_SR_SET1_SR_96000
;
284 dev_err(component
->dev
, "rate %d not supported\n",
285 params_rate(params
));
289 /* set DAI_SR to correct LRCLK frequency */
290 regmap_update_bits(max98373
->regmap
,
291 MAX98373_R2027_PCM_SR_SETUP_1
,
292 MAX98373_PCM_SR_SET1_SR_MASK
,
294 regmap_update_bits(max98373
->regmap
,
295 MAX98373_R2028_PCM_SR_SETUP_2
,
296 MAX98373_PCM_SR_SET2_SR_MASK
,
297 sampling_rate
<< MAX98373_PCM_SR_SET2_SR_SHIFT
);
299 /* set sampling rate of IV */
300 if (max98373
->interleave_mode
&&
301 sampling_rate
> MAX98373_PCM_SR_SET1_SR_16000
)
302 regmap_update_bits(max98373
->regmap
,
303 MAX98373_R2028_PCM_SR_SETUP_2
,
304 MAX98373_PCM_SR_SET2_IVADC_SR_MASK
,
307 regmap_update_bits(max98373
->regmap
,
308 MAX98373_R2028_PCM_SR_SETUP_2
,
309 MAX98373_PCM_SR_SET2_IVADC_SR_MASK
,
312 return max98373_set_clock(component
, params
);
317 static int max98373_dai_tdm_slot(struct snd_soc_dai
*dai
,
318 unsigned int tx_mask
, unsigned int rx_mask
,
319 int slots
, int slot_width
)
321 struct snd_soc_component
*component
= dai
->component
;
322 struct max98373_priv
*max98373
= snd_soc_component_get_drvdata(component
);
324 unsigned int chan_sz
= 0;
328 if (!tx_mask
&& !rx_mask
&& !slots
&& !slot_width
)
329 max98373
->tdm_mode
= false;
331 max98373
->tdm_mode
= true;
333 /* BCLK configuration */
334 bsel
= max98373_get_bclk_sel(slots
* slot_width
);
336 dev_err(component
->dev
, "BCLK %d not supported\n",
341 regmap_update_bits(max98373
->regmap
,
342 MAX98373_R2026_PCM_CLOCK_RATIO
,
343 MAX98373_PCM_CLK_SETUP_BSEL_MASK
,
346 /* Channel size configuration */
347 switch (slot_width
) {
349 chan_sz
= MAX98373_PCM_MODE_CFG_CHANSZ_16
;
352 chan_sz
= MAX98373_PCM_MODE_CFG_CHANSZ_24
;
355 chan_sz
= MAX98373_PCM_MODE_CFG_CHANSZ_32
;
358 dev_err(component
->dev
, "format unsupported %d\n",
363 regmap_update_bits(max98373
->regmap
,
364 MAX98373_R2024_PCM_DATA_FMT_CFG
,
365 MAX98373_PCM_MODE_CFG_CHANSZ_MASK
, chan_sz
);
367 /* Rx slot configuration */
370 for (x
= 0 ; x
< 16 ; x
++, mask
>>= 1) {
373 regmap_update_bits(max98373
->regmap
,
374 MAX98373_R2029_PCM_TO_SPK_MONO_MIX_1
,
375 MAX98373_PCM_TO_SPK_CH0_SRC_MASK
, x
);
377 regmap_write(max98373
->regmap
,
378 MAX98373_R202A_PCM_TO_SPK_MONO_MIX_2
,
386 /* Tx slot Hi-Z configuration */
387 regmap_write(max98373
->regmap
,
388 MAX98373_R2020_PCM_TX_HIZ_EN_1
,
390 regmap_write(max98373
->regmap
,
391 MAX98373_R2021_PCM_TX_HIZ_EN_2
,
392 (~tx_mask
& 0xFF00) >> 8);
397 #define MAX98373_RATES SNDRV_PCM_RATE_8000_96000
399 #define MAX98373_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
400 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
402 static const struct snd_soc_dai_ops max98373_dai_ops
= {
403 .set_fmt
= max98373_dai_set_fmt
,
404 .hw_params
= max98373_dai_hw_params
,
405 .set_tdm_slot
= max98373_dai_tdm_slot
,
408 static bool max98373_readable_register(struct device
*dev
, unsigned int reg
)
411 case MAX98373_R2000_SW_RESET
:
412 case MAX98373_R2001_INT_RAW1
... MAX98373_R200C_INT_EN3
:
413 case MAX98373_R2010_IRQ_CTRL
:
414 case MAX98373_R2014_THERM_WARN_THRESH
415 ... MAX98373_R2018_THERM_FOLDBACK_EN
:
416 case MAX98373_R201E_PIN_DRIVE_STRENGTH
417 ... MAX98373_R2036_SOUNDWIRE_CTRL
:
418 case MAX98373_R203D_AMP_DIG_VOL_CTRL
... MAX98373_R2043_AMP_EN
:
419 case MAX98373_R2046_IV_SENSE_ADC_DSP_CFG
420 ... MAX98373_R2047_IV_SENSE_ADC_EN
:
421 case MAX98373_R2051_MEAS_ADC_SAMPLING_RATE
422 ... MAX98373_R2056_MEAS_ADC_PVDD_CH_EN
:
423 case MAX98373_R2090_BDE_LVL_HOLD
... MAX98373_R2092_BDE_CLIPPER_MODE
:
424 case MAX98373_R2097_BDE_L1_THRESH
425 ... MAX98373_R209B_BDE_THRESH_HYST
:
426 case MAX98373_R20A8_BDE_L1_CFG_1
... MAX98373_R20B3_BDE_L4_CFG_3
:
427 case MAX98373_R20B5_BDE_EN
... MAX98373_R20B6_BDE_CUR_STATE_READBACK
:
428 case MAX98373_R20D1_DHT_CFG
... MAX98373_R20D4_DHT_EN
:
429 case MAX98373_R20E0_LIMITER_THRESH_CFG
... MAX98373_R20E2_LIMITER_EN
:
430 case MAX98373_R20FE_DEVICE_AUTO_RESTART_CFG
431 ... MAX98373_R20FF_GLOBAL_SHDN
:
432 case MAX98373_R21FF_REV_ID
:
439 static bool max98373_volatile_reg(struct device
*dev
, unsigned int reg
)
442 case MAX98373_R2000_SW_RESET
... MAX98373_R2009_INT_FLAG3
:
443 case MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK
:
444 case MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK
:
445 case MAX98373_R20B6_BDE_CUR_STATE_READBACK
:
446 case MAX98373_R20FF_GLOBAL_SHDN
:
447 case MAX98373_R21FF_REV_ID
:
454 static struct snd_soc_dai_driver max98373_dai
[] = {
456 .name
= "max98373-aif1",
458 .stream_name
= "HiFi Playback",
461 .rates
= MAX98373_RATES
,
462 .formats
= MAX98373_FORMATS
,
465 .stream_name
= "HiFi Capture",
468 .rates
= MAX98373_RATES
,
469 .formats
= MAX98373_FORMATS
,
471 .ops
= &max98373_dai_ops
,
475 #ifdef CONFIG_PM_SLEEP
476 static int max98373_suspend(struct device
*dev
)
478 struct max98373_priv
*max98373
= dev_get_drvdata(dev
);
481 /* cache feedback register values before suspend */
482 for (i
= 0; i
< max98373
->cache_num
; i
++)
483 regmap_read(max98373
->regmap
, max98373
->cache
[i
].reg
, &max98373
->cache
[i
].val
);
485 regcache_cache_only(max98373
->regmap
, true);
486 regcache_mark_dirty(max98373
->regmap
);
490 static int max98373_resume(struct device
*dev
)
492 struct max98373_priv
*max98373
= dev_get_drvdata(dev
);
494 regcache_cache_only(max98373
->regmap
, false);
495 max98373_reset(max98373
, dev
);
496 regcache_sync(max98373
->regmap
);
501 static const struct dev_pm_ops max98373_pm
= {
502 SET_SYSTEM_SLEEP_PM_OPS(max98373_suspend
, max98373_resume
)
505 static const struct regmap_config max98373_regmap
= {
508 .max_register
= MAX98373_R21FF_REV_ID
,
509 .reg_defaults
= max98373_reg
,
510 .num_reg_defaults
= ARRAY_SIZE(max98373_reg
),
511 .readable_reg
= max98373_readable_register
,
512 .volatile_reg
= max98373_volatile_reg
,
513 .cache_type
= REGCACHE_RBTREE
,
516 static int max98373_i2c_probe(struct i2c_client
*i2c
)
521 struct max98373_priv
*max98373
= NULL
;
523 max98373
= devm_kzalloc(&i2c
->dev
, sizeof(*max98373
), GFP_KERNEL
);
529 i2c_set_clientdata(i2c
, max98373
);
531 /* update interleave mode info */
532 if (device_property_read_bool(&i2c
->dev
, "maxim,interleave_mode"))
533 max98373
->interleave_mode
= true;
535 max98373
->interleave_mode
= false;
537 /* regmap initialization */
538 max98373
->regmap
= devm_regmap_init_i2c(i2c
, &max98373_regmap
);
539 if (IS_ERR(max98373
->regmap
)) {
540 ret
= PTR_ERR(max98373
->regmap
);
542 "Failed to allocate regmap: %d\n", ret
);
546 max98373
->cache_num
= ARRAY_SIZE(max98373_i2c_cache_reg
);
547 max98373
->cache
= devm_kcalloc(&i2c
->dev
, max98373
->cache_num
,
548 sizeof(*max98373
->cache
),
550 if (!max98373
->cache
) {
555 for (i
= 0; i
< max98373
->cache_num
; i
++)
556 max98373
->cache
[i
].reg
= max98373_i2c_cache_reg
[i
];
558 /* voltage/current slot & gpio configuration */
559 max98373_slot_config(&i2c
->dev
, max98373
);
561 /* Check Revision ID */
562 ret
= regmap_read(max98373
->regmap
,
563 MAX98373_R21FF_REV_ID
, ®
);
566 "Failed to read: 0x%02X\n", MAX98373_R21FF_REV_ID
);
569 dev_info(&i2c
->dev
, "MAX98373 revisionID: 0x%02X\n", reg
);
571 /* codec registration */
572 ret
= devm_snd_soc_register_component(&i2c
->dev
, &soc_codec_dev_max98373
,
573 max98373_dai
, ARRAY_SIZE(max98373_dai
));
575 dev_err(&i2c
->dev
, "Failed to register codec: %d\n", ret
);
580 static const struct i2c_device_id max98373_i2c_id
[] = {
585 MODULE_DEVICE_TABLE(i2c
, max98373_i2c_id
);
587 #if defined(CONFIG_OF)
588 static const struct of_device_id max98373_of_match
[] = {
589 { .compatible
= "maxim,max98373", },
592 MODULE_DEVICE_TABLE(of
, max98373_of_match
);
596 static const struct acpi_device_id max98373_acpi_match
[] = {
600 MODULE_DEVICE_TABLE(acpi
, max98373_acpi_match
);
603 static struct i2c_driver max98373_i2c_driver
= {
606 .of_match_table
= of_match_ptr(max98373_of_match
),
607 .acpi_match_table
= ACPI_PTR(max98373_acpi_match
),
610 .probe
= max98373_i2c_probe
,
611 .id_table
= max98373_i2c_id
,
614 module_i2c_driver(max98373_i2c_driver
)
616 MODULE_DESCRIPTION("ALSA SoC MAX98373 driver");
617 MODULE_AUTHOR("Ryan Lee <ryans.lee@maximintegrated.com>");
618 MODULE_LICENSE("GPL");