adc_qmsi_ss: Add power management support to driver
Add the device_ctrl hook to the ADC driver of the Sensor Subsystem, using the QMSI APIs to save and restore the driver's context. Jira: ZEP-667 Change-Id: I8b89a875d8185cc4db3c4bfc30ef0f39c6589df1 Signed-off-by: Iván Briano <ivan.briano@intel.com>
This commit is contained in:
parent
a5fce7aa11
commit
b190bd4da2
1 changed files with 71 additions and 6 deletions
|
@ -40,6 +40,12 @@ struct adc_info {
|
||||||
atomic_t state;
|
atomic_t state;
|
||||||
device_sync_call_t sync;
|
device_sync_call_t sync;
|
||||||
struct k_sem sem;
|
struct k_sem sem;
|
||||||
|
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
|
||||||
|
uint32_t device_power_state;
|
||||||
|
#ifdef CONFIG_SYS_POWER_DEEP_SLEEP
|
||||||
|
qm_ss_adc_context_t adc_ctx;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static void adc_config_irq(void);
|
static void adc_config_irq(void);
|
||||||
|
@ -243,13 +249,70 @@ static const struct adc_driver_api api_funcs = {
|
||||||
.read = adc_qmsi_ss_read,
|
.read = adc_qmsi_ss_read,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
|
||||||
|
static void adc_qmsi_ss_set_power_state(struct device *dev,
|
||||||
|
uint32_t power_state)
|
||||||
|
{
|
||||||
|
struct adc_info *context = dev->driver_data;
|
||||||
|
|
||||||
|
context->device_power_state = power_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t adc_qmsi_ss_get_power_state(struct device *dev)
|
||||||
|
{
|
||||||
|
struct adc_info *context = dev->driver_data;
|
||||||
|
|
||||||
|
return context->device_power_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_SYS_POWER_DEEP_SLEEP
|
||||||
|
static int adc_qmsi_ss_suspend_device(struct device *dev)
|
||||||
|
{
|
||||||
|
struct adc_info *context = dev->driver_data;
|
||||||
|
|
||||||
|
qm_ss_adc_save_context(QM_SS_ADC_0, &context->adc_ctx);
|
||||||
|
|
||||||
|
adc_qmsi_ss_set_power_state(dev, DEVICE_PM_SUSPEND_STATE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int adc_qmsi_ss_resume_device_from_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
struct adc_info *context = dev->driver_data;
|
||||||
|
|
||||||
|
qm_ss_adc_restore_context(QM_SS_ADC_0, &context->adc_ctx);
|
||||||
|
|
||||||
|
adc_qmsi_ss_set_power_state(dev, DEVICE_PM_ACTIVE_STATE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SYS_POWER_DEEP_SLEEP */
|
||||||
|
|
||||||
|
static int adc_qmsi_ss_device_ctrl(struct device *dev, uint32_t ctrl_command,
|
||||||
|
void *context)
|
||||||
|
{
|
||||||
|
if (ctrl_command == DEVICE_PM_SET_POWER_STATE) {
|
||||||
|
#ifdef CONFIG_SYS_POWER_DEEP_SLEEP
|
||||||
|
if (*((uint32_t *)context) == DEVICE_PM_SUSPEND_STATE) {
|
||||||
|
return adc_qmsi_ss_suspend_device(dev);
|
||||||
|
} else if (*((uint32_t *)context) == DEVICE_PM_ACTIVE_STATE) {
|
||||||
|
return adc_qmsi_ss_resume_device_from_suspend(dev);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else if (ctrl_command == DEVICE_PM_GET_POWER_STATE) {
|
||||||
|
*((uint32_t *)context) = adc_qmsi_ss_get_power_state(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define adc_qmsi_ss_set_power_state(...)
|
||||||
|
#endif /* CONFIG_DEVICE_POWER_MANAGEMENT */
|
||||||
int adc_qmsi_ss_init(struct device *dev)
|
int adc_qmsi_ss_init(struct device *dev)
|
||||||
{
|
{
|
||||||
struct adc_info *info = dev->driver_data;
|
struct adc_info *info = dev->driver_data;
|
||||||
|
|
||||||
dev->driver_api = &api_funcs;
|
|
||||||
|
|
||||||
|
|
||||||
/* Set up config */
|
/* Set up config */
|
||||||
/* Clock cycles between the start of each sample */
|
/* Clock cycles between the start of each sample */
|
||||||
cfg.window = CONFIG_ADC_QMSI_SERIAL_DELAY;
|
cfg.window = CONFIG_ADC_QMSI_SERIAL_DELAY;
|
||||||
|
@ -267,14 +330,16 @@ int adc_qmsi_ss_init(struct device *dev)
|
||||||
|
|
||||||
adc_config_irq();
|
adc_config_irq();
|
||||||
|
|
||||||
|
adc_qmsi_ss_set_power_state(dev, DEVICE_PM_ACTIVE_STATE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct adc_info adc_info_dev;
|
struct adc_info adc_info_dev;
|
||||||
|
|
||||||
DEVICE_INIT(adc_qmsi_ss, CONFIG_ADC_0_NAME, &adc_qmsi_ss_init,
|
DEVICE_DEFINE(adc_qmsi_ss, CONFIG_ADC_0_NAME, &adc_qmsi_ss_init,
|
||||||
&adc_info_dev, NULL,
|
adc_qmsi_ss_device_ctrl, &adc_info_dev, NULL, POST_KERNEL,
|
||||||
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &api_funcs);
|
||||||
|
|
||||||
static void adc_config_irq(void)
|
static void adc_config_irq(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue