1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Goodix Berlin Touchscreen Driver 4 * 5 * Copyright (C) 2020 - 2021 Goodix, Inc. 6 * Copyright (C) 2023 Linaro Ltd. 7 * 8 * Based on goodix_ts_berlin driver. 9 */ 10 #include <asm/unaligned.h> 11 #include <linux/kernel.h> 12 #include <linux/module.h> 13 #include <linux/regmap.h> 14 #include <linux/spi/spi.h> 15 #include <linux/input.h> 16 17 #include "goodix_berlin.h" 18 19 #define GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN 1 20 #define GOODIX_BERLIN_REGISTER_WIDTH 4 21 #define GOODIX_BERLIN_SPI_READ_DUMMY_LEN 3 22 #define GOODIX_BERLIN_SPI_READ_PREFIX_LEN (GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \ 23 GOODIX_BERLIN_REGISTER_WIDTH + \ 24 GOODIX_BERLIN_SPI_READ_DUMMY_LEN) 25 #define GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN (GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \ 26 GOODIX_BERLIN_REGISTER_WIDTH) 27 28 #define GOODIX_BERLIN_SPI_WRITE_FLAG 0xF0 29 #define GOODIX_BERLIN_SPI_READ_FLAG 0xF1 30 31 static int goodix_berlin_spi_read(void *context, const void *reg_buf, 32 size_t reg_size, void *val_buf, 33 size_t val_size) 34 { 35 struct spi_device *spi = context; 36 struct spi_transfer xfers; 37 struct spi_message spi_msg; 38 const u32 *reg = reg_buf; /* reg is stored as native u32 at start of buffer */ 39 u8 *buf; 40 int error; 41 42 if (reg_size != GOODIX_BERLIN_REGISTER_WIDTH) 43 return -EINVAL; 44 45 buf = kzalloc(GOODIX_BERLIN_SPI_READ_PREFIX_LEN + val_size, GFP_KERNEL); 46 if (!buf) 47 return -ENOMEM; 48 49 spi_message_init(&spi_msg); 50 memset(&xfers, 0, sizeof(xfers)); 51 52 /* buffer format: 0xF1 + addr(4bytes) + dummy(3bytes) + data */ 53 buf[0] = GOODIX_BERLIN_SPI_READ_FLAG; 54 put_unaligned_be32(*reg, buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN); 55 memset(buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + GOODIX_BERLIN_REGISTER_WIDTH, 56 0xff, GOODIX_BERLIN_SPI_READ_DUMMY_LEN); 57 58 xfers.tx_buf = buf; 59 xfers.rx_buf = buf; 60 xfers.len = GOODIX_BERLIN_SPI_READ_PREFIX_LEN + val_size; 61 xfers.cs_change = 0; 62 spi_message_add_tail(&xfers, &spi_msg); 63 64 error = spi_sync(spi, &spi_msg); 65 if (error < 0) 66 dev_err(&spi->dev, "spi transfer error, %d", error); 67 else 68 memcpy(val_buf, buf + GOODIX_BERLIN_SPI_READ_PREFIX_LEN, val_size); 69 70 kfree(buf); 71 return error; 72 } 73 74 static int goodix_berlin_spi_write(void *context, const void *data, 75 size_t count) 76 { 77 unsigned int len = count - GOODIX_BERLIN_REGISTER_WIDTH; 78 struct spi_device *spi = context; 79 struct spi_transfer xfers; 80 struct spi_message spi_msg; 81 const u32 *reg = data; /* reg is stored as native u32 at start of buffer */ 82 u8 *buf; 83 int error; 84 85 buf = kzalloc(GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN + len, GFP_KERNEL); 86 if (!buf) 87 return -ENOMEM; 88 89 spi_message_init(&spi_msg); 90 memset(&xfers, 0, sizeof(xfers)); 91 92 buf[0] = GOODIX_BERLIN_SPI_WRITE_FLAG; 93 put_unaligned_be32(*reg, buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN); 94 memcpy(buf + GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN, 95 data + GOODIX_BERLIN_REGISTER_WIDTH, len); 96 97 xfers.tx_buf = buf; 98 xfers.len = GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN + len; 99 xfers.cs_change = 0; 100 spi_message_add_tail(&xfers, &spi_msg); 101 102 error = spi_sync(spi, &spi_msg); 103 if (error < 0) 104 dev_err(&spi->dev, "spi transfer error, %d", error); 105 106 kfree(buf); 107 return error; 108 } 109 110 static const struct regmap_config goodix_berlin_spi_regmap_conf = { 111 .reg_bits = 32, 112 .val_bits = 8, 113 .read = goodix_berlin_spi_read, 114 .write = goodix_berlin_spi_write, 115 }; 116 117 /* vendor & product left unassigned here, should probably be updated from fw info */ 118 static const struct input_id goodix_berlin_spi_input_id = { 119 .bustype = BUS_SPI, 120 }; 121 122 static int goodix_berlin_spi_probe(struct spi_device *spi) 123 { 124 struct regmap_config regmap_config; 125 struct regmap *regmap; 126 size_t max_size; 127 int error = 0; 128 129 spi->mode = SPI_MODE_0; 130 spi->bits_per_word = 8; 131 error = spi_setup(spi); 132 if (error) 133 return error; 134 135 max_size = spi_max_transfer_size(spi); 136 137 regmap_config = goodix_berlin_spi_regmap_conf; 138 regmap_config.max_raw_read = max_size - GOODIX_BERLIN_SPI_READ_PREFIX_LEN; 139 regmap_config.max_raw_write = max_size - GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN; 140 141 regmap = devm_regmap_init(&spi->dev, NULL, spi, ®map_config); 142 if (IS_ERR(regmap)) 143 return PTR_ERR(regmap); 144 145 error = goodix_berlin_probe(&spi->dev, spi->irq, 146 &goodix_berlin_spi_input_id, regmap); 147 if (error) 148 return error; 149 150 return 0; 151 } 152 153 static const struct spi_device_id goodix_berlin_spi_ids[] = { 154 { "gt9916" }, 155 { }, 156 }; 157 MODULE_DEVICE_TABLE(spi, goodix_berlin_spi_ids); 158 159 static const struct of_device_id goodix_berlin_spi_of_match[] = { 160 { .compatible = "goodix,gt9916", }, 161 { } 162 }; 163 MODULE_DEVICE_TABLE(of, goodix_berlin_spi_of_match); 164 165 static struct spi_driver goodix_berlin_spi_driver = { 166 .driver = { 167 .name = "goodix-berlin-spi", 168 .of_match_table = goodix_berlin_spi_of_match, 169 .pm = pm_sleep_ptr(&goodix_berlin_pm_ops), 170 }, 171 .probe = goodix_berlin_spi_probe, 172 .id_table = goodix_berlin_spi_ids, 173 }; 174 module_spi_driver(goodix_berlin_spi_driver); 175 176 MODULE_LICENSE("GPL"); 177 MODULE_DESCRIPTION("Goodix Berlin SPI Touchscreen driver"); 178 MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>"); 179