0001
0002
0003
0004
0005
0006 #include <linux/module.h>
0007 #include <linux/siox.h>
0008 #include <linux/gpio/driver.h>
0009 #include <linux/of.h>
0010
0011 struct gpio_siox_ddata {
0012 struct gpio_chip gchip;
0013 struct irq_chip ichip;
0014 struct mutex lock;
0015 u8 setdata[1];
0016 u8 getdata[3];
0017
0018 raw_spinlock_t irqlock;
0019 u32 irq_enable;
0020 u32 irq_status;
0021 u32 irq_type[20];
0022 };
0023
0024
0025
0026
0027
0028 static int gpio_siox_set_data(struct siox_device *sdevice, u8 status, u8 buf[])
0029 {
0030 struct gpio_siox_ddata *ddata = dev_get_drvdata(&sdevice->dev);
0031
0032 mutex_lock(&ddata->lock);
0033 buf[0] = ddata->setdata[0];
0034 mutex_unlock(&ddata->lock);
0035
0036 return 0;
0037 }
0038
0039 static int gpio_siox_get_data(struct siox_device *sdevice, const u8 buf[])
0040 {
0041 struct gpio_siox_ddata *ddata = dev_get_drvdata(&sdevice->dev);
0042 size_t offset;
0043 u32 trigger;
0044
0045 mutex_lock(&ddata->lock);
0046
0047 raw_spin_lock_irq(&ddata->irqlock);
0048
0049 for (offset = 0; offset < 12; ++offset) {
0050 unsigned int bitpos = 11 - offset;
0051 unsigned int gpiolevel = buf[bitpos / 8] & (1 << bitpos % 8);
0052 unsigned int prev_level =
0053 ddata->getdata[bitpos / 8] & (1 << (bitpos % 8));
0054 u32 irq_type = ddata->irq_type[offset];
0055
0056 if (gpiolevel) {
0057 if ((irq_type & IRQ_TYPE_LEVEL_HIGH) ||
0058 ((irq_type & IRQ_TYPE_EDGE_RISING) && !prev_level))
0059 ddata->irq_status |= 1 << offset;
0060 } else {
0061 if ((irq_type & IRQ_TYPE_LEVEL_LOW) ||
0062 ((irq_type & IRQ_TYPE_EDGE_FALLING) && prev_level))
0063 ddata->irq_status |= 1 << offset;
0064 }
0065 }
0066
0067 trigger = ddata->irq_status & ddata->irq_enable;
0068
0069 raw_spin_unlock_irq(&ddata->irqlock);
0070
0071 ddata->getdata[0] = buf[0];
0072 ddata->getdata[1] = buf[1];
0073 ddata->getdata[2] = buf[2];
0074
0075 mutex_unlock(&ddata->lock);
0076
0077 for (offset = 0; offset < 12; ++offset) {
0078 if (trigger & (1 << offset)) {
0079 struct irq_domain *irqdomain = ddata->gchip.irq.domain;
0080 unsigned int irq = irq_find_mapping(irqdomain, offset);
0081
0082
0083
0084
0085
0086
0087 raw_spin_lock_irq(&ddata->irqlock);
0088 ddata->irq_status &= ~(1 << offset);
0089 raw_spin_unlock_irq(&ddata->irqlock);
0090
0091 handle_nested_irq(irq);
0092 }
0093 }
0094
0095 return 0;
0096 }
0097
0098 static void gpio_siox_irq_ack(struct irq_data *d)
0099 {
0100 struct irq_chip *ic = irq_data_get_irq_chip(d);
0101 struct gpio_siox_ddata *ddata =
0102 container_of(ic, struct gpio_siox_ddata, ichip);
0103
0104 raw_spin_lock(&ddata->irqlock);
0105 ddata->irq_status &= ~(1 << d->hwirq);
0106 raw_spin_unlock(&ddata->irqlock);
0107 }
0108
0109 static void gpio_siox_irq_mask(struct irq_data *d)
0110 {
0111 struct irq_chip *ic = irq_data_get_irq_chip(d);
0112 struct gpio_siox_ddata *ddata =
0113 container_of(ic, struct gpio_siox_ddata, ichip);
0114
0115 raw_spin_lock(&ddata->irqlock);
0116 ddata->irq_enable &= ~(1 << d->hwirq);
0117 raw_spin_unlock(&ddata->irqlock);
0118 }
0119
0120 static void gpio_siox_irq_unmask(struct irq_data *d)
0121 {
0122 struct irq_chip *ic = irq_data_get_irq_chip(d);
0123 struct gpio_siox_ddata *ddata =
0124 container_of(ic, struct gpio_siox_ddata, ichip);
0125
0126 raw_spin_lock(&ddata->irqlock);
0127 ddata->irq_enable |= 1 << d->hwirq;
0128 raw_spin_unlock(&ddata->irqlock);
0129 }
0130
0131 static int gpio_siox_irq_set_type(struct irq_data *d, u32 type)
0132 {
0133 struct irq_chip *ic = irq_data_get_irq_chip(d);
0134 struct gpio_siox_ddata *ddata =
0135 container_of(ic, struct gpio_siox_ddata, ichip);
0136
0137 raw_spin_lock(&ddata->irqlock);
0138 ddata->irq_type[d->hwirq] = type;
0139 raw_spin_unlock(&ddata->irqlock);
0140
0141 return 0;
0142 }
0143
0144 static int gpio_siox_get(struct gpio_chip *chip, unsigned int offset)
0145 {
0146 struct gpio_siox_ddata *ddata =
0147 container_of(chip, struct gpio_siox_ddata, gchip);
0148 int ret;
0149
0150 mutex_lock(&ddata->lock);
0151
0152 if (offset >= 12) {
0153 unsigned int bitpos = 19 - offset;
0154
0155 ret = ddata->setdata[0] & (1 << bitpos);
0156 } else {
0157 unsigned int bitpos = 11 - offset;
0158
0159 ret = ddata->getdata[bitpos / 8] & (1 << (bitpos % 8));
0160 }
0161
0162 mutex_unlock(&ddata->lock);
0163
0164 return ret;
0165 }
0166
0167 static void gpio_siox_set(struct gpio_chip *chip,
0168 unsigned int offset, int value)
0169 {
0170 struct gpio_siox_ddata *ddata =
0171 container_of(chip, struct gpio_siox_ddata, gchip);
0172 u8 mask = 1 << (19 - offset);
0173
0174 mutex_lock(&ddata->lock);
0175
0176 if (value)
0177 ddata->setdata[0] |= mask;
0178 else
0179 ddata->setdata[0] &= ~mask;
0180
0181 mutex_unlock(&ddata->lock);
0182 }
0183
0184 static int gpio_siox_direction_input(struct gpio_chip *chip,
0185 unsigned int offset)
0186 {
0187 if (offset >= 12)
0188 return -EINVAL;
0189
0190 return 0;
0191 }
0192
0193 static int gpio_siox_direction_output(struct gpio_chip *chip,
0194 unsigned int offset, int value)
0195 {
0196 if (offset < 12)
0197 return -EINVAL;
0198
0199 gpio_siox_set(chip, offset, value);
0200 return 0;
0201 }
0202
0203 static int gpio_siox_get_direction(struct gpio_chip *chip, unsigned int offset)
0204 {
0205 if (offset < 12)
0206 return GPIO_LINE_DIRECTION_IN;
0207 else
0208 return GPIO_LINE_DIRECTION_OUT;
0209 }
0210
0211 static int gpio_siox_probe(struct siox_device *sdevice)
0212 {
0213 struct gpio_siox_ddata *ddata;
0214 struct gpio_irq_chip *girq;
0215 struct device *dev = &sdevice->dev;
0216 int ret;
0217
0218 ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
0219 if (!ddata)
0220 return -ENOMEM;
0221
0222 dev_set_drvdata(dev, ddata);
0223
0224 mutex_init(&ddata->lock);
0225 raw_spin_lock_init(&ddata->irqlock);
0226
0227 ddata->gchip.base = -1;
0228 ddata->gchip.can_sleep = 1;
0229 ddata->gchip.parent = dev;
0230 ddata->gchip.owner = THIS_MODULE;
0231 ddata->gchip.get = gpio_siox_get;
0232 ddata->gchip.set = gpio_siox_set;
0233 ddata->gchip.direction_input = gpio_siox_direction_input;
0234 ddata->gchip.direction_output = gpio_siox_direction_output;
0235 ddata->gchip.get_direction = gpio_siox_get_direction;
0236 ddata->gchip.ngpio = 20;
0237
0238 ddata->ichip.name = "siox-gpio";
0239 ddata->ichip.irq_ack = gpio_siox_irq_ack;
0240 ddata->ichip.irq_mask = gpio_siox_irq_mask;
0241 ddata->ichip.irq_unmask = gpio_siox_irq_unmask;
0242 ddata->ichip.irq_set_type = gpio_siox_irq_set_type;
0243
0244 girq = &ddata->gchip.irq;
0245 girq->chip = &ddata->ichip;
0246 girq->default_type = IRQ_TYPE_NONE;
0247 girq->handler = handle_level_irq;
0248 girq->threaded = true;
0249
0250 ret = devm_gpiochip_add_data(dev, &ddata->gchip, NULL);
0251 if (ret)
0252 dev_err(dev, "Failed to register gpio chip (%d)\n", ret);
0253
0254 return ret;
0255 }
0256
0257 static struct siox_driver gpio_siox_driver = {
0258 .probe = gpio_siox_probe,
0259 .set_data = gpio_siox_set_data,
0260 .get_data = gpio_siox_get_data,
0261 .driver = {
0262 .name = "gpio-siox",
0263 },
0264 };
0265 module_siox_driver(gpio_siox_driver);
0266
0267 MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
0268 MODULE_DESCRIPTION("SIOX gpio driver");
0269 MODULE_LICENSE("GPL v2");