^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * AD714X CapTouch Programmable Controller driver supporting AD7142/3/7/8/7A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2009-2011 Analog Devices Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/input/ad714x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "ad714x.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define AD714X_PWR_CTRL 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define AD714X_STG_CAL_EN_REG 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define AD714X_AMB_COMP_CTRL0_REG 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define AD714X_PARTID_REG 0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define AD7142_PARTID 0xE620
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define AD7143_PARTID 0xE630
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define AD7147_PARTID 0x1470
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define AD7148_PARTID 0x1480
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define AD714X_STAGECFG_REG 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define AD714X_SYSCFG_REG 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define STG_LOW_INT_EN_REG 0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define STG_HIGH_INT_EN_REG 0x6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define STG_COM_INT_EN_REG 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define STG_LOW_INT_STA_REG 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define STG_HIGH_INT_STA_REG 0x9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define STG_COM_INT_STA_REG 0xA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define CDC_RESULT_S0 0xB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define CDC_RESULT_S1 0xC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define CDC_RESULT_S2 0xD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define CDC_RESULT_S3 0xE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define CDC_RESULT_S4 0xF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define CDC_RESULT_S5 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define CDC_RESULT_S6 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define CDC_RESULT_S7 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define CDC_RESULT_S8 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define CDC_RESULT_S9 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define CDC_RESULT_S10 0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define CDC_RESULT_S11 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define STAGE0_AMBIENT 0xF1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define STAGE1_AMBIENT 0x115
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define STAGE2_AMBIENT 0x139
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define STAGE3_AMBIENT 0x15D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define STAGE4_AMBIENT 0x181
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define STAGE5_AMBIENT 0x1A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define STAGE6_AMBIENT 0x1C9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define STAGE7_AMBIENT 0x1ED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define STAGE8_AMBIENT 0x211
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define STAGE9_AMBIENT 0x234
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define STAGE10_AMBIENT 0x259
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define STAGE11_AMBIENT 0x27D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define PER_STAGE_REG_NUM 36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define STAGE_CFGREG_NUM 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define SYS_CFGREG_NUM 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * driver information which will be used to maintain the software flow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) enum ad714x_device_state { IDLE, JITTER, ACTIVE, SPACE };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct ad714x_slider_drv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int highest_stage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int abs_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) int flt_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) enum ad714x_device_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct ad714x_wheel_drv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int abs_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int flt_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int pre_highest_stage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int highest_stage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) enum ad714x_device_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct ad714x_touchpad_drv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int x_highest_stage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int x_flt_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int x_abs_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) int y_highest_stage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int y_flt_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) int y_abs_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int left_ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int left_ep_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int right_ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int right_ep_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int top_ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int top_ep_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int bottom_ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int bottom_ep_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) enum ad714x_device_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct ad714x_button_drv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) enum ad714x_device_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * Unlike slider/wheel/touchpad, all buttons point to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * same input_dev instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct ad714x_driver_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct ad714x_slider_drv *slider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct ad714x_wheel_drv *wheel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct ad714x_touchpad_drv *touchpad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct ad714x_button_drv *button;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * information to integrate all things which will be private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * of spi/i2c device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static void ad714x_use_com_int(struct ad714x_chip *ad714x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int start_stage, int end_stage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) unsigned short data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) unsigned short mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ad714x->read(ad714x, STG_COM_INT_EN_REG, &data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) data |= 1 << end_stage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) data &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int start_stage, int end_stage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) unsigned short data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) unsigned short mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ad714x->read(ad714x, STG_COM_INT_EN_REG, &data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) data &= ~(1 << end_stage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) data |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static int ad714x_cal_highest_stage(struct ad714x_chip *ad714x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int start_stage, int end_stage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int max_res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int max_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) for (i = start_stage; i <= end_stage; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (ad714x->sensor_val[i] > max_res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) max_res = ad714x->sensor_val[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) max_idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return max_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static int ad714x_cal_abs_pos(struct ad714x_chip *ad714x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int start_stage, int end_stage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int highest_stage, int max_coord)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int a_param, b_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (highest_stage == start_stage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) a_param = ad714x->sensor_val[start_stage + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) b_param = ad714x->sensor_val[start_stage] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ad714x->sensor_val[start_stage + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) } else if (highest_stage == end_stage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) a_param = ad714x->sensor_val[end_stage] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) (end_stage - start_stage) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ad714x->sensor_val[end_stage - 1] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) (end_stage - start_stage - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) b_param = ad714x->sensor_val[end_stage] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ad714x->sensor_val[end_stage - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) a_param = ad714x->sensor_val[highest_stage] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) (highest_stage - start_stage) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ad714x->sensor_val[highest_stage - 1] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) (highest_stage - start_stage - 1) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ad714x->sensor_val[highest_stage + 1] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) (highest_stage - start_stage + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) b_param = ad714x->sensor_val[highest_stage] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) ad714x->sensor_val[highest_stage - 1] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ad714x->sensor_val[highest_stage + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return (max_coord / (end_stage - start_stage)) * a_param / b_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * One button can connect to multi positive and negative of CDCs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * Multi-buttons can connect to same positive/negative of one CDC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static void ad714x_button_state_machine(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct ad714x_button_plat *hw = &ad714x->hw->button[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct ad714x_button_drv *sw = &ad714x->sw->button[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) switch (sw->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (((ad714x->h_state & hw->h_mask) == hw->h_mask) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) ((ad714x->l_state & hw->l_mask) == hw->l_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) dev_dbg(ad714x->dev, "button %d touched\n", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) input_report_key(sw->input, hw->keycode, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) input_sync(sw->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) sw->state = ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) case ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (((ad714x->h_state & hw->h_mask) != hw->h_mask) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ((ad714x->l_state & hw->l_mask) != hw->l_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) dev_dbg(ad714x->dev, "button %d released\n", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) input_report_key(sw->input, hw->keycode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) input_sync(sw->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) sw->state = IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * The response of a sensor is defined by the absolute number of codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * between the current CDC value and the ambient value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static void ad714x_slider_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ad714x->read(ad714x, CDC_RESULT_S0 + hw->start_stage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) &ad714x->adc_reg[hw->start_stage],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) hw->end_stage - hw->start_stage + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) for (i = hw->start_stage; i <= hw->end_stage; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) &ad714x->amb_reg[i], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) ad714x->sensor_val[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) abs(ad714x->adc_reg[i] - ad714x->amb_reg[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static void ad714x_slider_cal_highest_stage(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) sw->highest_stage = ad714x_cal_highest_stage(ad714x, hw->start_stage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) hw->end_stage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) dev_dbg(ad714x->dev, "slider %d highest_stage:%d\n", idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) sw->highest_stage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * The formulae are very straight forward. It uses the sensor with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * highest response and the 2 adjacent ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * When Sensor 0 has the highest response, only sensor 0 and sensor 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * are used in the calculations. Similarly when the last sensor has the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * highest response, only the last sensor and the second last sensors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * are used in the calculations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * For i= idx_of_peak_Sensor-1 to i= idx_of_peak_Sensor+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * v += Sensor response(i)*i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * w += Sensor response(i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * POS=(Number_of_Positions_Wanted/(Number_of_Sensors_Used-1)) *(v/w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static void ad714x_slider_cal_abs_pos(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) sw->abs_pos = ad714x_cal_abs_pos(ad714x, hw->start_stage, hw->end_stage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) sw->highest_stage, hw->max_coord);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) dev_dbg(ad714x->dev, "slider %d absolute position:%d\n", idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) sw->abs_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * To minimise the Impact of the noise on the algorithm, ADI developed a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * routine that filters the CDC results after they have been read by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * host processor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * The filter used is an Infinite Input Response(IIR) filter implemented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * in firmware and attenuates the noise on the CDC results after they've
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * been read by the host processor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * Filtered_CDC_result = (Filtered_CDC_result * (10 - Coefficient) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * Latest_CDC_result * Coefficient)/10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static void ad714x_slider_cal_flt_pos(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) sw->flt_pos = (sw->flt_pos * (10 - 4) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) sw->abs_pos * 4)/10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) dev_dbg(ad714x->dev, "slider %d filter position:%d\n", idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) sw->flt_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static void ad714x_slider_use_com_int(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) ad714x_use_com_int(ad714x, hw->start_stage, hw->end_stage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static void ad714x_slider_use_thr_int(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) ad714x_use_thr_int(ad714x, hw->start_stage, hw->end_stage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static void ad714x_slider_state_machine(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct ad714x_slider_drv *sw = &ad714x->sw->slider[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) unsigned short h_state, c_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) unsigned short mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) mask = ((1 << (hw->end_stage + 1)) - 1) - ((1 << hw->start_stage) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) h_state = ad714x->h_state & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) c_state = ad714x->c_state & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) switch (sw->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) case IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (h_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) sw->state = JITTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* In End of Conversion interrupt mode, the AD714X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * continuously generates hardware interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ad714x_slider_use_com_int(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) dev_dbg(ad714x->dev, "slider %d touched\n", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) case JITTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (c_state == mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ad714x_slider_cal_sensor_val(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ad714x_slider_cal_highest_stage(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ad714x_slider_cal_abs_pos(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) sw->flt_pos = sw->abs_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) sw->state = ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) case ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (c_state == mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (h_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ad714x_slider_cal_sensor_val(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ad714x_slider_cal_highest_stage(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ad714x_slider_cal_abs_pos(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) ad714x_slider_cal_flt_pos(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) input_report_abs(sw->input, ABS_X, sw->flt_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) input_report_key(sw->input, BTN_TOUCH, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* When the user lifts off the sensor, configure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * the AD714X back to threshold interrupt mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ad714x_slider_use_thr_int(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) sw->state = IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) input_report_key(sw->input, BTN_TOUCH, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) dev_dbg(ad714x->dev, "slider %d released\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) input_sync(sw->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * When the scroll wheel is activated, we compute the absolute position based
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * on the sensor values. To calculate the position, we first determine the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * sensor that has the greatest response among the 8 sensors that constitutes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * the scrollwheel. Then we determined the 2 sensors on either sides of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * sensor with the highest response and we apply weights to these sensors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static void ad714x_wheel_cal_highest_stage(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) sw->pre_highest_stage = sw->highest_stage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) sw->highest_stage = ad714x_cal_highest_stage(ad714x, hw->start_stage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) hw->end_stage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) dev_dbg(ad714x->dev, "wheel %d highest_stage:%d\n", idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) sw->highest_stage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static void ad714x_wheel_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) ad714x->read(ad714x, CDC_RESULT_S0 + hw->start_stage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) &ad714x->adc_reg[hw->start_stage],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) hw->end_stage - hw->start_stage + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) for (i = hw->start_stage; i <= hw->end_stage; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) &ad714x->amb_reg[i], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ad714x->sensor_val[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ad714x->adc_reg[i] - ad714x->amb_reg[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ad714x->sensor_val[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * When the scroll wheel is activated, we compute the absolute position based
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * on the sensor values. To calculate the position, we first determine the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * sensor that has the greatest response among the sensors that constitutes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * the scrollwheel. Then we determined the sensors on either sides of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * sensor with the highest response and we apply weights to these sensors. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * result of this computation gives us the mean value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static void ad714x_wheel_cal_abs_pos(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) int stage_num = hw->end_stage - hw->start_stage + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) int first_before, highest, first_after;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) int a_param, b_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) first_before = (sw->highest_stage + stage_num - 1) % stage_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) highest = sw->highest_stage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) first_after = (sw->highest_stage + stage_num + 1) % stage_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) a_param = ad714x->sensor_val[highest] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) (highest - hw->start_stage) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ad714x->sensor_val[first_before] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) (highest - hw->start_stage - 1) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) ad714x->sensor_val[first_after] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) (highest - hw->start_stage + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) b_param = ad714x->sensor_val[highest] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ad714x->sensor_val[first_before] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ad714x->sensor_val[first_after];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) sw->abs_pos = ((hw->max_coord / (hw->end_stage - hw->start_stage)) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) a_param) / b_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (sw->abs_pos > hw->max_coord)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) sw->abs_pos = hw->max_coord;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) else if (sw->abs_pos < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) sw->abs_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) static void ad714x_wheel_cal_flt_pos(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (((sw->pre_highest_stage == hw->end_stage) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) (sw->highest_stage == hw->start_stage)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ((sw->pre_highest_stage == hw->start_stage) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) (sw->highest_stage == hw->end_stage)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) sw->flt_pos = sw->abs_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) sw->flt_pos = ((sw->flt_pos * 30) + (sw->abs_pos * 71)) / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (sw->flt_pos > hw->max_coord)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) sw->flt_pos = hw->max_coord;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) static void ad714x_wheel_use_com_int(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ad714x_use_com_int(ad714x, hw->start_stage, hw->end_stage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) static void ad714x_wheel_use_thr_int(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ad714x_use_thr_int(ad714x, hw->start_stage, hw->end_stage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static void ad714x_wheel_state_machine(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) unsigned short h_state, c_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) unsigned short mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) mask = ((1 << (hw->end_stage + 1)) - 1) - ((1 << hw->start_stage) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) h_state = ad714x->h_state & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) c_state = ad714x->c_state & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) switch (sw->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) case IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (h_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) sw->state = JITTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) /* In End of Conversion interrupt mode, the AD714X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * continuously generates hardware interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) ad714x_wheel_use_com_int(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) dev_dbg(ad714x->dev, "wheel %d touched\n", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) case JITTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (c_state == mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) ad714x_wheel_cal_sensor_val(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ad714x_wheel_cal_highest_stage(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ad714x_wheel_cal_abs_pos(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) sw->flt_pos = sw->abs_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) sw->state = ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) case ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (c_state == mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (h_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) ad714x_wheel_cal_sensor_val(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) ad714x_wheel_cal_highest_stage(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ad714x_wheel_cal_abs_pos(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ad714x_wheel_cal_flt_pos(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) input_report_abs(sw->input, ABS_WHEEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) sw->flt_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) input_report_key(sw->input, BTN_TOUCH, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /* When the user lifts off the sensor, configure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * the AD714X back to threshold interrupt mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) ad714x_wheel_use_thr_int(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) sw->state = IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) input_report_key(sw->input, BTN_TOUCH, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) dev_dbg(ad714x->dev, "wheel %d released\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) input_sync(sw->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) static void touchpad_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) ad714x->read(ad714x, CDC_RESULT_S0 + hw->x_start_stage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) &ad714x->adc_reg[hw->x_start_stage],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) hw->x_end_stage - hw->x_start_stage + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) for (i = hw->x_start_stage; i <= hw->x_end_stage; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) &ad714x->amb_reg[i], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) ad714x->sensor_val[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) ad714x->adc_reg[i] - ad714x->amb_reg[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) ad714x->sensor_val[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static void touchpad_cal_highest_stage(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) sw->x_highest_stage = ad714x_cal_highest_stage(ad714x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) hw->x_start_stage, hw->x_end_stage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) sw->y_highest_stage = ad714x_cal_highest_stage(ad714x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) hw->y_start_stage, hw->y_end_stage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) dev_dbg(ad714x->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) "touchpad %d x_highest_stage:%d, y_highest_stage:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) idx, sw->x_highest_stage, sw->y_highest_stage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * If 2 fingers are touching the sensor then 2 peaks can be observed in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * The arithmetic doesn't support to get absolute coordinates for multi-touch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static int touchpad_check_second_peak(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) for (i = hw->x_start_stage; i < sw->x_highest_stage; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if ((ad714x->sensor_val[i] - ad714x->sensor_val[i + 1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) > (ad714x->sensor_val[i + 1] / 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) for (i = sw->x_highest_stage; i < hw->x_end_stage; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if ((ad714x->sensor_val[i + 1] - ad714x->sensor_val[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) > (ad714x->sensor_val[i] / 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) for (i = hw->y_start_stage; i < sw->y_highest_stage; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if ((ad714x->sensor_val[i] - ad714x->sensor_val[i + 1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) > (ad714x->sensor_val[i + 1] / 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) for (i = sw->y_highest_stage; i < hw->y_end_stage; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if ((ad714x->sensor_val[i + 1] - ad714x->sensor_val[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) > (ad714x->sensor_val[i] / 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * If only one finger is used to activate the touch pad then only 1 peak will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * registered in the distribution. This peak and the 2 adjacent sensors will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * used in the calculation of the absolute position. This will prevent hand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * shadows to affect the absolute position calculation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) static void touchpad_cal_abs_pos(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) sw->x_abs_pos = ad714x_cal_abs_pos(ad714x, hw->x_start_stage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) hw->x_end_stage, sw->x_highest_stage, hw->x_max_coord);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) sw->y_abs_pos = ad714x_cal_abs_pos(ad714x, hw->y_start_stage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) hw->y_end_stage, sw->y_highest_stage, hw->y_max_coord);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) dev_dbg(ad714x->dev, "touchpad %d absolute position:(%d, %d)\n", idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) sw->x_abs_pos, sw->y_abs_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static void touchpad_cal_flt_pos(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) sw->x_flt_pos = (sw->x_flt_pos * (10 - 4) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) sw->x_abs_pos * 4)/10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) sw->y_flt_pos = (sw->y_flt_pos * (10 - 4) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) sw->y_abs_pos * 4)/10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) dev_dbg(ad714x->dev, "touchpad %d filter position:(%d, %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) idx, sw->x_flt_pos, sw->y_flt_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * To prevent distortion from showing in the absolute position, it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * necessary to detect the end points. When endpoints are detected, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * driver stops updating the status variables with absolute positions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * End points are detected on the 4 edges of the touchpad sensor. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * method to detect them is the same for all 4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * To detect the end points, the firmware computes the difference in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * percent between the sensor on the edge and the adjacent one. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) * difference is calculated in percent in order to make the end point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * detection independent of the pressure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) #define LEFT_END_POINT_DETECTION_LEVEL 550
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) #define RIGHT_END_POINT_DETECTION_LEVEL 750
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) #define LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL 850
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) #define TOP_END_POINT_DETECTION_LEVEL 550
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) #define BOTTOM_END_POINT_DETECTION_LEVEL 950
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) #define TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL 700
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static int touchpad_check_endpoint(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) int percent_sensor_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) /* left endpoint detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) percent_sensor_diff = (ad714x->sensor_val[hw->x_start_stage] -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) ad714x->sensor_val[hw->x_start_stage + 1]) * 100 /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) ad714x->sensor_val[hw->x_start_stage + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (!sw->left_ep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (percent_sensor_diff >= LEFT_END_POINT_DETECTION_LEVEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) sw->left_ep = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) sw->left_ep_val =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) ad714x->sensor_val[hw->x_start_stage + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if ((percent_sensor_diff < LEFT_END_POINT_DETECTION_LEVEL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) (ad714x->sensor_val[hw->x_start_stage + 1] >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL + sw->left_ep_val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) sw->left_ep = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /* right endpoint detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) percent_sensor_diff = (ad714x->sensor_val[hw->x_end_stage] -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) ad714x->sensor_val[hw->x_end_stage - 1]) * 100 /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) ad714x->sensor_val[hw->x_end_stage - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (!sw->right_ep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (percent_sensor_diff >= RIGHT_END_POINT_DETECTION_LEVEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) sw->right_ep = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) sw->right_ep_val =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) ad714x->sensor_val[hw->x_end_stage - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if ((percent_sensor_diff < RIGHT_END_POINT_DETECTION_LEVEL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) (ad714x->sensor_val[hw->x_end_stage - 1] >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL + sw->right_ep_val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) sw->right_ep = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) /* top endpoint detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) percent_sensor_diff = (ad714x->sensor_val[hw->y_start_stage] -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) ad714x->sensor_val[hw->y_start_stage + 1]) * 100 /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) ad714x->sensor_val[hw->y_start_stage + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (!sw->top_ep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (percent_sensor_diff >= TOP_END_POINT_DETECTION_LEVEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) sw->top_ep = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) sw->top_ep_val =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) ad714x->sensor_val[hw->y_start_stage + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if ((percent_sensor_diff < TOP_END_POINT_DETECTION_LEVEL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) (ad714x->sensor_val[hw->y_start_stage + 1] >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL + sw->top_ep_val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) sw->top_ep = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) /* bottom endpoint detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) percent_sensor_diff = (ad714x->sensor_val[hw->y_end_stage] -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) ad714x->sensor_val[hw->y_end_stage - 1]) * 100 /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) ad714x->sensor_val[hw->y_end_stage - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (!sw->bottom_ep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (percent_sensor_diff >= BOTTOM_END_POINT_DETECTION_LEVEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) sw->bottom_ep = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) sw->bottom_ep_val =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) ad714x->sensor_val[hw->y_end_stage - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if ((percent_sensor_diff < BOTTOM_END_POINT_DETECTION_LEVEL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) (ad714x->sensor_val[hw->y_end_stage - 1] >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL + sw->bottom_ep_val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) sw->bottom_ep = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return sw->left_ep || sw->right_ep || sw->top_ep || sw->bottom_ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) static void touchpad_use_com_int(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) ad714x_use_com_int(ad714x, hw->x_start_stage, hw->x_end_stage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) static void touchpad_use_thr_int(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) ad714x_use_thr_int(ad714x, hw->x_start_stage, hw->x_end_stage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) ad714x_use_thr_int(ad714x, hw->y_start_stage, hw->y_end_stage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) static void ad714x_touchpad_state_machine(struct ad714x_chip *ad714x, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct ad714x_touchpad_drv *sw = &ad714x->sw->touchpad[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) unsigned short h_state, c_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) unsigned short mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) mask = (((1 << (hw->x_end_stage + 1)) - 1) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) ((1 << hw->x_start_stage) - 1)) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) (((1 << (hw->y_end_stage + 1)) - 1) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) ((1 << hw->y_start_stage) - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) h_state = ad714x->h_state & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) c_state = ad714x->c_state & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) switch (sw->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) case IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) if (h_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) sw->state = JITTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /* In End of Conversion interrupt mode, the AD714X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * continuously generates hardware interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) touchpad_use_com_int(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) dev_dbg(ad714x->dev, "touchpad %d touched\n", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) case JITTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (c_state == mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) touchpad_cal_sensor_val(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) touchpad_cal_highest_stage(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if ((!touchpad_check_second_peak(ad714x, idx)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) (!touchpad_check_endpoint(ad714x, idx))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) dev_dbg(ad714x->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) "touchpad%d, 2 fingers or endpoint\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) touchpad_cal_abs_pos(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) sw->x_flt_pos = sw->x_abs_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) sw->y_flt_pos = sw->y_abs_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) sw->state = ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) case ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (c_state == mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (h_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) touchpad_cal_sensor_val(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) touchpad_cal_highest_stage(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if ((!touchpad_check_second_peak(ad714x, idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) && (!touchpad_check_endpoint(ad714x, idx))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) touchpad_cal_abs_pos(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) touchpad_cal_flt_pos(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) input_report_abs(sw->input, ABS_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) sw->x_flt_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) input_report_abs(sw->input, ABS_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) sw->y_flt_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) input_report_key(sw->input, BTN_TOUCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /* When the user lifts off the sensor, configure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * the AD714X back to threshold interrupt mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) touchpad_use_thr_int(ad714x, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) sw->state = IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) input_report_key(sw->input, BTN_TOUCH, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) dev_dbg(ad714x->dev, "touchpad %d released\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) input_sync(sw->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) static int ad714x_hw_detect(struct ad714x_chip *ad714x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) unsigned short data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) ad714x->read(ad714x, AD714X_PARTID_REG, &data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) switch (data & 0xFFF0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) case AD7142_PARTID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) ad714x->product = 0x7142;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ad714x->version = data & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) dev_info(ad714x->dev, "found AD7142 captouch, rev:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) ad714x->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) case AD7143_PARTID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) ad714x->product = 0x7143;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ad714x->version = data & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) dev_info(ad714x->dev, "found AD7143 captouch, rev:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) ad714x->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) case AD7147_PARTID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) ad714x->product = 0x7147;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) ad714x->version = data & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) dev_info(ad714x->dev, "found AD7147(A) captouch, rev:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) ad714x->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) case AD7148_PARTID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) ad714x->product = 0x7148;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) ad714x->version = data & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) dev_info(ad714x->dev, "found AD7148 captouch, rev:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) ad714x->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) dev_err(ad714x->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) "fail to detect AD714X captouch, read ID is %04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) static void ad714x_hw_init(struct ad714x_chip *ad714x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) unsigned short reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) unsigned short data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) /* configuration CDC and interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) for (i = 0; i < STAGE_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) reg_base = AD714X_STAGECFG_REG + i * STAGE_CFGREG_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) for (j = 0; j < STAGE_CFGREG_NUM; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) ad714x->write(ad714x, reg_base + j,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) ad714x->hw->stage_cfg_reg[i][j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) for (i = 0; i < SYS_CFGREG_NUM; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) ad714x->write(ad714x, AD714X_SYSCFG_REG + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) ad714x->hw->sys_cfg_reg[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) for (i = 0; i < SYS_CFGREG_NUM; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) ad714x->read(ad714x, AD714X_SYSCFG_REG + i, &data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) ad714x->write(ad714x, AD714X_STG_CAL_EN_REG, 0xFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) /* clear all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) struct ad714x_chip *ad714x = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) mutex_lock(&ad714x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) for (i = 0; i < ad714x->hw->button_num; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) ad714x_button_state_machine(ad714x, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) for (i = 0; i < ad714x->hw->slider_num; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) ad714x_slider_state_machine(ad714x, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) for (i = 0; i < ad714x->hw->wheel_num; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) ad714x_wheel_state_machine(ad714x, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) for (i = 0; i < ad714x->hw->touchpad_num; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) ad714x_touchpad_state_machine(ad714x, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) mutex_unlock(&ad714x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) ad714x_read_t read, ad714x_write_t write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct ad714x_platform_data *plat_data = dev_get_platdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct ad714x_chip *ad714x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) void *drv_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) unsigned long irqflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) struct ad714x_button_drv *bt_drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) struct ad714x_slider_drv *sd_drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) struct ad714x_wheel_drv *wl_drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) struct ad714x_touchpad_drv *tp_drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) dev_err(dev, "IRQ not configured!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (dev_get_platdata(dev) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) dev_err(dev, "platform data for ad714x doesn't exist\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) ad714x = devm_kzalloc(dev, sizeof(*ad714x) + sizeof(*ad714x->sw) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) sizeof(*sd_drv) * plat_data->slider_num +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) sizeof(*wl_drv) * plat_data->wheel_num +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) sizeof(*tp_drv) * plat_data->touchpad_num +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) sizeof(*bt_drv) * plat_data->button_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (!ad714x) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) ad714x->hw = plat_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) drv_mem = ad714x + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) ad714x->sw = drv_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) drv_mem += sizeof(*ad714x->sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) ad714x->sw->slider = sd_drv = drv_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) drv_mem += sizeof(*sd_drv) * ad714x->hw->slider_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) ad714x->sw->wheel = wl_drv = drv_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) drv_mem += sizeof(*wl_drv) * ad714x->hw->wheel_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) ad714x->sw->touchpad = tp_drv = drv_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) drv_mem += sizeof(*tp_drv) * ad714x->hw->touchpad_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) ad714x->sw->button = bt_drv = drv_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) drv_mem += sizeof(*bt_drv) * ad714x->hw->button_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) ad714x->read = read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) ad714x->write = write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) ad714x->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) ad714x->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) error = ad714x_hw_detect(ad714x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) /* initialize and request sw/hw resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) ad714x_hw_init(ad714x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) mutex_init(&ad714x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /* a slider uses one input_dev instance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (ad714x->hw->slider_num > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) struct ad714x_slider_plat *sd_plat = ad714x->hw->slider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) for (i = 0; i < ad714x->hw->slider_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) input = devm_input_allocate_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (!input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) __set_bit(EV_ABS, input->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) __set_bit(EV_KEY, input->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) __set_bit(ABS_X, input->absbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) __set_bit(BTN_TOUCH, input->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) input_set_abs_params(input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) ABS_X, 0, sd_plat->max_coord, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) input->id.bustype = bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) input->id.product = ad714x->product;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) input->id.version = ad714x->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) input->name = "ad714x_captouch_slider";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) input->dev.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) error = input_register_device(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) sd_drv[i].input = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) /* a wheel uses one input_dev instance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (ad714x->hw->wheel_num > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) struct ad714x_wheel_plat *wl_plat = ad714x->hw->wheel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) for (i = 0; i < ad714x->hw->wheel_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) input = devm_input_allocate_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (!input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) __set_bit(EV_KEY, input->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) __set_bit(EV_ABS, input->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) __set_bit(ABS_WHEEL, input->absbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) __set_bit(BTN_TOUCH, input->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) input_set_abs_params(input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) ABS_WHEEL, 0, wl_plat->max_coord, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) input->id.bustype = bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) input->id.product = ad714x->product;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) input->id.version = ad714x->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) input->name = "ad714x_captouch_wheel";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) input->dev.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) error = input_register_device(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) wl_drv[i].input = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /* a touchpad uses one input_dev instance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (ad714x->hw->touchpad_num > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) struct ad714x_touchpad_plat *tp_plat = ad714x->hw->touchpad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) for (i = 0; i < ad714x->hw->touchpad_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) input = devm_input_allocate_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (!input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) __set_bit(EV_ABS, input->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) __set_bit(EV_KEY, input->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) __set_bit(ABS_X, input->absbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) __set_bit(ABS_Y, input->absbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) __set_bit(BTN_TOUCH, input->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) input_set_abs_params(input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) ABS_X, 0, tp_plat->x_max_coord, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) input_set_abs_params(input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) ABS_Y, 0, tp_plat->y_max_coord, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) input->id.bustype = bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) input->id.product = ad714x->product;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) input->id.version = ad714x->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) input->name = "ad714x_captouch_pad";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) input->dev.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) error = input_register_device(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) tp_drv[i].input = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /* all buttons use one input node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (ad714x->hw->button_num > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) struct ad714x_button_plat *bt_plat = ad714x->hw->button;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) input = devm_input_allocate_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if (!input) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) __set_bit(EV_KEY, input->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) for (i = 0; i < ad714x->hw->button_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) bt_drv[i].input = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) __set_bit(bt_plat[i].keycode, input->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) input->id.bustype = bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) input->id.product = ad714x->product;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) input->id.version = ad714x->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) input->name = "ad714x_captouch_button";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) input->dev.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) error = input_register_device(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) irqflags = plat_data->irqflags ?: IRQF_TRIGGER_FALLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) irqflags |= IRQF_ONESHOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) error = devm_request_threaded_irq(dev, ad714x->irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) ad714x_interrupt_thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) irqflags, "ad714x_captouch", ad714x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) dev_err(dev, "can't allocate irq %d\n", ad714x->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return ad714x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) EXPORT_SYMBOL(ad714x_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) int ad714x_disable(struct ad714x_chip *ad714x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) unsigned short data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) dev_dbg(ad714x->dev, "%s enter\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) mutex_lock(&ad714x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) data = ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL] | 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) ad714x->write(ad714x, AD714X_PWR_CTRL, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) mutex_unlock(&ad714x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) EXPORT_SYMBOL(ad714x_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) int ad714x_enable(struct ad714x_chip *ad714x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) dev_dbg(ad714x->dev, "%s enter\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) mutex_lock(&ad714x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /* resume to non-shutdown mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) ad714x->write(ad714x, AD714X_PWR_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) /* make sure the interrupt output line is not low level after resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) * otherwise we will get no chance to enter falling-edge irq again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) mutex_unlock(&ad714x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) EXPORT_SYMBOL(ad714x_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) MODULE_LICENSE("GPL");