This source file includes following definitions.
- cs4270_reg_is_readable
- cs4270_reg_is_volatile
- cs4270_set_dai_sysclk
- cs4270_set_dai_fmt
- cs4270_hw_params
- cs4270_dai_mute
- cs4270_soc_put_mute
- cs4270_probe
- cs4270_remove
- cs4270_soc_suspend
- cs4270_soc_resume
- cs4270_i2c_probe
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/gpio/consumer.h>
33 #include <linux/of_device.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
116 static 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
126 static const char *supply_names[] = {
127 "va", "vd", "vlc"
128 };
129
130
131 struct 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
142 static const struct snd_soc_dapm_widget cs4270_dapm_widgets[] = {
143 SND_SOC_DAPM_INPUT("AINL"),
144 SND_SOC_DAPM_INPUT("AINR"),
145
146 SND_SOC_DAPM_OUTPUT("AOUTL"),
147 SND_SOC_DAPM_OUTPUT("AOUTR"),
148 };
149
150 static 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
190 struct cs4270_mode_ratios {
191 unsigned int ratio;
192 u8 speed_mode;
193 u8 mclk;
194 };
195
196 static 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
213 static bool cs4270_reg_is_readable(struct device *dev, unsigned int reg)
214 {
215 return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG);
216 }
217
218 static bool cs4270_reg_is_volatile(struct device *dev, unsigned int reg)
219 {
220
221 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
222 return true;
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
254 static 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_component *component = codec_dai->component;
258 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
259
260 cs4270->mclk = freq;
261 return 0;
262 }
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277 static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
278 unsigned int format)
279 {
280 struct snd_soc_component *component = codec_dai->component;
281 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
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(component->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(component->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
325 static 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_component *component = dai->component;
330 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
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(component->dev, "could not find matching ratio\n");
350 return -EINVAL;
351 }
352
353
354
355 reg = snd_soc_component_read32(component, 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_component_write(component, CS4270_MODE, reg);
365 if (ret < 0) {
366 dev_err(component->dev, "i2c write failed\n");
367 return ret;
368 }
369
370
371
372 reg = snd_soc_component_read32(component, 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(component->dev, "unknown dai format\n");
384 return -EINVAL;
385 }
386
387 ret = snd_soc_component_write(component, CS4270_FORMAT, reg);
388 if (ret < 0) {
389 dev_err(component->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
406 static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
407 {
408 struct snd_soc_component *component = dai->component;
409 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
410 int reg6;
411
412 reg6 = snd_soc_component_read32(component, 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_component_write(component, CS4270_MUTE, reg6);
422 }
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438 static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol,
439 struct snd_ctl_elem_value *ucontrol)
440 {
441 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
442 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
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
453 static 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
467 static 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
474 static 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
504 static int cs4270_probe(struct snd_soc_component *component)
505 {
506 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
507 int ret;
508
509
510
511
512
513
514 ret = snd_soc_component_update_bits(component, CS4270_MUTE, CS4270_MUTE_AUTO, 0);
515 if (ret < 0) {
516 dev_err(component->dev, "i2c write failed\n");
517 return ret;
518 }
519
520
521
522
523
524
525 ret = snd_soc_component_update_bits(component, CS4270_TRANS,
526 CS4270_TRANS_SOFT | CS4270_TRANS_ZERO, 0);
527 if (ret < 0) {
528 dev_err(component->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
544 static void cs4270_remove(struct snd_soc_component *component)
545 {
546 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
547
548 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
549 };
550
551 #ifdef CONFIG_PM
552
553
554
555
556
557
558
559
560
561
562 static int cs4270_soc_suspend(struct snd_soc_component *component)
563 {
564 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
565 int reg, ret;
566
567 reg = snd_soc_component_read32(component, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
568 if (reg < 0)
569 return reg;
570
571 ret = snd_soc_component_write(component, CS4270_PWRCTL, reg);
572 if (ret < 0)
573 return ret;
574
575 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies),
576 cs4270->supplies);
577
578 return 0;
579 }
580
581 static int cs4270_soc_resume(struct snd_soc_component *component)
582 {
583 struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
584 int reg, ret;
585
586 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
587 cs4270->supplies);
588 if (ret != 0)
589 return ret;
590
591
592
593 ndelay(500);
594
595
596 regcache_sync(cs4270->regmap);
597
598
599 reg = snd_soc_component_read32(component, CS4270_PWRCTL);
600 reg &= ~CS4270_PWRCTL_PDN_ALL;
601
602 return snd_soc_component_write(component, CS4270_PWRCTL, reg);
603 }
604 #else
605 #define cs4270_soc_suspend NULL
606 #define cs4270_soc_resume NULL
607 #endif
608
609
610
611
612 static const struct snd_soc_component_driver soc_component_device_cs4270 = {
613 .probe = cs4270_probe,
614 .remove = cs4270_remove,
615 .suspend = cs4270_soc_suspend,
616 .resume = cs4270_soc_resume,
617 .controls = cs4270_snd_controls,
618 .num_controls = ARRAY_SIZE(cs4270_snd_controls),
619 .dapm_widgets = cs4270_dapm_widgets,
620 .num_dapm_widgets = ARRAY_SIZE(cs4270_dapm_widgets),
621 .dapm_routes = cs4270_dapm_routes,
622 .num_dapm_routes = ARRAY_SIZE(cs4270_dapm_routes),
623 .idle_bias_on = 1,
624 .use_pmdown_time = 1,
625 .endianness = 1,
626 .non_legacy_dai_naming = 1,
627 };
628
629
630
631
632 static const struct of_device_id cs4270_of_match[] = {
633 { .compatible = "cirrus,cs4270", },
634 { }
635 };
636 MODULE_DEVICE_TABLE(of, cs4270_of_match);
637
638 static const struct regmap_config cs4270_regmap = {
639 .reg_bits = 8,
640 .val_bits = 8,
641 .max_register = CS4270_LASTREG,
642 .reg_defaults = cs4270_reg_defaults,
643 .num_reg_defaults = ARRAY_SIZE(cs4270_reg_defaults),
644 .cache_type = REGCACHE_RBTREE,
645 .write_flag_mask = CS4270_I2C_INCR,
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
659 static int cs4270_i2c_probe(struct i2c_client *i2c_client,
660 const struct i2c_device_id *id)
661 {
662 struct cs4270_private *cs4270;
663 struct gpio_desc *reset_gpiod;
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 reset_gpiod = devm_gpiod_get_optional(&i2c_client->dev, "reset",
683 GPIOD_OUT_HIGH);
684 if (IS_ERR(reset_gpiod) &&
685 PTR_ERR(reset_gpiod) == -EPROBE_DEFER)
686 return -EPROBE_DEFER;
687
688 cs4270->regmap = devm_regmap_init_i2c(i2c_client, &cs4270_regmap);
689 if (IS_ERR(cs4270->regmap))
690 return PTR_ERR(cs4270->regmap);
691
692
693 ret = regmap_read(cs4270->regmap, CS4270_CHIPID, &val);
694 if (ret < 0) {
695 dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
696 i2c_client->addr);
697 return ret;
698 }
699
700 if ((val & 0xF0) != 0xC0) {
701 dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
702 i2c_client->addr);
703 return -ENODEV;
704 }
705
706 dev_info(&i2c_client->dev, "found device at i2c address %X\n",
707 i2c_client->addr);
708 dev_info(&i2c_client->dev, "hardware revision %X\n", val & 0xF);
709
710 i2c_set_clientdata(i2c_client, cs4270);
711
712 ret = devm_snd_soc_register_component(&i2c_client->dev,
713 &soc_component_device_cs4270, &cs4270_dai, 1);
714 return ret;
715 }
716
717
718
719
720 static const struct i2c_device_id cs4270_id[] = {
721 {"cs4270", 0},
722 {}
723 };
724 MODULE_DEVICE_TABLE(i2c, cs4270_id);
725
726
727
728
729
730
731
732 static struct i2c_driver cs4270_i2c_driver = {
733 .driver = {
734 .name = "cs4270",
735 .of_match_table = cs4270_of_match,
736 },
737 .id_table = cs4270_id,
738 .probe = cs4270_i2c_probe,
739 };
740
741 module_i2c_driver(cs4270_i2c_driver);
742
743 MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
744 MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver");
745 MODULE_LICENSE("GPL");