File Index
Files and directories
Sign in
FILE

intel-thc-dev.c

File preview with syntax highlighting.

linux-6.19.14/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c C
   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
  12static 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
  22static 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
  32static const struct regmap_range thc_rw_ranges[] = {
  33	regmap_reg_range(0x10, 0x14),
  34	regmap_reg_range(0x1000, 0x1320),
  35};
  36
  37static 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
  42static 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 */
  62static 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 */
 195struct 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}
 227EXPORT_SYMBOL_NS_GPL(thc_dev_init, "INTEL_THC");
 228
 229static 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
 267static 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
 281static 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
 305static 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 */
 331int 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
 361end:
 362	mutex_unlock(&dev->thc_bus_lock);
 363	return ret;
 364}
 365EXPORT_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 */
 377int 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
 407end:
 408	mutex_unlock(&dev->thc_bus_lock);
 409	return ret;
 410}
 411EXPORT_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 */
 426int 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
 464end:
 465	mutex_unlock(&dev->thc_bus_lock);
 466	return ret;
 467}
 468EXPORT_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 */
 475void 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}
 602EXPORT_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 */
 610void 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}
 616EXPORT_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 */
 624void 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}
 630EXPORT_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 */
 640int 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}
 679EXPORT_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 */
 687void thc_set_pio_interrupt_support(struct thc_device *dev, bool supported)
 688{
 689	dev->pio_int_supported = supported;
 690}
 691EXPORT_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 */
 700void 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}
 759EXPORT_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 */
 767void 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}
 784EXPORT_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 */
 791void thc_ltr_unconfig(struct thc_device *dev)
 792{
 793	u32 ltr_ctrl, bits_clear;
 794
 795	regmap_read(dev->thc_regmap, THC_M_CMN_LTR_CTRL_OFFSET, &ltr_ctrl);
 796	bits_clear = THC_M_CMN_LTR_CTRL_LP_LTR_EN |
 797			THC_M_CMN_LTR_CTRL_ACTIVE_LTR_EN |
 798			THC_M_CMN_LTR_CTRL_LP_LTR_REQ |
 799			THC_M_CMN_LTR_CTRL_ACTIVE_LTR_REQ;
 800
 801	ltr_ctrl &= ~bits_clear;
 802
 803	regmap_write(dev->thc_regmap, THC_M_CMN_LTR_CTRL_OFFSET, ltr_ctrl);
 804}
 805EXPORT_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 */
 814u32 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}
 823EXPORT_SYMBOL_NS_GPL(thc_int_cause_read, "INTEL_THC");
 824
 825static 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 */
 872int 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}
