root/sound/soc/codecs/max98926.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. max98926_volatile_register
  2. max98926_readable_register
  3. max98926_set_sense_data
  4. max98926_dai_set_fmt
  5. max98926_dai_hw_params
  6. max98926_probe
  7. max98926_i2c_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * max98926.c -- ALSA SoC MAX98926 driver
   4  * Copyright 2013-15 Maxim Integrated Products
   5  */
   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 "max98926.h"
  17 
  18 static const char * const max98926_boost_voltage_txt[] = {
  19         "8.5V", "8.25V", "8.0V", "7.75V", "7.5V", "7.25V", "7.0V", "6.75V",
  20         "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V"
  21 };
  22 
  23 static const char *const max98926_pdm_ch_text[] = {
  24         "Current", "Voltage",
  25 };
  26 
  27 static const char *const max98926_hpf_cutoff_txt[] = {
  28         "Disable", "DC Block", "100Hz",
  29         "200Hz", "400Hz", "800Hz",
  30 };
  31 
  32 static const struct reg_default max98926_reg[] = {
  33         { 0x0B, 0x00 }, /* IRQ Enable0 */
  34         { 0x0C, 0x00 }, /* IRQ Enable1 */
  35         { 0x0D, 0x00 }, /* IRQ Enable2 */
  36         { 0x0E, 0x00 }, /* IRQ Clear0 */
  37         { 0x0F, 0x00 }, /* IRQ Clear1 */
  38         { 0x10, 0x00 }, /* IRQ Clear2 */
  39         { 0x11, 0xC0 }, /* Map0 */
  40         { 0x12, 0x00 }, /* Map1 */
  41         { 0x13, 0x00 }, /* Map2 */
  42         { 0x14, 0xF0 }, /* Map3 */
  43         { 0x15, 0x00 }, /* Map4 */
  44         { 0x16, 0xAB }, /* Map5 */
  45         { 0x17, 0x89 }, /* Map6 */
  46         { 0x18, 0x00 }, /* Map7 */
  47         { 0x19, 0x00 }, /* Map8 */
  48         { 0x1A, 0x04 }, /* DAI Clock Mode 1 */
  49         { 0x1B, 0x00 }, /* DAI Clock Mode 2 */
  50         { 0x1C, 0x00 }, /* DAI Clock Divider Denominator MSBs */
  51         { 0x1D, 0x00 }, /* DAI Clock Divider Denominator LSBs */
  52         { 0x1E, 0xF0 }, /* DAI Clock Divider Numerator MSBs */
  53         { 0x1F, 0x00 }, /* DAI Clock Divider Numerator LSBs */
  54         { 0x20, 0x50 }, /* Format */
  55         { 0x21, 0x00 }, /* TDM Slot Select */
  56         { 0x22, 0x00 }, /* DOUT Configuration VMON */
  57         { 0x23, 0x00 }, /* DOUT Configuration IMON */
  58         { 0x24, 0x00 }, /* DOUT Configuration VBAT */
  59         { 0x25, 0x00 }, /* DOUT Configuration VBST */
  60         { 0x26, 0x00 }, /* DOUT Configuration FLAG */
  61         { 0x27, 0xFF }, /* DOUT HiZ Configuration 1 */
  62         { 0x28, 0xFF }, /* DOUT HiZ Configuration 2 */
  63         { 0x29, 0xFF }, /* DOUT HiZ Configuration 3 */
  64         { 0x2A, 0xFF }, /* DOUT HiZ Configuration 4 */
  65         { 0x2B, 0x02 }, /* DOUT Drive Strength */
  66         { 0x2C, 0x90 }, /* Filters */
  67         { 0x2D, 0x00 }, /* Gain */
  68         { 0x2E, 0x02 }, /* Gain Ramping */
  69         { 0x2F, 0x00 }, /* Speaker Amplifier */
  70         { 0x30, 0x0A }, /* Threshold */
  71         { 0x31, 0x00 }, /* ALC Attack */
  72         { 0x32, 0x80 }, /* ALC Atten and Release */
  73         { 0x33, 0x00 }, /* ALC Infinite Hold Release */
  74         { 0x34, 0x92 }, /* ALC Configuration */
  75         { 0x35, 0x01 }, /* Boost Converter */
  76         { 0x36, 0x00 }, /* Block Enable */
  77         { 0x37, 0x00 }, /* Configuration */
  78         { 0x38, 0x00 }, /* Global Enable */
  79         { 0x3A, 0x00 }, /* Boost Limiter */
  80 };
  81 
  82 static const struct soc_enum max98926_voltage_enum[] = {
  83         SOC_ENUM_SINGLE(MAX98926_DAI_CLK_DIV_N_LSBS, 0,
  84                 ARRAY_SIZE(max98926_pdm_ch_text),
  85                 max98926_pdm_ch_text),
  86 };
  87 
  88 static const struct snd_kcontrol_new max98926_voltage_control =
  89         SOC_DAPM_ENUM("Route", max98926_voltage_enum);
  90 
  91 static const struct soc_enum max98926_current_enum[] = {
  92         SOC_ENUM_SINGLE(MAX98926_DAI_CLK_DIV_N_LSBS,
  93                 MAX98926_PDM_SOURCE_1_SHIFT,
  94                 ARRAY_SIZE(max98926_pdm_ch_text),
  95                 max98926_pdm_ch_text),
  96 };
  97 
  98 static const struct snd_kcontrol_new max98926_current_control =
  99         SOC_DAPM_ENUM("Route", max98926_current_enum);
 100 
 101 static const struct snd_kcontrol_new max98926_mixer_controls[] = {
 102         SOC_DAPM_SINGLE("PCM Single Switch", MAX98926_SPK_AMP,
 103                 MAX98926_INSELECT_MODE_SHIFT, 0, 0),
 104         SOC_DAPM_SINGLE("PDM Single Switch", MAX98926_SPK_AMP,
 105                 MAX98926_INSELECT_MODE_SHIFT, 1, 0),
 106 };
 107 
 108 static const struct snd_kcontrol_new max98926_dai_controls[] = {
 109         SOC_DAPM_SINGLE("Left", MAX98926_GAIN,
 110                 MAX98926_DAC_IN_SEL_SHIFT, 0, 0),
 111         SOC_DAPM_SINGLE("Right", MAX98926_GAIN,
 112                 MAX98926_DAC_IN_SEL_SHIFT, 1, 0),
 113         SOC_DAPM_SINGLE("LeftRight", MAX98926_GAIN,
 114                 MAX98926_DAC_IN_SEL_SHIFT, 2, 0),
 115         SOC_DAPM_SINGLE("(Left+Right)/2 Switch", MAX98926_GAIN,
 116                 MAX98926_DAC_IN_SEL_SHIFT, 3, 0),
 117 };
 118 
 119 static const struct snd_soc_dapm_widget max98926_dapm_widgets[] = {
 120         SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0,
 121                 SND_SOC_NOPM, 0, 0),
 122         SND_SOC_DAPM_DAC("Amp Enable", NULL, MAX98926_BLOCK_ENABLE,
 123                 MAX98926_SPK_EN_SHIFT, 0),
 124         SND_SOC_DAPM_SUPPLY("Global Enable", MAX98926_GLOBAL_ENABLE,
 125                 MAX98926_EN_SHIFT, 0, NULL, 0),
 126         SND_SOC_DAPM_SUPPLY("VI Enable", MAX98926_BLOCK_ENABLE,
 127                 MAX98926_ADC_IMON_EN_WIDTH |
 128                 MAX98926_ADC_VMON_EN_SHIFT,
 129                 0, NULL, 0),
 130         SND_SOC_DAPM_PGA("BST Enable", MAX98926_BLOCK_ENABLE,
 131                 MAX98926_BST_EN_SHIFT, 0, NULL, 0),
 132         SND_SOC_DAPM_OUTPUT("BE_OUT"),
 133         SND_SOC_DAPM_MIXER("PCM Sel", MAX98926_SPK_AMP,
 134                 MAX98926_INSELECT_MODE_SHIFT, 0,
 135                 &max98926_mixer_controls[0],
 136                 ARRAY_SIZE(max98926_mixer_controls)),
 137         SND_SOC_DAPM_MIXER("DAI Sel",
 138                 MAX98926_GAIN, MAX98926_DAC_IN_SEL_SHIFT, 0,
 139                 &max98926_dai_controls[0],
 140                 ARRAY_SIZE(max98926_dai_controls)),
 141         SND_SOC_DAPM_MUX("PDM CH1 Source",
 142                 MAX98926_DAI_CLK_DIV_N_LSBS,
 143                 MAX98926_PDM_CURRENT_SHIFT,
 144                 0, &max98926_current_control),
 145         SND_SOC_DAPM_MUX("PDM CH0 Source",
 146                 MAX98926_DAI_CLK_DIV_N_LSBS,
 147                 MAX98926_PDM_VOLTAGE_SHIFT,
 148                 0, &max98926_voltage_control),
 149 };
 150 
 151 static const struct snd_soc_dapm_route max98926_audio_map[] = {
 152         {"VI Enable", NULL, "DAI_OUT"},
 153         {"DAI Sel", "Left", "VI Enable"},
 154         {"DAI Sel", "Right", "VI Enable"},
 155         {"DAI Sel", "LeftRight", "VI Enable"},
 156         {"DAI Sel", "LeftRightDiv2", "VI Enable"},
 157         {"PCM Sel", "PCM", "DAI Sel"},
 158 
 159         {"PDM CH1 Source", "Current", "DAI_OUT"},
 160         {"PDM CH1 Source", "Voltage", "DAI_OUT"},
 161         {"PDM CH0 Source", "Current", "DAI_OUT"},
 162         {"PDM CH0 Source", "Voltage", "DAI_OUT"},
 163         {"PCM Sel", "Analog", "PDM CH1 Source"},
 164         {"PCM Sel", "Analog", "PDM CH0 Source"},
 165         {"Amp Enable", NULL, "PCM Sel"},
 166 
 167         {"BST Enable", NULL, "Amp Enable"},
 168         {"BE_OUT", NULL, "BST Enable"},
 169 };
 170 
 171 static bool max98926_volatile_register(struct device *dev, unsigned int reg)
 172 {
 173         switch (reg) {
 174         case MAX98926_VBAT_DATA:
 175         case MAX98926_VBST_DATA:
 176         case MAX98926_LIVE_STATUS0:
 177         case MAX98926_LIVE_STATUS1:
 178         case MAX98926_LIVE_STATUS2:
 179         case MAX98926_STATE0:
 180         case MAX98926_STATE1:
 181         case MAX98926_STATE2:
 182         case MAX98926_FLAG0:
 183         case MAX98926_FLAG1:
 184         case MAX98926_FLAG2:
 185         case MAX98926_VERSION:
 186                 return true;
 187         default:
 188                 return false;
 189         }
 190 }
 191 
 192 static bool max98926_readable_register(struct device *dev, unsigned int reg)
 193 {
 194         switch (reg) {
 195         case MAX98926_IRQ_CLEAR0:
 196         case MAX98926_IRQ_CLEAR1:
 197         case MAX98926_IRQ_CLEAR2:
 198         case MAX98926_ALC_HOLD_RLS:
 199                 return false;
 200         default:
 201                 return true;
 202         }
 203 };
 204 
 205 static DECLARE_TLV_DB_SCALE(max98926_spk_tlv, -600, 100, 0);
 206 static DECLARE_TLV_DB_RANGE(max98926_current_tlv,
 207         0, 11, TLV_DB_SCALE_ITEM(20, 20, 0),
 208         12, 15, TLV_DB_SCALE_ITEM(320, 40, 0),
 209 );
 210 
 211 static SOC_ENUM_SINGLE_DECL(max98926_dac_hpf_cutoff,
 212                 MAX98926_FILTERS, MAX98926_DAC_HPF_SHIFT,
 213                 max98926_hpf_cutoff_txt);
 214 
 215 static SOC_ENUM_SINGLE_DECL(max98926_boost_voltage,
 216                 MAX98926_CONFIGURATION, MAX98926_BST_VOUT_SHIFT,
 217                 max98926_boost_voltage_txt);
 218 
 219 static const struct snd_kcontrol_new max98926_snd_controls[] = {
 220         SOC_SINGLE_TLV("Speaker Volume", MAX98926_GAIN,
 221                 MAX98926_SPK_GAIN_SHIFT,
 222                 (1<<MAX98926_SPK_GAIN_WIDTH)-1, 0,
 223                 max98926_spk_tlv),
 224         SOC_SINGLE("Ramp Switch", MAX98926_GAIN_RAMPING,
 225                 MAX98926_SPK_RMP_EN_SHIFT, 1, 0),
 226         SOC_SINGLE("ZCD Switch", MAX98926_GAIN_RAMPING,
 227                 MAX98926_SPK_ZCD_EN_SHIFT, 1, 0),
 228         SOC_SINGLE("ALC Switch", MAX98926_THRESHOLD,
 229                 MAX98926_ALC_EN_SHIFT, 1, 0),
 230         SOC_SINGLE("ALC Threshold", MAX98926_THRESHOLD,
 231                 MAX98926_ALC_TH_SHIFT,
 232                 (1<<MAX98926_ALC_TH_WIDTH)-1, 0),
 233         SOC_ENUM("Boost Output Voltage", max98926_boost_voltage),
 234         SOC_SINGLE_TLV("Boost Current Limit", MAX98926_BOOST_LIMITER,
 235                 MAX98926_BST_ILIM_SHIFT,
 236                 (1<<MAX98926_BST_ILIM_SHIFT)-1, 0,
 237                 max98926_current_tlv),
 238         SOC_ENUM("DAC HPF Cutoff", max98926_dac_hpf_cutoff),
 239         SOC_DOUBLE("PDM Channel One", MAX98926_DAI_CLK_DIV_N_LSBS,
 240                 MAX98926_PDM_CHANNEL_1_SHIFT,
 241                 MAX98926_PDM_CHANNEL_1_HIZ, 1, 0),
 242         SOC_DOUBLE("PDM Channel Zero", MAX98926_DAI_CLK_DIV_N_LSBS,
 243                 MAX98926_PDM_CHANNEL_0_SHIFT,
 244                 MAX98926_PDM_CHANNEL_0_HIZ, 1, 0),
 245 };
 246 
 247 static const struct {
 248         int rate;
 249         int  sr;
 250 } rate_table[] = {
 251         {
 252                 .rate = 8000,
 253                 .sr = 0,
 254         },
 255         {
 256                 .rate = 11025,
 257                 .sr = 1,
 258         },
 259         {
 260                 .rate = 12000,
 261                 .sr = 2,
 262         },
 263         {
 264                 .rate = 16000,
 265                 .sr = 3,
 266         },
 267         {
 268                 .rate = 22050,
 269                 .sr = 4,
 270         },
 271         {
 272                 .rate = 24000,
 273                 .sr = 5,
 274         },
 275         {
 276                 .rate = 32000,
 277                 .sr = 6,
 278         },
 279         {
 280                 .rate = 44100,
 281                 .sr = 7,
 282         },
 283         {
 284                 .rate = 48000,
 285                 .sr = 8,
 286         },
 287 };
 288 
 289 static void max98926_set_sense_data(struct max98926_priv *max98926)
 290 {
 291         regmap_update_bits(max98926->regmap,
 292                 MAX98926_DOUT_CFG_VMON,
 293                 MAX98926_DAI_VMON_EN_MASK,
 294                 MAX98926_DAI_VMON_EN_MASK);
 295         regmap_update_bits(max98926->regmap,
 296                 MAX98926_DOUT_CFG_IMON,
 297                 MAX98926_DAI_IMON_EN_MASK,
 298                 MAX98926_DAI_IMON_EN_MASK);
 299 
 300         if (!max98926->interleave_mode) {
 301                 /* set VMON slots */
 302                 regmap_update_bits(max98926->regmap,
 303                         MAX98926_DOUT_CFG_VMON,
 304                         MAX98926_DAI_VMON_SLOT_MASK,
 305                         max98926->v_slot);
 306                 /* set IMON slots */
 307                 regmap_update_bits(max98926->regmap,
 308                         MAX98926_DOUT_CFG_IMON,
 309                         MAX98926_DAI_IMON_SLOT_MASK,
 310                         max98926->i_slot);
 311         } else {
 312                 /* enable interleave mode */
 313                 regmap_update_bits(max98926->regmap,
 314                         MAX98926_FORMAT,
 315                         MAX98926_DAI_INTERLEAVE_MASK,
 316                         MAX98926_DAI_INTERLEAVE_MASK);
 317                 /* set interleave slots */
 318                 regmap_update_bits(max98926->regmap,
 319                         MAX98926_DOUT_CFG_VBAT,
 320                         MAX98926_DAI_INTERLEAVE_SLOT_MASK,
 321                         max98926->v_slot);
 322         }
 323 }
 324 
 325 static int max98926_dai_set_fmt(struct snd_soc_dai *codec_dai,
 326                 unsigned int fmt)
 327 {
 328         struct snd_soc_component *component = codec_dai->component;
 329         struct max98926_priv *max98926 = snd_soc_component_get_drvdata(component);
 330         unsigned int invert = 0;
 331 
 332         dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
 333 
 334         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 335         case SND_SOC_DAIFMT_CBS_CFS:
 336                 max98926_set_sense_data(max98926);
 337                 break;
 338         default:
 339                 dev_err(component->dev, "DAI clock mode unsupported\n");
 340                 return -EINVAL;
 341         }
 342 
 343         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 344         case SND_SOC_DAIFMT_NB_NF:
 345                 break;
 346         case SND_SOC_DAIFMT_NB_IF:
 347                 invert = MAX98926_DAI_WCI_MASK;
 348                 break;
 349         case SND_SOC_DAIFMT_IB_NF:
 350                 invert = MAX98926_DAI_BCI_MASK;
 351                 break;
 352         case SND_SOC_DAIFMT_IB_IF:
 353                 invert = MAX98926_DAI_BCI_MASK | MAX98926_DAI_WCI_MASK;
 354                 break;
 355         default:
 356                 dev_err(component->dev, "DAI invert mode unsupported\n");
 357                 return -EINVAL;
 358         }
 359 
 360         regmap_write(max98926->regmap,
 361                         MAX98926_FORMAT, MAX98926_DAI_DLY_MASK);
 362         regmap_update_bits(max98926->regmap, MAX98926_FORMAT,
 363                         MAX98926_DAI_BCI_MASK, invert);
 364         return 0;
 365 }
 366 
 367 static int max98926_dai_hw_params(struct snd_pcm_substream *substream,
 368                 struct snd_pcm_hw_params *params,
 369                 struct snd_soc_dai *dai)
 370 {
 371         int dai_sr = -EINVAL;
 372         int rate = params_rate(params), i;
 373         struct snd_soc_component *component = dai->component;
 374         struct max98926_priv *max98926 = snd_soc_component_get_drvdata(component);
 375         int blr_clk_ratio;
 376 
 377         switch (params_format(params)) {
 378         case SNDRV_PCM_FORMAT_S16_LE:
 379                 regmap_update_bits(max98926->regmap,
 380                         MAX98926_FORMAT,
 381                         MAX98926_DAI_CHANSZ_MASK,
 382                         MAX98926_DAI_CHANSZ_16);
 383                 max98926->ch_size = 16;
 384                 break;
 385         case SNDRV_PCM_FORMAT_S24_LE:
 386                 regmap_update_bits(max98926->regmap,
 387                         MAX98926_FORMAT,
 388                         MAX98926_DAI_CHANSZ_MASK,
 389                         MAX98926_DAI_CHANSZ_24);
 390                 max98926->ch_size = 24;
 391                 break;
 392         case SNDRV_PCM_FORMAT_S32_LE:
 393                 regmap_update_bits(max98926->regmap,
 394                         MAX98926_FORMAT,
 395                         MAX98926_DAI_CHANSZ_MASK,
 396                         MAX98926_DAI_CHANSZ_32);
 397                 max98926->ch_size = 32;
 398                 break;
 399         default:
 400                 dev_dbg(component->dev, "format unsupported %d\n",
 401                         params_format(params));
 402                 return -EINVAL;
 403         }
 404 
 405         /* BCLK/LRCLK ratio calculation */
 406         blr_clk_ratio = params_channels(params) * max98926->ch_size;
 407 
 408         switch (blr_clk_ratio) {
 409         case 32:
 410                 regmap_update_bits(max98926->regmap,
 411                         MAX98926_DAI_CLK_MODE2,
 412                         MAX98926_DAI_BSEL_MASK,
 413                         MAX98926_DAI_BSEL_32);
 414                 break;
 415         case 48:
 416                 regmap_update_bits(max98926->regmap,
 417                         MAX98926_DAI_CLK_MODE2,
 418                         MAX98926_DAI_BSEL_MASK,
 419                         MAX98926_DAI_BSEL_48);
 420                 break;
 421         case 64:
 422                 regmap_update_bits(max98926->regmap,
 423                         MAX98926_DAI_CLK_MODE2,
 424                         MAX98926_DAI_BSEL_MASK,
 425                         MAX98926_DAI_BSEL_64);
 426                 break;
 427         default:
 428                 return -EINVAL;
 429         }
 430 
 431         /* find the closest rate */
 432         for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
 433                 if (rate_table[i].rate >= rate) {
 434                         dai_sr = rate_table[i].sr;
 435                         break;
 436                 }
 437         }
 438         if (dai_sr < 0)
 439                 return -EINVAL;
 440 
 441         /* set DAI_SR to correct LRCLK frequency */
 442         regmap_update_bits(max98926->regmap,
 443                 MAX98926_DAI_CLK_MODE2,
 444                 MAX98926_DAI_SR_MASK, dai_sr << MAX98926_DAI_SR_SHIFT);
 445         return 0;
 446 }
 447 
 448 #define MAX98926_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
 449                 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 450 
 451 static const struct snd_soc_dai_ops max98926_dai_ops = {
 452         .set_fmt = max98926_dai_set_fmt,
 453         .hw_params = max98926_dai_hw_params,
 454 };
 455 
 456 static struct snd_soc_dai_driver max98926_dai[] = {
 457 {
 458         .name = "max98926-aif1",
 459         .playback = {
 460                 .stream_name = "HiFi Playback",
 461                 .channels_min = 1,
 462                 .channels_max = 2,
 463                 .rates = SNDRV_PCM_RATE_8000_48000,
 464                 .formats = MAX98926_FORMATS,
 465         },
 466         .capture = {
 467                 .stream_name = "HiFi Capture",
 468                 .channels_min = 1,
 469                 .channels_max = 2,
 470                 .rates = SNDRV_PCM_RATE_8000_48000,
 471                 .formats = MAX98926_FORMATS,
 472         },
 473         .ops = &max98926_dai_ops,
 474 }
 475 };
 476 
 477 static int max98926_probe(struct snd_soc_component *component)
 478 {
 479         struct max98926_priv *max98926 = snd_soc_component_get_drvdata(component);
 480 
 481         max98926->component = component;
 482 
 483         /* Hi-Z all the slots */
 484         regmap_write(max98926->regmap, MAX98926_DOUT_HIZ_CFG4, 0xF0);
 485         return 0;
 486 }
 487 
 488 static const struct snd_soc_component_driver soc_component_dev_max98926 = {
 489         .probe                  = max98926_probe,
 490         .controls               = max98926_snd_controls,
 491         .num_controls           = ARRAY_SIZE(max98926_snd_controls),
 492         .dapm_routes            = max98926_audio_map,
 493         .num_dapm_routes        = ARRAY_SIZE(max98926_audio_map),
 494         .dapm_widgets           = max98926_dapm_widgets,
 495         .num_dapm_widgets       = ARRAY_SIZE(max98926_dapm_widgets),
 496         .idle_bias_on           = 1,
 497         .use_pmdown_time        = 1,
 498         .endianness             = 1,
 499         .non_legacy_dai_naming  = 1,
 500 };
 501 
 502 static const struct regmap_config max98926_regmap = {
 503         .reg_bits       = 8,
 504         .val_bits       = 8,
 505         .max_register   = MAX98926_VERSION,
 506         .reg_defaults   = max98926_reg,
 507         .num_reg_defaults = ARRAY_SIZE(max98926_reg),
 508         .volatile_reg   = max98926_volatile_register,
 509         .readable_reg   = max98926_readable_register,
 510         .cache_type             = REGCACHE_RBTREE,
 511 };
 512 
 513 static int max98926_i2c_probe(struct i2c_client *i2c,
 514                 const struct i2c_device_id *id)
 515 {
 516         int ret, reg;
 517         u32 value;
 518         struct max98926_priv *max98926;
 519 
 520         max98926 = devm_kzalloc(&i2c->dev,
 521                         sizeof(*max98926), GFP_KERNEL);
 522         if (!max98926)
 523                 return -ENOMEM;
 524 
 525         i2c_set_clientdata(i2c, max98926);
 526         max98926->regmap = devm_regmap_init_i2c(i2c, &max98926_regmap);
 527         if (IS_ERR(max98926->regmap)) {
 528                 ret = PTR_ERR(max98926->regmap);
 529                 dev_err(&i2c->dev,
 530                                 "Failed to allocate regmap: %d\n", ret);
 531                 goto err_out;
 532         }
 533         if (of_property_read_bool(i2c->dev.of_node, "interleave-mode"))
 534                 max98926->interleave_mode = true;
 535 
 536         if (!of_property_read_u32(i2c->dev.of_node, "vmon-slot-no", &value)) {
 537                 if (value > MAX98926_DAI_VMON_SLOT_1E_1F) {
 538                         dev_err(&i2c->dev, "vmon slot number is wrong:\n");
 539                         return -EINVAL;
 540                 }
 541                 max98926->v_slot = value;
 542         }
 543         if (!of_property_read_u32(i2c->dev.of_node, "imon-slot-no", &value)) {
 544                 if (value > MAX98926_DAI_IMON_SLOT_1E_1F) {
 545                         dev_err(&i2c->dev, "imon slot number is wrong:\n");
 546                         return -EINVAL;
 547                 }
 548                 max98926->i_slot = value;
 549         }
 550         ret = regmap_read(max98926->regmap,
 551                         MAX98926_VERSION, &reg);
 552         if (ret < 0) {
 553                 dev_err(&i2c->dev, "Failed to read: %x\n", reg);
 554                 return ret;
 555         }
 556 
 557         ret = devm_snd_soc_register_component(&i2c->dev,
 558                         &soc_component_dev_max98926,
 559                         max98926_dai, ARRAY_SIZE(max98926_dai));
 560         if (ret < 0)
 561                 dev_err(&i2c->dev,
 562                                 "Failed to register component: %d\n", ret);
 563         dev_info(&i2c->dev, "device version: %x\n", reg);
 564 err_out:
 565         return ret;
 566 }
 567 
 568 static const struct i2c_device_id max98926_i2c_id[] = {
 569         { "max98926", 0 },
 570         { }
 571 };
 572 MODULE_DEVICE_TABLE(i2c, max98926_i2c_id);
 573 
 574 static const struct of_device_id max98926_of_match[] = {
 575         { .compatible = "maxim,max98926", },
 576         { }
 577 };
 578 MODULE_DEVICE_TABLE(of, max98926_of_match);
 579 
 580 static struct i2c_driver max98926_i2c_driver = {
 581         .driver = {
 582                 .name = "max98926",
 583                 .of_match_table = of_match_ptr(max98926_of_match),
 584                 .pm = NULL,
 585         },
 586         .probe  = max98926_i2c_probe,
 587         .id_table = max98926_i2c_id,
 588 };
 589 
 590 module_i2c_driver(max98926_i2c_driver)
 591 MODULE_DESCRIPTION("ALSA SoC MAX98926 driver");
 592 MODULE_AUTHOR("Anish kumar <anish.kumar@maximintegrated.com>");
 593 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */