2 * Driver for the ALLO KATANA CODEC
4 * Author: Jaikumar <sudeepkumar@cem-solutions.net>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
17 #include <linux/module.h>
18 #include <linux/moduleparam.h>
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/delay.h>
22 #include <linux/gpio.h>
23 #include <linux/gpio/consumer.h>
24 #include <linux/platform_device.h>
26 #include <linux/i2c.h>
27 #include <linux/of_device.h>
28 #include <linux/regmap.h>
29 #include <linux/slab.h>
30 #include <sound/core.h>
31 #include <sound/pcm.h>
32 #include <sound/pcm_params.h>
33 #include <sound/soc.h>
34 #include <sound/soc-dapm.h>
35 #include <sound/initval.h>
36 #include <sound/tlv.h>
37 #include <linux/of_gpio.h>
38 #include <linux/regulator/consumer.h>
39 #include <linux/pm_runtime.h>
40 #include <linux/of_irq.h>
41 #include <linux/completion.h>
42 #include <linux/mutex.h>
43 #include <linux/workqueue.h>
44 #include <sound/jack.h>
46 #include "../codecs/cs43130.h"
48 #include <linux/clk.h>
49 #include <linux/gcd.h>
52 #define CS43130_DSD_EN_MASK 0x10
53 #define CS43130_PDN_DONE_INT_MASK 0x00
55 static struct gpio_desc *snd_allo_clk44gpio;
56 static struct gpio_desc *snd_allo_clk48gpio;
59 struct snd_soc_component *component;
60 struct regmap *regmap;
61 struct regulator_bulk_data supplies[CS43130_NUM_SUPPLIES];
62 struct gpio_desc *reset_gpio;
63 unsigned int dev_id; /* codec device ID */
65 /* shared by both DAIs */
66 struct mutex clk_mutex;
69 struct completion xtal_rdy;
70 struct completion pll_rdy;
72 unsigned int mclk_int;
76 struct cs43130_dai dais[CS43130_DAI_ID_MAX];
78 /* HP load specific */
82 struct completion hpload_evt;
83 unsigned int hpload_stat;
85 u16 dc_threshold[CS43130_DC_THRESHOLD];
86 u16 ac_freq[CS43130_AC_FREQ];
87 u16 hpload_ac[CS43130_AC_FREQ][2];
88 struct workqueue_struct *wq;
89 struct work_struct work;
90 struct snd_soc_jack jack;
93 static const struct reg_default cs43130_reg_defaults[] = {
94 {CS43130_SYS_CLK_CTL_1, 0x06},
95 {CS43130_SP_SRATE, 0x01},
96 {CS43130_SP_BITSIZE, 0x05},
97 {CS43130_PAD_INT_CFG, 0x03},
98 {CS43130_PWDN_CTL, 0xFE},
99 {CS43130_CRYSTAL_SET, 0x04},
100 {CS43130_PLL_SET_1, 0x00},
101 {CS43130_PLL_SET_2, 0x00},
102 {CS43130_PLL_SET_3, 0x00},
103 {CS43130_PLL_SET_4, 0x00},
104 {CS43130_PLL_SET_5, 0x40},
105 {CS43130_PLL_SET_6, 0x10},
106 {CS43130_PLL_SET_7, 0x80},
107 {CS43130_PLL_SET_8, 0x03},
108 {CS43130_PLL_SET_9, 0x02},
109 {CS43130_PLL_SET_10, 0x02},
110 {CS43130_CLKOUT_CTL, 0x00},
111 {CS43130_ASP_NUM_1, 0x01},
112 {CS43130_ASP_NUM_2, 0x00},
113 {CS43130_ASP_DEN_1, 0x08},
114 {CS43130_ASP_DEN_2, 0x00},
115 {CS43130_ASP_LRCK_HI_TIME_1, 0x1F},
116 {CS43130_ASP_LRCK_HI_TIME_2, 0x00},
117 {CS43130_ASP_LRCK_PERIOD_1, 0x3F},
118 {CS43130_ASP_LRCK_PERIOD_2, 0x00},
119 {CS43130_ASP_CLOCK_CONF, 0x0C},
120 {CS43130_ASP_FRAME_CONF, 0x0A},
121 {CS43130_XSP_NUM_1, 0x01},
122 {CS43130_XSP_NUM_2, 0x00},
123 {CS43130_XSP_DEN_1, 0x02},
124 {CS43130_XSP_DEN_2, 0x00},
125 {CS43130_XSP_LRCK_HI_TIME_1, 0x1F},
126 {CS43130_XSP_LRCK_HI_TIME_2, 0x00},
127 {CS43130_XSP_LRCK_PERIOD_1, 0x3F},
128 {CS43130_XSP_LRCK_PERIOD_2, 0x00},
129 {CS43130_XSP_CLOCK_CONF, 0x0C},
130 {CS43130_XSP_FRAME_CONF, 0x0A},
131 {CS43130_ASP_CH_1_LOC, 0x00},
132 {CS43130_ASP_CH_2_LOC, 0x00},
133 {CS43130_ASP_CH_1_SZ_EN, 0x06},
134 {CS43130_ASP_CH_2_SZ_EN, 0x0E},
135 {CS43130_XSP_CH_1_LOC, 0x00},
136 {CS43130_XSP_CH_2_LOC, 0x00},
137 {CS43130_XSP_CH_1_SZ_EN, 0x06},
138 {CS43130_XSP_CH_2_SZ_EN, 0x0E},
139 {CS43130_DSD_VOL_B, 0x78},
140 {CS43130_DSD_VOL_A, 0x78},
141 {CS43130_DSD_PATH_CTL_1, 0xA8},
142 {CS43130_DSD_INT_CFG, 0x00},
143 {CS43130_DSD_PATH_CTL_2, 0x02},
144 {CS43130_DSD_PCM_MIX_CTL, 0x00},
145 {CS43130_DSD_PATH_CTL_3, 0x40},
146 {CS43130_HP_OUT_CTL_1, 0x30},
147 {CS43130_PCM_FILT_OPT, 0x02},
148 {CS43130_PCM_VOL_B, 0x78},
149 {CS43130_PCM_VOL_A, 0x78},
150 {CS43130_PCM_PATH_CTL_1, 0xA8},
151 {CS43130_PCM_PATH_CTL_2, 0x00},
152 {CS43130_CLASS_H_CTL, 0x1E},
153 {CS43130_HP_DETECT, 0x04},
154 {CS43130_HP_LOAD_1, 0x00},
155 {CS43130_HP_MEAS_LOAD_1, 0x00},
156 {CS43130_HP_MEAS_LOAD_2, 0x00},
157 {CS43130_INT_MASK_1, 0xFF},
158 {CS43130_INT_MASK_2, 0xFF},
159 {CS43130_INT_MASK_3, 0xFF},
160 {CS43130_INT_MASK_4, 0xFF},
161 {CS43130_INT_MASK_5, 0xFF},
163 static bool cs43130_volatile_register(struct device *dev, unsigned int reg)
166 case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5:
167 case CS43130_HP_DC_STAT_1 ... CS43130_HP_DC_STAT_2:
168 case CS43130_HP_AC_STAT_1 ... CS43130_HP_AC_STAT_2:
175 static const char * const pcm_spd_texts[] = {
180 static SOC_ENUM_SINGLE_DECL(pcm_spd_enum, CS43130_PCM_FILT_OPT, 7,
183 static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(master_tlv, -12750, 0);
185 static const struct snd_kcontrol_new cs43130_controls[] = {
186 SOC_DOUBLE_R_TLV("Master Playback Volume", CS43130_PCM_VOL_B,
187 CS43130_PCM_VOL_A, 0, 255, 1, master_tlv),
188 SOC_DOUBLE("Master Playback Switch", CS43130_PCM_PATH_CTL_1,
190 SOC_DOUBLE_R_TLV("Digital Playback Volume", CS43130_DSD_VOL_B,
191 CS43130_DSD_VOL_A, 0, 255, 1, master_tlv),
192 SOC_DOUBLE("Digital Playback Switch", CS43130_DSD_PATH_CTL_1,
194 SOC_SINGLE("HV_Enable", CS43130_HP_OUT_CTL_1, 0, 1, 0),
195 SOC_ENUM("PCM Filter Speed", pcm_spd_enum),
196 SOC_SINGLE("PCM Phase Compensation", CS43130_PCM_FILT_OPT, 6, 1, 0),
197 SOC_SINGLE("PCM Nonoversample Emulate", CS43130_PCM_FILT_OPT, 5, 1, 0),
198 SOC_SINGLE("PCM High-pass Filter", CS43130_PCM_FILT_OPT, 1, 1, 0),
199 SOC_SINGLE("PCM De-emphasis Filter", CS43130_PCM_FILT_OPT, 0, 1, 0),
202 static bool cs43130_readable_register(struct device *dev, unsigned int reg)
205 case CS43130_DEVID_AB ... CS43130_SYS_CLK_CTL_1:
206 case CS43130_SP_SRATE ... CS43130_PAD_INT_CFG:
207 case CS43130_PWDN_CTL:
208 case CS43130_CRYSTAL_SET:
209 case CS43130_PLL_SET_1 ... CS43130_PLL_SET_5:
210 case CS43130_PLL_SET_6:
211 case CS43130_PLL_SET_7:
212 case CS43130_PLL_SET_8:
213 case CS43130_PLL_SET_9:
214 case CS43130_PLL_SET_10:
215 case CS43130_CLKOUT_CTL:
216 case CS43130_ASP_NUM_1 ... CS43130_ASP_FRAME_CONF:
217 case CS43130_XSP_NUM_1 ... CS43130_XSP_FRAME_CONF:
218 case CS43130_ASP_CH_1_LOC:
219 case CS43130_ASP_CH_2_LOC:
220 case CS43130_ASP_CH_1_SZ_EN:
221 case CS43130_ASP_CH_2_SZ_EN:
222 case CS43130_XSP_CH_1_LOC:
223 case CS43130_XSP_CH_2_LOC:
224 case CS43130_XSP_CH_1_SZ_EN:
225 case CS43130_XSP_CH_2_SZ_EN:
226 case CS43130_DSD_VOL_B ... CS43130_DSD_PATH_CTL_3:
227 case CS43130_HP_OUT_CTL_1:
228 case CS43130_PCM_FILT_OPT ... CS43130_PCM_PATH_CTL_2:
229 case CS43130_CLASS_H_CTL:
230 case CS43130_HP_DETECT:
231 case CS43130_HP_STATUS:
232 case CS43130_HP_LOAD_1:
233 case CS43130_HP_MEAS_LOAD_1:
234 case CS43130_HP_MEAS_LOAD_2:
235 case CS43130_HP_DC_STAT_1:
236 case CS43130_HP_DC_STAT_2:
237 case CS43130_HP_AC_STAT_1:
238 case CS43130_HP_AC_STAT_2:
239 case CS43130_HP_LOAD_STAT:
240 case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5:
241 case CS43130_INT_MASK_1 ... CS43130_INT_MASK_5:
247 static bool cs43130_precious_register(struct device *dev, unsigned int reg)
250 case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5:
256 static int cs43130_pcm_pdn(struct snd_soc_component *component)
258 struct cs43130_priv *cs43130 =
259 snd_soc_component_get_drvdata(component);
261 unsigned int reg, pdn_int;
263 regmap_write(cs43130->regmap, CS43130_DSD_PATH_CTL_2, 0x02);
264 regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
265 CS43130_PDN_DONE_INT_MASK, 0);
266 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
267 CS43130_PDN_HP_MASK, 1 << CS43130_PDN_HP_SHIFT);
268 usleep_range(10, 50);
269 ret = regmap_read(cs43130->regmap, CS43130_INT_STATUS_1, ®);
270 pdn_int = reg & 0xFE;
271 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
272 CS43130_PDN_ASP_MASK, 1 << CS43130_PDN_ASP_SHIFT);
276 static int cs43130_pwr_up_asp_dac(struct snd_soc_component *component)
278 struct cs43130_priv *cs43130 =
279 snd_soc_component_get_drvdata(component);
281 regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG,
282 CS43130_ASP_3ST_MASK, 0);
283 regmap_write(cs43130->regmap, CS43130_DXD1, 0x99);
284 regmap_write(cs43130->regmap, CS43130_DXD13, 0x20);
285 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
286 CS43130_PDN_ASP_MASK, 0);
287 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
288 CS43130_PDN_HP_MASK, 0);
289 usleep_range(10000, 12000);
290 regmap_write(cs43130->regmap, CS43130_DXD1, 0x00);
291 regmap_write(cs43130->regmap, CS43130_DXD13, 0x00);
294 static int cs43130_change_clksrc(struct snd_soc_component *component,
295 enum cs43130_mclk_src_sel src)
298 struct cs43130_priv *cs43130 =
299 snd_soc_component_get_drvdata(component);
300 int mclk_int_decoded;
302 if (src == cs43130->mclk_int_src) {
303 /* clk source has not changed */
306 switch (cs43130->mclk_int) {
307 case CS43130_MCLK_22M:
308 mclk_int_decoded = CS43130_MCLK_22P5;
310 case CS43130_MCLK_24M:
311 mclk_int_decoded = CS43130_MCLK_24P5;
314 dev_err(component->dev, "Invalid MCLK INT freq: %u\n",
320 case CS43130_MCLK_SRC_EXT:
321 cs43130->pll_bypass = true;
322 cs43130->mclk_int_src = CS43130_MCLK_SRC_EXT;
323 if (cs43130->xtal_ibias == CS43130_XTAL_UNUSED) {
324 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
325 CS43130_PDN_XTAL_MASK,
326 1 << CS43130_PDN_XTAL_SHIFT);
328 reinit_completion(&cs43130->xtal_rdy);
329 regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
330 CS43130_XTAL_RDY_INT_MASK, 0);
331 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
332 CS43130_PDN_XTAL_MASK, 0);
333 ret = wait_for_completion_timeout(&cs43130->xtal_rdy,
334 msecs_to_jiffies(100));
335 regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
336 CS43130_XTAL_RDY_INT_MASK,
337 1 << CS43130_XTAL_RDY_INT_SHIFT);
339 dev_err(component->dev, "Timeout waiting for XTAL_READY interrupt\n");
343 regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
344 CS43130_MCLK_SRC_SEL_MASK,
345 src << CS43130_MCLK_SRC_SEL_SHIFT);
346 regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
347 CS43130_MCLK_INT_MASK,
348 mclk_int_decoded << CS43130_MCLK_INT_SHIFT);
349 usleep_range(150, 200);
350 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
351 CS43130_PDN_PLL_MASK,
352 1 << CS43130_PDN_PLL_SHIFT);
354 case CS43130_MCLK_SRC_RCO:
355 cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO;
357 regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
358 CS43130_MCLK_SRC_SEL_MASK,
359 src << CS43130_MCLK_SRC_SEL_SHIFT);
360 regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
361 CS43130_MCLK_INT_MASK,
362 CS43130_MCLK_22P5 << CS43130_MCLK_INT_SHIFT);
363 usleep_range(150, 200);
364 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
365 CS43130_PDN_XTAL_MASK,
366 1 << CS43130_PDN_XTAL_SHIFT);
367 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
368 CS43130_PDN_PLL_MASK,
369 1 << CS43130_PDN_PLL_SHIFT);
372 dev_err(component->dev, "Invalid MCLK source value\n");
378 static const struct cs43130_bitwidth_map cs43130_bitwidth_table[] = {
379 {8, CS43130_SP_BIT_SIZE_8, CS43130_CH_BIT_SIZE_8},
380 {16, CS43130_SP_BIT_SIZE_16, CS43130_CH_BIT_SIZE_16},
381 {24, CS43130_SP_BIT_SIZE_24, CS43130_CH_BIT_SIZE_24},
382 {32, CS43130_SP_BIT_SIZE_32, CS43130_CH_BIT_SIZE_32},
385 static const struct cs43130_bitwidth_map *cs43130_get_bitwidth_table(
386 unsigned int bitwidth)
390 for (i = 0; i < ARRAY_SIZE(cs43130_bitwidth_table); i++) {
391 if (cs43130_bitwidth_table[i].bitwidth == bitwidth)
392 return &cs43130_bitwidth_table[i];
397 static int cs43130_set_bitwidth(int dai_id, unsigned int bitwidth_dai,
398 struct regmap *regmap)
400 const struct cs43130_bitwidth_map *bw_map;
402 bw_map = cs43130_get_bitwidth_table(bitwidth_dai);
407 case CS43130_ASP_PCM_DAI:
408 case CS43130_ASP_DOP_DAI:
409 regmap_update_bits(regmap, CS43130_ASP_CH_1_SZ_EN,
410 CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
411 regmap_update_bits(regmap, CS43130_ASP_CH_2_SZ_EN,
412 CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
413 regmap_update_bits(regmap, CS43130_SP_BITSIZE,
414 CS43130_ASP_BITSIZE_MASK, bw_map->sp_bit);
416 case CS43130_XSP_DOP_DAI:
417 regmap_update_bits(regmap, CS43130_XSP_CH_1_SZ_EN,
418 CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
419 regmap_update_bits(regmap, CS43130_XSP_CH_2_SZ_EN,
420 CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
421 regmap_update_bits(regmap, CS43130_SP_BITSIZE,
422 CS43130_XSP_BITSIZE_MASK, bw_map->sp_bit <<
423 CS43130_XSP_BITSIZE_SHIFT);
431 static const struct cs43130_rate_map cs43130_rate_table[] = {
432 {32000, CS43130_ASP_SPRATE_32K},
433 {44100, CS43130_ASP_SPRATE_44_1K},
434 {48000, CS43130_ASP_SPRATE_48K},
435 {88200, CS43130_ASP_SPRATE_88_2K},
436 {96000, CS43130_ASP_SPRATE_96K},
437 {176400, CS43130_ASP_SPRATE_176_4K},
438 {192000, CS43130_ASP_SPRATE_192K},
439 {352800, CS43130_ASP_SPRATE_352_8K},
440 {384000, CS43130_ASP_SPRATE_384K},
443 static const struct cs43130_rate_map *cs43130_get_rate_table(int fs)
447 for (i = 0; i < ARRAY_SIZE(cs43130_rate_table); i++) {
448 if (cs43130_rate_table[i].fs == fs)
449 return &cs43130_rate_table[i];
455 static const struct cs43130_clk_gen *cs43130_get_clk_gen(int mclk_int, int fs,
456 const struct cs43130_clk_gen *clk_gen_table, int len_clk_gen_table)
460 for (i = 0; i < len_clk_gen_table; i++) {
461 if (clk_gen_table[i].mclk_int == mclk_int &&
462 clk_gen_table[i].fs == fs)
463 return &clk_gen_table[i];
468 static int cs43130_set_sp_fmt(int dai_id, unsigned int bitwidth_sclk,
469 struct snd_pcm_hw_params *params,
470 struct cs43130_priv *cs43130)
483 const struct cs43130_clk_gen *clk_gen;
485 switch (cs43130->dais[dai_id].dai_format) {
486 case SND_SOC_DAIFMT_I2S:
487 hi_size = bitwidth_sclk;
491 case SND_SOC_DAIFMT_LEFT_J:
492 hi_size = bitwidth_sclk;
496 case SND_SOC_DAIFMT_DSP_A:
501 case SND_SOC_DAIFMT_DSP_B:
509 switch (cs43130->dais[dai_id].dai_mode) {
510 case SND_SOC_DAIFMT_CBS_CFS:
513 case SND_SOC_DAIFMT_CBM_CFM:
520 frm_size = bitwidth_sclk * params_channels(params);
524 loc_ch2 = bitwidth_sclk * (params_channels(params) - 1);
526 frm_data = frm_delay & CS43130_SP_FSD_MASK;
527 frm_data |= (frm_phase << CS43130_SP_STP_SHIFT) & CS43130_SP_STP_MASK;
529 clk_data = lrck_edge & CS43130_SP_LCPOL_IN_MASK;
530 clk_data |= (lrck_edge << CS43130_SP_LCPOL_OUT_SHIFT) &
531 CS43130_SP_LCPOL_OUT_MASK;
532 clk_data |= (sclk_edge << CS43130_SP_SCPOL_IN_SHIFT) &
533 CS43130_SP_SCPOL_IN_MASK;
534 clk_data |= (sclk_edge << CS43130_SP_SCPOL_OUT_SHIFT) &
535 CS43130_SP_SCPOL_OUT_MASK;
536 clk_data |= (dai_mode_val << CS43130_SP_MODE_SHIFT) &
537 CS43130_SP_MODE_MASK;
539 case CS43130_ASP_PCM_DAI:
540 case CS43130_ASP_DOP_DAI:
541 regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_1,
542 CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
543 CS43130_SP_LCPR_LSB_DATA_SHIFT);
544 regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_2,
545 CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
546 CS43130_SP_LCPR_MSB_DATA_SHIFT);
547 regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_1,
548 CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
549 CS43130_SP_LCHI_LSB_DATA_SHIFT);
550 regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_2,
551 CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
552 CS43130_SP_LCHI_MSB_DATA_SHIFT);
553 regmap_write(cs43130->regmap, CS43130_ASP_FRAME_CONF, frm_data);
554 regmap_write(cs43130->regmap, CS43130_ASP_CH_1_LOC, loc_ch1);
555 regmap_write(cs43130->regmap, CS43130_ASP_CH_2_LOC, loc_ch2);
556 regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_1_SZ_EN,
557 CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
558 regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_2_SZ_EN,
559 CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
560 regmap_write(cs43130->regmap, CS43130_ASP_CLOCK_CONF, clk_data);
562 case CS43130_XSP_DOP_DAI:
563 regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_1,
564 CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
565 CS43130_SP_LCPR_LSB_DATA_SHIFT);
566 regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_2,
567 CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
568 CS43130_SP_LCPR_MSB_DATA_SHIFT);
569 regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_1,
570 CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
571 CS43130_SP_LCHI_LSB_DATA_SHIFT);
572 regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_2,
573 CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
574 CS43130_SP_LCHI_MSB_DATA_SHIFT);
575 regmap_write(cs43130->regmap, CS43130_XSP_FRAME_CONF, frm_data);
576 regmap_write(cs43130->regmap, CS43130_XSP_CH_1_LOC, loc_ch1);
577 regmap_write(cs43130->regmap, CS43130_XSP_CH_2_LOC, loc_ch2);
578 regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_1_SZ_EN,
579 CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
580 regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_2_SZ_EN,
581 CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
582 regmap_write(cs43130->regmap, CS43130_XSP_CLOCK_CONF, clk_data);
589 clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
592 ARRAY_SIZE(cs43130_16_clk_gen));
595 clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
598 ARRAY_SIZE(cs43130_32_clk_gen));
601 clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
604 ARRAY_SIZE(cs43130_48_clk_gen));
607 clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
610 ARRAY_SIZE(cs43130_64_clk_gen));
618 case CS43130_ASP_PCM_DAI:
619 case CS43130_ASP_DOP_DAI:
620 regmap_write(cs43130->regmap, CS43130_ASP_DEN_1,
621 (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >>
622 CS43130_SP_M_LSB_DATA_SHIFT);
623 regmap_write(cs43130->regmap, CS43130_ASP_DEN_2,
624 (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >>
625 CS43130_SP_M_MSB_DATA_SHIFT);
626 regmap_write(cs43130->regmap, CS43130_ASP_NUM_1,
627 (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >>
628 CS43130_SP_N_LSB_DATA_SHIFT);
629 regmap_write(cs43130->regmap, CS43130_ASP_NUM_2,
630 (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >>
631 CS43130_SP_N_MSB_DATA_SHIFT);
633 case CS43130_XSP_DOP_DAI:
634 regmap_write(cs43130->regmap, CS43130_XSP_DEN_1,
635 (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >>
636 CS43130_SP_M_LSB_DATA_SHIFT);
637 regmap_write(cs43130->regmap, CS43130_XSP_DEN_2,
638 (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >>
639 CS43130_SP_M_MSB_DATA_SHIFT);
640 regmap_write(cs43130->regmap, CS43130_XSP_NUM_1,
641 (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >>
642 CS43130_SP_N_LSB_DATA_SHIFT);
643 regmap_write(cs43130->regmap, CS43130_XSP_NUM_2,
644 (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >>
645 CS43130_SP_N_MSB_DATA_SHIFT);
653 static int cs43130_hw_params(struct snd_pcm_substream *substream,
654 struct snd_pcm_hw_params *params,
655 struct snd_soc_dai *dai)
657 struct snd_soc_component *component = dai->component;
658 struct cs43130_priv *cs43130 =
659 snd_soc_component_get_drvdata(component);
660 const struct cs43130_rate_map *rate_map;
661 unsigned int sclk = cs43130->dais[dai->id].sclk;
662 unsigned int bitwidth_sclk;
663 unsigned int bitwidth_dai = (unsigned int)(params_width(params));
664 unsigned int dop_rate = (unsigned int)(params_rate(params));
665 unsigned int required_clk, ret;
668 cs43130->pll_bypass = true;
669 cs43130_pcm_pdn(component);
670 mutex_lock(&cs43130->clk_mutex);
671 if (!cs43130->clk_req) {
672 /* no DAI is currently using clk */
673 if (!(CS43130_MCLK_22M % params_rate(params))) {
674 required_clk = CS43130_MCLK_22M;
675 cs43130->mclk_int = CS43130_MCLK_22M;
676 gpiod_set_value_cansleep(snd_allo_clk44gpio, 1);
677 gpiod_set_value_cansleep(snd_allo_clk48gpio, 0);
678 usleep_range(13500, 14000);
680 required_clk = CS43130_MCLK_24M;
681 cs43130->mclk_int = CS43130_MCLK_24M;
682 gpiod_set_value_cansleep(snd_allo_clk48gpio, 1);
683 gpiod_set_value_cansleep(snd_allo_clk44gpio, 0);
684 usleep_range(13500, 14000);
686 if (cs43130->pll_bypass)
687 cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT);
689 cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL);
693 mutex_unlock(&cs43130->clk_mutex);
696 case CS43130_ASP_DOP_DAI:
697 case CS43130_XSP_DOP_DAI:
698 /* DoP bitwidth is always 24-bit */
700 sclk = params_rate(params) * bitwidth_dai *
701 params_channels(params);
703 switch (params_rate(params)) {
711 dev_err(component->dev, "Rate(%u) not supported\n",
712 params_rate(params));
716 regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
717 CS43130_DSD_SPEED_MASK,
718 dsd_speed << CS43130_DSD_SPEED_SHIFT);
720 case CS43130_ASP_PCM_DAI:
721 rate_map = cs43130_get_rate_table(params_rate(params));
725 regmap_write(cs43130->regmap, CS43130_SP_SRATE, rate_map->val);
726 if ((dop_rate == 176400) && (bitwidth_dai == 24)) {
728 regmap_update_bits(cs43130->regmap,
729 CS43130_DSD_PATH_CTL_2,
730 CS43130_DSD_SPEED_MASK,
731 dsd_speed << CS43130_DSD_SPEED_SHIFT);
732 regmap_update_bits(cs43130->regmap,
733 CS43130_DSD_PATH_CTL_2,
734 CS43130_DSD_SRC_MASK,
735 CS43130_DSD_SRC_ASP <<
736 CS43130_DSD_SRC_SHIFT);
737 regmap_update_bits(cs43130->regmap,
738 CS43130_DSD_PATH_CTL_2,
739 CS43130_DSD_EN_MASK, 0x01 <<
740 CS43130_DSD_EN_SHIFT);
744 dev_err(component->dev, "Invalid DAI (%d)\n", dai->id);
749 case CS43130_ASP_DOP_DAI:
750 regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
751 CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_ASP <<
752 CS43130_DSD_SRC_SHIFT);
753 regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
754 CS43130_DSD_EN_MASK, 0x01 <<
755 CS43130_DSD_EN_SHIFT);
757 case CS43130_XSP_DOP_DAI:
758 regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
759 CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_XSP <<
760 CS43130_DSD_SRC_SHIFT);
763 if (!sclk && cs43130->dais[dai->id].dai_mode ==
764 SND_SOC_DAIFMT_CBM_CFM) {
765 /* Calculate SCLK in master mode if unassigned */
766 sclk = params_rate(params) * bitwidth_dai *
767 params_channels(params);
770 /* at this point, SCLK must be set */
771 dev_err(component->dev, "SCLK freq is not set\n");
775 bitwidth_sclk = (sclk / params_rate(params)) / params_channels(params);
776 if (bitwidth_sclk < bitwidth_dai) {
777 dev_err(component->dev, "Format not supported: SCLK freq is too low\n");
781 dev_dbg(component->dev,
782 "sclk = %u, fs = %d, bitwidth_dai = %u\n",
783 sclk, params_rate(params), bitwidth_dai);
785 dev_dbg(component->dev,
786 "bitwidth_sclk = %u, num_ch = %u\n",
787 bitwidth_sclk, params_channels(params));
789 cs43130_set_bitwidth(dai->id, bitwidth_dai, cs43130->regmap);
790 cs43130_set_sp_fmt(dai->id, bitwidth_sclk, params, cs43130);
791 ret = cs43130_pwr_up_asp_dac(component);
795 static int cs43130_hw_free(struct snd_pcm_substream *substream,
796 struct snd_soc_dai *dai)
798 struct snd_soc_component *component = dai->component;
799 struct cs43130_priv *cs43130 =
800 snd_soc_component_get_drvdata(component);
802 mutex_lock(&cs43130->clk_mutex);
804 if (!cs43130->clk_req) {
805 /* no DAI is currently using clk */
806 cs43130_change_clksrc(component, CS43130_MCLK_SRC_RCO);
807 cs43130_pcm_pdn(component);
809 mutex_unlock(&cs43130->clk_mutex);
814 static const unsigned int cs43130_asp_src_rates[] = {
815 32000, 44100, 48000, 88200, 96000, 176400, 192000
818 static const struct snd_pcm_hw_constraint_list cs43130_asp_constraints = {
819 .count = ARRAY_SIZE(cs43130_asp_src_rates),
820 .list = cs43130_asp_src_rates,
823 static int cs43130_pcm_startup(struct snd_pcm_substream *substream,
824 struct snd_soc_dai *dai)
826 return snd_pcm_hw_constraint_list(substream->runtime, 0,
827 SNDRV_PCM_HW_PARAM_RATE,
828 &cs43130_asp_constraints);
831 static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
833 struct snd_soc_component *component = codec_dai->component;
834 struct cs43130_priv *cs43130 =
835 snd_soc_component_get_drvdata(component);
837 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
838 case SND_SOC_DAIFMT_CBS_CFS:
839 cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBS_CFS;
841 case SND_SOC_DAIFMT_CBM_CFM:
842 cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM;
845 dev_err(component->dev, "unsupported mode\n");
849 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
850 case SND_SOC_DAIFMT_I2S:
851 cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_I2S;
853 case SND_SOC_DAIFMT_LEFT_J:
854 cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_LEFT_J;
857 dev_err(component->dev,
858 "unsupported audio format\n");
862 dev_dbg(component->dev, "dai_id = %d, dai_mode = %u, dai_format = %u\n",
864 cs43130->dais[codec_dai->id].dai_mode,
865 cs43130->dais[codec_dai->id].dai_format);
870 static int cs43130_set_sysclk(struct snd_soc_dai *codec_dai,
871 int clk_id, unsigned int freq, int dir)
873 struct snd_soc_component *component = codec_dai->component;
874 struct cs43130_priv *cs43130 =
875 snd_soc_component_get_drvdata(component);
877 cs43130->dais[codec_dai->id].sclk = freq;
878 dev_dbg(component->dev, "dai_id = %d, sclk = %u\n", codec_dai->id,
879 cs43130->dais[codec_dai->id].sclk);
884 static int cs43130_component_set_sysclk(struct snd_soc_component *component,
885 int clk_id, int source,
886 unsigned int freq, int dir)
888 struct cs43130_priv *cs43130 =
889 snd_soc_component_get_drvdata(component);
891 dev_dbg(component->dev, "clk_id = %d, source = %d, freq = %d, dir = %d\n",
892 clk_id, source, freq, dir);
895 case CS43130_MCLK_22M:
896 case CS43130_MCLK_24M:
897 cs43130->mclk = freq;
900 dev_err(component->dev, "Invalid MCLK INT freq: %u\n", freq);
904 if (source == CS43130_MCLK_SRC_EXT) {
905 cs43130->pll_bypass = true;
907 dev_err(component->dev, "Invalid MCLK source\n");
913 static u16 const cs43130_ac_freq[CS43130_AC_FREQ] = {
925 static const struct snd_soc_dai_ops cs43130_dai_ops = {
926 .startup = cs43130_pcm_startup,
927 .hw_params = cs43130_hw_params,
928 .hw_free = cs43130_hw_free,
929 .set_sysclk = cs43130_set_sysclk,
930 .set_fmt = cs43130_pcm_set_fmt,
933 static struct snd_soc_dai_driver cs43130_codec_dai = {
934 .name = "allo-cs43130",
936 .stream_name = "Playback",
939 .rates = SNDRV_PCM_RATE_CONTINUOUS,
942 .formats = SNDRV_PCM_FMTBIT_S16_LE |
943 SNDRV_PCM_FMTBIT_S24_LE |
944 SNDRV_PCM_FMTBIT_S32_LE
947 .ops = &cs43130_dai_ops,
950 static struct snd_soc_component_driver cs43130_component_driver = {
951 .idle_bias_on = true,
952 .controls = cs43130_controls,
953 .num_controls = ARRAY_SIZE(cs43130_controls),
954 .set_sysclk = cs43130_component_set_sysclk,
956 .use_pmdown_time = 1,
958 .non_legacy_dai_naming = 1,
961 static const struct regmap_config cs43130_regmap = {
966 .max_register = CS43130_LASTREG,
967 .reg_defaults = cs43130_reg_defaults,
968 .num_reg_defaults = ARRAY_SIZE(cs43130_reg_defaults),
969 .readable_reg = cs43130_readable_register,
970 .precious_reg = cs43130_precious_register,
971 .volatile_reg = cs43130_volatile_register,
972 .cache_type = REGCACHE_RBTREE,
973 /* needed for regcache_sync */
974 .use_single_read = true,
975 .use_single_write = true,
978 static u16 const cs43130_dc_threshold[CS43130_DC_THRESHOLD] = {
983 static int cs43130_handle_device_data(struct i2c_client *i2c_client,
984 struct cs43130_priv *cs43130)
986 struct device_node *np = i2c_client->dev.of_node;
990 if (of_property_read_u32(np, "cirrus,xtal-ibias", &val) < 0) {
991 /* Crystal is unused. System clock is used for external MCLK */
992 cs43130->xtal_ibias = CS43130_XTAL_UNUSED;
998 cs43130->xtal_ibias = CS43130_XTAL_IBIAS_7_5UA;
1001 cs43130->xtal_ibias = CS43130_XTAL_IBIAS_12_5UA;
1004 cs43130->xtal_ibias = CS43130_XTAL_IBIAS_15UA;
1007 dev_err(&i2c_client->dev,
1008 "Invalid cirrus,xtal-ibias value: %d\n", val);
1012 cs43130->dc_meas = of_property_read_bool(np, "cirrus,dc-measure");
1013 cs43130->ac_meas = of_property_read_bool(np, "cirrus,ac-measure");
1015 if (of_property_read_u16_array(np, "cirrus,ac-freq", cs43130->ac_freq,
1016 CS43130_AC_FREQ) < 0) {
1017 for (i = 0; i < CS43130_AC_FREQ; i++)
1018 cs43130->ac_freq[i] = cs43130_ac_freq[i];
1021 if (of_property_read_u16_array(np, "cirrus,dc-threshold",
1022 cs43130->dc_threshold,
1023 CS43130_DC_THRESHOLD) < 0) {
1024 for (i = 0; i < CS43130_DC_THRESHOLD; i++)
1025 cs43130->dc_threshold[i] = cs43130_dc_threshold[i];
1032 static int allo_cs43130_component_probe(struct i2c_client *i2c,
1033 const struct i2c_device_id *id)
1035 struct regmap *regmap;
1036 struct regmap_config config = cs43130_regmap;
1037 struct device *dev = &i2c->dev;
1038 struct cs43130_priv *cs43130;
1039 unsigned int devid = 0;
1043 regmap = devm_regmap_init_i2c(i2c, &config);
1045 return PTR_ERR(regmap);
1047 cs43130 = devm_kzalloc(dev, sizeof(struct cs43130_priv),
1052 dev_set_drvdata(dev, cs43130);
1053 cs43130->regmap = regmap;
1055 if (i2c->dev.of_node) {
1056 ret = cs43130_handle_device_data(i2c, cs43130);
1060 usleep_range(2000, 2050);
1062 ret = regmap_read(cs43130->regmap, CS43130_DEVID_AB, ®);
1063 devid = (reg & 0xFF) << 12;
1064 ret = regmap_read(cs43130->regmap, CS43130_DEVID_CD, ®);
1065 devid |= (reg & 0xFF) << 4;
1066 ret = regmap_read(cs43130->regmap, CS43130_DEVID_E, ®);
1067 devid |= (reg & 0xF0) >> 4;
1068 if (devid != CS43198_CHIP_ID) {
1069 dev_err(dev, "Failed to read Chip or wrong Chip id: %d\n", ret);
1073 cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO;
1076 ret = snd_soc_register_component(dev, &cs43130_component_driver,
1077 &cs43130_codec_dai, 1);
1079 dev_err(dev, "failed to register codec: %d\n", ret);
1082 regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG,
1083 CS43130_ASP_3ST_MASK, 0);
1084 regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG,
1085 CS43130_XSP_3ST_MASK, 1);
1086 regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
1087 CS43130_PDN_HP_MASK, 1 << CS43130_PDN_HP_SHIFT);
1089 regmap_write(cs43130->regmap, CS43130_CLASS_H_CTL, 0x06);
1090 snd_allo_clk44gpio = devm_gpiod_get(dev, "clock44", GPIOD_OUT_HIGH);
1091 if (IS_ERR(snd_allo_clk44gpio))
1092 dev_err(dev, "devm_gpiod_get() failed\n");
1094 snd_allo_clk48gpio = devm_gpiod_get(dev, "clock48", GPIOD_OUT_LOW);
1095 if (IS_ERR(snd_allo_clk48gpio))
1096 dev_err(dev, "devm_gpiod_get() failed\n");
1101 static int allo_cs43130_component_remove(struct i2c_client *i2c)
1103 snd_soc_unregister_component(&i2c->dev);
1107 static const struct i2c_device_id allo_cs43130_component_id[] = {
1108 { "allo-cs43198", },
1111 MODULE_DEVICE_TABLE(i2c, allo_cs43130_component_id);
1113 static const struct of_device_id allo_cs43130_codec_of_match[] = {
1114 { .compatible = "allo,allo-cs43198", },
1117 MODULE_DEVICE_TABLE(of, allo_cs43130_codec_of_match);
1119 static struct i2c_driver allo_cs43130_component_driver = {
1120 .probe = allo_cs43130_component_probe,
1121 .remove = allo_cs43130_component_remove,
1122 .id_table = allo_cs43130_component_id,
1124 .name = "allo-cs43198",
1125 .of_match_table = allo_cs43130_codec_of_match,
1129 module_i2c_driver(allo_cs43130_component_driver);
1131 MODULE_DESCRIPTION("ASoC Allo Boss2 Codec Driver");
1132 MODULE_AUTHOR("Sudeepkumar <sudeepkumar@cem-solutions.net>");
1133 MODULE_LICENSE("GPL v2");