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