Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
f3b368d3
Commit
f3b368d3
authored
Jun 05, 2015
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/rt5645' into asoc-next
parents
977732b0
345b0f50
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
847 additions
and
266 deletions
+847
-266
include/sound/rt5645.h
include/sound/rt5645.h
+0
-3
sound/soc/codecs/rt5645.c
sound/soc/codecs/rt5645.c
+829
-249
sound/soc/codecs/rt5645.h
sound/soc/codecs/rt5645.h
+17
-13
sound/soc/intel/boards/cht_bsw_rt5645.c
sound/soc/intel/boards/cht_bsw_rt5645.c
+1
-1
No files found.
include/sound/rt5645.h
View file @
f3b368d3
...
...
@@ -15,7 +15,6 @@ struct rt5645_platform_data {
/* IN2 can optionally be differential */
bool
in2_diff
;
bool
dmic_en
;
unsigned
int
dmic1_data_pin
;
/* 0 = IN2N; 1 = GPIO5; 2 = GPIO11 */
unsigned
int
dmic2_data_pin
;
...
...
@@ -24,8 +23,6 @@ struct rt5645_platform_data {
unsigned
int
hp_det_gpio
;
bool
gpio_hp_det_active_high
;
/* true if codec's jd function is used */
bool
en_jd_func
;
unsigned
int
jd_mode
;
};
...
...
sound/soc/codecs/rt5645.c
View file @
f3b368d3
...
...
@@ -18,7 +18,9 @@
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/acpi.h>
#include <linux/dmi.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
...
...
@@ -415,9 +417,9 @@ static bool rt5645_readable_register(struct device *dev, unsigned int reg)
}
static
const
DECLARE_TLV_DB_SCALE
(
out_vol_tlv
,
-
4650
,
150
,
0
);
static
const
DECLARE_TLV_DB_SCALE
(
dac_vol_tlv
,
-
65
625
,
3
75
,
0
);
static
const
DECLARE_TLV_DB_SCALE
(
dac_vol_tlv
,
-
65
25
,
75
,
0
);
static
const
DECLARE_TLV_DB_SCALE
(
in_vol_tlv
,
-
3450
,
150
,
0
);
static
const
DECLARE_TLV_DB_SCALE
(
adc_vol_tlv
,
-
17
625
,
3
75
,
0
);
static
const
DECLARE_TLV_DB_SCALE
(
adc_vol_tlv
,
-
17
25
,
75
,
0
);
static
const
DECLARE_TLV_DB_SCALE
(
adc_bst_tlv
,
0
,
1200
,
0
);
/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
...
...
@@ -432,30 +434,6 @@ static unsigned int bst_tlv[] = {
8
,
8
,
TLV_DB_SCALE_ITEM
(
5200
,
0
,
0
),
};
static
const
char
*
const
rt5645_tdm_data_swap_select
[]
=
{
"L/R"
,
"R/L"
,
"L/L"
,
"R/R"
};
static
SOC_ENUM_SINGLE_DECL
(
rt5645_tdm_adc_slot0_1_enum
,
RT5645_TDM_CTRL_1
,
6
,
rt5645_tdm_data_swap_select
);
static
SOC_ENUM_SINGLE_DECL
(
rt5645_tdm_adc_slot2_3_enum
,
RT5645_TDM_CTRL_1
,
4
,
rt5645_tdm_data_swap_select
);
static
SOC_ENUM_SINGLE_DECL
(
rt5645_tdm_adc_slot4_5_enum
,
RT5645_TDM_CTRL_1
,
2
,
rt5645_tdm_data_swap_select
);
static
SOC_ENUM_SINGLE_DECL
(
rt5645_tdm_adc_slot6_7_enum
,
RT5645_TDM_CTRL_1
,
0
,
rt5645_tdm_data_swap_select
);
static
const
char
*
const
rt5645_tdm_adc_data_select
[]
=
{
"1/2/R"
,
"2/1/R"
,
"R/1/2"
,
"R/2/1"
};
static
SOC_ENUM_SINGLE_DECL
(
rt5645_tdm_adc_sel_enum
,
RT5645_TDM_CTRL_1
,
8
,
rt5645_tdm_adc_data_select
);
static
const
struct
snd_kcontrol_new
rt5645_snd_controls
[]
=
{
/* Speaker Output Volume */
SOC_DOUBLE
(
"Speaker Channel Switch"
,
RT5645_SPK_VOL
,
...
...
@@ -481,9 +459,9 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
SOC_DOUBLE
(
"DAC2 Playback Switch"
,
RT5645_DAC_CTRL
,
RT5645_M_DAC_L2_VOL_SFT
,
RT5645_M_DAC_R2_VOL_SFT
,
1
,
1
),
SOC_DOUBLE_TLV
(
"DAC1 Playback Volume"
,
RT5645_DAC1_DIG_VOL
,
RT5645_L_VOL_SFT
,
RT5645_R_VOL_SFT
,
175
,
0
,
dac_vol_tlv
),
RT5645_L_VOL_SFT
+
1
,
RT5645_R_VOL_SFT
+
1
,
87
,
0
,
dac_vol_tlv
),
SOC_DOUBLE_TLV
(
"Mono DAC Playback Volume"
,
RT5645_DAC2_DIG_VOL
,
RT5645_L_VOL_SFT
,
RT5645_R_VOL_SFT
,
175
,
0
,
dac_vol_tlv
),
RT5645_L_VOL_SFT
+
1
,
RT5645_R_VOL_SFT
+
1
,
87
,
0
,
dac_vol_tlv
),
/* IN1/IN2 Control */
SOC_SINGLE_TLV
(
"IN1 Boost"
,
RT5645_IN1_CTRL1
,
...
...
@@ -499,11 +477,11 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
SOC_DOUBLE
(
"ADC Capture Switch"
,
RT5645_STO1_ADC_DIG_VOL
,
RT5645_L_MUTE_SFT
,
RT5645_R_MUTE_SFT
,
1
,
1
),
SOC_DOUBLE_TLV
(
"ADC Capture Volume"
,
RT5645_STO1_ADC_DIG_VOL
,
RT5645_L_VOL_SFT
,
RT5645_R_VOL_SFT
,
127
,
0
,
adc_vol_tlv
),
RT5645_L_VOL_SFT
+
1
,
RT5645_R_VOL_SFT
+
1
,
63
,
0
,
adc_vol_tlv
),
SOC_DOUBLE
(
"Mono ADC Capture Switch"
,
RT5645_MONO_ADC_DIG_VOL
,
RT5645_L_MUTE_SFT
,
RT5645_R_MUTE_SFT
,
1
,
1
),
SOC_DOUBLE_TLV
(
"Mono ADC Capture Volume"
,
RT5645_MONO_ADC_DIG_VOL
,
RT5645_L_VOL_SFT
,
RT5645_R_VOL_SFT
,
127
,
0
,
adc_vol_tlv
),
RT5645_L_VOL_SFT
+
1
,
RT5645_R_VOL_SFT
+
1
,
63
,
0
,
adc_vol_tlv
),
/* ADC Boost Volume Control */
SOC_DOUBLE_TLV
(
"STO1 ADC Boost Gain"
,
RT5645_ADC_BST_VOL1
,
...
...
@@ -516,17 +494,6 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
/* I2S2 function select */
SOC_SINGLE
(
"I2S2 Func Switch"
,
RT5645_GPIO_CTRL1
,
RT5645_I2S2_SEL_SFT
,
1
,
1
),
/* TDM */
SOC_ENUM
(
"TDM Adc Slot0 1 Data"
,
rt5645_tdm_adc_slot0_1_enum
),
SOC_ENUM
(
"TDM Adc Slot2 3 Data"
,
rt5645_tdm_adc_slot2_3_enum
),
SOC_ENUM
(
"TDM Adc Slot4 5 Data"
,
rt5645_tdm_adc_slot4_5_enum
),
SOC_ENUM
(
"TDM Adc Slot6 7 Data"
,
rt5645_tdm_adc_slot6_7_enum
),
SOC_ENUM
(
"TDM IF1 ADC DATA Sel"
,
rt5645_tdm_adc_sel_enum
),
SOC_SINGLE
(
"TDM IF1_DAC1_L Sel"
,
RT5645_TDM_CTRL_3
,
12
,
7
,
0
),
SOC_SINGLE
(
"TDM IF1_DAC1_R Sel"
,
RT5645_TDM_CTRL_3
,
8
,
7
,
0
),
SOC_SINGLE
(
"TDM IF1_DAC2_L Sel"
,
RT5645_TDM_CTRL_3
,
4
,
7
,
0
),
SOC_SINGLE
(
"TDM IF1_DAC2_R Sel"
,
RT5645_TDM_CTRL_3
,
0
,
7
,
0
),
};
/**
...
...
@@ -1093,7 +1060,8 @@ static const struct snd_kcontrol_new rt5645_mono_adc_r2_mux =
/* MX-77 [9:8] */
static
const
char
*
const
rt5645_if1_adc_in_src
[]
=
{
"IF_ADC1"
,
"IF_ADC2"
,
"VAD_ADC"
"IF_ADC1/IF_ADC2/VAD_ADC"
,
"IF_ADC2/IF_ADC1/VAD_ADC"
,
"VAD_ADC/IF_ADC1/IF_ADC2"
,
"VAD_ADC/IF_ADC2/IF_ADC1"
};
static
SOC_ENUM_SINGLE_DECL
(
...
...
@@ -1103,6 +1071,140 @@ static SOC_ENUM_SINGLE_DECL(
static
const
struct
snd_kcontrol_new
rt5645_if1_adc_in_mux
=
SOC_DAPM_ENUM
(
"IF1 ADC IN source"
,
rt5645_if1_adc_in_enum
);
/* MX-78 [4:0] */
static
const
char
*
const
rt5650_if1_adc_in_src
[]
=
{
"IF_ADC1/IF_ADC2/DAC_REF/Null"
,
"IF_ADC1/IF_ADC2/Null/DAC_REF"
,
"IF_ADC1/DAC_REF/IF_ADC2/Null"
,
"IF_ADC1/DAC_REF/Null/IF_ADC2"
,
"IF_ADC1/Null/DAC_REF/IF_ADC2"
,
"IF_ADC1/Null/IF_ADC2/DAC_REF"
,
"IF_ADC2/IF_ADC1/DAC_REF/Null"
,
"IF_ADC2/IF_ADC1/Null/DAC_REF"
,
"IF_ADC2/DAC_REF/IF_ADC1/Null"
,
"IF_ADC2/DAC_REF/Null/IF_ADC1"
,
"IF_ADC2/Null/DAC_REF/IF_ADC1"
,
"IF_ADC2/Null/IF_ADC1/DAC_REF"
,
"DAC_REF/IF_ADC1/IF_ADC2/Null"
,
"DAC_REF/IF_ADC1/Null/IF_ADC2"
,
"DAC_REF/IF_ADC2/IF_ADC1/Null"
,
"DAC_REF/IF_ADC2/Null/IF_ADC1"
,
"DAC_REF/Null/IF_ADC1/IF_ADC2"
,
"DAC_REF/Null/IF_ADC2/IF_ADC1"
,
"Null/IF_ADC1/IF_ADC2/DAC_REF"
,
"Null/IF_ADC1/DAC_REF/IF_ADC2"
,
"Null/IF_ADC2/IF_ADC1/DAC_REF"
,
"Null/IF_ADC2/DAC_REF/IF_ADC1"
,
"Null/DAC_REF/IF_ADC1/IF_ADC2"
,
"Null/DAC_REF/IF_ADC2/IF_ADC1"
,
};
static
SOC_ENUM_SINGLE_DECL
(
rt5650_if1_adc_in_enum
,
RT5645_TDM_CTRL_2
,
0
,
rt5650_if1_adc_in_src
);
static
const
struct
snd_kcontrol_new
rt5650_if1_adc_in_mux
=
SOC_DAPM_ENUM
(
"IF1 ADC IN source"
,
rt5650_if1_adc_in_enum
);
/* MX-78 [15:14][13:12][11:10] */
static
const
char
*
const
rt5645_tdm_adc_swap_select
[]
=
{
"L/R"
,
"R/L"
,
"L/L"
,
"R/R"
};
static
SOC_ENUM_SINGLE_DECL
(
rt5650_tdm_adc_slot0_1_enum
,
RT5645_TDM_CTRL_2
,
14
,
rt5645_tdm_adc_swap_select
);
static
const
struct
snd_kcontrol_new
rt5650_if1_adc1_in_mux
=
SOC_DAPM_ENUM
(
"IF1 ADC1 IN source"
,
rt5650_tdm_adc_slot0_1_enum
);
static
SOC_ENUM_SINGLE_DECL
(
rt5650_tdm_adc_slot2_3_enum
,
RT5645_TDM_CTRL_2
,
12
,
rt5645_tdm_adc_swap_select
);
static
const
struct
snd_kcontrol_new
rt5650_if1_adc2_in_mux
=
SOC_DAPM_ENUM
(
"IF1 ADC2 IN source"
,
rt5650_tdm_adc_slot2_3_enum
);
static
SOC_ENUM_SINGLE_DECL
(
rt5650_tdm_adc_slot4_5_enum
,
RT5645_TDM_CTRL_2
,
10
,
rt5645_tdm_adc_swap_select
);
static
const
struct
snd_kcontrol_new
rt5650_if1_adc3_in_mux
=
SOC_DAPM_ENUM
(
"IF1 ADC3 IN source"
,
rt5650_tdm_adc_slot4_5_enum
);
/* MX-77 [7:6][5:4][3:2] */
static
SOC_ENUM_SINGLE_DECL
(
rt5645_tdm_adc_slot0_1_enum
,
RT5645_TDM_CTRL_1
,
6
,
rt5645_tdm_adc_swap_select
);
static
const
struct
snd_kcontrol_new
rt5645_if1_adc1_in_mux
=
SOC_DAPM_ENUM
(
"IF1 ADC1 IN source"
,
rt5645_tdm_adc_slot0_1_enum
);
static
SOC_ENUM_SINGLE_DECL
(
rt5645_tdm_adc_slot2_3_enum
,
RT5645_TDM_CTRL_1
,
4
,
rt5645_tdm_adc_swap_select
);
static
const
struct
snd_kcontrol_new
rt5645_if1_adc2_in_mux
=
SOC_DAPM_ENUM
(
"IF1 ADC2 IN source"
,
rt5645_tdm_adc_slot2_3_enum
);
static
SOC_ENUM_SINGLE_DECL
(
rt5645_tdm_adc_slot4_5_enum
,
RT5645_TDM_CTRL_1
,
2
,
rt5645_tdm_adc_swap_select
);
static
const
struct
snd_kcontrol_new
rt5645_if1_adc3_in_mux
=
SOC_DAPM_ENUM
(
"IF1 ADC3 IN source"
,
rt5645_tdm_adc_slot4_5_enum
);
/* MX-79 [14:12][10:8][6:4][2:0] */
static
const
char
*
const
rt5645_tdm_dac_swap_select
[]
=
{
"Slot0"
,
"Slot1"
,
"Slot2"
,
"Slot3"
};
static
SOC_ENUM_SINGLE_DECL
(
rt5645_tdm_dac0_enum
,
RT5645_TDM_CTRL_3
,
12
,
rt5645_tdm_dac_swap_select
);
static
const
struct
snd_kcontrol_new
rt5645_if1_dac0_tdm_sel_mux
=
SOC_DAPM_ENUM
(
"IF1 DAC0 source"
,
rt5645_tdm_dac0_enum
);
static
SOC_ENUM_SINGLE_DECL
(
rt5645_tdm_dac1_enum
,
RT5645_TDM_CTRL_3
,
8
,
rt5645_tdm_dac_swap_select
);
static
const
struct
snd_kcontrol_new
rt5645_if1_dac1_tdm_sel_mux
=
SOC_DAPM_ENUM
(
"IF1 DAC1 source"
,
rt5645_tdm_dac1_enum
);
static
SOC_ENUM_SINGLE_DECL
(
rt5645_tdm_dac2_enum
,
RT5645_TDM_CTRL_3
,
4
,
rt5645_tdm_dac_swap_select
);
static
const
struct
snd_kcontrol_new
rt5645_if1_dac2_tdm_sel_mux
=
SOC_DAPM_ENUM
(
"IF1 DAC2 source"
,
rt5645_tdm_dac2_enum
);
static
SOC_ENUM_SINGLE_DECL
(
rt5645_tdm_dac3_enum
,
RT5645_TDM_CTRL_3
,
0
,
rt5645_tdm_dac_swap_select
);
static
const
struct
snd_kcontrol_new
rt5645_if1_dac3_tdm_sel_mux
=
SOC_DAPM_ENUM
(
"IF1 DAC3 source"
,
rt5645_tdm_dac3_enum
);
/* MX-7a [14:12][10:8][6:4][2:0] */
static
SOC_ENUM_SINGLE_DECL
(
rt5650_tdm_dac0_enum
,
RT5650_TDM_CTRL_4
,
12
,
rt5645_tdm_dac_swap_select
);
static
const
struct
snd_kcontrol_new
rt5650_if1_dac0_tdm_sel_mux
=
SOC_DAPM_ENUM
(
"IF1 DAC0 source"
,
rt5650_tdm_dac0_enum
);
static
SOC_ENUM_SINGLE_DECL
(
rt5650_tdm_dac1_enum
,
RT5650_TDM_CTRL_4
,
8
,
rt5645_tdm_dac_swap_select
);
static
const
struct
snd_kcontrol_new
rt5650_if1_dac1_tdm_sel_mux
=
SOC_DAPM_ENUM
(
"IF1 DAC1 source"
,
rt5650_tdm_dac1_enum
);
static
SOC_ENUM_SINGLE_DECL
(
rt5650_tdm_dac2_enum
,
RT5650_TDM_CTRL_4
,
4
,
rt5645_tdm_dac_swap_select
);
static
const
struct
snd_kcontrol_new
rt5650_if1_dac2_tdm_sel_mux
=
SOC_DAPM_ENUM
(
"IF1 DAC2 source"
,
rt5650_tdm_dac2_enum
);
static
SOC_ENUM_SINGLE_DECL
(
rt5650_tdm_dac3_enum
,
RT5650_TDM_CTRL_4
,
0
,
rt5645_tdm_dac_swap_select
);
static
const
struct
snd_kcontrol_new
rt5650_if1_dac3_tdm_sel_mux
=
SOC_DAPM_ENUM
(
"IF1 DAC3 source"
,
rt5650_tdm_dac3_enum
);
/* MX-2d [3] [2] */
static
const
char
*
const
rt5650_a_dac1_src
[]
=
{
"DAC1"
,
"Stereo DAC Mixer"
...
...
@@ -1227,52 +1329,79 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on)
if
(
on
)
{
if
(
hp_amp_power_count
<=
0
)
{
/* depop parameters */
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M2
,
RT5645_DEPOP_MASK
,
RT5645_DEPOP_MAN
);
snd_soc_write
(
codec
,
RT5645_DEPOP_M1
,
0x000d
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
RT5645_HP_DCC_INT1
,
0x9f01
);
mdelay
(
150
);
/* headphone amp power on */
snd_soc_update_bits
(
codec
,
RT5645_PWR_ANLG1
,
RT5645_PWR_FV1
|
RT5645_PWR_FV2
,
0
);
snd_soc_update_bits
(
codec
,
RT5645_PWR_VOL
,
RT5645_PWR_HV_L
|
RT5645_PWR_HV_R
,
RT5645_PWR_HV_L
|
RT5645_PWR_HV_R
);
snd_soc_update_bits
(
codec
,
RT5645_PWR_ANLG1
,
RT5645_PWR_HP_L
|
RT5645_PWR_HP_R
|
RT5645_PWR_HA
,
RT5645_PWR_HP_L
|
RT5645_PWR_HP_R
|
RT5645_PWR_HA
);
mdelay
(
5
);
snd_soc_update_bits
(
codec
,
RT5645_PWR_ANLG1
,
RT5645_PWR_FV1
|
RT5645_PWR_FV2
,
RT5645_PWR_FV1
|
RT5645_PWR_FV2
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_HP_CO_MASK
|
RT5645_HP_SG_MASK
,
RT5645_HP_CO_EN
|
RT5645_HP_SG_EN
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
0x14
,
0x1aaa
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
0x24
,
0x0430
);
if
(
rt5645
->
codec_type
==
CODEC_TYPE_RT5650
)
{
snd_soc_write
(
codec
,
RT5645_CHARGE_PUMP
,
0x0e06
);
snd_soc_write
(
codec
,
RT5645_DEPOP_M1
,
0x001d
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
0x3e
,
0x7400
);
snd_soc_write
(
codec
,
RT5645_DEPOP_M3
,
0x0737
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
RT5645_MAMP_INT_REG2
,
0xfc00
);
snd_soc_write
(
codec
,
RT5645_DEPOP_M2
,
0x1140
);
}
else
{
/* depop parameters */
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M2
,
RT5645_DEPOP_MASK
,
RT5645_DEPOP_MAN
);
snd_soc_write
(
codec
,
RT5645_DEPOP_M1
,
0x000d
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
RT5645_HP_DCC_INT1
,
0x9f01
);
mdelay
(
150
);
/* headphone amp power on */
snd_soc_update_bits
(
codec
,
RT5645_PWR_ANLG1
,
RT5645_PWR_FV1
|
RT5645_PWR_FV2
,
0
);
snd_soc_update_bits
(
codec
,
RT5645_PWR_VOL
,
RT5645_PWR_HV_L
|
RT5645_PWR_HV_R
,
RT5645_PWR_HV_L
|
RT5645_PWR_HV_R
);
snd_soc_update_bits
(
codec
,
RT5645_PWR_ANLG1
,
RT5645_PWR_HP_L
|
RT5645_PWR_HP_R
|
RT5645_PWR_HA
,
RT5645_PWR_HP_L
|
RT5645_PWR_HP_R
|
RT5645_PWR_HA
);
mdelay
(
5
);
snd_soc_update_bits
(
codec
,
RT5645_PWR_ANLG1
,
RT5645_PWR_FV1
|
RT5645_PWR_FV2
,
RT5645_PWR_FV1
|
RT5645_PWR_FV2
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_HP_CO_MASK
|
RT5645_HP_SG_MASK
,
RT5645_HP_CO_EN
|
RT5645_HP_SG_EN
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
0x14
,
0x1aaa
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
0x24
,
0x0430
);
}
}
hp_amp_power_count
++
;
}
else
{
hp_amp_power_count
--
;
if
(
hp_amp_power_count
<=
0
)
{
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_HP_SG_MASK
|
RT5645_HP_L_SMT_MASK
|
RT5645_HP_R_SMT_MASK
,
RT5645_HP_SG_DIS
|
RT5645_HP_L_SMT_DIS
|
RT5645_HP_R_SMT_DIS
);
/* headphone amp power down */
snd_soc_write
(
codec
,
RT5645_DEPOP_M1
,
0x0000
);
snd_soc_update_bits
(
codec
,
RT5645_PWR_ANLG1
,
RT5645_PWR_HP_L
|
RT5645_PWR_HP_R
|
RT5645_PWR_HA
,
0
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M2
,
RT5645_DEPOP_MASK
,
0
);
if
(
rt5645
->
codec_type
==
CODEC_TYPE_RT5650
)
{
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
0x3e
,
0x7400
);
snd_soc_write
(
codec
,
RT5645_DEPOP_M3
,
0x0737
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
RT5645_MAMP_INT_REG2
,
0xfc00
);
snd_soc_write
(
codec
,
RT5645_DEPOP_M2
,
0x1140
);
msleep
(
100
);
snd_soc_write
(
codec
,
RT5645_DEPOP_M1
,
0x0001
);
}
else
{
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_HP_SG_MASK
|
RT5645_HP_L_SMT_MASK
|
RT5645_HP_R_SMT_MASK
,
RT5645_HP_SG_DIS
|
RT5645_HP_L_SMT_DIS
|
RT5645_HP_R_SMT_DIS
);
/* headphone amp power down */
snd_soc_write
(
codec
,
RT5645_DEPOP_M1
,
0x0000
);
snd_soc_update_bits
(
codec
,
RT5645_PWR_ANLG1
,
RT5645_PWR_HP_L
|
RT5645_PWR_HP_R
|
RT5645_PWR_HA
,
0
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M2
,
RT5645_DEPOP_MASK
,
0
);
}
}
}
}
...
...
@@ -1287,56 +1416,52 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
case
SND_SOC_DAPM_POST_PMU
:
hp_amp_power
(
codec
,
1
);
/* headphone unmute sequence */
if
(
rt5645
->
codec_type
==
CODEC_TYPE_RT5650
)
{
snd_soc_write
(
codec
,
RT5645_DEPOP_M3
,
0x0737
);
}
else
{
if
(
rt5645
->
codec_type
==
CODEC_TYPE_RT5645
)
{
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M3
,
RT5645_CP_FQ1_MASK
|
RT5645_CP_FQ2_MASK
|
RT5645_CP_FQ3_MASK
,
(
RT5645_CP_FQ_192_KHZ
<<
RT5645_CP_FQ1_SFT
)
|
(
RT5645_CP_FQ_12_KHZ
<<
RT5645_CP_FQ2_SFT
)
|
(
RT5645_CP_FQ_192_KHZ
<<
RT5645_CP_FQ3_SFT
));
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
RT5645_MAMP_INT_REG2
,
0xfc00
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_SMT_TRIG_MASK
,
RT5645_SMT_TRIG_EN
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_RSTN_MASK
,
RT5645_RSTN_EN
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_RSTN_MASK
|
RT5645_HP_L_SMT_MASK
|
RT5645_HP_R_SMT_MASK
,
RT5645_RSTN_DIS
|
RT5645_HP_L_SMT_EN
|
RT5645_HP_R_SMT_EN
);
msleep
(
40
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_HP_SG_MASK
|
RT5645_HP_L_SMT_MASK
|
RT5645_HP_R_SMT_MASK
,
RT5645_HP_SG_DIS
|
RT5645_HP_L_SMT_DIS
|
RT5645_HP_R_SMT_DIS
);
}
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
RT5645_MAMP_INT_REG2
,
0xfc00
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_SMT_TRIG_MASK
,
RT5645_SMT_TRIG_EN
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_RSTN_MASK
,
RT5645_RSTN_EN
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_RSTN_MASK
|
RT5645_HP_L_SMT_MASK
|
RT5645_HP_R_SMT_MASK
,
RT5645_RSTN_DIS
|
RT5645_HP_L_SMT_EN
|
RT5645_HP_R_SMT_EN
);
msleep
(
40
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_HP_SG_MASK
|
RT5645_HP_L_SMT_MASK
|
RT5645_HP_R_SMT_MASK
,
RT5645_HP_SG_DIS
|
RT5645_HP_L_SMT_DIS
|
RT5645_HP_R_SMT_DIS
);
break
;
case
SND_SOC_DAPM_PRE_PMD
:
/* headphone mute sequence */
if
(
rt5645
->
codec_type
==
CODEC_TYPE_RT5650
)
{
snd_soc_write
(
codec
,
RT5645_DEPOP_M3
,
0x0737
);
}
else
{
if
(
rt5645
->
codec_type
==
CODEC_TYPE_RT5645
)
{
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M3
,
RT5645_CP_FQ1_MASK
|
RT5645_CP_FQ2_MASK
|
RT5645_CP_FQ3_MASK
,
(
RT5645_CP_FQ_96_KHZ
<<
RT5645_CP_FQ1_SFT
)
|
(
RT5645_CP_FQ_12_KHZ
<<
RT5645_CP_FQ2_SFT
)
|
(
RT5645_CP_FQ_96_KHZ
<<
RT5645_CP_FQ3_SFT
));
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
RT5645_MAMP_INT_REG2
,
0xfc00
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_HP_SG_MASK
,
RT5645_HP_SG_EN
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_RSTP_MASK
,
RT5645_RSTP_EN
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_RSTP_MASK
|
RT5645_HP_L_SMT_MASK
|
RT5645_HP_R_SMT_MASK
,
RT5645_RSTP_DIS
|
RT5645_HP_L_SMT_EN
|
RT5645_HP_R_SMT_EN
);
msleep
(
30
);
}
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
RT5645_MAMP_INT_REG2
,
0xfc00
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_HP_SG_MASK
,
RT5645_HP_SG_EN
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_RSTP_MASK
,
RT5645_RSTP_EN
);
snd_soc_update_bits
(
codec
,
RT5645_DEPOP_M1
,
RT5645_RSTP_MASK
|
RT5645_HP_L_SMT_MASK
|
RT5645_HP_R_SMT_MASK
,
RT5645_RSTP_DIS
|
RT5645_HP_L_SMT_EN
|
RT5645_HP_R_SMT_EN
);
msleep
(
30
);
hp_amp_power
(
codec
,
0
);
break
;
...
...
@@ -1571,20 +1696,50 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = {
SND_SOC_DAPM_PGA
(
"IF1_ADC4"
,
SND_SOC_NOPM
,
0
,
0
,
NULL
,
0
),
/* IF1 2 Mux */
SND_SOC_DAPM_MUX
(
"IF1 ADC Mux"
,
SND_SOC_NOPM
,
SND_SOC_DAPM_MUX
(
"RT5645 IF1 ADC1 Swap Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5645_if1_adc1_in_mux
),
SND_SOC_DAPM_MUX
(
"RT5645 IF1 ADC2 Swap Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5645_if1_adc2_in_mux
),
SND_SOC_DAPM_MUX
(
"RT5645 IF1 ADC3 Swap Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5645_if1_adc3_in_mux
),
SND_SOC_DAPM_MUX
(
"RT5645 IF1 ADC Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5645_if1_adc_in_mux
),
SND_SOC_DAPM_MUX
(
"RT5650 IF1 ADC1 Swap Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5650_if1_adc1_in_mux
),
SND_SOC_DAPM_MUX
(
"RT5650 IF1 ADC2 Swap Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5650_if1_adc2_in_mux
),
SND_SOC_DAPM_MUX
(
"RT5650 IF1 ADC3 Swap Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5650_if1_adc3_in_mux
),
SND_SOC_DAPM_MUX
(
"RT5650 IF1 ADC Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5650_if1_adc_in_mux
),
SND_SOC_DAPM_MUX
(
"IF2 ADC Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5645_if2_adc_in_mux
),
/* Digital Interface */
SND_SOC_DAPM_SUPPLY
(
"I2S1"
,
RT5645_PWR_DIG1
,
RT5645_PWR_I2S1_BIT
,
0
,
NULL
,
0
),
SND_SOC_DAPM_PGA
(
"IF1 DAC0"
,
SND_SOC_NOPM
,
0
,
0
,
NULL
,
0
),
SND_SOC_DAPM_PGA
(
"IF1 DAC1"
,
SND_SOC_NOPM
,
0
,
0
,
NULL
,
0
),
SND_SOC_DAPM_PGA
(
"IF1 DAC2"
,
SND_SOC_NOPM
,
0
,
0
,
NULL
,
0
),
SND_SOC_DAPM_PGA
(
"IF1 DAC1 L"
,
SND_SOC_NOPM
,
0
,
0
,
NULL
,
0
),
SND_SOC_DAPM_PGA
(
"IF1 DAC1 R"
,
SND_SOC_NOPM
,
0
,
0
,
NULL
,
0
),
SND_SOC_DAPM_PGA
(
"IF1 DAC2 L"
,
SND_SOC_NOPM
,
0
,
0
,
NULL
,
0
),
SND_SOC_DAPM_PGA
(
"IF1 DAC2 R"
,
SND_SOC_NOPM
,
0
,
0
,
NULL
,
0
),
SND_SOC_DAPM_PGA
(
"IF1 DAC3"
,
SND_SOC_NOPM
,
0
,
0
,
NULL
,
0
),
SND_SOC_DAPM_MUX
(
"RT5645 IF1 DAC1 L Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5645_if1_dac0_tdm_sel_mux
),
SND_SOC_DAPM_MUX
(
"RT5645 IF1 DAC1 R Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5645_if1_dac1_tdm_sel_mux
),
SND_SOC_DAPM_MUX
(
"RT5645 IF1 DAC2 L Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5645_if1_dac2_tdm_sel_mux
),
SND_SOC_DAPM_MUX
(
"RT5645 IF1 DAC2 R Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5645_if1_dac3_tdm_sel_mux
),
SND_SOC_DAPM_MUX
(
"RT5650 IF1 DAC1 L Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5650_if1_dac0_tdm_sel_mux
),
SND_SOC_DAPM_MUX
(
"RT5650 IF1 DAC1 R Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5650_if1_dac1_tdm_sel_mux
),
SND_SOC_DAPM_MUX
(
"RT5650 IF1 DAC2 L Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5650_if1_dac2_tdm_sel_mux
),
SND_SOC_DAPM_MUX
(
"RT5650 IF1 DAC2 R Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
rt5650_if1_dac3_tdm_sel_mux
),
SND_SOC_DAPM_PGA
(
"IF1 ADC"
,
SND_SOC_NOPM
,
0
,
0
,
NULL
,
0
),
SND_SOC_DAPM_PGA
(
"IF1 ADC L"
,
SND_SOC_NOPM
,
0
,
0
,
NULL
,
0
),
SND_SOC_DAPM_PGA
(
"IF1 ADC R"
,
SND_SOC_NOPM
,
0
,
0
,
NULL
,
0
),
...
...
@@ -1848,42 +2003,32 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = {
{
"IF_ADC2"
,
NULL
,
"Mono ADC MIXR"
},
{
"VAD_ADC"
,
NULL
,
"VAD ADC Mux"
},
{
"IF1 ADC Mux"
,
"IF_ADC1"
,
"IF_ADC1"
},
{
"IF1 ADC Mux"
,
"IF_ADC2"
,
"IF_ADC2"
},
{
"IF1 ADC Mux"
,
"VAD_ADC"
,
"VAD_ADC"
},
{
"IF2 ADC Mux"
,
"IF_ADC1"
,
"IF_ADC1"
},
{
"IF2 ADC Mux"
,
"IF_ADC2"
,
"IF_ADC2"
},
{
"IF2 ADC Mux"
,
"VAD_ADC"
,
"VAD_ADC"
},
{
"IF1 ADC"
,
NULL
,
"I2S1"
},
{
"IF1 ADC"
,
NULL
,
"IF1 ADC Mux"
},
{
"IF2 ADC"
,
NULL
,
"I2S2"
},
{
"IF2 ADC"
,
NULL
,
"IF2 ADC Mux"
},
{
"AIF1TX"
,
NULL
,
"IF1 ADC"
},
{
"AIF1TX"
,
NULL
,
"IF2 ADC"
},
{
"AIF2TX"
,
NULL
,
"IF2 ADC"
},
{
"IF1 DAC0"
,
NULL
,
"AIF1RX"
},
{
"IF1 DAC1"
,
NULL
,
"AIF1RX"
},
{
"IF1 DAC2"
,
NULL
,
"AIF1RX"
},
{
"IF1 DAC3"
,
NULL
,
"AIF1RX"
},
{
"IF2 DAC"
,
NULL
,
"AIF2RX"
},
{
"IF1 DAC0"
,
NULL
,
"I2S1"
},
{
"IF1 DAC1"
,
NULL
,
"I2S1"
},
{
"IF1 DAC2"
,
NULL
,
"I2S1"
},
{
"IF1 DAC3"
,
NULL
,
"I2S1"
},
{
"IF2 DAC"
,
NULL
,
"I2S2"
},
{
"IF1 DAC2 L"
,
NULL
,
"IF1 DAC2"
},
{
"IF1 DAC2 R"
,
NULL
,
"IF1 DAC2"
},
{
"IF1 DAC1 L"
,
NULL
,
"IF1 DAC1"
},
{
"IF1 DAC1 R"
,
NULL
,
"IF1 DAC1"
},
{
"IF2 DAC L"
,
NULL
,
"IF2 DAC"
},
{
"IF2 DAC R"
,
NULL
,
"IF2 DAC"
},
{
"DAC1 L Mux"
,
"IF1 DAC"
,
"IF1 DAC1 L"
},
{
"DAC1 L Mux"
,
"IF2 DAC"
,
"IF2 DAC L"
},
{
"DAC1 R Mux"
,
"IF1 DAC"
,
"IF1 DAC1 R"
},
{
"DAC1 R Mux"
,
"IF2 DAC"
,
"IF2 DAC R"
},
{
"DAC1 MIXL"
,
"Stereo ADC Switch"
,
"Stereo1 ADC MIXL"
},
...
...
@@ -1893,14 +2038,12 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = {
{
"DAC1 MIXR"
,
"DAC1 Switch"
,
"DAC1 R Mux"
},
{
"DAC1 MIXR"
,
NULL
,
"dac stereo1 filter"
},
{
"DAC L2 Mux"
,
"IF1 DAC"
,
"IF1 DAC2 L"
},
{
"DAC L2 Mux"
,
"IF2 DAC"
,
"IF2 DAC L"
},
{
"DAC L2 Mux"
,
"Mono ADC"
,
"Mono ADC MIXL"
},
{
"DAC L2 Mux"
,
"VAD_ADC"
,
"VAD_ADC"
},
{
"DAC L2 Volume"
,
NULL
,
"DAC L2 Mux"
},
{
"DAC L2 Volume"
,
NULL
,
"dac mono left filter"
},
{
"DAC R2 Mux"
,
"IF1 DAC"
,
"IF1 DAC2 R"
},
{
"DAC R2 Mux"
,
"IF2 DAC"
,
"IF2 DAC R"
},
{
"DAC R2 Mux"
,
"Mono ADC"
,
"Mono ADC MIXR"
},
{
"DAC R2 Mux"
,
"Haptic"
,
"Haptic Generator"
},
...
...
@@ -2038,6 +2181,80 @@ static const struct snd_soc_dapm_route rt5650_specific_dapm_routes[] = {
{
"DAC R1"
,
NULL
,
"A DAC1 R Mux"
},
{
"DAC L2"
,
NULL
,
"A DAC2 L Mux"
},
{
"DAC R2"
,
NULL
,
"A DAC2 R Mux"
},
{
"RT5650 IF1 ADC1 Swap Mux"
,
"L/R"
,
"IF_ADC1"
},
{
"RT5650 IF1 ADC1 Swap Mux"
,
"R/L"
,
"IF_ADC1"
},
{
"RT5650 IF1 ADC1 Swap Mux"
,
"L/L"
,
"IF_ADC1"
},
{
"RT5650 IF1 ADC1 Swap Mux"
,
"R/R"
,
"IF_ADC1"
},
{
"RT5650 IF1 ADC2 Swap Mux"
,
"L/R"
,
"IF_ADC2"
},
{
"RT5650 IF1 ADC2 Swap Mux"
,
"R/L"
,
"IF_ADC2"
},
{
"RT5650 IF1 ADC2 Swap Mux"
,
"L/L"
,
"IF_ADC2"
},
{
"RT5650 IF1 ADC2 Swap Mux"
,
"R/R"
,
"IF_ADC2"
},
{
"RT5650 IF1 ADC3 Swap Mux"
,
"L/R"
,
"VAD_ADC"
},
{
"RT5650 IF1 ADC3 Swap Mux"
,
"R/L"
,
"VAD_ADC"
},
{
"RT5650 IF1 ADC3 Swap Mux"
,
"L/L"
,
"VAD_ADC"
},
{
"RT5650 IF1 ADC3 Swap Mux"
,
"R/R"
,
"VAD_ADC"
},
{
"IF1 ADC"
,
NULL
,
"RT5650 IF1 ADC1 Swap Mux"
},
{
"IF1 ADC"
,
NULL
,
"RT5650 IF1 ADC2 Swap Mux"
},
{
"IF1 ADC"
,
NULL
,
"RT5650 IF1 ADC3 Swap Mux"
},
{
"RT5650 IF1 ADC Mux"
,
"IF_ADC1/IF_ADC2/DAC_REF/Null"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"IF_ADC1/IF_ADC2/Null/DAC_REF"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"IF_ADC1/DAC_REF/IF_ADC2/Null"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"IF_ADC1/DAC_REF/Null/IF_ADC2"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"IF_ADC1/Null/DAC_REF/IF_ADC2"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"IF_ADC1/Null/IF_ADC2/DAC_REF"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"IF_ADC2/IF_ADC1/DAC_REF/Null"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"IF_ADC2/IF_ADC1/Null/DAC_REF"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"IF_ADC2/DAC_REF/IF_ADC1/Null"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"IF_ADC2/DAC_REF/Null/IF_ADC1"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"IF_ADC2/Null/DAC_REF/IF_ADC1"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"IF_ADC2/Null/IF_ADC1/DAC_REF"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"DAC_REF/IF_ADC1/IF_ADC2/Null"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"DAC_REF/IF_ADC1/Null/IF_ADC2"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"DAC_REF/IF_ADC2/IF_ADC1/Null"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"DAC_REF/IF_ADC2/Null/IF_ADC1"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"DAC_REF/Null/IF_ADC1/IF_ADC2"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"DAC_REF/Null/IF_ADC2/IF_ADC1"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"Null/IF_ADC1/IF_ADC2/DAC_REF"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"Null/IF_ADC1/DAC_REF/IF_ADC2"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"Null/IF_ADC2/IF_ADC1/DAC_REF"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"Null/IF_ADC2/DAC_REF/IF_ADC1"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"Null/DAC_REF/IF_ADC1/IF_ADC2"
,
"IF1 ADC"
},
{
"RT5650 IF1 ADC Mux"
,
"Null/DAC_REF/IF_ADC2/IF_ADC1"
,
"IF1 ADC"
},
{
"AIF1TX"
,
NULL
,
"RT5650 IF1 ADC Mux"
},
{
"RT5650 IF1 DAC1 L Mux"
,
"Slot0"
,
"IF1 DAC0"
},
{
"RT5650 IF1 DAC1 L Mux"
,
"Slot1"
,
"IF1 DAC1"
},
{
"RT5650 IF1 DAC1 L Mux"
,
"Slot2"
,
"IF1 DAC2"
},
{
"RT5650 IF1 DAC1 L Mux"
,
"Slot3"
,
"IF1 DAC3"
},
{
"RT5650 IF1 DAC1 R Mux"
,
"Slot0"
,
"IF1 DAC0"
},
{
"RT5650 IF1 DAC1 R Mux"
,
"Slot1"
,
"IF1 DAC1"
},
{
"RT5650 IF1 DAC1 R Mux"
,
"Slot2"
,
"IF1 DAC2"
},
{
"RT5650 IF1 DAC1 R Mux"
,
"Slot3"
,
"IF1 DAC3"
},
{
"RT5650 IF1 DAC2 L Mux"
,
"Slot0"
,
"IF1 DAC0"
},
{
"RT5650 IF1 DAC2 L Mux"
,
"Slot1"
,
"IF1 DAC1"
},
{
"RT5650 IF1 DAC2 L Mux"
,
"Slot2"
,
"IF1 DAC2"
},
{
"RT5650 IF1 DAC2 L Mux"
,
"Slot3"
,
"IF1 DAC3"
},
{
"RT5650 IF1 DAC2 R Mux"
,
"Slot0"
,
"IF1 DAC0"
},
{
"RT5650 IF1 DAC2 R Mux"
,
"Slot1"
,
"IF1 DAC1"
},
{
"RT5650 IF1 DAC2 R Mux"
,
"Slot2"
,
"IF1 DAC2"
},
{
"RT5650 IF1 DAC2 R Mux"
,
"Slot3"
,
"IF1 DAC3"
},
{
"DAC1 L Mux"
,
"IF1 DAC"
,
"RT5650 IF1 DAC1 L Mux"
},
{
"DAC1 R Mux"
,
"IF1 DAC"
,
"RT5650 IF1 DAC1 R Mux"
},
{
"DAC L2 Mux"
,
"IF1 DAC"
,
"RT5650 IF1 DAC2 L Mux"
},
{
"DAC R2 Mux"
,
"IF1 DAC"
,
"RT5650 IF1 DAC2 R Mux"
},
};
static
const
struct
snd_soc_dapm_route
rt5645_specific_dapm_routes
[]
=
{
...
...
@@ -2045,6 +2262,57 @@ static const struct snd_soc_dapm_route rt5645_specific_dapm_routes[] = {
{
"DAC R1"
,
NULL
,
"Stereo DAC MIXR"
},
{
"DAC L2"
,
NULL
,
"Mono DAC MIXL"
},
{
"DAC R2"
,
NULL
,
"Mono DAC MIXR"
},
{
"RT5645 IF1 ADC1 Swap Mux"
,
"L/R"
,
"IF_ADC1"
},
{
"RT5645 IF1 ADC1 Swap Mux"
,
"R/L"
,
"IF_ADC1"
},
{
"RT5645 IF1 ADC1 Swap Mux"
,
"L/L"
,
"IF_ADC1"
},
{
"RT5645 IF1 ADC1 Swap Mux"
,
"R/R"
,
"IF_ADC1"
},
{
"RT5645 IF1 ADC2 Swap Mux"
,
"L/R"
,
"IF_ADC2"
},
{
"RT5645 IF1 ADC2 Swap Mux"
,
"R/L"
,
"IF_ADC2"
},
{
"RT5645 IF1 ADC2 Swap Mux"
,
"L/L"
,
"IF_ADC2"
},
{
"RT5645 IF1 ADC2 Swap Mux"
,
"R/R"
,
"IF_ADC2"
},
{
"RT5645 IF1 ADC3 Swap Mux"
,
"L/R"
,
"VAD_ADC"
},
{
"RT5645 IF1 ADC3 Swap Mux"
,
"R/L"
,
"VAD_ADC"
},
{
"RT5645 IF1 ADC3 Swap Mux"
,
"L/L"
,
"VAD_ADC"
},
{
"RT5645 IF1 ADC3 Swap Mux"
,
"R/R"
,
"VAD_ADC"
},
{
"IF1 ADC"
,
NULL
,
"RT5645 IF1 ADC1 Swap Mux"
},
{
"IF1 ADC"
,
NULL
,
"RT5645 IF1 ADC2 Swap Mux"
},
{
"IF1 ADC"
,
NULL
,
"RT5645 IF1 ADC3 Swap Mux"
},
{
"RT5645 IF1 ADC Mux"
,
"IF_ADC1/IF_ADC2/VAD_ADC"
,
"IF1 ADC"
},
{
"RT5645 IF1 ADC Mux"
,
"IF_ADC2/IF_ADC1/VAD_ADC"
,
"IF1 ADC"
},
{
"RT5645 IF1 ADC Mux"
,
"VAD_ADC/IF_ADC1/IF_ADC2"
,
"IF1 ADC"
},
{
"RT5645 IF1 ADC Mux"
,
"VAD_ADC/IF_ADC2/IF_ADC1"
,
"IF1 ADC"
},
{
"AIF1TX"
,
NULL
,
"RT5645 IF1 ADC Mux"
},
{
"RT5645 IF1 DAC1 L Mux"
,
"Slot0"
,
"IF1 DAC0"
},
{
"RT5645 IF1 DAC1 L Mux"
,
"Slot1"
,
"IF1 DAC1"
},
{
"RT5645 IF1 DAC1 L Mux"
,
"Slot2"
,
"IF1 DAC2"
},
{
"RT5645 IF1 DAC1 L Mux"
,
"Slot3"
,
"IF1 DAC3"
},
{
"RT5645 IF1 DAC1 R Mux"
,
"Slot0"
,
"IF1 DAC0"
},
{
"RT5645 IF1 DAC1 R Mux"
,
"Slot1"
,
"IF1 DAC1"
},
{
"RT5645 IF1 DAC1 R Mux"
,
"Slot2"
,
"IF1 DAC2"
},
{
"RT5645 IF1 DAC1 R Mux"
,
"Slot3"
,
"IF1 DAC3"
},
{
"RT5645 IF1 DAC2 L Mux"
,
"Slot0"
,
"IF1 DAC0"
},
{
"RT5645 IF1 DAC2 L Mux"
,
"Slot1"
,
"IF1 DAC1"
},
{
"RT5645 IF1 DAC2 L Mux"
,
"Slot2"
,
"IF1 DAC2"
},
{
"RT5645 IF1 DAC2 L Mux"
,
"Slot3"
,
"IF1 DAC3"
},
{
"RT5645 IF1 DAC2 R Mux"
,
"Slot0"
,
"IF1 DAC0"
},
{
"RT5645 IF1 DAC2 R Mux"
,
"Slot1"
,
"IF1 DAC1"
},
{
"RT5645 IF1 DAC2 R Mux"
,
"Slot2"
,
"IF1 DAC2"
},
{
"RT5645 IF1 DAC2 R Mux"
,
"Slot3"
,
"IF1 DAC3"
},
{
"DAC1 L Mux"
,
"IF1 DAC"
,
"RT5645 IF1 DAC1 L Mux"
},
{
"DAC1 R Mux"
,
"IF1 DAC"
,
"RT5645 IF1 DAC1 R Mux"
},
{
"DAC L2 Mux"
,
"IF1 DAC"
,
"RT5645 IF1 DAC2 L Mux"
},
{
"DAC R2 Mux"
,
"IF1 DAC"
,
"RT5645 IF1 DAC2 R Mux"
},
};
static
int
rt5645_hw_params
(
struct
snd_pcm_substream
*
substream
,
...
...
@@ -2102,9 +2370,8 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream,
switch
(
dai
->
id
)
{
case
RT5645_AIF1
:
mask_clk
=
RT5645_I2S_BCLK_MS1_MASK
|
RT5645_I2S_PD1_MASK
;
val_clk
=
bclk_ms
<<
RT5645_I2S_BCLK_MS1_SFT
|
pre_div
<<
RT5645_I2S_PD1_SFT
;
mask_clk
=
RT5645_I2S_PD1_MASK
;
val_clk
=
pre_div
<<
RT5645_I2S_PD1_SFT
;
snd_soc_update_bits
(
codec
,
RT5645_I2S1_SDP
,
(
0x3
<<
dl_sft
),
(
val_len
<<
dl_sft
));
snd_soc_update_bits
(
codec
,
RT5645_ADDA_CLK1
,
mask_clk
,
val_clk
);
...
...
@@ -2369,6 +2636,8 @@ static int rt5645_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
static
int
rt5645_set_bias_level
(
struct
snd_soc_codec
*
codec
,
enum
snd_soc_bias_level
level
)
{
struct
rt5645_priv
*
rt5645
=
snd_soc_codec_get_drvdata
(
codec
);
switch
(
level
)
{
case
SND_SOC_BIAS_PREPARE
:
if
(
SND_SOC_BIAS_STANDBY
==
codec
->
dapm
.
bias_level
)
{
...
...
@@ -2399,8 +2668,9 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec,
case
SND_SOC_BIAS_OFF
:
snd_soc_write
(
codec
,
RT5645_DEPOP_M2
,
0x1100
);
snd_soc_update_bits
(
codec
,
RT5645_GEN_CTRL1
,
RT5645_DIG_GATE_CTRL
,
0
);
if
(
!
rt5645
->
en_button_func
)
snd_soc_update_bits
(
codec
,
RT5645_GEN_CTRL1
,
RT5645_DIG_GATE_CTRL
,
0
);
snd_soc_update_bits
(
codec
,
RT5645_PWR_ANLG1
,
RT5645_PWR_VREF1
|
RT5645_PWR_MB
|
RT5645_PWR_BG
|
RT5645_PWR_VREF2
|
...
...
@@ -2414,67 +2684,218 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec,
return
0
;
}
static
int
rt56
45_jack_detect
(
struct
snd_soc_codec
*
codec
)
static
int
rt56
50_calibration
(
struct
rt5645_priv
*
rt5645
)
{
struct
rt5645_priv
*
rt5645
=
snd_soc_codec_get_drvdata
(
codec
);
int
gpio_state
,
jack_type
=
0
;
unsigned
int
val
;
int
val
,
i
;
int
ret
=
-
1
;
if
(
!
gpio_is_valid
(
rt5645
->
pdata
.
hp_det_gpio
))
{
dev_err
(
codec
->
dev
,
"invalid gpio
\n
"
);
return
-
EINVAL
;
regcache_cache_bypass
(
rt5645
->
regmap
,
true
);
regmap_write
(
rt5645
->
regmap
,
RT5645_RESET
,
0
);
regmap_write
(
rt5645
->
regmap
,
RT5645_GEN_CTRL3
,
0x0800
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
RT5645_CHOP_DAC_ADC
,
0x3600
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
0x25
,
0x7000
);
regmap_write
(
rt5645
->
regmap
,
RT5645_I2S1_SDP
,
0x8008
);
/* headset type */
regmap_write
(
rt5645
->
regmap
,
RT5645_GEN_CTRL1
,
0x2061
);
regmap_write
(
rt5645
->
regmap
,
RT5645_CHARGE_PUMP
,
0x0006
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PWR_ANLG1
,
0x2012
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PWR_MIXER
,
0x0002
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PWR_VOL
,
0x0020
);
regmap_write
(
rt5645
->
regmap
,
RT5645_JD_CTRL3
,
0x00f0
);
regmap_write
(
rt5645
->
regmap
,
RT5645_IN1_CTRL1
,
0x0006
);
regmap_write
(
rt5645
->
regmap
,
RT5645_IN1_CTRL2
,
0x1827
);
regmap_write
(
rt5645
->
regmap
,
RT5645_IN1_CTRL2
,
0x0827
);
msleep
(
400
);
/* Inline command */
regmap_write
(
rt5645
->
regmap
,
RT5645_DEPOP_M1
,
0x0001
);
regmap_write
(
rt5645
->
regmap
,
RT5650_4BTN_IL_CMD2
,
0xc000
);
regmap_write
(
rt5645
->
regmap
,
RT5650_4BTN_IL_CMD1
,
0x0008
);
/* Calbration */
regmap_write
(
rt5645
->
regmap
,
RT5645_GLB_CLK
,
0x8000
);
regmap_write
(
rt5645
->
regmap
,
RT5645_DEPOP_M1
,
0x0000
);
regmap_write
(
rt5645
->
regmap
,
RT5650_4BTN_IL_CMD2
,
0xc000
);
regmap_write
(
rt5645
->
regmap
,
RT5650_4BTN_IL_CMD1
,
0x0008
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PWR_DIG2
,
0x8800
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PWR_ANLG1
,
0xe8fa
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PWR_ANLG2
,
0x8c04
);
regmap_write
(
rt5645
->
regmap
,
RT5645_DEPOP_M2
,
0x3100
);
regmap_write
(
rt5645
->
regmap
,
RT5645_CHARGE_PUMP
,
0x0e06
);
regmap_write
(
rt5645
->
regmap
,
RT5645_BASS_BACK
,
0x8a13
);
regmap_write
(
rt5645
->
regmap
,
RT5645_GEN_CTRL3
,
0x0820
);
regmap_write
(
rt5645
->
regmap
,
RT5645_DEPOP_M1
,
0x000d
);
/* Power on and Calbration */
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
RT5645_HP_DCC_INT1
,
0x9f01
);
msleep
(
200
);
for
(
i
=
0
;
i
<
5
;
i
++
)
{
regmap_read
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
0x7a
,
&
val
);
if
(
val
!=
0
&&
val
!=
0x3f3f
)
{
ret
=
0
;
break
;
}
msleep
(
50
);
}
gpio_state
=
gpio_get_value
(
rt5645
->
pdata
.
hp_det_gpio
);
pr_debug
(
"%s: PR-7A = 0x%x
\n
"
,
__func__
,
val
);
/* mute */
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
0x3e
,
0x7400
);
regmap_write
(
rt5645
->
regmap
,
RT5645_DEPOP_M3
,
0x0737
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PR_BASE
+
RT5645_MAMP_INT_REG2
,
0xfc00
);
regmap_write
(
rt5645
->
regmap
,
RT5645_DEPOP_M2
,
0x1140
);
regmap_write
(
rt5645
->
regmap
,
RT5645_DEPOP_M1
,
0x0000
);
regmap_write
(
rt5645
->
regmap
,
RT5645_GEN_CTRL2
,
0x4020
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PWR_ANLG2
,
0x0006
);
regmap_write
(
rt5645
->
regmap
,
RT5645_PWR_DIG2
,
0x0000
);
msleep
(
350
);
regcache_cache_bypass
(
rt5645
->
regmap
,
false
);
return
ret
;
}
dev_dbg
(
codec
->
dev
,
"gpio = %d(%d)
\n
"
,
rt5645
->
pdata
.
hp_det_gpio
,
gpio_state
);
static
void
rt5645_enable_push_button_irq
(
struct
snd_soc_codec
*
codec
,
bool
enable
)
{
struct
rt5645_priv
*
rt5645
=
snd_soc_codec_get_drvdata
(
codec
);
if
((
rt5645
->
pdata
.
gpio_hp_det_active_high
&&
gpio_state
)
||
(
!
rt5645
->
pdata
.
gpio_hp_det_active_high
&&
!
gpio_state
))
{
snd_soc_dapm_force_enable_pin
(
&
codec
->
dapm
,
"micbias1"
);
snd_soc_dapm_force_enable_pin
(
&
codec
->
dapm
,
"micbias2"
);
snd_soc_dapm_force_enable_pin
(
&
codec
->
dapm
,
"LDO2"
);
snd_soc_dapm_force_enable_pin
(
&
codec
->
dapm
,
"Mic Det Power"
);
snd_soc_dapm_sync
(
&
codec
->
dapm
);
if
(
enable
)
{
snd_soc_dapm_force_enable_pin_unlocked
(
&
codec
->
dapm
,
"ADC L power"
);
snd_soc_dapm_force_enable_pin_unlocked
(
&
codec
->
dapm
,
"ADC R power"
);
snd_soc_dapm_force_enable_pin_unlocked
(
&
codec
->
dapm
,
"LDO2"
);
snd_soc_dapm_force_enable_pin_unlocked
(
&
codec
->
dapm
,
"Mic Det Power"
);
snd_soc_dapm_sync_unlocked
(
&
codec
->
dapm
);
snd_soc_update_bits
(
codec
,
RT5645_INT_IRQ_ST
,
0x8
,
0x8
);
snd_soc_update_bits
(
codec
,
RT5650_4BTN_IL_CMD2
,
0x8000
,
0x8000
);
snd_soc_read
(
codec
,
RT5650_4BTN_IL_CMD1
);
pr_debug
(
"%s read %x = %x
\n
"
,
__func__
,
RT5650_4BTN_IL_CMD1
,
snd_soc_read
(
codec
,
RT5650_4BTN_IL_CMD1
));
}
else
{
snd_soc_update_bits
(
codec
,
RT5650_4BTN_IL_CMD2
,
0x8000
,
0x0
);
snd_soc_update_bits
(
codec
,
RT5645_INT_IRQ_ST
,
0x8
,
0x0
);
snd_soc_dapm_disable_pin_unlocked
(
&
codec
->
dapm
,
"ADC L power"
);
snd_soc_dapm_disable_pin_unlocked
(
&
codec
->
dapm
,
"ADC R power"
);
if
(
rt5645
->
pdata
.
jd_mode
==
0
)
snd_soc_dapm_disable_pin_unlocked
(
&
codec
->
dapm
,
"LDO2"
);
snd_soc_dapm_disable_pin_unlocked
(
&
codec
->
dapm
,
"Mic Det Power"
);
snd_soc_dapm_sync_unlocked
(
&
codec
->
dapm
);
}
}
snd_soc_write
(
codec
,
RT5645_IN1_CTRL1
,
0x0006
);
snd_soc_write
(
codec
,
RT5645_JD_CTRL3
,
0x00b0
);
static
int
rt5645_jack_detect
(
struct
snd_soc_codec
*
codec
,
int
jack_insert
)
{
struct
rt5645_priv
*
rt5645
=
snd_soc_codec_get_drvdata
(
codec
);
unsigned
int
val
;
snd_soc_update_bits
(
codec
,
RT5645_IN1_CTRL2
,
RT5645_CBJ_MN_JD
,
0
);
snd_soc_update_bits
(
codec
,
RT5645_IN1_CTRL2
,
RT5645_CBJ_MN_JD
,
RT5645_CBJ_MN_JD
);
if
(
jack_insert
)
{
regmap_write
(
rt5645
->
regmap
,
RT5645_CHARGE_PUMP
,
0x0006
);
if
(
codec
->
component
.
card
->
instantiated
)
{
/* for jack type detect */
snd_soc_dapm_force_enable_pin
(
&
codec
->
dapm
,
"LDO2"
);
snd_soc_dapm_force_enable_pin
(
&
codec
->
dapm
,
"Mic Det Power"
);
snd_soc_dapm_sync
(
&
codec
->
dapm
);
}
else
{
/* Power up necessary bits for JD if dapm is
not ready yet */
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_PWR_ANLG1
,
RT5645_PWR_MB
|
RT5645_PWR_VREF2
,
RT5645_PWR_MB
|
RT5645_PWR_VREF2
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_PWR_MIXER
,
RT5645_PWR_LDO2
,
RT5645_PWR_LDO2
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_PWR_VOL
,
RT5645_PWR_MIC_DET
,
RT5645_PWR_MIC_DET
);
}
msleep
(
400
);
val
=
snd_soc_read
(
codec
,
RT5645_IN1_CTRL3
)
&
0x7
;
regmap_write
(
rt5645
->
regmap
,
RT5645_JD_CTRL3
,
0x00f0
);
regmap_write
(
rt5645
->
regmap
,
RT5645_IN1_CTRL1
,
0x0006
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_IN1_CTRL2
,
0x1000
,
0x1000
);
msleep
(
100
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_IN1_CTRL2
,
0x1000
,
0x0000
);
msleep
(
450
);
regmap_read
(
rt5645
->
regmap
,
RT5645_IN1_CTRL3
,
&
val
);
val
&=
0x7
;
dev_dbg
(
codec
->
dev
,
"val = %d
\n
"
,
val
);
if
(
val
==
1
||
val
==
2
)
jack_type
=
SND_JACK_HEADSET
;
else
jack_type
=
SND_JACK_HEADPHONE
;
if
(
val
==
1
||
val
==
2
)
{
rt5645
->
jack_type
=
SND_JACK_HEADSET
;
if
(
rt5645
->
en_button_func
)
{
rt5645_enable_push_button_irq
(
codec
,
true
);
}
}
else
{
if
(
codec
->
component
.
card
->
instantiated
)
{
snd_soc_dapm_disable_pin
(
&
codec
->
dapm
,
"Mic Det Power"
);
snd_soc_dapm_sync
(
&
codec
->
dapm
);
}
else
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_PWR_VOL
,
RT5645_PWR_MIC_DET
,
0
);
rt5645
->
jack_type
=
SND_JACK_HEADPHONE
;
}
snd_soc_dapm_disable_pin
(
&
codec
->
dapm
,
"micbias1"
);
snd_soc_dapm_disable_pin
(
&
codec
->
dapm
,
"micbias2"
);
if
(
rt5645
->
pdata
.
jd_mode
==
0
)
snd_soc_dapm_disable_pin
(
&
codec
->
dapm
,
"LDO2"
);
snd_soc_dapm_disable_pin
(
&
codec
->
dapm
,
"Mic Det Power"
);
snd_soc_dapm_sync
(
&
codec
->
dapm
);
}
else
{
/* jack out */
rt5645
->
jack_type
=
0
;
if
(
rt5645
->
en_button_func
)
rt5645_enable_push_button_irq
(
codec
,
false
);
else
{
if
(
codec
->
component
.
card
->
instantiated
)
{
if
(
rt5645
->
pdata
.
jd_mode
==
0
)
snd_soc_dapm_disable_pin
(
&
codec
->
dapm
,
"LDO2"
);
snd_soc_dapm_disable_pin
(
&
codec
->
dapm
,
"Mic Det Power"
);
snd_soc_dapm_sync
(
&
codec
->
dapm
);
}
else
{
if
(
rt5645
->
pdata
.
jd_mode
==
0
)
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_PWR_MIXER
,
RT5645_PWR_LDO2
,
0
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_PWR_VOL
,
RT5645_PWR_MIC_DET
,
0
);
}
}
}
snd_soc_jack_report
(
rt5645
->
hp_jack
,
jack_type
,
SND_JACK_HEADPHONE
);
snd_soc_jack_report
(
rt5645
->
mic_jack
,
jack_type
,
SND_JACK_MICROPHONE
);
return
0
;
return
rt5645
->
jack_type
;
}
static
int
rt5645_irq_detection
(
struct
rt5645_priv
*
rt5645
);
static
irqreturn_t
rt5645_irq
(
int
irq
,
void
*
data
);
int
rt5645_set_jack_detect
(
struct
snd_soc_codec
*
codec
,
struct
snd_soc_jack
*
hp_jack
,
struct
snd_soc_jack
*
mic_jack
)
struct
snd_soc_jack
*
hp_jack
,
struct
snd_soc_jack
*
mic_jack
,
struct
snd_soc_jack
*
btn_jack
)
{
struct
rt5645_priv
*
rt5645
=
snd_soc_codec_get_drvdata
(
codec
);
rt5645
->
hp_jack
=
hp_jack
;
rt5645
->
mic_jack
=
mic_jack
;
rt5645_jack_detect
(
codec
);
rt5645
->
btn_jack
=
btn_jack
;
if
(
rt5645
->
btn_jack
&&
rt5645
->
codec_type
==
CODEC_TYPE_RT5650
)
{
rt5645
->
en_button_func
=
true
;
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_GPIO_CTRL1
,
RT5645_GP1_PIN_IRQ
,
RT5645_GP1_PIN_IRQ
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_DEPOP_M1
,
RT5645_HP_CB_MASK
,
RT5645_HP_CB_PU
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_GEN_CTRL1
,
RT5645_DIG_GATE_CTRL
,
RT5645_DIG_GATE_CTRL
);
}
rt5645_irq
(
0
,
rt5645
);
return
0
;
}
...
...
@@ -2485,7 +2906,7 @@ static void rt5645_jack_detect_work(struct work_struct *work)
struct
rt5645_priv
*
rt5645
=
container_of
(
work
,
struct
rt5645_priv
,
jack_detect_work
.
work
);
rt5645_
jack_detect
(
rt5645
->
codec
);
rt5645_
irq_detection
(
rt5645
);
}
static
irqreturn_t
rt5645_irq
(
int
irq
,
void
*
data
)
...
...
@@ -2498,6 +2919,126 @@ static irqreturn_t rt5645_irq(int irq, void *data)
return
IRQ_HANDLED
;
}
static
int
rt5645_button_detect
(
struct
snd_soc_codec
*
codec
)
{
int
btn_type
,
val
;
val
=
snd_soc_read
(
codec
,
RT5650_4BTN_IL_CMD1
);
pr_debug
(
"val=0x%x
\n
"
,
val
);
btn_type
=
val
&
0xfff0
;
snd_soc_write
(
codec
,
RT5650_4BTN_IL_CMD1
,
val
);
return
btn_type
;
}
static
int
rt5645_irq_detection
(
struct
rt5645_priv
*
rt5645
)
{
int
val
,
btn_type
,
gpio_state
=
0
,
report
=
0
;
switch
(
rt5645
->
pdata
.
jd_mode
)
{
case
0
:
/* Not using rt5645 JD */
if
(
gpio_is_valid
(
rt5645
->
pdata
.
hp_det_gpio
))
{
gpio_state
=
gpio_get_value
(
rt5645
->
pdata
.
hp_det_gpio
);
dev_dbg
(
rt5645
->
codec
->
dev
,
"gpio = %d(%d)
\n
"
,
rt5645
->
pdata
.
hp_det_gpio
,
gpio_state
);
}
if
((
rt5645
->
pdata
.
gpio_hp_det_active_high
&&
gpio_state
)
||
(
!
rt5645
->
pdata
.
gpio_hp_det_active_high
&&
!
gpio_state
))
{
report
=
rt5645_jack_detect
(
rt5645
->
codec
,
1
);
}
else
{
report
=
rt5645_jack_detect
(
rt5645
->
codec
,
0
);
}
snd_soc_jack_report
(
rt5645
->
hp_jack
,
report
,
SND_JACK_HEADPHONE
);
snd_soc_jack_report
(
rt5645
->
mic_jack
,
report
,
SND_JACK_MICROPHONE
);
return
report
;
case
1
:
/* 2 port */
val
=
snd_soc_read
(
rt5645
->
codec
,
RT5645_A_JD_CTRL1
)
&
0x0070
;
break
;
default:
/* 1 port */
val
=
snd_soc_read
(
rt5645
->
codec
,
RT5645_A_JD_CTRL1
)
&
0x0020
;
break
;
}
switch
(
val
)
{
/* jack in */
case
0x30
:
/* 2 port */
case
0x0
:
/* 1 port or 2 port */
if
(
rt5645
->
jack_type
==
0
)
{
report
=
rt5645_jack_detect
(
rt5645
->
codec
,
1
);
/* for push button and jack out */
break
;
}
btn_type
=
0
;
if
(
snd_soc_read
(
rt5645
->
codec
,
RT5645_INT_IRQ_ST
)
&
0x4
)
{
/* button pressed */
report
=
SND_JACK_HEADSET
;
btn_type
=
rt5645_button_detect
(
rt5645
->
codec
);
/* rt5650 can report three kinds of button behavior,
one click, double click and hold. However,
currently we will report button pressed/released
event. So all the three button behaviors are
treated as button pressed. */
switch
(
btn_type
)
{
case
0x8000
:
case
0x4000
:
case
0x2000
:
report
|=
SND_JACK_BTN_0
;
break
;
case
0x1000
:
case
0x0800
:
case
0x0400
:
report
|=
SND_JACK_BTN_1
;
break
;
case
0x0200
:
case
0x0100
:
case
0x0080
:
report
|=
SND_JACK_BTN_2
;
break
;
case
0x0040
:
case
0x0020
:
case
0x0010
:
report
|=
SND_JACK_BTN_3
;
break
;
case
0x0000
:
/* unpressed */
break
;
default:
dev_err
(
rt5645
->
codec
->
dev
,
"Unexpected button code 0x%04x
\n
"
,
btn_type
);
break
;
}
}
if
(
btn_type
==
0
)
/* button release */
report
=
rt5645
->
jack_type
;
break
;
/* jack out */
case
0x70
:
/* 2 port */
case
0x10
:
/* 2 port */
case
0x20
:
/* 1 port */
report
=
0
;
snd_soc_update_bits
(
rt5645
->
codec
,
RT5645_INT_IRQ_ST
,
0x1
,
0x0
);
rt5645_jack_detect
(
rt5645
->
codec
,
0
);
break
;
default:
break
;
}
snd_soc_jack_report
(
rt5645
->
hp_jack
,
report
,
SND_JACK_HEADPHONE
);
snd_soc_jack_report
(
rt5645
->
mic_jack
,
report
,
SND_JACK_MICROPHONE
);
if
(
rt5645
->
en_button_func
)
snd_soc_jack_report
(
rt5645
->
btn_jack
,
report
,
SND_JACK_BTN_0
|
SND_JACK_BTN_1
|
SND_JACK_BTN_2
|
SND_JACK_BTN_3
);
return
report
;
}
static
int
rt5645_probe
(
struct
snd_soc_codec
*
codec
)
{
struct
rt5645_priv
*
rt5645
=
snd_soc_codec_get_drvdata
(
codec
);
...
...
@@ -2522,10 +3063,8 @@ static int rt5645_probe(struct snd_soc_codec *codec)
snd_soc_codec_force_bias_level
(
codec
,
SND_SOC_BIAS_OFF
);
snd_soc_update_bits
(
codec
,
RT5645_CHARGE_PUMP
,
0x0300
,
0x0200
);
/* for JD function */
if
(
rt5645
->
pdata
.
en_jd_func
)
{
if
(
rt5645
->
pdata
.
jd_mode
)
{
snd_soc_dapm_force_enable_pin
(
&
codec
->
dapm
,
"JD Power"
);
snd_soc_dapm_force_enable_pin
(
&
codec
->
dapm
,
"LDO2"
);
snd_soc_dapm_sync
(
&
codec
->
dapm
);
...
...
@@ -2665,6 +3204,32 @@ static struct acpi_device_id rt5645_acpi_match[] = {
MODULE_DEVICE_TABLE
(
acpi
,
rt5645_acpi_match
);
#endif
static
struct
rt5645_platform_data
*
rt5645_pdata
;
static
struct
rt5645_platform_data
strago_platform_data
=
{
.
dmic1_data_pin
=
RT5645_DMIC1_DISABLE
,
.
dmic2_data_pin
=
RT5645_DMIC_DATA_IN2P
,
.
jd_mode
=
3
,
};
static
int
strago_quirk_cb
(
const
struct
dmi_system_id
*
id
)
{
rt5645_pdata
=
&
strago_platform_data
;
return
1
;
}
static
struct
dmi_system_id
dmi_platform_intel_braswell
[]
=
{
{
.
ident
=
"Intel Strago"
,
.
callback
=
strago_quirk_cb
,
.
matches
=
{
DMI_MATCH
(
DMI_PRODUCT_NAME
,
"Strago"
),
},
},
{
}
};
static
int
rt5645_i2c_probe
(
struct
i2c_client
*
i2c
,
const
struct
i2c_device_id
*
id
)
{
...
...
@@ -2672,6 +3237,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
struct
rt5645_priv
*
rt5645
;
int
ret
;
unsigned
int
val
;
struct
gpio_desc
*
gpiod
;
rt5645
=
devm_kzalloc
(
&
i2c
->
dev
,
sizeof
(
struct
rt5645_priv
),
GFP_KERNEL
);
...
...
@@ -2681,8 +3247,23 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
rt5645
->
i2c
=
i2c
;
i2c_set_clientdata
(
i2c
,
rt5645
);
if
(
pdata
)
if
(
pdata
)
{
rt5645
->
pdata
=
*
pdata
;
}
else
{
if
(
dmi_check_system
(
dmi_platform_intel_braswell
))
{
rt5645
->
pdata
=
*
rt5645_pdata
;
gpiod
=
devm_gpiod_get_index
(
&
i2c
->
dev
,
"rt5645"
,
0
);
if
(
IS_ERR
(
gpiod
)
||
gpiod_direction_input
(
gpiod
))
{
rt5645
->
pdata
.
hp_det_gpio
=
-
1
;
dev_err
(
&
i2c
->
dev
,
"failed to initialize gpiod
\n
"
);
}
else
{
rt5645
->
pdata
.
hp_det_gpio
=
desc_to_gpio
(
gpiod
);
rt5645
->
pdata
.
gpio_hp_det_active_high
=
!
gpiod_is_active_low
(
gpiod
);
}
}
}
rt5645
->
regmap
=
devm_regmap_init_i2c
(
i2c
,
&
rt5645_regmap
);
if
(
IS_ERR
(
rt5645
->
regmap
))
{
...
...
@@ -2708,6 +3289,13 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
return
-
ENODEV
;
}
if
(
rt5645
->
codec_type
==
CODEC_TYPE_RT5650
)
{
ret
=
rt5650_calibration
(
rt5645
);
if
(
ret
<
0
)
pr_err
(
"calibration failed!
\n
"
);
}
regmap_write
(
rt5645
->
regmap
,
RT5645_RESET
,
0
);
ret
=
regmap_register_patch
(
rt5645
->
regmap
,
init_list
,
...
...
@@ -2727,84 +3315,76 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_IN2_CTRL
,
RT5645_IN_DF2
,
RT5645_IN_DF2
);
if
(
rt5645
->
pdata
.
dmic
_e
n
)
{
if
(
rt5645
->
pdata
.
dmic
1_data_pin
||
rt5645
->
pdata
.
dmic2_data_pi
n
)
{
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_GPIO_CTRL1
,
RT5645_GP2_PIN_MASK
,
RT5645_GP2_PIN_DMIC1_SCL
);
}
switch
(
rt5645
->
pdata
.
dmic1_data_pin
)
{
case
RT5645_DMIC_DATA_IN2N
:
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_DMIC_CTRL1
,
RT5645_DMIC_1_DP_MASK
,
RT5645_DMIC_1_DP_IN2N
);
break
;
switch
(
rt5645
->
pdata
.
dmic1_data_pin
)
{
case
RT5645_DMIC_DATA_IN2N
:
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_DMIC_CTRL1
,
RT5645_DMIC_1_DP_MASK
,
RT5645_DMIC_1_DP_IN2N
);
break
;
case
RT5645_DMIC_DATA_GPIO5
:
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_DMIC_CTRL1
,
RT5645_DMIC_1_DP_MASK
,
RT5645_DMIC_1_DP_GPIO5
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_GPIO_CTRL1
,
RT5645_GP5_PIN_MASK
,
RT5645_GP5_PIN_DMIC1_SDA
);
break
;
case
RT5645_DMIC_DATA_GPIO11
:
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_DMIC_CTRL1
,
RT5645_DMIC_1_DP_MASK
,
RT5645_DMIC_1_DP_GPIO11
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_GPIO_CTRL1
,
RT5645_GP11_PIN_MASK
,
RT5645_GP11_PIN_DMIC1_SDA
);
break
;
case
RT5645_DMIC_DATA_GPIO5
:
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_DMIC_CTRL1
,
RT5645_DMIC_1_DP_MASK
,
RT5645_DMIC_1_DP_GPIO5
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_GPIO_CTRL1
,
RT5645_GP5_PIN_MASK
,
RT5645_GP5_PIN_DMIC1_SDA
);
break
;
default:
break
;
}
case
RT5645_DMIC_DATA_GPIO11
:
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_DMIC_CTRL1
,
RT5645_DMIC_1_DP_MASK
,
RT5645_DMIC_1_DP_GPIO11
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_GPIO_CTRL1
,
RT5645_GP11_PIN_MASK
,
RT5645_GP11_PIN_DMIC1_SDA
);
break
;
switch
(
rt5645
->
pdata
.
dmic2_data_pin
)
{
case
RT5645_DMIC_DATA_IN2P
:
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_DMIC_CTRL1
,
RT5645_DMIC_2_DP_MASK
,
RT5645_DMIC_2_DP_IN2P
);
break
;
default:
break
;
}
case
RT5645_DMIC_DATA_GPIO6
:
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_DMIC_CTRL1
,
RT5645_DMIC_2_DP_MASK
,
RT5645_DMIC_2_DP_GPIO6
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_GPIO_CTRL1
,
RT5645_GP6_PIN_MASK
,
RT5645_GP6_PIN_DMIC2_SDA
);
break
;
switch
(
rt5645
->
pdata
.
dmic2_data_pin
)
{
case
RT5645_DMIC_DATA_IN2P
:
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_DMIC_CTRL1
,
RT5645_DMIC_2_DP_MASK
,
RT5645_DMIC_2_DP_IN2P
);
break
;
case
RT5645_DMIC_DATA_GPIO10
:
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_DMIC_CTRL1
,
RT5645_DMIC_2_DP_MASK
,
RT5645_DMIC_2_DP_GPIO10
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_GPIO_CTRL1
,
RT5645_GP10_PIN_MASK
,
RT5645_GP10_PIN_DMIC2_SDA
);
break
;
case
RT5645_DMIC_DATA_GPIO6
:
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_DMIC_CTRL1
,
RT5645_DMIC_2_DP_MASK
,
RT5645_DMIC_2_DP_GPIO6
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_GPIO_CTRL1
,
RT5645_GP6_PIN_MASK
,
RT5645_GP6_PIN_DMIC2_SDA
);
break
;
case
RT5645_DMIC_DATA_GPIO12
:
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_DMIC_CTRL1
,
RT5645_DMIC_2_DP_MASK
,
RT5645_DMIC_2_DP_GPIO12
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_GPIO_CTRL1
,
RT5645_GP12
_PIN_MASK
,
RT5645_GP12
_PIN_DMIC2_SDA
);
break
;
case
RT5645_DMIC_DATA_GPIO10
:
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_DMIC_CTRL1
,
RT5645_DMIC_2_DP_MASK
,
RT5645_DMIC_2_DP_GPIO10
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_GPIO_CTRL1
,
RT5645_GP10
_PIN_MASK
,
RT5645_GP10
_PIN_DMIC2_SDA
);
break
;
default:
break
;
}
case
RT5645_DMIC_DATA_GPIO12
:
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_DMIC_CTRL1
,
RT5645_DMIC_2_DP_MASK
,
RT5645_DMIC_2_DP_GPIO12
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_GPIO_CTRL1
,
RT5645_GP12_PIN_MASK
,
RT5645_GP12_PIN_DMIC2_SDA
);
break
;
default:
break
;
}
if
(
rt5645
->
pdata
.
en_jd_func
)
{
if
(
rt5645
->
pdata
.
jd_mode
)
{
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_GEN_CTRL3
,
RT5645_IRQ_CLK_GATE_CTRL
|
RT5645_MICINDET_MANU
,
RT5645_IRQ_CLK_GATE_CTRL
|
RT5645_MICINDET_MANU
);
RT5645_IRQ_CLK_GATE_CTRL
,
RT5645_IRQ_CLK_GATE_CTRL
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_IN1_CTRL1
,
RT5645_CBJ_BST1_EN
,
RT5645_CBJ_BST1_EN
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_JD_CTRL3
,
RT5645_JD_CBJ_EN
|
RT5645_JD_CBJ_POL
,
RT5645_JD_CBJ_EN
|
RT5645_JD_CBJ_POL
);
RT5645_CBJ_BST1_EN
,
RT5645_CBJ_BST1_EN
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_MICBIAS
,
RT5645_IRQ_CLK_INT
,
RT5645_IRQ_CLK_INT
);
}
if
(
rt5645
->
pdata
.
jd_mode
)
{
RT5645_IRQ_CLK_INT
,
RT5645_IRQ_CLK_INT
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_IRQ_CTRL2
,
RT5645_IRQ_JD_1_1_EN
,
RT5645_IRQ_JD_1_1_EN
);
regmap_update_bits
(
rt5645
->
regmap
,
RT5645_GEN_CTRL3
,
...
...
sound/soc/codecs/rt5645.h
View file @
f3b368d3
...
...
@@ -105,6 +105,7 @@
#define RT5645_TDM_CTRL_1 0x77
#define RT5645_TDM_CTRL_2 0x78
#define RT5645_TDM_CTRL_3 0x79
#define RT5650_TDM_CTRL_4 0x7a
/* Function - Analog */
#define RT5645_GLB_CLK 0x80
...
...
@@ -942,10 +943,6 @@
#define RT5645_I2S2_SDI_I2S2 (0x1 << 6)
/* ADC/DAC Clock Control 1 (0x73) */
#define RT5645_I2S_BCLK_MS1_MASK (0x1 << 15)
#define RT5645_I2S_BCLK_MS1_SFT 15
#define RT5645_I2S_BCLK_MS1_32 (0x0 << 15)
#define RT5645_I2S_BCLK_MS1_64 (0x1 << 15)
#define RT5645_I2S_PD1_MASK (0x7 << 12)
#define RT5645_I2S_PD1_SFT 12
#define RT5645_I2S_PD1_1 (0x0 << 12)
...
...
@@ -1067,13 +1064,14 @@
#define RT5645_SCLK_SRC_SFT 14
#define RT5645_SCLK_SRC_MCLK (0x0 << 14)
#define RT5645_SCLK_SRC_PLL1 (0x1 << 14)
#define RT5645_SCLK_SRC_RCCLK (0x2 << 14)
/* 15MHz */
#define RT5645_PLL1_SRC_MASK (0x3 << 12)
#define RT5645_PLL1_SRC_SFT 12
#define RT5645_PLL1_SRC_MCLK (0x0 << 12)
#define RT5645_PLL1_SRC_BCLK1 (0x1 << 12)
#define RT5645_PLL1_SRC_BCLK2 (0x2 << 12)
#define RT5645_PLL1_SRC_BCLK3 (0x3 << 12)
#define RT5645_SCLK_SRC_RCCLK (0x2 << 14)
#define RT5645_PLL1_SRC_MASK (0x7 << 11)
#define RT5645_PLL1_SRC_SFT 11
#define RT5645_PLL1_SRC_MCLK (0x0 << 11)
#define RT5645_PLL1_SRC_BCLK1 (0x1 << 11)
#define RT5645_PLL1_SRC_BCLK2 (0x2 << 11)
#define RT5645_PLL1_SRC_BCLK3 (0x3 << 11)
#define RT5645_PLL1_SRC_RCCLK (0x4 << 11)
#define RT5645_PLL1_PD_MASK (0x1 << 3)
#define RT5645_PLL1_PD_SFT 3
#define RT5645_PLL1_PD_1 (0x0 << 3)
...
...
@@ -2147,6 +2145,7 @@ enum {
};
enum
{
RT5645_DMIC1_DISABLE
,
RT5645_DMIC_DATA_IN2P
,
RT5645_DMIC_DATA_GPIO6
,
RT5645_DMIC_DATA_GPIO10
,
...
...
@@ -2154,6 +2153,7 @@ enum {
};
enum
{
RT5645_DMIC2_DISABLE
,
RT5645_DMIC_DATA_IN2N
,
RT5645_DMIC_DATA_GPIO5
,
RT5645_DMIC_DATA_GPIO11
,
...
...
@@ -2184,6 +2184,7 @@ struct rt5645_priv {
struct
i2c_client
*
i2c
;
struct
snd_soc_jack
*
hp_jack
;
struct
snd_soc_jack
*
mic_jack
;
struct
snd_soc_jack
*
btn_jack
;
struct
delayed_work
jack_detect_work
;
int
codec_type
;
...
...
@@ -2196,9 +2197,12 @@ struct rt5645_priv {
int
pll_src
;
int
pll_in
;
int
pll_out
;
int
jack_type
;
bool
en_button_func
;
};
int
rt5645_set_jack_detect
(
struct
snd_soc_codec
*
codec
,
struct
snd_soc_jack
*
hp_jack
,
struct
snd_soc_jack
*
mic_jack
);
struct
snd_soc_jack
*
hp_jack
,
struct
snd_soc_jack
*
mic_jack
,
struct
snd_soc_jack
*
btn_jack
);
#endif
/* __RT5645_H__ */
sound/soc/intel/boards/cht_bsw_rt5645.c
View file @
f3b368d3
...
...
@@ -185,7 +185,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
return
ret
;
}
rt5645_set_jack_detect
(
codec
,
&
ctx
->
hp_jack
,
&
ctx
->
mic_jack
);
rt5645_set_jack_detect
(
codec
,
&
ctx
->
hp_jack
,
&
ctx
->
mic_jack
,
NULL
);
return
ret
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment