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 struct fwnode_handle *child; 70 int i; 71 72 st->num_keys = device_get_child_node_count(dev); 73 if (st->num_keys == 0) { 74 dev_err(dev, "keymap is missing\n"); 75 return -EINVAL; 76 } 77 78 map = devm_kmalloc_array(dev, st->num_keys, sizeof(*map), GFP_KERNEL); 79 if (!map) 80 return -ENOMEM; 81 82 i = 0; 83 device_for_each_child_node(dev, child) { 84 if (fwnode_property_read_u32(child, "press-threshold-microvolt", 85 &map[i].voltage)) { 86 dev_err(dev, "Key with invalid or missing voltage\n"); 87 fwnode_handle_put(child); 88 return -EINVAL; 89 } 90 map[i].voltage /= 1000; 91 92 if (fwnode_property_read_u32(child, "linux,code", 93 &map[i].keycode)) { 94 dev_err(dev, "Key with invalid or missing linux,code\n"); 95 fwnode_handle_put(child); 96 return -EINVAL; 97 } 98 99 i++; 100 } 101 102 st->map = map; 103 return 0; 104 } 105 106 static int adc_keys_probe(struct platform_device *pdev) 107 { 108 struct device *dev = &pdev->dev; 109 struct adc_keys_state *st; 110 struct input_dev *input; 111 enum iio_chan_type type; 112 int i, value; 113 int error; 114 115 st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); 116 if (!st) 117 return -ENOMEM; 118 119 st->channel = devm_iio_channel_get(dev, "buttons"); 120 if (IS_ERR(st->channel)) 121 return PTR_ERR(st->channel); 122 123 if (!st->channel->indio_dev) 124 return -ENXIO; 125 126 error = iio_get_channel_type(st->channel, &type); 127 if (error < 0) 128 return error; 129 130 if (type != IIO_VOLTAGE) { 131 dev_err(dev, "Incompatible channel type %d\n", type); 132 return -EINVAL; 133 } 134 135 if (device_property_read_u32(dev, "keyup-threshold-microvolt", 136 &st->keyup_voltage)) { 137 dev_err(dev, "Invalid or missing keyup voltage\n"); 138 return -EINVAL; 139 } 140 st->keyup_voltage /= 1000; 141 142 error = adc_keys_load_keymap(dev, st); 143 if (error) 144 return error; 145 146 input = devm_input_allocate_device(dev); 147 if (!input) { 148 dev_err(dev, "failed to allocate input device\n"); 149 return -ENOMEM; 150 } 151 152 input_set_drvdata(input, st); 153 154 input->name = pdev->name; 155 input->phys = "adc-keys/input0"; 156 157 input->id.bustype = BUS_HOST; 158 input->id.vendor = 0x0001; 159 input->id.product = 0x0001; 160 input->id.version = 0x0100; 161 162 __set_bit(EV_KEY, input->evbit); 163 for (i = 0; i < st->num_keys; i++) 164 __set_bit(st->map[i].keycode, input->keybit); 165 166 if (device_property_read_bool(dev, "autorepeat")) 167 __set_bit(EV_REP, input->evbit); 168 169 170 error = input_setup_polling(input, adc_keys_poll); 171 if (error) { 172 dev_err(dev, "Unable to set up polling: %d\n", error); 173 return error; 174 } 175 176 if (!device_property_read_u32(dev, "poll-interval", &value)) 177 input_set_poll_interval(input, value); 178 179 error = input_register_device(input); 180 if (error) { 181 dev_err(dev, "Unable to register input device: %d\n", error); 182 return error; 183 } 184 185 return 0; 186 } 187 188 #ifdef CONFIG_OF 189 static const struct of_device_id adc_keys_of_match[] = { 190 { .compatible = "adc-keys", }, 191 { } 192 }; 193 MODULE_DEVICE_TABLE(of, adc_keys_of_match); 194 #endif 195 196 static struct platform_driver adc_keys_driver = { 197 .driver = { 198 .name = "adc_keys", 199 .of_match_table = of_match_ptr(adc_keys_of_match), 200 }, 201 .probe = adc_keys_probe, 202 }; 203 module_platform_driver(adc_keys_driver); 204 205 MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>"); 206 MODULE_DESCRIPTION("Input driver for resistor ladder connected on ADC"); 207 MODULE_LICENSE("GPL v2"); 208