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>
11 * Copyright (C) 2013 Cypress Semiconductor
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * version 2, and only version 2, as published by the
16 * Free Software Foundation.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
27 #include "cyttsp_core.h"
29 #include <linux/delay.h>
30 #include <linux/input.h>
31 #include <linux/spi/spi.h>
33 #define CY_SPI_WR_OP 0x00 /* r/~w */
34 #define CY_SPI_RD_OP 0x01
35 #define CY_SPI_CMD_BYTES 4
36 #define CY_SPI_SYNC_BYTE 2
37 #define CY_SPI_SYNC_ACK1 0x62 /* from protocol v.2 */
38 #define CY_SPI_SYNC_ACK2 0x9D /* from protocol v.2 */
39 #define CY_SPI_DATA_SIZE 128
40 #define CY_SPI_DATA_BUF_SIZE (CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE)
41 #define CY_SPI_BITS_PER_WORD 8
43 static int cyttsp_spi_xfer(struct device
*dev
, u8
*xfer_buf
,
44 u8 op
, u16 reg
, u8
*buf
, int length
)
46 struct spi_device
*spi
= to_spi_device(dev
);
47 struct spi_message msg
;
48 struct spi_transfer xfer
[2];
49 u8
*wr_buf
= &xfer_buf
[0];
50 u8
*rd_buf
= &xfer_buf
[CY_SPI_DATA_BUF_SIZE
];
54 if (length
> CY_SPI_DATA_SIZE
) {
55 dev_err(dev
, "%s: length %d is too big.\n",
60 memset(wr_buf
, 0, CY_SPI_DATA_BUF_SIZE
);
61 memset(rd_buf
, 0, CY_SPI_DATA_BUF_SIZE
);
63 wr_buf
[0] = 0x00; /* header byte 0 */
64 wr_buf
[1] = 0xFF; /* header byte 1 */
65 wr_buf
[2] = reg
; /* reg index */
66 wr_buf
[3] = op
; /* r/~w */
67 if (op
== CY_SPI_WR_OP
)
68 memcpy(wr_buf
+ CY_SPI_CMD_BYTES
, buf
, length
);
70 memset(xfer
, 0, sizeof(xfer
));
71 spi_message_init(&msg
);
74 We set both TX and RX buffers because Cypress TTSP
75 requires full duplex operation.
77 xfer
[0].tx_buf
= wr_buf
;
78 xfer
[0].rx_buf
= rd_buf
;
81 xfer
[0].len
= length
+ CY_SPI_CMD_BYTES
;
82 spi_message_add_tail(&xfer
[0], &msg
);
86 xfer
[0].len
= CY_SPI_CMD_BYTES
;
87 spi_message_add_tail(&xfer
[0], &msg
);
91 spi_message_add_tail(&xfer
[1], &msg
);
95 dev_err(dev
, "%s: bad operation code=%d\n", __func__
, op
);
99 retval
= spi_sync(spi
, &msg
);
101 dev_dbg(dev
, "%s: spi_sync() error %d, len=%d, op=%d\n",
102 __func__
, retval
, xfer
[1].len
, op
);
105 * do not return here since was a bad ACK sequence
106 * let the following ACK check handle any errors and
107 * allow silent retries
111 if (rd_buf
[CY_SPI_SYNC_BYTE
] != CY_SPI_SYNC_ACK1
||
112 rd_buf
[CY_SPI_SYNC_BYTE
+ 1] != CY_SPI_SYNC_ACK2
) {
113 dev_dbg(dev
, "%s: operation %d failed\n", __func__
, op
);
115 for (i
= 0; i
< CY_SPI_CMD_BYTES
; i
++)
116 dev_dbg(dev
, "%s: test rd_buf[%d]:0x%02x\n",
117 __func__
, i
, rd_buf
[i
]);
118 for (i
= 0; i
< length
; i
++)
119 dev_dbg(dev
, "%s: test buf[%d]:0x%02x\n",
120 __func__
, i
, buf
[i
]);
128 static int cyttsp_spi_read_block_data(struct device
*dev
, u8
*xfer_buf
,
129 u16 addr
, u8 length
, void *data
)
131 return cyttsp_spi_xfer(dev
, xfer_buf
, CY_SPI_RD_OP
, addr
, data
,
135 static int cyttsp_spi_write_block_data(struct device
*dev
, u8
*xfer_buf
,
136 u16 addr
, u8 length
, const void *data
)
138 return cyttsp_spi_xfer(dev
, xfer_buf
, CY_SPI_WR_OP
, addr
, (void *)data
,
142 static const struct cyttsp_bus_ops cyttsp_spi_bus_ops
= {
144 .write
= cyttsp_spi_write_block_data
,
145 .read
= cyttsp_spi_read_block_data
,
148 static int cyttsp_spi_probe(struct spi_device
*spi
)
154 spi
->bits_per_word
= CY_SPI_BITS_PER_WORD
;
155 spi
->mode
= SPI_MODE_0
;
156 error
= spi_setup(spi
);
158 dev_err(&spi
->dev
, "%s: SPI setup error %d\n",
163 ts
= cyttsp_probe(&cyttsp_spi_bus_ops
, &spi
->dev
, spi
->irq
,
164 CY_SPI_DATA_BUF_SIZE
* 2);
168 spi_set_drvdata(spi
, ts
);
173 static int cyttsp_spi_remove(struct spi_device
*spi
)
175 struct cyttsp
*ts
= spi_get_drvdata(spi
);
182 static struct spi_driver cyttsp_spi_driver
= {
185 .pm
= &cyttsp_pm_ops
,
187 .probe
= cyttsp_spi_probe
,
188 .remove
= cyttsp_spi_remove
,
191 module_spi_driver(cyttsp_spi_driver
);
193 MODULE_LICENSE("GPL");
194 MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) SPI driver");
195 MODULE_AUTHOR("Cypress");
196 MODULE_ALIAS("spi:cyttsp");