xref: /openbmc/linux/drivers/input/misc/adxl34x-i2c.c (revision d8bde56d)
180503b23SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2e27c7292SMichael Hennerich /*
3e27c7292SMichael Hennerich  * ADLX345/346 Three-Axis Digital Accelerometers (I2C Interface)
4e27c7292SMichael Hennerich  *
5e27c7292SMichael Hennerich  * Enter bugs at http://blackfin.uclinux.org/
6e27c7292SMichael Hennerich  *
7e27c7292SMichael Hennerich  * Copyright (C) 2009 Michael Hennerich, Analog Devices Inc.
8e27c7292SMichael Hennerich  */
9e27c7292SMichael Hennerich 
10e27c7292SMichael Hennerich #include <linux/input.h>	/* BUS_I2C */
11e27c7292SMichael Hennerich #include <linux/i2c.h>
12e27c7292SMichael Hennerich #include <linux/module.h>
133a38958dSLaurent Pinchart #include <linux/of.h>
14e27c7292SMichael Hennerich #include <linux/types.h>
15fbb89935SMark Brown #include <linux/pm.h>
16e27c7292SMichael Hennerich #include "adxl34x.h"
17e27c7292SMichael Hennerich 
adxl34x_smbus_read(struct device * dev,unsigned char reg)18e27c7292SMichael Hennerich static int adxl34x_smbus_read(struct device *dev, unsigned char reg)
19e27c7292SMichael Hennerich {
20e27c7292SMichael Hennerich 	struct i2c_client *client = to_i2c_client(dev);
21e27c7292SMichael Hennerich 
22e27c7292SMichael Hennerich 	return i2c_smbus_read_byte_data(client, reg);
23e27c7292SMichael Hennerich }
24e27c7292SMichael Hennerich 
adxl34x_smbus_write(struct device * dev,unsigned char reg,unsigned char val)25e27c7292SMichael Hennerich static int adxl34x_smbus_write(struct device *dev,
26e27c7292SMichael Hennerich 			       unsigned char reg, unsigned char val)
27e27c7292SMichael Hennerich {
28e27c7292SMichael Hennerich 	struct i2c_client *client = to_i2c_client(dev);
29e27c7292SMichael Hennerich 
30e27c7292SMichael Hennerich 	return i2c_smbus_write_byte_data(client, reg, val);
31e27c7292SMichael Hennerich }
32e27c7292SMichael Hennerich 
adxl34x_smbus_read_block(struct device * dev,unsigned char reg,int count,void * buf)33e27c7292SMichael Hennerich static int adxl34x_smbus_read_block(struct device *dev,
34e27c7292SMichael Hennerich 				    unsigned char reg, int count,
35e27c7292SMichael Hennerich 				    void *buf)
36e27c7292SMichael Hennerich {
37e27c7292SMichael Hennerich 	struct i2c_client *client = to_i2c_client(dev);
38e27c7292SMichael Hennerich 
39e27c7292SMichael Hennerich 	return i2c_smbus_read_i2c_block_data(client, reg, count, buf);
40e27c7292SMichael Hennerich }
41e27c7292SMichael Hennerich 
adxl34x_i2c_read_block(struct device * dev,unsigned char reg,int count,void * buf)42e27c7292SMichael Hennerich static int adxl34x_i2c_read_block(struct device *dev,
43e27c7292SMichael Hennerich 				  unsigned char reg, int count,
44e27c7292SMichael Hennerich 				  void *buf)
45e27c7292SMichael Hennerich {
46e27c7292SMichael Hennerich 	struct i2c_client *client = to_i2c_client(dev);
47e27c7292SMichael Hennerich 	int ret;
48e27c7292SMichael Hennerich 
49e27c7292SMichael Hennerich 	ret = i2c_master_send(client, &reg, 1);
50e27c7292SMichael Hennerich 	if (ret < 0)
51e27c7292SMichael Hennerich 		return ret;
52e27c7292SMichael Hennerich 
53e27c7292SMichael Hennerich 	ret = i2c_master_recv(client, buf, count);
54e27c7292SMichael Hennerich 	if (ret < 0)
55e27c7292SMichael Hennerich 		return ret;
56e27c7292SMichael Hennerich 
57e27c7292SMichael Hennerich 	if (ret != count)
58e27c7292SMichael Hennerich 		return -EIO;
59e27c7292SMichael Hennerich 
60e27c7292SMichael Hennerich 	return 0;
61e27c7292SMichael Hennerich }
62e27c7292SMichael Hennerich 
63af6e1d99SDmitry Torokhov static const struct adxl34x_bus_ops adxl34x_smbus_bops = {
64e27c7292SMichael Hennerich 	.bustype	= BUS_I2C,
65e27c7292SMichael Hennerich 	.write		= adxl34x_smbus_write,
66e27c7292SMichael Hennerich 	.read		= adxl34x_smbus_read,
67e27c7292SMichael Hennerich 	.read_block	= adxl34x_smbus_read_block,
68e27c7292SMichael Hennerich };
69e27c7292SMichael Hennerich 
70af6e1d99SDmitry Torokhov static const struct adxl34x_bus_ops adxl34x_i2c_bops = {
71e27c7292SMichael Hennerich 	.bustype	= BUS_I2C,
72e27c7292SMichael Hennerich 	.write		= adxl34x_smbus_write,
73e27c7292SMichael Hennerich 	.read		= adxl34x_smbus_read,
74e27c7292SMichael Hennerich 	.read_block	= adxl34x_i2c_read_block,
75e27c7292SMichael Hennerich };
76e27c7292SMichael Hennerich 
adxl34x_i2c_probe(struct i2c_client * client)77e186e84eSUwe Kleine-König static int adxl34x_i2c_probe(struct i2c_client *client)
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 
adxl34x_i2c_remove(struct i2c_client * client)101ed5c2f5fSUwe Kleine-König static void adxl34x_i2c_remove(struct i2c_client *client)
102e27c7292SMichael Hennerich {
103e27c7292SMichael Hennerich 	struct adxl34x *ac = i2c_get_clientdata(client);
104e27c7292SMichael Hennerich 
105af98ff04SUwe Kleine-König 	adxl34x_remove(ac);
106e27c7292SMichael Hennerich }
107e27c7292SMichael Hennerich 
108e27c7292SMichael Hennerich static const struct i2c_device_id adxl34x_id[] = {
109e27c7292SMichael Hennerich 	{ "adxl34x", 0 },
110e27c7292SMichael Hennerich 	{ }
111e27c7292SMichael Hennerich };
112e27c7292SMichael Hennerich 
113e27c7292SMichael Hennerich MODULE_DEVICE_TABLE(i2c, adxl34x_id);
114e27c7292SMichael Hennerich 
1153a38958dSLaurent Pinchart static const struct of_device_id adxl34x_of_id[] = {
1163a38958dSLaurent Pinchart 	/*
1173a38958dSLaurent Pinchart 	 * The ADXL346 is backward-compatible with the ADXL345. Differences are
1183a38958dSLaurent Pinchart 	 * handled by runtime detection of the device model, there's thus no
1193a38958dSLaurent Pinchart 	 * need for listing the "adi,adxl346" compatible value explicitly.
1203a38958dSLaurent Pinchart 	 */
1213a38958dSLaurent Pinchart 	{ .compatible = "adi,adxl345", },
1223a38958dSLaurent Pinchart 	/*
1233a38958dSLaurent Pinchart 	 * Deprecated, DT nodes should use one or more of the device-specific
1243a38958dSLaurent Pinchart 	 * compatible values "adi,adxl345" and "adi,adxl346".
1253a38958dSLaurent Pinchart 	 */
1263a38958dSLaurent Pinchart 	{ .compatible = "adi,adxl34x", },
1273a38958dSLaurent Pinchart 	{ }
1283a38958dSLaurent Pinchart };
1293a38958dSLaurent Pinchart 
1303a38958dSLaurent Pinchart MODULE_DEVICE_TABLE(of, adxl34x_of_id);
1313a38958dSLaurent Pinchart 
132e27c7292SMichael Hennerich static struct i2c_driver adxl34x_driver = {
133e27c7292SMichael Hennerich 	.driver = {
134e27c7292SMichael Hennerich 		.name = "adxl34x",
13540be0646SJonathan Cameron 		.pm = pm_sleep_ptr(&adxl34x_pm),
13601427fe7SAndy Shevchenko 		.of_match_table = adxl34x_of_id,
137e27c7292SMichael Hennerich 	},
138*d8bde56dSUwe Kleine-König 	.probe    = adxl34x_i2c_probe,
1391cb0aa88SBill Pemberton 	.remove   = adxl34x_i2c_remove,
140e27c7292SMichael Hennerich 	.id_table = adxl34x_id,
141e27c7292SMichael Hennerich };
142e27c7292SMichael Hennerich 
1431b92c1cfSAxel Lin module_i2c_driver(adxl34x_driver);
144e27c7292SMichael Hennerich 
145e27c7292SMichael Hennerich MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
146e27c7292SMichael Hennerich MODULE_DESCRIPTION("ADXL345/346 Three-Axis Digital Accelerometer I2C Bus Driver");
147e27c7292SMichael Hennerich MODULE_LICENSE("GPL");
148