1*380639c7SRussell King /* 2*380639c7SRussell King * gpio-reg: single register individually fixed-direction GPIOs 3*380639c7SRussell King * 4*380639c7SRussell King * Copyright (C) 2016 Russell King 5*380639c7SRussell King * 6*380639c7SRussell King * This software is licensed under the terms of the GNU General Public 7*380639c7SRussell King * License version 2, as published by the Free Software Foundation, and 8*380639c7SRussell King * may be copied, distributed, and modified under those terms. 9*380639c7SRussell King */ 10*380639c7SRussell King #include <linux/gpio/driver.h> 11*380639c7SRussell King #include <linux/gpio/gpio-reg.h> 12*380639c7SRussell King #include <linux/io.h> 13*380639c7SRussell King #include <linux/slab.h> 14*380639c7SRussell King #include <linux/spinlock.h> 15*380639c7SRussell King 16*380639c7SRussell King struct gpio_reg { 17*380639c7SRussell King struct gpio_chip gc; 18*380639c7SRussell King spinlock_t lock; 19*380639c7SRussell King u32 direction; 20*380639c7SRussell King u32 out; 21*380639c7SRussell King void __iomem *reg; 22*380639c7SRussell King }; 23*380639c7SRussell King 24*380639c7SRussell King #define to_gpio_reg(x) container_of(x, struct gpio_reg, gc) 25*380639c7SRussell King 26*380639c7SRussell King static int gpio_reg_get_direction(struct gpio_chip *gc, unsigned offset) 27*380639c7SRussell King { 28*380639c7SRussell King struct gpio_reg *r = to_gpio_reg(gc); 29*380639c7SRussell King 30*380639c7SRussell King return r->direction & BIT(offset) ? 1 : 0; 31*380639c7SRussell King } 32*380639c7SRussell King 33*380639c7SRussell King static int gpio_reg_direction_output(struct gpio_chip *gc, unsigned offset, 34*380639c7SRussell King int value) 35*380639c7SRussell King { 36*380639c7SRussell King struct gpio_reg *r = to_gpio_reg(gc); 37*380639c7SRussell King 38*380639c7SRussell King if (r->direction & BIT(offset)) 39*380639c7SRussell King return -ENOTSUPP; 40*380639c7SRussell King 41*380639c7SRussell King gc->set(gc, offset, value); 42*380639c7SRussell King return 0; 43*380639c7SRussell King } 44*380639c7SRussell King 45*380639c7SRussell King static int gpio_reg_direction_input(struct gpio_chip *gc, unsigned offset) 46*380639c7SRussell King { 47*380639c7SRussell King struct gpio_reg *r = to_gpio_reg(gc); 48*380639c7SRussell King 49*380639c7SRussell King return r->direction & BIT(offset) ? 0 : -ENOTSUPP; 50*380639c7SRussell King } 51*380639c7SRussell King 52*380639c7SRussell King static void gpio_reg_set(struct gpio_chip *gc, unsigned offset, int value) 53*380639c7SRussell King { 54*380639c7SRussell King struct gpio_reg *r = to_gpio_reg(gc); 55*380639c7SRussell King unsigned long flags; 56*380639c7SRussell King u32 val, mask = BIT(offset); 57*380639c7SRussell King 58*380639c7SRussell King spin_lock_irqsave(&r->lock, flags); 59*380639c7SRussell King val = r->out; 60*380639c7SRussell King if (value) 61*380639c7SRussell King val |= mask; 62*380639c7SRussell King else 63*380639c7SRussell King val &= ~mask; 64*380639c7SRussell King r->out = val; 65*380639c7SRussell King writel_relaxed(val, r->reg); 66*380639c7SRussell King spin_unlock_irqrestore(&r->lock, flags); 67*380639c7SRussell King } 68*380639c7SRussell King 69*380639c7SRussell King static int gpio_reg_get(struct gpio_chip *gc, unsigned offset) 70*380639c7SRussell King { 71*380639c7SRussell King struct gpio_reg *r = to_gpio_reg(gc); 72*380639c7SRussell King u32 val, mask = BIT(offset); 73*380639c7SRussell King 74*380639c7SRussell King if (r->direction & mask) { 75*380639c7SRussell King /* 76*380639c7SRussell King * double-read the value, some registers latch after the 77*380639c7SRussell King * first read. 78*380639c7SRussell King */ 79*380639c7SRussell King readl_relaxed(r->reg); 80*380639c7SRussell King val = readl_relaxed(r->reg); 81*380639c7SRussell King } else { 82*380639c7SRussell King val = r->out; 83*380639c7SRussell King } 84*380639c7SRussell King return !!(val & mask); 85*380639c7SRussell King } 86*380639c7SRussell King 87*380639c7SRussell King static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask, 88*380639c7SRussell King unsigned long *bits) 89*380639c7SRussell King { 90*380639c7SRussell King struct gpio_reg *r = to_gpio_reg(gc); 91*380639c7SRussell King unsigned long flags; 92*380639c7SRussell King 93*380639c7SRussell King spin_lock_irqsave(&r->lock, flags); 94*380639c7SRussell King r->out = (r->out & ~*mask) | (*bits & *mask); 95*380639c7SRussell King writel_relaxed(r->out, r->reg); 96*380639c7SRussell King spin_unlock_irqrestore(&r->lock, flags); 97*380639c7SRussell King } 98*380639c7SRussell King 99*380639c7SRussell King /** 100*380639c7SRussell King * gpio_reg_init - add a fixed in/out register as gpio 101*380639c7SRussell King * @dev: optional struct device associated with this register 102*380639c7SRussell King * @base: start gpio number, or -1 to allocate 103*380639c7SRussell King * @num: number of GPIOs, maximum 32 104*380639c7SRussell King * @label: GPIO chip label 105*380639c7SRussell King * @direction: bitmask of fixed direction, one per GPIO signal, 1 = in 106*380639c7SRussell King * @def_out: initial GPIO output value 107*380639c7SRussell King * @names: array of %num strings describing each GPIO signal 108*380639c7SRussell King * 109*380639c7SRussell King * Add a single-register GPIO device containing up to 32 GPIO signals, 110*380639c7SRussell King * where each GPIO has a fixed input or output configuration. Only 111*380639c7SRussell King * input GPIOs are assumed to be readable from the register, and only 112*380639c7SRussell King * then after a double-read. Output values are assumed not to be 113*380639c7SRussell King * readable. 114*380639c7SRussell King */ 115*380639c7SRussell King struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg, 116*380639c7SRussell King int base, int num, const char *label, u32 direction, u32 def_out, 117*380639c7SRussell King const char *const *names) 118*380639c7SRussell King { 119*380639c7SRussell King struct gpio_reg *r; 120*380639c7SRussell King int ret; 121*380639c7SRussell King 122*380639c7SRussell King if (dev) 123*380639c7SRussell King r = devm_kzalloc(dev, sizeof(*r), GFP_KERNEL); 124*380639c7SRussell King else 125*380639c7SRussell King r = kzalloc(sizeof(*r), GFP_KERNEL); 126*380639c7SRussell King 127*380639c7SRussell King if (!r) 128*380639c7SRussell King return ERR_PTR(-ENOMEM); 129*380639c7SRussell King 130*380639c7SRussell King spin_lock_init(&r->lock); 131*380639c7SRussell King 132*380639c7SRussell King r->gc.label = label; 133*380639c7SRussell King r->gc.get_direction = gpio_reg_get_direction; 134*380639c7SRussell King r->gc.direction_input = gpio_reg_direction_input; 135*380639c7SRussell King r->gc.direction_output = gpio_reg_direction_output; 136*380639c7SRussell King r->gc.set = gpio_reg_set; 137*380639c7SRussell King r->gc.get = gpio_reg_get; 138*380639c7SRussell King r->gc.set_multiple = gpio_reg_set_multiple; 139*380639c7SRussell King r->gc.base = base; 140*380639c7SRussell King r->gc.ngpio = num; 141*380639c7SRussell King r->gc.names = names; 142*380639c7SRussell King r->direction = direction; 143*380639c7SRussell King r->out = def_out; 144*380639c7SRussell King r->reg = reg; 145*380639c7SRussell King 146*380639c7SRussell King if (dev) 147*380639c7SRussell King ret = devm_gpiochip_add_data(dev, &r->gc, r); 148*380639c7SRussell King else 149*380639c7SRussell King ret = gpiochip_add_data(&r->gc, r); 150*380639c7SRussell King 151*380639c7SRussell King return ret ? ERR_PTR(ret) : &r->gc; 152*380639c7SRussell King } 153*380639c7SRussell King 154*380639c7SRussell King int gpio_reg_resume(struct gpio_chip *gc) 155*380639c7SRussell King { 156*380639c7SRussell King struct gpio_reg *r = to_gpio_reg(gc); 157*380639c7SRussell King unsigned long flags; 158*380639c7SRussell King 159*380639c7SRussell King spin_lock_irqsave(&r->lock, flags); 160*380639c7SRussell King writel_relaxed(r->out, r->reg); 161*380639c7SRussell King spin_unlock_irqrestore(&r->lock, flags); 162*380639c7SRussell King 163*380639c7SRussell King return 0; 164*380639c7SRussell King } 165