Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * ADLX345/346 Three-Axis Digital Accelerometers (I2C Interface)
0004  *
0005  * Enter bugs at http://blackfin.uclinux.org/
0006  *
0007  * Copyright (C) 2009 Michael Hennerich, Analog Devices Inc.
0008  */
0009 
0010 #include <linux/input.h>    /* BUS_I2C */
0011 #include <linux/i2c.h>
0012 #include <linux/module.h>
0013 #include <linux/of.h>
0014 #include <linux/types.h>
0015 #include <linux/pm.h>
0016 #include "adxl34x.h"
0017 
0018 static int adxl34x_smbus_read(struct device *dev, unsigned char reg)
0019 {
0020     struct i2c_client *client = to_i2c_client(dev);
0021 
0022     return i2c_smbus_read_byte_data(client, reg);
0023 }
0024 
0025 static int adxl34x_smbus_write(struct device *dev,
0026                    unsigned char reg, unsigned char val)
0027 {
0028     struct i2c_client *client = to_i2c_client(dev);
0029 
0030     return i2c_smbus_write_byte_data(client, reg, val);
0031 }
0032 
0033 static int adxl34x_smbus_read_block(struct device *dev,
0034                     unsigned char reg, int count,
0035                     void *buf)
0036 {
0037     struct i2c_client *client = to_i2c_client(dev);
0038 
0039     return i2c_smbus_read_i2c_block_data(client, reg, count, buf);
0040 }
0041 
0042 static int adxl34x_i2c_read_block(struct device *dev,
0043                   unsigned char reg, int count,
0044                   void *buf)
0045 {
0046     struct i2c_client *client = to_i2c_client(dev);
0047     int ret;
0048 
0049     ret = i2c_master_send(client, &reg, 1);
0050     if (ret < 0)
0051         return ret;
0052 
0053     ret = i2c_master_recv(client, buf, count);
0054     if (ret < 0)
0055         return ret;
0056 
0057     if (ret != count)
0058         return -EIO;
0059 
0060     return 0;
0061 }
0062 
0063 static const struct adxl34x_bus_ops adxl34x_smbus_bops = {
0064     .bustype    = BUS_I2C,
0065     .write      = adxl34x_smbus_write,
0066     .read       = adxl34x_smbus_read,
0067     .read_block = adxl34x_smbus_read_block,
0068 };
0069 
0070 static const struct adxl34x_bus_ops adxl34x_i2c_bops = {
0071     .bustype    = BUS_I2C,
0072     .write      = adxl34x_smbus_write,
0073     .read       = adxl34x_smbus_read,
0074     .read_block = adxl34x_i2c_read_block,
0075 };
0076 
0077 static int adxl34x_i2c_probe(struct i2c_client *client,
0078                        const struct i2c_device_id *id)
0079 {
0080     struct adxl34x *ac;
0081     int error;
0082 
0083     error = i2c_check_functionality(client->adapter,
0084             I2C_FUNC_SMBUS_BYTE_DATA);
0085     if (!error) {
0086         dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
0087         return -EIO;
0088     }
0089 
0090     ac = adxl34x_probe(&client->dev, client->irq, false,
0091                i2c_check_functionality(client->adapter,
0092                            I2C_FUNC_SMBUS_READ_I2C_BLOCK) ?
0093                 &adxl34x_smbus_bops : &adxl34x_i2c_bops);
0094     if (IS_ERR(ac))
0095         return PTR_ERR(ac);
0096 
0097     i2c_set_clientdata(client, ac);
0098 
0099     return 0;
0100 }
0101 
0102 static int adxl34x_i2c_remove(struct i2c_client *client)
0103 {
0104     struct adxl34x *ac = i2c_get_clientdata(client);
0105 
0106     adxl34x_remove(ac);
0107 
0108     return 0;
0109 }
0110 
0111 static int __maybe_unused adxl34x_i2c_suspend(struct device *dev)
0112 {
0113     struct i2c_client *client = to_i2c_client(dev);
0114     struct adxl34x *ac = i2c_get_clientdata(client);
0115 
0116     adxl34x_suspend(ac);
0117 
0118     return 0;
0119 }
0120 
0121 static int __maybe_unused adxl34x_i2c_resume(struct device *dev)
0122 {
0123     struct i2c_client *client = to_i2c_client(dev);
0124     struct adxl34x *ac = i2c_get_clientdata(client);
0125 
0126     adxl34x_resume(ac);
0127 
0128     return 0;
0129 }
0130 
0131 static SIMPLE_DEV_PM_OPS(adxl34x_i2c_pm, adxl34x_i2c_suspend,
0132              adxl34x_i2c_resume);
0133 
0134 static const struct i2c_device_id adxl34x_id[] = {
0135     { "adxl34x", 0 },
0136     { }
0137 };
0138 
0139 MODULE_DEVICE_TABLE(i2c, adxl34x_id);
0140 
0141 static const struct of_device_id adxl34x_of_id[] = {
0142     /*
0143      * The ADXL346 is backward-compatible with the ADXL345. Differences are
0144      * handled by runtime detection of the device model, there's thus no
0145      * need for listing the "adi,adxl346" compatible value explicitly.
0146      */
0147     { .compatible = "adi,adxl345", },
0148     /*
0149      * Deprecated, DT nodes should use one or more of the device-specific
0150      * compatible values "adi,adxl345" and "adi,adxl346".
0151      */
0152     { .compatible = "adi,adxl34x", },
0153     { }
0154 };
0155 
0156 MODULE_DEVICE_TABLE(of, adxl34x_of_id);
0157 
0158 static struct i2c_driver adxl34x_driver = {
0159     .driver = {
0160         .name = "adxl34x",
0161         .pm = &adxl34x_i2c_pm,
0162         .of_match_table = adxl34x_of_id,
0163     },
0164     .probe    = adxl34x_i2c_probe,
0165     .remove   = adxl34x_i2c_remove,
0166     .id_table = adxl34x_id,
0167 };
0168 
0169 module_i2c_driver(adxl34x_driver);
0170 
0171 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
0172 MODULE_DESCRIPTION("ADXL345/346 Three-Axis Digital Accelerometer I2C Bus Driver");
0173 MODULE_LICENSE("GPL");