blob: 03dea20936398d41e1de0f8f1bb0590c0af24802 [file] [log] [blame]
Meng Wang43bbb872018-12-10 12:32:05 +08001// SPDX-License-Identifier: GPL-2.0-only
Vatsal Buchac2d6c222018-11-30 18:46:37 +05302/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303 */
4
5#include <linux/module.h>
6#include <linux/init.h>
7#include <linux/io.h>
8#include <linux/platform_device.h>
9#include <linux/clk.h>
Sudheer Papothi7601cc62019-03-30 03:00:52 +053010#include <linux/pm_runtime.h>
Laxminath Kasama7ecc582018-06-15 16:55:02 +053011#include <sound/soc.h>
12#include <sound/pcm.h>
13#include <sound/pcm_params.h>
14#include <sound/soc-dapm.h>
15#include <sound/tlv.h>
Sudheer Papothia3e969d2018-10-27 06:22:10 +053016#include <soc/swr-common.h>
Laxminath Kasama7ecc582018-06-15 16:55:02 +053017#include <soc/swr-wcd.h>
18
Meng Wang11a25cf2018-10-31 14:11:26 +080019#include <asoc/msm-cdc-pinctrl.h>
Laxminath Kasama7ecc582018-06-15 16:55:02 +053020#include "bolero-cdc.h"
21#include "bolero-cdc-registers.h"
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -070022#include "bolero-clk-rsc.h"
Laxminath Kasama7ecc582018-06-15 16:55:02 +053023
Sudheer Papothi7601cc62019-03-30 03:00:52 +053024#define AUTO_SUSPEND_DELAY 50 /* delay in msec */
Laxminath Kasama7ecc582018-06-15 16:55:02 +053025#define RX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
26 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
27 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\
28 SNDRV_PCM_RATE_384000)
29/* Fractional Rates */
30#define RX_MACRO_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
31 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800)
32
33#define RX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
34 SNDRV_PCM_FMTBIT_S24_LE |\
35 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
36
37#define RX_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
38 SNDRV_PCM_RATE_48000)
39#define RX_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
40 SNDRV_PCM_FMTBIT_S24_LE |\
41 SNDRV_PCM_FMTBIT_S24_3LE)
42
Laxminath Kasamac396d52018-09-06 12:53:26 +053043#define SAMPLING_RATE_44P1KHZ 44100
44#define SAMPLING_RATE_88P2KHZ 88200
45#define SAMPLING_RATE_176P4KHZ 176400
46#define SAMPLING_RATE_352P8KHZ 352800
47
Laxminath Kasama7ecc582018-06-15 16:55:02 +053048#define RX_MACRO_MAX_OFFSET 0x1000
49
50#define RX_MACRO_MAX_DMA_CH_PER_PORT 2
51#define RX_SWR_STRING_LEN 80
52#define RX_MACRO_CHILD_DEVICES_MAX 3
53
54#define RX_MACRO_INTERP_MUX_NUM_INPUTS 3
55#define RX_MACRO_SIDETONE_IIR_COEFF_MAX 5
56
57#define STRING(name) #name
58#define RX_MACRO_DAPM_ENUM(name, reg, offset, text) \
59static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
60static const struct snd_kcontrol_new name##_mux = \
61 SOC_DAPM_ENUM(STRING(name), name##_enum)
62
63#define RX_MACRO_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \
64static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
65static const struct snd_kcontrol_new name##_mux = \
66 SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname)
67
68#define RX_MACRO_DAPM_MUX(name, shift, kctl) \
69 SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux)
70
71#define RX_MACRO_RX_PATH_OFFSET 0x80
72#define RX_MACRO_COMP_OFFSET 0x40
73
Laxminath Kasam497a6512018-09-17 16:11:52 +053074#define MAX_IMPED_PARAMS 6
75
Vatsal Buchac2d6c222018-11-30 18:46:37 +053076#define RX_MACRO_EC_MIX_TX0_MASK 0xf0
77#define RX_MACRO_EC_MIX_TX1_MASK 0x0f
78#define RX_MACRO_EC_MIX_TX2_MASK 0x0f
79
Laxminath Kasam497a6512018-09-17 16:11:52 +053080struct wcd_imped_val {
81 u32 imped_val;
82 u8 index;
83};
84
85static const struct wcd_imped_val imped_index[] = {
86 {4, 0},
87 {5, 1},
88 {6, 2},
89 {7, 3},
90 {8, 4},
91 {9, 5},
92 {10, 6},
93 {11, 7},
94 {12, 8},
95 {13, 9},
96};
97
98struct rx_macro_reg_mask_val {
99 u16 reg;
100 u8 mask;
101 u8 val;
102};
103
104static const struct rx_macro_reg_mask_val imped_table[][MAX_IMPED_PARAMS] = {
105 {
106 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf2},
107 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf2},
108 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
109 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf2},
110 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf2},
111 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
112 },
113 {
114 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf4},
115 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf4},
116 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
117 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf4},
118 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf4},
119 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
120 },
121 {
122 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf7},
123 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf7},
124 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x01},
125 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf7},
126 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf7},
127 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x01},
128 },
129 {
130 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf9},
131 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf9},
132 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
133 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf9},
134 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf9},
135 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
136 },
137 {
138 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfa},
139 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfa},
140 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
141 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfa},
142 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfa},
143 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
144 },
145 {
146 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfb},
147 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfb},
148 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
149 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfb},
150 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfb},
151 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
152 },
153 {
154 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfc},
155 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfc},
156 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
157 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfc},
158 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfc},
159 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
160 },
161 {
162 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfd},
163 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfd},
164 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
165 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfd},
166 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
167 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
168 },
169 {
170 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfd},
171 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfd},
172 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x01},
173 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfd},
174 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
175 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x01},
176 },
177};
178
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530179enum {
180 INTERP_HPHL,
181 INTERP_HPHR,
182 INTERP_AUX,
183 INTERP_MAX
184};
185
186enum {
187 RX_MACRO_RX0,
188 RX_MACRO_RX1,
189 RX_MACRO_RX2,
190 RX_MACRO_RX3,
191 RX_MACRO_RX4,
192 RX_MACRO_RX5,
193 RX_MACRO_PORTS_MAX
194};
195
196enum {
197 RX_MACRO_COMP1, /* HPH_L */
198 RX_MACRO_COMP2, /* HPH_R */
199 RX_MACRO_COMP_MAX
200};
201
202enum {
Vatsal Buchac2d6c222018-11-30 18:46:37 +0530203 RX_MACRO_EC0_MUX = 0,
204 RX_MACRO_EC1_MUX,
205 RX_MACRO_EC2_MUX,
206 RX_MACRO_EC_MUX_MAX,
207};
208
209enum {
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530210 INTn_1_INP_SEL_ZERO = 0,
211 INTn_1_INP_SEL_DEC0,
212 INTn_1_INP_SEL_DEC1,
213 INTn_1_INP_SEL_IIR0,
214 INTn_1_INP_SEL_IIR1,
215 INTn_1_INP_SEL_RX0,
216 INTn_1_INP_SEL_RX1,
217 INTn_1_INP_SEL_RX2,
218 INTn_1_INP_SEL_RX3,
219 INTn_1_INP_SEL_RX4,
220 INTn_1_INP_SEL_RX5,
221};
222
223enum {
224 INTn_2_INP_SEL_ZERO = 0,
225 INTn_2_INP_SEL_RX0,
226 INTn_2_INP_SEL_RX1,
227 INTn_2_INP_SEL_RX2,
228 INTn_2_INP_SEL_RX3,
229 INTn_2_INP_SEL_RX4,
230 INTn_2_INP_SEL_RX5,
231};
232
233enum {
234 INTERP_MAIN_PATH,
235 INTERP_MIX_PATH,
236};
237
238/* Codec supports 2 IIR filters */
239enum {
240 IIR0 = 0,
241 IIR1,
242 IIR_MAX,
243};
244
245/* Each IIR has 5 Filter Stages */
246enum {
247 BAND1 = 0,
248 BAND2,
249 BAND3,
250 BAND4,
251 BAND5,
252 BAND_MAX,
253};
254
255struct rx_macro_idle_detect_config {
256 u8 hph_idle_thr;
257 u8 hph_idle_detect_en;
258};
259
260struct interp_sample_rate {
261 int sample_rate;
262 int rate_val;
263};
264
265static struct interp_sample_rate sr_val_tbl[] = {
266 {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5},
267 {192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA},
268 {176400, 0xB}, {352800, 0xC},
269};
270
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530271struct rx_macro_bcl_pmic_params {
272 u8 id;
273 u8 sid;
274 u8 ppid;
275};
276
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530277static int rx_macro_hw_params(struct snd_pcm_substream *substream,
278 struct snd_pcm_hw_params *params,
279 struct snd_soc_dai *dai);
280static int rx_macro_get_channel_map(struct snd_soc_dai *dai,
281 unsigned int *tx_num, unsigned int *tx_slot,
282 unsigned int *rx_num, unsigned int *rx_slot);
283static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
284 struct snd_ctl_elem_value *ucontrol);
285static int rx_macro_mux_get(struct snd_kcontrol *kcontrol,
286 struct snd_ctl_elem_value *ucontrol);
287static int rx_macro_mux_put(struct snd_kcontrol *kcontrol,
288 struct snd_ctl_elem_value *ucontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800289static int rx_macro_enable_interp_clk(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530290 int event, int interp_idx);
291
292/* Hold instance to soundwire platform device */
293struct rx_swr_ctrl_data {
294 struct platform_device *rx_swr_pdev;
295};
296
297struct rx_swr_ctrl_platform_data {
298 void *handle; /* holds codec private data */
299 int (*read)(void *handle, int reg);
300 int (*write)(void *handle, int reg, int val);
301 int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
302 int (*clk)(void *handle, bool enable);
303 int (*handle_irq)(void *handle,
304 irqreturn_t (*swrm_irq_handler)(int irq,
305 void *data),
306 void *swrm_handle,
307 int action);
308};
309
310enum {
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +0530311 RX_MACRO_AIF_INVALID = 0,
312 RX_MACRO_AIF1_PB,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530313 RX_MACRO_AIF2_PB,
314 RX_MACRO_AIF3_PB,
315 RX_MACRO_AIF4_PB,
Vatsal Buchac2d6c222018-11-30 18:46:37 +0530316 RX_MACRO_AIF_ECHO,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530317 RX_MACRO_MAX_DAIS,
318};
319
320enum {
321 RX_MACRO_AIF1_CAP = 0,
322 RX_MACRO_AIF2_CAP,
323 RX_MACRO_AIF3_CAP,
324 RX_MACRO_MAX_AIF_CAP_DAIS
325};
326/*
327 * @dev: rx macro device pointer
328 * @comp_enabled: compander enable mixer value set
329 * @prim_int_users: Users of interpolator
330 * @rx_mclk_users: RX MCLK users count
331 * @vi_feed_value: VI sense mask
332 * @swr_clk_lock: to lock swr master clock operations
333 * @swr_ctrl_data: SoundWire data structure
334 * @swr_plat_data: Soundwire platform data
335 * @rx_macro_add_child_devices_work: work for adding child devices
336 * @rx_swr_gpio_p: used by pinctrl API
Meng Wang15c825d2018-09-06 10:49:18 +0800337 * @component: codec handle
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530338 */
339struct rx_macro_priv {
340 struct device *dev;
341 int comp_enabled[RX_MACRO_COMP_MAX];
342 /* Main path clock users count */
343 int main_clk_users[INTERP_MAX];
344 int rx_port_value[RX_MACRO_PORTS_MAX];
345 u16 prim_int_users[INTERP_MAX];
346 int rx_mclk_users;
347 int swr_clk_users;
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530348 bool dapm_mclk_enable;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530349 bool reset_swr;
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +0530350 int clsh_users;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530351 int rx_mclk_cnt;
Laxminath Kasambee08192018-07-01 14:38:55 +0530352 bool is_native_on;
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +0530353 bool is_ear_mode_on;
Laxminath Kasam701e3582018-10-15 20:06:09 +0530354 bool dev_up;
Laxminath Kasamde09dfb2018-11-09 13:00:30 +0530355 bool hph_pwr_mode;
Laxminath Kasamd3ffb332018-11-14 19:59:21 +0530356 bool hph_hd2_mode;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530357 struct mutex mclk_lock;
358 struct mutex swr_clk_lock;
359 struct rx_swr_ctrl_data *swr_ctrl_data;
360 struct rx_swr_ctrl_platform_data swr_plat_data;
361 struct work_struct rx_macro_add_child_devices_work;
362 struct device_node *rx_swr_gpio_p;
Meng Wang15c825d2018-09-06 10:49:18 +0800363 struct snd_soc_component *component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530364 unsigned long active_ch_mask[RX_MACRO_MAX_DAIS];
365 unsigned long active_ch_cnt[RX_MACRO_MAX_DAIS];
366 u16 bit_width[RX_MACRO_MAX_DAIS];
367 char __iomem *rx_io_base;
368 char __iomem *rx_mclk_mode_muxsel;
369 struct rx_macro_idle_detect_config idle_det_cfg;
370 u8 sidetone_coeff_array[IIR_MAX][BAND_MAX]
371 [RX_MACRO_SIDETONE_IIR_COEFF_MAX * 4];
372
373 struct platform_device *pdev_child_devices
374 [RX_MACRO_CHILD_DEVICES_MAX];
375 int child_count;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530376 int is_softclip_on;
377 int softclip_clk_users;
378 struct rx_macro_bcl_pmic_params bcl_pmic_params;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700379 u16 clk_id;
380 u16 default_clk_id;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530381};
382
383static struct snd_soc_dai_driver rx_macro_dai[];
384static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
385
386static const char * const rx_int_mix_mux_text[] = {
387 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5"
388};
389
390static const char * const rx_prim_mix_text[] = {
391 "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2",
392 "RX3", "RX4", "RX5"
393};
394
395static const char * const rx_sidetone_mix_text[] = {
396 "ZERO", "SRC0", "SRC1", "SRC_SUM"
397};
398
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530399static const char * const iir_inp_mux_text[] = {
400 "ZERO", "DEC0", "DEC1", "DEC2", "DEC3",
401 "RX0", "RX1", "RX2", "RX3", "RX4", "RX5"
402};
403
404static const char * const rx_int_dem_inp_mux_text[] = {
405 "NORMAL_DSM_OUT", "CLSH_DSM_OUT",
406};
407
408static const char * const rx_int0_1_interp_mux_text[] = {
409 "ZERO", "RX INT0_1 MIX1",
410};
411
412static const char * const rx_int1_1_interp_mux_text[] = {
413 "ZERO", "RX INT1_1 MIX1",
414};
415
416static const char * const rx_int2_1_interp_mux_text[] = {
417 "ZERO", "RX INT2_1 MIX1",
418};
419
420static const char * const rx_int0_2_interp_mux_text[] = {
421 "ZERO", "RX INT0_2 MUX",
422};
423
424static const char * const rx_int1_2_interp_mux_text[] = {
425 "ZERO", "RX INT1_2 MUX",
426};
427
428static const char * const rx_int2_2_interp_mux_text[] = {
429 "ZERO", "RX INT2_2 MUX",
430};
431
432static const char *const rx_macro_mux_text[] = {
433 "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB"
434};
435
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +0530436static const char *const rx_macro_ear_mode_text[] = {"OFF", "ON"};
437static const struct soc_enum rx_macro_ear_mode_enum =
438 SOC_ENUM_SINGLE_EXT(2, rx_macro_ear_mode_text);
439
Laxminath Kasamd3ffb332018-11-14 19:59:21 +0530440static const char *const rx_macro_hph_hd2_mode_text[] = {"OFF", "ON"};
441static const struct soc_enum rx_macro_hph_hd2_mode_enum =
442 SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_hd2_mode_text);
443
Laxminath Kasamc21e98a2018-12-04 11:21:01 +0530444static const char *const rx_macro_hph_pwr_mode_text[] = {"ULP", "LOHIFI"};
Laxminath Kasamde09dfb2018-11-09 13:00:30 +0530445static const struct soc_enum rx_macro_hph_pwr_mode_enum =
446 SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_pwr_mode_text);
447
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530448static const char * const rx_macro_vbat_bcl_gsm_mode_text[] = {"OFF", "ON"};
449static const struct soc_enum rx_macro_vbat_bcl_gsm_mode_enum =
450 SOC_ENUM_SINGLE_EXT(2, rx_macro_vbat_bcl_gsm_mode_text);
451
452static const struct snd_kcontrol_new rx_int2_1_vbat_mix_switch[] = {
453 SOC_DAPM_SINGLE("RX AUX VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
454};
455
Vatsal Bucha8bcc97c2019-01-07 13:18:11 +0530456static const char * const hph_idle_detect_text[] = {"OFF", "ON"};
457
458static SOC_ENUM_SINGLE_EXT_DECL(hph_idle_detect_enum, hph_idle_detect_text);
459
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530460RX_MACRO_DAPM_ENUM(rx_int0_2, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 0,
461 rx_int_mix_mux_text);
462RX_MACRO_DAPM_ENUM(rx_int1_2, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 0,
463 rx_int_mix_mux_text);
464RX_MACRO_DAPM_ENUM(rx_int2_2, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG1, 0,
465 rx_int_mix_mux_text);
466
467
468RX_MACRO_DAPM_ENUM(rx_int0_1_mix_inp0, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0, 0,
469 rx_prim_mix_text);
470RX_MACRO_DAPM_ENUM(rx_int0_1_mix_inp1, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0, 4,
471 rx_prim_mix_text);
472RX_MACRO_DAPM_ENUM(rx_int0_1_mix_inp2, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 4,
473 rx_prim_mix_text);
474RX_MACRO_DAPM_ENUM(rx_int1_1_mix_inp0, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0, 0,
475 rx_prim_mix_text);
476RX_MACRO_DAPM_ENUM(rx_int1_1_mix_inp1, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0, 4,
477 rx_prim_mix_text);
478RX_MACRO_DAPM_ENUM(rx_int1_1_mix_inp2, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 4,
479 rx_prim_mix_text);
480RX_MACRO_DAPM_ENUM(rx_int2_1_mix_inp0, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG0, 0,
481 rx_prim_mix_text);
482RX_MACRO_DAPM_ENUM(rx_int2_1_mix_inp1, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG0, 4,
483 rx_prim_mix_text);
484RX_MACRO_DAPM_ENUM(rx_int2_1_mix_inp2, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG1, 4,
485 rx_prim_mix_text);
486
487RX_MACRO_DAPM_ENUM(rx_int0_mix2_inp, BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2,
488 rx_sidetone_mix_text);
489RX_MACRO_DAPM_ENUM(rx_int1_mix2_inp, BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4,
490 rx_sidetone_mix_text);
491RX_MACRO_DAPM_ENUM(rx_int2_mix2_inp, BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6,
492 rx_sidetone_mix_text);
493
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530494RX_MACRO_DAPM_ENUM(iir0_inp0, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0, 0,
495 iir_inp_mux_text);
496RX_MACRO_DAPM_ENUM(iir0_inp1, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1, 0,
497 iir_inp_mux_text);
498RX_MACRO_DAPM_ENUM(iir0_inp2, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2, 0,
499 iir_inp_mux_text);
500RX_MACRO_DAPM_ENUM(iir0_inp3, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3, 0,
501 iir_inp_mux_text);
502RX_MACRO_DAPM_ENUM(iir1_inp0, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0, 0,
503 iir_inp_mux_text);
504RX_MACRO_DAPM_ENUM(iir1_inp1, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1, 0,
505 iir_inp_mux_text);
506RX_MACRO_DAPM_ENUM(iir1_inp2, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2, 0,
507 iir_inp_mux_text);
508RX_MACRO_DAPM_ENUM(iir1_inp3, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3, 0,
509 iir_inp_mux_text);
510
511RX_MACRO_DAPM_ENUM(rx_int0_1_interp, SND_SOC_NOPM, 0,
512 rx_int0_1_interp_mux_text);
513RX_MACRO_DAPM_ENUM(rx_int1_1_interp, SND_SOC_NOPM, 0,
514 rx_int1_1_interp_mux_text);
515RX_MACRO_DAPM_ENUM(rx_int2_1_interp, SND_SOC_NOPM, 0,
516 rx_int2_1_interp_mux_text);
517
518RX_MACRO_DAPM_ENUM(rx_int0_2_interp, SND_SOC_NOPM, 0,
519 rx_int0_2_interp_mux_text);
520RX_MACRO_DAPM_ENUM(rx_int1_2_interp, SND_SOC_NOPM, 0,
521 rx_int1_2_interp_mux_text);
522RX_MACRO_DAPM_ENUM(rx_int2_2_interp, SND_SOC_NOPM, 0,
523 rx_int2_2_interp_mux_text);
524
525RX_MACRO_DAPM_ENUM_EXT(rx_int0_dem_inp, BOLERO_CDC_RX_RX0_RX_PATH_CFG1, 0,
526 rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double,
527 rx_macro_int_dem_inp_mux_put);
528RX_MACRO_DAPM_ENUM_EXT(rx_int1_dem_inp, BOLERO_CDC_RX_RX1_RX_PATH_CFG1, 0,
529 rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double,
530 rx_macro_int_dem_inp_mux_put);
531
532RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx0, SND_SOC_NOPM, 0, rx_macro_mux_text,
533 rx_macro_mux_get, rx_macro_mux_put);
534RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx1, SND_SOC_NOPM, 0, rx_macro_mux_text,
535 rx_macro_mux_get, rx_macro_mux_put);
536RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx2, SND_SOC_NOPM, 0, rx_macro_mux_text,
537 rx_macro_mux_get, rx_macro_mux_put);
538RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx3, SND_SOC_NOPM, 0, rx_macro_mux_text,
539 rx_macro_mux_get, rx_macro_mux_put);
540RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx4, SND_SOC_NOPM, 0, rx_macro_mux_text,
541 rx_macro_mux_get, rx_macro_mux_put);
542RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx5, SND_SOC_NOPM, 0, rx_macro_mux_text,
543 rx_macro_mux_get, rx_macro_mux_put);
544
Vatsal Buchac2d6c222018-11-30 18:46:37 +0530545static const char * const rx_echo_mux_text[] = {
546 "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2"
547};
548
549static const struct soc_enum rx_mix_tx2_mux_enum =
550 SOC_ENUM_SINGLE(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5, 0, 4,
551 rx_echo_mux_text);
552
553static const struct snd_kcontrol_new rx_mix_tx2_mux =
554 SOC_DAPM_ENUM("RX MIX TX2_MUX Mux", rx_mix_tx2_mux_enum);
555
556static const struct soc_enum rx_mix_tx1_mux_enum =
557 SOC_ENUM_SINGLE(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, 4,
558 rx_echo_mux_text);
559
560static const struct snd_kcontrol_new rx_mix_tx1_mux =
561 SOC_DAPM_ENUM("RX MIX TX1_MUX Mux", rx_mix_tx1_mux_enum);
562
563static const struct soc_enum rx_mix_tx0_mux_enum =
564 SOC_ENUM_SINGLE(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 4, 4,
565 rx_echo_mux_text);
566
567static const struct snd_kcontrol_new rx_mix_tx0_mux =
568 SOC_DAPM_ENUM("RX MIX TX0_MUX Mux", rx_mix_tx0_mux_enum);
569
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530570static struct snd_soc_dai_ops rx_macro_dai_ops = {
571 .hw_params = rx_macro_hw_params,
572 .get_channel_map = rx_macro_get_channel_map,
573};
574
575static struct snd_soc_dai_driver rx_macro_dai[] = {
576 {
577 .name = "rx_macro_rx1",
578 .id = RX_MACRO_AIF1_PB,
579 .playback = {
580 .stream_name = "RX_MACRO_AIF1 Playback",
581 .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES,
582 .formats = RX_MACRO_FORMATS,
583 .rate_max = 384000,
584 .rate_min = 8000,
585 .channels_min = 1,
586 .channels_max = 2,
587 },
588 .ops = &rx_macro_dai_ops,
589 },
590 {
591 .name = "rx_macro_rx2",
592 .id = RX_MACRO_AIF2_PB,
593 .playback = {
594 .stream_name = "RX_MACRO_AIF2 Playback",
595 .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES,
596 .formats = RX_MACRO_FORMATS,
597 .rate_max = 384000,
598 .rate_min = 8000,
599 .channels_min = 1,
600 .channels_max = 2,
601 },
602 .ops = &rx_macro_dai_ops,
603 },
604 {
605 .name = "rx_macro_rx3",
606 .id = RX_MACRO_AIF3_PB,
607 .playback = {
608 .stream_name = "RX_MACRO_AIF3 Playback",
609 .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES,
610 .formats = RX_MACRO_FORMATS,
611 .rate_max = 384000,
612 .rate_min = 8000,
613 .channels_min = 1,
614 .channels_max = 2,
615 },
616 .ops = &rx_macro_dai_ops,
617 },
618 {
619 .name = "rx_macro_rx4",
620 .id = RX_MACRO_AIF4_PB,
621 .playback = {
622 .stream_name = "RX_MACRO_AIF4 Playback",
623 .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES,
624 .formats = RX_MACRO_FORMATS,
625 .rate_max = 384000,
626 .rate_min = 8000,
627 .channels_min = 1,
628 .channels_max = 2,
629 },
630 .ops = &rx_macro_dai_ops,
631 },
Vatsal Buchac2d6c222018-11-30 18:46:37 +0530632 {
633 .name = "rx_macro_echo",
634 .id = RX_MACRO_AIF_ECHO,
635 .capture = {
636 .stream_name = "RX_AIF_ECHO Capture",
637 .rates = RX_MACRO_ECHO_RATES,
638 .formats = RX_MACRO_ECHO_FORMATS,
639 .rate_max = 48000,
640 .rate_min = 8000,
641 .channels_min = 1,
642 .channels_max = 3,
643 },
644 .ops = &rx_macro_dai_ops,
645 },
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530646};
647
Laxminath Kasam497a6512018-09-17 16:11:52 +0530648static int get_impedance_index(int imped)
649{
650 int i = 0;
651
652 if (imped < imped_index[i].imped_val) {
653 pr_debug("%s, detected impedance is less than %d Ohm\n",
654 __func__, imped_index[i].imped_val);
655 i = 0;
656 goto ret;
657 }
658 if (imped >= imped_index[ARRAY_SIZE(imped_index) - 1].imped_val) {
659 pr_debug("%s, detected impedance is greater than %d Ohm\n",
660 __func__,
661 imped_index[ARRAY_SIZE(imped_index) - 1].imped_val);
662 i = ARRAY_SIZE(imped_index) - 1;
663 goto ret;
664 }
665 for (i = 0; i < ARRAY_SIZE(imped_index) - 1; i++) {
666 if (imped >= imped_index[i].imped_val &&
667 imped < imped_index[i + 1].imped_val)
668 break;
669 }
670ret:
671 pr_debug("%s: selected impedance index = %d\n",
672 __func__, imped_index[i].index);
673 return imped_index[i].index;
674}
675
676/*
677 * rx_macro_wcd_clsh_imped_config -
678 * This function updates HPHL and HPHR gain settings
679 * according to the impedance value.
680 *
Meng Wang15c825d2018-09-06 10:49:18 +0800681 * @component: codec pointer handle
Laxminath Kasam497a6512018-09-17 16:11:52 +0530682 * @imped: impedance value of HPHL/R
683 * @reset: bool variable to reset registers when teardown
684 */
Meng Wang15c825d2018-09-06 10:49:18 +0800685static void rx_macro_wcd_clsh_imped_config(struct snd_soc_component *component,
Laxminath Kasam497a6512018-09-17 16:11:52 +0530686 int imped, bool reset)
687{
688 int i;
689 int index = 0;
690 int table_size;
691
692 static const struct rx_macro_reg_mask_val
693 (*imped_table_ptr)[MAX_IMPED_PARAMS];
694
695 table_size = ARRAY_SIZE(imped_table);
696 imped_table_ptr = imped_table;
697 /* reset = 1, which means request is to reset the register values */
698 if (reset) {
699 for (i = 0; i < MAX_IMPED_PARAMS; i++)
Meng Wang15c825d2018-09-06 10:49:18 +0800700 snd_soc_component_update_bits(component,
Laxminath Kasam497a6512018-09-17 16:11:52 +0530701 imped_table_ptr[index][i].reg,
702 imped_table_ptr[index][i].mask, 0);
703 return;
704 }
705 index = get_impedance_index(imped);
706 if (index >= (ARRAY_SIZE(imped_index) - 1)) {
707 pr_debug("%s, impedance not in range = %d\n", __func__, imped);
708 return;
709 }
710 if (index >= table_size) {
711 pr_debug("%s, impedance index not in range = %d\n", __func__,
712 index);
713 return;
714 }
715 for (i = 0; i < MAX_IMPED_PARAMS; i++)
Meng Wang15c825d2018-09-06 10:49:18 +0800716 snd_soc_component_update_bits(component,
Laxminath Kasam497a6512018-09-17 16:11:52 +0530717 imped_table_ptr[index][i].reg,
718 imped_table_ptr[index][i].mask,
719 imped_table_ptr[index][i].val);
720}
721
Meng Wang15c825d2018-09-06 10:49:18 +0800722static bool rx_macro_get_data(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530723 struct device **rx_dev,
724 struct rx_macro_priv **rx_priv,
725 const char *func_name)
726{
Meng Wang15c825d2018-09-06 10:49:18 +0800727 *rx_dev = bolero_get_device_ptr(component->dev, RX_MACRO);
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530728
729 if (!(*rx_dev)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800730 dev_err(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530731 "%s: null device for macro!\n", func_name);
732 return false;
733 }
734
735 *rx_priv = dev_get_drvdata((*rx_dev));
736 if (!(*rx_priv)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800737 dev_err(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530738 "%s: priv is null for macro!\n", func_name);
739 return false;
740 }
741
Meng Wang15c825d2018-09-06 10:49:18 +0800742 if (!(*rx_priv)->component) {
743 dev_err(component->dev,
Vatsal Buchac2d6c222018-11-30 18:46:37 +0530744 "%s: rx_priv component is not initialized!\n", func_name);
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530745 return false;
746 }
747
748 return true;
749}
750
Sudheer Papothia3e969d2018-10-27 06:22:10 +0530751static int rx_macro_set_port_map(struct snd_soc_component *component,
752 u32 usecase, u32 size, void *data)
753{
754 struct device *rx_dev = NULL;
755 struct rx_macro_priv *rx_priv = NULL;
756 struct swrm_port_config port_cfg;
757 int ret = 0;
758
759 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
760 return -EINVAL;
761
762 memset(&port_cfg, 0, sizeof(port_cfg));
763 port_cfg.uc = usecase;
764 port_cfg.size = size;
765 port_cfg.params = data;
766
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700767 if (rx_priv->swr_ctrl_data)
768 ret = swrm_wcd_notify(
769 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
770 SWR_SET_PORT_MAP, &port_cfg);
Sudheer Papothia3e969d2018-10-27 06:22:10 +0530771
772 return ret;
773}
774
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530775static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
776 struct snd_ctl_elem_value *ucontrol)
777{
778 struct snd_soc_dapm_widget *widget =
779 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800780 struct snd_soc_component *component =
781 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530782 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
783 unsigned int val = 0;
784 unsigned short look_ahead_dly_reg =
785 BOLERO_CDC_RX_RX0_RX_PATH_CFG0;
786
787 val = ucontrol->value.enumerated.item[0];
788 if (val >= e->items)
789 return -EINVAL;
790
Meng Wang15c825d2018-09-06 10:49:18 +0800791 dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530792 widget->name, val);
793
794 if (e->reg == BOLERO_CDC_RX_RX0_RX_PATH_CFG1)
795 look_ahead_dly_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0;
796 else if (e->reg == BOLERO_CDC_RX_RX1_RX_PATH_CFG1)
797 look_ahead_dly_reg = BOLERO_CDC_RX_RX1_RX_PATH_CFG0;
798
799 /* Set Look Ahead Delay */
Meng Wang15c825d2018-09-06 10:49:18 +0800800 snd_soc_component_update_bits(component, look_ahead_dly_reg,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530801 0x08, (val ? 0x08 : 0x00));
802 /* Set DEM INP Select */
803 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
804}
805
806static int rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
807 u8 rate_reg_val,
808 u32 sample_rate)
809{
810 u8 int_1_mix1_inp = 0;
811 u32 j = 0, port = 0;
812 u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
813 u16 int_fs_reg = 0;
814 u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
815 u8 inp0_sel = 0, inp1_sel = 0, inp2_sel = 0;
Meng Wang15c825d2018-09-06 10:49:18 +0800816 struct snd_soc_component *component = dai->component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530817 struct device *rx_dev = NULL;
818 struct rx_macro_priv *rx_priv = NULL;
819
Meng Wang15c825d2018-09-06 10:49:18 +0800820 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530821 return -EINVAL;
822
823 for_each_set_bit(port, &rx_priv->active_ch_mask[dai->id],
824 RX_MACRO_PORTS_MAX) {
825 int_1_mix1_inp = port;
826 if ((int_1_mix1_inp < RX_MACRO_RX0) ||
827 (int_1_mix1_inp > RX_MACRO_PORTS_MAX)) {
828 pr_err("%s: Invalid RX port, Dai ID is %d\n",
829 __func__, dai->id);
830 return -EINVAL;
831 }
832
833 int_mux_cfg0 = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0;
834
835 /*
836 * Loop through all interpolator MUX inputs and find out
837 * to which interpolator input, the rx port
838 * is connected
839 */
840 for (j = 0; j < INTERP_MAX; j++) {
841 int_mux_cfg1 = int_mux_cfg0 + 4;
842
Meng Wang15c825d2018-09-06 10:49:18 +0800843 int_mux_cfg0_val = snd_soc_component_read32(
844 component, int_mux_cfg0);
845 int_mux_cfg1_val = snd_soc_component_read32(
846 component, int_mux_cfg1);
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530847 inp0_sel = int_mux_cfg0_val & 0x07;
848 inp1_sel = (int_mux_cfg0_val >> 4) & 0x038;
849 inp2_sel = (int_mux_cfg1_val >> 4) & 0x038;
850 if ((inp0_sel == int_1_mix1_inp) ||
851 (inp1_sel == int_1_mix1_inp) ||
852 (inp2_sel == int_1_mix1_inp)) {
853 int_fs_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL +
854 0x80 * j;
855 pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_1\n",
856 __func__, dai->id, j);
857 pr_debug("%s: set INT%u_1 sample rate to %u\n",
858 __func__, j, sample_rate);
859 /* sample_rate is in Hz */
Meng Wang15c825d2018-09-06 10:49:18 +0800860 snd_soc_component_update_bits(component,
861 int_fs_reg,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530862 0x0F, rate_reg_val);
863 }
864 int_mux_cfg0 += 8;
865 }
866 }
867
868 return 0;
869}
870
871static int rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
872 u8 rate_reg_val,
873 u32 sample_rate)
874{
875 u8 int_2_inp = 0;
876 u32 j = 0, port = 0;
877 u16 int_mux_cfg1 = 0, int_fs_reg = 0;
878 u8 int_mux_cfg1_val = 0;
Meng Wang15c825d2018-09-06 10:49:18 +0800879 struct snd_soc_component *component = dai->component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530880 struct device *rx_dev = NULL;
881 struct rx_macro_priv *rx_priv = NULL;
882
Meng Wang15c825d2018-09-06 10:49:18 +0800883 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530884 return -EINVAL;
885
886 for_each_set_bit(port, &rx_priv->active_ch_mask[dai->id],
887 RX_MACRO_PORTS_MAX) {
888 int_2_inp = port;
889 if ((int_2_inp < RX_MACRO_RX0) ||
890 (int_2_inp > RX_MACRO_PORTS_MAX)) {
891 pr_err("%s: Invalid RX port, Dai ID is %d\n",
892 __func__, dai->id);
893 return -EINVAL;
894 }
895
896 int_mux_cfg1 = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1;
897 for (j = 0; j < INTERP_MAX; j++) {
Meng Wang15c825d2018-09-06 10:49:18 +0800898 int_mux_cfg1_val = snd_soc_component_read32(
899 component, int_mux_cfg1) &
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530900 0x07;
901 if (int_mux_cfg1_val == int_2_inp) {
902 int_fs_reg = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL +
903 0x80 * j;
904 pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_2\n",
905 __func__, dai->id, j);
906 pr_debug("%s: set INT%u_2 sample rate to %u\n",
907 __func__, j, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +0800908 snd_soc_component_update_bits(
909 component, int_fs_reg,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530910 0x0F, rate_reg_val);
911 }
912 int_mux_cfg1 += 8;
913 }
914 }
915 return 0;
916}
917
Laxminath Kasamac396d52018-09-06 12:53:26 +0530918static bool rx_macro_is_fractional_sample_rate(u32 sample_rate)
919{
920 switch (sample_rate) {
921 case SAMPLING_RATE_44P1KHZ:
922 case SAMPLING_RATE_88P2KHZ:
923 case SAMPLING_RATE_176P4KHZ:
924 case SAMPLING_RATE_352P8KHZ:
925 return true;
926 default:
927 return false;
928 }
929 return false;
930}
931
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530932static int rx_macro_set_interpolator_rate(struct snd_soc_dai *dai,
933 u32 sample_rate)
934{
Meng Wang15c825d2018-09-06 10:49:18 +0800935 struct snd_soc_component *component = dai->component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530936 int rate_val = 0;
937 int i = 0, ret = 0;
Laxminath Kasamac396d52018-09-06 12:53:26 +0530938 struct device *rx_dev = NULL;
939 struct rx_macro_priv *rx_priv = NULL;
940
Meng Wang15c825d2018-09-06 10:49:18 +0800941 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamac396d52018-09-06 12:53:26 +0530942 return -EINVAL;
943
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530944
945 for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) {
946 if (sample_rate == sr_val_tbl[i].sample_rate) {
947 rate_val = sr_val_tbl[i].rate_val;
Laxminath Kasamac396d52018-09-06 12:53:26 +0530948 if (rx_macro_is_fractional_sample_rate(sample_rate))
949 rx_priv->is_native_on = true;
950 else
951 rx_priv->is_native_on = false;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530952 break;
953 }
954 }
955 if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800956 dev_err(component->dev, "%s: Unsupported sample rate: %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530957 __func__, sample_rate);
958 return -EINVAL;
959 }
960
961 ret = rx_macro_set_prim_interpolator_rate(dai, (u8)rate_val, sample_rate);
962 if (ret)
963 return ret;
964 ret = rx_macro_set_mix_interpolator_rate(dai, (u8)rate_val, sample_rate);
965 if (ret)
966 return ret;
967
968 return ret;
969}
970
971static int rx_macro_hw_params(struct snd_pcm_substream *substream,
972 struct snd_pcm_hw_params *params,
973 struct snd_soc_dai *dai)
974{
Meng Wang15c825d2018-09-06 10:49:18 +0800975 struct snd_soc_component *component = dai->component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530976 int ret = 0;
977 struct device *rx_dev = NULL;
978 struct rx_macro_priv *rx_priv = NULL;
979
Meng Wang15c825d2018-09-06 10:49:18 +0800980 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530981 return -EINVAL;
982
Meng Wang15c825d2018-09-06 10:49:18 +0800983 dev_dbg(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530984 "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
985 dai->name, dai->id, params_rate(params),
986 params_channels(params));
987
988 switch (substream->stream) {
989 case SNDRV_PCM_STREAM_PLAYBACK:
990 ret = rx_macro_set_interpolator_rate(dai, params_rate(params));
991 if (ret) {
992 pr_err("%s: cannot set sample rate: %u\n",
993 __func__, params_rate(params));
994 return ret;
995 }
996 rx_priv->bit_width[dai->id] = params_width(params);
997 break;
998 case SNDRV_PCM_STREAM_CAPTURE:
999 default:
1000 break;
1001 }
1002 return 0;
1003}
1004
1005static int rx_macro_get_channel_map(struct snd_soc_dai *dai,
1006 unsigned int *tx_num, unsigned int *tx_slot,
1007 unsigned int *rx_num, unsigned int *rx_slot)
1008{
Meng Wang15c825d2018-09-06 10:49:18 +08001009 struct snd_soc_component *component = dai->component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301010 struct device *rx_dev = NULL;
1011 struct rx_macro_priv *rx_priv = NULL;
1012 unsigned int temp = 0, ch_mask = 0;
Vatsal Buchac2d6c222018-11-30 18:46:37 +05301013 u16 val = 0, mask = 0, cnt = 0, i = 0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301014
Meng Wang15c825d2018-09-06 10:49:18 +08001015 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301016 return -EINVAL;
1017
1018 switch (dai->id) {
1019 case RX_MACRO_AIF1_PB:
1020 case RX_MACRO_AIF2_PB:
1021 case RX_MACRO_AIF3_PB:
1022 case RX_MACRO_AIF4_PB:
1023 for_each_set_bit(temp, &rx_priv->active_ch_mask[dai->id],
1024 RX_MACRO_PORTS_MAX) {
Vatsal Bucha1a96a612018-11-26 13:04:56 +05301025 ch_mask |= (1 << temp);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301026 if (++i == RX_MACRO_MAX_DMA_CH_PER_PORT)
1027 break;
1028 }
1029 *rx_slot = ch_mask;
1030 *rx_num = rx_priv->active_ch_cnt[dai->id];
1031 break;
Vatsal Buchac2d6c222018-11-30 18:46:37 +05301032 case RX_MACRO_AIF_ECHO:
1033 val = snd_soc_component_read32(component,
1034 BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4);
1035 if (val & RX_MACRO_EC_MIX_TX0_MASK) {
1036 mask |= 0x1;
1037 cnt++;
1038 }
1039 if (val & RX_MACRO_EC_MIX_TX1_MASK) {
1040 mask |= 0x2;
1041 cnt++;
1042 }
1043 val = snd_soc_component_read32(component,
1044 BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5);
1045 if (val & RX_MACRO_EC_MIX_TX2_MASK) {
1046 mask |= 0x4;
1047 cnt++;
1048 }
1049 *tx_slot = mask;
1050 *tx_num = cnt;
1051 break;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301052 default:
1053 dev_err(rx_dev, "%s: Invalid AIF\n", __func__);
1054 break;
1055 }
1056 return 0;
1057}
1058
1059static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv,
1060 bool mclk_enable, bool dapm)
1061{
1062 struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001063 int ret = 0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301064
Tanya Dixit8530fb92018-09-14 16:01:25 +05301065 if (regmap == NULL) {
1066 dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__);
1067 return -EINVAL;
1068 }
1069
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301070 dev_dbg(rx_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
1071 __func__, mclk_enable, dapm, rx_priv->rx_mclk_users);
1072
1073 mutex_lock(&rx_priv->mclk_lock);
1074 if (mclk_enable) {
1075 if (rx_priv->rx_mclk_users == 0) {
Laxminath Kasam7b9cdb62018-09-28 16:28:54 +05301076 if (rx_priv->is_native_on)
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001077 rx_priv->clk_id = RX_CORE_CLK;
1078 ret = bolero_clk_rsc_request_clock(rx_priv->dev,
1079 rx_priv->default_clk_id,
1080 rx_priv->clk_id,
1081 true);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301082 if (ret < 0) {
1083 dev_err(rx_priv->dev,
1084 "%s: rx request clock enable failed\n",
1085 __func__);
1086 goto exit;
1087 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001088 bolero_clk_rsc_fs_gen_request(rx_priv->dev,
1089 true);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301090 regcache_mark_dirty(regmap);
1091 regcache_sync_region(regmap,
1092 RX_START_OFFSET,
1093 RX_MAX_OFFSET);
1094 regmap_update_bits(regmap,
1095 BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL,
1096 0x01, 0x01);
1097 regmap_update_bits(regmap,
Ramprasad Katkam9c2394a2018-08-23 13:13:48 +05301098 BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL,
1099 0x02, 0x02);
1100 regmap_update_bits(regmap,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301101 BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
1102 0x01, 0x01);
1103 }
1104 rx_priv->rx_mclk_users++;
1105 } else {
1106 if (rx_priv->rx_mclk_users <= 0) {
1107 dev_err(rx_priv->dev, "%s: clock already disabled\n",
1108 __func__);
1109 rx_priv->rx_mclk_users = 0;
1110 goto exit;
1111 }
1112 rx_priv->rx_mclk_users--;
1113 if (rx_priv->rx_mclk_users == 0) {
1114 regmap_update_bits(regmap,
1115 BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
1116 0x01, 0x00);
1117 regmap_update_bits(regmap,
1118 BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL,
1119 0x01, 0x00);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001120 bolero_clk_rsc_fs_gen_request(rx_priv->dev,
1121 false);
1122 bolero_clk_rsc_request_clock(rx_priv->dev,
1123 rx_priv->default_clk_id,
1124 rx_priv->clk_id,
1125 false);
1126 rx_priv->clk_id = rx_priv->default_clk_id;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301127 }
1128 }
1129exit:
1130 mutex_unlock(&rx_priv->mclk_lock);
1131 return ret;
1132}
1133
1134static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w,
1135 struct snd_kcontrol *kcontrol, int event)
1136{
Meng Wang15c825d2018-09-06 10:49:18 +08001137 struct snd_soc_component *component =
1138 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301139 int ret = 0;
1140 struct device *rx_dev = NULL;
1141 struct rx_macro_priv *rx_priv = NULL;
Laxminath Kasamac396d52018-09-06 12:53:26 +05301142 int mclk_freq = MCLK_FREQ;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301143
Meng Wang15c825d2018-09-06 10:49:18 +08001144 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301145 return -EINVAL;
1146
1147 dev_dbg(rx_dev, "%s: event = %d\n", __func__, event);
1148 switch (event) {
1149 case SND_SOC_DAPM_PRE_PMU:
Laxminath Kasambee08192018-07-01 14:38:55 +05301150 /* if swr_clk_users > 0, call device down */
1151 if (rx_priv->swr_clk_users > 0) {
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001152 if ((rx_priv->clk_id == rx_priv->default_clk_id &&
Laxminath Kasambee08192018-07-01 14:38:55 +05301153 rx_priv->is_native_on) ||
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001154 (rx_priv->clk_id == RX_CORE_CLK &&
Laxminath Kasambee08192018-07-01 14:38:55 +05301155 !rx_priv->is_native_on)) {
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001156 if (rx_priv->swr_ctrl_data)
1157 swrm_wcd_notify(
1158 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
1159 SWR_DEVICE_DOWN, NULL);
Laxminath Kasambee08192018-07-01 14:38:55 +05301160 }
1161 }
Laxminath Kasamac396d52018-09-06 12:53:26 +05301162 if (rx_priv->is_native_on)
1163 mclk_freq = MCLK_FREQ_NATIVE;
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001164 if (rx_priv->swr_ctrl_data)
1165 swrm_wcd_notify(
1166 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
1167 SWR_CLK_FREQ, &mclk_freq);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301168 ret = rx_macro_mclk_enable(rx_priv, 1, true);
Ramprasad Katkam452772a2019-01-07 17:30:36 +05301169 if (ret)
1170 rx_priv->dapm_mclk_enable = false;
1171 else
1172 rx_priv->dapm_mclk_enable = true;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301173 break;
1174 case SND_SOC_DAPM_POST_PMD:
Ramprasad Katkam452772a2019-01-07 17:30:36 +05301175 if (rx_priv->dapm_mclk_enable)
1176 ret = rx_macro_mclk_enable(rx_priv, 0, true);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301177 break;
1178 default:
1179 dev_err(rx_priv->dev,
1180 "%s: invalid DAPM event %d\n", __func__, event);
1181 ret = -EINVAL;
1182 }
1183 return ret;
1184}
1185
Meng Wang15c825d2018-09-06 10:49:18 +08001186static int rx_macro_event_handler(struct snd_soc_component *component,
1187 u16 event, u32 data)
Laxminath Kasam497a6512018-09-17 16:11:52 +05301188{
Vatsal Bucha53b4e142018-11-13 19:36:25 +05301189 u16 reg = 0, reg_mix = 0, rx_idx = 0, mute = 0x0, val = 0;
Laxminath Kasam497a6512018-09-17 16:11:52 +05301190 struct device *rx_dev = NULL;
1191 struct rx_macro_priv *rx_priv = NULL;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001192 int ret = 0;
Laxminath Kasam497a6512018-09-17 16:11:52 +05301193
Meng Wang15c825d2018-09-06 10:49:18 +08001194 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasam497a6512018-09-17 16:11:52 +05301195 return -EINVAL;
1196
1197 switch (event) {
1198 case BOLERO_MACRO_EVT_RX_MUTE:
1199 rx_idx = data >> 0x10;
1200 mute = data & 0xffff;
Vatsal Bucha53b4e142018-11-13 19:36:25 +05301201 val = mute ? 0x10 : 0x00;
Laxminath Kasam497a6512018-09-17 16:11:52 +05301202 reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + (rx_idx *
1203 RX_MACRO_RX_PATH_OFFSET);
1204 reg_mix = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL + (rx_idx *
1205 RX_MACRO_RX_PATH_OFFSET);
Meng Wang15c825d2018-09-06 10:49:18 +08001206 snd_soc_component_update_bits(component, reg,
1207 0x10, val);
1208 snd_soc_component_update_bits(component, reg_mix,
1209 0x10, val);
Laxminath Kasam497a6512018-09-17 16:11:52 +05301210 break;
Karthikeyan Manic14c27a2019-06-21 14:11:34 -07001211 case BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST:
1212 rx_idx = data >> 0x10;
1213 if (rx_idx == INTERP_AUX)
1214 goto done;
1215 reg = BOLERO_CDC_RX_COMPANDER0_CTL0 +
1216 (rx_idx * RX_MACRO_COMP_OFFSET);
1217 snd_soc_component_update_bits(component, reg,
1218 0x20, 0x20);
1219 snd_soc_component_update_bits(component, reg,
1220 0x20, 0x00);
1221 break;
Laxminath Kasam497a6512018-09-17 16:11:52 +05301222 case BOLERO_MACRO_EVT_IMPED_TRUE:
Meng Wang15c825d2018-09-06 10:49:18 +08001223 rx_macro_wcd_clsh_imped_config(component, data, true);
Laxminath Kasam497a6512018-09-17 16:11:52 +05301224 break;
1225 case BOLERO_MACRO_EVT_IMPED_FALSE:
Meng Wang15c825d2018-09-06 10:49:18 +08001226 rx_macro_wcd_clsh_imped_config(component, data, false);
Laxminath Kasam497a6512018-09-17 16:11:52 +05301227 break;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301228 case BOLERO_MACRO_EVT_SSR_DOWN:
Laxminath Kasam701e3582018-10-15 20:06:09 +05301229 rx_priv->dev_up = false;
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001230 if (rx_priv->swr_ctrl_data) {
1231 swrm_wcd_notify(
1232 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
1233 SWR_DEVICE_DOWN, NULL);
1234 swrm_wcd_notify(
1235 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
1236 SWR_DEVICE_SSR_DOWN, NULL);
1237 }
Aditya Bavanari50ef13e2019-08-09 15:14:43 +05301238 if ((!pm_runtime_enabled(rx_dev) ||
1239 !pm_runtime_suspended(rx_dev))) {
1240 ret = bolero_runtime_suspend(rx_dev);
1241 if (!ret) {
1242 pm_runtime_disable(rx_dev);
1243 pm_runtime_set_suspended(rx_dev);
1244 pm_runtime_enable(rx_dev);
1245 }
1246 }
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301247 break;
1248 case BOLERO_MACRO_EVT_SSR_UP:
Laxminath Kasam701e3582018-10-15 20:06:09 +05301249 rx_priv->dev_up = true;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05301250 /* reset swr after ssr/pdr */
1251 rx_priv->reset_swr = true;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001252 /* enable&disable RX_CORE_CLK to reset GFMUX reg */
1253 ret = bolero_clk_rsc_request_clock(rx_priv->dev,
1254 rx_priv->default_clk_id,
1255 RX_CORE_CLK, true);
1256 if (ret < 0)
1257 dev_err_ratelimited(rx_priv->dev,
1258 "%s, failed to enable clk, ret:%d\n",
1259 __func__, ret);
1260 else
1261 bolero_clk_rsc_request_clock(rx_priv->dev,
1262 rx_priv->default_clk_id,
1263 RX_CORE_CLK, false);
1264
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001265 if (rx_priv->swr_ctrl_data)
1266 swrm_wcd_notify(
1267 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
1268 SWR_DEVICE_SSR_UP, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301269 break;
Meng Wang8ef0cc22019-05-08 15:12:56 +08001270 case BOLERO_MACRO_EVT_CLK_RESET:
1271 bolero_rsc_clk_reset(rx_dev, RX_CORE_CLK);
1272 break;
Laxminath Kasam497a6512018-09-17 16:11:52 +05301273 }
Karthikeyan Manic14c27a2019-06-21 14:11:34 -07001274done:
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001275 return ret;
Laxminath Kasam497a6512018-09-17 16:11:52 +05301276}
1277
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301278static int rx_macro_find_playback_dai_id_for_port(int port_id,
1279 struct rx_macro_priv *rx_priv)
1280{
1281 int i = 0;
1282
1283 for (i = RX_MACRO_AIF1_PB; i < RX_MACRO_MAX_DAIS; i++) {
1284 if (test_bit(port_id, &rx_priv->active_ch_mask[i]))
1285 return i;
1286 }
1287
1288 return -EINVAL;
1289}
1290
Meng Wang15c825d2018-09-06 10:49:18 +08001291static int rx_macro_set_idle_detect_thr(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301292 struct rx_macro_priv *rx_priv,
1293 int interp, int path_type)
1294{
1295 int port_id[4] = { 0, 0, 0, 0 };
Laxminath Kasamb7f823c2018-08-02 13:23:11 +05301296 int *port_ptr = NULL;
1297 int num_ports = 0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301298 int bit_width = 0, i = 0;
1299 int mux_reg = 0, mux_reg_val = 0;
1300 int dai_id = 0, idle_thr = 0;
1301
1302 if ((interp != INTERP_HPHL) && (interp != INTERP_HPHR))
1303 return 0;
1304
1305 if (!rx_priv->idle_det_cfg.hph_idle_detect_en)
1306 return 0;
1307
1308 port_ptr = &port_id[0];
1309 num_ports = 0;
1310
1311 /*
1312 * Read interpolator MUX input registers and find
1313 * which cdc_dma port is connected and store the port
1314 * numbers in port_id array.
1315 */
1316 if (path_type == INTERP_MIX_PATH) {
1317 mux_reg = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1 +
1318 2 * interp;
Meng Wang15c825d2018-09-06 10:49:18 +08001319 mux_reg_val = snd_soc_component_read32(component, mux_reg) &
1320 0x0f;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301321
1322 if ((mux_reg_val >= INTn_2_INP_SEL_RX0) &&
1323 (mux_reg_val <= INTn_2_INP_SEL_RX5)) {
1324 *port_ptr++ = mux_reg_val - 1;
1325 num_ports++;
1326 }
1327 }
1328
1329 if (path_type == INTERP_MAIN_PATH) {
1330 mux_reg = BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0 +
1331 2 * (interp - 1);
Meng Wang15c825d2018-09-06 10:49:18 +08001332 mux_reg_val = snd_soc_component_read32(component, mux_reg) &
1333 0x0f;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301334 i = RX_MACRO_INTERP_MUX_NUM_INPUTS;
1335
1336 while (i) {
1337 if ((mux_reg_val >= INTn_1_INP_SEL_RX0) &&
1338 (mux_reg_val <= INTn_1_INP_SEL_RX5)) {
1339 *port_ptr++ = mux_reg_val -
1340 INTn_1_INP_SEL_RX0;
1341 num_ports++;
1342 }
Meng Wang15c825d2018-09-06 10:49:18 +08001343 mux_reg_val =
1344 (snd_soc_component_read32(component, mux_reg) &
1345 0xf0) >> 4;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301346 mux_reg += 1;
1347 i--;
1348 }
1349 }
1350
Meng Wang15c825d2018-09-06 10:49:18 +08001351 dev_dbg(component->dev, "%s: num_ports: %d, ports[%d %d %d %d]\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301352 __func__, num_ports, port_id[0], port_id[1],
1353 port_id[2], port_id[3]);
1354
1355 i = 0;
1356 while (num_ports) {
1357 dai_id = rx_macro_find_playback_dai_id_for_port(port_id[i++],
1358 rx_priv);
1359
1360 if ((dai_id >= 0) && (dai_id < RX_MACRO_MAX_DAIS)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001361 dev_dbg(component->dev, "%s: dai_id: %d bit_width: %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301362 __func__, dai_id,
1363 rx_priv->bit_width[dai_id]);
1364
1365 if (rx_priv->bit_width[dai_id] > bit_width)
1366 bit_width = rx_priv->bit_width[dai_id];
1367 }
1368 num_ports--;
1369 }
1370
1371 switch (bit_width) {
1372 case 16:
1373 idle_thr = 0xff; /* F16 */
1374 break;
1375 case 24:
1376 case 32:
1377 idle_thr = 0x03; /* F22 */
1378 break;
1379 default:
1380 idle_thr = 0x00;
1381 break;
1382 }
1383
Meng Wang15c825d2018-09-06 10:49:18 +08001384 dev_dbg(component->dev, "%s: (new) idle_thr: %d, (cur) idle_thr: %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301385 __func__, idle_thr, rx_priv->idle_det_cfg.hph_idle_thr);
1386
1387 if ((rx_priv->idle_det_cfg.hph_idle_thr == 0) ||
1388 (idle_thr < rx_priv->idle_det_cfg.hph_idle_thr)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001389 snd_soc_component_write(component,
1390 BOLERO_CDC_RX_IDLE_DETECT_CFG3, idle_thr);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301391 rx_priv->idle_det_cfg.hph_idle_thr = idle_thr;
1392 }
1393
1394 return 0;
1395}
1396
1397static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
1398 struct snd_kcontrol *kcontrol, int event)
1399{
Meng Wang15c825d2018-09-06 10:49:18 +08001400 struct snd_soc_component *component =
1401 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301402 u16 gain_reg = 0, mix_reg = 0;
1403 struct device *rx_dev = NULL;
1404 struct rx_macro_priv *rx_priv = NULL;
1405
Meng Wang15c825d2018-09-06 10:49:18 +08001406 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301407 return -EINVAL;
1408
1409 if (w->shift >= INTERP_MAX) {
Meng Wang15c825d2018-09-06 10:49:18 +08001410 dev_err(component->dev, "%s: Invalid Interpolator value %d for name %s\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301411 __func__, w->shift, w->name);
1412 return -EINVAL;
1413 }
1414
1415 gain_reg = BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL +
1416 (w->shift * RX_MACRO_RX_PATH_OFFSET);
1417 mix_reg = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL +
1418 (w->shift * RX_MACRO_RX_PATH_OFFSET);
1419
Meng Wang15c825d2018-09-06 10:49:18 +08001420 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301421
1422 switch (event) {
1423 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001424 rx_macro_set_idle_detect_thr(component, rx_priv, w->shift,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301425 INTERP_MIX_PATH);
Meng Wang15c825d2018-09-06 10:49:18 +08001426 rx_macro_enable_interp_clk(component, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301427 /* Clk enable */
Meng Wang15c825d2018-09-06 10:49:18 +08001428 snd_soc_component_update_bits(component, mix_reg, 0x20, 0x20);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301429 break;
1430 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001431 snd_soc_component_write(component, gain_reg,
1432 snd_soc_component_read32(component, gain_reg));
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301433 break;
1434 case SND_SOC_DAPM_POST_PMD:
1435 /* Clk Disable */
Meng Wang15c825d2018-09-06 10:49:18 +08001436 snd_soc_component_update_bits(component, mix_reg, 0x20, 0x00);
1437 rx_macro_enable_interp_clk(component, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301438 /* Reset enable and disable */
Meng Wang15c825d2018-09-06 10:49:18 +08001439 snd_soc_component_update_bits(component, mix_reg, 0x40, 0x40);
1440 snd_soc_component_update_bits(component, mix_reg, 0x40, 0x00);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301441 break;
1442 }
1443
1444 return 0;
1445}
1446
1447static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w,
1448 struct snd_kcontrol *kcontrol,
1449 int event)
1450{
Meng Wang15c825d2018-09-06 10:49:18 +08001451 struct snd_soc_component *component =
1452 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301453 u16 gain_reg = 0;
1454 u16 reg = 0;
1455 struct device *rx_dev = NULL;
1456 struct rx_macro_priv *rx_priv = NULL;
1457
Meng Wang15c825d2018-09-06 10:49:18 +08001458 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301459 return -EINVAL;
1460
Meng Wang15c825d2018-09-06 10:49:18 +08001461 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301462
1463 if (w->shift >= INTERP_MAX) {
Meng Wang15c825d2018-09-06 10:49:18 +08001464 dev_err(component->dev, "%s: Invalid Interpolator value %d for name %s\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301465 __func__, w->shift, w->name);
1466 return -EINVAL;
1467 }
1468
1469 reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + (w->shift *
1470 RX_MACRO_RX_PATH_OFFSET);
1471 gain_reg = BOLERO_CDC_RX_RX0_RX_VOL_CTL + (w->shift *
1472 RX_MACRO_RX_PATH_OFFSET);
1473
1474 switch (event) {
1475 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001476 rx_macro_set_idle_detect_thr(component, rx_priv, w->shift,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301477 INTERP_MAIN_PATH);
Meng Wang15c825d2018-09-06 10:49:18 +08001478 rx_macro_enable_interp_clk(component, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301479 break;
1480 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001481 snd_soc_component_write(component, gain_reg,
1482 snd_soc_component_read32(component, gain_reg));
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301483 break;
1484 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001485 rx_macro_enable_interp_clk(component, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301486 break;
1487 }
1488
1489 return 0;
1490}
1491
Meng Wang15c825d2018-09-06 10:49:18 +08001492static int rx_macro_config_compander(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301493 struct rx_macro_priv *rx_priv,
1494 int interp_n, int event)
1495{
1496 int comp = 0;
1497 u16 comp_ctl0_reg = 0, rx_path_cfg0_reg = 0;
1498
1499 /* AUX does not have compander */
1500 if (interp_n == INTERP_AUX)
1501 return 0;
1502
1503 comp = interp_n;
Meng Wang15c825d2018-09-06 10:49:18 +08001504 dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301505 __func__, event, comp + 1, rx_priv->comp_enabled[comp]);
1506
1507 if (!rx_priv->comp_enabled[comp])
1508 return 0;
1509
1510 comp_ctl0_reg = BOLERO_CDC_RX_COMPANDER0_CTL0 +
1511 (comp * RX_MACRO_COMP_OFFSET);
1512 rx_path_cfg0_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0 +
1513 (comp * RX_MACRO_RX_PATH_OFFSET);
1514
1515 if (SND_SOC_DAPM_EVENT_ON(event)) {
1516 /* Enable Compander Clock */
Meng Wang15c825d2018-09-06 10:49:18 +08001517 snd_soc_component_update_bits(component, comp_ctl0_reg,
1518 0x01, 0x01);
1519 snd_soc_component_update_bits(component, comp_ctl0_reg,
1520 0x02, 0x02);
1521 snd_soc_component_update_bits(component, comp_ctl0_reg,
1522 0x02, 0x00);
1523 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1524 0x02, 0x02);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301525 }
1526
1527 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001528 snd_soc_component_update_bits(component, comp_ctl0_reg,
1529 0x04, 0x04);
1530 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1531 0x02, 0x00);
1532 snd_soc_component_update_bits(component, comp_ctl0_reg,
1533 0x01, 0x00);
1534 snd_soc_component_update_bits(component, comp_ctl0_reg,
1535 0x04, 0x00);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301536 }
1537
1538 return 0;
1539}
1540
Meng Wang15c825d2018-09-06 10:49:18 +08001541static void rx_macro_enable_softclip_clk(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301542 struct rx_macro_priv *rx_priv,
1543 bool enable)
1544{
1545 if (enable) {
1546 if (rx_priv->softclip_clk_users == 0)
Meng Wang15c825d2018-09-06 10:49:18 +08001547 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301548 BOLERO_CDC_RX_SOFTCLIP_CRC,
1549 0x01, 0x01);
1550 rx_priv->softclip_clk_users++;
1551 } else {
1552 rx_priv->softclip_clk_users--;
1553 if (rx_priv->softclip_clk_users == 0)
Meng Wang15c825d2018-09-06 10:49:18 +08001554 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301555 BOLERO_CDC_RX_SOFTCLIP_CRC,
1556 0x01, 0x00);
1557 }
1558}
1559
Meng Wang15c825d2018-09-06 10:49:18 +08001560static int rx_macro_config_softclip(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301561 struct rx_macro_priv *rx_priv,
1562 int event)
1563{
Meng Wang15c825d2018-09-06 10:49:18 +08001564 dev_dbg(component->dev, "%s: event %d, enabled %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301565 __func__, event, rx_priv->is_softclip_on);
1566
1567 if (!rx_priv->is_softclip_on)
1568 return 0;
1569
1570 if (SND_SOC_DAPM_EVENT_ON(event)) {
1571 /* Enable Softclip clock */
Meng Wang15c825d2018-09-06 10:49:18 +08001572 rx_macro_enable_softclip_clk(component, rx_priv, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301573 /* Enable Softclip control */
Meng Wang15c825d2018-09-06 10:49:18 +08001574 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301575 BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x01, 0x01);
1576 }
1577
1578 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001579 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301580 BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001581 rx_macro_enable_softclip_clk(component, rx_priv, false);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301582 }
1583
1584 return 0;
1585}
1586
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301587static inline void
1588rx_macro_enable_clsh_block(struct rx_macro_priv *rx_priv, bool enable)
1589{
1590 if ((enable && ++rx_priv->clsh_users == 1) ||
1591 (!enable && --rx_priv->clsh_users == 0))
Meng Wang15c825d2018-09-06 10:49:18 +08001592 snd_soc_component_update_bits(rx_priv->component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301593 BOLERO_CDC_RX_CLSH_CRC, 0x01,
1594 (u8) enable);
1595 if (rx_priv->clsh_users < 0)
1596 rx_priv->clsh_users = 0;
1597 dev_dbg(rx_priv->dev, "%s: clsh_users %d, enable %d", __func__,
1598 rx_priv->clsh_users, enable);
1599}
1600
Meng Wang15c825d2018-09-06 10:49:18 +08001601static int rx_macro_config_classh(struct snd_soc_component *component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301602 struct rx_macro_priv *rx_priv,
1603 int interp_n, int event)
1604{
1605 if (SND_SOC_DAPM_EVENT_OFF(event)) {
1606 rx_macro_enable_clsh_block(rx_priv, false);
1607 return 0;
1608 }
1609
1610 if (!SND_SOC_DAPM_EVENT_ON(event))
1611 return 0;
1612
1613 rx_macro_enable_clsh_block(rx_priv, true);
1614 if (interp_n == INTERP_HPHL ||
1615 interp_n == INTERP_HPHR) {
1616 /*
1617 * These K1 values depend on the Headphone Impedance
1618 * For now it is assumed to be 16 ohm
1619 */
Meng Wang15c825d2018-09-06 10:49:18 +08001620 snd_soc_component_update_bits(component,
1621 BOLERO_CDC_RX_CLSH_K1_LSB,
1622 0xFF, 0xC0);
1623 snd_soc_component_update_bits(component,
1624 BOLERO_CDC_RX_CLSH_K1_MSB,
1625 0x0F, 0x00);
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301626 }
1627 switch (interp_n) {
1628 case INTERP_HPHL:
1629 if (rx_priv->is_ear_mode_on)
Meng Wang15c825d2018-09-06 10:49:18 +08001630 snd_soc_component_update_bits(component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301631 BOLERO_CDC_RX_CLSH_HPH_V_PA,
1632 0x3F, 0x39);
1633 else
Meng Wang15c825d2018-09-06 10:49:18 +08001634 snd_soc_component_update_bits(component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301635 BOLERO_CDC_RX_CLSH_HPH_V_PA,
1636 0x3F, 0x1C);
Meng Wang15c825d2018-09-06 10:49:18 +08001637 snd_soc_component_update_bits(component,
1638 BOLERO_CDC_RX_CLSH_DECAY_CTRL,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301639 0x07, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001640 snd_soc_component_update_bits(component,
1641 BOLERO_CDC_RX_RX0_RX_PATH_CFG0,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301642 0x40, 0x40);
1643 break;
1644 case INTERP_HPHR:
Meng Wang15c825d2018-09-06 10:49:18 +08001645 snd_soc_component_update_bits(component,
1646 BOLERO_CDC_RX_CLSH_HPH_V_PA,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301647 0x3F, 0x1C);
Meng Wang15c825d2018-09-06 10:49:18 +08001648 snd_soc_component_update_bits(component,
1649 BOLERO_CDC_RX_CLSH_DECAY_CTRL,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301650 0x07, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001651 snd_soc_component_update_bits(component,
1652 BOLERO_CDC_RX_RX1_RX_PATH_CFG0,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301653 0x40, 0x40);
1654 break;
1655 case INTERP_AUX:
Meng Wang15c825d2018-09-06 10:49:18 +08001656 snd_soc_component_update_bits(component,
1657 BOLERO_CDC_RX_RX2_RX_PATH_CFG0,
Laxminath Kasam1a4dd6d2019-04-02 15:21:54 +05301658 0x08, 0x08);
1659 snd_soc_component_update_bits(component,
1660 BOLERO_CDC_RX_RX2_RX_PATH_CFG0,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301661 0x10, 0x10);
1662 break;
1663 }
1664
1665 return 0;
1666}
1667
Meng Wang15c825d2018-09-06 10:49:18 +08001668static void rx_macro_hd2_control(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301669 u16 interp_idx, int event)
1670{
1671 u16 hd2_scale_reg = 0;
1672 u16 hd2_enable_reg = 0;
1673
1674 switch (interp_idx) {
1675 case INTERP_HPHL:
Laxminath Kasam7adc34e2018-11-09 11:24:38 +05301676 hd2_scale_reg = BOLERO_CDC_RX_RX0_RX_PATH_SEC3;
1677 hd2_enable_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301678 break;
1679 case INTERP_HPHR:
Laxminath Kasam7adc34e2018-11-09 11:24:38 +05301680 hd2_scale_reg = BOLERO_CDC_RX_RX1_RX_PATH_SEC3;
1681 hd2_enable_reg = BOLERO_CDC_RX_RX1_RX_PATH_CFG0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301682 break;
1683 }
1684
1685 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001686 snd_soc_component_update_bits(component, hd2_scale_reg,
1687 0x3C, 0x14);
1688 snd_soc_component_update_bits(component, hd2_enable_reg,
1689 0x04, 0x04);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301690 }
1691
1692 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001693 snd_soc_component_update_bits(component, hd2_enable_reg,
1694 0x04, 0x00);
1695 snd_soc_component_update_bits(component, hd2_scale_reg,
1696 0x3C, 0x00);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301697 }
1698}
1699
Vatsal Bucha8bcc97c2019-01-07 13:18:11 +05301700static int rx_macro_hph_idle_detect_get(struct snd_kcontrol *kcontrol,
1701 struct snd_ctl_elem_value *ucontrol)
1702{
1703 struct snd_soc_component *component =
1704 snd_soc_kcontrol_component(kcontrol);
1705 struct rx_macro_priv *rx_priv = NULL;
1706 struct device *rx_dev = NULL;
1707
1708 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
1709 return -EINVAL;
1710
1711 ucontrol->value.integer.value[0] =
1712 rx_priv->idle_det_cfg.hph_idle_detect_en;
1713
1714 return 0;
1715}
1716
1717static int rx_macro_hph_idle_detect_put(struct snd_kcontrol *kcontrol,
1718 struct snd_ctl_elem_value *ucontrol)
1719{
1720 struct snd_soc_component *component =
1721 snd_soc_kcontrol_component(kcontrol);
1722 struct rx_macro_priv *rx_priv = NULL;
1723 struct device *rx_dev = NULL;
1724
1725 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
1726 return -EINVAL;
1727
1728 rx_priv->idle_det_cfg.hph_idle_detect_en =
1729 ucontrol->value.integer.value[0];
1730
1731 return 0;
1732}
1733
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301734static int rx_macro_get_compander(struct snd_kcontrol *kcontrol,
1735 struct snd_ctl_elem_value *ucontrol)
1736{
Meng Wang15c825d2018-09-06 10:49:18 +08001737 struct snd_soc_component *component =
1738 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301739 int comp = ((struct soc_multi_mixer_control *)
1740 kcontrol->private_value)->shift;
1741 struct device *rx_dev = NULL;
1742 struct rx_macro_priv *rx_priv = NULL;
1743
Meng Wang15c825d2018-09-06 10:49:18 +08001744 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301745 return -EINVAL;
1746
1747 ucontrol->value.integer.value[0] = rx_priv->comp_enabled[comp];
1748 return 0;
1749}
1750
1751static int rx_macro_set_compander(struct snd_kcontrol *kcontrol,
1752 struct snd_ctl_elem_value *ucontrol)
1753{
Meng Wang15c825d2018-09-06 10:49:18 +08001754 struct snd_soc_component *component =
1755 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301756 int comp = ((struct soc_multi_mixer_control *)
1757 kcontrol->private_value)->shift;
1758 int value = ucontrol->value.integer.value[0];
1759 struct device *rx_dev = NULL;
1760 struct rx_macro_priv *rx_priv = NULL;
1761
Meng Wang15c825d2018-09-06 10:49:18 +08001762 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301763 return -EINVAL;
1764
Meng Wang15c825d2018-09-06 10:49:18 +08001765 dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301766 __func__, comp + 1, rx_priv->comp_enabled[comp], value);
1767 rx_priv->comp_enabled[comp] = value;
1768
1769 return 0;
1770}
1771
1772static int rx_macro_mux_get(struct snd_kcontrol *kcontrol,
1773 struct snd_ctl_elem_value *ucontrol)
1774{
1775 struct snd_soc_dapm_widget *widget =
1776 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08001777 struct snd_soc_component *component =
1778 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301779 struct device *rx_dev = NULL;
1780 struct rx_macro_priv *rx_priv = NULL;
1781
Meng Wang15c825d2018-09-06 10:49:18 +08001782 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301783 return -EINVAL;
1784
1785 ucontrol->value.integer.value[0] =
1786 rx_priv->rx_port_value[widget->shift];
1787 return 0;
1788}
1789
1790static int rx_macro_mux_put(struct snd_kcontrol *kcontrol,
1791 struct snd_ctl_elem_value *ucontrol)
1792{
1793 struct snd_soc_dapm_widget *widget =
1794 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08001795 struct snd_soc_component *component =
1796 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301797 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1798 struct snd_soc_dapm_update *update = NULL;
1799 u32 rx_port_value = ucontrol->value.integer.value[0];
1800 u32 aif_rst = 0;
1801 struct device *rx_dev = NULL;
1802 struct rx_macro_priv *rx_priv = NULL;
1803
Meng Wang15c825d2018-09-06 10:49:18 +08001804 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301805 return -EINVAL;
1806
1807 aif_rst = rx_priv->rx_port_value[widget->shift];
1808 if (!rx_port_value) {
1809 if (aif_rst == 0) {
1810 dev_err(rx_dev, "%s:AIF reset already\n", __func__);
1811 return 0;
1812 }
1813 }
1814 rx_priv->rx_port_value[widget->shift] = rx_port_value;
1815
1816 switch (rx_port_value) {
1817 case 0:
1818 clear_bit(widget->shift,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05301819 &rx_priv->active_ch_mask[aif_rst]);
1820 rx_priv->active_ch_cnt[aif_rst]--;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301821 break;
1822 case 1:
1823 case 2:
1824 case 3:
1825 case 4:
1826 set_bit(widget->shift,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05301827 &rx_priv->active_ch_mask[rx_port_value]);
1828 rx_priv->active_ch_cnt[rx_port_value]++;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301829 break;
1830 default:
Meng Wang15c825d2018-09-06 10:49:18 +08001831 dev_err(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301832 "%s:Invalid AIF_ID for RX_MACRO MUX\n", __func__);
1833 goto err;
1834 }
1835
1836 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
1837 rx_port_value, e, update);
1838 return 0;
1839err:
1840 return -EINVAL;
1841}
1842
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301843static int rx_macro_get_ear_mode(struct snd_kcontrol *kcontrol,
1844 struct snd_ctl_elem_value *ucontrol)
1845{
Meng Wang15c825d2018-09-06 10:49:18 +08001846 struct snd_soc_component *component =
1847 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301848 struct device *rx_dev = NULL;
1849 struct rx_macro_priv *rx_priv = NULL;
1850
Meng Wang15c825d2018-09-06 10:49:18 +08001851 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301852 return -EINVAL;
1853
1854 ucontrol->value.integer.value[0] = rx_priv->is_ear_mode_on;
1855 return 0;
1856}
1857
1858static int rx_macro_put_ear_mode(struct snd_kcontrol *kcontrol,
1859 struct snd_ctl_elem_value *ucontrol)
1860{
Meng Wang15c825d2018-09-06 10:49:18 +08001861 struct snd_soc_component *component =
1862 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301863 struct device *rx_dev = NULL;
1864 struct rx_macro_priv *rx_priv = NULL;
1865
Meng Wang15c825d2018-09-06 10:49:18 +08001866 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301867 return -EINVAL;
1868
1869 rx_priv->is_ear_mode_on =
1870 (!ucontrol->value.integer.value[0] ? false : true);
1871 return 0;
1872}
1873
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05301874static int rx_macro_get_hph_hd2_mode(struct snd_kcontrol *kcontrol,
1875 struct snd_ctl_elem_value *ucontrol)
1876{
Meng Wang15c825d2018-09-06 10:49:18 +08001877 struct snd_soc_component *component =
1878 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05301879 struct device *rx_dev = NULL;
1880 struct rx_macro_priv *rx_priv = NULL;
1881
Meng Wang15c825d2018-09-06 10:49:18 +08001882 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05301883 return -EINVAL;
1884
1885 ucontrol->value.integer.value[0] = rx_priv->hph_hd2_mode;
1886 return 0;
1887}
1888
1889static int rx_macro_put_hph_hd2_mode(struct snd_kcontrol *kcontrol,
1890 struct snd_ctl_elem_value *ucontrol)
1891{
Meng Wang15c825d2018-09-06 10:49:18 +08001892 struct snd_soc_component *component =
1893 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05301894 struct device *rx_dev = NULL;
1895 struct rx_macro_priv *rx_priv = NULL;
1896
Meng Wang15c825d2018-09-06 10:49:18 +08001897 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05301898 return -EINVAL;
1899
1900 rx_priv->hph_hd2_mode = ucontrol->value.integer.value[0];
1901 return 0;
1902}
1903
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05301904static int rx_macro_get_hph_pwr_mode(struct snd_kcontrol *kcontrol,
1905 struct snd_ctl_elem_value *ucontrol)
1906{
Meng Wang15c825d2018-09-06 10:49:18 +08001907 struct snd_soc_component *component =
1908 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05301909 struct device *rx_dev = NULL;
1910 struct rx_macro_priv *rx_priv = NULL;
1911
Meng Wang15c825d2018-09-06 10:49:18 +08001912 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05301913 return -EINVAL;
1914
1915 ucontrol->value.integer.value[0] = rx_priv->hph_pwr_mode;
1916 return 0;
1917}
1918
1919static int rx_macro_put_hph_pwr_mode(struct snd_kcontrol *kcontrol,
1920 struct snd_ctl_elem_value *ucontrol)
1921{
Meng Wang15c825d2018-09-06 10:49:18 +08001922 struct snd_soc_component *component =
1923 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05301924 struct device *rx_dev = NULL;
1925 struct rx_macro_priv *rx_priv = NULL;
1926
Meng Wang15c825d2018-09-06 10:49:18 +08001927 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05301928 return -EINVAL;
1929
1930 rx_priv->hph_pwr_mode = ucontrol->value.integer.value[0];
1931 return 0;
1932}
1933
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301934static int rx_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
1935 struct snd_ctl_elem_value *ucontrol)
1936{
Meng Wang15c825d2018-09-06 10:49:18 +08001937 struct snd_soc_component *component =
1938 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301939
1940 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08001941 ((snd_soc_component_read32(
1942 component, BOLERO_CDC_RX_BCL_VBAT_CFG) & 0x04) ?
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301943 1 : 0);
1944
Meng Wang15c825d2018-09-06 10:49:18 +08001945 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301946 ucontrol->value.integer.value[0]);
1947
1948 return 0;
1949}
1950
1951static int rx_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
1952 struct snd_ctl_elem_value *ucontrol)
1953{
Meng Wang15c825d2018-09-06 10:49:18 +08001954 struct snd_soc_component *component =
1955 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301956
Meng Wang15c825d2018-09-06 10:49:18 +08001957 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301958 ucontrol->value.integer.value[0]);
1959
1960 /* Set Vbat register configuration for GSM mode bit based on value */
1961 if (ucontrol->value.integer.value[0])
Meng Wang15c825d2018-09-06 10:49:18 +08001962 snd_soc_component_update_bits(component,
1963 BOLERO_CDC_RX_BCL_VBAT_CFG,
1964 0x04, 0x04);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301965 else
Meng Wang15c825d2018-09-06 10:49:18 +08001966 snd_soc_component_update_bits(component,
1967 BOLERO_CDC_RX_BCL_VBAT_CFG,
1968 0x04, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301969
1970 return 0;
1971}
1972
1973static int rx_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
1974 struct snd_ctl_elem_value *ucontrol)
1975{
Meng Wang15c825d2018-09-06 10:49:18 +08001976 struct snd_soc_component *component =
1977 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301978 struct device *rx_dev = NULL;
1979 struct rx_macro_priv *rx_priv = NULL;
1980
Meng Wang15c825d2018-09-06 10:49:18 +08001981 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301982 return -EINVAL;
1983
1984 ucontrol->value.integer.value[0] = rx_priv->is_softclip_on;
1985
Meng Wang15c825d2018-09-06 10:49:18 +08001986 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301987 __func__, ucontrol->value.integer.value[0]);
1988
1989 return 0;
1990}
1991
1992static int rx_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
1993 struct snd_ctl_elem_value *ucontrol)
1994{
Meng Wang15c825d2018-09-06 10:49:18 +08001995 struct snd_soc_component *component =
1996 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301997 struct device *rx_dev = NULL;
1998 struct rx_macro_priv *rx_priv = NULL;
1999
Meng Wang15c825d2018-09-06 10:49:18 +08002000 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302001 return -EINVAL;
2002
Meng Wang15c825d2018-09-06 10:49:18 +08002003 rx_priv->is_softclip_on = ucontrol->value.integer.value[0];
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302004
Meng Wang15c825d2018-09-06 10:49:18 +08002005 dev_dbg(component->dev, "%s: soft clip enable = %d\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302006 rx_priv->is_softclip_on);
2007
2008 return 0;
2009}
2010
2011static int rx_macro_enable_vbat(struct snd_soc_dapm_widget *w,
2012 struct snd_kcontrol *kcontrol,
2013 int event)
2014{
Meng Wang15c825d2018-09-06 10:49:18 +08002015 struct snd_soc_component *component =
2016 snd_soc_dapm_to_component(w->dapm);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302017 struct device *rx_dev = NULL;
2018 struct rx_macro_priv *rx_priv = NULL;
2019
Meng Wang15c825d2018-09-06 10:49:18 +08002020 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
2021 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302022 return -EINVAL;
2023
2024 switch (event) {
2025 case SND_SOC_DAPM_PRE_PMU:
2026 /* Enable clock for VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08002027 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302028 BOLERO_CDC_RX_BCL_VBAT_PATH_CTL, 0x10, 0x10);
2029 /* Enable VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08002030 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302031 BOLERO_CDC_RX_BCL_VBAT_CFG, 0x01, 0x01);
2032 /* Update interpolator with 384K path */
Meng Wang15c825d2018-09-06 10:49:18 +08002033 snd_soc_component_update_bits(component,
2034 BOLERO_CDC_RX_RX2_RX_PATH_CFG1, 0x80, 0x80);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302035 /* Update DSM FS rate */
Meng Wang15c825d2018-09-06 10:49:18 +08002036 snd_soc_component_update_bits(component,
2037 BOLERO_CDC_RX_RX2_RX_PATH_SEC7, 0x02, 0x02);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302038 /* Use attenuation mode */
Meng Wang15c825d2018-09-06 10:49:18 +08002039 snd_soc_component_update_bits(component,
2040 BOLERO_CDC_RX_BCL_VBAT_CFG, 0x02, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302041 /* BCL block needs softclip clock to be enabled */
Meng Wang15c825d2018-09-06 10:49:18 +08002042 rx_macro_enable_softclip_clk(component, rx_priv, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302043 /* Enable VBAT at channel level */
Meng Wang15c825d2018-09-06 10:49:18 +08002044 snd_soc_component_update_bits(component,
2045 BOLERO_CDC_RX_RX2_RX_PATH_CFG1, 0x02, 0x02);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302046 /* Set the ATTK1 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08002047 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302048 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1,
2049 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08002050 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302051 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2,
2052 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08002053 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302054 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3,
2055 0xFF, 0x00);
2056 /* Set the ATTK2 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08002057 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302058 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4,
2059 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08002060 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302061 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5,
2062 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08002063 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302064 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6,
2065 0xFF, 0x00);
2066 /* Set the ATTK3 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08002067 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302068 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7,
2069 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08002070 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302071 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8,
2072 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08002073 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302074 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9,
2075 0xFF, 0x00);
2076 break;
2077
2078 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08002079 snd_soc_component_update_bits(component,
2080 BOLERO_CDC_RX_RX2_RX_PATH_CFG1,
2081 0x80, 0x00);
2082 snd_soc_component_update_bits(component,
2083 BOLERO_CDC_RX_RX2_RX_PATH_SEC7,
2084 0x02, 0x00);
2085 snd_soc_component_update_bits(component,
2086 BOLERO_CDC_RX_BCL_VBAT_CFG,
2087 0x02, 0x02);
2088 snd_soc_component_update_bits(component,
2089 BOLERO_CDC_RX_RX2_RX_PATH_CFG1,
2090 0x02, 0x00);
2091 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302092 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1,
2093 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002094 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302095 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2,
2096 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002097 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302098 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3,
2099 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002100 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302101 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4,
2102 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002103 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302104 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5,
2105 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002106 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302107 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6,
2108 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002109 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302110 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7,
2111 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002112 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302113 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8,
2114 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002115 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302116 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9,
2117 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002118 rx_macro_enable_softclip_clk(component, rx_priv, false);
2119 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302120 BOLERO_CDC_RX_BCL_VBAT_CFG, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002121 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302122 BOLERO_CDC_RX_BCL_VBAT_PATH_CTL, 0x10, 0x00);
2123 break;
2124 default:
2125 dev_err(rx_dev, "%s: Invalid event %d\n", __func__, event);
2126 break;
2127 }
2128 return 0;
2129}
2130
Meng Wang15c825d2018-09-06 10:49:18 +08002131static void rx_macro_idle_detect_control(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302132 struct rx_macro_priv *rx_priv,
2133 int interp, int event)
2134{
2135 int reg = 0, mask = 0, val = 0;
2136
2137 if (!rx_priv->idle_det_cfg.hph_idle_detect_en)
2138 return;
2139
2140 if (interp == INTERP_HPHL) {
2141 reg = BOLERO_CDC_RX_IDLE_DETECT_PATH_CTL;
2142 mask = 0x01;
2143 val = 0x01;
2144 }
2145 if (interp == INTERP_HPHR) {
2146 reg = BOLERO_CDC_RX_IDLE_DETECT_PATH_CTL;
2147 mask = 0x02;
2148 val = 0x02;
2149 }
2150
2151 if (reg && SND_SOC_DAPM_EVENT_ON(event))
Meng Wang15c825d2018-09-06 10:49:18 +08002152 snd_soc_component_update_bits(component, reg, mask, val);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302153
2154 if (reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08002155 snd_soc_component_update_bits(component, reg, mask, 0x00);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302156 rx_priv->idle_det_cfg.hph_idle_thr = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08002157 snd_soc_component_write(component,
2158 BOLERO_CDC_RX_IDLE_DETECT_CFG3, 0x0);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302159 }
2160}
2161
Meng Wang15c825d2018-09-06 10:49:18 +08002162static void rx_macro_hphdelay_lutbypass(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302163 struct rx_macro_priv *rx_priv,
2164 u16 interp_idx, int event)
2165{
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302166 u16 hph_lut_bypass_reg = 0;
2167 u16 hph_comp_ctrl7 = 0;
2168
2169 switch (interp_idx) {
2170 case INTERP_HPHL:
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302171 hph_lut_bypass_reg = BOLERO_CDC_RX_TOP_HPHL_COMP_LUT;
2172 hph_comp_ctrl7 = BOLERO_CDC_RX_COMPANDER0_CTL7;
2173 break;
2174 case INTERP_HPHR:
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302175 hph_lut_bypass_reg = BOLERO_CDC_RX_TOP_HPHR_COMP_LUT;
2176 hph_comp_ctrl7 = BOLERO_CDC_RX_COMPANDER1_CTL7;
2177 break;
2178 default:
2179 break;
2180 }
2181
2182 if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) {
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302183 if (interp_idx == INTERP_HPHL) {
2184 if (rx_priv->is_ear_mode_on)
Meng Wang15c825d2018-09-06 10:49:18 +08002185 snd_soc_component_update_bits(component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302186 BOLERO_CDC_RX_RX0_RX_PATH_CFG1,
2187 0x02, 0x02);
2188 else
Meng Wang15c825d2018-09-06 10:49:18 +08002189 snd_soc_component_update_bits(component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302190 hph_lut_bypass_reg,
2191 0x80, 0x80);
2192 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08002193 snd_soc_component_update_bits(component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302194 hph_lut_bypass_reg,
2195 0x80, 0x80);
2196 }
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05302197 if (rx_priv->hph_pwr_mode)
Meng Wang15c825d2018-09-06 10:49:18 +08002198 snd_soc_component_update_bits(component,
2199 hph_comp_ctrl7,
2200 0x20, 0x00);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302201 }
2202
2203 if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08002204 snd_soc_component_update_bits(component,
2205 BOLERO_CDC_RX_RX0_RX_PATH_CFG1,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302206 0x02, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002207 snd_soc_component_update_bits(component, hph_lut_bypass_reg,
2208 0x80, 0x00);
2209 snd_soc_component_update_bits(component, hph_comp_ctrl7,
Karthikeyan Manic141ca92019-05-13 14:40:55 -07002210 0x20, 0x20);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302211 }
2212}
2213
Meng Wang15c825d2018-09-06 10:49:18 +08002214static int rx_macro_enable_interp_clk(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302215 int event, int interp_idx)
2216{
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302217 u16 main_reg = 0, dsm_reg = 0, rx_cfg2_reg = 0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302218 struct device *rx_dev = NULL;
2219 struct rx_macro_priv *rx_priv = NULL;
2220
Meng Wang15c825d2018-09-06 10:49:18 +08002221 if (!component) {
2222 pr_err("%s: component is NULL\n", __func__);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302223 return -EINVAL;
2224 }
2225
Meng Wang15c825d2018-09-06 10:49:18 +08002226 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302227 return -EINVAL;
2228
2229 main_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL +
2230 (interp_idx * RX_MACRO_RX_PATH_OFFSET);
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302231 dsm_reg = BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL +
2232 (interp_idx * RX_MACRO_RX_PATH_OFFSET);
Laxminath Kasam1a4dd6d2019-04-02 15:21:54 +05302233 if (interp_idx == INTERP_AUX)
2234 dsm_reg = BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL;
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302235 rx_cfg2_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG2 +
2236 (interp_idx * RX_MACRO_RX_PATH_OFFSET);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302237
2238 if (SND_SOC_DAPM_EVENT_ON(event)) {
2239 if (rx_priv->main_clk_users[interp_idx] == 0) {
2240 /* Main path PGA mute enable */
Meng Wang15c825d2018-09-06 10:49:18 +08002241 snd_soc_component_update_bits(component, main_reg,
2242 0x10, 0x10);
Laxminath Kasam1a4dd6d2019-04-02 15:21:54 +05302243 snd_soc_component_update_bits(component, dsm_reg,
2244 0x01, 0x01);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302245 /* Clk enable */
Meng Wang15c825d2018-09-06 10:49:18 +08002246 snd_soc_component_update_bits(component, main_reg,
2247 0x20, 0x20);
2248 snd_soc_component_update_bits(component, rx_cfg2_reg,
2249 0x03, 0x03);
2250 rx_macro_idle_detect_control(component, rx_priv,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302251 interp_idx, event);
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05302252 if (rx_priv->hph_hd2_mode)
Meng Wang15c825d2018-09-06 10:49:18 +08002253 rx_macro_hd2_control(
2254 component, interp_idx, event);
2255 rx_macro_hphdelay_lutbypass(component, rx_priv,
2256 interp_idx, event);
2257 rx_macro_config_compander(component, rx_priv,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302258 interp_idx, event);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302259 if (interp_idx == INTERP_AUX)
Meng Wang15c825d2018-09-06 10:49:18 +08002260 rx_macro_config_softclip(component, rx_priv,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302261 event);
Meng Wang15c825d2018-09-06 10:49:18 +08002262 rx_macro_config_classh(component, rx_priv,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302263 interp_idx, event);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302264 }
2265 rx_priv->main_clk_users[interp_idx]++;
2266 }
2267
2268 if (SND_SOC_DAPM_EVENT_OFF(event)) {
2269 rx_priv->main_clk_users[interp_idx]--;
2270 if (rx_priv->main_clk_users[interp_idx] <= 0) {
2271 rx_priv->main_clk_users[interp_idx] = 0;
Karthikeyan Manic14c27a2019-06-21 14:11:34 -07002272 /* Main path PGA mute enable */
2273 snd_soc_component_update_bits(component, main_reg,
2274 0x10, 0x10);
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302275 /* Clk Disable */
Meng Wang15c825d2018-09-06 10:49:18 +08002276 snd_soc_component_update_bits(component, dsm_reg,
2277 0x01, 0x00);
2278 snd_soc_component_update_bits(component, main_reg,
2279 0x20, 0x00);
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302280 /* Reset enable and disable */
Meng Wang15c825d2018-09-06 10:49:18 +08002281 snd_soc_component_update_bits(component, main_reg,
2282 0x40, 0x40);
2283 snd_soc_component_update_bits(component, main_reg,
2284 0x40, 0x00);
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302285 /* Reset rate to 48K*/
Meng Wang15c825d2018-09-06 10:49:18 +08002286 snd_soc_component_update_bits(component, main_reg,
2287 0x0F, 0x04);
2288 snd_soc_component_update_bits(component, rx_cfg2_reg,
2289 0x03, 0x00);
2290 rx_macro_config_classh(component, rx_priv,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302291 interp_idx, event);
Meng Wang15c825d2018-09-06 10:49:18 +08002292 rx_macro_config_compander(component, rx_priv,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302293 interp_idx, event);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302294 if (interp_idx == INTERP_AUX)
Meng Wang15c825d2018-09-06 10:49:18 +08002295 rx_macro_config_softclip(component, rx_priv,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302296 event);
Meng Wang15c825d2018-09-06 10:49:18 +08002297 rx_macro_hphdelay_lutbypass(component, rx_priv,
2298 interp_idx, event);
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05302299 if (rx_priv->hph_hd2_mode)
Meng Wang15c825d2018-09-06 10:49:18 +08002300 rx_macro_hd2_control(component, interp_idx,
2301 event);
2302 rx_macro_idle_detect_control(component, rx_priv,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302303 interp_idx, event);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302304 }
2305 }
2306
Meng Wang15c825d2018-09-06 10:49:18 +08002307 dev_dbg(component->dev, "%s event %d main_clk_users %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302308 __func__, event, rx_priv->main_clk_users[interp_idx]);
2309
2310 return rx_priv->main_clk_users[interp_idx];
2311}
2312
2313static int rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w,
2314 struct snd_kcontrol *kcontrol, int event)
2315{
Meng Wang15c825d2018-09-06 10:49:18 +08002316 struct snd_soc_component *component =
2317 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302318 u16 sidetone_reg = 0;
2319
Meng Wang15c825d2018-09-06 10:49:18 +08002320 dev_dbg(component->dev, "%s %d %d\n", __func__, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302321 sidetone_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG1 +
2322 RX_MACRO_RX_PATH_OFFSET * (w->shift);
2323
2324 switch (event) {
2325 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08002326 rx_macro_enable_interp_clk(component, event, w->shift);
2327 snd_soc_component_update_bits(component, sidetone_reg,
2328 0x10, 0x10);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302329 break;
2330 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08002331 snd_soc_component_update_bits(component, sidetone_reg,
2332 0x10, 0x00);
2333 rx_macro_enable_interp_clk(component, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302334 break;
2335 default:
2336 break;
2337 };
2338 return 0;
2339}
2340
2341static void rx_macro_restore_iir_coeff(struct rx_macro_priv *rx_priv, int iir_idx,
2342 int band_idx)
2343{
2344 u16 reg_add = 0, coeff_idx = 0, idx = 0;
2345 struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL);
2346
Tanya Dixit8530fb92018-09-14 16:01:25 +05302347 if (regmap == NULL) {
2348 dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__);
2349 return;
2350 }
2351
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302352 regmap_write(regmap,
2353 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
2354 (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
2355
2356 reg_add = BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx;
2357
2358 /* 5 coefficients per band and 4 writes per coefficient */
2359 for (coeff_idx = 0; coeff_idx < RX_MACRO_SIDETONE_IIR_COEFF_MAX;
2360 coeff_idx++) {
2361 /* Four 8 bit values(one 32 bit) per coefficient */
2362 regmap_write(regmap, reg_add,
2363 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
2364 regmap_write(regmap, reg_add,
2365 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
2366 regmap_write(regmap, reg_add,
2367 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
2368 regmap_write(regmap, reg_add,
2369 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
2370 }
2371}
2372
2373static int rx_macro_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol,
2374 struct snd_ctl_elem_value *ucontrol)
2375{
Meng Wang15c825d2018-09-06 10:49:18 +08002376 struct snd_soc_component *component =
2377 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302378 int iir_idx = ((struct soc_multi_mixer_control *)
2379 kcontrol->private_value)->reg;
2380 int band_idx = ((struct soc_multi_mixer_control *)
2381 kcontrol->private_value)->shift;
2382 /* IIR filter band registers are at integer multiples of 0x80 */
2383 u16 iir_reg = BOLERO_CDC_RX_SIDETONE_IIR0_IIR_CTL + 0x80 * iir_idx;
2384
Meng Wang15c825d2018-09-06 10:49:18 +08002385 ucontrol->value.integer.value[0] = (
2386 snd_soc_component_read32(component, iir_reg) &
2387 (1 << band_idx)) != 0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302388
Meng Wang15c825d2018-09-06 10:49:18 +08002389 dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302390 iir_idx, band_idx,
2391 (uint32_t)ucontrol->value.integer.value[0]);
2392 return 0;
2393}
2394
2395static int rx_macro_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol,
2396 struct snd_ctl_elem_value *ucontrol)
2397{
Meng Wang15c825d2018-09-06 10:49:18 +08002398 struct snd_soc_component *component =
2399 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302400 int iir_idx = ((struct soc_multi_mixer_control *)
2401 kcontrol->private_value)->reg;
2402 int band_idx = ((struct soc_multi_mixer_control *)
2403 kcontrol->private_value)->shift;
2404 bool iir_band_en_status = 0;
2405 int value = ucontrol->value.integer.value[0];
2406 u16 iir_reg = BOLERO_CDC_RX_SIDETONE_IIR0_IIR_CTL + 0x80 * iir_idx;
2407 struct device *rx_dev = NULL;
2408 struct rx_macro_priv *rx_priv = NULL;
2409
Meng Wang15c825d2018-09-06 10:49:18 +08002410 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302411 return -EINVAL;
2412
2413 rx_macro_restore_iir_coeff(rx_priv, iir_idx, band_idx);
2414
2415 /* Mask first 5 bits, 6-8 are reserved */
Meng Wang15c825d2018-09-06 10:49:18 +08002416 snd_soc_component_update_bits(component, iir_reg, (1 << band_idx),
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302417 (value << band_idx));
2418
Meng Wang15c825d2018-09-06 10:49:18 +08002419 iir_band_en_status = ((snd_soc_component_read32(component, iir_reg) &
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302420 (1 << band_idx)) != 0);
Meng Wang15c825d2018-09-06 10:49:18 +08002421 dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302422 iir_idx, band_idx, iir_band_en_status);
2423 return 0;
2424}
2425
Meng Wang15c825d2018-09-06 10:49:18 +08002426static uint32_t get_iir_band_coeff(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302427 int iir_idx, int band_idx,
2428 int coeff_idx)
2429{
2430 uint32_t value = 0;
2431
2432 /* Address does not automatically update if reading */
Meng Wang15c825d2018-09-06 10:49:18 +08002433 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302434 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
2435 ((band_idx * BAND_MAX + coeff_idx)
2436 * sizeof(uint32_t)) & 0x7F);
2437
Meng Wang15c825d2018-09-06 10:49:18 +08002438 value |= snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302439 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx));
2440
Meng Wang15c825d2018-09-06 10:49:18 +08002441 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302442 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
2443 ((band_idx * BAND_MAX + coeff_idx)
2444 * sizeof(uint32_t) + 1) & 0x7F);
2445
Meng Wang15c825d2018-09-06 10:49:18 +08002446 value |= (snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302447 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2448 0x80 * iir_idx)) << 8);
2449
Meng Wang15c825d2018-09-06 10:49:18 +08002450 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302451 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
2452 ((band_idx * BAND_MAX + coeff_idx)
2453 * sizeof(uint32_t) + 2) & 0x7F);
2454
Meng Wang15c825d2018-09-06 10:49:18 +08002455 value |= (snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302456 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2457 0x80 * iir_idx)) << 16);
2458
Meng Wang15c825d2018-09-06 10:49:18 +08002459 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302460 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
2461 ((band_idx * BAND_MAX + coeff_idx)
2462 * sizeof(uint32_t) + 3) & 0x7F);
2463
2464 /* Mask bits top 2 bits since they are reserved */
Meng Wang15c825d2018-09-06 10:49:18 +08002465 value |= ((snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302466 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2467 16 * iir_idx)) & 0x3F) << 24);
2468
2469 return value;
2470}
2471
2472static int rx_macro_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol,
2473 struct snd_ctl_elem_value *ucontrol)
2474{
Meng Wang15c825d2018-09-06 10:49:18 +08002475 struct snd_soc_component *component =
2476 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302477 int iir_idx = ((struct soc_multi_mixer_control *)
2478 kcontrol->private_value)->reg;
2479 int band_idx = ((struct soc_multi_mixer_control *)
2480 kcontrol->private_value)->shift;
2481
2482 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08002483 get_iir_band_coeff(component, iir_idx, band_idx, 0);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302484 ucontrol->value.integer.value[1] =
Meng Wang15c825d2018-09-06 10:49:18 +08002485 get_iir_band_coeff(component, iir_idx, band_idx, 1);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302486 ucontrol->value.integer.value[2] =
Meng Wang15c825d2018-09-06 10:49:18 +08002487 get_iir_band_coeff(component, iir_idx, band_idx, 2);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302488 ucontrol->value.integer.value[3] =
Meng Wang15c825d2018-09-06 10:49:18 +08002489 get_iir_band_coeff(component, iir_idx, band_idx, 3);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302490 ucontrol->value.integer.value[4] =
Meng Wang15c825d2018-09-06 10:49:18 +08002491 get_iir_band_coeff(component, iir_idx, band_idx, 4);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302492
Meng Wang15c825d2018-09-06 10:49:18 +08002493 dev_dbg(component->dev, "%s: IIR #%d band #%d b0 = 0x%x\n"
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302494 "%s: IIR #%d band #%d b1 = 0x%x\n"
2495 "%s: IIR #%d band #%d b2 = 0x%x\n"
2496 "%s: IIR #%d band #%d a1 = 0x%x\n"
2497 "%s: IIR #%d band #%d a2 = 0x%x\n",
2498 __func__, iir_idx, band_idx,
2499 (uint32_t)ucontrol->value.integer.value[0],
2500 __func__, iir_idx, band_idx,
2501 (uint32_t)ucontrol->value.integer.value[1],
2502 __func__, iir_idx, band_idx,
2503 (uint32_t)ucontrol->value.integer.value[2],
2504 __func__, iir_idx, band_idx,
2505 (uint32_t)ucontrol->value.integer.value[3],
2506 __func__, iir_idx, band_idx,
2507 (uint32_t)ucontrol->value.integer.value[4]);
2508 return 0;
2509}
2510
Meng Wang15c825d2018-09-06 10:49:18 +08002511static void set_iir_band_coeff(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302512 int iir_idx, int band_idx,
2513 uint32_t value)
2514{
Meng Wang15c825d2018-09-06 10:49:18 +08002515 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302516 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx),
2517 (value & 0xFF));
2518
Meng Wang15c825d2018-09-06 10:49:18 +08002519 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302520 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx),
2521 (value >> 8) & 0xFF);
2522
Meng Wang15c825d2018-09-06 10:49:18 +08002523 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302524 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx),
2525 (value >> 16) & 0xFF);
2526
2527 /* Mask top 2 bits, 7-8 are reserved */
Meng Wang15c825d2018-09-06 10:49:18 +08002528 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302529 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx),
2530 (value >> 24) & 0x3F);
2531}
2532
2533static int rx_macro_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol,
2534 struct snd_ctl_elem_value *ucontrol)
2535{
Meng Wang15c825d2018-09-06 10:49:18 +08002536 struct snd_soc_component *component =
2537 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302538 int iir_idx = ((struct soc_multi_mixer_control *)
2539 kcontrol->private_value)->reg;
2540 int band_idx = ((struct soc_multi_mixer_control *)
2541 kcontrol->private_value)->shift;
2542 int coeff_idx, idx = 0;
2543 struct device *rx_dev = NULL;
2544 struct rx_macro_priv *rx_priv = NULL;
2545
Meng Wang15c825d2018-09-06 10:49:18 +08002546 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302547 return -EINVAL;
2548
2549 /*
2550 * Mask top bit it is reserved
2551 * Updates addr automatically for each B2 write
2552 */
Meng Wang15c825d2018-09-06 10:49:18 +08002553 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302554 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2555 (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
2556
2557 /* Store the coefficients in sidetone coeff array */
2558 for (coeff_idx = 0; coeff_idx < RX_MACRO_SIDETONE_IIR_COEFF_MAX;
2559 coeff_idx++) {
2560 uint32_t value = ucontrol->value.integer.value[coeff_idx];
2561
Meng Wang15c825d2018-09-06 10:49:18 +08002562 set_iir_band_coeff(component, iir_idx, band_idx, value);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302563
2564 /* Four 8 bit values(one 32 bit) per coefficient */
2565 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
2566 (value & 0xFF);
2567 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
2568 (value >> 8) & 0xFF;
2569 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
2570 (value >> 16) & 0xFF;
2571 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
2572 (value >> 24) & 0xFF;
2573 }
2574
2575 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
2576 "%s: IIR #%d band #%d b1 = 0x%x\n"
2577 "%s: IIR #%d band #%d b2 = 0x%x\n"
2578 "%s: IIR #%d band #%d a1 = 0x%x\n"
2579 "%s: IIR #%d band #%d a2 = 0x%x\n",
2580 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08002581 get_iir_band_coeff(component, iir_idx, band_idx, 0),
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302582 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08002583 get_iir_band_coeff(component, iir_idx, band_idx, 1),
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302584 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08002585 get_iir_band_coeff(component, iir_idx, band_idx, 2),
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302586 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08002587 get_iir_band_coeff(component, iir_idx, band_idx, 3),
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302588 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08002589 get_iir_band_coeff(component, iir_idx, band_idx, 4));
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302590 return 0;
2591}
2592
2593static int rx_macro_set_iir_gain(struct snd_soc_dapm_widget *w,
2594 struct snd_kcontrol *kcontrol, int event)
2595{
Meng Wang15c825d2018-09-06 10:49:18 +08002596 struct snd_soc_component *component =
2597 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302598
Meng Wang15c825d2018-09-06 10:49:18 +08002599 dev_dbg(component->dev, "%s: event = %d\n", __func__, event);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302600
2601 switch (event) {
2602 case SND_SOC_DAPM_POST_PMU: /* fall through */
2603 case SND_SOC_DAPM_PRE_PMD:
2604 if (strnstr(w->name, "IIR0", sizeof("IIR0"))) {
Meng Wang15c825d2018-09-06 10:49:18 +08002605 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302606 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002607 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302608 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002609 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302610 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002611 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302612 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002613 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302614 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002615 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302616 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002617 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302618 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002619 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302620 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL));
2621 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08002622 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302623 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002624 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302625 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002626 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302627 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002628 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302629 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002630 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302631 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002632 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302633 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002634 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302635 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002636 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302637 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL));
2638 }
2639 break;
2640 }
2641 return 0;
2642}
2643
2644static const struct snd_kcontrol_new rx_macro_snd_controls[] = {
2645 SOC_SINGLE_SX_TLV("RX_RX0 Digital Volume",
2646 BOLERO_CDC_RX_RX0_RX_VOL_CTL,
2647 0, -84, 40, digital_gain),
2648 SOC_SINGLE_SX_TLV("RX_RX1 Digital Volume",
2649 BOLERO_CDC_RX_RX1_RX_VOL_CTL,
2650 0, -84, 40, digital_gain),
2651 SOC_SINGLE_SX_TLV("RX_RX2 Digital Volume",
2652 BOLERO_CDC_RX_RX2_RX_VOL_CTL,
2653 0, -84, 40, digital_gain),
2654 SOC_SINGLE_SX_TLV("RX_RX0 Mix Digital Volume",
2655 BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
2656 SOC_SINGLE_SX_TLV("RX_RX1 Mix Digital Volume",
2657 BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
2658 SOC_SINGLE_SX_TLV("RX_RX2 Mix Digital Volume",
2659 BOLERO_CDC_RX_RX2_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
2660
2661 SOC_SINGLE_EXT("RX_COMP1 Switch", SND_SOC_NOPM, RX_MACRO_COMP1, 1, 0,
2662 rx_macro_get_compander, rx_macro_set_compander),
2663 SOC_SINGLE_EXT("RX_COMP2 Switch", SND_SOC_NOPM, RX_MACRO_COMP2, 1, 0,
2664 rx_macro_get_compander, rx_macro_set_compander),
2665
Vatsal Bucha8bcc97c2019-01-07 13:18:11 +05302666 SOC_ENUM_EXT("HPH Idle Detect", hph_idle_detect_enum,
2667 rx_macro_hph_idle_detect_get, rx_macro_hph_idle_detect_put),
2668
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302669 SOC_ENUM_EXT("RX_EAR Mode", rx_macro_ear_mode_enum,
2670 rx_macro_get_ear_mode, rx_macro_put_ear_mode),
2671
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05302672 SOC_ENUM_EXT("RX_HPH HD2 Mode", rx_macro_hph_hd2_mode_enum,
2673 rx_macro_get_hph_hd2_mode, rx_macro_put_hph_hd2_mode),
2674
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05302675 SOC_ENUM_EXT("RX_HPH_PWR_MODE", rx_macro_hph_pwr_mode_enum,
2676 rx_macro_get_hph_pwr_mode, rx_macro_put_hph_pwr_mode),
2677
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302678 SOC_ENUM_EXT("RX_GSM mode Enable", rx_macro_vbat_bcl_gsm_mode_enum,
2679 rx_macro_vbat_bcl_gsm_mode_func_get,
2680 rx_macro_vbat_bcl_gsm_mode_func_put),
2681 SOC_SINGLE_EXT("RX_Softclip Enable", SND_SOC_NOPM, 0, 1, 0,
2682 rx_macro_soft_clip_enable_get,
2683 rx_macro_soft_clip_enable_put),
2684
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302685 SOC_SINGLE_SX_TLV("IIR0 INP0 Volume",
2686 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40,
2687 digital_gain),
2688 SOC_SINGLE_SX_TLV("IIR0 INP1 Volume",
2689 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84, 40,
2690 digital_gain),
2691 SOC_SINGLE_SX_TLV("IIR0 INP2 Volume",
2692 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84, 40,
2693 digital_gain),
2694 SOC_SINGLE_SX_TLV("IIR0 INP3 Volume",
2695 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84, 40,
2696 digital_gain),
2697 SOC_SINGLE_SX_TLV("IIR1 INP0 Volume",
2698 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0, -84, 40,
2699 digital_gain),
2700 SOC_SINGLE_SX_TLV("IIR1 INP1 Volume",
2701 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0, -84, 40,
2702 digital_gain),
2703 SOC_SINGLE_SX_TLV("IIR1 INP2 Volume",
2704 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0, -84, 40,
2705 digital_gain),
2706 SOC_SINGLE_SX_TLV("IIR1 INP3 Volume",
2707 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0, -84, 40,
2708 digital_gain),
2709
2710 SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0,
2711 rx_macro_iir_enable_audio_mixer_get,
2712 rx_macro_iir_enable_audio_mixer_put),
2713 SOC_SINGLE_EXT("IIR0 Enable Band2", IIR0, BAND2, 1, 0,
2714 rx_macro_iir_enable_audio_mixer_get,
2715 rx_macro_iir_enable_audio_mixer_put),
2716 SOC_SINGLE_EXT("IIR0 Enable Band3", IIR0, BAND3, 1, 0,
2717 rx_macro_iir_enable_audio_mixer_get,
2718 rx_macro_iir_enable_audio_mixer_put),
2719 SOC_SINGLE_EXT("IIR0 Enable Band4", IIR0, BAND4, 1, 0,
2720 rx_macro_iir_enable_audio_mixer_get,
2721 rx_macro_iir_enable_audio_mixer_put),
2722 SOC_SINGLE_EXT("IIR0 Enable Band5", IIR0, BAND5, 1, 0,
2723 rx_macro_iir_enable_audio_mixer_get,
2724 rx_macro_iir_enable_audio_mixer_put),
2725 SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
2726 rx_macro_iir_enable_audio_mixer_get,
2727 rx_macro_iir_enable_audio_mixer_put),
2728 SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
2729 rx_macro_iir_enable_audio_mixer_get,
2730 rx_macro_iir_enable_audio_mixer_put),
2731 SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
2732 rx_macro_iir_enable_audio_mixer_get,
2733 rx_macro_iir_enable_audio_mixer_put),
2734 SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
2735 rx_macro_iir_enable_audio_mixer_get,
2736 rx_macro_iir_enable_audio_mixer_put),
2737 SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
2738 rx_macro_iir_enable_audio_mixer_get,
2739 rx_macro_iir_enable_audio_mixer_put),
2740
2741 SOC_SINGLE_MULTI_EXT("IIR0 Band1", IIR0, BAND1, 255, 0, 5,
2742 rx_macro_iir_band_audio_mixer_get,
2743 rx_macro_iir_band_audio_mixer_put),
2744 SOC_SINGLE_MULTI_EXT("IIR0 Band2", IIR0, BAND2, 255, 0, 5,
2745 rx_macro_iir_band_audio_mixer_get,
2746 rx_macro_iir_band_audio_mixer_put),
2747 SOC_SINGLE_MULTI_EXT("IIR0 Band3", IIR0, BAND3, 255, 0, 5,
2748 rx_macro_iir_band_audio_mixer_get,
2749 rx_macro_iir_band_audio_mixer_put),
2750 SOC_SINGLE_MULTI_EXT("IIR0 Band4", IIR0, BAND4, 255, 0, 5,
2751 rx_macro_iir_band_audio_mixer_get,
2752 rx_macro_iir_band_audio_mixer_put),
2753 SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5,
2754 rx_macro_iir_band_audio_mixer_get,
2755 rx_macro_iir_band_audio_mixer_put),
2756 SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
2757 rx_macro_iir_band_audio_mixer_get,
2758 rx_macro_iir_band_audio_mixer_put),
2759 SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
2760 rx_macro_iir_band_audio_mixer_get,
2761 rx_macro_iir_band_audio_mixer_put),
2762 SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
2763 rx_macro_iir_band_audio_mixer_get,
2764 rx_macro_iir_band_audio_mixer_put),
2765 SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
2766 rx_macro_iir_band_audio_mixer_get,
2767 rx_macro_iir_band_audio_mixer_put),
2768 SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
2769 rx_macro_iir_band_audio_mixer_get,
2770 rx_macro_iir_band_audio_mixer_put),
2771};
2772
Vatsal Buchac2d6c222018-11-30 18:46:37 +05302773static int rx_macro_enable_echo(struct snd_soc_dapm_widget *w,
2774 struct snd_kcontrol *kcontrol,
2775 int event)
2776{
2777 struct snd_soc_component *component =
2778 snd_soc_dapm_to_component(w->dapm);
2779 struct device *rx_dev = NULL;
2780 struct rx_macro_priv *rx_priv = NULL;
2781 u16 val = 0, ec_hq_reg = 0;
2782 int ec_tx = 0;
2783
2784 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
2785 return -EINVAL;
2786
2787 dev_dbg(rx_dev, "%s %d %s\n", __func__, event, w->name);
2788
2789 val = snd_soc_component_read32(component,
2790 BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4);
2791 if (!(strcmp(w->name, "RX MIX TX0 MUX")))
2792 ec_tx = ((val & 0xf0) >> 0x4) - 1;
2793 else if (!(strcmp(w->name, "RX MIX TX1 MUX")))
2794 ec_tx = (val & 0x0f) - 1;
2795
2796 val = snd_soc_component_read32(component,
2797 BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5);
2798 if (!(strcmp(w->name, "RX MIX TX2 MUX")))
2799 ec_tx = (val & 0x0f) - 1;
2800
2801 if (ec_tx < 0 || (ec_tx >= RX_MACRO_EC_MUX_MAX)) {
2802 dev_err(rx_dev, "%s: EC mix control not set correctly\n",
2803 __func__);
2804 return -EINVAL;
2805 }
2806 ec_hq_reg = BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL +
2807 0x40 * ec_tx;
2808 snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01);
2809 ec_hq_reg = BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0 +
2810 0x40 * ec_tx;
2811 /* default set to 48k */
2812 snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08);
2813
2814 return 0;
2815}
2816
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302817static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = {
2818 SND_SOC_DAPM_AIF_IN("RX AIF1 PB", "RX_MACRO_AIF1 Playback", 0,
2819 SND_SOC_NOPM, 0, 0),
2820
2821 SND_SOC_DAPM_AIF_IN("RX AIF2 PB", "RX_MACRO_AIF2 Playback", 0,
2822 SND_SOC_NOPM, 0, 0),
2823
2824 SND_SOC_DAPM_AIF_IN("RX AIF3 PB", "RX_MACRO_AIF3 Playback", 0,
2825 SND_SOC_NOPM, 0, 0),
2826
2827 SND_SOC_DAPM_AIF_IN("RX AIF4 PB", "RX_MACRO_AIF4 Playback", 0,
2828 SND_SOC_NOPM, 0, 0),
2829
Vatsal Buchac2d6c222018-11-30 18:46:37 +05302830 SND_SOC_DAPM_AIF_OUT("RX AIF_ECHO", "RX_AIF_ECHO Capture", 0,
2831 SND_SOC_NOPM, 0, 0),
2832
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302833 RX_MACRO_DAPM_MUX("RX_MACRO RX0 MUX", RX_MACRO_RX0, rx_macro_rx0),
2834 RX_MACRO_DAPM_MUX("RX_MACRO RX1 MUX", RX_MACRO_RX1, rx_macro_rx1),
2835 RX_MACRO_DAPM_MUX("RX_MACRO RX2 MUX", RX_MACRO_RX2, rx_macro_rx2),
2836 RX_MACRO_DAPM_MUX("RX_MACRO RX3 MUX", RX_MACRO_RX3, rx_macro_rx3),
2837 RX_MACRO_DAPM_MUX("RX_MACRO RX4 MUX", RX_MACRO_RX4, rx_macro_rx4),
2838 RX_MACRO_DAPM_MUX("RX_MACRO RX5 MUX", RX_MACRO_RX5, rx_macro_rx5),
2839
2840 SND_SOC_DAPM_MIXER("RX_RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2841 SND_SOC_DAPM_MIXER("RX_RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2842 SND_SOC_DAPM_MIXER("RX_RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
2843 SND_SOC_DAPM_MIXER("RX_RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
2844 SND_SOC_DAPM_MIXER("RX_RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
2845 SND_SOC_DAPM_MIXER("RX_RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
2846
2847 RX_MACRO_DAPM_MUX("IIR0 INP0 MUX", 0, iir0_inp0),
2848 RX_MACRO_DAPM_MUX("IIR0 INP1 MUX", 0, iir0_inp1),
2849 RX_MACRO_DAPM_MUX("IIR0 INP2 MUX", 0, iir0_inp2),
2850 RX_MACRO_DAPM_MUX("IIR0 INP3 MUX", 0, iir0_inp3),
2851 RX_MACRO_DAPM_MUX("IIR1 INP0 MUX", 0, iir1_inp0),
2852 RX_MACRO_DAPM_MUX("IIR1 INP1 MUX", 0, iir1_inp1),
2853 RX_MACRO_DAPM_MUX("IIR1 INP2 MUX", 0, iir1_inp2),
2854 RX_MACRO_DAPM_MUX("IIR1 INP3 MUX", 0, iir1_inp3),
2855
Vatsal Buchac2d6c222018-11-30 18:46:37 +05302856 SND_SOC_DAPM_MUX_E("RX MIX TX0 MUX", SND_SOC_NOPM,
2857 RX_MACRO_EC0_MUX, 0,
2858 &rx_mix_tx0_mux, rx_macro_enable_echo,
2859 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2860 SND_SOC_DAPM_MUX_E("RX MIX TX1 MUX", SND_SOC_NOPM,
2861 RX_MACRO_EC1_MUX, 0,
2862 &rx_mix_tx1_mux, rx_macro_enable_echo,
2863 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2864 SND_SOC_DAPM_MUX_E("RX MIX TX2 MUX", SND_SOC_NOPM,
2865 RX_MACRO_EC2_MUX, 0,
2866 &rx_mix_tx2_mux, rx_macro_enable_echo,
2867 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2868
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302869 SND_SOC_DAPM_MIXER_E("IIR0", BOLERO_CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL,
2870 4, 0, NULL, 0, rx_macro_set_iir_gain,
2871 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2872 SND_SOC_DAPM_MIXER_E("IIR1", BOLERO_CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL,
2873 4, 0, NULL, 0, rx_macro_set_iir_gain,
2874 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2875 SND_SOC_DAPM_MIXER("SRC0", BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL,
2876 4, 0, NULL, 0),
2877 SND_SOC_DAPM_MIXER("SRC1", BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL,
2878 4, 0, NULL, 0),
2879
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302880 RX_MACRO_DAPM_MUX("RX INT0 DEM MUX", 0, rx_int0_dem_inp),
2881 RX_MACRO_DAPM_MUX("RX INT1 DEM MUX", 0, rx_int1_dem_inp),
2882
2883 SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", SND_SOC_NOPM, INTERP_HPHL, 0,
2884 &rx_int0_2_mux, rx_macro_enable_mix_path,
2885 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2886 SND_SOC_DAPM_POST_PMD),
2887 SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", SND_SOC_NOPM, INTERP_HPHR, 0,
2888 &rx_int1_2_mux, rx_macro_enable_mix_path,
2889 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2890 SND_SOC_DAPM_POST_PMD),
2891 SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", SND_SOC_NOPM, INTERP_AUX, 0,
2892 &rx_int2_2_mux, rx_macro_enable_mix_path,
2893 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2894 SND_SOC_DAPM_POST_PMD),
2895
2896 RX_MACRO_DAPM_MUX("RX INT0_1 MIX1 INP0", 0, rx_int0_1_mix_inp0),
2897 RX_MACRO_DAPM_MUX("RX INT0_1 MIX1 INP1", 0, rx_int0_1_mix_inp1),
2898 RX_MACRO_DAPM_MUX("RX INT0_1 MIX1 INP2", 0, rx_int0_1_mix_inp2),
2899 RX_MACRO_DAPM_MUX("RX INT1_1 MIX1 INP0", 0, rx_int1_1_mix_inp0),
2900 RX_MACRO_DAPM_MUX("RX INT1_1 MIX1 INP1", 0, rx_int1_1_mix_inp1),
2901 RX_MACRO_DAPM_MUX("RX INT1_1 MIX1 INP2", 0, rx_int1_1_mix_inp2),
2902 RX_MACRO_DAPM_MUX("RX INT2_1 MIX1 INP0", 0, rx_int2_1_mix_inp0),
2903 RX_MACRO_DAPM_MUX("RX INT2_1 MIX1 INP1", 0, rx_int2_1_mix_inp1),
2904 RX_MACRO_DAPM_MUX("RX INT2_1 MIX1 INP2", 0, rx_int2_1_mix_inp2),
2905
2906 SND_SOC_DAPM_MUX_E("RX INT0_1 INTERP", SND_SOC_NOPM, INTERP_HPHL, 0,
2907 &rx_int0_1_interp_mux, rx_macro_enable_main_path,
2908 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2909 SND_SOC_DAPM_POST_PMD),
2910 SND_SOC_DAPM_MUX_E("RX INT1_1 INTERP", SND_SOC_NOPM, INTERP_HPHR, 0,
2911 &rx_int1_1_interp_mux, rx_macro_enable_main_path,
2912 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2913 SND_SOC_DAPM_POST_PMD),
2914 SND_SOC_DAPM_MUX_E("RX INT2_1 INTERP", SND_SOC_NOPM, INTERP_AUX, 0,
2915 &rx_int2_1_interp_mux, rx_macro_enable_main_path,
2916 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2917 SND_SOC_DAPM_POST_PMD),
2918
2919 RX_MACRO_DAPM_MUX("RX INT0_2 INTERP", 0, rx_int0_2_interp),
2920 RX_MACRO_DAPM_MUX("RX INT1_2 INTERP", 0, rx_int1_2_interp),
2921 RX_MACRO_DAPM_MUX("RX INT2_2 INTERP", 0, rx_int2_2_interp),
2922
2923 SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2924 SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2925 SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2926 SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2927 SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2928 SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2929
2930 SND_SOC_DAPM_MUX_E("RX INT0 MIX2 INP", SND_SOC_NOPM, INTERP_HPHL,
2931 0, &rx_int0_mix2_inp_mux, rx_macro_enable_rx_path_clk,
2932 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2933 SND_SOC_DAPM_MUX_E("RX INT1 MIX2 INP", SND_SOC_NOPM, INTERP_HPHR,
2934 0, &rx_int1_mix2_inp_mux, rx_macro_enable_rx_path_clk,
2935 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2936 SND_SOC_DAPM_MUX_E("RX INT2 MIX2 INP", SND_SOC_NOPM, INTERP_AUX,
2937 0, &rx_int2_mix2_inp_mux, rx_macro_enable_rx_path_clk,
2938 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2939
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302940 SND_SOC_DAPM_MIXER_E("RX INT2_1 VBAT", SND_SOC_NOPM,
2941 0, 0, rx_int2_1_vbat_mix_switch,
2942 ARRAY_SIZE(rx_int2_1_vbat_mix_switch),
2943 rx_macro_enable_vbat,
2944 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2945
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302946 SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
2947 SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
2948 SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
2949
2950 SND_SOC_DAPM_OUTPUT("HPHL_OUT"),
2951 SND_SOC_DAPM_OUTPUT("HPHR_OUT"),
2952 SND_SOC_DAPM_OUTPUT("AUX_OUT"),
2953
2954 SND_SOC_DAPM_INPUT("RX_TX DEC0_INP"),
2955 SND_SOC_DAPM_INPUT("RX_TX DEC1_INP"),
2956 SND_SOC_DAPM_INPUT("RX_TX DEC2_INP"),
2957 SND_SOC_DAPM_INPUT("RX_TX DEC3_INP"),
2958
2959 SND_SOC_DAPM_SUPPLY_S("RX_MCLK", 0, SND_SOC_NOPM, 0, 0,
2960 rx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2961};
2962
2963static const struct snd_soc_dapm_route rx_audio_map[] = {
2964 {"RX AIF1 PB", NULL, "RX_MCLK"},
2965 {"RX AIF2 PB", NULL, "RX_MCLK"},
2966 {"RX AIF3 PB", NULL, "RX_MCLK"},
2967 {"RX AIF4 PB", NULL, "RX_MCLK"},
2968
2969 {"RX_MACRO RX0 MUX", "AIF1_PB", "RX AIF1 PB"},
2970 {"RX_MACRO RX1 MUX", "AIF1_PB", "RX AIF1 PB"},
2971 {"RX_MACRO RX2 MUX", "AIF1_PB", "RX AIF1 PB"},
2972 {"RX_MACRO RX3 MUX", "AIF1_PB", "RX AIF1 PB"},
2973 {"RX_MACRO RX4 MUX", "AIF1_PB", "RX AIF1 PB"},
2974 {"RX_MACRO RX5 MUX", "AIF1_PB", "RX AIF1 PB"},
2975
2976 {"RX_MACRO RX0 MUX", "AIF2_PB", "RX AIF2 PB"},
2977 {"RX_MACRO RX1 MUX", "AIF2_PB", "RX AIF2 PB"},
2978 {"RX_MACRO RX2 MUX", "AIF2_PB", "RX AIF2 PB"},
2979 {"RX_MACRO RX3 MUX", "AIF2_PB", "RX AIF2 PB"},
2980 {"RX_MACRO RX4 MUX", "AIF2_PB", "RX AIF2 PB"},
2981 {"RX_MACRO RX5 MUX", "AIF2_PB", "RX AIF2 PB"},
2982
2983 {"RX_MACRO RX0 MUX", "AIF3_PB", "RX AIF3 PB"},
2984 {"RX_MACRO RX1 MUX", "AIF3_PB", "RX AIF3 PB"},
2985 {"RX_MACRO RX2 MUX", "AIF3_PB", "RX AIF3 PB"},
2986 {"RX_MACRO RX3 MUX", "AIF3_PB", "RX AIF3 PB"},
2987 {"RX_MACRO RX4 MUX", "AIF3_PB", "RX AIF3 PB"},
2988 {"RX_MACRO RX5 MUX", "AIF3_PB", "RX AIF3 PB"},
2989
2990 {"RX_MACRO RX0 MUX", "AIF4_PB", "RX AIF4 PB"},
2991 {"RX_MACRO RX1 MUX", "AIF4_PB", "RX AIF4 PB"},
2992 {"RX_MACRO RX2 MUX", "AIF4_PB", "RX AIF4 PB"},
2993 {"RX_MACRO RX3 MUX", "AIF4_PB", "RX AIF4 PB"},
2994 {"RX_MACRO RX4 MUX", "AIF4_PB", "RX AIF4 PB"},
2995 {"RX_MACRO RX5 MUX", "AIF4_PB", "RX AIF4 PB"},
2996
2997 {"RX_RX0", NULL, "RX_MACRO RX0 MUX"},
2998 {"RX_RX1", NULL, "RX_MACRO RX1 MUX"},
2999 {"RX_RX2", NULL, "RX_MACRO RX2 MUX"},
3000 {"RX_RX3", NULL, "RX_MACRO RX3 MUX"},
3001 {"RX_RX4", NULL, "RX_MACRO RX4 MUX"},
3002 {"RX_RX5", NULL, "RX_MACRO RX5 MUX"},
3003
3004 {"RX INT0_1 MIX1 INP0", "RX0", "RX_RX0"},
3005 {"RX INT0_1 MIX1 INP0", "RX1", "RX_RX1"},
3006 {"RX INT0_1 MIX1 INP0", "RX2", "RX_RX2"},
3007 {"RX INT0_1 MIX1 INP0", "RX3", "RX_RX3"},
3008 {"RX INT0_1 MIX1 INP0", "RX4", "RX_RX4"},
3009 {"RX INT0_1 MIX1 INP0", "RX5", "RX_RX5"},
3010 {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"},
3011 {"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"},
3012 {"RX INT0_1 MIX1 INP1", "RX0", "RX_RX0"},
3013 {"RX INT0_1 MIX1 INP1", "RX1", "RX_RX1"},
3014 {"RX INT0_1 MIX1 INP1", "RX2", "RX_RX2"},
3015 {"RX INT0_1 MIX1 INP1", "RX3", "RX_RX3"},
3016 {"RX INT0_1 MIX1 INP1", "RX4", "RX_RX4"},
3017 {"RX INT0_1 MIX1 INP1", "RX5", "RX_RX5"},
3018 {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"},
3019 {"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"},
3020 {"RX INT0_1 MIX1 INP2", "RX0", "RX_RX0"},
3021 {"RX INT0_1 MIX1 INP2", "RX1", "RX_RX1"},
3022 {"RX INT0_1 MIX1 INP2", "RX2", "RX_RX2"},
3023 {"RX INT0_1 MIX1 INP2", "RX3", "RX_RX3"},
3024 {"RX INT0_1 MIX1 INP2", "RX4", "RX_RX4"},
3025 {"RX INT0_1 MIX1 INP2", "RX5", "RX_RX5"},
3026 {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"},
3027 {"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"},
3028
3029 {"RX INT1_1 MIX1 INP0", "RX0", "RX_RX0"},
3030 {"RX INT1_1 MIX1 INP0", "RX1", "RX_RX1"},
3031 {"RX INT1_1 MIX1 INP0", "RX2", "RX_RX2"},
3032 {"RX INT1_1 MIX1 INP0", "RX3", "RX_RX3"},
3033 {"RX INT1_1 MIX1 INP0", "RX4", "RX_RX4"},
3034 {"RX INT1_1 MIX1 INP0", "RX5", "RX_RX5"},
3035 {"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"},
3036 {"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"},
3037 {"RX INT1_1 MIX1 INP1", "RX0", "RX_RX0"},
3038 {"RX INT1_1 MIX1 INP1", "RX1", "RX_RX1"},
3039 {"RX INT1_1 MIX1 INP1", "RX2", "RX_RX2"},
3040 {"RX INT1_1 MIX1 INP1", "RX3", "RX_RX3"},
3041 {"RX INT1_1 MIX1 INP1", "RX4", "RX_RX4"},
3042 {"RX INT1_1 MIX1 INP1", "RX5", "RX_RX5"},
3043 {"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"},
3044 {"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"},
3045 {"RX INT1_1 MIX1 INP2", "RX0", "RX_RX0"},
3046 {"RX INT1_1 MIX1 INP2", "RX1", "RX_RX1"},
3047 {"RX INT1_1 MIX1 INP2", "RX2", "RX_RX2"},
3048 {"RX INT1_1 MIX1 INP2", "RX3", "RX_RX3"},
3049 {"RX INT1_1 MIX1 INP2", "RX4", "RX_RX4"},
3050 {"RX INT1_1 MIX1 INP2", "RX5", "RX_RX5"},
3051 {"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"},
3052 {"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"},
3053
3054 {"RX INT2_1 MIX1 INP0", "RX0", "RX_RX0"},
3055 {"RX INT2_1 MIX1 INP0", "RX1", "RX_RX1"},
3056 {"RX INT2_1 MIX1 INP0", "RX2", "RX_RX2"},
3057 {"RX INT2_1 MIX1 INP0", "RX3", "RX_RX3"},
3058 {"RX INT2_1 MIX1 INP0", "RX4", "RX_RX4"},
3059 {"RX INT2_1 MIX1 INP0", "RX5", "RX_RX5"},
3060 {"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"},
3061 {"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"},
3062 {"RX INT2_1 MIX1 INP1", "RX0", "RX_RX0"},
3063 {"RX INT2_1 MIX1 INP1", "RX1", "RX_RX1"},
3064 {"RX INT2_1 MIX1 INP1", "RX2", "RX_RX2"},
3065 {"RX INT2_1 MIX1 INP1", "RX3", "RX_RX3"},
3066 {"RX INT2_1 MIX1 INP1", "RX4", "RX_RX4"},
3067 {"RX INT2_1 MIX1 INP1", "RX5", "RX_RX5"},
3068 {"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"},
3069 {"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"},
3070 {"RX INT2_1 MIX1 INP2", "RX0", "RX_RX0"},
3071 {"RX INT2_1 MIX1 INP2", "RX1", "RX_RX1"},
3072 {"RX INT2_1 MIX1 INP2", "RX2", "RX_RX2"},
3073 {"RX INT2_1 MIX1 INP2", "RX3", "RX_RX3"},
3074 {"RX INT2_1 MIX1 INP2", "RX4", "RX_RX4"},
3075 {"RX INT2_1 MIX1 INP2", "RX5", "RX_RX5"},
3076 {"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"},
3077 {"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"},
3078
3079 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"},
3080 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"},
3081 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"},
3082 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP0"},
3083 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP1"},
3084 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP2"},
3085 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP0"},
3086 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"},
3087 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"},
3088
Vatsal Buchac2d6c222018-11-30 18:46:37 +05303089 {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
3090 {"RX MIX TX0 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
3091 {"RX MIX TX0 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
3092 {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
3093 {"RX MIX TX1 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
3094 {"RX MIX TX1 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
3095 {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
3096 {"RX MIX TX2 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
3097 {"RX MIX TX2 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
3098 {"RX AIF_ECHO", NULL, "RX MIX TX0 MUX"},
3099 {"RX AIF_ECHO", NULL, "RX MIX TX1 MUX"},
3100 {"RX AIF_ECHO", NULL, "RX MIX TX2 MUX"},
3101 {"RX AIF_ECHO", NULL, "RX_MCLK"},
3102
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303103 /* Mixing path INT0 */
3104 {"RX INT0_2 MUX", "RX0", "RX_RX0"},
3105 {"RX INT0_2 MUX", "RX1", "RX_RX1"},
3106 {"RX INT0_2 MUX", "RX2", "RX_RX2"},
3107 {"RX INT0_2 MUX", "RX3", "RX_RX3"},
3108 {"RX INT0_2 MUX", "RX4", "RX_RX4"},
3109 {"RX INT0_2 MUX", "RX5", "RX_RX5"},
3110 {"RX INT0_2 INTERP", NULL, "RX INT0_2 MUX"},
3111 {"RX INT0 SEC MIX", NULL, "RX INT0_2 INTERP"},
3112
3113 /* Mixing path INT1 */
3114 {"RX INT1_2 MUX", "RX0", "RX_RX0"},
3115 {"RX INT1_2 MUX", "RX1", "RX_RX1"},
3116 {"RX INT1_2 MUX", "RX2", "RX_RX2"},
3117 {"RX INT1_2 MUX", "RX3", "RX_RX3"},
3118 {"RX INT1_2 MUX", "RX4", "RX_RX4"},
3119 {"RX INT1_2 MUX", "RX5", "RX_RX5"},
3120 {"RX INT1_2 INTERP", NULL, "RX INT1_2 MUX"},
3121 {"RX INT1 SEC MIX", NULL, "RX INT1_2 INTERP"},
3122
3123 /* Mixing path INT2 */
3124 {"RX INT2_2 MUX", "RX0", "RX_RX0"},
3125 {"RX INT2_2 MUX", "RX1", "RX_RX1"},
3126 {"RX INT2_2 MUX", "RX2", "RX_RX2"},
3127 {"RX INT2_2 MUX", "RX3", "RX_RX3"},
3128 {"RX INT2_2 MUX", "RX4", "RX_RX4"},
3129 {"RX INT2_2 MUX", "RX5", "RX_RX5"},
3130 {"RX INT2_2 INTERP", NULL, "RX INT2_2 MUX"},
3131 {"RX INT2 SEC MIX", NULL, "RX INT2_2 INTERP"},
3132
3133 {"RX INT0_1 INTERP", NULL, "RX INT0_1 MIX1"},
3134 {"RX INT0 SEC MIX", NULL, "RX INT0_1 INTERP"},
3135 {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"},
3136 {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"},
3137 {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 MIX2"},
3138 {"HPHL_OUT", NULL, "RX INT0 DEM MUX"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05303139 {"HPHL_OUT", NULL, "RX_MCLK"},
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303140
3141 {"RX INT1_1 INTERP", NULL, "RX INT1_1 MIX1"},
3142 {"RX INT1 SEC MIX", NULL, "RX INT1_1 INTERP"},
3143 {"RX INT1 MIX2", NULL, "RX INT1 SEC MIX"},
3144 {"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"},
3145 {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 MIX2"},
3146 {"HPHR_OUT", NULL, "RX INT1 DEM MUX"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05303147 {"HPHR_OUT", NULL, "RX_MCLK"},
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303148
3149 {"RX INT2_1 INTERP", NULL, "RX INT2_1 MIX1"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303150
3151 {"RX INT2_1 VBAT", "RX AUX VBAT Enable", "RX INT2_1 INTERP"},
3152 {"RX INT2 SEC MIX", NULL, "RX INT2_1 VBAT"},
3153
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303154 {"RX INT2 SEC MIX", NULL, "RX INT2_1 INTERP"},
3155 {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"},
3156 {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"},
3157 {"AUX_OUT", NULL, "RX INT2 MIX2"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05303158 {"AUX_OUT", NULL, "RX_MCLK"},
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303159
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05303160 {"IIR0", NULL, "RX_MCLK"},
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303161 {"IIR0", NULL, "IIR0 INP0 MUX"},
3162 {"IIR0 INP0 MUX", "DEC0", "RX_TX DEC0_INP"},
3163 {"IIR0 INP0 MUX", "DEC1", "RX_TX DEC1_INP"},
3164 {"IIR0 INP0 MUX", "DEC2", "RX_TX DEC2_INP"},
3165 {"IIR0 INP0 MUX", "DEC3", "RX_TX DEC3_INP"},
3166 {"IIR0 INP0 MUX", "RX0", "RX_RX0"},
3167 {"IIR0 INP0 MUX", "RX1", "RX_RX1"},
3168 {"IIR0 INP0 MUX", "RX2", "RX_RX2"},
3169 {"IIR0 INP0 MUX", "RX3", "RX_RX3"},
3170 {"IIR0 INP0 MUX", "RX4", "RX_RX4"},
3171 {"IIR0 INP0 MUX", "RX5", "RX_RX5"},
3172 {"IIR0", NULL, "IIR0 INP1 MUX"},
3173 {"IIR0 INP1 MUX", "DEC0", "RX_TX DEC0_INP"},
3174 {"IIR0 INP1 MUX", "DEC1", "RX_TX DEC1_INP"},
3175 {"IIR0 INP1 MUX", "DEC2", "RX_TX DEC2_INP"},
3176 {"IIR0 INP1 MUX", "DEC3", "RX_TX DEC3_INP"},
3177 {"IIR0 INP1 MUX", "RX0", "RX_RX0"},
3178 {"IIR0 INP1 MUX", "RX1", "RX_RX1"},
3179 {"IIR0 INP1 MUX", "RX2", "RX_RX2"},
3180 {"IIR0 INP1 MUX", "RX3", "RX_RX3"},
3181 {"IIR0 INP1 MUX", "RX4", "RX_RX4"},
3182 {"IIR0 INP1 MUX", "RX5", "RX_RX5"},
3183 {"IIR0", NULL, "IIR0 INP2 MUX"},
3184 {"IIR0 INP2 MUX", "DEC0", "RX_TX DEC0_INP"},
3185 {"IIR0 INP2 MUX", "DEC1", "RX_TX DEC1_INP"},
3186 {"IIR0 INP2 MUX", "DEC2", "RX_TX DEC2_INP"},
3187 {"IIR0 INP2 MUX", "DEC3", "RX_TX DEC3_INP"},
3188 {"IIR0 INP2 MUX", "RX0", "RX_RX0"},
3189 {"IIR0 INP2 MUX", "RX1", "RX_RX1"},
3190 {"IIR0 INP2 MUX", "RX2", "RX_RX2"},
3191 {"IIR0 INP2 MUX", "RX3", "RX_RX3"},
3192 {"IIR0 INP2 MUX", "RX4", "RX_RX4"},
3193 {"IIR0 INP2 MUX", "RX5", "RX_RX5"},
3194 {"IIR0", NULL, "IIR0 INP3 MUX"},
3195 {"IIR0 INP3 MUX", "DEC0", "RX_TX DEC0_INP"},
3196 {"IIR0 INP3 MUX", "DEC1", "RX_TX DEC1_INP"},
3197 {"IIR0 INP3 MUX", "DEC2", "RX_TX DEC2_INP"},
3198 {"IIR0 INP3 MUX", "DEC3", "RX_TX DEC3_INP"},
3199 {"IIR0 INP3 MUX", "RX0", "RX_RX0"},
3200 {"IIR0 INP3 MUX", "RX1", "RX_RX1"},
3201 {"IIR0 INP3 MUX", "RX2", "RX_RX2"},
3202 {"IIR0 INP3 MUX", "RX3", "RX_RX3"},
3203 {"IIR0 INP3 MUX", "RX4", "RX_RX4"},
3204 {"IIR0 INP3 MUX", "RX5", "RX_RX5"},
3205
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05303206 {"IIR1", NULL, "RX_MCLK"},
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303207 {"IIR1", NULL, "IIR1 INP0 MUX"},
3208 {"IIR1 INP0 MUX", "DEC0", "RX_TX DEC0_INP"},
3209 {"IIR1 INP0 MUX", "DEC1", "RX_TX DEC1_INP"},
3210 {"IIR1 INP0 MUX", "DEC2", "RX_TX DEC2_INP"},
3211 {"IIR1 INP0 MUX", "DEC3", "RX_TX DEC3_INP"},
3212 {"IIR1 INP0 MUX", "RX0", "RX_RX0"},
3213 {"IIR1 INP0 MUX", "RX1", "RX_RX1"},
3214 {"IIR1 INP0 MUX", "RX2", "RX_RX2"},
3215 {"IIR1 INP0 MUX", "RX3", "RX_RX3"},
3216 {"IIR1 INP0 MUX", "RX4", "RX_RX4"},
3217 {"IIR1 INP0 MUX", "RX5", "RX_RX5"},
3218 {"IIR1", NULL, "IIR1 INP1 MUX"},
3219 {"IIR1 INP1 MUX", "DEC0", "RX_TX DEC0_INP"},
3220 {"IIR1 INP1 MUX", "DEC1", "RX_TX DEC1_INP"},
3221 {"IIR1 INP1 MUX", "DEC2", "RX_TX DEC2_INP"},
3222 {"IIR1 INP1 MUX", "DEC3", "RX_TX DEC3_INP"},
3223 {"IIR1 INP1 MUX", "RX0", "RX_RX0"},
3224 {"IIR1 INP1 MUX", "RX1", "RX_RX1"},
3225 {"IIR1 INP1 MUX", "RX2", "RX_RX2"},
3226 {"IIR1 INP1 MUX", "RX3", "RX_RX3"},
3227 {"IIR1 INP1 MUX", "RX4", "RX_RX4"},
3228 {"IIR1 INP1 MUX", "RX5", "RX_RX5"},
3229 {"IIR1", NULL, "IIR1 INP2 MUX"},
3230 {"IIR1 INP2 MUX", "DEC0", "RX_TX DEC0_INP"},
3231 {"IIR1 INP2 MUX", "DEC1", "RX_TX DEC1_INP"},
3232 {"IIR1 INP2 MUX", "DEC2", "RX_TX DEC2_INP"},
3233 {"IIR1 INP2 MUX", "DEC3", "RX_TX DEC3_INP"},
3234 {"IIR1 INP2 MUX", "RX0", "RX_RX0"},
3235 {"IIR1 INP2 MUX", "RX1", "RX_RX1"},
3236 {"IIR1 INP2 MUX", "RX2", "RX_RX2"},
3237 {"IIR1 INP2 MUX", "RX3", "RX_RX3"},
3238 {"IIR1 INP2 MUX", "RX4", "RX_RX4"},
3239 {"IIR1 INP2 MUX", "RX5", "RX_RX5"},
3240 {"IIR1", NULL, "IIR1 INP3 MUX"},
3241 {"IIR1 INP3 MUX", "DEC0", "RX_TX DEC0_INP"},
3242 {"IIR1 INP3 MUX", "DEC1", "RX_TX DEC1_INP"},
3243 {"IIR1 INP3 MUX", "DEC2", "RX_TX DEC2_INP"},
3244 {"IIR1 INP3 MUX", "DEC3", "RX_TX DEC3_INP"},
3245 {"IIR1 INP3 MUX", "RX0", "RX_RX0"},
3246 {"IIR1 INP3 MUX", "RX1", "RX_RX1"},
3247 {"IIR1 INP3 MUX", "RX2", "RX_RX2"},
3248 {"IIR1 INP3 MUX", "RX3", "RX_RX3"},
3249 {"IIR1 INP3 MUX", "RX4", "RX_RX4"},
3250 {"IIR1 INP3 MUX", "RX5", "RX_RX5"},
3251
3252 {"SRC0", NULL, "IIR0"},
3253 {"SRC1", NULL, "IIR1"},
3254 {"RX INT0 MIX2 INP", "SRC0", "SRC0"},
3255 {"RX INT0 MIX2 INP", "SRC1", "SRC1"},
3256 {"RX INT1 MIX2 INP", "SRC0", "SRC0"},
3257 {"RX INT1 MIX2 INP", "SRC1", "SRC1"},
3258 {"RX INT2 MIX2 INP", "SRC0", "SRC0"},
3259 {"RX INT2 MIX2 INP", "SRC1", "SRC1"},
3260};
3261
3262static int rx_swrm_clock(void *handle, bool enable)
3263{
3264 struct rx_macro_priv *rx_priv = (struct rx_macro_priv *) handle;
3265 struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL);
3266 int ret = 0;
3267
Tanya Dixit8530fb92018-09-14 16:01:25 +05303268 if (regmap == NULL) {
3269 dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__);
3270 return -EINVAL;
3271 }
3272
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303273 mutex_lock(&rx_priv->swr_clk_lock);
3274
3275 dev_dbg(rx_priv->dev, "%s: swrm clock %s\n",
3276 __func__, (enable ? "enable" : "disable"));
3277 if (enable) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303278 pm_runtime_get_sync(rx_priv->dev);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303279 if (rx_priv->swr_clk_users == 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08003280 msm_cdc_pinctrl_select_active_state(
3281 rx_priv->rx_swr_gpio_p);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303282 ret = rx_macro_mclk_enable(rx_priv, 1, true);
3283 if (ret < 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08003284 msm_cdc_pinctrl_select_sleep_state(
3285 rx_priv->rx_swr_gpio_p);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303286 dev_err(rx_priv->dev,
3287 "%s: rx request clock enable failed\n",
3288 __func__);
3289 goto exit;
3290 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05303291 if (rx_priv->reset_swr)
3292 regmap_update_bits(regmap,
3293 BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
3294 0x02, 0x02);
Ramprasad Katkam9c2394a2018-08-23 13:13:48 +05303295 regmap_update_bits(regmap,
3296 BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303297 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05303298 if (rx_priv->reset_swr)
3299 regmap_update_bits(regmap,
3300 BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
3301 0x02, 0x00);
3302 rx_priv->reset_swr = false;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303303 }
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303304 pm_runtime_mark_last_busy(rx_priv->dev);
3305 pm_runtime_put_autosuspend(rx_priv->dev);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303306 rx_priv->swr_clk_users++;
3307 } else {
3308 if (rx_priv->swr_clk_users <= 0) {
3309 dev_err(rx_priv->dev,
3310 "%s: rx swrm clock users already reset\n",
3311 __func__);
3312 rx_priv->swr_clk_users = 0;
3313 goto exit;
3314 }
3315 rx_priv->swr_clk_users--;
3316 if (rx_priv->swr_clk_users == 0) {
3317 regmap_update_bits(regmap,
3318 BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
3319 0x01, 0x00);
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08003320 rx_macro_mclk_enable(rx_priv, 0, true);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303321 msm_cdc_pinctrl_select_sleep_state(
3322 rx_priv->rx_swr_gpio_p);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303323 }
3324 }
3325 dev_dbg(rx_priv->dev, "%s: swrm clock users %d\n",
3326 __func__, rx_priv->swr_clk_users);
3327exit:
3328 mutex_unlock(&rx_priv->swr_clk_lock);
3329 return ret;
3330}
3331
Meng Wang15c825d2018-09-06 10:49:18 +08003332static void rx_macro_init_bcl_pmic_reg(struct snd_soc_component *component)
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303333{
3334 struct device *rx_dev = NULL;
3335 struct rx_macro_priv *rx_priv = NULL;
3336
Meng Wang15c825d2018-09-06 10:49:18 +08003337 if (!component) {
3338 pr_err("%s: NULL component pointer!\n", __func__);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303339 return;
3340 }
3341
Meng Wang15c825d2018-09-06 10:49:18 +08003342 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303343 return;
3344
3345 switch (rx_priv->bcl_pmic_params.id) {
3346 case 0:
3347 /* Enable ID0 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08003348 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303349 BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
3350 /* Update MC_SID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08003351 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303352 BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1, 0x0F,
3353 rx_priv->bcl_pmic_params.sid);
3354 /* Update MC_PPID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08003355 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303356 BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG2, 0xFF,
3357 rx_priv->bcl_pmic_params.ppid);
3358 break;
3359 case 1:
3360 /* Enable ID1 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08003361 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303362 BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
3363 /* Update MC_SID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08003364 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303365 BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG3, 0x0F,
3366 rx_priv->bcl_pmic_params.sid);
3367 /* Update MC_PPID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08003368 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303369 BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1, 0xFF,
3370 rx_priv->bcl_pmic_params.ppid);
3371 break;
3372 default:
Md Mansoor Ahmed26d8bdd2018-11-20 10:56:01 +05303373 dev_err(rx_dev, "%s: PMIC ID is invalid %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303374 __func__, rx_priv->bcl_pmic_params.id);
3375 break;
3376 }
3377}
3378
Meng Wang15c825d2018-09-06 10:49:18 +08003379static int rx_macro_init(struct snd_soc_component *component)
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303380{
Meng Wang15c825d2018-09-06 10:49:18 +08003381 struct snd_soc_dapm_context *dapm =
3382 snd_soc_component_get_dapm(component);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303383 int ret = 0;
3384 struct device *rx_dev = NULL;
3385 struct rx_macro_priv *rx_priv = NULL;
3386
Meng Wang15c825d2018-09-06 10:49:18 +08003387 rx_dev = bolero_get_device_ptr(component->dev, RX_MACRO);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303388 if (!rx_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08003389 dev_err(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303390 "%s: null device for macro!\n", __func__);
3391 return -EINVAL;
3392 }
3393 rx_priv = dev_get_drvdata(rx_dev);
3394 if (!rx_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08003395 dev_err(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303396 "%s: priv is null for macro!\n", __func__);
3397 return -EINVAL;
3398 }
3399
3400 ret = snd_soc_dapm_new_controls(dapm, rx_macro_dapm_widgets,
3401 ARRAY_SIZE(rx_macro_dapm_widgets));
3402 if (ret < 0) {
3403 dev_err(rx_dev, "%s: failed to add controls\n", __func__);
3404 return ret;
3405 }
3406 ret = snd_soc_dapm_add_routes(dapm, rx_audio_map,
3407 ARRAY_SIZE(rx_audio_map));
3408 if (ret < 0) {
3409 dev_err(rx_dev, "%s: failed to add routes\n", __func__);
3410 return ret;
3411 }
3412 ret = snd_soc_dapm_new_widgets(dapm->card);
3413 if (ret < 0) {
3414 dev_err(rx_dev, "%s: failed to add widgets\n", __func__);
3415 return ret;
3416 }
Meng Wang15c825d2018-09-06 10:49:18 +08003417 ret = snd_soc_add_component_controls(component, rx_macro_snd_controls,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303418 ARRAY_SIZE(rx_macro_snd_controls));
3419 if (ret < 0) {
3420 dev_err(rx_dev, "%s: failed to add snd_ctls\n", __func__);
3421 return ret;
3422 }
Laxminath Kasam701e3582018-10-15 20:06:09 +05303423 rx_priv->dev_up = true;
Laxminath Kasam638b5602018-09-24 13:19:52 +05303424 snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF1 Playback");
3425 snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF2 Playback");
3426 snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF3 Playback");
3427 snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF4 Playback");
3428 snd_soc_dapm_ignore_suspend(dapm, "HPHL_OUT");
3429 snd_soc_dapm_ignore_suspend(dapm, "HPHR_OUT");
3430 snd_soc_dapm_ignore_suspend(dapm, "AUX_OUT");
3431 snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC0_INP");
3432 snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC1_INP");
3433 snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC2_INP");
3434 snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC3_INP");
3435 snd_soc_dapm_sync(dapm);
3436
Meng Wang15c825d2018-09-06 10:49:18 +08003437 snd_soc_component_update_bits(component,
3438 BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL,
3439 0x01, 0x01);
3440 snd_soc_component_update_bits(component,
3441 BOLERO_CDC_RX_RX1_RX_PATH_DSM_CTL,
3442 0x01, 0x01);
3443 snd_soc_component_update_bits(component,
3444 BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL,
3445 0x01, 0x01);
3446 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX0_RX_PATH_SEC7,
3447 0x07, 0x02);
3448 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX1_RX_PATH_SEC7,
3449 0x07, 0x02);
3450 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX2_RX_PATH_SEC7,
3451 0x07, 0x02);
3452 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX0_RX_PATH_CFG3,
3453 0x03, 0x02);
3454 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX1_RX_PATH_CFG3,
3455 0x03, 0x02);
3456 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX2_RX_PATH_CFG3,
3457 0x03, 0x02);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303458
Meng Wang15c825d2018-09-06 10:49:18 +08003459 rx_priv->component = component;
Vatsal Bucha39ead2c2018-12-14 12:22:46 +05303460 rx_macro_init_bcl_pmic_reg(component);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303461
3462 return 0;
3463}
3464
Meng Wang15c825d2018-09-06 10:49:18 +08003465static int rx_macro_deinit(struct snd_soc_component *component)
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303466{
3467 struct device *rx_dev = NULL;
3468 struct rx_macro_priv *rx_priv = NULL;
3469
Meng Wang15c825d2018-09-06 10:49:18 +08003470 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303471 return -EINVAL;
3472
Meng Wang15c825d2018-09-06 10:49:18 +08003473 rx_priv->component = NULL;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303474
3475 return 0;
3476}
3477
3478static void rx_macro_add_child_devices(struct work_struct *work)
3479{
3480 struct rx_macro_priv *rx_priv = NULL;
3481 struct platform_device *pdev = NULL;
3482 struct device_node *node = NULL;
3483 struct rx_swr_ctrl_data *swr_ctrl_data = NULL, *temp = NULL;
3484 int ret = 0;
3485 u16 count = 0, ctrl_num = 0;
3486 struct rx_swr_ctrl_platform_data *platdata = NULL;
3487 char plat_dev_name[RX_SWR_STRING_LEN] = "";
3488 bool rx_swr_master_node = false;
3489
3490 rx_priv = container_of(work, struct rx_macro_priv,
3491 rx_macro_add_child_devices_work);
3492 if (!rx_priv) {
3493 pr_err("%s: Memory for rx_priv does not exist\n",
3494 __func__);
3495 return;
3496 }
3497
3498 if (!rx_priv->dev) {
3499 pr_err("%s: RX device does not exist\n", __func__);
3500 return;
3501 }
3502
3503 if(!rx_priv->dev->of_node) {
3504 dev_err(rx_priv->dev,
3505 "%s: DT node for RX dev does not exist\n", __func__);
3506 return;
3507 }
3508
3509 platdata = &rx_priv->swr_plat_data;
3510 rx_priv->child_count = 0;
3511
3512 for_each_available_child_of_node(rx_priv->dev->of_node, node) {
3513 rx_swr_master_node = false;
3514 if (strnstr(node->name, "rx_swr_master",
3515 strlen("rx_swr_master")) != NULL)
3516 rx_swr_master_node = true;
3517
3518 if(rx_swr_master_node)
3519 strlcpy(plat_dev_name, "rx_swr_ctrl",
3520 (RX_SWR_STRING_LEN - 1));
3521 else
3522 strlcpy(plat_dev_name, node->name,
3523 (RX_SWR_STRING_LEN - 1));
3524
3525 pdev = platform_device_alloc(plat_dev_name, -1);
3526 if (!pdev) {
3527 dev_err(rx_priv->dev, "%s: pdev memory alloc failed\n",
3528 __func__);
3529 ret = -ENOMEM;
3530 goto err;
3531 }
3532 pdev->dev.parent = rx_priv->dev;
3533 pdev->dev.of_node = node;
3534
3535 if (rx_swr_master_node) {
3536 ret = platform_device_add_data(pdev, platdata,
3537 sizeof(*platdata));
3538 if (ret) {
3539 dev_err(&pdev->dev,
3540 "%s: cannot add plat data ctrl:%d\n",
3541 __func__, ctrl_num);
3542 goto fail_pdev_add;
3543 }
3544 }
3545
3546 ret = platform_device_add(pdev);
3547 if (ret) {
3548 dev_err(&pdev->dev,
3549 "%s: Cannot add platform device\n",
3550 __func__);
3551 goto fail_pdev_add;
3552 }
3553
3554 if (rx_swr_master_node) {
3555 temp = krealloc(swr_ctrl_data,
3556 (ctrl_num + 1) * sizeof(
3557 struct rx_swr_ctrl_data),
3558 GFP_KERNEL);
3559 if (!temp) {
3560 ret = -ENOMEM;
3561 goto fail_pdev_add;
3562 }
3563 swr_ctrl_data = temp;
3564 swr_ctrl_data[ctrl_num].rx_swr_pdev = pdev;
3565 ctrl_num++;
3566 dev_dbg(&pdev->dev,
3567 "%s: Added soundwire ctrl device(s)\n",
3568 __func__);
3569 rx_priv->swr_ctrl_data = swr_ctrl_data;
3570 }
3571 if (rx_priv->child_count < RX_MACRO_CHILD_DEVICES_MAX)
3572 rx_priv->pdev_child_devices[
3573 rx_priv->child_count++] = pdev;
3574 else
3575 goto err;
3576 }
3577 return;
3578fail_pdev_add:
3579 for (count = 0; count < rx_priv->child_count; count++)
3580 platform_device_put(rx_priv->pdev_child_devices[count]);
3581err:
3582 return;
3583}
3584
3585static void rx_macro_init_ops(struct macro_ops *ops, char __iomem *rx_io_base)
3586{
3587 memset(ops, 0, sizeof(struct macro_ops));
3588 ops->init = rx_macro_init;
3589 ops->exit = rx_macro_deinit;
3590 ops->io_base = rx_io_base;
3591 ops->dai_ptr = rx_macro_dai;
3592 ops->num_dais = ARRAY_SIZE(rx_macro_dai);
Laxminath Kasam497a6512018-09-17 16:11:52 +05303593 ops->event_handler = rx_macro_event_handler;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05303594 ops->set_port_map = rx_macro_set_port_map;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303595}
3596
3597static int rx_macro_probe(struct platform_device *pdev)
3598{
3599 struct macro_ops ops = {0};
3600 struct rx_macro_priv *rx_priv = NULL;
3601 u32 rx_base_addr = 0, muxsel = 0;
3602 char __iomem *rx_io_base = NULL, *muxsel_io = NULL;
3603 int ret = 0;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303604 u8 bcl_pmic_params[3];
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003605 u32 default_clk_id = 0;
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07003606 u32 is_used_rx_swr_gpio = 1;
3607 const char *is_used_rx_swr_gpio_dt = "qcom,is-used-swr-gpio";
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303608
3609 rx_priv = devm_kzalloc(&pdev->dev, sizeof(struct rx_macro_priv),
3610 GFP_KERNEL);
3611 if (!rx_priv)
3612 return -ENOMEM;
3613
3614 rx_priv->dev = &pdev->dev;
3615 ret = of_property_read_u32(pdev->dev.of_node, "reg",
3616 &rx_base_addr);
3617 if (ret) {
3618 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
3619 __func__, "reg");
3620 return ret;
3621 }
3622 ret = of_property_read_u32(pdev->dev.of_node, "qcom,rx_mclk_mode_muxsel",
3623 &muxsel);
3624 if (ret) {
3625 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
3626 __func__, "reg");
3627 return ret;
3628 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003629 ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
3630 &default_clk_id);
3631 if (ret) {
3632 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
3633 __func__, "qcom,default-clk-id");
3634 default_clk_id = RX_CORE_CLK;
3635 }
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07003636 if (of_find_property(pdev->dev.of_node, is_used_rx_swr_gpio_dt,
3637 NULL)) {
3638 ret = of_property_read_u32(pdev->dev.of_node,
3639 is_used_rx_swr_gpio_dt,
3640 &is_used_rx_swr_gpio);
3641 if (ret) {
3642 dev_err(&pdev->dev, "%s: error reading %s in dt\n",
3643 __func__, is_used_rx_swr_gpio_dt);
3644 is_used_rx_swr_gpio = 1;
3645 }
3646 }
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303647 rx_priv->rx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
3648 "qcom,rx-swr-gpios", 0);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07003649 if (!rx_priv->rx_swr_gpio_p && is_used_rx_swr_gpio) {
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303650 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
3651 __func__);
3652 return -EINVAL;
3653 }
Karthikeyan Mani326536d2019-06-03 13:29:43 -07003654 if (msm_cdc_pinctrl_get_state(rx_priv->rx_swr_gpio_p) < 0) {
3655 dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
3656 __func__);
3657 return -EPROBE_DEFER;
3658 }
3659
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303660 rx_io_base = devm_ioremap(&pdev->dev, rx_base_addr,
3661 RX_MACRO_MAX_OFFSET);
3662 if (!rx_io_base) {
3663 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
3664 return -ENOMEM;
3665 }
3666 rx_priv->rx_io_base = rx_io_base;
3667 muxsel_io = devm_ioremap(&pdev->dev, muxsel, 0x4);
3668 if (!muxsel_io) {
3669 dev_err(&pdev->dev, "%s: ioremap failed for muxsel\n",
3670 __func__);
3671 return -ENOMEM;
3672 }
3673 rx_priv->rx_mclk_mode_muxsel = muxsel_io;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05303674 rx_priv->reset_swr = true;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303675 INIT_WORK(&rx_priv->rx_macro_add_child_devices_work,
3676 rx_macro_add_child_devices);
3677 rx_priv->swr_plat_data.handle = (void *) rx_priv;
3678 rx_priv->swr_plat_data.read = NULL;
3679 rx_priv->swr_plat_data.write = NULL;
3680 rx_priv->swr_plat_data.bulk_write = NULL;
3681 rx_priv->swr_plat_data.clk = rx_swrm_clock;
3682 rx_priv->swr_plat_data.handle_irq = NULL;
3683
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303684 ret = of_property_read_u8_array(pdev->dev.of_node,
3685 "qcom,rx-bcl-pmic-params", bcl_pmic_params,
3686 sizeof(bcl_pmic_params));
3687 if (ret) {
3688 dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
3689 __func__, "qcom,rx-bcl-pmic-params");
3690 } else {
3691 rx_priv->bcl_pmic_params.id = bcl_pmic_params[0];
3692 rx_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
3693 rx_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
3694 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003695 rx_priv->clk_id = default_clk_id;
3696 rx_priv->default_clk_id = default_clk_id;
3697 ops.clk_id_req = rx_priv->clk_id;
3698 ops.default_clk_id = default_clk_id;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303699
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303700 dev_set_drvdata(&pdev->dev, rx_priv);
3701 mutex_init(&rx_priv->mclk_lock);
3702 mutex_init(&rx_priv->swr_clk_lock);
3703 rx_macro_init_ops(&ops, rx_io_base);
3704
3705 ret = bolero_register_macro(&pdev->dev, RX_MACRO, &ops);
3706 if (ret) {
3707 dev_err(&pdev->dev,
3708 "%s: register macro failed\n", __func__);
3709 goto err_reg_macro;
3710 }
3711 schedule_work(&rx_priv->rx_macro_add_child_devices_work);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303712 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
3713 pm_runtime_use_autosuspend(&pdev->dev);
3714 pm_runtime_set_suspended(&pdev->dev);
3715 pm_runtime_enable(&pdev->dev);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303716
3717 return 0;
3718
3719err_reg_macro:
3720 mutex_destroy(&rx_priv->mclk_lock);
3721 mutex_destroy(&rx_priv->swr_clk_lock);
3722 return ret;
3723}
3724
3725static int rx_macro_remove(struct platform_device *pdev)
3726{
3727 struct rx_macro_priv *rx_priv = NULL;
3728 u16 count = 0;
3729
3730 rx_priv = dev_get_drvdata(&pdev->dev);
3731
3732 if (!rx_priv)
3733 return -EINVAL;
3734
3735 for (count = 0; count < rx_priv->child_count &&
3736 count < RX_MACRO_CHILD_DEVICES_MAX; count++)
3737 platform_device_unregister(rx_priv->pdev_child_devices[count]);
3738
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303739 pm_runtime_disable(&pdev->dev);
3740 pm_runtime_set_suspended(&pdev->dev);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303741 bolero_unregister_macro(&pdev->dev, RX_MACRO);
3742 mutex_destroy(&rx_priv->mclk_lock);
3743 mutex_destroy(&rx_priv->swr_clk_lock);
3744 kfree(rx_priv->swr_ctrl_data);
3745 return 0;
3746}
3747
3748static const struct of_device_id rx_macro_dt_match[] = {
3749 {.compatible = "qcom,rx-macro"},
3750 {}
3751};
3752
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303753static const struct dev_pm_ops bolero_dev_pm_ops = {
3754 SET_RUNTIME_PM_OPS(
3755 bolero_runtime_suspend,
3756 bolero_runtime_resume,
3757 NULL
3758 )
3759};
3760
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303761static struct platform_driver rx_macro_driver = {
3762 .driver = {
3763 .name = "rx_macro",
3764 .owner = THIS_MODULE,
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303765 .pm = &bolero_dev_pm_ops,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303766 .of_match_table = rx_macro_dt_match,
Xiaojun Sang53cd13a2018-06-29 15:14:37 +08003767 .suppress_bind_attrs = true,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303768 },
3769 .probe = rx_macro_probe,
3770 .remove = rx_macro_remove,
3771};
3772
3773module_platform_driver(rx_macro_driver);
3774
3775MODULE_DESCRIPTION("RX macro driver");
3776MODULE_LICENSE("GPL v2");