Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c8a23c2 authored by Linus Walleij's avatar Linus Walleij Committed by Dmitry Torokhov
Browse files

Input: gpio_tilt - delete driver



This driver was merged in 2011 as a tool for detecting the orientation
of a screen. The device driver assumes board file setup using the
platform data from <linux/input/gpio_tilt.h>. But no boards in the
kernel tree defines this platform data.

As I am faced with refactoring drivers to use GPIO descriptors and
pass decriptor tables from boards, or use the device tree device
drivers like these creates a serious problem: I cannot fix them and
cannot test them, not even compile-test them with a system actually
using it (no in-tree boardfile).

I suggest to delete this driver and rewrite it using device tree if
it is still in use on actively maintained systems.

I can also offer to rewrite it out of the blue using device tree if
someone promise to test it and help me iterate it.

Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Acked-by: default avatarHeiko Stuebner <heiko@sntech.de>
Patchwork-Id: 10133609
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent b3495cec
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -28,11 +28,6 @@ hardware descriptions such as device tree or ACPI:
- gpio-beeper: drivers/input/misc/gpio-beeper.c is used to provide a beep from
  an external speaker connected to a GPIO line.

- gpio-tilt-polled: drivers/input/misc/gpio_tilt_polled.c provides tilt
  detection switches using GPIO, which is useful for your homebrewn pinball
  machine if for nothing else. It can detect different tilt angles of the
  monitored object.

- extcon-gpio: drivers/extcon/extcon-gpio.c is used when you need to read an
  external connector status, such as a headset line for an audio driver or an
  HDMI connector. It will provide a better userspace sysfs interface than GPIO.
+0 −103
Original line number Diff line number Diff line
Driver for tilt-switches connected via GPIOs
============================================

Generic driver to read data from tilt switches connected via gpios.
Orientation can be provided by one or more than one tilt switches,
i.e. each tilt switch providing one axis, and the number of axes
is also not limited.


Data structures
---------------

The array of struct gpio in the gpios field is used to list the gpios
that represent the current tilt state.

The array of struct gpio_tilt_axis describes the axes that are reported
to the input system. The values set therein are used for the
input_set_abs_params calls needed to init the axes.

The array of struct gpio_tilt_state maps gpio states to the corresponding
values to report. The gpio state is represented as a bitfield where the
bit-index corresponds to the index of the gpio in the struct gpio array.
In the same manner the values stored in the axes array correspond to
the elements of the gpio_tilt_axis-array.


Example
-------

Example configuration for a single TS1003 tilt switch that rotates around
one axis in 4 steps and emits the current tilt via two GPIOs::

    static int sg060_tilt_enable(struct device *dev) {
	    /* code to enable the sensors */
    };

    static void sg060_tilt_disable(struct device *dev) {
	    /* code to disable the sensors */
    };

    static struct gpio sg060_tilt_gpios[] = {
	    { SG060_TILT_GPIO_SENSOR1, GPIOF_IN, "tilt_sensor1" },
	    { SG060_TILT_GPIO_SENSOR2, GPIOF_IN, "tilt_sensor2" },
    };

    static struct gpio_tilt_state sg060_tilt_states[] = {
	    {
		    .gpios = (0 << 1) | (0 << 0),
		    .axes = (int[]) {
			    0,
		    },
	    }, {
		    .gpios = (0 << 1) | (1 << 0),
		    .axes = (int[]) {
			    1, /* 90 degrees */
		    },
	    }, {
		    .gpios = (1 << 1) | (1 << 0),
		    .axes = (int[]) {
			    2, /* 180 degrees */
		    },
	    }, {
		    .gpios = (1 << 1) | (0 << 0),
		    .axes = (int[]) {
			    3, /* 270 degrees */
		    },
	    },
    };

    static struct gpio_tilt_axis sg060_tilt_axes[] = {
	    {
		    .axis = ABS_RY,
		    .min = 0,
		    .max = 3,
		    .fuzz = 0,
		    .flat = 0,
	    },
    };

    static struct gpio_tilt_platform_data sg060_tilt_pdata= {
	    .gpios = sg060_tilt_gpios,
	    .nr_gpios = ARRAY_SIZE(sg060_tilt_gpios),

	    .axes = sg060_tilt_axes,
	    .nr_axes = ARRAY_SIZE(sg060_tilt_axes),

	    .states = sg060_tilt_states,
	    .nr_states = ARRAY_SIZE(sg060_tilt_states),

	    .debounce_interval = 100,

	    .poll_interval = 1000,
	    .enable = sg060_tilt_enable,
	    .disable = sg060_tilt_disable,
    };

    static struct platform_device sg060_device_tilt = {
	    .name = "gpio-tilt-polled",
	    .id = -1,
	    .dev = {
		    .platform_data = &sg060_tilt_pdata,
	    },
    };
