Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright 2021 Google LLC.
0004  *
0005  * Driver for Semtech's SX9324 capacitive proximity/button solution.
0006  * Based on SX9324 driver and copy of datasheet at:
0007  * https://edit.wpgdadawant.com/uploads/news_file/program/2019/30184/tech_files/program_30184_suggest_other_file.pdf
0008  */
0009 
0010 #include <linux/acpi.h>
0011 #include <linux/bits.h>
0012 #include <linux/bitfield.h>
0013 #include <linux/delay.h>
0014 #include <linux/i2c.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/kernel.h>
0017 #include <linux/log2.h>
0018 #include <linux/mod_devicetable.h>
0019 #include <linux/module.h>
0020 #include <linux/pm.h>
0021 #include <linux/property.h>
0022 #include <linux/regmap.h>
0023 
0024 #include <linux/iio/iio.h>
0025 
0026 #include "sx_common.h"
0027 
0028 /* Register definitions. */
0029 #define SX9324_REG_IRQ_SRC      SX_COMMON_REG_IRQ_SRC
0030 #define SX9324_REG_STAT0        0x01
0031 #define SX9324_REG_STAT1        0x02
0032 #define SX9324_REG_STAT2        0x03
0033 #define SX9324_REG_STAT2_COMPSTAT_MASK  GENMASK(3, 0)
0034 #define SX9324_REG_STAT3        0x04
0035 #define SX9324_REG_IRQ_MSK      0x05
0036 #define SX9324_CONVDONE_IRQ     BIT(3)
0037 #define SX9324_FAR_IRQ          BIT(5)
0038 #define SX9324_CLOSE_IRQ        BIT(6)
0039 #define SX9324_REG_IRQ_CFG0     0x06
0040 #define SX9324_REG_IRQ_CFG1     0x07
0041 #define SX9324_REG_IRQ_CFG1_FAILCOND    0x80
0042 #define SX9324_REG_IRQ_CFG2     0x08
0043 
0044 #define SX9324_REG_GNRL_CTRL0       0x10
0045 #define SX9324_REG_GNRL_CTRL0_SCANPERIOD_MASK GENMASK(4, 0)
0046 #define SX9324_REG_GNRL_CTRL0_SCANPERIOD_100MS 0x16
0047 #define SX9324_REG_GNRL_CTRL1       0x11
0048 #define SX9324_REG_GNRL_CTRL1_PHEN_MASK GENMASK(3, 0)
0049 #define SX9324_REG_GNRL_CTRL1_PAUSECTRL 0x20
0050 
0051 #define SX9324_REG_I2C_ADDR     0x14
0052 #define SX9324_REG_CLK_SPRD     0x15
0053 
0054 #define SX9324_REG_AFE_CTRL0        0x20
0055 #define SX9324_REG_AFE_CTRL0_RINT_SHIFT     6
0056 #define SX9324_REG_AFE_CTRL0_RINT_MASK \
0057     GENMASK(SX9324_REG_AFE_CTRL0_RINT_SHIFT + 1, \
0058         SX9324_REG_AFE_CTRL0_RINT_SHIFT)
0059 #define SX9324_REG_AFE_CTRL0_RINT_LOWEST    0x00
0060 #define SX9324_REG_AFE_CTRL0_CSIDLE_SHIFT   4
0061 #define SX9324_REG_AFE_CTRL0_CSIDLE_MASK \
0062     GENMASK(SX9324_REG_AFE_CTRL0_CSIDLE_SHIFT + 1, \
0063         SX9324_REG_AFE_CTRL0_CSIDLE_SHIFT)
0064 #define SX9324_REG_AFE_CTRL0_RINT_LOWEST    0x00
0065 #define SX9324_REG_AFE_CTRL1        0x21
0066 #define SX9324_REG_AFE_CTRL2        0x22
0067 #define SX9324_REG_AFE_CTRL3        0x23
0068 #define SX9324_REG_AFE_CTRL4        0x24
0069 #define SX9324_REG_AFE_CTRL4_FREQ_83_33HZ 0x40
0070 #define SX9324_REG_AFE_CTRL4_RESOLUTION_MASK GENMASK(2, 0)
0071 #define SX9324_REG_AFE_CTRL4_RES_100    0x04
0072 #define SX9324_REG_AFE_CTRL5        0x25
0073 #define SX9324_REG_AFE_CTRL6        0x26
0074 #define SX9324_REG_AFE_CTRL7        0x27
0075 #define SX9324_REG_AFE_PH0      0x28
0076 #define SX9324_REG_AFE_PH0_PIN_MASK(_pin) \
0077     GENMASK(2 * (_pin) + 1, 2 * (_pin))
0078 
0079 #define SX9324_REG_AFE_PH1      0x29
0080 #define SX9324_REG_AFE_PH2      0x2a
0081 #define SX9324_REG_AFE_PH3      0x2b
0082 #define SX9324_REG_AFE_CTRL8        0x2c
0083 #define SX9324_REG_AFE_CTRL8_RESERVED   0x10
0084 #define SX9324_REG_AFE_CTRL8_RESFILTIN_4KOHM 0x02
0085 #define SX9324_REG_AFE_CTRL8_RESFILTIN_MASK GENMASK(3, 0)
0086 #define SX9324_REG_AFE_CTRL9        0x2d
0087 #define SX9324_REG_AFE_CTRL9_AGAIN_MASK         GENMASK(3, 0)
0088 #define SX9324_REG_AFE_CTRL9_AGAIN_1    0x08
0089 
0090 #define SX9324_REG_PROX_CTRL0       0x30
0091 #define SX9324_REG_PROX_CTRL0_GAIN_MASK GENMASK(5, 3)
0092 #define SX9324_REG_PROX_CTRL0_GAIN_SHIFT    3
0093 #define SX9324_REG_PROX_CTRL0_GAIN_RSVD     0x0
0094 #define SX9324_REG_PROX_CTRL0_GAIN_1        0x1
0095 #define SX9324_REG_PROX_CTRL0_GAIN_8        0x4
0096 #define SX9324_REG_PROX_CTRL0_RAWFILT_MASK  GENMASK(2, 0)
0097 #define SX9324_REG_PROX_CTRL0_RAWFILT_1P50  0x01
0098 #define SX9324_REG_PROX_CTRL1       0x31
0099 #define SX9324_REG_PROX_CTRL2       0x32
0100 #define SX9324_REG_PROX_CTRL2_AVGNEG_THRESH_16K 0x20
0101 #define SX9324_REG_PROX_CTRL3       0x33
0102 #define SX9324_REG_PROX_CTRL3_AVGDEB_2SAMPLES   0x40
0103 #define SX9324_REG_PROX_CTRL3_AVGPOS_THRESH_16K 0x20
0104 #define SX9324_REG_PROX_CTRL4       0x34
0105 #define SX9324_REG_PROX_CTRL4_AVGNEGFILT_MASK   GENMASK(5, 3)
0106 #define SX9324_REG_PROX_CTRL4_AVGNEG_FILT_2 0x08
0107 #define SX9324_REG_PROX_CTRL4_AVGPOSFILT_MASK   GENMASK(2, 0)
0108 #define SX9324_REG_PROX_CTRL4_AVGPOS_FILT_256 0x04
0109 #define SX9324_REG_PROX_CTRL5       0x35
0110 #define SX9324_REG_PROX_CTRL5_HYST_MASK         GENMASK(5, 4)
0111 #define SX9324_REG_PROX_CTRL5_CLOSE_DEBOUNCE_MASK   GENMASK(3, 2)
0112 #define SX9324_REG_PROX_CTRL5_FAR_DEBOUNCE_MASK     GENMASK(1, 0)
0113 #define SX9324_REG_PROX_CTRL6       0x36
0114 #define SX9324_REG_PROX_CTRL6_PROXTHRESH_32 0x08
0115 #define SX9324_REG_PROX_CTRL7       0x37
0116 
0117 #define SX9324_REG_ADV_CTRL0        0x40
0118 #define SX9324_REG_ADV_CTRL1        0x41
0119 #define SX9324_REG_ADV_CTRL2        0x42
0120 #define SX9324_REG_ADV_CTRL3        0x43
0121 #define SX9324_REG_ADV_CTRL4        0x44
0122 #define SX9324_REG_ADV_CTRL5        0x45
0123 #define SX9324_REG_ADV_CTRL5_STARTUPSENS_MASK GENMASK(3, 2)
0124 #define SX9324_REG_ADV_CTRL5_STARTUP_SENSOR_1   0x04
0125 #define SX9324_REG_ADV_CTRL5_STARTUP_METHOD_1   0x01
0126 #define SX9324_REG_ADV_CTRL6        0x46
0127 #define SX9324_REG_ADV_CTRL7        0x47
0128 #define SX9324_REG_ADV_CTRL8        0x48
0129 #define SX9324_REG_ADV_CTRL9        0x49
0130 #define SX9324_REG_ADV_CTRL10       0x4a
0131 #define SX9324_REG_ADV_CTRL11       0x4b
0132 #define SX9324_REG_ADV_CTRL12       0x4c
0133 #define SX9324_REG_ADV_CTRL13       0x4d
0134 #define SX9324_REG_ADV_CTRL14       0x4e
0135 #define SX9324_REG_ADV_CTRL15       0x4f
0136 #define SX9324_REG_ADV_CTRL16       0x50
0137 #define SX9324_REG_ADV_CTRL17       0x51
0138 #define SX9324_REG_ADV_CTRL18       0x52
0139 #define SX9324_REG_ADV_CTRL19       0x53
0140 #define SX9324_REG_ADV_CTRL20       0x54
0141 #define SX9324_REG_ADV_CTRL19_HIGHT_FAILURE_THRESH_SATURATION 0xf0
0142 
0143 #define SX9324_REG_PHASE_SEL        0x60
0144 
0145 #define SX9324_REG_USEFUL_MSB       0x61
0146 #define SX9324_REG_USEFUL_LSB       0x62
0147 
0148 #define SX9324_REG_AVG_MSB      0x63
0149 #define SX9324_REG_AVG_LSB      0x64
0150 
0151 #define SX9324_REG_DIFF_MSB     0x65
0152 #define SX9324_REG_DIFF_LSB     0x66
0153 
0154 #define SX9324_REG_OFFSET_MSB       0x67
0155 #define SX9324_REG_OFFSET_LSB       0x68
0156 
0157 #define SX9324_REG_SAR_MSB      0x69
0158 #define SX9324_REG_SAR_LSB      0x6a
0159 
0160 #define SX9324_REG_RESET        0x9f
0161 /* Write this to REG_RESET to do a soft reset. */
0162 #define SX9324_SOFT_RESET       0xde
0163 
0164 #define SX9324_REG_WHOAMI       0xfa
0165 #define   SX9324_WHOAMI_VALUE       0x23
0166 
0167 #define SX9324_REG_REVISION     0xfe
0168 
0169 /* 4 channels, as defined in STAT0: PH0, PH1, PH2 and PH3. */
0170 #define SX9324_NUM_CHANNELS     4
0171 /* 3 CS pins: CS0, CS1, CS2. */
0172 #define SX9324_NUM_PINS         3
0173 
0174 static const char * const sx9324_cs_pin_usage[] = { "HZ", "MI", "DS", "GD" };
0175 
0176 static ssize_t sx9324_phase_configuration_show(struct iio_dev *indio_dev,
0177                            uintptr_t private,
0178                            const struct iio_chan_spec *chan,
0179                            char *buf)
0180 {
0181     struct sx_common_data *data = iio_priv(indio_dev);
0182     unsigned int val;
0183     int i, ret, pin_idx;
0184     size_t len = 0;
0185 
0186     ret = regmap_read(data->regmap, SX9324_REG_AFE_PH0 + chan->channel, &val);
0187     if (ret < 0)
0188         return ret;
0189 
0190     for (i = 0; i < SX9324_NUM_PINS; i++) {
0191         pin_idx = (val & SX9324_REG_AFE_PH0_PIN_MASK(i)) >> (2 * i);
0192         len += sysfs_emit_at(buf, len, "%s,",
0193                      sx9324_cs_pin_usage[pin_idx]);
0194     }
0195     buf[len - 1] = '\n';
0196     return len;
0197 }
0198 
0199 static const struct iio_chan_spec_ext_info sx9324_channel_ext_info[] = {
0200     {
0201         .name = "setup",
0202         .shared = IIO_SEPARATE,
0203         .read = sx9324_phase_configuration_show,
0204     },
0205     {}
0206 };
0207 
0208 #define SX9324_CHANNEL(idx)                  \
0209 {                                \
0210     .type = IIO_PROXIMITY,                   \
0211     .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |       \
0212                   BIT(IIO_CHAN_INFO_HARDWAREGAIN),   \
0213     .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
0214     .info_mask_separate_available =              \
0215         BIT(IIO_CHAN_INFO_HARDWAREGAIN),         \
0216     .info_mask_shared_by_all_available =             \
0217         BIT(IIO_CHAN_INFO_SAMP_FREQ),            \
0218     .indexed = 1,                        \
0219     .channel = idx,                      \
0220     .address = SX9324_REG_DIFF_MSB,              \
0221     .event_spec = sx_common_events,              \
0222     .num_event_specs = ARRAY_SIZE(sx_common_events),     \
0223     .scan_index = idx,                   \
0224     .scan_type = {                       \
0225         .sign = 's',                     \
0226         .realbits = 12,                  \
0227         .storagebits = 16,               \
0228         .endianness = IIO_BE,                \
0229     },                           \
0230     .ext_info = sx9324_channel_ext_info,             \
0231 }
0232 
0233 static const struct iio_chan_spec sx9324_channels[] = {
0234     SX9324_CHANNEL(0),          /* Phase 0 */
0235     SX9324_CHANNEL(1),          /* Phase 1 */
0236     SX9324_CHANNEL(2),          /* Phase 2 */
0237     SX9324_CHANNEL(3),          /* Phase 3 */
0238     IIO_CHAN_SOFT_TIMESTAMP(4),
0239 };
0240 
0241 /*
0242  * Each entry contains the integer part (val) and the fractional part, in micro
0243  * seconds. It conforms to the IIO output IIO_VAL_INT_PLUS_MICRO.
0244  */
0245 static const struct {
0246     int val;
0247     int val2;
0248 } sx9324_samp_freq_table[] = {
0249     { 1000, 0 },  /* 00000: Min (no idle time) */
0250     { 500, 0 },  /* 00001: 2 ms */
0251     { 250, 0 },  /* 00010: 4 ms */
0252     { 166, 666666 },  /* 00011: 6 ms */
0253     { 125, 0 },  /* 00100: 8 ms */
0254     { 100, 0 },  /* 00101: 10 ms */
0255     { 71, 428571 },  /* 00110: 14 ms */
0256     { 55, 555556 },  /* 00111: 18 ms */
0257     { 45, 454545 },  /* 01000: 22 ms */
0258     { 38, 461538 },  /* 01001: 26 ms */
0259     { 33, 333333 },  /* 01010: 30 ms */
0260     { 29, 411765 },  /* 01011: 34 ms */
0261     { 26, 315789 },  /* 01100: 38 ms */
0262     { 23, 809524 },  /* 01101: 42 ms */
0263     { 21, 739130 },  /* 01110: 46 ms */
0264     { 20, 0 },  /* 01111: 50 ms */
0265     { 17, 857143 },  /* 10000: 56 ms */
0266     { 16, 129032 },  /* 10001: 62 ms */
0267     { 14, 705882 },  /* 10010: 68 ms */
0268     { 13, 513514 },  /* 10011: 74 ms */
0269     { 12, 500000 },  /* 10100: 80 ms */
0270     { 11, 111111 },  /* 10101: 90 ms */
0271     { 10, 0 },  /* 10110: 100 ms (Typ.) */
0272     { 5, 0 },  /* 10111: 200 ms */
0273     { 3, 333333 },  /* 11000: 300 ms */
0274     { 2, 500000 },  /* 11001: 400 ms */
0275     { 1, 666667 },  /* 11010: 600 ms */
0276     { 1, 250000 },  /* 11011: 800 ms */
0277     { 1, 0 },  /* 11100: 1 s */
0278     { 0, 500000 },  /* 11101: 2 s */
0279     { 0, 333333 },  /* 11110: 3 s */
0280     { 0, 250000 },  /* 11111: 4 s */
0281 };
0282 
0283 static const unsigned int sx9324_scan_period_table[] = {
0284     2,   15,  30,  45,   60,   90,   120,  200,
0285     400, 600, 800, 1000, 2000, 3000, 4000, 5000,
0286 };
0287 
0288 static const struct regmap_range sx9324_writable_reg_ranges[] = {
0289     /*
0290      * To set COMPSTAT for compensation, even if datasheet says register is
0291      * RO.
0292      */
0293     regmap_reg_range(SX9324_REG_STAT2, SX9324_REG_STAT2),
0294     regmap_reg_range(SX9324_REG_IRQ_MSK, SX9324_REG_IRQ_CFG2),
0295     regmap_reg_range(SX9324_REG_GNRL_CTRL0, SX9324_REG_GNRL_CTRL1),
0296     /* Leave i2c and clock spreading as unavailable */
0297     regmap_reg_range(SX9324_REG_AFE_CTRL0, SX9324_REG_AFE_CTRL9),
0298     regmap_reg_range(SX9324_REG_PROX_CTRL0, SX9324_REG_PROX_CTRL7),
0299     regmap_reg_range(SX9324_REG_ADV_CTRL0, SX9324_REG_ADV_CTRL20),
0300     regmap_reg_range(SX9324_REG_PHASE_SEL, SX9324_REG_PHASE_SEL),
0301     regmap_reg_range(SX9324_REG_OFFSET_MSB, SX9324_REG_OFFSET_LSB),
0302     regmap_reg_range(SX9324_REG_RESET, SX9324_REG_RESET),
0303 };
0304 
0305 static const struct regmap_access_table sx9324_writeable_regs = {
0306     .yes_ranges = sx9324_writable_reg_ranges,
0307     .n_yes_ranges = ARRAY_SIZE(sx9324_writable_reg_ranges),
0308 };
0309 
0310 /*
0311  * All allocated registers are readable, so we just list unallocated
0312  * ones.
0313  */
0314 static const struct regmap_range sx9324_non_readable_reg_ranges[] = {
0315     regmap_reg_range(SX9324_REG_IRQ_CFG2 + 1, SX9324_REG_GNRL_CTRL0 - 1),
0316     regmap_reg_range(SX9324_REG_GNRL_CTRL1 + 1, SX9324_REG_AFE_CTRL0 - 1),
0317     regmap_reg_range(SX9324_REG_AFE_CTRL9 + 1, SX9324_REG_PROX_CTRL0 - 1),
0318     regmap_reg_range(SX9324_REG_PROX_CTRL7 + 1, SX9324_REG_ADV_CTRL0 - 1),
0319     regmap_reg_range(SX9324_REG_ADV_CTRL20 + 1, SX9324_REG_PHASE_SEL - 1),
0320     regmap_reg_range(SX9324_REG_SAR_LSB + 1, SX9324_REG_RESET - 1),
0321     regmap_reg_range(SX9324_REG_RESET + 1, SX9324_REG_WHOAMI - 1),
0322     regmap_reg_range(SX9324_REG_WHOAMI + 1, SX9324_REG_REVISION - 1),
0323 };
0324 
0325 static const struct regmap_access_table sx9324_readable_regs = {
0326     .no_ranges = sx9324_non_readable_reg_ranges,
0327     .n_no_ranges = ARRAY_SIZE(sx9324_non_readable_reg_ranges),
0328 };
0329 
0330 static const struct regmap_range sx9324_volatile_reg_ranges[] = {
0331     regmap_reg_range(SX9324_REG_IRQ_SRC, SX9324_REG_STAT3),
0332     regmap_reg_range(SX9324_REG_USEFUL_MSB, SX9324_REG_DIFF_LSB),
0333     regmap_reg_range(SX9324_REG_SAR_MSB, SX9324_REG_SAR_LSB),
0334     regmap_reg_range(SX9324_REG_WHOAMI, SX9324_REG_WHOAMI),
0335     regmap_reg_range(SX9324_REG_REVISION, SX9324_REG_REVISION),
0336 };
0337 
0338 static const struct regmap_access_table sx9324_volatile_regs = {
0339     .yes_ranges = sx9324_volatile_reg_ranges,
0340     .n_yes_ranges = ARRAY_SIZE(sx9324_volatile_reg_ranges),
0341 };
0342 
0343 static const struct regmap_config sx9324_regmap_config = {
0344     .reg_bits = 8,
0345     .val_bits = 8,
0346 
0347     .max_register = SX9324_REG_REVISION,
0348     .cache_type = REGCACHE_RBTREE,
0349 
0350     .wr_table = &sx9324_writeable_regs,
0351     .rd_table = &sx9324_readable_regs,
0352     .volatile_table = &sx9324_volatile_regs,
0353 };
0354 
0355 static int sx9324_read_prox_data(struct sx_common_data *data,
0356                  const struct iio_chan_spec *chan,
0357                  __be16 *val)
0358 {
0359     int ret;
0360 
0361     ret = regmap_write(data->regmap, SX9324_REG_PHASE_SEL, chan->channel);
0362     if (ret < 0)
0363         return ret;
0364 
0365     return regmap_bulk_read(data->regmap, chan->address, val, sizeof(*val));
0366 }
0367 
0368 /*
0369  * If we have no interrupt support, we have to wait for a scan period
0370  * after enabling a channel to get a result.
0371  */
0372 static int sx9324_wait_for_sample(struct sx_common_data *data)
0373 {
0374     int ret;
0375     unsigned int val;
0376 
0377     ret = regmap_read(data->regmap, SX9324_REG_GNRL_CTRL0, &val);
0378     if (ret < 0)
0379         return ret;
0380     val = FIELD_GET(SX9324_REG_GNRL_CTRL0_SCANPERIOD_MASK, val);
0381 
0382     msleep(sx9324_scan_period_table[val]);
0383 
0384     return 0;
0385 }
0386 
0387 static int sx9324_read_gain(struct sx_common_data *data,
0388                 const struct iio_chan_spec *chan, int *val)
0389 {
0390     unsigned int reg, regval;
0391     int ret;
0392 
0393     reg = SX9324_REG_PROX_CTRL0 + chan->channel / 2;
0394     ret = regmap_read(data->regmap, reg, &regval);
0395     if (ret)
0396         return ret;
0397 
0398     regval = FIELD_GET(SX9324_REG_PROX_CTRL0_GAIN_MASK, regval);
0399     if (regval)
0400         regval--;
0401     else if (regval == SX9324_REG_PROX_CTRL0_GAIN_RSVD ||
0402          regval > SX9324_REG_PROX_CTRL0_GAIN_8)
0403         return -EINVAL;
0404 
0405     *val = 1 << regval;
0406 
0407     return IIO_VAL_INT;
0408 }
0409 
0410 static int sx9324_read_samp_freq(struct sx_common_data *data,
0411                  int *val, int *val2)
0412 {
0413     int ret;
0414     unsigned int regval;
0415 
0416     ret = regmap_read(data->regmap, SX9324_REG_GNRL_CTRL0, &regval);
0417     if (ret)
0418         return ret;
0419 
0420     regval = FIELD_GET(SX9324_REG_GNRL_CTRL0_SCANPERIOD_MASK, regval);
0421     *val = sx9324_samp_freq_table[regval].val;
0422     *val2 = sx9324_samp_freq_table[regval].val2;
0423 
0424     return IIO_VAL_INT_PLUS_MICRO;
0425 }
0426 
0427 static int sx9324_read_raw(struct iio_dev *indio_dev,
0428                const struct iio_chan_spec *chan,
0429                int *val, int *val2, long mask)
0430 {
0431     struct sx_common_data *data = iio_priv(indio_dev);
0432     int ret;
0433 
0434     switch (mask) {
0435     case IIO_CHAN_INFO_RAW:
0436         ret = iio_device_claim_direct_mode(indio_dev);
0437         if (ret)
0438             return ret;
0439 
0440         ret = sx_common_read_proximity(data, chan, val);
0441         iio_device_release_direct_mode(indio_dev);
0442         return ret;
0443     case IIO_CHAN_INFO_HARDWAREGAIN:
0444         ret = iio_device_claim_direct_mode(indio_dev);
0445         if (ret)
0446             return ret;
0447 
0448         ret = sx9324_read_gain(data, chan, val);
0449         iio_device_release_direct_mode(indio_dev);
0450         return ret;
0451     case IIO_CHAN_INFO_SAMP_FREQ:
0452         return sx9324_read_samp_freq(data, val, val2);
0453     default:
0454         return -EINVAL;
0455     }
0456 }
0457 
0458 static const int sx9324_gain_vals[] = { 1, 2, 4, 8 };
0459 
0460 static int sx9324_read_avail(struct iio_dev *indio_dev,
0461                  struct iio_chan_spec const *chan,
0462                  const int **vals, int *type, int *length,
0463                  long mask)
0464 {
0465     if (chan->type != IIO_PROXIMITY)
0466         return -EINVAL;
0467 
0468     switch (mask) {
0469     case IIO_CHAN_INFO_HARDWAREGAIN:
0470         *type = IIO_VAL_INT;
0471         *length = ARRAY_SIZE(sx9324_gain_vals);
0472         *vals = sx9324_gain_vals;
0473         return IIO_AVAIL_LIST;
0474     case IIO_CHAN_INFO_SAMP_FREQ:
0475         *type = IIO_VAL_INT_PLUS_MICRO;
0476         *length = ARRAY_SIZE(sx9324_samp_freq_table) * 2;
0477         *vals = (int *)sx9324_samp_freq_table;
0478         return IIO_AVAIL_LIST;
0479     default:
0480         return -EINVAL;
0481     }
0482 }
0483 
0484 static int sx9324_set_samp_freq(struct sx_common_data *data,
0485                 int val, int val2)
0486 {
0487     int i, ret;
0488 
0489     for (i = 0; i < ARRAY_SIZE(sx9324_samp_freq_table); i++)
0490         if (val == sx9324_samp_freq_table[i].val &&
0491             val2 == sx9324_samp_freq_table[i].val2)
0492             break;
0493 
0494     if (i == ARRAY_SIZE(sx9324_samp_freq_table))
0495         return -EINVAL;
0496 
0497     mutex_lock(&data->mutex);
0498 
0499     ret = regmap_update_bits(data->regmap,
0500                  SX9324_REG_GNRL_CTRL0,
0501                  SX9324_REG_GNRL_CTRL0_SCANPERIOD_MASK, i);
0502 
0503     mutex_unlock(&data->mutex);
0504 
0505     return ret;
0506 }
0507 
0508 static int sx9324_read_thresh(struct sx_common_data *data,
0509                   const struct iio_chan_spec *chan, int *val)
0510 {
0511     unsigned int regval;
0512     unsigned int reg;
0513     int ret;
0514 
0515     /*
0516      * TODO(gwendal): Depending on the phase function
0517      * (proximity/table/body), retrieve the right threshold.
0518      * For now, return the proximity threshold.
0519      */
0520     reg = SX9324_REG_PROX_CTRL6 + chan->channel / 2;
0521     ret = regmap_read(data->regmap, reg, &regval);
0522     if (ret)
0523         return ret;
0524 
0525     if (regval <= 1)
0526         *val = regval;
0527     else
0528         *val = (regval * regval) / 2;
0529 
0530     return IIO_VAL_INT;
0531 }
0532 
0533 static int sx9324_read_hysteresis(struct sx_common_data *data,
0534                   const struct iio_chan_spec *chan, int *val)
0535 {
0536     unsigned int regval, pthresh;
0537     int ret;
0538 
0539     ret = sx9324_read_thresh(data, chan, &pthresh);
0540     if (ret < 0)
0541         return ret;
0542 
0543     ret = regmap_read(data->regmap, SX9324_REG_PROX_CTRL5, &regval);
0544     if (ret)
0545         return ret;
0546 
0547     regval = FIELD_GET(SX9324_REG_PROX_CTRL5_HYST_MASK, regval);
0548     if (!regval)
0549         *val = 0;
0550     else
0551         *val = pthresh >> (5 - regval);
0552 
0553     return IIO_VAL_INT;
0554 }
0555 
0556 static int sx9324_read_far_debounce(struct sx_common_data *data, int *val)
0557 {
0558     unsigned int regval;
0559     int ret;
0560 
0561     ret = regmap_read(data->regmap, SX9324_REG_PROX_CTRL5, &regval);
0562     if (ret)
0563         return ret;
0564 
0565     regval = FIELD_GET(SX9324_REG_PROX_CTRL5_FAR_DEBOUNCE_MASK, regval);
0566     if (regval)
0567         *val = 1 << regval;
0568     else
0569         *val = 0;
0570 
0571     return IIO_VAL_INT;
0572 }
0573 
0574 static int sx9324_read_close_debounce(struct sx_common_data *data, int *val)
0575 {
0576     unsigned int regval;
0577     int ret;
0578 
0579     ret = regmap_read(data->regmap, SX9324_REG_PROX_CTRL5, &regval);
0580     if (ret)
0581         return ret;
0582 
0583     regval = FIELD_GET(SX9324_REG_PROX_CTRL5_CLOSE_DEBOUNCE_MASK, regval);
0584     if (regval)
0585         *val = 1 << regval;
0586     else
0587         *val = 0;
0588 
0589     return IIO_VAL_INT;
0590 }
0591 
0592 static int sx9324_read_event_val(struct iio_dev *indio_dev,
0593                  const struct iio_chan_spec *chan,
0594                  enum iio_event_type type,
0595                  enum iio_event_direction dir,
0596                  enum iio_event_info info, int *val, int *val2)
0597 {
0598     struct sx_common_data *data = iio_priv(indio_dev);
0599 
0600     if (chan->type != IIO_PROXIMITY)
0601         return -EINVAL;
0602 
0603     switch (info) {
0604     case IIO_EV_INFO_VALUE:
0605         return sx9324_read_thresh(data, chan, val);
0606     case IIO_EV_INFO_PERIOD:
0607         switch (dir) {
0608         case IIO_EV_DIR_RISING:
0609             return sx9324_read_far_debounce(data, val);
0610         case IIO_EV_DIR_FALLING:
0611             return sx9324_read_close_debounce(data, val);
0612         default:
0613             return -EINVAL;
0614         }
0615     case IIO_EV_INFO_HYSTERESIS:
0616         return sx9324_read_hysteresis(data, chan, val);
0617     default:
0618         return -EINVAL;
0619     }
0620 }
0621 
0622 static int sx9324_write_thresh(struct sx_common_data *data,
0623                    const struct iio_chan_spec *chan, int _val)
0624 {
0625     unsigned int reg, val = _val;
0626     int ret;
0627 
0628     reg = SX9324_REG_PROX_CTRL6 + chan->channel / 2;
0629 
0630     if (val >= 1)
0631         val = int_sqrt(2 * val);
0632 
0633     if (val > 0xff)
0634         return -EINVAL;
0635 
0636     mutex_lock(&data->mutex);
0637     ret = regmap_write(data->regmap, reg, val);
0638     mutex_unlock(&data->mutex);
0639 
0640     return ret;
0641 }
0642 
0643 static int sx9324_write_hysteresis(struct sx_common_data *data,
0644                    const struct iio_chan_spec *chan, int _val)
0645 {
0646     unsigned int hyst, val = _val;
0647     int ret, pthresh;
0648 
0649     ret = sx9324_read_thresh(data, chan, &pthresh);
0650     if (ret < 0)
0651         return ret;
0652 
0653     if (val == 0)
0654         hyst = 0;
0655     else if (val >= pthresh >> 2)
0656         hyst = 3;
0657     else if (val >= pthresh >> 3)
0658         hyst = 2;
0659     else if (val >= pthresh >> 4)
0660         hyst = 1;
0661     else
0662         return -EINVAL;
0663 
0664     hyst = FIELD_PREP(SX9324_REG_PROX_CTRL5_HYST_MASK, hyst);
0665     mutex_lock(&data->mutex);
0666     ret = regmap_update_bits(data->regmap, SX9324_REG_PROX_CTRL5,
0667                  SX9324_REG_PROX_CTRL5_HYST_MASK, hyst);
0668     mutex_unlock(&data->mutex);
0669 
0670     return ret;
0671 }
0672 
0673 static int sx9324_write_far_debounce(struct sx_common_data *data, int _val)
0674 {
0675     unsigned int regval, val = _val;
0676     int ret;
0677 
0678     if (val > 0)
0679         val = ilog2(val);
0680     if (!FIELD_FIT(SX9324_REG_PROX_CTRL5_FAR_DEBOUNCE_MASK, val))
0681         return -EINVAL;
0682 
0683     regval = FIELD_PREP(SX9324_REG_PROX_CTRL5_FAR_DEBOUNCE_MASK, val);
0684 
0685     mutex_lock(&data->mutex);
0686     ret = regmap_update_bits(data->regmap, SX9324_REG_PROX_CTRL5,
0687                  SX9324_REG_PROX_CTRL5_FAR_DEBOUNCE_MASK,
0688                  regval);
0689     mutex_unlock(&data->mutex);
0690 
0691     return ret;
0692 }
0693 
0694 static int sx9324_write_close_debounce(struct sx_common_data *data, int _val)
0695 {
0696     unsigned int regval, val = _val;
0697     int ret;
0698 
0699     if (val > 0)
0700         val = ilog2(val);
0701     if (!FIELD_FIT(SX9324_REG_PROX_CTRL5_CLOSE_DEBOUNCE_MASK, val))
0702         return -EINVAL;
0703 
0704     regval = FIELD_PREP(SX9324_REG_PROX_CTRL5_CLOSE_DEBOUNCE_MASK, val);
0705 
0706     mutex_lock(&data->mutex);
0707     ret = regmap_update_bits(data->regmap, SX9324_REG_PROX_CTRL5,
0708                  SX9324_REG_PROX_CTRL5_CLOSE_DEBOUNCE_MASK,
0709                  regval);
0710     mutex_unlock(&data->mutex);
0711 
0712     return ret;
0713 }
0714 
0715 static int sx9324_write_event_val(struct iio_dev *indio_dev,
0716                   const struct iio_chan_spec *chan,
0717                   enum iio_event_type type,
0718                   enum iio_event_direction dir,
0719                   enum iio_event_info info, int val, int val2)
0720 {
0721     struct sx_common_data *data = iio_priv(indio_dev);
0722 
0723     if (chan->type != IIO_PROXIMITY)
0724         return -EINVAL;
0725 
0726     switch (info) {
0727     case IIO_EV_INFO_VALUE:
0728         return sx9324_write_thresh(data, chan, val);
0729     case IIO_EV_INFO_PERIOD:
0730         switch (dir) {
0731         case IIO_EV_DIR_RISING:
0732             return sx9324_write_far_debounce(data, val);
0733         case IIO_EV_DIR_FALLING:
0734             return sx9324_write_close_debounce(data, val);
0735         default:
0736             return -EINVAL;
0737         }
0738     case IIO_EV_INFO_HYSTERESIS:
0739         return sx9324_write_hysteresis(data, chan, val);
0740     default:
0741         return -EINVAL;
0742     }
0743 }
0744 
0745 static int sx9324_write_gain(struct sx_common_data *data,
0746                  const struct iio_chan_spec *chan, int val)
0747 {
0748     unsigned int gain, reg;
0749     int ret;
0750 
0751     reg = SX9324_REG_PROX_CTRL0 + chan->channel / 2;
0752 
0753     gain = ilog2(val) + 1;
0754     if (val <= 0 || gain > SX9324_REG_PROX_CTRL0_GAIN_8)
0755         return -EINVAL;
0756 
0757     gain = FIELD_PREP(SX9324_REG_PROX_CTRL0_GAIN_MASK, gain);
0758 
0759     mutex_lock(&data->mutex);
0760     ret = regmap_update_bits(data->regmap, reg,
0761                  SX9324_REG_PROX_CTRL0_GAIN_MASK,
0762                  gain);
0763     mutex_unlock(&data->mutex);
0764 
0765     return ret;
0766 }
0767 
0768 static int sx9324_write_raw(struct iio_dev *indio_dev,
0769                 const struct iio_chan_spec *chan, int val, int val2,
0770                 long mask)
0771 {
0772     struct sx_common_data *data = iio_priv(indio_dev);
0773 
0774     switch (mask) {
0775     case IIO_CHAN_INFO_SAMP_FREQ:
0776         return sx9324_set_samp_freq(data, val, val2);
0777     case IIO_CHAN_INFO_HARDWAREGAIN:
0778         return sx9324_write_gain(data, chan, val);
0779     default:
0780         return -EINVAL;
0781     }
0782 }
0783 
0784 static const struct sx_common_reg_default sx9324_default_regs[] = {
0785     { SX9324_REG_IRQ_MSK, 0x00 },
0786     { SX9324_REG_IRQ_CFG0, 0x00 },
0787     { SX9324_REG_IRQ_CFG1, SX9324_REG_IRQ_CFG1_FAILCOND },
0788     { SX9324_REG_IRQ_CFG2, 0x00 },
0789     { SX9324_REG_GNRL_CTRL0, SX9324_REG_GNRL_CTRL0_SCANPERIOD_100MS },
0790     /*
0791      * The lower 4 bits should not be set as it enable sensors measurements.
0792      * Turning the detection on before the configuration values are set to
0793      * good values can cause the device to return erroneous readings.
0794      */
0795     { SX9324_REG_GNRL_CTRL1, SX9324_REG_GNRL_CTRL1_PAUSECTRL },
0796 
0797     { SX9324_REG_AFE_CTRL0, SX9324_REG_AFE_CTRL0_RINT_LOWEST },
0798     { SX9324_REG_AFE_CTRL3, 0x00 },
0799     { SX9324_REG_AFE_CTRL4, SX9324_REG_AFE_CTRL4_FREQ_83_33HZ |
0800         SX9324_REG_AFE_CTRL4_RES_100 },
0801     { SX9324_REG_AFE_CTRL6, 0x00 },
0802     { SX9324_REG_AFE_CTRL7, SX9324_REG_AFE_CTRL4_FREQ_83_33HZ |
0803         SX9324_REG_AFE_CTRL4_RES_100 },
0804 
0805     /* TODO(gwendal): PHx use chip default or all grounded? */
0806     { SX9324_REG_AFE_PH0, 0x29 },
0807     { SX9324_REG_AFE_PH1, 0x26 },
0808     { SX9324_REG_AFE_PH2, 0x1a },
0809     { SX9324_REG_AFE_PH3, 0x16 },
0810 
0811     { SX9324_REG_AFE_CTRL8, SX9324_REG_AFE_CTRL8_RESERVED |
0812         SX9324_REG_AFE_CTRL8_RESFILTIN_4KOHM },
0813     { SX9324_REG_AFE_CTRL9, SX9324_REG_AFE_CTRL9_AGAIN_1 },
0814 
0815     { SX9324_REG_PROX_CTRL0,
0816         SX9324_REG_PROX_CTRL0_GAIN_1 << SX9324_REG_PROX_CTRL0_GAIN_SHIFT |
0817         SX9324_REG_PROX_CTRL0_RAWFILT_1P50 },
0818     { SX9324_REG_PROX_CTRL1,
0819         SX9324_REG_PROX_CTRL0_GAIN_1 << SX9324_REG_PROX_CTRL0_GAIN_SHIFT |
0820         SX9324_REG_PROX_CTRL0_RAWFILT_1P50 },
0821     { SX9324_REG_PROX_CTRL2, SX9324_REG_PROX_CTRL2_AVGNEG_THRESH_16K },
0822     { SX9324_REG_PROX_CTRL3, SX9324_REG_PROX_CTRL3_AVGDEB_2SAMPLES |
0823         SX9324_REG_PROX_CTRL3_AVGPOS_THRESH_16K },
0824     { SX9324_REG_PROX_CTRL4, SX9324_REG_PROX_CTRL4_AVGNEG_FILT_2 |
0825         SX9324_REG_PROX_CTRL4_AVGPOS_FILT_256 },
0826     { SX9324_REG_PROX_CTRL5, 0x00 },
0827     { SX9324_REG_PROX_CTRL6, SX9324_REG_PROX_CTRL6_PROXTHRESH_32 },
0828     { SX9324_REG_PROX_CTRL7, SX9324_REG_PROX_CTRL6_PROXTHRESH_32 },
0829     { SX9324_REG_ADV_CTRL0, 0x00 },
0830     { SX9324_REG_ADV_CTRL1, 0x00 },
0831     { SX9324_REG_ADV_CTRL2, 0x00 },
0832     { SX9324_REG_ADV_CTRL3, 0x00 },
0833     { SX9324_REG_ADV_CTRL4, 0x00 },
0834     { SX9324_REG_ADV_CTRL5, SX9324_REG_ADV_CTRL5_STARTUP_SENSOR_1 |
0835         SX9324_REG_ADV_CTRL5_STARTUP_METHOD_1 },
0836     { SX9324_REG_ADV_CTRL6, 0x00 },
0837     { SX9324_REG_ADV_CTRL7, 0x00 },
0838     { SX9324_REG_ADV_CTRL8, 0x00 },
0839     { SX9324_REG_ADV_CTRL9, 0x00 },
0840     /* Body/Table threshold */
0841     { SX9324_REG_ADV_CTRL10, 0x00 },
0842     { SX9324_REG_ADV_CTRL11, 0x00 },
0843     { SX9324_REG_ADV_CTRL12, 0x00 },
0844     /* TODO(gwendal): SAR currenly disabled */
0845     { SX9324_REG_ADV_CTRL13, 0x00 },
0846     { SX9324_REG_ADV_CTRL14, 0x00 },
0847     { SX9324_REG_ADV_CTRL15, 0x00 },
0848     { SX9324_REG_ADV_CTRL16, 0x00 },
0849     { SX9324_REG_ADV_CTRL17, 0x00 },
0850     { SX9324_REG_ADV_CTRL18, 0x00 },
0851     { SX9324_REG_ADV_CTRL19, SX9324_REG_ADV_CTRL19_HIGHT_FAILURE_THRESH_SATURATION },
0852     { SX9324_REG_ADV_CTRL20, SX9324_REG_ADV_CTRL19_HIGHT_FAILURE_THRESH_SATURATION },
0853 };
0854 
0855 /* Activate all channels and perform an initial compensation. */
0856 static int sx9324_init_compensation(struct iio_dev *indio_dev)
0857 {
0858     struct sx_common_data *data = iio_priv(indio_dev);
0859     unsigned int val;
0860     int ret;
0861 
0862     /* run the compensation phase on all channels */
0863     ret = regmap_update_bits(data->regmap, SX9324_REG_STAT2,
0864                  SX9324_REG_STAT2_COMPSTAT_MASK,
0865                  SX9324_REG_STAT2_COMPSTAT_MASK);
0866     if (ret)
0867         return ret;
0868 
0869     return regmap_read_poll_timeout(data->regmap, SX9324_REG_STAT2, val,
0870                     !(val & SX9324_REG_STAT2_COMPSTAT_MASK),
0871                     20000, 2000000);
0872 }
0873 
0874 static const struct sx_common_reg_default *
0875 sx9324_get_default_reg(struct device *dev, int idx,
0876                struct sx_common_reg_default *reg_def)
0877 {
0878     static const char * const sx9324_rints[] = { "lowest", "low", "high",
0879         "highest" };
0880     static const char * const sx9324_csidle[] = { "hi-z", "hi-z", "gnd",
0881         "vdd" };
0882 #define SX9324_PIN_DEF "semtech,ph0-pin"
0883 #define SX9324_RESOLUTION_DEF "semtech,ph01-resolution"
0884 #define SX9324_PROXRAW_DEF "semtech,ph01-proxraw-strength"
0885     unsigned int pin_defs[SX9324_NUM_PINS];
0886     char prop[] = SX9324_PROXRAW_DEF;
0887     u32 start = 0, raw = 0, pos = 0;
0888     int ret, count, ph, pin;
0889     const char *res;
0890 
0891     memcpy(reg_def, &sx9324_default_regs[idx], sizeof(*reg_def));
0892     switch (reg_def->reg) {
0893     case SX9324_REG_AFE_PH0:
0894     case SX9324_REG_AFE_PH1:
0895     case SX9324_REG_AFE_PH2:
0896     case SX9324_REG_AFE_PH3:
0897         ph = reg_def->reg - SX9324_REG_AFE_PH0;
0898         scnprintf(prop, ARRAY_SIZE(prop), "semtech,ph%d-pin", ph);
0899 
0900         count = device_property_count_u32(dev, prop);
0901         if (count != ARRAY_SIZE(pin_defs))
0902             break;
0903         ret = device_property_read_u32_array(dev, prop, pin_defs,
0904                              ARRAY_SIZE(pin_defs));
0905         if (ret)
0906             break;
0907 
0908         for (pin = 0; pin < SX9324_NUM_PINS; pin++)
0909             raw |= (pin_defs[pin] << (2 * pin)) &
0910                    SX9324_REG_AFE_PH0_PIN_MASK(pin);
0911         reg_def->def = raw;
0912         break;
0913     case SX9324_REG_AFE_CTRL0:
0914         ret = device_property_read_string(dev,
0915                 "semtech,cs-idle-sleep", &res);
0916         if (!ret)
0917             ret = match_string(sx9324_csidle, ARRAY_SIZE(sx9324_csidle), res);
0918         if (ret >= 0) {
0919             reg_def->def &= ~SX9324_REG_AFE_CTRL0_CSIDLE_MASK;
0920             reg_def->def |= ret << SX9324_REG_AFE_CTRL0_CSIDLE_SHIFT;
0921         }
0922 
0923         ret = device_property_read_string(dev,
0924                 "semtech,int-comp-resistor", &res);
0925         if (ret)
0926             break;
0927         ret = match_string(sx9324_rints, ARRAY_SIZE(sx9324_rints), res);
0928         if (ret < 0)
0929             break;
0930         reg_def->def &= ~SX9324_REG_AFE_CTRL0_RINT_MASK;
0931         reg_def->def |= ret << SX9324_REG_AFE_CTRL0_RINT_SHIFT;
0932         break;
0933     case SX9324_REG_AFE_CTRL4:
0934     case SX9324_REG_AFE_CTRL7:
0935         if (reg_def->reg == SX9324_REG_AFE_CTRL4)
0936             strncpy(prop, "semtech,ph01-resolution",
0937                 ARRAY_SIZE(prop));
0938         else
0939             strncpy(prop, "semtech,ph23-resolution",
0940                 ARRAY_SIZE(prop));
0941 
0942         ret = device_property_read_u32(dev, prop, &raw);
0943         if (ret)
0944             break;
0945 
0946         raw = ilog2(raw) - 3;
0947 
0948         reg_def->def &= ~SX9324_REG_AFE_CTRL4_RESOLUTION_MASK;
0949         reg_def->def |= FIELD_PREP(SX9324_REG_AFE_CTRL4_RESOLUTION_MASK,
0950                        raw);
0951         break;
0952     case SX9324_REG_AFE_CTRL8:
0953         ret = device_property_read_u32(dev,
0954                 "semtech,input-precharge-resistor-ohms",
0955                 &raw);
0956         if (ret)
0957             break;
0958 
0959         reg_def->def &= ~SX9324_REG_AFE_CTRL8_RESFILTIN_MASK;
0960         reg_def->def |= FIELD_PREP(SX9324_REG_AFE_CTRL8_RESFILTIN_MASK,
0961                        raw / 2000);
0962         break;
0963 
0964     case SX9324_REG_AFE_CTRL9:
0965         ret = device_property_read_u32(dev,
0966                 "semtech,input-analog-gain", &raw);
0967         if (ret)
0968             break;
0969         /*
0970          * The analog gain has the following setting:
0971          * +---------+----------------+----------------+
0972          * | dt(raw) | physical value | register value |
0973          * +---------+----------------+----------------+
0974          * |  0      |      x1.247    |      6         |
0975          * |  1      |      x1        |      8         |
0976          * |  2      |      x0.768    |     11         |
0977          * |  3      |      x0.552    |     15         |
0978          * +---------+----------------+----------------+
0979          */
0980         reg_def->def &= ~SX9324_REG_AFE_CTRL9_AGAIN_MASK;
0981         reg_def->def |= FIELD_PREP(SX9324_REG_AFE_CTRL9_AGAIN_MASK,
0982                        6 + raw * (raw + 3) / 2);
0983         break;
0984 
0985     case SX9324_REG_ADV_CTRL5:
0986         ret = device_property_read_u32(dev, "semtech,startup-sensor",
0987                            &start);
0988         if (ret)
0989             break;
0990 
0991         reg_def->def &= ~SX9324_REG_ADV_CTRL5_STARTUPSENS_MASK;
0992         reg_def->def |= FIELD_PREP(SX9324_REG_ADV_CTRL5_STARTUPSENS_MASK,
0993                        start);
0994         break;
0995     case SX9324_REG_PROX_CTRL4:
0996         ret = device_property_read_u32(dev, "semtech,avg-pos-strength",
0997                            &pos);
0998         if (ret)
0999             break;
1000 
1001         /* Powers of 2, except for a gap between 16 and 64 */
1002         raw = clamp(ilog2(pos), 3, 11) - (pos >= 32 ? 4 : 3);
1003 
1004         reg_def->def &= ~SX9324_REG_PROX_CTRL4_AVGPOSFILT_MASK;
1005         reg_def->def |= FIELD_PREP(SX9324_REG_PROX_CTRL4_AVGPOSFILT_MASK,
1006                        raw);
1007         break;
1008     case SX9324_REG_PROX_CTRL0:
1009     case SX9324_REG_PROX_CTRL1:
1010         if (reg_def->reg == SX9324_REG_PROX_CTRL0)
1011             strncpy(prop, "semtech,ph01-proxraw-strength",
1012                 ARRAY_SIZE(prop));
1013         else
1014             strncpy(prop, "semtech,ph23-proxraw-strength",
1015                 ARRAY_SIZE(prop));
1016         ret = device_property_read_u32(dev, prop, &raw);
1017         if (ret)
1018             break;
1019 
1020         reg_def->def &= ~SX9324_REG_PROX_CTRL0_RAWFILT_MASK;
1021         reg_def->def |= FIELD_PREP(SX9324_REG_PROX_CTRL0_RAWFILT_MASK,
1022                        raw);
1023         break;
1024     }
1025     return reg_def;
1026 }
1027 
1028 static int sx9324_check_whoami(struct device *dev,
1029                    struct iio_dev *indio_dev)
1030 {
1031     /*
1032      * Only one sensor for this driver. Assuming the device tree
1033      * is correct, just set the sensor name.
1034      */
1035     indio_dev->name = "sx9324";
1036     return 0;
1037 }
1038 
1039 static const struct sx_common_chip_info sx9324_chip_info = {
1040     .reg_stat = SX9324_REG_STAT0,
1041     .reg_irq_msk = SX9324_REG_IRQ_MSK,
1042     .reg_enable_chan = SX9324_REG_GNRL_CTRL1,
1043     .reg_reset = SX9324_REG_RESET,
1044 
1045     .mask_enable_chan = SX9324_REG_GNRL_CTRL1_PHEN_MASK,
1046     .irq_msk_offset = 3,
1047     .num_channels = SX9324_NUM_CHANNELS,
1048     .num_default_regs = ARRAY_SIZE(sx9324_default_regs),
1049 
1050     .ops = {
1051         .read_prox_data = sx9324_read_prox_data,
1052         .check_whoami = sx9324_check_whoami,
1053         .init_compensation = sx9324_init_compensation,
1054         .wait_for_sample = sx9324_wait_for_sample,
1055         .get_default_reg = sx9324_get_default_reg,
1056     },
1057 
1058     .iio_channels = sx9324_channels,
1059     .num_iio_channels = ARRAY_SIZE(sx9324_channels),
1060     .iio_info =  {
1061         .read_raw = sx9324_read_raw,
1062         .read_avail = sx9324_read_avail,
1063         .read_event_value = sx9324_read_event_val,
1064         .write_event_value = sx9324_write_event_val,
1065         .write_raw = sx9324_write_raw,
1066         .read_event_config = sx_common_read_event_config,
1067         .write_event_config = sx_common_write_event_config,
1068     },
1069 };
1070 
1071 static int sx9324_probe(struct i2c_client *client)
1072 {
1073     return sx_common_probe(client, &sx9324_chip_info, &sx9324_regmap_config);
1074 }
1075 
1076 static int __maybe_unused sx9324_suspend(struct device *dev)
1077 {
1078     struct sx_common_data *data = iio_priv(dev_get_drvdata(dev));
1079     unsigned int regval;
1080     int ret;
1081 
1082     disable_irq_nosync(data->client->irq);
1083 
1084     mutex_lock(&data->mutex);
1085     ret = regmap_read(data->regmap, SX9324_REG_GNRL_CTRL1, &regval);
1086 
1087     data->suspend_ctrl =
1088         FIELD_GET(SX9324_REG_GNRL_CTRL1_PHEN_MASK, regval);
1089 
1090     if (ret < 0)
1091         goto out;
1092 
1093     /* Disable all phases, send the device to sleep. */
1094     ret = regmap_write(data->regmap, SX9324_REG_GNRL_CTRL1, 0);
1095 
1096 out:
1097     mutex_unlock(&data->mutex);
1098     return ret;
1099 }
1100 
1101 static int __maybe_unused sx9324_resume(struct device *dev)
1102 {
1103     struct sx_common_data *data = iio_priv(dev_get_drvdata(dev));
1104     int ret;
1105 
1106     mutex_lock(&data->mutex);
1107     ret = regmap_write(data->regmap, SX9324_REG_GNRL_CTRL1,
1108                data->suspend_ctrl | SX9324_REG_GNRL_CTRL1_PAUSECTRL);
1109     mutex_unlock(&data->mutex);
1110     if (ret)
1111         return ret;
1112 
1113     enable_irq(data->client->irq);
1114     return 0;
1115 }
1116 
1117 static SIMPLE_DEV_PM_OPS(sx9324_pm_ops, sx9324_suspend, sx9324_resume);
1118 
1119 static const struct acpi_device_id sx9324_acpi_match[] = {
1120     { "STH9324", SX9324_WHOAMI_VALUE },
1121     { }
1122 };
1123 MODULE_DEVICE_TABLE(acpi, sx9324_acpi_match);
1124 
1125 static const struct of_device_id sx9324_of_match[] = {
1126     { .compatible = "semtech,sx9324", (void *)SX9324_WHOAMI_VALUE },
1127     { }
1128 };
1129 MODULE_DEVICE_TABLE(of, sx9324_of_match);
1130 
1131 static const struct i2c_device_id sx9324_id[] = {
1132     { "sx9324", SX9324_WHOAMI_VALUE },
1133     { }
1134 };
1135 MODULE_DEVICE_TABLE(i2c, sx9324_id);
1136 
1137 static struct i2c_driver sx9324_driver = {
1138     .driver = {
1139         .name   = "sx9324",
1140         .acpi_match_table = sx9324_acpi_match,
1141         .of_match_table = sx9324_of_match,
1142         .pm = &sx9324_pm_ops,
1143 
1144         /*
1145          * Lots of i2c transfers in probe + over 200 ms waiting in
1146          * sx9324_init_compensation() mean a slow probe; prefer async
1147          * so we don't delay boot if we're builtin to the kernel.
1148          */
1149         .probe_type = PROBE_PREFER_ASYNCHRONOUS,
1150     },
1151     .probe_new  = sx9324_probe,
1152     .id_table   = sx9324_id,
1153 };
1154 module_i2c_driver(sx9324_driver);
1155 
1156 MODULE_AUTHOR("Gwendal Grignou <gwendal@chromium.org>");
1157 MODULE_DESCRIPTION("Driver for Semtech SX9324 proximity sensor");
1158 MODULE_LICENSE("GPL v2");
1159 MODULE_IMPORT_NS(SEMTECH_PROX);