1 /*
2  * Copyright 2024 Google LLC
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT pixart_pmw3610
8 
9 #include <stdint.h>
10 #include <stdlib.h>
11 
12 #include <zephyr/device.h>
13 #include <zephyr/drivers/gpio.h>
14 #include <zephyr/drivers/spi.h>
15 #include <zephyr/input/input.h>
16 #include <zephyr/input/input_pmw3610.h>
17 #include <zephyr/kernel.h>
18 #include <zephyr/logging/log.h>
19 #include <zephyr/pm/device.h>
20 #include <zephyr/pm/device_runtime.h>
21 #include <zephyr/sys/byteorder.h>
22 #include <zephyr/sys/util.h>
23 
24 LOG_MODULE_REGISTER(input_pmw3610, CONFIG_INPUT_LOG_LEVEL);
25 
26 /* Page 0 */
27 #define PMW3610_PROD_ID		0x00
28 #define PMW3610_REV_ID		0x01
29 #define PMW3610_MOTION		0x02
30 #define PMW3610_DELTA_X_L	0x03
31 #define PMW3610_DELTA_Y_L	0x04
32 #define PMW3610_DELTA_XY_H	0x05
33 #define PMW3610_PERFORMANCE	0x11
34 #define PMW3610_BURST_READ	0x12
35 #define PMW3610_RUN_DOWNSHIFT	0x1b
36 #define PMW3610_REST1_RATE	0x1c
37 #define PMW3610_REST1_DOWNSHIFT	0x1d
38 #define PMW3610_OBSERVATION1	0x2d
39 #define PMW3610_SMART_MODE	0x32
40 #define PMW3610_POWER_UP_RESET	0x3a
41 #define PMW3610_SHUTDOWN	0x3b
42 #define PMW3610_SPI_CLK_ON_REQ	0x41
43 #define PWM3610_SPI_PAGE0	0x7f
44 
45 /* Page 1 */
46 #define PMW3610_RES_STEP	0x05
47 #define PWM3610_SPI_PAGE1	0x7f
48 
49 /* Burst register offsets */
50 #define BURST_MOTION		0
51 #define BURST_DELTA_X_L		1
52 #define BURST_DELTA_Y_L		2
53 #define BURST_DELTA_XY_H	3
54 #define BURST_SQUAL		4
55 #define BURST_SHUTTER_HI	5
56 #define BURST_SHUTTER_LO	6
57 
58 #define BURST_DATA_LEN_NORMAL	(BURST_DELTA_XY_H + 1)
59 #define BURST_DATA_LEN_SMART	(BURST_SHUTTER_LO + 1)
60 #define BURST_DATA_LEN_MAX	MAX(BURST_DATA_LEN_NORMAL, BURST_DATA_LEN_SMART)
61 
62 /* Init sequence values */
63 #define OBSERVATION1_INIT_MASK 0x0f
64 #define PERFORMANCE_INIT 0x0d
65 #define RUN_DOWNSHIFT_INIT 0x04
66 #define REST1_RATE_INIT 0x04
67 #define REST1_DOWNSHIFT_INIT 0x0f
68 
69 #define PRODUCT_ID_PMW3610 0x3e
70 #define SPI_WRITE BIT(7)
71 #define MOTION_STATUS_MOTION BIT(7)
72 #define SPI_CLOCK_ON_REQ_ON 0xba
73 #define SPI_CLOCK_ON_REQ_OFF 0xb5
74 #define RES_STEP_INV_X_BIT 6
75 #define RES_STEP_INV_Y_BIT 5
76 #define RES_STEP_RES_MASK 0x1f
77 #define PERFORMANCE_FMODE_MASK (0x0f << 4)
78 #define PERFORMANCE_FMODE_NORMAL (0x00 << 4)
79 #define PERFORMANCE_FMODE_FORCE_AWAKE (0x0f << 4)
80 #define POWER_UP_WAKEUP 0x96
81 #define SHUTDOWN_ENABLE 0xe7
82 #define SPI_PAGE0_1 0xff
83 #define SPI_PAGE1_0 0x00
84 #define SHUTTER_SMART_THRESHOLD 45
85 #define SMART_MODE_ENABLE 0x00
86 #define SMART_MODE_DISABLE 0x80
87 
88 #define PMW3610_DATA_SIZE_BITS 12
89 
90 #define RESET_DELAY_MS 10
91 #define INIT_OBSERVATION_DELAY_MS 10
92 #define CLOCK_ON_DELAY_US 300
93 
94 #define RES_STEP 200
95 #define RES_MIN 200
96 #define RES_MAX 3200
97 
98 struct pmw3610_config {
99 	struct spi_dt_spec spi;
100 	struct gpio_dt_spec motion_gpio;
101 	struct gpio_dt_spec reset_gpio;
102 	uint16_t axis_x;
103 	uint16_t axis_y;
104 	int16_t res_cpi;
105 	bool invert_x;
106 	bool invert_y;
107 	bool force_awake;
108 	bool smart_mode;
109 };
110 
111 struct pmw3610_data {
112 	const struct device *dev;
113 	struct k_work motion_work;
114 	struct gpio_callback motion_cb;
115 	bool smart_flag;
116 };
117 
pmw3610_read(const struct device * dev,uint8_t addr,uint8_t * value,uint8_t len)118 static int pmw3610_read(const struct device *dev,
119 			uint8_t addr, uint8_t *value, uint8_t len)
120 {
121 	const struct pmw3610_config *cfg = dev->config;
122 
123 	const struct spi_buf tx_buf = {
124 		.buf = &addr,
125 		.len = sizeof(addr),
126 	};
127 	const struct spi_buf_set tx = {
128 		.buffers = &tx_buf,
129 		.count = 1,
130 	};
131 
132 	struct spi_buf rx_buf[] = {
133 		{
134 			.buf = NULL,
135 			.len = sizeof(addr),
136 		},
137 		{
138 			.buf = value,
139 			.len = len,
140 		},
141 	};
142 	const struct spi_buf_set rx = {
143 		.buffers = rx_buf,
144 		.count = ARRAY_SIZE(rx_buf),
145 	};
146 
147 	return spi_transceive_dt(&cfg->spi, &tx, &rx);
148 }
149 
pmw3610_read_reg(const struct device * dev,uint8_t addr,uint8_t * value)150 static int pmw3610_read_reg(const struct device *dev, uint8_t addr, uint8_t *value)
151 {
152 	return pmw3610_read(dev, addr, value, 1);
153 }
154 
pmw3610_write_reg(const struct device * dev,uint8_t addr,uint8_t value)155 static int pmw3610_write_reg(const struct device *dev, uint8_t addr, uint8_t value)
156 {
157 	const struct pmw3610_config *cfg = dev->config;
158 
159 	uint8_t write_buf[] = {addr | SPI_WRITE, value};
160 	const struct spi_buf tx_buf = {
161 		.buf = write_buf,
162 		.len = sizeof(write_buf),
163 	};
164 	const struct spi_buf_set tx = {
165 		.buffers = &tx_buf,
166 		.count = 1,
167 	};
168 
169 	return spi_write_dt(&cfg->spi, &tx);
170 }
171 
pmw3610_spi_clk_on(const struct device * dev)172 static int pmw3610_spi_clk_on(const struct device *dev)
173 {
174 	int ret;
175 
176 	ret = pmw3610_write_reg(dev, PMW3610_SPI_CLK_ON_REQ, SPI_CLOCK_ON_REQ_ON);
177 
178 	k_sleep(K_USEC(CLOCK_ON_DELAY_US));
179 
180 	return ret;
181 }
182 
pmw3610_spi_clk_off(const struct device * dev)183 static int pmw3610_spi_clk_off(const struct device *dev)
184 {
185 	return pmw3610_write_reg(dev, PMW3610_SPI_CLK_ON_REQ, SPI_CLOCK_ON_REQ_OFF);
186 }
187 
pmw3610_motion_work_handler(struct k_work * work)188 static void pmw3610_motion_work_handler(struct k_work *work)
189 {
190 	struct pmw3610_data *data = CONTAINER_OF(
191 			work, struct pmw3610_data, motion_work);
192 	const struct device *dev = data->dev;
193 	const struct pmw3610_config *cfg = dev->config;
194 	uint8_t burst_data[BURST_DATA_LEN_MAX];
195 	uint8_t burst_data_len;
196 	int32_t x, y;
197 	int ret;
198 
199 	if (cfg->smart_mode) {
200 		burst_data_len = BURST_DATA_LEN_SMART;
201 	} else {
202 		burst_data_len = BURST_DATA_LEN_NORMAL;
203 	}
204 
205 	ret = pmw3610_read(dev, PMW3610_BURST_READ, burst_data, burst_data_len);
206 	if (ret < 0) {
207 		return;
208 	}
209 
210 	if ((burst_data[BURST_MOTION] & MOTION_STATUS_MOTION) == 0x00) {
211 		return;
212 	}
213 
214 	x = ((burst_data[BURST_DELTA_XY_H] << 4) & 0xf00) | burst_data[BURST_DELTA_X_L];
215 	y = ((burst_data[BURST_DELTA_XY_H] << 8) & 0xf00) | burst_data[BURST_DELTA_Y_L];
216 
217 	x = sign_extend(x, PMW3610_DATA_SIZE_BITS - 1);
218 	y = sign_extend(y, PMW3610_DATA_SIZE_BITS - 1);
219 
220 	input_report_rel(data->dev, cfg->axis_x, x, false, K_FOREVER);
221 	input_report_rel(data->dev, cfg->axis_y, y, true, K_FOREVER);
222 
223 	if (cfg->smart_mode) {
224 		uint16_t shutter_val = sys_get_be16(&burst_data[BURST_SHUTTER_HI]);
225 
226 		if (data->smart_flag && shutter_val < SHUTTER_SMART_THRESHOLD) {
227 			pmw3610_spi_clk_on(dev);
228 
229 			ret = pmw3610_write_reg(dev, PMW3610_SMART_MODE, SMART_MODE_ENABLE);
230 			if (ret < 0) {
231 				return;
232 			}
233 
234 			pmw3610_spi_clk_off(dev);
235 
236 			data->smart_flag = false;
237 		} else if (!data->smart_flag && shutter_val > SHUTTER_SMART_THRESHOLD) {
238 			pmw3610_spi_clk_on(dev);
239 
240 			ret = pmw3610_write_reg(dev, PMW3610_SMART_MODE, SMART_MODE_DISABLE);
241 			if (ret < 0) {
242 				return;
243 			}
244 
245 			pmw3610_spi_clk_off(dev);
246 
247 			data->smart_flag = true;
248 		}
249 	}
250 }
251 
pmw3610_motion_handler(const struct device * gpio_dev,struct gpio_callback * cb,uint32_t pins)252 static void pmw3610_motion_handler(const struct device *gpio_dev,
253 				   struct gpio_callback *cb,
254 				   uint32_t pins)
255 {
256 	struct pmw3610_data *data = CONTAINER_OF(
257 			cb, struct pmw3610_data, motion_cb);
258 
259 	k_work_submit(&data->motion_work);
260 }
261 
pmw3610_set_resolution(const struct device * dev,uint16_t res_cpi)262 int pmw3610_set_resolution(const struct device *dev, uint16_t res_cpi)
263 {
264 	uint8_t val;
265 	int ret;
266 
267 	if (!IN_RANGE(res_cpi, RES_MIN, RES_MAX)) {
268 		LOG_ERR("res_cpi out of range: %d", res_cpi);
269 		return -EINVAL;
270 	}
271 
272 	ret = pmw3610_spi_clk_on(dev);
273 	if (ret < 0) {
274 		return ret;
275 	}
276 
277 	ret = pmw3610_write_reg(dev, PWM3610_SPI_PAGE0, SPI_PAGE0_1);
278 	if (ret < 0) {
279 		return ret;
280 	}
281 
282 	ret = pmw3610_read_reg(dev, PMW3610_RES_STEP, &val);
283 	if (ret < 0) {
284 		return ret;
285 	}
286 
287 	val &= ~RES_STEP_RES_MASK;
288 	val |= res_cpi / RES_STEP;
289 
290 	ret = pmw3610_write_reg(dev, PMW3610_RES_STEP, val);
291 	if (ret < 0) {
292 		return ret;
293 	}
294 
295 	ret = pmw3610_write_reg(dev, PWM3610_SPI_PAGE1, SPI_PAGE1_0);
296 	if (ret < 0) {
297 		return ret;
298 	}
299 
300 	ret = pmw3610_spi_clk_off(dev);
301 	if (ret < 0) {
302 		return ret;
303 	}
304 
305 	return 0;
306 }
307 
pmw3610_force_awake(const struct device * dev,bool enable)308 int pmw3610_force_awake(const struct device *dev, bool enable)
309 {
310 	uint8_t val;
311 	int ret;
312 
313 	ret = pmw3610_read_reg(dev, PMW3610_PERFORMANCE, &val);
314 	if (ret < 0) {
315 		return ret;
316 	}
317 
318 	val &= ~PERFORMANCE_FMODE_MASK;
319 	if (enable) {
320 		val |= PERFORMANCE_FMODE_FORCE_AWAKE;
321 	} else {
322 		val |= PERFORMANCE_FMODE_NORMAL;
323 	}
324 
325 	ret = pmw3610_spi_clk_on(dev);
326 	if (ret < 0) {
327 		return ret;
328 	}
329 
330 	ret = pmw3610_write_reg(dev, PMW3610_PERFORMANCE, val);
331 	if (ret < 0) {
332 		return ret;
333 	}
334 
335 	ret = pmw3610_spi_clk_off(dev);
336 	if (ret < 0) {
337 		return ret;
338 	}
339 
340 	return 0;
341 }
342 
pmw3610_configure(const struct device * dev)343 static int pmw3610_configure(const struct device *dev)
344 {
345 	const struct pmw3610_config *cfg = dev->config;
346 	uint8_t val;
347 	int ret;
348 
349 	if (cfg->reset_gpio.port != NULL) {
350 		if (!gpio_is_ready_dt(&cfg->reset_gpio)) {
351 			LOG_ERR("%s is not ready", cfg->reset_gpio.port->name);
352 			return -ENODEV;
353 		}
354 
355 		ret = gpio_pin_configure_dt(&cfg->reset_gpio, GPIO_OUTPUT_ACTIVE);
356 		if (ret != 0) {
357 			LOG_ERR("Reset pin configuration failed: %d", ret);
358 			return ret;
359 		}
360 
361 		k_sleep(K_MSEC(RESET_DELAY_MS));
362 
363 		gpio_pin_set_dt(&cfg->reset_gpio, 0);
364 
365 		k_sleep(K_MSEC(RESET_DELAY_MS));
366 	}
367 
368 	ret = pmw3610_read_reg(dev, PMW3610_PROD_ID, &val);
369 	if (ret < 0) {
370 		return ret;
371 	}
372 
373 	if (val != PRODUCT_ID_PMW3610) {
374 		LOG_ERR("Invalid product id: %02x", val);
375 		return -ENOTSUP;
376 	}
377 
378 	/* Power-up init sequence */
379 	ret = pmw3610_spi_clk_on(dev);
380 	if (ret < 0) {
381 		return ret;
382 	}
383 
384 	ret = pmw3610_write_reg(dev, PMW3610_OBSERVATION1, 0);
385 	if (ret < 0) {
386 		return ret;
387 	}
388 
389 	k_sleep(K_MSEC(INIT_OBSERVATION_DELAY_MS));
390 
391 	ret = pmw3610_read_reg(dev, PMW3610_OBSERVATION1, &val);
392 	if (ret < 0) {
393 		return ret;
394 	}
395 
396 	if ((val & OBSERVATION1_INIT_MASK) != OBSERVATION1_INIT_MASK) {
397 		LOG_ERR("Unexpected OBSERVATION1 value: %02x", val);
398 		return -EINVAL;
399 	}
400 
401 	for (uint8_t reg = PMW3610_MOTION; reg <= PMW3610_DELTA_XY_H; reg++) {
402 		ret = pmw3610_read_reg(dev, reg, &val);
403 		if (ret < 0) {
404 			return ret;
405 		}
406 	}
407 
408 	ret = pmw3610_write_reg(dev, PMW3610_PERFORMANCE, PERFORMANCE_INIT);
409 	if (ret < 0) {
410 		return ret;
411 	}
412 
413 	ret = pmw3610_write_reg(dev, PMW3610_RUN_DOWNSHIFT, RUN_DOWNSHIFT_INIT);
414 	if (ret < 0) {
415 		return ret;
416 	}
417 
418 	ret = pmw3610_write_reg(dev, PMW3610_REST1_RATE, REST1_RATE_INIT);
419 	if (ret < 0) {
420 		return ret;
421 	}
422 
423 	ret = pmw3610_write_reg(dev, PMW3610_REST1_DOWNSHIFT, REST1_DOWNSHIFT_INIT);
424 	if (ret < 0) {
425 		return ret;
426 	}
427 
428 	/* Configuration */
429 
430 	if (cfg->invert_x || cfg->invert_y) {
431 		ret = pmw3610_write_reg(dev, PWM3610_SPI_PAGE0, SPI_PAGE0_1);
432 		if (ret < 0) {
433 			return ret;
434 		}
435 
436 		ret = pmw3610_read_reg(dev, PMW3610_RES_STEP, &val);
437 		if (ret < 0) {
438 			return ret;
439 		}
440 
441 		WRITE_BIT(val, RES_STEP_INV_X_BIT, cfg->invert_x);
442 		WRITE_BIT(val, RES_STEP_INV_Y_BIT, cfg->invert_y);
443 
444 		ret = pmw3610_write_reg(dev, PMW3610_RES_STEP, val);
445 		if (ret < 0) {
446 			return ret;
447 		}
448 
449 		ret = pmw3610_write_reg(dev, PWM3610_SPI_PAGE1, SPI_PAGE1_0);
450 		if (ret < 0) {
451 			return ret;
452 		}
453 
454 	}
455 
456 	ret = pmw3610_spi_clk_off(dev);
457 	if (ret < 0) {
458 		return ret;
459 	}
460 
461 	/* The remaining functions call spi_clk_on/off independently. */
462 
463 	if (cfg->res_cpi > 0) {
464 		pmw3610_set_resolution(dev, cfg->res_cpi);
465 	}
466 
467 	pmw3610_force_awake(dev, cfg->force_awake);
468 
469 	return 0;
470 }
471 
pmw3610_init(const struct device * dev)472 static int pmw3610_init(const struct device *dev)
473 {
474 	const struct pmw3610_config *cfg = dev->config;
475 	struct pmw3610_data *data = dev->data;
476 	int ret;
477 
478 	if (!spi_is_ready_dt(&cfg->spi)) {
479 		LOG_ERR("%s is not ready", cfg->spi.bus->name);
480 		return -ENODEV;
481 	}
482 
483 	data->dev = dev;
484 
485 	k_work_init(&data->motion_work, pmw3610_motion_work_handler);
486 
487 	if (!gpio_is_ready_dt(&cfg->motion_gpio)) {
488 		LOG_ERR("%s is not ready", cfg->motion_gpio.port->name);
489 		return -ENODEV;
490 	}
491 
492 	ret = gpio_pin_configure_dt(&cfg->motion_gpio, GPIO_INPUT);
493 	if (ret != 0) {
494 		LOG_ERR("Motion pin configuration failed: %d", ret);
495 		return ret;
496 	}
497 
498 	gpio_init_callback(&data->motion_cb, pmw3610_motion_handler,
499 			   BIT(cfg->motion_gpio.pin));
500 
501 	ret = gpio_add_callback_dt(&cfg->motion_gpio, &data->motion_cb);
502 	if (ret < 0) {
503 		LOG_ERR("Could not set motion callback: %d", ret);
504 		return ret;
505 	}
506 
507 	ret = pmw3610_configure(dev);
508 	if (ret != 0) {
509 		LOG_ERR("Device configuration failed: %d", ret);
510 		return ret;
511 	}
512 
513 	ret = gpio_pin_interrupt_configure_dt(&cfg->motion_gpio,
514 					      GPIO_INT_EDGE_TO_ACTIVE);
515 	if (ret != 0) {
516 		LOG_ERR("Motion interrupt configuration failed: %d", ret);
517 		return ret;
518 	}
519 
520 	ret = pm_device_runtime_enable(dev);
521 	if (ret < 0) {
522 		LOG_ERR("Failed to enable runtime power management: %d", ret);
523 		return ret;
524 	}
525 
526 	return 0;
527 }
528 
529 #ifdef CONFIG_PM_DEVICE
pmw3610_pm_action(const struct device * dev,enum pm_device_action action)530 static int pmw3610_pm_action(const struct device *dev,
531 			     enum pm_device_action action)
532 {
533 	int ret;
534 
535 	switch (action) {
536 	case PM_DEVICE_ACTION_SUSPEND:
537 		ret = pmw3610_write_reg(dev, PMW3610_SHUTDOWN, SHUTDOWN_ENABLE);
538 		if (ret < 0) {
539 			return ret;
540 		}
541 		break;
542 	case PM_DEVICE_ACTION_RESUME:
543 		ret = pmw3610_write_reg(dev, PMW3610_POWER_UP_RESET, POWER_UP_WAKEUP);
544 		if (ret < 0) {
545 			return ret;
546 		}
547 		break;
548 	default:
549 		return -ENOTSUP;
550 	}
551 
552 	return 0;
553 }
554 #endif
555 
556 #define PMW3610_SPI_MODE (SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | \
557 			  SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_TRANSFER_MSB)
558 
559 #define PMW3610_INIT(n)								\
560 	BUILD_ASSERT(IN_RANGE(DT_INST_PROP_OR(n, res_cpi, RES_MIN),		\
561 			      RES_MIN, RES_MAX), "invalid res-cpi");		\
562 										\
563 	static const struct pmw3610_config pmw3610_cfg_##n = {			\
564 		.spi = SPI_DT_SPEC_INST_GET(n, PMW3610_SPI_MODE, 0),		\
565 		.motion_gpio = GPIO_DT_SPEC_INST_GET(n, motion_gpios),		\
566 		.reset_gpio = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {}),	\
567 		.axis_x = DT_INST_PROP(n, zephyr_axis_x),			\
568 		.axis_y = DT_INST_PROP(n, zephyr_axis_y),			\
569 		.res_cpi = DT_INST_PROP_OR(n, res_cpi, -1),			\
570 		.invert_x = DT_INST_PROP(n, invert_x),				\
571 		.invert_y = DT_INST_PROP(n, invert_y),				\
572 		.force_awake = DT_INST_PROP(n, force_awake),			\
573 		.smart_mode = DT_INST_PROP(n, smart_mode),			\
574 	};									\
575 										\
576 	static struct pmw3610_data pmw3610_data_##n;				\
577 										\
578 	PM_DEVICE_DT_INST_DEFINE(n, pmw3610_pm_action);				\
579 										\
580 	DEVICE_DT_INST_DEFINE(n, pmw3610_init, PM_DEVICE_DT_INST_GET(n),	\
581 			      &pmw3610_data_##n, &pmw3610_cfg_##n,		\
582 			      POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY,		\
583 			      NULL);
584 
585 DT_INST_FOREACH_STATUS_OKAY(PMW3610_INIT)
586