From: marek.vasut@gmail.com (Marek Vasut)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 2/2] pxa/hx4700: Add Synaptics NavPoint (PXA27x SSP/SPI) driver
Date: Tue, 16 Aug 2011 11:13:22 +0200 [thread overview]
Message-ID: <201108161113.23119.marek.vasut@gmail.com> (raw)
In-Reply-To: <E1QrY5Y-00012n-7c@outmx01.plus.net>
On Thursday, August 11, 2011 06:26:30 PM Paul Parsons wrote:
> Add support for the Synaptics NavPoint connected to a PXA27x SSP port in
> SPI slave mode. The driver implements a simple navigation pad. The four
> raised dots are mapped to UP/DOWN/LEFT/RIGHT buttons and the centre of the
> touchpad is mapped to the ENTER button.
>
> Signed-off-by: Paul Parsons <lost.distance@yahoo.com>
> ---
>
> V2: Split into 2 parts for hx4700 specific code and navpoint driver. Added
> GPIO23_SSP1_SCLK_IN and GPIO102_NAVPOINT_PWR to mfp-pxa27x.h. Replaced
> power on/off callback with gpio number. Added msleep() to SSP port ready
> loop.
>
> diff -uprN clean-3.0.1/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
> linux-3.0.1/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h ---
> clean-3.0.1/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h 2011-08-05
> 05:59:21.000000000 +0100 +++
> linux-3.0.1/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h 2011-08-11
> 16:49:00.004450942 +0100 @@ -206,6 +206,7 @@
> #define GPIO113_I2S_SYSCLK MFP_CFG_OUT(GPIO113, AF1, DRIVE_LOW)
>
> /* SSP 1 */
> +#define GPIO23_SSP1_SCLK_IN MFP_CFG_IN(GPIO23, AF2)
> #define GPIO23_SSP1_SCLK MFP_CFG_OUT(GPIO23, AF2, DRIVE_LOW)
> #define GPIO29_SSP1_SCLK MFP_CFG_IN(GPIO29, AF3)
> #define GPIO27_SSP1_SYSCLK MFP_CFG_OUT(GPIO27, AF1, DRIVE_LOW)
> @@ -434,6 +435,9 @@
> #define GPIO112_nMSINS MFP_CFG_IN(GPIO112, AF2)
> #define GPIO32_MSSCLK MFP_CFG_OUT(GPIO32, AF1, DRIVE_LOW)
>
> +/* Touchpad Controller */
> +#define GPIO102_NAVPOINT_PWR MFP_CFG_OUT(GPIO102, AF0, DRIVE_LOW)
> +
> /* commonly used pin configurations */
> #define GPIOxx_LCD_16BPP \
> GPIO58_LCD_LDD_0, \
> diff -uprN clean-3.0.1/drivers/input/mouse/Kconfig
> linux-3.0.1/drivers/input/mouse/Kconfig ---
> clean-3.0.1/drivers/input/mouse/Kconfig 2011-08-05 05:59:21.000000000
> +0100 +++ linux-3.0.1/drivers/input/mouse/Kconfig 2011-08-11
> 16:49:00.004450942 +0100 @@ -322,4 +322,14 @@ config MOUSE_SYNAPTICS_I2C
> To compile this driver as a module, choose M here: the
> module will be called synaptics_i2c.
>
> +config MOUSE_NAVPOINT_PXA27x
> + bool "Synaptics NavPoint (PXA27x SSP/SPI)"
> + depends on PXA27x && PXA_SSP
> + help
> + This option enables support for the Synaptics NavPoint connected to
> + a PXA27x SSP port in SPI slave mode. The driver implements a simple
> + navigation pad. The four raised dots are mapped to UP/DOWN/LEFT/RIGHT
> + buttons and the centre of the touchpad is mapped to the ENTER button.
> + Say Y to enable the Synaptics NavPoint on the HP iPAQ hx4700.
> +
> endif
> diff -uprN clean-3.0.1/drivers/input/mouse/Makefile
> linux-3.0.1/drivers/input/mouse/Makefile ---
> clean-3.0.1/drivers/input/mouse/Makefile 2011-08-05 05:59:21.000000000
> +0100 +++ linux-3.0.1/drivers/input/mouse/Makefile 2011-08-11
> 16:49:00.004450942 +0100 @@ -19,6 +19,7 @@ obj-$(CONFIG_MOUSE_RISCPC) +=
> rpcmouse.
> obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o
> obj-$(CONFIG_MOUSE_SYNAPTICS_I2C) += synaptics_i2c.o
> obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o
> +obj-$(CONFIG_MOUSE_NAVPOINT_PXA27x) += navpoint.o
Keep the list sorted
>
> psmouse-objs := psmouse-base.o synaptics.o
>
> diff -uprN clean-3.0.1/drivers/input/mouse/navpoint.c
> linux-3.0.1/drivers/input/mouse/navpoint.c ---
> clean-3.0.1/drivers/input/mouse/navpoint.c 1970-01-01 01:00:00.000000000
> +0100 +++ linux-3.0.1/drivers/input/mouse/navpoint.c 2011-08-11
> 16:50:35.093084330 +0100 @@ -0,0 +1,317 @@
> +/*
> + * Copyright (C) 2011 Paul Parsons <lost.distance@yahoo.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/init.h>
> +#include <linux/platform_device.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/gpio.h>
> +#include <linux/input.h>
> +#include <linux/input/navpoint.h>
> +#include <linux/interrupt.h>
> +#include <linux/pxa2xx_ssp.h>
> +#include <linux/slab.h>
> +
> +/*
> + * Synaptics NavPoint (PXA27x SSP/SPI) driver.
> + */
> +
> +struct driver_data {
> + struct ssp_device *ssp;
> + int gpio;
> + struct input_dev *input;
> + int index;
> + uint8_t data[8];
> + int pressed; /* 1 = pressed, 0 = released */
> + unsigned code; /* Key code of the last key pressed */
> +};
Use tabs for alignment please.
> +
> +static const u32 sscr0 = 0
> + | SSCR0_TUM /* TIM = 1; No TUR interrupts */
> + | SSCR0_RIM /* RIM = 1; No ROR interrupts */
> + | SSCR0_SSE /* SSE = 1; SSP enabled */
> + | SSCR0_Motorola /* FRF = 0; Motorola SPI */
> + | SSCR0_DataSize(16) /* DSS = 15; Data size = 16-bit */
> + ;
> +static const u32 sscr1 = 0
> + | SSCR1_SCFR /* SCFR = 1; SSPSCLK only during transfers */
> + | SSCR1_SCLKDIR /* SCLKDIR = 1; Slave mode */
> + | SSCR1_SFRMDIR /* SFRMDIR = 1; Slave mode */
> + | SSCR1_RWOT /* RWOT = 1; Receive without transmit mode */
> + | SSCR1_RxTresh(1) /* RFT = 0; Receive FIFO threshold = 1 */
> + | SSCR1_SPH /* SPH = 1; SSPSCLK inactive 0.5 + 1 cycles */
> + | SSCR1_RIE /* RIE = 1; Receive FIFO interrupt enabled */
> + ;
> +static const u32 sssr = 0
> + | SSSR_BCE /* BCE = 1; Clear BCE */
> + | SSSR_TUR /* TUR = 1; Clear TUR */
> + | SSSR_EOC /* EOC = 1; Clear EOC */
> + | SSSR_TINT /* TINT = 1; Clear TINT */
> + | SSSR_PINT /* PINT = 1; Clear PINT */
> + | SSSR_ROR /* ROR = 1; Clear ROR */
> + ;
> +
> +/*
> + * MEP Query $22: Touchpad Coordinate Range Query is not supported by
> + * the NavPoint module, so sampled values provide the N/S/E/W limits.
> + */
> +
> +#define WEST 2416 /* 1/3 width */
> +#define EAST 3904 /* 2/3 width */
> +#define SOUTH 2480 /* 1/3 height */
> +#define NORTH 3424 /* 2/3 height */
Can't we calibrate this instead of having this hardcoded ? Or use sysfs
attributes / module params ?
> +
> +static void navpoint_packet(void *dev)
> +{
> + struct driver_data *drv_data;
> + int pressed;
> + unsigned x, y;
> + unsigned code;
> +
> + drv_data = dev;
> +
> + switch (drv_data->data[0]) {
> + case 0xff: /* Garbage (packet?) between reset and Hello packet */
> + case 0x00: /* Module 0, NULL packet */
> + break;
> + case 0x0e: /* Module 0, Absolute packet */
> + pressed = (drv_data->data[1] & 0x01);
> + if ((drv_data->pressed ^ pressed) == 0) /* No change */
> + break;
> + drv_data->pressed = pressed;
> + x = ((drv_data->data[2] & 0x1f) << 8) | drv_data->data[3];
> + y = ((drv_data->data[4] & 0x1f) << 8) | drv_data->data[5];
> + if (x < WEST)
> + code = KEY_LEFT;
> + else if (x > EAST)
> + code = KEY_RIGHT;
> + else if (y < SOUTH)
> + code = KEY_DOWN;
> + else if (y > NORTH)
> + code = KEY_UP;
> + else
> + code = KEY_ENTER;
> + if (pressed)
> + drv_data->code = code;
> + input_report_key(drv_data->input, drv_data->code, pressed);
> + input_sync(drv_data->input);
> + break;
> + case 0x19: /* Module 0, Hello packet */
> + if ((drv_data->data[1] & 0xf0) == 0x10)
> + break;
> + /* FALLTHROUGH */
> + default:
> + dev_warn(dev, "spurious packet: 0x%02x,0x%02x,...\n",
> + drv_data->data[0],
> + drv_data->data[1]);
> + break;
> + }
> +
> + drv_data->index = 0;
> +}
> +
> +static irqreturn_t navpoint_int(int irq, void *dev)
> +{
> + struct driver_data *drv_data;
> + struct ssp_device *ssp;
> + u32 status;
> + irqreturn_t ret;
> +
> + drv_data = dev;
> + ssp = drv_data->ssp;
> +
> + status = pxa_ssp_read_reg(ssp, SSSR);
> + ret = (status & (sssr | SSSR_RFS)) ? IRQ_HANDLED : IRQ_NONE;
Please avoid ternary ops.
> +
> + if (status & sssr) {
> + dev_warn(dev, "spurious interrupt: 0x%02x\n", status);
> + pxa_ssp_write_reg(ssp, SSSR, (status & sssr));
> + }
> +
> + while (status & SSSR_RNE) {
> + u32 data;
> +
> + data = pxa_ssp_read_reg(ssp, SSDR);
> + drv_data->data[drv_data->index + 0] = (data >> 8);
> + drv_data->data[drv_data->index + 1] = data;
> + drv_data->index += 2;
> + if ((drv_data->data[0] & 0x07) < drv_data->index)
Maybe document magic numbers?
> + navpoint_packet(dev);
> + status = pxa_ssp_read_reg(ssp, SSSR);
> + }
> +
> + return ret;
> +}
> +
> +#ifdef CONFIG_SUSPEND
> +int navpoint_suspend(struct device *dev)
> +{
> + struct driver_data *drv_data;
> + struct ssp_device *ssp;
> +
> + drv_data = dev_get_drvdata(dev);
> + ssp = drv_data->ssp;
> +
> + if (drv_data->gpio)
> + gpio_set_value(drv_data->gpio, 0);
> +
> + pxa_ssp_write_reg(ssp, SSCR0, 0);
> +
> + clk_disable(ssp->clk);
> +
> + return 0;
> +}
> +
> +int navpoint_resume(struct device *dev)
> +{
> + struct driver_data *drv_data;
> + struct ssp_device *ssp;
> +
> + drv_data = dev_get_drvdata(dev);
> + ssp = drv_data->ssp;
> +
> + clk_enable(ssp->clk);
> +
> + pxa_ssp_write_reg(ssp, SSCR1, sscr1);
> + pxa_ssp_write_reg(ssp, SSSR, sssr);
> + pxa_ssp_write_reg(ssp, SSTO, 0);
> + pxa_ssp_write_reg(ssp, SSCR0, sscr0); /* SSCR0_SSE written last */
> +
> + if (drv_data->gpio)
> + gpio_set_value(drv_data->gpio, 1);
> +
> + /* Wait until SSP port is ready for slave clock operations */
> + while (pxa_ssp_read_reg(ssp, SSSR) & SSSR_CSS)
> + msleep(1);
> +
> + return 0;
> +}
> +
> +static const struct dev_pm_ops navpoint_pm_ops = {
> + .suspend = navpoint_suspend,
> + .resume = navpoint_resume,
> +};
> +#endif
> +
> +static int __devinit navpoint_probe(struct platform_device *pdev)
> +{
> + struct navpoint_platform_data *pdata = pdev->dev.platform_data;
> + int ret;
> + struct driver_data *drv_data;
> + struct ssp_device *ssp;
> + struct input_dev *input;
> +
> + drv_data = kzalloc(sizeof(struct driver_data), GFP_KERNEL);
> + if (!drv_data) {
> + ret = -ENOMEM;
> + goto ret0;
> + }
> +
> + ssp = pxa_ssp_request(pdata->port, pdev->name);
> + if (!ssp) {
> + ret = -ENODEV;
> + goto ret1;
> + }
> +
> + ret = request_irq(ssp->irq, navpoint_int, 0, pdev->name, drv_data);
> + if (ret)
> + goto ret2;
> +
> + input = input_allocate_device();
> + if (!input) {
> + ret = -ENOMEM;
> + goto ret3;
> + }
> + input->name = pdev->name;
> + __set_bit(EV_KEY, input->evbit);
> + __set_bit(KEY_ENTER, input->keybit);
> + __set_bit(KEY_UP, input->keybit);
> + __set_bit(KEY_LEFT, input->keybit);
> + __set_bit(KEY_RIGHT, input->keybit);
> + __set_bit(KEY_DOWN, input->keybit);
> + input->dev.parent = &pdev->dev;
> + ret = input_register_device(input);
> + if (ret)
> + goto ret4;
> +
> + drv_data->ssp = ssp;
> + drv_data->gpio = pdata->gpio;
> + drv_data->input = input;
> +
> + platform_set_drvdata(pdev, drv_data);
> +
> + (void) navpoint_resume(&pdev->dev);
> +
> + dev_info(&pdev->dev, "ssp%d, irq %d\n", pdata->port, ssp->irq);
> +
> + return 0;
> +
> +ret4:
> + input_free_device(input);
> +ret3:
> + free_irq(ssp->irq, drv_data);
> +ret2:
> + pxa_ssp_free(ssp);
> +ret1:
> + kfree(drv_data);
> +ret0:
> + return ret;
> +}
> +
> +static int __devexit navpoint_remove(struct platform_device *pdev)
> +{
> + struct driver_data *drv_data;
> + struct ssp_device *ssp;
> + struct input_dev *input;
> +
> + drv_data = platform_get_drvdata(pdev);
> + ssp = drv_data->ssp;
> + input = drv_data->input;
> +
> + (void) navpoint_suspend(&pdev->dev);
> +
> + input_unregister_device(input);
> +
> + free_irq(ssp->irq, drv_data);
> +
> + pxa_ssp_free(ssp);
> +
> + kfree(drv_data);
> +
> + return 0;
> +}
> +
> +static struct platform_driver navpoint_driver = {
> + .probe = navpoint_probe,
> + .remove = __devexit_p(navpoint_remove),
> + .driver = {
> + .name = "navpoint",
> + .owner = THIS_MODULE,
> +#ifdef CONFIG_SUSPEND
> + .pm = &navpoint_pm_ops,
> +#endif
> + },
> +};
> +
> +static int __init navpoint_init(void)
> +{
> + return platform_driver_register(&navpoint_driver);
> +}
> +
> +static void __exit navpoint_exit(void)
> +{
> + platform_driver_unregister(&navpoint_driver);
> +}
> +
> +module_init(navpoint_init);
> +module_exit(navpoint_exit);
> +
> +MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>");
> +MODULE_DESCRIPTION("Synaptics NavPoint (PXA27x SSP/SPI) driver");
> +MODULE_LICENSE("GPL");
Isn't the original authors credit missing here and/or in the header?
> diff -uprN clean-3.0.1/include/linux/input/navpoint.h
> linux-3.0.1/include/linux/input/navpoint.h ---
> clean-3.0.1/include/linux/input/navpoint.h 1970-01-01 01:00:00.000000000
> +0100 +++ linux-3.0.1/include/linux/input/navpoint.h 2011-08-11
> 16:50:50.761188696 +0100 @@ -0,0 +1,12 @@
> +/*
> + * Copyright (C) 2011 Paul Parsons <lost.distance@yahoo.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.
> + */
> +
> +struct navpoint_platform_data {
> + int port; /* PXA SSP port for pxa_ssp_request() */
> + int gpio; /* GPIO for power on/off */
> +};
Cheers!
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2011-08-16 9:13 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-11 16:26 [PATCH v2 2/2] pxa/hx4700: Add Synaptics NavPoint (PXA27x SSP/SPI) driver Paul Parsons
2011-08-16 9:13 ` Marek Vasut [this message]
2011-08-16 14:21 ` Paul Parsons
2011-08-16 15:13 ` Marek Vasut
2011-08-17 0:20 ` Paul Parsons
-- strict thread matches above, loose matches on Subject: below --
2011-08-14 10:31 Paul Parsons
2011-08-15 8:01 ` Eric Miao
2011-08-15 8:01 ` Eric Miao
2011-08-15 9:49 ` Paul Parsons
2011-08-15 9:49 ` Paul Parsons
2011-08-15 9:53 ` Eric Miao
2011-08-15 9:53 ` Eric Miao
2011-08-16 7:56 ` Igor Grinberg
2011-08-16 7:56 ` Igor Grinberg
2011-08-16 11:54 ` Paul Parsons
2011-08-16 11:54 ` Paul Parsons
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201108161113.23119.marek.vasut@gmail.com \
--to=marek.vasut@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.