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