2023-05-11 12:51:22 +03:00
// SPDX-License-Identifier: GPL-2.0
/*
* Core functions for TI TPS6594 / TPS6593 / LP8764 PMICs
*
* Copyright ( C ) 2023 BayLibre Incorporated - https : //www.baylibre.com/
*/
# include <linux/completion.h>
# include <linux/delay.h>
# include <linux/interrupt.h>
# include <linux/module.h>
2023-07-14 20:47:27 +03:00
# include <linux/of.h>
2023-05-11 12:51:22 +03:00
# include <linux/mfd/core.h>
# include <linux/mfd/tps6594.h>
# define TPS6594_CRC_SYNC_TIMEOUT_MS 150
/* Completion to synchronize CRC feature enabling on all PMICs */
static DECLARE_COMPLETION ( tps6594_crc_comp ) ;
static const struct resource tps6594_regulator_resources [ ] = {
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK1_OV , TPS6594_IRQ_NAME_BUCK1_OV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK1_UV , TPS6594_IRQ_NAME_BUCK1_UV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK1_SC , TPS6594_IRQ_NAME_BUCK1_SC ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK1_ILIM , TPS6594_IRQ_NAME_BUCK1_ILIM ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK2_OV , TPS6594_IRQ_NAME_BUCK2_OV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK2_UV , TPS6594_IRQ_NAME_BUCK2_UV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK2_SC , TPS6594_IRQ_NAME_BUCK2_SC ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK2_ILIM , TPS6594_IRQ_NAME_BUCK2_ILIM ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK3_OV , TPS6594_IRQ_NAME_BUCK3_OV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK3_UV , TPS6594_IRQ_NAME_BUCK3_UV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK3_SC , TPS6594_IRQ_NAME_BUCK3_SC ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK3_ILIM , TPS6594_IRQ_NAME_BUCK3_ILIM ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK4_OV , TPS6594_IRQ_NAME_BUCK4_OV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK4_UV , TPS6594_IRQ_NAME_BUCK4_UV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK4_SC , TPS6594_IRQ_NAME_BUCK4_SC ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK4_ILIM , TPS6594_IRQ_NAME_BUCK4_ILIM ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK5_OV , TPS6594_IRQ_NAME_BUCK5_OV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK5_UV , TPS6594_IRQ_NAME_BUCK5_UV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK5_SC , TPS6594_IRQ_NAME_BUCK5_SC ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BUCK5_ILIM , TPS6594_IRQ_NAME_BUCK5_ILIM ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO1_OV , TPS6594_IRQ_NAME_LDO1_OV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO1_UV , TPS6594_IRQ_NAME_LDO1_UV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO1_SC , TPS6594_IRQ_NAME_LDO1_SC ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO1_ILIM , TPS6594_IRQ_NAME_LDO1_ILIM ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO2_OV , TPS6594_IRQ_NAME_LDO2_OV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO2_UV , TPS6594_IRQ_NAME_LDO2_UV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO2_SC , TPS6594_IRQ_NAME_LDO2_SC ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO2_ILIM , TPS6594_IRQ_NAME_LDO2_ILIM ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO3_OV , TPS6594_IRQ_NAME_LDO3_OV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO3_UV , TPS6594_IRQ_NAME_LDO3_UV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO3_SC , TPS6594_IRQ_NAME_LDO3_SC ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO3_ILIM , TPS6594_IRQ_NAME_LDO3_ILIM ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO4_OV , TPS6594_IRQ_NAME_LDO4_OV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO4_UV , TPS6594_IRQ_NAME_LDO4_UV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO4_SC , TPS6594_IRQ_NAME_LDO4_SC ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_LDO4_ILIM , TPS6594_IRQ_NAME_LDO4_ILIM ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_VCCA_OV , TPS6594_IRQ_NAME_VCCA_OV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_VCCA_UV , TPS6594_IRQ_NAME_VCCA_UV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_VMON1_OV , TPS6594_IRQ_NAME_VMON1_OV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_VMON1_UV , TPS6594_IRQ_NAME_VMON1_UV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_VMON1_RV , TPS6594_IRQ_NAME_VMON1_RV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_VMON2_OV , TPS6594_IRQ_NAME_VMON2_OV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_VMON2_UV , TPS6594_IRQ_NAME_VMON2_UV ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_VMON2_RV , TPS6594_IRQ_NAME_VMON2_RV ) ,
} ;
static const struct resource tps6594_pinctrl_resources [ ] = {
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_GPIO9 , TPS6594_IRQ_NAME_GPIO9 ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_GPIO10 , TPS6594_IRQ_NAME_GPIO10 ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_GPIO11 , TPS6594_IRQ_NAME_GPIO11 ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_GPIO1 , TPS6594_IRQ_NAME_GPIO1 ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_GPIO2 , TPS6594_IRQ_NAME_GPIO2 ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_GPIO3 , TPS6594_IRQ_NAME_GPIO3 ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_GPIO4 , TPS6594_IRQ_NAME_GPIO4 ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_GPIO5 , TPS6594_IRQ_NAME_GPIO5 ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_GPIO6 , TPS6594_IRQ_NAME_GPIO6 ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_GPIO7 , TPS6594_IRQ_NAME_GPIO7 ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_GPIO8 , TPS6594_IRQ_NAME_GPIO8 ) ,
} ;
static const struct resource tps6594_pfsm_resources [ ] = {
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_NPWRON_START , TPS6594_IRQ_NAME_NPWRON_START ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_ENABLE , TPS6594_IRQ_NAME_ENABLE ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_FSD , TPS6594_IRQ_NAME_FSD ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_SOFT_REBOOT , TPS6594_IRQ_NAME_SOFT_REBOOT ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BIST_PASS , TPS6594_IRQ_NAME_BIST_PASS ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_EXT_CLK , TPS6594_IRQ_NAME_EXT_CLK ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_TWARN , TPS6594_IRQ_NAME_TWARN ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_TSD_ORD , TPS6594_IRQ_NAME_TSD_ORD ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_BIST_FAIL , TPS6594_IRQ_NAME_BIST_FAIL ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_REG_CRC_ERR , TPS6594_IRQ_NAME_REG_CRC_ERR ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_RECOV_CNT , TPS6594_IRQ_NAME_RECOV_CNT ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_SPMI_ERR , TPS6594_IRQ_NAME_SPMI_ERR ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_NPWRON_LONG , TPS6594_IRQ_NAME_NPWRON_LONG ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_NINT_READBACK , TPS6594_IRQ_NAME_NINT_READBACK ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_NRSTOUT_READBACK , TPS6594_IRQ_NAME_NRSTOUT_READBACK ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_TSD_IMM , TPS6594_IRQ_NAME_TSD_IMM ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_VCCA_OVP , TPS6594_IRQ_NAME_VCCA_OVP ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_PFSM_ERR , TPS6594_IRQ_NAME_PFSM_ERR ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_IMM_SHUTDOWN , TPS6594_IRQ_NAME_IMM_SHUTDOWN ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_ORD_SHUTDOWN , TPS6594_IRQ_NAME_ORD_SHUTDOWN ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_MCU_PWR_ERR , TPS6594_IRQ_NAME_MCU_PWR_ERR ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_SOC_PWR_ERR , TPS6594_IRQ_NAME_SOC_PWR_ERR ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_COMM_FRM_ERR , TPS6594_IRQ_NAME_COMM_FRM_ERR ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_COMM_CRC_ERR , TPS6594_IRQ_NAME_COMM_CRC_ERR ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_COMM_ADR_ERR , TPS6594_IRQ_NAME_COMM_ADR_ERR ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_EN_DRV_READBACK , TPS6594_IRQ_NAME_EN_DRV_READBACK ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_NRSTOUT_SOC_READBACK ,
TPS6594_IRQ_NAME_NRSTOUT_SOC_READBACK ) ,
} ;
static const struct resource tps6594_esm_resources [ ] = {
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_ESM_SOC_PIN , TPS6594_IRQ_NAME_ESM_SOC_PIN ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_ESM_SOC_FAIL , TPS6594_IRQ_NAME_ESM_SOC_FAIL ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_ESM_SOC_RST , TPS6594_IRQ_NAME_ESM_SOC_RST ) ,
} ;
static const struct resource tps6594_rtc_resources [ ] = {
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_TIMER , TPS6594_IRQ_NAME_TIMER ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_ALARM , TPS6594_IRQ_NAME_ALARM ) ,
DEFINE_RES_IRQ_NAMED ( TPS6594_IRQ_POWER_UP , TPS6594_IRQ_NAME_POWERUP ) ,
} ;
static const struct mfd_cell tps6594_common_cells [ ] = {
MFD_CELL_RES ( " tps6594-regulator " , tps6594_regulator_resources ) ,
MFD_CELL_RES ( " tps6594-pinctrl " , tps6594_pinctrl_resources ) ,
MFD_CELL_RES ( " tps6594-pfsm " , tps6594_pfsm_resources ) ,
MFD_CELL_RES ( " tps6594-esm " , tps6594_esm_resources ) ,
} ;
static const struct mfd_cell tps6594_rtc_cells [ ] = {
MFD_CELL_RES ( " tps6594-rtc " , tps6594_rtc_resources ) ,
} ;
static const struct regmap_irq tps6594_irqs [ ] = {
/* INT_BUCK1_2 register */
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK1_OV , 0 , TPS6594_BIT_BUCKX_OV_INT ( 0 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK1_UV , 0 , TPS6594_BIT_BUCKX_UV_INT ( 0 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK1_SC , 0 , TPS6594_BIT_BUCKX_SC_INT ( 0 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK1_ILIM , 0 , TPS6594_BIT_BUCKX_ILIM_INT ( 0 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK2_OV , 0 , TPS6594_BIT_BUCKX_OV_INT ( 1 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK2_UV , 0 , TPS6594_BIT_BUCKX_UV_INT ( 1 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK2_SC , 0 , TPS6594_BIT_BUCKX_SC_INT ( 1 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK2_ILIM , 0 , TPS6594_BIT_BUCKX_ILIM_INT ( 1 ) ) ,
/* INT_BUCK3_4 register */
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK3_OV , 1 , TPS6594_BIT_BUCKX_OV_INT ( 2 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK3_UV , 1 , TPS6594_BIT_BUCKX_UV_INT ( 2 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK3_SC , 1 , TPS6594_BIT_BUCKX_SC_INT ( 2 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK3_ILIM , 1 , TPS6594_BIT_BUCKX_ILIM_INT ( 2 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK4_OV , 1 , TPS6594_BIT_BUCKX_OV_INT ( 3 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK4_UV , 1 , TPS6594_BIT_BUCKX_UV_INT ( 3 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK4_SC , 1 , TPS6594_BIT_BUCKX_SC_INT ( 3 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK4_ILIM , 1 , TPS6594_BIT_BUCKX_ILIM_INT ( 3 ) ) ,
/* INT_BUCK5 register */
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK5_OV , 2 , TPS6594_BIT_BUCKX_OV_INT ( 4 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK5_UV , 2 , TPS6594_BIT_BUCKX_UV_INT ( 4 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK5_SC , 2 , TPS6594_BIT_BUCKX_SC_INT ( 4 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BUCK5_ILIM , 2 , TPS6594_BIT_BUCKX_ILIM_INT ( 4 ) ) ,
/* INT_LDO1_2 register */
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO1_OV , 3 , TPS6594_BIT_LDOX_OV_INT ( 0 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO1_UV , 3 , TPS6594_BIT_LDOX_UV_INT ( 0 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO1_SC , 3 , TPS6594_BIT_LDOX_SC_INT ( 0 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO1_ILIM , 3 , TPS6594_BIT_LDOX_ILIM_INT ( 0 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO2_OV , 3 , TPS6594_BIT_LDOX_OV_INT ( 1 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO2_UV , 3 , TPS6594_BIT_LDOX_UV_INT ( 1 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO2_SC , 3 , TPS6594_BIT_LDOX_SC_INT ( 1 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO2_ILIM , 3 , TPS6594_BIT_LDOX_ILIM_INT ( 1 ) ) ,
/* INT_LDO3_4 register */
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO3_OV , 4 , TPS6594_BIT_LDOX_OV_INT ( 2 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO3_UV , 4 , TPS6594_BIT_LDOX_UV_INT ( 2 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO3_SC , 4 , TPS6594_BIT_LDOX_SC_INT ( 2 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO3_ILIM , 4 , TPS6594_BIT_LDOX_ILIM_INT ( 2 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO4_OV , 4 , TPS6594_BIT_LDOX_OV_INT ( 3 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO4_UV , 4 , TPS6594_BIT_LDOX_UV_INT ( 3 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO4_SC , 4 , TPS6594_BIT_LDOX_SC_INT ( 3 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_LDO4_ILIM , 4 , TPS6594_BIT_LDOX_ILIM_INT ( 3 ) ) ,
/* INT_VMON register */
REGMAP_IRQ_REG ( TPS6594_IRQ_VCCA_OV , 5 , TPS6594_BIT_VCCA_OV_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_VCCA_UV , 5 , TPS6594_BIT_VCCA_UV_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_VMON1_OV , 5 , TPS6594_BIT_VMON1_OV_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_VMON1_UV , 5 , TPS6594_BIT_VMON1_UV_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_VMON1_RV , 5 , TPS6594_BIT_VMON1_RV_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_VMON2_OV , 5 , TPS6594_BIT_VMON2_OV_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_VMON2_UV , 5 , TPS6594_BIT_VMON2_UV_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_VMON2_RV , 5 , TPS6594_BIT_VMON2_RV_INT ) ,
/* INT_GPIO register */
REGMAP_IRQ_REG ( TPS6594_IRQ_GPIO9 , 6 , TPS6594_BIT_GPIO9_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_GPIO10 , 6 , TPS6594_BIT_GPIO10_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_GPIO11 , 6 , TPS6594_BIT_GPIO11_INT ) ,
/* INT_GPIO1_8 register */
REGMAP_IRQ_REG ( TPS6594_IRQ_GPIO1 , 7 , TPS6594_BIT_GPIOX_INT ( 0 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_GPIO2 , 7 , TPS6594_BIT_GPIOX_INT ( 1 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_GPIO3 , 7 , TPS6594_BIT_GPIOX_INT ( 2 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_GPIO4 , 7 , TPS6594_BIT_GPIOX_INT ( 3 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_GPIO5 , 7 , TPS6594_BIT_GPIOX_INT ( 4 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_GPIO6 , 7 , TPS6594_BIT_GPIOX_INT ( 5 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_GPIO7 , 7 , TPS6594_BIT_GPIOX_INT ( 6 ) ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_GPIO8 , 7 , TPS6594_BIT_GPIOX_INT ( 7 ) ) ,
/* INT_STARTUP register */
REGMAP_IRQ_REG ( TPS6594_IRQ_NPWRON_START , 8 , TPS6594_BIT_NPWRON_START_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_ENABLE , 8 , TPS6594_BIT_ENABLE_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_FSD , 8 , TPS6594_BIT_FSD_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_SOFT_REBOOT , 8 , TPS6594_BIT_SOFT_REBOOT_INT ) ,
/* INT_MISC register */
REGMAP_IRQ_REG ( TPS6594_IRQ_BIST_PASS , 9 , TPS6594_BIT_BIST_PASS_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_EXT_CLK , 9 , TPS6594_BIT_EXT_CLK_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_TWARN , 9 , TPS6594_BIT_TWARN_INT ) ,
/* INT_MODERATE_ERR register */
REGMAP_IRQ_REG ( TPS6594_IRQ_TSD_ORD , 10 , TPS6594_BIT_TSD_ORD_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_BIST_FAIL , 10 , TPS6594_BIT_BIST_FAIL_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_REG_CRC_ERR , 10 , TPS6594_BIT_REG_CRC_ERR_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_RECOV_CNT , 10 , TPS6594_BIT_RECOV_CNT_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_SPMI_ERR , 10 , TPS6594_BIT_SPMI_ERR_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_NPWRON_LONG , 10 , TPS6594_BIT_NPWRON_LONG_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_NINT_READBACK , 10 , TPS6594_BIT_NINT_READBACK_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_NRSTOUT_READBACK , 10 , TPS6594_BIT_NRSTOUT_READBACK_INT ) ,
/* INT_SEVERE_ERR register */
REGMAP_IRQ_REG ( TPS6594_IRQ_TSD_IMM , 11 , TPS6594_BIT_TSD_IMM_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_VCCA_OVP , 11 , TPS6594_BIT_VCCA_OVP_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_PFSM_ERR , 11 , TPS6594_BIT_PFSM_ERR_INT ) ,
/* INT_FSM_ERR register */
REGMAP_IRQ_REG ( TPS6594_IRQ_IMM_SHUTDOWN , 12 , TPS6594_BIT_IMM_SHUTDOWN_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_ORD_SHUTDOWN , 12 , TPS6594_BIT_ORD_SHUTDOWN_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_MCU_PWR_ERR , 12 , TPS6594_BIT_MCU_PWR_ERR_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_SOC_PWR_ERR , 12 , TPS6594_BIT_SOC_PWR_ERR_INT ) ,
/* INT_COMM_ERR register */
REGMAP_IRQ_REG ( TPS6594_IRQ_COMM_FRM_ERR , 13 , TPS6594_BIT_COMM_FRM_ERR_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_COMM_CRC_ERR , 13 , TPS6594_BIT_COMM_CRC_ERR_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_COMM_ADR_ERR , 13 , TPS6594_BIT_COMM_ADR_ERR_INT ) ,
/* INT_READBACK_ERR register */
REGMAP_IRQ_REG ( TPS6594_IRQ_EN_DRV_READBACK , 14 , TPS6594_BIT_EN_DRV_READBACK_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_NRSTOUT_SOC_READBACK , 14 , TPS6594_BIT_NRSTOUT_SOC_READBACK_INT ) ,
/* INT_ESM register */
REGMAP_IRQ_REG ( TPS6594_IRQ_ESM_SOC_PIN , 15 , TPS6594_BIT_ESM_SOC_PIN_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_ESM_SOC_FAIL , 15 , TPS6594_BIT_ESM_SOC_FAIL_INT ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_ESM_SOC_RST , 15 , TPS6594_BIT_ESM_SOC_RST_INT ) ,
/* RTC_STATUS register */
REGMAP_IRQ_REG ( TPS6594_IRQ_TIMER , 16 , TPS6594_BIT_TIMER ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_ALARM , 16 , TPS6594_BIT_ALARM ) ,
REGMAP_IRQ_REG ( TPS6594_IRQ_POWER_UP , 16 , TPS6594_BIT_POWER_UP ) ,
} ;
static const unsigned int tps6594_irq_reg [ ] = {
TPS6594_REG_INT_BUCK1_2 ,
TPS6594_REG_INT_BUCK3_4 ,
TPS6594_REG_INT_BUCK5 ,
TPS6594_REG_INT_LDO1_2 ,
TPS6594_REG_INT_LDO3_4 ,
TPS6594_REG_INT_VMON ,
TPS6594_REG_INT_GPIO ,
TPS6594_REG_INT_GPIO1_8 ,
TPS6594_REG_INT_STARTUP ,
TPS6594_REG_INT_MISC ,
TPS6594_REG_INT_MODERATE_ERR ,
TPS6594_REG_INT_SEVERE_ERR ,
TPS6594_REG_INT_FSM_ERR ,
TPS6594_REG_INT_COMM_ERR ,
TPS6594_REG_INT_READBACK_ERR ,
TPS6594_REG_INT_ESM ,
TPS6594_REG_RTC_STATUS ,
} ;
static inline unsigned int tps6594_get_irq_reg ( struct regmap_irq_chip_data * data ,
unsigned int base , int index )
{
return tps6594_irq_reg [ index ] ;
} ;
static int tps6594_handle_post_irq ( void * irq_drv_data )
{
struct tps6594 * tps = irq_drv_data ;
int ret = 0 ;
/*
* When CRC is enabled , writing to a read - only bit triggers an error ,
* and COMM_ADR_ERR_INT bit is set . Besides , bits indicating interrupts
* ( that must be cleared ) and read - only bits are sometimes grouped in
* the same register .
* Since regmap clears interrupts by doing a write per register , clearing
* an interrupt bit in a register containing also a read - only bit makes
* COMM_ADR_ERR_INT bit set . Clear immediately this bit to avoid raising
* a new interrupt .
*/
if ( tps - > use_crc )
ret = regmap_write_bits ( tps - > regmap , TPS6594_REG_INT_COMM_ERR ,
TPS6594_BIT_COMM_ADR_ERR_INT ,
TPS6594_BIT_COMM_ADR_ERR_INT ) ;
return ret ;
} ;
static struct regmap_irq_chip tps6594_irq_chip = {
. ack_base = TPS6594_REG_INT_BUCK1_2 ,
. ack_invert = 1 ,
. clear_ack = 1 ,
. init_ack_masked = 1 ,
. num_regs = ARRAY_SIZE ( tps6594_irq_reg ) ,
. irqs = tps6594_irqs ,
. num_irqs = ARRAY_SIZE ( tps6594_irqs ) ,
. get_irq_reg = tps6594_get_irq_reg ,
. handle_post_irq = tps6594_handle_post_irq ,
} ;
bool tps6594_is_volatile_reg ( struct device * dev , unsigned int reg )
{
return ( reg > = TPS6594_REG_INT_TOP & & reg < = TPS6594_REG_STAT_READBACK_ERR ) | |
reg = = TPS6594_REG_RTC_STATUS ;
}
EXPORT_SYMBOL_GPL ( tps6594_is_volatile_reg ) ;
static int tps6594_check_crc_mode ( struct tps6594 * tps , bool primary_pmic )
{
int ret ;
/*
* Check if CRC is enabled .
* Once CRC is enabled , it can ' t be disabled until next power cycle .
*/
tps - > use_crc = true ;
ret = regmap_test_bits ( tps - > regmap , TPS6594_REG_SERIAL_IF_CONFIG ,
TPS6594_BIT_I2C1_SPI_CRC_EN ) ;
if ( ret = = 0 ) {
ret = - EIO ;
} else if ( ret > 0 ) {
dev_info ( tps - > dev , " CRC feature enabled on %s PMIC " ,
primary_pmic ? " primary " : " secondary " ) ;
ret = 0 ;
}
return ret ;
}
static int tps6594_set_crc_feature ( struct tps6594 * tps )
{
int ret ;
ret = tps6594_check_crc_mode ( tps , true ) ;
if ( ret ) {
/*
* If CRC is not already enabled , force PFSM I2C_2 trigger to enable it
* on primary PMIC .
*/
tps - > use_crc = false ;
ret = regmap_write_bits ( tps - > regmap , TPS6594_REG_FSM_I2C_TRIGGERS ,
TPS6594_BIT_TRIGGER_I2C ( 2 ) , TPS6594_BIT_TRIGGER_I2C ( 2 ) ) ;
if ( ret )
return ret ;
/*
* Wait for PFSM to process trigger .
* The datasheet indicates 2 ms , and clock specification is + / - 5 % .
* 4 ms should provide sufficient margin .
*/
usleep_range ( 4000 , 5000 ) ;
ret = tps6594_check_crc_mode ( tps , true ) ;
}
return ret ;
}
static int tps6594_enable_crc ( struct tps6594 * tps )
{
struct device * dev = tps - > dev ;
unsigned int is_primary ;
unsigned long timeout = msecs_to_jiffies ( TPS6594_CRC_SYNC_TIMEOUT_MS ) ;
int ret ;
/*
* CRC mode can be used with I2C or SPI protocols .
* If this mode is specified for primary PMIC , it will also be applied to secondary PMICs
* through SPMI serial interface .
* In this multi - PMIC synchronization scheme , the primary PMIC is the controller device
* on the SPMI bus , and the secondary PMICs are the target devices on the SPMI bus .
*/
is_primary = of_property_read_bool ( dev - > of_node , " ti,primary-pmic " ) ;
if ( is_primary ) {
/* Enable CRC feature on primary PMIC */
ret = tps6594_set_crc_feature ( tps ) ;
if ( ret )
return ret ;
/* Notify secondary PMICs that CRC feature is enabled */
complete_all ( & tps6594_crc_comp ) ;
} else {
/* Wait for CRC feature enabling event from primary PMIC */
ret = wait_for_completion_interruptible_timeout ( & tps6594_crc_comp , timeout ) ;
if ( ret = = 0 )
ret = - ETIMEDOUT ;
else if ( ret > 0 )
ret = tps6594_check_crc_mode ( tps , false ) ;
}
return ret ;
}
int tps6594_device_init ( struct tps6594 * tps , bool enable_crc )
{
struct device * dev = tps - > dev ;
int ret ;
if ( enable_crc ) {
ret = tps6594_enable_crc ( tps ) ;
if ( ret )
return dev_err_probe ( dev , ret , " Failed to enable CRC \n " ) ;
}
/* Keep PMIC in ACTIVE state */
ret = regmap_set_bits ( tps - > regmap , TPS6594_REG_FSM_NSLEEP_TRIGGERS ,
TPS6594_BIT_NSLEEP1B | TPS6594_BIT_NSLEEP2B ) ;
if ( ret )
return dev_err_probe ( dev , ret , " Failed to set PMIC state \n " ) ;
tps6594_irq_chip . irq_drv_data = tps ;
tps6594_irq_chip . name = devm_kasprintf ( dev , GFP_KERNEL , " %s-%ld-0x%02x " ,
dev - > driver - > name , tps - > chip_id , tps - > reg ) ;
2023-12-08 06:33:20 +03:00
if ( ! tps6594_irq_chip . name )
return - ENOMEM ;
2023-05-11 12:51:22 +03:00
ret = devm_regmap_add_irq_chip ( dev , tps - > regmap , tps - > irq , IRQF_SHARED | IRQF_ONESHOT ,
0 , & tps6594_irq_chip , & tps - > irq_data ) ;
if ( ret )
return dev_err_probe ( dev , ret , " Failed to add regmap IRQ \n " ) ;
ret = devm_mfd_add_devices ( dev , PLATFORM_DEVID_AUTO , tps6594_common_cells ,
ARRAY_SIZE ( tps6594_common_cells ) , NULL , 0 ,
regmap_irq_get_domain ( tps - > irq_data ) ) ;
if ( ret )
return dev_err_probe ( dev , ret , " Failed to add common child devices \n " ) ;
/* No RTC for LP8764 */
if ( tps - > chip_id ! = LP8764 ) {
ret = devm_mfd_add_devices ( dev , PLATFORM_DEVID_AUTO , tps6594_rtc_cells ,
ARRAY_SIZE ( tps6594_rtc_cells ) , NULL , 0 ,
regmap_irq_get_domain ( tps - > irq_data ) ) ;
if ( ret )
return dev_err_probe ( dev , ret , " Failed to add RTC child device \n " ) ;
}
return 0 ;
}
EXPORT_SYMBOL_GPL ( tps6594_device_init ) ;
MODULE_AUTHOR ( " Julien Panis <jpanis@baylibre.com> " ) ;
MODULE_DESCRIPTION ( " TPS6594 Driver " ) ;
MODULE_LICENSE ( " GPL " ) ;