drivers: spi: pm: Add power management support for Ambiq Apollo3 SoCs SPI
Add power management support for Apollo3/Apollo3P SPI, and automatically enables device runtime power management Signed-off-by: Zhengwei Wang <zwang@ambiq.com>
This commit is contained in:
parent
2cbf3b9365
commit
4a7adb3d9d
3 changed files with 64 additions and 2 deletions
|
|
@ -13,6 +13,10 @@ LOG_MODULE_REGISTER(spi_ambiq);
|
|||
#include <zephyr/drivers/pinctrl.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
#include <zephyr/pm/device.h>
|
||||
#include <zephyr/pm/policy.h>
|
||||
#include <zephyr/pm/device_runtime.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "spi_context.h"
|
||||
|
|
@ -344,6 +348,12 @@ static int spi_ambiq_transceive(const struct device *dev, const struct spi_confi
|
|||
return 0;
|
||||
}
|
||||
|
||||
ret = pm_device_runtime_get(dev);
|
||||
|
||||
if (ret < 0) {
|
||||
LOG_ERR("pm_device_runtime_get failed: %d", ret);
|
||||
}
|
||||
|
||||
/* context setup */
|
||||
spi_context_lock(&data->ctx, false, NULL, NULL, config);
|
||||
|
||||
|
|
@ -360,6 +370,15 @@ static int spi_ambiq_transceive(const struct device *dev, const struct spi_confi
|
|||
|
||||
spi_context_release(&data->ctx, ret);
|
||||
|
||||
/* Use async put to avoid useless device suspension/resumption
|
||||
* when doing consecutive transmission.
|
||||
*/
|
||||
ret = pm_device_runtime_put_async(dev, K_MSEC(2));
|
||||
|
||||
if (ret < 0) {
|
||||
LOG_ERR("pm_device_runtime_put failed: %d", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -421,6 +440,35 @@ end:
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_DEVICE
|
||||
static int spi_ambiq_pm_action(const struct device *dev, enum pm_device_action action)
|
||||
{
|
||||
struct spi_ambiq_data *data = dev->data;
|
||||
uint32_t ret;
|
||||
am_hal_sysctrl_power_state_e status;
|
||||
|
||||
switch (action) {
|
||||
case PM_DEVICE_ACTION_RESUME:
|
||||
status = AM_HAL_SYSCTRL_WAKE;
|
||||
break;
|
||||
case PM_DEVICE_ACTION_SUSPEND:
|
||||
status = AM_HAL_SYSCTRL_DEEPSLEEP;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
ret = am_hal_iom_power_ctrl(data->iom_handler, status, true);
|
||||
|
||||
if (ret != AM_HAL_STATUS_SUCCESS) {
|
||||
LOG_ERR("am_hal_iom_power_ctrl failed: %d", ret);
|
||||
return -EPERM;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_PM_DEVICE */
|
||||
|
||||
#define AMBIQ_SPI_INIT(n) \
|
||||
PINCTRL_DT_INST_DEFINE(n); \
|
||||
static int pwr_on_ambiq_spi_##n(void) \
|
||||
|
|
@ -448,7 +496,9 @@ end:
|
|||
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
|
||||
.irq_config_func = spi_irq_config_func_##n, \
|
||||
.pwr_func = pwr_on_ambiq_spi_##n}; \
|
||||
DEVICE_DT_INST_DEFINE(n, spi_ambiq_init, NULL, &spi_ambiq_data##n, &spi_ambiq_config##n, \
|
||||
POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, &spi_ambiq_driver_api);
|
||||
PM_DEVICE_DT_INST_DEFINE(n, spi_ambiq_pm_action); \
|
||||
DEVICE_DT_INST_DEFINE(n, spi_ambiq_init, PM_DEVICE_DT_INST_GET(n), &spi_ambiq_data##n, \
|
||||
&spi_ambiq_config##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \
|
||||
&spi_ambiq_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(AMBIQ_SPI_INIT)
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@
|
|||
interrupts = <6 0>;
|
||||
status = "disabled";
|
||||
ambiq,pwrcfg = <&pwrcfg 0x8 0x2>;
|
||||
zephyr,pm-device-runtime-auto;
|
||||
};
|
||||
|
||||
spi1: spi@50005000 {
|
||||
|
|
@ -205,6 +206,7 @@
|
|||
interrupts = <7 0>;
|
||||
status = "disabled";
|
||||
ambiq,pwrcfg = <&pwrcfg 0x8 0x4>;
|
||||
zephyr,pm-device-runtime-auto;
|
||||
};
|
||||
|
||||
spi2: spi@50006000 {
|
||||
|
|
@ -214,6 +216,7 @@
|
|||
interrupts = <8 0>;
|
||||
status = "disabled";
|
||||
ambiq,pwrcfg = <&pwrcfg 0x8 0x8>;
|
||||
zephyr,pm-device-runtime-auto;
|
||||
};
|
||||
|
||||
spi3: spi@50007000 {
|
||||
|
|
@ -223,6 +226,7 @@
|
|||
interrupts = <9 0>;
|
||||
status = "disabled";
|
||||
ambiq,pwrcfg = <&pwrcfg 0x8 0x10>;
|
||||
zephyr,pm-device-runtime-auto;
|
||||
};
|
||||
|
||||
spi4: spi@50008000 {
|
||||
|
|
@ -232,6 +236,7 @@
|
|||
interrupts = <10 0>;
|
||||
status = "disabled";
|
||||
ambiq,pwrcfg = <&pwrcfg 0x8 0x20>;
|
||||
zephyr,pm-device-runtime-auto;
|
||||
};
|
||||
|
||||
spi5: spi@50009000 {
|
||||
|
|
@ -241,6 +246,7 @@
|
|||
interrupts = <11 0>;
|
||||
status = "disabled";
|
||||
ambiq,pwrcfg = <&pwrcfg 0x8 0x40>;
|
||||
zephyr,pm-device-runtime-auto;
|
||||
};
|
||||
|
||||
i2c0: i2c@50004000 {
|
||||
|
|
|
|||
|
|
@ -214,6 +214,7 @@
|
|||
interrupts = <6 0>;
|
||||
status = "disabled";
|
||||
ambiq,pwrcfg = <&pwrcfg 0x8 0x2>;
|
||||
zephyr,pm-device-runtime-auto;
|
||||
};
|
||||
|
||||
spi1: spi@50005000 {
|
||||
|
|
@ -223,6 +224,7 @@
|
|||
interrupts = <7 0>;
|
||||
status = "disabled";
|
||||
ambiq,pwrcfg = <&pwrcfg 0x8 0x4>;
|
||||
zephyr,pm-device-runtime-auto;
|
||||
};
|
||||
|
||||
spi2: spi@50006000 {
|
||||
|
|
@ -232,6 +234,7 @@
|
|||
interrupts = <8 0>;
|
||||
status = "disabled";
|
||||
ambiq,pwrcfg = <&pwrcfg 0x8 0x8>;
|
||||
zephyr,pm-device-runtime-auto;
|
||||
};
|
||||
|
||||
spi3: spi@50007000 {
|
||||
|
|
@ -241,6 +244,7 @@
|
|||
interrupts = <9 0>;
|
||||
status = "disabled";
|
||||
ambiq,pwrcfg = <&pwrcfg 0x8 0x10>;
|
||||
zephyr,pm-device-runtime-auto;
|
||||
};
|
||||
|
||||
spi4: spi@50008000 {
|
||||
|
|
@ -250,6 +254,7 @@
|
|||
interrupts = <10 0>;
|
||||
status = "disabled";
|
||||
ambiq,pwrcfg = <&pwrcfg 0x8 0x20>;
|
||||
zephyr,pm-device-runtime-auto;
|
||||
};
|
||||
|
||||
spi5: spi@50009000 {
|
||||
|
|
@ -259,6 +264,7 @@
|
|||
interrupts = <11 0>;
|
||||
status = "disabled";
|
||||
ambiq,pwrcfg = <&pwrcfg 0x8 0x40>;
|
||||
zephyr,pm-device-runtime-auto;
|
||||
};
|
||||
|
||||
i2c0: i2c@50004000 {
|
||||
|
|
|
|||
Loading…
Reference in a new issue