0001
0002
0003
0004
0005
0006 #include <linux/module.h>
0007 #include <linux/moduleparam.h>
0008 #include <linux/init.h>
0009 #include <linux/delay.h>
0010 #include <linux/pm.h>
0011 #include <linux/i2c.h>
0012 #include <linux/slab.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/regmap.h>
0015 #include <sound/core.h>
0016 #include <sound/pcm.h>
0017 #include <sound/pcm_params.h>
0018 #include <sound/soc.h>
0019 #include <sound/tlv.h>
0020 #include "ml26124.h"
0021
0022 #define DVOL_CTL_DVMUTE_ON BIT(4)
0023 #define DVOL_CTL_DVMUTE_OFF 0
0024 #define ML26124_SAI_NO_DELAY BIT(1)
0025 #define ML26124_SAI_FRAME_SYNC (BIT(5) | BIT(0))
0026 #define ML26134_CACHESIZE 212
0027 #define ML26124_VMID BIT(1)
0028 #define ML26124_RATES (SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_32000 |\
0029 SNDRV_PCM_RATE_48000)
0030 #define ML26124_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |\
0031 SNDRV_PCM_FMTBIT_S32_LE)
0032 #define ML26124_NUM_REGISTER ML26134_CACHESIZE
0033
0034 struct ml26124_priv {
0035 u32 mclk;
0036 u32 rate;
0037 struct regmap *regmap;
0038 int clk_in;
0039 struct snd_pcm_substream *substream;
0040 };
0041
0042 struct clk_coeff {
0043 u32 mclk;
0044 u32 rate;
0045 u8 pllnl;
0046 u8 pllnh;
0047 u8 pllml;
0048 u8 pllmh;
0049 u8 plldiv;
0050 };
0051
0052
0053 static const DECLARE_TLV_DB_SCALE(digital_tlv, -7150, 50, 0);
0054
0055 static const DECLARE_TLV_DB_SCALE(alclvl, -2250, 150, 0);
0056 static const DECLARE_TLV_DB_SCALE(mingain, -1200, 600, 0);
0057 static const DECLARE_TLV_DB_SCALE(maxgain, -675, 600, 0);
0058 static const DECLARE_TLV_DB_SCALE(boost_vol, -1200, 75, 0);
0059
0060 static const char * const ml26124_companding[] = {"16bit PCM", "u-law",
0061 "A-law"};
0062
0063 static SOC_ENUM_SINGLE_DECL(ml26124_adc_companding_enum,
0064 ML26124_SAI_TRANS_CTL, 6, ml26124_companding);
0065
0066 static SOC_ENUM_SINGLE_DECL(ml26124_dac_companding_enum,
0067 ML26124_SAI_RCV_CTL, 6, ml26124_companding);
0068
0069 static const struct snd_kcontrol_new ml26124_snd_controls[] = {
0070 SOC_SINGLE_TLV("Capture Digital Volume", ML26124_RECORD_DIG_VOL, 0,
0071 0xff, 1, digital_tlv),
0072 SOC_SINGLE_TLV("Playback Digital Volume", ML26124_PLBAK_DIG_VOL, 0,
0073 0xff, 1, digital_tlv),
0074 SOC_SINGLE_TLV("Digital Boost Volume", ML26124_DIGI_BOOST_VOL, 0,
0075 0x3f, 0, boost_vol),
0076 SOC_SINGLE_TLV("EQ Band0 Volume", ML26124_EQ_GAIN_BRAND0, 0,
0077 0xff, 1, digital_tlv),
0078 SOC_SINGLE_TLV("EQ Band1 Volume", ML26124_EQ_GAIN_BRAND1, 0,
0079 0xff, 1, digital_tlv),
0080 SOC_SINGLE_TLV("EQ Band2 Volume", ML26124_EQ_GAIN_BRAND2, 0,
0081 0xff, 1, digital_tlv),
0082 SOC_SINGLE_TLV("EQ Band3 Volume", ML26124_EQ_GAIN_BRAND3, 0,
0083 0xff, 1, digital_tlv),
0084 SOC_SINGLE_TLV("EQ Band4 Volume", ML26124_EQ_GAIN_BRAND4, 0,
0085 0xff, 1, digital_tlv),
0086 SOC_SINGLE_TLV("ALC Target Level", ML26124_ALC_TARGET_LEV, 0,
0087 0xf, 1, alclvl),
0088 SOC_SINGLE_TLV("ALC Min Input Volume", ML26124_ALC_MAXMIN_GAIN, 0,
0089 7, 0, mingain),
0090 SOC_SINGLE_TLV("ALC Max Input Volume", ML26124_ALC_MAXMIN_GAIN, 4,
0091 7, 1, maxgain),
0092 SOC_SINGLE_TLV("Playback Limiter Min Input Volume",
0093 ML26124_PL_MAXMIN_GAIN, 0, 7, 0, mingain),
0094 SOC_SINGLE_TLV("Playback Limiter Max Input Volume",
0095 ML26124_PL_MAXMIN_GAIN, 4, 7, 1, maxgain),
0096 SOC_SINGLE_TLV("Playback Boost Volume", ML26124_PLYBAK_BOST_VOL, 0,
0097 0x3f, 0, boost_vol),
0098 SOC_SINGLE("DC High Pass Filter Switch", ML26124_FILTER_EN, 0, 1, 0),
0099 SOC_SINGLE("Noise High Pass Filter Switch", ML26124_FILTER_EN, 1, 1, 0),
0100 SOC_SINGLE("ZC Switch", ML26124_PW_ZCCMP_PW_MNG, 1,
0101 1, 0),
0102 SOC_SINGLE("EQ Band0 Switch", ML26124_FILTER_EN, 2, 1, 0),
0103 SOC_SINGLE("EQ Band1 Switch", ML26124_FILTER_EN, 3, 1, 0),
0104 SOC_SINGLE("EQ Band2 Switch", ML26124_FILTER_EN, 4, 1, 0),
0105 SOC_SINGLE("EQ Band3 Switch", ML26124_FILTER_EN, 5, 1, 0),
0106 SOC_SINGLE("EQ Band4 Switch", ML26124_FILTER_EN, 6, 1, 0),
0107 SOC_SINGLE("Play Limiter", ML26124_DVOL_CTL, 0, 1, 0),
0108 SOC_SINGLE("Capture Limiter", ML26124_DVOL_CTL, 1, 1, 0),
0109 SOC_SINGLE("Digital Volume Fade Switch", ML26124_DVOL_CTL, 3, 1, 0),
0110 SOC_SINGLE("Digital Switch", ML26124_DVOL_CTL, 4, 1, 0),
0111 SOC_ENUM("DAC Companding", ml26124_dac_companding_enum),
0112 SOC_ENUM("ADC Companding", ml26124_adc_companding_enum),
0113 };
0114
0115 static const struct snd_kcontrol_new ml26124_output_mixer_controls[] = {
0116 SOC_DAPM_SINGLE("DAC Switch", ML26124_SPK_AMP_OUT, 1, 1, 0),
0117 SOC_DAPM_SINGLE("Line in loopback Switch", ML26124_SPK_AMP_OUT, 3, 1,
0118 0),
0119 SOC_DAPM_SINGLE("PGA Switch", ML26124_SPK_AMP_OUT, 5, 1, 0),
0120 };
0121
0122
0123 static const char * const ml26124_input_select[] = {"Analog MIC SingleEnded in",
0124 "Digital MIC in", "Analog MIC Differential in"};
0125
0126 static SOC_ENUM_SINGLE_DECL(ml26124_insel_enum,
0127 ML26124_MIC_IF_CTL, 0, ml26124_input_select);
0128
0129 static const struct snd_kcontrol_new ml26124_input_mux_controls =
0130 SOC_DAPM_ENUM("Input Select", ml26124_insel_enum);
0131
0132 static const struct snd_kcontrol_new ml26124_line_control =
0133 SOC_DAPM_SINGLE("Switch", ML26124_PW_LOUT_PW_MNG, 1, 1, 0);
0134
0135 static const struct snd_soc_dapm_widget ml26124_dapm_widgets[] = {
0136 SND_SOC_DAPM_SUPPLY("MCLKEN", ML26124_CLK_EN, 0, 0, NULL, 0),
0137 SND_SOC_DAPM_SUPPLY("PLLEN", ML26124_CLK_EN, 1, 0, NULL, 0),
0138 SND_SOC_DAPM_SUPPLY("PLLOE", ML26124_CLK_EN, 2, 0, NULL, 0),
0139 SND_SOC_DAPM_SUPPLY("MICBIAS", ML26124_PW_REF_PW_MNG, 2, 0, NULL, 0),
0140 SND_SOC_DAPM_MIXER("Output Mixer", SND_SOC_NOPM, 0, 0,
0141 &ml26124_output_mixer_controls[0],
0142 ARRAY_SIZE(ml26124_output_mixer_controls)),
0143 SND_SOC_DAPM_DAC("DAC", "Playback", ML26124_PW_DAC_PW_MNG, 1, 0),
0144 SND_SOC_DAPM_ADC("ADC", "Capture", ML26124_PW_IN_PW_MNG, 1, 0),
0145 SND_SOC_DAPM_PGA("PGA", ML26124_PW_IN_PW_MNG, 3, 0, NULL, 0),
0146 SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
0147 &ml26124_input_mux_controls),
0148 SND_SOC_DAPM_SWITCH("Line Out Enable", SND_SOC_NOPM, 0, 0,
0149 &ml26124_line_control),
0150 SND_SOC_DAPM_INPUT("MDIN"),
0151 SND_SOC_DAPM_INPUT("MIN"),
0152 SND_SOC_DAPM_INPUT("LIN"),
0153 SND_SOC_DAPM_OUTPUT("SPOUT"),
0154 SND_SOC_DAPM_OUTPUT("LOUT"),
0155 };
0156
0157 static const struct snd_soc_dapm_route ml26124_intercon[] = {
0158
0159 {"DAC", NULL, "MCLKEN"},
0160 {"ADC", NULL, "MCLKEN"},
0161 {"DAC", NULL, "PLLEN"},
0162 {"ADC", NULL, "PLLEN"},
0163 {"DAC", NULL, "PLLOE"},
0164 {"ADC", NULL, "PLLOE"},
0165
0166
0167 {"Output Mixer", "DAC Switch", "DAC"},
0168 {"Output Mixer", "Line in loopback Switch", "LIN"},
0169
0170
0171 {"LOUT", NULL, "Output Mixer"},
0172 {"SPOUT", NULL, "Output Mixer"},
0173 {"Line Out Enable", NULL, "LOUT"},
0174
0175
0176 {"ADC", NULL, "Input Mux"},
0177 {"Input Mux", "Analog MIC SingleEnded in", "PGA"},
0178 {"Input Mux", "Analog MIC Differential in", "PGA"},
0179 {"PGA", NULL, "MIN"},
0180 };
0181
0182
0183 static const struct clk_coeff coeff_div[] = {
0184 {12288000, 16000, 0xc, 0x0, 0x20, 0x0, 0x4},
0185 {12288000, 32000, 0xc, 0x0, 0x20, 0x0, 0x4},
0186 {12288000, 48000, 0xc, 0x0, 0x30, 0x0, 0x4},
0187 };
0188
0189 static const struct reg_default ml26124_reg[] = {
0190
0191 {0x00, 0x00 },
0192 {0x02, 0x00},
0193 {0x04, 0x00},
0194 {0x06, 0x00},
0195 {0x08, 0x00},
0196 {0x0a, 0x00},
0197 {0x0c, 0x00},
0198 {0x0e, 0x00},
0199
0200
0201 {0x10, 0x00},
0202 {0x12, 0x00},
0203 {0x14, 0x00},
0204
0205
0206 {0x20, 0x00},
0207 {0x22, 0x00},
0208 {0x24, 0x00},
0209 {0x26, 0x00},
0210 {0x28, 0x00},
0211 {0x2a, 0x00},
0212 {0x2e, 0x00},
0213
0214
0215 {0x30, 0x04},
0216
0217
0218 {0x32, 0x10},
0219 {0x38, 0x00},
0220 {0x3a, 0x33},
0221 {0x48, 0x00},
0222 {0x4a, 0x00},
0223
0224
0225 {0x54, 0x00},
0226 {0x5a, 0x00},
0227 {0xe8, 0x01},
0228
0229
0230 {0x60, 0x00},
0231 {0x62, 0x00},
0232 {0x64, 0x00},
0233
0234
0235 {0x66, 0x01},
0236 {0x68, 0x00},
0237 {0x6A, 0x00},
0238 {0x6C, 0xff},
0239 {0x70, 0xff},
0240 {0x72, 0x10},
0241 {0x74, 0xe7},
0242 {0x76, 0xe7},
0243 {0x78, 0xe7},
0244 {0x7A, 0xe7},
0245 {0x7C, 0xe7},
0246 {0x7E, 0x00},
0247 {0x80, 0x00},
0248 {0x82, 0x00},
0249 {0x84, 0x00},
0250 {0x86, 0x00},
0251 {0x88, 0x00},
0252 {0x8A, 0x00},
0253 {0x8C, 0x00},
0254 {0x8E, 0x00},
0255 {0x90, 0x00},
0256 {0x92, 0x00},
0257 {0x94, 0x00},
0258 {0x96, 0x00},
0259 {0x98, 0x00},
0260 {0x9A, 0x00},
0261 {0x9C, 0x00},
0262 {0x9E, 0x00},
0263 {0xA0, 0x00},
0264 {0xA2, 0x00},
0265 {0xA4, 0x00},
0266 {0xA6, 0x00},
0267
0268
0269 {0xb0, 0x00},
0270 {0xb2, 0x02},
0271 {0xb4, 0x03},
0272 {0xb6, 0x00},
0273 {0xb8, 0x0b},
0274 {0xba, 0x70},
0275 {0xbc, 0x00},
0276 {0xbe, 0x00},
0277
0278
0279 {0xc0, 0x04},
0280 {0xc2, 0x05},
0281 {0xc4, 0x0d},
0282 {0xc6, 0x70},
0283 {0xc8, 0x10},
0284 {0xca, 0x00},
0285
0286
0287 {0xd0, 0x01},
0288 {0xd2, 0x01},
0289 {0xd4, 0x01},
0290 };
0291
0292
0293 static inline int get_srate(int rate)
0294 {
0295 int srate;
0296
0297 switch (rate) {
0298 case 16000:
0299 srate = 3;
0300 break;
0301 case 32000:
0302 srate = 6;
0303 break;
0304 case 48000:
0305 srate = 8;
0306 break;
0307 default:
0308 return -EINVAL;
0309 }
0310 return srate;
0311 }
0312
0313 static inline int get_coeff(int mclk, int rate)
0314 {
0315 int i;
0316
0317 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
0318 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
0319 return i;
0320 }
0321 return -EINVAL;
0322 }
0323
0324 static int ml26124_hw_params(struct snd_pcm_substream *substream,
0325 struct snd_pcm_hw_params *hw_params,
0326 struct snd_soc_dai *dai)
0327 {
0328 struct snd_soc_component *component = dai->component;
0329 struct ml26124_priv *priv = snd_soc_component_get_drvdata(component);
0330 int i = get_coeff(priv->mclk, params_rate(hw_params));
0331 int srate;
0332
0333 if (i < 0)
0334 return i;
0335 priv->substream = substream;
0336 priv->rate = params_rate(hw_params);
0337
0338 if (priv->clk_in) {
0339 switch (priv->mclk / params_rate(hw_params)) {
0340 case 256:
0341 snd_soc_component_update_bits(component, ML26124_CLK_CTL,
0342 BIT(0) | BIT(1), 1);
0343 break;
0344 case 512:
0345 snd_soc_component_update_bits(component, ML26124_CLK_CTL,
0346 BIT(0) | BIT(1), 2);
0347 break;
0348 case 1024:
0349 snd_soc_component_update_bits(component, ML26124_CLK_CTL,
0350 BIT(0) | BIT(1), 3);
0351 break;
0352 default:
0353 dev_err(component->dev, "Unsupported MCLKI\n");
0354 break;
0355 }
0356 } else {
0357 snd_soc_component_update_bits(component, ML26124_CLK_CTL,
0358 BIT(0) | BIT(1), 0);
0359 }
0360
0361 srate = get_srate(params_rate(hw_params));
0362 if (srate < 0)
0363 return srate;
0364
0365 snd_soc_component_update_bits(component, ML26124_SMPLING_RATE, 0xf, srate);
0366 snd_soc_component_update_bits(component, ML26124_PLLNL, 0xff, coeff_div[i].pllnl);
0367 snd_soc_component_update_bits(component, ML26124_PLLNH, 0x1, coeff_div[i].pllnh);
0368 snd_soc_component_update_bits(component, ML26124_PLLML, 0xff, coeff_div[i].pllml);
0369 snd_soc_component_update_bits(component, ML26124_PLLMH, 0x3f, coeff_div[i].pllmh);
0370 snd_soc_component_update_bits(component, ML26124_PLLDIV, 0x1f, coeff_div[i].plldiv);
0371
0372 return 0;
0373 }
0374
0375 static int ml26124_mute(struct snd_soc_dai *dai, int mute, int direction)
0376 {
0377 struct snd_soc_component *component = dai->component;
0378 struct ml26124_priv *priv = snd_soc_component_get_drvdata(component);
0379
0380 switch (priv->substream->stream) {
0381 case SNDRV_PCM_STREAM_CAPTURE:
0382 snd_soc_component_update_bits(component, ML26124_REC_PLYBAK_RUN, BIT(0), 1);
0383 break;
0384 case SNDRV_PCM_STREAM_PLAYBACK:
0385 snd_soc_component_update_bits(component, ML26124_REC_PLYBAK_RUN, BIT(1), 2);
0386 break;
0387 }
0388
0389 if (mute)
0390 snd_soc_component_update_bits(component, ML26124_DVOL_CTL, BIT(4),
0391 DVOL_CTL_DVMUTE_ON);
0392 else
0393 snd_soc_component_update_bits(component, ML26124_DVOL_CTL, BIT(4),
0394 DVOL_CTL_DVMUTE_OFF);
0395
0396 return 0;
0397 }
0398
0399 static int ml26124_set_dai_fmt(struct snd_soc_dai *codec_dai,
0400 unsigned int fmt)
0401 {
0402 unsigned char mode;
0403 struct snd_soc_component *component = codec_dai->component;
0404
0405 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0406 case SND_SOC_DAIFMT_CBP_CFP:
0407 mode = 1;
0408 break;
0409 case SND_SOC_DAIFMT_CBC_CFC:
0410 mode = 0;
0411 break;
0412 default:
0413 return -EINVAL;
0414 }
0415 snd_soc_component_update_bits(component, ML26124_SAI_MODE_SEL, BIT(0), mode);
0416
0417
0418 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0419 case SND_SOC_DAIFMT_I2S:
0420 break;
0421 default:
0422 return -EINVAL;
0423 }
0424
0425
0426 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0427 case SND_SOC_DAIFMT_NB_NF:
0428 break;
0429 default:
0430 return -EINVAL;
0431 }
0432
0433 return 0;
0434 }
0435
0436 static int ml26124_set_dai_sysclk(struct snd_soc_dai *codec_dai,
0437 int clk_id, unsigned int freq, int dir)
0438 {
0439 struct snd_soc_component *component = codec_dai->component;
0440 struct ml26124_priv *priv = snd_soc_component_get_drvdata(component);
0441
0442 switch (clk_id) {
0443 case ML26124_USE_PLLOUT:
0444 priv->clk_in = ML26124_USE_PLLOUT;
0445 break;
0446 case ML26124_USE_MCLKI:
0447 priv->clk_in = ML26124_USE_MCLKI;
0448 break;
0449 default:
0450 return -EINVAL;
0451 }
0452
0453 priv->mclk = freq;
0454
0455 return 0;
0456 }
0457
0458 static int ml26124_set_bias_level(struct snd_soc_component *component,
0459 enum snd_soc_bias_level level)
0460 {
0461 struct ml26124_priv *priv = snd_soc_component_get_drvdata(component);
0462
0463 switch (level) {
0464 case SND_SOC_BIAS_ON:
0465 snd_soc_component_update_bits(component, ML26124_PW_SPAMP_PW_MNG,
0466 ML26124_R26_MASK, ML26124_BLT_PREAMP_ON);
0467 msleep(100);
0468 snd_soc_component_update_bits(component, ML26124_PW_SPAMP_PW_MNG,
0469 ML26124_R26_MASK,
0470 ML26124_MICBEN_ON | ML26124_BLT_ALL_ON);
0471 break;
0472 case SND_SOC_BIAS_PREPARE:
0473 break;
0474 case SND_SOC_BIAS_STANDBY:
0475
0476 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
0477 snd_soc_component_update_bits(component, ML26124_PW_REF_PW_MNG,
0478 ML26124_VMID, ML26124_VMID);
0479 msleep(500);
0480 regcache_sync(priv->regmap);
0481 }
0482 break;
0483 case SND_SOC_BIAS_OFF:
0484
0485 snd_soc_component_update_bits(component, ML26124_PW_REF_PW_MNG,
0486 ML26124_VMID, 0);
0487 break;
0488 }
0489 return 0;
0490 }
0491
0492 static const struct snd_soc_dai_ops ml26124_dai_ops = {
0493 .hw_params = ml26124_hw_params,
0494 .mute_stream = ml26124_mute,
0495 .set_fmt = ml26124_set_dai_fmt,
0496 .set_sysclk = ml26124_set_dai_sysclk,
0497 .no_capture_mute = 1,
0498 };
0499
0500 static struct snd_soc_dai_driver ml26124_dai = {
0501 .name = "ml26124-hifi",
0502 .playback = {
0503 .stream_name = "Playback",
0504 .channels_min = 1,
0505 .channels_max = 2,
0506 .rates = ML26124_RATES,
0507 .formats = ML26124_FORMATS,},
0508 .capture = {
0509 .stream_name = "Capture",
0510 .channels_min = 1,
0511 .channels_max = 2,
0512 .rates = ML26124_RATES,
0513 .formats = ML26124_FORMATS,},
0514 .ops = &ml26124_dai_ops,
0515 .symmetric_rate = 1,
0516 };
0517
0518 static int ml26124_probe(struct snd_soc_component *component)
0519 {
0520
0521 snd_soc_component_update_bits(component, ML26124_SW_RST, 0x01, 1);
0522 snd_soc_component_update_bits(component, ML26124_SW_RST, 0x01, 0);
0523
0524 return 0;
0525 }
0526
0527 static const struct snd_soc_component_driver soc_component_dev_ml26124 = {
0528 .probe = ml26124_probe,
0529 .set_bias_level = ml26124_set_bias_level,
0530 .controls = ml26124_snd_controls,
0531 .num_controls = ARRAY_SIZE(ml26124_snd_controls),
0532 .dapm_widgets = ml26124_dapm_widgets,
0533 .num_dapm_widgets = ARRAY_SIZE(ml26124_dapm_widgets),
0534 .dapm_routes = ml26124_intercon,
0535 .num_dapm_routes = ARRAY_SIZE(ml26124_intercon),
0536 .suspend_bias_off = 1,
0537 .idle_bias_on = 1,
0538 .use_pmdown_time = 1,
0539 .endianness = 1,
0540 };
0541
0542 static const struct regmap_config ml26124_i2c_regmap = {
0543 .val_bits = 8,
0544 .reg_bits = 8,
0545 .max_register = ML26124_NUM_REGISTER,
0546 .reg_defaults = ml26124_reg,
0547 .num_reg_defaults = ARRAY_SIZE(ml26124_reg),
0548 .cache_type = REGCACHE_RBTREE,
0549 .write_flag_mask = 0x01,
0550 };
0551
0552 static int ml26124_i2c_probe(struct i2c_client *i2c)
0553 {
0554 struct ml26124_priv *priv;
0555 int ret;
0556
0557 priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
0558 if (!priv)
0559 return -ENOMEM;
0560
0561 i2c_set_clientdata(i2c, priv);
0562
0563 priv->regmap = devm_regmap_init_i2c(i2c, &ml26124_i2c_regmap);
0564 if (IS_ERR(priv->regmap)) {
0565 ret = PTR_ERR(priv->regmap);
0566 dev_err(&i2c->dev, "regmap_init_i2c() failed: %d\n", ret);
0567 return ret;
0568 }
0569
0570 return devm_snd_soc_register_component(&i2c->dev,
0571 &soc_component_dev_ml26124, &ml26124_dai, 1);
0572 }
0573
0574 static const struct i2c_device_id ml26124_i2c_id[] = {
0575 { "ml26124", 0 },
0576 { }
0577 };
0578 MODULE_DEVICE_TABLE(i2c, ml26124_i2c_id);
0579
0580 static struct i2c_driver ml26124_i2c_driver = {
0581 .driver = {
0582 .name = "ml26124",
0583 },
0584 .probe_new = ml26124_i2c_probe,
0585 .id_table = ml26124_i2c_id,
0586 };
0587
0588 module_i2c_driver(ml26124_i2c_driver);
0589
0590 MODULE_AUTHOR("Tomoya MORINAGA <tomoya.rohm@gmail.com>");
0591 MODULE_DESCRIPTION("LAPIS Semiconductor ML26124 ALSA SoC codec driver");
0592 MODULE_LICENSE("GPL");