Commit 42671e9c authored by Linus Walleij's avatar Linus Walleij Committed by Thomas Bogendoerfer
Browse files

MIPS/input: Move RB532 button to GPIO descriptors



Convert the Mikrotik RouterBoard RB532 to use GPIO descriptors
by defining a software node for the GPIO chip, then register
the button platform device with full info passing the GPIO
as a device property.

This can be used as a base to move more of the RB532 devices
over to passing GPIOs using device properties.

Use the GPIO_ACTIVE_LOW flag and drop the inversion in the
rb532_button_pressed() function.

Signed-off-by: default avatarLinus Walleij <linusw@kernel.org>
Acked-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: default avatarThomas Bogendoerfer <tsbogend@alpha.franken.de>
parent f992846d
Loading
Loading
Loading
Loading
+40 −7
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@
#include <linux/mtd/mtd.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/gpio/property.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/property.h>
#include <linux/serial_8250.h>

#include <asm/bootinfo.h>
@@ -38,6 +40,10 @@ extern unsigned int idt_cpu_freq;

static struct mpmc_device dev3;

static const struct software_node rb532_gpio0_node = {
	.name = "gpio0",
};

void set_latch_u5(unsigned char or_mask, unsigned char nand_mask)
{
	unsigned long flags;
@@ -189,11 +195,6 @@ static struct platform_device rb532_led = {
	.id = -1,
};

static struct platform_device rb532_button = {
	.name	= "rb532-button",
	.id	= -1,
};

static struct resource rb532_wdt_res[] = {
	{
		.name = "rb532_wdt_res",
@@ -236,11 +237,23 @@ static struct platform_device *rb532_devs[] = {
	&nand_slot0,
	&cf_slot0,
	&rb532_led,
	&rb532_button,
	&rb532_uart,
	&rb532_wdt
};

static const struct property_entry rb532_button_properties[] = {
	PROPERTY_ENTRY_GPIO("button-gpios", &rb532_gpio0_node,
			    GPIO_BTN_S1, GPIO_ACTIVE_LOW),
	{ }
};

static const struct platform_device_info rb532_button_info  __initconst = {
	.name		= "rb532-button",
	.id		= PLATFORM_DEVID_NONE,
	.properties	= rb532_button_properties,
};


/* NAND definitions */
#define NAND_CHIP_DELAY 25

@@ -267,6 +280,9 @@ static void __init rb532_nand_setup(void)

static int __init plat_setup_devices(void)
{
	struct platform_device *pd;
	int ret;

	/* Look for the CF card reader */
	if (!readl(IDT434_REG_BASE + DEV1MASK))
		rb532_devs[2] = NULL;	/* disable cf_slot0 at index 2 */
@@ -295,7 +311,24 @@ static int __init plat_setup_devices(void)
	rb532_uart_res[0].uartclk = idt_cpu_freq;

	gpiod_add_lookup_table(&cf_slot0_gpio_table);
	return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
	ret = platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
	if (ret)
		return ret;

	/*
	 * Stack devices using full info and properties here, after we
	 * register the node for the GPIO chip.
	 */
	software_node_register(&rb532_gpio0_node);

	pd = platform_device_register_full(&rb532_button_info);
	ret = PTR_ERR_OR_ZERO(pd);
	if (ret) {
		pr_err("failed to create RB532 button device: %d\n", ret);
		return ret;
	}

	return 0;
}

#ifdef CONFIG_NET
+29 −6
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@
#include <linux/input.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>

#include <asm/mach-rc32434/gpio.h>
#include <asm/mach-rc32434/rb.h>
@@ -18,6 +18,14 @@
#define RB532_BTN_RATE 100 /* msec */
#define RB532_BTN_KSYM BTN_0

/**
 * struct rb532_button - RB532 button information
 * @gpio: GPIO connected to the button
 */
struct rb532_button {
	struct gpio_desc	*gpio;
};

/* The S1 button state is provided by GPIO pin 1. But as this
 * pin is also used for uart input as alternate function, the
 * operational modes must be switched first:
@@ -31,35 +39,48 @@
 * The GPIO value occurs to be inverted, so pin high means
 * button is not pressed.
 */
static bool rb532_button_pressed(void)
static bool rb532_button_pressed(struct rb532_button *button)
{
	int val;

	set_latch_u5(0, LO_FOFF);
	gpio_direction_input(GPIO_BTN_S1);
	gpiod_direction_input(button->gpio);

	val = gpio_get_value(GPIO_BTN_S1);
	val = gpiod_get_value(button->gpio);

	rb532_gpio_set_func(GPIO_BTN_S1);
	set_latch_u5(LO_FOFF, 0);

	return !val;
	return val;
}

static void rb532_button_poll(struct input_dev *input)
{
	input_report_key(input, RB532_BTN_KSYM, rb532_button_pressed());
	struct rb532_button *button = input_get_drvdata(input);

	input_report_key(input, RB532_BTN_KSYM, rb532_button_pressed(button));
	input_sync(input);
}

static int rb532_button_probe(struct platform_device *pdev)
{
	struct rb532_button *button;
	struct input_dev *input;
	int error;

	button = devm_kzalloc(&pdev->dev, sizeof(*button), GFP_KERNEL);
	if (!button)
		return -ENOMEM;

	button->gpio = devm_gpiod_get(&pdev->dev, "button", GPIOD_IN);
	if (IS_ERR(button->gpio))
		return dev_err_probe(&pdev->dev, PTR_ERR(button->gpio),
				     "error getting button GPIO\n");

	input = devm_input_allocate_device(&pdev->dev);
	if (!input)
		return -ENOMEM;
	input_set_drvdata(input, button);

	input->name = "rb532 button";
	input->phys = "rb532/button0";
@@ -77,6 +98,8 @@ static int rb532_button_probe(struct platform_device *pdev)
	if (error)
		return error;

	platform_set_drvdata(pdev, button);

	return 0;
}