1/* 2 * mma8452.c - Support for Freescale MMA8452Q 3-axis 12-bit accelerometer 3 * 4 * Copyright 2014 Peter Meerwald <pmeerw@pmeerw.net> 5 * 6 * This file is subject to the terms and conditions of version 2 of 7 * the GNU General Public License. See the file COPYING in the main 8 * directory of this archive for more details. 9 * 10 * 7-bit I2C slave address 0x1c/0x1d (pin selectable) 11 * 12 * TODO: interrupt, thresholding, orientation / freefall events, autosleep 13 */ 14 15#include <linux/module.h> 16#include <linux/i2c.h> 17#include <linux/iio/iio.h> 18#include <linux/iio/sysfs.h> 19#include <linux/iio/trigger_consumer.h> 20#include <linux/iio/buffer.h> 21#include <linux/iio/triggered_buffer.h> 22#include <linux/delay.h> 23 24#define MMA8452_STATUS 0x00 25#define MMA8452_OUT_X 0x01 /* MSB first, 12-bit */ 26#define MMA8452_OUT_Y 0x03 27#define MMA8452_OUT_Z 0x05 28#define MMA8452_WHO_AM_I 0x0d 29#define MMA8452_DATA_CFG 0x0e 30#define MMA8452_OFF_X 0x2f 31#define MMA8452_OFF_Y 0x30 32#define MMA8452_OFF_Z 0x31 33#define MMA8452_CTRL_REG1 0x2a 34#define MMA8452_CTRL_REG2 0x2b 35 36#define MMA8452_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0)) 37 38#define MMA8452_CTRL_DR_MASK (BIT(5) | BIT(4) | BIT(3)) 39#define MMA8452_CTRL_DR_SHIFT 3 40#define MMA8452_CTRL_DR_DEFAULT 0x4 /* 50 Hz sample frequency */ 41#define MMA8452_CTRL_ACTIVE BIT(0) 42 43#define MMA8452_DATA_CFG_FS_MASK (BIT(1) | BIT(0)) 44#define MMA8452_DATA_CFG_FS_2G 0 45#define MMA8452_DATA_CFG_FS_4G 1 46#define MMA8452_DATA_CFG_FS_8G 2 47 48#define MMA8452_DEVICE_ID 0x2a 49 50struct mma8452_data { 51 struct i2c_client *client; 52 struct mutex lock; 53 u8 ctrl_reg1; 54 u8 data_cfg; 55}; 56 57static int mma8452_drdy(struct mma8452_data *data) 58{ 59 int tries = 150; 60 61 while (tries-- > 0) { 62 int ret = i2c_smbus_read_byte_data(data->client, 63 MMA8452_STATUS); 64 if (ret < 0) 65 return ret; 66 if ((ret & MMA8452_STATUS_DRDY) == MMA8452_STATUS_DRDY) 67 return 0; 68 msleep(20); 69 } 70 71 dev_err(&data->client->dev, "data not ready\n"); 72 return -EIO; 73} 74 75static int mma8452_read(struct mma8452_data *data, __be16 buf[3]) 76{ 77 int ret = mma8452_drdy(data); 78 if (ret < 0) 79 return ret; 80 return i2c_smbus_read_i2c_block_data(data->client, 81 MMA8452_OUT_X, 3 * sizeof(__be16), (u8 *) buf); 82} 83 84static ssize_t mma8452_show_int_plus_micros(char *buf, 85 const int (*vals)[2], int n) 86{ 87 size_t len = 0; 88 89 while (n-- > 0) 90 len += scnprintf(buf + len, PAGE_SIZE - len, 91 "%d.%06d ", vals[n][0], vals[n][1]); 92 93 /* replace trailing space by newline */ 94 buf[len - 1] = '\n'; 95 96 return len; 97} 98 99static int mma8452_get_int_plus_micros_index(const int (*vals)[2], int n, 100 int val, int val2) 101{ 102 while (n-- > 0) 103 if (val == vals[n][0] && val2 == vals[n][1]) 104 return n; 105 106 return -EINVAL; 107} 108 109static const int mma8452_samp_freq[8][2] = { 110 {800, 0}, {400, 0}, {200, 0}, {100, 0}, {50, 0}, {12, 500000}, 111 {6, 250000}, {1, 560000} 112}; 113 114/* 115 * Hardware has fullscale of -2G, -4G, -8G corresponding to raw value -2048 116 * The userspace interface uses m/s^2 and we declare micro units 117 * So scale factor is given by: 118 * g * N * 1000000 / 2048 for N = 2, 4, 8 and g=9.80665 119 */ 120static const int mma8452_scales[3][2] = { 121 {0, 9577}, {0, 19154}, {0, 38307} 122}; 123 124static ssize_t mma8452_show_samp_freq_avail(struct device *dev, 125 struct device_attribute *attr, char *buf) 126{ 127 return mma8452_show_int_plus_micros(buf, mma8452_samp_freq, 128 ARRAY_SIZE(mma8452_samp_freq)); 129} 130 131static ssize_t mma8452_show_scale_avail(struct device *dev, 132 struct device_attribute *attr, char *buf) 133{ 134 return mma8452_show_int_plus_micros(buf, mma8452_scales, 135 ARRAY_SIZE(mma8452_scales)); 136} 137 138static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(mma8452_show_samp_freq_avail); 139static IIO_DEVICE_ATTR(in_accel_scale_available, S_IRUGO, 140 mma8452_show_scale_avail, NULL, 0); 141 142static int mma8452_get_samp_freq_index(struct mma8452_data *data, 143 int val, int val2) 144{ 145 return mma8452_get_int_plus_micros_index(mma8452_samp_freq, 146 ARRAY_SIZE(mma8452_samp_freq), val, val2); 147} 148 149static int mma8452_get_scale_index(struct mma8452_data *data, 150 int val, int val2) 151{ 152 return mma8452_get_int_plus_micros_index(mma8452_scales, 153 ARRAY_SIZE(mma8452_scales), val, val2); 154} 155 156static int mma8452_read_raw(struct iio_dev *indio_dev, 157 struct iio_chan_spec const *chan, 158 int *val, int *val2, long mask) 159{ 160 struct mma8452_data *data = iio_priv(indio_dev); 161 __be16 buffer[3]; 162 int i, ret; 163 164 switch (mask) { 165 case IIO_CHAN_INFO_RAW: 166 if (iio_buffer_enabled(indio_dev)) 167 return -EBUSY; 168 169 mutex_lock(&data->lock); 170 ret = mma8452_read(data, buffer); 171 mutex_unlock(&data->lock); 172 if (ret < 0) 173 return ret; 174 *val = sign_extend32( 175 be16_to_cpu(buffer[chan->scan_index]) >> 4, 11); 176 return IIO_VAL_INT; 177 case IIO_CHAN_INFO_SCALE: 178 i = data->data_cfg & MMA8452_DATA_CFG_FS_MASK; 179 *val = mma8452_scales[i][0]; 180 *val2 = mma8452_scales[i][1]; 181 return IIO_VAL_INT_PLUS_MICRO; 182 case IIO_CHAN_INFO_SAMP_FREQ: 183 i = (data->ctrl_reg1 & MMA8452_CTRL_DR_MASK) >> 184 MMA8452_CTRL_DR_SHIFT; 185 *val = mma8452_samp_freq[i][0]; 186 *val2 = mma8452_samp_freq[i][1]; 187 return IIO_VAL_INT_PLUS_MICRO; 188 case IIO_CHAN_INFO_CALIBBIAS: 189 ret = i2c_smbus_read_byte_data(data->client, MMA8452_OFF_X + 190 chan->scan_index); 191 if (ret < 0) 192 return ret; 193 *val = sign_extend32(ret, 7); 194 return IIO_VAL_INT; 195 } 196 return -EINVAL; 197} 198 199static int mma8452_standby(struct mma8452_data *data) 200{ 201 return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1, 202 data->ctrl_reg1 & ~MMA8452_CTRL_ACTIVE); 203} 204 205static int mma8452_active(struct mma8452_data *data) 206{ 207 return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1, 208 data->ctrl_reg1); 209} 210 211static int mma8452_change_config(struct mma8452_data *data, u8 reg, u8 val) 212{ 213 int ret; 214 215 mutex_lock(&data->lock); 216 217 /* config can only be changed when in standby */ 218 ret = mma8452_standby(data); 219 if (ret < 0) 220 goto fail; 221 222 ret = i2c_smbus_write_byte_data(data->client, reg, val); 223 if (ret < 0) 224 goto fail; 225 226 ret = mma8452_active(data); 227 if (ret < 0) 228 goto fail; 229 230 ret = 0; 231fail: 232 mutex_unlock(&data->lock); 233 return ret; 234} 235 236static int mma8452_write_raw(struct iio_dev *indio_dev, 237 struct iio_chan_spec const *chan, 238 int val, int val2, long mask) 239{ 240 struct mma8452_data *data = iio_priv(indio_dev); 241 int i; 242 243 if (iio_buffer_enabled(indio_dev)) 244 return -EBUSY; 245 246 switch (mask) { 247 case IIO_CHAN_INFO_SAMP_FREQ: 248 i = mma8452_get_samp_freq_index(data, val, val2); 249 if (i < 0) 250 return -EINVAL; 251 252 data->ctrl_reg1 &= ~MMA8452_CTRL_DR_MASK; 253 data->ctrl_reg1 |= i << MMA8452_CTRL_DR_SHIFT; 254 return mma8452_change_config(data, MMA8452_CTRL_REG1, 255 data->ctrl_reg1); 256 case IIO_CHAN_INFO_SCALE: 257 i = mma8452_get_scale_index(data, val, val2); 258 if (i < 0) 259 return -EINVAL; 260 data->data_cfg &= ~MMA8452_DATA_CFG_FS_MASK; 261 data->data_cfg |= i; 262 return mma8452_change_config(data, MMA8452_DATA_CFG, 263 data->data_cfg); 264 case IIO_CHAN_INFO_CALIBBIAS: 265 if (val < -128 || val > 127) 266 return -EINVAL; 267 return mma8452_change_config(data, MMA8452_OFF_X + 268 chan->scan_index, val); 269 default: 270 return -EINVAL; 271 } 272} 273 274static irqreturn_t mma8452_trigger_handler(int irq, void *p) 275{ 276 struct iio_poll_func *pf = p; 277 struct iio_dev *indio_dev = pf->indio_dev; 278 struct mma8452_data *data = iio_priv(indio_dev); 279 u8 buffer[16]; /* 3 16-bit channels + padding + ts */ 280 int ret; 281 282 ret = mma8452_read(data, (__be16 *) buffer); 283 if (ret < 0) 284 goto done; 285 286 iio_push_to_buffers_with_timestamp(indio_dev, buffer, 287 iio_get_time_ns()); 288 289done: 290 iio_trigger_notify_done(indio_dev->trig); 291 return IRQ_HANDLED; 292} 293 294#define MMA8452_CHANNEL(axis, idx) { \ 295 .type = IIO_ACCEL, \ 296 .modified = 1, \ 297 .channel2 = IIO_MOD_##axis, \ 298 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 299 BIT(IIO_CHAN_INFO_CALIBBIAS), \ 300 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ 301 BIT(IIO_CHAN_INFO_SCALE), \ 302 .scan_index = idx, \ 303 .scan_type = { \ 304 .sign = 's', \ 305 .realbits = 12, \ 306 .storagebits = 16, \ 307 .shift = 4, \ 308 .endianness = IIO_BE, \ 309 }, \ 310} 311 312static const struct iio_chan_spec mma8452_channels[] = { 313 MMA8452_CHANNEL(X, 0), 314 MMA8452_CHANNEL(Y, 1), 315 MMA8452_CHANNEL(Z, 2), 316 IIO_CHAN_SOFT_TIMESTAMP(3), 317}; 318 319static struct attribute *mma8452_attributes[] = { 320 &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 321 &iio_dev_attr_in_accel_scale_available.dev_attr.attr, 322 NULL 323}; 324 325static const struct attribute_group mma8452_group = { 326 .attrs = mma8452_attributes, 327}; 328 329static const struct iio_info mma8452_info = { 330 .attrs = &mma8452_group, 331 .read_raw = &mma8452_read_raw, 332 .write_raw = &mma8452_write_raw, 333 .driver_module = THIS_MODULE, 334}; 335 336static const unsigned long mma8452_scan_masks[] = {0x7, 0}; 337 338static int mma8452_probe(struct i2c_client *client, 339 const struct i2c_device_id *id) 340{ 341 struct mma8452_data *data; 342 struct iio_dev *indio_dev; 343 int ret; 344 345 ret = i2c_smbus_read_byte_data(client, MMA8452_WHO_AM_I); 346 if (ret < 0) 347 return ret; 348 if (ret != MMA8452_DEVICE_ID) 349 return -ENODEV; 350 351 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 352 if (!indio_dev) 353 return -ENOMEM; 354 355 data = iio_priv(indio_dev); 356 data->client = client; 357 mutex_init(&data->lock); 358 359 i2c_set_clientdata(client, indio_dev); 360 indio_dev->info = &mma8452_info; 361 indio_dev->name = id->name; 362 indio_dev->dev.parent = &client->dev; 363 indio_dev->modes = INDIO_DIRECT_MODE; 364 indio_dev->channels = mma8452_channels; 365 indio_dev->num_channels = ARRAY_SIZE(mma8452_channels); 366 indio_dev->available_scan_masks = mma8452_scan_masks; 367 368 data->ctrl_reg1 = MMA8452_CTRL_ACTIVE | 369 (MMA8452_CTRL_DR_DEFAULT << MMA8452_CTRL_DR_SHIFT); 370 ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG1, 371 data->ctrl_reg1); 372 if (ret < 0) 373 return ret; 374 375 data->data_cfg = MMA8452_DATA_CFG_FS_2G; 376 ret = i2c_smbus_write_byte_data(client, MMA8452_DATA_CFG, 377 data->data_cfg); 378 if (ret < 0) 379 return ret; 380 381 ret = iio_triggered_buffer_setup(indio_dev, NULL, 382 mma8452_trigger_handler, NULL); 383 if (ret < 0) 384 return ret; 385 386 ret = iio_device_register(indio_dev); 387 if (ret < 0) 388 goto buffer_cleanup; 389 return 0; 390 391buffer_cleanup: 392 iio_triggered_buffer_cleanup(indio_dev); 393 return ret; 394} 395 396static int mma8452_remove(struct i2c_client *client) 397{ 398 struct iio_dev *indio_dev = i2c_get_clientdata(client); 399 400 iio_device_unregister(indio_dev); 401 iio_triggered_buffer_cleanup(indio_dev); 402 mma8452_standby(iio_priv(indio_dev)); 403 404 return 0; 405} 406 407#ifdef CONFIG_PM_SLEEP 408static int mma8452_suspend(struct device *dev) 409{ 410 return mma8452_standby(iio_priv(i2c_get_clientdata( 411 to_i2c_client(dev)))); 412} 413 414static int mma8452_resume(struct device *dev) 415{ 416 return mma8452_active(iio_priv(i2c_get_clientdata( 417 to_i2c_client(dev)))); 418} 419 420static SIMPLE_DEV_PM_OPS(mma8452_pm_ops, mma8452_suspend, mma8452_resume); 421#define MMA8452_PM_OPS (&mma8452_pm_ops) 422#else 423#define MMA8452_PM_OPS NULL 424#endif 425 426static const struct i2c_device_id mma8452_id[] = { 427 { "mma8452", 0 }, 428 { } 429}; 430MODULE_DEVICE_TABLE(i2c, mma8452_id); 431 432static const struct of_device_id mma8452_dt_ids[] = { 433 { .compatible = "fsl,mma8452" }, 434 { } 435}; 436 437static struct i2c_driver mma8452_driver = { 438 .driver = { 439 .name = "mma8452", 440 .of_match_table = of_match_ptr(mma8452_dt_ids), 441 .pm = MMA8452_PM_OPS, 442 }, 443 .probe = mma8452_probe, 444 .remove = mma8452_remove, 445 .id_table = mma8452_id, 446}; 447module_i2c_driver(mma8452_driver); 448 449MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>"); 450MODULE_DESCRIPTION("Freescale MMA8452 accelerometer driver"); 451MODULE_LICENSE("GPL"); 452