Skip to content

Commit 992bbc9

Browse files
jlabundydtor
authored andcommitted
Input: iqs269a - add support for OTP variants
This patch adds support for each available OTP variant of the device. The OTP configuration cannot be read over I2C, so it is derived from a compatible string instead. Early revisions of the D0 order code require their OTP-enabled func- tionality to be manually restored following a soft reset; this patch accommodates this erratum as well. Signed-off-by: Jeff LaBundy <jeff@labundy.com> Link: https://lore.kernel.org/r/ZZMaZbdk6iAKUjlm@nixie71 Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
1 parent 56c083e commit 992bbc9

File tree

1 file changed

+89
-3
lines changed

1 file changed

+89
-3
lines changed

drivers/input/misc/iqs269a.c

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@
102102
#define IQS269_MISC_B_TRACKING_UI_ENABLE BIT(4)
103103
#define IQS269_MISC_B_FILT_STR_SLIDER GENMASK(1, 0)
104104

105+
#define IQS269_TOUCH_HOLD_SLIDER_SEL 0x89
106+
#define IQS269_TOUCH_HOLD_DEFAULT 0x14
107+
#define IQS269_TOUCH_HOLD_MS_MIN 256
108+
#define IQS269_TOUCH_HOLD_MS_MAX 65280
109+
105110
#define IQS269_TIMEOUT_TAP_MS_MAX 4080
106111
#define IQS269_TIMEOUT_SWIPE_MS_MAX 4080
107112
#define IQS269_THRESH_SWIPE_MAX 255
@@ -151,6 +156,10 @@
151156

152157
#define IQS269_MAX_REG 0xFF
153158

159+
#define IQS269_OTP_OPTION_DEFAULT 0x00
160+
#define IQS269_OTP_OPTION_TWS 0xD0
161+
#define IQS269_OTP_OPTION_HOLD BIT(7)
162+
154163
#define IQS269_NUM_CH 8
155164
#define IQS269_NUM_SL 2
156165

