root/drivers/iio/accel/mma9551.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mma9551_read_incli_chan
  2. mma9551_read_raw
  3. mma9551_read_event_config
  4. mma9551_config_incli_event
  5. mma9551_write_event_config
  6. mma9551_write_event_value
  7. mma9551_read_event_value
  8. mma9551_event_handler
  9. mma9551_init
  10. mma9551_gpio_probe
  11. mma9551_match_acpi_device
  12. mma9551_probe
  13. mma9551_remove
  14. mma9551_runtime_suspend
  15. mma9551_runtime_resume
  16. mma9551_suspend
  17. mma9551_resume

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Freescale MMA9551L Intelligent Motion-Sensing Platform driver
   4  * Copyright (c) 2014, Intel Corporation.
   5  */
   6 
   7 #include <linux/module.h>
   8 #include <linux/i2c.h>
   9 #include <linux/interrupt.h>
  10 #include <linux/slab.h>
  11 #include <linux/acpi.h>
  12 #include <linux/delay.h>
  13 #include <linux/gpio/consumer.h>
  14 #include <linux/iio/iio.h>
  15 #include <linux/iio/sysfs.h>
  16 #include <linux/iio/events.h>
  17 #include <linux/pm_runtime.h>
  18 #include "mma9551_core.h"
  19 
  20 #define MMA9551_DRV_NAME                "mma9551"
  21 #define MMA9551_IRQ_NAME                "mma9551_event"
  22 #define MMA9551_GPIO_COUNT              4
  23 
  24 /* Tilt application (inclination in IIO terms). */
  25 #define MMA9551_TILT_XZ_ANG_REG         0x00
  26 #define MMA9551_TILT_YZ_ANG_REG         0x01
  27 #define MMA9551_TILT_XY_ANG_REG         0x02
  28 #define MMA9551_TILT_ANGFLG             BIT(7)
  29 #define MMA9551_TILT_QUAD_REG           0x03
  30 #define MMA9551_TILT_XY_QUAD_SHIFT      0
  31 #define MMA9551_TILT_YZ_QUAD_SHIFT      2
  32 #define MMA9551_TILT_XZ_QUAD_SHIFT      4
  33 #define MMA9551_TILT_CFG_REG            0x01
  34 #define MMA9551_TILT_ANG_THRESH_MASK    GENMASK(3, 0)
  35 
  36 #define MMA9551_DEFAULT_SAMPLE_RATE     122     /* Hz */
  37 
  38 /* Tilt events are mapped to the first three GPIO pins. */
  39 enum mma9551_tilt_axis {
  40         mma9551_x = 0,
  41         mma9551_y,
  42         mma9551_z,
  43 };
  44 
  45 struct mma9551_data {
  46         struct i2c_client *client;
  47         struct mutex mutex;
  48         int event_enabled[3];
  49         int irqs[MMA9551_GPIO_COUNT];
  50 };
  51 
  52 static int mma9551_read_incli_chan(struct i2c_client *client,
  53                                    const struct iio_chan_spec *chan,
  54                                    int *val)
  55 {
  56         u8 quad_shift, angle, quadrant;
  57         u16 reg_addr;
  58         int ret;
  59 
  60         switch (chan->channel2) {
  61         case IIO_MOD_X:
  62                 reg_addr = MMA9551_TILT_YZ_ANG_REG;
  63                 quad_shift = MMA9551_TILT_YZ_QUAD_SHIFT;
  64                 break;
  65         case IIO_MOD_Y:
  66                 reg_addr = MMA9551_TILT_XZ_ANG_REG;
  67                 quad_shift = MMA9551_TILT_XZ_QUAD_SHIFT;
  68                 break;
  69         case IIO_MOD_Z:
  70                 reg_addr = MMA9551_TILT_XY_ANG_REG;
  71                 quad_shift = MMA9551_TILT_XY_QUAD_SHIFT;
  72                 break;
  73         default:
  74                 return -EINVAL;
  75         }
  76 
  77         ret = mma9551_set_power_state(client, true);
  78         if (ret < 0)
  79                 return ret;
  80 
  81         ret = mma9551_read_status_byte(client, MMA9551_APPID_TILT,
  82                                        reg_addr, &angle);
  83         if (ret < 0)
  84                 goto out_poweroff;
  85 
  86         ret = mma9551_read_status_byte(client, MMA9551_APPID_TILT,
  87                                        MMA9551_TILT_QUAD_REG, &quadrant);
  88         if (ret < 0)
  89                 goto out_poweroff;
  90 
  91         angle &= ~MMA9551_TILT_ANGFLG;
  92         quadrant = (quadrant >> quad_shift) & 0x03;
  93 
  94         if (quadrant == 1 || quadrant == 3)
  95                 *val = 90 * (quadrant + 1) - angle;
  96         else
  97                 *val = angle + 90 * quadrant;
  98 
  99         ret = IIO_VAL_INT;
 100 
 101 out_poweroff:
 102         mma9551_set_power_state(client, false);
 103         return ret;
 104 }
 105 
 106 static int mma9551_read_raw(struct iio_dev *indio_dev,
 107                             struct iio_chan_spec const *chan,
 108                             int *val, int *val2, long mask)
 109 {
 110         struct mma9551_data *data = iio_priv(indio_dev);
 111         int ret;
 112 
 113         switch (mask) {
 114         case IIO_CHAN_INFO_PROCESSED:
 115                 switch (chan->type) {
 116                 case IIO_INCLI:
 117                         mutex_lock(&data->mutex);
 118                         ret = mma9551_read_incli_chan(data->client, chan, val);
 119                         mutex_unlock(&data->mutex);
 120                         return ret;
 121                 default:
 122                         return -EINVAL;
 123                 }
 124         case IIO_CHAN_INFO_RAW:
 125                 switch (chan->type) {
 126                 case IIO_ACCEL:
 127                         mutex_lock(&data->mutex);
 128                         ret = mma9551_read_accel_chan(data->client,
 129                                                       chan, val, val2);
 130                         mutex_unlock(&data->mutex);
 131                         return ret;
 132                 default:
 133                         return -EINVAL;
 134                 }
 135         case IIO_CHAN_INFO_SCALE:
 136                 switch (chan->type) {
 137                 case IIO_ACCEL:
 138                         return mma9551_read_accel_scale(val, val2);
 139                 default:
 140                         return -EINVAL;
 141                 }
 142         default:
 143                 return -EINVAL;
 144         }
 145 }
 146 
 147 static int mma9551_read_event_config(struct iio_dev *indio_dev,
 148                                      const struct iio_chan_spec *chan,
 149                                      enum iio_event_type type,
 150                                      enum iio_event_direction dir)
 151 {
 152         struct mma9551_data *data = iio_priv(indio_dev);
 153 
 154         switch (chan->type) {
 155         case IIO_INCLI:
 156                 /* IIO counts axes from 1, because IIO_NO_MOD is 0. */
 157                 return data->event_enabled[chan->channel2 - 1];
 158         default:
 159                 return -EINVAL;
 160         }
 161 }
 162 
 163 static int mma9551_config_incli_event(struct iio_dev *indio_dev,
 164                                       enum iio_modifier axis,
 165                                       int state)
 166 {
 167         struct mma9551_data *data = iio_priv(indio_dev);
 168         enum mma9551_tilt_axis mma_axis;
 169         int ret;
 170 
 171         /* IIO counts axes from 1, because IIO_NO_MOD is 0. */
 172         mma_axis = axis - 1;
 173 
 174         if (data->event_enabled[mma_axis] == state)
 175                 return 0;
 176 
 177         if (state == 0) {
 178                 ret = mma9551_gpio_config(data->client,
 179                                           (enum mma9551_gpio_pin)mma_axis,
 180                                           MMA9551_APPID_NONE, 0, 0);
 181                 if (ret < 0)
 182                         return ret;
 183 
 184                 ret = mma9551_set_power_state(data->client, false);
 185                 if (ret < 0)
 186                         return ret;
 187         } else {
 188                 int bitnum;
 189 
 190                 /* Bit 7 of each angle register holds the angle flag. */
 191                 switch (axis) {
 192                 case IIO_MOD_X:
 193                         bitnum = 7 + 8 * MMA9551_TILT_YZ_ANG_REG;
 194                         break;
 195                 case IIO_MOD_Y:
 196                         bitnum = 7 + 8 * MMA9551_TILT_XZ_ANG_REG;
 197                         break;
 198                 case IIO_MOD_Z:
 199                         bitnum = 7 + 8 * MMA9551_TILT_XY_ANG_REG;
 200                         break;
 201                 default:
 202                         return -EINVAL;
 203                 }
 204 
 205 
 206                 ret = mma9551_set_power_state(data->client, true);
 207                 if (ret < 0)
 208                         return ret;
 209 
 210                 ret = mma9551_gpio_config(data->client,
 211                                           (enum mma9551_gpio_pin)mma_axis,
 212                                           MMA9551_APPID_TILT, bitnum, 0);
 213                 if (ret < 0) {
 214                         mma9551_set_power_state(data->client, false);
 215                         return ret;
 216                 }
 217         }
 218 
 219         data->event_enabled[mma_axis] = state;
 220 
 221         return ret;
 222 }
 223 
 224 static int mma9551_write_event_config(struct iio_dev *indio_dev,
 225                                       const struct iio_chan_spec *chan,
 226                                       enum iio_event_type type,
 227                                       enum iio_event_direction dir,
 228                                       int state)
 229 {
 230         struct mma9551_data *data = iio_priv(indio_dev);
 231         int ret;
 232 
 233         switch (chan->type) {
 234         case IIO_INCLI:
 235                 mutex_lock(&data->mutex);
 236                 ret = mma9551_config_incli_event(indio_dev,
 237                                                  chan->channel2, state);
 238                 mutex_unlock(&data->mutex);
 239                 return ret;
 240         default:
 241                 return -EINVAL;
 242         }
 243 }
 244 
 245 static int mma9551_write_event_value(struct iio_dev *indio_dev,
 246                                      const struct iio_chan_spec *chan,
 247                                      enum iio_event_type type,
 248                                      enum iio_event_direction dir,
 249                                      enum iio_event_info info,
 250                                      int val, int val2)
 251 {
 252         struct mma9551_data *data = iio_priv(indio_dev);
 253         int ret;
 254 
 255         switch (chan->type) {
 256         case IIO_INCLI:
 257                 if (val2 != 0 || val < 1 || val > 10)
 258                         return -EINVAL;
 259                 mutex_lock(&data->mutex);
 260                 ret = mma9551_update_config_bits(data->client,
 261                                                  MMA9551_APPID_TILT,
 262                                                  MMA9551_TILT_CFG_REG,
 263                                                  MMA9551_TILT_ANG_THRESH_MASK,
 264                                                  val);
 265                 mutex_unlock(&data->mutex);
 266                 return ret;
 267         default:
 268                 return -EINVAL;
 269         }
 270 }
 271 
 272 static int mma9551_read_event_value(struct iio_dev *indio_dev,
 273                                     const struct iio_chan_spec *chan,
 274                                     enum iio_event_type type,
 275                                     enum iio_event_direction dir,
 276                                     enum iio_event_info info,
 277                                     int *val, int *val2)
 278 {
 279         struct mma9551_data *data = iio_priv(indio_dev);
 280         int ret;
 281         u8 tmp;
 282 
 283         switch (chan->type) {
 284         case IIO_INCLI:
 285                 mutex_lock(&data->mutex);
 286                 ret = mma9551_read_config_byte(data->client,
 287                                                MMA9551_APPID_TILT,
 288                                                MMA9551_TILT_CFG_REG, &tmp);
 289                 mutex_unlock(&data->mutex);
 290                 if (ret < 0)
 291                         return ret;
 292                 *val = tmp & MMA9551_TILT_ANG_THRESH_MASK;
 293                 *val2 = 0;
 294                 return IIO_VAL_INT;
 295         default:
 296                 return -EINVAL;
 297         }
 298 }
 299 
 300 static const struct iio_event_spec mma9551_incli_event = {
 301         .type = IIO_EV_TYPE_ROC,
 302         .dir = IIO_EV_DIR_RISING,
 303         .mask_separate = BIT(IIO_EV_INFO_ENABLE),
 304         .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
 305 };
 306 
 307 #define MMA9551_INCLI_CHANNEL(axis) {                           \
 308         .type = IIO_INCLI,                                      \
 309         .modified = 1,                                          \
 310         .channel2 = axis,                                       \
 311         .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),     \
 312         .event_spec = &mma9551_incli_event,                     \
 313         .num_event_specs = 1,                                   \
 314 }
 315 
 316 static const struct iio_chan_spec mma9551_channels[] = {
 317         MMA9551_ACCEL_CHANNEL(IIO_MOD_X),
 318         MMA9551_ACCEL_CHANNEL(IIO_MOD_Y),
 319         MMA9551_ACCEL_CHANNEL(IIO_MOD_Z),
 320 
 321         MMA9551_INCLI_CHANNEL(IIO_MOD_X),
 322         MMA9551_INCLI_CHANNEL(IIO_MOD_Y),
 323         MMA9551_INCLI_CHANNEL(IIO_MOD_Z),
 324 };
 325 
 326 static const struct iio_info mma9551_info = {
 327         .read_raw = mma9551_read_raw,
 328         .read_event_config = mma9551_read_event_config,
 329         .write_event_config = mma9551_write_event_config,
 330         .read_event_value = mma9551_read_event_value,
 331         .write_event_value = mma9551_write_event_value,
 332 };
 333 
 334 static irqreturn_t mma9551_event_handler(int irq, void *private)
 335 {
 336         struct iio_dev *indio_dev = private;
 337         struct mma9551_data *data = iio_priv(indio_dev);
 338         int i, ret, mma_axis = -1;
 339         u16 reg;
 340         u8 val;
 341 
 342         mutex_lock(&data->mutex);
 343 
 344         for (i = 0; i < 3; i++)
 345                 if (irq == data->irqs[i]) {
 346                         mma_axis = i;
 347                         break;
 348                 }
 349 
 350         if (mma_axis == -1) {
 351                 /* IRQ was triggered on 4th line, which we don't use. */
 352                 dev_warn(&data->client->dev,
 353                          "irq triggered on unused line %d\n", data->irqs[3]);
 354                 goto out;
 355         }
 356 
 357         switch (mma_axis) {
 358         case mma9551_x:
 359                 reg = MMA9551_TILT_YZ_ANG_REG;
 360                 break;
 361         case mma9551_y:
 362                 reg = MMA9551_TILT_XZ_ANG_REG;
 363                 break;
 364         case mma9551_z:
 365                 reg = MMA9551_TILT_XY_ANG_REG;
 366                 break;
 367         }
 368 
 369         /*
 370          * Read the angle even though we don't use it, otherwise we
 371          * won't get any further interrupts.
 372          */
 373         ret = mma9551_read_status_byte(data->client, MMA9551_APPID_TILT,
 374                                        reg, &val);
 375         if (ret < 0) {
 376                 dev_err(&data->client->dev,
 377                         "error %d reading tilt register in IRQ\n", ret);
 378                 goto out;
 379         }
 380 
 381         iio_push_event(indio_dev,
 382                        IIO_MOD_EVENT_CODE(IIO_INCLI, 0, (mma_axis + 1),
 383                                           IIO_EV_TYPE_ROC, IIO_EV_DIR_RISING),
 384                        iio_get_time_ns(indio_dev));
 385 
 386 out:
 387         mutex_unlock(&data->mutex);
 388 
 389         return IRQ_HANDLED;
 390 }
 391 
 392 static int mma9551_init(struct mma9551_data *data)
 393 {
 394         int ret;
 395 
 396         ret = mma9551_read_version(data->client);
 397         if (ret)
 398                 return ret;
 399 
 400         return mma9551_set_device_state(data->client, true);
 401 }
 402 
 403 static int mma9551_gpio_probe(struct iio_dev *indio_dev)
 404 {
 405         struct gpio_desc *gpio;
 406         int i, ret;
 407         struct mma9551_data *data = iio_priv(indio_dev);
 408         struct device *dev = &data->client->dev;
 409 
 410         for (i = 0; i < MMA9551_GPIO_COUNT; i++) {
 411                 gpio = devm_gpiod_get_index(dev, NULL, i, GPIOD_IN);
 412                 if (IS_ERR(gpio)) {
 413                         dev_err(dev, "acpi gpio get index failed\n");
 414                         return PTR_ERR(gpio);
 415                 }
 416 
 417                 ret = gpiod_to_irq(gpio);
 418                 if (ret < 0)
 419                         return ret;
 420 
 421                 data->irqs[i] = ret;
 422                 ret = devm_request_threaded_irq(dev, data->irqs[i],
 423                                 NULL, mma9551_event_handler,
 424                                 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
 425                                 MMA9551_IRQ_NAME, indio_dev);
 426                 if (ret < 0) {
 427                         dev_err(dev, "request irq %d failed\n", data->irqs[i]);
 428                         return ret;
 429                 }
 430 
 431                 dev_dbg(dev, "gpio resource, no:%d irq:%d\n",
 432                         desc_to_gpio(gpio), data->irqs[i]);
 433         }
 434 
 435         return 0;
 436 }
 437 
 438 static const char *mma9551_match_acpi_device(struct device *dev)
 439 {
 440         const struct acpi_device_id *id;
 441 
 442         id = acpi_match_device(dev->driver->acpi_match_table, dev);
 443         if (!id)
 444                 return NULL;
 445 
 446         return dev_name(dev);
 447 }
 448 
 449 static int mma9551_probe(struct i2c_client *client,
 450                          const struct i2c_device_id *id)
 451 {
 452         struct mma9551_data *data;
 453         struct iio_dev *indio_dev;
 454         const char *name = NULL;
 455         int ret;
 456 
 457         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 458         if (!indio_dev)
 459                 return -ENOMEM;
 460 
 461         data = iio_priv(indio_dev);
 462         i2c_set_clientdata(client, indio_dev);
 463         data->client = client;
 464 
 465         if (id)
 466                 name = id->name;
 467         else if (ACPI_HANDLE(&client->dev))
 468                 name = mma9551_match_acpi_device(&client->dev);
 469 
 470         ret = mma9551_init(data);
 471         if (ret < 0)
 472                 return ret;
 473 
 474         mutex_init(&data->mutex);
 475 
 476         indio_dev->dev.parent = &client->dev;
 477         indio_dev->channels = mma9551_channels;
 478         indio_dev->num_channels = ARRAY_SIZE(mma9551_channels);
 479         indio_dev->name = name;
 480         indio_dev->modes = INDIO_DIRECT_MODE;
 481         indio_dev->info = &mma9551_info;
 482 
 483         ret = mma9551_gpio_probe(indio_dev);
 484         if (ret < 0)
 485                 goto out_poweroff;
 486 
 487         ret = pm_runtime_set_active(&client->dev);
 488         if (ret < 0)
 489                 goto out_poweroff;
 490 
 491         pm_runtime_enable(&client->dev);
 492         pm_runtime_set_autosuspend_delay(&client->dev,
 493                                          MMA9551_AUTO_SUSPEND_DELAY_MS);
 494         pm_runtime_use_autosuspend(&client->dev);
 495 
 496         ret = iio_device_register(indio_dev);
 497         if (ret < 0) {
 498                 dev_err(&client->dev, "unable to register iio device\n");
 499                 goto out_poweroff;
 500         }
 501 
 502         return 0;
 503 
 504 out_poweroff:
 505         mma9551_set_device_state(client, false);
 506 
 507         return ret;
 508 }
 509 
 510 static int mma9551_remove(struct i2c_client *client)
 511 {
 512         struct iio_dev *indio_dev = i2c_get_clientdata(client);
 513         struct mma9551_data *data = iio_priv(indio_dev);
 514 
 515         iio_device_unregister(indio_dev);
 516 
 517         pm_runtime_disable(&client->dev);
 518         pm_runtime_set_suspended(&client->dev);
 519         pm_runtime_put_noidle(&client->dev);
 520 
 521         mutex_lock(&data->mutex);
 522         mma9551_set_device_state(data->client, false);
 523         mutex_unlock(&data->mutex);
 524 
 525         return 0;
 526 }
 527 
 528 #ifdef CONFIG_PM
 529 static int mma9551_runtime_suspend(struct device *dev)
 530 {
 531         struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 532         struct mma9551_data *data = iio_priv(indio_dev);
 533         int ret;
 534 
 535         mutex_lock(&data->mutex);
 536         ret = mma9551_set_device_state(data->client, false);
 537         mutex_unlock(&data->mutex);
 538         if (ret < 0) {
 539                 dev_err(&data->client->dev, "powering off device failed\n");
 540                 return -EAGAIN;
 541         }
 542 
 543         return 0;
 544 }
 545 
 546 static int mma9551_runtime_resume(struct device *dev)
 547 {
 548         struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 549         struct mma9551_data *data = iio_priv(indio_dev);
 550         int ret;
 551 
 552         ret = mma9551_set_device_state(data->client, true);
 553         if (ret < 0)
 554                 return ret;
 555 
 556         mma9551_sleep(MMA9551_DEFAULT_SAMPLE_RATE);
 557 
 558         return 0;
 559 }
 560 #endif
 561 
 562 #ifdef CONFIG_PM_SLEEP
 563 static int mma9551_suspend(struct device *dev)
 564 {
 565         struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 566         struct mma9551_data *data = iio_priv(indio_dev);
 567         int ret;
 568 
 569         mutex_lock(&data->mutex);
 570         ret = mma9551_set_device_state(data->client, false);
 571         mutex_unlock(&data->mutex);
 572 
 573         return ret;
 574 }
 575 
 576 static int mma9551_resume(struct device *dev)
 577 {
 578         struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 579         struct mma9551_data *data = iio_priv(indio_dev);
 580         int ret;
 581 
 582         mutex_lock(&data->mutex);
 583         ret = mma9551_set_device_state(data->client, true);
 584         mutex_unlock(&data->mutex);
 585 
 586         return ret;
 587 }
 588 #endif
 589 
 590 static const struct dev_pm_ops mma9551_pm_ops = {
 591         SET_SYSTEM_SLEEP_PM_OPS(mma9551_suspend, mma9551_resume)
 592         SET_RUNTIME_PM_OPS(mma9551_runtime_suspend,
 593                            mma9551_runtime_resume, NULL)
 594 };
 595 
 596 static const struct acpi_device_id mma9551_acpi_match[] = {
 597         {"MMA9551", 0},
 598         {},
 599 };
 600 
 601 MODULE_DEVICE_TABLE(acpi, mma9551_acpi_match);
 602 
 603 static const struct i2c_device_id mma9551_id[] = {
 604         {"mma9551", 0},
 605         {}
 606 };
 607 
 608 MODULE_DEVICE_TABLE(i2c, mma9551_id);
 609 
 610 static struct i2c_driver mma9551_driver = {
 611         .driver = {
 612                    .name = MMA9551_DRV_NAME,
 613                    .acpi_match_table = ACPI_PTR(mma9551_acpi_match),
 614                    .pm = &mma9551_pm_ops,
 615                    },
 616         .probe = mma9551_probe,
 617         .remove = mma9551_remove,
 618         .id_table = mma9551_id,
 619 };
 620 
 621 module_i2c_driver(mma9551_driver);
 622 
 623 MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
 624 MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
 625 MODULE_LICENSE("GPL v2");
 626 MODULE_DESCRIPTION("MMA9551L motion-sensing platform driver");

/* [<][>][^][v][top][bottom][index][help] */