Add: speaker out is OK

This commit is contained in:
peter.yang 2018-01-26 11:08:09 +08:00
parent b032c0664d
commit 780db6f6ab
3 changed files with 62 additions and 29 deletions

64
ac101.c
View file

@ -34,6 +34,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/gpio/consumer.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include "ac101.h" #include "ac101.h"
@ -48,7 +49,7 @@
#define DMIC_USED 0 #define DMIC_USED 0
#define ADC_DIGITAL_GAIN 0xb0b0 #define ADC_DIGITAL_GAIN 0xb0b0
#define AGC_USED 0 #define AGC_USED 0
#define DRC_USED 1 #define DRC_USED 0
#define _MORE_WIDGETS 0 #define _MORE_WIDGETS 0
static bool speaker_double_used = false; static bool speaker_double_used = false;
@ -103,6 +104,8 @@ struct ac10x_priv {
struct work_struct codec_resume; struct work_struct codec_resume;
struct delayed_work dlywork; struct delayed_work dlywork;
int trgr_cnt; int trgr_cnt;
struct gpio_desc* gpiod_spk_amp_switch;
}; };
void get_configuration(void) void get_configuration(void)
@ -1105,7 +1108,7 @@ static const struct snd_soc_dapm_route ac10x_dapm_routes[] = {
{"DMICR VIR", NULL, "D_MIC"}, {"DMICR VIR", NULL, "D_MIC"},
}; };
#else // !_MORE_WIDGETS #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_vol_tlv, -11925, 75, 0);
static const DECLARE_TLV_DB_SCALE(dac_mix_vol_tlv, -600, 600, 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); 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[] = { static const struct snd_kcontrol_new ac10x_controls[] = {
/*DAC*/ /*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 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_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), 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) static int ac10x_aif_mute(struct snd_soc_dai *codec_dai, int mute)
{ {
struct snd_soc_codec *codec = codec_dai->codec; 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); AC10X_DBG("%s() L%d mute=%d\n", __func__, __LINE__, mute);
@ -1226,9 +1230,14 @@ static int ac10x_aif_mute(struct snd_soc_dai *codec_dai, int mute)
if (drc_used) { 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 { } 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) { if (drc_used) {
drc_enable(codec, 0); drc_enable(codec, 0);
} }
@ -1271,8 +1280,9 @@ static int ac10x_hw_params(struct snd_pcm_substream *substream,
{ {
int i = 0; int i = 0;
int AIF_CLK_CTRL = AIF1_CLK_CTRL; int AIF_CLK_CTRL = AIF1_CLK_CTRL;
int aif1_word_size = 16; int aif1_word_size = 24;
int aif1_lrck_div = 64; int aif1_slot_size = 32;
int aif1_lrck_div;
struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_codec *codec = codec_dai->codec;
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec); struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
int reg_val, freq_out; int reg_val, freq_out;
@ -1282,9 +1292,23 @@ static int ac10x_hw_params(struct snd_pcm_substream *substream,
ac10x->trgr_cnt = 0; ac10x->trgr_cnt = 0;
/* get channels count & slot size */
channels = params_channels(params); 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++) { for (i = 0; i < ARRAY_SIZE(codec_aif1_lrck); i++) {
if (codec_aif1_lrck[i].val == aif1_lrck_div) { if (codec_aif1_lrck[i].val == aif1_lrck_div) {
break; break;
@ -1292,6 +1316,7 @@ static int ac10x_hw_params(struct snd_pcm_substream *substream,
} }
snd_soc_update_bits(codec, AIF_CLK_CTRL, (0x7<<AIF1_LRCK_DIV), codec_aif1_lrck[i].bit<<AIF1_LRCK_DIV); snd_soc_update_bits(codec, AIF_CLK_CTRL, (0x7<<AIF1_LRCK_DIV), codec_aif1_lrck[i].bit<<AIF1_LRCK_DIV);
/* set PLL output freq */
freq_out = 24576000; freq_out = 24576000;
for (i = 0; i < ARRAY_SIZE(codec_aif1_fs); i++) { for (i = 0; i < ARRAY_SIZE(codec_aif1_fs); i++) {
if (codec_aif1_fs[i].samp_rate == params_rate(params)) { if (codec_aif1_fs[i].samp_rate == params_rate(params)) {
@ -1307,16 +1332,6 @@ static int ac10x_hw_params(struct snd_pcm_substream *substream,
} }
/* set I2S word size */ /* set I2S word size */
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_S32_LE:
aif1_word_size = 24;
break;
case SNDRV_PCM_FORMAT_S16_LE:
default:
aif1_word_size = 16;
break;
}
for (i = 0; i < ARRAY_SIZE(codec_aif1_wsize); i++) { for (i = 0; i < ARRAY_SIZE(codec_aif1_wsize); i++) {
if (codec_aif1_wsize[i].val == aif1_word_size) { if (codec_aif1_wsize[i].val == aif1_word_size) {
break; break;
@ -1325,13 +1340,8 @@ static int ac10x_hw_params(struct snd_pcm_substream *substream,
snd_soc_update_bits(codec, AIF_CLK_CTRL, (0x3<<AIF1_WORK_SIZ), ((codec_aif1_wsize[i].bit)<<AIF1_WORK_SIZ)); snd_soc_update_bits(codec, AIF_CLK_CTRL, (0x3<<AIF1_WORK_SIZ), ((codec_aif1_wsize[i].bit)<<AIF1_WORK_SIZ));
/* set TDM slot size */ /* set TDM slot size */
#if 0 if ((reg_val = codec_aif1_wsize[i].bit) > 2) reg_val = 2;
if ((i = codec_aif1_wsize[i].bit) > 2) snd_soc_update_bits(codec, AIF1_ADCDAT_CTRL, 0x3 << AIF1_SLOT_SIZ, reg_val << AIF1_SLOT_SIZ);
#else
/* fixed 32 bits */
i = 2;
#endif
snd_soc_update_bits(codec, AIF1_ADCDAT_CTRL, 0x3 << AIF1_SLOT_SIZ, i << AIF1_SLOT_SIZ);
/* setting pll if it's master mode */ /* setting pll if it's master mode */
reg_val = snd_soc_read(codec, AIF_CLK_CTRL); 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) { if (ret) {
pr_err("failed to create attr group\n"); 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; return 0;
} }

View file

@ -15,7 +15,7 @@
fragment@1 { fragment@1 {
target-path = "/clocks"; target-path = "/clocks";
__overlay__ { __overlay__ {
ac108_mclk: codec-mclk { ac10x_mclk: codec-mclk {
compatible = "fixed-clock"; compatible = "fixed-clock";
#clock-cells = <0>; #clock-cells = <0>;
clock-frequency = <24000000>; clock-frequency = <24000000>;
@ -24,6 +24,20 @@
}; };
fragment@2 { 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>; target = <&i2c1>;
__overlay__ { __overlay__ {
#address-cells = <1>; #address-cells = <1>;
@ -32,6 +46,9 @@
ac101: ac101@1a{ ac101: ac101@1a{
compatible = "x-power,ac101"; compatible = "x-power,ac101";
pinctrl-names = "default";
pinctrl-0 = <&spk_amp_switch_pins>,<&gpclk0_pins>;
spk-amp-switch-gpios = <&gpio 17 0>;
reg = <0x1a>; reg = <0x1a>;
#sound-dai-cells = <0>; #sound-dai-cells = <0>;
}; };
@ -53,7 +70,7 @@
}; };
}; };
fragment@3 { fragment@4 {
target = <&sound>; target = <&sound>;
sound_overlay: __overlay__ { sound_overlay: __overlay__ {
@ -76,7 +93,7 @@
}; };
codec_dai: simple-audio-card,codec { codec_dai: simple-audio-card,codec {
sound-dai = <&ac101>; sound-dai = <&ac101>;
clocks = <&ac108_mclk>; clocks = <&ac10x_mclk>;
system-clock-id = <1>; system-clock-id = <1>;
}; };
}; };

Binary file not shown.