| .. | .. |
|---|
| 9 | 9 | * axial sliders presented by the device. |
|---|
| 10 | 10 | */ |
|---|
| 11 | 11 | |
|---|
| 12 | +#include <linux/completion.h> |
|---|
| 12 | 13 | #include <linux/delay.h> |
|---|
| 13 | 14 | #include <linux/device.h> |
|---|
| 14 | 15 | #include <linux/err.h> |
|---|
| .. | .. |
|---|
| 96 | 97 | #define IQS269_MISC_B_TRACKING_UI_ENABLE BIT(4) |
|---|
| 97 | 98 | #define IQS269_MISC_B_FILT_STR_SLIDER GENMASK(1, 0) |
|---|
| 98 | 99 | |
|---|
| 99 | | -#define IQS269_CHx_SETTINGS 0x8C |
|---|
| 100 | | - |
|---|
| 101 | 100 | #define IQS269_CHx_ENG_A_MEAS_CAP_SIZE BIT(15) |
|---|
| 102 | 101 | #define IQS269_CHx_ENG_A_RX_GND_INACTIVE BIT(13) |
|---|
| 103 | 102 | #define IQS269_CHx_ENG_A_LOCAL_CAP_SIZE BIT(12) |
|---|
| .. | .. |
|---|
| 146 | 145 | #define IQS269_NUM_CH 8 |
|---|
| 147 | 146 | #define IQS269_NUM_SL 2 |
|---|
| 148 | 147 | |
|---|
| 149 | | -#define IQS269_ATI_POLL_SLEEP_US (iqs269->delay_mult * 10000) |
|---|
| 150 | | -#define IQS269_ATI_POLL_TIMEOUT_US (iqs269->delay_mult * 500000) |
|---|
| 151 | | -#define IQS269_ATI_STABLE_DELAY_MS (iqs269->delay_mult * 150) |
|---|
| 152 | | - |
|---|
| 153 | | -#define IQS269_PWR_MODE_POLL_SLEEP_US IQS269_ATI_POLL_SLEEP_US |
|---|
| 154 | | -#define IQS269_PWR_MODE_POLL_TIMEOUT_US IQS269_ATI_POLL_TIMEOUT_US |
|---|
| 155 | | - |
|---|
| 156 | | -#define iqs269_irq_wait() usleep_range(100, 150) |
|---|
| 148 | +#define iqs269_irq_wait() usleep_range(200, 250) |
|---|
| 157 | 149 | |
|---|
| 158 | 150 | enum iqs269_local_cap_size { |
|---|
| 159 | 151 | IQS269_LOCAL_CAP_SIZE_0, |
|---|
| .. | .. |
|---|
| 245 | 237 | u8 padding; |
|---|
| 246 | 238 | } __packed; |
|---|
| 247 | 239 | |
|---|
| 240 | +struct iqs269_ch_reg { |
|---|
| 241 | + u8 rx_enable; |
|---|
| 242 | + u8 tx_enable; |
|---|
| 243 | + __be16 engine_a; |
|---|
| 244 | + __be16 engine_b; |
|---|
| 245 | + __be16 ati_comp; |
|---|
| 246 | + u8 thresh[3]; |
|---|
| 247 | + u8 hyst; |
|---|
| 248 | + u8 assoc_select; |
|---|
| 249 | + u8 assoc_weight; |
|---|
| 250 | +} __packed; |
|---|
| 251 | + |
|---|
| 248 | 252 | struct iqs269_sys_reg { |
|---|
| 249 | 253 | __be16 general; |
|---|
| 250 | 254 | u8 active; |
|---|
| .. | .. |
|---|
| 266 | 270 | u8 timeout_swipe; |
|---|
| 267 | 271 | u8 thresh_swipe; |
|---|
| 268 | 272 | u8 redo_ati; |
|---|
| 269 | | -} __packed; |
|---|
| 270 | | - |
|---|
| 271 | | -struct iqs269_ch_reg { |
|---|
| 272 | | - u8 rx_enable; |
|---|
| 273 | | - u8 tx_enable; |
|---|
| 274 | | - __be16 engine_a; |
|---|
| 275 | | - __be16 engine_b; |
|---|
| 276 | | - __be16 ati_comp; |
|---|
| 277 | | - u8 thresh[3]; |
|---|
| 278 | | - u8 hyst; |
|---|
| 279 | | - u8 assoc_select; |
|---|
| 280 | | - u8 assoc_weight; |
|---|
| 273 | + struct iqs269_ch_reg ch_reg[IQS269_NUM_CH]; |
|---|
| 281 | 274 | } __packed; |
|---|
| 282 | 275 | |
|---|
| 283 | 276 | struct iqs269_flags { |
|---|
| .. | .. |
|---|
| 292 | 285 | struct regmap *regmap; |
|---|
| 293 | 286 | struct mutex lock; |
|---|
| 294 | 287 | struct iqs269_switch_desc switches[ARRAY_SIZE(iqs269_events)]; |
|---|
| 295 | | - struct iqs269_ch_reg ch_reg[IQS269_NUM_CH]; |
|---|
| 296 | 288 | struct iqs269_sys_reg sys_reg; |
|---|
| 289 | + struct completion ati_done; |
|---|
| 297 | 290 | struct input_dev *keypad; |
|---|
| 298 | 291 | struct input_dev *slider[IQS269_NUM_SL]; |
|---|
| 299 | 292 | unsigned int keycode[ARRAY_SIZE(iqs269_events) * IQS269_NUM_CH]; |
|---|
| 300 | | - unsigned int suspend_mode; |
|---|
| 301 | | - unsigned int delay_mult; |
|---|
| 302 | 293 | unsigned int ch_num; |
|---|
| 303 | 294 | bool hall_enable; |
|---|
| 304 | 295 | bool ati_current; |
|---|
| .. | .. |
|---|
| 307 | 298 | static int iqs269_ati_mode_set(struct iqs269_private *iqs269, |
|---|
| 308 | 299 | unsigned int ch_num, unsigned int mode) |
|---|
| 309 | 300 | { |
|---|
| 301 | + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; |
|---|
| 310 | 302 | u16 engine_a; |
|---|
| 311 | 303 | |
|---|
| 312 | 304 | if (ch_num >= IQS269_NUM_CH) |
|---|
| .. | .. |
|---|
| 317 | 309 | |
|---|
| 318 | 310 | mutex_lock(&iqs269->lock); |
|---|
| 319 | 311 | |
|---|
| 320 | | - engine_a = be16_to_cpu(iqs269->ch_reg[ch_num].engine_a); |
|---|
| 312 | + engine_a = be16_to_cpu(ch_reg[ch_num].engine_a); |
|---|
| 321 | 313 | |
|---|
| 322 | 314 | engine_a &= ~IQS269_CHx_ENG_A_ATI_MODE_MASK; |
|---|
| 323 | 315 | engine_a |= (mode << IQS269_CHx_ENG_A_ATI_MODE_SHIFT); |
|---|
| 324 | 316 | |
|---|
| 325 | | - iqs269->ch_reg[ch_num].engine_a = cpu_to_be16(engine_a); |
|---|
| 317 | + ch_reg[ch_num].engine_a = cpu_to_be16(engine_a); |
|---|
| 326 | 318 | iqs269->ati_current = false; |
|---|
| 327 | 319 | |
|---|
| 328 | 320 | mutex_unlock(&iqs269->lock); |
|---|
| .. | .. |
|---|
| 333 | 325 | static int iqs269_ati_mode_get(struct iqs269_private *iqs269, |
|---|
| 334 | 326 | unsigned int ch_num, unsigned int *mode) |
|---|
| 335 | 327 | { |
|---|
| 328 | + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; |
|---|
| 336 | 329 | u16 engine_a; |
|---|
| 337 | 330 | |
|---|
| 338 | 331 | if (ch_num >= IQS269_NUM_CH) |
|---|
| 339 | 332 | return -EINVAL; |
|---|
| 340 | 333 | |
|---|
| 341 | 334 | mutex_lock(&iqs269->lock); |
|---|
| 342 | | - engine_a = be16_to_cpu(iqs269->ch_reg[ch_num].engine_a); |
|---|
| 335 | + engine_a = be16_to_cpu(ch_reg[ch_num].engine_a); |
|---|
| 343 | 336 | mutex_unlock(&iqs269->lock); |
|---|
| 344 | 337 | |
|---|
| 345 | 338 | engine_a &= IQS269_CHx_ENG_A_ATI_MODE_MASK; |
|---|
| .. | .. |
|---|
| 351 | 344 | static int iqs269_ati_base_set(struct iqs269_private *iqs269, |
|---|
| 352 | 345 | unsigned int ch_num, unsigned int base) |
|---|
| 353 | 346 | { |
|---|
| 347 | + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; |
|---|
| 354 | 348 | u16 engine_b; |
|---|
| 355 | 349 | |
|---|
| 356 | 350 | if (ch_num >= IQS269_NUM_CH) |
|---|
| .. | .. |
|---|
| 379 | 373 | |
|---|
| 380 | 374 | mutex_lock(&iqs269->lock); |
|---|
| 381 | 375 | |
|---|
| 382 | | - engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b); |
|---|
| 376 | + engine_b = be16_to_cpu(ch_reg[ch_num].engine_b); |
|---|
| 383 | 377 | |
|---|
| 384 | 378 | engine_b &= ~IQS269_CHx_ENG_B_ATI_BASE_MASK; |
|---|
| 385 | 379 | engine_b |= base; |
|---|
| 386 | 380 | |
|---|
| 387 | | - iqs269->ch_reg[ch_num].engine_b = cpu_to_be16(engine_b); |
|---|
| 381 | + ch_reg[ch_num].engine_b = cpu_to_be16(engine_b); |
|---|
| 388 | 382 | iqs269->ati_current = false; |
|---|
| 389 | 383 | |
|---|
| 390 | 384 | mutex_unlock(&iqs269->lock); |
|---|
| .. | .. |
|---|
| 395 | 389 | static int iqs269_ati_base_get(struct iqs269_private *iqs269, |
|---|
| 396 | 390 | unsigned int ch_num, unsigned int *base) |
|---|
| 397 | 391 | { |
|---|
| 392 | + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; |
|---|
| 398 | 393 | u16 engine_b; |
|---|
| 399 | 394 | |
|---|
| 400 | 395 | if (ch_num >= IQS269_NUM_CH) |
|---|
| 401 | 396 | return -EINVAL; |
|---|
| 402 | 397 | |
|---|
| 403 | 398 | mutex_lock(&iqs269->lock); |
|---|
| 404 | | - engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b); |
|---|
| 399 | + engine_b = be16_to_cpu(ch_reg[ch_num].engine_b); |
|---|
| 405 | 400 | mutex_unlock(&iqs269->lock); |
|---|
| 406 | 401 | |
|---|
| 407 | 402 | switch (engine_b & IQS269_CHx_ENG_B_ATI_BASE_MASK) { |
|---|
| .. | .. |
|---|
| 429 | 424 | static int iqs269_ati_target_set(struct iqs269_private *iqs269, |
|---|
| 430 | 425 | unsigned int ch_num, unsigned int target) |
|---|
| 431 | 426 | { |
|---|
| 427 | + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; |
|---|
| 432 | 428 | u16 engine_b; |
|---|
| 433 | 429 | |
|---|
| 434 | 430 | if (ch_num >= IQS269_NUM_CH) |
|---|
| .. | .. |
|---|
| 439 | 435 | |
|---|
| 440 | 436 | mutex_lock(&iqs269->lock); |
|---|
| 441 | 437 | |
|---|
| 442 | | - engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b); |
|---|
| 438 | + engine_b = be16_to_cpu(ch_reg[ch_num].engine_b); |
|---|
| 443 | 439 | |
|---|
| 444 | 440 | engine_b &= ~IQS269_CHx_ENG_B_ATI_TARGET_MASK; |
|---|
| 445 | 441 | engine_b |= target / 32; |
|---|
| 446 | 442 | |
|---|
| 447 | | - iqs269->ch_reg[ch_num].engine_b = cpu_to_be16(engine_b); |
|---|
| 443 | + ch_reg[ch_num].engine_b = cpu_to_be16(engine_b); |
|---|
| 448 | 444 | iqs269->ati_current = false; |
|---|
| 449 | 445 | |
|---|
| 450 | 446 | mutex_unlock(&iqs269->lock); |
|---|
| .. | .. |
|---|
| 455 | 451 | static int iqs269_ati_target_get(struct iqs269_private *iqs269, |
|---|
| 456 | 452 | unsigned int ch_num, unsigned int *target) |
|---|
| 457 | 453 | { |
|---|
| 454 | + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; |
|---|
| 458 | 455 | u16 engine_b; |
|---|
| 459 | 456 | |
|---|
| 460 | 457 | if (ch_num >= IQS269_NUM_CH) |
|---|
| 461 | 458 | return -EINVAL; |
|---|
| 462 | 459 | |
|---|
| 463 | 460 | mutex_lock(&iqs269->lock); |
|---|
| 464 | | - engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b); |
|---|
| 461 | + engine_b = be16_to_cpu(ch_reg[ch_num].engine_b); |
|---|
| 465 | 462 | mutex_unlock(&iqs269->lock); |
|---|
| 466 | 463 | |
|---|
| 467 | 464 | *target = (engine_b & IQS269_CHx_ENG_B_ATI_TARGET_MASK) * 32; |
|---|
| .. | .. |
|---|
| 531 | 528 | if (fwnode_property_present(ch_node, "azoteq,slider1-select")) |
|---|
| 532 | 529 | iqs269->sys_reg.slider_select[1] |= BIT(reg); |
|---|
| 533 | 530 | |
|---|
| 534 | | - ch_reg = &iqs269->ch_reg[reg]; |
|---|
| 535 | | - |
|---|
| 536 | | - error = regmap_raw_read(iqs269->regmap, |
|---|
| 537 | | - IQS269_CHx_SETTINGS + reg * sizeof(*ch_reg) / 2, |
|---|
| 538 | | - ch_reg, sizeof(*ch_reg)); |
|---|
| 539 | | - if (error) |
|---|
| 540 | | - return error; |
|---|
| 531 | + ch_reg = &iqs269->sys_reg.ch_reg[reg]; |
|---|
| 541 | 532 | |
|---|
| 542 | 533 | error = iqs269_parse_mask(ch_node, "azoteq,rx-enable", |
|---|
| 543 | 534 | &ch_reg->rx_enable); |
|---|
| .. | .. |
|---|
| 694 | 685 | dev_err(&client->dev, |
|---|
| 695 | 686 | "Invalid channel %u threshold: %u\n", |
|---|
| 696 | 687 | reg, val); |
|---|
| 688 | + fwnode_handle_put(ev_node); |
|---|
| 697 | 689 | return -EINVAL; |
|---|
| 698 | 690 | } |
|---|
| 699 | 691 | |
|---|
| .. | .. |
|---|
| 707 | 699 | dev_err(&client->dev, |
|---|
| 708 | 700 | "Invalid channel %u hysteresis: %u\n", |
|---|
| 709 | 701 | reg, val); |
|---|
| 702 | + fwnode_handle_put(ev_node); |
|---|
| 710 | 703 | return -EINVAL; |
|---|
| 711 | 704 | } |
|---|
| 712 | 705 | |
|---|
| .. | .. |
|---|
| 721 | 714 | } |
|---|
| 722 | 715 | } |
|---|
| 723 | 716 | |
|---|
| 724 | | - if (fwnode_property_read_u32(ev_node, "linux,code", &val)) |
|---|
| 717 | + error = fwnode_property_read_u32(ev_node, "linux,code", &val); |
|---|
| 718 | + fwnode_handle_put(ev_node); |
|---|
| 719 | + if (error == -EINVAL) { |
|---|
| 725 | 720 | continue; |
|---|
| 721 | + } else if (error) { |
|---|
| 722 | + dev_err(&client->dev, |
|---|
| 723 | + "Failed to read channel %u code: %d\n", reg, |
|---|
| 724 | + error); |
|---|
| 725 | + return error; |
|---|
| 726 | + } |
|---|
| 726 | 727 | |
|---|
| 727 | 728 | switch (reg) { |
|---|
| 728 | 729 | case IQS269_CHx_HALL_ACTIVE: |
|---|
| .. | .. |
|---|
| 758 | 759 | |
|---|
| 759 | 760 | iqs269->hall_enable = device_property_present(&client->dev, |
|---|
| 760 | 761 | "azoteq,hall-enable"); |
|---|
| 761 | | - |
|---|
| 762 | | - if (!device_property_read_u32(&client->dev, "azoteq,suspend-mode", |
|---|
| 763 | | - &val)) { |
|---|
| 764 | | - if (val > IQS269_SYS_SETTINGS_PWR_MODE_MAX) { |
|---|
| 765 | | - dev_err(&client->dev, "Invalid suspend mode: %u\n", |
|---|
| 766 | | - val); |
|---|
| 767 | | - return -EINVAL; |
|---|
| 768 | | - } |
|---|
| 769 | | - |
|---|
| 770 | | - iqs269->suspend_mode = val; |
|---|
| 771 | | - } |
|---|
| 772 | 762 | |
|---|
| 773 | 763 | error = regmap_raw_read(iqs269->regmap, IQS269_SYS_SETTINGS, sys_reg, |
|---|
| 774 | 764 | sizeof(*sys_reg)); |
|---|
| .. | .. |
|---|
| 980 | 970 | |
|---|
| 981 | 971 | general = be16_to_cpu(sys_reg->general); |
|---|
| 982 | 972 | |
|---|
| 983 | | - if (device_property_present(&client->dev, "azoteq,clk-div")) { |
|---|
| 973 | + if (device_property_present(&client->dev, "azoteq,clk-div")) |
|---|
| 984 | 974 | general |= IQS269_SYS_SETTINGS_CLK_DIV; |
|---|
| 985 | | - iqs269->delay_mult = 4; |
|---|
| 986 | | - } else { |
|---|
| 987 | | - general &= ~IQS269_SYS_SETTINGS_CLK_DIV; |
|---|
| 988 | | - iqs269->delay_mult = 1; |
|---|
| 989 | | - } |
|---|
| 990 | 975 | |
|---|
| 991 | 976 | /* |
|---|
| 992 | 977 | * Configure the device to automatically switch between normal and low- |
|---|
| .. | .. |
|---|
| 996 | 981 | general &= ~IQS269_SYS_SETTINGS_ULP_AUTO; |
|---|
| 997 | 982 | general &= ~IQS269_SYS_SETTINGS_DIS_AUTO; |
|---|
| 998 | 983 | general &= ~IQS269_SYS_SETTINGS_PWR_MODE_MASK; |
|---|
| 984 | + |
|---|
| 985 | + if (!device_property_read_u32(&client->dev, "azoteq,suspend-mode", |
|---|
| 986 | + &val)) { |
|---|
| 987 | + if (val > IQS269_SYS_SETTINGS_PWR_MODE_MAX) { |
|---|
| 988 | + dev_err(&client->dev, "Invalid suspend mode: %u\n", |
|---|
| 989 | + val); |
|---|
| 990 | + return -EINVAL; |
|---|
| 991 | + } |
|---|
| 992 | + |
|---|
| 993 | + general |= (val << IQS269_SYS_SETTINGS_PWR_MODE_SHIFT); |
|---|
| 994 | + } |
|---|
| 999 | 995 | |
|---|
| 1000 | 996 | if (!device_property_read_u32(&client->dev, "azoteq,ulp-update", |
|---|
| 1001 | 997 | &val)) { |
|---|
| .. | .. |
|---|
| 1032 | 1028 | |
|---|
| 1033 | 1029 | static int iqs269_dev_init(struct iqs269_private *iqs269) |
|---|
| 1034 | 1030 | { |
|---|
| 1035 | | - struct iqs269_sys_reg *sys_reg = &iqs269->sys_reg; |
|---|
| 1036 | | - struct iqs269_ch_reg *ch_reg; |
|---|
| 1037 | | - unsigned int val; |
|---|
| 1038 | | - int error, i; |
|---|
| 1031 | + int error; |
|---|
| 1039 | 1032 | |
|---|
| 1040 | 1033 | mutex_lock(&iqs269->lock); |
|---|
| 1041 | 1034 | |
|---|
| .. | .. |
|---|
| 1045 | 1038 | if (error) |
|---|
| 1046 | 1039 | goto err_mutex; |
|---|
| 1047 | 1040 | |
|---|
| 1048 | | - for (i = 0; i < IQS269_NUM_CH; i++) { |
|---|
| 1049 | | - if (!(sys_reg->active & BIT(i))) |
|---|
| 1050 | | - continue; |
|---|
| 1051 | | - |
|---|
| 1052 | | - ch_reg = &iqs269->ch_reg[i]; |
|---|
| 1053 | | - |
|---|
| 1054 | | - error = regmap_raw_write(iqs269->regmap, |
|---|
| 1055 | | - IQS269_CHx_SETTINGS + i * |
|---|
| 1056 | | - sizeof(*ch_reg) / 2, ch_reg, |
|---|
| 1057 | | - sizeof(*ch_reg)); |
|---|
| 1058 | | - if (error) |
|---|
| 1059 | | - goto err_mutex; |
|---|
| 1060 | | - } |
|---|
| 1041 | + error = regmap_raw_write(iqs269->regmap, IQS269_SYS_SETTINGS, |
|---|
| 1042 | + &iqs269->sys_reg, sizeof(iqs269->sys_reg)); |
|---|
| 1043 | + if (error) |
|---|
| 1044 | + goto err_mutex; |
|---|
| 1061 | 1045 | |
|---|
| 1062 | 1046 | /* |
|---|
| 1063 | | - * The REDO-ATI and ATI channel selection fields must be written in the |
|---|
| 1064 | | - * same block write, so every field between registers 0x80 through 0x8B |
|---|
| 1065 | | - * (inclusive) must be written as well. |
|---|
| 1047 | + * The following delay gives the device time to deassert its RDY output |
|---|
| 1048 | + * so as to prevent an interrupt from being serviced prematurely. |
|---|
| 1066 | 1049 | */ |
|---|
| 1067 | | - error = regmap_raw_write(iqs269->regmap, IQS269_SYS_SETTINGS, sys_reg, |
|---|
| 1068 | | - sizeof(*sys_reg)); |
|---|
| 1069 | | - if (error) |
|---|
| 1070 | | - goto err_mutex; |
|---|
| 1050 | + usleep_range(2000, 2100); |
|---|
| 1071 | 1051 | |
|---|
| 1072 | | - error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val, |
|---|
| 1073 | | - !(val & IQS269_SYS_FLAGS_IN_ATI), |
|---|
| 1074 | | - IQS269_ATI_POLL_SLEEP_US, |
|---|
| 1075 | | - IQS269_ATI_POLL_TIMEOUT_US); |
|---|
| 1076 | | - if (error) |
|---|
| 1077 | | - goto err_mutex; |
|---|
| 1078 | | - |
|---|
| 1079 | | - msleep(IQS269_ATI_STABLE_DELAY_MS); |
|---|
| 1080 | 1052 | iqs269->ati_current = true; |
|---|
| 1081 | 1053 | |
|---|
| 1082 | 1054 | err_mutex: |
|---|
| .. | .. |
|---|
| 1088 | 1060 | static int iqs269_input_init(struct iqs269_private *iqs269) |
|---|
| 1089 | 1061 | { |
|---|
| 1090 | 1062 | struct i2c_client *client = iqs269->client; |
|---|
| 1091 | | - struct iqs269_flags flags; |
|---|
| 1092 | 1063 | unsigned int sw_code, keycode; |
|---|
| 1093 | 1064 | int error, i, j; |
|---|
| 1094 | | - u8 dir_mask, state; |
|---|
| 1095 | 1065 | |
|---|
| 1096 | 1066 | iqs269->keypad = devm_input_allocate_device(&client->dev); |
|---|
| 1097 | 1067 | if (!iqs269->keypad) |
|---|
| .. | .. |
|---|
| 1104 | 1074 | iqs269->keypad->name = "iqs269a_keypad"; |
|---|
| 1105 | 1075 | iqs269->keypad->id.bustype = BUS_I2C; |
|---|
| 1106 | 1076 | |
|---|
| 1107 | | - if (iqs269->hall_enable) { |
|---|
| 1108 | | - error = regmap_raw_read(iqs269->regmap, IQS269_SYS_FLAGS, |
|---|
| 1109 | | - &flags, sizeof(flags)); |
|---|
| 1110 | | - if (error) { |
|---|
| 1111 | | - dev_err(&client->dev, |
|---|
| 1112 | | - "Failed to read initial status: %d\n", error); |
|---|
| 1113 | | - return error; |
|---|
| 1114 | | - } |
|---|
| 1115 | | - } |
|---|
| 1116 | | - |
|---|
| 1117 | 1077 | for (i = 0; i < ARRAY_SIZE(iqs269_events); i++) { |
|---|
| 1118 | | - dir_mask = flags.states[IQS269_ST_OFFS_DIR]; |
|---|
| 1119 | | - if (!iqs269_events[i].dir_up) |
|---|
| 1120 | | - dir_mask = ~dir_mask; |
|---|
| 1121 | | - |
|---|
| 1122 | | - state = flags.states[iqs269_events[i].st_offs] & dir_mask; |
|---|
| 1123 | | - |
|---|
| 1124 | 1078 | sw_code = iqs269->switches[i].code; |
|---|
| 1125 | 1079 | |
|---|
| 1126 | 1080 | for (j = 0; j < IQS269_NUM_CH; j++) { |
|---|
| .. | .. |
|---|
| 1133 | 1087 | switch (j) { |
|---|
| 1134 | 1088 | case IQS269_CHx_HALL_ACTIVE: |
|---|
| 1135 | 1089 | if (iqs269->hall_enable && |
|---|
| 1136 | | - iqs269->switches[i].enabled) { |
|---|
| 1090 | + iqs269->switches[i].enabled) |
|---|
| 1137 | 1091 | input_set_capability(iqs269->keypad, |
|---|
| 1138 | 1092 | EV_SW, sw_code); |
|---|
| 1139 | | - input_report_switch(iqs269->keypad, |
|---|
| 1140 | | - sw_code, |
|---|
| 1141 | | - state & BIT(j)); |
|---|
| 1142 | | - } |
|---|
| 1143 | 1093 | fallthrough; |
|---|
| 1144 | 1094 | |
|---|
| 1145 | 1095 | case IQS269_CHx_HALL_INACTIVE: |
|---|
| .. | .. |
|---|
| 1153 | 1103 | EV_KEY, keycode); |
|---|
| 1154 | 1104 | } |
|---|
| 1155 | 1105 | } |
|---|
| 1156 | | - } |
|---|
| 1157 | | - |
|---|
| 1158 | | - input_sync(iqs269->keypad); |
|---|
| 1159 | | - |
|---|
| 1160 | | - error = input_register_device(iqs269->keypad); |
|---|
| 1161 | | - if (error) { |
|---|
| 1162 | | - dev_err(&client->dev, "Failed to register keypad: %d\n", error); |
|---|
| 1163 | | - return error; |
|---|
| 1164 | 1106 | } |
|---|
| 1165 | 1107 | |
|---|
| 1166 | 1108 | for (i = 0; i < IQS269_NUM_SL; i++) { |
|---|
| .. | .. |
|---|
| 1221 | 1163 | |
|---|
| 1222 | 1164 | return error; |
|---|
| 1223 | 1165 | } |
|---|
| 1166 | + |
|---|
| 1167 | + if (be16_to_cpu(flags.system) & IQS269_SYS_FLAGS_IN_ATI) |
|---|
| 1168 | + return 0; |
|---|
| 1224 | 1169 | |
|---|
| 1225 | 1170 | error = regmap_raw_read(iqs269->regmap, IQS269_SLIDER_X, slider_x, |
|---|
| 1226 | 1171 | sizeof(slider_x)); |
|---|
| .. | .. |
|---|
| 1284 | 1229 | |
|---|
| 1285 | 1230 | input_sync(iqs269->keypad); |
|---|
| 1286 | 1231 | |
|---|
| 1232 | + /* |
|---|
| 1233 | + * The following completion signals that ATI has finished, any initial |
|---|
| 1234 | + * switch states have been reported and the keypad can be registered. |
|---|
| 1235 | + */ |
|---|
| 1236 | + complete_all(&iqs269->ati_done); |
|---|
| 1237 | + |
|---|
| 1287 | 1238 | return 0; |
|---|
| 1288 | 1239 | } |
|---|
| 1289 | 1240 | |
|---|
| .. | .. |
|---|
| 1315 | 1266 | if (!iqs269->ati_current || iqs269->hall_enable) |
|---|
| 1316 | 1267 | return -EPERM; |
|---|
| 1317 | 1268 | |
|---|
| 1269 | + if (!completion_done(&iqs269->ati_done)) |
|---|
| 1270 | + return -EBUSY; |
|---|
| 1271 | + |
|---|
| 1318 | 1272 | /* |
|---|
| 1319 | 1273 | * Unsolicited I2C communication prompts the device to assert its RDY |
|---|
| 1320 | 1274 | * pin, so disable the interrupt line until the operation is finished |
|---|
| .. | .. |
|---|
| 1339 | 1293 | struct device_attribute *attr, char *buf) |
|---|
| 1340 | 1294 | { |
|---|
| 1341 | 1295 | struct iqs269_private *iqs269 = dev_get_drvdata(dev); |
|---|
| 1296 | + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; |
|---|
| 1342 | 1297 | struct i2c_client *client = iqs269->client; |
|---|
| 1343 | 1298 | unsigned int val; |
|---|
| 1344 | 1299 | int error; |
|---|
| .. | .. |
|---|
| 1353 | 1308 | if (error) |
|---|
| 1354 | 1309 | return error; |
|---|
| 1355 | 1310 | |
|---|
| 1356 | | - switch (iqs269->ch_reg[IQS269_CHx_HALL_ACTIVE].rx_enable & |
|---|
| 1357 | | - iqs269->ch_reg[IQS269_CHx_HALL_INACTIVE].rx_enable) { |
|---|
| 1311 | + switch (ch_reg[IQS269_CHx_HALL_ACTIVE].rx_enable & |
|---|
| 1312 | + ch_reg[IQS269_CHx_HALL_INACTIVE].rx_enable) { |
|---|
| 1358 | 1313 | case IQS269_HALL_PAD_R: |
|---|
| 1359 | 1314 | val &= IQS269_CAL_DATA_A_HALL_BIN_R_MASK; |
|---|
| 1360 | 1315 | val >>= IQS269_CAL_DATA_A_HALL_BIN_R_SHIFT; |
|---|
| .. | .. |
|---|
| 1434 | 1389 | struct device_attribute *attr, char *buf) |
|---|
| 1435 | 1390 | { |
|---|
| 1436 | 1391 | struct iqs269_private *iqs269 = dev_get_drvdata(dev); |
|---|
| 1392 | + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; |
|---|
| 1437 | 1393 | |
|---|
| 1438 | 1394 | return scnprintf(buf, PAGE_SIZE, "%u\n", |
|---|
| 1439 | | - iqs269->ch_reg[iqs269->ch_num].rx_enable); |
|---|
| 1395 | + ch_reg[iqs269->ch_num].rx_enable); |
|---|
| 1440 | 1396 | } |
|---|
| 1441 | 1397 | |
|---|
| 1442 | 1398 | static ssize_t rx_enable_store(struct device *dev, |
|---|
| .. | .. |
|---|
| 1444 | 1400 | size_t count) |
|---|
| 1445 | 1401 | { |
|---|
| 1446 | 1402 | struct iqs269_private *iqs269 = dev_get_drvdata(dev); |
|---|
| 1403 | + struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg; |
|---|
| 1447 | 1404 | unsigned int val; |
|---|
| 1448 | 1405 | int error; |
|---|
| 1449 | 1406 | |
|---|
| .. | .. |
|---|
| 1456 | 1413 | |
|---|
| 1457 | 1414 | mutex_lock(&iqs269->lock); |
|---|
| 1458 | 1415 | |
|---|
| 1459 | | - iqs269->ch_reg[iqs269->ch_num].rx_enable = val; |
|---|
| 1416 | + ch_reg[iqs269->ch_num].rx_enable = val; |
|---|
| 1460 | 1417 | iqs269->ati_current = false; |
|---|
| 1461 | 1418 | |
|---|
| 1462 | 1419 | mutex_unlock(&iqs269->lock); |
|---|
| .. | .. |
|---|
| 1568 | 1525 | { |
|---|
| 1569 | 1526 | struct iqs269_private *iqs269 = dev_get_drvdata(dev); |
|---|
| 1570 | 1527 | |
|---|
| 1571 | | - return scnprintf(buf, PAGE_SIZE, "%u\n", iqs269->ati_current); |
|---|
| 1528 | + return scnprintf(buf, PAGE_SIZE, "%u\n", |
|---|
| 1529 | + iqs269->ati_current && |
|---|
| 1530 | + completion_done(&iqs269->ati_done)); |
|---|
| 1572 | 1531 | } |
|---|
| 1573 | 1532 | |
|---|
| 1574 | 1533 | static ssize_t ati_trigger_store(struct device *dev, |
|---|
| .. | .. |
|---|
| 1588 | 1547 | return count; |
|---|
| 1589 | 1548 | |
|---|
| 1590 | 1549 | disable_irq(client->irq); |
|---|
| 1550 | + reinit_completion(&iqs269->ati_done); |
|---|
| 1591 | 1551 | |
|---|
| 1592 | 1552 | error = iqs269_dev_init(iqs269); |
|---|
| 1593 | 1553 | |
|---|
| .. | .. |
|---|
| 1596 | 1556 | |
|---|
| 1597 | 1557 | if (error) |
|---|
| 1598 | 1558 | return error; |
|---|
| 1559 | + |
|---|
| 1560 | + if (!wait_for_completion_timeout(&iqs269->ati_done, |
|---|
| 1561 | + msecs_to_jiffies(2000))) |
|---|
| 1562 | + return -ETIMEDOUT; |
|---|
| 1599 | 1563 | |
|---|
| 1600 | 1564 | return count; |
|---|
| 1601 | 1565 | } |
|---|
| .. | .. |
|---|
| 1655 | 1619 | } |
|---|
| 1656 | 1620 | |
|---|
| 1657 | 1621 | mutex_init(&iqs269->lock); |
|---|
| 1622 | + init_completion(&iqs269->ati_done); |
|---|
| 1658 | 1623 | |
|---|
| 1659 | 1624 | error = regmap_raw_read(iqs269->regmap, IQS269_VER_INFO, &ver_info, |
|---|
| 1660 | 1625 | sizeof(ver_info)); |
|---|
| .. | .. |
|---|
| 1690 | 1655 | return error; |
|---|
| 1691 | 1656 | } |
|---|
| 1692 | 1657 | |
|---|
| 1658 | + if (!wait_for_completion_timeout(&iqs269->ati_done, |
|---|
| 1659 | + msecs_to_jiffies(2000))) { |
|---|
| 1660 | + dev_err(&client->dev, "Failed to complete ATI\n"); |
|---|
| 1661 | + return -ETIMEDOUT; |
|---|
| 1662 | + } |
|---|
| 1663 | + |
|---|
| 1664 | + /* |
|---|
| 1665 | + * The keypad may include one or more switches and is not registered |
|---|
| 1666 | + * until ATI is complete and the initial switch states are read. |
|---|
| 1667 | + */ |
|---|
| 1668 | + error = input_register_device(iqs269->keypad); |
|---|
| 1669 | + if (error) { |
|---|
| 1670 | + dev_err(&client->dev, "Failed to register keypad: %d\n", error); |
|---|
| 1671 | + return error; |
|---|
| 1672 | + } |
|---|
| 1673 | + |
|---|
| 1693 | 1674 | error = devm_device_add_group(&client->dev, &iqs269_attr_group); |
|---|
| 1694 | 1675 | if (error) |
|---|
| 1695 | 1676 | dev_err(&client->dev, "Failed to add attributes: %d\n", error); |
|---|
| .. | .. |
|---|
| 1697 | 1678 | return error; |
|---|
| 1698 | 1679 | } |
|---|
| 1699 | 1680 | |
|---|
| 1681 | +static u16 iqs269_general_get(struct iqs269_private *iqs269) |
|---|
| 1682 | +{ |
|---|
| 1683 | + u16 general = be16_to_cpu(iqs269->sys_reg.general); |
|---|
| 1684 | + |
|---|
| 1685 | + general &= ~IQS269_SYS_SETTINGS_REDO_ATI; |
|---|
| 1686 | + general &= ~IQS269_SYS_SETTINGS_ACK_RESET; |
|---|
| 1687 | + |
|---|
| 1688 | + return general | IQS269_SYS_SETTINGS_DIS_AUTO; |
|---|
| 1689 | +} |
|---|
| 1690 | + |
|---|
| 1700 | 1691 | static int __maybe_unused iqs269_suspend(struct device *dev) |
|---|
| 1701 | 1692 | { |
|---|
| 1702 | 1693 | struct iqs269_private *iqs269 = dev_get_drvdata(dev); |
|---|
| 1703 | 1694 | struct i2c_client *client = iqs269->client; |
|---|
| 1704 | | - unsigned int val; |
|---|
| 1705 | 1695 | int error; |
|---|
| 1696 | + u16 general = iqs269_general_get(iqs269); |
|---|
| 1706 | 1697 | |
|---|
| 1707 | | - if (!iqs269->suspend_mode) |
|---|
| 1698 | + if (!(general & IQS269_SYS_SETTINGS_PWR_MODE_MASK)) |
|---|
| 1708 | 1699 | return 0; |
|---|
| 1709 | 1700 | |
|---|
| 1710 | 1701 | disable_irq(client->irq); |
|---|
| 1711 | 1702 | |
|---|
| 1712 | | - /* |
|---|
| 1713 | | - * Automatic power mode switching must be disabled before the device is |
|---|
| 1714 | | - * forced into any particular power mode. In this case, the device will |
|---|
| 1715 | | - * transition into normal-power mode. |
|---|
| 1716 | | - */ |
|---|
| 1717 | | - error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS, |
|---|
| 1718 | | - IQS269_SYS_SETTINGS_DIS_AUTO, ~0); |
|---|
| 1719 | | - if (error) |
|---|
| 1720 | | - goto err_irq; |
|---|
| 1703 | + error = regmap_write(iqs269->regmap, IQS269_SYS_SETTINGS, general); |
|---|
| 1721 | 1704 | |
|---|
| 1722 | | - /* |
|---|
| 1723 | | - * The following check ensures the device has completed its transition |
|---|
| 1724 | | - * into normal-power mode before a manual mode switch is performed. |
|---|
| 1725 | | - */ |
|---|
| 1726 | | - error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val, |
|---|
| 1727 | | - !(val & IQS269_SYS_FLAGS_PWR_MODE_MASK), |
|---|
| 1728 | | - IQS269_PWR_MODE_POLL_SLEEP_US, |
|---|
| 1729 | | - IQS269_PWR_MODE_POLL_TIMEOUT_US); |
|---|
| 1730 | | - if (error) |
|---|
| 1731 | | - goto err_irq; |
|---|
| 1732 | | - |
|---|
| 1733 | | - error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS, |
|---|
| 1734 | | - IQS269_SYS_SETTINGS_PWR_MODE_MASK, |
|---|
| 1735 | | - iqs269->suspend_mode << |
|---|
| 1736 | | - IQS269_SYS_SETTINGS_PWR_MODE_SHIFT); |
|---|
| 1737 | | - if (error) |
|---|
| 1738 | | - goto err_irq; |
|---|
| 1739 | | - |
|---|
| 1740 | | - /* |
|---|
| 1741 | | - * This last check ensures the device has completed its transition into |
|---|
| 1742 | | - * the desired power mode to prevent any spurious interrupts from being |
|---|
| 1743 | | - * triggered after iqs269_suspend has already returned. |
|---|
| 1744 | | - */ |
|---|
| 1745 | | - error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val, |
|---|
| 1746 | | - (val & IQS269_SYS_FLAGS_PWR_MODE_MASK) |
|---|
| 1747 | | - == (iqs269->suspend_mode << |
|---|
| 1748 | | - IQS269_SYS_FLAGS_PWR_MODE_SHIFT), |
|---|
| 1749 | | - IQS269_PWR_MODE_POLL_SLEEP_US, |
|---|
| 1750 | | - IQS269_PWR_MODE_POLL_TIMEOUT_US); |
|---|
| 1751 | | - |
|---|
| 1752 | | -err_irq: |
|---|
| 1753 | 1705 | iqs269_irq_wait(); |
|---|
| 1754 | 1706 | enable_irq(client->irq); |
|---|
| 1755 | 1707 | |
|---|
| .. | .. |
|---|
| 1760 | 1712 | { |
|---|
| 1761 | 1713 | struct iqs269_private *iqs269 = dev_get_drvdata(dev); |
|---|
| 1762 | 1714 | struct i2c_client *client = iqs269->client; |
|---|
| 1763 | | - unsigned int val; |
|---|
| 1764 | 1715 | int error; |
|---|
| 1716 | + u16 general = iqs269_general_get(iqs269); |
|---|
| 1765 | 1717 | |
|---|
| 1766 | | - if (!iqs269->suspend_mode) |
|---|
| 1718 | + if (!(general & IQS269_SYS_SETTINGS_PWR_MODE_MASK)) |
|---|
| 1767 | 1719 | return 0; |
|---|
| 1768 | 1720 | |
|---|
| 1769 | 1721 | disable_irq(client->irq); |
|---|
| 1770 | 1722 | |
|---|
| 1771 | | - error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS, |
|---|
| 1772 | | - IQS269_SYS_SETTINGS_PWR_MODE_MASK, 0); |
|---|
| 1773 | | - if (error) |
|---|
| 1774 | | - goto err_irq; |
|---|
| 1723 | + error = regmap_write(iqs269->regmap, IQS269_SYS_SETTINGS, |
|---|
| 1724 | + general & ~IQS269_SYS_SETTINGS_PWR_MODE_MASK); |
|---|
| 1725 | + if (!error) |
|---|
| 1726 | + error = regmap_write(iqs269->regmap, IQS269_SYS_SETTINGS, |
|---|
| 1727 | + general & ~IQS269_SYS_SETTINGS_DIS_AUTO); |
|---|
| 1775 | 1728 | |
|---|
| 1776 | | - /* |
|---|
| 1777 | | - * This check ensures the device has returned to normal-power mode |
|---|
| 1778 | | - * before automatic power mode switching is re-enabled. |
|---|
| 1779 | | - */ |
|---|
| 1780 | | - error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val, |
|---|
| 1781 | | - !(val & IQS269_SYS_FLAGS_PWR_MODE_MASK), |
|---|
| 1782 | | - IQS269_PWR_MODE_POLL_SLEEP_US, |
|---|
| 1783 | | - IQS269_PWR_MODE_POLL_TIMEOUT_US); |
|---|
| 1784 | | - if (error) |
|---|
| 1785 | | - goto err_irq; |
|---|
| 1786 | | - |
|---|
| 1787 | | - error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS, |
|---|
| 1788 | | - IQS269_SYS_SETTINGS_DIS_AUTO, 0); |
|---|
| 1789 | | - if (error) |
|---|
| 1790 | | - goto err_irq; |
|---|
| 1791 | | - |
|---|
| 1792 | | - /* |
|---|
| 1793 | | - * This step reports any events that may have been "swallowed" as a |
|---|
| 1794 | | - * result of polling PWR_MODE (which automatically acknowledges any |
|---|
| 1795 | | - * pending interrupts). |
|---|
| 1796 | | - */ |
|---|
| 1797 | | - error = iqs269_report(iqs269); |
|---|
| 1798 | | - |
|---|
| 1799 | | -err_irq: |
|---|
| 1800 | 1729 | iqs269_irq_wait(); |
|---|
| 1801 | 1730 | enable_irq(client->irq); |
|---|
| 1802 | 1731 | |
|---|