blob: af764bc87d7ceba5f7c8869ecc3d44a9591b2fa7 [file] [log] [blame]
Jeff LaBundy4d9cf7d2020-02-16 17:32:06 -06001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Azoteq IQS620A/621/622/624/625 Multi-Function Sensors
4 *
5 * Copyright (C) 2019 Jeff LaBundy <jeff@labundy.com>
6 *
7 * These devices rely on application-specific register settings and calibration
8 * data developed in and exported from a suite of GUIs offered by the vendor. A
9 * separate tool converts the GUIs' ASCII-based output into a standard firmware
10 * file parsed by the driver.
11 *
12 * Link to datasheets and GUIs: https://www.azoteq.com/
13 *
14 * Link to conversion tool: https://github.com/jlabundy/iqs62x-h2bin.git
15 */
16
17#include <linux/completion.h>
18#include <linux/delay.h>
19#include <linux/device.h>
20#include <linux/err.h>
21#include <linux/firmware.h>
22#include <linux/i2c.h>
23#include <linux/interrupt.h>
24#include <linux/kernel.h>
25#include <linux/list.h>
26#include <linux/mfd/core.h>
27#include <linux/mfd/iqs62x.h>
28#include <linux/module.h>
29#include <linux/notifier.h>
30#include <linux/of_device.h>
31#include <linux/property.h>
32#include <linux/regmap.h>
33#include <linux/slab.h>
34#include <asm/unaligned.h>
35
36#define IQS62X_PROD_NUM 0x00
37
38#define IQS62X_SYS_FLAGS 0x10
39#define IQS62X_SYS_FLAGS_IN_ATI BIT(2)
40
41#define IQS620_HALL_FLAGS 0x16
42#define IQS621_HALL_FLAGS 0x19
43#define IQS622_HALL_FLAGS IQS621_HALL_FLAGS
44
45#define IQS624_INTERVAL_NUM 0x18
46#define IQS625_INTERVAL_NUM 0x12
47
48#define IQS622_PROX_SETTINGS_4 0x48
49#define IQS620_PROX_SETTINGS_4 0x50
50#define IQS620_PROX_SETTINGS_4_SAR_EN BIT(7)
51
52#define IQS621_ALS_CAL_DIV_LUX 0x82
53#define IQS621_ALS_CAL_DIV_IR 0x83
54
55#define IQS620_TEMP_CAL_MULT 0xC2
56#define IQS620_TEMP_CAL_DIV 0xC3
57#define IQS620_TEMP_CAL_OFFS 0xC4
58
59#define IQS62X_SYS_SETTINGS 0xD0
60#define IQS62X_SYS_SETTINGS_SOFT_RESET BIT(7)
61#define IQS62X_SYS_SETTINGS_ACK_RESET BIT(6)
62#define IQS62X_SYS_SETTINGS_EVENT_MODE BIT(5)
63#define IQS62X_SYS_SETTINGS_CLK_DIV BIT(4)
64#define IQS62X_SYS_SETTINGS_REDO_ATI BIT(1)
65
66#define IQS62X_PWR_SETTINGS 0xD2
67#define IQS62X_PWR_SETTINGS_DIS_AUTO BIT(5)
68#define IQS62X_PWR_SETTINGS_PWR_MODE_MASK (BIT(4) | BIT(3))
69#define IQS62X_PWR_SETTINGS_PWR_MODE_HALT (BIT(4) | BIT(3))
70#define IQS62X_PWR_SETTINGS_PWR_MODE_NORM 0
71
72#define IQS62X_OTP_CMD 0xF0
73#define IQS62X_OTP_CMD_FG3 0x13
74#define IQS62X_OTP_DATA 0xF1
75#define IQS62X_MAX_REG 0xFF
76
77#define IQS62X_HALL_CAL_MASK GENMASK(3, 0)
78
79#define IQS62X_FW_REC_TYPE_INFO 0
80#define IQS62X_FW_REC_TYPE_PROD 1
81#define IQS62X_FW_REC_TYPE_HALL 2
82#define IQS62X_FW_REC_TYPE_MASK 3
83#define IQS62X_FW_REC_TYPE_DATA 4
84
85#define IQS62X_ATI_POLL_SLEEP_US 10000
86#define IQS62X_ATI_POLL_TIMEOUT_US 500000
87#define IQS62X_ATI_STABLE_DELAY_MS 150
88
89struct iqs62x_fw_rec {
90 u8 type;
91 u8 addr;
92 u8 len;
93 u8 data;
94} __packed;
95
96struct iqs62x_fw_blk {
97 struct list_head list;
98 u8 addr;
99 u8 mask;
100 u8 len;
101 u8 data[];
102};
103
104struct iqs62x_info {
105 u8 prod_num;
106 u8 sw_num;
107 u8 hw_num;
108} __packed;
109
110static int iqs62x_dev_init(struct iqs62x_core *iqs62x)
111{
112 struct iqs62x_fw_blk *fw_blk;
113 unsigned int val;
114 int ret;
115 u8 clk_div = 1;
116
117 list_for_each_entry(fw_blk, &iqs62x->fw_blk_head, list) {
118 if (fw_blk->mask)
119 ret = regmap_update_bits(iqs62x->regmap, fw_blk->addr,
120 fw_blk->mask, *fw_blk->data);
121 else
122 ret = regmap_raw_write(iqs62x->regmap, fw_blk->addr,
123 fw_blk->data, fw_blk->len);
124 if (ret)
125 return ret;
126 }
127
128 switch (iqs62x->dev_desc->prod_num) {
129 case IQS620_PROD_NUM:
130 case IQS622_PROD_NUM:
131 ret = regmap_read(iqs62x->regmap,
132 iqs62x->dev_desc->prox_settings, &val);
133 if (ret)
134 return ret;
135
136 if (val & IQS620_PROX_SETTINGS_4_SAR_EN)
137 iqs62x->ui_sel = IQS62X_UI_SAR1;
138
139 /* fall through */
140
141 case IQS621_PROD_NUM:
142 ret = regmap_write(iqs62x->regmap, IQS620_GLBL_EVENT_MASK,
143 IQS620_GLBL_EVENT_MASK_PMU |
144 iqs62x->dev_desc->prox_mask |
145 iqs62x->dev_desc->sar_mask |
146 iqs62x->dev_desc->hall_mask |
147 iqs62x->dev_desc->hyst_mask |
148 iqs62x->dev_desc->temp_mask |
149 iqs62x->dev_desc->als_mask |
150 iqs62x->dev_desc->ir_mask);
151 if (ret)
152 return ret;
153 break;
154
155 default:
156 ret = regmap_write(iqs62x->regmap, IQS624_HALL_UI,
157 IQS624_HALL_UI_WHL_EVENT |
158 IQS624_HALL_UI_INT_EVENT |
159 IQS624_HALL_UI_AUTO_CAL);
160 if (ret)
161 return ret;
162
163 /*
164 * The IQS625 default interval divider is below the minimum
165 * permissible value, and the datasheet mandates that it is
166 * corrected during initialization (unless an updated value
167 * has already been provided by firmware).
168 *
169 * To protect against an unacceptably low user-entered value
170 * stored in the firmware, the same check is extended to the
171 * IQS624 as well.
172 */
173 ret = regmap_read(iqs62x->regmap, IQS624_INTERVAL_DIV, &val);
174 if (ret)
175 return ret;
176
177 if (val >= iqs62x->dev_desc->interval_div)
178 break;
179
180 ret = regmap_write(iqs62x->regmap, IQS624_INTERVAL_DIV,
181 iqs62x->dev_desc->interval_div);
182 if (ret)
183 return ret;
184 }
185
186 ret = regmap_read(iqs62x->regmap, IQS62X_SYS_SETTINGS, &val);
187 if (ret)
188 return ret;
189
190 if (val & IQS62X_SYS_SETTINGS_CLK_DIV)
191 clk_div = iqs62x->dev_desc->clk_div;
192
193 ret = regmap_write(iqs62x->regmap, IQS62X_SYS_SETTINGS, val |
194 IQS62X_SYS_SETTINGS_ACK_RESET |
195 IQS62X_SYS_SETTINGS_EVENT_MODE |
196 IQS62X_SYS_SETTINGS_REDO_ATI);
197 if (ret)
198 return ret;
199
200 ret = regmap_read_poll_timeout(iqs62x->regmap, IQS62X_SYS_FLAGS, val,
201 !(val & IQS62X_SYS_FLAGS_IN_ATI),
202 IQS62X_ATI_POLL_SLEEP_US,
203 IQS62X_ATI_POLL_TIMEOUT_US * clk_div);
204 if (ret)
205 return ret;
206
207 msleep(IQS62X_ATI_STABLE_DELAY_MS * clk_div);
208
209 return 0;
210}
211
212static int iqs62x_firmware_parse(struct iqs62x_core *iqs62x,
213 const struct firmware *fw)
214{
215 struct i2c_client *client = iqs62x->client;
216 struct iqs62x_fw_rec *fw_rec;
217 struct iqs62x_fw_blk *fw_blk;
218 unsigned int val;
219 size_t pos = 0;
220 int ret = 0;
221 u8 mask, len, *data;
222 u8 hall_cal_index = 0;
223
224 while (pos < fw->size) {
225 if (pos + sizeof(*fw_rec) > fw->size) {
226 ret = -EINVAL;
227 break;
228 }
229 fw_rec = (struct iqs62x_fw_rec *)(fw->data + pos);
230 pos += sizeof(*fw_rec);
231
232 if (pos + fw_rec->len - 1 > fw->size) {
233 ret = -EINVAL;
234 break;
235 }
236 pos += fw_rec->len - 1;
237
238 switch (fw_rec->type) {
239 case IQS62X_FW_REC_TYPE_INFO:
240 continue;
241
242 case IQS62X_FW_REC_TYPE_PROD:
243 if (fw_rec->data == iqs62x->dev_desc->prod_num)
244 continue;
245
246 dev_err(&client->dev,
247 "Incompatible product number: 0x%02X\n",
248 fw_rec->data);
249 ret = -EINVAL;
250 break;
251
252 case IQS62X_FW_REC_TYPE_HALL:
253 if (!hall_cal_index) {
254 ret = regmap_write(iqs62x->regmap,
255 IQS62X_OTP_CMD,
256 IQS62X_OTP_CMD_FG3);
257 if (ret)
258 break;
259
260 ret = regmap_read(iqs62x->regmap,
261 IQS62X_OTP_DATA, &val);
262 if (ret)
263 break;
264
265 hall_cal_index = val & IQS62X_HALL_CAL_MASK;
266 if (!hall_cal_index) {
267 dev_err(&client->dev,
268 "Uncalibrated device\n");
269 ret = -ENODATA;
270 break;
271 }
272 }
273
274 if (hall_cal_index > fw_rec->len) {
275 ret = -EINVAL;
276 break;
277 }
278
279 mask = 0;
280 data = &fw_rec->data + hall_cal_index - 1;
281 len = sizeof(*data);
282 break;
283
284 case IQS62X_FW_REC_TYPE_MASK:
285 if (fw_rec->len < (sizeof(mask) + sizeof(*data))) {
286 ret = -EINVAL;
287 break;
288 }
289
290 mask = fw_rec->data;
291 data = &fw_rec->data + sizeof(mask);
292 len = sizeof(*data);
293 break;
294
295 case IQS62X_FW_REC_TYPE_DATA:
296 mask = 0;
297 data = &fw_rec->data;
298 len = fw_rec->len;
299 break;
300
301 default:
302 dev_err(&client->dev,
303 "Unrecognized record type: 0x%02X\n",
304 fw_rec->type);
305 ret = -EINVAL;
306 }
307
308 if (ret)
309 break;
310
311 fw_blk = devm_kzalloc(&client->dev,
312 struct_size(fw_blk, data, len),
313 GFP_KERNEL);
314 if (!fw_blk) {
315 ret = -ENOMEM;
316 break;
317 }
318
319 fw_blk->addr = fw_rec->addr;
320 fw_blk->mask = mask;
321 fw_blk->len = len;
322 memcpy(fw_blk->data, data, len);
323
324 list_add(&fw_blk->list, &iqs62x->fw_blk_head);
325 }
326
327 release_firmware(fw);
328
329 return ret;
330}
331
332const struct iqs62x_event_desc iqs62x_events[IQS62X_NUM_EVENTS] = {
333 [IQS62X_EVENT_PROX_CH0_T] = {
334 .reg = IQS62X_EVENT_PROX,
335 .mask = BIT(4),
336 .val = BIT(4),
337 },
338 [IQS62X_EVENT_PROX_CH0_P] = {
339 .reg = IQS62X_EVENT_PROX,
340 .mask = BIT(0),
341 .val = BIT(0),
342 },
343 [IQS62X_EVENT_PROX_CH1_T] = {
344 .reg = IQS62X_EVENT_PROX,
345 .mask = BIT(5),
346 .val = BIT(5),
347 },
348 [IQS62X_EVENT_PROX_CH1_P] = {
349 .reg = IQS62X_EVENT_PROX,
350 .mask = BIT(1),
351 .val = BIT(1),
352 },
353 [IQS62X_EVENT_PROX_CH2_T] = {
354 .reg = IQS62X_EVENT_PROX,
355 .mask = BIT(6),
356 .val = BIT(6),
357 },
358 [IQS62X_EVENT_PROX_CH2_P] = {
359 .reg = IQS62X_EVENT_PROX,
360 .mask = BIT(2),
361 .val = BIT(2),
362 },
363 [IQS62X_EVENT_HYST_POS_T] = {
364 .reg = IQS62X_EVENT_HYST,
365 .mask = BIT(6) | BIT(7),
366 .val = BIT(6),
367 },
368 [IQS62X_EVENT_HYST_POS_P] = {
369 .reg = IQS62X_EVENT_HYST,
370 .mask = BIT(5) | BIT(7),
371 .val = BIT(5),
372 },
373 [IQS62X_EVENT_HYST_NEG_T] = {
374 .reg = IQS62X_EVENT_HYST,
375 .mask = BIT(6) | BIT(7),
376 .val = BIT(6) | BIT(7),
377 },
378 [IQS62X_EVENT_HYST_NEG_P] = {
379 .reg = IQS62X_EVENT_HYST,
380 .mask = BIT(5) | BIT(7),
381 .val = BIT(5) | BIT(7),
382 },
383 [IQS62X_EVENT_SAR1_ACT] = {
384 .reg = IQS62X_EVENT_HYST,
385 .mask = BIT(4),
386 .val = BIT(4),
387 },
388 [IQS62X_EVENT_SAR1_QRD] = {
389 .reg = IQS62X_EVENT_HYST,
390 .mask = BIT(2),
391 .val = BIT(2),
392 },
393 [IQS62X_EVENT_SAR1_MOVE] = {
394 .reg = IQS62X_EVENT_HYST,
395 .mask = BIT(1),
396 .val = BIT(1),
397 },
398 [IQS62X_EVENT_SAR1_HALT] = {
399 .reg = IQS62X_EVENT_HYST,
400 .mask = BIT(0),
401 .val = BIT(0),
402 },
403 [IQS62X_EVENT_WHEEL_UP] = {
404 .reg = IQS62X_EVENT_WHEEL,
405 .mask = BIT(7) | BIT(6),
406 .val = BIT(7),
407 },
408 [IQS62X_EVENT_WHEEL_DN] = {
409 .reg = IQS62X_EVENT_WHEEL,
410 .mask = BIT(7) | BIT(6),
411 .val = BIT(7) | BIT(6),
412 },
413 [IQS62X_EVENT_HALL_N_T] = {
414 .reg = IQS62X_EVENT_HALL,
415 .mask = BIT(2) | BIT(0),
416 .val = BIT(2),
417 },
418 [IQS62X_EVENT_HALL_N_P] = {
419 .reg = IQS62X_EVENT_HALL,
420 .mask = BIT(1) | BIT(0),
421 .val = BIT(1),
422 },
423 [IQS62X_EVENT_HALL_S_T] = {
424 .reg = IQS62X_EVENT_HALL,
425 .mask = BIT(2) | BIT(0),
426 .val = BIT(2) | BIT(0),
427 },
428 [IQS62X_EVENT_HALL_S_P] = {
429 .reg = IQS62X_EVENT_HALL,
430 .mask = BIT(1) | BIT(0),
431 .val = BIT(1) | BIT(0),
432 },
433 [IQS62X_EVENT_SYS_RESET] = {
434 .reg = IQS62X_EVENT_SYS,
435 .mask = BIT(7),
436 .val = BIT(7),
437 },
438};
439EXPORT_SYMBOL_GPL(iqs62x_events);
440
441static irqreturn_t iqs62x_irq(int irq, void *context)
442{
443 struct iqs62x_core *iqs62x = context;
444 struct i2c_client *client = iqs62x->client;
445 struct iqs62x_event_data event_data;
446 struct iqs62x_event_desc event_desc;
447 enum iqs62x_event_reg event_reg;
448 unsigned long event_flags = 0;
449 int ret, i, j;
450 u8 event_map[IQS62X_EVENT_SIZE];
451
452 /*
453 * The device asserts the RDY output to signal the beginning of a
454 * communication window, which is closed by an I2C stop condition.
455 * As such, all interrupt status is captured in a single read and
456 * broadcast to any interested sub-device drivers.
457 */
458 ret = regmap_raw_read(iqs62x->regmap, IQS62X_SYS_FLAGS, event_map,
459 sizeof(event_map));
460 if (ret) {
461 dev_err(&client->dev, "Failed to read device status: %d\n",
462 ret);
463 return IRQ_NONE;
464 }
465
466 for (i = 0; i < sizeof(event_map); i++) {
467 event_reg = iqs62x->dev_desc->event_regs[iqs62x->ui_sel][i];
468
469 switch (event_reg) {
470 case IQS62X_EVENT_UI_LO:
471 event_data.ui_data = get_unaligned_le16(&event_map[i]);
472
473 /* fall through */
474
475 case IQS62X_EVENT_UI_HI:
476 case IQS62X_EVENT_NONE:
477 continue;
478
479 case IQS62X_EVENT_ALS:
480 event_data.als_flags = event_map[i];
481 continue;
482
483 case IQS62X_EVENT_IR:
484 event_data.ir_flags = event_map[i];
485 continue;
486
487 case IQS62X_EVENT_INTER:
488 event_data.interval = event_map[i];
489 continue;
490
491 case IQS62X_EVENT_HYST:
492 event_map[i] <<= iqs62x->dev_desc->hyst_shift;
493
494 /* fall through */
495
496 case IQS62X_EVENT_WHEEL:
497 case IQS62X_EVENT_HALL:
498 case IQS62X_EVENT_PROX:
499 case IQS62X_EVENT_SYS:
500 break;
501 }
502
503 for (j = 0; j < IQS62X_NUM_EVENTS; j++) {
504 event_desc = iqs62x_events[j];
505
506 if (event_desc.reg != event_reg)
507 continue;
508
509 if ((event_map[i] & event_desc.mask) == event_desc.val)
510 event_flags |= BIT(j);
511 }
512 }
513
514 /*
515 * The device resets itself in response to the I2C master stalling
516 * communication past a fixed timeout. In this case, all registers
517 * are restored and any interested sub-device drivers are notified.
518 */
519 if (event_flags & BIT(IQS62X_EVENT_SYS_RESET)) {
520 dev_err(&client->dev, "Unexpected device reset\n");
521
522 ret = iqs62x_dev_init(iqs62x);
523 if (ret) {
524 dev_err(&client->dev,
525 "Failed to re-initialize device: %d\n", ret);
526 return IRQ_NONE;
527 }
528 }
529
530 ret = blocking_notifier_call_chain(&iqs62x->nh, event_flags,
531 &event_data);
532 if (ret & NOTIFY_STOP_MASK)
533 return IRQ_NONE;
534
535 /*
536 * Once the communication window is closed, a small delay is added to
537 * ensure the device's RDY output has been deasserted by the time the
538 * interrupt handler returns.
539 */
540 usleep_range(50, 100);
541
542 return IRQ_HANDLED;
543}
544
545static void iqs62x_firmware_load(const struct firmware *fw, void *context)
546{
547 struct iqs62x_core *iqs62x = context;
548 struct i2c_client *client = iqs62x->client;
549 int ret;
550
551 if (fw) {
552 ret = iqs62x_firmware_parse(iqs62x, fw);
553 if (ret) {
554 dev_err(&client->dev, "Failed to parse firmware: %d\n",
555 ret);
556 goto err_out;
557 }
558 }
559
560 ret = iqs62x_dev_init(iqs62x);
561 if (ret) {
562 dev_err(&client->dev, "Failed to initialize device: %d\n", ret);
563 goto err_out;
564 }
565
566 ret = devm_request_threaded_irq(&client->dev, client->irq,
567 NULL, iqs62x_irq, IRQF_ONESHOT,
568 client->name, iqs62x);
569 if (ret) {
570 dev_err(&client->dev, "Failed to request IRQ: %d\n", ret);
571 goto err_out;
572 }
573
574 ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
575 iqs62x->dev_desc->sub_devs,
576 iqs62x->dev_desc->num_sub_devs,
577 NULL, 0, NULL);
578 if (ret)
579 dev_err(&client->dev, "Failed to add sub-devices: %d\n", ret);
580
581err_out:
582 complete_all(&iqs62x->fw_done);
583}
584
585static const struct mfd_cell iqs620at_sub_devs[] = {
586 {
587 .name = "iqs62x-keys",
588 .of_compatible = "azoteq,iqs620a-keys",
589 },
590 {
591 .name = "iqs620a-pwm",
592 .of_compatible = "azoteq,iqs620a-pwm",
593 },
594 { .name = "iqs620at-temp", },
595};
596
597static const struct mfd_cell iqs620a_sub_devs[] = {
598 {
599 .name = "iqs62x-keys",
600 .of_compatible = "azoteq,iqs620a-keys",
601 },
602 {
603 .name = "iqs620a-pwm",
604 .of_compatible = "azoteq,iqs620a-pwm",
605 },
606};
607
608static const struct mfd_cell iqs621_sub_devs[] = {
609 {
610 .name = "iqs62x-keys",
611 .of_compatible = "azoteq,iqs621-keys",
612 },
613 { .name = "iqs621-als", },
614};
615
616static const struct mfd_cell iqs622_sub_devs[] = {
617 {
618 .name = "iqs62x-keys",
619 .of_compatible = "azoteq,iqs622-keys",
620 },
621 { .name = "iqs621-als", },
622};
623
624static const struct mfd_cell iqs624_sub_devs[] = {
625 {
626 .name = "iqs62x-keys",
627 .of_compatible = "azoteq,iqs624-keys",
628 },
629 { .name = "iqs624-pos", },
630};
631
632static const struct mfd_cell iqs625_sub_devs[] = {
633 {
634 .name = "iqs62x-keys",
635 .of_compatible = "azoteq,iqs625-keys",
636 },
637 { .name = "iqs624-pos", },
638};
639
640static const u8 iqs620at_cal_regs[] = {
641 IQS620_TEMP_CAL_MULT,
642 IQS620_TEMP_CAL_DIV,
643 IQS620_TEMP_CAL_OFFS,
644};
645
646static const u8 iqs621_cal_regs[] = {
647 IQS621_ALS_CAL_DIV_LUX,
648 IQS621_ALS_CAL_DIV_IR,
649};
650
651static const enum iqs62x_event_reg iqs620a_event_regs[][IQS62X_EVENT_SIZE] = {
652 [IQS62X_UI_PROX] = {
653 IQS62X_EVENT_SYS, /* 0x10 */
654 IQS62X_EVENT_NONE,
655 IQS62X_EVENT_PROX, /* 0x12 */
656 IQS62X_EVENT_HYST, /* 0x13 */
657 IQS62X_EVENT_NONE,
658 IQS62X_EVENT_NONE,
659 IQS62X_EVENT_HALL, /* 0x16 */
660 IQS62X_EVENT_NONE,
661 IQS62X_EVENT_NONE,
662 IQS62X_EVENT_NONE,
663 },
664 [IQS62X_UI_SAR1] = {
665 IQS62X_EVENT_SYS, /* 0x10 */
666 IQS62X_EVENT_NONE,
667 IQS62X_EVENT_NONE,
668 IQS62X_EVENT_HYST, /* 0x13 */
669 IQS62X_EVENT_NONE,
670 IQS62X_EVENT_NONE,
671 IQS62X_EVENT_HALL, /* 0x16 */
672 IQS62X_EVENT_NONE,
673 IQS62X_EVENT_NONE,
674 IQS62X_EVENT_NONE,
675 },
676};
677
678static const enum iqs62x_event_reg iqs621_event_regs[][IQS62X_EVENT_SIZE] = {
679 [IQS62X_UI_PROX] = {
680 IQS62X_EVENT_SYS, /* 0x10 */
681 IQS62X_EVENT_NONE,
682 IQS62X_EVENT_PROX, /* 0x12 */
683 IQS62X_EVENT_HYST, /* 0x13 */
684 IQS62X_EVENT_NONE,
685 IQS62X_EVENT_NONE,
686 IQS62X_EVENT_ALS, /* 0x16 */
687 IQS62X_EVENT_UI_LO, /* 0x17 */
688 IQS62X_EVENT_UI_HI, /* 0x18 */
689 IQS62X_EVENT_HALL, /* 0x19 */
690 },
691};
692
693static const enum iqs62x_event_reg iqs622_event_regs[][IQS62X_EVENT_SIZE] = {
694 [IQS62X_UI_PROX] = {
695 IQS62X_EVENT_SYS, /* 0x10 */
696 IQS62X_EVENT_NONE,
697 IQS62X_EVENT_PROX, /* 0x12 */
698 IQS62X_EVENT_NONE,
699 IQS62X_EVENT_ALS, /* 0x14 */
700 IQS62X_EVENT_NONE,
701 IQS62X_EVENT_IR, /* 0x16 */
702 IQS62X_EVENT_UI_LO, /* 0x17 */
703 IQS62X_EVENT_UI_HI, /* 0x18 */
704 IQS62X_EVENT_HALL, /* 0x19 */
705 },
706 [IQS62X_UI_SAR1] = {
707 IQS62X_EVENT_SYS, /* 0x10 */
708 IQS62X_EVENT_NONE,
709 IQS62X_EVENT_NONE,
710 IQS62X_EVENT_HYST, /* 0x13 */
711 IQS62X_EVENT_ALS, /* 0x14 */
712 IQS62X_EVENT_NONE,
713 IQS62X_EVENT_IR, /* 0x16 */
714 IQS62X_EVENT_UI_LO, /* 0x17 */
715 IQS62X_EVENT_UI_HI, /* 0x18 */
716 IQS62X_EVENT_HALL, /* 0x19 */
717 },
718};
719
720static const enum iqs62x_event_reg iqs624_event_regs[][IQS62X_EVENT_SIZE] = {
721 [IQS62X_UI_PROX] = {
722 IQS62X_EVENT_SYS, /* 0x10 */
723 IQS62X_EVENT_NONE,
724 IQS62X_EVENT_PROX, /* 0x12 */
725 IQS62X_EVENT_NONE,
726 IQS62X_EVENT_WHEEL, /* 0x14 */
727 IQS62X_EVENT_NONE,
728 IQS62X_EVENT_UI_LO, /* 0x16 */
729 IQS62X_EVENT_UI_HI, /* 0x17 */
730 IQS62X_EVENT_INTER, /* 0x18 */
731 IQS62X_EVENT_NONE,
732 },
733};
734
735static const enum iqs62x_event_reg iqs625_event_regs[][IQS62X_EVENT_SIZE] = {
736 [IQS62X_UI_PROX] = {
737 IQS62X_EVENT_SYS, /* 0x10 */
738 IQS62X_EVENT_PROX, /* 0x11 */
739 IQS62X_EVENT_INTER, /* 0x12 */
740 IQS62X_EVENT_NONE,
741 IQS62X_EVENT_NONE,
742 IQS62X_EVENT_NONE,
743 IQS62X_EVENT_NONE,
744 IQS62X_EVENT_NONE,
745 IQS62X_EVENT_NONE,
746 IQS62X_EVENT_NONE,
747 },
748};
749
750static const struct iqs62x_dev_desc iqs62x_devs[] = {
751 {
752 .dev_name = "iqs620at",
753 .sub_devs = iqs620at_sub_devs,
754 .num_sub_devs = ARRAY_SIZE(iqs620at_sub_devs),
755
756 .prod_num = IQS620_PROD_NUM,
757 .sw_num = 0x08,
758 .cal_regs = iqs620at_cal_regs,
759 .num_cal_regs = ARRAY_SIZE(iqs620at_cal_regs),
760
761 .prox_mask = BIT(0),
762 .sar_mask = BIT(1) | BIT(7),
763 .hall_mask = BIT(2),
764 .hyst_mask = BIT(3),
765 .temp_mask = BIT(4),
766
767 .prox_settings = IQS620_PROX_SETTINGS_4,
768 .hall_flags = IQS620_HALL_FLAGS,
769
770 .clk_div = 4,
771 .fw_name = "iqs620a.bin",
772 .event_regs = &iqs620a_event_regs[IQS62X_UI_PROX],
773 },
774 {
775 .dev_name = "iqs620a",
776 .sub_devs = iqs620a_sub_devs,
777 .num_sub_devs = ARRAY_SIZE(iqs620a_sub_devs),
778
779 .prod_num = IQS620_PROD_NUM,
780 .sw_num = 0x08,
781
782 .prox_mask = BIT(0),
783 .sar_mask = BIT(1) | BIT(7),
784 .hall_mask = BIT(2),
785 .hyst_mask = BIT(3),
786 .temp_mask = BIT(4),
787
788 .prox_settings = IQS620_PROX_SETTINGS_4,
789 .hall_flags = IQS620_HALL_FLAGS,
790
791 .clk_div = 4,
792 .fw_name = "iqs620a.bin",
793 .event_regs = &iqs620a_event_regs[IQS62X_UI_PROX],
794 },
795 {
796 .dev_name = "iqs621",
797 .sub_devs = iqs621_sub_devs,
798 .num_sub_devs = ARRAY_SIZE(iqs621_sub_devs),
799
800 .prod_num = IQS621_PROD_NUM,
801 .sw_num = 0x09,
802 .cal_regs = iqs621_cal_regs,
803 .num_cal_regs = ARRAY_SIZE(iqs621_cal_regs),
804
805 .prox_mask = BIT(0),
806 .hall_mask = BIT(1),
807 .als_mask = BIT(2),
808 .hyst_mask = BIT(3),
809 .temp_mask = BIT(4),
810
811 .als_flags = IQS621_ALS_FLAGS,
812 .hall_flags = IQS621_HALL_FLAGS,
813 .hyst_shift = 5,
814
815 .clk_div = 2,
816 .fw_name = "iqs621.bin",
817 .event_regs = &iqs621_event_regs[IQS62X_UI_PROX],
818 },
819 {
820 .dev_name = "iqs622",
821 .sub_devs = iqs622_sub_devs,
822 .num_sub_devs = ARRAY_SIZE(iqs622_sub_devs),
823
824 .prod_num = IQS622_PROD_NUM,
825 .sw_num = 0x06,
826
827 .prox_mask = BIT(0),
828 .sar_mask = BIT(1),
829 .hall_mask = BIT(2),
830 .als_mask = BIT(3),
831 .ir_mask = BIT(4),
832
833 .prox_settings = IQS622_PROX_SETTINGS_4,
834 .als_flags = IQS622_ALS_FLAGS,
835 .hall_flags = IQS622_HALL_FLAGS,
836
837 .clk_div = 2,
838 .fw_name = "iqs622.bin",
839 .event_regs = &iqs622_event_regs[IQS62X_UI_PROX],
840 },
841 {
842 .dev_name = "iqs624",
843 .sub_devs = iqs624_sub_devs,
844 .num_sub_devs = ARRAY_SIZE(iqs624_sub_devs),
845
846 .prod_num = IQS624_PROD_NUM,
847 .sw_num = 0x0B,
848
849 .interval = IQS624_INTERVAL_NUM,
850 .interval_div = 3,
851
852 .clk_div = 2,
853 .fw_name = "iqs624.bin",
854 .event_regs = &iqs624_event_regs[IQS62X_UI_PROX],
855 },
856 {
857 .dev_name = "iqs625",
858 .sub_devs = iqs625_sub_devs,
859 .num_sub_devs = ARRAY_SIZE(iqs625_sub_devs),
860
861 .prod_num = IQS625_PROD_NUM,
862 .sw_num = 0x0B,
863
864 .interval = IQS625_INTERVAL_NUM,
865 .interval_div = 10,
866
867 .clk_div = 2,
868 .fw_name = "iqs625.bin",
869 .event_regs = &iqs625_event_regs[IQS62X_UI_PROX],
870 },
871};
872
873static const struct regmap_config iqs62x_map_config = {
874 .reg_bits = 8,
875 .val_bits = 8,
876 .max_register = IQS62X_MAX_REG,
877};
878
879static int iqs62x_probe(struct i2c_client *client)
880{
881 struct iqs62x_core *iqs62x;
882 struct iqs62x_info info;
883 unsigned int val;
884 int ret, i, j;
885 u8 sw_num = 0;
886 const char *fw_name = NULL;
887
888 iqs62x = devm_kzalloc(&client->dev, sizeof(*iqs62x), GFP_KERNEL);
889 if (!iqs62x)
890 return -ENOMEM;
891
892 i2c_set_clientdata(client, iqs62x);
893 iqs62x->client = client;
894
895 BLOCKING_INIT_NOTIFIER_HEAD(&iqs62x->nh);
896 INIT_LIST_HEAD(&iqs62x->fw_blk_head);
897 init_completion(&iqs62x->fw_done);
898
899 iqs62x->regmap = devm_regmap_init_i2c(client, &iqs62x_map_config);
900 if (IS_ERR(iqs62x->regmap)) {
901 ret = PTR_ERR(iqs62x->regmap);
902 dev_err(&client->dev, "Failed to initialize register map: %d\n",
903 ret);
904 return ret;
905 }
906
907 ret = regmap_raw_read(iqs62x->regmap, IQS62X_PROD_NUM, &info,
908 sizeof(info));
909 if (ret)
910 return ret;
911
912 /*
913 * The following sequence validates the device's product and software
914 * numbers. It then determines if the device is factory-calibrated by
915 * checking for nonzero values in the device's designated calibration
916 * registers (if applicable). Depending on the device, the absence of
917 * calibration data indicates a reduced feature set or invalid device.
918 *
919 * For devices given in both calibrated and uncalibrated versions, the
920 * calibrated version (e.g. IQS620AT) appears first in the iqs62x_devs
921 * array. The uncalibrated version (e.g. IQS620A) appears next and has
922 * the same product and software numbers, but no calibration registers
923 * are specified.
924 */
925 for (i = 0; i < ARRAY_SIZE(iqs62x_devs); i++) {
926 if (info.prod_num != iqs62x_devs[i].prod_num)
927 continue;
928
929 iqs62x->dev_desc = &iqs62x_devs[i];
930
931 if (info.sw_num < iqs62x->dev_desc->sw_num)
932 continue;
933
934 sw_num = info.sw_num;
935
936 /*
937 * Read each of the device's designated calibration registers,
938 * if any, and exit from the inner loop early if any are equal
939 * to zero (indicating the device is uncalibrated). This could
940 * be acceptable depending on the device (e.g. IQS620A instead
941 * of IQS620AT).
942 */
943 for (j = 0; j < iqs62x->dev_desc->num_cal_regs; j++) {
944 ret = regmap_read(iqs62x->regmap,
945 iqs62x->dev_desc->cal_regs[j], &val);
946 if (ret)
947 return ret;
948
949 if (!val)
950 break;
951 }
952
953 /*
954 * If the number of nonzero values read from the device equals
955 * the number of designated calibration registers (which could
956 * be zero), exit from the outer loop early to signal that the
957 * device's product and software numbers match a known device,
958 * and the device is calibrated (if applicable).
959 */
960 if (j == iqs62x->dev_desc->num_cal_regs)
961 break;
962 }
963
964 if (!iqs62x->dev_desc) {
965 dev_err(&client->dev, "Unrecognized product number: 0x%02X\n",
966 info.prod_num);
967 return -EINVAL;
968 }
969
970 if (!sw_num) {
971 dev_err(&client->dev, "Unrecognized software number: 0x%02X\n",
972 info.sw_num);
973 return -EINVAL;
974 }
975
976 if (i == ARRAY_SIZE(iqs62x_devs)) {
977 dev_err(&client->dev, "Uncalibrated device\n");
978 return -ENODATA;
979 }
980
981 device_property_read_string(&client->dev, "firmware-name", &fw_name);
982
983 ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
984 fw_name ? : iqs62x->dev_desc->fw_name,
985 &client->dev, GFP_KERNEL, iqs62x,
986 iqs62x_firmware_load);
987 if (ret)
988 dev_err(&client->dev, "Failed to request firmware: %d\n", ret);
989
990 return ret;
991}
992
993static int iqs62x_remove(struct i2c_client *client)
994{
995 struct iqs62x_core *iqs62x = i2c_get_clientdata(client);
996
997 wait_for_completion(&iqs62x->fw_done);
998
999 return 0;
1000}
1001
1002static int __maybe_unused iqs62x_suspend(struct device *dev)
1003{
1004 struct iqs62x_core *iqs62x = dev_get_drvdata(dev);
1005 int ret;
1006
1007 wait_for_completion(&iqs62x->fw_done);
1008
1009 /*
1010 * As per the datasheet, automatic mode switching must be disabled
1011 * before the device is placed in or taken out of halt mode.
1012 */
1013 ret = regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS,
1014 IQS62X_PWR_SETTINGS_DIS_AUTO, 0xFF);
1015 if (ret)
1016 return ret;
1017
1018 return regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS,
1019 IQS62X_PWR_SETTINGS_PWR_MODE_MASK,
1020 IQS62X_PWR_SETTINGS_PWR_MODE_HALT);
1021}
1022
1023static int __maybe_unused iqs62x_resume(struct device *dev)
1024{
1025 struct iqs62x_core *iqs62x = dev_get_drvdata(dev);
1026 int ret;
1027
1028 ret = regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS,
1029 IQS62X_PWR_SETTINGS_PWR_MODE_MASK,
1030 IQS62X_PWR_SETTINGS_PWR_MODE_NORM);
1031 if (ret)
1032 return ret;
1033
1034 return regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS,
1035 IQS62X_PWR_SETTINGS_DIS_AUTO, 0);
1036}
1037
1038static SIMPLE_DEV_PM_OPS(iqs62x_pm, iqs62x_suspend, iqs62x_resume);
1039
1040static const struct of_device_id iqs62x_of_match[] = {
1041 { .compatible = "azoteq,iqs620a" },
1042 { .compatible = "azoteq,iqs621" },
1043 { .compatible = "azoteq,iqs622" },
1044 { .compatible = "azoteq,iqs624" },
1045 { .compatible = "azoteq,iqs625" },
1046 { }
1047};
1048MODULE_DEVICE_TABLE(of, iqs62x_of_match);
1049
1050static struct i2c_driver iqs62x_i2c_driver = {
1051 .driver = {
1052 .name = "iqs62x",
1053 .of_match_table = iqs62x_of_match,
1054 .pm = &iqs62x_pm,
1055 },
1056 .probe_new = iqs62x_probe,
1057 .remove = iqs62x_remove,
1058};
1059module_i2c_driver(iqs62x_i2c_driver);
1060
1061MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>");
1062MODULE_DESCRIPTION("Azoteq IQS620A/621/622/624/625 Multi-Function Sensors");
1063MODULE_LICENSE("GPL");