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