0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/completion.h>
0018 #include <linux/delay.h>
0019 #include <linux/device.h>
0020 #include <linux/err.h>
0021 #include <linux/firmware.h>
0022 #include <linux/i2c.h>
0023 #include <linux/interrupt.h>
0024 #include <linux/kernel.h>
0025 #include <linux/list.h>
0026 #include <linux/mfd/core.h>
0027 #include <linux/mfd/iqs62x.h>
0028 #include <linux/module.h>
0029 #include <linux/notifier.h>
0030 #include <linux/of_device.h>
0031 #include <linux/property.h>
0032 #include <linux/regmap.h>
0033 #include <linux/slab.h>
0034 #include <asm/unaligned.h>
0035
0036 #define IQS62X_PROD_NUM 0x00
0037
0038 #define IQS62X_SYS_FLAGS 0x10
0039
0040 #define IQS620_HALL_FLAGS 0x16
0041 #define IQS621_HALL_FLAGS 0x19
0042 #define IQS622_HALL_FLAGS IQS621_HALL_FLAGS
0043
0044 #define IQS624_INTERVAL_NUM 0x18
0045 #define IQS625_INTERVAL_NUM 0x12
0046
0047 #define IQS622_PROX_SETTINGS_4 0x48
0048 #define IQS620_PROX_SETTINGS_4 0x50
0049 #define IQS620_PROX_SETTINGS_4_SAR_EN BIT(7)
0050
0051 #define IQS621_ALS_CAL_DIV_LUX 0x82
0052 #define IQS621_ALS_CAL_DIV_IR 0x83
0053
0054 #define IQS620_TEMP_CAL_MULT 0xC2
0055 #define IQS620_TEMP_CAL_DIV 0xC3
0056 #define IQS620_TEMP_CAL_OFFS 0xC4
0057
0058 #define IQS62X_SYS_SETTINGS 0xD0
0059 #define IQS62X_SYS_SETTINGS_ACK_RESET BIT(6)
0060 #define IQS62X_SYS_SETTINGS_EVENT_MODE BIT(5)
0061 #define IQS62X_SYS_SETTINGS_CLK_DIV BIT(4)
0062 #define IQS62X_SYS_SETTINGS_COMM_ATI BIT(3)
0063 #define IQS62X_SYS_SETTINGS_REDO_ATI BIT(1)
0064
0065 #define IQS62X_PWR_SETTINGS 0xD2
0066 #define IQS62X_PWR_SETTINGS_DIS_AUTO BIT(5)
0067 #define IQS62X_PWR_SETTINGS_PWR_MODE_MASK (BIT(4) | BIT(3))
0068 #define IQS62X_PWR_SETTINGS_PWR_MODE_HALT (BIT(4) | BIT(3))
0069 #define IQS62X_PWR_SETTINGS_PWR_MODE_NORM 0
0070
0071 #define IQS62X_OTP_CMD 0xF0
0072 #define IQS62X_OTP_CMD_FG3 0x13
0073 #define IQS62X_OTP_DATA 0xF1
0074 #define IQS62X_MAX_REG 0xFF
0075
0076 #define IQS62X_HALL_CAL_MASK GENMASK(3, 0)
0077
0078 #define IQS62X_FW_REC_TYPE_INFO 0
0079 #define IQS62X_FW_REC_TYPE_PROD 1
0080 #define IQS62X_FW_REC_TYPE_HALL 2
0081 #define IQS62X_FW_REC_TYPE_MASK 3
0082 #define IQS62X_FW_REC_TYPE_DATA 4
0083
0084 #define IQS62X_ATI_STARTUP_MS 350
0085 #define IQS62X_FILT_SETTLE_MS 250
0086
0087 struct iqs62x_fw_rec {
0088 u8 type;
0089 u8 addr;
0090 u8 len;
0091 u8 data;
0092 } __packed;
0093
0094 struct iqs62x_fw_blk {
0095 struct list_head list;
0096 u8 addr;
0097 u8 mask;
0098 u8 len;
0099 u8 data[];
0100 };
0101
0102 struct iqs62x_info {
0103 u8 prod_num;
0104 u8 sw_num;
0105 u8 hw_num;
0106 } __packed;
0107
0108 static int iqs62x_dev_init(struct iqs62x_core *iqs62x)
0109 {
0110 struct iqs62x_fw_blk *fw_blk;
0111 unsigned int val;
0112 int ret;
0113
0114 list_for_each_entry(fw_blk, &iqs62x->fw_blk_head, list) {
0115
0116
0117
0118
0119 if (fw_blk->addr == IQS62X_SYS_SETTINGS &&
0120 *fw_blk->data & IQS62X_SYS_SETTINGS_CLK_DIV)
0121 msleep(IQS62X_ATI_STARTUP_MS);
0122
0123 if (fw_blk->mask)
0124 ret = regmap_update_bits(iqs62x->regmap, fw_blk->addr,
0125 fw_blk->mask, *fw_blk->data);
0126 else
0127 ret = regmap_raw_write(iqs62x->regmap, fw_blk->addr,
0128 fw_blk->data, fw_blk->len);
0129 if (ret)
0130 return ret;
0131 }
0132
0133 switch (iqs62x->dev_desc->prod_num) {
0134 case IQS620_PROD_NUM:
0135 case IQS622_PROD_NUM:
0136 ret = regmap_read(iqs62x->regmap,
0137 iqs62x->dev_desc->prox_settings, &val);
0138 if (ret)
0139 return ret;
0140
0141 if (val & IQS620_PROX_SETTINGS_4_SAR_EN)
0142 iqs62x->ui_sel = IQS62X_UI_SAR1;
0143 fallthrough;
0144
0145 case IQS621_PROD_NUM:
0146 ret = regmap_write(iqs62x->regmap, IQS620_GLBL_EVENT_MASK,
0147 IQS620_GLBL_EVENT_MASK_PMU |
0148 iqs62x->dev_desc->prox_mask |
0149 iqs62x->dev_desc->sar_mask |
0150 iqs62x->dev_desc->hall_mask |
0151 iqs62x->dev_desc->hyst_mask |
0152 iqs62x->dev_desc->temp_mask |
0153 iqs62x->dev_desc->als_mask |
0154 iqs62x->dev_desc->ir_mask);
0155 if (ret)
0156 return ret;
0157 break;
0158
0159 default:
0160 ret = regmap_write(iqs62x->regmap, IQS624_HALL_UI,
0161 IQS624_HALL_UI_WHL_EVENT |
0162 IQS624_HALL_UI_INT_EVENT |
0163 IQS624_HALL_UI_AUTO_CAL);
0164 if (ret)
0165 return ret;
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177 ret = regmap_read(iqs62x->regmap, IQS624_INTERVAL_DIV, &val);
0178 if (ret)
0179 return ret;
0180
0181 if (val >= iqs62x->dev_desc->interval_div)
0182 break;
0183
0184 ret = regmap_write(iqs62x->regmap, IQS624_INTERVAL_DIV,
0185 iqs62x->dev_desc->interval_div);
0186 if (ret)
0187 return ret;
0188 }
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200 ret = regmap_update_bits(iqs62x->regmap, IQS62X_SYS_SETTINGS,
0201 IQS62X_SYS_SETTINGS_ACK_RESET |
0202 IQS62X_SYS_SETTINGS_EVENT_MODE |
0203 IQS62X_SYS_SETTINGS_COMM_ATI |
0204 IQS62X_SYS_SETTINGS_REDO_ATI,
0205 IQS62X_SYS_SETTINGS_ACK_RESET |
0206 IQS62X_SYS_SETTINGS_REDO_ATI);
0207 if (ret)
0208 return ret;
0209
0210
0211
0212
0213
0214
0215 usleep_range(5000, 5100);
0216
0217 return 0;
0218 }
0219
0220 static int iqs62x_firmware_parse(struct iqs62x_core *iqs62x,
0221 const struct firmware *fw)
0222 {
0223 struct i2c_client *client = iqs62x->client;
0224 struct iqs62x_fw_rec *fw_rec;
0225 struct iqs62x_fw_blk *fw_blk;
0226 unsigned int val;
0227 size_t pos = 0;
0228 int ret = 0;
0229 u8 mask, len, *data;
0230 u8 hall_cal_index = 0;
0231
0232 while (pos < fw->size) {
0233 if (pos + sizeof(*fw_rec) > fw->size) {
0234 ret = -EINVAL;
0235 break;
0236 }
0237 fw_rec = (struct iqs62x_fw_rec *)(fw->data + pos);
0238 pos += sizeof(*fw_rec);
0239
0240 if (pos + fw_rec->len - 1 > fw->size) {
0241 ret = -EINVAL;
0242 break;
0243 }
0244 pos += fw_rec->len - 1;
0245
0246 switch (fw_rec->type) {
0247 case IQS62X_FW_REC_TYPE_INFO:
0248 continue;
0249
0250 case IQS62X_FW_REC_TYPE_PROD:
0251 if (fw_rec->data == iqs62x->dev_desc->prod_num)
0252 continue;
0253
0254 dev_err(&client->dev,
0255 "Incompatible product number: 0x%02X\n",
0256 fw_rec->data);
0257 ret = -EINVAL;
0258 break;
0259
0260 case IQS62X_FW_REC_TYPE_HALL:
0261 if (!hall_cal_index) {
0262 ret = regmap_write(iqs62x->regmap,
0263 IQS62X_OTP_CMD,
0264 IQS62X_OTP_CMD_FG3);
0265 if (ret)
0266 break;
0267
0268 ret = regmap_read(iqs62x->regmap,
0269 IQS62X_OTP_DATA, &val);
0270 if (ret)
0271 break;
0272
0273 hall_cal_index = val & IQS62X_HALL_CAL_MASK;
0274 if (!hall_cal_index) {
0275 dev_err(&client->dev,
0276 "Uncalibrated device\n");
0277 ret = -ENODATA;
0278 break;
0279 }
0280 }
0281
0282 if (hall_cal_index > fw_rec->len) {
0283 ret = -EINVAL;
0284 break;
0285 }
0286
0287 mask = 0;
0288 data = &fw_rec->data + hall_cal_index - 1;
0289 len = sizeof(*data);
0290 break;
0291
0292 case IQS62X_FW_REC_TYPE_MASK:
0293 if (fw_rec->len < (sizeof(mask) + sizeof(*data))) {
0294 ret = -EINVAL;
0295 break;
0296 }
0297
0298 mask = fw_rec->data;
0299 data = &fw_rec->data + sizeof(mask);
0300 len = sizeof(*data);
0301 break;
0302
0303 case IQS62X_FW_REC_TYPE_DATA:
0304 mask = 0;
0305 data = &fw_rec->data;
0306 len = fw_rec->len;
0307 break;
0308
0309 default:
0310 dev_err(&client->dev,
0311 "Unrecognized record type: 0x%02X\n",
0312 fw_rec->type);
0313 ret = -EINVAL;
0314 }
0315
0316 if (ret)
0317 break;
0318
0319 fw_blk = devm_kzalloc(&client->dev,
0320 struct_size(fw_blk, data, len),
0321 GFP_KERNEL);
0322 if (!fw_blk) {
0323 ret = -ENOMEM;
0324 break;
0325 }
0326
0327 fw_blk->addr = fw_rec->addr;
0328 fw_blk->mask = mask;
0329 fw_blk->len = len;
0330 memcpy(fw_blk->data, data, len);
0331
0332 list_add(&fw_blk->list, &iqs62x->fw_blk_head);
0333 }
0334
0335 release_firmware(fw);
0336
0337 return ret;
0338 }
0339
0340 const struct iqs62x_event_desc iqs62x_events[IQS62X_NUM_EVENTS] = {
0341 [IQS62X_EVENT_PROX_CH0_T] = {
0342 .reg = IQS62X_EVENT_PROX,
0343 .mask = BIT(4),
0344 .val = BIT(4),
0345 },
0346 [IQS62X_EVENT_PROX_CH0_P] = {
0347 .reg = IQS62X_EVENT_PROX,
0348 .mask = BIT(0),
0349 .val = BIT(0),
0350 },
0351 [IQS62X_EVENT_PROX_CH1_T] = {
0352 .reg = IQS62X_EVENT_PROX,
0353 .mask = BIT(5),
0354 .val = BIT(5),
0355 },
0356 [IQS62X_EVENT_PROX_CH1_P] = {
0357 .reg = IQS62X_EVENT_PROX,
0358 .mask = BIT(1),
0359 .val = BIT(1),
0360 },
0361 [IQS62X_EVENT_PROX_CH2_T] = {
0362 .reg = IQS62X_EVENT_PROX,
0363 .mask = BIT(6),
0364 .val = BIT(6),
0365 },
0366 [IQS62X_EVENT_PROX_CH2_P] = {
0367 .reg = IQS62X_EVENT_PROX,
0368 .mask = BIT(2),
0369 .val = BIT(2),
0370 },
0371 [IQS62X_EVENT_HYST_POS_T] = {
0372 .reg = IQS62X_EVENT_HYST,
0373 .mask = BIT(6) | BIT(7),
0374 .val = BIT(6),
0375 },
0376 [IQS62X_EVENT_HYST_POS_P] = {
0377 .reg = IQS62X_EVENT_HYST,
0378 .mask = BIT(5) | BIT(7),
0379 .val = BIT(5),
0380 },
0381 [IQS62X_EVENT_HYST_NEG_T] = {
0382 .reg = IQS62X_EVENT_HYST,
0383 .mask = BIT(6) | BIT(7),
0384 .val = BIT(6) | BIT(7),
0385 },
0386 [IQS62X_EVENT_HYST_NEG_P] = {
0387 .reg = IQS62X_EVENT_HYST,
0388 .mask = BIT(5) | BIT(7),
0389 .val = BIT(5) | BIT(7),
0390 },
0391 [IQS62X_EVENT_SAR1_ACT] = {
0392 .reg = IQS62X_EVENT_HYST,
0393 .mask = BIT(4),
0394 .val = BIT(4),
0395 },
0396 [IQS62X_EVENT_SAR1_QRD] = {
0397 .reg = IQS62X_EVENT_HYST,
0398 .mask = BIT(2),
0399 .val = BIT(2),
0400 },
0401 [IQS62X_EVENT_SAR1_MOVE] = {
0402 .reg = IQS62X_EVENT_HYST,
0403 .mask = BIT(1),
0404 .val = BIT(1),
0405 },
0406 [IQS62X_EVENT_SAR1_HALT] = {
0407 .reg = IQS62X_EVENT_HYST,
0408 .mask = BIT(0),
0409 .val = BIT(0),
0410 },
0411 [IQS62X_EVENT_WHEEL_UP] = {
0412 .reg = IQS62X_EVENT_WHEEL,
0413 .mask = BIT(7) | BIT(6),
0414 .val = BIT(7),
0415 },
0416 [IQS62X_EVENT_WHEEL_DN] = {
0417 .reg = IQS62X_EVENT_WHEEL,
0418 .mask = BIT(7) | BIT(6),
0419 .val = BIT(7) | BIT(6),
0420 },
0421 [IQS62X_EVENT_HALL_N_T] = {
0422 .reg = IQS62X_EVENT_HALL,
0423 .mask = BIT(2) | BIT(0),
0424 .val = BIT(2),
0425 },
0426 [IQS62X_EVENT_HALL_N_P] = {
0427 .reg = IQS62X_EVENT_HALL,
0428 .mask = BIT(1) | BIT(0),
0429 .val = BIT(1),
0430 },
0431 [IQS62X_EVENT_HALL_S_T] = {
0432 .reg = IQS62X_EVENT_HALL,
0433 .mask = BIT(2) | BIT(0),
0434 .val = BIT(2) | BIT(0),
0435 },
0436 [IQS62X_EVENT_HALL_S_P] = {
0437 .reg = IQS62X_EVENT_HALL,
0438 .mask = BIT(1) | BIT(0),
0439 .val = BIT(1) | BIT(0),
0440 },
0441 [IQS62X_EVENT_SYS_RESET] = {
0442 .reg = IQS62X_EVENT_SYS,
0443 .mask = BIT(7),
0444 .val = BIT(7),
0445 },
0446 [IQS62X_EVENT_SYS_ATI] = {
0447 .reg = IQS62X_EVENT_SYS,
0448 .mask = BIT(2),
0449 .val = BIT(2),
0450 },
0451 };
0452 EXPORT_SYMBOL_GPL(iqs62x_events);
0453
0454 static irqreturn_t iqs62x_irq(int irq, void *context)
0455 {
0456 struct iqs62x_core *iqs62x = context;
0457 struct i2c_client *client = iqs62x->client;
0458 struct iqs62x_event_data event_data;
0459 struct iqs62x_event_desc event_desc;
0460 enum iqs62x_event_reg event_reg;
0461 unsigned long event_flags = 0;
0462 int ret, i, j;
0463 u8 event_map[IQS62X_EVENT_SIZE];
0464
0465
0466
0467
0468
0469
0470
0471 ret = regmap_raw_read(iqs62x->regmap, IQS62X_SYS_FLAGS, event_map,
0472 sizeof(event_map));
0473 if (ret) {
0474 dev_err(&client->dev, "Failed to read device status: %d\n",
0475 ret);
0476 return IRQ_NONE;
0477 }
0478
0479 for (i = 0; i < sizeof(event_map); i++) {
0480 event_reg = iqs62x->dev_desc->event_regs[iqs62x->ui_sel][i];
0481
0482 switch (event_reg) {
0483 case IQS62X_EVENT_UI_LO:
0484 event_data.ui_data = get_unaligned_le16(&event_map[i]);
0485 fallthrough;
0486
0487 case IQS62X_EVENT_UI_HI:
0488 case IQS62X_EVENT_NONE:
0489 continue;
0490
0491 case IQS62X_EVENT_ALS:
0492 event_data.als_flags = event_map[i];
0493 continue;
0494
0495 case IQS62X_EVENT_IR:
0496 event_data.ir_flags = event_map[i];
0497 continue;
0498
0499 case IQS62X_EVENT_INTER:
0500 event_data.interval = event_map[i];
0501 continue;
0502
0503 case IQS62X_EVENT_HYST:
0504 event_map[i] <<= iqs62x->dev_desc->hyst_shift;
0505 fallthrough;
0506
0507 case IQS62X_EVENT_WHEEL:
0508 case IQS62X_EVENT_HALL:
0509 case IQS62X_EVENT_PROX:
0510 case IQS62X_EVENT_SYS:
0511 break;
0512 }
0513
0514 for (j = 0; j < IQS62X_NUM_EVENTS; j++) {
0515 event_desc = iqs62x_events[j];
0516
0517 if (event_desc.reg != event_reg)
0518 continue;
0519
0520 if ((event_map[i] & event_desc.mask) == event_desc.val)
0521 event_flags |= BIT(j);
0522 }
0523 }
0524
0525
0526
0527
0528
0529
0530 if (event_flags & BIT(IQS62X_EVENT_SYS_RESET)) {
0531 dev_err(&client->dev, "Unexpected device reset\n");
0532
0533 ret = iqs62x_dev_init(iqs62x);
0534 if (ret) {
0535 dev_err(&client->dev,
0536 "Failed to re-initialize device: %d\n", ret);
0537 return IRQ_NONE;
0538 }
0539
0540 iqs62x->event_cache |= BIT(IQS62X_EVENT_SYS_RESET);
0541 reinit_completion(&iqs62x->ati_done);
0542 } else if (event_flags & BIT(IQS62X_EVENT_SYS_ATI)) {
0543 iqs62x->event_cache |= BIT(IQS62X_EVENT_SYS_ATI);
0544 reinit_completion(&iqs62x->ati_done);
0545 } else if (!completion_done(&iqs62x->ati_done)) {
0546 ret = regmap_update_bits(iqs62x->regmap, IQS62X_SYS_SETTINGS,
0547 IQS62X_SYS_SETTINGS_EVENT_MODE, 0xFF);
0548 if (ret) {
0549 dev_err(&client->dev,
0550 "Failed to enable event mode: %d\n", ret);
0551 return IRQ_NONE;
0552 }
0553
0554 msleep(IQS62X_FILT_SETTLE_MS);
0555 complete_all(&iqs62x->ati_done);
0556 }
0557
0558
0559
0560
0561
0562
0563 if (completion_done(&iqs62x->ati_done)) {
0564 event_flags |= iqs62x->event_cache;
0565 ret = blocking_notifier_call_chain(&iqs62x->nh, event_flags,
0566 &event_data);
0567 if (ret & NOTIFY_STOP_MASK)
0568 return IRQ_NONE;
0569
0570 iqs62x->event_cache = 0;
0571 }
0572
0573
0574
0575
0576
0577
0578 usleep_range(150, 200);
0579
0580 return IRQ_HANDLED;
0581 }
0582
0583 static void iqs62x_firmware_load(const struct firmware *fw, void *context)
0584 {
0585 struct iqs62x_core *iqs62x = context;
0586 struct i2c_client *client = iqs62x->client;
0587 int ret;
0588
0589 if (fw) {
0590 ret = iqs62x_firmware_parse(iqs62x, fw);
0591 if (ret) {
0592 dev_err(&client->dev, "Failed to parse firmware: %d\n",
0593 ret);
0594 goto err_out;
0595 }
0596 }
0597
0598 ret = iqs62x_dev_init(iqs62x);
0599 if (ret) {
0600 dev_err(&client->dev, "Failed to initialize device: %d\n", ret);
0601 goto err_out;
0602 }
0603
0604 ret = devm_request_threaded_irq(&client->dev, client->irq,
0605 NULL, iqs62x_irq, IRQF_ONESHOT,
0606 client->name, iqs62x);
0607 if (ret) {
0608 dev_err(&client->dev, "Failed to request IRQ: %d\n", ret);
0609 goto err_out;
0610 }
0611
0612 if (!wait_for_completion_timeout(&iqs62x->ati_done,
0613 msecs_to_jiffies(2000))) {
0614 dev_err(&client->dev, "Failed to complete ATI\n");
0615 goto err_out;
0616 }
0617
0618 ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
0619 iqs62x->dev_desc->sub_devs,
0620 iqs62x->dev_desc->num_sub_devs,
0621 NULL, 0, NULL);
0622 if (ret)
0623 dev_err(&client->dev, "Failed to add sub-devices: %d\n", ret);
0624
0625 err_out:
0626 complete_all(&iqs62x->fw_done);
0627 }
0628
0629 static const struct mfd_cell iqs620at_sub_devs[] = {
0630 {
0631 .name = "iqs62x-keys",
0632 .of_compatible = "azoteq,iqs620a-keys",
0633 },
0634 {
0635 .name = "iqs620a-pwm",
0636 .of_compatible = "azoteq,iqs620a-pwm",
0637 },
0638 { .name = "iqs620at-temp", },
0639 };
0640
0641 static const struct mfd_cell iqs620a_sub_devs[] = {
0642 {
0643 .name = "iqs62x-keys",
0644 .of_compatible = "azoteq,iqs620a-keys",
0645 },
0646 {
0647 .name = "iqs620a-pwm",
0648 .of_compatible = "azoteq,iqs620a-pwm",
0649 },
0650 };
0651
0652 static const struct mfd_cell iqs621_sub_devs[] = {
0653 {
0654 .name = "iqs62x-keys",
0655 .of_compatible = "azoteq,iqs621-keys",
0656 },
0657 { .name = "iqs621-als", },
0658 };
0659
0660 static const struct mfd_cell iqs622_sub_devs[] = {
0661 {
0662 .name = "iqs62x-keys",
0663 .of_compatible = "azoteq,iqs622-keys",
0664 },
0665 { .name = "iqs621-als", },
0666 };
0667
0668 static const struct mfd_cell iqs624_sub_devs[] = {
0669 {
0670 .name = "iqs62x-keys",
0671 .of_compatible = "azoteq,iqs624-keys",
0672 },
0673 { .name = "iqs624-pos", },
0674 };
0675
0676 static const struct mfd_cell iqs625_sub_devs[] = {
0677 {
0678 .name = "iqs62x-keys",
0679 .of_compatible = "azoteq,iqs625-keys",
0680 },
0681 { .name = "iqs624-pos", },
0682 };
0683
0684 static const u8 iqs620at_cal_regs[] = {
0685 IQS620_TEMP_CAL_MULT,
0686 IQS620_TEMP_CAL_DIV,
0687 IQS620_TEMP_CAL_OFFS,
0688 };
0689
0690 static const u8 iqs621_cal_regs[] = {
0691 IQS621_ALS_CAL_DIV_LUX,
0692 IQS621_ALS_CAL_DIV_IR,
0693 };
0694
0695 static const enum iqs62x_event_reg iqs620a_event_regs[][IQS62X_EVENT_SIZE] = {
0696 [IQS62X_UI_PROX] = {
0697 IQS62X_EVENT_SYS,
0698 IQS62X_EVENT_NONE,
0699 IQS62X_EVENT_PROX,
0700 IQS62X_EVENT_HYST,
0701 IQS62X_EVENT_NONE,
0702 IQS62X_EVENT_NONE,
0703 IQS62X_EVENT_HALL,
0704 IQS62X_EVENT_NONE,
0705 IQS62X_EVENT_NONE,
0706 IQS62X_EVENT_NONE,
0707 },
0708 [IQS62X_UI_SAR1] = {
0709 IQS62X_EVENT_SYS,
0710 IQS62X_EVENT_NONE,
0711 IQS62X_EVENT_NONE,
0712 IQS62X_EVENT_HYST,
0713 IQS62X_EVENT_NONE,
0714 IQS62X_EVENT_NONE,
0715 IQS62X_EVENT_HALL,
0716 IQS62X_EVENT_NONE,
0717 IQS62X_EVENT_NONE,
0718 IQS62X_EVENT_NONE,
0719 },
0720 };
0721
0722 static const enum iqs62x_event_reg iqs621_event_regs[][IQS62X_EVENT_SIZE] = {
0723 [IQS62X_UI_PROX] = {
0724 IQS62X_EVENT_SYS,
0725 IQS62X_EVENT_NONE,
0726 IQS62X_EVENT_PROX,
0727 IQS62X_EVENT_HYST,
0728 IQS62X_EVENT_NONE,
0729 IQS62X_EVENT_NONE,
0730 IQS62X_EVENT_ALS,
0731 IQS62X_EVENT_UI_LO,
0732 IQS62X_EVENT_UI_HI,
0733 IQS62X_EVENT_HALL,
0734 },
0735 };
0736
0737 static const enum iqs62x_event_reg iqs622_event_regs[][IQS62X_EVENT_SIZE] = {
0738 [IQS62X_UI_PROX] = {
0739 IQS62X_EVENT_SYS,
0740 IQS62X_EVENT_NONE,
0741 IQS62X_EVENT_PROX,
0742 IQS62X_EVENT_NONE,
0743 IQS62X_EVENT_ALS,
0744 IQS62X_EVENT_NONE,
0745 IQS62X_EVENT_IR,
0746 IQS62X_EVENT_UI_LO,
0747 IQS62X_EVENT_UI_HI,
0748 IQS62X_EVENT_HALL,
0749 },
0750 [IQS62X_UI_SAR1] = {
0751 IQS62X_EVENT_SYS,
0752 IQS62X_EVENT_NONE,
0753 IQS62X_EVENT_NONE,
0754 IQS62X_EVENT_HYST,
0755 IQS62X_EVENT_ALS,
0756 IQS62X_EVENT_NONE,
0757 IQS62X_EVENT_IR,
0758 IQS62X_EVENT_UI_LO,
0759 IQS62X_EVENT_UI_HI,
0760 IQS62X_EVENT_HALL,
0761 },
0762 };
0763
0764 static const enum iqs62x_event_reg iqs624_event_regs[][IQS62X_EVENT_SIZE] = {
0765 [IQS62X_UI_PROX] = {
0766 IQS62X_EVENT_SYS,
0767 IQS62X_EVENT_NONE,
0768 IQS62X_EVENT_PROX,
0769 IQS62X_EVENT_NONE,
0770 IQS62X_EVENT_WHEEL,
0771 IQS62X_EVENT_NONE,
0772 IQS62X_EVENT_UI_LO,
0773 IQS62X_EVENT_UI_HI,
0774 IQS62X_EVENT_INTER,
0775 IQS62X_EVENT_NONE,
0776 },
0777 };
0778
0779 static const enum iqs62x_event_reg iqs625_event_regs[][IQS62X_EVENT_SIZE] = {
0780 [IQS62X_UI_PROX] = {
0781 IQS62X_EVENT_SYS,
0782 IQS62X_EVENT_PROX,
0783 IQS62X_EVENT_INTER,
0784 IQS62X_EVENT_NONE,
0785 IQS62X_EVENT_NONE,
0786 IQS62X_EVENT_NONE,
0787 IQS62X_EVENT_NONE,
0788 IQS62X_EVENT_NONE,
0789 IQS62X_EVENT_NONE,
0790 IQS62X_EVENT_NONE,
0791 },
0792 };
0793
0794 static const struct iqs62x_dev_desc iqs62x_devs[] = {
0795 {
0796 .dev_name = "iqs620at",
0797 .sub_devs = iqs620at_sub_devs,
0798 .num_sub_devs = ARRAY_SIZE(iqs620at_sub_devs),
0799 .prod_num = IQS620_PROD_NUM,
0800 .sw_num = 0x08,
0801 .cal_regs = iqs620at_cal_regs,
0802 .num_cal_regs = ARRAY_SIZE(iqs620at_cal_regs),
0803 .prox_mask = BIT(0),
0804 .sar_mask = BIT(1) | BIT(7),
0805 .hall_mask = BIT(2),
0806 .hyst_mask = BIT(3),
0807 .temp_mask = BIT(4),
0808 .prox_settings = IQS620_PROX_SETTINGS_4,
0809 .hall_flags = IQS620_HALL_FLAGS,
0810 .fw_name = "iqs620a.bin",
0811 .event_regs = &iqs620a_event_regs[IQS62X_UI_PROX],
0812 },
0813 {
0814 .dev_name = "iqs620a",
0815 .sub_devs = iqs620a_sub_devs,
0816 .num_sub_devs = ARRAY_SIZE(iqs620a_sub_devs),
0817 .prod_num = IQS620_PROD_NUM,
0818 .sw_num = 0x08,
0819 .prox_mask = BIT(0),
0820 .sar_mask = BIT(1) | BIT(7),
0821 .hall_mask = BIT(2),
0822 .hyst_mask = BIT(3),
0823 .temp_mask = BIT(4),
0824 .prox_settings = IQS620_PROX_SETTINGS_4,
0825 .hall_flags = IQS620_HALL_FLAGS,
0826 .fw_name = "iqs620a.bin",
0827 .event_regs = &iqs620a_event_regs[IQS62X_UI_PROX],
0828 },
0829 {
0830 .dev_name = "iqs621",
0831 .sub_devs = iqs621_sub_devs,
0832 .num_sub_devs = ARRAY_SIZE(iqs621_sub_devs),
0833 .prod_num = IQS621_PROD_NUM,
0834 .sw_num = 0x09,
0835 .cal_regs = iqs621_cal_regs,
0836 .num_cal_regs = ARRAY_SIZE(iqs621_cal_regs),
0837 .prox_mask = BIT(0),
0838 .hall_mask = BIT(1),
0839 .als_mask = BIT(2),
0840 .hyst_mask = BIT(3),
0841 .temp_mask = BIT(4),
0842 .als_flags = IQS621_ALS_FLAGS,
0843 .hall_flags = IQS621_HALL_FLAGS,
0844 .hyst_shift = 5,
0845 .fw_name = "iqs621.bin",
0846 .event_regs = &iqs621_event_regs[IQS62X_UI_PROX],
0847 },
0848 {
0849 .dev_name = "iqs622",
0850 .sub_devs = iqs622_sub_devs,
0851 .num_sub_devs = ARRAY_SIZE(iqs622_sub_devs),
0852 .prod_num = IQS622_PROD_NUM,
0853 .sw_num = 0x06,
0854 .prox_mask = BIT(0),
0855 .sar_mask = BIT(1),
0856 .hall_mask = BIT(2),
0857 .als_mask = BIT(3),
0858 .ir_mask = BIT(4),
0859 .prox_settings = IQS622_PROX_SETTINGS_4,
0860 .als_flags = IQS622_ALS_FLAGS,
0861 .hall_flags = IQS622_HALL_FLAGS,
0862 .fw_name = "iqs622.bin",
0863 .event_regs = &iqs622_event_regs[IQS62X_UI_PROX],
0864 },
0865 {
0866 .dev_name = "iqs624",
0867 .sub_devs = iqs624_sub_devs,
0868 .num_sub_devs = ARRAY_SIZE(iqs624_sub_devs),
0869 .prod_num = IQS624_PROD_NUM,
0870 .sw_num = 0x0B,
0871 .interval = IQS624_INTERVAL_NUM,
0872 .interval_div = 3,
0873 .fw_name = "iqs624.bin",
0874 .event_regs = &iqs624_event_regs[IQS62X_UI_PROX],
0875 },
0876 {
0877 .dev_name = "iqs625",
0878 .sub_devs = iqs625_sub_devs,
0879 .num_sub_devs = ARRAY_SIZE(iqs625_sub_devs),
0880 .prod_num = IQS625_PROD_NUM,
0881 .sw_num = 0x0B,
0882 .interval = IQS625_INTERVAL_NUM,
0883 .interval_div = 10,
0884 .fw_name = "iqs625.bin",
0885 .event_regs = &iqs625_event_regs[IQS62X_UI_PROX],
0886 },
0887 };
0888
0889 static const struct regmap_config iqs62x_regmap_config = {
0890 .reg_bits = 8,
0891 .val_bits = 8,
0892 .max_register = IQS62X_MAX_REG,
0893 };
0894
0895 static int iqs62x_probe(struct i2c_client *client)
0896 {
0897 struct iqs62x_core *iqs62x;
0898 struct iqs62x_info info;
0899 unsigned int val;
0900 int ret, i, j;
0901 const char *fw_name = NULL;
0902
0903 iqs62x = devm_kzalloc(&client->dev, sizeof(*iqs62x), GFP_KERNEL);
0904 if (!iqs62x)
0905 return -ENOMEM;
0906
0907 i2c_set_clientdata(client, iqs62x);
0908 iqs62x->client = client;
0909
0910 BLOCKING_INIT_NOTIFIER_HEAD(&iqs62x->nh);
0911 INIT_LIST_HEAD(&iqs62x->fw_blk_head);
0912
0913 init_completion(&iqs62x->ati_done);
0914 init_completion(&iqs62x->fw_done);
0915
0916 iqs62x->regmap = devm_regmap_init_i2c(client, &iqs62x_regmap_config);
0917 if (IS_ERR(iqs62x->regmap)) {
0918 ret = PTR_ERR(iqs62x->regmap);
0919 dev_err(&client->dev, "Failed to initialize register map: %d\n",
0920 ret);
0921 return ret;
0922 }
0923
0924 ret = regmap_raw_read(iqs62x->regmap, IQS62X_PROD_NUM, &info,
0925 sizeof(info));
0926 if (ret)
0927 return ret;
0928
0929
0930
0931
0932
0933
0934
0935
0936
0937
0938
0939
0940
0941
0942 for (i = 0; i < ARRAY_SIZE(iqs62x_devs); i++) {
0943 if (info.prod_num != iqs62x_devs[i].prod_num)
0944 continue;
0945
0946 iqs62x->dev_desc = &iqs62x_devs[i];
0947
0948 if (info.sw_num < iqs62x->dev_desc->sw_num)
0949 continue;
0950
0951 iqs62x->sw_num = info.sw_num;
0952 iqs62x->hw_num = info.hw_num;
0953
0954
0955
0956
0957
0958
0959
0960
0961 for (j = 0; j < iqs62x->dev_desc->num_cal_regs; j++) {
0962 ret = regmap_read(iqs62x->regmap,
0963 iqs62x->dev_desc->cal_regs[j], &val);
0964 if (ret)
0965 return ret;
0966
0967 if (!val)
0968 break;
0969 }
0970
0971
0972
0973
0974
0975
0976
0977
0978 if (j == iqs62x->dev_desc->num_cal_regs)
0979 break;
0980 }
0981
0982 if (!iqs62x->dev_desc) {
0983 dev_err(&client->dev, "Unrecognized product number: 0x%02X\n",
0984 info.prod_num);
0985 return -EINVAL;
0986 }
0987
0988 if (!iqs62x->sw_num) {
0989 dev_err(&client->dev, "Unrecognized software number: 0x%02X\n",
0990 info.sw_num);
0991 return -EINVAL;
0992 }
0993
0994 if (i == ARRAY_SIZE(iqs62x_devs)) {
0995 dev_err(&client->dev, "Uncalibrated device\n");
0996 return -ENODATA;
0997 }
0998
0999 device_property_read_string(&client->dev, "firmware-name", &fw_name);
1000
1001 ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
1002 fw_name ? : iqs62x->dev_desc->fw_name,
1003 &client->dev, GFP_KERNEL, iqs62x,
1004 iqs62x_firmware_load);
1005 if (ret)
1006 dev_err(&client->dev, "Failed to request firmware: %d\n", ret);
1007
1008 return ret;
1009 }
1010
1011 static int iqs62x_remove(struct i2c_client *client)
1012 {
1013 struct iqs62x_core *iqs62x = i2c_get_clientdata(client);
1014
1015 wait_for_completion(&iqs62x->fw_done);
1016
1017 return 0;
1018 }
1019
1020 static int __maybe_unused iqs62x_suspend(struct device *dev)
1021 {
1022 struct iqs62x_core *iqs62x = dev_get_drvdata(dev);
1023 int ret;
1024
1025 wait_for_completion(&iqs62x->fw_done);
1026
1027
1028
1029
1030
1031 ret = regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS,
1032 IQS62X_PWR_SETTINGS_DIS_AUTO, 0xFF);
1033 if (ret)
1034 return ret;
1035
1036 return regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS,
1037 IQS62X_PWR_SETTINGS_PWR_MODE_MASK,
1038 IQS62X_PWR_SETTINGS_PWR_MODE_HALT);
1039 }
1040
1041 static int __maybe_unused iqs62x_resume(struct device *dev)
1042 {
1043 struct iqs62x_core *iqs62x = dev_get_drvdata(dev);
1044 int ret;
1045
1046 ret = regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS,
1047 IQS62X_PWR_SETTINGS_PWR_MODE_MASK,
1048 IQS62X_PWR_SETTINGS_PWR_MODE_NORM);
1049 if (ret)
1050 return ret;
1051
1052 return regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS,
1053 IQS62X_PWR_SETTINGS_DIS_AUTO, 0);
1054 }
1055
1056 static SIMPLE_DEV_PM_OPS(iqs62x_pm, iqs62x_suspend, iqs62x_resume);
1057
1058 static const struct of_device_id iqs62x_of_match[] = {
1059 { .compatible = "azoteq,iqs620a" },
1060 { .compatible = "azoteq,iqs621" },
1061 { .compatible = "azoteq,iqs622" },
1062 { .compatible = "azoteq,iqs624" },
1063 { .compatible = "azoteq,iqs625" },
1064 { }
1065 };
1066 MODULE_DEVICE_TABLE(of, iqs62x_of_match);
1067
1068 static struct i2c_driver iqs62x_i2c_driver = {
1069 .driver = {
1070 .name = "iqs62x",
1071 .of_match_table = iqs62x_of_match,
1072 .pm = &iqs62x_pm,
1073 },
1074 .probe_new = iqs62x_probe,
1075 .remove = iqs62x_remove,
1076 };
1077 module_i2c_driver(iqs62x_i2c_driver);
1078
1079 MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>");
1080 MODULE_DESCRIPTION("Azoteq IQS620A/621/622/624/625 Multi-Function Sensors");
1081 MODULE_LICENSE("GPL");