1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2015-2018 Pengutronix, Uwe Kleine-König <kernel@pengutronix.de> 4 */ 5 6 #include <linux/module.h> 7 #include <linux/siox.h> 8 #include <linux/gpio/driver.h> 9 #include <linux/of.h> 10 11 struct gpio_siox_ddata { 12 struct gpio_chip gchip; 13 struct irq_chip ichip; 14 struct mutex lock; 15 u8 setdata[1]; 16 u8 getdata[3]; 17 18 raw_spinlock_t irqlock; 19 u32 irq_enable; 20 u32 irq_status; 21 u32 irq_type[20]; 22 }; 23 24 /* 25 * Note that this callback only sets the value that is clocked out in the next 26 * cycle. 27 */ 28 static int gpio_siox_set_data(struct siox_device *sdevice, u8 status, u8 buf[]) 29 { 30 struct gpio_siox_ddata *ddata = dev_get_drvdata(&sdevice->dev); 31 32 mutex_lock(&ddata->lock); 33 buf[0] = ddata->setdata[0]; 34 mutex_unlock(&ddata->lock); 35 36 return 0; 37 } 38 39 static int gpio_siox_get_data(struct siox_device *sdevice, const u8 buf[]) 40 { 41 struct gpio_siox_ddata *ddata = dev_get_drvdata(&sdevice->dev); 42 size_t offset; 43 u32 trigger; 44 45 mutex_lock(&ddata->lock); 46 47 raw_spin_lock_irq(&ddata->irqlock); 48 49 for (offset = 0; offset < 12; ++offset) { 50 unsigned int bitpos = 11 - offset; 51 unsigned int gpiolevel = buf[bitpos / 8] & (1 << bitpos % 8); 52 unsigned int prev_level = 53 ddata->getdata[bitpos / 8] & (1 << (bitpos % 8)); 54 u32 irq_type = ddata->irq_type[offset]; 55 56 if (gpiolevel) { 57 if ((irq_type & IRQ_TYPE_LEVEL_HIGH) || 58 ((irq_type & IRQ_TYPE_EDGE_RISING) && !prev_level)) 59 ddata->irq_status |= 1 << offset; 60 } else { 61 if ((irq_type & IRQ_TYPE_LEVEL_LOW) || 62 ((irq_type & IRQ_TYPE_EDGE_FALLING) && prev_level)) 63 ddata->irq_status |= 1 << offset; 64 } 65 } 66 67 trigger = ddata->irq_status & ddata->irq_enable; 68 69 raw_spin_unlock_irq(&ddata->irqlock); 70 71 ddata->getdata[0] = buf[0]; 72 ddata->getdata[1] = buf[1]; 73 ddata->getdata[2] = buf[2]; 74 75 mutex_unlock(&ddata->lock); 76 77 for (offset = 0; offset < 12; ++offset) { 78 if (trigger & (1 << offset)) { 79 struct irq_domain *irqdomain = ddata->gchip.irq.domain; 80 unsigned int irq = irq_find_mapping(irqdomain, offset); 81 82 /* 83 * Conceptually handle_nested_irq should call the flow 84 * handler of the irq chip. But it doesn't, so we have 85 * to clean the irq_status here. 86 */ 87 raw_spin_lock_irq(&ddata->irqlock); 88 ddata->irq_status &= ~(1 << offset); 89 raw_spin_unlock_irq(&ddata->irqlock); 90 91 handle_nested_irq(irq); 92 } 93 } 94 95 return 0; 96 } 97 98 static void gpio_siox_irq_ack(struct irq_data *d) 99 { 100 struct irq_chip *ic = irq_data_get_irq_chip(d); 101 struct gpio_siox_ddata *ddata = 102 container_of(ic, struct gpio_siox_ddata, ichip); 103 104 raw_spin_lock(&ddata->irqlock); 105 ddata->irq_status &= ~(1 << d->hwirq); 106 raw_spin_unlock(&ddata->irqlock); 107 } 108 109 static void gpio_siox_irq_mask(struct irq_data *d) 110 { 111 struct irq_chip *ic = irq_data_get_irq_chip(d); 112 struct gpio_siox_ddata *ddata = 113 container_of(ic, struct gpio_siox_ddata, ichip); 114 115 raw_spin_lock(&ddata->irqlock); 116 ddata->irq_enable &= ~(1 << d->hwirq); 117 raw_spin_unlock(&ddata->irqlock); 118 } 119 120 static void gpio_siox_irq_unmask(struct irq_data *d) 121 { 122 struct irq_chip *ic = irq_data_get_irq_chip(d); 123 struct gpio_siox_ddata *ddata = 124 container_of(ic, struct gpio_siox_ddata, ichip); 125 126 raw_spin_lock(&ddata->irqlock); 127 ddata->irq_enable |= 1 << d->hwirq; 128 raw_spin_unlock(&ddata->irqlock); 129 } 130 131 static int gpio_siox_irq_set_type(struct irq_data *d, u32 type) 132 { 133 struct irq_chip *ic = irq_data_get_irq_chip(d); 134 struct gpio_siox_ddata *ddata = 135 container_of(ic, struct gpio_siox_ddata, ichip); 136 137 raw_spin_lock(&ddata->irqlock); 138 ddata->irq_type[d->hwirq] = type; 139 raw_spin_unlock(&ddata->irqlock); 140 141 return 0; 142 } 143 144 static int gpio_siox_get(struct gpio_chip *chip, unsigned int offset) 145 { 146 struct gpio_siox_ddata *ddata = 147 container_of(chip, struct gpio_siox_ddata, gchip); 148 int ret; 149 150 mutex_lock(&ddata->lock); 151 152 if (offset >= 12) { 153 unsigned int bitpos = 19 - offset; 154 155 ret = ddata->setdata[0] & (1 << bitpos); 156 } else { 157 unsigned int bitpos = 11 - offset; 158 159 ret = ddata->getdata[bitpos / 8] & (1 << (bitpos % 8)); 160 } 161 162 mutex_unlock(&ddata->lock); 163 164 return ret; 165 } 166 167 static void gpio_siox_set(struct gpio_chip *chip, 168 unsigned int offset, int value) 169 { 170 struct gpio_siox_ddata *ddata = 171 container_of(chip, struct gpio_siox_ddata, gchip); 172 u8 mask = 1 << (19 - offset); 173 174 mutex_lock(&ddata->lock); 175 176 if (value) 177 ddata->setdata[0] |= mask; 178 else 179 ddata->setdata[0] &= ~mask; 180 181 mutex_unlock(&ddata->lock); 182 } 183 184 static int gpio_siox_direction_input(struct gpio_chip *chip, 185 unsigned int offset) 186 { 187 if (offset >= 12) 188 return -EINVAL; 189 190 return 0; 191 } 192 193 static int gpio_siox_direction_output(struct gpio_chip *chip, 194 unsigned int offset, int value) 195 { 196 if (offset < 12) 197 return -EINVAL; 198 199 gpio_siox_set(chip, offset, value); 200 return 0; 201 } 202 203 static int gpio_siox_get_direction(struct gpio_chip *chip, unsigned int offset) 204 { 205 if (offset < 12) 206 return GPIO_LINE_DIRECTION_IN; 207 else 208 return GPIO_LINE_DIRECTION_OUT; 209 } 210 211 static int gpio_siox_probe(struct siox_device *sdevice) 212 { 213 struct gpio_siox_ddata *ddata; 214 struct gpio_irq_chip *girq; 215 struct device *dev = &sdevice->dev; 216 int ret; 217 218 ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); 219 if (!ddata) 220 return -ENOMEM; 221 222 dev_set_drvdata(dev, ddata); 223 224 mutex_init(&ddata->lock); 225 raw_spin_lock_init(&ddata->irqlock); 226 227 ddata->gchip.base = -1; 228 ddata->gchip.can_sleep = 1; 229 ddata->gchip.parent = dev; 230 ddata->gchip.owner = THIS_MODULE; 231 ddata->gchip.get = gpio_siox_get; 232 ddata->gchip.set = gpio_siox_set; 233 ddata->gchip.direction_input = gpio_siox_direction_input; 234 ddata->gchip.direction_output = gpio_siox_direction_output; 235 ddata->gchip.get_direction = gpio_siox_get_direction; 236 ddata->gchip.ngpio = 20; 237 238 ddata->ichip.name = "siox-gpio"; 239 ddata->ichip.irq_ack = gpio_siox_irq_ack; 240 ddata->ichip.irq_mask = gpio_siox_irq_mask; 241 ddata->ichip.irq_unmask = gpio_siox_irq_unmask; 242 ddata->ichip.irq_set_type = gpio_siox_irq_set_type; 243 244 girq = &ddata->gchip.irq; 245 girq->chip = &ddata->ichip; 246 girq->default_type = IRQ_TYPE_NONE; 247 girq->handler = handle_level_irq; 248 249 ret = devm_gpiochip_add_data(dev, &ddata->gchip, NULL); 250 if (ret) 251 dev_err(dev, "Failed to register gpio chip (%d)\n", ret); 252 253 return ret; 254 } 255 256 static struct siox_driver gpio_siox_driver = { 257 .probe = gpio_siox_probe, 258 .set_data = gpio_siox_set_data, 259 .get_data = gpio_siox_get_data, 260 .driver = { 261 .name = "gpio-siox", 262 }, 263 }; 264 module_siox_driver(gpio_siox_driver); 265 266 MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>"); 267 MODULE_DESCRIPTION("SIOX gpio driver"); 268 MODULE_LICENSE("GPL v2"); 269