180503b23SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
231a62963SBryan Wu /*
331a62963SBryan Wu * AD714X CapTouch Programmable Controller driver (I2C bus)
431a62963SBryan Wu *
59eff794bSMichael Hennerich * Copyright 2009-2011 Analog Devices Inc.
631a62963SBryan Wu */
731a62963SBryan Wu
831a62963SBryan Wu #include <linux/input.h> /* BUS_I2C */
931a62963SBryan Wu #include <linux/i2c.h>
1031a62963SBryan Wu #include <linux/module.h>
1131a62963SBryan Wu #include <linux/types.h>
126b7cfd19SMark Brown #include <linux/pm.h>
1331a62963SBryan Wu #include "ad714x.h"
1431a62963SBryan Wu
ad714x_i2c_write(struct ad714x_chip * chip,unsigned short reg,unsigned short data)15c0409febSDmitry Torokhov static int ad714x_i2c_write(struct ad714x_chip *chip,
16c0409febSDmitry Torokhov unsigned short reg, unsigned short data)
1731a62963SBryan Wu {
18c0409febSDmitry Torokhov struct i2c_client *client = to_i2c_client(chip->dev);
19c0409febSDmitry Torokhov int error;
2031a62963SBryan Wu
21c0409febSDmitry Torokhov chip->xfer_buf[0] = cpu_to_be16(reg);
22c0409febSDmitry Torokhov chip->xfer_buf[1] = cpu_to_be16(data);
2331a62963SBryan Wu
24c0409febSDmitry Torokhov error = i2c_master_send(client, (u8 *)chip->xfer_buf,
25c0409febSDmitry Torokhov 2 * sizeof(*chip->xfer_buf));
26c0409febSDmitry Torokhov if (unlikely(error < 0)) {
27c0409febSDmitry Torokhov dev_err(&client->dev, "I2C write error: %d\n", error);
28c0409febSDmitry Torokhov return error;
2931a62963SBryan Wu }
3031a62963SBryan Wu
31c0409febSDmitry Torokhov return 0;
3231a62963SBryan Wu }
3331a62963SBryan Wu
ad714x_i2c_read(struct ad714x_chip * chip,unsigned short reg,unsigned short * data,size_t len)34c0409febSDmitry Torokhov static int ad714x_i2c_read(struct ad714x_chip *chip,
359eff794bSMichael Hennerich unsigned short reg, unsigned short *data, size_t len)
3631a62963SBryan Wu {
37c0409febSDmitry Torokhov struct i2c_client *client = to_i2c_client(chip->dev);
389eff794bSMichael Hennerich int i;
39c0409febSDmitry Torokhov int error;
4031a62963SBryan Wu
41c0409febSDmitry Torokhov chip->xfer_buf[0] = cpu_to_be16(reg);
4231a62963SBryan Wu
43c0409febSDmitry Torokhov error = i2c_master_send(client, (u8 *)chip->xfer_buf,
44c0409febSDmitry Torokhov sizeof(*chip->xfer_buf));
45c0409febSDmitry Torokhov if (error >= 0)
46c0409febSDmitry Torokhov error = i2c_master_recv(client, (u8 *)chip->xfer_buf,
479eff794bSMichael Hennerich len * sizeof(*chip->xfer_buf));
4831a62963SBryan Wu
49c0409febSDmitry Torokhov if (unlikely(error < 0)) {
50c0409febSDmitry Torokhov dev_err(&client->dev, "I2C read error: %d\n", error);
51c0409febSDmitry Torokhov return error;
52c0409febSDmitry Torokhov }
53c0409febSDmitry Torokhov
549eff794bSMichael Hennerich for (i = 0; i < len; i++)
559eff794bSMichael Hennerich data[i] = be16_to_cpu(chip->xfer_buf[i]);
569eff794bSMichael Hennerich
57c0409febSDmitry Torokhov return 0;
5831a62963SBryan Wu }
5931a62963SBryan Wu
ad714x_i2c_probe(struct i2c_client * client)60d9526001SUwe Kleine-König static int ad714x_i2c_probe(struct i2c_client *client)
6131a62963SBryan Wu {
6231a62963SBryan Wu struct ad714x_chip *chip;
6331a62963SBryan Wu
6431a62963SBryan Wu chip = ad714x_probe(&client->dev, BUS_I2C, client->irq,
6531a62963SBryan Wu ad714x_i2c_read, ad714x_i2c_write);
6631a62963SBryan Wu if (IS_ERR(chip))
6731a62963SBryan Wu return PTR_ERR(chip);
6831a62963SBryan Wu
6931a62963SBryan Wu i2c_set_clientdata(client, chip);
7031a62963SBryan Wu
7131a62963SBryan Wu return 0;
7231a62963SBryan Wu }
7331a62963SBryan Wu
7431a62963SBryan Wu static const struct i2c_device_id ad714x_id[] = {
7531a62963SBryan Wu { "ad7142_captouch", 0 },
766c04d7b3SBarry Song { "ad7143_captouch", 0 },
7731a62963SBryan Wu { "ad7147_captouch", 0 },
786c04d7b3SBarry Song { "ad7147a_captouch", 0 },
796c04d7b3SBarry Song { "ad7148_captouch", 0 },
8031a62963SBryan Wu { }
8131a62963SBryan Wu };
8231a62963SBryan Wu MODULE_DEVICE_TABLE(i2c, ad714x_id);
8331a62963SBryan Wu
8431a62963SBryan Wu static struct i2c_driver ad714x_i2c_driver = {
8531a62963SBryan Wu .driver = {
8631a62963SBryan Wu .name = "ad714x_captouch",
87c0a150eeSJonathan Cameron .pm = pm_sleep_ptr(&ad714x_pm),
8831a62963SBryan Wu },
89*d8bde56dSUwe Kleine-König .probe = ad714x_i2c_probe,
9031a62963SBryan Wu .id_table = ad714x_id,
9131a62963SBryan Wu };
9231a62963SBryan Wu
931b92c1cfSAxel Lin module_i2c_driver(ad714x_i2c_driver);
9431a62963SBryan Wu
9531a62963SBryan Wu MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor I2C Bus Driver");
9631a62963SBryan Wu MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
9731a62963SBryan Wu MODULE_LICENSE("GPL");
98