1abeb6b1eSDaniel Baluta /* 2abeb6b1eSDaniel Baluta * MMC35240 - MEMSIC 3-axis Magnetic Sensor 3abeb6b1eSDaniel Baluta * 4abeb6b1eSDaniel Baluta * Copyright (c) 2015, Intel Corporation. 5abeb6b1eSDaniel Baluta * 6abeb6b1eSDaniel Baluta * This file is subject to the terms and conditions of version 2 of 7abeb6b1eSDaniel Baluta * the GNU General Public License. See the file COPYING in the main 8abeb6b1eSDaniel Baluta * directory of this archive for more details. 9abeb6b1eSDaniel Baluta * 10abeb6b1eSDaniel Baluta * IIO driver for MMC35240 (7-bit I2C slave address 0x30). 11abeb6b1eSDaniel Baluta * 12abeb6b1eSDaniel Baluta * TODO: offset, ACPI, continuous measurement mode, PM 13abeb6b1eSDaniel Baluta */ 14abeb6b1eSDaniel Baluta 15abeb6b1eSDaniel Baluta #include <linux/module.h> 16abeb6b1eSDaniel Baluta #include <linux/init.h> 17abeb6b1eSDaniel Baluta #include <linux/i2c.h> 18abeb6b1eSDaniel Baluta #include <linux/delay.h> 19abeb6b1eSDaniel Baluta #include <linux/regmap.h> 20d11715f0SDaniel Baluta #include <linux/acpi.h> 21553a776bSDaniel Baluta #include <linux/pm.h> 22abeb6b1eSDaniel Baluta 23abeb6b1eSDaniel Baluta #include <linux/iio/iio.h> 24abeb6b1eSDaniel Baluta #include <linux/iio/sysfs.h> 25abeb6b1eSDaniel Baluta 26abeb6b1eSDaniel Baluta #define MMC35240_DRV_NAME "mmc35240" 27abeb6b1eSDaniel Baluta #define MMC35240_REGMAP_NAME "mmc35240_regmap" 28abeb6b1eSDaniel Baluta 29abeb6b1eSDaniel Baluta #define MMC35240_REG_XOUT_L 0x00 30abeb6b1eSDaniel Baluta #define MMC35240_REG_XOUT_H 0x01 31abeb6b1eSDaniel Baluta #define MMC35240_REG_YOUT_L 0x02 32abeb6b1eSDaniel Baluta #define MMC35240_REG_YOUT_H 0x03 33abeb6b1eSDaniel Baluta #define MMC35240_REG_ZOUT_L 0x04 34abeb6b1eSDaniel Baluta #define MMC35240_REG_ZOUT_H 0x05 35abeb6b1eSDaniel Baluta 36abeb6b1eSDaniel Baluta #define MMC35240_REG_STATUS 0x06 37abeb6b1eSDaniel Baluta #define MMC35240_REG_CTRL0 0x07 38abeb6b1eSDaniel Baluta #define MMC35240_REG_CTRL1 0x08 39abeb6b1eSDaniel Baluta 40abeb6b1eSDaniel Baluta #define MMC35240_REG_ID 0x20 41abeb6b1eSDaniel Baluta 42abeb6b1eSDaniel Baluta #define MMC35240_STATUS_MEAS_DONE_BIT BIT(0) 43abeb6b1eSDaniel Baluta 44abeb6b1eSDaniel Baluta #define MMC35240_CTRL0_REFILL_BIT BIT(7) 45abeb6b1eSDaniel Baluta #define MMC35240_CTRL0_RESET_BIT BIT(6) 46abeb6b1eSDaniel Baluta #define MMC35240_CTRL0_SET_BIT BIT(5) 47abeb6b1eSDaniel Baluta #define MMC35240_CTRL0_CMM_BIT BIT(1) 48abeb6b1eSDaniel Baluta #define MMC35240_CTRL0_TM_BIT BIT(0) 49abeb6b1eSDaniel Baluta 50abeb6b1eSDaniel Baluta /* output resolution bits */ 51abeb6b1eSDaniel Baluta #define MMC35240_CTRL1_BW0_BIT BIT(0) 52abeb6b1eSDaniel Baluta #define MMC35240_CTRL1_BW1_BIT BIT(1) 53abeb6b1eSDaniel Baluta 54abeb6b1eSDaniel Baluta #define MMC35240_CTRL1_BW_MASK (MMC35240_CTRL1_BW0_BIT | \ 55abeb6b1eSDaniel Baluta MMC35240_CTRL1_BW1_BIT) 56abeb6b1eSDaniel Baluta #define MMC35240_CTRL1_BW_SHIFT 0 57abeb6b1eSDaniel Baluta 58abeb6b1eSDaniel Baluta #define MMC35240_WAIT_CHARGE_PUMP 50000 /* us */ 59abeb6b1eSDaniel Baluta #define MMC53240_WAIT_SET_RESET 1000 /* us */ 60abeb6b1eSDaniel Baluta 61abeb6b1eSDaniel Baluta enum mmc35240_resolution { 62abeb6b1eSDaniel Baluta MMC35240_16_BITS_SLOW = 0, /* 100 Hz */ 63abeb6b1eSDaniel Baluta MMC35240_16_BITS_FAST, /* 200 Hz */ 64abeb6b1eSDaniel Baluta MMC35240_14_BITS, /* 333 Hz */ 65abeb6b1eSDaniel Baluta MMC35240_12_BITS, /* 666 Hz */ 66abeb6b1eSDaniel Baluta }; 67abeb6b1eSDaniel Baluta 68abeb6b1eSDaniel Baluta enum mmc35240_axis { 69abeb6b1eSDaniel Baluta AXIS_X = 0, 70abeb6b1eSDaniel Baluta AXIS_Y, 71abeb6b1eSDaniel Baluta AXIS_Z, 72abeb6b1eSDaniel Baluta }; 73abeb6b1eSDaniel Baluta 74abeb6b1eSDaniel Baluta static const struct { 75abeb6b1eSDaniel Baluta int sens[3]; /* sensitivity per X, Y, Z axis */ 76abeb6b1eSDaniel Baluta int nfo; /* null field output */ 77abeb6b1eSDaniel Baluta } mmc35240_props_table[] = { 78abeb6b1eSDaniel Baluta /* 16 bits, 100Hz ODR */ 79abeb6b1eSDaniel Baluta { 80abeb6b1eSDaniel Baluta {1024, 1024, 770}, 81abeb6b1eSDaniel Baluta 32768, 82abeb6b1eSDaniel Baluta }, 83abeb6b1eSDaniel Baluta /* 16 bits, 200Hz ODR */ 84abeb6b1eSDaniel Baluta { 85abeb6b1eSDaniel Baluta {1024, 1024, 770}, 86abeb6b1eSDaniel Baluta 32768, 87abeb6b1eSDaniel Baluta }, 88abeb6b1eSDaniel Baluta /* 14 bits, 333Hz ODR */ 89abeb6b1eSDaniel Baluta { 90abeb6b1eSDaniel Baluta {256, 256, 193}, 91abeb6b1eSDaniel Baluta 8192, 92abeb6b1eSDaniel Baluta }, 93abeb6b1eSDaniel Baluta /* 12 bits, 666Hz ODR */ 94abeb6b1eSDaniel Baluta { 95abeb6b1eSDaniel Baluta {64, 64, 48}, 96abeb6b1eSDaniel Baluta 2048, 97abeb6b1eSDaniel Baluta }, 98abeb6b1eSDaniel Baluta }; 99abeb6b1eSDaniel Baluta 100abeb6b1eSDaniel Baluta struct mmc35240_data { 101abeb6b1eSDaniel Baluta struct i2c_client *client; 102abeb6b1eSDaniel Baluta struct mutex mutex; 103abeb6b1eSDaniel Baluta struct regmap *regmap; 104abeb6b1eSDaniel Baluta enum mmc35240_resolution res; 105abeb6b1eSDaniel Baluta }; 106abeb6b1eSDaniel Baluta 107abeb6b1eSDaniel Baluta static const int mmc35240_samp_freq[] = {100, 200, 333, 666}; 108abeb6b1eSDaniel Baluta 109abeb6b1eSDaniel Baluta static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("100 200 333 666"); 110abeb6b1eSDaniel Baluta 111abeb6b1eSDaniel Baluta #define MMC35240_CHANNEL(_axis) { \ 112abeb6b1eSDaniel Baluta .type = IIO_MAGN, \ 113abeb6b1eSDaniel Baluta .modified = 1, \ 114abeb6b1eSDaniel Baluta .channel2 = IIO_MOD_ ## _axis, \ 115abeb6b1eSDaniel Baluta .address = AXIS_ ## _axis, \ 116c2890547SDaniel Baluta .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 117c2890547SDaniel Baluta .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ 118c2890547SDaniel Baluta BIT(IIO_CHAN_INFO_SCALE), \ 119abeb6b1eSDaniel Baluta } 120abeb6b1eSDaniel Baluta 121abeb6b1eSDaniel Baluta static const struct iio_chan_spec mmc35240_channels[] = { 122abeb6b1eSDaniel Baluta MMC35240_CHANNEL(X), 123abeb6b1eSDaniel Baluta MMC35240_CHANNEL(Y), 124abeb6b1eSDaniel Baluta MMC35240_CHANNEL(Z), 125abeb6b1eSDaniel Baluta }; 126abeb6b1eSDaniel Baluta 127abeb6b1eSDaniel Baluta static struct attribute *mmc35240_attributes[] = { 128abeb6b1eSDaniel Baluta &iio_const_attr_sampling_frequency_available.dev_attr.attr, 129bd35a214SDaniel Baluta NULL 130abeb6b1eSDaniel Baluta }; 131abeb6b1eSDaniel Baluta 132abeb6b1eSDaniel Baluta static const struct attribute_group mmc35240_attribute_group = { 133abeb6b1eSDaniel Baluta .attrs = mmc35240_attributes, 134abeb6b1eSDaniel Baluta }; 135abeb6b1eSDaniel Baluta 136abeb6b1eSDaniel Baluta static int mmc35240_get_samp_freq_index(struct mmc35240_data *data, 137abeb6b1eSDaniel Baluta int val, int val2) 138abeb6b1eSDaniel Baluta { 139abeb6b1eSDaniel Baluta int i; 140abeb6b1eSDaniel Baluta 141abeb6b1eSDaniel Baluta for (i = 0; i < ARRAY_SIZE(mmc35240_samp_freq); i++) 142abeb6b1eSDaniel Baluta if (mmc35240_samp_freq[i] == val) 143abeb6b1eSDaniel Baluta return i; 144abeb6b1eSDaniel Baluta return -EINVAL; 145abeb6b1eSDaniel Baluta } 146abeb6b1eSDaniel Baluta 147abeb6b1eSDaniel Baluta static int mmc35240_hw_set(struct mmc35240_data *data, bool set) 148abeb6b1eSDaniel Baluta { 149abeb6b1eSDaniel Baluta int ret; 150abeb6b1eSDaniel Baluta u8 coil_bit; 151abeb6b1eSDaniel Baluta 152abeb6b1eSDaniel Baluta /* 153abeb6b1eSDaniel Baluta * Recharge the capacitor at VCAP pin, requested to be issued 154abeb6b1eSDaniel Baluta * before a SET/RESET command. 155abeb6b1eSDaniel Baluta */ 156abeb6b1eSDaniel Baluta ret = regmap_update_bits(data->regmap, MMC35240_REG_CTRL0, 157abeb6b1eSDaniel Baluta MMC35240_CTRL0_REFILL_BIT, 158abeb6b1eSDaniel Baluta MMC35240_CTRL0_REFILL_BIT); 159abeb6b1eSDaniel Baluta if (ret < 0) 160abeb6b1eSDaniel Baluta return ret; 161abeb6b1eSDaniel Baluta usleep_range(MMC35240_WAIT_CHARGE_PUMP, MMC35240_WAIT_CHARGE_PUMP + 1); 162abeb6b1eSDaniel Baluta 163abeb6b1eSDaniel Baluta if (set) 164abeb6b1eSDaniel Baluta coil_bit = MMC35240_CTRL0_SET_BIT; 165abeb6b1eSDaniel Baluta else 166abeb6b1eSDaniel Baluta coil_bit = MMC35240_CTRL0_RESET_BIT; 167abeb6b1eSDaniel Baluta 168abeb6b1eSDaniel Baluta return regmap_update_bits(data->regmap, MMC35240_REG_CTRL0, 169abeb6b1eSDaniel Baluta MMC35240_CTRL0_REFILL_BIT, 170abeb6b1eSDaniel Baluta coil_bit); 171abeb6b1eSDaniel Baluta } 172abeb6b1eSDaniel Baluta 173abeb6b1eSDaniel Baluta static int mmc35240_init(struct mmc35240_data *data) 174abeb6b1eSDaniel Baluta { 175abeb6b1eSDaniel Baluta int ret; 176abeb6b1eSDaniel Baluta unsigned int reg_id; 177abeb6b1eSDaniel Baluta 178abeb6b1eSDaniel Baluta ret = regmap_read(data->regmap, MMC35240_REG_ID, ®_id); 179abeb6b1eSDaniel Baluta if (ret < 0) { 180abeb6b1eSDaniel Baluta dev_err(&data->client->dev, "Error reading product id\n"); 181abeb6b1eSDaniel Baluta return ret; 182abeb6b1eSDaniel Baluta } 183abeb6b1eSDaniel Baluta 184abeb6b1eSDaniel Baluta dev_dbg(&data->client->dev, "MMC35240 chip id %x\n", reg_id); 185abeb6b1eSDaniel Baluta 186abeb6b1eSDaniel Baluta /* 187abeb6b1eSDaniel Baluta * make sure we restore sensor characteristics, by doing 188abeb6b1eSDaniel Baluta * a RESET/SET sequence 189abeb6b1eSDaniel Baluta */ 190abeb6b1eSDaniel Baluta ret = mmc35240_hw_set(data, false); 191abeb6b1eSDaniel Baluta if (ret < 0) 192abeb6b1eSDaniel Baluta return ret; 193abeb6b1eSDaniel Baluta usleep_range(MMC53240_WAIT_SET_RESET, MMC53240_WAIT_SET_RESET + 1); 194abeb6b1eSDaniel Baluta 195abeb6b1eSDaniel Baluta ret = mmc35240_hw_set(data, true); 196abeb6b1eSDaniel Baluta if (ret < 0) 197abeb6b1eSDaniel Baluta return ret; 198abeb6b1eSDaniel Baluta 199abeb6b1eSDaniel Baluta /* set default sampling frequency */ 200abeb6b1eSDaniel Baluta return regmap_update_bits(data->regmap, MMC35240_REG_CTRL1, 201abeb6b1eSDaniel Baluta MMC35240_CTRL1_BW_MASK, 202abeb6b1eSDaniel Baluta data->res << MMC35240_CTRL1_BW_SHIFT); 203abeb6b1eSDaniel Baluta } 204abeb6b1eSDaniel Baluta 205abeb6b1eSDaniel Baluta static int mmc35240_take_measurement(struct mmc35240_data *data) 206abeb6b1eSDaniel Baluta { 207abeb6b1eSDaniel Baluta int ret, tries = 100; 208abeb6b1eSDaniel Baluta unsigned int reg_status; 209abeb6b1eSDaniel Baluta 210abeb6b1eSDaniel Baluta ret = regmap_write(data->regmap, MMC35240_REG_CTRL0, 211abeb6b1eSDaniel Baluta MMC35240_CTRL0_TM_BIT); 212abeb6b1eSDaniel Baluta if (ret < 0) 213abeb6b1eSDaniel Baluta return ret; 214abeb6b1eSDaniel Baluta 215abeb6b1eSDaniel Baluta while (tries-- > 0) { 216abeb6b1eSDaniel Baluta ret = regmap_read(data->regmap, MMC35240_REG_STATUS, 217abeb6b1eSDaniel Baluta ®_status); 218abeb6b1eSDaniel Baluta if (ret < 0) 219abeb6b1eSDaniel Baluta return ret; 220abeb6b1eSDaniel Baluta if (reg_status & MMC35240_STATUS_MEAS_DONE_BIT) 221abeb6b1eSDaniel Baluta break; 222787f55c4SDaniel Baluta /* minimum wait time to complete measurement is 10 ms */ 223787f55c4SDaniel Baluta usleep_range(10000, 11000); 224abeb6b1eSDaniel Baluta } 225abeb6b1eSDaniel Baluta 226abeb6b1eSDaniel Baluta if (tries < 0) { 227abeb6b1eSDaniel Baluta dev_err(&data->client->dev, "data not ready\n"); 228abeb6b1eSDaniel Baluta return -EIO; 229abeb6b1eSDaniel Baluta } 230abeb6b1eSDaniel Baluta 231abeb6b1eSDaniel Baluta return 0; 232abeb6b1eSDaniel Baluta } 233abeb6b1eSDaniel Baluta 234abeb6b1eSDaniel Baluta static int mmc35240_read_measurement(struct mmc35240_data *data, __le16 buf[3]) 235abeb6b1eSDaniel Baluta { 236abeb6b1eSDaniel Baluta int ret; 237abeb6b1eSDaniel Baluta 238abeb6b1eSDaniel Baluta ret = mmc35240_take_measurement(data); 239abeb6b1eSDaniel Baluta if (ret < 0) 240abeb6b1eSDaniel Baluta return ret; 241abeb6b1eSDaniel Baluta 242abeb6b1eSDaniel Baluta return regmap_bulk_read(data->regmap, MMC35240_REG_XOUT_L, (u8 *)buf, 243abeb6b1eSDaniel Baluta 3 * sizeof(__le16)); 244abeb6b1eSDaniel Baluta } 245abeb6b1eSDaniel Baluta 246c2890547SDaniel Baluta /** 247c2890547SDaniel Baluta * mmc35240_raw_to_mgauss - convert raw readings to milli gauss. Also apply 248c2890547SDaniel Baluta compensation for output value. 249c2890547SDaniel Baluta * 250c2890547SDaniel Baluta * @data: device private data 251c2890547SDaniel Baluta * @index: axis index for which we want the conversion 252c2890547SDaniel Baluta * @buf: raw data to be converted, 2 bytes in little endian format 253c2890547SDaniel Baluta * @val: compensated output reading (unit is milli gauss) 254c2890547SDaniel Baluta * 255c2890547SDaniel Baluta * Returns: 0 in case of success, -EINVAL when @index is not valid 256c2890547SDaniel Baluta */ 257c2890547SDaniel Baluta static int mmc35240_raw_to_mgauss(struct mmc35240_data *data, int index, 258c2890547SDaniel Baluta __le16 buf[], int *val) 259abeb6b1eSDaniel Baluta { 260abeb6b1eSDaniel Baluta int raw_x, raw_y, raw_z; 261abeb6b1eSDaniel Baluta int sens_x, sens_y, sens_z; 262abeb6b1eSDaniel Baluta int nfo; 263abeb6b1eSDaniel Baluta 264abeb6b1eSDaniel Baluta raw_x = le16_to_cpu(buf[AXIS_X]); 265abeb6b1eSDaniel Baluta raw_y = le16_to_cpu(buf[AXIS_Y]); 266abeb6b1eSDaniel Baluta raw_z = le16_to_cpu(buf[AXIS_Z]); 267abeb6b1eSDaniel Baluta 268abeb6b1eSDaniel Baluta sens_x = mmc35240_props_table[data->res].sens[AXIS_X]; 269abeb6b1eSDaniel Baluta sens_y = mmc35240_props_table[data->res].sens[AXIS_Y]; 270abeb6b1eSDaniel Baluta sens_z = mmc35240_props_table[data->res].sens[AXIS_Z]; 271abeb6b1eSDaniel Baluta 272abeb6b1eSDaniel Baluta nfo = mmc35240_props_table[data->res].nfo; 273abeb6b1eSDaniel Baluta 274abeb6b1eSDaniel Baluta switch (index) { 275abeb6b1eSDaniel Baluta case AXIS_X: 276c2890547SDaniel Baluta *val = (raw_x - nfo) * 1000 / sens_x; 277abeb6b1eSDaniel Baluta break; 278abeb6b1eSDaniel Baluta case AXIS_Y: 279c2890547SDaniel Baluta *val = (raw_y - nfo) * 1000 / sens_y - 280c2890547SDaniel Baluta (raw_z - nfo) * 1000 / sens_z; 281abeb6b1eSDaniel Baluta break; 282abeb6b1eSDaniel Baluta case AXIS_Z: 283c2890547SDaniel Baluta *val = (raw_y - nfo) * 1000 / sens_y + 284c2890547SDaniel Baluta (raw_z - nfo) * 1000 / sens_z; 285abeb6b1eSDaniel Baluta break; 286abeb6b1eSDaniel Baluta default: 287abeb6b1eSDaniel Baluta return -EINVAL; 288abeb6b1eSDaniel Baluta } 289abeb6b1eSDaniel Baluta return 0; 290abeb6b1eSDaniel Baluta } 291abeb6b1eSDaniel Baluta 292abeb6b1eSDaniel Baluta static int mmc35240_read_raw(struct iio_dev *indio_dev, 293abeb6b1eSDaniel Baluta struct iio_chan_spec const *chan, int *val, 294abeb6b1eSDaniel Baluta int *val2, long mask) 295abeb6b1eSDaniel Baluta { 296abeb6b1eSDaniel Baluta struct mmc35240_data *data = iio_priv(indio_dev); 297abeb6b1eSDaniel Baluta int ret, i; 298abeb6b1eSDaniel Baluta unsigned int reg; 299abeb6b1eSDaniel Baluta __le16 buf[3]; 300abeb6b1eSDaniel Baluta 301abeb6b1eSDaniel Baluta switch (mask) { 302c2890547SDaniel Baluta case IIO_CHAN_INFO_RAW: 303abeb6b1eSDaniel Baluta mutex_lock(&data->mutex); 304abeb6b1eSDaniel Baluta ret = mmc35240_read_measurement(data, buf); 305abeb6b1eSDaniel Baluta mutex_unlock(&data->mutex); 306abeb6b1eSDaniel Baluta if (ret < 0) 307abeb6b1eSDaniel Baluta return ret; 308c2890547SDaniel Baluta ret = mmc35240_raw_to_mgauss(data, chan->address, buf, val); 309abeb6b1eSDaniel Baluta if (ret < 0) 310abeb6b1eSDaniel Baluta return ret; 311c2890547SDaniel Baluta return IIO_VAL_INT; 312c2890547SDaniel Baluta case IIO_CHAN_INFO_SCALE: 313c2890547SDaniel Baluta *val = 0; 314c2890547SDaniel Baluta *val2 = 1000; 315abeb6b1eSDaniel Baluta return IIO_VAL_INT_PLUS_MICRO; 316abeb6b1eSDaniel Baluta case IIO_CHAN_INFO_SAMP_FREQ: 317abeb6b1eSDaniel Baluta mutex_lock(&data->mutex); 318abeb6b1eSDaniel Baluta ret = regmap_read(data->regmap, MMC35240_REG_CTRL1, ®); 319abeb6b1eSDaniel Baluta mutex_unlock(&data->mutex); 320abeb6b1eSDaniel Baluta if (ret < 0) 321abeb6b1eSDaniel Baluta return ret; 322abeb6b1eSDaniel Baluta 323abeb6b1eSDaniel Baluta i = (reg & MMC35240_CTRL1_BW_MASK) >> MMC35240_CTRL1_BW_SHIFT; 3245517547bSDan Carpenter if (i < 0 || i >= ARRAY_SIZE(mmc35240_samp_freq)) 325abeb6b1eSDaniel Baluta return -EINVAL; 326abeb6b1eSDaniel Baluta 327abeb6b1eSDaniel Baluta *val = mmc35240_samp_freq[i]; 328abeb6b1eSDaniel Baluta *val2 = 0; 329abeb6b1eSDaniel Baluta return IIO_VAL_INT; 330abeb6b1eSDaniel Baluta default: 331abeb6b1eSDaniel Baluta return -EINVAL; 332abeb6b1eSDaniel Baluta } 333abeb6b1eSDaniel Baluta } 334abeb6b1eSDaniel Baluta 335abeb6b1eSDaniel Baluta static int mmc35240_write_raw(struct iio_dev *indio_dev, 336abeb6b1eSDaniel Baluta struct iio_chan_spec const *chan, int val, 337abeb6b1eSDaniel Baluta int val2, long mask) 338abeb6b1eSDaniel Baluta { 339abeb6b1eSDaniel Baluta struct mmc35240_data *data = iio_priv(indio_dev); 340abeb6b1eSDaniel Baluta int i, ret; 341abeb6b1eSDaniel Baluta 342abeb6b1eSDaniel Baluta switch (mask) { 343abeb6b1eSDaniel Baluta case IIO_CHAN_INFO_SAMP_FREQ: 344abeb6b1eSDaniel Baluta i = mmc35240_get_samp_freq_index(data, val, val2); 345abeb6b1eSDaniel Baluta if (i < 0) 346abeb6b1eSDaniel Baluta return -EINVAL; 347abeb6b1eSDaniel Baluta mutex_lock(&data->mutex); 348abeb6b1eSDaniel Baluta ret = regmap_update_bits(data->regmap, MMC35240_REG_CTRL1, 349abeb6b1eSDaniel Baluta MMC35240_CTRL1_BW_MASK, 350abeb6b1eSDaniel Baluta i << MMC35240_CTRL1_BW_SHIFT); 351abeb6b1eSDaniel Baluta mutex_unlock(&data->mutex); 352abeb6b1eSDaniel Baluta return ret; 353abeb6b1eSDaniel Baluta default: 354abeb6b1eSDaniel Baluta return -EINVAL; 355abeb6b1eSDaniel Baluta } 356abeb6b1eSDaniel Baluta } 357abeb6b1eSDaniel Baluta 358abeb6b1eSDaniel Baluta static const struct iio_info mmc35240_info = { 359abeb6b1eSDaniel Baluta .driver_module = THIS_MODULE, 360abeb6b1eSDaniel Baluta .read_raw = mmc35240_read_raw, 361abeb6b1eSDaniel Baluta .write_raw = mmc35240_write_raw, 362abeb6b1eSDaniel Baluta .attrs = &mmc35240_attribute_group, 363abeb6b1eSDaniel Baluta }; 364abeb6b1eSDaniel Baluta 365abeb6b1eSDaniel Baluta static bool mmc35240_is_writeable_reg(struct device *dev, unsigned int reg) 366abeb6b1eSDaniel Baluta { 367abeb6b1eSDaniel Baluta switch (reg) { 368abeb6b1eSDaniel Baluta case MMC35240_REG_CTRL0: 369abeb6b1eSDaniel Baluta case MMC35240_REG_CTRL1: 370abeb6b1eSDaniel Baluta return true; 371abeb6b1eSDaniel Baluta default: 372abeb6b1eSDaniel Baluta return false; 373abeb6b1eSDaniel Baluta } 374abeb6b1eSDaniel Baluta } 375abeb6b1eSDaniel Baluta 376abeb6b1eSDaniel Baluta static bool mmc35240_is_readable_reg(struct device *dev, unsigned int reg) 377abeb6b1eSDaniel Baluta { 378abeb6b1eSDaniel Baluta switch (reg) { 379abeb6b1eSDaniel Baluta case MMC35240_REG_XOUT_L: 380abeb6b1eSDaniel Baluta case MMC35240_REG_XOUT_H: 381abeb6b1eSDaniel Baluta case MMC35240_REG_YOUT_L: 382abeb6b1eSDaniel Baluta case MMC35240_REG_YOUT_H: 383abeb6b1eSDaniel Baluta case MMC35240_REG_ZOUT_L: 384abeb6b1eSDaniel Baluta case MMC35240_REG_ZOUT_H: 385abeb6b1eSDaniel Baluta case MMC35240_REG_STATUS: 386abeb6b1eSDaniel Baluta case MMC35240_REG_ID: 387abeb6b1eSDaniel Baluta return true; 388abeb6b1eSDaniel Baluta default: 389abeb6b1eSDaniel Baluta return false; 390abeb6b1eSDaniel Baluta } 391abeb6b1eSDaniel Baluta } 392abeb6b1eSDaniel Baluta 393abeb6b1eSDaniel Baluta static bool mmc35240_is_volatile_reg(struct device *dev, unsigned int reg) 394abeb6b1eSDaniel Baluta { 395abeb6b1eSDaniel Baluta switch (reg) { 396abeb6b1eSDaniel Baluta case MMC35240_REG_CTRL0: 397abeb6b1eSDaniel Baluta case MMC35240_REG_CTRL1: 398abeb6b1eSDaniel Baluta return false; 399abeb6b1eSDaniel Baluta default: 400abeb6b1eSDaniel Baluta return true; 401abeb6b1eSDaniel Baluta } 402abeb6b1eSDaniel Baluta } 403abeb6b1eSDaniel Baluta 404abeb6b1eSDaniel Baluta static struct reg_default mmc35240_reg_defaults[] = { 405abeb6b1eSDaniel Baluta { MMC35240_REG_CTRL0, 0x00 }, 406abeb6b1eSDaniel Baluta { MMC35240_REG_CTRL1, 0x00 }, 407abeb6b1eSDaniel Baluta }; 408abeb6b1eSDaniel Baluta 409abeb6b1eSDaniel Baluta static const struct regmap_config mmc35240_regmap_config = { 410abeb6b1eSDaniel Baluta .name = MMC35240_REGMAP_NAME, 411abeb6b1eSDaniel Baluta 412abeb6b1eSDaniel Baluta .reg_bits = 8, 413abeb6b1eSDaniel Baluta .val_bits = 8, 414abeb6b1eSDaniel Baluta 415abeb6b1eSDaniel Baluta .max_register = MMC35240_REG_ID, 416abeb6b1eSDaniel Baluta .cache_type = REGCACHE_FLAT, 417abeb6b1eSDaniel Baluta 418abeb6b1eSDaniel Baluta .writeable_reg = mmc35240_is_writeable_reg, 419abeb6b1eSDaniel Baluta .readable_reg = mmc35240_is_readable_reg, 420abeb6b1eSDaniel Baluta .volatile_reg = mmc35240_is_volatile_reg, 421abeb6b1eSDaniel Baluta 422abeb6b1eSDaniel Baluta .reg_defaults = mmc35240_reg_defaults, 423abeb6b1eSDaniel Baluta .num_reg_defaults = ARRAY_SIZE(mmc35240_reg_defaults), 424abeb6b1eSDaniel Baluta }; 425abeb6b1eSDaniel Baluta 426abeb6b1eSDaniel Baluta static int mmc35240_probe(struct i2c_client *client, 427abeb6b1eSDaniel Baluta const struct i2c_device_id *id) 428abeb6b1eSDaniel Baluta { 429abeb6b1eSDaniel Baluta struct mmc35240_data *data; 430abeb6b1eSDaniel Baluta struct iio_dev *indio_dev; 431abeb6b1eSDaniel Baluta struct regmap *regmap; 432abeb6b1eSDaniel Baluta int ret; 433abeb6b1eSDaniel Baluta 434abeb6b1eSDaniel Baluta indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 435abeb6b1eSDaniel Baluta if (!indio_dev) 436abeb6b1eSDaniel Baluta return -ENOMEM; 437abeb6b1eSDaniel Baluta 438abeb6b1eSDaniel Baluta regmap = devm_regmap_init_i2c(client, &mmc35240_regmap_config); 439abeb6b1eSDaniel Baluta if (IS_ERR(regmap)) { 440abeb6b1eSDaniel Baluta dev_err(&client->dev, "regmap initialization failed\n"); 441abeb6b1eSDaniel Baluta return PTR_ERR(regmap); 442abeb6b1eSDaniel Baluta } 443abeb6b1eSDaniel Baluta 444abeb6b1eSDaniel Baluta data = iio_priv(indio_dev); 445abeb6b1eSDaniel Baluta data->client = client; 446abeb6b1eSDaniel Baluta data->regmap = regmap; 447abeb6b1eSDaniel Baluta data->res = MMC35240_16_BITS_SLOW; 448abeb6b1eSDaniel Baluta 449abeb6b1eSDaniel Baluta mutex_init(&data->mutex); 450abeb6b1eSDaniel Baluta 451abeb6b1eSDaniel Baluta indio_dev->dev.parent = &client->dev; 452abeb6b1eSDaniel Baluta indio_dev->info = &mmc35240_info; 453abeb6b1eSDaniel Baluta indio_dev->name = MMC35240_DRV_NAME; 454abeb6b1eSDaniel Baluta indio_dev->channels = mmc35240_channels; 455abeb6b1eSDaniel Baluta indio_dev->num_channels = ARRAY_SIZE(mmc35240_channels); 456abeb6b1eSDaniel Baluta indio_dev->modes = INDIO_DIRECT_MODE; 457abeb6b1eSDaniel Baluta 458abeb6b1eSDaniel Baluta ret = mmc35240_init(data); 459abeb6b1eSDaniel Baluta if (ret < 0) { 460abeb6b1eSDaniel Baluta dev_err(&client->dev, "mmc35240 chip init failed\n"); 461abeb6b1eSDaniel Baluta return ret; 462abeb6b1eSDaniel Baluta } 463abeb6b1eSDaniel Baluta return devm_iio_device_register(&client->dev, indio_dev); 464abeb6b1eSDaniel Baluta } 465abeb6b1eSDaniel Baluta 466553a776bSDaniel Baluta #ifdef CONFIG_PM_SLEEP 467553a776bSDaniel Baluta static int mmc35240_suspend(struct device *dev) 468553a776bSDaniel Baluta { 469553a776bSDaniel Baluta struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 470553a776bSDaniel Baluta struct mmc35240_data *data = iio_priv(indio_dev); 471553a776bSDaniel Baluta 472553a776bSDaniel Baluta regcache_cache_only(data->regmap, true); 473553a776bSDaniel Baluta 474553a776bSDaniel Baluta return 0; 475553a776bSDaniel Baluta } 476553a776bSDaniel Baluta 477553a776bSDaniel Baluta static int mmc35240_resume(struct device *dev) 478553a776bSDaniel Baluta { 479553a776bSDaniel Baluta struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 480553a776bSDaniel Baluta struct mmc35240_data *data = iio_priv(indio_dev); 481553a776bSDaniel Baluta int ret; 482553a776bSDaniel Baluta 483553a776bSDaniel Baluta regcache_mark_dirty(data->regmap); 484553a776bSDaniel Baluta ret = regcache_sync_region(data->regmap, MMC35240_REG_CTRL0, 485553a776bSDaniel Baluta MMC35240_REG_CTRL1); 486553a776bSDaniel Baluta if (ret < 0) 487553a776bSDaniel Baluta dev_err(dev, "Failed to restore control registers\n"); 488553a776bSDaniel Baluta 489553a776bSDaniel Baluta regcache_cache_only(data->regmap, false); 490553a776bSDaniel Baluta 491553a776bSDaniel Baluta return 0; 492553a776bSDaniel Baluta } 493553a776bSDaniel Baluta #endif 494553a776bSDaniel Baluta 495553a776bSDaniel Baluta static const struct dev_pm_ops mmc35240_pm_ops = { 496553a776bSDaniel Baluta SET_SYSTEM_SLEEP_PM_OPS(mmc35240_suspend, mmc35240_resume) 497553a776bSDaniel Baluta }; 498553a776bSDaniel Baluta 499d11715f0SDaniel Baluta static const struct acpi_device_id mmc35240_acpi_match[] = { 500d11715f0SDaniel Baluta {"MMC35240", 0}, 501d11715f0SDaniel Baluta { }, 502d11715f0SDaniel Baluta }; 503d11715f0SDaniel Baluta MODULE_DEVICE_TABLE(acpi, mmc35240_acpi_match); 504d11715f0SDaniel Baluta 505abeb6b1eSDaniel Baluta static const struct i2c_device_id mmc35240_id[] = { 506a52ffebcSDaniel Baluta {"mmc35240", 0}, 507abeb6b1eSDaniel Baluta {} 508abeb6b1eSDaniel Baluta }; 509abeb6b1eSDaniel Baluta MODULE_DEVICE_TABLE(i2c, mmc35240_id); 510abeb6b1eSDaniel Baluta 511abeb6b1eSDaniel Baluta static struct i2c_driver mmc35240_driver = { 512abeb6b1eSDaniel Baluta .driver = { 513abeb6b1eSDaniel Baluta .name = MMC35240_DRV_NAME, 514553a776bSDaniel Baluta .pm = &mmc35240_pm_ops, 515d11715f0SDaniel Baluta .acpi_match_table = ACPI_PTR(mmc35240_acpi_match), 516abeb6b1eSDaniel Baluta }, 517abeb6b1eSDaniel Baluta .probe = mmc35240_probe, 518abeb6b1eSDaniel Baluta .id_table = mmc35240_id, 519abeb6b1eSDaniel Baluta }; 520abeb6b1eSDaniel Baluta 521abeb6b1eSDaniel Baluta module_i2c_driver(mmc35240_driver); 522abeb6b1eSDaniel Baluta 523abeb6b1eSDaniel Baluta MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>"); 524abeb6b1eSDaniel Baluta MODULE_DESCRIPTION("MEMSIC MMC35240 magnetic sensor driver"); 525abeb6b1eSDaniel Baluta MODULE_LICENSE("GPL v2"); 526