31
31
#define INVALID_PORT 0xFF
32
32
#define INTERRUPT_COUNT 8
33
33
34
+ struct gpio_siwx91x_pin_config_info {
35
+ const struct device * port_dev ;
36
+ gpio_pin_t pin ;
37
+ gpio_flags_t flags ;
38
+ };
39
+
34
40
/* Types */
35
41
struct gpio_siwx91x_common_config {
36
42
EGPIO_Type * reg ;
37
43
uint8_t port_count ;
44
+ uint8_t max_pin_usage_count ;
38
45
};
39
46
40
47
struct gpio_siwx91x_port_config {
@@ -51,54 +58,24 @@ struct gpio_siwx91x_common_data {
51
58
/* a list of all ports */
52
59
const struct device * * ports ;
53
60
sl_gpio_t interrupts [INTERRUPT_COUNT ];
61
+ struct gpio_siwx91x_pin_config_info * pin_config_info ;
62
+ uint8_t cur_pin ;
54
63
};
55
64
56
65
struct gpio_siwx91x_port_data {
57
66
/* gpio_driver_data needs to be first */
58
67
struct gpio_driver_data common ;
59
68
/* port ISR callback routine address */
60
69
sys_slist_t callbacks ;
61
- #if defined(CONFIG_PM )
62
- /* stores the direction of each pin */
63
- uint16_t pin_direction [MAX_PIN_COUNT ];
64
- #endif
65
70
};
66
71
67
72
/* Functions */
68
- static int gpio_siwx91x_port_pm_action (const struct device * port , enum pm_device_action action )
69
- {
70
- __maybe_unused const struct gpio_siwx91x_port_config * config = port -> config ;
71
- __maybe_unused struct gpio_siwx91x_port_data * data = port -> data ;
72
- #if defined(CONFIG_PM )
73
- switch (action ) {
74
- case PM_DEVICE_ACTION_RESUME :
75
- for (int pin = 0 ; pin < MAX_PIN_COUNT ; ++ pin ) {
76
- if (config -> common .port_pin_mask & BIT (pin )) {
77
- sl_si91x_gpio_set_pin_direction (config -> hal_port , pin ,
78
- data -> pin_direction [pin ]);
79
- }
80
- }
81
- break ;
82
- case PM_DEVICE_ACTION_SUSPEND :
83
- for (int pin = 0 ; pin < MAX_PIN_COUNT ; ++ pin ) {
84
- if (config -> common .port_pin_mask & BIT (pin )) {
85
- data -> pin_direction [pin ] =
86
- sl_si91x_gpio_get_pin_direction (config -> hal_port , pin );
87
- }
88
- }
89
- break ;
90
- default :
91
- return - ENOTSUP ;
92
- }
93
- #endif
94
- return 0 ;
95
- }
96
-
97
73
static int gpio_siwx91x_pin_configure (const struct device * dev , gpio_pin_t pin , gpio_flags_t flags )
98
74
{
99
75
const struct gpio_siwx91x_port_config * cfg = dev -> config ;
100
76
const struct device * parent = cfg -> parent ;
101
77
const struct gpio_siwx91x_common_config * pcfg = parent -> config ;
78
+ struct gpio_siwx91x_common_data * pdata = parent -> data ;
102
79
sl_status_t status ;
103
80
sl_si91x_gpio_driver_disable_state_t disable_state = GPIO_HZ ;
104
81
@@ -158,6 +135,47 @@ static int gpio_siwx91x_pin_configure(const struct device *dev, gpio_pin_t pin,
158
135
159
136
sl_si91x_gpio_set_pin_direction (cfg -> hal_port , pin , (flags & GPIO_OUTPUT ) ? 0 : 1 );
160
137
138
+ if (pdata -> cur_pin < pcfg -> max_pin_usage_count ) {
139
+ pdata -> pin_config_info [pdata -> cur_pin ].port_dev = dev ;
140
+ pdata -> pin_config_info [pdata -> cur_pin ].pin = pin ;
141
+ pdata -> pin_config_info [pdata -> cur_pin ].flags = flags ;
142
+ pdata -> cur_pin ++ ;
143
+ } else {
144
+ return - EIO ;
145
+ }
146
+
147
+ return 0 ;
148
+ }
149
+
150
+ static int gpio_siwx91x_pm_action (const struct device * dev , enum pm_device_action action )
151
+ {
152
+ const struct gpio_siwx91x_common_config * pcfg = dev -> config ;
153
+ struct gpio_siwx91x_common_data * pdata = dev -> data ;
154
+ int ret ;
155
+ int i = 0 ;
156
+
157
+ switch (action ) {
158
+ case PM_DEVICE_ACTION_TURN_ON :
159
+ while (pdata -> pin_config_info [i ].port_dev != NULL &&
160
+ i < pcfg -> max_pin_usage_count ) {
161
+ ret = gpio_siwx91x_pin_configure (pdata -> pin_config_info [i ].port_dev ,
162
+ pdata -> pin_config_info [i ].pin ,
163
+ pdata -> pin_config_info [i ].flags );
164
+ if (ret ) {
165
+ return ret ;
166
+ }
167
+ i ++ ;
168
+ }
169
+ break ;
170
+ case PM_DEVICE_ACTION_TURN_OFF :
171
+ break ;
172
+ case PM_DEVICE_ACTION_RESUME :
173
+ break ;
174
+ case PM_DEVICE_ACTION_SUSPEND :
175
+ break ;
176
+ default :
177
+ return - ENOTSUP ;
178
+ }
161
179
return 0 ;
162
180
}
163
181
@@ -330,7 +348,7 @@ static inline int gpio_siwx91x_init_port(const struct device *port)
330
348
__ASSERT (cfg -> port < parent -> config -> port_count , "Too many ports" );
331
349
data -> ports [cfg -> port ] = port ;
332
350
333
- return pm_device_driver_init ( port , gpio_siwx91x_port_pm_action ) ;
351
+ return 0 ;
334
352
}
335
353
336
354
static void gpio_siwx91x_isr (const struct device * parent )
@@ -396,10 +414,9 @@ static DEVICE_API(gpio, gpio_siwx91x_api) = {
396
414
}; \
397
415
static struct gpio_siwx91x_port_data gpio_siwx91x_port_data##n; \
398
416
\
399
- PM_DEVICE_DT_INST_DEFINE(n, gpio_siwx91x_port_pm_action); \
400
- DEVICE_DT_DEFINE(n, gpio_siwx91x_init_port, PM_DEVICE_DT_INST_GET(n), \
401
- &gpio_siwx91x_port_data##n, &gpio_siwx91x_port_config##n, PRE_KERNEL_1, \
402
- CONFIG_GPIO_INIT_PRIORITY, &gpio_siwx91x_api);
417
+ DEVICE_DT_DEFINE(n, gpio_siwx91x_init_port, NULL, &gpio_siwx91x_port_data##n, \
418
+ &gpio_siwx91x_port_config##n, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, \
419
+ &gpio_siwx91x_api);
403
420
404
421
#define CONFIGURE_SHARED_INTERRUPT (node_id , prop , idx ) \
405
422
IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, idx, irq), DT_IRQ_BY_IDX(node_id, idx, priority), \
@@ -410,12 +427,16 @@ static DEVICE_API(gpio, gpio_siwx91x_common_api) = { };
410
427
411
428
#define GPIO_CONTROLLER_INIT (idx ) \
412
429
const struct device *ports_##idx[DT_INST_PROP(idx, silabs_port_count)]; \
430
+ struct gpio_siwx91x_pin_config_info \
431
+ pin_config_info_##idx[DT_INST_PROP(idx, silabs_max_pin_usage_count)]; \
413
432
static const struct gpio_siwx91x_common_config gpio_siwx91x_config##idx = { \
414
433
.reg = (EGPIO_Type *)DT_INST_REG_ADDR(idx), \
415
434
.port_count = DT_INST_PROP(idx, silabs_port_count), \
435
+ .max_pin_usage_count = DT_INST_PROP(idx, silabs_max_pin_usage_count), \
416
436
}; \
417
437
static struct gpio_siwx91x_common_data gpio_siwx91x_data##idx = { \
418
438
.ports = ports_##idx, \
439
+ .pin_config_info = pin_config_info_##idx, \
419
440
}; \
420
441
\
421
442
static int gpio_siwx91x_init_controller_##idx(const struct device *dev) \
@@ -432,11 +453,12 @@ static DEVICE_API(gpio, gpio_siwx91x_common_api) = { };
432
453
data->interrupts[i].port = INVALID_PORT; \
433
454
} \
434
455
DT_INST_FOREACH_PROP_ELEM(idx, interrupt_names, CONFIGURE_SHARED_INTERRUPT); \
435
- return 0; \
456
+ return pm_device_driver_init(dev, gpio_siwx91x_pm_action); \
436
457
} \
437
- DEVICE_DT_INST_DEFINE(idx, gpio_siwx91x_init_controller_##idx, NULL, \
438
- &gpio_siwx91x_data##idx, &gpio_siwx91x_config##idx, \
439
- PRE_KERNEL_1, CONFIG_GPIO_SILABS_SIWX91X_COMMON_INIT_PRIORITY, \
458
+ PM_DEVICE_DT_INST_DEFINE(idx, gpio_siwx91x_pm_action); \
459
+ DEVICE_DT_INST_DEFINE(idx, gpio_siwx91x_init_controller_##idx, PM_DEVICE_DT_INST_GET(idx), \
460
+ &gpio_siwx91x_data##idx, &gpio_siwx91x_config##idx, PRE_KERNEL_1, \
461
+ CONFIG_GPIO_SILABS_SIWX91X_COMMON_INIT_PRIORITY, \
440
462
&gpio_siwx91x_common_api); \
441
463
DT_INST_FOREACH_CHILD_STATUS_OKAY(idx, GPIO_PORT_INIT);
442
464
0 commit comments