Skip to content

Commit 86fa606

Browse files
udivya73nashif
authored andcommitted
drivers: gpio: Add GPIO driver for Intel Elkhart Lake
Added support for GPIO driver for Intel Elkhart Lake board. The GPIO driver will support pin value read/write operations, pin direction and interrupt configuration. ACPI enumeration support and support for different GPIO communities is also present. Verified on ehl_crb. Signed-off-by: U Divya <[email protected]>
1 parent f6436a1 commit 86fa606

File tree

6 files changed

+386
-51
lines changed

6 files changed

+386
-51
lines changed

drivers/gpio/gpio_intel.c

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
* we export GPIO_INTEL_NR_SUBDEVS devices to the kernel.
2020
*/
2121

22-
#define GPIO_INTEL_NR_SUBDEVS 10
23-
2422
#include <errno.h>
2523
#include <drivers/gpio.h>
2624
#include <soc.h>
@@ -33,8 +31,6 @@
3331

3432
BUILD_ASSERT(DT_INST_IRQN(0) == 14);
3533

36-
#define REG_PAD_BASE_ADDR 0x000C
37-
3834
#define REG_MISCCFG 0x0010
3935
#define MISCCFG_IRQ_ROUTE_POS 3
4036

@@ -45,12 +41,10 @@ BUILD_ASSERT(DT_INST_IRQN(0) == 14);
4541
#define PAD_OWN_ISH 2
4642
#define PAD_OWN_IE 3
4743

48-
#define REG_PAD_HOST_SW_OWNER 0x0080
4944
#define PAD_HOST_SW_OWN_GPIO 1
5045
#define PAD_HOST_SW_OWN_ACPI 0
5146

5247
#define REG_GPI_INT_STS_BASE 0x0100
53-
#define REG_GPI_INT_EN_BASE 0x0110
5448

5549
#define PAD_CFG0_RXPADSTSEL BIT(29)
5650
#define PAD_CFG0_RXRAW1 BIT(28)
@@ -104,26 +98,34 @@ BUILD_ASSERT(DT_INST_IRQN(0) == 14);
10498
struct gpio_intel_config {
10599
/* gpio_driver_config needs to be first */
106100
struct gpio_driver_config common;
101+
107102
DEVICE_MMIO_NAMED_ROM(reg_base);
108103

109104
uint8_t pin_offset;
105+
uint8_t group_index;
110106
uint8_t num_pins;
111107
};
112108

113109
struct gpio_intel_data {
114110
/* gpio_driver_data needs to be first */
115111
struct gpio_driver_data common;
112+
116113
DEVICE_MMIO_NAMED_RAM(reg_base);
117114

118115
/* Pad base address */
119-
uint32_t pad_base;
116+
uint32_t pad_base;
120117

121-
sys_slist_t cb;
118+
sys_slist_t cb;
122119
};
123120

124121
static inline mm_reg_t regs(const struct device *dev)
125122
{
126-
return DEVICE_MMIO_NAMED_GET(dev, reg_base);
123+
return GPIO_REG_BASE(DEVICE_MMIO_NAMED_GET(dev, reg_base));
124+
}
125+
126+
static inline mm_reg_t pad_base(const struct device *dev)
127+
{
128+
return GPIO_PAD_BASE(DEVICE_MMIO_NAMED_GET(dev, reg_base));
127129
}
128130

