Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[imx9 boot reason 1/4] imx9_pmic driver #348

Merged
merged 2 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 103 additions & 36 deletions arch/arm64/src/imx9/imx9_pmic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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 = &reg_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);
Expand All @@ -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 = &reg_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);
}
50 changes: 44 additions & 6 deletions arch/arm64/src/imx9/imx9_pmic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
t-salminen marked this conversation as resolved.
Show resolved Hide resolved

/****************************************************************************
* 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
Expand All @@ -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)
Expand Down
Loading