xref: /kernel/linux/linux-5.10/drivers/mfd/iqs62x.c (revision 8c2ecf20)
1// 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		fallthrough;
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			fallthrough;
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			fallthrough;
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");
1064