aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorOder Chiou <oder_chiou@realtek.com>2016-02-03 06:53:24 -0500
committerMark Brown <broonie@kernel.org>2016-02-03 12:07:32 -0500
commit4a6180ea7399b945cd380dc63e2e8118f9b432d3 (patch)
treebd8c3c30185a67dd596d059fafe1c52beccbb703 /sound/soc
parent92e963f50fc74041b5e9e744c330dca48e04f08d (diff)
ASoC: rt5514: add rt5514 codec driver
This is the initial codec driver for rt5514. The codec includes a low power DSP for voice wake up. The register address is incremental by 4 in the DSP memory map. In order to recover the codec settings in the codec mode and manipulate the DSP mode for voice wake up, we use the multi-level register map. One is for ALSA API in codec mode that can be recovered by cache before recording. Another is for DSP related settings that can be accessed with 32bit address of the DSP in the application of voice wake up. Signed-off-by: Oder Chiou <oder_chiou@realtek.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/Kconfig6
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/rt5514.c982
-rw-r--r--sound/soc/codecs/rt5514.h252
4 files changed, 1242 insertions, 0 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 50693c867e71..dabd479bf1f0 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -95,6 +95,7 @@ config SND_SOC_ALL_CODECS
95 select SND_SOC_PCM512x_SPI if SPI_MASTER 95 select SND_SOC_PCM512x_SPI if SPI_MASTER
96 select SND_SOC_RT286 if I2C 96 select SND_SOC_RT286 if I2C
97 select SND_SOC_RT298 if I2C 97 select SND_SOC_RT298 if I2C
98 select SND_SOC_RT5514 if I2C
98 select SND_SOC_RT5616 if I2C 99 select SND_SOC_RT5616 if I2C
99 select SND_SOC_RT5631 if I2C 100 select SND_SOC_RT5631 if I2C
100 select SND_SOC_RT5640 if I2C 101 select SND_SOC_RT5640 if I2C
@@ -565,6 +566,7 @@ config SND_SOC_PCM512x_SPI
565 566
566config SND_SOC_RL6231 567config SND_SOC_RL6231
567 tristate 568 tristate
569 default y if SND_SOC_RT5514=y
568 default y if SND_SOC_RT5616=y 570 default y if SND_SOC_RT5616=y
569 default y if SND_SOC_RT5640=y 571 default y if SND_SOC_RT5640=y
570 default y if SND_SOC_RT5645=y 572 default y if SND_SOC_RT5645=y
@@ -572,6 +574,7 @@ config SND_SOC_RL6231
572 default y if SND_SOC_RT5659=y 574 default y if SND_SOC_RT5659=y
573 default y if SND_SOC_RT5670=y 575 default y if SND_SOC_RT5670=y
574 default y if SND_SOC_RT5677=y 576 default y if SND_SOC_RT5677=y
577 default m if SND_SOC_RT5514=m
575 default m if SND_SOC_RT5616=m 578 default m if SND_SOC_RT5616=m
576 default m if SND_SOC_RT5640=m 579 default m if SND_SOC_RT5640=m
577 default m if SND_SOC_RT5645=m 580 default m if SND_SOC_RT5645=m
@@ -595,6 +598,9 @@ config SND_SOC_RT298
595 tristate 598 tristate
596 depends on I2C 599 depends on I2C
597 600
601config SND_SOC_RT5514
602 tristate
603
598config SND_SOC_RT5616 604config SND_SOC_RT5616
599 tristate 605 tristate
600 606
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index d44f7d347183..79f95dd4ed68 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -92,6 +92,7 @@ snd-soc-rl6231-objs := rl6231.o
92snd-soc-rl6347a-objs := rl6347a.o 92snd-soc-rl6347a-objs := rl6347a.o
93snd-soc-rt286-objs := rt286.o 93snd-soc-rt286-objs := rt286.o
94snd-soc-rt298-objs := rt298.o 94snd-soc-rt298-objs := rt298.o
95snd-soc-rt5514-objs := rt5514.o
95snd-soc-rt5616-objs := rt5616.o 96snd-soc-rt5616-objs := rt5616.o
96snd-soc-rt5631-objs := rt5631.o 97snd-soc-rt5631-objs := rt5631.o
97snd-soc-rt5640-objs := rt5640.o 98snd-soc-rt5640-objs := rt5640.o
@@ -296,6 +297,7 @@ obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
296obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o 297obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o
297obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o 298obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
298obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o 299obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o
300obj-$(CONFIG_SND_SOC_RT5514) += snd-soc-rt5514.o
299obj-$(CONFIG_SND_SOC_RT5616) += snd-soc-rt5616.o 301obj-$(CONFIG_SND_SOC_RT5616) += snd-soc-rt5616.o
300obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o 302obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
301obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o 303obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c
new file mode 100644
index 000000000000..879bf60f4965
--- /dev/null
+++ b/sound/soc/codecs/rt5514.c
@@ -0,0 +1,982 @@
1/*
2 * rt5514.c -- RT5514 ALSA SoC audio codec driver
3 *
4 * Copyright 2015 Realtek Semiconductor Corp.
5 * Author: Oder Chiou <oder_chiou@realtek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/fs.h>
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/regmap.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <linux/firmware.h>
22#include <linux/gpio.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30
31#include "rl6231.h"
32#include "rt5514.h"
33
34static const struct reg_sequence rt5514_i2c_patch[] = {
35 {0x1800101c, 0x00000000},
36 {0x18001100, 0x0000031f},
37 {0x18001104, 0x00000007},
38 {0x18001108, 0x00000000},
39 {0x1800110c, 0x00000000},
40 {0x18001110, 0x00000000},
41 {0x18001114, 0x00000001},
42 {0x18001118, 0x00000000},
43 {0x18002f08, 0x00000006},
44 {0x18002f00, 0x00055149},
45 {0x18002f00, 0x0005514b},
46 {0x18002f00, 0x00055149},
47 {0xfafafafa, 0x00000001},
48 {0x18002f10, 0x00000001},
49 {0x18002f10, 0x00000000},
50 {0x18002f10, 0x00000001},
51 {0xfafafafa, 0x00000001},
52 {0x18002000, 0x000010ec},
53 {0xfafafafa, 0x00000000},
54};
55
56static const struct reg_sequence rt5514_patch[] = {
57 {RT5514_DIG_IO_CTRL, 0x00000040},
58 {RT5514_CLK_CTRL1, 0x38020041},
59 {RT5514_SRC_CTRL, 0x44000eee},
60 {RT5514_ANA_CTRL_LDO10, 0x00028604},
61 {RT5514_ANA_CTRL_ADCFED, 0x00000800},
62};
63
64static const struct reg_default rt5514_reg[] = {
65 {RT5514_RESET, 0x00000000},
66 {RT5514_PWR_ANA1, 0x00808880},
67 {RT5514_PWR_ANA2, 0x00220000},
68 {RT5514_I2S_CTRL1, 0x00000330},
69 {RT5514_I2S_CTRL2, 0x20000000},
70 {RT5514_VAD_CTRL6, 0xc00007d2},
71 {RT5514_EXT_VAD_CTRL, 0x80000080},
72 {RT5514_DIG_IO_CTRL, 0x00000040},
73 {RT5514_PAD_CTRL1, 0x00804000},
74 {RT5514_DMIC_DATA_CTRL, 0x00000005},
75 {RT5514_DIG_SOURCE_CTRL, 0x00000002},
76 {RT5514_SRC_CTRL, 0x44000eee},
77 {RT5514_DOWNFILTER2_CTRL1, 0x0000882f},
78 {RT5514_PLL_SOURCE_CTRL, 0x00000004},
79 {RT5514_CLK_CTRL1, 0x38020041},
80 {RT5514_CLK_CTRL2, 0x00000000},
81 {RT5514_PLL3_CALIB_CTRL1, 0x00400200},
82 {RT5514_PLL3_CALIB_CTRL5, 0x40220012},
83 {RT5514_DELAY_BUF_CTRL1, 0x7fff006a},
84 {RT5514_DELAY_BUF_CTRL3, 0x00000000},
85 {RT5514_DOWNFILTER0_CTRL1, 0x00020c2f},
86 {RT5514_DOWNFILTER0_CTRL2, 0x00020c2f},
87 {RT5514_DOWNFILTER0_CTRL3, 0x00000362},
88 {RT5514_DOWNFILTER1_CTRL1, 0x00020c2f},
89 {RT5514_DOWNFILTER1_CTRL2, 0x00020c2f},
90 {RT5514_DOWNFILTER1_CTRL3, 0x00000362},
91 {RT5514_ANA_CTRL_LDO10, 0x00028604},
92 {RT5514_ANA_CTRL_LDO18_16, 0x02000345},
93 {RT5514_ANA_CTRL_ADC12, 0x0000a2a8},
94 {RT5514_ANA_CTRL_ADC21, 0x00001180},
95 {RT5514_ANA_CTRL_ADC22, 0x0000aaa8},
96 {RT5514_ANA_CTRL_ADC23, 0x00151427},
97 {RT5514_ANA_CTRL_MICBST, 0x00002000},
98 {RT5514_ANA_CTRL_ADCFED, 0x00000800},
99 {RT5514_ANA_CTRL_INBUF, 0x00000143},
100 {RT5514_ANA_CTRL_VREF, 0x00008d50},
101 {RT5514_ANA_CTRL_PLL3, 0x0000000e},
102 {RT5514_ANA_CTRL_PLL1_1, 0x00000000},
103 {RT5514_ANA_CTRL_PLL1_2, 0x00030220},
104 {RT5514_DMIC_LP_CTRL, 0x00000000},
105 {RT5514_MISC_CTRL_DSP, 0x00000000},
106 {RT5514_DSP_CTRL1, 0x00055149},
107 {RT5514_DSP_CTRL3, 0x00000006},
108 {RT5514_DSP_CTRL4, 0x00000001},
109 {RT5514_VENDOR_ID1, 0x00000001},
110 {RT5514_VENDOR_ID2, 0x10ec5514},
111};
112
113static bool rt5514_volatile_register(struct device *dev, unsigned int reg)
114{
115 switch (reg) {
116 case RT5514_VENDOR_ID1:
117 case RT5514_VENDOR_ID2:
118 return true;
119
120 default:
121 return false;
122 }
123}
124
125static bool rt5514_readable_register(struct device *dev, unsigned int reg)
126{
127 switch (reg) {
128 case RT5514_RESET:
129 case RT5514_PWR_ANA1:
130 case RT5514_PWR_ANA2:
131 case RT5514_I2S_CTRL1:
132 case RT5514_I2S_CTRL2:
133 case RT5514_VAD_CTRL6:
134 case RT5514_EXT_VAD_CTRL:
135 case RT5514_DIG_IO_CTRL:
136 case RT5514_PAD_CTRL1:
137 case RT5514_DMIC_DATA_CTRL:
138 case RT5514_DIG_SOURCE_CTRL:
139 case RT5514_SRC_CTRL:
140 case RT5514_DOWNFILTER2_CTRL1:
141 case RT5514_PLL_SOURCE_CTRL:
142 case RT5514_CLK_CTRL1:
143 case RT5514_CLK_CTRL2:
144 case RT5514_PLL3_CALIB_CTRL1:
145 case RT5514_PLL3_CALIB_CTRL5:
146 case RT5514_DELAY_BUF_CTRL1:
147 case RT5514_DELAY_BUF_CTRL3:
148 case RT5514_DOWNFILTER0_CTRL1:
149 case RT5514_DOWNFILTER0_CTRL2:
150 case RT5514_DOWNFILTER0_CTRL3:
151 case RT5514_DOWNFILTER1_CTRL1:
152 case RT5514_DOWNFILTER1_CTRL2:
153 case RT5514_DOWNFILTER1_CTRL3:
154 case RT5514_ANA_CTRL_LDO10:
155 case RT5514_ANA_CTRL_LDO18_16:
156 case RT5514_ANA_CTRL_ADC12:
157 case RT5514_ANA_CTRL_ADC21:
158 case RT5514_ANA_CTRL_ADC22:
159 case RT5514_ANA_CTRL_ADC23:
160 case RT5514_ANA_CTRL_MICBST:
161 case RT5514_ANA_CTRL_ADCFED:
162 case RT5514_ANA_CTRL_INBUF:
163 case RT5514_ANA_CTRL_VREF:
164 case RT5514_ANA_CTRL_PLL3:
165 case RT5514_ANA_CTRL_PLL1_1:
166 case RT5514_ANA_CTRL_PLL1_2:
167 case RT5514_DMIC_LP_CTRL:
168 case RT5514_MISC_CTRL_DSP:
169 case RT5514_DSP_CTRL1:
170 case RT5514_DSP_CTRL3:
171 case RT5514_DSP_CTRL4:
172 case RT5514_VENDOR_ID1:
173 case RT5514_VENDOR_ID2:
174 return true;
175
176 default:
177 return false;
178 }
179}
180
181static bool rt5514_i2c_readable_register(struct device *dev,
182 unsigned int reg)
183{
184 switch (reg) {
185 case RT5514_DSP_MAPPING | RT5514_RESET:
186 case RT5514_DSP_MAPPING | RT5514_PWR_ANA1:
187 case RT5514_DSP_MAPPING | RT5514_PWR_ANA2:
188 case RT5514_DSP_MAPPING | RT5514_I2S_CTRL1:
189 case RT5514_DSP_MAPPING | RT5514_I2S_CTRL2:
190 case RT5514_DSP_MAPPING | RT5514_VAD_CTRL6:
191 case RT5514_DSP_MAPPING | RT5514_EXT_VAD_CTRL:
192 case RT5514_DSP_MAPPING | RT5514_DIG_IO_CTRL:
193 case RT5514_DSP_MAPPING | RT5514_PAD_CTRL1:
194 case RT5514_DSP_MAPPING | RT5514_DMIC_DATA_CTRL:
195 case RT5514_DSP_MAPPING | RT5514_DIG_SOURCE_CTRL:
196 case RT5514_DSP_MAPPING | RT5514_SRC_CTRL:
197 case RT5514_DSP_MAPPING | RT5514_DOWNFILTER2_CTRL1:
198 case RT5514_DSP_MAPPING | RT5514_PLL_SOURCE_CTRL:
199 case RT5514_DSP_MAPPING | RT5514_CLK_CTRL1:
200 case RT5514_DSP_MAPPING | RT5514_CLK_CTRL2:
201 case RT5514_DSP_MAPPING | RT5514_PLL3_CALIB_CTRL1:
202 case RT5514_DSP_MAPPING | RT5514_PLL3_CALIB_CTRL5:
203 case RT5514_DSP_MAPPING | RT5514_DELAY_BUF_CTRL1:
204 case RT5514_DSP_MAPPING | RT5514_DELAY_BUF_CTRL3:
205 case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL1:
206 case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL2:
207 case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL3:
208 case RT5514_DSP_MAPPING | RT5514_DOWNFILTER1_CTRL1:
209 case RT5514_DSP_MAPPING | RT5514_DOWNFILTER1_CTRL2:
210 case RT5514_DSP_MAPPING | RT5514_DOWNFILTER1_CTRL3:
211 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_LDO10:
212 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_LDO18_16:
213 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_ADC12:
214 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_ADC21:
215 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_ADC22:
216 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_ADC23:
217 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_MICBST:
218 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_ADCFED:
219 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_INBUF:
220 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_VREF:
221 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_PLL3:
222 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_PLL1_1:
223 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_PLL1_2:
224 case RT5514_DSP_MAPPING | RT5514_DMIC_LP_CTRL:
225 case RT5514_DSP_MAPPING | RT5514_MISC_CTRL_DSP:
226 case RT5514_DSP_MAPPING | RT5514_DSP_CTRL1:
227 case RT5514_DSP_MAPPING | RT5514_DSP_CTRL3:
228 case RT5514_DSP_MAPPING | RT5514_DSP_CTRL4:
229 case RT5514_DSP_MAPPING | RT5514_VENDOR_ID1:
230 case RT5514_DSP_MAPPING | RT5514_VENDOR_ID2:
231 return true;
232
233 default:
234 return false;
235 }
236}
237
238/* {-3, 0, +3, +4.5, +7.5, +9.5, +12, +14, +17} dB */
239static const DECLARE_TLV_DB_RANGE(bst_tlv,
240 0, 2, TLV_DB_SCALE_ITEM(-300, 300, 0),
241 3, 3, TLV_DB_SCALE_ITEM(450, 0, 0),
242 4, 4, TLV_DB_SCALE_ITEM(750, 0, 0),
243 5, 5, TLV_DB_SCALE_ITEM(950, 0, 0),
244 6, 6, TLV_DB_SCALE_ITEM(1200, 0, 0),
245 7, 7, TLV_DB_SCALE_ITEM(1400, 0, 0),
246 8, 8, TLV_DB_SCALE_ITEM(1700, 0, 0)
247);
248
249static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
250
251static const struct snd_kcontrol_new rt5514_snd_controls[] = {
252 SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST,
253 RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv),
254 SOC_DOUBLE_R_TLV("ADC1 Capture Volume", RT5514_DOWNFILTER0_CTRL1,
255 RT5514_DOWNFILTER0_CTRL2, RT5514_AD_GAIN_SFT, 127, 0,
256 adc_vol_tlv),
257 SOC_DOUBLE_R_TLV("ADC2 Capture Volume", RT5514_DOWNFILTER1_CTRL1,
258 RT5514_DOWNFILTER1_CTRL2, RT5514_AD_GAIN_SFT, 127, 0,
259 adc_vol_tlv),
260};
261
262/* ADC Mixer*/
263static const struct snd_kcontrol_new rt5514_sto1_adc_l_mix[] = {
264 SOC_DAPM_SINGLE("DMIC Switch", RT5514_DOWNFILTER0_CTRL1,
265 RT5514_AD_DMIC_MIX_BIT, 1, 1),
266 SOC_DAPM_SINGLE("ADC Switch", RT5514_DOWNFILTER0_CTRL1,
267 RT5514_AD_AD_MIX_BIT, 1, 1),
268};
269
270static const struct snd_kcontrol_new rt5514_sto1_adc_r_mix[] = {
271 SOC_DAPM_SINGLE("DMIC Switch", RT5514_DOWNFILTER0_CTRL2,
272 RT5514_AD_DMIC_MIX_BIT, 1, 1),
273 SOC_DAPM_SINGLE("ADC Switch", RT5514_DOWNFILTER0_CTRL2,
274 RT5514_AD_AD_MIX_BIT, 1, 1),
275};
276
277static const struct snd_kcontrol_new rt5514_sto2_adc_l_mix[] = {
278 SOC_DAPM_SINGLE("DMIC Switch", RT5514_DOWNFILTER1_CTRL1,
279 RT5514_AD_DMIC_MIX_BIT, 1, 1),
280 SOC_DAPM_SINGLE("ADC Switch", RT5514_DOWNFILTER1_CTRL1,
281 RT5514_AD_AD_MIX_BIT, 1, 1),
282};
283
284static const struct snd_kcontrol_new rt5514_sto2_adc_r_mix[] = {
285 SOC_DAPM_SINGLE("DMIC Switch", RT5514_DOWNFILTER1_CTRL2,
286 RT5514_AD_DMIC_MIX_BIT, 1, 1),
287 SOC_DAPM_SINGLE("ADC Switch", RT5514_DOWNFILTER1_CTRL2,
288 RT5514_AD_AD_MIX_BIT, 1, 1),
289};
290
291/* DMIC Source */
292static const char * const rt5514_dmic_src[] = {
293 "DMIC1", "DMIC2"
294};
295
296static const SOC_ENUM_SINGLE_DECL(
297 rt5514_stereo1_dmic_enum, RT5514_DIG_SOURCE_CTRL,
298 RT5514_AD0_DMIC_INPUT_SEL_SFT, rt5514_dmic_src);
299
300static const struct snd_kcontrol_new rt5514_sto1_dmic_mux =
301 SOC_DAPM_ENUM("Stereo1 DMIC Source", rt5514_stereo1_dmic_enum);
302
303static const SOC_ENUM_SINGLE_DECL(
304 rt5514_stereo2_dmic_enum, RT5514_DIG_SOURCE_CTRL,
305 RT5514_AD1_DMIC_INPUT_SEL_SFT, rt5514_dmic_src);
306
307static const struct snd_kcontrol_new rt5514_sto2_dmic_mux =
308 SOC_DAPM_ENUM("Stereo2 DMIC Source", rt5514_stereo2_dmic_enum);
309
310/**
311 * rt5514_calc_dmic_clk - Calculate the frequency divider parameter of dmic.
312 *
313 * @rate: base clock rate.
314 *
315 * Choose divider parameter that gives the highest possible DMIC frequency in
316 * 1MHz - 3MHz range.
317 */
318static int rt5514_calc_dmic_clk(struct snd_soc_codec *codec, int rate)
319{
320 int div[] = {2, 3, 4, 8, 12, 16, 24, 32};
321 int i;
322
323 if (rate < 1000000 * div[0]) {
324 pr_warn("Base clock rate %d is too low\n", rate);
325 return -EINVAL;
326 }
327
328 for (i = 0; i < ARRAY_SIZE(div); i++) {
329 /* find divider that gives DMIC frequency below 3.072MHz */
330 if (3072000 * div[i] >= rate)
331 return i;
332 }
333
334 dev_warn(codec->dev, "Base clock rate %d is too high\n", rate);
335 return -EINVAL;
336}
337
338static int rt5514_set_dmic_clk(struct snd_soc_dapm_widget *w,
339 struct snd_kcontrol *kcontrol, int event)
340{
341 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
342 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
343 int idx;
344
345 idx = rt5514_calc_dmic_clk(codec, rt5514->sysclk);
346 if (idx < 0)
347 dev_err(codec->dev, "Failed to set DMIC clock\n");
348 else
349 regmap_update_bits(rt5514->regmap, RT5514_CLK_CTRL1,
350 RT5514_CLK_DMIC_OUT_SEL_MASK,
351 idx << RT5514_CLK_DMIC_OUT_SEL_SFT);
352
353 return idx;
354}
355
356static int rt5514_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
357 struct snd_soc_dapm_widget *sink)
358{
359 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
360 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
361
362 if (rt5514->sysclk_src == RT5514_SCLK_S_PLL1)
363 return 1;
364 else
365 return 0;
366}
367
368static const struct snd_soc_dapm_widget rt5514_dapm_widgets[] = {
369 /* Input Lines */
370 SND_SOC_DAPM_INPUT("DMIC1L"),
371 SND_SOC_DAPM_INPUT("DMIC1R"),
372 SND_SOC_DAPM_INPUT("DMIC2L"),
373 SND_SOC_DAPM_INPUT("DMIC2R"),
374
375 SND_SOC_DAPM_INPUT("AMICL"),
376 SND_SOC_DAPM_INPUT("AMICR"),
377
378 SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0),
379 SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0),
380
381 SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
382 rt5514_set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
383
384 SND_SOC_DAPM_SUPPLY("ADC CLK", RT5514_CLK_CTRL1,
385 RT5514_CLK_AD_ANA1_EN_BIT, 0, NULL, 0),
386
387 SND_SOC_DAPM_SUPPLY("LDO18 IN", RT5514_PWR_ANA1,
388 RT5514_POW_LDO18_IN_BIT, 0, NULL, 0),
389 SND_SOC_DAPM_SUPPLY("LDO18 ADC", RT5514_PWR_ANA1,
390 RT5514_POW_LDO18_ADC_BIT, 0, NULL, 0),
391 SND_SOC_DAPM_SUPPLY("LDO21", RT5514_PWR_ANA1, RT5514_POW_LDO21_BIT, 0,
392 NULL, 0),
393 SND_SOC_DAPM_SUPPLY("BG LDO18 IN", RT5514_PWR_ANA1,
394 RT5514_POW_BG_LDO18_IN_BIT, 0, NULL, 0),
395 SND_SOC_DAPM_SUPPLY("BG LDO21", RT5514_PWR_ANA1,
396 RT5514_POW_BG_LDO21_BIT, 0, NULL, 0),
397 SND_SOC_DAPM_SUPPLY("BG MBIAS", RT5514_PWR_ANA2,
398 RT5514_POW_BG_MBIAS_BIT, 0, NULL, 0),
399 SND_SOC_DAPM_SUPPLY("MBIAS", RT5514_PWR_ANA2, RT5514_POW_MBIAS_BIT, 0,
400 NULL, 0),
401 SND_SOC_DAPM_SUPPLY("VREF2", RT5514_PWR_ANA2, RT5514_POW_VREF2_BIT, 0,
402 NULL, 0),
403 SND_SOC_DAPM_SUPPLY("VREF1", RT5514_PWR_ANA2, RT5514_POW_VREF1_BIT, 0,
404 NULL, 0),
405 SND_SOC_DAPM_SUPPLY("ADC Power", SND_SOC_NOPM, 0, 0, NULL, 0),
406
407
408 SND_SOC_DAPM_SUPPLY("LDO16L", RT5514_PWR_ANA2, RT5514_POWL_LDO16_BIT, 0,
409 NULL, 0),
410 SND_SOC_DAPM_SUPPLY("ADC1L", RT5514_PWR_ANA2, RT5514_POW_ADC1_L_BIT, 0,
411 NULL, 0),
412 SND_SOC_DAPM_SUPPLY("BSTL2", RT5514_PWR_ANA2, RT5514_POW2_BSTL_BIT, 0,
413 NULL, 0),
414 SND_SOC_DAPM_SUPPLY("BSTL", RT5514_PWR_ANA2, RT5514_POW_BSTL_BIT, 0,
415 NULL, 0),
416 SND_SOC_DAPM_SUPPLY("ADCFEDL", RT5514_PWR_ANA2, RT5514_POW_ADCFEDL_BIT,
417 0, NULL, 0),
418 SND_SOC_DAPM_SUPPLY("ADCL Power", SND_SOC_NOPM, 0, 0, NULL, 0),
419
420 SND_SOC_DAPM_SUPPLY("LDO16R", RT5514_PWR_ANA2, RT5514_POWR_LDO16_BIT, 0,
421 NULL, 0),
422 SND_SOC_DAPM_SUPPLY("ADC1R", RT5514_PWR_ANA2, RT5514_POW_ADC1_R_BIT, 0,
423 NULL, 0),
424 SND_SOC_DAPM_SUPPLY("BSTR2", RT5514_PWR_ANA2, RT5514_POW2_BSTR_BIT, 0,
425 NULL, 0),
426 SND_SOC_DAPM_SUPPLY("BSTR", RT5514_PWR_ANA2, RT5514_POW_BSTR_BIT, 0,
427 NULL, 0),
428 SND_SOC_DAPM_SUPPLY("ADCFEDR", RT5514_PWR_ANA2, RT5514_POW_ADCFEDR_BIT,
429 0, NULL, 0),
430 SND_SOC_DAPM_SUPPLY("ADCR Power", SND_SOC_NOPM, 0, 0, NULL, 0),
431
432 SND_SOC_DAPM_SUPPLY("PLL1 LDO ENABLE", RT5514_ANA_CTRL_PLL1_2,
433 RT5514_EN_LDO_PLL1_BIT, 0, NULL, 0),
434 SND_SOC_DAPM_SUPPLY("PLL1 LDO", RT5514_PWR_ANA2,
435 RT5514_POW_PLL1_LDO_BIT, 0, NULL, 0),
436 SND_SOC_DAPM_SUPPLY("PLL1", RT5514_PWR_ANA2, RT5514_POW_PLL1_BIT, 0,
437 NULL, 0),
438
439 /* ADC Mux */
440 SND_SOC_DAPM_MUX("Stereo1 DMIC Mux", SND_SOC_NOPM, 0, 0,
441 &rt5514_sto1_dmic_mux),
442 SND_SOC_DAPM_MUX("Stereo2 DMIC Mux", SND_SOC_NOPM, 0, 0,
443 &rt5514_sto2_dmic_mux),
444
445 /* ADC Mixer */
446 SND_SOC_DAPM_SUPPLY("adc stereo1 filter", RT5514_CLK_CTRL1,
447 RT5514_CLK_AD0_EN_BIT, 0, NULL, 0),
448 SND_SOC_DAPM_SUPPLY("adc stereo2 filter", RT5514_CLK_CTRL1,
449 RT5514_CLK_AD1_EN_BIT, 0, NULL, 0),
450
451 SND_SOC_DAPM_MIXER("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0,
452 rt5514_sto1_adc_l_mix, ARRAY_SIZE(rt5514_sto1_adc_l_mix)),
453 SND_SOC_DAPM_MIXER("Sto1 ADC MIXR", SND_SOC_NOPM, 0, 0,
454 rt5514_sto1_adc_r_mix, ARRAY_SIZE(rt5514_sto1_adc_r_mix)),
455 SND_SOC_DAPM_MIXER("Sto2 ADC MIXL", SND_SOC_NOPM, 0, 0,
456 rt5514_sto2_adc_l_mix, ARRAY_SIZE(rt5514_sto2_adc_l_mix)),
457 SND_SOC_DAPM_MIXER("Sto2 ADC MIXR", SND_SOC_NOPM, 0, 0,
458 rt5514_sto2_adc_r_mix, ARRAY_SIZE(rt5514_sto2_adc_r_mix)),
459
460 SND_SOC_DAPM_ADC("Stereo1 ADC MIXL", NULL, RT5514_DOWNFILTER0_CTRL1,
461 RT5514_AD_AD_MUTE_BIT, 1),
462 SND_SOC_DAPM_ADC("Stereo1 ADC MIXR", NULL, RT5514_DOWNFILTER0_CTRL2,
463 RT5514_AD_AD_MUTE_BIT, 1),
464 SND_SOC_DAPM_ADC("Stereo2 ADC MIXL", NULL, RT5514_DOWNFILTER1_CTRL1,
465 RT5514_AD_AD_MUTE_BIT, 1),
466 SND_SOC_DAPM_ADC("Stereo2 ADC MIXR", NULL, RT5514_DOWNFILTER1_CTRL2,
467 RT5514_AD_AD_MUTE_BIT, 1),
468
469 /* ADC PGA */
470 SND_SOC_DAPM_PGA("Stereo1 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
471 SND_SOC_DAPM_PGA("Stereo2 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
472
473 /* Audio Interface */
474 SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
475};
476
477static const struct snd_soc_dapm_route rt5514_dapm_routes[] = {
478 { "DMIC1", NULL, "DMIC1L" },
479 { "DMIC1", NULL, "DMIC1R" },
480 { "DMIC2", NULL, "DMIC2L" },
481 { "DMIC2", NULL, "DMIC2R" },
482
483 { "DMIC1L", NULL, "DMIC CLK" },
484 { "DMIC1R", NULL, "DMIC CLK" },
485 { "DMIC2L", NULL, "DMIC CLK" },
486 { "DMIC2R", NULL, "DMIC CLK" },
487
488 { "Stereo1 DMIC Mux", "DMIC1", "DMIC1" },
489 { "Stereo1 DMIC Mux", "DMIC2", "DMIC2" },
490
491 { "Sto1 ADC MIXL", "DMIC Switch", "Stereo1 DMIC Mux" },
492 { "Sto1 ADC MIXL", "ADC Switch", "AMICL" },
493 { "Sto1 ADC MIXR", "DMIC Switch", "Stereo1 DMIC Mux" },
494 { "Sto1 ADC MIXR", "ADC Switch", "AMICR" },
495
496 { "ADC Power", NULL, "LDO18 IN" },
497 { "ADC Power", NULL, "LDO18 ADC" },
498 { "ADC Power", NULL, "LDO21" },
499 { "ADC Power", NULL, "BG LDO18 IN" },
500 { "ADC Power", NULL, "BG LDO21" },
501 { "ADC Power", NULL, "BG MBIAS" },
502 { "ADC Power", NULL, "MBIAS" },
503 { "ADC Power", NULL, "VREF2" },
504 { "ADC Power", NULL, "VREF1" },
505
506 { "ADCL Power", NULL, "LDO16L" },
507 { "ADCL Power", NULL, "ADC1L" },
508 { "ADCL Power", NULL, "BSTL2" },
509 { "ADCL Power", NULL, "BSTL" },
510 { "ADCL Power", NULL, "ADCFEDL" },
511
512 { "ADCR Power", NULL, "LDO16R" },
513 { "ADCR Power", NULL, "ADC1R" },
514 { "ADCR Power", NULL, "BSTR2" },
515 { "ADCR Power", NULL, "BSTR" },
516 { "ADCR Power", NULL, "ADCFEDR" },
517
518 { "AMICL", NULL, "ADC CLK" },
519 { "AMICL", NULL, "ADC Power" },
520 { "AMICL", NULL, "ADCL Power" },
521 { "AMICR", NULL, "ADC CLK" },
522 { "AMICR", NULL, "ADC Power" },
523 { "AMICR", NULL, "ADCR Power" },
524
525 { "PLL1 LDO", NULL, "PLL1 LDO ENABLE" },
526 { "PLL1", NULL, "PLL1 LDO" },
527
528 { "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" },
529 { "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" },
530
531 { "Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXL" },
532 { "Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXR" },
533 { "Stereo1 ADC MIX", NULL, "adc stereo1 filter" },
534 { "adc stereo1 filter", NULL, "PLL1", rt5514_is_sys_clk_from_pll },
535
536 { "Stereo2 DMIC Mux", "DMIC1", "DMIC1" },
537 { "Stereo2 DMIC Mux", "DMIC2", "DMIC2" },
538
539 { "Sto2 ADC MIXL", "DMIC Switch", "Stereo2 DMIC Mux" },
540 { "Sto2 ADC MIXL", "ADC Switch", "AMICL" },
541 { "Sto2 ADC MIXR", "DMIC Switch", "Stereo2 DMIC Mux" },
542 { "Sto2 ADC MIXR", "ADC Switch", "AMICR" },
543
544 { "Stereo2 ADC MIXL", NULL, "Sto2 ADC MIXL" },
545 { "Stereo2 ADC MIXR", NULL, "Sto2 ADC MIXR" },
546
547 { "Stereo2 ADC MIX", NULL, "Stereo2 ADC MIXL" },
548 { "Stereo2 ADC MIX", NULL, "Stereo2 ADC MIXR" },
549 { "Stereo2 ADC MIX", NULL, "adc stereo2 filter" },
550 { "adc stereo2 filter", NULL, "PLL1", rt5514_is_sys_clk_from_pll },
551
552 { "AIF1TX", NULL, "Stereo1 ADC MIX"},
553 { "AIF1TX", NULL, "Stereo2 ADC MIX"},
554};
555
556static int rt5514_hw_params(struct snd_pcm_substream *substream,
557 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
558{
559 struct snd_soc_codec *codec = dai->codec;
560 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
561 int pre_div, bclk_ms, frame_size;
562 unsigned int val_len = 0;
563
564 rt5514->lrck = params_rate(params);
565 pre_div = rl6231_get_clk_info(rt5514->sysclk, rt5514->lrck);
566 if (pre_div < 0) {
567 dev_err(codec->dev, "Unsupported clock setting\n");
568 return -EINVAL;
569 }
570
571 frame_size = snd_soc_params_to_frame_size(params);
572 if (frame_size < 0) {
573 dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
574 return -EINVAL;
575 }
576
577 bclk_ms = frame_size > 32;
578 rt5514->bclk = rt5514->lrck * (32 << bclk_ms);
579
580 dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n",
581 rt5514->bclk, rt5514->lrck);
582 dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
583 bclk_ms, pre_div, dai->id);
584
585 switch (params_format(params)) {
586 case SNDRV_PCM_FORMAT_S16_LE:
587 break;
588 case SNDRV_PCM_FORMAT_S20_3LE:
589 val_len = RT5514_I2S_DL_20;
590 break;
591 case SNDRV_PCM_FORMAT_S24_LE:
592 val_len = RT5514_I2S_DL_24;
593 break;
594 case SNDRV_PCM_FORMAT_S8:
595 val_len = RT5514_I2S_DL_8;
596 break;
597 default:
598 return -EINVAL;
599 }
600
601 regmap_update_bits(rt5514->regmap, RT5514_I2S_CTRL1, RT5514_I2S_DL_MASK,
602 val_len);
603 regmap_update_bits(rt5514->regmap, RT5514_CLK_CTRL2,
604 RT5514_CLK_SYS_DIV_OUT_MASK | RT5514_SEL_ADC_OSR_MASK,
605 pre_div << RT5514_CLK_SYS_DIV_OUT_SFT |
606 pre_div << RT5514_SEL_ADC_OSR_SFT);
607
608 return 0;
609}
610
611static int rt5514_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
612{
613 struct snd_soc_codec *codec = dai->codec;
614 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
615 unsigned int reg_val = 0;
616
617 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
618 case SND_SOC_DAIFMT_NB_NF:
619 break;
620
621 case SND_SOC_DAIFMT_NB_IF:
622 reg_val |= RT5514_I2S_LR_INV;
623 break;
624
625 case SND_SOC_DAIFMT_IB_NF:
626 reg_val |= RT5514_I2S_BP_INV;
627 break;
628
629 case SND_SOC_DAIFMT_IB_IF:
630 reg_val |= RT5514_I2S_BP_INV | RT5514_I2S_LR_INV;
631 break;
632
633 default:
634 return -EINVAL;
635 }
636
637 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
638 case SND_SOC_DAIFMT_I2S:
639 break;
640
641 case SND_SOC_DAIFMT_LEFT_J:
642 reg_val |= RT5514_I2S_DF_LEFT;
643 break;
644
645 case SND_SOC_DAIFMT_DSP_A:
646 reg_val |= RT5514_I2S_DF_PCM_A;
647 break;
648
649 case SND_SOC_DAIFMT_DSP_B:
650 reg_val |= RT5514_I2S_DF_PCM_B;
651 break;
652
653 default:
654 return -EINVAL;
655 }
656
657 regmap_update_bits(rt5514->regmap, RT5514_I2S_CTRL1,
658 RT5514_I2S_DF_MASK | RT5514_I2S_BP_MASK | RT5514_I2S_LR_MASK,
659 reg_val);
660
661 return 0;
662}
663
664static int rt5514_set_dai_sysclk(struct snd_soc_dai *dai,
665 int clk_id, unsigned int freq, int dir)
666{
667 struct snd_soc_codec *codec = dai->codec;
668 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
669 unsigned int reg_val = 0;
670
671 if (freq == rt5514->sysclk && clk_id == rt5514->sysclk_src)
672 return 0;
673
674 switch (clk_id) {
675 case RT5514_SCLK_S_MCLK:
676 reg_val |= RT5514_CLK_SYS_PRE_SEL_MCLK;
677 break;
678
679 case RT5514_SCLK_S_PLL1:
680 reg_val |= RT5514_CLK_SYS_PRE_SEL_PLL;
681 break;
682
683 default:
684 dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
685 return -EINVAL;
686 }
687
688 regmap_update_bits(rt5514->regmap, RT5514_CLK_CTRL2,
689 RT5514_CLK_SYS_PRE_SEL_MASK, reg_val);
690
691 rt5514->sysclk = freq;
692 rt5514->sysclk_src = clk_id;
693
694 dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
695
696 return 0;
697}
698
699static int rt5514_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
700 unsigned int freq_in, unsigned int freq_out)
701{
702 struct snd_soc_codec *codec = dai->codec;
703 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
704 struct rl6231_pll_code pll_code;
705 int ret;
706
707 if (!freq_in || !freq_out) {
708 dev_dbg(codec->dev, "PLL disabled\n");
709
710 rt5514->pll_in = 0;
711 rt5514->pll_out = 0;
712 regmap_update_bits(rt5514->regmap, RT5514_CLK_CTRL2,
713 RT5514_CLK_SYS_PRE_SEL_MASK,
714 RT5514_CLK_SYS_PRE_SEL_MCLK);
715
716 return 0;
717 }
718
719 if (source == rt5514->pll_src && freq_in == rt5514->pll_in &&
720 freq_out == rt5514->pll_out)
721 return 0;
722
723 switch (source) {
724 case RT5514_PLL1_S_MCLK:
725 regmap_update_bits(rt5514->regmap, RT5514_PLL_SOURCE_CTRL,
726 RT5514_PLL_1_SEL_MASK, RT5514_PLL_1_SEL_MCLK);
727 break;
728
729 case RT5514_PLL1_S_BCLK:
730 regmap_update_bits(rt5514->regmap, RT5514_PLL_SOURCE_CTRL,
731 RT5514_PLL_1_SEL_MASK, RT5514_PLL_1_SEL_SCLK);
732 break;
733
734 default:
735 dev_err(codec->dev, "Unknown PLL source %d\n", source);
736 return -EINVAL;
737 }
738
739 ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
740 if (ret < 0) {
741 dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
742 return ret;
743 }
744
745 dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
746 pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
747 pll_code.n_code, pll_code.k_code);
748
749 regmap_write(rt5514->regmap, RT5514_ANA_CTRL_PLL1_1,
750 pll_code.k_code << RT5514_PLL_K_SFT |
751 pll_code.n_code << RT5514_PLL_N_SFT |
752 (pll_code.m_bp ? 0 : pll_code.m_code) << RT5514_PLL_M_SFT);
753 regmap_update_bits(rt5514->regmap, RT5514_ANA_CTRL_PLL1_2,
754 RT5514_PLL_M_BP, pll_code.m_bp << RT5514_PLL_M_BP_SFT);
755
756 rt5514->pll_in = freq_in;
757 rt5514->pll_out = freq_out;
758 rt5514->pll_src = source;
759
760 return 0;
761}
762
763static int rt5514_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
764 unsigned int rx_mask, int slots, int slot_width)
765{
766 struct snd_soc_codec *codec = dai->codec;
767 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
768 unsigned int val = 0;
769
770 if (rx_mask || tx_mask)
771 val |= RT5514_TDM_MODE;
772
773 if (slots == 4)
774 val |= RT5514_TDMSLOT_SEL_RX_4CH | RT5514_TDMSLOT_SEL_TX_4CH;
775
776
777 switch (slot_width) {
778 case 20:
779 val |= RT5514_CH_LEN_RX_20 | RT5514_CH_LEN_TX_20;
780 break;
781
782 case 24:
783 val |= RT5514_CH_LEN_RX_24 | RT5514_CH_LEN_TX_24;
784 break;
785
786 case 32:
787 val |= RT5514_CH_LEN_RX_32 | RT5514_CH_LEN_TX_32;
788 break;
789
790 case 16:
791 default:
792 break;
793 }
794
795 regmap_update_bits(rt5514->regmap, RT5514_I2S_CTRL1, RT5514_TDM_MODE |
796 RT5514_TDMSLOT_SEL_RX_MASK | RT5514_TDMSLOT_SEL_TX_MASK |
797 RT5514_CH_LEN_RX_MASK | RT5514_CH_LEN_TX_MASK, val);
798
799 return 0;
800}
801
802static int rt5514_probe(struct snd_soc_codec *codec)
803{
804 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
805
806 rt5514->codec = codec;
807
808 return 0;
809}
810
811static int rt5514_i2c_read(void *context, unsigned int reg, unsigned int *val)
812{
813 struct i2c_client *client = context;
814 struct rt5514_priv *rt5514 = i2c_get_clientdata(client);
815
816 regmap_read(rt5514->i2c_regmap, reg | RT5514_DSP_MAPPING, val);
817
818 return 0;
819}
820
821static int rt5514_i2c_write(void *context, unsigned int reg, unsigned int val)
822{
823 struct i2c_client *client = context;
824 struct rt5514_priv *rt5514 = i2c_get_clientdata(client);
825
826 regmap_write(rt5514->i2c_regmap, reg | RT5514_DSP_MAPPING, val);
827
828 return 0;
829}
830
831#define RT5514_STEREO_RATES SNDRV_PCM_RATE_8000_192000
832#define RT5514_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
833 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
834
835struct snd_soc_dai_ops rt5514_aif_dai_ops = {
836 .hw_params = rt5514_hw_params,
837 .set_fmt = rt5514_set_dai_fmt,
838 .set_sysclk = rt5514_set_dai_sysclk,
839 .set_pll = rt5514_set_dai_pll,
840 .set_tdm_slot = rt5514_set_tdm_slot,
841};
842
843struct snd_soc_dai_driver rt5514_dai[] = {
844 {
845 .name = "rt5514-aif1",
846 .id = 0,
847 .capture = {
848 .stream_name = "AIF1 Capture",
849 .channels_min = 1,
850 .channels_max = 4,
851 .rates = RT5514_STEREO_RATES,
852 .formats = RT5514_FORMATS,
853 },
854 .ops = &rt5514_aif_dai_ops,
855 }
856};
857
858static struct snd_soc_codec_driver soc_codec_dev_rt5514 = {
859 .probe = rt5514_probe,
860 .idle_bias_off = true,
861 .controls = rt5514_snd_controls,
862 .num_controls = ARRAY_SIZE(rt5514_snd_controls),
863 .dapm_widgets = rt5514_dapm_widgets,
864 .num_dapm_widgets = ARRAY_SIZE(rt5514_dapm_widgets),
865 .dapm_routes = rt5514_dapm_routes,
866 .num_dapm_routes = ARRAY_SIZE(rt5514_dapm_routes),
867};
868
869static const struct regmap_config rt5514_i2c_regmap = {
870 .name = "i2c",
871 .reg_bits = 32,
872 .val_bits = 32,
873
874 .max_register = RT5514_DSP_MAPPING | RT5514_VENDOR_ID2,
875 .readable_reg = rt5514_i2c_readable_register,
876
877 .cache_type = REGCACHE_NONE,
878};
879
880static const struct regmap_config rt5514_regmap = {
881 .reg_bits = 16,
882 .val_bits = 32,
883
884 .max_register = RT5514_VENDOR_ID2,
885 .volatile_reg = rt5514_volatile_register,
886 .readable_reg = rt5514_readable_register,
887 .reg_read = rt5514_i2c_read,
888 .reg_write = rt5514_i2c_write,
889
890 .cache_type = REGCACHE_RBTREE,
891 .reg_defaults = rt5514_reg,
892 .num_reg_defaults = ARRAY_SIZE(rt5514_reg),
893 .use_single_rw = true,
894};
895
896static const struct i2c_device_id rt5514_i2c_id[] = {
897 { "rt5514", 0 },
898 { }
899};
900MODULE_DEVICE_TABLE(i2c, rt5514_i2c_id);
901
902#if defined(CONFIG_OF)
903static const struct of_device_id rt5514_of_match[] = {
904 { .compatible = "realtek,rt5514", },
905 {},
906};
907MODULE_DEVICE_TABLE(of, rt5514_of_match);
908#endif
909
910static int rt5514_i2c_probe(struct i2c_client *i2c,
911 const struct i2c_device_id *id)
912{
913 struct rt5514_priv *rt5514;
914 int ret;
915 unsigned int val;
916
917 rt5514 = devm_kzalloc(&i2c->dev, sizeof(struct rt5514_priv),
918 GFP_KERNEL);
919 if (rt5514 == NULL)
920 return -ENOMEM;
921
922 i2c_set_clientdata(i2c, rt5514);
923
924 rt5514->i2c_regmap = devm_regmap_init_i2c(i2c, &rt5514_i2c_regmap);
925 if (IS_ERR(rt5514->i2c_regmap)) {
926 ret = PTR_ERR(rt5514->i2c_regmap);
927 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
928 ret);
929 return ret;
930 }
931
932 rt5514->regmap = devm_regmap_init(&i2c->dev, NULL, i2c, &rt5514_regmap);
933 if (IS_ERR(rt5514->regmap)) {
934 ret = PTR_ERR(rt5514->regmap);
935 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
936 ret);
937 return ret;
938 }
939
940 regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val);
941 if (val != RT5514_DEVICE_ID) {
942 dev_err(&i2c->dev,
943 "Device with ID register %x is not rt5514\n", val);
944 return -ENODEV;
945 }
946
947 ret = regmap_register_patch(rt5514->i2c_regmap, rt5514_i2c_patch,
948 ARRAY_SIZE(rt5514_i2c_patch));
949 if (ret != 0)
950 dev_warn(&i2c->dev, "Failed to apply i2c_regmap patch: %d\n",
951 ret);
952
953 ret = regmap_register_patch(rt5514->regmap, rt5514_patch,
954 ARRAY_SIZE(rt5514_patch));
955 if (ret != 0)
956 dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
957
958 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5514,
959 rt5514_dai, ARRAY_SIZE(rt5514_dai));
960}
961
962static int rt5514_i2c_remove(struct i2c_client *i2c)
963{
964 snd_soc_unregister_codec(&i2c->dev);
965
966 return 0;
967}
968
969struct i2c_driver rt5514_i2c_driver = {
970 .driver = {
971 .name = "rt5514",
972 .of_match_table = of_match_ptr(rt5514_of_match),
973 },
974 .probe = rt5514_i2c_probe,
975 .remove = rt5514_i2c_remove,
976 .id_table = rt5514_i2c_id,
977};
978module_i2c_driver(rt5514_i2c_driver);
979
980MODULE_DESCRIPTION("ASoC RT5514 driver");
981MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
982MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/rt5514.h b/sound/soc/codecs/rt5514.h
new file mode 100644
index 000000000000..6ad8a612f659
--- /dev/null
+++ b/sound/soc/codecs/rt5514.h
@@ -0,0 +1,252 @@
1/*
2 * rt5514.h -- RT5514 ALSA SoC audio driver
3 *
4 * Copyright 2015 Realtek Microelectronics
5 * Author: Oder Chiou <oder_chiou@realtek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __RT5514_H__
13#define __RT5514_H__
14
15#define RT5514_DEVICE_ID 0x10ec5514
16
17#define RT5514_RESET 0x2000
18#define RT5514_PWR_ANA1 0x2004
19#define RT5514_PWR_ANA2 0x2008
20#define RT5514_I2S_CTRL1 0x2010
21#define RT5514_I2S_CTRL2 0x2014
22#define RT5514_VAD_CTRL6 0x2030
23#define RT5514_EXT_VAD_CTRL 0x206c
24#define RT5514_DIG_IO_CTRL 0x2070
25#define RT5514_PAD_CTRL1 0x2080
26#define RT5514_DMIC_DATA_CTRL 0x20a0
27#define RT5514_DIG_SOURCE_CTRL 0x20a4
28#define RT5514_SRC_CTRL 0x20ac
29#define RT5514_DOWNFILTER2_CTRL1 0x20d0
30#define RT5514_PLL_SOURCE_CTRL 0x2100
31#define RT5514_CLK_CTRL1 0x2104
32#define RT5514_CLK_CTRL2 0x2108
33#define RT5514_PLL3_CALIB_CTRL1 0x2110
34#define RT5514_PLL3_CALIB_CTRL5 0x2124
35#define RT5514_DELAY_BUF_CTRL1 0x2140
36#define RT5514_DELAY_BUF_CTRL3 0x2148
37#define RT5514_DOWNFILTER0_CTRL1 0x2190
38#define RT5514_DOWNFILTER0_CTRL2 0x2194
39#define RT5514_DOWNFILTER0_CTRL3 0x2198
40#define RT5514_DOWNFILTER1_CTRL1 0x21a0
41#define RT5514_DOWNFILTER1_CTRL2 0x21a4
42#define RT5514_DOWNFILTER1_CTRL3 0x21a8
43#define RT5514_ANA_CTRL_LDO10 0x2200
44#define RT5514_ANA_CTRL_LDO18_16 0x2204
45#define RT5514_ANA_CTRL_ADC12 0x2210
46#define RT5514_ANA_CTRL_ADC21 0x2214
47#define RT5514_ANA_CTRL_ADC22 0x2218
48#define RT5514_ANA_CTRL_ADC23 0x221c
49#define RT5514_ANA_CTRL_MICBST 0x2220
50#define RT5514_ANA_CTRL_ADCFED 0x2224
51#define RT5514_ANA_CTRL_INBUF 0x2228
52#define RT5514_ANA_CTRL_VREF 0x222c
53#define RT5514_ANA_CTRL_PLL3 0x2240
54#define RT5514_ANA_CTRL_PLL1_1 0x2260
55#define RT5514_ANA_CTRL_PLL1_2 0x2264
56#define RT5514_DMIC_LP_CTRL 0x2e00
57#define RT5514_MISC_CTRL_DSP 0x2e04
58#define RT5514_DSP_CTRL1 0x2f00
59#define RT5514_DSP_CTRL3 0x2f08
60#define RT5514_DSP_CTRL4 0x2f10
61#define RT5514_VENDOR_ID1 0x2ff0
62#define RT5514_VENDOR_ID2 0x2ff4
63
64#define RT5514_DSP_MAPPING 0x18000000
65
66/* RT5514_PWR_ANA1 (0x2004) */
67#define RT5514_POW_LDO18_IN (0x1 << 5)
68#define RT5514_POW_LDO18_IN_BIT 5
69#define RT5514_POW_LDO18_ADC (0x1 << 4)
70#define RT5514_POW_LDO18_ADC_BIT 4
71#define RT5514_POW_LDO21 (0x1 << 3)
72#define RT5514_POW_LDO21_BIT 3
73#define RT5514_POW_BG_LDO18_IN (0x1 << 2)
74#define RT5514_POW_BG_LDO18_IN_BIT 2
75#define RT5514_POW_BG_LDO21 (0x1 << 1)
76#define RT5514_POW_BG_LDO21_BIT 1
77
78/* RT5514_PWR_ANA2 (0x2008) */
79#define RT5514_POW_PLL1 (0x1 << 18)
80#define RT5514_POW_PLL1_BIT 18
81#define RT5514_POW_PLL1_LDO (0x1 << 16)
82#define RT5514_POW_PLL1_LDO_BIT 16
83#define RT5514_POW_BG_MBIAS (0x1 << 15)
84#define RT5514_POW_BG_MBIAS_BIT 15
85#define RT5514_POW_MBIAS (0x1 << 14)
86#define RT5514_POW_MBIAS_BIT 14
87#define RT5514_POW_VREF2 (0x1 << 13)
88#define RT5514_POW_VREF2_BIT 13
89#define RT5514_POW_VREF1 (0x1 << 12)
90#define RT5514_POW_VREF1_BIT 12
91#define RT5514_POWR_LDO16 (0x1 << 11)
92#define RT5514_POWR_LDO16_BIT 11
93#define RT5514_POWL_LDO16 (0x1 << 10)
94#define RT5514_POWL_LDO16_BIT 10
95#define RT5514_POW_ADC2 (0x1 << 9)
96#define RT5514_POW_ADC2_BIT 9
97#define RT5514_POW_INPUT_BUF (0x1 << 8)
98#define RT5514_POW_INPUT_BUF_BIT 8
99#define RT5514_POW_ADC1_R (0x1 << 7)
100#define RT5514_POW_ADC1_R_BIT 7
101#define RT5514_POW_ADC1_L (0x1 << 6)
102#define RT5514_POW_ADC1_L_BIT 6
103#define RT5514_POW2_BSTR (0x1 << 5)
104#define RT5514_POW2_BSTR_BIT 5
105#define RT5514_POW2_BSTL (0x1 << 4)
106#define RT5514_POW2_BSTL_BIT 4
107#define RT5514_POW_BSTR (0x1 << 3)
108#define RT5514_POW_BSTR_BIT 3
109#define RT5514_POW_BSTL (0x1 << 2)
110#define RT5514_POW_BSTL_BIT 2
111#define RT5514_POW_ADCFEDR (0x1 << 1)
112#define RT5514_POW_ADCFEDR_BIT 1
113#define RT5514_POW_ADCFEDL (0x1 << 0)
114#define RT5514_POW_ADCFEDL_BIT 0
115
116/* RT5514_I2S_CTRL1 (0x2010) */
117#define RT5514_TDM_MODE (0x1 << 28)
118#define RT5514_TDM_MODE_SFT 28
119#define RT5514_I2S_LR_MASK (0x1 << 26)
120#define RT5514_I2S_LR_SFT 26
121#define RT5514_I2S_LR_NOR (0x0 << 26)
122#define RT5514_I2S_LR_INV (0x1 << 26)
123#define RT5514_I2S_BP_MASK (0x1 << 25)
124#define RT5514_I2S_BP_SFT 25
125#define RT5514_I2S_BP_NOR (0x0 << 25)
126#define RT5514_I2S_BP_INV (0x1 << 25)
127#define RT5514_I2S_DF_MASK (0x7 << 16)
128#define RT5514_I2S_DF_SFT 16
129#define RT5514_I2S_DF_I2S (0x0 << 16)
130#define RT5514_I2S_DF_LEFT (0x1 << 16)
131#define RT5514_I2S_DF_PCM_A (0x2 << 16)
132#define RT5514_I2S_DF_PCM_B (0x3 << 16)
133#define RT5514_TDMSLOT_SEL_RX_MASK (0x3 << 10)
134#define RT5514_TDMSLOT_SEL_RX_SFT 10
135#define RT5514_TDMSLOT_SEL_RX_4CH (0x1 << 10)
136#define RT5514_CH_LEN_RX_MASK (0x3 << 8)
137#define RT5514_CH_LEN_RX_SFT 8
138#define RT5514_CH_LEN_RX_16 (0x0 << 8)
139#define RT5514_CH_LEN_RX_20 (0x1 << 8)
140#define RT5514_CH_LEN_RX_24 (0x2 << 8)
141#define RT5514_CH_LEN_RX_32 (0x3 << 8)
142#define RT5514_TDMSLOT_SEL_TX_MASK (0x3 << 6)
143#define RT5514_TDMSLOT_SEL_TX_SFT 6
144#define RT5514_TDMSLOT_SEL_TX_4CH (0x1 << 6)
145#define RT5514_CH_LEN_TX_MASK (0x3 << 4)
146#define RT5514_CH_LEN_TX_SFT 4
147#define RT5514_CH_LEN_TX_16 (0x0 << 4)
148#define RT5514_CH_LEN_TX_20 (0x1 << 4)
149#define RT5514_CH_LEN_TX_24 (0x2 << 4)
150#define RT5514_CH_LEN_TX_32 (0x3 << 4)
151#define RT5514_I2S_DL_MASK (0x3 << 0)
152#define RT5514_I2S_DL_SFT 0
153#define RT5514_I2S_DL_16 (0x0 << 0)
154#define RT5514_I2S_DL_20 (0x1 << 0)
155#define RT5514_I2S_DL_24 (0x2 << 0)
156#define RT5514_I2S_DL_8 (0x3 << 0)
157
158/* RT5514_DIG_SOURCE_CTRL (0x20a4) */
159#define RT5514_AD1_DMIC_INPUT_SEL (0x1 << 1)
160#define RT5514_AD1_DMIC_INPUT_SEL_SFT 1
161#define RT5514_AD0_DMIC_INPUT_SEL (0x1 << 0)
162#define RT5514_AD0_DMIC_INPUT_SEL_SFT 0
163
164/* RT5514_PLL_SOURCE_CTRL (0x2100) */
165#define RT5514_PLL_1_SEL_MASK (0x7 << 12)
166#define RT5514_PLL_1_SEL_SFT 12
167#define RT5514_PLL_1_SEL_SCLK (0x3 << 12)
168#define RT5514_PLL_1_SEL_MCLK (0x4 << 12)
169
170/* RT5514_CLK_CTRL1 (0x2104) */
171#define RT5514_CLK_AD_ANA1_EN (0x1 << 31)
172#define RT5514_CLK_AD_ANA1_EN_BIT 31
173#define RT5514_CLK_AD1_EN (0x1 << 24)
174#define RT5514_CLK_AD1_EN_BIT 24
175#define RT5514_CLK_AD0_EN (0x1 << 23)
176#define RT5514_CLK_AD0_EN_BIT 23
177#define RT5514_CLK_DMIC_OUT_SEL_MASK (0x7 << 8)
178#define RT5514_CLK_DMIC_OUT_SEL_SFT 8
179
180/* RT5514_CLK_CTRL2 (0x2108) */
181#define RT5514_CLK_SYS_DIV_OUT_MASK (0x7 << 8)
182#define RT5514_CLK_SYS_DIV_OUT_SFT 8
183#define RT5514_SEL_ADC_OSR_MASK (0x7 << 4)
184#define RT5514_SEL_ADC_OSR_SFT 4
185#define RT5514_CLK_SYS_PRE_SEL_MASK (0x3 << 0)
186#define RT5514_CLK_SYS_PRE_SEL_SFT 0
187#define RT5514_CLK_SYS_PRE_SEL_MCLK (0x2 << 0)
188#define RT5514_CLK_SYS_PRE_SEL_PLL (0x3 << 0)
189
190/* RT5514_DOWNFILTER_CTRL (0x2190 0x2194 0x21a0 0x21a4) */
191#define RT5514_AD_DMIC_MIX (0x1 << 11)
192#define RT5514_AD_DMIC_MIX_BIT 11
193#define RT5514_AD_AD_MIX (0x1 << 10)
194#define RT5514_AD_AD_MIX_BIT 10
195#define RT5514_AD_AD_MUTE (0x1 << 7)
196#define RT5514_AD_AD_MUTE_BIT 7
197#define RT5514_AD_GAIN_MASK (0x7f << 0)
198#define RT5514_AD_GAIN_SFT 0
199
200/* RT5514_ANA_CTRL_MICBST (0x2220) */
201#define RT5514_SEL_BSTL_MASK (0xf << 4)
202#define RT5514_SEL_BSTL_SFT 4
203#define RT5514_SEL_BSTR_MASK (0xf << 0)
204#define RT5514_SEL_BSTR_SFT 0
205
206/* RT5514_ANA_CTRL_PLL1_1 (0x2260) */
207#define RT5514_PLL_K_MAX 0x1f
208#define RT5514_PLL_K_MASK (RT5514_PLL_K_MAX << 16)
209#define RT5514_PLL_K_SFT 16
210#define RT5514_PLL_N_MAX 0x1ff
211#define RT5514_PLL_N_MASK (RT5514_PLL_N_MAX << 7)
212#define RT5514_PLL_N_SFT 4
213#define RT5514_PLL_M_MAX 0xf
214#define RT5514_PLL_M_MASK (RT5514_PLL_M_MAX << 0)
215#define RT5514_PLL_M_SFT 0
216
217/* RT5514_ANA_CTRL_PLL1_2 (0x2264) */
218#define RT5514_PLL_M_BP (0x1 << 2)
219#define RT5514_PLL_M_BP_SFT 2
220#define RT5514_PLL_K_BP (0x1 << 1)
221#define RT5514_PLL_K_BP_SFT 1
222#define RT5514_EN_LDO_PLL1 (0x1 << 0)
223#define RT5514_EN_LDO_PLL1_BIT 0
224
225#define RT5514_PLL_INP_MAX 40000000
226#define RT5514_PLL_INP_MIN 256000
227
228/* System Clock Source */
229enum {
230 RT5514_SCLK_S_MCLK,
231 RT5514_SCLK_S_PLL1,
232};
233
234/* PLL1 Source */
235enum {
236 RT5514_PLL1_S_MCLK,
237 RT5514_PLL1_S_BCLK,
238};
239
240struct rt5514_priv {
241 struct snd_soc_codec *codec;
242 struct regmap *i2c_regmap, *regmap;
243 int sysclk;
244 int sysclk_src;
245 int lrck;
246 int bclk;
247 int pll_src;
248 int pll_in;
249 int pll_out;
250};
251
252#endif /* __RT5514_H__ */