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
thc_regmap_read(void * context,unsigned int reg,unsigned int * val)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
thc_regmap_write(void * context,unsigned int reg,unsigned int val)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 */
thc_clear_state(const struct thc_device * dev)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 */
thc_dev_init(struct device * device,void __iomem * mem_addr)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
prepare_pio(const struct thc_device * dev,const u8 pio_op,const u32 address,const u32 size)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
pio_start(const struct thc_device * dev,u32 size_in_bytes,const u32 * buffer)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
pio_complete(const struct thc_device * dev,u32 * buffer,u32 * size)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
pio_wait(const struct thc_device * dev)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 */
thc_tic_pio_read(struct thc_device * dev,const u32 address,const u32 size,u32 * actual_size,u32 * buffer)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 */
thc_tic_pio_write(struct thc_device * dev,const u32 address,const u32 size,const u32 * buffer)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 */
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)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 */
thc_interrupt_config(struct thc_device * dev)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 */
thc_int_trigger_type_select(struct thc_device * dev,bool edge_trigger)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 */
thc_interrupt_enable(struct thc_device * dev,bool int_enable)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 */
thc_interrupt_quiesce(const struct thc_device * dev,bool int_quiesce)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 */
thc_set_pio_interrupt_support(struct thc_device * dev,bool supported)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 */
thc_ltr_config(struct thc_device * dev,u32 active_ltr_us,u32 lp_ltr_us)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 */
thc_change_ltr_mode(struct thc_device * dev,u32 ltr_mode)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 */
thc_ltr_unconfig(struct thc_device * dev)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, <r_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 */
thc_int_cause_read(struct thc_device * dev)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
thc_print_txn_error_cause(const struct thc_device * dev)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 */
thc_interrupt_handler(struct thc_device * dev)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 */
thc_port_select(struct thc_device * dev,enum thc_port_type port_type)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_15M 15625000
1116 #define THC_SPI_FREQUENCY_17M 17857100
1117 #define THC_SPI_FREQUENCY_20M 20833000
1118 #define THC_SPI_FREQUENCY_25M 25000000
1119 #define THC_SPI_FREQUENCY_31M 31250000
1120 #define THC_SPI_FREQUENCY_41M 41666700
1121
1122 #define THC_SPI_LOW_FREQUENCY THC_SPI_FREQUENCY_17M
1123
thc_get_spi_freq_div_val(struct thc_device * dev,u32 spi_freq_val)1124 static u8 thc_get_spi_freq_div_val(struct thc_device *dev, u32 spi_freq_val)
1125 {
1126 static const int frequency[] = {
1127 THC_SPI_FREQUENCY_7M,
1128 THC_SPI_FREQUENCY_15M,
1129 THC_SPI_FREQUENCY_17M,
1130 THC_SPI_FREQUENCY_20M,
1131 THC_SPI_FREQUENCY_25M,
1132 THC_SPI_FREQUENCY_31M,
1133 THC_SPI_FREQUENCY_41M,
1134 };
1135 static const u8 frequency_div[] = {
1136 THC_SPI_FRQ_DIV_2,
1137 THC_SPI_FRQ_DIV_1,
1138 THC_SPI_FRQ_DIV_7,
1139 THC_SPI_FRQ_DIV_6,
1140 THC_SPI_FRQ_DIV_5,
1141 THC_SPI_FRQ_DIV_4,
1142 THC_SPI_FRQ_DIV_3,
1143 };
1144 int size = ARRAY_SIZE(frequency);
1145 u32 closest_freq;
1146 u8 freq_div;
1147 int i;
1148
1149 for (i = size - 1; i >= 0; i--)
1150 if ((int)spi_freq_val - frequency[i] >= 0)
1151 break;
1152
1153 if (i < 0) {
1154 dev_err_once(dev->dev, "Not supported SPI frequency %d\n", spi_freq_val);
1155 return THC_SPI_FRQ_RESERVED;
1156 }
1157
1158 closest_freq = frequency[i];
1159 freq_div = frequency_div[i];
1160
1161 dev_dbg(dev->dev,
1162 "Setting SPI frequency: spi_freq_val = %u, Closest freq = %u\n",
1163 spi_freq_val, closest_freq);
1164
1165 return freq_div;
1166 }
1167
1168 /**
1169 * thc_spi_read_config - Configure SPI bus read attributes
1170 *
1171 * @dev: The pointer of THC private device context
1172 * @spi_freq_val: SPI read frequecy value
1173 * @io_mode: SPI read IO mode
1174 * @opcode: Read opcode
1175 * @spi_rd_mps: SPI read max packet size
1176 *
1177 * Return: 0 on success, other error codes on failed.
1178 */
thc_spi_read_config(struct thc_device * dev,u32 spi_freq_val,u32 io_mode,u32 opcode,u32 spi_rd_mps)1179 int thc_spi_read_config(struct thc_device *dev, u32 spi_freq_val,
1180 u32 io_mode, u32 opcode, u32 spi_rd_mps)
1181 {
1182 bool is_low_freq = false;
1183 u32 cfg, mask;
1184 u8 freq_div;
1185
1186 freq_div = thc_get_spi_freq_div_val(dev, spi_freq_val);
1187 if (freq_div == THC_SPI_FRQ_RESERVED)
1188 return -EINVAL;
1189
1190 if (spi_freq_val < THC_SPI_LOW_FREQUENCY)
1191 is_low_freq = true;
1192
1193 cfg = FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TCRF, freq_div) |
1194 FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TRMODE, io_mode) |
1195 (is_low_freq ? THC_M_PRT_SPI_CFG_SPI_LOW_FREQ_EN : 0) |
1196 FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_RD_MPS, spi_rd_mps);
1197 mask = THC_M_PRT_SPI_CFG_SPI_TCRF |
1198 THC_M_PRT_SPI_CFG_SPI_TRMODE |
1199 THC_M_PRT_SPI_CFG_SPI_LOW_FREQ_EN |
1200 THC_M_PRT_SPI_CFG_SPI_RD_MPS;
1201
1202 regmap_write_bits(dev->thc_regmap,
1203 THC_M_PRT_SPI_CFG_OFFSET, mask, cfg);
1204
1205 if (io_mode == THC_QUAD_IO)
1206 opcode = FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_SPI_QIO, opcode);
1207 else if (io_mode == THC_DUAL_IO)
1208 opcode = FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_SPI_DIO, opcode);
1209 else
1210 opcode = FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_SPI_SIO, opcode);
1211
1212 regmap_write(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, opcode);
1213 regmap_write(dev->thc_regmap, THC_M_PRT_SPI_DMARD_OPCODE_OFFSET, opcode);
1214
1215 return 0;
1216 }
1217 EXPORT_SYMBOL_NS_GPL(thc_spi_read_config, "INTEL_THC");
1218
1219 /**
1220 * thc_spi_write_config - Configure SPI bus write attributes
1221 *
1222 * @dev: The pointer of THC private device context
1223 * @spi_freq_val: SPI write frequecy value
1224 * @io_mode: SPI write IO mode
1225 * @opcode: Write opcode
1226 * @spi_wr_mps: SPI write max packet size
1227 * @perf_limit: Performance limitation in unit of 10us
1228 *
1229 * Return: 0 on success, other error codes on failed.
1230 */
thc_spi_write_config(struct thc_device * dev,u32 spi_freq_val,u32 io_mode,u32 opcode,u32 spi_wr_mps,u32 perf_limit)1231 int thc_spi_write_config(struct thc_device *dev, u32 spi_freq_val,
1232 u32 io_mode, u32 opcode, u32 spi_wr_mps,
1233 u32 perf_limit)
1234 {
1235 bool is_low_freq = false;
1236 u32 cfg, mask;
1237 u8 freq_div;
1238
1239 freq_div = thc_get_spi_freq_div_val(dev, spi_freq_val);
1240 if (freq_div == THC_SPI_FRQ_RESERVED)
1241 return -EINVAL;
1242
1243 if (spi_freq_val < THC_SPI_LOW_FREQUENCY)
1244 is_low_freq = true;
1245
1246 cfg = FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TCWF, freq_div) |
1247 FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TWMODE, io_mode) |
1248 (is_low_freq ? THC_M_PRT_SPI_CFG_SPI_LOW_FREQ_EN : 0) |
1249 FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_WR_MPS, spi_wr_mps);
1250 mask = THC_M_PRT_SPI_CFG_SPI_TCWF |
1251 THC_M_PRT_SPI_CFG_SPI_TWMODE |
1252 THC_M_PRT_SPI_CFG_SPI_LOW_FREQ_EN |
1253 THC_M_PRT_SPI_CFG_SPI_WR_MPS;
1254
1255 regmap_write_bits(dev->thc_regmap,
1256 THC_M_PRT_SPI_CFG_OFFSET, mask, cfg);
1257
1258 if (io_mode == THC_QUAD_IO)
1259 opcode = FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_SPI_QIO, opcode);
1260 else if (io_mode == THC_DUAL_IO)
1261 opcode = FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_SPI_DIO, opcode);
1262 else
1263 opcode = FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_SPI_SIO, opcode);
1264
1265 regmap_write(dev->thc_regmap, THC_M_PRT_SPI_WR_OPCODE_OFFSET, opcode);
1266
1267 dev->perf_limit = perf_limit;
1268
1269 return 0;
1270 }
1271 EXPORT_SYMBOL_NS_GPL(thc_spi_write_config, "INTEL_THC");
1272
1273 /**
1274 * thc_spi_input_output_address_config - Configure SPI input and output addresses
1275 *
1276 * @dev: the pointer of THC private device context
1277 * @input_hdr_addr: input report header address
1278 * @input_bdy_addr: input report body address
1279 * @output_addr: output report address
1280 */
thc_spi_input_output_address_config(struct thc_device * dev,u32 input_hdr_addr,u32 input_bdy_addr,u32 output_addr)1281 void thc_spi_input_output_address_config(struct thc_device *dev, u32 input_hdr_addr,
1282 u32 input_bdy_addr, u32 output_addr)
1283 {
1284 regmap_write(dev->thc_regmap,
1285 THC_M_PRT_DEV_INT_CAUSE_ADDR_OFFSET, input_hdr_addr);
1286 regmap_write(dev->thc_regmap,
1287 THC_M_PRT_RD_BULK_ADDR_1_OFFSET, input_bdy_addr);
1288 regmap_write(dev->thc_regmap,
1289 THC_M_PRT_RD_BULK_ADDR_2_OFFSET, input_bdy_addr);
1290 regmap_write(dev->thc_regmap,
1291 THC_M_PRT_WR_BULK_ADDR_OFFSET, output_addr);
1292 }
1293 EXPORT_SYMBOL_NS_GPL(thc_spi_input_output_address_config, "INTEL_THC");
1294
thc_i2c_subip_pio_read(struct thc_device * dev,const u32 address,u32 * size,u32 * buffer)1295 static int thc_i2c_subip_pio_read(struct thc_device *dev, const u32 address,
1296 u32 *size, u32 *buffer)
1297 {
1298 int ret;
1299
1300 if (!size || *size == 0 || !buffer) {
1301 dev_err(dev->dev, "Invalid input parameters, size %p, buffer %p\n",
1302 size, buffer);
1303 return -EINVAL;
1304 }
1305
1306 if (mutex_lock_interruptible(&dev->thc_bus_lock))
1307 return -EINTR;
1308
1309 ret = prepare_pio(dev, THC_PIO_OP_I2C_SUBSYSTEM_READ, address, *size);
1310 if (ret < 0)
1311 goto end;
1312
1313 pio_start(dev, 0, NULL);
1314
1315 ret = pio_wait(dev);
1316 if (ret < 0)
1317 goto end;
1318
1319 ret = pio_complete(dev, buffer, size);
1320 if (ret < 0)
1321 goto end;
1322
1323 end:
1324 mutex_unlock(&dev->thc_bus_lock);
1325
1326 if (ret)
1327 dev_err_once(dev->dev, "Read THC I2C SubIP register failed %d, offset %u\n",
1328 ret, address);
1329
1330 return ret;
1331 }
1332
thc_i2c_subip_pio_write(struct thc_device * dev,const u32 address,const u32 size,const u32 * buffer)1333 static int thc_i2c_subip_pio_write(struct thc_device *dev, const u32 address,
1334 const u32 size, const u32 *buffer)
1335 {
1336 int ret;
1337
1338 if (size == 0 || !buffer) {
1339 dev_err(dev->dev, "Invalid input parameters, size %u, buffer %p\n",
1340 size, buffer);
1341 return -EINVAL;
1342 }
1343
1344 if (mutex_lock_interruptible(&dev->thc_bus_lock))
1345 return -EINTR;
1346
1347 ret = prepare_pio(dev, THC_PIO_OP_I2C_SUBSYSTEM_WRITE, address, size);
1348 if (ret < 0)
1349 goto end;
1350
1351 pio_start(dev, size, buffer);
1352
1353 ret = pio_wait(dev);
1354 if (ret < 0)
1355 goto end;
1356
1357 ret = pio_complete(dev, NULL, NULL);
1358 if (ret < 0)
1359 goto end;
1360
1361 end:
1362 mutex_unlock(&dev->thc_bus_lock);
1363
1364 if (ret)
1365 dev_err_once(dev->dev, "Write THC I2C SubIP register failed %d, offset %u\n",
1366 ret, address);
1367
1368 return ret;
1369 }
1370
1371 #define I2C_SUBIP_CON_DEFAULT 0x663
1372 #define I2C_SUBIP_INT_MASK_DEFAULT 0x7FFF
1373 #define I2C_SUBIP_RX_TL_DEFAULT 62
1374 #define I2C_SUBIP_TX_TL_DEFAULT 0
1375 #define I2C_SUBIP_DMA_TDLR_DEFAULT 7
1376 #define I2C_SUBIP_DMA_RDLR_DEFAULT 7
1377
thc_i2c_subip_set_speed(struct thc_device * dev,const u32 speed,const u32 hcnt,const u32 lcnt)1378 static int thc_i2c_subip_set_speed(struct thc_device *dev, const u32 speed,
1379 const u32 hcnt, const u32 lcnt)
1380 {
1381 u32 hcnt_offset, lcnt_offset;
1382 u32 val;
1383 int ret;
1384
1385 switch (speed) {
1386 case THC_I2C_STANDARD:
1387 hcnt_offset = THC_I2C_IC_SS_SCL_HCNT_OFFSET;
1388 lcnt_offset = THC_I2C_IC_SS_SCL_LCNT_OFFSET;
1389 break;
1390
1391 case THC_I2C_FAST_AND_PLUS:
1392 hcnt_offset = THC_I2C_IC_FS_SCL_HCNT_OFFSET;
1393 lcnt_offset = THC_I2C_IC_FS_SCL_LCNT_OFFSET;
1394 break;
1395
1396 case THC_I2C_HIGH_SPEED:
1397 hcnt_offset = THC_I2C_IC_HS_SCL_HCNT_OFFSET;
1398 lcnt_offset = THC_I2C_IC_HS_SCL_LCNT_OFFSET;
1399 break;
1400
1401 default:
1402 dev_err_once(dev->dev, "Unsupported i2c speed %d\n", speed);
1403 ret = -EINVAL;
1404 return ret;
1405 }
1406
1407 ret = thc_i2c_subip_pio_write(dev, hcnt_offset, sizeof(u32), &hcnt);
1408 if (ret < 0)
1409 return ret;
1410
1411 ret = thc_i2c_subip_pio_write(dev, lcnt_offset, sizeof(u32), &lcnt);
1412 if (ret < 0)
1413 return ret;
1414
1415 val = I2C_SUBIP_CON_DEFAULT & ~THC_I2C_IC_CON_SPEED;
1416 val |= FIELD_PREP(THC_I2C_IC_CON_SPEED, speed);
1417 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_CON_OFFSET, sizeof(u32), &val);
1418 if (ret < 0)
1419 return ret;
1420
1421 return 0;
1422 }
1423
1424 static u32 i2c_subip_regs[] = {
1425 THC_I2C_IC_CON_OFFSET,
1426 THC_I2C_IC_TAR_OFFSET,
1427 THC_I2C_IC_INTR_MASK_OFFSET,
1428 THC_I2C_IC_RX_TL_OFFSET,
1429 THC_I2C_IC_TX_TL_OFFSET,
1430 THC_I2C_IC_DMA_CR_OFFSET,
1431 THC_I2C_IC_DMA_TDLR_OFFSET,
1432 THC_I2C_IC_DMA_RDLR_OFFSET,
1433 THC_I2C_IC_SS_SCL_HCNT_OFFSET,
1434 THC_I2C_IC_SS_SCL_LCNT_OFFSET,
1435 THC_I2C_IC_FS_SCL_HCNT_OFFSET,
1436 THC_I2C_IC_FS_SCL_LCNT_OFFSET,
1437 THC_I2C_IC_HS_SCL_HCNT_OFFSET,
1438 THC_I2C_IC_HS_SCL_LCNT_OFFSET,
1439 THC_I2C_IC_ENABLE_OFFSET,
1440 };
1441
1442 /**
1443 * thc_i2c_subip_init - Initialize and configure THC I2C subsystem
1444 *
1445 * @dev: The pointer of THC private device context
1446 * @target_address: Slave address of touch device (TIC)
1447 * @speed: I2C bus frequency speed mode
1448 * @hcnt: I2C clock SCL high count
1449 * @lcnt: I2C clock SCL low count
1450 *
1451 * Return: 0 on success, other error codes on failed.
1452 */
thc_i2c_subip_init(struct thc_device * dev,const u32 target_address,const u32 speed,const u32 hcnt,const u32 lcnt)1453 int thc_i2c_subip_init(struct thc_device *dev, const u32 target_address,
1454 const u32 speed, const u32 hcnt, const u32 lcnt)
1455 {
1456 u32 read_size = sizeof(u32);
1457 u32 val;
1458 int ret;
1459
1460 ret = thc_i2c_subip_pio_read(dev, THC_I2C_IC_ENABLE_OFFSET, &read_size, &val);
1461 if (ret < 0)
1462 return ret;
1463
1464 val &= ~THC_I2C_IC_ENABLE_ENABLE;
1465 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_ENABLE_OFFSET, sizeof(u32), &val);
1466 if (ret < 0)
1467 return ret;
1468
1469 ret = thc_i2c_subip_pio_read(dev, THC_I2C_IC_TAR_OFFSET, &read_size, &val);
1470 if (ret < 0)
1471 return ret;
1472
1473 val &= ~THC_I2C_IC_TAR_IC_TAR;
1474 val |= FIELD_PREP(THC_I2C_IC_TAR_IC_TAR, target_address);
1475 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_TAR_OFFSET, sizeof(u32), &val);
1476 if (ret < 0)
1477 return ret;
1478
1479 ret = thc_i2c_subip_set_speed(dev, speed, hcnt, lcnt);
1480 if (ret < 0)
1481 return ret;
1482
1483 val = I2C_SUBIP_INT_MASK_DEFAULT;
1484 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_INTR_MASK_OFFSET, sizeof(u32), &val);
1485 if (ret < 0)
1486 return ret;
1487
1488 val = I2C_SUBIP_RX_TL_DEFAULT;
1489 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_RX_TL_OFFSET, sizeof(u32), &val);
1490 if (ret < 0)
1491 return ret;
1492
1493 val = I2C_SUBIP_TX_TL_DEFAULT;
1494 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_TX_TL_OFFSET, sizeof(u32), &val);
1495 if (ret < 0)
1496 return ret;
1497
1498 val = THC_I2C_IC_DMA_CR_RDMAE | THC_I2C_IC_DMA_CR_TDMAE;
1499 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_DMA_CR_OFFSET, sizeof(u32), &val);
1500 if (ret < 0)
1501 return ret;
1502
1503 val = I2C_SUBIP_DMA_TDLR_DEFAULT;
1504 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_DMA_TDLR_OFFSET, sizeof(u32), &val);
1505 if (ret < 0)
1506 return ret;
1507
1508 val = I2C_SUBIP_DMA_RDLR_DEFAULT;
1509 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_DMA_RDLR_OFFSET, sizeof(u32), &val);
1510 if (ret < 0)
1511 return ret;
1512
1513 ret = thc_i2c_subip_pio_read(dev, THC_I2C_IC_ENABLE_OFFSET, &read_size, &val);
1514 if (ret < 0)
1515 return ret;
1516
1517 val |= THC_I2C_IC_ENABLE_ENABLE;
1518 ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_ENABLE_OFFSET, sizeof(u32), &val);
1519 if (ret < 0)
1520 return ret;
1521
1522 dev->i2c_subip_regs = devm_kzalloc(dev->dev, sizeof(i2c_subip_regs), GFP_KERNEL);
1523 if (!dev->i2c_subip_regs)
1524 return -ENOMEM;
1525
1526 return 0;
1527 }
1528 EXPORT_SYMBOL_NS_GPL(thc_i2c_subip_init, "INTEL_THC");
1529
1530 /**
1531 * thc_i2c_subip_regs_save - Save THC I2C sub-subsystem register values to THC device context
1532 *
1533 * @dev: The pointer of THC private device context
1534 *
1535 * Return: 0 on success, other error codes on failed.
1536 */
thc_i2c_subip_regs_save(struct thc_device * dev)1537 int thc_i2c_subip_regs_save(struct thc_device *dev)
1538 {
1539 int ret;
1540 u32 read_size = sizeof(u32);
1541
1542 for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) {
1543 ret = thc_i2c_subip_pio_read(dev, i2c_subip_regs[i],
1544 &read_size, &dev->i2c_subip_regs[i]);
1545 if (ret < 0)
1546 return ret;
1547 }
1548
1549 return 0;
1550 }
1551 EXPORT_SYMBOL_NS_GPL(thc_i2c_subip_regs_save, "INTEL_THC");
1552
1553 /**
1554 * thc_i2c_subip_regs_restore - Restore THC I2C subsystem registers from THC device context
1555 *
1556 * @dev: The pointer of THC private device context
1557 *
1558 * Return: 0 on success, other error codes on failed.
1559 */
thc_i2c_subip_regs_restore(struct thc_device * dev)1560 int thc_i2c_subip_regs_restore(struct thc_device *dev)
1561 {
1562 int ret;
1563 u32 write_size = sizeof(u32);
1564
1565 for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) {
1566 ret = thc_i2c_subip_pio_write(dev, i2c_subip_regs[i],
1567 write_size, &dev->i2c_subip_regs[i]);
1568 if (ret < 0)
1569 return ret;
1570 }
1571
1572 return 0;
1573 }
1574 EXPORT_SYMBOL_NS_GPL(thc_i2c_subip_regs_restore, "INTEL_THC");
1575
1576 /**
1577 * thc_i2c_set_rx_max_size - Set I2C Rx transfer max input size
1578 * @dev: The pointer of THC private device context
1579 * @max_rx_size: Max input report packet size for input report
1580 *
1581 * Set @max_rx_size for I2C RxDMA max input size control feature.
1582 *
1583 * Return: 0 on success, other error codes on failure.
1584 */
thc_i2c_set_rx_max_size(struct thc_device * dev,u32 max_rx_size)1585 int thc_i2c_set_rx_max_size(struct thc_device *dev, u32 max_rx_size)
1586 {
1587 u32 val;
1588 int ret;
1589
1590 if (!dev)
1591 return -EINVAL;
1592
1593 if (!max_rx_size)
1594 return -EOPNOTSUPP;
1595
1596 ret = regmap_read(dev->thc_regmap, THC_M_PRT_SW_SEQ_STS_OFFSET, &val);
1597 if (ret)
1598 return ret;
1599
1600 val |= FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_I2C_MAX_SIZE, max_rx_size);
1601
1602 ret = regmap_write(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, val);
1603 if (ret)
1604 return ret;
1605
1606 dev->i2c_max_rx_size = max_rx_size;
1607
1608 return 0;
1609 }
1610 EXPORT_SYMBOL_NS_GPL(thc_i2c_set_rx_max_size, "INTEL_THC");
1611
1612 /**
1613 * thc_i2c_rx_max_size_enable - Enable I2C Rx max input size control
1614 * @dev: The pointer of THC private device context
1615 * @enable: Enable max input size control or not
1616 *
1617 * Enable or disable I2C RxDMA max input size control feature.
1618 * Max input size control only can be enabled after max input size
1619 * was set by thc_i2c_set_rx_max_size().
1620 *
1621 * Return: 0 on success, other error codes on failure.
1622 */
thc_i2c_rx_max_size_enable(struct thc_device * dev,bool enable)1623 int thc_i2c_rx_max_size_enable(struct thc_device *dev, bool enable)
1624 {
1625 u32 mask = THC_M_PRT_SPI_ICRRD_OPCODE_I2C_MAX_SIZE_EN;
1626 u32 val = enable ? mask : 0;
1627 int ret;
1628
1629 if (!dev)
1630 return -EINVAL;
1631
1632 if (!dev->i2c_max_rx_size)
1633 return -EOPNOTSUPP;
1634
1635 ret = regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, mask, val);
1636 if (ret)
1637 return ret;
1638
1639 dev->i2c_max_rx_size_en = enable;
1640
1641 return 0;
1642 }
1643 EXPORT_SYMBOL_NS_GPL(thc_i2c_rx_max_size_enable, "INTEL_THC");
1644
1645 /**
1646 * thc_i2c_set_rx_int_delay - Set I2C Rx input interrupt delay value
1647 * @dev: The pointer of THC private device context
1648 * @delay_us: Interrupt delay value, unit is us
1649 *
1650 * Set @delay_us for I2C RxDMA input interrupt delay feature.
1651 *
1652 * Return: 0 on success, other error codes on failure.
1653 */
thc_i2c_set_rx_int_delay(struct thc_device * dev,u32 delay_us)1654 int thc_i2c_set_rx_int_delay(struct thc_device *dev, u32 delay_us)
1655 {
1656 u32 val;
1657 int ret;
1658
1659 if (!dev)
1660 return -EINVAL;
1661
1662 if (!delay_us)
1663 return -EOPNOTSUPP;
1664
1665 ret = regmap_read(dev->thc_regmap, THC_M_PRT_SW_SEQ_STS_OFFSET, &val);
1666 if (ret)
1667 return ret;
1668
1669 /* THC hardware counts at 10us unit */
1670 val |= FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_I2C_INTERVAL, DIV_ROUND_UP(delay_us, 10));
1671
1672 ret = regmap_write(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, val);
1673 if (ret)
1674 return ret;
1675
1676 dev->i2c_int_delay_us = delay_us;
1677
1678 return 0;
1679 }
1680 EXPORT_SYMBOL_NS_GPL(thc_i2c_set_rx_int_delay, "INTEL_THC");
1681
1682 /**
1683 * thc_i2c_rx_int_delay_enable - Enable I2C Rx interrupt delay
1684 * @dev: The pointer of THC private device context
1685 * @enable: Enable interrupt delay or not
1686 *
1687 * Enable or disable I2C RxDMA input interrupt delay feature.
1688 * Input interrupt delay can only be enabled after interrupt delay value
1689 * was set by thc_i2c_set_rx_int_delay().
1690 *
1691 * Return: 0 on success, other error codes on failure.
1692 */
thc_i2c_rx_int_delay_enable(struct thc_device * dev,bool enable)1693 int thc_i2c_rx_int_delay_enable(struct thc_device *dev, bool enable)
1694 {
1695 u32 mask = THC_M_PRT_SPI_ICRRD_OPCODE_I2C_INTERVAL_EN;
1696 u32 val = enable ? mask : 0;
1697 int ret;
1698
1699 if (!dev)
1700 return -EINVAL;
1701
1702 if (!dev->i2c_int_delay_us)
1703 return -EOPNOTSUPP;
1704
1705 ret = regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, mask, val);
1706 if (ret)
1707 return ret;
1708
1709 dev->i2c_int_delay_en = enable;
1710
1711 return 0;
1712 }
1713 EXPORT_SYMBOL_NS_GPL(thc_i2c_rx_int_delay_enable, "INTEL_THC");
1714
1715 MODULE_AUTHOR("Xinpeng Sun <xinpeng.sun@intel.com>");
1716 MODULE_AUTHOR("Even Xu <even.xu@intel.com>");
1717
1718 MODULE_DESCRIPTION("Intel(R) Intel THC Hardware Driver");
1719 MODULE_LICENSE("GPL");
1720