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