rotary_encoder.c 9.8 KB
Newer Older
1 2 3 4
/*
 * rotary_encoder.c
 *
 * (c) 2009 Daniel Mack <daniel@caiaq.de>
5
 * Copyright (C) 2011 Johan Hovold <jhovold@gmail.com>
6 7 8 9
 *
 * state machine code inspired by code from Tim Ruetz
 *
 * A generic driver for rotary encoders connected to GPIO lines.
P
Paul Bolle 已提交
10
 * See file:Documentation/input/rotary-encoder.txt for more information
11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/rotary_encoder.h>
25
#include <linux/slab.h>
26
#include <linux/of.h>
27 28
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
29
#include <linux/pm.h>
30 31 32 33 34

#define DRV_NAME "rotary-encoder"

struct rotary_encoder {
	struct input_dev *input;
35
	const struct rotary_encoder_platform_data *pdata;
36
	struct mutex access_mutex;
37 38 39 40 41 42 43 44 45

	unsigned int axis;
	unsigned int pos;

	unsigned int irq_a;
	unsigned int irq_b;

	bool armed;
	unsigned char dir;	/* 0 - clockwise, 1 - CCW */
46 47

	char last_stable;
48 49
};

50
static int rotary_encoder_get_state(const struct rotary_encoder_platform_data *pdata)
51
{
52 53
	int a = !!gpio_get_value_cansleep(pdata->gpio_a);
	int b = !!gpio_get_value_cansleep(pdata->gpio_b);
54 55 56 57

	a ^= pdata->inverted_a;
	b ^= pdata->inverted_b;

58 59
	return ((a << 1) | b);
}
60

61 62
static void rotary_encoder_report_event(struct rotary_encoder *encoder)
{
63
	const struct rotary_encoder_platform_data *pdata = encoder->pdata;
64

65 66 67 68 69 70 71 72
	if (pdata->relative_axis) {
		input_report_rel(encoder->input,
				 pdata->axis, encoder->dir ? -1 : 1);
	} else {
		unsigned int pos = encoder->pos;

		if (encoder->dir) {
			/* turning counter-clockwise */
73
			if (pdata->rollover)
74 75 76 77 78 79 80
				pos += pdata->steps;
			if (pos)
				pos--;
		} else {
			/* turning clockwise */
			if (pdata->rollover || pos < pdata->steps)
				pos++;
81 82
		}

83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
		if (pdata->rollover)
			pos %= pdata->steps;

		encoder->pos = pos;
		input_report_abs(encoder->input, pdata->axis, encoder->pos);
	}

	input_sync(encoder->input);
}

static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
{
	struct rotary_encoder *encoder = dev_id;
	int state;

98 99
	mutex_lock(&encoder->access_mutex);

100 101 102 103 104 105 106 107
	state = rotary_encoder_get_state(encoder->pdata);

	switch (state) {
	case 0x0:
		if (encoder->armed) {
			rotary_encoder_report_event(encoder);
			encoder->armed = false;
		}
108 109 110 111 112 113 114 115 116
		break;

	case 0x1:
	case 0x2:
		if (encoder->armed)
			encoder->dir = state - 1;
		break;

	case 0x3:
117
		encoder->armed = true;
118 119 120
		break;
	}

121 122
	mutex_unlock(&encoder->access_mutex);

123 124 125
	return IRQ_HANDLED;
}

126 127 128 129 130
static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id)
{
	struct rotary_encoder *encoder = dev_id;
	int state;

131 132
	mutex_lock(&encoder->access_mutex);

133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
	state = rotary_encoder_get_state(encoder->pdata);

	switch (state) {
	case 0x00:
	case 0x03:
		if (state != encoder->last_stable) {
			rotary_encoder_report_event(encoder);
			encoder->last_stable = state;
		}
		break;

	case 0x01:
	case 0x02:
		encoder->dir = (encoder->last_stable + state) & 0x01;
		break;
	}

150 151
	mutex_unlock(&encoder->access_mutex);

152 153 154
	return IRQ_HANDLED;
}

