cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sx9324.c (31093B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright 2021 Google LLC.
      4 *
      5 * Driver for Semtech's SX9324 capacitive proximity/button solution.
      6 * Based on SX9324 driver and copy of datasheet at:
      7 * https://edit.wpgdadawant.com/uploads/news_file/program/2019/30184/tech_files/program_30184_suggest_other_file.pdf
      8 */
      9
     10#include <linux/acpi.h>
     11#include <linux/bits.h>
     12#include <linux/bitfield.h>
     13#include <linux/delay.h>
     14#include <linux/i2c.h>
     15#include <linux/interrupt.h>
     16#include <linux/kernel.h>
     17#include <linux/log2.h>
     18#include <linux/mod_devicetable.h>
     19#include <linux/module.h>
     20#include <linux/pm.h>
     21#include <linux/property.h>
     22#include <linux/regmap.h>
     23
     24#include <linux/iio/iio.h>
     25
     26#include "sx_common.h"
     27
     28/* Register definitions. */
     29#define SX9324_REG_IRQ_SRC		SX_COMMON_REG_IRQ_SRC
     30#define SX9324_REG_STAT0		0x01
     31#define SX9324_REG_STAT1		0x02
     32#define SX9324_REG_STAT2		0x03
     33#define SX9324_REG_STAT2_COMPSTAT_MASK	GENMASK(3, 0)
     34#define SX9324_REG_STAT3		0x04
     35#define SX9324_REG_IRQ_MSK		0x05
     36#define SX9324_CONVDONE_IRQ		BIT(3)
     37#define SX9324_FAR_IRQ			BIT(5)
     38#define SX9324_CLOSE_IRQ		BIT(6)
     39#define SX9324_REG_IRQ_CFG0		0x06
     40#define SX9324_REG_IRQ_CFG1		0x07
     41#define SX9324_REG_IRQ_CFG1_FAILCOND    0x80
     42#define SX9324_REG_IRQ_CFG2		0x08
     43
     44#define SX9324_REG_GNRL_CTRL0		0x10
     45#define SX9324_REG_GNRL_CTRL0_SCANPERIOD_MASK GENMASK(4, 0)
     46#define SX9324_REG_GNRL_CTRL0_SCANPERIOD_100MS 0x16
     47#define SX9324_REG_GNRL_CTRL1		0x11
     48#define SX9324_REG_GNRL_CTRL1_PHEN_MASK GENMASK(3, 0)
     49#define SX9324_REG_GNRL_CTRL1_PAUSECTRL 0x20
     50
     51#define SX9324_REG_I2C_ADDR		0x14
     52#define SX9324_REG_CLK_SPRD		0x15
     53
     54#define SX9324_REG_AFE_CTRL0		0x20
     55#define SX9324_REG_AFE_CTRL1		0x21
     56#define SX9324_REG_AFE_CTRL2		0x22
     57#define SX9324_REG_AFE_CTRL3		0x23
     58#define SX9324_REG_AFE_CTRL4		0x24
     59#define SX9324_REG_AFE_CTRL4_FREQ_83_33HZ 0x40
     60#define SX9324_REG_AFE_CTRL4_RESOLUTION_MASK GENMASK(2, 0)
     61#define SX9324_REG_AFE_CTRL4_RES_100	0x04
     62#define SX9324_REG_AFE_CTRL5		0x25
     63#define SX9324_REG_AFE_CTRL6		0x26
     64#define SX9324_REG_AFE_CTRL7		0x27
     65#define SX9324_REG_AFE_PH0		0x28
     66#define SX9324_REG_AFE_PH0_PIN_MASK(_pin) \
     67	GENMASK(2 * (_pin) + 1, 2 * (_pin))
     68
     69#define SX9324_REG_AFE_PH1		0x29
     70#define SX9324_REG_AFE_PH2		0x2a
     71#define SX9324_REG_AFE_PH3		0x2b
     72#define SX9324_REG_AFE_CTRL8		0x2c
     73#define SX9324_REG_AFE_CTRL8_RESERVED	0x10
     74#define SX9324_REG_AFE_CTRL8_RESFILTIN_4KOHM 0x02
     75#define SX9324_REG_AFE_CTRL9		0x2d
     76#define SX9324_REG_AFE_CTRL9_AGAIN_1	0x08
     77
     78#define SX9324_REG_PROX_CTRL0		0x30
     79#define SX9324_REG_PROX_CTRL0_GAIN_MASK	GENMASK(5, 3)
     80#define SX9324_REG_PROX_CTRL0_GAIN_SHIFT	3
     81#define SX9324_REG_PROX_CTRL0_GAIN_RSVD		0x0
     82#define SX9324_REG_PROX_CTRL0_GAIN_1		0x1
     83#define SX9324_REG_PROX_CTRL0_GAIN_8		0x4
     84#define SX9324_REG_PROX_CTRL0_RAWFILT_MASK	GENMASK(2, 0)
     85#define SX9324_REG_PROX_CTRL0_RAWFILT_1P50	0x01
     86#define SX9324_REG_PROX_CTRL1		0x31
     87#define SX9324_REG_PROX_CTRL2		0x32
     88#define SX9324_REG_PROX_CTRL2_AVGNEG_THRESH_16K 0x20
     89#define SX9324_REG_PROX_CTRL3		0x33
     90#define SX9324_REG_PROX_CTRL3_AVGDEB_2SAMPLES	0x40
     91#define SX9324_REG_PROX_CTRL3_AVGPOS_THRESH_16K 0x20
     92#define SX9324_REG_PROX_CTRL4		0x34
     93#define SX9324_REG_PROX_CTRL4_AVGNEGFILT_MASK	GENMASK(5, 3)
     94#define SX9324_REG_PROX_CTRL4_AVGNEG_FILT_2 0x08
     95#define SX9324_REG_PROX_CTRL4_AVGPOSFILT_MASK	GENMASK(2, 0)
     96#define SX9324_REG_PROX_CTRL3_AVGPOS_FILT_256 0x04
     97#define SX9324_REG_PROX_CTRL5		0x35
     98#define SX9324_REG_PROX_CTRL5_HYST_MASK			GENMASK(5, 4)
     99#define SX9324_REG_PROX_CTRL5_CLOSE_DEBOUNCE_MASK	GENMASK(3, 2)
    100#define SX9324_REG_PROX_CTRL5_FAR_DEBOUNCE_MASK		GENMASK(1, 0)
    101#define SX9324_REG_PROX_CTRL6		0x36
    102#define SX9324_REG_PROX_CTRL6_PROXTHRESH_32	0x08
    103#define SX9324_REG_PROX_CTRL7		0x37
    104
    105#define SX9324_REG_ADV_CTRL0		0x40
    106#define SX9324_REG_ADV_CTRL1		0x41
    107#define SX9324_REG_ADV_CTRL2		0x42
    108#define SX9324_REG_ADV_CTRL3		0x43
    109#define SX9324_REG_ADV_CTRL4		0x44
    110#define SX9324_REG_ADV_CTRL5		0x45
    111#define SX9324_REG_ADV_CTRL5_STARTUPSENS_MASK GENMASK(3, 2)
    112#define SX9324_REG_ADV_CTRL5_STARTUP_SENSOR_1	0x04
    113#define SX9324_REG_ADV_CTRL5_STARTUP_METHOD_1	0x01
    114#define SX9324_REG_ADV_CTRL6		0x46
    115#define SX9324_REG_ADV_CTRL7		0x47
    116#define SX9324_REG_ADV_CTRL8		0x48
    117#define SX9324_REG_ADV_CTRL9		0x49
    118#define SX9324_REG_ADV_CTRL10		0x4a
    119#define SX9324_REG_ADV_CTRL11		0x4b
    120#define SX9324_REG_ADV_CTRL12		0x4c
    121#define SX9324_REG_ADV_CTRL13		0x4d
    122#define SX9324_REG_ADV_CTRL14		0x4e
    123#define SX9324_REG_ADV_CTRL15		0x4f
    124#define SX9324_REG_ADV_CTRL16		0x50
    125#define SX9324_REG_ADV_CTRL17		0x51
    126#define SX9324_REG_ADV_CTRL18		0x52
    127#define SX9324_REG_ADV_CTRL19		0x53
    128#define SX9324_REG_ADV_CTRL20		0x54
    129#define SX9324_REG_ADV_CTRL19_HIGHT_FAILURE_THRESH_SATURATION 0xf0
    130
    131#define SX9324_REG_PHASE_SEL		0x60
    132
    133#define SX9324_REG_USEFUL_MSB		0x61
    134#define SX9324_REG_USEFUL_LSB		0x62
    135
    136#define SX9324_REG_AVG_MSB		0x63
    137#define SX9324_REG_AVG_LSB		0x64
    138
    139#define SX9324_REG_DIFF_MSB		0x65
    140#define SX9324_REG_DIFF_LSB		0x66
    141
    142#define SX9324_REG_OFFSET_MSB		0x67
    143#define SX9324_REG_OFFSET_LSB		0x68
    144
    145#define SX9324_REG_SAR_MSB		0x69
    146#define SX9324_REG_SAR_LSB		0x6a
    147
    148#define SX9324_REG_RESET		0x9f
    149/* Write this to REG_RESET to do a soft reset. */
    150#define SX9324_SOFT_RESET		0xde
    151
    152#define SX9324_REG_WHOAMI		0xfa
    153#define   SX9324_WHOAMI_VALUE		0x23
    154
    155#define SX9324_REG_REVISION		0xfe
    156
    157/* 4 channels, as defined in STAT0: PH0, PH1, PH2 and PH3. */
    158#define SX9324_NUM_CHANNELS		4
    159/* 3 CS pins: CS0, CS1, CS2. */
    160#define SX9324_NUM_PINS			3
    161
    162static const char * const sx9324_cs_pin_usage[] = { "HZ", "MI", "DS", "GD" };
    163
    164static ssize_t sx9324_phase_configuration_show(struct iio_dev *indio_dev,
    165					       uintptr_t private,
    166					       const struct iio_chan_spec *chan,
    167					       char *buf)
    168{
    169	struct sx_common_data *data = iio_priv(indio_dev);
    170	unsigned int val;
    171	int i, ret, pin_idx;
    172	size_t len = 0;
    173
    174	ret = regmap_read(data->regmap, SX9324_REG_AFE_PH0 + chan->channel, &val);
    175	if (ret < 0)
    176		return ret;
    177
    178	for (i = 0; i < SX9324_NUM_PINS; i++) {
    179		pin_idx = (val & SX9324_REG_AFE_PH0_PIN_MASK(i)) >> (2 * i);
    180		len += sysfs_emit_at(buf, len, "%s,",
    181				     sx9324_cs_pin_usage[pin_idx]);
    182	}
    183	buf[len - 1] = '\n';
    184	return len;
    185}
    186
    187static const struct iio_chan_spec_ext_info sx9324_channel_ext_info[] = {
    188	{
    189		.name = "setup",
    190		.shared = IIO_SEPARATE,
    191		.read = sx9324_phase_configuration_show,
    192	},
    193	{}
    194};
    195
    196#define SX9324_CHANNEL(idx)					 \
    197{								 \
    198	.type = IIO_PROXIMITY,					 \
    199	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |		 \
    200			      BIT(IIO_CHAN_INFO_HARDWAREGAIN),	 \
    201	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
    202	.info_mask_separate_available =				 \
    203		BIT(IIO_CHAN_INFO_HARDWAREGAIN),		 \
    204	.info_mask_shared_by_all_available =			 \
    205		BIT(IIO_CHAN_INFO_SAMP_FREQ),			 \
    206	.indexed = 1,						 \
    207	.channel = idx,						 \
    208	.address = SX9324_REG_DIFF_MSB,				 \
    209	.event_spec = sx_common_events,				 \
    210	.num_event_specs = ARRAY_SIZE(sx_common_events),	 \
    211	.scan_index = idx,					 \
    212	.scan_type = {						 \
    213		.sign = 's',					 \
    214		.realbits = 12,					 \
    215		.storagebits = 16,				 \
    216		.endianness = IIO_BE,				 \
    217	},							 \
    218	.ext_info = sx9324_channel_ext_info,			 \
    219}
    220
    221static const struct iio_chan_spec sx9324_channels[] = {
    222	SX9324_CHANNEL(0),			/* Phase 0 */
    223	SX9324_CHANNEL(1),			/* Phase 1 */
    224	SX9324_CHANNEL(2),			/* Phase 2 */
    225	SX9324_CHANNEL(3),			/* Phase 3 */
    226	IIO_CHAN_SOFT_TIMESTAMP(4),
    227};
    228
    229/*
    230 * Each entry contains the integer part (val) and the fractional part, in micro
    231 * seconds. It conforms to the IIO output IIO_VAL_INT_PLUS_MICRO.
    232 */
    233static const struct {
    234	int val;
    235	int val2;
    236} sx9324_samp_freq_table[] = {
    237	{ 1000, 0 },  /* 00000: Min (no idle time) */
    238	{ 500, 0 },  /* 00001: 2 ms */
    239	{ 250, 0 },  /* 00010: 4 ms */
    240	{ 166, 666666 },  /* 00011: 6 ms */
    241	{ 125, 0 },  /* 00100: 8 ms */
    242	{ 100, 0 },  /* 00101: 10 ms */
    243	{ 71, 428571 },  /* 00110: 14 ms */
    244	{ 55, 555556 },  /* 00111: 18 ms */
    245	{ 45, 454545 },  /* 01000: 22 ms */
    246	{ 38, 461538 },  /* 01001: 26 ms */
    247	{ 33, 333333 },  /* 01010: 30 ms */
    248	{ 29, 411765 },  /* 01011: 34 ms */
    249	{ 26, 315789 },  /* 01100: 38 ms */
    250	{ 23, 809524 },  /* 01101: 42 ms */
    251	{ 21, 739130 },  /* 01110: 46 ms */
    252	{ 20, 0 },  /* 01111: 50 ms */
    253	{ 17, 857143 },  /* 10000: 56 ms */
    254	{ 16, 129032 },  /* 10001: 62 ms */
    255	{ 14, 705882 },  /* 10010: 68 ms */
    256	{ 13, 513514 },  /* 10011: 74 ms */
    257	{ 12, 500000 },  /* 10100: 80 ms */
    258	{ 11, 111111 },  /* 10101: 90 ms */
    259	{ 10, 0 },  /* 10110: 100 ms (Typ.) */
    260	{ 5, 0 },  /* 10111: 200 ms */
    261	{ 3, 333333 },  /* 11000: 300 ms */
    262	{ 2, 500000 },  /* 11001: 400 ms */
    263	{ 1, 666667 },  /* 11010: 600 ms */
    264	{ 1, 250000 },  /* 11011: 800 ms */
    265	{ 1, 0 },  /* 11100: 1 s */
    266	{ 0, 500000 },  /* 11101: 2 s */
    267	{ 0, 333333 },  /* 11110: 3 s */
    268	{ 0, 250000 },  /* 11111: 4 s */
    269};
    270
    271static const unsigned int sx9324_scan_period_table[] = {
    272	2,   15,  30,  45,   60,   90,	 120,  200,
    273	400, 600, 800, 1000, 2000, 3000, 4000, 5000,
    274};
    275
    276static const struct regmap_range sx9324_writable_reg_ranges[] = {
    277	/*
    278	 * To set COMPSTAT for compensation, even if datasheet says register is
    279	 * RO.
    280	 */
    281	regmap_reg_range(SX9324_REG_STAT2, SX9324_REG_STAT2),
    282	regmap_reg_range(SX9324_REG_IRQ_MSK, SX9324_REG_IRQ_CFG2),
    283	regmap_reg_range(SX9324_REG_GNRL_CTRL0, SX9324_REG_GNRL_CTRL1),
    284	/* Leave i2c and clock spreading as unavailable */
    285	regmap_reg_range(SX9324_REG_AFE_CTRL0, SX9324_REG_AFE_CTRL9),
    286	regmap_reg_range(SX9324_REG_PROX_CTRL0, SX9324_REG_PROX_CTRL7),
    287	regmap_reg_range(SX9324_REG_ADV_CTRL0, SX9324_REG_ADV_CTRL20),
    288	regmap_reg_range(SX9324_REG_PHASE_SEL, SX9324_REG_PHASE_SEL),
    289	regmap_reg_range(SX9324_REG_OFFSET_MSB, SX9324_REG_OFFSET_LSB),
    290	regmap_reg_range(SX9324_REG_RESET, SX9324_REG_RESET),
    291};
    292
    293static const struct regmap_access_table sx9324_writeable_regs = {
    294	.yes_ranges = sx9324_writable_reg_ranges,
    295	.n_yes_ranges = ARRAY_SIZE(sx9324_writable_reg_ranges),
    296};
    297
    298/*
    299 * All allocated registers are readable, so we just list unallocated
    300 * ones.
    301 */
    302static const struct regmap_range sx9324_non_readable_reg_ranges[] = {
    303	regmap_reg_range(SX9324_REG_IRQ_CFG2 + 1, SX9324_REG_GNRL_CTRL0 - 1),
    304	regmap_reg_range(SX9324_REG_GNRL_CTRL1 + 1, SX9324_REG_AFE_CTRL0 - 1),
    305	regmap_reg_range(SX9324_REG_AFE_CTRL9 + 1, SX9324_REG_PROX_CTRL0 - 1),
    306	regmap_reg_range(SX9324_REG_PROX_CTRL7 + 1, SX9324_REG_ADV_CTRL0 - 1),
    307	regmap_reg_range(SX9324_REG_ADV_CTRL20 + 1, SX9324_REG_PHASE_SEL - 1),
    308	regmap_reg_range(SX9324_REG_SAR_LSB + 1, SX9324_REG_RESET - 1),
    309	regmap_reg_range(SX9324_REG_RESET + 1, SX9324_REG_WHOAMI - 1),
    310	regmap_reg_range(SX9324_REG_WHOAMI + 1, SX9324_REG_REVISION - 1),
    311};
    312
    313static const struct regmap_access_table sx9324_readable_regs = {
    314	.no_ranges = sx9324_non_readable_reg_ranges,
    315	.n_no_ranges = ARRAY_SIZE(sx9324_non_readable_reg_ranges),
    316};
    317
    318static const struct regmap_range sx9324_volatile_reg_ranges[] = {
    319	regmap_reg_range(SX9324_REG_IRQ_SRC, SX9324_REG_STAT3),
    320	regmap_reg_range(SX9324_REG_USEFUL_MSB, SX9324_REG_DIFF_LSB),
    321	regmap_reg_range(SX9324_REG_SAR_MSB, SX9324_REG_SAR_LSB),
    322	regmap_reg_range(SX9324_REG_WHOAMI, SX9324_REG_WHOAMI),
    323	regmap_reg_range(SX9324_REG_REVISION, SX9324_REG_REVISION),
    324};
    325
    326static const struct regmap_access_table sx9324_volatile_regs = {
    327	.yes_ranges = sx9324_volatile_reg_ranges,
    328	.n_yes_ranges = ARRAY_SIZE(sx9324_volatile_reg_ranges),
    329};
    330
    331static const struct regmap_config sx9324_regmap_config = {
    332	.reg_bits = 8,
    333	.val_bits = 8,
    334
    335	.max_register = SX9324_REG_REVISION,
    336	.cache_type = REGCACHE_RBTREE,
    337
    338	.wr_table = &sx9324_writeable_regs,
    339	.rd_table = &sx9324_readable_regs,
    340	.volatile_table = &sx9324_volatile_regs,
    341};
    342
    343static int sx9324_read_prox_data(struct sx_common_data *data,
    344				 const struct iio_chan_spec *chan,
    345				 __be16 *val)
    346{
    347	int ret;
    348
    349	ret = regmap_write(data->regmap, SX9324_REG_PHASE_SEL, chan->channel);
    350	if (ret < 0)
    351		return ret;
    352
    353	return regmap_bulk_read(data->regmap, chan->address, val, sizeof(*val));
    354}
    355
    356/*
    357 * If we have no interrupt support, we have to wait for a scan period
    358 * after enabling a channel to get a result.
    359 */
    360static int sx9324_wait_for_sample(struct sx_common_data *data)
    361{
    362	int ret;
    363	unsigned int val;
    364
    365	ret = regmap_read(data->regmap, SX9324_REG_GNRL_CTRL0, &val);
    366	if (ret < 0)
    367		return ret;
    368	val = FIELD_GET(SX9324_REG_GNRL_CTRL0_SCANPERIOD_MASK, val);
    369
    370	msleep(sx9324_scan_period_table[val]);
    371
    372	return 0;
    373}
    374
    375static int sx9324_read_gain(struct sx_common_data *data,
    376			    const struct iio_chan_spec *chan, int *val)
    377{
    378	unsigned int reg, regval;
    379	int ret;
    380
    381	reg = SX9324_REG_PROX_CTRL0 + chan->channel / 2;
    382	ret = regmap_read(data->regmap, reg, &regval);
    383	if (ret)
    384		return ret;
    385
    386	regval = FIELD_GET(SX9324_REG_PROX_CTRL0_GAIN_MASK, regval);
    387	if (regval)
    388		regval--;
    389	else if (regval == SX9324_REG_PROX_CTRL0_GAIN_RSVD ||
    390		 regval > SX9324_REG_PROX_CTRL0_GAIN_8)
    391		return -EINVAL;
    392
    393	*val = 1 << regval;
    394
    395	return IIO_VAL_INT;
    396}
    397
    398static int sx9324_read_samp_freq(struct sx_common_data *data,
    399				 int *val, int *val2)
    400{
    401	int ret;
    402	unsigned int regval;
    403
    404	ret = regmap_read(data->regmap, SX9324_REG_GNRL_CTRL0, &regval);
    405	if (ret)
    406		return ret;
    407
    408	regval = FIELD_GET(SX9324_REG_GNRL_CTRL0_SCANPERIOD_MASK, regval);
    409	*val = sx9324_samp_freq_table[regval].val;
    410	*val2 = sx9324_samp_freq_table[regval].val2;
    411
    412	return IIO_VAL_INT_PLUS_MICRO;
    413}
    414
    415static int sx9324_read_raw(struct iio_dev *indio_dev,
    416			   const struct iio_chan_spec *chan,
    417			   int *val, int *val2, long mask)
    418{
    419	struct sx_common_data *data = iio_priv(indio_dev);
    420	int ret;
    421
    422	switch (mask) {
    423	case IIO_CHAN_INFO_RAW:
    424		ret = iio_device_claim_direct_mode(indio_dev);
    425		if (ret)
    426			return ret;
    427
    428		ret = sx_common_read_proximity(data, chan, val);
    429		iio_device_release_direct_mode(indio_dev);
    430		return ret;
    431	case IIO_CHAN_INFO_HARDWAREGAIN:
    432		ret = iio_device_claim_direct_mode(indio_dev);
    433		if (ret)
    434			return ret;
    435
    436		ret = sx9324_read_gain(data, chan, val);
    437		iio_device_release_direct_mode(indio_dev);
    438		return ret;
    439	case IIO_CHAN_INFO_SAMP_FREQ:
    440		return sx9324_read_samp_freq(data, val, val2);
    441	default:
    442		return -EINVAL;
    443	}
    444}
    445
    446static const int sx9324_gain_vals[] = { 1, 2, 4, 8 };
    447
    448static int sx9324_read_avail(struct iio_dev *indio_dev,
    449			     struct iio_chan_spec const *chan,
    450			     const int **vals, int *type, int *length,
    451			     long mask)
    452{
    453	if (chan->type != IIO_PROXIMITY)
    454		return -EINVAL;
    455
    456	switch (mask) {
    457	case IIO_CHAN_INFO_HARDWAREGAIN:
    458		*type = IIO_VAL_INT;
    459		*length = ARRAY_SIZE(sx9324_gain_vals);
    460		*vals = sx9324_gain_vals;
    461		return IIO_AVAIL_LIST;
    462	case IIO_CHAN_INFO_SAMP_FREQ:
    463		*type = IIO_VAL_INT_PLUS_MICRO;
    464		*length = ARRAY_SIZE(sx9324_samp_freq_table) * 2;
    465		*vals = (int *)sx9324_samp_freq_table;
    466		return IIO_AVAIL_LIST;
    467	default:
    468		return -EINVAL;
    469	}
    470}
    471
    472static int sx9324_set_samp_freq(struct sx_common_data *data,
    473				int val, int val2)
    474{
    475	int i, ret;
    476
    477	for (i = 0; i < ARRAY_SIZE(sx9324_samp_freq_table); i++)
    478		if (val == sx9324_samp_freq_table[i].val &&
    479		    val2 == sx9324_samp_freq_table[i].val2)
    480			break;
    481
    482	if (i == ARRAY_SIZE(sx9324_samp_freq_table))
    483		return -EINVAL;
    484
    485	mutex_lock(&data->mutex);
    486
    487	ret = regmap_update_bits(data->regmap,
    488				 SX9324_REG_GNRL_CTRL0,
    489				 SX9324_REG_GNRL_CTRL0_SCANPERIOD_MASK, i);
    490
    491	mutex_unlock(&data->mutex);
    492
    493	return ret;
    494}
    495
    496static int sx9324_read_thresh(struct sx_common_data *data,
    497			      const struct iio_chan_spec *chan, int *val)
    498{
    499	unsigned int regval;
    500	unsigned int reg;
    501	int ret;
    502
    503	/*
    504	 * TODO(gwendal): Depending on the phase function
    505	 * (proximity/table/body), retrieve the right threshold.
    506	 * For now, return the proximity threshold.
    507	 */
    508	reg = SX9324_REG_PROX_CTRL6 + chan->channel / 2;
    509	ret = regmap_read(data->regmap, reg, &regval);
    510	if (ret)
    511		return ret;
    512
    513	if (regval <= 1)
    514		*val = regval;
    515	else
    516		*val = (regval * regval) / 2;
    517
    518	return IIO_VAL_INT;
    519}
    520
    521static int sx9324_read_hysteresis(struct sx_common_data *data,
    522				  const struct iio_chan_spec *chan, int *val)
    523{
    524	unsigned int regval, pthresh;
    525	int ret;
    526
    527	ret = sx9324_read_thresh(data, chan, &pthresh);
    528	if (ret < 0)
    529		return ret;
    530
    531	ret = regmap_read(data->regmap, SX9324_REG_PROX_CTRL5, &regval);
    532	if (ret)
    533		return ret;
    534
    535	regval = FIELD_GET(SX9324_REG_PROX_CTRL5_HYST_MASK, regval);
    536	if (!regval)
    537		*val = 0;
    538	else
    539		*val = pthresh >> (5 - regval);
    540
    541	return IIO_VAL_INT;
    542}
    543
    544static int sx9324_read_far_debounce(struct sx_common_data *data, int *val)
    545{
    546	unsigned int regval;
    547	int ret;
    548
    549	ret = regmap_read(data->regmap, SX9324_REG_PROX_CTRL5, &regval);
    550	if (ret)
    551		return ret;
    552
    553	regval = FIELD_GET(SX9324_REG_PROX_CTRL5_FAR_DEBOUNCE_MASK, regval);
    554	if (regval)
    555		*val = 1 << regval;
    556	else
    557		*val = 0;
    558
    559	return IIO_VAL_INT;
    560}
    561
    562static int sx9324_read_close_debounce(struct sx_common_data *data, int *val)
    563{
    564	unsigned int regval;
    565	int ret;
    566
    567	ret = regmap_read(data->regmap, SX9324_REG_PROX_CTRL5, &regval);
    568	if (ret)
    569		return ret;
    570
    571	regval = FIELD_GET(SX9324_REG_PROX_CTRL5_CLOSE_DEBOUNCE_MASK, regval);
    572	if (regval)
    573		*val = 1 << regval;
    574	else
    575		*val = 0;
    576
    577	return IIO_VAL_INT;
    578}
    579
    580static int sx9324_read_event_val(struct iio_dev *indio_dev,
    581				 const struct iio_chan_spec *chan,
    582				 enum iio_event_type type,
    583				 enum iio_event_direction dir,
    584				 enum iio_event_info info, int *val, int *val2)
    585{
    586	struct sx_common_data *data = iio_priv(indio_dev);
    587
    588	if (chan->type != IIO_PROXIMITY)
    589		return -EINVAL;
    590
    591	switch (info) {
    592	case IIO_EV_INFO_VALUE:
    593		return sx9324_read_thresh(data, chan, val);
    594	case IIO_EV_INFO_PERIOD:
    595		switch (dir) {
    596		case IIO_EV_DIR_RISING:
    597			return sx9324_read_far_debounce(data, val);
    598		case IIO_EV_DIR_FALLING:
    599			return sx9324_read_close_debounce(data, val);
    600		default:
    601			return -EINVAL;
    602		}
    603	case IIO_EV_INFO_HYSTERESIS:
    604		return sx9324_read_hysteresis(data, chan, val);
    605	default:
    606		return -EINVAL;
    607	}
    608}
    609
    610static int sx9324_write_thresh(struct sx_common_data *data,
    611			       const struct iio_chan_spec *chan, int _val)
    612{
    613	unsigned int reg, val = _val;
    614	int ret;
    615
    616	reg = SX9324_REG_PROX_CTRL6 + chan->channel / 2;
    617
    618	if (val >= 1)
    619		val = int_sqrt(2 * val);
    620
    621	if (val > 0xff)
    622		return -EINVAL;
    623
    624	mutex_lock(&data->mutex);
    625	ret = regmap_write(data->regmap, reg, val);
    626	mutex_unlock(&data->mutex);
    627
    628	return ret;
    629}
    630
    631static int sx9324_write_hysteresis(struct sx_common_data *data,
    632				   const struct iio_chan_spec *chan, int _val)
    633{
    634	unsigned int hyst, val = _val;
    635	int ret, pthresh;
    636
    637	ret = sx9324_read_thresh(data, chan, &pthresh);
    638	if (ret < 0)
    639		return ret;
    640
    641	if (val == 0)
    642		hyst = 0;
    643	else if (val >= pthresh >> 2)
    644		hyst = 3;
    645	else if (val >= pthresh >> 3)
    646		hyst = 2;
    647	else if (val >= pthresh >> 4)
    648		hyst = 1;
    649	else
    650		return -EINVAL;
    651
    652	hyst = FIELD_PREP(SX9324_REG_PROX_CTRL5_HYST_MASK, hyst);
    653	mutex_lock(&data->mutex);
    654	ret = regmap_update_bits(data->regmap, SX9324_REG_PROX_CTRL5,
    655				 SX9324_REG_PROX_CTRL5_HYST_MASK, hyst);
    656	mutex_unlock(&data->mutex);
    657
    658	return ret;
    659}
    660
    661static int sx9324_write_far_debounce(struct sx_common_data *data, int _val)
    662{
    663	unsigned int regval, val = _val;
    664	int ret;
    665
    666	if (val > 0)
    667		val = ilog2(val);
    668	if (!FIELD_FIT(SX9324_REG_PROX_CTRL5_FAR_DEBOUNCE_MASK, val))
    669		return -EINVAL;
    670
    671	regval = FIELD_PREP(SX9324_REG_PROX_CTRL5_FAR_DEBOUNCE_MASK, val);
    672
    673	mutex_lock(&data->mutex);
    674	ret = regmap_update_bits(data->regmap, SX9324_REG_PROX_CTRL5,
    675				 SX9324_REG_PROX_CTRL5_FAR_DEBOUNCE_MASK,
    676				 regval);
    677	mutex_unlock(&data->mutex);
    678
    679	return ret;
    680}
    681
    682static int sx9324_write_close_debounce(struct sx_common_data *data, int _val)
    683{
    684	unsigned int regval, val = _val;
    685	int ret;
    686
    687	if (val > 0)
    688		val = ilog2(val);
    689	if (!FIELD_FIT(SX9324_REG_PROX_CTRL5_CLOSE_DEBOUNCE_MASK, val))
    690		return -EINVAL;
    691
    692	regval = FIELD_PREP(SX9324_REG_PROX_CTRL5_CLOSE_DEBOUNCE_MASK, val);
    693
    694	mutex_lock(&data->mutex);
    695	ret = regmap_update_bits(data->regmap, SX9324_REG_PROX_CTRL5,
    696				 SX9324_REG_PROX_CTRL5_CLOSE_DEBOUNCE_MASK,
    697				 regval);
    698	mutex_unlock(&data->mutex);
    699
    700	return ret;
    701}
    702
    703static int sx9324_write_event_val(struct iio_dev *indio_dev,
    704				  const struct iio_chan_spec *chan,
    705				  enum iio_event_type type,
    706				  enum iio_event_direction dir,
    707				  enum iio_event_info info, int val, int val2)
    708{
    709	struct sx_common_data *data = iio_priv(indio_dev);
    710
    711	if (chan->type != IIO_PROXIMITY)
    712		return -EINVAL;
    713
    714	switch (info) {
    715	case IIO_EV_INFO_VALUE:
    716		return sx9324_write_thresh(data, chan, val);
    717	case IIO_EV_INFO_PERIOD:
    718		switch (dir) {
    719		case IIO_EV_DIR_RISING:
    720			return sx9324_write_far_debounce(data, val);
    721		case IIO_EV_DIR_FALLING:
    722			return sx9324_write_close_debounce(data, val);
    723		default:
    724			return -EINVAL;
    725		}
    726	case IIO_EV_INFO_HYSTERESIS:
    727		return sx9324_write_hysteresis(data, chan, val);
    728	default:
    729		return -EINVAL;
    730	}
    731}
    732
    733static int sx9324_write_gain(struct sx_common_data *data,
    734			     const struct iio_chan_spec *chan, int val)
    735{
    736	unsigned int gain, reg;
    737	int ret;
    738
    739	reg = SX9324_REG_PROX_CTRL0 + chan->channel / 2;
    740
    741	gain = ilog2(val) + 1;
    742	if (val <= 0 || gain > SX9324_REG_PROX_CTRL0_GAIN_8)
    743		return -EINVAL;
    744
    745	gain = FIELD_PREP(SX9324_REG_PROX_CTRL0_GAIN_MASK, gain);
    746
    747	mutex_lock(&data->mutex);
    748	ret = regmap_update_bits(data->regmap, reg,
    749				 SX9324_REG_PROX_CTRL0_GAIN_MASK,
    750				 gain);
    751	mutex_unlock(&data->mutex);
    752
    753	return ret;
    754}
    755
    756static int sx9324_write_raw(struct iio_dev *indio_dev,
    757			    const struct iio_chan_spec *chan, int val, int val2,
    758			    long mask)
    759{
    760	struct sx_common_data *data = iio_priv(indio_dev);
    761
    762	switch (mask) {
    763	case IIO_CHAN_INFO_SAMP_FREQ:
    764		return sx9324_set_samp_freq(data, val, val2);
    765	case IIO_CHAN_INFO_HARDWAREGAIN:
    766		return sx9324_write_gain(data, chan, val);
    767	default:
    768		return -EINVAL;
    769	}
    770}
    771
    772static const struct sx_common_reg_default sx9324_default_regs[] = {
    773	{ SX9324_REG_IRQ_MSK, 0x00 },
    774	{ SX9324_REG_IRQ_CFG0, 0x00 },
    775	{ SX9324_REG_IRQ_CFG1, SX9324_REG_IRQ_CFG1_FAILCOND },
    776	{ SX9324_REG_IRQ_CFG2, 0x00 },
    777	{ SX9324_REG_GNRL_CTRL0, SX9324_REG_GNRL_CTRL0_SCANPERIOD_100MS },
    778	/*
    779	 * The lower 4 bits should not be set as it enable sensors measurements.
    780	 * Turning the detection on before the configuration values are set to
    781	 * good values can cause the device to return erroneous readings.
    782	 */
    783	{ SX9324_REG_GNRL_CTRL1, SX9324_REG_GNRL_CTRL1_PAUSECTRL },
    784
    785	{ SX9324_REG_AFE_CTRL0, 0x00 },
    786	{ SX9324_REG_AFE_CTRL3, 0x00 },
    787	{ SX9324_REG_AFE_CTRL4, SX9324_REG_AFE_CTRL4_FREQ_83_33HZ |
    788		SX9324_REG_AFE_CTRL4_RES_100 },
    789	{ SX9324_REG_AFE_CTRL6, 0x00 },
    790	{ SX9324_REG_AFE_CTRL7, SX9324_REG_AFE_CTRL4_FREQ_83_33HZ |
    791		SX9324_REG_AFE_CTRL4_RES_100 },
    792
    793	/* TODO(gwendal): PHx use chip default or all grounded? */
    794	{ SX9324_REG_AFE_PH0, 0x29 },
    795	{ SX9324_REG_AFE_PH1, 0x26 },
    796	{ SX9324_REG_AFE_PH2, 0x1a },
    797	{ SX9324_REG_AFE_PH3, 0x16 },
    798
    799	{ SX9324_REG_AFE_CTRL8, SX9324_REG_AFE_CTRL8_RESERVED |
    800		SX9324_REG_AFE_CTRL8_RESFILTIN_4KOHM },
    801	{ SX9324_REG_AFE_CTRL9, SX9324_REG_AFE_CTRL9_AGAIN_1 },
    802
    803	{ SX9324_REG_PROX_CTRL0,
    804		SX9324_REG_PROX_CTRL0_GAIN_1 << SX9324_REG_PROX_CTRL0_GAIN_SHIFT |
    805		SX9324_REG_PROX_CTRL0_RAWFILT_1P50 },
    806	{ SX9324_REG_PROX_CTRL1,
    807		SX9324_REG_PROX_CTRL0_GAIN_1 << SX9324_REG_PROX_CTRL0_GAIN_SHIFT |
    808		SX9324_REG_PROX_CTRL0_RAWFILT_1P50 },
    809	{ SX9324_REG_PROX_CTRL2, SX9324_REG_PROX_CTRL2_AVGNEG_THRESH_16K },
    810	{ SX9324_REG_PROX_CTRL3, SX9324_REG_PROX_CTRL3_AVGDEB_2SAMPLES |
    811		SX9324_REG_PROX_CTRL3_AVGPOS_THRESH_16K },
    812	{ SX9324_REG_PROX_CTRL4, SX9324_REG_PROX_CTRL4_AVGNEG_FILT_2 |
    813		SX9324_REG_PROX_CTRL3_AVGPOS_FILT_256 },
    814	{ SX9324_REG_PROX_CTRL5, 0x00 },
    815	{ SX9324_REG_PROX_CTRL6, SX9324_REG_PROX_CTRL6_PROXTHRESH_32 },
    816	{ SX9324_REG_PROX_CTRL7, SX9324_REG_PROX_CTRL6_PROXTHRESH_32 },
    817	{ SX9324_REG_ADV_CTRL0, 0x00 },
    818	{ SX9324_REG_ADV_CTRL1, 0x00 },
    819	{ SX9324_REG_ADV_CTRL2, 0x00 },
    820	{ SX9324_REG_ADV_CTRL3, 0x00 },
    821	{ SX9324_REG_ADV_CTRL4, 0x00 },
    822	{ SX9324_REG_ADV_CTRL5, SX9324_REG_ADV_CTRL5_STARTUP_SENSOR_1 |
    823		SX9324_REG_ADV_CTRL5_STARTUP_METHOD_1 },
    824	{ SX9324_REG_ADV_CTRL6, 0x00 },
    825	{ SX9324_REG_ADV_CTRL7, 0x00 },
    826	{ SX9324_REG_ADV_CTRL8, 0x00 },
    827	{ SX9324_REG_ADV_CTRL9, 0x00 },
    828	/* Body/Table threshold */
    829	{ SX9324_REG_ADV_CTRL10, 0x00 },
    830	{ SX9324_REG_ADV_CTRL11, 0x00 },
    831	{ SX9324_REG_ADV_CTRL12, 0x00 },
    832	/* TODO(gwendal): SAR currenly disabled */
    833	{ SX9324_REG_ADV_CTRL13, 0x00 },
    834	{ SX9324_REG_ADV_CTRL14, 0x00 },
    835	{ SX9324_REG_ADV_CTRL15, 0x00 },
    836	{ SX9324_REG_ADV_CTRL16, 0x00 },
    837	{ SX9324_REG_ADV_CTRL17, 0x00 },
    838	{ SX9324_REG_ADV_CTRL18, 0x00 },
    839	{ SX9324_REG_ADV_CTRL19, SX9324_REG_ADV_CTRL19_HIGHT_FAILURE_THRESH_SATURATION },
    840	{ SX9324_REG_ADV_CTRL20, SX9324_REG_ADV_CTRL19_HIGHT_FAILURE_THRESH_SATURATION },
    841};
    842
    843/* Activate all channels and perform an initial compensation. */
    844static int sx9324_init_compensation(struct iio_dev *indio_dev)
    845{
    846	struct sx_common_data *data = iio_priv(indio_dev);
    847	unsigned int val;
    848	int ret;
    849
    850	/* run the compensation phase on all channels */
    851	ret = regmap_update_bits(data->regmap, SX9324_REG_STAT2,
    852				 SX9324_REG_STAT2_COMPSTAT_MASK,
    853				 SX9324_REG_STAT2_COMPSTAT_MASK);
    854	if (ret)
    855		return ret;
    856
    857	return regmap_read_poll_timeout(data->regmap, SX9324_REG_STAT2, val,
    858					!(val & SX9324_REG_STAT2_COMPSTAT_MASK),
    859					20000, 2000000);
    860}
    861
    862static const struct sx_common_reg_default *
    863sx9324_get_default_reg(struct device *dev, int idx,
    864		       struct sx_common_reg_default *reg_def)
    865{
    866#define SX9324_PIN_DEF "semtech,ph0-pin"
    867#define SX9324_RESOLUTION_DEF "semtech,ph01-resolution"
    868#define SX9324_PROXRAW_DEF "semtech,ph01-proxraw-strength"
    869	unsigned int pin_defs[SX9324_NUM_PINS];
    870	char prop[] = SX9324_PROXRAW_DEF;
    871	u32 start = 0, raw = 0, pos = 0;
    872	int ret, count, ph, pin;
    873
    874	memcpy(reg_def, &sx9324_default_regs[idx], sizeof(*reg_def));
    875	switch (reg_def->reg) {
    876	case SX9324_REG_AFE_PH0:
    877	case SX9324_REG_AFE_PH1:
    878	case SX9324_REG_AFE_PH2:
    879	case SX9324_REG_AFE_PH3:
    880		ph = reg_def->reg - SX9324_REG_AFE_PH0;
    881		scnprintf(prop, ARRAY_SIZE(prop), "semtech,ph%d-pin", ph);
    882
    883		count = device_property_count_u32(dev, prop);
    884		if (count != ARRAY_SIZE(pin_defs))
    885			break;
    886		ret = device_property_read_u32_array(dev, prop, pin_defs,
    887						     ARRAY_SIZE(pin_defs));
    888		if (ret)
    889			break;
    890
    891		for (pin = 0; pin < SX9324_NUM_PINS; pin++)
    892			raw |= (pin_defs[pin] << (2 * pin)) &
    893			       SX9324_REG_AFE_PH0_PIN_MASK(pin);
    894		reg_def->def = raw;
    895		break;
    896	case SX9324_REG_AFE_CTRL4:
    897	case SX9324_REG_AFE_CTRL7:
    898		if (reg_def->reg == SX9324_REG_AFE_CTRL4)
    899			strncpy(prop, "semtech,ph01-resolution",
    900				ARRAY_SIZE(prop));
    901		else
    902			strncpy(prop, "semtech,ph23-resolution",
    903				ARRAY_SIZE(prop));
    904
    905		ret = device_property_read_u32(dev, prop, &raw);
    906		if (ret)
    907			break;
    908
    909		raw = ilog2(raw) - 3;
    910
    911		reg_def->def &= ~SX9324_REG_AFE_CTRL4_RESOLUTION_MASK;
    912		reg_def->def |= FIELD_PREP(SX9324_REG_AFE_CTRL4_RESOLUTION_MASK,
    913					   raw);
    914		break;
    915	case SX9324_REG_ADV_CTRL5:
    916		ret = device_property_read_u32(dev, "semtech,startup-sensor",
    917					       &start);
    918		if (ret)
    919			break;
    920
    921		reg_def->def &= ~SX9324_REG_ADV_CTRL5_STARTUPSENS_MASK;
    922		reg_def->def |= FIELD_PREP(SX9324_REG_ADV_CTRL5_STARTUPSENS_MASK,
    923					   start);
    924		break;
    925	case SX9324_REG_PROX_CTRL4:
    926		ret = device_property_read_u32(dev, "semtech,avg-pos-strength",
    927					       &pos);
    928		if (ret)
    929			break;
    930
    931		/* Powers of 2, except for a gap between 16 and 64 */
    932		raw = clamp(ilog2(pos), 3, 11) - (pos >= 32 ? 4 : 3);
    933
    934		reg_def->def &= ~SX9324_REG_PROX_CTRL4_AVGPOSFILT_MASK;
    935		reg_def->def |= FIELD_PREP(SX9324_REG_PROX_CTRL4_AVGPOSFILT_MASK,
    936					   raw);
    937		break;
    938	case SX9324_REG_PROX_CTRL0:
    939	case SX9324_REG_PROX_CTRL1:
    940		if (reg_def->reg == SX9324_REG_PROX_CTRL0)
    941			strncpy(prop, "semtech,ph01-proxraw-strength",
    942				ARRAY_SIZE(prop));
    943		else
    944			strncpy(prop, "semtech,ph23-proxraw-strength",
    945				ARRAY_SIZE(prop));
    946		ret = device_property_read_u32(dev, prop, &raw);
    947		if (ret)
    948			break;
    949
    950		reg_def->def &= ~SX9324_REG_PROX_CTRL0_RAWFILT_MASK;
    951		reg_def->def |= FIELD_PREP(SX9324_REG_PROX_CTRL0_RAWFILT_MASK,
    952					   raw);
    953		break;
    954	}
    955	return reg_def;
    956}
    957
    958static int sx9324_check_whoami(struct device *dev,
    959			       struct iio_dev *indio_dev)
    960{
    961	/*
    962	 * Only one sensor for this driver. Assuming the device tree
    963	 * is correct, just set the sensor name.
    964	 */
    965	indio_dev->name = "sx9324";
    966	return 0;
    967}
    968
    969static const struct sx_common_chip_info sx9324_chip_info = {
    970	.reg_stat = SX9324_REG_STAT0,
    971	.reg_irq_msk = SX9324_REG_IRQ_MSK,
    972	.reg_enable_chan = SX9324_REG_GNRL_CTRL1,
    973	.reg_reset = SX9324_REG_RESET,
    974
    975	.mask_enable_chan = SX9324_REG_GNRL_CTRL1_PHEN_MASK,
    976	.irq_msk_offset = 3,
    977	.num_channels = SX9324_NUM_CHANNELS,
    978	.num_default_regs = ARRAY_SIZE(sx9324_default_regs),
    979
    980	.ops = {
    981		.read_prox_data = sx9324_read_prox_data,
    982		.check_whoami = sx9324_check_whoami,
    983		.init_compensation = sx9324_init_compensation,
    984		.wait_for_sample = sx9324_wait_for_sample,
    985		.get_default_reg = sx9324_get_default_reg,
    986	},
    987
    988	.iio_channels = sx9324_channels,
    989	.num_iio_channels = ARRAY_SIZE(sx9324_channels),
    990	.iio_info =  {
    991		.read_raw = sx9324_read_raw,
    992		.read_avail = sx9324_read_avail,
    993		.read_event_value = sx9324_read_event_val,
    994		.write_event_value = sx9324_write_event_val,
    995		.write_raw = sx9324_write_raw,
    996		.read_event_config = sx_common_read_event_config,
    997		.write_event_config = sx_common_write_event_config,
    998	},
    999};
   1000
   1001static int sx9324_probe(struct i2c_client *client)
   1002{
   1003	return sx_common_probe(client, &sx9324_chip_info, &sx9324_regmap_config);
   1004}
   1005
   1006static int __maybe_unused sx9324_suspend(struct device *dev)
   1007{
   1008	struct sx_common_data *data = iio_priv(dev_get_drvdata(dev));
   1009	unsigned int regval;
   1010	int ret;
   1011
   1012	disable_irq_nosync(data->client->irq);
   1013
   1014	mutex_lock(&data->mutex);
   1015	ret = regmap_read(data->regmap, SX9324_REG_GNRL_CTRL1, &regval);
   1016
   1017	data->suspend_ctrl =
   1018		FIELD_GET(SX9324_REG_GNRL_CTRL1_PHEN_MASK, regval);
   1019
   1020	if (ret < 0)
   1021		goto out;
   1022
   1023	/* Disable all phases, send the device to sleep. */
   1024	ret = regmap_write(data->regmap, SX9324_REG_GNRL_CTRL1, 0);
   1025
   1026out:
   1027	mutex_unlock(&data->mutex);
   1028	return ret;
   1029}
   1030
   1031static int __maybe_unused sx9324_resume(struct device *dev)
   1032{
   1033	struct sx_common_data *data = iio_priv(dev_get_drvdata(dev));
   1034	int ret;
   1035
   1036	mutex_lock(&data->mutex);
   1037	ret = regmap_write(data->regmap, SX9324_REG_GNRL_CTRL1,
   1038			   data->suspend_ctrl | SX9324_REG_GNRL_CTRL1_PAUSECTRL);
   1039	mutex_unlock(&data->mutex);
   1040	if (ret)
   1041		return ret;
   1042
   1043	enable_irq(data->client->irq);
   1044	return 0;
   1045}
   1046
   1047static SIMPLE_DEV_PM_OPS(sx9324_pm_ops, sx9324_suspend, sx9324_resume);
   1048
   1049static const struct acpi_device_id sx9324_acpi_match[] = {
   1050	{ "STH9324", SX9324_WHOAMI_VALUE },
   1051	{ }
   1052};
   1053MODULE_DEVICE_TABLE(acpi, sx9324_acpi_match);
   1054
   1055static const struct of_device_id sx9324_of_match[] = {
   1056	{ .compatible = "semtech,sx9324", (void *)SX9324_WHOAMI_VALUE },
   1057	{ }
   1058};
   1059MODULE_DEVICE_TABLE(of, sx9324_of_match);
   1060
   1061static const struct i2c_device_id sx9324_id[] = {
   1062	{ "sx9324", SX9324_WHOAMI_VALUE },
   1063	{ }
   1064};
   1065MODULE_DEVICE_TABLE(i2c, sx9324_id);
   1066
   1067static struct i2c_driver sx9324_driver = {
   1068	.driver = {
   1069		.name	= "sx9324",
   1070		.acpi_match_table = sx9324_acpi_match,
   1071		.of_match_table = sx9324_of_match,
   1072		.pm = &sx9324_pm_ops,
   1073
   1074		/*
   1075		 * Lots of i2c transfers in probe + over 200 ms waiting in
   1076		 * sx9324_init_compensation() mean a slow probe; prefer async
   1077		 * so we don't delay boot if we're builtin to the kernel.
   1078		 */
   1079		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
   1080	},
   1081	.probe_new	= sx9324_probe,
   1082	.id_table	= sx9324_id,
   1083};
   1084module_i2c_driver(sx9324_driver);
   1085
   1086MODULE_AUTHOR("Gwendal Grignou <gwendal@chromium.org>");
   1087MODULE_DESCRIPTION("Driver for Semtech SX9324 proximity sensor");
   1088MODULE_LICENSE("GPL v2");
   1089MODULE_IMPORT_NS(SEMTECH_PROX);