Skip to content

Commit ad85bca

Browse files
Binyuan Lanrkhuangtao
authored andcommitted
ASoC: rockchip: rk817-codec: add some functions
distinguish MIC input differential or single-ended disable DAC_D_HPF add pdm support Change-Id: Id2befb3f817c9eaf273e1120036cf013db463639 Signed-off-by: Binyuan Lan <lby@rock-chips.com>
1 parent 7e99010 commit ad85bca

3 files changed

Lines changed: 163 additions & 39 deletions

File tree

Documentation/devicetree/bindings/sound/rockchip,rk817-codec.txt

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,29 @@ Required properties:
55
- compatible: "rockchip,rk817-codec"
66
- clocks: a list of phandle + clock-specifer pairs, one for each entry in clock-names.
77
- clock-names: should be "mclk".
8-
8+
- spk-volume: DAC L/R volume digital setting for Speaker
9+
- hp-volume: DAC L/R volume digital setting for Headphone
10+
*
11+
* DDAC L/R volume setting
12+
* 0db~-95db,0.375db/step,for example:
13+
* 0: 0dB
14+
* 10: -3.75dB
15+
* 125: -46dB
16+
* 255: -95dB
17+
*
18+
- capture-volume: ADC L/R volume digital setting for Microphone
19+
*
20+
* DADC L/R volume setting
21+
* 0db~-95db,0.375db/step,for example:
22+
* 0: 0dB
23+
* 10: -3.75dB
24+
* 125: -46dB
25+
* 255: -95dB
26+
*
27+
- mic-in-differential:
28+
Boolean. Indicate MIC input are differential, rather than single-ended.
29+
- pdmdata-out-enable:
30+
Boolean. Indicate pdmdata output is enable or disable.
931

1032
Example for rk817 codec:
1133

