1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ 4 * 5 * A generic driver to read multiple gpio lines and translate the 6 * encoded numeric value into an input event. 7 */ 8 9 #include <linux/device.h> 10 #include <linux/gpio/consumer.h> 11 #include <linux/input.h> 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/of.h> 15 #include <linux/platform_device.h> 16 17 struct gpio_decoder { 18 struct gpio_descs *input_gpios; 19 struct device *dev; 20 u32 axis; 21 u32 last_stable; 22 }; 23 24 static int gpio_decoder_get_gpios_state(struct gpio_decoder *decoder) 25 { 26 struct gpio_descs *gpios = decoder->input_gpios; 27 unsigned int ret = 0; 28 int i, val; 29 30 for (i = 0; i < gpios->ndescs; i++) { 31 val = gpiod_get_value_cansleep(gpios->desc[i]); 32 if (val < 0) { 33 dev_err(decoder->dev, 34 "Error reading gpio %d: %d\n", 35 desc_to_gpio(gpios->desc[i]), val); 36 return val; 37 } 38 39 val = !!val; 40 ret = (ret << 1) | val; 41 } 42 43 return ret; 44 } 45 46 static void gpio_decoder_poll_gpios(struct input_dev *input) 47 { 48 struct gpio_decoder *decoder = input_get_drvdata(input); 49 int state; 50 51 state = gpio_decoder_get_gpios_state(decoder); 52 if (state >= 0 && state != decoder->last_stable) { 53 input_report_abs(input, decoder->axis, state); 54 input_sync(input); 55 decoder->last_stable = state; 56 } 57 } 58 59 static int gpio_decoder_probe(struct platform_device *pdev) 60 { 61 struct device *dev = &pdev->dev; 62 struct gpio_decoder *decoder; 63 struct input_dev *input; 64 u32 max; 65 int err; 66 67 decoder = devm_kzalloc(dev, sizeof(*decoder), GFP_KERNEL); 68 if (!decoder) 69 return -ENOMEM; 70 71 decoder->dev = dev; 72 device_property_read_u32(dev, "linux,axis", &decoder->axis); 73 74 decoder->input_gpios = devm_gpiod_get_array(dev, NULL, GPIOD_IN); 75 if (IS_ERR(decoder->input_gpios)) { 76 dev_err(dev, "unable to acquire input gpios\n"); 77 return PTR_ERR(decoder->input_gpios); 78 } 79 80 if (decoder->input_gpios->ndescs < 2) { 81 dev_err(dev, "not enough gpios found\n"); 82 return -EINVAL; 83 } 84 85 if (device_property_read_u32(dev, "decoder-max-value", &max)) 86 max = (1U << decoder->input_gpios->ndescs) - 1; 87 88 input = devm_input_allocate_device(dev); 89 if (!input) 90 return -ENOMEM; 91 92 input_set_drvdata(input, decoder); 93 94 input->name = pdev->name; 95 input->id.bustype = BUS_HOST; 96 input_set_abs_params(input, decoder->axis, 0, max, 0, 0); 97 98 err = input_setup_polling(input, gpio_decoder_poll_gpios); 99 if (err) { 100 dev_err(dev, "failed to set up polling\n"); 101 return err; 102 } 103 104 err = input_register_device(input); 105 if (err) { 106 dev_err(dev, "failed to register input device\n"); 107 return err; 108 } 109 110 return 0; 111 } 112 113 #ifdef CONFIG_OF 114 static const struct of_device_id gpio_decoder_of_match[] = { 115 { .compatible = "gpio-decoder", }, 116 { }, 117 }; 118 MODULE_DEVICE_TABLE(of, gpio_decoder_of_match); 119 #endif 120 121 static struct platform_driver gpio_decoder_driver = { 122 .probe = gpio_decoder_probe, 123 .driver = { 124 .name = "gpio-decoder", 125 .of_match_table = of_match_ptr(gpio_decoder_of_match), 126 } 127 }; 128 module_platform_driver(gpio_decoder_driver); 129 130 MODULE_DESCRIPTION("GPIO decoder input driver"); 131 MODULE_AUTHOR("Vignesh R <vigneshr@ti.com>"); 132 MODULE_LICENSE("GPL v2"); 133