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 SX9360 capacitive proximity/button solution.
0006  * Based on SX9360 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 /* Nominal Oscillator Frequency. */
0029 #define SX9360_FOSC_MHZ         4
0030 #define SX9360_FOSC_HZ          (SX9360_FOSC_MHZ * 1000000)
0031 
0032 /* Register definitions. */
0033 #define SX9360_REG_IRQ_SRC      SX_COMMON_REG_IRQ_SRC
0034 #define SX9360_REG_STAT     0x01
0035 #define SX9360_REG_STAT_COMPSTAT_MASK   GENMASK(2, 1)
0036 #define SX9360_REG_IRQ_MSK      0x02
0037 #define SX9360_CONVDONE_IRQ     BIT(0)
0038 #define SX9360_FAR_IRQ          BIT(2)
0039 #define SX9360_CLOSE_IRQ        BIT(3)
0040 #define SX9360_REG_IRQ_CFG      0x03
0041 
0042 #define SX9360_REG_GNRL_CTRL0       0x10
0043 #define SX9360_REG_GNRL_CTRL0_PHEN_MASK GENMASK(1, 0)
0044 #define SX9360_REG_GNRL_CTRL1       0x11
0045 #define SX9360_REG_GNRL_CTRL1_SCANPERIOD_MASK GENMASK(2, 0)
0046 #define SX9360_REG_GNRL_CTRL2       0x12
0047 #define SX9360_REG_GNRL_CTRL2_PERIOD_102MS  0x32
0048 #define SX9360_REG_GNRL_REG_2_PERIOD_MS(_r) \
0049     (((_r) * 8192) / (SX9360_FOSC_HZ / 1000))
0050 #define SX9360_REG_GNRL_FREQ_2_REG(_f)  (((_f) * 8192) / SX9360_FOSC_HZ)
0051 #define SX9360_REG_GNRL_REG_2_FREQ(_r)  (SX9360_FOSC_HZ / ((_r) * 8192))
0052 
0053 #define SX9360_REG_AFE_CTRL1        0x21
0054 #define SX9360_REG_AFE_CTRL1_RESFILTIN_MASK GENMASK(3, 0)
0055 #define SX9360_REG_AFE_CTRL1_RESFILTIN_0OHMS 0
0056 #define SX9360_REG_AFE_PARAM0_PHR   0x22
0057 #define SX9360_REG_AFE_PARAM1_PHR   0x23
0058 #define SX9360_REG_AFE_PARAM0_PHM   0x24
0059 #define SX9360_REG_AFE_PARAM0_RSVD      0x08
0060 #define SX9360_REG_AFE_PARAM0_RESOLUTION_MASK   GENMASK(2, 0)
0061 #define SX9360_REG_AFE_PARAM0_RESOLUTION_128    0x02
0062 #define SX9360_REG_AFE_PARAM1_PHM   0x25
0063 #define SX9360_REG_AFE_PARAM1_AGAIN_PHM_6PF 0x40
0064 #define SX9360_REG_AFE_PARAM1_FREQ_83_33HZ  0x06
0065 
0066 #define SX9360_REG_PROX_CTRL0_PHR   0x40
0067 #define SX9360_REG_PROX_CTRL0_PHM   0x41
0068 #define SX9360_REG_PROX_CTRL0_GAIN_MASK GENMASK(5, 3)
0069 #define SX9360_REG_PROX_CTRL0_GAIN_1        0x80
0070 #define SX9360_REG_PROX_CTRL0_RAWFILT_MASK  GENMASK(2, 0)
0071 #define SX9360_REG_PROX_CTRL0_RAWFILT_1P50  0x01
0072 #define SX9360_REG_PROX_CTRL1       0x42
0073 #define SX9360_REG_PROX_CTRL1_AVGNEG_THRESH_MASK    GENMASK(5, 3)
0074 #define SX9360_REG_PROX_CTRL1_AVGNEG_THRESH_16K 0x20
0075 #define SX9360_REG_PROX_CTRL2       0x43
0076 #define SX9360_REG_PROX_CTRL2_AVGDEB_MASK   GENMASK(7, 6)
0077 #define SX9360_REG_PROX_CTRL2_AVGDEB_2SAMPLES   0x40
0078 #define SX9360_REG_PROX_CTRL2_AVGPOS_THRESH_16K 0x20
0079 #define SX9360_REG_PROX_CTRL3       0x44
0080 #define SX9360_REG_PROX_CTRL3_AVGNEG_FILT_MASK  GENMASK(5, 3)
0081 #define SX9360_REG_PROX_CTRL3_AVGNEG_FILT_2 0x08
0082 #define SX9360_REG_PROX_CTRL3_AVGPOS_FILT_MASK  GENMASK(2, 0)
0083 #define SX9360_REG_PROX_CTRL3_AVGPOS_FILT_256   0x04
0084 #define SX9360_REG_PROX_CTRL4       0x45
0085 #define SX9360_REG_PROX_CTRL4_HYST_MASK         GENMASK(5, 4)
0086 #define SX9360_REG_PROX_CTRL4_CLOSE_DEBOUNCE_MASK   GENMASK(3, 2)
0087 #define SX9360_REG_PROX_CTRL4_FAR_DEBOUNCE_MASK     GENMASK(1, 0)
0088 #define SX9360_REG_PROX_CTRL5       0x46
0089 #define SX9360_REG_PROX_CTRL5_PROXTHRESH_32 0x08
0090 
0091 #define SX9360_REG_REF_CORR0        0x60
0092 #define SX9360_REG_REF_CORR1        0x61
0093 
0094 #define SX9360_REG_USEFUL_PHR_MSB       0x90
0095 #define SX9360_REG_USEFUL_PHR_LSB       0x91
0096 
0097 #define SX9360_REG_OFFSET_PMR_MSB       0x92
0098 #define SX9360_REG_OFFSET_PMR_LSB       0x93
0099 
0100 #define SX9360_REG_USEFUL_PHM_MSB       0x94
0101 #define SX9360_REG_USEFUL_PHM_LSB       0x95
0102 
0103 #define SX9360_REG_AVG_PHM_MSB      0x96
0104 #define SX9360_REG_AVG_PHM_LSB      0x97
0105 
0106 #define SX9360_REG_DIFF_PHM_MSB     0x98
0107 #define SX9360_REG_DIFF_PHM_LSB     0x99
0108 
0109 #define SX9360_REG_OFFSET_PHM_MSB       0x9a
0110 #define SX9360_REG_OFFSET_PHM_LSB       0x9b
0111 
0112 #define SX9360_REG_USE_FILTER_MSB       0x9a
0113 #define SX9360_REG_USE_FILTER_LSB       0x9b
0114 
0115 #define SX9360_REG_RESET        0xcf
0116 /* Write this to REG_RESET to do a soft reset. */
0117 #define SX9360_SOFT_RESET       0xde
0118 
0119 #define SX9360_REG_WHOAMI       0xfa
0120 #define   SX9360_WHOAMI_VALUE               0x60
0121 
0122 #define SX9360_REG_REVISION     0xfe
0123 
0124 /* 2 channels, Phase Reference and Measurement. */
0125 #define SX9360_NUM_CHANNELS     2
0126 
0127 static const struct iio_chan_spec sx9360_channels[] = {
0128     {
0129         .type = IIO_PROXIMITY,
0130         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0131                       BIT(IIO_CHAN_INFO_HARDWAREGAIN),
0132         .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
0133         .info_mask_separate_available =
0134             BIT(IIO_CHAN_INFO_HARDWAREGAIN),
0135         .info_mask_shared_by_all_available =
0136             BIT(IIO_CHAN_INFO_SAMP_FREQ),
0137         .indexed = 1,
0138         .address = SX9360_REG_USEFUL_PHR_MSB,
0139         .channel = 0,
0140         .scan_index = 0,
0141         .scan_type = {
0142             .sign = 's',
0143             .realbits = 12,
0144             .storagebits = 16,
0145             .endianness = IIO_BE,
0146         },
0147     },
0148     {
0149         .type = IIO_PROXIMITY,
0150         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0151                       BIT(IIO_CHAN_INFO_HARDWAREGAIN),
0152         .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
0153         .info_mask_separate_available =
0154             BIT(IIO_CHAN_INFO_HARDWAREGAIN),
0155         .info_mask_shared_by_all_available =
0156             BIT(IIO_CHAN_INFO_SAMP_FREQ),
0157         .indexed = 1,
0158         .address = SX9360_REG_USEFUL_PHM_MSB,
0159         .event_spec = sx_common_events,
0160         .num_event_specs = ARRAY_SIZE(sx_common_events),
0161         .channel = 1,
0162         .scan_index = 1,
0163         .scan_type = {
0164             .sign = 's',
0165             .realbits = 12,
0166             .storagebits = 16,
0167             .endianness = IIO_BE,
0168         },
0169     },
0170     IIO_CHAN_SOFT_TIMESTAMP(2),
0171 };
0172 
0173 /*
0174  * Each entry contains the integer part (val) and the fractional part, in micro
0175  * seconds. It conforms to the IIO output IIO_VAL_INT_PLUS_MICRO.
0176  *
0177  * The frequency control register holds the period, with a ~2ms increment.
0178  * Therefore the smallest frequency is 4MHz / (2047 * 8192),
0179  * The fastest is 4MHz / 8192.
0180  * The interval is not linear, but given there is 2047 possible value,
0181  * Returns the fake increment of (Max-Min)/2047
0182  */
0183 static const struct {
0184     int val;
0185     int val2;
0186 } sx9360_samp_freq_interval[] = {
0187     { 0, 281250 },  /* 4MHz / (8192 * 2047) */
0188     { 0, 281250 },
0189     { 448, 281250 },  /* 4MHz / 8192 */
0190 };
0191 
0192 static const struct regmap_range sx9360_writable_reg_ranges[] = {
0193     /*
0194      * To set COMPSTAT for compensation, even if datasheet says register is
0195      * RO.
0196      */
0197     regmap_reg_range(SX9360_REG_STAT, SX9360_REG_IRQ_CFG),
0198     regmap_reg_range(SX9360_REG_GNRL_CTRL0, SX9360_REG_GNRL_CTRL2),
0199     regmap_reg_range(SX9360_REG_AFE_CTRL1, SX9360_REG_AFE_PARAM1_PHM),
0200     regmap_reg_range(SX9360_REG_PROX_CTRL0_PHR, SX9360_REG_PROX_CTRL5),
0201     regmap_reg_range(SX9360_REG_REF_CORR0, SX9360_REG_REF_CORR1),
0202     regmap_reg_range(SX9360_REG_OFFSET_PMR_MSB, SX9360_REG_OFFSET_PMR_LSB),
0203     regmap_reg_range(SX9360_REG_RESET, SX9360_REG_RESET),
0204 };
0205 
0206 static const struct regmap_access_table sx9360_writeable_regs = {
0207     .yes_ranges = sx9360_writable_reg_ranges,
0208     .n_yes_ranges = ARRAY_SIZE(sx9360_writable_reg_ranges),
0209 };
0210 
0211 /*
0212  * All allocated registers are readable, so we just list unallocated
0213  * ones.
0214  */
0215 static const struct regmap_range sx9360_non_readable_reg_ranges[] = {
0216     regmap_reg_range(SX9360_REG_IRQ_CFG + 1, SX9360_REG_GNRL_CTRL0 - 1),
0217     regmap_reg_range(SX9360_REG_GNRL_CTRL2 + 1, SX9360_REG_AFE_CTRL1 - 1),
0218     regmap_reg_range(SX9360_REG_AFE_PARAM1_PHM + 1,
0219              SX9360_REG_PROX_CTRL0_PHR - 1),
0220     regmap_reg_range(SX9360_REG_PROX_CTRL5 + 1, SX9360_REG_REF_CORR0 - 1),
0221     regmap_reg_range(SX9360_REG_REF_CORR1 + 1,
0222              SX9360_REG_USEFUL_PHR_MSB - 1),
0223     regmap_reg_range(SX9360_REG_USE_FILTER_LSB + 1, SX9360_REG_RESET - 1),
0224     regmap_reg_range(SX9360_REG_RESET + 1, SX9360_REG_WHOAMI - 1),
0225     regmap_reg_range(SX9360_REG_WHOAMI + 1, SX9360_REG_REVISION - 1),
0226 };
0227 
0228 static const struct regmap_access_table sx9360_readable_regs = {
0229     .no_ranges = sx9360_non_readable_reg_ranges,
0230     .n_no_ranges = ARRAY_SIZE(sx9360_non_readable_reg_ranges),
0231 };
0232 
0233 static const struct regmap_range sx9360_volatile_reg_ranges[] = {
0234     regmap_reg_range(SX9360_REG_IRQ_SRC, SX9360_REG_STAT),
0235     regmap_reg_range(SX9360_REG_USEFUL_PHR_MSB, SX9360_REG_USE_FILTER_LSB),
0236     regmap_reg_range(SX9360_REG_WHOAMI, SX9360_REG_WHOAMI),
0237     regmap_reg_range(SX9360_REG_REVISION, SX9360_REG_REVISION),
0238 };
0239 
0240 static const struct regmap_access_table sx9360_volatile_regs = {
0241     .yes_ranges = sx9360_volatile_reg_ranges,
0242     .n_yes_ranges = ARRAY_SIZE(sx9360_volatile_reg_ranges),
0243 };
0244 
0245 static const struct regmap_config sx9360_regmap_config = {
0246     .reg_bits = 8,
0247     .val_bits = 8,
0248 
0249     .max_register = SX9360_REG_REVISION,
0250     .cache_type = REGCACHE_RBTREE,
0251 
0252     .wr_table = &sx9360_writeable_regs,
0253     .rd_table = &sx9360_readable_regs,
0254     .volatile_table = &sx9360_volatile_regs,
0255 };
0256 
0257 static int sx9360_read_prox_data(struct sx_common_data *data,
0258                  const struct iio_chan_spec *chan,
0259                  __be16 *val)
0260 {
0261     return regmap_bulk_read(data->regmap, chan->address, val, sizeof(*val));
0262 }
0263 
0264 /*
0265  * If we have no interrupt support, we have to wait for a scan period
0266  * after enabling a channel to get a result.
0267  */
0268 static int sx9360_wait_for_sample(struct sx_common_data *data)
0269 {
0270     int ret;
0271     __be16 buf;
0272 
0273     ret = regmap_bulk_read(data->regmap, SX9360_REG_GNRL_CTRL1,
0274                    &buf, sizeof(buf));
0275     if (ret < 0)
0276         return ret;
0277     msleep(SX9360_REG_GNRL_REG_2_PERIOD_MS(be16_to_cpu(buf)));
0278 
0279     return 0;
0280 }
0281 
0282 static int sx9360_read_gain(struct sx_common_data *data,
0283                 const struct iio_chan_spec *chan, int *val)
0284 {
0285     unsigned int reg, regval;
0286     int ret;
0287 
0288     reg = SX9360_REG_PROX_CTRL0_PHR + chan->channel;
0289     ret = regmap_read(data->regmap, reg, &regval);
0290     if (ret)
0291         return ret;
0292 
0293     *val = 1 << FIELD_GET(SX9360_REG_PROX_CTRL0_GAIN_MASK, regval);
0294 
0295     return IIO_VAL_INT;
0296 }
0297 
0298 static int sx9360_read_samp_freq(struct sx_common_data *data,
0299                  int *val, int *val2)
0300 {
0301     int ret, divisor;
0302     __be16 buf;
0303 
0304     ret = regmap_bulk_read(data->regmap, SX9360_REG_GNRL_CTRL1,
0305                    &buf, sizeof(buf));
0306     if (ret < 0)
0307         return ret;
0308     divisor = be16_to_cpu(buf);
0309     if (divisor == 0) {
0310         *val = 0;
0311         return IIO_VAL_INT;
0312     }
0313 
0314     *val = SX9360_FOSC_HZ;
0315     *val2 = divisor * 8192;
0316 
0317     return IIO_VAL_FRACTIONAL;
0318 }
0319 
0320 static int sx9360_read_raw(struct iio_dev *indio_dev,
0321                const struct iio_chan_spec *chan,
0322                int *val, int *val2, long mask)
0323 {
0324     struct sx_common_data *data = iio_priv(indio_dev);
0325     int ret;
0326 
0327     switch (mask) {
0328     case IIO_CHAN_INFO_RAW:
0329         ret = iio_device_claim_direct_mode(indio_dev);
0330         if (ret)
0331             return ret;
0332 
0333         ret = sx_common_read_proximity(data, chan, val);
0334         iio_device_release_direct_mode(indio_dev);
0335         return ret;
0336     case IIO_CHAN_INFO_HARDWAREGAIN:
0337         ret = iio_device_claim_direct_mode(indio_dev);
0338         if (ret)
0339             return ret;
0340 
0341         ret = sx9360_read_gain(data, chan, val);
0342         iio_device_release_direct_mode(indio_dev);
0343         return ret;
0344     case IIO_CHAN_INFO_SAMP_FREQ:
0345         return sx9360_read_samp_freq(data, val, val2);
0346     default:
0347         return -EINVAL;
0348     }
0349 }
0350 
0351 static const char *sx9360_channel_labels[SX9360_NUM_CHANNELS] = {
0352     "reference", "main",
0353 };
0354 
0355 static int sx9360_read_label(struct iio_dev *iio_dev, const struct iio_chan_spec *chan,
0356                  char *label)
0357 {
0358     return sysfs_emit(label, "%s\n", sx9360_channel_labels[chan->channel]);
0359 }
0360 
0361 static const int sx9360_gain_vals[] = { 1, 2, 4, 8 };
0362 
0363 static int sx9360_read_avail(struct iio_dev *indio_dev,
0364                  struct iio_chan_spec const *chan,
0365                  const int **vals, int *type, int *length,
0366                  long mask)
0367 {
0368     if (chan->type != IIO_PROXIMITY)
0369         return -EINVAL;
0370 
0371     switch (mask) {
0372     case IIO_CHAN_INFO_HARDWAREGAIN:
0373         *type = IIO_VAL_INT;
0374         *length = ARRAY_SIZE(sx9360_gain_vals);
0375         *vals = sx9360_gain_vals;
0376         return IIO_AVAIL_LIST;
0377     case IIO_CHAN_INFO_SAMP_FREQ:
0378         *type = IIO_VAL_INT_PLUS_MICRO;
0379         *length = ARRAY_SIZE(sx9360_samp_freq_interval) * 2;
0380         *vals = (int *)sx9360_samp_freq_interval;
0381         return IIO_AVAIL_RANGE;
0382     default:
0383         return -EINVAL;
0384     }
0385 }
0386 
0387 static int sx9360_set_samp_freq(struct sx_common_data *data,
0388                 int val, int val2)
0389 {
0390     int ret, reg;
0391     __be16 buf;
0392 
0393     reg = val * 8192 / SX9360_FOSC_HZ + val2 * 8192 / (SX9360_FOSC_MHZ);
0394     buf = cpu_to_be16(reg);
0395     mutex_lock(&data->mutex);
0396 
0397     ret = regmap_bulk_write(data->regmap, SX9360_REG_GNRL_CTRL1, &buf,
0398                 sizeof(buf));
0399 
0400     mutex_unlock(&data->mutex);
0401 
0402     return ret;
0403 }
0404 
0405 static int sx9360_read_thresh(struct sx_common_data *data, int *val)
0406 {
0407     unsigned int regval;
0408     int ret;
0409 
0410     ret = regmap_read(data->regmap, SX9360_REG_PROX_CTRL5, &regval);
0411     if (ret)
0412         return ret;
0413 
0414     if (regval <= 1)
0415         *val = regval;
0416     else
0417         *val = (regval * regval) / 2;
0418 
0419     return IIO_VAL_INT;
0420 }
0421 
0422 static int sx9360_read_hysteresis(struct sx_common_data *data, int *val)
0423 {
0424     unsigned int regval, pthresh;
0425     int ret;
0426 
0427     ret = sx9360_read_thresh(data, &pthresh);
0428     if (ret < 0)
0429         return ret;
0430 
0431     ret = regmap_read(data->regmap, SX9360_REG_PROX_CTRL4, &regval);
0432     if (ret)
0433         return ret;
0434 
0435     regval = FIELD_GET(SX9360_REG_PROX_CTRL4_HYST_MASK, regval);
0436     if (!regval)
0437         *val = 0;
0438     else
0439         *val = pthresh >> (5 - regval);
0440 
0441     return IIO_VAL_INT;
0442 }
0443 
0444 static int sx9360_read_far_debounce(struct sx_common_data *data, int *val)
0445 {
0446     unsigned int regval;
0447     int ret;
0448 
0449     ret = regmap_read(data->regmap, SX9360_REG_PROX_CTRL4, &regval);
0450     if (ret)
0451         return ret;
0452 
0453     regval = FIELD_GET(SX9360_REG_PROX_CTRL4_FAR_DEBOUNCE_MASK, regval);
0454     if (regval)
0455         *val = 1 << regval;
0456     else
0457         *val = 0;
0458 
0459     return IIO_VAL_INT;
0460 }
0461 
0462 static int sx9360_read_close_debounce(struct sx_common_data *data, int *val)
0463 {
0464     unsigned int regval;
0465     int ret;
0466 
0467     ret = regmap_read(data->regmap, SX9360_REG_PROX_CTRL4, &regval);
0468     if (ret)
0469         return ret;
0470 
0471     regval = FIELD_GET(SX9360_REG_PROX_CTRL4_CLOSE_DEBOUNCE_MASK, regval);
0472     if (regval)
0473         *val = 1 << regval;
0474     else
0475         *val = 0;
0476 
0477     return IIO_VAL_INT;
0478 }
0479 
0480 static int sx9360_read_event_val(struct iio_dev *indio_dev,
0481                  const struct iio_chan_spec *chan,
0482                  enum iio_event_type type,
0483                  enum iio_event_direction dir,
0484                  enum iio_event_info info, int *val, int *val2)
0485 {
0486     struct sx_common_data *data = iio_priv(indio_dev);
0487 
0488     if (chan->type != IIO_PROXIMITY)
0489         return -EINVAL;
0490 
0491     switch (info) {
0492     case IIO_EV_INFO_VALUE:
0493         return sx9360_read_thresh(data, val);
0494     case IIO_EV_INFO_PERIOD:
0495         switch (dir) {
0496         case IIO_EV_DIR_RISING:
0497             return sx9360_read_far_debounce(data, val);
0498         case IIO_EV_DIR_FALLING:
0499             return sx9360_read_close_debounce(data, val);
0500         default:
0501             return -EINVAL;
0502         }
0503     case IIO_EV_INFO_HYSTERESIS:
0504         return sx9360_read_hysteresis(data, val);
0505     default:
0506         return -EINVAL;
0507     }
0508 }
0509 
0510 static int sx9360_write_thresh(struct sx_common_data *data, int _val)
0511 {
0512     unsigned int val = _val;
0513     int ret;
0514 
0515     if (val >= 1)
0516         val = int_sqrt(2 * val);
0517 
0518     if (val > 0xff)
0519         return -EINVAL;
0520 
0521     mutex_lock(&data->mutex);
0522     ret = regmap_write(data->regmap, SX9360_REG_PROX_CTRL5, val);
0523     mutex_unlock(&data->mutex);
0524 
0525     return ret;
0526 }
0527 
0528 static int sx9360_write_hysteresis(struct sx_common_data *data, int _val)
0529 {
0530     unsigned int hyst, val = _val;
0531     int ret, pthresh;
0532 
0533     ret = sx9360_read_thresh(data, &pthresh);
0534     if (ret < 0)
0535         return ret;
0536 
0537     if (val == 0)
0538         hyst = 0;
0539     else if (val >= pthresh >> 2)
0540         hyst = 3;
0541     else if (val >= pthresh >> 3)
0542         hyst = 2;
0543     else if (val >= pthresh >> 4)
0544         hyst = 1;
0545     else
0546         return -EINVAL;
0547 
0548     hyst = FIELD_PREP(SX9360_REG_PROX_CTRL4_HYST_MASK, hyst);
0549     mutex_lock(&data->mutex);
0550     ret = regmap_update_bits(data->regmap, SX9360_REG_PROX_CTRL4,
0551                  SX9360_REG_PROX_CTRL4_HYST_MASK, hyst);
0552     mutex_unlock(&data->mutex);
0553 
0554     return ret;
0555 }
0556 
0557 static int sx9360_write_far_debounce(struct sx_common_data *data, int _val)
0558 {
0559     unsigned int regval, val = _val;
0560     int ret;
0561 
0562     if (val > 0)
0563         val = ilog2(val);
0564     if (!FIELD_FIT(SX9360_REG_PROX_CTRL4_FAR_DEBOUNCE_MASK, val))
0565         return -EINVAL;
0566 
0567     regval = FIELD_PREP(SX9360_REG_PROX_CTRL4_FAR_DEBOUNCE_MASK, val);
0568 
0569     mutex_lock(&data->mutex);
0570     ret = regmap_update_bits(data->regmap, SX9360_REG_PROX_CTRL4,
0571                  SX9360_REG_PROX_CTRL4_FAR_DEBOUNCE_MASK,
0572                  regval);
0573     mutex_unlock(&data->mutex);
0574 
0575     return ret;
0576 }
0577 
0578 static int sx9360_write_close_debounce(struct sx_common_data *data, int _val)
0579 {
0580     unsigned int regval, val = _val;
0581     int ret;
0582 
0583     if (val > 0)
0584         val = ilog2(val);
0585     if (!FIELD_FIT(SX9360_REG_PROX_CTRL4_CLOSE_DEBOUNCE_MASK, val))
0586         return -EINVAL;
0587 
0588     regval = FIELD_PREP(SX9360_REG_PROX_CTRL4_CLOSE_DEBOUNCE_MASK, val);
0589 
0590     mutex_lock(&data->mutex);
0591     ret = regmap_update_bits(data->regmap, SX9360_REG_PROX_CTRL4,
0592                  SX9360_REG_PROX_CTRL4_CLOSE_DEBOUNCE_MASK,
0593                  regval);
0594     mutex_unlock(&data->mutex);
0595 
0596     return ret;
0597 }
0598 
0599 static int sx9360_write_event_val(struct iio_dev *indio_dev,
0600                   const struct iio_chan_spec *chan,
0601                   enum iio_event_type type,
0602                   enum iio_event_direction dir,
0603                   enum iio_event_info info, int val, int val2)
0604 {
0605     struct sx_common_data *data = iio_priv(indio_dev);
0606 
0607     if (chan->type != IIO_PROXIMITY)
0608         return -EINVAL;
0609 
0610     switch (info) {
0611     case IIO_EV_INFO_VALUE:
0612         return sx9360_write_thresh(data, val);
0613     case IIO_EV_INFO_PERIOD:
0614         switch (dir) {
0615         case IIO_EV_DIR_RISING:
0616             return sx9360_write_far_debounce(data, val);
0617         case IIO_EV_DIR_FALLING:
0618             return sx9360_write_close_debounce(data, val);
0619         default:
0620             return -EINVAL;
0621         }
0622     case IIO_EV_INFO_HYSTERESIS:
0623         return sx9360_write_hysteresis(data, val);
0624     default:
0625         return -EINVAL;
0626     }
0627 }
0628 
0629 static int sx9360_write_gain(struct sx_common_data *data,
0630                  const struct iio_chan_spec *chan, int val)
0631 {
0632     unsigned int gain, reg;
0633     int ret;
0634 
0635     gain = ilog2(val);
0636     reg = SX9360_REG_PROX_CTRL0_PHR + chan->channel;
0637     gain = FIELD_PREP(SX9360_REG_PROX_CTRL0_GAIN_MASK, gain);
0638 
0639     mutex_lock(&data->mutex);
0640     ret = regmap_update_bits(data->regmap, reg,
0641                  SX9360_REG_PROX_CTRL0_GAIN_MASK,
0642                  gain);
0643     mutex_unlock(&data->mutex);
0644 
0645     return ret;
0646 }
0647 
0648 static int sx9360_write_raw(struct iio_dev *indio_dev,
0649                 const struct iio_chan_spec *chan, int val, int val2,
0650                 long mask)
0651 {
0652     struct sx_common_data *data = iio_priv(indio_dev);
0653 
0654     switch (mask) {
0655     case IIO_CHAN_INFO_SAMP_FREQ:
0656         return sx9360_set_samp_freq(data, val, val2);
0657     case IIO_CHAN_INFO_HARDWAREGAIN:
0658         return sx9360_write_gain(data, chan, val);
0659     default:
0660         return -EINVAL;
0661     }
0662 }
0663 
0664 static const struct sx_common_reg_default sx9360_default_regs[] = {
0665     { SX9360_REG_IRQ_MSK, 0x00 },
0666     { SX9360_REG_IRQ_CFG, 0x00 },
0667     /*
0668      * The lower 2 bits should not be set as it enable sensors measurements.
0669      * Turning the detection on before the configuration values are set to
0670      * good values can cause the device to return erroneous readings.
0671      */
0672     { SX9360_REG_GNRL_CTRL0, 0x00 },
0673     { SX9360_REG_GNRL_CTRL1, 0x00 },
0674     { SX9360_REG_GNRL_CTRL2, SX9360_REG_GNRL_CTRL2_PERIOD_102MS },
0675 
0676     { SX9360_REG_AFE_CTRL1, SX9360_REG_AFE_CTRL1_RESFILTIN_0OHMS },
0677     { SX9360_REG_AFE_PARAM0_PHR, SX9360_REG_AFE_PARAM0_RSVD |
0678         SX9360_REG_AFE_PARAM0_RESOLUTION_128 },
0679     { SX9360_REG_AFE_PARAM1_PHR, SX9360_REG_AFE_PARAM1_AGAIN_PHM_6PF |
0680         SX9360_REG_AFE_PARAM1_FREQ_83_33HZ },
0681     { SX9360_REG_AFE_PARAM0_PHM, SX9360_REG_AFE_PARAM0_RSVD |
0682         SX9360_REG_AFE_PARAM0_RESOLUTION_128 },
0683     { SX9360_REG_AFE_PARAM1_PHM, SX9360_REG_AFE_PARAM1_AGAIN_PHM_6PF |
0684         SX9360_REG_AFE_PARAM1_FREQ_83_33HZ },
0685 
0686     { SX9360_REG_PROX_CTRL0_PHR, SX9360_REG_PROX_CTRL0_GAIN_1 |
0687         SX9360_REG_PROX_CTRL0_RAWFILT_1P50 },
0688     { SX9360_REG_PROX_CTRL0_PHM, SX9360_REG_PROX_CTRL0_GAIN_1 |
0689         SX9360_REG_PROX_CTRL0_RAWFILT_1P50 },
0690     { SX9360_REG_PROX_CTRL1, SX9360_REG_PROX_CTRL1_AVGNEG_THRESH_16K },
0691     { SX9360_REG_PROX_CTRL2, SX9360_REG_PROX_CTRL2_AVGDEB_2SAMPLES |
0692         SX9360_REG_PROX_CTRL2_AVGPOS_THRESH_16K },
0693     { SX9360_REG_PROX_CTRL3, SX9360_REG_PROX_CTRL3_AVGNEG_FILT_2 |
0694         SX9360_REG_PROX_CTRL3_AVGPOS_FILT_256 },
0695     { SX9360_REG_PROX_CTRL4, 0x00 },
0696     { SX9360_REG_PROX_CTRL5, SX9360_REG_PROX_CTRL5_PROXTHRESH_32 },
0697 };
0698 
0699 /* Activate all channels and perform an initial compensation. */
0700 static int sx9360_init_compensation(struct iio_dev *indio_dev)
0701 {
0702     struct sx_common_data *data = iio_priv(indio_dev);
0703     unsigned int val;
0704     int ret;
0705 
0706     /* run the compensation phase on all channels */
0707     ret = regmap_update_bits(data->regmap, SX9360_REG_STAT,
0708                  SX9360_REG_STAT_COMPSTAT_MASK,
0709                  SX9360_REG_STAT_COMPSTAT_MASK);
0710     if (ret)
0711         return ret;
0712 
0713     return regmap_read_poll_timeout(data->regmap, SX9360_REG_STAT, val,
0714                        !(val & SX9360_REG_STAT_COMPSTAT_MASK),
0715                        20000, 2000000);
0716 }
0717 
0718 static const struct sx_common_reg_default *
0719 sx9360_get_default_reg(struct device *dev, int idx,
0720                struct sx_common_reg_default *reg_def)
0721 {
0722     u32 raw = 0, pos = 0;
0723     int ret;
0724 
0725     memcpy(reg_def, &sx9360_default_regs[idx], sizeof(*reg_def));
0726     switch (reg_def->reg) {
0727     case SX9360_REG_AFE_CTRL1:
0728         ret = device_property_read_u32(dev,
0729                 "semtech,input-precharge-resistor-ohms",
0730                 &raw);
0731         if (ret)
0732             break;
0733 
0734         reg_def->def &= ~SX9360_REG_AFE_CTRL1_RESFILTIN_MASK;
0735         reg_def->def |= FIELD_PREP(SX9360_REG_AFE_CTRL1_RESFILTIN_MASK,
0736                        raw / 2000);
0737         break;
0738     case SX9360_REG_AFE_PARAM0_PHR:
0739     case SX9360_REG_AFE_PARAM0_PHM:
0740         ret = device_property_read_u32(dev, "semtech,resolution", &raw);
0741         if (ret)
0742             break;
0743 
0744         raw = ilog2(raw) - 3;
0745 
0746         reg_def->def &= ~SX9360_REG_AFE_PARAM0_RESOLUTION_MASK;
0747         reg_def->def |= FIELD_PREP(SX9360_REG_AFE_PARAM0_RESOLUTION_MASK, raw);
0748         break;
0749     case SX9360_REG_PROX_CTRL0_PHR:
0750     case SX9360_REG_PROX_CTRL0_PHM:
0751         ret = device_property_read_u32(dev, "semtech,proxraw-strength", &raw);
0752         if (ret)
0753             break;
0754 
0755         reg_def->def &= ~SX9360_REG_PROX_CTRL0_RAWFILT_MASK;
0756         reg_def->def |= FIELD_PREP(SX9360_REG_PROX_CTRL0_RAWFILT_MASK, raw);
0757         break;
0758     case SX9360_REG_PROX_CTRL3:
0759         ret = device_property_read_u32(dev, "semtech,avg-pos-strength",
0760                            &pos);
0761         if (ret)
0762             break;
0763 
0764         /* Powers of 2, except for a gap between 16 and 64 */
0765         raw = clamp(ilog2(pos), 3, 11) - (pos >= 32 ? 4 : 3);
0766         reg_def->def &= ~SX9360_REG_PROX_CTRL3_AVGPOS_FILT_MASK;
0767         reg_def->def |= FIELD_PREP(SX9360_REG_PROX_CTRL3_AVGPOS_FILT_MASK, raw);
0768         break;
0769     }
0770 
0771     return reg_def;
0772 }
0773 
0774 static int sx9360_check_whoami(struct device *dev, struct iio_dev *indio_dev)
0775 {
0776     /*
0777      * Only one sensor for this driver. Assuming the device tree
0778      * is correct, just set the sensor name.
0779      */
0780     indio_dev->name = "sx9360";
0781     return 0;
0782 }
0783 
0784 static const struct sx_common_chip_info sx9360_chip_info = {
0785     .reg_stat = SX9360_REG_STAT,
0786     .reg_irq_msk = SX9360_REG_IRQ_MSK,
0787     .reg_enable_chan = SX9360_REG_GNRL_CTRL0,
0788     .reg_reset = SX9360_REG_RESET,
0789 
0790     .mask_enable_chan = SX9360_REG_GNRL_CTRL0_PHEN_MASK,
0791     .stat_offset = 2,
0792     .num_channels = SX9360_NUM_CHANNELS,
0793     .num_default_regs = ARRAY_SIZE(sx9360_default_regs),
0794 
0795     .ops = {
0796         .read_prox_data = sx9360_read_prox_data,
0797         .check_whoami = sx9360_check_whoami,
0798         .init_compensation = sx9360_init_compensation,
0799         .wait_for_sample = sx9360_wait_for_sample,
0800         .get_default_reg = sx9360_get_default_reg,
0801     },
0802 
0803     .iio_channels = sx9360_channels,
0804     .num_iio_channels = ARRAY_SIZE(sx9360_channels),
0805     .iio_info =  {
0806         .read_raw = sx9360_read_raw,
0807         .read_avail = sx9360_read_avail,
0808         .read_label = sx9360_read_label,
0809         .read_event_value = sx9360_read_event_val,
0810         .write_event_value = sx9360_write_event_val,
0811         .write_raw = sx9360_write_raw,
0812         .read_event_config = sx_common_read_event_config,
0813         .write_event_config = sx_common_write_event_config,
0814     },
0815 };
0816 
0817 static int sx9360_probe(struct i2c_client *client)
0818 {
0819     return sx_common_probe(client, &sx9360_chip_info, &sx9360_regmap_config);
0820 }
0821 
0822 static int __maybe_unused sx9360_suspend(struct device *dev)
0823 {
0824     struct sx_common_data *data = iio_priv(dev_get_drvdata(dev));
0825     unsigned int regval;
0826     int ret;
0827 
0828     disable_irq_nosync(data->client->irq);
0829 
0830     mutex_lock(&data->mutex);
0831     ret = regmap_read(data->regmap, SX9360_REG_GNRL_CTRL0, &regval);
0832 
0833     data->suspend_ctrl =
0834         FIELD_GET(SX9360_REG_GNRL_CTRL0_PHEN_MASK, regval);
0835 
0836     if (ret < 0)
0837         goto out;
0838 
0839     /* Disable all phases, send the device to sleep. */
0840     ret = regmap_write(data->regmap, SX9360_REG_GNRL_CTRL0, 0);
0841 
0842 out:
0843     mutex_unlock(&data->mutex);
0844     return ret;
0845 }
0846 
0847 static int __maybe_unused sx9360_resume(struct device *dev)
0848 {
0849     struct sx_common_data *data = iio_priv(dev_get_drvdata(dev));
0850     int ret;
0851 
0852     mutex_lock(&data->mutex);
0853     ret = regmap_update_bits(data->regmap, SX9360_REG_GNRL_CTRL0,
0854                  SX9360_REG_GNRL_CTRL0_PHEN_MASK,
0855                  data->suspend_ctrl);
0856     mutex_unlock(&data->mutex);
0857     if (ret)
0858         return ret;
0859 
0860     enable_irq(data->client->irq);
0861     return 0;
0862 }
0863 
0864 static SIMPLE_DEV_PM_OPS(sx9360_pm_ops, sx9360_suspend, sx9360_resume);
0865 
0866 static const struct acpi_device_id sx9360_acpi_match[] = {
0867     { "STH9360", SX9360_WHOAMI_VALUE },
0868     { }
0869 };
0870 MODULE_DEVICE_TABLE(acpi, sx9360_acpi_match);
0871 
0872 static const struct of_device_id sx9360_of_match[] = {
0873     { .compatible = "semtech,sx9360", (void *)SX9360_WHOAMI_VALUE },
0874     { }
0875 };
0876 MODULE_DEVICE_TABLE(of, sx9360_of_match);
0877 
0878 static const struct i2c_device_id sx9360_id[] = {
0879     {"sx9360", SX9360_WHOAMI_VALUE },
0880     { }
0881 };
0882 MODULE_DEVICE_TABLE(i2c, sx9360_id);
0883 
0884 static struct i2c_driver sx9360_driver = {
0885     .driver = {
0886         .name   = "sx9360",
0887         .acpi_match_table = sx9360_acpi_match,
0888         .of_match_table = sx9360_of_match,
0889         .pm = &sx9360_pm_ops,
0890 
0891         /*
0892          * Lots of i2c transfers in probe + over 200 ms waiting in
0893          * sx9360_init_compensation() mean a slow probe; prefer async
0894          * so we don't delay boot if we're builtin to the kernel.
0895          */
0896         .probe_type = PROBE_PREFER_ASYNCHRONOUS,
0897     },
0898     .probe_new  = sx9360_probe,
0899     .id_table   = sx9360_id,
0900 };
0901 module_i2c_driver(sx9360_driver);
0902 
0903 MODULE_AUTHOR("Gwendal Grignou <gwendal@chromium.org>");
0904 MODULE_DESCRIPTION("Driver for Semtech SX9360 proximity sensor");
0905 MODULE_LICENSE("GPL v2");
0906 MODULE_IMPORT_NS(SEMTECH_PROX);