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> 16*b25862c5SDaniel Baluta #include <linux/acpi.h> 17*b25862c5SDaniel Baluta #include <linux/gpio/consumer.h> 1820ffac27SDaniel Baluta #include <linux/iio/iio.h> 1920ffac27SDaniel Baluta #include <linux/iio/sysfs.h> 2020ffac27SDaniel Baluta 2120ffac27SDaniel Baluta #define KMX61_DRV_NAME "kmx61" 22*b25862c5SDaniel Baluta #define KMX61_GPIO_NAME "kmx61_int" 2320ffac27SDaniel Baluta 2420ffac27SDaniel Baluta #define KMX61_REG_WHO_AM_I 0x00 2520ffac27SDaniel Baluta 2620ffac27SDaniel Baluta /* 2720ffac27SDaniel Baluta * three 16-bit accelerometer output registers for X/Y/Z axis 2820ffac27SDaniel Baluta * we use only XOUT_L as a base register, all other addresses 2920ffac27SDaniel Baluta * can be obtained by applying an offset and are provided here 3020ffac27SDaniel Baluta * only for clarity. 3120ffac27SDaniel Baluta */ 3220ffac27SDaniel Baluta #define KMX61_ACC_XOUT_L 0x0A 3320ffac27SDaniel Baluta #define KMX61_ACC_XOUT_H 0x0B 3420ffac27SDaniel Baluta #define KMX61_ACC_YOUT_L 0x0C 3520ffac27SDaniel Baluta #define KMX61_ACC_YOUT_H 0x0D 3620ffac27SDaniel Baluta #define KMX61_ACC_ZOUT_L 0x0E 3720ffac27SDaniel Baluta #define KMX61_ACC_ZOUT_H 0x0F 3820ffac27SDaniel Baluta 3920ffac27SDaniel Baluta /* 4020ffac27SDaniel Baluta * one 16-bit temperature output register 4120ffac27SDaniel Baluta */ 4220ffac27SDaniel Baluta #define KMX61_TEMP_L 0x10 4320ffac27SDaniel Baluta #define KMX61_TEMP_H 0x11 4420ffac27SDaniel Baluta 4520ffac27SDaniel Baluta /* 4620ffac27SDaniel Baluta * three 16-bit magnetometer output registers for X/Y/Z axis 4720ffac27SDaniel Baluta */ 4820ffac27SDaniel Baluta #define KMX61_MAG_XOUT_L 0x12 4920ffac27SDaniel Baluta #define KMX61_MAG_XOUT_H 0x13 5020ffac27SDaniel Baluta #define KMX61_MAG_YOUT_L 0x14 5120ffac27SDaniel Baluta #define KMX61_MAG_YOUT_H 0x15 5220ffac27SDaniel Baluta #define KMX61_MAG_ZOUT_L 0x16 5320ffac27SDaniel Baluta #define KMX61_MAG_ZOUT_H 0x17 5420ffac27SDaniel Baluta 5520ffac27SDaniel Baluta #define KMX61_REG_STBY 0x29 5620ffac27SDaniel Baluta #define KMX61_REG_CTRL1 0x2A 5720ffac27SDaniel Baluta #define KMX61_REG_ODCNTL 0x2C 5820ffac27SDaniel Baluta 5920ffac27SDaniel Baluta #define KMX61_ACC_STBY_BIT BIT(0) 6020ffac27SDaniel Baluta #define KMX61_MAG_STBY_BIT BIT(1) 6120ffac27SDaniel Baluta #define KMX61_ACT_STBY_BIT BIT(7) 6220ffac27SDaniel Baluta 6320ffac27SDaniel Baluta #define KMX61_ALL_STBY (KMX61_ACC_STBY_BIT | KMX61_MAG_STBY_BIT) 6420ffac27SDaniel Baluta 6520ffac27SDaniel Baluta #define KMX61_REG_CTRL1_GSEL_MASK 0x03 6620ffac27SDaniel Baluta 6720ffac27SDaniel Baluta #define KMX61_ACC_ODR_SHIFT 0 6820ffac27SDaniel Baluta #define KMX61_MAG_ODR_SHIFT 4 6920ffac27SDaniel Baluta #define KMX61_ACC_ODR_MASK 0x0F 7020ffac27SDaniel Baluta #define KMX61_MAG_ODR_MASK 0xF0 7120ffac27SDaniel Baluta 7220ffac27SDaniel Baluta #define KMX61_CHIP_ID 0x12 7320ffac27SDaniel Baluta 7420ffac27SDaniel Baluta /* KMX61 devices */ 7520ffac27SDaniel Baluta #define KMX61_ACC 0x01 7620ffac27SDaniel Baluta #define KMX61_MAG 0x02 7720ffac27SDaniel Baluta 7820ffac27SDaniel Baluta struct kmx61_data { 7920ffac27SDaniel Baluta struct i2c_client *client; 8020ffac27SDaniel Baluta 8120ffac27SDaniel Baluta /* serialize access to non-atomic ops, e.g set_mode */ 8220ffac27SDaniel Baluta struct mutex lock; 8320ffac27SDaniel Baluta 8420ffac27SDaniel Baluta /* standby state */ 8520ffac27SDaniel Baluta bool acc_stby; 8620ffac27SDaniel Baluta bool mag_stby; 8720ffac27SDaniel Baluta 8820ffac27SDaniel Baluta /* config bits */ 8920ffac27SDaniel Baluta u8 range; 9020ffac27SDaniel Baluta u8 odr_bits; 9120ffac27SDaniel Baluta 9220ffac27SDaniel Baluta /* accelerometer specific data */ 9320ffac27SDaniel Baluta struct iio_dev *acc_indio_dev; 9420ffac27SDaniel Baluta 9520ffac27SDaniel Baluta /* magnetometer specific data */ 9620ffac27SDaniel Baluta struct iio_dev *mag_indio_dev; 9720ffac27SDaniel Baluta }; 9820ffac27SDaniel Baluta 9920ffac27SDaniel Baluta enum kmx61_range { 10020ffac27SDaniel Baluta KMX61_RANGE_2G, 10120ffac27SDaniel Baluta KMX61_RANGE_4G, 10220ffac27SDaniel Baluta KMX61_RANGE_8G, 10320ffac27SDaniel Baluta }; 10420ffac27SDaniel Baluta 10520ffac27SDaniel Baluta enum kmx61_axis { 10620ffac27SDaniel Baluta KMX61_AXIS_X, 10720ffac27SDaniel Baluta KMX61_AXIS_Y, 10820ffac27SDaniel Baluta KMX61_AXIS_Z, 10920ffac27SDaniel Baluta }; 11020ffac27SDaniel Baluta 11120ffac27SDaniel Baluta static const u16 kmx61_uscale_table[] = {9582, 19163, 38326}; 11220ffac27SDaniel Baluta 11320ffac27SDaniel Baluta static const struct { 11420ffac27SDaniel Baluta int val; 11520ffac27SDaniel Baluta int val2; 11620ffac27SDaniel Baluta u8 odr_bits; 11720ffac27SDaniel Baluta } kmx61_samp_freq_table[] = { {12, 500000, 0x00}, 11820ffac27SDaniel Baluta {25, 0, 0x01}, 11920ffac27SDaniel Baluta {50, 0, 0x02}, 12020ffac27SDaniel Baluta {100, 0, 0x03}, 12120ffac27SDaniel Baluta {200, 0, 0x04}, 12220ffac27SDaniel Baluta {400, 0, 0x05}, 12320ffac27SDaniel Baluta {800, 0, 0x06}, 12420ffac27SDaniel Baluta {1600, 0, 0x07}, 12520ffac27SDaniel Baluta {0, 781000, 0x08}, 12620ffac27SDaniel Baluta {1, 563000, 0x09}, 12720ffac27SDaniel Baluta {3, 125000, 0x0A}, 12820ffac27SDaniel Baluta {6, 250000, 0x0B} }; 12920ffac27SDaniel Baluta 13020ffac27SDaniel Baluta static IIO_CONST_ATTR(accel_scale_available, "0.009582 0.019163 0.038326"); 13120ffac27SDaniel Baluta static IIO_CONST_ATTR(magn_scale_available, "0.001465"); 13220ffac27SDaniel Baluta static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( 13320ffac27SDaniel Baluta "0.781000 1.563000 3.125000 6.250000 12.500000 25 50 100 200 400 800"); 13420ffac27SDaniel Baluta 13520ffac27SDaniel Baluta static struct attribute *kmx61_acc_attributes[] = { 13620ffac27SDaniel Baluta &iio_const_attr_accel_scale_available.dev_attr.attr, 13720ffac27SDaniel Baluta &iio_const_attr_sampling_frequency_available.dev_attr.attr, 13820ffac27SDaniel Baluta NULL, 13920ffac27SDaniel Baluta }; 14020ffac27SDaniel Baluta 14120ffac27SDaniel Baluta static struct attribute *kmx61_mag_attributes[] = { 14220ffac27SDaniel Baluta &iio_const_attr_magn_scale_available.dev_attr.attr, 14320ffac27SDaniel Baluta &iio_const_attr_sampling_frequency_available.dev_attr.attr, 14420ffac27SDaniel Baluta NULL, 14520ffac27SDaniel Baluta }; 14620ffac27SDaniel Baluta 14720ffac27SDaniel Baluta static const struct attribute_group kmx61_acc_attribute_group = { 14820ffac27SDaniel Baluta .attrs = kmx61_acc_attributes, 14920ffac27SDaniel Baluta }; 15020ffac27SDaniel Baluta 15120ffac27SDaniel Baluta static const struct attribute_group kmx61_mag_attribute_group = { 15220ffac27SDaniel Baluta .attrs = kmx61_mag_attributes, 15320ffac27SDaniel Baluta }; 15420ffac27SDaniel Baluta 15520ffac27SDaniel Baluta #define KMX61_ACC_CHAN(_axis) { \ 15620ffac27SDaniel Baluta .type = IIO_ACCEL, \ 15720ffac27SDaniel Baluta .modified = 1, \ 15820ffac27SDaniel Baluta .channel2 = IIO_MOD_ ## _axis, \ 15920ffac27SDaniel Baluta .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 16020ffac27SDaniel Baluta .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 16120ffac27SDaniel Baluta BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 16220ffac27SDaniel Baluta .address = KMX61_ACC, \ 16320ffac27SDaniel Baluta .scan_index = KMX61_AXIS_ ## _axis, \ 16420ffac27SDaniel Baluta .scan_type = { \ 16520ffac27SDaniel Baluta .sign = 's', \ 16620ffac27SDaniel Baluta .realbits = 12, \ 16720ffac27SDaniel Baluta .storagebits = 16, \ 16820ffac27SDaniel Baluta .shift = 4, \ 16920ffac27SDaniel Baluta .endianness = IIO_LE, \ 17020ffac27SDaniel Baluta }, \ 17120ffac27SDaniel Baluta } 17220ffac27SDaniel Baluta 17320ffac27SDaniel Baluta #define KMX61_MAG_CHAN(_axis) { \ 17420ffac27SDaniel Baluta .type = IIO_MAGN, \ 17520ffac27SDaniel Baluta .modified = 1, \ 17620ffac27SDaniel Baluta .channel2 = IIO_MOD_ ## _axis, \ 17720ffac27SDaniel Baluta .address = KMX61_MAG, \ 17820ffac27SDaniel Baluta .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 17920ffac27SDaniel Baluta .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 18020ffac27SDaniel Baluta BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 18120ffac27SDaniel Baluta .scan_index = KMX61_AXIS_ ## _axis, \ 18220ffac27SDaniel Baluta .scan_type = { \ 18320ffac27SDaniel Baluta .sign = 's', \ 18420ffac27SDaniel Baluta .realbits = 14, \ 18520ffac27SDaniel Baluta .storagebits = 16, \ 18620ffac27SDaniel Baluta .shift = 2, \ 18720ffac27SDaniel Baluta .endianness = IIO_LE, \ 18820ffac27SDaniel Baluta }, \ 18920ffac27SDaniel Baluta } 19020ffac27SDaniel Baluta 19120ffac27SDaniel Baluta static const struct iio_chan_spec kmx61_acc_channels[] = { 19220ffac27SDaniel Baluta KMX61_ACC_CHAN(X), 19320ffac27SDaniel Baluta KMX61_ACC_CHAN(Y), 19420ffac27SDaniel Baluta KMX61_ACC_CHAN(Z), 19520ffac27SDaniel Baluta }; 19620ffac27SDaniel Baluta 19720ffac27SDaniel Baluta static const struct iio_chan_spec kmx61_mag_channels[] = { 19820ffac27SDaniel Baluta KMX61_MAG_CHAN(X), 19920ffac27SDaniel Baluta KMX61_MAG_CHAN(Y), 20020ffac27SDaniel Baluta KMX61_MAG_CHAN(Z), 20120ffac27SDaniel Baluta }; 20220ffac27SDaniel Baluta 20320ffac27SDaniel Baluta static void kmx61_set_data(struct iio_dev *indio_dev, struct kmx61_data *data) 20420ffac27SDaniel Baluta { 20520ffac27SDaniel Baluta struct kmx61_data **priv = iio_priv(indio_dev); 20620ffac27SDaniel Baluta 20720ffac27SDaniel Baluta *priv = data; 20820ffac27SDaniel Baluta } 20920ffac27SDaniel Baluta 21020ffac27SDaniel Baluta static struct kmx61_data *kmx61_get_data(struct iio_dev *indio_dev) 21120ffac27SDaniel Baluta { 21220ffac27SDaniel Baluta return *(struct kmx61_data **)iio_priv(indio_dev); 21320ffac27SDaniel Baluta } 21420ffac27SDaniel Baluta 21520ffac27SDaniel Baluta static int kmx61_convert_freq_to_bit(int val, int val2) 21620ffac27SDaniel Baluta { 21720ffac27SDaniel Baluta int i; 21820ffac27SDaniel Baluta 21920ffac27SDaniel Baluta for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++) 22020ffac27SDaniel Baluta if (val == kmx61_samp_freq_table[i].val && 22120ffac27SDaniel Baluta val2 == kmx61_samp_freq_table[i].val2) 22220ffac27SDaniel Baluta return kmx61_samp_freq_table[i].odr_bits; 22320ffac27SDaniel Baluta return -EINVAL; 22420ffac27SDaniel Baluta } 22520ffac27SDaniel Baluta 22620ffac27SDaniel Baluta /** 22720ffac27SDaniel Baluta * kmx61_set_mode() - set KMX61 device operating mode 22820ffac27SDaniel Baluta * @data - kmx61 device private data pointer 22920ffac27SDaniel Baluta * @mode - bitmask, indicating operating mode for @device 23020ffac27SDaniel Baluta * @device - bitmask, indicating device for which @mode needs to be set 23120ffac27SDaniel Baluta * @update - update stby bits stored in device's private @data 23220ffac27SDaniel Baluta * 23320ffac27SDaniel Baluta * For each sensor (accelerometer/magnetometer) there are two operating modes 23420ffac27SDaniel Baluta * STANDBY and OPERATION. Neither accel nor magn can be disabled independently 23520ffac27SDaniel Baluta * if they are both enabled. Internal sensors state is saved in acc_stby and 23620ffac27SDaniel Baluta * mag_stby members of driver's private @data. 23720ffac27SDaniel Baluta */ 23820ffac27SDaniel Baluta static int kmx61_set_mode(struct kmx61_data *data, u8 mode, u8 device, 23920ffac27SDaniel Baluta bool update) 24020ffac27SDaniel Baluta { 24120ffac27SDaniel Baluta int ret; 24220ffac27SDaniel Baluta int acc_stby = -1, mag_stby = -1; 24320ffac27SDaniel Baluta 24420ffac27SDaniel Baluta ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_STBY); 24520ffac27SDaniel Baluta if (ret < 0) { 24620ffac27SDaniel Baluta dev_err(&data->client->dev, "Error reading reg_stby\n"); 24720ffac27SDaniel Baluta return ret; 24820ffac27SDaniel Baluta } 24920ffac27SDaniel Baluta if (device & KMX61_ACC) { 25020ffac27SDaniel Baluta if (mode & KMX61_ACC_STBY_BIT) { 25120ffac27SDaniel Baluta ret |= KMX61_ACC_STBY_BIT; 25220ffac27SDaniel Baluta acc_stby = 1; 25320ffac27SDaniel Baluta } else { 25420ffac27SDaniel Baluta ret &= ~KMX61_ACC_STBY_BIT; 25520ffac27SDaniel Baluta acc_stby = 0; 25620ffac27SDaniel Baluta } 25720ffac27SDaniel Baluta } 25820ffac27SDaniel Baluta 25920ffac27SDaniel Baluta if (device & KMX61_MAG) { 26020ffac27SDaniel Baluta if (mode & KMX61_MAG_STBY_BIT) { 26120ffac27SDaniel Baluta ret |= KMX61_MAG_STBY_BIT; 26220ffac27SDaniel Baluta mag_stby = 1; 26320ffac27SDaniel Baluta } else { 26420ffac27SDaniel Baluta ret &= ~KMX61_MAG_STBY_BIT; 26520ffac27SDaniel Baluta mag_stby = 0; 26620ffac27SDaniel Baluta } 26720ffac27SDaniel Baluta } 26820ffac27SDaniel Baluta 26920ffac27SDaniel Baluta if (mode & KMX61_ACT_STBY_BIT) 27020ffac27SDaniel Baluta ret |= KMX61_ACT_STBY_BIT; 27120ffac27SDaniel Baluta 27220ffac27SDaniel Baluta ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_STBY, ret); 27320ffac27SDaniel Baluta if (ret < 0) { 27420ffac27SDaniel Baluta dev_err(&data->client->dev, "Error writing reg_stby\n"); 27520ffac27SDaniel Baluta return ret; 27620ffac27SDaniel Baluta } 27720ffac27SDaniel Baluta 27820ffac27SDaniel Baluta if (acc_stby != -1 && update) 27920ffac27SDaniel Baluta data->acc_stby = acc_stby; 28020ffac27SDaniel Baluta if (mag_stby != -1 && update) 28120ffac27SDaniel Baluta data->mag_stby = mag_stby; 28220ffac27SDaniel Baluta 28320ffac27SDaniel Baluta return 0; 28420ffac27SDaniel Baluta } 28520ffac27SDaniel Baluta 28620ffac27SDaniel Baluta static int kmx61_get_mode(struct kmx61_data *data, u8 *mode, u8 device) 28720ffac27SDaniel Baluta { 28820ffac27SDaniel Baluta int ret; 28920ffac27SDaniel Baluta 29020ffac27SDaniel Baluta ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_STBY); 29120ffac27SDaniel Baluta if (ret < 0) { 29220ffac27SDaniel Baluta dev_err(&data->client->dev, "Error reading reg_stby\n"); 29320ffac27SDaniel Baluta return ret; 29420ffac27SDaniel Baluta } 29520ffac27SDaniel Baluta *mode = 0; 29620ffac27SDaniel Baluta 29720ffac27SDaniel Baluta if (device & KMX61_ACC) { 29820ffac27SDaniel Baluta if (ret & KMX61_ACC_STBY_BIT) 29920ffac27SDaniel Baluta *mode |= KMX61_ACC_STBY_BIT; 30020ffac27SDaniel Baluta else 30120ffac27SDaniel Baluta *mode &= ~KMX61_ACC_STBY_BIT; 30220ffac27SDaniel Baluta } 30320ffac27SDaniel Baluta 30420ffac27SDaniel Baluta if (device & KMX61_MAG) { 30520ffac27SDaniel Baluta if (ret & KMX61_MAG_STBY_BIT) 30620ffac27SDaniel Baluta *mode |= KMX61_MAG_STBY_BIT; 30720ffac27SDaniel Baluta else 30820ffac27SDaniel Baluta *mode &= ~KMX61_MAG_STBY_BIT; 30920ffac27SDaniel Baluta } 31020ffac27SDaniel Baluta 31120ffac27SDaniel Baluta return 0; 31220ffac27SDaniel Baluta } 31320ffac27SDaniel Baluta 31420ffac27SDaniel Baluta static int kmx61_set_odr(struct kmx61_data *data, int val, int val2, u8 device) 31520ffac27SDaniel Baluta { 31620ffac27SDaniel Baluta int ret; 31720ffac27SDaniel Baluta u8 mode; 31820ffac27SDaniel Baluta int lodr_bits, odr_bits; 31920ffac27SDaniel Baluta 32020ffac27SDaniel Baluta ret = kmx61_get_mode(data, &mode, KMX61_ACC | KMX61_MAG); 32120ffac27SDaniel Baluta if (ret < 0) 32220ffac27SDaniel Baluta return ret; 32320ffac27SDaniel Baluta 32420ffac27SDaniel Baluta lodr_bits = kmx61_convert_freq_to_bit(val, val2); 32520ffac27SDaniel Baluta if (lodr_bits < 0) 32620ffac27SDaniel Baluta return lodr_bits; 32720ffac27SDaniel Baluta 32820ffac27SDaniel Baluta /* To change ODR, accel and magn must be in STDBY */ 32920ffac27SDaniel Baluta ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, 33020ffac27SDaniel Baluta true); 33120ffac27SDaniel Baluta if (ret < 0) 33220ffac27SDaniel Baluta return ret; 33320ffac27SDaniel Baluta 33420ffac27SDaniel Baluta odr_bits = 0; 33520ffac27SDaniel Baluta if (device & KMX61_ACC) 33620ffac27SDaniel Baluta odr_bits |= lodr_bits << KMX61_ACC_ODR_SHIFT; 33720ffac27SDaniel Baluta if (device & KMX61_MAG) 33820ffac27SDaniel Baluta odr_bits |= lodr_bits << KMX61_MAG_ODR_SHIFT; 33920ffac27SDaniel Baluta 34020ffac27SDaniel Baluta ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_ODCNTL, 34120ffac27SDaniel Baluta odr_bits); 34220ffac27SDaniel Baluta if (ret < 0) 34320ffac27SDaniel Baluta return ret; 34420ffac27SDaniel Baluta 34520ffac27SDaniel Baluta return kmx61_set_mode(data, mode, KMX61_ACC | KMX61_MAG, true); 34620ffac27SDaniel Baluta } 34720ffac27SDaniel Baluta 34820ffac27SDaniel Baluta static int kmx61_get_odr(struct kmx61_data *data, int *val, int *val2, 34920ffac27SDaniel Baluta u8 device) 35020ffac27SDaniel Baluta { int i; 35120ffac27SDaniel Baluta u8 lodr_bits; 35220ffac27SDaniel Baluta 35320ffac27SDaniel Baluta if (device & KMX61_ACC) 35420ffac27SDaniel Baluta lodr_bits = (data->odr_bits >> KMX61_ACC_ODR_SHIFT) & 35520ffac27SDaniel Baluta KMX61_ACC_ODR_MASK; 35620ffac27SDaniel Baluta else if (device & KMX61_MAG) 35720ffac27SDaniel Baluta lodr_bits = (data->odr_bits >> KMX61_MAG_ODR_SHIFT) & 35820ffac27SDaniel Baluta KMX61_MAG_ODR_MASK; 35920ffac27SDaniel Baluta else 36020ffac27SDaniel Baluta return -EINVAL; 36120ffac27SDaniel Baluta 36220ffac27SDaniel Baluta for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++) 36320ffac27SDaniel Baluta if (lodr_bits == kmx61_samp_freq_table[i].odr_bits) { 36420ffac27SDaniel Baluta *val = kmx61_samp_freq_table[i].val; 36520ffac27SDaniel Baluta *val2 = kmx61_samp_freq_table[i].val2; 36620ffac27SDaniel Baluta return 0; 36720ffac27SDaniel Baluta } 36820ffac27SDaniel Baluta return -EINVAL; 36920ffac27SDaniel Baluta } 37020ffac27SDaniel Baluta 37120ffac27SDaniel Baluta static int kmx61_set_range(struct kmx61_data *data, u8 range) 37220ffac27SDaniel Baluta { 37320ffac27SDaniel Baluta int ret; 37420ffac27SDaniel Baluta 37520ffac27SDaniel Baluta ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_CTRL1); 37620ffac27SDaniel Baluta if (ret < 0) { 37720ffac27SDaniel Baluta dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); 37820ffac27SDaniel Baluta return ret; 37920ffac27SDaniel Baluta } 38020ffac27SDaniel Baluta 38120ffac27SDaniel Baluta ret &= ~KMX61_REG_CTRL1_GSEL_MASK; 38220ffac27SDaniel Baluta ret |= range & KMX61_REG_CTRL1_GSEL_MASK; 38320ffac27SDaniel Baluta 38420ffac27SDaniel Baluta ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_CTRL1, ret); 38520ffac27SDaniel Baluta if (ret < 0) { 38620ffac27SDaniel Baluta dev_err(&data->client->dev, "Error writing reg_ctrl1\n"); 38720ffac27SDaniel Baluta return ret; 38820ffac27SDaniel Baluta } 38920ffac27SDaniel Baluta 39020ffac27SDaniel Baluta data->range = range; 39120ffac27SDaniel Baluta 39220ffac27SDaniel Baluta return 0; 39320ffac27SDaniel Baluta } 39420ffac27SDaniel Baluta 39520ffac27SDaniel Baluta static int kmx61_set_scale(struct kmx61_data *data, u16 uscale) 39620ffac27SDaniel Baluta { 39720ffac27SDaniel Baluta int ret, i; 39820ffac27SDaniel Baluta u8 mode; 39920ffac27SDaniel Baluta 40020ffac27SDaniel Baluta for (i = 0; i < ARRAY_SIZE(kmx61_uscale_table); i++) { 40120ffac27SDaniel Baluta if (kmx61_uscale_table[i] == uscale) { 40220ffac27SDaniel Baluta ret = kmx61_get_mode(data, &mode, 40320ffac27SDaniel Baluta KMX61_ACC | KMX61_MAG); 40420ffac27SDaniel Baluta if (ret < 0) 40520ffac27SDaniel Baluta return ret; 40620ffac27SDaniel Baluta 40720ffac27SDaniel Baluta ret = kmx61_set_mode(data, KMX61_ALL_STBY, 40820ffac27SDaniel Baluta KMX61_ACC | KMX61_MAG, true); 40920ffac27SDaniel Baluta if (ret < 0) 41020ffac27SDaniel Baluta return ret; 41120ffac27SDaniel Baluta 41220ffac27SDaniel Baluta ret = kmx61_set_range(data, i); 41320ffac27SDaniel Baluta if (ret < 0) 41420ffac27SDaniel Baluta return ret; 41520ffac27SDaniel Baluta 41620ffac27SDaniel Baluta return kmx61_set_mode(data, mode, 41720ffac27SDaniel Baluta KMX61_ACC | KMX61_MAG, true); 41820ffac27SDaniel Baluta } 41920ffac27SDaniel Baluta } 42020ffac27SDaniel Baluta return -EINVAL; 42120ffac27SDaniel Baluta } 42220ffac27SDaniel Baluta 42320ffac27SDaniel Baluta static int kmx61_chip_init(struct kmx61_data *data) 42420ffac27SDaniel Baluta { 42520ffac27SDaniel Baluta int ret; 42620ffac27SDaniel Baluta 42720ffac27SDaniel Baluta ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_WHO_AM_I); 42820ffac27SDaniel Baluta if (ret < 0) { 42920ffac27SDaniel Baluta dev_err(&data->client->dev, "Error reading who_am_i\n"); 43020ffac27SDaniel Baluta return ret; 43120ffac27SDaniel Baluta } 43220ffac27SDaniel Baluta 43320ffac27SDaniel Baluta if (ret != KMX61_CHIP_ID) { 43420ffac27SDaniel Baluta dev_err(&data->client->dev, 43520ffac27SDaniel Baluta "Wrong chip id, got %x expected %x\n", 43620ffac27SDaniel Baluta ret, KMX61_CHIP_ID); 43720ffac27SDaniel Baluta return -EINVAL; 43820ffac27SDaniel Baluta } 43920ffac27SDaniel Baluta 44020ffac27SDaniel Baluta /* set accel 12bit, 4g range */ 44120ffac27SDaniel Baluta ret = kmx61_set_range(data, KMX61_RANGE_4G); 44220ffac27SDaniel Baluta if (ret < 0) 44320ffac27SDaniel Baluta return ret; 44420ffac27SDaniel Baluta 44520ffac27SDaniel Baluta ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_ODCNTL); 44620ffac27SDaniel Baluta if (ret < 0) { 44720ffac27SDaniel Baluta dev_err(&data->client->dev, "Error reading reg_odcntl\n"); 44820ffac27SDaniel Baluta return ret; 44920ffac27SDaniel Baluta } 45020ffac27SDaniel Baluta data->odr_bits = ret; 45120ffac27SDaniel Baluta 45220ffac27SDaniel Baluta /* set acc/magn to OPERATION mode */ 45320ffac27SDaniel Baluta ret = kmx61_set_mode(data, 0, KMX61_ACC | KMX61_MAG, true); 45420ffac27SDaniel Baluta if (ret < 0) 45520ffac27SDaniel Baluta return ret; 45620ffac27SDaniel Baluta 45720ffac27SDaniel Baluta return 0; 45820ffac27SDaniel Baluta } 45920ffac27SDaniel Baluta 46020ffac27SDaniel Baluta static int kmx61_read_measurement(struct kmx61_data *data, u8 base, u8 offset) 46120ffac27SDaniel Baluta { 46220ffac27SDaniel Baluta int ret; 46320ffac27SDaniel Baluta u8 reg = base + offset * 2; 46420ffac27SDaniel Baluta 46520ffac27SDaniel Baluta ret = i2c_smbus_read_word_data(data->client, reg); 46620ffac27SDaniel Baluta if (ret < 0) 46720ffac27SDaniel Baluta dev_err(&data->client->dev, "failed to read reg at %x\n", reg); 46820ffac27SDaniel Baluta 46920ffac27SDaniel Baluta return ret; 47020ffac27SDaniel Baluta } 47120ffac27SDaniel Baluta 47220ffac27SDaniel Baluta static int kmx61_read_raw(struct iio_dev *indio_dev, 47320ffac27SDaniel Baluta struct iio_chan_spec const *chan, int *val, 47420ffac27SDaniel Baluta int *val2, long mask) 47520ffac27SDaniel Baluta { 47620ffac27SDaniel Baluta int ret; 47720ffac27SDaniel Baluta u8 base_reg; 47820ffac27SDaniel Baluta struct kmx61_data *data = kmx61_get_data(indio_dev); 47920ffac27SDaniel Baluta 48020ffac27SDaniel Baluta switch (mask) { 48120ffac27SDaniel Baluta case IIO_CHAN_INFO_RAW: 48220ffac27SDaniel Baluta switch (chan->type) { 48320ffac27SDaniel Baluta case IIO_ACCEL: 48420ffac27SDaniel Baluta base_reg = KMX61_ACC_XOUT_L; 48520ffac27SDaniel Baluta break; 48620ffac27SDaniel Baluta case IIO_MAGN: 48720ffac27SDaniel Baluta base_reg = KMX61_MAG_XOUT_L; 48820ffac27SDaniel Baluta break; 48920ffac27SDaniel Baluta default: 49020ffac27SDaniel Baluta return -EINVAL; 49120ffac27SDaniel Baluta } 49220ffac27SDaniel Baluta mutex_lock(&data->lock); 49320ffac27SDaniel Baluta 49420ffac27SDaniel Baluta ret = kmx61_read_measurement(data, base_reg, chan->scan_index); 49520ffac27SDaniel Baluta if (ret < 0) { 49620ffac27SDaniel Baluta mutex_unlock(&data->lock); 49720ffac27SDaniel Baluta return ret; 49820ffac27SDaniel Baluta } 49920ffac27SDaniel Baluta *val = sign_extend32(ret >> chan->scan_type.shift, 50020ffac27SDaniel Baluta chan->scan_type.realbits - 1); 50120ffac27SDaniel Baluta 50220ffac27SDaniel Baluta mutex_unlock(&data->lock); 50320ffac27SDaniel Baluta return IIO_VAL_INT; 50420ffac27SDaniel Baluta case IIO_CHAN_INFO_SCALE: 50520ffac27SDaniel Baluta switch (chan->type) { 50620ffac27SDaniel Baluta case IIO_ACCEL: 50720ffac27SDaniel Baluta *val = 0; 50820ffac27SDaniel Baluta *val2 = kmx61_uscale_table[data->range]; 50920ffac27SDaniel Baluta return IIO_VAL_INT_PLUS_MICRO; 51020ffac27SDaniel Baluta case IIO_MAGN: 51120ffac27SDaniel Baluta /* 14 bits res, 1465 microGauss per magn count */ 51220ffac27SDaniel Baluta *val = 0; 51320ffac27SDaniel Baluta *val2 = 1465; 51420ffac27SDaniel Baluta return IIO_VAL_INT_PLUS_MICRO; 51520ffac27SDaniel Baluta default: 51620ffac27SDaniel Baluta return -EINVAL; 51720ffac27SDaniel Baluta } 51820ffac27SDaniel Baluta case IIO_CHAN_INFO_SAMP_FREQ: 51920ffac27SDaniel Baluta if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN) 52020ffac27SDaniel Baluta return -EINVAL; 52120ffac27SDaniel Baluta 52220ffac27SDaniel Baluta mutex_lock(&data->lock); 52320ffac27SDaniel Baluta ret = kmx61_get_odr(data, val, val2, chan->address); 52420ffac27SDaniel Baluta mutex_unlock(&data->lock); 52520ffac27SDaniel Baluta if (ret) 52620ffac27SDaniel Baluta return -EINVAL; 52720ffac27SDaniel Baluta return IIO_VAL_INT_PLUS_MICRO; 52820ffac27SDaniel Baluta } 52920ffac27SDaniel Baluta return -EINVAL; 53020ffac27SDaniel Baluta } 53120ffac27SDaniel Baluta 53220ffac27SDaniel Baluta static int kmx61_write_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 struct kmx61_data *data = kmx61_get_data(indio_dev); 53820ffac27SDaniel Baluta 53920ffac27SDaniel Baluta switch (mask) { 54020ffac27SDaniel Baluta case IIO_CHAN_INFO_SAMP_FREQ: 54120ffac27SDaniel Baluta if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN) 54220ffac27SDaniel Baluta return -EINVAL; 54320ffac27SDaniel Baluta 54420ffac27SDaniel Baluta mutex_lock(&data->lock); 54520ffac27SDaniel Baluta ret = kmx61_set_odr(data, val, val2, chan->address); 54620ffac27SDaniel Baluta mutex_unlock(&data->lock); 54720ffac27SDaniel Baluta return ret; 54820ffac27SDaniel Baluta case IIO_CHAN_INFO_SCALE: 54920ffac27SDaniel Baluta switch (chan->type) { 55020ffac27SDaniel Baluta case IIO_ACCEL: 55120ffac27SDaniel Baluta if (val != 0) 55220ffac27SDaniel Baluta return -EINVAL; 55320ffac27SDaniel Baluta mutex_lock(&data->lock); 55420ffac27SDaniel Baluta ret = kmx61_set_scale(data, val2); 55520ffac27SDaniel Baluta mutex_unlock(&data->lock); 55620ffac27SDaniel Baluta return ret; 55720ffac27SDaniel Baluta default: 55820ffac27SDaniel Baluta return -EINVAL; 55920ffac27SDaniel Baluta } 56020ffac27SDaniel Baluta default: 56120ffac27SDaniel Baluta return -EINVAL; 56220ffac27SDaniel Baluta } 56320ffac27SDaniel Baluta } 56420ffac27SDaniel Baluta 56520ffac27SDaniel Baluta static const struct iio_info kmx61_acc_info = { 56620ffac27SDaniel Baluta .driver_module = THIS_MODULE, 56720ffac27SDaniel Baluta .read_raw = kmx61_read_raw, 56820ffac27SDaniel Baluta .write_raw = kmx61_write_raw, 56920ffac27SDaniel Baluta .attrs = &kmx61_acc_attribute_group, 57020ffac27SDaniel Baluta }; 57120ffac27SDaniel Baluta 57220ffac27SDaniel Baluta static const struct iio_info kmx61_mag_info = { 57320ffac27SDaniel Baluta .driver_module = THIS_MODULE, 57420ffac27SDaniel Baluta .read_raw = kmx61_read_raw, 57520ffac27SDaniel Baluta .write_raw = kmx61_write_raw, 57620ffac27SDaniel Baluta .attrs = &kmx61_mag_attribute_group, 57720ffac27SDaniel Baluta }; 57820ffac27SDaniel Baluta 579*b25862c5SDaniel Baluta static const char *kmx61_match_acpi_device(struct device *dev) 580*b25862c5SDaniel Baluta { 581*b25862c5SDaniel Baluta const struct acpi_device_id *id; 582*b25862c5SDaniel Baluta 583*b25862c5SDaniel Baluta id = acpi_match_device(dev->driver->acpi_match_table, dev); 584*b25862c5SDaniel Baluta if (!id) 585*b25862c5SDaniel Baluta return NULL; 586*b25862c5SDaniel Baluta return dev_name(dev); 587*b25862c5SDaniel Baluta } 588*b25862c5SDaniel Baluta 589*b25862c5SDaniel Baluta static int kmx61_gpio_probe(struct i2c_client *client, struct kmx61_data *data) 590*b25862c5SDaniel Baluta { 591*b25862c5SDaniel Baluta struct device *dev; 592*b25862c5SDaniel Baluta struct gpio_desc *gpio; 593*b25862c5SDaniel Baluta int ret; 594*b25862c5SDaniel Baluta 595*b25862c5SDaniel Baluta if (!client) 596*b25862c5SDaniel Baluta return -EINVAL; 597*b25862c5SDaniel Baluta 598*b25862c5SDaniel Baluta dev = &client->dev; 599*b25862c5SDaniel Baluta 600*b25862c5SDaniel Baluta /* data ready gpio interrupt pin */ 601*b25862c5SDaniel Baluta gpio = devm_gpiod_get_index(dev, KMX61_GPIO_NAME, 0); 602*b25862c5SDaniel Baluta if (IS_ERR(gpio)) { 603*b25862c5SDaniel Baluta dev_err(dev, "acpi gpio get index failed\n"); 604*b25862c5SDaniel Baluta return PTR_ERR(gpio); 605*b25862c5SDaniel Baluta } 606*b25862c5SDaniel Baluta 607*b25862c5SDaniel Baluta ret = gpiod_direction_input(gpio); 608*b25862c5SDaniel Baluta if (ret) 609*b25862c5SDaniel Baluta return ret; 610*b25862c5SDaniel Baluta 611*b25862c5SDaniel Baluta ret = gpiod_to_irq(gpio); 612*b25862c5SDaniel Baluta 613*b25862c5SDaniel Baluta dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); 614*b25862c5SDaniel Baluta return ret; 615*b25862c5SDaniel Baluta } 616*b25862c5SDaniel Baluta 61720ffac27SDaniel Baluta static struct iio_dev *kmx61_indiodev_setup(struct kmx61_data *data, 61820ffac27SDaniel Baluta const struct iio_info *info, 61920ffac27SDaniel Baluta const struct iio_chan_spec *chan, 62020ffac27SDaniel Baluta int num_channels, 62120ffac27SDaniel Baluta const char *name) 62220ffac27SDaniel Baluta { 62320ffac27SDaniel Baluta struct iio_dev *indio_dev; 62420ffac27SDaniel Baluta 62520ffac27SDaniel Baluta indio_dev = devm_iio_device_alloc(&data->client->dev, sizeof(data)); 62620ffac27SDaniel Baluta if (!indio_dev) 62720ffac27SDaniel Baluta return ERR_PTR(-ENOMEM); 62820ffac27SDaniel Baluta 62920ffac27SDaniel Baluta kmx61_set_data(indio_dev, data); 63020ffac27SDaniel Baluta 63120ffac27SDaniel Baluta indio_dev->dev.parent = &data->client->dev; 63220ffac27SDaniel Baluta indio_dev->channels = chan; 63320ffac27SDaniel Baluta indio_dev->num_channels = num_channels; 63420ffac27SDaniel Baluta indio_dev->name = name; 63520ffac27SDaniel Baluta indio_dev->modes = INDIO_DIRECT_MODE; 63620ffac27SDaniel Baluta indio_dev->info = info; 63720ffac27SDaniel Baluta 63820ffac27SDaniel Baluta return indio_dev; 63920ffac27SDaniel Baluta } 64020ffac27SDaniel Baluta 64120ffac27SDaniel Baluta static int kmx61_probe(struct i2c_client *client, 64220ffac27SDaniel Baluta const struct i2c_device_id *id) 64320ffac27SDaniel Baluta { 64420ffac27SDaniel Baluta int ret; 64520ffac27SDaniel Baluta struct kmx61_data *data; 64620ffac27SDaniel Baluta const char *name = NULL; 64720ffac27SDaniel Baluta 64820ffac27SDaniel Baluta data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); 64920ffac27SDaniel Baluta if (!data) 65020ffac27SDaniel Baluta return -ENOMEM; 65120ffac27SDaniel Baluta 65220ffac27SDaniel Baluta i2c_set_clientdata(client, data); 65320ffac27SDaniel Baluta data->client = client; 65420ffac27SDaniel Baluta 65520ffac27SDaniel Baluta mutex_init(&data->lock); 65620ffac27SDaniel Baluta 657*b25862c5SDaniel Baluta if (id) 658*b25862c5SDaniel Baluta name = id->name; 659*b25862c5SDaniel Baluta else if (ACPI_HANDLE(&client->dev)) 660*b25862c5SDaniel Baluta name = kmx61_match_acpi_device(&client->dev); 661*b25862c5SDaniel Baluta else 662*b25862c5SDaniel Baluta return -ENODEV; 663*b25862c5SDaniel Baluta 66420ffac27SDaniel Baluta data->acc_indio_dev = 66520ffac27SDaniel Baluta kmx61_indiodev_setup(data, &kmx61_acc_info, 66620ffac27SDaniel Baluta kmx61_acc_channels, 66720ffac27SDaniel Baluta ARRAY_SIZE(kmx61_acc_channels), 66820ffac27SDaniel Baluta name); 66920ffac27SDaniel Baluta if (IS_ERR(data->acc_indio_dev)) 67020ffac27SDaniel Baluta return PTR_ERR(data->acc_indio_dev); 67120ffac27SDaniel Baluta 67220ffac27SDaniel Baluta data->mag_indio_dev = 67320ffac27SDaniel Baluta kmx61_indiodev_setup(data, &kmx61_mag_info, 67420ffac27SDaniel Baluta kmx61_mag_channels, 67520ffac27SDaniel Baluta ARRAY_SIZE(kmx61_mag_channels), 67620ffac27SDaniel Baluta name); 67720ffac27SDaniel Baluta if (IS_ERR(data->mag_indio_dev)) 67820ffac27SDaniel Baluta return PTR_ERR(data->mag_indio_dev); 67920ffac27SDaniel Baluta 68020ffac27SDaniel Baluta ret = kmx61_chip_init(data); 68120ffac27SDaniel Baluta if (ret < 0) 68220ffac27SDaniel Baluta return ret; 68320ffac27SDaniel Baluta 684*b25862c5SDaniel Baluta if (client->irq < 0) 685*b25862c5SDaniel Baluta client->irq = kmx61_gpio_probe(client, data); 686*b25862c5SDaniel Baluta 68720ffac27SDaniel Baluta ret = iio_device_register(data->acc_indio_dev); 68820ffac27SDaniel Baluta if (ret < 0) { 68920ffac27SDaniel Baluta dev_err(&client->dev, "Failed to register acc iio device\n"); 69020ffac27SDaniel Baluta goto err_chip_uninit; 69120ffac27SDaniel Baluta } 69220ffac27SDaniel Baluta 69320ffac27SDaniel Baluta ret = iio_device_register(data->mag_indio_dev); 69420ffac27SDaniel Baluta if (ret < 0) { 69520ffac27SDaniel Baluta dev_err(&client->dev, "Failed to register mag iio device\n"); 69620ffac27SDaniel Baluta goto err_iio_unregister; 69720ffac27SDaniel Baluta } 69820ffac27SDaniel Baluta 69920ffac27SDaniel Baluta return 0; 70020ffac27SDaniel Baluta 70120ffac27SDaniel Baluta err_iio_unregister: 70220ffac27SDaniel Baluta iio_device_unregister(data->acc_indio_dev); 70320ffac27SDaniel Baluta err_chip_uninit: 70420ffac27SDaniel Baluta kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true); 70520ffac27SDaniel Baluta return ret; 70620ffac27SDaniel Baluta } 70720ffac27SDaniel Baluta 70820ffac27SDaniel Baluta static int kmx61_remove(struct i2c_client *client) 70920ffac27SDaniel Baluta { 71020ffac27SDaniel Baluta struct kmx61_data *data = i2c_get_clientdata(client); 71120ffac27SDaniel Baluta 71220ffac27SDaniel Baluta iio_device_unregister(data->acc_indio_dev); 71320ffac27SDaniel Baluta iio_device_unregister(data->mag_indio_dev); 71420ffac27SDaniel Baluta 71520ffac27SDaniel Baluta mutex_lock(&data->lock); 71620ffac27SDaniel Baluta kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true); 71720ffac27SDaniel Baluta mutex_unlock(&data->lock); 71820ffac27SDaniel Baluta 71920ffac27SDaniel Baluta return 0; 72020ffac27SDaniel Baluta } 72120ffac27SDaniel Baluta 722*b25862c5SDaniel Baluta static const struct acpi_device_id kmx61_acpi_match[] = { 723*b25862c5SDaniel Baluta {"KMX61021", 0}, 724*b25862c5SDaniel Baluta {} 725*b25862c5SDaniel Baluta }; 726*b25862c5SDaniel Baluta 727*b25862c5SDaniel Baluta MODULE_DEVICE_TABLE(acpi, kmx61_acpi_match); 728*b25862c5SDaniel Baluta 72920ffac27SDaniel Baluta static const struct i2c_device_id kmx61_id[] = { 73020ffac27SDaniel Baluta {"kmx611021", 0}, 73120ffac27SDaniel Baluta {} 73220ffac27SDaniel Baluta }; 73320ffac27SDaniel Baluta 73420ffac27SDaniel Baluta MODULE_DEVICE_TABLE(i2c, kmx61_id); 73520ffac27SDaniel Baluta 73620ffac27SDaniel Baluta static struct i2c_driver kmx61_driver = { 73720ffac27SDaniel Baluta .driver = { 73820ffac27SDaniel Baluta .name = KMX61_DRV_NAME, 739*b25862c5SDaniel Baluta .acpi_match_table = ACPI_PTR(kmx61_acpi_match), 74020ffac27SDaniel Baluta }, 74120ffac27SDaniel Baluta .probe = kmx61_probe, 74220ffac27SDaniel Baluta .remove = kmx61_remove, 74320ffac27SDaniel Baluta .id_table = kmx61_id, 74420ffac27SDaniel Baluta }; 74520ffac27SDaniel Baluta 74620ffac27SDaniel Baluta module_i2c_driver(kmx61_driver); 74720ffac27SDaniel Baluta 74820ffac27SDaniel Baluta MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>"); 74920ffac27SDaniel Baluta MODULE_DESCRIPTION("KMX61 accelerometer/magnetometer driver"); 75020ffac27SDaniel Baluta MODULE_LICENSE("GPL v2"); 751