3 * Cypress TrueTouch(TM) Standard Product (TTSP) SPI touchscreen driver.
4 * For use with Cypress Txx3xx parts.
5 * Supported parts include:
9 * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc.
10 * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org>
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * version 2, and only version 2, as published by the
15 * Free Software Foundation.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 * Contact Cypress Semiconductor at www.cypress.com <kev@cypress.com>
30 #include "cyttsp_core.h"
32 #include <linux/delay.h>
33 #include <linux/input.h>
34 #include <linux/spi/spi.h>
36 #define CY_SPI_WR_OP 0x00 /* r/~w */
37 #define CY_SPI_RD_OP 0x01
38 #define CY_SPI_CMD_BYTES 4
39 #define CY_SPI_SYNC_BYTE 2
40 #define CY_SPI_SYNC_ACK1 0x62 /* from protocol v.2 */
41 #define CY_SPI_SYNC_ACK2 0x9D /* from protocol v.2 */
42 #define CY_SPI_DATA_SIZE 128
43 #define CY_SPI_DATA_BUF_SIZE (CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE)
44 #define CY_SPI_BITS_PER_WORD 8
46 static int cyttsp_spi_xfer(struct cyttsp
*ts
,
47 u8 op
, u8 reg
, u8
*buf
, int length
)
49 struct spi_device
*spi
= to_spi_device(ts
->dev
);
50 struct spi_message msg
;
51 struct spi_transfer xfer
[2];
52 u8
*wr_buf
= &ts
->xfer_buf
[0];
53 u8
*rd_buf
= &ts
->xfer_buf
[CY_SPI_DATA_BUF_SIZE
];
57 if (length
> CY_SPI_DATA_SIZE
) {
58 dev_err(ts
->dev
, "%s: length %d is too big.\n",
63 memset(wr_buf
, 0, CY_SPI_DATA_BUF_SIZE
);
64 memset(rd_buf
, 0, CY_SPI_DATA_BUF_SIZE
);
66 wr_buf
[0] = 0x00; /* header byte 0 */
67 wr_buf
[1] = 0xFF; /* header byte 1 */
68 wr_buf
[2] = reg
; /* reg index */
69 wr_buf
[3] = op
; /* r/~w */
70 if (op
== CY_SPI_WR_OP
)
71 memcpy(wr_buf
+ CY_SPI_CMD_BYTES
, buf
, length
);
73 memset(xfer
, 0, sizeof(xfer
));
74 spi_message_init(&msg
);
77 We set both TX and RX buffers because Cypress TTSP
78 requires full duplex operation.
80 xfer
[0].tx_buf
= wr_buf
;
81 xfer
[0].rx_buf
= rd_buf
;
84 xfer
[0].len
= length
+ CY_SPI_CMD_BYTES
;
85 spi_message_add_tail(&xfer
[0], &msg
);
89 xfer
[0].len
= CY_SPI_CMD_BYTES
;
90 spi_message_add_tail(&xfer
[0], &msg
);
94 spi_message_add_tail(&xfer
[1], &msg
);
98 dev_err(ts
->dev
, "%s: bad operation code=%d\n", __func__
, op
);
102 retval
= spi_sync(spi
, &msg
);
104 dev_dbg(ts
->dev
, "%s: spi_sync() error %d, len=%d, op=%d\n",
105 __func__
, retval
, xfer
[1].len
, op
);
108 * do not return here since was a bad ACK sequence
109 * let the following ACK check handle any errors and
110 * allow silent retries
114 if (rd_buf
[CY_SPI_SYNC_BYTE
] != CY_SPI_SYNC_ACK1
||
115 rd_buf
[CY_SPI_SYNC_BYTE
+ 1] != CY_SPI_SYNC_ACK2
) {
117 dev_dbg(ts
->dev
, "%s: operation %d failed\n", __func__
, op
);
119 for (i
= 0; i
< CY_SPI_CMD_BYTES
; i
++)
120 dev_dbg(ts
->dev
, "%s: test rd_buf[%d]:0x%02x\n",
121 __func__
, i
, rd_buf
[i
]);
122 for (i
= 0; i
< length
; i
++)
123 dev_dbg(ts
->dev
, "%s: test buf[%d]:0x%02x\n",
124 __func__
, i
, buf
[i
]);
132 static int cyttsp_spi_read_block_data(struct cyttsp
*ts
,
133 u8 addr
, u8 length
, void *data
)
135 return cyttsp_spi_xfer(ts
, CY_SPI_RD_OP
, addr
, data
, length
);
138 static int cyttsp_spi_write_block_data(struct cyttsp
*ts
,
139 u8 addr
, u8 length
, const void *data
)
141 return cyttsp_spi_xfer(ts
, CY_SPI_WR_OP
, addr
, (void *)data
, length
);
144 static const struct cyttsp_bus_ops cyttsp_spi_bus_ops
= {
146 .write
= cyttsp_spi_write_block_data
,
147 .read
= cyttsp_spi_read_block_data
,
150 static int __devinit
cyttsp_spi_probe(struct spi_device
*spi
)
156 spi
->bits_per_word
= CY_SPI_BITS_PER_WORD
;
157 spi
->mode
= SPI_MODE_0
;
158 error
= spi_setup(spi
);
160 dev_err(&spi
->dev
, "%s: SPI setup error %d\n",
165 ts
= cyttsp_probe(&cyttsp_spi_bus_ops
, &spi
->dev
, spi
->irq
,
166 CY_SPI_DATA_BUF_SIZE
* 2);
170 spi_set_drvdata(spi
, ts
);
175 static int __devexit
cyttsp_spi_remove(struct spi_device
*spi
)
177 struct cyttsp
*ts
= spi_get_drvdata(spi
);
184 static struct spi_driver cyttsp_spi_driver
= {
187 .owner
= THIS_MODULE
,
188 .pm
= &cyttsp_pm_ops
,
190 .probe
= cyttsp_spi_probe
,
191 .remove
= __devexit_p(cyttsp_spi_remove
),
194 module_spi_driver(cyttsp_spi_driver
);
196 MODULE_ALIAS("spi:cyttsp");
197 MODULE_LICENSE("GPL");
198 MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) SPI driver");
199 MODULE_AUTHOR("Cypress");
200 MODULE_ALIAS("spi:cyttsp");