+0 −14
Original line number Diff line number Diff line
@@ -268,20 +268,6 @@ config INPUT_GPIO_BEEPER
	  To compile this driver as a module, choose M here: the
	  module will be called gpio-beeper.

config INPUT_GPIO_TILT_POLLED
	tristate "Polled GPIO tilt switch"
	depends on GPIOLIB || COMPILE_TEST
	select INPUT_POLLDEV
	help
	  This driver implements support for tilt switches connected
	  to GPIO pins that are not capable of generating interrupts.

	  The list of gpios to use and the mapping of their states
	  to specific angles is done via platform data.

	  To compile this driver as a module, choose M here: the
	  module will be called gpio_tilt_polled.

config INPUT_GPIO_DECODER
	tristate "Polled GPIO Decoder Input driver"
	depends on GPIOLIB || COMPILE_TEST
+0 −1
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ obj-$(CONFIG_INPUT_DRV2665_HAPTICS) += drv2665.o
obj-$(CONFIG_INPUT_DRV2667_HAPTICS)	+= drv2667.o
obj-$(CONFIG_INPUT_GP2A)		+= gp2ap002a00f.o
obj-$(CONFIG_INPUT_GPIO_BEEPER)		+= gpio-beeper.o
obj-$(CONFIG_INPUT_GPIO_TILT_POLLED)	+= gpio_tilt_polled.o
obj-$(CONFIG_INPUT_GPIO_DECODER)	+= gpio_decoder.o
obj-$(CONFIG_INPUT_HISI_POWERKEY)	+= hisi_powerkey.o
obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
+0 −210
Original line number Diff line number Diff line
/*
 *  Driver for tilt switches connected via GPIO lines
 *  not capable of generating interrupts
 *
 *  Copyright (C) 2011 Heiko Stuebner <heiko@sntech.de>
 *
 *  based on: drivers/input/keyboard/gpio_keys_polled.c
 *
 *  Copyright (C) 2007-2010 Gabor Juhos <juhosg@openwrt.org>
 *  Copyright (C) 2010 Nuno Goncalves <nunojpg@gmail.com>
 *
 *  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/slab.h>
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/input/gpio_tilt.h>

#define DRV_NAME	"gpio-tilt-polled"

struct gpio_tilt_polled_dev {
	struct input_polled_dev *poll_dev;
	struct device *dev;
	const struct gpio_tilt_platform_data *pdata;

	int last_state;

	int threshold;
	int count;
};

static void gpio_tilt_polled_poll(struct input_polled_dev *dev)
{
	struct gpio_tilt_polled_dev *tdev = dev->private;
	const struct gpio_tilt_platform_data *pdata = tdev->pdata;
	struct input_dev *input = dev->input;
	struct gpio_tilt_state *tilt_state = NULL;
	int state, i;

	if (tdev->count < tdev->threshold) {
		tdev->count++;
	} else {
		state = 0;
		for (i = 0; i < pdata->nr_gpios; i++)
			state |= (!!gpio_get_value(pdata->gpios[i].gpio) << i);

		if (state != tdev->last_state) {
			for (i = 0; i < pdata->nr_states; i++)
				if (pdata->states[i].gpios == state)
					tilt_state = &pdata->states[i];

			if (tilt_state) {
				for (i = 0; i < pdata->nr_axes; i++)
					input_report_abs(input,
							 pdata->axes[i].axis,
							 tilt_state->axes[i]);

				input_sync(input);
			}

			tdev->count = 0;
			tdev->last_state = state;
		}
	}
}

static void gpio_tilt_polled_open(struct input_polled_dev *dev)
{
	struct gpio_tilt_polled_dev *tdev = dev->private;
	const struct gpio_tilt_platform_data *pdata = tdev->pdata;

	if (pdata->enable)
		pdata->enable(tdev->dev);

	/* report initial state of the axes */
	tdev->last_state = -1;
	tdev->count = tdev->threshold;
	gpio_tilt_polled_poll(tdev->poll_dev);
}

