blob: bcb7c6b4dd37e8e641a1390c5b85e47e36d897dd [file] [log] [blame]
Meng Wang43bbb872018-12-10 12:32:05 +08001// SPDX-License-Identifier: GPL-2.0-only
Vatsal Buchac2d6c222018-11-30 18:46:37 +05302/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303 */
4
5#include <linux/module.h>
6#include <linux/init.h>
7#include <linux/io.h>
8#include <linux/platform_device.h>
9#include <linux/clk.h>
Sudheer Papothi7601cc62019-03-30 03:00:52 +053010#include <linux/pm_runtime.h>
Laxminath Kasama7ecc582018-06-15 16:55:02 +053011#include <sound/soc.h>
12#include <sound/pcm.h>
13#include <sound/pcm_params.h>
14#include <sound/soc-dapm.h>
15#include <sound/tlv.h>
Sudheer Papothia3e969d2018-10-27 06:22:10 +053016#include <soc/swr-common.h>
Laxminath Kasama7ecc582018-06-15 16:55:02 +053017#include <soc/swr-wcd.h>
18
Meng Wang11a25cf2018-10-31 14:11:26 +080019#include <asoc/msm-cdc-pinctrl.h>
Laxminath Kasama7ecc582018-06-15 16:55:02 +053020#include "bolero-cdc.h"
21#include "bolero-cdc-registers.h"
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -070022#include "bolero-clk-rsc.h"
Laxminath Kasama7ecc582018-06-15 16:55:02 +053023
Sudheer Papothi7601cc62019-03-30 03:00:52 +053024#define AUTO_SUSPEND_DELAY 50 /* delay in msec */
Laxminath Kasama7ecc582018-06-15 16:55:02 +053025#define RX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
26 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
27 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\
28 SNDRV_PCM_RATE_384000)
29/* Fractional Rates */
30#define RX_MACRO_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
31 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800)
32
33#define RX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
34 SNDRV_PCM_FMTBIT_S24_LE |\
35 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
36
37#define RX_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
38 SNDRV_PCM_RATE_48000)
39#define RX_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
40 SNDRV_PCM_FMTBIT_S24_LE |\
41 SNDRV_PCM_FMTBIT_S24_3LE)
42
Laxminath Kasamac396d52018-09-06 12:53:26 +053043#define SAMPLING_RATE_44P1KHZ 44100
44#define SAMPLING_RATE_88P2KHZ 88200
45#define SAMPLING_RATE_176P4KHZ 176400
46#define SAMPLING_RATE_352P8KHZ 352800
47
Laxminath Kasama7ecc582018-06-15 16:55:02 +053048#define RX_MACRO_MAX_OFFSET 0x1000
49
50#define RX_MACRO_MAX_DMA_CH_PER_PORT 2
51#define RX_SWR_STRING_LEN 80
52#define RX_MACRO_CHILD_DEVICES_MAX 3
53
54#define RX_MACRO_INTERP_MUX_NUM_INPUTS 3
55#define RX_MACRO_SIDETONE_IIR_COEFF_MAX 5
56
57#define STRING(name) #name
58#define RX_MACRO_DAPM_ENUM(name, reg, offset, text) \
59static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
60static const struct snd_kcontrol_new name##_mux = \
61 SOC_DAPM_ENUM(STRING(name), name##_enum)
62
63#define RX_MACRO_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \
64static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
65static const struct snd_kcontrol_new name##_mux = \
66 SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname)
67
68#define RX_MACRO_DAPM_MUX(name, shift, kctl) \
69 SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux)
70
71#define RX_MACRO_RX_PATH_OFFSET 0x80
72#define RX_MACRO_COMP_OFFSET 0x40
73
Laxminath Kasam497a6512018-09-17 16:11:52 +053074#define MAX_IMPED_PARAMS 6
75
Vatsal Buchac2d6c222018-11-30 18:46:37 +053076#define RX_MACRO_EC_MIX_TX0_MASK 0xf0
77#define RX_MACRO_EC_MIX_TX1_MASK 0x0f
78#define RX_MACRO_EC_MIX_TX2_MASK 0x0f
79
Laxminath Kasam497a6512018-09-17 16:11:52 +053080struct wcd_imped_val {
81 u32 imped_val;
82 u8 index;
83};
84
85static const struct wcd_imped_val imped_index[] = {
86 {4, 0},
87 {5, 1},
88 {6, 2},
89 {7, 3},
90 {8, 4},
91 {9, 5},
92 {10, 6},
93 {11, 7},
94 {12, 8},
95 {13, 9},
96};
97
98struct rx_macro_reg_mask_val {
99 u16 reg;
100 u8 mask;
101 u8 val;
102};
103
104static const struct rx_macro_reg_mask_val imped_table[][MAX_IMPED_PARAMS] = {
105 {
106 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf2},
107 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf2},
108 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
109 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf2},
110 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf2},
111 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
112 },
113 {
114 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf4},
115 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf4},
116 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
117 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf4},
118 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf4},
119 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
120 },
121 {
122 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf7},
123 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf7},
124 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x01},
125 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf7},
126 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf7},
127 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x01},
128 },
129 {
130 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf9},
131 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf9},
132 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
133 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf9},
134 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf9},
135 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
136 },
137 {
138 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfa},
139 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfa},
140 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
141 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfa},
142 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfa},
143 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
144 },
145 {
146 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfb},
147 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfb},
148 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
149 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfb},
150 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfb},
151 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
152 },
153 {
154 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfc},
155 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfc},
156 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
157 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfc},
158 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfc},
159 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
160 },
161 {
162 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfd},
163 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfd},
164 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
165 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfd},
166 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
167 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
168 },
169 {
170 {BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfd},
171 {BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfd},
172 {BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x01},
173 {BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfd},
174 {BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
175 {BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x01},
176 },
177};
178
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530179enum {
180 INTERP_HPHL,
181 INTERP_HPHR,
182 INTERP_AUX,
183 INTERP_MAX
184};
185
186enum {
187 RX_MACRO_RX0,
188 RX_MACRO_RX1,
189 RX_MACRO_RX2,
190 RX_MACRO_RX3,
191 RX_MACRO_RX4,
192 RX_MACRO_RX5,
193 RX_MACRO_PORTS_MAX
194};
195
196enum {
197 RX_MACRO_COMP1, /* HPH_L */
198 RX_MACRO_COMP2, /* HPH_R */
199 RX_MACRO_COMP_MAX
200};
201
202enum {
Vatsal Buchac2d6c222018-11-30 18:46:37 +0530203 RX_MACRO_EC0_MUX = 0,
204 RX_MACRO_EC1_MUX,
205 RX_MACRO_EC2_MUX,
206 RX_MACRO_EC_MUX_MAX,
207};
208
209enum {
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530210 INTn_1_INP_SEL_ZERO = 0,
211 INTn_1_INP_SEL_DEC0,
212 INTn_1_INP_SEL_DEC1,
213 INTn_1_INP_SEL_IIR0,
214 INTn_1_INP_SEL_IIR1,
215 INTn_1_INP_SEL_RX0,
216 INTn_1_INP_SEL_RX1,
217 INTn_1_INP_SEL_RX2,
218 INTn_1_INP_SEL_RX3,
219 INTn_1_INP_SEL_RX4,
220 INTn_1_INP_SEL_RX5,
221};
222
223enum {
224 INTn_2_INP_SEL_ZERO = 0,
225 INTn_2_INP_SEL_RX0,
226 INTn_2_INP_SEL_RX1,
227 INTn_2_INP_SEL_RX2,
228 INTn_2_INP_SEL_RX3,
229 INTn_2_INP_SEL_RX4,
230 INTn_2_INP_SEL_RX5,
231};
232
233enum {
234 INTERP_MAIN_PATH,
235 INTERP_MIX_PATH,
236};
237
238/* Codec supports 2 IIR filters */
239enum {
240 IIR0 = 0,
241 IIR1,
242 IIR_MAX,
243};
244
245/* Each IIR has 5 Filter Stages */
246enum {
247 BAND1 = 0,
248 BAND2,
249 BAND3,
250 BAND4,
251 BAND5,
252 BAND_MAX,
253};
254
255struct rx_macro_idle_detect_config {
256 u8 hph_idle_thr;
257 u8 hph_idle_detect_en;
258};
259
260struct interp_sample_rate {
261 int sample_rate;
262 int rate_val;
263};
264
265static struct interp_sample_rate sr_val_tbl[] = {
266 {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5},
267 {192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA},
268 {176400, 0xB}, {352800, 0xC},
269};
270
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530271struct rx_macro_bcl_pmic_params {
272 u8 id;
273 u8 sid;
274 u8 ppid;
275};
276
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530277static int rx_macro_hw_params(struct snd_pcm_substream *substream,
278 struct snd_pcm_hw_params *params,
279 struct snd_soc_dai *dai);
280static int rx_macro_get_channel_map(struct snd_soc_dai *dai,
281 unsigned int *tx_num, unsigned int *tx_slot,
282 unsigned int *rx_num, unsigned int *rx_slot);
283static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
284 struct snd_ctl_elem_value *ucontrol);
285static int rx_macro_mux_get(struct snd_kcontrol *kcontrol,
286 struct snd_ctl_elem_value *ucontrol);
287static int rx_macro_mux_put(struct snd_kcontrol *kcontrol,
288 struct snd_ctl_elem_value *ucontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800289static int rx_macro_enable_interp_clk(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530290 int event, int interp_idx);
291
292/* Hold instance to soundwire platform device */
293struct rx_swr_ctrl_data {
294 struct platform_device *rx_swr_pdev;
295};
296
297struct rx_swr_ctrl_platform_data {
298 void *handle; /* holds codec private data */
299 int (*read)(void *handle, int reg);
300 int (*write)(void *handle, int reg, int val);
301 int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
302 int (*clk)(void *handle, bool enable);
303 int (*handle_irq)(void *handle,
304 irqreturn_t (*swrm_irq_handler)(int irq,
305 void *data),
306 void *swrm_handle,
307 int action);
308};
309
310enum {
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +0530311 RX_MACRO_AIF_INVALID = 0,
312 RX_MACRO_AIF1_PB,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530313 RX_MACRO_AIF2_PB,
314 RX_MACRO_AIF3_PB,
315 RX_MACRO_AIF4_PB,
Vatsal Buchac2d6c222018-11-30 18:46:37 +0530316 RX_MACRO_AIF_ECHO,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530317 RX_MACRO_MAX_DAIS,
318};
319
320enum {
321 RX_MACRO_AIF1_CAP = 0,
322 RX_MACRO_AIF2_CAP,
323 RX_MACRO_AIF3_CAP,
324 RX_MACRO_MAX_AIF_CAP_DAIS
325};
326/*
327 * @dev: rx macro device pointer
328 * @comp_enabled: compander enable mixer value set
329 * @prim_int_users: Users of interpolator
330 * @rx_mclk_users: RX MCLK users count
331 * @vi_feed_value: VI sense mask
332 * @swr_clk_lock: to lock swr master clock operations
333 * @swr_ctrl_data: SoundWire data structure
334 * @swr_plat_data: Soundwire platform data
335 * @rx_macro_add_child_devices_work: work for adding child devices
336 * @rx_swr_gpio_p: used by pinctrl API
Meng Wang15c825d2018-09-06 10:49:18 +0800337 * @component: codec handle
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530338 */
339struct rx_macro_priv {
340 struct device *dev;
341 int comp_enabled[RX_MACRO_COMP_MAX];
342 /* Main path clock users count */
343 int main_clk_users[INTERP_MAX];
344 int rx_port_value[RX_MACRO_PORTS_MAX];
345 u16 prim_int_users[INTERP_MAX];
346 int rx_mclk_users;
347 int swr_clk_users;
Ramprasad Katkam452772a2019-01-07 17:30:36 +0530348 bool dapm_mclk_enable;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +0530349 bool reset_swr;
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +0530350 int clsh_users;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530351 int rx_mclk_cnt;
Laxminath Kasambee08192018-07-01 14:38:55 +0530352 bool is_native_on;
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +0530353 bool is_ear_mode_on;
Laxminath Kasam701e3582018-10-15 20:06:09 +0530354 bool dev_up;
Laxminath Kasamde09dfb2018-11-09 13:00:30 +0530355 bool hph_pwr_mode;
Laxminath Kasamd3ffb332018-11-14 19:59:21 +0530356 bool hph_hd2_mode;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530357 struct mutex mclk_lock;
358 struct mutex swr_clk_lock;
359 struct rx_swr_ctrl_data *swr_ctrl_data;
360 struct rx_swr_ctrl_platform_data swr_plat_data;
361 struct work_struct rx_macro_add_child_devices_work;
362 struct device_node *rx_swr_gpio_p;
Meng Wang15c825d2018-09-06 10:49:18 +0800363 struct snd_soc_component *component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530364 unsigned long active_ch_mask[RX_MACRO_MAX_DAIS];
365 unsigned long active_ch_cnt[RX_MACRO_MAX_DAIS];
366 u16 bit_width[RX_MACRO_MAX_DAIS];
367 char __iomem *rx_io_base;
368 char __iomem *rx_mclk_mode_muxsel;
369 struct rx_macro_idle_detect_config idle_det_cfg;
370 u8 sidetone_coeff_array[IIR_MAX][BAND_MAX]
371 [RX_MACRO_SIDETONE_IIR_COEFF_MAX * 4];
372
373 struct platform_device *pdev_child_devices
374 [RX_MACRO_CHILD_DEVICES_MAX];
375 int child_count;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530376 int is_softclip_on;
377 int softclip_clk_users;
378 struct rx_macro_bcl_pmic_params bcl_pmic_params;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -0700379 u16 clk_id;
380 u16 default_clk_id;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530381};
382
383static struct snd_soc_dai_driver rx_macro_dai[];
384static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
385
386static const char * const rx_int_mix_mux_text[] = {
387 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5"
388};
389
390static const char * const rx_prim_mix_text[] = {
391 "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2",
392 "RX3", "RX4", "RX5"
393};
394
395static const char * const rx_sidetone_mix_text[] = {
396 "ZERO", "SRC0", "SRC1", "SRC_SUM"
397};
398
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530399static const char * const iir_inp_mux_text[] = {
400 "ZERO", "DEC0", "DEC1", "DEC2", "DEC3",
401 "RX0", "RX1", "RX2", "RX3", "RX4", "RX5"
402};
403
404static const char * const rx_int_dem_inp_mux_text[] = {
405 "NORMAL_DSM_OUT", "CLSH_DSM_OUT",
406};
407
408static const char * const rx_int0_1_interp_mux_text[] = {
409 "ZERO", "RX INT0_1 MIX1",
410};
411
412static const char * const rx_int1_1_interp_mux_text[] = {
413 "ZERO", "RX INT1_1 MIX1",
414};
415
416static const char * const rx_int2_1_interp_mux_text[] = {
417 "ZERO", "RX INT2_1 MIX1",
418};
419
420static const char * const rx_int0_2_interp_mux_text[] = {
421 "ZERO", "RX INT0_2 MUX",
422};
423
424static const char * const rx_int1_2_interp_mux_text[] = {
425 "ZERO", "RX INT1_2 MUX",
426};
427
428static const char * const rx_int2_2_interp_mux_text[] = {
429 "ZERO", "RX INT2_2 MUX",
430};
431
432static const char *const rx_macro_mux_text[] = {
433 "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB"
434};
435
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +0530436static const char *const rx_macro_ear_mode_text[] = {"OFF", "ON"};
437static const struct soc_enum rx_macro_ear_mode_enum =
438 SOC_ENUM_SINGLE_EXT(2, rx_macro_ear_mode_text);
439
Laxminath Kasamd3ffb332018-11-14 19:59:21 +0530440static const char *const rx_macro_hph_hd2_mode_text[] = {"OFF", "ON"};
441static const struct soc_enum rx_macro_hph_hd2_mode_enum =
442 SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_hd2_mode_text);
443
Laxminath Kasamc21e98a2018-12-04 11:21:01 +0530444static const char *const rx_macro_hph_pwr_mode_text[] = {"ULP", "LOHIFI"};
Laxminath Kasamde09dfb2018-11-09 13:00:30 +0530445static const struct soc_enum rx_macro_hph_pwr_mode_enum =
446 SOC_ENUM_SINGLE_EXT(2, rx_macro_hph_pwr_mode_text);
447
Aditya Bavanari4f3d5642018-09-18 22:19:10 +0530448static const char * const rx_macro_vbat_bcl_gsm_mode_text[] = {"OFF", "ON"};
449static const struct soc_enum rx_macro_vbat_bcl_gsm_mode_enum =
450 SOC_ENUM_SINGLE_EXT(2, rx_macro_vbat_bcl_gsm_mode_text);
451
452static const struct snd_kcontrol_new rx_int2_1_vbat_mix_switch[] = {
453 SOC_DAPM_SINGLE("RX AUX VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
454};
455
Vatsal Bucha8bcc97c2019-01-07 13:18:11 +0530456static const char * const hph_idle_detect_text[] = {"OFF", "ON"};
457
458static SOC_ENUM_SINGLE_EXT_DECL(hph_idle_detect_enum, hph_idle_detect_text);
459
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530460RX_MACRO_DAPM_ENUM(rx_int0_2, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 0,
461 rx_int_mix_mux_text);
462RX_MACRO_DAPM_ENUM(rx_int1_2, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 0,
463 rx_int_mix_mux_text);
464RX_MACRO_DAPM_ENUM(rx_int2_2, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG1, 0,
465 rx_int_mix_mux_text);
466
467
468RX_MACRO_DAPM_ENUM(rx_int0_1_mix_inp0, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0, 0,
469 rx_prim_mix_text);
470RX_MACRO_DAPM_ENUM(rx_int0_1_mix_inp1, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0, 4,
471 rx_prim_mix_text);
472RX_MACRO_DAPM_ENUM(rx_int0_1_mix_inp2, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 4,
473 rx_prim_mix_text);
474RX_MACRO_DAPM_ENUM(rx_int1_1_mix_inp0, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0, 0,
475 rx_prim_mix_text);
476RX_MACRO_DAPM_ENUM(rx_int1_1_mix_inp1, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0, 4,
477 rx_prim_mix_text);
478RX_MACRO_DAPM_ENUM(rx_int1_1_mix_inp2, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 4,
479 rx_prim_mix_text);
480RX_MACRO_DAPM_ENUM(rx_int2_1_mix_inp0, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG0, 0,
481 rx_prim_mix_text);
482RX_MACRO_DAPM_ENUM(rx_int2_1_mix_inp1, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG0, 4,
483 rx_prim_mix_text);
484RX_MACRO_DAPM_ENUM(rx_int2_1_mix_inp2, BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG1, 4,
485 rx_prim_mix_text);
486
487RX_MACRO_DAPM_ENUM(rx_int0_mix2_inp, BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2,
488 rx_sidetone_mix_text);
489RX_MACRO_DAPM_ENUM(rx_int1_mix2_inp, BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4,
490 rx_sidetone_mix_text);
491RX_MACRO_DAPM_ENUM(rx_int2_mix2_inp, BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6,
492 rx_sidetone_mix_text);
493
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530494RX_MACRO_DAPM_ENUM(iir0_inp0, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0, 0,
495 iir_inp_mux_text);
496RX_MACRO_DAPM_ENUM(iir0_inp1, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1, 0,
497 iir_inp_mux_text);
498RX_MACRO_DAPM_ENUM(iir0_inp2, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2, 0,
499 iir_inp_mux_text);
500RX_MACRO_DAPM_ENUM(iir0_inp3, BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3, 0,
501 iir_inp_mux_text);
502RX_MACRO_DAPM_ENUM(iir1_inp0, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0, 0,
503 iir_inp_mux_text);
504RX_MACRO_DAPM_ENUM(iir1_inp1, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1, 0,
505 iir_inp_mux_text);
506RX_MACRO_DAPM_ENUM(iir1_inp2, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2, 0,
507 iir_inp_mux_text);
508RX_MACRO_DAPM_ENUM(iir1_inp3, BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3, 0,
509 iir_inp_mux_text);
510
511RX_MACRO_DAPM_ENUM(rx_int0_1_interp, SND_SOC_NOPM, 0,
512 rx_int0_1_interp_mux_text);
513RX_MACRO_DAPM_ENUM(rx_int1_1_interp, SND_SOC_NOPM, 0,
514 rx_int1_1_interp_mux_text);
515RX_MACRO_DAPM_ENUM(rx_int2_1_interp, SND_SOC_NOPM, 0,
516 rx_int2_1_interp_mux_text);
517
518RX_MACRO_DAPM_ENUM(rx_int0_2_interp, SND_SOC_NOPM, 0,
519 rx_int0_2_interp_mux_text);
520RX_MACRO_DAPM_ENUM(rx_int1_2_interp, SND_SOC_NOPM, 0,
521 rx_int1_2_interp_mux_text);
522RX_MACRO_DAPM_ENUM(rx_int2_2_interp, SND_SOC_NOPM, 0,
523 rx_int2_2_interp_mux_text);
524
525RX_MACRO_DAPM_ENUM_EXT(rx_int0_dem_inp, BOLERO_CDC_RX_RX0_RX_PATH_CFG1, 0,
526 rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double,
527 rx_macro_int_dem_inp_mux_put);
528RX_MACRO_DAPM_ENUM_EXT(rx_int1_dem_inp, BOLERO_CDC_RX_RX1_RX_PATH_CFG1, 0,
529 rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double,
530 rx_macro_int_dem_inp_mux_put);
531
532RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx0, SND_SOC_NOPM, 0, rx_macro_mux_text,
533 rx_macro_mux_get, rx_macro_mux_put);
534RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx1, SND_SOC_NOPM, 0, rx_macro_mux_text,
535 rx_macro_mux_get, rx_macro_mux_put);
536RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx2, SND_SOC_NOPM, 0, rx_macro_mux_text,
537 rx_macro_mux_get, rx_macro_mux_put);
538RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx3, SND_SOC_NOPM, 0, rx_macro_mux_text,
539 rx_macro_mux_get, rx_macro_mux_put);
540RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx4, SND_SOC_NOPM, 0, rx_macro_mux_text,
541 rx_macro_mux_get, rx_macro_mux_put);
542RX_MACRO_DAPM_ENUM_EXT(rx_macro_rx5, SND_SOC_NOPM, 0, rx_macro_mux_text,
543 rx_macro_mux_get, rx_macro_mux_put);
544
Vatsal Buchac2d6c222018-11-30 18:46:37 +0530545static const char * const rx_echo_mux_text[] = {
546 "ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2"
547};
548
549static const struct soc_enum rx_mix_tx2_mux_enum =
550 SOC_ENUM_SINGLE(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5, 0, 4,
551 rx_echo_mux_text);
552
553static const struct snd_kcontrol_new rx_mix_tx2_mux =
554 SOC_DAPM_ENUM("RX MIX TX2_MUX Mux", rx_mix_tx2_mux_enum);
555
556static const struct soc_enum rx_mix_tx1_mux_enum =
557 SOC_ENUM_SINGLE(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, 4,
558 rx_echo_mux_text);
559
560static const struct snd_kcontrol_new rx_mix_tx1_mux =
561 SOC_DAPM_ENUM("RX MIX TX1_MUX Mux", rx_mix_tx1_mux_enum);
562
563static const struct soc_enum rx_mix_tx0_mux_enum =
564 SOC_ENUM_SINGLE(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 4, 4,
565 rx_echo_mux_text);
566
567static const struct snd_kcontrol_new rx_mix_tx0_mux =
568 SOC_DAPM_ENUM("RX MIX TX0_MUX Mux", rx_mix_tx0_mux_enum);
569
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530570static struct snd_soc_dai_ops rx_macro_dai_ops = {
571 .hw_params = rx_macro_hw_params,
572 .get_channel_map = rx_macro_get_channel_map,
573};
574
575static struct snd_soc_dai_driver rx_macro_dai[] = {
576 {
577 .name = "rx_macro_rx1",
578 .id = RX_MACRO_AIF1_PB,
579 .playback = {
580 .stream_name = "RX_MACRO_AIF1 Playback",
581 .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES,
582 .formats = RX_MACRO_FORMATS,
583 .rate_max = 384000,
584 .rate_min = 8000,
585 .channels_min = 1,
586 .channels_max = 2,
587 },
588 .ops = &rx_macro_dai_ops,
589 },
590 {
591 .name = "rx_macro_rx2",
592 .id = RX_MACRO_AIF2_PB,
593 .playback = {
594 .stream_name = "RX_MACRO_AIF2 Playback",
595 .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES,
596 .formats = RX_MACRO_FORMATS,
597 .rate_max = 384000,
598 .rate_min = 8000,
599 .channels_min = 1,
600 .channels_max = 2,
601 },
602 .ops = &rx_macro_dai_ops,
603 },
604 {
605 .name = "rx_macro_rx3",
606 .id = RX_MACRO_AIF3_PB,
607 .playback = {
608 .stream_name = "RX_MACRO_AIF3 Playback",
609 .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES,
610 .formats = RX_MACRO_FORMATS,
611 .rate_max = 384000,
612 .rate_min = 8000,
613 .channels_min = 1,
614 .channels_max = 2,
615 },
616 .ops = &rx_macro_dai_ops,
617 },
618 {
619 .name = "rx_macro_rx4",
620 .id = RX_MACRO_AIF4_PB,
621 .playback = {
622 .stream_name = "RX_MACRO_AIF4 Playback",
623 .rates = RX_MACRO_RATES | RX_MACRO_FRAC_RATES,
624 .formats = RX_MACRO_FORMATS,
625 .rate_max = 384000,
626 .rate_min = 8000,
627 .channels_min = 1,
628 .channels_max = 2,
629 },
630 .ops = &rx_macro_dai_ops,
631 },
Vatsal Buchac2d6c222018-11-30 18:46:37 +0530632 {
633 .name = "rx_macro_echo",
634 .id = RX_MACRO_AIF_ECHO,
635 .capture = {
636 .stream_name = "RX_AIF_ECHO Capture",
637 .rates = RX_MACRO_ECHO_RATES,
638 .formats = RX_MACRO_ECHO_FORMATS,
639 .rate_max = 48000,
640 .rate_min = 8000,
641 .channels_min = 1,
642 .channels_max = 3,
643 },
644 .ops = &rx_macro_dai_ops,
645 },
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530646};
647
Laxminath Kasam497a6512018-09-17 16:11:52 +0530648static int get_impedance_index(int imped)
649{
650 int i = 0;
651
652 if (imped < imped_index[i].imped_val) {
653 pr_debug("%s, detected impedance is less than %d Ohm\n",
654 __func__, imped_index[i].imped_val);
655 i = 0;
656 goto ret;
657 }
658 if (imped >= imped_index[ARRAY_SIZE(imped_index) - 1].imped_val) {
659 pr_debug("%s, detected impedance is greater than %d Ohm\n",
660 __func__,
661 imped_index[ARRAY_SIZE(imped_index) - 1].imped_val);
662 i = ARRAY_SIZE(imped_index) - 1;
663 goto ret;
664 }
665 for (i = 0; i < ARRAY_SIZE(imped_index) - 1; i++) {
666 if (imped >= imped_index[i].imped_val &&
667 imped < imped_index[i + 1].imped_val)
668 break;
669 }
670ret:
671 pr_debug("%s: selected impedance index = %d\n",
672 __func__, imped_index[i].index);
673 return imped_index[i].index;
674}
675
676/*
677 * rx_macro_wcd_clsh_imped_config -
678 * This function updates HPHL and HPHR gain settings
679 * according to the impedance value.
680 *
Meng Wang15c825d2018-09-06 10:49:18 +0800681 * @component: codec pointer handle
Laxminath Kasam497a6512018-09-17 16:11:52 +0530682 * @imped: impedance value of HPHL/R
683 * @reset: bool variable to reset registers when teardown
684 */
Meng Wang15c825d2018-09-06 10:49:18 +0800685static void rx_macro_wcd_clsh_imped_config(struct snd_soc_component *component,
Laxminath Kasam497a6512018-09-17 16:11:52 +0530686 int imped, bool reset)
687{
688 int i;
689 int index = 0;
690 int table_size;
691
692 static const struct rx_macro_reg_mask_val
693 (*imped_table_ptr)[MAX_IMPED_PARAMS];
694
695 table_size = ARRAY_SIZE(imped_table);
696 imped_table_ptr = imped_table;
697 /* reset = 1, which means request is to reset the register values */
698 if (reset) {
699 for (i = 0; i < MAX_IMPED_PARAMS; i++)
Meng Wang15c825d2018-09-06 10:49:18 +0800700 snd_soc_component_update_bits(component,
Laxminath Kasam497a6512018-09-17 16:11:52 +0530701 imped_table_ptr[index][i].reg,
702 imped_table_ptr[index][i].mask, 0);
703 return;
704 }
705 index = get_impedance_index(imped);
706 if (index >= (ARRAY_SIZE(imped_index) - 1)) {
707 pr_debug("%s, impedance not in range = %d\n", __func__, imped);
708 return;
709 }
710 if (index >= table_size) {
711 pr_debug("%s, impedance index not in range = %d\n", __func__,
712 index);
713 return;
714 }
715 for (i = 0; i < MAX_IMPED_PARAMS; i++)
Meng Wang15c825d2018-09-06 10:49:18 +0800716 snd_soc_component_update_bits(component,
Laxminath Kasam497a6512018-09-17 16:11:52 +0530717 imped_table_ptr[index][i].reg,
718 imped_table_ptr[index][i].mask,
719 imped_table_ptr[index][i].val);
720}
721
Meng Wang15c825d2018-09-06 10:49:18 +0800722static bool rx_macro_get_data(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530723 struct device **rx_dev,
724 struct rx_macro_priv **rx_priv,
725 const char *func_name)
726{
Meng Wang15c825d2018-09-06 10:49:18 +0800727 *rx_dev = bolero_get_device_ptr(component->dev, RX_MACRO);
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530728
729 if (!(*rx_dev)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800730 dev_err(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530731 "%s: null device for macro!\n", func_name);
732 return false;
733 }
734
735 *rx_priv = dev_get_drvdata((*rx_dev));
736 if (!(*rx_priv)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800737 dev_err(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530738 "%s: priv is null for macro!\n", func_name);
739 return false;
740 }
741
Meng Wang15c825d2018-09-06 10:49:18 +0800742 if (!(*rx_priv)->component) {
743 dev_err(component->dev,
Vatsal Buchac2d6c222018-11-30 18:46:37 +0530744 "%s: rx_priv component is not initialized!\n", func_name);
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530745 return false;
746 }
747
748 return true;
749}
750
Sudheer Papothia3e969d2018-10-27 06:22:10 +0530751static int rx_macro_set_port_map(struct snd_soc_component *component,
752 u32 usecase, u32 size, void *data)
753{
754 struct device *rx_dev = NULL;
755 struct rx_macro_priv *rx_priv = NULL;
756 struct swrm_port_config port_cfg;
757 int ret = 0;
758
759 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
760 return -EINVAL;
761
762 memset(&port_cfg, 0, sizeof(port_cfg));
763 port_cfg.uc = usecase;
764 port_cfg.size = size;
765 port_cfg.params = data;
766
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -0700767 if (rx_priv->swr_ctrl_data)
768 ret = swrm_wcd_notify(
769 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
770 SWR_SET_PORT_MAP, &port_cfg);
Sudheer Papothia3e969d2018-10-27 06:22:10 +0530771
772 return ret;
773}
774
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530775static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
776 struct snd_ctl_elem_value *ucontrol)
777{
778 struct snd_soc_dapm_widget *widget =
779 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +0800780 struct snd_soc_component *component =
781 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530782 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
783 unsigned int val = 0;
784 unsigned short look_ahead_dly_reg =
785 BOLERO_CDC_RX_RX0_RX_PATH_CFG0;
786
787 val = ucontrol->value.enumerated.item[0];
788 if (val >= e->items)
789 return -EINVAL;
790
Meng Wang15c825d2018-09-06 10:49:18 +0800791 dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530792 widget->name, val);
793
794 if (e->reg == BOLERO_CDC_RX_RX0_RX_PATH_CFG1)
795 look_ahead_dly_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0;
796 else if (e->reg == BOLERO_CDC_RX_RX1_RX_PATH_CFG1)
797 look_ahead_dly_reg = BOLERO_CDC_RX_RX1_RX_PATH_CFG0;
798
799 /* Set Look Ahead Delay */
Meng Wang15c825d2018-09-06 10:49:18 +0800800 snd_soc_component_update_bits(component, look_ahead_dly_reg,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530801 0x08, (val ? 0x08 : 0x00));
802 /* Set DEM INP Select */
803 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
804}
805
806static int rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
807 u8 rate_reg_val,
808 u32 sample_rate)
809{
810 u8 int_1_mix1_inp = 0;
811 u32 j = 0, port = 0;
812 u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
813 u16 int_fs_reg = 0;
814 u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
815 u8 inp0_sel = 0, inp1_sel = 0, inp2_sel = 0;
Meng Wang15c825d2018-09-06 10:49:18 +0800816 struct snd_soc_component *component = dai->component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530817 struct device *rx_dev = NULL;
818 struct rx_macro_priv *rx_priv = NULL;
819
Meng Wang15c825d2018-09-06 10:49:18 +0800820 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530821 return -EINVAL;
822
823 for_each_set_bit(port, &rx_priv->active_ch_mask[dai->id],
824 RX_MACRO_PORTS_MAX) {
825 int_1_mix1_inp = port;
826 if ((int_1_mix1_inp < RX_MACRO_RX0) ||
827 (int_1_mix1_inp > RX_MACRO_PORTS_MAX)) {
828 pr_err("%s: Invalid RX port, Dai ID is %d\n",
829 __func__, dai->id);
830 return -EINVAL;
831 }
832
833 int_mux_cfg0 = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0;
834
835 /*
836 * Loop through all interpolator MUX inputs and find out
837 * to which interpolator input, the rx port
838 * is connected
839 */
840 for (j = 0; j < INTERP_MAX; j++) {
841 int_mux_cfg1 = int_mux_cfg0 + 4;
842
Meng Wang15c825d2018-09-06 10:49:18 +0800843 int_mux_cfg0_val = snd_soc_component_read32(
844 component, int_mux_cfg0);
845 int_mux_cfg1_val = snd_soc_component_read32(
846 component, int_mux_cfg1);
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530847 inp0_sel = int_mux_cfg0_val & 0x07;
848 inp1_sel = (int_mux_cfg0_val >> 4) & 0x038;
849 inp2_sel = (int_mux_cfg1_val >> 4) & 0x038;
850 if ((inp0_sel == int_1_mix1_inp) ||
851 (inp1_sel == int_1_mix1_inp) ||
852 (inp2_sel == int_1_mix1_inp)) {
853 int_fs_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL +
854 0x80 * j;
855 pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_1\n",
856 __func__, dai->id, j);
857 pr_debug("%s: set INT%u_1 sample rate to %u\n",
858 __func__, j, sample_rate);
859 /* sample_rate is in Hz */
Meng Wang15c825d2018-09-06 10:49:18 +0800860 snd_soc_component_update_bits(component,
861 int_fs_reg,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530862 0x0F, rate_reg_val);
863 }
864 int_mux_cfg0 += 8;
865 }
866 }
867
868 return 0;
869}
870
871static int rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
872 u8 rate_reg_val,
873 u32 sample_rate)
874{
875 u8 int_2_inp = 0;
876 u32 j = 0, port = 0;
877 u16 int_mux_cfg1 = 0, int_fs_reg = 0;
878 u8 int_mux_cfg1_val = 0;
Meng Wang15c825d2018-09-06 10:49:18 +0800879 struct snd_soc_component *component = dai->component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530880 struct device *rx_dev = NULL;
881 struct rx_macro_priv *rx_priv = NULL;
882
Meng Wang15c825d2018-09-06 10:49:18 +0800883 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530884 return -EINVAL;
885
886 for_each_set_bit(port, &rx_priv->active_ch_mask[dai->id],
887 RX_MACRO_PORTS_MAX) {
888 int_2_inp = port;
889 if ((int_2_inp < RX_MACRO_RX0) ||
890 (int_2_inp > RX_MACRO_PORTS_MAX)) {
891 pr_err("%s: Invalid RX port, Dai ID is %d\n",
892 __func__, dai->id);
893 return -EINVAL;
894 }
895
896 int_mux_cfg1 = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1;
897 for (j = 0; j < INTERP_MAX; j++) {
Meng Wang15c825d2018-09-06 10:49:18 +0800898 int_mux_cfg1_val = snd_soc_component_read32(
899 component, int_mux_cfg1) &
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530900 0x07;
901 if (int_mux_cfg1_val == int_2_inp) {
902 int_fs_reg = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL +
903 0x80 * j;
904 pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_2\n",
905 __func__, dai->id, j);
906 pr_debug("%s: set INT%u_2 sample rate to %u\n",
907 __func__, j, sample_rate);
Meng Wang15c825d2018-09-06 10:49:18 +0800908 snd_soc_component_update_bits(
909 component, int_fs_reg,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530910 0x0F, rate_reg_val);
911 }
912 int_mux_cfg1 += 8;
913 }
914 }
915 return 0;
916}
917
Laxminath Kasamac396d52018-09-06 12:53:26 +0530918static bool rx_macro_is_fractional_sample_rate(u32 sample_rate)
919{
920 switch (sample_rate) {
921 case SAMPLING_RATE_44P1KHZ:
922 case SAMPLING_RATE_88P2KHZ:
923 case SAMPLING_RATE_176P4KHZ:
924 case SAMPLING_RATE_352P8KHZ:
925 return true;
926 default:
927 return false;
928 }
929 return false;
930}
931
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530932static int rx_macro_set_interpolator_rate(struct snd_soc_dai *dai,
933 u32 sample_rate)
934{
Meng Wang15c825d2018-09-06 10:49:18 +0800935 struct snd_soc_component *component = dai->component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530936 int rate_val = 0;
937 int i = 0, ret = 0;
Laxminath Kasamac396d52018-09-06 12:53:26 +0530938 struct device *rx_dev = NULL;
939 struct rx_macro_priv *rx_priv = NULL;
940
Meng Wang15c825d2018-09-06 10:49:18 +0800941 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamac396d52018-09-06 12:53:26 +0530942 return -EINVAL;
943
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530944
945 for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) {
946 if (sample_rate == sr_val_tbl[i].sample_rate) {
947 rate_val = sr_val_tbl[i].rate_val;
Laxminath Kasamac396d52018-09-06 12:53:26 +0530948 if (rx_macro_is_fractional_sample_rate(sample_rate))
949 rx_priv->is_native_on = true;
950 else
951 rx_priv->is_native_on = false;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530952 break;
953 }
954 }
955 if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) {
Meng Wang15c825d2018-09-06 10:49:18 +0800956 dev_err(component->dev, "%s: Unsupported sample rate: %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530957 __func__, sample_rate);
958 return -EINVAL;
959 }
960
961 ret = rx_macro_set_prim_interpolator_rate(dai, (u8)rate_val, sample_rate);
962 if (ret)
963 return ret;
964 ret = rx_macro_set_mix_interpolator_rate(dai, (u8)rate_val, sample_rate);
965 if (ret)
966 return ret;
967
968 return ret;
969}
970
971static int rx_macro_hw_params(struct snd_pcm_substream *substream,
972 struct snd_pcm_hw_params *params,
973 struct snd_soc_dai *dai)
974{
Meng Wang15c825d2018-09-06 10:49:18 +0800975 struct snd_soc_component *component = dai->component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530976 int ret = 0;
977 struct device *rx_dev = NULL;
978 struct rx_macro_priv *rx_priv = NULL;
979
Meng Wang15c825d2018-09-06 10:49:18 +0800980 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530981 return -EINVAL;
982
Meng Wang15c825d2018-09-06 10:49:18 +0800983 dev_dbg(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +0530984 "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
985 dai->name, dai->id, params_rate(params),
986 params_channels(params));
987
988 switch (substream->stream) {
989 case SNDRV_PCM_STREAM_PLAYBACK:
990 ret = rx_macro_set_interpolator_rate(dai, params_rate(params));
991 if (ret) {
992 pr_err("%s: cannot set sample rate: %u\n",
993 __func__, params_rate(params));
994 return ret;
995 }
996 rx_priv->bit_width[dai->id] = params_width(params);
997 break;
998 case SNDRV_PCM_STREAM_CAPTURE:
999 default:
1000 break;
1001 }
1002 return 0;
1003}
1004
1005static int rx_macro_get_channel_map(struct snd_soc_dai *dai,
1006 unsigned int *tx_num, unsigned int *tx_slot,
1007 unsigned int *rx_num, unsigned int *rx_slot)
1008{
Meng Wang15c825d2018-09-06 10:49:18 +08001009 struct snd_soc_component *component = dai->component;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301010 struct device *rx_dev = NULL;
1011 struct rx_macro_priv *rx_priv = NULL;
1012 unsigned int temp = 0, ch_mask = 0;
Vatsal Buchac2d6c222018-11-30 18:46:37 +05301013 u16 val = 0, mask = 0, cnt = 0, i = 0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301014
Meng Wang15c825d2018-09-06 10:49:18 +08001015 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301016 return -EINVAL;
1017
1018 switch (dai->id) {
1019 case RX_MACRO_AIF1_PB:
1020 case RX_MACRO_AIF2_PB:
1021 case RX_MACRO_AIF3_PB:
1022 case RX_MACRO_AIF4_PB:
1023 for_each_set_bit(temp, &rx_priv->active_ch_mask[dai->id],
1024 RX_MACRO_PORTS_MAX) {
Vatsal Bucha1a96a612018-11-26 13:04:56 +05301025 ch_mask |= (1 << temp);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301026 if (++i == RX_MACRO_MAX_DMA_CH_PER_PORT)
1027 break;
1028 }
1029 *rx_slot = ch_mask;
1030 *rx_num = rx_priv->active_ch_cnt[dai->id];
1031 break;
Vatsal Buchac2d6c222018-11-30 18:46:37 +05301032 case RX_MACRO_AIF_ECHO:
1033 val = snd_soc_component_read32(component,
1034 BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4);
1035 if (val & RX_MACRO_EC_MIX_TX0_MASK) {
1036 mask |= 0x1;
1037 cnt++;
1038 }
1039 if (val & RX_MACRO_EC_MIX_TX1_MASK) {
1040 mask |= 0x2;
1041 cnt++;
1042 }
1043 val = snd_soc_component_read32(component,
1044 BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5);
1045 if (val & RX_MACRO_EC_MIX_TX2_MASK) {
1046 mask |= 0x4;
1047 cnt++;
1048 }
1049 *tx_slot = mask;
1050 *tx_num = cnt;
1051 break;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301052 default:
1053 dev_err(rx_dev, "%s: Invalid AIF\n", __func__);
1054 break;
1055 }
1056 return 0;
1057}
1058
1059static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv,
1060 bool mclk_enable, bool dapm)
1061{
1062 struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001063 int ret = 0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301064
Tanya Dixit8530fb92018-09-14 16:01:25 +05301065 if (regmap == NULL) {
1066 dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__);
1067 return -EINVAL;
1068 }
1069
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301070 dev_dbg(rx_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
1071 __func__, mclk_enable, dapm, rx_priv->rx_mclk_users);
1072
1073 mutex_lock(&rx_priv->mclk_lock);
1074 if (mclk_enable) {
1075 if (rx_priv->rx_mclk_users == 0) {
Laxminath Kasam7b9cdb62018-09-28 16:28:54 +05301076 if (rx_priv->is_native_on)
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001077 rx_priv->clk_id = RX_CORE_CLK;
1078 ret = bolero_clk_rsc_request_clock(rx_priv->dev,
1079 rx_priv->default_clk_id,
1080 rx_priv->clk_id,
1081 true);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301082 if (ret < 0) {
1083 dev_err(rx_priv->dev,
1084 "%s: rx request clock enable failed\n",
1085 __func__);
1086 goto exit;
1087 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001088 bolero_clk_rsc_fs_gen_request(rx_priv->dev,
1089 true);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301090 regcache_mark_dirty(regmap);
1091 regcache_sync_region(regmap,
1092 RX_START_OFFSET,
1093 RX_MAX_OFFSET);
1094 regmap_update_bits(regmap,
1095 BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL,
1096 0x01, 0x01);
1097 regmap_update_bits(regmap,
Ramprasad Katkam9c2394a2018-08-23 13:13:48 +05301098 BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL,
1099 0x02, 0x02);
1100 regmap_update_bits(regmap,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301101 BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
1102 0x01, 0x01);
1103 }
1104 rx_priv->rx_mclk_users++;
1105 } else {
1106 if (rx_priv->rx_mclk_users <= 0) {
1107 dev_err(rx_priv->dev, "%s: clock already disabled\n",
1108 __func__);
1109 rx_priv->rx_mclk_users = 0;
1110 goto exit;
1111 }
1112 rx_priv->rx_mclk_users--;
1113 if (rx_priv->rx_mclk_users == 0) {
1114 regmap_update_bits(regmap,
1115 BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
1116 0x01, 0x00);
1117 regmap_update_bits(regmap,
1118 BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL,
1119 0x01, 0x00);
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001120 bolero_clk_rsc_fs_gen_request(rx_priv->dev,
1121 false);
1122 bolero_clk_rsc_request_clock(rx_priv->dev,
1123 rx_priv->default_clk_id,
1124 rx_priv->clk_id,
1125 false);
1126 rx_priv->clk_id = rx_priv->default_clk_id;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301127 }
1128 }
1129exit:
1130 mutex_unlock(&rx_priv->mclk_lock);
1131 return ret;
1132}
1133
1134static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w,
1135 struct snd_kcontrol *kcontrol, int event)
1136{
Meng Wang15c825d2018-09-06 10:49:18 +08001137 struct snd_soc_component *component =
1138 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301139 int ret = 0;
1140 struct device *rx_dev = NULL;
1141 struct rx_macro_priv *rx_priv = NULL;
Laxminath Kasamac396d52018-09-06 12:53:26 +05301142 int mclk_freq = MCLK_FREQ;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301143
Meng Wang15c825d2018-09-06 10:49:18 +08001144 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301145 return -EINVAL;
1146
1147 dev_dbg(rx_dev, "%s: event = %d\n", __func__, event);
1148 switch (event) {
1149 case SND_SOC_DAPM_PRE_PMU:
Laxminath Kasambee08192018-07-01 14:38:55 +05301150 /* if swr_clk_users > 0, call device down */
1151 if (rx_priv->swr_clk_users > 0) {
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001152 if ((rx_priv->clk_id == rx_priv->default_clk_id &&
Laxminath Kasambee08192018-07-01 14:38:55 +05301153 rx_priv->is_native_on) ||
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001154 (rx_priv->clk_id == RX_CORE_CLK &&
Laxminath Kasambee08192018-07-01 14:38:55 +05301155 !rx_priv->is_native_on)) {
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001156 if (rx_priv->swr_ctrl_data)
1157 swrm_wcd_notify(
1158 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
1159 SWR_DEVICE_DOWN, NULL);
Laxminath Kasambee08192018-07-01 14:38:55 +05301160 }
1161 }
Laxminath Kasamac396d52018-09-06 12:53:26 +05301162 if (rx_priv->is_native_on)
1163 mclk_freq = MCLK_FREQ_NATIVE;
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001164 if (rx_priv->swr_ctrl_data)
1165 swrm_wcd_notify(
1166 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
1167 SWR_CLK_FREQ, &mclk_freq);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301168 ret = rx_macro_mclk_enable(rx_priv, 1, true);
Ramprasad Katkam452772a2019-01-07 17:30:36 +05301169 if (ret)
1170 rx_priv->dapm_mclk_enable = false;
1171 else
1172 rx_priv->dapm_mclk_enable = true;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301173 break;
1174 case SND_SOC_DAPM_POST_PMD:
Ramprasad Katkam452772a2019-01-07 17:30:36 +05301175 if (rx_priv->dapm_mclk_enable)
1176 ret = rx_macro_mclk_enable(rx_priv, 0, true);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301177 break;
1178 default:
1179 dev_err(rx_priv->dev,
1180 "%s: invalid DAPM event %d\n", __func__, event);
1181 ret = -EINVAL;
1182 }
1183 return ret;
1184}
1185
Meng Wang15c825d2018-09-06 10:49:18 +08001186static int rx_macro_event_handler(struct snd_soc_component *component,
1187 u16 event, u32 data)
Laxminath Kasam497a6512018-09-17 16:11:52 +05301188{
Vatsal Bucha53b4e142018-11-13 19:36:25 +05301189 u16 reg = 0, reg_mix = 0, rx_idx = 0, mute = 0x0, val = 0;
Laxminath Kasam497a6512018-09-17 16:11:52 +05301190 struct device *rx_dev = NULL;
1191 struct rx_macro_priv *rx_priv = NULL;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001192 int ret = 0;
Laxminath Kasam497a6512018-09-17 16:11:52 +05301193
Meng Wang15c825d2018-09-06 10:49:18 +08001194 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasam497a6512018-09-17 16:11:52 +05301195 return -EINVAL;
1196
1197 switch (event) {
1198 case BOLERO_MACRO_EVT_RX_MUTE:
1199 rx_idx = data >> 0x10;
1200 mute = data & 0xffff;
Vatsal Bucha53b4e142018-11-13 19:36:25 +05301201 val = mute ? 0x10 : 0x00;
Laxminath Kasam497a6512018-09-17 16:11:52 +05301202 reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + (rx_idx *
1203 RX_MACRO_RX_PATH_OFFSET);
1204 reg_mix = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL + (rx_idx *
1205 RX_MACRO_RX_PATH_OFFSET);
Meng Wang15c825d2018-09-06 10:49:18 +08001206 snd_soc_component_update_bits(component, reg,
1207 0x10, val);
1208 snd_soc_component_update_bits(component, reg_mix,
1209 0x10, val);
Laxminath Kasam497a6512018-09-17 16:11:52 +05301210 break;
1211 case BOLERO_MACRO_EVT_IMPED_TRUE:
Meng Wang15c825d2018-09-06 10:49:18 +08001212 rx_macro_wcd_clsh_imped_config(component, data, true);
Laxminath Kasam497a6512018-09-17 16:11:52 +05301213 break;
1214 case BOLERO_MACRO_EVT_IMPED_FALSE:
Meng Wang15c825d2018-09-06 10:49:18 +08001215 rx_macro_wcd_clsh_imped_config(component, data, false);
Laxminath Kasam497a6512018-09-17 16:11:52 +05301216 break;
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301217 case BOLERO_MACRO_EVT_SSR_DOWN:
Laxminath Kasam701e3582018-10-15 20:06:09 +05301218 rx_priv->dev_up = false;
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001219 if (rx_priv->swr_ctrl_data) {
1220 swrm_wcd_notify(
1221 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
1222 SWR_DEVICE_DOWN, NULL);
1223 swrm_wcd_notify(
1224 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
1225 SWR_DEVICE_SSR_DOWN, NULL);
1226 }
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301227 break;
1228 case BOLERO_MACRO_EVT_SSR_UP:
Laxminath Kasam701e3582018-10-15 20:06:09 +05301229 rx_priv->dev_up = true;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05301230 /* reset swr after ssr/pdr */
1231 rx_priv->reset_swr = true;
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001232 /* enable&disable RX_CORE_CLK to reset GFMUX reg */
1233 ret = bolero_clk_rsc_request_clock(rx_priv->dev,
1234 rx_priv->default_clk_id,
1235 RX_CORE_CLK, true);
1236 if (ret < 0)
1237 dev_err_ratelimited(rx_priv->dev,
1238 "%s, failed to enable clk, ret:%d\n",
1239 __func__, ret);
1240 else
1241 bolero_clk_rsc_request_clock(rx_priv->dev,
1242 rx_priv->default_clk_id,
1243 RX_CORE_CLK, false);
1244
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07001245 if (rx_priv->swr_ctrl_data)
1246 swrm_wcd_notify(
1247 rx_priv->swr_ctrl_data[0].rx_swr_pdev,
1248 SWR_DEVICE_SSR_UP, NULL);
Laxminath Kasamfb0d6832018-09-22 01:49:52 +05301249 break;
Laxminath Kasam497a6512018-09-17 16:11:52 +05301250 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07001251 return ret;
Laxminath Kasam497a6512018-09-17 16:11:52 +05301252}
1253
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301254static int rx_macro_find_playback_dai_id_for_port(int port_id,
1255 struct rx_macro_priv *rx_priv)
1256{
1257 int i = 0;
1258
1259 for (i = RX_MACRO_AIF1_PB; i < RX_MACRO_MAX_DAIS; i++) {
1260 if (test_bit(port_id, &rx_priv->active_ch_mask[i]))
1261 return i;
1262 }
1263
1264 return -EINVAL;
1265}
1266
Meng Wang15c825d2018-09-06 10:49:18 +08001267static int rx_macro_set_idle_detect_thr(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301268 struct rx_macro_priv *rx_priv,
1269 int interp, int path_type)
1270{
1271 int port_id[4] = { 0, 0, 0, 0 };
Laxminath Kasamb7f823c2018-08-02 13:23:11 +05301272 int *port_ptr = NULL;
1273 int num_ports = 0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301274 int bit_width = 0, i = 0;
1275 int mux_reg = 0, mux_reg_val = 0;
1276 int dai_id = 0, idle_thr = 0;
1277
1278 if ((interp != INTERP_HPHL) && (interp != INTERP_HPHR))
1279 return 0;
1280
1281 if (!rx_priv->idle_det_cfg.hph_idle_detect_en)
1282 return 0;
1283
1284 port_ptr = &port_id[0];
1285 num_ports = 0;
1286
1287 /*
1288 * Read interpolator MUX input registers and find
1289 * which cdc_dma port is connected and store the port
1290 * numbers in port_id array.
1291 */
1292 if (path_type == INTERP_MIX_PATH) {
1293 mux_reg = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1 +
1294 2 * interp;
Meng Wang15c825d2018-09-06 10:49:18 +08001295 mux_reg_val = snd_soc_component_read32(component, mux_reg) &
1296 0x0f;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301297
1298 if ((mux_reg_val >= INTn_2_INP_SEL_RX0) &&
1299 (mux_reg_val <= INTn_2_INP_SEL_RX5)) {
1300 *port_ptr++ = mux_reg_val - 1;
1301 num_ports++;
1302 }
1303 }
1304
1305 if (path_type == INTERP_MAIN_PATH) {
1306 mux_reg = BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0 +
1307 2 * (interp - 1);
Meng Wang15c825d2018-09-06 10:49:18 +08001308 mux_reg_val = snd_soc_component_read32(component, mux_reg) &
1309 0x0f;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301310 i = RX_MACRO_INTERP_MUX_NUM_INPUTS;
1311
1312 while (i) {
1313 if ((mux_reg_val >= INTn_1_INP_SEL_RX0) &&
1314 (mux_reg_val <= INTn_1_INP_SEL_RX5)) {
1315 *port_ptr++ = mux_reg_val -
1316 INTn_1_INP_SEL_RX0;
1317 num_ports++;
1318 }
Meng Wang15c825d2018-09-06 10:49:18 +08001319 mux_reg_val =
1320 (snd_soc_component_read32(component, mux_reg) &
1321 0xf0) >> 4;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301322 mux_reg += 1;
1323 i--;
1324 }
1325 }
1326
Meng Wang15c825d2018-09-06 10:49:18 +08001327 dev_dbg(component->dev, "%s: num_ports: %d, ports[%d %d %d %d]\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301328 __func__, num_ports, port_id[0], port_id[1],
1329 port_id[2], port_id[3]);
1330
1331 i = 0;
1332 while (num_ports) {
1333 dai_id = rx_macro_find_playback_dai_id_for_port(port_id[i++],
1334 rx_priv);
1335
1336 if ((dai_id >= 0) && (dai_id < RX_MACRO_MAX_DAIS)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001337 dev_dbg(component->dev, "%s: dai_id: %d bit_width: %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301338 __func__, dai_id,
1339 rx_priv->bit_width[dai_id]);
1340
1341 if (rx_priv->bit_width[dai_id] > bit_width)
1342 bit_width = rx_priv->bit_width[dai_id];
1343 }
1344 num_ports--;
1345 }
1346
1347 switch (bit_width) {
1348 case 16:
1349 idle_thr = 0xff; /* F16 */
1350 break;
1351 case 24:
1352 case 32:
1353 idle_thr = 0x03; /* F22 */
1354 break;
1355 default:
1356 idle_thr = 0x00;
1357 break;
1358 }
1359
Meng Wang15c825d2018-09-06 10:49:18 +08001360 dev_dbg(component->dev, "%s: (new) idle_thr: %d, (cur) idle_thr: %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301361 __func__, idle_thr, rx_priv->idle_det_cfg.hph_idle_thr);
1362
1363 if ((rx_priv->idle_det_cfg.hph_idle_thr == 0) ||
1364 (idle_thr < rx_priv->idle_det_cfg.hph_idle_thr)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001365 snd_soc_component_write(component,
1366 BOLERO_CDC_RX_IDLE_DETECT_CFG3, idle_thr);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301367 rx_priv->idle_det_cfg.hph_idle_thr = idle_thr;
1368 }
1369
1370 return 0;
1371}
1372
1373static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
1374 struct snd_kcontrol *kcontrol, int event)
1375{
Meng Wang15c825d2018-09-06 10:49:18 +08001376 struct snd_soc_component *component =
1377 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301378 u16 gain_reg = 0, mix_reg = 0;
1379 struct device *rx_dev = NULL;
1380 struct rx_macro_priv *rx_priv = NULL;
1381
Meng Wang15c825d2018-09-06 10:49:18 +08001382 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301383 return -EINVAL;
1384
1385 if (w->shift >= INTERP_MAX) {
Meng Wang15c825d2018-09-06 10:49:18 +08001386 dev_err(component->dev, "%s: Invalid Interpolator value %d for name %s\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301387 __func__, w->shift, w->name);
1388 return -EINVAL;
1389 }
1390
1391 gain_reg = BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL +
1392 (w->shift * RX_MACRO_RX_PATH_OFFSET);
1393 mix_reg = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL +
1394 (w->shift * RX_MACRO_RX_PATH_OFFSET);
1395
Meng Wang15c825d2018-09-06 10:49:18 +08001396 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301397
1398 switch (event) {
1399 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001400 rx_macro_set_idle_detect_thr(component, rx_priv, w->shift,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301401 INTERP_MIX_PATH);
Meng Wang15c825d2018-09-06 10:49:18 +08001402 rx_macro_enable_interp_clk(component, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301403 /* Clk enable */
Meng Wang15c825d2018-09-06 10:49:18 +08001404 snd_soc_component_update_bits(component, mix_reg, 0x20, 0x20);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301405 break;
1406 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001407 snd_soc_component_write(component, gain_reg,
1408 snd_soc_component_read32(component, gain_reg));
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301409 break;
1410 case SND_SOC_DAPM_POST_PMD:
1411 /* Clk Disable */
Meng Wang15c825d2018-09-06 10:49:18 +08001412 snd_soc_component_update_bits(component, mix_reg, 0x20, 0x00);
1413 rx_macro_enable_interp_clk(component, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301414 /* Reset enable and disable */
Meng Wang15c825d2018-09-06 10:49:18 +08001415 snd_soc_component_update_bits(component, mix_reg, 0x40, 0x40);
1416 snd_soc_component_update_bits(component, mix_reg, 0x40, 0x00);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301417 break;
1418 }
1419
1420 return 0;
1421}
1422
1423static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w,
1424 struct snd_kcontrol *kcontrol,
1425 int event)
1426{
Meng Wang15c825d2018-09-06 10:49:18 +08001427 struct snd_soc_component *component =
1428 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301429 u16 gain_reg = 0;
1430 u16 reg = 0;
1431 struct device *rx_dev = NULL;
1432 struct rx_macro_priv *rx_priv = NULL;
1433
Meng Wang15c825d2018-09-06 10:49:18 +08001434 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301435 return -EINVAL;
1436
Meng Wang15c825d2018-09-06 10:49:18 +08001437 dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301438
1439 if (w->shift >= INTERP_MAX) {
Meng Wang15c825d2018-09-06 10:49:18 +08001440 dev_err(component->dev, "%s: Invalid Interpolator value %d for name %s\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301441 __func__, w->shift, w->name);
1442 return -EINVAL;
1443 }
1444
1445 reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + (w->shift *
1446 RX_MACRO_RX_PATH_OFFSET);
1447 gain_reg = BOLERO_CDC_RX_RX0_RX_VOL_CTL + (w->shift *
1448 RX_MACRO_RX_PATH_OFFSET);
1449
1450 switch (event) {
1451 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001452 rx_macro_set_idle_detect_thr(component, rx_priv, w->shift,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301453 INTERP_MAIN_PATH);
Meng Wang15c825d2018-09-06 10:49:18 +08001454 rx_macro_enable_interp_clk(component, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301455 break;
1456 case SND_SOC_DAPM_POST_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08001457 snd_soc_component_write(component, gain_reg,
1458 snd_soc_component_read32(component, gain_reg));
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301459 break;
1460 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08001461 rx_macro_enable_interp_clk(component, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301462 break;
1463 }
1464
1465 return 0;
1466}
1467
Meng Wang15c825d2018-09-06 10:49:18 +08001468static int rx_macro_config_compander(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301469 struct rx_macro_priv *rx_priv,
1470 int interp_n, int event)
1471{
1472 int comp = 0;
1473 u16 comp_ctl0_reg = 0, rx_path_cfg0_reg = 0;
1474
1475 /* AUX does not have compander */
1476 if (interp_n == INTERP_AUX)
1477 return 0;
1478
1479 comp = interp_n;
Meng Wang15c825d2018-09-06 10:49:18 +08001480 dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301481 __func__, event, comp + 1, rx_priv->comp_enabled[comp]);
1482
1483 if (!rx_priv->comp_enabled[comp])
1484 return 0;
1485
1486 comp_ctl0_reg = BOLERO_CDC_RX_COMPANDER0_CTL0 +
1487 (comp * RX_MACRO_COMP_OFFSET);
1488 rx_path_cfg0_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0 +
1489 (comp * RX_MACRO_RX_PATH_OFFSET);
1490
1491 if (SND_SOC_DAPM_EVENT_ON(event)) {
1492 /* Enable Compander Clock */
Meng Wang15c825d2018-09-06 10:49:18 +08001493 snd_soc_component_update_bits(component, comp_ctl0_reg,
1494 0x01, 0x01);
1495 snd_soc_component_update_bits(component, comp_ctl0_reg,
1496 0x02, 0x02);
1497 snd_soc_component_update_bits(component, comp_ctl0_reg,
1498 0x02, 0x00);
1499 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1500 0x02, 0x02);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301501 }
1502
1503 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001504 snd_soc_component_update_bits(component, comp_ctl0_reg,
1505 0x04, 0x04);
1506 snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1507 0x02, 0x00);
1508 snd_soc_component_update_bits(component, comp_ctl0_reg,
1509 0x01, 0x00);
1510 snd_soc_component_update_bits(component, comp_ctl0_reg,
1511 0x04, 0x00);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301512 }
1513
1514 return 0;
1515}
1516
Meng Wang15c825d2018-09-06 10:49:18 +08001517static void rx_macro_enable_softclip_clk(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301518 struct rx_macro_priv *rx_priv,
1519 bool enable)
1520{
1521 if (enable) {
1522 if (rx_priv->softclip_clk_users == 0)
Meng Wang15c825d2018-09-06 10:49:18 +08001523 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301524 BOLERO_CDC_RX_SOFTCLIP_CRC,
1525 0x01, 0x01);
1526 rx_priv->softclip_clk_users++;
1527 } else {
1528 rx_priv->softclip_clk_users--;
1529 if (rx_priv->softclip_clk_users == 0)
Meng Wang15c825d2018-09-06 10:49:18 +08001530 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301531 BOLERO_CDC_RX_SOFTCLIP_CRC,
1532 0x01, 0x00);
1533 }
1534}
1535
Meng Wang15c825d2018-09-06 10:49:18 +08001536static int rx_macro_config_softclip(struct snd_soc_component *component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301537 struct rx_macro_priv *rx_priv,
1538 int event)
1539{
Meng Wang15c825d2018-09-06 10:49:18 +08001540 dev_dbg(component->dev, "%s: event %d, enabled %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301541 __func__, event, rx_priv->is_softclip_on);
1542
1543 if (!rx_priv->is_softclip_on)
1544 return 0;
1545
1546 if (SND_SOC_DAPM_EVENT_ON(event)) {
1547 /* Enable Softclip clock */
Meng Wang15c825d2018-09-06 10:49:18 +08001548 rx_macro_enable_softclip_clk(component, rx_priv, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301549 /* Enable Softclip control */
Meng Wang15c825d2018-09-06 10:49:18 +08001550 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301551 BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x01, 0x01);
1552 }
1553
1554 if (SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001555 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301556 BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001557 rx_macro_enable_softclip_clk(component, rx_priv, false);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301558 }
1559
1560 return 0;
1561}
1562
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301563static inline void
1564rx_macro_enable_clsh_block(struct rx_macro_priv *rx_priv, bool enable)
1565{
1566 if ((enable && ++rx_priv->clsh_users == 1) ||
1567 (!enable && --rx_priv->clsh_users == 0))
Meng Wang15c825d2018-09-06 10:49:18 +08001568 snd_soc_component_update_bits(rx_priv->component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301569 BOLERO_CDC_RX_CLSH_CRC, 0x01,
1570 (u8) enable);
1571 if (rx_priv->clsh_users < 0)
1572 rx_priv->clsh_users = 0;
1573 dev_dbg(rx_priv->dev, "%s: clsh_users %d, enable %d", __func__,
1574 rx_priv->clsh_users, enable);
1575}
1576
Meng Wang15c825d2018-09-06 10:49:18 +08001577static int rx_macro_config_classh(struct snd_soc_component *component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301578 struct rx_macro_priv *rx_priv,
1579 int interp_n, int event)
1580{
1581 if (SND_SOC_DAPM_EVENT_OFF(event)) {
1582 rx_macro_enable_clsh_block(rx_priv, false);
1583 return 0;
1584 }
1585
1586 if (!SND_SOC_DAPM_EVENT_ON(event))
1587 return 0;
1588
1589 rx_macro_enable_clsh_block(rx_priv, true);
1590 if (interp_n == INTERP_HPHL ||
1591 interp_n == INTERP_HPHR) {
1592 /*
1593 * These K1 values depend on the Headphone Impedance
1594 * For now it is assumed to be 16 ohm
1595 */
Meng Wang15c825d2018-09-06 10:49:18 +08001596 snd_soc_component_update_bits(component,
1597 BOLERO_CDC_RX_CLSH_K1_LSB,
1598 0xFF, 0xC0);
1599 snd_soc_component_update_bits(component,
1600 BOLERO_CDC_RX_CLSH_K1_MSB,
1601 0x0F, 0x00);
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301602 }
1603 switch (interp_n) {
1604 case INTERP_HPHL:
1605 if (rx_priv->is_ear_mode_on)
Meng Wang15c825d2018-09-06 10:49:18 +08001606 snd_soc_component_update_bits(component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301607 BOLERO_CDC_RX_CLSH_HPH_V_PA,
1608 0x3F, 0x39);
1609 else
Meng Wang15c825d2018-09-06 10:49:18 +08001610 snd_soc_component_update_bits(component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301611 BOLERO_CDC_RX_CLSH_HPH_V_PA,
1612 0x3F, 0x1C);
Meng Wang15c825d2018-09-06 10:49:18 +08001613 snd_soc_component_update_bits(component,
1614 BOLERO_CDC_RX_CLSH_DECAY_CTRL,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301615 0x07, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001616 snd_soc_component_update_bits(component,
1617 BOLERO_CDC_RX_RX0_RX_PATH_CFG0,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301618 0x40, 0x40);
1619 break;
1620 case INTERP_HPHR:
Meng Wang15c825d2018-09-06 10:49:18 +08001621 snd_soc_component_update_bits(component,
1622 BOLERO_CDC_RX_CLSH_HPH_V_PA,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301623 0x3F, 0x1C);
Meng Wang15c825d2018-09-06 10:49:18 +08001624 snd_soc_component_update_bits(component,
1625 BOLERO_CDC_RX_CLSH_DECAY_CTRL,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301626 0x07, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08001627 snd_soc_component_update_bits(component,
1628 BOLERO_CDC_RX_RX1_RX_PATH_CFG0,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301629 0x40, 0x40);
1630 break;
1631 case INTERP_AUX:
Meng Wang15c825d2018-09-06 10:49:18 +08001632 snd_soc_component_update_bits(component,
1633 BOLERO_CDC_RX_RX2_RX_PATH_CFG0,
Laxminath Kasam1a4dd6d2019-04-02 15:21:54 +05301634 0x08, 0x08);
1635 snd_soc_component_update_bits(component,
1636 BOLERO_CDC_RX_RX2_RX_PATH_CFG0,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301637 0x10, 0x10);
1638 break;
1639 }
1640
1641 return 0;
1642}
1643
Meng Wang15c825d2018-09-06 10:49:18 +08001644static void rx_macro_hd2_control(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301645 u16 interp_idx, int event)
1646{
1647 u16 hd2_scale_reg = 0;
1648 u16 hd2_enable_reg = 0;
1649
1650 switch (interp_idx) {
1651 case INTERP_HPHL:
Laxminath Kasam7adc34e2018-11-09 11:24:38 +05301652 hd2_scale_reg = BOLERO_CDC_RX_RX0_RX_PATH_SEC3;
1653 hd2_enable_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301654 break;
1655 case INTERP_HPHR:
Laxminath Kasam7adc34e2018-11-09 11:24:38 +05301656 hd2_scale_reg = BOLERO_CDC_RX_RX1_RX_PATH_SEC3;
1657 hd2_enable_reg = BOLERO_CDC_RX_RX1_RX_PATH_CFG0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301658 break;
1659 }
1660
1661 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001662 snd_soc_component_update_bits(component, hd2_scale_reg,
1663 0x3C, 0x14);
1664 snd_soc_component_update_bits(component, hd2_enable_reg,
1665 0x04, 0x04);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301666 }
1667
1668 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08001669 snd_soc_component_update_bits(component, hd2_enable_reg,
1670 0x04, 0x00);
1671 snd_soc_component_update_bits(component, hd2_scale_reg,
1672 0x3C, 0x00);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301673 }
1674}
1675
Vatsal Bucha8bcc97c2019-01-07 13:18:11 +05301676static int rx_macro_hph_idle_detect_get(struct snd_kcontrol *kcontrol,
1677 struct snd_ctl_elem_value *ucontrol)
1678{
1679 struct snd_soc_component *component =
1680 snd_soc_kcontrol_component(kcontrol);
1681 struct rx_macro_priv *rx_priv = NULL;
1682 struct device *rx_dev = NULL;
1683
1684 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
1685 return -EINVAL;
1686
1687 ucontrol->value.integer.value[0] =
1688 rx_priv->idle_det_cfg.hph_idle_detect_en;
1689
1690 return 0;
1691}
1692
1693static int rx_macro_hph_idle_detect_put(struct snd_kcontrol *kcontrol,
1694 struct snd_ctl_elem_value *ucontrol)
1695{
1696 struct snd_soc_component *component =
1697 snd_soc_kcontrol_component(kcontrol);
1698 struct rx_macro_priv *rx_priv = NULL;
1699 struct device *rx_dev = NULL;
1700
1701 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
1702 return -EINVAL;
1703
1704 rx_priv->idle_det_cfg.hph_idle_detect_en =
1705 ucontrol->value.integer.value[0];
1706
1707 return 0;
1708}
1709
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301710static int rx_macro_get_compander(struct snd_kcontrol *kcontrol,
1711 struct snd_ctl_elem_value *ucontrol)
1712{
Meng Wang15c825d2018-09-06 10:49:18 +08001713 struct snd_soc_component *component =
1714 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301715 int comp = ((struct soc_multi_mixer_control *)
1716 kcontrol->private_value)->shift;
1717 struct device *rx_dev = NULL;
1718 struct rx_macro_priv *rx_priv = NULL;
1719
Meng Wang15c825d2018-09-06 10:49:18 +08001720 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301721 return -EINVAL;
1722
1723 ucontrol->value.integer.value[0] = rx_priv->comp_enabled[comp];
1724 return 0;
1725}
1726
1727static int rx_macro_set_compander(struct snd_kcontrol *kcontrol,
1728 struct snd_ctl_elem_value *ucontrol)
1729{
Meng Wang15c825d2018-09-06 10:49:18 +08001730 struct snd_soc_component *component =
1731 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301732 int comp = ((struct soc_multi_mixer_control *)
1733 kcontrol->private_value)->shift;
1734 int value = ucontrol->value.integer.value[0];
1735 struct device *rx_dev = NULL;
1736 struct rx_macro_priv *rx_priv = NULL;
1737
Meng Wang15c825d2018-09-06 10:49:18 +08001738 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301739 return -EINVAL;
1740
Meng Wang15c825d2018-09-06 10:49:18 +08001741 dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301742 __func__, comp + 1, rx_priv->comp_enabled[comp], value);
1743 rx_priv->comp_enabled[comp] = value;
1744
1745 return 0;
1746}
1747
1748static int rx_macro_mux_get(struct snd_kcontrol *kcontrol,
1749 struct snd_ctl_elem_value *ucontrol)
1750{
1751 struct snd_soc_dapm_widget *widget =
1752 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08001753 struct snd_soc_component *component =
1754 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301755 struct device *rx_dev = NULL;
1756 struct rx_macro_priv *rx_priv = NULL;
1757
Meng Wang15c825d2018-09-06 10:49:18 +08001758 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301759 return -EINVAL;
1760
1761 ucontrol->value.integer.value[0] =
1762 rx_priv->rx_port_value[widget->shift];
1763 return 0;
1764}
1765
1766static int rx_macro_mux_put(struct snd_kcontrol *kcontrol,
1767 struct snd_ctl_elem_value *ucontrol)
1768{
1769 struct snd_soc_dapm_widget *widget =
1770 snd_soc_dapm_kcontrol_widget(kcontrol);
Meng Wang15c825d2018-09-06 10:49:18 +08001771 struct snd_soc_component *component =
1772 snd_soc_dapm_to_component(widget->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301773 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1774 struct snd_soc_dapm_update *update = NULL;
1775 u32 rx_port_value = ucontrol->value.integer.value[0];
1776 u32 aif_rst = 0;
1777 struct device *rx_dev = NULL;
1778 struct rx_macro_priv *rx_priv = NULL;
1779
Meng Wang15c825d2018-09-06 10:49:18 +08001780 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301781 return -EINVAL;
1782
1783 aif_rst = rx_priv->rx_port_value[widget->shift];
1784 if (!rx_port_value) {
1785 if (aif_rst == 0) {
1786 dev_err(rx_dev, "%s:AIF reset already\n", __func__);
1787 return 0;
1788 }
1789 }
1790 rx_priv->rx_port_value[widget->shift] = rx_port_value;
1791
1792 switch (rx_port_value) {
1793 case 0:
1794 clear_bit(widget->shift,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05301795 &rx_priv->active_ch_mask[aif_rst]);
1796 rx_priv->active_ch_cnt[aif_rst]--;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301797 break;
1798 case 1:
1799 case 2:
1800 case 3:
1801 case 4:
1802 set_bit(widget->shift,
Laxminath Kasam59c7a1d2018-08-09 16:11:17 +05301803 &rx_priv->active_ch_mask[rx_port_value]);
1804 rx_priv->active_ch_cnt[rx_port_value]++;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301805 break;
1806 default:
Meng Wang15c825d2018-09-06 10:49:18 +08001807 dev_err(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05301808 "%s:Invalid AIF_ID for RX_MACRO MUX\n", __func__);
1809 goto err;
1810 }
1811
1812 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
1813 rx_port_value, e, update);
1814 return 0;
1815err:
1816 return -EINVAL;
1817}
1818
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301819static int rx_macro_get_ear_mode(struct snd_kcontrol *kcontrol,
1820 struct snd_ctl_elem_value *ucontrol)
1821{
Meng Wang15c825d2018-09-06 10:49:18 +08001822 struct snd_soc_component *component =
1823 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301824 struct device *rx_dev = NULL;
1825 struct rx_macro_priv *rx_priv = NULL;
1826
Meng Wang15c825d2018-09-06 10:49:18 +08001827 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301828 return -EINVAL;
1829
1830 ucontrol->value.integer.value[0] = rx_priv->is_ear_mode_on;
1831 return 0;
1832}
1833
1834static int rx_macro_put_ear_mode(struct snd_kcontrol *kcontrol,
1835 struct snd_ctl_elem_value *ucontrol)
1836{
Meng Wang15c825d2018-09-06 10:49:18 +08001837 struct snd_soc_component *component =
1838 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301839 struct device *rx_dev = NULL;
1840 struct rx_macro_priv *rx_priv = NULL;
1841
Meng Wang15c825d2018-09-06 10:49:18 +08001842 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05301843 return -EINVAL;
1844
1845 rx_priv->is_ear_mode_on =
1846 (!ucontrol->value.integer.value[0] ? false : true);
1847 return 0;
1848}
1849
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05301850static int rx_macro_get_hph_hd2_mode(struct snd_kcontrol *kcontrol,
1851 struct snd_ctl_elem_value *ucontrol)
1852{
Meng Wang15c825d2018-09-06 10:49:18 +08001853 struct snd_soc_component *component =
1854 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05301855 struct device *rx_dev = NULL;
1856 struct rx_macro_priv *rx_priv = NULL;
1857
Meng Wang15c825d2018-09-06 10:49:18 +08001858 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05301859 return -EINVAL;
1860
1861 ucontrol->value.integer.value[0] = rx_priv->hph_hd2_mode;
1862 return 0;
1863}
1864
1865static int rx_macro_put_hph_hd2_mode(struct snd_kcontrol *kcontrol,
1866 struct snd_ctl_elem_value *ucontrol)
1867{
Meng Wang15c825d2018-09-06 10:49:18 +08001868 struct snd_soc_component *component =
1869 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05301870 struct device *rx_dev = NULL;
1871 struct rx_macro_priv *rx_priv = NULL;
1872
Meng Wang15c825d2018-09-06 10:49:18 +08001873 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05301874 return -EINVAL;
1875
1876 rx_priv->hph_hd2_mode = ucontrol->value.integer.value[0];
1877 return 0;
1878}
1879
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05301880static int rx_macro_get_hph_pwr_mode(struct snd_kcontrol *kcontrol,
1881 struct snd_ctl_elem_value *ucontrol)
1882{
Meng Wang15c825d2018-09-06 10:49:18 +08001883 struct snd_soc_component *component =
1884 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05301885 struct device *rx_dev = NULL;
1886 struct rx_macro_priv *rx_priv = NULL;
1887
Meng Wang15c825d2018-09-06 10:49:18 +08001888 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05301889 return -EINVAL;
1890
1891 ucontrol->value.integer.value[0] = rx_priv->hph_pwr_mode;
1892 return 0;
1893}
1894
1895static int rx_macro_put_hph_pwr_mode(struct snd_kcontrol *kcontrol,
1896 struct snd_ctl_elem_value *ucontrol)
1897{
Meng Wang15c825d2018-09-06 10:49:18 +08001898 struct snd_soc_component *component =
1899 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05301900 struct device *rx_dev = NULL;
1901 struct rx_macro_priv *rx_priv = NULL;
1902
Meng Wang15c825d2018-09-06 10:49:18 +08001903 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05301904 return -EINVAL;
1905
1906 rx_priv->hph_pwr_mode = ucontrol->value.integer.value[0];
1907 return 0;
1908}
1909
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301910static int rx_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
1911 struct snd_ctl_elem_value *ucontrol)
1912{
Meng Wang15c825d2018-09-06 10:49:18 +08001913 struct snd_soc_component *component =
1914 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301915
1916 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08001917 ((snd_soc_component_read32(
1918 component, BOLERO_CDC_RX_BCL_VBAT_CFG) & 0x04) ?
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301919 1 : 0);
1920
Meng Wang15c825d2018-09-06 10:49:18 +08001921 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301922 ucontrol->value.integer.value[0]);
1923
1924 return 0;
1925}
1926
1927static int rx_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
1928 struct snd_ctl_elem_value *ucontrol)
1929{
Meng Wang15c825d2018-09-06 10:49:18 +08001930 struct snd_soc_component *component =
1931 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301932
Meng Wang15c825d2018-09-06 10:49:18 +08001933 dev_dbg(component->dev, "%s: value: %lu\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301934 ucontrol->value.integer.value[0]);
1935
1936 /* Set Vbat register configuration for GSM mode bit based on value */
1937 if (ucontrol->value.integer.value[0])
Meng Wang15c825d2018-09-06 10:49:18 +08001938 snd_soc_component_update_bits(component,
1939 BOLERO_CDC_RX_BCL_VBAT_CFG,
1940 0x04, 0x04);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301941 else
Meng Wang15c825d2018-09-06 10:49:18 +08001942 snd_soc_component_update_bits(component,
1943 BOLERO_CDC_RX_BCL_VBAT_CFG,
1944 0x04, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301945
1946 return 0;
1947}
1948
1949static int rx_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
1950 struct snd_ctl_elem_value *ucontrol)
1951{
Meng Wang15c825d2018-09-06 10:49:18 +08001952 struct snd_soc_component *component =
1953 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301954 struct device *rx_dev = NULL;
1955 struct rx_macro_priv *rx_priv = NULL;
1956
Meng Wang15c825d2018-09-06 10:49:18 +08001957 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301958 return -EINVAL;
1959
1960 ucontrol->value.integer.value[0] = rx_priv->is_softclip_on;
1961
Meng Wang15c825d2018-09-06 10:49:18 +08001962 dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301963 __func__, ucontrol->value.integer.value[0]);
1964
1965 return 0;
1966}
1967
1968static int rx_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
1969 struct snd_ctl_elem_value *ucontrol)
1970{
Meng Wang15c825d2018-09-06 10:49:18 +08001971 struct snd_soc_component *component =
1972 snd_soc_kcontrol_component(kcontrol);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301973 struct device *rx_dev = NULL;
1974 struct rx_macro_priv *rx_priv = NULL;
1975
Meng Wang15c825d2018-09-06 10:49:18 +08001976 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301977 return -EINVAL;
1978
Meng Wang15c825d2018-09-06 10:49:18 +08001979 rx_priv->is_softclip_on = ucontrol->value.integer.value[0];
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301980
Meng Wang15c825d2018-09-06 10:49:18 +08001981 dev_dbg(component->dev, "%s: soft clip enable = %d\n", __func__,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301982 rx_priv->is_softclip_on);
1983
1984 return 0;
1985}
1986
1987static int rx_macro_enable_vbat(struct snd_soc_dapm_widget *w,
1988 struct snd_kcontrol *kcontrol,
1989 int event)
1990{
Meng Wang15c825d2018-09-06 10:49:18 +08001991 struct snd_soc_component *component =
1992 snd_soc_dapm_to_component(w->dapm);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301993 struct device *rx_dev = NULL;
1994 struct rx_macro_priv *rx_priv = NULL;
1995
Meng Wang15c825d2018-09-06 10:49:18 +08001996 dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
1997 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05301998 return -EINVAL;
1999
2000 switch (event) {
2001 case SND_SOC_DAPM_PRE_PMU:
2002 /* Enable clock for VBAT block */
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_PATH_CTL, 0x10, 0x10);
2005 /* Enable VBAT block */
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_CFG, 0x01, 0x01);
2008 /* Update interpolator with 384K path */
Meng Wang15c825d2018-09-06 10:49:18 +08002009 snd_soc_component_update_bits(component,
2010 BOLERO_CDC_RX_RX2_RX_PATH_CFG1, 0x80, 0x80);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302011 /* Update DSM FS rate */
Meng Wang15c825d2018-09-06 10:49:18 +08002012 snd_soc_component_update_bits(component,
2013 BOLERO_CDC_RX_RX2_RX_PATH_SEC7, 0x02, 0x02);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302014 /* Use attenuation mode */
Meng Wang15c825d2018-09-06 10:49:18 +08002015 snd_soc_component_update_bits(component,
2016 BOLERO_CDC_RX_BCL_VBAT_CFG, 0x02, 0x00);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302017 /* BCL block needs softclip clock to be enabled */
Meng Wang15c825d2018-09-06 10:49:18 +08002018 rx_macro_enable_softclip_clk(component, rx_priv, true);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302019 /* Enable VBAT at channel level */
Meng Wang15c825d2018-09-06 10:49:18 +08002020 snd_soc_component_update_bits(component,
2021 BOLERO_CDC_RX_RX2_RX_PATH_CFG1, 0x02, 0x02);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302022 /* Set the ATTK1 gain */
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_UPD1,
2025 0xFF, 0xFF);
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_UPD2,
2028 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08002029 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302030 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3,
2031 0xFF, 0x00);
2032 /* Set the ATTK2 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08002033 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302034 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4,
2035 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08002036 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302037 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5,
2038 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08002039 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302040 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6,
2041 0xFF, 0x00);
2042 /* Set the ATTK3 gain */
Meng Wang15c825d2018-09-06 10:49:18 +08002043 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302044 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7,
2045 0xFF, 0xFF);
Meng Wang15c825d2018-09-06 10:49:18 +08002046 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302047 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8,
2048 0xFF, 0x03);
Meng Wang15c825d2018-09-06 10:49:18 +08002049 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302050 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9,
2051 0xFF, 0x00);
2052 break;
2053
2054 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08002055 snd_soc_component_update_bits(component,
2056 BOLERO_CDC_RX_RX2_RX_PATH_CFG1,
2057 0x80, 0x00);
2058 snd_soc_component_update_bits(component,
2059 BOLERO_CDC_RX_RX2_RX_PATH_SEC7,
2060 0x02, 0x00);
2061 snd_soc_component_update_bits(component,
2062 BOLERO_CDC_RX_BCL_VBAT_CFG,
2063 0x02, 0x02);
2064 snd_soc_component_update_bits(component,
2065 BOLERO_CDC_RX_RX2_RX_PATH_CFG1,
2066 0x02, 0x00);
2067 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302068 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1,
2069 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002070 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302071 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2,
2072 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002073 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302074 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3,
2075 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002076 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302077 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4,
2078 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002079 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302080 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5,
2081 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002082 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302083 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6,
2084 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002085 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302086 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7,
2087 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002088 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302089 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8,
2090 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002091 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302092 BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9,
2093 0xFF, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002094 rx_macro_enable_softclip_clk(component, rx_priv, false);
2095 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302096 BOLERO_CDC_RX_BCL_VBAT_CFG, 0x01, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002097 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302098 BOLERO_CDC_RX_BCL_VBAT_PATH_CTL, 0x10, 0x00);
2099 break;
2100 default:
2101 dev_err(rx_dev, "%s: Invalid event %d\n", __func__, event);
2102 break;
2103 }
2104 return 0;
2105}
2106
Meng Wang15c825d2018-09-06 10:49:18 +08002107static void rx_macro_idle_detect_control(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302108 struct rx_macro_priv *rx_priv,
2109 int interp, int event)
2110{
2111 int reg = 0, mask = 0, val = 0;
2112
2113 if (!rx_priv->idle_det_cfg.hph_idle_detect_en)
2114 return;
2115
2116 if (interp == INTERP_HPHL) {
2117 reg = BOLERO_CDC_RX_IDLE_DETECT_PATH_CTL;
2118 mask = 0x01;
2119 val = 0x01;
2120 }
2121 if (interp == INTERP_HPHR) {
2122 reg = BOLERO_CDC_RX_IDLE_DETECT_PATH_CTL;
2123 mask = 0x02;
2124 val = 0x02;
2125 }
2126
2127 if (reg && SND_SOC_DAPM_EVENT_ON(event))
Meng Wang15c825d2018-09-06 10:49:18 +08002128 snd_soc_component_update_bits(component, reg, mask, val);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302129
2130 if (reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08002131 snd_soc_component_update_bits(component, reg, mask, 0x00);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302132 rx_priv->idle_det_cfg.hph_idle_thr = 0;
Meng Wang15c825d2018-09-06 10:49:18 +08002133 snd_soc_component_write(component,
2134 BOLERO_CDC_RX_IDLE_DETECT_CFG3, 0x0);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302135 }
2136}
2137
Meng Wang15c825d2018-09-06 10:49:18 +08002138static void rx_macro_hphdelay_lutbypass(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302139 struct rx_macro_priv *rx_priv,
2140 u16 interp_idx, int event)
2141{
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302142 u16 hph_lut_bypass_reg = 0;
2143 u16 hph_comp_ctrl7 = 0;
2144
2145 switch (interp_idx) {
2146 case INTERP_HPHL:
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302147 hph_lut_bypass_reg = BOLERO_CDC_RX_TOP_HPHL_COMP_LUT;
2148 hph_comp_ctrl7 = BOLERO_CDC_RX_COMPANDER0_CTL7;
2149 break;
2150 case INTERP_HPHR:
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302151 hph_lut_bypass_reg = BOLERO_CDC_RX_TOP_HPHR_COMP_LUT;
2152 hph_comp_ctrl7 = BOLERO_CDC_RX_COMPANDER1_CTL7;
2153 break;
2154 default:
2155 break;
2156 }
2157
2158 if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) {
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302159 if (interp_idx == INTERP_HPHL) {
2160 if (rx_priv->is_ear_mode_on)
Meng Wang15c825d2018-09-06 10:49:18 +08002161 snd_soc_component_update_bits(component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302162 BOLERO_CDC_RX_RX0_RX_PATH_CFG1,
2163 0x02, 0x02);
2164 else
Meng Wang15c825d2018-09-06 10:49:18 +08002165 snd_soc_component_update_bits(component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302166 hph_lut_bypass_reg,
2167 0x80, 0x80);
2168 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08002169 snd_soc_component_update_bits(component,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302170 hph_lut_bypass_reg,
2171 0x80, 0x80);
2172 }
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05302173 if (rx_priv->hph_pwr_mode)
Meng Wang15c825d2018-09-06 10:49:18 +08002174 snd_soc_component_update_bits(component,
2175 hph_comp_ctrl7,
2176 0x20, 0x00);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302177 }
2178
2179 if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
Meng Wang15c825d2018-09-06 10:49:18 +08002180 snd_soc_component_update_bits(component,
2181 BOLERO_CDC_RX_RX0_RX_PATH_CFG1,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302182 0x02, 0x00);
Meng Wang15c825d2018-09-06 10:49:18 +08002183 snd_soc_component_update_bits(component, hph_lut_bypass_reg,
2184 0x80, 0x00);
2185 snd_soc_component_update_bits(component, hph_comp_ctrl7,
Karthikeyan Manic141ca92019-05-13 14:40:55 -07002186 0x20, 0x20);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302187 }
2188}
2189
Meng Wang15c825d2018-09-06 10:49:18 +08002190static int rx_macro_enable_interp_clk(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302191 int event, int interp_idx)
2192{
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302193 u16 main_reg = 0, dsm_reg = 0, rx_cfg2_reg = 0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302194 struct device *rx_dev = NULL;
2195 struct rx_macro_priv *rx_priv = NULL;
2196
Meng Wang15c825d2018-09-06 10:49:18 +08002197 if (!component) {
2198 pr_err("%s: component is NULL\n", __func__);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302199 return -EINVAL;
2200 }
2201
Meng Wang15c825d2018-09-06 10:49:18 +08002202 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302203 return -EINVAL;
2204
2205 main_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL +
2206 (interp_idx * RX_MACRO_RX_PATH_OFFSET);
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302207 dsm_reg = BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL +
2208 (interp_idx * RX_MACRO_RX_PATH_OFFSET);
Laxminath Kasam1a4dd6d2019-04-02 15:21:54 +05302209 if (interp_idx == INTERP_AUX)
2210 dsm_reg = BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL;
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302211 rx_cfg2_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG2 +
2212 (interp_idx * RX_MACRO_RX_PATH_OFFSET);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302213
2214 if (SND_SOC_DAPM_EVENT_ON(event)) {
2215 if (rx_priv->main_clk_users[interp_idx] == 0) {
2216 /* Main path PGA mute enable */
Meng Wang15c825d2018-09-06 10:49:18 +08002217 snd_soc_component_update_bits(component, main_reg,
2218 0x10, 0x10);
Laxminath Kasam1a4dd6d2019-04-02 15:21:54 +05302219 snd_soc_component_update_bits(component, dsm_reg,
2220 0x01, 0x01);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302221 /* Clk enable */
Meng Wang15c825d2018-09-06 10:49:18 +08002222 snd_soc_component_update_bits(component, main_reg,
2223 0x20, 0x20);
2224 snd_soc_component_update_bits(component, rx_cfg2_reg,
2225 0x03, 0x03);
2226 rx_macro_idle_detect_control(component, rx_priv,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302227 interp_idx, event);
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05302228 if (rx_priv->hph_hd2_mode)
Meng Wang15c825d2018-09-06 10:49:18 +08002229 rx_macro_hd2_control(
2230 component, interp_idx, event);
2231 rx_macro_hphdelay_lutbypass(component, rx_priv,
2232 interp_idx, event);
2233 rx_macro_config_compander(component, rx_priv,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302234 interp_idx, event);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302235 if (interp_idx == INTERP_AUX)
Meng Wang15c825d2018-09-06 10:49:18 +08002236 rx_macro_config_softclip(component, rx_priv,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302237 event);
Meng Wang15c825d2018-09-06 10:49:18 +08002238 rx_macro_config_classh(component, rx_priv,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302239 interp_idx, event);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302240 }
2241 rx_priv->main_clk_users[interp_idx]++;
2242 }
2243
2244 if (SND_SOC_DAPM_EVENT_OFF(event)) {
2245 rx_priv->main_clk_users[interp_idx]--;
2246 if (rx_priv->main_clk_users[interp_idx] <= 0) {
2247 rx_priv->main_clk_users[interp_idx] = 0;
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302248 /* Clk Disable */
Meng Wang15c825d2018-09-06 10:49:18 +08002249 snd_soc_component_update_bits(component, dsm_reg,
2250 0x01, 0x00);
2251 snd_soc_component_update_bits(component, main_reg,
2252 0x20, 0x00);
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302253 /* Reset enable and disable */
Meng Wang15c825d2018-09-06 10:49:18 +08002254 snd_soc_component_update_bits(component, main_reg,
2255 0x40, 0x40);
2256 snd_soc_component_update_bits(component, main_reg,
2257 0x40, 0x00);
Laxminath Kasam35849cc2018-11-14 20:36:08 +05302258 /* Reset rate to 48K*/
Meng Wang15c825d2018-09-06 10:49:18 +08002259 snd_soc_component_update_bits(component, main_reg,
2260 0x0F, 0x04);
2261 snd_soc_component_update_bits(component, rx_cfg2_reg,
2262 0x03, 0x00);
2263 rx_macro_config_classh(component, rx_priv,
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302264 interp_idx, event);
Meng Wang15c825d2018-09-06 10:49:18 +08002265 rx_macro_config_compander(component, rx_priv,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302266 interp_idx, event);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302267 if (interp_idx == INTERP_AUX)
Meng Wang15c825d2018-09-06 10:49:18 +08002268 rx_macro_config_softclip(component, rx_priv,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302269 event);
Meng Wang15c825d2018-09-06 10:49:18 +08002270 rx_macro_hphdelay_lutbypass(component, rx_priv,
2271 interp_idx, event);
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05302272 if (rx_priv->hph_hd2_mode)
Meng Wang15c825d2018-09-06 10:49:18 +08002273 rx_macro_hd2_control(component, interp_idx,
2274 event);
2275 rx_macro_idle_detect_control(component, rx_priv,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302276 interp_idx, event);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302277 }
2278 }
2279
Meng Wang15c825d2018-09-06 10:49:18 +08002280 dev_dbg(component->dev, "%s event %d main_clk_users %d\n",
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302281 __func__, event, rx_priv->main_clk_users[interp_idx]);
2282
2283 return rx_priv->main_clk_users[interp_idx];
2284}
2285
2286static int rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w,
2287 struct snd_kcontrol *kcontrol, int event)
2288{
Meng Wang15c825d2018-09-06 10:49:18 +08002289 struct snd_soc_component *component =
2290 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302291 u16 sidetone_reg = 0;
2292
Meng Wang15c825d2018-09-06 10:49:18 +08002293 dev_dbg(component->dev, "%s %d %d\n", __func__, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302294 sidetone_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG1 +
2295 RX_MACRO_RX_PATH_OFFSET * (w->shift);
2296
2297 switch (event) {
2298 case SND_SOC_DAPM_PRE_PMU:
Meng Wang15c825d2018-09-06 10:49:18 +08002299 rx_macro_enable_interp_clk(component, event, w->shift);
2300 snd_soc_component_update_bits(component, sidetone_reg,
2301 0x10, 0x10);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302302 break;
2303 case SND_SOC_DAPM_POST_PMD:
Meng Wang15c825d2018-09-06 10:49:18 +08002304 snd_soc_component_update_bits(component, sidetone_reg,
2305 0x10, 0x00);
2306 rx_macro_enable_interp_clk(component, event, w->shift);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302307 break;
2308 default:
2309 break;
2310 };
2311 return 0;
2312}
2313
2314static void rx_macro_restore_iir_coeff(struct rx_macro_priv *rx_priv, int iir_idx,
2315 int band_idx)
2316{
2317 u16 reg_add = 0, coeff_idx = 0, idx = 0;
2318 struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL);
2319
Tanya Dixit8530fb92018-09-14 16:01:25 +05302320 if (regmap == NULL) {
2321 dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__);
2322 return;
2323 }
2324
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302325 regmap_write(regmap,
2326 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
2327 (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
2328
2329 reg_add = BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx;
2330
2331 /* 5 coefficients per band and 4 writes per coefficient */
2332 for (coeff_idx = 0; coeff_idx < RX_MACRO_SIDETONE_IIR_COEFF_MAX;
2333 coeff_idx++) {
2334 /* Four 8 bit values(one 32 bit) per coefficient */
2335 regmap_write(regmap, reg_add,
2336 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
2337 regmap_write(regmap, reg_add,
2338 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
2339 regmap_write(regmap, reg_add,
2340 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
2341 regmap_write(regmap, reg_add,
2342 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
2343 }
2344}
2345
2346static int rx_macro_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol,
2347 struct snd_ctl_elem_value *ucontrol)
2348{
Meng Wang15c825d2018-09-06 10:49:18 +08002349 struct snd_soc_component *component =
2350 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302351 int iir_idx = ((struct soc_multi_mixer_control *)
2352 kcontrol->private_value)->reg;
2353 int band_idx = ((struct soc_multi_mixer_control *)
2354 kcontrol->private_value)->shift;
2355 /* IIR filter band registers are at integer multiples of 0x80 */
2356 u16 iir_reg = BOLERO_CDC_RX_SIDETONE_IIR0_IIR_CTL + 0x80 * iir_idx;
2357
Meng Wang15c825d2018-09-06 10:49:18 +08002358 ucontrol->value.integer.value[0] = (
2359 snd_soc_component_read32(component, iir_reg) &
2360 (1 << band_idx)) != 0;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302361
Meng Wang15c825d2018-09-06 10:49:18 +08002362 dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302363 iir_idx, band_idx,
2364 (uint32_t)ucontrol->value.integer.value[0]);
2365 return 0;
2366}
2367
2368static int rx_macro_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol,
2369 struct snd_ctl_elem_value *ucontrol)
2370{
Meng Wang15c825d2018-09-06 10:49:18 +08002371 struct snd_soc_component *component =
2372 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302373 int iir_idx = ((struct soc_multi_mixer_control *)
2374 kcontrol->private_value)->reg;
2375 int band_idx = ((struct soc_multi_mixer_control *)
2376 kcontrol->private_value)->shift;
2377 bool iir_band_en_status = 0;
2378 int value = ucontrol->value.integer.value[0];
2379 u16 iir_reg = BOLERO_CDC_RX_SIDETONE_IIR0_IIR_CTL + 0x80 * iir_idx;
2380 struct device *rx_dev = NULL;
2381 struct rx_macro_priv *rx_priv = NULL;
2382
Meng Wang15c825d2018-09-06 10:49:18 +08002383 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302384 return -EINVAL;
2385
2386 rx_macro_restore_iir_coeff(rx_priv, iir_idx, band_idx);
2387
2388 /* Mask first 5 bits, 6-8 are reserved */
Meng Wang15c825d2018-09-06 10:49:18 +08002389 snd_soc_component_update_bits(component, iir_reg, (1 << band_idx),
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302390 (value << band_idx));
2391
Meng Wang15c825d2018-09-06 10:49:18 +08002392 iir_band_en_status = ((snd_soc_component_read32(component, iir_reg) &
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302393 (1 << band_idx)) != 0);
Meng Wang15c825d2018-09-06 10:49:18 +08002394 dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302395 iir_idx, band_idx, iir_band_en_status);
2396 return 0;
2397}
2398
Meng Wang15c825d2018-09-06 10:49:18 +08002399static uint32_t get_iir_band_coeff(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302400 int iir_idx, int band_idx,
2401 int coeff_idx)
2402{
2403 uint32_t value = 0;
2404
2405 /* Address does not automatically update if reading */
Meng Wang15c825d2018-09-06 10:49:18 +08002406 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302407 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
2408 ((band_idx * BAND_MAX + coeff_idx)
2409 * sizeof(uint32_t)) & 0x7F);
2410
Meng Wang15c825d2018-09-06 10:49:18 +08002411 value |= snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302412 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx));
2413
Meng Wang15c825d2018-09-06 10:49:18 +08002414 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302415 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
2416 ((band_idx * BAND_MAX + coeff_idx)
2417 * sizeof(uint32_t) + 1) & 0x7F);
2418
Meng Wang15c825d2018-09-06 10:49:18 +08002419 value |= (snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302420 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2421 0x80 * iir_idx)) << 8);
2422
Meng Wang15c825d2018-09-06 10:49:18 +08002423 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302424 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
2425 ((band_idx * BAND_MAX + coeff_idx)
2426 * sizeof(uint32_t) + 2) & 0x7F);
2427
Meng Wang15c825d2018-09-06 10:49:18 +08002428 value |= (snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302429 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2430 0x80 * iir_idx)) << 16);
2431
Meng Wang15c825d2018-09-06 10:49:18 +08002432 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302433 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
2434 ((band_idx * BAND_MAX + coeff_idx)
2435 * sizeof(uint32_t) + 3) & 0x7F);
2436
2437 /* Mask bits top 2 bits since they are reserved */
Meng Wang15c825d2018-09-06 10:49:18 +08002438 value |= ((snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302439 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL +
2440 16 * iir_idx)) & 0x3F) << 24);
2441
2442 return value;
2443}
2444
2445static int rx_macro_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol,
2446 struct snd_ctl_elem_value *ucontrol)
2447{
Meng Wang15c825d2018-09-06 10:49:18 +08002448 struct snd_soc_component *component =
2449 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302450 int iir_idx = ((struct soc_multi_mixer_control *)
2451 kcontrol->private_value)->reg;
2452 int band_idx = ((struct soc_multi_mixer_control *)
2453 kcontrol->private_value)->shift;
2454
2455 ucontrol->value.integer.value[0] =
Meng Wang15c825d2018-09-06 10:49:18 +08002456 get_iir_band_coeff(component, iir_idx, band_idx, 0);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302457 ucontrol->value.integer.value[1] =
Meng Wang15c825d2018-09-06 10:49:18 +08002458 get_iir_band_coeff(component, iir_idx, band_idx, 1);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302459 ucontrol->value.integer.value[2] =
Meng Wang15c825d2018-09-06 10:49:18 +08002460 get_iir_band_coeff(component, iir_idx, band_idx, 2);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302461 ucontrol->value.integer.value[3] =
Meng Wang15c825d2018-09-06 10:49:18 +08002462 get_iir_band_coeff(component, iir_idx, band_idx, 3);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302463 ucontrol->value.integer.value[4] =
Meng Wang15c825d2018-09-06 10:49:18 +08002464 get_iir_band_coeff(component, iir_idx, band_idx, 4);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302465
Meng Wang15c825d2018-09-06 10:49:18 +08002466 dev_dbg(component->dev, "%s: IIR #%d band #%d b0 = 0x%x\n"
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302467 "%s: IIR #%d band #%d b1 = 0x%x\n"
2468 "%s: IIR #%d band #%d b2 = 0x%x\n"
2469 "%s: IIR #%d band #%d a1 = 0x%x\n"
2470 "%s: IIR #%d band #%d a2 = 0x%x\n",
2471 __func__, iir_idx, band_idx,
2472 (uint32_t)ucontrol->value.integer.value[0],
2473 __func__, iir_idx, band_idx,
2474 (uint32_t)ucontrol->value.integer.value[1],
2475 __func__, iir_idx, band_idx,
2476 (uint32_t)ucontrol->value.integer.value[2],
2477 __func__, iir_idx, band_idx,
2478 (uint32_t)ucontrol->value.integer.value[3],
2479 __func__, iir_idx, band_idx,
2480 (uint32_t)ucontrol->value.integer.value[4]);
2481 return 0;
2482}
2483
Meng Wang15c825d2018-09-06 10:49:18 +08002484static void set_iir_band_coeff(struct snd_soc_component *component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302485 int iir_idx, int band_idx,
2486 uint32_t value)
2487{
Meng Wang15c825d2018-09-06 10:49:18 +08002488 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302489 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx),
2490 (value & 0xFF));
2491
Meng Wang15c825d2018-09-06 10:49:18 +08002492 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302493 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx),
2494 (value >> 8) & 0xFF);
2495
Meng Wang15c825d2018-09-06 10:49:18 +08002496 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302497 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx),
2498 (value >> 16) & 0xFF);
2499
2500 /* Mask top 2 bits, 7-8 are reserved */
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_B2_CTL + 0x80 * iir_idx),
2503 (value >> 24) & 0x3F);
2504}
2505
2506static int rx_macro_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol,
2507 struct snd_ctl_elem_value *ucontrol)
2508{
Meng Wang15c825d2018-09-06 10:49:18 +08002509 struct snd_soc_component *component =
2510 snd_soc_kcontrol_component(kcontrol);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302511 int iir_idx = ((struct soc_multi_mixer_control *)
2512 kcontrol->private_value)->reg;
2513 int band_idx = ((struct soc_multi_mixer_control *)
2514 kcontrol->private_value)->shift;
2515 int coeff_idx, idx = 0;
2516 struct device *rx_dev = NULL;
2517 struct rx_macro_priv *rx_priv = NULL;
2518
Meng Wang15c825d2018-09-06 10:49:18 +08002519 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302520 return -EINVAL;
2521
2522 /*
2523 * Mask top bit it is reserved
2524 * Updates addr automatically for each B2 write
2525 */
Meng Wang15c825d2018-09-06 10:49:18 +08002526 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302527 (BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
2528 (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
2529
2530 /* Store the coefficients in sidetone coeff array */
2531 for (coeff_idx = 0; coeff_idx < RX_MACRO_SIDETONE_IIR_COEFF_MAX;
2532 coeff_idx++) {
2533 uint32_t value = ucontrol->value.integer.value[coeff_idx];
2534
Meng Wang15c825d2018-09-06 10:49:18 +08002535 set_iir_band_coeff(component, iir_idx, band_idx, value);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302536
2537 /* Four 8 bit values(one 32 bit) per coefficient */
2538 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
2539 (value & 0xFF);
2540 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
2541 (value >> 8) & 0xFF;
2542 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
2543 (value >> 16) & 0xFF;
2544 rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
2545 (value >> 24) & 0xFF;
2546 }
2547
2548 pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
2549 "%s: IIR #%d band #%d b1 = 0x%x\n"
2550 "%s: IIR #%d band #%d b2 = 0x%x\n"
2551 "%s: IIR #%d band #%d a1 = 0x%x\n"
2552 "%s: IIR #%d band #%d a2 = 0x%x\n",
2553 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08002554 get_iir_band_coeff(component, iir_idx, band_idx, 0),
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302555 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08002556 get_iir_band_coeff(component, iir_idx, band_idx, 1),
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302557 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08002558 get_iir_band_coeff(component, iir_idx, band_idx, 2),
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302559 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08002560 get_iir_band_coeff(component, iir_idx, band_idx, 3),
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302561 __func__, iir_idx, band_idx,
Meng Wang15c825d2018-09-06 10:49:18 +08002562 get_iir_band_coeff(component, iir_idx, band_idx, 4));
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302563 return 0;
2564}
2565
2566static int rx_macro_set_iir_gain(struct snd_soc_dapm_widget *w,
2567 struct snd_kcontrol *kcontrol, int event)
2568{
Meng Wang15c825d2018-09-06 10:49:18 +08002569 struct snd_soc_component *component =
2570 snd_soc_dapm_to_component(w->dapm);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302571
Meng Wang15c825d2018-09-06 10:49:18 +08002572 dev_dbg(component->dev, "%s: event = %d\n", __func__, event);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302573
2574 switch (event) {
2575 case SND_SOC_DAPM_POST_PMU: /* fall through */
2576 case SND_SOC_DAPM_PRE_PMD:
2577 if (strnstr(w->name, "IIR0", sizeof("IIR0"))) {
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_IIR0_IIR_GAIN_B1_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_IIR0_IIR_GAIN_B1_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_IIR0_IIR_GAIN_B2_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_IIR0_IIR_GAIN_B2_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002586 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302587 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002588 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302589 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002590 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302591 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002592 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302593 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL));
2594 } else {
Meng Wang15c825d2018-09-06 10:49:18 +08002595 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302596 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002597 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302598 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002599 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302600 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002601 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302602 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002603 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302604 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002605 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302606 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL));
Meng Wang15c825d2018-09-06 10:49:18 +08002607 snd_soc_component_write(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302608 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL,
Meng Wang15c825d2018-09-06 10:49:18 +08002609 snd_soc_component_read32(component,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302610 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL));
2611 }
2612 break;
2613 }
2614 return 0;
2615}
2616
2617static const struct snd_kcontrol_new rx_macro_snd_controls[] = {
2618 SOC_SINGLE_SX_TLV("RX_RX0 Digital Volume",
2619 BOLERO_CDC_RX_RX0_RX_VOL_CTL,
2620 0, -84, 40, digital_gain),
2621 SOC_SINGLE_SX_TLV("RX_RX1 Digital Volume",
2622 BOLERO_CDC_RX_RX1_RX_VOL_CTL,
2623 0, -84, 40, digital_gain),
2624 SOC_SINGLE_SX_TLV("RX_RX2 Digital Volume",
2625 BOLERO_CDC_RX_RX2_RX_VOL_CTL,
2626 0, -84, 40, digital_gain),
2627 SOC_SINGLE_SX_TLV("RX_RX0 Mix Digital Volume",
2628 BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
2629 SOC_SINGLE_SX_TLV("RX_RX1 Mix Digital Volume",
2630 BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
2631 SOC_SINGLE_SX_TLV("RX_RX2 Mix Digital Volume",
2632 BOLERO_CDC_RX_RX2_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
2633
2634 SOC_SINGLE_EXT("RX_COMP1 Switch", SND_SOC_NOPM, RX_MACRO_COMP1, 1, 0,
2635 rx_macro_get_compander, rx_macro_set_compander),
2636 SOC_SINGLE_EXT("RX_COMP2 Switch", SND_SOC_NOPM, RX_MACRO_COMP2, 1, 0,
2637 rx_macro_get_compander, rx_macro_set_compander),
2638
Vatsal Bucha8bcc97c2019-01-07 13:18:11 +05302639 SOC_ENUM_EXT("HPH Idle Detect", hph_idle_detect_enum,
2640 rx_macro_hph_idle_detect_get, rx_macro_hph_idle_detect_put),
2641
Laxminath Kasamd2d8d9f2018-08-06 18:10:14 +05302642 SOC_ENUM_EXT("RX_EAR Mode", rx_macro_ear_mode_enum,
2643 rx_macro_get_ear_mode, rx_macro_put_ear_mode),
2644
Laxminath Kasamd3ffb332018-11-14 19:59:21 +05302645 SOC_ENUM_EXT("RX_HPH HD2 Mode", rx_macro_hph_hd2_mode_enum,
2646 rx_macro_get_hph_hd2_mode, rx_macro_put_hph_hd2_mode),
2647
Laxminath Kasamde09dfb2018-11-09 13:00:30 +05302648 SOC_ENUM_EXT("RX_HPH_PWR_MODE", rx_macro_hph_pwr_mode_enum,
2649 rx_macro_get_hph_pwr_mode, rx_macro_put_hph_pwr_mode),
2650
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302651 SOC_ENUM_EXT("RX_GSM mode Enable", rx_macro_vbat_bcl_gsm_mode_enum,
2652 rx_macro_vbat_bcl_gsm_mode_func_get,
2653 rx_macro_vbat_bcl_gsm_mode_func_put),
2654 SOC_SINGLE_EXT("RX_Softclip Enable", SND_SOC_NOPM, 0, 1, 0,
2655 rx_macro_soft_clip_enable_get,
2656 rx_macro_soft_clip_enable_put),
2657
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302658 SOC_SINGLE_SX_TLV("IIR0 INP0 Volume",
2659 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40,
2660 digital_gain),
2661 SOC_SINGLE_SX_TLV("IIR0 INP1 Volume",
2662 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84, 40,
2663 digital_gain),
2664 SOC_SINGLE_SX_TLV("IIR0 INP2 Volume",
2665 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84, 40,
2666 digital_gain),
2667 SOC_SINGLE_SX_TLV("IIR0 INP3 Volume",
2668 BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84, 40,
2669 digital_gain),
2670 SOC_SINGLE_SX_TLV("IIR1 INP0 Volume",
2671 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0, -84, 40,
2672 digital_gain),
2673 SOC_SINGLE_SX_TLV("IIR1 INP1 Volume",
2674 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0, -84, 40,
2675 digital_gain),
2676 SOC_SINGLE_SX_TLV("IIR1 INP2 Volume",
2677 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0, -84, 40,
2678 digital_gain),
2679 SOC_SINGLE_SX_TLV("IIR1 INP3 Volume",
2680 BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0, -84, 40,
2681 digital_gain),
2682
2683 SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0,
2684 rx_macro_iir_enable_audio_mixer_get,
2685 rx_macro_iir_enable_audio_mixer_put),
2686 SOC_SINGLE_EXT("IIR0 Enable Band2", IIR0, BAND2, 1, 0,
2687 rx_macro_iir_enable_audio_mixer_get,
2688 rx_macro_iir_enable_audio_mixer_put),
2689 SOC_SINGLE_EXT("IIR0 Enable Band3", IIR0, BAND3, 1, 0,
2690 rx_macro_iir_enable_audio_mixer_get,
2691 rx_macro_iir_enable_audio_mixer_put),
2692 SOC_SINGLE_EXT("IIR0 Enable Band4", IIR0, BAND4, 1, 0,
2693 rx_macro_iir_enable_audio_mixer_get,
2694 rx_macro_iir_enable_audio_mixer_put),
2695 SOC_SINGLE_EXT("IIR0 Enable Band5", IIR0, BAND5, 1, 0,
2696 rx_macro_iir_enable_audio_mixer_get,
2697 rx_macro_iir_enable_audio_mixer_put),
2698 SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
2699 rx_macro_iir_enable_audio_mixer_get,
2700 rx_macro_iir_enable_audio_mixer_put),
2701 SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
2702 rx_macro_iir_enable_audio_mixer_get,
2703 rx_macro_iir_enable_audio_mixer_put),
2704 SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
2705 rx_macro_iir_enable_audio_mixer_get,
2706 rx_macro_iir_enable_audio_mixer_put),
2707 SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
2708 rx_macro_iir_enable_audio_mixer_get,
2709 rx_macro_iir_enable_audio_mixer_put),
2710 SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
2711 rx_macro_iir_enable_audio_mixer_get,
2712 rx_macro_iir_enable_audio_mixer_put),
2713
2714 SOC_SINGLE_MULTI_EXT("IIR0 Band1", IIR0, BAND1, 255, 0, 5,
2715 rx_macro_iir_band_audio_mixer_get,
2716 rx_macro_iir_band_audio_mixer_put),
2717 SOC_SINGLE_MULTI_EXT("IIR0 Band2", IIR0, BAND2, 255, 0, 5,
2718 rx_macro_iir_band_audio_mixer_get,
2719 rx_macro_iir_band_audio_mixer_put),
2720 SOC_SINGLE_MULTI_EXT("IIR0 Band3", IIR0, BAND3, 255, 0, 5,
2721 rx_macro_iir_band_audio_mixer_get,
2722 rx_macro_iir_band_audio_mixer_put),
2723 SOC_SINGLE_MULTI_EXT("IIR0 Band4", IIR0, BAND4, 255, 0, 5,
2724 rx_macro_iir_band_audio_mixer_get,
2725 rx_macro_iir_band_audio_mixer_put),
2726 SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5,
2727 rx_macro_iir_band_audio_mixer_get,
2728 rx_macro_iir_band_audio_mixer_put),
2729 SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
2730 rx_macro_iir_band_audio_mixer_get,
2731 rx_macro_iir_band_audio_mixer_put),
2732 SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
2733 rx_macro_iir_band_audio_mixer_get,
2734 rx_macro_iir_band_audio_mixer_put),
2735 SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
2736 rx_macro_iir_band_audio_mixer_get,
2737 rx_macro_iir_band_audio_mixer_put),
2738 SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
2739 rx_macro_iir_band_audio_mixer_get,
2740 rx_macro_iir_band_audio_mixer_put),
2741 SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
2742 rx_macro_iir_band_audio_mixer_get,
2743 rx_macro_iir_band_audio_mixer_put),
2744};
2745
Vatsal Buchac2d6c222018-11-30 18:46:37 +05302746static int rx_macro_enable_echo(struct snd_soc_dapm_widget *w,
2747 struct snd_kcontrol *kcontrol,
2748 int event)
2749{
2750 struct snd_soc_component *component =
2751 snd_soc_dapm_to_component(w->dapm);
2752 struct device *rx_dev = NULL;
2753 struct rx_macro_priv *rx_priv = NULL;
2754 u16 val = 0, ec_hq_reg = 0;
2755 int ec_tx = 0;
2756
2757 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
2758 return -EINVAL;
2759
2760 dev_dbg(rx_dev, "%s %d %s\n", __func__, event, w->name);
2761
2762 val = snd_soc_component_read32(component,
2763 BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4);
2764 if (!(strcmp(w->name, "RX MIX TX0 MUX")))
2765 ec_tx = ((val & 0xf0) >> 0x4) - 1;
2766 else if (!(strcmp(w->name, "RX MIX TX1 MUX")))
2767 ec_tx = (val & 0x0f) - 1;
2768
2769 val = snd_soc_component_read32(component,
2770 BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5);
2771 if (!(strcmp(w->name, "RX MIX TX2 MUX")))
2772 ec_tx = (val & 0x0f) - 1;
2773
2774 if (ec_tx < 0 || (ec_tx >= RX_MACRO_EC_MUX_MAX)) {
2775 dev_err(rx_dev, "%s: EC mix control not set correctly\n",
2776 __func__);
2777 return -EINVAL;
2778 }
2779 ec_hq_reg = BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL +
2780 0x40 * ec_tx;
2781 snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01);
2782 ec_hq_reg = BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0 +
2783 0x40 * ec_tx;
2784 /* default set to 48k */
2785 snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08);
2786
2787 return 0;
2788}
2789
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302790static const struct snd_soc_dapm_widget rx_macro_dapm_widgets[] = {
2791 SND_SOC_DAPM_AIF_IN("RX AIF1 PB", "RX_MACRO_AIF1 Playback", 0,
2792 SND_SOC_NOPM, 0, 0),
2793
2794 SND_SOC_DAPM_AIF_IN("RX AIF2 PB", "RX_MACRO_AIF2 Playback", 0,
2795 SND_SOC_NOPM, 0, 0),
2796
2797 SND_SOC_DAPM_AIF_IN("RX AIF3 PB", "RX_MACRO_AIF3 Playback", 0,
2798 SND_SOC_NOPM, 0, 0),
2799
2800 SND_SOC_DAPM_AIF_IN("RX AIF4 PB", "RX_MACRO_AIF4 Playback", 0,
2801 SND_SOC_NOPM, 0, 0),
2802
Vatsal Buchac2d6c222018-11-30 18:46:37 +05302803 SND_SOC_DAPM_AIF_OUT("RX AIF_ECHO", "RX_AIF_ECHO Capture", 0,
2804 SND_SOC_NOPM, 0, 0),
2805
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302806 RX_MACRO_DAPM_MUX("RX_MACRO RX0 MUX", RX_MACRO_RX0, rx_macro_rx0),
2807 RX_MACRO_DAPM_MUX("RX_MACRO RX1 MUX", RX_MACRO_RX1, rx_macro_rx1),
2808 RX_MACRO_DAPM_MUX("RX_MACRO RX2 MUX", RX_MACRO_RX2, rx_macro_rx2),
2809 RX_MACRO_DAPM_MUX("RX_MACRO RX3 MUX", RX_MACRO_RX3, rx_macro_rx3),
2810 RX_MACRO_DAPM_MUX("RX_MACRO RX4 MUX", RX_MACRO_RX4, rx_macro_rx4),
2811 RX_MACRO_DAPM_MUX("RX_MACRO RX5 MUX", RX_MACRO_RX5, rx_macro_rx5),
2812
2813 SND_SOC_DAPM_MIXER("RX_RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2814 SND_SOC_DAPM_MIXER("RX_RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2815 SND_SOC_DAPM_MIXER("RX_RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
2816 SND_SOC_DAPM_MIXER("RX_RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
2817 SND_SOC_DAPM_MIXER("RX_RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
2818 SND_SOC_DAPM_MIXER("RX_RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
2819
2820 RX_MACRO_DAPM_MUX("IIR0 INP0 MUX", 0, iir0_inp0),
2821 RX_MACRO_DAPM_MUX("IIR0 INP1 MUX", 0, iir0_inp1),
2822 RX_MACRO_DAPM_MUX("IIR0 INP2 MUX", 0, iir0_inp2),
2823 RX_MACRO_DAPM_MUX("IIR0 INP3 MUX", 0, iir0_inp3),
2824 RX_MACRO_DAPM_MUX("IIR1 INP0 MUX", 0, iir1_inp0),
2825 RX_MACRO_DAPM_MUX("IIR1 INP1 MUX", 0, iir1_inp1),
2826 RX_MACRO_DAPM_MUX("IIR1 INP2 MUX", 0, iir1_inp2),
2827 RX_MACRO_DAPM_MUX("IIR1 INP3 MUX", 0, iir1_inp3),
2828
Vatsal Buchac2d6c222018-11-30 18:46:37 +05302829 SND_SOC_DAPM_MUX_E("RX MIX TX0 MUX", SND_SOC_NOPM,
2830 RX_MACRO_EC0_MUX, 0,
2831 &rx_mix_tx0_mux, rx_macro_enable_echo,
2832 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2833 SND_SOC_DAPM_MUX_E("RX MIX TX1 MUX", SND_SOC_NOPM,
2834 RX_MACRO_EC1_MUX, 0,
2835 &rx_mix_tx1_mux, rx_macro_enable_echo,
2836 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2837 SND_SOC_DAPM_MUX_E("RX MIX TX2 MUX", SND_SOC_NOPM,
2838 RX_MACRO_EC2_MUX, 0,
2839 &rx_mix_tx2_mux, rx_macro_enable_echo,
2840 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2841
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302842 SND_SOC_DAPM_MIXER_E("IIR0", BOLERO_CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL,
2843 4, 0, NULL, 0, rx_macro_set_iir_gain,
2844 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2845 SND_SOC_DAPM_MIXER_E("IIR1", BOLERO_CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL,
2846 4, 0, NULL, 0, rx_macro_set_iir_gain,
2847 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2848 SND_SOC_DAPM_MIXER("SRC0", BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL,
2849 4, 0, NULL, 0),
2850 SND_SOC_DAPM_MIXER("SRC1", BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL,
2851 4, 0, NULL, 0),
2852
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302853 RX_MACRO_DAPM_MUX("RX INT0 DEM MUX", 0, rx_int0_dem_inp),
2854 RX_MACRO_DAPM_MUX("RX INT1 DEM MUX", 0, rx_int1_dem_inp),
2855
2856 SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", SND_SOC_NOPM, INTERP_HPHL, 0,
2857 &rx_int0_2_mux, rx_macro_enable_mix_path,
2858 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2859 SND_SOC_DAPM_POST_PMD),
2860 SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", SND_SOC_NOPM, INTERP_HPHR, 0,
2861 &rx_int1_2_mux, rx_macro_enable_mix_path,
2862 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2863 SND_SOC_DAPM_POST_PMD),
2864 SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", SND_SOC_NOPM, INTERP_AUX, 0,
2865 &rx_int2_2_mux, rx_macro_enable_mix_path,
2866 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2867 SND_SOC_DAPM_POST_PMD),
2868
2869 RX_MACRO_DAPM_MUX("RX INT0_1 MIX1 INP0", 0, rx_int0_1_mix_inp0),
2870 RX_MACRO_DAPM_MUX("RX INT0_1 MIX1 INP1", 0, rx_int0_1_mix_inp1),
2871 RX_MACRO_DAPM_MUX("RX INT0_1 MIX1 INP2", 0, rx_int0_1_mix_inp2),
2872 RX_MACRO_DAPM_MUX("RX INT1_1 MIX1 INP0", 0, rx_int1_1_mix_inp0),
2873 RX_MACRO_DAPM_MUX("RX INT1_1 MIX1 INP1", 0, rx_int1_1_mix_inp1),
2874 RX_MACRO_DAPM_MUX("RX INT1_1 MIX1 INP2", 0, rx_int1_1_mix_inp2),
2875 RX_MACRO_DAPM_MUX("RX INT2_1 MIX1 INP0", 0, rx_int2_1_mix_inp0),
2876 RX_MACRO_DAPM_MUX("RX INT2_1 MIX1 INP1", 0, rx_int2_1_mix_inp1),
2877 RX_MACRO_DAPM_MUX("RX INT2_1 MIX1 INP2", 0, rx_int2_1_mix_inp2),
2878
2879 SND_SOC_DAPM_MUX_E("RX INT0_1 INTERP", SND_SOC_NOPM, INTERP_HPHL, 0,
2880 &rx_int0_1_interp_mux, rx_macro_enable_main_path,
2881 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2882 SND_SOC_DAPM_POST_PMD),
2883 SND_SOC_DAPM_MUX_E("RX INT1_1 INTERP", SND_SOC_NOPM, INTERP_HPHR, 0,
2884 &rx_int1_1_interp_mux, rx_macro_enable_main_path,
2885 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2886 SND_SOC_DAPM_POST_PMD),
2887 SND_SOC_DAPM_MUX_E("RX INT2_1 INTERP", SND_SOC_NOPM, INTERP_AUX, 0,
2888 &rx_int2_1_interp_mux, rx_macro_enable_main_path,
2889 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2890 SND_SOC_DAPM_POST_PMD),
2891
2892 RX_MACRO_DAPM_MUX("RX INT0_2 INTERP", 0, rx_int0_2_interp),
2893 RX_MACRO_DAPM_MUX("RX INT1_2 INTERP", 0, rx_int1_2_interp),
2894 RX_MACRO_DAPM_MUX("RX INT2_2 INTERP", 0, rx_int2_2_interp),
2895
2896 SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2897 SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2898 SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2899 SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2900 SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2901 SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2902
2903 SND_SOC_DAPM_MUX_E("RX INT0 MIX2 INP", SND_SOC_NOPM, INTERP_HPHL,
2904 0, &rx_int0_mix2_inp_mux, rx_macro_enable_rx_path_clk,
2905 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2906 SND_SOC_DAPM_MUX_E("RX INT1 MIX2 INP", SND_SOC_NOPM, INTERP_HPHR,
2907 0, &rx_int1_mix2_inp_mux, rx_macro_enable_rx_path_clk,
2908 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2909 SND_SOC_DAPM_MUX_E("RX INT2 MIX2 INP", SND_SOC_NOPM, INTERP_AUX,
2910 0, &rx_int2_mix2_inp_mux, rx_macro_enable_rx_path_clk,
2911 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2912
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05302913 SND_SOC_DAPM_MIXER_E("RX INT2_1 VBAT", SND_SOC_NOPM,
2914 0, 0, rx_int2_1_vbat_mix_switch,
2915 ARRAY_SIZE(rx_int2_1_vbat_mix_switch),
2916 rx_macro_enable_vbat,
2917 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2918
Laxminath Kasama7ecc582018-06-15 16:55:02 +05302919 SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
2920 SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
2921 SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
2922
2923 SND_SOC_DAPM_OUTPUT("HPHL_OUT"),
2924 SND_SOC_DAPM_OUTPUT("HPHR_OUT"),
2925 SND_SOC_DAPM_OUTPUT("AUX_OUT"),
2926
2927 SND_SOC_DAPM_INPUT("RX_TX DEC0_INP"),
2928 SND_SOC_DAPM_INPUT("RX_TX DEC1_INP"),
2929 SND_SOC_DAPM_INPUT("RX_TX DEC2_INP"),
2930 SND_SOC_DAPM_INPUT("RX_TX DEC3_INP"),
2931
2932 SND_SOC_DAPM_SUPPLY_S("RX_MCLK", 0, SND_SOC_NOPM, 0, 0,
2933 rx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2934};
2935
2936static const struct snd_soc_dapm_route rx_audio_map[] = {
2937 {"RX AIF1 PB", NULL, "RX_MCLK"},
2938 {"RX AIF2 PB", NULL, "RX_MCLK"},
2939 {"RX AIF3 PB", NULL, "RX_MCLK"},
2940 {"RX AIF4 PB", NULL, "RX_MCLK"},
2941
2942 {"RX_MACRO RX0 MUX", "AIF1_PB", "RX AIF1 PB"},
2943 {"RX_MACRO RX1 MUX", "AIF1_PB", "RX AIF1 PB"},
2944 {"RX_MACRO RX2 MUX", "AIF1_PB", "RX AIF1 PB"},
2945 {"RX_MACRO RX3 MUX", "AIF1_PB", "RX AIF1 PB"},
2946 {"RX_MACRO RX4 MUX", "AIF1_PB", "RX AIF1 PB"},
2947 {"RX_MACRO RX5 MUX", "AIF1_PB", "RX AIF1 PB"},
2948
2949 {"RX_MACRO RX0 MUX", "AIF2_PB", "RX AIF2 PB"},
2950 {"RX_MACRO RX1 MUX", "AIF2_PB", "RX AIF2 PB"},
2951 {"RX_MACRO RX2 MUX", "AIF2_PB", "RX AIF2 PB"},
2952 {"RX_MACRO RX3 MUX", "AIF2_PB", "RX AIF2 PB"},
2953 {"RX_MACRO RX4 MUX", "AIF2_PB", "RX AIF2 PB"},
2954 {"RX_MACRO RX5 MUX", "AIF2_PB", "RX AIF2 PB"},
2955
2956 {"RX_MACRO RX0 MUX", "AIF3_PB", "RX AIF3 PB"},
2957 {"RX_MACRO RX1 MUX", "AIF3_PB", "RX AIF3 PB"},
2958 {"RX_MACRO RX2 MUX", "AIF3_PB", "RX AIF3 PB"},
2959 {"RX_MACRO RX3 MUX", "AIF3_PB", "RX AIF3 PB"},
2960 {"RX_MACRO RX4 MUX", "AIF3_PB", "RX AIF3 PB"},
2961 {"RX_MACRO RX5 MUX", "AIF3_PB", "RX AIF3 PB"},
2962
2963 {"RX_MACRO RX0 MUX", "AIF4_PB", "RX AIF4 PB"},
2964 {"RX_MACRO RX1 MUX", "AIF4_PB", "RX AIF4 PB"},
2965 {"RX_MACRO RX2 MUX", "AIF4_PB", "RX AIF4 PB"},
2966 {"RX_MACRO RX3 MUX", "AIF4_PB", "RX AIF4 PB"},
2967 {"RX_MACRO RX4 MUX", "AIF4_PB", "RX AIF4 PB"},
2968 {"RX_MACRO RX5 MUX", "AIF4_PB", "RX AIF4 PB"},
2969
2970 {"RX_RX0", NULL, "RX_MACRO RX0 MUX"},
2971 {"RX_RX1", NULL, "RX_MACRO RX1 MUX"},
2972 {"RX_RX2", NULL, "RX_MACRO RX2 MUX"},
2973 {"RX_RX3", NULL, "RX_MACRO RX3 MUX"},
2974 {"RX_RX4", NULL, "RX_MACRO RX4 MUX"},
2975 {"RX_RX5", NULL, "RX_MACRO RX5 MUX"},
2976
2977 {"RX INT0_1 MIX1 INP0", "RX0", "RX_RX0"},
2978 {"RX INT0_1 MIX1 INP0", "RX1", "RX_RX1"},
2979 {"RX INT0_1 MIX1 INP0", "RX2", "RX_RX2"},
2980 {"RX INT0_1 MIX1 INP0", "RX3", "RX_RX3"},
2981 {"RX INT0_1 MIX1 INP0", "RX4", "RX_RX4"},
2982 {"RX INT0_1 MIX1 INP0", "RX5", "RX_RX5"},
2983 {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"},
2984 {"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"},
2985 {"RX INT0_1 MIX1 INP1", "RX0", "RX_RX0"},
2986 {"RX INT0_1 MIX1 INP1", "RX1", "RX_RX1"},
2987 {"RX INT0_1 MIX1 INP1", "RX2", "RX_RX2"},
2988 {"RX INT0_1 MIX1 INP1", "RX3", "RX_RX3"},
2989 {"RX INT0_1 MIX1 INP1", "RX4", "RX_RX4"},
2990 {"RX INT0_1 MIX1 INP1", "RX5", "RX_RX5"},
2991 {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"},
2992 {"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"},
2993 {"RX INT0_1 MIX1 INP2", "RX0", "RX_RX0"},
2994 {"RX INT0_1 MIX1 INP2", "RX1", "RX_RX1"},
2995 {"RX INT0_1 MIX1 INP2", "RX2", "RX_RX2"},
2996 {"RX INT0_1 MIX1 INP2", "RX3", "RX_RX3"},
2997 {"RX INT0_1 MIX1 INP2", "RX4", "RX_RX4"},
2998 {"RX INT0_1 MIX1 INP2", "RX5", "RX_RX5"},
2999 {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"},
3000 {"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"},
3001
3002 {"RX INT1_1 MIX1 INP0", "RX0", "RX_RX0"},
3003 {"RX INT1_1 MIX1 INP0", "RX1", "RX_RX1"},
3004 {"RX INT1_1 MIX1 INP0", "RX2", "RX_RX2"},
3005 {"RX INT1_1 MIX1 INP0", "RX3", "RX_RX3"},
3006 {"RX INT1_1 MIX1 INP0", "RX4", "RX_RX4"},
3007 {"RX INT1_1 MIX1 INP0", "RX5", "RX_RX5"},
3008 {"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"},
3009 {"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"},
3010 {"RX INT1_1 MIX1 INP1", "RX0", "RX_RX0"},
3011 {"RX INT1_1 MIX1 INP1", "RX1", "RX_RX1"},
3012 {"RX INT1_1 MIX1 INP1", "RX2", "RX_RX2"},
3013 {"RX INT1_1 MIX1 INP1", "RX3", "RX_RX3"},
3014 {"RX INT1_1 MIX1 INP1", "RX4", "RX_RX4"},
3015 {"RX INT1_1 MIX1 INP1", "RX5", "RX_RX5"},
3016 {"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"},
3017 {"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"},
3018 {"RX INT1_1 MIX1 INP2", "RX0", "RX_RX0"},
3019 {"RX INT1_1 MIX1 INP2", "RX1", "RX_RX1"},
3020 {"RX INT1_1 MIX1 INP2", "RX2", "RX_RX2"},
3021 {"RX INT1_1 MIX1 INP2", "RX3", "RX_RX3"},
3022 {"RX INT1_1 MIX1 INP2", "RX4", "RX_RX4"},
3023 {"RX INT1_1 MIX1 INP2", "RX5", "RX_RX5"},
3024 {"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"},
3025 {"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"},
3026
3027 {"RX INT2_1 MIX1 INP0", "RX0", "RX_RX0"},
3028 {"RX INT2_1 MIX1 INP0", "RX1", "RX_RX1"},
3029 {"RX INT2_1 MIX1 INP0", "RX2", "RX_RX2"},
3030 {"RX INT2_1 MIX1 INP0", "RX3", "RX_RX3"},
3031 {"RX INT2_1 MIX1 INP0", "RX4", "RX_RX4"},
3032 {"RX INT2_1 MIX1 INP0", "RX5", "RX_RX5"},
3033 {"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"},
3034 {"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"},
3035 {"RX INT2_1 MIX1 INP1", "RX0", "RX_RX0"},
3036 {"RX INT2_1 MIX1 INP1", "RX1", "RX_RX1"},
3037 {"RX INT2_1 MIX1 INP1", "RX2", "RX_RX2"},
3038 {"RX INT2_1 MIX1 INP1", "RX3", "RX_RX3"},
3039 {"RX INT2_1 MIX1 INP1", "RX4", "RX_RX4"},
3040 {"RX INT2_1 MIX1 INP1", "RX5", "RX_RX5"},
3041 {"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"},
3042 {"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"},
3043 {"RX INT2_1 MIX1 INP2", "RX0", "RX_RX0"},
3044 {"RX INT2_1 MIX1 INP2", "RX1", "RX_RX1"},
3045 {"RX INT2_1 MIX1 INP2", "RX2", "RX_RX2"},
3046 {"RX INT2_1 MIX1 INP2", "RX3", "RX_RX3"},
3047 {"RX INT2_1 MIX1 INP2", "RX4", "RX_RX4"},
3048 {"RX INT2_1 MIX1 INP2", "RX5", "RX_RX5"},
3049 {"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"},
3050 {"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"},
3051
3052 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"},
3053 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"},
3054 {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"},
3055 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP0"},
3056 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP1"},
3057 {"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP2"},
3058 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP0"},
3059 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"},
3060 {"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"},
3061
Vatsal Buchac2d6c222018-11-30 18:46:37 +05303062 {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
3063 {"RX MIX TX0 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
3064 {"RX MIX TX0 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
3065 {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
3066 {"RX MIX TX1 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
3067 {"RX MIX TX1 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
3068 {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
3069 {"RX MIX TX2 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
3070 {"RX MIX TX2 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
3071 {"RX AIF_ECHO", NULL, "RX MIX TX0 MUX"},
3072 {"RX AIF_ECHO", NULL, "RX MIX TX1 MUX"},
3073 {"RX AIF_ECHO", NULL, "RX MIX TX2 MUX"},
3074 {"RX AIF_ECHO", NULL, "RX_MCLK"},
3075
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303076 /* Mixing path INT0 */
3077 {"RX INT0_2 MUX", "RX0", "RX_RX0"},
3078 {"RX INT0_2 MUX", "RX1", "RX_RX1"},
3079 {"RX INT0_2 MUX", "RX2", "RX_RX2"},
3080 {"RX INT0_2 MUX", "RX3", "RX_RX3"},
3081 {"RX INT0_2 MUX", "RX4", "RX_RX4"},
3082 {"RX INT0_2 MUX", "RX5", "RX_RX5"},
3083 {"RX INT0_2 INTERP", NULL, "RX INT0_2 MUX"},
3084 {"RX INT0 SEC MIX", NULL, "RX INT0_2 INTERP"},
3085
3086 /* Mixing path INT1 */
3087 {"RX INT1_2 MUX", "RX0", "RX_RX0"},
3088 {"RX INT1_2 MUX", "RX1", "RX_RX1"},
3089 {"RX INT1_2 MUX", "RX2", "RX_RX2"},
3090 {"RX INT1_2 MUX", "RX3", "RX_RX3"},
3091 {"RX INT1_2 MUX", "RX4", "RX_RX4"},
3092 {"RX INT1_2 MUX", "RX5", "RX_RX5"},
3093 {"RX INT1_2 INTERP", NULL, "RX INT1_2 MUX"},
3094 {"RX INT1 SEC MIX", NULL, "RX INT1_2 INTERP"},
3095
3096 /* Mixing path INT2 */
3097 {"RX INT2_2 MUX", "RX0", "RX_RX0"},
3098 {"RX INT2_2 MUX", "RX1", "RX_RX1"},
3099 {"RX INT2_2 MUX", "RX2", "RX_RX2"},
3100 {"RX INT2_2 MUX", "RX3", "RX_RX3"},
3101 {"RX INT2_2 MUX", "RX4", "RX_RX4"},
3102 {"RX INT2_2 MUX", "RX5", "RX_RX5"},
3103 {"RX INT2_2 INTERP", NULL, "RX INT2_2 MUX"},
3104 {"RX INT2 SEC MIX", NULL, "RX INT2_2 INTERP"},
3105
3106 {"RX INT0_1 INTERP", NULL, "RX INT0_1 MIX1"},
3107 {"RX INT0 SEC MIX", NULL, "RX INT0_1 INTERP"},
3108 {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"},
3109 {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"},
3110 {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 MIX2"},
3111 {"HPHL_OUT", NULL, "RX INT0 DEM MUX"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05303112 {"HPHL_OUT", NULL, "RX_MCLK"},
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303113
3114 {"RX INT1_1 INTERP", NULL, "RX INT1_1 MIX1"},
3115 {"RX INT1 SEC MIX", NULL, "RX INT1_1 INTERP"},
3116 {"RX INT1 MIX2", NULL, "RX INT1 SEC MIX"},
3117 {"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"},
3118 {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 MIX2"},
3119 {"HPHR_OUT", NULL, "RX INT1 DEM MUX"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05303120 {"HPHR_OUT", NULL, "RX_MCLK"},
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303121
3122 {"RX INT2_1 INTERP", NULL, "RX INT2_1 MIX1"},
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303123
3124 {"RX INT2_1 VBAT", "RX AUX VBAT Enable", "RX INT2_1 INTERP"},
3125 {"RX INT2 SEC MIX", NULL, "RX INT2_1 VBAT"},
3126
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303127 {"RX INT2 SEC MIX", NULL, "RX INT2_1 INTERP"},
3128 {"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"},
3129 {"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"},
3130 {"AUX_OUT", NULL, "RX INT2 MIX2"},
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05303131 {"AUX_OUT", NULL, "RX_MCLK"},
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303132
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05303133 {"IIR0", NULL, "RX_MCLK"},
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303134 {"IIR0", NULL, "IIR0 INP0 MUX"},
3135 {"IIR0 INP0 MUX", "DEC0", "RX_TX DEC0_INP"},
3136 {"IIR0 INP0 MUX", "DEC1", "RX_TX DEC1_INP"},
3137 {"IIR0 INP0 MUX", "DEC2", "RX_TX DEC2_INP"},
3138 {"IIR0 INP0 MUX", "DEC3", "RX_TX DEC3_INP"},
3139 {"IIR0 INP0 MUX", "RX0", "RX_RX0"},
3140 {"IIR0 INP0 MUX", "RX1", "RX_RX1"},
3141 {"IIR0 INP0 MUX", "RX2", "RX_RX2"},
3142 {"IIR0 INP0 MUX", "RX3", "RX_RX3"},
3143 {"IIR0 INP0 MUX", "RX4", "RX_RX4"},
3144 {"IIR0 INP0 MUX", "RX5", "RX_RX5"},
3145 {"IIR0", NULL, "IIR0 INP1 MUX"},
3146 {"IIR0 INP1 MUX", "DEC0", "RX_TX DEC0_INP"},
3147 {"IIR0 INP1 MUX", "DEC1", "RX_TX DEC1_INP"},
3148 {"IIR0 INP1 MUX", "DEC2", "RX_TX DEC2_INP"},
3149 {"IIR0 INP1 MUX", "DEC3", "RX_TX DEC3_INP"},
3150 {"IIR0 INP1 MUX", "RX0", "RX_RX0"},
3151 {"IIR0 INP1 MUX", "RX1", "RX_RX1"},
3152 {"IIR0 INP1 MUX", "RX2", "RX_RX2"},
3153 {"IIR0 INP1 MUX", "RX3", "RX_RX3"},
3154 {"IIR0 INP1 MUX", "RX4", "RX_RX4"},
3155 {"IIR0 INP1 MUX", "RX5", "RX_RX5"},
3156 {"IIR0", NULL, "IIR0 INP2 MUX"},
3157 {"IIR0 INP2 MUX", "DEC0", "RX_TX DEC0_INP"},
3158 {"IIR0 INP2 MUX", "DEC1", "RX_TX DEC1_INP"},
3159 {"IIR0 INP2 MUX", "DEC2", "RX_TX DEC2_INP"},
3160 {"IIR0 INP2 MUX", "DEC3", "RX_TX DEC3_INP"},
3161 {"IIR0 INP2 MUX", "RX0", "RX_RX0"},
3162 {"IIR0 INP2 MUX", "RX1", "RX_RX1"},
3163 {"IIR0 INP2 MUX", "RX2", "RX_RX2"},
3164 {"IIR0 INP2 MUX", "RX3", "RX_RX3"},
3165 {"IIR0 INP2 MUX", "RX4", "RX_RX4"},
3166 {"IIR0 INP2 MUX", "RX5", "RX_RX5"},
3167 {"IIR0", NULL, "IIR0 INP3 MUX"},
3168 {"IIR0 INP3 MUX", "DEC0", "RX_TX DEC0_INP"},
3169 {"IIR0 INP3 MUX", "DEC1", "RX_TX DEC1_INP"},
3170 {"IIR0 INP3 MUX", "DEC2", "RX_TX DEC2_INP"},
3171 {"IIR0 INP3 MUX", "DEC3", "RX_TX DEC3_INP"},
3172 {"IIR0 INP3 MUX", "RX0", "RX_RX0"},
3173 {"IIR0 INP3 MUX", "RX1", "RX_RX1"},
3174 {"IIR0 INP3 MUX", "RX2", "RX_RX2"},
3175 {"IIR0 INP3 MUX", "RX3", "RX_RX3"},
3176 {"IIR0 INP3 MUX", "RX4", "RX_RX4"},
3177 {"IIR0 INP3 MUX", "RX5", "RX_RX5"},
3178
Laxminath Kasamfc281ad2018-08-06 20:19:40 +05303179 {"IIR1", NULL, "RX_MCLK"},
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303180 {"IIR1", NULL, "IIR1 INP0 MUX"},
3181 {"IIR1 INP0 MUX", "DEC0", "RX_TX DEC0_INP"},
3182 {"IIR1 INP0 MUX", "DEC1", "RX_TX DEC1_INP"},
3183 {"IIR1 INP0 MUX", "DEC2", "RX_TX DEC2_INP"},
3184 {"IIR1 INP0 MUX", "DEC3", "RX_TX DEC3_INP"},
3185 {"IIR1 INP0 MUX", "RX0", "RX_RX0"},
3186 {"IIR1 INP0 MUX", "RX1", "RX_RX1"},
3187 {"IIR1 INP0 MUX", "RX2", "RX_RX2"},
3188 {"IIR1 INP0 MUX", "RX3", "RX_RX3"},
3189 {"IIR1 INP0 MUX", "RX4", "RX_RX4"},
3190 {"IIR1 INP0 MUX", "RX5", "RX_RX5"},
3191 {"IIR1", NULL, "IIR1 INP1 MUX"},
3192 {"IIR1 INP1 MUX", "DEC0", "RX_TX DEC0_INP"},
3193 {"IIR1 INP1 MUX", "DEC1", "RX_TX DEC1_INP"},
3194 {"IIR1 INP1 MUX", "DEC2", "RX_TX DEC2_INP"},
3195 {"IIR1 INP1 MUX", "DEC3", "RX_TX DEC3_INP"},
3196 {"IIR1 INP1 MUX", "RX0", "RX_RX0"},
3197 {"IIR1 INP1 MUX", "RX1", "RX_RX1"},
3198 {"IIR1 INP1 MUX", "RX2", "RX_RX2"},
3199 {"IIR1 INP1 MUX", "RX3", "RX_RX3"},
3200 {"IIR1 INP1 MUX", "RX4", "RX_RX4"},
3201 {"IIR1 INP1 MUX", "RX5", "RX_RX5"},
3202 {"IIR1", NULL, "IIR1 INP2 MUX"},
3203 {"IIR1 INP2 MUX", "DEC0", "RX_TX DEC0_INP"},
3204 {"IIR1 INP2 MUX", "DEC1", "RX_TX DEC1_INP"},
3205 {"IIR1 INP2 MUX", "DEC2", "RX_TX DEC2_INP"},
3206 {"IIR1 INP2 MUX", "DEC3", "RX_TX DEC3_INP"},
3207 {"IIR1 INP2 MUX", "RX0", "RX_RX0"},
3208 {"IIR1 INP2 MUX", "RX1", "RX_RX1"},
3209 {"IIR1 INP2 MUX", "RX2", "RX_RX2"},
3210 {"IIR1 INP2 MUX", "RX3", "RX_RX3"},
3211 {"IIR1 INP2 MUX", "RX4", "RX_RX4"},
3212 {"IIR1 INP2 MUX", "RX5", "RX_RX5"},
3213 {"IIR1", NULL, "IIR1 INP3 MUX"},
3214 {"IIR1 INP3 MUX", "DEC0", "RX_TX DEC0_INP"},
3215 {"IIR1 INP3 MUX", "DEC1", "RX_TX DEC1_INP"},
3216 {"IIR1 INP3 MUX", "DEC2", "RX_TX DEC2_INP"},
3217 {"IIR1 INP3 MUX", "DEC3", "RX_TX DEC3_INP"},
3218 {"IIR1 INP3 MUX", "RX0", "RX_RX0"},
3219 {"IIR1 INP3 MUX", "RX1", "RX_RX1"},
3220 {"IIR1 INP3 MUX", "RX2", "RX_RX2"},
3221 {"IIR1 INP3 MUX", "RX3", "RX_RX3"},
3222 {"IIR1 INP3 MUX", "RX4", "RX_RX4"},
3223 {"IIR1 INP3 MUX", "RX5", "RX_RX5"},
3224
3225 {"SRC0", NULL, "IIR0"},
3226 {"SRC1", NULL, "IIR1"},
3227 {"RX INT0 MIX2 INP", "SRC0", "SRC0"},
3228 {"RX INT0 MIX2 INP", "SRC1", "SRC1"},
3229 {"RX INT1 MIX2 INP", "SRC0", "SRC0"},
3230 {"RX INT1 MIX2 INP", "SRC1", "SRC1"},
3231 {"RX INT2 MIX2 INP", "SRC0", "SRC0"},
3232 {"RX INT2 MIX2 INP", "SRC1", "SRC1"},
3233};
3234
3235static int rx_swrm_clock(void *handle, bool enable)
3236{
3237 struct rx_macro_priv *rx_priv = (struct rx_macro_priv *) handle;
3238 struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL);
3239 int ret = 0;
3240
Tanya Dixit8530fb92018-09-14 16:01:25 +05303241 if (regmap == NULL) {
3242 dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__);
3243 return -EINVAL;
3244 }
3245
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303246 mutex_lock(&rx_priv->swr_clk_lock);
3247
3248 dev_dbg(rx_priv->dev, "%s: swrm clock %s\n",
3249 __func__, (enable ? "enable" : "disable"));
3250 if (enable) {
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303251 pm_runtime_get_sync(rx_priv->dev);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303252 if (rx_priv->swr_clk_users == 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08003253 msm_cdc_pinctrl_select_active_state(
3254 rx_priv->rx_swr_gpio_p);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303255 ret = rx_macro_mclk_enable(rx_priv, 1, true);
3256 if (ret < 0) {
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08003257 msm_cdc_pinctrl_select_sleep_state(
3258 rx_priv->rx_swr_gpio_p);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303259 dev_err(rx_priv->dev,
3260 "%s: rx request clock enable failed\n",
3261 __func__);
3262 goto exit;
3263 }
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05303264 if (rx_priv->reset_swr)
3265 regmap_update_bits(regmap,
3266 BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
3267 0x02, 0x02);
Ramprasad Katkam9c2394a2018-08-23 13:13:48 +05303268 regmap_update_bits(regmap,
3269 BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303270 0x01, 0x01);
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05303271 if (rx_priv->reset_swr)
3272 regmap_update_bits(regmap,
3273 BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
3274 0x02, 0x00);
3275 rx_priv->reset_swr = false;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303276 }
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303277 pm_runtime_mark_last_busy(rx_priv->dev);
3278 pm_runtime_put_autosuspend(rx_priv->dev);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303279 rx_priv->swr_clk_users++;
3280 } else {
3281 if (rx_priv->swr_clk_users <= 0) {
3282 dev_err(rx_priv->dev,
3283 "%s: rx swrm clock users already reset\n",
3284 __func__);
3285 rx_priv->swr_clk_users = 0;
3286 goto exit;
3287 }
3288 rx_priv->swr_clk_users--;
3289 if (rx_priv->swr_clk_users == 0) {
3290 regmap_update_bits(regmap,
3291 BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
3292 0x01, 0x00);
Karthikeyan Mani01f1ba42019-02-26 18:48:15 -08003293 rx_macro_mclk_enable(rx_priv, 0, true);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303294 msm_cdc_pinctrl_select_sleep_state(
3295 rx_priv->rx_swr_gpio_p);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303296 }
3297 }
3298 dev_dbg(rx_priv->dev, "%s: swrm clock users %d\n",
3299 __func__, rx_priv->swr_clk_users);
3300exit:
3301 mutex_unlock(&rx_priv->swr_clk_lock);
3302 return ret;
3303}
3304
Meng Wang15c825d2018-09-06 10:49:18 +08003305static void rx_macro_init_bcl_pmic_reg(struct snd_soc_component *component)
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303306{
3307 struct device *rx_dev = NULL;
3308 struct rx_macro_priv *rx_priv = NULL;
3309
Meng Wang15c825d2018-09-06 10:49:18 +08003310 if (!component) {
3311 pr_err("%s: NULL component pointer!\n", __func__);
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303312 return;
3313 }
3314
Meng Wang15c825d2018-09-06 10:49:18 +08003315 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303316 return;
3317
3318 switch (rx_priv->bcl_pmic_params.id) {
3319 case 0:
3320 /* Enable ID0 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08003321 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303322 BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
3323 /* Update MC_SID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08003324 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303325 BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1, 0x0F,
3326 rx_priv->bcl_pmic_params.sid);
3327 /* Update MC_PPID0 */
Meng Wang15c825d2018-09-06 10:49:18 +08003328 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303329 BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG2, 0xFF,
3330 rx_priv->bcl_pmic_params.ppid);
3331 break;
3332 case 1:
3333 /* Enable ID1 to listen to respective PMIC group interrupts */
Meng Wang15c825d2018-09-06 10:49:18 +08003334 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303335 BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
3336 /* Update MC_SID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08003337 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303338 BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG3, 0x0F,
3339 rx_priv->bcl_pmic_params.sid);
3340 /* Update MC_PPID1 */
Meng Wang15c825d2018-09-06 10:49:18 +08003341 snd_soc_component_update_bits(component,
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303342 BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1, 0xFF,
3343 rx_priv->bcl_pmic_params.ppid);
3344 break;
3345 default:
Md Mansoor Ahmed26d8bdd2018-11-20 10:56:01 +05303346 dev_err(rx_dev, "%s: PMIC ID is invalid %d\n",
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303347 __func__, rx_priv->bcl_pmic_params.id);
3348 break;
3349 }
3350}
3351
Meng Wang15c825d2018-09-06 10:49:18 +08003352static int rx_macro_init(struct snd_soc_component *component)
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303353{
Meng Wang15c825d2018-09-06 10:49:18 +08003354 struct snd_soc_dapm_context *dapm =
3355 snd_soc_component_get_dapm(component);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303356 int ret = 0;
3357 struct device *rx_dev = NULL;
3358 struct rx_macro_priv *rx_priv = NULL;
3359
Meng Wang15c825d2018-09-06 10:49:18 +08003360 rx_dev = bolero_get_device_ptr(component->dev, RX_MACRO);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303361 if (!rx_dev) {
Meng Wang15c825d2018-09-06 10:49:18 +08003362 dev_err(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303363 "%s: null device for macro!\n", __func__);
3364 return -EINVAL;
3365 }
3366 rx_priv = dev_get_drvdata(rx_dev);
3367 if (!rx_priv) {
Meng Wang15c825d2018-09-06 10:49:18 +08003368 dev_err(component->dev,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303369 "%s: priv is null for macro!\n", __func__);
3370 return -EINVAL;
3371 }
3372
3373 ret = snd_soc_dapm_new_controls(dapm, rx_macro_dapm_widgets,
3374 ARRAY_SIZE(rx_macro_dapm_widgets));
3375 if (ret < 0) {
3376 dev_err(rx_dev, "%s: failed to add controls\n", __func__);
3377 return ret;
3378 }
3379 ret = snd_soc_dapm_add_routes(dapm, rx_audio_map,
3380 ARRAY_SIZE(rx_audio_map));
3381 if (ret < 0) {
3382 dev_err(rx_dev, "%s: failed to add routes\n", __func__);
3383 return ret;
3384 }
3385 ret = snd_soc_dapm_new_widgets(dapm->card);
3386 if (ret < 0) {
3387 dev_err(rx_dev, "%s: failed to add widgets\n", __func__);
3388 return ret;
3389 }
Meng Wang15c825d2018-09-06 10:49:18 +08003390 ret = snd_soc_add_component_controls(component, rx_macro_snd_controls,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303391 ARRAY_SIZE(rx_macro_snd_controls));
3392 if (ret < 0) {
3393 dev_err(rx_dev, "%s: failed to add snd_ctls\n", __func__);
3394 return ret;
3395 }
Laxminath Kasam701e3582018-10-15 20:06:09 +05303396 rx_priv->dev_up = true;
Laxminath Kasam638b5602018-09-24 13:19:52 +05303397 snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF1 Playback");
3398 snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF2 Playback");
3399 snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF3 Playback");
3400 snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF4 Playback");
3401 snd_soc_dapm_ignore_suspend(dapm, "HPHL_OUT");
3402 snd_soc_dapm_ignore_suspend(dapm, "HPHR_OUT");
3403 snd_soc_dapm_ignore_suspend(dapm, "AUX_OUT");
3404 snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC0_INP");
3405 snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC1_INP");
3406 snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC2_INP");
3407 snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC3_INP");
3408 snd_soc_dapm_sync(dapm);
3409
Meng Wang15c825d2018-09-06 10:49:18 +08003410 snd_soc_component_update_bits(component,
3411 BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL,
3412 0x01, 0x01);
3413 snd_soc_component_update_bits(component,
3414 BOLERO_CDC_RX_RX1_RX_PATH_DSM_CTL,
3415 0x01, 0x01);
3416 snd_soc_component_update_bits(component,
3417 BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL,
3418 0x01, 0x01);
3419 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX0_RX_PATH_SEC7,
3420 0x07, 0x02);
3421 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX1_RX_PATH_SEC7,
3422 0x07, 0x02);
3423 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX2_RX_PATH_SEC7,
3424 0x07, 0x02);
3425 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX0_RX_PATH_CFG3,
3426 0x03, 0x02);
3427 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX1_RX_PATH_CFG3,
3428 0x03, 0x02);
3429 snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX2_RX_PATH_CFG3,
3430 0x03, 0x02);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303431
Meng Wang15c825d2018-09-06 10:49:18 +08003432 rx_priv->component = component;
Vatsal Bucha39ead2c2018-12-14 12:22:46 +05303433 rx_macro_init_bcl_pmic_reg(component);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303434
3435 return 0;
3436}
3437
Meng Wang15c825d2018-09-06 10:49:18 +08003438static int rx_macro_deinit(struct snd_soc_component *component)
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303439{
3440 struct device *rx_dev = NULL;
3441 struct rx_macro_priv *rx_priv = NULL;
3442
Meng Wang15c825d2018-09-06 10:49:18 +08003443 if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303444 return -EINVAL;
3445
Meng Wang15c825d2018-09-06 10:49:18 +08003446 rx_priv->component = NULL;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303447
3448 return 0;
3449}
3450
3451static void rx_macro_add_child_devices(struct work_struct *work)
3452{
3453 struct rx_macro_priv *rx_priv = NULL;
3454 struct platform_device *pdev = NULL;
3455 struct device_node *node = NULL;
3456 struct rx_swr_ctrl_data *swr_ctrl_data = NULL, *temp = NULL;
3457 int ret = 0;
3458 u16 count = 0, ctrl_num = 0;
3459 struct rx_swr_ctrl_platform_data *platdata = NULL;
3460 char plat_dev_name[RX_SWR_STRING_LEN] = "";
3461 bool rx_swr_master_node = false;
3462
3463 rx_priv = container_of(work, struct rx_macro_priv,
3464 rx_macro_add_child_devices_work);
3465 if (!rx_priv) {
3466 pr_err("%s: Memory for rx_priv does not exist\n",
3467 __func__);
3468 return;
3469 }
3470
3471 if (!rx_priv->dev) {
3472 pr_err("%s: RX device does not exist\n", __func__);
3473 return;
3474 }
3475
3476 if(!rx_priv->dev->of_node) {
3477 dev_err(rx_priv->dev,
3478 "%s: DT node for RX dev does not exist\n", __func__);
3479 return;
3480 }
3481
3482 platdata = &rx_priv->swr_plat_data;
3483 rx_priv->child_count = 0;
3484
3485 for_each_available_child_of_node(rx_priv->dev->of_node, node) {
3486 rx_swr_master_node = false;
3487 if (strnstr(node->name, "rx_swr_master",
3488 strlen("rx_swr_master")) != NULL)
3489 rx_swr_master_node = true;
3490
3491 if(rx_swr_master_node)
3492 strlcpy(plat_dev_name, "rx_swr_ctrl",
3493 (RX_SWR_STRING_LEN - 1));
3494 else
3495 strlcpy(plat_dev_name, node->name,
3496 (RX_SWR_STRING_LEN - 1));
3497
3498 pdev = platform_device_alloc(plat_dev_name, -1);
3499 if (!pdev) {
3500 dev_err(rx_priv->dev, "%s: pdev memory alloc failed\n",
3501 __func__);
3502 ret = -ENOMEM;
3503 goto err;
3504 }
3505 pdev->dev.parent = rx_priv->dev;
3506 pdev->dev.of_node = node;
3507
3508 if (rx_swr_master_node) {
3509 ret = platform_device_add_data(pdev, platdata,
3510 sizeof(*platdata));
3511 if (ret) {
3512 dev_err(&pdev->dev,
3513 "%s: cannot add plat data ctrl:%d\n",
3514 __func__, ctrl_num);
3515 goto fail_pdev_add;
3516 }
3517 }
3518
3519 ret = platform_device_add(pdev);
3520 if (ret) {
3521 dev_err(&pdev->dev,
3522 "%s: Cannot add platform device\n",
3523 __func__);
3524 goto fail_pdev_add;
3525 }
3526
3527 if (rx_swr_master_node) {
3528 temp = krealloc(swr_ctrl_data,
3529 (ctrl_num + 1) * sizeof(
3530 struct rx_swr_ctrl_data),
3531 GFP_KERNEL);
3532 if (!temp) {
3533 ret = -ENOMEM;
3534 goto fail_pdev_add;
3535 }
3536 swr_ctrl_data = temp;
3537 swr_ctrl_data[ctrl_num].rx_swr_pdev = pdev;
3538 ctrl_num++;
3539 dev_dbg(&pdev->dev,
3540 "%s: Added soundwire ctrl device(s)\n",
3541 __func__);
3542 rx_priv->swr_ctrl_data = swr_ctrl_data;
3543 }
3544 if (rx_priv->child_count < RX_MACRO_CHILD_DEVICES_MAX)
3545 rx_priv->pdev_child_devices[
3546 rx_priv->child_count++] = pdev;
3547 else
3548 goto err;
3549 }
3550 return;
3551fail_pdev_add:
3552 for (count = 0; count < rx_priv->child_count; count++)
3553 platform_device_put(rx_priv->pdev_child_devices[count]);
3554err:
3555 return;
3556}
3557
3558static void rx_macro_init_ops(struct macro_ops *ops, char __iomem *rx_io_base)
3559{
3560 memset(ops, 0, sizeof(struct macro_ops));
3561 ops->init = rx_macro_init;
3562 ops->exit = rx_macro_deinit;
3563 ops->io_base = rx_io_base;
3564 ops->dai_ptr = rx_macro_dai;
3565 ops->num_dais = ARRAY_SIZE(rx_macro_dai);
Laxminath Kasam497a6512018-09-17 16:11:52 +05303566 ops->event_handler = rx_macro_event_handler;
Sudheer Papothia3e969d2018-10-27 06:22:10 +05303567 ops->set_port_map = rx_macro_set_port_map;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303568}
3569
3570static int rx_macro_probe(struct platform_device *pdev)
3571{
3572 struct macro_ops ops = {0};
3573 struct rx_macro_priv *rx_priv = NULL;
3574 u32 rx_base_addr = 0, muxsel = 0;
3575 char __iomem *rx_io_base = NULL, *muxsel_io = NULL;
3576 int ret = 0;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303577 u8 bcl_pmic_params[3];
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003578 u32 default_clk_id = 0;
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07003579 u32 is_used_rx_swr_gpio = 1;
3580 const char *is_used_rx_swr_gpio_dt = "qcom,is-used-swr-gpio";
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303581
3582 rx_priv = devm_kzalloc(&pdev->dev, sizeof(struct rx_macro_priv),
3583 GFP_KERNEL);
3584 if (!rx_priv)
3585 return -ENOMEM;
3586
3587 rx_priv->dev = &pdev->dev;
3588 ret = of_property_read_u32(pdev->dev.of_node, "reg",
3589 &rx_base_addr);
3590 if (ret) {
3591 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
3592 __func__, "reg");
3593 return ret;
3594 }
3595 ret = of_property_read_u32(pdev->dev.of_node, "qcom,rx_mclk_mode_muxsel",
3596 &muxsel);
3597 if (ret) {
3598 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
3599 __func__, "reg");
3600 return ret;
3601 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003602 ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
3603 &default_clk_id);
3604 if (ret) {
3605 dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
3606 __func__, "qcom,default-clk-id");
3607 default_clk_id = RX_CORE_CLK;
3608 }
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07003609 if (of_find_property(pdev->dev.of_node, is_used_rx_swr_gpio_dt,
3610 NULL)) {
3611 ret = of_property_read_u32(pdev->dev.of_node,
3612 is_used_rx_swr_gpio_dt,
3613 &is_used_rx_swr_gpio);
3614 if (ret) {
3615 dev_err(&pdev->dev, "%s: error reading %s in dt\n",
3616 __func__, is_used_rx_swr_gpio_dt);
3617 is_used_rx_swr_gpio = 1;
3618 }
3619 }
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303620 rx_priv->rx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
3621 "qcom,rx-swr-gpios", 0);
Karthikeyan Mani3bd80a52019-06-04 23:40:16 -07003622 if (!rx_priv->rx_swr_gpio_p && is_used_rx_swr_gpio) {
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303623 dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
3624 __func__);
3625 return -EINVAL;
3626 }
3627 rx_io_base = devm_ioremap(&pdev->dev, rx_base_addr,
3628 RX_MACRO_MAX_OFFSET);
3629 if (!rx_io_base) {
3630 dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
3631 return -ENOMEM;
3632 }
3633 rx_priv->rx_io_base = rx_io_base;
3634 muxsel_io = devm_ioremap(&pdev->dev, muxsel, 0x4);
3635 if (!muxsel_io) {
3636 dev_err(&pdev->dev, "%s: ioremap failed for muxsel\n",
3637 __func__);
3638 return -ENOMEM;
3639 }
3640 rx_priv->rx_mclk_mode_muxsel = muxsel_io;
Ramprasad Katkama4c747b2018-12-11 19:15:53 +05303641 rx_priv->reset_swr = true;
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303642 INIT_WORK(&rx_priv->rx_macro_add_child_devices_work,
3643 rx_macro_add_child_devices);
3644 rx_priv->swr_plat_data.handle = (void *) rx_priv;
3645 rx_priv->swr_plat_data.read = NULL;
3646 rx_priv->swr_plat_data.write = NULL;
3647 rx_priv->swr_plat_data.bulk_write = NULL;
3648 rx_priv->swr_plat_data.clk = rx_swrm_clock;
3649 rx_priv->swr_plat_data.handle_irq = NULL;
3650
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303651 ret = of_property_read_u8_array(pdev->dev.of_node,
3652 "qcom,rx-bcl-pmic-params", bcl_pmic_params,
3653 sizeof(bcl_pmic_params));
3654 if (ret) {
3655 dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
3656 __func__, "qcom,rx-bcl-pmic-params");
3657 } else {
3658 rx_priv->bcl_pmic_params.id = bcl_pmic_params[0];
3659 rx_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
3660 rx_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
3661 }
Vidyakumar Athota5d45f4c2019-03-10 22:35:07 -07003662 rx_priv->clk_id = default_clk_id;
3663 rx_priv->default_clk_id = default_clk_id;
3664 ops.clk_id_req = rx_priv->clk_id;
3665 ops.default_clk_id = default_clk_id;
Aditya Bavanari4f3d5642018-09-18 22:19:10 +05303666
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303667 dev_set_drvdata(&pdev->dev, rx_priv);
3668 mutex_init(&rx_priv->mclk_lock);
3669 mutex_init(&rx_priv->swr_clk_lock);
3670 rx_macro_init_ops(&ops, rx_io_base);
3671
3672 ret = bolero_register_macro(&pdev->dev, RX_MACRO, &ops);
3673 if (ret) {
3674 dev_err(&pdev->dev,
3675 "%s: register macro failed\n", __func__);
3676 goto err_reg_macro;
3677 }
3678 schedule_work(&rx_priv->rx_macro_add_child_devices_work);
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303679 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
3680 pm_runtime_use_autosuspend(&pdev->dev);
3681 pm_runtime_set_suspended(&pdev->dev);
3682 pm_runtime_enable(&pdev->dev);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303683
3684 return 0;
3685
3686err_reg_macro:
3687 mutex_destroy(&rx_priv->mclk_lock);
3688 mutex_destroy(&rx_priv->swr_clk_lock);
3689 return ret;
3690}
3691
3692static int rx_macro_remove(struct platform_device *pdev)
3693{
3694 struct rx_macro_priv *rx_priv = NULL;
3695 u16 count = 0;
3696
3697 rx_priv = dev_get_drvdata(&pdev->dev);
3698
3699 if (!rx_priv)
3700 return -EINVAL;
3701
3702 for (count = 0; count < rx_priv->child_count &&
3703 count < RX_MACRO_CHILD_DEVICES_MAX; count++)
3704 platform_device_unregister(rx_priv->pdev_child_devices[count]);
3705
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303706 pm_runtime_disable(&pdev->dev);
3707 pm_runtime_set_suspended(&pdev->dev);
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303708 bolero_unregister_macro(&pdev->dev, RX_MACRO);
3709 mutex_destroy(&rx_priv->mclk_lock);
3710 mutex_destroy(&rx_priv->swr_clk_lock);
3711 kfree(rx_priv->swr_ctrl_data);
3712 return 0;
3713}
3714
3715static const struct of_device_id rx_macro_dt_match[] = {
3716 {.compatible = "qcom,rx-macro"},
3717 {}
3718};
3719
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303720static const struct dev_pm_ops bolero_dev_pm_ops = {
3721 SET_RUNTIME_PM_OPS(
3722 bolero_runtime_suspend,
3723 bolero_runtime_resume,
3724 NULL
3725 )
3726};
3727
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303728static struct platform_driver rx_macro_driver = {
3729 .driver = {
3730 .name = "rx_macro",
3731 .owner = THIS_MODULE,
Sudheer Papothi7601cc62019-03-30 03:00:52 +05303732 .pm = &bolero_dev_pm_ops,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303733 .of_match_table = rx_macro_dt_match,
Xiaojun Sang53cd13a2018-06-29 15:14:37 +08003734 .suppress_bind_attrs = true,
Laxminath Kasama7ecc582018-06-15 16:55:02 +05303735 },
3736 .probe = rx_macro_probe,
3737 .remove = rx_macro_remove,
3738};
3739
3740module_platform_driver(rx_macro_driver);
3741
3742MODULE_DESCRIPTION("RX macro driver");
3743MODULE_LICENSE("GPL v2");