Commit | Line | Data |
---|---|---|
31a62963 BW |
1 | /* |
2 | * AD714X CapTouch Programmable Controller driver (SPI bus) | |
3 | * | |
9eff794b | 4 | * Copyright 2009-2011 Analog Devices Inc. |
31a62963 BW |
5 | * |
6 | * Licensed under the GPL-2 or later. | |
7 | */ | |
8 | ||
6337de22 | 9 | #include <linux/input.h> /* BUS_SPI */ |
31a62963 BW |
10 | #include <linux/module.h> |
11 | #include <linux/spi/spi.h> | |
a257090c | 12 | #include <linux/pm.h> |
31a62963 BW |
13 | #include <linux/types.h> |
14 | #include "ad714x.h" | |
15 | ||
16 | #define AD714x_SPI_CMD_PREFIX 0xE000 /* bits 15:11 */ | |
17 | #define AD714x_SPI_READ BIT(10) | |
18 | ||
84c0c9f5 | 19 | #ifdef CONFIG_PM_SLEEP |
a257090c | 20 | static int ad714x_spi_suspend(struct device *dev) |
31a62963 | 21 | { |
a257090c | 22 | return ad714x_disable(spi_get_drvdata(to_spi_device(dev))); |
31a62963 BW |
23 | } |
24 | ||
a257090c | 25 | static int ad714x_spi_resume(struct device *dev) |
31a62963 | 26 | { |
a257090c | 27 | return ad714x_enable(spi_get_drvdata(to_spi_device(dev))); |
31a62963 | 28 | } |
31a62963 BW |
29 | #endif |
30 | ||
a257090c MB |
31 | static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume); |
32 | ||
c0409feb | 33 | static int ad714x_spi_read(struct ad714x_chip *chip, |
9eff794b | 34 | unsigned short reg, unsigned short *data, size_t len) |
31a62963 | 35 | { |
c0409feb DT |
36 | struct spi_device *spi = to_spi_device(chip->dev); |
37 | struct spi_message message; | |
38 | struct spi_transfer xfer[2]; | |
9eff794b | 39 | int i; |
c0409feb DT |
40 | int error; |
41 | ||
42 | spi_message_init(&message); | |
43 | memset(xfer, 0, sizeof(xfer)); | |
44 | ||
45 | chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX | | |
6337de22 | 46 | AD714x_SPI_READ | reg); |
c0409feb DT |
47 | xfer[0].tx_buf = &chip->xfer_buf[0]; |
48 | xfer[0].len = sizeof(chip->xfer_buf[0]); | |
49 | spi_message_add_tail(&xfer[0], &message); | |
31a62963 | 50 | |
c0409feb | 51 | xfer[1].rx_buf = &chip->xfer_buf[1]; |
9eff794b | 52 | xfer[1].len = sizeof(chip->xfer_buf[1]) * len; |
c0409feb | 53 | spi_message_add_tail(&xfer[1], &message); |
6337de22 | 54 | |
c0409feb DT |
55 | error = spi_sync(spi, &message); |
56 | if (unlikely(error)) { | |
57 | dev_err(chip->dev, "SPI read error: %d\n", error); | |
58 | return error; | |
59 | } | |
6337de22 | 60 | |
9eff794b MH |
61 | for (i = 0; i < len; i++) |
62 | data[i] = be16_to_cpu(chip->xfer_buf[i + 1]); | |
63 | ||
c0409feb | 64 | return 0; |
31a62963 BW |
65 | } |
66 | ||
c0409feb | 67 | static int ad714x_spi_write(struct ad714x_chip *chip, |
6337de22 | 68 | unsigned short reg, unsigned short data) |
31a62963 | 69 | { |
c0409feb DT |
70 | struct spi_device *spi = to_spi_device(chip->dev); |
71 | int error; | |
72 | ||
73 | chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg); | |
74 | chip->xfer_buf[1] = cpu_to_be16(data); | |
75 | ||
76 | error = spi_write(spi, (u8 *)chip->xfer_buf, | |
77 | 2 * sizeof(*chip->xfer_buf)); | |
78 | if (unlikely(error)) { | |
79 | dev_err(chip->dev, "SPI write error: %d\n", error); | |
80 | return error; | |
81 | } | |
31a62963 | 82 | |
c0409feb | 83 | return 0; |
31a62963 BW |
84 | } |
85 | ||
5298cc4c | 86 | static int ad714x_spi_probe(struct spi_device *spi) |
31a62963 BW |
87 | { |
88 | struct ad714x_chip *chip; | |
5b9063b1 MH |
89 | int err; |
90 | ||
91 | spi->bits_per_word = 8; | |
92 | err = spi_setup(spi); | |
93 | if (err < 0) | |
94 | return err; | |
31a62963 BW |
95 | |
96 | chip = ad714x_probe(&spi->dev, BUS_SPI, spi->irq, | |
97 | ad714x_spi_read, ad714x_spi_write); | |
98 | if (IS_ERR(chip)) | |
99 | return PTR_ERR(chip); | |
100 | ||
101 | spi_set_drvdata(spi, chip); | |
102 | ||
103 | return 0; | |
104 | } | |
105 | ||
e2619cf7 | 106 | static int ad714x_spi_remove(struct spi_device *spi) |
31a62963 BW |
107 | { |
108 | struct ad714x_chip *chip = spi_get_drvdata(spi); | |
109 | ||
110 | ad714x_remove(chip); | |
31a62963 BW |
111 | |
112 | return 0; | |
113 | } | |
114 | ||
115 | static struct spi_driver ad714x_spi_driver = { | |
116 | .driver = { | |
117 | .name = "ad714x_captouch", | |
118 | .owner = THIS_MODULE, | |
a257090c | 119 | .pm = &ad714x_spi_pm, |
31a62963 BW |
120 | }, |
121 | .probe = ad714x_spi_probe, | |
1cb0aa88 | 122 | .remove = ad714x_spi_remove, |
31a62963 BW |
123 | }; |
124 | ||
ca83922e | 125 | module_spi_driver(ad714x_spi_driver); |
31a62963 BW |
126 | |
127 | MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor SPI Bus Driver"); | |
128 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | |
129 | MODULE_LICENSE("GPL"); |