• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/input/misc/
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 "adxl34x.h"
15
16static int adxl34x_smbus_read(struct device *dev, unsigned char reg)
17{
18	struct i2c_client *client = to_i2c_client(dev);
19
20	return i2c_smbus_read_byte_data(client, reg);
21}
22
23static int adxl34x_smbus_write(struct device *dev,
24			       unsigned char reg, unsigned char val)
25{
26	struct i2c_client *client = to_i2c_client(dev);
27
28	return i2c_smbus_write_byte_data(client, reg, val);
29}
30
31static int adxl34x_smbus_read_block(struct device *dev,
32				    unsigned char reg, int count,
33				    void *buf)
34{
35	struct i2c_client *client = to_i2c_client(dev);
36
37	return i2c_smbus_read_i2c_block_data(client, reg, count, buf);
38}
39
40static int adxl34x_i2c_read_block(struct device *dev,
41				  unsigned char reg, int count,
42				  void *buf)
43{
44	struct i2c_client *client = to_i2c_client(dev);
45	int ret;
46
47	ret = i2c_master_send(client, &reg, 1);
48	if (ret < 0)
49		return ret;
50
51	ret = i2c_master_recv(client, buf, count);
52	if (ret < 0)
53		return ret;
54
55	if (ret != count)
56		return -EIO;
57
58	return 0;
59}
60
61static const struct adxl34x_bus_ops adxl34x_smbus_bops = {
62	.bustype	= BUS_I2C,
63	.write		= adxl34x_smbus_write,
64	.read		= adxl34x_smbus_read,
65	.read_block	= adxl34x_smbus_read_block,
66};
67
68static const struct adxl34x_bus_ops adxl34x_i2c_bops = {
69	.bustype	= BUS_I2C,
70	.write		= adxl34x_smbus_write,
71	.read		= adxl34x_smbus_read,
72	.read_block	= adxl34x_i2c_read_block,
73};
74
75static int __devinit adxl34x_i2c_probe(struct i2c_client *client,
76				       const struct i2c_device_id *id)
77{
78	struct adxl34x *ac;
79	int error;
80
81	error = i2c_check_functionality(client->adapter,
82			I2C_FUNC_SMBUS_BYTE_DATA);
83	if (!error) {
84		dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
85		return -EIO;
86	}
87
88	ac = adxl34x_probe(&client->dev, client->irq, false,
89			   i2c_check_functionality(client->adapter,
90						   I2C_FUNC_SMBUS_READ_I2C_BLOCK) ?
91				&adxl34x_smbus_bops : &adxl34x_i2c_bops);
92	if (IS_ERR(ac))
93		return PTR_ERR(ac);
94
95	i2c_set_clientdata(client, ac);
96
97	return 0;
98}
99
100static int __devexit adxl34x_i2c_remove(struct i2c_client *client)
101{
102	struct adxl34x *ac = i2c_get_clientdata(client);
103
104	return adxl34x_remove(ac);
105}
106
107#ifdef CONFIG_PM
108static int adxl34x_i2c_suspend(struct i2c_client *client, pm_message_t message)
109{
110	struct adxl34x *ac = i2c_get_clientdata(client);
111
112	adxl34x_suspend(ac);
113
114	return 0;
115}
116
117static int adxl34x_i2c_resume(struct i2c_client *client)
118{
119	struct adxl34x *ac = i2c_get_clientdata(client);
120
121	adxl34x_resume(ac);
122
123	return 0;
124}
125#else
126# define adxl34x_i2c_suspend NULL
127# define adxl34x_i2c_resume  NULL
128#endif
129
130static const struct i2c_device_id adxl34x_id[] = {
131	{ "adxl34x", 0 },
132	{ }
133};
134
135MODULE_DEVICE_TABLE(i2c, adxl34x_id);
136
137static struct i2c_driver adxl34x_driver = {
138	.driver = {
139		.name = "adxl34x",
140		.owner = THIS_MODULE,
141	},
142	.probe    = adxl34x_i2c_probe,
143	.remove   = __devexit_p(adxl34x_i2c_remove),
144	.suspend  = adxl34x_i2c_suspend,
145	.resume   = adxl34x_i2c_resume,
146	.id_table = adxl34x_id,
147};
148
149static int __init adxl34x_i2c_init(void)
150{
151	return i2c_add_driver(&adxl34x_driver);
152}
153module_init(adxl34x_i2c_init);
154
155static void __exit adxl34x_i2c_exit(void)
156{
157	i2c_del_driver(&adxl34x_driver);
158}
159module_exit(adxl34x_i2c_exit);
160
161MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
162MODULE_DESCRIPTION("ADXL345/346 Three-Axis Digital Accelerometer I2C Bus Driver");
163MODULE_LICENSE("GPL");
164