1 // SPDX-License-Identifier: GPL-2.0-only
4 * Cypress TrueTouch(TM) Standard Product (TTSP) SPI touchscreen driver.
5 * For use with Cypress Txx3xx parts.
6 * Supported parts include:
10 * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc.
11 * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org>
12 * Copyright (C) 2013 Cypress Semiconductor
14 * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
17 #include "cyttsp_core.h"
19 #include <linux/delay.h>
20 #include <linux/input.h>
21 #include <linux/spi/spi.h>
23 #define CY_SPI_WR_OP 0x00 /* r/~w */
24 #define CY_SPI_RD_OP 0x01
25 #define CY_SPI_CMD_BYTES 4
26 #define CY_SPI_SYNC_BYTE 2
27 #define CY_SPI_SYNC_ACK1 0x62 /* from protocol v.2 */
28 #define CY_SPI_SYNC_ACK2 0x9D /* from protocol v.2 */
29 #define CY_SPI_DATA_SIZE 128
30 #define CY_SPI_DATA_BUF_SIZE (CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE)
31 #define CY_SPI_BITS_PER_WORD 8
33 static int cyttsp_spi_xfer(struct device
*dev
, u8
*xfer_buf
,
34 u8 op
, u16 reg
, u8
*buf
, int length
)
36 struct spi_device
*spi
= to_spi_device(dev
);
37 struct spi_message msg
;
38 struct spi_transfer xfer
[2];
39 u8
*wr_buf
= &xfer_buf
[0];
40 u8
*rd_buf
= &xfer_buf
[CY_SPI_DATA_BUF_SIZE
];
44 if (length
> CY_SPI_DATA_SIZE
) {
45 dev_err(dev
, "%s: length %d is too big.\n",
50 memset(wr_buf
, 0, CY_SPI_DATA_BUF_SIZE
);
51 memset(rd_buf
, 0, CY_SPI_DATA_BUF_SIZE
);
53 wr_buf
[0] = 0x00; /* header byte 0 */
54 wr_buf
[1] = 0xFF; /* header byte 1 */
55 wr_buf
[2] = reg
; /* reg index */
56 wr_buf
[3] = op
; /* r/~w */
57 if (op
== CY_SPI_WR_OP
)
58 memcpy(wr_buf
+ CY_SPI_CMD_BYTES
, buf
, length
);
60 memset(xfer
, 0, sizeof(xfer
));
61 spi_message_init(&msg
);
64 We set both TX and RX buffers because Cypress TTSP
65 requires full duplex operation.
67 xfer
[0].tx_buf
= wr_buf
;
68 xfer
[0].rx_buf
= rd_buf
;
71 xfer
[0].len
= length
+ CY_SPI_CMD_BYTES
;
72 spi_message_add_tail(&xfer
[0], &msg
);
76 xfer
[0].len
= CY_SPI_CMD_BYTES
;
77 spi_message_add_tail(&xfer
[0], &msg
);
81 spi_message_add_tail(&xfer
[1], &msg
);
85 dev_err(dev
, "%s: bad operation code=%d\n", __func__
, op
);
89 retval
= spi_sync(spi
, &msg
);
91 dev_dbg(dev
, "%s: spi_sync() error %d, len=%d, op=%d\n",
92 __func__
, retval
, xfer
[1].len
, op
);
95 * do not return here since was a bad ACK sequence
96 * let the following ACK check handle any errors and
97 * allow silent retries
101 if (rd_buf
[CY_SPI_SYNC_BYTE
] != CY_SPI_SYNC_ACK1
||
102 rd_buf
[CY_SPI_SYNC_BYTE
+ 1] != CY_SPI_SYNC_ACK2
) {
103 dev_dbg(dev
, "%s: operation %d failed\n", __func__
, op
);
105 for (i
= 0; i
< CY_SPI_CMD_BYTES
; i
++)
106 dev_dbg(dev
, "%s: test rd_buf[%d]:0x%02x\n",
107 __func__
, i
, rd_buf
[i
]);
108 for (i
= 0; i
< length
; i
++)
109 dev_dbg(dev
, "%s: test buf[%d]:0x%02x\n",
110 __func__
, i
, buf
[i
]);
118 static int cyttsp_spi_read_block_data(struct device
*dev
, u8
*xfer_buf
,
119 u16 addr
, u8 length
, void *data
)
121 return cyttsp_spi_xfer(dev
, xfer_buf
, CY_SPI_RD_OP
, addr
, data
,
125 static int cyttsp_spi_write_block_data(struct device
*dev
, u8
*xfer_buf
,
126 u16 addr
, u8 length
, const void *data
)
128 return cyttsp_spi_xfer(dev
, xfer_buf
, CY_SPI_WR_OP
, addr
, (void *)data
,
132 static const struct cyttsp_bus_ops cyttsp_spi_bus_ops
= {
134 .write
= cyttsp_spi_write_block_data
,
135 .read
= cyttsp_spi_read_block_data
,
138 static int cyttsp_spi_probe(struct spi_device
*spi
)
144 spi
->bits_per_word
= CY_SPI_BITS_PER_WORD
;
145 spi
->mode
= SPI_MODE_0
;
146 error
= spi_setup(spi
);
148 dev_err(&spi
->dev
, "%s: SPI setup error %d\n",
153 ts
= cyttsp_probe(&cyttsp_spi_bus_ops
, &spi
->dev
, spi
->irq
,
154 CY_SPI_DATA_BUF_SIZE
* 2);
158 spi_set_drvdata(spi
, ts
);
163 static struct spi_driver cyttsp_spi_driver
= {
166 .pm
= &cyttsp_pm_ops
,
168 .probe
= cyttsp_spi_probe
,
171 module_spi_driver(cyttsp_spi_driver
);
173 MODULE_LICENSE("GPL");
174 MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) SPI driver");
175 MODULE_AUTHOR("Cypress");
176 MODULE_ALIAS("spi:cyttsp");