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