524 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Driver for the Diolan DLN-2 USB-GPIO adapter4 *5 * Copyright (c) 2014 Intel Corporation6 */7 8#include <linux/kernel.h>9#include <linux/module.h>10#include <linux/slab.h>11#include <linux/types.h>12#include <linux/irqdomain.h>13#include <linux/irq.h>14#include <linux/irqchip/chained_irq.h>15#include <linux/gpio/driver.h>16#include <linux/platform_device.h>17#include <linux/mfd/dln2.h>18 19#define DLN2_GPIO_ID 0x0120 21#define DLN2_GPIO_GET_PIN_COUNT DLN2_CMD(0x01, DLN2_GPIO_ID)22#define DLN2_GPIO_SET_DEBOUNCE DLN2_CMD(0x04, DLN2_GPIO_ID)23#define DLN2_GPIO_GET_DEBOUNCE DLN2_CMD(0x05, DLN2_GPIO_ID)24#define DLN2_GPIO_PORT_GET_VAL DLN2_CMD(0x06, DLN2_GPIO_ID)25#define DLN2_GPIO_PIN_GET_VAL DLN2_CMD(0x0B, DLN2_GPIO_ID)26#define DLN2_GPIO_PIN_SET_OUT_VAL DLN2_CMD(0x0C, DLN2_GPIO_ID)27#define DLN2_GPIO_PIN_GET_OUT_VAL DLN2_CMD(0x0D, DLN2_GPIO_ID)28#define DLN2_GPIO_CONDITION_MET_EV DLN2_CMD(0x0F, DLN2_GPIO_ID)29#define DLN2_GPIO_PIN_ENABLE DLN2_CMD(0x10, DLN2_GPIO_ID)30#define DLN2_GPIO_PIN_DISABLE DLN2_CMD(0x11, DLN2_GPIO_ID)31#define DLN2_GPIO_PIN_SET_DIRECTION DLN2_CMD(0x13, DLN2_GPIO_ID)32#define DLN2_GPIO_PIN_GET_DIRECTION DLN2_CMD(0x14, DLN2_GPIO_ID)33#define DLN2_GPIO_PIN_SET_EVENT_CFG DLN2_CMD(0x1E, DLN2_GPIO_ID)34#define DLN2_GPIO_PIN_GET_EVENT_CFG DLN2_CMD(0x1F, DLN2_GPIO_ID)35 36#define DLN2_GPIO_EVENT_NONE 037#define DLN2_GPIO_EVENT_CHANGE 138#define DLN2_GPIO_EVENT_LVL_HIGH 239#define DLN2_GPIO_EVENT_LVL_LOW 340#define DLN2_GPIO_EVENT_CHANGE_RISING 0x1141#define DLN2_GPIO_EVENT_CHANGE_FALLING 0x2142#define DLN2_GPIO_EVENT_MASK 0x0F43 44#define DLN2_GPIO_MAX_PINS 3245 46struct dln2_gpio {47 struct platform_device *pdev;48 struct gpio_chip gpio;49 50 /*51 * Cache pin direction to save us one transfer, since the hardware has52 * separate commands to read the in and out values.53 */54 DECLARE_BITMAP(output_enabled, DLN2_GPIO_MAX_PINS);55 56 /* active IRQs - not synced to hardware */57 DECLARE_BITMAP(unmasked_irqs, DLN2_GPIO_MAX_PINS);58 /* active IRQS - synced to hardware */59 DECLARE_BITMAP(enabled_irqs, DLN2_GPIO_MAX_PINS);60 int irq_type[DLN2_GPIO_MAX_PINS];61 struct mutex irq_lock;62};63 64struct dln2_gpio_pin {65 __le16 pin;66};67 68struct dln2_gpio_pin_val {69 __le16 pin __packed;70 u8 value;71};72 73static int dln2_gpio_get_pin_count(struct platform_device *pdev)74{75 int ret;76 __le16 count;77 int len = sizeof(count);78 79 ret = dln2_transfer_rx(pdev, DLN2_GPIO_GET_PIN_COUNT, &count, &len);80 if (ret < 0)81 return ret;82 if (len < sizeof(count))83 return -EPROTO;84 85 return le16_to_cpu(count);86}87 88static int dln2_gpio_pin_cmd(struct dln2_gpio *dln2, int cmd, unsigned pin)89{90 struct dln2_gpio_pin req = {91 .pin = cpu_to_le16(pin),92 };93 94 return dln2_transfer_tx(dln2->pdev, cmd, &req, sizeof(req));95}96 97static int dln2_gpio_pin_val(struct dln2_gpio *dln2, int cmd, unsigned int pin)98{99 int ret;100 struct dln2_gpio_pin req = {101 .pin = cpu_to_le16(pin),102 };103 struct dln2_gpio_pin_val rsp;104 int len = sizeof(rsp);105 106 ret = dln2_transfer(dln2->pdev, cmd, &req, sizeof(req), &rsp, &len);107 if (ret < 0)108 return ret;109 if (len < sizeof(rsp) || req.pin != rsp.pin)110 return -EPROTO;111 112 return rsp.value;113}114 115static int dln2_gpio_pin_get_in_val(struct dln2_gpio *dln2, unsigned int pin)116{117 int ret;118 119 ret = dln2_gpio_pin_val(dln2, DLN2_GPIO_PIN_GET_VAL, pin);120 if (ret < 0)121 return ret;122 return !!ret;123}124 125static int dln2_gpio_pin_get_out_val(struct dln2_gpio *dln2, unsigned int pin)126{127 int ret;128 129 ret = dln2_gpio_pin_val(dln2, DLN2_GPIO_PIN_GET_OUT_VAL, pin);130 if (ret < 0)131 return ret;132 return !!ret;133}134 135static int dln2_gpio_pin_set_out_val(struct dln2_gpio *dln2,136 unsigned int pin, int value)137{138 struct dln2_gpio_pin_val req = {139 .pin = cpu_to_le16(pin),140 .value = value,141 };142 143 return dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_OUT_VAL, &req,144 sizeof(req));145}146 147#define DLN2_GPIO_DIRECTION_IN 0148#define DLN2_GPIO_DIRECTION_OUT 1149 150static int dln2_gpio_request(struct gpio_chip *chip, unsigned offset)151{152 struct dln2_gpio *dln2 = gpiochip_get_data(chip);153 struct dln2_gpio_pin req = {154 .pin = cpu_to_le16(offset),155 };156 struct dln2_gpio_pin_val rsp;157 int len = sizeof(rsp);158 int ret;159 160 ret = dln2_gpio_pin_cmd(dln2, DLN2_GPIO_PIN_ENABLE, offset);161 if (ret < 0)162 return ret;163 164 /* cache the pin direction */165 ret = dln2_transfer(dln2->pdev, DLN2_GPIO_PIN_GET_DIRECTION,166 &req, sizeof(req), &rsp, &len);167 if (ret < 0)168 return ret;169 if (len < sizeof(rsp) || req.pin != rsp.pin) {170 ret = -EPROTO;171 goto out_disable;172 }173 174 switch (rsp.value) {175 case DLN2_GPIO_DIRECTION_IN:176 clear_bit(offset, dln2->output_enabled);177 return 0;178 case DLN2_GPIO_DIRECTION_OUT:179 set_bit(offset, dln2->output_enabled);180 return 0;181 default:182 ret = -EPROTO;183 goto out_disable;184 }185 186out_disable:187 dln2_gpio_pin_cmd(dln2, DLN2_GPIO_PIN_DISABLE, offset);188 return ret;189}190 191static void dln2_gpio_free(struct gpio_chip *chip, unsigned offset)192{193 struct dln2_gpio *dln2 = gpiochip_get_data(chip);194 195 dln2_gpio_pin_cmd(dln2, DLN2_GPIO_PIN_DISABLE, offset);196}197 198static int dln2_gpio_get_direction(struct gpio_chip *chip, unsigned offset)199{200 struct dln2_gpio *dln2 = gpiochip_get_data(chip);201 202 if (test_bit(offset, dln2->output_enabled))203 return GPIO_LINE_DIRECTION_OUT;204 205 return GPIO_LINE_DIRECTION_IN;206}207 208static int dln2_gpio_get(struct gpio_chip *chip, unsigned int offset)209{210 struct dln2_gpio *dln2 = gpiochip_get_data(chip);211 int dir;212 213 dir = dln2_gpio_get_direction(chip, offset);214 if (dir < 0)215 return dir;216 217 if (dir == GPIO_LINE_DIRECTION_IN)218 return dln2_gpio_pin_get_in_val(dln2, offset);219 220 return dln2_gpio_pin_get_out_val(dln2, offset);221}222 223static void dln2_gpio_set(struct gpio_chip *chip, unsigned offset, int value)224{225 struct dln2_gpio *dln2 = gpiochip_get_data(chip);226 227 dln2_gpio_pin_set_out_val(dln2, offset, value);228}229 230static int dln2_gpio_set_direction(struct gpio_chip *chip, unsigned offset,231 unsigned dir)232{233 struct dln2_gpio *dln2 = gpiochip_get_data(chip);234 struct dln2_gpio_pin_val req = {235 .pin = cpu_to_le16(offset),236 .value = dir,237 };238 int ret;239 240 ret = dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_DIRECTION,241 &req, sizeof(req));242 if (ret < 0)243 return ret;244 245 if (dir == DLN2_GPIO_DIRECTION_OUT)246 set_bit(offset, dln2->output_enabled);247 else248 clear_bit(offset, dln2->output_enabled);249 250 return ret;251}252 253static int dln2_gpio_direction_input(struct gpio_chip *chip, unsigned offset)254{255 return dln2_gpio_set_direction(chip, offset, DLN2_GPIO_DIRECTION_IN);256}257 258static int dln2_gpio_direction_output(struct gpio_chip *chip, unsigned offset,259 int value)260{261 struct dln2_gpio *dln2 = gpiochip_get_data(chip);262 int ret;263 264 ret = dln2_gpio_pin_set_out_val(dln2, offset, value);265 if (ret < 0)266 return ret;267 268 return dln2_gpio_set_direction(chip, offset, DLN2_GPIO_DIRECTION_OUT);269}270 271static int dln2_gpio_set_config(struct gpio_chip *chip, unsigned offset,272 unsigned long config)273{274 struct dln2_gpio *dln2 = gpiochip_get_data(chip);275 __le32 duration;276 277 if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)278 return -ENOTSUPP;279 280 duration = cpu_to_le32(pinconf_to_config_argument(config));281 return dln2_transfer_tx(dln2->pdev, DLN2_GPIO_SET_DEBOUNCE,282 &duration, sizeof(duration));283}284 285static int dln2_gpio_set_event_cfg(struct dln2_gpio *dln2, unsigned pin,286 unsigned type, unsigned period)287{288 struct {289 __le16 pin;290 u8 type;291 __le16 period;292 } __packed req = {293 .pin = cpu_to_le16(pin),294 .type = type,295 .period = cpu_to_le16(period),296 };297 298 return dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_EVENT_CFG,299 &req, sizeof(req));300}301 302static void dln2_irq_unmask(struct irq_data *irqd)303{304 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);305 struct dln2_gpio *dln2 = gpiochip_get_data(gc);306 int pin = irqd_to_hwirq(irqd);307 308 gpiochip_enable_irq(gc, pin);309 set_bit(pin, dln2->unmasked_irqs);310}311 312static void dln2_irq_mask(struct irq_data *irqd)313{314 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);315 struct dln2_gpio *dln2 = gpiochip_get_data(gc);316 int pin = irqd_to_hwirq(irqd);317 318 clear_bit(pin, dln2->unmasked_irqs);319 gpiochip_disable_irq(gc, pin);320}321 322static int dln2_irq_set_type(struct irq_data *irqd, unsigned type)323{324 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);325 struct dln2_gpio *dln2 = gpiochip_get_data(gc);326 int pin = irqd_to_hwirq(irqd);327 328 switch (type) {329 case IRQ_TYPE_LEVEL_HIGH:330 dln2->irq_type[pin] = DLN2_GPIO_EVENT_LVL_HIGH;331 break;332 case IRQ_TYPE_LEVEL_LOW:333 dln2->irq_type[pin] = DLN2_GPIO_EVENT_LVL_LOW;334 break;335 case IRQ_TYPE_EDGE_BOTH:336 dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE;337 break;338 case IRQ_TYPE_EDGE_RISING:339 dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE_RISING;340 break;341 case IRQ_TYPE_EDGE_FALLING:342 dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE_FALLING;343 break;344 default:345 return -EINVAL;346 }347 348 return 0;349}350 351static void dln2_irq_bus_lock(struct irq_data *irqd)352{353 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);354 struct dln2_gpio *dln2 = gpiochip_get_data(gc);355 356 mutex_lock(&dln2->irq_lock);357}358 359static void dln2_irq_bus_unlock(struct irq_data *irqd)360{361 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);362 struct dln2_gpio *dln2 = gpiochip_get_data(gc);363 int pin = irqd_to_hwirq(irqd);364 int enabled, unmasked;365 unsigned type;366 int ret;367 368 enabled = test_bit(pin, dln2->enabled_irqs);369 unmasked = test_bit(pin, dln2->unmasked_irqs);370 371 if (enabled != unmasked) {372 if (unmasked) {373 type = dln2->irq_type[pin] & DLN2_GPIO_EVENT_MASK;374 set_bit(pin, dln2->enabled_irqs);375 } else {376 type = DLN2_GPIO_EVENT_NONE;377 clear_bit(pin, dln2->enabled_irqs);378 }379 380 ret = dln2_gpio_set_event_cfg(dln2, pin, type, 0);381 if (ret)382 dev_err(dln2->gpio.parent, "failed to set event\n");383 }384 385 mutex_unlock(&dln2->irq_lock);386}387 388static const struct irq_chip dln2_irqchip = {389 .name = "dln2-irq",390 .irq_mask = dln2_irq_mask,391 .irq_unmask = dln2_irq_unmask,392 .irq_set_type = dln2_irq_set_type,393 .irq_bus_lock = dln2_irq_bus_lock,394 .irq_bus_sync_unlock = dln2_irq_bus_unlock,395 .flags = IRQCHIP_IMMUTABLE,396 GPIOCHIP_IRQ_RESOURCE_HELPERS,397};398 399static void dln2_gpio_event(struct platform_device *pdev, u16 echo,400 const void *data, int len)401{402 int pin, ret;403 404 const struct {405 __le16 count;406 __u8 type;407 __le16 pin;408 __u8 value;409 } __packed *event = data;410 struct dln2_gpio *dln2 = platform_get_drvdata(pdev);411 412 if (len < sizeof(*event)) {413 dev_err(dln2->gpio.parent, "short event message\n");414 return;415 }416 417 pin = le16_to_cpu(event->pin);418 if (pin >= dln2->gpio.ngpio) {419 dev_err(dln2->gpio.parent, "out of bounds pin %d\n", pin);420 return;421 }422 423 switch (dln2->irq_type[pin]) {424 case DLN2_GPIO_EVENT_CHANGE_RISING:425 if (!event->value)426 return;427 break;428 case DLN2_GPIO_EVENT_CHANGE_FALLING:429 if (event->value)430 return;431 break;432 }433 434 ret = generic_handle_domain_irq(dln2->gpio.irq.domain, pin);435 if (unlikely(ret))436 dev_err(dln2->gpio.parent, "pin %d not mapped to IRQ\n", pin);437}438 439static int dln2_gpio_probe(struct platform_device *pdev)440{441 struct dln2_gpio *dln2;442 struct device *dev = &pdev->dev;443 struct gpio_irq_chip *girq;444 int pins;445 int ret;446 447 pins = dln2_gpio_get_pin_count(pdev);448 if (pins < 0) {449 dev_err(dev, "failed to get pin count: %d\n", pins);450 return pins;451 }452 if (pins > DLN2_GPIO_MAX_PINS) {453 pins = DLN2_GPIO_MAX_PINS;454 dev_warn(dev, "clamping pins to %d\n", DLN2_GPIO_MAX_PINS);455 }456 457 dln2 = devm_kzalloc(&pdev->dev, sizeof(*dln2), GFP_KERNEL);458 if (!dln2)459 return -ENOMEM;460 461 mutex_init(&dln2->irq_lock);462 463 dln2->pdev = pdev;464 465 dln2->gpio.label = "dln2";466 dln2->gpio.parent = dev;467 dln2->gpio.owner = THIS_MODULE;468 dln2->gpio.base = -1;469 dln2->gpio.ngpio = pins;470 dln2->gpio.can_sleep = true;471 dln2->gpio.set = dln2_gpio_set;472 dln2->gpio.get = dln2_gpio_get;473 dln2->gpio.request = dln2_gpio_request;474 dln2->gpio.free = dln2_gpio_free;475 dln2->gpio.get_direction = dln2_gpio_get_direction;476 dln2->gpio.direction_input = dln2_gpio_direction_input;477 dln2->gpio.direction_output = dln2_gpio_direction_output;478 dln2->gpio.set_config = dln2_gpio_set_config;479 480 girq = &dln2->gpio.irq;481 gpio_irq_chip_set_chip(girq, &dln2_irqchip);482 /* The event comes from the outside so no parent handler */483 girq->parent_handler = NULL;484 girq->num_parents = 0;485 girq->parents = NULL;486 girq->default_type = IRQ_TYPE_NONE;487 girq->handler = handle_simple_irq;488 489 platform_set_drvdata(pdev, dln2);490 491 ret = devm_gpiochip_add_data(dev, &dln2->gpio, dln2);492 if (ret < 0) {493 dev_err(dev, "failed to add gpio chip: %d\n", ret);494 return ret;495 }496 497 ret = dln2_register_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV,498 dln2_gpio_event);499 if (ret) {500 dev_err(dev, "failed to register event cb: %d\n", ret);501 return ret;502 }503 504 return 0;505}506 507static void dln2_gpio_remove(struct platform_device *pdev)508{509 dln2_unregister_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV);510}511 512static struct platform_driver dln2_gpio_driver = {513 .driver.name = "dln2-gpio",514 .probe = dln2_gpio_probe,515 .remove_new = dln2_gpio_remove,516};517 518module_platform_driver(dln2_gpio_driver);519 520MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com");521MODULE_DESCRIPTION("Driver for the Diolan DLN2 GPIO interface");522MODULE_LICENSE("GPL v2");523MODULE_ALIAS("platform:dln2-gpio");524