static int exynos5422PinMode(int i, enum pinmode_t mode) { struct layout_t *pin = NULL; unsigned long addr = 0; uint32_t val = 0; if(exynos5422->map == NULL) { wiringXLog(LOG_ERR, "The %s %s has not yet been mapped", exynos5422->brand, exynos5422->chip); return -1; } if(exynos5422->fd <= 0 || exynos5422->gpio == NULL) { wiringXLog(LOG_ERR, "The %s %s has not yet been setup by wiringX", exynos5422->brand, exynos5422->chip); return -1; } pin = &exynos5422->layout[exynos5422->map[i]]; addr = (unsigned long)(exynos5422->gpio[pin->addr] + exynos5422->base_offs[pin->addr] + pin->con.offset); pin->mode = mode; val = soc_readl(addr); if(mode == PINMODE_OUTPUT) { val &= ~(0xF << pin->con.bit); val |= (0x1 << pin->con.bit); } else if(mode == PINMODE_INPUT) { val &= ~(0xF << pin->con.bit); } soc_writel(addr, val); return 0; }
static int exynos5422DigitalRead(int i) { void *gpio = NULL; struct layout_t *pin = NULL; unsigned long addr = 0; uint32_t val = 0; pin = &exynos5422->layout[exynos5422->map[i]]; gpio = exynos5422->gpio[pin->addr]; addr = (unsigned long)(gpio + exynos5422->base_offs[pin->addr] + pin->dat.offset); if(exynos5422->map == NULL) { wiringXLog(LOG_ERR, "The %s %s has not yet been mapped", exynos5422->brand, exynos5422->chip); return -1; } if(exynos5422->fd <= 0 || exynos5422->gpio == NULL) { wiringXLog(LOG_ERR, "The %s %s has not yet been setup by wiringX", exynos5422->brand, exynos5422->chip); return -1; } if(pin->mode != PINMODE_INPUT) { wiringXLog(LOG_ERR, "The %s %s GPIO %d is not set to input mode", exynos5422->brand, exynos5422->chip, i); return -1; } val = soc_readl(addr); return (int)((val & (1 << pin->dat.bit)) >> pin->dat.bit); }
static int exynos5422DigitalWrite(int i, enum digital_value_t value) { struct layout_t *pin = NULL; unsigned long addr = 0; uint32_t val = 0; pin = &exynos5422->layout[exynos5422->map[i]]; if(exynos5422->map == NULL) { wiringXLog(LOG_ERR, "The %s %s has not yet been mapped", exynos5422->brand, exynos5422->chip); return -1; } if(exynos5422->fd <= 0 || exynos5422->gpio == NULL) { wiringXLog(LOG_ERR, "The %s %s has not yet been setup by wiringX", exynos5422->brand, exynos5422->chip); return -1; } if(pin->mode != PINMODE_OUTPUT) { wiringXLog(LOG_ERR, "The %s %s GPIO %d is not set to output mode", exynos5422->brand, exynos5422->chip, i); return -1; } addr = (unsigned long)(exynos5422->gpio[pin->addr] + exynos5422->base_offs[pin->addr] + pin->dat.offset); val = soc_readl(addr); if(value == HIGH) { soc_writel(addr, val | (1 << pin->dat.bit)); } else { soc_writel(addr, val & ~(1 << pin->dat.bit)); } return 0; }
static int broadcom2836PinMode(int i, enum pinmode_t mode) { struct layout_t *pin = NULL; unsigned long addr = 0; uint32_t val = 0; if(broadcom2836->map == NULL) { wiringXLog(LOG_ERR, "The %s %s has not yet been mapped", broadcom2836->brand, broadcom2836->chip); return -1; } if(broadcom2836->fd <= 0 || broadcom2836->gpio == NULL) { wiringXLog(LOG_ERR, "The %s %s has not yet been setup by wiringX", broadcom2836->brand, broadcom2836->chip); return -1; } pin = &broadcom2836->layout[broadcom2836->map[i]]; addr = (unsigned long)(broadcom2836->gpio[pin->addr] + broadcom2836->base_offs[pin->addr] + pin->select.offset); pin->mode = mode; val = soc_readl(addr); if(mode == PINMODE_OUTPUT) { val |= (1 << pin->select.bit); } else if(mode == PINMODE_INPUT) { val &= ~(1 << pin->select.bit); } val &= ~(1 << (pin->select.bit+1)); val &= ~(1 << (pin->select.bit+2)); soc_writel(addr, val); return 0; }
static void unmask_megamod(struct irq_data *data) { struct megamod_pic *pic = irq_data_get_irq_chip_data(data); irq_hw_number_t src = irqd_to_hwirq(data); u32 __iomem *evtmask = &pic->regs->evtmask[src / 32]; raw_spin_lock(&pic->lock); soc_writel(soc_readl(evtmask) & ~(1 << (src & 31)), evtmask); raw_spin_unlock(&pic->lock); }
static int get_exception(void) { int i, bit; u32 mask; for (i = 0; i < NR_COMBINERS; i++) { mask = soc_readl(&mm_pic->regs->mexpflag[i]); if (mask) { bit = __ffs(mask); soc_writel(1 << bit, &mm_pic->regs->evtclr[i]); return (i * 32) + bit; } } return -1; }
static void __init set_megamod_mux(struct megamod_pic *pic, int src, int output) { int index, offset; u32 val; if (src < 0 || src >= (NR_COMBINERS * 32)) { pic->output_to_irq[output] = IRQ_UNMAPPED; return; } /* */ index = output / 4; offset = (output & 3) * 8; val = soc_readl(&pic->regs->intmux[index]); val &= ~(0xff << offset); val |= src << offset; soc_writel(val, &pic->regs->intmux[index]); }
static void megamod_irq_cascade(unsigned int irq, struct irq_desc *desc) { struct megamod_cascade_data *cascade; struct megamod_pic *pic; u32 events; int n, idx; cascade = irq_desc_get_handler_data(desc); pic = cascade->pic; idx = cascade->index; while ((events = soc_readl(&pic->regs->mevtflag[idx])) != 0) { n = __ffs(events); irq = irq_linear_revmap(pic->irqhost, idx * 32 + n); soc_writel(1 << n, &pic->regs->evtclr[idx]); generic_handle_irq(irq); } }