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