xref: /openbmc/linux/drivers/input/misc/adxl34x-i2c.c (revision fbb89935)
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, &reg, 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