Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

input: pat912x: add a bunch of settings #69636

Merged
merged 1 commit into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions drivers/input/input_pat912x.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/input/input.h>
#include <zephyr/input/input_pat912x.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/pm/device.h>
Expand Down Expand Up @@ -47,6 +48,10 @@ LOG_MODULE_REGISTER(input_pat912x, CONFIG_INPUT_LOG_LEVEL);
#define WRITE_PROTECT_ENABLE 0x00
#define WRITE_PROTECT_DISABLE 0x5a
#define MOTION_STATUS_MOTION BIT(7)
#define RES_SCALING_FACTOR 5
#define RES_MAX (UINT8_MAX * RES_SCALING_FACTOR)
#define OPERATION_MODE_SLEEP_1_EN BIT(4)
#define OPERATION_MODE_SLEEP_12_EN (BIT(4) | BIT(3))

#define PAT912X_DATA_SIZE_BITS 12

Expand All @@ -57,6 +62,12 @@ struct pat912x_config {
struct gpio_dt_spec motion_gpio;
int32_t axis_x;
int32_t axis_y;
int16_t res_x_cpi;
int16_t res_y_cpi;
bool invert_x;
bool invert_y;
bool sleep1_enable;
bool sleep2_enable;
};

struct pat912x_data {
Expand Down Expand Up @@ -102,6 +113,13 @@ static void pat912x_motion_work_handler(struct k_work *work)
x = sign_extend(x, PAT912X_DATA_SIZE_BITS - 1);
y = sign_extend(y, PAT912X_DATA_SIZE_BITS - 1);

if (cfg->invert_x) {
x *= -1;
}
if (cfg->invert_y) {
y *= -1;
}

LOG_DBG("x=%4d y=%4d", x, y);

if (cfg->axis_x >= 0) {
Expand All @@ -128,6 +146,41 @@ static void pat912x_motion_handler(const struct device *gpio_dev,
k_work_submit(&data->motion_work);
}

int pat912x_set_resolution(const struct device *dev,
int16_t res_x_cpi, int16_t res_y_cpi)
{
const struct pat912x_config *cfg = dev->config;
int ret;

if (res_x_cpi >= 0) {
if (!IN_RANGE(res_x_cpi, 0, RES_MAX)) {
LOG_ERR("res_x_cpi out of range: %d", res_x_cpi);
return -EINVAL;
}

ret = i2c_reg_write_byte_dt(&cfg->i2c, PAT912X_RES_X,
res_x_cpi / RES_SCALING_FACTOR);
if (ret < 0) {
return ret;
}
}

if (res_y_cpi >= 0) {
if (!IN_RANGE(res_y_cpi, 0, RES_MAX)) {
LOG_ERR("res_y_cpi out of range: %d", res_y_cpi);
return -EINVAL;
}

ret = i2c_reg_write_byte_dt(&cfg->i2c, PAT912X_RES_Y,
res_y_cpi / RES_SCALING_FACTOR);
if (ret < 0) {
return ret;
}
}

return 0;
}

static int pat912x_configure(const struct device *dev)
{
const struct pat912x_config *cfg = dev->config;
Expand Down Expand Up @@ -156,6 +209,29 @@ static int pat912x_configure(const struct device *dev)
return ret;
}

ret = pat912x_set_resolution(dev, cfg->res_x_cpi, cfg->res_y_cpi);
if (ret < 0) {
return ret;
}

if (cfg->sleep1_enable && cfg->sleep2_enable) {
ret = i2c_reg_update_byte_dt(&cfg->i2c,
PAT912X_OPERATION_MODE,
OPERATION_MODE_SLEEP_12_EN,
OPERATION_MODE_SLEEP_12_EN);
if (ret < 0) {
return ret;
}
} else if (cfg->sleep1_enable) {
ret = i2c_reg_update_byte_dt(&cfg->i2c,
PAT912X_OPERATION_MODE,
OPERATION_MODE_SLEEP_12_EN,
OPERATION_MODE_SLEEP_1_EN);
if (ret < 0) {
return ret;
}
}

return 0;
}

Expand Down Expand Up @@ -249,11 +325,25 @@ static int pat912x_pm_action(const struct device *dev,
#endif

#define PAT912X_INIT(n) \
BUILD_ASSERT(IN_RANGE(DT_INST_PROP(n, res_x_cpi), 0, RES_MAX), \
"invalid res-x-cpy"); \
BUILD_ASSERT(IN_RANGE(DT_INST_PROP(n, res_y_cpi), 0, RES_MAX), \
"invalid res-y-cpy"); \
Comment on lines +328 to +331
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be nice if a generous soul introduced min/max setting in our binding language. @fabiobaltieri maybe :-) ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know what this project really needs? Interns.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... or DT maintainers 👀

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know what this project really needs? Interns.

You mean like .. Summer of Code? :)

