1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <sound/core.h>
27#include <sound/soc.h>
28#include <sound/initval.h>
29#include <linux/i2c.h>
30#include <linux/delay.h>
31
32#include "cs4270.h"
33
34
35
36
37
38
39
40#define CS4270_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
41 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
42 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
43 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
44 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \
45 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
46
47
48#define CS4270_CHIPID 0x01
49#define CS4270_PWRCTL 0x02
50#define CS4270_MODE 0x03
51#define CS4270_FORMAT 0x04
52#define CS4270_TRANS 0x05
53#define CS4270_MUTE 0x06
54#define CS4270_VOLA 0x07
55#define CS4270_VOLB 0x08
56
57#define CS4270_FIRSTREG 0x01
58#define CS4270_LASTREG 0x08
59#define CS4270_NUMREGS (CS4270_LASTREG - CS4270_FIRSTREG + 1)
60#define CS4270_I2C_INCR 0x80
61
62
63#define CS4270_CHIPID_ID 0xF0
64#define CS4270_CHIPID_REV 0x0F
65#define CS4270_PWRCTL_FREEZE 0x80
66#define CS4270_PWRCTL_PDN_ADC 0x20
67#define CS4270_PWRCTL_PDN_DAC 0x02
68#define CS4270_PWRCTL_PDN 0x01
69#define CS4270_PWRCTL_PDN_ALL \
70 (CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | CS4270_PWRCTL_PDN)
71#define CS4270_MODE_SPEED_MASK 0x30
72#define CS4270_MODE_1X 0x00
73#define CS4270_MODE_2X 0x10
74#define CS4270_MODE_4X 0x20
75#define CS4270_MODE_SLAVE 0x30
76#define CS4270_MODE_DIV_MASK 0x0E
77#define CS4270_MODE_DIV1 0x00
78#define CS4270_MODE_DIV15 0x02
79#define CS4270_MODE_DIV2 0x04
80#define CS4270_MODE_DIV3 0x06
81#define CS4270_MODE_DIV4 0x08
82#define CS4270_MODE_POPGUARD 0x01
83#define CS4270_FORMAT_FREEZE_A 0x80
84#define CS4270_FORMAT_FREEZE_B 0x40
85#define CS4270_FORMAT_LOOPBACK 0x20
86#define CS4270_FORMAT_DAC_MASK 0x18
87#define CS4270_FORMAT_DAC_LJ 0x00
88#define CS4270_FORMAT_DAC_I2S 0x08
89#define CS4270_FORMAT_DAC_RJ16 0x18
90#define CS4270_FORMAT_DAC_RJ24 0x10
91#define CS4270_FORMAT_ADC_MASK 0x01
92#define CS4270_FORMAT_ADC_LJ 0x00
93#define CS4270_FORMAT_ADC_I2S 0x01
94#define CS4270_TRANS_ONE_VOL 0x80
95#define CS4270_TRANS_SOFT 0x40
96#define CS4270_TRANS_ZERO 0x20
97#define CS4270_TRANS_INV_ADC_A 0x08
98#define CS4270_TRANS_INV_ADC_B 0x10
99#define CS4270_TRANS_INV_DAC_A 0x02
100#define CS4270_TRANS_INV_DAC_B 0x04
101#define CS4270_TRANS_DEEMPH 0x01
102#define CS4270_MUTE_AUTO 0x20
103#define CS4270_MUTE_ADC_A 0x08
104#define CS4270_MUTE_ADC_B 0x10
105#define CS4270_MUTE_POLARITY 0x04
106#define CS4270_MUTE_DAC_A 0x01
107#define CS4270_MUTE_DAC_B 0x02
108
109
110struct cs4270_private {
111 struct snd_soc_codec codec;
112 u8 reg_cache[CS4270_NUMREGS];
113 unsigned int mclk;
114 unsigned int mode;
115 unsigned int slave_mode;
116 unsigned int manual_mute;
117};
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151struct cs4270_mode_ratios {
152 unsigned int ratio;
153 u8 speed_mode;
154 u8 mclk;
155};
156
157static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
158 {64, CS4270_MODE_4X, CS4270_MODE_DIV1},
159#ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA
160 {96, CS4270_MODE_4X, CS4270_MODE_DIV15},
161#endif
162 {128, CS4270_MODE_2X, CS4270_MODE_DIV1},
163 {192, CS4270_MODE_4X, CS4270_MODE_DIV3},
164 {256, CS4270_MODE_1X, CS4270_MODE_DIV1},
165 {384, CS4270_MODE_2X, CS4270_MODE_DIV3},
166 {512, CS4270_MODE_1X, CS4270_MODE_DIV2},
167 {768, CS4270_MODE_1X, CS4270_MODE_DIV3},
168 {1024, CS4270_MODE_1X, CS4270_MODE_DIV4}
169};
170
171
172#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios)
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
197 int clk_id, unsigned int freq, int dir)
198{
199 struct snd_soc_codec *codec = codec_dai->codec;
200 struct cs4270_private *cs4270 = codec->private_data;
201 unsigned int rates = 0;
202 unsigned int rate_min = -1;
203 unsigned int rate_max = 0;
204 unsigned int i;
205
206 cs4270->mclk = freq;
207
208 for (i = 0; i < NUM_MCLK_RATIOS; i++) {
209 unsigned int rate = freq / cs4270_mode_ratios[i].ratio;
210 rates |= snd_pcm_rate_to_rate_bit(rate);
211 if (rate < rate_min)
212 rate_min = rate;
213 if (rate > rate_max)
214 rate_max = rate;
215 }
216
217 rates &= ~SNDRV_PCM_RATE_KNOT;
218
219 if (!rates) {
220 dev_err(codec->dev, "could not find a valid sample rate\n");
221 return -EINVAL;
222 }
223
224 codec_dai->playback.rates = rates;
225 codec_dai->playback.rate_min = rate_min;
226 codec_dai->playback.rate_max = rate_max;
227
228 codec_dai->capture.rates = rates;
229 codec_dai->capture.rate_min = rate_min;
230 codec_dai->capture.rate_max = rate_max;
231
232 return 0;
233}
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
249 unsigned int format)
250{
251 struct snd_soc_codec *codec = codec_dai->codec;
252 struct cs4270_private *cs4270 = codec->private_data;
253 int ret = 0;
254
255
256 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
257 case SND_SOC_DAIFMT_I2S:
258 case SND_SOC_DAIFMT_LEFT_J:
259 cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
260 break;
261 default:
262 dev_err(codec->dev, "invalid dai format\n");
263 ret = -EINVAL;
264 }
265
266
267 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
268 case SND_SOC_DAIFMT_CBS_CFS:
269 cs4270->slave_mode = 1;
270 break;
271 case SND_SOC_DAIFMT_CBM_CFM:
272 cs4270->slave_mode = 0;
273 break;
274 default:
275
276 ret = -EINVAL;
277 }
278
279 return ret;
280}
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296static int cs4270_fill_cache(struct snd_soc_codec *codec)
297{
298 u8 *cache = codec->reg_cache;
299 struct i2c_client *i2c_client = codec->control_data;
300 s32 length;
301
302 length = i2c_smbus_read_i2c_block_data(i2c_client,
303 CS4270_FIRSTREG | CS4270_I2C_INCR, CS4270_NUMREGS, cache);
304
305 if (length != CS4270_NUMREGS) {
306 dev_err(codec->dev, "i2c read failure, addr=0x%x\n",
307 i2c_client->addr);
308 return -EIO;
309 }
310
311 return 0;
312}
313
314
315
316
317
318
319
320
321
322
323
324
325
326static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec,
327 unsigned int reg)
328{
329 u8 *cache = codec->reg_cache;
330
331 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
332 return -EIO;
333
334 return cache[reg - CS4270_FIRSTREG];
335}
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
351 unsigned int value)
352{
353 u8 *cache = codec->reg_cache;
354
355 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
356 return -EIO;
357
358
359 if (cache[reg - CS4270_FIRSTREG] != value) {
360 struct i2c_client *client = codec->control_data;
361 if (i2c_smbus_write_byte_data(client, reg, value)) {
362 dev_err(codec->dev, "i2c write failed\n");
363 return -EIO;
364 }
365
366
367 cache[reg - CS4270_FIRSTREG] = value;
368 }
369
370 return 0;
371}
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387static int cs4270_hw_params(struct snd_pcm_substream *substream,
388 struct snd_pcm_hw_params *params,
389 struct snd_soc_dai *dai)
390{
391 struct snd_soc_pcm_runtime *rtd = substream->private_data;
392 struct snd_soc_device *socdev = rtd->socdev;
393 struct snd_soc_codec *codec = socdev->card->codec;
394 struct cs4270_private *cs4270 = codec->private_data;
395 int ret;
396 unsigned int i;
397 unsigned int rate;
398 unsigned int ratio;
399 int reg;
400
401
402
403 rate = params_rate(params);
404 ratio = cs4270->mclk / rate;
405
406 for (i = 0; i < NUM_MCLK_RATIOS; i++) {
407 if (cs4270_mode_ratios[i].ratio == ratio)
408 break;
409 }
410
411 if (i == NUM_MCLK_RATIOS) {
412
413 dev_err(codec->dev, "could not find matching ratio\n");
414 return -EINVAL;
415 }
416
417
418
419 reg = snd_soc_read(codec, CS4270_MODE);
420 reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK);
421 reg |= cs4270_mode_ratios[i].mclk;
422
423 if (cs4270->slave_mode)
424 reg |= CS4270_MODE_SLAVE;
425 else
426 reg |= cs4270_mode_ratios[i].speed_mode;
427
428 ret = snd_soc_write(codec, CS4270_MODE, reg);
429 if (ret < 0) {
430 dev_err(codec->dev, "i2c write failed\n");
431 return ret;
432 }
433
434
435
436 reg = snd_soc_read(codec, CS4270_FORMAT);
437 reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK);
438
439 switch (cs4270->mode) {
440 case SND_SOC_DAIFMT_I2S:
441 reg |= CS4270_FORMAT_DAC_I2S | CS4270_FORMAT_ADC_I2S;
442 break;
443 case SND_SOC_DAIFMT_LEFT_J:
444 reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ;
445 break;
446 default:
447 dev_err(codec->dev, "unknown dai format\n");
448 return -EINVAL;
449 }
450
451 ret = snd_soc_write(codec, CS4270_FORMAT, reg);
452 if (ret < 0) {
453 dev_err(codec->dev, "i2c write failed\n");
454 return ret;
455 }
456
457 return ret;
458}
459
460
461
462
463
464
465
466
467
468
469
470static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
471{
472 struct snd_soc_codec *codec = dai->codec;
473 struct cs4270_private *cs4270 = codec->private_data;
474 int reg6;
475
476 reg6 = snd_soc_read(codec, CS4270_MUTE);
477
478 if (mute)
479 reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
480 else {
481 reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
482 reg6 |= cs4270->manual_mute;
483 }
484
485 return snd_soc_write(codec, CS4270_MUTE, reg6);
486}
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol,
503 struct snd_ctl_elem_value *ucontrol)
504{
505 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
506 struct cs4270_private *cs4270 = codec->private_data;
507 int left = !ucontrol->value.integer.value[0];
508 int right = !ucontrol->value.integer.value[1];
509
510 cs4270->manual_mute = (left ? CS4270_MUTE_DAC_A : 0) |
511 (right ? CS4270_MUTE_DAC_B : 0);
512
513 return snd_soc_put_volsw(kcontrol, ucontrol);
514}
515
516
517static const struct snd_kcontrol_new cs4270_snd_controls[] = {
518 SOC_DOUBLE_R("Master Playback Volume",
519 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1),
520 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0),
521 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0),
522 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
523 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
524 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
525 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1),
526 SOC_DOUBLE_EXT("Master Playback Switch", CS4270_MUTE, 0, 1, 1, 1,
527 snd_soc_get_volsw, cs4270_soc_put_mute),
528};
529
530
531
532
533
534
535
536
537
538
539
540
541static struct snd_soc_codec *cs4270_codec;
542
543static struct snd_soc_dai_ops cs4270_dai_ops = {
544 .hw_params = cs4270_hw_params,
545 .set_sysclk = cs4270_set_dai_sysclk,
546 .set_fmt = cs4270_set_dai_fmt,
547 .digital_mute = cs4270_dai_mute,
548};
549
550struct snd_soc_dai cs4270_dai = {
551 .name = "cs4270",
552 .playback = {
553 .stream_name = "Playback",
554 .channels_min = 1,
555 .channels_max = 2,
556 .rates = 0,
557 .formats = CS4270_FORMATS,
558 },
559 .capture = {
560 .stream_name = "Capture",
561 .channels_min = 1,
562 .channels_max = 2,
563 .rates = 0,
564 .formats = CS4270_FORMATS,
565 },
566 .ops = &cs4270_dai_ops,
567};
568EXPORT_SYMBOL_GPL(cs4270_dai);
569
570
571
572
573
574
575
576
577static int cs4270_probe(struct platform_device *pdev)
578{
579 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
580 struct snd_soc_codec *codec = cs4270_codec;
581 int ret;
582
583
584 socdev->card->codec = codec;
585
586
587 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
588 if (ret < 0) {
589 dev_err(codec->dev, "failed to create pcms\n");
590 return ret;
591 }
592
593
594 ret = snd_soc_add_controls(codec, cs4270_snd_controls,
595 ARRAY_SIZE(cs4270_snd_controls));
596 if (ret < 0) {
597 dev_err(codec->dev, "failed to add controls\n");
598 goto error_free_pcms;
599 }
600
601
602 ret = snd_soc_init_card(socdev);
603 if (ret < 0) {
604 dev_err(codec->dev, "failed to register card\n");
605 goto error_free_pcms;
606 }
607
608 return 0;
609
610error_free_pcms:
611 snd_soc_free_pcms(socdev);
612
613 return ret;
614}
615
616
617
618
619
620
621
622static int cs4270_remove(struct platform_device *pdev)
623{
624 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
625
626 snd_soc_free_pcms(socdev);
627
628 return 0;
629};
630
631
632
633
634
635
636
637
638
639static int cs4270_i2c_probe(struct i2c_client *i2c_client,
640 const struct i2c_device_id *id)
641{
642 struct snd_soc_codec *codec;
643 struct cs4270_private *cs4270;
644 unsigned int reg;
645 int ret;
646
647
648
649
650 if (cs4270_codec) {
651 dev_err(&i2c_client->dev, "ignoring CS4270 at addr %X\n",
652 i2c_client->addr);
653 dev_err(&i2c_client->dev, "only one per board allowed\n");
654
655 return -ENODEV;
656 }
657
658
659
660 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
661 if (ret < 0) {
662 dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
663 i2c_client->addr);
664 return ret;
665 }
666
667 if ((ret & 0xF0) != 0xC0) {
668 dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
669 i2c_client->addr);
670 return -ENODEV;
671 }
672
673 dev_info(&i2c_client->dev, "found device at i2c address %X\n",
674 i2c_client->addr);
675 dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
676
677
678
679 cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL);
680 if (!cs4270) {
681 dev_err(&i2c_client->dev, "could not allocate codec\n");
682 return -ENOMEM;
683 }
684 codec = &cs4270->codec;
685
686 mutex_init(&codec->mutex);
687 INIT_LIST_HEAD(&codec->dapm_widgets);
688 INIT_LIST_HEAD(&codec->dapm_paths);
689
690 codec->dev = &i2c_client->dev;
691 codec->name = "CS4270";
692 codec->owner = THIS_MODULE;
693 codec->dai = &cs4270_dai;
694 codec->num_dai = 1;
695 codec->private_data = cs4270;
696 codec->control_data = i2c_client;
697 codec->read = cs4270_read_reg_cache;
698 codec->write = cs4270_i2c_write;
699 codec->reg_cache = cs4270->reg_cache;
700 codec->reg_cache_size = CS4270_NUMREGS;
701
702
703
704 ret = cs4270_fill_cache(codec);
705 if (ret < 0) {
706 dev_err(&i2c_client->dev, "failed to fill register cache\n");
707 goto error_free_codec;
708 }
709
710
711
712
713
714
715
716 reg = cs4270_read_reg_cache(codec, CS4270_MUTE);
717 reg &= ~CS4270_MUTE_AUTO;
718 ret = cs4270_i2c_write(codec, CS4270_MUTE, reg);
719 if (ret < 0) {
720 dev_err(&i2c_client->dev, "i2c write failed\n");
721 return ret;
722 }
723
724
725
726
727
728
729
730 reg = cs4270_read_reg_cache(codec, CS4270_TRANS);
731 reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
732 ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
733 if (ret < 0) {
734 dev_err(&i2c_client->dev, "i2c write failed\n");
735 return ret;
736 }
737
738
739
740
741
742
743 cs4270_dai.dev = &i2c_client->dev;
744
745
746
747
748
749 cs4270_codec = codec;
750 ret = snd_soc_register_dai(&cs4270_dai);
751 if (ret < 0) {
752 dev_err(&i2c_client->dev, "failed to register DAIe\n");
753 goto error_free_codec;
754 }
755
756 i2c_set_clientdata(i2c_client, cs4270);
757
758 return 0;
759
760error_free_codec:
761 kfree(cs4270);
762 cs4270_codec = NULL;
763 cs4270_dai.dev = NULL;
764
765 return ret;
766}
767
768
769
770
771
772
773
774static int cs4270_i2c_remove(struct i2c_client *i2c_client)
775{
776 struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client);
777
778 kfree(cs4270);
779 cs4270_codec = NULL;
780 cs4270_dai.dev = NULL;
781
782 return 0;
783}
784
785
786
787
788static struct i2c_device_id cs4270_id[] = {
789 {"cs4270", 0},
790 {}
791};
792MODULE_DEVICE_TABLE(i2c, cs4270_id);
793
794#ifdef CONFIG_PM
795
796
797
798
799
800
801
802
803
804
805static int cs4270_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
806{
807 struct cs4270_private *cs4270 = i2c_get_clientdata(client);
808 struct snd_soc_codec *codec = &cs4270->codec;
809
810 return snd_soc_suspend_device(codec->dev);
811}
812
813static int cs4270_i2c_resume(struct i2c_client *client)
814{
815 struct cs4270_private *cs4270 = i2c_get_clientdata(client);
816 struct snd_soc_codec *codec = &cs4270->codec;
817
818 return snd_soc_resume_device(codec->dev);
819}
820
821static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
822{
823 struct snd_soc_codec *codec = cs4270_codec;
824 int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
825
826 return snd_soc_write(codec, CS4270_PWRCTL, reg);
827}
828
829static int cs4270_soc_resume(struct platform_device *pdev)
830{
831 struct snd_soc_codec *codec = cs4270_codec;
832 struct i2c_client *i2c_client = codec->control_data;
833 int reg;
834
835
836
837 ndelay(500);
838
839
840 for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) {
841 u8 val = snd_soc_read(codec, reg);
842
843 if (i2c_smbus_write_byte_data(i2c_client, reg, val)) {
844 dev_err(codec->dev, "i2c write failed\n");
845 return -EIO;
846 }
847 }
848
849
850 reg = snd_soc_read(codec, CS4270_PWRCTL);
851 reg &= ~CS4270_PWRCTL_PDN_ALL;
852
853 return snd_soc_write(codec, CS4270_PWRCTL, reg);
854}
855#else
856#define cs4270_i2c_suspend NULL
857#define cs4270_i2c_resume NULL
858#define cs4270_soc_suspend NULL
859#define cs4270_soc_resume NULL
860#endif
861
862
863
864
865
866
867
868static struct i2c_driver cs4270_i2c_driver = {
869 .driver = {
870 .name = "cs4270",
871 .owner = THIS_MODULE,
872 },
873 .id_table = cs4270_id,
874 .probe = cs4270_i2c_probe,
875 .remove = cs4270_i2c_remove,
876 .suspend = cs4270_i2c_suspend,
877 .resume = cs4270_i2c_resume,
878};
879
880
881
882
883
884
885
886struct snd_soc_codec_device soc_codec_device_cs4270 = {
887 .probe = cs4270_probe,
888 .remove = cs4270_remove,
889 .suspend = cs4270_soc_suspend,
890 .resume = cs4270_soc_resume,
891};
892EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
893
894static int __init cs4270_init(void)
895{
896 pr_info("Cirrus Logic CS4270 ALSA SoC Codec Driver\n");
897
898 return i2c_add_driver(&cs4270_i2c_driver);
899}
900module_init(cs4270_init);
901
902static void __exit cs4270_exit(void)
903{
904 i2c_del_driver(&cs4270_i2c_driver);
905}
906module_exit(cs4270_exit);
907
908MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
909MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver");
910MODULE_LICENSE("GPL");
911