xref: /openbmc/linux/drivers/input/misc/ad714x-i2c.c (revision 1b92c1cf)
131a62963SBryan Wu /*
231a62963SBryan Wu  * AD714X CapTouch Programmable Controller driver (I2C bus)
331a62963SBryan Wu  *
49eff794bSMichael Hennerich  * Copyright 2009-2011 Analog Devices Inc.
531a62963SBryan Wu  *
631a62963SBryan Wu  * Licensed under the GPL-2 or later.
731a62963SBryan Wu  */
831a62963SBryan Wu 
931a62963SBryan Wu #include <linux/input.h>	/* BUS_I2C */
1031a62963SBryan Wu #include <linux/i2c.h>
1131a62963SBryan Wu #include <linux/module.h>
1231a62963SBryan Wu #include <linux/types.h>
136b7cfd19SMark Brown #include <linux/pm.h>
1431a62963SBryan Wu #include "ad714x.h"
1531a62963SBryan Wu 
1631a62963SBryan Wu #ifdef CONFIG_PM
176b7cfd19SMark Brown static int ad714x_i2c_suspend(struct device *dev)
1831a62963SBryan Wu {
196b7cfd19SMark Brown 	return ad714x_disable(i2c_get_clientdata(to_i2c_client(dev)));
2031a62963SBryan Wu }
2131a62963SBryan Wu 
226b7cfd19SMark Brown static int ad714x_i2c_resume(struct device *dev)
2331a62963SBryan Wu {
246b7cfd19SMark Brown 	return ad714x_enable(i2c_get_clientdata(to_i2c_client(dev)));
2531a62963SBryan Wu }
2631a62963SBryan Wu #endif
2731a62963SBryan Wu 
286b7cfd19SMark Brown static SIMPLE_DEV_PM_OPS(ad714x_i2c_pm, ad714x_i2c_suspend, ad714x_i2c_resume);
296b7cfd19SMark Brown 
30c0409febSDmitry Torokhov static int ad714x_i2c_write(struct ad714x_chip *chip,
31c0409febSDmitry Torokhov 			    unsigned short reg, unsigned short data)
3231a62963SBryan Wu {
33c0409febSDmitry Torokhov 	struct i2c_client *client = to_i2c_client(chip->dev);
34c0409febSDmitry Torokhov 	int error;
3531a62963SBryan Wu 
36c0409febSDmitry Torokhov 	chip->xfer_buf[0] = cpu_to_be16(reg);
37c0409febSDmitry Torokhov 	chip->xfer_buf[1] = cpu_to_be16(data);
3831a62963SBryan Wu 
39c0409febSDmitry Torokhov 	error = i2c_master_send(client, (u8 *)chip->xfer_buf,
40c0409febSDmitry Torokhov 				2 * sizeof(*chip->xfer_buf));
41c0409febSDmitry Torokhov 	if (unlikely(error < 0)) {
42c0409febSDmitry Torokhov 		dev_err(&client->dev, "I2C write error: %d\n", error);
43c0409febSDmitry Torokhov 		return error;
4431a62963SBryan Wu 	}
4531a62963SBryan Wu 
46c0409febSDmitry Torokhov 	return 0;
4731a62963SBryan Wu }
4831a62963SBryan Wu 
49c0409febSDmitry Torokhov static int ad714x_i2c_read(struct ad714x_chip *chip,
509eff794bSMichael Hennerich 			   unsigned short reg, unsigned short *data, size_t len)
5131a62963SBryan Wu {
52c0409febSDmitry Torokhov 	struct i2c_client *client = to_i2c_client(chip->dev);
539eff794bSMichael Hennerich 	int i;
54c0409febSDmitry Torokhov 	int error;
5531a62963SBryan Wu 
56c0409febSDmitry Torokhov 	chip->xfer_buf[0] = cpu_to_be16(reg);
5731a62963SBryan Wu 
58c0409febSDmitry Torokhov 	error = i2c_master_send(client, (u8 *)chip->xfer_buf,
59c0409febSDmitry Torokhov 				sizeof(*chip->xfer_buf));
60c0409febSDmitry Torokhov 	if (error >= 0)
61c0409febSDmitry Torokhov 		error = i2c_master_recv(client, (u8 *)chip->xfer_buf,
629eff794bSMichael Hennerich 					len * sizeof(*chip->xfer_buf));
6331a62963SBryan Wu 
64c0409febSDmitry Torokhov 	if (unlikely(error < 0)) {
65c0409febSDmitry Torokhov 		dev_err(&client->dev, "I2C read error: %d\n", error);
66c0409febSDmitry Torokhov 		return error;
67c0409febSDmitry Torokhov 	}
68c0409febSDmitry Torokhov 
699eff794bSMichael Hennerich 	for (i = 0; i < len; i++)
709eff794bSMichael Hennerich 		data[i] = be16_to_cpu(chip->xfer_buf[i]);
719eff794bSMichael Hennerich 
72c0409febSDmitry Torokhov 	return 0;
7331a62963SBryan Wu }
7431a62963SBryan Wu 
7531a62963SBryan Wu static int __devinit ad714x_i2c_probe(struct i2c_client *client,
7631a62963SBryan Wu 					const struct i2c_device_id *id)
7731a62963SBryan Wu {
7831a62963SBryan Wu 	struct ad714x_chip *chip;
7931a62963SBryan Wu 
8031a62963SBryan Wu 	chip = ad714x_probe(&client->dev, BUS_I2C, client->irq,
8131a62963SBryan Wu 			    ad714x_i2c_read, ad714x_i2c_write);
8231a62963SBryan Wu 	if (IS_ERR(chip))
8331a62963SBryan Wu 		return PTR_ERR(chip);
8431a62963SBryan Wu 
8531a62963SBryan Wu 	i2c_set_clientdata(client, chip);
8631a62963SBryan Wu 
8731a62963SBryan Wu 	return 0;
8831a62963SBryan Wu }
8931a62963SBryan Wu 
9031a62963SBryan Wu static int __devexit ad714x_i2c_remove(struct i2c_client *client)
9131a62963SBryan Wu {
9231a62963SBryan Wu 	struct ad714x_chip *chip = i2c_get_clientdata(client);
9331a62963SBryan Wu 
9431a62963SBryan Wu 	ad714x_remove(chip);
9531a62963SBryan Wu 
9631a62963SBryan Wu 	return 0;
9731a62963SBryan Wu }
9831a62963SBryan Wu 
9931a62963SBryan Wu static const struct i2c_device_id ad714x_id[] = {
10031a62963SBryan Wu 	{ "ad7142_captouch", 0 },
1016c04d7b3SBarry Song 	{ "ad7143_captouch", 0 },
10231a62963SBryan Wu 	{ "ad7147_captouch", 0 },
1036c04d7b3SBarry Song 	{ "ad7147a_captouch", 0 },
1046c04d7b3SBarry Song 	{ "ad7148_captouch", 0 },
10531a62963SBryan Wu 	{ }
10631a62963SBryan Wu };
10731a62963SBryan Wu MODULE_DEVICE_TABLE(i2c, ad714x_id);
10831a62963SBryan Wu 
10931a62963SBryan Wu static struct i2c_driver ad714x_i2c_driver = {
11031a62963SBryan Wu 	.driver = {
11131a62963SBryan Wu 		.name = "ad714x_captouch",
1126b7cfd19SMark Brown 		.pm   = &ad714x_i2c_pm,
11331a62963SBryan Wu 	},
11431a62963SBryan Wu 	.probe    = ad714x_i2c_probe,
11531a62963SBryan Wu 	.remove   = __devexit_p(ad714x_i2c_remove),
11631a62963SBryan Wu 	.id_table = ad714x_id,
11731a62963SBryan Wu };
11831a62963SBryan Wu 
1191b92c1cfSAxel Lin module_i2c_driver(ad714x_i2c_driver);
12031a62963SBryan Wu 
12131a62963SBryan Wu MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor I2C Bus Driver");
12231a62963SBryan Wu MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
12331a62963SBryan Wu MODULE_LICENSE("GPL");
124