linux/drivers/input/misc/adxl34x-i2c.c
<<
>>
Prefs
   1/*
   2 * ADLX345/346 Three-Axis Digital Accelerometers (I2C Interface)
   3 *
   4 * Enter bugs at http://blackfin.uclinux.org/
   5 *
   6 * Copyright (C) 2009 Michael Hennerich, Analog Devices Inc.
   7 * Licensed under the GPL-2 or later.
   8 */
   9
  10#include <linux/input.h>        /* BUS_I2C */
  11#include <linux/i2c.h>
  12#include <linux/module.h>
  13#include <linux/types.h>
  14#include <linux/pm.h>
  15#include "adxl34x.h"
  16
  17static int adxl34x_smbus_read(struct device *dev, unsigned char reg)
  18{
  19        struct i2c_client *client = to_i2c_client(dev);
  20
  21        return i2c_smbus_read_byte_data(client, reg);
  22}
  23
  24static int adxl34x_smbus_write(struct device *dev,
  25                               unsigned char reg, unsigned char val)
  26{
  27        struct i2c_client *client = to_i2c_client(dev);
  28
  29        return i2c_smbus_write_byte_data(client, reg, val);
  30}
  31
  32static int adxl34x_smbus_read_block(struct device *dev,
  33                                    unsigned char reg, int count,
  34                                    void *buf)
  35{
  36        struct i2c_client *client = to_i2c_client(dev);
  37
  38        return i2c_smbus_read_i2c_block_data(client, reg, count, buf);
  39}
  40
  41static int adxl34x_i2c_read_block(struct device *dev,
  42                                  unsigned char reg, int count,
  43                                  void *buf)
  44{
  45        struct i2c_client *client = to_i2c_client(dev);
  46        int ret;
  47
  48        ret = i2c_master_send(client, &reg, 1);
  49        if (ret < 0)
  50                return ret;
  51
  52        ret = i2c_master_recv(client, buf, count);
  53        if (ret < 0)
  54                return ret;
  55
  56        if (ret != count)
  57                return -EIO;
  58
  59        return 0;
  60}
  61
  62static const struct adxl34x_bus_ops adxl34x_smbus_bops = {
  63        .bustype        = BUS_I2C,
  64        .write          = adxl34x_smbus_write,
  65        .read           = adxl34x_smbus_read,
  66        .read_block     = adxl34x_smbus_read_block,
  67};
  68
  69static const struct adxl34x_bus_ops adxl34x_i2c_bops = {
  70        .bustype        = BUS_I2C,
  71        .write          = adxl34x_smbus_write,
  72        .read           = adxl34x_smbus_read,
  73        .read_block     = adxl34x_i2c_read_block,
  74};
  75
  76static int adxl34x_i2c_probe(struct i2c_client *client,
  77                                       const struct i2c_device_id *id)
  78{
  79        struct adxl34x *ac;
  80        int error;
  81
  82        error = i2c_check_functionality(client->adapter,
  83                        I2C_FUNC_SMBUS_BYTE_DATA);
  84        if (!error) {
  85                dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
  86                return -EIO;
  87        }
  88
  89        ac = adxl34x_probe(&client->dev, client->irq, false,
  90                           i2c_check_functionality(client->adapter,
  91                                                   I2C_FUNC_SMBUS_READ_I2C_BLOCK) ?
  92                                &adxl34x_smbus_bops : &adxl34x_i2c_bops);
  93        if (IS_ERR(ac))
  94                return PTR_ERR(ac);
  95
  96        i2c_set_clientdata(client, ac);
  97
  98        return 0;
  99}
 100
 101static int adxl34x_i2c_remove(struct i2c_client *client)
 102{
 103        struct adxl34x *ac = i2c_get_clientdata(client);
 104
 105        return adxl34x_remove(ac);
 106}
 107
 108#ifdef CONFIG_PM_SLEEP
 109static int adxl34x_i2c_suspend(struct device *dev)
 110{
 111        struct i2c_client *client = to_i2c_client(dev);
 112        struct adxl34x *ac = i2c_get_clientdata(client);
 113
 114        adxl34x_suspend(ac);
 115
 116        return 0;
 117}
 118
 119static int adxl34x_i2c_resume(struct device *dev)
 120{
 121        struct i2c_client *client = to_i2c_client(dev);
 122        struct adxl34x *ac = i2c_get_clientdata(client);
 123
 124        adxl34x_resume(ac);
 125
 126        return 0;
 127}
 128#endif
 129
 130static SIMPLE_DEV_PM_OPS(adxl34x_i2c_pm, adxl34x_i2c_suspend,
 131                         adxl34x_i2c_resume);
 132
 133static const struct i2c_device_id adxl34x_id[] = {
 134        { "adxl34x", 0 },
 135        { }
 136};
 137
 138MODULE_DEVICE_TABLE(i2c, adxl34x_id);
 139
 140static struct i2c_driver adxl34x_driver = {
 141        .driver = {
 142                .name = "adxl34x",
 143                .owner = THIS_MODULE,
 144                .pm = &adxl34x_i2c_pm,
 145        },
 146        .probe    = adxl34x_i2c_probe,
 147        .remove   = adxl34x_i2c_remove,
 148        .id_table = adxl34x_id,
 149};
 150
 151module_i2c_driver(adxl34x_driver);
 152
 153MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 154MODULE_DESCRIPTION("ADXL345/346 Three-Axis Digital Accelerometer I2C Bus Driver");
 155MODULE_LICENSE("GPL");
 156