summaryrefslogtreecommitdiff
path: root/drivers/input/rmi4/rmi_f12.c
diff options
context:
space:
mode:
authorMarge Yang <marge.yang@tw.synaptics.com>2024-08-05 17:30:55 +0300
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2024-08-05 20:31:33 +0300
commit14d650fcb7fb57f121fda361b9f63eeefd8d59a5 (patch)
tree27b181e7ec3b0fd1b9704795bb2828f159fb59d1 /drivers/input/rmi4/rmi_f12.c
parent63f92f11385dc3b1990e5af1d6412c22c71d7342 (diff)
downloadlinux-14d650fcb7fb57f121fda361b9f63eeefd8d59a5.tar.xz
Input: synaptics-rmi4 - add support for querying DPM value (F12)
Newer firmware allows to query touchpad resolution information by reading from resolution register. Presence of resolution register is signalled via bit 29 of the "register presence" register. On devices that lack this resolution register we fall back to using pitch and number of receivers data to calculate size of the sensor. Signed-off-by: Marge Yang <marge.yang@tw.synaptics.com> Signed-off-by: Vincent Huang <Vincent.Huang@tw.synaptics.com> Link: https://lore.kernel.org/r/20240805083636.1381205-1-marge.yang@tw.synaptics.com Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/rmi4/rmi_f12.c')
-rw-r--r--drivers/input/rmi4/rmi_f12.c44
1 files changed, 34 insertions, 10 deletions
diff --git a/drivers/input/rmi4/rmi_f12.c b/drivers/input/rmi4/rmi_f12.c
index 7e97944f7616..fc2cc8e2b0ba 100644
--- a/drivers/input/rmi4/rmi_f12.c
+++ b/drivers/input/rmi4/rmi_f12.c
@@ -24,6 +24,7 @@ enum rmi_f12_object_type {
};
#define F12_DATA1_BYTES_PER_OBJ 8
+#define RMI_F12_QUERY_RESOLUTION 29
struct f12_data {
struct rmi_2d_sensor sensor;
@@ -73,6 +74,8 @@ static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
int pitch_y = 0;
int rx_receivers = 0;
int tx_receivers = 0;
+ u16 query_dpm_addr = 0;
+ int dpm_resolution = 0;
item = rmi_get_register_desc_item(&f12->control_reg_desc, 8);
if (!item) {
@@ -122,18 +125,39 @@ static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
offset += 4;
}
- if (rmi_register_desc_has_subpacket(item, 3)) {
- rx_receivers = buf[offset];
- tx_receivers = buf[offset + 1];
- offset += 2;
- }
+ /*
+ * Use the Query DPM feature when the resolution query register
+ * exists.
+ */
+ item = rmi_get_register_desc_item(&f12->query_reg_desc,
+ RMI_F12_QUERY_RESOLUTION);
+ if (item) {
+ offset = rmi_register_desc_calc_reg_offset(&f12->query_reg_desc,
+ RMI_F12_QUERY_RESOLUTION);
+ query_dpm_addr = fn->fd.query_base_addr + offset;
+ ret = rmi_read(fn->rmi_dev, query_dpm_addr, buf);
+ if (ret < 0) {
+ dev_err(&fn->dev, "Failed to read DPM value: %d\n", ret);
+ return -ENODEV;
+ }
+ dpm_resolution = buf[0];
- /* Skip over sensor flags */
- if (rmi_register_desc_has_subpacket(item, 4))
- offset += 1;
+ sensor->x_mm = sensor->max_x / dpm_resolution;
+ sensor->y_mm = sensor->max_y / dpm_resolution;
+ } else {
+ if (rmi_register_desc_has_subpacket(item, 3)) {
+ rx_receivers = buf[offset];
+ tx_receivers = buf[offset + 1];
+ offset += 2;
+ }
- sensor->x_mm = (pitch_x * rx_receivers) >> 12;
- sensor->y_mm = (pitch_y * tx_receivers) >> 12;
+ /* Skip over sensor flags */
+ if (rmi_register_desc_has_subpacket(item, 4))
+ offset += 1;
+
+ sensor->x_mm = (pitch_x * rx_receivers) >> 12;
+ sensor->y_mm = (pitch_y * tx_receivers) >> 12;
+ }
rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: x_mm: %d y_mm: %d\n", __func__,
sensor->x_mm, sensor->y_mm);