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, <r_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