Skip to content
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
96 changes: 90 additions & 6 deletions drivers/i2c/i2c_mspm0.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#include <zephyr/sys/util.h>
#include <zephyr/sys/sys_io.h>
#include <soc.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/pm/policy.h>

#include "i2c-priv.h"

Expand Down Expand Up @@ -406,6 +409,47 @@ static inline uint8_t i2c_receive_controller_data(mm_reg_t base)
return (uint8_t)(sys_read32(base + I2C_REG_CRXDATA) & I2C_CRXDATA_VALUE_MASK);
}

#if defined(CONFIG_PM_DEVICE)
static int i2c_mspm0_pm_action(const struct device *dev, enum pm_device_action action)
{
int err;
const struct i2c_mspm0_config *config = dev->config;
const mm_reg_t base = config->base;
i2c_clock_config_t clock_config = config->clock_config;

switch (action) {
case PM_DEVICE_ACTION_RESUME:
/* Set pins to active state */
err = pinctrl_apply_state(config->pinctrl, PINCTRL_STATE_DEFAULT);
if (err < 0) {
return err;
}

/* Restore the parent clock selection. */
i2c_set_clock_config(base, &clock_config);

break;

case PM_DEVICE_ACTION_SUSPEND:
/* Move pins to sleep state */
err = pinctrl_apply_state(config->pinctrl, PINCTRL_STATE_SLEEP);
if ((err < 0) && (err != -ENOENT)) {
return err;
}

/* Unselect all parent clocks to gate the peripheral clock. */
clock_config.clock_sel = 0;
i2c_set_clock_config(base, &clock_config);

break;
default:
return -ENOTSUP;
}

return 0;
}
#endif

/* Multi-byte FIFO operations */
static uint16_t i2c_fill_controller_tx_fifo(mm_reg_t base, const uint8_t *buffer, uint16_t count)
{
Expand Down Expand Up @@ -650,6 +694,11 @@ static int i2c_mspm0_configure(const struct device *dev, uint32_t dev_config)
return -ENODEV;
}

ret = pm_device_runtime_get(dev);
if (ret < 0) {
return ret;
}

k_sem_take(&data->i2c_lock, K_FOREVER);

/* Config I2C speed */
Expand Down Expand Up @@ -721,6 +770,7 @@ static int i2c_mspm0_configure(const struct device *dev, uint32_t dev_config)

sem_give:
k_sem_give(&data->i2c_lock);
pm_device_runtime_put(dev);
return ret;
}

Expand Down Expand Up @@ -767,7 +817,16 @@ static int i2c_mspm0_init(const struct device *dev)
/* Enable interrupts */
config->irq_config_func(dev);

#ifdef CONFIG_PM_DEVICE
ret = i2c_mspm0_pm_action(dev, PM_DEVICE_ACTION_SUSPEND);
if (ret < 0) {
return ret;
}

return pm_device_driver_init(dev, i2c_mspm0_pm_action);
#else
return 0;
#endif
}

static int i2c_mspm0_get_config(const struct device *dev, uint32_t *dev_config)
Expand Down Expand Up @@ -860,7 +919,13 @@ static int i2c_mspm0_transfer(const struct device *dev, struct i2c_msg *msgs, ui
uint32_t dev_config;
int ret;

ret = pm_device_runtime_get(dev);
if (ret < 0) {
return ret;
}

k_sem_take(&data->i2c_lock, K_FOREVER);
pm_policy_device_power_lock_get(dev);

data->msgs = msgs;
data->num_msgs = num_msgs;
Expand Down Expand Up @@ -895,7 +960,10 @@ static int i2c_mspm0_transfer(const struct device *dev, struct i2c_msg *msgs, ui
i2c_mspm0_configure(dev, dev_config);
}

pm_policy_device_power_lock_put(dev);
k_sem_give(&data->i2c_lock);

pm_device_runtime_put(dev);
return ret;
}

Expand All @@ -905,13 +973,23 @@ static int i2c_mspm0_target_register(const struct device *dev, struct i2c_target
const struct i2c_mspm0_config *config = dev->config;
struct i2c_mspm0_data *data = dev->data;
const mm_reg_t base = config->base;
int ret;

k_sem_take(&data->i2c_lock, K_FOREVER);

/* Device is already registered as target */
if (data->is_target || data->target_config == cfg) {
k_sem_give(&data->i2c_lock);
return -EBUSY;
}

k_sem_take(&data->i2c_lock, K_FOREVER);
ret = pm_device_runtime_get(dev);
if (ret < 0) {
k_sem_give(&data->i2c_lock);
return ret;
}

pm_policy_device_power_lock_get(dev);

data->target_config = cfg;
data->target_callbacks = cfg->callbacks;
Expand Down Expand Up @@ -953,19 +1031,24 @@ static int i2c_mspm0_target_unregister(const struct device *dev, struct i2c_targ
struct i2c_mspm0_data *data = dev->data;
const mm_reg_t base = config->base;

k_sem_take(&data->i2c_lock, K_FOREVER);

if (data->is_target == false) {
k_sem_give(&data->i2c_lock);
return 0;
}

k_sem_take(&data->i2c_lock, K_FOREVER);

data->target_config = NULL;
data->is_target = false;

i2c_disable_target(base);
i2c_disable_interrupt(base, TI_MSPM0_TARGET_INTERRUPTS);

pm_policy_device_power_lock_put(dev);
k_sem_give(&data->i2c_lock);

pm_device_runtime_put(dev);

return 0;
}

Expand Down Expand Up @@ -1322,8 +1405,9 @@ static DEVICE_API(i2c, i2c_mspm0_driver_api) = {
.divide_ratio = I2C_CLKDIV_RATIO_DIVIDE_BY_1, \
}}; \
static struct i2c_mspm0_data i2c_mspm0_data_##index; \
I2C_DEVICE_DT_INST_DEFINE(index, i2c_mspm0_init, NULL, &i2c_mspm0_data_##index, \
&i2c_mspm0_cfg_##index, POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \
&i2c_mspm0_driver_api);
PM_DEVICE_DT_INST_DEFINE(index, i2c_mspm0_pm_action); \
I2C_DEVICE_DT_INST_DEFINE(index, i2c_mspm0_init, PM_DEVICE_DT_INST_GET(index), \
&i2c_mspm0_data_##index, &i2c_mspm0_cfg_##index, POST_KERNEL, \
CONFIG_I2C_INIT_PRIORITY, &i2c_mspm0_driver_api);

