ASoC: cs42l83: Extend CS42L42 support to new part
[platform/kernel/linux-starfive.git] / sound / soc / codecs / cs42l83-i2c.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * cs42l83-i2c.c -- CS42L83 ALSA SoC audio driver for I2C
4  *
5  * Based on cs42l42-i2c.c:
6  *   Copyright 2016, 2022 Cirrus Logic, Inc.
7  */
8
9 #include <linux/i2c.h>
10 #include <linux/module.h>
11 #include <linux/regmap.h>
12 #include <linux/slab.h>
13 #include <linux/types.h>
14
15 #include "cs42l42.h"
16
17 static const struct reg_default cs42l83_reg_defaults[] = {
18         { CS42L42_FRZ_CTL,                      0x00 },
19         { CS42L42_SRC_CTL,                      0x10 },
20         { CS42L42_MCLK_CTL,                     0x00 }, /* <- only deviation from CS42L42 */
21         { CS42L42_SFTRAMP_RATE,                 0xA4 },
22         { CS42L42_SLOW_START_ENABLE,            0x70 },
23         { CS42L42_I2C_DEBOUNCE,                 0x88 },
24         { CS42L42_I2C_STRETCH,                  0x03 },
25         { CS42L42_I2C_TIMEOUT,                  0xB7 },
26         { CS42L42_PWR_CTL1,                     0xFF },
27         { CS42L42_PWR_CTL2,                     0x84 },
28         { CS42L42_PWR_CTL3,                     0x20 },
29         { CS42L42_RSENSE_CTL1,                  0x40 },
30         { CS42L42_RSENSE_CTL2,                  0x00 },
31         { CS42L42_OSC_SWITCH,                   0x00 },
32         { CS42L42_RSENSE_CTL3,                  0x1B },
33         { CS42L42_TSENSE_CTL,                   0x1B },
34         { CS42L42_TSRS_INT_DISABLE,             0x00 },
35         { CS42L42_HSDET_CTL1,                   0x77 },
36         { CS42L42_HSDET_CTL2,                   0x00 },
37         { CS42L42_HS_SWITCH_CTL,                0xF3 },
38         { CS42L42_HS_CLAMP_DISABLE,             0x00 },
39         { CS42L42_MCLK_SRC_SEL,                 0x00 },
40         { CS42L42_SPDIF_CLK_CFG,                0x00 },
41         { CS42L42_FSYNC_PW_LOWER,               0x00 },
42         { CS42L42_FSYNC_PW_UPPER,               0x00 },
43         { CS42L42_FSYNC_P_LOWER,                0xF9 },
44         { CS42L42_FSYNC_P_UPPER,                0x00 },
45         { CS42L42_ASP_CLK_CFG,                  0x00 },
46         { CS42L42_ASP_FRM_CFG,                  0x10 },
47         { CS42L42_FS_RATE_EN,                   0x00 },
48         { CS42L42_IN_ASRC_CLK,                  0x00 },
49         { CS42L42_OUT_ASRC_CLK,                 0x00 },
50         { CS42L42_PLL_DIV_CFG1,                 0x00 },
51         { CS42L42_ADC_OVFL_INT_MASK,            0x01 },
52         { CS42L42_MIXER_INT_MASK,               0x0F },
53         { CS42L42_SRC_INT_MASK,                 0x0F },
54         { CS42L42_ASP_RX_INT_MASK,              0x1F },
55         { CS42L42_ASP_TX_INT_MASK,              0x0F },
56         { CS42L42_CODEC_INT_MASK,               0x03 },
57         { CS42L42_SRCPL_INT_MASK,               0x7F },
58         { CS42L42_VPMON_INT_MASK,               0x01 },
59         { CS42L42_PLL_LOCK_INT_MASK,            0x01 },
60         { CS42L42_TSRS_PLUG_INT_MASK,           0x0F },
61         { CS42L42_PLL_CTL1,                     0x00 },
62         { CS42L42_PLL_DIV_FRAC0,                0x00 },
63         { CS42L42_PLL_DIV_FRAC1,                0x00 },
64         { CS42L42_PLL_DIV_FRAC2,                0x00 },
65         { CS42L42_PLL_DIV_INT,                  0x40 },
66         { CS42L42_PLL_CTL3,                     0x10 },
67         { CS42L42_PLL_CAL_RATIO,                0x80 },
68         { CS42L42_PLL_CTL4,                     0x03 },
69         { CS42L42_LOAD_DET_EN,                  0x00 },
70         { CS42L42_HSBIAS_SC_AUTOCTL,            0x03 },
71         { CS42L42_WAKE_CTL,                     0xC0 },
72         { CS42L42_ADC_DISABLE_MUTE,             0x00 },
73         { CS42L42_TIPSENSE_CTL,                 0x02 },
74         { CS42L42_MISC_DET_CTL,                 0x03 },
75         { CS42L42_MIC_DET_CTL1,                 0x1F },
76         { CS42L42_MIC_DET_CTL2,                 0x2F },
77         { CS42L42_DET_INT1_MASK,                0xE0 },
78         { CS42L42_DET_INT2_MASK,                0xFF },
79         { CS42L42_HS_BIAS_CTL,                  0xC2 },
80         { CS42L42_ADC_CTL,                      0x00 },
81         { CS42L42_ADC_VOLUME,                   0x00 },
82         { CS42L42_ADC_WNF_HPF_CTL,              0x71 },
83         { CS42L42_DAC_CTL1,                     0x00 },
84         { CS42L42_DAC_CTL2,                     0x02 },
85         { CS42L42_HP_CTL,                       0x0D },
86         { CS42L42_CLASSH_CTL,                   0x07 },
87         { CS42L42_MIXER_CHA_VOL,                0x3F },
88         { CS42L42_MIXER_ADC_VOL,                0x3F },
89         { CS42L42_MIXER_CHB_VOL,                0x3F },
90         { CS42L42_EQ_COEF_IN0,                  0x00 },
91         { CS42L42_EQ_COEF_IN1,                  0x00 },
92         { CS42L42_EQ_COEF_IN2,                  0x00 },
93         { CS42L42_EQ_COEF_IN3,                  0x00 },
94         { CS42L42_EQ_COEF_RW,                   0x00 },
95         { CS42L42_EQ_COEF_OUT0,                 0x00 },
96         { CS42L42_EQ_COEF_OUT1,                 0x00 },
97         { CS42L42_EQ_COEF_OUT2,                 0x00 },
98         { CS42L42_EQ_COEF_OUT3,                 0x00 },
99         { CS42L42_EQ_INIT_STAT,                 0x00 },
100         { CS42L42_EQ_START_FILT,                0x00 },
101         { CS42L42_EQ_MUTE_CTL,                  0x00 },
102         { CS42L42_SP_RX_CH_SEL,                 0x04 },
103         { CS42L42_SP_RX_ISOC_CTL,               0x04 },
104         { CS42L42_SP_RX_FS,                     0x8C },
105         { CS42l42_SPDIF_CH_SEL,                 0x0E },
106         { CS42L42_SP_TX_ISOC_CTL,               0x04 },
107         { CS42L42_SP_TX_FS,                     0xCC },
108         { CS42L42_SPDIF_SW_CTL1,                0x3F },
109         { CS42L42_SRC_SDIN_FS,                  0x40 },
110         { CS42L42_SRC_SDOUT_FS,                 0x40 },
111         { CS42L42_SPDIF_CTL1,                   0x01 },
112         { CS42L42_SPDIF_CTL2,                   0x00 },
113         { CS42L42_SPDIF_CTL3,                   0x00 },
114         { CS42L42_SPDIF_CTL4,                   0x42 },
115         { CS42L42_ASP_TX_SZ_EN,                 0x00 },
116         { CS42L42_ASP_TX_CH_EN,                 0x00 },
117         { CS42L42_ASP_TX_CH_AP_RES,             0x0F },
118         { CS42L42_ASP_TX_CH1_BIT_MSB,           0x00 },
119         { CS42L42_ASP_TX_CH1_BIT_LSB,           0x00 },
120         { CS42L42_ASP_TX_HIZ_DLY_CFG,           0x00 },
121         { CS42L42_ASP_TX_CH2_BIT_MSB,           0x00 },
122         { CS42L42_ASP_TX_CH2_BIT_LSB,           0x00 },
123         { CS42L42_ASP_RX_DAI0_EN,               0x00 },
124         { CS42L42_ASP_RX_DAI0_CH1_AP_RES,       0x03 },
125         { CS42L42_ASP_RX_DAI0_CH1_BIT_MSB,      0x00 },
126         { CS42L42_ASP_RX_DAI0_CH1_BIT_LSB,      0x00 },
127         { CS42L42_ASP_RX_DAI0_CH2_AP_RES,       0x03 },
128         { CS42L42_ASP_RX_DAI0_CH2_BIT_MSB,      0x00 },
129         { CS42L42_ASP_RX_DAI0_CH2_BIT_LSB,      0x00 },
130         { CS42L42_ASP_RX_DAI0_CH3_AP_RES,       0x03 },
131         { CS42L42_ASP_RX_DAI0_CH3_BIT_MSB,      0x00 },
132         { CS42L42_ASP_RX_DAI0_CH3_BIT_LSB,      0x00 },
133         { CS42L42_ASP_RX_DAI0_CH4_AP_RES,       0x03 },
134         { CS42L42_ASP_RX_DAI0_CH4_BIT_MSB,      0x00 },
135         { CS42L42_ASP_RX_DAI0_CH4_BIT_LSB,      0x00 },
136         { CS42L42_ASP_RX_DAI1_CH1_AP_RES,       0x03 },
137         { CS42L42_ASP_RX_DAI1_CH1_BIT_MSB,      0x00 },
138         { CS42L42_ASP_RX_DAI1_CH1_BIT_LSB,      0x00 },
139         { CS42L42_ASP_RX_DAI1_CH2_AP_RES,       0x03 },
140         { CS42L42_ASP_RX_DAI1_CH2_BIT_MSB,      0x00 },
141         { CS42L42_ASP_RX_DAI1_CH2_BIT_LSB,      0x00 },
142 };
143
144 /*
145  * This is all the same as for CS42L42 but we
146  * replace the on-reset register defaults.
147  */
148 const struct regmap_config cs42l83_regmap = {
149         .reg_bits = 8,
150         .val_bits = 8,
151
152         .readable_reg = cs42l42_readable_register,
153         .volatile_reg = cs42l42_volatile_register,
154
155         .ranges = &cs42l42_page_range,
156         .num_ranges = 1,
157
158         .max_register = CS42L42_MAX_REGISTER,
159         .reg_defaults = cs42l83_reg_defaults,
160         .num_reg_defaults = ARRAY_SIZE(cs42l83_reg_defaults),
161         .cache_type = REGCACHE_RBTREE,
162
163         .use_single_read = true,
164         .use_single_write = true,
165 };
166
167 static int cs42l83_i2c_probe(struct i2c_client *i2c_client)
168 {
169         struct device *dev = &i2c_client->dev;
170         struct cs42l42_private *cs42l83;
171         struct regmap *regmap;
172         int ret;
173
174         cs42l83 = devm_kzalloc(dev, sizeof(*cs42l83), GFP_KERNEL);
175         if (!cs42l83)
176                 return -ENOMEM;
177
178         regmap = devm_regmap_init_i2c(i2c_client, &cs42l83_regmap);
179         if (IS_ERR(regmap))
180                 return dev_err_probe(&i2c_client->dev, PTR_ERR(regmap),
181                                      "regmap_init() failed\n");
182
183         cs42l83->devid = CS42L83_CHIP_ID;
184         cs42l83->dev = dev;
185         cs42l83->regmap = regmap;
186         cs42l83->irq = i2c_client->irq;
187
188         ret = cs42l42_common_probe(cs42l83, &cs42l42_soc_component, &cs42l42_dai);
189         if (ret)
190                 return ret;
191
192         return cs42l42_init(cs42l83);
193 }
194
195 static int cs42l83_i2c_remove(struct i2c_client *i2c_client)
196 {
197         struct cs42l42_private *cs42l83 = dev_get_drvdata(&i2c_client->dev);
198
199         cs42l42_common_remove(cs42l83);
200
201         return 0;
202 }
203
204 static int __maybe_unused cs42l83_i2c_resume(struct device *dev)
205 {
206         int ret;
207
208         ret = cs42l42_resume(dev);
209         if (ret)
210                 return ret;
211
212         cs42l42_resume_restore(dev);
213
214         return 0;
215 }
216
217 static const struct dev_pm_ops cs42l83_i2c_pm_ops = {
218         SET_SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l83_i2c_resume)
219 };
220
221 static const struct of_device_id __maybe_unused cs42l83_of_match[] = {
222         { .compatible = "cirrus,cs42l83", },
223         {}
224 };
225 MODULE_DEVICE_TABLE(of, cs42l83_of_match);
226
227 static struct i2c_driver cs42l83_i2c_driver = {
228         .driver = {
229                 .name = "cs42l83",
230                 .pm = &cs42l83_i2c_pm_ops,
231                 .of_match_table = of_match_ptr(cs42l83_of_match),
232                 },
233         .probe_new = cs42l83_i2c_probe,
234         .remove = cs42l83_i2c_remove,
235 };
236
237 module_i2c_driver(cs42l83_i2c_driver);
238
239 MODULE_DESCRIPTION("ASoC CS42L83 I2C driver");
240 MODULE_AUTHOR("Martin PoviĊĦer <povik+lin@cutebit.org>");
241 MODULE_LICENSE("GPL");
242 MODULE_IMPORT_NS(SND_SOC_CS42L42_CORE);