1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * AD714X CapTouch Programmable Controller driver (I2C bus) |
4 | * |
5 | * Copyright 2009-2011 Analog Devices Inc. |
6 | */ |
7 | |
8 | #include <linux/input.h> /* BUS_I2C */ |
9 | #include <linux/i2c.h> |
10 | #include <linux/module.h> |
11 | #include <linux/types.h> |
12 | #include <linux/pm.h> |
13 | #include "ad714x.h" |
14 | |
15 | static int ad714x_i2c_write(struct ad714x_chip *chip, |
16 | unsigned short reg, unsigned short data) |
17 | { |
18 | struct i2c_client *client = to_i2c_client(chip->dev); |
19 | int error; |
20 | |
21 | chip->xfer_buf[0] = cpu_to_be16(reg); |
22 | chip->xfer_buf[1] = cpu_to_be16(data); |
23 | |
24 | error = i2c_master_send(client, buf: (u8 *)chip->xfer_buf, |
25 | count: 2 * sizeof(*chip->xfer_buf)); |
26 | if (unlikely(error < 0)) { |
27 | dev_err(&client->dev, "I2C write error: %d\n" , error); |
28 | return error; |
29 | } |
30 | |
31 | return 0; |
32 | } |
33 | |
34 | static int ad714x_i2c_read(struct ad714x_chip *chip, |
35 | unsigned short reg, unsigned short *data, size_t len) |
36 | { |
37 | struct i2c_client *client = to_i2c_client(chip->dev); |
38 | int i; |
39 | int error; |
40 | |
41 | chip->xfer_buf[0] = cpu_to_be16(reg); |
42 | |
43 | error = i2c_master_send(client, buf: (u8 *)chip->xfer_buf, |
44 | count: sizeof(*chip->xfer_buf)); |
45 | if (error >= 0) |
46 | error = i2c_master_recv(client, buf: (u8 *)chip->xfer_buf, |
47 | count: len * sizeof(*chip->xfer_buf)); |
48 | |
49 | if (unlikely(error < 0)) { |
50 | dev_err(&client->dev, "I2C read error: %d\n" , error); |
51 | return error; |
52 | } |
53 | |
54 | for (i = 0; i < len; i++) |
55 | data[i] = be16_to_cpu(chip->xfer_buf[i]); |
56 | |
57 | return 0; |
58 | } |
59 | |
60 | static int ad714x_i2c_probe(struct i2c_client *client) |
61 | { |
62 | struct ad714x_chip *chip; |
63 | |
64 | chip = ad714x_probe(dev: &client->dev, BUS_I2C, irq: client->irq, |
65 | read: ad714x_i2c_read, write: ad714x_i2c_write); |
66 | if (IS_ERR(ptr: chip)) |
67 | return PTR_ERR(ptr: chip); |
68 | |
69 | i2c_set_clientdata(client, data: chip); |
70 | |
71 | return 0; |
72 | } |
73 | |
74 | static const struct i2c_device_id ad714x_id[] = { |
75 | { "ad7142_captouch" , 0 }, |
76 | { "ad7143_captouch" , 0 }, |
77 | { "ad7147_captouch" , 0 }, |
78 | { "ad7147a_captouch" , 0 }, |
79 | { "ad7148_captouch" , 0 }, |
80 | { } |
81 | }; |
82 | MODULE_DEVICE_TABLE(i2c, ad714x_id); |
83 | |
84 | static struct i2c_driver ad714x_i2c_driver = { |
85 | .driver = { |
86 | .name = "ad714x_captouch" , |
87 | .pm = pm_sleep_ptr(&ad714x_pm), |
88 | }, |
89 | .probe = ad714x_i2c_probe, |
90 | .id_table = ad714x_id, |
91 | }; |
92 | |
93 | module_i2c_driver(ad714x_i2c_driver); |
94 | |
95 | MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor I2C Bus Driver" ); |
96 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>" ); |
97 | MODULE_LICENSE("GPL" ); |
98 | |