11a4fbf6aSSrinivas Pandruvada /* 21a4fbf6aSSrinivas Pandruvada * KXCJK-1013 3-axis accelerometer driver 31a4fbf6aSSrinivas Pandruvada * Copyright (c) 2014, Intel Corporation. 41a4fbf6aSSrinivas Pandruvada * 51a4fbf6aSSrinivas Pandruvada * This program is free software; you can redistribute it and/or modify it 61a4fbf6aSSrinivas Pandruvada * under the terms and conditions of the GNU General Public License, 71a4fbf6aSSrinivas Pandruvada * version 2, as published by the Free Software Foundation. 81a4fbf6aSSrinivas Pandruvada * 91a4fbf6aSSrinivas Pandruvada * This program is distributed in the hope it will be useful, but WITHOUT 101a4fbf6aSSrinivas Pandruvada * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 111a4fbf6aSSrinivas Pandruvada * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 121a4fbf6aSSrinivas Pandruvada * more details. 131a4fbf6aSSrinivas Pandruvada */ 141a4fbf6aSSrinivas Pandruvada 151a4fbf6aSSrinivas Pandruvada #include <linux/module.h> 161a4fbf6aSSrinivas Pandruvada #include <linux/i2c.h> 171a4fbf6aSSrinivas Pandruvada #include <linux/interrupt.h> 181a4fbf6aSSrinivas Pandruvada #include <linux/delay.h> 191a4fbf6aSSrinivas Pandruvada #include <linux/bitops.h> 201a4fbf6aSSrinivas Pandruvada #include <linux/slab.h> 211a4fbf6aSSrinivas Pandruvada #include <linux/string.h> 221a4fbf6aSSrinivas Pandruvada #include <linux/acpi.h> 23124e1b1dSSrinivas Pandruvada #include <linux/pm.h> 24124e1b1dSSrinivas Pandruvada #include <linux/pm_runtime.h> 251a4fbf6aSSrinivas Pandruvada #include <linux/iio/iio.h> 261a4fbf6aSSrinivas Pandruvada #include <linux/iio/sysfs.h> 271a4fbf6aSSrinivas Pandruvada #include <linux/iio/buffer.h> 281a4fbf6aSSrinivas Pandruvada #include <linux/iio/trigger.h> 29b4b491c0SSrinivas Pandruvada #include <linux/iio/events.h> 301a4fbf6aSSrinivas Pandruvada #include <linux/iio/trigger_consumer.h> 311a4fbf6aSSrinivas Pandruvada #include <linux/iio/triggered_buffer.h> 321a4fbf6aSSrinivas Pandruvada #include <linux/iio/accel/kxcjk_1013.h> 331a4fbf6aSSrinivas Pandruvada 341a4fbf6aSSrinivas Pandruvada #define KXCJK1013_DRV_NAME "kxcjk1013" 351a4fbf6aSSrinivas Pandruvada #define KXCJK1013_IRQ_NAME "kxcjk1013_event" 361a4fbf6aSSrinivas Pandruvada 371a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_XOUT_L 0x06 381a4fbf6aSSrinivas Pandruvada /* 391a4fbf6aSSrinivas Pandruvada * From low byte X axis register, all the other addresses of Y and Z can be 401a4fbf6aSSrinivas Pandruvada * obtained by just applying axis offset. The following axis defines are just 411a4fbf6aSSrinivas Pandruvada * provide clarity, but not used. 421a4fbf6aSSrinivas Pandruvada */ 431a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_XOUT_H 0x07 441a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_YOUT_L 0x08 451a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_YOUT_H 0x09 461a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_ZOUT_L 0x0A 471a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_ZOUT_H 0x0B 481a4fbf6aSSrinivas Pandruvada 491a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_DCST_RESP 0x0C 501a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_WHO_AM_I 0x0F 511a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_INT_SRC1 0x16 521a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_INT_SRC2 0x17 531a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_STATUS_REG 0x18 541a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_INT_REL 0x1A 551a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_CTRL1 0x1B 561a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_CTRL2 0x1D 571a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_INT_CTRL1 0x1E 581a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_INT_CTRL2 0x1F 591a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_DATA_CTRL 0x21 601a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_WAKE_TIMER 0x29 611a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_SELF_TEST 0x3A 621a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_WAKE_THRES 0x6A 631a4fbf6aSSrinivas Pandruvada 641a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_CTRL1_BIT_PC1 BIT(7) 651a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_CTRL1_BIT_RES BIT(6) 661a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_CTRL1_BIT_DRDY BIT(5) 671a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_CTRL1_BIT_GSEL1 BIT(4) 681a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_CTRL1_BIT_GSEL0 BIT(3) 691a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_CTRL1_BIT_WUFE BIT(1) 701a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_INT_REG1_BIT_IEA BIT(4) 711a4fbf6aSSrinivas Pandruvada #define KXCJK1013_REG_INT_REG1_BIT_IEN BIT(5) 721a4fbf6aSSrinivas Pandruvada 731a4fbf6aSSrinivas Pandruvada #define KXCJK1013_DATA_MASK_12_BIT 0x0FFF 741a4fbf6aSSrinivas Pandruvada #define KXCJK1013_MAX_STARTUP_TIME_US 100000 751a4fbf6aSSrinivas Pandruvada 76124e1b1dSSrinivas Pandruvada #define KXCJK1013_SLEEP_DELAY_MS 2000 77124e1b1dSSrinivas Pandruvada 78b4b491c0SSrinivas Pandruvada #define KXCJK1013_REG_INT_SRC2_BIT_ZP BIT(0) 79b4b491c0SSrinivas Pandruvada #define KXCJK1013_REG_INT_SRC2_BIT_ZN BIT(1) 80b4b491c0SSrinivas Pandruvada #define KXCJK1013_REG_INT_SRC2_BIT_YP BIT(2) 81b4b491c0SSrinivas Pandruvada #define KXCJK1013_REG_INT_SRC2_BIT_YN BIT(3) 82b4b491c0SSrinivas Pandruvada #define KXCJK1013_REG_INT_SRC2_BIT_XP BIT(4) 83b4b491c0SSrinivas Pandruvada #define KXCJK1013_REG_INT_SRC2_BIT_XN BIT(5) 84b4b491c0SSrinivas Pandruvada 85b4b491c0SSrinivas Pandruvada #define KXCJK1013_DEFAULT_WAKE_THRES 1 86b4b491c0SSrinivas Pandruvada 87c6861377SDaniel Baluta enum kx_chipset { 88c6861377SDaniel Baluta KXCJK1013, 89c6861377SDaniel Baluta KXCJ91008, 90c6861377SDaniel Baluta KXTJ21009, 91c6861377SDaniel Baluta KX_MAX_CHIPS /* this must be last */ 92c6861377SDaniel Baluta }; 93c6861377SDaniel Baluta 941a4fbf6aSSrinivas Pandruvada struct kxcjk1013_data { 951a4fbf6aSSrinivas Pandruvada struct i2c_client *client; 96b4b491c0SSrinivas Pandruvada struct iio_trigger *dready_trig; 97b4b491c0SSrinivas Pandruvada struct iio_trigger *motion_trig; 981a4fbf6aSSrinivas Pandruvada struct mutex mutex; 991a4fbf6aSSrinivas Pandruvada s16 buffer[8]; 1001a4fbf6aSSrinivas Pandruvada u8 odr_bits; 101a735e3d7SSrinivas Pandruvada u8 range; 102b4b491c0SSrinivas Pandruvada int wake_thres; 103b4b491c0SSrinivas Pandruvada int wake_dur; 1041a4fbf6aSSrinivas Pandruvada bool active_high_intr; 105b4b491c0SSrinivas Pandruvada bool dready_trigger_on; 106b4b491c0SSrinivas Pandruvada int ev_enable_state; 107b4b491c0SSrinivas Pandruvada bool motion_trigger_on; 108b4b491c0SSrinivas Pandruvada int64_t timestamp; 109c6861377SDaniel Baluta enum kx_chipset chipset; 1103bfa74f8SBastien Nocera bool is_smo8500_device; 1111a4fbf6aSSrinivas Pandruvada }; 1121a4fbf6aSSrinivas Pandruvada 1131a4fbf6aSSrinivas Pandruvada enum kxcjk1013_axis { 1141a4fbf6aSSrinivas Pandruvada AXIS_X, 1151a4fbf6aSSrinivas Pandruvada AXIS_Y, 1161a4fbf6aSSrinivas Pandruvada AXIS_Z, 11709cf1b32SAdriana Reus AXIS_MAX, 1181a4fbf6aSSrinivas Pandruvada }; 1191a4fbf6aSSrinivas Pandruvada 1201a4fbf6aSSrinivas Pandruvada enum kxcjk1013_mode { 1211a4fbf6aSSrinivas Pandruvada STANDBY, 1221a4fbf6aSSrinivas Pandruvada OPERATION, 1231a4fbf6aSSrinivas Pandruvada }; 1241a4fbf6aSSrinivas Pandruvada 125a735e3d7SSrinivas Pandruvada enum kxcjk1013_range { 126a735e3d7SSrinivas Pandruvada KXCJK1013_RANGE_2G, 127a735e3d7SSrinivas Pandruvada KXCJK1013_RANGE_4G, 128a735e3d7SSrinivas Pandruvada KXCJK1013_RANGE_8G, 129a735e3d7SSrinivas Pandruvada }; 130a735e3d7SSrinivas Pandruvada 1311a4fbf6aSSrinivas Pandruvada static const struct { 1321a4fbf6aSSrinivas Pandruvada int val; 1331a4fbf6aSSrinivas Pandruvada int val2; 1341a4fbf6aSSrinivas Pandruvada int odr_bits; 1351a4fbf6aSSrinivas Pandruvada } samp_freq_table[] = { {0, 781000, 0x08}, {1, 563000, 0x09}, 136f0ca9749SSrinivas Pandruvada {3, 125000, 0x0A}, {6, 250000, 0x0B}, {12, 500000, 0}, 1371a4fbf6aSSrinivas Pandruvada {25, 0, 0x01}, {50, 0, 0x02}, {100, 0, 0x03}, 1381a4fbf6aSSrinivas Pandruvada {200, 0, 0x04}, {400, 0, 0x05}, {800, 0, 0x06}, 1391a4fbf6aSSrinivas Pandruvada {1600, 0, 0x07} }; 1401a4fbf6aSSrinivas Pandruvada 1411a4fbf6aSSrinivas Pandruvada /* Refer to section 4 of the specification */ 1421a4fbf6aSSrinivas Pandruvada static const struct { 1431a4fbf6aSSrinivas Pandruvada int odr_bits; 1441a4fbf6aSSrinivas Pandruvada int usec; 145c6861377SDaniel Baluta } odr_start_up_times[KX_MAX_CHIPS][12] = { 146c6861377SDaniel Baluta /* KXCJK-1013 */ 147c6861377SDaniel Baluta { 148c6861377SDaniel Baluta {0x08, 100000}, 149c6861377SDaniel Baluta {0x09, 100000}, 150c6861377SDaniel Baluta {0x0A, 100000}, 151c6861377SDaniel Baluta {0x0B, 100000}, 152c6861377SDaniel Baluta {0, 80000}, 153c6861377SDaniel Baluta {0x01, 41000}, 154c6861377SDaniel Baluta {0x02, 21000}, 155c6861377SDaniel Baluta {0x03, 11000}, 156c6861377SDaniel Baluta {0x04, 6400}, 157c6861377SDaniel Baluta {0x05, 3900}, 158c6861377SDaniel Baluta {0x06, 2700}, 159c6861377SDaniel Baluta {0x07, 2100}, 160c6861377SDaniel Baluta }, 161c6861377SDaniel Baluta /* KXCJ9-1008 */ 162c6861377SDaniel Baluta { 163c6861377SDaniel Baluta {0x08, 100000}, 164c6861377SDaniel Baluta {0x09, 100000}, 165c6861377SDaniel Baluta {0x0A, 100000}, 166c6861377SDaniel Baluta {0x0B, 100000}, 167c6861377SDaniel Baluta {0, 80000}, 168c6861377SDaniel Baluta {0x01, 41000}, 169c6861377SDaniel Baluta {0x02, 21000}, 170c6861377SDaniel Baluta {0x03, 11000}, 171c6861377SDaniel Baluta {0x04, 6400}, 172c6861377SDaniel Baluta {0x05, 3900}, 173c6861377SDaniel Baluta {0x06, 2700}, 174c6861377SDaniel Baluta {0x07, 2100}, 175c6861377SDaniel Baluta }, 176c6861377SDaniel Baluta /* KXCTJ2-1009 */ 177c6861377SDaniel Baluta { 178c6861377SDaniel Baluta {0x08, 1240000}, 179c6861377SDaniel Baluta {0x09, 621000}, 180c6861377SDaniel Baluta {0x0A, 309000}, 181c6861377SDaniel Baluta {0x0B, 151000}, 182c6861377SDaniel Baluta {0, 80000}, 183c6861377SDaniel Baluta {0x01, 41000}, 184c6861377SDaniel Baluta {0x02, 21000}, 185c6861377SDaniel Baluta {0x03, 11000}, 186c6861377SDaniel Baluta {0x04, 6000}, 187c6861377SDaniel Baluta {0x05, 4000}, 188c6861377SDaniel Baluta {0x06, 3000}, 189c6861377SDaniel Baluta {0x07, 2000}, 190c6861377SDaniel Baluta }, 191c6861377SDaniel Baluta }; 1921a4fbf6aSSrinivas Pandruvada 193a735e3d7SSrinivas Pandruvada static const struct { 194a735e3d7SSrinivas Pandruvada u16 scale; 195a735e3d7SSrinivas Pandruvada u8 gsel_0; 196a735e3d7SSrinivas Pandruvada u8 gsel_1; 197a735e3d7SSrinivas Pandruvada } KXCJK1013_scale_table[] = { {9582, 0, 0}, 198a735e3d7SSrinivas Pandruvada {19163, 1, 0}, 199a735e3d7SSrinivas Pandruvada {38326, 0, 1} }; 200a735e3d7SSrinivas Pandruvada 201b4b491c0SSrinivas Pandruvada static const struct { 202b4b491c0SSrinivas Pandruvada int val; 203b4b491c0SSrinivas Pandruvada int val2; 204b4b491c0SSrinivas Pandruvada int odr_bits; 205b4b491c0SSrinivas Pandruvada } wake_odr_data_rate_table[] = { {0, 781000, 0x00}, 206b4b491c0SSrinivas Pandruvada {1, 563000, 0x01}, 207b4b491c0SSrinivas Pandruvada {3, 125000, 0x02}, 208b4b491c0SSrinivas Pandruvada {6, 250000, 0x03}, 209b4b491c0SSrinivas Pandruvada {12, 500000, 0x04}, 210b4b491c0SSrinivas Pandruvada {25, 0, 0x05}, 211b4b491c0SSrinivas Pandruvada {50, 0, 0x06}, 212b4b491c0SSrinivas Pandruvada {100, 0, 0x06}, 213b4b491c0SSrinivas Pandruvada {200, 0, 0x06}, 214b4b491c0SSrinivas Pandruvada {400, 0, 0x06}, 215b4b491c0SSrinivas Pandruvada {800, 0, 0x06}, 216b4b491c0SSrinivas Pandruvada {1600, 0, 0x06} }; 217b4b491c0SSrinivas Pandruvada 2181a4fbf6aSSrinivas Pandruvada static int kxcjk1013_set_mode(struct kxcjk1013_data *data, 2191a4fbf6aSSrinivas Pandruvada enum kxcjk1013_mode mode) 2201a4fbf6aSSrinivas Pandruvada { 2211a4fbf6aSSrinivas Pandruvada int ret; 2221a4fbf6aSSrinivas Pandruvada 2231a4fbf6aSSrinivas Pandruvada ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1); 2241a4fbf6aSSrinivas Pandruvada if (ret < 0) { 2251a4fbf6aSSrinivas Pandruvada dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); 2261a4fbf6aSSrinivas Pandruvada return ret; 2271a4fbf6aSSrinivas Pandruvada } 2281a4fbf6aSSrinivas Pandruvada 2291a4fbf6aSSrinivas Pandruvada if (mode == STANDBY) 2301a4fbf6aSSrinivas Pandruvada ret &= ~KXCJK1013_REG_CTRL1_BIT_PC1; 2311a4fbf6aSSrinivas Pandruvada else 2321a4fbf6aSSrinivas Pandruvada ret |= KXCJK1013_REG_CTRL1_BIT_PC1; 2331a4fbf6aSSrinivas Pandruvada 2341a4fbf6aSSrinivas Pandruvada ret = i2c_smbus_write_byte_data(data->client, 2351a4fbf6aSSrinivas Pandruvada KXCJK1013_REG_CTRL1, ret); 2361a4fbf6aSSrinivas Pandruvada if (ret < 0) { 2371a4fbf6aSSrinivas Pandruvada dev_err(&data->client->dev, "Error writing reg_ctrl1\n"); 2381a4fbf6aSSrinivas Pandruvada return ret; 2391a4fbf6aSSrinivas Pandruvada } 2401a4fbf6aSSrinivas Pandruvada 2411a4fbf6aSSrinivas Pandruvada return 0; 2421a4fbf6aSSrinivas Pandruvada } 2431a4fbf6aSSrinivas Pandruvada 244124e1b1dSSrinivas Pandruvada static int kxcjk1013_get_mode(struct kxcjk1013_data *data, 245124e1b1dSSrinivas Pandruvada enum kxcjk1013_mode *mode) 246124e1b1dSSrinivas Pandruvada { 247124e1b1dSSrinivas Pandruvada int ret; 248124e1b1dSSrinivas Pandruvada 249124e1b1dSSrinivas Pandruvada ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1); 250124e1b1dSSrinivas Pandruvada if (ret < 0) { 251124e1b1dSSrinivas Pandruvada dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); 252124e1b1dSSrinivas Pandruvada return ret; 253124e1b1dSSrinivas Pandruvada } 254124e1b1dSSrinivas Pandruvada 255124e1b1dSSrinivas Pandruvada if (ret & KXCJK1013_REG_CTRL1_BIT_PC1) 256124e1b1dSSrinivas Pandruvada *mode = OPERATION; 257124e1b1dSSrinivas Pandruvada else 258124e1b1dSSrinivas Pandruvada *mode = STANDBY; 259124e1b1dSSrinivas Pandruvada 260124e1b1dSSrinivas Pandruvada return 0; 261124e1b1dSSrinivas Pandruvada } 262124e1b1dSSrinivas Pandruvada 263a735e3d7SSrinivas Pandruvada static int kxcjk1013_set_range(struct kxcjk1013_data *data, int range_index) 264a735e3d7SSrinivas Pandruvada { 265a735e3d7SSrinivas Pandruvada int ret; 266a735e3d7SSrinivas Pandruvada 267a735e3d7SSrinivas Pandruvada ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1); 268a735e3d7SSrinivas Pandruvada if (ret < 0) { 269a735e3d7SSrinivas Pandruvada dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); 270a735e3d7SSrinivas Pandruvada return ret; 271a735e3d7SSrinivas Pandruvada } 272a735e3d7SSrinivas Pandruvada 273e90dea6aSDaniel Baluta ret &= ~(KXCJK1013_REG_CTRL1_BIT_GSEL0 | 274e90dea6aSDaniel Baluta KXCJK1013_REG_CTRL1_BIT_GSEL1); 275a735e3d7SSrinivas Pandruvada ret |= (KXCJK1013_scale_table[range_index].gsel_0 << 3); 276a735e3d7SSrinivas Pandruvada ret |= (KXCJK1013_scale_table[range_index].gsel_1 << 4); 277a735e3d7SSrinivas Pandruvada 278a735e3d7SSrinivas Pandruvada ret = i2c_smbus_write_byte_data(data->client, 279a735e3d7SSrinivas Pandruvada KXCJK1013_REG_CTRL1, 280a735e3d7SSrinivas Pandruvada ret); 281a735e3d7SSrinivas Pandruvada if (ret < 0) { 282a735e3d7SSrinivas Pandruvada dev_err(&data->client->dev, "Error writing reg_ctrl1\n"); 283a735e3d7SSrinivas Pandruvada return ret; 284a735e3d7SSrinivas Pandruvada } 285a735e3d7SSrinivas Pandruvada 286a735e3d7SSrinivas Pandruvada data->range = range_index; 287a735e3d7SSrinivas Pandruvada 288a735e3d7SSrinivas Pandruvada return 0; 289a735e3d7SSrinivas Pandruvada } 290a735e3d7SSrinivas Pandruvada 2911a4fbf6aSSrinivas Pandruvada static int kxcjk1013_chip_init(struct kxcjk1013_data *data) 2921a4fbf6aSSrinivas Pandruvada { 2931a4fbf6aSSrinivas Pandruvada int ret; 2941a4fbf6aSSrinivas Pandruvada 2951a4fbf6aSSrinivas Pandruvada ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_WHO_AM_I); 2961a4fbf6aSSrinivas Pandruvada if (ret < 0) { 2971a4fbf6aSSrinivas Pandruvada dev_err(&data->client->dev, "Error reading who_am_i\n"); 2981a4fbf6aSSrinivas Pandruvada return ret; 2991a4fbf6aSSrinivas Pandruvada } 3001a4fbf6aSSrinivas Pandruvada 3011a4fbf6aSSrinivas Pandruvada dev_dbg(&data->client->dev, "KXCJK1013 Chip Id %x\n", ret); 3021a4fbf6aSSrinivas Pandruvada 3031a4fbf6aSSrinivas Pandruvada ret = kxcjk1013_set_mode(data, STANDBY); 3041a4fbf6aSSrinivas Pandruvada if (ret < 0) 3051a4fbf6aSSrinivas Pandruvada return ret; 3061a4fbf6aSSrinivas Pandruvada 3071a4fbf6aSSrinivas Pandruvada ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1); 3081a4fbf6aSSrinivas Pandruvada if (ret < 0) { 3091a4fbf6aSSrinivas Pandruvada dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); 3101a4fbf6aSSrinivas Pandruvada return ret; 3111a4fbf6aSSrinivas Pandruvada } 3121a4fbf6aSSrinivas Pandruvada 3131a4fbf6aSSrinivas Pandruvada /* Set 12 bit mode */ 3141a4fbf6aSSrinivas Pandruvada ret |= KXCJK1013_REG_CTRL1_BIT_RES; 3151a4fbf6aSSrinivas Pandruvada 3161a4fbf6aSSrinivas Pandruvada ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_CTRL1, 3171a4fbf6aSSrinivas Pandruvada ret); 3181a4fbf6aSSrinivas Pandruvada if (ret < 0) { 3191a4fbf6aSSrinivas Pandruvada dev_err(&data->client->dev, "Error reading reg_ctrl\n"); 3201a4fbf6aSSrinivas Pandruvada return ret; 3211a4fbf6aSSrinivas Pandruvada } 3221a4fbf6aSSrinivas Pandruvada 323a735e3d7SSrinivas Pandruvada /* Setting range to 4G */ 324a735e3d7SSrinivas Pandruvada ret = kxcjk1013_set_range(data, KXCJK1013_RANGE_4G); 325a735e3d7SSrinivas Pandruvada if (ret < 0) 326a735e3d7SSrinivas Pandruvada return ret; 327a735e3d7SSrinivas Pandruvada 3281a4fbf6aSSrinivas Pandruvada ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_DATA_CTRL); 3291a4fbf6aSSrinivas Pandruvada if (ret < 0) { 3301a4fbf6aSSrinivas Pandruvada dev_err(&data->client->dev, "Error reading reg_data_ctrl\n"); 3311a4fbf6aSSrinivas Pandruvada return ret; 3321a4fbf6aSSrinivas Pandruvada } 3331a4fbf6aSSrinivas Pandruvada 3341a4fbf6aSSrinivas Pandruvada data->odr_bits = ret; 3351a4fbf6aSSrinivas Pandruvada 3361a4fbf6aSSrinivas Pandruvada /* Set up INT polarity */ 3371a4fbf6aSSrinivas Pandruvada ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_CTRL1); 3381a4fbf6aSSrinivas Pandruvada if (ret < 0) { 3391a4fbf6aSSrinivas Pandruvada dev_err(&data->client->dev, "Error reading reg_int_ctrl1\n"); 3401a4fbf6aSSrinivas Pandruvada return ret; 3411a4fbf6aSSrinivas Pandruvada } 3421a4fbf6aSSrinivas Pandruvada 3431a4fbf6aSSrinivas Pandruvada if (data->active_high_intr) 3441a4fbf6aSSrinivas Pandruvada ret |= KXCJK1013_REG_INT_REG1_BIT_IEA; 3451a4fbf6aSSrinivas Pandruvada else 3461a4fbf6aSSrinivas Pandruvada ret &= ~KXCJK1013_REG_INT_REG1_BIT_IEA; 3471a4fbf6aSSrinivas Pandruvada 3481a4fbf6aSSrinivas Pandruvada ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_INT_CTRL1, 3491a4fbf6aSSrinivas Pandruvada ret); 3501a4fbf6aSSrinivas Pandruvada if (ret < 0) { 3511a4fbf6aSSrinivas Pandruvada dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n"); 3521a4fbf6aSSrinivas Pandruvada return ret; 3531a4fbf6aSSrinivas Pandruvada } 3541a4fbf6aSSrinivas Pandruvada 355124e1b1dSSrinivas Pandruvada ret = kxcjk1013_set_mode(data, OPERATION); 356124e1b1dSSrinivas Pandruvada if (ret < 0) 357124e1b1dSSrinivas Pandruvada return ret; 358124e1b1dSSrinivas Pandruvada 359b4b491c0SSrinivas Pandruvada data->wake_thres = KXCJK1013_DEFAULT_WAKE_THRES; 360b4b491c0SSrinivas Pandruvada 361124e1b1dSSrinivas Pandruvada return 0; 362124e1b1dSSrinivas Pandruvada } 363124e1b1dSSrinivas Pandruvada 3646f0a13f2SRafael J. Wysocki #ifdef CONFIG_PM 365124e1b1dSSrinivas Pandruvada static int kxcjk1013_get_startup_times(struct kxcjk1013_data *data) 366124e1b1dSSrinivas Pandruvada { 367124e1b1dSSrinivas Pandruvada int i; 368c6861377SDaniel Baluta int idx = data->chipset; 369124e1b1dSSrinivas Pandruvada 370c6861377SDaniel Baluta for (i = 0; i < ARRAY_SIZE(odr_start_up_times[idx]); ++i) { 371c6861377SDaniel Baluta if (odr_start_up_times[idx][i].odr_bits == data->odr_bits) 372c6861377SDaniel Baluta return odr_start_up_times[idx][i].usec; 373124e1b1dSSrinivas Pandruvada } 374124e1b1dSSrinivas Pandruvada 375124e1b1dSSrinivas Pandruvada return KXCJK1013_MAX_STARTUP_TIME_US; 376124e1b1dSSrinivas Pandruvada } 377c9bf2373SDaniel Baluta #endif 378124e1b1dSSrinivas Pandruvada 379124e1b1dSSrinivas Pandruvada static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on) 380124e1b1dSSrinivas Pandruvada { 381c75b8dc8SIrina Tirdea #ifdef CONFIG_PM 382124e1b1dSSrinivas Pandruvada int ret; 383124e1b1dSSrinivas Pandruvada 384124e1b1dSSrinivas Pandruvada if (on) 385124e1b1dSSrinivas Pandruvada ret = pm_runtime_get_sync(&data->client->dev); 386124e1b1dSSrinivas Pandruvada else { 387124e1b1dSSrinivas Pandruvada pm_runtime_mark_last_busy(&data->client->dev); 388124e1b1dSSrinivas Pandruvada ret = pm_runtime_put_autosuspend(&data->client->dev); 389124e1b1dSSrinivas Pandruvada } 390124e1b1dSSrinivas Pandruvada if (ret < 0) { 391124e1b1dSSrinivas Pandruvada dev_err(&data->client->dev, 392124e1b1dSSrinivas Pandruvada "Failed: kxcjk1013_set_power_state for %d\n", on); 393fbd123e9SIrina Tirdea if (on) 394fbd123e9SIrina Tirdea pm_runtime_put_noidle(&data->client->dev); 395124e1b1dSSrinivas Pandruvada return ret; 396124e1b1dSSrinivas Pandruvada } 397c75b8dc8SIrina Tirdea #endif 398124e1b1dSSrinivas Pandruvada 3991a4fbf6aSSrinivas Pandruvada return 0; 4001a4fbf6aSSrinivas Pandruvada } 4011a4fbf6aSSrinivas Pandruvada 402b4b491c0SSrinivas Pandruvada static int kxcjk1013_chip_update_thresholds(struct kxcjk1013_data *data) 403b4b491c0SSrinivas Pandruvada { 404b4b491c0SSrinivas Pandruvada int ret; 405b4b491c0SSrinivas Pandruvada 406b4b491c0SSrinivas Pandruvada ret = i2c_smbus_write_byte_data(data->client, 407b4b491c0SSrinivas Pandruvada KXCJK1013_REG_WAKE_TIMER, 408b4b491c0SSrinivas Pandruvada data->wake_dur); 409b4b491c0SSrinivas Pandruvada if (ret < 0) { 410b4b491c0SSrinivas Pandruvada dev_err(&data->client->dev, 411b4b491c0SSrinivas Pandruvada "Error writing reg_wake_timer\n"); 412b4b491c0SSrinivas Pandruvada return ret; 413b4b491c0SSrinivas Pandruvada } 414b4b491c0SSrinivas Pandruvada 415b4b491c0SSrinivas Pandruvada ret = i2c_smbus_write_byte_data(data->client, 416b4b491c0SSrinivas Pandruvada KXCJK1013_REG_WAKE_THRES, 417b4b491c0SSrinivas Pandruvada data->wake_thres); 418b4b491c0SSrinivas Pandruvada if (ret < 0) { 419b4b491c0SSrinivas Pandruvada dev_err(&data->client->dev, "Error writing reg_wake_thres\n"); 420b4b491c0SSrinivas Pandruvada return ret; 421b4b491c0SSrinivas Pandruvada } 422b4b491c0SSrinivas Pandruvada 423b4b491c0SSrinivas Pandruvada return 0; 424b4b491c0SSrinivas Pandruvada } 425b4b491c0SSrinivas Pandruvada 426b4b491c0SSrinivas Pandruvada static int kxcjk1013_setup_any_motion_interrupt(struct kxcjk1013_data *data, 427b4b491c0SSrinivas Pandruvada bool status) 428b4b491c0SSrinivas Pandruvada { 429b4b491c0SSrinivas Pandruvada int ret; 430b4b491c0SSrinivas Pandruvada enum kxcjk1013_mode store_mode; 431b4b491c0SSrinivas Pandruvada 432b4b491c0SSrinivas Pandruvada ret = kxcjk1013_get_mode(data, &store_mode); 433b4b491c0SSrinivas Pandruvada if (ret < 0) 434b4b491c0SSrinivas Pandruvada return ret; 435b4b491c0SSrinivas Pandruvada 436b4b491c0SSrinivas Pandruvada /* This is requirement by spec to change state to STANDBY */ 437b4b491c0SSrinivas Pandruvada ret = kxcjk1013_set_mode(data, STANDBY); 438b4b491c0SSrinivas Pandruvada if (ret < 0) 439b4b491c0SSrinivas Pandruvada return ret; 440b4b491c0SSrinivas Pandruvada 441b4b491c0SSrinivas Pandruvada ret = kxcjk1013_chip_update_thresholds(data); 442b4b491c0SSrinivas Pandruvada if (ret < 0) 443b4b491c0SSrinivas Pandruvada return ret; 444b4b491c0SSrinivas Pandruvada 445b4b491c0SSrinivas Pandruvada ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_CTRL1); 446b4b491c0SSrinivas Pandruvada if (ret < 0) { 447b4b491c0SSrinivas Pandruvada dev_err(&data->client->dev, "Error reading reg_int_ctrl1\n"); 448b4b491c0SSrinivas Pandruvada return ret; 449b4b491c0SSrinivas Pandruvada } 450b4b491c0SSrinivas Pandruvada 451b4b491c0SSrinivas Pandruvada if (status) 452b4b491c0SSrinivas Pandruvada ret |= KXCJK1013_REG_INT_REG1_BIT_IEN; 453b4b491c0SSrinivas Pandruvada else 454b4b491c0SSrinivas Pandruvada ret &= ~KXCJK1013_REG_INT_REG1_BIT_IEN; 455b4b491c0SSrinivas Pandruvada 456b4b491c0SSrinivas Pandruvada ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_INT_CTRL1, 457b4b491c0SSrinivas Pandruvada ret); 458b4b491c0SSrinivas Pandruvada if (ret < 0) { 459b4b491c0SSrinivas Pandruvada dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n"); 460b4b491c0SSrinivas Pandruvada return ret; 461b4b491c0SSrinivas Pandruvada } 462b4b491c0SSrinivas Pandruvada 463b4b491c0SSrinivas Pandruvada ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1); 464b4b491c0SSrinivas Pandruvada if (ret < 0) { 465b4b491c0SSrinivas Pandruvada dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); 466b4b491c0SSrinivas Pandruvada return ret; 467b4b491c0SSrinivas Pandruvada } 468b4b491c0SSrinivas Pandruvada 469b4b491c0SSrinivas Pandruvada if (status) 470b4b491c0SSrinivas Pandruvada ret |= KXCJK1013_REG_CTRL1_BIT_WUFE; 471b4b491c0SSrinivas Pandruvada else 472b4b491c0SSrinivas Pandruvada ret &= ~KXCJK1013_REG_CTRL1_BIT_WUFE; 473b4b491c0SSrinivas Pandruvada 474b4b491c0SSrinivas Pandruvada ret = i2c_smbus_write_byte_data(data->client, 475b4b491c0SSrinivas Pandruvada KXCJK1013_REG_CTRL1, ret); 476b4b491c0SSrinivas Pandruvada if (ret < 0) { 477b4b491c0SSrinivas Pandruvada dev_err(&data->client->dev, "Error writing reg_ctrl1\n"); 478b4b491c0SSrinivas Pandruvada return ret; 479b4b491c0SSrinivas Pandruvada } 480b4b491c0SSrinivas Pandruvada 481b4b491c0SSrinivas Pandruvada if (store_mode == OPERATION) { 482b4b491c0SSrinivas Pandruvada ret = kxcjk1013_set_mode(data, OPERATION); 483b4b491c0SSrinivas Pandruvada if (ret < 0) 484b4b491c0SSrinivas Pandruvada return ret; 485b4b491c0SSrinivas Pandruvada } 486b4b491c0SSrinivas Pandruvada 487b4b491c0SSrinivas Pandruvada return 0; 488b4b491c0SSrinivas Pandruvada } 489b4b491c0SSrinivas Pandruvada 490b4b491c0SSrinivas Pandruvada static int kxcjk1013_setup_new_data_interrupt(struct kxcjk1013_data *data, 4911a4fbf6aSSrinivas Pandruvada bool status) 4921a4fbf6aSSrinivas Pandruvada { 4931a4fbf6aSSrinivas Pandruvada int ret; 494124e1b1dSSrinivas Pandruvada enum kxcjk1013_mode store_mode; 495124e1b1dSSrinivas Pandruvada 496124e1b1dSSrinivas Pandruvada ret = kxcjk1013_get_mode(data, &store_mode); 497124e1b1dSSrinivas Pandruvada if (ret < 0) 498124e1b1dSSrinivas Pandruvada return ret; 4991a4fbf6aSSrinivas Pandruvada 5001a4fbf6aSSrinivas Pandruvada /* This is requirement by spec to change state to STANDBY */ 5011a4fbf6aSSrinivas Pandruvada ret = kxcjk1013_set_mode(data, STANDBY); 5021a4fbf6aSSrinivas Pandruvada if (ret < 0) 5031a4fbf6aSSrinivas Pandruvada return ret; 5041a4fbf6aSSrinivas Pandruvada 5051a4fbf6aSSrinivas Pandruvada ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_CTRL1); 5061a4fbf6aSSrinivas Pandruvada if (ret < 0) { 5071a4fbf6aSSrinivas Pandruvada dev_err(&data->client->dev, "Error reading reg_int_ctrl1\n"); 5081a4fbf6aSSrinivas Pandruvada return ret; 5091a4fbf6aSSrinivas Pandruvada } 5101a4fbf6aSSrinivas Pandruvada 5111a4fbf6aSSrinivas Pandruvada if (status) 5121a4fbf6aSSrinivas Pandruvada ret |= KXCJK1013_REG_INT_REG1_BIT_IEN; 5131a4fbf6aSSrinivas Pandruvada else 5141a4fbf6aSSrinivas Pandruvada ret &= ~KXCJK1013_REG_INT_REG1_BIT_IEN; 5151a4fbf6aSSrinivas Pandruvada 5161a4fbf6aSSrinivas Pandruvada ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_INT_CTRL1, 5171a4fbf6aSSrinivas Pandruvada ret); 5181a4fbf6aSSrinivas Pandruvada if (ret < 0) { 5191a4fbf6aSSrinivas Pandruvada dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n"); 5201a4fbf6aSSrinivas Pandruvada return ret; 5211a4fbf6aSSrinivas Pandruvada } 5221a4fbf6aSSrinivas Pandruvada 5231a4fbf6aSSrinivas Pandruvada ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1); 5241a4fbf6aSSrinivas Pandruvada if (ret < 0) { 5251a4fbf6aSSrinivas Pandruvada dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); 5261a4fbf6aSSrinivas Pandruvada return ret; 5271a4fbf6aSSrinivas Pandruvada } 5281a4fbf6aSSrinivas Pandruvada 5291a4fbf6aSSrinivas Pandruvada if (status) 5301a4fbf6aSSrinivas Pandruvada ret |= KXCJK1013_REG_CTRL1_BIT_DRDY; 5311a4fbf6aSSrinivas Pandruvada else 5321a4fbf6aSSrinivas Pandruvada ret &= ~KXCJK1013_REG_CTRL1_BIT_DRDY; 5331a4fbf6aSSrinivas Pandruvada 5341a4fbf6aSSrinivas Pandruvada ret = i2c_smbus_write_byte_data(data->client, 5351a4fbf6aSSrinivas Pandruvada KXCJK1013_REG_CTRL1, ret); 5361a4fbf6aSSrinivas Pandruvada if (ret < 0) { 5371a4fbf6aSSrinivas Pandruvada dev_err(&data->client->dev, "Error writing reg_ctrl1\n"); 5381a4fbf6aSSrinivas Pandruvada return ret; 5391a4fbf6aSSrinivas Pandruvada } 5401a4fbf6aSSrinivas Pandruvada 541124e1b1dSSrinivas Pandruvada if (store_mode == OPERATION) { 542124e1b1dSSrinivas Pandruvada ret = kxcjk1013_set_mode(data, OPERATION); 543124e1b1dSSrinivas Pandruvada if (ret < 0) 5441a4fbf6aSSrinivas Pandruvada return ret; 5451a4fbf6aSSrinivas Pandruvada } 5461a4fbf6aSSrinivas Pandruvada 547124e1b1dSSrinivas Pandruvada return 0; 548124e1b1dSSrinivas Pandruvada } 549124e1b1dSSrinivas Pandruvada 5501a4fbf6aSSrinivas Pandruvada static int kxcjk1013_convert_freq_to_bit(int val, int val2) 5511a4fbf6aSSrinivas Pandruvada { 5521a4fbf6aSSrinivas Pandruvada int i; 5531a4fbf6aSSrinivas Pandruvada 5541a4fbf6aSSrinivas Pandruvada for (i = 0; i < ARRAY_SIZE(samp_freq_table); ++i) { 5551a4fbf6aSSrinivas Pandruvada if (samp_freq_table[i].val == val && 5561a4fbf6aSSrinivas Pandruvada samp_freq_table[i].val2 == val2) { 5571a4fbf6aSSrinivas Pandruvada return samp_freq_table[i].odr_bits; 5581a4fbf6aSSrinivas Pandruvada } 5591a4fbf6aSSrinivas Pandruvada } 5601a4fbf6aSSrinivas Pandruvada 5611a4fbf6aSSrinivas Pandruvada return -EINVAL; 5621a4fbf6aSSrinivas Pandruvada } 5631a4fbf6aSSrinivas Pandruvada 564b4b491c0SSrinivas Pandruvada static int kxcjk1013_convert_wake_odr_to_bit(int val, int val2) 565b4b491c0SSrinivas Pandruvada { 566b4b491c0SSrinivas Pandruvada int i; 567b4b491c0SSrinivas Pandruvada 568b4b491c0SSrinivas Pandruvada for (i = 0; i < ARRAY_SIZE(wake_odr_data_rate_table); ++i) { 569b4b491c0SSrinivas Pandruvada if (wake_odr_data_rate_table[i].val == val && 570b4b491c0SSrinivas Pandruvada wake_odr_data_rate_table[i].val2 == val2) { 571b4b491c0SSrinivas Pandruvada return wake_odr_data_rate_table[i].odr_bits; 572b4b491c0SSrinivas Pandruvada } 573b4b491c0SSrinivas Pandruvada } 574b4b491c0SSrinivas Pandruvada 575b4b491c0SSrinivas Pandruvada return -EINVAL; 576b4b491c0SSrinivas Pandruvada } 577b4b491c0SSrinivas Pandruvada 5781a4fbf6aSSrinivas Pandruvada static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2) 5791a4fbf6aSSrinivas Pandruvada { 5801a4fbf6aSSrinivas Pandruvada int ret; 5811a4fbf6aSSrinivas Pandruvada int odr_bits; 582124e1b1dSSrinivas Pandruvada enum kxcjk1013_mode store_mode; 583124e1b1dSSrinivas Pandruvada 584124e1b1dSSrinivas Pandruvada ret = kxcjk1013_get_mode(data, &store_mode); 585124e1b1dSSrinivas Pandruvada if (ret < 0) 586124e1b1dSSrinivas Pandruvada return ret; 5871a4fbf6aSSrinivas Pandruvada 5881a4fbf6aSSrinivas Pandruvada odr_bits = kxcjk1013_convert_freq_to_bit(val, val2); 5891a4fbf6aSSrinivas Pandruvada if (odr_bits < 0) 5901a4fbf6aSSrinivas Pandruvada return odr_bits; 5911a4fbf6aSSrinivas Pandruvada 5921a4fbf6aSSrinivas Pandruvada /* To change ODR, the chip must be set to STANDBY as per spec */ 5931a4fbf6aSSrinivas Pandruvada ret = kxcjk1013_set_mode(data, STANDBY); 5941a4fbf6aSSrinivas Pandruvada if (ret < 0) 5951a4fbf6aSSrinivas Pandruvada return ret; 5961a4fbf6aSSrinivas Pandruvada 5971a4fbf6aSSrinivas Pandruvada ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_DATA_CTRL, 5981a4fbf6aSSrinivas Pandruvada odr_bits); 5991a4fbf6aSSrinivas Pandruvada if (ret < 0) { 6001a4fbf6aSSrinivas Pandruvada dev_err(&data->client->dev, "Error writing data_ctrl\n"); 6011a4fbf6aSSrinivas Pandruvada return ret; 6021a4fbf6aSSrinivas Pandruvada } 6031a4fbf6aSSrinivas Pandruvada 6041a4fbf6aSSrinivas Pandruvada data->odr_bits = odr_bits; 6051a4fbf6aSSrinivas Pandruvada 606b4b491c0SSrinivas Pandruvada odr_bits = kxcjk1013_convert_wake_odr_to_bit(val, val2); 607b4b491c0SSrinivas Pandruvada if (odr_bits < 0) 608b4b491c0SSrinivas Pandruvada return odr_bits; 609b4b491c0SSrinivas Pandruvada 610b4b491c0SSrinivas Pandruvada ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_CTRL2, 611b4b491c0SSrinivas Pandruvada odr_bits); 612b4b491c0SSrinivas Pandruvada if (ret < 0) { 613b4b491c0SSrinivas Pandruvada dev_err(&data->client->dev, "Error writing reg_ctrl2\n"); 614b4b491c0SSrinivas Pandruvada return ret; 615b4b491c0SSrinivas Pandruvada } 616b4b491c0SSrinivas Pandruvada 617124e1b1dSSrinivas Pandruvada if (store_mode == OPERATION) { 6181a4fbf6aSSrinivas Pandruvada ret = kxcjk1013_set_mode(data, OPERATION); 6191a4fbf6aSSrinivas Pandruvada if (ret < 0) 6201a4fbf6aSSrinivas Pandruvada return ret; 6211a4fbf6aSSrinivas Pandruvada } 6221a4fbf6aSSrinivas Pandruvada 6231a4fbf6aSSrinivas Pandruvada return 0; 6241a4fbf6aSSrinivas Pandruvada } 6251a4fbf6aSSrinivas Pandruvada 6261a4fbf6aSSrinivas Pandruvada static int kxcjk1013_get_odr(struct kxcjk1013_data *data, int *val, int *val2) 6271a4fbf6aSSrinivas Pandruvada { 6281a4fbf6aSSrinivas Pandruvada int i; 6291a4fbf6aSSrinivas Pandruvada 6301a4fbf6aSSrinivas Pandruvada for (i = 0; i < ARRAY_SIZE(samp_freq_table); ++i) { 6311a4fbf6aSSrinivas Pandruvada if (samp_freq_table[i].odr_bits == data->odr_bits) { 6321a4fbf6aSSrinivas Pandruvada *val = samp_freq_table[i].val; 6331a4fbf6aSSrinivas Pandruvada *val2 = samp_freq_table[i].val2; 6341a4fbf6aSSrinivas Pandruvada return IIO_VAL_INT_PLUS_MICRO; 6351a4fbf6aSSrinivas Pandruvada } 6361a4fbf6aSSrinivas Pandruvada } 6371a4fbf6aSSrinivas Pandruvada 6381a4fbf6aSSrinivas Pandruvada return -EINVAL; 6391a4fbf6aSSrinivas Pandruvada } 6401a4fbf6aSSrinivas Pandruvada 6411a4fbf6aSSrinivas Pandruvada static int kxcjk1013_get_acc_reg(struct kxcjk1013_data *data, int axis) 6421a4fbf6aSSrinivas Pandruvada { 6431a4fbf6aSSrinivas Pandruvada u8 reg = KXCJK1013_REG_XOUT_L + axis * 2; 6441a4fbf6aSSrinivas Pandruvada int ret; 6451a4fbf6aSSrinivas Pandruvada 6461a4fbf6aSSrinivas Pandruvada ret = i2c_smbus_read_word_data(data->client, reg); 6471a4fbf6aSSrinivas Pandruvada if (ret < 0) { 6481a4fbf6aSSrinivas Pandruvada dev_err(&data->client->dev, 6491a4fbf6aSSrinivas Pandruvada "failed to read accel_%c registers\n", 'x' + axis); 6501a4fbf6aSSrinivas Pandruvada return ret; 6511a4fbf6aSSrinivas Pandruvada } 6521a4fbf6aSSrinivas Pandruvada 6531a4fbf6aSSrinivas Pandruvada return ret; 6541a4fbf6aSSrinivas Pandruvada } 6551a4fbf6aSSrinivas Pandruvada 656a735e3d7SSrinivas Pandruvada static int kxcjk1013_set_scale(struct kxcjk1013_data *data, int val) 657a735e3d7SSrinivas Pandruvada { 658a735e3d7SSrinivas Pandruvada int ret, i; 659a735e3d7SSrinivas Pandruvada enum kxcjk1013_mode store_mode; 660a735e3d7SSrinivas Pandruvada 661a735e3d7SSrinivas Pandruvada for (i = 0; i < ARRAY_SIZE(KXCJK1013_scale_table); ++i) { 662a735e3d7SSrinivas Pandruvada if (KXCJK1013_scale_table[i].scale == val) { 663a735e3d7SSrinivas Pandruvada ret = kxcjk1013_get_mode(data, &store_mode); 664a735e3d7SSrinivas Pandruvada if (ret < 0) 665a735e3d7SSrinivas Pandruvada return ret; 666a735e3d7SSrinivas Pandruvada 667a735e3d7SSrinivas Pandruvada ret = kxcjk1013_set_mode(data, STANDBY); 668a735e3d7SSrinivas Pandruvada if (ret < 0) 669a735e3d7SSrinivas Pandruvada return ret; 670a735e3d7SSrinivas Pandruvada 671a735e3d7SSrinivas Pandruvada ret = kxcjk1013_set_range(data, i); 672a735e3d7SSrinivas Pandruvada if (ret < 0) 673a735e3d7SSrinivas Pandruvada return ret; 674a735e3d7SSrinivas Pandruvada 675a735e3d7SSrinivas Pandruvada if (store_mode == OPERATION) { 676a735e3d7SSrinivas Pandruvada ret = kxcjk1013_set_mode(data, OPERATION); 677a735e3d7SSrinivas Pandruvada if (ret) 678a735e3d7SSrinivas Pandruvada return ret; 679a735e3d7SSrinivas Pandruvada } 680a735e3d7SSrinivas Pandruvada 681a735e3d7SSrinivas Pandruvada return 0; 682a735e3d7SSrinivas Pandruvada } 683a735e3d7SSrinivas Pandruvada } 684a735e3d7SSrinivas Pandruvada 685a735e3d7SSrinivas Pandruvada return -EINVAL; 686a735e3d7SSrinivas Pandruvada } 687a735e3d7SSrinivas Pandruvada 6881a4fbf6aSSrinivas Pandruvada static int kxcjk1013_read_raw(struct iio_dev *indio_dev, 6891a4fbf6aSSrinivas Pandruvada struct iio_chan_spec const *chan, int *val, 6901a4fbf6aSSrinivas Pandruvada int *val2, long mask) 6911a4fbf6aSSrinivas Pandruvada { 6921a4fbf6aSSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 6931a4fbf6aSSrinivas Pandruvada int ret; 6941a4fbf6aSSrinivas Pandruvada 6951a4fbf6aSSrinivas Pandruvada switch (mask) { 6961a4fbf6aSSrinivas Pandruvada case IIO_CHAN_INFO_RAW: 6971a4fbf6aSSrinivas Pandruvada mutex_lock(&data->mutex); 6981a4fbf6aSSrinivas Pandruvada if (iio_buffer_enabled(indio_dev)) 6991a4fbf6aSSrinivas Pandruvada ret = -EBUSY; 7001a4fbf6aSSrinivas Pandruvada else { 701124e1b1dSSrinivas Pandruvada ret = kxcjk1013_set_power_state(data, true); 70288f6da77SSrinivas Pandruvada if (ret < 0) { 70388f6da77SSrinivas Pandruvada mutex_unlock(&data->mutex); 7041a4fbf6aSSrinivas Pandruvada return ret; 70588f6da77SSrinivas Pandruvada } 7061a4fbf6aSSrinivas Pandruvada ret = kxcjk1013_get_acc_reg(data, chan->scan_index); 707124e1b1dSSrinivas Pandruvada if (ret < 0) { 708124e1b1dSSrinivas Pandruvada kxcjk1013_set_power_state(data, false); 709124e1b1dSSrinivas Pandruvada mutex_unlock(&data->mutex); 710124e1b1dSSrinivas Pandruvada return ret; 711124e1b1dSSrinivas Pandruvada } 712124e1b1dSSrinivas Pandruvada *val = sign_extend32(ret >> 4, 11); 713124e1b1dSSrinivas Pandruvada ret = kxcjk1013_set_power_state(data, false); 7141a4fbf6aSSrinivas Pandruvada } 7151a4fbf6aSSrinivas Pandruvada mutex_unlock(&data->mutex); 7161a4fbf6aSSrinivas Pandruvada 7171a4fbf6aSSrinivas Pandruvada if (ret < 0) 7181a4fbf6aSSrinivas Pandruvada return ret; 7191a4fbf6aSSrinivas Pandruvada 7201a4fbf6aSSrinivas Pandruvada return IIO_VAL_INT; 7211a4fbf6aSSrinivas Pandruvada 7221a4fbf6aSSrinivas Pandruvada case IIO_CHAN_INFO_SCALE: 7231a4fbf6aSSrinivas Pandruvada *val = 0; 724a735e3d7SSrinivas Pandruvada *val2 = KXCJK1013_scale_table[data->range].scale; 7251a4fbf6aSSrinivas Pandruvada return IIO_VAL_INT_PLUS_MICRO; 7261a4fbf6aSSrinivas Pandruvada 7271a4fbf6aSSrinivas Pandruvada case IIO_CHAN_INFO_SAMP_FREQ: 7281a4fbf6aSSrinivas Pandruvada mutex_lock(&data->mutex); 7291a4fbf6aSSrinivas Pandruvada ret = kxcjk1013_get_odr(data, val, val2); 7301a4fbf6aSSrinivas Pandruvada mutex_unlock(&data->mutex); 7311a4fbf6aSSrinivas Pandruvada return ret; 7321a4fbf6aSSrinivas Pandruvada 7331a4fbf6aSSrinivas Pandruvada default: 7341a4fbf6aSSrinivas Pandruvada return -EINVAL; 7351a4fbf6aSSrinivas Pandruvada } 7361a4fbf6aSSrinivas Pandruvada } 7371a4fbf6aSSrinivas Pandruvada 7381a4fbf6aSSrinivas Pandruvada static int kxcjk1013_write_raw(struct iio_dev *indio_dev, 7391a4fbf6aSSrinivas Pandruvada struct iio_chan_spec const *chan, int val, 7401a4fbf6aSSrinivas Pandruvada int val2, long mask) 7411a4fbf6aSSrinivas Pandruvada { 7421a4fbf6aSSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 7431a4fbf6aSSrinivas Pandruvada int ret; 7441a4fbf6aSSrinivas Pandruvada 7451a4fbf6aSSrinivas Pandruvada switch (mask) { 7461a4fbf6aSSrinivas Pandruvada case IIO_CHAN_INFO_SAMP_FREQ: 7471a4fbf6aSSrinivas Pandruvada mutex_lock(&data->mutex); 7481a4fbf6aSSrinivas Pandruvada ret = kxcjk1013_set_odr(data, val, val2); 7491a4fbf6aSSrinivas Pandruvada mutex_unlock(&data->mutex); 7501a4fbf6aSSrinivas Pandruvada break; 751a735e3d7SSrinivas Pandruvada case IIO_CHAN_INFO_SCALE: 752a735e3d7SSrinivas Pandruvada if (val) 753a735e3d7SSrinivas Pandruvada return -EINVAL; 754a735e3d7SSrinivas Pandruvada 755a735e3d7SSrinivas Pandruvada mutex_lock(&data->mutex); 756a735e3d7SSrinivas Pandruvada ret = kxcjk1013_set_scale(data, val2); 757a735e3d7SSrinivas Pandruvada mutex_unlock(&data->mutex); 758a735e3d7SSrinivas Pandruvada break; 7591a4fbf6aSSrinivas Pandruvada default: 7601a4fbf6aSSrinivas Pandruvada ret = -EINVAL; 7611a4fbf6aSSrinivas Pandruvada } 7621a4fbf6aSSrinivas Pandruvada 7631a4fbf6aSSrinivas Pandruvada return ret; 7641a4fbf6aSSrinivas Pandruvada } 7651a4fbf6aSSrinivas Pandruvada 766b4b491c0SSrinivas Pandruvada static int kxcjk1013_read_event(struct iio_dev *indio_dev, 767b4b491c0SSrinivas Pandruvada const struct iio_chan_spec *chan, 768b4b491c0SSrinivas Pandruvada enum iio_event_type type, 769b4b491c0SSrinivas Pandruvada enum iio_event_direction dir, 770b4b491c0SSrinivas Pandruvada enum iio_event_info info, 771b4b491c0SSrinivas Pandruvada int *val, int *val2) 772b4b491c0SSrinivas Pandruvada { 773b4b491c0SSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 774b4b491c0SSrinivas Pandruvada 775b4b491c0SSrinivas Pandruvada *val2 = 0; 776b4b491c0SSrinivas Pandruvada switch (info) { 777b4b491c0SSrinivas Pandruvada case IIO_EV_INFO_VALUE: 778b4b491c0SSrinivas Pandruvada *val = data->wake_thres; 779b4b491c0SSrinivas Pandruvada break; 780b4b491c0SSrinivas Pandruvada case IIO_EV_INFO_PERIOD: 781b4b491c0SSrinivas Pandruvada *val = data->wake_dur; 782b4b491c0SSrinivas Pandruvada break; 783b4b491c0SSrinivas Pandruvada default: 784b4b491c0SSrinivas Pandruvada return -EINVAL; 785b4b491c0SSrinivas Pandruvada } 786b4b491c0SSrinivas Pandruvada 787b4b491c0SSrinivas Pandruvada return IIO_VAL_INT; 788b4b491c0SSrinivas Pandruvada } 789b4b491c0SSrinivas Pandruvada 790b4b491c0SSrinivas Pandruvada static int kxcjk1013_write_event(struct iio_dev *indio_dev, 791b4b491c0SSrinivas Pandruvada const struct iio_chan_spec *chan, 792b4b491c0SSrinivas Pandruvada enum iio_event_type type, 793b4b491c0SSrinivas Pandruvada enum iio_event_direction dir, 794b4b491c0SSrinivas Pandruvada enum iio_event_info info, 795b4b491c0SSrinivas Pandruvada int val, int val2) 796b4b491c0SSrinivas Pandruvada { 797b4b491c0SSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 798b4b491c0SSrinivas Pandruvada 799b4b491c0SSrinivas Pandruvada if (data->ev_enable_state) 800b4b491c0SSrinivas Pandruvada return -EBUSY; 801b4b491c0SSrinivas Pandruvada 802b4b491c0SSrinivas Pandruvada switch (info) { 803b4b491c0SSrinivas Pandruvada case IIO_EV_INFO_VALUE: 804b4b491c0SSrinivas Pandruvada data->wake_thres = val; 805b4b491c0SSrinivas Pandruvada break; 806b4b491c0SSrinivas Pandruvada case IIO_EV_INFO_PERIOD: 807b4b491c0SSrinivas Pandruvada data->wake_dur = val; 808b4b491c0SSrinivas Pandruvada break; 809b4b491c0SSrinivas Pandruvada default: 810b4b491c0SSrinivas Pandruvada return -EINVAL; 811b4b491c0SSrinivas Pandruvada } 812b4b491c0SSrinivas Pandruvada 813b4b491c0SSrinivas Pandruvada return 0; 814b4b491c0SSrinivas Pandruvada } 815b4b491c0SSrinivas Pandruvada 816b4b491c0SSrinivas Pandruvada static int kxcjk1013_read_event_config(struct iio_dev *indio_dev, 817b4b491c0SSrinivas Pandruvada const struct iio_chan_spec *chan, 818b4b491c0SSrinivas Pandruvada enum iio_event_type type, 819b4b491c0SSrinivas Pandruvada enum iio_event_direction dir) 820b4b491c0SSrinivas Pandruvada { 821b4b491c0SSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 822b4b491c0SSrinivas Pandruvada 823b4b491c0SSrinivas Pandruvada return data->ev_enable_state; 824b4b491c0SSrinivas Pandruvada } 825b4b491c0SSrinivas Pandruvada 826b4b491c0SSrinivas Pandruvada static int kxcjk1013_write_event_config(struct iio_dev *indio_dev, 827b4b491c0SSrinivas Pandruvada const struct iio_chan_spec *chan, 828b4b491c0SSrinivas Pandruvada enum iio_event_type type, 829b4b491c0SSrinivas Pandruvada enum iio_event_direction dir, 830b4b491c0SSrinivas Pandruvada int state) 831b4b491c0SSrinivas Pandruvada { 832b4b491c0SSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 833b4b491c0SSrinivas Pandruvada int ret; 834b4b491c0SSrinivas Pandruvada 835b4b491c0SSrinivas Pandruvada if (state && data->ev_enable_state) 836b4b491c0SSrinivas Pandruvada return 0; 837b4b491c0SSrinivas Pandruvada 838b4b491c0SSrinivas Pandruvada mutex_lock(&data->mutex); 839b4b491c0SSrinivas Pandruvada 840b4b491c0SSrinivas Pandruvada if (!state && data->motion_trigger_on) { 841b4b491c0SSrinivas Pandruvada data->ev_enable_state = 0; 842b4b491c0SSrinivas Pandruvada mutex_unlock(&data->mutex); 843b4b491c0SSrinivas Pandruvada return 0; 844b4b491c0SSrinivas Pandruvada } 845b4b491c0SSrinivas Pandruvada 846b4b491c0SSrinivas Pandruvada /* 847b4b491c0SSrinivas Pandruvada * We will expect the enable and disable to do operation in 848b4b491c0SSrinivas Pandruvada * in reverse order. This will happen here anyway as our 849b4b491c0SSrinivas Pandruvada * resume operation uses sync mode runtime pm calls, the 850b4b491c0SSrinivas Pandruvada * suspend operation will be delayed by autosuspend delay 851b4b491c0SSrinivas Pandruvada * So the disable operation will still happen in reverse of 852b4b491c0SSrinivas Pandruvada * enable operation. When runtime pm is disabled the mode 853b4b491c0SSrinivas Pandruvada * is always on so sequence doesn't matter 854b4b491c0SSrinivas Pandruvada */ 855b4b491c0SSrinivas Pandruvada ret = kxcjk1013_set_power_state(data, state); 856b4b491c0SSrinivas Pandruvada if (ret < 0) { 857b4b491c0SSrinivas Pandruvada mutex_unlock(&data->mutex); 858b4b491c0SSrinivas Pandruvada return ret; 859b4b491c0SSrinivas Pandruvada } 860b4b491c0SSrinivas Pandruvada 861b4b491c0SSrinivas Pandruvada ret = kxcjk1013_setup_any_motion_interrupt(data, state); 862b4b491c0SSrinivas Pandruvada if (ret < 0) { 863fbd123e9SIrina Tirdea kxcjk1013_set_power_state(data, false); 864fbd123e9SIrina Tirdea data->ev_enable_state = 0; 865b4b491c0SSrinivas Pandruvada mutex_unlock(&data->mutex); 866b4b491c0SSrinivas Pandruvada return ret; 867b4b491c0SSrinivas Pandruvada } 868b4b491c0SSrinivas Pandruvada 869b4b491c0SSrinivas Pandruvada data->ev_enable_state = state; 870b4b491c0SSrinivas Pandruvada mutex_unlock(&data->mutex); 871b4b491c0SSrinivas Pandruvada 872b4b491c0SSrinivas Pandruvada return 0; 873b4b491c0SSrinivas Pandruvada } 874b4b491c0SSrinivas Pandruvada 875a25691c1SVlad Dogaru static int kxcjk1013_buffer_preenable(struct iio_dev *indio_dev) 8761a4fbf6aSSrinivas Pandruvada { 8771a4fbf6aSSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 8781a4fbf6aSSrinivas Pandruvada 879a25691c1SVlad Dogaru return kxcjk1013_set_power_state(data, true); 880a25691c1SVlad Dogaru } 8811a4fbf6aSSrinivas Pandruvada 882a25691c1SVlad Dogaru static int kxcjk1013_buffer_postdisable(struct iio_dev *indio_dev) 883a25691c1SVlad Dogaru { 884a25691c1SVlad Dogaru struct kxcjk1013_data *data = iio_priv(indio_dev); 885a25691c1SVlad Dogaru 886a25691c1SVlad Dogaru return kxcjk1013_set_power_state(data, false); 8871a4fbf6aSSrinivas Pandruvada } 8881a4fbf6aSSrinivas Pandruvada 8891a4fbf6aSSrinivas Pandruvada static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( 8901a4fbf6aSSrinivas Pandruvada "0.781000 1.563000 3.125000 6.250000 12.500000 25 50 100 200 400 800 1600"); 8911a4fbf6aSSrinivas Pandruvada 892a735e3d7SSrinivas Pandruvada static IIO_CONST_ATTR(in_accel_scale_available, "0.009582 0.019163 0.038326"); 893a735e3d7SSrinivas Pandruvada 8941a4fbf6aSSrinivas Pandruvada static struct attribute *kxcjk1013_attributes[] = { 8951a4fbf6aSSrinivas Pandruvada &iio_const_attr_sampling_frequency_available.dev_attr.attr, 896a735e3d7SSrinivas Pandruvada &iio_const_attr_in_accel_scale_available.dev_attr.attr, 8971a4fbf6aSSrinivas Pandruvada NULL, 8981a4fbf6aSSrinivas Pandruvada }; 8991a4fbf6aSSrinivas Pandruvada 9001a4fbf6aSSrinivas Pandruvada static const struct attribute_group kxcjk1013_attrs_group = { 9011a4fbf6aSSrinivas Pandruvada .attrs = kxcjk1013_attributes, 9021a4fbf6aSSrinivas Pandruvada }; 9031a4fbf6aSSrinivas Pandruvada 904b4b491c0SSrinivas Pandruvada static const struct iio_event_spec kxcjk1013_event = { 905b4b491c0SSrinivas Pandruvada .type = IIO_EV_TYPE_THRESH, 90625afffe1SDaniel Baluta .dir = IIO_EV_DIR_EITHER, 907b4b491c0SSrinivas Pandruvada .mask_separate = BIT(IIO_EV_INFO_VALUE) | 908b4b491c0SSrinivas Pandruvada BIT(IIO_EV_INFO_ENABLE) | 909b4b491c0SSrinivas Pandruvada BIT(IIO_EV_INFO_PERIOD) 910b4b491c0SSrinivas Pandruvada }; 911b4b491c0SSrinivas Pandruvada 9121a4fbf6aSSrinivas Pandruvada #define KXCJK1013_CHANNEL(_axis) { \ 9131a4fbf6aSSrinivas Pandruvada .type = IIO_ACCEL, \ 9141a4fbf6aSSrinivas Pandruvada .modified = 1, \ 9151a4fbf6aSSrinivas Pandruvada .channel2 = IIO_MOD_##_axis, \ 9161a4fbf6aSSrinivas Pandruvada .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 9171a4fbf6aSSrinivas Pandruvada .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 9181a4fbf6aSSrinivas Pandruvada BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 9191a4fbf6aSSrinivas Pandruvada .scan_index = AXIS_##_axis, \ 9201a4fbf6aSSrinivas Pandruvada .scan_type = { \ 9211a4fbf6aSSrinivas Pandruvada .sign = 's', \ 9221a4fbf6aSSrinivas Pandruvada .realbits = 12, \ 9231a4fbf6aSSrinivas Pandruvada .storagebits = 16, \ 9241a4fbf6aSSrinivas Pandruvada .shift = 4, \ 92565ae47b0SAdriana Reus .endianness = IIO_LE, \ 9261a4fbf6aSSrinivas Pandruvada }, \ 927b4b491c0SSrinivas Pandruvada .event_spec = &kxcjk1013_event, \ 928b4b491c0SSrinivas Pandruvada .num_event_specs = 1 \ 9291a4fbf6aSSrinivas Pandruvada } 9301a4fbf6aSSrinivas Pandruvada 9311a4fbf6aSSrinivas Pandruvada static const struct iio_chan_spec kxcjk1013_channels[] = { 9321a4fbf6aSSrinivas Pandruvada KXCJK1013_CHANNEL(X), 9331a4fbf6aSSrinivas Pandruvada KXCJK1013_CHANNEL(Y), 9341a4fbf6aSSrinivas Pandruvada KXCJK1013_CHANNEL(Z), 9351a4fbf6aSSrinivas Pandruvada IIO_CHAN_SOFT_TIMESTAMP(3), 9361a4fbf6aSSrinivas Pandruvada }; 9371a4fbf6aSSrinivas Pandruvada 938a25691c1SVlad Dogaru static const struct iio_buffer_setup_ops kxcjk1013_buffer_setup_ops = { 939a25691c1SVlad Dogaru .preenable = kxcjk1013_buffer_preenable, 940a25691c1SVlad Dogaru .postenable = iio_triggered_buffer_postenable, 941a25691c1SVlad Dogaru .postdisable = kxcjk1013_buffer_postdisable, 942a25691c1SVlad Dogaru .predisable = iio_triggered_buffer_predisable, 943a25691c1SVlad Dogaru }; 944a25691c1SVlad Dogaru 9451a4fbf6aSSrinivas Pandruvada static const struct iio_info kxcjk1013_info = { 9461a4fbf6aSSrinivas Pandruvada .attrs = &kxcjk1013_attrs_group, 9471a4fbf6aSSrinivas Pandruvada .read_raw = kxcjk1013_read_raw, 9481a4fbf6aSSrinivas Pandruvada .write_raw = kxcjk1013_write_raw, 949b4b491c0SSrinivas Pandruvada .read_event_value = kxcjk1013_read_event, 950b4b491c0SSrinivas Pandruvada .write_event_value = kxcjk1013_write_event, 951b4b491c0SSrinivas Pandruvada .write_event_config = kxcjk1013_write_event_config, 952b4b491c0SSrinivas Pandruvada .read_event_config = kxcjk1013_read_event_config, 9531a4fbf6aSSrinivas Pandruvada .driver_module = THIS_MODULE, 9541a4fbf6aSSrinivas Pandruvada }; 9551a4fbf6aSSrinivas Pandruvada 95609cf1b32SAdriana Reus static const unsigned long kxcjk1013_scan_masks[] = {0x7, 0}; 95709cf1b32SAdriana Reus 9581a4fbf6aSSrinivas Pandruvada static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p) 9591a4fbf6aSSrinivas Pandruvada { 9601a4fbf6aSSrinivas Pandruvada struct iio_poll_func *pf = p; 9611a4fbf6aSSrinivas Pandruvada struct iio_dev *indio_dev = pf->indio_dev; 9621a4fbf6aSSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 96365ae47b0SAdriana Reus int ret; 9641a4fbf6aSSrinivas Pandruvada 9651a4fbf6aSSrinivas Pandruvada mutex_lock(&data->mutex); 96665ae47b0SAdriana Reus ret = i2c_smbus_read_i2c_block_data_or_emulated(data->client, 96765ae47b0SAdriana Reus KXCJK1013_REG_XOUT_L, 96865ae47b0SAdriana Reus AXIS_MAX * 2, 96965ae47b0SAdriana Reus (u8 *)data->buffer); 9701a4fbf6aSSrinivas Pandruvada mutex_unlock(&data->mutex); 97165ae47b0SAdriana Reus if (ret < 0) 9721a4fbf6aSSrinivas Pandruvada goto err; 9731a4fbf6aSSrinivas Pandruvada 9741a4fbf6aSSrinivas Pandruvada iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, 975b4b491c0SSrinivas Pandruvada data->timestamp); 9761a4fbf6aSSrinivas Pandruvada err: 9771a4fbf6aSSrinivas Pandruvada iio_trigger_notify_done(indio_dev->trig); 9781a4fbf6aSSrinivas Pandruvada 9791a4fbf6aSSrinivas Pandruvada return IRQ_HANDLED; 9801a4fbf6aSSrinivas Pandruvada } 9811a4fbf6aSSrinivas Pandruvada 98259bfeabaSSrinivas Pandruvada static int kxcjk1013_trig_try_reen(struct iio_trigger *trig) 98359bfeabaSSrinivas Pandruvada { 98459bfeabaSSrinivas Pandruvada struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 98559bfeabaSSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 98659bfeabaSSrinivas Pandruvada int ret; 98759bfeabaSSrinivas Pandruvada 98859bfeabaSSrinivas Pandruvada ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_REL); 98959bfeabaSSrinivas Pandruvada if (ret < 0) { 99059bfeabaSSrinivas Pandruvada dev_err(&data->client->dev, "Error reading reg_int_rel\n"); 99159bfeabaSSrinivas Pandruvada return ret; 99259bfeabaSSrinivas Pandruvada } 99359bfeabaSSrinivas Pandruvada 99459bfeabaSSrinivas Pandruvada return 0; 99559bfeabaSSrinivas Pandruvada } 99659bfeabaSSrinivas Pandruvada 9971a4fbf6aSSrinivas Pandruvada static int kxcjk1013_data_rdy_trigger_set_state(struct iio_trigger *trig, 9981a4fbf6aSSrinivas Pandruvada bool state) 9991a4fbf6aSSrinivas Pandruvada { 10001a4fbf6aSSrinivas Pandruvada struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 10011a4fbf6aSSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 1002124e1b1dSSrinivas Pandruvada int ret; 1003124e1b1dSSrinivas Pandruvada 10041a4fbf6aSSrinivas Pandruvada mutex_lock(&data->mutex); 1005b4b491c0SSrinivas Pandruvada 1006b4b491c0SSrinivas Pandruvada if (!state && data->ev_enable_state && data->motion_trigger_on) { 1007b4b491c0SSrinivas Pandruvada data->motion_trigger_on = false; 1008b4b491c0SSrinivas Pandruvada mutex_unlock(&data->mutex); 1009b4b491c0SSrinivas Pandruvada return 0; 1010b4b491c0SSrinivas Pandruvada } 1011b4b491c0SSrinivas Pandruvada 1012124e1b1dSSrinivas Pandruvada ret = kxcjk1013_set_power_state(data, state); 1013124e1b1dSSrinivas Pandruvada if (ret < 0) { 101488f6da77SSrinivas Pandruvada mutex_unlock(&data->mutex); 1015124e1b1dSSrinivas Pandruvada return ret; 101688f6da77SSrinivas Pandruvada } 1017b4b491c0SSrinivas Pandruvada if (data->motion_trig == trig) 1018b4b491c0SSrinivas Pandruvada ret = kxcjk1013_setup_any_motion_interrupt(data, state); 1019b4b491c0SSrinivas Pandruvada else 1020b4b491c0SSrinivas Pandruvada ret = kxcjk1013_setup_new_data_interrupt(data, state); 1021b4b491c0SSrinivas Pandruvada if (ret < 0) { 1022fbd123e9SIrina Tirdea kxcjk1013_set_power_state(data, false); 1023b4b491c0SSrinivas Pandruvada mutex_unlock(&data->mutex); 1024b4b491c0SSrinivas Pandruvada return ret; 10251a4fbf6aSSrinivas Pandruvada } 1026b4b491c0SSrinivas Pandruvada if (data->motion_trig == trig) 1027b4b491c0SSrinivas Pandruvada data->motion_trigger_on = state; 1028b4b491c0SSrinivas Pandruvada else 1029b4b491c0SSrinivas Pandruvada data->dready_trigger_on = state; 1030b4b491c0SSrinivas Pandruvada 10311a4fbf6aSSrinivas Pandruvada mutex_unlock(&data->mutex); 10321a4fbf6aSSrinivas Pandruvada 10331a4fbf6aSSrinivas Pandruvada return 0; 10341a4fbf6aSSrinivas Pandruvada } 10351a4fbf6aSSrinivas Pandruvada 10361a4fbf6aSSrinivas Pandruvada static const struct iio_trigger_ops kxcjk1013_trigger_ops = { 10371a4fbf6aSSrinivas Pandruvada .set_trigger_state = kxcjk1013_data_rdy_trigger_set_state, 103859bfeabaSSrinivas Pandruvada .try_reenable = kxcjk1013_trig_try_reen, 10391a4fbf6aSSrinivas Pandruvada .owner = THIS_MODULE, 10401a4fbf6aSSrinivas Pandruvada }; 10411a4fbf6aSSrinivas Pandruvada 1042b4b491c0SSrinivas Pandruvada static irqreturn_t kxcjk1013_event_handler(int irq, void *private) 1043b4b491c0SSrinivas Pandruvada { 1044b4b491c0SSrinivas Pandruvada struct iio_dev *indio_dev = private; 1045b4b491c0SSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 1046b4b491c0SSrinivas Pandruvada int ret; 1047b4b491c0SSrinivas Pandruvada 1048b4b491c0SSrinivas Pandruvada ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_SRC1); 1049b4b491c0SSrinivas Pandruvada if (ret < 0) { 1050b4b491c0SSrinivas Pandruvada dev_err(&data->client->dev, "Error reading reg_int_src1\n"); 1051b4b491c0SSrinivas Pandruvada goto ack_intr; 1052b4b491c0SSrinivas Pandruvada } 1053b4b491c0SSrinivas Pandruvada 1054b4b491c0SSrinivas Pandruvada if (ret & 0x02) { 1055b4b491c0SSrinivas Pandruvada ret = i2c_smbus_read_byte_data(data->client, 1056b4b491c0SSrinivas Pandruvada KXCJK1013_REG_INT_SRC2); 1057b4b491c0SSrinivas Pandruvada if (ret < 0) { 1058b4b491c0SSrinivas Pandruvada dev_err(&data->client->dev, 1059b4b491c0SSrinivas Pandruvada "Error reading reg_int_src2\n"); 1060b4b491c0SSrinivas Pandruvada goto ack_intr; 1061b4b491c0SSrinivas Pandruvada } 1062b4b491c0SSrinivas Pandruvada 1063b4b491c0SSrinivas Pandruvada if (ret & KXCJK1013_REG_INT_SRC2_BIT_XN) 1064b4b491c0SSrinivas Pandruvada iio_push_event(indio_dev, 1065b4b491c0SSrinivas Pandruvada IIO_MOD_EVENT_CODE(IIO_ACCEL, 1066b4b491c0SSrinivas Pandruvada 0, 1067b4b491c0SSrinivas Pandruvada IIO_MOD_X, 1068b4b491c0SSrinivas Pandruvada IIO_EV_TYPE_THRESH, 1069b4b491c0SSrinivas Pandruvada IIO_EV_DIR_FALLING), 1070b4b491c0SSrinivas Pandruvada data->timestamp); 1071b4b491c0SSrinivas Pandruvada if (ret & KXCJK1013_REG_INT_SRC2_BIT_XP) 1072b4b491c0SSrinivas Pandruvada iio_push_event(indio_dev, 1073b4b491c0SSrinivas Pandruvada IIO_MOD_EVENT_CODE(IIO_ACCEL, 1074b4b491c0SSrinivas Pandruvada 0, 1075b4b491c0SSrinivas Pandruvada IIO_MOD_X, 1076b4b491c0SSrinivas Pandruvada IIO_EV_TYPE_THRESH, 1077b4b491c0SSrinivas Pandruvada IIO_EV_DIR_RISING), 1078b4b491c0SSrinivas Pandruvada data->timestamp); 1079b4b491c0SSrinivas Pandruvada 1080b4b491c0SSrinivas Pandruvada 1081b4b491c0SSrinivas Pandruvada if (ret & KXCJK1013_REG_INT_SRC2_BIT_YN) 1082b4b491c0SSrinivas Pandruvada iio_push_event(indio_dev, 1083b4b491c0SSrinivas Pandruvada IIO_MOD_EVENT_CODE(IIO_ACCEL, 1084b4b491c0SSrinivas Pandruvada 0, 1085b4b491c0SSrinivas Pandruvada IIO_MOD_Y, 1086b4b491c0SSrinivas Pandruvada IIO_EV_TYPE_THRESH, 1087b4b491c0SSrinivas Pandruvada IIO_EV_DIR_FALLING), 1088b4b491c0SSrinivas Pandruvada data->timestamp); 1089b4b491c0SSrinivas Pandruvada if (ret & KXCJK1013_REG_INT_SRC2_BIT_YP) 1090b4b491c0SSrinivas Pandruvada iio_push_event(indio_dev, 1091b4b491c0SSrinivas Pandruvada IIO_MOD_EVENT_CODE(IIO_ACCEL, 1092b4b491c0SSrinivas Pandruvada 0, 1093b4b491c0SSrinivas Pandruvada IIO_MOD_Y, 1094b4b491c0SSrinivas Pandruvada IIO_EV_TYPE_THRESH, 1095b4b491c0SSrinivas Pandruvada IIO_EV_DIR_RISING), 1096b4b491c0SSrinivas Pandruvada data->timestamp); 1097b4b491c0SSrinivas Pandruvada 1098b4b491c0SSrinivas Pandruvada if (ret & KXCJK1013_REG_INT_SRC2_BIT_ZN) 1099b4b491c0SSrinivas Pandruvada iio_push_event(indio_dev, 1100b4b491c0SSrinivas Pandruvada IIO_MOD_EVENT_CODE(IIO_ACCEL, 1101b4b491c0SSrinivas Pandruvada 0, 1102b4b491c0SSrinivas Pandruvada IIO_MOD_Z, 1103b4b491c0SSrinivas Pandruvada IIO_EV_TYPE_THRESH, 1104b4b491c0SSrinivas Pandruvada IIO_EV_DIR_FALLING), 1105b4b491c0SSrinivas Pandruvada data->timestamp); 1106b4b491c0SSrinivas Pandruvada if (ret & KXCJK1013_REG_INT_SRC2_BIT_ZP) 1107b4b491c0SSrinivas Pandruvada iio_push_event(indio_dev, 1108b4b491c0SSrinivas Pandruvada IIO_MOD_EVENT_CODE(IIO_ACCEL, 1109b4b491c0SSrinivas Pandruvada 0, 1110b4b491c0SSrinivas Pandruvada IIO_MOD_Z, 1111b4b491c0SSrinivas Pandruvada IIO_EV_TYPE_THRESH, 1112b4b491c0SSrinivas Pandruvada IIO_EV_DIR_RISING), 1113b4b491c0SSrinivas Pandruvada data->timestamp); 1114b4b491c0SSrinivas Pandruvada } 1115b4b491c0SSrinivas Pandruvada 1116b4b491c0SSrinivas Pandruvada ack_intr: 1117b4b491c0SSrinivas Pandruvada if (data->dready_trigger_on) 1118b4b491c0SSrinivas Pandruvada return IRQ_HANDLED; 1119b4b491c0SSrinivas Pandruvada 1120b4b491c0SSrinivas Pandruvada ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_REL); 1121b4b491c0SSrinivas Pandruvada if (ret < 0) 1122b4b491c0SSrinivas Pandruvada dev_err(&data->client->dev, "Error reading reg_int_rel\n"); 1123b4b491c0SSrinivas Pandruvada 1124b4b491c0SSrinivas Pandruvada return IRQ_HANDLED; 1125b4b491c0SSrinivas Pandruvada } 1126b4b491c0SSrinivas Pandruvada 1127b4b491c0SSrinivas Pandruvada static irqreturn_t kxcjk1013_data_rdy_trig_poll(int irq, void *private) 1128b4b491c0SSrinivas Pandruvada { 1129b4b491c0SSrinivas Pandruvada struct iio_dev *indio_dev = private; 1130b4b491c0SSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 1131b4b491c0SSrinivas Pandruvada 1132bc2b7dabSGregor Boirie data->timestamp = iio_get_time_ns(indio_dev); 1133b4b491c0SSrinivas Pandruvada 1134b4b491c0SSrinivas Pandruvada if (data->dready_trigger_on) 1135b4b491c0SSrinivas Pandruvada iio_trigger_poll(data->dready_trig); 1136b4b491c0SSrinivas Pandruvada else if (data->motion_trigger_on) 1137b4b491c0SSrinivas Pandruvada iio_trigger_poll(data->motion_trig); 1138b4b491c0SSrinivas Pandruvada 1139b4b491c0SSrinivas Pandruvada if (data->ev_enable_state) 1140b4b491c0SSrinivas Pandruvada return IRQ_WAKE_THREAD; 1141b4b491c0SSrinivas Pandruvada else 1142b4b491c0SSrinivas Pandruvada return IRQ_HANDLED; 1143b4b491c0SSrinivas Pandruvada } 1144b4b491c0SSrinivas Pandruvada 1145c6861377SDaniel Baluta static const char *kxcjk1013_match_acpi_device(struct device *dev, 11463bfa74f8SBastien Nocera enum kx_chipset *chipset, 11473bfa74f8SBastien Nocera bool *is_smo8500_device) 11481a4fbf6aSSrinivas Pandruvada { 11491a4fbf6aSSrinivas Pandruvada const struct acpi_device_id *id; 1150b0868df4SRoberta Dobrescu 1151c6861377SDaniel Baluta id = acpi_match_device(dev->driver->acpi_match_table, dev); 1152c6861377SDaniel Baluta if (!id) 1153c6861377SDaniel Baluta return NULL; 1154e693e15eSAntonio Ospite 11553bfa74f8SBastien Nocera if (strcmp(id->id, "SMO8500") == 0) 11563bfa74f8SBastien Nocera *is_smo8500_device = true; 1157e693e15eSAntonio Ospite 1158c6861377SDaniel Baluta *chipset = (enum kx_chipset)id->driver_data; 1159c6861377SDaniel Baluta 1160c6861377SDaniel Baluta return dev_name(dev); 1161c6861377SDaniel Baluta } 1162c6861377SDaniel Baluta 11631a4fbf6aSSrinivas Pandruvada static int kxcjk1013_probe(struct i2c_client *client, 11641a4fbf6aSSrinivas Pandruvada const struct i2c_device_id *id) 11651a4fbf6aSSrinivas Pandruvada { 11661a4fbf6aSSrinivas Pandruvada struct kxcjk1013_data *data; 11671a4fbf6aSSrinivas Pandruvada struct iio_dev *indio_dev; 11681a4fbf6aSSrinivas Pandruvada struct kxcjk_1013_platform_data *pdata; 1169c6861377SDaniel Baluta const char *name; 11701a4fbf6aSSrinivas Pandruvada int ret; 11711a4fbf6aSSrinivas Pandruvada 11721a4fbf6aSSrinivas Pandruvada indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 11731a4fbf6aSSrinivas Pandruvada if (!indio_dev) 11741a4fbf6aSSrinivas Pandruvada return -ENOMEM; 11751a4fbf6aSSrinivas Pandruvada 11761a4fbf6aSSrinivas Pandruvada data = iio_priv(indio_dev); 11771a4fbf6aSSrinivas Pandruvada i2c_set_clientdata(client, indio_dev); 11781a4fbf6aSSrinivas Pandruvada data->client = client; 11791a4fbf6aSSrinivas Pandruvada 11801a4fbf6aSSrinivas Pandruvada pdata = dev_get_platdata(&client->dev); 11811a4fbf6aSSrinivas Pandruvada if (pdata) 11821a4fbf6aSSrinivas Pandruvada data->active_high_intr = pdata->active_high_intr; 11831a4fbf6aSSrinivas Pandruvada else 11841a4fbf6aSSrinivas Pandruvada data->active_high_intr = true; /* default polarity */ 11851a4fbf6aSSrinivas Pandruvada 1186c6861377SDaniel Baluta if (id) { 1187c6861377SDaniel Baluta data->chipset = (enum kx_chipset)(id->driver_data); 1188c6861377SDaniel Baluta name = id->name; 1189c6861377SDaniel Baluta } else if (ACPI_HANDLE(&client->dev)) { 1190c6861377SDaniel Baluta name = kxcjk1013_match_acpi_device(&client->dev, 11913bfa74f8SBastien Nocera &data->chipset, 11923bfa74f8SBastien Nocera &data->is_smo8500_device); 1193c6861377SDaniel Baluta } else 1194c6861377SDaniel Baluta return -ENODEV; 1195c6861377SDaniel Baluta 11961a4fbf6aSSrinivas Pandruvada ret = kxcjk1013_chip_init(data); 11971a4fbf6aSSrinivas Pandruvada if (ret < 0) 11981a4fbf6aSSrinivas Pandruvada return ret; 11991a4fbf6aSSrinivas Pandruvada 12001a4fbf6aSSrinivas Pandruvada mutex_init(&data->mutex); 12011a4fbf6aSSrinivas Pandruvada 12021a4fbf6aSSrinivas Pandruvada indio_dev->dev.parent = &client->dev; 12031a4fbf6aSSrinivas Pandruvada indio_dev->channels = kxcjk1013_channels; 12041a4fbf6aSSrinivas Pandruvada indio_dev->num_channels = ARRAY_SIZE(kxcjk1013_channels); 120509cf1b32SAdriana Reus indio_dev->available_scan_masks = kxcjk1013_scan_masks; 1206c6861377SDaniel Baluta indio_dev->name = name; 12071a4fbf6aSSrinivas Pandruvada indio_dev->modes = INDIO_DIRECT_MODE; 12081a4fbf6aSSrinivas Pandruvada indio_dev->info = &kxcjk1013_info; 12091a4fbf6aSSrinivas Pandruvada 12100f079650SOctavian Purdila if (client->irq > 0 && !data->is_smo8500_device) { 1211b4b491c0SSrinivas Pandruvada ret = devm_request_threaded_irq(&client->dev, client->irq, 1212b4b491c0SSrinivas Pandruvada kxcjk1013_data_rdy_trig_poll, 1213b4b491c0SSrinivas Pandruvada kxcjk1013_event_handler, 12141a4fbf6aSSrinivas Pandruvada IRQF_TRIGGER_RISING, 12151a4fbf6aSSrinivas Pandruvada KXCJK1013_IRQ_NAME, 1216b4b491c0SSrinivas Pandruvada indio_dev); 12171a4fbf6aSSrinivas Pandruvada if (ret) 12189d02daf7SIrina Tirdea goto err_poweroff; 1219b4b491c0SSrinivas Pandruvada 1220b4b491c0SSrinivas Pandruvada data->dready_trig = devm_iio_trigger_alloc(&client->dev, 1221b4b491c0SSrinivas Pandruvada "%s-dev%d", 1222b4b491c0SSrinivas Pandruvada indio_dev->name, 1223b4b491c0SSrinivas Pandruvada indio_dev->id); 12249d02daf7SIrina Tirdea if (!data->dready_trig) { 12259d02daf7SIrina Tirdea ret = -ENOMEM; 12269d02daf7SIrina Tirdea goto err_poweroff; 12279d02daf7SIrina Tirdea } 1228b4b491c0SSrinivas Pandruvada 1229b4b491c0SSrinivas Pandruvada data->motion_trig = devm_iio_trigger_alloc(&client->dev, 1230b4b491c0SSrinivas Pandruvada "%s-any-motion-dev%d", 1231b4b491c0SSrinivas Pandruvada indio_dev->name, 1232b4b491c0SSrinivas Pandruvada indio_dev->id); 12339d02daf7SIrina Tirdea if (!data->motion_trig) { 12349d02daf7SIrina Tirdea ret = -ENOMEM; 12359d02daf7SIrina Tirdea goto err_poweroff; 12369d02daf7SIrina Tirdea } 1237b4b491c0SSrinivas Pandruvada 1238b4b491c0SSrinivas Pandruvada data->dready_trig->dev.parent = &client->dev; 1239b4b491c0SSrinivas Pandruvada data->dready_trig->ops = &kxcjk1013_trigger_ops; 1240b4b491c0SSrinivas Pandruvada iio_trigger_set_drvdata(data->dready_trig, indio_dev); 1241b4b491c0SSrinivas Pandruvada indio_dev->trig = data->dready_trig; 1242b4b491c0SSrinivas Pandruvada iio_trigger_get(indio_dev->trig); 1243b4b491c0SSrinivas Pandruvada ret = iio_trigger_register(data->dready_trig); 1244b4b491c0SSrinivas Pandruvada if (ret) 12459d02daf7SIrina Tirdea goto err_poweroff; 1246b4b491c0SSrinivas Pandruvada 1247b4b491c0SSrinivas Pandruvada data->motion_trig->dev.parent = &client->dev; 1248b4b491c0SSrinivas Pandruvada data->motion_trig->ops = &kxcjk1013_trigger_ops; 1249b4b491c0SSrinivas Pandruvada iio_trigger_set_drvdata(data->motion_trig, indio_dev); 1250b4b491c0SSrinivas Pandruvada ret = iio_trigger_register(data->motion_trig); 1251b4b491c0SSrinivas Pandruvada if (ret) { 1252b4b491c0SSrinivas Pandruvada data->motion_trig = NULL; 1253b4b491c0SSrinivas Pandruvada goto err_trigger_unregister; 1254b4b491c0SSrinivas Pandruvada } 1255a25691c1SVlad Dogaru } 12561a4fbf6aSSrinivas Pandruvada 12571a4fbf6aSSrinivas Pandruvada ret = iio_triggered_buffer_setup(indio_dev, 12581a4fbf6aSSrinivas Pandruvada &iio_pollfunc_store_time, 12591a4fbf6aSSrinivas Pandruvada kxcjk1013_trigger_handler, 1260a25691c1SVlad Dogaru &kxcjk1013_buffer_setup_ops); 12611a4fbf6aSSrinivas Pandruvada if (ret < 0) { 1262a25691c1SVlad Dogaru dev_err(&client->dev, "iio triggered buffer setup failed\n"); 12631a4fbf6aSSrinivas Pandruvada goto err_trigger_unregister; 12641a4fbf6aSSrinivas Pandruvada } 12651a4fbf6aSSrinivas Pandruvada 1266124e1b1dSSrinivas Pandruvada ret = pm_runtime_set_active(&client->dev); 1267124e1b1dSSrinivas Pandruvada if (ret) 12687d0ead5cSAdriana Reus goto err_buffer_cleanup; 1269124e1b1dSSrinivas Pandruvada 1270124e1b1dSSrinivas Pandruvada pm_runtime_enable(&client->dev); 1271124e1b1dSSrinivas Pandruvada pm_runtime_set_autosuspend_delay(&client->dev, 1272124e1b1dSSrinivas Pandruvada KXCJK1013_SLEEP_DELAY_MS); 1273124e1b1dSSrinivas Pandruvada pm_runtime_use_autosuspend(&client->dev); 1274124e1b1dSSrinivas Pandruvada 12757d0ead5cSAdriana Reus ret = iio_device_register(indio_dev); 12767d0ead5cSAdriana Reus if (ret < 0) { 12777d0ead5cSAdriana Reus dev_err(&client->dev, "unable to register iio device\n"); 12787d0ead5cSAdriana Reus goto err_buffer_cleanup; 12797d0ead5cSAdriana Reus } 12807d0ead5cSAdriana Reus 12811a4fbf6aSSrinivas Pandruvada return 0; 12821a4fbf6aSSrinivas Pandruvada 12831a4fbf6aSSrinivas Pandruvada err_buffer_cleanup: 1284b4b491c0SSrinivas Pandruvada if (data->dready_trig) 12851a4fbf6aSSrinivas Pandruvada iio_triggered_buffer_cleanup(indio_dev); 12861a4fbf6aSSrinivas Pandruvada err_trigger_unregister: 1287b4b491c0SSrinivas Pandruvada if (data->dready_trig) 1288b4b491c0SSrinivas Pandruvada iio_trigger_unregister(data->dready_trig); 1289b4b491c0SSrinivas Pandruvada if (data->motion_trig) 1290b4b491c0SSrinivas Pandruvada iio_trigger_unregister(data->motion_trig); 12919d02daf7SIrina Tirdea err_poweroff: 12929d02daf7SIrina Tirdea kxcjk1013_set_mode(data, STANDBY); 12931a4fbf6aSSrinivas Pandruvada 12941a4fbf6aSSrinivas Pandruvada return ret; 12951a4fbf6aSSrinivas Pandruvada } 12961a4fbf6aSSrinivas Pandruvada 12971a4fbf6aSSrinivas Pandruvada static int kxcjk1013_remove(struct i2c_client *client) 12981a4fbf6aSSrinivas Pandruvada { 12991a4fbf6aSSrinivas Pandruvada struct iio_dev *indio_dev = i2c_get_clientdata(client); 13001a4fbf6aSSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 13011a4fbf6aSSrinivas Pandruvada 13027d0ead5cSAdriana Reus iio_device_unregister(indio_dev); 13037d0ead5cSAdriana Reus 1304124e1b1dSSrinivas Pandruvada pm_runtime_disable(&client->dev); 1305124e1b1dSSrinivas Pandruvada pm_runtime_set_suspended(&client->dev); 1306124e1b1dSSrinivas Pandruvada pm_runtime_put_noidle(&client->dev); 1307124e1b1dSSrinivas Pandruvada 1308b4b491c0SSrinivas Pandruvada if (data->dready_trig) { 13091a4fbf6aSSrinivas Pandruvada iio_triggered_buffer_cleanup(indio_dev); 1310b4b491c0SSrinivas Pandruvada iio_trigger_unregister(data->dready_trig); 1311b4b491c0SSrinivas Pandruvada iio_trigger_unregister(data->motion_trig); 13121a4fbf6aSSrinivas Pandruvada } 13131a4fbf6aSSrinivas Pandruvada 13141a4fbf6aSSrinivas Pandruvada mutex_lock(&data->mutex); 13151a4fbf6aSSrinivas Pandruvada kxcjk1013_set_mode(data, STANDBY); 13161a4fbf6aSSrinivas Pandruvada mutex_unlock(&data->mutex); 13171a4fbf6aSSrinivas Pandruvada 13181a4fbf6aSSrinivas Pandruvada return 0; 13191a4fbf6aSSrinivas Pandruvada } 13201a4fbf6aSSrinivas Pandruvada 13211a4fbf6aSSrinivas Pandruvada #ifdef CONFIG_PM_SLEEP 13221a4fbf6aSSrinivas Pandruvada static int kxcjk1013_suspend(struct device *dev) 13231a4fbf6aSSrinivas Pandruvada { 13241a4fbf6aSSrinivas Pandruvada struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 13251a4fbf6aSSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 1326124e1b1dSSrinivas Pandruvada int ret; 13271a4fbf6aSSrinivas Pandruvada 13281a4fbf6aSSrinivas Pandruvada mutex_lock(&data->mutex); 1329124e1b1dSSrinivas Pandruvada ret = kxcjk1013_set_mode(data, STANDBY); 13301a4fbf6aSSrinivas Pandruvada mutex_unlock(&data->mutex); 13311a4fbf6aSSrinivas Pandruvada 1332124e1b1dSSrinivas Pandruvada return ret; 13331a4fbf6aSSrinivas Pandruvada } 13341a4fbf6aSSrinivas Pandruvada 13351a4fbf6aSSrinivas Pandruvada static int kxcjk1013_resume(struct device *dev) 13361a4fbf6aSSrinivas Pandruvada { 13371a4fbf6aSSrinivas Pandruvada struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 13381a4fbf6aSSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 1339124e1b1dSSrinivas Pandruvada int ret = 0; 13401a4fbf6aSSrinivas Pandruvada 13411a4fbf6aSSrinivas Pandruvada mutex_lock(&data->mutex); 1342124e1b1dSSrinivas Pandruvada ret = kxcjk1013_set_mode(data, OPERATION); 13431a4fbf6aSSrinivas Pandruvada mutex_unlock(&data->mutex); 13441a4fbf6aSSrinivas Pandruvada 1345124e1b1dSSrinivas Pandruvada return ret; 1346124e1b1dSSrinivas Pandruvada } 1347124e1b1dSSrinivas Pandruvada #endif 1348124e1b1dSSrinivas Pandruvada 13496f0a13f2SRafael J. Wysocki #ifdef CONFIG_PM 1350124e1b1dSSrinivas Pandruvada static int kxcjk1013_runtime_suspend(struct device *dev) 1351124e1b1dSSrinivas Pandruvada { 1352124e1b1dSSrinivas Pandruvada struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 1353124e1b1dSSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 1354fbd123e9SIrina Tirdea int ret; 1355124e1b1dSSrinivas Pandruvada 1356fbd123e9SIrina Tirdea ret = kxcjk1013_set_mode(data, STANDBY); 1357fbd123e9SIrina Tirdea if (ret < 0) { 1358fbd123e9SIrina Tirdea dev_err(&data->client->dev, "powering off device failed\n"); 1359fbd123e9SIrina Tirdea return -EAGAIN; 1360fbd123e9SIrina Tirdea } 1361fbd123e9SIrina Tirdea return 0; 1362124e1b1dSSrinivas Pandruvada } 1363124e1b1dSSrinivas Pandruvada 1364124e1b1dSSrinivas Pandruvada static int kxcjk1013_runtime_resume(struct device *dev) 1365124e1b1dSSrinivas Pandruvada { 1366124e1b1dSSrinivas Pandruvada struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 1367124e1b1dSSrinivas Pandruvada struct kxcjk1013_data *data = iio_priv(indio_dev); 1368124e1b1dSSrinivas Pandruvada int ret; 1369124e1b1dSSrinivas Pandruvada int sleep_val; 1370124e1b1dSSrinivas Pandruvada 1371124e1b1dSSrinivas Pandruvada ret = kxcjk1013_set_mode(data, OPERATION); 1372124e1b1dSSrinivas Pandruvada if (ret < 0) 1373124e1b1dSSrinivas Pandruvada return ret; 1374124e1b1dSSrinivas Pandruvada 1375124e1b1dSSrinivas Pandruvada sleep_val = kxcjk1013_get_startup_times(data); 1376124e1b1dSSrinivas Pandruvada if (sleep_val < 20000) 1377124e1b1dSSrinivas Pandruvada usleep_range(sleep_val, 20000); 1378124e1b1dSSrinivas Pandruvada else 1379124e1b1dSSrinivas Pandruvada msleep_interruptible(sleep_val/1000); 1380124e1b1dSSrinivas Pandruvada 13811a4fbf6aSSrinivas Pandruvada return 0; 13821a4fbf6aSSrinivas Pandruvada } 13831a4fbf6aSSrinivas Pandruvada #endif 13841a4fbf6aSSrinivas Pandruvada 1385124e1b1dSSrinivas Pandruvada static const struct dev_pm_ops kxcjk1013_pm_ops = { 1386124e1b1dSSrinivas Pandruvada SET_SYSTEM_SLEEP_PM_OPS(kxcjk1013_suspend, kxcjk1013_resume) 1387124e1b1dSSrinivas Pandruvada SET_RUNTIME_PM_OPS(kxcjk1013_runtime_suspend, 1388124e1b1dSSrinivas Pandruvada kxcjk1013_runtime_resume, NULL) 1389124e1b1dSSrinivas Pandruvada }; 1390124e1b1dSSrinivas Pandruvada 13911a4fbf6aSSrinivas Pandruvada static const struct acpi_device_id kx_acpi_match[] = { 1392c6861377SDaniel Baluta {"KXCJ1013", KXCJK1013}, 1393c6861377SDaniel Baluta {"KXCJ1008", KXCJ91008}, 139461e2c70dSAntonio Ospite {"KXCJ9000", KXCJ91008}, 1395*4d19c487SChristophe Chapuis {"KIOX000A", KXCJ91008}, 1396c6861377SDaniel Baluta {"KXTJ1009", KXTJ21009}, 13973bfa74f8SBastien Nocera {"SMO8500", KXCJ91008}, 13981a4fbf6aSSrinivas Pandruvada { }, 13991a4fbf6aSSrinivas Pandruvada }; 14001a4fbf6aSSrinivas Pandruvada MODULE_DEVICE_TABLE(acpi, kx_acpi_match); 14011a4fbf6aSSrinivas Pandruvada 14021a4fbf6aSSrinivas Pandruvada static const struct i2c_device_id kxcjk1013_id[] = { 1403c6861377SDaniel Baluta {"kxcjk1013", KXCJK1013}, 1404c6861377SDaniel Baluta {"kxcj91008", KXCJ91008}, 1405c6861377SDaniel Baluta {"kxtj21009", KXTJ21009}, 14063bfa74f8SBastien Nocera {"SMO8500", KXCJ91008}, 14071a4fbf6aSSrinivas Pandruvada {} 14081a4fbf6aSSrinivas Pandruvada }; 14091a4fbf6aSSrinivas Pandruvada 14101a4fbf6aSSrinivas Pandruvada MODULE_DEVICE_TABLE(i2c, kxcjk1013_id); 14111a4fbf6aSSrinivas Pandruvada 14121a4fbf6aSSrinivas Pandruvada static struct i2c_driver kxcjk1013_driver = { 14131a4fbf6aSSrinivas Pandruvada .driver = { 14141a4fbf6aSSrinivas Pandruvada .name = KXCJK1013_DRV_NAME, 14151a4fbf6aSSrinivas Pandruvada .acpi_match_table = ACPI_PTR(kx_acpi_match), 1416124e1b1dSSrinivas Pandruvada .pm = &kxcjk1013_pm_ops, 14171a4fbf6aSSrinivas Pandruvada }, 14181a4fbf6aSSrinivas Pandruvada .probe = kxcjk1013_probe, 14191a4fbf6aSSrinivas Pandruvada .remove = kxcjk1013_remove, 14201a4fbf6aSSrinivas Pandruvada .id_table = kxcjk1013_id, 14211a4fbf6aSSrinivas Pandruvada }; 14221a4fbf6aSSrinivas Pandruvada module_i2c_driver(kxcjk1013_driver); 14231a4fbf6aSSrinivas Pandruvada 14241a4fbf6aSSrinivas Pandruvada MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"); 14251a4fbf6aSSrinivas Pandruvada MODULE_LICENSE("GPL v2"); 14261a4fbf6aSSrinivas Pandruvada MODULE_DESCRIPTION("KXCJK1013 accelerometer driver"); 1427