3 * Cypress TrueTouch(TM) Standard Product (TTSP) SPI touchscreen driver.
4 * For use with Cypress Txx4xx 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 "cyttsp4_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_BITS_PER_WORD 8
36 #define CY_SPI_A8_BIT 0x02
37 #define CY_SPI_WR_HEADER_BYTES 2
38 #define CY_SPI_RD_HEADER_BYTES 1
39 #define CY_SPI_CMD_BYTES 2
40 #define CY_SPI_SYNC_BYTE 0
41 #define CY_SPI_SYNC_ACK 0x62 /* from TRM *A protocol */
42 #define CY_SPI_DATA_SIZE (2 * 256)
44 #define CY_SPI_DATA_BUF_SIZE (CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE)
46 static int cyttsp_spi_xfer(struct device
*dev
, u8
*xfer_buf
,
47 u8 op
, u16 reg
, u8
*buf
, int length
)
49 struct spi_device
*spi
= to_spi_device(dev
);
50 struct spi_message msg
;
51 struct spi_transfer xfer
[2];
52 u8
*wr_buf
= &xfer_buf
[0];
53 u8 rd_buf
[CY_SPI_CMD_BYTES
];
57 if (length
> CY_SPI_DATA_SIZE
) {
58 dev_err(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_CMD_BYTES
);
66 wr_buf
[0] = op
+ (((reg
>> 8) & 0x1) ? CY_SPI_A8_BIT
: 0);
67 if (op
== CY_SPI_WR_OP
) {
68 wr_buf
[1] = reg
& 0xFF;
70 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_RD_HEADER_BYTES
;
90 spi_message_add_tail(&xfer
[0], &msg
);
94 spi_message_add_tail(&xfer
[1], &msg
);
98 dev_err(dev
, "%s: bad operation code=%d\n", __func__
, op
);
102 retval
= spi_sync(spi
, &msg
);
104 dev_dbg(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_ACK
) {
115 dev_dbg(dev
, "%s: operation %d failed\n", __func__
, op
);
117 for (i
= 0; i
< CY_SPI_CMD_BYTES
; i
++)
118 dev_dbg(dev
, "%s: test rd_buf[%d]:0x%02x\n",
119 __func__
, i
, rd_buf
[i
]);
120 for (i
= 0; i
< length
; i
++)
121 dev_dbg(dev
, "%s: test buf[%d]:0x%02x\n",
122 __func__
, i
, buf
[i
]);
130 static int cyttsp_spi_read_block_data(struct device
*dev
, u8
*xfer_buf
,
131 u16 addr
, u8 length
, void *data
)
135 rc
= cyttsp_spi_xfer(dev
, xfer_buf
, CY_SPI_WR_OP
, addr
, NULL
, 0);
139 return cyttsp_spi_xfer(dev
, xfer_buf
, CY_SPI_RD_OP
, addr
, data
,
143 static int cyttsp_spi_write_block_data(struct device
*dev
, u8
*xfer_buf
,
144 u16 addr
, u8 length
, const void *data
)
146 return cyttsp_spi_xfer(dev
, xfer_buf
, CY_SPI_WR_OP
, addr
, (void *)data
,
150 static const struct cyttsp4_bus_ops cyttsp_spi_bus_ops
= {
152 .write
= cyttsp_spi_write_block_data
,
153 .read
= cyttsp_spi_read_block_data
,
156 static int cyttsp4_spi_probe(struct spi_device
*spi
)
162 spi
->bits_per_word
= CY_SPI_BITS_PER_WORD
;
163 spi
->mode
= SPI_MODE_0
;
164 error
= spi_setup(spi
);
166 dev_err(&spi
->dev
, "%s: SPI setup error %d\n",
171 ts
= cyttsp4_probe(&cyttsp_spi_bus_ops
, &spi
->dev
, spi
->irq
,
172 CY_SPI_DATA_BUF_SIZE
);
174 return PTR_ERR_OR_ZERO(ts
);
177 static int cyttsp4_spi_remove(struct spi_device
*spi
)
179 struct cyttsp4
*ts
= spi_get_drvdata(spi
);
185 static struct spi_driver cyttsp4_spi_driver
= {
187 .name
= CYTTSP4_SPI_NAME
,
188 .pm
= &cyttsp4_pm_ops
,
190 .probe
= cyttsp4_spi_probe
,
191 .remove
= cyttsp4_spi_remove
,
194 module_spi_driver(cyttsp4_spi_driver
);
196 MODULE_LICENSE("GPL");
197 MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) SPI driver");
198 MODULE_AUTHOR("Cypress");
199 MODULE_ALIAS("spi:cyttsp4");