Skip to content

Commit 0b1fca9

Browse files
sunxinpengJiri Kosina
authored andcommitted
HID: intel-thc-hid: intel-quicki2c: support ACPI config for advanced features
There is a new BIOS enhancement that adds the capability to configure the following two features of I2C subsystem introduced in commit 1ed0b48 ("Intel-thc: Introduce max input size control") and commit 3f2a921 ("Intel-thc: Introduce interrupt delay control"): - Max input size control - Interrupt delay control As BIOS is used for the configuration of these two features, change driver data usage to indicate hardware capability, and add corresponding ACPI configuration support in QuickI2C driver. Signed-off-by: Xinpeng Sun <xinpeng.sun@intel.com> Tested-by: Rui Zhang <rui1.zhang@intel.com> Reviewed-by: Even Xu <even.xu@intel.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
1 parent 71b2876 commit 0b1fca9

2 files changed

Lines changed: 53 additions & 10 deletions

File tree

drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
static struct quicki2c_ddata ptl_ddata = {
2525
.max_detect_size = MAX_RX_DETECT_SIZE_PTL,
26+
.max_interrupt_delay = MAX_RX_INTERRUPT_DELAY,
2627
};
2728

2829
/* THC QuickI2C ACPI method to get device properties */
@@ -200,6 +201,21 @@ static int quicki2c_get_acpi_resources(struct quicki2c_device *qcdev)
200201
return -EOPNOTSUPP;
201202
}
202203

204+
if (qcdev->ddata) {
205+
qcdev->i2c_max_frame_size_enable = i2c_config.FSEN;
206+
qcdev->i2c_int_delay_enable = i2c_config.INDE;
207+
208+
if (i2c_config.FSVL <= qcdev->ddata->max_detect_size)
209+
qcdev->i2c_max_frame_size = i2c_config.FSVL;
210+
else
211+
qcdev->i2c_max_frame_size = qcdev->ddata->max_detect_size;
212+
213+
if (i2c_config.INDV <= qcdev->ddata->max_interrupt_delay)
214+
qcdev->i2c_int_delay = i2c_config.INDV;
215+
else
216+
qcdev->i2c_int_delay = qcdev->ddata->max_interrupt_delay;
217+
}
218+
203219
return 0;
204220
}
205221

@@ -441,17 +457,24 @@ static void quicki2c_dma_adv_enable(struct quicki2c_device *qcdev)
441457
* max input length <= THC detect capability, enable the feature with device
442458
* max input length.
443459
*/
444-
if (qcdev->ddata->max_detect_size >=
445-
le16_to_cpu(qcdev->dev_desc.max_input_len)) {
446-
thc_i2c_set_rx_max_size(qcdev->thc_hw,
447-
le16_to_cpu(qcdev->dev_desc.max_input_len));
460+
if (qcdev->i2c_max_frame_size_enable) {
461+
if (qcdev->i2c_max_frame_size >=
462+
le16_to_cpu(qcdev->dev_desc.max_input_len)) {
463+
thc_i2c_set_rx_max_size(qcdev->thc_hw,
464+
le16_to_cpu(qcdev->dev_desc.max_input_len));
465+
} else {
466+
dev_warn(qcdev->dev,
467+
"Max frame size is smaller than hid max input length!");
468+
thc_i2c_set_rx_max_size(qcdev->thc_hw,
469+
le16_to_cpu(qcdev->i2c_max_frame_size));
470+
}
448471
thc_i2c_rx_max_size_enable(qcdev->thc_hw, true);
449472
}
450473

451474
/* If platform supports interrupt delay feature, enable it with given delay */
452-
if (qcdev->ddata->interrupt_delay) {
475+
if (qcdev->i2c_int_delay_enable) {
453476
thc_i2c_set_rx_int_delay(qcdev->thc_hw,
454-
qcdev->ddata->interrupt_delay);
477+
qcdev->i2c_int_delay * 10);
455478
thc_i2c_rx_int_delay_enable(qcdev->thc_hw, true);
456479
}
457480
}
@@ -464,10 +487,10 @@ static void quicki2c_dma_adv_enable(struct quicki2c_device *qcdev)
464487
*/
465488
static void quicki2c_dma_adv_disable(struct quicki2c_device *qcdev)
466489
{
467-
if (qcdev->ddata->max_detect_size)
490+
if (qcdev->i2c_max_frame_size_enable)
468491
thc_i2c_rx_max_size_enable(qcdev->thc_hw, false);
469492

470-
if (qcdev->ddata->interrupt_delay)
493+
if (qcdev->i2c_int_delay_enable)
471494
thc_i2c_rx_int_delay_enable(qcdev->thc_hw, false);
472495
}
473496

drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838

3939
/* PTL Max packet size detection capability is 255 Bytes */
4040
#define MAX_RX_DETECT_SIZE_PTL 255
41+
/* Max interrupt delay capability is 2.56ms */
42+
#define MAX_RX_INTERRUPT_DELAY 256
4143

4244
/* Default interrupt delay is 1ms, suitable for most devices */
4345
#define DEFAULT_INTERRUPT_DELAY_US (1 * USEC_PER_MSEC)
@@ -101,6 +103,10 @@ struct quicki2c_subip_acpi_parameter {
101103
* @HMTD: High Speed Mode Plus (3.4Mbits/sec) Serial Data Line Transmit HOLD Period
102104
* @HMRD: High Speed Mode Plus (3.4Mbits/sec) Serial Data Line Receive HOLD Period
103105
* @HMSL: Maximum length (in ic_clk_cycles) of suppressed spikes in High Speed Mode
106+
* @FSEN: Maximum Frame Size Feature Enable Control
107+
* @FSVL: Maximum Frame Size Value (unit in Bytes)
108+
* @INDE: Interrupt Delay Feature Enable Control
109+
* @INDV: Interrupt Delay Value (unit in 10 us)
104110
*
105111
* Those properties get from QUICKI2C_ACPI_METHOD_NAME_ISUB method, used for
106112
* I2C timing configure.
@@ -127,17 +133,22 @@ struct quicki2c_subip_acpi_config {
127133
u64 HMTD;
128134
u64 HMRD;
129135
u64 HMSL;
136+
137+
u64 FSEN;
138+
u64 FSVL;
139+
u64 INDE;
140+
u64 INDV;
130141
u8 reserved;
131142
};
132143

133144
/**
134145
* struct quicki2c_ddata - Driver specific data for quicki2c device
135146
* @max_detect_size: Identify max packet size detect for rx
136-
* @interrupt_delay: Identify interrupt detect delay for rx
147+
* @interrupt_delay: Identify max interrupt detect delay for rx
137148
*/
138149
struct quicki2c_ddata {
139150
u32 max_detect_size;
140-
u32 interrupt_delay;
151+
u32 max_interrupt_delay;
141152
};
142153

143154
struct device;
@@ -170,6 +181,10 @@ struct acpi_device;
170181
* @report_len: The length of input/output report packet
171182
* @reset_ack_wq: Workqueue for waiting reset response from device
172183
* @reset_ack: Indicate reset response received or not
184+
* @i2c_max_frame_size_enable: Indicate max frame size feature enabled or not
185+
* @i2c_max_frame_size: Max RX frame size (unit in Bytes)
186+
* @i2c_int_delay_enable: Indicate interrupt delay feature enabled or not
187+
* @i2c_int_delay: Interrupt detection delay value (unit in 10 us)
173188
*/
174189
struct quicki2c_device {
175190
struct device *dev;
@@ -200,6 +215,11 @@ struct quicki2c_device {
200215

201216
wait_queue_head_t reset_ack_wq;
202217
bool reset_ack;
218+
219+
u32 i2c_max_frame_size_enable;
220+
u32 i2c_max_frame_size;
221+
u32 i2c_int_delay_enable;
222+
u32 i2c_int_delay;
203223
};
204224

205225
#endif /* _QUICKI2C_DEV_H_ */

0 commit comments

Comments
 (0)