Skip to content

Commit e86df90

Browse files
sunxinpengJiri Kosina
authored andcommitted
HID: intel-thc-hid: intel-thc: Add THC LTR interfaces
THC supports LTR configuration and runtimely mode switching. There are two LTR modes: Active LTR and Low Power LTR. THC hardware layer provides APIs for LTR configuration and mode switching. Co-developed-by: Even Xu <[email protected]> Signed-off-by: Even Xu <[email protected]> Signed-off-by: Xinpeng Sun <[email protected]> Tested-by: Rui Zhang <[email protected]> Tested-by: Mark Pearson <[email protected]> Reviewed-by: Srinivas Pandruvada <[email protected]> Reviewed-by: Mark Pearson <[email protected]> Tested-by: Aaron Ma <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent a688404 commit e86df90

File tree

3 files changed

+138
-0
lines changed

3 files changed

+138
-0
lines changed

drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,120 @@ void thc_set_pio_interrupt_support(struct thc_device *dev, bool supported)
688688
}
689689
EXPORT_SYMBOL_NS_GPL(thc_set_pio_interrupt_support, "INTEL_THC");
690690

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+
*/
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+
*/
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+
*/
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, &ltr_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+
691805
MODULE_AUTHOR("Xinpeng Sun <[email protected]>");
692806
MODULE_AUTHOR("Even Xu <[email protected]>");
693807

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,8 @@ void thc_int_trigger_type_select(struct thc_device *dev, bool edge_trigger);
6868
void thc_interrupt_enable(struct thc_device *dev, bool int_enable);
6969
void thc_set_pio_interrupt_support(struct thc_device *dev, bool supported);
7070
int thc_interrupt_quiesce(const struct thc_device *dev, bool int_quiesce);
71+
void thc_ltr_config(struct thc_device *dev, u32 active_ltr_us, u32 lp_ltr_us);
72+
void thc_change_ltr_mode(struct thc_device *dev, u32 ltr_mode);
73+
void thc_ltr_unconfig(struct thc_device *dev);
7174

7275
#endif /* _INTEL_THC_DEV_H_ */

drivers/hid/intel-thc-hid/intel-thc/intel-thc-hw.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,27 @@
656656
/* Interrupt Quiesce default timeout value */
657657
#define THC_QUIESCE_EN_TIMEOUT_US USEC_PER_SEC /* 1s */
658658

659+
/* LTR definition */
660+
/*
661+
* THC uses scale to calculate final LTR value.
662+
* Scale is geometric progression of 2^5 step, starting from 2^0.
663+
* For example, THC_LTR_SCALE_2(2) means 2^(5 * 2) = 1024, unit is ns.
664+
*/
665+
#define THC_LTR_SCALE_0 0
666+
#define THC_LTR_SCALE_1 1
667+
#define THC_LTR_SCALE_2 2
668+
#define THC_LTR_SCALE_3 3
669+
#define THC_LTR_SCALE_4 4
670+
#define THC_LTR_SCALE_5 5
671+
#define THC_LTR_MODE_ACTIVE 0
672+
#define THC_LTR_MODE_LP 1
673+
#define THC_LTR_MIN_VAL_SCALE_3 BIT(10)
674+
#define THC_LTR_MAX_VAL_SCALE_3 BIT(15)
675+
#define THC_LTR_MIN_VAL_SCALE_4 BIT(15)
676+
#define THC_LTR_MAX_VAL_SCALE_4 BIT(20)
677+
#define THC_LTR_MIN_VAL_SCALE_5 BIT(20)
678+
#define THC_LTR_MAX_VAL_SCALE_5 BIT(25)
679+
659680
/*
660681
* THC PIO opcode default value
661682
* @THC_PIO_OP_SPI_TIC_READ: THC opcode for SPI PIO read

0 commit comments

Comments
 (0)