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/slab.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#include <linux/regulator/consumer.h>
32#include <linux/of_device.h>
33#include <linux/of_gpio.h>
34
35
36
37
38
39
40
41#define CS4270_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
42 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
43 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
44 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
45 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \
46 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
47
48
49#define CS4270_CHIPID 0x01
50#define CS4270_PWRCTL 0x02
51#define CS4270_MODE 0x03
52#define CS4270_FORMAT 0x04
53#define CS4270_TRANS 0x05
54#define CS4270_MUTE 0x06
55#define CS4270_VOLA 0x07
56#define CS4270_VOLB 0x08
57
58#define CS4270_FIRSTREG 0x01
59#define CS4270_LASTREG 0x08
60#define CS4270_NUMREGS (CS4270_LASTREG - CS4270_FIRSTREG + 1)
61#define CS4270_I2C_INCR 0x80
62
63
64#define CS4270_CHIPID_ID 0xF0
65#define CS4270_CHIPID_REV 0x0F
66#define CS4270_PWRCTL_FREEZE 0x80
67#define CS4270_PWRCTL_PDN_ADC 0x20
68#define CS4270_PWRCTL_PDN_DAC 0x02
69#define CS4270_PWRCTL_PDN 0x01
70#define CS4270_PWRCTL_PDN_ALL \
71 (CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | CS4270_PWRCTL_PDN)
72#define CS4270_MODE_SPEED_MASK 0x30
73#define CS4270_MODE_1X 0x00
74#define CS4270_MODE_2X 0x10
75#define CS4270_MODE_4X 0x20
76#define CS4270_MODE_SLAVE 0x30
77#define CS4270_MODE_DIV_MASK 0x0E
78#define CS4270_MODE_DIV1 0x00
79#define CS4270_MODE_DIV15 0x02
80#define CS4270_MODE_DIV2 0x04
81#define CS4270_MODE_DIV3 0x06
82#define CS4270_MODE_DIV4 0x08
83#define CS4270_MODE_POPGUARD 0x01
84#define CS4270_FORMAT_FREEZE_A 0x80
85#define CS4270_FORMAT_FREEZE_B 0x40
86#define CS4270_FORMAT_LOOPBACK 0x20
87#define CS4270_FORMAT_DAC_MASK 0x18
88#define CS4270_FORMAT_DAC_LJ 0x00
89#define CS4270_FORMAT_DAC_I2S 0x08
90#define CS4270_FORMAT_DAC_RJ16 0x18
91#define CS4270_FORMAT_DAC_RJ24 0x10
92#define CS4270_FORMAT_ADC_MASK 0x01
93#define CS4270_FORMAT_ADC_LJ 0x00
94#define CS4270_FORMAT_ADC_I2S 0x01
95#define CS4270_TRANS_ONE_VOL 0x80
96#define CS4270_TRANS_SOFT 0x40
97#define CS4270_TRANS_ZERO 0x20
98#define CS4270_TRANS_INV_ADC_A 0x08
99#define CS4270_TRANS_INV_ADC_B 0x10
100#define CS4270_TRANS_INV_DAC_A 0x02
101#define CS4270_TRANS_INV_DAC_B 0x04
102#define CS4270_TRANS_DEEMPH 0x01
103#define CS4270_MUTE_AUTO 0x20
104#define CS4270_MUTE_ADC_A 0x08
105#define CS4270_MUTE_ADC_B 0x10
106#define CS4270_MUTE_POLARITY 0x04
107#define CS4270_MUTE_DAC_A 0x01
108#define CS4270_MUTE_DAC_B 0x02
109
110
111
112
113
114
115
116static const struct reg_default cs4270_reg_defaults[] = {
117 { 2, 0x00 },
118 { 3, 0x30 },
119 { 4, 0x00 },
120 { 5, 0x60 },
121 { 6, 0x20 },
122 { 7, 0x00 },
123 { 8, 0x00 },
124};
125
126static const char *supply_names[] = {
127 "va", "vd", "vlc"
128};
129
130
131struct cs4270_private {
132 struct regmap *regmap;
133 unsigned int mclk;
134 unsigned int mode;
135 unsigned int slave_mode;
136 unsigned int manual_mute;
137
138
139 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
140};
141
142static const struct snd_soc_dapm_widget cs4270_dapm_widgets[] = {
143SND_SOC_DAPM_INPUT("AINL"),
144SND_SOC_DAPM_INPUT("AINR"),
145
146SND_SOC_DAPM_OUTPUT("AOUTL"),
147SND_SOC_DAPM_OUTPUT("AOUTR"),
148};
149
150static const struct snd_soc_dapm_route cs4270_dapm_routes[] = {
151 { "Capture", NULL, "AINL" },
152 { "Capture", NULL, "AINR" },
153
154 { "AOUTL", NULL, "Playback" },
155 { "AOUTR", NULL, "Playback" },
156};
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190struct cs4270_mode_ratios {
191 unsigned int ratio;
192 u8 speed_mode;
193 u8 mclk;
194};
195
196static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
197 {64, CS4270_MODE_4X, CS4270_MODE_DIV1},
198#ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA
199 {96, CS4270_MODE_4X, CS4270_MODE_DIV15},
200#endif
201 {128, CS4270_MODE_2X, CS4270_MODE_DIV1},
202 {192, CS4270_MODE_4X, CS4270_MODE_DIV3},
203 {256, CS4270_MODE_1X, CS4270_MODE_DIV1},
204 {384, CS4270_MODE_2X, CS4270_MODE_DIV3},
205 {512, CS4270_MODE_1X, CS4270_MODE_DIV2},
206 {768, CS4270_MODE_1X, CS4270_MODE_DIV3},
207 {1024, CS4270_MODE_1X, CS4270_MODE_DIV4}
208};
209
210
211#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios)
212
213static bool cs4270_reg_is_readable(struct device *dev, unsigned int reg)
214{
215 return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG);
216}
217
218static bool cs4270_reg_is_volatile(struct device *dev, unsigned int reg)
219{
220
221 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
222 return 1;
223
224 return reg == CS4270_CHIPID;
225}
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
255 int clk_id, unsigned int freq, int dir)
256{
257 struct snd_soc_codec *codec = codec_dai->codec;
258 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
259
260 cs4270->mclk = freq;
261 return 0;
262}
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
278 unsigned int format)
279{
280 struct snd_soc_codec *codec = codec_dai->codec;
281 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
282
283
284 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
285 case SND_SOC_DAIFMT_I2S:
286 case SND_SOC_DAIFMT_LEFT_J:
287 cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
288 break;
289 default:
290 dev_err(codec->dev, "invalid dai format\n");
291 return -EINVAL;
292 }
293
294
295 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
296 case SND_SOC_DAIFMT_CBS_CFS:
297 cs4270->slave_mode = 1;
298 break;
299 case SND_SOC_DAIFMT_CBM_CFM:
300 cs4270->slave_mode = 0;
301 break;
302 default:
303
304 dev_err(codec->dev, "Unknown master/slave configuration\n");
305 return -EINVAL;
306 }
307
308 return 0;
309}
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325static int cs4270_hw_params(struct snd_pcm_substream *substream,
326 struct snd_pcm_hw_params *params,
327 struct snd_soc_dai *dai)
328{
329 struct snd_soc_codec *codec = dai->codec;
330 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
331 int ret;
332 unsigned int i;
333 unsigned int rate;
334 unsigned int ratio;
335 int reg;
336
337
338
339 rate = params_rate(params);
340 ratio = cs4270->mclk / rate;
341
342 for (i = 0; i < NUM_MCLK_RATIOS; i++) {
343 if (cs4270_mode_ratios[i].ratio == ratio)
344 break;
345 }
346
347 if (i == NUM_MCLK_RATIOS) {
348
349 dev_err(codec->dev, "could not find matching ratio\n");
350 return -EINVAL;
351 }
352
353
354
355 reg = snd_soc_read(codec, CS4270_MODE);
356 reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK);
357 reg |= cs4270_mode_ratios[i].mclk;
358
359 if (cs4270->slave_mode)
360 reg |= CS4270_MODE_SLAVE;
361 else
362 reg |= cs4270_mode_ratios[i].speed_mode;
363
364 ret = snd_soc_write(codec, CS4270_MODE, reg);
365 if (ret < 0) {
366 dev_err(codec->dev, "i2c write failed\n");
367 return ret;
368 }
369
370
371
372 reg = snd_soc_read(codec, CS4270_FORMAT);
373 reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK);
374
375 switch (cs4270->mode) {
376 case SND_SOC_DAIFMT_I2S:
377 reg |= CS4270_FORMAT_DAC_I2S | CS4270_FORMAT_ADC_I2S;
378 break;
379 case SND_SOC_DAIFMT_LEFT_J:
380 reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ;
381 break;
382 default:
383 dev_err(codec->dev, "unknown dai format\n");
384 return -EINVAL;
385 }
386
387 ret = snd_soc_write(codec, CS4270_FORMAT, reg);
388 if (ret < 0) {
389 dev_err(codec->dev, "i2c write failed\n");
390 return ret;
391 }
392
393 return ret;
394}
395
396
397
398
399
400
401
402
403
404
405
406static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
407{
408 struct snd_soc_codec *codec = dai->codec;
409 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
410 int reg6;
411
412 reg6 = snd_soc_read(codec, CS4270_MUTE);
413
414 if (mute)
415 reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
416 else {
417 reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
418 reg6 |= cs4270->manual_mute;
419 }
420
421 return snd_soc_write(codec, CS4270_MUTE, reg6);
422}
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol,
439 struct snd_ctl_elem_value *ucontrol)
440{
441 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
442 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
443 int left = !ucontrol->value.integer.value[0];
444 int right = !ucontrol->value.integer.value[1];
445
446 cs4270->manual_mute = (left ? CS4270_MUTE_DAC_A : 0) |
447 (right ? CS4270_MUTE_DAC_B : 0);
448
449 return snd_soc_put_volsw(kcontrol, ucontrol);
450}
451
452
453static const struct snd_kcontrol_new cs4270_snd_controls[] = {
454 SOC_DOUBLE_R("Master Playback Volume",
455 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1),
456 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0),
457 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0),
458 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
459 SOC_SINGLE("De-emphasis filter", CS4270_TRANS, 0, 1, 0),
460 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
461 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
462 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1),
463 SOC_DOUBLE_EXT("Master Playback Switch", CS4270_MUTE, 0, 1, 1, 1,
464 snd_soc_get_volsw, cs4270_soc_put_mute),
465};
466
467static const struct snd_soc_dai_ops cs4270_dai_ops = {
468 .hw_params = cs4270_hw_params,
469 .set_sysclk = cs4270_set_dai_sysclk,
470 .set_fmt = cs4270_set_dai_fmt,
471 .digital_mute = cs4270_dai_mute,
472};
473
474static struct snd_soc_dai_driver cs4270_dai = {
475 .name = "cs4270-hifi",
476 .playback = {
477 .stream_name = "Playback",
478 .channels_min = 2,
479 .channels_max = 2,
480 .rates = SNDRV_PCM_RATE_CONTINUOUS,
481 .rate_min = 4000,
482 .rate_max = 216000,
483 .formats = CS4270_FORMATS,
484 },
485 .capture = {
486 .stream_name = "Capture",
487 .channels_min = 2,
488 .channels_max = 2,
489 .rates = SNDRV_PCM_RATE_CONTINUOUS,
490 .rate_min = 4000,
491 .rate_max = 216000,
492 .formats = CS4270_FORMATS,
493 },
494 .ops = &cs4270_dai_ops,
495};
496
497
498
499
500
501
502
503
504static int cs4270_probe(struct snd_soc_codec *codec)
505{
506 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
507 int ret;
508
509
510
511
512
513
514 ret = snd_soc_update_bits(codec, CS4270_MUTE, CS4270_MUTE_AUTO, 0);
515 if (ret < 0) {
516 dev_err(codec->dev, "i2c write failed\n");
517 return ret;
518 }
519
520
521
522
523
524
525 ret = snd_soc_update_bits(codec, CS4270_TRANS,
526 CS4270_TRANS_SOFT | CS4270_TRANS_ZERO, 0);
527 if (ret < 0) {
528 dev_err(codec->dev, "i2c write failed\n");
529 return ret;
530 }
531
532 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
533 cs4270->supplies);
534
535 return ret;
536}
537
538
539
540
541
542
543
544static int cs4270_remove(struct snd_soc_codec *codec)
545{
546 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
547
548 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
549
550 return 0;
551};
552
553#ifdef CONFIG_PM
554
555
556
557
558
559
560
561
562
563
564static int cs4270_soc_suspend(struct snd_soc_codec *codec)
565{
566 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
567 int reg, ret;
568
569 reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
570 if (reg < 0)
571 return reg;
572
573 ret = snd_soc_write(codec, CS4270_PWRCTL, reg);
574 if (ret < 0)
575 return ret;
576
577 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies),
578 cs4270->supplies);
579
580 return 0;
581}
582
583static int cs4270_soc_resume(struct snd_soc_codec *codec)
584{
585 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
586 int reg, ret;
587
588 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
589 cs4270->supplies);
590 if (ret != 0)
591 return ret;
592
593
594
595 ndelay(500);
596
597
598 regcache_sync(cs4270->regmap);
599
600
601 reg = snd_soc_read(codec, CS4270_PWRCTL);
602 reg &= ~CS4270_PWRCTL_PDN_ALL;
603
604 return snd_soc_write(codec, CS4270_PWRCTL, reg);
605}
606#else
607#define cs4270_soc_suspend NULL
608#define cs4270_soc_resume NULL
609#endif
610
611
612
613
614static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
615 .probe = cs4270_probe,
616 .remove = cs4270_remove,
617 .suspend = cs4270_soc_suspend,
618 .resume = cs4270_soc_resume,
619
620 .component_driver = {
621 .controls = cs4270_snd_controls,
622 .num_controls = ARRAY_SIZE(cs4270_snd_controls),
623 .dapm_widgets = cs4270_dapm_widgets,
624 .num_dapm_widgets = ARRAY_SIZE(cs4270_dapm_widgets),
625 .dapm_routes = cs4270_dapm_routes,
626 .num_dapm_routes = ARRAY_SIZE(cs4270_dapm_routes),
627 },
628};
629
630
631
632
633static const struct of_device_id cs4270_of_match[] = {
634 { .compatible = "cirrus,cs4270", },
635 { }
636};
637MODULE_DEVICE_TABLE(of, cs4270_of_match);
638
639static const struct regmap_config cs4270_regmap = {
640 .reg_bits = 8,
641 .val_bits = 8,
642 .max_register = CS4270_LASTREG,
643 .reg_defaults = cs4270_reg_defaults,
644 .num_reg_defaults = ARRAY_SIZE(cs4270_reg_defaults),
645 .cache_type = REGCACHE_RBTREE,
646
647 .readable_reg = cs4270_reg_is_readable,
648 .volatile_reg = cs4270_reg_is_volatile,
649};
650
651
652
653
654
655
656
657
658
659static int cs4270_i2c_probe(struct i2c_client *i2c_client,
660 const struct i2c_device_id *id)
661{
662 struct device_node *np = i2c_client->dev.of_node;
663 struct cs4270_private *cs4270;
664 unsigned int val;
665 int ret, i;
666
667 cs4270 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs4270_private),
668 GFP_KERNEL);
669 if (!cs4270)
670 return -ENOMEM;
671
672
673 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
674 cs4270->supplies[i].supply = supply_names[i];
675
676 ret = devm_regulator_bulk_get(&i2c_client->dev,
677 ARRAY_SIZE(cs4270->supplies),
678 cs4270->supplies);
679 if (ret < 0)
680 return ret;
681
682
683 if (np) {
684 enum of_gpio_flags flags;
685 int gpio = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags);
686
687 if (gpio_is_valid(gpio)) {
688 ret = devm_gpio_request_one(&i2c_client->dev, gpio,
689 flags & OF_GPIO_ACTIVE_LOW ?
690 GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH,
691 "cs4270 reset");
692 if (ret < 0)
693 return ret;
694 }
695 }
696
697 cs4270->regmap = devm_regmap_init_i2c(i2c_client, &cs4270_regmap);
698 if (IS_ERR(cs4270->regmap))
699 return PTR_ERR(cs4270->regmap);
700
701
702 ret = regmap_read(cs4270->regmap, CS4270_CHIPID, &val);
703 if (ret < 0) {
704 dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
705 i2c_client->addr);
706 return ret;
707 }
708
709 if ((val & 0xF0) != 0xC0) {
710 dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
711 i2c_client->addr);
712 return -ENODEV;
713 }
714
715 dev_info(&i2c_client->dev, "found device at i2c address %X\n",
716 i2c_client->addr);
717 dev_info(&i2c_client->dev, "hardware revision %X\n", val & 0xF);
718
719 i2c_set_clientdata(i2c_client, cs4270);
720
721 ret = snd_soc_register_codec(&i2c_client->dev,
722 &soc_codec_device_cs4270, &cs4270_dai, 1);
723 return ret;
724}
725
726
727
728
729
730
731
732static int cs4270_i2c_remove(struct i2c_client *i2c_client)
733{
734 snd_soc_unregister_codec(&i2c_client->dev);
735 return 0;
736}
737
738
739
740
741static const struct i2c_device_id cs4270_id[] = {
742 {"cs4270", 0},
743 {}
744};
745MODULE_DEVICE_TABLE(i2c, cs4270_id);
746
747
748
749
750
751
752
753static struct i2c_driver cs4270_i2c_driver = {
754 .driver = {
755 .name = "cs4270",
756 .of_match_table = cs4270_of_match,
757 },
758 .id_table = cs4270_id,
759 .probe = cs4270_i2c_probe,
760 .remove = cs4270_i2c_remove,
761};
762
763module_i2c_driver(cs4270_i2c_driver);
764
765MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
766MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver");
767MODULE_LICENSE("GPL");
768