Skip to content

Commit 6ed98bf

Browse files
xodus7kartben
authored andcommitted
drivers: i3c: i3c_dw: add pinctrl support
Adds pinctrl support on init and on PM actions. General PM support is added to the driver to enable the later. Signed-off-by: Corey Wharton <[email protected]>
1 parent c6bc092 commit 6ed98bf

File tree

1 file changed

+72
-3
lines changed

1 file changed

+72
-3
lines changed

drivers/i3c/i3c_dw.c

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,14 @@
88
#include <zephyr/logging/log.h>
99
#include <zephyr/drivers/i3c.h>
1010
#include <zephyr/drivers/clock_control.h>
11+
#include <zephyr/pm/device.h>
1112
#include <zephyr/sys/util.h>
1213
#include <assert.h>
1314

15+
#if defined(CONFIG_PINCTRL)
16+
#include <zephyr/drivers/pinctrl.h>
17+
#endif
18+
1419
#define NANO_SEC 1000000000ULL
1520
#define BYTES_PER_DWORD 4
1621

@@ -365,6 +370,10 @@ struct dw_i3c_config {
365370
uint32_t od_tlow_min_ns;
366371

367372
void (*irq_config_func)();
373+
374+
#if defined(CONFIG_PINCTRL)
375+
const struct pinctrl_dev_config *pcfg;
376+
#endif
368377
};
369378

370379
struct dw_i3c_data {
@@ -2204,6 +2213,27 @@ static int dw_i3c_target_unregister(const struct device *dev, struct i3c_target_
22042213
return 0;
22052214
}
22062215

2216+
static int dw_i3c_pinctrl_enable(const struct device *dev, bool enable)
2217+
{
2218+
#ifdef CONFIG_PINCTRL
2219+
const struct dw_i3c_config *config = dev->config;
2220+
uint8_t state = enable ? PINCTRL_STATE_DEFAULT : PINCTRL_STATE_SLEEP;
2221+
int ret;
2222+
2223+
ret = pinctrl_apply_state(config->pcfg, state);
2224+
if (ret == -ENOENT) {
2225+
/* State not defined; ignore and return success. */
2226+
ret = 0;
2227+
}
2228+
2229+
return ret;
2230+
#else
2231+
ARG_UNUSED(dev);
2232+
ARG_UNUSED(enable);
2233+
return 0;
2234+
#endif
2235+
}
2236+
22072237
static int dw_i3c_init(const struct device *dev)
22082238
{
22092239
const struct dw_i3c_config *config = dev->config;
@@ -2229,6 +2259,8 @@ static int dw_i3c_init(const struct device *dev)
22292259
k_sem_init(&data->sem_xfer, 0, 1);
22302260
k_mutex_init(&data->mt);
22312261

2262+
dw_i3c_pinctrl_enable(dev, true);
2263+
22322264
data->mode = i3c_bus_mode(&config->common.dev_list);
22332265

22342266
/* reset all */
@@ -2309,6 +2341,32 @@ static int dw_i3c_init(const struct device *dev)
23092341
return 0;
23102342
}
23112343

2344+
#if defined(CONFIG_PM_DEVICE)
2345+
static int dw_i3c_pm_ctrl(const struct device *dev, enum pm_device_action action)
2346+
{
2347+
const struct dw_i3c_config *config = dev->config;
2348+
2349+
LOG_DBG("PM action: %d", (int)action);
2350+
2351+
switch (action) {
2352+
case PM_DEVICE_ACTION_SUSPEND:
2353+
dw_i3c_enable_controller(config, false);
2354+
dw_i3c_pinctrl_enable(dev, false);
2355+
break;
2356+
2357+
case PM_DEVICE_ACTION_RESUME:
2358+
dw_i3c_pinctrl_enable(dev, true);
2359+
dw_i3c_enable_controller(config, true);
2360+
break;
2361+
2362+
default:
2363+
return -ENOTSUP;
2364+
}
2365+
2366+
return 0;
2367+
}
2368+
#endif
2369+
23122370
static DEVICE_API(i3c, dw_i3c_api) = {
23132371
.i2c_api.transfer = dw_i3c_i2c_api_transfer,
23142372

@@ -2348,8 +2406,17 @@ static DEVICE_API(i3c, dw_i3c_api) = {
23482406
irq_enable(DT_INST_IRQN(n)); \
23492407
}
23502408

2409+
#if defined(CONFIG_PINCTRL)
2410+
#define I3C_DW_PINCTRL_DEFINE(n) PINCTRL_DT_INST_DEFINE(n)
2411+
#define I3C_DW_PINCTRL_INIT(n) .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),
2412+
#else
2413+
#define I3C_DW_PINCTRL_DEFINE(n)
2414+
#define I3C_DW_PINCTRL_INIT(n)
2415+
#endif
2416+
23512417
#define DEFINE_DEVICE_FN(n) \
23522418
I3C_DW_IRQ_HANDLER(n) \
2419+
I3C_DW_PINCTRL_DEFINE(n); \
23532420
static struct i3c_device_desc dw_i3c_device_array_##n[] = I3C_DEVICE_ARRAY_DT_INST(n); \
23542421
static struct i3c_i2c_device_desc dw_i3c_i2c_device_array_##n[] = \
23552422
I3C_I2C_DEVICE_ARRAY_DT_INST(n); \
@@ -2368,9 +2435,11 @@ static DEVICE_API(i3c, dw_i3c_api) = {
23682435
.common.dev_list.num_i3c = ARRAY_SIZE(dw_i3c_device_array_##n), \
23692436
.common.dev_list.i2c = dw_i3c_i2c_device_array_##n, \
23702437
.common.dev_list.num_i2c = ARRAY_SIZE(dw_i3c_i2c_device_array_##n), \
2371-
}; \
2372-
DEVICE_DT_INST_DEFINE(n, dw_i3c_init, NULL, &dw_i3c_data_##n, &dw_i3c_cfg_##n, \
2373-
POST_KERNEL, CONFIG_I3C_CONTROLLER_INIT_PRIORITY, &dw_i3c_api);
2438+
I3C_DW_PINCTRL_INIT(n)}; \
2439+
PM_DEVICE_DT_INST_DEFINE(n, dw_i3c_pm_action); \
2440+
DEVICE_DT_INST_DEFINE(n, dw_i3c_init, PM_DEVICE_DT_INST_GET(n), &dw_i3c_data_##n, \
2441+
&dw_i3c_cfg_##n, POST_KERNEL, CONFIG_I3C_CONTROLLER_INIT_PRIORITY, \
2442+
&dw_i3c_api);
23742443

23752444
#define DT_DRV_COMPAT snps_designware_i3c
23762445
DT_INST_FOREACH_STATUS_OKAY(DEFINE_DEVICE_FN);

0 commit comments

Comments
 (0)