11a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada/*
21a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada * KXCJK-1013 3-axis accelerometer driver
31a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada * Copyright (c) 2014, Intel Corporation.
41a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada *
51a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada * This program is free software; you can redistribute it and/or modify it
61a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada * under the terms and conditions of the GNU General Public License,
71a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada * version 2, as published by the Free Software Foundation.
81a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada *
91a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada * This program is distributed in the hope it will be useful, but WITHOUT
101a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
111a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
121a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada * more details.
131a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada */
141a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
151a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/module.h>
161a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/i2c.h>
171a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/interrupt.h>
181a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/delay.h>
191a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/bitops.h>
201a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/slab.h>
211a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/string.h>
221a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/acpi.h>
231a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/gpio/consumer.h>
24124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada#include <linux/pm.h>
25124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada#include <linux/pm_runtime.h>
261a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/iio/iio.h>
271a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/iio/sysfs.h>
281a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/iio/buffer.h>
291a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/iio/trigger.h>
30b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada#include <linux/iio/events.h>
311a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/iio/trigger_consumer.h>
321a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/iio/triggered_buffer.h>
331a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#include <linux/iio/accel/kxcjk_1013.h>
341a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
351a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_DRV_NAME "kxcjk1013"
361a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_IRQ_NAME "kxcjk1013_event"
371a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
381a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_XOUT_L		0x06
391a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada/*
401a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada * From low byte X axis register, all the other addresses of Y and Z can be
411a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada * obtained by just applying axis offset. The following axis defines are just
421a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada * provide clarity, but not used.
431a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada */
441a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_XOUT_H		0x07
451a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_YOUT_L		0x08
461a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_YOUT_H		0x09
471a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_ZOUT_L		0x0A
481a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_ZOUT_H		0x0B
491a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
501a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_DCST_RESP		0x0C
511a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_WHO_AM_I		0x0F
521a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_INT_SRC1		0x16
531a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_INT_SRC2		0x17
541a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_STATUS_REG	0x18
551a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_INT_REL		0x1A
561a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_CTRL1		0x1B
571a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_CTRL2		0x1D
581a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_INT_CTRL1		0x1E
591a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_INT_CTRL2		0x1F
601a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_DATA_CTRL		0x21
611a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_WAKE_TIMER	0x29
621a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_SELF_TEST		0x3A
631a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_WAKE_THRES	0x6A
641a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
651a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_CTRL1_BIT_PC1	BIT(7)
661a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_CTRL1_BIT_RES	BIT(6)
671a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_CTRL1_BIT_DRDY	BIT(5)
681a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_CTRL1_BIT_GSEL1	BIT(4)
691a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_CTRL1_BIT_GSEL0	BIT(3)
701a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_CTRL1_BIT_WUFE	BIT(1)
711a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_INT_REG1_BIT_IEA	BIT(4)
721a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_REG_INT_REG1_BIT_IEN	BIT(5)
731a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
741a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_DATA_MASK_12_BIT	0x0FFF
751a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada#define KXCJK1013_MAX_STARTUP_TIME_US	100000
761a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
77124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada#define KXCJK1013_SLEEP_DELAY_MS	2000
78124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada
79b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada#define KXCJK1013_REG_INT_SRC2_BIT_ZP	BIT(0)
80b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada#define KXCJK1013_REG_INT_SRC2_BIT_ZN	BIT(1)
81b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada#define KXCJK1013_REG_INT_SRC2_BIT_YP	BIT(2)
82b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada#define KXCJK1013_REG_INT_SRC2_BIT_YN	BIT(3)
83b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada#define KXCJK1013_REG_INT_SRC2_BIT_XP	BIT(4)
84b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada#define KXCJK1013_REG_INT_SRC2_BIT_XN	BIT(5)
85b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
86b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada#define KXCJK1013_DEFAULT_WAKE_THRES	1
87b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
88c68613777517e538ace751e4e738e238eb216f86Daniel Balutaenum kx_chipset {
89c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	KXCJK1013,
90c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	KXCJ91008,
91c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	KXTJ21009,
92c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	KX_MAX_CHIPS /* this must be last */
93c68613777517e538ace751e4e738e238eb216f86Daniel Baluta};
94c68613777517e538ace751e4e738e238eb216f86Daniel Baluta
951a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvadastruct kxcjk1013_data {
961a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	struct i2c_client *client;
97b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	struct iio_trigger *dready_trig;
98b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	struct iio_trigger *motion_trig;
991a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	struct mutex mutex;
1001a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	s16 buffer[8];
1011a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	u8 odr_bits;
102a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	u8 range;
103b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	int wake_thres;
104b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	int wake_dur;
1051a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	bool active_high_intr;
106b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	bool dready_trigger_on;
107b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	int ev_enable_state;
108b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	bool motion_trigger_on;
109b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	int64_t timestamp;
110c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	enum kx_chipset chipset;
1111a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada};
1121a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
1131a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvadaenum kxcjk1013_axis {
1141a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	AXIS_X,
1151a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	AXIS_Y,
1161a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	AXIS_Z,
1171a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada};
1181a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
1191a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvadaenum kxcjk1013_mode {
1201a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	STANDBY,
1211a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	OPERATION,
1221a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada};
1231a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
124a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvadaenum kxcjk1013_range {
125a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	KXCJK1013_RANGE_2G,
126a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	KXCJK1013_RANGE_4G,
127a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	KXCJK1013_RANGE_8G,
128a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada};
129a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada
1301a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvadastatic const struct {
1311a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	int val;
1321a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	int val2;
1331a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	int odr_bits;
1341a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada} samp_freq_table[] = { {0, 781000, 0x08}, {1, 563000, 0x09},
135f0ca974920686d53cf2330ef8abcc6e4489201d6Srinivas Pandruvada			{3, 125000, 0x0A}, {6, 250000, 0x0B}, {12, 500000, 0},
1361a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada			{25, 0, 0x01}, {50, 0, 0x02}, {100, 0, 0x03},
1371a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada			{200, 0, 0x04}, {400, 0, 0x05}, {800, 0, 0x06},
1381a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada			{1600, 0, 0x07} };
1391a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
1401a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada/* Refer to section 4 of the specification */
1411a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvadastatic const struct {
1421a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	int odr_bits;
1431a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	int usec;
144c68613777517e538ace751e4e738e238eb216f86Daniel Baluta} odr_start_up_times[KX_MAX_CHIPS][12] = {
145c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	/* KXCJK-1013 */
146c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	{
147c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x08, 100000},
148c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x09, 100000},
149c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x0A, 100000},
150c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x0B, 100000},
151c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0, 80000},
152c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x01, 41000},
153c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x02, 21000},
154c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x03, 11000},
155c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x04, 6400},
156c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x05, 3900},
157c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x06, 2700},
158c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x07, 2100},
159c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	},
160c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	/* KXCJ9-1008 */
161c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	{
162c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x08, 100000},
163c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x09, 100000},
164c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x0A, 100000},
165c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x0B, 100000},
166c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0, 80000},
167c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x01, 41000},
168c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x02, 21000},
169c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x03, 11000},
170c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x04, 6400},
171c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x05, 3900},
172c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x06, 2700},
173c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x07, 2100},
174c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	},
175c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	/* KXCTJ2-1009 */
176c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	{
177c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x08, 1240000},
178c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x09, 621000},
179c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x0A, 309000},
180c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x0B, 151000},
181c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0, 80000},
182c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x01, 41000},
183c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x02, 21000},
184c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x03, 11000},
185c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x04, 6000},
186c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x05, 4000},
187c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x06, 3000},
188c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		{0x07, 2000},
189c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	},
190c68613777517e538ace751e4e738e238eb216f86Daniel Baluta};
1911a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
192a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvadastatic const struct {
193a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	u16 scale;
194a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	u8 gsel_0;
195a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	u8 gsel_1;
196a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada} KXCJK1013_scale_table[] = { {9582, 0, 0},
197a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada			      {19163, 1, 0},
198a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada			      {38326, 0, 1} };
199a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada
200b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvadastatic const struct {
201b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	int val;
202b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	int val2;
203b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	int odr_bits;
204b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada} wake_odr_data_rate_table[] = { {0, 781000, 0x00},
205b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada				 {1, 563000, 0x01},
206b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada				 {3, 125000, 0x02},
207b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada				 {6, 250000, 0x03},
208b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada				 {12, 500000, 0x04},
209b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada				 {25, 0, 0x05},
210b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada				 {50, 0, 0x06},
211b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada				 {100, 0, 0x06},
212b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada				 {200, 0, 0x06},
213b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada				 {400, 0, 0x06},
214b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada				 {800, 0, 0x06},
215b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada				 {1600, 0, 0x06} };
216b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
2171a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvadastatic int kxcjk1013_set_mode(struct kxcjk1013_data *data,
2181a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada			      enum kxcjk1013_mode mode)
2191a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada{
2201a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	int ret;
2211a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
2221a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
2231a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (ret < 0) {
2241a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
2251a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		return ret;
2261a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	}
2271a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
2281a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (mode == STANDBY)
2291a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		ret &= ~KXCJK1013_REG_CTRL1_BIT_PC1;
2301a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	else
2311a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		ret |= KXCJK1013_REG_CTRL1_BIT_PC1;
2321a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
2331a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	ret = i2c_smbus_write_byte_data(data->client,
2341a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada					KXCJK1013_REG_CTRL1, ret);
2351a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (ret < 0) {
2361a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
2371a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		return ret;
2381a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	}
2391a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
2401a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	return 0;
2411a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada}
2421a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
243124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvadastatic int kxcjk1013_get_mode(struct kxcjk1013_data *data,
244124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada			      enum kxcjk1013_mode *mode)
245124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada{
246124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	int ret;
247124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada
248124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
249124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	if (ret < 0) {
250124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada		dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
251124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada		return ret;
252124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	}
253124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada
254124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	if (ret & KXCJK1013_REG_CTRL1_BIT_PC1)
255124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada		*mode = OPERATION;
256124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	else
257124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada		*mode = STANDBY;
258124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada
259124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	return 0;
260124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada}
261124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada
262a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvadastatic int kxcjk1013_set_range(struct kxcjk1013_data *data, int range_index)
263a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada{
264a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	int ret;
265a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada
266a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
267a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	if (ret < 0) {
268a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada		dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
269a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada		return ret;
270a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	}
271a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada
272e90dea6aafa14eb60ab0927f6fe54c620f61ef74Daniel Baluta	ret &= ~(KXCJK1013_REG_CTRL1_BIT_GSEL0 |
273e90dea6aafa14eb60ab0927f6fe54c620f61ef74Daniel Baluta		 KXCJK1013_REG_CTRL1_BIT_GSEL1);
274a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	ret |= (KXCJK1013_scale_table[range_index].gsel_0 << 3);
275a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	ret |= (KXCJK1013_scale_table[range_index].gsel_1 << 4);
276a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada
277a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	ret = i2c_smbus_write_byte_data(data->client,
278a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada					KXCJK1013_REG_CTRL1,
279a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada					ret);
280a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	if (ret < 0) {
281a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada		dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
282a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada		return ret;
283a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	}
284a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada
285a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	data->range = range_index;
286a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada
287a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	return 0;
288a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada}
289a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada
2901a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvadastatic int kxcjk1013_chip_init(struct kxcjk1013_data *data)
2911a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada{
2921a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	int ret;
2931a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
2941a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_WHO_AM_I);
2951a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (ret < 0) {
2961a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		dev_err(&data->client->dev, "Error reading who_am_i\n");
2971a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		return ret;
2981a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	}
2991a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
3001a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	dev_dbg(&data->client->dev, "KXCJK1013 Chip Id %x\n", ret);
3011a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
3021a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	ret = kxcjk1013_set_mode(data, STANDBY);
3031a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (ret < 0)
3041a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		return ret;
3051a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
3061a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
3071a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (ret < 0) {
3081a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
3091a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		return ret;
3101a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	}
3111a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
3121a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	/* Set 12 bit mode */
3131a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	ret |= KXCJK1013_REG_CTRL1_BIT_RES;
3141a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
3151a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_CTRL1,
3161a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada					ret);
3171a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (ret < 0) {
3181a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		dev_err(&data->client->dev, "Error reading reg_ctrl\n");
3191a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		return ret;
3201a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	}
3211a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
322a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	/* Setting range to 4G */
323a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	ret = kxcjk1013_set_range(data, KXCJK1013_RANGE_4G);
324a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada	if (ret < 0)
325a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada		return ret;
326a735e3d7f03ab40d746290954baaf535719d9025Srinivas Pandruvada
3271a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_DATA_CTRL);
3281a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (ret < 0) {
3291a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		dev_err(&data->client->dev, "Error reading reg_data_ctrl\n");
3301a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		return ret;
3311a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	}
3321a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
3331a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	data->odr_bits = ret;
3341a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
3351a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	/* Set up INT polarity */
3361a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_CTRL1);
3371a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (ret < 0) {
3381a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		dev_err(&data->client->dev, "Error reading reg_int_ctrl1\n");
3391a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		return ret;
3401a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	}
3411a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
3421a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (data->active_high_intr)
3431a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		ret |= KXCJK1013_REG_INT_REG1_BIT_IEA;
3441a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	else
3451a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		ret &= ~KXCJK1013_REG_INT_REG1_BIT_IEA;
3461a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
3471a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_INT_CTRL1,
3481a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada					ret);
3491a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (ret < 0) {
3501a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n");
3511a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		return ret;
3521a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	}
3531a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
354124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	ret = kxcjk1013_set_mode(data, OPERATION);
355124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	if (ret < 0)
356124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada		return ret;
357124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada
358b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	data->wake_thres = KXCJK1013_DEFAULT_WAKE_THRES;
359b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
360124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	return 0;
361124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada}
362124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada
363c9bf2373da2144dec511503cebf5f8a63b0dcff3Daniel Baluta#ifdef CONFIG_PM_RUNTIME
364124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvadastatic int kxcjk1013_get_startup_times(struct kxcjk1013_data *data)
365124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada{
366124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	int i;
367c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	int idx = data->chipset;
368124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada
369c68613777517e538ace751e4e738e238eb216f86Daniel Baluta	for (i = 0; i < ARRAY_SIZE(odr_start_up_times[idx]); ++i) {
370c68613777517e538ace751e4e738e238eb216f86Daniel Baluta		if (odr_start_up_times[idx][i].odr_bits == data->odr_bits)
371c68613777517e538ace751e4e738e238eb216f86Daniel Baluta			return odr_start_up_times[idx][i].usec;
372124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	}
373124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada
374124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	return KXCJK1013_MAX_STARTUP_TIME_US;
375124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada}
376c9bf2373da2144dec511503cebf5f8a63b0dcff3Daniel Baluta#endif
377124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada
378124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvadastatic int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on)
379124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada{
380124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	int ret;
381124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada
382124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	if (on)
383124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada		ret = pm_runtime_get_sync(&data->client->dev);
384124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	else {
385124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada		pm_runtime_mark_last_busy(&data->client->dev);
386124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada		ret = pm_runtime_put_autosuspend(&data->client->dev);
387124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	}
388124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	if (ret < 0) {
389124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada		dev_err(&data->client->dev,
390124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada			"Failed: kxcjk1013_set_power_state for %d\n", on);
391124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada		return ret;
392124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	}
393124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada
3941a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	return 0;
3951a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada}
3961a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
397b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvadastatic int kxcjk1013_chip_update_thresholds(struct kxcjk1013_data *data)
398b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada{
399b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	int ret;
400b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
401b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	ret = i2c_smbus_write_byte_data(data->client,
402b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada					KXCJK1013_REG_WAKE_TIMER,
403b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada					data->wake_dur);
404b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	if (ret < 0) {
405b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		dev_err(&data->client->dev,
406b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada			"Error writing reg_wake_timer\n");
407b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		return ret;
408b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	}
409b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
410b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	ret = i2c_smbus_write_byte_data(data->client,
411b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada					KXCJK1013_REG_WAKE_THRES,
412b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada					data->wake_thres);
413b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	if (ret < 0) {
414b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		dev_err(&data->client->dev, "Error writing reg_wake_thres\n");
415b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		return ret;
416b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	}
417b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
418b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	return 0;
419b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada}
420b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
421b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvadastatic int kxcjk1013_setup_any_motion_interrupt(struct kxcjk1013_data *data,
422b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada						bool status)
423b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada{
424b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	int ret;
425b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	enum kxcjk1013_mode store_mode;
426b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
427b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	ret = kxcjk1013_get_mode(data, &store_mode);
428b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	if (ret < 0)
429b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		return ret;
430b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
431b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	/* This is requirement by spec to change state to STANDBY */
432b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	ret = kxcjk1013_set_mode(data, STANDBY);
433b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	if (ret < 0)
434b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		return ret;
435b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
436b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	ret = kxcjk1013_chip_update_thresholds(data);
437b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	if (ret < 0)
438b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		return ret;
439b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
440b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_CTRL1);
441b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	if (ret < 0) {
442b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		dev_err(&data->client->dev, "Error reading reg_int_ctrl1\n");
443b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		return ret;
444b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	}
445b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
446b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	if (status)
447b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		ret |= KXCJK1013_REG_INT_REG1_BIT_IEN;
448b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	else
449b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		ret &= ~KXCJK1013_REG_INT_REG1_BIT_IEN;
450b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
451b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_INT_CTRL1,
452b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada					ret);
453b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	if (ret < 0) {
454b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n");
455b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		return ret;
456b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	}
457b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
458b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
459b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	if (ret < 0) {
460b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
461b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		return ret;
462b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	}
463b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
464b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	if (status)
465b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		ret |= KXCJK1013_REG_CTRL1_BIT_WUFE;
466b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	else
467b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		ret &= ~KXCJK1013_REG_CTRL1_BIT_WUFE;
468b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
469b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	ret = i2c_smbus_write_byte_data(data->client,
470b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada					KXCJK1013_REG_CTRL1, ret);
471b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	if (ret < 0) {
472b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
473b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		return ret;
474b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	}
475b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
476b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	if (store_mode == OPERATION) {
477b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		ret = kxcjk1013_set_mode(data, OPERATION);
478b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		if (ret < 0)
479b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada			return ret;
480b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	}
481b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
482b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	return 0;
483b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada}
484b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
485b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvadastatic int kxcjk1013_setup_new_data_interrupt(struct kxcjk1013_data *data,
486b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada					      bool status)
4871a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada{
4881a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	int ret;
489124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	enum kxcjk1013_mode store_mode;
490124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada
491124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	ret = kxcjk1013_get_mode(data, &store_mode);
492124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	if (ret < 0)
493124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada		return ret;
4941a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
4951a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	/* This is requirement by spec to change state to STANDBY */
4961a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	ret = kxcjk1013_set_mode(data, STANDBY);
4971a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (ret < 0)
4981a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		return ret;
4991a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
5001a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_CTRL1);
5011a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (ret < 0) {
5021a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		dev_err(&data->client->dev, "Error reading reg_int_ctrl1\n");
5031a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		return ret;
5041a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	}
5051a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
5061a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (status)
5071a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		ret |= KXCJK1013_REG_INT_REG1_BIT_IEN;
5081a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	else
5091a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		ret &= ~KXCJK1013_REG_INT_REG1_BIT_IEN;
5101a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
5111a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_INT_CTRL1,
5121a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada					ret);
5131a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (ret < 0) {
5141a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n");
5151a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		return ret;
5161a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	}
5171a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
5181a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
5191a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (ret < 0) {
5201a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
5211a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		return ret;
5221a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	}
5231a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
5241a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (status)
5251a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		ret |= KXCJK1013_REG_CTRL1_BIT_DRDY;
5261a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	else
5271a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		ret &= ~KXCJK1013_REG_CTRL1_BIT_DRDY;
5281a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
5291a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	ret = i2c_smbus_write_byte_data(data->client,
5301a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada					KXCJK1013_REG_CTRL1, ret);
5311a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	if (ret < 0) {
5321a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
5331a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		return ret;
5341a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	}
5351a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
536124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	if (store_mode == OPERATION) {
537124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada		ret = kxcjk1013_set_mode(data, OPERATION);
538124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada		if (ret < 0)
539124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada			return ret;
540124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	}
541124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada
542124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	return 0;
5431a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada}
5441a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
5451a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvadastatic int kxcjk1013_convert_freq_to_bit(int val, int val2)
5461a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada{
5471a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	int i;
5481a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
5491a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	for (i = 0; i < ARRAY_SIZE(samp_freq_table); ++i) {
5501a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		if (samp_freq_table[i].val == val &&
5511a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada			samp_freq_table[i].val2 == val2) {
5521a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada			return samp_freq_table[i].odr_bits;
5531a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada		}
5541a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	}
5551a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
5561a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	return -EINVAL;
5571a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada}
5581a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada
559b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvadastatic int kxcjk1013_convert_wake_odr_to_bit(int val, int val2)
560b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada{
561b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	int i;
562b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
563b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	for (i = 0; i < ARRAY_SIZE(wake_odr_data_rate_table); ++i) {
564b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		if (wake_odr_data_rate_table[i].val == val &&
565b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada			wake_odr_data_rate_table[i].val2 == val2) {
566b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada			return wake_odr_data_rate_table[i].odr_bits;
567b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada		}
568b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	}
569b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
570b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada	return -EINVAL;
571b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada}
572b4b491c0832ef90a7a5070e5975bc8427f2049caSrinivas Pandruvada
5731a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvadastatic int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2)
5741a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada{
5751a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	int ret;
5761a4fbf6a9286a6e3db497bc7bbae2024f0f1ad90Srinivas Pandruvada	int odr_bits;
577124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada	enum kxcjk1013_mode store_mode;
578124e1b1d0924ca51ded8bb6f52844b2bc9e485f7Srinivas Pandruvada
579