DT_INST_FOREACH_STATUS_OKAY(MSP_I2C_INIT_FN)
1 change: 1 addition & 0 deletions dts/arm/ti/mspm0/g/mspm0g.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@

i2c1: i2c@400f2000 {
compatible = "ti,mspm0-i2c";
zephyr,disabling-power-states = <&stdby1>;
clocks = <&ckm MSPM0_CLOCK_ULPCLK>;
clock-frequency = <I2C_BITRATE_STANDARD>;
#address-cells = <1>;
Expand Down
1 change: 1 addition & 0 deletions dts/arm/ti/mspm0/g/mspm0gx51x.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@

i2c2: i2c@400f4000 {
compatible = "ti,mspm0-i2c";
zephyr,disabling-power-states = <&stdby1>;
clocks = <&ckm MSPM0_CLOCK_ULPCLK>;
clock-frequency = <I2C_BITRATE_STANDARD>;
#address-cells = <1>;
Expand Down
1 change: 1 addition & 0 deletions dts/arm/ti/mspm0/l/mspm0l13x3.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

i2c1: i2c@400f2000 {
compatible = "ti,mspm0-i2c";
zephyr,disabling-power-states = <&stdby1>;
clocks = <&ckm MSPM0_CLOCK_ULPCLK>;
clock-frequency = <I2C_BITRATE_STANDARD>;
#address-cells = <1>;
Expand Down
1 change: 1 addition & 0 deletions dts/arm/ti/mspm0/l/mspm0l13x4.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

i2c1: i2c@400f2000 {
compatible = "ti,mspm0-i2c";
zephyr,disabling-power-states = <&stdby1>;
clocks = <&ckm MSPM0_CLOCK_ULPCLK>;
clock-frequency = <I2C_BITRATE_STANDARD>;
#address-cells = <1>;
Expand Down
1 change: 1 addition & 0 deletions dts/arm/ti/mspm0/l/mspm0l13x5.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

i2c1: i2c@400f2000 {
compatible = "ti,mspm0-i2c";
zephyr,disabling-power-states = <&stdby1>;
clocks = <&ckm MSPM0_CLOCK_ULPCLK>;
clock-frequency = <I2C_BITRATE_STANDARD>;
#address-cells = <1>;
Expand Down
1 change: 1 addition & 0 deletions dts/arm/ti/mspm0/l/mspm0l13x6.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

i2c1: i2c@400f2000 {
compatible = "ti,mspm0-i2c";
zephyr,disabling-power-states = <&stdby1>;
clocks = <&ckm MSPM0_CLOCK_ULPCLK>;
clock-frequency = <I2C_BITRATE_STANDARD>;
#address-cells = <1>;
Expand Down
2 changes: 2 additions & 0 deletions dts/arm/ti/mspm0/l/mspm0lx22x.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@

i2c1: i2c@400f2000 {
compatible = "ti,mspm0-i2c";
zephyr,disabling-power-states = <&stdby1>;
clocks = <&ckm MSPM0_CLOCK_ULPCLK>;
clock-frequency = <I2C_BITRATE_STANDARD>;
#address-cells = <1>;
Expand All @@ -157,6 +158,7 @@

i2c2: i2c@400f4000 {
compatible = "ti,mspm0-i2c";
zephyr,disabling-power-states = <&stdby1>;
clocks = <&ckm MSPM0_CLOCK_ULPCLK>;
clock-frequency = <I2C_BITRATE_STANDARD>;
#address-cells = <1>;
Expand Down
1 change: 1 addition & 0 deletions dts/arm/ti/mspm0/mspm0.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@

i2c0: i2c@400f0000 {
compatible = "ti,mspm0-i2c";
zephyr,disabling-power-states = <&stdby1>;
clocks = <&ckm MSPM0_CLOCK_ULPCLK>;
clock-frequency = <I2C_BITRATE_STANDARD>;
#address-cells = <1>;
Expand Down
Loading