155 156 157 158 159 160
static irqreturn_t rotary_encoder_quarter_period_irq(int irq, void *dev_id)
{
	struct rotary_encoder *encoder = dev_id;
	unsigned char sum;
	int state;

161 162
	mutex_lock(&encoder->access_mutex);

163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
	state = rotary_encoder_get_state(encoder->pdata);

	/*
	 * We encode the previous and the current state using a byte.
	 * The previous state in the MSB nibble, the current state in the LSB
	 * nibble. Then use a table to decide the direction of the turn.
	 */
	sum = (encoder->last_stable << 4) + state;
	switch (sum) {
	case 0x31:
	case 0x10:
	case 0x02:
	case 0x23:
		encoder->dir = 0; /* clockwise */
		break;

	case 0x13:
	case 0x01:
	case 0x20:
	case 0x32:
		encoder->dir = 1; /* counter-clockwise */
		break;

	default:
		/*
		 * Ignore all other values. This covers the case when the
		 * state didn't change (a spurious interrupt) and the
		 * cases where the state changed by two steps, making it
		 * impossible to tell the direction.
		 *
		 * In either case, don't report any event and save the
		 * state for later.
		 */
		goto out;
	}

	rotary_encoder_report_event(encoder);

out:
	encoder->last_stable = state;
203 204
	mutex_unlock(&encoder->access_mutex);

205 206 207
	return IRQ_HANDLED;
}

208
#ifdef CONFIG_OF
209
static const struct of_device_id rotary_encoder_of_match[] = {
210 211 212 213 214
	{ .compatible = "rotary-encoder", },
	{ },
};
MODULE_DEVICE_TABLE(of, rotary_encoder_of_match);

B
Bill Pemberton 已提交
215
static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct device *dev)
216 217 218 219 220 221
{
	const struct of_device_id *of_id =
				of_match_device(rotary_encoder_of_match, dev);
	struct device_node *np = dev->of_node;
	struct rotary_encoder_platform_data *pdata;
	enum of_gpio_flags flags;
222
	int error;
223 224 225 226

	if (!of_id || !np)
		return NULL;

227 228
	pdata = devm_kzalloc(dev, sizeof(struct rotary_encoder_platform_data),
			     GFP_KERNEL);
229 230 231 232 233 234 235 236 237 238 239 240
	if (!pdata)
		return ERR_PTR(-ENOMEM);

	of_property_read_u32(np, "rotary-encoder,steps", &pdata->steps);
	of_property_read_u32(np, "linux,axis", &pdata->axis);

	pdata->gpio_a = of_get_gpio_flags(np, 0, &flags);
	pdata->inverted_a = flags & OF_GPIO_ACTIVE_LOW;

	pdata->gpio_b = of_get_gpio_flags(np, 1, &flags);
	pdata->inverted_b = flags & OF_GPIO_ACTIVE_LOW;

241 242 243
	pdata->relative_axis =
		of_property_read_bool(np, "rotary-encoder,relative-axis");
	pdata->rollover = of_property_read_bool(np, "rotary-encoder,rollover");
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260

	error = of_property_read_u32(np, "rotary-encoder,steps-per-period",
				     &pdata->steps_per_period);
	if (error) {
		/*
		 * The 'half-period' property has been deprecated, you must use
		 * 'steps-per-period' and set an appropriate value, but we still
		 * need to parse it to maintain compatibility.
		 */
		if (of_property_read_bool(np, "rotary-encoder,half-period")) {
			pdata->steps_per_period = 2;
		} else {
			/* Fallback to one step per period behavior */
			pdata->steps_per_period = 1;
		}
	}

261
	pdata->wakeup_source = of_property_read_bool(np, "wakeup-source");
262 263 264 265 266 267 268 269 270 271 272

	return pdata;
}
#else
static inline struct rotary_encoder_platform_data *
rotary_encoder_parse_dt(struct device *dev)
{
	return NULL;
}
#endif

