18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  Microchip AT42QT1050 QTouch Sensor Controller
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Copyright (C) 2019 Pengutronix, Marco Felsch <kernel@pengutronix.de>
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci *  Base on AT42QT1070 driver by:
88c2ecf20Sopenharmony_ci *  Bo Shen <voice.shen@atmel.com>
98c2ecf20Sopenharmony_ci *  Copyright (C) 2011 Atmel
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/delay.h>
138c2ecf20Sopenharmony_ci#include <linux/i2c.h>
148c2ecf20Sopenharmony_ci#include <linux/input.h>
158c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
168c2ecf20Sopenharmony_ci#include <linux/kernel.h>
178c2ecf20Sopenharmony_ci#include <linux/log2.h>
188c2ecf20Sopenharmony_ci#include <linux/module.h>
198c2ecf20Sopenharmony_ci#include <linux/of.h>
208c2ecf20Sopenharmony_ci#include <linux/regmap.h>
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci/* Chip ID */
238c2ecf20Sopenharmony_ci#define QT1050_CHIP_ID		0x00
248c2ecf20Sopenharmony_ci#define QT1050_CHIP_ID_VER	0x46
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci/* Firmware version */
278c2ecf20Sopenharmony_ci#define QT1050_FW_VERSION	0x01
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci/* Detection status */
308c2ecf20Sopenharmony_ci#define QT1050_DET_STATUS	0x02
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci/* Key status */
338c2ecf20Sopenharmony_ci#define QT1050_KEY_STATUS	0x03
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci/* Key Signals */
368c2ecf20Sopenharmony_ci#define QT1050_KEY_SIGNAL_0_MSB	0x06
378c2ecf20Sopenharmony_ci#define QT1050_KEY_SIGNAL_0_LSB	0x07
388c2ecf20Sopenharmony_ci#define QT1050_KEY_SIGNAL_1_MSB	0x08
398c2ecf20Sopenharmony_ci#define QT1050_KEY_SIGNAL_1_LSB	0x09
408c2ecf20Sopenharmony_ci#define QT1050_KEY_SIGNAL_2_MSB	0x0c
418c2ecf20Sopenharmony_ci#define QT1050_KEY_SIGNAL_2_LSB	0x0d
428c2ecf20Sopenharmony_ci#define QT1050_KEY_SIGNAL_3_MSB	0x0e
438c2ecf20Sopenharmony_ci#define QT1050_KEY_SIGNAL_3_LSB	0x0f
448c2ecf20Sopenharmony_ci#define QT1050_KEY_SIGNAL_4_MSB	0x10
458c2ecf20Sopenharmony_ci#define QT1050_KEY_SIGNAL_4_LSB	0x11
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci/* Reference data */
488c2ecf20Sopenharmony_ci#define QT1050_REF_DATA_0_MSB	0x14
498c2ecf20Sopenharmony_ci#define QT1050_REF_DATA_0_LSB	0x15
508c2ecf20Sopenharmony_ci#define QT1050_REF_DATA_1_MSB	0x16
518c2ecf20Sopenharmony_ci#define QT1050_REF_DATA_1_LSB	0x17
528c2ecf20Sopenharmony_ci#define QT1050_REF_DATA_2_MSB	0x1a
538c2ecf20Sopenharmony_ci#define QT1050_REF_DATA_2_LSB	0x1b
548c2ecf20Sopenharmony_ci#define QT1050_REF_DATA_3_MSB	0x1c
558c2ecf20Sopenharmony_ci#define QT1050_REF_DATA_3_LSB	0x1d
568c2ecf20Sopenharmony_ci#define QT1050_REF_DATA_4_MSB	0x1e
578c2ecf20Sopenharmony_ci#define QT1050_REF_DATA_4_LSB	0x1f
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci/* Negative threshold level */
608c2ecf20Sopenharmony_ci#define QT1050_NTHR_0		0x21
618c2ecf20Sopenharmony_ci#define QT1050_NTHR_1		0x22
628c2ecf20Sopenharmony_ci#define QT1050_NTHR_2		0x24
638c2ecf20Sopenharmony_ci#define QT1050_NTHR_3		0x25
648c2ecf20Sopenharmony_ci#define QT1050_NTHR_4		0x26
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci/* Pulse / Scale  */
678c2ecf20Sopenharmony_ci#define QT1050_PULSE_SCALE_0	0x28
688c2ecf20Sopenharmony_ci#define QT1050_PULSE_SCALE_1	0x29
698c2ecf20Sopenharmony_ci#define QT1050_PULSE_SCALE_2	0x2b
708c2ecf20Sopenharmony_ci#define QT1050_PULSE_SCALE_3	0x2c
718c2ecf20Sopenharmony_ci#define QT1050_PULSE_SCALE_4	0x2d
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci/* Detection integrator counter / AKS */
748c2ecf20Sopenharmony_ci#define QT1050_DI_AKS_0		0x2f
758c2ecf20Sopenharmony_ci#define QT1050_DI_AKS_1		0x30
768c2ecf20Sopenharmony_ci#define QT1050_DI_AKS_2		0x32
778c2ecf20Sopenharmony_ci#define QT1050_DI_AKS_3		0x33
788c2ecf20Sopenharmony_ci#define QT1050_DI_AKS_4		0x34
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci/* Charge Share Delay */
818c2ecf20Sopenharmony_ci#define QT1050_CSD_0		0x36
828c2ecf20Sopenharmony_ci#define QT1050_CSD_1		0x37
838c2ecf20Sopenharmony_ci#define QT1050_CSD_2		0x39
848c2ecf20Sopenharmony_ci#define QT1050_CSD_3		0x3a
858c2ecf20Sopenharmony_ci#define QT1050_CSD_4		0x3b
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci/* Low Power Mode */
888c2ecf20Sopenharmony_ci#define QT1050_LPMODE		0x3d
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci/* Calibration and Reset */
918c2ecf20Sopenharmony_ci#define QT1050_RES_CAL		0x3f
928c2ecf20Sopenharmony_ci#define QT1050_RES_CAL_RESET		BIT(7)
938c2ecf20Sopenharmony_ci#define QT1050_RES_CAL_CALIBRATE	BIT(1)
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci#define QT1050_MAX_KEYS		5
968c2ecf20Sopenharmony_ci#define QT1050_RESET_TIME	255
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_cistruct qt1050_key_regs {
998c2ecf20Sopenharmony_ci	unsigned int nthr;
1008c2ecf20Sopenharmony_ci	unsigned int pulse_scale;
1018c2ecf20Sopenharmony_ci	unsigned int di_aks;
1028c2ecf20Sopenharmony_ci	unsigned int csd;
1038c2ecf20Sopenharmony_ci};
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cistruct qt1050_key {
1068c2ecf20Sopenharmony_ci	u32 num;
1078c2ecf20Sopenharmony_ci	u32 charge_delay;
1088c2ecf20Sopenharmony_ci	u32 thr_cnt;
1098c2ecf20Sopenharmony_ci	u32 samples;
1108c2ecf20Sopenharmony_ci	u32 scale;
1118c2ecf20Sopenharmony_ci	u32 keycode;
1128c2ecf20Sopenharmony_ci};
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_cistruct qt1050_priv {
1158c2ecf20Sopenharmony_ci	struct i2c_client	*client;
1168c2ecf20Sopenharmony_ci	struct input_dev	*input;
1178c2ecf20Sopenharmony_ci	struct regmap		*regmap;
1188c2ecf20Sopenharmony_ci	struct qt1050_key	keys[QT1050_MAX_KEYS];
1198c2ecf20Sopenharmony_ci	unsigned short		keycodes[QT1050_MAX_KEYS];
1208c2ecf20Sopenharmony_ci	u8			reg_keys;
1218c2ecf20Sopenharmony_ci	u8			last_keys;
1228c2ecf20Sopenharmony_ci};
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_cistatic const struct qt1050_key_regs qt1050_key_regs_data[] = {
1258c2ecf20Sopenharmony_ci	{
1268c2ecf20Sopenharmony_ci		.nthr = QT1050_NTHR_0,
1278c2ecf20Sopenharmony_ci		.pulse_scale = QT1050_PULSE_SCALE_0,
1288c2ecf20Sopenharmony_ci		.di_aks = QT1050_DI_AKS_0,
1298c2ecf20Sopenharmony_ci		.csd = QT1050_CSD_0,
1308c2ecf20Sopenharmony_ci	}, {
1318c2ecf20Sopenharmony_ci		.nthr = QT1050_NTHR_1,
1328c2ecf20Sopenharmony_ci		.pulse_scale = QT1050_PULSE_SCALE_1,
1338c2ecf20Sopenharmony_ci		.di_aks = QT1050_DI_AKS_1,
1348c2ecf20Sopenharmony_ci		.csd = QT1050_CSD_1,
1358c2ecf20Sopenharmony_ci	}, {
1368c2ecf20Sopenharmony_ci		.nthr = QT1050_NTHR_2,
1378c2ecf20Sopenharmony_ci		.pulse_scale = QT1050_PULSE_SCALE_2,
1388c2ecf20Sopenharmony_ci		.di_aks = QT1050_DI_AKS_2,
1398c2ecf20Sopenharmony_ci		.csd = QT1050_CSD_2,
1408c2ecf20Sopenharmony_ci	}, {
1418c2ecf20Sopenharmony_ci		.nthr = QT1050_NTHR_3,
1428c2ecf20Sopenharmony_ci		.pulse_scale = QT1050_PULSE_SCALE_3,
1438c2ecf20Sopenharmony_ci		.di_aks = QT1050_DI_AKS_3,
1448c2ecf20Sopenharmony_ci		.csd = QT1050_CSD_3,
1458c2ecf20Sopenharmony_ci	}, {
1468c2ecf20Sopenharmony_ci		.nthr = QT1050_NTHR_4,
1478c2ecf20Sopenharmony_ci		.pulse_scale = QT1050_PULSE_SCALE_4,
1488c2ecf20Sopenharmony_ci		.di_aks = QT1050_DI_AKS_4,
1498c2ecf20Sopenharmony_ci		.csd = QT1050_CSD_4,
1508c2ecf20Sopenharmony_ci	}
1518c2ecf20Sopenharmony_ci};
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_cistatic bool qt1050_volatile_reg(struct device *dev, unsigned int reg)
1548c2ecf20Sopenharmony_ci{
1558c2ecf20Sopenharmony_ci	switch (reg) {
1568c2ecf20Sopenharmony_ci	case QT1050_DET_STATUS:
1578c2ecf20Sopenharmony_ci	case QT1050_KEY_STATUS:
1588c2ecf20Sopenharmony_ci	case QT1050_KEY_SIGNAL_0_MSB:
1598c2ecf20Sopenharmony_ci	case QT1050_KEY_SIGNAL_0_LSB:
1608c2ecf20Sopenharmony_ci	case QT1050_KEY_SIGNAL_1_MSB:
1618c2ecf20Sopenharmony_ci	case QT1050_KEY_SIGNAL_1_LSB:
1628c2ecf20Sopenharmony_ci	case QT1050_KEY_SIGNAL_2_MSB:
1638c2ecf20Sopenharmony_ci	case QT1050_KEY_SIGNAL_2_LSB:
1648c2ecf20Sopenharmony_ci	case QT1050_KEY_SIGNAL_3_MSB:
1658c2ecf20Sopenharmony_ci	case QT1050_KEY_SIGNAL_3_LSB:
1668c2ecf20Sopenharmony_ci	case QT1050_KEY_SIGNAL_4_MSB:
1678c2ecf20Sopenharmony_ci	case QT1050_KEY_SIGNAL_4_LSB:
1688c2ecf20Sopenharmony_ci		return true;
1698c2ecf20Sopenharmony_ci	default:
1708c2ecf20Sopenharmony_ci		return false;
1718c2ecf20Sopenharmony_ci	}
1728c2ecf20Sopenharmony_ci}
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_cistatic const struct regmap_range qt1050_readable_ranges[] = {
1758c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_CHIP_ID, QT1050_KEY_STATUS),
1768c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_KEY_SIGNAL_0_MSB, QT1050_KEY_SIGNAL_1_LSB),
1778c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_KEY_SIGNAL_2_MSB, QT1050_KEY_SIGNAL_4_LSB),
1788c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_REF_DATA_0_MSB, QT1050_REF_DATA_1_LSB),
1798c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_REF_DATA_2_MSB, QT1050_REF_DATA_4_LSB),
1808c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_NTHR_0, QT1050_NTHR_1),
1818c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_NTHR_2, QT1050_NTHR_4),
1828c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_PULSE_SCALE_0, QT1050_PULSE_SCALE_1),
1838c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_PULSE_SCALE_2, QT1050_PULSE_SCALE_4),
1848c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_DI_AKS_0, QT1050_DI_AKS_1),
1858c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_DI_AKS_2, QT1050_DI_AKS_4),
1868c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_CSD_0, QT1050_CSD_1),
1878c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_CSD_2, QT1050_RES_CAL),
1888c2ecf20Sopenharmony_ci};
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_cistatic const struct regmap_access_table qt1050_readable_table = {
1918c2ecf20Sopenharmony_ci	.yes_ranges = qt1050_readable_ranges,
1928c2ecf20Sopenharmony_ci	.n_yes_ranges = ARRAY_SIZE(qt1050_readable_ranges),
1938c2ecf20Sopenharmony_ci};
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_cistatic const struct regmap_range qt1050_writeable_ranges[] = {
1968c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_NTHR_0, QT1050_NTHR_1),
1978c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_NTHR_2, QT1050_NTHR_4),
1988c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_PULSE_SCALE_0, QT1050_PULSE_SCALE_1),
1998c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_PULSE_SCALE_2, QT1050_PULSE_SCALE_4),
2008c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_DI_AKS_0, QT1050_DI_AKS_1),
2018c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_DI_AKS_2, QT1050_DI_AKS_4),
2028c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_CSD_0, QT1050_CSD_1),
2038c2ecf20Sopenharmony_ci	regmap_reg_range(QT1050_CSD_2, QT1050_RES_CAL),
2048c2ecf20Sopenharmony_ci};
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_cistatic const struct regmap_access_table qt1050_writeable_table = {
2078c2ecf20Sopenharmony_ci	.yes_ranges = qt1050_writeable_ranges,
2088c2ecf20Sopenharmony_ci	.n_yes_ranges = ARRAY_SIZE(qt1050_writeable_ranges),
2098c2ecf20Sopenharmony_ci};
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_cistatic struct regmap_config qt1050_regmap_config = {
2128c2ecf20Sopenharmony_ci	.reg_bits = 8,
2138c2ecf20Sopenharmony_ci	.val_bits = 8,
2148c2ecf20Sopenharmony_ci	.max_register = QT1050_RES_CAL,
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_ci	.cache_type = REGCACHE_RBTREE,
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci	.wr_table = &qt1050_writeable_table,
2198c2ecf20Sopenharmony_ci	.rd_table = &qt1050_readable_table,
2208c2ecf20Sopenharmony_ci	.volatile_reg = qt1050_volatile_reg,
2218c2ecf20Sopenharmony_ci};
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_cistatic bool qt1050_identify(struct qt1050_priv *ts)
2248c2ecf20Sopenharmony_ci{
2258c2ecf20Sopenharmony_ci	unsigned int val;
2268c2ecf20Sopenharmony_ci	int err;
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci	/* Read Chip ID */
2298c2ecf20Sopenharmony_ci	regmap_read(ts->regmap, QT1050_CHIP_ID, &val);
2308c2ecf20Sopenharmony_ci	if (val != QT1050_CHIP_ID_VER) {
2318c2ecf20Sopenharmony_ci		dev_err(&ts->client->dev, "ID %d not supported\n", val);
2328c2ecf20Sopenharmony_ci		return false;
2338c2ecf20Sopenharmony_ci	}
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci	/* Read firmware version */
2368c2ecf20Sopenharmony_ci	err = regmap_read(ts->regmap, QT1050_FW_VERSION, &val);
2378c2ecf20Sopenharmony_ci	if (err) {
2388c2ecf20Sopenharmony_ci		dev_err(&ts->client->dev, "could not read the firmware version\n");
2398c2ecf20Sopenharmony_ci		return false;
2408c2ecf20Sopenharmony_ci	}
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci	dev_info(&ts->client->dev, "AT42QT1050 firmware version %1d.%1d\n",
2438c2ecf20Sopenharmony_ci		 val >> 4, val & 0xf);
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ci	return true;
2468c2ecf20Sopenharmony_ci}
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_cistatic irqreturn_t qt1050_irq_threaded(int irq, void *dev_id)
2498c2ecf20Sopenharmony_ci{
2508c2ecf20Sopenharmony_ci	struct qt1050_priv *ts = dev_id;
2518c2ecf20Sopenharmony_ci	struct input_dev *input = ts->input;
2528c2ecf20Sopenharmony_ci	unsigned long new_keys, changed;
2538c2ecf20Sopenharmony_ci	unsigned int val;
2548c2ecf20Sopenharmony_ci	int i, err;
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci	/* Read the detected status register, thus clearing interrupt */
2578c2ecf20Sopenharmony_ci	err = regmap_read(ts->regmap, QT1050_DET_STATUS, &val);
2588c2ecf20Sopenharmony_ci	if (err) {
2598c2ecf20Sopenharmony_ci		dev_err(&ts->client->dev, "Fail to read detection status: %d\n",
2608c2ecf20Sopenharmony_ci			err);
2618c2ecf20Sopenharmony_ci		return IRQ_NONE;
2628c2ecf20Sopenharmony_ci	}
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci	/* Read which key changed, keys are not continuous */
2658c2ecf20Sopenharmony_ci	err = regmap_read(ts->regmap, QT1050_KEY_STATUS, &val);
2668c2ecf20Sopenharmony_ci	if (err) {
2678c2ecf20Sopenharmony_ci		dev_err(&ts->client->dev,
2688c2ecf20Sopenharmony_ci			"Fail to determine the key status: %d\n", err);
2698c2ecf20Sopenharmony_ci		return IRQ_NONE;
2708c2ecf20Sopenharmony_ci	}
2718c2ecf20Sopenharmony_ci	new_keys = (val & 0x70) >> 2 | (val & 0x6) >> 1;
2728c2ecf20Sopenharmony_ci	changed = ts->last_keys ^ new_keys;
2738c2ecf20Sopenharmony_ci	/* Report registered keys only */
2748c2ecf20Sopenharmony_ci	changed &= ts->reg_keys;
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	for_each_set_bit(i, &changed, QT1050_MAX_KEYS)
2778c2ecf20Sopenharmony_ci		input_report_key(input, ts->keys[i].keycode,
2788c2ecf20Sopenharmony_ci				 test_bit(i, &new_keys));
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_ci	ts->last_keys = new_keys;
2818c2ecf20Sopenharmony_ci	input_sync(input);
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	return IRQ_HANDLED;
2848c2ecf20Sopenharmony_ci}
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_cistatic const struct qt1050_key_regs *qt1050_get_key_regs(int key_num)
2878c2ecf20Sopenharmony_ci{
2888c2ecf20Sopenharmony_ci	return &qt1050_key_regs_data[key_num];
2898c2ecf20Sopenharmony_ci}
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_cistatic int qt1050_set_key(struct regmap *map, int number, int on)
2928c2ecf20Sopenharmony_ci{
2938c2ecf20Sopenharmony_ci	const struct qt1050_key_regs *key_regs;
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci	key_regs = qt1050_get_key_regs(number);
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_ci	return regmap_update_bits(map, key_regs->di_aks, 0xfc,
2988c2ecf20Sopenharmony_ci				  on ? BIT(4) : 0x00);
2998c2ecf20Sopenharmony_ci}
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_cistatic int qt1050_apply_fw_data(struct qt1050_priv *ts)
3028c2ecf20Sopenharmony_ci{
3038c2ecf20Sopenharmony_ci	struct regmap *map = ts->regmap;
3048c2ecf20Sopenharmony_ci	struct qt1050_key *button = &ts->keys[0];
3058c2ecf20Sopenharmony_ci	const struct qt1050_key_regs *key_regs;
3068c2ecf20Sopenharmony_ci	int i, err;
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci	/* Disable all keys and enable only the specified ones */
3098c2ecf20Sopenharmony_ci	for (i = 0; i < QT1050_MAX_KEYS; i++) {
3108c2ecf20Sopenharmony_ci		err = qt1050_set_key(map, i, 0);
3118c2ecf20Sopenharmony_ci		if (err)
3128c2ecf20Sopenharmony_ci			return err;
3138c2ecf20Sopenharmony_ci	}
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci	for (i = 0; i < QT1050_MAX_KEYS; i++, button++) {
3168c2ecf20Sopenharmony_ci		/* Keep KEY_RESERVED keys off */
3178c2ecf20Sopenharmony_ci		if (button->keycode == KEY_RESERVED)
3188c2ecf20Sopenharmony_ci			continue;
3198c2ecf20Sopenharmony_ci
3208c2ecf20Sopenharmony_ci		err = qt1050_set_key(map, button->num, 1);
3218c2ecf20Sopenharmony_ci		if (err)
3228c2ecf20Sopenharmony_ci			return err;
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci		key_regs = qt1050_get_key_regs(button->num);
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci		err = regmap_write(map, key_regs->pulse_scale,
3278c2ecf20Sopenharmony_ci				   (button->samples << 4) | (button->scale));
3288c2ecf20Sopenharmony_ci		if (err)
3298c2ecf20Sopenharmony_ci			return err;
3308c2ecf20Sopenharmony_ci		err = regmap_write(map, key_regs->csd, button->charge_delay);
3318c2ecf20Sopenharmony_ci		if (err)
3328c2ecf20Sopenharmony_ci			return err;
3338c2ecf20Sopenharmony_ci		err = regmap_write(map, key_regs->nthr, button->thr_cnt);
3348c2ecf20Sopenharmony_ci		if (err)
3358c2ecf20Sopenharmony_ci			return err;
3368c2ecf20Sopenharmony_ci	}
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci	return 0;
3398c2ecf20Sopenharmony_ci}
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_cistatic int qt1050_parse_fw(struct qt1050_priv *ts)
3428c2ecf20Sopenharmony_ci{
3438c2ecf20Sopenharmony_ci	struct device *dev = &ts->client->dev;
3448c2ecf20Sopenharmony_ci	struct fwnode_handle *child;
3458c2ecf20Sopenharmony_ci	int nbuttons;
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci	nbuttons = device_get_child_node_count(dev);
3488c2ecf20Sopenharmony_ci	if (nbuttons == 0 || nbuttons > QT1050_MAX_KEYS)
3498c2ecf20Sopenharmony_ci		return -ENODEV;
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci	device_for_each_child_node(dev, child) {
3528c2ecf20Sopenharmony_ci		struct qt1050_key button;
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci		/* Required properties */
3558c2ecf20Sopenharmony_ci		if (fwnode_property_read_u32(child, "linux,code",
3568c2ecf20Sopenharmony_ci					     &button.keycode)) {
3578c2ecf20Sopenharmony_ci			dev_err(dev, "Button without keycode\n");
3588c2ecf20Sopenharmony_ci			goto err;
3598c2ecf20Sopenharmony_ci		}
3608c2ecf20Sopenharmony_ci		if (button.keycode >= KEY_MAX) {
3618c2ecf20Sopenharmony_ci			dev_err(dev, "Invalid keycode 0x%x\n",
3628c2ecf20Sopenharmony_ci				button.keycode);
3638c2ecf20Sopenharmony_ci			goto err;
3648c2ecf20Sopenharmony_ci		}
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_ci		if (fwnode_property_read_u32(child, "reg",
3678c2ecf20Sopenharmony_ci					     &button.num)) {
3688c2ecf20Sopenharmony_ci			dev_err(dev, "Button without pad number\n");
3698c2ecf20Sopenharmony_ci			goto err;
3708c2ecf20Sopenharmony_ci		}
3718c2ecf20Sopenharmony_ci		if (button.num < 0 || button.num > QT1050_MAX_KEYS - 1)
3728c2ecf20Sopenharmony_ci			goto err;
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_ci		ts->reg_keys |= BIT(button.num);
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci		/* Optional properties */
3778c2ecf20Sopenharmony_ci		if (fwnode_property_read_u32(child,
3788c2ecf20Sopenharmony_ci					     "microchip,pre-charge-time-ns",
3798c2ecf20Sopenharmony_ci					     &button.charge_delay)) {
3808c2ecf20Sopenharmony_ci			button.charge_delay = 0;
3818c2ecf20Sopenharmony_ci		} else {
3828c2ecf20Sopenharmony_ci			if (button.charge_delay % 2500 == 0)
3838c2ecf20Sopenharmony_ci				button.charge_delay =
3848c2ecf20Sopenharmony_ci					button.charge_delay / 2500;
3858c2ecf20Sopenharmony_ci			else
3868c2ecf20Sopenharmony_ci				button.charge_delay = 0;
3878c2ecf20Sopenharmony_ci		}
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_ci		if (fwnode_property_read_u32(child, "microchip,average-samples",
3908c2ecf20Sopenharmony_ci					 &button.samples)) {
3918c2ecf20Sopenharmony_ci			button.samples = 0;
3928c2ecf20Sopenharmony_ci		} else {
3938c2ecf20Sopenharmony_ci			if (is_power_of_2(button.samples))
3948c2ecf20Sopenharmony_ci				button.samples = ilog2(button.samples);
3958c2ecf20Sopenharmony_ci			else
3968c2ecf20Sopenharmony_ci				button.samples = 0;
3978c2ecf20Sopenharmony_ci		}
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_ci		if (fwnode_property_read_u32(child, "microchip,average-scaling",
4008c2ecf20Sopenharmony_ci					     &button.scale)) {
4018c2ecf20Sopenharmony_ci			button.scale = 0;
4028c2ecf20Sopenharmony_ci		} else {
4038c2ecf20Sopenharmony_ci			if (is_power_of_2(button.scale))
4048c2ecf20Sopenharmony_ci				button.scale = ilog2(button.scale);
4058c2ecf20Sopenharmony_ci			else
4068c2ecf20Sopenharmony_ci				button.scale = 0;
4078c2ecf20Sopenharmony_ci
4088c2ecf20Sopenharmony_ci		}
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_ci		if (fwnode_property_read_u32(child, "microchip,threshold",
4118c2ecf20Sopenharmony_ci					 &button.thr_cnt)) {
4128c2ecf20Sopenharmony_ci			button.thr_cnt = 20;
4138c2ecf20Sopenharmony_ci		} else {
4148c2ecf20Sopenharmony_ci			if (button.thr_cnt > 255)
4158c2ecf20Sopenharmony_ci				button.thr_cnt = 20;
4168c2ecf20Sopenharmony_ci		}
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_ci		ts->keys[button.num] = button;
4198c2ecf20Sopenharmony_ci	}
4208c2ecf20Sopenharmony_ci
4218c2ecf20Sopenharmony_ci	return 0;
4228c2ecf20Sopenharmony_ci
4238c2ecf20Sopenharmony_cierr:
4248c2ecf20Sopenharmony_ci	fwnode_handle_put(child);
4258c2ecf20Sopenharmony_ci	return -EINVAL;
4268c2ecf20Sopenharmony_ci}
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_cistatic int qt1050_probe(struct i2c_client *client)
4298c2ecf20Sopenharmony_ci{
4308c2ecf20Sopenharmony_ci	struct qt1050_priv *ts;
4318c2ecf20Sopenharmony_ci	struct input_dev *input;
4328c2ecf20Sopenharmony_ci	struct device *dev = &client->dev;
4338c2ecf20Sopenharmony_ci	struct regmap *map;
4348c2ecf20Sopenharmony_ci	unsigned int status, i;
4358c2ecf20Sopenharmony_ci	int err;
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_ci	/* Check basic functionality */
4388c2ecf20Sopenharmony_ci	err = i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE);
4398c2ecf20Sopenharmony_ci	if (!err) {
4408c2ecf20Sopenharmony_ci		dev_err(&client->dev, "%s adapter not supported\n",
4418c2ecf20Sopenharmony_ci			dev_driver_string(&client->adapter->dev));
4428c2ecf20Sopenharmony_ci		return -ENODEV;
4438c2ecf20Sopenharmony_ci	}
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_ci	if (!client->irq) {
4468c2ecf20Sopenharmony_ci		dev_err(dev, "assign a irq line to this device\n");
4478c2ecf20Sopenharmony_ci		return -EINVAL;
4488c2ecf20Sopenharmony_ci	}
4498c2ecf20Sopenharmony_ci
4508c2ecf20Sopenharmony_ci	ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
4518c2ecf20Sopenharmony_ci	if (!ts)
4528c2ecf20Sopenharmony_ci		return -ENOMEM;
4538c2ecf20Sopenharmony_ci
4548c2ecf20Sopenharmony_ci	input = devm_input_allocate_device(dev);
4558c2ecf20Sopenharmony_ci	if (!input)
4568c2ecf20Sopenharmony_ci		return -ENOMEM;
4578c2ecf20Sopenharmony_ci
4588c2ecf20Sopenharmony_ci	map = devm_regmap_init_i2c(client, &qt1050_regmap_config);
4598c2ecf20Sopenharmony_ci	if (IS_ERR(map))
4608c2ecf20Sopenharmony_ci		return PTR_ERR(map);
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci	ts->client = client;
4638c2ecf20Sopenharmony_ci	ts->input = input;
4648c2ecf20Sopenharmony_ci	ts->regmap = map;
4658c2ecf20Sopenharmony_ci
4668c2ecf20Sopenharmony_ci	i2c_set_clientdata(client, ts);
4678c2ecf20Sopenharmony_ci
4688c2ecf20Sopenharmony_ci	/* Identify the qt1050 chip */
4698c2ecf20Sopenharmony_ci	if (!qt1050_identify(ts))
4708c2ecf20Sopenharmony_ci		return -ENODEV;
4718c2ecf20Sopenharmony_ci
4728c2ecf20Sopenharmony_ci	/* Get pdata */
4738c2ecf20Sopenharmony_ci	err = qt1050_parse_fw(ts);
4748c2ecf20Sopenharmony_ci	if (err) {
4758c2ecf20Sopenharmony_ci		dev_err(dev, "Failed to parse firmware: %d\n", err);
4768c2ecf20Sopenharmony_ci		return err;
4778c2ecf20Sopenharmony_ci	}
4788c2ecf20Sopenharmony_ci
4798c2ecf20Sopenharmony_ci	input->name = "AT42QT1050 QTouch Sensor";
4808c2ecf20Sopenharmony_ci	input->dev.parent = &client->dev;
4818c2ecf20Sopenharmony_ci	input->id.bustype = BUS_I2C;
4828c2ecf20Sopenharmony_ci
4838c2ecf20Sopenharmony_ci	/* Add the keycode */
4848c2ecf20Sopenharmony_ci	input->keycode = ts->keycodes;
4858c2ecf20Sopenharmony_ci	input->keycodesize = sizeof(ts->keycodes[0]);
4868c2ecf20Sopenharmony_ci	input->keycodemax = QT1050_MAX_KEYS;
4878c2ecf20Sopenharmony_ci
4888c2ecf20Sopenharmony_ci	__set_bit(EV_KEY, input->evbit);
4898c2ecf20Sopenharmony_ci	for (i = 0; i < QT1050_MAX_KEYS; i++) {
4908c2ecf20Sopenharmony_ci		ts->keycodes[i] = ts->keys[i].keycode;
4918c2ecf20Sopenharmony_ci		__set_bit(ts->keycodes[i], input->keybit);
4928c2ecf20Sopenharmony_ci	}
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_ci	/* Trigger re-calibration */
4958c2ecf20Sopenharmony_ci	err = regmap_update_bits(ts->regmap, QT1050_RES_CAL, 0x7f,
4968c2ecf20Sopenharmony_ci				 QT1050_RES_CAL_CALIBRATE);
4978c2ecf20Sopenharmony_ci	if (err) {
4988c2ecf20Sopenharmony_ci		dev_err(dev, "Trigger calibration failed: %d\n", err);
4998c2ecf20Sopenharmony_ci		return err;
5008c2ecf20Sopenharmony_ci	}
5018c2ecf20Sopenharmony_ci	err = regmap_read_poll_timeout(ts->regmap, QT1050_DET_STATUS, status,
5028c2ecf20Sopenharmony_ci				 status >> 7 == 1, 10000, 200000);
5038c2ecf20Sopenharmony_ci	if (err) {
5048c2ecf20Sopenharmony_ci		dev_err(dev, "Calibration failed: %d\n", err);
5058c2ecf20Sopenharmony_ci		return err;
5068c2ecf20Sopenharmony_ci	}
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci	/* Soft reset to set defaults */
5098c2ecf20Sopenharmony_ci	err = regmap_update_bits(ts->regmap, QT1050_RES_CAL,
5108c2ecf20Sopenharmony_ci				 QT1050_RES_CAL_RESET, QT1050_RES_CAL_RESET);
5118c2ecf20Sopenharmony_ci	if (err) {
5128c2ecf20Sopenharmony_ci		dev_err(dev, "Trigger soft reset failed: %d\n", err);
5138c2ecf20Sopenharmony_ci		return err;
5148c2ecf20Sopenharmony_ci	}
5158c2ecf20Sopenharmony_ci	msleep(QT1050_RESET_TIME);
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_ci	/* Set pdata */
5188c2ecf20Sopenharmony_ci	err = qt1050_apply_fw_data(ts);
5198c2ecf20Sopenharmony_ci	if (err) {
5208c2ecf20Sopenharmony_ci		dev_err(dev, "Failed to set firmware data: %d\n", err);
5218c2ecf20Sopenharmony_ci		return err;
5228c2ecf20Sopenharmony_ci	}
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_ci	err = devm_request_threaded_irq(dev, client->irq, NULL,
5258c2ecf20Sopenharmony_ci					qt1050_irq_threaded, IRQF_ONESHOT,
5268c2ecf20Sopenharmony_ci					"qt1050", ts);
5278c2ecf20Sopenharmony_ci	if (err) {
5288c2ecf20Sopenharmony_ci		dev_err(&client->dev, "Failed to request irq: %d\n", err);
5298c2ecf20Sopenharmony_ci		return err;
5308c2ecf20Sopenharmony_ci	}
5318c2ecf20Sopenharmony_ci
5328c2ecf20Sopenharmony_ci	/* Clear #CHANGE line */
5338c2ecf20Sopenharmony_ci	err = regmap_read(ts->regmap, QT1050_DET_STATUS, &status);
5348c2ecf20Sopenharmony_ci	if (err) {
5358c2ecf20Sopenharmony_ci		dev_err(dev, "Failed to clear #CHANGE line level: %d\n", err);
5368c2ecf20Sopenharmony_ci		return err;
5378c2ecf20Sopenharmony_ci	}
5388c2ecf20Sopenharmony_ci
5398c2ecf20Sopenharmony_ci	/* Register the input device */
5408c2ecf20Sopenharmony_ci	err = input_register_device(ts->input);
5418c2ecf20Sopenharmony_ci	if (err) {
5428c2ecf20Sopenharmony_ci		dev_err(&client->dev, "Failed to register input device: %d\n",
5438c2ecf20Sopenharmony_ci			err);
5448c2ecf20Sopenharmony_ci		return err;
5458c2ecf20Sopenharmony_ci	}
5468c2ecf20Sopenharmony_ci
5478c2ecf20Sopenharmony_ci	return 0;
5488c2ecf20Sopenharmony_ci}
5498c2ecf20Sopenharmony_ci
5508c2ecf20Sopenharmony_cistatic int __maybe_unused qt1050_suspend(struct device *dev)
5518c2ecf20Sopenharmony_ci{
5528c2ecf20Sopenharmony_ci	struct i2c_client *client = to_i2c_client(dev);
5538c2ecf20Sopenharmony_ci	struct qt1050_priv *ts = i2c_get_clientdata(client);
5548c2ecf20Sopenharmony_ci
5558c2ecf20Sopenharmony_ci	disable_irq(client->irq);
5568c2ecf20Sopenharmony_ci
5578c2ecf20Sopenharmony_ci	/*
5588c2ecf20Sopenharmony_ci	 * Set measurement interval to 1s (125 x 8ms) if wakeup is allowed
5598c2ecf20Sopenharmony_ci	 * else turn off. The 1s interval seems to be a good compromise between
5608c2ecf20Sopenharmony_ci	 * low power and response time.
5618c2ecf20Sopenharmony_ci	 */
5628c2ecf20Sopenharmony_ci	return regmap_write(ts->regmap, QT1050_LPMODE,
5638c2ecf20Sopenharmony_ci			    device_may_wakeup(dev) ? 125 : 0);
5648c2ecf20Sopenharmony_ci}
5658c2ecf20Sopenharmony_ci
5668c2ecf20Sopenharmony_cistatic int __maybe_unused qt1050_resume(struct device *dev)
5678c2ecf20Sopenharmony_ci{
5688c2ecf20Sopenharmony_ci	struct i2c_client *client = to_i2c_client(dev);
5698c2ecf20Sopenharmony_ci	struct qt1050_priv *ts = i2c_get_clientdata(client);
5708c2ecf20Sopenharmony_ci
5718c2ecf20Sopenharmony_ci	enable_irq(client->irq);
5728c2ecf20Sopenharmony_ci
5738c2ecf20Sopenharmony_ci	/* Set measurement interval back to 16ms (2 x 8ms) */
5748c2ecf20Sopenharmony_ci	return regmap_write(ts->regmap, QT1050_LPMODE, 2);
5758c2ecf20Sopenharmony_ci}
5768c2ecf20Sopenharmony_ci
5778c2ecf20Sopenharmony_cistatic SIMPLE_DEV_PM_OPS(qt1050_pm_ops, qt1050_suspend, qt1050_resume);
5788c2ecf20Sopenharmony_ci
5798c2ecf20Sopenharmony_cistatic const struct of_device_id __maybe_unused qt1050_of_match[] = {
5808c2ecf20Sopenharmony_ci	{ .compatible = "microchip,qt1050", },
5818c2ecf20Sopenharmony_ci	{ },
5828c2ecf20Sopenharmony_ci};
5838c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, qt1050_of_match);
5848c2ecf20Sopenharmony_ci
5858c2ecf20Sopenharmony_cistatic struct i2c_driver qt1050_driver = {
5868c2ecf20Sopenharmony_ci	.driver	= {
5878c2ecf20Sopenharmony_ci		.name = "qt1050",
5888c2ecf20Sopenharmony_ci		.of_match_table = of_match_ptr(qt1050_of_match),
5898c2ecf20Sopenharmony_ci		.pm = &qt1050_pm_ops,
5908c2ecf20Sopenharmony_ci	},
5918c2ecf20Sopenharmony_ci	.probe_new = qt1050_probe,
5928c2ecf20Sopenharmony_ci};
5938c2ecf20Sopenharmony_ci
5948c2ecf20Sopenharmony_cimodule_i2c_driver(qt1050_driver);
5958c2ecf20Sopenharmony_ci
5968c2ecf20Sopenharmony_ciMODULE_AUTHOR("Marco Felsch <kernel@pengutronix.de");
5978c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Driver for AT42QT1050 QTouch sensor");
5988c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2");
599