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