B
Bill Pemberton 已提交
273
static int rotary_encoder_probe(struct platform_device *pdev)
274
{
275 276
	struct device *dev = &pdev->dev;
	const struct rotary_encoder_platform_data *pdata = dev_get_platdata(dev);
277 278
	struct rotary_encoder *encoder;
	struct input_dev *input;
279
	irq_handler_t handler;
280 281
	int err;

282
	if (!pdata) {
283 284 285 286 287 288 289 290
		pdata = rotary_encoder_parse_dt(dev);
		if (IS_ERR(pdata))
			return PTR_ERR(pdata);

		if (!pdata) {
			dev_err(dev, "missing platform data\n");
			return -EINVAL;
		}
291 292
	}

293 294 295 296 297 298 299
	encoder = devm_kzalloc(dev, sizeof(struct rotary_encoder), GFP_KERNEL);
	if (!encoder)
		return -ENOMEM;

	input = devm_input_allocate_device(dev);
	if (!input)
		return -ENOMEM;
300

301 302
	mutex_init(&encoder->access_mutex);

303 304 305 306 307
	encoder->input = input;
	encoder->pdata = pdata;

	input->name = pdev->name;
	input->id.bustype = BUS_HOST;
308
	input->dev.parent = dev;
309 310 311 312 313 314 315 316 317

	if (pdata->relative_axis) {
		input->evbit[0] = BIT_MASK(EV_REL);
		input->relbit[0] = BIT_MASK(pdata->axis);
	} else {
		input->evbit[0] = BIT_MASK(EV_ABS);
		input_set_abs_params(encoder->input,
				     pdata->axis, 0, pdata->steps, 0, 1);
	}
318 319

	/* request the GPIOs */
320 321
	err = devm_gpio_request_one(dev, pdata->gpio_a, GPIOF_IN,
				    dev_name(dev));
322
	if (err) {
323
		dev_err(dev, "unable to request GPIO %d\n", pdata->gpio_a);
324
		return err;
325 326
	}

327 328
	err = devm_gpio_request_one(dev, pdata->gpio_b, GPIOF_IN,
				    dev_name(dev));
329
	if (err) {
330
		dev_err(dev, "unable to request GPIO %d\n", pdata->gpio_b);
331
		return err;
332 333
	}

334 335 336
	encoder->irq_a = gpio_to_irq(pdata->gpio_a);
	encoder->irq_b = gpio_to_irq(pdata->gpio_b);

337 338 339 340 341 342
	switch (pdata->steps_per_period) {
	case 4:
		handler = &rotary_encoder_quarter_period_irq;
		encoder->last_stable = rotary_encoder_get_state(pdata);
		break;
	case 2:
343 344
		handler = &rotary_encoder_half_period_irq;
		encoder->last_stable = rotary_encoder_get_state(pdata);
345 346
		break;
	case 1:
347
		handler = &rotary_encoder_irq;
348 349 350 351
		break;
	default:
		dev_err(dev, "'%d' is not a valid steps-per-period value\n",
			pdata->steps_per_period);
352
		return -EINVAL;
353 354
	}

355 356 357 358
	err = devm_request_threaded_irq(dev, encoder->irq_a, NULL, handler,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
				IRQF_ONESHOT,
				DRV_NAME, encoder);
359
	if (err) {
360
		dev_err(dev, "unable to request IRQ %d\n", encoder->irq_a);
361
		return err;
362 363
	}

364 365 366 367
	err = devm_request_threaded_irq(dev, encoder->irq_b, NULL, handler,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
				IRQF_ONESHOT,
				DRV_NAME, encoder);
368
	if (err) {
369
		dev_err(dev, "unable to request IRQ %d\n", encoder->irq_b);
370
		return err;
371 372
	}

373 374 375
	err = input_register_device(input);
	if (err) {
		dev_err(dev, "failed to register input device\n");
376
		return err;
377 378
	}

379 380
	device_init_wakeup(&pdev->dev, pdata->wakeup_source);

381 382 383 384 385
	platform_set_drvdata(pdev, encoder);

	return 0;
}

386
static int __maybe_unused rotary_encoder_suspend(struct device *dev)
387 388 389 390 391 392 393 394 395 396 397
{
	struct rotary_encoder *encoder = dev_get_drvdata(dev);

	if (device_may_wakeup(dev)) {
		enable_irq_wake(encoder->irq_a);
		enable_irq_wake(encoder->irq_b);
	}

	return 0;
}

398
static int __maybe_unused rotary_encoder_resume(struct device *dev)
399 400 401 402 403 404 405 406 407 408 409 410
{
	struct rotary_encoder *encoder = dev_get_drvdata(dev);

	if (device_may_wakeup(dev)) {
		disable_irq_wake(encoder->irq_a);
		disable_irq_wake(encoder->irq_b);
	}

	return 0;
}

static SIMPLE_DEV_PM_OPS(rotary_encoder_pm_ops,
411
			 rotary_encoder_suspend, rotary_encoder_resume);
412

413 414 415 416
static struct platform_driver rotary_encoder_driver = {
	.probe		= rotary_encoder_probe,
	.driver		= {
		.name	= DRV_NAME,
417
		.pm	= &rotary_encoder_pm_ops,
418
		.of_match_table = of_match_ptr(rotary_encoder_of_match),
419 420
	}
};
421
module_platform_driver(rotary_encoder_driver);
422 423 424

MODULE_ALIAS("platform:" DRV_NAME);
MODULE_DESCRIPTION("GPIO rotary encoder driver");
425
MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>, Johan Hovold");
426
MODULE_LICENSE("GPL v2");