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