1*9c92ab61SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2c7efd123SYoichi Yuasa /* 3c7efd123SYoichi Yuasa * ROHM BU21023/24 Dual touch support resistive touch screen driver 4c7efd123SYoichi Yuasa * Copyright (C) 2012 ROHM CO.,LTD. 5c7efd123SYoichi Yuasa */ 6c7efd123SYoichi Yuasa #include <linux/delay.h> 7c7efd123SYoichi Yuasa #include <linux/firmware.h> 8c7efd123SYoichi Yuasa #include <linux/i2c.h> 9c7efd123SYoichi Yuasa #include <linux/input.h> 10c7efd123SYoichi Yuasa #include <linux/input/mt.h> 11c7efd123SYoichi Yuasa #include <linux/interrupt.h> 12c7efd123SYoichi Yuasa #include <linux/module.h> 13c7efd123SYoichi Yuasa #include <linux/slab.h> 14c7efd123SYoichi Yuasa 15c7efd123SYoichi Yuasa #define BU21023_NAME "bu21023_ts" 16c7efd123SYoichi Yuasa #define BU21023_FIRMWARE_NAME "bu21023.bin" 17c7efd123SYoichi Yuasa 18c7efd123SYoichi Yuasa #define MAX_CONTACTS 2 19c7efd123SYoichi Yuasa 20c7efd123SYoichi Yuasa #define AXIS_ADJUST 4 21c7efd123SYoichi Yuasa #define AXIS_OFFSET 8 22c7efd123SYoichi Yuasa 23c7efd123SYoichi Yuasa #define FIRMWARE_BLOCK_SIZE 32U 24c7efd123SYoichi Yuasa #define FIRMWARE_RETRY_MAX 4 25c7efd123SYoichi Yuasa 26c7efd123SYoichi Yuasa #define SAMPLING_DELAY 12 /* msec */ 27c7efd123SYoichi Yuasa 28c7efd123SYoichi Yuasa #define CALIBRATION_RETRY_MAX 6 29c7efd123SYoichi Yuasa 30c7efd123SYoichi Yuasa #define ROHM_TS_ABS_X_MIN 40 31c7efd123SYoichi Yuasa #define ROHM_TS_ABS_X_MAX 990 32c7efd123SYoichi Yuasa #define ROHM_TS_ABS_Y_MIN 160 33c7efd123SYoichi Yuasa #define ROHM_TS_ABS_Y_MAX 920 34c7efd123SYoichi Yuasa #define ROHM_TS_DISPLACEMENT_MAX 0 /* zero for infinite */ 35c7efd123SYoichi Yuasa 36c7efd123SYoichi Yuasa /* 37c7efd123SYoichi Yuasa * BU21023GUL/BU21023MUV/BU21024FV-M registers map 38c7efd123SYoichi Yuasa */ 39c7efd123SYoichi Yuasa #define VADOUT_YP_H 0x00 40c7efd123SYoichi Yuasa #define VADOUT_YP_L 0x01 41c7efd123SYoichi Yuasa #define VADOUT_XP_H 0x02 42c7efd123SYoichi Yuasa #define VADOUT_XP_L 0x03 43c7efd123SYoichi Yuasa #define VADOUT_YN_H 0x04 44c7efd123SYoichi Yuasa #define VADOUT_YN_L 0x05 45c7efd123SYoichi Yuasa #define VADOUT_XN_H 0x06 46c7efd123SYoichi Yuasa #define VADOUT_XN_L 0x07 47c7efd123SYoichi Yuasa 48c7efd123SYoichi Yuasa #define PRM1_X_H 0x08 49c7efd123SYoichi Yuasa #define PRM1_X_L 0x09 50c7efd123SYoichi Yuasa #define PRM1_Y_H 0x0a 51c7efd123SYoichi Yuasa #define PRM1_Y_L 0x0b 52c7efd123SYoichi Yuasa #define PRM2_X_H 0x0c 53c7efd123SYoichi Yuasa #define PRM2_X_L 0x0d 54c7efd123SYoichi Yuasa #define PRM2_Y_H 0x0e 55c7efd123SYoichi Yuasa #define PRM2_Y_L 0x0f 56c7efd123SYoichi Yuasa 57c7efd123SYoichi Yuasa #define MLT_PRM_MONI_X 0x10 58c7efd123SYoichi Yuasa #define MLT_PRM_MONI_Y 0x11 59c7efd123SYoichi Yuasa 60c7efd123SYoichi Yuasa #define DEBUG_MONI_1 0x12 61c7efd123SYoichi Yuasa #define DEBUG_MONI_2 0x13 62c7efd123SYoichi Yuasa 63c7efd123SYoichi Yuasa #define VADOUT_ZX_H 0x14 64c7efd123SYoichi Yuasa #define VADOUT_ZX_L 0x15 65c7efd123SYoichi Yuasa #define VADOUT_ZY_H 0x16 66c7efd123SYoichi Yuasa #define VADOUT_ZY_L 0x17 67c7efd123SYoichi Yuasa 68c7efd123SYoichi Yuasa #define Z_PARAM_H 0x18 69c7efd123SYoichi Yuasa #define Z_PARAM_L 0x19 70c7efd123SYoichi Yuasa 71c7efd123SYoichi Yuasa /* 72c7efd123SYoichi Yuasa * Value for VADOUT_*_L 73c7efd123SYoichi Yuasa */ 74c7efd123SYoichi Yuasa #define VADOUT_L_MASK 0x01 75c7efd123SYoichi Yuasa 76c7efd123SYoichi Yuasa /* 77c7efd123SYoichi Yuasa * Value for PRM*_*_L 78c7efd123SYoichi Yuasa */ 79c7efd123SYoichi Yuasa #define PRM_L_MASK 0x01 80c7efd123SYoichi Yuasa 81c7efd123SYoichi Yuasa #define POS_X1_H 0x20 82c7efd123SYoichi Yuasa #define POS_X1_L 0x21 83c7efd123SYoichi Yuasa #define POS_Y1_H 0x22 84c7efd123SYoichi Yuasa #define POS_Y1_L 0x23 85c7efd123SYoichi Yuasa #define POS_X2_H 0x24 86c7efd123SYoichi Yuasa #define POS_X2_L 0x25 87c7efd123SYoichi Yuasa #define POS_Y2_H 0x26 88c7efd123SYoichi Yuasa #define POS_Y2_L 0x27 89c7efd123SYoichi Yuasa 90c7efd123SYoichi Yuasa /* 91c7efd123SYoichi Yuasa * Value for POS_*_L 92c7efd123SYoichi Yuasa */ 93c7efd123SYoichi Yuasa #define POS_L_MASK 0x01 94c7efd123SYoichi Yuasa 95c7efd123SYoichi Yuasa #define TOUCH 0x28 96c7efd123SYoichi Yuasa #define TOUCH_DETECT 0x01 97c7efd123SYoichi Yuasa 98c7efd123SYoichi Yuasa #define TOUCH_GESTURE 0x29 99c7efd123SYoichi Yuasa #define SINGLE_TOUCH 0x01 100c7efd123SYoichi Yuasa #define DUAL_TOUCH 0x03 101c7efd123SYoichi Yuasa #define TOUCH_MASK 0x03 102c7efd123SYoichi Yuasa #define CALIBRATION_REQUEST 0x04 103c7efd123SYoichi Yuasa #define CALIBRATION_STATUS 0x08 104c7efd123SYoichi Yuasa #define CALIBRATION_MASK 0x0c 105c7efd123SYoichi Yuasa #define GESTURE_SPREAD 0x10 106c7efd123SYoichi Yuasa #define GESTURE_PINCH 0x20 107c7efd123SYoichi Yuasa #define GESTURE_ROTATE_R 0x40 108c7efd123SYoichi Yuasa #define GESTURE_ROTATE_L 0x80 109c7efd123SYoichi Yuasa 110c7efd123SYoichi Yuasa #define INT_STATUS 0x2a 111c7efd123SYoichi Yuasa #define INT_MASK 0x3d 112c7efd123SYoichi Yuasa #define INT_CLEAR 0x3e 113c7efd123SYoichi Yuasa 114c7efd123SYoichi Yuasa /* 115c7efd123SYoichi Yuasa * Values for INT_* 116c7efd123SYoichi Yuasa */ 117c7efd123SYoichi Yuasa #define COORD_UPDATE 0x01 118c7efd123SYoichi Yuasa #define CALIBRATION_DONE 0x02 119c7efd123SYoichi Yuasa #define SLEEP_IN 0x04 120c7efd123SYoichi Yuasa #define SLEEP_OUT 0x08 121c7efd123SYoichi Yuasa #define PROGRAM_LOAD_DONE 0x10 122c7efd123SYoichi Yuasa #define ERROR 0x80 123c7efd123SYoichi Yuasa #define INT_ALL 0x9f 124c7efd123SYoichi Yuasa 125c7efd123SYoichi Yuasa #define ERR_STATUS 0x2b 126c7efd123SYoichi Yuasa #define ERR_MASK 0x3f 127c7efd123SYoichi Yuasa 128c7efd123SYoichi Yuasa /* 129c7efd123SYoichi Yuasa * Values for ERR_* 130c7efd123SYoichi Yuasa */ 131c7efd123SYoichi Yuasa #define ADC_TIMEOUT 0x01 132c7efd123SYoichi Yuasa #define CPU_TIMEOUT 0x02 133c7efd123SYoichi Yuasa #define CALIBRATION_ERR 0x04 134c7efd123SYoichi Yuasa #define PROGRAM_LOAD_ERR 0x10 135c7efd123SYoichi Yuasa 136c7efd123SYoichi Yuasa #define COMMON_SETUP1 0x30 137c7efd123SYoichi Yuasa #define PROGRAM_LOAD_HOST 0x02 138c7efd123SYoichi Yuasa #define PROGRAM_LOAD_EEPROM 0x03 139c7efd123SYoichi Yuasa #define CENSOR_4PORT 0x04 140c7efd123SYoichi Yuasa #define CENSOR_8PORT 0x00 /* Not supported by BU21023 */ 141c7efd123SYoichi Yuasa #define CALIBRATION_TYPE_DEFAULT 0x08 142c7efd123SYoichi Yuasa #define CALIBRATION_TYPE_SPECIAL 0x00 143c7efd123SYoichi Yuasa #define INT_ACTIVE_HIGH 0x10 144c7efd123SYoichi Yuasa #define INT_ACTIVE_LOW 0x00 145c7efd123SYoichi Yuasa #define AUTO_CALIBRATION 0x40 146c7efd123SYoichi Yuasa #define MANUAL_CALIBRATION 0x00 147c7efd123SYoichi Yuasa #define COMMON_SETUP1_DEFAULT 0x4e 148c7efd123SYoichi Yuasa 149c7efd123SYoichi Yuasa #define COMMON_SETUP2 0x31 150c7efd123SYoichi Yuasa #define MAF_NONE 0x00 151c7efd123SYoichi Yuasa #define MAF_1SAMPLE 0x01 152c7efd123SYoichi Yuasa #define MAF_3SAMPLES 0x02 153c7efd123SYoichi Yuasa #define MAF_5SAMPLES 0x03 154c7efd123SYoichi Yuasa #define INV_Y 0x04 155c7efd123SYoichi Yuasa #define INV_X 0x08 156c7efd123SYoichi Yuasa #define SWAP_XY 0x10 157c7efd123SYoichi Yuasa 158c7efd123SYoichi Yuasa #define COMMON_SETUP3 0x32 159c7efd123SYoichi Yuasa #define EN_SLEEP 0x01 160c7efd123SYoichi Yuasa #define EN_MULTI 0x02 161c7efd123SYoichi Yuasa #define EN_GESTURE 0x04 162c7efd123SYoichi Yuasa #define EN_INTVL 0x08 163c7efd123SYoichi Yuasa #define SEL_STEP 0x10 164c7efd123SYoichi Yuasa #define SEL_MULTI 0x20 165c7efd123SYoichi Yuasa #define SEL_TBL_DEFAULT 0x40 166c7efd123SYoichi Yuasa 167c7efd123SYoichi Yuasa #define INTERVAL_TIME 0x33 168c7efd123SYoichi Yuasa #define INTERVAL_TIME_DEFAULT 0x10 169c7efd123SYoichi Yuasa 170c7efd123SYoichi Yuasa #define STEP_X 0x34 171c7efd123SYoichi Yuasa #define STEP_X_DEFAULT 0x41 172c7efd123SYoichi Yuasa 173c7efd123SYoichi Yuasa #define STEP_Y 0x35 174c7efd123SYoichi Yuasa #define STEP_Y_DEFAULT 0x8d 175c7efd123SYoichi Yuasa 176c7efd123SYoichi Yuasa #define OFFSET_X 0x38 177c7efd123SYoichi Yuasa #define OFFSET_X_DEFAULT 0x0c 178c7efd123SYoichi Yuasa 179c7efd123SYoichi Yuasa #define OFFSET_Y 0x39 180c7efd123SYoichi Yuasa #define OFFSET_Y_DEFAULT 0x0c 181c7efd123SYoichi Yuasa 182c7efd123SYoichi Yuasa #define THRESHOLD_TOUCH 0x3a 183c7efd123SYoichi Yuasa #define THRESHOLD_TOUCH_DEFAULT 0xa0 184c7efd123SYoichi Yuasa 185c7efd123SYoichi Yuasa #define THRESHOLD_GESTURE 0x3b 186c7efd123SYoichi Yuasa #define THRESHOLD_GESTURE_DEFAULT 0x17 187c7efd123SYoichi Yuasa 188c7efd123SYoichi Yuasa #define SYSTEM 0x40 189c7efd123SYoichi Yuasa #define ANALOG_POWER_ON 0x01 190c7efd123SYoichi Yuasa #define ANALOG_POWER_OFF 0x00 191c7efd123SYoichi Yuasa #define CPU_POWER_ON 0x02 192c7efd123SYoichi Yuasa #define CPU_POWER_OFF 0x00 193c7efd123SYoichi Yuasa 194c7efd123SYoichi Yuasa #define FORCE_CALIBRATION 0x42 195c7efd123SYoichi Yuasa #define FORCE_CALIBRATION_ON 0x01 196c7efd123SYoichi Yuasa #define FORCE_CALIBRATION_OFF 0x00 197c7efd123SYoichi Yuasa 198c7efd123SYoichi Yuasa #define CPU_FREQ 0x50 /* 10 / (reg + 1) MHz */ 199c7efd123SYoichi Yuasa #define CPU_FREQ_10MHZ 0x00 200c7efd123SYoichi Yuasa #define CPU_FREQ_5MHZ 0x01 201c7efd123SYoichi Yuasa #define CPU_FREQ_1MHZ 0x09 202c7efd123SYoichi Yuasa 203c7efd123SYoichi Yuasa #define EEPROM_ADDR 0x51 204c7efd123SYoichi Yuasa 205c7efd123SYoichi Yuasa #define CALIBRATION_ADJUST 0x52 206c7efd123SYoichi Yuasa #define CALIBRATION_ADJUST_DEFAULT 0x00 207c7efd123SYoichi Yuasa 208c7efd123SYoichi Yuasa #define THRESHOLD_SLEEP_IN 0x53 209c7efd123SYoichi Yuasa 210c7efd123SYoichi Yuasa #define EVR_XY 0x56 211c7efd123SYoichi Yuasa #define EVR_XY_DEFAULT 0x10 212c7efd123SYoichi Yuasa 213c7efd123SYoichi Yuasa #define PRM_SWOFF_TIME 0x57 214c7efd123SYoichi Yuasa #define PRM_SWOFF_TIME_DEFAULT 0x04 215c7efd123SYoichi Yuasa 216c7efd123SYoichi Yuasa #define PROGRAM_VERSION 0x5f 217c7efd123SYoichi Yuasa 218c7efd123SYoichi Yuasa #define ADC_CTRL 0x60 219c7efd123SYoichi Yuasa #define ADC_DIV_MASK 0x1f /* The minimum value is 4 */ 220c7efd123SYoichi Yuasa #define ADC_DIV_DEFAULT 0x08 221c7efd123SYoichi Yuasa 222c7efd123SYoichi Yuasa #define ADC_WAIT 0x61 223c7efd123SYoichi Yuasa #define ADC_WAIT_DEFAULT 0x0a 224c7efd123SYoichi Yuasa 225c7efd123SYoichi Yuasa #define SWCONT 0x62 226c7efd123SYoichi Yuasa #define SWCONT_DEFAULT 0x0f 227c7efd123SYoichi Yuasa 228c7efd123SYoichi Yuasa #define EVR_X 0x63 229c7efd123SYoichi Yuasa #define EVR_X_DEFAULT 0x86 230c7efd123SYoichi Yuasa 231c7efd123SYoichi Yuasa #define EVR_Y 0x64 232c7efd123SYoichi Yuasa #define EVR_Y_DEFAULT 0x64 233c7efd123SYoichi Yuasa 234c7efd123SYoichi Yuasa #define TEST1 0x65 235c7efd123SYoichi Yuasa #define DUALTOUCH_STABILIZE_ON 0x01 236c7efd123SYoichi Yuasa #define DUALTOUCH_STABILIZE_OFF 0x00 237c7efd123SYoichi Yuasa #define DUALTOUCH_REG_ON 0x20 238c7efd123SYoichi Yuasa #define DUALTOUCH_REG_OFF 0x00 239c7efd123SYoichi Yuasa 240c7efd123SYoichi Yuasa #define CALIBRATION_REG1 0x68 241c7efd123SYoichi Yuasa #define CALIBRATION_REG1_DEFAULT 0xd9 242c7efd123SYoichi Yuasa 243c7efd123SYoichi Yuasa #define CALIBRATION_REG2 0x69 244c7efd123SYoichi Yuasa #define CALIBRATION_REG2_DEFAULT 0x36 245c7efd123SYoichi Yuasa 246c7efd123SYoichi Yuasa #define CALIBRATION_REG3 0x6a 247c7efd123SYoichi Yuasa #define CALIBRATION_REG3_DEFAULT 0x32 248c7efd123SYoichi Yuasa 249c7efd123SYoichi Yuasa #define EX_ADDR_H 0x70 250c7efd123SYoichi Yuasa #define EX_ADDR_L 0x71 251c7efd123SYoichi Yuasa #define EX_WDAT 0x72 252c7efd123SYoichi Yuasa #define EX_RDAT 0x73 253c7efd123SYoichi Yuasa #define EX_CHK_SUM1 0x74 254c7efd123SYoichi Yuasa #define EX_CHK_SUM2 0x75 255c7efd123SYoichi Yuasa #define EX_CHK_SUM3 0x76 256c7efd123SYoichi Yuasa 257c7efd123SYoichi Yuasa struct rohm_ts_data { 258c7efd123SYoichi Yuasa struct i2c_client *client; 259c7efd123SYoichi Yuasa struct input_dev *input; 260c7efd123SYoichi Yuasa 261c7efd123SYoichi Yuasa bool initialized; 262c7efd123SYoichi Yuasa 263c7efd123SYoichi Yuasa unsigned int contact_count[MAX_CONTACTS + 1]; 264c7efd123SYoichi Yuasa int finger_count; 265c7efd123SYoichi Yuasa 266c7efd123SYoichi Yuasa u8 setup2; 267c7efd123SYoichi Yuasa }; 268c7efd123SYoichi Yuasa 269c7efd123SYoichi Yuasa /* 270c7efd123SYoichi Yuasa * rohm_i2c_burst_read - execute combined I2C message for ROHM BU21023/24 271c7efd123SYoichi Yuasa * @client: Handle to ROHM BU21023/24 272c7efd123SYoichi Yuasa * @start: Where to start read address from ROHM BU21023/24 273c7efd123SYoichi Yuasa * @buf: Where to store read data from ROHM BU21023/24 274c7efd123SYoichi Yuasa * @len: How many bytes to read 275c7efd123SYoichi Yuasa * 276c7efd123SYoichi Yuasa * Returns negative errno, else zero on success. 277c7efd123SYoichi Yuasa * 278c7efd123SYoichi Yuasa * Note 279c7efd123SYoichi Yuasa * In BU21023/24 burst read, stop condition is needed after "address write". 280c7efd123SYoichi Yuasa * Therefore, transmission is performed in 2 steps. 281c7efd123SYoichi Yuasa */ 282c7efd123SYoichi Yuasa static int rohm_i2c_burst_read(struct i2c_client *client, u8 start, void *buf, 283c7efd123SYoichi Yuasa size_t len) 284c7efd123SYoichi Yuasa { 285c7efd123SYoichi Yuasa struct i2c_adapter *adap = client->adapter; 286c7efd123SYoichi Yuasa struct i2c_msg msg[2]; 287c7efd123SYoichi Yuasa int i, ret = 0; 288c7efd123SYoichi Yuasa 289c7efd123SYoichi Yuasa msg[0].addr = client->addr; 290c7efd123SYoichi Yuasa msg[0].flags = 0; 291c7efd123SYoichi Yuasa msg[0].len = 1; 292c7efd123SYoichi Yuasa msg[0].buf = &start; 293c7efd123SYoichi Yuasa 294c7efd123SYoichi Yuasa msg[1].addr = client->addr; 295c7efd123SYoichi Yuasa msg[1].flags = I2C_M_RD; 296c7efd123SYoichi Yuasa msg[1].len = len; 297c7efd123SYoichi Yuasa msg[1].buf = buf; 298c7efd123SYoichi Yuasa 299193c2a07SPeter Rosin i2c_lock_bus(adap, I2C_LOCK_SEGMENT); 300c7efd123SYoichi Yuasa 301c7efd123SYoichi Yuasa for (i = 0; i < 2; i++) { 302c7efd123SYoichi Yuasa if (__i2c_transfer(adap, &msg[i], 1) < 0) { 303c7efd123SYoichi Yuasa ret = -EIO; 304c7efd123SYoichi Yuasa break; 305c7efd123SYoichi Yuasa } 306c7efd123SYoichi Yuasa } 307c7efd123SYoichi Yuasa 308193c2a07SPeter Rosin i2c_unlock_bus(adap, I2C_LOCK_SEGMENT); 309c7efd123SYoichi Yuasa 310c7efd123SYoichi Yuasa return ret; 311c7efd123SYoichi Yuasa } 312c7efd123SYoichi Yuasa 313c7efd123SYoichi Yuasa static int rohm_ts_manual_calibration(struct rohm_ts_data *ts) 314c7efd123SYoichi Yuasa { 315c7efd123SYoichi Yuasa struct i2c_client *client = ts->client; 316c7efd123SYoichi Yuasa struct device *dev = &client->dev; 317c7efd123SYoichi Yuasa u8 buf[33]; /* for PRM1_X_H(0x08)-TOUCH(0x28) */ 318c7efd123SYoichi Yuasa 319c7efd123SYoichi Yuasa int retry; 320c7efd123SYoichi Yuasa bool success = false; 321c7efd123SYoichi Yuasa bool first_time = true; 322c7efd123SYoichi Yuasa bool calibration_done; 323c7efd123SYoichi Yuasa 324c7efd123SYoichi Yuasa u8 reg1, reg2, reg3; 325c7efd123SYoichi Yuasa s32 reg1_orig, reg2_orig, reg3_orig; 326c7efd123SYoichi Yuasa s32 val; 327c7efd123SYoichi Yuasa 328c7efd123SYoichi Yuasa int calib_x = 0, calib_y = 0; 329c7efd123SYoichi Yuasa int reg_x, reg_y; 330c7efd123SYoichi Yuasa int err_x, err_y; 331c7efd123SYoichi Yuasa 332c7efd123SYoichi Yuasa int error, error2; 333c7efd123SYoichi Yuasa int i; 334c7efd123SYoichi Yuasa 335c7efd123SYoichi Yuasa reg1_orig = i2c_smbus_read_byte_data(client, CALIBRATION_REG1); 336c7efd123SYoichi Yuasa if (reg1_orig < 0) 337c7efd123SYoichi Yuasa return reg1_orig; 338c7efd123SYoichi Yuasa 339c7efd123SYoichi Yuasa reg2_orig = i2c_smbus_read_byte_data(client, CALIBRATION_REG2); 340c7efd123SYoichi Yuasa if (reg2_orig < 0) 341c7efd123SYoichi Yuasa return reg2_orig; 342c7efd123SYoichi Yuasa 343c7efd123SYoichi Yuasa reg3_orig = i2c_smbus_read_byte_data(client, CALIBRATION_REG3); 344c7efd123SYoichi Yuasa if (reg3_orig < 0) 345c7efd123SYoichi Yuasa return reg3_orig; 346c7efd123SYoichi Yuasa 347c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_MASK, 348c7efd123SYoichi Yuasa COORD_UPDATE | SLEEP_IN | SLEEP_OUT | 349c7efd123SYoichi Yuasa PROGRAM_LOAD_DONE); 350c7efd123SYoichi Yuasa if (error) 351c7efd123SYoichi Yuasa goto out; 352c7efd123SYoichi Yuasa 353c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, TEST1, 354c7efd123SYoichi Yuasa DUALTOUCH_STABILIZE_ON); 355c7efd123SYoichi Yuasa if (error) 356c7efd123SYoichi Yuasa goto out; 357c7efd123SYoichi Yuasa 358c7efd123SYoichi Yuasa for (retry = 0; retry < CALIBRATION_RETRY_MAX; retry++) { 359c7efd123SYoichi Yuasa /* wait 2 sampling for update */ 360c7efd123SYoichi Yuasa mdelay(2 * SAMPLING_DELAY); 361c7efd123SYoichi Yuasa 362c7efd123SYoichi Yuasa #define READ_CALIB_BUF(reg) buf[((reg) - PRM1_X_H)] 363c7efd123SYoichi Yuasa 364c7efd123SYoichi Yuasa error = rohm_i2c_burst_read(client, PRM1_X_H, buf, sizeof(buf)); 365c7efd123SYoichi Yuasa if (error) 366c7efd123SYoichi Yuasa goto out; 367c7efd123SYoichi Yuasa 368c7efd123SYoichi Yuasa if (READ_CALIB_BUF(TOUCH) & TOUCH_DETECT) 369c7efd123SYoichi Yuasa continue; 370c7efd123SYoichi Yuasa 371c7efd123SYoichi Yuasa if (first_time) { 372c7efd123SYoichi Yuasa /* generate calibration parameter */ 373c7efd123SYoichi Yuasa calib_x = ((int)READ_CALIB_BUF(PRM1_X_H) << 2 | 374c7efd123SYoichi Yuasa READ_CALIB_BUF(PRM1_X_L)) - AXIS_OFFSET; 375c7efd123SYoichi Yuasa calib_y = ((int)READ_CALIB_BUF(PRM1_Y_H) << 2 | 376c7efd123SYoichi Yuasa READ_CALIB_BUF(PRM1_Y_L)) - AXIS_OFFSET; 377c7efd123SYoichi Yuasa 378c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, TEST1, 379c7efd123SYoichi Yuasa DUALTOUCH_STABILIZE_ON | DUALTOUCH_REG_ON); 380c7efd123SYoichi Yuasa if (error) 381c7efd123SYoichi Yuasa goto out; 382c7efd123SYoichi Yuasa 383c7efd123SYoichi Yuasa first_time = false; 384c7efd123SYoichi Yuasa } else { 385c7efd123SYoichi Yuasa /* generate adjustment parameter */ 386c7efd123SYoichi Yuasa err_x = (int)READ_CALIB_BUF(PRM1_X_H) << 2 | 387c7efd123SYoichi Yuasa READ_CALIB_BUF(PRM1_X_L); 388c7efd123SYoichi Yuasa err_y = (int)READ_CALIB_BUF(PRM1_Y_H) << 2 | 389c7efd123SYoichi Yuasa READ_CALIB_BUF(PRM1_Y_L); 390c7efd123SYoichi Yuasa 391c7efd123SYoichi Yuasa /* X axis ajust */ 392c7efd123SYoichi Yuasa if (err_x <= 4) 393c7efd123SYoichi Yuasa calib_x -= AXIS_ADJUST; 394c7efd123SYoichi Yuasa else if (err_x >= 60) 395c7efd123SYoichi Yuasa calib_x += AXIS_ADJUST; 396c7efd123SYoichi Yuasa 397c7efd123SYoichi Yuasa /* Y axis ajust */ 398c7efd123SYoichi Yuasa if (err_y <= 4) 399c7efd123SYoichi Yuasa calib_y -= AXIS_ADJUST; 400c7efd123SYoichi Yuasa else if (err_y >= 60) 401c7efd123SYoichi Yuasa calib_y += AXIS_ADJUST; 402c7efd123SYoichi Yuasa } 403c7efd123SYoichi Yuasa 404c7efd123SYoichi Yuasa /* generate calibration setting value */ 405c7efd123SYoichi Yuasa reg_x = calib_x + ((calib_x & 0x200) << 1); 406c7efd123SYoichi Yuasa reg_y = calib_y + ((calib_y & 0x200) << 1); 407c7efd123SYoichi Yuasa 408c7efd123SYoichi Yuasa /* convert for register format */ 409c7efd123SYoichi Yuasa reg1 = reg_x >> 3; 410c7efd123SYoichi Yuasa reg2 = (reg_y & 0x7) << 4 | (reg_x & 0x7); 411c7efd123SYoichi Yuasa reg3 = reg_y >> 3; 412c7efd123SYoichi Yuasa 413c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, 414c7efd123SYoichi Yuasa CALIBRATION_REG1, reg1); 415c7efd123SYoichi Yuasa if (error) 416c7efd123SYoichi Yuasa goto out; 417c7efd123SYoichi Yuasa 418c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, 419c7efd123SYoichi Yuasa CALIBRATION_REG2, reg2); 420c7efd123SYoichi Yuasa if (error) 421c7efd123SYoichi Yuasa goto out; 422c7efd123SYoichi Yuasa 423c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, 424c7efd123SYoichi Yuasa CALIBRATION_REG3, reg3); 425c7efd123SYoichi Yuasa if (error) 426c7efd123SYoichi Yuasa goto out; 427c7efd123SYoichi Yuasa 428c7efd123SYoichi Yuasa /* 429c7efd123SYoichi Yuasa * force calibration sequcence 430c7efd123SYoichi Yuasa */ 431c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, FORCE_CALIBRATION, 432c7efd123SYoichi Yuasa FORCE_CALIBRATION_OFF); 433c7efd123SYoichi Yuasa if (error) 434c7efd123SYoichi Yuasa goto out; 435c7efd123SYoichi Yuasa 436c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, FORCE_CALIBRATION, 437c7efd123SYoichi Yuasa FORCE_CALIBRATION_ON); 438c7efd123SYoichi Yuasa if (error) 439c7efd123SYoichi Yuasa goto out; 440c7efd123SYoichi Yuasa 441c7efd123SYoichi Yuasa /* clear all interrupts */ 442c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff); 443c7efd123SYoichi Yuasa if (error) 444c7efd123SYoichi Yuasa goto out; 445c7efd123SYoichi Yuasa 446c7efd123SYoichi Yuasa /* 447c7efd123SYoichi Yuasa * Wait for the status change of calibration, max 10 sampling 448c7efd123SYoichi Yuasa */ 449c7efd123SYoichi Yuasa calibration_done = false; 450c7efd123SYoichi Yuasa 451c7efd123SYoichi Yuasa for (i = 0; i < 10; i++) { 452c7efd123SYoichi Yuasa mdelay(SAMPLING_DELAY); 453c7efd123SYoichi Yuasa 454c7efd123SYoichi Yuasa val = i2c_smbus_read_byte_data(client, TOUCH_GESTURE); 455c7efd123SYoichi Yuasa if (!(val & CALIBRATION_MASK)) { 456c7efd123SYoichi Yuasa calibration_done = true; 457c7efd123SYoichi Yuasa break; 458c7efd123SYoichi Yuasa } else if (val < 0) { 459c7efd123SYoichi Yuasa error = val; 460c7efd123SYoichi Yuasa goto out; 461c7efd123SYoichi Yuasa } 462c7efd123SYoichi Yuasa } 463c7efd123SYoichi Yuasa 464c7efd123SYoichi Yuasa if (calibration_done) { 465c7efd123SYoichi Yuasa val = i2c_smbus_read_byte_data(client, INT_STATUS); 466c7efd123SYoichi Yuasa if (val == CALIBRATION_DONE) { 467c7efd123SYoichi Yuasa success = true; 468c7efd123SYoichi Yuasa break; 469c7efd123SYoichi Yuasa } else if (val < 0) { 470c7efd123SYoichi Yuasa error = val; 471c7efd123SYoichi Yuasa goto out; 472c7efd123SYoichi Yuasa } 473c7efd123SYoichi Yuasa } else { 474c7efd123SYoichi Yuasa dev_warn(dev, "calibration timeout\n"); 475c7efd123SYoichi Yuasa } 476c7efd123SYoichi Yuasa } 477c7efd123SYoichi Yuasa 478c7efd123SYoichi Yuasa if (!success) { 479c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CALIBRATION_REG1, 480c7efd123SYoichi Yuasa reg1_orig); 481c7efd123SYoichi Yuasa if (error) 482c7efd123SYoichi Yuasa goto out; 483c7efd123SYoichi Yuasa 484c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CALIBRATION_REG2, 485c7efd123SYoichi Yuasa reg2_orig); 486c7efd123SYoichi Yuasa if (error) 487c7efd123SYoichi Yuasa goto out; 488c7efd123SYoichi Yuasa 489c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CALIBRATION_REG3, 490c7efd123SYoichi Yuasa reg3_orig); 491c7efd123SYoichi Yuasa if (error) 492c7efd123SYoichi Yuasa goto out; 493c7efd123SYoichi Yuasa 494c7efd123SYoichi Yuasa /* calibration data enable */ 495c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, TEST1, 496c7efd123SYoichi Yuasa DUALTOUCH_STABILIZE_ON | 497c7efd123SYoichi Yuasa DUALTOUCH_REG_ON); 498c7efd123SYoichi Yuasa if (error) 499c7efd123SYoichi Yuasa goto out; 500c7efd123SYoichi Yuasa 501c7efd123SYoichi Yuasa /* wait 10 sampling */ 502c7efd123SYoichi Yuasa mdelay(10 * SAMPLING_DELAY); 503c7efd123SYoichi Yuasa 504c7efd123SYoichi Yuasa error = -EBUSY; 505c7efd123SYoichi Yuasa } 506c7efd123SYoichi Yuasa 507c7efd123SYoichi Yuasa out: 508c7efd123SYoichi Yuasa error2 = i2c_smbus_write_byte_data(client, INT_MASK, INT_ALL); 509c7efd123SYoichi Yuasa if (!error2) 510c7efd123SYoichi Yuasa /* Clear all interrupts */ 511c7efd123SYoichi Yuasa error2 = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff); 512c7efd123SYoichi Yuasa 513c7efd123SYoichi Yuasa return error ? error : error2; 514c7efd123SYoichi Yuasa } 515c7efd123SYoichi Yuasa 516c7efd123SYoichi Yuasa static const unsigned int untouch_threshold[3] = { 0, 1, 5 }; 517c7efd123SYoichi Yuasa static const unsigned int single_touch_threshold[3] = { 0, 0, 4 }; 518c7efd123SYoichi Yuasa static const unsigned int dual_touch_threshold[3] = { 10, 8, 0 }; 519c7efd123SYoichi Yuasa 520c7efd123SYoichi Yuasa static irqreturn_t rohm_ts_soft_irq(int irq, void *dev_id) 521c7efd123SYoichi Yuasa { 522c7efd123SYoichi Yuasa struct rohm_ts_data *ts = dev_id; 523c7efd123SYoichi Yuasa struct i2c_client *client = ts->client; 524c7efd123SYoichi Yuasa struct input_dev *input_dev = ts->input; 525c7efd123SYoichi Yuasa struct device *dev = &client->dev; 526c7efd123SYoichi Yuasa 527c7efd123SYoichi Yuasa u8 buf[10]; /* for POS_X1_H(0x20)-TOUCH_GESTURE(0x29) */ 528c7efd123SYoichi Yuasa 529c7efd123SYoichi Yuasa struct input_mt_pos pos[MAX_CONTACTS]; 530c7efd123SYoichi Yuasa int slots[MAX_CONTACTS]; 531c7efd123SYoichi Yuasa u8 touch_flags; 532c7efd123SYoichi Yuasa unsigned int threshold; 533c7efd123SYoichi Yuasa int finger_count = -1; 534c7efd123SYoichi Yuasa int prev_finger_count = ts->finger_count; 535c7efd123SYoichi Yuasa int count; 536c7efd123SYoichi Yuasa int error; 537c7efd123SYoichi Yuasa int i; 538c7efd123SYoichi Yuasa 539c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_MASK, INT_ALL); 540c7efd123SYoichi Yuasa if (error) 541c7efd123SYoichi Yuasa return IRQ_HANDLED; 542c7efd123SYoichi Yuasa 543c7efd123SYoichi Yuasa /* Clear all interrupts */ 544c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff); 545c7efd123SYoichi Yuasa if (error) 546c7efd123SYoichi Yuasa return IRQ_HANDLED; 547c7efd123SYoichi Yuasa 548c7efd123SYoichi Yuasa #define READ_POS_BUF(reg) buf[((reg) - POS_X1_H)] 549c7efd123SYoichi Yuasa 550c7efd123SYoichi Yuasa error = rohm_i2c_burst_read(client, POS_X1_H, buf, sizeof(buf)); 551c7efd123SYoichi Yuasa if (error) 552c7efd123SYoichi Yuasa return IRQ_HANDLED; 553c7efd123SYoichi Yuasa 554c7efd123SYoichi Yuasa touch_flags = READ_POS_BUF(TOUCH_GESTURE) & TOUCH_MASK; 555c7efd123SYoichi Yuasa if (touch_flags) { 556c7efd123SYoichi Yuasa /* generate coordinates */ 557c7efd123SYoichi Yuasa pos[0].x = ((s16)READ_POS_BUF(POS_X1_H) << 2) | 558c7efd123SYoichi Yuasa READ_POS_BUF(POS_X1_L); 559c7efd123SYoichi Yuasa pos[0].y = ((s16)READ_POS_BUF(POS_Y1_H) << 2) | 560c7efd123SYoichi Yuasa READ_POS_BUF(POS_Y1_L); 561c7efd123SYoichi Yuasa pos[1].x = ((s16)READ_POS_BUF(POS_X2_H) << 2) | 562c7efd123SYoichi Yuasa READ_POS_BUF(POS_X2_L); 563c7efd123SYoichi Yuasa pos[1].y = ((s16)READ_POS_BUF(POS_Y2_H) << 2) | 564c7efd123SYoichi Yuasa READ_POS_BUF(POS_Y2_L); 565c7efd123SYoichi Yuasa } 566c7efd123SYoichi Yuasa 567c7efd123SYoichi Yuasa switch (touch_flags) { 568c7efd123SYoichi Yuasa case 0: 569c7efd123SYoichi Yuasa threshold = untouch_threshold[prev_finger_count]; 570c7efd123SYoichi Yuasa if (++ts->contact_count[0] >= threshold) 571c7efd123SYoichi Yuasa finger_count = 0; 572c7efd123SYoichi Yuasa break; 573c7efd123SYoichi Yuasa 574c7efd123SYoichi Yuasa case SINGLE_TOUCH: 575c7efd123SYoichi Yuasa threshold = single_touch_threshold[prev_finger_count]; 576c7efd123SYoichi Yuasa if (++ts->contact_count[1] >= threshold) 577c7efd123SYoichi Yuasa finger_count = 1; 578c7efd123SYoichi Yuasa 579c7efd123SYoichi Yuasa if (finger_count == 1) { 580c7efd123SYoichi Yuasa if (pos[1].x != 0 && pos[1].y != 0) { 581c7efd123SYoichi Yuasa pos[0].x = pos[1].x; 582c7efd123SYoichi Yuasa pos[0].y = pos[1].y; 583c7efd123SYoichi Yuasa pos[1].x = 0; 584c7efd123SYoichi Yuasa pos[1].y = 0; 585c7efd123SYoichi Yuasa } 586c7efd123SYoichi Yuasa } 587c7efd123SYoichi Yuasa break; 588c7efd123SYoichi Yuasa 589c7efd123SYoichi Yuasa case DUAL_TOUCH: 590c7efd123SYoichi Yuasa threshold = dual_touch_threshold[prev_finger_count]; 591c7efd123SYoichi Yuasa if (++ts->contact_count[2] >= threshold) 592c7efd123SYoichi Yuasa finger_count = 2; 593c7efd123SYoichi Yuasa break; 594c7efd123SYoichi Yuasa 595c7efd123SYoichi Yuasa default: 596c7efd123SYoichi Yuasa dev_dbg(dev, 597c7efd123SYoichi Yuasa "Three or more touches are not supported\n"); 598c7efd123SYoichi Yuasa return IRQ_HANDLED; 599c7efd123SYoichi Yuasa } 600c7efd123SYoichi Yuasa 601c7efd123SYoichi Yuasa if (finger_count >= 0) { 602c7efd123SYoichi Yuasa if (prev_finger_count != finger_count) { 603c7efd123SYoichi Yuasa count = ts->contact_count[finger_count]; 604c7efd123SYoichi Yuasa memset(ts->contact_count, 0, sizeof(ts->contact_count)); 605c7efd123SYoichi Yuasa ts->contact_count[finger_count] = count; 606c7efd123SYoichi Yuasa } 607c7efd123SYoichi Yuasa 608c7efd123SYoichi Yuasa input_mt_assign_slots(input_dev, slots, pos, 609c7efd123SYoichi Yuasa finger_count, ROHM_TS_DISPLACEMENT_MAX); 610c7efd123SYoichi Yuasa 611c7efd123SYoichi Yuasa for (i = 0; i < finger_count; i++) { 612c7efd123SYoichi Yuasa input_mt_slot(input_dev, slots[i]); 613c7efd123SYoichi Yuasa input_mt_report_slot_state(input_dev, 614c7efd123SYoichi Yuasa MT_TOOL_FINGER, true); 615c7efd123SYoichi Yuasa input_report_abs(input_dev, 616c7efd123SYoichi Yuasa ABS_MT_POSITION_X, pos[i].x); 617c7efd123SYoichi Yuasa input_report_abs(input_dev, 618c7efd123SYoichi Yuasa ABS_MT_POSITION_Y, pos[i].y); 619c7efd123SYoichi Yuasa } 620c7efd123SYoichi Yuasa 621c7efd123SYoichi Yuasa input_mt_sync_frame(input_dev); 622c7efd123SYoichi Yuasa input_mt_report_pointer_emulation(input_dev, true); 623c7efd123SYoichi Yuasa input_sync(input_dev); 624c7efd123SYoichi Yuasa 625c7efd123SYoichi Yuasa ts->finger_count = finger_count; 626c7efd123SYoichi Yuasa } 627c7efd123SYoichi Yuasa 628c7efd123SYoichi Yuasa if (READ_POS_BUF(TOUCH_GESTURE) & CALIBRATION_REQUEST) { 629c7efd123SYoichi Yuasa error = rohm_ts_manual_calibration(ts); 630c7efd123SYoichi Yuasa if (error) 631c7efd123SYoichi Yuasa dev_warn(dev, "manual calibration failed: %d\n", 632c7efd123SYoichi Yuasa error); 633c7efd123SYoichi Yuasa } 634c7efd123SYoichi Yuasa 635c7efd123SYoichi Yuasa i2c_smbus_write_byte_data(client, INT_MASK, 636c7efd123SYoichi Yuasa CALIBRATION_DONE | SLEEP_OUT | SLEEP_IN | 637c7efd123SYoichi Yuasa PROGRAM_LOAD_DONE); 638c7efd123SYoichi Yuasa 639c7efd123SYoichi Yuasa return IRQ_HANDLED; 640c7efd123SYoichi Yuasa } 641c7efd123SYoichi Yuasa 642c7efd123SYoichi Yuasa static int rohm_ts_load_firmware(struct i2c_client *client, 643c7efd123SYoichi Yuasa const char *firmware_name) 644c7efd123SYoichi Yuasa { 645c7efd123SYoichi Yuasa struct device *dev = &client->dev; 646c7efd123SYoichi Yuasa const struct firmware *fw; 647c7efd123SYoichi Yuasa s32 status; 648c7efd123SYoichi Yuasa unsigned int offset, len, xfer_len; 649c7efd123SYoichi Yuasa unsigned int retry = 0; 650c7efd123SYoichi Yuasa int error, error2; 651c7efd123SYoichi Yuasa 652c7efd123SYoichi Yuasa error = request_firmware(&fw, firmware_name, dev); 653c7efd123SYoichi Yuasa if (error) { 654c7efd123SYoichi Yuasa dev_err(dev, "unable to retrieve firmware %s: %d\n", 655c7efd123SYoichi Yuasa firmware_name, error); 656c7efd123SYoichi Yuasa return error; 657c7efd123SYoichi Yuasa } 658c7efd123SYoichi Yuasa 659c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_MASK, 660c7efd123SYoichi Yuasa COORD_UPDATE | CALIBRATION_DONE | 661c7efd123SYoichi Yuasa SLEEP_IN | SLEEP_OUT); 662c7efd123SYoichi Yuasa if (error) 663c7efd123SYoichi Yuasa goto out; 664c7efd123SYoichi Yuasa 665c7efd123SYoichi Yuasa do { 666c7efd123SYoichi Yuasa if (retry) { 667c7efd123SYoichi Yuasa dev_warn(dev, "retrying firmware load\n"); 668c7efd123SYoichi Yuasa 669c7efd123SYoichi Yuasa /* settings for retry */ 670c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, EX_WDAT, 0); 671c7efd123SYoichi Yuasa if (error) 672c7efd123SYoichi Yuasa goto out; 673c7efd123SYoichi Yuasa } 674c7efd123SYoichi Yuasa 675c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, EX_ADDR_H, 0); 676c7efd123SYoichi Yuasa if (error) 677c7efd123SYoichi Yuasa goto out; 678c7efd123SYoichi Yuasa 679c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, EX_ADDR_L, 0); 680c7efd123SYoichi Yuasa if (error) 681c7efd123SYoichi Yuasa goto out; 682c7efd123SYoichi Yuasa 683c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, COMMON_SETUP1, 684c7efd123SYoichi Yuasa COMMON_SETUP1_DEFAULT); 685c7efd123SYoichi Yuasa if (error) 686c7efd123SYoichi Yuasa goto out; 687c7efd123SYoichi Yuasa 688c7efd123SYoichi Yuasa /* firmware load to the device */ 689c7efd123SYoichi Yuasa offset = 0; 690c7efd123SYoichi Yuasa len = fw->size; 691c7efd123SYoichi Yuasa 692c7efd123SYoichi Yuasa while (len) { 693c7efd123SYoichi Yuasa xfer_len = min(FIRMWARE_BLOCK_SIZE, len); 694c7efd123SYoichi Yuasa 695c7efd123SYoichi Yuasa error = i2c_smbus_write_i2c_block_data(client, EX_WDAT, 696c7efd123SYoichi Yuasa xfer_len, &fw->data[offset]); 697c7efd123SYoichi Yuasa if (error) 698c7efd123SYoichi Yuasa goto out; 699c7efd123SYoichi Yuasa 700c7efd123SYoichi Yuasa len -= xfer_len; 701c7efd123SYoichi Yuasa offset += xfer_len; 702c7efd123SYoichi Yuasa } 703c7efd123SYoichi Yuasa 704c7efd123SYoichi Yuasa /* check firmware load result */ 705c7efd123SYoichi Yuasa status = i2c_smbus_read_byte_data(client, INT_STATUS); 706c7efd123SYoichi Yuasa if (status < 0) { 707c7efd123SYoichi Yuasa error = status; 708c7efd123SYoichi Yuasa goto out; 709c7efd123SYoichi Yuasa } 710c7efd123SYoichi Yuasa 711c7efd123SYoichi Yuasa /* clear all interrupts */ 712c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff); 713c7efd123SYoichi Yuasa if (error) 714c7efd123SYoichi Yuasa goto out; 715c7efd123SYoichi Yuasa 716c7efd123SYoichi Yuasa if (status == PROGRAM_LOAD_DONE) 717c7efd123SYoichi Yuasa break; 718c7efd123SYoichi Yuasa 719c7efd123SYoichi Yuasa error = -EIO; 720415a249fSDmitry Torokhov } while (++retry <= FIRMWARE_RETRY_MAX); 721c7efd123SYoichi Yuasa 722c7efd123SYoichi Yuasa out: 723c7efd123SYoichi Yuasa error2 = i2c_smbus_write_byte_data(client, INT_MASK, INT_ALL); 724c7efd123SYoichi Yuasa 725c7efd123SYoichi Yuasa release_firmware(fw); 726c7efd123SYoichi Yuasa 727c7efd123SYoichi Yuasa return error ? error : error2; 728c7efd123SYoichi Yuasa } 729c7efd123SYoichi Yuasa 730c7efd123SYoichi Yuasa static ssize_t swap_xy_show(struct device *dev, struct device_attribute *attr, 731c7efd123SYoichi Yuasa char *buf) 732c7efd123SYoichi Yuasa { 733c7efd123SYoichi Yuasa struct i2c_client *client = to_i2c_client(dev); 734c7efd123SYoichi Yuasa struct rohm_ts_data *ts = i2c_get_clientdata(client); 735c7efd123SYoichi Yuasa 736c7efd123SYoichi Yuasa return sprintf(buf, "%d\n", !!(ts->setup2 & SWAP_XY)); 737c7efd123SYoichi Yuasa } 738c7efd123SYoichi Yuasa 739c7efd123SYoichi Yuasa static ssize_t swap_xy_store(struct device *dev, struct device_attribute *attr, 740c7efd123SYoichi Yuasa const char *buf, size_t count) 741c7efd123SYoichi Yuasa { 742c7efd123SYoichi Yuasa struct i2c_client *client = to_i2c_client(dev); 743c7efd123SYoichi Yuasa struct rohm_ts_data *ts = i2c_get_clientdata(client); 744c7efd123SYoichi Yuasa unsigned int val; 745c7efd123SYoichi Yuasa int error; 746c7efd123SYoichi Yuasa 747c7efd123SYoichi Yuasa error = kstrtouint(buf, 0, &val); 748c7efd123SYoichi Yuasa if (error) 749c7efd123SYoichi Yuasa return error; 750c7efd123SYoichi Yuasa 751c7efd123SYoichi Yuasa error = mutex_lock_interruptible(&ts->input->mutex); 752c7efd123SYoichi Yuasa if (error) 753c7efd123SYoichi Yuasa return error; 754c7efd123SYoichi Yuasa 755c7efd123SYoichi Yuasa if (val) 756c7efd123SYoichi Yuasa ts->setup2 |= SWAP_XY; 757c7efd123SYoichi Yuasa else 758c7efd123SYoichi Yuasa ts->setup2 &= ~SWAP_XY; 759c7efd123SYoichi Yuasa 760c7efd123SYoichi Yuasa if (ts->initialized) 761c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2, 762c7efd123SYoichi Yuasa ts->setup2); 763c7efd123SYoichi Yuasa 764c7efd123SYoichi Yuasa mutex_unlock(&ts->input->mutex); 765c7efd123SYoichi Yuasa 766c7efd123SYoichi Yuasa return error ? error : count; 767c7efd123SYoichi Yuasa } 768c7efd123SYoichi Yuasa 769c7efd123SYoichi Yuasa static ssize_t inv_x_show(struct device *dev, struct device_attribute *attr, 770c7efd123SYoichi Yuasa char *buf) 771c7efd123SYoichi Yuasa { 772c7efd123SYoichi Yuasa struct i2c_client *client = to_i2c_client(dev); 773c7efd123SYoichi Yuasa struct rohm_ts_data *ts = i2c_get_clientdata(client); 774c7efd123SYoichi Yuasa 775c7efd123SYoichi Yuasa return sprintf(buf, "%d\n", !!(ts->setup2 & INV_X)); 776c7efd123SYoichi Yuasa } 777c7efd123SYoichi Yuasa 778c7efd123SYoichi Yuasa static ssize_t inv_x_store(struct device *dev, struct device_attribute *attr, 779c7efd123SYoichi Yuasa const char *buf, size_t count) 780c7efd123SYoichi Yuasa { 781c7efd123SYoichi Yuasa struct i2c_client *client = to_i2c_client(dev); 782c7efd123SYoichi Yuasa struct rohm_ts_data *ts = i2c_get_clientdata(client); 783c7efd123SYoichi Yuasa unsigned int val; 784c7efd123SYoichi Yuasa int error; 785c7efd123SYoichi Yuasa 786c7efd123SYoichi Yuasa error = kstrtouint(buf, 0, &val); 787c7efd123SYoichi Yuasa if (error) 788c7efd123SYoichi Yuasa return error; 789c7efd123SYoichi Yuasa 790c7efd123SYoichi Yuasa error = mutex_lock_interruptible(&ts->input->mutex); 791c7efd123SYoichi Yuasa if (error) 792c7efd123SYoichi Yuasa return error; 793c7efd123SYoichi Yuasa 794c7efd123SYoichi Yuasa if (val) 795c7efd123SYoichi Yuasa ts->setup2 |= INV_X; 796c7efd123SYoichi Yuasa else 797c7efd123SYoichi Yuasa ts->setup2 &= ~INV_X; 798c7efd123SYoichi Yuasa 799c7efd123SYoichi Yuasa if (ts->initialized) 800c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2, 801c7efd123SYoichi Yuasa ts->setup2); 802c7efd123SYoichi Yuasa 803c7efd123SYoichi Yuasa mutex_unlock(&ts->input->mutex); 804c7efd123SYoichi Yuasa 805c7efd123SYoichi Yuasa return error ? error : count; 806c7efd123SYoichi Yuasa } 807c7efd123SYoichi Yuasa 808c7efd123SYoichi Yuasa static ssize_t inv_y_show(struct device *dev, struct device_attribute *attr, 809c7efd123SYoichi Yuasa char *buf) 810c7efd123SYoichi Yuasa { 811c7efd123SYoichi Yuasa struct i2c_client *client = to_i2c_client(dev); 812c7efd123SYoichi Yuasa struct rohm_ts_data *ts = i2c_get_clientdata(client); 813c7efd123SYoichi Yuasa 814c7efd123SYoichi Yuasa return sprintf(buf, "%d\n", !!(ts->setup2 & INV_Y)); 815c7efd123SYoichi Yuasa } 816c7efd123SYoichi Yuasa 817c7efd123SYoichi Yuasa static ssize_t inv_y_store(struct device *dev, struct device_attribute *attr, 818c7efd123SYoichi Yuasa const char *buf, size_t count) 819c7efd123SYoichi Yuasa { 820c7efd123SYoichi Yuasa struct i2c_client *client = to_i2c_client(dev); 821c7efd123SYoichi Yuasa struct rohm_ts_data *ts = i2c_get_clientdata(client); 822c7efd123SYoichi Yuasa unsigned int val; 823c7efd123SYoichi Yuasa int error; 824c7efd123SYoichi Yuasa 825c7efd123SYoichi Yuasa error = kstrtouint(buf, 0, &val); 826c7efd123SYoichi Yuasa if (error) 827c7efd123SYoichi Yuasa return error; 828c7efd123SYoichi Yuasa 829c7efd123SYoichi Yuasa error = mutex_lock_interruptible(&ts->input->mutex); 830c7efd123SYoichi Yuasa if (error) 831c7efd123SYoichi Yuasa return error; 832c7efd123SYoichi Yuasa 833c7efd123SYoichi Yuasa if (val) 834c7efd123SYoichi Yuasa ts->setup2 |= INV_Y; 835c7efd123SYoichi Yuasa else 836c7efd123SYoichi Yuasa ts->setup2 &= ~INV_Y; 837c7efd123SYoichi Yuasa 838c7efd123SYoichi Yuasa if (ts->initialized) 839c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, COMMON_SETUP2, 840c7efd123SYoichi Yuasa ts->setup2); 841c7efd123SYoichi Yuasa 842c7efd123SYoichi Yuasa mutex_unlock(&ts->input->mutex); 843c7efd123SYoichi Yuasa 844c7efd123SYoichi Yuasa return error ? error : count; 845c7efd123SYoichi Yuasa } 846c7efd123SYoichi Yuasa 847c7efd123SYoichi Yuasa static DEVICE_ATTR_RW(swap_xy); 848c7efd123SYoichi Yuasa static DEVICE_ATTR_RW(inv_x); 849c7efd123SYoichi Yuasa static DEVICE_ATTR_RW(inv_y); 850c7efd123SYoichi Yuasa 851c7efd123SYoichi Yuasa static struct attribute *rohm_ts_attrs[] = { 852c7efd123SYoichi Yuasa &dev_attr_swap_xy.attr, 853c7efd123SYoichi Yuasa &dev_attr_inv_x.attr, 854c7efd123SYoichi Yuasa &dev_attr_inv_y.attr, 855c7efd123SYoichi Yuasa NULL, 856c7efd123SYoichi Yuasa }; 857c7efd123SYoichi Yuasa 858c7efd123SYoichi Yuasa static const struct attribute_group rohm_ts_attr_group = { 859c7efd123SYoichi Yuasa .attrs = rohm_ts_attrs, 860c7efd123SYoichi Yuasa }; 861c7efd123SYoichi Yuasa 862c7efd123SYoichi Yuasa static int rohm_ts_device_init(struct i2c_client *client, u8 setup2) 863c7efd123SYoichi Yuasa { 864c7efd123SYoichi Yuasa struct device *dev = &client->dev; 865c7efd123SYoichi Yuasa int error; 866c7efd123SYoichi Yuasa 867c7efd123SYoichi Yuasa disable_irq(client->irq); 868c7efd123SYoichi Yuasa 869c7efd123SYoichi Yuasa /* 870c7efd123SYoichi Yuasa * Wait 200usec for reset 871c7efd123SYoichi Yuasa */ 872c7efd123SYoichi Yuasa udelay(200); 873c7efd123SYoichi Yuasa 874c7efd123SYoichi Yuasa /* Release analog reset */ 875c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, SYSTEM, 876c7efd123SYoichi Yuasa ANALOG_POWER_ON | CPU_POWER_OFF); 877c7efd123SYoichi Yuasa if (error) 878c7efd123SYoichi Yuasa return error; 879c7efd123SYoichi Yuasa 880c7efd123SYoichi Yuasa /* Waiting for the analog warm-up, max. 200usec */ 881c7efd123SYoichi Yuasa udelay(200); 882c7efd123SYoichi Yuasa 883c7efd123SYoichi Yuasa /* clear all interrupts */ 884c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff); 885c7efd123SYoichi Yuasa if (error) 886c7efd123SYoichi Yuasa return error; 887c7efd123SYoichi Yuasa 888c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, EX_WDAT, 0); 889c7efd123SYoichi Yuasa if (error) 890c7efd123SYoichi Yuasa return error; 891c7efd123SYoichi Yuasa 892c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, COMMON_SETUP1, 0); 893c7efd123SYoichi Yuasa if (error) 894c7efd123SYoichi Yuasa return error; 895c7efd123SYoichi Yuasa 896c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, COMMON_SETUP2, setup2); 897c7efd123SYoichi Yuasa if (error) 898c7efd123SYoichi Yuasa return error; 899c7efd123SYoichi Yuasa 900c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, COMMON_SETUP3, 901c7efd123SYoichi Yuasa SEL_TBL_DEFAULT | EN_MULTI); 902c7efd123SYoichi Yuasa if (error) 903c7efd123SYoichi Yuasa return error; 904c7efd123SYoichi Yuasa 905c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, THRESHOLD_GESTURE, 906c7efd123SYoichi Yuasa THRESHOLD_GESTURE_DEFAULT); 907c7efd123SYoichi Yuasa if (error) 908c7efd123SYoichi Yuasa return error; 909c7efd123SYoichi Yuasa 910c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INTERVAL_TIME, 911c7efd123SYoichi Yuasa INTERVAL_TIME_DEFAULT); 912c7efd123SYoichi Yuasa if (error) 913c7efd123SYoichi Yuasa return error; 914c7efd123SYoichi Yuasa 915c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CPU_FREQ, CPU_FREQ_10MHZ); 916c7efd123SYoichi Yuasa if (error) 917c7efd123SYoichi Yuasa return error; 918c7efd123SYoichi Yuasa 919c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, PRM_SWOFF_TIME, 920c7efd123SYoichi Yuasa PRM_SWOFF_TIME_DEFAULT); 921c7efd123SYoichi Yuasa if (error) 922c7efd123SYoichi Yuasa return error; 923c7efd123SYoichi Yuasa 924c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, ADC_CTRL, ADC_DIV_DEFAULT); 925c7efd123SYoichi Yuasa if (error) 926c7efd123SYoichi Yuasa return error; 927c7efd123SYoichi Yuasa 928c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, ADC_WAIT, ADC_WAIT_DEFAULT); 929c7efd123SYoichi Yuasa if (error) 930c7efd123SYoichi Yuasa return error; 931c7efd123SYoichi Yuasa 932c7efd123SYoichi Yuasa /* 933c7efd123SYoichi Yuasa * Panel setup, these values change with the panel. 934c7efd123SYoichi Yuasa */ 935c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, STEP_X, STEP_X_DEFAULT); 936c7efd123SYoichi Yuasa if (error) 937c7efd123SYoichi Yuasa return error; 938c7efd123SYoichi Yuasa 939c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, STEP_Y, STEP_Y_DEFAULT); 940c7efd123SYoichi Yuasa if (error) 941c7efd123SYoichi Yuasa return error; 942c7efd123SYoichi Yuasa 943c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, OFFSET_X, OFFSET_X_DEFAULT); 944c7efd123SYoichi Yuasa if (error) 945c7efd123SYoichi Yuasa return error; 946c7efd123SYoichi Yuasa 947c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, OFFSET_Y, OFFSET_Y_DEFAULT); 948c7efd123SYoichi Yuasa if (error) 949c7efd123SYoichi Yuasa return error; 950c7efd123SYoichi Yuasa 951c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, THRESHOLD_TOUCH, 952c7efd123SYoichi Yuasa THRESHOLD_TOUCH_DEFAULT); 953c7efd123SYoichi Yuasa if (error) 954c7efd123SYoichi Yuasa return error; 955c7efd123SYoichi Yuasa 956c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, EVR_XY, EVR_XY_DEFAULT); 957c7efd123SYoichi Yuasa if (error) 958c7efd123SYoichi Yuasa return error; 959c7efd123SYoichi Yuasa 960c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, EVR_X, EVR_X_DEFAULT); 961c7efd123SYoichi Yuasa if (error) 962c7efd123SYoichi Yuasa return error; 963c7efd123SYoichi Yuasa 964c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, EVR_Y, EVR_Y_DEFAULT); 965c7efd123SYoichi Yuasa if (error) 966c7efd123SYoichi Yuasa return error; 967c7efd123SYoichi Yuasa 968c7efd123SYoichi Yuasa /* Fixed value settings */ 969c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CALIBRATION_ADJUST, 970c7efd123SYoichi Yuasa CALIBRATION_ADJUST_DEFAULT); 971c7efd123SYoichi Yuasa if (error) 972c7efd123SYoichi Yuasa return error; 973c7efd123SYoichi Yuasa 974c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, SWCONT, SWCONT_DEFAULT); 975c7efd123SYoichi Yuasa if (error) 976c7efd123SYoichi Yuasa return error; 977c7efd123SYoichi Yuasa 978c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, TEST1, 979c7efd123SYoichi Yuasa DUALTOUCH_STABILIZE_ON | 980c7efd123SYoichi Yuasa DUALTOUCH_REG_ON); 981c7efd123SYoichi Yuasa if (error) 982c7efd123SYoichi Yuasa return error; 983c7efd123SYoichi Yuasa 984c7efd123SYoichi Yuasa error = rohm_ts_load_firmware(client, BU21023_FIRMWARE_NAME); 985c7efd123SYoichi Yuasa if (error) { 986c7efd123SYoichi Yuasa dev_err(dev, "failed to load firmware: %d\n", error); 987c7efd123SYoichi Yuasa return error; 988c7efd123SYoichi Yuasa } 989c7efd123SYoichi Yuasa 990c7efd123SYoichi Yuasa /* 991c7efd123SYoichi Yuasa * Manual calibration results are not changed in same environment. 992c7efd123SYoichi Yuasa * If the force calibration is performed, 993c7efd123SYoichi Yuasa * the controller will not require calibration request interrupt 994c7efd123SYoichi Yuasa * when the typical values are set to the calibration registers. 995c7efd123SYoichi Yuasa */ 996c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CALIBRATION_REG1, 997c7efd123SYoichi Yuasa CALIBRATION_REG1_DEFAULT); 998c7efd123SYoichi Yuasa if (error) 999c7efd123SYoichi Yuasa return error; 1000c7efd123SYoichi Yuasa 1001c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CALIBRATION_REG2, 1002c7efd123SYoichi Yuasa CALIBRATION_REG2_DEFAULT); 1003c7efd123SYoichi Yuasa if (error) 1004c7efd123SYoichi Yuasa return error; 1005c7efd123SYoichi Yuasa 1006c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CALIBRATION_REG3, 1007c7efd123SYoichi Yuasa CALIBRATION_REG3_DEFAULT); 1008c7efd123SYoichi Yuasa if (error) 1009c7efd123SYoichi Yuasa return error; 1010c7efd123SYoichi Yuasa 1011c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, FORCE_CALIBRATION, 1012c7efd123SYoichi Yuasa FORCE_CALIBRATION_OFF); 1013c7efd123SYoichi Yuasa if (error) 1014c7efd123SYoichi Yuasa return error; 1015c7efd123SYoichi Yuasa 1016c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, FORCE_CALIBRATION, 1017c7efd123SYoichi Yuasa FORCE_CALIBRATION_ON); 1018c7efd123SYoichi Yuasa if (error) 1019c7efd123SYoichi Yuasa return error; 1020c7efd123SYoichi Yuasa 1021c7efd123SYoichi Yuasa /* Clear all interrupts */ 1022c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff); 1023c7efd123SYoichi Yuasa if (error) 1024c7efd123SYoichi Yuasa return error; 1025c7efd123SYoichi Yuasa 1026c7efd123SYoichi Yuasa /* Enable coordinates update interrupt */ 1027c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_MASK, 1028c7efd123SYoichi Yuasa CALIBRATION_DONE | SLEEP_OUT | 1029c7efd123SYoichi Yuasa SLEEP_IN | PROGRAM_LOAD_DONE); 1030c7efd123SYoichi Yuasa if (error) 1031c7efd123SYoichi Yuasa return error; 1032c7efd123SYoichi Yuasa 1033c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, ERR_MASK, 1034c7efd123SYoichi Yuasa PROGRAM_LOAD_ERR | CPU_TIMEOUT | 1035c7efd123SYoichi Yuasa ADC_TIMEOUT); 1036c7efd123SYoichi Yuasa if (error) 1037c7efd123SYoichi Yuasa return error; 1038c7efd123SYoichi Yuasa 1039c7efd123SYoichi Yuasa /* controller CPU power on */ 1040c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, SYSTEM, 1041c7efd123SYoichi Yuasa ANALOG_POWER_ON | CPU_POWER_ON); 1042c7efd123SYoichi Yuasa 1043c7efd123SYoichi Yuasa enable_irq(client->irq); 1044c7efd123SYoichi Yuasa 1045c7efd123SYoichi Yuasa return error; 1046c7efd123SYoichi Yuasa } 1047c7efd123SYoichi Yuasa 1048c7efd123SYoichi Yuasa static int rohm_ts_power_off(struct i2c_client *client) 1049c7efd123SYoichi Yuasa { 1050c7efd123SYoichi Yuasa int error; 1051c7efd123SYoichi Yuasa 1052c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, SYSTEM, 1053c7efd123SYoichi Yuasa ANALOG_POWER_ON | CPU_POWER_OFF); 1054c7efd123SYoichi Yuasa if (error) { 1055c7efd123SYoichi Yuasa dev_err(&client->dev, 1056c7efd123SYoichi Yuasa "failed to power off device CPU: %d\n", error); 1057c7efd123SYoichi Yuasa return error; 1058c7efd123SYoichi Yuasa } 1059c7efd123SYoichi Yuasa 1060c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, SYSTEM, 1061c7efd123SYoichi Yuasa ANALOG_POWER_OFF | CPU_POWER_OFF); 1062c7efd123SYoichi Yuasa if (error) 1063c7efd123SYoichi Yuasa dev_err(&client->dev, 1064c7efd123SYoichi Yuasa "failed to power off the device: %d\n", error); 1065c7efd123SYoichi Yuasa 1066c7efd123SYoichi Yuasa return error; 1067c7efd123SYoichi Yuasa } 1068c7efd123SYoichi Yuasa 1069c7efd123SYoichi Yuasa static int rohm_ts_open(struct input_dev *input_dev) 1070c7efd123SYoichi Yuasa { 1071c7efd123SYoichi Yuasa struct rohm_ts_data *ts = input_get_drvdata(input_dev); 1072c7efd123SYoichi Yuasa struct i2c_client *client = ts->client; 1073c7efd123SYoichi Yuasa int error; 1074c7efd123SYoichi Yuasa 1075c7efd123SYoichi Yuasa if (!ts->initialized) { 1076c7efd123SYoichi Yuasa error = rohm_ts_device_init(client, ts->setup2); 1077c7efd123SYoichi Yuasa if (error) { 1078c7efd123SYoichi Yuasa dev_err(&client->dev, 1079c7efd123SYoichi Yuasa "device initialization failed: %d\n", error); 1080c7efd123SYoichi Yuasa return error; 1081c7efd123SYoichi Yuasa } 1082c7efd123SYoichi Yuasa 1083c7efd123SYoichi Yuasa ts->initialized = true; 1084c7efd123SYoichi Yuasa } 1085c7efd123SYoichi Yuasa 1086c7efd123SYoichi Yuasa return 0; 1087c7efd123SYoichi Yuasa } 1088c7efd123SYoichi Yuasa 1089c7efd123SYoichi Yuasa static void rohm_ts_close(struct input_dev *input_dev) 1090c7efd123SYoichi Yuasa { 1091c7efd123SYoichi Yuasa struct rohm_ts_data *ts = input_get_drvdata(input_dev); 1092c7efd123SYoichi Yuasa 1093c7efd123SYoichi Yuasa rohm_ts_power_off(ts->client); 1094c7efd123SYoichi Yuasa 1095c7efd123SYoichi Yuasa ts->initialized = false; 1096c7efd123SYoichi Yuasa } 1097c7efd123SYoichi Yuasa 1098c7efd123SYoichi Yuasa static int rohm_bu21023_i2c_probe(struct i2c_client *client, 1099c7efd123SYoichi Yuasa const struct i2c_device_id *id) 1100c7efd123SYoichi Yuasa { 1101c7efd123SYoichi Yuasa struct device *dev = &client->dev; 1102c7efd123SYoichi Yuasa struct rohm_ts_data *ts; 1103c7efd123SYoichi Yuasa struct input_dev *input; 1104c7efd123SYoichi Yuasa int error; 1105c7efd123SYoichi Yuasa 1106c7efd123SYoichi Yuasa if (!client->irq) { 1107c7efd123SYoichi Yuasa dev_err(dev, "IRQ is not assigned\n"); 1108c7efd123SYoichi Yuasa return -EINVAL; 1109c7efd123SYoichi Yuasa } 1110c7efd123SYoichi Yuasa 1111c7efd123SYoichi Yuasa if (!client->adapter->algo->master_xfer) { 1112c7efd123SYoichi Yuasa dev_err(dev, "I2C level transfers not supported\n"); 1113c7efd123SYoichi Yuasa return -EOPNOTSUPP; 1114c7efd123SYoichi Yuasa } 1115c7efd123SYoichi Yuasa 1116c7efd123SYoichi Yuasa /* Turn off CPU just in case */ 1117c7efd123SYoichi Yuasa error = rohm_ts_power_off(client); 1118c7efd123SYoichi Yuasa if (error) 1119c7efd123SYoichi Yuasa return error; 1120c7efd123SYoichi Yuasa 1121c7efd123SYoichi Yuasa ts = devm_kzalloc(dev, sizeof(struct rohm_ts_data), GFP_KERNEL); 1122c7efd123SYoichi Yuasa if (!ts) 1123c7efd123SYoichi Yuasa return -ENOMEM; 1124c7efd123SYoichi Yuasa 1125c7efd123SYoichi Yuasa ts->client = client; 1126c7efd123SYoichi Yuasa ts->setup2 = MAF_1SAMPLE; 1127c7efd123SYoichi Yuasa i2c_set_clientdata(client, ts); 1128c7efd123SYoichi Yuasa 1129c7efd123SYoichi Yuasa input = devm_input_allocate_device(dev); 1130c7efd123SYoichi Yuasa if (!input) 1131c7efd123SYoichi Yuasa return -ENOMEM; 1132c7efd123SYoichi Yuasa 1133c7efd123SYoichi Yuasa input->name = BU21023_NAME; 1134c7efd123SYoichi Yuasa input->id.bustype = BUS_I2C; 1135c7efd123SYoichi Yuasa input->open = rohm_ts_open; 1136c7efd123SYoichi Yuasa input->close = rohm_ts_close; 1137c7efd123SYoichi Yuasa 1138c7efd123SYoichi Yuasa ts->input = input; 1139c7efd123SYoichi Yuasa input_set_drvdata(input, ts); 1140c7efd123SYoichi Yuasa 1141c7efd123SYoichi Yuasa input_set_abs_params(input, ABS_MT_POSITION_X, 1142c7efd123SYoichi Yuasa ROHM_TS_ABS_X_MIN, ROHM_TS_ABS_X_MAX, 0, 0); 1143c7efd123SYoichi Yuasa input_set_abs_params(input, ABS_MT_POSITION_Y, 1144c7efd123SYoichi Yuasa ROHM_TS_ABS_Y_MIN, ROHM_TS_ABS_Y_MAX, 0, 0); 1145c7efd123SYoichi Yuasa 1146c7efd123SYoichi Yuasa error = input_mt_init_slots(input, MAX_CONTACTS, 1147c7efd123SYoichi Yuasa INPUT_MT_DIRECT | INPUT_MT_TRACK | 1148c7efd123SYoichi Yuasa INPUT_MT_DROP_UNUSED); 1149c7efd123SYoichi Yuasa if (error) { 1150c7efd123SYoichi Yuasa dev_err(dev, "failed to multi touch slots initialization\n"); 1151c7efd123SYoichi Yuasa return error; 1152c7efd123SYoichi Yuasa } 1153c7efd123SYoichi Yuasa 1154c7efd123SYoichi Yuasa error = devm_request_threaded_irq(dev, client->irq, 1155c7efd123SYoichi Yuasa NULL, rohm_ts_soft_irq, 1156c7efd123SYoichi Yuasa IRQF_ONESHOT, client->name, ts); 1157c7efd123SYoichi Yuasa if (error) { 1158c7efd123SYoichi Yuasa dev_err(dev, "failed to request IRQ: %d\n", error); 1159c7efd123SYoichi Yuasa return error; 1160c7efd123SYoichi Yuasa } 1161c7efd123SYoichi Yuasa 1162c7efd123SYoichi Yuasa error = input_register_device(input); 1163c7efd123SYoichi Yuasa if (error) { 1164c7efd123SYoichi Yuasa dev_err(dev, "failed to register input device: %d\n", error); 1165c7efd123SYoichi Yuasa return error; 1166c7efd123SYoichi Yuasa } 1167c7efd123SYoichi Yuasa 1168a71b8b5cSAndi Shyti error = devm_device_add_group(dev, &rohm_ts_attr_group); 1169c7efd123SYoichi Yuasa if (error) { 1170c7efd123SYoichi Yuasa dev_err(dev, "failed to create sysfs group: %d\n", error); 1171c7efd123SYoichi Yuasa return error; 1172c7efd123SYoichi Yuasa } 1173c7efd123SYoichi Yuasa 1174c7efd123SYoichi Yuasa return error; 1175c7efd123SYoichi Yuasa } 1176c7efd123SYoichi Yuasa 1177c7efd123SYoichi Yuasa static const struct i2c_device_id rohm_bu21023_i2c_id[] = { 1178c7efd123SYoichi Yuasa { BU21023_NAME, 0 }, 1179c7efd123SYoichi Yuasa { /* sentinel */ } 1180c7efd123SYoichi Yuasa }; 1181c7efd123SYoichi Yuasa MODULE_DEVICE_TABLE(i2c, rohm_bu21023_i2c_id); 1182c7efd123SYoichi Yuasa 1183c7efd123SYoichi Yuasa static struct i2c_driver rohm_bu21023_i2c_driver = { 1184c7efd123SYoichi Yuasa .driver = { 1185c7efd123SYoichi Yuasa .name = BU21023_NAME, 1186c7efd123SYoichi Yuasa }, 1187c7efd123SYoichi Yuasa .probe = rohm_bu21023_i2c_probe, 1188c7efd123SYoichi Yuasa .id_table = rohm_bu21023_i2c_id, 1189c7efd123SYoichi Yuasa }; 1190c7efd123SYoichi Yuasa module_i2c_driver(rohm_bu21023_i2c_driver); 1191c7efd123SYoichi Yuasa 1192c7efd123SYoichi Yuasa MODULE_DESCRIPTION("ROHM BU21023/24 Touchscreen driver"); 1193c7efd123SYoichi Yuasa MODULE_LICENSE("GPL v2"); 1194c7efd123SYoichi Yuasa MODULE_AUTHOR("ROHM Co., Ltd."); 1195