@@ -19,13 +41,17 @@ rk817: pmic@20 {
1941

2042
........
2143

22-
rk817_codec: rk817-codec {
44+
rk817_codec: codec {
2345
#sound-dai-cells = <0>;
2446
compatible = "rockchip,rk817-codec";
2547
clocks = <&cru SCLK_I2S_8CH_OUT>;
2648
clock-names = "mclk";
2749
pinctrl-names = "default";
2850
pinctrl-0 = <&i2s_8ch_mclk>;
51+
hp-volume = <3>;
52+
spk-volume = <3>;
53+
capture-volume = <0>;
54+
mic-in-differential;
2955
status = "okay";
3056
};
3157

sound/soc/codecs/rk817_codec.c

Lines changed: 95 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,21 @@ module_param_named(dbg_level, dbg_enable, int, 0644);
4444

4545
/*
4646
* DDAC L/R volume setting
47+
* 0db~-95db,0.375db/step,for example:
4748
* 0: 0dB
48-
* 0x0a:-3.75dB
49+
* 0x0a: -3.75dB
4950
* 0x7d: -46dB
5051
* 0xff: -95dB
51-
* Step: 0.375dB
5252
*/
5353
#define OUT_VOLUME (0x03)
5454

5555
/*
5656
* DADC L/R volume setting
57+
* 0db~-95db,0.375db/step,for example:
5758
* 0: 0dB
58-
* 0x0a:-3.75dB
59+
* 0x0a: -3.75dB
5960
* 0x7d: -46dB
6061
* 0xff: -95dB
61-
* Step: 0.375dB
6262
*/
6363
#define CAPTURE_VOLUME (0x0)
6464

@@ -75,6 +75,9 @@ struct rk817_codec_priv {
7575
unsigned int hp_volume;
7676
unsigned int capture_volume;
7777

78+
bool mic_in_differential;
79+
bool pdmdata_out_enable;
80+
7881
long int playback_path;
7982
long int capture_path;
8083
};
@@ -227,8 +230,8 @@ static struct rk817_reg_val_typ playback_power_up_list[] = {
227230
{RK817_CODEC_AREF_RTCFG1, 0x40},
228231
{RK817_CODEC_DDAC_POPD_DACST, 0x02},
229232
{RK817_CODEC_DDAC_SR_LMT0, 0x02},
230-
/*{RK817_CODEC_DTOP_DIGEN_CLKE, 0x0f},*/
231-
/*APLL*/
233+
/* {RK817_CODEC_DTOP_DIGEN_CLKE, 0x0f}, */
234+
/* APLL */
232235
{RK817_CODEC_APLL_CFG0, 0x04},
233236
{RK817_CODEC_APLL_CFG1, 0x58},
234237
{RK817_CODEC_APLL_CFG2, 0x2d},
@@ -242,6 +245,7 @@ static struct rk817_reg_val_typ playback_power_up_list[] = {
242245
{RK817_CODEC_DI2S_RXCR1, 0x00},
243246
{RK817_CODEC_DI2S_RXCMD_TSD, 0x20},
244247
{RK817_CODEC_DTOP_VUCTIME, 0xf4},
248+
{RK817_CODEC_DDAC_MUTE_MIXCTL, 0x00},
245249

246250
{RK817_CODEC_DDAC_VOLL, 0x0a},
247251
{RK817_CODEC_DDAC_VOLR, 0x0a},
@@ -251,7 +255,7 @@ static struct rk817_reg_val_typ playback_power_up_list[] = {
251255
ARRAY_SIZE(playback_power_up_list)
252256

253257
static struct rk817_reg_val_typ playback_power_down_list[] = {
254-
{RK817_CODEC_DDAC_MUTE_MIXCTL, 0xa1},
258+
{RK817_CODEC_DDAC_MUTE_MIXCTL, 0x01},
255259
{RK817_CODEC_ADAC_CFG1, 0x0f},
256260
/* HP */
257261
{RK817_CODEC_AHP_CFG0, 0xe0},
@@ -267,7 +271,7 @@ static struct rk817_reg_val_typ capture_power_up_list[] = {
267271
{RK817_CODEC_AREF_RTCFG1, 0x40},
268272
{RK817_CODEC_DDAC_SR_LMT0, 0x02},
269273
{RK817_CODEC_DADC_SR_ACL0, 0x02},
270-
/*{RK817_CODEC_DTOP_DIGEN_CLKE, 0xff},*/
274+
/* {RK817_CODEC_DTOP_DIGEN_CLKE, 0xff}, */
271275
{RK817_CODEC_APLL_CFG0, 0x04},
272276
{RK817_CODEC_APLL_CFG1, 0x58},
273277
{RK817_CODEC_APLL_CFG2, 0x2d},
@@ -287,7 +291,7 @@ static struct rk817_reg_val_typ capture_power_up_list[] = {
287291
{RK817_CODEC_AMIC_CFG0, 0x0f},
288292
{RK817_CODEC_DI2S_TXCR3_TXCMD, 0x88},
289293
{RK817_CODEC_DDAC_POPD_DACST, 0x02},
290-
/* 0x29: -18db to 27db*/
294+
/* 0x29: -18db to 27db */
291295
{RK817_CODEC_DMIC_PGA_GAIN, 0xaa},
292296
};
293297

@@ -310,18 +314,17 @@ static int rk817_codec_power_up(int type)
310314

311315
codec = rk817->codec;
312316

313-
dev_info(codec->dev, "%s : power up %s %s %s\n", __func__,
314-
type & RK817_CODEC_PLAYBACK ? "playback" : "",
315-
type & RK817_CODEC_CAPTURE ? "capture" : "",
316-
type & RK817_CODEC_INCALL ? "incall" : "");
317+
DBG("%s : power up %s %s %s\n", __func__,
318+
type & RK817_CODEC_PLAYBACK ? "playback" : "",
319+
type & RK817_CODEC_CAPTURE ? "capture" : "",
320+
type & RK817_CODEC_INCALL ? "incall" : "");
317321

318322
if (type & RK817_CODEC_PLAYBACK) {
319323
snd_soc_update_bits(codec, RK817_CODEC_DTOP_DIGEN_CLKE,
320324
DAC_DIG_CLK_MASK, DAC_DIG_CLK_EN);
321325
for (i = 0; i < RK817_CODEC_PLAYBACK_POWER_UP_LIST_LEN; i++) {
322326
snd_soc_write(codec, playback_power_up_list[i].reg,
323327
playback_power_up_list[i].value);
324-
usleep_range(1000, 1100);
325328
}
326329
}
327330

@@ -331,8 +334,19 @@ static int rk817_codec_power_up(int type)
331334
for (i = 0; i < RK817_CODEC_CAPTURE_POWER_UP_LIST_LEN; i++) {
332335
snd_soc_write(codec, capture_power_up_list[i].reg,
333336
capture_power_up_list[i].value);
334-
usleep_range(1000, 1100);
335337
}
338+
339+
if (rk817->mic_in_differential)
340+
snd_soc_update_bits(codec, RK817_CODEC_AMIC_CFG0,
341+
MIC_DIFF_MASK, MIC_DIFF_EN);
342+
else
343+
snd_soc_update_bits(codec, RK817_CODEC_AMIC_CFG0,
344+
MIC_DIFF_MASK, MIC_DIFF_DIS);
345+
346+
if (rk817->pdmdata_out_enable)
347+
snd_soc_update_bits(codec, RK817_CODEC_DI2S_CKM,
348+
PDM_EN_MASK, PDM_EN_ENABLE);
349+
336350
snd_soc_write(codec, RK817_CODEC_DADC_VOLL,
337351
rk817->capture_volume);
338352
snd_soc_write(codec, RK817_CODEC_DADC_VOLR,
@@ -350,10 +364,10 @@ static int rk817_codec_power_down(int type)
350364

351365
codec = rk817->codec;
352366

353-
dev_info(codec->dev, "%s : power down %s %s %s\n", __func__,
354-
type & RK817_CODEC_PLAYBACK ? "playback" : "",
355-
type & RK817_CODEC_CAPTURE ? "capture" : "",
356-
type & RK817_CODEC_INCALL ? "incall" : "");
367+
DBG("%s : power down %s %s %s\n", __func__,
368+
type & RK817_CODEC_PLAYBACK ? "playback" : "",
369+
type & RK817_CODEC_CAPTURE ? "capture" : "",
370+
type & RK817_CODEC_INCALL ? "incall" : "");
357371

358372
/* mute output for pop noise */
359373
if ((type & RK817_CODEC_PLAYBACK) ||
@@ -449,23 +463,25 @@ static int rk817_playback_path_put(struct snd_kcontrol *kcontrol,
449463

450464
switch (rk817->playback_path) {
451465
case OFF:
452-
if (pre_path != OFF)
466+
if (pre_path != OFF && (pre_path != HP_PATH &&
467+
pre_path != HP_NO_MIC && pre_path != RING_HP &&
468+
pre_path != RING_HP_NO_MIC))
453469
rk817_codec_power_down(RK817_CODEC_PLAYBACK);
454470
break;
455471
case RCV:
456472
case SPK_PATH:
457473
case RING_SPK:
458474
if (pre_path == OFF)
459475
rk817_codec_power_up(RK817_CODEC_PLAYBACK);
460-
/* power on dac ibias/l/r*/
476+
/* power on dac ibias/l/r */
461477
snd_soc_write(codec, RK817_CODEC_ADAC_CFG1,
462478
PWD_DACBIAS_ON | PWD_DACD_ON |
463479
PWD_DACL_ON | PWD_DACR_ON);
464-
/* CLASS D mode*/
480+
/* CLASS D mode */
465481
snd_soc_write(codec, RK817_CODEC_DDAC_MUTE_MIXCTL, 0x10);
466-
/* CLASS D enable*/
482+
/* CLASS D enable */
467483
snd_soc_write(codec, RK817_CODEC_ACLASSD_CFG1, 0xa5);
468-
/* restart CLASS D, OCPP/N*/
484+
/* restart CLASS D, OCPP/N */
469485
snd_soc_write(codec, RK817_CODEC_ACLASSD_CFG2, 0xc4);
470486

471487
snd_soc_write(codec, RK817_CODEC_DDAC_VOLL, rk817->spk_volume);
@@ -479,9 +495,9 @@ static int rk817_playback_path_put(struct snd_kcontrol *kcontrol,
479495
rk817_codec_power_up(RK817_CODEC_PLAYBACK);
480496
/* HP_CP_EN , CP 2.3V */
481497
snd_soc_write(codec, RK817_CODEC_AHP_CP, 0x11);
482-
/* power on HP two stage opamp ,HP amplitude 0db*/
498+
/* power on HP two stage opamp ,HP amplitude 0db */
483499
snd_soc_write(codec, RK817_CODEC_AHP_CFG0, 0x80);
484-
/* power on dac ibias/l/r*/
500+
/* power on dac ibias/l/r */
485501
snd_soc_write(codec, RK817_CODEC_ADAC_CFG1,
486502
PWD_DACBIAS_ON | PWD_DACD_DOWN |
487503
PWD_DACL_ON | PWD_DACR_ON);
@@ -497,6 +513,21 @@ static int rk817_playback_path_put(struct snd_kcontrol *kcontrol,
497513
case RING_SPK_HP:
498514
if (pre_path == OFF)
499515
rk817_codec_power_up(RK817_CODEC_PLAYBACK);
516+
/* HP_CP_EN , CP 2.3V */
517+
snd_soc_write(codec, RK817_CODEC_AHP_CP, 0x11);
518+
/* power on HP two stage opamp ,HP amplitude 0db */
519+
snd_soc_write(codec, RK817_CODEC_AHP_CFG0, 0x80);
520+
521+
/* power on dac ibias/l/r */
522+
snd_soc_write(codec, RK817_CODEC_ADAC_CFG1,
523+
PWD_DACBIAS_ON | PWD_DACD_ON |
524+
PWD_DACL_ON | PWD_DACR_ON);
525+
/* CLASS D mode */
526+
snd_soc_write(codec, RK817_CODEC_DDAC_MUTE_MIXCTL, 0x10);
527+
/* CLASS D enable */
528+
snd_soc_write(codec, RK817_CODEC_ACLASSD_CFG1, 0xa5);
529+
/* restart CLASS D, OCPP/N */
530+
snd_soc_write(codec, RK817_CODEC_ACLASSD_CFG2, 0xc4);
500531

501532
snd_soc_write(codec, RK817_CODEC_DDAC_VOLL, rk817->hp_volume);
502533
snd_soc_write(codec, RK817_CODEC_DDAC_VOLR, rk817->hp_volume);
@@ -550,10 +581,26 @@ static int rk817_capture_path_put(struct snd_kcontrol *kcontrol,
550581
case MAIN_MIC:
551582
if (pre_path == MIC_OFF)
552583
rk817_codec_power_up(RK817_CODEC_CAPTURE);
584+
585+
if (!rk817->mic_in_differential) {
586+
snd_soc_write(codec, RK817_CODEC_DADC_VOLR, 0xff);
587+
snd_soc_update_bits(codec, RK817_CODEC_AADC_CFG0,
588+
ADC_R_PWD_MASK, ADC_R_PWD_EN);
589+
snd_soc_update_bits(codec, RK817_CODEC_AMIC_CFG0,
590+
PWD_PGA_R_MASK, PWD_PGA_R_EN);
591+
}
553592
break;
554593
case HANDS_FREE_MIC:
555594
if (pre_path == MIC_OFF)
556595
rk817_codec_power_up(RK817_CODEC_CAPTURE);
596+
597+
if (!rk817->mic_in_differential) {
598+
snd_soc_write(codec, RK817_CODEC_DADC_VOLL, 0xff);
599+
snd_soc_update_bits(codec, RK817_CODEC_AADC_CFG0,
600+
ADC_L_PWD_MASK, ADC_L_PWD_EN);
601+
snd_soc_update_bits(codec, RK817_CODEC_AMIC_CFG0,
602+
PWD_PGA_L_MASK, PWD_PGA_L_EN);
603+
}
557604
break;
558605
case BT_SCO_MIC:
559606
break;
@@ -641,7 +688,16 @@ static int rk817_hw_params(struct snd_pcm_substream *substream,
641688

642689
static int rk817_digital_mute(struct snd_soc_dai *dai, int mute)
643690
{
644-
DBG("%s immediately return for mid\n", __func__);
691+
struct snd_soc_codec *codec = dai->codec;
692+
693+
DBG("%s %d\n", __func__, mute);
694+
if (mute)
695+
snd_soc_update_bits(codec, RK817_CODEC_DDAC_MUTE_MIXCTL,
696+
DACMT_ENABLE, DACMT_ENABLE);
697+
else
698+
snd_soc_update_bits(codec, RK817_CODEC_DDAC_MUTE_MIXCTL,
699+
DACMT_ENABLE, DACMT_DISABLE);
700+
645701
return 0;
646702
}
647703

@@ -766,9 +822,9 @@ static int rk817_codec_parse_dt_property(struct device *dev,
766822
return -ENODEV;
767823
}
768824

769-
node = of_get_child_by_name(dev->parent->of_node, "rk817-codec");
825+
node = of_get_child_by_name(dev->parent->of_node, "codec");
770826
if (!node) {
771-
dev_err(dev, "%s() Can not get child: rk817-codec\n",
827+
dev_err(dev, "%s() Can not get child: codec\n",
772828
__func__);
773829
return -ENODEV;
774830
}
@@ -778,6 +834,8 @@ static int rk817_codec_parse_dt_property(struct device *dev,
778834
DBG("%s() Can not read property skp-volume\n", __func__);
779835
rk817->spk_volume = OUT_VOLUME;
780836
}
837+
if (rk817->spk_volume < 3)
838+
rk817->spk_volume = 3;
781839

782840
ret = of_property_read_u32(node, "hp-volume",
783841
&rk817->hp_volume);
@@ -786,6 +844,8 @@ static int rk817_codec_parse_dt_property(struct device *dev,
786844
__func__);
787845
rk817->hp_volume = OUT_VOLUME;
788846
}
847+
if (rk817->hp_volume < 3)
848+
rk817->hp_volume = 3;
789849

790850
ret = of_property_read_u32(node, "capture-volume",
791851
&rk817->capture_volume);
@@ -795,6 +855,12 @@ static int rk817_codec_parse_dt_property(struct device *dev,
795855
rk817->capture_volume = CAPTURE_VOLUME;
796856
}
797857

858+
rk817->mic_in_differential =
859+
of_property_read_bool(node, "mic-in-differential");
860+
861+
rk817->pdmdata_out_enable =
862+
of_property_read_bool(node, "pdmdata-out-enable");
863+
798864
return 0;
799865
}
800866

0 commit comments

Comments
 (0)