diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk index a9119d844e..091fc3b9a0 100644 --- a/builddefs/common_features.mk +++ b/builddefs/common_features.mk @@ -123,7 +123,7 @@ ifeq ($(strip $(MOUSEKEY_ENABLE)), yes) MOUSE_ENABLE := yes endif -VALID_POINTING_DEVICE_DRIVER_TYPES := adns5050 adns9800 analog_joystick azoteq_iqs5xx cirque_pinnacle_i2c cirque_pinnacle_spi paw3204 pmw3320 pmw3360 pmw3389 pimoroni_trackball navigator_trackball navigator_trackpad custom +VALID_POINTING_DEVICE_DRIVER_TYPES := adns5050 adns9800 analog_joystick azoteq_iqs5xx cirque_pinnacle_i2c cirque_pinnacle_spi paw3204 pmw3320 pmw3360 pmw3389 pimoroni_trackball navigator_trackpad custom ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes) ifeq ($(filter $(POINTING_DEVICE_DRIVER),$(VALID_POINTING_DEVICE_DRIVER_TYPES)),) $(call CATASTROPHIC_ERROR,Invalid POINTING_DEVICE_DRIVER,POINTING_DEVICE_DRIVER="$(POINTING_DEVICE_DRIVER)" is not a valid pointing device type) @@ -157,9 +157,6 @@ ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes) SRC += $(QUANTUM_DIR)/pointing_device/pointing_device_gestures.c else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pimoroni_trackball) I2C_DRIVER_REQUIRED = yes - else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), navigator_trackball) - I2C_DRIVER_REQUIRED = yes - SRC += drivers/sensors/navigator.c else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), navigator_trackpad) I2C_DRIVER_REQUIRED = yes SRC += drivers/sensors/navigator.c diff --git a/drivers/sensors/navigator_trackball.c b/drivers/sensors/navigator_trackball.c deleted file mode 100644 index 62b836dd04..0000000000 --- a/drivers/sensors/navigator_trackball.c +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright 2025 ZSA Technology Labs, Inc -// SPDX-License-Identifier: GPL-2.0-or-later - -// This is the QMK driver for the Navigator Trackball. It is comprised of two ICs: -// 1. The sci18is606 is a i2c to spi bridge that converts the i2c protocol to the spi protocol. It allows the trackball to -// be plugged using the TRRS jack used by ZSA keyboards or any other split keyboard. -// 2. The paw3805ek is a high-speed motion detection sensor. It is used to detect the motion of the trackball. - -#include "i2c_master.h" -#include "navigator_trackball.h" -#include -#include -#include "quantum.h" - -const pointing_device_driver_t navigator_trackball_pointing_device_driver = { - .init = navigator_trackball_device_init, - .get_report = navigator_trackball_get_report, - .get_cpi = navigator_trackball_get_cpi, - .set_cpi = navigator_trackball_set_cpi -}; - -uint8_t current_cpi = NAVIGATOR_TRACKBALL_CPI; - -uint8_t has_motion = 0; - -uint8_t trackball_init = 0; - -deferred_token callback_token = 0; - -// The sequence of commands to configure and boot the paw3805ek sensor. -paw3805ek_reg_seq_t paw3805ek_configure_seq[] = { - {0x06, 0x80}, // Software reset - {0x00, 0x00}, // Request the sensor ID - {0x09 | WRITE_REG_BIT, 0x5A}, // Disable the write protection -#ifdef MOUSE_EXTENDED_REPORT - {0x19 | WRITE_REG_BIT, 0x30}, // Set the sensor orientation, set motion data length to 16 bits -#else - {0x19 | WRITE_REG_BIT, 0x34}, // Set the sensor orientation, set motion data length to 8 bits -#endif - //{0x26 | WRITE_REG_BIT, 0x10}, // Enable burst mode - {0x09 | WRITE_REG_BIT, 0x00}, // Enable the write protection -}; - -// A wrapper function for i2c_transmit that adds the address of the bridge chip to the data. -i2c_status_t sci18is606_write(uint8_t *data, uint8_t length) { - return i2c_transmit(NAVIGATOR_TRACKBALL_ADDRESS, data, length, NAVIGATOR_TRACKBALL_TIMEOUT); -} - -// A wrapper function for i2c_receive that adds the address of the bridge chip to the data. -i2c_status_t sci18is606_read(uint8_t *data, uint8_t length) { - return i2c_receive(NAVIGATOR_TRACKBALL_ADDRESS, data, length, NAVIGATOR_TRACKBALL_TIMEOUT); -} - -// A wrapper function that allows to write and optionally read from the bridge chip. -i2c_status_t sci18is606_spi_tx(uint8_t *data, uint8_t length, bool read) { - i2c_status_t status = sci18is606_write(data, length); - wait_us(length * 15); - // Read the SPI response if the command expects it - if (read) { - status = sci18is606_read(data, length); - } - if (status != I2C_STATUS_SUCCESS) { - trackball_init = 0; - } - return status; -} - -// Configure the bridge chip to enable SPI mode. -i2c_status_t sci18is606_configure(void) { - uint8_t spi_conf[2] = {SCI18IS606_CONF_SPI, SCI18IS606_CONF}; - i2c_status_t status = sci18is606_write(spi_conf, 2); - wait_ms(10); - if (status != I2C_STATUS_SUCCESS) { - trackball_init = 0; - } - return status; -} - -bool paw3805ek_set_cpi(void) { - - paw3805ek_reg_seq_t cpi_reg_seq[] = { - {0x09 | WRITE_REG_BIT, 0x5A}, // Disable write protection - {0x0D | WRITE_REG_BIT, current_cpi}, - {0x0E | WRITE_REG_BIT, current_cpi}, - {0x09 | WRITE_REG_BIT, 0x00}, // Enable the write protection - }; - - // Run the spi sequence to configure the cpi. - for (uint8_t i = 0; i < sizeof(cpi_reg_seq) / sizeof(paw3805ek_reg_seq_t); i++) { - uint8_t buf[3]; - buf[0] = NCS_PIN; - buf[1] = cpi_reg_seq[i].reg; - buf[2] = cpi_reg_seq[i].data; - if (sci18is606_spi_tx(buf, 3, true) != I2C_STATUS_SUCCESS) { - return false; - } - } - - return true; -} - -// Run the paw3805ek configuration sequence. -bool paw3805ek_configure(void) { - for (uint8_t i = 0; i < sizeof(paw3805ek_configure_seq) / sizeof(paw3805ek_reg_seq_t); i++) { - uint8_t buf[3]; - buf[0] = NCS_PIN; - buf[1] = paw3805ek_configure_seq[i].reg; - buf[2] = paw3805ek_configure_seq[i].data; - if (sci18is606_spi_tx(buf, 3, true) != I2C_STATUS_SUCCESS) { - return false; - } - // Wait for the sensor to restart after the software reset cmd - wait_ms(1); - - // Check the sensor ID to validate the spi link after the reset - if (i == 1 && buf[1] != PAW3805EK_ID) { - return false; - } - } - - return true; -} - -// Assert the CS pin to read the motion register. -bool paw3805ek_has_motion(void) { - uint8_t motion[3] = {0x01, 0x02, 0x00}; - if (sci18is606_spi_tx(motion, 3, true) != I2C_STATUS_SUCCESS) { - return false; - } - return motion[1] & 0x80; -} - -// Read the motion data from the paw3805ek sensor. -void paw3804ek_read_motion(report_mouse_t *mouse_report) { -#ifdef MOUSE_EXTENDED_REPORT - uint8_t delta_x_l[2] = {0x01, 0x03}; - if (sci18is606_spi_tx(delta_x_l, 3, true) != I2C_STATUS_SUCCESS) { - return; - } - - uint8_t delta_y_l[2] = {0x01, 0x04}; - if (sci18is606_spi_tx(delta_y_l, 3, true) != I2C_STATUS_SUCCESS) { - return; - } - - uint8_t delta_x_h[2] = {0x01, 0x11}; - if (sci18is606_spi_tx(delta_x_h, 3, true) != I2C_STATUS_SUCCESS) { - return; - } - - uint8_t delta_y_h[2] = {0x01, 0x12}; - if (sci18is606_spi_tx(delta_y_h, 3, true) != I2C_STATUS_SUCCESS) { - return; - } - - mouse_report->x = (int16_t)((delta_x_h[1] << 8) | delta_x_l[1]); - mouse_report->y = (int16_t)((delta_y_h[1] << 8) | delta_y_l[1]); -#else - uint8_t delta_x[2] = {0x01, 0x03}; - if (sci18is606_spi_tx(delta_x, 3, true) != I2C_STATUS_SUCCESS) { - return; - } - - uint8_t delta_y[2] = {0x01, 0x04}; - if (sci18is606_spi_tx(delta_y, 3, true) != I2C_STATUS_SUCCESS) { - return; - } - - mouse_report->x = delta_x[1]; - mouse_report->y = delta_y[1]; -#endif -} - -// Deffered execution callback that periodically checks for motion. -uint32_t sci18is606_read_callback(uint32_t trigger_time, void *cb_arg) { - if (!trackball_init) { - navigator_trackball_device_init(); - return NAVIGATOR_TRACKBALL_PROBE; - } - if (paw3805ek_has_motion()) { - has_motion = 1; - } - return NAVIGATOR_TRACKBALL_READ; -} - -void navigator_trackball_device_init(void) { - i2c_init(); - if (sci18is606_configure() == I2C_STATUS_SUCCESS) { - paw3805ek_configure(); - } else { - return; - } - - trackball_init = 1; - restore_cpi(current_cpi); - if (!callback_token) { - // Register the callback to read the trackball motion - callback_token = defer_exec(NAVIGATOR_TRACKBALL_READ, sci18is606_read_callback, NULL); - } -} - -report_mouse_t navigator_trackball_get_report(report_mouse_t mouse_report) { - if (!trackball_init) { - return mouse_report; - } - - if (has_motion) { - has_motion = 0; - paw3804ek_read_motion(&mouse_report); - } - return mouse_report; -} - -uint16_t navigator_trackball_get_cpi(void) { - return current_cpi; -} - -void restore_cpi(uint8_t cpi) { - current_cpi = cpi; - paw3805ek_set_cpi(); -} - -void navigator_trackball_set_cpi(uint16_t cpi) { - if (cpi == 0) { // Decrease one tick - if (current_cpi > NAVIGATOR_TRACKBALL_CPI_TICK) { - current_cpi -= NAVIGATOR_TRACKBALL_CPI_TICK; - paw3805ek_set_cpi(); - } - } else { - if (current_cpi <= NAVIGATOR_TRACKBALL_CPI_MAX - NAVIGATOR_TRACKBALL_CPI_TICK) { - current_cpi += NAVIGATOR_TRACKBALL_CPI_TICK; - paw3805ek_set_cpi(); - } - } -}; diff --git a/drivers/sensors/navigator_trackball.h b/drivers/sensors/navigator_trackball.h deleted file mode 100644 index 74fe38301b..0000000000 --- a/drivers/sensors/navigator_trackball.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2025 ZSA Technology Labs, Inc -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once -#include -#include -#include "pointing_device.h" - -#ifndef NAVIGATOR_TRACKBALL_ADDRESS -# define NAVIGATOR_TRACKBALL_ADDRESS 0x50 -#endif - -#ifndef NAVIGATOR_TRACKBALL_CPI -# define NAVIGATOR_TRACKBALL_CPI 40 -#endif - -#ifndef NAVIGATOR_TRACKBALL_CPI_TICK -# define NAVIGATOR_TRACKBALL_CPI_TICK 5 -#endif - -#define NAVIGATOR_TRACKBALL_CPI_MAX 125 - -#ifndef NAVIGATOR_TRACKBALL_TIMEOUT -# define NAVIGATOR_TRACKBALL_TIMEOUT 100 -#endif - -#define NAVIGATOR_TRACKBALL_READ 7 -#define NAVIGATOR_TRACKBALL_PROBE 1000 - -#define NCS_PIN 0x01 -#define PAW3805EK_ID 0x31 - -#define SCI18IS606_CONF 0xDC //00001110b // MSB first, Mode 3, 155kHz - -#define SCI18IS606_RW_SPI 0x00 -#define SCI18IS606_CONF_SPI 0xF0 -#define SCI18IS606_CLR_INT 0xF1 -#define SCI18IS606_GET_ID 0xFE - -#define WRITE_REG_BIT 0x80 - -typedef struct { - uint8_t reg; - uint8_t data; -} paw3805ek_reg_seq_t; - -const pointing_device_driver_t navigator_trackball_pointing_device_driver; - -void navigator_trackball_device_init(void); -report_mouse_t navigator_trackball_get_report(report_mouse_t mouse_report); -uint16_t navigator_trackball_get_cpi(void); -void navigator_trackball_set_cpi(uint16_t cpi); -void restore_cpi(uint8_t cpi); diff --git a/modules/zsa b/modules/zsa index 96d0cb94f9..6c50ecf97a 160000 --- a/modules/zsa +++ b/modules/zsa @@ -1 +1 @@ -Subproject commit 96d0cb94f9415de9af95c2ad3ec65ced77cf1419 +Subproject commit 6c50ecf97abc06deefaffcfe33d3ddd1b5ee4bdf diff --git a/quantum/pointing_device/pointing_device.h b/quantum/pointing_device/pointing_device.h index a9e9146d26..6822a03dd6 100644 --- a/quantum/pointing_device/pointing_device.h +++ b/quantum/pointing_device/pointing_device.h @@ -74,10 +74,6 @@ typedef struct { # include "spi_master.h" # include "drivers/sensors/pmw33xx_common.h" # define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW -#elif defined(POINTING_DEVICE_DRIVER_navigator_trackball) -# include "i2c_master.h" -# include "drivers/sensors/navigator_trackball.h" -# include "drivers/sensors/navigator.h" #elif defined(POINTING_DEVICE_DRIVER_navigator_trackpad) # include "i2c_master.h" # include "drivers/sensors/navigator_trackpad.h"