1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Input driver for resistor ladder connected on ADC 4 * 5 * Copyright (c) 2016 Alexandre Belloni 6 */ 7 8 #include <linux/err.h> 9 #include <linux/iio/consumer.h> 10 #include <linux/iio/types.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 #include <linux/property.h> 17 #include <linux/slab.h> 18 19 struct adc_keys_button { 20 u32 voltage; 21 u32 keycode; 22 }; 23 24 struct adc_keys_state { 25 struct iio_channel *channel; 26 u32 num_keys; 27 u32 last_key; 28 u32 keyup_voltage; 29 const struct adc_keys_button *map; 30 }; 31 32 static void adc_keys_poll(struct input_dev *input) 33 { 34 struct adc_keys_state *st = input_get_drvdata(input); 35 int i, value, ret; 36 u32 diff, closest = 0xffffffff; 37 int keycode = 0; 38 39 ret = iio_read_channel_processed(st->channel, &value); 40 if (unlikely(ret < 0)) { 41 /* Forcibly release key if any was pressed */ 42 value = st->keyup_voltage; 43 } else { 44 for (i = 0; i < st->num_keys; i++) { 45 diff = abs(st->map[i].voltage - value); 46 if (diff < closest) { 47 closest = diff; 48 keycode = st->map[i].keycode; 49 } 50 } 51 } 52 53 if (abs(st->keyup_voltage - value) < closest) 54 keycode = 0; 55 56 if (st->last_key && st->last_key != keycode) 57 input_report_key(input, st->last_key, 0); 58 59 if (keycode) 60 input_report_key(input, keycode, 1); 61 62 input_sync(input); 63 st->last_key = keycode; 64 } 65 66 static int adc_keys_load_keymap(struct device *dev, struct adc_keys_state *st) 67 { 68 struct adc_keys_button *map; 69 int i; 70 71 st->num_keys = device_get_child_node_count(dev); 72 if (st->num_keys == 0) { 73 dev_err(dev, "keymap is missing\n"); 74 return -EINVAL; 75 } 76 77 map = devm_kmalloc_array(dev, st->num_keys, sizeof(*map), GFP_KERNEL); 78 if (!map) 79 return -ENOMEM; 80 81 i = 0; 82 device_for_each_child_node_scoped(dev, child) { 83 if (fwnode_property_read_u32(child, "press-threshold-microvolt", 84 &map[i].voltage)) { 85 dev_err(dev, "Key with invalid or missing voltage\n"); 86 return -EINVAL; 87 } 88 map[i].voltage /= 1000; 89 90 if (fwnode_property_read_u32(child, "linux,code", 91 &map[i].keycode)) { 92 dev_err(dev, "Key with invalid or missing linux,code\n"); 93 return -EINVAL; 94 } 95 96 i++; 97 } 98 99 st->map = map; 100 return 0; 101 } 102 103 static int adc_keys_probe(struct platform_device *pdev) 104 { 105 struct device *dev = &pdev->dev; 106 struct adc_keys_state *st; 107 struct input_dev *input; 108 enum iio_chan_type type; 109 int i, value; 110 int error; 111 112 st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); 113 if (!st) 114 return -ENOMEM; 115 116 st->channel = devm_iio_channel_get(dev, "buttons"); 117 if (IS_ERR(st->channel)) 118 return PTR_ERR(st->channel); 119 120 if (!st->channel->indio_dev) 121 return -ENXIO; 122 123 error = iio_get_channel_type(st->channel, &type); 124 if (error < 0) 125 return error; 126 127 if (type != IIO_VOLTAGE) { 128 dev_err(dev, "Incompatible channel type %d\n", type); 129 return -EINVAL; 130 } 131 132 if (device_property_read_u32(dev, "keyup-threshold-microvolt", 133 &st->keyup_voltage)) { 134 dev_err(dev, "Invalid or missing keyup voltage\n"); 135 return -EINVAL; 136 } 137 st->keyup_voltage /= 1000; 138 139 error = adc_keys_load_keymap(dev, st); 140 if (error) 141 return error; 142 143 input = devm_input_allocate_device(dev); 144 if (!input) { 145 dev_err(dev, "failed to allocate input device\n"); 146 return -ENOMEM; 147 } 148 149 input_set_drvdata(input, st); 150 151 input->name = pdev->name; 152 input->phys = "adc-keys/input0"; 153 154 input->id.bustype = BUS_HOST; 155 input->id.vendor = 0x0001; 156 input->id.product = 0x0001; 157 input->id.version = 0x0100; 158 159 __set_bit(EV_KEY, input->evbit); 160 for (i = 0; i < st->num_keys; i++) 161 __set_bit(st->map[i].keycode, input->keybit); 162 163 if (device_property_read_bool(dev, "autorepeat")) 164 __set_bit(EV_REP, input->evbit); 165 166 167 error = input_setup_polling(input, adc_keys_poll); 168 if (error) { 169 dev_err(dev, "Unable to set up polling: %d\n", error); 170 return error; 171 } 172 173 if (!device_property_read_u32(dev, "poll-interval", &value)) 174 input_set_poll_interval(input, value); 175 176 error = input_register_device(input); 177 if (error) { 178 dev_err(dev, "Unable to register input device: %d\n", error); 179 return error; 180 } 181 182 return 0; 183 } 184 185 #ifdef CONFIG_OF 186 static const struct of_device_id adc_keys_of_match[] = { 187 { .compatible = "adc-keys", }, 188 { } 189 }; 190 MODULE_DEVICE_TABLE(of, adc_keys_of_match); 191 #endif 192 193 static struct platform_driver adc_keys_driver = { 194 .driver = { 195 .name = "adc_keys", 196 .of_match_table = of_match_ptr(adc_keys_of_match), 197 }, 198 .probe = adc_keys_probe, 199 }; 200 module_platform_driver(adc_keys_driver); 201 202 MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>"); 203 MODULE_DESCRIPTION("Input driver for resistor ladder connected on ADC"); 204 MODULE_LICENSE("GPL v2"); 205