static void gpio_tilt_polled_close(struct input_polled_dev *dev)
{
	struct gpio_tilt_polled_dev *tdev = dev->private;
	const struct gpio_tilt_platform_data *pdata = tdev->pdata;

	if (pdata->disable)
		pdata->disable(tdev->dev);
}

static int gpio_tilt_polled_probe(struct platform_device *pdev)
{
	const struct gpio_tilt_platform_data *pdata =
			dev_get_platdata(&pdev->dev);
	struct device *dev = &pdev->dev;
	struct gpio_tilt_polled_dev *tdev;
	struct input_polled_dev *poll_dev;
	struct input_dev *input;
	int error, i;

	if (!pdata || !pdata->poll_interval)
		return -EINVAL;

	tdev = kzalloc(sizeof(struct gpio_tilt_polled_dev), GFP_KERNEL);
	if (!tdev) {
		dev_err(dev, "no memory for private data\n");
		return -ENOMEM;
	}

	error = gpio_request_array(pdata->gpios, pdata->nr_gpios);
	if (error) {
		dev_err(dev,
			"Could not request tilt GPIOs: %d\n", error);
		goto err_free_tdev;
	}

	poll_dev = input_allocate_polled_device();
	if (!poll_dev) {
		dev_err(dev, "no memory for polled device\n");
		error = -ENOMEM;
		goto err_free_gpios;
	}

	poll_dev->private = tdev;
	poll_dev->poll = gpio_tilt_polled_poll;
	poll_dev->poll_interval = pdata->poll_interval;
	poll_dev->open = gpio_tilt_polled_open;
	poll_dev->close = gpio_tilt_polled_close;

	input = poll_dev->input;

	input->name = pdev->name;
	input->phys = DRV_NAME"/input0";
	input->dev.parent = dev;

	input->id.bustype = BUS_HOST;
	input->id.vendor = 0x0001;
	input->id.product = 0x0001;
	input->id.version = 0x0100;

	__set_bit(EV_ABS, input->evbit);
	for (i = 0; i < pdata->nr_axes; i++)
		input_set_abs_params(input, pdata->axes[i].axis,
				     pdata->axes[i].min, pdata->axes[i].max,
				     pdata->axes[i].fuzz, pdata->axes[i].flat);

	tdev->threshold = DIV_ROUND_UP(pdata->debounce_interval,
				       pdata->poll_interval);

	tdev->poll_dev = poll_dev;
	tdev->dev = dev;
	tdev->pdata = pdata;

	error = input_register_polled_device(poll_dev);
	if (error) {
		dev_err(dev, "unable to register polled device, err=%d\n",
			error);
		goto err_free_polldev;
	}

	platform_set_drvdata(pdev, tdev);

	return 0;

err_free_polldev:
	input_free_polled_device(poll_dev);
err_free_gpios:
	gpio_free_array(pdata->gpios, pdata->nr_gpios);
err_free_tdev:
	kfree(tdev);

	return error;
}

static int gpio_tilt_polled_remove(struct platform_device *pdev)
{
	struct gpio_tilt_polled_dev *tdev = platform_get_drvdata(pdev);
	const struct gpio_tilt_platform_data *pdata = tdev->pdata;

	input_unregister_polled_device(tdev->poll_dev);
	input_free_polled_device(tdev->poll_dev);

	gpio_free_array(pdata->gpios, pdata->nr_gpios);

	kfree(tdev);

	return 0;
}

static struct platform_driver gpio_tilt_polled_driver = {
	.probe	= gpio_tilt_polled_probe,
	.remove	= gpio_tilt_polled_remove,
	.driver	= {
		.name	= DRV_NAME,
	},
};

module_platform_driver(gpio_tilt_polled_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
MODULE_DESCRIPTION("Polled GPIO tilt driver");
MODULE_ALIAS("platform:" DRV_NAME);
Loading