blob: 4d9ccb43761c973a9159086ce4cb02ee2f14d8d0 [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>
10#include <sound/soc.h>
11#include <sound/pcm.h>
12#include <sound/pcm_params.h>
13#include <sound/soc-dapm.h>
14#include <sound/tlv.h>
Sudheer Papothia3e969d2018-10-27 06:22:10 +053015#include <soc/swr-common.h>
Laxminath Kasama7ecc582018-06-15 16:55:02 +053016#include <soc/swr-wcd.h>
17
Meng Wang11a25cf2018-10-31 14:11:26 +080018#include <asoc/msm-cdc-pinctrl.h>
Laxminath Kasama7ecc582018-06-15 16:55:02 +053019#include "bolero-cdc.h"
20#include "bolero-cdc-registers.h"
Laxminath Kasama7ecc582018-06-15 16:55:02 +053021
22#define RX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
23 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
24 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\
25 SNDRV_PCM_RATE_384000)
26/* Fractional Rates */
27#define RX_MACRO_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
28 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800)
29
30#define RX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
31 SNDRV_PCM_FMTBIT_S24_LE |\
32 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
33
34#define RX_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
35 SNDRV_PCM_RATE_48000)
36#define RX_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
37 SNDRV_PCM_FMTBIT_S24_LE |\
38 SNDRV_PCM_FMTBIT_S24_3LE)
39
Laxminath Kasamac396d52018-09-06 12:53:26 +053040#define SAMPLING_RATE_44P1KHZ 44100
41#define SAMPLING_RATE_88P2KHZ 88200
42#define SAMPLING_RATE_176P4KHZ 176400
43#define SAMPLING_RATE_352P8KHZ 352800
44
Laxminath Kasama7ecc582018-06-15 16:55:02 +053045#define RX_MACRO_MAX_OFFSET 0x1000
46
47#define RX_MACRO_MAX_DMA_CH_PER_PORT 2
48#define RX_SWR_STRING_LEN 80
49#define RX_MACRO_CHILD_DEVICES_MAX 3
50
51#define RX_MACRO_INTERP_MUX_NUM_INPUTS 3
52#define RX_MACRO_SIDETONE_IIR_COEFF_MAX 5
53
54#define STRING(name) #name
55#define RX_MACRO_DAPM_ENUM(name, reg, offset, text) \
56static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
57static const struct snd_kcontrol_new name##_mux = \
58 SOC_DAPM_ENUM(STRING(name), name##_enum)
59
60#define RX_MACRO_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \
61static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
62static const struct snd_kcontrol_new name##_mux = \
63 SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname)
64
65#define RX_MACRO_DAPM_MUX(name, shift, kctl) \
66 SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux)
67
68#define RX_MACRO_RX_PATH_OFFSET 0x80
69#define RX_MACRO_COMP_OFFSET 0x40
70
Laxminath Kasam497a6512018-09-17 16:11:52 +053071#define MAX_IMPED_PARAMS 6
72
Vatsal Buchac2d6c222018-11-30 18:46:37 +053073#define RX_MACRO_EC_MIX_TX0_MASK 0xf0
74#define RX_MACRO_EC_MIX_TX1_MASK 0x0f
75#define RX_MACRO_EC_MIX_TX2_MASK 0x0f
76
Laxminath Kasam497a6512018-09-17 16:11:52 +053077struct wcd_imped_val {
78 u32 imped_val;
79 u8 index;
80};
81
82static const struct wcd_imped_val imped_index[] = {
83 {4, 0},
84 {5, 1},
85 {6, 2},
86 {7, 3},
87 {8, 4},
88 {9, 5},
89 {10, 6},
90 {11, 7},
91 {12, 8},
92 {13, 9},
93};
94
95struct rx_macro_reg_mask_val {
96 u16 reg;
97 u8 mask;
98 u8 val;
99};
100
101static const struct rx_macro_reg_mask_val imped_table[][MAX_IMPED_PARAMS] = {
102 {
103 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf2},
104 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf2},
105 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
106 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf2},
107 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf2},
108 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
109 },
110 {
111 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf4},
112 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf4},
113 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
114 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf4},
115 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf4},
116 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
117 },
118 {
119 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf7},
120 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf7},
121 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x01},
122 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf7},
123 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf7},
124 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x01},
125 },
126 {
127 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf9},
128 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf9},
129 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
130 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf9},
131 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf9},
132 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
133 },
134 {
135 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfa},
136 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfa},
137 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
138 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfa},
139 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfa},
140 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
141 },
142 {
143 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfb},
144 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfb},
145 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
146 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfb},
147 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfb},
148 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
149 },
150 {
151 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfc},
152 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfc},
153 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
154 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfc},
155 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfc},
156 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
157 },
158 {
159 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfd},
160 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfd},
161 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
162 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfd},
163 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
164 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
165 },
166 {
167 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfd},
168 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfd},
169 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x01},
170 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfd},
171 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
172 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x01},
173 },
174};
175
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530176enum {
177 INTERP_HPHL,
178 INTERP_HPHR,
179 INTERP_AUX,
180 INTERP_MAX
181};
182
183enum {
184 RX_MACRO_RX0,
185 RX_MACRO_RX1,
186 RX_MACRO_RX2,
187 RX_MACRO_RX3,
188 RX_MACRO_RX4,
189 RX_MACRO_RX5,
190 RX_MACRO_PORTS_MAX
191};
192
193enum {
194 RX_MACRO_COMP1, /* HPH_L */
195 RX_MACRO_COMP2, /* HPH_R */
196 RX_MACRO_COMP_MAX
197};
198
199enum {
Vatsal Buchac2d6c222018-11-30 18:46:37 +0530200 RX_MACRO_EC0_MUX = 0,
201 RX_MACRO_EC1_MUX,
202 RX_MACRO_EC2_MUX,
203 RX_MACRO_EC_MUX_MAX,
204};
205
206enum {
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530207 INTn_1_INP_SEL_ZERO = 0,
208 INTn_1_INP_SEL_DEC0,
209 INTn_1_INP_SEL_DEC1,
210 INTn_1_INP_SEL_IIR0,
211 INTn_1_INP_SEL_IIR1,
212 INTn_1_INP_SEL_RX0,
213 INTn_1_INP_SEL_RX1,
214 INTn_1_INP_SEL_RX2,
215 INTn_1_INP_SEL_RX3,
216 INTn_1_INP_SEL_RX4,
217 INTn_1_INP_SEL_RX5,
218};
219
220enum {
221 INTn_2_INP_SEL_ZERO = 0,
222 INTn_2_INP_SEL_RX0,
223 INTn_2_INP_SEL_RX1,
224 INTn_2_INP_SEL_RX2,
225 INTn_2_INP_SEL_RX3,
226 INTn_2_INP_SEL_RX4,
227 INTn_2_INP_SEL_RX5,
228};
229
230enum {
231 INTERP_MAIN_PATH,
232 INTERP_MIX_PATH,
233};
234
235/* Codec supports 2 IIR filters */
236enum {
237 IIR0 = 0,
238 IIR1,
239 IIR_MAX,
240};
241
242/* Each IIR has 5 Filter Stages */
243enum {
244 BAND1 = 0,
245 BAND2,
246 BAND3,
247 BAND4,
248 BAND5,
249 BAND_MAX,
250};
251
252struct rx_macro_idle_detect_config {
253 u8 hph_idle_thr;
254 u8 hph_idle_detect_en;
255};
256
257struct interp_sample_rate {
258 int sample_rate;
259 int rate_val;
260};
261
262static struct interp_sample_rate sr_val_tbl[] = {
263 {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5},
264 {192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA},
265 {176400, 0xB}, {352800, 0xC},
266};
267
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530268struct rx_macro_bcl_pmic_params {
269 u8 id;
270 u8 sid;
271 u8 ppid;
272};
273
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530274static int rx_macro_hw_params(struct snd_pcm_substream *substream,
275 struct snd_pcm_hw_params *params,
276 struct snd_soc_dai *dai);
277static int rx_macro_get_channel_map(struct snd_soc_dai *dai,
278 unsigned int *tx_num, unsigned int *tx_slot,
279 unsigned int *rx_num, unsigned int *rx_slot);
280static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
281 struct snd_ctl_elem_value *ucontrol);
282static int rx_macro_mux_get(struct snd_kcontrol *kcontrol,
283 struct snd_ctl_elem_value *ucontrol);
284static int rx_macro_mux_put(struct snd_kcontrol *kcontrol,
285 struct snd_ctl_elem_value *ucontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800286static int rx_macro_enable_interp_clk(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530287 int event, int interp_idx);
288
289/* Hold instance to soundwire platform device */
290struct rx_swr_ctrl_data {
291 struct platform_device *rx_swr_pdev;
292};
293
294struct rx_swr_ctrl_platform_data {
295 void *handle; /* holds codec private data */
296 int (*read)(void *handle, int reg);
297 int (*write)(void *handle, int reg, int val);
298 int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
299 int (*clk)(void *handle, bool enable);
300 int (*handle_irq)(void *handle,
301 irqreturn_t (*swrm_irq_handler)(int irq,
302 void *data),
303 void *swrm_handle,
304 int action);
305};
306
307enum {
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +0530308 RX_MACRO_AIF_INVALID = 0,
309 RX_MACRO_AIF1_PB,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530310 RX_MACRO_AIF2_PB,
311 RX_MACRO_AIF3_PB,
312 RX_MACRO_AIF4_PB,
Vatsal Buchac2d6c222018-11-30 18:46:37 +0530313 RX_MACRO_AIF_ECHO,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530314 RX_MACRO_MAX_DAIS,
315};
316
317enum {
318 RX_MACRO_AIF1_CAP = 0,
319 RX_MACRO_AIF2_CAP,
320 RX_MACRO_AIF3_CAP,
321 RX_MACRO_MAX_AIF_CAP_DAIS
322};
323/*
324 * @dev: rx macro device pointer
325 * @comp_enabled: compander enable mixer value set
326 * @prim_int_users: Users of interpolator
327 * @rx_mclk_users: RX MCLK users count
328 * @vi_feed_value: VI sense mask
329 * @swr_clk_lock: to lock swr master clock operations
330 * @swr_ctrl_data: SoundWire data structure
331 * @swr_plat_data: Soundwire platform data
332 * @rx_macro_add_child_devices_work: work for adding child devices
333 * @rx_swr_gpio_p: used by pinctrl API
334 * @rx_core_clk: MCLK for rx macro
335 * @rx_npl_clk: NPL clock for RX soundwire
Meng Wang15c825d2018-09-06 10:49:18 +0800336 * @component: codec handle
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530337 */
338struct rx_macro_priv {
339 struct device *dev;
340 int comp_enabled[RX_MACRO_COMP_MAX];
341 /* Main path clock users count */
342 int main_clk_users[INTERP_MAX];
343 int rx_port_value[RX_MACRO_PORTS_MAX];
344 u16 prim_int_users[INTERP_MAX];
345 int rx_mclk_users;
346 int swr_clk_users;
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530347 bool dapm_mclk_enable;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530348 bool reset_swr;
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +0530349 int clsh_users;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530350 int rx_mclk_cnt;
Laxminath Kasambee08192018-07-01 14:38:55 +0530351 bool is_native_on;
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +0530352 bool is_ear_mode_on;
Laxminath Kasam701e3582018-10-15 20:06:09 +0530353 bool dev_up;
Laxminath Kasamde09dfb2018-11-09 13:00:30 +0530354 bool hph_pwr_mode;
Laxminath Kasamd3ffb332018-11-14 19:59:21 +0530355 bool hph_hd2_mode;
Laxminath Kasambee08192018-07-01 14:38:55 +0530356 u16 mclk_mux;
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;
363 struct clk *rx_core_clk;
364 struct clk *rx_npl_clk;
Meng Wang15c825d2018-09-06 10:49:18 +0800365 struct snd_soc_component *component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530366 unsigned long active_ch_mask[RX_MACRO_MAX_DAIS];
367 unsigned long active_ch_cnt[RX_MACRO_MAX_DAIS];
368 u16 bit_width[RX_MACRO_MAX_DAIS];
369 char __iomem *rx_io_base;
370 char __iomem *rx_mclk_mode_muxsel;
371 struct rx_macro_idle_detect_config idle_det_cfg;
372 u8 sidetone_coeff_array[IIR_MAX][BAND_MAX]
373 [RX_MACRO_SIDETONE_IIR_COEFF_MAX * 4];
374
375 struct platform_device *pdev_child_devices
376 [RX_MACRO_CHILD_DEVICES_MAX];
377 int child_count;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530378 int is_softclip_on;
379 int softclip_clk_users;
380 struct rx_macro_bcl_pmic_params bcl_pmic_params;
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
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530456RX_MACRO_DAPM_ENUM(rx_int0_2, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 0,
457 rx_int_mix_mux_text);
458RX_MACRO_DAPM_ENUM(rx_int1_2, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 0,
459 rx_int_mix_mux_text);
460RX_MACRO_DAPM_ENUM(rx_int2_2, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG1, 0,
461 rx_int_mix_mux_text);
462
463
464RX_MACRO_DAPM_ENUM(rx_int0_1_mix_inp0, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0, 0,
465 rx_prim_mix_text);
466RX_MACRO_DAPM_ENUM(rx_int0_1_mix_inp1, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0, 4,
467 rx_prim_mix_text);
468RX_MACRO_DAPM_ENUM(rx_int0_1_mix_inp2, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 4,
469 rx_prim_mix_text);
470RX_MACRO_DAPM_ENUM(rx_int1_1_mix_inp0, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0, 0,
471 rx_prim_mix_text);
472RX_MACRO_DAPM_ENUM(rx_int1_1_mix_inp1, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0, 4,
473 rx_prim_mix_text);
474RX_MACRO_DAPM_ENUM(rx_int1_1_mix_inp2, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 4,
475 rx_prim_mix_text);
476RX_MACRO_DAPM_ENUM(rx_int2_1_mix_inp0, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG0, 0,
477 rx_prim_mix_text);
478RX_MACRO_DAPM_ENUM(rx_int2_1_mix_inp1, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG0, 4,
479 rx_prim_mix_text);
480RX_MACRO_DAPM_ENUM(rx_int2_1_mix_inp2, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG1, 4,
481 rx_prim_mix_text);
482
483RX_MACRO_DAPM_ENUM(rx_int0_mix2_inp, BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2,
484 rx_sidetone_mix_text);
485RX_MACRO_DAPM_ENUM(rx_int1_mix2_inp, BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4,
486 rx_sidetone_mix_text);
487RX_MACRO_DAPM_ENUM(rx_int2_mix2_inp, BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6,
488 rx_sidetone_mix_text);
489
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530490RX_MACRO_DAPM_ENUM(iir0_inp0, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0, 0,
491 iir_inp_mux_text);
492RX_MACRO_DAPM_ENUM(iir0_inp1, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1, 0,
493 iir_inp_mux_text);
494RX_MACRO_DAPM_ENUM(iir0_inp2, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2, 0,
495 iir_inp_mux_text);
496RX_MACRO_DAPM_ENUM(iir0_inp3, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3, 0,
497 iir_inp_mux_text);
498RX_MACRO_DAPM_ENUM(iir1_inp0, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0, 0,
499 iir_inp_mux_text);
500RX_MACRO_DAPM_ENUM(iir1_inp1, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1, 0,
501 iir_inp_mux_text);
502RX_MACRO_DAPM_ENUM(iir1_inp2, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2, 0,
503 iir_inp_mux_text);
504RX_MACRO_DAPM_ENUM(iir1_inp3, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3, 0,
505 iir_inp_mux_text);
506
507RX_MACRO_DAPM_ENUM(rx_int0_1_interp, SND_SOC_NOPM, 0,
508 rx_int0_1_interp_mux_text);
509RX_MACRO_DAPM_ENUM(rx_int1_1_interp, SND_SOC_NOPM, 0,
510 rx_int1_1_interp_mux_text);
511RX_MACRO_DAPM_ENUM(rx_int2_1_interp, SND_SOC_NOPM, 0,
512 rx_int2_1_interp_mux_text);
513
514RX_MACRO_DAPM_ENUM(rx_int0_2_interp, SND_SOC_NOPM, 0,
515 rx_int0_2_interp_mux_text);
516RX_MACRO_DAPM_ENUM(rx_int1_2_interp, SND_SOC_NOPM, 0,
517 rx_int1_2_interp_mux_text);
518RX_MACRO_DAPM_ENUM(rx_int2_2_interp, SND_SOC_NOPM, 0,
519 rx_int2_2_interp_mux_text);
520
521RX_MACRO_DAPM_ENUM_EXT(rx_int0_dem_inp, BOLERO_CDC_RX_RX0_RX_PATH_CFG1, 0,
522 rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double,
523 rx_macro_int_dem_inp_mux_put);
524RX_MACRO_DAPM_ENUM_EXT(rx_int1_dem_inp, BOLERO_CDC_RX_RX1_RX_PATH_CFG1, 0,
525 rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double,
526 rx_macro_int_dem_inp_mux_put);
527
528RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx0, SND_SOC_NOPM, 0, rx_macro_mux_text,
529 rx_macro_mux_get, rx_macro_mux_put);
530RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx1, SND_SOC_NOPM, 0, rx_macro_mux_text,
531 rx_macro_mux_get, rx_macro_mux_put);
532RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx2, SND_SOC_NOPM, 0, rx_macro_mux_text,
533 rx_macro_mux_get, rx_macro_mux_put);
534RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx3, SND_SOC_NOPM, 0, rx_macro_mux_text,
535 rx_macro_mux_get, rx_macro_mux_put);
536RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx4, SND_SOC_NOPM, 0, rx_macro_mux_text,
537 rx_macro_mux_get, rx_macro_mux_put);
538RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx5, SND_SOC_NOPM, 0, rx_macro_mux_text,
539 rx_macro_mux_get, rx_macro_mux_put);
540
Vatsal Buchac2d6c222018-11-30 18:46:37 +0530541static const char * const rx_echo_mux_text[] = {
542 "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2"
543};
544
545static const struct soc_enum rx_mix_tx2_mux_enum =
546 SOC_ENUM_SINGLE(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5, 0, 4,
547 rx_echo_mux_text);
548
549static const struct snd_kcontrol_new rx_mix_tx2_mux =
550 SOC_DAPM_ENUM("RX MIX TX2_MUX Mux", rx_mix_tx2_mux_enum);
551
552static const struct soc_enum rx_mix_tx1_mux_enum =
553 SOC_ENUM_SINGLE(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, 4,
554 rx_echo_mux_text);
555
556static const struct snd_kcontrol_new rx_mix_tx1_mux =
557 SOC_DAPM_ENUM("RX MIX TX1_MUX Mux", rx_mix_tx1_mux_enum);
558
559static const struct soc_enum rx_mix_tx0_mux_enum =
560 SOC_ENUM_SINGLE(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 4, 4,
561 rx_echo_mux_text);
562
563static const struct snd_kcontrol_new rx_mix_tx0_mux =
564 SOC_DAPM_ENUM("RX MIX TX0_MUX Mux", rx_mix_tx0_mux_enum);
565
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530566static struct snd_soc_dai_ops rx_macro_dai_ops = {
567 .hw_params = rx_macro_hw_params,
568 .get_channel_map = rx_macro_get_channel_map,
569};
570
571static struct snd_soc_dai_driver rx_macro_dai[] = {
572 {
573 .name = "rx_macro_rx1",
574 .id = RX_MACRO_AIF1_PB,
575 .playback = {
576 .stream_name = "RX_MACRO_AIF1 Playback",
577 .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES,
578 .formats = RX_MACRO_FORMATS,
579 .rate_max = 384000,
580 .rate_min = 8000,
581 .channels_min = 1,
582 .channels_max = 2,
583 },
584 .ops = &rx_macro_dai_ops,
585 },
586 {
587 .name = "rx_macro_rx2",
588 .id = RX_MACRO_AIF2_PB,
589 .playback = {
590 .stream_name = "RX_MACRO_AIF2 Playback",
591 .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES,
592 .formats = RX_MACRO_FORMATS,
593 .rate_max = 384000,
594 .rate_min = 8000,
595 .channels_min = 1,
596 .channels_max = 2,
597 },
598 .ops = &rx_macro_dai_ops,
599 },
600 {
601 .name = "rx_macro_rx3",
602 .id = RX_MACRO_AIF3_PB,
603 .playback = {
604 .stream_name = "RX_MACRO_AIF3 Playback",
605 .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES,
606 .formats = RX_MACRO_FORMATS,
607 .rate_max = 384000,
608 .rate_min = 8000,
609 .channels_min = 1,
610 .channels_max = 2,
611 },
612 .ops = &rx_macro_dai_ops,
613 },
614 {
615 .name = "rx_macro_rx4",
616 .id = RX_MACRO_AIF4_PB,
617 .playback = {
618 .stream_name = "RX_MACRO_AIF4 Playback",
619 .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES,
620 .formats = RX_MACRO_FORMATS,
621 .rate_max = 384000,
622 .rate_min = 8000,
623 .channels_min = 1,
624 .channels_max = 2,
625 },
626 .ops = &rx_macro_dai_ops,
627 },
Vatsal Buchac2d6c222018-11-30 18:46:37 +0530628 {
629 .name = "rx_macro_echo",
630 .id = RX_MACRO_AIF_ECHO,
631 .capture = {
632 .stream_name = "RX_AIF_ECHO Capture",
633 .rates = RX_MACRO_ECHO_RATES,
634 .formats = RX_MACRO_ECHO_FORMATS,
635 .rate_max = 48000,
636 .rate_min = 8000,
637 .channels_min = 1,
638 .channels_max = 3,
639 },
640 .ops = &rx_macro_dai_ops,
641 },
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530642};
643
Laxminath Kasam497a6512018-09-17 16:11:52 +0530644static int get_impedance_index(int imped)
645{
646 int i = 0;
647
648 if (imped < imped_index[i].imped_val) {
649 pr_debug("%s, detected impedance is less than %d Ohm\n",
650 __func__, imped_index[i].imped_val);
651 i = 0;
652 goto ret;
653 }
654 if (imped >= imped_index[ARRAY_SIZE(imped_index) - 1].imped_val) {
655 pr_debug("%s, detected impedance is greater than %d Ohm\n",
656 __func__,
657 imped_index[ARRAY_SIZE(imped_index) - 1].imped_val);
658 i = ARRAY_SIZE(imped_index) - 1;
659 goto ret;
660 }
661 for (i = 0; i < ARRAY_SIZE(imped_index) - 1; i++) {
662 if (imped >= imped_index[i].imped_val &&
663 imped < imped_index[i + 1].imped_val)
664 break;
665 }
666ret:
667 pr_debug("%s: selected impedance index = %d\n",
668 __func__, imped_index[i].index);
669 return imped_index[i].index;
670}
671
672/*
673 * rx_macro_wcd_clsh_imped_config -
674 * This function updates HPHL and HPHR gain settings
675 * according to the impedance value.
676 *
Meng Wang15c825d2018-09-06 10:49:18 +0800677 * @component: codec pointer handle
Laxminath Kasam497a6512018-09-17 16:11:52 +0530678 * @imped: impedance value of HPHL/R
679 * @reset: bool variable to reset registers when teardown
680 */
Meng Wang15c825d2018-09-06 10:49:18 +0800681static void rx_macro_wcd_clsh_imped_config(struct snd_soc_component *component,
Laxminath Kasam497a6512018-09-17 16:11:52 +0530682 int imped, bool reset)
683{
684 int i;
685 int index = 0;
686 int table_size;
687
688 static const struct rx_macro_reg_mask_val
689 (*imped_table_ptr)[MAX_IMPED_PARAMS];
690
691 table_size = ARRAY_SIZE(imped_table);
692 imped_table_ptr = imped_table;
693 /* reset = 1, which means request is to reset the register values */
694 if (reset) {
695 for (i = 0; i < MAX_IMPED_PARAMS; i++)
Meng Wang15c825d2018-09-06 10:49:18 +0800696 snd_soc_component_update_bits(component,
Laxminath Kasam497a6512018-09-17 16:11:52 +0530697 imped_table_ptr[index][i].reg,
698 imped_table_ptr[index][i].mask, 0);
699 return;
700 }
701 index = get_impedance_index(imped);
702 if (index >= (ARRAY_SIZE(imped_index) - 1)) {
703 pr_debug("%s, impedance not in range = %d\n", __func__, imped);
704 return;
705 }
706 if (index >= table_size) {
707 pr_debug("%s, impedance index not in range = %d\n", __func__,
708 index);
709 return;
710 }
711 for (i = 0; i < MAX_IMPED_PARAMS; i++)
Meng Wang15c825d2018-09-06 10:49:18 +0800712 snd_soc_component_update_bits(component,
Laxminath Kasam497a6512018-09-17 16:11:52 +0530713 imped_table_ptr[index][i].reg,
714 imped_table_ptr[index][i].mask,
715 imped_table_ptr[index][i].val);
716}
717
Meng Wang15c825d2018-09-06 10:49:18 +0800718static bool rx_macro_get_data(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530719 struct device **rx_dev,
720 struct rx_macro_priv **rx_priv,
721 const char *func_name)
722{
Meng Wang15c825d2018-09-06 10:49:18 +0800723 *rx_dev = bolero_get_device_ptr(component->dev, RX_MACRO);
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530724
725 if (!(*rx_dev)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800726 dev_err(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530727 "%s: null device for macro!\n", func_name);
728 return false;
729 }
730
731 *rx_priv = dev_get_drvdata((*rx_dev));
732 if (!(*rx_priv)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800733 dev_err(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530734 "%s: priv is null for macro!\n", func_name);
735 return false;
736 }
737
Meng Wang15c825d2018-09-06 10:49:18 +0800738 if (!(*rx_priv)->component) {
739 dev_err(component->dev,
Vatsal Buchac2d6c222018-11-30 18:46:37 +0530740 "%s: rx_priv component is not initialized!\n", func_name);
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530741 return false;
742 }
743
744 return true;
745}
746
Sudheer Papothia3e969d2018-10-27 06:22:10 +0530747static int rx_macro_set_port_map(struct snd_soc_component *component,
748 u32 usecase, u32 size, void *data)
749{
750 struct device *rx_dev = NULL;
751 struct rx_macro_priv *rx_priv = NULL;
752 struct swrm_port_config port_cfg;
753 int ret = 0;
754
755 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
756 return -EINVAL;
757
758 memset(&port_cfg, 0, sizeof(port_cfg));
759 port_cfg.uc = usecase;
760 port_cfg.size = size;
761 port_cfg.params = data;
762
763 ret = swrm_wcd_notify(
764 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
765 SWR_SET_PORT_MAP, &port_cfg);
766
767 return ret;
768}
769
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530770static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
771 struct snd_ctl_elem_value *ucontrol)
772{
773 struct snd_soc_dapm_widget *widget =
774 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800775 struct snd_soc_component *component =
776 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530777 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
778 unsigned int val = 0;
779 unsigned short look_ahead_dly_reg =
780 BOLERO_CDC_RX_RX0_RX_PATH_CFG0;
781
782 val = ucontrol->value.enumerated.item[0];
783 if (val >= e->items)
784 return -EINVAL;
785
Meng Wang15c825d2018-09-06 10:49:18 +0800786 dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530787 widget->name, val);
788
789 if (e->reg == BOLERO_CDC_RX_RX0_RX_PATH_CFG1)
790 look_ahead_dly_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0;
791 else if (e->reg == BOLERO_CDC_RX_RX1_RX_PATH_CFG1)
792 look_ahead_dly_reg = BOLERO_CDC_RX_RX1_RX_PATH_CFG0;
793
794 /* Set Look Ahead Delay */
Meng Wang15c825d2018-09-06 10:49:18 +0800795 snd_soc_component_update_bits(component, look_ahead_dly_reg,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530796 0x08, (val ? 0x08 : 0x00));
797 /* Set DEM INP Select */
798 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
799}
800
801static int rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
802 u8 rate_reg_val,
803 u32 sample_rate)
804{
805 u8 int_1_mix1_inp = 0;
806 u32 j = 0, port = 0;
807 u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
808 u16 int_fs_reg = 0;
809 u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
810 u8 inp0_sel = 0, inp1_sel = 0, inp2_sel = 0;
Meng Wang15c825d2018-09-06 10:49:18 +0800811 struct snd_soc_component *component = dai->component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530812 struct device *rx_dev = NULL;
813 struct rx_macro_priv *rx_priv = NULL;
814
Meng Wang15c825d2018-09-06 10:49:18 +0800815 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530816 return -EINVAL;
817
818 for_each_set_bit(port, &rx_priv->active_ch_mask[dai->id],
819 RX_MACRO_PORTS_MAX) {
820 int_1_mix1_inp = port;
821 if ((int_1_mix1_inp < RX_MACRO_RX0) ||
822 (int_1_mix1_inp > RX_MACRO_PORTS_MAX)) {
823 pr_err("%s: Invalid RX port, Dai ID is %d\n",
824 __func__, dai->id);
825 return -EINVAL;
826 }
827
828 int_mux_cfg0 = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0;
829
830 /*
831 * Loop through all interpolator MUX inputs and find out
832 * to which interpolator input, the rx port
833 * is connected
834 */
835 for (j = 0; j < INTERP_MAX; j++) {
836 int_mux_cfg1 = int_mux_cfg0 + 4;
837
Meng Wang15c825d2018-09-06 10:49:18 +0800838 int_mux_cfg0_val = snd_soc_component_read32(
839 component, int_mux_cfg0);
840 int_mux_cfg1_val = snd_soc_component_read32(
841 component, int_mux_cfg1);
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530842 inp0_sel = int_mux_cfg0_val & 0x07;
843 inp1_sel = (int_mux_cfg0_val >> 4) & 0x038;
844 inp2_sel = (int_mux_cfg1_val >> 4) & 0x038;
845 if ((inp0_sel == int_1_mix1_inp) ||
846 (inp1_sel == int_1_mix1_inp) ||
847 (inp2_sel == int_1_mix1_inp)) {
848 int_fs_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL +
849 0x80 * j;
850 pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_1\n",
851 __func__, dai->id, j);
852 pr_debug("%s: set INT%u_1 sample rate to %u\n",
853 __func__, j, sample_rate);
854 /* sample_rate is in Hz */
Meng Wang15c825d2018-09-06 10:49:18 +0800855 snd_soc_component_update_bits(component,
856 int_fs_reg,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530857 0x0F, rate_reg_val);
858 }
859 int_mux_cfg0 += 8;
860 }
861 }
862
863 return 0;
864}
865
866static int rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
867 u8 rate_reg_val,
868 u32 sample_rate)
869{
870 u8 int_2_inp = 0;
871 u32 j = 0, port = 0;
872 u16 int_mux_cfg1 = 0, int_fs_reg = 0;
873 u8 int_mux_cfg1_val = 0;
Meng Wang15c825d2018-09-06 10:49:18 +0800874 struct snd_soc_component *component = dai->component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530875 struct device *rx_dev = NULL;
876 struct rx_macro_priv *rx_priv = NULL;
877
Meng Wang15c825d2018-09-06 10:49:18 +0800878 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530879 return -EINVAL;
880
881 for_each_set_bit(port, &rx_priv->active_ch_mask[dai->id],
882 RX_MACRO_PORTS_MAX) {
883 int_2_inp = port;
884 if ((int_2_inp < RX_MACRO_RX0) ||
885 (int_2_inp > RX_MACRO_PORTS_MAX)) {
886 pr_err("%s: Invalid RX port, Dai ID is %d\n",
887 __func__, dai->id);
888 return -EINVAL;
889 }
890
891 int_mux_cfg1 = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1;
892 for (j = 0; j < INTERP_MAX; j++) {
Meng Wang15c825d2018-09-06 10:49:18 +0800893 int_mux_cfg1_val = snd_soc_component_read32(
894 component, int_mux_cfg1) &
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530895 0x07;
896 if (int_mux_cfg1_val == int_2_inp) {
897 int_fs_reg = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL +
898 0x80 * j;
899 pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_2\n",
900 __func__, dai->id, j);
901 pr_debug("%s: set INT%u_2 sample rate to %u\n",
902 __func__, j, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +0800903 snd_soc_component_update_bits(
904 component, int_fs_reg,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530905 0x0F, rate_reg_val);
906 }
907 int_mux_cfg1 += 8;
908 }
909 }
910 return 0;
911}
912
Laxminath Kasamac396d52018-09-06 12:53:26 +0530913static bool rx_macro_is_fractional_sample_rate(u32 sample_rate)
914{
915 switch (sample_rate) {
916 case SAMPLING_RATE_44P1KHZ:
917 case SAMPLING_RATE_88P2KHZ:
918 case SAMPLING_RATE_176P4KHZ:
919 case SAMPLING_RATE_352P8KHZ:
920 return true;
921 default:
922 return false;
923 }
924 return false;
925}
926
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530927static int rx_macro_set_interpolator_rate(struct snd_soc_dai *dai,
928 u32 sample_rate)
929{
Meng Wang15c825d2018-09-06 10:49:18 +0800930 struct snd_soc_component *component = dai->component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530931 int rate_val = 0;
932 int i = 0, ret = 0;
Laxminath Kasamac396d52018-09-06 12:53:26 +0530933 struct device *rx_dev = NULL;
934 struct rx_macro_priv *rx_priv = NULL;
935
Meng Wang15c825d2018-09-06 10:49:18 +0800936 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamac396d52018-09-06 12:53:26 +0530937 return -EINVAL;
938
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530939
940 for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) {
941 if (sample_rate == sr_val_tbl[i].sample_rate) {
942 rate_val = sr_val_tbl[i].rate_val;
Laxminath Kasamac396d52018-09-06 12:53:26 +0530943 if (rx_macro_is_fractional_sample_rate(sample_rate))
944 rx_priv->is_native_on = true;
945 else
946 rx_priv->is_native_on = false;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530947 break;
948 }
949 }
950 if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800951 dev_err(component->dev, "%s: Unsupported sample rate: %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530952 __func__, sample_rate);
953 return -EINVAL;
954 }
955
956 ret = rx_macro_set_prim_interpolator_rate(dai, (u8)rate_val, sample_rate);
957 if (ret)
958 return ret;
959 ret = rx_macro_set_mix_interpolator_rate(dai, (u8)rate_val, sample_rate);
960 if (ret)
961 return ret;
962
963 return ret;
964}
965
966static int rx_macro_hw_params(struct snd_pcm_substream *substream,
967 struct snd_pcm_hw_params *params,
968 struct snd_soc_dai *dai)
969{
Meng Wang15c825d2018-09-06 10:49:18 +0800970 struct snd_soc_component *component = dai->component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530971 int ret = 0;
972 struct device *rx_dev = NULL;
973 struct rx_macro_priv *rx_priv = NULL;
974
Meng Wang15c825d2018-09-06 10:49:18 +0800975 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530976 return -EINVAL;
977
Meng Wang15c825d2018-09-06 10:49:18 +0800978 dev_dbg(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530979 "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
980 dai->name, dai->id, params_rate(params),
981 params_channels(params));
982
983 switch (substream->stream) {
984 case SNDRV_PCM_STREAM_PLAYBACK:
985 ret = rx_macro_set_interpolator_rate(dai, params_rate(params));
986 if (ret) {
987 pr_err("%s: cannot set sample rate: %u\n",
988 __func__, params_rate(params));
989 return ret;
990 }
991 rx_priv->bit_width[dai->id] = params_width(params);
992 break;
993 case SNDRV_PCM_STREAM_CAPTURE:
994 default:
995 break;
996 }
997 return 0;
998}
999
1000static int rx_macro_get_channel_map(struct snd_soc_dai *dai,
1001 unsigned int *tx_num, unsigned int *tx_slot,
1002 unsigned int *rx_num, unsigned int *rx_slot)
1003{
Meng Wang15c825d2018-09-06 10:49:18 +08001004 struct snd_soc_component *component = dai->component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301005 struct device *rx_dev = NULL;
1006 struct rx_macro_priv *rx_priv = NULL;
1007 unsigned int temp = 0, ch_mask = 0;
Vatsal Buchac2d6c222018-11-30 18:46:37 +05301008 u16 val = 0, mask = 0, cnt = 0, i = 0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301009
Meng Wang15c825d2018-09-06 10:49:18 +08001010 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301011 return -EINVAL;
1012
1013 switch (dai->id) {
1014 case RX_MACRO_AIF1_PB:
1015 case RX_MACRO_AIF2_PB:
1016 case RX_MACRO_AIF3_PB:
1017 case RX_MACRO_AIF4_PB:
1018 for_each_set_bit(temp, &rx_priv->active_ch_mask[dai->id],
1019 RX_MACRO_PORTS_MAX) {
Vatsal Bucha1a96a612018-11-26 13:04:56 +05301020 ch_mask |= (1 << temp);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301021 if (++i == RX_MACRO_MAX_DMA_CH_PER_PORT)
1022 break;
1023 }
1024 *rx_slot = ch_mask;
1025 *rx_num = rx_priv->active_ch_cnt[dai->id];
1026 break;
Vatsal Buchac2d6c222018-11-30 18:46:37 +05301027 case RX_MACRO_AIF_ECHO:
1028 val = snd_soc_component_read32(component,
1029 BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4);
1030 if (val & RX_MACRO_EC_MIX_TX0_MASK) {
1031 mask |= 0x1;
1032 cnt++;
1033 }
1034 if (val & RX_MACRO_EC_MIX_TX1_MASK) {
1035 mask |= 0x2;
1036 cnt++;
1037 }
1038 val = snd_soc_component_read32(component,
1039 BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5);
1040 if (val & RX_MACRO_EC_MIX_TX2_MASK) {
1041 mask |= 0x4;
1042 cnt++;
1043 }
1044 *tx_slot = mask;
1045 *tx_num = cnt;
1046 break;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301047 default:
1048 dev_err(rx_dev, "%s: Invalid AIF\n", __func__);
1049 break;
1050 }
1051 return 0;
1052}
1053
1054static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv,
1055 bool mclk_enable, bool dapm)
1056{
1057 struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL);
Laxminath Kasambee08192018-07-01 14:38:55 +05301058 int ret = 0, mclk_mux = MCLK_MUX0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301059
Tanya Dixit8530fb92018-09-14 16:01:25 +05301060 if (regmap == NULL) {
1061 dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__);
1062 return -EINVAL;
1063 }
1064
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301065 dev_dbg(rx_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
1066 __func__, mclk_enable, dapm, rx_priv->rx_mclk_users);
1067
1068 mutex_lock(&rx_priv->mclk_lock);
1069 if (mclk_enable) {
1070 if (rx_priv->rx_mclk_users == 0) {
Laxminath Kasam7b9cdb62018-09-28 16:28:54 +05301071 if (rx_priv->is_native_on)
1072 mclk_mux = MCLK_MUX1;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301073 ret = bolero_request_clock(rx_priv->dev,
Laxminath Kasambee08192018-07-01 14:38:55 +05301074 RX_MACRO, mclk_mux, true);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301075 if (ret < 0) {
1076 dev_err(rx_priv->dev,
1077 "%s: rx request clock enable failed\n",
1078 __func__);
1079 goto exit;
1080 }
Laxminath Kasambee08192018-07-01 14:38:55 +05301081 rx_priv->mclk_mux = mclk_mux;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301082 regcache_mark_dirty(regmap);
1083 regcache_sync_region(regmap,
1084 RX_START_OFFSET,
1085 RX_MAX_OFFSET);
1086 regmap_update_bits(regmap,
1087 BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL,
1088 0x01, 0x01);
1089 regmap_update_bits(regmap,
Ramprasad Katkam9c2394a2018-08-23 13:13:48 +05301090 BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL,
1091 0x02, 0x02);
1092 regmap_update_bits(regmap,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301093 BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
1094 0x01, 0x01);
1095 }
1096 rx_priv->rx_mclk_users++;
1097 } else {
1098 if (rx_priv->rx_mclk_users <= 0) {
1099 dev_err(rx_priv->dev, "%s: clock already disabled\n",
1100 __func__);
1101 rx_priv->rx_mclk_users = 0;
1102 goto exit;
1103 }
1104 rx_priv->rx_mclk_users--;
1105 if (rx_priv->rx_mclk_users == 0) {
1106 regmap_update_bits(regmap,
1107 BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
1108 0x01, 0x00);
1109 regmap_update_bits(regmap,
1110 BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL,
1111 0x01, 0x00);
Laxminath Kasam7b9cdb62018-09-28 16:28:54 +05301112 mclk_mux = rx_priv->mclk_mux;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301113 bolero_request_clock(rx_priv->dev,
Laxminath Kasambee08192018-07-01 14:38:55 +05301114 RX_MACRO, mclk_mux, false);
1115 rx_priv->mclk_mux = MCLK_MUX0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301116 }
1117 }
1118exit:
1119 mutex_unlock(&rx_priv->mclk_lock);
1120 return ret;
1121}
1122
1123static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w,
1124 struct snd_kcontrol *kcontrol, int event)
1125{
Meng Wang15c825d2018-09-06 10:49:18 +08001126 struct snd_soc_component *component =
1127 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301128 int ret = 0;
1129 struct device *rx_dev = NULL;
1130 struct rx_macro_priv *rx_priv = NULL;
Laxminath Kasamac396d52018-09-06 12:53:26 +05301131 int mclk_freq = MCLK_FREQ;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301132
Meng Wang15c825d2018-09-06 10:49:18 +08001133 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301134 return -EINVAL;
1135
1136 dev_dbg(rx_dev, "%s: event = %d\n", __func__, event);
1137 switch (event) {
1138 case SND_SOC_DAPM_PRE_PMU:
Laxminath Kasambee08192018-07-01 14:38:55 +05301139 /* if swr_clk_users > 0, call device down */
1140 if (rx_priv->swr_clk_users > 0) {
1141 if ((rx_priv->mclk_mux == MCLK_MUX0 &&
1142 rx_priv->is_native_on) ||
Laxminath Kasamac396d52018-09-06 12:53:26 +05301143 (rx_priv->mclk_mux == MCLK_MUX1 &&
Laxminath Kasambee08192018-07-01 14:38:55 +05301144 !rx_priv->is_native_on)) {
1145 swrm_wcd_notify(
1146 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
1147 SWR_DEVICE_DOWN, NULL);
1148 }
1149 }
Laxminath Kasamac396d52018-09-06 12:53:26 +05301150 if (rx_priv->is_native_on)
1151 mclk_freq = MCLK_FREQ_NATIVE;
1152 swrm_wcd_notify(
1153 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
1154 SWR_CLK_FREQ, &mclk_freq);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301155 ret = rx_macro_mclk_enable(rx_priv, 1, true);
Ramprasad Katkam452772a2019-01-07 17:30:36 +05301156 if (ret)
1157 rx_priv->dapm_mclk_enable = false;
1158 else
1159 rx_priv->dapm_mclk_enable = true;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301160 break;
1161 case SND_SOC_DAPM_POST_PMD:
Ramprasad Katkam452772a2019-01-07 17:30:36 +05301162 if (rx_priv->dapm_mclk_enable)
1163 ret = rx_macro_mclk_enable(rx_priv, 0, true);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301164 break;
1165 default:
1166 dev_err(rx_priv->dev,
1167 "%s: invalid DAPM event %d\n", __func__, event);
1168 ret = -EINVAL;
1169 }
1170 return ret;
1171}
1172
1173static int rx_macro_mclk_ctrl(struct device *dev, bool enable)
1174{
1175 struct rx_macro_priv *rx_priv = dev_get_drvdata(dev);
1176 int ret = 0;
1177
1178 if (enable) {
1179 ret = clk_prepare_enable(rx_priv->rx_core_clk);
1180 if (ret < 0) {
1181 dev_err(dev, "%s:rx mclk enable failed\n", __func__);
1182 return ret;
1183 }
1184 ret = clk_prepare_enable(rx_priv->rx_npl_clk);
1185 if (ret < 0) {
1186 clk_disable_unprepare(rx_priv->rx_core_clk);
1187 dev_err(dev, "%s:rx npl_clk enable failed\n",
1188 __func__);
1189 return ret;
1190 }
Laxminath Kasam701e3582018-10-15 20:06:09 +05301191 if (rx_priv->rx_mclk_cnt++ == 0) {
1192 if (rx_priv->dev_up)
1193 iowrite32(0x1, rx_priv->rx_mclk_mode_muxsel);
1194 }
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301195 } else {
1196 if (rx_priv->rx_mclk_cnt <= 0) {
1197 dev_dbg(dev, "%s:rx mclk already disabled\n", __func__);
1198 rx_priv->rx_mclk_cnt = 0;
1199 return 0;
1200 }
Laxminath Kasam701e3582018-10-15 20:06:09 +05301201 if (--rx_priv->rx_mclk_cnt == 0) {
1202 if (rx_priv->dev_up)
1203 iowrite32(0x0, rx_priv->rx_mclk_mode_muxsel);
1204 }
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301205 clk_disable_unprepare(rx_priv->rx_npl_clk);
1206 clk_disable_unprepare(rx_priv->rx_core_clk);
1207 }
1208
1209 return 0;
1210}
1211
Meng Wang15c825d2018-09-06 10:49:18 +08001212static int rx_macro_event_handler(struct snd_soc_component *component,
1213 u16 event, u32 data)
Laxminath Kasam497a6512018-09-17 16:11:52 +05301214{
Vatsal Bucha53b4e142018-11-13 19:36:25 +05301215 u16 reg = 0, reg_mix = 0, rx_idx = 0, mute = 0x0, val = 0;
Laxminath Kasam497a6512018-09-17 16:11:52 +05301216 struct device *rx_dev = NULL;
1217 struct rx_macro_priv *rx_priv = NULL;
1218
Meng Wang15c825d2018-09-06 10:49:18 +08001219 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasam497a6512018-09-17 16:11:52 +05301220 return -EINVAL;
1221
1222 switch (event) {
1223 case BOLERO_MACRO_EVT_RX_MUTE:
1224 rx_idx = data >> 0x10;
1225 mute = data & 0xffff;
Vatsal Bucha53b4e142018-11-13 19:36:25 +05301226 val = mute ? 0x10 : 0x00;
Laxminath Kasam497a6512018-09-17 16:11:52 +05301227 reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + (rx_idx *
1228 RX_MACRO_RX_PATH_OFFSET);
1229 reg_mix = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL + (rx_idx *
1230 RX_MACRO_RX_PATH_OFFSET);
Meng Wang15c825d2018-09-06 10:49:18 +08001231 snd_soc_component_update_bits(component, reg,
1232 0x10, val);
1233 snd_soc_component_update_bits(component, reg_mix,
1234 0x10, val);
Laxminath Kasam497a6512018-09-17 16:11:52 +05301235 break;
1236 case BOLERO_MACRO_EVT_IMPED_TRUE:
Meng Wang15c825d2018-09-06 10:49:18 +08001237 rx_macro_wcd_clsh_imped_config(component, data, true);
Laxminath Kasam497a6512018-09-17 16:11:52 +05301238 break;
1239 case BOLERO_MACRO_EVT_IMPED_FALSE:
Meng Wang15c825d2018-09-06 10:49:18 +08001240 rx_macro_wcd_clsh_imped_config(component, data, false);
Laxminath Kasam497a6512018-09-17 16:11:52 +05301241 break;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301242 case BOLERO_MACRO_EVT_SSR_DOWN:
Laxminath Kasam701e3582018-10-15 20:06:09 +05301243 rx_priv->dev_up = false;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301244 swrm_wcd_notify(
1245 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
Ramprasad Katkam5ee54ae2018-12-19 18:56:00 +05301246 SWR_DEVICE_DOWN, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301247 swrm_wcd_notify(
1248 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
Ramprasad Katkam5ee54ae2018-12-19 18:56:00 +05301249 SWR_DEVICE_SSR_DOWN, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301250 break;
1251 case BOLERO_MACRO_EVT_SSR_UP:
Laxminath Kasam701e3582018-10-15 20:06:09 +05301252 rx_priv->dev_up = true;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05301253 /* reset swr after ssr/pdr */
1254 rx_priv->reset_swr = true;
Laxminath Kasam701e3582018-10-15 20:06:09 +05301255 /* enable&disable MCLK_MUX1 to reset GFMUX reg */
1256 bolero_request_clock(rx_priv->dev,
1257 RX_MACRO, MCLK_MUX1, true);
1258 bolero_request_clock(rx_priv->dev,
1259 RX_MACRO, MCLK_MUX1, false);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301260 swrm_wcd_notify(
1261 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
1262 SWR_DEVICE_SSR_UP, NULL);
1263 break;
Laxminath Kasam497a6512018-09-17 16:11:52 +05301264 }
1265 return 0;
1266}
1267
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301268static int rx_macro_find_playback_dai_id_for_port(int port_id,
1269 struct rx_macro_priv *rx_priv)
1270{
1271 int i = 0;
1272
1273 for (i = RX_MACRO_AIF1_PB; i < RX_MACRO_MAX_DAIS; i++) {
1274 if (test_bit(port_id, &rx_priv->active_ch_mask[i]))
1275 return i;
1276 }
1277
1278 return -EINVAL;
1279}
1280
Meng Wang15c825d2018-09-06 10:49:18 +08001281static int rx_macro_set_idle_detect_thr(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301282 struct rx_macro_priv *rx_priv,
1283 int interp, int path_type)
1284{
1285 int port_id[4] = { 0, 0, 0, 0 };
Laxminath Kasamb7f823c2018-08-02 13:23:11 +05301286 int *port_ptr = NULL;
1287 int num_ports = 0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301288 int bit_width = 0, i = 0;
1289 int mux_reg = 0, mux_reg_val = 0;
1290 int dai_id = 0, idle_thr = 0;
1291
1292 if ((interp != INTERP_HPHL) && (interp != INTERP_HPHR))
1293 return 0;
1294
1295 if (!rx_priv->idle_det_cfg.hph_idle_detect_en)
1296 return 0;
1297
1298 port_ptr = &port_id[0];
1299 num_ports = 0;
1300
1301 /*
1302 * Read interpolator MUX input registers and find
1303 * which cdc_dma port is connected and store the port
1304 * numbers in port_id array.
1305 */
1306 if (path_type == INTERP_MIX_PATH) {
1307 mux_reg = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1 +
1308 2 * interp;
Meng Wang15c825d2018-09-06 10:49:18 +08001309 mux_reg_val = snd_soc_component_read32(component, mux_reg) &
1310 0x0f;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301311
1312 if ((mux_reg_val >= INTn_2_INP_SEL_RX0) &&
1313 (mux_reg_val <= INTn_2_INP_SEL_RX5)) {
1314 *port_ptr++ = mux_reg_val - 1;
1315 num_ports++;
1316 }
1317 }
1318
1319 if (path_type == INTERP_MAIN_PATH) {
1320 mux_reg = BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0 +
1321 2 * (interp - 1);
Meng Wang15c825d2018-09-06 10:49:18 +08001322 mux_reg_val = snd_soc_component_read32(component, mux_reg) &
1323 0x0f;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301324 i = RX_MACRO_INTERP_MUX_NUM_INPUTS;
1325
1326 while (i) {
1327 if ((mux_reg_val >= INTn_1_INP_SEL_RX0) &&
1328 (mux_reg_val <= INTn_1_INP_SEL_RX5)) {
1329 *port_ptr++ = mux_reg_val -
1330 INTn_1_INP_SEL_RX0;
1331 num_ports++;
1332 }
Meng Wang15c825d2018-09-06 10:49:18 +08001333 mux_reg_val =
1334 (snd_soc_component_read32(component, mux_reg) &
1335 0xf0) >> 4;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301336 mux_reg += 1;
1337 i--;
1338 }
1339 }
1340
Meng Wang15c825d2018-09-06 10:49:18 +08001341 dev_dbg(component->dev, "%s: num_ports: %d, ports[%d %d %d %d]\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301342 __func__, num_ports, port_id[0], port_id[1],
1343 port_id[2], port_id[3]);
1344
1345 i = 0;
1346 while (num_ports) {
1347 dai_id = rx_macro_find_playback_dai_id_for_port(port_id[i++],
1348 rx_priv);
1349
1350 if ((dai_id >= 0) && (dai_id < RX_MACRO_MAX_DAIS)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001351 dev_dbg(component->dev, "%s: dai_id: %d bit_width: %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301352 __func__, dai_id,
1353 rx_priv->bit_width[dai_id]);
1354
1355 if (rx_priv->bit_width[dai_id] > bit_width)
1356 bit_width = rx_priv->bit_width[dai_id];
1357 }
1358 num_ports--;
1359 }
1360
1361 switch (bit_width) {
1362 case 16:
1363 idle_thr = 0xff; /* F16 */
1364 break;
1365 case 24:
1366 case 32:
1367 idle_thr = 0x03; /* F22 */
1368 break;
1369 default:
1370 idle_thr = 0x00;
1371 break;
1372 }
1373
Meng Wang15c825d2018-09-06 10:49:18 +08001374 dev_dbg(component->dev, "%s: (new) idle_thr: %d, (cur) idle_thr: %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301375 __func__, idle_thr, rx_priv->idle_det_cfg.hph_idle_thr);
1376
1377 if ((rx_priv->idle_det_cfg.hph_idle_thr == 0) ||
1378 (idle_thr < rx_priv->idle_det_cfg.hph_idle_thr)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001379 snd_soc_component_write(component,
1380 BOLERO_CDC_RX_IDLE_DETECT_CFG3, idle_thr);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301381 rx_priv->idle_det_cfg.hph_idle_thr = idle_thr;
1382 }
1383
1384 return 0;
1385}
1386
1387static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
1388 struct snd_kcontrol *kcontrol, int event)
1389{
Meng Wang15c825d2018-09-06 10:49:18 +08001390 struct snd_soc_component *component =
1391 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301392 u16 gain_reg = 0, mix_reg = 0;
1393 struct device *rx_dev = NULL;
1394 struct rx_macro_priv *rx_priv = NULL;
1395
Meng Wang15c825d2018-09-06 10:49:18 +08001396 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301397 return -EINVAL;
1398
1399 if (w->shift >= INTERP_MAX) {
Meng Wang15c825d2018-09-06 10:49:18 +08001400 dev_err(component->dev, "%s: Invalid Interpolator value %d for name %s\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301401 __func__, w->shift, w->name);
1402 return -EINVAL;
1403 }
1404
1405 gain_reg = BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL +
1406 (w->shift * RX_MACRO_RX_PATH_OFFSET);
1407 mix_reg = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL +
1408 (w->shift * RX_MACRO_RX_PATH_OFFSET);
1409
Meng Wang15c825d2018-09-06 10:49:18 +08001410 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301411
1412 switch (event) {
1413 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001414 rx_macro_set_idle_detect_thr(component, rx_priv, w->shift,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301415 INTERP_MIX_PATH);
Meng Wang15c825d2018-09-06 10:49:18 +08001416 rx_macro_enable_interp_clk(component, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301417 /* Clk enable */
Meng Wang15c825d2018-09-06 10:49:18 +08001418 snd_soc_component_update_bits(component, mix_reg, 0x20, 0x20);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301419 break;
1420 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001421 snd_soc_component_write(component, gain_reg,
1422 snd_soc_component_read32(component, gain_reg));
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301423 break;
1424 case SND_SOC_DAPM_POST_PMD:
1425 /* Clk Disable */
Meng Wang15c825d2018-09-06 10:49:18 +08001426 snd_soc_component_update_bits(component, mix_reg, 0x20, 0x00);
1427 rx_macro_enable_interp_clk(component, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301428 /* Reset enable and disable */
Meng Wang15c825d2018-09-06 10:49:18 +08001429 snd_soc_component_update_bits(component, mix_reg, 0x40, 0x40);
1430 snd_soc_component_update_bits(component, mix_reg, 0x40, 0x00);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301431 break;
1432 }
1433
1434 return 0;
1435}
1436
1437static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w,
1438 struct snd_kcontrol *kcontrol,
1439 int event)
1440{
Meng Wang15c825d2018-09-06 10:49:18 +08001441 struct snd_soc_component *component =
1442 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301443 u16 gain_reg = 0;
1444 u16 reg = 0;
1445 struct device *rx_dev = NULL;
1446 struct rx_macro_priv *rx_priv = NULL;
1447
Meng Wang15c825d2018-09-06 10:49:18 +08001448 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301449 return -EINVAL;
1450
Meng Wang15c825d2018-09-06 10:49:18 +08001451 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301452
1453 if (w->shift >= INTERP_MAX) {
Meng Wang15c825d2018-09-06 10:49:18 +08001454 dev_err(component->dev, "%s: Invalid Interpolator value %d for name %s\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301455 __func__, w->shift, w->name);
1456 return -EINVAL;
1457 }
1458
1459 reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + (w->shift *
1460 RX_MACRO_RX_PATH_OFFSET);
1461 gain_reg = BOLERO_CDC_RX_RX0_RX_VOL_CTL + (w->shift *
1462 RX_MACRO_RX_PATH_OFFSET);
1463
1464 switch (event) {
1465 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001466 rx_macro_set_idle_detect_thr(component, rx_priv, w->shift,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301467 INTERP_MAIN_PATH);
Meng Wang15c825d2018-09-06 10:49:18 +08001468 rx_macro_enable_interp_clk(component, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301469 break;
1470 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001471 snd_soc_component_write(component, gain_reg,
1472 snd_soc_component_read32(component, gain_reg));
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301473 break;
1474 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001475 rx_macro_enable_interp_clk(component, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301476 break;
1477 }
1478
1479 return 0;
1480}
1481
Meng Wang15c825d2018-09-06 10:49:18 +08001482static int rx_macro_config_compander(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301483 struct rx_macro_priv *rx_priv,
1484 int interp_n, int event)
1485{
1486 int comp = 0;
1487 u16 comp_ctl0_reg = 0, rx_path_cfg0_reg = 0;
1488
1489 /* AUX does not have compander */
1490 if (interp_n == INTERP_AUX)
1491 return 0;
1492
1493 comp = interp_n;
Meng Wang15c825d2018-09-06 10:49:18 +08001494 dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301495 __func__, event, comp + 1, rx_priv->comp_enabled[comp]);
1496
1497 if (!rx_priv->comp_enabled[comp])
1498 return 0;
1499
1500 comp_ctl0_reg = BOLERO_CDC_RX_COMPANDER0_CTL0 +
1501 (comp * RX_MACRO_COMP_OFFSET);
1502 rx_path_cfg0_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0 +
1503 (comp * RX_MACRO_RX_PATH_OFFSET);
1504
1505 if (SND_SOC_DAPM_EVENT_ON(event)) {
1506 /* Enable Compander Clock */
Meng Wang15c825d2018-09-06 10:49:18 +08001507 snd_soc_component_update_bits(component, comp_ctl0_reg,
1508 0x01, 0x01);
1509 snd_soc_component_update_bits(component, comp_ctl0_reg,
1510 0x02, 0x02);
1511 snd_soc_component_update_bits(component, comp_ctl0_reg,
1512 0x02, 0x00);
1513 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1514 0x02, 0x02);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301515 }
1516
1517 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001518 snd_soc_component_update_bits(component, comp_ctl0_reg,
1519 0x04, 0x04);
1520 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1521 0x02, 0x00);
1522 snd_soc_component_update_bits(component, comp_ctl0_reg,
1523 0x01, 0x00);
1524 snd_soc_component_update_bits(component, comp_ctl0_reg,
1525 0x04, 0x00);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301526 }
1527
1528 return 0;
1529}
1530
Meng Wang15c825d2018-09-06 10:49:18 +08001531static void rx_macro_enable_softclip_clk(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301532 struct rx_macro_priv *rx_priv,
1533 bool enable)
1534{
1535 if (enable) {
1536 if (rx_priv->softclip_clk_users == 0)
Meng Wang15c825d2018-09-06 10:49:18 +08001537 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301538 BOLERO_CDC_RX_SOFTCLIP_CRC,
1539 0x01, 0x01);
1540 rx_priv->softclip_clk_users++;
1541 } else {
1542 rx_priv->softclip_clk_users--;
1543 if (rx_priv->softclip_clk_users == 0)
Meng Wang15c825d2018-09-06 10:49:18 +08001544 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301545 BOLERO_CDC_RX_SOFTCLIP_CRC,
1546 0x01, 0x00);
1547 }
1548}
1549
Meng Wang15c825d2018-09-06 10:49:18 +08001550static int rx_macro_config_softclip(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301551 struct rx_macro_priv *rx_priv,
1552 int event)
1553{
Meng Wang15c825d2018-09-06 10:49:18 +08001554 dev_dbg(component->dev, "%s: event %d, enabled %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301555 __func__, event, rx_priv->is_softclip_on);
1556
1557 if (!rx_priv->is_softclip_on)
1558 return 0;
1559
1560 if (SND_SOC_DAPM_EVENT_ON(event)) {
1561 /* Enable Softclip clock */
Meng Wang15c825d2018-09-06 10:49:18 +08001562 rx_macro_enable_softclip_clk(component, rx_priv, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301563 /* Enable Softclip control */
Meng Wang15c825d2018-09-06 10:49:18 +08001564 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301565 BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x01, 0x01);
1566 }
1567
1568 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001569 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301570 BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001571 rx_macro_enable_softclip_clk(component, rx_priv, false);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301572 }
1573
1574 return 0;
1575}
1576
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301577static inline void
1578rx_macro_enable_clsh_block(struct rx_macro_priv *rx_priv, bool enable)
1579{
1580 if ((enable && ++rx_priv->clsh_users == 1) ||
1581 (!enable && --rx_priv->clsh_users == 0))
Meng Wang15c825d2018-09-06 10:49:18 +08001582 snd_soc_component_update_bits(rx_priv->component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301583 BOLERO_CDC_RX_CLSH_CRC, 0x01,
1584 (u8) enable);
1585 if (rx_priv->clsh_users < 0)
1586 rx_priv->clsh_users = 0;
1587 dev_dbg(rx_priv->dev, "%s: clsh_users %d, enable %d", __func__,
1588 rx_priv->clsh_users, enable);
1589}
1590
Meng Wang15c825d2018-09-06 10:49:18 +08001591static int rx_macro_config_classh(struct snd_soc_component *component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301592 struct rx_macro_priv *rx_priv,
1593 int interp_n, int event)
1594{
1595 if (SND_SOC_DAPM_EVENT_OFF(event)) {
1596 rx_macro_enable_clsh_block(rx_priv, false);
1597 return 0;
1598 }
1599
1600 if (!SND_SOC_DAPM_EVENT_ON(event))
1601 return 0;
1602
1603 rx_macro_enable_clsh_block(rx_priv, true);
1604 if (interp_n == INTERP_HPHL ||
1605 interp_n == INTERP_HPHR) {
1606 /*
1607 * These K1 values depend on the Headphone Impedance
1608 * For now it is assumed to be 16 ohm
1609 */
Meng Wang15c825d2018-09-06 10:49:18 +08001610 snd_soc_component_update_bits(component,
1611 BOLERO_CDC_RX_CLSH_K1_LSB,
1612 0xFF, 0xC0);
1613 snd_soc_component_update_bits(component,
1614 BOLERO_CDC_RX_CLSH_K1_MSB,
1615 0x0F, 0x00);
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301616 }
1617 switch (interp_n) {
1618 case INTERP_HPHL:
1619 if (rx_priv->is_ear_mode_on)
Meng Wang15c825d2018-09-06 10:49:18 +08001620 snd_soc_component_update_bits(component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301621 BOLERO_CDC_RX_CLSH_HPH_V_PA,
1622 0x3F, 0x39);
1623 else
Meng Wang15c825d2018-09-06 10:49:18 +08001624 snd_soc_component_update_bits(component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301625 BOLERO_CDC_RX_CLSH_HPH_V_PA,
1626 0x3F, 0x1C);
Meng Wang15c825d2018-09-06 10:49:18 +08001627 snd_soc_component_update_bits(component,
1628 BOLERO_CDC_RX_CLSH_DECAY_CTRL,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301629 0x07, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001630 snd_soc_component_update_bits(component,
1631 BOLERO_CDC_RX_RX0_RX_PATH_CFG0,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301632 0x40, 0x40);
1633 break;
1634 case INTERP_HPHR:
Meng Wang15c825d2018-09-06 10:49:18 +08001635 snd_soc_component_update_bits(component,
1636 BOLERO_CDC_RX_CLSH_HPH_V_PA,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301637 0x3F, 0x1C);
Meng Wang15c825d2018-09-06 10:49:18 +08001638 snd_soc_component_update_bits(component,
1639 BOLERO_CDC_RX_CLSH_DECAY_CTRL,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301640 0x07, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001641 snd_soc_component_update_bits(component,
1642 BOLERO_CDC_RX_RX1_RX_PATH_CFG0,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301643 0x40, 0x40);
1644 break;
1645 case INTERP_AUX:
Meng Wang15c825d2018-09-06 10:49:18 +08001646 snd_soc_component_update_bits(component,
1647 BOLERO_CDC_RX_RX2_RX_PATH_CFG0,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301648 0x10, 0x10);
1649 break;
1650 }
1651
1652 return 0;
1653}
1654
Meng Wang15c825d2018-09-06 10:49:18 +08001655static void rx_macro_hd2_control(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301656 u16 interp_idx, int event)
1657{
1658 u16 hd2_scale_reg = 0;
1659 u16 hd2_enable_reg = 0;
1660
1661 switch (interp_idx) {
1662 case INTERP_HPHL:
Laxminath Kasam7adc34e2018-11-09 11:24:38 +05301663 hd2_scale_reg = BOLERO_CDC_RX_RX0_RX_PATH_SEC3;
1664 hd2_enable_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301665 break;
1666 case INTERP_HPHR:
Laxminath Kasam7adc34e2018-11-09 11:24:38 +05301667 hd2_scale_reg = BOLERO_CDC_RX_RX1_RX_PATH_SEC3;
1668 hd2_enable_reg = BOLERO_CDC_RX_RX1_RX_PATH_CFG0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301669 break;
1670 }
1671
1672 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001673 snd_soc_component_update_bits(component, hd2_scale_reg,
1674 0x3C, 0x14);
1675 snd_soc_component_update_bits(component, hd2_enable_reg,
1676 0x04, 0x04);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301677 }
1678
1679 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001680 snd_soc_component_update_bits(component, hd2_enable_reg,
1681 0x04, 0x00);
1682 snd_soc_component_update_bits(component, hd2_scale_reg,
1683 0x3C, 0x00);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301684 }
1685}
1686
1687static int rx_macro_get_compander(struct snd_kcontrol *kcontrol,
1688 struct snd_ctl_elem_value *ucontrol)
1689{
Meng Wang15c825d2018-09-06 10:49:18 +08001690 struct snd_soc_component *component =
1691 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301692 int comp = ((struct soc_multi_mixer_control *)
1693 kcontrol->private_value)->shift;
1694 struct device *rx_dev = NULL;
1695 struct rx_macro_priv *rx_priv = NULL;
1696
Meng Wang15c825d2018-09-06 10:49:18 +08001697 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301698 return -EINVAL;
1699
1700 ucontrol->value.integer.value[0] = rx_priv->comp_enabled[comp];
1701 return 0;
1702}
1703
1704static int rx_macro_set_compander(struct snd_kcontrol *kcontrol,
1705 struct snd_ctl_elem_value *ucontrol)
1706{
Meng Wang15c825d2018-09-06 10:49:18 +08001707 struct snd_soc_component *component =
1708 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301709 int comp = ((struct soc_multi_mixer_control *)
1710 kcontrol->private_value)->shift;
1711 int value = ucontrol->value.integer.value[0];
1712 struct device *rx_dev = NULL;
1713 struct rx_macro_priv *rx_priv = NULL;
1714
Meng Wang15c825d2018-09-06 10:49:18 +08001715 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301716 return -EINVAL;
1717
Meng Wang15c825d2018-09-06 10:49:18 +08001718 dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301719 __func__, comp + 1, rx_priv->comp_enabled[comp], value);
1720 rx_priv->comp_enabled[comp] = value;
1721
1722 return 0;
1723}
1724
1725static int rx_macro_mux_get(struct snd_kcontrol *kcontrol,
1726 struct snd_ctl_elem_value *ucontrol)
1727{
1728 struct snd_soc_dapm_widget *widget =
1729 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08001730 struct snd_soc_component *component =
1731 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301732 struct device *rx_dev = NULL;
1733 struct rx_macro_priv *rx_priv = NULL;
1734
Meng Wang15c825d2018-09-06 10:49:18 +08001735 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301736 return -EINVAL;
1737
1738 ucontrol->value.integer.value[0] =
1739 rx_priv->rx_port_value[widget->shift];
1740 return 0;
1741}
1742
1743static int rx_macro_mux_put(struct snd_kcontrol *kcontrol,
1744 struct snd_ctl_elem_value *ucontrol)
1745{
1746 struct snd_soc_dapm_widget *widget =
1747 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08001748 struct snd_soc_component *component =
1749 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301750 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1751 struct snd_soc_dapm_update *update = NULL;
1752 u32 rx_port_value = ucontrol->value.integer.value[0];
1753 u32 aif_rst = 0;
1754 struct device *rx_dev = NULL;
1755 struct rx_macro_priv *rx_priv = NULL;
1756
Meng Wang15c825d2018-09-06 10:49:18 +08001757 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301758 return -EINVAL;
1759
1760 aif_rst = rx_priv->rx_port_value[widget->shift];
1761 if (!rx_port_value) {
1762 if (aif_rst == 0) {
1763 dev_err(rx_dev, "%s:AIF reset already\n", __func__);
1764 return 0;
1765 }
1766 }
1767 rx_priv->rx_port_value[widget->shift] = rx_port_value;
1768
1769 switch (rx_port_value) {
1770 case 0:
1771 clear_bit(widget->shift,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05301772 &rx_priv->active_ch_mask[aif_rst]);
1773 rx_priv->active_ch_cnt[aif_rst]--;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301774 break;
1775 case 1:
1776 case 2:
1777 case 3:
1778 case 4:
1779 set_bit(widget->shift,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05301780 &rx_priv->active_ch_mask[rx_port_value]);
1781 rx_priv->active_ch_cnt[rx_port_value]++;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301782 break;
1783 default:
Meng Wang15c825d2018-09-06 10:49:18 +08001784 dev_err(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301785 "%s:Invalid AIF_ID for RX_MACRO MUX\n", __func__);
1786 goto err;
1787 }
1788
1789 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
1790 rx_port_value, e, update);
1791 return 0;
1792err:
1793 return -EINVAL;
1794}
1795
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301796static int rx_macro_get_ear_mode(struct snd_kcontrol *kcontrol,
1797 struct snd_ctl_elem_value *ucontrol)
1798{
Meng Wang15c825d2018-09-06 10:49:18 +08001799 struct snd_soc_component *component =
1800 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301801 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 Kasamd2d8d9f2018-08-06 18:10:14 +05301805 return -EINVAL;
1806
1807 ucontrol->value.integer.value[0] = rx_priv->is_ear_mode_on;
1808 return 0;
1809}
1810
1811static int rx_macro_put_ear_mode(struct snd_kcontrol *kcontrol,
1812 struct snd_ctl_elem_value *ucontrol)
1813{
Meng Wang15c825d2018-09-06 10:49:18 +08001814 struct snd_soc_component *component =
1815 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301816 struct device *rx_dev = NULL;
1817 struct rx_macro_priv *rx_priv = NULL;
1818
Meng Wang15c825d2018-09-06 10:49:18 +08001819 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301820 return -EINVAL;
1821
1822 rx_priv->is_ear_mode_on =
1823 (!ucontrol->value.integer.value[0] ? false : true);
1824 return 0;
1825}
1826
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05301827static int rx_macro_get_hph_hd2_mode(struct snd_kcontrol *kcontrol,
1828 struct snd_ctl_elem_value *ucontrol)
1829{
Meng Wang15c825d2018-09-06 10:49:18 +08001830 struct snd_soc_component *component =
1831 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05301832 struct device *rx_dev = NULL;
1833 struct rx_macro_priv *rx_priv = NULL;
1834
Meng Wang15c825d2018-09-06 10:49:18 +08001835 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05301836 return -EINVAL;
1837
1838 ucontrol->value.integer.value[0] = rx_priv->hph_hd2_mode;
1839 return 0;
1840}
1841
1842static int rx_macro_put_hph_hd2_mode(struct snd_kcontrol *kcontrol,
1843 struct snd_ctl_elem_value *ucontrol)
1844{
Meng Wang15c825d2018-09-06 10:49:18 +08001845 struct snd_soc_component *component =
1846 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05301847 struct device *rx_dev = NULL;
1848 struct rx_macro_priv *rx_priv = NULL;
1849
Meng Wang15c825d2018-09-06 10:49:18 +08001850 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05301851 return -EINVAL;
1852
1853 rx_priv->hph_hd2_mode = ucontrol->value.integer.value[0];
1854 return 0;
1855}
1856
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05301857static int rx_macro_get_hph_pwr_mode(struct snd_kcontrol *kcontrol,
1858 struct snd_ctl_elem_value *ucontrol)
1859{
Meng Wang15c825d2018-09-06 10:49:18 +08001860 struct snd_soc_component *component =
1861 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05301862 struct device *rx_dev = NULL;
1863 struct rx_macro_priv *rx_priv = NULL;
1864
Meng Wang15c825d2018-09-06 10:49:18 +08001865 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05301866 return -EINVAL;
1867
1868 ucontrol->value.integer.value[0] = rx_priv->hph_pwr_mode;
1869 return 0;
1870}
1871
1872static int rx_macro_put_hph_pwr_mode(struct snd_kcontrol *kcontrol,
1873 struct snd_ctl_elem_value *ucontrol)
1874{
Meng Wang15c825d2018-09-06 10:49:18 +08001875 struct snd_soc_component *component =
1876 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05301877 struct device *rx_dev = NULL;
1878 struct rx_macro_priv *rx_priv = NULL;
1879
Meng Wang15c825d2018-09-06 10:49:18 +08001880 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05301881 return -EINVAL;
1882
1883 rx_priv->hph_pwr_mode = ucontrol->value.integer.value[0];
1884 return 0;
1885}
1886
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301887static int rx_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
1888 struct snd_ctl_elem_value *ucontrol)
1889{
Meng Wang15c825d2018-09-06 10:49:18 +08001890 struct snd_soc_component *component =
1891 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301892
1893 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08001894 ((snd_soc_component_read32(
1895 component, BOLERO_CDC_RX_BCL_VBAT_CFG) & 0x04) ?
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301896 1 : 0);
1897
Meng Wang15c825d2018-09-06 10:49:18 +08001898 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301899 ucontrol->value.integer.value[0]);
1900
1901 return 0;
1902}
1903
1904static int rx_macro_vbat_bcl_gsm_mode_func_put(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);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301909
Meng Wang15c825d2018-09-06 10:49:18 +08001910 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301911 ucontrol->value.integer.value[0]);
1912
1913 /* Set Vbat register configuration for GSM mode bit based on value */
1914 if (ucontrol->value.integer.value[0])
Meng Wang15c825d2018-09-06 10:49:18 +08001915 snd_soc_component_update_bits(component,
1916 BOLERO_CDC_RX_BCL_VBAT_CFG,
1917 0x04, 0x04);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301918 else
Meng Wang15c825d2018-09-06 10:49:18 +08001919 snd_soc_component_update_bits(component,
1920 BOLERO_CDC_RX_BCL_VBAT_CFG,
1921 0x04, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301922
1923 return 0;
1924}
1925
1926static int rx_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
1927 struct snd_ctl_elem_value *ucontrol)
1928{
Meng Wang15c825d2018-09-06 10:49:18 +08001929 struct snd_soc_component *component =
1930 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301931 struct device *rx_dev = NULL;
1932 struct rx_macro_priv *rx_priv = NULL;
1933
Meng Wang15c825d2018-09-06 10:49:18 +08001934 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301935 return -EINVAL;
1936
1937 ucontrol->value.integer.value[0] = rx_priv->is_softclip_on;
1938
Meng Wang15c825d2018-09-06 10:49:18 +08001939 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301940 __func__, ucontrol->value.integer.value[0]);
1941
1942 return 0;
1943}
1944
1945static int rx_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
1946 struct snd_ctl_elem_value *ucontrol)
1947{
Meng Wang15c825d2018-09-06 10:49:18 +08001948 struct snd_soc_component *component =
1949 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301950 struct device *rx_dev = NULL;
1951 struct rx_macro_priv *rx_priv = NULL;
1952
Meng Wang15c825d2018-09-06 10:49:18 +08001953 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301954 return -EINVAL;
1955
Meng Wang15c825d2018-09-06 10:49:18 +08001956 rx_priv->is_softclip_on = ucontrol->value.integer.value[0];
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301957
Meng Wang15c825d2018-09-06 10:49:18 +08001958 dev_dbg(component->dev, "%s: soft clip enable = %d\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301959 rx_priv->is_softclip_on);
1960
1961 return 0;
1962}
1963
1964static int rx_macro_enable_vbat(struct snd_soc_dapm_widget *w,
1965 struct snd_kcontrol *kcontrol,
1966 int event)
1967{
Meng Wang15c825d2018-09-06 10:49:18 +08001968 struct snd_soc_component *component =
1969 snd_soc_dapm_to_component(w->dapm);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301970 struct device *rx_dev = NULL;
1971 struct rx_macro_priv *rx_priv = NULL;
1972
Meng Wang15c825d2018-09-06 10:49:18 +08001973 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
1974 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301975 return -EINVAL;
1976
1977 switch (event) {
1978 case SND_SOC_DAPM_PRE_PMU:
1979 /* Enable clock for VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001980 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301981 BOLERO_CDC_RX_BCL_VBAT_PATH_CTL, 0x10, 0x10);
1982 /* Enable VBAT block */
Meng Wang15c825d2018-09-06 10:49:18 +08001983 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301984 BOLERO_CDC_RX_BCL_VBAT_CFG, 0x01, 0x01);
1985 /* Update interpolator with 384K path */
Meng Wang15c825d2018-09-06 10:49:18 +08001986 snd_soc_component_update_bits(component,
1987 BOLERO_CDC_RX_RX2_RX_PATH_CFG1, 0x80, 0x80);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301988 /* Update DSM FS rate */
Meng Wang15c825d2018-09-06 10:49:18 +08001989 snd_soc_component_update_bits(component,
1990 BOLERO_CDC_RX_RX2_RX_PATH_SEC7, 0x02, 0x02);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301991 /* Use attenuation mode */
Meng Wang15c825d2018-09-06 10:49:18 +08001992 snd_soc_component_update_bits(component,
1993 BOLERO_CDC_RX_BCL_VBAT_CFG, 0x02, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301994 /* BCL block needs softclip clock to be enabled */
Meng Wang15c825d2018-09-06 10:49:18 +08001995 rx_macro_enable_softclip_clk(component, rx_priv, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301996 /* Enable VBAT at channel level */
Meng Wang15c825d2018-09-06 10:49:18 +08001997 snd_soc_component_update_bits(component,
1998 BOLERO_CDC_RX_RX2_RX_PATH_CFG1, 0x02, 0x02);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301999 /* Set the ATTK1 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08002000 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302001 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1,
2002 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08002003 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302004 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2,
2005 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08002006 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302007 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3,
2008 0xFF, 0x00);
2009 /* Set the ATTK2 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08002010 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302011 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4,
2012 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08002013 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302014 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5,
2015 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08002016 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302017 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6,
2018 0xFF, 0x00);
2019 /* Set the ATTK3 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08002020 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302021 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7,
2022 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08002023 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302024 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8,
2025 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08002026 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302027 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9,
2028 0xFF, 0x00);
2029 break;
2030
2031 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08002032 snd_soc_component_update_bits(component,
2033 BOLERO_CDC_RX_RX2_RX_PATH_CFG1,
2034 0x80, 0x00);
2035 snd_soc_component_update_bits(component,
2036 BOLERO_CDC_RX_RX2_RX_PATH_SEC7,
2037 0x02, 0x00);
2038 snd_soc_component_update_bits(component,
2039 BOLERO_CDC_RX_BCL_VBAT_CFG,
2040 0x02, 0x02);
2041 snd_soc_component_update_bits(component,
2042 BOLERO_CDC_RX_RX2_RX_PATH_CFG1,
2043 0x02, 0x00);
2044 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302045 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1,
2046 0xFF, 0x00);
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_UPD2,
2049 0xFF, 0x00);
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_UPD3,
2052 0xFF, 0x00);
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_UPD4,
2055 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002056 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302057 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5,
2058 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002059 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302060 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6,
2061 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002062 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302063 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7,
2064 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002065 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302066 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8,
2067 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002068 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302069 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9,
2070 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002071 rx_macro_enable_softclip_clk(component, rx_priv, false);
2072 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302073 BOLERO_CDC_RX_BCL_VBAT_CFG, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002074 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302075 BOLERO_CDC_RX_BCL_VBAT_PATH_CTL, 0x10, 0x00);
2076 break;
2077 default:
2078 dev_err(rx_dev, "%s: Invalid event %d\n", __func__, event);
2079 break;
2080 }
2081 return 0;
2082}
2083
Meng Wang15c825d2018-09-06 10:49:18 +08002084static void rx_macro_idle_detect_control(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302085 struct rx_macro_priv *rx_priv,
2086 int interp, int event)
2087{
2088 int reg = 0, mask = 0, val = 0;
2089
2090 if (!rx_priv->idle_det_cfg.hph_idle_detect_en)
2091 return;
2092
2093 if (interp == INTERP_HPHL) {
2094 reg = BOLERO_CDC_RX_IDLE_DETECT_PATH_CTL;
2095 mask = 0x01;
2096 val = 0x01;
2097 }
2098 if (interp == INTERP_HPHR) {
2099 reg = BOLERO_CDC_RX_IDLE_DETECT_PATH_CTL;
2100 mask = 0x02;
2101 val = 0x02;
2102 }
2103
2104 if (reg && SND_SOC_DAPM_EVENT_ON(event))
Meng Wang15c825d2018-09-06 10:49:18 +08002105 snd_soc_component_update_bits(component, reg, mask, val);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302106
2107 if (reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08002108 snd_soc_component_update_bits(component, reg, mask, 0x00);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302109 rx_priv->idle_det_cfg.hph_idle_thr = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08002110 snd_soc_component_write(component,
2111 BOLERO_CDC_RX_IDLE_DETECT_CFG3, 0x0);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302112 }
2113}
2114
Meng Wang15c825d2018-09-06 10:49:18 +08002115static void rx_macro_hphdelay_lutbypass(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302116 struct rx_macro_priv *rx_priv,
2117 u16 interp_idx, int event)
2118{
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302119 u16 hph_lut_bypass_reg = 0;
2120 u16 hph_comp_ctrl7 = 0;
2121
2122 switch (interp_idx) {
2123 case INTERP_HPHL:
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302124 hph_lut_bypass_reg = BOLERO_CDC_RX_TOP_HPHL_COMP_LUT;
2125 hph_comp_ctrl7 = BOLERO_CDC_RX_COMPANDER0_CTL7;
2126 break;
2127 case INTERP_HPHR:
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302128 hph_lut_bypass_reg = BOLERO_CDC_RX_TOP_HPHR_COMP_LUT;
2129 hph_comp_ctrl7 = BOLERO_CDC_RX_COMPANDER1_CTL7;
2130 break;
2131 default:
2132 break;
2133 }
2134
2135 if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) {
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302136 if (interp_idx == INTERP_HPHL) {
2137 if (rx_priv->is_ear_mode_on)
Meng Wang15c825d2018-09-06 10:49:18 +08002138 snd_soc_component_update_bits(component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302139 BOLERO_CDC_RX_RX0_RX_PATH_CFG1,
2140 0x02, 0x02);
2141 else
Meng Wang15c825d2018-09-06 10:49:18 +08002142 snd_soc_component_update_bits(component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302143 hph_lut_bypass_reg,
2144 0x80, 0x80);
2145 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08002146 snd_soc_component_update_bits(component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302147 hph_lut_bypass_reg,
2148 0x80, 0x80);
2149 }
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05302150 if (rx_priv->hph_pwr_mode)
Meng Wang15c825d2018-09-06 10:49:18 +08002151 snd_soc_component_update_bits(component,
2152 hph_comp_ctrl7,
2153 0x20, 0x00);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302154 }
2155
2156 if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08002157 snd_soc_component_update_bits(component,
2158 BOLERO_CDC_RX_RX0_RX_PATH_CFG1,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302159 0x02, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002160 snd_soc_component_update_bits(component, hph_lut_bypass_reg,
2161 0x80, 0x00);
2162 snd_soc_component_update_bits(component, hph_comp_ctrl7,
2163 0x20, 0x0);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302164 }
2165}
2166
Meng Wang15c825d2018-09-06 10:49:18 +08002167static int rx_macro_enable_interp_clk(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302168 int event, int interp_idx)
2169{
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302170 u16 main_reg = 0, dsm_reg = 0, rx_cfg2_reg = 0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302171 struct device *rx_dev = NULL;
2172 struct rx_macro_priv *rx_priv = NULL;
2173
Meng Wang15c825d2018-09-06 10:49:18 +08002174 if (!component) {
2175 pr_err("%s: component is NULL\n", __func__);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302176 return -EINVAL;
2177 }
2178
Meng Wang15c825d2018-09-06 10:49:18 +08002179 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302180 return -EINVAL;
2181
2182 main_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL +
2183 (interp_idx * RX_MACRO_RX_PATH_OFFSET);
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302184 dsm_reg = BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL +
2185 (interp_idx * RX_MACRO_RX_PATH_OFFSET);
2186 rx_cfg2_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG2 +
2187 (interp_idx * RX_MACRO_RX_PATH_OFFSET);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302188
2189 if (SND_SOC_DAPM_EVENT_ON(event)) {
2190 if (rx_priv->main_clk_users[interp_idx] == 0) {
Meng Wang15c825d2018-09-06 10:49:18 +08002191 snd_soc_component_update_bits(component, dsm_reg,
2192 0x01, 0x01);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302193 /* Main path PGA mute enable */
Meng Wang15c825d2018-09-06 10:49:18 +08002194 snd_soc_component_update_bits(component, main_reg,
2195 0x10, 0x10);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302196 /* Clk enable */
Meng Wang15c825d2018-09-06 10:49:18 +08002197 snd_soc_component_update_bits(component, main_reg,
2198 0x20, 0x20);
2199 snd_soc_component_update_bits(component, rx_cfg2_reg,
2200 0x03, 0x03);
2201 rx_macro_idle_detect_control(component, rx_priv,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302202 interp_idx, event);
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05302203 if (rx_priv->hph_hd2_mode)
Meng Wang15c825d2018-09-06 10:49:18 +08002204 rx_macro_hd2_control(
2205 component, interp_idx, event);
2206 rx_macro_hphdelay_lutbypass(component, rx_priv,
2207 interp_idx, event);
2208 rx_macro_config_compander(component, rx_priv,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302209 interp_idx, event);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302210 if (interp_idx == INTERP_AUX)
Meng Wang15c825d2018-09-06 10:49:18 +08002211 rx_macro_config_softclip(component, rx_priv,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302212 event);
Meng Wang15c825d2018-09-06 10:49:18 +08002213 rx_macro_config_classh(component, rx_priv,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302214 interp_idx, event);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302215 }
2216 rx_priv->main_clk_users[interp_idx]++;
2217 }
2218
2219 if (SND_SOC_DAPM_EVENT_OFF(event)) {
2220 rx_priv->main_clk_users[interp_idx]--;
2221 if (rx_priv->main_clk_users[interp_idx] <= 0) {
2222 rx_priv->main_clk_users[interp_idx] = 0;
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302223 /* Clk Disable */
Meng Wang15c825d2018-09-06 10:49:18 +08002224 snd_soc_component_update_bits(component, dsm_reg,
2225 0x01, 0x00);
2226 snd_soc_component_update_bits(component, main_reg,
2227 0x20, 0x00);
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302228 /* Reset enable and disable */
Meng Wang15c825d2018-09-06 10:49:18 +08002229 snd_soc_component_update_bits(component, main_reg,
2230 0x40, 0x40);
2231 snd_soc_component_update_bits(component, main_reg,
2232 0x40, 0x00);
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302233 /* Reset rate to 48K*/
Meng Wang15c825d2018-09-06 10:49:18 +08002234 snd_soc_component_update_bits(component, main_reg,
2235 0x0F, 0x04);
2236 snd_soc_component_update_bits(component, rx_cfg2_reg,
2237 0x03, 0x00);
2238 rx_macro_config_classh(component, rx_priv,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302239 interp_idx, event);
Meng Wang15c825d2018-09-06 10:49:18 +08002240 rx_macro_config_compander(component, rx_priv,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302241 interp_idx, event);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302242 if (interp_idx == INTERP_AUX)
Meng Wang15c825d2018-09-06 10:49:18 +08002243 rx_macro_config_softclip(component, rx_priv,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302244 event);
Meng Wang15c825d2018-09-06 10:49:18 +08002245 rx_macro_hphdelay_lutbypass(component, rx_priv,
2246 interp_idx, event);
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05302247 if (rx_priv->hph_hd2_mode)
Meng Wang15c825d2018-09-06 10:49:18 +08002248 rx_macro_hd2_control(component, interp_idx,
2249 event);
2250 rx_macro_idle_detect_control(component, rx_priv,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302251 interp_idx, event);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302252 }
2253 }
2254
Meng Wang15c825d2018-09-06 10:49:18 +08002255 dev_dbg(component->dev, "%s event %d main_clk_users %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302256 __func__, event, rx_priv->main_clk_users[interp_idx]);
2257
2258 return rx_priv->main_clk_users[interp_idx];
2259}
2260
2261static int rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w,
2262 struct snd_kcontrol *kcontrol, int event)
2263{
Meng Wang15c825d2018-09-06 10:49:18 +08002264 struct snd_soc_component *component =
2265 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302266 u16 sidetone_reg = 0;
2267
Meng Wang15c825d2018-09-06 10:49:18 +08002268 dev_dbg(component->dev, "%s %d %d\n", __func__, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302269 sidetone_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG1 +
2270 RX_MACRO_RX_PATH_OFFSET * (w->shift);
2271
2272 switch (event) {
2273 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08002274 rx_macro_enable_interp_clk(component, event, w->shift);
2275 snd_soc_component_update_bits(component, sidetone_reg,
2276 0x10, 0x10);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302277 break;
2278 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08002279 snd_soc_component_update_bits(component, sidetone_reg,
2280 0x10, 0x00);
2281 rx_macro_enable_interp_clk(component, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302282 break;
2283 default:
2284 break;
2285 };
2286 return 0;
2287}
2288
2289static void rx_macro_restore_iir_coeff(struct rx_macro_priv *rx_priv, int iir_idx,
2290 int band_idx)
2291{
2292 u16 reg_add = 0, coeff_idx = 0, idx = 0;
2293 struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL);
2294
Tanya Dixit8530fb92018-09-14 16:01:25 +05302295 if (regmap == NULL) {
2296 dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__);
2297 return;
2298 }
2299
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302300 regmap_write(regmap,
2301 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
2302 (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
2303
2304 reg_add = BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx;
2305
2306 /* 5 coefficients per band and 4 writes per coefficient */
2307 for (coeff_idx = 0; coeff_idx < RX_MACRO_SIDETONE_IIR_COEFF_MAX;
2308 coeff_idx++) {
2309 /* Four 8 bit values(one 32 bit) per coefficient */
2310 regmap_write(regmap, reg_add,
2311 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
2312 regmap_write(regmap, reg_add,
2313 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
2314 regmap_write(regmap, reg_add,
2315 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
2316 regmap_write(regmap, reg_add,
2317 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
2318 }
2319}
2320
2321static int rx_macro_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol,
2322 struct snd_ctl_elem_value *ucontrol)
2323{
Meng Wang15c825d2018-09-06 10:49:18 +08002324 struct snd_soc_component *component =
2325 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302326 int iir_idx = ((struct soc_multi_mixer_control *)
2327 kcontrol->private_value)->reg;
2328 int band_idx = ((struct soc_multi_mixer_control *)
2329 kcontrol->private_value)->shift;
2330 /* IIR filter band registers are at integer multiples of 0x80 */
2331 u16 iir_reg = BOLERO_CDC_RX_SIDETONE_IIR0_IIR_CTL + 0x80 * iir_idx;
2332
Meng Wang15c825d2018-09-06 10:49:18 +08002333 ucontrol->value.integer.value[0] = (
2334 snd_soc_component_read32(component, iir_reg) &
2335 (1 << band_idx)) != 0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302336
Meng Wang15c825d2018-09-06 10:49:18 +08002337 dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302338 iir_idx, band_idx,
2339 (uint32_t)ucontrol->value.integer.value[0]);
2340 return 0;
2341}
2342
2343static int rx_macro_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol,
2344 struct snd_ctl_elem_value *ucontrol)
2345{
Meng Wang15c825d2018-09-06 10:49:18 +08002346 struct snd_soc_component *component =
2347 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302348 int iir_idx = ((struct soc_multi_mixer_control *)
2349 kcontrol->private_value)->reg;
2350 int band_idx = ((struct soc_multi_mixer_control *)
2351 kcontrol->private_value)->shift;
2352 bool iir_band_en_status = 0;
2353 int value = ucontrol->value.integer.value[0];
2354 u16 iir_reg = BOLERO_CDC_RX_SIDETONE_IIR0_IIR_CTL + 0x80 * iir_idx;
2355 struct device *rx_dev = NULL;
2356 struct rx_macro_priv *rx_priv = NULL;
2357
Meng Wang15c825d2018-09-06 10:49:18 +08002358 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302359 return -EINVAL;
2360
2361 rx_macro_restore_iir_coeff(rx_priv, iir_idx, band_idx);
2362
2363 /* Mask first 5 bits, 6-8 are reserved */
Meng Wang15c825d2018-09-06 10:49:18 +08002364 snd_soc_component_update_bits(component, iir_reg, (1 << band_idx),
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302365 (value << band_idx));
2366
Meng Wang15c825d2018-09-06 10:49:18 +08002367 iir_band_en_status = ((snd_soc_component_read32(component, iir_reg) &
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302368 (1 << band_idx)) != 0);
Meng Wang15c825d2018-09-06 10:49:18 +08002369 dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302370 iir_idx, band_idx, iir_band_en_status);
2371 return 0;
2372}
2373
Meng Wang15c825d2018-09-06 10:49:18 +08002374static uint32_t get_iir_band_coeff(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302375 int iir_idx, int band_idx,
2376 int coeff_idx)
2377{
2378 uint32_t value = 0;
2379
2380 /* Address does not automatically update if reading */
Meng Wang15c825d2018-09-06 10:49:18 +08002381 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302382 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
2383 ((band_idx * BAND_MAX + coeff_idx)
2384 * sizeof(uint32_t)) & 0x7F);
2385
Meng Wang15c825d2018-09-06 10:49:18 +08002386 value |= snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302387 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx));
2388
Meng Wang15c825d2018-09-06 10:49:18 +08002389 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302390 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
2391 ((band_idx * BAND_MAX + coeff_idx)
2392 * sizeof(uint32_t) + 1) & 0x7F);
2393
Meng Wang15c825d2018-09-06 10:49:18 +08002394 value |= (snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302395 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2396 0x80 * iir_idx)) << 8);
2397
Meng Wang15c825d2018-09-06 10:49:18 +08002398 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302399 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
2400 ((band_idx * BAND_MAX + coeff_idx)
2401 * sizeof(uint32_t) + 2) & 0x7F);
2402
Meng Wang15c825d2018-09-06 10:49:18 +08002403 value |= (snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302404 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2405 0x80 * iir_idx)) << 16);
2406
Meng Wang15c825d2018-09-06 10:49:18 +08002407 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302408 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
2409 ((band_idx * BAND_MAX + coeff_idx)
2410 * sizeof(uint32_t) + 3) & 0x7F);
2411
2412 /* Mask bits top 2 bits since they are reserved */
Meng Wang15c825d2018-09-06 10:49:18 +08002413 value |= ((snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302414 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2415 16 * iir_idx)) & 0x3F) << 24);
2416
2417 return value;
2418}
2419
2420static int rx_macro_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol,
2421 struct snd_ctl_elem_value *ucontrol)
2422{
Meng Wang15c825d2018-09-06 10:49:18 +08002423 struct snd_soc_component *component =
2424 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302425 int iir_idx = ((struct soc_multi_mixer_control *)
2426 kcontrol->private_value)->reg;
2427 int band_idx = ((struct soc_multi_mixer_control *)
2428 kcontrol->private_value)->shift;
2429
2430 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08002431 get_iir_band_coeff(component, iir_idx, band_idx, 0);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302432 ucontrol->value.integer.value[1] =
Meng Wang15c825d2018-09-06 10:49:18 +08002433 get_iir_band_coeff(component, iir_idx, band_idx, 1);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302434 ucontrol->value.integer.value[2] =
Meng Wang15c825d2018-09-06 10:49:18 +08002435 get_iir_band_coeff(component, iir_idx, band_idx, 2);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302436 ucontrol->value.integer.value[3] =
Meng Wang15c825d2018-09-06 10:49:18 +08002437 get_iir_band_coeff(component, iir_idx, band_idx, 3);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302438 ucontrol->value.integer.value[4] =
Meng Wang15c825d2018-09-06 10:49:18 +08002439 get_iir_band_coeff(component, iir_idx, band_idx, 4);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302440
Meng Wang15c825d2018-09-06 10:49:18 +08002441 dev_dbg(component->dev, "%s: IIR #%d band #%d b0 = 0x%x\n"
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302442 "%s: IIR #%d band #%d b1 = 0x%x\n"
2443 "%s: IIR #%d band #%d b2 = 0x%x\n"
2444 "%s: IIR #%d band #%d a1 = 0x%x\n"
2445 "%s: IIR #%d band #%d a2 = 0x%x\n",
2446 __func__, iir_idx, band_idx,
2447 (uint32_t)ucontrol->value.integer.value[0],
2448 __func__, iir_idx, band_idx,
2449 (uint32_t)ucontrol->value.integer.value[1],
2450 __func__, iir_idx, band_idx,
2451 (uint32_t)ucontrol->value.integer.value[2],
2452 __func__, iir_idx, band_idx,
2453 (uint32_t)ucontrol->value.integer.value[3],
2454 __func__, iir_idx, band_idx,
2455 (uint32_t)ucontrol->value.integer.value[4]);
2456 return 0;
2457}
2458
Meng Wang15c825d2018-09-06 10:49:18 +08002459static void set_iir_band_coeff(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302460 int iir_idx, int band_idx,
2461 uint32_t value)
2462{
Meng Wang15c825d2018-09-06 10:49:18 +08002463 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302464 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx),
2465 (value & 0xFF));
2466
Meng Wang15c825d2018-09-06 10:49:18 +08002467 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302468 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx),
2469 (value >> 8) & 0xFF);
2470
Meng Wang15c825d2018-09-06 10:49:18 +08002471 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302472 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx),
2473 (value >> 16) & 0xFF);
2474
2475 /* Mask top 2 bits, 7-8 are reserved */
Meng Wang15c825d2018-09-06 10:49:18 +08002476 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302477 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx),
2478 (value >> 24) & 0x3F);
2479}
2480
2481static int rx_macro_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol,
2482 struct snd_ctl_elem_value *ucontrol)
2483{
Meng Wang15c825d2018-09-06 10:49:18 +08002484 struct snd_soc_component *component =
2485 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302486 int iir_idx = ((struct soc_multi_mixer_control *)
2487 kcontrol->private_value)->reg;
2488 int band_idx = ((struct soc_multi_mixer_control *)
2489 kcontrol->private_value)->shift;
2490 int coeff_idx, idx = 0;
2491 struct device *rx_dev = NULL;
2492 struct rx_macro_priv *rx_priv = NULL;
2493
Meng Wang15c825d2018-09-06 10:49:18 +08002494 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302495 return -EINVAL;
2496
2497 /*
2498 * Mask top bit it is reserved
2499 * Updates addr automatically for each B2 write
2500 */
Meng Wang15c825d2018-09-06 10:49:18 +08002501 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302502 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2503 (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
2504
2505 /* Store the coefficients in sidetone coeff array */
2506 for (coeff_idx = 0; coeff_idx < RX_MACRO_SIDETONE_IIR_COEFF_MAX;
2507 coeff_idx++) {
2508 uint32_t value = ucontrol->value.integer.value[coeff_idx];
2509
Meng Wang15c825d2018-09-06 10:49:18 +08002510 set_iir_band_coeff(component, iir_idx, band_idx, value);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302511
2512 /* Four 8 bit values(one 32 bit) per coefficient */
2513 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
2514 (value & 0xFF);
2515 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
2516 (value >> 8) & 0xFF;
2517 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
2518 (value >> 16) & 0xFF;
2519 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
2520 (value >> 24) & 0xFF;
2521 }
2522
2523 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
2524 "%s: IIR #%d band #%d b1 = 0x%x\n"
2525 "%s: IIR #%d band #%d b2 = 0x%x\n"
2526 "%s: IIR #%d band #%d a1 = 0x%x\n"
2527 "%s: IIR #%d band #%d a2 = 0x%x\n",
2528 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08002529 get_iir_band_coeff(component, iir_idx, band_idx, 0),
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302530 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08002531 get_iir_band_coeff(component, iir_idx, band_idx, 1),
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302532 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08002533 get_iir_band_coeff(component, iir_idx, band_idx, 2),
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302534 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08002535 get_iir_band_coeff(component, iir_idx, band_idx, 3),
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302536 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08002537 get_iir_band_coeff(component, iir_idx, band_idx, 4));
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302538 return 0;
2539}
2540
2541static int rx_macro_set_iir_gain(struct snd_soc_dapm_widget *w,
2542 struct snd_kcontrol *kcontrol, int event)
2543{
Meng Wang15c825d2018-09-06 10:49:18 +08002544 struct snd_soc_component *component =
2545 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302546
Meng Wang15c825d2018-09-06 10:49:18 +08002547 dev_dbg(component->dev, "%s: event = %d\n", __func__, event);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302548
2549 switch (event) {
2550 case SND_SOC_DAPM_POST_PMU: /* fall through */
2551 case SND_SOC_DAPM_PRE_PMD:
2552 if (strnstr(w->name, "IIR0", sizeof("IIR0"))) {
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_GAIN_B1_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002555 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302556 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002557 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302558 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002559 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302560 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002561 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302562 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002563 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302564 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002565 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302566 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002567 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302568 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL));
2569 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08002570 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302571 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002572 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302573 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002574 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302575 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002576 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302577 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002578 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302579 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002580 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302581 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002582 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302583 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002584 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302585 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL));
2586 }
2587 break;
2588 }
2589 return 0;
2590}
2591
2592static const struct snd_kcontrol_new rx_macro_snd_controls[] = {
2593 SOC_SINGLE_SX_TLV("RX_RX0 Digital Volume",
2594 BOLERO_CDC_RX_RX0_RX_VOL_CTL,
2595 0, -84, 40, digital_gain),
2596 SOC_SINGLE_SX_TLV("RX_RX1 Digital Volume",
2597 BOLERO_CDC_RX_RX1_RX_VOL_CTL,
2598 0, -84, 40, digital_gain),
2599 SOC_SINGLE_SX_TLV("RX_RX2 Digital Volume",
2600 BOLERO_CDC_RX_RX2_RX_VOL_CTL,
2601 0, -84, 40, digital_gain),
2602 SOC_SINGLE_SX_TLV("RX_RX0 Mix Digital Volume",
2603 BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
2604 SOC_SINGLE_SX_TLV("RX_RX1 Mix Digital Volume",
2605 BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
2606 SOC_SINGLE_SX_TLV("RX_RX2 Mix Digital Volume",
2607 BOLERO_CDC_RX_RX2_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
2608
2609 SOC_SINGLE_EXT("RX_COMP1 Switch", SND_SOC_NOPM, RX_MACRO_COMP1, 1, 0,
2610 rx_macro_get_compander, rx_macro_set_compander),
2611 SOC_SINGLE_EXT("RX_COMP2 Switch", SND_SOC_NOPM, RX_MACRO_COMP2, 1, 0,
2612 rx_macro_get_compander, rx_macro_set_compander),
2613
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302614 SOC_ENUM_EXT("RX_EAR Mode", rx_macro_ear_mode_enum,
2615 rx_macro_get_ear_mode, rx_macro_put_ear_mode),
2616
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05302617 SOC_ENUM_EXT("RX_HPH HD2 Mode", rx_macro_hph_hd2_mode_enum,
2618 rx_macro_get_hph_hd2_mode, rx_macro_put_hph_hd2_mode),
2619
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05302620 SOC_ENUM_EXT("RX_HPH_PWR_MODE", rx_macro_hph_pwr_mode_enum,
2621 rx_macro_get_hph_pwr_mode, rx_macro_put_hph_pwr_mode),
2622
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302623 SOC_ENUM_EXT("RX_GSM mode Enable", rx_macro_vbat_bcl_gsm_mode_enum,
2624 rx_macro_vbat_bcl_gsm_mode_func_get,
2625 rx_macro_vbat_bcl_gsm_mode_func_put),
2626 SOC_SINGLE_EXT("RX_Softclip Enable", SND_SOC_NOPM, 0, 1, 0,
2627 rx_macro_soft_clip_enable_get,
2628 rx_macro_soft_clip_enable_put),
2629
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302630 SOC_SINGLE_SX_TLV("IIR0 INP0 Volume",
2631 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40,
2632 digital_gain),
2633 SOC_SINGLE_SX_TLV("IIR0 INP1 Volume",
2634 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84, 40,
2635 digital_gain),
2636 SOC_SINGLE_SX_TLV("IIR0 INP2 Volume",
2637 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84, 40,
2638 digital_gain),
2639 SOC_SINGLE_SX_TLV("IIR0 INP3 Volume",
2640 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84, 40,
2641 digital_gain),
2642 SOC_SINGLE_SX_TLV("IIR1 INP0 Volume",
2643 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0, -84, 40,
2644 digital_gain),
2645 SOC_SINGLE_SX_TLV("IIR1 INP1 Volume",
2646 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0, -84, 40,
2647 digital_gain),
2648 SOC_SINGLE_SX_TLV("IIR1 INP2 Volume",
2649 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0, -84, 40,
2650 digital_gain),
2651 SOC_SINGLE_SX_TLV("IIR1 INP3 Volume",
2652 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0, -84, 40,
2653 digital_gain),
2654
2655 SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0,
2656 rx_macro_iir_enable_audio_mixer_get,
2657 rx_macro_iir_enable_audio_mixer_put),
2658 SOC_SINGLE_EXT("IIR0 Enable Band2", IIR0, BAND2, 1, 0,
2659 rx_macro_iir_enable_audio_mixer_get,
2660 rx_macro_iir_enable_audio_mixer_put),
2661 SOC_SINGLE_EXT("IIR0 Enable Band3", IIR0, BAND3, 1, 0,
2662 rx_macro_iir_enable_audio_mixer_get,
2663 rx_macro_iir_enable_audio_mixer_put),
2664 SOC_SINGLE_EXT("IIR0 Enable Band4", IIR0, BAND4, 1, 0,
2665 rx_macro_iir_enable_audio_mixer_get,
2666 rx_macro_iir_enable_audio_mixer_put),
2667 SOC_SINGLE_EXT("IIR0 Enable Band5", IIR0, BAND5, 1, 0,
2668 rx_macro_iir_enable_audio_mixer_get,
2669 rx_macro_iir_enable_audio_mixer_put),
2670 SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
2671 rx_macro_iir_enable_audio_mixer_get,
2672 rx_macro_iir_enable_audio_mixer_put),
2673 SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
2674 rx_macro_iir_enable_audio_mixer_get,
2675 rx_macro_iir_enable_audio_mixer_put),
2676 SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
2677 rx_macro_iir_enable_audio_mixer_get,
2678 rx_macro_iir_enable_audio_mixer_put),
2679 SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
2680 rx_macro_iir_enable_audio_mixer_get,
2681 rx_macro_iir_enable_audio_mixer_put),
2682 SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
2683 rx_macro_iir_enable_audio_mixer_get,
2684 rx_macro_iir_enable_audio_mixer_put),
2685
2686 SOC_SINGLE_MULTI_EXT("IIR0 Band1", IIR0, BAND1, 255, 0, 5,
2687 rx_macro_iir_band_audio_mixer_get,
2688 rx_macro_iir_band_audio_mixer_put),
2689 SOC_SINGLE_MULTI_EXT("IIR0 Band2", IIR0, BAND2, 255, 0, 5,
2690 rx_macro_iir_band_audio_mixer_get,
2691 rx_macro_iir_band_audio_mixer_put),
2692 SOC_SINGLE_MULTI_EXT("IIR0 Band3", IIR0, BAND3, 255, 0, 5,
2693 rx_macro_iir_band_audio_mixer_get,
2694 rx_macro_iir_band_audio_mixer_put),
2695 SOC_SINGLE_MULTI_EXT("IIR0 Band4", IIR0, BAND4, 255, 0, 5,
2696 rx_macro_iir_band_audio_mixer_get,
2697 rx_macro_iir_band_audio_mixer_put),
2698 SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5,
2699 rx_macro_iir_band_audio_mixer_get,
2700 rx_macro_iir_band_audio_mixer_put),
2701 SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
2702 rx_macro_iir_band_audio_mixer_get,
2703 rx_macro_iir_band_audio_mixer_put),
2704 SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
2705 rx_macro_iir_band_audio_mixer_get,
2706 rx_macro_iir_band_audio_mixer_put),
2707 SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
2708 rx_macro_iir_band_audio_mixer_get,
2709 rx_macro_iir_band_audio_mixer_put),
2710 SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
2711 rx_macro_iir_band_audio_mixer_get,
2712 rx_macro_iir_band_audio_mixer_put),
2713 SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
2714 rx_macro_iir_band_audio_mixer_get,
2715 rx_macro_iir_band_audio_mixer_put),
2716};
2717
Vatsal Buchac2d6c222018-11-30 18:46:37 +05302718static int rx_macro_enable_echo(struct snd_soc_dapm_widget *w,
2719 struct snd_kcontrol *kcontrol,
2720 int event)
2721{
2722 struct snd_soc_component *component =
2723 snd_soc_dapm_to_component(w->dapm);
2724 struct device *rx_dev = NULL;
2725 struct rx_macro_priv *rx_priv = NULL;
2726 u16 val = 0, ec_hq_reg = 0;
2727 int ec_tx = 0;
2728
2729 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
2730 return -EINVAL;
2731
2732 dev_dbg(rx_dev, "%s %d %s\n", __func__, event, w->name);
2733
2734 val = snd_soc_component_read32(component,
2735 BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4);
2736 if (!(strcmp(w->name, "RX MIX TX0 MUX")))
2737 ec_tx = ((val & 0xf0) >> 0x4) - 1;
2738 else if (!(strcmp(w->name, "RX MIX TX1 MUX")))
2739 ec_tx = (val & 0x0f) - 1;
2740
2741 val = snd_soc_component_read32(component,
2742 BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5);
2743 if (!(strcmp(w->name, "RX MIX TX2 MUX")))
2744 ec_tx = (val & 0x0f) - 1;
2745
2746 if (ec_tx < 0 || (ec_tx >= RX_MACRO_EC_MUX_MAX)) {
2747 dev_err(rx_dev, "%s: EC mix control not set correctly\n",
2748 __func__);
2749 return -EINVAL;
2750 }
2751 ec_hq_reg = BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL +
2752 0x40 * ec_tx;
2753 snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01);
2754 ec_hq_reg = BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0 +
2755 0x40 * ec_tx;
2756 /* default set to 48k */
2757 snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08);
2758
2759 return 0;
2760}
2761
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302762static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = {
2763 SND_SOC_DAPM_AIF_IN("RX AIF1 PB", "RX_MACRO_AIF1 Playback", 0,
2764 SND_SOC_NOPM, 0, 0),
2765
2766 SND_SOC_DAPM_AIF_IN("RX AIF2 PB", "RX_MACRO_AIF2 Playback", 0,
2767 SND_SOC_NOPM, 0, 0),
2768
2769 SND_SOC_DAPM_AIF_IN("RX AIF3 PB", "RX_MACRO_AIF3 Playback", 0,
2770 SND_SOC_NOPM, 0, 0),
2771
2772 SND_SOC_DAPM_AIF_IN("RX AIF4 PB", "RX_MACRO_AIF4 Playback", 0,
2773 SND_SOC_NOPM, 0, 0),
2774
Vatsal Buchac2d6c222018-11-30 18:46:37 +05302775 SND_SOC_DAPM_AIF_OUT("RX AIF_ECHO", "RX_AIF_ECHO Capture", 0,
2776 SND_SOC_NOPM, 0, 0),
2777
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302778 RX_MACRO_DAPM_MUX("RX_MACRO RX0 MUX", RX_MACRO_RX0, rx_macro_rx0),
2779 RX_MACRO_DAPM_MUX("RX_MACRO RX1 MUX", RX_MACRO_RX1, rx_macro_rx1),
2780 RX_MACRO_DAPM_MUX("RX_MACRO RX2 MUX", RX_MACRO_RX2, rx_macro_rx2),
2781 RX_MACRO_DAPM_MUX("RX_MACRO RX3 MUX", RX_MACRO_RX3, rx_macro_rx3),
2782 RX_MACRO_DAPM_MUX("RX_MACRO RX4 MUX", RX_MACRO_RX4, rx_macro_rx4),
2783 RX_MACRO_DAPM_MUX("RX_MACRO RX5 MUX", RX_MACRO_RX5, rx_macro_rx5),
2784
2785 SND_SOC_DAPM_MIXER("RX_RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2786 SND_SOC_DAPM_MIXER("RX_RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2787 SND_SOC_DAPM_MIXER("RX_RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
2788 SND_SOC_DAPM_MIXER("RX_RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
2789 SND_SOC_DAPM_MIXER("RX_RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
2790 SND_SOC_DAPM_MIXER("RX_RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
2791
2792 RX_MACRO_DAPM_MUX("IIR0 INP0 MUX", 0, iir0_inp0),
2793 RX_MACRO_DAPM_MUX("IIR0 INP1 MUX", 0, iir0_inp1),
2794 RX_MACRO_DAPM_MUX("IIR0 INP2 MUX", 0, iir0_inp2),
2795 RX_MACRO_DAPM_MUX("IIR0 INP3 MUX", 0, iir0_inp3),
2796 RX_MACRO_DAPM_MUX("IIR1 INP0 MUX", 0, iir1_inp0),
2797 RX_MACRO_DAPM_MUX("IIR1 INP1 MUX", 0, iir1_inp1),
2798 RX_MACRO_DAPM_MUX("IIR1 INP2 MUX", 0, iir1_inp2),
2799 RX_MACRO_DAPM_MUX("IIR1 INP3 MUX", 0, iir1_inp3),
2800
Vatsal Buchac2d6c222018-11-30 18:46:37 +05302801 SND_SOC_DAPM_MUX_E("RX MIX TX0 MUX", SND_SOC_NOPM,
2802 RX_MACRO_EC0_MUX, 0,
2803 &rx_mix_tx0_mux, rx_macro_enable_echo,
2804 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2805 SND_SOC_DAPM_MUX_E("RX MIX TX1 MUX", SND_SOC_NOPM,
2806 RX_MACRO_EC1_MUX, 0,
2807 &rx_mix_tx1_mux, rx_macro_enable_echo,
2808 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2809 SND_SOC_DAPM_MUX_E("RX MIX TX2 MUX", SND_SOC_NOPM,
2810 RX_MACRO_EC2_MUX, 0,
2811 &rx_mix_tx2_mux, rx_macro_enable_echo,
2812 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2813
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302814 SND_SOC_DAPM_MIXER_E("IIR0", BOLERO_CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL,
2815 4, 0, NULL, 0, rx_macro_set_iir_gain,
2816 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2817 SND_SOC_DAPM_MIXER_E("IIR1", BOLERO_CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL,
2818 4, 0, NULL, 0, rx_macro_set_iir_gain,
2819 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2820 SND_SOC_DAPM_MIXER("SRC0", BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL,
2821 4, 0, NULL, 0),
2822 SND_SOC_DAPM_MIXER("SRC1", BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL,
2823 4, 0, NULL, 0),
2824
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302825 RX_MACRO_DAPM_MUX("RX INT0 DEM MUX", 0, rx_int0_dem_inp),
2826 RX_MACRO_DAPM_MUX("RX INT1 DEM MUX", 0, rx_int1_dem_inp),
2827
2828 SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", SND_SOC_NOPM, INTERP_HPHL, 0,
2829 &rx_int0_2_mux, rx_macro_enable_mix_path,
2830 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2831 SND_SOC_DAPM_POST_PMD),
2832 SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", SND_SOC_NOPM, INTERP_HPHR, 0,
2833 &rx_int1_2_mux, rx_macro_enable_mix_path,
2834 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2835 SND_SOC_DAPM_POST_PMD),
2836 SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", SND_SOC_NOPM, INTERP_AUX, 0,
2837 &rx_int2_2_mux, rx_macro_enable_mix_path,
2838 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2839 SND_SOC_DAPM_POST_PMD),
2840
2841 RX_MACRO_DAPM_MUX("RX INT0_1 MIX1 INP0", 0, rx_int0_1_mix_inp0),
2842 RX_MACRO_DAPM_MUX("RX INT0_1 MIX1 INP1", 0, rx_int0_1_mix_inp1),
2843 RX_MACRO_DAPM_MUX("RX INT0_1 MIX1 INP2", 0, rx_int0_1_mix_inp2),
2844 RX_MACRO_DAPM_MUX("RX INT1_1 MIX1 INP0", 0, rx_int1_1_mix_inp0),
2845 RX_MACRO_DAPM_MUX("RX INT1_1 MIX1 INP1", 0, rx_int1_1_mix_inp1),
2846 RX_MACRO_DAPM_MUX("RX INT1_1 MIX1 INP2", 0, rx_int1_1_mix_inp2),
2847 RX_MACRO_DAPM_MUX("RX INT2_1 MIX1 INP0", 0, rx_int2_1_mix_inp0),
2848 RX_MACRO_DAPM_MUX("RX INT2_1 MIX1 INP1", 0, rx_int2_1_mix_inp1),
2849 RX_MACRO_DAPM_MUX("RX INT2_1 MIX1 INP2", 0, rx_int2_1_mix_inp2),
2850
2851 SND_SOC_DAPM_MUX_E("RX INT0_1 INTERP", SND_SOC_NOPM, INTERP_HPHL, 0,
2852 &rx_int0_1_interp_mux, rx_macro_enable_main_path,
2853 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2854 SND_SOC_DAPM_POST_PMD),
2855 SND_SOC_DAPM_MUX_E("RX INT1_1 INTERP", SND_SOC_NOPM, INTERP_HPHR, 0,
2856 &rx_int1_1_interp_mux, rx_macro_enable_main_path,
2857 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2858 SND_SOC_DAPM_POST_PMD),
2859 SND_SOC_DAPM_MUX_E("RX INT2_1 INTERP", SND_SOC_NOPM, INTERP_AUX, 0,
2860 &rx_int2_1_interp_mux, rx_macro_enable_main_path,
2861 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2862 SND_SOC_DAPM_POST_PMD),
2863
2864 RX_MACRO_DAPM_MUX("RX INT0_2 INTERP", 0, rx_int0_2_interp),
2865 RX_MACRO_DAPM_MUX("RX INT1_2 INTERP", 0, rx_int1_2_interp),
2866 RX_MACRO_DAPM_MUX("RX INT2_2 INTERP", 0, rx_int2_2_interp),
2867
2868 SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2869 SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2870 SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2871 SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2872 SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2873 SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2874
2875 SND_SOC_DAPM_MUX_E("RX INT0 MIX2 INP", SND_SOC_NOPM, INTERP_HPHL,
2876 0, &rx_int0_mix2_inp_mux, rx_macro_enable_rx_path_clk,
2877 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2878 SND_SOC_DAPM_MUX_E("RX INT1 MIX2 INP", SND_SOC_NOPM, INTERP_HPHR,
2879 0, &rx_int1_mix2_inp_mux, rx_macro_enable_rx_path_clk,
2880 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2881 SND_SOC_DAPM_MUX_E("RX INT2 MIX2 INP", SND_SOC_NOPM, INTERP_AUX,
2882 0, &rx_int2_mix2_inp_mux, rx_macro_enable_rx_path_clk,
2883 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2884
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302885 SND_SOC_DAPM_MIXER_E("RX INT2_1 VBAT", SND_SOC_NOPM,
2886 0, 0, rx_int2_1_vbat_mix_switch,
2887 ARRAY_SIZE(rx_int2_1_vbat_mix_switch),
2888 rx_macro_enable_vbat,
2889 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2890
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302891 SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
2892 SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
2893 SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
2894
2895 SND_SOC_DAPM_OUTPUT("HPHL_OUT"),
2896 SND_SOC_DAPM_OUTPUT("HPHR_OUT"),
2897 SND_SOC_DAPM_OUTPUT("AUX_OUT"),
2898
2899 SND_SOC_DAPM_INPUT("RX_TX DEC0_INP"),
2900 SND_SOC_DAPM_INPUT("RX_TX DEC1_INP"),
2901 SND_SOC_DAPM_INPUT("RX_TX DEC2_INP"),
2902 SND_SOC_DAPM_INPUT("RX_TX DEC3_INP"),
2903
2904 SND_SOC_DAPM_SUPPLY_S("RX_MCLK", 0, SND_SOC_NOPM, 0, 0,
2905 rx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2906};
2907
2908static const struct snd_soc_dapm_route rx_audio_map[] = {
2909 {"RX AIF1 PB", NULL, "RX_MCLK"},
2910 {"RX AIF2 PB", NULL, "RX_MCLK"},
2911 {"RX AIF3 PB", NULL, "RX_MCLK"},
2912 {"RX AIF4 PB", NULL, "RX_MCLK"},
2913
2914 {"RX_MACRO RX0 MUX", "AIF1_PB", "RX AIF1 PB"},
2915 {"RX_MACRO RX1 MUX", "AIF1_PB", "RX AIF1 PB"},
2916 {"RX_MACRO RX2 MUX", "AIF1_PB", "RX AIF1 PB"},
2917 {"RX_MACRO RX3 MUX", "AIF1_PB", "RX AIF1 PB"},
2918 {"RX_MACRO RX4 MUX", "AIF1_PB", "RX AIF1 PB"},
2919 {"RX_MACRO RX5 MUX", "AIF1_PB", "RX AIF1 PB"},
2920
2921 {"RX_MACRO RX0 MUX", "AIF2_PB", "RX AIF2 PB"},
2922 {"RX_MACRO RX1 MUX", "AIF2_PB", "RX AIF2 PB"},
2923 {"RX_MACRO RX2 MUX", "AIF2_PB", "RX AIF2 PB"},
2924 {"RX_MACRO RX3 MUX", "AIF2_PB", "RX AIF2 PB"},
2925 {"RX_MACRO RX4 MUX", "AIF2_PB", "RX AIF2 PB"},
2926 {"RX_MACRO RX5 MUX", "AIF2_PB", "RX AIF2 PB"},
2927
2928 {"RX_MACRO RX0 MUX", "AIF3_PB", "RX AIF3 PB"},
2929 {"RX_MACRO RX1 MUX", "AIF3_PB", "RX AIF3 PB"},
2930 {"RX_MACRO RX2 MUX", "AIF3_PB", "RX AIF3 PB"},
2931 {"RX_MACRO RX3 MUX", "AIF3_PB", "RX AIF3 PB"},
2932 {"RX_MACRO RX4 MUX", "AIF3_PB", "RX AIF3 PB"},
2933 {"RX_MACRO RX5 MUX", "AIF3_PB", "RX AIF3 PB"},
2934
2935 {"RX_MACRO RX0 MUX", "AIF4_PB", "RX AIF4 PB"},
2936 {"RX_MACRO RX1 MUX", "AIF4_PB", "RX AIF4 PB"},
2937 {"RX_MACRO RX2 MUX", "AIF4_PB", "RX AIF4 PB"},
2938 {"RX_MACRO RX3 MUX", "AIF4_PB", "RX AIF4 PB"},
2939 {"RX_MACRO RX4 MUX", "AIF4_PB", "RX AIF4 PB"},
2940 {"RX_MACRO RX5 MUX", "AIF4_PB", "RX AIF4 PB"},
2941
2942 {"RX_RX0", NULL, "RX_MACRO RX0 MUX"},
2943 {"RX_RX1", NULL, "RX_MACRO RX1 MUX"},
2944 {"RX_RX2", NULL, "RX_MACRO RX2 MUX"},
2945 {"RX_RX3", NULL, "RX_MACRO RX3 MUX"},
2946 {"RX_RX4", NULL, "RX_MACRO RX4 MUX"},
2947 {"RX_RX5", NULL, "RX_MACRO RX5 MUX"},
2948
2949 {"RX INT0_1 MIX1 INP0", "RX0", "RX_RX0"},
2950 {"RX INT0_1 MIX1 INP0", "RX1", "RX_RX1"},
2951 {"RX INT0_1 MIX1 INP0", "RX2", "RX_RX2"},
2952 {"RX INT0_1 MIX1 INP0", "RX3", "RX_RX3"},
2953 {"RX INT0_1 MIX1 INP0", "RX4", "RX_RX4"},
2954 {"RX INT0_1 MIX1 INP0", "RX5", "RX_RX5"},
2955 {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"},
2956 {"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"},
2957 {"RX INT0_1 MIX1 INP1", "RX0", "RX_RX0"},
2958 {"RX INT0_1 MIX1 INP1", "RX1", "RX_RX1"},
2959 {"RX INT0_1 MIX1 INP1", "RX2", "RX_RX2"},
2960 {"RX INT0_1 MIX1 INP1", "RX3", "RX_RX3"},
2961 {"RX INT0_1 MIX1 INP1", "RX4", "RX_RX4"},
2962 {"RX INT0_1 MIX1 INP1", "RX5", "RX_RX5"},
2963 {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"},
2964 {"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"},
2965 {"RX INT0_1 MIX1 INP2", "RX0", "RX_RX0"},
2966 {"RX INT0_1 MIX1 INP2", "RX1", "RX_RX1"},
2967 {"RX INT0_1 MIX1 INP2", "RX2", "RX_RX2"},
2968 {"RX INT0_1 MIX1 INP2", "RX3", "RX_RX3"},
2969 {"RX INT0_1 MIX1 INP2", "RX4", "RX_RX4"},
2970 {"RX INT0_1 MIX1 INP2", "RX5", "RX_RX5"},
2971 {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"},
2972 {"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"},
2973
2974 {"RX INT1_1 MIX1 INP0", "RX0", "RX_RX0"},
2975 {"RX INT1_1 MIX1 INP0", "RX1", "RX_RX1"},
2976 {"RX INT1_1 MIX1 INP0", "RX2", "RX_RX2"},
2977 {"RX INT1_1 MIX1 INP0", "RX3", "RX_RX3"},
2978 {"RX INT1_1 MIX1 INP0", "RX4", "RX_RX4"},
2979 {"RX INT1_1 MIX1 INP0", "RX5", "RX_RX5"},
2980 {"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"},
2981 {"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"},
2982 {"RX INT1_1 MIX1 INP1", "RX0", "RX_RX0"},
2983 {"RX INT1_1 MIX1 INP1", "RX1", "RX_RX1"},
2984 {"RX INT1_1 MIX1 INP1", "RX2", "RX_RX2"},
2985 {"RX INT1_1 MIX1 INP1", "RX3", "RX_RX3"},
2986 {"RX INT1_1 MIX1 INP1", "RX4", "RX_RX4"},
2987 {"RX INT1_1 MIX1 INP1", "RX5", "RX_RX5"},
2988 {"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"},
2989 {"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"},
2990 {"RX INT1_1 MIX1 INP2", "RX0", "RX_RX0"},
2991 {"RX INT1_1 MIX1 INP2", "RX1", "RX_RX1"},
2992 {"RX INT1_1 MIX1 INP2", "RX2", "RX_RX2"},
2993 {"RX INT1_1 MIX1 INP2", "RX3", "RX_RX3"},
2994 {"RX INT1_1 MIX1 INP2", "RX4", "RX_RX4"},
2995 {"RX INT1_1 MIX1 INP2", "RX5", "RX_RX5"},
2996 {"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"},
2997 {"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"},
2998
2999 {"RX INT2_1 MIX1 INP0", "RX0", "RX_RX0"},
3000 {"RX INT2_1 MIX1 INP0", "RX1", "RX_RX1"},
3001 {"RX INT2_1 MIX1 INP0", "RX2", "RX_RX2"},
3002 {"RX INT2_1 MIX1 INP0", "RX3", "RX_RX3"},
3003 {"RX INT2_1 MIX1 INP0", "RX4", "RX_RX4"},
3004 {"RX INT2_1 MIX1 INP0", "RX5", "RX_RX5"},
3005 {"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"},
3006 {"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"},
3007 {"RX INT2_1 MIX1 INP1", "RX0", "RX_RX0"},
3008 {"RX INT2_1 MIX1 INP1", "RX1", "RX_RX1"},
3009 {"RX INT2_1 MIX1 INP1", "RX2", "RX_RX2"},
3010 {"RX INT2_1 MIX1 INP1", "RX3", "RX_RX3"},
3011 {"RX INT2_1 MIX1 INP1", "RX4", "RX_RX4"},
3012 {"RX INT2_1 MIX1 INP1", "RX5", "RX_RX5"},
3013 {"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"},
3014 {"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"},
3015 {"RX INT2_1 MIX1 INP2", "RX0", "RX_RX0"},
3016 {"RX INT2_1 MIX1 INP2", "RX1", "RX_RX1"},
3017 {"RX INT2_1 MIX1 INP2", "RX2", "RX_RX2"},
3018 {"RX INT2_1 MIX1 INP2", "RX3", "RX_RX3"},
3019 {"RX INT2_1 MIX1 INP2", "RX4", "RX_RX4"},
3020 {"RX INT2_1 MIX1 INP2", "RX5", "RX_RX5"},
3021 {"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"},
3022 {"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"},
3023
3024 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"},
3025 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"},
3026 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"},
3027 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP0"},
3028 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP1"},
3029 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP2"},
3030 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP0"},
3031 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"},
3032 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"},
3033
Vatsal Buchac2d6c222018-11-30 18:46:37 +05303034 {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
3035 {"RX MIX TX0 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
3036 {"RX MIX TX0 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
3037 {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
3038 {"RX MIX TX1 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
3039 {"RX MIX TX1 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
3040 {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
3041 {"RX MIX TX2 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
3042 {"RX MIX TX2 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
3043 {"RX AIF_ECHO", NULL, "RX MIX TX0 MUX"},
3044 {"RX AIF_ECHO", NULL, "RX MIX TX1 MUX"},
3045 {"RX AIF_ECHO", NULL, "RX MIX TX2 MUX"},
3046 {"RX AIF_ECHO", NULL, "RX_MCLK"},
3047
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303048 /* Mixing path INT0 */
3049 {"RX INT0_2 MUX", "RX0", "RX_RX0"},
3050 {"RX INT0_2 MUX", "RX1", "RX_RX1"},
3051 {"RX INT0_2 MUX", "RX2", "RX_RX2"},
3052 {"RX INT0_2 MUX", "RX3", "RX_RX3"},
3053 {"RX INT0_2 MUX", "RX4", "RX_RX4"},
3054 {"RX INT0_2 MUX", "RX5", "RX_RX5"},
3055 {"RX INT0_2 INTERP", NULL, "RX INT0_2 MUX"},
3056 {"RX INT0 SEC MIX", NULL, "RX INT0_2 INTERP"},
3057
3058 /* Mixing path INT1 */
3059 {"RX INT1_2 MUX", "RX0", "RX_RX0"},
3060 {"RX INT1_2 MUX", "RX1", "RX_RX1"},
3061 {"RX INT1_2 MUX", "RX2", "RX_RX2"},
3062 {"RX INT1_2 MUX", "RX3", "RX_RX3"},
3063 {"RX INT1_2 MUX", "RX4", "RX_RX4"},
3064 {"RX INT1_2 MUX", "RX5", "RX_RX5"},
3065 {"RX INT1_2 INTERP", NULL, "RX INT1_2 MUX"},
3066 {"RX INT1 SEC MIX", NULL, "RX INT1_2 INTERP"},
3067
3068 /* Mixing path INT2 */
3069 {"RX INT2_2 MUX", "RX0", "RX_RX0"},
3070 {"RX INT2_2 MUX", "RX1", "RX_RX1"},
3071 {"RX INT2_2 MUX", "RX2", "RX_RX2"},
3072 {"RX INT2_2 MUX", "RX3", "RX_RX3"},
3073 {"RX INT2_2 MUX", "RX4", "RX_RX4"},
3074 {"RX INT2_2 MUX", "RX5", "RX_RX5"},
3075 {"RX INT2_2 INTERP", NULL, "RX INT2_2 MUX"},
3076 {"RX INT2 SEC MIX", NULL, "RX INT2_2 INTERP"},
3077
3078 {"RX INT0_1 INTERP", NULL, "RX INT0_1 MIX1"},
3079 {"RX INT0 SEC MIX", NULL, "RX INT0_1 INTERP"},
3080 {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"},
3081 {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"},
3082 {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 MIX2"},
3083 {"HPHL_OUT", NULL, "RX INT0 DEM MUX"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05303084 {"HPHL_OUT", NULL, "RX_MCLK"},
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303085
3086 {"RX INT1_1 INTERP", NULL, "RX INT1_1 MIX1"},
3087 {"RX INT1 SEC MIX", NULL, "RX INT1_1 INTERP"},
3088 {"RX INT1 MIX2", NULL, "RX INT1 SEC MIX"},
3089 {"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"},
3090 {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 MIX2"},
3091 {"HPHR_OUT", NULL, "RX INT1 DEM MUX"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05303092 {"HPHR_OUT", NULL, "RX_MCLK"},
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303093
3094 {"RX INT2_1 INTERP", NULL, "RX INT2_1 MIX1"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303095
3096 {"RX INT2_1 VBAT", "RX AUX VBAT Enable", "RX INT2_1 INTERP"},
3097 {"RX INT2 SEC MIX", NULL, "RX INT2_1 VBAT"},
3098
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303099 {"RX INT2 SEC MIX", NULL, "RX INT2_1 INTERP"},
3100 {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"},
3101 {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"},
3102 {"AUX_OUT", NULL, "RX INT2 MIX2"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05303103 {"AUX_OUT", NULL, "RX_MCLK"},
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303104
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05303105 {"IIR0", NULL, "RX_MCLK"},
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303106 {"IIR0", NULL, "IIR0 INP0 MUX"},
3107 {"IIR0 INP0 MUX", "DEC0", "RX_TX DEC0_INP"},
3108 {"IIR0 INP0 MUX", "DEC1", "RX_TX DEC1_INP"},
3109 {"IIR0 INP0 MUX", "DEC2", "RX_TX DEC2_INP"},
3110 {"IIR0 INP0 MUX", "DEC3", "RX_TX DEC3_INP"},
3111 {"IIR0 INP0 MUX", "RX0", "RX_RX0"},
3112 {"IIR0 INP0 MUX", "RX1", "RX_RX1"},
3113 {"IIR0 INP0 MUX", "RX2", "RX_RX2"},
3114 {"IIR0 INP0 MUX", "RX3", "RX_RX3"},
3115 {"IIR0 INP0 MUX", "RX4", "RX_RX4"},
3116 {"IIR0 INP0 MUX", "RX5", "RX_RX5"},
3117 {"IIR0", NULL, "IIR0 INP1 MUX"},
3118 {"IIR0 INP1 MUX", "DEC0", "RX_TX DEC0_INP"},
3119 {"IIR0 INP1 MUX", "DEC1", "RX_TX DEC1_INP"},
3120 {"IIR0 INP1 MUX", "DEC2", "RX_TX DEC2_INP"},
3121 {"IIR0 INP1 MUX", "DEC3", "RX_TX DEC3_INP"},
3122 {"IIR0 INP1 MUX", "RX0", "RX_RX0"},
3123 {"IIR0 INP1 MUX", "RX1", "RX_RX1"},
3124 {"IIR0 INP1 MUX", "RX2", "RX_RX2"},
3125 {"IIR0 INP1 MUX", "RX3", "RX_RX3"},
3126 {"IIR0 INP1 MUX", "RX4", "RX_RX4"},
3127 {"IIR0 INP1 MUX", "RX5", "RX_RX5"},
3128 {"IIR0", NULL, "IIR0 INP2 MUX"},
3129 {"IIR0 INP2 MUX", "DEC0", "RX_TX DEC0_INP"},
3130 {"IIR0 INP2 MUX", "DEC1", "RX_TX DEC1_INP"},
3131 {"IIR0 INP2 MUX", "DEC2", "RX_TX DEC2_INP"},
3132 {"IIR0 INP2 MUX", "DEC3", "RX_TX DEC3_INP"},
3133 {"IIR0 INP2 MUX", "RX0", "RX_RX0"},
3134 {"IIR0 INP2 MUX", "RX1", "RX_RX1"},
3135 {"IIR0 INP2 MUX", "RX2", "RX_RX2"},
3136 {"IIR0 INP2 MUX", "RX3", "RX_RX3"},
3137 {"IIR0 INP2 MUX", "RX4", "RX_RX4"},
3138 {"IIR0 INP2 MUX", "RX5", "RX_RX5"},
3139 {"IIR0", NULL, "IIR0 INP3 MUX"},
3140 {"IIR0 INP3 MUX", "DEC0", "RX_TX DEC0_INP"},
3141 {"IIR0 INP3 MUX", "DEC1", "RX_TX DEC1_INP"},
3142 {"IIR0 INP3 MUX", "DEC2", "RX_TX DEC2_INP"},
3143 {"IIR0 INP3 MUX", "DEC3", "RX_TX DEC3_INP"},
3144 {"IIR0 INP3 MUX", "RX0", "RX_RX0"},
3145 {"IIR0 INP3 MUX", "RX1", "RX_RX1"},
3146 {"IIR0 INP3 MUX", "RX2", "RX_RX2"},
3147 {"IIR0 INP3 MUX", "RX3", "RX_RX3"},
3148 {"IIR0 INP3 MUX", "RX4", "RX_RX4"},
3149 {"IIR0 INP3 MUX", "RX5", "RX_RX5"},
3150
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05303151 {"IIR1", NULL, "RX_MCLK"},
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303152 {"IIR1", NULL, "IIR1 INP0 MUX"},
3153 {"IIR1 INP0 MUX", "DEC0", "RX_TX DEC0_INP"},
3154 {"IIR1 INP0 MUX", "DEC1", "RX_TX DEC1_INP"},
3155 {"IIR1 INP0 MUX", "DEC2", "RX_TX DEC2_INP"},
3156 {"IIR1 INP0 MUX", "DEC3", "RX_TX DEC3_INP"},
3157 {"IIR1 INP0 MUX", "RX0", "RX_RX0"},
3158 {"IIR1 INP0 MUX", "RX1", "RX_RX1"},
3159 {"IIR1 INP0 MUX", "RX2", "RX_RX2"},
3160 {"IIR1 INP0 MUX", "RX3", "RX_RX3"},
3161 {"IIR1 INP0 MUX", "RX4", "RX_RX4"},
3162 {"IIR1 INP0 MUX", "RX5", "RX_RX5"},
3163 {"IIR1", NULL, "IIR1 INP1 MUX"},
3164 {"IIR1 INP1 MUX", "DEC0", "RX_TX DEC0_INP"},
3165 {"IIR1 INP1 MUX", "DEC1", "RX_TX DEC1_INP"},
3166 {"IIR1 INP1 MUX", "DEC2", "RX_TX DEC2_INP"},
3167 {"IIR1 INP1 MUX", "DEC3", "RX_TX DEC3_INP"},
3168 {"IIR1 INP1 MUX", "RX0", "RX_RX0"},
3169 {"IIR1 INP1 MUX", "RX1", "RX_RX1"},
3170 {"IIR1 INP1 MUX", "RX2", "RX_RX2"},
3171 {"IIR1 INP1 MUX", "RX3", "RX_RX3"},
3172 {"IIR1 INP1 MUX", "RX4", "RX_RX4"},
3173 {"IIR1 INP1 MUX", "RX5", "RX_RX5"},
3174 {"IIR1", NULL, "IIR1 INP2 MUX"},
3175 {"IIR1 INP2 MUX", "DEC0", "RX_TX DEC0_INP"},
3176 {"IIR1 INP2 MUX", "DEC1", "RX_TX DEC1_INP"},
3177 {"IIR1 INP2 MUX", "DEC2", "RX_TX DEC2_INP"},
3178 {"IIR1 INP2 MUX", "DEC3", "RX_TX DEC3_INP"},
3179 {"IIR1 INP2 MUX", "RX0", "RX_RX0"},
3180 {"IIR1 INP2 MUX", "RX1", "RX_RX1"},
3181 {"IIR1 INP2 MUX", "RX2", "RX_RX2"},
3182 {"IIR1 INP2 MUX", "RX3", "RX_RX3"},
3183 {"IIR1 INP2 MUX", "RX4", "RX_RX4"},
3184 {"IIR1 INP2 MUX", "RX5", "RX_RX5"},
3185 {"IIR1", NULL, "IIR1 INP3 MUX"},
3186 {"IIR1 INP3 MUX", "DEC0", "RX_TX DEC0_INP"},
3187 {"IIR1 INP3 MUX", "DEC1", "RX_TX DEC1_INP"},
3188 {"IIR1 INP3 MUX", "DEC2", "RX_TX DEC2_INP"},
3189 {"IIR1 INP3 MUX", "DEC3", "RX_TX DEC3_INP"},
3190 {"IIR1 INP3 MUX", "RX0", "RX_RX0"},
3191 {"IIR1 INP3 MUX", "RX1", "RX_RX1"},
3192 {"IIR1 INP3 MUX", "RX2", "RX_RX2"},
3193 {"IIR1 INP3 MUX", "RX3", "RX_RX3"},
3194 {"IIR1 INP3 MUX", "RX4", "RX_RX4"},
3195 {"IIR1 INP3 MUX", "RX5", "RX_RX5"},
3196
3197 {"SRC0", NULL, "IIR0"},
3198 {"SRC1", NULL, "IIR1"},
3199 {"RX INT0 MIX2 INP", "SRC0", "SRC0"},
3200 {"RX INT0 MIX2 INP", "SRC1", "SRC1"},
3201 {"RX INT1 MIX2 INP", "SRC0", "SRC0"},
3202 {"RX INT1 MIX2 INP", "SRC1", "SRC1"},
3203 {"RX INT2 MIX2 INP", "SRC0", "SRC0"},
3204 {"RX INT2 MIX2 INP", "SRC1", "SRC1"},
3205};
3206
3207static int rx_swrm_clock(void *handle, bool enable)
3208{
3209 struct rx_macro_priv *rx_priv = (struct rx_macro_priv *) handle;
3210 struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL);
3211 int ret = 0;
3212
Tanya Dixit8530fb92018-09-14 16:01:25 +05303213 if (regmap == NULL) {
3214 dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__);
3215 return -EINVAL;
3216 }
3217
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303218 mutex_lock(&rx_priv->swr_clk_lock);
3219
3220 dev_dbg(rx_priv->dev, "%s: swrm clock %s\n",
3221 __func__, (enable ? "enable" : "disable"));
3222 if (enable) {
3223 if (rx_priv->swr_clk_users == 0) {
3224 ret = rx_macro_mclk_enable(rx_priv, 1, true);
3225 if (ret < 0) {
3226 dev_err(rx_priv->dev,
3227 "%s: rx request clock enable failed\n",
3228 __func__);
3229 goto exit;
3230 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05303231 if (rx_priv->reset_swr)
3232 regmap_update_bits(regmap,
3233 BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
3234 0x02, 0x02);
Ramprasad Katkam9c2394a2018-08-23 13:13:48 +05303235 regmap_update_bits(regmap,
3236 BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303237 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05303238 if (rx_priv->reset_swr)
3239 regmap_update_bits(regmap,
3240 BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
3241 0x02, 0x00);
3242 rx_priv->reset_swr = false;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303243 msm_cdc_pinctrl_select_active_state(
3244 rx_priv->rx_swr_gpio_p);
3245 }
3246 rx_priv->swr_clk_users++;
3247 } else {
3248 if (rx_priv->swr_clk_users <= 0) {
3249 dev_err(rx_priv->dev,
3250 "%s: rx swrm clock users already reset\n",
3251 __func__);
3252 rx_priv->swr_clk_users = 0;
3253 goto exit;
3254 }
3255 rx_priv->swr_clk_users--;
3256 if (rx_priv->swr_clk_users == 0) {
3257 regmap_update_bits(regmap,
3258 BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
3259 0x01, 0x00);
3260 msm_cdc_pinctrl_select_sleep_state(
3261 rx_priv->rx_swr_gpio_p);
3262 rx_macro_mclk_enable(rx_priv, 0, true);
3263 }
3264 }
3265 dev_dbg(rx_priv->dev, "%s: swrm clock users %d\n",
3266 __func__, rx_priv->swr_clk_users);
3267exit:
3268 mutex_unlock(&rx_priv->swr_clk_lock);
3269 return ret;
3270}
3271
Meng Wang15c825d2018-09-06 10:49:18 +08003272static void rx_macro_init_bcl_pmic_reg(struct snd_soc_component *component)
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303273{
3274 struct device *rx_dev = NULL;
3275 struct rx_macro_priv *rx_priv = NULL;
3276
Meng Wang15c825d2018-09-06 10:49:18 +08003277 if (!component) {
3278 pr_err("%s: NULL component pointer!\n", __func__);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303279 return;
3280 }
3281
Meng Wang15c825d2018-09-06 10:49:18 +08003282 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303283 return;
3284
3285 switch (rx_priv->bcl_pmic_params.id) {
3286 case 0:
3287 /* Enable ID0 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08003288 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303289 BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
3290 /* Update MC_SID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08003291 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303292 BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1, 0x0F,
3293 rx_priv->bcl_pmic_params.sid);
3294 /* Update MC_PPID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08003295 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303296 BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG2, 0xFF,
3297 rx_priv->bcl_pmic_params.ppid);
3298 break;
3299 case 1:
3300 /* Enable ID1 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08003301 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303302 BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
3303 /* Update MC_SID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08003304 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303305 BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG3, 0x0F,
3306 rx_priv->bcl_pmic_params.sid);
3307 /* Update MC_PPID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08003308 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303309 BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1, 0xFF,
3310 rx_priv->bcl_pmic_params.ppid);
3311 break;
3312 default:
Md Mansoor Ahmed26d8bdd2018-11-20 10:56:01 +05303313 dev_err(rx_dev, "%s: PMIC ID is invalid %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303314 __func__, rx_priv->bcl_pmic_params.id);
3315 break;
3316 }
3317}
3318
Meng Wang15c825d2018-09-06 10:49:18 +08003319static int rx_macro_init(struct snd_soc_component *component)
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303320{
Meng Wang15c825d2018-09-06 10:49:18 +08003321 struct snd_soc_dapm_context *dapm =
3322 snd_soc_component_get_dapm(component);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303323 int ret = 0;
3324 struct device *rx_dev = NULL;
3325 struct rx_macro_priv *rx_priv = NULL;
3326
Meng Wang15c825d2018-09-06 10:49:18 +08003327 rx_dev = bolero_get_device_ptr(component->dev, RX_MACRO);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303328 if (!rx_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08003329 dev_err(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303330 "%s: null device for macro!\n", __func__);
3331 return -EINVAL;
3332 }
3333 rx_priv = dev_get_drvdata(rx_dev);
3334 if (!rx_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08003335 dev_err(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303336 "%s: priv is null for macro!\n", __func__);
3337 return -EINVAL;
3338 }
3339
3340 ret = snd_soc_dapm_new_controls(dapm, rx_macro_dapm_widgets,
3341 ARRAY_SIZE(rx_macro_dapm_widgets));
3342 if (ret < 0) {
3343 dev_err(rx_dev, "%s: failed to add controls\n", __func__);
3344 return ret;
3345 }
3346 ret = snd_soc_dapm_add_routes(dapm, rx_audio_map,
3347 ARRAY_SIZE(rx_audio_map));
3348 if (ret < 0) {
3349 dev_err(rx_dev, "%s: failed to add routes\n", __func__);
3350 return ret;
3351 }
3352 ret = snd_soc_dapm_new_widgets(dapm->card);
3353 if (ret < 0) {
3354 dev_err(rx_dev, "%s: failed to add widgets\n", __func__);
3355 return ret;
3356 }
Meng Wang15c825d2018-09-06 10:49:18 +08003357 ret = snd_soc_add_component_controls(component, rx_macro_snd_controls,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303358 ARRAY_SIZE(rx_macro_snd_controls));
3359 if (ret < 0) {
3360 dev_err(rx_dev, "%s: failed to add snd_ctls\n", __func__);
3361 return ret;
3362 }
Laxminath Kasam701e3582018-10-15 20:06:09 +05303363 rx_priv->dev_up = true;
Laxminath Kasam638b5602018-09-24 13:19:52 +05303364 snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF1 Playback");
3365 snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF2 Playback");
3366 snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF3 Playback");
3367 snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF4 Playback");
3368 snd_soc_dapm_ignore_suspend(dapm, "HPHL_OUT");
3369 snd_soc_dapm_ignore_suspend(dapm, "HPHR_OUT");
3370 snd_soc_dapm_ignore_suspend(dapm, "AUX_OUT");
3371 snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC0_INP");
3372 snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC1_INP");
3373 snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC2_INP");
3374 snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC3_INP");
3375 snd_soc_dapm_sync(dapm);
3376
Meng Wang15c825d2018-09-06 10:49:18 +08003377 snd_soc_component_update_bits(component,
3378 BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL,
3379 0x01, 0x01);
3380 snd_soc_component_update_bits(component,
3381 BOLERO_CDC_RX_RX1_RX_PATH_DSM_CTL,
3382 0x01, 0x01);
3383 snd_soc_component_update_bits(component,
3384 BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL,
3385 0x01, 0x01);
3386 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX0_RX_PATH_SEC7,
3387 0x07, 0x02);
3388 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX1_RX_PATH_SEC7,
3389 0x07, 0x02);
3390 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX2_RX_PATH_SEC7,
3391 0x07, 0x02);
3392 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX0_RX_PATH_CFG3,
3393 0x03, 0x02);
3394 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX1_RX_PATH_CFG3,
3395 0x03, 0x02);
3396 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX2_RX_PATH_CFG3,
3397 0x03, 0x02);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303398
Meng Wang15c825d2018-09-06 10:49:18 +08003399 rx_priv->component = component;
Vatsal Bucha39ead2c2018-12-14 12:22:46 +05303400 rx_macro_init_bcl_pmic_reg(component);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303401
3402 return 0;
3403}
3404
Meng Wang15c825d2018-09-06 10:49:18 +08003405static int rx_macro_deinit(struct snd_soc_component *component)
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303406{
3407 struct device *rx_dev = NULL;
3408 struct rx_macro_priv *rx_priv = NULL;
3409
Meng Wang15c825d2018-09-06 10:49:18 +08003410 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303411 return -EINVAL;
3412
Meng Wang15c825d2018-09-06 10:49:18 +08003413 rx_priv->component = NULL;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303414
3415 return 0;
3416}
3417
3418static void rx_macro_add_child_devices(struct work_struct *work)
3419{
3420 struct rx_macro_priv *rx_priv = NULL;
3421 struct platform_device *pdev = NULL;
3422 struct device_node *node = NULL;
3423 struct rx_swr_ctrl_data *swr_ctrl_data = NULL, *temp = NULL;
3424 int ret = 0;
3425 u16 count = 0, ctrl_num = 0;
3426 struct rx_swr_ctrl_platform_data *platdata = NULL;
3427 char plat_dev_name[RX_SWR_STRING_LEN] = "";
3428 bool rx_swr_master_node = false;
3429
3430 rx_priv = container_of(work, struct rx_macro_priv,
3431 rx_macro_add_child_devices_work);
3432 if (!rx_priv) {
3433 pr_err("%s: Memory for rx_priv does not exist\n",
3434 __func__);
3435 return;
3436 }
3437
3438 if (!rx_priv->dev) {
3439 pr_err("%s: RX device does not exist\n", __func__);
3440 return;
3441 }
3442
3443 if(!rx_priv->dev->of_node) {
3444 dev_err(rx_priv->dev,
3445 "%s: DT node for RX dev does not exist\n", __func__);
3446 return;
3447 }
3448
3449 platdata = &rx_priv->swr_plat_data;
3450 rx_priv->child_count = 0;
3451
3452 for_each_available_child_of_node(rx_priv->dev->of_node, node) {
3453 rx_swr_master_node = false;
3454 if (strnstr(node->name, "rx_swr_master",
3455 strlen("rx_swr_master")) != NULL)
3456 rx_swr_master_node = true;
3457
3458 if(rx_swr_master_node)
3459 strlcpy(plat_dev_name, "rx_swr_ctrl",
3460 (RX_SWR_STRING_LEN - 1));
3461 else
3462 strlcpy(plat_dev_name, node->name,
3463 (RX_SWR_STRING_LEN - 1));
3464
3465 pdev = platform_device_alloc(plat_dev_name, -1);
3466 if (!pdev) {
3467 dev_err(rx_priv->dev, "%s: pdev memory alloc failed\n",
3468 __func__);
3469 ret = -ENOMEM;
3470 goto err;
3471 }
3472 pdev->dev.parent = rx_priv->dev;
3473 pdev->dev.of_node = node;
3474
3475 if (rx_swr_master_node) {
3476 ret = platform_device_add_data(pdev, platdata,
3477 sizeof(*platdata));
3478 if (ret) {
3479 dev_err(&pdev->dev,
3480 "%s: cannot add plat data ctrl:%d\n",
3481 __func__, ctrl_num);
3482 goto fail_pdev_add;
3483 }
3484 }
3485
3486 ret = platform_device_add(pdev);
3487 if (ret) {
3488 dev_err(&pdev->dev,
3489 "%s: Cannot add platform device\n",
3490 __func__);
3491 goto fail_pdev_add;
3492 }
3493
3494 if (rx_swr_master_node) {
3495 temp = krealloc(swr_ctrl_data,
3496 (ctrl_num + 1) * sizeof(
3497 struct rx_swr_ctrl_data),
3498 GFP_KERNEL);
3499 if (!temp) {
3500 ret = -ENOMEM;
3501 goto fail_pdev_add;
3502 }
3503 swr_ctrl_data = temp;
3504 swr_ctrl_data[ctrl_num].rx_swr_pdev = pdev;
3505 ctrl_num++;
3506 dev_dbg(&pdev->dev,
3507 "%s: Added soundwire ctrl device(s)\n",
3508 __func__);
3509 rx_priv->swr_ctrl_data = swr_ctrl_data;
3510 }
3511 if (rx_priv->child_count < RX_MACRO_CHILD_DEVICES_MAX)
3512 rx_priv->pdev_child_devices[
3513 rx_priv->child_count++] = pdev;
3514 else
3515 goto err;
3516 }
3517 return;
3518fail_pdev_add:
3519 for (count = 0; count < rx_priv->child_count; count++)
3520 platform_device_put(rx_priv->pdev_child_devices[count]);
3521err:
3522 return;
3523}
3524
3525static void rx_macro_init_ops(struct macro_ops *ops, char __iomem *rx_io_base)
3526{
3527 memset(ops, 0, sizeof(struct macro_ops));
3528 ops->init = rx_macro_init;
3529 ops->exit = rx_macro_deinit;
3530 ops->io_base = rx_io_base;
3531 ops->dai_ptr = rx_macro_dai;
3532 ops->num_dais = ARRAY_SIZE(rx_macro_dai);
3533 ops->mclk_fn = rx_macro_mclk_ctrl;
Laxminath Kasam497a6512018-09-17 16:11:52 +05303534 ops->event_handler = rx_macro_event_handler;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05303535 ops->set_port_map = rx_macro_set_port_map;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303536}
3537
3538static int rx_macro_probe(struct platform_device *pdev)
3539{
3540 struct macro_ops ops = {0};
3541 struct rx_macro_priv *rx_priv = NULL;
3542 u32 rx_base_addr = 0, muxsel = 0;
3543 char __iomem *rx_io_base = NULL, *muxsel_io = NULL;
3544 int ret = 0;
3545 struct clk *rx_core_clk = NULL, *rx_npl_clk = NULL;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303546 u8 bcl_pmic_params[3];
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303547
3548 rx_priv = devm_kzalloc(&pdev->dev, sizeof(struct rx_macro_priv),
3549 GFP_KERNEL);
3550 if (!rx_priv)
3551 return -ENOMEM;
3552
3553 rx_priv->dev = &pdev->dev;
3554 ret = of_property_read_u32(pdev->dev.of_node, "reg",
3555 &rx_base_addr);
3556 if (ret) {
3557 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
3558 __func__, "reg");
3559 return ret;
3560 }
3561 ret = of_property_read_u32(pdev->dev.of_node, "qcom,rx_mclk_mode_muxsel",
3562 &muxsel);
3563 if (ret) {
3564 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
3565 __func__, "reg");
3566 return ret;
3567 }
3568 rx_priv->rx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
3569 "qcom,rx-swr-gpios", 0);
3570 if (!rx_priv->rx_swr_gpio_p) {
3571 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
3572 __func__);
3573 return -EINVAL;
3574 }
3575 rx_io_base = devm_ioremap(&pdev->dev, rx_base_addr,
3576 RX_MACRO_MAX_OFFSET);
3577 if (!rx_io_base) {
3578 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
3579 return -ENOMEM;
3580 }
3581 rx_priv->rx_io_base = rx_io_base;
3582 muxsel_io = devm_ioremap(&pdev->dev, muxsel, 0x4);
3583 if (!muxsel_io) {
3584 dev_err(&pdev->dev, "%s: ioremap failed for muxsel\n",
3585 __func__);
3586 return -ENOMEM;
3587 }
3588 rx_priv->rx_mclk_mode_muxsel = muxsel_io;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05303589 rx_priv->reset_swr = true;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303590 INIT_WORK(&rx_priv->rx_macro_add_child_devices_work,
3591 rx_macro_add_child_devices);
3592 rx_priv->swr_plat_data.handle = (void *) rx_priv;
3593 rx_priv->swr_plat_data.read = NULL;
3594 rx_priv->swr_plat_data.write = NULL;
3595 rx_priv->swr_plat_data.bulk_write = NULL;
3596 rx_priv->swr_plat_data.clk = rx_swrm_clock;
3597 rx_priv->swr_plat_data.handle_irq = NULL;
3598
3599 /* Register MCLK for rx macro */
3600 rx_core_clk = devm_clk_get(&pdev->dev, "rx_core_clk");
3601 if (IS_ERR(rx_core_clk)) {
3602 ret = PTR_ERR(rx_core_clk);
3603 dev_err(&pdev->dev, "%s: clk get %s failed %d\n",
3604 __func__, "rx_core_clk", ret);
3605 return ret;
3606 }
3607 rx_priv->rx_core_clk = rx_core_clk;
3608 /* Register npl clk for soundwire */
3609 rx_npl_clk = devm_clk_get(&pdev->dev, "rx_npl_clk");
3610 if (IS_ERR(rx_npl_clk)) {
3611 ret = PTR_ERR(rx_npl_clk);
3612 dev_err(&pdev->dev, "%s: clk get %s failed %d\n",
3613 __func__, "rx_npl_clk", ret);
3614 return ret;
3615 }
3616 rx_priv->rx_npl_clk = rx_npl_clk;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303617
3618 ret = of_property_read_u8_array(pdev->dev.of_node,
3619 "qcom,rx-bcl-pmic-params", bcl_pmic_params,
3620 sizeof(bcl_pmic_params));
3621 if (ret) {
3622 dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
3623 __func__, "qcom,rx-bcl-pmic-params");
3624 } else {
3625 rx_priv->bcl_pmic_params.id = bcl_pmic_params[0];
3626 rx_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
3627 rx_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
3628 }
3629
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303630 dev_set_drvdata(&pdev->dev, rx_priv);
3631 mutex_init(&rx_priv->mclk_lock);
3632 mutex_init(&rx_priv->swr_clk_lock);
3633 rx_macro_init_ops(&ops, rx_io_base);
3634
3635 ret = bolero_register_macro(&pdev->dev, RX_MACRO, &ops);
3636 if (ret) {
3637 dev_err(&pdev->dev,
3638 "%s: register macro failed\n", __func__);
3639 goto err_reg_macro;
3640 }
3641 schedule_work(&rx_priv->rx_macro_add_child_devices_work);
3642
3643 return 0;
3644
3645err_reg_macro:
3646 mutex_destroy(&rx_priv->mclk_lock);
3647 mutex_destroy(&rx_priv->swr_clk_lock);
3648 return ret;
3649}
3650
3651static int rx_macro_remove(struct platform_device *pdev)
3652{
3653 struct rx_macro_priv *rx_priv = NULL;
3654 u16 count = 0;
3655
3656 rx_priv = dev_get_drvdata(&pdev->dev);
3657
3658 if (!rx_priv)
3659 return -EINVAL;
3660
3661 for (count = 0; count < rx_priv->child_count &&
3662 count < RX_MACRO_CHILD_DEVICES_MAX; count++)
3663 platform_device_unregister(rx_priv->pdev_child_devices[count]);
3664
3665 bolero_unregister_macro(&pdev->dev, RX_MACRO);
3666 mutex_destroy(&rx_priv->mclk_lock);
3667 mutex_destroy(&rx_priv->swr_clk_lock);
3668 kfree(rx_priv->swr_ctrl_data);
3669 return 0;
3670}
3671
3672static const struct of_device_id rx_macro_dt_match[] = {
3673 {.compatible = "qcom,rx-macro"},
3674 {}
3675};
3676
3677static struct platform_driver rx_macro_driver = {
3678 .driver = {
3679 .name = "rx_macro",
3680 .owner = THIS_MODULE,
3681 .of_match_table = rx_macro_dt_match,
3682 },
3683 .probe = rx_macro_probe,
3684 .remove = rx_macro_remove,
3685};
3686
3687module_platform_driver(rx_macro_driver);
3688
3689MODULE_DESCRIPTION("RX macro driver");
3690MODULE_LICENSE("GPL v2");