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: drv260x - fix magnitude handling

First of all, previously the 16-bit magnitude was written as-is to the
device which actually discarded the upper 8 bits since the device has
8-bit registers only. This meant that a strong_magnitude of 0xFF00 would
result in 0. To correct this shift the strong_magnitude / weak_magnitude
input values so we discard the lower 8 bits and keep the upper bits
instead.

Secondly the RTP mode that is used by default interprets the values as
signed (2s complement), so 0x81 = 0%, 0x00 = 50%, 0x7F = 100%. This
doesn't match the FF_RUMBLE interface at all, so let's tell the device
to interpret the data as unsigned instead which gets us 0x00 = 0% and
0xFF = 100%.

As last change switch ERM to using "Closed-Loop Mode, Unidirectional"
instead of "Open-Loop Mode" since it's recommended by the datasheet
compared to open loop and better matches our use case of 0% - 100%
vibration.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
Link: https://lore.kernel.org/r/20230430-drv260x-improvements-v1-4-1fb28b4cc698@z3ntu.xyz
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Luca Weiss and committed by
Dmitry Torokhov
d09dbc7a 980626ec

+7 -6
+7 -6
drivers/input/misc/drv260x.c
··· 186 186 struct work_struct work; 187 187 struct gpio_desc *enable_gpio; 188 188 struct regulator *regulator; 189 - u32 magnitude; 189 + u8 magnitude; 190 190 u32 mode; 191 191 u32 library; 192 192 int rated_voltage; ··· 237 237 238 238 haptics->mode = DRV260X_LRA_NO_CAL_MODE; 239 239 240 + /* Scale u16 magnitude into u8 register value */ 240 241 if (effect->u.rumble.strong_magnitude > 0) 241 - haptics->magnitude = effect->u.rumble.strong_magnitude; 242 + haptics->magnitude = effect->u.rumble.strong_magnitude >> 8; 242 243 else if (effect->u.rumble.weak_magnitude > 0) 243 - haptics->magnitude = effect->u.rumble.weak_magnitude; 244 + haptics->magnitude = effect->u.rumble.weak_magnitude >> 8; 244 245 else 245 246 haptics->magnitude = 0; 246 247 ··· 267 266 268 267 static const struct reg_sequence drv260x_lra_cal_regs[] = { 269 268 { DRV260X_MODE, DRV260X_AUTO_CAL }, 270 - { DRV260X_CTRL3, DRV260X_NG_THRESH_2 }, 269 + { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_RTP_UNSIGNED_DATA }, 271 270 { DRV260X_FEEDBACK_CTRL, DRV260X_FB_REG_LRA_MODE | 272 271 DRV260X_BRAKE_FACTOR_4X | DRV260X_LOOP_GAIN_HIGH }, 273 272 }; ··· 285 284 DRV260X_BEMF_GAIN_3 }, 286 285 { DRV260X_CTRL1, DRV260X_STARTUP_BOOST }, 287 286 { DRV260X_CTRL2, DRV260X_SAMP_TIME_250 }, 288 - { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_ANALOG_IN }, 287 + { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_RTP_UNSIGNED_DATA | DRV260X_ANALOG_IN }, 289 288 { DRV260X_CTRL4, DRV260X_AUTOCAL_TIME_500MS }, 290 289 }; 291 290 ··· 300 299 { DRV260X_CTRL1, DRV260X_STARTUP_BOOST }, 301 300 { DRV260X_CTRL2, DRV260X_SAMP_TIME_250 | DRV260X_BLANK_TIME_75 | 302 301 DRV260X_IDISS_TIME_75 }, 303 - { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_ERM_OPEN_LOOP }, 302 + { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_RTP_UNSIGNED_DATA }, 304 303 { DRV260X_CTRL4, DRV260X_AUTOCAL_TIME_500MS }, 305 304 }; 306 305