1064EXPORT_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 */
1074int 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}
1112EXPORT_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
1124static 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 */
1179int 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}
1217EXPORT_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 */
1231int 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}
1271EXPORT_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 */
1281void 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}
1293EXPORT_SYMBOL_NS_GPL(thc_spi_input_output_address_config, "INTEL_THC");
1294
1295static 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
1323end:
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
1333static 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
1361end:
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
1378static 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
1424static 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 */
1453int 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}
1528EXPORT_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 */
1537int 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}
1551EXPORT_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 */
1560int 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}
1574EXPORT_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 */
1585int 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_SPI_ICRRD_OPCODE_OFFSET, &val);
1597	if (ret)
1598		return ret;
1599
1600	val = val & ~THC_M_PRT_SPI_ICRRD_OPCODE_I2C_MAX_SIZE;
1601	val |= FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_I2C_MAX_SIZE, max_rx_size);
1602
1603	ret = regmap_write(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, val);
1604	if (ret)
1605		return ret;
1606
1607	dev->i2c_max_rx_size = max_rx_size;
1608
1609	return 0;
1610}
1611EXPORT_SYMBOL_NS_GPL(thc_i2c_set_rx_max_size, "INTEL_THC");
1612
1613/**
1614 * thc_i2c_rx_max_size_enable - Enable I2C Rx max input size control
1615 * @dev: The pointer of THC private device context
1616 * @enable: Enable max input size control or not
1617 *
1618 * Enable or disable I2C RxDMA max input size control feature.
1619 * Max input size control only can be enabled after max input size
1620 * was set by thc_i2c_set_rx_max_size().
1621 *
1622 * Return: 0 on success, other error codes on failure.
1623 */
1624int thc_i2c_rx_max_size_enable(struct thc_device *dev, bool enable)
1625{
1626	u32 mask = THC_M_PRT_SPI_ICRRD_OPCODE_I2C_MAX_SIZE_EN;
1627	u32 val = enable ? mask : 0;
1628	int ret;
1629
1630	if (!dev)
1631		return -EINVAL;
1632
1633	if (!dev->i2c_max_rx_size)
1634		return -EOPNOTSUPP;
1635
1636	ret = regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, mask, val);
1637	if (ret)
1638		return ret;
1639
1640	dev->i2c_max_rx_size_en = enable;
1641
1642	return 0;
1643}
1644EXPORT_SYMBOL_NS_GPL(thc_i2c_rx_max_size_enable, "INTEL_THC");
1645
1646/**
1647 * thc_i2c_set_rx_int_delay - Set I2C Rx input interrupt delay value
1648 * @dev: The pointer of THC private device context
1649 * @delay_us: Interrupt delay value, unit is us
1650 *
1651 * Set @delay_us for I2C RxDMA input interrupt delay feature.
1652 *
1653 * Return: 0 on success, other error codes on failure.
1654 */
1655int thc_i2c_set_rx_int_delay(struct thc_device *dev, u32 delay_us)
1656{
1657	u32 val;
1658	int ret;
1659
1660	if (!dev)
1661		return -EINVAL;
1662
1663	if (!delay_us)
1664		return -EOPNOTSUPP;
1665
1666	ret = regmap_read(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, &val);
1667	if (ret)
1668		return ret;
1669
1670	/* THC hardware counts at 10us unit */
1671	val = val & ~THC_M_PRT_SPI_ICRRD_OPCODE_I2C_INTERVAL;
1672	val |= FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_I2C_INTERVAL, DIV_ROUND_UP(delay_us, 10));
1673
1674	ret = regmap_write(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, val);
1675	if (ret)
1676		return ret;
1677
1678	dev->i2c_int_delay_us = delay_us;
1679
1680	return 0;
1681}
1682EXPORT_SYMBOL_NS_GPL(thc_i2c_set_rx_int_delay, "INTEL_THC");
1683
1684/**
1685 * thc_i2c_rx_int_delay_enable - Enable I2C Rx interrupt delay
1686 * @dev: The pointer of THC private device context
1687 * @enable: Enable interrupt delay or not
1688 *
1689 * Enable or disable I2C RxDMA input interrupt delay feature.
1690 * Input interrupt delay can only be enabled after interrupt delay value
1691 * was set by thc_i2c_set_rx_int_delay().
1692 *
1693 * Return: 0 on success, other error codes on failure.
1694 */
1695int thc_i2c_rx_int_delay_enable(struct thc_device *dev, bool enable)
1696{
1697	u32 mask = THC_M_PRT_SPI_ICRRD_OPCODE_I2C_INTERVAL_EN;
1698	u32 val = enable ? mask : 0;
1699	int ret;
1700
1701	if (!dev)
1702		return -EINVAL;
1703
1704	if (!dev->i2c_int_delay_us)
1705		return -EOPNOTSUPP;
1706
1707	ret = regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, mask, val);
1708	if (ret)
1709		return ret;
1710
1711	dev->i2c_int_delay_en = enable;
1712
1713	return 0;
1714}
1715EXPORT_SYMBOL_NS_GPL(thc_i2c_rx_int_delay_enable, "INTEL_THC");
1716
1717MODULE_AUTHOR("Xinpeng Sun <xinpeng.sun@intel.com>");
1718MODULE_AUTHOR("Even Xu <even.xu@intel.com>");
1719
1720MODULE_DESCRIPTION("Intel(R) Intel THC Hardware Driver");
1721MODULE_LICENSE("GPL");
~/ Read-only file preview.