0001
0002
0003
0004
0005
0006
0007
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
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
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
0170 #define SX9324_NUM_CHANNELS 4
0171
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),
0235 SX9324_CHANNEL(1),
0236 SX9324_CHANNEL(2),
0237 SX9324_CHANNEL(3),
0238 IIO_CHAN_SOFT_TIMESTAMP(4),
0239 };
0240
0241
0242
0243
0244
0245 static const struct {
0246 int val;
0247 int val2;
0248 } sx9324_samp_freq_table[] = {
0249 { 1000, 0 },
0250 { 500, 0 },
0251 { 250, 0 },
0252 { 166, 666666 },
0253 { 125, 0 },
0254 { 100, 0 },
0255 { 71, 428571 },
0256 { 55, 555556 },
0257 { 45, 454545 },
0258 { 38, 461538 },
0259 { 33, 333333 },
0260 { 29, 411765 },
0261 { 26, 315789 },
0262 { 23, 809524 },
0263 { 21, 739130 },
0264 { 20, 0 },
0265 { 17, 857143 },
0266 { 16, 129032 },
0267 { 14, 705882 },
0268 { 13, 513514 },
0269 { 12, 500000 },
0270 { 11, 111111 },
0271 { 10, 0 },
0272 { 5, 0 },
0273 { 3, 333333 },
0274 { 2, 500000 },
0275 { 1, 666667 },
0276 { 1, 250000 },
0277 { 1, 0 },
0278 { 0, 500000 },
0279 { 0, 333333 },
0280 { 0, 250000 },
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
0291
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
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
0312
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
0370
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, ®val);
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, ®val);
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
0517
0518
0519
0520 reg = SX9324_REG_PROX_CTRL6 + chan->channel / 2;
0521 ret = regmap_read(data->regmap, reg, ®val);
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, ®val);
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, ®val);
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, ®val);
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
0792
0793
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
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
0841 { SX9324_REG_ADV_CTRL10, 0x00 },
0842 { SX9324_REG_ADV_CTRL11, 0x00 },
0843 { SX9324_REG_ADV_CTRL12, 0x00 },
0844
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
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
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
0971
0972
0973
0974
0975
0976
0977
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
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
1033
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, ®val);
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
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
1146
1147
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);