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 <linux/slab.h>
27#include <sound/core.h>
28#include <sound/soc.h>
29#include <sound/initval.h>
30#include <linux/i2c.h>
31#include <linux/delay.h>
32#include <linux/regulator/consumer.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
110
111
112
113
114
115
116
117
118
119
120static const u8 cs4270_default_reg_cache[CS4270_LASTREG + 1] = {
121 0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x20, 0x00, 0x00
122};
123
124static const char *supply_names[] = {
125 "va", "vd", "vlc"
126};
127
128
129struct cs4270_private {
130 enum snd_soc_control_type control_type;
131 unsigned int mclk;
132 unsigned int mode;
133 unsigned int slave_mode;
134 unsigned int manual_mute;
135
136
137 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
138};
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172struct cs4270_mode_ratios {
173 unsigned int ratio;
174 u8 speed_mode;
175 u8 mclk;
176};
177
178static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
179 {64, CS4270_MODE_4X, CS4270_MODE_DIV1},
180#ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA
181 {96, CS4270_MODE_4X, CS4270_MODE_DIV15},
182#endif
183 {128, CS4270_MODE_2X, CS4270_MODE_DIV1},
184 {192, CS4270_MODE_4X, CS4270_MODE_DIV3},
185 {256, CS4270_MODE_1X, CS4270_MODE_DIV1},
186 {384, CS4270_MODE_2X, CS4270_MODE_DIV3},
187 {512, CS4270_MODE_1X, CS4270_MODE_DIV2},
188 {768, CS4270_MODE_1X, CS4270_MODE_DIV3},
189 {1024, CS4270_MODE_1X, CS4270_MODE_DIV4}
190};
191
192
193#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios)
194
195static int cs4270_reg_is_readable(struct snd_soc_codec *codec, unsigned int reg)
196{
197 return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG);
198}
199
200static int cs4270_reg_is_volatile(struct snd_soc_codec *codec, unsigned int reg)
201{
202
203 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
204 return 1;
205
206 return reg == CS4270_CHIPID;
207}
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
237 int clk_id, unsigned int freq, int dir)
238{
239 struct snd_soc_codec *codec = codec_dai->codec;
240 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
241
242 cs4270->mclk = freq;
243 return 0;
244}
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
260 unsigned int format)
261{
262 struct snd_soc_codec *codec = codec_dai->codec;
263 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
264
265
266 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
267 case SND_SOC_DAIFMT_I2S:
268 case SND_SOC_DAIFMT_LEFT_J:
269 cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
270 break;
271 default:
272 dev_err(codec->dev, "invalid dai format\n");
273 return -EINVAL;
274 }
275
276
277 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
278 case SND_SOC_DAIFMT_CBS_CFS:
279 cs4270->slave_mode = 1;
280 break;
281 case SND_SOC_DAIFMT_CBM_CFM:
282 cs4270->slave_mode = 0;
283 break;
284 default:
285
286 dev_err(codec->dev, "Unknown master/slave configuration\n");
287 return -EINVAL;
288 }
289
290 return 0;
291}
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307static int cs4270_hw_params(struct snd_pcm_substream *substream,
308 struct snd_pcm_hw_params *params,
309 struct snd_soc_dai *dai)
310{
311 struct snd_soc_pcm_runtime *rtd = substream->private_data;
312 struct snd_soc_codec *codec = rtd->codec;
313 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
314 int ret;
315 unsigned int i;
316 unsigned int rate;
317 unsigned int ratio;
318 int reg;
319
320
321
322 rate = params_rate(params);
323 ratio = cs4270->mclk / rate;
324
325 for (i = 0; i < NUM_MCLK_RATIOS; i++) {
326 if (cs4270_mode_ratios[i].ratio == ratio)
327 break;
328 }
329
330 if (i == NUM_MCLK_RATIOS) {
331
332 dev_err(codec->dev, "could not find matching ratio\n");
333 return -EINVAL;
334 }
335
336
337
338 reg = snd_soc_read(codec, CS4270_MODE);
339 reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK);
340 reg |= cs4270_mode_ratios[i].mclk;
341
342 if (cs4270->slave_mode)
343 reg |= CS4270_MODE_SLAVE;
344 else
345 reg |= cs4270_mode_ratios[i].speed_mode;
346
347 ret = snd_soc_write(codec, CS4270_MODE, reg);
348 if (ret < 0) {
349 dev_err(codec->dev, "i2c write failed\n");
350 return ret;
351 }
352
353
354
355 reg = snd_soc_read(codec, CS4270_FORMAT);
356 reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK);
357
358 switch (cs4270->mode) {
359 case SND_SOC_DAIFMT_I2S:
360 reg |= CS4270_FORMAT_DAC_I2S | CS4270_FORMAT_ADC_I2S;
361 break;
362 case SND_SOC_DAIFMT_LEFT_J:
363 reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ;
364 break;
365 default:
366 dev_err(codec->dev, "unknown dai format\n");
367 return -EINVAL;
368 }
369
370 ret = snd_soc_write(codec, CS4270_FORMAT, reg);
371 if (ret < 0) {
372 dev_err(codec->dev, "i2c write failed\n");
373 return ret;
374 }
375
376 return ret;
377}
378
379
380
381
382
383
384
385
386
387
388
389static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
390{
391 struct snd_soc_codec *codec = dai->codec;
392 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
393 int reg6;
394
395 reg6 = snd_soc_read(codec, CS4270_MUTE);
396
397 if (mute)
398 reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
399 else {
400 reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
401 reg6 |= cs4270->manual_mute;
402 }
403
404 return snd_soc_write(codec, CS4270_MUTE, reg6);
405}
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol,
422 struct snd_ctl_elem_value *ucontrol)
423{
424 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
425 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
426 int left = !ucontrol->value.integer.value[0];
427 int right = !ucontrol->value.integer.value[1];
428
429 cs4270->manual_mute = (left ? CS4270_MUTE_DAC_A : 0) |
430 (right ? CS4270_MUTE_DAC_B : 0);
431
432 return snd_soc_put_volsw(kcontrol, ucontrol);
433}
434
435
436static const struct snd_kcontrol_new cs4270_snd_controls[] = {
437 SOC_DOUBLE_R("Master Playback Volume",
438 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1),
439 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0),
440 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0),
441 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
442 SOC_SINGLE("De-emphasis filter", CS4270_TRANS, 0, 1, 0),
443 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
444 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
445 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1),
446 SOC_DOUBLE_EXT("Master Playback Switch", CS4270_MUTE, 0, 1, 1, 1,
447 snd_soc_get_volsw, cs4270_soc_put_mute),
448};
449
450static struct snd_soc_dai_ops cs4270_dai_ops = {
451 .hw_params = cs4270_hw_params,
452 .set_sysclk = cs4270_set_dai_sysclk,
453 .set_fmt = cs4270_set_dai_fmt,
454 .digital_mute = cs4270_dai_mute,
455};
456
457static struct snd_soc_dai_driver cs4270_dai = {
458 .name = "cs4270-hifi",
459 .playback = {
460 .stream_name = "Playback",
461 .channels_min = 1,
462 .channels_max = 2,
463 .rates = SNDRV_PCM_RATE_CONTINUOUS,
464 .rate_min = 4000,
465 .rate_max = 216000,
466 .formats = CS4270_FORMATS,
467 },
468 .capture = {
469 .stream_name = "Capture",
470 .channels_min = 1,
471 .channels_max = 2,
472 .rates = SNDRV_PCM_RATE_CONTINUOUS,
473 .rate_min = 4000,
474 .rate_max = 216000,
475 .formats = CS4270_FORMATS,
476 },
477 .ops = &cs4270_dai_ops,
478};
479
480
481
482
483
484
485
486
487static int cs4270_probe(struct snd_soc_codec *codec)
488{
489 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
490 int i, ret;
491
492
493
494
495 ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs4270->control_type);
496 if (ret < 0) {
497 dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret);
498 return ret;
499 }
500
501
502
503
504
505
506 ret = snd_soc_update_bits(codec, CS4270_MUTE, CS4270_MUTE_AUTO, 0);
507 if (ret < 0) {
508 dev_err(codec->dev, "i2c write failed\n");
509 return ret;
510 }
511
512
513
514
515
516
517 ret = snd_soc_update_bits(codec, CS4270_TRANS,
518 CS4270_TRANS_SOFT | CS4270_TRANS_ZERO, 0);
519 if (ret < 0) {
520 dev_err(codec->dev, "i2c write failed\n");
521 return ret;
522 }
523
524
525 ret = snd_soc_add_controls(codec, cs4270_snd_controls,
526 ARRAY_SIZE(cs4270_snd_controls));
527 if (ret < 0) {
528 dev_err(codec->dev, "failed to add controls\n");
529 return ret;
530 }
531
532
533 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
534 cs4270->supplies[i].supply = supply_names[i];
535
536 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
537 cs4270->supplies);
538 if (ret < 0)
539 return ret;
540
541 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
542 cs4270->supplies);
543 if (ret < 0)
544 goto error_free_regulators;
545
546 return 0;
547
548error_free_regulators:
549 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
550 cs4270->supplies);
551
552 return ret;
553}
554
555
556
557
558
559
560
561static int cs4270_remove(struct snd_soc_codec *codec)
562{
563 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
564
565 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
566 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
567
568 return 0;
569};
570
571#ifdef CONFIG_PM
572
573
574
575
576
577
578
579
580
581
582static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
583{
584 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
585 int reg, ret;
586
587 reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
588 if (reg < 0)
589 return reg;
590
591 ret = snd_soc_write(codec, CS4270_PWRCTL, reg);
592 if (ret < 0)
593 return ret;
594
595 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies),
596 cs4270->supplies);
597
598 return 0;
599}
600
601static int cs4270_soc_resume(struct snd_soc_codec *codec)
602{
603 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
604 int reg;
605
606 regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
607 cs4270->supplies);
608
609
610
611 ndelay(500);
612
613
614 snd_soc_cache_sync(codec);
615
616
617 reg = snd_soc_read(codec, CS4270_PWRCTL);
618 reg &= ~CS4270_PWRCTL_PDN_ALL;
619
620 return snd_soc_write(codec, CS4270_PWRCTL, reg);
621}
622#else
623#define cs4270_soc_suspend NULL
624#define cs4270_soc_resume NULL
625#endif
626
627
628
629
630static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
631 .probe = cs4270_probe,
632 .remove = cs4270_remove,
633 .suspend = cs4270_soc_suspend,
634 .resume = cs4270_soc_resume,
635 .volatile_register = cs4270_reg_is_volatile,
636 .readable_register = cs4270_reg_is_readable,
637 .reg_cache_size = CS4270_LASTREG + 1,
638 .reg_word_size = sizeof(u8),
639 .reg_cache_default = cs4270_default_reg_cache,
640};
641
642
643
644
645
646
647
648
649
650static int cs4270_i2c_probe(struct i2c_client *i2c_client,
651 const struct i2c_device_id *id)
652{
653 struct cs4270_private *cs4270;
654 int ret;
655
656
657
658 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
659 if (ret < 0) {
660 dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
661 i2c_client->addr);
662 return ret;
663 }
664
665 if ((ret & 0xF0) != 0xC0) {
666 dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
667 i2c_client->addr);
668 return -ENODEV;
669 }
670
671 dev_info(&i2c_client->dev, "found device at i2c address %X\n",
672 i2c_client->addr);
673 dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
674
675 cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL);
676 if (!cs4270) {
677 dev_err(&i2c_client->dev, "could not allocate codec\n");
678 return -ENOMEM;
679 }
680
681 i2c_set_clientdata(i2c_client, cs4270);
682 cs4270->control_type = SND_SOC_I2C;
683
684 ret = snd_soc_register_codec(&i2c_client->dev,
685 &soc_codec_device_cs4270, &cs4270_dai, 1);
686 if (ret < 0)
687 kfree(cs4270);
688 return ret;
689}
690
691
692
693
694
695
696
697static int cs4270_i2c_remove(struct i2c_client *i2c_client)
698{
699 snd_soc_unregister_codec(&i2c_client->dev);
700 kfree(i2c_get_clientdata(i2c_client));
701 return 0;
702}
703
704
705
706
707static const struct i2c_device_id cs4270_id[] = {
708 {"cs4270", 0},
709 {}
710};
711MODULE_DEVICE_TABLE(i2c, cs4270_id);
712
713
714
715
716
717
718
719static struct i2c_driver cs4270_i2c_driver = {
720 .driver = {
721 .name = "cs4270-codec",
722 .owner = THIS_MODULE,
723 },
724 .id_table = cs4270_id,
725 .probe = cs4270_i2c_probe,
726 .remove = cs4270_i2c_remove,
727};
728
729static int __init cs4270_init(void)
730{
731 return i2c_add_driver(&cs4270_i2c_driver);
732}
733module_init(cs4270_init);
734
735static void __exit cs4270_exit(void)
736{
737 i2c_del_driver(&cs4270_i2c_driver);
738}
739module_exit(cs4270_exit);
740
741MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
742MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver");
743MODULE_LICENSE("GPL");
744