linux/drivers/iio/gyro/itg3200_core.c
<<
>>
Prefs
   1/*
   2 * itg3200_core.c -- support InvenSense ITG3200
   3 *                   Digital 3-Axis Gyroscope driver
   4 *
   5 * Copyright (c) 2011 Christian Strobel <christian.strobel@iis.fraunhofer.de>
   6 * Copyright (c) 2011 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
   7 * Copyright (c) 2012 Thorsten Nowak <thorsten.nowak@iis.fraunhofer.de>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 *
  13 * TODO:
  14 * - Support digital low pass filter
  15 * - Support power management
  16 */
  17
  18#include <linux/interrupt.h>
  19#include <linux/irq.h>
  20#include <linux/i2c.h>
  21#include <linux/gpio.h>
  22#include <linux/slab.h>
  23#include <linux/stat.h>
  24#include <linux/module.h>
  25#include <linux/delay.h>
  26
  27#include <linux/iio/iio.h>
  28#include <linux/iio/sysfs.h>
  29#include <linux/iio/events.h>
  30#include <linux/iio/buffer.h>
  31
  32#include <linux/iio/gyro/itg3200.h>
  33
  34
  35int itg3200_write_reg_8(struct iio_dev *indio_dev,
  36                u8 reg_address, u8 val)
  37{
  38        struct itg3200 *st = iio_priv(indio_dev);
  39
  40        return i2c_smbus_write_byte_data(st->i2c, 0x80 | reg_address, val);
  41}
  42
  43int itg3200_read_reg_8(struct iio_dev *indio_dev,
  44                u8 reg_address, u8 *val)
  45{
  46        struct itg3200 *st = iio_priv(indio_dev);
  47        int ret;
  48
  49        ret = i2c_smbus_read_byte_data(st->i2c, reg_address);
  50        if (ret < 0)
  51                return ret;
  52        *val = ret;
  53        return 0;
  54}
  55
  56static int itg3200_read_reg_s16(struct iio_dev *indio_dev, u8 lower_reg_address,
  57                int *val)
  58{
  59        struct itg3200 *st = iio_priv(indio_dev);
  60        struct i2c_client *client = st->i2c;
  61        int ret;
  62        s16 out;
  63
  64        struct i2c_msg msg[2] = {
  65                {
  66                        .addr = client->addr,
  67                        .flags = client->flags,
  68                        .len = 1,
  69                        .buf = (char *)&lower_reg_address,
  70                },
  71                {
  72                        .addr = client->addr,
  73                        .flags = client->flags | I2C_M_RD,
  74                        .len = 2,
  75                        .buf = (char *)&out,
  76                },
  77        };
  78
  79        lower_reg_address |= 0x80;
  80        ret = i2c_transfer(client->adapter, msg, 2);
  81        be16_to_cpus(&out);
  82        *val = out;
  83
  84        return (ret == 2) ? 0 : ret;
  85}
  86
  87static int itg3200_read_raw(struct iio_dev *indio_dev,
  88                const struct iio_chan_spec *chan,
  89                int *val, int *val2, long info)
  90{
  91        int ret = 0;
  92        u8 reg;
  93
  94        switch (info) {
  95        case IIO_CHAN_INFO_RAW:
  96                reg = (u8)chan->address;
  97                ret = itg3200_read_reg_s16(indio_dev, reg, val);
  98                return IIO_VAL_INT;
  99        case IIO_CHAN_INFO_SCALE:
 100                *val = 0;
 101                if (chan->type == IIO_TEMP)
 102                        *val2 = 1000000000/280;
 103                else
 104                        *val2 = 1214142; /* (1 / 14,375) * (PI / 180) */
 105                return IIO_VAL_INT_PLUS_NANO;
 106        case IIO_CHAN_INFO_OFFSET:
 107                /* Only the temperature channel has an offset */
 108                *val = 23000;
 109                return IIO_VAL_INT;
 110        default:
 111                return -EINVAL;
 112        }
 113
 114        return ret;
 115}
 116
 117static ssize_t itg3200_read_frequency(struct device *dev,
 118                struct device_attribute *attr, char *buf)
 119{
 120        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 121        int ret, sps;
 122        u8 val;
 123
 124        ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &val);
 125        if (ret)
 126                return ret;
 127
 128        sps = (val & ITG3200_DLPF_CFG_MASK) ? 1000 : 8000;
 129
 130        ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_SAMPLE_RATE_DIV, &val);
 131        if (ret)
 132                return ret;
 133
 134        sps /= val + 1;
 135
 136        return sprintf(buf, "%d\n", sps);
 137}
 138
 139static ssize_t itg3200_write_frequency(struct device *dev,
 140                struct device_attribute *attr,
 141                const char *buf,
 142                size_t len)
 143{
 144        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 145        unsigned val;
 146        int ret;
 147        u8 t;
 148
 149        ret = kstrtouint(buf, 10, &val);
 150        if (ret)
 151                return ret;
 152
 153        mutex_lock(&indio_dev->mlock);
 154
 155        ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &t);
 156        if (ret)
 157                goto err_ret;
 158
 159        if (val == 0) {
 160                ret = -EINVAL;
 161                goto err_ret;
 162        }
 163        t = ((t & ITG3200_DLPF_CFG_MASK) ? 1000u : 8000u) / val - 1;
 164
 165        ret = itg3200_write_reg_8(indio_dev, ITG3200_REG_SAMPLE_RATE_DIV, t);
 166
 167err_ret:
 168        mutex_unlock(&indio_dev->mlock);
 169
 170        return ret ? ret : len;
 171}
 172
 173/*
 174 * Reset device and internal registers to the power-up-default settings
 175 * Use the gyro clock as reference, as suggested by the datasheet
 176 */
 177static int itg3200_reset(struct iio_dev *indio_dev)
 178{
 179        struct itg3200 *st = iio_priv(indio_dev);
 180        int ret;
 181
 182        dev_dbg(&st->i2c->dev, "reset device");
 183
 184        ret = itg3200_write_reg_8(indio_dev,
 185                        ITG3200_REG_POWER_MANAGEMENT,
 186                        ITG3200_RESET);
 187        if (ret) {
 188                dev_err(&st->i2c->dev, "error resetting device");
 189                goto error_ret;
 190        }
 191
 192        /* Wait for PLL (1ms according to datasheet) */
 193        udelay(1500);
 194
 195        ret = itg3200_write_reg_8(indio_dev,
 196                        ITG3200_REG_IRQ_CONFIG,
 197                        ITG3200_IRQ_ACTIVE_HIGH |
 198                        ITG3200_IRQ_PUSH_PULL |
 199                        ITG3200_IRQ_LATCH_50US_PULSE |
 200                        ITG3200_IRQ_LATCH_CLEAR_ANY);
 201
 202        if (ret)
 203                dev_err(&st->i2c->dev, "error init device");
 204
 205error_ret:
 206        return ret;
 207}
 208
 209/* itg3200_enable_full_scale() - Disables the digital low pass filter */
 210static int itg3200_enable_full_scale(struct iio_dev *indio_dev)
 211{
 212        u8 val;
 213        int ret;
 214
 215        ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &val);
 216        if (ret)
 217                goto err_ret;
 218
 219        val |= ITG3200_DLPF_FS_SEL_2000;
 220        return itg3200_write_reg_8(indio_dev, ITG3200_REG_DLPF, val);
 221
 222err_ret:
 223        return ret;
 224}
 225
 226static int itg3200_initial_setup(struct iio_dev *indio_dev)
 227{
 228        struct itg3200 *st = iio_priv(indio_dev);
 229        int ret;
 230        u8 val;
 231
 232        ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_ADDRESS, &val);
 233        if (ret)
 234                goto err_ret;
 235
 236        if (((val >> 1) & 0x3f) != 0x34) {
 237                dev_err(&st->i2c->dev, "invalid reg value 0x%02x", val);
 238                ret = -ENXIO;
 239                goto err_ret;
 240        }
 241
 242        ret = itg3200_reset(indio_dev);
 243        if (ret)
 244                goto err_ret;
 245
 246        ret = itg3200_enable_full_scale(indio_dev);
 247err_ret:
 248        return ret;
 249}
 250
 251#define ITG3200_ST                                              \
 252        { .sign = 's', .realbits = 16, .storagebits = 16, .endianness = IIO_BE }
 253
 254#define ITG3200_GYRO_CHAN(_mod) { \
 255        .type = IIO_ANGL_VEL, \
 256        .modified = 1, \
 257        .channel2 = IIO_MOD_ ## _mod, \
 258        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
 259        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
 260        .address = ITG3200_REG_GYRO_ ## _mod ## OUT_H, \
 261        .scan_index = ITG3200_SCAN_GYRO_ ## _mod, \
 262        .scan_type = ITG3200_ST, \
 263}
 264
 265static const struct iio_chan_spec itg3200_channels[] = {
 266        {
 267                .type = IIO_TEMP,
 268                .channel2 = IIO_NO_MOD,
 269                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 270                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
 271                BIT(IIO_CHAN_INFO_SCALE),
 272                .address = ITG3200_REG_TEMP_OUT_H,
 273                .scan_index = ITG3200_SCAN_TEMP,
 274                .scan_type = ITG3200_ST,
 275        },
 276        ITG3200_GYRO_CHAN(X),
 277        ITG3200_GYRO_CHAN(Y),
 278        ITG3200_GYRO_CHAN(Z),
 279        IIO_CHAN_SOFT_TIMESTAMP(ITG3200_SCAN_ELEMENTS),
 280};
 281
 282/* IIO device attributes */
 283static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, itg3200_read_frequency,
 284                itg3200_write_frequency);
 285
 286static struct attribute *itg3200_attributes[] = {
 287        &iio_dev_attr_sampling_frequency.dev_attr.attr,
 288        NULL
 289};
 290
 291static const struct attribute_group itg3200_attribute_group = {
 292        .attrs = itg3200_attributes,
 293};
 294
 295static const struct iio_info itg3200_info = {
 296        .attrs = &itg3200_attribute_group,
 297        .read_raw = &itg3200_read_raw,
 298        .driver_module = THIS_MODULE,
 299};
 300
 301static const unsigned long itg3200_available_scan_masks[] = { 0xffffffff, 0x0 };
 302
 303static int itg3200_probe(struct i2c_client *client,
 304                const struct i2c_device_id *id)
 305{
 306        int ret;
 307        struct itg3200 *st;
 308        struct iio_dev *indio_dev;
 309
 310        dev_dbg(&client->dev, "probe I2C dev with IRQ %i", client->irq);
 311
 312        indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
 313        if (!indio_dev)
 314                return -ENOMEM;
 315
 316        st = iio_priv(indio_dev);
 317
 318        i2c_set_clientdata(client, indio_dev);
 319        st->i2c = client;
 320
 321        indio_dev->dev.parent = &client->dev;
 322        indio_dev->name = client->dev.driver->name;
 323        indio_dev->channels = itg3200_channels;
 324        indio_dev->num_channels = ARRAY_SIZE(itg3200_channels);
 325        indio_dev->available_scan_masks = itg3200_available_scan_masks;
 326        indio_dev->info = &itg3200_info;
 327        indio_dev->modes = INDIO_DIRECT_MODE;
 328
 329        ret = itg3200_buffer_configure(indio_dev);
 330        if (ret)
 331                return ret;
 332
 333        if (client->irq) {
 334                ret = itg3200_probe_trigger(indio_dev);
 335                if (ret)
 336                        goto error_unconfigure_buffer;
 337        }
 338
 339        ret = itg3200_initial_setup(indio_dev);
 340        if (ret)
 341                goto error_remove_trigger;
 342
 343        ret = iio_device_register(indio_dev);
 344        if (ret)
 345                goto error_remove_trigger;
 346
 347        return 0;
 348
 349error_remove_trigger:
 350        if (client->irq)
 351                itg3200_remove_trigger(indio_dev);
 352error_unconfigure_buffer:
 353        itg3200_buffer_unconfigure(indio_dev);
 354        return ret;
 355}
 356
 357static int itg3200_remove(struct i2c_client *client)
 358{
 359        struct iio_dev *indio_dev = i2c_get_clientdata(client);
 360
 361        iio_device_unregister(indio_dev);
 362
 363        if (client->irq)
 364                itg3200_remove_trigger(indio_dev);
 365
 366        itg3200_buffer_unconfigure(indio_dev);
 367
 368        return 0;
 369}
 370
 371static const struct i2c_device_id itg3200_id[] = {
 372        { "itg3200", 0 },
 373        { }
 374};
 375MODULE_DEVICE_TABLE(i2c, itg3200_id);
 376
 377static struct i2c_driver itg3200_driver = {
 378        .driver = {
 379                .owner  = THIS_MODULE,
 380                .name   = "itg3200",
 381        },
 382        .id_table       = itg3200_id,
 383        .probe          = itg3200_probe,
 384        .remove         = itg3200_remove,
 385};
 386
 387module_i2c_driver(itg3200_driver);
 388
 389MODULE_AUTHOR("Christian Strobel <christian.strobel@iis.fraunhofer.de>");
 390MODULE_DESCRIPTION("ITG3200 Gyroscope I2C driver");
 391MODULE_LICENSE("GPL v2");
 392