From 780db6f6ab52160fde77519f5bbbae4643c0b158 Mon Sep 17 00:00:00 2001 From: "peter.yang" Date: Fri, 26 Jan 2018 11:08:09 +0800 Subject: [PATCH] Add: speaker out is OK --- ac101.c | 68 +++++++++++++++++++------------ seeed-8mic-voicecard-overlay.dts | 23 +++++++++-- seeed-8mic-voicecard.dtbo | Bin 2359 -> 3045 bytes 3 files changed, 62 insertions(+), 29 deletions(-) diff --git a/ac101.c b/ac101.c index 74b800a..812636b 100644 --- a/ac101.c +++ b/ac101.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "ac101.h" @@ -48,7 +49,7 @@ #define DMIC_USED 0 #define ADC_DIGITAL_GAIN 0xb0b0 #define AGC_USED 0 -#define DRC_USED 1 +#define DRC_USED 0 #define _MORE_WIDGETS 0 static bool speaker_double_used = false; @@ -103,6 +104,8 @@ struct ac10x_priv { struct work_struct codec_resume; struct delayed_work dlywork; int trgr_cnt; + + struct gpio_desc* gpiod_spk_amp_switch; }; void get_configuration(void) @@ -1105,7 +1108,7 @@ static const struct snd_soc_dapm_route ac10x_dapm_routes[] = { {"DMICR VIR", NULL, "D_MIC"}, }; #else // !_MORE_WIDGETS - #if 0 + #if 1 static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -11925, 75, 0); static const DECLARE_TLV_DB_SCALE(dac_mix_vol_tlv, -600, 600, 0); static const DECLARE_TLV_DB_SCALE(dig_vol_tlv, -7308, 116, 0); @@ -1115,7 +1118,7 @@ static const struct snd_soc_dapm_route ac10x_dapm_routes[] = { static const struct snd_kcontrol_new ac10x_controls[] = { /*DAC*/ - #if 0 + #if 1 SOC_DOUBLE_TLV("DAC volume", DAC_VOL_CTRL, DAC_VOL_L, DAC_VOL_R, 0xff, 0, dac_vol_tlv), SOC_DOUBLE_TLV("DAC mixer gain", DAC_MXR_GAIN, DACL_MXR_GAIN, DACR_MXR_GAIN, 0xf, 0, dac_mix_vol_tlv), SOC_SINGLE_TLV("digital volume", DAC_DBG_CTRL, DVC, 0x3f, 1, dig_vol_tlv), @@ -1214,6 +1217,7 @@ static const unsigned ac10x_bclkdivs[] = { static int ac10x_aif_mute(struct snd_soc_dai *codec_dai, int mute) { struct snd_soc_codec *codec = codec_dai->codec; + struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec); AC10X_DBG("%s() L%d mute=%d\n", __func__, __LINE__, mute); @@ -1224,13 +1228,18 @@ static int ac10x_aif_mute(struct snd_soc_dai *codec_dai, int mute) late_enable_dac(codec, SND_SOC_DAPM_PRE_PMU); ac10x_headphone_event(codec, SND_SOC_DAPM_POST_PMU); if (drc_used) { - drc_enable(codec,1); + drc_enable(codec, 1); + } + if (ac10x->gpiod_spk_amp_switch) { + gpiod_set_value(ac10x->gpiod_spk_amp_switch, 1); } } else { - struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec); + if (ac10x->gpiod_spk_amp_switch) { + gpiod_set_value(ac10x->gpiod_spk_amp_switch, 0); + } if (drc_used) { - drc_enable(codec,0); + drc_enable(codec, 0); } ac10x_headphone_event(codec, SND_SOC_DAPM_PRE_PMD); late_enable_dac(codec, SND_SOC_DAPM_POST_PMD); @@ -1271,8 +1280,9 @@ static int ac10x_hw_params(struct snd_pcm_substream *substream, { int i = 0; int AIF_CLK_CTRL = AIF1_CLK_CTRL; - int aif1_word_size = 16; - int aif1_lrck_div = 64; + int aif1_word_size = 24; + int aif1_slot_size = 32; + int aif1_lrck_div; struct snd_soc_codec *codec = codec_dai->codec; struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec); int reg_val, freq_out; @@ -1282,9 +1292,23 @@ static int ac10x_hw_params(struct snd_pcm_substream *substream, ac10x->trgr_cnt = 0; + /* get channels count & slot size */ channels = params_channels(params); - aif1_lrck_div = 32 * channels; + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S32_LE: + aif1_slot_size = 32; + break; + case SNDRV_PCM_FORMAT_S16_LE: + default: + aif1_slot_size = 16; + break; + } + + + /* set LRCK/BCLK ratio */ + aif1_lrck_div = aif1_slot_size * channels; for (i = 0; i < ARRAY_SIZE(codec_aif1_lrck); i++) { if (codec_aif1_lrck[i].val == aif1_lrck_div) { break; @@ -1292,6 +1316,7 @@ static int ac10x_hw_params(struct snd_pcm_substream *substream, } snd_soc_update_bits(codec, AIF_CLK_CTRL, (0x7< 2) - #else - /* fixed 32 bits */ - i = 2; - #endif - snd_soc_update_bits(codec, AIF1_ADCDAT_CTRL, 0x3 << AIF1_SLOT_SIZ, i << AIF1_SLOT_SIZ); + if ((reg_val = codec_aif1_wsize[i].bit) > 2) reg_val = 2; + snd_soc_update_bits(codec, AIF1_ADCDAT_CTRL, 0x3 << AIF1_SLOT_SIZ, reg_val << AIF1_SLOT_SIZ); /* setting pll if it's master mode */ reg_val = snd_soc_read(codec, AIF_CLK_CTRL); @@ -1903,6 +1913,12 @@ static int ac10x_probe(struct i2c_client *i2c, const struct i2c_device_id *id) if (ret) { pr_err("failed to create attr group\n"); } + + ac10x->gpiod_spk_amp_switch = devm_gpiod_get_optional(&i2c->dev, "spk-amp-switch", GPIOD_OUT_LOW); + if (IS_ERR(ac10x->gpiod_spk_amp_switch)) { + ac10x->gpiod_spk_amp_switch = NULL; + dev_err(&i2c->dev, "failed get spk-amp-switch in device tree\n"); + } return 0; } diff --git a/seeed-8mic-voicecard-overlay.dts b/seeed-8mic-voicecard-overlay.dts index e87148e..684e665 100644 --- a/seeed-8mic-voicecard-overlay.dts +++ b/seeed-8mic-voicecard-overlay.dts @@ -15,7 +15,7 @@ fragment@1 { target-path = "/clocks"; __overlay__ { - ac108_mclk: codec-mclk { + ac10x_mclk: codec-mclk { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <24000000>; @@ -24,6 +24,20 @@ }; fragment@2 { + target = <&gpio>; + __overlay__ { + spk_amp_switch_pins: speaker_amp_switch_pins { + brcm,pins = <17>; + brcm,function = <1>; /* out */ + }; + gpclk0_pins: gpclk0_pins { + brcm,pins = <4>; + brcm,function = <4>; /* alt func 0 */ + }; + }; + }; + + fragment@3 { target = <&i2c1>; __overlay__ { #address-cells = <1>; @@ -32,6 +46,9 @@ ac101: ac101@1a{ compatible = "x-power,ac101"; + pinctrl-names = "default"; + pinctrl-0 = <&spk_amp_switch_pins>,<&gpclk0_pins>; + spk-amp-switch-gpios = <&gpio 17 0>; reg = <0x1a>; #sound-dai-cells = <0>; }; @@ -53,7 +70,7 @@ }; }; - fragment@3 { + fragment@4 { target = <&sound>; sound_overlay: __overlay__ { @@ -76,7 +93,7 @@ }; codec_dai: simple-audio-card,codec { sound-dai = <&ac101>; - clocks = <&ac108_mclk>; + clocks = <&ac10x_mclk>; system-clock-id = <1>; }; }; diff --git a/seeed-8mic-voicecard.dtbo b/seeed-8mic-voicecard.dtbo index a9de216dbf7730b65050753c22d3c14a64110926..1360e19d26a3f608963b028d5e95329c8c182d56 100644 GIT binary patch literal 3045 zcmb7GJFgry6!u&o4<$j62=SvzW31IBJ{ z=>G$nuhV>uCXEwA>lcpf|3sdBiT>|^UX;>|7t+i>nG%*8(XtdPqq6E^>UikBO!L-1 zH0VEyCvLnGMrS(Le@z<)_H*cbRmo)0$SzqNBtT&sI529Yh4 zSgSG?riks8uHFi=AIy$d{-tZ#7Qsvmm8zJyf6W=Ck zDeAPsYFK+lbchMoPzOKwx%oClC;?W6&rVs z)uu=l7j>d@E=8HR?asDqME;!EBKE<6y>HO`%_>Fp{J?0*pX6GqcAML`AJgFH-?SIB z=c70GcoaY48RW9hyEwomFK37Y_~^igu`Fs5&Cz<*ElyPl`s6#Ymv z@`o7)bRqkd{)c2CSJz4Iah;9eUHuN&iH557PAAA3Vh_}J6eqb@??V9P_od(`4h&nr=`RCPXO?PAY~VFS-?US|nU zgr=Ps!2W`;ziMITL)gOsJ-5Z0(^rKzUlqP8bZ$LzgH65TWYJ=uw%G1?cRqAhtPsQFK^ONO zBk;KI81OSpf9}EkrL*1r-PgY)FH*&t(qN-quDMicYMHG>Ra-CSq6GW6V7p9JQ=7S?N4uBatMfvetu)to~YgnzUtArX0P+ zvcOH*P}Q(ft=QqETIQt@)queDt3&+-y>9SW<3`v@l>-~8V2nC0mgH`xQp*c^LoNg% z;XR2w3}Ee)r6{VpR2|)L&lue`UL}UxG_QD8oBqO;PACmMooWN?*8RoOFFNNam0R-8 zG|x+}6Nay`3o}E#Z({czr7#~n`MRyMdDgfp36Ew*AJLesVXmD!O3y9By=HnYXUu7{ Fe*tv7dJ+Ht delta 528 zcmZ8dKS+W>9KE~myYKU>EGhM=t)8XAKTEs4@36B>eA8zSPhGzCu8 zR5(P?*3wc$1T{v`5;X)34gLFFC`k_<_j~ty_q)6I=ss=?UfI817_;Jxv3|zP7_C8~ zljtB4gvOZhaTN4&q@^F@!a|0(Z*AI~3F>kp8JJGY;aT&dB)X+iD+p?B2#X2qY5~_; zDxaHD2MEgVBJSW$i}xN