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