xref: /openbmc/linux/drivers/input/misc/ad714x-i2c.c (revision c0409feb)
131a62963SBryan Wu /*
231a62963SBryan Wu  * AD714X CapTouch Programmable Controller driver (I2C bus)
331a62963SBryan Wu  *
431a62963SBryan Wu  * Copyright 2009 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;
47c0409febSDmitry Torokhov }
48c0409febSDmitry Torokhov 
49c0409febSDmitry Torokhov static int ad714x_i2c_read(struct ad714x_chip *chip,
50c0409febSDmitry Torokhov 			   unsigned short reg, unsigned short *data)
5131a62963SBryan Wu {
52c0409febSDmitry Torokhov 	struct i2c_client *client = to_i2c_client(chip->dev);
53c0409febSDmitry Torokhov 	int error;
5431a62963SBryan Wu 
55c0409febSDmitry Torokhov 	chip->xfer_buf[0] = cpu_to_be16(reg);
5631a62963SBryan Wu 
57c0409febSDmitry Torokhov 	error = i2c_master_send(client, (u8 *)chip->xfer_buf,
58c0409febSDmitry Torokhov 				sizeof(*chip->xfer_buf));
59c0409febSDmitry Torokhov 	if (error >= 0)
60c0409febSDmitry Torokhov 		error = i2c_master_recv(client, (u8 *)chip->xfer_buf,
61c0409febSDmitry Torokhov 					sizeof(*chip->xfer_buf));
6231a62963SBryan Wu 
63c0409febSDmitry Torokhov 	if (unlikely(error < 0)) {
64c0409febSDmitry Torokhov 		dev_err(&client->dev, "I2C read error: %d\n", error);
65c0409febSDmitry Torokhov 		return error;
66c0409febSDmitry Torokhov 	}
67c0409febSDmitry Torokhov 
68c0409febSDmitry Torokhov 	*data = be16_to_cpup(chip->xfer_buf);
69c0409febSDmitry Torokhov 	return 0;
7031a62963SBryan Wu }
7131a62963SBryan Wu 
7231a62963SBryan Wu static int __devinit ad714x_i2c_probe(struct i2c_client *client,
7331a62963SBryan Wu 					const struct i2c_device_id *id)
7431a62963SBryan Wu {
7531a62963SBryan Wu 	struct ad714x_chip *chip;
7631a62963SBryan Wu 
7731a62963SBryan Wu 	chip = ad714x_probe(&client->dev, BUS_I2C, client->irq,
7831a62963SBryan Wu 			    ad714x_i2c_read, ad714x_i2c_write);
7931a62963SBryan Wu 	if (IS_ERR(chip))
8031a62963SBryan Wu 		return PTR_ERR(chip);
8131a62963SBryan Wu 
8231a62963SBryan Wu 	i2c_set_clientdata(client, chip);
8331a62963SBryan Wu 
8431a62963SBryan Wu 	return 0;
8531a62963SBryan Wu }
8631a62963SBryan Wu 
8731a62963SBryan Wu static int __devexit ad714x_i2c_remove(struct i2c_client *client)
8831a62963SBryan Wu {
8931a62963SBryan Wu 	struct ad714x_chip *chip = i2c_get_clientdata(client);
9031a62963SBryan Wu 
9131a62963SBryan Wu 	ad714x_remove(chip);
9231a62963SBryan Wu 
9331a62963SBryan Wu 	return 0;
9431a62963SBryan Wu }
9531a62963SBryan Wu 
9631a62963SBryan Wu static const struct i2c_device_id ad714x_id[] = {
9731a62963SBryan Wu 	{ "ad7142_captouch", 0 },
986c04d7b3SBarry Song 	{ "ad7143_captouch", 0 },
9931a62963SBryan Wu 	{ "ad7147_captouch", 0 },
1006c04d7b3SBarry Song 	{ "ad7147a_captouch", 0 },
1016c04d7b3SBarry Song 	{ "ad7148_captouch", 0 },
10231a62963SBryan Wu 	{ }
10331a62963SBryan Wu };
10431a62963SBryan Wu MODULE_DEVICE_TABLE(i2c, ad714x_id);
10531a62963SBryan Wu 
10631a62963SBryan Wu static struct i2c_driver ad714x_i2c_driver = {
10731a62963SBryan Wu 	.driver = {
10831a62963SBryan Wu 		.name = "ad714x_captouch",
1096b7cfd19SMark Brown 		.pm   = &ad714x_i2c_pm,
11031a62963SBryan Wu 	},
11131a62963SBryan Wu 	.probe    = ad714x_i2c_probe,
11231a62963SBryan Wu 	.remove   = __devexit_p(ad714x_i2c_remove),
11331a62963SBryan Wu 	.id_table = ad714x_id,
11431a62963SBryan Wu };
11531a62963SBryan Wu 
11631a62963SBryan Wu static __init int ad714x_i2c_init(void)
11731a62963SBryan Wu {
11831a62963SBryan Wu 	return i2c_add_driver(&ad714x_i2c_driver);
11931a62963SBryan Wu }
12031a62963SBryan Wu module_init(ad714x_i2c_init);
12131a62963SBryan Wu 
12231a62963SBryan Wu static __exit void ad714x_i2c_exit(void)
12331a62963SBryan Wu {
12431a62963SBryan Wu 	i2c_del_driver(&ad714x_i2c_driver);
12531a62963SBryan Wu }
12631a62963SBryan Wu module_exit(ad714x_i2c_exit);
12731a62963SBryan Wu 
12831a62963SBryan Wu MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor I2C Bus Driver");
12931a62963SBryan Wu MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
13031a62963SBryan Wu MODULE_LICENSE("GPL");
131