|
2 | 2 | /* Copyright (c) 2024 Intel Corporation */ |
3 | 3 |
|
4 | 4 | #include <linux/bitfield.h> |
| 5 | +#include <linux/math.h> |
5 | 6 | #include <linux/regmap.h> |
6 | 7 |
|
7 | 8 | #include "intel-thc-dev.h" |
@@ -1640,6 +1641,76 @@ int thc_i2c_rx_max_size_enable(struct thc_device *dev, bool enable) |
1640 | 1641 | } |
1641 | 1642 | EXPORT_SYMBOL_NS_GPL(thc_i2c_rx_max_size_enable, "INTEL_THC"); |
1642 | 1643 |
|
| 1644 | +/** |
| 1645 | + * thc_i2c_set_rx_int_delay - Set I2C Rx input interrupt delay value |
| 1646 | + * @dev: The pointer of THC private device context |
| 1647 | + * @delay_us: Interrupt delay value, unit is us |
| 1648 | + * |
| 1649 | + * Set @delay_us for I2C RxDMA input interrupt delay feature. |
| 1650 | + * |
| 1651 | + * Return: 0 on success, other error codes on failure. |
| 1652 | + */ |
| 1653 | +int thc_i2c_set_rx_int_delay(struct thc_device *dev, u32 delay_us) |
| 1654 | +{ |
| 1655 | + u32 val; |
| 1656 | + int ret; |
| 1657 | + |
| 1658 | + if (!dev) |
| 1659 | + return -EINVAL; |
| 1660 | + |
| 1661 | + if (!delay_us) |
| 1662 | + return -EOPNOTSUPP; |
| 1663 | + |
| 1664 | + ret = regmap_read(dev->thc_regmap, THC_M_PRT_SW_SEQ_STS_OFFSET, &val); |
| 1665 | + if (ret) |
| 1666 | + return ret; |
| 1667 | + |
| 1668 | + /* THC hardware counts at 10us unit */ |
| 1669 | + val |= FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_I2C_INTERVAL, DIV_ROUND_UP(delay_us, 10)); |
| 1670 | + |
| 1671 | + ret = regmap_write(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, val); |
| 1672 | + if (ret) |
| 1673 | + return ret; |
| 1674 | + |
| 1675 | + dev->i2c_int_delay_us = delay_us; |
| 1676 | + |
| 1677 | + return 0; |
| 1678 | +} |
| 1679 | +EXPORT_SYMBOL_NS_GPL(thc_i2c_set_rx_int_delay, "INTEL_THC"); |
| 1680 | + |
| 1681 | +/** |
| 1682 | + * thc_i2c_rx_int_delay_enable - Enable I2C Rx interrupt delay |
| 1683 | + * @dev: The pointer of THC private device context |
| 1684 | + * @enable: Enable interrupt delay or not |
| 1685 | + * |
| 1686 | + * Enable or disable I2C RxDMA input interrupt delay feature. |
| 1687 | + * Input interrupt delay can only be enabled after interrupt delay value |
| 1688 | + * was set by thc_i2c_set_rx_int_delay(). |
| 1689 | + * |
| 1690 | + * Return: 0 on success, other error codes on failure. |
| 1691 | + */ |
| 1692 | +int thc_i2c_rx_int_delay_enable(struct thc_device *dev, bool enable) |
| 1693 | +{ |
| 1694 | + u32 mask = THC_M_PRT_SPI_ICRRD_OPCODE_I2C_INTERVAL_EN; |
| 1695 | + u32 val = enable ? mask : 0; |
| 1696 | + int ret; |
| 1697 | + |
| 1698 | + if (!dev) |
| 1699 | + return -EINVAL; |
| 1700 | + |
| 1701 | + if (!dev->i2c_int_delay_us) |
| 1702 | + return -EOPNOTSUPP; |
| 1703 | + |
| 1704 | + ret = regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, mask, val); |
| 1705 | + if (ret) |
| 1706 | + return ret; |
| 1707 | + |
| 1708 | + dev->i2c_int_delay_en = enable; |
| 1709 | + |
| 1710 | + return 0; |
| 1711 | +} |
| 1712 | +EXPORT_SYMBOL_NS_GPL(thc_i2c_rx_int_delay_enable, "INTEL_THC"); |
| 1713 | + |
1643 | 1714 | MODULE_AUTHOR( "Xinpeng Sun <[email protected]>"); |
1644 | 1715 | MODULE_AUTHOR( "Even Xu <[email protected]>"); |
1645 | 1716 |
|
|
0 commit comments