2 * rk3190_codec.c -- RK3190 CODEC ALSA SoC audio driver
4 * Copyright 2013 Rockchip
5 * Author: zhangjun <showy.zhang@rock-chips.com>
8 #include <linux/module.h>
9 #include <linux/moduleparam.h>
10 #include <linux/init.h>
11 #include <linux/delay.h>
13 #include <linux/i2c.h>
14 #include <linux/platform_device.h>
15 #include <linux/spi/spi.h>
16 #include <linux/gpio.h>
17 #include <linux/clk.h>
18 #include <sound/core.h>
19 #include <sound/pcm.h>
20 #include <sound/pcm_params.h>
21 #include <sound/soc.h>
22 #include <sound/soc-dapm.h>
23 #include <sound/initval.h>
24 #include <sound/tlv.h>
27 #include "rk3190_codec.h"
29 #ifdef CONFIG_RK_HEADSET_DET
30 #include "../../../drivers/headset_observe/rk_headset.h"
34 #define DBG(x...) printk(KERN_INFO x)
45 #define OUT_VOLUME 26//0~31
53 #define CAP_VOL 18//0-31
55 //with capacity or not
57 #define SPK_AMP_DELAY 200
58 #define HP_MOS_DELAY 200
59 #ifdef CONFIG_MACH_RK_FAC
65 #define INVALID_GPIO -1
67 struct rk3190_codec_priv {
68 struct snd_soc_codec *codec;
70 unsigned int stereo_sysclk;
82 long int playback_path;
83 long int capture_path;
84 long int voice_call_path;
92 static struct rk3190_codec_priv *rk3190_priv = NULL;
94 #define RK3190_CODEC_ALL 0
95 #define RK3190_CODEC_PLAYBACK 1
96 #define RK3190_CODEC_CAPTURE 2
97 #define RK3190_CODEC_INCALL 3
99 static bool rk3190_for_mid = 1;
101 static const unsigned int rk3190_reg_defaults[RK3190_PGA_AGC_CTL5+1] = {
102 [RK3190_RESET] = 0x0003,
103 [RK3190_ADC_INT_CTL1] = 0x0050,
104 [RK3190_ADC_INT_CTL2] = 0x000e,
105 [RK3190_DAC_INT_CTL1] = 0x0050,
106 [RK3190_DAC_INT_CTL2] = 0x000e,
107 [RK3190_BIST_CTL] = 0x0000,
108 [RK3190_SELECT_CURRENT] = 0x0001,
109 [RK3190_BIAS_CTL] = 0x0000,
110 [RK3190_ADC_CTL] = 0x0000,
111 [RK3190_BST_CTL] = 0x0000,
112 [RK3190_ALC_MUNIN_CTL] = 0x0044,
113 [RK3190_ALCL_GAIN_CTL] = 0x000c,
114 [RK3190_ALCR_GAIN_CTL] = 0x000c,
115 [RK3190_ADC_ENABLE] = 0x0000,
116 [RK3190_DAC_CTL] = 0x0000,
117 [RK3190_DAC_ENABLE] = 0x0000,
118 [RK3190_HPMIX_CTL] = 0x0000,
119 [RK3190_HPMIX_S_SELECT] = 0x0000,
120 [RK3190_HPOUT_CTL] = 0x0000,
121 [RK3190_HPOUTL_GAIN] = 0x0000,
122 [RK3190_HPOUTR_GAIN] = 0x0000,
123 [RK3190_PGA_AGC_CTL1] = 0x0000,
124 [RK3190_PGA_AGC_CTL2] = 0x0046,
125 [RK3190_PGA_AGC_CTL3] = 0x0041,
126 [RK3190_PGA_AGC_CTL4] = 0x002c,
127 [RK3190_PGA_ASR_CTL] = 0x0000,
128 [RK3190_PGA_AGC_MAX_H] = 0x0026,
129 [RK3190_PGA_AGC_MAX_L] = 0x0040,
130 [RK3190_PGA_AGC_MIN_H] = 0x0036,
131 [RK3190_PGA_AGC_MIN_L] = 0x0020,
132 [RK3190_PGA_AGC_CTL5] = 0x0038,
135 static struct rk3190_init_bit_typ rk3190_init_bit_list[] = {
136 {RK3190_HPOUT_CTL, RK3190_HPOUTL_EN, RK3190_HPOUTL_WORK,RK3190_HPVREF_EN},
137 {RK3190_HPOUT_CTL, RK3190_HPOUTR_EN, RK3190_HPOUTR_WORK,RK3190_HPVREF_WORK},
138 {RK3190_HPMIX_CTL, RK3190_HPMIXR_EN, RK3190_HPMIXR_WORK2,RK3190_HPMIXR_WORK1},
139 {RK3190_HPMIX_CTL, RK3190_HPMIXL_EN, RK3190_HPMIXL_WORK2,RK3190_HPMIXL_WORK1},
142 #define RK3190_INIT_BIT_LIST_LEN ARRAY_SIZE(rk3190_init_bit_list)
144 static int rk3190_init_bit_register(unsigned int reg, int i)
146 for (; i < RK3190_INIT_BIT_LIST_LEN; i++) {
147 if (rk3190_init_bit_list[i].reg == reg)
154 static unsigned int rk3190_codec_read(struct snd_soc_codec *codec, unsigned int reg);
155 static inline void rk3190_write_reg_cache(struct snd_soc_codec *codec,
156 unsigned int reg, unsigned int value);
158 static unsigned int rk3190_set_init_value(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
160 unsigned int read_value, power_bit, set_bit2,set_bit1;
163 // read codec init register
164 i = rk3190_init_bit_register(reg, 0);
166 // set codec init bit
167 // widget init bit should be setted 0 after widget power up or unmute,
168 // and should be setted 1 after widget power down or mute.
170 read_value = rk3190_codec_read(codec, reg);
172 power_bit = rk3190_init_bit_list[i].power_bit;
173 set_bit2 = rk3190_init_bit_list[i].init2_bit;
174 set_bit1 = rk3190_init_bit_list[i].init1_bit;
176 if ((read_value & power_bit) != (value & power_bit))
178 if (value & power_bit)
180 tmp = value | set_bit2 | set_bit1;
181 writel(value, rk3190_priv->regbase+reg);
182 writel(tmp, rk3190_priv->regbase+reg);
187 tmp = value & (~set_bit2) & (~set_bit1);
188 writel(tmp, rk3190_priv->regbase+reg);
189 writel(value, rk3190_priv->regbase+reg);
195 if (read_value != value)
196 writel(value, rk3190_priv->regbase+reg);
199 i = rk3190_init_bit_register(reg, ++i);
201 rk3190_write_reg_cache(codec, reg, value);
212 static int rk3190_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
222 static int rk3190_codec_register(struct snd_soc_codec *codec, unsigned int reg)
226 case RK3190_ADC_INT_CTL1:
227 case RK3190_ADC_INT_CTL2:
228 case RK3190_DAC_INT_CTL1:
229 case RK3190_DAC_INT_CTL2:
230 case RK3190_BIST_CTL:
231 case RK3190_SELECT_CURRENT:
232 case RK3190_BIAS_CTL:
235 case RK3190_ALC_MUNIN_CTL:
236 case RK3190_ALCL_GAIN_CTL:
237 case RK3190_ALCR_GAIN_CTL:
238 case RK3190_ADC_ENABLE:
240 case RK3190_DAC_ENABLE:
241 case RK3190_HPMIX_CTL:
242 case RK3190_HPMIX_S_SELECT:
243 case RK3190_HPOUT_CTL:
244 case RK3190_HPOUTL_GAIN:
245 case RK3190_HPOUTR_GAIN:
246 case RK3190_PGA_AGC_CTL1:
247 case RK3190_PGA_AGC_CTL2:
248 case RK3190_PGA_AGC_CTL3:
249 case RK3190_PGA_AGC_CTL4:
250 case RK3190_PGA_ASR_CTL:
251 case RK3190_PGA_AGC_MAX_H:
252 case RK3190_PGA_AGC_MAX_L:
253 case RK3190_PGA_AGC_MIN_H:
254 case RK3190_PGA_AGC_MIN_L:
255 case RK3190_PGA_AGC_CTL5:
262 static inline unsigned int rk3190_read_reg_cache(struct snd_soc_codec *codec,
265 unsigned int *cache = codec->reg_cache;
267 if (rk3190_codec_register(codec, reg) )
270 printk("%s : reg error!\n", __func__);
275 static inline void rk3190_write_reg_cache(struct snd_soc_codec *codec,
276 unsigned int reg, unsigned int value)
278 unsigned int *cache = codec->reg_cache;
280 if (rk3190_codec_register(codec, reg)) {
285 printk("%s : reg error!\n", __func__);
288 static unsigned int rk3190_codec_read(struct snd_soc_codec *codec, unsigned int reg)
293 printk("%s : rk3190 is NULL\n", __func__);
297 if (!rk3190_codec_register(codec, reg)) {
298 printk("%s : reg error!\n", __func__);
302 if (rk3190_volatile_register(codec, reg) == 0) {
303 value = rk3190_read_reg_cache(codec, reg);
305 value = readl_relaxed(rk3190_priv->regbase+reg);
308 value = readl_relaxed(rk3190_priv->regbase+reg);
309 DBG("%s : reg = 0x%x, val= 0x%x\n", __func__, reg, value);
314 static int rk3190_codec_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
319 printk("%s : rk3190 is NULL\n", __func__);
321 } else if (!rk3190_codec_register(codec, reg)) {
322 printk("%s : reg error!\n", __func__);
326 //new_value = rk3190_set_init_value(codec, reg, value);
330 writel(value, rk3190_priv->regbase+reg);
331 rk3190_write_reg_cache(codec, reg, value);
334 DBG("%s : reg = 0x%x, val = 0x%x, new_value=%d\n", __func__, reg, value,new_value);
338 static int rk3190_hw_write(const struct i2c_client *client, const char *buf, int count)
340 unsigned int reg, value;
342 if (!rk3190_priv || !rk3190_priv->codec) {
343 printk("%s : rk3190_priv or rk3190_priv->codec is NULL\n", __func__);
348 reg = (unsigned int)buf[0];
349 value = (buf[1] & 0xff00) | (0x00ff & buf[2]);
350 writel(value, rk3190_priv->regbase+reg);
352 printk("%s : i2c len error\n", __func__);
358 static int rk3190_reset(struct snd_soc_codec *codec)
360 writel(0x00, rk3190_priv->regbase+RK3190_RESET);
362 writel(0x03, rk3190_priv->regbase+RK3190_RESET);
365 memcpy(codec->reg_cache, rk3190_reg_defaults,
366 sizeof(rk3190_reg_defaults));
371 int rk3190_headset_mic_detect(bool headset_status)
374 struct snd_soc_codec *codec = rk3190_priv->codec;
376 DBG("%s\n", __func__);
378 if (!rk3190_priv || !rk3190_priv->codec) {
379 printk("%s : rk3190_priv or rk3190_priv->codec is NULL\n", __func__);
383 if (headset_status) {
384 snd_soc_update_bits(codec, RK3190_ADC_MIC_CTL,
385 RK3190_MICBIAS2_PWRD | RK3190_MICBIAS2_V_MASK,
386 RK3190_MICBIAS2_V_1_7);
387 } else {// headset is out, disable MIC2 && MIC1 Bias
388 DBG("%s : headset is out,disable Mic2 Bias\n", __func__);
389 snd_soc_update_bits(codec, RK3190_ADC_MIC_CTL,
390 RK3190_MICBIAS2_PWRD | RK3190_MICBIAS2_V_MASK,
391 RK3190_MICBIAS2_V_1_0|RK3190_MICBIAS2_PWRD);
396 EXPORT_SYMBOL(rk3190_headset_mic_detect);
399 static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -3900, 150, 0);
400 static const DECLARE_TLV_DB_SCALE(pga_vol_tlv, -1800, 150, 0);
401 static const DECLARE_TLV_DB_SCALE(bst_vol_tlv, 0, 2000, 0);
402 static const DECLARE_TLV_DB_SCALE(pga_agc_max_vol_tlv, -1350, 600, 0);
403 static const DECLARE_TLV_DB_SCALE(pga_agc_min_vol_tlv, -1800, 600, 0);
405 static const char *rk3190_input_mode[] = {"Differential","Single-Ended"};
407 static const char *rk3190_micbias_ratio[] = {"1.0 Vref", "1.1 Vref",
408 "1.2 Vref", "1.3 Vref", "1.4 Vref", "1.5 Vref", "1.6 Vref", "1.7 Vref",};
410 static const char *rk3190_dis_en_sel[] = {"Disable", "Enable"};
412 static const char *rk3190_pga_agc_way[] = {"Normal", "Jack"};
414 static const char *rk3190_agc_backup_way[] = {"Normal", "Jack1", "Jack2", "Jack3"};
416 static const char *rk3190_pga_agc_hold_time[] = {"0ms", "2ms",
417 "4ms", "8ms", "16ms", "32ms", "64ms", "128ms", "256ms", "512ms", "1s"};
419 static const char *rk3190_pga_agc_ramp_up_time[] = {"Normal:500us Jack:125us",
420 "Normal:1ms Jack:250us", "Normal:2ms Jack:500us", "Normal:4ms Jack:1ms",
421 "Normal:8ms Jack:2ms", "Normal:16ms Jack:4ms", "Normal:32ms Jack:8ms",
422 "Normal:64ms Jack:16ms", "Normal:128ms Jack:32ms", "Normal:256ms Jack:64ms",
423 "Normal:512ms Jack:128ms"};
425 static const char *rk3190_pga_agc_ramp_down_time[] = {"Normal:125us Jack:32us",
426 "Normal:250us Jack:64us", "Normal:500us Jack:125us", "Normal:1ms Jack:250us",
427 "Normal:2ms Jack:500us", "Normal:4ms Jack:1ms", "Normal:8ms Jack:2ms",
428 "Normal:16ms Jack:4ms", "Normal:32ms Jack:8ms", "Normal:64ms Jack:16ms",
429 "Normal:128ms Jack:32ms"};
431 static const char *rk3190_pga_agc_mode[] = {"Normal", "Limiter"};
433 static const char *rk3190_pga_agc_recovery_mode[] = {"Right Now", "After AGC to Limiter"};
435 static const char *rk3190_pga_agc_noise_gate_threhold[] = {"-39dB", "-45dB", "-51dB",
436 "-57dB", "-63dB", "-69dB", "-75dB", "-81dB"};
438 static const char *rk3190_pga_agc_update_gain[] = {"Right Now", "After 1st Zero Cross"};
440 static const char *rk3190_pga_agc_approximate_sample_rate[] = {"96KHZ","48KHz","441KHZ", "32KHz",
441 "24KHz", "16KHz", "12KHz", "8KHz"};
443 static const struct soc_enum rk3190_bst_enum[] = {
444 SOC_ENUM_SINGLE(RK3190_BSTL_ALCL_CTL, RK3190_BSTL_MODE_SFT, 2, rk3190_input_mode),
448 static const struct soc_enum rk3190_micbias_enum[] = {
449 SOC_ENUM_SINGLE(RK3190_ADC_MIC_CTL, RK3190_MICBIAS_VOL_SHT, 8, rk3190_micbias_ratio),
452 static const struct soc_enum rk3190_agcl_enum[] = {
453 SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL1, RK3190_PGA_AGC_BK_WAY_SFT, 4, rk3190_agc_backup_way),/*0*/
454 SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL1, RK3190_PGA_AGC_WAY_SFT, 2, rk3190_pga_agc_way),/*1*/
455 SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL1, RK3190_PGA_AGC_HOLD_T_SFT, 11, rk3190_pga_agc_hold_time),/*2*/
456 SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL2, RK3190_PGA_AGC_GRU_T_SFT, 11, rk3190_pga_agc_ramp_up_time),/*3*/
457 SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL2, RK3190_PGA_AGC_GRD_T_SFT, 11, rk3190_pga_agc_ramp_down_time),/*4*/
458 SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL3, RK3190_PGA_AGC_MODE_SFT, 2, rk3190_pga_agc_mode),/*5*/
459 SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL3, RK3190_PGA_AGC_ZO_SFT, 2, rk3190_dis_en_sel),/*6*/
460 SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL3, RK3190_PGA_AGC_REC_MODE_SFT, 2, rk3190_pga_agc_recovery_mode),/*7*/
461 SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL3, RK3190_PGA_AGC_FAST_D_SFT, 2, rk3190_dis_en_sel),/*8*/
462 SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL3, RK3190_PGA_AGC_NG_SFT, 2, rk3190_dis_en_sel),/*9*/
463 SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL3, RK3190_PGA_AGC_NG_THR_SFT, 8, rk3190_pga_agc_noise_gate_threhold),/*10*/
464 SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL4, RK3190_PGA_AGC_ZO_MODE_SFT, 2, rk3190_pga_agc_update_gain),/*11*/
465 SOC_ENUM_SINGLE(RK3190_PGAL_ASR_CTL, RK3190_PGA_SLOW_CLK_SFT, 2, rk3190_dis_en_sel),/*12*/
466 SOC_ENUM_SINGLE(RK3190_PGAL_ASR_CTL, RK3190_PGA_ASR_SFT, 8, rk3190_pga_agc_approximate_sample_rate),/*13*/
467 SOC_ENUM_SINGLE(RK3190_PGAL_AGC_CTL5, RK3190_PGA_AGC_SFT, 2, rk3190_dis_en_sel),/*14*/
470 static const struct soc_enum rk3190_agcr_enum[] = {
471 SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL1, RK3190_PGA_AGC_BK_WAY_SFT, 4, rk3190_agc_backup_way),/*0*/
472 SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL1, RK3190_PGA_AGC_WAY_SFT, 2, rk3190_pga_agc_way),/*1*/
473 SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL1, RK3190_PGA_AGC_HOLD_T_SFT, 11, rk3190_pga_agc_hold_time),/*2*/
474 SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL2, RK3190_PGA_AGC_GRU_T_SFT, 11, rk3190_pga_agc_ramp_up_time),/*3*/
475 SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL2, RK3190_PGA_AGC_GRD_T_SFT, 11, rk3190_pga_agc_ramp_down_time),/*4*/
476 SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL3, RK3190_PGA_AGC_MODE_SFT, 2, rk3190_pga_agc_mode),/*5*/
477 SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL3, RK3190_PGA_AGC_ZO_SFT, 2, rk3190_dis_en_sel),/*6*/
478 SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL3, RK3190_PGA_AGC_REC_MODE_SFT, 2, rk3190_pga_agc_recovery_mode),/*7*/
479 SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL3, RK3190_PGA_AGC_FAST_D_SFT, 2, rk3190_dis_en_sel),/*8*/
480 SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL3, RK3190_PGA_AGC_NG_SFT, 2, rk3190_dis_en_sel),/*9*/
481 SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL3, RK3190_PGA_AGC_NG_THR_SFT, 8, rk3190_pga_agc_noise_gate_threhold),/*10*/
482 SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL4, RK3190_PGA_AGC_ZO_MODE_SFT, 2, rk3190_pga_agc_update_gain),/*11*/
483 SOC_ENUM_SINGLE(RK3190_PGAR_ASR_CTL, RK3190_PGA_SLOW_CLK_SFT, 2, rk3190_dis_en_sel),/*12*/
484 SOC_ENUM_SINGLE(RK3190_PGAR_ASR_CTL, RK3190_PGA_ASR_SFT, 8, rk3190_pga_agc_approximate_sample_rate),/*13*/
485 SOC_ENUM_SINGLE(RK3190_PGAR_AGC_CTL5, RK3190_PGA_AGC_SFT, 2, rk3190_dis_en_sel),/*14*/
488 static const struct snd_kcontrol_new rk3190_snd_controls[] = {
489 //Add for set voice volume
490 SOC_DOUBLE_R_TLV("Speaker Playback Volume", RK3190_HPOUTL_GAIN,
491 RK3190_HPOUTR_GAIN, RK3190_HPOUT_GAIN_SFT, 31, 0, out_vol_tlv),
492 SOC_DOUBLE("Speaker Playback Switch", RK3190_HPOUT_CTL,
493 RK3190_HPOUTL_MUTE_SHT, RK3190_HPOUTR_MUTE_SHT, 1, 0),
494 SOC_DOUBLE_R_TLV("Headphone Playback Volume", RK3190_HPOUTL_GAIN,
495 RK3190_HPOUTR_GAIN, RK3190_HPOUT_GAIN_SFT, 31, 0, out_vol_tlv),
496 SOC_DOUBLE("Headphone Playback Switch", RK3190_HPOUT_CTL,
497 RK3190_HPOUTL_MUTE_SHT, RK3190_HPOUTR_MUTE_SHT, 1, 0),
498 SOC_DOUBLE_R_TLV("Earpiece Playback Volume", RK3190_HPOUTL_GAIN,
499 RK3190_HPOUTR_GAIN, RK3190_HPOUT_GAIN_SFT, 31, 0, out_vol_tlv),
500 SOC_DOUBLE("Earpiece Playback Switch", RK3190_HPOUT_CTL,
501 RK3190_HPOUTL_MUTE_SHT, RK3190_HPOUTR_MUTE_SHT, 1, 0),
504 //Add for set capture mute
505 SOC_SINGLE_TLV("Main Mic Capture Volume", RK3190_BST_CTL,
506 RK3190_BSTL_GAIN_SHT, 1, 0, bst_vol_tlv),
507 SOC_SINGLE("Main Mic Capture Switch", RK3190_BST_CTL,
508 RK3190_BSTL_MUTE_SHT, 1, 0),
509 SOC_SINGLE_TLV("Headset Mic Capture Volume", RK3190_BST_CTL,
510 RK3190_BSTR_GAIN_SHT, 1, 0, bst_vol_tlv),
511 SOC_SINGLE("Headset Mic Capture Switch", RK3190_BST_CTL,
512 RK3190_BSTR_MUTE_SHT, 1, 0),
514 SOC_SINGLE("ALCL Switch", RK3190_ALC_MUNIN_CTL,
515 RK3190_ALCL_MUTE_SHT, 1, 0),
516 SOC_SINGLE_TLV("ALCL Capture Volume", RK3190_BSTL_ALCL_CTL,
517 RK3190_ALCL_GAIN_SHT, 31, 0, pga_vol_tlv),
518 SOC_SINGLE("ALCR Switch", RK3190_ALC_MUNIN_CTL,
519 RK3190_ALCR_MUTE_SHT, 1, 0),
520 SOC_SINGLE_TLV("ALCR Capture Volume", RK3190_ALCR_GAIN_CTL,
521 RK3190_ALCL_GAIN_SHT, 31, 0, pga_vol_tlv),
523 SOC_ENUM("BST_L Mode", rk3190_bst_enum[0]),
525 SOC_ENUM("Micbias Voltage", rk3190_micbias_enum[0]),
526 SOC_ENUM("PGAL AGC Back Way", rk3190_agcl_enum[0]),
527 SOC_ENUM("PGAL AGC Way", rk3190_agcl_enum[1]),
528 SOC_ENUM("PGAL AGC Hold Time", rk3190_agcl_enum[2]),
529 SOC_ENUM("PGAL AGC Ramp Up Time", rk3190_agcl_enum[3]),
530 SOC_ENUM("PGAL AGC Ramp Down Time", rk3190_agcl_enum[4]),
531 SOC_ENUM("PGAL AGC Mode", rk3190_agcl_enum[5]),
532 SOC_ENUM("PGAL AGC Gain Update Zero Enable", rk3190_agcl_enum[6]),
533 SOC_ENUM("PGAL AGC Gain Recovery LPGA VOL", rk3190_agcl_enum[7]),
534 SOC_ENUM("PGAL AGC Fast Decrement Enable", rk3190_agcl_enum[8]),
535 SOC_ENUM("PGAL AGC Noise Gate Enable", rk3190_agcl_enum[9]),
536 SOC_ENUM("PGAL AGC Noise Gate Threhold", rk3190_agcl_enum[10]),
537 SOC_ENUM("PGAL AGC Upate Gain", rk3190_agcl_enum[11]),
538 SOC_ENUM("PGAL AGC Slow Clock Enable", rk3190_agcl_enum[12]),
539 SOC_ENUM("PGAL AGC Approximate Sample Rate", rk3190_agcl_enum[13]),
540 SOC_ENUM("PGAL AGC Enable", rk3190_agcl_enum[14]),
542 SOC_SINGLE_TLV("PGAL AGC Volume", RK3190_PGAL_AGC_CTL4,
543 RK3190_PGA_AGC_VOL_SFT, 31, 0, pga_vol_tlv),//AGC disable and 0x0a bit 5 is 1
545 SOC_SINGLE("PGAL AGC Max Level High 8 Bits", RK3190_PGAL_AGC_MAX_H,
547 SOC_SINGLE("PGAL AGC Max Level Low 8 Bits", RK3190_PGAL_AGC_MAX_L,
549 SOC_SINGLE("PGAL AGC Min Level High 8 Bits", RK3190_PGAL_AGC_MIN_H,
551 SOC_SINGLE("PGAL AGC Min Level Low 8 Bits", RK3190_PGAL_AGC_MIN_L,
554 SOC_SINGLE_TLV("PGAL AGC Max Gain", RK3190_PGAL_AGC_CTL5,
555 RK3190_PGA_AGC_MAX_G_SFT, 7, 0, pga_agc_max_vol_tlv),//AGC enable and 0x0a bit 5 is 1
556 SOC_SINGLE_TLV("PGAL AGC Min Gain", RK3190_PGAL_AGC_CTL5,
557 RK3190_PGA_AGC_MIN_G_SFT, 7, 0, pga_agc_min_vol_tlv),//AGC enable and 0x0a bit 5 is 1
559 SOC_ENUM("PGAR AGC Back Way", rk3190_agcr_enum[0]),
560 SOC_ENUM("PGAR AGC Way", rk3190_agcr_enum[1]),
561 SOC_ENUM("PGAR AGC Hold Time", rk3190_agcr_enum[2]),
562 SOC_ENUM("PGAR AGC Ramp Up Time", rk3190_agcr_enum[3]),
563 SOC_ENUM("PGAR AGC Ramp Down Time", rk3190_agcr_enum[4]),
564 SOC_ENUM("PGAR AGC Mode", rk3190_agcr_enum[5]),
565 SOC_ENUM("PGAR AGC Gain Update Zero Enable", rk3190_agcr_enum[6]),
566 SOC_ENUM("PGAR AGC Gain Recovery LPGA VOL", rk3190_agcr_enum[7]),
567 SOC_ENUM("PGAR AGC Fast Decrement Enable", rk3190_agcr_enum[8]),
568 SOC_ENUM("PGAR AGC Noise Gate Enable", rk3190_agcr_enum[9]),
569 SOC_ENUM("PGAR AGC Noise Gate Threhold", rk3190_agcr_enum[10]),
570 SOC_ENUM("PGAR AGC Upate Gain", rk3190_agcr_enum[11]),
571 SOC_ENUM("PGAR AGC Slow Clock Enable", rk3190_agcr_enum[12]),
572 SOC_ENUM("PGAR AGC Approximate Sample Rate", rk3190_agcr_enum[13]),
573 SOC_ENUM("PGAR AGC Enable", rk3190_agcr_enum[14]),
575 SOC_SINGLE_TLV("PGAR AGC Volume", RK3190_PGAR_AGC_CTL4,
576 RK3190_PGA_AGC_VOL_SFT, 31, 0, pga_vol_tlv),//AGC disable and 0x0a bit 4 is 1
578 SOC_SINGLE("PGAR AGC Max Level High 8 Bits", RK3190_PGAR_AGC_MAX_H,
580 SOC_SINGLE("PGAR AGC Max Level Low 8 Bits", RK3190_PGAR_AGC_MAX_L,
582 SOC_SINGLE("PGAR AGC Min Level High 8 Bits", RK3190_PGAR_AGC_MIN_H,
584 SOC_SINGLE("PGAR AGC Min Level Low 8 Bits", RK3190_PGAR_AGC_MIN_L,
587 SOC_SINGLE_TLV("PGAR AGC Max Gain", RK3190_PGAR_AGC_CTL5,
588 RK3190_PGA_AGC_MAX_G_SFT, 7, 0, pga_agc_max_vol_tlv),//AGC enable and 0x06 bit 4 is 1
589 SOC_SINGLE_TLV("PGAR AGC Min Gain", RK3190_PGAR_AGC_CTL5,
590 RK3190_PGA_AGC_MIN_G_SFT, 7, 0, pga_agc_min_vol_tlv),//AGC enable and 0x06 bit 4 is 1
595 //For tiny alsa playback/capture/voice call path
596 static const char *rk3190_playback_path_mode[] = {"OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT", "SPK_HP", //0-6
597 "RING_SPK", "RING_HP", "RING_HP_NO_MIC", "RING_SPK_HP"};//7-10
599 static const char *rk3190_capture_path_mode[] = {"MIC OFF", "Main Mic", "Hands Free Mic", "BT Sco Mic"};
601 static const char *rk3190_voice_call_path_mode[] = {"OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT"};//0-5
603 static const SOC_ENUM_SINGLE_DECL(rk3190_playback_path_type, 0, 0, rk3190_playback_path_mode);
605 static const SOC_ENUM_SINGLE_DECL(rk3190_capture_path_type, 0, 0, rk3190_capture_path_mode);
607 static const SOC_ENUM_SINGLE_DECL(rk3190_voice_call_path_type, 0, 0, rk3190_voice_call_path_mode);
609 static int rk3190_codec_power_up(int type);
610 static int rk3190_codec_power_down(int type);
612 static int rk3190_playback_path_get(struct snd_kcontrol *kcontrol,
613 struct snd_ctl_elem_value *ucontrol)
615 struct rk3190_codec_priv *rk3190 = rk3190_priv;
618 printk("%s : rk3190_priv is NULL\n", __func__);
622 DBG("%s : playback_path %ld\n",__func__,ucontrol->value.integer.value[0]);
624 ucontrol->value.integer.value[0] = rk3190->playback_path;
629 static int rk3190_playback_path_put(struct snd_kcontrol *kcontrol,
630 struct snd_ctl_elem_value *ucontrol)
632 struct rk3190_codec_priv *rk3190 = rk3190_priv;
633 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
637 printk("%s : rk3190_priv is NULL\n", __func__);
641 if (rk3190->playback_path == ucontrol->value.integer.value[0]){
642 DBG("%s : playback_path is not changed!\n",__func__);
646 pre_path = rk3190->playback_path;
647 rk3190->playback_path = ucontrol->value.integer.value[0];
649 printk("%s : set playback_path %ld, pre_path %ld\n", __func__,
650 rk3190->playback_path, pre_path);
653 // mute output for pop noise
654 if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) {
655 DBG("%s : set spk ctl gpio LOW\n", __func__);
656 gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW);
659 if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) {
660 DBG("%s : set hp ctl gpio LOW\n", __func__);
661 gpio_set_value(rk3190->hp_ctl_gpio, GPIO_LOW);
664 switch (rk3190->playback_path) {
667 rk3190_codec_power_down(RK3190_CODEC_PLAYBACK);
670 if (rk3190->voice_call_path != OFF) {
672 rk3190_codec_power_down(RK3190_CODEC_INCALL);
674 rk3190->voice_call_path = OFF;
679 DBG("%s : PUT SPK_PATH\n",__func__);
681 rk3190_codec_power_up(RK3190_CODEC_PLAYBACK);
683 snd_soc_update_bits(codec, RK3190_SPKL_CTL,
684 rk3190_VOL_MASK, SPKOUT_VOLUME); //, volume (bit 0-4)
685 snd_soc_update_bits(codec, rk3190_SPKR_CTL,
686 rk3190_VOL_MASK, SPKOUT_VOLUME);
688 if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) {
689 DBG("%s : set hp ctl gpio LOW\n", __func__);
690 gpio_set_value(rk3190->hp_ctl_gpio, GPIO_LOW);
691 //sleep for MOSFET or SPK power amplifier chip
692 msleep(HP_MOS_DELAY);
694 if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) {
695 DBG("%s : set spk ctl gpio HIGH\n", __func__);
696 gpio_set_value(rk3190->spk_ctl_gpio, GPIO_HIGH);
697 //sleep for MOSFET or SPK power amplifier chip
698 msleep(SPK_AMP_DELAY);
707 rk3190_codec_power_up(RK3190_CODEC_PLAYBACK);
709 snd_soc_update_bits(codec, rk3190_SPKL_CTL,
710 rk3190_VOL_MASK, HPOUT_VOLUME); //, volume (bit 0-4)
711 snd_soc_update_bits(codec, rk3190_SPKR_CTL,
712 rk3190_VOL_MASK, HPOUT_VOLUME);
714 if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) {
715 DBG("%s : set hp ctl gpio HIGH\n", __func__);
716 gpio_set_value(rk3190->hp_ctl_gpio, GPIO_HIGH);
717 //sleep for MOSFET or SPK power amplifier chip
718 msleep(HP_MOS_DELAY);
720 if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) {
721 DBG("%s : set spk ctl gpio LOW\n", __func__);
722 gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW);
723 //sleep for MOSFET or SPK power amplifier chip
724 msleep(SPK_AMP_DELAY);
733 rk3190_codec_power_up(RK3190_CODEC_PLAYBACK);
735 snd_soc_update_bits(codec, rk3190_SPKL_CTL,
736 rk3190_VOL_MASK, HPOUT_VOLUME); //, volume (bit 0-4)
737 snd_soc_update_bits(codec, rk3190_SPKR_CTL,
738 rk3190_VOL_MASK, HPOUT_VOLUME);
740 if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) {
741 DBG("%s : set spk ctl gpio HIGH\n", __func__);
742 gpio_set_value(rk3190->spk_ctl_gpio, GPIO_HIGH);
743 //sleep for MOSFET or SPK power amplifier chip
744 msleep(SPK_AMP_DELAY);
747 if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) {
748 DBG("%s : set hp ctl gpio HIGH\n", __func__);
749 gpio_set_value(rk3190->hp_ctl_gpio, GPIO_HIGH);
750 //sleep for MOSFET or SPK power amplifier chip
751 msleep(HP_MOS_DELAY);
762 static int rk3190_capture_path_get(struct snd_kcontrol *kcontrol,
763 struct snd_ctl_elem_value *ucontrol)
765 struct rk3190_codec_priv *rk3190 = rk3190_priv;
768 printk("%s : rk3190_priv is NULL\n", __func__);
772 DBG("%s : capture_path %ld\n", __func__,
773 ucontrol->value.integer.value[0]);
775 ucontrol->value.integer.value[0] = rk3190->capture_path;
780 static int rk3190_capture_path_put(struct snd_kcontrol *kcontrol,
781 struct snd_ctl_elem_value *ucontrol)
783 struct rk3190_codec_priv *rk3190 = rk3190_priv;
784 //struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
788 printk("%s : rk3190_priv is NULL\n", __func__);
792 if (rk3190->capture_path == ucontrol->value.integer.value[0]){
793 DBG("%s : capture_path is not changed!\n", __func__);
797 pre_path = rk3190->capture_path;
798 rk3190->capture_path = ucontrol->value.integer.value[0];
800 printk("%s : set capture_path %ld, pre_path %ld\n", __func__,
801 rk3190->capture_path, pre_path);
803 switch (rk3190->capture_path) {
805 if (pre_path != MIC_OFF)
806 rk3190_codec_power_down(RK3190_CODEC_CAPTURE);
809 DBG("%s : PUT MAIN_MIC_PATH\n",__func__);
810 if (pre_path == MIC_OFF)
811 rk3190_codec_power_up(RK3190_CODEC_CAPTURE);
813 if (rk3190 && rk3190->mic_sel_gpio != INVALID_GPIO) {
814 DBG("%s : set mic sel gpio HIGH\n", __func__);
815 gpio_set_value(rk3190->mic_sel_gpio, GPIO_HIGH);
820 if (pre_path == MIC_OFF)
821 rk3190_codec_power_up(RK3190_CODEC_CAPTURE);
823 if (rk3190 && rk3190->mic_sel_gpio != INVALID_GPIO) {
824 DBG("%s : set mic sel gpio HIGH\n", __func__);
825 gpio_set_value(rk3190->mic_sel_gpio, GPIO_LOW);
838 static int rk3190_voice_call_path_get(struct snd_kcontrol *kcontrol,
839 struct snd_ctl_elem_value *ucontrol)
841 struct rk3190_codec_priv *rk3190 = rk3190_priv;
844 printk("%s : rk3190_priv is NULL\n", __func__);
848 DBG("%s : voice_call_path %ld\n", __func__,
849 ucontrol->value.integer.value[0]);
851 ucontrol->value.integer.value[0] = rk3190->voice_call_path;
856 static int rk3190_voice_call_path_put(struct snd_kcontrol *kcontrol,
857 struct snd_ctl_elem_value *ucontrol)
859 struct rk3190_codec_priv *rk3190 = rk3190_priv;
860 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
864 printk("%s : rk3190_priv is NULL\n", __func__);
868 if (rk3190->voice_call_path == ucontrol->value.integer.value[0]){
869 DBG("%s : voice_call_path is not changed!\n",__func__);
873 pre_path = rk3190->voice_call_path;
874 rk3190->voice_call_path = ucontrol->value.integer.value[0];
876 printk("%s : set voice_call_path %ld, pre_path %ld\n", __func__,
877 rk3190->voice_call_path, pre_path);
879 if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) {
880 DBG("%s : set spk ctl gpio LOW\n", __func__);
881 gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW);
884 if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) {
885 DBG("%s : set hp ctl gpio LOW\n", __func__);
886 gpio_set_value(rk3190->hp_ctl_gpio, GPIO_LOW);
889 switch (rk3190->voice_call_path) {
892 if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) {
893 DBG("%s : set spk ctl gpio LOW\n", __func__);
894 gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW);
897 if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) {
898 DBG("%s : set hp ctl gpio LOW\n", __func__);
899 gpio_set_value(rk3190->hp_ctl_gpio, GPIO_LOW);
902 if (rk3190 && rk3190->ear_ctl_gpio != INVALID_GPIO) {
903 DBG("%s : set ear ctl gpio LOW\n", __func__);
904 gpio_set_value(rk3190->ear_ctl_gpio, GPIO_LOW);
907 rk3190_codec_power_down(RK3190_CODEC_INCALL);
908 rk3190_codec_power_up(RK3190_CODEC_PLAYBACK);
913 if (rk3190 && rk3190->mic_sel_gpio != INVALID_GPIO) {
914 DBG("%s : set mic sel gpio HIGH\n", __func__);
915 gpio_set_value(rk3190->mic_sel_gpio, GPIO_HIGH);
920 //rcv is controled by modem, so close incall route
921 if (pre_path != OFF && pre_path != BT)
922 rk3190_codec_power_down(RK3190_CODEC_INCALL);
924 rk3190_codec_power_up(RK3190_CODEC_INCALL);
926 if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) {
927 DBG("%s : set spk ctl gpio LOW\n", __func__);
928 gpio_set_value(rk3190->hp_ctl_gpio, GPIO_LOW);
931 if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) {
932 DBG("%s : set spk ctl gpio LOW\n", __func__);
933 gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW);
936 if (rk3190 && rk3190->ear_ctl_gpio != INVALID_GPIO) {
937 DBG("%s : set ear ctl gpio HIGH\n", __func__);
938 gpio_set_value(rk3190->ear_ctl_gpio, GPIO_HIGH);
945 if (rk3190 && rk3190->mic_sel_gpio != INVALID_GPIO) {
946 DBG("%s : set mic sel gpio HIGH\n", __func__);
947 gpio_set_value(rk3190->mic_sel_gpio, GPIO_HIGH);
951 if (pre_path == OFF ||
954 rk3190_codec_power_up(RK3190_CODEC_INCALL);
956 snd_soc_update_bits(codec, rk3190_SPKL_CTL,
957 rk3190_VOL_MASK, SPKOUT_VOLUME); //, volume (bit 0-4)
958 snd_soc_update_bits(codec, rk3190_SPKR_CTL,
959 rk3190_VOL_MASK, SPKOUT_VOLUME);
961 if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) {
962 DBG("%s : set spk ctl gpio LOW\n", __func__);
963 gpio_set_value(rk3190->hp_ctl_gpio, GPIO_LOW);
966 if (rk3190 && rk3190->ear_ctl_gpio != INVALID_GPIO) {
967 DBG("%s : set ear ctl gpio LOW\n", __func__);
968 gpio_set_value(rk3190->ear_ctl_gpio, GPIO_LOW);
970 if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) {
971 DBG("%s : set spk ctl gpio HIGH\n", __func__);
972 gpio_set_value(rk3190->spk_ctl_gpio, GPIO_HIGH);
973 //sleep for MOSFET or SPK power amplifier chip
974 msleep(SPK_AMP_DELAY);
980 if (rk3190 && rk3190->mic_sel_gpio != INVALID_GPIO) {
981 DBG("%s : set mic sel gpio HIGH\n", __func__);
982 gpio_set_value(rk3190->mic_sel_gpio, GPIO_LOW);
986 if (pre_path == OFF ||
989 rk3190_codec_power_up(RK3190_CODEC_INCALL);
991 snd_soc_update_bits(codec, rk3190_SPKL_CTL,
992 rk3190_VOL_MASK, HPOUT_VOLUME); //, volume (bit 0-4)
993 snd_soc_update_bits(codec, rk3190_SPKR_CTL,
994 rk3190_VOL_MASK, HPOUT_VOLUME);
997 if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) {
998 DBG("%s : set spk ctl gpio HIGH\n", __func__);
999 gpio_set_value(rk3190->hp_ctl_gpio, GPIO_HIGH);
1000 //sleep for MOSFET or SPK power amplifier chip
1001 msleep(HP_MOS_DELAY);
1004 if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) {
1005 DBG("%s : set spk ctl gpio LOW\n", __func__);
1006 gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW);
1009 if (rk3190 && rk3190->ear_ctl_gpio != INVALID_GPIO) {
1010 DBG("%s : set ear ctl gpio LOW\n", __func__);
1011 gpio_set_value(rk3190->ear_ctl_gpio, GPIO_LOW);
1018 if (rk3190 && rk3190->mic_sel_gpio != INVALID_GPIO) {
1019 DBG("%s : set mic sel gpio HIGH\n", __func__);
1020 gpio_set_value(rk3190->mic_sel_gpio, GPIO_HIGH);
1024 if (pre_path == OFF ||
1027 rk3190_codec_power_up(RK3190_CODEC_INCALL);
1029 snd_soc_update_bits(codec, rk3190_SPKL_CTL,
1030 rk3190_VOL_MASK, HPOUT_VOLUME); //, volume (bit 0-4)
1031 snd_soc_update_bits(codec, rk3190_SPKR_CTL,
1032 rk3190_VOL_MASK, HPOUT_VOLUME);
1035 if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) {
1036 DBG("%s : set spk ctl gpio HIGH\n", __func__);
1037 gpio_set_value(rk3190->hp_ctl_gpio, GPIO_HIGH);
1038 //sleep for MOSFET or SPK power amplifier chip
1039 msleep(HP_MOS_DELAY);
1042 if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) {
1043 DBG("%s : set spk ctl gpio LOW\n", __func__);
1044 gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW);
1047 if (rk3190 && rk3190->ear_ctl_gpio != INVALID_GPIO) {
1048 DBG("%s : set ear ctl gpio LOW\n", __func__);
1049 gpio_set_value(rk3190->ear_ctl_gpio, GPIO_LOW);
1054 //BT is controled by modem, so close incall route
1055 if (pre_path != OFF &&
1057 rk3190_codec_power_down(RK3190_CODEC_INCALL);
1060 if (rk3190 && rk3190->hp_ctl_gpio != INVALID_GPIO) {
1061 DBG("%s : set spk ctl gpio LOW\n", __func__);
1062 gpio_set_value(rk3190->hp_ctl_gpio, GPIO_LOW);
1063 //sleep for MOSFET or SPK power amplifier chip
1064 msleep(HP_MOS_DELAY);
1067 if (rk3190 && rk3190->spk_ctl_gpio != INVALID_GPIO) {
1068 DBG("%s : set spk ctl gpio LOW\n", __func__);
1069 gpio_set_value(rk3190->spk_ctl_gpio, GPIO_LOW);
1072 if (rk3190 && rk3190->ear_ctl_gpio != INVALID_GPIO) {
1073 DBG("%s : set ear ctl gpio LOW\n", __func__);
1074 gpio_set_value(rk3190->ear_ctl_gpio, GPIO_LOW);
1084 static const struct snd_kcontrol_new rk3190_snd_path_controls[] = {
1085 SOC_ENUM_EXT("Playback Path", rk3190_playback_path_type,
1086 rk3190_playback_path_get, rk3190_playback_path_put),
1088 SOC_ENUM_EXT("Capture MIC Path", rk3190_capture_path_type,
1089 rk3190_capture_path_get, rk3190_capture_path_put),
1091 SOC_ENUM_EXT("Voice Call Path", rk3190_voice_call_path_type,
1092 rk3190_voice_call_path_get, rk3190_voice_call_path_put),
1096 static int rk3190_dacl_event(struct snd_soc_dapm_widget *w,
1097 struct snd_kcontrol *kcontrol, int event)
1099 struct snd_soc_codec *codec = w->codec;
1102 case SND_SOC_DAPM_POST_PMU:
1103 snd_soc_update_bits(codec, RK3190_DAC_ENABLE,
1104 RK3190_DACL_WORK,0);
1105 snd_soc_update_bits(codec, RK3190_DAC_ENABLE,
1106 RK3190_DACL_EN | RK3190_DACL_CLK_EN,
1107 RK3190_DACL_EN | RK3190_DACL_CLK_EN);
1108 snd_soc_update_bits(codec, RK3190_DAC_ENABLE,
1109 RK3190_DACL_WORK, RK3190_DACL_WORK);
1112 case SND_SOC_DAPM_POST_PMD:
1113 snd_soc_update_bits(codec, RK3190_DAC_ENABLE,
1114 RK3190_DACL_EN | RK3190_DACL_CLK_EN,0);
1115 snd_soc_update_bits(codec, RK3190_DAC_ENABLE,
1116 RK3190_DACL_WORK, 0);
1126 static int rk3190_dacr_event(struct snd_soc_dapm_widget *w,
1127 struct snd_kcontrol *kcontrol, int event)
1129 struct snd_soc_codec *codec = w->codec;
1132 case SND_SOC_DAPM_POST_PMU:
1133 snd_soc_update_bits(codec, RK3190_DAC_ENABLE,
1134 RK3190_DACR_WORK,0);
1135 snd_soc_update_bits(codec, RK3190_DAC_ENABLE,
1136 RK3190_DACR_EN | RK3190_DACR_CLK_EN,
1137 RK3190_DACR_EN | RK3190_DACR_CLK_EN);
1138 snd_soc_update_bits(codec, RK3190_DAC_ENABLE,
1139 RK3190_DACR_WORK, RK3190_DACR_WORK);
1142 case SND_SOC_DAPM_POST_PMD:
1143 snd_soc_update_bits(codec, RK3190_DAC_ENABLE,
1144 RK3190_DACR_EN | RK3190_DACR_CLK_EN,0);
1145 snd_soc_update_bits(codec, RK3190_DAC_ENABLE,
1146 RK3190_DACR_WORK, 0);
1156 static int rk3190_adcl_event(struct snd_soc_dapm_widget *w,
1157 struct snd_kcontrol *kcontrol, int event)
1159 struct snd_soc_codec *codec = w->codec;
1162 case SND_SOC_DAPM_POST_PMU:
1163 snd_soc_update_bits(codec, RK3190_ADC_ENABLE,
1164 RK3190_ADCL_CLK_EN_SFT | RK3190_ADCL_AMP_EN_SFT,
1165 RK3190_ADCL_CLK_EN | RK3190_ADCL_AMP_EN);
1168 case SND_SOC_DAPM_POST_PMD:
1169 snd_soc_update_bits(codec, RK3190_ADC_ENABLE,
1170 RK3190_ADCL_CLK_EN_SFT | RK3190_ADCL_AMP_EN_SFT,0);
1180 static int rk3190_adcr_event(struct snd_soc_dapm_widget *w,
1181 struct snd_kcontrol *kcontrol, int event)
1183 struct snd_soc_codec *codec = w->codec;
1186 case SND_SOC_DAPM_POST_PMU:
1187 snd_soc_update_bits(codec, RK3190_ADC_ENABLE,
1188 RK3190_ADCR_CLK_EN_SFT | RK3190_ADCR_AMP_EN_SFT,
1189 RK3190_ADCR_CLK_EN | RK3190_ADCR_AMP_EN );
1192 case SND_SOC_DAPM_POST_PMD:
1193 snd_soc_update_bits(codec, RK3190_ADC_ENABLE,
1194 RK3190_ADCR_CLK_EN_SFT | RK3190_ADCR_AMP_EN_SFT,0);
1205 static const struct snd_kcontrol_new rk3190_hpmixl[] = {
1206 SOC_DAPM_SINGLE("ALCR Switch", RK3190_HPMIX_S_SELECT,
1207 RK3190_HPMIXL_SEL_ALCR_SFT, 1, 0),
1208 SOC_DAPM_SINGLE("ALCL Switch", RK3190_HPMIX_S_SELECT,
1209 RK3190_HPMIXL_SEL_ALCL_SFT, 1, 0),
1210 SOC_DAPM_SINGLE("DACL Switch", RK3190_HPMIX_S_SELECT,
1211 RK3190_HPMIXL_SEL_DACL_SFT, 1, 0),
1214 static const struct snd_kcontrol_new rk3190_hpmixr[] = {
1215 SOC_DAPM_SINGLE("ALCR Switch", RK3190_HPMIX_S_SELECT,
1216 RK3190_HPMIXR_SEL_ALCR_SFT, 1, 0),
1217 SOC_DAPM_SINGLE("ALCL Switch", RK3190_HPMIX_S_SELECT,
1218 RK3190_HPMIXR_SEL_ALCL_SFT, 1, 0),
1219 SOC_DAPM_SINGLE("DACR Switch", RK3190_HPMIX_S_SELECT,
1220 RK3190_HPMIXR_SEL_DACR_SFT, 1, 0),
1223 static int rk3190_hpmixl_event(struct snd_soc_dapm_widget *w,
1224 struct snd_kcontrol *kcontrol, int event)
1226 struct snd_soc_codec *codec = w->codec;
1229 case SND_SOC_DAPM_POST_PMU:
1230 snd_soc_update_bits(codec, RK3190_DAC_CTL,
1231 RK3190_ZO_DET_VOUTR_SFT, RK3190_ZO_DET_VOUTR_EN);
1232 snd_soc_update_bits(codec, RK3190_DAC_CTL,
1233 RK3190_ZO_DET_VOUTL_SFT, RK3190_ZO_DET_VOUTL_EN);
1236 case SND_SOC_DAPM_PRE_PMD:
1237 snd_soc_update_bits(codec, RK3190_DAC_CTL,
1238 RK3190_ZO_DET_VOUTR_SFT, RK3190_ZO_DET_VOUTR_DIS);
1239 snd_soc_update_bits(codec, RK3190_DAC_CTL,
1240 RK3190_ZO_DET_VOUTL_SFT, RK3190_ZO_DET_VOUTL_DIS);
1250 static int rk3190_hpmixr_event(struct snd_soc_dapm_widget *w,
1251 struct snd_kcontrol *kcontrol, int event)
1253 struct snd_soc_codec *codec = w->codec;
1256 case SND_SOC_DAPM_POST_PMU:
1257 snd_soc_update_bits(codec, RK3190_HPMIX_CTL,
1258 RK3190_HPMIXR_WORK2, RK3190_HPMIXR_WORK2);
1261 case SND_SOC_DAPM_PRE_PMD:
1262 snd_soc_update_bits(codec, RK3190_HPMIX_CTL,
1263 RK3190_HPMIXR_WORK2, 0);
1275 static const char *hpl_sel[] = {"HPMIXL", "DACL"};
1277 static const struct soc_enum hpl_sel_enum =
1278 SOC_ENUM_SINGLE(RK3190_HPMIX_S_SELECT, RK3190_HPMIXL_BYPASS_SFT,
1279 ARRAY_SIZE(hpl_sel), hpl_sel);
1281 static const struct snd_kcontrol_new hpl_sel_mux =
1282 SOC_DAPM_ENUM("HPL select Mux", hpl_sel_enum);
1284 static const char *hpr_sel[] = {"HPMIXR", "DACR"};
1286 static const struct soc_enum hpr_sel_enum =
1287 SOC_ENUM_SINGLE(RK3190_HPMIX_S_SELECT, RK3190_HPMIXR_BYPASS_SFT,
1288 ARRAY_SIZE(hpr_sel), hpr_sel);
1290 static const struct snd_kcontrol_new hpr_sel_mux =
1291 SOC_DAPM_ENUM("HPR select Mux", hpr_sel_enum);
1294 static const char *lnl_sel[] = {"NO","BSTL", "LINEL","NOUSE"};
1296 static const struct soc_enum lnl_sel_enum =
1297 SOC_ENUM_SINGLE(RK3190_ALC_MUNIN_CTL, RK3190_MUXINL_F_SHT,
1298 ARRAY_SIZE(lnl_sel), lnl_sel);
1300 static const struct snd_kcontrol_new lnl_sel_mux =
1301 SOC_DAPM_ENUM("MUXIN_L select", lnl_sel_enum);
1304 static const char *lnr_sel[] = {"NO","BSTR", "LINER","NOUSE"};
1306 static const struct soc_enum lnr_sel_enum =
1307 SOC_ENUM_SINGLE(RK3190_ALC_MUNIN_CTL, RK3190_MUXINR_F_SHT,
1308 ARRAY_SIZE(lnr_sel), lnr_sel);
1310 static const struct snd_kcontrol_new lnr_sel_mux =
1311 SOC_DAPM_ENUM("MUXIN_R select", lnr_sel_enum);
1314 static const struct snd_soc_dapm_widget rk3190_dapm_widgets[] = {
1316 /* microphone bias */
1317 SND_SOC_DAPM_MICBIAS("Mic Bias", RK3190_ADC_MIC_CTL,
1318 RK3190_MICBIAS_VOL_ENABLE, 0),
1321 SND_SOC_DAPM_DAC_E("DACL", NULL, SND_SOC_NOPM,
1322 0, 0, rk3190_dacl_event,
1323 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
1324 SND_SOC_DAPM_DAC_E("DACR", NULL, SND_SOC_NOPM,
1325 0, 0, rk3190_dacr_event,
1326 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
1329 SND_SOC_DAPM_ADC_E("ADCL", NULL, SND_SOC_NOPM,
1330 0, 0, rk3190_adcl_event,
1331 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
1332 SND_SOC_DAPM_ADC_E("ADCR", NULL, SND_SOC_NOPM,
1333 0, 0, rk3190_adcr_event,
1334 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
1337 SND_SOC_DAPM_PGA("BSTL", RK3190_BST_CTL,
1338 RK3190_BSTL_PWRD_SFT, 0, NULL, 0),
1339 SND_SOC_DAPM_PGA("BSTR", RK3190_BST_CTL,
1340 RK3190_BSTR_PWRD_SFT, 0, NULL, 0),
1341 SND_SOC_DAPM_PGA("ALCL", RK3190_ALC_MUNIN_CTL,
1342 RK3190_ALCL_PWR_SHT , 0, NULL, 0),
1343 SND_SOC_DAPM_PGA("ALCR", RK3190_ALC_MUNIN_CTL,
1344 RK3190_ALCR_PWR_SHT , 0, NULL, 0),
1345 SND_SOC_DAPM_PGA("HPL", RK3190_HPOUT_CTL,
1346 RK3190_HPOUTL_PWR_SHT, 0, NULL, 0),
1347 SND_SOC_DAPM_PGA("HPR", RK3190_HPOUT_CTL,
1348 RK3190_HPOUTR_PWR_SHT, 0, NULL, 0),
1351 SND_SOC_DAPM_MIXER_E("HPMIXL", RK3190_HPMIX_CTL,
1352 RK3190_HPMIXL_SFT, 0, rk3190_hpmixl,
1353 ARRAY_SIZE(rk3190_hpmixl),rk3190_hpmixl_event,
1354 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1355 SND_SOC_DAPM_MIXER_E("HPMIXR", RK3190_HPMIX_CTL,
1356 RK3190_HPMIXR_SFT, 0, rk3190_hpmixr,
1357 ARRAY_SIZE(rk3190_hpmixr),rk3190_hpmixr_event,
1358 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1361 SND_SOC_DAPM_MUX("IN_R Mux", SND_SOC_NOPM, 0, 0,
1363 SND_SOC_DAPM_MUX("IN_L Mux", SND_SOC_NOPM, 0, 0,
1365 SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0,
1367 SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0,
1370 /* Audio Interface */
1371 SND_SOC_DAPM_AIF_IN("I2S DAC", "HiFi Playback", 0,
1372 SND_SOC_NOPM, 0, 0),
1373 SND_SOC_DAPM_AIF_OUT("I2S ADC", "HiFi Capture", 0,
1374 SND_SOC_NOPM, 0, 0),
1377 SND_SOC_DAPM_INPUT("LINEL"),
1378 SND_SOC_DAPM_INPUT("LINER"),
1379 SND_SOC_DAPM_INPUT("MICP"),
1380 SND_SOC_DAPM_INPUT("MICN"),
1383 SND_SOC_DAPM_OUTPUT("HPOUTL"),
1384 SND_SOC_DAPM_OUTPUT("HPOUTR"),
1388 static const struct snd_soc_dapm_route rk3190_dapm_routes[] = {
1390 {"BSTR", NULL, "MICP"},
1391 {"BSTL", NULL, "MICP"},
1392 {"BSTL", NULL, "MICN"},
1394 {"IN_R Mux", "LINER", "LINER"},
1395 {"IN_R Mux", "BSTR", "BSTR"},
1396 {"IN_L Mux", "LINEL", "LINEL"},
1397 {"IN_L Mux", "BSTL", "BSTL"},
1399 {"ALCL", NULL, "IN_L Mux"},
1400 {"ALCR", NULL, "IN_R Mux"},
1403 {"ADCR", NULL, "ALCR"},
1404 {"ADCL", NULL, "ALCL"},
1406 {"I2S ADC", NULL, "ADCR"},
1407 {"I2S ADC", NULL, "ADCL"},
1411 {"DACR", NULL, "I2S DAC"},
1412 {"DACL", NULL, "I2S DAC"},
1414 {"HPMIXR", "ALCR Switch", "ALCR"},
1415 {"HPMIXR", "ALCL Switch", "ALCL"},
1416 {"HPMIXR", "DACR Switch", "DACR"},
1418 {"HPMIXL", "ALCR Switch", "ALCR"},
1419 {"HPMIXL", "ALCL Switch", "ALCL"},
1420 {"HPMIXL", "DACL Switch", "DACL"},
1423 {"HPR Mux", "DACR", "DACR"},
1424 {"HPR Mux", "HPMIXR", "HPMIXR"},
1425 {"HPL Mux", "DACL", "DACL"},
1426 {"HPL Mux", "HPMIXL", "HPMIXL"},
1428 {"HPR", NULL, "HPR Mux"},
1429 {"HPL", NULL, "HPL Mux"},
1431 {"HPOUTR", NULL, "HPR"},
1432 {"HPOUTL", NULL, "HPL"},
1436 static int rk3190_set_bias_level(struct snd_soc_codec *codec,
1437 enum snd_soc_bias_level level)
1439 DBG("%s level=%d\n",__func__,level);
1442 case SND_SOC_BIAS_ON:
1445 case SND_SOC_BIAS_PREPARE:
1448 case SND_SOC_BIAS_STANDBY:
1450 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1451 writel(0x32, rk3190_priv->regbase+RK3190_DAC_INT_CTL3);
1452 snd_soc_update_bits(codec, RK3190_ADC_MIC_CTL,
1453 RK3190_ADC_CURRENT_ENABLE, RK3190_ADC_CURRENT_ENABLE);
1454 snd_soc_update_bits(codec, RK3190_DAC_CTL,
1455 RK3190_CURRENT_EN, RK3190_CURRENT_EN);
1457 snd_soc_update_bits(codec, RK3190_ADC_ENABLE,
1458 RK3190_ADCL_REF_VOL_EN_SFT | RK3190_ADCR_REF_VOL_EN_SFT,
1459 RK3190_ADCL_REF_VOL_EN | RK3190_ADCR_REF_VOL_EN);
1461 snd_soc_update_bits(codec, RK3190_ADC_MIC_CTL,
1462 RK3190_ADCL_ZERO_DET_EN_SFT | RK3190_ADCR_ZERO_DET_EN_SFT,
1463 RK3190_ADCL_ZERO_DET_EN | RK3190_ADCR_ZERO_DET_EN);
1465 snd_soc_update_bits(codec, RK3190_DAC_CTL,
1466 RK3190_REF_VOL_DACL_EN_SFT | RK3190_REF_VOL_DACR_EN_SFT,
1467 RK3190_REF_VOL_DACL_EN | RK3190_REF_VOL_DACR_EN );
1469 snd_soc_update_bits(codec, RK3190_DAC_ENABLE,
1470 RK3190_DACL_REF_VOL_EN_SFT | RK3190_DACR_REF_VOL_EN_SFT,
1471 RK3190_DACL_REF_VOL_EN | RK3190_DACR_REF_VOL_EN );
1475 case SND_SOC_BIAS_OFF:
1477 snd_soc_update_bits(codec, RK3190_DAC_ENABLE,
1478 RK3190_DACL_REF_VOL_EN_SFT | RK3190_DACR_REF_VOL_EN_SFT,0);
1479 snd_soc_update_bits(codec, RK3190_DAC_CTL,
1480 RK3190_REF_VOL_DACL_EN_SFT | RK3190_REF_VOL_DACR_EN_SFT,0);
1481 snd_soc_update_bits(codec, RK3190_ADC_MIC_CTL,
1482 RK3190_ADCL_ZERO_DET_EN_SFT | RK3190_ADCR_ZERO_DET_EN_SFT,0);
1483 snd_soc_update_bits(codec, RK3190_ADC_ENABLE,
1484 RK3190_ADCL_REF_VOL_EN_SFT | RK3190_ADCR_REF_VOL_EN_SFT,0);
1485 snd_soc_update_bits(codec, RK3190_ADC_MIC_CTL,
1486 RK3190_ADC_CURRENT_ENABLE, 0);
1487 snd_soc_update_bits(codec, RK3190_DAC_CTL,
1488 RK3190_CURRENT_EN, 0);
1489 writel(0x22, rk3190_priv->regbase+RK3190_DAC_INT_CTL3);
1493 codec->dapm.bias_level = level;
1498 static int rk3190_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1499 int clk_id, unsigned int freq, int dir)
1501 struct rk3190_codec_priv *rk3190 = rk3190_priv;
1504 printk("%s : rk3190 is NULL\n", __func__);
1508 rk3190->stereo_sysclk = freq;
1513 static int rk3190_set_dai_fmt(struct snd_soc_dai *codec_dai,
1516 struct snd_soc_codec *codec = codec_dai->codec;
1517 unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0;
1519 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1520 case SND_SOC_DAIFMT_CBS_CFS:
1521 adc_aif2 |= RK3190_I2S_MODE_SLV;
1523 case SND_SOC_DAIFMT_CBM_CFM:
1524 adc_aif2 |= RK3190_I2S_MODE_MST;
1527 printk("%s : set master mask failed!\n", __func__);
1531 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1532 case SND_SOC_DAIFMT_DSP_A:
1533 adc_aif1 |= RK3190_ADC_DF_PCM;
1534 dac_aif1 |= RK3190_DAC_DF_PCM;
1536 case SND_SOC_DAIFMT_DSP_B:
1538 case SND_SOC_DAIFMT_I2S:
1539 adc_aif1 |= RK3190_ADC_DF_I2S;
1540 dac_aif1 |= RK3190_DAC_DF_I2S;
1542 case SND_SOC_DAIFMT_RIGHT_J:
1543 adc_aif1 |= RK3190_ADC_DF_RJ;
1544 dac_aif1 |= RK3190_DAC_DF_RJ;
1546 case SND_SOC_DAIFMT_LEFT_J:
1547 adc_aif1 |= RK3190_ADC_DF_LJ;
1548 dac_aif1 |= RK3190_DAC_DF_LJ;
1551 printk("%s : set format failed!\n", __func__);
1555 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1556 case SND_SOC_DAIFMT_NB_NF:
1557 adc_aif1 |= RK3190_ALRCK_POL_DIS;
1558 adc_aif2 |= RK3190_ABCLK_POL_DIS;
1559 dac_aif1 |= RK3190_DLRCK_POL_DIS;
1560 dac_aif2 |= RK3190_DBCLK_POL_DIS;
1562 case SND_SOC_DAIFMT_IB_IF:
1563 adc_aif1 |= RK3190_ALRCK_POL_EN;
1564 adc_aif2 |= RK3190_ABCLK_POL_EN;
1565 dac_aif1 |= RK3190_DLRCK_POL_EN;
1566 dac_aif2 |= RK3190_DBCLK_POL_EN;
1568 case SND_SOC_DAIFMT_IB_NF:
1569 adc_aif1 |= RK3190_ALRCK_POL_DIS;
1570 adc_aif2 |= RK3190_ABCLK_POL_EN;
1571 dac_aif1 |= RK3190_DLRCK_POL_DIS;
1572 dac_aif2 |= RK3190_DBCLK_POL_EN;
1574 case SND_SOC_DAIFMT_NB_IF:
1575 adc_aif1 |= RK3190_ALRCK_POL_EN;
1576 adc_aif2 |= RK3190_ABCLK_POL_DIS;
1577 dac_aif1 |= RK3190_DLRCK_POL_EN;
1578 dac_aif2 |= RK3190_DBCLK_POL_DIS;
1581 printk("%s : set dai format failed!\n", __func__);
1585 snd_soc_update_bits(codec, RK3190_ADC_INT_CTL1,
1586 RK3190_ALRCK_POL_MASK | RK3190_ADC_DF_MASK, adc_aif1);
1587 snd_soc_update_bits(codec, RK3190_ADC_INT_CTL2,
1588 RK3190_ABCLK_POL_MASK | RK3190_I2S_MODE_MASK, adc_aif2);
1589 snd_soc_update_bits(codec, RK3190_DAC_INT_CTL1,
1590 RK3190_DLRCK_POL_MASK | RK3190_DAC_DF_MASK, dac_aif1);
1591 snd_soc_update_bits(codec, RK3190_DAC_INT_CTL2,
1592 RK3190_DBCLK_POL_MASK, dac_aif2);
1597 static int rk3190_hw_params(struct snd_pcm_substream *substream,
1598 struct snd_pcm_hw_params *params,
1599 struct snd_soc_dai *dai)
1601 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1602 struct snd_soc_codec *codec =rtd->codec;
1603 struct rk3190_codec_priv *rk3190 = rk3190_priv;
1604 unsigned int rate = params_rate(params);
1606 unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0;
1609 printk("%s : rk3190 is NULL\n", __func__);
1613 // bclk = codec_clk / 4
1614 // lrck = bclk / (wl * 2)
1615 div = (((rk3190->stereo_sysclk / 4) / rate) / 2);
1617 if ((rk3190->stereo_sysclk % (4 * rate * 2) > 0) ||
1618 (div != 16 && div != 20 && div != 24 && div != 32)) {
1619 printk("%s : need PLL\n", __func__);
1625 adc_aif2 |= RK3190_ADC_WL_16;
1626 dac_aif2 |= RK3190_DAC_WL_16;
1629 adc_aif2 |= RK3190_ADC_WL_20;
1630 dac_aif2 |= RK3190_DAC_WL_20;
1633 adc_aif2 |= RK3190_ADC_WL_24;
1634 dac_aif2 |= RK3190_DAC_WL_24;
1637 adc_aif2 |= RK3190_ADC_WL_32;
1638 dac_aif2 |= RK3190_DAC_WL_32;
1645 DBG("%s : MCLK = %dHz, sample rate = %dHz, div = %d\n", __func__,
1646 rk3190->stereo_sysclk, rate, div);
1648 switch (params_format(params)) {
1649 case SNDRV_PCM_FORMAT_S16_LE:
1650 adc_aif1 |= RK3190_ADC_VWL_16;
1651 dac_aif1 |= RK3190_DAC_VWL_16;
1653 case SNDRV_PCM_FORMAT_S20_3LE:
1654 adc_aif1 |= RK3190_ADC_VWL_20;
1655 dac_aif1 |= RK3190_DAC_VWL_20;
1657 case SNDRV_PCM_FORMAT_S24_LE:
1658 adc_aif1 |= RK3190_ADC_VWL_24;
1659 dac_aif1 |= RK3190_DAC_VWL_24;
1661 case SNDRV_PCM_FORMAT_S32_LE:
1662 adc_aif1 |= RK3190_ADC_VWL_32;
1663 dac_aif1 |= RK3190_DAC_VWL_32;
1669 switch (params_channels(params)) {
1671 adc_aif1 |= RK3190_ADC_TYPE_MONO;
1674 adc_aif1 |= RK3190_ADC_TYPE_STEREO;
1680 adc_aif1 |= RK3190_ADC_SWAP_DIS;
1681 adc_aif2 |= RK3190_ADC_RST_DIS;
1682 dac_aif1 |= RK3190_DAC_SWAP_DIS;
1683 dac_aif2 |= RK3190_DAC_RST_DIS;
1685 rk3190->rate = rate;
1687 snd_soc_update_bits(codec, RK3190_ADC_INT_CTL1,
1688 RK3190_ADC_VWL_MASK | RK3190_ADC_SWAP_MASK |
1689 RK3190_ADC_TYPE_MASK, adc_aif1);
1690 snd_soc_update_bits(codec, RK3190_ADC_INT_CTL2,
1691 RK3190_ADC_WL_MASK | RK3190_ADC_RST_MASK, adc_aif2);
1692 snd_soc_update_bits(codec, RK3190_DAC_INT_CTL1,
1693 RK3190_DAC_VWL_MASK | RK3190_DAC_SWAP_MASK, dac_aif1);
1694 snd_soc_update_bits(codec, RK3190_DAC_INT_CTL2,
1695 RK3190_DAC_WL_MASK | RK3190_DAC_RST_MASK, dac_aif2);
1700 static int rk3190_digital_mute(struct snd_soc_dai *dai, int mute)
1705 static struct rk3190_reg_val_typ playback_power_up_list[] = {
1706 //{RK3190_DAC_INT_CTL3,0x32},
1707 {RK3190_DAC_CTL,0x40},
1708 {RK3190_DAC_CTL,0x62},
1709 {RK3190_DAC_ENABLE,0x88},
1710 {RK3190_DAC_ENABLE,0xcc},
1711 {RK3190_DAC_ENABLE,0xee},
1712 {RK3190_HPMIX_CTL,0x44},
1713 {RK3190_HPOUT_CTL,0x90},
1714 {RK3190_HPOUT_CTL,0xd8},
1715 {RK3190_HPMIX_S_SELECT,0x11},//DAC
1716 {RK3190_HPMIX_CTL,0x55},
1717 {RK3190_HPMIX_CTL,0x77},
1718 {RK3190_DAC_ENABLE,0xff},
1719 {RK3190_HPOUT_CTL,0xfc},
1720 {RK3190_DAC_CTL,0x73},
1721 {RK3190_HPOUTL_GAIN,OUT_VOLUME},
1722 {RK3190_HPOUTR_GAIN,OUT_VOLUME},
1724 #define RK3190_CODEC_PLAYBACK_POWER_UP_LIST_LEN ARRAY_SIZE(playback_power_up_list)
1726 static struct rk3190_reg_val_typ playback_power_down_list[] = {
1727 {RK3190_HPOUT_CTL,0xdb},
1728 {RK3190_HPMIX_CTL,0x44},
1729 {RK3190_HPMIX_S_SELECT,0x00},
1730 {RK3190_HPOUT_CTL,0x92},
1731 {RK3190_DAC_CTL,0x22},
1732 {RK3190_HPOUT_CTL,0x00},
1733 {RK3190_HPMIX_CTL,0x00},
1734 {RK3190_DAC_ENABLE,0x00},
1735 {RK3190_DAC_CTL,0x00},
1736 //{RK3190_DAC_INT_CTL3,0x22},
1738 //{RK3190_SELECT_CURRENT,0x08},
1740 {RK3190_HPOUTL_GAIN,0x0},
1741 {RK3190_HPOUTR_GAIN,0x0},
1743 #define RK3190_CODEC_PLAYBACK_POWER_DOWN_LIST_LEN ARRAY_SIZE(playback_power_down_list)
1745 static struct rk3190_reg_val_typ capture_power_up_list[] = {
1746 {RK3190_ADC_CTL, 0x40},
1747 //{RK3190_BIAS_CTL, 0x08},
1748 //{RK3190_BIAS_CTL, 0x0f},
1749 {RK3190_ADC_CTL, 0x62},
1750 {RK3190_BST_CTL, 0x88},
1751 {RK3190_ALC_MUNIN_CTL, 0x66},
1752 {RK3190_ADC_ENABLE, 0x44},
1753 {RK3190_ADC_ENABLE, 0x66},
1754 {RK3190_BST_CTL, 0xee},
1755 {RK3190_BST_CTL, 0xfe}, //single-ended
1756 {RK3190_ALC_MUNIN_CTL, 0x77},
1757 {RK3190_ALCL_GAIN_CTL, CAP_VOL},
1758 {RK3190_ALCR_GAIN_CTL, CAP_VOL},
1759 {RK3190_ADC_CTL, 0x73},
1762 #define RK3190_CODEC_CAPTURE_POWER_UP_LIST_LEN ARRAY_SIZE(capture_power_up_list)
1764 static struct rk3190_reg_val_typ capture_power_down_list[] = {
1765 {RK3190_ADC_ENABLE, 0x44},
1766 {RK3190_ALC_MUNIN_CTL, 0x66},
1767 {RK3190_BST_CTL, 0x88},
1768 {RK3190_ADC_ENABLE, 0x00},
1769 {RK3190_ADC_CTL, 0x62},
1770 //{RK3190_BIAS_CTL, 0x08},
1771 {RK3190_ADC_CTL, 0x40},
1772 {RK3190_BST_CTL, 0x00},
1773 {RK3190_ALCL_GAIN_CTL, 0x00},
1774 {RK3190_ALCR_GAIN_CTL, 0x00},
1775 {RK3190_ADC_CTL, 0x00},
1776 //{RK3190_BIAS_CTL, 0x00},
1777 {RK3190_ALC_MUNIN_CTL, 0x00},
1779 #define RK3190_CODEC_CAPTURE_POWER_DOWN_LIST_LEN ARRAY_SIZE(capture_power_down_list)
1781 static struct rk3190_reg_val_typ lineIn_bypass_power_up_list[] = {
1783 //{RK3190_DAC_INT_CTL3, 0x32},
1784 {RK3190_ADC_CTL, 0x40},
1785 {RK3190_BIAS_CTL, 0x08},
1786 {RK3190_BIAS_CTL, 0x0f},
1787 {RK3190_ALC_MUNIN_CTL, 0x22},
1788 {RK3190_ALC_MUNIN_CTL, 0x66},
1789 {RK3190_ADC_CTL, 0x62},
1790 {RK3190_DAC_CTL, 0x40},
1791 {RK3190_DAC_CTL, 0x62},
1792 {RK3190_DAC_ENABLE, 0x88},
1793 {RK3190_DAC_ENABLE, 0xcc},
1794 {RK3190_DAC_ENABLE, 0xee},
1795 {RK3190_HPMIX_CTL, 0x44},
1796 {RK3190_HPOUT_CTL, 0x92},
1797 {RK3190_HPOUT_CTL, 0xdb},
1798 {RK3190_HPMIX_S_SELECT, 0x22},//ALCL/R+DACL/R
1799 {RK3190_HPMIX_CTL, 0x55},
1800 {RK3190_HPMIX_CTL, 0x77},
1801 {RK3190_DAC_ENABLE, 0xff},
1802 {RK3190_HPOUT_CTL, 0xff},
1803 {RK3190_ALC_MUNIN_CTL, 0x77},
1804 {RK3190_ALCL_GAIN_CTL, CAP_VOL},
1805 {RK3190_ALCR_GAIN_CTL, CAP_VOL},
1806 {RK3190_HPOUTL_GAIN, OUT_VOLUME},
1807 {RK3190_HPOUTR_GAIN, OUT_VOLUME},
1808 {RK3190_ADC_CTL, 0x73},
1809 {RK3190_DAC_CTL, 0x73},
1812 #define RK3190_CODEC_LINEIN_BYPASS_POWER_UP_LIST_LEN ARRAY_SIZE(lineIn_bypass_power_up_list)
1814 static struct rk3190_reg_val_typ lineIn_bypass_power_down_list[] = {
1815 {RK3190_ALC_MUNIN_CTL, 0xaa},
1816 {RK3190_BIAS_CTL, 0xc7},
1817 //{RK3190_BIAS_CTL, 0x80},
1818 {RK3190_ADC_CTL, 0x62},
1819 //{RK3190_BIAS_CTL, 0x00},
1820 {RK3190_ALC_MUNIN_CTL, 0x00},
1821 {RK3190_HPOUT_CTL, 0xdb},
1822 {RK3190_HPMIX_CTL, 0x44},
1823 {RK3190_HPMIX_S_SELECT, 0x00},
1824 {RK3190_HPOUT_CTL, 0x92},
1825 {RK3190_DAC_CTL, 0x22},
1826 {RK3190_ADC_CTL, 0x00},
1827 {RK3190_HPOUT_CTL, 0x00},
1828 {RK3190_HPMIX_CTL, 0x00},
1829 {RK3190_DAC_CTL, 0x00},
1830 {RK3190_DAC_ENABLE, 0x00},
1831 {RK3190_HPOUTL_GAIN, 0x00},
1832 {RK3190_HPOUTR_GAIN, 0x00},
1833 {RK3190_ALCL_GAIN_CTL, 0x00},
1834 {RK3190_ALCR_GAIN_CTL, 0x00},
1835 //{RK3190_DAC_INT_CTL3, 0x00},
1837 #define RK3190_CODEC_LINEIN_BYPASS_POWER_DOWN_LIST_LEN ARRAY_SIZE(lineIn_bypass_power_down_list)
1840 static int rk3190_codec_power_up(int type)
1842 struct snd_soc_codec *codec = rk3190_priv->codec;
1845 if (!rk3190_priv || !rk3190_priv->codec) {
1846 printk("%s : rk3190_priv or rk3190_priv->codec is NULL\n", __func__);
1850 printk("%s : power up %s%s%s\n", __func__,
1851 type == RK3190_CODEC_PLAYBACK ? "playback" : "",
1852 type == RK3190_CODEC_CAPTURE ? "capture" : "",
1853 type == RK3190_CODEC_INCALL ? "incall" : "");
1855 if (type == RK3190_CODEC_PLAYBACK) {
1856 for (i = 0; i < RK3190_CODEC_PLAYBACK_POWER_UP_LIST_LEN; i++) {
1857 snd_soc_write(codec, playback_power_up_list[i].reg,
1858 playback_power_up_list[i].value);
1861 } else if (type == RK3190_CODEC_CAPTURE) {
1862 for (i = 0; i < RK3190_CODEC_CAPTURE_POWER_UP_LIST_LEN; i++) {
1863 snd_soc_write(codec, capture_power_up_list[i].reg,
1864 capture_power_up_list[i].value);
1867 } else if (type == RK3190_CODEC_INCALL) {
1869 for (i = 0; i < RK3190_CODEC_LINEIN_BYPASS_POWER_UP_LIST_LEN; i++) {
1870 snd_soc_write(codec, lineIn_bypass_power_up_list[i].reg,
1871 lineIn_bypass_power_up_list[i].value);
1879 static int rk3190_codec_power_down(int type)
1881 struct snd_soc_codec *codec = rk3190_priv->codec;
1884 if (!rk3190_priv || !rk3190_priv->codec) {
1885 printk("%s : rk3190_priv or rk3190_priv->codec is NULL\n", __func__);
1889 printk("%s : power down %s%s%s%s\n", __func__,
1890 type == RK3190_CODEC_PLAYBACK ? "playback" : "",
1891 type == RK3190_CODEC_CAPTURE ? "capture" : "",
1892 type == RK3190_CODEC_INCALL ? "incall" : "",
1893 type == RK3190_CODEC_ALL ? "all" : "");
1895 if ((type == RK3190_CODEC_CAPTURE) || (type == RK3190_CODEC_INCALL)) {
1896 for (i = 0; i < RK3190_CODEC_CAPTURE_POWER_DOWN_LIST_LEN; i++) {
1897 snd_soc_write(codec, capture_power_down_list[i].reg,
1898 capture_power_down_list[i].value);
1900 } else if (type == RK3190_CODEC_PLAYBACK) {
1902 snd_soc_write(codec, RK3190_DAC_CTL,0x62);
1903 for ( i = OUT_VOLUME; i >= 0; i--)
1905 snd_soc_write(codec, 0xb4,i);
1906 snd_soc_write(codec, 0xb8,i);
1910 for (i = 0; i < RK3190_CODEC_PLAYBACK_POWER_DOWN_LIST_LEN; i++) {
1911 snd_soc_write(codec, playback_power_down_list[i].reg,
1912 playback_power_down_list[i].value);
1915 } else if (type == RK3190_CODEC_INCALL) {
1917 for (i = 0; i < RK3190_CODEC_LINEIN_BYPASS_POWER_DOWN_LIST_LEN; i++) {
1918 snd_soc_write(codec, lineIn_bypass_power_down_list[i].reg,
1919 lineIn_bypass_power_down_list[i].value);
1921 } else if (type == RK3190_CODEC_ALL) {
1922 rk3190_reset(codec);
1928 #define RK3190_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\
1929 SNDRV_PCM_RATE_16000 | \
1930 SNDRV_PCM_RATE_32000 | \
1931 SNDRV_PCM_RATE_44100 | \
1932 SNDRV_PCM_RATE_48000 | \
1933 SNDRV_PCM_RATE_96000)
1935 #define RK3190_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
1936 SNDRV_PCM_RATE_16000 | \
1937 SNDRV_PCM_RATE_32000 | \
1938 SNDRV_PCM_RATE_44100 | \
1939 SNDRV_PCM_RATE_48000 | \
1940 SNDRV_PCM_RATE_96000)
1942 #define RK3190_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1943 SNDRV_PCM_FMTBIT_S20_3LE |\
1944 SNDRV_PCM_FMTBIT_S24_LE |\
1945 SNDRV_PCM_FMTBIT_S32_LE)
1947 static struct snd_soc_dai_ops rk3190_dai_ops = {
1948 .hw_params = rk3190_hw_params,
1949 .set_fmt = rk3190_set_dai_fmt,
1950 .set_sysclk = rk3190_set_dai_sysclk,
1951 .digital_mute = rk3190_digital_mute,
1954 static struct snd_soc_dai_driver rk3190_dai[] = {
1956 .name = "rk3190-hifi",
1959 .stream_name = "HiFi Playback",
1962 .rates = RK3190_PLAYBACK_RATES,
1963 .formats = RK3190_FORMATS,
1966 .stream_name = "HiFi Capture",
1969 .rates = RK3190_CAPTURE_RATES,
1970 .formats = RK3190_FORMATS,
1972 .ops = &rk3190_dai_ops,
1975 .name = "rk3190-voice",
1978 .stream_name = "Voice Playback",
1981 .rates = RK3190_PLAYBACK_RATES,
1982 .formats = RK3190_FORMATS,
1985 .stream_name = "Voice Capture",
1988 .rates = RK3190_CAPTURE_RATES,
1989 .formats = RK3190_FORMATS,
1991 .ops = &rk3190_dai_ops,
1996 static int rk3190_suspend(struct snd_soc_codec *codec)
2000 rk3190_codec_power_down(RK3190_CODEC_PLAYBACK);
2001 rk3190_codec_power_down(RK3190_CODEC_ALL);
2003 snd_soc_write(codec, RK3190_SELECT_CURRENT,0x3e);
2004 snd_soc_write(codec, RK3190_SELECT_CURRENT,0x1e);
2008 rk3190_set_bias_level(codec, SND_SOC_BIAS_OFF);
2013 static int rk3190_resume(struct snd_soc_codec *codec)
2015 if (!rk3190_for_mid)
2016 rk3190_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2018 snd_soc_write(codec, RK3190_SELECT_CURRENT,0x1e);
2019 snd_soc_write(codec, RK3190_SELECT_CURRENT,0x3e);
2024 static int rk3190_probe(struct snd_soc_codec *codec)
2026 struct rk3190_codec_priv *rk3190;
2027 struct rk3190_codec_pdata *rk3190_plt = codec->dev->platform_data;
2028 struct platform_device *pdev = to_platform_device(codec->dev);
2029 struct resource *res, *mem;
2033 DBG("%s\n", __func__);
2035 rk3190 = kzalloc(sizeof(struct rk3190_codec_priv), GFP_KERNEL);
2037 printk("%s : rk3190 priv kzalloc failed!\n", __func__);
2041 rk3190->codec = codec;
2043 res = pdev->resource;
2044 rk3190->regbase_phy = res->start;
2045 rk3190->regsize_phy = (res->end - res->start) + 1;
2047 mem = request_mem_region(res->start, (res->end - res->start) + 1, pdev->name);
2050 dev_err(&pdev->dev, "failed to request mem region for rk2928 codec\n");
2055 rk3190->regbase = (int)ioremap(res->start, (res->end - res->start) + 1);
2056 if (!rk3190->regbase) {
2057 dev_err(&pdev->dev, "cannot ioremap acodec registers\n");
2062 rk3190->pclk = clk_get(NULL,"pclk_acodec");
2063 if(IS_ERR(rk3190->pclk))
2065 dev_err(&pdev->dev, "Unable to get acodec hclk\n");
2069 clk_enable(rk3190->pclk);
2071 rk3190_priv = rk3190;
2073 if (rk3190_priv && rk3190_plt->spk_ctl_gpio) {
2074 gpio_request(rk3190_plt->spk_ctl_gpio, NULL);
2075 gpio_direction_output(rk3190_plt->spk_ctl_gpio, GPIO_LOW);
2076 rk3190->spk_ctl_gpio = rk3190_plt->spk_ctl_gpio;
2078 printk("%s : rk3190 spk_ctl_gpio is NULL!\n", __func__);
2079 rk3190->spk_ctl_gpio = INVALID_GPIO;
2082 if (rk3190_priv && rk3190_plt->hp_ctl_gpio) {
2083 gpio_request(rk3190_plt->hp_ctl_gpio, NULL);
2084 gpio_direction_output(rk3190_plt->hp_ctl_gpio, GPIO_LOW);
2085 rk3190->hp_ctl_gpio = rk3190_plt->hp_ctl_gpio;
2087 printk("%s : rk3190 hp_ctl_gpio is NULL!\n", __func__);
2088 rk3190->hp_ctl_gpio = INVALID_GPIO;
2091 if (rk3190_plt->delay_time) {
2092 rk3190->delay_time = rk3190_plt->delay_time;
2094 printk("%s : rk3190 delay_time is NULL!\n", __func__);
2095 rk3190->delay_time = 10;
2098 if (rk3190_plt->ear_ctl_gpio) {
2099 gpio_request(rk3190_plt->ear_ctl_gpio, NULL);
2100 gpio_direction_output(rk3190_plt->ear_ctl_gpio, GPIO_LOW);
2101 rk3190->ear_ctl_gpio = rk3190_plt->ear_ctl_gpio;
2103 printk("%s : rk3190 ear_ctl_gpio is NULL!\n", __func__);
2104 rk3190->ear_ctl_gpio = INVALID_GPIO;
2107 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
2109 printk("%s : Failed to set cache I/O: %d\n", __func__, ret);
2113 codec->hw_read = rk3190_codec_read;
2114 codec->hw_write = (hw_write_t)rk3190_hw_write;
2115 codec->read = rk3190_codec_read;
2116 codec->write = rk3190_codec_write;
2118 rk3190_reset(codec);
2120 val = snd_soc_read(codec, RK3190_RESET);
2121 if (val != rk3190_reg_defaults[RK3190_RESET]) {
2122 printk("%s : codec register 0: %x is not a 0x00000003\n", __func__, val);
2127 if (!rk3190_for_mid)
2129 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
2130 rk3190_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2134 //set for capacity output,clear up noise
2135 snd_soc_write(codec, RK3190_SELECT_CURRENT,0x1e);
2136 snd_soc_write(codec, RK3190_SELECT_CURRENT,0x3e);
2140 // select used with internal audio codec soc_con[4] bit 7
2141 val = readl(RK319X_GRF_BASE+GRF_SOC_CON4);
2142 writel(val | 0x00800080,RK319X_GRF_BASE+GRF_SOC_CON4);
2143 val = readl(RK319X_GRF_BASE+GRF_SOC_CON4);
2144 printk("%s : i2s used with internal audio codec val=0x%x,soc_con[4] bit 7 =1 is correct\n",__func__,val);
2147 /*ENABLE MICBIAS and always ON*/
2149 snd_soc_write(codec, RK3190_BIAS_CTL, 0x08);
2150 snd_soc_write(codec, RK3190_BIAS_CTL, 0x0f);
2152 if(rk3190_for_mid) {
2153 snd_soc_add_codec_controls(codec, rk3190_snd_path_controls,
2154 ARRAY_SIZE(rk3190_snd_path_controls));
2160 release_mem_region(res->start,(res->end - res->start) + 1);
2168 /* power down chip */
2169 static int rk3190_remove(struct snd_soc_codec *codec)
2172 DBG("%s\n", __func__);
2175 printk("%s : rk3190_priv is NULL\n", __func__);
2179 if (rk3190_priv->spk_ctl_gpio != INVALID_GPIO)
2180 gpio_set_value(rk3190_priv->spk_ctl_gpio, GPIO_LOW);
2182 if (rk3190_priv->hp_ctl_gpio != INVALID_GPIO)
2183 gpio_set_value(rk3190_priv->hp_ctl_gpio, GPIO_LOW);
2187 snd_soc_write(codec, RK3190_RESET, 0xfc);
2189 snd_soc_write(codec, RK3190_RESET, 0x3);
2198 static struct snd_soc_codec_driver soc_codec_dev_rk3190 = {
2199 .probe =rk3190_probe,
2200 .remove =rk3190_remove,
2201 .suspend =rk3190_suspend,
2202 .resume = rk3190_resume,
2203 .set_bias_level = rk3190_set_bias_level,
2204 .reg_cache_size = ARRAY_SIZE(rk3190_reg_defaults),
2205 .reg_word_size = sizeof(unsigned int),
2206 .reg_cache_default = rk3190_reg_defaults,
2207 .volatile_register = rk3190_volatile_register,
2208 .readable_register = rk3190_codec_register,
2209 .reg_cache_step = sizeof(unsigned int),
2212 static int rk3190_platform_probe(struct platform_device *pdev)
2214 DBG("%s\n", __func__);
2216 return snd_soc_register_codec(&pdev->dev,
2217 &soc_codec_dev_rk3190, rk3190_dai, ARRAY_SIZE(rk3190_dai));
2220 static int rk3190_platform_remove(struct platform_device *pdev)
2222 snd_soc_unregister_codec(&pdev->dev);
2226 void rk3190_platform_shutdown(struct platform_device *pdev)
2229 DBG("%s\n", __func__);
2231 if (!rk3190_priv || !rk3190_priv->codec) {
2232 printk("%s : rk3190_priv or rk3190_priv->codec is NULL\n", __func__);
2236 if (rk3190_priv->spk_ctl_gpio != INVALID_GPIO)
2237 gpio_set_value(rk3190_priv->spk_ctl_gpio, GPIO_LOW);
2239 if (rk3190_priv->hp_ctl_gpio != INVALID_GPIO)
2240 gpio_set_value(rk3190_priv->hp_ctl_gpio, GPIO_LOW);
2244 writel(0xfc, rk3190_priv->regbase+RK3190_RESET);
2246 writel(0x03, rk3190_priv->regbase+RK3190_RESET);
2252 static struct platform_driver rk3190_codec_driver = {
2254 .name = "rk3190-codec",
2255 .owner = THIS_MODULE,
2257 .probe = rk3190_platform_probe,
2258 .remove = rk3190_platform_remove,
2259 .shutdown = rk3190_platform_shutdown,
2263 static __init int rk3190_modinit(void)
2265 return platform_driver_register(&rk3190_codec_driver);
2267 module_init(rk3190_modinit);
2269 static __exit void rk3190_exit(void)
2271 platform_driver_unregister(&rk3190_codec_driver);
2273 module_exit(rk3190_exit);
2275 MODULE_DESCRIPTION("ASoC RK3190 driver");
2276 MODULE_AUTHOR("zhangjun <showy.zhang@rock-chips.com>");
2277 MODULE_LICENSE("GPL");