@@ -315,6 +324,7 @@ struct iqs269_private {
315324
struct input_dev *slider[IQS269_NUM_SL];
316325
unsigned int keycode[ARRAY_SIZE(iqs269_events) * IQS269_NUM_CH];
317326
unsigned int sl_code[IQS269_NUM_SL][IQS269_NUM_GESTURES];
327+
unsigned int otp_option;
318328
unsigned int ch_num;
319329
bool hall_enable;
320330
bool ati_current;
@@ -325,6 +335,14 @@ static enum iqs269_slider_id iqs269_slider_type(struct iqs269_private *iqs269,
325335
{
326336
int i;
327337

338+
/*
339+
* Slider 1 is unavailable if the touch-and-hold option is enabled via
340+
* OTP. In that case, the channel selection register is repurposed for
341+
* the touch-and-hold timer ceiling.
342+
*/
343+
if (slider_num && (iqs269->otp_option & IQS269_OTP_OPTION_HOLD))
344+
return IQS269_SLIDER_NONE;
345+
328346
if (!iqs269->sys_reg.slider_select[slider_num])
329347
return IQS269_SLIDER_NONE;
330348

@@ -565,7 +583,8 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269,
565583
if (fwnode_property_present(ch_node, "azoteq,slider0-select"))
566584
iqs269->sys_reg.slider_select[0] |= BIT(reg);
567585

568-
if (fwnode_property_present(ch_node, "azoteq,slider1-select"))
586+
if (fwnode_property_present(ch_node, "azoteq,slider1-select") &&
587+
!(iqs269->otp_option & IQS269_OTP_OPTION_HOLD))
569588
iqs269->sys_reg.slider_select[1] |= BIT(reg);
570589

571590
ch_reg = &iqs269->sys_reg.ch_reg[reg];
@@ -990,7 +1009,43 @@ static int iqs269_parse_prop(struct iqs269_private *iqs269)
9901009
sys_reg->blocking = 0;
9911010

9921011
sys_reg->slider_select[0] = 0;
993-
sys_reg->slider_select[1] = 0;
1012+
1013+
/*
1014+
* If configured via OTP to do so, the device asserts a pulse on the
1015+
* GPIO4 pin for approximately 60 ms once a selected channel is held
1016+
* in a state of touch for a configurable length of time.
1017+
*
1018+
* In that case, the register used for slider 1 channel selection is
1019+
* repurposed for the touch-and-hold timer ceiling.
1020+
*/
1021+
if (iqs269->otp_option & IQS269_OTP_OPTION_HOLD) {
1022+
if (!device_property_read_u32(&client->dev,
1023+
"azoteq,touch-hold-ms", &val)) {
1024+
if (val < IQS269_TOUCH_HOLD_MS_MIN ||
1025+
val > IQS269_TOUCH_HOLD_MS_MAX) {
1026+
dev_err(&client->dev,
1027+
"Invalid touch-and-hold ceiling: %u\n",
1028+
val);
1029+
return -EINVAL;
1030+
}
1031+
1032+
sys_reg->slider_select[1] = val / 256;
1033+
} else if (iqs269->ver_info.fw_num < IQS269_VER_INFO_FW_NUM_3) {
1034+
/*
1035+
* The default touch-and-hold timer ceiling initially
1036+
* read from early revisions of silicon is invalid if
1037+
* the device experienced a soft reset between power-
1038+
* on and the read operation.
1039+
*
1040+
* To protect against this case, explicitly cache the
1041+
* default value so that it is restored each time the
1042+
* device is re-initialized.
1043+
*/
1044+
sys_reg->slider_select[1] = IQS269_TOUCH_HOLD_DEFAULT;
1045+
}
1046+
} else {
1047+
sys_reg->slider_select[1] = 0;
1048+
}
9941049

9951050
sys_reg->event_mask = ~((u8)IQS269_EVENT_MASK_SYS);
9961051

@@ -1137,12 +1192,30 @@ static int iqs269_parse_prop(struct iqs269_private *iqs269)
11371192
return 0;
11381193
}
11391194

1195+
static const struct reg_sequence iqs269_tws_init[] = {
1196+
{ IQS269_TOUCH_HOLD_SLIDER_SEL, IQS269_TOUCH_HOLD_DEFAULT },
1197+
{ 0xF0, 0x580F },
1198+
{ 0xF0, 0x59EF },
1199+
};
1200+
11401201
static int iqs269_dev_init(struct iqs269_private *iqs269)
11411202
{
11421203
int error;
11431204

11441205
mutex_lock(&iqs269->lock);
11451206

1207+
/*
1208+
* Early revisions of silicon require the following workaround in order
1209+
* to restore any OTP-enabled functionality after a soft reset.
1210+
*/
1211+
if (iqs269->otp_option == IQS269_OTP_OPTION_TWS &&
1212+
iqs269->ver_info.fw_num < IQS269_VER_INFO_FW_NUM_3) {
1213+
error = regmap_multi_reg_write(iqs269->regmap, iqs269_tws_init,
1214+
ARRAY_SIZE(iqs269_tws_init));
1215+
if (error)
1216+
goto err_mutex;
1217+
}
1218+
11461219
error = regmap_update_bits(iqs269->regmap, IQS269_HALL_UI,
11471220
IQS269_HALL_UI_ENABLE,
11481221
iqs269->hall_enable ? ~0 : 0);
@@ -1779,6 +1852,8 @@ static int iqs269_probe(struct i2c_client *client)
17791852
mutex_init(&iqs269->lock);
17801853
init_completion(&iqs269->ati_done);
17811854

1855+
iqs269->otp_option = (uintptr_t)device_get_match_data(&client->dev);
1856+
17821857
error = regmap_raw_read(iqs269->regmap, IQS269_VER_INFO,
17831858
&iqs269->ver_info, sizeof(iqs269->ver_info));
17841859
if (error)
@@ -1889,7 +1964,18 @@ static int iqs269_resume(struct device *dev)
18891964
static DEFINE_SIMPLE_DEV_PM_OPS(iqs269_pm, iqs269_suspend, iqs269_resume);
18901965

18911966
static const struct of_device_id iqs269_of_match[] = {
1892-
{ .compatible = "azoteq,iqs269a" },
1967+
{
1968+
.compatible = "azoteq,iqs269a",
1969+
.data = (void *)IQS269_OTP_OPTION_DEFAULT,
1970+
},
1971+
{
1972+
.compatible = "azoteq,iqs269a-00",
1973+
.data = (void *)IQS269_OTP_OPTION_DEFAULT,
1974+
},
1975+
{
1976+
.compatible = "azoteq,iqs269a-d0",
1977+
.data = (void *)IQS269_OTP_OPTION_TWS,
1978+
},
18931979
{ }
18941980
};
18951981
MODULE_DEVICE_TABLE(of, iqs269_of_match);

0 commit comments

Comments
 (0)