24 #include <linux/module.h>
25 #include <linux/slab.h>
29 #include <linux/i2c.h>
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)
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
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
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
116 static const struct reg_default cs4270_reg_defaults[] = {
126 static const char *supply_names[] = {
182 #ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA
195 #define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios)
197 static bool cs4270_reg_is_readable(
struct device *
dev,
unsigned int reg)
202 static bool cs4270_reg_is_volatile(
struct device *
dev,
unsigned int reg)
238 static int cs4270_set_dai_sysclk(
struct snd_soc_dai *codec_dai,
239 int clk_id,
unsigned int freq,
int dir)
261 static int cs4270_set_dai_fmt(
struct snd_soc_dai *codec_dai,
288 dev_err(codec->
dev,
"Unknown master/slave configuration\n");
327 if (cs4270_mode_ratios[i].ratio == ratio)
331 if (i == NUM_MCLK_RATIOS) {
333 dev_err(codec->
dev,
"could not find matching ratio\n");
341 reg |= cs4270_mode_ratios[
i].
mclk;
359 switch (cs4270->
mode) {
422 static int cs4270_soc_put_mute(
struct snd_kcontrol *kcontrol,
427 int left = !ucontrol->
value.integer.value[0];
428 int right = !ucontrol->
value.integer.value[1];
452 .hw_params = cs4270_hw_params,
453 .set_sysclk = cs4270_set_dai_sysclk,
454 .set_fmt = cs4270_set_dai_fmt,
455 .digital_mute = cs4270_dai_mute,
459 .name =
"cs4270-hifi",
461 .stream_name =
"Playback",
470 .stream_name =
"Capture",
478 .ops = &cs4270_dai_ops,
498 dev_err(codec->
dev,
"failed to set cache I/O (ret=%i)\n", ret);
600 #define cs4270_soc_suspend NULL
601 #define cs4270_soc_resume NULL
608 .probe = cs4270_probe,
609 .remove = cs4270_remove,
613 .controls = cs4270_snd_controls,
614 .num_controls =
ARRAY_SIZE(cs4270_snd_controls),
621 { .compatible =
"cirrus,cs4270", },
626 static const struct regmap_config cs4270_regmap = {
630 .reg_defaults = cs4270_reg_defaults,
631 .num_reg_defaults =
ARRAY_SIZE(cs4270_reg_defaults),
634 .readable_reg = cs4270_reg_is_readable,
635 .volatile_reg = cs4270_reg_is_volatile,
657 dev_err(&i2c_client->
dev,
"could not allocate codec\n");
662 for (i = 0; i <
ARRAY_SIZE(supply_names); i++)
663 cs4270->
supplies[i].supply = supply_names[i];
676 if (gpio_is_valid(gpio)) {
687 if (IS_ERR(cs4270->
regmap))
688 return PTR_ERR(cs4270->
regmap);
693 dev_err(&i2c_client->
dev,
"failed to read i2c at addr %X\n",
698 if ((val & 0xF0) != 0xC0) {
699 dev_err(&i2c_client->
dev,
"device at addr %X is not a CS4270\n",
704 dev_info(&i2c_client->
dev,
"found device at i2c address %X\n",
706 dev_info(&i2c_client->
dev,
"hardware revision %X\n", val & 0xF);
708 i2c_set_clientdata(i2c_client, cs4270);
711 &soc_codec_device_cs4270, &cs4270_dai, 1);
721 static int cs4270_i2c_remove(
struct i2c_client *i2c_client)
742 static struct i2c_driver cs4270_i2c_driver = {
746 .of_match_table = cs4270_of_match,
748 .id_table = cs4270_id,
749 .probe = cs4270_i2c_probe,
750 .remove = cs4270_i2c_remove,