0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <linux/module.h>
0025 #include <linux/slab.h>
0026 #include <sound/core.h>
0027 #include <sound/soc.h>
0028 #include <sound/initval.h>
0029 #include <linux/i2c.h>
0030 #include <linux/delay.h>
0031 #include <linux/regulator/consumer.h>
0032 #include <linux/gpio/consumer.h>
0033 #include <linux/of_device.h>
0034
0035 #define CS4270_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
0036 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE | \
0037 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE)
0038
0039
0040 #define CS4270_CHIPID 0x01
0041 #define CS4270_PWRCTL 0x02
0042 #define CS4270_MODE 0x03
0043 #define CS4270_FORMAT 0x04
0044 #define CS4270_TRANS 0x05
0045 #define CS4270_MUTE 0x06
0046 #define CS4270_VOLA 0x07
0047 #define CS4270_VOLB 0x08
0048
0049 #define CS4270_FIRSTREG 0x01
0050 #define CS4270_LASTREG 0x08
0051 #define CS4270_NUMREGS (CS4270_LASTREG - CS4270_FIRSTREG + 1)
0052 #define CS4270_I2C_INCR 0x80
0053
0054
0055 #define CS4270_CHIPID_ID 0xF0
0056 #define CS4270_CHIPID_REV 0x0F
0057 #define CS4270_PWRCTL_FREEZE 0x80
0058 #define CS4270_PWRCTL_PDN_ADC 0x20
0059 #define CS4270_PWRCTL_PDN_DAC 0x02
0060 #define CS4270_PWRCTL_PDN 0x01
0061 #define CS4270_PWRCTL_PDN_ALL \
0062 (CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | CS4270_PWRCTL_PDN)
0063 #define CS4270_MODE_SPEED_MASK 0x30
0064 #define CS4270_MODE_1X 0x00
0065 #define CS4270_MODE_2X 0x10
0066 #define CS4270_MODE_4X 0x20
0067 #define CS4270_MODE_SLAVE 0x30
0068 #define CS4270_MODE_DIV_MASK 0x0E
0069 #define CS4270_MODE_DIV1 0x00
0070 #define CS4270_MODE_DIV15 0x02
0071 #define CS4270_MODE_DIV2 0x04
0072 #define CS4270_MODE_DIV3 0x06
0073 #define CS4270_MODE_DIV4 0x08
0074 #define CS4270_MODE_POPGUARD 0x01
0075 #define CS4270_FORMAT_FREEZE_A 0x80
0076 #define CS4270_FORMAT_FREEZE_B 0x40
0077 #define CS4270_FORMAT_LOOPBACK 0x20
0078 #define CS4270_FORMAT_DAC_MASK 0x18
0079 #define CS4270_FORMAT_DAC_LJ 0x00
0080 #define CS4270_FORMAT_DAC_I2S 0x08
0081 #define CS4270_FORMAT_DAC_RJ16 0x18
0082 #define CS4270_FORMAT_DAC_RJ24 0x10
0083 #define CS4270_FORMAT_ADC_MASK 0x01
0084 #define CS4270_FORMAT_ADC_LJ 0x00
0085 #define CS4270_FORMAT_ADC_I2S 0x01
0086 #define CS4270_TRANS_ONE_VOL 0x80
0087 #define CS4270_TRANS_SOFT 0x40
0088 #define CS4270_TRANS_ZERO 0x20
0089 #define CS4270_TRANS_INV_ADC_A 0x08
0090 #define CS4270_TRANS_INV_ADC_B 0x10
0091 #define CS4270_TRANS_INV_DAC_A 0x02
0092 #define CS4270_TRANS_INV_DAC_B 0x04
0093 #define CS4270_TRANS_DEEMPH 0x01
0094 #define CS4270_MUTE_AUTO 0x20
0095 #define CS4270_MUTE_ADC_A 0x08
0096 #define CS4270_MUTE_ADC_B 0x10
0097 #define CS4270_MUTE_POLARITY 0x04
0098 #define CS4270_MUTE_DAC_A 0x01
0099 #define CS4270_MUTE_DAC_B 0x02
0100
0101
0102
0103
0104
0105
0106
0107 static const struct reg_default cs4270_reg_defaults[] = {
0108 { 2, 0x00 },
0109 { 3, 0x30 },
0110 { 4, 0x00 },
0111 { 5, 0x60 },
0112 { 6, 0x20 },
0113 { 7, 0x00 },
0114 { 8, 0x00 },
0115 };
0116
0117 static const char *supply_names[] = {
0118 "va", "vd", "vlc"
0119 };
0120
0121
0122 struct cs4270_private {
0123 struct regmap *regmap;
0124 unsigned int mclk;
0125 unsigned int mode;
0126 unsigned int slave_mode;
0127 unsigned int manual_mute;
0128
0129
0130 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
0131
0132
0133 struct gpio_desc *reset_gpio;
0134 };
0135
0136 static const struct snd_soc_dapm_widget cs4270_dapm_widgets[] = {
0137 SND_SOC_DAPM_INPUT("AINL"),
0138 SND_SOC_DAPM_INPUT("AINR"),
0139
0140 SND_SOC_DAPM_OUTPUT("AOUTL"),
0141 SND_SOC_DAPM_OUTPUT("AOUTR"),
0142 };
0143
0144 static const struct snd_soc_dapm_route cs4270_dapm_routes[] = {
0145 { "Capture", NULL, "AINL" },
0146 { "Capture", NULL, "AINR" },
0147
0148 { "AOUTL", NULL, "Playback" },
0149 { "AOUTR", NULL, "Playback" },
0150 };
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184 struct cs4270_mode_ratios {
0185 unsigned int ratio;
0186 u8 speed_mode;
0187 u8 mclk;
0188 };
0189
0190 static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
0191 {64, CS4270_MODE_4X, CS4270_MODE_DIV1},
0192 #ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA
0193 {96, CS4270_MODE_4X, CS4270_MODE_DIV15},
0194 #endif
0195 {128, CS4270_MODE_2X, CS4270_MODE_DIV1},
0196 {192, CS4270_MODE_4X, CS4270_MODE_DIV3},
0197 {256, CS4270_MODE_1X, CS4270_MODE_DIV1},
0198 {384, CS4270_MODE_2X, CS4270_MODE_DIV3},
0199 {512, CS4270_MODE_1X, CS4270_MODE_DIV2},
0200 {768, CS4270_MODE_1X, CS4270_MODE_DIV3},
0201 {1024, CS4270_MODE_1X, CS4270_MODE_DIV4}
0202 };
0203
0204
0205 #define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios)
0206
0207 static bool cs4270_reg_is_readable(struct device *dev, unsigned int reg)
0208 {
0209 return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG);
0210 }
0211
0212 static bool cs4270_reg_is_volatile(struct device *dev, unsigned int reg)
0213 {
0214
0215 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
0216 return true;
0217
0218 return reg == CS4270_CHIPID;
0219 }
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248 static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
0249 int clk_id, unsigned int freq, int dir)
0250 {
0251 struct snd_soc_component *component = codec_dai->component;
0252 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
0253
0254 cs4270->mclk = freq;
0255 return 0;
0256 }
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271 static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
0272 unsigned int format)
0273 {
0274 struct snd_soc_component *component = codec_dai->component;
0275 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
0276
0277
0278 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
0279 case SND_SOC_DAIFMT_I2S:
0280 case SND_SOC_DAIFMT_LEFT_J:
0281 cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
0282 break;
0283 default:
0284 dev_err(component->dev, "invalid dai format\n");
0285 return -EINVAL;
0286 }
0287
0288
0289 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
0290 case SND_SOC_DAIFMT_CBS_CFS:
0291 cs4270->slave_mode = 1;
0292 break;
0293 case SND_SOC_DAIFMT_CBM_CFM:
0294 cs4270->slave_mode = 0;
0295 break;
0296 default:
0297
0298 dev_err(component->dev, "Unknown master/slave configuration\n");
0299 return -EINVAL;
0300 }
0301
0302 return 0;
0303 }
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319 static int cs4270_hw_params(struct snd_pcm_substream *substream,
0320 struct snd_pcm_hw_params *params,
0321 struct snd_soc_dai *dai)
0322 {
0323 struct snd_soc_component *component = dai->component;
0324 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
0325 int ret;
0326 unsigned int i;
0327 unsigned int rate;
0328 unsigned int ratio;
0329 int reg;
0330
0331
0332
0333 rate = params_rate(params);
0334 ratio = cs4270->mclk / rate;
0335
0336 for (i = 0; i < NUM_MCLK_RATIOS; i++) {
0337 if (cs4270_mode_ratios[i].ratio == ratio)
0338 break;
0339 }
0340
0341 if (i == NUM_MCLK_RATIOS) {
0342
0343 dev_err(component->dev, "could not find matching ratio\n");
0344 return -EINVAL;
0345 }
0346
0347
0348
0349 reg = snd_soc_component_read(component, CS4270_MODE);
0350 reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK);
0351 reg |= cs4270_mode_ratios[i].mclk;
0352
0353 if (cs4270->slave_mode)
0354 reg |= CS4270_MODE_SLAVE;
0355 else
0356 reg |= cs4270_mode_ratios[i].speed_mode;
0357
0358 ret = snd_soc_component_write(component, CS4270_MODE, reg);
0359 if (ret < 0) {
0360 dev_err(component->dev, "i2c write failed\n");
0361 return ret;
0362 }
0363
0364
0365
0366 reg = snd_soc_component_read(component, CS4270_FORMAT);
0367 reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK);
0368
0369 switch (cs4270->mode) {
0370 case SND_SOC_DAIFMT_I2S:
0371 reg |= CS4270_FORMAT_DAC_I2S | CS4270_FORMAT_ADC_I2S;
0372 break;
0373 case SND_SOC_DAIFMT_LEFT_J:
0374 reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ;
0375 break;
0376 default:
0377 dev_err(component->dev, "unknown dai format\n");
0378 return -EINVAL;
0379 }
0380
0381 ret = snd_soc_component_write(component, CS4270_FORMAT, reg);
0382 if (ret < 0) {
0383 dev_err(component->dev, "i2c write failed\n");
0384 return ret;
0385 }
0386
0387 return ret;
0388 }
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401 static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute, int direction)
0402 {
0403 struct snd_soc_component *component = dai->component;
0404 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
0405 int reg6;
0406
0407 reg6 = snd_soc_component_read(component, CS4270_MUTE);
0408
0409 if (mute)
0410 reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
0411 else {
0412 reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
0413 reg6 |= cs4270->manual_mute;
0414 }
0415
0416 return snd_soc_component_write(component, CS4270_MUTE, reg6);
0417 }
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433 static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol,
0434 struct snd_ctl_elem_value *ucontrol)
0435 {
0436 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
0437 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
0438 int left = !ucontrol->value.integer.value[0];
0439 int right = !ucontrol->value.integer.value[1];
0440
0441 cs4270->manual_mute = (left ? CS4270_MUTE_DAC_A : 0) |
0442 (right ? CS4270_MUTE_DAC_B : 0);
0443
0444 return snd_soc_put_volsw(kcontrol, ucontrol);
0445 }
0446
0447
0448 static const struct snd_kcontrol_new cs4270_snd_controls[] = {
0449 SOC_DOUBLE_R("Master Playback Volume",
0450 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1),
0451 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0),
0452 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0),
0453 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
0454 SOC_SINGLE("De-emphasis filter", CS4270_TRANS, 0, 1, 0),
0455 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
0456 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
0457 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1),
0458 SOC_DOUBLE_EXT("Master Playback Switch", CS4270_MUTE, 0, 1, 1, 1,
0459 snd_soc_get_volsw, cs4270_soc_put_mute),
0460 };
0461
0462 static const struct snd_soc_dai_ops cs4270_dai_ops = {
0463 .hw_params = cs4270_hw_params,
0464 .set_sysclk = cs4270_set_dai_sysclk,
0465 .set_fmt = cs4270_set_dai_fmt,
0466 .mute_stream = cs4270_dai_mute,
0467 .no_capture_mute = 1,
0468 };
0469
0470 static struct snd_soc_dai_driver cs4270_dai = {
0471 .name = "cs4270-hifi",
0472 .playback = {
0473 .stream_name = "Playback",
0474 .channels_min = 2,
0475 .channels_max = 2,
0476 .rates = SNDRV_PCM_RATE_CONTINUOUS,
0477 .rate_min = 4000,
0478 .rate_max = 216000,
0479 .formats = CS4270_FORMATS,
0480 },
0481 .capture = {
0482 .stream_name = "Capture",
0483 .channels_min = 2,
0484 .channels_max = 2,
0485 .rates = SNDRV_PCM_RATE_CONTINUOUS,
0486 .rate_min = 4000,
0487 .rate_max = 216000,
0488 .formats = CS4270_FORMATS,
0489 },
0490 .ops = &cs4270_dai_ops,
0491 };
0492
0493
0494
0495
0496
0497
0498
0499
0500 static int cs4270_probe(struct snd_soc_component *component)
0501 {
0502 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
0503 int ret;
0504
0505
0506
0507
0508
0509
0510 ret = snd_soc_component_update_bits(component, CS4270_MUTE, CS4270_MUTE_AUTO, 0);
0511 if (ret < 0) {
0512 dev_err(component->dev, "i2c write failed\n");
0513 return ret;
0514 }
0515
0516
0517
0518
0519
0520
0521 ret = snd_soc_component_update_bits(component, CS4270_TRANS,
0522 CS4270_TRANS_SOFT | CS4270_TRANS_ZERO, 0);
0523 if (ret < 0) {
0524 dev_err(component->dev, "i2c write failed\n");
0525 return ret;
0526 }
0527
0528 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
0529 cs4270->supplies);
0530
0531 return ret;
0532 }
0533
0534
0535
0536
0537
0538
0539
0540 static void cs4270_remove(struct snd_soc_component *component)
0541 {
0542 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
0543
0544 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
0545 };
0546
0547 #ifdef CONFIG_PM
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558 static int cs4270_soc_suspend(struct snd_soc_component *component)
0559 {
0560 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
0561 int reg, ret;
0562
0563 reg = snd_soc_component_read(component, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
0564 if (reg < 0)
0565 return reg;
0566
0567 ret = snd_soc_component_write(component, CS4270_PWRCTL, reg);
0568 if (ret < 0)
0569 return ret;
0570
0571 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies),
0572 cs4270->supplies);
0573
0574 return 0;
0575 }
0576
0577 static int cs4270_soc_resume(struct snd_soc_component *component)
0578 {
0579 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
0580 int reg, ret;
0581
0582 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
0583 cs4270->supplies);
0584 if (ret != 0)
0585 return ret;
0586
0587
0588
0589 ndelay(500);
0590
0591
0592 regcache_sync(cs4270->regmap);
0593
0594
0595 reg = snd_soc_component_read(component, CS4270_PWRCTL);
0596 reg &= ~CS4270_PWRCTL_PDN_ALL;
0597
0598 return snd_soc_component_write(component, CS4270_PWRCTL, reg);
0599 }
0600 #else
0601 #define cs4270_soc_suspend NULL
0602 #define cs4270_soc_resume NULL
0603 #endif
0604
0605
0606
0607
0608 static const struct snd_soc_component_driver soc_component_device_cs4270 = {
0609 .probe = cs4270_probe,
0610 .remove = cs4270_remove,
0611 .suspend = cs4270_soc_suspend,
0612 .resume = cs4270_soc_resume,
0613 .controls = cs4270_snd_controls,
0614 .num_controls = ARRAY_SIZE(cs4270_snd_controls),
0615 .dapm_widgets = cs4270_dapm_widgets,
0616 .num_dapm_widgets = ARRAY_SIZE(cs4270_dapm_widgets),
0617 .dapm_routes = cs4270_dapm_routes,
0618 .num_dapm_routes = ARRAY_SIZE(cs4270_dapm_routes),
0619 .idle_bias_on = 1,
0620 .use_pmdown_time = 1,
0621 .endianness = 1,
0622 };
0623
0624
0625
0626
0627 static const struct of_device_id cs4270_of_match[] = {
0628 { .compatible = "cirrus,cs4270", },
0629 { }
0630 };
0631 MODULE_DEVICE_TABLE(of, cs4270_of_match);
0632
0633 static const struct regmap_config cs4270_regmap = {
0634 .reg_bits = 8,
0635 .val_bits = 8,
0636 .max_register = CS4270_LASTREG,
0637 .reg_defaults = cs4270_reg_defaults,
0638 .num_reg_defaults = ARRAY_SIZE(cs4270_reg_defaults),
0639 .cache_type = REGCACHE_RBTREE,
0640 .write_flag_mask = CS4270_I2C_INCR,
0641
0642 .readable_reg = cs4270_reg_is_readable,
0643 .volatile_reg = cs4270_reg_is_volatile,
0644 };
0645
0646
0647
0648
0649
0650
0651
0652
0653 static int cs4270_i2c_remove(struct i2c_client *i2c_client)
0654 {
0655 struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client);
0656
0657 gpiod_set_value_cansleep(cs4270->reset_gpio, 0);
0658
0659 return 0;
0660 }
0661
0662
0663
0664
0665
0666
0667
0668
0669 static int cs4270_i2c_probe(struct i2c_client *i2c_client)
0670 {
0671 struct cs4270_private *cs4270;
0672 unsigned int val;
0673 int ret, i;
0674
0675 cs4270 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs4270_private),
0676 GFP_KERNEL);
0677 if (!cs4270)
0678 return -ENOMEM;
0679
0680
0681 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
0682 cs4270->supplies[i].supply = supply_names[i];
0683
0684 ret = devm_regulator_bulk_get(&i2c_client->dev,
0685 ARRAY_SIZE(cs4270->supplies),
0686 cs4270->supplies);
0687 if (ret < 0)
0688 return ret;
0689
0690
0691 cs4270->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev, "reset",
0692 GPIOD_OUT_LOW);
0693 if (IS_ERR(cs4270->reset_gpio)) {
0694 dev_dbg(&i2c_client->dev, "Error getting CS4270 reset GPIO\n");
0695 return PTR_ERR(cs4270->reset_gpio);
0696 }
0697
0698 if (cs4270->reset_gpio) {
0699 dev_dbg(&i2c_client->dev, "Found reset GPIO\n");
0700 gpiod_set_value_cansleep(cs4270->reset_gpio, 1);
0701 }
0702
0703
0704 ndelay(500);
0705
0706 cs4270->regmap = devm_regmap_init_i2c(i2c_client, &cs4270_regmap);
0707 if (IS_ERR(cs4270->regmap))
0708 return PTR_ERR(cs4270->regmap);
0709
0710
0711 ret = regmap_read(cs4270->regmap, CS4270_CHIPID, &val);
0712 if (ret < 0) {
0713 dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
0714 i2c_client->addr);
0715 return ret;
0716 }
0717
0718 if ((val & 0xF0) != 0xC0) {
0719 dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
0720 i2c_client->addr);
0721 return -ENODEV;
0722 }
0723
0724 dev_info(&i2c_client->dev, "found device at i2c address %X\n",
0725 i2c_client->addr);
0726 dev_info(&i2c_client->dev, "hardware revision %X\n", val & 0xF);
0727
0728 i2c_set_clientdata(i2c_client, cs4270);
0729
0730 ret = devm_snd_soc_register_component(&i2c_client->dev,
0731 &soc_component_device_cs4270, &cs4270_dai, 1);
0732 return ret;
0733 }
0734
0735
0736
0737
0738 static const struct i2c_device_id cs4270_id[] = {
0739 {"cs4270", 0},
0740 {}
0741 };
0742 MODULE_DEVICE_TABLE(i2c, cs4270_id);
0743
0744
0745
0746
0747
0748
0749
0750 static struct i2c_driver cs4270_i2c_driver = {
0751 .driver = {
0752 .name = "cs4270",
0753 .of_match_table = cs4270_of_match,
0754 },
0755 .id_table = cs4270_id,
0756 .probe_new = cs4270_i2c_probe,
0757 .remove = cs4270_i2c_remove,
0758 };
0759
0760 module_i2c_driver(cs4270_i2c_driver);
0761
0762 MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
0763 MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver");
0764 MODULE_LICENSE("GPL");