From a2d0f258d89ccc8dbbb0de58277da62fe8671961 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 14 Oct 2015 11:26:46 +0100 Subject: sound: codec: Add support to msm8x16_wcd codec. On msm8x16 SOCs the codec integration is split into digital and analog parts, digitial part is integrated with SOC and the analog part is integrated as part of pmic chip pm8916. This driver provides basic playback support with lot of todos: 1> Capture support 2> Cleanup 3> Multi button head set support. 4> Impedenace matching logic. Signed-off-by: Srinivas Kandagatla --- sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 3 +- sound/soc/codecs/msm8x16-wcd-tables.c | 742 ++++++++++++++ sound/soc/codecs/msm8x16-wcd.c | 1636 ++++++++++++++++++++++++++++++ sound/soc/codecs/msm8x16-wcd.h | 234 +++++ sound/soc/codecs/msm8x16_wcd_registers.h | 518 ++++++++++ 6 files changed, 3136 insertions(+), 1 deletion(-) create mode 100644 sound/soc/codecs/msm8x16-wcd-tables.c create mode 100644 sound/soc/codecs/msm8x16-wcd.c create mode 100644 sound/soc/codecs/msm8x16-wcd.h create mode 100644 sound/soc/codecs/msm8x16_wcd_registers.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 0c9733ecd17f..ba8be1954732 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -486,6 +486,10 @@ config SND_SOC_MAX98925 config SND_SOC_MAX9850 tristate +config SND_SOC_MSM8x16_WCD + tristate "Qualcomm MSM8x16 WCD" + depends on SPMI && MFD_SYSCON + config SND_SOC_PCM1681 tristate "Texas Instruments PCM1681 CODEC" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 4a32077954ae..2c6c0e8aa178 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -72,6 +72,7 @@ snd-soc-max98925-objs := max98925.o snd-soc-max9850-objs := max9850.o snd-soc-mc13783-objs := mc13783.o snd-soc-ml26124-objs := ml26124.o +snd-soc-msm8x16-objs := msm8x16-wcd.o msm8x16-wcd-tables.o snd-soc-hdmi-codec-objs := hdmi.o snd-soc-pcm1681-objs := pcm1681.o snd-soc-pcm1792a-codec-objs := pcm1792a.o @@ -182,7 +183,6 @@ snd-soc-wm9705-objs := wm9705.o snd-soc-wm9712-objs := wm9712.o snd-soc-wm9713-objs := wm9713.o snd-soc-wm-hubs-objs := wm_hubs.o - # Amp snd-soc-max9877-objs := max9877.o snd-soc-tpa6130a2-objs := tpa6130a2.o @@ -264,6 +264,7 @@ obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o +obj-$(CONFIG_SND_SOC_MSM8x16_WCD) +=snd-soc-msm8x16.o obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o diff --git a/sound/soc/codecs/msm8x16-wcd-tables.c b/sound/soc/codecs/msm8x16-wcd-tables.c new file mode 100644 index 000000000000..9030ca4e4812 --- /dev/null +++ b/sound/soc/codecs/msm8x16-wcd-tables.c @@ -0,0 +1,742 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "msm8x16-wcd.h" + +const u8 msm8x16_wcd_reg_readable[MSM8X16_WCD_CACHE_SIZE] = { + [MSM8X16_WCD_A_DIGITAL_REVISION1] = 1, + [MSM8X16_WCD_A_DIGITAL_REVISION2] = 1, + [MSM8X16_WCD_A_DIGITAL_PERPH_TYPE] = 1, + [MSM8X16_WCD_A_DIGITAL_PERPH_SUBTYPE] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_RT_STS] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_SET_TYPE] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_POLARITY_HIGH] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_POLARITY_LOW] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_EN_SET] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_EN_CLR] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_LATCHED_STS] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_PENDING_STS] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_MID_SEL] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_PRIORITY] = 1, + [MSM8X16_WCD_A_DIGITAL_GPIO_MODE] = 1, + [MSM8X16_WCD_A_DIGITAL_PIN_CTL_OE] = 1, + [MSM8X16_WCD_A_DIGITAL_PIN_CTL_DATA] = 1, + [MSM8X16_WCD_A_DIGITAL_PIN_STATUS] = 1, + [MSM8X16_WCD_A_DIGITAL_HDRIVE_CTL] = 1, + [MSM8X16_WCD_A_DIGITAL_CDC_RST_CTL] = 1, + [MSM8X16_WCD_A_DIGITAL_CDC_TOP_CLK_CTL] = 1, + [MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL] = 1, + [MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL] = 1, + [MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX1_CTL] = 1, + [MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX2_CTL] = 1, + [MSM8X16_WCD_A_DIGITAL_CDC_CONN_HPHR_DAC_CTL] = 1, + [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX1_CTL] = 1, + [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX2_CTL] = 1, + [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX3_CTL] = 1, + [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX_LB_CTL] = 1, + [MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL1] = 1, + [MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL2] = 1, + [MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL3] = 1, + [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA0] = 1, + [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA1] = 1, + [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA2] = 1, + [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA3] = 1, + [MSM8X16_WCD_A_DIGITAL_DIG_DEBUG_CTL] = 1, + [MSM8X16_WCD_A_DIGITAL_SPARE_0] = 1, + [MSM8X16_WCD_A_DIGITAL_SPARE_1] = 1, + [MSM8X16_WCD_A_DIGITAL_SPARE_2] = 1, + [MSM8X16_WCD_A_ANALOG_REVISION1] = 1, + [MSM8X16_WCD_A_ANALOG_REVISION2] = 1, + [MSM8X16_WCD_A_ANALOG_REVISION3] = 1, + [MSM8X16_WCD_A_ANALOG_REVISION4] = 1, + [MSM8X16_WCD_A_ANALOG_PERPH_TYPE] = 1, + [MSM8X16_WCD_A_ANALOG_PERPH_SUBTYPE] = 1, + [MSM8X16_WCD_A_ANALOG_INT_RT_STS] = 1, + [MSM8X16_WCD_A_ANALOG_INT_SET_TYPE] = 1, + [MSM8X16_WCD_A_ANALOG_INT_POLARITY_HIGH] = 1, + [MSM8X16_WCD_A_ANALOG_INT_POLARITY_LOW] = 1, + [MSM8X16_WCD_A_ANALOG_INT_EN_SET] = 1, + [MSM8X16_WCD_A_ANALOG_INT_EN_CLR] = 1, + [MSM8X16_WCD_A_ANALOG_INT_LATCHED_STS] = 1, + [MSM8X16_WCD_A_ANALOG_INT_PENDING_STS] = 1, + [MSM8X16_WCD_A_ANALOG_INT_MID_SEL] = 1, + [MSM8X16_WCD_A_ANALOG_INT_PRIORITY] = 1, + [MSM8X16_WCD_A_ANALOG_MICB_1_EN] = 1, + [MSM8X16_WCD_A_ANALOG_MICB_1_VAL] = 1, + [MSM8X16_WCD_A_ANALOG_MICB_1_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_MICB_1_INT_RBIAS] = 1, + [MSM8X16_WCD_A_ANALOG_MICB_2_EN] = 1, + [MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_1] = 1, + [MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2] = 1, + [MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_MBHC_DBNC_TIMER] = 1, + [MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_MBHC_BTN1_ZDETM_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_MBHC_BTN3_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_MBHC_BTN4_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_MBHC_BTN_RESULT] = 1, + [MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT] = 1, + [MSM8X16_WCD_A_ANALOG_TX_1_EN] = 1, + [MSM8X16_WCD_A_ANALOG_TX_2_EN] = 1, + [MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_1] = 1, + [MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_2] = 1, + [MSM8X16_WCD_A_ANALOG_TX_1_2_ATEST_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_TX_1_2_OPAMP_BIAS] = 1, + [MSM8X16_WCD_A_ANALOG_TX_1_2_TXFE_CLKDIV] = 1, + [MSM8X16_WCD_A_ANALOG_TX_3_EN] = 1, + [MSM8X16_WCD_A_ANALOG_NCP_EN] = 1, + [MSM8X16_WCD_A_ANALOG_NCP_CLK] = 1, + [MSM8X16_WCD_A_ANALOG_NCP_DEGLITCH] = 1, + [MSM8X16_WCD_A_ANALOG_NCP_FBCTRL] = 1, + [MSM8X16_WCD_A_ANALOG_NCP_BIAS] = 1, + [MSM8X16_WCD_A_ANALOG_NCP_VCTRL] = 1, + [MSM8X16_WCD_A_ANALOG_NCP_TEST] = 1, + [MSM8X16_WCD_A_ANALOG_RX_CLOCK_DIVIDER] = 1, + [MSM8X16_WCD_A_ANALOG_RX_COM_OCP_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_RX_COM_OCP_COUNT] = 1, + [MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC] = 1, + [MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_PA] = 1, + [MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_LDO_OCP] = 1, + [MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_CNP] = 1, + [MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_EN] = 1, + [MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_TIME] = 1, + [MSM8X16_WCD_A_ANALOG_RX_HPH_L_TEST] = 1, + [MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_RX_HPH_R_TEST] = 1, + [MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_RX_EAR_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_RX_ATEST] = 1, + [MSM8X16_WCD_A_ANALOG_RX_HPH_STATUS] = 1, + [MSM8X16_WCD_A_ANALOG_RX_EAR_STATUS] = 1, + [MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_SPKR_DRV_CLIP_DET] = 1, + [MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_SPKR_ANA_BIAS_SET] = 1, + [MSM8X16_WCD_A_ANALOG_SPKR_OCP_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_SPKR_DRV_MISC] = 1, + [MSM8X16_WCD_A_ANALOG_SPKR_DRV_DBG] = 1, + [MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT] = 1, + [MSM8X16_WCD_A_ANALOG_OUTPUT_VOLTAGE] = 1, + [MSM8X16_WCD_A_ANALOG_BYPASS_MODE] = 1, + [MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_SLOPE_COMP_IP_ZERO] = 1, + [MSM8X16_WCD_A_ANALOG_RDSON_MAX_DUTY_CYCLE] = 1, + [MSM8X16_WCD_A_ANALOG_BOOST_TEST1_1] = 1, + [MSM8X16_WCD_A_ANALOG_BOOST_TEST_2] = 1, + [MSM8X16_WCD_A_ANALOG_SPKR_SAR_STATUS] = 1, + [MSM8X16_WCD_A_ANALOG_SPKR_DRV_STATUS] = 1, + [MSM8X16_WCD_A_ANALOG_PBUS_ADD_CSR] = 1, + [MSM8X16_WCD_A_ANALOG_PBUS_ADD_SEL] = 1, + [MSM8X16_WCD_A_CDC_CLK_RX_RESET_CTL] = 1, + [MSM8X16_WCD_A_CDC_CLK_TX_RESET_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_CLK_DMIC_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL] = 1, + [MSM8X16_WCD_A_CDC_CLK_TX_I2S_CTL] = 1, + [MSM8X16_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_CLK_OTHR_CTL] = 1, + [MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_CLK_MCLK_CTL] = 1, + [MSM8X16_WCD_A_CDC_CLK_PDM_CTL] = 1, + [MSM8X16_WCD_A_CDC_CLK_SD_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX1_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX2_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX3_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX1_B2_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX2_B2_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX3_B2_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX1_B3_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX2_B3_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX3_B3_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX1_B4_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX2_B4_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX3_B4_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX1_B5_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX2_B5_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX3_B5_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX1_B6_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX2_B6_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX3_B6_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B2_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B2_CTL] = 1, + [MSM8X16_WCD_A_CDC_TOP_GAIN_UPDATE] = 1, + [MSM8X16_WCD_A_CDC_TOP_CTL] = 1, + [MSM8X16_WCD_A_CDC_DEBUG_DESER1_CTL] = 1, + [MSM8X16_WCD_A_CDC_DEBUG_DESER2_CTL] = 1, + [MSM8X16_WCD_A_CDC_DEBUG_B1_CTL_CFG] = 1, + [MSM8X16_WCD_A_CDC_DEBUG_B2_CTL_CFG] = 1, + [MSM8X16_WCD_A_CDC_DEBUG_B3_CTL_CFG] = 1, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B2_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B2_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B3_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B3_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B4_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B4_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B5_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B5_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B6_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B6_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B7_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B7_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B8_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B8_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR1_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR2_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_TIMER_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_TIMER_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR2_COEF_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR2_COEF_B2_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_RX1_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_RX1_B2_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_RX1_B3_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_RX2_B2_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_RX2_B3_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_RX3_B2_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_TX_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_EQ1_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_EQ1_B2_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_EQ1_B3_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_EQ1_B4_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_EQ2_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_EQ2_B2_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_EQ2_B3_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_EQ2_B4_CTL] = 1, + [MSM8X16_WCD_A_CDC_CONN_TX_I2S_SD1_CTL] = 1, + [MSM8X16_WCD_A_CDC_TX1_VOL_CTL_TIMER] = 1, + [MSM8X16_WCD_A_CDC_TX2_VOL_CTL_TIMER] = 1, + [MSM8X16_WCD_A_CDC_TX1_VOL_CTL_GAIN] = 1, + [MSM8X16_WCD_A_CDC_TX2_VOL_CTL_GAIN] = 1, + [MSM8X16_WCD_A_CDC_TX1_VOL_CTL_CFG] = 1, + [MSM8X16_WCD_A_CDC_TX2_VOL_CTL_CFG] = 1, + [MSM8X16_WCD_A_CDC_TX1_MUX_CTL] = 1, + [MSM8X16_WCD_A_CDC_TX2_MUX_CTL] = 1, + [MSM8X16_WCD_A_CDC_TX1_CLK_FS_CTL] = 1, + [MSM8X16_WCD_A_CDC_TX2_CLK_FS_CTL] = 1, + [MSM8X16_WCD_A_CDC_TX1_DMIC_CTL] = 1, + [MSM8X16_WCD_A_CDC_TX2_DMIC_CTL] = 1, + [MSM8X16_WCD_A_ANALOG_MASTER_BIAS_CTL] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_LATCHED_CLR] = 1, + [MSM8X16_WCD_A_ANALOG_INT_LATCHED_CLR] = 1, + [MSM8X16_WCD_A_ANALOG_NCP_CLIM_ADDR] = 1, + [MSM8X16_WCD_A_DIGITAL_SEC_ACCESS] = 1, + [MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL3] = 1, + [MSM8X16_WCD_A_ANALOG_SEC_ACCESS] = 1, +}; + +const u8 msm8x16_wcd_reg_readonly[MSM8X16_WCD_CACHE_SIZE] = { + [MSM8X16_WCD_A_DIGITAL_REVISION1] = 1, + [MSM8X16_WCD_A_DIGITAL_REVISION2] = 1, + [MSM8X16_WCD_A_DIGITAL_PERPH_TYPE] = 1, + [MSM8X16_WCD_A_DIGITAL_PERPH_SUBTYPE] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_RT_STS] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_SET_TYPE] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_POLARITY_HIGH] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_POLARITY_LOW] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_LATCHED_STS] = 1, + [MSM8X16_WCD_A_DIGITAL_INT_PENDING_STS] = 1, + [MSM8X16_WCD_A_DIGITAL_PIN_STATUS] = 1, + [MSM8X16_WCD_A_ANALOG_REVISION1] = 1, + [MSM8X16_WCD_A_ANALOG_REVISION2] = 1, + [MSM8X16_WCD_A_ANALOG_REVISION3] = 1, + [MSM8X16_WCD_A_ANALOG_REVISION4] = 1, + [MSM8X16_WCD_A_ANALOG_PERPH_TYPE] = 1, + [MSM8X16_WCD_A_ANALOG_PERPH_SUBTYPE] = 1, + [MSM8X16_WCD_A_ANALOG_INT_RT_STS] = 1, + [MSM8X16_WCD_A_ANALOG_INT_SET_TYPE] = 1, + [MSM8X16_WCD_A_ANALOG_INT_POLARITY_HIGH] = 1, + [MSM8X16_WCD_A_ANALOG_INT_POLARITY_LOW] = 1, + [MSM8X16_WCD_A_ANALOG_INT_LATCHED_STS] = 1, + [MSM8X16_WCD_A_ANALOG_INT_PENDING_STS] = 1, + [MSM8X16_WCD_A_ANALOG_MBHC_BTN_RESULT] = 1, + [MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT] = 1, + [MSM8X16_WCD_A_ANALOG_RX_HPH_STATUS] = 1, + [MSM8X16_WCD_A_ANALOG_RX_EAR_STATUS] = 1, + [MSM8X16_WCD_A_ANALOG_SPKR_SAR_STATUS] = 1, + [MSM8X16_WCD_A_ANALOG_SPKR_DRV_STATUS] = 1, + [MSM8X16_WCD_A_CDC_RX1_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX2_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX3_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX1_B6_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX2_B6_CTL] = 1, + [MSM8X16_WCD_A_CDC_RX3_B6_CTL] = 1, + [MSM8X16_WCD_A_CDC_TX1_VOL_CTL_CFG] = 1, + [MSM8X16_WCD_A_CDC_TX2_VOL_CTL_CFG] = 1, + [MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_IIR2_COEF_B1_CTL] = 1, + [MSM8X16_WCD_A_CDC_CLK_MCLK_CTL] = 1, + [MSM8X16_WCD_A_CDC_CLK_PDM_CTL] = 1, +}; + +u8 msm8x16_wcd_reset_reg_defaults[MSM8X16_WCD_CACHE_SIZE] = { + [MSM8X16_WCD_A_DIGITAL_REVISION1] = + MSM8X16_WCD_A_DIGITAL_REVISION1__POR, + [MSM8X16_WCD_A_DIGITAL_REVISION2] = + MSM8X16_WCD_A_DIGITAL_REVISION2__POR, + [MSM8X16_WCD_A_DIGITAL_PERPH_TYPE] = + MSM8X16_WCD_A_DIGITAL_PERPH_TYPE__POR, + [MSM8X16_WCD_A_DIGITAL_PERPH_SUBTYPE] = + MSM8X16_WCD_A_DIGITAL_PERPH_SUBTYPE__POR, + [MSM8X16_WCD_A_DIGITAL_INT_RT_STS] = + MSM8X16_WCD_A_DIGITAL_INT_RT_STS__POR, + [MSM8X16_WCD_A_DIGITAL_INT_SET_TYPE] = + MSM8X16_WCD_A_DIGITAL_INT_SET_TYPE__POR, + [MSM8X16_WCD_A_DIGITAL_INT_POLARITY_HIGH] = + MSM8X16_WCD_A_DIGITAL_INT_POLARITY_HIGH__POR, + [MSM8X16_WCD_A_DIGITAL_INT_POLARITY_LOW] = + MSM8X16_WCD_A_DIGITAL_INT_POLARITY_LOW__POR, + [MSM8X16_WCD_A_DIGITAL_INT_LATCHED_CLR] = + MSM8X16_WCD_A_DIGITAL_INT_LATCHED_CLR__POR, + [MSM8X16_WCD_A_DIGITAL_INT_EN_SET] = + MSM8X16_WCD_A_DIGITAL_INT_EN_SET__POR, + [MSM8X16_WCD_A_DIGITAL_INT_EN_CLR] = + MSM8X16_WCD_A_DIGITAL_INT_EN_CLR__POR, + [MSM8X16_WCD_A_DIGITAL_INT_LATCHED_STS] = + MSM8X16_WCD_A_DIGITAL_INT_LATCHED_STS__POR, + [MSM8X16_WCD_A_DIGITAL_INT_PENDING_STS] = + MSM8X16_WCD_A_DIGITAL_INT_PENDING_STS__POR, + [MSM8X16_WCD_A_DIGITAL_INT_MID_SEL] = + MSM8X16_WCD_A_DIGITAL_INT_MID_SEL__POR, + [MSM8X16_WCD_A_DIGITAL_INT_PRIORITY] = + MSM8X16_WCD_A_DIGITAL_INT_PRIORITY__POR, + [MSM8X16_WCD_A_DIGITAL_GPIO_MODE] = + MSM8X16_WCD_A_DIGITAL_GPIO_MODE__POR, + [MSM8X16_WCD_A_DIGITAL_PIN_CTL_OE] = + MSM8X16_WCD_A_DIGITAL_PIN_CTL_OE__POR, + [MSM8X16_WCD_A_DIGITAL_PIN_CTL_DATA] = + MSM8X16_WCD_A_DIGITAL_PIN_CTL_DATA__POR, + [MSM8X16_WCD_A_DIGITAL_PIN_STATUS] = + MSM8X16_WCD_A_DIGITAL_PIN_STATUS__POR, + [MSM8X16_WCD_A_DIGITAL_HDRIVE_CTL] = + MSM8X16_WCD_A_DIGITAL_HDRIVE_CTL__POR, + [MSM8X16_WCD_A_DIGITAL_CDC_RST_CTL] = + MSM8X16_WCD_A_DIGITAL_CDC_RST_CTL__POR, + [MSM8X16_WCD_A_DIGITAL_CDC_TOP_CLK_CTL] = + MSM8X16_WCD_A_DIGITAL_CDC_TOP_CLK_CTL__POR, + [MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL] = + MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL__POR, + [MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL] = + MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL__POR, + [MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX1_CTL] = + MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX1_CTL__POR, + [MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX2_CTL] = + MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX2_CTL__POR, + [MSM8X16_WCD_A_DIGITAL_CDC_CONN_HPHR_DAC_CTL] = + MSM8X16_WCD_A_DIGITAL_CDC_CONN_HPHR_DAC_CTL__POR, + [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX1_CTL] = + MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX1_CTL__POR, + [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX2_CTL] = + MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX2_CTL__POR, + [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX3_CTL] = + MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX3_CTL__POR, + [MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX_LB_CTL] = + MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX_LB_CTL__POR, + [MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL1] = + MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL1__POR, + [MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL2] = + MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL2__POR, + [MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL3] = + MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL3__POR, + [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA0] = + MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA0__POR, + [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA1] = + MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA1__POR, + [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA2] = + MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA2__POR, + [MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA3] = + MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA3__POR, + [MSM8X16_WCD_A_DIGITAL_SPARE_0] = + MSM8X16_WCD_A_DIGITAL_SPARE_0__POR, + [MSM8X16_WCD_A_DIGITAL_SPARE_1] = + MSM8X16_WCD_A_DIGITAL_SPARE_1__POR, + [MSM8X16_WCD_A_DIGITAL_SPARE_2] = + MSM8X16_WCD_A_DIGITAL_SPARE_2__POR, + [MSM8X16_WCD_A_ANALOG_REVISION1] = + MSM8X16_WCD_A_ANALOG_REVISION1__POR, + [MSM8X16_WCD_A_ANALOG_REVISION2] = + MSM8X16_WCD_A_ANALOG_REVISION2__POR, + [MSM8X16_WCD_A_ANALOG_REVISION3] = + MSM8X16_WCD_A_ANALOG_REVISION3__POR, + [MSM8X16_WCD_A_ANALOG_REVISION4] = + MSM8X16_WCD_A_ANALOG_REVISION4__POR, + [MSM8X16_WCD_A_ANALOG_PERPH_TYPE] = + MSM8X16_WCD_A_ANALOG_PERPH_TYPE__POR, + [MSM8X16_WCD_A_ANALOG_PERPH_SUBTYPE] = + MSM8X16_WCD_A_ANALOG_PERPH_SUBTYPE__POR, + [MSM8X16_WCD_A_ANALOG_INT_RT_STS] = + MSM8X16_WCD_A_ANALOG_INT_RT_STS__POR, + [MSM8X16_WCD_A_ANALOG_INT_SET_TYPE] = + MSM8X16_WCD_A_ANALOG_INT_SET_TYPE__POR, + [MSM8X16_WCD_A_ANALOG_INT_POLARITY_HIGH] = + MSM8X16_WCD_A_ANALOG_INT_POLARITY_HIGH__POR, + [MSM8X16_WCD_A_ANALOG_INT_POLARITY_LOW] = + MSM8X16_WCD_A_ANALOG_INT_POLARITY_LOW__POR, + [MSM8X16_WCD_A_ANALOG_INT_LATCHED_CLR] = + MSM8X16_WCD_A_ANALOG_INT_LATCHED_CLR__POR, + [MSM8X16_WCD_A_ANALOG_INT_EN_SET] = + MSM8X16_WCD_A_ANALOG_INT_EN_SET__POR, + [MSM8X16_WCD_A_ANALOG_INT_EN_CLR] = + MSM8X16_WCD_A_ANALOG_INT_EN_CLR__POR, + [MSM8X16_WCD_A_ANALOG_INT_LATCHED_STS] = + MSM8X16_WCD_A_ANALOG_INT_LATCHED_STS__POR, + [MSM8X16_WCD_A_ANALOG_INT_PENDING_STS] = + MSM8X16_WCD_A_ANALOG_INT_PENDING_STS__POR, + [MSM8X16_WCD_A_ANALOG_INT_MID_SEL] = + MSM8X16_WCD_A_ANALOG_INT_MID_SEL__POR, + [MSM8X16_WCD_A_ANALOG_INT_PRIORITY] = + MSM8X16_WCD_A_ANALOG_INT_PRIORITY__POR, + [MSM8X16_WCD_A_ANALOG_MICB_1_EN] = + MSM8X16_WCD_A_ANALOG_MICB_1_EN__POR, + [MSM8X16_WCD_A_ANALOG_MICB_1_VAL] = + MSM8X16_WCD_A_ANALOG_MICB_1_VAL__POR, + [MSM8X16_WCD_A_ANALOG_MICB_1_CTL] = + MSM8X16_WCD_A_ANALOG_MICB_1_CTL__POR, + [MSM8X16_WCD_A_ANALOG_MICB_1_INT_RBIAS] = + MSM8X16_WCD_A_ANALOG_MICB_1_INT_RBIAS__POR, + [MSM8X16_WCD_A_ANALOG_MICB_2_EN] = + MSM8X16_WCD_A_ANALOG_MICB_2_EN__POR, + [MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_1] = + MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_1__POR, + [MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2] = + MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2__POR, + [MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL] = + MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL__POR, + [MSM8X16_WCD_A_ANALOG_MBHC_DBNC_TIMER] = + MSM8X16_WCD_A_ANALOG_MBHC_DBNC_TIMER__POR, + [MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL] = + MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL__POR, + [MSM8X16_WCD_A_ANALOG_MBHC_BTN1_ZDETM_CTL] = + MSM8X16_WCD_A_ANALOG_MBHC_BTN1_ZDETM_CTL__POR, + [MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL] = + MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL__POR, + [MSM8X16_WCD_A_ANALOG_MBHC_BTN3_CTL] = + MSM8X16_WCD_A_ANALOG_MBHC_BTN3_CTL__POR, + [MSM8X16_WCD_A_ANALOG_MBHC_BTN4_CTL] = + MSM8X16_WCD_A_ANALOG_MBHC_BTN4_CTL__POR, + [MSM8X16_WCD_A_ANALOG_MBHC_BTN_RESULT] = + MSM8X16_WCD_A_ANALOG_MBHC_BTN_RESULT__POR, + [MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT] = + MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT__POR, + [MSM8X16_WCD_A_ANALOG_TX_1_EN] = + MSM8X16_WCD_A_ANALOG_TX_1_EN__POR, + [MSM8X16_WCD_A_ANALOG_TX_2_EN] = + MSM8X16_WCD_A_ANALOG_TX_2_EN__POR, + [MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_1] = + MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_1__POR, + [MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_2] = + MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_2__POR, + [MSM8X16_WCD_A_ANALOG_TX_1_2_ATEST_CTL] = + MSM8X16_WCD_A_ANALOG_TX_1_2_ATEST_CTL__POR, + [MSM8X16_WCD_A_ANALOG_TX_1_2_OPAMP_BIAS] = + MSM8X16_WCD_A_ANALOG_TX_1_2_OPAMP_BIAS__POR, + [MSM8X16_WCD_A_ANALOG_TX_1_2_TXFE_CLKDIV] = + MSM8X16_WCD_A_ANALOG_TX_1_2_TXFE_CLKDIV__POR, + [MSM8X16_WCD_A_ANALOG_TX_3_EN] = + MSM8X16_WCD_A_ANALOG_TX_3_EN__POR, + [MSM8X16_WCD_A_ANALOG_NCP_EN] = + MSM8X16_WCD_A_ANALOG_NCP_EN__POR, + [MSM8X16_WCD_A_ANALOG_NCP_CLK] = + MSM8X16_WCD_A_ANALOG_NCP_CLK__POR, + [MSM8X16_WCD_A_ANALOG_NCP_DEGLITCH] = + MSM8X16_WCD_A_ANALOG_NCP_DEGLITCH__POR, + [MSM8X16_WCD_A_ANALOG_NCP_FBCTRL] = + MSM8X16_WCD_A_ANALOG_NCP_FBCTRL__POR, + [MSM8X16_WCD_A_ANALOG_NCP_BIAS] = + MSM8X16_WCD_A_ANALOG_NCP_BIAS__POR, + [MSM8X16_WCD_A_ANALOG_NCP_VCTRL] = + MSM8X16_WCD_A_ANALOG_NCP_VCTRL__POR, + [MSM8X16_WCD_A_ANALOG_NCP_TEST] = + MSM8X16_WCD_A_ANALOG_NCP_TEST__POR, + [MSM8X16_WCD_A_ANALOG_RX_CLOCK_DIVIDER] = + MSM8X16_WCD_A_ANALOG_RX_CLOCK_DIVIDER__POR, + [MSM8X16_WCD_A_ANALOG_RX_COM_OCP_CTL] = + MSM8X16_WCD_A_ANALOG_RX_COM_OCP_CTL__POR, + [MSM8X16_WCD_A_ANALOG_RX_COM_OCP_COUNT] = + MSM8X16_WCD_A_ANALOG_RX_COM_OCP_COUNT__POR, + [MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC] = + MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC__POR, + [MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_PA] = + MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_PA__POR, + [MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_LDO_OCP] = + MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_LDO_OCP__POR, + [MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_CNP] = + MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_CNP__POR, + [MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_EN] = + MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_EN__POR, + [MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_CTL] = + MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_CTL__POR, + [MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_TIME] = + MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_TIME__POR, + [MSM8X16_WCD_A_ANALOG_RX_HPH_L_TEST] = + MSM8X16_WCD_A_ANALOG_RX_HPH_L_TEST__POR, + [MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL] = + MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL__POR, + [MSM8X16_WCD_A_ANALOG_RX_HPH_R_TEST] = + MSM8X16_WCD_A_ANALOG_RX_HPH_R_TEST__POR, + [MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL] = + MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL__POR, + [MSM8X16_WCD_A_ANALOG_RX_EAR_CTL] = + MSM8X16_WCD_A_ANALOG_RX_EAR_CTL___POR, + [MSM8X16_WCD_A_ANALOG_RX_ATEST] = + MSM8X16_WCD_A_ANALOG_RX_ATEST__POR, + [MSM8X16_WCD_A_ANALOG_RX_HPH_STATUS] = + MSM8X16_WCD_A_ANALOG_RX_HPH_STATUS__POR, + [MSM8X16_WCD_A_ANALOG_RX_EAR_STATUS] = + MSM8X16_WCD_A_ANALOG_RX_EAR_STATUS__POR, + [MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL] = + MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL__POR, + [MSM8X16_WCD_A_ANALOG_SPKR_DRV_CLIP_DET] = + MSM8X16_WCD_A_ANALOG_SPKR_DRV_CLIP_DET__POR, + [MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL] = + MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL__POR, + [MSM8X16_WCD_A_ANALOG_SPKR_ANA_BIAS_SET] = + MSM8X16_WCD_A_ANALOG_SPKR_ANA_BIAS_SET__POR, + [MSM8X16_WCD_A_ANALOG_SPKR_OCP_CTL] = + MSM8X16_WCD_A_ANALOG_SPKR_OCP_CTL__POR, + [MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL] = + MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL__POR, + [MSM8X16_WCD_A_ANALOG_SPKR_DRV_MISC] = + MSM8X16_WCD_A_ANALOG_SPKR_DRV_MISC__POR, + [MSM8X16_WCD_A_ANALOG_SPKR_DRV_DBG] = + MSM8X16_WCD_A_ANALOG_SPKR_DRV_DBG__POR, + [MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT] = + MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT__POR, + [MSM8X16_WCD_A_ANALOG_OUTPUT_VOLTAGE] = + MSM8X16_WCD_A_ANALOG_OUTPUT_VOLTAGE__POR, + [MSM8X16_WCD_A_ANALOG_BYPASS_MODE] = + MSM8X16_WCD_A_ANALOG_BYPASS_MODE__POR, + [MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL] = + MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL__POR, + [MSM8X16_WCD_A_ANALOG_SLOPE_COMP_IP_ZERO] = + MSM8X16_WCD_A_ANALOG_SLOPE_COMP_IP_ZERO__POR, + [MSM8X16_WCD_A_ANALOG_RDSON_MAX_DUTY_CYCLE] = + MSM8X16_WCD_A_ANALOG_RDSON_MAX_DUTY_CYCLE__POR, + [MSM8X16_WCD_A_ANALOG_BOOST_TEST1_1] = + MSM8X16_WCD_A_ANALOG_BOOST_TEST1_1__POR, + [MSM8X16_WCD_A_ANALOG_BOOST_TEST_2] = + MSM8X16_WCD_A_ANALOG_BOOST_TEST_2__POR, + [MSM8X16_WCD_A_ANALOG_SPKR_SAR_STATUS] = + MSM8X16_WCD_A_ANALOG_SPKR_SAR_STATUS__POR, + [MSM8X16_WCD_A_ANALOG_SPKR_DRV_STATUS] = + MSM8X16_WCD_A_ANALOG_SPKR_DRV_STATUS__POR, + [MSM8X16_WCD_A_ANALOG_PBUS_ADD_CSR] = + MSM8X16_WCD_A_ANALOG_PBUS_ADD_CSR__POR, + [MSM8X16_WCD_A_ANALOG_PBUS_ADD_SEL] = + MSM8X16_WCD_A_ANALOG_PBUS_ADD_SEL__POR, + [MSM8X16_WCD_A_CDC_CLK_RX_RESET_CTL] = + MSM8X16_WCD_A_CDC_CLK_RX_RESET_CTL__POR, + [MSM8X16_WCD_A_CDC_CLK_TX_RESET_B1_CTL] = + MSM8X16_WCD_A_CDC_CLK_TX_RESET_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_CLK_DMIC_B1_CTL] = + MSM8X16_WCD_A_CDC_CLK_DMIC_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL] = + MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL__POR, + [MSM8X16_WCD_A_CDC_CLK_TX_I2S_CTL] = + MSM8X16_WCD_A_CDC_CLK_TX_I2S_CTL__POR, + [MSM8X16_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL] = + MSM8X16_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL] = + MSM8X16_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_CLK_OTHR_CTL] = + MSM8X16_WCD_A_CDC_CLK_OTHR_CTL__POR, + [MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL] = + MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_CLK_MCLK_CTL] = + MSM8X16_WCD_A_CDC_CLK_MCLK_CTL__POR, + [MSM8X16_WCD_A_CDC_CLK_PDM_CTL] = + MSM8X16_WCD_A_CDC_CLK_PDM_CTL__POR, + [MSM8X16_WCD_A_CDC_CLK_SD_CTL] = + MSM8X16_WCD_A_CDC_CLK_SD_CTL__POR, + [MSM8X16_WCD_A_CDC_RX1_B1_CTL] = + MSM8X16_WCD_A_CDC_RX1_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_RX2_B1_CTL] = + MSM8X16_WCD_A_CDC_RX2_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_RX3_B1_CTL] = + MSM8X16_WCD_A_CDC_RX3_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_RX1_B2_CTL] = + MSM8X16_WCD_A_CDC_RX1_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_RX2_B2_CTL] = + MSM8X16_WCD_A_CDC_RX2_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_RX3_B2_CTL] = + MSM8X16_WCD_A_CDC_RX3_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_RX1_B3_CTL] = + MSM8X16_WCD_A_CDC_RX1_B3_CTL__POR, + [MSM8X16_WCD_A_CDC_RX2_B3_CTL] = + MSM8X16_WCD_A_CDC_RX2_B3_CTL__POR, + [MSM8X16_WCD_A_CDC_RX3_B3_CTL] = + MSM8X16_WCD_A_CDC_RX3_B3_CTL__POR, + [MSM8X16_WCD_A_CDC_RX1_B4_CTL] = + MSM8X16_WCD_A_CDC_RX1_B4_CTL__POR, + [MSM8X16_WCD_A_CDC_RX2_B4_CTL] = + MSM8X16_WCD_A_CDC_RX2_B4_CTL__POR, + [MSM8X16_WCD_A_CDC_RX3_B4_CTL] = + MSM8X16_WCD_A_CDC_RX3_B4_CTL__POR, + [MSM8X16_WCD_A_CDC_RX1_B5_CTL] = + MSM8X16_WCD_A_CDC_RX1_B5_CTL__POR, + [MSM8X16_WCD_A_CDC_RX2_B5_CTL] = + MSM8X16_WCD_A_CDC_RX2_B5_CTL__POR, + [MSM8X16_WCD_A_CDC_RX3_B5_CTL] = + MSM8X16_WCD_A_CDC_RX3_B5_CTL__POR, + [MSM8X16_WCD_A_CDC_RX1_B6_CTL] = + MSM8X16_WCD_A_CDC_RX1_B6_CTL__POR, + [MSM8X16_WCD_A_CDC_RX2_B6_CTL] = + MSM8X16_WCD_A_CDC_RX2_B6_CTL__POR, + [MSM8X16_WCD_A_CDC_RX3_B6_CTL] = + MSM8X16_WCD_A_CDC_RX3_B6_CTL__POR, + [MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B1_CTL] = + MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B1_CTL] = + MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B1_CTL] = + MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL] = + MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B2_CTL] = + MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B2_CTL] = + MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_TOP_GAIN_UPDATE] = + MSM8X16_WCD_A_CDC_TOP_GAIN_UPDATE__POR, + [MSM8X16_WCD_A_CDC_TOP_CTL] = + MSM8X16_WCD_A_CDC_TOP_CTL__POR, + [MSM8X16_WCD_A_CDC_DEBUG_DESER1_CTL] = + MSM8X16_WCD_A_CDC_DEBUG_DESER1_CTL__POR, + [MSM8X16_WCD_A_CDC_DEBUG_DESER2_CTL] = + MSM8X16_WCD_A_CDC_DEBUG_DESER2_CTL__POR, + [MSM8X16_WCD_A_CDC_DEBUG_B1_CTL_CFG] = + MSM8X16_WCD_A_CDC_DEBUG_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_DEBUG_B2_CTL_CFG] = + MSM8X16_WCD_A_CDC_DEBUG_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_DEBUG_B3_CTL_CFG] = + MSM8X16_WCD_A_CDC_DEBUG_B3_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B1_CTL] = + MSM8X16_WCD_A_CDC_IIR1_GAIN_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B1_CTL] = + MSM8X16_WCD_A_CDC_IIR2_GAIN_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B2_CTL] = + MSM8X16_WCD_A_CDC_IIR1_GAIN_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B2_CTL] = + MSM8X16_WCD_A_CDC_IIR2_GAIN_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B3_CTL] = + MSM8X16_WCD_A_CDC_IIR1_GAIN_B3_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B3_CTL] = + MSM8X16_WCD_A_CDC_IIR2_GAIN_B3_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B4_CTL] = + MSM8X16_WCD_A_CDC_IIR1_GAIN_B4_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B4_CTL] = + MSM8X16_WCD_A_CDC_IIR2_GAIN_B4_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B5_CTL] = + MSM8X16_WCD_A_CDC_IIR1_GAIN_B5_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B5_CTL] = + MSM8X16_WCD_A_CDC_IIR2_GAIN_B5_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B6_CTL] = + MSM8X16_WCD_A_CDC_IIR1_GAIN_B6_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B6_CTL] = + MSM8X16_WCD_A_CDC_IIR2_GAIN_B6_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B7_CTL] = + MSM8X16_WCD_A_CDC_IIR1_GAIN_B7_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B7_CTL] = + MSM8X16_WCD_A_CDC_IIR2_GAIN_B7_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_B8_CTL] = + MSM8X16_WCD_A_CDC_IIR1_GAIN_B8_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_B8_CTL] = + MSM8X16_WCD_A_CDC_IIR2_GAIN_B8_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR1_CTL] = + MSM8X16_WCD_A_CDC_IIR1_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR2_CTL] = + MSM8X16_WCD_A_CDC_IIR2_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR1_GAIN_TIMER_CTL] = + MSM8X16_WCD_A_CDC_IIR1_GAIN_TIMER_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR2_GAIN_TIMER_CTL] = + MSM8X16_WCD_A_CDC_IIR2_GAIN_TIMER_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL] = + MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR2_COEF_B1_CTL] = + MSM8X16_WCD_A_CDC_IIR2_COEF_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL] = + MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_IIR2_COEF_B2_CTL] = + MSM8X16_WCD_A_CDC_IIR2_COEF_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_RX1_B1_CTL] = + MSM8X16_WCD_A_CDC_CONN_RX1_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_RX1_B2_CTL] = + MSM8X16_WCD_A_CDC_CONN_RX1_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_RX1_B3_CTL] = + MSM8X16_WCD_A_CDC_CONN_RX1_B3_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL] = + MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_RX2_B2_CTL] = + MSM8X16_WCD_A_CDC_CONN_RX2_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_RX2_B3_CTL] = + MSM8X16_WCD_A_CDC_CONN_RX2_B3_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL] = + MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_RX3_B2_CTL] = + MSM8X16_WCD_A_CDC_CONN_RX3_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_TX_B1_CTL] = + MSM8X16_WCD_A_CDC_CONN_TX_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_EQ1_B1_CTL] = + MSM8X16_WCD_A_CDC_CONN_EQ1_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_EQ1_B2_CTL] = + MSM8X16_WCD_A_CDC_CONN_EQ1_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_EQ1_B3_CTL] = + MSM8X16_WCD_A_CDC_CONN_EQ1_B3_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_EQ1_B4_CTL] = + MSM8X16_WCD_A_CDC_CONN_EQ1_B4_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_EQ2_B1_CTL] = + MSM8X16_WCD_A_CDC_CONN_EQ2_B1_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_EQ2_B2_CTL] = + MSM8X16_WCD_A_CDC_CONN_EQ2_B2_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_EQ2_B3_CTL] = + MSM8X16_WCD_A_CDC_CONN_EQ2_B3_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_EQ2_B4_CTL] = + MSM8X16_WCD_A_CDC_CONN_EQ2_B4_CTL__POR, + [MSM8X16_WCD_A_CDC_CONN_TX_I2S_SD1_CTL] = + MSM8X16_WCD_A_CDC_CONN_TX_I2S_SD1_CTL__POR, + [MSM8X16_WCD_A_CDC_TX1_VOL_CTL_TIMER] = + MSM8X16_WCD_A_CDC_TX1_VOL_CTL_TIMER__POR, + [MSM8X16_WCD_A_CDC_TX2_VOL_CTL_TIMER] = + MSM8X16_WCD_A_CDC_TX2_VOL_CTL_TIMER__POR, + [MSM8X16_WCD_A_CDC_TX1_VOL_CTL_GAIN] = + MSM8X16_WCD_A_CDC_TX1_VOL_CTL_GAIN__POR, + [MSM8X16_WCD_A_CDC_TX2_VOL_CTL_GAIN] = + MSM8X16_WCD_A_CDC_TX2_VOL_CTL_GAIN__POR, + [MSM8X16_WCD_A_CDC_TX1_VOL_CTL_CFG] = + MSM8X16_WCD_A_CDC_TX1_VOL_CTL_CFG__POR, + [MSM8X16_WCD_A_CDC_TX2_VOL_CTL_CFG] = + MSM8X16_WCD_A_CDC_TX2_VOL_CTL_CFG__POR, + [MSM8X16_WCD_A_CDC_TX1_MUX_CTL] = + MSM8X16_WCD_A_CDC_TX1_MUX_CTL__POR, + [MSM8X16_WCD_A_CDC_TX2_MUX_CTL] = + MSM8X16_WCD_A_CDC_TX2_MUX_CTL__POR, + [MSM8X16_WCD_A_CDC_TX1_CLK_FS_CTL] = + MSM8X16_WCD_A_CDC_TX1_CLK_FS_CTL__POR, + [MSM8X16_WCD_A_CDC_TX2_CLK_FS_CTL] = + MSM8X16_WCD_A_CDC_TX2_CLK_FS_CTL__POR, + [MSM8X16_WCD_A_CDC_TX1_DMIC_CTL] = + MSM8X16_WCD_A_CDC_TX1_DMIC_CTL__POR, + [MSM8X16_WCD_A_CDC_TX2_DMIC_CTL] = + MSM8X16_WCD_A_CDC_TX2_DMIC_CTL__POR, +}; diff --git a/sound/soc/codecs/msm8x16-wcd.c b/sound/soc/codecs/msm8x16-wcd.c new file mode 100644 index 000000000000..d0df8c3e1155 --- /dev/null +++ b/sound/soc/codecs/msm8x16-wcd.c @@ -0,0 +1,1636 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "msm8x16-wcd.h" +#include "msm8x16_wcd_registers.h" + +#define MSM8X16_WCD_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000) +#define MSM8X16_WCD_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE) + + +#define TOMBAK_VERSION_1_0 0 +#define TOMBAK_IS_1_0(ver) \ + ((ver == TOMBAK_VERSION_1_0) ? 1 : 0) + +#define HPHL_PA_DISABLE (0x01 << 1) +#define HPHR_PA_DISABLE (0x01 << 2) +#define EAR_PA_DISABLE (0x01 << 3) +#define SPKR_PA_DISABLE (0x01 << 4) + +enum { + AIF1_PB = 0, + AIF1_CAP, + NUM_CODEC_DAIS, +}; + +static unsigned long rx_digital_gain_reg[] = { + MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL, + MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B2_CTL, + MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B2_CTL, +}; + +struct wcd_chip { + struct regmap *analog_map; + struct regmap *digital_map; + unsigned int analog_base; + u16 pmic_rev; + u16 codec_version; + bool spk_boost_set; + u32 mute_mask; + u32 rx_bias_count; + bool ear_pa_boost_set; + bool lb_mode; + struct clk *mclk; + + struct regulator *vddio; + struct regulator *vdd_pa; + struct regulator *vdd_px; + struct regulator *vdd_cp; +}; + + +static int msm8x16_wcd_volatile(struct snd_soc_codec *codec, unsigned int reg) +{ + return msm8x16_wcd_reg_readonly[reg]; +} + +static int msm8x16_wcd_readable(struct snd_soc_codec *ssc, unsigned int reg) +{ + return msm8x16_wcd_reg_readable[reg]; +} + +static int __msm8x16_wcd_reg_write(struct snd_soc_codec *codec, + unsigned short reg, u8 val) +{ + int ret = -EINVAL; + struct wcd_chip *chip = dev_get_drvdata(codec->dev); + + if (MSM8X16_WCD_IS_TOMBAK_REG(reg)) { + ret = regmap_write(chip->analog_map, + chip->analog_base + reg, val); + } else if (MSM8X16_WCD_IS_DIGITAL_REG(reg)) { + u32 temp = val & 0x000000FF; + u16 offset = (reg ^ 0x0200) & 0x0FFF; + + ret = regmap_write(chip->digital_map, offset, temp); + } + + return ret; +} + +static int msm8x16_wcd_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) +{ + if (reg == SND_SOC_NOPM) + return 0; + + BUG_ON(reg > MSM8X16_WCD_MAX_REGISTER); + if (!msm8x16_wcd_volatile(codec, reg)) + msm8x16_wcd_reset_reg_defaults[reg] = value; + + return __msm8x16_wcd_reg_write(codec, reg, (u8)value); +} + +static int __msm8x16_wcd_reg_read(struct snd_soc_codec *codec, + unsigned short reg) +{ + int ret = -EINVAL; + u32 temp = 0; + struct wcd_chip *chip = dev_get_drvdata(codec->dev); + + if (MSM8X16_WCD_IS_TOMBAK_REG(reg)) { + ret = regmap_read(chip->analog_map, + chip->analog_base + reg, &temp); + } else if (MSM8X16_WCD_IS_DIGITAL_REG(reg)) { + u32 val; + u16 offset = (reg ^ 0x0200) & 0x0FFF; + + ret = regmap_read(chip->digital_map, offset, &val); + temp = (u8)val; + } + + if (ret < 0) { + dev_err(codec->dev, + "%s: codec read failed for reg 0x%x\n", + __func__, reg); + return ret; + } + + dev_dbg(codec->dev, "Read 0x%02x from 0x%x\n", temp, reg); + + return temp; +} + + +static unsigned int msm8x16_wcd_read(struct snd_soc_codec *codec, + unsigned int reg) +{ + unsigned int val; + + if (reg == SND_SOC_NOPM) + return 0; + + BUG_ON(reg > MSM8X16_WCD_MAX_REGISTER); + + if (!msm8x16_wcd_volatile(codec, reg) && + msm8x16_wcd_readable(codec, reg) && + reg < codec->driver->reg_cache_size) { + return msm8x16_wcd_reset_reg_defaults[reg]; + } + + val = __msm8x16_wcd_reg_read(codec, reg); + + return val; +} + +static const struct msm8x16_wcd_reg_mask_val msm8x16_wcd_reg_defaults[] = { + MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL, 0x03), + MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT, 0x82), + MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_SPKR_OCP_CTL, 0xE1), +}; + +static const struct msm8x16_wcd_reg_mask_val msm8x16_wcd_reg_defaults_2_0[] = { + MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL3, 0x0F), + MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_TX_1_2_OPAMP_BIAS, 0x4B), + MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_NCP_FBCTRL, 0x28), + MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL, 0x69), + MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_SPKR_DRV_DBG, 0x01), + MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL, 0x5F), + MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_SLOPE_COMP_IP_ZERO, 0x88), + MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL3, 0x0F), + MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT, 0x82), + MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL, 0x03), + MSM8X16_WCD_REG_VAL(MSM8X16_WCD_A_ANALOG_SPKR_OCP_CTL, 0xE1), +}; + +static int msm8x16_wcd_bringup(struct snd_soc_codec *codec) +{ + snd_soc_write(codec, MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL4, 0x01); + snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL4, 0x01); + return 0; +} + +static const struct msm8x16_wcd_reg_mask_val + msm8x16_wcd_codec_reg_init_val[] = { + + /* Initialize current threshold to 350MA + * number of wait and run cycles to 4096 + */ + {MSM8X16_WCD_A_ANALOG_RX_COM_OCP_CTL, 0xFF, 0xD1}, + {MSM8X16_WCD_A_ANALOG_RX_COM_OCP_COUNT, 0xFF, 0xFF}, +}; + +static void msm8x16_wcd_codec_init_reg(struct snd_soc_codec *codec) +{ + u32 i; + + for (i = 0; i < ARRAY_SIZE(msm8x16_wcd_codec_reg_init_val); i++) + snd_soc_update_bits(codec, + msm8x16_wcd_codec_reg_init_val[i].reg, + msm8x16_wcd_codec_reg_init_val[i].mask, + msm8x16_wcd_codec_reg_init_val[i].val); +} + +static void msm8x16_wcd_update_reg_defaults(struct snd_soc_codec *codec) +{ + u32 i; + struct wcd_chip *msm8x16_wcd = snd_soc_codec_get_drvdata(codec); + + if (TOMBAK_IS_1_0(msm8x16_wcd->pmic_rev)) { + for (i = 0; i < ARRAY_SIZE(msm8x16_wcd_reg_defaults); i++) + snd_soc_write(codec, msm8x16_wcd_reg_defaults[i].reg, + msm8x16_wcd_reg_defaults[i].val); + } else { + for (i = 0; i < ARRAY_SIZE(msm8x16_wcd_reg_defaults_2_0); i++) + snd_soc_write(codec, + msm8x16_wcd_reg_defaults_2_0[i].reg, + msm8x16_wcd_reg_defaults_2_0[i].val); + } +} + +static int msm8x16_wcd_device_up(struct snd_soc_codec *codec) +{ + u32 reg; + + dev_dbg(codec->dev, "%s: device up!\n", __func__); + msm8x16_wcd_bringup(codec); + + for (reg = 0; reg < ARRAY_SIZE(msm8x16_wcd_reset_reg_defaults); reg++) + if (msm8x16_wcd_reg_readable[reg]) + msm8x16_wcd_write(codec, + reg, msm8x16_wcd_reset_reg_defaults[reg]); + + /* delay is required to make sure sound card state updated */ + usleep_range(5000, 5100); + + msm8x16_wcd_codec_init_reg(codec); + msm8x16_wcd_update_reg_defaults(codec); + + + return 0; +} + +static int msm8x16_wcd_codec_enable_clock_block(struct snd_soc_codec *codec, + int enable) +{ + struct wcd_chip *msm8x16_wcd = snd_soc_codec_get_drvdata(codec); + unsigned long mclk_rate; + + if (enable) { + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_CLK_MCLK_CTL, 0x01, 0x01); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_CLK_PDM_CTL, 0x03, 0x03); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_MASTER_BIAS_CTL, 0x30, 0x30); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_RST_CTL, 0x80, 0x80); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_TOP_CLK_CTL, 0x0C, 0x0C); + + mclk_rate = clk_get_rate(msm8x16_wcd->mclk); + + if (mclk_rate == 12288000) + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_TOP_CTL, 0x01, 0x00); + else if (mclk_rate == 9600000) + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_TOP_CTL, 0x01, 0x01); + } else { + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_TOP_CLK_CTL, 0x0C, 0x00); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_CLK_PDM_CTL, 0x03, 0x00); + + } + return 0; +} + +static int msm8x16_wcd_codec_probe(struct snd_soc_codec *codec) +{ + struct wcd_chip *chip = dev_get_drvdata(codec->dev); + int err; + + snd_soc_codec_set_drvdata(codec, chip); + chip->pmic_rev = snd_soc_read(codec, MSM8X16_WCD_A_DIGITAL_REVISION1); + dev_info(codec->dev, "%s :PMIC REV: %d", __func__, + chip->pmic_rev); + + chip->codec_version = snd_soc_read(codec, + MSM8X16_WCD_A_DIGITAL_PERPH_SUBTYPE); + dev_info(codec->dev, "%s :CODEC Version: %d", __func__, + chip->codec_version); + + msm8x16_wcd_device_up(codec); + + err = regulator_enable(chip->vddio); + if (err < 0) { + dev_err(codec->dev, "failed to enable VDD regulator\n"); + return err; + } + + err = regulator_enable(chip->vdd_pa); + if (err < 0) { + dev_err(codec->dev, "failed to enable VDD regulator\n"); + return err; + } + + msm8x16_wcd_codec_enable_clock_block(codec, 1); + + return 0; +} + +static int msm8x16_wcd_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + dev_dbg(dai->codec->dev, "%s(): substream = %s stream = %d\n", + __func__, + substream->name, substream->stream); + return 0; +} + +static void msm8x16_wcd_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + dev_dbg(dai->codec->dev, + "%s(): substream = %s stream = %d\n", __func__, + substream->name, substream->stream); +} + +static int msm8x16_wcd_set_interpolator_rate(struct snd_soc_dai *dai, + u8 rx_fs_rate_reg_val, u32 sample_rate) +{ + return 0; +} + +static int msm8x16_wcd_set_decimator_rate(struct snd_soc_dai *dai, + u8 tx_fs_rate_reg_val, u32 sample_rate) +{ + return 0; +} + +static int msm8x16_wcd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + u8 tx_fs_rate, rx_fs_rate; + int ret; + + dev_dbg(dai->codec->dev, + "%s: dai_name = %s DAI-ID %x rate %d num_ch %d format %d\n", + __func__, dai->name, dai->id, params_rate(params), + params_channels(params), params_format(params)); + + switch (params_rate(params)) { + case 8000: + tx_fs_rate = 0x00; + rx_fs_rate = 0x00; + break; + case 16000: + tx_fs_rate = 0x01; + rx_fs_rate = 0x20; + break; + case 32000: + tx_fs_rate = 0x02; + rx_fs_rate = 0x40; + break; + case 48000: + tx_fs_rate = 0x03; + rx_fs_rate = 0x60; + break; + case 96000: + tx_fs_rate = 0x04; + rx_fs_rate = 0x80; + break; + case 192000: + tx_fs_rate = 0x05; + rx_fs_rate = 0xA0; + break; + default: + dev_err(dai->codec->dev, + "%s: Invalid sampling rate %d\n", __func__, + params_rate(params)); + return -EINVAL; + } + + switch (substream->stream) { + case SNDRV_PCM_STREAM_CAPTURE: + ret = msm8x16_wcd_set_decimator_rate(dai, tx_fs_rate, + params_rate(params)); + if (ret < 0) { + dev_err(dai->codec->dev, + "%s: set decimator rate failed %d\n", __func__, + ret); + return ret; + } + break; + case SNDRV_PCM_STREAM_PLAYBACK: + ret = msm8x16_wcd_set_interpolator_rate(dai, rx_fs_rate, + params_rate(params)); + if (ret < 0) { + dev_err(dai->codec->dev, + "%s: set decimator rate failed %d\n", __func__, + ret); + return ret; + } + break; + default: + dev_err(dai->codec->dev, + "%s: Invalid stream type %d\n", __func__, + substream->stream); + return -EINVAL; + } + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + snd_soc_update_bits(dai->codec, + MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL, 0x20, 0x20); + break; + case SNDRV_PCM_FORMAT_S24_LE: + snd_soc_update_bits(dai->codec, + MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL, 0x20, 0x00); + break; + default: + dev_err(dai->dev, "%s: wrong format selected\n", + __func__); + return -EINVAL; + } + + return 0; +} + +static int msm8x16_wcd_set_dai_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + dev_dbg(dai->codec->dev, "%s\n", __func__); + return 0; +} + +static int msm8x16_wcd_set_channel_map(struct snd_soc_dai *dai, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot) + +{ + dev_dbg(dai->codec->dev, "%s\n", __func__); + return 0; +} + +static int msm8x16_wcd_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + dev_dbg(dai->codec->dev, "%s\n", __func__); + + return 0; +} + +static struct snd_soc_dai_ops msm8x16_wcd_dai_ops = { + .startup = msm8x16_wcd_startup, + .shutdown = msm8x16_wcd_shutdown, + .hw_params = msm8x16_wcd_hw_params, + .set_sysclk = msm8x16_wcd_set_dai_sysclk, + .set_fmt = msm8x16_wcd_set_dai_fmt, + .set_channel_map = msm8x16_wcd_set_channel_map, +}; + +static struct snd_soc_dai_driver msm8x16_wcd_codec_dai[] = { + { + .name = "msm8x16_wcd_i2s_rx1", + .id = AIF1_PB, + .playback = { + .stream_name = "AIF1 Playback", + .rates = MSM8X16_WCD_RATES, + .formats = MSM8X16_WCD_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 3, + }, + .ops = &msm8x16_wcd_dai_ops, + }, + { + .name = "msm8x16_wcd_i2s_tx1", + .id = AIF1_CAP, + .capture = { + .stream_name = "AIF1 Capture", + .rates = MSM8X16_WCD_RATES, + .formats = MSM8X16_WCD_FORMATS, + .rate_max = 192000, + .rate_min = 8000, + .channels_min = 1, + .channels_max = 4, + }, + .ops = &msm8x16_wcd_dai_ops, + }, +}; + +static int msm8x16_wcd_codec_remove(struct snd_soc_codec *codec) +{ + /* TODO */ + return 0; +}; + + +static int msm8x16_wcd_spk_boost_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wcd_chip *msm8x16_wcd = dev_get_drvdata(codec->dev); + + if (msm8x16_wcd->spk_boost_set == false) { + ucontrol->value.integer.value[0] = 0; + } else if (msm8x16_wcd->spk_boost_set == true) { + ucontrol->value.integer.value[0] = 1; + } else { + dev_err(codec->dev, "%s: ERROR: Unsupported Speaker Boost = %d\n", + __func__, msm8x16_wcd->spk_boost_set); + return -EINVAL; + } + + dev_dbg(codec->dev, "%s: msm8x16_wcd->spk_boost_set = %d\n", __func__, + msm8x16_wcd->spk_boost_set); + return 0; +} + +static int msm8x16_wcd_spk_boost_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wcd_chip *msm8x16_wcd = snd_soc_codec_get_drvdata(codec); + + + switch (ucontrol->value.integer.value[0]) { + case 0: + msm8x16_wcd->spk_boost_set = false; + break; + case 1: + msm8x16_wcd->spk_boost_set = true; + break; + default: + return -EINVAL; + } + dev_dbg(codec->dev, "%s: msm8x16_wcd->spk_boost_set = %d\n", + __func__, msm8x16_wcd->spk_boost_set); + return 0; +} + +static const char * const hph_text[] = { + "ZERO", "Switch", +}; + +static const struct soc_enum hph_enum = + SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(hph_text), hph_text); + + +static const struct snd_kcontrol_new hphl_mux[] = { + SOC_DAPM_ENUM("HPHL", hph_enum) +}; + +static const struct snd_kcontrol_new hphr_mux[] = { + SOC_DAPM_ENUM("HPHR", hph_enum) +}; + +static const struct snd_kcontrol_new spkr_switch[] = { + SOC_DAPM_SINGLE("Switch", + MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL, 7, 1, 0) +}; + +static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); +static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); + +static const struct snd_soc_dapm_route audio_map[] = { + {"RX_I2S_CLK", NULL, "CDC_CONN"}, + {"I2S RX1", NULL, "RX_I2S_CLK"}, + {"I2S RX2", NULL, "RX_I2S_CLK"}, + {"I2S RX3", NULL, "RX_I2S_CLK"}, + + {"I2S TX1", NULL, "TX_I2S_CLK"}, + {"I2S TX2", NULL, "TX_I2S_CLK"}, + + {"I2S TX1", NULL, "DEC1 MUX"}, + {"I2S TX2", NULL, "DEC2 MUX"}, + + /* RDAC Connections */ + {"HPHR DAC", NULL, "RDAC2 MUX"}, + {"RDAC2 MUX", "RX1", "RX1 CHAIN"}, + {"RDAC2 MUX", "RX2", "RX2 CHAIN"}, + + /* Earpiece (RX MIX1) */ + {"EAR", NULL, "EAR_S"}, + {"EAR_S", "Switch", "EAR PA"}, + {"EAR PA", NULL, "RX_BIAS"}, + {"EAR PA", NULL, "HPHL DAC"}, + {"EAR PA", NULL, "HPHR DAC"}, + {"EAR PA", NULL, "EAR CP"}, + + /* Headset (RX MIX1 and RX MIX2) */ + {"HEADPHONE", NULL, "HPHL PA"}, + {"HEADPHONE", NULL, "HPHR PA"}, + + + {"HPHL PA", NULL, "HPHL"}, + {"HPHR PA", NULL, "HPHR"}, + {"HPHL", "Switch", "HPHL DAC"}, + {"HPHR", "Switch", "HPHR DAC"}, + {"HPHL PA", NULL, "CP"}, + {"HPHL PA", NULL, "RX_BIAS"}, + {"HPHR PA", NULL, "CP"}, + {"HPHR PA", NULL, "RX_BIAS"}, + {"HPHL DAC", NULL, "RX1 CHAIN"}, + + {"SPK_OUT", NULL, "SPK PA"}, + {"SPK PA", NULL, "SPK_RX_BIAS"}, + {"SPK PA", NULL, "SPK DAC"}, + {"SPK DAC", "Switch", "RX3 CHAIN"}, + + {"RX1 CHAIN", NULL, "RX1 CLK"}, + {"RX2 CHAIN", NULL, "RX2 CLK"}, + {"RX3 CHAIN", NULL, "RX3 CLK"}, + {"RX1 CHAIN", NULL, "RX1 MIX2"}, + {"RX2 CHAIN", NULL, "RX2 MIX2"}, + {"RX1 CHAIN", NULL, "RX1 MIX1"}, + {"RX2 CHAIN", NULL, "RX2 MIX1"}, + {"RX3 CHAIN", NULL, "RX3 MIX1"}, + + {"RX1 MIX1", NULL, "RX1 MIX1 INP1"}, + {"RX1 MIX1", NULL, "RX1 MIX1 INP2"}, + {"RX1 MIX1", NULL, "RX1 MIX1 INP3"}, + + {"RX2 MIX1", NULL, "RX2 MIX1 INP1"}, + {"RX2 MIX1", NULL, "RX2 MIX1 INP2"}, + + {"RX3 MIX1", NULL, "RX3 MIX1 INP1"}, + {"RX3 MIX1", NULL, "RX3 MIX1 INP2"}, + + {"RX1 MIX2", NULL, "RX1 MIX2 INP1"}, + {"RX2 MIX2", NULL, "RX2 MIX2 INP1"}, + + {"RX1 MIX1 INP1", "RX1", "I2S RX1"}, + {"RX1 MIX1 INP1", "RX2", "I2S RX2"}, + {"RX1 MIX1 INP1", "RX3", "I2S RX3"}, + {"RX1 MIX1 INP1", "IIR1", "IIR1"}, + {"RX1 MIX1 INP2", "RX1", "I2S RX1"}, + {"RX1 MIX1 INP2", "RX2", "I2S RX2"}, + {"RX1 MIX1 INP2", "RX3", "I2S RX3"}, + {"RX1 MIX1 INP2", "IIR1", "IIR1"}, + {"RX1 MIX1 INP3", "RX1", "I2S RX1"}, + {"RX1 MIX1 INP3", "RX2", "I2S RX2"}, + {"RX1 MIX1 INP3", "RX3", "I2S RX3"}, + + {"RX2 MIX1 INP1", "RX1", "I2S RX1"}, + {"RX2 MIX1 INP1", "RX2", "I2S RX2"}, + {"RX2 MIX1 INP1", "RX3", "I2S RX3"}, + {"RX2 MIX1 INP1", "IIR1", "IIR1"}, + {"RX2 MIX1 INP2", "RX1", "I2S RX1"}, + {"RX2 MIX1 INP2", "RX2", "I2S RX2"}, + {"RX2 MIX1 INP2", "RX3", "I2S RX3"}, + {"RX2 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX3 MIX1 INP1", "RX1", "I2S RX1"}, + {"RX3 MIX1 INP1", "RX2", "I2S RX2"}, + {"RX3 MIX1 INP1", "RX3", "I2S RX3"}, + {"RX3 MIX1 INP1", "IIR1", "IIR1"}, + {"RX3 MIX1 INP2", "RX1", "I2S RX1"}, + {"RX3 MIX1 INP2", "RX2", "I2S RX2"}, + {"RX3 MIX1 INP2", "RX3", "I2S RX3"}, + {"RX3 MIX1 INP2", "IIR1", "IIR1"}, + + {"RX1 MIX2 INP1", "IIR1", "IIR1"}, + {"RX2 MIX2 INP1", "IIR1", "IIR1"}, + + /* Decimator Inputs */ + {"DEC1 MUX", "DMIC1", "DMIC1"}, + {"DEC1 MUX", "DMIC2", "DMIC2"}, + {"DEC1 MUX", "ADC1", "ADC1"}, + {"DEC1 MUX", "ADC2", "ADC2"}, + {"DEC1 MUX", "ADC3", "ADC3"}, + {"DEC1 MUX", NULL, "CDC_CONN"}, + + {"DEC2 MUX", "DMIC1", "DMIC1"}, + {"DEC2 MUX", "DMIC2", "DMIC2"}, + {"DEC2 MUX", "ADC1", "ADC1"}, + {"DEC2 MUX", "ADC2", "ADC2"}, + {"DEC2 MUX", "ADC3", "ADC3"}, + {"DEC2 MUX", NULL, "CDC_CONN"}, + + /* ADC Connections */ + {"ADC2", NULL, "ADC2 MUX"}, + {"ADC3", NULL, "ADC2 MUX"}, + {"ADC2 MUX", "INP2", "ADC2_INP2"}, + {"ADC2 MUX", "INP3", "ADC2_INP3"}, + + {"ADC1", NULL, "AMIC1"}, + {"ADC2_INP2", NULL, "AMIC2"}, + {"ADC2_INP3", NULL, "AMIC3"}, + + /* TODO: Fix this */ + {"IIR1", NULL, "IIR1 INP1 MUX"}, + {"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"}, + {"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"}, + {"MIC BIAS Internal1", NULL, "INT_LDO_H"}, + {"MIC BIAS Internal2", NULL, "INT_LDO_H"}, + {"MIC BIAS External", NULL, "INT_LDO_H"}, + {"MIC BIAS External2", NULL, "INT_LDO_H"}, + {"MIC BIAS Internal1", NULL, "MICBIAS_REGULATOR"}, + {"MIC BIAS Internal2", NULL, "MICBIAS_REGULATOR"}, + {"MIC BIAS External", NULL, "MICBIAS_REGULATOR"}, + {"MIC BIAS External2", NULL, "MICBIAS_REGULATOR"}, +}; + +static const char * const rx_mix1_text[] = { + "ZERO", "IIR1", "IIR2", "RX1", "RX2", "RX3" +}; + +static const char * const rx_mix2_text[] = { + "ZERO", "IIR1", "IIR2" +}; + +static const char * const dec_mux_text[] = { + "ZERO", "ADC1", "ADC2", "ADC3", "DMIC1", "DMIC2" +}; + +static const char * const adc2_mux_text[] = { + "ZERO", "INP2", "INP3" +}; + +static const char * const rdac2_mux_text[] = { + "ZERO", "RX2", "RX1" +}; + +static const char * const iir1_inp1_text[] = { + "ZERO", "DEC1", "DEC2", "RX1", "RX2", "RX3" +}; + +/* RX1 MIX1 */ +static const struct soc_enum rx_mix1_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX1_B1_CTL, + 0, 6, rx_mix1_text); + +static const struct soc_enum rx_mix1_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX1_B1_CTL, + 3, 6, rx_mix1_text); + +static const struct soc_enum rx_mix1_inp3_chain_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX1_B2_CTL, + 0, 6, rx_mix1_text); +/* RX1 MIX2 */ +static const struct soc_enum rx_mix2_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX1_B3_CTL, + 0, 3, rx_mix2_text); + +/* RX2 MIX1 */ +static const struct soc_enum rx2_mix1_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL, + 0, 6, rx_mix1_text); + +static const struct soc_enum rx2_mix1_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL, + 3, 6, rx_mix1_text); + +static const struct soc_enum rx2_mix1_inp3_chain_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL, + 0, 6, rx_mix1_text); + +/* RX2 MIX2 */ +static const struct soc_enum rx2_mix2_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX2_B3_CTL, + 0, 3, rx_mix2_text); + +/* RX3 MIX1 */ +static const struct soc_enum rx3_mix1_inp1_chain_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL, + 0, 6, rx_mix1_text); + +static const struct soc_enum rx3_mix1_inp2_chain_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL, + 3, 6, rx_mix1_text); + +static const struct soc_enum rdac2_mux_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_DIGITAL_CDC_CONN_HPHR_DAC_CTL, + 0, 3, rdac2_mux_text); + +static const struct soc_enum rx3_mix1_inp3_chain_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL, + 0, 6, rx_mix1_text); +static const struct snd_kcontrol_new rx_mix1_inp1_mux = + SOC_DAPM_ENUM("RX1 MIX1 INP1 Mux", rx_mix1_inp1_chain_enum); + +static const struct snd_kcontrol_new rdac2_mux = + SOC_DAPM_ENUM("RDAC2 MUX Mux", rdac2_mux_enum); + +static const struct snd_kcontrol_new rx_mix1_inp2_mux = + SOC_DAPM_ENUM("RX1 MIX1 INP2 Mux", rx_mix1_inp2_chain_enum); + +static const struct snd_kcontrol_new rx_mix1_inp3_mux = + SOC_DAPM_ENUM("RX1 MIX1 INP3 Mux", rx_mix1_inp3_chain_enum); + +static const struct snd_kcontrol_new rx2_mix1_inp1_mux = + SOC_DAPM_ENUM("RX2 MIX1 INP1 Mux", rx2_mix1_inp1_chain_enum); + +static const struct snd_kcontrol_new rx2_mix1_inp2_mux = + SOC_DAPM_ENUM("RX2 MIX1 INP2 Mux", rx2_mix1_inp2_chain_enum); + +static const struct snd_kcontrol_new rx2_mix1_inp3_mux = + SOC_DAPM_ENUM("RX2 MIX1 INP3 Mux", rx2_mix1_inp3_chain_enum); + +static const struct snd_kcontrol_new rx3_mix1_inp1_mux = + SOC_DAPM_ENUM("RX3 MIX1 INP1 Mux", rx3_mix1_inp1_chain_enum); + +static const struct snd_kcontrol_new rx3_mix1_inp2_mux = + SOC_DAPM_ENUM("RX3 MIX1 INP2 Mux", rx3_mix1_inp2_chain_enum); + +static const struct snd_kcontrol_new rx3_mix1_inp3_mux = + SOC_DAPM_ENUM("RX3 MIX1 INP3 Mux", rx3_mix1_inp3_chain_enum); + +static const struct snd_kcontrol_new rx1_mix2_inp1_mux = + SOC_DAPM_ENUM("RX1 MIX2 INP1 Mux", rx_mix2_inp1_chain_enum); + +static const struct snd_kcontrol_new rx2_mix2_inp1_mux = + SOC_DAPM_ENUM("RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum); + +static const char * const msm8x16_wcd_loopback_mode_ctrl_text[] = { + "DISABLE", "ENABLE"}; + +static const struct soc_enum msm8x16_wcd_loopback_mode_ctl_enum[] = { + SOC_ENUM_SINGLE_EXT(2, msm8x16_wcd_loopback_mode_ctrl_text), +}; + +static const char * const msm8x16_wcd_ear_pa_boost_ctrl_text[] = { + "DISABLE", "ENABLE"}; +static const struct soc_enum msm8x16_wcd_ear_pa_boost_ctl_enum[] = { + SOC_ENUM_SINGLE_EXT(2, msm8x16_wcd_ear_pa_boost_ctrl_text), +}; + +static const char * const msm8x16_wcd_ear_pa_gain_text[] = { + "POS_6_DB", "POS_1P5_DB"}; +static const struct soc_enum msm8x16_wcd_ear_pa_gain_enum[] = { + SOC_ENUM_SINGLE_EXT(2, msm8x16_wcd_ear_pa_gain_text), +}; + +static const char * const msm8x16_wcd_spk_boost_ctrl_text[] = { + "DISABLE", "ENABLE"}; +static const struct soc_enum msm8x16_wcd_spk_boost_ctl_enum[] = { + SOC_ENUM_SINGLE_EXT(2, msm8x16_wcd_spk_boost_ctrl_text), +}; + +/*cut of frequency for high pass filter*/ +static const char * const cf_text[] = { + "MIN_3DB_4Hz", "MIN_3DB_75Hz", "MIN_3DB_150Hz" +}; + +static const struct soc_enum cf_dec1_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_TX1_MUX_CTL, 4, 3, cf_text); + +static const struct soc_enum cf_dec2_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_TX2_MUX_CTL, 4, 3, cf_text); + +static const struct soc_enum cf_rxmix1_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_RX1_B4_CTL, 0, 3, cf_text); + +static const struct soc_enum cf_rxmix2_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_RX2_B4_CTL, 0, 3, cf_text); + +static const struct soc_enum cf_rxmix3_enum = + SOC_ENUM_SINGLE(MSM8X16_WCD_A_CDC_RX3_B4_CTL, 0, 3, cf_text); + +static const struct snd_kcontrol_new msm8x16_wcd_snd_controls[] = { + + SOC_ENUM_EXT("Speaker Boost", msm8x16_wcd_spk_boost_ctl_enum[0], + msm8x16_wcd_spk_boost_get, msm8x16_wcd_spk_boost_set), + + SOC_SINGLE_TLV("ADC1 Volume", MSM8X16_WCD_A_ANALOG_TX_1_EN, 3, + 8, 0, analog_gain), + SOC_SINGLE_TLV("ADC2 Volume", MSM8X16_WCD_A_ANALOG_TX_2_EN, 3, + 8, 0, analog_gain), + SOC_SINGLE_TLV("ADC3 Volume", MSM8X16_WCD_A_ANALOG_TX_3_EN, 3, + 8, 0, analog_gain), + + SOC_SINGLE_SX_TLV("RX1 Digital Volume", + MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX2 Digital Volume", + MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B2_CTL, + 0, -84, 40, digital_gain), + SOC_SINGLE_SX_TLV("RX3 Digital Volume", + MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B2_CTL, + 0, -84, 40, digital_gain), + + SOC_SINGLE("RX1 HPF Switch", + MSM8X16_WCD_A_CDC_RX1_B5_CTL, 2, 1, 0), + SOC_SINGLE("RX2 HPF Switch", + MSM8X16_WCD_A_CDC_RX2_B5_CTL, 2, 1, 0), + SOC_SINGLE("RX3 HPF Switch", + MSM8X16_WCD_A_CDC_RX3_B5_CTL, 2, 1, 0), + + SOC_ENUM("RX1 HPF cut off", cf_rxmix1_enum), + SOC_ENUM("RX2 HPF cut off", cf_rxmix2_enum), + SOC_ENUM("RX3 HPF cut off", cf_rxmix3_enum), +}; + + +static const struct snd_kcontrol_new ear_pa_switch[] = { + SOC_DAPM_SINGLE("Switch", + MSM8X16_WCD_A_ANALOG_RX_EAR_CTL, 5, 1, 0) +}; + +static int msm8x16_wcd_codec_enable_ear_pa(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 wcd_chip *msm8x16_wcd = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + dev_dbg(codec->dev, + "%s: Sleeping 20ms after select EAR PA\n", + __func__); + snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_RX_EAR_CTL, + 0x80, 0x80); + break; + case SND_SOC_DAPM_POST_PMU: + dev_dbg(codec->dev, + "%s: Sleeping 20ms after enabling EAR PA\n", + __func__); + snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_RX_EAR_CTL, + 0x40, 0x40); + usleep_range(7000, 7100); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0x01, 0x00); + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0x01, 0x01); + msleep(20); + msm8x16_wcd->mute_mask |= EAR_PA_DISABLE; + break; + case SND_SOC_DAPM_POST_PMD: + dev_dbg(codec->dev, + "%s: Sleeping 7ms after disabling EAR PA\n", + __func__); + snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_RX_EAR_CTL, + 0x40, 0x00); + usleep_range(7000, 7100); + /* + * Reset pa select bit from ear to hph after ear pa + * is disabled to reduce ear turn off pop + */ + snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_RX_EAR_CTL, + 0x80, 0x00); + break; + } + return 0; +} + + +static int msm8x16_wcd_codec_enable_spk_pa(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 wcd_chip *msm8x16_wcd = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x10); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL, 0x01, 0x01); + if (!msm8x16_wcd->spk_boost_set) + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL, 0x10, 0x10); + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL, 0xE0, 0xE0); + if (!TOMBAK_IS_1_0(msm8x16_wcd->pmic_rev)) + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_RX_EAR_CTL, 0x01, 0x01); + break; + case SND_SOC_DAPM_POST_PMU: + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + if (msm8x16_wcd->spk_boost_set) + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL, 0xEF, 0xEF); + else + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL, 0x10, 0x00); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_RX3_B6_CTL, 0x01, 0x00); + snd_soc_update_bits(codec, w->reg, 0x80, 0x80); + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_RX3_B6_CTL, 0x01, 0x01); + msleep(20); + msm8x16_wcd->mute_mask |= SPKR_PA_DISABLE; + snd_soc_update_bits(codec, w->reg, 0x80, 0x00); + if (msm8x16_wcd->spk_boost_set) + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL, 0xEF, 0x00); + else + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL, 0x10, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL, 0xE0, 0x00); + if (!TOMBAK_IS_1_0(msm8x16_wcd->pmic_rev)) + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_RX_EAR_CTL, 0x01, 0x00); + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL, 0x01, 0x00); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00); + break; + } + return 0; +} + +static int msm8x16_wcd_codec_enable_interpolator(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 wcd_chip *msm8x16_wcd = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* apply the digital gain after the interpolator is enabled*/ + if ((w->shift) < ARRAY_SIZE(rx_digital_gain_reg)) + snd_soc_write(codec, + rx_digital_gain_reg[w->shift], + snd_soc_read(codec, + rx_digital_gain_reg[w->shift]) + ); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_CLK_RX_RESET_CTL, + 1 << w->shift, 1 << w->shift); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_CLK_RX_RESET_CTL, + 1 << w->shift, 0x0); + /* + * disable the mute enabled during the PMD of this device + */ + if (msm8x16_wcd->mute_mask & HPHL_PA_DISABLE) { + pr_debug("disabling HPHL mute\n"); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0x01, 0x00); + msm8x16_wcd->mute_mask &= ~(HPHL_PA_DISABLE); + } + if (msm8x16_wcd->mute_mask & HPHR_PA_DISABLE) { + pr_debug("disabling HPHR mute\n"); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_RX2_B6_CTL, 0x01, 0x00); + msm8x16_wcd->mute_mask &= ~(HPHR_PA_DISABLE); + } + if (msm8x16_wcd->mute_mask & SPKR_PA_DISABLE) { + pr_debug("disabling SPKR mute\n"); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_RX3_B6_CTL, 0x01, 0x00); + msm8x16_wcd->mute_mask &= ~(SPKR_PA_DISABLE); + } + if (msm8x16_wcd->mute_mask & EAR_PA_DISABLE) { + pr_debug("disabling EAR mute\n"); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0x01, 0x00); + msm8x16_wcd->mute_mask &= ~(EAR_PA_DISABLE); + } + } + return 0; +} + +static int msm8x16_wcd_codec_enable_dig_clk(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 wcd_chip *msm8x16_wcd = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (w->shift == 2) + snd_soc_update_bits(codec, w->reg, 0x80, 0x80); + if (msm8x16_wcd->spk_boost_set) { + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_SEC_ACCESS, + 0xA5, 0xA5); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL3, + 0x0F, 0x0F); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT, + 0x82, 0x82); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, + 0x20, 0x20); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL, + 0xDF, 0xDF); + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT, + 0x83, 0x83); + } else if (msm8x16_wcd->ear_pa_boost_set) { + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_SEC_ACCESS, + 0xA5, 0xA5); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL3, + 0x07, 0x07); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_BYPASS_MODE, + 0x40, 0x40); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_BYPASS_MODE, + 0x80, 0x80); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_BYPASS_MODE, + 0x02, 0x02); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL, + 0xDF, 0xDF); + } else { + snd_soc_update_bits(codec, w->reg, 1<shift, + 1<shift); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (msm8x16_wcd->spk_boost_set) { + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL, + 0xDF, 0x5F); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, + 0x20, 0x00); + } else if (msm8x16_wcd->ear_pa_boost_set) { + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL, + 0x80, 0x00); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_BYPASS_MODE, + 0x80, 0x00); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_BYPASS_MODE, + 0x02, 0x00); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_BYPASS_MODE, + 0x40, 0x00); + } else { + snd_soc_update_bits(codec, w->reg, 1<shift, 0x00); + } + break; + } + return 0; +} + +static int msm8x16_wcd_codec_enable_rx_chain(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x80); + dev_dbg(codec->dev, + "%s: PMU:Sleeping 20ms after disabling mute\n", + __func__); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x00); + dev_dbg(codec->dev, + "%s: PMD:Sleeping 20ms after disabling mute\n", + __func__); + snd_soc_update_bits(codec, w->reg, + 1 << w->shift, 0x00); + msleep(20); + break; + } + return 0; +} + +static int msm8x16_wcd_codec_enable_rx_bias(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 wcd_chip *msm8x16_wcd = snd_soc_codec_get_drvdata(codec); + + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + msm8x16_wcd->rx_bias_count++; + if (msm8x16_wcd->rx_bias_count == 1) + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC, + 0x81, 0x81); + break; + case SND_SOC_DAPM_POST_PMD: + msm8x16_wcd->rx_bias_count--; + if (msm8x16_wcd->rx_bias_count == 0) + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC, + 0x81, 0x00); + break; + } + dev_dbg(codec->dev, "%s rx_bias_count = %d\n", + __func__, msm8x16_wcd->rx_bias_count); + return 0; +} + +static int msm8x16_wcd_codec_enable_charge_pump(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 wcd_chip *msm8x16_wcd = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (!(strcmp(w->name, "EAR CP"))) + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x80); + else + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, + 0xC0, 0xC0); + break; + case SND_SOC_DAPM_POST_PMU: + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + break; + case SND_SOC_DAPM_POST_PMD: + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + if (!(strcmp(w->name, "EAR CP"))) + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x00); + else { + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, + 0x40, 0x00); + if (msm8x16_wcd->rx_bias_count == 0) + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, + 0x80, 0x00); + dev_dbg(codec->dev, "%s: rx_bias_count = %d\n", + __func__, msm8x16_wcd->rx_bias_count); + } + break; + } + return 0; +} + +static int msm8x16_wcd_hphl_dac_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); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x02, 0x02); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x01); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x02); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL, 0x02, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL, 0x02, 0x00); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, 0x01, 0x00); + break; + } + return 0; +} + +static int msm8x16_wcd_hph_pa_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 wcd_chip *msm8x16_wcd = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (w->shift == 5) { + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_RX_HPH_L_TEST, 0x04, 0x04); + } else if (w->shift == 4) { + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_RX_HPH_R_TEST, 0x04, 0x04); + } + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_NCP_FBCTRL, 0x20, 0x20); + break; + + case SND_SOC_DAPM_POST_PMU: + usleep_range(4000, 4100); + if (w->shift == 5) + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0x01, 0x00); + else if (w->shift == 4) + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_RX2_B6_CTL, 0x01, 0x00); + usleep_range(10000, 10100); + break; + + case SND_SOC_DAPM_PRE_PMD: + if (w->shift == 5) { + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0x01, 0x01); + msleep(20); + msm8x16_wcd->mute_mask |= HPHL_PA_DISABLE; + } else if (w->shift == 4) { + snd_soc_update_bits(codec, + MSM8X16_WCD_A_CDC_RX2_B6_CTL, 0x01, 0x01); + msleep(20); + msm8x16_wcd->mute_mask |= HPHR_PA_DISABLE; + } + break; + case SND_SOC_DAPM_POST_PMD: + if (w->shift == 5) { + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_RX_HPH_L_TEST, 0x04, 0x00); + + } else if (w->shift == 4) { + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_RX_HPH_R_TEST, 0x04, 0x00); + } + usleep_range(4000, 4100); + + usleep_range(CODEC_DELAY_1_MS, CODEC_DELAY_1_1_MS); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, 0x40, 0x40); + dev_dbg(codec->dev, + "%s: sleep 10 ms after %s PA disable.\n", __func__, + w->name); + usleep_range(10000, 10100); + break; + } + return 0; +} + +static int msm8x16_wcd_hphr_dac_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); + + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x02, 0x02); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, 0x02, 0x02); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL, 0x01, 0x01); + break; + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, + MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL, 0x02, 0x00); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL, 0x01, 0x00); + snd_soc_update_bits(codec, + MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, 0x02, 0x00); + break; + } + return 0; +} + +static const struct snd_soc_dapm_widget msm8x16_wcd_dapm_widgets[] = { + /*RX stuff */ + SND_SOC_DAPM_OUTPUT("EAR"), + + SND_SOC_DAPM_PGA_E("EAR PA", SND_SOC_NOPM, + 0, 0, NULL, 0, msm8x16_wcd_codec_enable_ear_pa, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("EAR_S", SND_SOC_NOPM, 0, 0, + ear_pa_switch, ARRAY_SIZE(ear_pa_switch)), + + SND_SOC_DAPM_AIF_IN("I2S RX1", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_IN("I2S RX2", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_AIF_IN("I2S RX3", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_SUPPLY("INT_LDO_H", SND_SOC_NOPM, 1, 0, NULL, 0), + + SND_SOC_DAPM_OUTPUT("HEADPHONE"), + SND_SOC_DAPM_PGA_E("HPHL PA", MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_EN, + 5, 0, NULL, 0, + msm8x16_wcd_hph_pa_event, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("HPHL", SND_SOC_NOPM, 0, 0, hphl_mux), + + SND_SOC_DAPM_MIXER_E("HPHL DAC", + MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL, 3, 0, NULL, + 0, msm8x16_wcd_hphl_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_PGA_E("HPHR PA", MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_EN, + 4, 0, NULL, 0, + msm8x16_wcd_hph_pa_event, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX("HPHR", SND_SOC_NOPM, 0, 0, hphr_mux), + + SND_SOC_DAPM_MIXER("SPK DAC", SND_SOC_NOPM, 0, 0, + spkr_switch, ARRAY_SIZE(spkr_switch)), + + SND_SOC_DAPM_MIXER_E("HPHR DAC", + MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL, 3, 0, NULL, + 0, msm8x16_wcd_hphr_dac_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + /* Speaker */ + SND_SOC_DAPM_OUTPUT("SPK_OUT"), + + SND_SOC_DAPM_PGA_E("SPK PA", MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL, + 6, 0, NULL, 0, msm8x16_wcd_codec_enable_spk_pa, + SND_SOC_DAPM_PRE_REG| + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER_E("RX1 MIX1", + MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL, 0, + msm8x16_wcd_codec_enable_interpolator, + SND_SOC_DAPM_PRE_REG| + SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD| + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER_E("RX2 MIX1", + MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL, 0, + msm8x16_wcd_codec_enable_interpolator, + SND_SOC_DAPM_PRE_REG| + SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER_E("RX1 MIX2", + MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL, + 0, msm8x16_wcd_codec_enable_interpolator, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX2 MIX2", + MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL, + 0, msm8x16_wcd_codec_enable_interpolator, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX3 MIX1", + MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL, + 0, msm8x16_wcd_codec_enable_interpolator, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("RX1 CLK", MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, + 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("RX2 CLK", MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, + 1, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("RX3 CLK", MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, + 2, 0, msm8x16_wcd_codec_enable_dig_clk, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX1 CHAIN", MSM8X16_WCD_A_CDC_RX1_B6_CTL, 0, 0, + NULL, 0, + msm8x16_wcd_codec_enable_rx_chain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX2 CHAIN", MSM8X16_WCD_A_CDC_RX2_B6_CTL, 0, 0, + NULL, 0, + msm8x16_wcd_codec_enable_rx_chain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX3 CHAIN", MSM8X16_WCD_A_CDC_RX3_B6_CTL, 0, 0, + NULL, 0, + msm8x16_wcd_codec_enable_rx_chain, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx_mix1_inp1_mux), + SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx_mix1_inp2_mux), + SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0, + &rx_mix1_inp3_mux), + + SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx2_mix1_inp1_mux), + SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx2_mix1_inp2_mux), + SND_SOC_DAPM_MUX("RX2 MIX1 INP3", SND_SOC_NOPM, 0, 0, + &rx2_mix1_inp3_mux), + + SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0, + &rx3_mix1_inp1_mux), + SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0, + &rx3_mix1_inp2_mux), + SND_SOC_DAPM_MUX("RX3 MIX1 INP3", SND_SOC_NOPM, 0, 0, + &rx3_mix1_inp3_mux), + + SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0, + &rx1_mix2_inp1_mux), + SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0, + &rx2_mix2_inp1_mux), + SND_SOC_DAPM_SUPPLY("CP", MSM8X16_WCD_A_ANALOG_NCP_EN, 0, 0, + msm8x16_wcd_codec_enable_charge_pump, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("EAR CP", MSM8X16_WCD_A_ANALOG_NCP_EN, 4, 0, + msm8x16_wcd_codec_enable_charge_pump, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, + 0, 0, msm8x16_wcd_codec_enable_rx_bias, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY("SPK_RX_BIAS", + SND_SOC_NOPM, 0, 0, + msm8x16_wcd_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX("RDAC2 MUX", SND_SOC_NOPM, 0, 0, &rdac2_mux), + SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", + MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL, 4, 0, NULL, 0), +}; + + +static struct snd_soc_codec_driver msm8x16_wcd_codec = { + .probe = msm8x16_wcd_codec_probe, + .remove = msm8x16_wcd_codec_remove, + .read = msm8x16_wcd_read, + .write = msm8x16_wcd_write, + .reg_cache_size = MSM8X16_WCD_CACHE_SIZE, + .reg_cache_default = msm8x16_wcd_reset_reg_defaults, + .reg_word_size = 1, + .controls = msm8x16_wcd_snd_controls, + .num_controls = ARRAY_SIZE(msm8x16_wcd_snd_controls), + .dapm_widgets = msm8x16_wcd_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(msm8x16_wcd_dapm_widgets), + .dapm_routes = audio_map, + .num_dapm_routes = ARRAY_SIZE(audio_map), +}; + +static int msm8x16_wcd_codec_parse_dt(struct platform_device *pdev, + struct wcd_chip *chip) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + int ret; + u32 res[2]; + + ret = of_property_read_u32_array(np, "reg", res, 2); + if (ret < 0) + return ret; + + chip->analog_base = res[0]; + + chip->digital_map = syscon_regmap_lookup_by_phandle(np, "digital"); + if (IS_ERR(chip->digital_map)) + return PTR_ERR(chip->digital_map); + + chip->vddio = devm_regulator_get(dev, "vddio"); + if (IS_ERR(chip->vddio)) { + dev_err(dev, "Failed to get vdd supply\n"); + return PTR_ERR(chip->vddio); + } + + chip->vdd_pa = devm_regulator_get(dev, "vdd-pa"); + if (IS_ERR(chip->vdd_pa)) { + dev_err(dev, "Failed to get vdd supply\n"); + return PTR_ERR(chip->vdd_pa); + } + + chip->mclk = devm_clk_get(dev, "mclk"); + + return 0; +} + +static int wcd_probe(struct platform_device *pdev) +{ + struct wcd_chip *chip; + struct device *dev = &pdev->dev; + + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->analog_map = dev_get_regmap(dev->parent, NULL); + if (!chip->analog_map) + return -ENXIO; + + msm8x16_wcd_codec_parse_dt(pdev, chip); + clk_set_rate(chip->mclk, 9600000); + clk_prepare_enable(chip->mclk); + + dev_set_drvdata(dev, chip); + + return snd_soc_register_codec(dev, &msm8x16_wcd_codec, + msm8x16_wcd_codec_dai, + ARRAY_SIZE(msm8x16_wcd_codec_dai)); +} + +static int wcd_remove(struct platform_device *pdev) +{ + return 0; +} + +static const struct of_device_id wcd_match_table[] = { + { .compatible = "qcom,apq8016-wcd-codec" }, + { } +}; +MODULE_DEVICE_TABLE(of, wcd_match_table); + +static struct platform_driver wcd_driver = { + .driver = { + .name = "spmi-wcd-codec", + .of_match_table = wcd_match_table, + }, + .probe = wcd_probe, + .remove = wcd_remove, +}; +module_platform_driver(wcd_driver); + +MODULE_ALIAS("platform:spmi-wcd-codec"); +MODULE_DESCRIPTION("SPMI PMIC WCD codec driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/msm8x16-wcd.h b/sound/soc/codecs/msm8x16-wcd.h new file mode 100644 index 000000000000..ad4c9d0c5ae6 --- /dev/null +++ b/sound/soc/codecs/msm8x16-wcd.h @@ -0,0 +1,234 @@ +/* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef MSM8X16_WCD_H +#define MSM8X16_WCD_H + +#include + +#define MSM8X16_WCD_NUM_REGISTERS 0x6FF +#define MSM8X16_WCD_MAX_REGISTER (MSM8X16_WCD_NUM_REGISTERS-1) +#define MSM8X16_WCD_CACHE_SIZE MSM8X16_WCD_NUM_REGISTERS +#define MSM8X16_WCD_NUM_IRQ_REGS 2 +#define MAX_REGULATOR 7 +#define MSM8X16_WCD_REG_VAL(reg, val) {reg, 0, val} +#define MSM8X16_TOMBAK_LPASS_AUDIO_CORE_DIG_CODEC_CLK_SEL 0xFE03B004 +#define MSM8X16_TOMBAK_LPASS_DIGCODEC_CMD_RCGR 0x0181C09C +#define MSM8X16_TOMBAK_LPASS_DIGCODEC_CFG_RCGR 0x0181C0A0 +#define MSM8X16_TOMBAK_LPASS_DIGCODEC_M 0x0181C0A4 +#define MSM8X16_TOMBAK_LPASS_DIGCODEC_N 0x0181C0A8 +#define MSM8X16_TOMBAK_LPASS_DIGCODEC_D 0x0181C0AC +#define MSM8X16_TOMBAK_LPASS_DIGCODEC_CBCR 0x0181C0B0 +#define MSM8X16_TOMBAK_LPASS_DIGCODEC_AHB_CBCR 0x0181C0B4 + +#define MSM8X16_CODEC_NAME "msm8x16_wcd_codec" + +#define MSM8X16_WCD_IS_DIGITAL_REG(reg) \ + (((reg >= 0x200) && (reg <= 0x4FF)) ? 1 : 0) +#define MSM8X16_WCD_IS_TOMBAK_REG(reg) \ + (((reg >= 0x000) && (reg <= 0x1FF)) ? 1 : 0) +/* + * MCLK activity indicators during suspend and resume call + */ +#define MCLK_SUS_DIS 1 +#define MCLK_SUS_RSC 2 +#define MCLK_SUS_NO_ACT 3 + +#define NUM_DECIMATORS 2 + +extern const u8 msm8x16_wcd_reg_readable[MSM8X16_WCD_CACHE_SIZE]; +extern const u8 msm8x16_wcd_reg_readonly[MSM8X16_WCD_CACHE_SIZE]; +extern u8 msm8x16_wcd_reset_reg_defaults[MSM8X16_WCD_CACHE_SIZE]; + +enum msm8x16_wcd_pid_current { + MSM8X16_WCD_PID_MIC_2P5_UA, + MSM8X16_WCD_PID_MIC_5_UA, + MSM8X16_WCD_PID_MIC_10_UA, + MSM8X16_WCD_PID_MIC_20_UA, +}; + +struct msm8x16_wcd_reg_mask_val { + u16 reg; + u8 mask; + u8 val; +}; + +enum msm8x16_wcd_mbhc_analog_pwr_cfg { + MSM8X16_WCD_ANALOG_PWR_COLLAPSED = 0, + MSM8X16_WCD_ANALOG_PWR_ON, + MSM8X16_WCD_NUM_ANALOG_PWR_CONFIGS, +}; + +/* Number of input and output I2S port */ +enum { + MSM8X16_WCD_RX1 = 0, + MSM8X16_WCD_RX2, + MSM8X16_WCD_RX3, + MSM8X16_WCD_RX_MAX, +}; + +enum { + MSM8X16_WCD_TX1 = 0, + MSM8X16_WCD_TX2, + MSM8X16_WCD_TX3, + MSM8X16_WCD_TX4, + MSM8X16_WCD_TX_MAX, +}; + +enum { + /* INTR_REG 0 - Digital Periph */ + MSM8X16_WCD_IRQ_SPKR_CNP = 0, + MSM8X16_WCD_IRQ_SPKR_CLIP, + MSM8X16_WCD_IRQ_SPKR_OCP, + MSM8X16_WCD_IRQ_MBHC_INSREM_DET1, + MSM8X16_WCD_IRQ_MBHC_RELEASE, + MSM8X16_WCD_IRQ_MBHC_PRESS, + MSM8X16_WCD_IRQ_MBHC_INSREM_DET, + MSM8X16_WCD_IRQ_MBHC_HS_DET, + /* INTR_REG 1 - Analog Periph */ + MSM8X16_WCD_IRQ_EAR_OCP, + MSM8X16_WCD_IRQ_HPHR_OCP, + MSM8X16_WCD_IRQ_HPHL_OCP, + MSM8X16_WCD_IRQ_EAR_CNP, + MSM8X16_WCD_IRQ_HPHR_CNP, + MSM8X16_WCD_IRQ_HPHL_CNP, + MSM8X16_WCD_NUM_IRQS, +}; + +enum wcd_notify_event { + WCD_EVENT_INVALID, + /* events for micbias ON and OFF */ + WCD_EVENT_PRE_MICBIAS_2_OFF, + WCD_EVENT_POST_MICBIAS_2_OFF, + WCD_EVENT_PRE_MICBIAS_2_ON, + WCD_EVENT_POST_MICBIAS_2_ON, + /* events for PA ON and OFF */ + WCD_EVENT_PRE_HPHL_PA_ON, + WCD_EVENT_POST_HPHL_PA_OFF, + WCD_EVENT_PRE_HPHR_PA_ON, + WCD_EVENT_POST_HPHR_PA_OFF, + WCD_EVENT_LAST, +}; + +enum { + ON_DEMAND_MICBIAS = 0, + ON_DEMAND_SUPPLIES_MAX, +}; + +/* + * The delay list is per codec HW specification. + * Please add delay in the list in the future instead + * of magic number + */ +enum { + CODEC_DELAY_1_MS = 1000, + CODEC_DELAY_1_1_MS = 1100, +}; +#if 0 +struct msm8x16_wcd_regulator { + const char *name; + int min_uv; + int max_uv; + int optimum_ua; + bool ondemand; + struct regulator *regulator; +}; + +struct msm8916_asoc_mach_data { + int codec_type; + int ext_pa; + int us_euro_gpio; + int mclk_freq; + int lb_mode; + atomic_t mclk_rsc_ref; + atomic_t mclk_enabled; + struct mutex cdc_mclk_mutex; + struct delayed_work disable_mclk_work; + struct afe_digital_clk_cfg digital_cdc_clk; +}; + +struct msm8x16_wcd_pdata { + int irq; + int irq_base; + int num_irqs; + int reset_gpio; + void *msm8x16_wcd_ahb_base_vaddr; + struct wcd9xxx_micbias_setting micbias; + struct msm8x16_wcd_regulator regulator[MAX_REGULATOR]; + u32 mclk_rate; +}; + +enum msm8x16_wcd_micbias_num { + MSM8X16_WCD_MICBIAS1 = 0, +}; + +struct msm8x16_wcd { + struct device *dev; + struct mutex io_lock; + u8 version; + + int reset_gpio; + int (*read_dev)(struct snd_soc_codec *codec, + unsigned short reg); + int (*write_dev)(struct snd_soc_codec *codec, + unsigned short reg, u8 val); + + u32 num_of_supplies; + struct regulator_bulk_data *supplies; + + u8 idbyte[4]; + + int num_irqs; + u32 mclk_rate; + char __iomem *dig_base; +}; + +struct on_demand_supply { + struct regulator *supply; + atomic_t ref; +}; + +struct msm8x16_wcd_priv { + struct snd_soc_codec *codec; + u16 pmic_rev; + u32 adc_count; + u32 rx_bias_count; + s32 dmic_1_2_clk_cnt; + u32 mute_mask; + bool mclk_enabled; + bool clock_active; + bool config_mode_active; + bool spk_boost_set; + bool ear_pa_boost_set; + bool dec_active[NUM_DECIMATORS]; + struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX]; + /* mbhc module */ + struct wcd_mbhc mbhc; + struct blocking_notifier_head notifier; + +}; + +extern int msm8x16_wcd_mclk_enable(struct snd_soc_codec *codec, int mclk_enable, + bool dapm); + +extern int msm8x16_wcd_hs_detect(struct snd_soc_codec *codec, + struct wcd_mbhc_config *mbhc_cfg); + +extern void msm8x16_wcd_hs_detect_exit(struct snd_soc_codec *codec); + +extern int msm8x16_register_notifier(struct snd_soc_codec *codec, + struct notifier_block *nblock); + +extern int msm8x16_unregister_notifier(struct snd_soc_codec *codec, + struct notifier_block *nblock); +#endif +#endif + diff --git a/sound/soc/codecs/msm8x16_wcd_registers.h b/sound/soc/codecs/msm8x16_wcd_registers.h new file mode 100644 index 000000000000..03d92c844e49 --- /dev/null +++ b/sound/soc/codecs/msm8x16_wcd_registers.h @@ -0,0 +1,518 @@ + /* Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef MSM8X16_WCD_REGISTERS_H +#define MSM8X16_WCD_REGISTERS_H + +#define MSM8X16_WCD_A_DIGITAL_REVISION1 (0x000) +#define MSM8X16_WCD_A_DIGITAL_REVISION1__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_REVISION2 (0x001) +#define MSM8X16_WCD_A_DIGITAL_REVISION2__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_PERPH_TYPE (0x004) +#define MSM8X16_WCD_A_DIGITAL_PERPH_TYPE__POR (0x23) +#define MSM8X16_WCD_A_DIGITAL_PERPH_SUBTYPE (0x005) +#define MSM8X16_WCD_A_DIGITAL_PERPH_SUBTYPE__POR (0x01) +#define MSM8X16_WCD_A_DIGITAL_INT_RT_STS (0x010) +#define MSM8X16_WCD_A_DIGITAL_INT_RT_STS__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_INT_SET_TYPE (0x011) +#define MSM8X16_WCD_A_DIGITAL_INT_SET_TYPE__POR (0xFF) +#define MSM8X16_WCD_A_DIGITAL_INT_POLARITY_HIGH (0x012) +#define MSM8X16_WCD_A_DIGITAL_INT_POLARITY_HIGH__POR (0xFF) +#define MSM8X16_WCD_A_DIGITAL_INT_POLARITY_LOW (0x013) +#define MSM8X16_WCD_A_DIGITAL_INT_POLARITY_LOW__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_INT_LATCHED_CLR (0x014) +#define MSM8X16_WCD_A_DIGITAL_INT_LATCHED_CLR__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_INT_EN_SET (0x015) +#define MSM8X16_WCD_A_DIGITAL_INT_EN_SET__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_INT_EN_CLR (0x016) +#define MSM8X16_WCD_A_DIGITAL_INT_EN_CLR__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_INT_LATCHED_STS (0x018) +#define MSM8X16_WCD_A_DIGITAL_INT_LATCHED_STS__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_INT_PENDING_STS (0x019) +#define MSM8X16_WCD_A_DIGITAL_INT_PENDING_STS__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_INT_MID_SEL (0x01A) +#define MSM8X16_WCD_A_DIGITAL_INT_MID_SEL__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_INT_PRIORITY (0x01B) +#define MSM8X16_WCD_A_DIGITAL_INT_PRIORITY__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_GPIO_MODE (0x040) +#define MSM8X16_WCD_A_DIGITAL_GPIO_MODE__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_PIN_CTL_OE (0x041) +#define MSM8X16_WCD_A_DIGITAL_PIN_CTL_OE__POR (0x01) +#define MSM8X16_WCD_A_DIGITAL_PIN_CTL_DATA (0x042) +#define MSM8X16_WCD_A_DIGITAL_PIN_CTL_DATA__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_PIN_STATUS (0x043) +#define MSM8X16_WCD_A_DIGITAL_PIN_STATUS__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_HDRIVE_CTL (0x044) +#define MSM8X16_WCD_A_DIGITAL_HDRIVE_CTL__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_CDC_RST_CTL (0x046) +#define MSM8X16_WCD_A_DIGITAL_CDC_RST_CTL__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_CDC_TOP_CLK_CTL (0x048) +#define MSM8X16_WCD_A_DIGITAL_CDC_TOP_CLK_CTL__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL (0x049) +#define MSM8X16_WCD_A_DIGITAL_CDC_ANA_CLK_CTL__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL (0x04A) +#define MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX1_CTL (0x050) +#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX1_CTL__POR (0x02) +#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX2_CTL (0x051) +#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_TX2_CTL__POR (0x02) +#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_HPHR_DAC_CTL (0x052) +#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_HPHR_DAC_CTL__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX1_CTL (0x053) +#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX1_CTL__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX2_CTL (0x054) +#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX2_CTL__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX3_CTL (0x055) +#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX3_CTL__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX_LB_CTL (0x056) +#define MSM8X16_WCD_A_DIGITAL_CDC_CONN_RX_LB_CTL__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL1 (0x058) +#define MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL1__POR (0x7C) +#define MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL2 (0x059) +#define MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL2__POR (0x7C) +#define MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL3 (0x05A) +#define MSM8X16_WCD_A_DIGITAL_CDC_RX_CTL3__POR (0x7C) +#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA0 (0x05B) +#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA0__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA1 (0x05C) +#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA1__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA2 (0x05D) +#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA2__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA3 (0x05E) +#define MSM8X16_WCD_A_DIGITAL_DEM_BYPASS_DATA3__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_DIG_DEBUG_CTL (0x068) +#define MSM8X16_WCD_A_DIGITAL_DIG_DEBUG_CTL__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_DIG_DEBUG_EN (0x069) +#define MSM8X16_WCD_A_DIGITAL_DIG_DEBUG_EN__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_SPARE_0 (0x070) +#define MSM8X16_WCD_A_DIGITAL_SPARE_0__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_SPARE_1 (0x071) +#define MSM8X16_WCD_A_DIGITAL_SPARE_1__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_SPARE_2 (0x072) +#define MSM8X16_WCD_A_DIGITAL_SPARE_2__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_SEC_ACCESS (0x0D0) +#define MSM8X16_WCD_A_DIGITAL_SEC_ACCESS__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL1 (0x0D8) +#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL1__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL2 (0x0D9) +#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL2__POR (0x01) +#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL3 (0x0DA) +#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL3__POR (0x05) +#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL4 (0x0DB) +#define MSM8X16_WCD_A_DIGITAL_PERPH_RESET_CTL4__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_INT_TEST1 (0x0E0) +#define MSM8X16_WCD_A_DIGITAL_INT_TEST1__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_INT_TEST_VAL (0x0E1) +#define MSM8X16_WCD_A_DIGITAL_INT_TEST_VAL__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_TRIM_NUM (0x0F0) +#define MSM8X16_WCD_A_DIGITAL_TRIM_NUM__POR (0x00) +#define MSM8X16_WCD_A_DIGITAL_TRIM_CTRL (0x0F1) +#define MSM8X16_WCD_A_DIGITAL_TRIM_CTRL__POR (0x00) + +#define MSM8X16_WCD_A_ANALOG_REVISION1 (0x100) +#define MSM8X16_WCD_A_ANALOG_REVISION1__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_REVISION2 (0x101) +#define MSM8X16_WCD_A_ANALOG_REVISION2__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_REVISION3 (0x102) +#define MSM8X16_WCD_A_ANALOG_REVISION3__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_REVISION4 (0x103) +#define MSM8X16_WCD_A_ANALOG_REVISION4__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_PERPH_TYPE (0x104) +#define MSM8X16_WCD_A_ANALOG_PERPH_TYPE__POR (0x23) +#define MSM8X16_WCD_A_ANALOG_PERPH_SUBTYPE (0x105) +#define MSM8X16_WCD_A_ANALOG_PERPH_SUBTYPE__POR (0x09) +#define MSM8X16_WCD_A_ANALOG_INT_RT_STS (0x110) +#define MSM8X16_WCD_A_ANALOG_INT_RT_STS__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_INT_SET_TYPE (0x111) +#define MSM8X16_WCD_A_ANALOG_INT_SET_TYPE__POR (0x3F) +#define MSM8X16_WCD_A_ANALOG_INT_POLARITY_HIGH (0x112) +#define MSM8X16_WCD_A_ANALOG_INT_POLARITY_HIGH__POR (0x3F) +#define MSM8X16_WCD_A_ANALOG_INT_POLARITY_LOW (0x113) +#define MSM8X16_WCD_A_ANALOG_INT_POLARITY_LOW__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_INT_LATCHED_CLR (0x114) +#define MSM8X16_WCD_A_ANALOG_INT_LATCHED_CLR__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_INT_EN_SET (0x115) +#define MSM8X16_WCD_A_ANALOG_INT_EN_SET__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_INT_EN_CLR (0x116) +#define MSM8X16_WCD_A_ANALOG_INT_EN_CLR__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_INT_LATCHED_STS (0x118) +#define MSM8X16_WCD_A_ANALOG_INT_LATCHED_STS__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_INT_PENDING_STS (0x119) +#define MSM8X16_WCD_A_ANALOG_INT_PENDING_STS__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_INT_MID_SEL (0x11A) +#define MSM8X16_WCD_A_ANALOG_INT_MID_SEL__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_INT_PRIORITY (0x11B) +#define MSM8X16_WCD_A_ANALOG_INT_PRIORITY__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_MICB_1_EN (0x140) +#define MSM8X16_WCD_A_ANALOG_MICB_1_EN__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_MICB_1_VAL (0x141) +#define MSM8X16_WCD_A_ANALOG_MICB_1_VAL__POR (0x20) +#define MSM8X16_WCD_A_ANALOG_MICB_1_CTL (0x142) +#define MSM8X16_WCD_A_ANALOG_MICB_1_CTL__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_MICB_1_INT_RBIAS (0x143) +#define MSM8X16_WCD_A_ANALOG_MICB_1_INT_RBIAS__POR (0x49) +#define MSM8X16_WCD_A_ANALOG_MICB_2_EN (0x144) +#define MSM8X16_WCD_A_ANALOG_MICB_2_EN__POR (0x20) +#define MSM8X16_WCD_A_ANALOG_TX_1_2_ATEST_CTL_2 (0x145) +#define MSM8X16_WCD_A_ANALOG_TX_1_2_ATEST_CTL_2__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_MASTER_BIAS_CTL (0x146) +#define MSM8X16_WCD_A_ANALOG_MASTER_BIAS_CTL__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_1 (0x147) +#define MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_1__POR (0x35) +#define MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2 (0x150) +#define MSM8X16_WCD_A_ANALOG_MBHC_DET_CTL_2__POR (0x08) +#define MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL (0x151) +#define MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_MBHC_DBNC_TIMER (0x152) +#define MSM8X16_WCD_A_ANALOG_MBHC_DBNC_TIMER__POR (0x98) +#define MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL (0x153) +#define MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_MBHC_BTN1_ZDETM_CTL (0x154) +#define MSM8X16_WCD_A_ANALOG_MBHC_BTN1_ZDETM_CTL__POR (0x20) +#define MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL (0x155) +#define MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL__POR (0x40) +#define MSM8X16_WCD_A_ANALOG_MBHC_BTN3_CTL (0x156) +#define MSM8X16_WCD_A_ANALOG_MBHC_BTN3_CTL__POR (0x61) +#define MSM8X16_WCD_A_ANALOG_MBHC_BTN4_CTL (0x157) +#define MSM8X16_WCD_A_ANALOG_MBHC_BTN4_CTL__POR (0x80) +#define MSM8X16_WCD_A_ANALOG_MBHC_BTN_RESULT (0x158) +#define MSM8X16_WCD_A_ANALOG_MBHC_BTN_RESULT__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT (0x159) +#define MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_TX_1_EN (0x160) +#define MSM8X16_WCD_A_ANALOG_TX_1_EN__POR (0x03) +#define MSM8X16_WCD_A_ANALOG_TX_2_EN (0x161) +#define MSM8X16_WCD_A_ANALOG_TX_2_EN__POR (0x03) +#define MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_1 (0x162) +#define MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_1__POR (0xBF) +#define MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_2 (0x163) +#define MSM8X16_WCD_A_ANALOG_TX_1_2_TEST_CTL_2__POR (0x8C) +#define MSM8X16_WCD_A_ANALOG_TX_1_2_ATEST_CTL (0x164) +#define MSM8X16_WCD_A_ANALOG_TX_1_2_ATEST_CTL__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_TX_1_2_OPAMP_BIAS (0x165) +#define MSM8X16_WCD_A_ANALOG_TX_1_2_OPAMP_BIAS__POR (0x6B) +#define MSM8X16_WCD_A_ANALOG_TX_1_2_TXFE_CLKDIV (0x166) +#define MSM8X16_WCD_A_ANALOG_TX_1_2_TXFE_CLKDIV__POR (0x51) +#define MSM8X16_WCD_A_ANALOG_TX_3_EN (0x167) +#define MSM8X16_WCD_A_ANALOG_TX_3_EN__POR (0x02) +#define MSM8X16_WCD_A_ANALOG_NCP_EN (0x180) +#define MSM8X16_WCD_A_ANALOG_NCP_EN__POR (0x26) +#define MSM8X16_WCD_A_ANALOG_NCP_CLK (0x181) +#define MSM8X16_WCD_A_ANALOG_NCP_CLK__POR (0x23) +#define MSM8X16_WCD_A_ANALOG_NCP_DEGLITCH (0x182) +#define MSM8X16_WCD_A_ANALOG_NCP_DEGLITCH__POR (0x5B) +#define MSM8X16_WCD_A_ANALOG_NCP_FBCTRL (0x183) +#define MSM8X16_WCD_A_ANALOG_NCP_FBCTRL__POR (0x08) +#define MSM8X16_WCD_A_ANALOG_NCP_BIAS (0x184) +#define MSM8X16_WCD_A_ANALOG_NCP_BIAS__POR (0x29) +#define MSM8X16_WCD_A_ANALOG_NCP_VCTRL (0x185) +#define MSM8X16_WCD_A_ANALOG_NCP_VCTRL__POR (0x24) +#define MSM8X16_WCD_A_ANALOG_NCP_TEST (0x186) +#define MSM8X16_WCD_A_ANALOG_NCP_TEST__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_NCP_CLIM_ADDR (0x187) +#define MSM8X16_WCD_A_ANALOG_NCP_CLIM_ADDR__POR (0xD5) +#define MSM8X16_WCD_A_ANALOG_RX_CLOCK_DIVIDER (0x190) +#define MSM8X16_WCD_A_ANALOG_RX_CLOCK_DIVIDER__POR (0xE8) +#define MSM8X16_WCD_A_ANALOG_RX_COM_OCP_CTL (0x191) +#define MSM8X16_WCD_A_ANALOG_RX_COM_OCP_CTL__POR (0xCF) +#define MSM8X16_WCD_A_ANALOG_RX_COM_OCP_COUNT (0x192) +#define MSM8X16_WCD_A_ANALOG_RX_COM_OCP_COUNT__POR (0x6E) +#define MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC (0x193) +#define MSM8X16_WCD_A_ANALOG_RX_COM_BIAS_DAC__POR (0x10) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_PA (0x194) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_PA__POR (0x5A) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_LDO_OCP (0x195) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_LDO_OCP__POR (0x69) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_CNP (0x196) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_BIAS_CNP__POR (0x29) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_EN (0x197) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_EN__POR (0x80) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_CTL (0x198) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_CTL__POR (0xDA) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_TIME (0x199) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_CNP_WG_TIME__POR (0x16) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_L_TEST (0x19A) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_L_TEST__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL (0x19B) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_L_PA_DAC_CTL__POR (0x20) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_R_TEST (0x19C) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_R_TEST__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL (0x19D) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_R_PA_DAC_CTL__POR (0x20) +#define MSM8X16_WCD_A_ANALOG_RX_EAR_CTL (0x19E) +#define MSM8X16_WCD_A_ANALOG_RX_EAR_CTL___POR (0x12) +#define MSM8X16_WCD_A_ANALOG_RX_ATEST (0x19F) +#define MSM8X16_WCD_A_ANALOG_RX_ATEST__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_STATUS (0x1A0) +#define MSM8X16_WCD_A_ANALOG_RX_HPH_STATUS__POR (0x0C) +#define MSM8X16_WCD_A_ANALOG_RX_EAR_STATUS (0x1A1) +#define MSM8X16_WCD_A_ANALOG_RX_EAR_STATUS__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL (0x1B0) +#define MSM8X16_WCD_A_ANALOG_SPKR_DAC_CTL__POR (0x83) +#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_CLIP_DET (0x1B1) +#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_CLIP_DET__POR (0x91) +#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL (0x1B2) +#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_CTL__POR (0x29) +#define MSM8X16_WCD_A_ANALOG_SPKR_ANA_BIAS_SET (0x1B3) +#define MSM8X16_WCD_A_ANALOG_SPKR_ANA_BIAS_SET__POR (0x4D) +#define MSM8X16_WCD_A_ANALOG_SPKR_OCP_CTL (0x1B4) +#define MSM8X16_WCD_A_ANALOG_SPKR_OCP_CTL__POR (0xE1) +#define MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL (0x1B5) +#define MSM8X16_WCD_A_ANALOG_SPKR_PWRSTG_CTL__POR (0x1E) +#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_MISC (0x1B6) +#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_MISC__POR (0xCB) +#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_DBG (0x1B7) +#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_DBG__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT (0x1C0) +#define MSM8X16_WCD_A_ANALOG_CURRENT_LIMIT__POR (0x02) +#define MSM8X16_WCD_A_ANALOG_OUTPUT_VOLTAGE (0x1C1) +#define MSM8X16_WCD_A_ANALOG_OUTPUT_VOLTAGE__POR (0x14) +#define MSM8X16_WCD_A_ANALOG_BYPASS_MODE (0x1C2) +#define MSM8X16_WCD_A_ANALOG_BYPASS_MODE__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL (0x1C3) +#define MSM8X16_WCD_A_ANALOG_BOOST_EN_CTL__POR (0x1F) +#define MSM8X16_WCD_A_ANALOG_SLOPE_COMP_IP_ZERO (0x1C4) +#define MSM8X16_WCD_A_ANALOG_SLOPE_COMP_IP_ZERO__POR (0x8C) +#define MSM8X16_WCD_A_ANALOG_RDSON_MAX_DUTY_CYCLE (0x1C5) +#define MSM8X16_WCD_A_ANALOG_RDSON_MAX_DUTY_CYCLE__POR (0xC0) +#define MSM8X16_WCD_A_ANALOG_BOOST_TEST1_1 (0x1C6) +#define MSM8X16_WCD_A_ANALOG_BOOST_TEST1_1__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_BOOST_TEST_2 (0x1C7) +#define MSM8X16_WCD_A_ANALOG_BOOST_TEST_2__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_SPKR_SAR_STATUS (0x1C8) +#define MSM8X16_WCD_A_ANALOG_SPKR_SAR_STATUS__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_STATUS (0x1C9) +#define MSM8X16_WCD_A_ANALOG_SPKR_DRV_STATUS__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_PBUS_ADD_CSR (0x1CE) +#define MSM8X16_WCD_A_ANALOG_PBUS_ADD_CSR__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_PBUS_ADD_SEL (0x1CF) +#define MSM8X16_WCD_A_ANALOG_PBUS_ADD_SEL__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_SEC_ACCESS (0x1D0) +#define MSM8X16_WCD_A_ANALOG_SEC_ACCESS__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL1 (0x1D8) +#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL1__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL2 (0x1D9) +#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL2__POR (0x01) +#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL3 (0x1DA) +#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL3__POR (0x05) +#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL4 (0x1DB) +#define MSM8X16_WCD_A_ANALOG_PERPH_RESET_CTL4__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_INT_TEST1 (0x1E0) +#define MSM8X16_WCD_A_ANALOG_INT_TEST1__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_INT_TEST_VAL (0x1E1) +#define MSM8X16_WCD_A_ANALOG_INT_TEST_VAL__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_TRIM_NUM (0x1F0) +#define MSM8X16_WCD_A_ANALOG_TRIM_NUM__POR (0x04) +#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL1 (0x1F1) +#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL1__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL2 (0x1F2) +#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL2__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL3 (0x1F3) +#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL3__POR (0x00) +#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL4 (0x1F4) +#define MSM8X16_WCD_A_ANALOG_TRIM_CTRL4__POR (0x00) + +/* Digital part */ +#define MSM8X16_WCD_A_CDC_CLK_RX_RESET_CTL (0x200) +#define MSM8X16_WCD_A_CDC_CLK_RX_RESET_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CLK_TX_RESET_B1_CTL (0x204) +#define MSM8X16_WCD_A_CDC_CLK_TX_RESET_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CLK_DMIC_B1_CTL (0x208) +#define MSM8X16_WCD_A_CDC_CLK_DMIC_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL (0x20C) +#define MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL__POR (0x13) +#define MSM8X16_WCD_A_CDC_CLK_TX_I2S_CTL (0x210) +#define MSM8X16_WCD_A_CDC_CLK_TX_I2S_CTL__POR (0x13) +#define MSM8X16_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL (0x214) +#define MSM8X16_WCD_A_CDC_CLK_OTHR_RESET_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL (0x218) +#define MSM8X16_WCD_A_CDC_CLK_TX_CLK_EN_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CLK_OTHR_CTL (0x21C) +#define MSM8X16_WCD_A_CDC_CLK_OTHR_CTL__POR (0x04) +#define MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL (0x220) +#define MSM8X16_WCD_A_CDC_CLK_RX_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CLK_MCLK_CTL (0x224) +#define MSM8X16_WCD_A_CDC_CLK_MCLK_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CLK_PDM_CTL (0x228) +#define MSM8X16_WCD_A_CDC_CLK_PDM_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CLK_SD_CTL (0x22C) +#define MSM8X16_WCD_A_CDC_CLK_SD_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX1_B1_CTL (0x240) +#define MSM8X16_WCD_A_CDC_RX1_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX2_B1_CTL (0x260) +#define MSM8X16_WCD_A_CDC_RX2_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX3_B1_CTL (0x280) +#define MSM8X16_WCD_A_CDC_RX3_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX1_B2_CTL (0x244) +#define MSM8X16_WCD_A_CDC_RX1_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX2_B2_CTL (0x264) +#define MSM8X16_WCD_A_CDC_RX2_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX3_B2_CTL (0x284) +#define MSM8X16_WCD_A_CDC_RX3_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX1_B3_CTL (0x248) +#define MSM8X16_WCD_A_CDC_RX1_B3_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX2_B3_CTL (0x268) +#define MSM8X16_WCD_A_CDC_RX2_B3_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX3_B3_CTL (0x288) +#define MSM8X16_WCD_A_CDC_RX3_B3_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX1_B4_CTL (0x24C) +#define MSM8X16_WCD_A_CDC_RX1_B4_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX2_B4_CTL (0x26C) +#define MSM8X16_WCD_A_CDC_RX2_B4_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX3_B4_CTL (0x28C) +#define MSM8X16_WCD_A_CDC_RX3_B4_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX1_B5_CTL (0x250) +#define MSM8X16_WCD_A_CDC_RX1_B5_CTL__POR (0x68) +#define MSM8X16_WCD_A_CDC_RX2_B5_CTL (0x270) +#define MSM8X16_WCD_A_CDC_RX2_B5_CTL__POR (0x68) +#define MSM8X16_WCD_A_CDC_RX3_B5_CTL (0x290) +#define MSM8X16_WCD_A_CDC_RX3_B5_CTL__POR (0x68) +#define MSM8X16_WCD_A_CDC_RX1_B6_CTL (0x254) +#define MSM8X16_WCD_A_CDC_RX1_B6_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX2_B6_CTL (0x274) +#define MSM8X16_WCD_A_CDC_RX2_B6_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX3_B6_CTL (0x294) +#define MSM8X16_WCD_A_CDC_RX3_B6_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B1_CTL (0x258) +#define MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B1_CTL (0x278) +#define MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B1_CTL (0x298) +#define MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL (0x25C) +#define MSM8X16_WCD_A_CDC_RX1_VOL_CTL_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B2_CTL (0x27C) +#define MSM8X16_WCD_A_CDC_RX2_VOL_CTL_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B2_CTL (0x29C) +#define MSM8X16_WCD_A_CDC_RX3_VOL_CTL_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_TOP_GAIN_UPDATE (0x2A0) +#define MSM8X16_WCD_A_CDC_TOP_GAIN_UPDATE__POR (0x00) +#define MSM8X16_WCD_A_CDC_TOP_CTL (0x2A4) +#define MSM8X16_WCD_A_CDC_TOP_CTL__POR (0x01) +#define MSM8X16_WCD_A_CDC_DEBUG_DESER1_CTL (0x2E0) +#define MSM8X16_WCD_A_CDC_DEBUG_DESER1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_DEBUG_DESER2_CTL (0x2E4) +#define MSM8X16_WCD_A_CDC_DEBUG_DESER2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_DEBUG_B1_CTL_CFG (0x2E8) +#define MSM8X16_WCD_A_CDC_DEBUG_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_DEBUG_B2_CTL_CFG (0x2EC) +#define MSM8X16_WCD_A_CDC_DEBUG_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_DEBUG_B3_CTL_CFG (0x2F0) +#define MSM8X16_WCD_A_CDC_DEBUG_B3_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B1_CTL (0x300) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B1_CTL (0x340) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B2_CTL (0x304) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B2_CTL (0x344) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B3_CTL (0x308) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B3_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B3_CTL (0x348) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B3_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B4_CTL (0x30C) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B4_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B4_CTL (0x34C) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B4_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B5_CTL (0x310) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B5_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B5_CTL (0x350) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B5_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B6_CTL (0x314) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B6_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B6_CTL (0x354) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B6_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B7_CTL (0x318) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B7_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B7_CTL (0x358) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B7_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B8_CTL (0x31C) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_B8_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B8_CTL (0x35C) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_B8_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR1_CTL (0x320) +#define MSM8X16_WCD_A_CDC_IIR1_CTL__POR (0x40) +#define MSM8X16_WCD_A_CDC_IIR2_CTL (0x360) +#define MSM8X16_WCD_A_CDC_IIR2_CTL__POR (0x40) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_TIMER_CTL (0x324) +#define MSM8X16_WCD_A_CDC_IIR1_GAIN_TIMER_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_TIMER_CTL (0x364) +#define MSM8X16_WCD_A_CDC_IIR2_GAIN_TIMER_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL (0x328) +#define MSM8X16_WCD_A_CDC_IIR1_COEF_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR2_COEF_B1_CTL (0x368) +#define MSM8X16_WCD_A_CDC_IIR2_COEF_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL (0x32C) +#define MSM8X16_WCD_A_CDC_IIR1_COEF_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_IIR2_COEF_B2_CTL (0x36C) +#define MSM8X16_WCD_A_CDC_IIR2_COEF_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_RX1_B1_CTL (0x380) +#define MSM8X16_WCD_A_CDC_CONN_RX1_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_RX1_B2_CTL (0x384) +#define MSM8X16_WCD_A_CDC_CONN_RX1_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_RX1_B3_CTL (0x388) +#define MSM8X16_WCD_A_CDC_CONN_RX1_B3_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL (0x38C) +#define MSM8X16_WCD_A_CDC_CONN_RX2_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_RX2_B2_CTL (0x390) +#define MSM8X16_WCD_A_CDC_CONN_RX2_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_RX2_B3_CTL (0x394) +#define MSM8X16_WCD_A_CDC_CONN_RX2_B3_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL (0x398) +#define MSM8X16_WCD_A_CDC_CONN_RX3_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_RX3_B2_CTL (0x39C) +#define MSM8X16_WCD_A_CDC_CONN_RX3_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_TX_B1_CTL (0x3A0) +#define MSM8X16_WCD_A_CDC_CONN_TX_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_EQ1_B1_CTL (0x3A8) +#define MSM8X16_WCD_A_CDC_CONN_EQ1_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_EQ1_B2_CTL (0x3AC) +#define MSM8X16_WCD_A_CDC_CONN_EQ1_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_EQ1_B3_CTL (0x3B0) +#define MSM8X16_WCD_A_CDC_CONN_EQ1_B3_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_EQ1_B4_CTL (0x3B4) +#define MSM8X16_WCD_A_CDC_CONN_EQ1_B4_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_EQ2_B1_CTL (0x3B8) +#define MSM8X16_WCD_A_CDC_CONN_EQ2_B1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_EQ2_B2_CTL (0x3BC) +#define MSM8X16_WCD_A_CDC_CONN_EQ2_B2_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_EQ2_B3_CTL (0x3C0) +#define MSM8X16_WCD_A_CDC_CONN_EQ2_B3_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_EQ2_B4_CTL (0x3C4) +#define MSM8X16_WCD_A_CDC_CONN_EQ2_B4_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_CONN_TX_I2S_SD1_CTL (0x3C8) +#define MSM8X16_WCD_A_CDC_CONN_TX_I2S_SD1_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_TX1_VOL_CTL_TIMER (0x480) +#define MSM8X16_WCD_A_CDC_TX1_VOL_CTL_TIMER__POR (0x00) +#define MSM8X16_WCD_A_CDC_TX2_VOL_CTL_TIMER (0x4A0) +#define MSM8X16_WCD_A_CDC_TX2_VOL_CTL_TIMER__POR (0x00) +#define MSM8X16_WCD_A_CDC_TX1_VOL_CTL_GAIN (0x484) +#define MSM8X16_WCD_A_CDC_TX1_VOL_CTL_GAIN__POR (0x00) +#define MSM8X16_WCD_A_CDC_TX2_VOL_CTL_GAIN (0x4A4) +#define MSM8X16_WCD_A_CDC_TX2_VOL_CTL_GAIN__POR (0x00) +#define MSM8X16_WCD_A_CDC_TX1_VOL_CTL_CFG (0x488) +#define MSM8X16_WCD_A_CDC_TX1_VOL_CTL_CFG__POR (0x00) +#define MSM8X16_WCD_A_CDC_TX2_VOL_CTL_CFG (0x4A8) +#define MSM8X16_WCD_A_CDC_TX2_VOL_CTL_CFG__POR (0x00) +#define MSM8X16_WCD_A_CDC_TX1_MUX_CTL (0x48C) +#define MSM8X16_WCD_A_CDC_TX1_MUX_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_TX2_MUX_CTL (0x4AC) +#define MSM8X16_WCD_A_CDC_TX2_MUX_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_TX1_CLK_FS_CTL (0x490) +#define MSM8X16_WCD_A_CDC_TX1_CLK_FS_CTL__POR (0x03) +#define MSM8X16_WCD_A_CDC_TX2_CLK_FS_CTL (0x4B0) +#define MSM8X16_WCD_A_CDC_TX2_CLK_FS_CTL__POR (0x03) +#define MSM8X16_WCD_A_CDC_TX1_DMIC_CTL (0x494) +#define MSM8X16_WCD_A_CDC_TX1_DMIC_CTL__POR (0x00) +#define MSM8X16_WCD_A_CDC_TX2_DMIC_CTL (0x4B4) +#define MSM8X16_WCD_A_CDC_TX2_DMIC_CTL__POR (0x00) +#endif -- cgit v1.2.3 From 14764562f3e56b0c47cd805d3eaaff9455495cf3 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 11 Mar 2015 15:51:19 -0500 Subject: devicetree: bindings: Document qcom,msm-id and qcom,board-id The top level qcom,msm-id and qcom,board-id are utilized by bootloaders on Qualcomm MSM platforms to determine which device tree should be utilized and passed to the kernel. Cc: Signed-off-by: Kumar Gala --- Documentation/devicetree/bindings/arm/msm/ids.txt | 65 +++++++++++++++++++++++ include/dt-bindings/arm/qcom-ids.h | 33 ++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/msm/ids.txt create mode 100644 include/dt-bindings/arm/qcom-ids.h diff --git a/Documentation/devicetree/bindings/arm/msm/ids.txt b/Documentation/devicetree/bindings/arm/msm/ids.txt new file mode 100644 index 000000000000..9ee8428f4670 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/msm/ids.txt @@ -0,0 +1,65 @@ +* MSM-ID + +The qcom,msm-id entry specifies the MSM chipset and hardware revision. It can +optionally be an array of these to indicate multiple hardware that use the same +device tree. It is expected that the bootloader will use this information at +boot-up to decide which device tree to use when given multiple device trees, +some of which may not be compatible with the actual hardware. It is the +bootloader's responsibility to pass the correct device tree to the kernel. + +PROPERTIES + +- qcom,msm-id: + Usage: required + Value type: ( [, ..]) + Definition: + The "chipset_id" consists of three fields as below: + + bits 0-15 = The unique MSM chipset id. + bits 16-31 = Reserved. Should be 0 + + chipset_id is an exact match value + + The "rev_id" is a chipset specific 32-bit id that represents + the version of the chipset. + + The rev_id is a best match id. The bootloader will look for + the closest possible patch. + +* BOARD-ID + +The qcom,board-id entry specifies the board type and revision information. It +can optionally be an array of these to indicate multiple boards that use the +same device tree. It is expected that the bootloader will use this information +at boot-up to decide which device tree to use when given multiple device trees, +some of which may not be compatible with the actual hardware. It is the +bootloader's responsibility to pass the correct device tree to the kernel. + +PROPERTIES + +- qcom,board-id: + Usage: required + Value type: ( [, ..]) + Definition: + The "board_id" consists of three fields as below: + + bits 31-24 = Unusued. + bits 23-16 = Platform Version Major + bits 15-8 = Platfrom Version Minor + bits 7-0 = Platform Type + + Platform Type field is an exact match value. The Platform + Major/Minor field is a best match. The bootloader will look + for the closest possible match. + + The "subtype_id" is unique to a Platform Type/Chipset ID. For + a given Platform Type, there will typically only be a single + board and the subtype_id will be 0. However in some cases board + variants may need to be distinquished by different subtype_id + values. + + subtype_id is an exact match value. + +EXAMPLE: + qcom,board-id = <15 2>; + qcom,msm-id = <0x1007e 0>; diff --git a/include/dt-bindings/arm/qcom-ids.h b/include/dt-bindings/arm/qcom-ids.h new file mode 100644 index 000000000000..a18f34e7d965 --- /dev/null +++ b/include/dt-bindings/arm/qcom-ids.h @@ -0,0 +1,33 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __DT_BINDINGS_QCOM_IDS_H +#define __DT_BINDINGS_QCOM_IDS_H + +/* qcom,msm-id */ +#define QCOM_ID_MSM8916 206 +#define QCOM_ID_APQ8016 247 +#define QCOM_ID_MSM8216 248 +#define QCOM_ID_MSM8116 249 +#define QCOM_ID_MSM8616 250 + +/* qcom,board-id */ +#define QCOM_BRD_ID(a, major, minor) \ + (((major & 0xff) << 16) | ((minor & 0xff) << 8) | QCOM_BRD_ID_##a) + +#define QCOM_BRD_ID_MTP 8 +#define QCOM_BRD_ID_DRAGONBRD 10 +#define QCOM_BRD_ID_SBC 24 + +#define QCOM_BRD_SUBTYPE_DEFAULT 0 +#define QCOM_BRD_SUBTYPE_MTP8916_SMB1360 1 + +#endif -- cgit v1.2.3 From 28a8898c283a5b77a493303a9144afadc62825aa Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 11 Mar 2015 15:51:20 -0500 Subject: arm64: dts: Add Qualcomm MSM8916 & MTP8916 ids Add qcom,msm-id and qcom,board-id to allow bootloader to identify which device tree to boot on the MTP8916 boards. Signed-off-by: Kumar Gala --- arch/arm64/boot/dts/qcom/msm8916-mtp.dts | 3 +++ arch/arm64/boot/dts/qcom/msm8916.dtsi | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916-mtp.dts b/arch/arm64/boot/dts/qcom/msm8916-mtp.dts index fced77f0fd3a..6c68b4ed4de2 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-mtp.dts +++ b/arch/arm64/boot/dts/qcom/msm8916-mtp.dts @@ -13,10 +13,13 @@ /dts-v1/; +#include #include "msm8916-mtp.dtsi" / { model = "Qualcomm Technologies, Inc. MSM 8916 MTP"; compatible = "qcom,msm8916-mtp", "qcom,msm8916-mtp-smb1360", "qcom,msm8916", "qcom,mtp"; + qcom,board-id = , + ; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 5911de008dd5..d369133111f7 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -14,10 +14,15 @@ #include #include #include +#include / { model = "Qualcomm Technologies, Inc. MSM8916"; compatible = "qcom,msm8916"; + qcom,msm-id = , + , + , + ; interrupt-parent = <&intc>; -- cgit v1.2.3 From 11212b4ffd2ed1313261bdd1323ddc7cdb81cbd9 Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Tue, 17 Mar 2015 18:25:32 +0200 Subject: DT: arm64: msm8916-mtp: enable spi3 This enable spi3 on msm8916 mtp board Signed-off-by: Stanimir Varbanov --- arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi index a1aa0b201e92..01d677b3e7a1 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi @@ -32,3 +32,11 @@ }; }; }; + +&blsp_dma { + status = "okay"; +}; + +&blsp_spi3 { + status = "okay"; +}; -- cgit v1.2.3 From 294918441aeaa11c0884f700bc0b69c46d836597 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Tue, 7 Apr 2015 16:19:31 -0500 Subject: arm64: qcom: msm8916: add smem Signed-off-by: Andy Gross --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index d369133111f7..14ba6dd236fc 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -42,6 +42,21 @@ reg = <0 0 0 0>; }; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + stuff: stuff@0x86000000 { /* fill in the gap */ + reg = <0x0 0x86000000 0x0 0x0300000>; + no-map; + }; + smem_mem: smem_region@86300000 { + reg = <0x0 0x86300000 0x0 0x0100000>; + no-map; + }; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -100,6 +115,27 @@ #interrupt-cells = <2>; }; + tcsr_mutex_regs: syscon@1905000 { + compatible = "syscon"; + reg = <0x1905000 0x20000>; + }; + + tcsr_mutex: hwlock { + compatible = "qcom,tcsr-mutex"; + syscon = <&tcsr_mutex_regs 0 0x1000>; + #hwlock-cells = <1>; + }; + + smem { + compatible = "qcom,smem"; + reg = <0x60000 0x8000>; + reg-names = "aux-mem1"; + + memory-region = <&smem_mem>; + + hwlocks = <&tcsr_mutex 3>; + }; + gcc: qcom,gcc@1800000 { compatible = "qcom,gcc-msm8916"; #clock-cells = <1>; -- cgit v1.2.3 From 92d4e5dd46c5d481a7ef94f5d4b1d09dfcac21f4 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Mon, 13 Apr 2015 21:23:49 -0500 Subject: arm64: dt: msm8916: Add SMD and RPM nodes This patch adds the devicetree nodes for SMD and RPM. Signed-off-by: Andy Gross --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 14ba6dd236fc..a4d9feab8976 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -136,6 +136,27 @@ hwlocks = <&tcsr_mutex 3>; }; + + apcs: syscon@b011000 { + compatible = "syscon"; + reg = <0x0b011000 0x1000>; + }; + + smd { + compatible = "qcom,smd"; + + rpm { + interrupts = <0 168 1>; + qcom,ipc = <&apcs 8 0>; + qcom,smd-edge = <15>; + + rpm_requests { + compatible = "qcom,rpm-msm8916"; + qcom,smd-channels = "rpm_requests"; + }; + }; + }; + gcc: qcom,gcc@1800000 { compatible = "qcom,gcc-msm8916"; #clock-cells = <1>; -- cgit v1.2.3 From 0a9509df117e6c2b9f9c775756aadbb218166a37 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Wed, 22 Apr 2015 15:34:36 -0500 Subject: arm64: dt: msm8916: Add PM8916 support This patch adds support for the PM8916 device that is present on the msm8916. Signed-off-by: Andy Gross --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 99 +++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index a4d9feab8976..7ad7da718333 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -153,6 +153,105 @@ rpm_requests { compatible = "qcom,rpm-msm8916"; qcom,smd-channels = "rpm_requests"; + + pm8916-regulators { + compatible = "qcom,rpm-pm8916-regulators"; + + vdd_l1_l2_l3-supply = <&pm8916_s3>; + vdd_l5-supply = <&pm8916_s3>; + vdd_l4_l5_l6-supply = <&pm8916_s4>; + vdd_l7-supply = <&pm8916_s4>; + + pm8916_s1: s1 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1562000>; + }; + pm8916_s2: s2 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1562000>; + }; + pm8916_s3: s3 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1562000>; + }; + pm8916_s4: s4 { + regulator-min-microvolt = <1550000>; + regulator-max-microvolt = <2325000>; + }; + + pm8916_l1: l1 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1525000>; + }; + pm8916_l2: l2 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1525000>; + }; + pm8916_l3: l3 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1525000>; + }; + pm8916_l4: l4 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + pm8916_l5: l5 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + pm8916_l6: l6 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + pm8916_l7: l7 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + pm8916_l8: l8 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + pm8916_l9: l9 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + pm8916_l10: l10 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + pm8916_l11: l11 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + pm8916_l12: l12 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + pm8916_l13: l13 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + pm8916_l14: l14 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + pm8916_l15: l15 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + pm8916_l16: l16 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + pm8916_l17: l17 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + pm8916_l18: l18 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + }; }; }; }; -- cgit v1.2.3 From fa39c277bc21708ecf08c28ef2522e940c9a06d8 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Tue, 31 Mar 2015 14:26:15 -0500 Subject: arm64: dts: qcom: Add APQ8016 SBC support This patch set adds support for the APQ8016 SBC. Signed-off-by: Andy Gross [Srinivas Kandagatla]: rebased on top of kumars original patch Signed-off-by: Srinivas Kandagatla --- arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 3 ++- arch/arm64/boot/dts/qcom/msm8916.dtsi | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts index 825f489a2af7..b0cac5337fcc 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts @@ -12,10 +12,11 @@ */ /dts-v1/; - +#include #include "apq8016-sbc.dtsi" / { model = "Qualcomm Technologies, Inc. APQ 8016 SBC"; compatible = "qcom,apq8016-sbc", "qcom,apq8016", "qcom,sbc"; + qcom,board-id = ; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 7ad7da718333..53894efc787c 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -22,7 +22,9 @@ qcom,msm-id = , , , - ; + , + ; + interrupt-parent = <&intc>; -- cgit v1.2.3 From 34e839e6c6570db597f71ff6780b41304492e60f Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 20 Apr 2015 10:45:38 +0300 Subject: arm64: dts: qcom: Add SPMI PMIC Arbiter node for MSM8916 Add SPMI PMIC Arbiter configuration nodes for MSM8916. Signed-off-by: Ivan T. Ivanov Signed-off-by: Kumar Gala Conflicts: arch/arm64/boot/dts/qcom/msm8916.dtsi --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 53894efc787c..c8b57c716f17 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -553,6 +553,7 @@ interrupt-controller; #interrupt-cells = <4>; }; + }; }; -- cgit v1.2.3 From c548f33b15f2abbd90b67981e78f37bb2ce9369a Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Fri, 3 Apr 2015 15:31:34 +0300 Subject: arm64: dts: qcom: Add USB related device nodes on APQ8016 SBC board Signed-off-by: Ivan T. Ivanov --- arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi | 8 ++++++ arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 32 ++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi index cbeee0bcdf52..fad306607082 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi @@ -9,5 +9,13 @@ function = "gpio"; output-low; }; + + usb_id_default: usb_id_default { + pins = "gpio121"; + function = "gpio"; + drive-strength = <8>; + input-enable; + bias-pull-up; + }; }; }; diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index 66804ffbc6d2..9ad626051c62 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -11,6 +11,7 @@ * GNU General Public License for more details. */ +#include #include "msm8916.dtsi" #include "pm8916.dtsi" #include "apq8016-sbc-soc-pins.dtsi" @@ -84,4 +85,35 @@ }; }; }; + + usb2513 { + compatible = "smsc,usb3503"; + reset-gpios = <&pm8916_gpios 1 GPIO_ACTIVE_LOW>; + initial-mode = <1>; + }; + + usb_id: usb-id { + interrupt-parent = <&msmgpio>; + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&msmgpio 121 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb_id_default>; + }; +}; + + +&usb_dev { + extcon = <&usb_id>, <&usb_id>; + status = "okay"; +}; + +&usb_host { + status = "okay"; }; + +&usb_otg { + extcon = <&usb_id>, <&usb_id>; + dr_mode = "otg"; + status = "okay"; +}; + -- cgit v1.2.3 From 7b8258fabd9c4495baac68cb947d6cd19c4addf0 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Tue, 7 Apr 2015 12:47:01 +0100 Subject: arm64: dts: qcom: Add sdhci support for APQ8016 SBC board Currently it have the same functionality as MTP board. Signed-off-by: Ivan T. Ivanov --- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index 9ad626051c62..f8e83fde574a 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -100,7 +100,44 @@ pinctrl-0 = <&usb_id_default>; }; }; +&blsp_dma { + status = "okay"; +}; + +&blsp_spi3 { + status = "okay"; +}; +&sdhc_1 { + vmmc-supply = <&pm8916_l8>; + vqmmc-supply = <&pm8916_l5>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; + status = "okay"; +}; + +&sdhc_2 { + vmmc-supply = <&pm8916_l11>; + vqmmc-supply = <&pm8916_l12>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; + #address-cells = <0>; + interrupt-parent = <&sdhc_2>; + interrupts = <0 1 2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 125 0 + 1 &intc 0 221 0 + 2 &msmgpio 38 0>; + interrupt-names = "hc_irq", "pwr_irq", "status_irq"; + cd-gpios = <&msmgpio 38 0x1>; + + //status = "okay"; +}; &usb_dev { extcon = <&usb_id>, <&usb_id>; -- cgit v1.2.3 From f13ac30c6376e0173b9ae0297bf8d02180c8e260 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Tue, 14 Apr 2015 18:42:14 +0530 Subject: arm: dts: qcom: Add #power-domain-cells property msm8974 has gcc and mmcc nodes, and apq8084 has a gcc node which implement gdsc powerdomains. Add the #power-domain-cells property to them. Signed-off-by: Rajendra Nayak --- arch/arm/boot/dts/qcom-apq8084.dtsi | 1 + arch/arm/boot/dts/qcom-msm8974.dtsi | 2 ++ 2 files changed, 3 insertions(+) diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi index 0554fbd72c40..fcffecae3e67 100644 --- a/arch/arm/boot/dts/qcom-apq8084.dtsi +++ b/arch/arm/boot/dts/qcom-apq8084.dtsi @@ -221,6 +221,7 @@ compatible = "qcom,gcc-apq8084"; #clock-cells = <1>; #reset-cells = <1>; + #power-domain-cells = <1>; reg = <0xfc400000 0x4000>; }; diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index ab8e57250468..ab8473bbef38 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -228,6 +228,7 @@ compatible = "qcom,gcc-msm8974"; #clock-cells = <1>; #reset-cells = <1>; + #power-domain-cells = <1>; reg = <0xfc400000 0x4000>; }; @@ -240,6 +241,7 @@ compatible = "qcom,mmcc-msm8974"; #clock-cells = <1>; #reset-cells = <1>; + #power-domain-cells = <1>; reg = <0xfd8c0000 0x6000>; }; -- cgit v1.2.3 From 3319acf69c22a133a6d782c151405addf4c5a932 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 27 Feb 2015 16:11:57 -0600 Subject: arm64: dts: Add nodes we need for SMP boot Conflicts: arch/arm64/boot/dts/qcom/msm8916.dtsi --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index c8b57c716f17..b71011e131f2 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -67,27 +67,49 @@ device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x0>; + enable-method = "qcom,arm-cortex-acc"; + qcom,acc = <&acc0>; + next-level-cache = <&L2_0>; + L2_0: l2-cache { + compatible = "arm,arch-cache"; + cache-level = <2>; + power-domain = <&l2ccc_0>; + }; }; CPU1: cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x1>; + enable-method = "qcom,arm-cortex-acc"; + qcom,acc = <&acc1>; + next-level-cache = <&L2_0>; }; CPU2: cpu@2 { device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x2>; + enable-method = "qcom,arm-cortex-acc"; + qcom,acc = <&acc2>; + next-level-cache = <&L2_0>; }; CPU3: cpu@3 { device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x3>; + enable-method = "qcom,arm-cortex-acc"; + qcom,acc = <&acc3>; + next-level-cache = <&L2_0>; }; }; + cpu-pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = ; + }; + timer { compatible = "arm,armv8-timer"; interrupts = , @@ -477,6 +499,11 @@ reg = <0x0b000000 0x1000>, <0x0b002000 0x1000>; }; + l2ccc_0: clock-controller@b011000 { + compatible = "qcom,8916-l2ccc"; + reg = <0x0b011000 0x1000>; + }; + timer@b020000 { #address-cells = <1>; #size-cells = <1>; @@ -554,6 +581,29 @@ #interrupt-cells = <4>; }; + acc0: clock-controller@b088000 { + compatible = "qcom,arm-cortex-acc"; + reg = <0x0b088000 0x1000>, + <0x0b008000 0x1000>; + }; + + acc1: clock-controller@b098000 { + compatible = "qcom,arm-cortex-acc"; + reg = <0x0b098000 0x1000>, + <0x0b008000 0x1000>; + }; + + acc2: clock-controller@b0a8000 { + compatible = "qcom,arm-cortex-acc"; + reg = <0x0b0a8000 0x1000>, + <0x0b008000 0x1000>; + }; + + acc3: clock-controller@b0b8000 { + compatible = "qcom,arm-cortex-acc"; + reg = <0x0b0b8000 0x1000>, + <0x0b008000 0x1000>; + }; }; }; -- cgit v1.2.3 From 9cb0831d000c426cbff995930163a7ad240b2942 Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Thu, 26 Mar 2015 17:41:01 +0200 Subject: ARM: dts: Enable SD card (disable vmcc) Signed-off-by: Georgi Djakov --- arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi index 01d677b3e7a1..a222af32debe 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-mtp.dtsi @@ -40,3 +40,34 @@ &blsp_spi3 { status = "okay"; }; + +&sdhc_1 { + vmmc-supply = <&pm8916_l8>; + vqmmc-supply = <&pm8916_l5>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; + status = "okay"; +}; + +&sdhc_2 { + //vmmc-supply = <&pm8916_l11>; + vqmmc-supply = <&pm8916_l12>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; + #address-cells = <0>; + interrupt-parent = <&sdhc_2>; + interrupts = <0 1 2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 125 0 + 1 &intc 0 221 0 + 2 &msmgpio 38 0>; + interrupt-names = "hc_irq", "pwr_irq", "status_irq"; + cd-gpios = <&msmgpio 38 0x1>; + + status = "okay"; +}; -- cgit v1.2.3 From c0e2b0c5ef9aae4e95d95041fee637fc1797fc21 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Thu, 16 Apr 2015 15:50:34 +0530 Subject: arm64: msm8916 dtsi: Add mdss support Add a DT node for mdss mdp and mdss_dsi and dsi phy. A new dtsi file is created for this. Signed-off-by: Archit Taneja Conflicts: arch/arm64/boot/dts/qcom/msm8916.dtsi --- arch/arm64/boot/dts/qcom/msm8916-mdss.dtsi | 87 ++++++++++++++++++++++++++++++ arch/arm64/boot/dts/qcom/msm8916.dtsi | 1 + 2 files changed, 88 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/msm8916-mdss.dtsi diff --git a/arch/arm64/boot/dts/qcom/msm8916-mdss.dtsi b/arch/arm64/boot/dts/qcom/msm8916-mdss.dtsi new file mode 100644 index 000000000000..25b609e69240 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8916-mdss.dtsi @@ -0,0 +1,87 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + mdss_mdp: qcom,mdss_mdp@1a00000 { + compatible = "qcom,mdss_mdp"; + reg = <0x1a00000 0x90000>, + <0x1ac8000 0x3000>; + reg-names = "mdp_phys", "vbif_phys"; + interrupts = <0 72 0>; + + interrupt-controller; + #interrupt-cells = <1>; + + power-domains = <&gcc MDSS_GDSC>; + + connectors = <&mdss_dsi0>; + + clocks = <&gcc GCC_MDSS_AHB_CLK>, + <&gcc GCC_MDSS_AXI_CLK>, + <&gcc MDP_CLK_SRC>, + <&gcc GCC_MDSS_MDP_CLK>, + <&gcc GCC_MDSS_MDP_CLK>, + <&gcc GCC_MDSS_VSYNC_CLK>; + clock-names = "iface_clk", "bus_clk", "core_clk_src", + "core_clk", "lut_clk", "vsync_clk"; + }; + + mdss_dsi0: qcom,mdss_dsi@1a98000 { + compatible = "qcom,mdss-dsi-ctrl"; + label = "MDSS DSI CTRL->0"; + qcom,dsi-host-index = <0>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x1a98000 0x25c>; + reg-names = "dsi_ctrl"; + + interrupt-parent = <&mdss_mdp>; + interrupts = <4 0>; + + vdda-supply = <&pm8916_l2>; + vdd-supply = <&pm8916_l17>; + vddio-supply = <&pm8916_l6>; + + clocks = <&gcc GCC_MDSS_MDP_CLK>, + <&gcc GCC_MDSS_AHB_CLK>, + <&gcc GCC_MDSS_AXI_CLK>, + <&gcc GCC_MDSS_AHB_CLK>, + <&gcc GCC_MDSS_BYTE0_CLK>, + <&gcc GCC_MDSS_PCLK0_CLK>, + <&gcc GCC_MDSS_ESC0_CLK>, + <&gcc BYTE0_CLK_SRC>, + <&gcc PCLK0_CLK_SRC>; + clock-names = "mdp_core_clk", "iface_clk", "bus_clk", + "core_mmss_clk", "byte_clk", "pixel_clk", + "core_clk", "byte_clk_src", "pixel_clk_src"; + qcom,dsi-phy = <&mdss_dsi_phy0>; + }; + + mdss_dsi_phy0: qcom,mdss_dsi_phy@1a98300 { + compatible = "qcom,dsi-phy-28nm-lp"; + qcom,dsi-phy-index = <0>; + + power-domains = <&gcc MDSS_GDSC>; + + reg-names = "dsi_pll", "dsi_phy", "dsi_phy_regulator"; + reg = <0x1a98300 0xd4>, + <0x1a98500 0x280>, + <0x1a98780 0x30>; + + clocks = <&gcc GCC_MDSS_AHB_CLK>; + clock-names = "iface_clk"; + + vddio-supply = <&pm8916_l6>; + }; +}; + + diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index b71011e131f2..5641d2afe07b 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -284,6 +284,7 @@ compatible = "qcom,gcc-msm8916"; #clock-cells = <1>; #reset-cells = <1>; + #power-domain-cells = <1>; reg = <0x1800000 0x80000>; }; -- cgit v1.2.3 From 3f3b8bd2aba35ce935b4e88bf4e10c178c0d10f3 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Thu, 16 Apr 2015 15:53:07 +0530 Subject: arm64: sb8016: Add ADV7533 bridge in sbc8016 dtsi - Add adv7533 bridge child to mdss_dsi - Add pinmux configs required gpios connected to ADV7533 Signed-off-by: Archit Taneja --- arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi | 48 ++++++++++++++++++++++ arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 35 +++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi index fad306607082..cf6f9c4a4d89 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi @@ -18,4 +18,52 @@ bias-pull-up; }; }; + + adv7533_int_active: adv533_int_active { + pinmux { + function = "gpio"; + pins = "gpio31"; + }; + pinconf { + pins = "gpio31"; + drive-strength = <16>; + bias-disable; + }; + }; + + adv7533_int_suspend: adv7533_int_suspend { + pinmux { + function = "gpio"; + pins = "gpio31"; + }; + pinconf { + pins = "gpio31"; + drive-strength = <2>; + bias-disable; + }; + }; + + adv7533_switch_active: adv7533_switch_active { + pinmux { + function = "gpio"; + pins = "gpio32"; + }; + pinconf { + pins = "gpio32"; + drive-strength = <16>; + bias-disable; + }; + }; + + adv7533_switch_suspend: adv7533_switch_suspend { + pinmux { + function = "gpio"; + pins = "gpio32"; + }; + pinconf { + pins = "gpio32"; + drive-strength = <2>; + bias-disable; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index f8e83fde574a..9eb249c18cba 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -16,7 +16,7 @@ #include "pm8916.dtsi" #include "apq8016-sbc-soc-pins.dtsi" #include "apq8016-sbc-pmic-pins.dtsi" - +#include "msm8916-mdss.dtsi" / { aliases { serial0 = &blsp1_uart2; @@ -154,3 +154,36 @@ status = "okay"; }; +&blsp_i2c4 { + status = "ok"; + + bridge@39 { + status = "ok"; + compatible = "adi,adv7533"; + reg = <0x39>; + interrupt-parent = <&msmgpio>; + //interrupts = <31 2>; + adi,dsi-lanes = <4>; + pd-gpios = <&msmgpio 32 0>; + pinctrl-names = "default","sleep"; + pinctrl-0 = <&adv7533_int_active &adv7533_switch_active>; + pinctrl-1 = <&adv7533_int_suspend &adv7533_switch_suspend>; + + port { + adv_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + + }; +}; + +&mdss_dsi0 { + status = "ok"; + + port { + dsi_out: endpoint { + remote-endpoint = <&adv_in>; + }; + }; +}; \ No newline at end of file -- cgit v1.2.3 From 9263f7dbbbbe05e6bf7ba87f991455fd15cbfd59 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 6 May 2015 09:57:34 +0100 Subject: arm64: dts: Add apq8016-sbc hdmi audio support This patch adds hdmi audio support to apq8016-sbc board. Signed-off-by: Srinivas Kandagatla Conflicts: arch/arm64/boot/dts/qcom/msm8916.dtsi --- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 42 +++++- arch/arm64/boot/dts/qcom/msm8916-pins.dtsi | 216 +++++++++++++++++++++++++++++ arch/arm64/boot/dts/qcom/msm8916.dtsi | 36 +++++ 3 files changed, 293 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index 9eb249c18cba..f704273b74b8 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -12,6 +12,7 @@ */ #include +#include #include "msm8916.dtsi" #include "pm8916.dtsi" #include "apq8016-sbc-soc-pins.dtsi" @@ -157,7 +158,7 @@ &blsp_i2c4 { status = "ok"; - bridge@39 { + adv_bridge: bridge@39 { status = "ok"; compatible = "adi,adv7533"; reg = <0x39>; @@ -168,6 +169,7 @@ pinctrl-names = "default","sleep"; pinctrl-0 = <&adv7533_int_active &adv7533_switch_active>; pinctrl-1 = <&adv7533_int_suspend &adv7533_switch_suspend>; + #sound-dai-cells = <0>; port { adv_in: endpoint { @@ -186,4 +188,42 @@ remote-endpoint = <&adv_in>; }; }; +}; + +&lpass { + status = "okay"; +}; + /* + Internal Codec + playback - Primary MI2S + capture - Ter MI2S + + External Primary: + playback - secondary MI2S + capture - Quat MI2S + + External Secondary: + playback - Quat MI2S + capture - Quat MI2S + + */ +&sound { + status = "okay"; + pinctrl-0 = <&cdc_pdm_lines_act &ext_sec_tlmm_lines_act &ext_mclk_tlmm_lines_act>; + pinctrl-1 = <&cdc_pdm_lines_sus &ext_sec_tlmm_lines_sus &ext_mclk_tlmm_lines_sus>; + pinctrl-names = "default", "sleep"; + qcom,model = "DB410c"; + + + /* External Primary or External Secondary -ADV7533 HDMI */ + external-dai-link@0 { + link-name = "ADV7533"; + + cpu { /* QUAT */ + sound-dai = <&lpass MI2S_QUATERNARY>; + }; + codec { + sound-dai = <&adv_bridge 0>; + }; + }; }; \ No newline at end of file diff --git a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi index 568956859088..3a89f55fa98b 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi @@ -427,4 +427,220 @@ }; }; }; + + ext-codec-lines { + ext_codec_lines_act: lines_on { + pinmux { + function = "gpio"; + pins = "gpio67"; + }; + pinconf { + pins = "gpio67"; + drive-strength = <8>; + bias-disable; + output-high; + }; + }; + ext_codec_lines_sus: lines_off { + pinmux { + function = "gpio"; + pins = "gpio67"; + }; + pinconf { + pins = "gpio67"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + cdc-pdm-lines { + cdc_pdm_lines_act: pdm_lines_on { + pinmux { + function = "cdc_pdm0"; + pins = "gpio63", "gpio64", "gpio65", "gpio66", + "gpio67", "gpio68"; + }; + pinconf { + pins = "gpio63", "gpio64", "gpio65", "gpio66", + "gpio67", "gpio68"; + drive-strength = <8>; + bias-pull-none; + }; + }; + cdc_pdm_lines_sus: pdm_lines_off { + pinmux { + function = "cdc_pdm0"; + pins = "gpio63", "gpio64", "gpio65", "gpio66", + "gpio67", "gpio68"; + }; + pinconf { + pins = "gpio63", "gpio64", "gpio65", "gpio66", + "gpio67", "gpio68"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + ext-pri-tlmm-lines { + ext_pri_tlmm_lines_act: ext_pa_on { + pinmux { + function = "pri_mi2s"; + pins = "gpio113", "gpio114", "gpio115", + "gpio116"; + }; + pinconf { + pins = "gpio113", "gpio114", "gpio115", + "gpio116"; + drive-strength = <8>; + bias-pull-none; + }; + }; + + ext_pri_tlmm_lines_sus: ext_pa_off { + pinmux { + function = "pri_mi2s"; + pins = "gpio113", "gpio114", "gpio115", + "gpio116"; + }; + pinconf { + pins = "gpio113", "gpio114", "gpio115", + "gpio116"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + ext-pri-ws-line { + ext_pri_ws_act: ext_pa_on { + pinmux { + function = "pri_mi2s_ws"; + pins = "gpio110"; + }; + pinconf { + pins = "gpio110"; + drive-strength = <8>; + bias-pull-none; + }; + }; + + ext_pri_ws_sus: ext_pa_off { + pinmux { + function = "pri_mi2s_ws"; + pins = "gpio110"; + }; + pinconf { + pins = "gpio110"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + ext-mclk-tlmm-lines { + ext_mclk_tlmm_lines_act: mclk_lines_on { + pinmux { + function = "pri_mi2s"; + pins = "gpio116"; + }; + pinconf { + pins = "gpio116"; + drive-strength = <8>; + bias-pull-none; + }; + }; + ext_mclk_tlmm_lines_sus: mclk_lines_off { + pinmux { + function = "pri_mi2s"; + pins = "gpio116"; + }; + pinconf { + pins = "gpio116"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + /* secondary Mi2S */ + ext-sec-tlmm-lines { + ext_sec_tlmm_lines_act: tlmm_lines_on { + pinmux { + function = "sec_mi2s"; + pins = "gpio112", "gpio117", "gpio118", + "gpio119"; + }; + pinconf { + pins = "gpio112", "gpio117", "gpio118", + "gpio119"; + drive-strength = <8>; + bias-pull-none; + }; + }; + ext_sec_tlmm_lines_sus: tlmm_lines_off { + pinmux { + function = "sec_mi2s"; + pins = "gpio112", "gpio117", "gpio118", + "gpio119"; + }; + pinconf { + pins = "gpio112", "gpio117", "gpio118", + "gpio119"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + cdc-dmic-lines { + cdc_dmic_lines_act: dmic_lines_on { + pinmux_dmic0_clk { + function = "dmic0_clk"; + pins = "gpio0"; + }; + pinmux_dmic0_data { + function = "dmic0_data"; + pins = "gpio1"; + }; + pinconf { + pins = "gpio0", "gpio1"; + drive-strength = <8>; + }; + }; + cdc_dmic_lines_sus: dmic_lines_off { + pinconf { + pins = "gpio0", "gpio1"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + cross-conn-det { + cross_conn_det_act: lines_on { + pinmux { + function = "gpio"; + pins = "gpio120"; + }; + pinconf { + pins = "gpio120"; + drive-strength = <8>; + output-low; + bias-pull-down; + }; + }; + cross_conn_det_sus: lines_off { + pinmux { + function = "gpio"; + pins = "gpio120"; + }; + pinconf { + pins = "gpio120"; + drive-strength = <2>; + bias-disable; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 5641d2afe07b..76bce84cbb26 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -605,6 +605,42 @@ reg = <0x0b0b8000 0x1000>, <0x0b008000 0x1000>; }; + + /* Audio */ + + lpass: lpass-cpu@07700000 { + status = "disabled"; + compatible = "qcom,lpass-cpu-apq8016"; + clocks = <&gcc GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK>, + <&gcc GCC_ULTAUDIO_PCNOC_MPORT_CLK>, + <&gcc GCC_ULTAUDIO_PCNOC_SWAY_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK>; + + clock-names = "ahbix-clk", + "pcnoc-mport-clk", + "pcnoc-sway-clk", + "mi2s-bit-clk0", + "mi2s-bit-clk1", + "mi2s-bit-clk2", + "mi2s-bit-clk3"; + #sound-dai-cells = <1>; + + interrupts = <0 160 0>; + interrupt-names = "lpass-irq-lpaif"; + reg = <0x07708000 0x10000>, <0x07702000 0x4>, <0x07702004 0x4>; + reg-names = "lpass-lpaif", "mic-iomux", "spkr-iomux"; + }; + + sound: sound { + status = "disabled"; + compatible = "qcom,apq8016-sbc-sndcard"; + reg = <0x07702000 0x4>, <0x07702004 0x4>; + reg-names = "mic-iomux", "spkr-iomux"; + }; + }; }; -- cgit v1.2.3 From f4c7bc01c9a319946ac03d4ad64dc78fda733956 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Fri, 8 May 2015 12:26:19 +0300 Subject: arm64: dts: qcom: apq8016-sbc: Don't hog client driver pins Hogging pins from pinctrl driver prevents client drivers to probe. Signed-off-by: Ivan T. Ivanov --- arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi index e03c11d9d834..f64903fa3a05 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi @@ -10,6 +10,14 @@ }; }; + pm8916_gpios_default: default { + usb_hub_reset_pm { + pins = "gpio1"; + function = PMIC_GPIO_FUNC_NORMAL; + output-low; + }; + }; + usb_sw_sel_pm: usb_sw_sel_pm { pinconf { pins = "gpio4"; -- cgit v1.2.3 From 10d05077d28a9cabae3870273c9869dacf87ab64 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Thu, 21 May 2015 09:44:48 +0300 Subject: arm64: dts: qcom: Fix apq8016-sbc board USB related pin definitions USB2513B HUB reset line is connected to PMIC GPIO 3 not to GPIO 1. TC7USB40MU Dual SPDT Switch select input line is connected to PMIC GPIO 4 not to GPIO 2. Fix this. Remove unused LED nodes. Signed-off-by: Ivan T. Ivanov --- arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi | 2 +- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi index f64903fa3a05..26c2cf7940fb 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi @@ -42,7 +42,7 @@ pinconf { pins = "mpp2", "mpp3"; function = PMIC_GPIO_FUNC_NORMAL; - output-low; + input-disable; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index f704273b74b8..3508a5c33673 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -89,7 +89,7 @@ usb2513 { compatible = "smsc,usb3503"; - reset-gpios = <&pm8916_gpios 1 GPIO_ACTIVE_LOW>; + reset-gpios = <&pm8916_gpios 3 GPIO_ACTIVE_LOW>; initial-mode = <1>; }; @@ -226,4 +226,4 @@ sound-dai = <&adv_bridge 0>; }; }; -}; \ No newline at end of file +}; -- cgit v1.2.3 From 341fc45c71cf9e849073f9df629b5d49893344df Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Wed, 20 May 2015 14:49:04 +0300 Subject: arm64: dts: qcom: Add apq8016-sbc board LED's related device nodes APQ8016 SBC board have 6 user controllable LED's. Add following devices: LED1 green LED triggered by system heartbeat. LED2 green LED triggered by access to eMMC device. LED3 green LED triggered by access to SD card. LED4 green LED no trigger assigned. LED5 yellow LED triggered by access to WLAN. LED6 blue LED triggered by access to Bluetooth. Signed-off-by: Ivan T. Ivanov --- .../arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi | 18 ++++++++ arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi | 8 ++++ arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 52 ++++++++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi index 26c2cf7940fb..e745f2ae43da 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi @@ -45,4 +45,22 @@ input-disable; }; }; + + pm8916_gpios_leds_default: pm8916_gpios_leds_default { + pinconf { + pins = "gpio1", "gpio2"; + function = PMIC_GPIO_FUNC_NORMAL; + output-low; + }; + }; +}; + +&pm8916_mpps { + pm8916_mpps_leds_default: pm8916_mpps_leds_default { + pinconf { + pins = "mpp2", "mpp3"; + function = PMIC_GPIO_FUNC_NORMAL; + output-low; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi index cf6f9c4a4d89..1ee5a2d5bae0 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi @@ -19,6 +19,14 @@ }; }; + msm_gpios_leds_default: msm_gpios_leds_default { + pinconf { + pins = "gpio21", "gpio10"; + function = "gpio"; + output-low; + }; + }; + adv7533_int_active: adv533_int_active { pinmux { function = "gpio"; diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index 3508a5c33673..7278b7ec18b3 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -100,6 +100,58 @@ pinctrl-names = "default"; pinctrl-0 = <&usb_id_default>; }; + + leds { + pinctrl-names = "default"; + pinctrl-0 = <&msm_gpios_leds_default>, + <&pm8916_gpios_leds_default>, + <&pm8916_mpps_leds_default>; + + compatible = "gpio-leds"; + + led@1 { + label = "apq8016-sbc:green:user1"; + gpios = <&msmgpio 21 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + default-state = "off"; + }; + + led@2 { + label = "apq8016-sbc:green:user2"; + gpios = <&msmgpio 120 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "mmc0"; + default-state = "off"; + }; + + led@3 { + label = "apq8016-sbc:green:user3"; + gpios = <&pm8916_gpios 1 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "mmc1"; + default-state = "off"; + }; + + led@4 { + label = "apq8016-sbc:green:user4"; + gpios = <&pm8916_gpios 2 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "none"; + default-state = "off"; + }; + + led@5 { + label = "apq8016-sbc:yellow:wlan"; + gpios = <&pm8916_mpps 2 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "wlan"; + default-state = "off"; + }; + + led@6 { + label = "apq8016-sbc:blue:bt"; + gpios = <&pm8916_mpps 3 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "bt"; + default-state = "off"; + }; + }; + }; &blsp_dma { status = "okay"; -- cgit v1.2.3 From 19589608af71b2a81ba23a55fd1be36e0190429c Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Fri, 29 May 2015 15:47:21 +0300 Subject: arm64: dts: qcom: apq8016-sbc: add D+/D- route switch GPIO Signed-off-by: Ivan T. Ivanov --- arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi | 3 ++- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi index e745f2ae43da..102e070948c5 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi @@ -42,7 +42,8 @@ pinconf { pins = "mpp2", "mpp3"; function = PMIC_GPIO_FUNC_NORMAL; - input-disable; + power-source = ; + output-low; // USB device mode }; }; diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index 7278b7ec18b3..bd60192ae911 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -205,6 +205,9 @@ extcon = <&usb_id>, <&usb_id>; dr_mode = "otg"; status = "okay"; + switch-gpio = <&pm8916_gpios 4 GPIO_ACTIVE_HIGH>; // D+/D- lines: 1 - Routed to HUB, 0 - Device + pinctrl-names = "default"; + pinctrl-0 = <&usb_sw_sel_pm>; }; &blsp_i2c4 { -- cgit v1.2.3 From 0dc055b67730e556e3baebebd3f89085926060d1 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Fri, 5 Jun 2015 15:38:47 +0300 Subject: arm64: dts: qcom: apq8016-sbc: Fix sdhci pinctrl default state name Pinctrl framework is using "default" string to find and activate device pin configuration before driver probe method. s/active/default. Signed-off-by: Ivan T. Ivanov --- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index bd60192ae911..d5fc4a6157e0 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -165,7 +165,7 @@ vmmc-supply = <&pm8916_l8>; vqmmc-supply = <&pm8916_l5>; - pinctrl-names = "active", "sleep"; + pinctrl-names = "default", "sleep"; pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; status = "okay"; @@ -175,7 +175,7 @@ vmmc-supply = <&pm8916_l11>; vqmmc-supply = <&pm8916_l12>; - pinctrl-names = "active", "sleep"; + pinctrl-names = "default", "sleep"; pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; #address-cells = <0>; -- cgit v1.2.3 From 4f85fd97b1bc76075663435611da0a20c0057e0f Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 8 Jun 2015 12:57:01 +0300 Subject: arm64: dts: qcom: apq8016-sbc: Enable SD card slot Signed-off-by: Ivan T. Ivanov --- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index d5fc4a6157e0..92325bacd909 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -189,7 +189,7 @@ interrupt-names = "hc_irq", "pwr_irq", "status_irq"; cd-gpios = <&msmgpio 38 0x1>; - //status = "okay"; + status = "okay"; }; &usb_dev { -- cgit v1.2.3 From 144ee4eda0944e442479264835e65ad2137c1976 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Tue, 7 Jul 2015 14:14:39 +0300 Subject: arm64: dts: qcom: Fix MPP's function used for LED control The qcom-spmi-mpp driver is now using string "digital" to denote old "normal" functionality. Update DTS file. Signed-off-by: Ivan T. Ivanov --- arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi index 102e070948c5..181ac9c16460 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi @@ -60,7 +60,7 @@ pm8916_mpps_leds_default: pm8916_mpps_leds_default { pinconf { pins = "mpp2", "mpp3"; - function = PMIC_GPIO_FUNC_NORMAL; + function = "digital"; output-low; }; }; -- cgit v1.2.3 From 3fff3fb5800d4bc2c5c5efd0ffe22dbbbeb4d3cd Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Tue, 7 Jul 2015 16:38:06 +0300 Subject: arm64: dts: qcom: Enable USB manual pullup on msm8916 On msm8916 based chipset vbus is not routed to USB controller/phy and controller driver therefore enables pull-up explicitly before starting controller using usbcmd run/stop bit. Signed-off-by: Ivan T. Ivanov --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 76bce84cbb26..23df1fe3aff8 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -481,6 +481,7 @@ qcom,phy-init-sequence = <0x44 0x6B 0x24 0x13>; dr_mode = "peripheral"; qcom,otg-control = <2>; // PMIC + qcom,manual-pullup; clocks = <&gcc GCC_USB_HS_AHB_CLK>, <&gcc GCC_USB_HS_SYSTEM_CLK>, -- cgit v1.2.3 From 6b5cc9fc896ea1f2d2b2cd0dfa8718d4dbead6d1 Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Wed, 22 Apr 2015 15:22:12 +0300 Subject: arm64: dts: qcom: msm8916: Add RPMCC DT node Add the RPM Clock Controller DT node and include the necessary header file for clocks. Signed-off-by: Georgi Djakov --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 23df1fe3aff8..739e34164a44 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -14,6 +14,7 @@ #include #include #include +#include #include / { @@ -178,6 +179,11 @@ compatible = "qcom,rpm-msm8916"; qcom,smd-channels = "rpm_requests"; + rpmcc: qcom,rpmcc { + compatible = "qcom,rpmcc-msm8916"; + #clock-cells = <1>; + }; + pm8916-regulators { compatible = "qcom,rpm-pm8916-regulators"; -- cgit v1.2.3 From bc11fdf0f3db5eddf6b4c8ff4cb704f5d51ccaf1 Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Wed, 22 Apr 2015 16:56:21 +0300 Subject: arm64: dts: qcom: msm8916: Add A53 DT node Add node for the A53 clocks, so that the driver can probe and register the CPU clocks. Signed-off-by: Georgi Djakov --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 739e34164a44..f5651ecbc51c 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -294,6 +294,13 @@ reg = <0x1800000 0x80000>; }; + a53cc: qcom,a53cc@0b016000 { + compatible = "qcom,clock-a53-msm8916"; + reg = <0x0b016000 0x40>; + #clock-cells = <1>; + qcom,apcs = <&apcs>; + }; + blsp1_uart2: serial@78b0000 { compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; reg = <0x78b0000 0x200>; -- cgit v1.2.3 From aa8277affe6c75683bf55ba10cc7859da2f22071 Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Wed, 20 May 2015 17:32:45 +0300 Subject: arm64: dts: Add cpufreq-dt support for msm8916 Add a reference to the cpu frequency scaling clock. Signed-off-by: Georgi Djakov --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index f5651ecbc51c..8bcd78a9e8f1 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -71,6 +71,7 @@ enable-method = "qcom,arm-cortex-acc"; qcom,acc = <&acc0>; next-level-cache = <&L2_0>; + clocks = <&a53cc 1>; L2_0: l2-cache { compatible = "arm,arch-cache"; cache-level = <2>; @@ -85,6 +86,7 @@ enable-method = "qcom,arm-cortex-acc"; qcom,acc = <&acc1>; next-level-cache = <&L2_0>; + clocks = <&a53cc 1>; }; CPU2: cpu@2 { @@ -94,6 +96,7 @@ enable-method = "qcom,arm-cortex-acc"; qcom,acc = <&acc2>; next-level-cache = <&L2_0>; + clocks = <&a53cc 1>; }; CPU3: cpu@3 { @@ -103,6 +106,7 @@ enable-method = "qcom,arm-cortex-acc"; qcom,acc = <&acc3>; next-level-cache = <&L2_0>; + clocks = <&a53cc 1>; }; }; -- cgit v1.2.3 From 0e4e5b64556e8ebe01415738191bba750ae5ee85 Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Tue, 9 Jun 2015 12:13:39 +0300 Subject: arm64: dts: Add clock-latency for msm8916 Add clock-latency property for msm8916, so that we can use ondemand governor. Signed-off-by: Georgi Djakov --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 8bcd78a9e8f1..c9e13f90b81b 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -72,6 +72,7 @@ qcom,acc = <&acc0>; next-level-cache = <&L2_0>; clocks = <&a53cc 1>; + clock-latency = <200000>; L2_0: l2-cache { compatible = "arm,arch-cache"; cache-level = <2>; @@ -87,6 +88,7 @@ qcom,acc = <&acc1>; next-level-cache = <&L2_0>; clocks = <&a53cc 1>; + clock-latency = <200000>; }; CPU2: cpu@2 { @@ -97,6 +99,7 @@ qcom,acc = <&acc2>; next-level-cache = <&L2_0>; clocks = <&a53cc 1>; + clock-latency = <200000>; }; CPU3: cpu@3 { @@ -107,6 +110,7 @@ qcom,acc = <&acc3>; next-level-cache = <&L2_0>; clocks = <&a53cc 1>; + clock-latency = <200000>; }; }; -- cgit v1.2.3 From 441a3ef3dc295c0a4d9fd5f57c3bad4fbdcc66f5 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 1 Apr 2015 23:07:52 -0700 Subject: arm64: dts: Add CPR DT node for msm8916 Signed-off-by: Georgi Djakov --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index c9e13f90b81b..e09d6013679e 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -663,6 +663,36 @@ reg-names = "mic-iomux", "spkr-iomux"; }; + tcsr: syscon@1937000 { + compatible = "qcom,tcsr-msm8916", "syscon"; + reg = <0x1937000 0x30000>; + }; + + uqfprom: eeprom@58000 { + compatible = "qcom,qfprom-msm8916"; + reg = <0x58000 0x7000>; + }; + + cpr@b018000 { + compatible = "qcom,cpr"; + reg = <0xb018000 0x1000>; + interrupts = <0 15 1>, <0 16 1>, <0 17 1>; + vdd-mx-supply = <&pm8916_l3>; + acc-syscon = <&tcsr>; + eeprom = <&uqfprom>; + + qcom,cpr-ref-clk = <19200>; + qcom,cpr-timer-delay-us = <5000>; + qcom,cpr-timer-cons-up = <0>; + qcom,cpr-timer-cons-down = <2>; + qcom,cpr-up-threshold = <0>; + qcom,cpr-down-threshold = <2>; + qcom,cpr-idle-clocks = <15>; + qcom,cpr-gcnt-us = <1>; + qcom,vdd-apc-step-up-limit = <1>; + qcom,vdd-apc-step-down-limit = <1>; + qcom,cpr-cpus = <&CPU0 &CPU1 &CPU2 &CPU3>; + }; }; }; -- cgit v1.2.3 From 496280cca3114ee00f55c867335081d2486bd408 Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Mon, 1 Jun 2015 12:51:33 +0300 Subject: arm64: dts: Add cpu-supply properties for cpufreq Signed-off-by: Georgi Djakov --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index e09d6013679e..2b01afd24663 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -73,6 +73,7 @@ next-level-cache = <&L2_0>; clocks = <&a53cc 1>; clock-latency = <200000>; + cpu-supply = <&pm8916_s2>; L2_0: l2-cache { compatible = "arm,arch-cache"; cache-level = <2>; @@ -89,6 +90,7 @@ next-level-cache = <&L2_0>; clocks = <&a53cc 1>; clock-latency = <200000>; + cpu-supply = <&pm8916_s2>; }; CPU2: cpu@2 { @@ -100,6 +102,7 @@ next-level-cache = <&L2_0>; clocks = <&a53cc 1>; clock-latency = <200000>; + cpu-supply = <&pm8916_s2>; }; CPU3: cpu@3 { @@ -111,6 +114,7 @@ next-level-cache = <&L2_0>; clocks = <&a53cc 1>; clock-latency = <200000>; + cpu-supply = <&pm8916_s2>; }; }; -- cgit v1.2.3 From 916860036aa4ec2f7a137e19271bc030f2636826 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Wed, 8 Jul 2015 15:17:15 +0530 Subject: arm: dts: msm8974: Add thermal zones, tsens and eeprom nodes Add thermal zones, tsens and eeprom nodes Signed-off-by: Rajendra Nayak --- arch/arm/boot/dts/qcom-msm8974.dtsi | 105 ++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index ab8473bbef38..fe2c5a601d8e 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -86,6 +86,88 @@ }; }; + thermal-zones { + cpu-thermal0 { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 5>; + + trips { + cpu_alert0: trip@0 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit0: trip@1 { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + cpu-thermal1 { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 6>; + + trips { + cpu_alert1: trip@0 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit1: trip@1 { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + cpu-thermal2 { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 7>; + + trips { + cpu_alert2: trip@0 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit2: trip@1 { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + cpu-thermal3 { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 8>; + + trips { + cpu_alert3: trip@0 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit3: trip@1 { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + }; + cpu-pmu { compatible = "qcom,krait-pmu"; interrupts = <1 7 0xf04>; @@ -114,6 +196,29 @@ <0xf9002000 0x1000>; }; + qfprom: qfprom@fc4bc000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "qcom,qfprom"; + reg = <0xfc4bc000 0x1000>; + tsens_calib: calib@d0 { + reg = <0xd0 0x18>; + }; + tsens_backup: backup@440 { + reg = <0x440 0x10>; + }; + }; + + tsens: thermal-sensor@fc4a8000 { + compatible = "qcom,msm8974-tsens"; + reg = <0xfc4a8000 0x2000>; + nvmem-cells = <&tsens_calib>, <&tsens_backup>; + nvmem-cell-names = "calib", "calib_backup"; + qcom,tsens-slopes = <3200 3200 3200 3200 3200 3200 + 3200 3200 3200 3200 3200>; + #thermal-sensor-cells = <1>; + }; + timer@f9020000 { #address-cells = <1>; #size-cells = <1>; -- cgit v1.2.3 From 4ee38eabffe3c1d4856d9dd8224483e0e24d6dbc Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Wed, 8 Jul 2015 15:17:17 +0530 Subject: arm: dts: apq8084: Add thermal zones, tsens and eeprom nodes Add thermal zones, tsens and eeprom nodes Signed-off-by: Rajendra Nayak --- arch/arm/boot/dts/qcom-apq8084.dtsi | 105 ++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi index fcffecae3e67..477173c55d0b 100644 --- a/arch/arm/boot/dts/qcom-apq8084.dtsi +++ b/arch/arm/boot/dts/qcom-apq8084.dtsi @@ -75,6 +75,88 @@ }; }; + thermal-zones { + cpu-thermal0 { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 5>; + + trips { + cpu_alert0: trip@0 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit0: trip@1 { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + cpu-thermal1 { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 6>; + + trips { + cpu_alert1: trip@0 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit1: trip@1 { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + cpu-thermal2 { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 7>; + + trips { + cpu_alert2: trip@0 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit2: trip@1 { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + cpu-thermal3 { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 8>; + + trips { + cpu_alert3: trip@0 { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit3: trip@1 { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + }; + cpu-pmu { compatible = "qcom,krait-pmu"; interrupts = <1 7 0xf04>; @@ -103,6 +185,29 @@ <0xf9002000 0x1000>; }; + qfprom: qfprom@fc4bc000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "qcom,qfprom"; + reg = <0xfc4bc000 0x1000>; + tsens_calib: calib@d0 { + reg = <0xd0 0x18>; + }; + tsens_backup: backup@440 { + reg = <0x440 0x10>; + }; + }; + + tsens: thermal-sensor@fc4a8000 { + compatible = "qcom,msm8974-tsens"; + reg = <0xfc4a8000 0x2000>; + nvmem-cells = <&tsens_calib>, <&tsens_backup>; + nvmem-cell-names = "calib", "calib_backup"; + qcom,tsens-slopes = <3200 3200 3200 3200 3200 3200 + 3200 3200 3200 3200 3200>; + #thermal-sensor-cells = <1>; + }; + timer@f9020000 { #address-cells = <1>; #size-cells = <1>; -- cgit v1.2.3 From f98ccaf024755528ed86d439696b110bb381b1a0 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Wed, 8 Jul 2015 15:17:18 +0530 Subject: arm64: dts: msm8916: Add thermal zones, tsens and eeprom nodes Add thermal zones, tsens and eeprom nodes Signed-off-by: Rajendra Nayak --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 65 +++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 2b01afd24663..60a1266943ba 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -123,6 +123,48 @@ interrupts = ; }; + thermal-zones { + cpu-thermal0 { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 4>; + + trips { + cpu_alert0: trip@0 { + temperature = <100000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit0: trip@1 { + temperature = <125000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + cpu-thermal1 { + polling-delay-passive = <250>; + polling-delay = <1000>; + + thermal-sensors = <&tsens 3>; + + trips { + cpu_alert1: trip@0 { + temperature = <100000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit1: trip@1 { + temperature = <125000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + }; + timer { compatible = "arm,armv8-timer"; interrupts = , @@ -697,6 +739,29 @@ qcom,vdd-apc-step-down-limit = <1>; qcom,cpr-cpus = <&CPU0 &CPU1 &CPU2 &CPU3>; }; + + qfprom: qfprom@5c000 { + compatible = "qcom,qfprom"; + reg = <0x5c000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + tsens_caldata: caldata@d0 { + reg = <0xd0 0x8>; + }; + tsens_calsel: calsel@ec { + reg = <0xec 0x4>; + }; + }; + + tsens: thermal-sensor@4a8000 { + compatible = "qcom,msm8916-tsens"; + reg = <0x4a8000 0x2000>; + nvmem-cells = <&tsens_caldata>, <&tsens_calsel>; + nvmem-cell-names = "calib", "calib_sel"; + qcom,tsens-slopes = <3200 3200 3200 3200 3200>; + qcom,sensor-id = <0 1 2 4 5>; + #thermal-sensor-cells = <1>; + }; }; }; -- cgit v1.2.3 From 983bcffca3d1c190173fd6d1cda078844fca5fe1 Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Thu, 16 Jul 2015 11:52:38 +0300 Subject: arm64: dts: Add spmi-regulator nodes for pm8916 Add the necessary nodes for the pm8916 PMIC regulators. Signed-off-by: Georgi Djakov --- arch/arm64/boot/dts/qcom/pm8916.dtsi | 118 +++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi index b222ece7e3d2..debc74dd8b05 100644 --- a/arch/arm64/boot/dts/qcom/pm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi @@ -95,5 +95,123 @@ reg = <0x1 SPMI_USID>; #address-cells = <1>; #size-cells = <0>; + + regulators { + compatible = "qcom,pm8916-regulators"; + #address-cells = <1>; + #size-cells = <1>; + + s1@1400 { + reg = <0x1400 0x300>; + status = "disabled"; + }; + + pm8916_s2: s2@1700 { + reg = <0x1700 0x300>; + status = "ok"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1350000>; + }; + + s3@1a00 { + reg = <0x1a00 0x300>; + status = "disabled"; + }; + + s4@1d00 { + reg = <0x1d00 0x300>; + status = "disabled"; + }; + + l1@4000 { + reg = <0x4000 0x100>; + status = "disabled"; + }; + + l2@4100 { + reg = <0x4100 0x100>; + status = "disabled"; + }; + + l3@4200 { + reg = <0x4200 0x100>; + status = "disabled"; + }; + + l4@4300 { + reg = <0x4300 0x100>; + status = "disabled"; + }; + + l5@4400 { + reg = <0x4400 0x100>; + status = "disabled"; + }; + + l6@4500 { + reg = <0x4500 0x100>; + status = "disabled"; + }; + + l7@4600 { + reg = <0x4600 0x100>; + status = "disabled"; + }; + + l8@4700 { + reg = <0x4700 0x100>; + status = "disabled"; + }; + + l9@4800 { + reg = <0x4800 0x100>; + status = "disabled"; + }; + + l10@4900 { + reg = <0x4900 0x100>; + status = "disabled"; + }; + + l11@4a00 { + reg = <0x4a00 0x100>; + status = "disabled"; + }; + + l12@4b00 { + reg = <0x4b00 0x100>; + status = "disabled"; + }; + + l13@4c00 { + reg = <0x4c00 0x100>; + status = "disabled"; + }; + + l14@4d00 { + reg = <0x4d00 0x100>; + status = "disabled"; + }; + + l15@4e00 { + reg = <0x4e00 0x100>; + status = "disabled"; + }; + + l16@4f00 { + reg = <0x4f00 0x100>; + status = "disabled"; + }; + + l17@5000 { + reg = <0x5000 0x100>; + status = "disabled"; + }; + + l18@5100 { + reg = <0x5100 0x100>; + status = "disabled"; + }; + }; }; }; -- cgit v1.2.3 From bbe4693ce302f844adeb93cc5f18b08888a86246 Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Thu, 16 Jul 2015 11:53:48 +0300 Subject: arm64: dts: Avoid phandle conflicts. Use pm8916_s2 spmi-regulator instead of rpm for cpu voltages. Signed-off-by: Georgi Djakov --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 60a1266943ba..cf20281061cb 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -250,7 +250,7 @@ regulator-min-microvolt = <375000>; regulator-max-microvolt = <1562000>; }; - pm8916_s2: s2 { + s2 { regulator-min-microvolt = <375000>; regulator-max-microvolt = <1562000>; }; -- cgit v1.2.3 From 46b0c9ddf83cc8b6851cff54856f588929199d8c Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Tue, 2 Jun 2015 11:00:15 +0530 Subject: arm64: dts: msm8916: Add cpu cooling maps Add cpu cooling maps for cpu passive trip points. The cpu cooling device states are mapped to cpufreq based scaling frequencies. Signed-off-by: Rajendra Nayak --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index cf20281061cb..2c4a5d1e0ea1 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -15,6 +15,7 @@ #include #include #include +#include #include / { @@ -74,6 +75,10 @@ clocks = <&a53cc 1>; clock-latency = <200000>; cpu-supply = <&pm8916_s2>; + /* cooling options */ + cooling-min-level = <0>; + cooling-max-level = <7>; + #cooling-cells = <2>; L2_0: l2-cache { compatible = "arm,arch-cache"; cache-level = <2>; @@ -91,6 +96,10 @@ clocks = <&a53cc 1>; clock-latency = <200000>; cpu-supply = <&pm8916_s2>; + /* cooling options */ + cooling-min-level = <0>; + cooling-max-level = <7>; + #cooling-cells = <2>; }; CPU2: cpu@2 { @@ -103,6 +112,10 @@ clocks = <&a53cc 1>; clock-latency = <200000>; cpu-supply = <&pm8916_s2>; + /* cooling options */ + cooling-min-level = <0>; + cooling-max-level = <7>; + #cooling-cells = <2>; }; CPU3: cpu@3 { @@ -115,6 +128,10 @@ clocks = <&a53cc 1>; clock-latency = <200000>; cpu-supply = <&pm8916_s2>; + /* cooling options */ + cooling-min-level = <0>; + cooling-max-level = <7>; + #cooling-cells = <2>; }; }; @@ -132,16 +149,23 @@ trips { cpu_alert0: trip@0 { - temperature = <100000>; + temperature = <75000>; hysteresis = <2000>; type = "passive"; }; cpu_crit0: trip@1 { - temperature = <125000>; + temperature = <95000>; hysteresis = <2000>; type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; cpu-thermal1 { @@ -162,6 +186,13 @@ type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&cpu_alert1>; + cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; }; -- cgit v1.2.3 From 85cb6011851a1bbcffc73613aebdf93dc18b9486 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 6 May 2015 13:16:10 -0400 Subject: WIP: dt: add support for gpu on msm8916/apq8016 --- arch/arm64/boot/dts/qcom/msm8916-mdss.dtsi | 35 ++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916-mdss.dtsi b/arch/arm64/boot/dts/qcom/msm8916-mdss.dtsi index 25b609e69240..95d3d337ae48 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-mdss.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-mdss.dtsi @@ -11,6 +11,40 @@ */ &soc { + gpu: qcom,adreno-3xx@01c00000 { + compatible = "qcom,adreno-3xx"; + #stream-id-cells = <16>; + reg = <0x01c00000 0x20000>; + reg-names = "kgsl_3d0_reg_memory"; + interrupts = <0 33 0>; + interrupt-names = "kgsl_3d0_irq"; + clock-names = + "core_clk", + "iface_clk", + "mem_clk", + "mem_iface_clk", + "alt_mem_iface_clk", + "gfx3d_clk_src"; + clocks = + <&gcc GCC_OXILI_GFX3D_CLK>, + <&gcc GCC_OXILI_AHB_CLK>, + <&gcc GCC_OXILI_GMEM_CLK>, + <&gcc GCC_BIMC_GFX_CLK>, + <&gcc GCC_BIMC_GPU_CLK>, + <&gcc GFX3D_CLK_SRC>; + power-domains = <&gcc OXILI_GDSC>; + qcom,chipid = <0x03000600>; + qcom,gpu-pwrlevels { + compatible = "qcom,gpu-pwrlevels"; + qcom,gpu-pwrlevel@0 { + qcom,gpu-freq = <400000000>; + }; + qcom,gpu-pwrlevel@1 { + qcom,gpu-freq = <19200000>; + }; + }; + }; + mdss_mdp: qcom,mdss_mdp@1a00000 { compatible = "qcom,mdss_mdp"; reg = <0x1a00000 0x90000>, @@ -24,6 +58,7 @@ power-domains = <&gcc MDSS_GDSC>; connectors = <&mdss_dsi0>; + gpus = <&gpu>; clocks = <&gcc GCC_MDSS_AHB_CLK>, <&gcc GCC_MDSS_AXI_CLK>, -- cgit v1.2.3 From 3bdff5ed42ae8dd90d63a0d24fb899d8197d619f Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Tue, 28 Apr 2015 14:07:43 +0300 Subject: DT: arm64: add iommu dtsi files Signed-off-by: Stanimir Varbanov Conflicts: arch/arm64/boot/dts/qcom/msm8916.dtsi --- arch/arm64/boot/dts/qcom/msm-iommu-v2.dtsi | 238 ++++++++++++++++++++++++++++ arch/arm64/boot/dts/qcom/msm8916-iommu.dtsi | 21 +++ arch/arm64/boot/dts/qcom/msm8916.dtsi | 1 + 3 files changed, 260 insertions(+) create mode 100644 arch/arm64/boot/dts/qcom/msm-iommu-v2.dtsi create mode 100644 arch/arm64/boot/dts/qcom/msm8916-iommu.dtsi diff --git a/arch/arm64/boot/dts/qcom/msm-iommu-v2.dtsi b/arch/arm64/boot/dts/qcom/msm-iommu-v2.dtsi new file mode 100644 index 000000000000..6f73eb26aaec --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm-iommu-v2.dtsi @@ -0,0 +1,238 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + gfx_iommu: qcom,iommu@1f00000 { + compatible = "qcom,msm-smmu-v2", "qcom,msm-mmu-500"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0x1f00000 0x10000>; + reg-names = "iommu_base"; + interrupts = <0 43 0>, <0 42 0>; + interrupt-names = "global_cfg_NS_irq", "global_cfg_S_irq"; + label = "gfx_iommu"; + qcom,iommu-secure-id = <18>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_GFX_TCU_CLK>; + clock-names = "iface_clk", "core_clk"; + status = "disabled"; + + qcom,iommu-ctx@1f09000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1f09000 0x1000>; + interrupts = <0 241 0>; + qcom,iommu-ctx-sids = <0>; + label = "gfx3d_user"; + }; + + qcom,iommu-ctx@1f0a000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1f0a000 0x1000>; + interrupts = <0 242 0>; + qcom,iommu-ctx-sids = <1>; + label = "gfx3d_priv"; + }; + }; + + apps_iommu: qcom,iommu@1e00000 { + compatible = "qcom,msm-smmu-v2", "qcom,msm-mmu-500"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = <0x1e00000 0x40000 + 0x1ef0000 0x3000>; + reg-names = "iommu_base", "smmu_local_base"; + interrupts = <0 43 0>, <0 42 0>; + interrupt-names = "global_cfg_NS_irq", "global_cfg_S_irq"; + label = "apps_iommu"; + qcom,iommu-secure-id = <17>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_APSS_TCU_CLK>; + clock-names = "iface_clk", "core_clk"; + qcom,cb-base-offset = <0x20000>; + status = "disabled"; + + qcom,iommu-ctx@1e22000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e22000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x2000>; + label = "jpeg_enc0"; + }; + + qcom,iommu-ctx@1e23000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e23000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x400>; + label = "vfe"; + }; + + qcom,iommu-ctx@1e24000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e24000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0xc00>; + label = "mdp_0"; + }; + + venus_ns: qcom,iommu-ctx@1e25000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e25000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x800 0x801 0x802 0x803 + 0x804 0x805 0x807>; + label = "venus_ns"; + }; + + qcom,iommu-ctx@1e26000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e26000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x402>; + label = "cpp"; + }; + + qcom,iommu-ctx@1e27000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e27000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1000>; + label = "mDSP"; + }; + + qcom,iommu-ctx@1e28000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e28000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1400>; + label = "gss"; + }; + + qcom,iommu-ctx@1e29000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e29000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1800>; + label = "a2"; + }; + + qcom,iommu-ctx@1e32000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e32000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0xc01>; + label = "mdp_1"; + }; + + venus_sec_pixel: qcom,iommu-ctx@1e33000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e33000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x885>; + label = "venus_sec_pixel"; + }; + + venus_sec_bitstream: qcom,iommu-ctx@1e34000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e34000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x880 0x881 0x882 0x883 0x884>; + label = "venus_sec_bitstream"; + }; + + venus_sec_non_pixel: qcom,iommu-ctx@1e35000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e35000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x887 0x8a0>; + label = "venus_sec_non_pixel"; + }; + + venus_fw: qcom,iommu-ctx@1e36000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e36000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x8c0 0x8c6>; + label = "venus_fw"; + }; + + periph_rpm: qcom,iommu-ctx@1e37000 { + compatible = "qcom,msm-smmu-v2-ctx"; + qcom,secure-context; + reg = <0x1e37000 0x1000>; + interrupts = <0 70 0>, <0 70 0>; + qcom,iommu-ctx-sids = <0x40>; + label = "periph_rpm"; + }; + + qcom,iommu-ctx@1e38000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e38000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0xC0 0xC4 0xC8 0xCC 0xD0 0xD3 + 0xD4 0xD7 0xD8 0xDB 0xDC 0xDF + 0xF0 0xF3 0xF4 0xF7 0xF8 0xFB + 0xFC 0xFF>; + label = "periph_CE"; + }; + + qcom,iommu-ctx@1e39000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e39000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x280 0x283 0x284 0x287 0x288 + 0x28B 0x28C 0x28F 0x290 0x293 + 0x294 0x297 0x298 0x29B 0x29C + 0x29F>; + label = "periph_BLSP"; + }; + + qcom,iommu-ctx@1e3a000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3a000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x100>; + label = "periph_SDC1"; + }; + + qcom,iommu-ctx@1e3b000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3b000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x140>; + label = "periph_SDC2"; + }; + + qcom,iommu-ctx@1e3c000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3c000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x1c0>; + label = "periph_audio"; + }; + + qcom,iommu-ctx@1e3d000 { + compatible = "qcom,msm-smmu-v2-ctx"; + reg = <0x1e3d000 0x1000>; + interrupts = <0 70 0>; + qcom,iommu-ctx-sids = <0x2c0>; + label = "periph_USB_HS1"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8916-iommu.dtsi b/arch/arm64/boot/dts/qcom/msm8916-iommu.dtsi new file mode 100644 index 000000000000..82acb8df2a8a --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8916-iommu.dtsi @@ -0,0 +1,21 @@ +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msm-iommu-v2.dtsi" + +&gfx_iommu { + status = "ok"; +}; + +&apps_iommu { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 2c4a5d1e0ea1..1f27d3492b29 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -797,3 +797,4 @@ }; #include "msm8916-pins.dtsi" +#include "msm8916-iommu.dtsi" -- cgit v1.2.3 From f665737427866198250d147236f330ea7e4617c3 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Mon, 13 Jul 2015 22:47:03 -0500 Subject: arm64: dt: Add WCNSS related nodes This patch addes DT nodes for reservered memory, smp2p, wcnss/pronto Signed-off-by: Andy Gross --- arch/arm64/boot/dts/qcom/msm8916-pins.dtsi | 25 ++++++ arch/arm64/boot/dts/qcom/msm8916.dtsi | 120 ++++++++++++++++++++++++++++- 2 files changed, 143 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi index 3a89f55fa98b..4e0d000061a1 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi @@ -643,4 +643,29 @@ }; }; }; + + wcnss_default: wcnss_default { + pinmux2 { + function = "wcss_wlan"; + pins = "gpio40"; + }; + pinmux1 { + function = "wcss_wlan"; + pins = "gpio41"; + }; + pinmux0 { + function = "wcss_wlan"; + pins = "gpio42"; + }; + pinmux { + function = "wcss_wlan"; + pins = "gpio43", "gpio44"; + }; + pinconf { + pins = "gpio40", "gpio41", "gpio42", "gpio43", + "gpio44"; + drive-strength = <6>; + bias-pull-up; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 1f27d3492b29..35cc4a0d452a 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -59,6 +59,16 @@ reg = <0x0 0x86300000 0x0 0x0100000>; no-map; }; + + modem_adsp_mem: modem_adsp_region@86400000 { + no-map; + reg = <0x0 0x86400000 0x0 0x05200000>; + }; + + peripheral_mem: peripheral_region@8b600000 { + no-map; + reg = <0x0 0x8b600000 0x0 0x0600000>; + }; }; cpus { @@ -259,6 +269,7 @@ interrupts = <0 168 1>; qcom,ipc = <&apcs 8 0>; qcom,smd-edge = <15>; + qcom,remote-pid = <0xffffffff>; rpm_requests { compatible = "qcom,rpm-msm8916"; @@ -290,8 +301,10 @@ regulator-max-microvolt = <1562000>; }; pm8916_s4: s4 { - regulator-min-microvolt = <1550000>; - regulator-max-microvolt = <2325000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; }; pm8916_l1: l1 { @@ -369,6 +382,47 @@ }; }; }; + + pronto_smd_edge: pronto { + interrupts = <0 142 1>; + + qcom,ipc = <&apcs 8 17>; + qcom,smd-edge = <6>; + qcom,remote-pid = <4>; + +#if 0 + bt { + compatible = "qcom,hci-smd"; + qcom,smd-channels = "APPS_RIVA_BT_CMD", "APPS_RIVA_BT_ACL"; + qcom,smd-channel-names = "event", "data"; + }; + + ipcrtr { + compatible = "qcom,ipcrtr"; + qcom,smd-channels = "IPCRTR"; + }; + + wifi { + compatible = "qcom,wcn3680"; + qcom,smd-channels = "WLAN_CTRL"; + + interrupts = <0 145 0>, <0 146 0>; + interrupt-names = "wcnss_wlantx_irq", "wcnss_wlanrx_irq"; + + qcom,wcnss_mmio = <0xfb000000 0x21b000>; + + qcom,tx-enable-gpios = <&apps_smsm 10 0>; + qcom,tx-rings-empty-gpios = <&apps_smsm 9 0>; + }; + + wcnss_ctrl { + compatible = "qcom,wcnss-ctrl"; + qcom,smd-channels = "WCNSS_CTRL"; + + qcom,wcnss_mmio = <0xfb21b000 0x3000>; + }; +#endif + }; }; gcc: qcom,gcc@1800000 { @@ -793,6 +847,68 @@ qcom,sensor-id = <0 1 2 4 5>; #thermal-sensor-cells = <1>; }; + + wcnss-smp2p { + compatible = "qcom,smp2p"; + qcom,smem = <451>, <431>; + + interrupts = <0 143 1>; + + qcom,ipc = <&apcs 8 18>; + + qcom,local-pid = <0>; + qcom,remote-pid = <4>; + + wcnss_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + qcom,outbound; + + gpio-controller; + #gpio-cells = <2>; + }; + + wcnss_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + qcom,inbound; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + pronto_rproc { + compatible = "qcom,tz-pil"; + + interrupts-extended = <&intc 0 149 1>, + <&wcnss_smp2p_in 0 0>, + <&wcnss_smp2p_in 1 0>, + <&wcnss_smp2p_in 2 0>, + <&wcnss_smp2p_in 3 0>; + interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack"; + + clocks = <&gcc GCC_CRYPTO_CLK>, + <&gcc GCC_CRYPTO_AHB_CLK>, + <&gcc GCC_CRYPTO_AXI_CLK>, + <&gcc CRYPTO_CLK_SRC>; + clock-names = "scm_core_clk", "scm_iface_clk", "scm_bus_clk", "scm_src_clk"; + + qcom,firmware-name = "wcnss"; + qcom,pas-id = <6>; + + qcom,crash-reason = <422>; + qcom,smd-edges = <&pronto_smd_edge>; + + qcom,pll-supply = <&pm8916_l7>; + qcom,pll-uV = <1800000>; + qcom,pll-uA = <18000>; + + qcom,stop-gpio = <&wcnss_smp2p_out 0 0>; + + pinctrl-names = "default"; + pinctrl-0 = <&wcnss_default>; + + memory-region = <&peripheral_mem>; + }; }; }; -- cgit v1.2.3 From bc7697155a52b5df35a01121bc2c666cd5517fe7 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Wed, 15 Jul 2015 15:10:50 +0300 Subject: arm64: dts: qcom: 8x16: Add UART1 configuration nodes Add devicetree bindings for UART1 pins and device controller with DMA channel specifiers. Enable UART1 on apq8016-sdc board (DB410c). Signed-off-by: Ivan T. Ivanov Conflicts: arch/arm64/boot/dts/qcom/msm8916.dtsi --- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 8 ++++++++ arch/arm64/boot/dts/qcom/msm8916-pins.dtsi | 28 ++++++++++++++++++++++++++++ arch/arm64/boot/dts/qcom/msm8916.dtsi | 12 ++++++++++++ 3 files changed, 48 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index 92325bacd909..bf64cf7da86e 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -21,6 +21,7 @@ / { aliases { serial0 = &blsp1_uart2; + serial1 = &blsp1_uart1; }; chosen { @@ -157,6 +158,13 @@ status = "okay"; }; +&blsp1_uart1 { + status = "okay"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&blsp1_uart1_default>; + pinctrl-1 = <&blsp1_uart1_sleep>; +}; + &blsp_spi3 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi index 4e0d000061a1..8352ac8db54b 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi @@ -12,6 +12,34 @@ */ &msmgpio { + blsp1_uart1_default: blsp1_uart1_default { + pinmux { + function = "blsp_uart1"; + // TX, RX, CTS_N, RTS_N + pins = "gpio0", "gpio1", + "gpio2", "gpio3"; + }; + pinconf { + pins = "gpio0", "gpio1", + "gpio2", "gpio3"; + drive-strength = <16>; + bias-disable; + }; + }; + + blsp1_uart1_sleep: blsp1_uart1_sleep { + pinmux { + function = "blsp_uart1"; + pins = "gpio0", "gpio1", + "gpio2", "gpio3"; + }; + pinconf { + pins = "gpio0", "gpio1", + "gpio2", "gpio3"; + drive-strength = <2>; + bias-pull-down; + }; + }; blsp1_uart2_default: blsp1_uart2_default { pinmux { diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 35cc4a0d452a..4d48afd2284b 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -440,6 +440,18 @@ qcom,apcs = <&apcs>; }; + blsp1_uart1: serial@78af000 { + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + reg = <0x78af000 0x200>; + interrupts = ; + clocks = <&gcc GCC_BLSP1_UART1_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + dmas = <&blsp_dma 1>, <&blsp_dma 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + blsp1_uart2: serial@78b0000 { compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; reg = <0x78b0000 0x200>; -- cgit v1.2.3 From 85dfd330ab238c62f97ae108163f5f21b44ea1b6 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Fri, 31 Jul 2015 13:00:38 +0300 Subject: arm64: dts: qcom: 8x16: UART2 use DMA for RX and TX Signed-off-by: Ivan T. Ivanov --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 4d48afd2284b..bce639e48b2b 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -458,6 +458,8 @@ interrupts = ; clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>; clock-names = "core", "iface"; + dmas = <&blsp_dma 3>, <&blsp_dma 2>; + dma-names = "rx", "tx"; status = "disabled"; }; -- cgit v1.2.3 From 9b21fc2fabd14679a7dfc7e6e37ae3c990fb48c3 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 22 May 2015 08:24:56 +0100 Subject: dts: arm64: apq8016-sbc: enable LS 1.8v regulator by default This patch is a temporary fix to enable 1.8v on Low speed expansion on DB410c board. Signed-off-by: Srinivas Kandagatla Signed-off-by: Nicolas Dechesne --- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index bf64cf7da86e..b5bfd9908ac5 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -290,3 +290,8 @@ }; }; }; + +/* default regulators required for mezzanine boards */ +&pm8916_l15 { + regulator-always-on; +}; -- cgit v1.2.3 From 831d91d8e4c1a67c99605645afadd3ecc43ad5e1 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Tue, 28 Jul 2015 15:06:26 +0300 Subject: arm64: dts: qcom: apq8016-sbc: Fix LED's naming 96Boards CE specs uses user 0, 1, 2, 3 and WIFI for LED's naming. Fix implementation to match specification. Signed-off-by: Ivan T. Ivanov --- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index b5bfd9908ac5..4313965cf2cc 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -111,35 +111,35 @@ compatible = "gpio-leds"; led@1 { - label = "apq8016-sbc:green:user1"; + label = "apq8016-sbc:green:user0"; gpios = <&msmgpio 21 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; default-state = "off"; }; led@2 { - label = "apq8016-sbc:green:user2"; + label = "apq8016-sbc:green:user1"; gpios = <&msmgpio 120 GPIO_ACTIVE_HIGH>; linux,default-trigger = "mmc0"; default-state = "off"; }; led@3 { - label = "apq8016-sbc:green:user3"; + label = "apq8016-sbc:green:user2"; gpios = <&pm8916_gpios 1 GPIO_ACTIVE_HIGH>; linux,default-trigger = "mmc1"; default-state = "off"; }; led@4 { - label = "apq8016-sbc:green:user4"; + label = "apq8016-sbc:green:user3"; gpios = <&pm8916_gpios 2 GPIO_ACTIVE_HIGH>; linux,default-trigger = "none"; default-state = "off"; }; led@5 { - label = "apq8016-sbc:yellow:wlan"; + label = "apq8016-sbc:yellow:wifi"; gpios = <&pm8916_mpps 2 GPIO_ACTIVE_HIGH>; linux,default-trigger = "wlan"; default-state = "off"; -- cgit v1.2.3 From 268e8a27361eabdbaddc39729b808bc3e4aab1e7 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 24 Sep 2015 18:16:16 +0100 Subject: ARM64: dts: Fix the missing usb otg regulators. This patch fixes up the usb otg node with correct regulators. Without this patch the otg on the DB410c is not functional. Signed-off-by: Srinivas Kandagatla --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index bce639e48b2b..679030d2b980 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -643,6 +643,8 @@ interrupts = , ; + v1p8-supply = <&pm8916_l7>; + v3p3-supply = <&pm8916_l13>; qcom,vdd-levels = <1 5 7>; qcom,phy-init-sequence = <0x44 0x6B 0x24 0x13>; dr_mode = "peripheral"; -- cgit v1.2.3 From 1e5fadb1a52563c2828433d2304aba91b58ad0bf Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Thu, 24 Sep 2015 20:49:03 +0300 Subject: arm64: dts: Fix memory region descriptions Update the reserved memory region descriptions. 0x86400000 - hypervisor memory 0x86800000 - adsp memory Signed-off-by: Georgi Djakov --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 679030d2b980..c7d41f1b5d98 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -51,16 +51,17 @@ #size-cells = <2>; ranges; - stuff: stuff@0x86000000 { /* fill in the gap */ + reserve_aligned@86000000 { reg = <0x0 0x86000000 0x0 0x0300000>; no-map; }; + smem_mem: smem_region@86300000 { reg = <0x0 0x86300000 0x0 0x0100000>; no-map; }; - modem_adsp_mem: modem_adsp_region@86400000 { + hypervisor_mem: hypervisor_region@86400000 { no-map; reg = <0x0 0x86400000 0x0 0x05200000>; }; -- cgit v1.2.3 From 94f92207a795dac3f810dce6e04f5d7132c5f8a5 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 14 Oct 2015 11:32:30 +0100 Subject: arm64: dts: msm8916: add wcd codec support This patch adds wcd codec support in the soc layer. Signed-off-by: Srinivas Kandagatla --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 5 +++++ arch/arm64/boot/dts/qcom/pm8916.dtsi | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index c7d41f1b5d98..ed709630497d 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -778,6 +778,11 @@ /* Audio */ + wcd_digital: codec-digital{ + compatible = "syscon", "qcom,apq8016-wcd-digital-codec"; + reg = <0x0771c000 0x400>; + }; + lpass: lpass-cpu@07700000 { status = "disabled"; compatible = "qcom,lpass-cpu-apq8016"; diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi index debc74dd8b05..5f6a92516eab 100644 --- a/arch/arm64/boot/dts/qcom/pm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi @@ -213,5 +213,13 @@ status = "disabled"; }; }; + + wcd_codec: codec@f000 { + compatible = "qcom,apq8016-wcd-codec"; + reg = <0xf000 0x200>; + #sound-dai-cells = <0>; + vddio-supply = <&pm8916_l5>; + vdd-pa-supply = <&pm8916_s4>; + }; }; }; -- cgit v1.2.3 From 5f3480a73c6305458213dd57dd36b8f868c2b2de Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 14 Oct 2015 11:40:02 +0100 Subject: arm64: dts: add support to analog audio playback This patch adds support to analog audio playback. Only tested with headphones. TODO: more testing on earphones and speakers. to play analog audio on headpones: amixer cset numid=18,iface=MIXER,name='RX1 MIX1 INP1' 'RX1' amixer cset numid=21,iface=MIXER,name='RX2 MIX1 INP1' 'RX2' amixer cset numid=5,iface=MIXER,name='RX1 Digital Volume' 60 amixer cset numid=6,iface=MIXER,name='RX2 Digital Volume' 60 amixer cset numid=25,iface=MIXER,name='RDAC2 MUX' 'RX2' aplay -D hw:0,0 /usr/share/sounds/alsa/* To play audio on HDMI: aplay -D hw:0,1 /usr/share/sounds/alsa/* Signed-off-by: Srinivas Kandagatla --- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index 4313965cf2cc..e494ff3aabef 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -256,6 +256,13 @@ &lpass { status = "okay"; }; + +&wcd_codec { + status = "okay"; + clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>; + clock-names = "mclk"; + digital = <&wcd_digital>; +}; /* Internal Codec playback - Primary MI2S @@ -278,6 +285,16 @@ qcom,model = "DB410c"; + internal-codec-playback-dai-link@0 { /* I2S - Internal codec */ + link-name = "WCD"; + cpu { /* PRIMARY */ + sound-dai = <&lpass MI2S_PRIMARY>; + }; + codec { + sound-dai = <&wcd_codec 0>; + }; + }; + /* External Primary or External Secondary -ADV7533 HDMI */ external-dai-link@0 { link-name = "ADV7533"; -- cgit v1.2.3 From 81643433487014efa7a3e95e47632d1294039f7d Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 8 Oct 2015 11:36:05 +0100 Subject: arm64: dts: fix i2c pinconf sleep state function This patch fixes the i2c pinctrl sleep state by changing the pinconf function to be in gpio mode rather than i2c. Signed-off-by: Srinivas Kandagatla --- arch/arm64/boot/dts/qcom/msm8916-pins.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi index 8352ac8db54b..0ad09d655f42 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi @@ -283,7 +283,7 @@ i2c4_sleep: i2c4_sleep { pinmux { - function = "blsp_i2c4"; + function = "gpio"; pins = "gpio14", "gpio15"; }; pinconf { -- cgit v1.2.3 From 655946bb4c4e94198c469c5fe0cbbb054b6d8f99 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 1 Oct 2015 16:46:11 +0100 Subject: arm64: dts: qcom: Add msm8916 I2C nodes. This patch adds missing support for i2c0 and i2c6, this support is required to connect the i2c slaves on LS expansion on DB410c. Signed-off-by: Srinivas Kandagatla --- arch/arm64/boot/dts/qcom/msm8916-pins.dtsi | 48 ++++++++++++++++++++++++++++++ arch/arm64/boot/dts/qcom/msm8916.dtsi | 30 +++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi index 0ad09d655f42..5d2e4a5e91ef 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi @@ -269,6 +269,30 @@ }; }; + i2c2_default: i2c2_default { + pinmux { + function = "blsp_i2c2"; + pins = "gpio6", "gpio7"; + }; + pinconf { + pins = "gpio6", "gpio7"; + drive-strength = <2>; + bias-disable = <0>; + }; + }; + + i2c2_sleep: i2c2_sleep { + pinmux { + function = "gpio"; + pins = "gpio6", "gpio7"; + }; + pinconf { + pins = "gpio6", "gpio7"; + drive-strength = <2>; + bias-disable = <0>; + }; + }; + i2c4_default: i2c4_default { pinmux { function = "blsp_i2c4"; @@ -293,6 +317,30 @@ }; }; + i2c6_default: i2c6_default { + pinmux { + function = "blsp_i2c6"; + pins = "gpio22", "gpio23"; + }; + pinconf { + pins = "gpio22", "gpio23"; + drive-strength = <2>; + bias-disable = <0>; + }; + }; + + i2c6_sleep: i2c6_sleep { + pinmux { + function = "gpio"; + pins = "gpio22", "gpio23"; + }; + pinconf { + pins = "gpio22", "gpio23"; + drive-strength = <2>; + bias-disable = <0>; + }; + }; + sdhc2_cd_pin { sdc2_cd_on: cd_on { pinmux { diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index ed709630497d..00be07ef3694 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -577,6 +577,21 @@ status = "disabled"; }; + blsp_i2c2: i2c@78b6000 { + compatible = "qcom,i2c-qup-v2.2.1"; + reg = <0x78b6000 0x1000>; + interrupts = ; + clocks = <&gcc GCC_BLSP1_AHB_CLK>, + <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>; + clock-names = "iface", "core"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c2_default>; + pinctrl-1 = <&i2c2_sleep>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + blsp_i2c4: i2c@78b8000 { compatible = "qcom,i2c-qup-v2.2.1"; reg = <0x78b8000 0x1000>; @@ -592,6 +607,21 @@ status = "disabled"; }; + blsp_i2c6: i2c@78ba000 { + compatible = "qcom,i2c-qup-v2.2.1"; + reg = <0x78ba000 0x1000>; + interrupts = ; + clocks = <&gcc GCC_BLSP1_AHB_CLK>, + <&gcc GCC_BLSP1_QUP6_I2C_APPS_CLK>; + clock-names = "iface", "core"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c6_default>; + pinctrl-1 = <&i2c6_sleep>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + sdhc_1: sdhci@07824000 { compatible = "qcom,sdhci-msm-v4"; reg = <0x07824900 0x11c>, <0x07824000 0x800>; -- cgit v1.2.3 From 40a3de1f438000666b359c2966f22d8256e471d7 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 8 Oct 2015 12:08:02 +0100 Subject: arm64: dts: apq8016-sbc: enable i2c buses on LS and HS This patch enables i2c buses on low speed and high speed expansion connectors on DB410C. Signed-off-by: Srinivas Kandagatla --- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index e494ff3aabef..4a22b9999eac 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -36,6 +36,21 @@ pinctrl-1 = <&blsp1_uart2_sleep>; }; + i2c@78b6000 { + /* On Low speed expansion */ + status = "okay"; + }; + + i2c@78b8000 { + /* On High speed expansion */ + status = "okay"; + }; + + i2c@78ba000 { + /* On Low speed expansion */ + status = "okay"; + }; + leds { pinctrl-names = "default"; pinctrl-0 = <&msmgpio_leds>, -- cgit v1.2.3 From 901d352414f19c8f525d82d8dd85113be63e89af Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 8 Oct 2015 12:11:20 +0100 Subject: arm64: dts: apq8016-sbc: enable spi buses on LS and HS This patch enables spi buses on low speed and high speed expansion connectors on DB410C Signed-off-by: Srinivas Kandagatla --- arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index 4a22b9999eac..bc40ec5945aa 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -51,6 +51,16 @@ status = "okay"; }; + spi@78b7000 { + /* On High speed expansion */ + status = "okay"; + }; + + spi@78b9000 { + /* On Low speed expansion */ + status = "okay"; + }; + leds { pinctrl-names = "default"; pinctrl-0 = <&msmgpio_leds>, -- cgit v1.2.3 From 9eba4c401cd929d9da7fb2ab4a0dd151d4b2ee7d Mon Sep 17 00:00:00 2001 From: Nicolas Dechesne Date: Thu, 8 Oct 2015 11:10:53 +0100 Subject: arm64: dts: qcom: fix typo: user LED2 uses GPIO 120, not 10 Signed-off-by: Nicolas Dechesne --- arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi index 1ee5a2d5bae0..c7db0aeaebaa 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi @@ -21,7 +21,7 @@ msm_gpios_leds_default: msm_gpios_leds_default { pinconf { - pins = "gpio21", "gpio10"; + pins = "gpio21", "gpio120"; function = "gpio"; output-low; }; -- cgit v1.2.3 From 3bfc84e75e4754765f015965cf46bbf50e4fbe4c Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 1 Aug 2014 09:42:34 +0100 Subject: mfd: ssbi: promote the driver to subsys level This patch promtes the driver to be at subsystem level as this driver will be used by gpio controller drivers which inturn are used by many platform drivers. Signed-off-by: Srinivas Kandagatla --- drivers/mfd/ssbi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/ssbi.c b/drivers/mfd/ssbi.c index 27986f641f7d..39734999fe40 100644 --- a/drivers/mfd/ssbi.c +++ b/drivers/mfd/ssbi.c @@ -330,7 +330,12 @@ static struct platform_driver ssbi_driver = { .of_match_table = ssbi_match_table, }, }; -module_platform_driver(ssbi_driver); + +static int ssbi_init(void) +{ + return platform_driver_register(&ssbi_driver); +} +subsys_initcall(ssbi_init); MODULE_LICENSE("GPL v2"); MODULE_VERSION("1.0"); -- cgit v1.2.3 From bf978563444eff9b1613c6953ab877d1ec381650 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 9 Dec 2014 16:33:46 +0000 Subject: WIP: add memblock_overlaps_memory Signed-off-by: Srinivas Kandagatla --- include/linux/memblock.h | 1 + mm/memblock.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/include/linux/memblock.h b/include/linux/memblock.h index c518eb589260..f0586b08c9e3 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -324,6 +324,7 @@ phys_addr_t memblock_end_of_DRAM(void); void memblock_enforce_memory_limit(phys_addr_t memory_limit); int memblock_is_memory(phys_addr_t addr); int memblock_is_region_memory(phys_addr_t base, phys_addr_t size); +int memblock_overlaps_memory(phys_addr_t base, phys_addr_t size); int memblock_is_reserved(phys_addr_t addr); bool memblock_is_region_reserved(phys_addr_t base, phys_addr_t size); diff --git a/mm/memblock.c b/mm/memblock.c index 1c7b647e5897..29cd3726374f 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -1558,6 +1558,12 @@ int __init_memblock memblock_is_region_memory(phys_addr_t base, phys_addr_t size memblock.memory.regions[idx].size) >= end; } +int __init_memblock memblock_overlaps_memory(phys_addr_t base, phys_addr_t size) +{ + memblock_cap_size(base, &size); + return memblock_overlaps_region(&memblock.memory, base, size) >= 0; +} + /** * memblock_is_region_reserved - check if a region intersects reserved memory * @base: base of region to check -- cgit v1.2.3 From 52e059d385839a9ad40a162ce17ce440af0e9773 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 18 Aug 2014 06:06:46 +0100 Subject: mmc: mmci: Support any block sizes for ux500v2 and qcom variant For the ux500v2 variant of the PL18x block, any block sizes are supported. This will make it possible to decrease data overhead for SDIO transfers. This patch is based on Ulf Hansson patch http://www.spinics.net/lists/linux-mmc/msg12160.html Signed-off-by: Srinivas Kandagatla enabled this support on qcom variant. Signed-off-by: Ulf Hansson Signed-off-by: Linus Walleij --- drivers/mmc/host/mmci.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index fb266745f824..70805ba9577c 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -78,6 +78,7 @@ static unsigned int fmax = 515633; * @qcom_fifo: enables qcom specific fifo pio read logic. * @qcom_dml: enables qcom specific dma glue for dma transfers. * @reversed_irq_handling: handle data irq before cmd irq. + * @any_blksize: true if block any sizes are supported */ struct variant_data { unsigned int clkreg; @@ -104,6 +105,7 @@ struct variant_data { bool qcom_fifo; bool qcom_dml; bool reversed_irq_handling; + bool any_blksize; }; static struct variant_data variant_arm = { @@ -200,6 +202,7 @@ static struct variant_data variant_ux500v2 = { .pwrreg_clkgate = true, .busy_detect = true, .pwrreg_nopower = true, + .any_blksize = true, }; static struct variant_data variant_qcom = { @@ -218,6 +221,7 @@ static struct variant_data variant_qcom = { .explicit_mclk_control = true, .qcom_fifo = true, .qcom_dml = true, + .any_blksize = true, }; static int mmci_card_busy(struct mmc_host *mmc) @@ -245,10 +249,11 @@ static int mmci_card_busy(struct mmc_host *mmc) static int mmci_validate_data(struct mmci_host *host, struct mmc_data *data) { + struct variant_data *variant = host->variant; + if (!data) return 0; - - if (!is_power_of_2(data->blksz)) { + if (!is_power_of_2(data->blksz) && !variant->any_blksize) { dev_err(mmc_dev(host->mmc), "unsupported block size (%d bytes)\n", data->blksz); return -EINVAL; @@ -804,7 +809,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) writel(host->size, base + MMCIDATALENGTH); blksz_bits = ffs(data->blksz) - 1; - BUG_ON(1 << blksz_bits != data->blksz); if (variant->blksz_datactrl16) datactrl = MCI_DPSM_ENABLE | (data->blksz << 16); -- cgit v1.2.3 From ccf23ee96b433f9107ad39e6f7b3e496d2de7f87 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Mon, 19 Jan 2015 11:12:46 +0000 Subject: WIP:mfd:qcom-rpm: Add qcom_rpm_read functionality This patch add qcom_rpm_read functionality. Signed-off-by: Srinivas Kandagatla --- drivers/mfd/qcom_rpm.c | 36 ++++++++++++++++++++++++++++++++++++ include/linux/mfd/qcom_rpm.h | 1 + 2 files changed, 37 insertions(+) diff --git a/drivers/mfd/qcom_rpm.c b/drivers/mfd/qcom_rpm.c index 6afc9fabd94c..63886e443a5e 100644 --- a/drivers/mfd/qcom_rpm.c +++ b/drivers/mfd/qcom_rpm.c @@ -373,6 +373,42 @@ static const struct of_device_id qcom_rpm_of_match[] = { }; MODULE_DEVICE_TABLE(of, qcom_rpm_of_match); +#define QCOM_RPM_STATUS_ID_SEQUENCE 7 +int qcom_rpm_read(struct qcom_rpm *rpm, + int resource, + u32 *val, + size_t count) +{ + const struct qcom_rpm_resource *res; + const struct qcom_rpm_data *data = rpm->data; + uint32_t seq_begin; + uint32_t seq_end; + int rc; + int i; + + if (WARN_ON(resource < 0 || resource >= data->n_resources)) + return -EINVAL; + + res = &data->resource_table[resource]; + if (WARN_ON(res->size != count)) + return -EINVAL; + + mutex_lock(&rpm->lock); + seq_begin = readl(RPM_STATUS_REG(rpm, QCOM_RPM_STATUS_ID_SEQUENCE)); + + for (i = 0; i < count; i++) + *val++ = readl(RPM_STATUS_REG(rpm, res->status_id)); + + seq_end = readl(RPM_STATUS_REG(rpm, QCOM_RPM_STATUS_ID_SEQUENCE)); + + rc = (seq_begin != seq_end || (seq_begin & 0x01)) ? -EBUSY : 0; + + mutex_unlock(&rpm->lock); + return rc; + +} +EXPORT_SYMBOL(qcom_rpm_read); + int qcom_rpm_write(struct qcom_rpm *rpm, int state, int resource, diff --git a/include/linux/mfd/qcom_rpm.h b/include/linux/mfd/qcom_rpm.h index 742ebf1b76ca..a7af2edf0f64 100644 --- a/include/linux/mfd/qcom_rpm.h +++ b/include/linux/mfd/qcom_rpm.h @@ -9,5 +9,6 @@ struct qcom_rpm; #define QCOM_RPM_SLEEP_STATE 1 int qcom_rpm_write(struct qcom_rpm *rpm, int state, int resource, u32 *buf, size_t count); +int qcom_rpm_read(struct qcom_rpm *rpm, int resource, u32 *buf, size_t count); #endif -- cgit v1.2.3 From ab8fa4845138c0efe706c2862bbd9141ef7f0cab Mon Sep 17 00:00:00 2001 From: Kiran Rudramuni Date: Tue, 15 Sep 2015 21:06:04 +0200 Subject: hid: add support for Lilliput touchscreen Signed-off-by: Kiran Rudramuni Signed-off-by: Nicolas Dechesne --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 4 ++++ drivers/hid/hid-multitouch.c | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 70a11ac38119..47031883d8d1 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2043,6 +2043,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LILLIPUT, USB_PROD_ID_LILLIPUT) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index f769208276ae..e10908b7ec88 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -1047,4 +1047,8 @@ #define USB_DEVICE_ID_RAPHNET_2NES2SNES 0x0002 #define USB_DEVICE_ID_RAPHNET_4NES4SNES 0x0003 +/* Lilliput Capacitive TouchScreen */ +#define USB_VENDOR_ID_LILLIPUT 0x1391 +#define USB_PROD_ID_LILLIPUT 0x2112 + #endif diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 426b2f1a3450..17b03e862897 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1153,6 +1153,11 @@ static const struct hid_device_id mt_devices[] = { MT_USB_DEVICE(USB_VENDOR_ID_CJTOUCH, USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040) }, + /* Lilliput multitouch panels */ + { .driver_data = MT_CLS_DEFAULT, + HID_USB_DEVICE(USB_VENDOR_ID_LILLIPUT, + USB_PROD_ID_LILLIPUT) }, + /* CVTouch panels */ { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, -- cgit v1.2.3 From 686b6214574fa5cb1434d334fa83decf425456bb Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 9 Dec 2014 10:15:24 +0000 Subject: ARM: qcom_defconfig: Add QCOM specific drivers This patch adds common kconfig options required for qcom chips to work. Signed-off-by: Srinivas Kandagatla --- arch/arm/configs/qcom_defconfig | 154 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 147 insertions(+), 7 deletions(-) diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig index ff7985ba226e..77972a6ca8ad 100644 --- a/arch/arm/configs/qcom_defconfig +++ b/arch/arm/configs/qcom_defconfig @@ -1,8 +1,10 @@ CONFIG_SYSVIPC=y +CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUPS=y CONFIG_BLK_DEV_INITRD=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS_ALL=y @@ -21,19 +23,36 @@ CONFIG_ARCH_QCOM=y CONFIG_ARCH_MSM8X60=y CONFIG_ARCH_MSM8960=y CONFIG_ARCH_MSM8974=y +CONFIG_PCI=y +CONFIG_PCI_MSI=y +CONFIG_PCI_STUB=y +CONFIG_PCI_HOST_GENERIC=y +CONFIG_PCIEPORTBUS=y CONFIG_SMP=y CONFIG_PREEMPT=y CONFIG_AEABI=y CONFIG_HIGHMEM=y CONFIG_HIGHPTE=y CONFIG_CLEANCACHE=y +CONFIG_CMA=y +CONFIG_SECCOMP=y CONFIG_ARM_APPENDED_DTB=y CONFIG_ARM_ATAG_DTB_COMPAT=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPUFREQ_DT=y +CONFIG_ARM_QCOM_CPUFREQ=y CONFIG_CPU_IDLE=y CONFIG_ARM_CPUIDLE=y +CONFIG_ARM_QCOM_CPUIDLE=y CONFIG_VFP=y CONFIG_NEON=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_PM_RUNTIME=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -48,25 +67,44 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set -CONFIG_CFG80211=y +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_CFG80211=m +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=m CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=y +CONFIG_RFKILL_GPIO=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=64 CONFIG_MTD=y CONFIG_MTD_BLOCK=y CONFIG_MTD_M25P80=y CONFIG_MTD_SPI_NOR=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y -CONFIG_SCSI=y +CONFIG_EEPROM_AT24=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y CONFIG_CHR_DEV_SCH=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_ATA=y +CONFIG_SATA_AHCI_PLATFORM=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y +CONFIG_ATL1C=y CONFIG_KS8851=y CONFIG_MDIO_BITBANG=y CONFIG_MDIO_GPIO=y @@ -76,6 +114,9 @@ CONFIG_SLIP_MODE_SLIP6=y CONFIG_USB_USBNET=y # CONFIG_USB_NET_AX8817X is not set # CONFIG_USB_NET_ZAURUS is not set +CONFIG_ATH_CARDS=m +CONFIG_ATH6KL=m +CONFIG_ATH6KL_SDIO=m CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set # CONFIG_MOUSE_PS2 is not set @@ -88,7 +129,6 @@ CONFIG_SERIO_LIBPS2=y CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_QUP=y CONFIG_SPI=y @@ -99,18 +139,87 @@ CONFIG_PINCTRL_APQ8084=y CONFIG_PINCTRL_IPQ8064=y CONFIG_PINCTRL_MSM8960=y CONFIG_PINCTRL_MSM8X74=y +CONFIG_PINCTRL_QCOM_SPMI_PMIC=y +CONFIG_PINCTRL_QCOM_SSBI_PMIC=y CONFIG_GPIOLIB=y -CONFIG_DEBUG_GPIO=y CONFIG_GPIO_SYSFS=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_MSM=y CONFIG_THERMAL=y CONFIG_MFD_QCOM_RPM=y +CONFIG_CPU_THERMAL=y +CONFIG_QCOM_TSENS=y +CONFIG_WATCHDOG=y +CONFIG_QCOM_WDT=y +CONFIG_MFD_PM8921_CORE=y +CONFIG_MFD_SPMI_PMIC=y +CONFIG_MFD_SYSCON=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_QCOM_RPM=y CONFIG_MEDIA_SUPPORT=y -CONFIG_FB=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=y +CONFIG_USB_GSPCA=y +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GL860=m +CONFIG_USB_GSPCA_BENQ=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_CPIA1=m +CONFIG_USB_GSPCA_DTCS033=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_JEILINJ=m +CONFIG_USB_GSPCA_JL2005BCD=m +CONFIG_USB_GSPCA_KINECT=m +CONFIG_USB_GSPCA_KONICA=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_NW80X=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_OV534_9=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7302=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SE401=m +CONFIG_USB_GSPCA_SN9C2028=m +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_SPCA1528=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_SQ930X=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_STK1135=m +CONFIG_USB_GSPCA_STV0680=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TOPRO=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_VICAM=m +CONFIG_USB_GSPCA_XIRLINK_CIT=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_USB_PWC=m +CONFIG_USB_ZR364XX=m +CONFIG_DRM=y +CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GPIO=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_DYNAMIC_MINORS=y @@ -119,15 +228,32 @@ CONFIG_SND_DYNAMIC_MINORS=y # CONFIG_SND_USB is not set CONFIG_SND_SOC=y CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HID_APPLE=y +CONFIG_HID_LOGITECH=m +CONFIG_HID_MAGICMOUSE=m +CONFIG_HID_MICROSOFT=m CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_OTG_FSM=y CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_MSM=y CONFIG_USB_ACM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_UAS=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y CONFIG_USB_SERIAL=y +CONFIG_USB_MSM_OTG=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_DEBUG_FILES=y CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_ETH=m +CONFIG_USB_GADGETFS=m +CONFIG_USB_FUNCTIONFS=m +CONFIG_USB_FUNCTIONFS_RNDIS=y +CONFIG_USB_MASS_STORAGE=m CONFIG_MMC=y CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_ARMMMCI=y @@ -135,8 +261,10 @@ CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_MSM=y CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_PM8XXX=y CONFIG_DMADEVICES=y CONFIG_QCOM_BAM_DMA=y +CONFIG_QCOM_ADM=y CONFIG_STAGING=y CONFIG_COMMON_CLK_QCOM=y CONFIG_APQ_MMCC_8084=y @@ -145,23 +273,35 @@ CONFIG_MSM_GCC_8660=y CONFIG_MSM_LCC_8960=y CONFIG_MSM_MMCC_8960=y CONFIG_MSM_MMCC_8974=y +CONFIG_QCOM_HFPLL=y +CONFIG_KPSS_XCC=y +CONFIG_KRAITCC=y +CONFIG_MSM_RPMCC_8064=y CONFIG_MSM_IOMMU=y CONFIG_QCOM_GSBI=y CONFIG_QCOM_PM=y CONFIG_PHY_QCOM_APQ8064_SATA=y CONFIG_PHY_QCOM_IPQ806X_SATA=y +CONFIG_NVMEM=y +CONFIG_QCOM_QFPROM=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT4_FS=y +CONFIG_FANOTIFY=y +CONFIG_AUTOFS4_FS=y CONFIG_FUSE_FS=y CONFIG_VFAT_FS=y -CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y CONFIG_JFFS2_FS=y CONFIG_NFS_FS=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y CONFIG_CIFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=y @@ -173,5 +313,5 @@ CONFIG_DEBUG_INFO=y CONFIG_MAGIC_SYSRQ=y CONFIG_LOCKUP_DETECTOR=y # CONFIG_DETECT_HUNG_TASK is not set -# CONFIG_SCHED_DEBUG is not set +CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y -- cgit v1.2.3 From db5c92f359acc34a5bfccc3be235a7b1e9cf90b9 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 18 Mar 2015 18:40:30 +0000 Subject: arm:multi_v7_defconfig: Add QCOM specific Kconfigs Signed-off-by: Srinivas Kandagatla --- arch/arm/configs/multi_v7_defconfig | 59 +++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 03deb7fb35e8..46e4087c3546 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -124,8 +124,15 @@ CONFIG_KEXEC=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_STAT_DETAILS=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPUFREQ_DT=y +CONFIG_ARM_QCOM_CPUFREQ=y CONFIG_CPU_IDLE=y CONFIG_ARM_CPUIDLE=y +CONFIG_ARM_ZYNQ_CPUIDLE=y +CONFIG_ARM_QCOM_CPUIDLE=y CONFIG_NEON=y CONFIG_KERNEL_MODE_NEON=y CONFIG_ARM_ZYNQ_CPUIDLE=y @@ -153,10 +160,20 @@ CONFIG_CAN_DEV=y CONFIG_CAN_AT91=m CONFIG_CAN_XILINXCAN=y CONFIG_CAN_MCP251X=y -CONFIG_BT=m +CONFIG_BT=y CONFIG_BT_MRVL=m CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_ATH3K=y CONFIG_CFG80211=m +CONFIG_CFG80211_WEXT=y CONFIG_MAC80211=m CONFIG_RFKILL=y CONFIG_RFKILL_INPUT=y @@ -202,6 +219,7 @@ CONFIG_SATA_RCAR=y CONFIG_NETDEVICES=y CONFIG_HIX5HD2_GMAC=y CONFIG_SUN4I_EMAC=y +CONFIG_ATL1C=y CONFIG_MACB=y CONFIG_NET_CALXEDA_XGMAC=y CONFIG_IGB=y @@ -224,6 +242,10 @@ CONFIG_USB_PEGASUS=y CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC75XX=y CONFIG_USB_NET_SMSC95XX=y +CONFIG_ATH_CARDS=m +CONFIG_ATH_DEBUG=y +CONFIG_ATH6KL=m +CONFIG_ATH6KL_SDIO=m CONFIG_BRCMFMAC=m CONFIG_RT2X00=m CONFIG_RT2800USB=m @@ -301,6 +323,7 @@ CONFIG_I2C_DIGICOLOR=m CONFIG_I2C_GPIO=m CONFIG_I2C_EXYNOS5=y CONFIG_I2C_MV64XXX=y +CONFIG_I2C_QUP=y CONFIG_I2C_RIIC=y CONFIG_I2C_S3C2410=y CONFIG_I2C_SH_MOBILE=y @@ -330,9 +353,16 @@ CONFIG_SPI_TEGRA20_SFLASH=y CONFIG_SPI_TEGRA20_SLINK=y CONFIG_SPI_XILINX=y CONFIG_SPI_SPIDEV=y +CONFIG_SPMI=y CONFIG_PINCTRL_AS3722=y CONFIG_PINCTRL_PALMAS=y +CONFIG_PINCTRL_APQ8064=y CONFIG_PINCTRL_APQ8084=y +CONFIG_PINCTRL_IPQ8064=y +CONFIG_PINCTRL_MSM8960=y +CONFIG_PINCTRL_MSM8X74=y +CONFIG_PINCTRL_QCOM_SPMI_PMIC=y +CONFIG_PINCTRL_QCOM_SSBI_PMIC=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_GENERIC_PLATFORM=y CONFIG_GPIO_DAVINCI=y @@ -371,6 +401,7 @@ CONFIG_DAVINCI_WATCHDOG=m CONFIG_EXYNOS_THERMAL=m CONFIG_ST_THERMAL_SYSCFG=y CONFIG_ST_THERMAL_MEMMAP=y +CONFIG_QCOM_TSENS=y CONFIG_WATCHDOG=y CONFIG_XILINX_WATCHDOG=y CONFIG_ARM_SP805_WATCHDOG=y @@ -391,6 +422,8 @@ CONFIG_MFD_MAX14577=y CONFIG_MFD_MAX77686=y CONFIG_MFD_MAX77693=y CONFIG_MFD_MAX8907=y +CONFIG_MFD_PM8921_CORE=y +CONFIG_MFD_QCOM_RPM=y CONFIG_MFD_SEC_CORE=y CONFIG_MFD_STMPE=y CONFIG_MFD_PALMAS=y @@ -415,6 +448,7 @@ CONFIG_REGULATOR_MAX77802=m CONFIG_REGULATOR_PALMAS=y CONFIG_REGULATOR_PBIAS=y CONFIG_REGULATOR_PWM=m +CONFIG_REGULATOR_QCOM_RPM=y CONFIG_REGULATOR_S2MPS11=y CONFIG_REGULATOR_S5M8767=y CONFIG_REGULATOR_TPS51632=y @@ -464,6 +498,7 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_LCD_PLATFORM=m CONFIG_BACKLIGHT_PWM=y CONFIG_BACKLIGHT_AS3711=y +CONFIG_BACKLIGHT_GPIO=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_SOUND=m @@ -494,6 +529,7 @@ CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_MVEBU=y CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_MSM=y CONFIG_USB_EHCI_EXYNOS=y CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_EHCI_HCD_STI=y @@ -514,12 +550,13 @@ CONFIG_KEYSTONE_USB_PHY=y CONFIG_OMAP_USB3=y CONFIG_USB_GPIO_VBUS=y CONFIG_USB_ISP1301=y +CONFIG_USB_MSM_OTG=y CONFIG_USB_MXS_PHY=y CONFIG_USB_RCAR_PHY=m CONFIG_USB_GADGET=y CONFIG_USB_RENESAS_USBHS_UDC=m CONFIG_MMC=y -CONFIG_MMC_BLOCK_MINORS=16 +CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_ARMMMCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y @@ -536,6 +573,7 @@ CONFIG_MMC_SDHCI_ST=y CONFIG_MMC_OMAP=y CONFIG_MMC_OMAP_HS=y CONFIG_MMC_ATMELMCI=y +CONFIG_MMC_SDHCI_MSM=y CONFIG_MMC_MVSDIO=y CONFIG_MMC_SDHI=y CONFIG_MMC_DW=y @@ -582,6 +620,7 @@ CONFIG_RTC_DRV_DIGICOLOR=m CONFIG_RTC_DRV_S5M=m CONFIG_RTC_DRV_S3C=m CONFIG_RTC_DRV_PL031=y +CONFIG_RTC_DRV_PM8XXX=y CONFIG_RTC_DRV_AT91RM9200=m CONFIG_RTC_DRV_AT91SAM9=m CONFIG_RTC_DRV_VT8500=y @@ -605,6 +644,8 @@ CONFIG_IMX_SDMA=y CONFIG_IMX_DMA=y CONFIG_MXS_DMA=y CONFIG_DMA_OMAP=y +CONFIG_QCOM_BAM_DMA=y +CONFIG_QCOM_ADM=y CONFIG_XILINX_VDMA=y CONFIG_DMA_SUN6I=y CONFIG_STAGING=y @@ -627,6 +668,12 @@ CONFIG_APQ_MMCC_8084=y CONFIG_MSM_GCC_8660=y CONFIG_MSM_MMCC_8960=y CONFIG_MSM_MMCC_8974=y +CONFIG_QCOM_RPMCC=y +CONFIG_QCOM_HFPLL=y +CONFIG_KPSS_XCC=y +CONFIG_KRAITCC=y +CONFIG_MSM_RPMCC_8064=y +CONFIG_MSM_IOMMU=y CONFIG_TEGRA_IOMMU_GART=y CONFIG_TEGRA_IOMMU_SMMU=y CONFIG_PM_DEVFREQ=y @@ -651,6 +698,7 @@ CONFIG_PHY_HIX5HD2_SATA=y CONFIG_PWM_STI=m CONFIG_OMAP_USB2=y CONFIG_TI_PIPE3=y +CONFIG_PHY_QCOM_APQ8064_SATA=y CONFIG_PHY_MIPHY28LP=y CONFIG_PHY_MIPHY365X=y CONFIG_PHY_RCAR_GEN2=m @@ -659,6 +707,8 @@ CONFIG_PHY_STIH407_USB=y CONFIG_PHY_SUN4I_USB=y CONFIG_PHY_SUN9I_USB=y CONFIG_PHY_SAMSUNG_USB2=m +CONFIG_NVMEM=y +CONFIG_QCOM_QFPROM=y CONFIG_EXT4_FS=y CONFIG_AUTOFS4_FS=y CONFIG_MSDOS_FS=y @@ -682,7 +732,6 @@ CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_LOCKUP_DETECTOR=y CONFIG_CRYPTO_DEV_TEGRA_AES=y -CONFIG_CPUFREQ_DT=y CONFIG_KEYSTONE_IRQ=y CONFIG_CRYPTO_DEV_SUN4I_SS=m CONFIG_ARM_CRYPTO=y @@ -699,3 +748,7 @@ CONFIG_CRYPTO_GHASH_ARM_CE=m CONFIG_CRYPTO_DEV_ATMEL_AES=m CONFIG_CRYPTO_DEV_ATMEL_TDES=m CONFIG_CRYPTO_DEV_ATMEL_SHA=m +CONFIG_FUNCTION_TRACER=y +CONFIG_SCHED_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_TRACEPOINT_BENCHMARK=y -- cgit v1.2.3 From 932404d9e2549613d6082bcdf66b63743536325e Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 17 Sep 2015 10:17:05 +0100 Subject: WIP:pwrseq: Convert in to proper platform device Signed-off-by: Srinivas Kandagatla --- drivers/mmc/Kconfig | 2 + drivers/mmc/core/Kconfig | 8 +++ drivers/mmc/core/Makefile | 4 +- drivers/mmc/core/pwrseq.c | 92 +++++++++++++++--------------- drivers/mmc/core/pwrseq.h | 25 +++++++-- drivers/mmc/core/pwrseq_emmc.c | 91 ++++++++++++++++++++---------- drivers/mmc/core/pwrseq_simple.c | 118 +++++++++++++++++++++++++-------------- 7 files changed, 215 insertions(+), 125 deletions(-) diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index f2eeb38efa65..bc08c3b1335c 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -5,6 +5,8 @@ menuconfig MMC tristate "MMC/SD/SDIO card support" depends on HAS_IOMEM + select PWRSEQ_SIMPLE + select PWRSEQ_EMMC help This selects MultiMediaCard, Secure Digital and Secure Digital I/O support. diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig index 9ebee72d9c3f..a52c69042155 100644 --- a/drivers/mmc/core/Kconfig +++ b/drivers/mmc/core/Kconfig @@ -11,3 +11,11 @@ config MMC_CLKGATE support handling this in order for it to be of any use. If unsure, say N. + +config PWRSEQ_EMMC + tristate "PwrSeq EMMC" + depends on OF + +config PWRSEQ_SIMPLE + tristate "PwrSeq Simple" + depends on OF diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index 2c25138f28b7..b281675edb92 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile @@ -8,5 +8,7 @@ mmc_core-y := core.o bus.o host.o \ sdio.o sdio_ops.o sdio_bus.o \ sdio_cis.o sdio_io.o sdio_irq.o \ quirks.o slot-gpio.o -mmc_core-$(CONFIG_OF) += pwrseq.o pwrseq_simple.o pwrseq_emmc.o +mmc_core-$(CONFIG_OF) += pwrseq.o mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o +obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o +obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o diff --git a/drivers/mmc/core/pwrseq.c b/drivers/mmc/core/pwrseq.c index 4c1d1757dbf9..9af53a66e646 100644 --- a/drivers/mmc/core/pwrseq.c +++ b/drivers/mmc/core/pwrseq.c @@ -8,50 +8,28 @@ * MMC power sequence management */ #include -#include #include #include -#include - #include - #include "pwrseq.h" -struct mmc_pwrseq_match { - const char *compatible; - struct mmc_pwrseq *(*alloc)(struct mmc_host *host, struct device *dev); -}; - -static struct mmc_pwrseq_match pwrseq_match[] = { - { - .compatible = "mmc-pwrseq-simple", - .alloc = mmc_pwrseq_simple_alloc, - }, { - .compatible = "mmc-pwrseq-emmc", - .alloc = mmc_pwrseq_emmc_alloc, - }, -}; - -static struct mmc_pwrseq_match *mmc_pwrseq_find(struct device_node *np) +static DEFINE_MUTEX(pwrseq_list_mutex); +static LIST_HEAD(pwrseq_list); + +static struct mmc_pwrseq *of_find_mmc_pwrseq(struct device_node *np) { - struct mmc_pwrseq_match *match = ERR_PTR(-ENODEV); - int i; + struct mmc_pwrseq *p; - for (i = 0; i < ARRAY_SIZE(pwrseq_match); i++) { - if (of_device_is_compatible(np, pwrseq_match[i].compatible)) { - match = &pwrseq_match[i]; - break; - } - } + list_for_each_entry(p, &pwrseq_list, list) + if (p->dev->of_node == np) + return p; - return match; + return NULL; } int mmc_pwrseq_alloc(struct mmc_host *host) { - struct platform_device *pdev; struct device_node *np; - struct mmc_pwrseq_match *match; struct mmc_pwrseq *pwrseq; int ret = 0; @@ -59,25 +37,18 @@ int mmc_pwrseq_alloc(struct mmc_host *host) if (!np) return 0; - pdev = of_find_device_by_node(np); - if (!pdev) { - ret = -ENODEV; - goto err; - } - - match = mmc_pwrseq_find(np); - if (IS_ERR(match)) { - ret = PTR_ERR(match); - goto err; - } + pwrseq = of_find_mmc_pwrseq(np); - pwrseq = match->alloc(host, &pdev->dev); - if (IS_ERR(pwrseq)) { - ret = PTR_ERR(pwrseq); - goto err; + if (pwrseq && pwrseq->ops && pwrseq->ops->alloc) { + host->pwrseq = pwrseq; + ret = pwrseq->ops->alloc(host); + if (IS_ERR_VALUE(ret)) { + host->pwrseq = NULL; + goto err; + } } + pwrseq->users++; - host->pwrseq = pwrseq; dev_info(host->parent, "allocated mmc-pwrseq\n"); err: @@ -116,5 +87,32 @@ void mmc_pwrseq_free(struct mmc_host *host) if (pwrseq && pwrseq->ops && pwrseq->ops->free) pwrseq->ops->free(host); + pwrseq->users--; host->pwrseq = NULL; } + +int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq) +{ + if (!pwrseq || !pwrseq->ops || !pwrseq->dev) + return -EINVAL; + + mutex_lock(&pwrseq_list_mutex); + list_add(&pwrseq->list, &pwrseq_list); + mutex_unlock(&pwrseq_list_mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(mmc_pwrseq_register); + +int mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq) +{ + if (!pwrseq->users) { + mutex_lock(&pwrseq_list_mutex); + list_del(&pwrseq->list); + mutex_unlock(&pwrseq_list_mutex); + return 0; + } + + return -EBUSY; +} +EXPORT_SYMBOL_GPL(mmc_pwrseq_unregister); diff --git a/drivers/mmc/core/pwrseq.h b/drivers/mmc/core/pwrseq.h index 096da48c6a7e..462c0abfb651 100644 --- a/drivers/mmc/core/pwrseq.h +++ b/drivers/mmc/core/pwrseq.h @@ -8,7 +8,10 @@ #ifndef _MMC_CORE_PWRSEQ_H #define _MMC_CORE_PWRSEQ_H +#include + struct mmc_pwrseq_ops { + int (*alloc)(struct mmc_host *host); void (*pre_power_on)(struct mmc_host *host); void (*post_power_on)(struct mmc_host *host); void (*power_off)(struct mmc_host *host); @@ -17,23 +20,35 @@ struct mmc_pwrseq_ops { struct mmc_pwrseq { struct mmc_pwrseq_ops *ops; + struct device *dev; + struct list_head list; + int users; + }; #ifdef CONFIG_OF +int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq); +int mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq); + int mmc_pwrseq_alloc(struct mmc_host *host); void mmc_pwrseq_pre_power_on(struct mmc_host *host); void mmc_pwrseq_post_power_on(struct mmc_host *host); void mmc_pwrseq_power_off(struct mmc_host *host); void mmc_pwrseq_free(struct mmc_host *host); -struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host, - struct device *dev); -struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host, - struct device *dev); - #else +static inline int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq) +{ + return -ENOSYS; +} + +static inline int mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq) +{ + return -ENOSYS; +} + static inline int mmc_pwrseq_alloc(struct mmc_host *host) { return 0; } static inline void mmc_pwrseq_pre_power_on(struct mmc_host *host) {} static inline void mmc_pwrseq_post_power_on(struct mmc_host *host) {} diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c index 9d6d2fb21796..0b12bd79ba8e 100644 --- a/drivers/mmc/core/pwrseq_emmc.c +++ b/drivers/mmc/core/pwrseq_emmc.c @@ -9,6 +9,8 @@ */ #include #include +#include +#include #include #include #include @@ -16,7 +18,6 @@ #include #include - #include "pwrseq.h" struct mmc_pwrseq_emmc { @@ -25,6 +26,8 @@ struct mmc_pwrseq_emmc { struct gpio_desc *reset_gpio; }; +#define to_pwrseq_emmc(p) container_of(p, struct mmc_pwrseq_emmc, pwrseq) + static void __mmc_pwrseq_emmc_reset(struct mmc_pwrseq_emmc *pwrseq) { gpiod_set_value(pwrseq->reset_gpio, 1); @@ -35,52 +38,37 @@ static void __mmc_pwrseq_emmc_reset(struct mmc_pwrseq_emmc *pwrseq) static void mmc_pwrseq_emmc_reset(struct mmc_host *host) { - struct mmc_pwrseq_emmc *pwrseq = container_of(host->pwrseq, - struct mmc_pwrseq_emmc, pwrseq); + struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq); __mmc_pwrseq_emmc_reset(pwrseq); } static void mmc_pwrseq_emmc_free(struct mmc_host *host) { - struct mmc_pwrseq_emmc *pwrseq = container_of(host->pwrseq, - struct mmc_pwrseq_emmc, pwrseq); + struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq); unregister_restart_handler(&pwrseq->reset_nb); gpiod_put(pwrseq->reset_gpio); - kfree(pwrseq); } -static struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = { - .post_power_on = mmc_pwrseq_emmc_reset, - .free = mmc_pwrseq_emmc_free, -}; - static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this, unsigned long mode, void *cmd) { struct mmc_pwrseq_emmc *pwrseq = container_of(this, - struct mmc_pwrseq_emmc, reset_nb); + struct mmc_pwrseq_emmc, reset_nb); __mmc_pwrseq_emmc_reset(pwrseq); return NOTIFY_DONE; } -struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host, - struct device *dev) +static int mmc_pwrseq_emmc_alloc(struct mmc_host *host) { - struct mmc_pwrseq_emmc *pwrseq; - int ret = 0; - - pwrseq = kzalloc(sizeof(struct mmc_pwrseq_emmc), GFP_KERNEL); - if (!pwrseq) - return ERR_PTR(-ENOMEM); - - pwrseq->reset_gpio = gpiod_get_index(dev, "reset", 0, GPIOD_OUT_LOW); - if (IS_ERR(pwrseq->reset_gpio)) { - ret = PTR_ERR(pwrseq->reset_gpio); - goto free; - } + struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq); + + pwrseq->reset_gpio = gpiod_get_index(host->pwrseq->dev, + "reset", 0, GPIOD_OUT_LOW); + if (IS_ERR(pwrseq->reset_gpio)) + return PTR_ERR(pwrseq->reset_gpio); /* * register reset handler to ensure emmc reset also from @@ -91,10 +79,53 @@ struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host, pwrseq->reset_nb.priority = 129; register_restart_handler(&pwrseq->reset_nb); + return 0; +} + +static struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = { + .alloc = mmc_pwrseq_emmc_alloc, + .post_power_on = mmc_pwrseq_emmc_reset, + .free = mmc_pwrseq_emmc_free, +}; + +static int mmc_pwrseq_emmc_probe(struct platform_device *pdev) +{ + struct mmc_pwrseq_emmc *pwrseq; + struct device *dev = &pdev->dev; + + pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL); + if (!pwrseq) + return -ENOMEM; + pwrseq->pwrseq.ops = &mmc_pwrseq_emmc_ops; + pwrseq->pwrseq.dev = dev; + + platform_set_drvdata(pdev, pwrseq); - return &pwrseq->pwrseq; -free: - kfree(pwrseq); - return ERR_PTR(ret); + return mmc_pwrseq_register(&pwrseq->pwrseq); } + +static int mmc_pwrseq_emmc_remove(struct platform_device *pdev) +{ + struct mmc_pwrseq_emmc *spwrseq = platform_get_drvdata(pdev); + + return mmc_pwrseq_unregister(&spwrseq->pwrseq); +} + +static const struct of_device_id mmc_pwrseq_emmc_of_match[] = { + { .compatible = "mmc-pwrseq-emmc",}, + {/* sentinel */}, +}; +MODULE_DEVICE_TABLE(of, mmc_pwrseq_emmc_of_match); + +static struct platform_driver mmc_pwrseq_emmc_driver = { + .probe = mmc_pwrseq_emmc_probe, + .remove = mmc_pwrseq_emmc_remove, + .driver = { + .name = "pwrseq_emmc", + .of_match_table = mmc_pwrseq_emmc_of_match, + }, +}; + +module_platform_driver(mmc_pwrseq_emmc_driver); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c index 0b14b83a53d6..f2a7613fd1e5 100644 --- a/drivers/mmc/core/pwrseq_simple.c +++ b/drivers/mmc/core/pwrseq_simple.c @@ -9,6 +9,7 @@ */ #include #include +#include #include #include #include @@ -27,6 +28,8 @@ struct mmc_pwrseq_simple { struct gpio_desc *reset_gpios[0]; }; +#define to_pwrseq_simple(p) container_of(p, struct mmc_pwrseq_simple, pwrseq) + static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq, int value) { @@ -39,8 +42,7 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq, static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host) { - struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq, - struct mmc_pwrseq_simple, pwrseq); + struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); if (!IS_ERR(pwrseq->ext_clk) && !pwrseq->clk_enabled) { clk_prepare_enable(pwrseq->ext_clk); @@ -52,16 +54,14 @@ static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host) static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host) { - struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq, - struct mmc_pwrseq_simple, pwrseq); + struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); mmc_pwrseq_simple_set_gpios_value(pwrseq, 0); } static void mmc_pwrseq_simple_power_off(struct mmc_host *host) { - struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq, - struct mmc_pwrseq_simple, pwrseq); + struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); mmc_pwrseq_simple_set_gpios_value(pwrseq, 1); @@ -73,8 +73,7 @@ static void mmc_pwrseq_simple_power_off(struct mmc_host *host) static void mmc_pwrseq_simple_free(struct mmc_host *host) { - struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq, - struct mmc_pwrseq_simple, pwrseq); + struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); int i; for (i = 0; i < pwrseq->nr_gpios; i++) @@ -84,39 +83,22 @@ static void mmc_pwrseq_simple_free(struct mmc_host *host) if (!IS_ERR(pwrseq->ext_clk)) clk_put(pwrseq->ext_clk); - kfree(pwrseq); } -static struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = { - .pre_power_on = mmc_pwrseq_simple_pre_power_on, - .post_power_on = mmc_pwrseq_simple_post_power_on, - .power_off = mmc_pwrseq_simple_power_off, - .free = mmc_pwrseq_simple_free, -}; - -struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host, - struct device *dev) +int mmc_pwrseq_simple_alloc(struct mmc_host *host) { - struct mmc_pwrseq_simple *pwrseq; - int i, nr_gpios, ret = 0; - - nr_gpios = of_gpio_named_count(dev->of_node, "reset-gpios"); - if (nr_gpios < 0) - nr_gpios = 0; - - pwrseq = kzalloc(sizeof(struct mmc_pwrseq_simple) + nr_gpios * - sizeof(struct gpio_desc *), GFP_KERNEL); - if (!pwrseq) - return ERR_PTR(-ENOMEM); + struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq); + struct device *dev = host->pwrseq->dev; + int i, ret = 0; pwrseq->ext_clk = clk_get(dev, "ext_clock"); if (IS_ERR(pwrseq->ext_clk) && PTR_ERR(pwrseq->ext_clk) != -ENOENT) { - ret = PTR_ERR(pwrseq->ext_clk); - goto free; + return PTR_ERR(pwrseq->ext_clk); + } - for (i = 0; i < nr_gpios; i++) { + for (i = 0; i < pwrseq->nr_gpios; i++) { pwrseq->reset_gpios[i] = gpiod_get_index(dev, "reset", i, GPIOD_OUT_HIGH); if (IS_ERR(pwrseq->reset_gpios[i]) && @@ -127,18 +109,70 @@ struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host, while (i--) gpiod_put(pwrseq->reset_gpios[i]); - goto clk_put; + if (!IS_ERR(pwrseq->ext_clk)) + clk_put(pwrseq->ext_clk); + + return -EINVAL; } } - pwrseq->nr_gpios = nr_gpios; - pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops; - return &pwrseq->pwrseq; -clk_put: - if (!IS_ERR(pwrseq->ext_clk)) - clk_put(pwrseq->ext_clk); -free: - kfree(pwrseq); - return ERR_PTR(ret); + return 0; +} + +static struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = { + .alloc = mmc_pwrseq_simple_alloc, + .pre_power_on = mmc_pwrseq_simple_pre_power_on, + .post_power_on = mmc_pwrseq_simple_post_power_on, + .power_off = mmc_pwrseq_simple_power_off, + .free = mmc_pwrseq_simple_free, +}; + +static const struct of_device_id mmc_pwrseq_simple_of_match[] = { + { .compatible = "mmc-pwrseq-simple",}, + {/* sentinel */}, +}; +MODULE_DEVICE_TABLE(of, mmc_pwrseq_simple_of_match); + +static int mmc_pwrseq_simple_probe(struct platform_device *pdev) +{ + struct mmc_pwrseq_simple *spwrseq; + struct device *dev = &pdev->dev; + int nr_gpios; + + nr_gpios = of_gpio_named_count(dev->of_node, "reset-gpios"); + if (nr_gpios < 0) + nr_gpios = 0; + + spwrseq = devm_kzalloc(dev, sizeof(struct mmc_pwrseq_simple) + nr_gpios * + sizeof(struct gpio_desc *), GFP_KERNEL); + if (!spwrseq) + return -ENOMEM; + + spwrseq->pwrseq.dev = dev; + spwrseq->nr_gpios = nr_gpios; + spwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops; + + platform_set_drvdata(pdev, spwrseq); + + return mmc_pwrseq_register(&spwrseq->pwrseq); } + +static int mmc_pwrseq_simple_remove(struct platform_device *pdev) +{ + struct mmc_pwrseq_simple *spwrseq = platform_get_drvdata(pdev); + + return mmc_pwrseq_unregister(&spwrseq->pwrseq); +} + +static struct platform_driver mmc_pwrseq_simple_driver = { + .probe = mmc_pwrseq_simple_probe, + .remove = mmc_pwrseq_simple_remove, + .driver = { + .name = "pwrseq_simple", + .of_match_table = mmc_pwrseq_simple_of_match, + }, +}; + +module_platform_driver(mmc_pwrseq_simple_driver); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 095e191e4da8cb6fbe44a87ac4beb6be75c77107 Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Wed, 7 Oct 2015 14:28:55 -0700 Subject: mm: Don't offset memmap for flatmem Srinivas Kandagatla reported bad page messages when trying to remove the bottom 2MB on an ARM based IFC6410 board BUG: Bad page state in process swapper pfn:fffa8 page:ef7fb500 count:0 mapcount:0 mapping: (null) index:0x0 flags: 0x96640253(locked|error|dirty|active|arch_1|reclaim|mlocked) page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set bad because of flags: flags: 0x200041(locked|active|mlocked) Modules linked in: CPU: 0 PID: 0 Comm: swapper Not tainted 3.19.0-rc3-00007-g412f9ba-dirty #816 Hardware name: Qualcomm (Flattened Device Tree) [] (unwind_backtrace) from [] (show_stack+0x20/0x24) [] (show_stack) from [] (dump_stack+0x80/0x9c) [] (dump_stack) from [] (bad_page+0xc8/0x128) [] (bad_page) from [] (free_pages_prepare+0x168/0x1e0) [] (free_pages_prepare) from [] (free_hot_cold_page+0x3c/0x174) [] (free_hot_cold_page) from [] (__free_pages+0x54/0x58) [] (__free_pages) from [] (free_highmem_page+0x38/0x88) [] (free_highmem_page) from [] (mem_init+0x240/0x430) [] (mem_init) from [] (start_kernel+0x1e4/0x3c8) [] (start_kernel) from [<80208074>] (0x80208074) Disabling lock debugging due to kernel taint Removing the lower 2MB made the start of the lowmem zone to no longer be page block aligned. IFC6410 uses CONFIG_FLATMEM where alloc_node_mem_map allocates memory for the mem_map. alloc_node_mem_map will offset for unaligned nodes with the assumption the pfn/page translation functions will account for the offset. The functions for CONFIG_FLATMEM do not offset however, resulting in overrunning the memmap array. Just use the allocated memmap without any offset when running with CONFIG_FLATMEM to avoid the overrun. Signed-off-by: Laura Abbott Signed-off-by: Laura Abbott Reported-by: Srinivas Kandagatla Tested-by: Srinivas Kandagatla Acked-by: Vlastimil Babka Tested-by: Bjorn Andersson --- mm/page_alloc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 48aaf7b9f253..19613cb13d1c 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5423,6 +5423,8 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat) static void __init_refok alloc_node_mem_map(struct pglist_data *pgdat) { + unsigned long __maybe_unused offset = 0; + /* Skip empty nodes */ if (!pgdat->node_spanned_pages) return; @@ -5439,6 +5441,7 @@ static void __init_refok alloc_node_mem_map(struct pglist_data *pgdat) * for the buddy allocator to function correctly. */ start = pgdat->node_start_pfn & ~(MAX_ORDER_NR_PAGES - 1); + offset = pgdat->node_start_pfn - start; end = pgdat_end_pfn(pgdat); end = ALIGN(end, MAX_ORDER_NR_PAGES); size = (end - start) * sizeof(struct page); @@ -5446,7 +5449,7 @@ static void __init_refok alloc_node_mem_map(struct pglist_data *pgdat) if (!map) map = memblock_virt_alloc_node_nopanic(size, pgdat->node_id); - pgdat->node_mem_map = map + (pgdat->node_start_pfn - start); + pgdat->node_mem_map = map + offset; } #ifndef CONFIG_NEED_MULTIPLE_NODES /* @@ -5454,9 +5457,9 @@ static void __init_refok alloc_node_mem_map(struct pglist_data *pgdat) */ if (pgdat == NODE_DATA(0)) { mem_map = NODE_DATA(0)->node_mem_map; -#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP +#if defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP) || defined(CONFIG_FLATMEM) if (page_to_pfn(mem_map) != pgdat->node_start_pfn) - mem_map -= (pgdat->node_start_pfn - ARCH_PFN_OFFSET); + mem_map -= offset; #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */ } #endif -- cgit v1.2.3 From 7ce6cefe1102ff36d8f6c07fcf1836fb972cf8d6 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 16 May 2014 11:53:23 -0500 Subject: PCI: qcom: Add support for pcie controllers on IPQ8064 fixed checkpatch warnings too. Signed-off-by: Kumar Gala Signed-off-by: Srinivas Kandagatla --- arch/arm/mach-qcom/Kconfig | 2 + drivers/pci/host/Makefile | 1 + drivers/pci/host/pci-qcom.c | 690 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 693 insertions(+) create mode 100644 drivers/pci/host/pci-qcom.c diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig index 2256cd1e25d1..afa30dd9521d 100644 --- a/arch/arm/mach-qcom/Kconfig +++ b/arch/arm/mach-qcom/Kconfig @@ -4,6 +4,8 @@ menuconfig ARCH_QCOM select ARM_GIC select ARM_AMBA select PINCTRL + select MIGHT_HAVE_PCI + select PCI_DOMAINS if PCI select QCOM_SCM if SMP help Support for Qualcomm's devicetree based systems. diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 140d66f796e4..451d49e3df44 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o +obj-$(CONFIG_PCI_QCOM) += pci-qcom.o diff --git a/drivers/pci/host/pci-qcom.c b/drivers/pci/host/pci-qcom.c new file mode 100644 index 000000000000..d9c9c76c64a2 --- /dev/null +++ b/drivers/pci/host/pci-qcom.c @@ -0,0 +1,690 @@ +/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * QCOM MSM PCIe controller driver. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Root Complex Port vendor/device IDs */ +#define PCIE_VENDOR_ID_RCP 0x17cb +#define PCIE_DEVICE_ID_RCP 0x0101 + +#define __set(v, a, b) (((v) << (b)) & GENMASK(a, b)) + +#define PCIE20_PARF_PCS_DEEMPH 0x34 +#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN1(x) __set(x, 21, 16) +#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x) __set(x, 13, 8) +#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x) __set(x, 5, 0) + +#define PCIE20_PARF_PCS_SWING 0x38 +#define PCIE20_PARF_PCS_SWING_TX_SWING_FULL(x) __set(x, 14, 8) +#define PCIE20_PARF_PCS_SWING_TX_SWING_LOW(x) __set(x, 6, 0) + +#define PCIE20_PARF_PHY_CTRL 0x40 +#define PCIE20_PARF_PHY_CTRL_PHY_TX0_TERM_OFFST(x) __set(x, 20, 16) +#define PCIE20_PARF_PHY_CTRL_PHY_LOS_LEVEL(x) __set(x, 12, 8) +#define PCIE20_PARF_PHY_CTRL_PHY_RTUNE_REQ (1 << 4) +#define PCIE20_PARF_PHY_CTRL_PHY_TEST_BURNIN (1 << 2) +#define PCIE20_PARF_PHY_CTRL_PHY_TEST_BYPASS (1 << 1) +#define PCIE20_PARF_PHY_CTRL_PHY_TEST_PWR_DOWN (1 << 0) + +#define PCIE20_PARF_PHY_REFCLK 0x4C +#define PCIE20_PARF_CONFIG_BITS 0x50 + +#define PCIE20_ELBI_SYS_CTRL 0x04 +#define PCIE20_ELBI_SYS_CTRL_LTSSM_EN 0x01 + +#define PCIE20_CAP 0x70 +#define PCIE20_CAP_LINKCTRLSTATUS (PCIE20_CAP + 0x10) + +#define PCIE20_COMMAND_STATUS 0x04 +#define PCIE20_BUSNUMBERS 0x18 +#define PCIE20_MEMORY_BASE_LIMIT 0x20 + +#define PCIE20_AXI_MSTR_RESP_COMP_CTRL0 0x818 +#define PCIE20_AXI_MSTR_RESP_COMP_CTRL1 0x81c +#define PCIE20_PLR_IATU_VIEWPORT 0x900 +#define PCIE20_PLR_IATU_CTRL1 0x904 +#define PCIE20_PLR_IATU_CTRL2 0x908 +#define PCIE20_PLR_IATU_LBAR 0x90C +#define PCIE20_PLR_IATU_UBAR 0x910 +#define PCIE20_PLR_IATU_LAR 0x914 +#define PCIE20_PLR_IATU_LTAR 0x918 +#define PCIE20_PLR_IATU_UTAR 0x91c + +#define MSM_PCIE_DEV_CFG_ADDR 0x01000000 + +#define RD 0 +#define WR 1 + +#define MAX_RC_NUM 3 +#define PCIE_BUS_PRIV_DATA(pdev) \ + (((struct pci_sys_data *)pdev->bus->sysdata)->private_data) + +/* PCIe TLP types that we are interested in */ +#define PCI_CFG0_RDWR 0x4 +#define PCI_CFG1_RDWR 0x5 + +#define readl_poll_timeout(addr, val, cond, sleep_us, timeout_us) \ +({ \ + unsigned long timeout = jiffies + usecs_to_jiffies(timeout_us); \ + might_sleep_if(timeout_us); \ + for (;;) { \ + (val) = readl(addr); \ + if (cond) \ + break; \ + if (timeout_us && time_after(jiffies, timeout)) { \ + (val) = readl(addr); \ + break; \ + } \ + if (sleep_us) \ + usleep_range(DIV_ROUND_UP(sleep_us, 4), sleep_us); \ + } \ + (cond) ? 0 : -ETIMEDOUT; \ +}) + +struct qcom_pcie { + void __iomem *elbi_base; + void __iomem *parf_base; + void __iomem *dwc_base; + void __iomem *cfg_base; + int reset_gpio; + struct clk *iface_clk; + struct clk *bus_clk; + struct clk *phy_clk; + int irq_int[4]; + struct reset_control *axi_reset; + struct reset_control *ahb_reset; + struct reset_control *por_reset; + struct reset_control *pci_reset; + struct reset_control *phy_reset; + + struct resource conf; + struct resource io; + struct resource mem; +}; + +static int qcom_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); +static int qcom_pcie_setup(int nr, struct pci_sys_data *sys); +static int msm_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, + int size, u32 *val); +static int msm_pcie_wr_conf(struct pci_bus *bus, u32 devfn, + int where, int size, u32 val); + +static struct pci_ops qcom_pcie_ops = { + .read = msm_pcie_rd_conf, + .write = msm_pcie_wr_conf, +}; + +static struct hw_pci qcom_hw_pci[MAX_RC_NUM] = { + { +#ifdef CONFIG_PCI_DOMAINS + .domain = 0, +#endif + .ops = &qcom_pcie_ops, + .nr_controllers = 1, + .swizzle = pci_common_swizzle, + .setup = qcom_pcie_setup, + .map_irq = qcom_pcie_map_irq, + }, + { +#ifdef CONFIG_PCI_DOMAINS + .domain = 1, +#endif + .ops = &qcom_pcie_ops, + .nr_controllers = 1, + .swizzle = pci_common_swizzle, + .setup = qcom_pcie_setup, + .map_irq = qcom_pcie_map_irq, + }, + { +#ifdef CONFIG_PCI_DOMAINS + .domain = 2, +#endif + .ops = &qcom_pcie_ops, + .nr_controllers = 1, + .swizzle = pci_common_swizzle, + .setup = qcom_pcie_setup, + .map_irq = qcom_pcie_map_irq, + }, +}; + +static int nr_controllers; +static DEFINE_SPINLOCK(qcom_hw_pci_lock); + +static inline struct qcom_pcie *sys_to_pcie(struct pci_sys_data *sys) +{ + return sys->private_data; +} + +inline int is_msm_pcie_rc(struct pci_bus *bus) +{ + return (bus->number == 0); +} + +static int qcom_pcie_is_link_up(struct qcom_pcie *dev) +{ + return readl_relaxed(dev->dwc_base + PCIE20_CAP_LINKCTRLSTATUS) & + BIT(29); +} + +inline int msm_pcie_get_cfgtype(struct pci_bus *bus) +{ + /* + * http://www.tldp.org/LDP/tlk/dd/pci.html + * Pass it onto the secondary bus interface unchanged if the + * bus number specified is greater than the secondary bus + * number and less than or equal to the subordinate bus + * number. + * + * Read/Write to the RC and Device/Switch connected to the RC + * are CFG0 type transactions. Rest have to be forwarded + * down stream as CFG1 transactions. + * + */ + if (bus->number == 0) + return PCI_CFG0_RDWR; + + return PCI_CFG0_RDWR; +} + +void msm_pcie_config_cfgtype(struct pci_bus *bus, u32 devfn) +{ + uint32_t bdf, cfgtype; + struct qcom_pcie *dev = sys_to_pcie(bus->sysdata); + + cfgtype = msm_pcie_get_cfgtype(bus); + + if (cfgtype == PCI_CFG0_RDWR) { + bdf = MSM_PCIE_DEV_CFG_ADDR; + } else { + /* + * iATU Lower Target Address Register + * Bits Description + * *-1:0 Forms bits [*:0] of the + * start address of the new + * address of the translated + * region. The start address + * must be aligned to a + * CX_ATU_MIN_REGION_SIZE kB + * boundary, so these bits are + * always 0. A write to this + * location is ignored by the + * PCIe core. + * 31:*1 Forms bits [31:*] of the of + * the new address of the + * translated region. + * + * * is log2(CX_ATU_MIN_REGION_SIZE) + */ + bdf = (((bus->number & 0xff) << 24) & 0xff000000) | + (((devfn & 0xff) << 16) & 0x00ff0000); + } + + writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_VIEWPORT); + wmb(); + + /* Program Bdf Address */ + writel_relaxed(bdf, dev->dwc_base + PCIE20_PLR_IATU_LTAR); + wmb(); + + /* Write Config Request Type */ + writel_relaxed(cfgtype, dev->dwc_base + PCIE20_PLR_IATU_CTRL1); + wmb(); +} + +static inline int msm_pcie_oper_conf(struct pci_bus *bus, u32 devfn, int oper, + int where, int size, u32 *val) +{ + uint32_t word_offset, byte_offset, mask; + uint32_t rd_val, wr_val; + struct qcom_pcie *dev = sys_to_pcie(bus->sysdata); + void __iomem *config_base; + int rc; + + rc = is_msm_pcie_rc(bus); + + /* + * For downstream bus, make sure link is up + */ + if (rc && (devfn != 0)) { + *val = ~0; + return PCIBIOS_DEVICE_NOT_FOUND; + } else if ((!rc) && (!qcom_pcie_is_link_up(dev))) { + *val = ~0; + return PCIBIOS_DEVICE_NOT_FOUND; + } + + msm_pcie_config_cfgtype(bus, devfn); + + word_offset = where & ~0x3; + byte_offset = where & 0x3; + mask = (~0 >> (8 * (4 - size))) << (8 * byte_offset); + + config_base = (rc) ? dev->dwc_base : dev->cfg_base; + rd_val = readl_relaxed(config_base + word_offset); + + if (oper == RD) { + *val = ((rd_val & mask) >> (8 * byte_offset)); + } else { + wr_val = (rd_val & ~mask) | + ((*val << (8 * byte_offset)) & mask); + writel_relaxed(wr_val, config_base + word_offset); + wmb(); /* ensure config data is written to hardware register */ + } + + return 0; +} + +static int msm_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, + int size, u32 *val) +{ + return msm_pcie_oper_conf(bus, devfn, RD, where, size, val); +} + +static int msm_pcie_wr_conf(struct pci_bus *bus, u32 devfn, + int where, int size, u32 val) +{ + /* + *Attempt to reset secondary bus is causing PCIE core to reset. + *Disable secondary bus reset functionality. + */ + if ((bus->number == 0) && (where == PCI_BRIDGE_CONTROL) && + (val & PCI_BRIDGE_CTL_BUS_RESET)) { + pr_info("PCIE secondary bus reset not supported\n"); + val &= ~PCI_BRIDGE_CTL_BUS_RESET; + } + + return msm_pcie_oper_conf(bus, devfn, WR, where, size, &val); +} + +static int qcom_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + struct qcom_pcie *pcie_dev = PCIE_BUS_PRIV_DATA(dev); + + return pcie_dev->irq_int[pin-1]; +} + +static int qcom_pcie_setup(int nr, struct pci_sys_data *sys) +{ + struct qcom_pcie *qcom_pcie = sys->private_data; + + /* + * specify linux PCI framework to allocate device memory (BARs) + * from msm_pcie_dev.dev_mem_res resource. + */ + sys->mem_offset = 0; + sys->io_offset = 0; + + pci_add_resource(&sys->resources, &qcom_pcie->mem); + pci_add_resource(&sys->resources, &qcom_pcie->io); + + return 1; +} + +static inline void qcom_elbi_writel_relaxed(struct qcom_pcie *pcie, + u32 val, u32 reg) +{ + writel_relaxed(val, pcie->elbi_base + reg); +} + +static inline u32 qcom_elbi_readl_relaxed(struct qcom_pcie *pcie, u32 reg) +{ + return readl_relaxed(pcie->elbi_base + reg); +} + +static inline void qcom_parf_writel_relaxed(struct qcom_pcie *pcie, + u32 val, u32 reg) +{ + writel_relaxed(val, pcie->parf_base + reg); +} + +static inline u32 qcom_parf_readl_relaxed(struct qcom_pcie *pcie, u32 reg) +{ + return readl_relaxed(pcie->parf_base + reg); +} + +static void msm_pcie_write_mask(void __iomem *addr, + uint32_t clear_mask, uint32_t set_mask) +{ + uint32_t val; + + val = (readl_relaxed(addr) & ~clear_mask) | set_mask; + writel_relaxed(val, addr); + wmb(); /* ensure data is written to hardware register */ +} + +static void qcom_pcie_config_controller(struct qcom_pcie *dev) +{ + /* + * program and enable address translation region 0 (device config + * address space); region type config; + * axi config address range to device config address range + */ + writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_VIEWPORT); + /* ensure that hardware locks the region before programming it */ + wmb(); + + writel_relaxed(4, dev->dwc_base + PCIE20_PLR_IATU_CTRL1); + writel_relaxed(BIT(31), dev->dwc_base + PCIE20_PLR_IATU_CTRL2); + writel_relaxed(dev->conf.start, dev->dwc_base + PCIE20_PLR_IATU_LBAR); + writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UBAR); + writel_relaxed(dev->conf.end, dev->dwc_base + PCIE20_PLR_IATU_LAR); + writel_relaxed(MSM_PCIE_DEV_CFG_ADDR, + dev->dwc_base + PCIE20_PLR_IATU_LTAR); + writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UTAR); + /* ensure that hardware registers the configuration */ + wmb(); + + /* + * program and enable address translation region 2 (device resource + * address space); region type memory; + * axi device bar address range to device bar address range + */ + writel_relaxed(2, dev->dwc_base + PCIE20_PLR_IATU_VIEWPORT); + /* ensure that hardware locks the region before programming it */ + wmb(); + + writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_CTRL1); + writel_relaxed(BIT(31), dev->dwc_base + PCIE20_PLR_IATU_CTRL2); + writel_relaxed(dev->mem.start, dev->dwc_base + PCIE20_PLR_IATU_LBAR); + writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UBAR); + writel_relaxed(dev->mem.end, dev->dwc_base + PCIE20_PLR_IATU_LAR); + writel_relaxed(dev->mem.start, + dev->dwc_base + PCIE20_PLR_IATU_LTAR); + writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UTAR); + /* ensure that hardware registers the configuration */ + wmb(); + + /* 1K PCIE buffer setting */ + writel_relaxed(0x3, dev->dwc_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL0); + writel_relaxed(0x1, dev->dwc_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL1); + /* ensure that hardware registers the configuration */ + wmb(); +} + +static int qcom_pcie_probe(struct platform_device *pdev) +{ + unsigned long flags; + struct qcom_pcie *qcom_pcie; + struct device_node *np = pdev->dev.of_node; + struct resource *elbi_base, *parf_base, *dwc_base; + struct hw_pci *hw; + struct of_pci_range range; + struct of_pci_range_parser parser; + int ret, i; + u32 val; + + qcom_pcie = devm_kzalloc(&pdev->dev, sizeof(*qcom_pcie), GFP_KERNEL); + if (!qcom_pcie) { + dev_err(&pdev->dev, "no memory for qcom_pcie\n"); + return -ENOMEM; + } + + elbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi"); + qcom_pcie->elbi_base = devm_ioremap_resource(&pdev->dev, elbi_base); + if (IS_ERR(qcom_pcie->elbi_base)) { + dev_err(&pdev->dev, "Failed to ioremap elbi space\n"); + return PTR_ERR(qcom_pcie->elbi_base); + } + + parf_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "parf"); + qcom_pcie->parf_base = devm_ioremap_resource(&pdev->dev, parf_base); + if (IS_ERR(qcom_pcie->parf_base)) { + dev_err(&pdev->dev, "Failed to ioremap parf space\n"); + return PTR_ERR(qcom_pcie->parf_base); + } + + dwc_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "base"); + qcom_pcie->dwc_base = devm_ioremap_resource(&pdev->dev, dwc_base); + if (IS_ERR(qcom_pcie->dwc_base)) { + dev_err(&pdev->dev, "Failed to ioremap dwc_base space\n"); + return PTR_ERR(qcom_pcie->dwc_base); + } + + if (of_pci_range_parser_init(&parser, np)) { + dev_err(&pdev->dev, "missing ranges property\n"); + return -EINVAL; + } + + /* Get the I/O and memory ranges from DT */ + for_each_of_pci_range(&parser, &range) { + switch (range.pci_space & 0x3) { + case 0: /* cfg */ + of_pci_range_to_resource(&range, np, &qcom_pcie->conf); + qcom_pcie->conf.flags = IORESOURCE_MEM; + break; + case 1: /* io */ + of_pci_range_to_resource(&range, np, &qcom_pcie->io); + break; + default: /* mem */ + of_pci_range_to_resource(&range, np, &qcom_pcie->mem); + break; + } + } + + qcom_pcie->cfg_base = devm_ioremap_resource(&pdev->dev, + &qcom_pcie->conf); + if (IS_ERR(qcom_pcie->cfg_base)) { + dev_err(&pdev->dev, "Failed to ioremap PCIe cfg space\n"); + return PTR_ERR(qcom_pcie->cfg_base); + } + + qcom_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); + if (!gpio_is_valid(qcom_pcie->reset_gpio)) { + dev_err(&pdev->dev, "pcie reset gpio is not valid\n"); + return -EINVAL; + } + + ret = devm_gpio_request_one(&pdev->dev, qcom_pcie->reset_gpio, + GPIOF_DIR_OUT, "pcie_reset"); + if (ret) { + dev_err(&pdev->dev, "Failed to request pcie reset gpio\n"); + return ret; + } + + qcom_pcie->iface_clk = devm_clk_get(&pdev->dev, "iface"); + if (IS_ERR(qcom_pcie->iface_clk)) { + dev_err(&pdev->dev, "Failed to get pcie iface clock\n"); + return PTR_ERR(qcom_pcie->iface_clk); + } + + qcom_pcie->phy_clk = devm_clk_get(&pdev->dev, "phy"); + if (IS_ERR(qcom_pcie->phy_clk)) { + dev_err(&pdev->dev, "Failed to get pcie phy clock\n"); + return PTR_ERR(qcom_pcie->phy_clk); + } + + qcom_pcie->bus_clk = devm_clk_get(&pdev->dev, "core"); + if (IS_ERR(qcom_pcie->bus_clk)) { + dev_err(&pdev->dev, "Failed to get pcie core clock\n"); + return PTR_ERR(qcom_pcie->bus_clk); + } + + qcom_pcie->axi_reset = devm_reset_control_get(&pdev->dev, "axi"); + if (IS_ERR(qcom_pcie->axi_reset)) { + dev_err(&pdev->dev, "Failed to get axi reset\n"); + return PTR_ERR(qcom_pcie->axi_reset); + } + + qcom_pcie->ahb_reset = devm_reset_control_get(&pdev->dev, "ahb"); + if (IS_ERR(qcom_pcie->ahb_reset)) { + dev_err(&pdev->dev, "Failed to get ahb reset\n"); + return PTR_ERR(qcom_pcie->ahb_reset); + } + + qcom_pcie->por_reset = devm_reset_control_get(&pdev->dev, "por"); + if (IS_ERR(qcom_pcie->por_reset)) { + dev_err(&pdev->dev, "Failed to get por reset\n"); + return PTR_ERR(qcom_pcie->por_reset); + } + + qcom_pcie->pci_reset = devm_reset_control_get(&pdev->dev, "pci"); + if (IS_ERR(qcom_pcie->pci_reset)) { + dev_err(&pdev->dev, "Failed to get pci reset\n"); + return PTR_ERR(qcom_pcie->pci_reset); + } + + qcom_pcie->phy_reset = devm_reset_control_get(&pdev->dev, "phy"); + if (IS_ERR(qcom_pcie->phy_reset)) { + dev_err(&pdev->dev, "Failed to get phy reset\n"); + return PTR_ERR(qcom_pcie->phy_reset); + } + + for (i = 0; i < 4; i++) { + qcom_pcie->irq_int[i] = platform_get_irq(pdev, i+1); + if (qcom_pcie->irq_int[i] < 0) { + dev_err(&pdev->dev, "failed to get irq resource\n"); + return qcom_pcie->irq_int[i]; + } + } + + gpio_set_value(qcom_pcie->reset_gpio, 0); + usleep_range(10000, 15000); + + /* assert PCIe PARF reset while powering the core */ + reset_control_assert(qcom_pcie->ahb_reset); + + /* enable clocks */ + ret = clk_prepare_enable(qcom_pcie->iface_clk); + if (ret) + return ret; + ret = clk_prepare_enable(qcom_pcie->phy_clk); + if (ret) + return ret; + ret = clk_prepare_enable(qcom_pcie->bus_clk); + if (ret) + return ret; + + /* + * de-assert PCIe PARF reset; + * wait 1us before accessing PARF registers + */ + reset_control_deassert(qcom_pcie->ahb_reset); + udelay(1); + + /* enable PCIe clocks and resets */ + msm_pcie_write_mask(qcom_pcie->parf_base + PCIE20_PARF_PHY_CTRL, + BIT(0), 0); + + /* Set Tx Termination Offset */ + val = qcom_parf_readl_relaxed(qcom_pcie, PCIE20_PARF_PHY_CTRL); + val |= PCIE20_PARF_PHY_CTRL_PHY_TX0_TERM_OFFST(7); + qcom_parf_writel_relaxed(qcom_pcie, val, PCIE20_PARF_PHY_CTRL); + + /* PARF programming */ + qcom_parf_writel_relaxed(qcom_pcie, + PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN1(0x18) | + PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(0x18) | + PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(0x22), + PCIE20_PARF_PCS_DEEMPH); + qcom_parf_writel_relaxed(qcom_pcie, + PCIE20_PARF_PCS_SWING_TX_SWING_FULL(0x78) | + PCIE20_PARF_PCS_SWING_TX_SWING_LOW(0x78), + PCIE20_PARF_PCS_SWING); + qcom_parf_writel_relaxed(qcom_pcie, (4<<24), PCIE20_PARF_CONFIG_BITS); + /* ensure that hardware registers the PARF configuration */ + wmb(); + + /* enable reference clock */ + msm_pcie_write_mask(qcom_pcie->parf_base + PCIE20_PARF_PHY_REFCLK, + BIT(12), BIT(16)); + + /* ensure that access is enabled before proceeding */ + wmb(); + + /* de-assert PICe PHY, Core, POR and AXI clk domain resets */ + reset_control_deassert(qcom_pcie->phy_reset); + reset_control_deassert(qcom_pcie->pci_reset); + reset_control_deassert(qcom_pcie->por_reset); + reset_control_deassert(qcom_pcie->axi_reset); + + /* wait 150ms for clock acquisition */ + usleep_range(10000, 15000); + + /* de-assert PCIe reset link to bring EP out of reset */ + gpio_set_value(qcom_pcie->reset_gpio, 1 - 0); + usleep_range(10000, 15000); + + /* enable link training */ + val = qcom_elbi_readl_relaxed(qcom_pcie, PCIE20_ELBI_SYS_CTRL); + val |= PCIE20_ELBI_SYS_CTRL_LTSSM_EN; + qcom_elbi_writel_relaxed(qcom_pcie, val, PCIE20_ELBI_SYS_CTRL); + wmb(); + + /* poll for link to come up for upto 100ms */ + ret = readl_poll_timeout( + (qcom_pcie->dwc_base + PCIE20_CAP_LINKCTRLSTATUS), + val, (val & BIT(29)), 10000, 100000); + + dev_info(&pdev->dev, "link initialized %d\n", ret); + + qcom_pcie_config_controller(qcom_pcie); + + platform_set_drvdata(pdev, qcom_pcie); + + spin_lock_irqsave(&qcom_hw_pci_lock, flags); + qcom_hw_pci[nr_controllers].private_data = (void **)&qcom_pcie; + hw = &qcom_hw_pci[nr_controllers]; + nr_controllers++; + spin_unlock_irqrestore(&qcom_hw_pci_lock, flags); + + pci_common_init(hw); + + return 0; +} + +static int __exit qcom_pcie_remove(struct platform_device *pdev) +{ + struct qcom_pcie *qcom_pcie = platform_get_drvdata(pdev); + + return 0; +} + +static struct of_device_id qcom_pcie_match[] = { + { .compatible = "qcom,pcie-ipq8064", }, + {} +}; + +static struct platform_driver qcom_pcie_driver = { + .probe = qcom_pcie_probe, + .remove = qcom_pcie_remove, + .driver = { + .name = "qcom_pcie", + .owner = THIS_MODULE, + .of_match_table = qcom_pcie_match, + }, +}; + +static int qcom_pcie_init(void) +{ + return platform_driver_register(&qcom_pcie_driver); +} +subsys_initcall(qcom_pcie_init); + +/* RC do not represent the right class; set it to PCI_CLASS_BRIDGE_PCI */ +static void msm_pcie_fixup_early(struct pci_dev *dev) +{ + if (dev->hdr_type == 1) + dev->class = (dev->class & 0xff) | (PCI_CLASS_BRIDGE_PCI << 8); +} +DECLARE_PCI_FIXUP_EARLY(PCIE_VENDOR_ID_RCP, PCIE_DEVICE_ID_RCP, msm_pcie_fixup_early); -- cgit v1.2.3 From 26c9e990d05ab2b8304c7eb02f1d01286d9c87a1 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 8 Jul 2014 10:11:32 +0100 Subject: pci: qcom: fix a typo in reset gpio This patch fixes a typo in gpio reset code. Signed-off-by: Srinivas Kandagatla --- drivers/pci/host/pci-qcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/host/pci-qcom.c b/drivers/pci/host/pci-qcom.c index d9c9c76c64a2..3a7e30939425 100644 --- a/drivers/pci/host/pci-qcom.c +++ b/drivers/pci/host/pci-qcom.c @@ -622,7 +622,7 @@ static int qcom_pcie_probe(struct platform_device *pdev) usleep_range(10000, 15000); /* de-assert PCIe reset link to bring EP out of reset */ - gpio_set_value(qcom_pcie->reset_gpio, 1 - 0); + gpio_set_value(qcom_pcie->reset_gpio, 1); usleep_range(10000, 15000); /* enable link training */ -- cgit v1.2.3 From b286f774a8d4f77a0dc966eb0c5455fbcf4dce22 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 8 Jul 2014 10:14:01 +0100 Subject: pci: qcom: fix unused variable warning. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes warning: unused variable ‘qcom_pcie’ in the remove code. Signed-off-by: Srinivas Kandagatla --- drivers/pci/host/pci-qcom.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/pci/host/pci-qcom.c b/drivers/pci/host/pci-qcom.c index 3a7e30939425..9a6072ce6cde 100644 --- a/drivers/pci/host/pci-qcom.c +++ b/drivers/pci/host/pci-qcom.c @@ -655,8 +655,6 @@ static int qcom_pcie_probe(struct platform_device *pdev) static int __exit qcom_pcie_remove(struct platform_device *pdev) { - struct qcom_pcie *qcom_pcie = platform_get_drvdata(pdev); - return 0; } -- cgit v1.2.3 From 3f499a07c6474c16c99c25c8c671fcea5e7fb122 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 8 Jul 2014 13:12:02 +0100 Subject: pci: qcom: move dt parsing code out of probe This patch is a cleanup patch to probe function, as the code in probe function exceeds more than 200 lines, so its better to split it for better reablity and easy in future to add new code for regulators. Signed-off-by: Srinivas Kandagatla --- drivers/pci/host/pci-qcom.c | 48 ++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/drivers/pci/host/pci-qcom.c b/drivers/pci/host/pci-qcom.c index 9a6072ce6cde..9b0d48b3e02e 100644 --- a/drivers/pci/host/pci-qcom.c +++ b/drivers/pci/host/pci-qcom.c @@ -422,23 +422,14 @@ static void qcom_pcie_config_controller(struct qcom_pcie *dev) wmb(); } -static int qcom_pcie_probe(struct platform_device *pdev) +static int qcom_pcie_parse_dt(struct qcom_pcie *qcom_pcie, + struct platform_device *pdev) { - unsigned long flags; - struct qcom_pcie *qcom_pcie; struct device_node *np = pdev->dev.of_node; struct resource *elbi_base, *parf_base, *dwc_base; - struct hw_pci *hw; struct of_pci_range range; struct of_pci_range_parser parser; int ret, i; - u32 val; - - qcom_pcie = devm_kzalloc(&pdev->dev, sizeof(*qcom_pcie), GFP_KERNEL); - if (!qcom_pcie) { - dev_err(&pdev->dev, "no memory for qcom_pcie\n"); - return -ENOMEM; - } elbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi"); qcom_pcie->elbi_base = devm_ioremap_resource(&pdev->dev, elbi_base); @@ -482,13 +473,6 @@ static int qcom_pcie_probe(struct platform_device *pdev) } } - qcom_pcie->cfg_base = devm_ioremap_resource(&pdev->dev, - &qcom_pcie->conf); - if (IS_ERR(qcom_pcie->cfg_base)) { - dev_err(&pdev->dev, "Failed to ioremap PCIe cfg space\n"); - return PTR_ERR(qcom_pcie->cfg_base); - } - qcom_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); if (!gpio_is_valid(qcom_pcie->reset_gpio)) { dev_err(&pdev->dev, "pcie reset gpio is not valid\n"); @@ -558,6 +542,34 @@ static int qcom_pcie_probe(struct platform_device *pdev) } } + return 0; +} + +static int qcom_pcie_probe(struct platform_device *pdev) +{ + unsigned long flags; + struct qcom_pcie *qcom_pcie; + struct hw_pci *hw; + int ret; + u32 val; + + qcom_pcie = devm_kzalloc(&pdev->dev, sizeof(*qcom_pcie), GFP_KERNEL); + if (!qcom_pcie) { + dev_err(&pdev->dev, "no memory for qcom_pcie\n"); + return -ENOMEM; + } + + ret = qcom_pcie_parse_dt(qcom_pcie, pdev); + if (IS_ERR_VALUE(ret)) + return ret; + + qcom_pcie->cfg_base = devm_ioremap_resource(&pdev->dev, + &qcom_pcie->conf); + if (IS_ERR(qcom_pcie->cfg_base)) { + dev_err(&pdev->dev, "Failed to ioremap PCIe cfg space\n"); + return PTR_ERR(qcom_pcie->cfg_base); + } + gpio_set_value(qcom_pcie->reset_gpio, 0); usleep_range(10000, 15000); -- cgit v1.2.3 From bba288a932980272740f61d95db16d9b3b8bb4da Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 8 Jul 2014 13:15:26 +0100 Subject: pci: qcom: Add regulator support This patch adds regulator support to the driver. There are 3 regulators VDD, AVDD and V3P3_PCIECLK which are necessary for pci IP to work. Signed-off-by: Srinivas Kandagatla --- drivers/pci/host/pci-qcom.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/drivers/pci/host/pci-qcom.c b/drivers/pci/host/pci-qcom.c index 9b0d48b3e02e..665943baed4e 100644 --- a/drivers/pci/host/pci-qcom.c +++ b/drivers/pci/host/pci-qcom.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -107,6 +108,7 @@ struct qcom_pcie { void __iomem *parf_base; void __iomem *dwc_base; void __iomem *cfg_base; + struct device *dev; int reset_gpio; struct clk *iface_clk; struct clk *bus_clk; @@ -121,6 +123,11 @@ struct qcom_pcie { struct resource conf; struct resource io; struct resource mem; + + struct regulator *vdd_supply; + struct regulator *avdd_supply; + struct regulator *pcie_clk_supply; + }; static int qcom_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); @@ -422,6 +429,32 @@ static void qcom_pcie_config_controller(struct qcom_pcie *dev) wmb(); } +static int qcom_pcie_vreg_on(struct qcom_pcie *qcom_pcie) +{ + int err; + /* enable regulators */ + err = regulator_enable(qcom_pcie->vdd_supply); + if (err < 0) { + dev_err(qcom_pcie->dev, "failed to enable VDD regulator\n"); + return err; + } + + err = regulator_enable(qcom_pcie->pcie_clk_supply); + if (err < 0) { + dev_err(qcom_pcie->dev, "failed to enable pcie-clk regulator\n"); + return err; + } + + err = regulator_enable(qcom_pcie->avdd_supply); + if (err < 0) { + dev_err(qcom_pcie->dev, "failed to enable AVDD regulator\n"); + return err; + } + + return err; + +} + static int qcom_pcie_parse_dt(struct qcom_pcie *qcom_pcie, struct platform_device *pdev) { @@ -473,6 +506,24 @@ static int qcom_pcie_parse_dt(struct qcom_pcie *qcom_pcie, } } + qcom_pcie->vdd_supply = devm_regulator_get(&pdev->dev, "vdd"); + if (IS_ERR(qcom_pcie->vdd_supply)) { + dev_err(&pdev->dev, "Failed to get vdd supply\n"); + return PTR_ERR(qcom_pcie->vdd_supply); + } + + qcom_pcie->pcie_clk_supply = devm_regulator_get(&pdev->dev, "pcie-clk"); + if (IS_ERR(qcom_pcie->pcie_clk_supply)) { + dev_err(&pdev->dev, "Failed to get pcie clk supply\n"); + return PTR_ERR(qcom_pcie->pcie_clk_supply); + } + qcom_pcie->avdd_supply = devm_regulator_get(&pdev->dev, "avdd"); + if (IS_ERR(qcom_pcie->avdd_supply)) { + dev_err(&pdev->dev, "Failed to get avdd supply\n"); + return PTR_ERR(qcom_pcie->avdd_supply); + } + + qcom_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); if (!gpio_is_valid(qcom_pcie->reset_gpio)) { dev_err(&pdev->dev, "pcie reset gpio is not valid\n"); @@ -558,6 +609,7 @@ static int qcom_pcie_probe(struct platform_device *pdev) dev_err(&pdev->dev, "no memory for qcom_pcie\n"); return -ENOMEM; } + qcom_pcie->dev = &pdev->dev; ret = qcom_pcie_parse_dt(qcom_pcie, pdev); if (IS_ERR_VALUE(ret)) @@ -573,6 +625,8 @@ static int qcom_pcie_probe(struct platform_device *pdev) gpio_set_value(qcom_pcie->reset_gpio, 0); usleep_range(10000, 15000); + /* enable power */ + qcom_pcie_vreg_on(qcom_pcie); /* assert PCIe PARF reset while powering the core */ reset_control_assert(qcom_pcie->ahb_reset); -- cgit v1.2.3 From 6fc62efcd55fa7575400016d13dd7c83cdee3675 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 8 Jul 2014 14:16:14 +0100 Subject: pci: qcom: remove static declaration of functions. This patch removes declaration of the local function, by re-ordering the usage. Signed-off-by: Srinivas Kandagatla --- drivers/pci/host/pci-qcom.c | 84 +++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 45 deletions(-) diff --git a/drivers/pci/host/pci-qcom.c b/drivers/pci/host/pci-qcom.c index 665943baed4e..5b49bfde3351 100644 --- a/drivers/pci/host/pci-qcom.c +++ b/drivers/pci/host/pci-qcom.c @@ -130,51 +130,6 @@ struct qcom_pcie { }; -static int qcom_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); -static int qcom_pcie_setup(int nr, struct pci_sys_data *sys); -static int msm_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, - int size, u32 *val); -static int msm_pcie_wr_conf(struct pci_bus *bus, u32 devfn, - int where, int size, u32 val); - -static struct pci_ops qcom_pcie_ops = { - .read = msm_pcie_rd_conf, - .write = msm_pcie_wr_conf, -}; - -static struct hw_pci qcom_hw_pci[MAX_RC_NUM] = { - { -#ifdef CONFIG_PCI_DOMAINS - .domain = 0, -#endif - .ops = &qcom_pcie_ops, - .nr_controllers = 1, - .swizzle = pci_common_swizzle, - .setup = qcom_pcie_setup, - .map_irq = qcom_pcie_map_irq, - }, - { -#ifdef CONFIG_PCI_DOMAINS - .domain = 1, -#endif - .ops = &qcom_pcie_ops, - .nr_controllers = 1, - .swizzle = pci_common_swizzle, - .setup = qcom_pcie_setup, - .map_irq = qcom_pcie_map_irq, - }, - { -#ifdef CONFIG_PCI_DOMAINS - .domain = 2, -#endif - .ops = &qcom_pcie_ops, - .nr_controllers = 1, - .swizzle = pci_common_swizzle, - .setup = qcom_pcie_setup, - .map_irq = qcom_pcie_map_irq, - }, -}; - static int nr_controllers; static DEFINE_SPINLOCK(qcom_hw_pci_lock); @@ -348,6 +303,45 @@ static int qcom_pcie_setup(int nr, struct pci_sys_data *sys) return 1; } +static struct pci_ops qcom_pcie_ops = { + .read = msm_pcie_rd_conf, + .write = msm_pcie_wr_conf, +}; + +static struct hw_pci qcom_hw_pci[MAX_RC_NUM] = { + { +#ifdef CONFIG_PCI_DOMAINS + .domain = 0, +#endif + .ops = &qcom_pcie_ops, + .nr_controllers = 1, + .swizzle = pci_common_swizzle, + .setup = qcom_pcie_setup, + .map_irq = qcom_pcie_map_irq, + .add_bus = qcom_pcie_add_bus, + }, + { +#ifdef CONFIG_PCI_DOMAINS + .domain = 1, +#endif + .ops = &qcom_pcie_ops, + .nr_controllers = 1, + .swizzle = pci_common_swizzle, + .setup = qcom_pcie_setup, + .map_irq = qcom_pcie_map_irq, + }, + { +#ifdef CONFIG_PCI_DOMAINS + .domain = 2, +#endif + .ops = &qcom_pcie_ops, + .nr_controllers = 1, + .swizzle = pci_common_swizzle, + .setup = qcom_pcie_setup, + .map_irq = qcom_pcie_map_irq, + }, +}; + static inline void qcom_elbi_writel_relaxed(struct qcom_pcie *pcie, u32 val, u32 reg) { -- cgit v1.2.3 From 772b10f74c65d0bc0b020ef4d4a5abda06409c98 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 8 Jul 2014 14:17:27 +0100 Subject: pci: qcom: Add support to external phy reference clk. This patch adds support to configuration which use external phy reference clk, this option is now available via dt using "qcom,external-phy-refclk" property. Without this option the driver will always configure the phy to use internal clk which will not work for SOCs like APQ8064 which uses external phy reference clock on IFC6410 board. Signed-off-by: Srinivas Kandagatla --- drivers/pci/host/pci-qcom.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/pci/host/pci-qcom.c b/drivers/pci/host/pci-qcom.c index 5b49bfde3351..38d14c0040d2 100644 --- a/drivers/pci/host/pci-qcom.c +++ b/drivers/pci/host/pci-qcom.c @@ -110,6 +110,7 @@ struct qcom_pcie { void __iomem *cfg_base; struct device *dev; int reset_gpio; + bool ext_phy_ref_clk; struct clk *iface_clk; struct clk *bus_clk; struct clk *phy_clk; @@ -458,6 +459,9 @@ static int qcom_pcie_parse_dt(struct qcom_pcie *qcom_pcie, struct of_pci_range_parser parser; int ret, i; + qcom_pcie->ext_phy_ref_clk = of_property_read_bool(np, + "qcom,external-phy-refclk"); + elbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi"); qcom_pcie->elbi_base = devm_ioremap_resource(&pdev->dev, elbi_base); if (IS_ERR(qcom_pcie->elbi_base)) { @@ -667,7 +671,8 @@ static int qcom_pcie_probe(struct platform_device *pdev) /* enable reference clock */ msm_pcie_write_mask(qcom_pcie->parf_base + PCIE20_PARF_PHY_REFCLK, - BIT(12), BIT(16)); + qcom_pcie->ext_phy_ref_clk ? 0 : BIT(12), + BIT(16)); /* ensure that access is enabled before proceeding */ wmb(); -- cgit v1.2.3 From 62cc41357ff4ce520b095c5aa7a7415327f4920e Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 8 Jul 2014 14:22:27 +0100 Subject: pci: qcom: add msi support This patch adds msi support using irq domain in the driver, this is required to get ethernet working on IFC6410 board. Signed-off-by: Srinivas Kandagatla --- drivers/pci/host/pci-qcom.c | 212 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 211 insertions(+), 1 deletion(-) diff --git a/drivers/pci/host/pci-qcom.c b/drivers/pci/host/pci-qcom.c index 38d14c0040d2..ed01a27f8f47 100644 --- a/drivers/pci/host/pci-qcom.c +++ b/drivers/pci/host/pci-qcom.c @@ -17,7 +17,11 @@ #include #include #include +#include +#include +#include #include +#include #include #include #include @@ -25,6 +29,16 @@ #include #include +#define INT_PCI_MSI_NR (8 * 32) +#define MSM_PCIE_MSI_PHY 0xa0000000 + +#define PCIE20_MSI_CTRL_ADDR (0x820) +#define PCIE20_MSI_CTRL_UPPER_ADDR (0x824) +#define PCIE20_MSI_CTRL_INTR_EN (0x828) +#define PCIE20_MSI_CTRL_INTR_MASK (0x82C) +#define PCIE20_MSI_CTRL_INTR_STATUS (0x830) + +#define PCIE20_MSI_CTRL_MAX 8 /* Root Complex Port vendor/device IDs */ #define PCIE_VENDOR_ID_RCP 0x17cb #define PCIE_DEVICE_ID_RCP 0x0101 @@ -103,6 +117,15 @@ (cond) ? 0 : -ETIMEDOUT; \ }) +struct qcom_msi { + struct msi_controller chip; + DECLARE_BITMAP(used, INT_PCI_MSI_NR); + struct irq_domain *domain; + unsigned long pages; + struct mutex lock; + int irq; +}; + struct qcom_pcie { void __iomem *elbi_base; void __iomem *parf_base; @@ -129,6 +152,7 @@ struct qcom_pcie { struct regulator *avdd_supply; struct regulator *pcie_clk_supply; + struct qcom_msi msi; }; static int nr_controllers; @@ -139,6 +163,7 @@ static inline struct qcom_pcie *sys_to_pcie(struct pci_sys_data *sys) return sys->private_data; } + inline int is_msm_pcie_rc(struct pci_bus *bus) { return (bus->number == 0); @@ -319,7 +344,6 @@ static struct hw_pci qcom_hw_pci[MAX_RC_NUM] = { .swizzle = pci_common_swizzle, .setup = qcom_pcie_setup, .map_irq = qcom_pcie_map_irq, - .add_bus = qcom_pcie_add_bus, }, { #ifdef CONFIG_PCI_DOMAINS @@ -424,6 +448,187 @@ static void qcom_pcie_config_controller(struct qcom_pcie *dev) wmb(); } +static int qcom_msi_alloc(struct qcom_msi *chip) +{ + int msi; + + mutex_lock(&chip->lock); + + msi = find_first_zero_bit(chip->used, INT_PCI_MSI_NR); + if (msi < INT_PCI_MSI_NR) + set_bit(msi, chip->used); + else + msi = -ENOSPC; + + mutex_unlock(&chip->lock); + + return msi; +} + +static void qcom_msi_free(struct qcom_msi *chip, unsigned long irq) +{ + struct device *dev = chip->chip.dev; + + mutex_lock(&chip->lock); + + if (!test_bit(irq, chip->used)) + dev_err(dev, "trying to free unused MSI#%lu\n", irq); + else + clear_bit(irq, chip->used); + + mutex_unlock(&chip->lock); +} + + +static irqreturn_t handle_msi_irq(int irq, void *data) +{ + int i, j, index; + unsigned long val; + struct qcom_pcie *dev = data; + void __iomem *ctrl_status; + struct qcom_msi *msi = &dev->msi; + + /* check for set bits, clear it by setting that bit + and trigger corresponding irq */ + for (i = 0; i < PCIE20_MSI_CTRL_MAX; i++) { + ctrl_status = dev->dwc_base + + PCIE20_MSI_CTRL_INTR_STATUS + (i * 12); + + val = readl_relaxed(ctrl_status); + while (val) { + j = find_first_bit(&val, 32); + index = j + (32 * i); + writel_relaxed(BIT(j), ctrl_status); + /* ensure that interrupt is cleared (acked) */ + wmb(); + + irq = irq_find_mapping(msi->domain, index); + if (irq) { + if (test_bit(index, msi->used)) + generic_handle_irq(irq); + else + dev_info(dev->dev, "unhandled MSI\n"); + } + val = readl_relaxed(ctrl_status); + } + } + + return IRQ_HANDLED; +} + +static inline struct qcom_msi *to_qcom_msi(struct msi_controller *chip) +{ + return container_of(chip, struct qcom_msi, chip); +} + +static int qcom_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev, + struct msi_desc *desc) +{ + struct qcom_msi *msi = to_qcom_msi(chip); + struct msi_msg msg; + unsigned int irq; + int hwirq; + + hwirq = qcom_msi_alloc(msi); + if (hwirq < 0) + return hwirq; + + irq = irq_create_mapping(msi->domain, hwirq); + if (!irq) + return -EINVAL; + + irq_set_msi_desc(irq, desc); + + msg.address_lo = MSM_PCIE_MSI_PHY; + /* 32 bit address only */ + msg.address_hi = 0; + msg.data = hwirq; + + write_msi_msg(irq, &msg); + + return 0; +} + +static void qcom_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) +{ + struct qcom_msi *msi = to_qcom_msi(chip); + struct irq_data *d = irq_get_irq_data(irq); + + qcom_msi_free(msi, d->hwirq); +} + +static struct irq_chip qcom_msi_irq_chip = { + .name = "PCI-MSI", + .irq_enable = unmask_msi_irq, + .irq_disable = mask_msi_irq, + .irq_mask = mask_msi_irq, + .irq_unmask = unmask_msi_irq, +}; + + +static int qcom_pcie_msi_map(struct irq_domain *domain, unsigned int irq, + irq_hw_number_t hwirq) +{ + irq_set_chip_and_handler(irq, &qcom_msi_irq_chip, handle_simple_irq); + irq_set_chip_data(irq, domain->host_data); + set_irq_flags(irq, IRQF_VALID); + + return 0; +} + + +static const struct irq_domain_ops msi_domain_ops = { + .map = qcom_pcie_msi_map, +}; +uint32_t msm_pcie_msi_init(struct qcom_pcie *pcie, struct platform_device *pdev) +{ + int i, rc; + struct qcom_msi *msi = &pcie->msi; + int err; + + mutex_init(&msi->lock); + + msi->chip.dev = pcie->dev; + msi->chip.setup_irq = qcom_msi_setup_irq; + msi->chip.teardown_irq = qcom_msi_teardown_irq; + msi->domain = irq_domain_add_linear(pdev->dev.of_node, INT_PCI_MSI_NR, + &msi_domain_ops, &msi->chip); + if (!msi->domain) { + dev_err(&pdev->dev, "failed to create IRQ domain\n"); + return -ENOMEM; + } + + + err = platform_get_irq_byname(pdev, "msi"); + if (err < 0) { + dev_err(&pdev->dev, "failed to get IRQ: %d\n", err); + return err; + } + + msi->irq = err; + + /* program MSI controller and enable all interrupts */ + writel_relaxed(MSM_PCIE_MSI_PHY, pcie->dwc_base + PCIE20_MSI_CTRL_ADDR); + writel_relaxed(0, pcie->dwc_base + PCIE20_MSI_CTRL_UPPER_ADDR); + + for (i = 0; i < PCIE20_MSI_CTRL_MAX; i++) + writel_relaxed(~0, pcie->dwc_base + + PCIE20_MSI_CTRL_INTR_EN + (i * 12)); + + /* ensure that hardware is configured before proceeding */ + wmb(); + + /* register handler for physical MSI interrupt line */ + rc = request_irq(msi->irq, handle_msi_irq, IRQF_TRIGGER_RISING, + "msm_pcie_msi", pcie); + if (rc) { + pr_err("Unable to allocate msi interrupt\n"); + return rc; + } + + return rc; +} + static int qcom_pcie_vreg_on(struct qcom_pcie *qcom_pcie) { int err; @@ -710,11 +915,16 @@ static int qcom_pcie_probe(struct platform_device *pdev) spin_lock_irqsave(&qcom_hw_pci_lock, flags); qcom_hw_pci[nr_controllers].private_data = (void **)&qcom_pcie; hw = &qcom_hw_pci[nr_controllers]; + +#ifdef CONFIG_PCI_MSI + hw->msi_ctrl = &qcom_pcie->msi.chip; +#endif nr_controllers++; spin_unlock_irqrestore(&qcom_hw_pci_lock, flags); pci_common_init(hw); + msm_pcie_msi_init(qcom_pcie, pdev); return 0; } -- cgit v1.2.3 From 79f81b5de61ba477ac61f010c5b47dc56863fd39 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 9 Jul 2014 10:14:00 +0100 Subject: pci: qcom: move device init to subsys_initcall_sync This patch moves device init call from subsys_initcall to its sync variant. This is required because most of the dependent regulators drivers comeup at subsys_initcall level and this will result in defer probe of this driver. This behaviour will have an side effect of pci devices being probed at pci_scan_root_bus call, which means before the bus resources are actually allocated. moving to subsys_initcall_sync call will ensure that all the subsys_initcall level calls are finished before invoking the deivce init. Originally found while testing atl1c driver on IFC6410 board. [ 0.281558] qcom_pcie 1b500000.pci: Failed to get vdd supply [ 0.286396] platform 1b500000.pci: Driver qcom_pcie requests probe deferral ... [ 1.804406] PCI host bridge to bus 0000:00 [ 1.806090] pci_bus 0000:00: root bus resource [mem 0x08000000-0x0fdfffff] [ 1.810247] pci_bus 0000:00: root bus resource [io 0xfe00000-0xfefffff] [ 1.817105] pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff] [ 1.824023] pci 0000:00:00.0: [17cb:0101] type 01 class 0xff0000 [ 1.832008] pci 0000:00:00.0: supports D1 [ 1.837829] pci 0000:00:00.0: PME# supported from D0 D1 D3hot [ 1.842170] PCI: bus0: Fast back to back transfers disabled [ 1.847485] pci 0000:00:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring [ 1.853206] pci 0000:01:00.0: [1969:1083] type 00 class 0x020000 [ 1.860920] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x0003ffff 64bit] [ 1.867123] pci 0000:01:00.0: reg 0x18: [io 0x0000-0x007f] [ 1.874105] pci 0000:01:00.0: PME# supported from D0 D1 D2 D3hot D3cold [ 1.879499] PCI: bus1: Fast back to back transfers disabled [ 1.885777] pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01 [ 1.891336] pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 01 [ 1.898325] atl1c 0000:01:00.0: can't enable device: BAR 0 [mem 0x00000000-0x0003ffff 64bit] not claimed [ 1.904509] atl1c 0000:01:00.0: cannot enable PCI device [ 1.914232] atl1c: probe of 0000:01:00.0 failed with error -22 [ 1.919630] pci 0000:00:00.0: BAR 8: assigned [mem 0x08000000-0x080fffff] [ 1.925172] pci 0000:00:00.0: BAR 7: assigned [io 0xfe00000-0xfe00fff] [ 1.932044] pci 0000:01:00.0: BAR 0: assigned [mem 0x08000000-0x0803ffff 64bit] [ 1.938488] pci 0000:01:00.0: BAR 2: assigned [io 0xfe00000-0xfe0007f] Signed-off-by: Srinivas Kandagatla --- drivers/pci/host/pci-qcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/host/pci-qcom.c b/drivers/pci/host/pci-qcom.c index ed01a27f8f47..22ca8b776868 100644 --- a/drivers/pci/host/pci-qcom.c +++ b/drivers/pci/host/pci-qcom.c @@ -952,7 +952,7 @@ static int qcom_pcie_init(void) { return platform_driver_register(&qcom_pcie_driver); } -subsys_initcall(qcom_pcie_init); +subsys_initcall_sync(qcom_pcie_init); /* RC do not represent the right class; set it to PCI_CLASS_BRIDGE_PCI */ static void msm_pcie_fixup_early(struct pci_dev *dev) -- cgit v1.2.3 From d8b4426c0be45adefa4c2f76aace838cd6b8f777 Mon Sep 17 00:00:00 2001 From: Pramod Gurav Date: Mon, 1 Dec 2014 15:13:59 +0530 Subject: pci: qcom: Add ext_3p3v regulator support This regulator is needed by ethernet hence enable in the pcie driver so that ethernet is functional. Signed-off-by: Pramod Gurav --- drivers/pci/host/pci-qcom.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/pci/host/pci-qcom.c b/drivers/pci/host/pci-qcom.c index 22ca8b776868..fc851b73a372 100644 --- a/drivers/pci/host/pci-qcom.c +++ b/drivers/pci/host/pci-qcom.c @@ -151,6 +151,7 @@ struct qcom_pcie { struct regulator *vdd_supply; struct regulator *avdd_supply; struct regulator *pcie_clk_supply; + struct regulator *pcie_ext3p3v_supply; struct qcom_msi msi; }; @@ -651,6 +652,12 @@ static int qcom_pcie_vreg_on(struct qcom_pcie *qcom_pcie) return err; } + err = regulator_enable(qcom_pcie->pcie_ext3p3v_supply); + if (err < 0) { + dev_err(qcom_pcie->dev, "failed to enable pcie_ext3p3v regulator\n"); + return err; + } + return err; } @@ -726,6 +733,12 @@ static int qcom_pcie_parse_dt(struct qcom_pcie *qcom_pcie, return PTR_ERR(qcom_pcie->avdd_supply); } + qcom_pcie->pcie_ext3p3v_supply = devm_regulator_get(&pdev->dev, + "ext-3p3v"); + if (IS_ERR(qcom_pcie->pcie_ext3p3v_supply)) { + dev_err(&pdev->dev, "Failed to get pcie_ext3p3v supply\n"); + return PTR_ERR(qcom_pcie->pcie_ext3p3v_supply); + } qcom_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); if (!gpio_is_valid(qcom_pcie->reset_gpio)) { -- cgit v1.2.3 From a0b2384bbe985b2a0c65e8046aa752d56456b5e7 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Mon, 23 Feb 2015 17:18:04 +0000 Subject: pci: qcom: remove static domain name allocation Signed-off-by: Srinivas Kandagatla --- drivers/pci/host/pci-qcom.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/pci/host/pci-qcom.c b/drivers/pci/host/pci-qcom.c index fc851b73a372..c1150d575535 100644 --- a/drivers/pci/host/pci-qcom.c +++ b/drivers/pci/host/pci-qcom.c @@ -337,9 +337,6 @@ static struct pci_ops qcom_pcie_ops = { static struct hw_pci qcom_hw_pci[MAX_RC_NUM] = { { -#ifdef CONFIG_PCI_DOMAINS - .domain = 0, -#endif .ops = &qcom_pcie_ops, .nr_controllers = 1, .swizzle = pci_common_swizzle, @@ -347,9 +344,6 @@ static struct hw_pci qcom_hw_pci[MAX_RC_NUM] = { .map_irq = qcom_pcie_map_irq, }, { -#ifdef CONFIG_PCI_DOMAINS - .domain = 1, -#endif .ops = &qcom_pcie_ops, .nr_controllers = 1, .swizzle = pci_common_swizzle, @@ -357,9 +351,6 @@ static struct hw_pci qcom_hw_pci[MAX_RC_NUM] = { .map_irq = qcom_pcie_map_irq, }, { -#ifdef CONFIG_PCI_DOMAINS - .domain = 2, -#endif .ops = &qcom_pcie_ops, .nr_controllers = 1, .swizzle = pci_common_swizzle, @@ -935,7 +926,8 @@ static int qcom_pcie_probe(struct platform_device *pdev) nr_controllers++; spin_unlock_irqrestore(&qcom_hw_pci_lock, flags); - pci_common_init(hw); + ///pci_common_init(hw); + pci_common_init_dev(&pdev->dev, hw); msm_pcie_msi_init(qcom_pcie, pdev); return 0; -- cgit v1.2.3 From 95d770e047c5d2fbaeb432b16cdd7472eec0f36a Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 18 Mar 2015 13:34:32 +0000 Subject: pci: qcom: add Kconfig to not build on arm64 Signed-off-by: Srinivas Kandagatla --- drivers/pci/host/Kconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index d5e58bae95cf..f87b1c98292f 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -30,6 +30,11 @@ config PCI_IMX6 select PCIEPORTBUS select PCIE_DW +config PCI_QCOM + bool "Qualcomm PCIe controller" + default y + depends on ARCH_QCOM && !ARM64 + config PCI_TEGRA bool "NVIDIA Tegra PCIe controller" depends on ARCH_TEGRA && !ARM64 -- cgit v1.2.3 From 07be338504d71a4a7fe1022013310120e094a8c4 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 24 Sep 2015 19:00:17 +0100 Subject: pci:qcom: kill set_irq_flags and use genirq Signed-off-by: Srinivas Kandagatla --- drivers/pci/host/pci-qcom.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pci/host/pci-qcom.c b/drivers/pci/host/pci-qcom.c index c1150d575535..5a39f6368aa3 100644 --- a/drivers/pci/host/pci-qcom.c +++ b/drivers/pci/host/pci-qcom.c @@ -563,7 +563,6 @@ static int qcom_pcie_msi_map(struct irq_domain *domain, unsigned int irq, { irq_set_chip_and_handler(irq, &qcom_msi_irq_chip, handle_simple_irq); irq_set_chip_data(irq, domain->host_data); - set_irq_flags(irq, IRQF_VALID); return 0; } -- cgit v1.2.3 From a34ff4c20a0075f9c78e73aef339c92c47110b88 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 13 Aug 2015 14:13:40 +0100 Subject: drm/edid: Add support to get edid early This patch adds support to get edid way early before the connector is created, this is mainly used for panel drivers to auto-probe the panel based on the vendor and product id from EDID. Signed-off-by: Srinivas Kandagatla --- drivers/gpu/drm/drm_edid.c | 8 ++++++++ include/drm/drm_crtc.h | 1 + 2 files changed, 9 insertions(+) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 05bb7311ac5d..9076b8fc0d4d 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -1388,6 +1388,14 @@ struct edid *drm_get_edid(struct drm_connector *connector, } EXPORT_SYMBOL(drm_get_edid); +struct edid *drm_get_edid_early(struct i2c_adapter *adapter) +{ + struct drm_connector dummy_connector; + + return drm_get_edid(&dummy_connector, adapter); +} +EXPORT_SYMBOL(drm_get_edid_early); + /** * drm_edid_duplicate - duplicate an EDID and the extensions * @edid: EDID to duplicate diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index faaeff7db684..10d53e905c6b 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1304,6 +1304,7 @@ extern void drm_property_destroy_user_blobs(struct drm_device *dev, extern bool drm_probe_ddc(struct i2c_adapter *adapter); extern struct edid *drm_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter); +extern struct edid *drm_get_edid_early(struct i2c_adapter *adapter); extern struct edid *drm_edid_duplicate(const struct edid *edid); extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid); extern void drm_mode_config_init(struct drm_device *dev); -- cgit v1.2.3 From e607bd92c7abc137cea4b33acedfaae69580718a Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 13 Aug 2015 14:15:40 +0100 Subject: drm/edid: export edid_vendor() This patch exports edid_vendor() match function, so that other drivers could use it for matching the vendor id. Signed-off-by: Srinivas Kandagatla --- drivers/gpu/drm/drm_edid.c | 4 ++-- include/drm/drm_crtc.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 9076b8fc0d4d..f32e090b3d85 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -1417,7 +1417,7 @@ EXPORT_SYMBOL(drm_edid_duplicate); * * Returns true if @vendor is in @edid, false otherwise */ -static bool edid_vendor(struct edid *edid, char *vendor) +bool edid_vendor(struct edid *edid, char *vendor) { char edid_vendor[3]; @@ -1428,7 +1428,7 @@ static bool edid_vendor(struct edid *edid, char *vendor) return !strncmp(edid_vendor, vendor, 3); } - +EXPORT_SYMBOL(edid_vendor); /** * edid_get_quirks - return quirk flags for a given EDID * @edid: EDID to process diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 10d53e905c6b..f07ee6b6cb47 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1306,6 +1306,7 @@ extern struct edid *drm_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter); extern struct edid *drm_get_edid_early(struct i2c_adapter *adapter); extern struct edid *drm_edid_duplicate(const struct edid *edid); +extern bool edid_vendor(struct edid *edid, char *vendor); extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid); extern void drm_mode_config_init(struct drm_device *dev); extern void drm_mode_config_reset(struct drm_device *dev); -- cgit v1.2.3 From f0115847edf5e960c6b94a9b8ab6a4e3b81b1b25 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 14 Aug 2015 13:58:07 +0100 Subject: drm/panel: simple-panel: Add panel picker support. This patch adds panel picker support to simple-panel. The idea of panel picker is to select the correct panel timings if it supports probing edid via DDC bus, edid contains manufacture ID and Manufacturer product code, so it can match against the panel_picker entries to get the correct panel timings. From DT point of view the panel picker uses generic compatible string "panel-simple", keeping the panel specific compatible strings still supported. Panels can be static entry in the DT, but practically development boards like IFC6410 where developers can connect any LVDS panel which makes it difficult to maintian the dt support for those panels in dts file. With this dynamic probing via panel picker makes it easy to support such use-cases. This patch also adds panel presence detection based, if there is no panel detected or panel picker could not find the panel then the driver would mark the panel DT node as disabled so that the drm driver would be able to take right decision based on that panel node status. Signed-off-by: Srinivas Kandagatla --- drivers/gpu/drm/panel/panel-simple.c | 83 +++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index f97b73ec4713..34d73a32e78a 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -32,6 +32,7 @@ #include #include #include +#include #include