0001
0002
0003
0004
0005
0006
0007
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, ®, 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
0144
0145
0146
0147 { .compatible = "adi,adxl345", },
0148
0149
0150
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");