History

Input: navpoint - remove driver

This driver does not use the SPI core as it should, instead tampering with the SSP registers manually. Refactoring the driver is almost certainly not worth it as the hardware seems to have been designed for and used only in the HP iPAQ hx4700 removed more than a year ago in d6df7df7ae5a ("ARM: pxa: remove unused board files"), so let's remove it.

Duje Mihanović committed 2 years ago

Commit f0eb58d1 parent 52c4e594 files · +0 −371Browse files

Unified · Split

4 files
  1. drivers/input/mouse/Kconfig +0 −12
  2. drivers/input/mouse/Makefile +0 −1
  3. drivers/input/mouse/navpoint.c +0 −350
  4. include/linux/input/navpoint.h +0 −8
drivers/input/mouse/Kconfig+0−12
@@ -439,16 +439,4 @@ config MOUSE_SYNAPTICS_USB · 438 unmodified lines
439 To compile this driver as a module, choose M here: the439 To compile this driver as a module, choose M here: the
440 module will be called synaptics_usb.440 module will be called synaptics_usb.
441 441
442config MOUSE_NAVPOINT_PXA27x
443 tristate "Synaptics NavPoint (PXA27x SSP/SPI)"
444 depends on PXA27x && PXA_SSP
445 help
446 This driver adds support for the Synaptics NavPoint touchpad connected
447 to a PXA27x SSP port in SPI slave mode. The device emulates a mouse;
448 a tap or tap-and-a-half drag gesture emulates the left mouse button.
449 For example, use the xf86-input-evdev driver for an X pointing device.
450
451 To compile this driver as a module, choose M here: the
452 module will be called navpoint.
453
454endif442endif
drivers/input/mouse/Makefile+0−1
@@ -15,7 +15,6 @@ obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o · 14 unmodified lines
15obj-$(CONFIG_MOUSE_INPORT) += inport.o15obj-$(CONFIG_MOUSE_INPORT) += inport.o
16obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o16obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o
17obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o17obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o
18obj-$(CONFIG_MOUSE_NAVPOINT_PXA27x) += navpoint.o
19obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o18obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o
20obj-$(CONFIG_MOUSE_PS2) += psmouse.o19obj-$(CONFIG_MOUSE_PS2) += psmouse.o
21obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o20obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o
drivers/input/mouse/navpoint.c+0−350
@@ -1,350 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Synaptics NavPoint (PXA27x SSP/SPI) driver.
4 *
5 * Copyright (C) 2012 Paul Parsons <lost.distance@yahoo.com>
6 */
7
8#include <linux/kernel.h>
9#include <linux/module.h>
10#include <linux/platform_device.h>
11#include <linux/clk.h>
12#include <linux/delay.h>
13#include <linux/gpio/consumer.h>
14#include <linux/input.h>
15#include <linux/input/navpoint.h>
16#include <linux/interrupt.h>
17#include <linux/mutex.h>
18#include <linux/pxa2xx_ssp.h>
19#include <linux/slab.h>
20
21/*
22 * Synaptics Modular Embedded Protocol: Module Packet Format.
23 * Module header byte 2:0 = Length (# bytes that follow)
24 * Module header byte 4:3 = Control
25 * Module header byte 7:5 = Module Address
26 */
27#define HEADER_LENGTH(byte) ((byte) & 0x07)
28#define HEADER_CONTROL(byte) (((byte) >> 3) & 0x03)
29#define HEADER_ADDRESS(byte) ((byte) >> 5)
30
31struct navpoint {
32 struct ssp_device *ssp;
33 struct input_dev *input;
34 struct device *dev;
35 struct gpio_desc *gpiod;
36 int index;
37 u8 data[1 + HEADER_LENGTH(0xff)];
38};
39
40/*
41 * Initialization values for SSCR0_x, SSCR1_x, SSSR_x.
42 */
43static const u32 sscr0 = 0
44 | SSCR0_TUM /* TIM = 1; No TUR interrupts */
45 | SSCR0_RIM /* RIM = 1; No ROR interrupts */
46 | SSCR0_SSE /* SSE = 1; SSP enabled */
47 | SSCR0_Motorola /* FRF = 0; Motorola SPI */
48 | SSCR0_DataSize(16) /* DSS = 15; Data size = 16-bit */
49 ;
50static const u32 sscr1 = 0
51 | SSCR1_SCFR /* SCFR = 1; SSPSCLK only during transfers */
52 | SSCR1_SCLKDIR /* SCLKDIR = 1; Slave mode */
53 | SSCR1_SFRMDIR /* SFRMDIR = 1; Slave mode */
54 | SSCR1_RWOT /* RWOT = 1; Receive without transmit mode */
55 | SSCR1_RxTresh(1) /* RFT = 0; Receive FIFO threshold = 1 */
56 | SSCR1_SPH /* SPH = 1; SSPSCLK inactive 0.5 + 1 cycles */
57 | SSCR1_RIE /* RIE = 1; Receive FIFO interrupt enabled */
58 ;
59static const u32 sssr = 0
60 | SSSR_BCE /* BCE = 1; Clear BCE */
61 | SSSR_TUR /* TUR = 1; Clear TUR */
62 | SSSR_EOC /* EOC = 1; Clear EOC */
63 | SSSR_TINT /* TINT = 1; Clear TINT */
64 | SSSR_PINT /* PINT = 1; Clear PINT */
65 | SSSR_ROR /* ROR = 1; Clear ROR */
66 ;
67
68/*
69 * MEP Query $22: Touchpad Coordinate Range Query is not supported by
70 * the NavPoint module, so sampled values provide the default limits.
71 */
72#define NAVPOINT_X_MIN 1278
73#define NAVPOINT_X_MAX 5340
74#define NAVPOINT_Y_MIN 1572
75#define NAVPOINT_Y_MAX 4396
76#define NAVPOINT_PRESSURE_MIN 0
77#define NAVPOINT_PRESSURE_MAX 255
78
79static void navpoint_packet(struct navpoint *navpoint)
80{
81 int finger;
82 int gesture;
83 int x, y, z;
84
85 switch (navpoint->data[0]) {
86 case 0xff: /* Garbage (packet?) between reset and Hello packet */
87 case 0x00: /* Module 0, NULL packet */
88 break;
89
90 case 0x0e: /* Module 0, Absolute packet */
91 finger = (navpoint->data[1] & 0x01);
92 gesture = (navpoint->data[1] & 0x02);
93 x = ((navpoint->data[2] & 0x1f) << 8) | navpoint->data[3];
94 y = ((navpoint->data[4] & 0x1f) << 8) | navpoint->data[5];
95 z = navpoint->data[6];
96 input_report_key(navpoint->input, BTN_TOUCH, finger);
97 input_report_abs(navpoint->input, ABS_X, x);
98 input_report_abs(navpoint->input, ABS_Y, y);
99 input_report_abs(navpoint->input, ABS_PRESSURE, z);
100 input_report_key(navpoint->input, BTN_TOOL_FINGER, finger);
101 input_report_key(navpoint->input, BTN_LEFT, gesture);
102 input_sync(navpoint->input);
103 break;
104
105 case 0x19: /* Module 0, Hello packet */
106 if ((navpoint->data[1] & 0xf0) == 0x10)
107 break;
108 fallthrough;
109 default:
110 dev_warn(navpoint->dev,
111 "spurious packet: data=0x%02x,0x%02x,...\n",
112 navpoint->data[0], navpoint->data[1]);
113 break;
114 }
115}
116
117static irqreturn_t navpoint_irq(int irq, void *dev_id)
118{
119 struct navpoint *navpoint = dev_id;
120 struct ssp_device *ssp = navpoint->ssp;
121 irqreturn_t ret = IRQ_NONE;
122 u32 status;
123
124 status = pxa_ssp_read_reg(ssp, SSSR);
125 if (status & sssr) {
126 dev_warn(navpoint->dev,
127 "unexpected interrupt: status=0x%08x\n", status);
128 pxa_ssp_write_reg(ssp, SSSR, (status & sssr));
129 ret = IRQ_HANDLED;
130 }
131
132 while (status & SSSR_RNE) {
133 u32 data;
134
135 data = pxa_ssp_read_reg(ssp, SSDR);
136 navpoint->data[navpoint->index + 0] = (data >> 8);
137 navpoint->data[navpoint->index + 1] = data;
138 navpoint->index += 2;
139 if (HEADER_LENGTH(navpoint->data[0]) < navpoint->index) {
140 navpoint_packet(navpoint);
141 navpoint->index = 0;
142 }
143 status = pxa_ssp_read_reg(ssp, SSSR);
144 ret = IRQ_HANDLED;
145 }
146
147 return ret;
148}
149
150static void navpoint_up(struct navpoint *navpoint)
151{
152 struct ssp_device *ssp = navpoint->ssp;
153 int timeout;
154
155 clk_prepare_enable(ssp->clk);
156
157 pxa_ssp_write_reg(ssp, SSCR1, sscr1);
158 pxa_ssp_write_reg(ssp, SSSR, sssr);
159 pxa_ssp_write_reg(ssp, SSTO, 0);
160 pxa_ssp_write_reg(ssp, SSCR0, sscr0); /* SSCR0_SSE written last */
161
162 /* Wait until SSP port is ready for slave clock operations */
163 for (timeout = 100; timeout != 0; --timeout) {
164 if (!(pxa_ssp_read_reg(ssp, SSSR) & SSSR_CSS))
165 break;
166 msleep(1);
167 }
168
169 if (timeout == 0)
170 dev_err(navpoint->dev,
171 "timeout waiting for SSSR[CSS] to clear\n");
172
173 gpiod_set_value(navpoint->gpiod, 1);
174}
175
176static void navpoint_down(struct navpoint *navpoint)
177{
178 struct ssp_device *ssp = navpoint->ssp;
179
180 gpiod_set_value(navpoint->gpiod, 0);
181
182 pxa_ssp_write_reg(ssp, SSCR0, 0);
183
184 clk_disable_unprepare(ssp->clk);
185}
186
187static int navpoint_open(struct input_dev *input)
188{
189 struct navpoint *navpoint = input_get_drvdata(input);
190
191 navpoint_up(navpoint);
192
193 return 0;
194}
195
196static void navpoint_close(struct input_dev *input)
197{
198 struct navpoint *navpoint = input_get_drvdata(input);
199
200 navpoint_down(navpoint);
201}
202
203static int navpoint_probe(struct platform_device *pdev)
204{
205 const struct navpoint_platform_data *pdata =
206 dev_get_platdata(&pdev->dev);
207 struct ssp_device *ssp;
208 struct input_dev *input;
209 struct navpoint *navpoint;
210 int error;
211
212 if (!pdata) {
213 dev_err(&pdev->dev, "no platform data\n");
214 return -EINVAL;
215 }
216
217 ssp = pxa_ssp_request(pdata->port, pdev->name);
218 if (!ssp)
219 return -ENODEV;
220
221 /* HaRET does not disable devices before jumping into Linux */
222 if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
223 pxa_ssp_write_reg(ssp, SSCR0, 0);
224 dev_warn(&pdev->dev, "ssp%d already enabled\n", pdata->port);
225 }
226
227 navpoint = kzalloc(sizeof(*navpoint), GFP_KERNEL);
228 input = input_allocate_device();
229 if (!navpoint || !input) {
230 error = -ENOMEM;
231 goto err_free_mem;
232 }
233
234 navpoint->gpiod = gpiod_get_optional(&pdev->dev,
235 NULL, GPIOD_OUT_LOW);
236 if (IS_ERR(navpoint->gpiod)) {
237 error = PTR_ERR(navpoint->gpiod);
238 dev_err(&pdev->dev, "error getting GPIO\n");
239 goto err_free_mem;
240 }
241 gpiod_set_consumer_name(navpoint->gpiod, "SYNAPTICS_ON");
242
243 navpoint->ssp = ssp;
244 navpoint->input = input;
245 navpoint->dev = &pdev->dev;
246
247 input->name = pdev->name;
248 input->dev.parent = &pdev->dev;
249
250 __set_bit(EV_KEY, input->evbit);
251 __set_bit(EV_ABS, input->evbit);
252 __set_bit(BTN_LEFT, input->keybit);
253 __set_bit(BTN_TOUCH, input->keybit);
254 __set_bit(BTN_TOOL_FINGER, input->keybit);
255
256 input_set_abs_params(input, ABS_X,
257 NAVPOINT_X_MIN, NAVPOINT_X_MAX, 0, 0);
258 input_set_abs_params(input, ABS_Y,
259 NAVPOINT_Y_MIN, NAVPOINT_Y_MAX, 0, 0);
260 input_set_abs_params(input, ABS_PRESSURE,
261 NAVPOINT_PRESSURE_MIN, NAVPOINT_PRESSURE_MAX,
262 0, 0);
263
264 input->open = navpoint_open;
265 input->close = navpoint_close;
266
267 input_set_drvdata(input, navpoint);
268
269 error = request_irq(ssp->irq, navpoint_irq, 0, pdev->name, navpoint);
270 if (error)
271 goto err_free_mem;
272
273 error = input_register_device(input);
274 if (error)
275 goto err_free_irq;
276
277 platform_set_drvdata(pdev, navpoint);
278 dev_dbg(&pdev->dev, "ssp%d, irq %d\n", pdata->port, ssp->irq);
279
280 return 0;
281
282err_free_irq:
283 free_irq(ssp->irq, navpoint);
284err_free_mem:
285 input_free_device(input);
286 kfree(navpoint);
287 pxa_ssp_free(ssp);
288
289 return error;
290}
291
292static void navpoint_remove(struct platform_device *pdev)
293{
294 struct navpoint *navpoint = platform_get_drvdata(pdev);
295 struct ssp_device *ssp = navpoint->ssp;
296
297 free_irq(ssp->irq, navpoint);
298
299 input_unregister_device(navpoint->input);
300 kfree(navpoint);
301
302 pxa_ssp_free(ssp);
303}
304
305static int navpoint_suspend(struct device *dev)
306{
307 struct platform_device *pdev = to_platform_device(dev);
308 struct navpoint *navpoint = platform_get_drvdata(pdev);
309 struct input_dev *input = navpoint->input;
310
311 mutex_lock(&input->mutex);
312 if (input_device_enabled(input))
313 navpoint_down(navpoint);
314 mutex_unlock(&input->mutex);
315
316 return 0;
317}
318
319static int navpoint_resume(struct device *dev)
320{
321 struct platform_device *pdev = to_platform_device(dev);
322 struct navpoint *navpoint = platform_get_drvdata(pdev);
323 struct input_dev *input = navpoint->input;
324
325 mutex_lock(&input->mutex);
326 if (input_device_enabled(input))
327 navpoint_up(navpoint);
328 mutex_unlock(&input->mutex);
329
330 return 0;
331}
332
333static DEFINE_SIMPLE_DEV_PM_OPS(navpoint_pm_ops,
334 navpoint_suspend, navpoint_resume);
335
336static struct platform_driver navpoint_driver = {
337 .probe = navpoint_probe,
338 .remove_new = navpoint_remove,
339 .driver = {
340 .name = "navpoint",
341 .pm = pm_sleep_ptr(&navpoint_pm_ops),
342 },
343};
344
345module_platform_driver(navpoint_driver);
346
347MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>");
348MODULE_DESCRIPTION("Synaptics NavPoint (PXA27x SSP/SPI) driver");
349MODULE_LICENSE("GPL");
350MODULE_ALIAS("platform:navpoint");
include/linux/input/navpoint.h+0−8
@@ -1,8 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2012 Paul Parsons <lost.distance@yahoo.com>
4 */
5
6struct navpoint_platform_data {
7 int port; /* PXA SSP port for pxa_ssp_request() */
8};