xref: /openbmc/linux/drivers/input/misc/ad714x-i2c.c (revision 6c04d7b3)
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>
1331a62963SBryan Wu #include "ad714x.h"
1431a62963SBryan Wu 
1531a62963SBryan Wu #ifdef CONFIG_PM
1631a62963SBryan Wu static int ad714x_i2c_suspend(struct i2c_client *client, pm_message_t message)
1731a62963SBryan Wu {
1831a62963SBryan Wu 	return ad714x_disable(i2c_get_clientdata(client));
1931a62963SBryan Wu }
2031a62963SBryan Wu 
2131a62963SBryan Wu static int ad714x_i2c_resume(struct i2c_client *client)
2231a62963SBryan Wu {
2331a62963SBryan Wu 	return ad714x_enable(i2c_get_clientdata(client));
2431a62963SBryan Wu }
2531a62963SBryan Wu #else
2631a62963SBryan Wu # define ad714x_i2c_suspend NULL
2731a62963SBryan Wu # define ad714x_i2c_resume  NULL
2831a62963SBryan Wu #endif
2931a62963SBryan Wu 
3031a62963SBryan Wu static int ad714x_i2c_write(struct device *dev, unsigned short reg,
3131a62963SBryan Wu 				unsigned short data)
3231a62963SBryan Wu {
3331a62963SBryan Wu 	struct i2c_client *client = to_i2c_client(dev);
3431a62963SBryan Wu 	int ret = 0;
3531a62963SBryan Wu 	u8 *_reg = (u8 *)&reg;
3631a62963SBryan Wu 	u8 *_data = (u8 *)&data;
3731a62963SBryan Wu 
3831a62963SBryan Wu 	u8 tx[4] = {
3931a62963SBryan Wu 		_reg[1],
4031a62963SBryan Wu 		_reg[0],
4131a62963SBryan Wu 		_data[1],
4231a62963SBryan Wu 		_data[0]
4331a62963SBryan Wu 	};
4431a62963SBryan Wu 
4531a62963SBryan Wu 	ret = i2c_master_send(client, tx, 4);
4631a62963SBryan Wu 	if (ret < 0)
4731a62963SBryan Wu 		dev_err(&client->dev, "I2C write error\n");
4831a62963SBryan Wu 
4931a62963SBryan Wu 	return ret;
5031a62963SBryan Wu }
5131a62963SBryan Wu 
5231a62963SBryan Wu static int ad714x_i2c_read(struct device *dev, unsigned short reg,
5331a62963SBryan Wu 				unsigned short *data)
5431a62963SBryan Wu {
5531a62963SBryan Wu 	struct i2c_client *client = to_i2c_client(dev);
5631a62963SBryan Wu 	int ret = 0;
5731a62963SBryan Wu 	u8 *_reg = (u8 *)&reg;
5831a62963SBryan Wu 	u8 *_data = (u8 *)data;
5931a62963SBryan Wu 
6031a62963SBryan Wu 	u8 tx[2] = {
6131a62963SBryan Wu 		_reg[1],
6231a62963SBryan Wu 		_reg[0]
6331a62963SBryan Wu 	};
6431a62963SBryan Wu 	u8 rx[2];
6531a62963SBryan Wu 
6631a62963SBryan Wu 	ret = i2c_master_send(client, tx, 2);
6731a62963SBryan Wu 	if (ret >= 0)
6831a62963SBryan Wu 		ret = i2c_master_recv(client, rx, 2);
6931a62963SBryan Wu 
7031a62963SBryan Wu 	if (unlikely(ret < 0)) {
7131a62963SBryan Wu 		dev_err(&client->dev, "I2C read error\n");
7231a62963SBryan Wu 	} else {
7331a62963SBryan Wu 		_data[0] = rx[1];
7431a62963SBryan Wu 		_data[1] = rx[0];
7531a62963SBryan Wu 	}
7631a62963SBryan Wu 
7731a62963SBryan Wu 	return ret;
7831a62963SBryan Wu }
7931a62963SBryan Wu 
8031a62963SBryan Wu static int __devinit ad714x_i2c_probe(struct i2c_client *client,
8131a62963SBryan Wu 					const struct i2c_device_id *id)
8231a62963SBryan Wu {
8331a62963SBryan Wu 	struct ad714x_chip *chip;
8431a62963SBryan Wu 
8531a62963SBryan Wu 	chip = ad714x_probe(&client->dev, BUS_I2C, client->irq,
8631a62963SBryan Wu 			    ad714x_i2c_read, ad714x_i2c_write);
8731a62963SBryan Wu 	if (IS_ERR(chip))
8831a62963SBryan Wu 		return PTR_ERR(chip);
8931a62963SBryan Wu 
9031a62963SBryan Wu 	i2c_set_clientdata(client, chip);
9131a62963SBryan Wu 
9231a62963SBryan Wu 	return 0;
9331a62963SBryan Wu }
9431a62963SBryan Wu 
9531a62963SBryan Wu static int __devexit ad714x_i2c_remove(struct i2c_client *client)
9631a62963SBryan Wu {
9731a62963SBryan Wu 	struct ad714x_chip *chip = i2c_get_clientdata(client);
9831a62963SBryan Wu 
9931a62963SBryan Wu 	ad714x_remove(chip);
10031a62963SBryan Wu 	i2c_set_clientdata(client, NULL);
10131a62963SBryan Wu 
10231a62963SBryan Wu 	return 0;
10331a62963SBryan Wu }
10431a62963SBryan Wu 
10531a62963SBryan Wu static const struct i2c_device_id ad714x_id[] = {
10631a62963SBryan Wu 	{ "ad7142_captouch", 0 },
1076c04d7b3SBarry Song 	{ "ad7143_captouch", 0 },
10831a62963SBryan Wu 	{ "ad7147_captouch", 0 },
1096c04d7b3SBarry Song 	{ "ad7147a_captouch", 0 },
1106c04d7b3SBarry Song 	{ "ad7148_captouch", 0 },
11131a62963SBryan Wu 	{ }
11231a62963SBryan Wu };
11331a62963SBryan Wu MODULE_DEVICE_TABLE(i2c, ad714x_id);
11431a62963SBryan Wu 
11531a62963SBryan Wu static struct i2c_driver ad714x_i2c_driver = {
11631a62963SBryan Wu 	.driver = {
11731a62963SBryan Wu 		.name = "ad714x_captouch",
11831a62963SBryan Wu 	},
11931a62963SBryan Wu 	.probe    = ad714x_i2c_probe,
12031a62963SBryan Wu 	.remove   = __devexit_p(ad714x_i2c_remove),
12131a62963SBryan Wu 	.suspend  = ad714x_i2c_suspend,
12231a62963SBryan Wu 	.resume	  = ad714x_i2c_resume,
12331a62963SBryan Wu 	.id_table = ad714x_id,
12431a62963SBryan Wu };
12531a62963SBryan Wu 
12631a62963SBryan Wu static __init int ad714x_i2c_init(void)
12731a62963SBryan Wu {
12831a62963SBryan Wu 	return i2c_add_driver(&ad714x_i2c_driver);
12931a62963SBryan Wu }
13031a62963SBryan Wu module_init(ad714x_i2c_init);
13131a62963SBryan Wu 
13231a62963SBryan Wu static __exit void ad714x_i2c_exit(void)
13331a62963SBryan Wu {
13431a62963SBryan Wu 	i2c_del_driver(&ad714x_i2c_driver);
13531a62963SBryan Wu }
13631a62963SBryan Wu module_exit(ad714x_i2c_exit);
13731a62963SBryan Wu 
13831a62963SBryan Wu MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor I2C Bus Driver");
13931a62963SBryan Wu MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
14031a62963SBryan Wu MODULE_LICENSE("GPL");
141