^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Source for:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Cypress TrueTouch(TM) Standard Product (TTSP) SPI touchscreen driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * For use with Cypress Txx3xx parts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Supported parts include:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * CY8CTST341
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * CY8CTMA340
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Copyright (C) 2013 Cypress Semiconductor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "cyttsp_core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define CY_SPI_WR_OP 0x00 /* r/~w */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define CY_SPI_RD_OP 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define CY_SPI_CMD_BYTES 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define CY_SPI_SYNC_BYTE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define CY_SPI_SYNC_ACK1 0x62 /* from protocol v.2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define CY_SPI_SYNC_ACK2 0x9D /* from protocol v.2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define CY_SPI_DATA_SIZE 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define CY_SPI_DATA_BUF_SIZE (CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define CY_SPI_BITS_PER_WORD 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) u8 op, u16 reg, u8 *buf, int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct spi_device *spi = to_spi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct spi_message msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct spi_transfer xfer[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) u8 *wr_buf = &xfer_buf[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u8 *rd_buf = &xfer_buf[CY_SPI_DATA_BUF_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (length > CY_SPI_DATA_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) dev_err(dev, "%s: length %d is too big.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) __func__, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) memset(wr_buf, 0, CY_SPI_DATA_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) memset(rd_buf, 0, CY_SPI_DATA_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) wr_buf[0] = 0x00; /* header byte 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) wr_buf[1] = 0xFF; /* header byte 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) wr_buf[2] = reg; /* reg index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) wr_buf[3] = op; /* r/~w */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (op == CY_SPI_WR_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) memcpy(wr_buf + CY_SPI_CMD_BYTES, buf, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) memset(xfer, 0, sizeof(xfer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) spi_message_init(&msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) We set both TX and RX buffers because Cypress TTSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) requires full duplex operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) xfer[0].tx_buf = wr_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) xfer[0].rx_buf = rd_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) case CY_SPI_WR_OP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) xfer[0].len = length + CY_SPI_CMD_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) spi_message_add_tail(&xfer[0], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) case CY_SPI_RD_OP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) xfer[0].len = CY_SPI_CMD_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) spi_message_add_tail(&xfer[0], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) xfer[1].rx_buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) xfer[1].len = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) spi_message_add_tail(&xfer[1], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) dev_err(dev, "%s: bad operation code=%d\n", __func__, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) retval = spi_sync(spi, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) dev_dbg(dev, "%s: spi_sync() error %d, len=%d, op=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) __func__, retval, xfer[1].len, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * do not return here since was a bad ACK sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * let the following ACK check handle any errors and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * allow silent retries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (rd_buf[CY_SPI_SYNC_BYTE] != CY_SPI_SYNC_ACK1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) rd_buf[CY_SPI_SYNC_BYTE + 1] != CY_SPI_SYNC_ACK2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) dev_dbg(dev, "%s: operation %d failed\n", __func__, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) for (i = 0; i < CY_SPI_CMD_BYTES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) dev_dbg(dev, "%s: test rd_buf[%d]:0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) __func__, i, rd_buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) for (i = 0; i < length; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) dev_dbg(dev, "%s: test buf[%d]:0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) __func__, i, buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u16 addr, u8 length, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_RD_OP, addr, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int cyttsp_spi_write_block_data(struct device *dev, u8 *xfer_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u16 addr, u8 length, const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static const struct cyttsp_bus_ops cyttsp_spi_bus_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .bustype = BUS_SPI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .write = cyttsp_spi_write_block_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .read = cyttsp_spi_read_block_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static int cyttsp_spi_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct cyttsp *ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* Set up SPI*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) spi->bits_per_word = CY_SPI_BITS_PER_WORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) spi->mode = SPI_MODE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) error = spi_setup(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) dev_err(&spi->dev, "%s: SPI setup error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) __func__, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ts = cyttsp_probe(&cyttsp_spi_bus_ops, &spi->dev, spi->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) CY_SPI_DATA_BUF_SIZE * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (IS_ERR(ts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return PTR_ERR(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) spi_set_drvdata(spi, ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static struct spi_driver cyttsp_spi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .name = CY_SPI_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .pm = &cyttsp_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .probe = cyttsp_spi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) module_spi_driver(cyttsp_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) SPI driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) MODULE_AUTHOR("Cypress");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) MODULE_ALIAS("spi:cyttsp");