1*69464161SVignesh R /* 2*69464161SVignesh R * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ 3*69464161SVignesh R * 4*69464161SVignesh R * This program is free software; you can redistribute it and/or 5*69464161SVignesh R * modify it under the terms of the GNU General Public License as 6*69464161SVignesh R * published by the Free Software Foundation version 2. 7*69464161SVignesh R * 8*69464161SVignesh R * This program is distributed "as is" WITHOUT ANY WARRANTY of any 9*69464161SVignesh R * kind, whether express or implied; without even the implied warranty 10*69464161SVignesh R * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11*69464161SVignesh R * GNU General Public License for more details. 12*69464161SVignesh R * 13*69464161SVignesh R * A generic driver to read multiple gpio lines and translate the 14*69464161SVignesh R * encoded numeric value into an input event. 15*69464161SVignesh R */ 16*69464161SVignesh R 17*69464161SVignesh R #include <linux/device.h> 18*69464161SVignesh R #include <linux/gpio/consumer.h> 19*69464161SVignesh R #include <linux/input.h> 20*69464161SVignesh R #include <linux/input-polldev.h> 21*69464161SVignesh R #include <linux/kernel.h> 22*69464161SVignesh R #include <linux/module.h> 23*69464161SVignesh R #include <linux/of.h> 24*69464161SVignesh R #include <linux/platform_device.h> 25*69464161SVignesh R 26*69464161SVignesh R struct gpio_decoder { 27*69464161SVignesh R struct input_polled_dev *poll_dev; 28*69464161SVignesh R struct gpio_descs *input_gpios; 29*69464161SVignesh R struct device *dev; 30*69464161SVignesh R u32 axis; 31*69464161SVignesh R u32 last_stable; 32*69464161SVignesh R }; 33*69464161SVignesh R 34*69464161SVignesh R static int gpio_decoder_get_gpios_state(struct gpio_decoder *decoder) 35*69464161SVignesh R { 36*69464161SVignesh R struct gpio_descs *gpios = decoder->input_gpios; 37*69464161SVignesh R unsigned int ret = 0; 38*69464161SVignesh R int i, val; 39*69464161SVignesh R 40*69464161SVignesh R for (i = 0; i < gpios->ndescs; i++) { 41*69464161SVignesh R val = gpiod_get_value_cansleep(gpios->desc[i]); 42*69464161SVignesh R if (val < 0) { 43*69464161SVignesh R dev_err(decoder->dev, 44*69464161SVignesh R "Error reading gpio %d: %d\n", 45*69464161SVignesh R desc_to_gpio(gpios->desc[i]), val); 46*69464161SVignesh R return val; 47*69464161SVignesh R } 48*69464161SVignesh R 49*69464161SVignesh R val = !!val; 50*69464161SVignesh R ret = (ret << 1) | val; 51*69464161SVignesh R } 52*69464161SVignesh R 53*69464161SVignesh R return ret; 54*69464161SVignesh R } 55*69464161SVignesh R 56*69464161SVignesh R static void gpio_decoder_poll_gpios(struct input_polled_dev *poll_dev) 57*69464161SVignesh R { 58*69464161SVignesh R struct gpio_decoder *decoder = poll_dev->private; 59*69464161SVignesh R int state; 60*69464161SVignesh R 61*69464161SVignesh R state = gpio_decoder_get_gpios_state(decoder); 62*69464161SVignesh R if (state >= 0 && state != decoder->last_stable) { 63*69464161SVignesh R input_report_abs(poll_dev->input, decoder->axis, state); 64*69464161SVignesh R input_sync(poll_dev->input); 65*69464161SVignesh R decoder->last_stable = state; 66*69464161SVignesh R } 67*69464161SVignesh R } 68*69464161SVignesh R 69*69464161SVignesh R static int gpio_decoder_probe(struct platform_device *pdev) 70*69464161SVignesh R { 71*69464161SVignesh R struct device *dev = &pdev->dev; 72*69464161SVignesh R struct gpio_decoder *decoder; 73*69464161SVignesh R struct input_polled_dev *poll_dev; 74*69464161SVignesh R u32 max; 75*69464161SVignesh R int err; 76*69464161SVignesh R 77*69464161SVignesh R decoder = devm_kzalloc(dev, sizeof(struct gpio_decoder), GFP_KERNEL); 78*69464161SVignesh R if (!decoder) 79*69464161SVignesh R return -ENOMEM; 80*69464161SVignesh R 81*69464161SVignesh R device_property_read_u32(dev, "linux,axis", &decoder->axis); 82*69464161SVignesh R decoder->input_gpios = devm_gpiod_get_array(dev, NULL, GPIOD_IN); 83*69464161SVignesh R if (IS_ERR(decoder->input_gpios)) { 84*69464161SVignesh R dev_err(dev, "unable to acquire input gpios\n"); 85*69464161SVignesh R return PTR_ERR(decoder->input_gpios); 86*69464161SVignesh R } 87*69464161SVignesh R if (decoder->input_gpios->ndescs < 2) { 88*69464161SVignesh R dev_err(dev, "not enough gpios found\n"); 89*69464161SVignesh R return -EINVAL; 90*69464161SVignesh R } 91*69464161SVignesh R 92*69464161SVignesh R if (device_property_read_u32(dev, "decoder-max-value", &max)) 93*69464161SVignesh R max = (1U << decoder->input_gpios->ndescs) - 1; 94*69464161SVignesh R 95*69464161SVignesh R decoder->dev = dev; 96*69464161SVignesh R poll_dev = devm_input_allocate_polled_device(decoder->dev); 97*69464161SVignesh R if (!poll_dev) 98*69464161SVignesh R return -ENOMEM; 99*69464161SVignesh R 100*69464161SVignesh R poll_dev->private = decoder; 101*69464161SVignesh R poll_dev->poll = gpio_decoder_poll_gpios; 102*69464161SVignesh R decoder->poll_dev = poll_dev; 103*69464161SVignesh R 104*69464161SVignesh R poll_dev->input->name = pdev->name; 105*69464161SVignesh R poll_dev->input->id.bustype = BUS_HOST; 106*69464161SVignesh R input_set_abs_params(poll_dev->input, decoder->axis, 0, max, 0, 0); 107*69464161SVignesh R 108*69464161SVignesh R err = input_register_polled_device(poll_dev); 109*69464161SVignesh R if (err) { 110*69464161SVignesh R dev_err(dev, "failed to register polled device\n"); 111*69464161SVignesh R return err; 112*69464161SVignesh R } 113*69464161SVignesh R platform_set_drvdata(pdev, decoder); 114*69464161SVignesh R 115*69464161SVignesh R return 0; 116*69464161SVignesh R } 117*69464161SVignesh R 118*69464161SVignesh R #ifdef CONFIG_OF 119*69464161SVignesh R static const struct of_device_id gpio_decoder_of_match[] = { 120*69464161SVignesh R { .compatible = "gpio-decoder", }, 121*69464161SVignesh R { }, 122*69464161SVignesh R }; 123*69464161SVignesh R MODULE_DEVICE_TABLE(of, gpio_decoder_of_match); 124*69464161SVignesh R #endif 125*69464161SVignesh R 126*69464161SVignesh R static struct platform_driver gpio_decoder_driver = { 127*69464161SVignesh R .probe = gpio_decoder_probe, 128*69464161SVignesh R .driver = { 129*69464161SVignesh R .name = "gpio-decoder", 130*69464161SVignesh R .of_match_table = of_match_ptr(gpio_decoder_of_match), 131*69464161SVignesh R } 132*69464161SVignesh R }; 133*69464161SVignesh R module_platform_driver(gpio_decoder_driver); 134*69464161SVignesh R 135*69464161SVignesh R MODULE_DESCRIPTION("GPIO decoder input driver"); 136*69464161SVignesh R MODULE_AUTHOR("Vignesh R <vigneshr@ti.com>"); 137*69464161SVignesh R MODULE_LICENSE("GPL v2"); 138