647 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * max98925.c -- ALSA SoC Stereo MAX98925 driver4 * Copyright 2013-15 Maxim Integrated Products5 */6#include <linux/delay.h>7#include <linux/i2c.h>8#include <linux/module.h>9#include <linux/regmap.h>10#include <linux/slab.h>11#include <linux/cdev.h>12#include <sound/pcm.h>13#include <sound/pcm_params.h>14#include <sound/soc.h>15#include <sound/tlv.h>16#include "max98925.h"17 18static const char *const dai_text[] = {19 "Left", "Right", "LeftRight", "LeftRightDiv2",20};21 22static const char * const max98925_boost_voltage_text[] = {23 "8.5V", "8.25V", "8.0V", "7.75V", "7.5V", "7.25V", "7.0V", "6.75V",24 "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V"25};26 27static SOC_ENUM_SINGLE_DECL(max98925_boost_voltage,28 MAX98925_CONFIGURATION, M98925_BST_VOUT_SHIFT,29 max98925_boost_voltage_text);30 31static const char *const hpf_text[] = {32 "Disable", "DC Block", "100Hz", "200Hz", "400Hz", "800Hz",33};34 35static const struct reg_default max98925_reg[] = {36 { 0x0B, 0x00 }, /* IRQ Enable0 */37 { 0x0C, 0x00 }, /* IRQ Enable1 */38 { 0x0D, 0x00 }, /* IRQ Enable2 */39 { 0x0E, 0x00 }, /* IRQ Clear0 */40 { 0x0F, 0x00 }, /* IRQ Clear1 */41 { 0x10, 0x00 }, /* IRQ Clear2 */42 { 0x11, 0xC0 }, /* Map0 */43 { 0x12, 0x00 }, /* Map1 */44 { 0x13, 0x00 }, /* Map2 */45 { 0x14, 0xF0 }, /* Map3 */46 { 0x15, 0x00 }, /* Map4 */47 { 0x16, 0xAB }, /* Map5 */48 { 0x17, 0x89 }, /* Map6 */49 { 0x18, 0x00 }, /* Map7 */50 { 0x19, 0x00 }, /* Map8 */51 { 0x1A, 0x06 }, /* DAI Clock Mode 1 */52 { 0x1B, 0xC0 }, /* DAI Clock Mode 2 */53 { 0x1C, 0x00 }, /* DAI Clock Divider Denominator MSBs */54 { 0x1D, 0x00 }, /* DAI Clock Divider Denominator LSBs */55 { 0x1E, 0xF0 }, /* DAI Clock Divider Numerator MSBs */56 { 0x1F, 0x00 }, /* DAI Clock Divider Numerator LSBs */57 { 0x20, 0x50 }, /* Format */58 { 0x21, 0x00 }, /* TDM Slot Select */59 { 0x22, 0x00 }, /* DOUT Configuration VMON */60 { 0x23, 0x00 }, /* DOUT Configuration IMON */61 { 0x24, 0x00 }, /* DOUT Configuration VBAT */62 { 0x25, 0x00 }, /* DOUT Configuration VBST */63 { 0x26, 0x00 }, /* DOUT Configuration FLAG */64 { 0x27, 0xFF }, /* DOUT HiZ Configuration 1 */65 { 0x28, 0xFF }, /* DOUT HiZ Configuration 2 */66 { 0x29, 0xFF }, /* DOUT HiZ Configuration 3 */67 { 0x2A, 0xFF }, /* DOUT HiZ Configuration 4 */68 { 0x2B, 0x02 }, /* DOUT Drive Strength */69 { 0x2C, 0x90 }, /* Filters */70 { 0x2D, 0x00 }, /* Gain */71 { 0x2E, 0x02 }, /* Gain Ramping */72 { 0x2F, 0x00 }, /* Speaker Amplifier */73 { 0x30, 0x0A }, /* Threshold */74 { 0x31, 0x00 }, /* ALC Attack */75 { 0x32, 0x80 }, /* ALC Atten and Release */76 { 0x33, 0x00 }, /* ALC Infinite Hold Release */77 { 0x34, 0x92 }, /* ALC Configuration */78 { 0x35, 0x01 }, /* Boost Converter */79 { 0x36, 0x00 }, /* Block Enable */80 { 0x37, 0x00 }, /* Configuration */81 { 0x38, 0x00 }, /* Global Enable */82 { 0x3A, 0x00 }, /* Boost Limiter */83};84 85static const struct soc_enum max98925_dai_enum =86 SOC_ENUM_SINGLE(MAX98925_GAIN, 5, ARRAY_SIZE(dai_text), dai_text);87 88static const struct soc_enum max98925_hpf_enum =89 SOC_ENUM_SINGLE(MAX98925_FILTERS, 0, ARRAY_SIZE(hpf_text), hpf_text);90 91static const struct snd_kcontrol_new max98925_hpf_sel_mux =92 SOC_DAPM_ENUM("Rc Filter MUX Mux", max98925_hpf_enum);93 94static const struct snd_kcontrol_new max98925_dai_sel_mux =95 SOC_DAPM_ENUM("DAI IN MUX Mux", max98925_dai_enum);96 97static int max98925_dac_event(struct snd_soc_dapm_widget *w,98 struct snd_kcontrol *kcontrol, int event)99{100 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);101 struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);102 103 switch (event) {104 case SND_SOC_DAPM_PRE_PMU:105 regmap_update_bits(max98925->regmap,106 MAX98925_BLOCK_ENABLE,107 M98925_BST_EN_MASK |108 M98925_ADC_IMON_EN_MASK | M98925_ADC_VMON_EN_MASK,109 M98925_BST_EN_MASK |110 M98925_ADC_IMON_EN_MASK | M98925_ADC_VMON_EN_MASK);111 break;112 case SND_SOC_DAPM_POST_PMD:113 regmap_update_bits(max98925->regmap,114 MAX98925_BLOCK_ENABLE, M98925_BST_EN_MASK |115 M98925_ADC_IMON_EN_MASK | M98925_ADC_VMON_EN_MASK, 0);116 break;117 default:118 return 0;119 }120 return 0;121}122 123static const struct snd_soc_dapm_widget max98925_dapm_widgets[] = {124 SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),125 SND_SOC_DAPM_MUX("DAI IN MUX", SND_SOC_NOPM, 0, 0,126 &max98925_dai_sel_mux),127 SND_SOC_DAPM_MUX("Rc Filter MUX", SND_SOC_NOPM, 0, 0,128 &max98925_hpf_sel_mux),129 SND_SOC_DAPM_DAC_E("Amp Enable", NULL, MAX98925_BLOCK_ENABLE,130 M98925_SPK_EN_SHIFT, 0, max98925_dac_event,131 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),132 SND_SOC_DAPM_SUPPLY("Global Enable", MAX98925_GLOBAL_ENABLE,133 M98925_EN_SHIFT, 0, NULL, 0),134 SND_SOC_DAPM_OUTPUT("BE_OUT"),135};136 137static const struct snd_soc_dapm_route max98925_audio_map[] = {138 {"DAI IN MUX", "Left", "DAI_OUT"},139 {"DAI IN MUX", "Right", "DAI_OUT"},140 {"DAI IN MUX", "LeftRight", "DAI_OUT"},141 {"DAI IN MUX", "LeftRightDiv2", "DAI_OUT"},142 {"Rc Filter MUX", "Disable", "DAI IN MUX"},143 {"Rc Filter MUX", "DC Block", "DAI IN MUX"},144 {"Rc Filter MUX", "100Hz", "DAI IN MUX"},145 {"Rc Filter MUX", "200Hz", "DAI IN MUX"},146 {"Rc Filter MUX", "400Hz", "DAI IN MUX"},147 {"Rc Filter MUX", "800Hz", "DAI IN MUX"},148 {"Amp Enable", NULL, "Rc Filter MUX"},149 {"BE_OUT", NULL, "Amp Enable"},150 {"BE_OUT", NULL, "Global Enable"},151};152 153static bool max98925_volatile_register(struct device *dev, unsigned int reg)154{155 switch (reg) {156 case MAX98925_VBAT_DATA:157 case MAX98925_VBST_DATA:158 case MAX98925_LIVE_STATUS0:159 case MAX98925_LIVE_STATUS1:160 case MAX98925_LIVE_STATUS2:161 case MAX98925_STATE0:162 case MAX98925_STATE1:163 case MAX98925_STATE2:164 case MAX98925_FLAG0:165 case MAX98925_FLAG1:166 case MAX98925_FLAG2:167 case MAX98925_REV_VERSION:168 return true;169 default:170 return false;171 }172}173 174static bool max98925_readable_register(struct device *dev, unsigned int reg)175{176 switch (reg) {177 case MAX98925_IRQ_CLEAR0:178 case MAX98925_IRQ_CLEAR1:179 case MAX98925_IRQ_CLEAR2:180 case MAX98925_ALC_HOLD_RLS:181 return false;182 default:183 return true;184 }185}186 187static DECLARE_TLV_DB_SCALE(max98925_spk_tlv, -600, 100, 0);188 189static const struct snd_kcontrol_new max98925_snd_controls[] = {190 SOC_SINGLE_TLV("Speaker Volume", MAX98925_GAIN,191 M98925_SPK_GAIN_SHIFT, (1<<M98925_SPK_GAIN_WIDTH)-1, 0,192 max98925_spk_tlv),193 SOC_SINGLE("Ramp Switch", MAX98925_GAIN_RAMPING,194 M98925_SPK_RMP_EN_SHIFT, 1, 0),195 SOC_SINGLE("ZCD Switch", MAX98925_GAIN_RAMPING,196 M98925_SPK_ZCD_EN_SHIFT, 1, 0),197 SOC_SINGLE("ALC Switch", MAX98925_THRESHOLD,198 M98925_ALC_EN_SHIFT, 1, 0),199 SOC_SINGLE("ALC Threshold", MAX98925_THRESHOLD, M98925_ALC_TH_SHIFT,200 (1<<M98925_ALC_TH_WIDTH)-1, 0),201 SOC_ENUM("Boost Output Voltage", max98925_boost_voltage),202};203 204/* codec sample rate and n/m dividers parameter table */205static const struct {206 int rate;207 int sr;208 int divisors[3][2];209} rate_table[] = {210 {211 .rate = 8000,212 .sr = 0,213 .divisors = { {1, 375}, {5, 1764}, {1, 384} }214 },215 {216 .rate = 11025,217 .sr = 1,218 .divisors = { {147, 40000}, {1, 256}, {147, 40960} }219 },220 {221 .rate = 12000,222 .sr = 2,223 .divisors = { {1, 250}, {5, 1176}, {1, 256} }224 },225 {226 .rate = 16000,227 .sr = 3,228 .divisors = { {2, 375}, {5, 882}, {1, 192} }229 },230 {231 .rate = 22050,232 .sr = 4,233 .divisors = { {147, 20000}, {1, 128}, {147, 20480} }234 },235 {236 .rate = 24000,237 .sr = 5,238 .divisors = { {1, 125}, {5, 588}, {1, 128} }239 },240 {241 .rate = 32000,242 .sr = 6,243 .divisors = { {4, 375}, {5, 441}, {1, 96} }244 },245 {246 .rate = 44100,247 .sr = 7,248 .divisors = { {147, 10000}, {1, 64}, {147, 10240} }249 },250 {251 .rate = 48000,252 .sr = 8,253 .divisors = { {2, 125}, {5, 294}, {1, 64} }254 },255};256 257static inline int max98925_rate_value(struct snd_soc_component *component,258 int rate, int clock, int *value, int *n, int *m)259{260 int ret = -EINVAL;261 int i;262 263 for (i = 0; i < ARRAY_SIZE(rate_table); i++) {264 if (rate_table[i].rate >= rate) {265 *value = rate_table[i].sr;266 *n = rate_table[i].divisors[clock][0];267 *m = rate_table[i].divisors[clock][1];268 ret = 0;269 break;270 }271 }272 return ret;273}274 275static void max98925_set_sense_data(struct max98925_priv *max98925)276{277 /* set VMON slots */278 regmap_update_bits(max98925->regmap,279 MAX98925_DOUT_CFG_VMON,280 M98925_DAI_VMON_EN_MASK, M98925_DAI_VMON_EN_MASK);281 regmap_update_bits(max98925->regmap,282 MAX98925_DOUT_CFG_VMON,283 M98925_DAI_VMON_SLOT_MASK,284 max98925->v_slot << M98925_DAI_VMON_SLOT_SHIFT);285 /* set IMON slots */286 regmap_update_bits(max98925->regmap,287 MAX98925_DOUT_CFG_IMON,288 M98925_DAI_IMON_EN_MASK, M98925_DAI_IMON_EN_MASK);289 regmap_update_bits(max98925->regmap,290 MAX98925_DOUT_CFG_IMON,291 M98925_DAI_IMON_SLOT_MASK,292 max98925->i_slot << M98925_DAI_IMON_SLOT_SHIFT);293}294 295static int max98925_dai_set_fmt(struct snd_soc_dai *codec_dai,296 unsigned int fmt)297{298 struct snd_soc_component *component = codec_dai->component;299 struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);300 unsigned int invert = 0;301 302 dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);303 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {304 case SND_SOC_DAIFMT_CBC_CFC:305 regmap_update_bits(max98925->regmap,306 MAX98925_DAI_CLK_MODE2,307 M98925_DAI_MAS_MASK, 0);308 max98925_set_sense_data(max98925);309 break;310 case SND_SOC_DAIFMT_CBP_CFP:311 /*312 * set left channel DAI to provider mode,313 * right channel always consumer314 */315 regmap_update_bits(max98925->regmap,316 MAX98925_DAI_CLK_MODE2,317 M98925_DAI_MAS_MASK, M98925_DAI_MAS_MASK);318 break;319 default:320 dev_err(component->dev, "DAI clock mode unsupported");321 return -EINVAL;322 }323 324 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {325 case SND_SOC_DAIFMT_NB_NF:326 break;327 case SND_SOC_DAIFMT_NB_IF:328 invert = M98925_DAI_WCI_MASK;329 break;330 case SND_SOC_DAIFMT_IB_NF:331 invert = M98925_DAI_BCI_MASK;332 break;333 case SND_SOC_DAIFMT_IB_IF:334 invert = M98925_DAI_BCI_MASK | M98925_DAI_WCI_MASK;335 break;336 default:337 dev_err(component->dev, "DAI invert mode unsupported");338 return -EINVAL;339 }340 341 regmap_update_bits(max98925->regmap, MAX98925_FORMAT,342 M98925_DAI_BCI_MASK | M98925_DAI_WCI_MASK, invert);343 return 0;344}345 346static int max98925_set_clock(struct max98925_priv *max98925,347 struct snd_pcm_hw_params *params)348{349 unsigned int dai_sr = 0, clock, mdll, n, m;350 struct snd_soc_component *component = max98925->component;351 int rate = params_rate(params);352 /* BCLK/LRCLK ratio calculation */353 int blr_clk_ratio = params_channels(params) * max98925->ch_size;354 355 switch (blr_clk_ratio) {356 case 32:357 regmap_update_bits(max98925->regmap,358 MAX98925_DAI_CLK_MODE2,359 M98925_DAI_BSEL_MASK, M98925_DAI_BSEL_32);360 break;361 case 48:362 regmap_update_bits(max98925->regmap,363 MAX98925_DAI_CLK_MODE2,364 M98925_DAI_BSEL_MASK, M98925_DAI_BSEL_48);365 break;366 case 64:367 regmap_update_bits(max98925->regmap,368 MAX98925_DAI_CLK_MODE2,369 M98925_DAI_BSEL_MASK, M98925_DAI_BSEL_64);370 break;371 default:372 return -EINVAL;373 }374 375 switch (max98925->sysclk) {376 case 6000000:377 clock = 0;378 mdll = M98925_MDLL_MULT_MCLKx16;379 break;380 case 11289600:381 clock = 1;382 mdll = M98925_MDLL_MULT_MCLKx8;383 break;384 case 12000000:385 clock = 0;386 mdll = M98925_MDLL_MULT_MCLKx8;387 break;388 case 12288000:389 clock = 2;390 mdll = M98925_MDLL_MULT_MCLKx8;391 break;392 default:393 dev_info(max98925->component->dev, "unsupported sysclk %d\n",394 max98925->sysclk);395 return -EINVAL;396 }397 398 if (max98925_rate_value(component, rate, clock, &dai_sr, &n, &m))399 return -EINVAL;400 401 /* set DAI_SR to correct LRCLK frequency */402 regmap_update_bits(max98925->regmap,403 MAX98925_DAI_CLK_MODE2,404 M98925_DAI_SR_MASK, dai_sr << M98925_DAI_SR_SHIFT);405 /* set DAI m divider */406 regmap_write(max98925->regmap,407 MAX98925_DAI_CLK_DIV_M_MSBS, m >> 8);408 regmap_write(max98925->regmap,409 MAX98925_DAI_CLK_DIV_M_LSBS, m & 0xFF);410 /* set DAI n divider */411 regmap_write(max98925->regmap,412 MAX98925_DAI_CLK_DIV_N_MSBS, n >> 8);413 regmap_write(max98925->regmap,414 MAX98925_DAI_CLK_DIV_N_LSBS, n & 0xFF);415 /* set MDLL */416 regmap_update_bits(max98925->regmap, MAX98925_DAI_CLK_MODE1,417 M98925_MDLL_MULT_MASK, mdll << M98925_MDLL_MULT_SHIFT);418 return 0;419}420 421static int max98925_dai_hw_params(struct snd_pcm_substream *substream,422 struct snd_pcm_hw_params *params,423 struct snd_soc_dai *dai)424{425 struct snd_soc_component *component = dai->component;426 struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);427 428 switch (params_width(params)) {429 case 16:430 regmap_update_bits(max98925->regmap,431 MAX98925_FORMAT,432 M98925_DAI_CHANSZ_MASK, M98925_DAI_CHANSZ_16);433 max98925->ch_size = 16;434 break;435 case 24:436 regmap_update_bits(max98925->regmap,437 MAX98925_FORMAT,438 M98925_DAI_CHANSZ_MASK, M98925_DAI_CHANSZ_24);439 max98925->ch_size = 24;440 break;441 case 32:442 regmap_update_bits(max98925->regmap,443 MAX98925_FORMAT,444 M98925_DAI_CHANSZ_MASK, M98925_DAI_CHANSZ_32);445 max98925->ch_size = 32;446 break;447 default:448 pr_err("%s: format unsupported %d",449 __func__, params_format(params));450 return -EINVAL;451 }452 dev_dbg(component->dev, "%s: format supported %d",453 __func__, params_format(params));454 return max98925_set_clock(max98925, params);455}456 457static int max98925_dai_set_sysclk(struct snd_soc_dai *dai,458 int clk_id, unsigned int freq, int dir)459{460 struct snd_soc_component *component = dai->component;461 struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);462 463 switch (clk_id) {464 case 0:465 /* use MCLK for Left channel, right channel always BCLK */466 regmap_update_bits(max98925->regmap,467 MAX98925_DAI_CLK_MODE1,468 M98925_DAI_CLK_SOURCE_MASK, 0);469 break;470 case 1:471 /* configure dai clock source to BCLK instead of MCLK */472 regmap_update_bits(max98925->regmap,473 MAX98925_DAI_CLK_MODE1,474 M98925_DAI_CLK_SOURCE_MASK,475 M98925_DAI_CLK_SOURCE_MASK);476 break;477 default:478 return -EINVAL;479 }480 max98925->sysclk = freq;481 return 0;482}483 484#define MAX98925_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \485 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)486 487static const struct snd_soc_dai_ops max98925_dai_ops = {488 .set_sysclk = max98925_dai_set_sysclk,489 .set_fmt = max98925_dai_set_fmt,490 .hw_params = max98925_dai_hw_params,491};492 493static struct snd_soc_dai_driver max98925_dai[] = {494 {495 .name = "max98925-aif1",496 .playback = {497 .stream_name = "HiFi Playback",498 .channels_min = 1,499 .channels_max = 2,500 .rates = SNDRV_PCM_RATE_8000_48000,501 .formats = MAX98925_FORMATS,502 },503 .capture = {504 .stream_name = "HiFi Capture",505 .channels_min = 1,506 .channels_max = 2,507 .rates = SNDRV_PCM_RATE_8000_48000,508 .formats = MAX98925_FORMATS,509 },510 .ops = &max98925_dai_ops,511 }512};513 514static int max98925_probe(struct snd_soc_component *component)515{516 struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);517 518 max98925->component = component;519 regmap_write(max98925->regmap, MAX98925_GLOBAL_ENABLE, 0x00);520 /* It's not the default but we need to set DAI_DLY */521 regmap_write(max98925->regmap,522 MAX98925_FORMAT, M98925_DAI_DLY_MASK);523 regmap_write(max98925->regmap, MAX98925_TDM_SLOT_SELECT, 0xC8);524 regmap_write(max98925->regmap, MAX98925_DOUT_HIZ_CFG1, 0xFF);525 regmap_write(max98925->regmap, MAX98925_DOUT_HIZ_CFG2, 0xFF);526 regmap_write(max98925->regmap, MAX98925_DOUT_HIZ_CFG3, 0xFF);527 regmap_write(max98925->regmap, MAX98925_DOUT_HIZ_CFG4, 0xF0);528 regmap_write(max98925->regmap, MAX98925_FILTERS, 0xD8);529 regmap_write(max98925->regmap, MAX98925_ALC_CONFIGURATION, 0xF8);530 regmap_write(max98925->regmap, MAX98925_CONFIGURATION, 0xF0);531 /* Disable ALC muting */532 regmap_write(max98925->regmap, MAX98925_BOOST_LIMITER, 0xF8);533 return 0;534}535 536static const struct snd_soc_component_driver soc_component_dev_max98925 = {537 .probe = max98925_probe,538 .controls = max98925_snd_controls,539 .num_controls = ARRAY_SIZE(max98925_snd_controls),540 .dapm_routes = max98925_audio_map,541 .num_dapm_routes = ARRAY_SIZE(max98925_audio_map),542 .dapm_widgets = max98925_dapm_widgets,543 .num_dapm_widgets = ARRAY_SIZE(max98925_dapm_widgets),544 .idle_bias_on = 1,545 .use_pmdown_time = 1,546 .endianness = 1,547};548 549static const struct regmap_config max98925_regmap = {550 .reg_bits = 8,551 .val_bits = 8,552 .max_register = MAX98925_REV_VERSION,553 .reg_defaults = max98925_reg,554 .num_reg_defaults = ARRAY_SIZE(max98925_reg),555 .volatile_reg = max98925_volatile_register,556 .readable_reg = max98925_readable_register,557 .cache_type = REGCACHE_RBTREE,558};559 560static int max98925_i2c_probe(struct i2c_client *i2c)561{562 int ret, reg;563 u32 value;564 struct max98925_priv *max98925;565 566 max98925 = devm_kzalloc(&i2c->dev,567 sizeof(*max98925), GFP_KERNEL);568 if (!max98925)569 return -ENOMEM;570 571 i2c_set_clientdata(i2c, max98925);572 max98925->regmap = devm_regmap_init_i2c(i2c, &max98925_regmap);573 if (IS_ERR(max98925->regmap)) {574 ret = PTR_ERR(max98925->regmap);575 dev_err(&i2c->dev,576 "Failed to allocate regmap: %d\n", ret);577 return ret;578 }579 580 if (!of_property_read_u32(i2c->dev.of_node, "vmon-slot-no", &value)) {581 if (value > M98925_DAI_VMON_SLOT_1E_1F) {582 dev_err(&i2c->dev, "vmon slot number is wrong:\n");583 return -EINVAL;584 }585 max98925->v_slot = value;586 }587 if (!of_property_read_u32(i2c->dev.of_node, "imon-slot-no", &value)) {588 if (value > M98925_DAI_IMON_SLOT_1E_1F) {589 dev_err(&i2c->dev, "imon slot number is wrong:\n");590 return -EINVAL;591 }592 max98925->i_slot = value;593 }594 595 ret = regmap_read(max98925->regmap, MAX98925_REV_VERSION, ®);596 if (ret < 0) {597 dev_err(&i2c->dev, "Read revision failed\n");598 return ret;599 }600 601 if ((reg != MAX98925_VERSION) && (reg != MAX98925_VERSION1)) {602 ret = -ENODEV;603 dev_err(&i2c->dev, "Invalid revision (%d 0x%02X)\n",604 ret, reg);605 return ret;606 }607 608 dev_info(&i2c->dev, "device version 0x%02X\n", reg);609 610 ret = devm_snd_soc_register_component(&i2c->dev,611 &soc_component_dev_max98925,612 max98925_dai, ARRAY_SIZE(max98925_dai));613 if (ret < 0)614 dev_err(&i2c->dev,615 "Failed to register component: %d\n", ret);616 return ret;617}618 619static const struct i2c_device_id max98925_i2c_id[] = {620 { "max98925" },621 { }622};623MODULE_DEVICE_TABLE(i2c, max98925_i2c_id);624 625#ifdef CONFIG_OF626static const struct of_device_id max98925_of_match[] = {627 { .compatible = "maxim,max98925", },628 { }629};630MODULE_DEVICE_TABLE(of, max98925_of_match);631#endif632 633static struct i2c_driver max98925_i2c_driver = {634 .driver = {635 .name = "max98925",636 .of_match_table = of_match_ptr(max98925_of_match),637 },638 .probe = max98925_i2c_probe,639 .id_table = max98925_i2c_id,640};641 642module_i2c_driver(max98925_i2c_driver)643 644MODULE_DESCRIPTION("ALSA SoC MAX98925 driver");645MODULE_AUTHOR("Ralph Birt <rdbirt@gmail.com>, Anish kumar <anish.kumar@maximintegrated.com>");646MODULE_LICENSE("GPL");647