]>
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 | ||
97a652a8 | 19 | static int __maybe_unused ad714x_spi_suspend(struct device *dev) |
31a62963 | 20 | { |
a257090c | 21 | return ad714x_disable(spi_get_drvdata(to_spi_device(dev))); |
31a62963 BW |
22 | } |
23 | ||
97a652a8 | 24 | static int __maybe_unused ad714x_spi_resume(struct device *dev) |
31a62963 | 25 | { |
a257090c | 26 | return ad714x_enable(spi_get_drvdata(to_spi_device(dev))); |
31a62963 | 27 | } |
31a62963 | 28 | |
a257090c MB |
29 | static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume); |
30 | ||
c0409feb | 31 | static int ad714x_spi_read(struct ad714x_chip *chip, |
9eff794b | 32 | unsigned short reg, unsigned short *data, size_t len) |
31a62963 | 33 | { |
c0409feb DT |
34 | struct spi_device *spi = to_spi_device(chip->dev); |
35 | struct spi_message message; | |
36 | struct spi_transfer xfer[2]; | |
9eff794b | 37 | int i; |
c0409feb DT |
38 | int error; |
39 | ||
40 | spi_message_init(&message); | |
41 | memset(xfer, 0, sizeof(xfer)); | |
42 | ||
43 | chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX | | |
6337de22 | 44 | AD714x_SPI_READ | reg); |
c0409feb DT |
45 | xfer[0].tx_buf = &chip->xfer_buf[0]; |
46 | xfer[0].len = sizeof(chip->xfer_buf[0]); | |
47 | spi_message_add_tail(&xfer[0], &message); | |
31a62963 | 48 | |
c0409feb | 49 | xfer[1].rx_buf = &chip->xfer_buf[1]; |
9eff794b | 50 | xfer[1].len = sizeof(chip->xfer_buf[1]) * len; |
c0409feb | 51 | spi_message_add_tail(&xfer[1], &message); |
6337de22 | 52 | |
c0409feb DT |
53 | error = spi_sync(spi, &message); |
54 | if (unlikely(error)) { | |
55 | dev_err(chip->dev, "SPI read error: %d\n", error); | |
56 | return error; | |
57 | } | |
6337de22 | 58 | |
9eff794b MH |
59 | for (i = 0; i < len; i++) |
60 | data[i] = be16_to_cpu(chip->xfer_buf[i + 1]); | |
61 | ||
c0409feb | 62 | return 0; |
31a62963 BW |
63 | } |
64 | ||
c0409feb | 65 | static int ad714x_spi_write(struct ad714x_chip *chip, |
6337de22 | 66 | unsigned short reg, unsigned short data) |
31a62963 | 67 | { |
c0409feb DT |
68 | struct spi_device *spi = to_spi_device(chip->dev); |
69 | int error; | |
70 | ||
71 | chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg); | |
72 | chip->xfer_buf[1] = cpu_to_be16(data); | |
73 | ||
74 | error = spi_write(spi, (u8 *)chip->xfer_buf, | |
75 | 2 * sizeof(*chip->xfer_buf)); | |
76 | if (unlikely(error)) { | |
77 | dev_err(chip->dev, "SPI write error: %d\n", error); | |
78 | return error; | |
79 | } | |
31a62963 | 80 | |
c0409feb | 81 | return 0; |
31a62963 BW |
82 | } |
83 | ||
5298cc4c | 84 | static int ad714x_spi_probe(struct spi_device *spi) |
31a62963 BW |
85 | { |
86 | struct ad714x_chip *chip; | |
5b9063b1 MH |
87 | int err; |
88 | ||
89 | spi->bits_per_word = 8; | |
90 | err = spi_setup(spi); | |
91 | if (err < 0) | |
92 | return err; | |
31a62963 BW |
93 | |
94 | chip = ad714x_probe(&spi->dev, BUS_SPI, spi->irq, | |
95 | ad714x_spi_read, ad714x_spi_write); | |
96 | if (IS_ERR(chip)) | |
97 | return PTR_ERR(chip); | |
98 | ||
99 | spi_set_drvdata(spi, chip); | |
100 | ||
101 | return 0; | |
102 | } | |
103 | ||
31a62963 BW |
104 | static struct spi_driver ad714x_spi_driver = { |
105 | .driver = { | |
106 | .name = "ad714x_captouch", | |
a257090c | 107 | .pm = &ad714x_spi_pm, |
31a62963 BW |
108 | }, |
109 | .probe = ad714x_spi_probe, | |
31a62963 BW |
110 | }; |
111 | ||
ca83922e | 112 | module_spi_driver(ad714x_spi_driver); |
31a62963 BW |
113 | |
114 | MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor SPI Bus Driver"); | |
115 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | |
116 | MODULE_LICENSE("GPL"); |