diff --git a/arch/arm64/src/imx9/imx9_pmic.c b/arch/arm64/src/imx9/imx9_pmic.c index 8c99debeaae74..f510a65c5c63a 100644 --- a/arch/arm64/src/imx9/imx9_pmic.c +++ b/arch/arm64/src/imx9/imx9_pmic.c @@ -48,6 +48,7 @@ #define PCA9451A_I2C_ADDR 0x25 #define REG_SW_RST 0x06 #define REG_POWERON_STAT 0x05 +#define REG_RESET_CTRL 0x08 #define COLD_RESET 0x64 #define WARM_RESET 0x35 @@ -56,57 +57,69 @@ ****************************************************************************/ /**************************************************************************** - * Name: imx9_pmic_reset + * Name: imx9_pmic_reg_read * * Description: - * Reset SoC via pmic + * Read 8-bit register value from pmic * ****************************************************************************/ -void imx9_pmic_reset(void) +static int imx9_pmic_reg_read(uint8_t reg, uint8_t *value) { struct i2c_master_s *i2c; - struct i2c_msg_s msg; - uint8_t buffer[2]; + struct i2c_msg_s msgs[2]; + uint8_t reg_addr = reg; int ret; - i2c = imx9_i2cbus_initialize(CONFIG_IMX9_PMIC_I2C); + if (!value) + { + _err("Invalid value parameter\n"); + return -EINVAL; + } + i2c = imx9_i2cbus_initialize(CONFIG_IMX9_PMIC_I2C); if (i2c == NULL) { - return; + _err("Failed to initialize I2C bus\n"); + return -ENODEV; } - buffer[0] = REG_SW_RST; - buffer[1] = COLD_RESET; + msgs[0].frequency = 400000; + msgs[0].addr = PCA9451A_I2C_ADDR; + msgs[0].flags = 0; + msgs[0].buffer = ®_addr; + msgs[0].length = 1; - msg.frequency = 400000; - msg.addr = PCA9451A_I2C_ADDR; - msg.flags = 0; - msg.buffer = buffer; - msg.length = 2; + msgs[1].frequency = 400000; + msgs[1].addr = PCA9451A_I2C_ADDR; + msgs[1].flags = I2C_M_READ; + msgs[1].buffer = value; + msgs[1].length = 1; - ret = I2C_TRANSFER(i2c, &msg, 1); + ret = I2C_TRANSFER(i2c, msgs, 2); if (ret < 0) { - _err("ERROR: Failed to write reset via I2C2 interface\n"); + _err("I2C transfer failed: %d\n", ret); } + + imx9_i2cbus_uninitialize(i2c); + + return ret < 0 ? ret : 0; /* negative errno or 0 */ } /**************************************************************************** - * Name: imx9_get_pmic_reset_reason + * Name: imx9_pmic_reg_read * * Description: - * Read reset reason from pmic + * Write 8-bit register value to pmic * ****************************************************************************/ -uint32_t imx9_pmic_getreset_reason(void) +static int imx9_pmic_reg_write(uint8_t reg, uint8_t val) { struct i2c_master_s *i2c; - struct i2c_msg_s msgs[2]; - uint8_t reg_addr = REG_POWERON_STAT; - uint8_t data; + struct i2c_msg_s msg; + uint8_t buffer[2]; int ret; i2c = imx9_i2cbus_initialize(CONFIG_IMX9_PMIC_I2C); @@ -116,26 +129,80 @@ uint32_t imx9_pmic_getreset_reason(void) return -ENODEV; } - msgs[0].frequency = 400000; - msgs[0].addr = PCA9451A_I2C_ADDR; - msgs[0].flags = 0; - msgs[0].buffer = ®_addr; - msgs[0].length = 1; + buffer[0] = reg; + buffer[1] = val; - msgs[1].frequency = 400000; - msgs[1].addr = PCA9451A_I2C_ADDR; - msgs[1].flags = I2C_M_READ; - msgs[1].buffer = &data; - msgs[1].length = 1; + msg.frequency = 400000; + msg.addr = PCA9451A_I2C_ADDR; + msg.flags = 0; + msg.buffer = buffer; + msg.length = 2; - ret = I2C_TRANSFER(i2c, msgs, 2); + ret = I2C_TRANSFER(i2c, &msg, 1); if (ret < 0) { _err("I2C transfer failed: %d\n", ret); - imx9_i2cbus_uninitialize(i2c); - return ret; } imx9_i2cbus_uninitialize(i2c); - return (uint32_t)data; + + return ret < 0 ? ret : 0; /* negative errno or 0 */ +} + +/**************************************************************************** + * Name: imx9_pmic_reset + * + * Description: + * Reset SoC via pmic + * + ****************************************************************************/ + +int imx9_pmic_reset(void) +{ + return imx9_pmic_reg_write(REG_SW_RST, COLD_RESET); +} + +/**************************************************************************** + * Name: imx9_pmic_get_reset_reason + * + * Description: + * Read reset reason from pmic + * + ****************************************************************************/ + +int imx9_pmic_get_reset_reason(uint8_t *value) +{ + return imx9_pmic_reg_read(REG_POWERON_STAT, value); +} + +/**************************************************************************** + * Name: imx9_pmic_get_reset_ctrl + * + * Description: + * Read reset control register value + * + ****************************************************************************/ + +int imx9_pmic_get_reset_ctrl(uint8_t *value) +{ + return imx9_pmic_reg_read(REG_RESET_CTRL, value); +} + +/**************************************************************************** + * Name: imx9_pmic_set_reset_ctrl + * + * Description: + * Set reset control register value + * + * Input Parameters: + * Register value + * + * Returned Value: + * None + * + ****************************************************************************/ + +int imx9_pmic_set_reset_ctrl(uint8_t val) +{ + return imx9_pmic_reg_write(REG_RESET_CTRL, val); } diff --git a/arch/arm64/src/imx9/imx9_pmic.h b/arch/arm64/src/imx9/imx9_pmic.h index 176e4d081de33..4ac5ab36dc8de 100644 --- a/arch/arm64/src/imx9/imx9_pmic.h +++ b/arch/arm64/src/imx9/imx9_pmic.h @@ -44,21 +44,27 @@ extern "C" #define EXTERN extern #endif +#define IMX9_PMIC_RESET_CTRL_DEFAULT 0x21 + +/* WDOG_B_CFG [7:6]: 11b (Cold Reset) */ + +#define IMX9_PMIC_RESET_CTRL_WDOG_COLD_RESET_MASK 0xC0 + /**************************************************************************** - * Name: imx9_pmic_getreset_reason + * Name: imx9_pmic_get_reset_reason * * Description: * Read reset reason from pmic via i2c * * Input Parameters: - * None + * Pointer to reset reason value * * Returned Value: - * uin32_t, reset reason + * Zero on success or error code * ****************************************************************************/ -uint32_t imx9_pmic_getreset_reason(void); +int imx9_pmic_get_reset_reason(uint8_t *value); /**************************************************************************** * Name: imx9_pmic_reset @@ -70,11 +76,43 @@ uint32_t imx9_pmic_getreset_reason(void); * None * * Returned Value: - * None + * Zero on success or error code + * + ****************************************************************************/ + +int imx9_pmic_reset(void); + +/**************************************************************************** + * Name: imx9_pmic_get_reset_ctrl + * + * Description: + * Read reset control register value + * + * Input Parameters: + * Pointer to reset reason value + * + * Returned Value: + * Zero on success or error code + * + ****************************************************************************/ + +int imx9_pmic_get_reset_ctrl(uint8_t *value); + +/**************************************************************************** + * Name: imx9_pmic_set_reset_ctrl + * + * Description: + * Set reset control register value + * + * Input Parameters: + * Register value + * + * Returned Value: + * Zero on success or error code * ****************************************************************************/ -void imx9_pmic_reset(void); +int imx9_pmic_set_reset_ctrl(uint8_t val); #undef EXTERN #if defined(__cplusplus)