aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLi Xu <li.xu@cirrus.com>2017-08-18 12:00:19 -0400
committerMark Brown <broonie@kernel.org>2017-09-01 06:44:43 -0400
commit8f1e5bf9b4408e91942b94c76583eaf098f19382 (patch)
tree15c2c51830a828a4cebc457c0bbb2ce99aebe977
parent5771a8c08880cdca3bfb4a3fc6d309d6bba20877 (diff)
ASoC: cs43130: Add support for CS43130 codec
Add support for Cirrus Logic CS43130 codec. Support: I2S/DSP PCM playback. DoP/DSD playback. HP detection and DC/AC impedance measurement. Signed-off-by: Li Xu <li.xu@cirrus.com> Acked-by: Brian Austin <brian.austin@cirrus.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/codecs/Kconfig6
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/cs43130.c2690
-rw-r--r--sound/soc/codecs/cs43130.h546
4 files changed, 3244 insertions, 0 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 6c78b0b49b81..ea7a2d540e5e 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -60,6 +60,7 @@ config SND_SOC_ALL_CODECS
60 select SND_SOC_CS4271_I2C if I2C 60 select SND_SOC_CS4271_I2C if I2C
61 select SND_SOC_CS4271_SPI if SPI_MASTER 61 select SND_SOC_CS4271_SPI if SPI_MASTER
62 select SND_SOC_CS42XX8_I2C if I2C 62 select SND_SOC_CS42XX8_I2C if I2C
63 select SND_SOC_CS43130 if I2C
63 select SND_SOC_CS4349 if I2C 64 select SND_SOC_CS4349 if I2C
64 select SND_SOC_CS47L24 if MFD_CS47L24 65 select SND_SOC_CS47L24 if MFD_CS47L24
65 select SND_SOC_CS53L30 if I2C 66 select SND_SOC_CS53L30 if I2C
@@ -486,6 +487,11 @@ config SND_SOC_CS42XX8_I2C
486 select SND_SOC_CS42XX8 487 select SND_SOC_CS42XX8
487 select REGMAP_I2C 488 select REGMAP_I2C
488 489
490# Cirrus Logic CS43130 HiFi DAC
491config SND_SOC_CS43130
492 tristate "Cirrus Logic CS43130 CODEC"
493 depends on I2C
494
489# Cirrus Logic CS4349 HiFi DAC 495# Cirrus Logic CS4349 HiFi DAC
490config SND_SOC_CS4349 496config SND_SOC_CS4349
491 tristate "Cirrus Logic CS4349 CODEC" 497 tristate "Cirrus Logic CS4349 CODEC"
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 1755a54e3dc9..5030e1f440d4 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -53,6 +53,7 @@ snd-soc-cs4271-i2c-objs := cs4271-i2c.o
53snd-soc-cs4271-spi-objs := cs4271-spi.o 53snd-soc-cs4271-spi-objs := cs4271-spi.o
54snd-soc-cs42xx8-objs := cs42xx8.o 54snd-soc-cs42xx8-objs := cs42xx8.o
55snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o 55snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o
56snd-soc-cs43130-objs := cs43130.o
56snd-soc-cs4349-objs := cs4349.o 57snd-soc-cs4349-objs := cs4349.o
57snd-soc-cs47l24-objs := cs47l24.o 58snd-soc-cs47l24-objs := cs47l24.o
58snd-soc-cs53l30-objs := cs53l30.o 59snd-soc-cs53l30-objs := cs53l30.o
@@ -290,6 +291,7 @@ obj-$(CONFIG_SND_SOC_CS4271_I2C) += snd-soc-cs4271-i2c.o
290obj-$(CONFIG_SND_SOC_CS4271_SPI) += snd-soc-cs4271-spi.o 291obj-$(CONFIG_SND_SOC_CS4271_SPI) += snd-soc-cs4271-spi.o
291obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o 292obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o
292obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o 293obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o
294obj-$(CONFIG_SND_SOC_CS43130) += snd-soc-cs43130.o
293obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o 295obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o
294obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o 296obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o
295obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o 297obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o
diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c
new file mode 100644
index 000000000000..220e30199c5b
--- /dev/null
+++ b/sound/soc/codecs/cs43130.c
@@ -0,0 +1,2690 @@
1/*
2 * cs43130.c -- CS43130 ALSA Soc Audio driver
3 *
4 * Copyright 2017 Cirrus Logic, Inc.
5 *
6 * Authors: Li Xu <li.xu@cirrus.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/gpio.h>
18#include <linux/gpio/consumer.h>
19#include <linux/platform_device.h>
20#include <linux/pm.h>
21#include <linux/i2c.h>
22#include <linux/of_device.h>
23#include <linux/regmap.h>
24#include <linux/slab.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/initval.h>
31#include <sound/tlv.h>
32#include <linux/of_gpio.h>
33#include <linux/regulator/consumer.h>
34#include <linux/pm_runtime.h>
35#include <linux/of_irq.h>
36#include <linux/completion.h>
37#include <linux/mutex.h>
38#include <linux/workqueue.h>
39#include <sound/jack.h>
40
41#include "cs43130.h"
42
43static const struct reg_default cs43130_reg_defaults[] = {
44 {CS43130_SYS_CLK_CTL_1, 0x06},
45 {CS43130_SP_SRATE, 0x01},
46 {CS43130_SP_BITSIZE, 0x05},
47 {CS43130_PAD_INT_CFG, 0x03},
48 {CS43130_PWDN_CTL, 0xFE},
49 {CS43130_CRYSTAL_SET, 0x04},
50 {CS43130_PLL_SET_1, 0x00},
51 {CS43130_PLL_SET_2, 0x00},
52 {CS43130_PLL_SET_3, 0x00},
53 {CS43130_PLL_SET_4, 0x00},
54 {CS43130_PLL_SET_5, 0x40},
55 {CS43130_PLL_SET_6, 0x10},
56 {CS43130_PLL_SET_7, 0x80},
57 {CS43130_PLL_SET_8, 0x03},
58 {CS43130_PLL_SET_9, 0x02},
59 {CS43130_PLL_SET_10, 0x02},
60 {CS43130_CLKOUT_CTL, 0x00},
61 {CS43130_ASP_NUM_1, 0x01},
62 {CS43130_ASP_NUM_2, 0x00},
63 {CS43130_ASP_DEN_1, 0x08},
64 {CS43130_ASP_DEN_2, 0x00},
65 {CS43130_ASP_LRCK_HI_TIME_1, 0x1F},
66 {CS43130_ASP_LRCK_HI_TIME_2, 0x00},
67 {CS43130_ASP_LRCK_PERIOD_1, 0x3F},
68 {CS43130_ASP_LRCK_PERIOD_2, 0x00},
69 {CS43130_ASP_CLOCK_CONF, 0x0C},
70 {CS43130_ASP_FRAME_CONF, 0x0A},
71 {CS43130_XSP_NUM_1, 0x01},
72 {CS43130_XSP_NUM_2, 0x00},
73 {CS43130_XSP_DEN_1, 0x02},
74 {CS43130_XSP_DEN_2, 0x00},
75 {CS43130_XSP_LRCK_HI_TIME_1, 0x1F},
76 {CS43130_XSP_LRCK_HI_TIME_2, 0x00},
77 {CS43130_XSP_LRCK_PERIOD_1, 0x3F},
78 {CS43130_XSP_LRCK_PERIOD_2, 0x00},
79 {CS43130_XSP_CLOCK_CONF, 0x0C},
80 {CS43130_XSP_FRAME_CONF, 0x0A},
81 {CS43130_ASP_CH_1_LOC, 0x00},
82 {CS43130_ASP_CH_2_LOC, 0x00},
83 {CS43130_ASP_CH_1_SZ_EN, 0x06},
84 {CS43130_ASP_CH_2_SZ_EN, 0x0E},
85 {CS43130_XSP_CH_1_LOC, 0x00},
86 {CS43130_XSP_CH_2_LOC, 0x00},
87 {CS43130_XSP_CH_1_SZ_EN, 0x06},
88 {CS43130_XSP_CH_2_SZ_EN, 0x0E},
89 {CS43130_DSD_VOL_B, 0x78},
90 {CS43130_DSD_VOL_A, 0x78},
91 {CS43130_DSD_PATH_CTL_1, 0xA8},
92 {CS43130_DSD_INT_CFG, 0x00},
93 {CS43130_DSD_PATH_CTL_2, 0x02},
94 {CS43130_DSD_PCM_MIX_CTL, 0x00},
95 {CS43130_DSD_PATH_CTL_3, 0x40},
96 {CS43130_HP_OUT_CTL_1, 0x30},
97 {CS43130_PCM_FILT_OPT, 0x02},
98 {CS43130_PCM_VOL_B, 0x78},
99 {CS43130_PCM_VOL_A, 0x78},
100 {CS43130_PCM_PATH_CTL_1, 0xA8},
101 {CS43130_PCM_PATH_CTL_2, 0x00},
102 {CS43130_CLASS_H_CTL, 0x1E},
103 {CS43130_HP_DETECT, 0x04},
104 {CS43130_HP_LOAD_1, 0x00},
105 {CS43130_HP_MEAS_LOAD_1, 0x00},
106 {CS43130_HP_MEAS_LOAD_2, 0x00},
107 {CS43130_INT_MASK_1, 0xFF},
108 {CS43130_INT_MASK_2, 0xFF},
109 {CS43130_INT_MASK_3, 0xFF},
110 {CS43130_INT_MASK_4, 0xFF},
111 {CS43130_INT_MASK_5, 0xFF},
112};
113
114static bool cs43130_volatile_register(struct device *dev, unsigned int reg)
115{
116 switch (reg) {
117 case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5:
118 case CS43130_HP_DC_STAT_1 ... CS43130_HP_DC_STAT_2:
119 case CS43130_HP_AC_STAT_1 ... CS43130_HP_AC_STAT_2:
120 return true;
121 default:
122 return false;
123 }
124}
125
126static bool cs43130_readable_register(struct device *dev, unsigned int reg)
127{
128 switch (reg) {
129 case CS43130_DEVID_AB ... CS43130_SYS_CLK_CTL_1:
130 case CS43130_SP_SRATE ... CS43130_PAD_INT_CFG:
131 case CS43130_PWDN_CTL:
132 case CS43130_CRYSTAL_SET:
133 case CS43130_PLL_SET_1 ... CS43130_PLL_SET_5:
134 case CS43130_PLL_SET_6:
135 case CS43130_PLL_SET_7:
136 case CS43130_PLL_SET_8:
137 case CS43130_PLL_SET_9:
138 case CS43130_PLL_SET_10:
139 case CS43130_CLKOUT_CTL:
140 case CS43130_ASP_NUM_1 ... CS43130_ASP_FRAME_CONF:
141 case CS43130_XSP_NUM_1 ... CS43130_XSP_FRAME_CONF:
142 case CS43130_ASP_CH_1_LOC:
143 case CS43130_ASP_CH_2_LOC:
144 case CS43130_ASP_CH_1_SZ_EN:
145 case CS43130_ASP_CH_2_SZ_EN:
146 case CS43130_XSP_CH_1_LOC:
147 case CS43130_XSP_CH_2_LOC:
148 case CS43130_XSP_CH_1_SZ_EN:
149 case CS43130_XSP_CH_2_SZ_EN:
150 case CS43130_DSD_VOL_B ... CS43130_DSD_PATH_CTL_3:
151 case CS43130_HP_OUT_CTL_1:
152 case CS43130_PCM_FILT_OPT ... CS43130_PCM_PATH_CTL_2:
153 case CS43130_CLASS_H_CTL:
154 case CS43130_HP_DETECT:
155 case CS43130_HP_STATUS:
156 case CS43130_HP_LOAD_1:
157 case CS43130_HP_MEAS_LOAD_1:
158 case CS43130_HP_MEAS_LOAD_2:
159 case CS43130_HP_DC_STAT_1:
160 case CS43130_HP_DC_STAT_2:
161 case CS43130_HP_AC_STAT_1:
162 case CS43130_HP_AC_STAT_2:
163 case CS43130_HP_LOAD_STAT:
164 case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5:
165 case CS43130_INT_MASK_1 ... CS43130_INT_MASK_5:
166 return true;
167 default:
168 return false;
169 }
170}
171
172static bool cs43130_precious_register(struct device *dev, unsigned int reg)
173{
174 switch (reg) {
175 case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5:
176 return true;
177 default:
178 return false;
179 }
180}
181
182struct cs43130_pll_params {
183 unsigned int pll_in;
184 u8 sclk_prediv;
185 u8 pll_div_int;
186 u32 pll_div_frac;
187 u8 pll_mode;
188 u8 pll_divout;
189 unsigned int pll_out;
190 u8 pll_cal_ratio;
191};
192
193static const struct cs43130_pll_params pll_ratio_table[] = {
194 {9600000, 0x02, 0x49, 0x800000, 0x00, 0x08, 22579200, 151},
195 {9600000, 0x02, 0x50, 0x000000, 0x00, 0x08, 24576000, 164},
196
197 {11289600, 0x02, 0X40, 0, 0x01, 0x08, 22579200, 128},
198 {11289600, 0x02, 0x44, 0x06F700, 0x0, 0x08, 24576000, 139},
199
200 {12000000, 0x02, 0x49, 0x800000, 0x00, 0x0A, 22579200, 120},
201 {12000000, 0x02, 0x40, 0x000000, 0x00, 0x08, 24576000, 131},
202
203 {12288000, 0x02, 0x49, 0x800000, 0x01, 0x0A, 22579200, 118},
204 {12288000, 0x02, 0x40, 0x000000, 0x01, 0x08, 24576000, 128},
205
206 {13000000, 0x02, 0x45, 0x797680, 0x01, 0x0A, 22579200, 111},
207 {13000000, 0x02, 0x3C, 0x7EA940, 0x01, 0x08, 24576000, 121},
208
209 {19200000, 0x03, 0x49, 0x800000, 0x00, 0x08, 22579200, 151},
210 {19200000, 0x03, 0x50, 0x000000, 0x00, 0x08, 24576000, 164},
211
212 {22579200, 0, 0, 0, 0, 0, 22579200, 0},
213 {22579200, 0x03, 0x44, 0x06F700, 0x00, 0x08, 24576000, 139},
214
215 {24000000, 0x03, 0x49, 0x800000, 0x00, 0x0A, 22579200, 120},
216 {24000000, 0x03, 0x40, 0x000000, 0x00, 0x08, 24576000, 131},
217
218 {24576000, 0x03, 0x49, 0x800000, 0x01, 0x0A, 22579200, 118},
219 {24576000, 0, 0, 0, 0, 0, 24576000, 0},
220
221 {26000000, 0x03, 0x45, 0x797680, 0x01, 0x0A, 22579200, 111},
222 {26000000, 0x03, 0x3C, 0x7EA940, 0x01, 0x08, 24576000, 121},
223};
224
225static const struct cs43130_pll_params *cs43130_get_pll_table(
226 unsigned int freq_in, unsigned int freq_out)
227{
228 int i;
229
230 for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) {
231 if (pll_ratio_table[i].pll_in == freq_in &&
232 pll_ratio_table[i].pll_out == freq_out)
233 return &pll_ratio_table[i];
234 }
235
236 return NULL;
237}
238
239static int cs43130_pll_config(struct snd_soc_codec *codec)
240{
241 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
242 const struct cs43130_pll_params *pll_entry;
243
244 dev_dbg(codec->dev, "cs43130->mclk = %u, cs43130->mclk_int = %u\n",
245 cs43130->mclk, cs43130->mclk_int);
246
247 pll_entry = cs43130_get_pll_table(cs43130->mclk, cs43130->mclk_int);
248 if (!pll_entry)
249 return -EINVAL;
250
251 if (pll_entry->pll_cal_ratio == 0) {
252 regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_1,
253 CS43130_PLL_START_MASK, 0);
254
255 cs43130->pll_bypass = true;
256 return 0;
257 }
258
259 cs43130->pll_bypass = false;
260
261 regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_2,
262 CS43130_PLL_DIV_DATA_MASK,
263 pll_entry->pll_div_frac >>
264 CS43130_PLL_DIV_FRAC_0_DATA_SHIFT);
265 regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_3,
266 CS43130_PLL_DIV_DATA_MASK,
267 pll_entry->pll_div_frac >>
268 CS43130_PLL_DIV_FRAC_1_DATA_SHIFT);
269 regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_4,
270 CS43130_PLL_DIV_DATA_MASK,
271 pll_entry->pll_div_frac >>
272 CS43130_PLL_DIV_FRAC_2_DATA_SHIFT);
273 regmap_write(cs43130->regmap, CS43130_PLL_SET_5,
274 pll_entry->pll_div_int);
275 regmap_write(cs43130->regmap, CS43130_PLL_SET_6, pll_entry->pll_divout);
276 regmap_write(cs43130->regmap, CS43130_PLL_SET_7,
277 pll_entry->pll_cal_ratio);
278 regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_8,
279 CS43130_PLL_MODE_MASK,
280 pll_entry->pll_mode << CS43130_PLL_MODE_SHIFT);
281 regmap_write(cs43130->regmap, CS43130_PLL_SET_9,
282 pll_entry->sclk_prediv);
283 regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_1,
284 CS43130_PLL_START_MASK, 1);
285
286 return 0;
287}
288
289static int cs43130_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
290 unsigned int freq_in, unsigned int freq_out)
291{
292 int ret = 0;
293 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
294
295 switch (freq_in) {
296 case 9600000:
297 case 11289600:
298 case 12000000:
299 case 12288000:
300 case 13000000:
301 case 19200000:
302 case 22579200:
303 case 24000000:
304 case 24576000:
305 case 26000000:
306 cs43130->mclk = freq_in;
307 break;
308 default:
309 dev_err(codec->dev,
310 "unsupported pll input reference clock:%d\n", freq_in);
311 return -EINVAL;
312 }
313
314 switch (freq_out) {
315 case 22579200:
316 cs43130->mclk_int = freq_out;
317 break;
318 case 24576000:
319 cs43130->mclk_int = freq_out;
320 break;
321 default:
322 dev_err(codec->dev,
323 "unsupported pll output ref clock: %u\n", freq_out);
324 return -EINVAL;
325 }
326
327 ret = cs43130_pll_config(codec);
328 dev_dbg(codec->dev, "cs43130->pll_bypass = %d", cs43130->pll_bypass);
329 return ret;
330}
331
332static int cs43130_change_clksrc(struct snd_soc_codec *codec,
333 enum cs43130_mclk_src_sel src)
334{
335 int ret;
336 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
337 int mclk_int_decoded;
338
339 if (src == cs43130->mclk_int_src) {
340 /* clk source has not changed */
341 return 0;
342 }
343
344 switch (cs43130->mclk_int) {
345 case CS43130_MCLK_22M:
346 mclk_int_decoded = CS43130_MCLK_22P5;
347 break;
348 case CS43130_MCLK_24M:
349 mclk_int_decoded = CS43130_MCLK_24P5;
350 break;
351 default:
352 dev_err(codec->dev, "Invalid MCLK INT freq: %u\n", cs43130->mclk_int);
353 return -EINVAL;
354 }
355
356 switch (src) {
357 case CS43130_MCLK_SRC_EXT:
358 cs43130->pll_bypass = true;
359 cs43130->mclk_int_src = CS43130_MCLK_SRC_EXT;
360 if (cs43130->xtal_ibias == CS43130_XTAL_UNUSED) {
361 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
362 CS43130_PDN_XTAL_MASK,
363 1 << CS43130_PDN_XTAL_SHIFT);
364 } else {
365 reinit_completion(&cs43130->xtal_rdy);
366 regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
367 CS43130_XTAL_RDY_INT_MASK, 0);
368 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
369 CS43130_PDN_XTAL_MASK, 0);
370 ret = wait_for_completion_timeout(&cs43130->xtal_rdy,
371 msecs_to_jiffies(100));
372 regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
373 CS43130_XTAL_RDY_INT_MASK,
374 1 << CS43130_XTAL_RDY_INT_SHIFT);
375 if (ret == 0) {
376 dev_err(codec->dev, "Timeout waiting for XTAL_READY interrupt\n");
377 return -ETIMEDOUT;
378 }
379 }
380
381 regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
382 CS43130_MCLK_SRC_SEL_MASK,
383 src << CS43130_MCLK_SRC_SEL_SHIFT);
384 regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
385 CS43130_MCLK_INT_MASK,
386 mclk_int_decoded << CS43130_MCLK_INT_SHIFT);
387 usleep_range(150, 200);
388
389 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
390 CS43130_PDN_PLL_MASK,
391 1 << CS43130_PDN_PLL_SHIFT);
392 break;
393 case CS43130_MCLK_SRC_PLL:
394 cs43130->pll_bypass = false;
395 cs43130->mclk_int_src = CS43130_MCLK_SRC_PLL;
396 if (cs43130->xtal_ibias == CS43130_XTAL_UNUSED) {
397 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
398 CS43130_PDN_XTAL_MASK,
399 1 << CS43130_PDN_XTAL_SHIFT);
400 } else {
401 reinit_completion(&cs43130->xtal_rdy);
402 regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
403 CS43130_XTAL_RDY_INT_MASK, 0);
404 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
405 CS43130_PDN_XTAL_MASK, 0);
406 ret = wait_for_completion_timeout(&cs43130->xtal_rdy,
407 msecs_to_jiffies(100));
408 regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
409 CS43130_XTAL_RDY_INT_MASK,
410 1 << CS43130_XTAL_RDY_INT_SHIFT);
411 if (ret == 0) {
412 dev_err(codec->dev, "Timeout waiting for XTAL_READY interrupt\n");
413 return -ETIMEDOUT;
414 }
415 }
416
417 reinit_completion(&cs43130->pll_rdy);
418 regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
419 CS43130_PLL_RDY_INT_MASK, 0);
420 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
421 CS43130_PDN_PLL_MASK, 0);
422 ret = wait_for_completion_timeout(&cs43130->pll_rdy,
423 msecs_to_jiffies(100));
424 regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
425 CS43130_PLL_RDY_INT_MASK,
426 1 << CS43130_PLL_RDY_INT_SHIFT);
427 if (ret == 0) {
428 dev_err(codec->dev, "Timeout waiting for PLL_READY interrupt\n");
429 return -ETIMEDOUT;
430 }
431
432 regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
433 CS43130_MCLK_SRC_SEL_MASK,
434 src << CS43130_MCLK_SRC_SEL_SHIFT);
435 regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
436 CS43130_MCLK_INT_MASK,
437 mclk_int_decoded << CS43130_MCLK_INT_SHIFT);
438 usleep_range(150, 200);
439 break;
440 case CS43130_MCLK_SRC_RCO:
441 cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO;
442
443 regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
444 CS43130_MCLK_SRC_SEL_MASK,
445 src << CS43130_MCLK_SRC_SEL_SHIFT);
446 regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
447 CS43130_MCLK_INT_MASK,
448 CS43130_MCLK_22P5 << CS43130_MCLK_INT_SHIFT);
449 usleep_range(150, 200);
450
451 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
452 CS43130_PDN_XTAL_MASK,
453 1 << CS43130_PDN_XTAL_SHIFT);
454 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
455 CS43130_PDN_PLL_MASK,
456 1 << CS43130_PDN_PLL_SHIFT);
457 break;
458 default:
459 dev_err(codec->dev, "Invalid MCLK source value\n");
460 return -EINVAL;
461 }
462
463 return 0;
464}
465
466static const struct cs43130_bitwidth_map cs43130_bitwidth_table[] = {
467 {8, CS43130_SP_BIT_SIZE_8, CS43130_CH_BIT_SIZE_8},
468 {16, CS43130_SP_BIT_SIZE_16, CS43130_CH_BIT_SIZE_16},
469 {24, CS43130_SP_BIT_SIZE_24, CS43130_CH_BIT_SIZE_24},
470 {32, CS43130_SP_BIT_SIZE_32, CS43130_CH_BIT_SIZE_32},
471};
472
473static const struct cs43130_bitwidth_map *cs43130_get_bitwidth_table(
474 unsigned int bitwidth)
475{
476 int i;
477
478 for (i = 0; i < ARRAY_SIZE(cs43130_bitwidth_table); i++) {
479 if (cs43130_bitwidth_table[i].bitwidth == bitwidth)
480 return &cs43130_bitwidth_table[i];
481 }
482
483 return NULL;
484}
485
486static int cs43130_set_bitwidth(int dai_id, unsigned int bitwidth_dai,
487 struct regmap *regmap)
488{
489 const struct cs43130_bitwidth_map *bw_map;
490
491 bw_map = cs43130_get_bitwidth_table(bitwidth_dai);
492 if (!bw_map)
493 return -EINVAL;
494
495 switch (dai_id) {
496 case CS43130_ASP_PCM_DAI:
497 case CS43130_ASP_DOP_DAI:
498 regmap_update_bits(regmap, CS43130_ASP_CH_1_SZ_EN,
499 CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
500 regmap_update_bits(regmap, CS43130_ASP_CH_2_SZ_EN,
501 CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
502 regmap_update_bits(regmap, CS43130_SP_BITSIZE,
503 CS43130_ASP_BITSIZE_MASK, bw_map->sp_bit);
504 break;
505 case CS43130_XSP_DOP_DAI:
506 regmap_update_bits(regmap, CS43130_XSP_CH_1_SZ_EN,
507 CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
508 regmap_update_bits(regmap, CS43130_XSP_CH_2_SZ_EN,
509 CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
510 regmap_update_bits(regmap, CS43130_SP_BITSIZE,
511 CS43130_XSP_BITSIZE_MASK, bw_map->sp_bit <<
512 CS43130_XSP_BITSIZE_SHIFT);
513 break;
514 default:
515 return -EINVAL;
516 }
517
518 return 0;
519}
520
521static const struct cs43130_rate_map cs43130_rate_table[] = {
522 {32000, CS43130_ASP_SPRATE_32K},
523 {44100, CS43130_ASP_SPRATE_44_1K},
524 {48000, CS43130_ASP_SPRATE_48K},
525 {88200, CS43130_ASP_SPRATE_88_2K},
526 {96000, CS43130_ASP_SPRATE_96K},
527 {176400, CS43130_ASP_SPRATE_176_4K},
528 {192000, CS43130_ASP_SPRATE_192K},
529 {352800, CS43130_ASP_SPRATE_352_8K},
530 {384000, CS43130_ASP_SPRATE_384K},
531};
532
533static const struct cs43130_rate_map *cs43130_get_rate_table(int fs)
534{
535 int i;
536
537 for (i = 0; i < ARRAY_SIZE(cs43130_rate_table); i++) {
538 if (cs43130_rate_table[i].fs == fs)
539 return &cs43130_rate_table[i];
540 }
541
542 return NULL;
543}
544
545static const struct cs43130_clk_gen *cs43130_get_clk_gen(int mclk_int, int fs,
546 const struct cs43130_clk_gen *clk_gen_table, int len_clk_gen_table)
547{
548 int i;
549
550 for (i = 0; i < len_clk_gen_table; i++) {
551 if (clk_gen_table[i].mclk_int == mclk_int &&
552 clk_gen_table[i].fs == fs)
553 return &clk_gen_table[i];
554 }
555
556 return NULL;
557}
558
559static int cs43130_set_sp_fmt(int dai_id, unsigned int bitwidth_sclk,
560 struct snd_pcm_hw_params *params,
561 struct cs43130_private *cs43130)
562{
563 u16 frm_size;
564 u16 hi_size;
565 u8 frm_delay;
566 u8 frm_phase;
567 u8 frm_data;
568 u8 sclk_edge;
569 u8 lrck_edge;
570 u8 clk_data;
571 u8 loc_ch1;
572 u8 loc_ch2;
573 u8 dai_mode_val;
574 const struct cs43130_clk_gen *clk_gen;
575
576 switch (cs43130->dais[dai_id].dai_format) {
577 case SND_SOC_DAIFMT_I2S:
578 hi_size = bitwidth_sclk;
579 frm_delay = 2;
580 frm_phase = 0;
581 break;
582 case SND_SOC_DAIFMT_LEFT_J:
583 hi_size = bitwidth_sclk;
584 frm_delay = 2;
585 frm_phase = 1;
586 break;
587 case SND_SOC_DAIFMT_DSP_A:
588 hi_size = 1;
589 frm_delay = 2;
590 frm_phase = 1;
591 break;
592 case SND_SOC_DAIFMT_DSP_B:
593 hi_size = 1;
594 frm_delay = 0;
595 frm_phase = 1;
596 break;
597 default:
598 return -EINVAL;
599 }
600
601 switch (cs43130->dais[dai_id].dai_mode) {
602 case SND_SOC_DAIFMT_CBS_CFS:
603 dai_mode_val = 0;
604 break;
605 case SND_SOC_DAIFMT_CBM_CFM:
606 dai_mode_val = 1;
607 break;
608 default:
609 return -EINVAL;
610 }
611
612 frm_size = bitwidth_sclk * params_channels(params);
613 sclk_edge = 1;
614 lrck_edge = 0;
615 loc_ch1 = 0;
616 loc_ch2 = bitwidth_sclk * (params_channels(params) - 1);
617
618 frm_data = frm_delay & CS43130_SP_FSD_MASK;
619 frm_data |= (frm_phase << CS43130_SP_STP_SHIFT) & CS43130_SP_STP_MASK;
620
621 clk_data = lrck_edge & CS43130_SP_LCPOL_IN_MASK;
622 clk_data |= (lrck_edge << CS43130_SP_LCPOL_OUT_SHIFT) &
623 CS43130_SP_LCPOL_OUT_MASK;
624 clk_data |= (sclk_edge << CS43130_SP_SCPOL_IN_SHIFT) &
625 CS43130_SP_SCPOL_IN_MASK;
626 clk_data |= (sclk_edge << CS43130_SP_SCPOL_OUT_SHIFT) &
627 CS43130_SP_SCPOL_OUT_MASK;
628 clk_data |= (dai_mode_val << CS43130_SP_MODE_SHIFT) &
629 CS43130_SP_MODE_MASK;
630
631 switch (dai_id) {
632 case CS43130_ASP_PCM_DAI:
633 case CS43130_ASP_DOP_DAI:
634 regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_1,
635 CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
636 CS43130_SP_LCPR_LSB_DATA_SHIFT);
637 regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_2,
638 CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
639 CS43130_SP_LCPR_MSB_DATA_SHIFT);
640 regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_1,
641 CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
642 CS43130_SP_LCHI_LSB_DATA_SHIFT);
643 regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_2,
644 CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
645 CS43130_SP_LCHI_MSB_DATA_SHIFT);
646 regmap_write(cs43130->regmap, CS43130_ASP_FRAME_CONF, frm_data);
647 regmap_write(cs43130->regmap, CS43130_ASP_CH_1_LOC, loc_ch1);
648 regmap_write(cs43130->regmap, CS43130_ASP_CH_2_LOC, loc_ch2);
649 regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_1_SZ_EN,
650 CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
651 regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_2_SZ_EN,
652 CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
653 regmap_write(cs43130->regmap, CS43130_ASP_CLOCK_CONF, clk_data);
654 break;
655 case CS43130_XSP_DOP_DAI:
656 regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_1,
657 CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
658 CS43130_SP_LCPR_LSB_DATA_SHIFT);
659 regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_2,
660 CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
661 CS43130_SP_LCPR_MSB_DATA_SHIFT);
662 regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_1,
663 CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
664 CS43130_SP_LCHI_LSB_DATA_SHIFT);
665 regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_2,
666 CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
667 CS43130_SP_LCHI_MSB_DATA_SHIFT);
668 regmap_write(cs43130->regmap, CS43130_XSP_FRAME_CONF, frm_data);
669 regmap_write(cs43130->regmap, CS43130_XSP_CH_1_LOC, loc_ch1);
670 regmap_write(cs43130->regmap, CS43130_XSP_CH_2_LOC, loc_ch2);
671 regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_1_SZ_EN,
672 CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
673 regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_2_SZ_EN,
674 CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
675 regmap_write(cs43130->regmap, CS43130_XSP_CLOCK_CONF, clk_data);
676 break;
677 default:
678 return -EINVAL;
679 }
680
681 switch (frm_size) {
682 case 16:
683 clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
684 params_rate(params),
685 cs43130_16_clk_gen,
686 ARRAY_SIZE(cs43130_16_clk_gen));
687 break;
688 case 32:
689 clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
690 params_rate(params),
691 cs43130_32_clk_gen,
692 ARRAY_SIZE(cs43130_32_clk_gen));
693 break;
694 case 48:
695 clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
696 params_rate(params),
697 cs43130_48_clk_gen,
698 ARRAY_SIZE(cs43130_48_clk_gen));
699 break;
700 case 64:
701 clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
702 params_rate(params),
703 cs43130_64_clk_gen,
704 ARRAY_SIZE(cs43130_64_clk_gen));
705 break;
706 default:
707 return -EINVAL;
708 }
709
710 if (!clk_gen)
711 return -EINVAL;
712
713 switch (dai_id) {
714 case CS43130_ASP_PCM_DAI:
715 case CS43130_ASP_DOP_DAI:
716 regmap_write(cs43130->regmap, CS43130_ASP_DEN_1,
717 (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >>
718 CS43130_SP_M_LSB_DATA_SHIFT);
719 regmap_write(cs43130->regmap, CS43130_ASP_DEN_2,
720 (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >>
721 CS43130_SP_M_MSB_DATA_SHIFT);
722 regmap_write(cs43130->regmap, CS43130_ASP_NUM_1,
723 (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >>
724 CS43130_SP_N_LSB_DATA_SHIFT);
725 regmap_write(cs43130->regmap, CS43130_ASP_NUM_2,
726 (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >>
727 CS43130_SP_N_MSB_DATA_SHIFT);
728 break;
729 case CS43130_XSP_DOP_DAI:
730 regmap_write(cs43130->regmap, CS43130_XSP_DEN_1,
731 (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >>
732 CS43130_SP_M_LSB_DATA_SHIFT);
733 regmap_write(cs43130->regmap, CS43130_XSP_DEN_2,
734 (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >>
735 CS43130_SP_M_MSB_DATA_SHIFT);
736 regmap_write(cs43130->regmap, CS43130_XSP_NUM_1,
737 (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >>
738 CS43130_SP_N_LSB_DATA_SHIFT);
739 regmap_write(cs43130->regmap, CS43130_XSP_NUM_2,
740 (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >>
741 CS43130_SP_N_MSB_DATA_SHIFT);
742 break;
743 default:
744 return -EINVAL;
745 }
746
747 return 0;
748}
749
750static int cs43130_pcm_dsd_mix(bool en, struct regmap *regmap)
751{
752 if (en) {
753 regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL,
754 CS43130_MIX_PCM_PREP_MASK,
755 1 << CS43130_MIX_PCM_PREP_SHIFT);
756 usleep_range(6000, 6050);
757 regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL,
758 CS43130_MIX_PCM_DSD_MASK,
759 1 << CS43130_MIX_PCM_DSD_SHIFT);
760 } else {
761 regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL,
762 CS43130_MIX_PCM_DSD_MASK,
763 0 << CS43130_MIX_PCM_DSD_SHIFT);
764 usleep_range(1600, 1650);
765 regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL,
766 CS43130_MIX_PCM_PREP_MASK,
767 0 << CS43130_MIX_PCM_PREP_SHIFT);
768 }
769
770 return 0;
771}
772
773static int cs43130_dsd_hw_params(struct snd_pcm_substream *substream,
774 struct snd_pcm_hw_params *params,
775 struct snd_soc_dai *dai)
776{
777 struct snd_soc_codec *codec = dai->codec;
778 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
779 unsigned int required_clk;
780 u8 dsd_speed;
781
782 mutex_lock(&cs43130->clk_mutex);
783 if (!cs43130->clk_req) {
784 /* no DAI is currently using clk */
785 if (!(CS43130_MCLK_22M % params_rate(params)))
786 required_clk = CS43130_MCLK_22M;
787 else
788 required_clk = CS43130_MCLK_24M;
789
790 cs43130_set_pll(codec, 0, 0, cs43130->mclk, required_clk);
791 if (cs43130->pll_bypass)
792 cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT);
793 else
794 cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL);
795 }
796
797 cs43130->clk_req++;
798 if (cs43130->clk_req == 2)
799 cs43130_pcm_dsd_mix(true, cs43130->regmap);
800 mutex_unlock(&cs43130->clk_mutex);
801
802 switch (params_rate(params)) {
803 case 176400:
804 dsd_speed = 0;
805 break;
806 case 352800:
807 dsd_speed = 1;
808 break;
809 default:
810 dev_err(codec->dev, "Rate(%u) not supported\n",
811 params_rate(params));
812 return -EINVAL;
813 }
814
815 if (cs43130->dais[dai->id].dai_mode == SND_SOC_DAIFMT_CBM_CFM)
816 regmap_update_bits(cs43130->regmap, CS43130_DSD_INT_CFG,
817 CS43130_DSD_MASTER, CS43130_DSD_MASTER);
818 else
819 regmap_update_bits(cs43130->regmap, CS43130_DSD_INT_CFG,
820 CS43130_DSD_MASTER, 0);
821
822 regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
823 CS43130_DSD_SPEED_MASK,
824 dsd_speed << CS43130_DSD_SPEED_SHIFT);
825 regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
826 CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_DSD <<
827 CS43130_DSD_SRC_SHIFT);
828
829 return 0;
830}
831
832static int cs43130_hw_params(struct snd_pcm_substream *substream,
833 struct snd_pcm_hw_params *params,
834 struct snd_soc_dai *dai)
835{
836 struct snd_soc_codec *codec = dai->codec;
837 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
838 const struct cs43130_rate_map *rate_map;
839 unsigned int sclk = cs43130->dais[dai->id].sclk;
840 unsigned int bitwidth_sclk;
841 unsigned int bitwidth_dai = (unsigned int)(params_width(params));
842 unsigned int required_clk;
843 u8 dsd_speed;
844
845 mutex_lock(&cs43130->clk_mutex);
846 if (!cs43130->clk_req) {
847 /* no DAI is currently using clk */
848 if (!(CS43130_MCLK_22M % params_rate(params)))
849 required_clk = CS43130_MCLK_22M;
850 else
851 required_clk = CS43130_MCLK_24M;
852
853 cs43130_set_pll(codec, 0, 0, cs43130->mclk, required_clk);
854 if (cs43130->pll_bypass)
855 cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT);
856 else
857 cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL);
858 }
859
860 cs43130->clk_req++;
861 if (cs43130->clk_req == 2)
862 cs43130_pcm_dsd_mix(true, cs43130->regmap);
863 mutex_unlock(&cs43130->clk_mutex);
864
865 switch (dai->id) {
866 case CS43130_ASP_DOP_DAI:
867 case CS43130_XSP_DOP_DAI:
868 /* DoP bitwidth is always 24-bit */
869 bitwidth_dai = 24;
870 sclk = params_rate(params) * bitwidth_dai *
871 params_channels(params);
872
873 switch (params_rate(params)) {
874 case 176400:
875 dsd_speed = 0;
876 break;
877 case 352800:
878 dsd_speed = 1;
879 break;
880 default:
881 dev_err(codec->dev, "Rate(%u) not supported\n",
882 params_rate(params));
883 return -EINVAL;
884 }
885
886 regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
887 CS43130_DSD_SPEED_MASK,
888 dsd_speed << CS43130_DSD_SPEED_SHIFT);
889 break;
890 case CS43130_ASP_PCM_DAI:
891 rate_map = cs43130_get_rate_table(params_rate(params));
892 if (!rate_map)
893 return -EINVAL;
894
895 regmap_write(cs43130->regmap, CS43130_SP_SRATE, rate_map->val);
896 break;
897 default:
898 dev_err(codec->dev, "Invalid DAI (%d)\n", dai->id);
899 return -EINVAL;
900 }
901
902 switch (dai->id) {
903 case CS43130_ASP_DOP_DAI:
904 regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
905 CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_ASP <<
906 CS43130_DSD_SRC_SHIFT);
907 break;
908 case CS43130_XSP_DOP_DAI:
909 regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
910 CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_XSP <<
911 CS43130_DSD_SRC_SHIFT);
912 }
913
914 if (!sclk && cs43130->dais[dai->id].dai_mode == SND_SOC_DAIFMT_CBM_CFM)
915 /* Calculate SCLK in master mode if unassigned */
916 sclk = params_rate(params) * bitwidth_dai *
917 params_channels(params);
918
919 if (!sclk) {
920 /* at this point, SCLK must be set */
921 dev_err(codec->dev, "SCLK freq is not set\n");
922 return -EINVAL;
923 }
924
925 bitwidth_sclk = (sclk / params_rate(params)) / params_channels(params);
926 if (bitwidth_sclk < bitwidth_dai) {
927 dev_err(codec->dev, "Format not supported: SCLK freq is too low\n");
928 return -EINVAL;
929 }
930
931 dev_dbg(codec->dev,
932 "sclk = %u, fs = %d, bitwidth_dai = %u\n",
933 sclk, params_rate(params), bitwidth_dai);
934
935 dev_dbg(codec->dev,
936 "bitwidth_sclk = %u, num_ch = %u\n",
937 bitwidth_sclk, params_channels(params));
938
939 cs43130_set_bitwidth(dai->id, bitwidth_dai, cs43130->regmap);
940 cs43130_set_sp_fmt(dai->id, bitwidth_sclk, params, cs43130);
941
942 return 0;
943}
944
945static int cs43130_hw_free(struct snd_pcm_substream *substream,
946 struct snd_soc_dai *dai)
947{
948 struct snd_soc_codec *codec = dai->codec;
949 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
950
951 mutex_lock(&cs43130->clk_mutex);
952 cs43130->clk_req--;
953 if (!cs43130->clk_req) {
954 /* no DAI is currently using clk */
955 cs43130_change_clksrc(codec, CS43130_MCLK_SRC_RCO);
956 cs43130_pcm_dsd_mix(false, cs43130->regmap);
957 }
958 mutex_unlock(&cs43130->clk_mutex);
959
960 return 0;
961}
962
963static const DECLARE_TLV_DB_SCALE(pcm_vol_tlv, -12750, 50, 1);
964
965static const char * const pcm_ch_text[] = {
966 "Left-Right Ch",
967 "Left-Left Ch",
968 "Right-Left Ch",
969 "Right-Right Ch",
970};
971
972static const struct reg_sequence pcm_ch_en_seq[] = {
973 {CS43130_DXD1, 0x99},
974 {0x180005, 0x8C},
975 {0x180007, 0xAB},
976 {0x180015, 0x31},
977 {0x180017, 0xB2},
978 {0x180025, 0x30},
979 {0x180027, 0x84},
980 {0x180035, 0x9C},
981 {0x180037, 0xAE},
982 {0x18000D, 0x24},
983 {0x18000F, 0xA3},
984 {0x18001D, 0x05},
985 {0x18001F, 0xD4},
986 {0x18002D, 0x0B},
987 {0x18002F, 0xC7},
988 {0x18003D, 0x71},
989 {0x18003F, 0xE7},
990 {CS43130_DXD1, 0},
991};
992
993static const struct reg_sequence pcm_ch_dis_seq[] = {
994 {CS43130_DXD1, 0x99},
995 {0x180005, 0x24},
996 {0x180007, 0xA3},
997 {0x180015, 0x05},
998 {0x180017, 0xD4},
999 {0x180025, 0x0B},
1000 {0x180027, 0xC7},
1001 {0x180035, 0x71},
1002 {0x180037, 0xE7},
1003 {0x18000D, 0x8C},
1004 {0x18000F, 0xAB},
1005 {0x18001D, 0x31},
1006 {0x18001F, 0xB2},
1007 {0x18002D, 0x30},
1008 {0x18002F, 0x84},
1009 {0x18003D, 0x9C},
1010 {0x18003F, 0xAE},
1011 {CS43130_DXD1, 0},
1012};
1013
1014static int cs43130_pcm_ch_get(struct snd_kcontrol *kcontrol,
1015 struct snd_ctl_elem_value *ucontrol)
1016{
1017 return snd_soc_get_enum_double(kcontrol, ucontrol);
1018}
1019
1020static int cs43130_pcm_ch_put(struct snd_kcontrol *kcontrol,
1021 struct snd_ctl_elem_value *ucontrol)
1022{
1023 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1024 unsigned int *item = ucontrol->value.enumerated.item;
1025 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
1026 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
1027 unsigned int val;
1028
1029 if (item[0] >= e->items)
1030 return -EINVAL;
1031 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
1032
1033 switch (cs43130->dev_id) {
1034 case CS43131_CHIP_ID:
1035 case CS43198_CHIP_ID:
1036 if (val >= 2)
1037 regmap_multi_reg_write(cs43130->regmap, pcm_ch_en_seq,
1038 ARRAY_SIZE(pcm_ch_en_seq));
1039 else
1040 regmap_multi_reg_write(cs43130->regmap, pcm_ch_dis_seq,
1041 ARRAY_SIZE(pcm_ch_dis_seq));
1042 }
1043
1044 return snd_soc_put_enum_double(kcontrol, ucontrol);
1045}
1046
1047static SOC_ENUM_SINGLE_DECL(pcm_ch_enum, CS43130_PCM_PATH_CTL_2, 0,
1048 pcm_ch_text);
1049
1050static const char * const pcm_spd_texts[] = {
1051 "Fast",
1052 "Slow",
1053};
1054
1055static SOC_ENUM_SINGLE_DECL(pcm_spd_enum, CS43130_PCM_FILT_OPT, 7,
1056 pcm_spd_texts);
1057
1058static const char * const dsd_texts[] = {
1059 "Off",
1060 "BCKA Mode",
1061 "BCKD Mode",
1062};
1063
1064static const unsigned int dsd_values[] = {
1065 CS43130_DSD_SRC_DSD,
1066 CS43130_DSD_SRC_ASP,
1067 CS43130_DSD_SRC_XSP,
1068};
1069
1070static SOC_VALUE_ENUM_SINGLE_DECL(dsd_enum, CS43130_DSD_INT_CFG, 0, 0x03,
1071 dsd_texts, dsd_values);
1072
1073static const struct snd_kcontrol_new cs43130_snd_controls[] = {
1074 SOC_DOUBLE_R_TLV("Master Playback Volume",
1075 CS43130_PCM_VOL_A, CS43130_PCM_VOL_B, 0, 0xFF, 1,
1076 pcm_vol_tlv),
1077 SOC_DOUBLE_R_TLV("Master DSD Playback Volume",
1078 CS43130_DSD_VOL_A, CS43130_DSD_VOL_B, 0, 0xFF, 1,
1079 pcm_vol_tlv),
1080 SOC_ENUM_EXT("PCM Ch Select", pcm_ch_enum, cs43130_pcm_ch_get,
1081 cs43130_pcm_ch_put),
1082 SOC_ENUM("PCM Filter Speed", pcm_spd_enum),
1083 SOC_SINGLE("PCM Phase Compensation", CS43130_PCM_FILT_OPT, 6, 1, 0),
1084 SOC_SINGLE("PCM Nonoversample Emulate", CS43130_PCM_FILT_OPT, 5, 1, 0),
1085 SOC_SINGLE("PCM High-pass Filter", CS43130_PCM_FILT_OPT, 1, 1, 0),
1086 SOC_SINGLE("PCM De-emphasis Filter", CS43130_PCM_FILT_OPT, 0, 1, 0),
1087 SOC_ENUM("DSD Phase Modulation", dsd_enum),
1088};
1089
1090static const struct reg_sequence pcm_seq[] = {
1091 {CS43130_DXD1, 0x99},
1092 {CS43130_DXD7, 0x01},
1093 {CS43130_DXD8, 0},
1094 {CS43130_DXD9, 0x01},
1095 {CS43130_DXD3, 0x12},
1096 {CS43130_DXD4, 0},
1097 {CS43130_DXD10, 0x28},
1098 {CS43130_DXD11, 0x28},
1099 {CS43130_DXD1, 0},
1100};
1101
1102static const struct reg_sequence dsd_seq[] = {
1103 {CS43130_DXD1, 0x99},
1104 {CS43130_DXD7, 0x01},
1105 {CS43130_DXD8, 0},
1106 {CS43130_DXD9, 0x01},
1107 {CS43130_DXD3, 0x12},
1108 {CS43130_DXD4, 0},
1109 {CS43130_DXD10, 0x1E},
1110 {CS43130_DXD11, 0x20},
1111 {CS43130_DXD1, 0},
1112};
1113
1114static const struct reg_sequence pop_free_seq[] = {
1115 {CS43130_DXD1, 0x99},
1116 {CS43130_DXD12, 0x0A},
1117 {CS43130_DXD1, 0},
1118};
1119
1120static const struct reg_sequence pop_free_seq2[] = {
1121 {CS43130_DXD1, 0x99},
1122 {CS43130_DXD13, 0x20},
1123 {CS43130_DXD1, 0},
1124};
1125
1126static const struct reg_sequence mute_seq[] = {
1127 {CS43130_DXD1, 0x99},
1128 {CS43130_DXD3, 0x12},
1129 {CS43130_DXD5, 0x02},
1130 {CS43130_DXD4, 0x12},
1131 {CS43130_DXD1, 0},
1132};
1133
1134static const struct reg_sequence unmute_seq[] = {
1135 {CS43130_DXD1, 0x99},
1136 {CS43130_DXD3, 0x10},
1137 {CS43130_DXD5, 0},
1138 {CS43130_DXD4, 0x16},
1139 {CS43130_DXD1, 0},
1140};
1141
1142static int cs43130_dsd_event(struct snd_soc_dapm_widget *w,
1143 struct snd_kcontrol *kcontrol, int event)
1144{
1145 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1146 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
1147
1148 switch (event) {
1149 case SND_SOC_DAPM_PRE_PMU:
1150 switch (cs43130->dev_id) {
1151 case CS43130_CHIP_ID:
1152 case CS4399_CHIP_ID:
1153 regmap_multi_reg_write(cs43130->regmap, dsd_seq,
1154 ARRAY_SIZE(dsd_seq));
1155 }
1156 break;
1157 case SND_SOC_DAPM_POST_PMU:
1158 regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_1,
1159 CS43130_MUTE_MASK, 0);
1160 switch (cs43130->dev_id) {
1161 case CS43130_CHIP_ID:
1162 case CS4399_CHIP_ID:
1163 regmap_multi_reg_write(cs43130->regmap, unmute_seq,
1164 ARRAY_SIZE(unmute_seq));
1165 }
1166 break;
1167 case SND_SOC_DAPM_PRE_PMD:
1168 switch (cs43130->dev_id) {
1169 case CS43130_CHIP_ID:
1170 case CS4399_CHIP_ID:
1171 regmap_multi_reg_write(cs43130->regmap, mute_seq,
1172 ARRAY_SIZE(mute_seq));
1173 regmap_update_bits(cs43130->regmap,
1174 CS43130_DSD_PATH_CTL_1,
1175 CS43130_MUTE_MASK, CS43130_MUTE_EN);
1176 /*
1177 * DSD Power Down Sequence
1178 * According to Design, 130ms is preferred.
1179 */
1180 msleep(130);
1181 break;
1182 case CS43131_CHIP_ID:
1183 case CS43198_CHIP_ID:
1184 regmap_update_bits(cs43130->regmap,
1185 CS43130_DSD_PATH_CTL_1,
1186 CS43130_MUTE_MASK, CS43130_MUTE_EN);
1187 }
1188 break;
1189 default:
1190 dev_err(codec->dev, "Invalid event = 0x%x\n", event);
1191 return -EINVAL;
1192 }
1193 return 0;
1194}
1195
1196static int cs43130_pcm_event(struct snd_soc_dapm_widget *w,
1197 struct snd_kcontrol *kcontrol, int event)
1198{
1199 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1200 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
1201
1202 switch (event) {
1203 case SND_SOC_DAPM_PRE_PMU:
1204 switch (cs43130->dev_id) {
1205 case CS43130_CHIP_ID:
1206 case CS4399_CHIP_ID:
1207 regmap_multi_reg_write(cs43130->regmap, pcm_seq,
1208 ARRAY_SIZE(pcm_seq));
1209 }
1210 break;
1211 case SND_SOC_DAPM_POST_PMU:
1212 regmap_update_bits(cs43130->regmap, CS43130_PCM_PATH_CTL_1,
1213 CS43130_MUTE_MASK, 0);
1214 switch (cs43130->dev_id) {
1215 case CS43130_CHIP_ID:
1216 case CS4399_CHIP_ID:
1217 regmap_multi_reg_write(cs43130->regmap, unmute_seq,
1218 ARRAY_SIZE(unmute_seq));
1219 }
1220 break;
1221 case SND_SOC_DAPM_PRE_PMD:
1222 switch (cs43130->dev_id) {
1223 case CS43130_CHIP_ID:
1224 case CS4399_CHIP_ID:
1225 regmap_multi_reg_write(cs43130->regmap, mute_seq,
1226 ARRAY_SIZE(mute_seq));
1227 regmap_update_bits(cs43130->regmap,
1228 CS43130_PCM_PATH_CTL_1,
1229 CS43130_MUTE_MASK, CS43130_MUTE_EN);
1230 /*
1231 * PCM Power Down Sequence
1232 * According to Design, 130ms is preferred.
1233 */
1234 msleep(130);
1235 break;
1236 case CS43131_CHIP_ID:
1237 case CS43198_CHIP_ID:
1238 regmap_update_bits(cs43130->regmap,
1239 CS43130_PCM_PATH_CTL_1,
1240 CS43130_MUTE_MASK, CS43130_MUTE_EN);
1241 }
1242 break;
1243 default:
1244 dev_err(codec->dev, "Invalid event = 0x%x\n", event);
1245 return -EINVAL;
1246 }
1247 return 0;
1248}
1249
1250static const struct reg_sequence dac_postpmu_seq[] = {
1251 {CS43130_DXD9, 0x0C},
1252 {CS43130_DXD3, 0x10},
1253 {CS43130_DXD4, 0x20},
1254};
1255
1256static const struct reg_sequence dac_postpmd_seq[] = {
1257 {CS43130_DXD1, 0x99},
1258 {CS43130_DXD6, 0x01},
1259 {CS43130_DXD1, 0},
1260};
1261
1262static int cs43130_dac_event(struct snd_soc_dapm_widget *w,
1263 struct snd_kcontrol *kcontrol, int event)
1264{
1265 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1266 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
1267
1268 switch (event) {
1269 case SND_SOC_DAPM_PRE_PMU:
1270 switch (cs43130->dev_id) {
1271 case CS43130_CHIP_ID:
1272 case CS4399_CHIP_ID:
1273 regmap_multi_reg_write(cs43130->regmap, pop_free_seq,
1274 ARRAY_SIZE(pop_free_seq));
1275 break;
1276 case CS43131_CHIP_ID:
1277 case CS43198_CHIP_ID:
1278 regmap_multi_reg_write(cs43130->regmap, pop_free_seq2,
1279 ARRAY_SIZE(pop_free_seq2));
1280 }
1281 break;
1282 case SND_SOC_DAPM_POST_PMU:
1283 usleep_range(10000, 10050);
1284
1285 regmap_write(cs43130->regmap, CS43130_DXD1, 0x99);
1286
1287 switch (cs43130->dev_id) {
1288 case CS43130_CHIP_ID:
1289 case CS4399_CHIP_ID:
1290 regmap_multi_reg_write(cs43130->regmap, dac_postpmu_seq,
1291 ARRAY_SIZE(dac_postpmu_seq));
1292 /*
1293 * Per datasheet, Sec. PCM Power-Up Sequence.
1294 * According to Design, CS43130_DXD12 must be 0 to meet
1295 * THDN and Dynamic Range spec.
1296 */
1297 msleep(1000);
1298 regmap_write(cs43130->regmap, CS43130_DXD12, 0);
1299 break;
1300 case CS43131_CHIP_ID:
1301 case CS43198_CHIP_ID:
1302 usleep_range(12000, 12010);
1303 regmap_write(cs43130->regmap, CS43130_DXD13, 0);
1304 }
1305
1306 regmap_write(cs43130->regmap, CS43130_DXD1, 0);
1307 break;
1308 case SND_SOC_DAPM_POST_PMD:
1309 switch (cs43130->dev_id) {
1310 case CS43130_CHIP_ID:
1311 case CS4399_CHIP_ID:
1312 regmap_multi_reg_write(cs43130->regmap, dac_postpmd_seq,
1313 ARRAY_SIZE(dac_postpmd_seq));
1314 }
1315 break;
1316 default:
1317 dev_err(codec->dev, "Invalid DAC event = 0x%x\n", event);
1318 return -EINVAL;
1319 }
1320 return 0;
1321}
1322
1323static const struct reg_sequence hpin_prepmd_seq[] = {
1324 {CS43130_DXD1, 0x99},
1325 {CS43130_DXD15, 0x64},
1326 {CS43130_DXD14, 0},
1327 {CS43130_DXD2, 0},
1328 {CS43130_DXD1, 0},
1329};
1330
1331static const struct reg_sequence hpin_postpmu_seq[] = {
1332 {CS43130_DXD1, 0x99},
1333 {CS43130_DXD2, 1},
1334 {CS43130_DXD14, 0xDC},
1335 {CS43130_DXD15, 0xE4},
1336 {CS43130_DXD1, 0},
1337};
1338
1339static int cs43130_hpin_event(struct snd_soc_dapm_widget *w,
1340 struct snd_kcontrol *kcontrol, int event)
1341{
1342 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1343 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
1344
1345 switch (event) {
1346 case SND_SOC_DAPM_POST_PMD:
1347 regmap_multi_reg_write(cs43130->regmap, hpin_prepmd_seq,
1348 ARRAY_SIZE(hpin_prepmd_seq));
1349 break;
1350 case SND_SOC_DAPM_PRE_PMU:
1351 regmap_multi_reg_write(cs43130->regmap, hpin_postpmu_seq,
1352 ARRAY_SIZE(hpin_postpmu_seq));
1353 break;
1354 default:
1355 dev_err(codec->dev, "Invalid HPIN event = 0x%x\n", event);
1356 return -EINVAL;
1357 }
1358 return 0;
1359}
1360
1361static const struct snd_soc_dapm_widget digital_hp_widgets[] = {
1362 SND_SOC_DAPM_OUTPUT("HPOUTA"),
1363 SND_SOC_DAPM_OUTPUT("HPOUTB"),
1364
1365 SND_SOC_DAPM_AIF_IN_E("ASPIN PCM", NULL, 0, CS43130_PWDN_CTL,
1366 CS43130_PDN_ASP_SHIFT, 1, cs43130_pcm_event,
1367 (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1368 SND_SOC_DAPM_PRE_PMD)),
1369
1370 SND_SOC_DAPM_AIF_IN_E("ASPIN DoP", NULL, 0, CS43130_PWDN_CTL,
1371 CS43130_PDN_ASP_SHIFT, 1, cs43130_dsd_event,
1372 (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1373 SND_SOC_DAPM_PRE_PMD)),
1374
1375 SND_SOC_DAPM_AIF_IN_E("XSPIN DoP", NULL, 0, CS43130_PWDN_CTL,
1376 CS43130_PDN_XSP_SHIFT, 1, cs43130_dsd_event,
1377 (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1378 SND_SOC_DAPM_PRE_PMD)),
1379
1380 SND_SOC_DAPM_AIF_IN_E("XSPIN DSD", NULL, 0, CS43130_PWDN_CTL,
1381 CS43130_PDN_DSDIF_SHIFT, 1, cs43130_dsd_event,
1382 (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1383 SND_SOC_DAPM_PRE_PMD)),
1384
1385 SND_SOC_DAPM_DAC("DSD", NULL, CS43130_DSD_PATH_CTL_2,
1386 CS43130_DSD_EN_SHIFT, 0),
1387
1388 SND_SOC_DAPM_DAC_E("HiFi DAC", NULL, CS43130_PWDN_CTL,
1389 CS43130_PDN_HP_SHIFT, 1, cs43130_dac_event,
1390 (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1391 SND_SOC_DAPM_POST_PMD)),
1392};
1393
1394static const struct snd_soc_dapm_widget analog_hp_widgets[] = {
1395 SND_SOC_DAPM_DAC_E("Analog Playback", NULL, CS43130_HP_OUT_CTL_1,
1396 CS43130_HP_IN_EN_SHIFT, 0, cs43130_hpin_event,
1397 (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD)),
1398};
1399
1400static struct snd_soc_dapm_widget all_hp_widgets[
1401 ARRAY_SIZE(digital_hp_widgets) +
1402 ARRAY_SIZE(analog_hp_widgets)];
1403
1404static const struct snd_soc_dapm_route digital_hp_routes[] = {
1405 {"ASPIN PCM", NULL, "ASP PCM Playback"},
1406 {"ASPIN DoP", NULL, "ASP DoP Playback"},
1407 {"XSPIN DoP", NULL, "XSP DoP Playback"},
1408 {"XSPIN DSD", NULL, "XSP DSD Playback"},
1409 {"DSD", NULL, "ASPIN DoP"},
1410 {"DSD", NULL, "XSPIN DoP"},
1411 {"DSD", NULL, "XSPIN DSD"},
1412 {"HiFi DAC", NULL, "ASPIN PCM"},
1413 {"HiFi DAC", NULL, "DSD"},
1414 {"HPOUTA", NULL, "HiFi DAC"},
1415 {"HPOUTB", NULL, "HiFi DAC"},
1416};
1417
1418static const struct snd_soc_dapm_route analog_hp_routes[] = {
1419 {"HPOUTA", NULL, "Analog Playback"},
1420 {"HPOUTB", NULL, "Analog Playback"},
1421};
1422
1423static struct snd_soc_dapm_route all_hp_routes[
1424 ARRAY_SIZE(digital_hp_routes) +
1425 ARRAY_SIZE(analog_hp_routes)];
1426
1427static const unsigned int cs43130_asp_src_rates[] = {
1428 32000, 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000
1429};
1430
1431static const struct snd_pcm_hw_constraint_list cs43130_asp_constraints = {
1432 .count = ARRAY_SIZE(cs43130_asp_src_rates),
1433 .list = cs43130_asp_src_rates,
1434};
1435
1436static int cs43130_pcm_startup(struct snd_pcm_substream *substream,
1437 struct snd_soc_dai *dai)
1438{
1439 return snd_pcm_hw_constraint_list(substream->runtime, 0,
1440 SNDRV_PCM_HW_PARAM_RATE,
1441 &cs43130_asp_constraints);
1442}
1443
1444static const unsigned int cs43130_dop_src_rates[] = {
1445 176400, 352800,
1446};
1447
1448static const struct snd_pcm_hw_constraint_list cs43130_dop_constraints = {
1449 .count = ARRAY_SIZE(cs43130_dop_src_rates),
1450 .list = cs43130_dop_src_rates,
1451};
1452
1453static int cs43130_dop_startup(struct snd_pcm_substream *substream,
1454 struct snd_soc_dai *dai)
1455{
1456 return snd_pcm_hw_constraint_list(substream->runtime, 0,
1457 SNDRV_PCM_HW_PARAM_RATE,
1458 &cs43130_dop_constraints);
1459}
1460
1461static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1462{
1463 struct snd_soc_codec *codec = codec_dai->codec;
1464 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
1465
1466 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1467 case SND_SOC_DAIFMT_CBS_CFS:
1468 cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBS_CFS;
1469 break;
1470 case SND_SOC_DAIFMT_CBM_CFM:
1471 cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM;
1472 break;
1473 default:
1474 dev_err(codec->dev, "unsupported mode\n");
1475 return -EINVAL;
1476 }
1477
1478 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1479 case SND_SOC_DAIFMT_I2S:
1480 cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_I2S;
1481 break;
1482 case SND_SOC_DAIFMT_LEFT_J:
1483 cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_LEFT_J;
1484 break;
1485 case SND_SOC_DAIFMT_DSP_A:
1486 cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_DSP_A;
1487 break;
1488 case SND_SOC_DAIFMT_DSP_B:
1489 cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_DSP_B;
1490 break;
1491 default:
1492 dev_err(codec->dev,
1493 "unsupported audio format\n");
1494 return -EINVAL;
1495 }
1496
1497 dev_dbg(codec->dev, "dai_id = %d, dai_mode = %u, dai_format = %u\n",
1498 codec_dai->id,
1499 cs43130->dais[codec_dai->id].dai_mode,
1500 cs43130->dais[codec_dai->id].dai_format);
1501
1502 return 0;
1503}
1504
1505static int cs43130_dsd_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1506{
1507 struct snd_soc_codec *codec = codec_dai->codec;
1508 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
1509
1510 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1511 case SND_SOC_DAIFMT_CBS_CFS:
1512 cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBS_CFS;
1513 break;
1514 case SND_SOC_DAIFMT_CBM_CFM:
1515 cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM;
1516 break;
1517 default:
1518 dev_err(codec->dev, "Unsupported DAI format.\n");
1519 return -EINVAL;
1520 }
1521
1522 dev_dbg(codec->dev, "dai_mode = 0x%x\n",
1523 cs43130->dais[codec_dai->id].dai_mode);
1524
1525 return 0;
1526}
1527
1528static int cs43130_set_sysclk(struct snd_soc_dai *codec_dai,
1529 int clk_id, unsigned int freq, int dir)
1530{
1531 struct snd_soc_codec *codec = codec_dai->codec;
1532 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
1533
1534 cs43130->dais[codec_dai->id].sclk = freq;
1535 dev_dbg(codec->dev, "dai_id = %d, sclk = %u\n", codec_dai->id,
1536 cs43130->dais[codec_dai->id].sclk);
1537
1538 return 0;
1539}
1540
1541static const struct snd_soc_dai_ops cs43130_pcm_ops = {
1542 .startup = cs43130_pcm_startup,
1543 .hw_params = cs43130_hw_params,
1544 .hw_free = cs43130_hw_free,
1545 .set_sysclk = cs43130_set_sysclk,
1546 .set_fmt = cs43130_pcm_set_fmt,
1547};
1548
1549static const struct snd_soc_dai_ops cs43130_dop_ops = {
1550 .startup = cs43130_dop_startup,
1551 .hw_params = cs43130_hw_params,
1552 .hw_free = cs43130_hw_free,
1553 .set_sysclk = cs43130_set_sysclk,
1554 .set_fmt = cs43130_pcm_set_fmt,
1555};
1556
1557static const struct snd_soc_dai_ops cs43130_dsd_ops = {
1558 .startup = cs43130_dop_startup,
1559 .hw_params = cs43130_dsd_hw_params,
1560 .hw_free = cs43130_hw_free,
1561 .set_fmt = cs43130_dsd_set_fmt,
1562};
1563
1564static struct snd_soc_dai_driver cs43130_dai[] = {
1565 {
1566 .name = "cs43130-asp-pcm",
1567 .id = CS43130_ASP_PCM_DAI,
1568 .playback = {
1569 .stream_name = "ASP PCM Playback",
1570 .channels_min = 1,
1571 .channels_max = 2,
1572 .rates = SNDRV_PCM_RATE_KNOT,
1573 .formats = CS43130_PCM_FORMATS,
1574 },
1575 .ops = &cs43130_pcm_ops,
1576 .symmetric_rates = 1,
1577 },
1578 {
1579 .name = "cs43130-asp-dop",
1580 .id = CS43130_ASP_DOP_DAI,
1581 .playback = {
1582 .stream_name = "ASP DoP Playback",
1583 .channels_min = 1,
1584 .channels_max = 2,
1585 .rates = SNDRV_PCM_RATE_KNOT,
1586 .formats = CS43130_DOP_FORMATS,
1587 },
1588 .ops = &cs43130_dop_ops,
1589 .symmetric_rates = 1,
1590 },
1591 {
1592 .name = "cs43130-xsp-dop",
1593 .id = CS43130_XSP_DOP_DAI,
1594 .playback = {
1595 .stream_name = "XSP DoP Playback",
1596 .channels_min = 1,
1597 .channels_max = 2,
1598 .rates = SNDRV_PCM_RATE_KNOT,
1599 .formats = CS43130_DOP_FORMATS,
1600 },
1601 .ops = &cs43130_dop_ops,
1602 .symmetric_rates = 1,
1603 },
1604 {
1605 .name = "cs43130-xsp-dsd",
1606 .id = CS43130_XSP_DSD_DAI,
1607 .playback = {
1608 .stream_name = "XSP DSD Playback",
1609 .channels_min = 1,
1610 .channels_max = 2,
1611 .rates = SNDRV_PCM_RATE_KNOT,
1612 .formats = CS43130_DOP_FORMATS,
1613 },
1614 .ops = &cs43130_dsd_ops,
1615 },
1616
1617};
1618
1619static int cs43130_codec_set_sysclk(struct snd_soc_codec *codec,
1620 int clk_id, int source, unsigned int freq,
1621 int dir)
1622{
1623 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
1624
1625 dev_dbg(codec->dev, "clk_id = %d, source = %d, freq = %d, dir = %d\n",
1626 clk_id, source, freq, dir);
1627
1628 switch (freq) {
1629 case CS43130_MCLK_22M:
1630 case CS43130_MCLK_24M:
1631 cs43130->mclk = freq;
1632 break;
1633 default:
1634 dev_err(codec->dev, "Invalid MCLK INT freq: %u\n", freq);
1635 return -EINVAL;
1636 }
1637
1638 if (source == CS43130_MCLK_SRC_EXT) {
1639 cs43130->pll_bypass = true;
1640 } else {
1641 dev_err(codec->dev, "Invalid MCLK source\n");
1642 return -EINVAL;
1643 }
1644
1645 return 0;
1646}
1647
1648static inline u16 cs43130_get_ac_reg_val(u16 ac_freq)
1649{
1650 /* AC freq is counted in 5.94Hz step. */
1651 return ac_freq / 6;
1652}
1653
1654static int cs43130_show_dc(struct device *dev, char *buf, u8 ch)
1655{
1656 struct i2c_client *client = to_i2c_client(dev);
1657 struct cs43130_private *cs43130 = i2c_get_clientdata(client);
1658
1659 if (!cs43130->hpload_done)
1660 return scnprintf(buf, PAGE_SIZE, "NO_HPLOAD\n");
1661 else
1662 return scnprintf(buf, PAGE_SIZE, "%u\n",
1663 cs43130->hpload_dc[ch]);
1664}
1665
1666static ssize_t cs43130_show_dc_l(struct device *dev,
1667 struct device_attribute *attr, char *buf)
1668{
1669 return cs43130_show_dc(dev, buf, HP_LEFT);
1670}
1671
1672static ssize_t cs43130_show_dc_r(struct device *dev,
1673 struct device_attribute *attr, char *buf)
1674{
1675 return cs43130_show_dc(dev, buf, HP_RIGHT);
1676}
1677
1678static u16 const cs43130_ac_freq[CS43130_AC_FREQ] = {
1679 24,
1680 43,
1681 93,
1682 200,
1683 431,
1684 928,
1685 2000,
1686 4309,
1687 9283,
1688 20000,
1689};
1690
1691static int cs43130_show_ac(struct device *dev, char *buf, u8 ch)
1692{
1693 int i, j = 0, tmp;
1694 struct i2c_client *client = to_i2c_client(dev);
1695 struct cs43130_private *cs43130 = i2c_get_clientdata(client);
1696
1697 if (cs43130->hpload_done && cs43130->ac_meas) {
1698 for (i = 0; i < ARRAY_SIZE(cs43130_ac_freq); i++) {
1699 tmp = scnprintf(buf + j, PAGE_SIZE - j, "%u\n",
1700 cs43130->hpload_ac[i][ch]);
1701 if (!tmp)
1702 break;
1703
1704 j += tmp;
1705 }
1706
1707 return j;
1708 } else {
1709 return scnprintf(buf, PAGE_SIZE, "NO_HPLOAD\n");
1710 }
1711}
1712
1713static ssize_t cs43130_show_ac_l(struct device *dev,
1714 struct device_attribute *attr, char *buf)
1715{
1716 return cs43130_show_ac(dev, buf, HP_LEFT);
1717}
1718
1719static ssize_t cs43130_show_ac_r(struct device *dev,
1720 struct device_attribute *attr, char *buf)
1721{
1722 return cs43130_show_ac(dev, buf, HP_RIGHT);
1723}
1724
1725static DEVICE_ATTR(hpload_dc_l, S_IRUGO, cs43130_show_dc_l, NULL);
1726static DEVICE_ATTR(hpload_dc_r, S_IRUGO, cs43130_show_dc_r, NULL);
1727static DEVICE_ATTR(hpload_ac_l, S_IRUGO, cs43130_show_ac_l, NULL);
1728static DEVICE_ATTR(hpload_ac_r, S_IRUGO, cs43130_show_ac_r, NULL);
1729
1730static struct reg_sequence hp_en_cal_seq[] = {
1731 {CS43130_INT_MASK_4, CS43130_INT_MASK_ALL},
1732 {CS43130_HP_MEAS_LOAD_1, 0},
1733 {CS43130_HP_MEAS_LOAD_2, 0},
1734 {CS43130_INT_MASK_4, 0},
1735 {CS43130_DXD1, 0x99},
1736 {CS43130_DXD16, 0xBB},
1737 {CS43130_DXD12, 0x01},
1738 {CS43130_DXD19, 0xCB},
1739 {CS43130_DXD17, 0x95},
1740 {CS43130_DXD18, 0x0B},
1741 {CS43130_DXD1, 0},
1742 {CS43130_HP_LOAD_1, 0x80},
1743};
1744
1745static struct reg_sequence hp_en_cal_seq2[] = {
1746 {CS43130_INT_MASK_4, CS43130_INT_MASK_ALL},
1747 {CS43130_HP_MEAS_LOAD_1, 0},
1748 {CS43130_HP_MEAS_LOAD_2, 0},
1749 {CS43130_INT_MASK_4, 0},
1750 {CS43130_HP_LOAD_1, 0x80},
1751};
1752
1753static struct reg_sequence hp_dis_cal_seq[] = {
1754 {CS43130_HP_LOAD_1, 0x80},
1755 {CS43130_DXD1, 0x99},
1756 {CS43130_DXD12, 0},
1757 {CS43130_DXD1, 0},
1758 {CS43130_HP_LOAD_1, 0},
1759};
1760
1761static struct reg_sequence hp_dis_cal_seq2[] = {
1762 {CS43130_HP_LOAD_1, 0x80},
1763 {CS43130_HP_LOAD_1, 0},
1764};
1765
1766static struct reg_sequence hp_dc_ch_l_seq[] = {
1767 {CS43130_DXD1, 0x99},
1768 {CS43130_DXD19, 0x0A},
1769 {CS43130_DXD17, 0x93},
1770 {CS43130_DXD18, 0x0A},
1771 {CS43130_DXD1, 0},
1772 {CS43130_HP_LOAD_1, 0x80},
1773 {CS43130_HP_LOAD_1, 0x81},
1774};
1775
1776static struct reg_sequence hp_dc_ch_l_seq2[] = {
1777 {CS43130_HP_LOAD_1, 0x80},
1778 {CS43130_HP_LOAD_1, 0x81},
1779};
1780
1781static struct reg_sequence hp_dc_ch_r_seq[] = {
1782 {CS43130_DXD1, 0x99},
1783 {CS43130_DXD19, 0x8A},
1784 {CS43130_DXD17, 0x15},
1785 {CS43130_DXD18, 0x06},
1786 {CS43130_DXD1, 0},
1787 {CS43130_HP_LOAD_1, 0x90},
1788 {CS43130_HP_LOAD_1, 0x91},
1789};
1790
1791static struct reg_sequence hp_dc_ch_r_seq2[] = {
1792 {CS43130_HP_LOAD_1, 0x90},
1793 {CS43130_HP_LOAD_1, 0x91},
1794};
1795
1796static struct reg_sequence hp_ac_ch_l_seq[] = {
1797 {CS43130_DXD1, 0x99},
1798 {CS43130_DXD19, 0x0A},
1799 {CS43130_DXD17, 0x93},
1800 {CS43130_DXD18, 0x0A},
1801 {CS43130_DXD1, 0},
1802 {CS43130_HP_LOAD_1, 0x80},
1803 {CS43130_HP_LOAD_1, 0x82},
1804};
1805
1806static struct reg_sequence hp_ac_ch_l_seq2[] = {
1807 {CS43130_HP_LOAD_1, 0x80},
1808 {CS43130_HP_LOAD_1, 0x82},
1809};
1810
1811static struct reg_sequence hp_ac_ch_r_seq[] = {
1812 {CS43130_DXD1, 0x99},
1813 {CS43130_DXD19, 0x8A},
1814 {CS43130_DXD17, 0x15},
1815 {CS43130_DXD18, 0x06},
1816 {CS43130_DXD1, 0},
1817 {CS43130_HP_LOAD_1, 0x90},
1818 {CS43130_HP_LOAD_1, 0x92},
1819};
1820
1821static struct reg_sequence hp_ac_ch_r_seq2[] = {
1822 {CS43130_HP_LOAD_1, 0x90},
1823 {CS43130_HP_LOAD_1, 0x92},
1824};
1825
1826static struct reg_sequence hp_cln_seq[] = {
1827 {CS43130_INT_MASK_4, CS43130_INT_MASK_ALL},
1828 {CS43130_HP_MEAS_LOAD_1, 0},
1829 {CS43130_HP_MEAS_LOAD_2, 0},
1830};
1831
1832struct reg_sequences {
1833 struct reg_sequence *seq;
1834 int size;
1835 unsigned int msk;
1836};
1837
1838static struct reg_sequences hpload_seq1[] = {
1839 {
1840 .seq = hp_en_cal_seq,
1841 .size = ARRAY_SIZE(hp_en_cal_seq),
1842 .msk = CS43130_HPLOAD_ON_INT,
1843 },
1844 {
1845 .seq = hp_dc_ch_l_seq,
1846 .size = ARRAY_SIZE(hp_dc_ch_l_seq),
1847 .msk = CS43130_HPLOAD_DC_INT,
1848 },
1849 {
1850 .seq = hp_ac_ch_l_seq,
1851 .size = ARRAY_SIZE(hp_ac_ch_l_seq),
1852 .msk = CS43130_HPLOAD_AC_INT,
1853 },
1854 {
1855 .seq = hp_dis_cal_seq,
1856 .size = ARRAY_SIZE(hp_dis_cal_seq),
1857 .msk = CS43130_HPLOAD_OFF_INT,
1858 },
1859 {
1860 .seq = hp_en_cal_seq,
1861 .size = ARRAY_SIZE(hp_en_cal_seq),
1862 .msk = CS43130_HPLOAD_ON_INT,
1863 },
1864 {
1865 .seq = hp_dc_ch_r_seq,
1866 .size = ARRAY_SIZE(hp_dc_ch_r_seq),
1867 .msk = CS43130_HPLOAD_DC_INT,
1868 },
1869 {
1870 .seq = hp_ac_ch_r_seq,
1871 .size = ARRAY_SIZE(hp_ac_ch_r_seq),
1872 .msk = CS43130_HPLOAD_AC_INT,
1873 },
1874};
1875
1876static struct reg_sequences hpload_seq2[] = {
1877 {
1878 .seq = hp_en_cal_seq2,
1879 .size = ARRAY_SIZE(hp_en_cal_seq2),
1880 .msk = CS43130_HPLOAD_ON_INT,
1881 },
1882 {
1883 .seq = hp_dc_ch_l_seq2,
1884 .size = ARRAY_SIZE(hp_dc_ch_l_seq2),
1885 .msk = CS43130_HPLOAD_DC_INT,
1886 },
1887 {
1888 .seq = hp_ac_ch_l_seq2,
1889 .size = ARRAY_SIZE(hp_ac_ch_l_seq2),
1890 .msk = CS43130_HPLOAD_AC_INT,
1891 },
1892 {
1893 .seq = hp_dis_cal_seq2,
1894 .size = ARRAY_SIZE(hp_dis_cal_seq2),
1895 .msk = CS43130_HPLOAD_OFF_INT,
1896 },
1897 {
1898 .seq = hp_en_cal_seq2,
1899 .size = ARRAY_SIZE(hp_en_cal_seq2),
1900 .msk = CS43130_HPLOAD_ON_INT,
1901 },
1902 {
1903 .seq = hp_dc_ch_r_seq2,
1904 .size = ARRAY_SIZE(hp_dc_ch_r_seq2),
1905 .msk = CS43130_HPLOAD_DC_INT,
1906 },
1907 {
1908 .seq = hp_ac_ch_r_seq2,
1909 .size = ARRAY_SIZE(hp_ac_ch_r_seq2),
1910 .msk = CS43130_HPLOAD_AC_INT,
1911 },
1912};
1913
1914static int cs43130_update_hpload(unsigned int msk, int ac_idx,
1915 struct cs43130_private *cs43130)
1916{
1917 bool left_ch = true;
1918 unsigned int reg;
1919 u32 addr;
1920 u16 impedance;
1921 struct snd_soc_codec *codec = cs43130->codec;
1922
1923 switch (msk) {
1924 case CS43130_HPLOAD_DC_INT:
1925 case CS43130_HPLOAD_AC_INT:
1926 break;
1927 default:
1928 return 0;
1929 }
1930
1931 regmap_read(cs43130->regmap, CS43130_HP_LOAD_1, &reg);
1932 if (reg & CS43130_HPLOAD_CHN_SEL)
1933 left_ch = false;
1934
1935 if (msk == CS43130_HPLOAD_DC_INT)
1936 addr = CS43130_HP_DC_STAT_1;
1937 else
1938 addr = CS43130_HP_AC_STAT_1;
1939
1940 regmap_read(cs43130->regmap, addr, &reg);
1941 impedance = reg >> 3;
1942 regmap_read(cs43130->regmap, addr + 1, &reg);
1943 impedance |= reg << 5;
1944
1945 if (msk == CS43130_HPLOAD_DC_INT) {
1946 if (left_ch)
1947 cs43130->hpload_dc[HP_LEFT] = impedance;
1948 else
1949 cs43130->hpload_dc[HP_RIGHT] = impedance;
1950
1951 dev_dbg(codec->dev, "HP DC impedance (Ch %u): %u\n", !left_ch,
1952 impedance);
1953 } else {
1954 if (left_ch)
1955 cs43130->hpload_ac[ac_idx][HP_LEFT] = impedance;
1956 else
1957 cs43130->hpload_ac[ac_idx][HP_RIGHT] = impedance;
1958
1959 dev_dbg(codec->dev, "HP AC (%u Hz) impedance (Ch %u): %u\n",
1960 cs43130->ac_freq[ac_idx], !left_ch, impedance);
1961 }
1962
1963 return 0;
1964}
1965
1966static int cs43130_hpload_proc(struct cs43130_private *cs43130,
1967 struct reg_sequence *seq, int seq_size,
1968 unsigned int rslt_msk, int ac_idx)
1969{
1970 int ret;
1971 unsigned int msk;
1972 u16 ac_reg_val;
1973 struct snd_soc_codec *codec = cs43130->codec;
1974
1975 reinit_completion(&cs43130->hpload_evt);
1976
1977 if (rslt_msk == CS43130_HPLOAD_AC_INT) {
1978 ac_reg_val = cs43130_get_ac_reg_val(cs43130->ac_freq[ac_idx]);
1979 regmap_update_bits(cs43130->regmap, CS43130_HP_LOAD_1,
1980 CS43130_HPLOAD_AC_START, 0);
1981 regmap_update_bits(cs43130->regmap, CS43130_HP_MEAS_LOAD_1,
1982 CS43130_HP_MEAS_LOAD_MASK,
1983 ac_reg_val >> CS43130_HP_MEAS_LOAD_1_SHIFT);
1984 regmap_update_bits(cs43130->regmap, CS43130_HP_MEAS_LOAD_2,
1985 CS43130_HP_MEAS_LOAD_MASK,
1986 ac_reg_val >> CS43130_HP_MEAS_LOAD_2_SHIFT);
1987 }
1988
1989 regmap_multi_reg_write(cs43130->regmap, seq,
1990 seq_size);
1991
1992 ret = wait_for_completion_timeout(&cs43130->hpload_evt,
1993 msecs_to_jiffies(1000));
1994 regmap_read(cs43130->regmap, CS43130_INT_MASK_4, &msk);
1995 if (!ret) {
1996 dev_err(codec->dev, "Timeout waiting for HPLOAD interrupt\n");
1997 return -1;
1998 }
1999
2000 dev_dbg(codec->dev, "HP load stat: %x, INT_MASK_4: %x\n",
2001 cs43130->hpload_stat, msk);
2002 if ((cs43130->hpload_stat & (CS43130_HPLOAD_NO_DC_INT |
2003 CS43130_HPLOAD_UNPLUG_INT |
2004 CS43130_HPLOAD_OOR_INT)) ||
2005 !(cs43130->hpload_stat & rslt_msk)) {
2006 dev_dbg(codec->dev, "HP load measure failed\n");
2007 return -1;
2008 }
2009
2010 return 0;
2011}
2012
2013static const struct reg_sequence hv_seq[][2] = {
2014 {
2015 {CS43130_CLASS_H_CTL, 0x1C},
2016 {CS43130_HP_OUT_CTL_1, 0x10},
2017 },
2018 {
2019 {CS43130_CLASS_H_CTL, 0x1E},
2020 {CS43130_HP_OUT_CTL_1, 0x20},
2021 },
2022 {
2023 {CS43130_CLASS_H_CTL, 0x1E},
2024 {CS43130_HP_OUT_CTL_1, 0x30},
2025 },
2026};
2027
2028static int cs43130_set_hv(struct regmap *regmap, u16 hpload_dc,
2029 const u16 *dc_threshold)
2030{
2031 int i;
2032
2033 for (i = 0; i < CS43130_DC_THRESHOLD; i++) {
2034 if (hpload_dc <= dc_threshold[i])
2035 break;
2036 }
2037
2038 regmap_multi_reg_write(regmap, hv_seq[i], ARRAY_SIZE(hv_seq[i]));
2039
2040 return 0;
2041}
2042
2043static void cs43130_imp_meas(struct work_struct *wk)
2044{
2045 unsigned int reg, seq_size;
2046 int i, ret, ac_idx;
2047 struct cs43130_private *cs43130;
2048 struct snd_soc_codec *codec;
2049 struct reg_sequences *hpload_seq;
2050
2051 cs43130 = container_of(wk, struct cs43130_private, work);
2052 codec = cs43130->codec;
2053
2054 if (!cs43130->mclk)
2055 return;
2056
2057 cs43130->hpload_done = false;
2058
2059 mutex_lock(&cs43130->clk_mutex);
2060 if (!cs43130->clk_req) {
2061 /* clk not in use */
2062 cs43130_set_pll(codec, 0, 0, cs43130->mclk, CS43130_MCLK_22M);
2063 if (cs43130->pll_bypass)
2064 cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT);
2065 else
2066 cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL);
2067 }
2068
2069 cs43130->clk_req++;
2070 mutex_unlock(&cs43130->clk_mutex);
2071
2072 regmap_read(cs43130->regmap, CS43130_INT_STATUS_4, &reg);
2073
2074 switch (cs43130->dev_id) {
2075 case CS43130_CHIP_ID:
2076 hpload_seq = hpload_seq1;
2077 seq_size = ARRAY_SIZE(hpload_seq1);
2078 break;
2079 case CS43131_CHIP_ID:
2080 hpload_seq = hpload_seq2;
2081 seq_size = ARRAY_SIZE(hpload_seq2);
2082 }
2083
2084 i = 0;
2085 ac_idx = 0;
2086 while (i < seq_size) {
2087 ret = cs43130_hpload_proc(cs43130, hpload_seq[i].seq,
2088 hpload_seq[i].size,
2089 hpload_seq[i].msk, ac_idx);
2090 if (ret < 0)
2091 goto exit;
2092
2093 cs43130_update_hpload(hpload_seq[i].msk, ac_idx, cs43130);
2094
2095 if (cs43130->ac_meas &&
2096 hpload_seq[i].msk == CS43130_HPLOAD_AC_INT &&
2097 ac_idx < CS43130_AC_FREQ - 1) {
2098 ac_idx++;
2099 } else {
2100 ac_idx = 0;
2101 i++;
2102 }
2103 }
2104 cs43130->hpload_done = true;
2105
2106 if (cs43130->hpload_dc[HP_LEFT] >= CS43130_LINEOUT_LOAD)
2107 snd_soc_jack_report(&cs43130->jack, CS43130_JACK_LINEOUT,
2108 CS43130_JACK_MASK);
2109 else
2110 snd_soc_jack_report(&cs43130->jack, CS43130_JACK_HEADPHONE,
2111 CS43130_JACK_MASK);
2112
2113 dev_dbg(codec->dev, "Set HP output control. DC threshold\n");
2114 for (i = 0; i < CS43130_DC_THRESHOLD; i++)
2115 dev_dbg(codec->dev, "DC threshold[%d]: %u.\n", i,
2116 cs43130->dc_threshold[i]);
2117
2118 cs43130_set_hv(cs43130->regmap, cs43130->hpload_dc[HP_LEFT],
2119 cs43130->dc_threshold);
2120
2121exit:
2122 switch (cs43130->dev_id) {
2123 case CS43130_CHIP_ID:
2124 cs43130_hpload_proc(cs43130, hp_dis_cal_seq,
2125 ARRAY_SIZE(hp_dis_cal_seq),
2126 CS43130_HPLOAD_OFF_INT, ac_idx);
2127 break;
2128 case CS43131_CHIP_ID:
2129 cs43130_hpload_proc(cs43130, hp_dis_cal_seq2,
2130 ARRAY_SIZE(hp_dis_cal_seq2),
2131 CS43130_HPLOAD_OFF_INT, ac_idx);
2132 }
2133
2134 regmap_multi_reg_write(cs43130->regmap, hp_cln_seq,
2135 ARRAY_SIZE(hp_cln_seq));
2136
2137 mutex_lock(&cs43130->clk_mutex);
2138 cs43130->clk_req--;
2139 /* clk not in use */
2140 if (!cs43130->clk_req)
2141 cs43130_change_clksrc(codec, CS43130_MCLK_SRC_RCO);
2142 mutex_unlock(&cs43130->clk_mutex);
2143}
2144
2145static irqreturn_t cs43130_irq_thread(int irq, void *data)
2146{
2147 struct cs43130_private *cs43130 = (struct cs43130_private *)data;
2148 struct snd_soc_codec *codec = cs43130->codec;
2149 unsigned int stickies[CS43130_NUM_INT];
2150 unsigned int irq_occurrance = 0;
2151 unsigned int masks[CS43130_NUM_INT];
2152 int i, j;
2153
2154 for (i = 0; i < ARRAY_SIZE(stickies); i++) {
2155 regmap_read(cs43130->regmap, CS43130_INT_STATUS_1 + i,
2156 &stickies[i]);
2157 regmap_read(cs43130->regmap, CS43130_INT_MASK_1 + i,
2158 &masks[i]);
2159 }
2160
2161 for (i = 0; i < ARRAY_SIZE(stickies); i++) {
2162 stickies[i] = stickies[i] & (~masks[i]);
2163 for (j = 0; j < 8; j++)
2164 irq_occurrance += (stickies[i] >> j) & 1;
2165 }
2166 dev_dbg(codec->dev, "number of interrupts occurred (%u)\n",
2167 irq_occurrance);
2168
2169 if (!irq_occurrance)
2170 return IRQ_NONE;
2171
2172 if (stickies[0] & CS43130_XTAL_RDY_INT) {
2173 complete(&cs43130->xtal_rdy);
2174 return IRQ_HANDLED;
2175 }
2176
2177 if (stickies[0] & CS43130_PLL_RDY_INT) {
2178 complete(&cs43130->pll_rdy);
2179 return IRQ_HANDLED;
2180 }
2181
2182 if (stickies[3] & CS43130_HPLOAD_NO_DC_INT) {
2183 cs43130->hpload_stat = stickies[3];
2184 dev_err(codec->dev,
2185 "DC load has not completed before AC load (%x)\n",
2186 cs43130->hpload_stat);
2187 complete(&cs43130->hpload_evt);
2188 return IRQ_HANDLED;
2189 }
2190
2191 if (stickies[3] & CS43130_HPLOAD_UNPLUG_INT) {
2192 cs43130->hpload_stat = stickies[3];
2193 dev_err(codec->dev, "HP unplugged during measurement (%x)\n",
2194 cs43130->hpload_stat);
2195 complete(&cs43130->hpload_evt);
2196 return IRQ_HANDLED;
2197 }
2198
2199 if (stickies[3] & CS43130_HPLOAD_OOR_INT) {
2200 cs43130->hpload_stat = stickies[3];
2201 dev_err(codec->dev, "HP load out of range (%x)\n",
2202 cs43130->hpload_stat);
2203 complete(&cs43130->hpload_evt);
2204 return IRQ_HANDLED;
2205 }
2206
2207 if (stickies[3] & CS43130_HPLOAD_AC_INT) {
2208 cs43130->hpload_stat = stickies[3];
2209 dev_dbg(codec->dev, "HP AC load measurement done (%x)\n",
2210 cs43130->hpload_stat);
2211 complete(&cs43130->hpload_evt);
2212 return IRQ_HANDLED;
2213 }
2214
2215 if (stickies[3] & CS43130_HPLOAD_DC_INT) {
2216 cs43130->hpload_stat = stickies[3];
2217 dev_dbg(codec->dev, "HP DC load measurement done (%x)\n",
2218 cs43130->hpload_stat);
2219 complete(&cs43130->hpload_evt);
2220 return IRQ_HANDLED;
2221 }
2222
2223 if (stickies[3] & CS43130_HPLOAD_ON_INT) {
2224 cs43130->hpload_stat = stickies[3];
2225 dev_dbg(codec->dev, "HP load state machine on done (%x)\n",
2226 cs43130->hpload_stat);
2227 complete(&cs43130->hpload_evt);
2228 return IRQ_HANDLED;
2229 }
2230
2231 if (stickies[3] & CS43130_HPLOAD_OFF_INT) {
2232 cs43130->hpload_stat = stickies[3];
2233 dev_dbg(codec->dev, "HP load state machine off done (%x)\n",
2234 cs43130->hpload_stat);
2235 complete(&cs43130->hpload_evt);
2236 return IRQ_HANDLED;
2237 }
2238
2239 if (stickies[0] & CS43130_XTAL_ERR_INT) {
2240 dev_err(codec->dev, "Crystal err: clock is not running\n");
2241 return IRQ_HANDLED;
2242 }
2243
2244 if (stickies[0] & CS43130_HP_UNPLUG_INT) {
2245 dev_dbg(codec->dev, "HP unplugged\n");
2246 cs43130->hpload_done = false;
2247 snd_soc_jack_report(&cs43130->jack, 0, CS43130_JACK_MASK);
2248 return IRQ_HANDLED;
2249 }
2250
2251 if (stickies[0] & CS43130_HP_PLUG_INT) {
2252 if (cs43130->dc_meas && !cs43130->hpload_done &&
2253 !work_busy(&cs43130->work)) {
2254 dev_dbg(codec->dev, "HP load queue work\n");
2255 queue_work(cs43130->wq, &cs43130->work);
2256 }
2257
2258 snd_soc_jack_report(&cs43130->jack, SND_JACK_MECHANICAL,
2259 CS43130_JACK_MASK);
2260 return IRQ_HANDLED;
2261 }
2262
2263 return IRQ_NONE;
2264}
2265
2266static int cs43130_probe(struct snd_soc_codec *codec)
2267{
2268 int ret;
2269 struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
2270 struct snd_soc_card *card = codec->component.card;
2271 unsigned int reg;
2272
2273 cs43130->codec = codec;
2274
2275 if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED) {
2276 regmap_update_bits(cs43130->regmap, CS43130_CRYSTAL_SET,
2277 CS43130_XTAL_IBIAS_MASK,
2278 cs43130->xtal_ibias);
2279 regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
2280 CS43130_XTAL_ERR_INT, 0);
2281 }
2282
2283 ret = snd_soc_card_jack_new(card, "Headphone", CS43130_JACK_MASK,
2284 &cs43130->jack, NULL, 0);
2285 if (ret < 0) {
2286 dev_err(codec->dev, "Cannot create jack\n");
2287 return ret;
2288 }
2289
2290 cs43130->hpload_done = false;
2291 if (cs43130->dc_meas) {
2292 ret = device_create_file(codec->dev, &dev_attr_hpload_dc_l);
2293 if (ret < 0)
2294 return ret;
2295
2296 ret = device_create_file(codec->dev, &dev_attr_hpload_dc_r);
2297 if (ret < 0)
2298 return ret;
2299
2300 ret = device_create_file(codec->dev, &dev_attr_hpload_ac_l);
2301 if (ret < 0)
2302 return ret;
2303
2304 ret = device_create_file(codec->dev, &dev_attr_hpload_ac_r);
2305 if (ret < 0)
2306 return ret;
2307
2308 cs43130->wq = create_singlethread_workqueue("cs43130_hp");
2309 INIT_WORK(&cs43130->work, cs43130_imp_meas);
2310 }
2311
2312 regmap_read(cs43130->regmap, CS43130_INT_STATUS_1, &reg);
2313 regmap_read(cs43130->regmap, CS43130_HP_STATUS, &reg);
2314 regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
2315 CS43130_HP_PLUG_INT | CS43130_HP_UNPLUG_INT, 0);
2316 regmap_update_bits(cs43130->regmap, CS43130_HP_DETECT,
2317 CS43130_HP_DETECT_CTRL_MASK, 0);
2318 regmap_update_bits(cs43130->regmap, CS43130_HP_DETECT,
2319 CS43130_HP_DETECT_CTRL_MASK,
2320 CS43130_HP_DETECT_CTRL_MASK);
2321
2322 return 0;
2323}
2324
2325static struct snd_soc_codec_driver soc_codec_dev_cs43130 = {
2326 .probe = cs43130_probe,
2327 .component_driver = {
2328 .controls = cs43130_snd_controls,
2329 .num_controls = ARRAY_SIZE(cs43130_snd_controls),
2330 },
2331 .set_sysclk = cs43130_codec_set_sysclk,
2332 .set_pll = cs43130_set_pll,
2333};
2334
2335static const struct regmap_config cs43130_regmap = {
2336 .reg_bits = 24,
2337 .pad_bits = 8,
2338 .val_bits = 8,
2339
2340 .max_register = CS43130_LASTREG,
2341 .reg_defaults = cs43130_reg_defaults,
2342 .num_reg_defaults = ARRAY_SIZE(cs43130_reg_defaults),
2343 .readable_reg = cs43130_readable_register,
2344 .precious_reg = cs43130_precious_register,
2345 .volatile_reg = cs43130_volatile_register,
2346 .cache_type = REGCACHE_RBTREE,
2347 .use_single_rw = true, /* needed for regcache_sync */
2348};
2349
2350static u16 const cs43130_dc_threshold[CS43130_DC_THRESHOLD] = {
2351 50,
2352 120,
2353};
2354
2355static int cs43130_handle_device_data(struct i2c_client *i2c_client,
2356 struct cs43130_private *cs43130)
2357{
2358 struct device_node *np = i2c_client->dev.of_node;
2359 unsigned int val;
2360 int i;
2361
2362 if (of_property_read_u32(np, "cirrus,xtal-ibias", &val) < 0) {
2363 /* Crystal is unused. System clock is used for external MCLK */
2364 cs43130->xtal_ibias = CS43130_XTAL_UNUSED;
2365 return 0;
2366 }
2367
2368 switch (val) {
2369 case 1:
2370 cs43130->xtal_ibias = CS43130_XTAL_IBIAS_7_5UA;
2371 break;
2372 case 2:
2373 cs43130->xtal_ibias = CS43130_XTAL_IBIAS_12_5UA;
2374 break;
2375 case 3:
2376 cs43130->xtal_ibias = CS43130_XTAL_IBIAS_15UA;
2377 break;
2378 default:
2379 dev_err(&i2c_client->dev,
2380 "Invalid cirrus,xtal-ibias value: %d\n", val);
2381 return -EINVAL;
2382 }
2383
2384 cs43130->dc_meas = of_property_read_bool(np, "cirrus,dc-measure");
2385 cs43130->ac_meas = of_property_read_bool(np, "cirrus,ac-measure");
2386
2387 if (of_property_read_u16_array(np, "cirrus,ac-freq", cs43130->ac_freq,
2388 CS43130_AC_FREQ) < 0) {
2389 for (i = 0; i < CS43130_AC_FREQ; i++)
2390 cs43130->ac_freq[i] = cs43130_ac_freq[i];
2391 }
2392
2393 if (of_property_read_u16_array(np, "cirrus,dc-threshold",
2394 cs43130->dc_threshold,
2395 CS43130_DC_THRESHOLD) < 0) {
2396 for (i = 0; i < CS43130_DC_THRESHOLD; i++)
2397 cs43130->dc_threshold[i] = cs43130_dc_threshold[i];
2398 }
2399
2400 return 0;
2401}
2402
2403static int cs43130_i2c_probe(struct i2c_client *client,
2404 const struct i2c_device_id *id)
2405{
2406 struct cs43130_private *cs43130;
2407 int ret;
2408 unsigned int devid = 0;
2409 unsigned int reg;
2410 int i;
2411
2412 cs43130 = devm_kzalloc(&client->dev, sizeof(*cs43130), GFP_KERNEL);
2413 if (!cs43130)
2414 return -ENOMEM;
2415
2416 i2c_set_clientdata(client, cs43130);
2417
2418 cs43130->regmap = devm_regmap_init_i2c(client, &cs43130_regmap);
2419 if (IS_ERR(cs43130->regmap)) {
2420 ret = PTR_ERR(cs43130->regmap);
2421 return ret;
2422 }
2423
2424 if (client->dev.of_node) {
2425 ret = cs43130_handle_device_data(client, cs43130);
2426 if (ret != 0)
2427 return ret;
2428 }
2429 for (i = 0; i < ARRAY_SIZE(cs43130->supplies); i++)
2430 cs43130->supplies[i].supply = cs43130_supply_names[i];
2431
2432 ret = devm_regulator_bulk_get(&client->dev,
2433 ARRAY_SIZE(cs43130->supplies),
2434 cs43130->supplies);
2435 if (ret != 0) {
2436 dev_err(&client->dev, "Failed to request supplies: %d\n", ret);
2437 return ret;
2438 }
2439 ret = regulator_bulk_enable(ARRAY_SIZE(cs43130->supplies),
2440 cs43130->supplies);
2441 if (ret != 0) {
2442 dev_err(&client->dev, "Failed to enable supplies: %d\n", ret);
2443 return ret;
2444 }
2445
2446 cs43130->reset_gpio = devm_gpiod_get_optional(&client->dev,
2447 "reset", GPIOD_OUT_LOW);
2448 if (IS_ERR(cs43130->reset_gpio))
2449 return PTR_ERR(cs43130->reset_gpio);
2450
2451 gpiod_set_value_cansleep(cs43130->reset_gpio, 1);
2452
2453 usleep_range(2000, 2050);
2454
2455 ret = regmap_read(cs43130->regmap, CS43130_DEVID_AB, &reg);
2456
2457 devid = (reg & 0xFF) << 12;
2458 ret = regmap_read(cs43130->regmap, CS43130_DEVID_CD, &reg);
2459 devid |= (reg & 0xFF) << 4;
2460 ret = regmap_read(cs43130->regmap, CS43130_DEVID_E, &reg);
2461 devid |= (reg & 0xF0) >> 4;
2462
2463 switch (devid) {
2464 case CS43130_CHIP_ID:
2465 case CS4399_CHIP_ID:
2466 case CS43131_CHIP_ID:
2467 case CS43198_CHIP_ID:
2468 break;
2469 default:
2470 dev_err(&client->dev,
2471 "CS43130 Device ID %X. Expected ID %X, %X, %X or %X\n",
2472 devid, CS43130_CHIP_ID, CS4399_CHIP_ID,
2473 CS43131_CHIP_ID, CS43198_CHIP_ID);
2474 ret = -ENODEV;
2475 goto err;
2476 }
2477
2478 cs43130->dev_id = devid;
2479 ret = regmap_read(cs43130->regmap, CS43130_REV_ID, &reg);
2480 if (ret < 0) {
2481 dev_err(&client->dev, "Get Revision ID failed\n");
2482 goto err;
2483 }
2484
2485 dev_info(&client->dev,
2486 "Cirrus Logic CS43130 (%x), Revision: %02X\n", devid,
2487 reg & 0xFF);
2488
2489 mutex_init(&cs43130->clk_mutex);
2490
2491 init_completion(&cs43130->xtal_rdy);
2492 init_completion(&cs43130->pll_rdy);
2493 init_completion(&cs43130->hpload_evt);
2494
2495 ret = devm_request_threaded_irq(&client->dev, client->irq,
2496 NULL, cs43130_irq_thread,
2497 IRQF_ONESHOT | IRQF_TRIGGER_LOW,
2498 "cs43130", cs43130);
2499 if (ret != 0) {
2500 dev_err(&client->dev, "Failed to request IRQ: %d\n", ret);
2501 return ret;
2502 }
2503
2504 cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO;
2505
2506 pm_runtime_set_autosuspend_delay(&client->dev, 100);
2507 pm_runtime_use_autosuspend(&client->dev);
2508 pm_runtime_set_active(&client->dev);
2509 pm_runtime_enable(&client->dev);
2510
2511 switch (cs43130->dev_id) {
2512 case CS43130_CHIP_ID:
2513 case CS43131_CHIP_ID:
2514 memcpy(all_hp_widgets, digital_hp_widgets,
2515 sizeof(digital_hp_widgets));
2516 memcpy(all_hp_widgets + ARRAY_SIZE(digital_hp_widgets),
2517 analog_hp_widgets, sizeof(analog_hp_widgets));
2518 memcpy(all_hp_routes, digital_hp_routes,
2519 sizeof(digital_hp_routes));
2520 memcpy(all_hp_routes + ARRAY_SIZE(digital_hp_routes),
2521 analog_hp_routes, sizeof(analog_hp_routes));
2522
2523 soc_codec_dev_cs43130.component_driver.dapm_widgets =
2524 all_hp_widgets;
2525 soc_codec_dev_cs43130.component_driver.num_dapm_widgets =
2526 ARRAY_SIZE(all_hp_widgets);
2527 soc_codec_dev_cs43130.component_driver.dapm_routes =
2528 all_hp_routes;
2529 soc_codec_dev_cs43130.component_driver.num_dapm_routes =
2530 ARRAY_SIZE(all_hp_routes);
2531 break;
2532 case CS43198_CHIP_ID:
2533 case CS4399_CHIP_ID:
2534 soc_codec_dev_cs43130.component_driver.dapm_widgets =
2535 digital_hp_widgets;
2536 soc_codec_dev_cs43130.component_driver.num_dapm_widgets =
2537 ARRAY_SIZE(digital_hp_widgets);
2538 soc_codec_dev_cs43130.component_driver.dapm_routes =
2539 digital_hp_routes;
2540 soc_codec_dev_cs43130.component_driver.num_dapm_routes =
2541 ARRAY_SIZE(digital_hp_routes);
2542 }
2543
2544 ret = snd_soc_register_codec(&client->dev, &soc_codec_dev_cs43130,
2545 cs43130_dai, ARRAY_SIZE(cs43130_dai));
2546 if (ret < 0) {
2547 dev_err(&client->dev,
2548 "snd_soc_register_codec failed with ret = %d\n", ret);
2549 goto err;
2550 }
2551
2552 regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG,
2553 CS43130_ASP_3ST_MASK, 0);
2554 regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG,
2555 CS43130_XSP_3ST_MASK, 0);
2556
2557 return 0;
2558err:
2559 return ret;
2560}
2561
2562static int cs43130_i2c_remove(struct i2c_client *client)
2563{
2564 struct cs43130_private *cs43130 = i2c_get_clientdata(client);
2565
2566 if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED)
2567 regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
2568 CS43130_XTAL_ERR_INT,
2569 1 << CS43130_XTAL_ERR_INT_SHIFT);
2570
2571 regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
2572 CS43130_HP_PLUG_INT | CS43130_HP_UNPLUG_INT,
2573 CS43130_HP_PLUG_INT | CS43130_HP_UNPLUG_INT);
2574
2575 if (cs43130->dc_meas) {
2576 cancel_work_sync(&cs43130->work);
2577 flush_workqueue(cs43130->wq);
2578
2579 device_remove_file(&client->dev, &dev_attr_hpload_dc_l);
2580 device_remove_file(&client->dev, &dev_attr_hpload_dc_r);
2581 device_remove_file(&client->dev, &dev_attr_hpload_ac_l);
2582 device_remove_file(&client->dev, &dev_attr_hpload_ac_r);
2583 }
2584
2585 if (cs43130->reset_gpio)
2586 gpiod_set_value_cansleep(cs43130->reset_gpio, 0);
2587
2588 pm_runtime_disable(&client->dev);
2589 regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies);
2590
2591 snd_soc_unregister_codec(&client->dev);
2592
2593 return 0;
2594}
2595
2596static int cs43130_runtime_suspend(struct device *dev)
2597{
2598 struct cs43130_private *cs43130 = dev_get_drvdata(dev);
2599
2600 if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED)
2601 regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
2602 CS43130_XTAL_ERR_INT,
2603 1 << CS43130_XTAL_ERR_INT_SHIFT);
2604
2605 regcache_cache_only(cs43130->regmap, true);
2606 regcache_mark_dirty(cs43130->regmap);
2607
2608 gpiod_set_value_cansleep(cs43130->reset_gpio, 0);
2609
2610 regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies);
2611
2612 return 0;
2613}
2614
2615static int cs43130_runtime_resume(struct device *dev)
2616{
2617 struct cs43130_private *cs43130 = dev_get_drvdata(dev);
2618 int ret;
2619
2620 ret = regulator_bulk_enable(CS43130_NUM_SUPPLIES, cs43130->supplies);
2621 if (ret != 0) {
2622 dev_err(dev, "Failed to enable supplies: %d\n", ret);
2623 return ret;
2624 }
2625
2626 regcache_cache_only(cs43130->regmap, false);
2627
2628 gpiod_set_value_cansleep(cs43130->reset_gpio, 1);
2629
2630 usleep_range(2000, 2050);
2631
2632 ret = regcache_sync(cs43130->regmap);
2633 if (ret != 0) {
2634 dev_err(dev, "Failed to restore register cache\n");
2635 goto err;
2636 }
2637
2638 if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED)
2639 regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
2640 CS43130_XTAL_ERR_INT, 0);
2641
2642 return 0;
2643err:
2644 regcache_cache_only(cs43130->regmap, true);
2645 regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies);
2646
2647 return ret;
2648}
2649
2650static const struct dev_pm_ops cs43130_runtime_pm = {
2651 SET_RUNTIME_PM_OPS(cs43130_runtime_suspend, cs43130_runtime_resume,
2652 NULL)
2653};
2654
2655static const struct of_device_id cs43130_of_match[] = {
2656 {.compatible = "cirrus,cs43130",},
2657 {.compatible = "cirrus,cs4399",},
2658 {.compatible = "cirrus,cs43131",},
2659 {.compatible = "cirrus,cs43198",},
2660 {},
2661};
2662
2663MODULE_DEVICE_TABLE(of, cs43130_of_match);
2664
2665static const struct i2c_device_id cs43130_i2c_id[] = {
2666 {"cs43130", 0},
2667 {"cs4399", 0},
2668 {"cs43131", 0},
2669 {"cs43198", 0},
2670 {}
2671};
2672
2673MODULE_DEVICE_TABLE(i2c, cs43130_i2c_id);
2674
2675static struct i2c_driver cs43130_i2c_driver = {
2676 .driver = {
2677 .name = "cs43130",
2678 .of_match_table = cs43130_of_match,
2679 .pm = &cs43130_runtime_pm,
2680 },
2681 .id_table = cs43130_i2c_id,
2682 .probe = cs43130_i2c_probe,
2683 .remove = cs43130_i2c_remove,
2684};
2685
2686module_i2c_driver(cs43130_i2c_driver);
2687
2688MODULE_AUTHOR("Li Xu <li.xu@cirrus.com>");
2689MODULE_DESCRIPTION("Cirrus Logic CS43130 ALSA SoC Codec Driver");
2690MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs43130.h b/sound/soc/codecs/cs43130.h
new file mode 100644
index 000000000000..781258418d89
--- /dev/null
+++ b/sound/soc/codecs/cs43130.h
@@ -0,0 +1,546 @@
1/*
2 * ALSA SoC CS43130 codec driver
3 *
4 * Copyright 2017 Cirrus Logic, Inc.
5 *
6 * Author: Li Xu <li.xu@cirrus.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 */
18
19#ifndef __CS43130_H__
20#define __CS43130_H__
21
22/* CS43130 registers addresses */
23/* all reg address is shifted by a byte for control byte to be LSB */
24#define CS43130_FIRSTREG 0x010000
25#define CS43130_LASTREG 0x190000
26#define CS43130_CHIP_ID 0x00043130
27#define CS4399_CHIP_ID 0x00043990
28#define CS43131_CHIP_ID 0x00043131
29#define CS43198_CHIP_ID 0x00043198
30#define CS43130_DEVID_AB 0x010000 /* Device ID A & B [RO] */
31#define CS43130_DEVID_CD 0x010001 /* Device ID C & D [RO] */
32#define CS43130_DEVID_E 0x010002 /* Device ID E [RO] */
33#define CS43130_FAB_ID 0x010003 /* Fab ID [RO] */
34#define CS43130_REV_ID 0x010004 /* Revision ID [RO] */
35#define CS43130_SUBREV_ID 0x010005 /* Subrevision ID */
36#define CS43130_SYS_CLK_CTL_1 0x010006 /* System Clocking Ctl 1 */
37#define CS43130_SP_SRATE 0x01000B /* Serial Port Sample Rate */
38#define CS43130_SP_BITSIZE 0x01000C /* Serial Port Bit Size */
39#define CS43130_PAD_INT_CFG 0x01000D /* Pad Interface Config */
40#define CS43130_DXD1 0x010010 /* DXD1 */
41#define CS43130_DXD7 0x010025 /* DXD7 */
42#define CS43130_DXD19 0x010026 /* DXD19 */
43#define CS43130_DXD17 0x010027 /* DXD17 */
44#define CS43130_DXD18 0x010028 /* DXD18 */
45#define CS43130_DXD12 0x01002C /* DXD12 */
46#define CS43130_DXD8 0x01002E /* DXD8 */
47#define CS43130_PWDN_CTL 0x020000 /* Power Down Ctl */
48#define CS43130_DXD2 0x020019 /* DXD2 */
49#define CS43130_CRYSTAL_SET 0x020052 /* Crystal Setting */
50#define CS43130_PLL_SET_1 0x030001 /* PLL Setting 1 */
51#define CS43130_PLL_SET_2 0x030002 /* PLL Setting 2 */
52#define CS43130_PLL_SET_3 0x030003 /* PLL Setting 3 */
53#define CS43130_PLL_SET_4 0x030004 /* PLL Setting 4 */
54#define CS43130_PLL_SET_5 0x030005 /* PLL Setting 5 */
55#define CS43130_PLL_SET_6 0x030008 /* PLL Setting 6 */
56#define CS43130_PLL_SET_7 0x03000A /* PLL Setting 7 */
57#define CS43130_PLL_SET_8 0x03001B /* PLL Setting 8 */
58#define CS43130_PLL_SET_9 0x040002 /* PLL Setting 9 */
59#define CS43130_PLL_SET_10 0x040003 /* PLL Setting 10 */
60#define CS43130_CLKOUT_CTL 0x040004 /* CLKOUT Ctl */
61#define CS43130_ASP_NUM_1 0x040010 /* ASP Numerator 1 */
62#define CS43130_ASP_NUM_2 0x040011 /* ASP Numerator 2 */
63#define CS43130_ASP_DEN_1 0x040012 /* ASP Denominator 1 */
64#define CS43130_ASP_DEN_2 0x040013 /* ASP Denominator 2 */
65#define CS43130_ASP_LRCK_HI_TIME_1 0x040014 /* ASP LRCK High Time 1 */
66#define CS43130_ASP_LRCK_HI_TIME_2 0x040015 /* ASP LRCK High Time 2 */
67#define CS43130_ASP_LRCK_PERIOD_1 0x040016 /* ASP LRCK Period 1 */
68#define CS43130_ASP_LRCK_PERIOD_2 0x040017 /* ASP LRCK Period 2 */
69#define CS43130_ASP_CLOCK_CONF 0x040018 /* ASP Clock Config */
70#define CS43130_ASP_FRAME_CONF 0x040019 /* ASP Frame Config */
71#define CS43130_XSP_NUM_1 0x040020 /* XSP Numerator 1 */
72#define CS43130_XSP_NUM_2 0x040021 /* XSP Numerator 2 */
73#define CS43130_XSP_DEN_1 0x040022 /* XSP Denominator 1 */
74#define CS43130_XSP_DEN_2 0x040023 /* XSP Denominator 2 */
75#define CS43130_XSP_LRCK_HI_TIME_1 0x040024 /* XSP LRCK High Time 1 */
76#define CS43130_XSP_LRCK_HI_TIME_2 0x040025 /* XSP LRCK High Time 2 */
77#define CS43130_XSP_LRCK_PERIOD_1 0x040026 /* XSP LRCK Period 1 */
78#define CS43130_XSP_LRCK_PERIOD_2 0x040027 /* XSP LRCK Period 2 */
79#define CS43130_XSP_CLOCK_CONF 0x040028 /* XSP Clock Config */
80#define CS43130_XSP_FRAME_CONF 0x040029 /* XSP Frame Config */
81#define CS43130_ASP_CH_1_LOC 0x050000 /* ASP Chan 1 Location */
82#define CS43130_ASP_CH_2_LOC 0x050001 /* ASP Chan 2 Location */
83#define CS43130_ASP_CH_1_SZ_EN 0x05000A /* ASP Chan 1 Size, Enable */
84#define CS43130_ASP_CH_2_SZ_EN 0x05000B /* ASP Chan 2 Size, Enable */
85#define CS43130_XSP_CH_1_LOC 0x060000 /* XSP Chan 1 Location */
86#define CS43130_XSP_CH_2_LOC 0x060001 /* XSP Chan 2 Location */
87#define CS43130_XSP_CH_1_SZ_EN 0x06000A /* XSP Chan 1 Size, Enable */
88#define CS43130_XSP_CH_2_SZ_EN 0x06000B /* XSP Chan 2 Size, Enable */
89#define CS43130_DSD_VOL_B 0x070000 /* DSD Volume B */
90#define CS43130_DSD_VOL_A 0x070001 /* DSD Volume A */
91#define CS43130_DSD_PATH_CTL_1 0x070002 /* DSD Proc Path Sig Ctl 1 */
92#define CS43130_DSD_INT_CFG 0x070003 /* DSD Interface Config */
93#define CS43130_DSD_PATH_CTL_2 0x070004 /* DSD Proc Path Sig Ctl 2 */
94#define CS43130_DSD_PCM_MIX_CTL 0x070005 /* DSD and PCM Mixing Ctl */
95#define CS43130_DSD_PATH_CTL_3 0x070006 /* DSD Proc Path Sig Ctl 3 */
96#define CS43130_HP_OUT_CTL_1 0x080000 /* HP Output Ctl 1 */
97#define CS43130_DXD16 0x080024 /* DXD16 */
98#define CS43130_DXD13 0x080032 /* DXD13 */
99#define CS43130_PCM_FILT_OPT 0x090000 /* PCM Filter Option */
100#define CS43130_PCM_VOL_B 0x090001 /* PCM Volume B */
101#define CS43130_PCM_VOL_A 0x090002 /* PCM Volume A */
102#define CS43130_PCM_PATH_CTL_1 0x090003 /* PCM Path Signal Ctl 1 */
103#define CS43130_PCM_PATH_CTL_2 0x090004 /* PCM Path Signal Ctl 2 */
104#define CS43130_DXD6 0x090097 /* DXD6 */
105#define CS43130_CLASS_H_CTL 0x0B0000 /* Class H Ctl */
106#define CS43130_DXD15 0x0B0005 /* DXD15 */
107#define CS43130_DXD14 0x0B0006 /* DXD14 */
108#define CS43130_DXD3 0x0C0002 /* DXD3 */
109#define CS43130_DXD10 0x0C0003 /* DXD10 */
110#define CS43130_DXD11 0x0C0005 /* DXD11 */
111#define CS43130_DXD9 0x0C0006 /* DXD9 */
112#define CS43130_DXD4 0x0C0009 /* DXD4 */
113#define CS43130_DXD5 0x0C000E /* DXD5 */
114#define CS43130_HP_DETECT 0x0D0000 /* HP Detect */
115#define CS43130_HP_STATUS 0x0D0001 /* HP Status [RO] */
116#define CS43130_HP_LOAD_1 0x0E0000 /* HP Load 1 */
117#define CS43130_HP_MEAS_LOAD_1 0x0E0003 /* HP Load Measurement 1 */
118#define CS43130_HP_MEAS_LOAD_2 0x0E0004 /* HP Load Measurement 2 */
119#define CS43130_HP_DC_STAT_1 0x0E000D /* HP DC Load Status 0 [RO] */
120#define CS43130_HP_DC_STAT_2 0x0E000E /* HP DC Load Status 1 [RO] */
121#define CS43130_HP_AC_STAT_1 0x0E0010 /* HP AC Load Status 0 [RO] */
122#define CS43130_HP_AC_STAT_2 0x0E0011 /* HP AC Load Status 1 [RO] */
123#define CS43130_HP_LOAD_STAT 0x0E001A /* HP Load Status [RO] */
124#define CS43130_INT_STATUS_1 0x0F0000 /* Interrupt Status 1 */
125#define CS43130_INT_STATUS_2 0x0F0001 /* Interrupt Status 2 */
126#define CS43130_INT_STATUS_3 0x0F0002 /* Interrupt Status 3 */
127#define CS43130_INT_STATUS_4 0x0F0003 /* Interrupt Status 4 */
128#define CS43130_INT_STATUS_5 0x0F0004 /* Interrupt Status 5 */
129#define CS43130_INT_MASK_1 0x0F0010 /* Interrupt Mask 1 */
130#define CS43130_INT_MASK_2 0x0F0011 /* Interrupt Mask 2 */
131#define CS43130_INT_MASK_3 0x0F0012 /* Interrupt Mask 3 */
132#define CS43130_INT_MASK_4 0x0F0013 /* Interrupt Mask 4 */
133#define CS43130_INT_MASK_5 0x0F0014 /* Interrupt Mask 5 */
134
135#define CS43130_MCLK_SRC_SEL_MASK 0x03
136#define CS43130_MCLK_SRC_SEL_SHIFT 0
137#define CS43130_MCLK_INT_MASK 0x04
138#define CS43130_MCLK_INT_SHIFT 2
139#define CS43130_CH_BITSIZE_MASK 0x03
140#define CS43130_CH_EN_MASK 0x04
141#define CS43130_CH_EN_SHIFT 2
142#define CS43130_ASP_BITSIZE_MASK 0x03
143#define CS43130_XSP_BITSIZE_MASK 0x0C
144#define CS43130_XSP_BITSIZE_SHIFT 2
145#define CS43130_SP_BITSIZE_ASP_SHIFT 0
146#define CS43130_HP_DETECT_CTRL_SHIFT 6
147#define CS43130_HP_DETECT_CTRL_MASK (0x03 << CS43130_HP_DETECT_CTRL_SHIFT)
148#define CS43130_HP_DETECT_INV_SHIFT 5
149#define CS43130_HP_DETECT_INV_MASK (1 << CS43130_HP_DETECT_INV_SHIFT)
150
151/* CS43130_INT_MASK_1 */
152#define CS43130_HP_PLUG_INT_SHIFT 6
153#define CS43130_HP_PLUG_INT (1 << CS43130_HP_PLUG_INT_SHIFT)
154#define CS43130_HP_UNPLUG_INT_SHIFT 5
155#define CS43130_HP_UNPLUG_INT (1 << CS43130_HP_UNPLUG_INT_SHIFT)
156#define CS43130_XTAL_RDY_INT_SHIFT 4
157#define CS43130_XTAL_RDY_INT_MASK 0x10
158#define CS43130_XTAL_RDY_INT (1 << CS43130_XTAL_RDY_INT_SHIFT)
159#define CS43130_XTAL_ERR_INT_SHIFT 3
160#define CS43130_XTAL_ERR_INT (1 << CS43130_XTAL_ERR_INT_SHIFT)
161#define CS43130_PLL_RDY_INT_MASK 0x04
162#define CS43130_PLL_RDY_INT_SHIFT 2
163#define CS43130_PLL_RDY_INT (1 << CS43130_PLL_RDY_INT_SHIFT)
164
165/* CS43130_INT_MASK_4 */
166#define CS43130_INT_MASK_ALL 0xFF
167#define CS43130_HPLOAD_NO_DC_INT_SHIFT 7
168#define CS43130_HPLOAD_NO_DC_INT (1 << CS43130_HPLOAD_NO_DC_INT_SHIFT)
169#define CS43130_HPLOAD_UNPLUG_INT_SHIFT 6
170#define CS43130_HPLOAD_UNPLUG_INT (1 << CS43130_HPLOAD_UNPLUG_INT_SHIFT)
171#define CS43130_HPLOAD_OOR_INT_SHIFT 4
172#define CS43130_HPLOAD_OOR_INT (1 << CS43130_HPLOAD_OOR_INT_SHIFT)
173#define CS43130_HPLOAD_AC_INT_SHIFT 3
174#define CS43130_HPLOAD_AC_INT (1 << CS43130_HPLOAD_AC_INT_SHIFT)
175#define CS43130_HPLOAD_DC_INT_SHIFT 2
176#define CS43130_HPLOAD_DC_INT (1 << CS43130_HPLOAD_DC_INT_SHIFT)
177#define CS43130_HPLOAD_OFF_INT_SHIFT 1
178#define CS43130_HPLOAD_OFF_INT (1 << CS43130_HPLOAD_OFF_INT_SHIFT)
179#define CS43130_HPLOAD_ON_INT 1
180
181/* CS43130_HP_LOAD_1 */
182#define CS43130_HPLOAD_EN_SHIFT 7
183#define CS43130_HPLOAD_EN (1 << CS43130_HPLOAD_EN_SHIFT)
184#define CS43130_HPLOAD_CHN_SEL_SHIFT 4
185#define CS43130_HPLOAD_CHN_SEL (1 << CS43130_HPLOAD_CHN_SEL_SHIFT)
186#define CS43130_HPLOAD_AC_START_SHIFT 1
187#define CS43130_HPLOAD_AC_START (1 << CS43130_HPLOAD_AC_START_SHIFT)
188#define CS43130_HPLOAD_DC_START 1
189
190/* Reg CS43130_SP_BITSIZE */
191#define CS43130_SP_BIT_SIZE_8 0x03
192#define CS43130_SP_BIT_SIZE_16 0x02
193#define CS43130_SP_BIT_SIZE_24 0x01
194#define CS43130_SP_BIT_SIZE_32 0x00
195
196/* Reg CS43130_SP_CH_SZ_EN */
197#define CS43130_CH_BIT_SIZE_8 0x00
198#define CS43130_CH_BIT_SIZE_16 0x01
199#define CS43130_CH_BIT_SIZE_24 0x02
200#define CS43130_CH_BIT_SIZE_32 0x03
201
202/* PLL */
203#define CS43130_PLL_START_MASK 0x01
204#define CS43130_PLL_MODE_MASK 0x02
205#define CS43130_PLL_MODE_SHIFT 1
206
207#define CS43130_PLL_REF_PREDIV_MASK 0x3
208
209#define CS43130_SP_STP_MASK 0x10
210#define CS43130_SP_STP_SHIFT 4
211#define CS43130_SP_5050_MASK 0x08
212#define CS43130_SP_5050_SHIFT 3
213#define CS43130_SP_FSD_MASK 0x07
214
215#define CS43130_SP_MODE_MASK 0x10
216#define CS43130_SP_MODE_SHIFT 4
217#define CS43130_SP_SCPOL_OUT_MASK 0x08
218#define CS43130_SP_SCPOL_OUT_SHIFT 3
219#define CS43130_SP_SCPOL_IN_MASK 0x04
220#define CS43130_SP_SCPOL_IN_SHIFT 2
221#define CS43130_SP_LCPOL_OUT_MASK 0x02
222#define CS43130_SP_LCPOL_OUT_SHIFT 1
223#define CS43130_SP_LCPOL_IN_MASK 0x01
224#define CS43130_SP_LCPOL_IN_SHIFT 0
225
226/* Reg CS43130_PWDN_CTL */
227#define CS43130_PDN_XSP_MASK 0x80
228#define CS43130_PDN_XSP_SHIFT 7
229#define CS43130_PDN_ASP_MASK 0x40
230#define CS43130_PDN_ASP_SHIFT 6
231#define CS43130_PDN_DSPIF_MASK 0x20
232#define CS43130_PDN_DSDIF_SHIFT 5
233#define CS43130_PDN_HP_MASK 0x10
234#define CS43130_PDN_HP_SHIFT 4
235#define CS43130_PDN_XTAL_MASK 0x08
236#define CS43130_PDN_XTAL_SHIFT 3
237#define CS43130_PDN_PLL_MASK 0x04
238#define CS43130_PDN_PLL_SHIFT 2
239#define CS43130_PDN_CLKOUT_MASK 0x02
240#define CS43130_PDN_CLKOUT_SHIFT 1
241
242/* Reg CS43130_HP_OUT_CTL_1 */
243#define CS43130_HP_IN_EN_SHIFT 3
244#define CS43130_HP_IN_EN_MASK 0x08
245
246/* Reg CS43130_PAD_INT_CFG */
247#define CS43130_ASP_3ST_MASK 0x01
248#define CS43130_XSP_3ST_MASK 0x02
249
250/* Reg CS43130_PLL_SET_2 */
251#define CS43130_PLL_DIV_DATA_MASK 0x000000FF
252#define CS43130_PLL_DIV_FRAC_0_DATA_SHIFT 0
253
254/* Reg CS43130_PLL_SET_3 */
255#define CS43130_PLL_DIV_FRAC_1_DATA_SHIFT 8
256
257/* Reg CS43130_PLL_SET_4 */
258#define CS43130_PLL_DIV_FRAC_2_DATA_SHIFT 16
259
260/* Reg CS43130_SP_DEN_1 */
261#define CS43130_SP_M_LSB_DATA_MASK 0x00FF
262#define CS43130_SP_M_LSB_DATA_SHIFT 0
263
264/* Reg CS43130_SP_DEN_2 */
265#define CS43130_SP_M_MSB_DATA_MASK 0xFF00
266#define CS43130_SP_M_MSB_DATA_SHIFT 8
267
268/* Reg CS43130_SP_NUM_1 */
269#define CS43130_SP_N_LSB_DATA_MASK 0x00FF
270#define CS43130_SP_N_LSB_DATA_SHIFT 0
271
272/* Reg CS43130_SP_NUM_2 */
273#define CS43130_SP_N_MSB_DATA_MASK 0xFF00
274#define CS43130_SP_N_MSB_DATA_SHIFT 8
275
276/* Reg CS43130_SP_LRCK_HI_TIME_1 */
277#define CS43130_SP_LCHI_DATA_MASK 0x00FF
278#define CS43130_SP_LCHI_LSB_DATA_SHIFT 0
279
280/* Reg CS43130_SP_LRCK_HI_TIME_2 */
281#define CS43130_SP_LCHI_MSB_DATA_SHIFT 8
282
283/* Reg CS43130_SP_LRCK_PERIOD_1 */
284#define CS43130_SP_LCPR_DATA_MASK 0x00FF
285#define CS43130_SP_LCPR_LSB_DATA_SHIFT 0
286
287/* Reg CS43130_SP_LRCK_PERIOD_2 */
288#define CS43130_SP_LCPR_MSB_DATA_SHIFT 8
289
290#define CS43130_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
291 SNDRV_PCM_FMTBIT_S16_LE | \
292 SNDRV_PCM_FMTBIT_S24_LE | \
293 SNDRV_PCM_FMTBIT_S32_LE)
294
295#define CS43130_DOP_FORMATS (SNDRV_PCM_FMTBIT_DSD_U16_LE | \
296 SNDRV_PCM_FMTBIT_DSD_U16_BE | \
297 SNDRV_PCM_FMTBIT_S24_LE)
298
299/* Reg CS43130_CRYSTAL_SET */
300#define CS43130_XTAL_IBIAS_MASK 0x07
301
302/* Reg CS43130_PATH_CTL_1 */
303#define CS43130_MUTE_MASK 0x03
304#define CS43130_MUTE_EN 0x03
305
306/* Reg CS43130_DSD_INT_CFG */
307#define CS43130_DSD_MASTER 0x04
308
309/* Reg CS43130_DSD_PATH_CTL_2 */
310#define CS43130_DSD_SRC_MASK 0x60
311#define CS43130_DSD_SRC_SHIFT 5
312#define CS43130_DSD_EN_SHIFT 4
313#define CS43130_DSD_SPEED_MASK 0x04
314#define CS43130_DSD_SPEED_SHIFT 2
315
316/* Reg CS43130_DSD_PCM_MIX_CTL */
317#define CS43130_MIX_PCM_PREP_SHIFT 1
318#define CS43130_MIX_PCM_PREP_MASK 0x02
319
320#define CS43130_MIX_PCM_DSD_SHIFT 0
321#define CS43130_MIX_PCM_DSD_MASK 0x01
322
323/* Reg CS43130_HP_MEAS_LOAD */
324#define CS43130_HP_MEAS_LOAD_MASK 0x000000FF
325#define CS43130_HP_MEAS_LOAD_1_SHIFT 0
326#define CS43130_HP_MEAS_LOAD_2_SHIFT 8
327
328#define CS43130_MCLK_22M 22579200
329#define CS43130_MCLK_24M 24576000
330
331#define CS43130_LINEOUT_LOAD 5000
332#define CS43130_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT)
333#define CS43130_JACK_HEADPHONE (SND_JACK_MECHANICAL | \
334 SND_JACK_HEADPHONE)
335#define CS43130_JACK_MASK (SND_JACK_MECHANICAL | \
336 SND_JACK_LINEOUT | \
337 SND_JACK_HEADPHONE)
338
339enum cs43130_dsd_src {
340 CS43130_DSD_SRC_DSD = 0,
341 CS43130_DSD_SRC_ASP = 2,
342 CS43130_DSD_SRC_XSP = 3,
343};
344
345enum cs43130_asp_rate {
346 CS43130_ASP_SPRATE_32K = 0,
347 CS43130_ASP_SPRATE_44_1K,
348 CS43130_ASP_SPRATE_48K,
349 CS43130_ASP_SPRATE_88_2K,
350 CS43130_ASP_SPRATE_96K,
351 CS43130_ASP_SPRATE_176_4K,
352 CS43130_ASP_SPRATE_192K,
353 CS43130_ASP_SPRATE_352_8K,
354 CS43130_ASP_SPRATE_384K,
355};
356
357enum cs43130_mclk_src_sel {
358 CS43130_MCLK_SRC_EXT = 0,
359 CS43130_MCLK_SRC_PLL,
360 CS43130_MCLK_SRC_RCO
361};
362
363enum cs43130_mclk_int_freq {
364 CS43130_MCLK_24P5 = 0,
365 CS43130_MCLK_22P5,
366};
367
368enum cs43130_xtal_ibias {
369 CS43130_XTAL_UNUSED = -1,
370 CS43130_XTAL_IBIAS_15UA = 2,
371 CS43130_XTAL_IBIAS_12_5UA = 4,
372 CS43130_XTAL_IBIAS_7_5UA = 6,
373};
374
375enum cs43130_dai_id {
376 CS43130_ASP_PCM_DAI = 0,
377 CS43130_ASP_DOP_DAI,
378 CS43130_XSP_DOP_DAI,
379 CS43130_XSP_DSD_DAI,
380 CS43130_DAI_ID_MAX,
381};
382
383struct cs43130_clk_gen {
384 unsigned int mclk_int;
385 int fs;
386 u16 den;
387 u16 num;
388};
389
390/* frm_size = 16 */
391static const struct cs43130_clk_gen cs43130_16_clk_gen[] = {
392 {22579200, 32000, 441, 10,},
393 {22579200, 44100, 32, 1,},
394 {22579200, 48000, 147, 5,},
395 {22579200, 88200, 16, 1,},
396 {22579200, 96000, 147, 10,},
397 {22579200, 176400, 8, 1,},
398 {22579200, 192000, 147, 20,},
399 {22579200, 352800, 4, 1,},
400 {22579200, 384000, 147, 40,},
401 {24576000, 32000, 48, 1,},
402 {24576000, 44100, 5120, 147,},
403 {24576000, 48000, 32, 1,},
404 {24576000, 88200, 2560, 147,},
405 {24576000, 96000, 16, 1,},
406 {24576000, 176400, 1280, 147,},
407 {24576000, 192000, 8, 1,},
408 {24576000, 352800, 640, 147,},
409 {24576000, 384000, 4, 1,},
410};
411
412/* frm_size = 32 */
413static const struct cs43130_clk_gen cs43130_32_clk_gen[] = {
414 {22579200, 32000, 441, 20,},
415 {22579200, 44100, 16, 1,},
416 {22579200, 48000, 147, 10,},
417 {22579200, 88200, 8, 1,},
418 {22579200, 96000, 147, 20,},
419 {22579200, 176400, 4, 1,},
420 {22579200, 192000, 147, 40,},
421 {22579200, 352800, 2, 1,},
422 {22579200, 384000, 147, 80,},
423 {24576000, 32000, 24, 1,},
424 {24576000, 44100, 2560, 147,},
425 {24576000, 48000, 16, 1,},
426 {24576000, 88200, 1280, 147,},
427 {24576000, 96000, 8, 1,},
428 {24576000, 176400, 640, 147,},
429 {24576000, 192000, 4, 1,},
430 {24576000, 352800, 320, 147,},
431 {24576000, 384000, 2, 1,},
432};
433
434/* frm_size = 48 */
435static const struct cs43130_clk_gen cs43130_48_clk_gen[] = {
436 {22579200, 32000, 147, 100,},
437 {22579200, 44100, 32, 3,},
438 {22579200, 48000, 49, 5,},
439 {22579200, 88200, 16, 3,},
440 {22579200, 96000, 49, 10,},
441 {22579200, 176400, 8, 3,},
442 {22579200, 192000, 49, 20,},
443 {22579200, 352800, 4, 3,},
444 {22579200, 384000, 49, 40,},
445 {24576000, 32000, 16, 1,},
446 {24576000, 44100, 5120, 441,},
447 {24576000, 48000, 32, 3,},
448 {24576000, 88200, 2560, 441,},
449 {24576000, 96000, 16, 3,},
450 {24576000, 176400, 1280, 441,},
451 {24576000, 192000, 8, 3,},
452 {24576000, 352800, 640, 441,},
453 {24576000, 384000, 4, 3,},
454};
455
456/* frm_size = 64 */
457static const struct cs43130_clk_gen cs43130_64_clk_gen[] = {
458 {22579200, 32000, 441, 40,},
459 {22579200, 44100, 8, 1,},
460 {22579200, 48000, 147, 20,},
461 {22579200, 88200, 4, 1,},
462 {22579200, 96000, 147, 40,},
463 {22579200, 176400, 2, 1,},
464 {22579200, 192000, 147, 80,},
465 {22579200, 352800, 1, 1,},
466 {24576000, 32000, 12, 1,},
467 {24576000, 44100, 1280, 147,},
468 {24576000, 48000, 8, 1,},
469 {24576000, 88200, 640, 147,},
470 {24576000, 96000, 4, 1,},
471 {24576000, 176400, 320, 147,},
472 {24576000, 192000, 2, 1,},
473 {24576000, 352800, 160, 147,},
474 {24576000, 384000, 1, 1,},
475};
476
477struct cs43130_bitwidth_map {
478 unsigned int bitwidth;
479 u8 sp_bit;
480 u8 ch_bit;
481};
482
483struct cs43130_rate_map {
484 int fs;
485 int val;
486};
487
488#define HP_LEFT 0
489#define HP_RIGHT 1
490#define CS43130_AC_FREQ 10
491#define CS43130_DC_THRESHOLD 2
492
493#define CS43130_NUM_SUPPLIES 5
494static const char *const cs43130_supply_names[CS43130_NUM_SUPPLIES] = {
495 "VA",
496 "VP",
497 "VCP",
498 "VD",
499 "VL",
500};
501
502#define CS43130_NUM_INT 5 /* number of interrupt status reg */
503
504struct cs43130_dai {
505 unsigned int sclk;
506 unsigned int dai_format;
507 unsigned int dai_mode;
508};
509
510struct cs43130_private {
511 struct snd_soc_codec *codec;
512 struct regmap *regmap;
513 struct regulator_bulk_data supplies[CS43130_NUM_SUPPLIES];
514 struct gpio_desc *reset_gpio;
515 unsigned int dev_id; /* codec device ID */
516 int xtal_ibias;
517
518 /* shared by both DAIs */
519 struct mutex clk_mutex;
520 int clk_req;
521 bool pll_bypass;
522 struct completion xtal_rdy;
523 struct completion pll_rdy;
524 unsigned int mclk;
525 unsigned int mclk_int;
526 int mclk_int_src;
527
528 /* DAI specific */
529 struct cs43130_dai dais[CS43130_DAI_ID_MAX];
530
531 /* HP load specific */
532 bool dc_meas;
533 bool ac_meas;
534 bool hpload_done;
535 struct completion hpload_evt;
536 unsigned int hpload_stat;
537 u16 hpload_dc[2];
538 u16 dc_threshold[CS43130_DC_THRESHOLD];
539 u16 ac_freq[CS43130_AC_FREQ];
540 u16 hpload_ac[CS43130_AC_FREQ][2];
541 struct workqueue_struct *wq;
542 struct work_struct work;
543 struct snd_soc_jack jack;
544};
545
546#endif /* __CS43130_H__ */