36 #include "shared-isr.h"
40 #define SWPORTA_DR 0x00
41 #define SWPORTA_DDR 0x04
44 #define INTTYPE_LEVEL 0x38
45 #define INT_POLARITY 0x3c
46 #define INTSTATUS 0x40
47 #define RAW_INTSTATUS 0x44
49 #define PORTA_EOI 0x4c
50 #define EXT_PORTA 0x50
57 #define HIGHEST_REG LS_SYNC
59 #if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING
60 #define MMIO_SZ MIN_PAGE_SIZE
62 #define MMIO_SZ (HIGHEST_REG + 4)
67 struct gpio_internal_data {
68 quarkX1000_gpio_callback callback;
71 static struct gpio_internal_data data;
73 void quarkX1000_gpio_mmin(uint32_t offset, uint32_t *res);
74 SYSCALLS_DEFINE_SINGLETON(quarkX1000_gpio_mmin, drv,
75 uint32_t offset, uint32_t *res)
79 PROT_DOMAINS_VALIDATE_PTR(loc_res, res,
sizeof(*res));
80 if(HIGHEST_REG < offset) {
84 prot_domains_enable_mmio();
85 PCI_MMIO_READL(drv, *loc_res, offset);
86 prot_domains_disable_mmio();
89 static inline uint32_t
93 quarkX1000_gpio_mmin(offset, &res);
97 void quarkX1000_gpio_mmout(uint32_t offset, uint32_t val);
98 SYSCALLS_DEFINE_SINGLETON(quarkX1000_gpio_mmout, drv,
99 uint32_t offset, uint32_t val)
101 if(HIGHEST_REG < offset) {
105 prot_domains_enable_mmio();
106 PCI_MMIO_WRITEL(drv, offset, val);
107 prot_domains_disable_mmio();
111 write(uint32_t offset, uint32_t val)
113 quarkX1000_gpio_mmout(offset, val);
118 set_bit(uint32_t offset, uint32_t bit, uint32_t value)
135 int_status = read(INTSTATUS);
137 if(int_status == 0) {
142 data.callback(int_status);
144 write(PORTA_EOI, -1);
150 gpio_interrupt_config(uint8_t pin,
int flags)
153 set_bit(SWPORTA_DDR, pin, 0);
156 set_bit(INTEN, pin, 1);
159 set_bit(INTMASK, pin, 0);
162 set_bit(INT_POLARITY, pin, !!(flags & QUARKX1000_GPIO_ACTIVE_HIGH));
165 set_bit(INTTYPE_LEVEL, pin, !!(flags & QUARKX1000_GPIO_EDGE));
168 set_bit(DEBOUNCE, pin, !!(flags & QUARKX1000_GPIO_DEBOUNCE));
171 set_bit(LS_SYNC, 0, !!(flags & QUARKX1000_GPIO_CLOCK_SYNC));
175 quarkX1000_gpio_config(uint8_t pin,
int flags)
177 if (((flags & QUARKX1000_GPIO_IN) && (flags & QUARKX1000_GPIO_OUT)) ||
178 ((flags & QUARKX1000_GPIO_INT) && (flags & QUARKX1000_GPIO_OUT))) {
182 if (flags & QUARKX1000_GPIO_INT) {
183 gpio_interrupt_config(pin, flags);
186 set_bit(SWPORTA_DDR, pin, !!(flags & QUARKX1000_GPIO_OUT));
189 set_bit(INTEN, pin, 0);
196 quarkX1000_gpio_config_port(
int flags)
200 for (i = 0; i < PINS; i++) {
201 if (quarkX1000_gpio_config(i, flags) < 0) {
210 quarkX1000_gpio_read(uint8_t pin, uint8_t *value)
212 uint32_t value32 = read(EXT_PORTA);
213 *value = !!(value32 &
BIT(pin));
219 quarkX1000_gpio_write(uint8_t pin, uint8_t value)
221 set_bit(SWPORTA_DR, pin, !!value);
226 quarkX1000_gpio_read_port(uint8_t *value)
228 uint32_t value32 = read(EXT_PORTA);
229 *value = value32 & ~0xFFFFFF00;
235 quarkX1000_gpio_write_port(uint8_t value)
237 write(SWPORTA_DR, value);
242 quarkX1000_gpio_set_callback(quarkX1000_gpio_callback callback)
244 data.callback = callback;
249 quarkX1000_gpio_clock_enable(
void)
251 set_bit(LS_SYNC, 0, 1);
255 quarkX1000_gpio_clock_disable(
void)
257 set_bit(LS_SYNC, 0, 0);
260 DEFINE_SHARED_IRQ(GPIO_IRQ, IRQAGENT3, INTC, PIRQC, gpio_isr);
263 quarkX1000_gpio_init(
void)
271 pci_addr.
reg_off = PCI_CONFIG_REG_BAR1;
273 pci_command_enable(pci_addr, PCI_CMD_1_MEM_SPACE_EN);
275 PROT_DOMAINS_INIT_ID(drv);
276 pci_init(&drv, pci_addr, MMIO_SZ, 0, 0);
277 SYSCALLS_INIT(quarkX1000_gpio_mmin);
278 SYSCALLS_AUTHZ(quarkX1000_gpio_mmin, drv);
279 SYSCALLS_INIT(quarkX1000_gpio_mmout);
280 SYSCALLS_AUTHZ(quarkX1000_gpio_mmout, drv);
284 quarkX1000_gpio_clock_enable();
uint32_t func
Function number.
#define BIT(x)
Useful to reference a single bit of a byte.
PCI configuration address.
uint32_t dev
Device number.
static uint8_t int_status(void)
Check whether a data or wake on motion interrupt has occurred.
Data associated with each protection domain that is owned by clients of that domain and used to ident...
uint32_t reg_off
Register/offset number.