]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/spi/tsc2301-core.c
SPI: Add support for TSC2301 protocol driver
[linux-2.6-omap-h63xx.git] / drivers / spi / tsc2301-core.c
1 /*
2  * TSC2301 driver
3  *
4  * Copyright (C) 2005, 2006 Nokia Corporation
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21
22 #include <linux/module.h>
23 #include <linux/device.h>
24 #include <linux/delay.h>
25 #include <linux/spi/spi.h>
26 #include <linux/spi/tsc2301.h>
27
28 #ifdef CONFIG_ARCH_OMAP
29 #include <asm/arch/gpio.h>
30 #endif
31
32 u16 tsc2301_read_reg(struct tsc2301 *tsc, int reg)
33 {
34         struct spi_transfer t[2];
35         struct spi_message m;
36         u16 data = 0, cmd;
37
38         cmd = reg;
39         cmd |= 0x8000;
40
41         memset(t, 0, sizeof(t));
42         spi_message_init(&m);
43         m.spi = tsc->spi;
44
45         t[0].tx_buf = &cmd;
46         t[0].rx_buf = NULL;
47         t[0].len = 2;
48         spi_message_add_tail(&t[0], &m);
49
50         t[1].tx_buf = NULL;
51         t[1].rx_buf = &data;
52         t[1].len = 2;
53         spi_message_add_tail(&t[1], &m);
54
55         spi_sync(m.spi, &m);
56
57         return data;
58 }
59
60 void tsc2301_write_reg(struct tsc2301 *tsc, int reg, u16 val)
61 {
62         struct spi_transfer t;
63         struct spi_message m;
64         u16 data[2];
65
66         /* Now we prepare the command for transferring */
67         data[0] = reg;
68         data[1] = val;
69
70         spi_message_init(&m);
71         m.spi = tsc->spi;
72
73         memset(&t, 0, sizeof(t));
74         t.tx_buf = data;
75         t.rx_buf = NULL;
76         t.len = 4;
77         spi_message_add_tail(&t, &m);
78
79         spi_sync(m.spi, &m);
80 }
81
82 void tsc2301_write_kbc(struct tsc2301 *tsc, int val)
83 {
84         u16 w;
85
86         w = tsc->config2_shadow;
87         w &= ~(0x03 << 14);
88         w |= (val & 0x03) << 14;
89         tsc2301_write_reg(tsc, TSC2301_REG_CONFIG2, w);
90         tsc->config2_shadow = w;
91 }
92
93 void tsc2301_write_pll(struct tsc2301 *tsc,
94                        int pll_n, int pll_a, int pll_pdc, int pct_e, int pll_o)
95 {
96         u16 w;
97
98         w = tsc->config2_shadow;
99         w &= ~0x3fff;
100         w |= (pll_n & 0x0f) | ((pll_a & 0x0f) << 4) | ((pll_pdc & 0x0f) << 8);
101         w |= pct_e ? (1 << 12) : 0;
102         w |= pll_o ? (1 << 13) : 0;
103         tsc2301_write_reg(tsc, TSC2301_REG_CONFIG2, w);
104         tsc->config2_shadow = w;
105 }
106
107 void tsc2301_read_buf(struct tsc2301 *tsc, int reg, u16 *rx_buf, int len)
108 {
109         struct spi_transfer t[2];
110         struct spi_message m;
111         u16 cmd, i;
112
113         cmd = reg;
114         cmd |= 0x8000;
115
116         spi_message_init(&m);
117         m.spi = tsc->spi;
118
119         memset(t, 0, sizeof(t));
120         t[0].tx_buf = &cmd;
121         t[0].rx_buf = NULL;
122         t[0].len = 2;
123         spi_message_add_tail(&t[0], &m);
124
125         t[1].tx_buf = NULL;
126         t[1].rx_buf = rx_buf;
127         t[1].len = 2 * len;
128         spi_message_add_tail(&t[1], &m);
129
130         spi_sync(m.spi, &m);
131
132         for (i = 0; i < len; i++)
133                 printk(KERN_DEBUG "rx_buf[%d]: %04x\n", i, rx_buf[i]);
134 }
135
136 static int __devinit tsc2301_probe(struct spi_device *spi)
137 {
138         struct tsc2301                  *tsc;
139         struct tsc2301_platform_data    *pdata = spi->dev.platform_data;
140         int r;
141         u16 w;
142
143         if (!pdata) {
144                 dev_dbg(&spi->dev, "no platform data?\n");
145                 return -ENODEV;
146         }
147
148         tsc = kzalloc(sizeof(*tsc), GFP_KERNEL);
149         if (tsc == NULL)
150                 return -ENOMEM;
151
152         dev_set_drvdata(&spi->dev, tsc);
153         tsc->spi = spi;
154         spi->dev.power.power_state = PMSG_ON;
155
156         tsc->enable_clock = pdata->enable_clock;
157         tsc->disable_clock = pdata->disable_clock;
158
159         if (pdata->reset_gpio >= 0) {
160                 tsc->reset_gpio = pdata->reset_gpio;
161 #ifdef CONFIG_ARCH_OMAP
162                 r = omap_request_gpio(tsc->reset_gpio);
163                 if (r < 0)
164                         goto err1;
165                 omap_set_gpio_dataout(tsc->reset_gpio, 1);
166                 omap_set_gpio_direction(tsc->reset_gpio, 0);
167                 mdelay(1);
168                 omap_set_gpio_dataout(tsc->reset_gpio, 0);
169 #endif
170         } else
171                 tsc->reset_gpio = -1;
172
173         spi->mode = SPI_MODE_0;
174         spi->bits_per_word = 16;
175         /* The max speed might've been defined by the board-specific
176          * struct */
177         if (!spi->max_speed_hz)
178                 spi->max_speed_hz = TSC2301_HZ;
179         spi_setup(spi);
180
181         /* Soft reset */
182         tsc2301_write_reg(tsc, TSC2301_REG_RESET, 0xbb00);
183         msleep(1);
184
185         w = tsc2301_read_reg(tsc, TSC2301_REG_ADC);
186         if (!(w & (1 << 14))) {
187                 dev_err(&spi->dev, "invalid ADC reg value: %04x\n", w);
188                 r = -ENODEV;
189                 goto err1;
190         }
191
192         w = tsc2301_read_reg(tsc, TSC2301_REG_DAC);
193         if (!(w & (1 << 15))) {
194                 dev_err(&spi->dev, "invalid DAC reg value: %04x\n", w);
195                 r = -ENODEV;
196                 goto err1;
197         }
198
199         /* Stop keypad scanning */
200         tsc2301_write_reg(tsc, TSC2301_REG_KEY, 0x4000);
201
202         /* We have to cache this for read-modify-write, since we can't
203          * read back BIT15 */
204         w = tsc2301_read_reg(tsc, TSC2301_REG_CONFIG2);
205         /* By default BIT15 is set */
206         w |= 1 << 15;
207         tsc->config2_shadow = w;
208
209         r = tsc2301_kp_init(tsc, pdata);
210         if (r)
211                 goto err1;
212         r = tsc2301_ts_init(tsc, pdata);
213         if (r)
214                 goto err2;
215         r = tsc2301_mixer_init(tsc, pdata);
216         if (r)
217                 goto err3;
218         return 0;
219
220 err3:
221         tsc2301_ts_exit(tsc);
222 err2:
223         tsc2301_kp_exit(tsc);
224 err1:
225         kfree(tsc);
226         return r;
227 }
228
229 static int __devexit tsc2301_remove(struct spi_device *spi)
230 {
231         struct tsc2301 *tsc = dev_get_drvdata(&spi->dev);
232
233         tsc2301_mixer_exit(tsc);
234         tsc2301_ts_exit(tsc);
235         tsc2301_kp_exit(tsc);
236         kfree(tsc);
237
238         return 0;
239 }
240
241 #ifdef CONFIG_PM
242 static int tsc2301_suspend(struct spi_device *spi, pm_message_t mesg)
243 {
244         struct tsc2301 *tsc = dev_get_drvdata(&spi->dev);
245         int r;
246
247         if ((r = tsc2301_mixer_suspend(tsc)) < 0)
248                 return r;
249         if ((r = tsc2301_kp_suspend(tsc)) < 0)
250                 goto err1;
251         if ((r = tsc2301_ts_suspend(tsc)) < 0)
252                 goto err2;
253
254         return 0;
255 err2:
256         tsc2301_kp_resume(tsc);
257 err1:
258         tsc2301_mixer_resume(tsc);
259         return r;
260 }
261
262 static int tsc2301_resume(struct spi_device *spi)
263 {
264         struct tsc2301 *tsc = dev_get_drvdata(&spi->dev);
265
266         tsc2301_ts_resume(tsc);
267         tsc2301_kp_resume(tsc);
268         tsc2301_mixer_resume(tsc);
269         return 0;
270 }
271 #endif
272
273 static struct spi_driver tsc2301_driver = {
274         .driver = {
275                    .name = "tsc2301",
276                    .bus = &spi_bus_type,
277                    .owner = THIS_MODULE,
278         },
279 #ifdef CONFIG_PM
280         .suspend = tsc2301_suspend,
281         .resume = tsc2301_resume,
282 #endif
283         .probe = tsc2301_probe,
284         .remove = __devexit_p(tsc2301_remove),
285 };
286
287 static int __init tsc2301_init(void)
288 {
289         printk("TSC2301 driver initializing\n");
290
291         return spi_register_driver(&tsc2301_driver);
292 }
293 module_init(tsc2301_init);
294
295 static void __exit tsc2301_exit(void)
296 {
297         spi_unregister_driver(&tsc2301_driver);
298 }
299 module_exit(tsc2301_exit);
300
301 MODULE_AUTHOR("Juha Yrjölä <juha.yrjola@nokia.com>");
302 MODULE_LICENSE("GPL");