Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Marge Yang and committed by
Dmitry Torokhov
14d650fc 63f92f11

+35 -11
+35 -11
drivers/input/rmi4/rmi_f12.c
··· 24 24 }; 25 25 26 26 #define F12_DATA1_BYTES_PER_OBJ 8 27 + #define RMI_F12_QUERY_RESOLUTION 29 27 28 28 29 struct f12_data { 29 30 struct rmi_2d_sensor sensor; ··· 74 73 int pitch_y = 0; 75 74 int rx_receivers = 0; 76 75 int tx_receivers = 0; 76 + u16 query_dpm_addr = 0; 77 + int dpm_resolution = 0; 77 78 78 79 item = rmi_get_register_desc_item(&f12->control_reg_desc, 8); 79 80 if (!item) { ··· 125 122 offset += 4; 126 123 } 127 124 128 - if (rmi_register_desc_has_subpacket(item, 3)) { 129 - rx_receivers = buf[offset]; 130 - tx_receivers = buf[offset + 1]; 131 - offset += 2; 125 + /* 126 + * Use the Query DPM feature when the resolution query register 127 + * exists. 128 + */ 129 + item = rmi_get_register_desc_item(&f12->query_reg_desc, 130 + RMI_F12_QUERY_RESOLUTION); 131 + if (item) { 132 + offset = rmi_register_desc_calc_reg_offset(&f12->query_reg_desc, 133 + RMI_F12_QUERY_RESOLUTION); 134 + query_dpm_addr = fn->fd.query_base_addr + offset; 135 + ret = rmi_read(fn->rmi_dev, query_dpm_addr, buf); 136 + if (ret < 0) { 137 + dev_err(&fn->dev, "Failed to read DPM value: %d\n", ret); 138 + return -ENODEV; 139 + } 140 + dpm_resolution = buf[0]; 141 + 142 + sensor->x_mm = sensor->max_x / dpm_resolution; 143 + sensor->y_mm = sensor->max_y / dpm_resolution; 144 + } else { 145 + if (rmi_register_desc_has_subpacket(item, 3)) { 146 + rx_receivers = buf[offset]; 147 + tx_receivers = buf[offset + 1]; 148 + offset += 2; 149 + } 150 + 151 + /* Skip over sensor flags */ 152 + if (rmi_register_desc_has_subpacket(item, 4)) 153 + offset += 1; 154 + 155 + sensor->x_mm = (pitch_x * rx_receivers) >> 12; 156 + sensor->y_mm = (pitch_y * tx_receivers) >> 12; 132 157 } 133 - 134 - /* Skip over sensor flags */ 135 - if (rmi_register_desc_has_subpacket(item, 4)) 136 - offset += 1; 137 - 138 - sensor->x_mm = (pitch_x * rx_receivers) >> 12; 139 - sensor->y_mm = (pitch_y * tx_receivers) >> 12; 140 158 141 159 rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: x_mm: %d y_mm: %d\n", __func__, 142 160 sensor->x_mm, sensor->y_mm);