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