1*20ffac27SDaniel Baluta /* 2*20ffac27SDaniel Baluta * KMX61 - Kionix 6-axis Accelerometer/Magnetometer 3*20ffac27SDaniel Baluta * 4*20ffac27SDaniel Baluta * Copyright (c) 2014, Intel Corporation. 5*20ffac27SDaniel Baluta * 6*20ffac27SDaniel Baluta * This file is subject to the terms and conditions of version 2 of 7*20ffac27SDaniel Baluta * the GNU General Public License. See the file COPYING in the main 8*20ffac27SDaniel Baluta * directory of this archive for more details. 9*20ffac27SDaniel Baluta * 10*20ffac27SDaniel Baluta * IIO driver for KMX61 (7-bit I2C slave address 0x0E or 0x0F). 11*20ffac27SDaniel Baluta * 12*20ffac27SDaniel Baluta */ 13*20ffac27SDaniel Baluta 14*20ffac27SDaniel Baluta #include <linux/module.h> 15*20ffac27SDaniel Baluta #include <linux/i2c.h> 16*20ffac27SDaniel Baluta #include <linux/iio/iio.h> 17*20ffac27SDaniel Baluta #include <linux/iio/sysfs.h> 18*20ffac27SDaniel Baluta 19*20ffac27SDaniel Baluta #define KMX61_DRV_NAME "kmx61" 20*20ffac27SDaniel Baluta 21*20ffac27SDaniel Baluta #define KMX61_REG_WHO_AM_I 0x00 22*20ffac27SDaniel Baluta 23*20ffac27SDaniel Baluta /* 24*20ffac27SDaniel Baluta * three 16-bit accelerometer output registers for X/Y/Z axis 25*20ffac27SDaniel Baluta * we use only XOUT_L as a base register, all other addresses 26*20ffac27SDaniel Baluta * can be obtained by applying an offset and are provided here 27*20ffac27SDaniel Baluta * only for clarity. 28*20ffac27SDaniel Baluta */ 29*20ffac27SDaniel Baluta #define KMX61_ACC_XOUT_L 0x0A 30*20ffac27SDaniel Baluta #define KMX61_ACC_XOUT_H 0x0B 31*20ffac27SDaniel Baluta #define KMX61_ACC_YOUT_L 0x0C 32*20ffac27SDaniel Baluta #define KMX61_ACC_YOUT_H 0x0D 33*20ffac27SDaniel Baluta #define KMX61_ACC_ZOUT_L 0x0E 34*20ffac27SDaniel Baluta #define KMX61_ACC_ZOUT_H 0x0F 35*20ffac27SDaniel Baluta 36*20ffac27SDaniel Baluta /* 37*20ffac27SDaniel Baluta * one 16-bit temperature output register 38*20ffac27SDaniel Baluta */ 39*20ffac27SDaniel Baluta #define KMX61_TEMP_L 0x10 40*20ffac27SDaniel Baluta #define KMX61_TEMP_H 0x11 41*20ffac27SDaniel Baluta 42*20ffac27SDaniel Baluta /* 43*20ffac27SDaniel Baluta * three 16-bit magnetometer output registers for X/Y/Z axis 44*20ffac27SDaniel Baluta */ 45*20ffac27SDaniel Baluta #define KMX61_MAG_XOUT_L 0x12 46*20ffac27SDaniel Baluta #define KMX61_MAG_XOUT_H 0x13 47*20ffac27SDaniel Baluta #define KMX61_MAG_YOUT_L 0x14 48*20ffac27SDaniel Baluta #define KMX61_MAG_YOUT_H 0x15 49*20ffac27SDaniel Baluta #define KMX61_MAG_ZOUT_L 0x16 50*20ffac27SDaniel Baluta #define KMX61_MAG_ZOUT_H 0x17 51*20ffac27SDaniel Baluta 52*20ffac27SDaniel Baluta #define KMX61_REG_STBY 0x29 53*20ffac27SDaniel Baluta #define KMX61_REG_CTRL1 0x2A 54*20ffac27SDaniel Baluta #define KMX61_REG_ODCNTL 0x2C 55*20ffac27SDaniel Baluta 56*20ffac27SDaniel Baluta #define KMX61_ACC_STBY_BIT BIT(0) 57*20ffac27SDaniel Baluta #define KMX61_MAG_STBY_BIT BIT(1) 58*20ffac27SDaniel Baluta #define KMX61_ACT_STBY_BIT BIT(7) 59*20ffac27SDaniel Baluta 60*20ffac27SDaniel Baluta #define KMX61_ALL_STBY (KMX61_ACC_STBY_BIT | KMX61_MAG_STBY_BIT) 61*20ffac27SDaniel Baluta 62*20ffac27SDaniel Baluta #define KMX61_REG_CTRL1_GSEL_MASK 0x03 63*20ffac27SDaniel Baluta 64*20ffac27SDaniel Baluta #define KMX61_ACC_ODR_SHIFT 0 65*20ffac27SDaniel Baluta #define KMX61_MAG_ODR_SHIFT 4 66*20ffac27SDaniel Baluta #define KMX61_ACC_ODR_MASK 0x0F 67*20ffac27SDaniel Baluta #define KMX61_MAG_ODR_MASK 0xF0 68*20ffac27SDaniel Baluta 69*20ffac27SDaniel Baluta #define KMX61_CHIP_ID 0x12 70*20ffac27SDaniel Baluta 71*20ffac27SDaniel Baluta /* KMX61 devices */ 72*20ffac27SDaniel Baluta #define KMX61_ACC 0x01 73*20ffac27SDaniel Baluta #define KMX61_MAG 0x02 74*20ffac27SDaniel Baluta 75*20ffac27SDaniel Baluta struct kmx61_data { 76*20ffac27SDaniel Baluta struct i2c_client *client; 77*20ffac27SDaniel Baluta 78*20ffac27SDaniel Baluta /* serialize access to non-atomic ops, e.g set_mode */ 79*20ffac27SDaniel Baluta struct mutex lock; 80*20ffac27SDaniel Baluta 81*20ffac27SDaniel Baluta /* standby state */ 82*20ffac27SDaniel Baluta bool acc_stby; 83*20ffac27SDaniel Baluta bool mag_stby; 84*20ffac27SDaniel Baluta 85*20ffac27SDaniel Baluta /* config bits */ 86*20ffac27SDaniel Baluta u8 range; 87*20ffac27SDaniel Baluta u8 odr_bits; 88*20ffac27SDaniel Baluta 89*20ffac27SDaniel Baluta /* accelerometer specific data */ 90*20ffac27SDaniel Baluta struct iio_dev *acc_indio_dev; 91*20ffac27SDaniel Baluta 92*20ffac27SDaniel Baluta /* magnetometer specific data */ 93*20ffac27SDaniel Baluta struct iio_dev *mag_indio_dev; 94*20ffac27SDaniel Baluta }; 95*20ffac27SDaniel Baluta 96*20ffac27SDaniel Baluta enum kmx61_range { 97*20ffac27SDaniel Baluta KMX61_RANGE_2G, 98*20ffac27SDaniel Baluta KMX61_RANGE_4G, 99*20ffac27SDaniel Baluta KMX61_RANGE_8G, 100*20ffac27SDaniel Baluta }; 101*20ffac27SDaniel Baluta 102*20ffac27SDaniel Baluta enum kmx61_axis { 103*20ffac27SDaniel Baluta KMX61_AXIS_X, 104*20ffac27SDaniel Baluta KMX61_AXIS_Y, 105*20ffac27SDaniel Baluta KMX61_AXIS_Z, 106*20ffac27SDaniel Baluta }; 107*20ffac27SDaniel Baluta 108*20ffac27SDaniel Baluta static const u16 kmx61_uscale_table[] = {9582, 19163, 38326}; 109*20ffac27SDaniel Baluta 110*20ffac27SDaniel Baluta static const struct { 111*20ffac27SDaniel Baluta int val; 112*20ffac27SDaniel Baluta int val2; 113*20ffac27SDaniel Baluta u8 odr_bits; 114*20ffac27SDaniel Baluta } kmx61_samp_freq_table[] = { {12, 500000, 0x00}, 115*20ffac27SDaniel Baluta {25, 0, 0x01}, 116*20ffac27SDaniel Baluta {50, 0, 0x02}, 117*20ffac27SDaniel Baluta {100, 0, 0x03}, 118*20ffac27SDaniel Baluta {200, 0, 0x04}, 119*20ffac27SDaniel Baluta {400, 0, 0x05}, 120*20ffac27SDaniel Baluta {800, 0, 0x06}, 121*20ffac27SDaniel Baluta {1600, 0, 0x07}, 122*20ffac27SDaniel Baluta {0, 781000, 0x08}, 123*20ffac27SDaniel Baluta {1, 563000, 0x09}, 124*20ffac27SDaniel Baluta {3, 125000, 0x0A}, 125*20ffac27SDaniel Baluta {6, 250000, 0x0B} }; 126*20ffac27SDaniel Baluta 127*20ffac27SDaniel Baluta static IIO_CONST_ATTR(accel_scale_available, "0.009582 0.019163 0.038326"); 128*20ffac27SDaniel Baluta static IIO_CONST_ATTR(magn_scale_available, "0.001465"); 129*20ffac27SDaniel Baluta static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( 130*20ffac27SDaniel Baluta "0.781000 1.563000 3.125000 6.250000 12.500000 25 50 100 200 400 800"); 131*20ffac27SDaniel Baluta 132*20ffac27SDaniel Baluta static struct attribute *kmx61_acc_attributes[] = { 133*20ffac27SDaniel Baluta &iio_const_attr_accel_scale_available.dev_attr.attr, 134*20ffac27SDaniel Baluta &iio_const_attr_sampling_frequency_available.dev_attr.attr, 135*20ffac27SDaniel Baluta NULL, 136*20ffac27SDaniel Baluta }; 137*20ffac27SDaniel Baluta 138*20ffac27SDaniel Baluta static struct attribute *kmx61_mag_attributes[] = { 139*20ffac27SDaniel Baluta &iio_const_attr_magn_scale_available.dev_attr.attr, 140*20ffac27SDaniel Baluta &iio_const_attr_sampling_frequency_available.dev_attr.attr, 141*20ffac27SDaniel Baluta NULL, 142*20ffac27SDaniel Baluta }; 143*20ffac27SDaniel Baluta 144*20ffac27SDaniel Baluta static const struct attribute_group kmx61_acc_attribute_group = { 145*20ffac27SDaniel Baluta .attrs = kmx61_acc_attributes, 146*20ffac27SDaniel Baluta }; 147*20ffac27SDaniel Baluta 148*20ffac27SDaniel Baluta static const struct attribute_group kmx61_mag_attribute_group = { 149*20ffac27SDaniel Baluta .attrs = kmx61_mag_attributes, 150*20ffac27SDaniel Baluta }; 151*20ffac27SDaniel Baluta 152*20ffac27SDaniel Baluta #define KMX61_ACC_CHAN(_axis) { \ 153*20ffac27SDaniel Baluta .type = IIO_ACCEL, \ 154*20ffac27SDaniel Baluta .modified = 1, \ 155*20ffac27SDaniel Baluta .channel2 = IIO_MOD_ ## _axis, \ 156*20ffac27SDaniel Baluta .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 157*20ffac27SDaniel Baluta .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 158*20ffac27SDaniel Baluta BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 159*20ffac27SDaniel Baluta .address = KMX61_ACC, \ 160*20ffac27SDaniel Baluta .scan_index = KMX61_AXIS_ ## _axis, \ 161*20ffac27SDaniel Baluta .scan_type = { \ 162*20ffac27SDaniel Baluta .sign = 's', \ 163*20ffac27SDaniel Baluta .realbits = 12, \ 164*20ffac27SDaniel Baluta .storagebits = 16, \ 165*20ffac27SDaniel Baluta .shift = 4, \ 166*20ffac27SDaniel Baluta .endianness = IIO_LE, \ 167*20ffac27SDaniel Baluta }, \ 168*20ffac27SDaniel Baluta } 169*20ffac27SDaniel Baluta 170*20ffac27SDaniel Baluta #define KMX61_MAG_CHAN(_axis) { \ 171*20ffac27SDaniel Baluta .type = IIO_MAGN, \ 172*20ffac27SDaniel Baluta .modified = 1, \ 173*20ffac27SDaniel Baluta .channel2 = IIO_MOD_ ## _axis, \ 174*20ffac27SDaniel Baluta .address = KMX61_MAG, \ 175*20ffac27SDaniel Baluta .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 176*20ffac27SDaniel Baluta .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 177*20ffac27SDaniel Baluta BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 178*20ffac27SDaniel Baluta .scan_index = KMX61_AXIS_ ## _axis, \ 179*20ffac27SDaniel Baluta .scan_type = { \ 180*20ffac27SDaniel Baluta .sign = 's', \ 181*20ffac27SDaniel Baluta .realbits = 14, \ 182*20ffac27SDaniel Baluta .storagebits = 16, \ 183*20ffac27SDaniel Baluta .shift = 2, \ 184*20ffac27SDaniel Baluta .endianness = IIO_LE, \ 185*20ffac27SDaniel Baluta }, \ 186*20ffac27SDaniel Baluta } 187*20ffac27SDaniel Baluta 188*20ffac27SDaniel Baluta static const struct iio_chan_spec kmx61_acc_channels[] = { 189*20ffac27SDaniel Baluta KMX61_ACC_CHAN(X), 190*20ffac27SDaniel Baluta KMX61_ACC_CHAN(Y), 191*20ffac27SDaniel Baluta KMX61_ACC_CHAN(Z), 192*20ffac27SDaniel Baluta }; 193*20ffac27SDaniel Baluta 194*20ffac27SDaniel Baluta static const struct iio_chan_spec kmx61_mag_channels[] = { 195*20ffac27SDaniel Baluta KMX61_MAG_CHAN(X), 196*20ffac27SDaniel Baluta KMX61_MAG_CHAN(Y), 197*20ffac27SDaniel Baluta KMX61_MAG_CHAN(Z), 198*20ffac27SDaniel Baluta }; 199*20ffac27SDaniel Baluta 200*20ffac27SDaniel Baluta static void kmx61_set_data(struct iio_dev *indio_dev, struct kmx61_data *data) 201*20ffac27SDaniel Baluta { 202*20ffac27SDaniel Baluta struct kmx61_data **priv = iio_priv(indio_dev); 203*20ffac27SDaniel Baluta 204*20ffac27SDaniel Baluta *priv = data; 205*20ffac27SDaniel Baluta } 206*20ffac27SDaniel Baluta 207*20ffac27SDaniel Baluta static struct kmx61_data *kmx61_get_data(struct iio_dev *indio_dev) 208*20ffac27SDaniel Baluta { 209*20ffac27SDaniel Baluta return *(struct kmx61_data **)iio_priv(indio_dev); 210*20ffac27SDaniel Baluta } 211*20ffac27SDaniel Baluta 212*20ffac27SDaniel Baluta static int kmx61_convert_freq_to_bit(int val, int val2) 213*20ffac27SDaniel Baluta { 214*20ffac27SDaniel Baluta int i; 215*20ffac27SDaniel Baluta 216*20ffac27SDaniel Baluta for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++) 217*20ffac27SDaniel Baluta if (val == kmx61_samp_freq_table[i].val && 218*20ffac27SDaniel Baluta val2 == kmx61_samp_freq_table[i].val2) 219*20ffac27SDaniel Baluta return kmx61_samp_freq_table[i].odr_bits; 220*20ffac27SDaniel Baluta return -EINVAL; 221*20ffac27SDaniel Baluta } 222*20ffac27SDaniel Baluta 223*20ffac27SDaniel Baluta /** 224*20ffac27SDaniel Baluta * kmx61_set_mode() - set KMX61 device operating mode 225*20ffac27SDaniel Baluta * @data - kmx61 device private data pointer 226*20ffac27SDaniel Baluta * @mode - bitmask, indicating operating mode for @device 227*20ffac27SDaniel Baluta * @device - bitmask, indicating device for which @mode needs to be set 228*20ffac27SDaniel Baluta * @update - update stby bits stored in device's private @data 229*20ffac27SDaniel Baluta * 230*20ffac27SDaniel Baluta * For each sensor (accelerometer/magnetometer) there are two operating modes 231*20ffac27SDaniel Baluta * STANDBY and OPERATION. Neither accel nor magn can be disabled independently 232*20ffac27SDaniel Baluta * if they are both enabled. Internal sensors state is saved in acc_stby and 233*20ffac27SDaniel Baluta * mag_stby members of driver's private @data. 234*20ffac27SDaniel Baluta */ 235*20ffac27SDaniel Baluta static int kmx61_set_mode(struct kmx61_data *data, u8 mode, u8 device, 236*20ffac27SDaniel Baluta bool update) 237*20ffac27SDaniel Baluta { 238*20ffac27SDaniel Baluta int ret; 239*20ffac27SDaniel Baluta int acc_stby = -1, mag_stby = -1; 240*20ffac27SDaniel Baluta 241*20ffac27SDaniel Baluta ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_STBY); 242*20ffac27SDaniel Baluta if (ret < 0) { 243*20ffac27SDaniel Baluta dev_err(&data->client->dev, "Error reading reg_stby\n"); 244*20ffac27SDaniel Baluta return ret; 245*20ffac27SDaniel Baluta } 246*20ffac27SDaniel Baluta if (device & KMX61_ACC) { 247*20ffac27SDaniel Baluta if (mode & KMX61_ACC_STBY_BIT) { 248*20ffac27SDaniel Baluta ret |= KMX61_ACC_STBY_BIT; 249*20ffac27SDaniel Baluta acc_stby = 1; 250*20ffac27SDaniel Baluta } else { 251*20ffac27SDaniel Baluta ret &= ~KMX61_ACC_STBY_BIT; 252*20ffac27SDaniel Baluta acc_stby = 0; 253*20ffac27SDaniel Baluta } 254*20ffac27SDaniel Baluta } 255*20ffac27SDaniel Baluta 256*20ffac27SDaniel Baluta if (device & KMX61_MAG) { 257*20ffac27SDaniel Baluta if (mode & KMX61_MAG_STBY_BIT) { 258*20ffac27SDaniel Baluta ret |= KMX61_MAG_STBY_BIT; 259*20ffac27SDaniel Baluta mag_stby = 1; 260*20ffac27SDaniel Baluta } else { 261*20ffac27SDaniel Baluta ret &= ~KMX61_MAG_STBY_BIT; 262*20ffac27SDaniel Baluta mag_stby = 0; 263*20ffac27SDaniel Baluta } 264*20ffac27SDaniel Baluta } 265*20ffac27SDaniel Baluta 266*20ffac27SDaniel Baluta if (mode & KMX61_ACT_STBY_BIT) 267*20ffac27SDaniel Baluta ret |= KMX61_ACT_STBY_BIT; 268*20ffac27SDaniel Baluta 269*20ffac27SDaniel Baluta ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_STBY, ret); 270*20ffac27SDaniel Baluta if (ret < 0) { 271*20ffac27SDaniel Baluta dev_err(&data->client->dev, "Error writing reg_stby\n"); 272*20ffac27SDaniel Baluta return ret; 273*20ffac27SDaniel Baluta } 274*20ffac27SDaniel Baluta 275*20ffac27SDaniel Baluta if (acc_stby != -1 && update) 276*20ffac27SDaniel Baluta data->acc_stby = acc_stby; 277*20ffac27SDaniel Baluta if (mag_stby != -1 && update) 278*20ffac27SDaniel Baluta data->mag_stby = mag_stby; 279*20ffac27SDaniel Baluta 280*20ffac27SDaniel Baluta return 0; 281*20ffac27SDaniel Baluta } 282*20ffac27SDaniel Baluta 283*20ffac27SDaniel Baluta static int kmx61_get_mode(struct kmx61_data *data, u8 *mode, u8 device) 284*20ffac27SDaniel Baluta { 285*20ffac27SDaniel Baluta int ret; 286*20ffac27SDaniel Baluta 287*20ffac27SDaniel Baluta ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_STBY); 288*20ffac27SDaniel Baluta if (ret < 0) { 289*20ffac27SDaniel Baluta dev_err(&data->client->dev, "Error reading reg_stby\n"); 290*20ffac27SDaniel Baluta return ret; 291*20ffac27SDaniel Baluta } 292*20ffac27SDaniel Baluta *mode = 0; 293*20ffac27SDaniel Baluta 294*20ffac27SDaniel Baluta if (device & KMX61_ACC) { 295*20ffac27SDaniel Baluta if (ret & KMX61_ACC_STBY_BIT) 296*20ffac27SDaniel Baluta *mode |= KMX61_ACC_STBY_BIT; 297*20ffac27SDaniel Baluta else 298*20ffac27SDaniel Baluta *mode &= ~KMX61_ACC_STBY_BIT; 299*20ffac27SDaniel Baluta } 300*20ffac27SDaniel Baluta 301*20ffac27SDaniel Baluta if (device & KMX61_MAG) { 302*20ffac27SDaniel Baluta if (ret & KMX61_MAG_STBY_BIT) 303*20ffac27SDaniel Baluta *mode |= KMX61_MAG_STBY_BIT; 304*20ffac27SDaniel Baluta else 305*20ffac27SDaniel Baluta *mode &= ~KMX61_MAG_STBY_BIT; 306*20ffac27SDaniel Baluta } 307*20ffac27SDaniel Baluta 308*20ffac27SDaniel Baluta return 0; 309*20ffac27SDaniel Baluta } 310*20ffac27SDaniel Baluta 311*20ffac27SDaniel Baluta static int kmx61_set_odr(struct kmx61_data *data, int val, int val2, u8 device) 312*20ffac27SDaniel Baluta { 313*20ffac27SDaniel Baluta int ret; 314*20ffac27SDaniel Baluta u8 mode; 315*20ffac27SDaniel Baluta int lodr_bits, odr_bits; 316*20ffac27SDaniel Baluta 317*20ffac27SDaniel Baluta ret = kmx61_get_mode(data, &mode, KMX61_ACC | KMX61_MAG); 318*20ffac27SDaniel Baluta if (ret < 0) 319*20ffac27SDaniel Baluta return ret; 320*20ffac27SDaniel Baluta 321*20ffac27SDaniel Baluta lodr_bits = kmx61_convert_freq_to_bit(val, val2); 322*20ffac27SDaniel Baluta if (lodr_bits < 0) 323*20ffac27SDaniel Baluta return lodr_bits; 324*20ffac27SDaniel Baluta 325*20ffac27SDaniel Baluta /* To change ODR, accel and magn must be in STDBY */ 326*20ffac27SDaniel Baluta ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, 327*20ffac27SDaniel Baluta true); 328*20ffac27SDaniel Baluta if (ret < 0) 329*20ffac27SDaniel Baluta return ret; 330*20ffac27SDaniel Baluta 331*20ffac27SDaniel Baluta odr_bits = 0; 332*20ffac27SDaniel Baluta if (device & KMX61_ACC) 333*20ffac27SDaniel Baluta odr_bits |= lodr_bits << KMX61_ACC_ODR_SHIFT; 334*20ffac27SDaniel Baluta if (device & KMX61_MAG) 335*20ffac27SDaniel Baluta odr_bits |= lodr_bits << KMX61_MAG_ODR_SHIFT; 336*20ffac27SDaniel Baluta 337*20ffac27SDaniel Baluta ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_ODCNTL, 338*20ffac27SDaniel Baluta odr_bits); 339*20ffac27SDaniel Baluta if (ret < 0) 340*20ffac27SDaniel Baluta return ret; 341*20ffac27SDaniel Baluta 342*20ffac27SDaniel Baluta return kmx61_set_mode(data, mode, KMX61_ACC | KMX61_MAG, true); 343*20ffac27SDaniel Baluta } 344*20ffac27SDaniel Baluta 345*20ffac27SDaniel Baluta static int kmx61_get_odr(struct kmx61_data *data, int *val, int *val2, 346*20ffac27SDaniel Baluta u8 device) 347*20ffac27SDaniel Baluta { int i; 348*20ffac27SDaniel Baluta u8 lodr_bits; 349*20ffac27SDaniel Baluta 350*20ffac27SDaniel Baluta if (device & KMX61_ACC) 351*20ffac27SDaniel Baluta lodr_bits = (data->odr_bits >> KMX61_ACC_ODR_SHIFT) & 352*20ffac27SDaniel Baluta KMX61_ACC_ODR_MASK; 353*20ffac27SDaniel Baluta else if (device & KMX61_MAG) 354*20ffac27SDaniel Baluta lodr_bits = (data->odr_bits >> KMX61_MAG_ODR_SHIFT) & 355*20ffac27SDaniel Baluta KMX61_MAG_ODR_MASK; 356*20ffac27SDaniel Baluta else 357*20ffac27SDaniel Baluta return -EINVAL; 358*20ffac27SDaniel Baluta 359*20ffac27SDaniel Baluta for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++) 360*20ffac27SDaniel Baluta if (lodr_bits == kmx61_samp_freq_table[i].odr_bits) { 361*20ffac27SDaniel Baluta *val = kmx61_samp_freq_table[i].val; 362*20ffac27SDaniel Baluta *val2 = kmx61_samp_freq_table[i].val2; 363*20ffac27SDaniel Baluta return 0; 364*20ffac27SDaniel Baluta } 365*20ffac27SDaniel Baluta return -EINVAL; 366*20ffac27SDaniel Baluta } 367*20ffac27SDaniel Baluta 368*20ffac27SDaniel Baluta static int kmx61_set_range(struct kmx61_data *data, u8 range) 369*20ffac27SDaniel Baluta { 370*20ffac27SDaniel Baluta int ret; 371*20ffac27SDaniel Baluta 372*20ffac27SDaniel Baluta ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_CTRL1); 373*20ffac27SDaniel Baluta if (ret < 0) { 374*20ffac27SDaniel Baluta dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); 375*20ffac27SDaniel Baluta return ret; 376*20ffac27SDaniel Baluta } 377*20ffac27SDaniel Baluta 378*20ffac27SDaniel Baluta ret &= ~KMX61_REG_CTRL1_GSEL_MASK; 379*20ffac27SDaniel Baluta ret |= range & KMX61_REG_CTRL1_GSEL_MASK; 380*20ffac27SDaniel Baluta 381*20ffac27SDaniel Baluta ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_CTRL1, ret); 382*20ffac27SDaniel Baluta if (ret < 0) { 383*20ffac27SDaniel Baluta dev_err(&data->client->dev, "Error writing reg_ctrl1\n"); 384*20ffac27SDaniel Baluta return ret; 385*20ffac27SDaniel Baluta } 386*20ffac27SDaniel Baluta 387*20ffac27SDaniel Baluta data->range = range; 388*20ffac27SDaniel Baluta 389*20ffac27SDaniel Baluta return 0; 390*20ffac27SDaniel Baluta } 391*20ffac27SDaniel Baluta 392*20ffac27SDaniel Baluta static int kmx61_set_scale(struct kmx61_data *data, u16 uscale) 393*20ffac27SDaniel Baluta { 394*20ffac27SDaniel Baluta int ret, i; 395*20ffac27SDaniel Baluta u8 mode; 396*20ffac27SDaniel Baluta 397*20ffac27SDaniel Baluta for (i = 0; i < ARRAY_SIZE(kmx61_uscale_table); i++) { 398*20ffac27SDaniel Baluta if (kmx61_uscale_table[i] == uscale) { 399*20ffac27SDaniel Baluta ret = kmx61_get_mode(data, &mode, 400*20ffac27SDaniel Baluta KMX61_ACC | KMX61_MAG); 401*20ffac27SDaniel Baluta if (ret < 0) 402*20ffac27SDaniel Baluta return ret; 403*20ffac27SDaniel Baluta 404*20ffac27SDaniel Baluta ret = kmx61_set_mode(data, KMX61_ALL_STBY, 405*20ffac27SDaniel Baluta KMX61_ACC | KMX61_MAG, true); 406*20ffac27SDaniel Baluta if (ret < 0) 407*20ffac27SDaniel Baluta return ret; 408*20ffac27SDaniel Baluta 409*20ffac27SDaniel Baluta ret = kmx61_set_range(data, i); 410*20ffac27SDaniel Baluta if (ret < 0) 411*20ffac27SDaniel Baluta return ret; 412*20ffac27SDaniel Baluta 413*20ffac27SDaniel Baluta return kmx61_set_mode(data, mode, 414*20ffac27SDaniel Baluta KMX61_ACC | KMX61_MAG, true); 415*20ffac27SDaniel Baluta } 416*20ffac27SDaniel Baluta } 417*20ffac27SDaniel Baluta return -EINVAL; 418*20ffac27SDaniel Baluta } 419*20ffac27SDaniel Baluta 420*20ffac27SDaniel Baluta static int kmx61_chip_init(struct kmx61_data *data) 421*20ffac27SDaniel Baluta { 422*20ffac27SDaniel Baluta int ret; 423*20ffac27SDaniel Baluta 424*20ffac27SDaniel Baluta ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_WHO_AM_I); 425*20ffac27SDaniel Baluta if (ret < 0) { 426*20ffac27SDaniel Baluta dev_err(&data->client->dev, "Error reading who_am_i\n"); 427*20ffac27SDaniel Baluta return ret; 428*20ffac27SDaniel Baluta } 429*20ffac27SDaniel Baluta 430*20ffac27SDaniel Baluta if (ret != KMX61_CHIP_ID) { 431*20ffac27SDaniel Baluta dev_err(&data->client->dev, 432*20ffac27SDaniel Baluta "Wrong chip id, got %x expected %x\n", 433*20ffac27SDaniel Baluta ret, KMX61_CHIP_ID); 434*20ffac27SDaniel Baluta return -EINVAL; 435*20ffac27SDaniel Baluta } 436*20ffac27SDaniel Baluta 437*20ffac27SDaniel Baluta /* set accel 12bit, 4g range */ 438*20ffac27SDaniel Baluta ret = kmx61_set_range(data, KMX61_RANGE_4G); 439*20ffac27SDaniel Baluta if (ret < 0) 440*20ffac27SDaniel Baluta return ret; 441*20ffac27SDaniel Baluta 442*20ffac27SDaniel Baluta ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_ODCNTL); 443*20ffac27SDaniel Baluta if (ret < 0) { 444*20ffac27SDaniel Baluta dev_err(&data->client->dev, "Error reading reg_odcntl\n"); 445*20ffac27SDaniel Baluta return ret; 446*20ffac27SDaniel Baluta } 447*20ffac27SDaniel Baluta data->odr_bits = ret; 448*20ffac27SDaniel Baluta 449*20ffac27SDaniel Baluta /* set acc/magn to OPERATION mode */ 450*20ffac27SDaniel Baluta ret = kmx61_set_mode(data, 0, KMX61_ACC | KMX61_MAG, true); 451*20ffac27SDaniel Baluta if (ret < 0) 452*20ffac27SDaniel Baluta return ret; 453*20ffac27SDaniel Baluta 454*20ffac27SDaniel Baluta return 0; 455*20ffac27SDaniel Baluta } 456*20ffac27SDaniel Baluta 457*20ffac27SDaniel Baluta static int kmx61_read_measurement(struct kmx61_data *data, u8 base, u8 offset) 458*20ffac27SDaniel Baluta { 459*20ffac27SDaniel Baluta int ret; 460*20ffac27SDaniel Baluta u8 reg = base + offset * 2; 461*20ffac27SDaniel Baluta 462*20ffac27SDaniel Baluta ret = i2c_smbus_read_word_data(data->client, reg); 463*20ffac27SDaniel Baluta if (ret < 0) 464*20ffac27SDaniel Baluta dev_err(&data->client->dev, "failed to read reg at %x\n", reg); 465*20ffac27SDaniel Baluta 466*20ffac27SDaniel Baluta return ret; 467*20ffac27SDaniel Baluta } 468*20ffac27SDaniel Baluta 469*20ffac27SDaniel Baluta static int kmx61_read_raw(struct iio_dev *indio_dev, 470*20ffac27SDaniel Baluta struct iio_chan_spec const *chan, int *val, 471*20ffac27SDaniel Baluta int *val2, long mask) 472*20ffac27SDaniel Baluta { 473*20ffac27SDaniel Baluta int ret; 474*20ffac27SDaniel Baluta u8 base_reg; 475*20ffac27SDaniel Baluta struct kmx61_data *data = kmx61_get_data(indio_dev); 476*20ffac27SDaniel Baluta 477*20ffac27SDaniel Baluta switch (mask) { 478*20ffac27SDaniel Baluta case IIO_CHAN_INFO_RAW: 479*20ffac27SDaniel Baluta switch (chan->type) { 480*20ffac27SDaniel Baluta case IIO_ACCEL: 481*20ffac27SDaniel Baluta base_reg = KMX61_ACC_XOUT_L; 482*20ffac27SDaniel Baluta break; 483*20ffac27SDaniel Baluta case IIO_MAGN: 484*20ffac27SDaniel Baluta base_reg = KMX61_MAG_XOUT_L; 485*20ffac27SDaniel Baluta break; 486*20ffac27SDaniel Baluta default: 487*20ffac27SDaniel Baluta return -EINVAL; 488*20ffac27SDaniel Baluta } 489*20ffac27SDaniel Baluta mutex_lock(&data->lock); 490*20ffac27SDaniel Baluta 491*20ffac27SDaniel Baluta ret = kmx61_read_measurement(data, base_reg, chan->scan_index); 492*20ffac27SDaniel Baluta if (ret < 0) { 493*20ffac27SDaniel Baluta mutex_unlock(&data->lock); 494*20ffac27SDaniel Baluta return ret; 495*20ffac27SDaniel Baluta } 496*20ffac27SDaniel Baluta *val = sign_extend32(ret >> chan->scan_type.shift, 497*20ffac27SDaniel Baluta chan->scan_type.realbits - 1); 498*20ffac27SDaniel Baluta 499*20ffac27SDaniel Baluta mutex_unlock(&data->lock); 500*20ffac27SDaniel Baluta return IIO_VAL_INT; 501*20ffac27SDaniel Baluta case IIO_CHAN_INFO_SCALE: 502*20ffac27SDaniel Baluta switch (chan->type) { 503*20ffac27SDaniel Baluta case IIO_ACCEL: 504*20ffac27SDaniel Baluta *val = 0; 505*20ffac27SDaniel Baluta *val2 = kmx61_uscale_table[data->range]; 506*20ffac27SDaniel Baluta return IIO_VAL_INT_PLUS_MICRO; 507*20ffac27SDaniel Baluta case IIO_MAGN: 508*20ffac27SDaniel Baluta /* 14 bits res, 1465 microGauss per magn count */ 509*20ffac27SDaniel Baluta *val = 0; 510*20ffac27SDaniel Baluta *val2 = 1465; 511*20ffac27SDaniel Baluta return IIO_VAL_INT_PLUS_MICRO; 512*20ffac27SDaniel Baluta default: 513*20ffac27SDaniel Baluta return -EINVAL; 514*20ffac27SDaniel Baluta } 515*20ffac27SDaniel Baluta case IIO_CHAN_INFO_SAMP_FREQ: 516*20ffac27SDaniel Baluta if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN) 517*20ffac27SDaniel Baluta return -EINVAL; 518*20ffac27SDaniel Baluta 519*20ffac27SDaniel Baluta mutex_lock(&data->lock); 520*20ffac27SDaniel Baluta ret = kmx61_get_odr(data, val, val2, chan->address); 521*20ffac27SDaniel Baluta mutex_unlock(&data->lock); 522*20ffac27SDaniel Baluta if (ret) 523*20ffac27SDaniel Baluta return -EINVAL; 524*20ffac27SDaniel Baluta return IIO_VAL_INT_PLUS_MICRO; 525*20ffac27SDaniel Baluta } 526*20ffac27SDaniel Baluta return -EINVAL; 527*20ffac27SDaniel Baluta } 528*20ffac27SDaniel Baluta 529*20ffac27SDaniel Baluta static int kmx61_write_raw(struct iio_dev *indio_dev, 530*20ffac27SDaniel Baluta struct iio_chan_spec const *chan, int val, 531*20ffac27SDaniel Baluta int val2, long mask) 532*20ffac27SDaniel Baluta { 533*20ffac27SDaniel Baluta int ret; 534*20ffac27SDaniel Baluta struct kmx61_data *data = kmx61_get_data(indio_dev); 535*20ffac27SDaniel Baluta 536*20ffac27SDaniel Baluta switch (mask) { 537*20ffac27SDaniel Baluta case IIO_CHAN_INFO_SAMP_FREQ: 538*20ffac27SDaniel Baluta if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN) 539*20ffac27SDaniel Baluta return -EINVAL; 540*20ffac27SDaniel Baluta 541*20ffac27SDaniel Baluta mutex_lock(&data->lock); 542*20ffac27SDaniel Baluta ret = kmx61_set_odr(data, val, val2, chan->address); 543*20ffac27SDaniel Baluta mutex_unlock(&data->lock); 544*20ffac27SDaniel Baluta return ret; 545*20ffac27SDaniel Baluta case IIO_CHAN_INFO_SCALE: 546*20ffac27SDaniel Baluta switch (chan->type) { 547*20ffac27SDaniel Baluta case IIO_ACCEL: 548*20ffac27SDaniel Baluta if (val != 0) 549*20ffac27SDaniel Baluta return -EINVAL; 550*20ffac27SDaniel Baluta mutex_lock(&data->lock); 551*20ffac27SDaniel Baluta ret = kmx61_set_scale(data, val2); 552*20ffac27SDaniel Baluta mutex_unlock(&data->lock); 553*20ffac27SDaniel Baluta return ret; 554*20ffac27SDaniel Baluta default: 555*20ffac27SDaniel Baluta return -EINVAL; 556*20ffac27SDaniel Baluta } 557*20ffac27SDaniel Baluta default: 558*20ffac27SDaniel Baluta return -EINVAL; 559*20ffac27SDaniel Baluta } 560*20ffac27SDaniel Baluta } 561*20ffac27SDaniel Baluta 562*20ffac27SDaniel Baluta static const struct iio_info kmx61_acc_info = { 563*20ffac27SDaniel Baluta .driver_module = THIS_MODULE, 564*20ffac27SDaniel Baluta .read_raw = kmx61_read_raw, 565*20ffac27SDaniel Baluta .write_raw = kmx61_write_raw, 566*20ffac27SDaniel Baluta .attrs = &kmx61_acc_attribute_group, 567*20ffac27SDaniel Baluta }; 568*20ffac27SDaniel Baluta 569*20ffac27SDaniel Baluta static const struct iio_info kmx61_mag_info = { 570*20ffac27SDaniel Baluta .driver_module = THIS_MODULE, 571*20ffac27SDaniel Baluta .read_raw = kmx61_read_raw, 572*20ffac27SDaniel Baluta .write_raw = kmx61_write_raw, 573*20ffac27SDaniel Baluta .attrs = &kmx61_mag_attribute_group, 574*20ffac27SDaniel Baluta }; 575*20ffac27SDaniel Baluta 576*20ffac27SDaniel Baluta static struct iio_dev *kmx61_indiodev_setup(struct kmx61_data *data, 577*20ffac27SDaniel Baluta const struct iio_info *info, 578*20ffac27SDaniel Baluta const struct iio_chan_spec *chan, 579*20ffac27SDaniel Baluta int num_channels, 580*20ffac27SDaniel Baluta const char *name) 581*20ffac27SDaniel Baluta { 582*20ffac27SDaniel Baluta struct iio_dev *indio_dev; 583*20ffac27SDaniel Baluta 584*20ffac27SDaniel Baluta indio_dev = devm_iio_device_alloc(&data->client->dev, sizeof(data)); 585*20ffac27SDaniel Baluta if (!indio_dev) 586*20ffac27SDaniel Baluta return ERR_PTR(-ENOMEM); 587*20ffac27SDaniel Baluta 588*20ffac27SDaniel Baluta kmx61_set_data(indio_dev, data); 589*20ffac27SDaniel Baluta 590*20ffac27SDaniel Baluta indio_dev->dev.parent = &data->client->dev; 591*20ffac27SDaniel Baluta indio_dev->channels = chan; 592*20ffac27SDaniel Baluta indio_dev->num_channels = num_channels; 593*20ffac27SDaniel Baluta indio_dev->name = name; 594*20ffac27SDaniel Baluta indio_dev->modes = INDIO_DIRECT_MODE; 595*20ffac27SDaniel Baluta indio_dev->info = info; 596*20ffac27SDaniel Baluta 597*20ffac27SDaniel Baluta return indio_dev; 598*20ffac27SDaniel Baluta } 599*20ffac27SDaniel Baluta 600*20ffac27SDaniel Baluta static int kmx61_probe(struct i2c_client *client, 601*20ffac27SDaniel Baluta const struct i2c_device_id *id) 602*20ffac27SDaniel Baluta { 603*20ffac27SDaniel Baluta int ret; 604*20ffac27SDaniel Baluta struct kmx61_data *data; 605*20ffac27SDaniel Baluta const char *name = NULL; 606*20ffac27SDaniel Baluta 607*20ffac27SDaniel Baluta data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); 608*20ffac27SDaniel Baluta if (!data) 609*20ffac27SDaniel Baluta return -ENOMEM; 610*20ffac27SDaniel Baluta 611*20ffac27SDaniel Baluta i2c_set_clientdata(client, data); 612*20ffac27SDaniel Baluta data->client = client; 613*20ffac27SDaniel Baluta 614*20ffac27SDaniel Baluta mutex_init(&data->lock); 615*20ffac27SDaniel Baluta 616*20ffac27SDaniel Baluta data->acc_indio_dev = 617*20ffac27SDaniel Baluta kmx61_indiodev_setup(data, &kmx61_acc_info, 618*20ffac27SDaniel Baluta kmx61_acc_channels, 619*20ffac27SDaniel Baluta ARRAY_SIZE(kmx61_acc_channels), 620*20ffac27SDaniel Baluta name); 621*20ffac27SDaniel Baluta if (IS_ERR(data->acc_indio_dev)) 622*20ffac27SDaniel Baluta return PTR_ERR(data->acc_indio_dev); 623*20ffac27SDaniel Baluta 624*20ffac27SDaniel Baluta data->mag_indio_dev = 625*20ffac27SDaniel Baluta kmx61_indiodev_setup(data, &kmx61_mag_info, 626*20ffac27SDaniel Baluta kmx61_mag_channels, 627*20ffac27SDaniel Baluta ARRAY_SIZE(kmx61_mag_channels), 628*20ffac27SDaniel Baluta name); 629*20ffac27SDaniel Baluta if (IS_ERR(data->mag_indio_dev)) 630*20ffac27SDaniel Baluta return PTR_ERR(data->mag_indio_dev); 631*20ffac27SDaniel Baluta 632*20ffac27SDaniel Baluta ret = kmx61_chip_init(data); 633*20ffac27SDaniel Baluta if (ret < 0) 634*20ffac27SDaniel Baluta return ret; 635*20ffac27SDaniel Baluta 636*20ffac27SDaniel Baluta ret = iio_device_register(data->acc_indio_dev); 637*20ffac27SDaniel Baluta if (ret < 0) { 638*20ffac27SDaniel Baluta dev_err(&client->dev, "Failed to register acc iio device\n"); 639*20ffac27SDaniel Baluta goto err_chip_uninit; 640*20ffac27SDaniel Baluta } 641*20ffac27SDaniel Baluta 642*20ffac27SDaniel Baluta ret = iio_device_register(data->mag_indio_dev); 643*20ffac27SDaniel Baluta if (ret < 0) { 644*20ffac27SDaniel Baluta dev_err(&client->dev, "Failed to register mag iio device\n"); 645*20ffac27SDaniel Baluta goto err_iio_unregister; 646*20ffac27SDaniel Baluta } 647*20ffac27SDaniel Baluta 648*20ffac27SDaniel Baluta return 0; 649*20ffac27SDaniel Baluta 650*20ffac27SDaniel Baluta err_iio_unregister: 651*20ffac27SDaniel Baluta iio_device_unregister(data->acc_indio_dev); 652*20ffac27SDaniel Baluta err_chip_uninit: 653*20ffac27SDaniel Baluta kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true); 654*20ffac27SDaniel Baluta return ret; 655*20ffac27SDaniel Baluta } 656*20ffac27SDaniel Baluta 657*20ffac27SDaniel Baluta static int kmx61_remove(struct i2c_client *client) 658*20ffac27SDaniel Baluta { 659*20ffac27SDaniel Baluta struct kmx61_data *data = i2c_get_clientdata(client); 660*20ffac27SDaniel Baluta 661*20ffac27SDaniel Baluta iio_device_unregister(data->acc_indio_dev); 662*20ffac27SDaniel Baluta iio_device_unregister(data->mag_indio_dev); 663*20ffac27SDaniel Baluta 664*20ffac27SDaniel Baluta mutex_lock(&data->lock); 665*20ffac27SDaniel Baluta kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true); 666*20ffac27SDaniel Baluta mutex_unlock(&data->lock); 667*20ffac27SDaniel Baluta 668*20ffac27SDaniel Baluta return 0; 669*20ffac27SDaniel Baluta } 670*20ffac27SDaniel Baluta 671*20ffac27SDaniel Baluta static const struct i2c_device_id kmx61_id[] = { 672*20ffac27SDaniel Baluta {"kmx611021", 0}, 673*20ffac27SDaniel Baluta {} 674*20ffac27SDaniel Baluta }; 675*20ffac27SDaniel Baluta 676*20ffac27SDaniel Baluta MODULE_DEVICE_TABLE(i2c, kmx61_id); 677*20ffac27SDaniel Baluta 678*20ffac27SDaniel Baluta static struct i2c_driver kmx61_driver = { 679*20ffac27SDaniel Baluta .driver = { 680*20ffac27SDaniel Baluta .name = KMX61_DRV_NAME, 681*20ffac27SDaniel Baluta }, 682*20ffac27SDaniel Baluta .probe = kmx61_probe, 683*20ffac27SDaniel Baluta .remove = kmx61_remove, 684*20ffac27SDaniel Baluta .id_table = kmx61_id, 685*20ffac27SDaniel Baluta }; 686*20ffac27SDaniel Baluta 687*20ffac27SDaniel Baluta module_i2c_driver(kmx61_driver); 688*20ffac27SDaniel Baluta 689*20ffac27SDaniel Baluta MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>"); 690*20ffac27SDaniel Baluta MODULE_DESCRIPTION("KMX61 accelerometer/magnetometer driver"); 691*20ffac27SDaniel Baluta MODULE_LICENSE("GPL v2"); 692