aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2024-04-25 13:31:02 +0200
committerLinus Walleij <linus.walleij@linaro.org>2024-04-29 14:29:42 +0200
commit6740c34b91f06e758a0ac8dabeb4145aacb7a87b (patch)
tree02aa6374cca3d823b5e5209e72a44d2354db3e01
parentd55070d9be7a1c43693cb2d2a65a4997f1b59217 (diff)
downloadlinux-gpio-b4/spitz.tar.gz
ARM: spitz: Use software nodes for the ADS7846 touchscreenb4/spitz
Convert the Spitz to use software nodes for SPI CS and the ADS7846 touchscreen following the pattern used in the TI platforms. The Spitz is the only user of the wait_for_sync() callback in the platform data, so define that this is a separate GPIO in the device tree bindings (previous patch) and handle this directly inside the ADS7846 driver instead. Add some infrastructure to the PXA boardfile common code to handle software nodes attached to the SPI bus instead of platform data. The SPI core will investigate the numner of GPIO handles to figure out the number of chipselects used on the platform, so no explicit encoding of the number of the number of chipselects is needed. Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--arch/arm/mach-pxa/devices.c16
-rw-r--r--arch/arm/mach-pxa/spitz.c75
-rw-r--r--drivers/input/touchscreen/ads7846.c31
-rw-r--r--include/linux/spi/ads7846.h1
-rw-r--r--include/linux/spi/pxa2xx_spi.h2
5 files changed, 78 insertions, 47 deletions
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index 661b3fc4327596..e0e21cb97f7107 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -9,6 +9,7 @@
#include <linux/dmaengine.h>
#include <linux/spi/pxa2xx_spi.h>
#include <linux/platform_data/i2c-pxa.h>
+#include <linux/property.h>
#include <linux/soc/pxa/cpu.h>
#include "udc.h"
@@ -682,6 +683,21 @@ void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_controller *info)
platform_device_add(pd);
}
+void __init pxa2xx_set_spi_node(unsigned id, const struct property_entry *props)
+{
+ struct platform_device *pd;
+
+ pd = platform_device_alloc("pxa2xx-spi", id);
+ if (pd == NULL) {
+ printk(KERN_ERR "pxa2xx-spi: failed to allocate device id %d\n",
+ id);
+ return;
+ }
+
+ device_create_managed_software_node(&pd->dev, props, NULL);
+ platform_device_add(pd);
+}
+
static struct resource pxa_dma_resource[] = {
[0] = {
.start = 0x40000000,
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 36aec5ea72187f..bc93ceed0022cd 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -14,6 +14,7 @@
#include <linux/gpio_keys.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
+#include <linux/gpio/property.h>
#include <linux/leds.h>
#include <linux/i2c.h>
#include <linux/platform_data/i2c-pxa.h>
@@ -28,6 +29,7 @@
#include <linux/input/matrix_keypad.h>
#include <linux/regulator/machine.h>
#include <linux/io.h>
+#include <linux/property.h>
#include <linux/reboot.h>
#include <linux/memblock.h>
@@ -128,6 +130,15 @@ static unsigned long spitz_pin_config[] __initdata = {
GPIO1_GPIO | WAKEUP_ON_EDGE_FALL, /* SPITZ_GPIO_RESET */
};
+static const struct software_node pxa_gpiochip_node = {
+ .name = "gpio-pxa",
+};
+
+static const struct software_node *spitz_gpiochip_nodes[] = {
+ &pxa_gpiochip_node,
+ /* TODO: add the GPIO expander nodes here */
+ NULL
+};
/******************************************************************************
* Scoop GPIO expander
@@ -500,31 +511,23 @@ static inline void spitz_leds_init(void) {}
* SSP Devices
******************************************************************************/
#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
-static void spitz_ads7846_wait_for_hsync(void)
-{
- while (gpio_get_value(SPITZ_GPIO_HSYNC))
- cpu_relax();
-
- while (!gpio_get_value(SPITZ_GPIO_HSYNC))
- cpu_relax();
-}
-static struct ads7846_platform_data spitz_ads7846_info = {
- .model = 7846,
- .vref_delay_usecs = 100,
- .x_plate_ohms = 419,
- .y_plate_ohms = 486,
- .pressure_max = 1024,
- .wait_for_sync = spitz_ads7846_wait_for_hsync,
+static const struct property_entry spitz_ads7846_props[] = {
+ PROPERTY_ENTRY_STRING("compatible", "ti,ads7846"),
+ PROPERTY_ENTRY_U32("touchscreen-max-pressure", 1024),
+ PROPERTY_ENTRY_U16("ti,x-plate-ohms", 419),
+ PROPERTY_ENTRY_U16("ti,y-plate-ohms", 486),
+ PROPERTY_ENTRY_U16("ti,vref-delay-usecs", 100),
+ PROPERTY_ENTRY_GPIO("pendown-gpios", &pxa_gpiochip_node,
+ SPITZ_GPIO_TP_INT, GPIO_ACTIVE_LOW),
+ PROPERTY_ENTRY_GPIO("ti,hsync-gpios", &pxa_gpiochip_node,
+ SPITZ_GPIO_HSYNC, GPIO_ACTIVE_LOW),
+ { }
};
-static struct gpiod_lookup_table spitz_ads7846_gpio_table = {
- .dev_id = "spi2.0",
- .table = {
- GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_TP_INT,
- "pendown", GPIO_ACTIVE_LOW),
- { }
- },
+static const struct software_node spitz_ads7846_swnode = {
+ .name = "ads7846",
+ .properties = spitz_ads7846_props,
};
static struct gpiod_lookup_table spitz_lcdcon_gpio_table = {
@@ -563,8 +566,7 @@ static struct spi_board_info spitz_spi_devices[] = {
.max_speed_hz = 1200000,
.bus_num = 2,
.chip_select = 0,
- .platform_data = &spitz_ads7846_info,
- .irq = PXA_GPIO_TO_IRQ(SPITZ_GPIO_TP_INT),
+ .swnode = &spitz_ads7846_swnode,
}, {
.modalias = "corgi-lcd",
.max_speed_hz = 50000,
@@ -579,18 +581,18 @@ static struct spi_board_info spitz_spi_devices[] = {
},
};
-static struct pxa2xx_spi_controller spitz_spi_info = {
- .num_chipselect = 3,
+static const struct software_node_ref_args spitz_spi_gpio_refs[] = {
+ SOFTWARE_NODE_REFERENCE(&pxa_gpiochip_node, SPITZ_GPIO_ADS7846_CS,
+ GPIO_ACTIVE_LOW),
+ SOFTWARE_NODE_REFERENCE(&pxa_gpiochip_node, SPITZ_GPIO_LCDCON_CS,
+ GPIO_ACTIVE_LOW),
+ SOFTWARE_NODE_REFERENCE(&pxa_gpiochip_node, SPITZ_GPIO_MAX1111_CS,
+ GPIO_ACTIVE_LOW),
};
-static struct gpiod_lookup_table spitz_spi_gpio_table = {
- .dev_id = "spi2",
- .table = {
- GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_ADS7846_CS, "cs", 0, GPIO_ACTIVE_LOW),
- GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_LCDCON_CS, "cs", 1, GPIO_ACTIVE_LOW),
- GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_MAX1111_CS, "cs", 2, GPIO_ACTIVE_LOW),
- { },
- },
+static const struct property_entry spitz_spi_props[] = {
+ PROPERTY_ENTRY_REF_ARRAY("gpios", spitz_spi_gpio_refs),
+ { }
};
static void __init spitz_spi_init(void)
@@ -600,9 +602,7 @@ static void __init spitz_spi_init(void)
else
gpiod_add_lookup_table(&spitz_lcdcon_gpio_table);
- gpiod_add_lookup_table(&spitz_ads7846_gpio_table);
- gpiod_add_lookup_table(&spitz_spi_gpio_table);
- pxa2xx_set_spi_info(2, &spitz_spi_info);
+ pxa2xx_set_spi_node(2, spitz_spi_props);
spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices));
}
#else
@@ -1007,6 +1007,7 @@ static void spitz_restart(enum reboot_mode mode, const char *cmd)
static void __init spitz_init(void)
{
+ software_node_register_node_group(spitz_gpiochip_nodes);
init_gpio_reset(SPITZ_GPIO_ON_RESET, 1, 0);
pm_power_off = spitz_poweroff;
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index d2bbb436a77df9..af02f70e66fc78 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -138,8 +138,7 @@ struct ads7846 {
void *filter_data;
int (*get_pendown_state)(void);
struct gpio_desc *gpio_pendown;
-
- void (*wait_for_sync)(void);
+ struct gpio_desc *gpio_hsync;
};
enum ads7846_filter {
@@ -634,10 +633,6 @@ ATTRIBUTE_GROUPS(ads784x);
/*--------------------------------------------------------------------------*/
-static void null_wait_for_sync(void)
-{
-}
-
static int ads7846_debounce_filter(void *ads, int data_idx, int *val)
{
struct ads7846 *ts = ads;
@@ -790,6 +785,23 @@ static int ads7846_filter(struct ads7846 *ts)
return 0;
}
+static void ads7846_wait_for_hsync(struct ads7846 *ts)
+{
+ if (!ts->gpio_hsync)
+ return;
+
+ /*
+ * Wait for HSYNC to assert the line should be flagged
+ * as active low so here we are waiting for it to assert
+ */
+ while (!gpiod_get_value(ts->gpio_hsync))
+ cpu_relax();
+
+ /* Then we wait for it do de-assert */
+ while (gpiod_get_value(ts->gpio_hsync))
+ cpu_relax();
+}
+
static void ads7846_read_state(struct ads7846 *ts)
{
struct ads7846_packet *packet = ts->packet;
@@ -800,8 +812,7 @@ static void ads7846_read_state(struct ads7846 *ts)
packet->last_cmd_idx = 0;
while (true) {
- ts->wait_for_sync();
-
+ ads7846_wait_for_hsync(ts);
m = &ts->msg[msg_idx];
error = spi_sync(ts->spi, m);
if (error) {
@@ -1258,7 +1269,9 @@ static int ads7846_probe(struct spi_device *spi)
ts->penirq_recheck_delay_usecs =
pdata->penirq_recheck_delay_usecs;
- ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync;
+ ts->gpio_hsync = devm_gpiod_get_optional(dev, "ti,hsync", GPIOD_IN);
+ if (IS_ERR(ts->gpio_hsync))
+ return PTR_ERR(ts->gpio_hsync);
snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev));
snprintf(ts->name, sizeof(ts->name), "ADS%d Touchscreen", ts->model);
diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h
index a04c1c34c34438..fa7c4f119023ea 100644
--- a/include/linux/spi/ads7846.h
+++ b/include/linux/spi/ads7846.h
@@ -38,7 +38,6 @@ struct ads7846_platform_data {
int gpio_pendown_debounce; /* platform specific debounce time for
* the gpio_pendown */
int (*get_pendown_state)(void);
- void (*wait_for_sync)(void);
bool wakeup;
unsigned long irq_flags;
};
diff --git a/include/linux/spi/pxa2xx_spi.h b/include/linux/spi/pxa2xx_spi.h
index ca2cd4e30ead7d..d166d4469fece9 100644
--- a/include/linux/spi/pxa2xx_spi.h
+++ b/include/linux/spi/pxa2xx_spi.h
@@ -6,6 +6,7 @@
#define __LINUX_SPI_PXA2XX_SPI_H
#include <linux/dmaengine.h>
+#include <linux/property.h>
#include <linux/types.h>
#include <linux/pxa2xx_ssp.h>
@@ -50,6 +51,7 @@ struct pxa2xx_spi_chip {
#include <linux/clk.h>
extern void pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_controller *info);
+void pxa2xx_set_spi_node(unsigned id, const struct property_entry *props);
#endif