145051539SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2e8e70d83SChris Hudson /* 3e8e70d83SChris Hudson * Copyright (C) 2011 Kionix, Inc. 4e8e70d83SChris Hudson * Written by Chris Hudson <chudson@kionix.com> 5e8e70d83SChris Hudson */ 6e8e70d83SChris Hudson 7e8e70d83SChris Hudson #include <linux/delay.h> 8e8e70d83SChris Hudson #include <linux/i2c.h> 9e8e70d83SChris Hudson #include <linux/input.h> 10e8e70d83SChris Hudson #include <linux/interrupt.h> 112501ec97SStephen Rothwell #include <linux/module.h> 12e8e70d83SChris Hudson #include <linux/slab.h> 13e8e70d83SChris Hudson #include <linux/input/kxtj9.h> 14e8e70d83SChris Hudson #include <linux/input-polldev.h> 15e8e70d83SChris Hudson 16e8e70d83SChris Hudson #define NAME "kxtj9" 17e8e70d83SChris Hudson #define G_MAX 8000 18e8e70d83SChris Hudson /* OUTPUT REGISTERS */ 19e8e70d83SChris Hudson #define XOUT_L 0x06 20e8e70d83SChris Hudson #define WHO_AM_I 0x0F 21e8e70d83SChris Hudson /* CONTROL REGISTERS */ 22e8e70d83SChris Hudson #define INT_REL 0x1A 23e8e70d83SChris Hudson #define CTRL_REG1 0x1B 24e8e70d83SChris Hudson #define INT_CTRL1 0x1E 25e8e70d83SChris Hudson #define DATA_CTRL 0x21 26e8e70d83SChris Hudson /* CONTROL REGISTER 1 BITS */ 27e8e70d83SChris Hudson #define PC1_OFF 0x7F 28e8e70d83SChris Hudson #define PC1_ON (1 << 7) 29e8e70d83SChris Hudson /* Data ready funtion enable bit: set during probe if using irq mode */ 30e8e70d83SChris Hudson #define DRDYE (1 << 5) 3104391660SChristopher Hudson /* DATA CONTROL REGISTER BITS */ 3204391660SChristopher Hudson #define ODR12_5F 0 3304391660SChristopher Hudson #define ODR25F 1 3404391660SChristopher Hudson #define ODR50F 2 3504391660SChristopher Hudson #define ODR100F 3 3604391660SChristopher Hudson #define ODR200F 4 3704391660SChristopher Hudson #define ODR400F 5 3804391660SChristopher Hudson #define ODR800F 6 39e8e70d83SChris Hudson /* INTERRUPT CONTROL REGISTER 1 BITS */ 40e8e70d83SChris Hudson /* Set these during probe if using irq mode */ 41e8e70d83SChris Hudson #define KXTJ9_IEL (1 << 3) 42e8e70d83SChris Hudson #define KXTJ9_IEA (1 << 4) 43e8e70d83SChris Hudson #define KXTJ9_IEN (1 << 5) 44e8e70d83SChris Hudson /* INPUT_ABS CONSTANTS */ 45e8e70d83SChris Hudson #define FUZZ 3 46e8e70d83SChris Hudson #define FLAT 3 47e8e70d83SChris Hudson /* RESUME STATE INDICES */ 48e8e70d83SChris Hudson #define RES_DATA_CTRL 0 49e8e70d83SChris Hudson #define RES_CTRL_REG1 1 50e8e70d83SChris Hudson #define RES_INT_CTRL1 2 51e8e70d83SChris Hudson #define RESUME_ENTRIES 3 52e8e70d83SChris Hudson 53e8e70d83SChris Hudson /* 54e8e70d83SChris Hudson * The following table lists the maximum appropriate poll interval for each 55e8e70d83SChris Hudson * available output data rate. 56e8e70d83SChris Hudson */ 57e8e70d83SChris Hudson static const struct { 58e8e70d83SChris Hudson unsigned int cutoff; 59e8e70d83SChris Hudson u8 mask; 60e8e70d83SChris Hudson } kxtj9_odr_table[] = { 61e8e70d83SChris Hudson { 3, ODR800F }, 62e8e70d83SChris Hudson { 5, ODR400F }, 63e8e70d83SChris Hudson { 10, ODR200F }, 64e8e70d83SChris Hudson { 20, ODR100F }, 65e8e70d83SChris Hudson { 40, ODR50F }, 66e8e70d83SChris Hudson { 80, ODR25F }, 67e8e70d83SChris Hudson { 0, ODR12_5F}, 68e8e70d83SChris Hudson }; 69e8e70d83SChris Hudson 70e8e70d83SChris Hudson struct kxtj9_data { 71e8e70d83SChris Hudson struct i2c_client *client; 72e8e70d83SChris Hudson struct kxtj9_platform_data pdata; 73e8e70d83SChris Hudson struct input_dev *input_dev; 74e8e70d83SChris Hudson #ifdef CONFIG_INPUT_KXTJ9_POLLED_MODE 75e8e70d83SChris Hudson struct input_polled_dev *poll_dev; 76e8e70d83SChris Hudson #endif 77e8e70d83SChris Hudson unsigned int last_poll_interval; 78e8e70d83SChris Hudson u8 shift; 79e8e70d83SChris Hudson u8 ctrl_reg1; 80e8e70d83SChris Hudson u8 data_ctrl; 81e8e70d83SChris Hudson u8 int_ctrl; 82e8e70d83SChris Hudson }; 83e8e70d83SChris Hudson 84e8e70d83SChris Hudson static int kxtj9_i2c_read(struct kxtj9_data *tj9, u8 addr, u8 *data, int len) 85e8e70d83SChris Hudson { 86e8e70d83SChris Hudson struct i2c_msg msgs[] = { 87e8e70d83SChris Hudson { 88e8e70d83SChris Hudson .addr = tj9->client->addr, 89e8e70d83SChris Hudson .flags = tj9->client->flags, 90e8e70d83SChris Hudson .len = 1, 91e8e70d83SChris Hudson .buf = &addr, 92e8e70d83SChris Hudson }, 93e8e70d83SChris Hudson { 94e8e70d83SChris Hudson .addr = tj9->client->addr, 95e8e70d83SChris Hudson .flags = tj9->client->flags | I2C_M_RD, 96e8e70d83SChris Hudson .len = len, 97e8e70d83SChris Hudson .buf = data, 98e8e70d83SChris Hudson }, 99e8e70d83SChris Hudson }; 100e8e70d83SChris Hudson 101e8e70d83SChris Hudson return i2c_transfer(tj9->client->adapter, msgs, 2); 102e8e70d83SChris Hudson } 103e8e70d83SChris Hudson 104e8e70d83SChris Hudson static void kxtj9_report_acceleration_data(struct kxtj9_data *tj9) 105e8e70d83SChris Hudson { 106e8e70d83SChris Hudson s16 acc_data[3]; /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ 107e8e70d83SChris Hudson s16 x, y, z; 108e8e70d83SChris Hudson int err; 109e8e70d83SChris Hudson 110e8e70d83SChris Hudson err = kxtj9_i2c_read(tj9, XOUT_L, (u8 *)acc_data, 6); 111e8e70d83SChris Hudson if (err < 0) 112e8e70d83SChris Hudson dev_err(&tj9->client->dev, "accelerometer data read failed\n"); 113e8e70d83SChris Hudson 11404391660SChristopher Hudson x = le16_to_cpu(acc_data[tj9->pdata.axis_map_x]); 11504391660SChristopher Hudson y = le16_to_cpu(acc_data[tj9->pdata.axis_map_y]); 11604391660SChristopher Hudson z = le16_to_cpu(acc_data[tj9->pdata.axis_map_z]); 11704391660SChristopher Hudson 11804391660SChristopher Hudson x >>= tj9->shift; 11904391660SChristopher Hudson y >>= tj9->shift; 12004391660SChristopher Hudson z >>= tj9->shift; 121e8e70d83SChris Hudson 122e8e70d83SChris Hudson input_report_abs(tj9->input_dev, ABS_X, tj9->pdata.negate_x ? -x : x); 123e8e70d83SChris Hudson input_report_abs(tj9->input_dev, ABS_Y, tj9->pdata.negate_y ? -y : y); 124e8e70d83SChris Hudson input_report_abs(tj9->input_dev, ABS_Z, tj9->pdata.negate_z ? -z : z); 125e8e70d83SChris Hudson input_sync(tj9->input_dev); 126e8e70d83SChris Hudson } 127e8e70d83SChris Hudson 128e8e70d83SChris Hudson static irqreturn_t kxtj9_isr(int irq, void *dev) 129e8e70d83SChris Hudson { 130e8e70d83SChris Hudson struct kxtj9_data *tj9 = dev; 131e8e70d83SChris Hudson int err; 132e8e70d83SChris Hudson 133e8e70d83SChris Hudson /* data ready is the only possible interrupt type */ 134e8e70d83SChris Hudson kxtj9_report_acceleration_data(tj9); 135e8e70d83SChris Hudson 136e8e70d83SChris Hudson err = i2c_smbus_read_byte_data(tj9->client, INT_REL); 137e8e70d83SChris Hudson if (err < 0) 138e8e70d83SChris Hudson dev_err(&tj9->client->dev, 139e8e70d83SChris Hudson "error clearing interrupt status: %d\n", err); 140e8e70d83SChris Hudson 141e8e70d83SChris Hudson return IRQ_HANDLED; 142e8e70d83SChris Hudson } 143e8e70d83SChris Hudson 144e8e70d83SChris Hudson static int kxtj9_update_g_range(struct kxtj9_data *tj9, u8 new_g_range) 145e8e70d83SChris Hudson { 146e8e70d83SChris Hudson switch (new_g_range) { 147e8e70d83SChris Hudson case KXTJ9_G_2G: 148e8e70d83SChris Hudson tj9->shift = 4; 149e8e70d83SChris Hudson break; 150e8e70d83SChris Hudson case KXTJ9_G_4G: 151e8e70d83SChris Hudson tj9->shift = 3; 152e8e70d83SChris Hudson break; 153e8e70d83SChris Hudson case KXTJ9_G_8G: 154e8e70d83SChris Hudson tj9->shift = 2; 155e8e70d83SChris Hudson break; 156e8e70d83SChris Hudson default: 157e8e70d83SChris Hudson return -EINVAL; 158e8e70d83SChris Hudson } 159e8e70d83SChris Hudson 160e8e70d83SChris Hudson tj9->ctrl_reg1 &= 0xe7; 161e8e70d83SChris Hudson tj9->ctrl_reg1 |= new_g_range; 162e8e70d83SChris Hudson 163e8e70d83SChris Hudson return 0; 164e8e70d83SChris Hudson } 165e8e70d83SChris Hudson 166e8e70d83SChris Hudson static int kxtj9_update_odr(struct kxtj9_data *tj9, unsigned int poll_interval) 167e8e70d83SChris Hudson { 168e8e70d83SChris Hudson int err; 169e8e70d83SChris Hudson int i; 170e8e70d83SChris Hudson 171e8e70d83SChris Hudson /* Use the lowest ODR that can support the requested poll interval */ 172e8e70d83SChris Hudson for (i = 0; i < ARRAY_SIZE(kxtj9_odr_table); i++) { 173e8e70d83SChris Hudson tj9->data_ctrl = kxtj9_odr_table[i].mask; 174e8e70d83SChris Hudson if (poll_interval < kxtj9_odr_table[i].cutoff) 175e8e70d83SChris Hudson break; 176e8e70d83SChris Hudson } 177e8e70d83SChris Hudson 178e8e70d83SChris Hudson err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, 0); 179e8e70d83SChris Hudson if (err < 0) 180e8e70d83SChris Hudson return err; 181e8e70d83SChris Hudson 182e8e70d83SChris Hudson err = i2c_smbus_write_byte_data(tj9->client, DATA_CTRL, tj9->data_ctrl); 183e8e70d83SChris Hudson if (err < 0) 184e8e70d83SChris Hudson return err; 185e8e70d83SChris Hudson 186e8e70d83SChris Hudson err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, tj9->ctrl_reg1); 187e8e70d83SChris Hudson if (err < 0) 188e8e70d83SChris Hudson return err; 189e8e70d83SChris Hudson 190e8e70d83SChris Hudson return 0; 191e8e70d83SChris Hudson } 192e8e70d83SChris Hudson 193e8e70d83SChris Hudson static int kxtj9_device_power_on(struct kxtj9_data *tj9) 194e8e70d83SChris Hudson { 195e8e70d83SChris Hudson if (tj9->pdata.power_on) 196e8e70d83SChris Hudson return tj9->pdata.power_on(); 197e8e70d83SChris Hudson 198e8e70d83SChris Hudson return 0; 199e8e70d83SChris Hudson } 200e8e70d83SChris Hudson 201e8e70d83SChris Hudson static void kxtj9_device_power_off(struct kxtj9_data *tj9) 202e8e70d83SChris Hudson { 203e8e70d83SChris Hudson int err; 204e8e70d83SChris Hudson 205e8e70d83SChris Hudson tj9->ctrl_reg1 &= PC1_OFF; 206e8e70d83SChris Hudson err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, tj9->ctrl_reg1); 207e8e70d83SChris Hudson if (err < 0) 208e8e70d83SChris Hudson dev_err(&tj9->client->dev, "soft power off failed\n"); 209e8e70d83SChris Hudson 210e8e70d83SChris Hudson if (tj9->pdata.power_off) 211e8e70d83SChris Hudson tj9->pdata.power_off(); 212e8e70d83SChris Hudson } 213e8e70d83SChris Hudson 214e8e70d83SChris Hudson static int kxtj9_enable(struct kxtj9_data *tj9) 215e8e70d83SChris Hudson { 216e8e70d83SChris Hudson int err; 217e8e70d83SChris Hudson 218e8e70d83SChris Hudson err = kxtj9_device_power_on(tj9); 219e8e70d83SChris Hudson if (err < 0) 220e8e70d83SChris Hudson return err; 221e8e70d83SChris Hudson 222e8e70d83SChris Hudson /* ensure that PC1 is cleared before updating control registers */ 223e8e70d83SChris Hudson err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, 0); 224e8e70d83SChris Hudson if (err < 0) 225e8e70d83SChris Hudson return err; 226e8e70d83SChris Hudson 227e8e70d83SChris Hudson /* only write INT_CTRL_REG1 if in irq mode */ 228e8e70d83SChris Hudson if (tj9->client->irq) { 229e8e70d83SChris Hudson err = i2c_smbus_write_byte_data(tj9->client, 230e8e70d83SChris Hudson INT_CTRL1, tj9->int_ctrl); 231e8e70d83SChris Hudson if (err < 0) 232e8e70d83SChris Hudson return err; 233e8e70d83SChris Hudson } 234e8e70d83SChris Hudson 235e8e70d83SChris Hudson err = kxtj9_update_g_range(tj9, tj9->pdata.g_range); 236e8e70d83SChris Hudson if (err < 0) 237e8e70d83SChris Hudson return err; 238e8e70d83SChris Hudson 239e8e70d83SChris Hudson /* turn on outputs */ 240e8e70d83SChris Hudson tj9->ctrl_reg1 |= PC1_ON; 241e8e70d83SChris Hudson err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, tj9->ctrl_reg1); 242e8e70d83SChris Hudson if (err < 0) 243e8e70d83SChris Hudson return err; 244e8e70d83SChris Hudson 245e8e70d83SChris Hudson err = kxtj9_update_odr(tj9, tj9->last_poll_interval); 246e8e70d83SChris Hudson if (err < 0) 247e8e70d83SChris Hudson return err; 248e8e70d83SChris Hudson 249e8e70d83SChris Hudson /* clear initial interrupt if in irq mode */ 250e8e70d83SChris Hudson if (tj9->client->irq) { 251e8e70d83SChris Hudson err = i2c_smbus_read_byte_data(tj9->client, INT_REL); 252e8e70d83SChris Hudson if (err < 0) { 253e8e70d83SChris Hudson dev_err(&tj9->client->dev, 254e8e70d83SChris Hudson "error clearing interrupt: %d\n", err); 255e8e70d83SChris Hudson goto fail; 256e8e70d83SChris Hudson } 257e8e70d83SChris Hudson } 258e8e70d83SChris Hudson 259e8e70d83SChris Hudson return 0; 260e8e70d83SChris Hudson 261e8e70d83SChris Hudson fail: 262e8e70d83SChris Hudson kxtj9_device_power_off(tj9); 263e8e70d83SChris Hudson return err; 264e8e70d83SChris Hudson } 265e8e70d83SChris Hudson 266e8e70d83SChris Hudson static void kxtj9_disable(struct kxtj9_data *tj9) 267e8e70d83SChris Hudson { 268e8e70d83SChris Hudson kxtj9_device_power_off(tj9); 269e8e70d83SChris Hudson } 270e8e70d83SChris Hudson 271e8e70d83SChris Hudson static int kxtj9_input_open(struct input_dev *input) 272e8e70d83SChris Hudson { 273e8e70d83SChris Hudson struct kxtj9_data *tj9 = input_get_drvdata(input); 274e8e70d83SChris Hudson 275e8e70d83SChris Hudson return kxtj9_enable(tj9); 276e8e70d83SChris Hudson } 277e8e70d83SChris Hudson 278e8e70d83SChris Hudson static void kxtj9_input_close(struct input_dev *dev) 279e8e70d83SChris Hudson { 280e8e70d83SChris Hudson struct kxtj9_data *tj9 = input_get_drvdata(dev); 281e8e70d83SChris Hudson 282e8e70d83SChris Hudson kxtj9_disable(tj9); 283e8e70d83SChris Hudson } 284e8e70d83SChris Hudson 2855298cc4cSBill Pemberton static void kxtj9_init_input_device(struct kxtj9_data *tj9, 286e8e70d83SChris Hudson struct input_dev *input_dev) 287e8e70d83SChris Hudson { 288e8e70d83SChris Hudson __set_bit(EV_ABS, input_dev->evbit); 289e8e70d83SChris Hudson input_set_abs_params(input_dev, ABS_X, -G_MAX, G_MAX, FUZZ, FLAT); 290e8e70d83SChris Hudson input_set_abs_params(input_dev, ABS_Y, -G_MAX, G_MAX, FUZZ, FLAT); 291e8e70d83SChris Hudson input_set_abs_params(input_dev, ABS_Z, -G_MAX, G_MAX, FUZZ, FLAT); 292e8e70d83SChris Hudson 293e8e70d83SChris Hudson input_dev->name = "kxtj9_accel"; 294e8e70d83SChris Hudson input_dev->id.bustype = BUS_I2C; 295e8e70d83SChris Hudson } 296e8e70d83SChris Hudson 2975298cc4cSBill Pemberton static int kxtj9_setup_input_device(struct kxtj9_data *tj9) 298e8e70d83SChris Hudson { 299e8e70d83SChris Hudson struct input_dev *input_dev; 300e8e70d83SChris Hudson int err; 301e8e70d83SChris Hudson 302e7339118SDmitry Torokhov input_dev = devm_input_allocate_device(&tj9->client->dev); 3034fd9fcf7SDan Carpenter if (!input_dev) { 304e8e70d83SChris Hudson dev_err(&tj9->client->dev, "input device allocate failed\n"); 305e8e70d83SChris Hudson return -ENOMEM; 306e8e70d83SChris Hudson } 307e8e70d83SChris Hudson 308e8e70d83SChris Hudson tj9->input_dev = input_dev; 309e8e70d83SChris Hudson 310e8e70d83SChris Hudson input_dev->open = kxtj9_input_open; 311e8e70d83SChris Hudson input_dev->close = kxtj9_input_close; 312e8e70d83SChris Hudson input_set_drvdata(input_dev, tj9); 313e8e70d83SChris Hudson 314e8e70d83SChris Hudson kxtj9_init_input_device(tj9, input_dev); 315e8e70d83SChris Hudson 316e8e70d83SChris Hudson err = input_register_device(tj9->input_dev); 317e8e70d83SChris Hudson if (err) { 318e8e70d83SChris Hudson dev_err(&tj9->client->dev, 319e8e70d83SChris Hudson "unable to register input polled device %s: %d\n", 320e8e70d83SChris Hudson tj9->input_dev->name, err); 321e8e70d83SChris Hudson return err; 322e8e70d83SChris Hudson } 323e8e70d83SChris Hudson 324e8e70d83SChris Hudson return 0; 325e8e70d83SChris Hudson } 326e8e70d83SChris Hudson 327e8e70d83SChris Hudson /* 328e8e70d83SChris Hudson * When IRQ mode is selected, we need to provide an interface to allow the user 329e8e70d83SChris Hudson * to change the output data rate of the part. For consistency, we are using 330e8e70d83SChris Hudson * the set_poll method, which accepts a poll interval in milliseconds, and then 331e8e70d83SChris Hudson * calls update_odr() while passing this value as an argument. In IRQ mode, the 332e8e70d83SChris Hudson * data outputs will not be read AT the requested poll interval, rather, the 333e8e70d83SChris Hudson * lowest ODR that can support the requested interval. The client application 334e8e70d83SChris Hudson * will be responsible for retrieving data from the input node at the desired 335e8e70d83SChris Hudson * interval. 336e8e70d83SChris Hudson */ 337e8e70d83SChris Hudson 338e8e70d83SChris Hudson /* Returns currently selected poll interval (in ms) */ 339e8e70d83SChris Hudson static ssize_t kxtj9_get_poll(struct device *dev, 340e8e70d83SChris Hudson struct device_attribute *attr, char *buf) 341e8e70d83SChris Hudson { 342e8e70d83SChris Hudson struct i2c_client *client = to_i2c_client(dev); 343e8e70d83SChris Hudson struct kxtj9_data *tj9 = i2c_get_clientdata(client); 344e8e70d83SChris Hudson 345e8e70d83SChris Hudson return sprintf(buf, "%d\n", tj9->last_poll_interval); 346e8e70d83SChris Hudson } 347e8e70d83SChris Hudson 348e8e70d83SChris Hudson /* Allow users to select a new poll interval (in ms) */ 349e8e70d83SChris Hudson static ssize_t kxtj9_set_poll(struct device *dev, struct device_attribute *attr, 350e8e70d83SChris Hudson const char *buf, size_t count) 351e8e70d83SChris Hudson { 352e8e70d83SChris Hudson struct i2c_client *client = to_i2c_client(dev); 353e8e70d83SChris Hudson struct kxtj9_data *tj9 = i2c_get_clientdata(client); 354e8e70d83SChris Hudson struct input_dev *input_dev = tj9->input_dev; 355e8e70d83SChris Hudson unsigned int interval; 356e8e70d83SChris Hudson int error; 357e8e70d83SChris Hudson 358e8e70d83SChris Hudson error = kstrtouint(buf, 10, &interval); 359e8e70d83SChris Hudson if (error < 0) 360e8e70d83SChris Hudson return error; 361e8e70d83SChris Hudson 362e8e70d83SChris Hudson /* Lock the device to prevent races with open/close (and itself) */ 3636eab7ce6SDan Carpenter mutex_lock(&input_dev->mutex); 364e8e70d83SChris Hudson 365e8e70d83SChris Hudson disable_irq(client->irq); 366e8e70d83SChris Hudson 367e8e70d83SChris Hudson /* 368e8e70d83SChris Hudson * Set current interval to the greater of the minimum interval or 369e8e70d83SChris Hudson * the requested interval 370e8e70d83SChris Hudson */ 371e8e70d83SChris Hudson tj9->last_poll_interval = max(interval, tj9->pdata.min_interval); 372e8e70d83SChris Hudson 373e8e70d83SChris Hudson kxtj9_update_odr(tj9, tj9->last_poll_interval); 374e8e70d83SChris Hudson 375e8e70d83SChris Hudson enable_irq(client->irq); 376e8e70d83SChris Hudson mutex_unlock(&input_dev->mutex); 377e8e70d83SChris Hudson 378e8e70d83SChris Hudson return count; 379e8e70d83SChris Hudson } 380e8e70d83SChris Hudson 381e8e70d83SChris Hudson static DEVICE_ATTR(poll, S_IRUGO|S_IWUSR, kxtj9_get_poll, kxtj9_set_poll); 382e8e70d83SChris Hudson 383e8e70d83SChris Hudson static struct attribute *kxtj9_attributes[] = { 384e8e70d83SChris Hudson &dev_attr_poll.attr, 385e8e70d83SChris Hudson NULL 386e8e70d83SChris Hudson }; 387e8e70d83SChris Hudson 388e8e70d83SChris Hudson static struct attribute_group kxtj9_attribute_group = { 389e8e70d83SChris Hudson .attrs = kxtj9_attributes 390e8e70d83SChris Hudson }; 391e8e70d83SChris Hudson 392e8e70d83SChris Hudson 393e8e70d83SChris Hudson #ifdef CONFIG_INPUT_KXTJ9_POLLED_MODE 394e8e70d83SChris Hudson static void kxtj9_poll(struct input_polled_dev *dev) 395e8e70d83SChris Hudson { 396e8e70d83SChris Hudson struct kxtj9_data *tj9 = dev->private; 397e8e70d83SChris Hudson unsigned int poll_interval = dev->poll_interval; 398e8e70d83SChris Hudson 399e8e70d83SChris Hudson kxtj9_report_acceleration_data(tj9); 400e8e70d83SChris Hudson 401e8e70d83SChris Hudson if (poll_interval != tj9->last_poll_interval) { 402e8e70d83SChris Hudson kxtj9_update_odr(tj9, poll_interval); 403e8e70d83SChris Hudson tj9->last_poll_interval = poll_interval; 404e8e70d83SChris Hudson } 405e8e70d83SChris Hudson } 406e8e70d83SChris Hudson 407e8e70d83SChris Hudson static void kxtj9_polled_input_open(struct input_polled_dev *dev) 408e8e70d83SChris Hudson { 409e8e70d83SChris Hudson struct kxtj9_data *tj9 = dev->private; 410e8e70d83SChris Hudson 411e8e70d83SChris Hudson kxtj9_enable(tj9); 412e8e70d83SChris Hudson } 413e8e70d83SChris Hudson 414e8e70d83SChris Hudson static void kxtj9_polled_input_close(struct input_polled_dev *dev) 415e8e70d83SChris Hudson { 416e8e70d83SChris Hudson struct kxtj9_data *tj9 = dev->private; 417e8e70d83SChris Hudson 418e8e70d83SChris Hudson kxtj9_disable(tj9); 419e8e70d83SChris Hudson } 420e8e70d83SChris Hudson 4215298cc4cSBill Pemberton static int kxtj9_setup_polled_device(struct kxtj9_data *tj9) 422e8e70d83SChris Hudson { 423e8e70d83SChris Hudson int err; 424e8e70d83SChris Hudson struct input_polled_dev *poll_dev; 425e8e70d83SChris Hudson 426e7339118SDmitry Torokhov poll_dev = devm_input_allocate_polled_device(&tj9->client->dev); 427e8e70d83SChris Hudson if (!poll_dev) { 428e8e70d83SChris Hudson dev_err(&tj9->client->dev, 429e8e70d83SChris Hudson "Failed to allocate polled device\n"); 430e8e70d83SChris Hudson return -ENOMEM; 431e8e70d83SChris Hudson } 432e8e70d83SChris Hudson 433e8e70d83SChris Hudson tj9->poll_dev = poll_dev; 434e8e70d83SChris Hudson tj9->input_dev = poll_dev->input; 435e8e70d83SChris Hudson 436e8e70d83SChris Hudson poll_dev->private = tj9; 437e8e70d83SChris Hudson poll_dev->poll = kxtj9_poll; 438e8e70d83SChris Hudson poll_dev->open = kxtj9_polled_input_open; 439e8e70d83SChris Hudson poll_dev->close = kxtj9_polled_input_close; 440e8e70d83SChris Hudson 441e8e70d83SChris Hudson kxtj9_init_input_device(tj9, poll_dev->input); 442e8e70d83SChris Hudson 443e8e70d83SChris Hudson err = input_register_polled_device(poll_dev); 444e8e70d83SChris Hudson if (err) { 445e8e70d83SChris Hudson dev_err(&tj9->client->dev, 446e8e70d83SChris Hudson "Unable to register polled device, err=%d\n", err); 447e8e70d83SChris Hudson return err; 448e8e70d83SChris Hudson } 449e8e70d83SChris Hudson 450e8e70d83SChris Hudson return 0; 451e8e70d83SChris Hudson } 452e8e70d83SChris Hudson 453e8e70d83SChris Hudson #else 454e8e70d83SChris Hudson 455e8e70d83SChris Hudson static inline int kxtj9_setup_polled_device(struct kxtj9_data *tj9) 456e8e70d83SChris Hudson { 457e8e70d83SChris Hudson return -ENOSYS; 458e8e70d83SChris Hudson } 459e8e70d83SChris Hudson 460e8e70d83SChris Hudson #endif 461e8e70d83SChris Hudson 462e7339118SDmitry Torokhov static void kxtj9_platform_exit(void *data) 463e7339118SDmitry Torokhov { 464e7339118SDmitry Torokhov struct kxtj9_data *tj9 = data; 465e7339118SDmitry Torokhov 466e7339118SDmitry Torokhov if (tj9->pdata.exit) 467e7339118SDmitry Torokhov tj9->pdata.exit(); 468e7339118SDmitry Torokhov } 469e7339118SDmitry Torokhov 4705298cc4cSBill Pemberton static int kxtj9_verify(struct kxtj9_data *tj9) 471e8e70d83SChris Hudson { 472e8e70d83SChris Hudson int retval; 473e8e70d83SChris Hudson 474e8e70d83SChris Hudson retval = kxtj9_device_power_on(tj9); 475e8e70d83SChris Hudson if (retval < 0) 476e8e70d83SChris Hudson return retval; 477e8e70d83SChris Hudson 478e8e70d83SChris Hudson retval = i2c_smbus_read_byte_data(tj9->client, WHO_AM_I); 479e8e70d83SChris Hudson if (retval < 0) { 480e8e70d83SChris Hudson dev_err(&tj9->client->dev, "read err int source\n"); 481e8e70d83SChris Hudson goto out; 482e8e70d83SChris Hudson } 483e8e70d83SChris Hudson 48404391660SChristopher Hudson retval = (retval != 0x07 && retval != 0x08) ? -EIO : 0; 485e8e70d83SChris Hudson 486e8e70d83SChris Hudson out: 487e8e70d83SChris Hudson kxtj9_device_power_off(tj9); 488e8e70d83SChris Hudson return retval; 489e8e70d83SChris Hudson } 490e8e70d83SChris Hudson 4915298cc4cSBill Pemberton static int kxtj9_probe(struct i2c_client *client, 492e8e70d83SChris Hudson const struct i2c_device_id *id) 493e8e70d83SChris Hudson { 494c838cb3dSJingoo Han const struct kxtj9_platform_data *pdata = 495c838cb3dSJingoo Han dev_get_platdata(&client->dev); 496e8e70d83SChris Hudson struct kxtj9_data *tj9; 497e8e70d83SChris Hudson int err; 498e8e70d83SChris Hudson 499e8e70d83SChris Hudson if (!i2c_check_functionality(client->adapter, 500e8e70d83SChris Hudson I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE_DATA)) { 501e8e70d83SChris Hudson dev_err(&client->dev, "client is not i2c capable\n"); 502e8e70d83SChris Hudson return -ENXIO; 503e8e70d83SChris Hudson } 504e8e70d83SChris Hudson 505e8e70d83SChris Hudson if (!pdata) { 506e8e70d83SChris Hudson dev_err(&client->dev, "platform data is NULL; exiting\n"); 507e8e70d83SChris Hudson return -EINVAL; 508e8e70d83SChris Hudson } 509e8e70d83SChris Hudson 510e7339118SDmitry Torokhov tj9 = devm_kzalloc(&client->dev, sizeof(*tj9), GFP_KERNEL); 511e8e70d83SChris Hudson if (!tj9) { 512e8e70d83SChris Hudson dev_err(&client->dev, 513e8e70d83SChris Hudson "failed to allocate memory for module data\n"); 514e8e70d83SChris Hudson return -ENOMEM; 515e8e70d83SChris Hudson } 516e8e70d83SChris Hudson 517e8e70d83SChris Hudson tj9->client = client; 518e8e70d83SChris Hudson tj9->pdata = *pdata; 519e8e70d83SChris Hudson 520e8e70d83SChris Hudson if (pdata->init) { 521e8e70d83SChris Hudson err = pdata->init(); 522e8e70d83SChris Hudson if (err < 0) 523e7339118SDmitry Torokhov return err; 524e8e70d83SChris Hudson } 525e8e70d83SChris Hudson 526e7339118SDmitry Torokhov err = devm_add_action_or_reset(&client->dev, kxtj9_platform_exit, tj9); 527e7339118SDmitry Torokhov if (err) 528e7339118SDmitry Torokhov return err; 529e7339118SDmitry Torokhov 530e8e70d83SChris Hudson err = kxtj9_verify(tj9); 531e8e70d83SChris Hudson if (err < 0) { 532e8e70d83SChris Hudson dev_err(&client->dev, "device not recognized\n"); 533e7339118SDmitry Torokhov return err; 534e8e70d83SChris Hudson } 535e8e70d83SChris Hudson 536e8e70d83SChris Hudson i2c_set_clientdata(client, tj9); 537e8e70d83SChris Hudson 538e8e70d83SChris Hudson tj9->ctrl_reg1 = tj9->pdata.res_12bit | tj9->pdata.g_range; 53904391660SChristopher Hudson tj9->last_poll_interval = tj9->pdata.init_interval; 540e8e70d83SChris Hudson 541e8e70d83SChris Hudson if (client->irq) { 542e8e70d83SChris Hudson /* If in irq mode, populate INT_CTRL_REG1 and enable DRDY. */ 543e8e70d83SChris Hudson tj9->int_ctrl |= KXTJ9_IEN | KXTJ9_IEA | KXTJ9_IEL; 544e8e70d83SChris Hudson tj9->ctrl_reg1 |= DRDYE; 545e8e70d83SChris Hudson 546e8e70d83SChris Hudson err = kxtj9_setup_input_device(tj9); 547e8e70d83SChris Hudson if (err) 548e7339118SDmitry Torokhov return err; 549e8e70d83SChris Hudson 550e7339118SDmitry Torokhov err = devm_request_threaded_irq(&client->dev, client->irq, 551e7339118SDmitry Torokhov NULL, kxtj9_isr, 552e7339118SDmitry Torokhov IRQF_TRIGGER_RISING | 553e7339118SDmitry Torokhov IRQF_ONESHOT, 554e8e70d83SChris Hudson "kxtj9-irq", tj9); 555e8e70d83SChris Hudson if (err) { 556e8e70d83SChris Hudson dev_err(&client->dev, "request irq failed: %d\n", err); 557e7339118SDmitry Torokhov return err; 558e8e70d83SChris Hudson } 559e8e70d83SChris Hudson 560e7339118SDmitry Torokhov err = devm_device_add_group(&client->dev, 561e7339118SDmitry Torokhov &kxtj9_attribute_group); 562e8e70d83SChris Hudson if (err) { 563e8e70d83SChris Hudson dev_err(&client->dev, "sysfs create failed: %d\n", err); 564e7339118SDmitry Torokhov return err; 565e8e70d83SChris Hudson } 566e8e70d83SChris Hudson 567e8e70d83SChris Hudson } else { 568e8e70d83SChris Hudson err = kxtj9_setup_polled_device(tj9); 569e8e70d83SChris Hudson if (err) 570e8e70d83SChris Hudson return err; 571e8e70d83SChris Hudson } 572e8e70d83SChris Hudson 573e8e70d83SChris Hudson return 0; 574e8e70d83SChris Hudson } 575e8e70d83SChris Hudson 57697a652a8SJingoo Han static int __maybe_unused kxtj9_suspend(struct device *dev) 577e8e70d83SChris Hudson { 578e8e70d83SChris Hudson struct i2c_client *client = to_i2c_client(dev); 579e8e70d83SChris Hudson struct kxtj9_data *tj9 = i2c_get_clientdata(client); 580e8e70d83SChris Hudson struct input_dev *input_dev = tj9->input_dev; 581e8e70d83SChris Hudson 582e8e70d83SChris Hudson mutex_lock(&input_dev->mutex); 583e8e70d83SChris Hudson 584e8e70d83SChris Hudson if (input_dev->users) 585e8e70d83SChris Hudson kxtj9_disable(tj9); 586e8e70d83SChris Hudson 587e8e70d83SChris Hudson mutex_unlock(&input_dev->mutex); 588e8e70d83SChris Hudson return 0; 589e8e70d83SChris Hudson } 590e8e70d83SChris Hudson 59197a652a8SJingoo Han static int __maybe_unused kxtj9_resume(struct device *dev) 592e8e70d83SChris Hudson { 593e8e70d83SChris Hudson struct i2c_client *client = to_i2c_client(dev); 594e8e70d83SChris Hudson struct kxtj9_data *tj9 = i2c_get_clientdata(client); 595e8e70d83SChris Hudson struct input_dev *input_dev = tj9->input_dev; 596e8e70d83SChris Hudson 597e8e70d83SChris Hudson mutex_lock(&input_dev->mutex); 598e8e70d83SChris Hudson 599e8e70d83SChris Hudson if (input_dev->users) 600e8e70d83SChris Hudson kxtj9_enable(tj9); 601e8e70d83SChris Hudson 602e8e70d83SChris Hudson mutex_unlock(&input_dev->mutex); 6035ccd9abdSJavier Martinez Canillas return 0; 604e8e70d83SChris Hudson } 605e8e70d83SChris Hudson 606e8e70d83SChris Hudson static SIMPLE_DEV_PM_OPS(kxtj9_pm_ops, kxtj9_suspend, kxtj9_resume); 607e8e70d83SChris Hudson 608e8e70d83SChris Hudson static const struct i2c_device_id kxtj9_id[] = { 609e8e70d83SChris Hudson { NAME, 0 }, 610e8e70d83SChris Hudson { }, 611e8e70d83SChris Hudson }; 612e8e70d83SChris Hudson 613e8e70d83SChris Hudson MODULE_DEVICE_TABLE(i2c, kxtj9_id); 614e8e70d83SChris Hudson 615e8e70d83SChris Hudson static struct i2c_driver kxtj9_driver = { 616e8e70d83SChris Hudson .driver = { 617e8e70d83SChris Hudson .name = NAME, 618e8e70d83SChris Hudson .pm = &kxtj9_pm_ops, 619e8e70d83SChris Hudson }, 620e8e70d83SChris Hudson .probe = kxtj9_probe, 621e8e70d83SChris Hudson .id_table = kxtj9_id, 622e8e70d83SChris Hudson }; 623e8e70d83SChris Hudson 6241b92c1cfSAxel Lin module_i2c_driver(kxtj9_driver); 625e8e70d83SChris Hudson 626e8e70d83SChris Hudson MODULE_DESCRIPTION("KXTJ9 accelerometer driver"); 627e8e70d83SChris Hudson MODULE_AUTHOR("Chris Hudson <chudson@kionix.com>"); 628e8e70d83SChris Hudson MODULE_LICENSE("GPL"); 629