1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (c) 2024 Intel Corporation */
3
4 #include <linux/bitfield.h>
5 #include <linux/math.h>
6 #include <linux/regmap.h>
7
8 #include "intel-thc-dev.h"
9 #include "intel-thc-hw.h"
10
thc_regmap_read(void * context,unsigned int reg,unsigned int * val)11 static int thc_regmap_read(void *context, unsigned int reg,
12 unsigned int *val)
13 {
14 struct thc_device *thc_ctx = context;
15 void __iomem *base = thc_ctx->mmio_addr;
16
17 *val = ioread32(base + reg);
18 return 0;
19 }
20
thc_regmap_write(void * context,unsigned int reg,unsigned int val)21 static int thc_regmap_write(void *context, unsigned int reg,
22 unsigned int val)
23 {
24 struct thc_device *thc_ctx = context;
25 void __iomem *base = thc_ctx->mmio_addr;
26
27 iowrite32(val, base + reg);
28 return 0;
29 }
30
31 static const struct regmap_range thc_rw_ranges[] = {
32 regmap_reg_range(0x10, 0x14),
33 regmap_reg_range(0x1000, 0x1320),
34 };
35
36 static const struct regmap_access_table thc_rw_table = {
37 .yes_ranges = thc_rw_ranges,
38 .n_yes_ranges = ARRAY_SIZE(thc_rw_ranges),
39 };
40
41 static const struct regmap_config thc_regmap_cfg = {
42 .name = "thc_regmap_common",
43 .reg_bits = 32,
44 .val_bits = 32,
45 .reg_stride = 4,
46 .max_register = 0x1320,
47 .reg_read = thc_regmap_read,
48 .reg_write = thc_regmap_write,
49 .cache_type = REGCACHE_NONE,
50 .fast_io = true,
51 .rd_table = &thc_rw_table,
52 .wr_table = &thc_rw_table,
53 .volatile_table = &thc_rw_table,
54 };
55
56 /**
57 * thc_clear_state - Clear THC hardware state
58 *
59 * @dev: The pointer of THC device structure
60 */
thc_clear_state(const struct thc_device * dev)61 static void thc_clear_state(const struct thc_device *dev)
62 {
63 u32 val;
64
65 /* Clear interrupt cause register */
66 val = THC_M_PRT_ERR_CAUSE_INVLD_DEV_ENTRY |
67 THC_M_PRT_ERR_CAUSE_FRAME_BABBLE_ERR |
68 THC_M_PRT_ERR_CAUSE_BUF_OVRRUN_ERR |
69 THC_M_PRT_ERR_CAUSE_PRD_ENTRY_ERR;
70 regmap_write_bits(dev->thc_regmap, THC_M_PRT_ERR_CAUSE_OFFSET, val, val);
71
72 /* Clear interrupt error state */
73 regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_CNTRL_1_OFFSET,
74 THC_M_PRT_READ_DMA_CNTRL_IE_STALL,
75 THC_M_PRT_READ_DMA_CNTRL_IE_STALL);
76 regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_CNTRL_2_OFFSET,
77 THC_M_PRT_READ_DMA_CNTRL_IE_STALL,
78 THC_M_PRT_READ_DMA_CNTRL_IE_STALL);
79
80 regmap_write_bits(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
81 THC_M_PRT_INT_STATUS_TXN_ERR_INT_STS,
82 THC_M_PRT_INT_STATUS_TXN_ERR_INT_STS);
83 regmap_write_bits(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
84 THC_M_PRT_INT_STATUS_FATAL_ERR_INT_STS,
85 THC_M_PRT_INT_STATUS_FATAL_ERR_INT_STS);
86
87 val = THC_M_PRT_INT_EN_TXN_ERR_INT_EN |
88 THC_M_PRT_INT_EN_FATAL_ERR_INT_EN |
89 THC_M_PRT_INT_EN_BUF_OVRRUN_ERR_INT_EN;
90 regmap_write_bits(dev->thc_regmap, THC_M_PRT_INT_EN_OFFSET, val, val);
91
92 val = THC_M_PRT_SW_SEQ_STS_THC_SS_ERR |
93 THC_M_PRT_SW_SEQ_STS_TSSDONE;
94 regmap_write_bits(dev->thc_regmap, THC_M_PRT_SW_SEQ_STS_OFFSET, val, val);
95
96 /* Clear RxDMA state */
97 regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_CNTRL_1_OFFSET,
98 THC_M_PRT_READ_DMA_CNTRL_IE_EOF, 0);
99 regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_CNTRL_2_OFFSET,
100 THC_M_PRT_READ_DMA_CNTRL_IE_EOF, 0);
101
102 regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_INT_STS_1_OFFSET,
103 THC_M_PRT_READ_DMA_INT_STS_EOF_INT_STS,
104 THC_M_PRT_READ_DMA_INT_STS_EOF_INT_STS);
105 regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_INT_STS_2_OFFSET,
106 THC_M_PRT_READ_DMA_INT_STS_EOF_INT_STS,
107 THC_M_PRT_READ_DMA_INT_STS_EOF_INT_STS);
108 regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_INT_STS_1_OFFSET,
109 THC_M_PRT_READ_DMA_INT_STS_NONDMA_INT_STS,
110 THC_M_PRT_READ_DMA_INT_STS_NONDMA_INT_STS);
111
112 /* Clear TxDMA state */
113 regmap_write_bits(dev->thc_regmap, THC_M_PRT_WRITE_DMA_CNTRL_OFFSET,
114 THC_M_PRT_WRITE_DMA_CNTRL_THC_WRDMA_IE_IOC_DMACPL,
115 THC_M_PRT_WRITE_DMA_CNTRL_THC_WRDMA_IE_IOC_DMACPL);
116
117 val = THC_M_PRT_WRITE_INT_STS_THC_WRDMA_ERROR_STS |
118 THC_M_PRT_WRITE_INT_STS_THC_WRDMA_IOC_STS |
119 THC_M_PRT_WRITE_INT_STS_THC_WRDMA_CMPL_STATUS;
120 regmap_write_bits(dev->thc_regmap, THC_M_PRT_WRITE_INT_STS_OFFSET, val, val);
121
122 /* Reset all DMAs count */
123 regmap_write_bits(dev->thc_regmap, THC_M_PRT_DB_CNT_1_OFFSET,
124 THC_M_PRT_DB_CNT_1_THC_M_PRT_DB_CNT_RST,
125 THC_M_PRT_DB_CNT_1_THC_M_PRT_DB_CNT_RST);
126
127 regmap_write_bits(dev->thc_regmap, THC_M_PRT_DEVINT_CNT_OFFSET,
128 THC_M_PRT_DEVINT_CNT_THC_M_PRT_DEVINT_CNT_RST,
129 THC_M_PRT_DEVINT_CNT_THC_M_PRT_DEVINT_CNT_RST);
130 regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_CNTRL_1_OFFSET,
131 THC_M_PRT_READ_DMA_CNTRL_TPCPR,
132 THC_M_PRT_READ_DMA_CNTRL_TPCPR);
133
134 /* Reset THC hardware sequence state */
135 regmap_write_bits(dev->thc_regmap, THC_M_PRT_FRAME_DROP_CNT_1_OFFSET,
136 THC_M_PRT_FRAME_DROP_CNT_1_RFDC,
137 THC_M_PRT_FRAME_DROP_CNT_1_RFDC);
138 regmap_write_bits(dev->thc_regmap, THC_M_PRT_FRAME_DROP_CNT_2_OFFSET,
139 THC_M_PRT_FRAME_DROP_CNT_2_RFDC,
140 THC_M_PRT_FRAME_DROP_CNT_2_RFDC);
141
142 regmap_write_bits(dev->thc_regmap, THC_M_PRT_FRM_CNT_1_OFFSET,
143 THC_M_PRT_FRM_CNT_1_THC_M_PRT_FRM_CNT_RST,
144 THC_M_PRT_FRM_CNT_1_THC_M_PRT_FRM_CNT_RST);
145 regmap_write_bits(dev->thc_regmap, THC_M_PRT_FRM_CNT_2_OFFSET,
146 THC_M_PRT_FRM_CNT_2_THC_M_PRT_FRM_CNT_RST,
147 THC_M_PRT_FRM_CNT_2_THC_M_PRT_FRM_CNT_RST);
148
149 regmap_write_bits(dev->thc_regmap, THC_M_PRT_RXDMA_PKT_CNT_1_OFFSET,
150 THC_M_PRT_RXDMA_PKT_CNT_1_THC_M_PRT_RXDMA_PKT_CNT_RST,
151 THC_M_PRT_RXDMA_PKT_CNT_1_THC_M_PRT_RXDMA_PKT_CNT_RST);
152 regmap_write_bits(dev->thc_regmap, THC_M_PRT_RXDMA_PKT_CNT_2_OFFSET,
153 THC_M_PRT_RXDMA_PKT_CNT_2_THC_M_PRT_RXDMA_PKT_CNT_RST,
154 THC_M_PRT_RXDMA_PKT_CNT_2_THC_M_PRT_RXDMA_PKT_CNT_RST);
155
156 regmap_write_bits(dev->thc_regmap, THC_M_PRT_SWINT_CNT_1_OFFSET,
157 THC_M_PRT_SWINT_CNT_1_THC_M_PRT_SWINT_CNT_RST,
158 THC_M_PRT_SWINT_CNT_1_THC_M_PRT_SWINT_CNT_RST);
159 regmap_write_bits(dev->thc_regmap, THC_M_PRT_SWINT_CNT_1_OFFSET,
160 THC_M_PRT_SWINT_CNT_1_THC_M_PRT_SWINT_CNT_RST,
161 THC_M_PRT_SWINT_CNT_1_THC_M_PRT_SWINT_CNT_RST);
162
163 regmap_write_bits(dev->thc_regmap, THC_M_PRT_TX_FRM_CNT_OFFSET,
164 THC_M_PRT_TX_FRM_CNT_THC_M_PRT_TX_FRM_CNT_RST,
165 THC_M_PRT_TX_FRM_CNT_THC_M_PRT_TX_FRM_CNT_RST);
166
167 regmap_write_bits(dev->thc_regmap, THC_M_PRT_TXDMA_PKT_CNT_OFFSET,
168 THC_M_PRT_TXDMA_PKT_CNT_THC_M_PRT_TXDMA_PKT_CNT_RST,
169 THC_M_PRT_TXDMA_PKT_CNT_THC_M_PRT_TXDMA_PKT_CNT_RST);
170
171 regmap_write_bits(dev->thc_regmap, THC_M_PRT_UFRM_CNT_1_OFFSET,
172 THC_M_PRT_UFRM_CNT_1_THC_M_PRT_UFRM_CNT_RST,
173 THC_M_PRT_UFRM_CNT_1_THC_M_PRT_UFRM_CNT_RST);
174 regmap_write_bits(dev->thc_regmap, THC_M_PRT_UFRM_CNT_2_OFFSET,
175 THC_M_PRT_UFRM_CNT_2_THC_M_PRT_UFRM_CNT_RST,
176 THC_M_PRT_UFRM_CNT_2_THC_M_PRT_UFRM_CNT_RST);
177
178 regmap_write_bits(dev->thc_regmap, THC_M_PRT_PRD_EMPTY_CNT_1_OFFSET,
179 THC_M_PRT_PRD_EMPTY_CNT_1_RPTEC,
180 THC_M_PRT_PRD_EMPTY_CNT_1_RPTEC);
181 regmap_write_bits(dev->thc_regmap, THC_M_PRT_PRD_EMPTY_CNT_2_OFFSET,
182 THC_M_PRT_PRD_EMPTY_CNT_2_RPTEC,
183 THC_M_PRT_PRD_EMPTY_CNT_2_RPTEC);
184 }
185
186 /**
187 * thc_dev_init - Allocate and initialize the THC device structure
188 *
189 * @device: The pointer of device structure
190 * @mem_addr: The pointer of MMIO memory address
191 *
192 * Return: The thc_device pointer on success, NULL on failed.
193 */
thc_dev_init(struct device * device,void __iomem * mem_addr)194 struct thc_device *thc_dev_init(struct device *device, void __iomem *mem_addr)
195 {
196 struct thc_device *thc_dev;
197 int ret;
198
199 thc_dev = devm_kzalloc(device, sizeof(*thc_dev), GFP_KERNEL);
200 if (!thc_dev)
201 return ERR_PTR(-ENOMEM);
202
203 thc_dev->dev = device;
204 thc_dev->mmio_addr = mem_addr;
205 thc_dev->thc_regmap = devm_regmap_init(device, NULL, thc_dev, &thc_regmap_cfg);
206 if (IS_ERR(thc_dev->thc_regmap)) {
207 ret = PTR_ERR(thc_dev->thc_regmap);
208 dev_err_once(device, "Failed to init thc_regmap: %d\n", ret);
209 return ERR_PTR(ret);
210 }
211
212 thc_clear_state(thc_dev);
213
214 mutex_init(&thc_dev->thc_bus_lock);
215 init_waitqueue_head(&thc_dev->write_complete_wait);
216 init_waitqueue_head(&thc_dev->swdma_complete_wait);
217
218 thc_dev->dma_ctx = thc_dma_init(thc_dev);
219 if (!thc_dev->dma_ctx) {
220 dev_err_once(device, "DMA context init failed\n");
221 return ERR_PTR(-ENOMEM);
222 }
223
224 return thc_dev;
225 }
226 EXPORT_SYMBOL_NS_GPL(thc_dev_init, "INTEL_THC");
227
prepare_pio(const struct thc_device * dev,const u8 pio_op,const u32 address,const u32 size)228 static int prepare_pio(const struct thc_device *dev, const u8 pio_op,
229 const u32 address, const u32 size)
230 {
231 u32 sts, ctrl, addr, mask;
232
233 regmap_read(dev->thc_regmap, THC_M_PRT_SW_SEQ_STS_OFFSET, &sts);
234
235 /* Check if THC previous PIO still in progress */
236 if (sts & THC_M_PRT_SW_SEQ_STS_THC_SS_CIP) {
237 dev_err_once(dev->dev, "THC PIO is still busy!\n");
238 return -EBUSY;
239 }
240
241 /* Clear error bit and complete bit in state register */
242 sts |= THC_M_PRT_SW_SEQ_STS_THC_SS_ERR |
243 THC_M_PRT_SW_SEQ_STS_TSSDONE;
244 regmap_write(dev->thc_regmap, THC_M_PRT_SW_SEQ_STS_OFFSET, sts);
245
246 /* Set PIO data size, opcode and interrupt capability */
247 ctrl = FIELD_PREP(THC_M_PRT_SW_SEQ_CNTRL_THC_SS_BC, size) |
248 FIELD_PREP(THC_M_PRT_SW_SEQ_CNTRL_THC_SS_CMD, pio_op);
249 if (dev->pio_int_supported)
250 ctrl |= THC_M_PRT_SW_SEQ_CNTRL_THC_SS_CD_IE;
251
252 mask = THC_M_PRT_SW_SEQ_CNTRL_THC_SS_BC |
253 THC_M_PRT_SW_SEQ_CNTRL_THC_SS_CMD |
254 THC_M_PRT_SW_SEQ_CNTRL_THC_SS_CD_IE;
255 regmap_write_bits(dev->thc_regmap,
256 THC_M_PRT_SW_SEQ_CNTRL_OFFSET, mask, ctrl);
257
258 /* Set PIO target address */
259 addr = FIELD_PREP(THC_M_PRT_SW_SEQ_DATA0_ADDR_THC_SW_SEQ_DATA0_ADDR, address);
260 mask = THC_M_PRT_SW_SEQ_DATA0_ADDR_THC_SW_SEQ_DATA0_ADDR;
261 regmap_write_bits(dev->thc_regmap,
262 THC_M_PRT_SW_SEQ_DATA0_ADDR_OFFSET, mask, addr);
263 return 0;
264 }
265
pio_start(const struct thc_device * dev,u32 size_in_bytes,const u32 * buffer)266 static void pio_start(const struct thc_device *dev,
267 u32 size_in_bytes, const u32 *buffer)
268 {
269 if (size_in_bytes && buffer)
270 regmap_bulk_write(dev->thc_regmap, THC_M_PRT_SW_SEQ_DATA1_OFFSET,
271 buffer, size_in_bytes / sizeof(u32));
272
273 /* Enable Start bit */
274 regmap_write_bits(dev->thc_regmap,
275 THC_M_PRT_SW_SEQ_CNTRL_OFFSET,
276 THC_M_PRT_SW_SEQ_CNTRL_TSSGO,
277 THC_M_PRT_SW_SEQ_CNTRL_TSSGO);
278 }
279
pio_complete(const struct thc_device * dev,u32 * buffer,u32 * size)280 static int pio_complete(const struct thc_device *dev,
281 u32 *buffer, u32 *size)
282 {
283 u32 sts, ctrl;
284
285 regmap_read(dev->thc_regmap, THC_M_PRT_SW_SEQ_STS_OFFSET, &sts);
286 if (sts & THC_M_PRT_SW_SEQ_STS_THC_SS_ERR) {
287 dev_err_once(dev->dev, "PIO operation error\n");
288 return -EBUSY;
289 }
290
291 if (buffer && size) {
292 regmap_read(dev->thc_regmap, THC_M_PRT_SW_SEQ_CNTRL_OFFSET, &ctrl);
293 *size = FIELD_GET(THC_M_PRT_SW_SEQ_CNTRL_THC_SS_BC, ctrl);
294
295 regmap_bulk_read(dev->thc_regmap, THC_M_PRT_SW_SEQ_DATA1_OFFSET,
296 buffer, *size / sizeof(u32));
297 }
298
299 sts |= THC_M_PRT_SW_SEQ_STS_THC_SS_ERR | THC_M_PRT_SW_SEQ_STS_TSSDONE;
300 regmap_write(dev->thc_regmap, THC_M_PRT_SW_SEQ_STS_OFFSET, sts);
301 return 0;
302 }
303
pio_wait(const struct thc_device * dev)304 static int pio_wait(const struct thc_device *dev)
305 {
306 u32 sts = 0;
307 int ret;
308
309 ret = regmap_read_poll_timeout(dev->thc_regmap, THC_M_PRT_SW_SEQ_STS_OFFSET, sts,
310 !(sts & THC_M_PRT_SW_SEQ_STS_THC_SS_CIP ||
311 !(sts & THC_M_PRT_SW_SEQ_STS_TSSDONE)),
312 THC_REGMAP_POLLING_INTERVAL_US, THC_PIO_DONE_TIMEOUT_US);
313 if (ret)
314 dev_err_once(dev->dev, "Timeout while polling PIO operation done\n");
315
316 return ret;
317 }
318
319 /**
320 * thc_tic_pio_read - Read data from touch device by PIO
321 *
322 * @dev: The pointer of THC private device context
323 * @address: Slave address for the PIO operation
324 * @size: Expected read data size
325 * @actual_size: The pointer of the actual data size read from touch device
326 * @buffer: The pointer of data buffer to store the data read from touch device
327 *
328 * Return: 0 on success, other error codes on failed.
329 */
thc_tic_pio_read(struct thc_device * dev,const u32 address,const u32 size,u32 * actual_size,u32 * buffer)330 int thc_tic_pio_read(struct thc_device *dev, const u32 address,
331 const u32 size, u32 *actual_size, u32 *buffer)
332 {
333 u8 opcode;
334 int ret;
335
336 if (size <= 0 || !actual_size || !buffer) {
337 dev_err(dev->dev, "Invalid input parameters, size %u, actual_size %p, buffer %p\n",
338 size, actual_size, buffer);
339 return -EINVAL;
340 }
341
342 if (mutex_lock_interruptible(&dev->thc_bus_lock))
343 return -EINTR;
344
345 opcode = (dev->port_type == THC_PORT_TYPE_SPI) ?
346 THC_PIO_OP_SPI_TIC_READ : THC_PIO_OP_I2C_TIC_READ;
347
348 ret = prepare_pio(dev, opcode, address, size);
349 if (ret < 0)
350 goto end;
351
352 pio_start(dev, 0, NULL);
353
354 ret = pio_wait(dev);
355 if (ret < 0)
356 goto end;
357
358 ret = pio_complete(dev, buffer, actual_size);
359
360 end:
361 mutex_unlock(&dev->thc_bus_lock);
362 return ret;
363 }
364 EXPORT_SYMBOL_NS_GPL(thc_tic_pio_read, "INTEL_THC");
365
366 /**
367 * thc_tic_pio_write - Write data to touch device by PIO
368 *
369 * @dev: The pointer of THC private device context
370 * @address: Slave address for the PIO operation
371 * @size: PIO write data size
372 * @buffer: The pointer of the write data buffer
373 *
374 * Return: 0 on success, other error codes on failed.
375 */
thc_tic_pio_write(struct thc_device * dev,const u32 address,const u32 size,const u32 * buffer)376 int thc_tic_pio_write(struct thc_device *dev, const u32 address,
377 const u32 size, const u32 *buffer)
378 {
379 u8 opcode;
380 int ret;
381
382 if (size <= 0 || !buffer) {
383 dev_err(dev->dev, "Invalid input parameters, size %u, buffer %p\n",
384 size, buffer);
385 return -EINVAL;
386 }
387
388 if (mutex_lock_interruptible(&dev->thc_bus_lock))
389 return -EINTR;
390
391 opcode = (dev->port_type == THC_PORT_TYPE_SPI) ?
392 THC_PIO_OP_SPI_TIC_WRITE : THC_PIO_OP_I2C_TIC_WRITE;
393
394 ret = prepare_pio(dev, opcode, address, size);
395 if (ret < 0)
396 goto end;
397
398 pio_start(dev, size, buffer);
399
400 ret = pio_wait(dev);
401 if (ret < 0)
402 goto end;
403
404 ret = pio_complete(dev, NULL, NULL);
405
406 end:
407 mutex_unlock(&dev->thc_bus_lock);
408 return ret;
409 }
410 EXPORT_SYMBOL_NS_GPL(thc_tic_pio_write, "INTEL_THC");
411
412 /**
413 * thc_tic_pio_write_and_read - Write data followed by read data by PIO
414 *
415 * @dev: The pointer of THC private device context
416 * @address: Slave address for the PIO operation
417 * @write_size: PIO write data size
418 * @write_buffer: The pointer of the write data buffer
419 * @read_size: Expected PIO read data size
420 * @actual_size: The pointer of the actual read data size
421 * @read_buffer: The pointer of PIO read data buffer
422 *
423 * Return: 0 on success, other error codes on failed.
424 */
thc_tic_pio_write_and_read(struct thc_device * dev,const u32 address,const u32 write_size,const u32 * write_buffer,const u32 read_size,u32 * actual_size,u32 * read_buffer)425 int thc_tic_pio_write_and_read(struct thc_device *dev, const u32 address,
426 const u32 write_size, const u32 *write_buffer,
427 const u32 read_size, u32 *actual_size, u32 *read_buffer)
428 {
429 u32 i2c_ctrl, mask;
430 int ret;
431
432 if (dev->port_type == THC_PORT_TYPE_SPI) {
433 dev_err(dev->dev, "SPI port type doesn't support pio write and read!");
434 return -EINVAL;
435 }
436
437 if (mutex_lock_interruptible(&dev->thc_bus_lock))
438 return -EINTR;
439
440 /* Config i2c PIO write and read sequence */
441 i2c_ctrl = FIELD_PREP(THC_M_PRT_SW_SEQ_I2C_WR_CNTRL_THC_PIO_I2C_WBC, write_size);
442 mask = THC_M_PRT_SW_SEQ_I2C_WR_CNTRL_THC_PIO_I2C_WBC;
443
444 regmap_write_bits(dev->thc_regmap, THC_M_PRT_SW_SEQ_I2C_WR_CNTRL_OFFSET,
445 mask, i2c_ctrl);
446
447 regmap_write_bits(dev->thc_regmap, THC_M_PRT_SW_SEQ_I2C_WR_CNTRL_OFFSET,
448 THC_M_PRT_SW_SEQ_I2C_WR_CNTRL_THC_I2C_RW_PIO_EN,
449 THC_M_PRT_SW_SEQ_I2C_WR_CNTRL_THC_I2C_RW_PIO_EN);
450
451 ret = prepare_pio(dev, THC_PIO_OP_I2C_TIC_WRITE_AND_READ, address, read_size);
452 if (ret < 0)
453 goto end;
454
455 pio_start(dev, write_size, write_buffer);
456
457 ret = pio_wait(dev);
458 if (ret < 0)
459 goto end;
460
461 ret = pio_complete(dev, read_buffer, actual_size);
462
463 end:
464 mutex_unlock(&dev->thc_bus_lock);
465 return ret;
466 }
467 EXPORT_SYMBOL_NS_GPL(thc_tic_pio_write_and_read, "INTEL_THC");
468
469 /**
470 * thc_interrupt_config - Configure THC interrupts
471 *
472 * @dev: The pointer of THC private device context
473 */
thc_interrupt_config(struct thc_device * dev)474 void thc_interrupt_config(struct thc_device *dev)
475 {
476 u32 mbits, mask, r_dma_ctrl_1;
477
478 /* Clear Error reporting interrupt status bits */
479 mbits = THC_M_PRT_INT_STATUS_TXN_ERR_INT_STS |
480 THC_M_PRT_INT_STATUS_FATAL_ERR_INT_STS;
481 regmap_write_bits(dev->thc_regmap,
482 THC_M_PRT_INT_STATUS_OFFSET,
483 mbits, mbits);
484
485 /* Enable Error Reporting Interrupts */
486 mbits = THC_M_PRT_INT_EN_TXN_ERR_INT_EN |
487 THC_M_PRT_INT_EN_FATAL_ERR_INT_EN |
488 THC_M_PRT_INT_EN_BUF_OVRRUN_ERR_INT_EN;
489 regmap_write_bits(dev->thc_regmap,
490 THC_M_PRT_INT_EN_OFFSET,
491 mbits, mbits);
492
493 /* Clear PIO Interrupt status bits */
494 mbits = THC_M_PRT_SW_SEQ_STS_THC_SS_ERR |
495 THC_M_PRT_SW_SEQ_STS_TSSDONE;
496 regmap_write_bits(dev->thc_regmap,
497 THC_M_PRT_SW_SEQ_STS_OFFSET,
498 mbits, mbits);
499
500 /* Read Interrupts */
501 regmap_read(dev->thc_regmap,
502 THC_M_PRT_READ_DMA_CNTRL_1_OFFSET,
503 &r_dma_ctrl_1);
504 /* Disable RxDMA1 */
505 r_dma_ctrl_1 &= ~THC_M_PRT_READ_DMA_CNTRL_IE_EOF;
506 regmap_write(dev->thc_regmap,
507 THC_M_PRT_READ_DMA_CNTRL_1_OFFSET,
508 r_dma_ctrl_1);
509
510 /* Ack EOF Interrupt RxDMA1 */
511 mbits = THC_M_PRT_READ_DMA_INT_STS_EOF_INT_STS;
512 /* Ack NonDMA Interrupt */
513 mbits |= THC_M_PRT_READ_DMA_INT_STS_NONDMA_INT_STS;
514 regmap_write_bits(dev->thc_regmap,
515 THC_M_PRT_READ_DMA_INT_STS_1_OFFSET,
516 mbits, mbits);
517
518 /* Ack EOF Interrupt RxDMA2 */
519 regmap_write_bits(dev->thc_regmap,
520 THC_M_PRT_READ_DMA_INT_STS_2_OFFSET,
521 THC_M_PRT_READ_DMA_INT_STS_EOF_INT_STS,
522 THC_M_PRT_READ_DMA_INT_STS_EOF_INT_STS);
523
524 /* Write Interrupts */
525 /* Disable TxDMA */
526 regmap_write_bits(dev->thc_regmap,
527 THC_M_PRT_WRITE_DMA_CNTRL_OFFSET,
528 THC_M_PRT_WRITE_DMA_CNTRL_THC_WRDMA_IE_IOC_DMACPL,
529 0);
530
531 /* Clear TxDMA interrupt status bits */
532 mbits = THC_M_PRT_WRITE_INT_STS_THC_WRDMA_ERROR_STS;
533 mbits |= THC_M_PRT_WRITE_INT_STS_THC_WRDMA_IOC_STS;
534 regmap_write_bits(dev->thc_regmap,
535 THC_M_PRT_WRITE_INT_STS_OFFSET,
536 mbits, mbits);
537
538 /* Enable Non-DMA device inband interrupt */
539 r_dma_ctrl_1 |= THC_M_PRT_READ_DMA_CNTRL_IE_NDDI;
540 regmap_write(dev->thc_regmap,
541 THC_M_PRT_READ_DMA_CNTRL_1_OFFSET,
542 r_dma_ctrl_1);
543
544 if (dev->port_type == THC_PORT_TYPE_SPI) {
545 /* Edge triggered interrupt */
546 regmap_write_bits(dev->thc_regmap, THC_M_PRT_TSEQ_CNTRL_1_OFFSET,
547 THC_M_PRT_TSEQ_CNTRL_1_INT_EDG_DET_EN,
548 THC_M_PRT_TSEQ_CNTRL_1_INT_EDG_DET_EN);
549 } else {
550 /* Level triggered interrupt */
551 regmap_write_bits(dev->thc_regmap, THC_M_PRT_TSEQ_CNTRL_1_OFFSET,
552 THC_M_PRT_TSEQ_CNTRL_1_INT_EDG_DET_EN, 0);
553
554 mbits = THC_M_PRT_INT_EN_THC_I2C_IC_MST_ON_HOLD_INT_EN |
555 THC_M_PRT_INT_EN_THC_I2C_IC_SCL_STUCK_AT_LOW_DET_INT_EN |
556 THC_M_PRT_INT_EN_THC_I2C_IC_TX_ABRT_INT_EN |
557 THC_M_PRT_INT_EN_THC_I2C_IC_TX_OVER_INT_EN |
558 THC_M_PRT_INT_EN_THC_I2C_IC_RX_FULL_INT_EN |
559 THC_M_PRT_INT_EN_THC_I2C_IC_RX_OVER_INT_EN |
560 THC_M_PRT_INT_EN_THC_I2C_IC_RX_UNDER_INT_EN;
561 regmap_write_bits(dev->thc_regmap, THC_M_PRT_INT_EN_OFFSET,
562 mbits, mbits);
563 }
564
565 thc_set_pio_interrupt_support(dev, false);
566
567 /* HIDSPI specific settings */
568 if (dev->port_type == THC_PORT_TYPE_SPI) {
569 mbits = FIELD_PREP(THC_M_PRT_DEVINT_CFG_1_THC_M_PRT_INTTYP_OFFSET,
570 THC_BIT_OFFSET_INTERRUPT_TYPE) |
571 FIELD_PREP(THC_M_PRT_DEVINT_CFG_1_THC_M_PRT_INTTYP_LEN,
572 THC_BIT_LENGTH_INTERRUPT_TYPE) |
573 FIELD_PREP(THC_M_PRT_DEVINT_CFG_1_THC_M_PRT_EOF_OFFSET,
574 THC_BIT_OFFSET_LAST_FRAGMENT_FLAG) |
575 FIELD_PREP(THC_M_PRT_DEVINT_CFG_1_THC_M_PRT_INTTYP_DATA_VAL,
576 THC_BITMASK_INVALID_TYPE_DATA);
577 mask = THC_M_PRT_DEVINT_CFG_1_THC_M_PRT_INTTYP_OFFSET |
578 THC_M_PRT_DEVINT_CFG_1_THC_M_PRT_INTTYP_LEN |
579 THC_M_PRT_DEVINT_CFG_1_THC_M_PRT_EOF_OFFSET |
580 THC_M_PRT_DEVINT_CFG_1_THC_M_PRT_INTTYP_DATA_VAL;
581 regmap_write_bits(dev->thc_regmap, THC_M_PRT_DEVINT_CFG_1_OFFSET,
582 mask, mbits);
583
584 mbits = FIELD_PREP(THC_M_PRT_DEVINT_CFG_2_THC_M_PRT_UFSIZE_OFFSET,
585 THC_BIT_OFFSET_MICROFRAME_SIZE) |
586 FIELD_PREP(THC_M_PRT_DEVINT_CFG_2_THC_M_PRT_UFSIZE_LEN,
587 THC_BIT_LENGTH_MICROFRAME_SIZE) |
588 FIELD_PREP(THC_M_PRT_DEVINT_CFG_2_THC_M_PRT_UFSIZE_UNIT,
589 THC_UNIT_MICROFRAME_SIZE) |
590 THC_M_PRT_DEVINT_CFG_2_THC_M_PRT_FTYPE_IGNORE |
591 THC_M_PRT_DEVINT_CFG_2_THC_M_PRT_FTYPE_VAL;
592 mask = THC_M_PRT_DEVINT_CFG_2_THC_M_PRT_UFSIZE_OFFSET |
593 THC_M_PRT_DEVINT_CFG_2_THC_M_PRT_UFSIZE_LEN |
594 THC_M_PRT_DEVINT_CFG_2_THC_M_PRT_UFSIZE_UNIT |
595 THC_M_PRT_DEVINT_CFG_2_THC_M_PRT_FTYPE_IGNORE |
596 THC_M_PRT_DEVINT_CFG_2_THC_M_PRT_FTYPE_VAL;
597 regmap_write_bits(dev->thc_regmap, THC_M_PRT_DEVINT_CFG_2_OFFSET,
598 mask, mbits);
599 }
600 }
601 EXPORT_SYMBOL_NS_GPL(thc_interrupt_config, "INTEL_THC");
602
603 /**
604 * thc_int_trigger_type_select - Select THC interrupt trigger type
605 *
606 * @dev: the pointer of THC private device context
607 * @edge_trigger: determine the interrupt is edge triggered or level triggered
608 */
thc_int_trigger_type_select(struct thc_device * dev,bool edge_trigger)609 void thc_int_trigger_type_select(struct thc_device *dev, bool edge_trigger)
610 {
611 regmap_write_bits(dev->thc_regmap, THC_M_PRT_TSEQ_CNTRL_1_OFFSET,
612 THC_M_PRT_TSEQ_CNTRL_1_INT_EDG_DET_EN,
613 edge_trigger ? THC_M_PRT_TSEQ_CNTRL_1_INT_EDG_DET_EN : 0);
614 }
615 EXPORT_SYMBOL_NS_GPL(thc_int_trigger_type_select, "INTEL_THC");
616
617 /**
618 * thc_interrupt_enable - Enable or disable THC interrupt
619 *
620 * @dev: the pointer of THC private device context
621 * @int_enable: the flag to control THC interrupt enable or disable
622 */
thc_interrupt_enable(struct thc_device * dev,bool int_enable)623 void thc_interrupt_enable(struct thc_device *dev, bool int_enable)
624 {
625 regmap_write_bits(dev->thc_regmap, THC_M_PRT_INT_EN_OFFSET,
626 THC_M_PRT_INT_EN_GBL_INT_EN,
627 int_enable ? THC_M_PRT_INT_EN_GBL_INT_EN : 0);
628 }
629 EXPORT_SYMBOL_NS_GPL(thc_interrupt_enable, "INTEL_THC");
630
631 /**
632 * thc_interrupt_quiesce - Quiesce or unquiesce external touch device interrupt
633 *
634 * @dev: the pointer of THC private device context
635 * @int_quiesce: the flag to determine quiesce or unquiesce device interrupt
636 *
637 * Return: 0 on success, other error codes on failed
638 */
thc_interrupt_quiesce(const struct thc_device * dev,bool int_quiesce)639 int thc_interrupt_quiesce(const struct thc_device *dev, bool int_quiesce)
640 {
641 u32 ctrl;
642 int ret;
643
644 regmap_read(dev->thc_regmap, THC_M_PRT_CONTROL_OFFSET, &ctrl);
645 if (!(ctrl & THC_M_PRT_CONTROL_THC_DEVINT_QUIESCE_EN) && !int_quiesce) {
646 dev_warn(dev->dev, "THC interrupt already unquiesce\n");
647 return 0;
648 }
649
650 if ((ctrl & THC_M_PRT_CONTROL_THC_DEVINT_QUIESCE_EN) && int_quiesce) {
651 dev_warn(dev->dev, "THC interrupt already quiesce\n");
652 return 0;
653 }
654
655 /* Quiesce device interrupt - Set quiesce bit and waiting for THC HW to ACK */
656 if (int_quiesce)
657 regmap_write_bits(dev->thc_regmap, THC_M_PRT_CONTROL_OFFSET,
658 THC_M_PRT_CONTROL_THC_DEVINT_QUIESCE_EN,
659 THC_M_PRT_CONTROL_THC_DEVINT_QUIESCE_EN);
660
661 ret = regmap_read_poll_timeout(dev->thc_regmap, THC_M_PRT_CONTROL_OFFSET, ctrl,
662 ctrl & THC_M_PRT_CONTROL_THC_DEVINT_QUIESCE_HW_STS,
663 THC_REGMAP_POLLING_INTERVAL_US, THC_QUIESCE_EN_TIMEOUT_US);
664 if (ret) {
665 dev_err_once(dev->dev,
666 "Timeout while waiting THC idle, target quiesce state = %s\n",
667 int_quiesce ? "true" : "false");
668 return ret;
669 }
670
671 /* Unquiesce device interrupt - Clear the quiesce bit */
672 if (!int_quiesce)
673 regmap_write_bits(dev->thc_regmap, THC_M_PRT_CONTROL_OFFSET,
674 THC_M_PRT_CONTROL_THC_DEVINT_QUIESCE_EN, 0);
675
676 return 0;
677 }
678 EXPORT_SYMBOL_NS_GPL(thc_interrupt_quiesce, "INTEL_THC");
679
680 /**
681 * thc_set_pio_interrupt_support - Determine PIO interrupt is supported or not
682 *
683 * @dev: The pointer of THC private device context
684 * @supported: The flag to determine enabling PIO interrupt or not
685 */
thc_set_pio_interrupt_support(struct thc_device * dev,bool supported)686 void thc_set_pio_interrupt_support(struct thc_device *dev, bool supported)
687 {
688 dev->pio_int_supported = supported;
689 }
690 EXPORT_SYMBOL_NS_GPL(thc_set_pio_interrupt_support, "INTEL_THC");
691
692 /**
693 * thc_ltr_config - Configure THC Latency Tolerance Reporting(LTR) settings
694 *
695 * @dev: The pointer of THC private device context
696 * @active_ltr_us: active LTR value, unit is us
697 * @lp_ltr_us: low power LTR value, unit is us
698 */
thc_ltr_config(struct thc_device * dev,u32 active_ltr_us,u32 lp_ltr_us)699 void thc_ltr_config(struct thc_device *dev, u32 active_ltr_us, u32 lp_ltr_us)
700 {
701 u32 active_ltr_scale, lp_ltr_scale, ltr_ctrl, ltr_mask, orig, tmp;
702
703 if (active_ltr_us >= THC_LTR_MIN_VAL_SCALE_3 &&
704 active_ltr_us < THC_LTR_MAX_VAL_SCALE_3) {
705 active_ltr_scale = THC_LTR_SCALE_3;
706 active_ltr_us = active_ltr_us >> 5;
707 } else if (active_ltr_us >= THC_LTR_MIN_VAL_SCALE_4 &&
708 active_ltr_us < THC_LTR_MAX_VAL_SCALE_4) {
709 active_ltr_scale = THC_LTR_SCALE_4;
710 active_ltr_us = active_ltr_us >> 10;
711 } else if (active_ltr_us >= THC_LTR_MIN_VAL_SCALE_5 &&
712 active_ltr_us < THC_LTR_MAX_VAL_SCALE_5) {
713 active_ltr_scale = THC_LTR_SCALE_5;
714 active_ltr_us = active_ltr_us >> 15;
715 } else {
716 active_ltr_scale = THC_LTR_SCALE_2;
717 }
718
719 if (lp_ltr_us >= THC_LTR_MIN_VAL_SCALE_3 &&
720 lp_ltr_us < THC_LTR_MAX_VAL_SCALE_3) {
721 lp_ltr_scale = THC_LTR_SCALE_3;
722 lp_ltr_us = lp_ltr_us >> 5;
723 } else if (lp_ltr_us >= THC_LTR_MIN_VAL_SCALE_4 &&
724 lp_ltr_us < THC_LTR_MAX_VAL_SCALE_4) {
725 lp_ltr_scale = THC_LTR_SCALE_4;
726 lp_ltr_us = lp_ltr_us >> 10;
727 } else if (lp_ltr_us >= THC_LTR_MIN_VAL_SCALE_5 &&
728 lp_ltr_us < THC_LTR_MAX_VAL_SCALE_5) {
729 lp_ltr_scale = THC_LTR_SCALE_5;
730 lp_ltr_us = lp_ltr_us >> 15;
731 } else {
732 lp_ltr_scale = THC_LTR_SCALE_2;
733 }
734
735 regmap_read(dev->thc_regmap, THC_M_CMN_LTR_CTRL_OFFSET, &orig);
736 ltr_ctrl = FIELD_PREP(THC_M_CMN_LTR_CTRL_ACT_LTR_VAL, active_ltr_us) |
737 FIELD_PREP(THC_M_CMN_LTR_CTRL_ACT_LTR_SCALE, active_ltr_scale) |
738 THC_M_CMN_LTR_CTRL_ACTIVE_LTR_REQ |
739 THC_M_CMN_LTR_CTRL_ACTIVE_LTR_EN |
740 FIELD_PREP(THC_M_CMN_LTR_CTRL_LP_LTR_VAL, lp_ltr_us) |
741 FIELD_PREP(THC_M_CMN_LTR_CTRL_LP_LTR_SCALE, lp_ltr_scale) |
742 THC_M_CMN_LTR_CTRL_LP_LTR_REQ;
743
744 ltr_mask = THC_M_CMN_LTR_CTRL_ACT_LTR_VAL |
745 THC_M_CMN_LTR_CTRL_ACT_LTR_SCALE |
746 THC_M_CMN_LTR_CTRL_ACTIVE_LTR_REQ |
747 THC_M_CMN_LTR_CTRL_ACTIVE_LTR_EN |
748 THC_M_CMN_LTR_CTRL_LP_LTR_VAL |
749 THC_M_CMN_LTR_CTRL_LP_LTR_SCALE |
750 THC_M_CMN_LTR_CTRL_LP_LTR_REQ |
751 THC_M_CMN_LTR_CTRL_LP_LTR_EN;
752
753 tmp = orig & ~ltr_mask;
754 tmp |= ltr_ctrl & ltr_mask;
755
756 regmap_write(dev->thc_regmap, THC_M_CMN_LTR_CTRL_OFFSET, tmp);
757 }
758 EXPORT_SYMBOL_NS_GPL(thc_ltr_config, "INTEL_THC");
759
760 /**
761 * thc_change_ltr_mode - Change THC LTR mode
762 *
763 * @dev: The pointer of THC private device context
764 * @ltr_mode: LTR mode(active or low power)
765 */
thc_change_ltr_mode(struct thc_device * dev,u32 ltr_mode)766 void thc_change_ltr_mode(struct thc_device *dev, u32 ltr_mode)
767 {
768 if (ltr_mode == THC_LTR_MODE_ACTIVE) {
769 regmap_write_bits(dev->thc_regmap, THC_M_CMN_LTR_CTRL_OFFSET,
770 THC_M_CMN_LTR_CTRL_LP_LTR_EN, 0);
771 regmap_write_bits(dev->thc_regmap, THC_M_CMN_LTR_CTRL_OFFSET,
772 THC_M_CMN_LTR_CTRL_ACTIVE_LTR_EN,
773 THC_M_CMN_LTR_CTRL_ACTIVE_LTR_EN);
774 return;
775 }
776
777 regmap_write_bits(dev->thc_regmap, THC_M_CMN_LTR_CTRL_OFFSET,
778 THC_M_CMN_LTR_CTRL_ACTIVE_LTR_EN, 0);
779 regmap_write_bits(dev->thc_regmap, THC_M_CMN_LTR_CTRL_OFFSET,
780 THC_M_CMN_LTR_CTRL_LP_LTR_EN,
781 THC_M_CMN_LTR_CTRL_LP_LTR_EN);
782 }
783 EXPORT_SYMBOL_NS_GPL(thc_change_ltr_mode, "INTEL_THC");
784
785 /**
786 * thc_ltr_unconfig - Unconfigure THC Latency Tolerance Reporting(LTR) settings
787 *
788 * @dev: The pointer of THC private device context
789 */
thc_ltr_unconfig(struct thc_device * dev)790 void thc_ltr_unconfig(struct thc_device *dev)
791 {
792 u32 ltr_ctrl, bits_clear;
793
794 regmap_read(dev->thc_regmap, THC_M_CMN_LTR_CTRL_OFFSET, <r_ctrl);
795 bits_clear = THC_M_CMN_LTR_CTRL_LP_LTR_EN |
796 THC_M_CMN_LTR_CTRL_ACTIVE_LTR_EN |
797 THC_M_CMN_LTR_CTRL_LP_LTR_REQ |
798 THC_M_CMN_LTR_CTRL_ACTIVE_LTR_REQ;
799
800 ltr_ctrl &= ~bits_clear;
801
802 regmap_write(dev->thc_regmap, THC_M_CMN_LTR_CTRL_OFFSET, ltr_ctrl);
803 }
804 EXPORT_SYMBOL_NS_GPL(thc_ltr_unconfig, "INTEL_THC");
805
806 /**
807 * thc_int_cause_read - Read interrupt cause register value
808 *
809 * @dev: The pointer of THC private device context
810 *
811 * Return: The interrupt cause register value
812 */
thc_int_cause_read(struct thc_device * dev)813 u32 thc_int_cause_read(struct thc_device *dev)
814 {
815 u32 int_cause;
816
817 regmap_read(dev->thc_regmap,
818 THC_M_PRT_DEV_INT_CAUSE_REG_VAL_OFFSET, &int_cause);
819
820 return int_cause;
821 }
822 EXPORT_SYMBOL_NS_GPL(thc_int_cause_read, "INTEL_THC");
823
thc_print_txn_error_cause(const struct thc_device * dev)824 static void thc_print_txn_error_cause(const struct thc_device *dev)
825 {
826 bool known_error = false;
827 u32 cause = 0;
828
829 regmap_read(dev->thc_regmap, THC_M_PRT_ERR_CAUSE_OFFSET, &cause);
830
831 if (cause & THC_M_PRT_ERR_CAUSE_PRD_ENTRY_ERR) {
832 dev_err(dev->dev, "TXN Error: Invalid PRD Entry\n");
833 known_error = true;
834 }
835 if (cause & THC_M_PRT_ERR_CAUSE_BUF_OVRRUN_ERR) {
836 dev_err(dev->dev, "TXN Error: THC Buffer Overrun\n");
837 known_error = true;
838 }
839 if (cause & THC_M_PRT_ERR_CAUSE_FRAME_BABBLE_ERR) {
840 dev_err(dev->dev, "TXN Error: Frame Babble\n");
841 known_error = true;
842 }
843 if (cause & THC_M_PRT_ERR_CAUSE_INVLD_DEV_ENTRY) {
844 dev_err(dev->dev, "TXN Error: Invalid Device Register Setting\n");
845 known_error = true;
846 }
847
848 /* Clear interrupt status bits */
849 regmap_write(dev->thc_regmap, THC_M_PRT_ERR_CAUSE_OFFSET, cause);
850
851 if (!known_error)
852 dev_err(dev->dev, "TXN Error does not match any known value: 0x%X\n",
853 cause);
854 }
855
856 /**
857 * thc_interrupt_handler - Handle THC interrupts
858 *
859 * THC interrupts include several types: external touch device (TIC) non-DMA
860 * interrupts, PIO completion interrupts, DMA interrtups, I2C subIP raw
861 * interrupts and error interrupts.
862 *
863 * This is a help function for interrupt processing, it detects interrupt
864 * type, clear the interrupt status bit and return the interrupt type to caller
865 * for future processing.
866 *
867 * @dev: The pointer of THC private device context
868 *
869 * Return: The combined flag for interrupt type
870 */
thc_interrupt_handler(struct thc_device * dev)871 int thc_interrupt_handler(struct thc_device *dev)
872 {
873 u32 read_sts_1, read_sts_2, read_sts_sw, write_sts;
874 u32 int_sts, err_cause, seq_cntrl, seq_sts;
875 int interrupt_type = 0;
876
877 regmap_read(dev->thc_regmap,
878 THC_M_PRT_READ_DMA_INT_STS_1_OFFSET, &read_sts_1);
879
880 if (read_sts_1 & THC_M_PRT_READ_DMA_INT_STS_NONDMA_INT_STS) {
881 dev_dbg(dev->dev, "THC non-DMA device interrupt\n");
882
883 regmap_write(dev->thc_regmap, THC_M_PRT_READ_DMA_INT_STS_1_OFFSET,
884 NONDMA_INT_STS_BIT);
885
886 interrupt_type |= BIT(THC_NONDMA_INT);
887
888 return interrupt_type;
889 }
890
891 regmap_read(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET, &int_sts);
892
893 if (int_sts & THC_M_PRT_INT_STATUS_TXN_ERR_INT_STS) {
894 dev_err(dev->dev, "THC transaction error, int_sts: 0x%08X\n", int_sts);
895 thc_print_txn_error_cause(dev);
896
897 regmap_write(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
898 TXN_ERR_INT_STS_BIT);
899
900 interrupt_type |= BIT(THC_TXN_ERR_INT);
901
902 return interrupt_type;
903 }
904
905 regmap_read(dev->thc_regmap, THC_M_PRT_ERR_CAUSE_OFFSET, &err_cause);
906 regmap_read(dev->thc_regmap,
907 THC_M_PRT_READ_DMA_INT_STS_2_OFFSET, &read_sts_2);
908
909 if (err_cause & THC_M_PRT_ERR_CAUSE_BUF_OVRRUN_ERR ||
910 read_sts_1 & THC_M_PRT_READ_DMA_INT_STS_STALL_STS ||
911 read_sts_2 & THC_M_PRT_READ_DMA_INT_STS_STALL_STS) {
912 dev_err(dev->dev, "Buffer overrun or RxDMA engine stalled!\n");
913 thc_print_txn_error_cause(dev);
914
915 regmap_write(dev->thc_regmap, THC_M_PRT_READ_DMA_INT_STS_2_OFFSET,
916 THC_M_PRT_READ_DMA_INT_STS_STALL_STS);
917 regmap_write(dev->thc_regmap, THC_M_PRT_READ_DMA_INT_STS_1_OFFSET,
918 THC_M_PRT_READ_DMA_INT_STS_STALL_STS);
919 regmap_write(dev->thc_regmap, THC_M_PRT_ERR_CAUSE_OFFSET,
920 THC_M_PRT_ERR_CAUSE_BUF_OVRRUN_ERR);
921
922 interrupt_type |= BIT(THC_TXN_ERR_INT);
923
924 return interrupt_type;
925 }
926
927 if (int_sts & THC_M_PRT_INT_STATUS_FATAL_ERR_INT_STS) {
928 dev_err_once(dev->dev, "THC FATAL error, int_sts: 0x%08X\n", int_sts);
929
930 regmap_write(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
931 TXN_FATAL_INT_STS_BIT);
932
933 interrupt_type |= BIT(THC_FATAL_ERR_INT);
934
935 return interrupt_type;
936 }
937
938 regmap_read(dev->thc_regmap,
939 THC_M_PRT_SW_SEQ_CNTRL_OFFSET, &seq_cntrl);
940 regmap_read(dev->thc_regmap,
941 THC_M_PRT_SW_SEQ_STS_OFFSET, &seq_sts);
942
943 if (seq_cntrl & THC_M_PRT_SW_SEQ_CNTRL_THC_SS_CD_IE &&
944 seq_sts & THC_M_PRT_SW_SEQ_STS_TSSDONE) {
945 dev_dbg(dev->dev, "THC_SS_CD_IE and TSSDONE are set\n");
946 interrupt_type |= BIT(THC_PIO_DONE_INT);
947 }
948
949 if (read_sts_1 & THC_M_PRT_READ_DMA_INT_STS_EOF_INT_STS) {
950 dev_dbg(dev->dev, "Got RxDMA1 Read Interrupt\n");
951
952 regmap_write(dev->thc_regmap,
953 THC_M_PRT_READ_DMA_INT_STS_1_OFFSET, read_sts_1);
954
955 interrupt_type |= BIT(THC_RXDMA1_INT);
956 }
957
958 if (read_sts_2 & THC_M_PRT_READ_DMA_INT_STS_EOF_INT_STS) {
959 dev_dbg(dev->dev, "Got RxDMA2 Read Interrupt\n");
960
961 regmap_write(dev->thc_regmap,
962 THC_M_PRT_READ_DMA_INT_STS_2_OFFSET, read_sts_2);
963
964 interrupt_type |= BIT(THC_RXDMA2_INT);
965 }
966
967 regmap_read(dev->thc_regmap,
968 THC_M_PRT_READ_DMA_INT_STS_SW_OFFSET, &read_sts_sw);
969
970 if (read_sts_sw & THC_M_PRT_READ_DMA_INT_STS_DMACPL_STS) {
971 dev_dbg(dev->dev, "Got SwDMA Read Interrupt\n");
972
973 regmap_write(dev->thc_regmap,
974 THC_M_PRT_READ_DMA_INT_STS_SW_OFFSET, read_sts_sw);
975
976 dev->swdma_done = true;
977 wake_up_interruptible(&dev->swdma_complete_wait);
978
979 interrupt_type |= BIT(THC_SWDMA_INT);
980 }
981
982 regmap_read(dev->thc_regmap,
983 THC_M_PRT_WRITE_INT_STS_OFFSET, &write_sts);
984
985 if (write_sts & THC_M_PRT_WRITE_INT_STS_THC_WRDMA_CMPL_STATUS) {
986 dev_dbg(dev->dev, "Got TxDMA Write complete Interrupt\n");
987
988 regmap_write(dev->thc_regmap,
989 THC_M_PRT_WRITE_INT_STS_OFFSET, write_sts);
990
991 dev->write_done = true;
992 wake_up_interruptible(&dev->write_complete_wait);
993
994 interrupt_type |= BIT(THC_TXDMA_INT);
995 }
996
997 if (int_sts & THC_M_PRT_INT_STATUS_DEV_RAW_INT_STS) {
998 regmap_write(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
999 THC_M_PRT_INT_STATUS_DEV_RAW_INT_STS);
1000 interrupt_type |= BIT(THC_I2CSUBIP_INT);
1001 }
1002 if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_RX_UNDER_INT_STS) {
1003 regmap_write(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
1004 THC_M_PRT_INT_STATUS_THC_I2C_IC_RX_UNDER_INT_STS);
1005 interrupt_type |= BIT(THC_I2CSUBIP_INT);
1006 }
1007 if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_RX_OVER_INT_STS) {
1008 regmap_write(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
1009 THC_M_PRT_INT_STATUS_THC_I2C_IC_RX_OVER_INT_STS);
1010 interrupt_type |= BIT(THC_I2CSUBIP_INT);
1011 }
1012 if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_RX_FULL_INT_STS) {
1013 regmap_write(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
1014 THC_M_PRT_INT_STATUS_THC_I2C_IC_RX_FULL_INT_STS);
1015 interrupt_type |= BIT(THC_I2CSUBIP_INT);
1016 }
1017 if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_TX_OVER_INT_STS) {
1018 regmap_write(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
1019 THC_M_PRT_INT_STATUS_THC_I2C_IC_TX_OVER_INT_STS);
1020 interrupt_type |= BIT(THC_I2CSUBIP_INT);
1021 }
1022 if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_TX_EMPTY_INT_STS) {
1023 regmap_write(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
1024 THC_M_PRT_INT_STATUS_THC_I2C_IC_TX_EMPTY_INT_STS);
1025 interrupt_type |= BIT(THC_I2CSUBIP_INT);
1026 }
1027 if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_TX_ABRT_INT_STS) {
1028 regmap_write(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
1029 THC_M_PRT_INT_STATUS_THC_I2C_IC_TX_ABRT_INT_STS);
1030 interrupt_type |= BIT(THC_I2CSUBIP_INT);
1031 }
1032 if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_ACTIVITY_INT_STS) {
1033 regmap_write(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
1034 THC_M_PRT_INT_STATUS_THC_I2C_IC_ACTIVITY_INT_STS);
1035 interrupt_type |= BIT(THC_I2CSUBIP_INT);
1036 }
1037 if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_SCL_STUCK_AT_LOW_INT_STS) {
1038 regmap_write(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
1039 THC_M_PRT_INT_STATUS_THC_I2C_IC_SCL_STUCK_AT_LOW_INT_STS);
1040 interrupt_type |= BIT(THC_I2CSUBIP_INT);
1041 }
1042 if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_STOP_DET_INT_STS) {
1043 regmap_write(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
1044 THC_M_PRT_INT_STATUS_THC_I2C_IC_STOP_DET_INT_STS);
1045 interrupt_type |= BIT(THC_I2CSUBIP_INT);
1046 }
1047 if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_START_DET_INT_STS) {
1048 regmap_write(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
1049 THC_M_PRT_INT_STATUS_THC_I2C_IC_START_DET_INT_STS);
1050 interrupt_type |= BIT(THC_I2CSUBIP_INT);
1051 }
1052 if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_MST_ON_HOLD_INT_STS) {
1053 regmap_write(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
1054 THC_M_PRT_INT_STATUS_THC_I2C_IC_MST_ON_HOLD_INT_STS);
1055 interrupt_type |= BIT(THC_I2CSUBIP_INT);
1056 }
1057
1058 if (!interrupt_type)
1059 interrupt_type |= BIT(THC_UNKNOWN_INT);
1060
1061 return interrupt_type;
1062 }
1063 EXPORT_SYMBOL_NS_GPL(thc_interrupt_handler, "INTEL_THC");
1064
1065 /**
1066 * thc_port_select - Set THC port type
1067 *
1068 * @dev: The pointer of THC private device context
1069 * @port_type: THC port type to use for current device
1070 *
1071 * Return: 0 on success, other error codes on failed.
1072 */
thc_port_select(struct thc_device * dev,enum thc_port_type port_type)1073 int thc_port_select(struct thc_device *dev, enum thc_port_type port_type)
1074 {
1075 u32 ctrl, mask;
1076
1077 if (port_type == THC_PORT_TYPE_SPI) {
1078 dev_dbg(dev->dev, "Set THC port type to SPI\n");
1079 dev->port_type = THC_PORT_TYPE_SPI;
1080
1081 /* Enable delay of CS assertion and set to default value */
1082 ctrl = THC_M_PRT_SPI_DUTYC_CFG_SPI_CSA_CK_DELAY_EN |
1083 FIELD_PREP(THC_M_PRT_SPI_DUTYC_CFG_SPI_CSA_CK_DELAY_VAL,
1084 THC_CSA_CK_DELAY_VAL_DEFAULT);
1085 mask = THC_M_PRT_SPI_DUTYC_CFG_SPI_CSA_CK_DELAY_EN |
1086 THC_M_PRT_SPI_DUTYC_CFG_SPI_CSA_CK_DELAY_VAL;
1087 regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_DUTYC_CFG_OFFSET,
1088 mask, ctrl);
1089 } else if (port_type == THC_PORT_TYPE_I2C) {
1090 dev_dbg(dev->dev, "Set THC port type to I2C\n");
1091 dev->port_type = THC_PORT_TYPE_I2C;
1092
1093 /* Set THC transition arbitration policy to frame boundary for I2C */
1094 ctrl = FIELD_PREP(THC_M_PRT_CONTROL_THC_ARB_POLICY,
1095 THC_ARB_POLICY_FRAME_BOUNDARY);
1096 mask = THC_M_PRT_CONTROL_THC_ARB_POLICY;
1097
1098 regmap_write_bits(dev->thc_regmap, THC_M_PRT_CONTROL_OFFSET, mask, ctrl);
1099 } else {
1100 dev_err(dev->dev, "unsupported THC port type: %d\n", port_type);
1101 return -EINVAL;
1102 }
1103
1104 ctrl = FIELD_PREP(THC_M_PRT_CONTROL_PORT_TYPE, port_type);
1105 mask = THC_M_PRT_CONTROL_PORT_TYPE;
1106
1107 regmap_write_bits(dev->thc_regmap, THC_M_PRT_CONTROL_OFFSET, mask, ctrl);
1108
1109 return 0;
1110 }
1111 EXPORT_SYMBOL_NS_GPL(thc_port_select, "INTEL_THC");
1112
1113 #define THC_SPI_FREQUENCY_7M 7812500
1114 #define THC_SPI_FREQUENCY_15M 15625000
1115 #define THC_SPI_FREQUENCY_17M 17857100
1116 #define THC_SPI_FREQUENCY_20M 20833000
1117 #define THC_SPI_FREQUENCY_25M 25000000
1118 #define THC_SPI_FREQUENCY_31M 31250000
1119 #define THC_SPI_FREQUENCY_41M 41666700
1120
1121 #define THC_SPI_LOW_FREQUENCY THC_SPI_FREQUENCY_17M
1122
thc_get_spi_freq_div_val(struct thc_device * dev,u32 spi_freq_val)1123 static u8 thc_get_spi_freq_div_val(struct thc_device *dev, u32 spi_freq_val)
1124 {
1125 static const int frequency[] = {
1126 THC_SPI_FREQUENCY_7M,
1127 THC_SPI_FREQUENCY_15M,
1128 THC_SPI_FREQUENCY_17M,
1129 THC_SPI_FREQUENCY_20M,
1130 THC_SPI_FREQUENCY_25M,
1131 THC_SPI_FREQUENCY_31M,
1132 THC_SPI_FREQUENCY_41M,
1133 };
1134 static const u8 frequency_div[] = {
1135 THC_SPI_FRQ_DIV_2,
1136 THC_SPI_FRQ_DIV_1,
1137 THC_SPI_FRQ_DIV_7,
1138 THC_SPI_FRQ_DIV_6,
1139 THC_SPI_FRQ_DIV_5,
1140 THC_SPI_FRQ_DIV_4,
1141 THC_SPI_FRQ_DIV_3,
1142 };
1143 int size = ARRAY_SIZE(frequency);
1144 u32 closest_freq;
1145 u8 freq_div;
1146 int i;
1147
1148 for (i = size - 1; i >= 0; i--)
1149 if ((int)spi_freq_val - frequency[i] >= 0)
1150 break;
1151
1152 if (i < 0) {
1153 dev_err_once(dev->dev, "Not supported SPI frequency %d\n", spi_freq_val);
1154 return THC_SPI_FRQ_RESERVED;
1155 }
1156
1157 closest_freq = frequency[i];
1158 freq_div = frequency_div[i];
1159
1160 dev_dbg(dev->dev,
1161 "Setting SPI frequency: spi_freq_val = %u, Closest freq = %u\n",
1162 spi_freq_val, closest_freq);
1163
1164 return freq_div;
1165 }
1166
1167 /**
1168 * thc_spi_read_config - Configure SPI bus read attributes
1169 *
1170 * @dev: The pointer of THC private device context
1171 * @spi_freq_val: SPI read frequecy value
1172 * @io_mode: SPI read IO mode
1173 * @opcode: Read opcode
1174 * @spi_rd_mps: SPI read max packet size
1175 *
1176 * Return: 0 on success, other error codes on failed.
1177 */
thc_spi_read_config(struct thc_device * dev,u32 spi_freq_val,u32 io_mode,u32 opcode,u32 spi_rd_mps)1178 int thc_spi_read_config(struct thc_device *dev, u32 spi_freq_val,
1179 u32 io_mode, u32 opcode, u32 spi_rd_mps)
1180 {
1181 bool is_low_freq = false;
1182 u32 cfg, mask;
1183 u8 freq_div;
1184
1185 freq_div = thc_get_spi_freq_div_val(dev, spi_freq_val);
1186 if (freq_div == THC_SPI_FRQ_RESERVED)
1187 return -EINVAL;
1188
1189 if (spi_freq_val < THC_SPI_LOW_FREQUENCY)
1190 is_low_freq = true;
1191
1192 cfg = FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TCRF, freq_div) |
1193 FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TRMODE, io_mode) |
1194 (is_low_freq ? THC_M_PRT_SPI_CFG_SPI_LOW_FREQ_EN : 0) |
1195 FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_RD_MPS, spi_rd_mps);
1196 mask = THC_M_PRT_SPI_CFG_SPI_TCRF |
1197 THC_M_PRT_SPI_CFG_SPI_TRMODE |
1198 THC_M_PRT_SPI_CFG_SPI_LOW_FREQ_EN |
1199 THC_M_PRT_SPI_CFG_SPI_RD_MPS;
1200
1201 regmap_write_bits(dev->thc_regmap,
1202 THC_M_PRT_SPI_CFG_OFFSET, mask, cfg);
1203
1204 if (io_mode == THC_QUAD_IO)
1205 opcode = FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_SPI_QIO, opcode);
1206 else if (io_mode == THC_DUAL_IO)
1207 opcode = FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_SPI_DIO, opcode);
1208 else
1209 opcode = FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_SPI_SIO, opcode);
1210
1211 regmap_write(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, opcode);
1212 regmap_write(dev->thc_regmap, THC_M_PRT_SPI_DMARD_OPCODE_OFFSET, opcode);
1213
1214 return 0;
1215 }
1216 EXPORT_SYMBOL_NS_GPL(thc_spi_read_config, "INTEL_THC");
1217
1218 /**
1219 * thc_spi_write_config - Configure SPI bus write attributes
1220 *
1221 * @dev: The pointer of THC private device context
1222 * @spi_freq_val: SPI write frequecy value
1223 * @io_mode: SPI write IO mode
1224 * @opcode: Write opcode
1225 * @spi_wr_mps: SPI write max packet size
1226 * @perf_limit: Performance limitation in unit of 10us
1227 *
1228 * Return: 0 on success, other error codes on failed.
1229 */
thc_spi_write_config(struct thc_device * dev,u32 spi_freq_val,u32 io_mode,u32 opcode,u32 spi_wr_mps,u32 perf_limit)1230 int thc_spi_write_config(struct thc_device *dev, u32 spi_freq_val,
1231 u32 io_mode, u32 opcode, u32 spi_wr_mps,
1232 u32 perf_limit)
1233 {
1234 bool is_low_freq = false;
1235 u32 cfg, mask;
1236 u8 freq_div;
1237
1238 freq_div = thc_get_spi_freq_div_val(dev, spi_freq_val);
1239 if (freq_div == THC_SPI_FRQ_RESERVED)
1240 return -EINVAL;
1241
1242 if (spi_freq_val < THC_SPI_LOW_FREQUENCY)
1243 is_low_freq = true;
1244
1245 cfg = FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TCWF, freq_div) |
1246 FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TWMODE, io_mode) |
1247 (is_low_freq ? THC_M_PRT_SPI_CFG_SPI_LOW_FREQ_EN : 0) |
1248 FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_WR_MPS, spi_wr_mps);
1249 mask = THC_M_PRT_SPI_CFG_SPI_TCWF |
1250 THC_M_PRT_SPI_CFG_SPI_TWMODE |
1251 THC_M_PRT_SPI_CFG_SPI_LOW_FREQ_EN |
1252 THC_M_PRT_SPI_CFG_SPI_WR_MPS;
1253
1254 regmap_write_bits(dev->thc_regmap,
1255 THC_M_PRT_SPI_CFG_OFFSET, mask, cfg);
1256
1257 if (io_mode == THC_QUAD_IO)
1258 opcode = FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_SPI_QIO, opcode);
1259 else if (io_mode == THC_DUAL_IO)
1260 opcode = FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_SPI_DIO, opcode);
1261 else
1262 opcode = FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_SPI_SIO, opcode);
1263
1264 regmap_write(dev->thc_regmap, THC_M_PRT_SPI_WR_OPCODE_OFFSET, opcode);
1265
1266 dev->perf_limit = perf_limit;
1267
1268 return 0;
1269 }
1270 EXPORT_SYMBOL_NS_GPL(thc_spi_write_config, "INTEL_THC");
1271
1272 /**
1273 * thc_spi_input_output_address_config - Configure SPI input and output addresses
1274 *
1275 * @dev: the pointer of THC private device context
1276 * @input_hdr_addr: input report header address
1277 * @input_bdy_addr: input report body address
1278 * @output_addr: output report address
1279 */
thc_spi_input_output_address_config(struct thc_device * dev,u32 input_hdr_addr,u32 input_bdy_addr,u32 output_addr)1280 void thc_spi_input_output_address_config(struct thc_device *dev, u32 input_hdr_addr,
1281 u32 input_bdy_addr, u32 output_addr)
1282 {
1283 regmap_write(dev->thc_regmap,
1284 THC_M_PRT_DEV_INT_CAUSE_ADDR_OFFSET, input_hdr_addr);
1285 regmap_write(dev->thc_regmap,
1286 THC_M_PRT_RD_BULK_ADDR_1_OFFSET, input_bdy_addr);
1287 regmap_write(dev->thc_regmap,
1288 THC_M_PRT_RD_BULK_ADDR_2_OFFSET, input_bdy_addr);
1289 regmap_write(dev->thc_regmap,
1290 THC_M_PRT_WR_BULK_ADDR_OFFSET, output_addr);
1291 }
1292 EXPORT_SYMBOL_NS_GPL(thc_spi_input_output_address_config, "INTEL_THC");
1293
thc_i2c_subip_pio_read(struct thc_device * dev,const u32 address,u32 * size,u32 * buffer)1294 static int thc_i2c_subip_pio_read(struct thc_device *dev, const u32 address,
1295 u32 *size, u32 *buffer)
1296 {
1297 int ret;
1298
1299 if (!size || *size == 0 || !buffer) {
1300 dev_err(dev->dev, "Invalid input parameters, size %p, buffer %p\n",
1301 size, buffer);
1302 return -EINVAL;
1303 }
1304
1305 if (mutex_lock_interruptible(&dev->thc_bus_lock))
1306 return -EINTR;
1307
1308 ret = prepare_pio(dev, THC_PIO_OP_I2C_SUBSYSTEM_READ, address, *size);
1309 if (ret < 0)
1310 goto end;
1311
1312 pio_start(dev, 0, NULL);
1313
1314 ret = pio_wait(dev);
1315 if (ret < 0)
1316 goto end;
1317
1318 ret = pio_complete(dev, buffer, size);
1319 if (ret < 0)
1320 goto end;
1321
1322 end:
1323 mutex_unlock(&dev->thc_bus_lock);
1324
1325 if (ret)
1326 dev_err_once(dev->dev, "Read THC I2C SubIP register failed %d, offset %u\n",
1327 ret, address);
1328
1329 return ret;
1330 }
1331
thc_i2c_subip_pio_write(struct thc_device * dev,const u32 address,const u32 size,const u32 * buffer)1332 static int thc_i2c_subip_pio_write(struct thc_device *dev, const u32 address,
1333 const u32 size, const u32 *buffer)
1334 {
1335 int ret;
1336
1337 if (size == 0 || !buffer) {
1338 dev_err(dev->dev, "Invalid input parameters, size %u, buffer %p\n",
1339 size, buffer);
1340 return -EINVAL;
1341 }
1342
1343 if (mutex_lock_interruptible(&dev->thc_bus_lock))
1344 return -EINTR;
1345
1346 ret = prepare_pio(dev, THC_PIO_OP_I2C_SUBSYSTEM_WRITE, address, size);
1347 if (ret < 0)
1348 goto end;
1349
1350 pio_start(dev, size, buffer);
1351
1352 ret = pio_wait(dev);
1353 if (ret < 0)
1354 goto end;
1355
1356 ret = pio_complete(dev, NULL, NULL);
1357 if (ret < 0)
1358 goto end;
1359
1360 end:
1361 mutex_unlock(&dev->thc_bus_lock);
1362
1363 if (ret)
1364 dev_err_once(dev->dev, "Write THC I2C SubIP register failed %d, offset %u\n",
1365 ret, address);
1366
1367 return ret;
1368 }
1369
1370 #define I2C_SUBIP_CON_DEFAULT 0x663
1371 #define I2C_SUBIP_INT_MASK_DEFAULT 0x7FFF
1372 #define I2C_SUBIP_RX_TL_DEFAULT 62
1373 #define I2C_SUBIP_TX_TL_DEFAULT 0
1374 #define I2C_SUBIP_DMA_TDLR_DEFAULT 7
1375 #define I2C_SUBIP_DMA_RDLR_DEFAULT 7
1376
thc_i2c_subip_set_speed(struct thc_device * dev,const u32 speed,const u32 hcnt,const u32 lcnt)1377 static int thc_i2c_subip_set_speed(struct thc_device *dev, const u32 speed,
1378 const u32 hcnt, const u32 lcnt)
1379 {
1380 u32 hcnt_offset, lcnt_offset;
1381 u32 val;
1382 int ret;
1383
1384 switch (speed) {
1385 case THC_I2C_STANDARD:
1386 hcnt_offset = THC_I2C_IC_SS_SCL_HCNT_OFFSET;
1387 lcnt_offset = THC_I2C_IC_SS_SCL_LCNT_OFFSET;
1388 break;
1389
1390 case THC_I2C_FAST_AND_PLUS:
1391 hcnt_offset = THC_I2C_IC_FS_SCL_HCNT_OFFSET;
1392 lcnt_offset = THC_I2C_IC_FS_SCL_LCNT_OFFSET;
1393 break;
1394
1395 case THC_I2C_HIGH_SPEED:
1396 hcnt_offset = THC_I2C_IC_HS_SCL_HCNT_OFFSET;
1397 lcnt_offset = THC_I2C_IC_HS_SCL_LCNT_OFFSET;
1398 break;
1399
1400 default:
1401 dev_err_once(dev->dev, "Unsupported i2c speed %d\n", speed);
1402 ret = -EINVAL;
1403 return ret;
1404 }
1405
1406 ret = thc_i2c_subip_pio_write(dev, hcnt_offset, sizeof(u32), &hcnt);
1407 if (ret < 0)
1408 return ret;
1409
1410 ret = thc_i2c_subip_pio_write(dev, lcnt_offset, sizeof(u32), &lcnt);
1411 if (ret < 0)
1412 return ret;
1413
1414 val = I2C_SUBIP_CON_DEFAULT & ~THC_I2C_IC_CON_SPEED;
1415 val |= FIELD_PREP(THC_I2C_IC_CON_SPEED, speed);
1416 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_CON_OFFSET, sizeof(u32), &val);
1417 if (ret < 0)
1418 return ret;
1419
1420 return 0;
1421 }
1422
1423 static u32 i2c_subip_regs[] = {
1424 THC_I2C_IC_CON_OFFSET,
1425 THC_I2C_IC_TAR_OFFSET,
1426 THC_I2C_IC_INTR_MASK_OFFSET,
1427 THC_I2C_IC_RX_TL_OFFSET,
1428 THC_I2C_IC_TX_TL_OFFSET,
1429 THC_I2C_IC_DMA_CR_OFFSET,
1430 THC_I2C_IC_DMA_TDLR_OFFSET,
1431 THC_I2C_IC_DMA_RDLR_OFFSET,
1432 THC_I2C_IC_SS_SCL_HCNT_OFFSET,
1433 THC_I2C_IC_SS_SCL_LCNT_OFFSET,
1434 THC_I2C_IC_FS_SCL_HCNT_OFFSET,
1435 THC_I2C_IC_FS_SCL_LCNT_OFFSET,
1436 THC_I2C_IC_HS_SCL_HCNT_OFFSET,
1437 THC_I2C_IC_HS_SCL_LCNT_OFFSET,
1438 THC_I2C_IC_ENABLE_OFFSET,
1439 };
1440
1441 /**
1442 * thc_i2c_subip_init - Initialize and configure THC I2C subsystem
1443 *
1444 * @dev: The pointer of THC private device context
1445 * @target_address: Slave address of touch device (TIC)
1446 * @speed: I2C bus frequency speed mode
1447 * @hcnt: I2C clock SCL high count
1448 * @lcnt: I2C clock SCL low count
1449 *
1450 * Return: 0 on success, other error codes on failed.
1451 */
thc_i2c_subip_init(struct thc_device * dev,const u32 target_address,const u32 speed,const u32 hcnt,const u32 lcnt)1452 int thc_i2c_subip_init(struct thc_device *dev, const u32 target_address,
1453 const u32 speed, const u32 hcnt, const u32 lcnt)
1454 {
1455 u32 read_size = sizeof(u32);
1456 u32 val;
1457 int ret;
1458
1459 ret = thc_i2c_subip_pio_read(dev, THC_I2C_IC_ENABLE_OFFSET, &read_size, &val);
1460 if (ret < 0)
1461 return ret;
1462
1463 val &= ~THC_I2C_IC_ENABLE_ENABLE;
1464 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_ENABLE_OFFSET, sizeof(u32), &val);
1465 if (ret < 0)
1466 return ret;
1467
1468 ret = thc_i2c_subip_pio_read(dev, THC_I2C_IC_TAR_OFFSET, &read_size, &val);
1469 if (ret < 0)
1470 return ret;
1471
1472 val &= ~THC_I2C_IC_TAR_IC_TAR;
1473 val |= FIELD_PREP(THC_I2C_IC_TAR_IC_TAR, target_address);
1474 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_TAR_OFFSET, sizeof(u32), &val);
1475 if (ret < 0)
1476 return ret;
1477
1478 ret = thc_i2c_subip_set_speed(dev, speed, hcnt, lcnt);
1479 if (ret < 0)
1480 return ret;
1481
1482 val = I2C_SUBIP_INT_MASK_DEFAULT;
1483 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_INTR_MASK_OFFSET, sizeof(u32), &val);
1484 if (ret < 0)
1485 return ret;
1486
1487 val = I2C_SUBIP_RX_TL_DEFAULT;
1488 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_RX_TL_OFFSET, sizeof(u32), &val);
1489 if (ret < 0)
1490 return ret;
1491
1492 val = I2C_SUBIP_TX_TL_DEFAULT;
1493 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_TX_TL_OFFSET, sizeof(u32), &val);
1494 if (ret < 0)
1495 return ret;
1496
1497 val = THC_I2C_IC_DMA_CR_RDMAE | THC_I2C_IC_DMA_CR_TDMAE;
1498 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_DMA_CR_OFFSET, sizeof(u32), &val);
1499 if (ret < 0)
1500 return ret;
1501
1502 val = I2C_SUBIP_DMA_TDLR_DEFAULT;
1503 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_DMA_TDLR_OFFSET, sizeof(u32), &val);
1504 if (ret < 0)
1505 return ret;
1506
1507 val = I2C_SUBIP_DMA_RDLR_DEFAULT;
1508 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_DMA_RDLR_OFFSET, sizeof(u32), &val);
1509 if (ret < 0)
1510 return ret;
1511
1512 ret = thc_i2c_subip_pio_read(dev, THC_I2C_IC_ENABLE_OFFSET, &read_size, &val);
1513 if (ret < 0)
1514 return ret;
1515
1516 val |= THC_I2C_IC_ENABLE_ENABLE;
1517 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_ENABLE_OFFSET, sizeof(u32), &val);
1518 if (ret < 0)
1519 return ret;
1520
1521 dev->i2c_subip_regs = devm_kzalloc(dev->dev, sizeof(i2c_subip_regs), GFP_KERNEL);
1522 if (!dev->i2c_subip_regs)
1523 return -ENOMEM;
1524
1525 return 0;
1526 }
1527 EXPORT_SYMBOL_NS_GPL(thc_i2c_subip_init, "INTEL_THC");
1528
1529 /**
1530 * thc_i2c_subip_regs_save - Save THC I2C sub-subsystem register values to THC device context
1531 *
1532 * @dev: The pointer of THC private device context
1533 *
1534 * Return: 0 on success, other error codes on failed.
1535 */
thc_i2c_subip_regs_save(struct thc_device * dev)1536 int thc_i2c_subip_regs_save(struct thc_device *dev)
1537 {
1538 int ret;
1539 u32 read_size = sizeof(u32);
1540
1541 for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) {
1542 ret = thc_i2c_subip_pio_read(dev, i2c_subip_regs[i],
1543 &read_size, (u32 *)&dev->i2c_subip_regs + i);
1544 if (ret < 0)
1545 return ret;
1546 }
1547
1548 return 0;
1549 }
1550 EXPORT_SYMBOL_NS_GPL(thc_i2c_subip_regs_save, "INTEL_THC");
1551
1552 /**
1553 * thc_i2c_subip_regs_restore - Restore THC I2C subsystem registers from THC device context
1554 *
1555 * @dev: The pointer of THC private device context
1556 *
1557 * Return: 0 on success, other error codes on failed.
1558 */
thc_i2c_subip_regs_restore(struct thc_device * dev)1559 int thc_i2c_subip_regs_restore(struct thc_device *dev)
1560 {
1561 int ret;
1562 u32 write_size = sizeof(u32);
1563
1564 for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) {
1565 ret = thc_i2c_subip_pio_write(dev, i2c_subip_regs[i],
1566 write_size, (u32 *)&dev->i2c_subip_regs + i);
1567 if (ret < 0)
1568 return ret;
1569 }
1570
1571 return 0;
1572 }
1573 EXPORT_SYMBOL_NS_GPL(thc_i2c_subip_regs_restore, "INTEL_THC");
1574
1575 /**
1576 * thc_i2c_set_rx_max_size - Set I2C Rx transfer max input size
1577 * @dev: The pointer of THC private device context
1578 * @max_rx_size: Max input report packet size for input report
1579 *
1580 * Set @max_rx_size for I2C RxDMA max input size control feature.
1581 *
1582 * Return: 0 on success, other error codes on failure.
1583 */
thc_i2c_set_rx_max_size(struct thc_device * dev,u32 max_rx_size)1584 int thc_i2c_set_rx_max_size(struct thc_device *dev, u32 max_rx_size)
1585 {
1586 u32 val;
1587 int ret;
1588
1589 if (!dev)
1590 return -EINVAL;
1591
1592 if (!max_rx_size)
1593 return -EOPNOTSUPP;
1594
1595 ret = regmap_read(dev->thc_regmap, THC_M_PRT_SW_SEQ_STS_OFFSET, &val);
1596 if (ret)
1597 return ret;
1598
1599 val |= FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_I2C_MAX_SIZE, max_rx_size);
1600
1601 ret = regmap_write(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, val);
1602 if (ret)
1603 return ret;
1604
1605 dev->i2c_max_rx_size = max_rx_size;
1606
1607 return 0;
1608 }
1609 EXPORT_SYMBOL_NS_GPL(thc_i2c_set_rx_max_size, "INTEL_THC");
1610
1611 /**
1612 * thc_i2c_rx_max_size_enable - Enable I2C Rx max input size control
1613 * @dev: The pointer of THC private device context
1614 * @enable: Enable max input size control or not
1615 *
1616 * Enable or disable I2C RxDMA max input size control feature.
1617 * Max input size control only can be enabled after max input size
1618 * was set by thc_i2c_set_rx_max_size().
1619 *
1620 * Return: 0 on success, other error codes on failure.
1621 */
thc_i2c_rx_max_size_enable(struct thc_device * dev,bool enable)1622 int thc_i2c_rx_max_size_enable(struct thc_device *dev, bool enable)
1623 {
1624 u32 mask = THC_M_PRT_SPI_ICRRD_OPCODE_I2C_MAX_SIZE_EN;
1625 u32 val = enable ? mask : 0;
1626 int ret;
1627
1628 if (!dev)
1629 return -EINVAL;
1630
1631 if (!dev->i2c_max_rx_size)
1632 return -EOPNOTSUPP;
1633
1634 ret = regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, mask, val);
1635 if (ret)
1636 return ret;
1637
1638 dev->i2c_max_rx_size_en = enable;
1639
1640 return 0;
1641 }
1642 EXPORT_SYMBOL_NS_GPL(thc_i2c_rx_max_size_enable, "INTEL_THC");
1643
1644 /**
1645 * thc_i2c_set_rx_int_delay - Set I2C Rx input interrupt delay value
1646 * @dev: The pointer of THC private device context
1647 * @delay_us: Interrupt delay value, unit is us
1648 *
1649 * Set @delay_us for I2C RxDMA input interrupt delay feature.
1650 *
1651 * Return: 0 on success, other error codes on failure.
1652 */
thc_i2c_set_rx_int_delay(struct thc_device * dev,u32 delay_us)1653 int thc_i2c_set_rx_int_delay(struct thc_device *dev, u32 delay_us)
1654 {
1655 u32 val;
1656 int ret;
1657
1658 if (!dev)
1659 return -EINVAL;
1660
1661 if (!delay_us)
1662 return -EOPNOTSUPP;
1663
1664 ret = regmap_read(dev->thc_regmap, THC_M_PRT_SW_SEQ_STS_OFFSET, &val);
1665 if (ret)
1666 return ret;
1667
1668 /* THC hardware counts at 10us unit */
1669 val |= FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_I2C_INTERVAL, DIV_ROUND_UP(delay_us, 10));
1670
1671 ret = regmap_write(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, val);
1672 if (ret)
1673 return ret;
1674
1675 dev->i2c_int_delay_us = delay_us;
1676
1677 return 0;
1678 }
1679 EXPORT_SYMBOL_NS_GPL(thc_i2c_set_rx_int_delay, "INTEL_THC");
1680
1681 /**
1682 * thc_i2c_rx_int_delay_enable - Enable I2C Rx interrupt delay
1683 * @dev: The pointer of THC private device context
1684 * @enable: Enable interrupt delay or not
1685 *
1686 * Enable or disable I2C RxDMA input interrupt delay feature.
1687 * Input interrupt delay can only be enabled after interrupt delay value
1688 * was set by thc_i2c_set_rx_int_delay().
1689 *
1690 * Return: 0 on success, other error codes on failure.
1691 */
thc_i2c_rx_int_delay_enable(struct thc_device * dev,bool enable)1692 int thc_i2c_rx_int_delay_enable(struct thc_device *dev, bool enable)
1693 {
1694 u32 mask = THC_M_PRT_SPI_ICRRD_OPCODE_I2C_INTERVAL_EN;
1695 u32 val = enable ? mask : 0;
1696 int ret;
1697
1698 if (!dev)
1699 return -EINVAL;
1700
1701 if (!dev->i2c_int_delay_us)
1702 return -EOPNOTSUPP;
1703
1704 ret = regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, mask, val);
1705 if (ret)
1706 return ret;
1707
1708 dev->i2c_int_delay_en = enable;
1709
1710 return 0;
1711 }
1712 EXPORT_SYMBOL_NS_GPL(thc_i2c_rx_int_delay_enable, "INTEL_THC");
1713
1714 MODULE_AUTHOR("Xinpeng Sun <xinpeng.sun@intel.com>");
1715 MODULE_AUTHOR("Even Xu <even.xu@intel.com>");
1716
1717 MODULE_DESCRIPTION("Intel(R) Intel THC Hardware Driver");
1718 MODULE_LICENSE("GPL");
1719