129131
#ifdef CONFIG_GPIO_INTEL_CHECK_PERMS
@@ -138,16 +140,18 @@ static inline mm_reg_t regs(const struct device *dev)
138140
static bool check_perm(const struct device *dev, uint32_t raw_pin)
139141
{
140142
struct gpio_intel_data *data = dev->data;
141-
uint32_t offset, val;
143+
const struct gpio_intel_config *cfg = dev->config;
144+
uint32_t offset, val, pin_offset;
142145

146+
pin_offset = cfg->pin_offset;
143147
/* First is to establish that host software owns the pin */
144148

145149
/* read the Pad Ownership register related to the pin */
146-
offset = REG_PAD_OWNER_BASE + ((raw_pin >> 3) << 2);
150+
offset = GPIO_PAD_OWNERSHIP(raw_pin, pin_offset);
147151
val = sys_read32(regs(dev) + offset);
148152

149153
/* get the bits about ownership */
150-
offset = raw_pin % 8;
154+
offset = GPIO_OWNERSHIP_BIT(raw_pin);
151155
val = (val >> offset) & PAD_OWN_MASK;
152156
if (val) {
153157
/* PAD_OWN_HOST == 0, so !0 => false*/
@@ -191,7 +195,7 @@ static void gpio_intel_isr(const struct device *dev)
191195
data = dev->data;
192196

193197
reg = regs(dev) + REG_GPI_INT_STS_BASE
194-
+ ((cfg->pin_offset >> 5) << 2);
198+
+ GPIO_INTERRUPT_BASE(cfg);
195199
int_sts = sys_read32(reg);
196200
acc_mask = 0U;
197201

@@ -223,14 +227,14 @@ static int gpio_intel_config(const struct device *dev,
223227

224228
pin = k_array_index_sanitize(pin, cfg->num_pins + 1);
225229

226-
raw_pin = cfg->pin_offset + pin;
230+
raw_pin = GPIO_RAW_PIN(pin, cfg->pin_offset);
227231

228232
if (!check_perm(dev, raw_pin)) {
229233
return -EINVAL;
230234
}
231235

232236
/* read in pad configuration register */
233-
reg = regs(dev) + data->pad_base + (raw_pin * 8U);
237+
reg = regs(dev) + data->pad_base + (raw_pin * PIN_OFFSET);
234238
cfg0 = sys_read32(reg);
235239
cfg1 = sys_read32(reg + 4);
236240

@@ -300,28 +304,28 @@ static int gpio_intel_pin_interrupt_configure(const struct device *dev,
300304

301305
pin = k_array_index_sanitize(pin, cfg->num_pins + 1);
302306

303-
raw_pin = cfg->pin_offset + pin;
307+
raw_pin = GPIO_RAW_PIN(pin, cfg->pin_offset);
304308

305309
if (!check_perm(dev, raw_pin)) {
306310
return -EINVAL;
307311
}
308312

309313
/* set owner to GPIO driver mode for legacy interrupt mode */
310-
reg = regs(dev) + REG_PAD_HOST_SW_OWNER;
314+
reg = regs(dev) + REG_PAD_HOST_SW_OWNER + GPIO_BASE(cfg);
311315
sys_bitfield_set_bit(reg, raw_pin);
312316

313317
/* read in pad configuration register */
314-
reg = regs(dev) + data->pad_base + (raw_pin * 8U);
318+
reg = regs(dev) + data->pad_base + (raw_pin * PIN_OFFSET);
315319
cfg0 = sys_read32(reg);
316320
cfg1 = sys_read32(reg + 4);
317321

318-
reg_en = regs(dev) + REG_GPI_INT_EN_BASE;
322+
reg_en = regs(dev) + REG_GPI_INT_EN_BASE + GPIO_BASE(cfg);
319323

320324
/* disable interrupt bit first before setup */
321325
sys_bitfield_clear_bit(reg_en, raw_pin);
322326

323327
/* clear (by setting) interrupt status bit */
324-
reg_sts = regs(dev) + REG_GPI_INT_STS_BASE;
328+
reg_sts = regs(dev) + REG_GPI_INT_STS_BASE + GPIO_BASE(cfg);
325329
sys_bitfield_set_bit(reg_sts, raw_pin);
326330

327331
/* clear level/edge configuration bits */
@@ -408,13 +412,13 @@ static int port_get_raw(const struct device *dev, uint32_t mask,
408412

409413
mask &= ~BIT(pin);
410414

411-
raw_pin = cfg->pin_offset + pin;
415+
raw_pin = GPIO_RAW_PIN(pin, cfg->pin_offset);
412416

413417
if (!check_perm(dev, raw_pin)) {
414418
continue;
415419
}
416420

417-
reg_addr = regs(dev) + data->pad_base + (raw_pin * 8U);
421+
reg_addr = regs(dev) + data->pad_base + (raw_pin * PIN_OFFSET);
418422
reg_val = sys_read32(reg_addr);
419423

420424
if ((reg_val & cmp) != 0U) {
@@ -441,13 +445,13 @@ static int port_set_raw(const struct device *dev, uint32_t mask,
441445

442446
mask &= ~BIT(pin);
443447

444-
raw_pin = cfg->pin_offset + pin;
448+
raw_pin = GPIO_RAW_PIN(pin, cfg->pin_offset);
445449

446450
if (!check_perm(dev, raw_pin)) {
447451
continue;
448452
}
449453

450-
reg_addr = regs(dev) + data->pad_base + (raw_pin * 8U);
454+
reg_addr = regs(dev) + data->pad_base + (raw_pin * PIN_OFFSET);
451455
reg_val = sys_read32(reg_addr);
452456

453457
if ((value & BIT(pin)) != 0) {
@@ -525,7 +529,7 @@ int gpio_intel_init(const struct device *dev)
525529
struct gpio_intel_data *data = dev->data;
526530

527531
DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE);
528-
data->pad_base = sys_read32(regs(dev) + REG_PAD_BASE_ADDR);
532+
data->pad_base = pad_base(dev);
529533

530534
__ASSERT(nr_isr_devs < GPIO_INTEL_NR_SUBDEVS, "too many subdevs");
531535

@@ -551,26 +555,27 @@ int gpio_intel_init(const struct device *dev)
551555
return 0;
552556
}
553557

554-
#define GPIO_INTEL_DEV_CFG_DATA(n) \
555-
static const struct gpio_intel_config \
556-
gpio_intel_cfg_##n = { \
557-
.common = { \
558-
.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \
559-
}, \
560-
DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)), \
561-
.pin_offset = DT_INST_PROP(n, pin_offset), \
562-
.num_pins = DT_INST_PROP(n, ngpios), \
563-
}; \
564-
\
565-
static struct gpio_intel_data gpio_intel_data_##n; \
566-
\
567-
DEVICE_DT_INST_DEFINE(n, \
568-
gpio_intel_init, \
569-
NULL, \
570-
&gpio_intel_data_##n, \
571-
&gpio_intel_cfg_##n, \
572-
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
573-
&gpio_intel_api);
558+
#define GPIO_INTEL_DEV_CFG_DATA(n) \
559+
static const struct gpio_intel_config \
560+
gpio_intel_cfg_##n = { \
561+
.common = { \
562+
.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \
563+
}, \
564+
DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)), \
565+
.pin_offset = DT_INST_PROP(n, pin_offset), \
566+
.group_index = DT_INST_PROP_OR(n, group_index, 0), \
567+
.num_pins = DT_INST_PROP(n, ngpios), \
568+
}; \
569+
\
570+
static struct gpio_intel_data gpio_intel_data_##n; \
571+
\
572+
DEVICE_DT_INST_DEFINE(n, \
573+
gpio_intel_init, \
574+
NULL, \
575+
&gpio_intel_data_##n, \
576+
&gpio_intel_cfg_##n, \
577+
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
578+
&gpio_intel_api);
574579

575580
/* "sub" devices. no more than GPIO_INTEL_NR_SUBDEVS of these! */
576581
DT_INST_FOREACH_STATUS_OKAY(GPIO_INTEL_DEV_CFG_DATA)

dts/bindings/gpio/intel,gpio.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ properties:
1414
label:
1515
required: true
1616

17-
community_base:
18-
type: int
19-
description: Base address of the community to which this GPIO belongs to
20-
2117
group-index:
2218
type: int
2319
description: Group number for this GPIO entry

0 commit comments

Comments
 (0)