From 27ee5b3f7762de1bdce74c772c5d7e75db785abc Mon Sep 17 00:00:00 2001 From: Chen Jinsen Date: Tue, 29 Oct 2019 11:00:17 +0800 Subject: [PATCH] ASoC: rockchip: add support for rk312x codec Change-Id: I1679742e7f6abb4ad9d894828ddf3781fc1bc2bb Signed-off-by: Chen Jinsen --- sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/rk312x_codec.c | 530 ++++++++++++++++---------------- 3 files changed, 273 insertions(+), 264 deletions(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 8010531c55b7..de7df7467c52 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -124,6 +124,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_PCM5102A select SND_SOC_PCM512x_I2C if I2C select SND_SOC_PCM512x_SPI if SPI_MASTER + select SND_SOC_RK312X select SND_SOC_RK3328 select SND_SOC_RK817 if I2C select SND_SOC_RT274 if I2C @@ -767,6 +768,10 @@ config SND_SOC_PCM512x_SPI select SND_SOC_PCM512x select REGMAP_SPI +config SND_SOC_RK312X + select REGMAP_MMIO + tristate "Rockchip RK312X CODEC" + config SND_SOC_RK3328 select REGMAP_MMIO tristate "Rockchip RK3328 CODEC" diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 264e5d1e1d48..bdf70a513ce4 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -126,6 +126,7 @@ snd-soc-pcm5102a-objs := pcm5102a.o snd-soc-pcm512x-objs := pcm512x.o snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o snd-soc-pcm512x-spi-objs := pcm512x-spi.o +snd-soc-rk312x-objs := rk312x_codec.o snd-soc-rk3328-objs := rk3328_codec.o snd-soc-rk817-objs := rk817_codec.o snd-soc-rl6231-objs := rl6231.o @@ -388,6 +389,7 @@ obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o +obj-$(CONFIG_SND_SOC_RK312X) += snd-soc-rk312x.o obj-$(CONFIG_SND_SOC_RK3328) += snd-soc-rk3328.o obj-$(CONFIG_SND_SOC_RK817) += snd-soc-rk817.o obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o diff --git a/sound/soc/codecs/rk312x_codec.c b/sound/soc/codecs/rk312x_codec.c index e5f459570def..085c20a73b16 100644 --- a/sound/soc/codecs/rk312x_codec.c +++ b/sound/soc/codecs/rk312x_codec.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include "rk312x_codec.h" static int debug = -1; @@ -57,8 +57,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CODEC_SET_SPK 1 #define CODEC_SET_HP 2 #define SWITCH_SPK 1 -#define BIT_HEADSET (1 << 0) -#define BIT_HEADSET_NO_MIC (1 << 1) #define GRF_ACODEC_CON 0x013c #define GRF_SOC_STATUS0 0x014c /* volume setting @@ -85,7 +83,7 @@ struct rk312x_codec_priv { struct regmap *grf; struct device *dev; unsigned int irq; - struct snd_soc_codec *codec; + struct snd_soc_component *component; unsigned int stereo_sysclk; unsigned int rate; @@ -118,12 +116,19 @@ struct rk312x_codec_priv { long int voice_call_path; struct clk *pclk; struct clk *mclk; - struct switch_dev sdev; + struct extcon_dev *edev; struct work_struct work; struct delayed_work init_delayed_work; struct delayed_work mute_delayed_work; struct delayed_work hpdet_work; }; + +static const unsigned int headset_extcon_cable[] = { + EXTCON_JACK_MICROPHONE, + EXTCON_JACK_HEADPHONE, + EXTCON_NONE, +}; + static struct rk312x_codec_priv *rk312x_priv; #define RK312x_CODEC_ALL 0 @@ -294,7 +299,7 @@ static int switch_to_spk(int enable) } #endif -static int rk312x_reset(struct snd_soc_codec *codec) +static int rk312x_reset(struct snd_soc_component *component) { DBG("%s\n", __func__); regmap_write(rk312x_priv->regmap, RK312x_RESET, 0x00); @@ -302,9 +307,6 @@ static int rk312x_reset(struct snd_soc_codec *codec) regmap_write(rk312x_priv->regmap, RK312x_RESET, 0x43); mdelay(10); - memcpy(codec->reg_cache, rk312x_reg_defaults, - sizeof(rk312x_reg_defaults)); - return 0; } @@ -634,8 +636,8 @@ int rk312x_codec_mute_dac(int mute) return -EINVAL; } if (mute) { - snd_soc_write(rk312x_priv->codec, 0xb4, 0x40); - snd_soc_write(rk312x_priv->codec, 0xb8, 0x40); + snd_soc_component_write(rk312x_priv->component, 0xb4, 0x40); + snd_soc_component_write(rk312x_priv->component, 0xb8, 0x40); } return 0; } @@ -660,7 +662,6 @@ static int rk312x_playback_path_get(struct snd_kcontrol *kcontrol, static int rk312x_playback_path_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - /* struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); */ long int pre_path; if (!rk312x_priv) { @@ -691,8 +692,10 @@ static int rk312x_playback_path_put(struct snd_kcontrol *kcontrol, case RING_SPK: if (pre_path == OFF) { rk312x_codec_power_up(RK312x_CODEC_PLAYBACK); - snd_soc_write(rk312x_priv->codec, 0xb4, rk312x_priv->spk_volume); - snd_soc_write(rk312x_priv->codec, 0xb8, rk312x_priv->spk_volume); + snd_soc_component_write(rk312x_priv->component, + 0xb4, rk312x_priv->spk_volume); + snd_soc_component_write(rk312x_priv->component, + 0xb8, rk312x_priv->spk_volume); } break; case HP_PATH: @@ -701,8 +704,10 @@ static int rk312x_playback_path_put(struct snd_kcontrol *kcontrol, case RING_HP_NO_MIC: if (pre_path == OFF) { rk312x_codec_power_up(RK312x_CODEC_PLAYBACK); - snd_soc_write(rk312x_priv->codec, 0xb4, rk312x_priv->hp_volume); - snd_soc_write(rk312x_priv->codec, 0xb8, rk312x_priv->hp_volume); + snd_soc_component_write(rk312x_priv->component, + 0xb4, rk312x_priv->hp_volume); + snd_soc_component_write(rk312x_priv->component, + 0xb8, rk312x_priv->hp_volume); } break; case BT: @@ -711,8 +716,10 @@ static int rk312x_playback_path_put(struct snd_kcontrol *kcontrol, case RING_SPK_HP: if (pre_path == OFF) { rk312x_codec_power_up(RK312x_CODEC_PLAYBACK); - snd_soc_write(rk312x_priv->codec, 0xb4, rk312x_priv->spk_volume); - snd_soc_write(rk312x_priv->codec, 0xb8, rk312x_priv->spk_volume); + snd_soc_component_write(rk312x_priv->component, + 0xb4, rk312x_priv->spk_volume); + snd_soc_component_write(rk312x_priv->component, + 0xb8, rk312x_priv->spk_volume); } break; default: @@ -741,7 +748,6 @@ static int rk312x_capture_path_get(struct snd_kcontrol *kcontrol, static int rk312x_capture_path_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - /* struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); */ long int pre_path; if (!rk312x_priv) { @@ -766,27 +772,19 @@ static int rk312x_capture_path_put(struct snd_kcontrol *kcontrol, case Main_Mic: if (pre_path == MIC_OFF) { rk312x_codec_power_up(RK312x_CODEC_CAPTURE); - /* snd_soc_write(rk312x_priv->codec, 0x94, - 0x20|rk312x_priv->capture_volume); */ - /* snd_soc_write(rk312x_priv->codec, 0x98, - rk312x_priv->capture_volume); */ - snd_soc_write(rk312x_priv->codec, 0x10c, - 0x20|rk312x_priv->capture_volume); - snd_soc_write(rk312x_priv->codec, 0x14c, - 0x20|rk312x_priv->capture_volume); + snd_soc_component_write(rk312x_priv->component, 0x10c, + 0x20 | rk312x_priv->capture_volume); + snd_soc_component_write(rk312x_priv->component, 0x14c, + 0x20 | rk312x_priv->capture_volume); } break; case Hands_Free_Mic: if (pre_path == MIC_OFF) { rk312x_codec_power_up(RK312x_CODEC_CAPTURE); - /* snd_soc_write(rk312x_priv->codec,0x94, - 0x20|rk312x_priv->capture_volume); */ - /* snd_soc_write(rk312x_priv->codec, - 0x98, rk312x_priv->capture_volume); */ - snd_soc_write(rk312x_priv->codec, - 0x10c, 0x20|rk312x_priv->capture_volume); - snd_soc_write(rk312x_priv->codec, - 0x14c, 0x20|rk312x_priv->capture_volume); + snd_soc_component_write(rk312x_priv->component, + 0x10c, 0x20 | rk312x_priv->capture_volume); + snd_soc_component_write(rk312x_priv->component, + 0x14c, 0x20 | rk312x_priv->capture_volume); } break; case BT_Sco_Mic: @@ -818,7 +816,6 @@ static int rk312x_voice_call_path_get(struct snd_kcontrol *kcontrol, static int rk312x_voice_call_path_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - /* struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); */ long int pre_path; if (!rk312x_priv) { @@ -842,8 +839,10 @@ static int rk312x_voice_call_path_put(struct snd_kcontrol *kcontrol, mdelay(100); } else { rk312x_codec_power_up(RK312x_CODEC_PLAYBACK); - snd_soc_write(rk312x_priv->codec, 0xb4, rk312x_priv->spk_volume); - snd_soc_write(rk312x_priv->codec, 0xb8, rk312x_priv->spk_volume); + snd_soc_component_write(rk312x_priv->component, + 0xb4, rk312x_priv->spk_volume); + snd_soc_component_write(rk312x_priv->component, + 0xb8, rk312x_priv->spk_volume); } } @@ -888,25 +887,24 @@ static int rk312x_dacl_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); switch (event) { case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK312x_DAC_ENABLE, - RK312x_DACL_WORK, 0); - snd_soc_update_bits(codec, RK312x_DAC_ENABLE, - RK312x_DACL_EN | RK312x_DACL_CLK_EN, - RK312x_DACL_EN | RK312x_DACL_CLK_EN); - snd_soc_update_bits(codec, RK312x_DAC_ENABLE, - RK312x_DACL_WORK, RK312x_DACL_WORK); + snd_soc_component_update_bits(component, RK312x_DAC_ENABLE, + RK312x_DACL_WORK, 0); + snd_soc_component_update_bits(component, RK312x_DAC_ENABLE, + RK312x_DACL_EN | RK312x_DACL_CLK_EN, + RK312x_DACL_EN | RK312x_DACL_CLK_EN); + snd_soc_component_update_bits(component, RK312x_DAC_ENABLE, + RK312x_DACL_WORK, RK312x_DACL_WORK); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK312x_DAC_ENABLE, - RK312x_DACL_EN - | RK312x_DACL_CLK_EN, 0); - snd_soc_update_bits(codec, RK312x_DAC_ENABLE, - RK312x_DACL_WORK, 0); + snd_soc_component_update_bits(component, RK312x_DAC_ENABLE, + RK312x_DACL_EN | RK312x_DACL_CLK_EN, 0); + snd_soc_component_update_bits(component, RK312x_DAC_ENABLE, + RK312x_DACL_WORK, 0); break; default: @@ -920,28 +918,28 @@ static int rk312x_dacr_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); switch (event) { case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK312x_DAC_ENABLE, - RK312x_DACR_WORK, 0); - snd_soc_update_bits(codec, RK312x_DAC_ENABLE, - RK312x_DACR_EN - | RK312x_DACR_CLK_EN, - RK312x_DACR_EN - | RK312x_DACR_CLK_EN); - snd_soc_update_bits(codec, RK312x_DAC_ENABLE, - RK312x_DACR_WORK, - RK312x_DACR_WORK); + snd_soc_component_update_bits(component, RK312x_DAC_ENABLE, + RK312x_DACR_WORK, 0); + snd_soc_component_update_bits(component, RK312x_DAC_ENABLE, + RK312x_DACR_EN + | RK312x_DACR_CLK_EN, + RK312x_DACR_EN + | RK312x_DACR_CLK_EN); + snd_soc_component_update_bits(component, RK312x_DAC_ENABLE, + RK312x_DACR_WORK, + RK312x_DACR_WORK); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK312x_DAC_ENABLE, - RK312x_DACR_EN - | RK312x_DACR_CLK_EN, 0); - snd_soc_update_bits(codec, RK312x_DAC_ENABLE, - RK312x_DACR_WORK, 0); + snd_soc_component_update_bits(component, RK312x_DAC_ENABLE, + RK312x_DACR_EN + | RK312x_DACR_CLK_EN, 0); + snd_soc_component_update_bits(component, RK312x_DAC_ENABLE, + RK312x_DACR_WORK, 0); break; default: @@ -954,21 +952,21 @@ static int rk312x_dacr_event(struct snd_soc_dapm_widget *w, static int rk312x_adcl_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); switch (event) { case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK312x_ADC_ENABLE, - RK312x_ADCL_CLK_EN_SFT - | RK312x_ADCL_AMP_EN_SFT, - RK312x_ADCL_CLK_EN - | RK312x_ADCL_AMP_EN); + snd_soc_component_update_bits(component, RK312x_ADC_ENABLE, + RK312x_ADCL_CLK_EN_SFT + | RK312x_ADCL_AMP_EN_SFT, + RK312x_ADCL_CLK_EN + | RK312x_ADCL_AMP_EN); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK312x_ADC_ENABLE, - RK312x_ADCL_CLK_EN_SFT - | RK312x_ADCL_AMP_EN_SFT, 0); + snd_soc_component_update_bits(component, RK312x_ADC_ENABLE, + RK312x_ADCL_CLK_EN_SFT + | RK312x_ADCL_AMP_EN_SFT, 0); break; default: @@ -981,21 +979,21 @@ static int rk312x_adcl_event(struct snd_soc_dapm_widget *w, static int rk312x_adcr_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); switch (event) { case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK312x_ADC_ENABLE, - RK312x_ADCR_CLK_EN_SFT - | RK312x_ADCR_AMP_EN_SFT, - RK312x_ADCR_CLK_EN - | RK312x_ADCR_AMP_EN); + snd_soc_component_update_bits(component, RK312x_ADC_ENABLE, + RK312x_ADCR_CLK_EN_SFT + | RK312x_ADCR_AMP_EN_SFT, + RK312x_ADCR_CLK_EN + | RK312x_ADCR_AMP_EN); break; case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK312x_ADC_ENABLE, - RK312x_ADCR_CLK_EN_SFT - | RK312x_ADCR_AMP_EN_SFT, 0); + snd_soc_component_update_bits(component, RK312x_ADC_ENABLE, + RK312x_ADCR_CLK_EN_SFT + | RK312x_ADCR_AMP_EN_SFT, 0); break; default: @@ -1027,25 +1025,25 @@ static const struct snd_kcontrol_new rk312x_hpmixr[] = { static int rk312x_hpmixl_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); switch (event) { case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK312x_DAC_CTL, - RK312x_ZO_DET_VOUTR_SFT, - RK312x_ZO_DET_VOUTR_EN); - snd_soc_update_bits(codec, RK312x_DAC_CTL, - RK312x_ZO_DET_VOUTL_SFT, - RK312x_ZO_DET_VOUTL_EN); + snd_soc_component_update_bits(component, RK312x_DAC_CTL, + RK312x_ZO_DET_VOUTR_SFT, + RK312x_ZO_DET_VOUTR_EN); + snd_soc_component_update_bits(component, RK312x_DAC_CTL, + RK312x_ZO_DET_VOUTL_SFT, + RK312x_ZO_DET_VOUTL_EN); break; case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, RK312x_DAC_CTL, - RK312x_ZO_DET_VOUTR_SFT, - RK312x_ZO_DET_VOUTR_DIS); - snd_soc_update_bits(codec, RK312x_DAC_CTL, - RK312x_ZO_DET_VOUTL_SFT, - RK312x_ZO_DET_VOUTL_DIS); + snd_soc_component_update_bits(component, RK312x_DAC_CTL, + RK312x_ZO_DET_VOUTR_SFT, + RK312x_ZO_DET_VOUTR_DIS); + snd_soc_component_update_bits(component, RK312x_DAC_CTL, + RK312x_ZO_DET_VOUTL_SFT, + RK312x_ZO_DET_VOUTL_DIS); break; default: @@ -1058,17 +1056,16 @@ static int rk312x_hpmixl_event(struct snd_soc_dapm_widget *w, static int rk312x_hpmixr_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - /* struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); */ #if 0 switch (event) { case SND_SOC_DAPM_POST_PMU: - snd_soc_update_bits(codec, RK312x_HPMIX_CTL, - RK312x_HPMIXR_WORK2, RK312x_HPMIXR_WORK2); + snd_soc_component_update_bits(component, RK312x_HPMIX_CTL, + RK312x_HPMIXR_WORK2, RK312x_HPMIXR_WORK2); break; case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, RK312x_HPMIX_CTL, - RK312x_HPMIXR_WORK2, 0); + snd_soc_component_update_bits(component, RK312x_HPMIX_CTL, + RK312x_HPMIXR_WORK2, 0); break; default: @@ -1249,7 +1246,7 @@ static const struct snd_soc_dapm_route rk312x_dapm_routes[] = { {"HPOUTL", NULL, "HPL"}, }; -static int rk312x_set_bias_level(struct snd_soc_codec *codec, +static int rk312x_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { DBG("%s level=%d\n", __func__, level); @@ -1262,58 +1259,58 @@ static int rk312x_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { + if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { regmap_write(rk312x_priv->regmap, RK312x_DAC_INT_CTL3, 0x32); - snd_soc_update_bits(codec, RK312x_ADC_MIC_CTL, - RK312x_ADC_CURRENT_ENABLE, - RK312x_ADC_CURRENT_ENABLE); - snd_soc_update_bits(codec, RK312x_DAC_CTL, - RK312x_CURRENT_EN, - RK312x_CURRENT_EN); + snd_soc_component_update_bits(component, RK312x_ADC_MIC_CTL, + RK312x_ADC_CURRENT_ENABLE, + RK312x_ADC_CURRENT_ENABLE); + snd_soc_component_update_bits(component, RK312x_DAC_CTL, + RK312x_CURRENT_EN, + RK312x_CURRENT_EN); /* set power */ - snd_soc_update_bits(codec, RK312x_ADC_ENABLE, - RK312x_ADCL_REF_VOL_EN_SFT - | RK312x_ADCR_REF_VOL_EN_SFT, - RK312x_ADCL_REF_VOL_EN - | RK312x_ADCR_REF_VOL_EN); + snd_soc_component_update_bits(component, RK312x_ADC_ENABLE, + RK312x_ADCL_REF_VOL_EN_SFT + | RK312x_ADCR_REF_VOL_EN_SFT, + RK312x_ADCL_REF_VOL_EN + | RK312x_ADCR_REF_VOL_EN); - snd_soc_update_bits(codec, RK312x_ADC_MIC_CTL, - RK312x_ADCL_ZERO_DET_EN_SFT - | RK312x_ADCR_ZERO_DET_EN_SFT, - RK312x_ADCL_ZERO_DET_EN - | RK312x_ADCR_ZERO_DET_EN); + snd_soc_component_update_bits(component, RK312x_ADC_MIC_CTL, + RK312x_ADCL_ZERO_DET_EN_SFT + | RK312x_ADCR_ZERO_DET_EN_SFT, + RK312x_ADCL_ZERO_DET_EN + | RK312x_ADCR_ZERO_DET_EN); - snd_soc_update_bits(codec, RK312x_DAC_CTL, - RK312x_REF_VOL_DACL_EN_SFT - | RK312x_REF_VOL_DACR_EN_SFT, - RK312x_REF_VOL_DACL_EN - | RK312x_REF_VOL_DACR_EN); + snd_soc_component_update_bits(component, RK312x_DAC_CTL, + RK312x_REF_VOL_DACL_EN_SFT + | RK312x_REF_VOL_DACR_EN_SFT, + RK312x_REF_VOL_DACL_EN + | RK312x_REF_VOL_DACR_EN); - snd_soc_update_bits(codec, RK312x_DAC_ENABLE, - RK312x_DACL_REF_VOL_EN_SFT - | RK312x_DACR_REF_VOL_EN_SFT, - RK312x_DACL_REF_VOL_EN - | RK312x_DACR_REF_VOL_EN); + snd_soc_component_update_bits(component, RK312x_DAC_ENABLE, + RK312x_DACL_REF_VOL_EN_SFT + | RK312x_DACR_REF_VOL_EN_SFT, + RK312x_DACL_REF_VOL_EN + | RK312x_DACR_REF_VOL_EN); } break; case SND_SOC_BIAS_OFF: - snd_soc_update_bits(codec, RK312x_DAC_ENABLE, - RK312x_DACL_REF_VOL_EN_SFT - | RK312x_DACR_REF_VOL_EN_SFT, 0); - snd_soc_update_bits(codec, RK312x_DAC_CTL, - RK312x_REF_VOL_DACL_EN_SFT - | RK312x_REF_VOL_DACR_EN_SFT, 0); - snd_soc_update_bits(codec, RK312x_ADC_MIC_CTL, - RK312x_ADCL_ZERO_DET_EN_SFT - | RK312x_ADCR_ZERO_DET_EN_SFT, 0); - snd_soc_update_bits(codec, RK312x_ADC_ENABLE, - RK312x_ADCL_REF_VOL_EN_SFT - | RK312x_ADCR_REF_VOL_EN_SFT, 0); - snd_soc_update_bits(codec, RK312x_ADC_MIC_CTL, - RK312x_ADC_CURRENT_ENABLE, 0); - snd_soc_update_bits(codec, RK312x_DAC_CTL, - RK312x_CURRENT_EN, 0); + snd_soc_component_update_bits(component, RK312x_DAC_ENABLE, + RK312x_DACL_REF_VOL_EN_SFT + | RK312x_DACR_REF_VOL_EN_SFT, 0); + snd_soc_component_update_bits(component, RK312x_DAC_CTL, + RK312x_REF_VOL_DACL_EN_SFT + | RK312x_REF_VOL_DACR_EN_SFT, 0); + snd_soc_component_update_bits(component, RK312x_ADC_MIC_CTL, + RK312x_ADCL_ZERO_DET_EN_SFT + | RK312x_ADCR_ZERO_DET_EN_SFT, 0); + snd_soc_component_update_bits(component, RK312x_ADC_ENABLE, + RK312x_ADCL_REF_VOL_EN_SFT + | RK312x_ADCR_REF_VOL_EN_SFT, 0); + snd_soc_component_update_bits(component, RK312x_ADC_MIC_CTL, + RK312x_ADC_CURRENT_ENABLE, 0); + snd_soc_component_update_bits(component, RK312x_DAC_CTL, + RK312x_CURRENT_EN, 0); regmap_write(rk312x_priv->regmap, RK312x_DAC_INT_CTL3, 0x22); break; } @@ -1339,7 +1336,7 @@ static int rk312x_set_dai_sysclk(struct snd_soc_dai *codec_dai, static int rk312x_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { - struct snd_soc_codec *codec = codec_dai->codec; + struct snd_soc_component *component = codec_dai->component; unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { @@ -1408,17 +1405,17 @@ static int rk312x_set_dai_fmt(struct snd_soc_dai *codec_dai, return -EINVAL; } - snd_soc_update_bits(codec, RK312x_ADC_INT_CTL1, - RK312x_ALRCK_POL_MASK - | RK312x_ADC_DF_MASK, adc_aif1); - snd_soc_update_bits(codec, RK312x_ADC_INT_CTL2, - RK312x_ABCLK_POL_MASK - | RK312x_I2S_MODE_MASK, adc_aif2); - snd_soc_update_bits(codec, RK312x_DAC_INT_CTL1, - RK312x_DLRCK_POL_MASK - | RK312x_DAC_DF_MASK, dac_aif1); - snd_soc_update_bits(codec, RK312x_DAC_INT_CTL2, - RK312x_DBCLK_POL_MASK, dac_aif2); + snd_soc_component_update_bits(component, RK312x_ADC_INT_CTL1, + RK312x_ALRCK_POL_MASK + | RK312x_ADC_DF_MASK, adc_aif1); + snd_soc_component_update_bits(component, RK312x_ADC_INT_CTL2, + RK312x_ABCLK_POL_MASK + | RK312x_I2S_MODE_MASK, adc_aif2); + snd_soc_component_update_bits(component, RK312x_DAC_INT_CTL1, + RK312x_DLRCK_POL_MASK + | RK312x_DAC_DF_MASK, dac_aif1); + snd_soc_component_update_bits(component, RK312x_DAC_INT_CTL2, + RK312x_DBCLK_POL_MASK, dac_aif2); return 0; } @@ -1428,7 +1425,7 @@ static int rk312x_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_component *component = rtd->codec_dai->component; struct rk312x_codec_priv *rk312x = rk312x_priv; unsigned int rate = params_rate(params); unsigned int div; @@ -1515,19 +1512,19 @@ static int rk312x_hw_params(struct snd_pcm_substream *substream, rk312x->rate = rate; - snd_soc_update_bits(codec, RK312x_ADC_INT_CTL1, - RK312x_ADC_VWL_MASK - | RK312x_ADC_SWAP_MASK - | RK312x_ADC_TYPE_MASK, adc_aif1); - snd_soc_update_bits(codec, RK312x_ADC_INT_CTL2, - RK312x_ADC_WL_MASK - | RK312x_ADC_RST_MASK, adc_aif2); - snd_soc_update_bits(codec, RK312x_DAC_INT_CTL1, - RK312x_DAC_VWL_MASK - | RK312x_DAC_SWAP_MASK, dac_aif1); - snd_soc_update_bits(codec, RK312x_DAC_INT_CTL2, - RK312x_DAC_WL_MASK - | RK312x_DAC_RST_MASK, dac_aif2); + snd_soc_component_update_bits(component, RK312x_ADC_INT_CTL1, + RK312x_ADC_VWL_MASK + | RK312x_ADC_SWAP_MASK + | RK312x_ADC_TYPE_MASK, adc_aif1); + snd_soc_component_update_bits(component, RK312x_ADC_INT_CTL2, + RK312x_ADC_WL_MASK + | RK312x_ADC_RST_MASK, adc_aif2); + snd_soc_component_update_bits(component, RK312x_DAC_INT_CTL1, + RK312x_DAC_VWL_MASK + | RK312x_DAC_SWAP_MASK, dac_aif1); + snd_soc_component_update_bits(component, RK312x_DAC_INT_CTL2, + RK312x_DAC_WL_MASK + | RK312x_DAC_RST_MASK, dac_aif2); return 0; } @@ -1678,15 +1675,15 @@ static struct rk312x_reg_val_typ capture_power_down_list[] = { static int rk312x_codec_power_up(int type) { - struct snd_soc_codec *codec; + struct snd_soc_component *component; int i; - if (!rk312x_priv || !rk312x_priv->codec) { + if (!rk312x_priv || !rk312x_priv->component) { DBG("%s : rk312x_priv or rk312x_priv->codec is NULL\n", __func__); return -EINVAL; } - codec = rk312x_priv->codec; + component = rk312x_priv->component; DBG("%s : power up %s%s\n", __func__, type == RK312x_CODEC_PLAYBACK ? "playback" : "", @@ -1694,8 +1691,9 @@ static int rk312x_codec_power_up(int type) if (type == RK312x_CODEC_PLAYBACK) { for (i = 0; i < RK312x_CODEC_PLAYBACK_POWER_UP_LIST_LEN; i++) { - snd_soc_write(codec, playback_power_up_list[i].reg, - playback_power_up_list[i].value); + snd_soc_component_write(component, + playback_power_up_list[i].reg, + playback_power_up_list[i].value); usleep_range(1000, 1100); } } else if (type == RK312x_CODEC_CAPTURE) { @@ -1703,23 +1701,23 @@ static int rk312x_codec_power_up(int type) for (i = 0; i < RK312x_CODEC_CAPTURE_POWER_UP_LIST_LEN; i++) { - snd_soc_write(codec, - capture_power_up_list[i].reg, - capture_power_up_list[i].value); + snd_soc_component_write(component, + capture_power_up_list[i].reg, + capture_power_up_list[i].value); } } else { for (i = 0; i < RK312x_CODEC_CAPTURE_POWER_UP_LIST_LEN - 4; i++) { - snd_soc_write(codec, - capture_power_up_list[i].reg, - capture_power_up_list[i].value); + snd_soc_component_write(component, + capture_power_up_list[i].reg, + capture_power_up_list[i].value); } } } else if (type == RK312x_CODEC_INCALL) { - snd_soc_update_bits(codec, RK312x_ALC_MUNIN_CTL, - RK312x_MUXINL_F_MSK | RK312x_MUXINR_F_MSK, - RK312x_MUXINR_F_INR | RK312x_MUXINL_F_INL); + snd_soc_component_update_bits(component, RK312x_ALC_MUNIN_CTL, + RK312x_MUXINL_F_MSK | RK312x_MUXINR_F_MSK, + RK312x_MUXINR_F_INR | RK312x_MUXINL_F_INL); } return 0; @@ -1727,15 +1725,15 @@ static int rk312x_codec_power_up(int type) static int rk312x_codec_power_down(int type) { - struct snd_soc_codec *codec; + struct snd_soc_component *component; int i; - if (!rk312x_priv || !rk312x_priv->codec) { - DBG("%s : rk312x_priv or rk312x_priv->codec is NULL\n", + if (!rk312x_priv || !rk312x_priv->component) { + DBG("%s : rk312x_priv or rk312x_priv->component is NULL\n", __func__); return -EINVAL; } - codec = rk312x_priv->codec; + component = rk312x_priv->component; DBG("%s : power down %s%s%s\n", __func__, type == RK312x_CODEC_PLAYBACK ? "playback" : "", @@ -1744,19 +1742,21 @@ static int rk312x_codec_power_down(int type) if ((type == RK312x_CODEC_CAPTURE) || (type == RK312x_CODEC_INCALL)) { for (i = 0; i < RK312x_CODEC_CAPTURE_POWER_DOWN_LIST_LEN; i++) { - snd_soc_write(codec, capture_power_down_list[i].reg, - capture_power_down_list[i].value); + snd_soc_component_write(component, + capture_power_down_list[i].reg, + capture_power_down_list[i].value); } } else if (type == RK312x_CODEC_PLAYBACK) { for (i = 0; i < RK312x_CODEC_PLAYBACK_POWER_DOWN_LIST_LEN; i++) { - snd_soc_write(codec, playback_power_down_list[i].reg, - playback_power_down_list[i].value); + snd_soc_component_write(component, + playback_power_down_list[i].reg, + playback_power_down_list[i].value); } } else if (type == RK312x_CODEC_ALL) { - rk312x_reset(codec); + rk312x_reset(component); } return 0; @@ -1773,14 +1773,10 @@ static void rk312x_codec_capture_work(struct work_struct *work) break; case RK312x_CODEC_WORK_POWER_UP: rk312x_codec_power_up(RK312x_CODEC_CAPTURE); - /* snd_soc_write(rk312x_priv->codec, - 0x94, 0x20|rk312x_priv->capture_volume); */ - /* snd_soc_write(rk312x_priv->codec, - 0x98, rk312x_priv->capture_volume); */ - snd_soc_write(rk312x_priv->codec, - 0x10c, 0x20|rk312x_priv->capture_volume); - snd_soc_write(rk312x_priv->codec, - 0x14c, 0x20|rk312x_priv->capture_volume); + snd_soc_component_write(rk312x_priv->component, + 0x10c, 0x20 | rk312x_priv->capture_volume); + snd_soc_component_write(rk312x_priv->component, + 0x14c, 0x20 | rk312x_priv->capture_volume); break; default: break; @@ -1816,8 +1812,10 @@ static int rk312x_startup(struct snd_pcm_substream *substream, if (rk312x->playback_active > 0) if (!is_codec_playback_running) { rk312x_codec_power_up(RK312x_CODEC_PLAYBACK); - snd_soc_write(rk312x_priv->codec, 0xb4, rk312x_priv->spk_volume); - snd_soc_write(rk312x_priv->codec, 0xb8, rk312x_priv->spk_volume); + snd_soc_component_write(rk312x_priv->component, + 0xb4, rk312x_priv->spk_volume); + snd_soc_component_write(rk312x_priv->component, + 0xb8, rk312x_priv->spk_volume); } } else { if (rk312x->capture_active > 0 && !is_codec_capture_running) { @@ -1971,7 +1969,7 @@ static struct snd_soc_dai_driver rk312x_dai[] = { }; -static int rk312x_suspend(struct snd_soc_codec *codec) +static int rk312x_suspend(struct snd_soc_component *component) { unsigned int val=0; DBG("%s\n", __func__); @@ -1991,10 +1989,10 @@ static int rk312x_suspend(struct snd_soc_codec *codec) rk312x_codec_power_down(RK312x_CODEC_PLAYBACK); rk312x_codec_power_down(RK312x_CODEC_ALL); - snd_soc_write(codec, RK312x_SELECT_CURRENT, 0x1e); - snd_soc_write(codec, RK312x_SELECT_CURRENT, 0x3e); + snd_soc_component_write(component, RK312x_SELECT_CURRENT, 0x1e); + snd_soc_component_write(component, RK312x_SELECT_CURRENT, 0x3e); } else { - snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF); + snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); } return 0; } @@ -2012,7 +2010,7 @@ static ssize_t gpio_store(struct kobject *kobj, struct kobj_attribute *attr, char cmd; int ret; struct rk312x_codec_priv *rk312x = - snd_soc_codec_get_drvdata(rk312x_priv->codec); + snd_soc_component_get_drvdata(rk312x_priv->component); ret = sscanf(buftmp, "%c ", &cmd); if (ret == 0) @@ -2062,14 +2060,15 @@ static struct gpio_attribute gpio_attrs[] = { __ATTR(spk-ctl, S_IRUGO | S_IWUSR, gpio_show, gpio_store), }; -static int rk312x_resume(struct snd_soc_codec *codec) +static int rk312x_resume(struct snd_soc_component *component) { - unsigned int val=0; - if(rk312x_priv->codec_hp_det) - { + unsigned int val = 0; + + if (rk312x_priv->codec_hp_det) { /* enable hp det interrupt */ - snd_soc_write(codec, RK312x_DAC_CTL, 0x08); - printk("0xa0 -- 0x%x\n",snd_soc_read(codec, RK312x_DAC_CTL)); + snd_soc_component_write(component, RK312x_DAC_CTL, 0x08); + snd_soc_component_read(component, RK312x_DAC_CTL, &val); + printk("0xa0 -- 0x%x\n", val); regmap_read(rk312x_priv->grf, GRF_ACODEC_CON, &val); regmap_write(rk312x_priv->grf, GRF_ACODEC_CON, 0x1f001f); regmap_read(rk312x_priv->grf, GRF_ACODEC_CON, &val); @@ -2077,7 +2076,8 @@ static int rk312x_resume(struct snd_soc_codec *codec) schedule_delayed_work(&rk312x_priv->hpdet_work, msecs_to_jiffies(20)); } if (!rk312x_priv->rk312x_for_mid) - snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY); + snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); + return 0; } @@ -2106,42 +2106,41 @@ static void hpdet_work_func(struct work_struct *work) if (val & 0x80000000) { DBG("%s hp det high\n", __func__); DBG("%s no headset\n", __func__); - switch_set_state(&rk312x_priv->sdev, 0); + extcon_set_state_sync(rk312x_priv->edev, + EXTCON_JACK_HEADPHONE, false); } else { DBG("%s hp det low\n", __func__); DBG("%s headset inserted\n", __func__); - switch_set_state(&rk312x_priv->sdev, BIT_HEADSET_NO_MIC); + extcon_set_state_sync(rk312x_priv->edev, + EXTCON_JACK_HEADPHONE, true); } return; } -static ssize_t h2w_print_name(struct switch_dev *sdev, char *buf) -{ - return sprintf(buf, "Headset\n"); -} + static void rk312x_delay_workq(struct work_struct *work) { int ret; unsigned int val; struct rk312x_codec_priv *rk312x_codec; - struct snd_soc_codec *codec; + struct snd_soc_component *component; printk("%s\n", __func__); - if (!rk312x_priv || !rk312x_priv->codec) { - DBG("%s : rk312x_priv or rk312x_priv->codec is NULL\n", + if (!rk312x_priv || !rk312x_priv->component) { + DBG("%s : rk312x_priv or rk312x_priv->component is NULL\n", __func__); return; } - rk312x_codec = snd_soc_codec_get_drvdata(rk312x_priv->codec); - codec = rk312x_codec->codec; - rk312x_reset(codec); + rk312x_codec = snd_soc_component_get_drvdata(rk312x_priv->component); + component = rk312x_codec->component; + rk312x_reset(component); if (!rk312x_priv->rk312x_for_mid) { - snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF); - snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY); + snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); + snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); } #ifdef WITH_CAP - snd_soc_write(codec, RK312x_SELECT_CURRENT, 0x1e); - snd_soc_write(codec, RK312x_SELECT_CURRENT, 0x3e); + snd_soc_component_write(component, RK312x_SELECT_CURRENT, 0x1e); + snd_soc_component_write(component, RK312x_SELECT_CURRENT, 0x3e); #endif if (rk312x_codec->codec_hp_det) { @@ -2150,34 +2149,31 @@ static void rk312x_delay_workq(struct work_struct *work) IRQF_TRIGGER_RISING, "codec_hp_det", NULL); if (ret < 0) DBG(" codec_hp_det request_irq failed %d\n", ret); - rk312x_codec->sdev.name = "h2w"; - rk312x_codec->sdev.print_name = h2w_print_name; - ret = switch_dev_register(&rk312x_codec->sdev); - if (ret) - DBG(KERN_ERR"register switch dev failed\n"); + regmap_read(rk312x_priv->grf, GRF_ACODEC_CON, &val); regmap_write(rk312x_priv->grf, GRF_ACODEC_CON, 0x1f001f); regmap_read(rk312x_priv->grf, GRF_ACODEC_CON, &val); DBG("GRF_ACODEC_CON 3334is 0x%x\n", val); /* enable rk 3128 codec_hp_det */ - snd_soc_write(codec, RK312x_DAC_CTL, 0x08); - DBG("0xa0 -- 0x%x\n", snd_soc_read(codec, RK312x_DAC_CTL)); + snd_soc_component_write(component, RK312x_DAC_CTL, 0x08); + snd_soc_component_read(component, RK312x_DAC_CTL, &val); + DBG("0xa0 -- 0x%x\n", val); /* codec hp det once */ schedule_delayed_work(&rk312x_priv->hpdet_work, msecs_to_jiffies(100)); } } -static int rk312x_probe(struct snd_soc_codec *codec) +static int rk312x_probe(struct snd_soc_component *component) { struct rk312x_codec_priv *rk312x_codec = - snd_soc_codec_get_drvdata(codec); + snd_soc_component_get_drvdata(component); unsigned int val; int ret; int i = 0; - rk312x_codec->codec = codec; - snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF); + rk312x_codec->component = component; + snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); clk_prepare_enable(rk312x_codec->pclk); rk312x_codec->playback_active = 0; @@ -2191,7 +2187,8 @@ static int rk312x_probe(struct snd_soc_codec *codec) goto err__; } - val = snd_soc_read(codec, RK312x_RESET); + snd_soc_component_read(component, RK312x_RESET, &val); + if (val != rk312x_reg_defaults[RK312x_RESET]) { DBG("%s : codec register 0: %x is not a 0x00000003\n", __func__, val); @@ -2199,8 +2196,8 @@ static int rk312x_probe(struct snd_soc_codec *codec) goto err__; } - snd_soc_add_codec_controls(codec, rk312x_snd_path_controls, - ARRAY_SIZE(rk312x_snd_path_controls)); + snd_soc_add_component_controls(component, rk312x_snd_path_controls, + ARRAY_SIZE(rk312x_snd_path_controls)); INIT_DELAYED_WORK(&rk312x_priv->init_delayed_work, rk312x_delay_workq); INIT_DELAYED_WORK(&rk312x_priv->mute_delayed_work, rk312x_codec_unpop); INIT_DELAYED_WORK(&rk312x_priv->hpdet_work, hpdet_work_func); @@ -2227,13 +2224,13 @@ err__: } /* power down chip */ -static int rk312x_remove(struct snd_soc_codec *codec) +static void rk312x_remove(struct snd_soc_component *component) { DBG("%s\n", __func__); if (!rk312x_priv) { DBG("%s : rk312x_priv is NULL\n", __func__); - return 0; + return; } if (rk312x_priv->spk_ctl_gpio) @@ -2250,25 +2247,19 @@ static int rk312x_remove(struct snd_soc_codec *codec) if (rk312x_codec_work_capture_type != RK312x_CODEC_WORK_NULL) rk312x_codec_work_capture_type = RK312x_CODEC_WORK_NULL; } - snd_soc_write(codec, RK312x_RESET, 0xfc); + snd_soc_component_write(component, RK312x_RESET, 0xfc); mdelay(10); - snd_soc_write(codec, RK312x_RESET, 0x3); + snd_soc_component_write(component, RK312x_RESET, 0x3); mdelay(10); - - return 0; } -static struct snd_soc_codec_driver soc_codec_dev_rk312x = { +static struct snd_soc_component_driver soc_codec_dev_rk312x = { .probe = rk312x_probe, .remove = rk312x_remove, .suspend = rk312x_suspend, .resume = rk312x_resume, .set_bias_level = rk312x_set_bias_level, - .reg_cache_size = ARRAY_SIZE(rk312x_reg_defaults), - .reg_word_size = sizeof(unsigned int), - .reg_cache_default = rk312x_reg_defaults, - .reg_cache_step = sizeof(unsigned int), }; static const struct regmap_config rk312x_codec_regmap_config = { @@ -2324,6 +2315,18 @@ static int rk312x_platform_probe(struct platform_device *pdev) } } #endif + rk312x->edev = devm_extcon_dev_allocate(&pdev->dev, headset_extcon_cable); + if (IS_ERR(rk312x->edev)) { + dev_err(&pdev->dev, "failed to allocate extcon device\n"); + return -ENOMEM; + } + + ret = devm_extcon_dev_register(&pdev->dev, rk312x->edev); + if (ret < 0) { + dev_err(&pdev->dev, "failed to register extcon device\n"); + return ret; + } + rk312x->hp_ctl_gpio = devm_gpiod_get_optional(&pdev->dev, "hp-ctl", GPIOD_OUT_LOW); if (!IS_ERR_OR_NULL(rk312x->hp_ctl_gpio)) { @@ -2441,8 +2444,8 @@ static int rk312x_platform_probe(struct platform_device *pdev) clk_prepare_enable(rk312x->mclk); clk_set_rate(rk312x->mclk, 11289600); - return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_rk312x, - rk312x_dai, ARRAY_SIZE(rk312x_dai)); + return devm_snd_soc_register_component(&pdev->dev, &soc_codec_dev_rk312x, + rk312x_dai, ARRAY_SIZE(rk312x_dai)); err__: platform_set_drvdata(pdev, NULL); @@ -2454,7 +2457,6 @@ static int rk312x_platform_remove(struct platform_device *pdev) { DBG("%s\n", __func__); rk312x_priv = NULL; - snd_soc_unregister_codec(&pdev->dev); return 0; } @@ -2462,8 +2464,8 @@ void rk312x_platform_shutdown(struct platform_device *pdev) { unsigned int val = 0; DBG("%s\n", __func__); - if (!rk312x_priv || !rk312x_priv->codec) { - DBG("%s : rk312x_priv or rk312x_priv->codec is NULL\n", + if (!rk312x_priv || !rk312x_priv->component) { + DBG("%s : rk312x_priv or rk312x_priv->component is NULL\n", __func__); return; }