^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 Txx4xx parts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Supported parts include:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * TMA4XX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * TMA1036
^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 "cyttsp4_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_BITS_PER_WORD 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define CY_SPI_A8_BIT 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define CY_SPI_WR_HEADER_BYTES 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define CY_SPI_RD_HEADER_BYTES 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define CY_SPI_CMD_BYTES 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define CY_SPI_SYNC_BYTE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define CY_SPI_SYNC_ACK 0x62 /* from TRM *A protocol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define CY_SPI_DATA_SIZE (2 * 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define CY_SPI_DATA_BUF_SIZE (CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) u8 op, u16 reg, u8 *buf, int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct spi_device *spi = to_spi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct spi_message msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct spi_transfer xfer[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) u8 *wr_buf = &xfer_buf[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) u8 rd_buf[CY_SPI_CMD_BYTES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (length > CY_SPI_DATA_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) dev_err(dev, "%s: length %d is too big.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) __func__, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) memset(wr_buf, 0, CY_SPI_DATA_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) memset(rd_buf, 0, CY_SPI_CMD_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) wr_buf[0] = op + (((reg >> 8) & 0x1) ? CY_SPI_A8_BIT : 0);
^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) wr_buf[1] = reg & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (length > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) memcpy(wr_buf + CY_SPI_CMD_BYTES, buf, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) memset(xfer, 0, sizeof(xfer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) spi_message_init(&msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) We set both TX and RX buffers because Cypress TTSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) requires full duplex operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) xfer[0].tx_buf = wr_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) xfer[0].rx_buf = rd_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) case CY_SPI_WR_OP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) xfer[0].len = length + CY_SPI_CMD_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) spi_message_add_tail(&xfer[0], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) case CY_SPI_RD_OP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) xfer[0].len = CY_SPI_RD_HEADER_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) spi_message_add_tail(&xfer[0], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) xfer[1].rx_buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) xfer[1].len = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) spi_message_add_tail(&xfer[1], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) dev_err(dev, "%s: bad operation code=%d\n", __func__, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) retval = spi_sync(spi, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) dev_dbg(dev, "%s: spi_sync() error %d, len=%d, op=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) __func__, retval, xfer[1].len, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * do not return here since was a bad ACK sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * let the following ACK check handle any errors and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * allow silent retries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (rd_buf[CY_SPI_SYNC_BYTE] != CY_SPI_SYNC_ACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) dev_dbg(dev, "%s: operation %d failed\n", __func__, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) for (i = 0; i < CY_SPI_CMD_BYTES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) dev_dbg(dev, "%s: test rd_buf[%d]:0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) __func__, i, rd_buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) for (i = 0; i < length; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) dev_dbg(dev, "%s: test buf[%d]:0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) __func__, i, buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) u16 addr, u8 length, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) rc = cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_RD_OP, addr, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static int cyttsp_spi_write_block_data(struct device *dev, u8 *xfer_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u16 addr, u8 length, const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static const struct cyttsp4_bus_ops cyttsp_spi_bus_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .bustype = BUS_SPI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .write = cyttsp_spi_write_block_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .read = cyttsp_spi_read_block_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static int cyttsp4_spi_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct cyttsp4 *ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* Set up SPI*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) spi->bits_per_word = CY_SPI_BITS_PER_WORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) spi->mode = SPI_MODE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) error = spi_setup(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) dev_err(&spi->dev, "%s: SPI setup error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) __func__, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ts = cyttsp4_probe(&cyttsp_spi_bus_ops, &spi->dev, spi->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) CY_SPI_DATA_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return PTR_ERR_OR_ZERO(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int cyttsp4_spi_remove(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct cyttsp4 *ts = spi_get_drvdata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) cyttsp4_remove(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static struct spi_driver cyttsp4_spi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .name = CYTTSP4_SPI_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .pm = &cyttsp4_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .probe = cyttsp4_spi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .remove = cyttsp4_spi_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) module_spi_driver(cyttsp4_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) SPI driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) MODULE_AUTHOR("Cypress");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) MODULE_ALIAS("spi:cyttsp4");