xref: /openbmc/linux/drivers/iio/imu/kmx61.c (revision aff8609addd00efa3d907f3523823693f95686fd)
120ffac27SDaniel Baluta /*
220ffac27SDaniel Baluta  * KMX61 - Kionix 6-axis Accelerometer/Magnetometer
320ffac27SDaniel Baluta  *
420ffac27SDaniel Baluta  * Copyright (c) 2014, Intel Corporation.
520ffac27SDaniel Baluta  *
620ffac27SDaniel Baluta  * This file is subject to the terms and conditions of version 2 of
720ffac27SDaniel Baluta  * the GNU General Public License.  See the file COPYING in the main
820ffac27SDaniel Baluta  * directory of this archive for more details.
920ffac27SDaniel Baluta  *
1020ffac27SDaniel Baluta  * IIO driver for KMX61 (7-bit I2C slave address 0x0E or 0x0F).
1120ffac27SDaniel Baluta  *
1220ffac27SDaniel Baluta  */
1320ffac27SDaniel Baluta 
1420ffac27SDaniel Baluta #include <linux/module.h>
1520ffac27SDaniel Baluta #include <linux/i2c.h>
16b25862c5SDaniel Baluta #include <linux/acpi.h>
17b25862c5SDaniel Baluta #include <linux/gpio/consumer.h>
18*aff8609aSDaniel Baluta #include <linux/interrupt.h>
19*aff8609aSDaniel Baluta #include <linux/pm_runtime.h>
2020ffac27SDaniel Baluta #include <linux/iio/iio.h>
2120ffac27SDaniel Baluta #include <linux/iio/sysfs.h>
2220ffac27SDaniel Baluta 
2320ffac27SDaniel Baluta #define KMX61_DRV_NAME "kmx61"
24b25862c5SDaniel Baluta #define KMX61_GPIO_NAME "kmx61_int"
2520ffac27SDaniel Baluta 
2620ffac27SDaniel Baluta #define KMX61_REG_WHO_AM_I	0x00
2720ffac27SDaniel Baluta 
2820ffac27SDaniel Baluta /*
2920ffac27SDaniel Baluta  * three 16-bit accelerometer output registers for X/Y/Z axis
3020ffac27SDaniel Baluta  * we use only XOUT_L as a base register, all other addresses
3120ffac27SDaniel Baluta  * can be obtained by applying an offset and are provided here
3220ffac27SDaniel Baluta  * only for clarity.
3320ffac27SDaniel Baluta  */
3420ffac27SDaniel Baluta #define KMX61_ACC_XOUT_L	0x0A
3520ffac27SDaniel Baluta #define KMX61_ACC_XOUT_H	0x0B
3620ffac27SDaniel Baluta #define KMX61_ACC_YOUT_L	0x0C
3720ffac27SDaniel Baluta #define KMX61_ACC_YOUT_H	0x0D
3820ffac27SDaniel Baluta #define KMX61_ACC_ZOUT_L	0x0E
3920ffac27SDaniel Baluta #define KMX61_ACC_ZOUT_H	0x0F
4020ffac27SDaniel Baluta 
4120ffac27SDaniel Baluta /*
4220ffac27SDaniel Baluta  * one 16-bit temperature output register
4320ffac27SDaniel Baluta  */
4420ffac27SDaniel Baluta #define KMX61_TEMP_L		0x10
4520ffac27SDaniel Baluta #define KMX61_TEMP_H		0x11
4620ffac27SDaniel Baluta 
4720ffac27SDaniel Baluta /*
4820ffac27SDaniel Baluta  * three 16-bit magnetometer output registers for X/Y/Z axis
4920ffac27SDaniel Baluta  */
5020ffac27SDaniel Baluta #define KMX61_MAG_XOUT_L	0x12
5120ffac27SDaniel Baluta #define KMX61_MAG_XOUT_H	0x13
5220ffac27SDaniel Baluta #define KMX61_MAG_YOUT_L	0x14
5320ffac27SDaniel Baluta #define KMX61_MAG_YOUT_H	0x15
5420ffac27SDaniel Baluta #define KMX61_MAG_ZOUT_L	0x16
5520ffac27SDaniel Baluta #define KMX61_MAG_ZOUT_H	0x17
5620ffac27SDaniel Baluta 
5720ffac27SDaniel Baluta #define KMX61_REG_STBY		0x29
5820ffac27SDaniel Baluta #define KMX61_REG_CTRL1		0x2A
5920ffac27SDaniel Baluta #define KMX61_REG_ODCNTL	0x2C
6020ffac27SDaniel Baluta 
6120ffac27SDaniel Baluta #define KMX61_ACC_STBY_BIT	BIT(0)
6220ffac27SDaniel Baluta #define KMX61_MAG_STBY_BIT	BIT(1)
6320ffac27SDaniel Baluta #define KMX61_ACT_STBY_BIT	BIT(7)
6420ffac27SDaniel Baluta 
6520ffac27SDaniel Baluta #define KMX61_ALL_STBY		(KMX61_ACC_STBY_BIT | KMX61_MAG_STBY_BIT)
6620ffac27SDaniel Baluta 
6720ffac27SDaniel Baluta #define KMX61_REG_CTRL1_GSEL_MASK	0x03
6820ffac27SDaniel Baluta 
6920ffac27SDaniel Baluta #define KMX61_ACC_ODR_SHIFT	0
7020ffac27SDaniel Baluta #define KMX61_MAG_ODR_SHIFT	4
7120ffac27SDaniel Baluta #define KMX61_ACC_ODR_MASK	0x0F
7220ffac27SDaniel Baluta #define KMX61_MAG_ODR_MASK	0xF0
7320ffac27SDaniel Baluta 
74*aff8609aSDaniel Baluta #define KMX61_SLEEP_DELAY_MS	2000
75*aff8609aSDaniel Baluta 
7620ffac27SDaniel Baluta #define KMX61_CHIP_ID		0x12
7720ffac27SDaniel Baluta 
7820ffac27SDaniel Baluta /* KMX61 devices */
7920ffac27SDaniel Baluta #define KMX61_ACC	0x01
8020ffac27SDaniel Baluta #define KMX61_MAG	0x02
8120ffac27SDaniel Baluta 
8220ffac27SDaniel Baluta struct kmx61_data {
8320ffac27SDaniel Baluta 	struct i2c_client *client;
8420ffac27SDaniel Baluta 
8520ffac27SDaniel Baluta 	/* serialize access to non-atomic ops, e.g set_mode */
8620ffac27SDaniel Baluta 	struct mutex lock;
8720ffac27SDaniel Baluta 
8820ffac27SDaniel Baluta 	/* standby state */
8920ffac27SDaniel Baluta 	bool acc_stby;
9020ffac27SDaniel Baluta 	bool mag_stby;
9120ffac27SDaniel Baluta 
92*aff8609aSDaniel Baluta 	/* power state */
93*aff8609aSDaniel Baluta 	bool acc_ps;
94*aff8609aSDaniel Baluta 	bool mag_ps;
95*aff8609aSDaniel Baluta 
9620ffac27SDaniel Baluta 	/* config bits */
9720ffac27SDaniel Baluta 	u8 range;
9820ffac27SDaniel Baluta 	u8 odr_bits;
9920ffac27SDaniel Baluta 
10020ffac27SDaniel Baluta 	/* accelerometer specific data */
10120ffac27SDaniel Baluta 	struct iio_dev *acc_indio_dev;
10220ffac27SDaniel Baluta 
10320ffac27SDaniel Baluta 	/* magnetometer specific data */
10420ffac27SDaniel Baluta 	struct iio_dev *mag_indio_dev;
10520ffac27SDaniel Baluta };
10620ffac27SDaniel Baluta 
10720ffac27SDaniel Baluta enum kmx61_range {
10820ffac27SDaniel Baluta 	KMX61_RANGE_2G,
10920ffac27SDaniel Baluta 	KMX61_RANGE_4G,
11020ffac27SDaniel Baluta 	KMX61_RANGE_8G,
11120ffac27SDaniel Baluta };
11220ffac27SDaniel Baluta 
11320ffac27SDaniel Baluta enum kmx61_axis {
11420ffac27SDaniel Baluta 	KMX61_AXIS_X,
11520ffac27SDaniel Baluta 	KMX61_AXIS_Y,
11620ffac27SDaniel Baluta 	KMX61_AXIS_Z,
11720ffac27SDaniel Baluta };
11820ffac27SDaniel Baluta 
11920ffac27SDaniel Baluta static const u16 kmx61_uscale_table[] = {9582, 19163, 38326};
12020ffac27SDaniel Baluta 
12120ffac27SDaniel Baluta static const struct {
12220ffac27SDaniel Baluta 	int val;
12320ffac27SDaniel Baluta 	int val2;
12420ffac27SDaniel Baluta 	u8 odr_bits;
12520ffac27SDaniel Baluta } kmx61_samp_freq_table[] = { {12, 500000, 0x00},
12620ffac27SDaniel Baluta 			{25, 0, 0x01},
12720ffac27SDaniel Baluta 			{50, 0, 0x02},
12820ffac27SDaniel Baluta 			{100, 0, 0x03},
12920ffac27SDaniel Baluta 			{200, 0, 0x04},
13020ffac27SDaniel Baluta 			{400, 0, 0x05},
13120ffac27SDaniel Baluta 			{800, 0, 0x06},
13220ffac27SDaniel Baluta 			{1600, 0, 0x07},
13320ffac27SDaniel Baluta 			{0, 781000, 0x08},
13420ffac27SDaniel Baluta 			{1, 563000, 0x09},
13520ffac27SDaniel Baluta 			{3, 125000, 0x0A},
13620ffac27SDaniel Baluta 			{6, 250000, 0x0B} };
13720ffac27SDaniel Baluta 
13820ffac27SDaniel Baluta static IIO_CONST_ATTR(accel_scale_available, "0.009582 0.019163 0.038326");
13920ffac27SDaniel Baluta static IIO_CONST_ATTR(magn_scale_available, "0.001465");
14020ffac27SDaniel Baluta static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
14120ffac27SDaniel Baluta 	"0.781000 1.563000 3.125000 6.250000 12.500000 25 50 100 200 400 800");
14220ffac27SDaniel Baluta 
14320ffac27SDaniel Baluta static struct attribute *kmx61_acc_attributes[] = {
14420ffac27SDaniel Baluta 	&iio_const_attr_accel_scale_available.dev_attr.attr,
14520ffac27SDaniel Baluta 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
14620ffac27SDaniel Baluta 	NULL,
14720ffac27SDaniel Baluta };
14820ffac27SDaniel Baluta 
14920ffac27SDaniel Baluta static struct attribute *kmx61_mag_attributes[] = {
15020ffac27SDaniel Baluta 	&iio_const_attr_magn_scale_available.dev_attr.attr,
15120ffac27SDaniel Baluta 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
15220ffac27SDaniel Baluta 	NULL,
15320ffac27SDaniel Baluta };
15420ffac27SDaniel Baluta 
15520ffac27SDaniel Baluta static const struct attribute_group kmx61_acc_attribute_group = {
15620ffac27SDaniel Baluta 	.attrs = kmx61_acc_attributes,
15720ffac27SDaniel Baluta };
15820ffac27SDaniel Baluta 
15920ffac27SDaniel Baluta static const struct attribute_group kmx61_mag_attribute_group = {
16020ffac27SDaniel Baluta 	.attrs = kmx61_mag_attributes,
16120ffac27SDaniel Baluta };
16220ffac27SDaniel Baluta 
16320ffac27SDaniel Baluta #define KMX61_ACC_CHAN(_axis) { \
16420ffac27SDaniel Baluta 	.type = IIO_ACCEL, \
16520ffac27SDaniel Baluta 	.modified = 1, \
16620ffac27SDaniel Baluta 	.channel2 = IIO_MOD_ ## _axis, \
16720ffac27SDaniel Baluta 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
16820ffac27SDaniel Baluta 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
16920ffac27SDaniel Baluta 				BIT(IIO_CHAN_INFO_SAMP_FREQ), \
17020ffac27SDaniel Baluta 	.address = KMX61_ACC, \
17120ffac27SDaniel Baluta 	.scan_index = KMX61_AXIS_ ## _axis, \
17220ffac27SDaniel Baluta 	.scan_type = { \
17320ffac27SDaniel Baluta 		.sign = 's', \
17420ffac27SDaniel Baluta 		.realbits = 12, \
17520ffac27SDaniel Baluta 		.storagebits = 16, \
17620ffac27SDaniel Baluta 		.shift = 4, \
17720ffac27SDaniel Baluta 		.endianness = IIO_LE, \
17820ffac27SDaniel Baluta 	}, \
17920ffac27SDaniel Baluta }
18020ffac27SDaniel Baluta 
18120ffac27SDaniel Baluta #define KMX61_MAG_CHAN(_axis) { \
18220ffac27SDaniel Baluta 	.type = IIO_MAGN, \
18320ffac27SDaniel Baluta 	.modified = 1, \
18420ffac27SDaniel Baluta 	.channel2 = IIO_MOD_ ## _axis, \
18520ffac27SDaniel Baluta 	.address = KMX61_MAG, \
18620ffac27SDaniel Baluta 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
18720ffac27SDaniel Baluta 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
18820ffac27SDaniel Baluta 				BIT(IIO_CHAN_INFO_SAMP_FREQ), \
18920ffac27SDaniel Baluta 	.scan_index = KMX61_AXIS_ ## _axis, \
19020ffac27SDaniel Baluta 	.scan_type = { \
19120ffac27SDaniel Baluta 		.sign = 's', \
19220ffac27SDaniel Baluta 		.realbits = 14, \
19320ffac27SDaniel Baluta 		.storagebits = 16, \
19420ffac27SDaniel Baluta 		.shift = 2, \
19520ffac27SDaniel Baluta 		.endianness = IIO_LE, \
19620ffac27SDaniel Baluta 	}, \
19720ffac27SDaniel Baluta }
19820ffac27SDaniel Baluta 
19920ffac27SDaniel Baluta static const struct iio_chan_spec kmx61_acc_channels[] = {
20020ffac27SDaniel Baluta 	KMX61_ACC_CHAN(X),
20120ffac27SDaniel Baluta 	KMX61_ACC_CHAN(Y),
20220ffac27SDaniel Baluta 	KMX61_ACC_CHAN(Z),
20320ffac27SDaniel Baluta };
20420ffac27SDaniel Baluta 
20520ffac27SDaniel Baluta static const struct iio_chan_spec kmx61_mag_channels[] = {
20620ffac27SDaniel Baluta 	KMX61_MAG_CHAN(X),
20720ffac27SDaniel Baluta 	KMX61_MAG_CHAN(Y),
20820ffac27SDaniel Baluta 	KMX61_MAG_CHAN(Z),
20920ffac27SDaniel Baluta };
21020ffac27SDaniel Baluta 
21120ffac27SDaniel Baluta static void kmx61_set_data(struct iio_dev *indio_dev, struct kmx61_data *data)
21220ffac27SDaniel Baluta {
21320ffac27SDaniel Baluta 	struct kmx61_data **priv = iio_priv(indio_dev);
21420ffac27SDaniel Baluta 
21520ffac27SDaniel Baluta 	*priv = data;
21620ffac27SDaniel Baluta }
21720ffac27SDaniel Baluta 
21820ffac27SDaniel Baluta static struct kmx61_data *kmx61_get_data(struct iio_dev *indio_dev)
21920ffac27SDaniel Baluta {
22020ffac27SDaniel Baluta 	return *(struct kmx61_data **)iio_priv(indio_dev);
22120ffac27SDaniel Baluta }
22220ffac27SDaniel Baluta 
22320ffac27SDaniel Baluta static int kmx61_convert_freq_to_bit(int val, int val2)
22420ffac27SDaniel Baluta {
22520ffac27SDaniel Baluta 	int i;
22620ffac27SDaniel Baluta 
22720ffac27SDaniel Baluta 	for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++)
22820ffac27SDaniel Baluta 		if (val == kmx61_samp_freq_table[i].val &&
22920ffac27SDaniel Baluta 		    val2 == kmx61_samp_freq_table[i].val2)
23020ffac27SDaniel Baluta 			return kmx61_samp_freq_table[i].odr_bits;
23120ffac27SDaniel Baluta 	return -EINVAL;
23220ffac27SDaniel Baluta }
23320ffac27SDaniel Baluta 
23420ffac27SDaniel Baluta /**
23520ffac27SDaniel Baluta  * kmx61_set_mode() - set KMX61 device operating mode
23620ffac27SDaniel Baluta  * @data - kmx61 device private data pointer
23720ffac27SDaniel Baluta  * @mode - bitmask, indicating operating mode for @device
23820ffac27SDaniel Baluta  * @device - bitmask, indicating device for which @mode needs to be set
23920ffac27SDaniel Baluta  * @update - update stby bits stored in device's private  @data
24020ffac27SDaniel Baluta  *
24120ffac27SDaniel Baluta  * For each sensor (accelerometer/magnetometer) there are two operating modes
24220ffac27SDaniel Baluta  * STANDBY and OPERATION. Neither accel nor magn can be disabled independently
24320ffac27SDaniel Baluta  * if they are both enabled. Internal sensors state is saved in acc_stby and
24420ffac27SDaniel Baluta  * mag_stby members of driver's private @data.
24520ffac27SDaniel Baluta  */
24620ffac27SDaniel Baluta static int kmx61_set_mode(struct kmx61_data *data, u8 mode, u8 device,
24720ffac27SDaniel Baluta 			  bool update)
24820ffac27SDaniel Baluta {
24920ffac27SDaniel Baluta 	int ret;
25020ffac27SDaniel Baluta 	int acc_stby = -1, mag_stby = -1;
25120ffac27SDaniel Baluta 
25220ffac27SDaniel Baluta 	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_STBY);
25320ffac27SDaniel Baluta 	if (ret < 0) {
25420ffac27SDaniel Baluta 		dev_err(&data->client->dev, "Error reading reg_stby\n");
25520ffac27SDaniel Baluta 		return ret;
25620ffac27SDaniel Baluta 	}
25720ffac27SDaniel Baluta 	if (device & KMX61_ACC) {
25820ffac27SDaniel Baluta 		if (mode & KMX61_ACC_STBY_BIT) {
25920ffac27SDaniel Baluta 			ret |= KMX61_ACC_STBY_BIT;
26020ffac27SDaniel Baluta 			acc_stby = 1;
26120ffac27SDaniel Baluta 		} else {
26220ffac27SDaniel Baluta 			ret &= ~KMX61_ACC_STBY_BIT;
26320ffac27SDaniel Baluta 			acc_stby = 0;
26420ffac27SDaniel Baluta 		}
26520ffac27SDaniel Baluta 	}
26620ffac27SDaniel Baluta 
26720ffac27SDaniel Baluta 	if (device & KMX61_MAG) {
26820ffac27SDaniel Baluta 		if (mode & KMX61_MAG_STBY_BIT) {
26920ffac27SDaniel Baluta 			ret |= KMX61_MAG_STBY_BIT;
27020ffac27SDaniel Baluta 			mag_stby = 1;
27120ffac27SDaniel Baluta 		} else {
27220ffac27SDaniel Baluta 			ret &= ~KMX61_MAG_STBY_BIT;
27320ffac27SDaniel Baluta 			mag_stby = 0;
27420ffac27SDaniel Baluta 		}
27520ffac27SDaniel Baluta 	}
27620ffac27SDaniel Baluta 
27720ffac27SDaniel Baluta 	if (mode & KMX61_ACT_STBY_BIT)
27820ffac27SDaniel Baluta 		ret |= KMX61_ACT_STBY_BIT;
27920ffac27SDaniel Baluta 
28020ffac27SDaniel Baluta 	ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_STBY, ret);
28120ffac27SDaniel Baluta 	if (ret < 0) {
28220ffac27SDaniel Baluta 		dev_err(&data->client->dev, "Error writing reg_stby\n");
28320ffac27SDaniel Baluta 		return ret;
28420ffac27SDaniel Baluta 	}
28520ffac27SDaniel Baluta 
28620ffac27SDaniel Baluta 	if (acc_stby != -1 && update)
28720ffac27SDaniel Baluta 		data->acc_stby = acc_stby;
28820ffac27SDaniel Baluta 	if (mag_stby != -1 && update)
28920ffac27SDaniel Baluta 		data->mag_stby = mag_stby;
29020ffac27SDaniel Baluta 
29120ffac27SDaniel Baluta 	return 0;
29220ffac27SDaniel Baluta }
29320ffac27SDaniel Baluta 
29420ffac27SDaniel Baluta static int kmx61_get_mode(struct kmx61_data *data, u8 *mode, u8 device)
29520ffac27SDaniel Baluta {
29620ffac27SDaniel Baluta 	int ret;
29720ffac27SDaniel Baluta 
29820ffac27SDaniel Baluta 	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_STBY);
29920ffac27SDaniel Baluta 	if (ret < 0) {
30020ffac27SDaniel Baluta 		dev_err(&data->client->dev, "Error reading reg_stby\n");
30120ffac27SDaniel Baluta 		return ret;
30220ffac27SDaniel Baluta 	}
30320ffac27SDaniel Baluta 	*mode = 0;
30420ffac27SDaniel Baluta 
30520ffac27SDaniel Baluta 	if (device & KMX61_ACC) {
30620ffac27SDaniel Baluta 		if (ret & KMX61_ACC_STBY_BIT)
30720ffac27SDaniel Baluta 			*mode |= KMX61_ACC_STBY_BIT;
30820ffac27SDaniel Baluta 		else
30920ffac27SDaniel Baluta 			*mode &= ~KMX61_ACC_STBY_BIT;
31020ffac27SDaniel Baluta 	}
31120ffac27SDaniel Baluta 
31220ffac27SDaniel Baluta 	if (device & KMX61_MAG) {
31320ffac27SDaniel Baluta 		if (ret & KMX61_MAG_STBY_BIT)
31420ffac27SDaniel Baluta 			*mode |= KMX61_MAG_STBY_BIT;
31520ffac27SDaniel Baluta 		else
31620ffac27SDaniel Baluta 			*mode &= ~KMX61_MAG_STBY_BIT;
31720ffac27SDaniel Baluta 	}
31820ffac27SDaniel Baluta 
31920ffac27SDaniel Baluta 	return 0;
32020ffac27SDaniel Baluta }
32120ffac27SDaniel Baluta 
32220ffac27SDaniel Baluta static int kmx61_set_odr(struct kmx61_data *data, int val, int val2, u8 device)
32320ffac27SDaniel Baluta {
32420ffac27SDaniel Baluta 	int ret;
32520ffac27SDaniel Baluta 	u8 mode;
32620ffac27SDaniel Baluta 	int lodr_bits, odr_bits;
32720ffac27SDaniel Baluta 
32820ffac27SDaniel Baluta 	ret = kmx61_get_mode(data, &mode, KMX61_ACC | KMX61_MAG);
32920ffac27SDaniel Baluta 	if (ret < 0)
33020ffac27SDaniel Baluta 		return ret;
33120ffac27SDaniel Baluta 
33220ffac27SDaniel Baluta 	lodr_bits = kmx61_convert_freq_to_bit(val, val2);
33320ffac27SDaniel Baluta 	if (lodr_bits < 0)
33420ffac27SDaniel Baluta 		return lodr_bits;
33520ffac27SDaniel Baluta 
33620ffac27SDaniel Baluta 	/* To change ODR, accel and magn must be in STDBY */
33720ffac27SDaniel Baluta 	ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG,
33820ffac27SDaniel Baluta 			     true);
33920ffac27SDaniel Baluta 	if (ret < 0)
34020ffac27SDaniel Baluta 		return ret;
34120ffac27SDaniel Baluta 
34220ffac27SDaniel Baluta 	odr_bits = 0;
34320ffac27SDaniel Baluta 	if (device & KMX61_ACC)
34420ffac27SDaniel Baluta 		odr_bits |= lodr_bits << KMX61_ACC_ODR_SHIFT;
34520ffac27SDaniel Baluta 	if (device & KMX61_MAG)
34620ffac27SDaniel Baluta 		odr_bits |= lodr_bits << KMX61_MAG_ODR_SHIFT;
34720ffac27SDaniel Baluta 
34820ffac27SDaniel Baluta 	ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_ODCNTL,
34920ffac27SDaniel Baluta 					odr_bits);
35020ffac27SDaniel Baluta 	if (ret < 0)
35120ffac27SDaniel Baluta 		return ret;
35220ffac27SDaniel Baluta 
35320ffac27SDaniel Baluta 	return kmx61_set_mode(data, mode, KMX61_ACC | KMX61_MAG, true);
35420ffac27SDaniel Baluta }
35520ffac27SDaniel Baluta 
35620ffac27SDaniel Baluta static int kmx61_get_odr(struct kmx61_data *data, int *val, int *val2,
35720ffac27SDaniel Baluta 			 u8 device)
35820ffac27SDaniel Baluta {	int i;
35920ffac27SDaniel Baluta 	u8 lodr_bits;
36020ffac27SDaniel Baluta 
36120ffac27SDaniel Baluta 	if (device & KMX61_ACC)
36220ffac27SDaniel Baluta 		lodr_bits = (data->odr_bits >> KMX61_ACC_ODR_SHIFT) &
36320ffac27SDaniel Baluta 			     KMX61_ACC_ODR_MASK;
36420ffac27SDaniel Baluta 	else if (device & KMX61_MAG)
36520ffac27SDaniel Baluta 		lodr_bits = (data->odr_bits >> KMX61_MAG_ODR_SHIFT) &
36620ffac27SDaniel Baluta 			     KMX61_MAG_ODR_MASK;
36720ffac27SDaniel Baluta 	else
36820ffac27SDaniel Baluta 		return -EINVAL;
36920ffac27SDaniel Baluta 
37020ffac27SDaniel Baluta 	for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++)
37120ffac27SDaniel Baluta 		if (lodr_bits == kmx61_samp_freq_table[i].odr_bits) {
37220ffac27SDaniel Baluta 			*val = kmx61_samp_freq_table[i].val;
37320ffac27SDaniel Baluta 			*val2 = kmx61_samp_freq_table[i].val2;
37420ffac27SDaniel Baluta 			return 0;
37520ffac27SDaniel Baluta 		}
37620ffac27SDaniel Baluta 	return -EINVAL;
37720ffac27SDaniel Baluta }
37820ffac27SDaniel Baluta 
37920ffac27SDaniel Baluta static int kmx61_set_range(struct kmx61_data *data, u8 range)
38020ffac27SDaniel Baluta {
38120ffac27SDaniel Baluta 	int ret;
38220ffac27SDaniel Baluta 
38320ffac27SDaniel Baluta 	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_CTRL1);
38420ffac27SDaniel Baluta 	if (ret < 0) {
38520ffac27SDaniel Baluta 		dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
38620ffac27SDaniel Baluta 		return ret;
38720ffac27SDaniel Baluta 	}
38820ffac27SDaniel Baluta 
38920ffac27SDaniel Baluta 	ret &= ~KMX61_REG_CTRL1_GSEL_MASK;
39020ffac27SDaniel Baluta 	ret |= range & KMX61_REG_CTRL1_GSEL_MASK;
39120ffac27SDaniel Baluta 
39220ffac27SDaniel Baluta 	ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_CTRL1, ret);
39320ffac27SDaniel Baluta 	if (ret < 0) {
39420ffac27SDaniel Baluta 		dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
39520ffac27SDaniel Baluta 		return ret;
39620ffac27SDaniel Baluta 	}
39720ffac27SDaniel Baluta 
39820ffac27SDaniel Baluta 	data->range = range;
39920ffac27SDaniel Baluta 
40020ffac27SDaniel Baluta 	return 0;
40120ffac27SDaniel Baluta }
40220ffac27SDaniel Baluta 
40320ffac27SDaniel Baluta static int kmx61_set_scale(struct kmx61_data *data, u16 uscale)
40420ffac27SDaniel Baluta {
40520ffac27SDaniel Baluta 	int ret, i;
40620ffac27SDaniel Baluta 	u8  mode;
40720ffac27SDaniel Baluta 
40820ffac27SDaniel Baluta 	for (i = 0; i < ARRAY_SIZE(kmx61_uscale_table); i++) {
40920ffac27SDaniel Baluta 		if (kmx61_uscale_table[i] == uscale) {
41020ffac27SDaniel Baluta 			ret = kmx61_get_mode(data, &mode,
41120ffac27SDaniel Baluta 					     KMX61_ACC | KMX61_MAG);
41220ffac27SDaniel Baluta 			if (ret < 0)
41320ffac27SDaniel Baluta 				return ret;
41420ffac27SDaniel Baluta 
41520ffac27SDaniel Baluta 			ret = kmx61_set_mode(data, KMX61_ALL_STBY,
41620ffac27SDaniel Baluta 					     KMX61_ACC | KMX61_MAG, true);
41720ffac27SDaniel Baluta 			if (ret < 0)
41820ffac27SDaniel Baluta 				return ret;
41920ffac27SDaniel Baluta 
42020ffac27SDaniel Baluta 			ret = kmx61_set_range(data, i);
42120ffac27SDaniel Baluta 			if (ret < 0)
42220ffac27SDaniel Baluta 				return ret;
42320ffac27SDaniel Baluta 
42420ffac27SDaniel Baluta 			return  kmx61_set_mode(data, mode,
42520ffac27SDaniel Baluta 					       KMX61_ACC | KMX61_MAG, true);
42620ffac27SDaniel Baluta 		}
42720ffac27SDaniel Baluta 	}
42820ffac27SDaniel Baluta 	return -EINVAL;
42920ffac27SDaniel Baluta }
43020ffac27SDaniel Baluta 
43120ffac27SDaniel Baluta static int kmx61_chip_init(struct kmx61_data *data)
43220ffac27SDaniel Baluta {
43320ffac27SDaniel Baluta 	int ret;
43420ffac27SDaniel Baluta 
43520ffac27SDaniel Baluta 	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_WHO_AM_I);
43620ffac27SDaniel Baluta 	if (ret < 0) {
43720ffac27SDaniel Baluta 		dev_err(&data->client->dev, "Error reading who_am_i\n");
43820ffac27SDaniel Baluta 		return ret;
43920ffac27SDaniel Baluta 	}
44020ffac27SDaniel Baluta 
44120ffac27SDaniel Baluta 	if (ret != KMX61_CHIP_ID) {
44220ffac27SDaniel Baluta 		dev_err(&data->client->dev,
44320ffac27SDaniel Baluta 			"Wrong chip id, got %x expected %x\n",
44420ffac27SDaniel Baluta 			 ret, KMX61_CHIP_ID);
44520ffac27SDaniel Baluta 		return -EINVAL;
44620ffac27SDaniel Baluta 	}
44720ffac27SDaniel Baluta 
44820ffac27SDaniel Baluta 	/* set accel 12bit, 4g range */
44920ffac27SDaniel Baluta 	ret = kmx61_set_range(data, KMX61_RANGE_4G);
45020ffac27SDaniel Baluta 	if (ret < 0)
45120ffac27SDaniel Baluta 		return ret;
45220ffac27SDaniel Baluta 
45320ffac27SDaniel Baluta 	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_ODCNTL);
45420ffac27SDaniel Baluta 	if (ret < 0) {
45520ffac27SDaniel Baluta 		dev_err(&data->client->dev, "Error reading reg_odcntl\n");
45620ffac27SDaniel Baluta 		return ret;
45720ffac27SDaniel Baluta 	}
45820ffac27SDaniel Baluta 	data->odr_bits = ret;
45920ffac27SDaniel Baluta 
46020ffac27SDaniel Baluta 	/* set acc/magn to OPERATION mode */
46120ffac27SDaniel Baluta 	ret = kmx61_set_mode(data, 0, KMX61_ACC | KMX61_MAG, true);
46220ffac27SDaniel Baluta 	if (ret < 0)
46320ffac27SDaniel Baluta 		return ret;
46420ffac27SDaniel Baluta 
46520ffac27SDaniel Baluta 	return 0;
46620ffac27SDaniel Baluta }
46720ffac27SDaniel Baluta 
468*aff8609aSDaniel Baluta /**
469*aff8609aSDaniel Baluta  * kmx61_set_power_state() - set power state for kmx61 @device
470*aff8609aSDaniel Baluta  * @data - kmx61 device private pointer
471*aff8609aSDaniel Baluta  * @on - power state to be set for @device
472*aff8609aSDaniel Baluta  * @device - bitmask indicating device for which @on state needs to be set
473*aff8609aSDaniel Baluta  *
474*aff8609aSDaniel Baluta  * Notice that when ACC power state needs to be set to ON and MAG is in
475*aff8609aSDaniel Baluta  * OPERATION then we know that kmx61_runtime_resume was already called
476*aff8609aSDaniel Baluta  * so we must set ACC OPERATION mode here. The same happens when MAG power
477*aff8609aSDaniel Baluta  * state needs to be set to ON and ACC is in OPERATION.
478*aff8609aSDaniel Baluta  */
479*aff8609aSDaniel Baluta static int kmx61_set_power_state(struct kmx61_data *data, bool on, u8 device)
480*aff8609aSDaniel Baluta {
481*aff8609aSDaniel Baluta #ifdef CONFIG_PM_RUNTIME
482*aff8609aSDaniel Baluta 	int ret;
483*aff8609aSDaniel Baluta 
484*aff8609aSDaniel Baluta 	if (device & KMX61_ACC) {
485*aff8609aSDaniel Baluta 		if (on && !data->acc_ps && !data->mag_stby) {
486*aff8609aSDaniel Baluta 			ret = kmx61_set_mode(data, 0, KMX61_ACC, true);
487*aff8609aSDaniel Baluta 			if (ret < 0)
488*aff8609aSDaniel Baluta 				return ret;
489*aff8609aSDaniel Baluta 		}
490*aff8609aSDaniel Baluta 		data->acc_ps = on;
491*aff8609aSDaniel Baluta 	}
492*aff8609aSDaniel Baluta 	if (device & KMX61_MAG) {
493*aff8609aSDaniel Baluta 		if (on && !data->mag_ps && !data->acc_stby) {
494*aff8609aSDaniel Baluta 			ret = kmx61_set_mode(data, 0, KMX61_MAG, true);
495*aff8609aSDaniel Baluta 			if (ret < 0)
496*aff8609aSDaniel Baluta 				return ret;
497*aff8609aSDaniel Baluta 		}
498*aff8609aSDaniel Baluta 		data->mag_ps = on;
499*aff8609aSDaniel Baluta 	}
500*aff8609aSDaniel Baluta 
501*aff8609aSDaniel Baluta 	if (on) {
502*aff8609aSDaniel Baluta 		ret = pm_runtime_get_sync(&data->client->dev);
503*aff8609aSDaniel Baluta 	} else {
504*aff8609aSDaniel Baluta 		pm_runtime_mark_last_busy(&data->client->dev);
505*aff8609aSDaniel Baluta 		ret = pm_runtime_put_autosuspend(&data->client->dev);
506*aff8609aSDaniel Baluta 	}
507*aff8609aSDaniel Baluta 	if (ret < 0) {
508*aff8609aSDaniel Baluta 		dev_err(&data->client->dev,
509*aff8609aSDaniel Baluta 			"Failed: kmx61_set_power_state for %d, ret %d\n",
510*aff8609aSDaniel Baluta 			on, ret);
511*aff8609aSDaniel Baluta 		if (on)
512*aff8609aSDaniel Baluta 			pm_runtime_put_noidle(&data->client->dev);
513*aff8609aSDaniel Baluta 
514*aff8609aSDaniel Baluta 		return ret;
515*aff8609aSDaniel Baluta 	}
516*aff8609aSDaniel Baluta #endif
517*aff8609aSDaniel Baluta 	return 0;
518*aff8609aSDaniel Baluta }
519*aff8609aSDaniel Baluta 
52020ffac27SDaniel Baluta static int kmx61_read_measurement(struct kmx61_data *data, u8 base, u8 offset)
52120ffac27SDaniel Baluta {
52220ffac27SDaniel Baluta 	int ret;
52320ffac27SDaniel Baluta 	u8 reg = base + offset * 2;
52420ffac27SDaniel Baluta 
52520ffac27SDaniel Baluta 	ret = i2c_smbus_read_word_data(data->client, reg);
52620ffac27SDaniel Baluta 	if (ret < 0)
52720ffac27SDaniel Baluta 		dev_err(&data->client->dev, "failed to read reg at %x\n", reg);
52820ffac27SDaniel Baluta 
52920ffac27SDaniel Baluta 	return ret;
53020ffac27SDaniel Baluta }
53120ffac27SDaniel Baluta 
53220ffac27SDaniel Baluta static int kmx61_read_raw(struct iio_dev *indio_dev,
53320ffac27SDaniel Baluta 			  struct iio_chan_spec const *chan, int *val,
53420ffac27SDaniel Baluta 			  int *val2, long mask)
53520ffac27SDaniel Baluta {
53620ffac27SDaniel Baluta 	int ret;
53720ffac27SDaniel Baluta 	u8 base_reg;
53820ffac27SDaniel Baluta 	struct kmx61_data *data = kmx61_get_data(indio_dev);
53920ffac27SDaniel Baluta 
54020ffac27SDaniel Baluta 	switch (mask) {
54120ffac27SDaniel Baluta 	case IIO_CHAN_INFO_RAW:
54220ffac27SDaniel Baluta 		switch (chan->type) {
54320ffac27SDaniel Baluta 		case IIO_ACCEL:
54420ffac27SDaniel Baluta 			base_reg = KMX61_ACC_XOUT_L;
54520ffac27SDaniel Baluta 			break;
54620ffac27SDaniel Baluta 		case IIO_MAGN:
54720ffac27SDaniel Baluta 			base_reg = KMX61_MAG_XOUT_L;
54820ffac27SDaniel Baluta 			break;
54920ffac27SDaniel Baluta 		default:
55020ffac27SDaniel Baluta 			return -EINVAL;
55120ffac27SDaniel Baluta 		}
55220ffac27SDaniel Baluta 		mutex_lock(&data->lock);
55320ffac27SDaniel Baluta 
554*aff8609aSDaniel Baluta 		kmx61_set_power_state(data, true, chan->address);
55520ffac27SDaniel Baluta 		ret = kmx61_read_measurement(data, base_reg, chan->scan_index);
55620ffac27SDaniel Baluta 		if (ret < 0) {
557*aff8609aSDaniel Baluta 			kmx61_set_power_state(data, false, chan->address);
55820ffac27SDaniel Baluta 			mutex_unlock(&data->lock);
55920ffac27SDaniel Baluta 			return ret;
56020ffac27SDaniel Baluta 		}
56120ffac27SDaniel Baluta 		*val = sign_extend32(ret >> chan->scan_type.shift,
56220ffac27SDaniel Baluta 				     chan->scan_type.realbits - 1);
563*aff8609aSDaniel Baluta 		kmx61_set_power_state(data, false, chan->address);
56420ffac27SDaniel Baluta 
56520ffac27SDaniel Baluta 		mutex_unlock(&data->lock);
56620ffac27SDaniel Baluta 		return IIO_VAL_INT;
56720ffac27SDaniel Baluta 	case IIO_CHAN_INFO_SCALE:
56820ffac27SDaniel Baluta 		switch (chan->type) {
56920ffac27SDaniel Baluta 		case IIO_ACCEL:
57020ffac27SDaniel Baluta 			*val = 0;
57120ffac27SDaniel Baluta 			*val2 = kmx61_uscale_table[data->range];
57220ffac27SDaniel Baluta 			return IIO_VAL_INT_PLUS_MICRO;
57320ffac27SDaniel Baluta 		case IIO_MAGN:
57420ffac27SDaniel Baluta 			/* 14 bits res, 1465 microGauss per magn count */
57520ffac27SDaniel Baluta 			*val = 0;
57620ffac27SDaniel Baluta 			*val2 = 1465;
57720ffac27SDaniel Baluta 			return IIO_VAL_INT_PLUS_MICRO;
57820ffac27SDaniel Baluta 		default:
57920ffac27SDaniel Baluta 			return -EINVAL;
58020ffac27SDaniel Baluta 		}
58120ffac27SDaniel Baluta 	case IIO_CHAN_INFO_SAMP_FREQ:
58220ffac27SDaniel Baluta 		if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN)
58320ffac27SDaniel Baluta 			return -EINVAL;
58420ffac27SDaniel Baluta 
58520ffac27SDaniel Baluta 		mutex_lock(&data->lock);
58620ffac27SDaniel Baluta 		ret = kmx61_get_odr(data, val, val2, chan->address);
58720ffac27SDaniel Baluta 		mutex_unlock(&data->lock);
58820ffac27SDaniel Baluta 		if (ret)
58920ffac27SDaniel Baluta 			return -EINVAL;
59020ffac27SDaniel Baluta 		return IIO_VAL_INT_PLUS_MICRO;
59120ffac27SDaniel Baluta 	}
59220ffac27SDaniel Baluta 	return -EINVAL;
59320ffac27SDaniel Baluta }
59420ffac27SDaniel Baluta 
59520ffac27SDaniel Baluta static int kmx61_write_raw(struct iio_dev *indio_dev,
59620ffac27SDaniel Baluta 			   struct iio_chan_spec const *chan, int val,
59720ffac27SDaniel Baluta 			   int val2, long mask)
59820ffac27SDaniel Baluta {
59920ffac27SDaniel Baluta 	int ret;
60020ffac27SDaniel Baluta 	struct kmx61_data *data = kmx61_get_data(indio_dev);
60120ffac27SDaniel Baluta 
60220ffac27SDaniel Baluta 	switch (mask) {
60320ffac27SDaniel Baluta 	case IIO_CHAN_INFO_SAMP_FREQ:
60420ffac27SDaniel Baluta 		if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN)
60520ffac27SDaniel Baluta 			return -EINVAL;
60620ffac27SDaniel Baluta 
60720ffac27SDaniel Baluta 		mutex_lock(&data->lock);
60820ffac27SDaniel Baluta 		ret = kmx61_set_odr(data, val, val2, chan->address);
60920ffac27SDaniel Baluta 		mutex_unlock(&data->lock);
61020ffac27SDaniel Baluta 		return ret;
61120ffac27SDaniel Baluta 	case IIO_CHAN_INFO_SCALE:
61220ffac27SDaniel Baluta 		switch (chan->type) {
61320ffac27SDaniel Baluta 		case IIO_ACCEL:
61420ffac27SDaniel Baluta 			if (val != 0)
61520ffac27SDaniel Baluta 				return -EINVAL;
61620ffac27SDaniel Baluta 			mutex_lock(&data->lock);
61720ffac27SDaniel Baluta 			ret = kmx61_set_scale(data, val2);
61820ffac27SDaniel Baluta 			mutex_unlock(&data->lock);
61920ffac27SDaniel Baluta 			return ret;
62020ffac27SDaniel Baluta 		default:
62120ffac27SDaniel Baluta 			return -EINVAL;
62220ffac27SDaniel Baluta 		}
62320ffac27SDaniel Baluta 	default:
62420ffac27SDaniel Baluta 		return -EINVAL;
62520ffac27SDaniel Baluta 	}
62620ffac27SDaniel Baluta }
62720ffac27SDaniel Baluta 
62820ffac27SDaniel Baluta static const struct iio_info kmx61_acc_info = {
62920ffac27SDaniel Baluta 	.driver_module		= THIS_MODULE,
63020ffac27SDaniel Baluta 	.read_raw		= kmx61_read_raw,
63120ffac27SDaniel Baluta 	.write_raw		= kmx61_write_raw,
63220ffac27SDaniel Baluta 	.attrs			= &kmx61_acc_attribute_group,
63320ffac27SDaniel Baluta };
63420ffac27SDaniel Baluta 
63520ffac27SDaniel Baluta static const struct iio_info kmx61_mag_info = {
63620ffac27SDaniel Baluta 	.driver_module		= THIS_MODULE,
63720ffac27SDaniel Baluta 	.read_raw		= kmx61_read_raw,
63820ffac27SDaniel Baluta 	.write_raw		= kmx61_write_raw,
63920ffac27SDaniel Baluta 	.attrs			= &kmx61_mag_attribute_group,
64020ffac27SDaniel Baluta };
64120ffac27SDaniel Baluta 
642b25862c5SDaniel Baluta static const char *kmx61_match_acpi_device(struct device *dev)
643b25862c5SDaniel Baluta {
644b25862c5SDaniel Baluta 	const struct acpi_device_id *id;
645b25862c5SDaniel Baluta 
646b25862c5SDaniel Baluta 	id = acpi_match_device(dev->driver->acpi_match_table, dev);
647b25862c5SDaniel Baluta 	if (!id)
648b25862c5SDaniel Baluta 		return NULL;
649b25862c5SDaniel Baluta 	return dev_name(dev);
650b25862c5SDaniel Baluta }
651b25862c5SDaniel Baluta 
652b25862c5SDaniel Baluta static int kmx61_gpio_probe(struct i2c_client *client, struct kmx61_data *data)
653b25862c5SDaniel Baluta {
654b25862c5SDaniel Baluta 	struct device *dev;
655b25862c5SDaniel Baluta 	struct gpio_desc *gpio;
656b25862c5SDaniel Baluta 	int ret;
657b25862c5SDaniel Baluta 
658b25862c5SDaniel Baluta 	if (!client)
659b25862c5SDaniel Baluta 		return -EINVAL;
660b25862c5SDaniel Baluta 
661b25862c5SDaniel Baluta 	dev = &client->dev;
662b25862c5SDaniel Baluta 
663b25862c5SDaniel Baluta 	/* data ready gpio interrupt pin */
664b25862c5SDaniel Baluta 	gpio = devm_gpiod_get_index(dev, KMX61_GPIO_NAME, 0);
665b25862c5SDaniel Baluta 	if (IS_ERR(gpio)) {
666b25862c5SDaniel Baluta 		dev_err(dev, "acpi gpio get index failed\n");
667b25862c5SDaniel Baluta 		return PTR_ERR(gpio);
668b25862c5SDaniel Baluta 	}
669b25862c5SDaniel Baluta 
670b25862c5SDaniel Baluta 	ret = gpiod_direction_input(gpio);
671b25862c5SDaniel Baluta 	if (ret)
672b25862c5SDaniel Baluta 		return ret;
673b25862c5SDaniel Baluta 
674b25862c5SDaniel Baluta 	ret = gpiod_to_irq(gpio);
675b25862c5SDaniel Baluta 
676b25862c5SDaniel Baluta 	dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
677b25862c5SDaniel Baluta 	return ret;
678b25862c5SDaniel Baluta }
679b25862c5SDaniel Baluta 
68020ffac27SDaniel Baluta static struct iio_dev *kmx61_indiodev_setup(struct kmx61_data *data,
68120ffac27SDaniel Baluta 					    const struct iio_info *info,
68220ffac27SDaniel Baluta 					    const struct iio_chan_spec *chan,
68320ffac27SDaniel Baluta 					    int num_channels,
68420ffac27SDaniel Baluta 					    const char *name)
68520ffac27SDaniel Baluta {
68620ffac27SDaniel Baluta 	struct iio_dev *indio_dev;
68720ffac27SDaniel Baluta 
68820ffac27SDaniel Baluta 	indio_dev = devm_iio_device_alloc(&data->client->dev, sizeof(data));
68920ffac27SDaniel Baluta 	if (!indio_dev)
69020ffac27SDaniel Baluta 		return ERR_PTR(-ENOMEM);
69120ffac27SDaniel Baluta 
69220ffac27SDaniel Baluta 	kmx61_set_data(indio_dev, data);
69320ffac27SDaniel Baluta 
69420ffac27SDaniel Baluta 	indio_dev->dev.parent = &data->client->dev;
69520ffac27SDaniel Baluta 	indio_dev->channels = chan;
69620ffac27SDaniel Baluta 	indio_dev->num_channels = num_channels;
69720ffac27SDaniel Baluta 	indio_dev->name = name;
69820ffac27SDaniel Baluta 	indio_dev->modes = INDIO_DIRECT_MODE;
69920ffac27SDaniel Baluta 	indio_dev->info = info;
70020ffac27SDaniel Baluta 
70120ffac27SDaniel Baluta 	return indio_dev;
70220ffac27SDaniel Baluta }
70320ffac27SDaniel Baluta 
70420ffac27SDaniel Baluta static int kmx61_probe(struct i2c_client *client,
70520ffac27SDaniel Baluta 		       const struct i2c_device_id *id)
70620ffac27SDaniel Baluta {
70720ffac27SDaniel Baluta 	int ret;
70820ffac27SDaniel Baluta 	struct kmx61_data *data;
70920ffac27SDaniel Baluta 	const char *name = NULL;
71020ffac27SDaniel Baluta 
71120ffac27SDaniel Baluta 	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
71220ffac27SDaniel Baluta 	if (!data)
71320ffac27SDaniel Baluta 		return -ENOMEM;
71420ffac27SDaniel Baluta 
71520ffac27SDaniel Baluta 	i2c_set_clientdata(client, data);
71620ffac27SDaniel Baluta 	data->client = client;
71720ffac27SDaniel Baluta 
71820ffac27SDaniel Baluta 	mutex_init(&data->lock);
71920ffac27SDaniel Baluta 
720b25862c5SDaniel Baluta 	if (id)
721b25862c5SDaniel Baluta 		name = id->name;
722b25862c5SDaniel Baluta 	else if (ACPI_HANDLE(&client->dev))
723b25862c5SDaniel Baluta 		name = kmx61_match_acpi_device(&client->dev);
724b25862c5SDaniel Baluta 	else
725b25862c5SDaniel Baluta 		return -ENODEV;
726b25862c5SDaniel Baluta 
72720ffac27SDaniel Baluta 	data->acc_indio_dev =
72820ffac27SDaniel Baluta 		kmx61_indiodev_setup(data, &kmx61_acc_info,
72920ffac27SDaniel Baluta 				     kmx61_acc_channels,
73020ffac27SDaniel Baluta 				     ARRAY_SIZE(kmx61_acc_channels),
73120ffac27SDaniel Baluta 				     name);
73220ffac27SDaniel Baluta 	if (IS_ERR(data->acc_indio_dev))
73320ffac27SDaniel Baluta 		return PTR_ERR(data->acc_indio_dev);
73420ffac27SDaniel Baluta 
73520ffac27SDaniel Baluta 	data->mag_indio_dev =
73620ffac27SDaniel Baluta 		kmx61_indiodev_setup(data, &kmx61_mag_info,
73720ffac27SDaniel Baluta 				     kmx61_mag_channels,
73820ffac27SDaniel Baluta 				     ARRAY_SIZE(kmx61_mag_channels),
73920ffac27SDaniel Baluta 				     name);
74020ffac27SDaniel Baluta 	if (IS_ERR(data->mag_indio_dev))
74120ffac27SDaniel Baluta 		return PTR_ERR(data->mag_indio_dev);
74220ffac27SDaniel Baluta 
74320ffac27SDaniel Baluta 	ret = kmx61_chip_init(data);
74420ffac27SDaniel Baluta 	if (ret < 0)
74520ffac27SDaniel Baluta 		return ret;
74620ffac27SDaniel Baluta 
747b25862c5SDaniel Baluta 	if (client->irq < 0)
748b25862c5SDaniel Baluta 		client->irq = kmx61_gpio_probe(client, data);
749b25862c5SDaniel Baluta 
75020ffac27SDaniel Baluta 	ret = iio_device_register(data->acc_indio_dev);
75120ffac27SDaniel Baluta 	if (ret < 0) {
75220ffac27SDaniel Baluta 		dev_err(&client->dev, "Failed to register acc iio device\n");
75320ffac27SDaniel Baluta 		goto err_chip_uninit;
75420ffac27SDaniel Baluta 	}
75520ffac27SDaniel Baluta 
75620ffac27SDaniel Baluta 	ret = iio_device_register(data->mag_indio_dev);
75720ffac27SDaniel Baluta 	if (ret < 0) {
75820ffac27SDaniel Baluta 		dev_err(&client->dev, "Failed to register mag iio device\n");
759*aff8609aSDaniel Baluta 		goto err_iio_unregister_acc;
76020ffac27SDaniel Baluta 	}
76120ffac27SDaniel Baluta 
762*aff8609aSDaniel Baluta 	ret = pm_runtime_set_active(&client->dev);
763*aff8609aSDaniel Baluta 	if (ret < 0)
764*aff8609aSDaniel Baluta 		goto err_iio_unregister_mag;
765*aff8609aSDaniel Baluta 
766*aff8609aSDaniel Baluta 	pm_runtime_enable(&client->dev);
767*aff8609aSDaniel Baluta 	pm_runtime_set_autosuspend_delay(&client->dev, KMX61_SLEEP_DELAY_MS);
768*aff8609aSDaniel Baluta 	pm_runtime_use_autosuspend(&client->dev);
769*aff8609aSDaniel Baluta 
77020ffac27SDaniel Baluta 	return 0;
77120ffac27SDaniel Baluta 
772*aff8609aSDaniel Baluta err_iio_unregister_mag:
773*aff8609aSDaniel Baluta 	iio_device_unregister(data->mag_indio_dev);
774*aff8609aSDaniel Baluta err_iio_unregister_acc:
77520ffac27SDaniel Baluta 	iio_device_unregister(data->acc_indio_dev);
77620ffac27SDaniel Baluta err_chip_uninit:
77720ffac27SDaniel Baluta 	kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
77820ffac27SDaniel Baluta 	return ret;
77920ffac27SDaniel Baluta }
78020ffac27SDaniel Baluta 
78120ffac27SDaniel Baluta static int kmx61_remove(struct i2c_client *client)
78220ffac27SDaniel Baluta {
78320ffac27SDaniel Baluta 	struct kmx61_data *data = i2c_get_clientdata(client);
78420ffac27SDaniel Baluta 
785*aff8609aSDaniel Baluta 	pm_runtime_disable(&client->dev);
786*aff8609aSDaniel Baluta 	pm_runtime_set_suspended(&client->dev);
787*aff8609aSDaniel Baluta 	pm_runtime_put_noidle(&client->dev);
788*aff8609aSDaniel Baluta 
78920ffac27SDaniel Baluta 	iio_device_unregister(data->acc_indio_dev);
79020ffac27SDaniel Baluta 	iio_device_unregister(data->mag_indio_dev);
79120ffac27SDaniel Baluta 
79220ffac27SDaniel Baluta 	mutex_lock(&data->lock);
79320ffac27SDaniel Baluta 	kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
79420ffac27SDaniel Baluta 	mutex_unlock(&data->lock);
79520ffac27SDaniel Baluta 
79620ffac27SDaniel Baluta 	return 0;
79720ffac27SDaniel Baluta }
79820ffac27SDaniel Baluta 
799*aff8609aSDaniel Baluta 
800*aff8609aSDaniel Baluta #ifdef CONFIG_PM_RUNTIME
801*aff8609aSDaniel Baluta static int kmx61_runtime_suspend(struct device *dev)
802*aff8609aSDaniel Baluta {
803*aff8609aSDaniel Baluta 	struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev));
804*aff8609aSDaniel Baluta 	int ret;
805*aff8609aSDaniel Baluta 
806*aff8609aSDaniel Baluta 	mutex_lock(&data->lock);
807*aff8609aSDaniel Baluta 	ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
808*aff8609aSDaniel Baluta 	mutex_unlock(&data->lock);
809*aff8609aSDaniel Baluta 
810*aff8609aSDaniel Baluta 	return ret;
811*aff8609aSDaniel Baluta }
812*aff8609aSDaniel Baluta 
813*aff8609aSDaniel Baluta static int kmx61_runtime_resume(struct device *dev)
814*aff8609aSDaniel Baluta {
815*aff8609aSDaniel Baluta 	struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev));
816*aff8609aSDaniel Baluta 	u8 stby = 0;
817*aff8609aSDaniel Baluta 
818*aff8609aSDaniel Baluta 	if (!data->acc_ps)
819*aff8609aSDaniel Baluta 		stby |= KMX61_ACC_STBY_BIT;
820*aff8609aSDaniel Baluta 	if (!data->mag_ps)
821*aff8609aSDaniel Baluta 		stby |= KMX61_MAG_STBY_BIT;
822*aff8609aSDaniel Baluta 
823*aff8609aSDaniel Baluta 	return kmx61_set_mode(data, stby, KMX61_ACC | KMX61_MAG, true);
824*aff8609aSDaniel Baluta }
825*aff8609aSDaniel Baluta #endif
826*aff8609aSDaniel Baluta 
827*aff8609aSDaniel Baluta static const struct dev_pm_ops kmx61_pm_ops = {
828*aff8609aSDaniel Baluta 	SET_RUNTIME_PM_OPS(kmx61_runtime_suspend, kmx61_runtime_resume, NULL)
829*aff8609aSDaniel Baluta };
830*aff8609aSDaniel Baluta 
831b25862c5SDaniel Baluta static const struct acpi_device_id kmx61_acpi_match[] = {
832b25862c5SDaniel Baluta 	{"KMX61021", 0},
833b25862c5SDaniel Baluta 	{}
834b25862c5SDaniel Baluta };
835b25862c5SDaniel Baluta 
836b25862c5SDaniel Baluta MODULE_DEVICE_TABLE(acpi, kmx61_acpi_match);
837b25862c5SDaniel Baluta 
83820ffac27SDaniel Baluta static const struct i2c_device_id kmx61_id[] = {
83920ffac27SDaniel Baluta 	{"kmx611021", 0},
84020ffac27SDaniel Baluta 	{}
84120ffac27SDaniel Baluta };
84220ffac27SDaniel Baluta 
84320ffac27SDaniel Baluta MODULE_DEVICE_TABLE(i2c, kmx61_id);
84420ffac27SDaniel Baluta 
84520ffac27SDaniel Baluta static struct i2c_driver kmx61_driver = {
84620ffac27SDaniel Baluta 	.driver = {
84720ffac27SDaniel Baluta 		.name = KMX61_DRV_NAME,
848b25862c5SDaniel Baluta 		.acpi_match_table = ACPI_PTR(kmx61_acpi_match),
849*aff8609aSDaniel Baluta 		.pm = &kmx61_pm_ops,
85020ffac27SDaniel Baluta 	},
85120ffac27SDaniel Baluta 	.probe		= kmx61_probe,
85220ffac27SDaniel Baluta 	.remove		= kmx61_remove,
85320ffac27SDaniel Baluta 	.id_table	= kmx61_id,
85420ffac27SDaniel Baluta };
85520ffac27SDaniel Baluta 
85620ffac27SDaniel Baluta module_i2c_driver(kmx61_driver);
85720ffac27SDaniel Baluta 
85820ffac27SDaniel Baluta MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
85920ffac27SDaniel Baluta MODULE_DESCRIPTION("KMX61 accelerometer/magnetometer driver");
86020ffac27SDaniel Baluta MODULE_LICENSE("GPL v2");
861