Lines Matching +full:iqs624 +full:- +full:keys
1 // SPDX-License-Identifier: GPL-2.0+
3 * Azoteq IQS620A/621/622/624/625 Multi-Function Sensors
7 * These devices rely on application-specific register settings and calibration
9 * separate tool converts the GUIs' ASCII-based output into a standard firmware
14 * Link to conversion tool: https://github.com/jlabundy/iqs62x-h2bin.git
117 list_for_each_entry(fw_blk, &iqs62x->fw_blk_head, list) { in iqs62x_dev_init()
118 if (fw_blk->mask) in iqs62x_dev_init()
119 ret = regmap_update_bits(iqs62x->regmap, fw_blk->addr, in iqs62x_dev_init()
120 fw_blk->mask, *fw_blk->data); in iqs62x_dev_init()
122 ret = regmap_raw_write(iqs62x->regmap, fw_blk->addr, in iqs62x_dev_init()
123 fw_blk->data, fw_blk->len); in iqs62x_dev_init()
128 switch (iqs62x->dev_desc->prod_num) { in iqs62x_dev_init()
131 ret = regmap_read(iqs62x->regmap, in iqs62x_dev_init()
132 iqs62x->dev_desc->prox_settings, &val); in iqs62x_dev_init()
137 iqs62x->ui_sel = IQS62X_UI_SAR1; in iqs62x_dev_init()
142 ret = regmap_write(iqs62x->regmap, IQS620_GLBL_EVENT_MASK, in iqs62x_dev_init()
144 iqs62x->dev_desc->prox_mask | in iqs62x_dev_init()
145 iqs62x->dev_desc->sar_mask | in iqs62x_dev_init()
146 iqs62x->dev_desc->hall_mask | in iqs62x_dev_init()
147 iqs62x->dev_desc->hyst_mask | in iqs62x_dev_init()
148 iqs62x->dev_desc->temp_mask | in iqs62x_dev_init()
149 iqs62x->dev_desc->als_mask | in iqs62x_dev_init()
150 iqs62x->dev_desc->ir_mask); in iqs62x_dev_init()
156 ret = regmap_write(iqs62x->regmap, IQS624_HALL_UI, in iqs62x_dev_init()
169 * To protect against an unacceptably low user-entered value in iqs62x_dev_init()
171 * IQS624 as well. in iqs62x_dev_init()
173 ret = regmap_read(iqs62x->regmap, IQS624_INTERVAL_DIV, &val); in iqs62x_dev_init()
177 if (val >= iqs62x->dev_desc->interval_div) in iqs62x_dev_init()
180 ret = regmap_write(iqs62x->regmap, IQS624_INTERVAL_DIV, in iqs62x_dev_init()
181 iqs62x->dev_desc->interval_div); in iqs62x_dev_init()
186 ret = regmap_read(iqs62x->regmap, IQS62X_SYS_SETTINGS, &val); in iqs62x_dev_init()
191 clk_div = iqs62x->dev_desc->clk_div; in iqs62x_dev_init()
193 ret = regmap_write(iqs62x->regmap, IQS62X_SYS_SETTINGS, val | in iqs62x_dev_init()
200 ret = regmap_read_poll_timeout(iqs62x->regmap, IQS62X_SYS_FLAGS, val, in iqs62x_dev_init()
215 struct i2c_client *client = iqs62x->client; in iqs62x_firmware_parse()
224 while (pos < fw->size) { in iqs62x_firmware_parse()
225 if (pos + sizeof(*fw_rec) > fw->size) { in iqs62x_firmware_parse()
226 ret = -EINVAL; in iqs62x_firmware_parse()
229 fw_rec = (struct iqs62x_fw_rec *)(fw->data + pos); in iqs62x_firmware_parse()
232 if (pos + fw_rec->len - 1 > fw->size) { in iqs62x_firmware_parse()
233 ret = -EINVAL; in iqs62x_firmware_parse()
236 pos += fw_rec->len - 1; in iqs62x_firmware_parse()
238 switch (fw_rec->type) { in iqs62x_firmware_parse()
243 if (fw_rec->data == iqs62x->dev_desc->prod_num) in iqs62x_firmware_parse()
246 dev_err(&client->dev, in iqs62x_firmware_parse()
248 fw_rec->data); in iqs62x_firmware_parse()
249 ret = -EINVAL; in iqs62x_firmware_parse()
254 ret = regmap_write(iqs62x->regmap, in iqs62x_firmware_parse()
260 ret = regmap_read(iqs62x->regmap, in iqs62x_firmware_parse()
267 dev_err(&client->dev, in iqs62x_firmware_parse()
269 ret = -ENODATA; in iqs62x_firmware_parse()
274 if (hall_cal_index > fw_rec->len) { in iqs62x_firmware_parse()
275 ret = -EINVAL; in iqs62x_firmware_parse()
280 data = &fw_rec->data + hall_cal_index - 1; in iqs62x_firmware_parse()
285 if (fw_rec->len < (sizeof(mask) + sizeof(*data))) { in iqs62x_firmware_parse()
286 ret = -EINVAL; in iqs62x_firmware_parse()
290 mask = fw_rec->data; in iqs62x_firmware_parse()
291 data = &fw_rec->data + sizeof(mask); in iqs62x_firmware_parse()
297 data = &fw_rec->data; in iqs62x_firmware_parse()
298 len = fw_rec->len; in iqs62x_firmware_parse()
302 dev_err(&client->dev, in iqs62x_firmware_parse()
304 fw_rec->type); in iqs62x_firmware_parse()
305 ret = -EINVAL; in iqs62x_firmware_parse()
311 fw_blk = devm_kzalloc(&client->dev, in iqs62x_firmware_parse()
315 ret = -ENOMEM; in iqs62x_firmware_parse()
319 fw_blk->addr = fw_rec->addr; in iqs62x_firmware_parse()
320 fw_blk->mask = mask; in iqs62x_firmware_parse()
321 fw_blk->len = len; in iqs62x_firmware_parse()
322 memcpy(fw_blk->data, data, len); in iqs62x_firmware_parse()
324 list_add(&fw_blk->list, &iqs62x->fw_blk_head); in iqs62x_firmware_parse()
444 struct i2c_client *client = iqs62x->client; in iqs62x_irq()
456 * broadcast to any interested sub-device drivers. in iqs62x_irq()
458 ret = regmap_raw_read(iqs62x->regmap, IQS62X_SYS_FLAGS, event_map, in iqs62x_irq()
461 dev_err(&client->dev, "Failed to read device status: %d\n", in iqs62x_irq()
467 event_reg = iqs62x->dev_desc->event_regs[iqs62x->ui_sel][i]; in iqs62x_irq()
492 event_map[i] <<= iqs62x->dev_desc->hyst_shift; in iqs62x_irq()
517 * are restored and any interested sub-device drivers are notified. in iqs62x_irq()
520 dev_err(&client->dev, "Unexpected device reset\n"); in iqs62x_irq()
524 dev_err(&client->dev, in iqs62x_irq()
525 "Failed to re-initialize device: %d\n", ret); in iqs62x_irq()
530 ret = blocking_notifier_call_chain(&iqs62x->nh, event_flags, in iqs62x_irq()
548 struct i2c_client *client = iqs62x->client; in iqs62x_firmware_load()
554 dev_err(&client->dev, "Failed to parse firmware: %d\n", in iqs62x_firmware_load()
562 dev_err(&client->dev, "Failed to initialize device: %d\n", ret); in iqs62x_firmware_load()
566 ret = devm_request_threaded_irq(&client->dev, client->irq, in iqs62x_firmware_load()
568 client->name, iqs62x); in iqs62x_firmware_load()
570 dev_err(&client->dev, "Failed to request IRQ: %d\n", ret); in iqs62x_firmware_load()
574 ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE, in iqs62x_firmware_load()
575 iqs62x->dev_desc->sub_devs, in iqs62x_firmware_load()
576 iqs62x->dev_desc->num_sub_devs, in iqs62x_firmware_load()
579 dev_err(&client->dev, "Failed to add sub-devices: %d\n", ret); in iqs62x_firmware_load()
582 complete_all(&iqs62x->fw_done); in iqs62x_firmware_load()
587 .name = "iqs62x-keys",
588 .of_compatible = "azoteq,iqs620a-keys",
591 .name = "iqs620a-pwm",
592 .of_compatible = "azoteq,iqs620a-pwm",
594 { .name = "iqs620at-temp", },
599 .name = "iqs62x-keys",
600 .of_compatible = "azoteq,iqs620a-keys",
603 .name = "iqs620a-pwm",
604 .of_compatible = "azoteq,iqs620a-pwm",
610 .name = "iqs62x-keys",
611 .of_compatible = "azoteq,iqs621-keys",
613 { .name = "iqs621-als", },
618 .name = "iqs62x-keys",
619 .of_compatible = "azoteq,iqs622-keys",
621 { .name = "iqs621-als", },
626 .name = "iqs62x-keys",
627 .of_compatible = "azoteq,iqs624-keys",
629 { .name = "iqs624-pos", },
634 .name = "iqs62x-keys",
635 .of_compatible = "azoteq,iqs625-keys",
637 { .name = "iqs624-pos", },
842 .dev_name = "iqs624",
853 .fw_name = "iqs624.bin",
888 iqs62x = devm_kzalloc(&client->dev, sizeof(*iqs62x), GFP_KERNEL); in iqs62x_probe()
890 return -ENOMEM; in iqs62x_probe()
893 iqs62x->client = client; in iqs62x_probe()
895 BLOCKING_INIT_NOTIFIER_HEAD(&iqs62x->nh); in iqs62x_probe()
896 INIT_LIST_HEAD(&iqs62x->fw_blk_head); in iqs62x_probe()
897 init_completion(&iqs62x->fw_done); in iqs62x_probe()
899 iqs62x->regmap = devm_regmap_init_i2c(client, &iqs62x_map_config); in iqs62x_probe()
900 if (IS_ERR(iqs62x->regmap)) { in iqs62x_probe()
901 ret = PTR_ERR(iqs62x->regmap); in iqs62x_probe()
902 dev_err(&client->dev, "Failed to initialize register map: %d\n", in iqs62x_probe()
907 ret = regmap_raw_read(iqs62x->regmap, IQS62X_PROD_NUM, &info, in iqs62x_probe()
914 * numbers. It then determines if the device is factory-calibrated by in iqs62x_probe()
929 iqs62x->dev_desc = &iqs62x_devs[i]; in iqs62x_probe()
931 if (info.sw_num < iqs62x->dev_desc->sw_num) in iqs62x_probe()
943 for (j = 0; j < iqs62x->dev_desc->num_cal_regs; j++) { in iqs62x_probe()
944 ret = regmap_read(iqs62x->regmap, in iqs62x_probe()
945 iqs62x->dev_desc->cal_regs[j], &val); in iqs62x_probe()
960 if (j == iqs62x->dev_desc->num_cal_regs) in iqs62x_probe()
964 if (!iqs62x->dev_desc) { in iqs62x_probe()
965 dev_err(&client->dev, "Unrecognized product number: 0x%02X\n", in iqs62x_probe()
967 return -EINVAL; in iqs62x_probe()
971 dev_err(&client->dev, "Unrecognized software number: 0x%02X\n", in iqs62x_probe()
973 return -EINVAL; in iqs62x_probe()
977 dev_err(&client->dev, "Uncalibrated device\n"); in iqs62x_probe()
978 return -ENODATA; in iqs62x_probe()
981 device_property_read_string(&client->dev, "firmware-name", &fw_name); in iqs62x_probe()
984 fw_name ? : iqs62x->dev_desc->fw_name, in iqs62x_probe()
985 &client->dev, GFP_KERNEL, iqs62x, in iqs62x_probe()
988 dev_err(&client->dev, "Failed to request firmware: %d\n", ret); in iqs62x_probe()
997 wait_for_completion(&iqs62x->fw_done); in iqs62x_remove()
1007 wait_for_completion(&iqs62x->fw_done); in iqs62x_suspend()
1013 ret = regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS, in iqs62x_suspend()
1018 return regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS, in iqs62x_suspend()
1028 ret = regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS, in iqs62x_resume()
1034 return regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS, in iqs62x_resume()
1044 { .compatible = "azoteq,iqs624" },
1062 MODULE_DESCRIPTION("Azoteq IQS620A/621/622/624/625 Multi-Function Sensors");