BUILD_ASSERT(DT_INST_PROP(n, sleep1_enable) || \
!DT_INST_PROP(n, sleep2_enable), \
"invalid sleep configuration"); \
\
static const struct pat912x_config pat912x_cfg_##n = { \
.i2c = I2C_DT_SPEC_INST_GET(n), \
.motion_gpio = GPIO_DT_SPEC_INST_GET(n, motion_gpios), \
.axis_x = DT_INST_PROP_OR(n, zephyr_axis_x, -1), \
.axis_y = DT_INST_PROP_OR(n, zephyr_axis_y, -1), \
.res_x_cpi = DT_INST_PROP_OR(n, res_x_cpi, -1), \
.res_y_cpi = DT_INST_PROP_OR(n, res_y_cpi, -1), \
.invert_x = DT_INST_PROP(n, invert_x), \
.invert_y = DT_INST_PROP(n, invert_y), \
.sleep1_enable = DT_INST_PROP(n, sleep1_enable), \
.sleep2_enable = DT_INST_PROP(n, sleep2_enable), \
}; \
\
static struct pat912x_data pat912x_data_##n; \
Expand Down
32 changes: 32 additions & 0 deletions dts/bindings/input/pixart,pat912x.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,35 @@ properties:
description: |
The input code for the Y axis to report for the device, typically any of
INPUT_REL_*. No report produced for the device Y axis if unspecified.

res-x-cpi:
type: int
description: |
CPI resolution for the X axis, range 0 to 1275, rounded down to the
closest supported value in increments of 5.

res-y-cpi:
type: int
description: |
CPI resolution for the Y axis, range 0 to 1275, rounded down to the
closest supported value in increments of 5.

invert-x:
type: boolean
description: |
Invert X axis values.

invert-y:
type: boolean
description: |
Invert Y axis values.

sleep1-enable:
type: boolean
description: |
Enable sleep1 mode.

sleep2-enable:
type: boolean
description: |
Enable sleep2 mode, only valid if sleep1 is also enabled.
fabiobaltieri marked this conversation as resolved.
Show resolved Hide resolved
22 changes: 22 additions & 0 deletions include/zephyr/input/input_pat912x.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2024 Google LLC
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_INCLUDE_INPUT_PAT912X_H_
#define ZEPHYR_INCLUDE_INPUT_PAT912X_H_

/**
* @brief Set resolution on a pat912x device
*
* @param dev pat912x device.
* @param res_x_cpi CPI resolution for the X axis, 0 to 1275, -1 to keep the
* current value.
* @param res_y_cpi CPI resolution for the Y axis, 0 to 1275, -1 to keep the
* current value.
*/
int pat912x_set_resolution(const struct device *dev,
int16_t res_x_cpi, int16_t res_y_cpi);
faxe1008 marked this conversation as resolved.
Show resolved Hide resolved

#endif /* ZEPHYR_INCLUDE_INPUT_PAT912X_H_ */
6 changes: 6 additions & 0 deletions tests/drivers/build_all/input/app.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,12 @@
motion-gpios = <&test_gpio 0 0>;
zephyr,axis-x = <0>;
zephyr,axis-y = <1>;
res-x-cpi = <0>;
res-y-cpi = <0>;
invert-x;
invert-y;
sleep1-enable;
sleep2-enable;
};
};

Expand Down
Loading