0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/bitfield.h>
0014 #include <linux/delay.h>
0015 #include <linux/i2c.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/kernel.h>
0018 #include <linux/log2.h>
0019 #include <linux/mod_devicetable.h>
0020 #include <linux/module.h>
0021 #include <linux/pm.h>
0022 #include <linux/property.h>
0023 #include <linux/regmap.h>
0024 #include <linux/iio/iio.h>
0025
0026 #include "sx_common.h"
0027
0028
0029 #define SX9310_REG_IRQ_SRC SX_COMMON_REG_IRQ_SRC
0030 #define SX9310_REG_STAT0 0x01
0031 #define SX9310_REG_STAT1 0x02
0032 #define SX9310_REG_STAT1_COMPSTAT_MASK GENMASK(3, 0)
0033 #define SX9310_REG_IRQ_MSK 0x03
0034 #define SX9310_CONVDONE_IRQ BIT(3)
0035 #define SX9310_FAR_IRQ BIT(5)
0036 #define SX9310_CLOSE_IRQ BIT(6)
0037 #define SX9310_REG_IRQ_FUNC 0x04
0038
0039 #define SX9310_REG_PROX_CTRL0 0x10
0040 #define SX9310_REG_PROX_CTRL0_SENSOREN_MASK GENMASK(3, 0)
0041 #define SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK GENMASK(7, 4)
0042 #define SX9310_REG_PROX_CTRL0_SCANPERIOD_15MS 0x01
0043 #define SX9310_REG_PROX_CTRL1 0x11
0044 #define SX9310_REG_PROX_CTRL2 0x12
0045 #define SX9310_REG_PROX_CTRL2_COMBMODE_MASK GENMASK(7, 6)
0046 #define SX9310_REG_PROX_CTRL2_COMBMODE_CS0_CS1_CS2_CS3 (0x03 << 6)
0047 #define SX9310_REG_PROX_CTRL2_COMBMODE_CS1_CS2 (0x02 << 6)
0048 #define SX9310_REG_PROX_CTRL2_COMBMODE_CS0_CS1 (0x01 << 6)
0049 #define SX9310_REG_PROX_CTRL2_COMBMODE_CS3 (0x00 << 6)
0050 #define SX9310_REG_PROX_CTRL2_SHIELDEN_MASK GENMASK(3, 2)
0051 #define SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC (0x01 << 2)
0052 #define SX9310_REG_PROX_CTRL2_SHIELDEN_GROUND (0x02 << 2)
0053 #define SX9310_REG_PROX_CTRL3 0x13
0054 #define SX9310_REG_PROX_CTRL3_GAIN0_MASK GENMASK(3, 2)
0055 #define SX9310_REG_PROX_CTRL3_GAIN0_X8 (0x03 << 2)
0056 #define SX9310_REG_PROX_CTRL3_GAIN12_MASK GENMASK(1, 0)
0057 #define SX9310_REG_PROX_CTRL3_GAIN12_X4 0x02
0058 #define SX9310_REG_PROX_CTRL4 0x14
0059 #define SX9310_REG_PROX_CTRL4_RESOLUTION_MASK GENMASK(2, 0)
0060 #define SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST 0x07
0061 #define SX9310_REG_PROX_CTRL4_RESOLUTION_VERY_FINE 0x06
0062 #define SX9310_REG_PROX_CTRL4_RESOLUTION_FINE 0x05
0063 #define SX9310_REG_PROX_CTRL4_RESOLUTION_MEDIUM 0x04
0064 #define SX9310_REG_PROX_CTRL4_RESOLUTION_MEDIUM_COARSE 0x03
0065 #define SX9310_REG_PROX_CTRL4_RESOLUTION_COARSE 0x02
0066 #define SX9310_REG_PROX_CTRL4_RESOLUTION_VERY_COARSE 0x01
0067 #define SX9310_REG_PROX_CTRL4_RESOLUTION_COARSEST 0x00
0068 #define SX9310_REG_PROX_CTRL5 0x15
0069 #define SX9310_REG_PROX_CTRL5_RANGE_SMALL (0x03 << 6)
0070 #define SX9310_REG_PROX_CTRL5_STARTUPSENS_MASK GENMASK(3, 2)
0071 #define SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 (0x01 << 2)
0072 #define SX9310_REG_PROX_CTRL5_RAWFILT_MASK GENMASK(1, 0)
0073 #define SX9310_REG_PROX_CTRL5_RAWFILT_SHIFT 0
0074 #define SX9310_REG_PROX_CTRL5_RAWFILT_1P25 0x02
0075 #define SX9310_REG_PROX_CTRL6 0x16
0076 #define SX9310_REG_PROX_CTRL6_AVGTHRESH_DEFAULT 0x20
0077 #define SX9310_REG_PROX_CTRL7 0x17
0078 #define SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 (0x01 << 3)
0079 #define SX9310_REG_PROX_CTRL7_AVGPOSFILT_MASK GENMASK(2, 0)
0080 #define SX9310_REG_PROX_CTRL7_AVGPOSFILT_SHIFT 0
0081 #define SX9310_REG_PROX_CTRL7_AVGPOSFILT_512 0x05
0082 #define SX9310_REG_PROX_CTRL8 0x18
0083 #define SX9310_REG_PROX_CTRL8_9_PTHRESH_MASK GENMASK(7, 3)
0084 #define SX9310_REG_PROX_CTRL9 0x19
0085 #define SX9310_REG_PROX_CTRL8_9_PTHRESH_28 (0x08 << 3)
0086 #define SX9310_REG_PROX_CTRL8_9_PTHRESH_96 (0x11 << 3)
0087 #define SX9310_REG_PROX_CTRL8_9_BODYTHRESH_900 0x03
0088 #define SX9310_REG_PROX_CTRL8_9_BODYTHRESH_1500 0x05
0089 #define SX9310_REG_PROX_CTRL10 0x1a
0090 #define SX9310_REG_PROX_CTRL10_HYST_MASK GENMASK(5, 4)
0091 #define SX9310_REG_PROX_CTRL10_HYST_6PCT (0x01 << 4)
0092 #define SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_MASK GENMASK(3, 2)
0093 #define SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_MASK GENMASK(1, 0)
0094 #define SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_2 0x01
0095 #define SX9310_REG_PROX_CTRL11 0x1b
0096 #define SX9310_REG_PROX_CTRL12 0x1c
0097 #define SX9310_REG_PROX_CTRL13 0x1d
0098 #define SX9310_REG_PROX_CTRL14 0x1e
0099 #define SX9310_REG_PROX_CTRL15 0x1f
0100 #define SX9310_REG_PROX_CTRL16 0x20
0101 #define SX9310_REG_PROX_CTRL17 0x21
0102 #define SX9310_REG_PROX_CTRL18 0x22
0103 #define SX9310_REG_PROX_CTRL19 0x23
0104 #define SX9310_REG_SAR_CTRL0 0x2a
0105 #define SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES (0x02 << 5)
0106 #define SX9310_REG_SAR_CTRL0_SARHYST_8 (0x02 << 3)
0107 #define SX9310_REG_SAR_CTRL1 0x2b
0108
0109 #define SX9310_REG_SAR_CTRL1_SLOPE(_hnslope) (_hnslope / 78125)
0110 #define SX9310_REG_SAR_CTRL2 0x2c
0111 #define SX9310_REG_SAR_CTRL2_SAROFFSET_DEFAULT 0x3c
0112
0113 #define SX9310_REG_SENSOR_SEL 0x30
0114 #define SX9310_REG_USE_MSB 0x31
0115 #define SX9310_REG_USE_LSB 0x32
0116 #define SX9310_REG_AVG_MSB 0x33
0117 #define SX9310_REG_AVG_LSB 0x34
0118 #define SX9310_REG_DIFF_MSB 0x35
0119 #define SX9310_REG_DIFF_LSB 0x36
0120 #define SX9310_REG_OFFSET_MSB 0x37
0121 #define SX9310_REG_OFFSET_LSB 0x38
0122 #define SX9310_REG_SAR_MSB 0x39
0123 #define SX9310_REG_SAR_LSB 0x3a
0124 #define SX9310_REG_I2C_ADDR 0x40
0125 #define SX9310_REG_PAUSE 0x41
0126 #define SX9310_REG_WHOAMI 0x42
0127 #define SX9310_WHOAMI_VALUE 0x01
0128 #define SX9311_WHOAMI_VALUE 0x02
0129 #define SX9310_REG_RESET 0x7f
0130
0131
0132
0133 #define SX9310_NUM_CHANNELS 4
0134 static_assert(SX9310_NUM_CHANNELS <= SX_COMMON_MAX_NUM_CHANNELS);
0135
0136 #define SX9310_NAMED_CHANNEL(idx, name) \
0137 { \
0138 .type = IIO_PROXIMITY, \
0139 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
0140 BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
0141 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
0142 .info_mask_separate_available = \
0143 BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
0144 .info_mask_shared_by_all_available = \
0145 BIT(IIO_CHAN_INFO_SAMP_FREQ), \
0146 .indexed = 1, \
0147 .channel = idx, \
0148 .extend_name = name, \
0149 .address = SX9310_REG_DIFF_MSB, \
0150 .event_spec = sx_common_events, \
0151 .num_event_specs = ARRAY_SIZE(sx_common_events), \
0152 .scan_index = idx, \
0153 .scan_type = { \
0154 .sign = 's', \
0155 .realbits = 12, \
0156 .storagebits = 16, \
0157 .endianness = IIO_BE, \
0158 }, \
0159 }
0160 #define SX9310_CHANNEL(idx) SX9310_NAMED_CHANNEL(idx, NULL)
0161
0162 static const struct iio_chan_spec sx9310_channels[] = {
0163 SX9310_CHANNEL(0),
0164 SX9310_CHANNEL(1),
0165 SX9310_CHANNEL(2),
0166 SX9310_NAMED_CHANNEL(3, "comb"),
0167
0168 IIO_CHAN_SOFT_TIMESTAMP(4),
0169 };
0170
0171
0172
0173
0174
0175 static const struct {
0176 int val;
0177 int val2;
0178 } sx9310_samp_freq_table[] = {
0179 { 500, 0 },
0180 { 66, 666666 },
0181 { 33, 333333 },
0182 { 22, 222222 },
0183 { 16, 666666 },
0184 { 11, 111111 },
0185 { 8, 333333 },
0186 { 5, 0 },
0187 { 2, 500000 },
0188 { 1, 666666 },
0189 { 1, 250000 },
0190 { 1, 0 },
0191 { 0, 500000 },
0192 { 0, 333333 },
0193 { 0, 250000 },
0194 { 0, 200000 },
0195 };
0196 static const unsigned int sx9310_scan_period_table[] = {
0197 2, 15, 30, 45, 60, 90, 120, 200,
0198 400, 600, 800, 1000, 2000, 3000, 4000, 5000,
0199 };
0200
0201 static const struct regmap_range sx9310_writable_reg_ranges[] = {
0202 regmap_reg_range(SX9310_REG_IRQ_MSK, SX9310_REG_IRQ_FUNC),
0203 regmap_reg_range(SX9310_REG_PROX_CTRL0, SX9310_REG_PROX_CTRL19),
0204 regmap_reg_range(SX9310_REG_SAR_CTRL0, SX9310_REG_SAR_CTRL2),
0205 regmap_reg_range(SX9310_REG_SENSOR_SEL, SX9310_REG_SENSOR_SEL),
0206 regmap_reg_range(SX9310_REG_OFFSET_MSB, SX9310_REG_OFFSET_LSB),
0207 regmap_reg_range(SX9310_REG_PAUSE, SX9310_REG_PAUSE),
0208 regmap_reg_range(SX9310_REG_RESET, SX9310_REG_RESET),
0209 };
0210
0211 static const struct regmap_access_table sx9310_writeable_regs = {
0212 .yes_ranges = sx9310_writable_reg_ranges,
0213 .n_yes_ranges = ARRAY_SIZE(sx9310_writable_reg_ranges),
0214 };
0215
0216 static const struct regmap_range sx9310_readable_reg_ranges[] = {
0217 regmap_reg_range(SX9310_REG_IRQ_SRC, SX9310_REG_IRQ_FUNC),
0218 regmap_reg_range(SX9310_REG_PROX_CTRL0, SX9310_REG_PROX_CTRL19),
0219 regmap_reg_range(SX9310_REG_SAR_CTRL0, SX9310_REG_SAR_CTRL2),
0220 regmap_reg_range(SX9310_REG_SENSOR_SEL, SX9310_REG_SAR_LSB),
0221 regmap_reg_range(SX9310_REG_I2C_ADDR, SX9310_REG_WHOAMI),
0222 regmap_reg_range(SX9310_REG_RESET, SX9310_REG_RESET),
0223 };
0224
0225 static const struct regmap_access_table sx9310_readable_regs = {
0226 .yes_ranges = sx9310_readable_reg_ranges,
0227 .n_yes_ranges = ARRAY_SIZE(sx9310_readable_reg_ranges),
0228 };
0229
0230 static const struct regmap_range sx9310_volatile_reg_ranges[] = {
0231 regmap_reg_range(SX9310_REG_IRQ_SRC, SX9310_REG_STAT1),
0232 regmap_reg_range(SX9310_REG_USE_MSB, SX9310_REG_DIFF_LSB),
0233 regmap_reg_range(SX9310_REG_SAR_MSB, SX9310_REG_SAR_LSB),
0234 regmap_reg_range(SX9310_REG_RESET, SX9310_REG_RESET),
0235 };
0236
0237 static const struct regmap_access_table sx9310_volatile_regs = {
0238 .yes_ranges = sx9310_volatile_reg_ranges,
0239 .n_yes_ranges = ARRAY_SIZE(sx9310_volatile_reg_ranges),
0240 };
0241
0242 static const struct regmap_config sx9310_regmap_config = {
0243 .reg_bits = 8,
0244 .val_bits = 8,
0245
0246 .max_register = SX9310_REG_RESET,
0247 .cache_type = REGCACHE_RBTREE,
0248
0249 .wr_table = &sx9310_writeable_regs,
0250 .rd_table = &sx9310_readable_regs,
0251 .volatile_table = &sx9310_volatile_regs,
0252 };
0253
0254 static int sx9310_read_prox_data(struct sx_common_data *data,
0255 const struct iio_chan_spec *chan, __be16 *val)
0256 {
0257 int ret;
0258
0259 ret = regmap_write(data->regmap, SX9310_REG_SENSOR_SEL, chan->channel);
0260 if (ret)
0261 return ret;
0262
0263 return regmap_bulk_read(data->regmap, chan->address, val, sizeof(*val));
0264 }
0265
0266
0267
0268
0269
0270 static int sx9310_wait_for_sample(struct sx_common_data *data)
0271 {
0272 int ret;
0273 unsigned int val;
0274
0275 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, &val);
0276 if (ret)
0277 return ret;
0278
0279 val = FIELD_GET(SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, val);
0280
0281 msleep(sx9310_scan_period_table[val]);
0282
0283 return 0;
0284 }
0285
0286 static int sx9310_read_gain(struct sx_common_data *data,
0287 const struct iio_chan_spec *chan, int *val)
0288 {
0289 unsigned int regval, gain;
0290 int ret;
0291
0292 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL3, ®val);
0293 if (ret)
0294 return ret;
0295
0296 switch (chan->channel) {
0297 case 0:
0298 case 3:
0299 gain = FIELD_GET(SX9310_REG_PROX_CTRL3_GAIN0_MASK, regval);
0300 break;
0301 case 1:
0302 case 2:
0303 gain = FIELD_GET(SX9310_REG_PROX_CTRL3_GAIN12_MASK, regval);
0304 break;
0305 default:
0306 return -EINVAL;
0307 }
0308
0309 *val = 1 << gain;
0310
0311 return IIO_VAL_INT;
0312 }
0313
0314 static int sx9310_read_samp_freq(struct sx_common_data *data, int *val, int *val2)
0315 {
0316 unsigned int regval;
0317 int ret;
0318
0319 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, ®val);
0320 if (ret)
0321 return ret;
0322
0323 regval = FIELD_GET(SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, regval);
0324 *val = sx9310_samp_freq_table[regval].val;
0325 *val2 = sx9310_samp_freq_table[regval].val2;
0326
0327 return IIO_VAL_INT_PLUS_MICRO;
0328 }
0329
0330 static int sx9310_read_raw(struct iio_dev *indio_dev,
0331 const struct iio_chan_spec *chan, int *val,
0332 int *val2, long mask)
0333 {
0334 struct sx_common_data *data = iio_priv(indio_dev);
0335 int ret;
0336
0337 if (chan->type != IIO_PROXIMITY)
0338 return -EINVAL;
0339
0340 switch (mask) {
0341 case IIO_CHAN_INFO_RAW:
0342 ret = iio_device_claim_direct_mode(indio_dev);
0343 if (ret)
0344 return ret;
0345
0346 ret = sx_common_read_proximity(data, chan, val);
0347 iio_device_release_direct_mode(indio_dev);
0348 return ret;
0349 case IIO_CHAN_INFO_HARDWAREGAIN:
0350 ret = iio_device_claim_direct_mode(indio_dev);
0351 if (ret)
0352 return ret;
0353
0354 ret = sx9310_read_gain(data, chan, val);
0355 iio_device_release_direct_mode(indio_dev);
0356 return ret;
0357 case IIO_CHAN_INFO_SAMP_FREQ:
0358 return sx9310_read_samp_freq(data, val, val2);
0359 default:
0360 return -EINVAL;
0361 }
0362 }
0363
0364 static const int sx9310_gain_vals[] = { 1, 2, 4, 8 };
0365
0366 static int sx9310_read_avail(struct iio_dev *indio_dev,
0367 struct iio_chan_spec const *chan,
0368 const int **vals, int *type, int *length,
0369 long mask)
0370 {
0371 if (chan->type != IIO_PROXIMITY)
0372 return -EINVAL;
0373
0374 switch (mask) {
0375 case IIO_CHAN_INFO_HARDWAREGAIN:
0376 *type = IIO_VAL_INT;
0377 *length = ARRAY_SIZE(sx9310_gain_vals);
0378 *vals = sx9310_gain_vals;
0379 return IIO_AVAIL_LIST;
0380 case IIO_CHAN_INFO_SAMP_FREQ:
0381 *type = IIO_VAL_INT_PLUS_MICRO;
0382 *length = ARRAY_SIZE(sx9310_samp_freq_table) * 2;
0383 *vals = (int *)sx9310_samp_freq_table;
0384 return IIO_AVAIL_LIST;
0385 default:
0386 return -EINVAL;
0387 }
0388 }
0389
0390 static const unsigned int sx9310_pthresh_codes[] = {
0391 2, 4, 6, 8, 12, 16, 20, 24, 28, 32, 40, 48, 56, 64, 72, 80, 88, 96, 112,
0392 128, 144, 160, 192, 224, 256, 320, 384, 512, 640, 768, 1024, 1536
0393 };
0394
0395 static int sx9310_get_thresh_reg(unsigned int channel)
0396 {
0397 switch (channel) {
0398 case 0:
0399 case 3:
0400 return SX9310_REG_PROX_CTRL8;
0401 case 1:
0402 case 2:
0403 return SX9310_REG_PROX_CTRL9;
0404 default:
0405 return -EINVAL;
0406 }
0407 }
0408
0409 static int sx9310_read_thresh(struct sx_common_data *data,
0410 const struct iio_chan_spec *chan, int *val)
0411 {
0412 unsigned int reg;
0413 unsigned int regval;
0414 int ret;
0415
0416 reg = ret = sx9310_get_thresh_reg(chan->channel);
0417 if (ret < 0)
0418 return ret;
0419
0420 ret = regmap_read(data->regmap, reg, ®val);
0421 if (ret)
0422 return ret;
0423
0424 regval = FIELD_GET(SX9310_REG_PROX_CTRL8_9_PTHRESH_MASK, regval);
0425 if (regval >= ARRAY_SIZE(sx9310_pthresh_codes))
0426 return -EINVAL;
0427
0428 *val = sx9310_pthresh_codes[regval];
0429 return IIO_VAL_INT;
0430 }
0431
0432 static int sx9310_read_hysteresis(struct sx_common_data *data,
0433 const struct iio_chan_spec *chan, int *val)
0434 {
0435 unsigned int regval, pthresh;
0436 int ret;
0437
0438 ret = sx9310_read_thresh(data, chan, &pthresh);
0439 if (ret < 0)
0440 return ret;
0441
0442 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL10, ®val);
0443 if (ret)
0444 return ret;
0445
0446 regval = FIELD_GET(SX9310_REG_PROX_CTRL10_HYST_MASK, regval);
0447 if (!regval)
0448 regval = 5;
0449
0450
0451 *val = pthresh >> (5 - regval);
0452
0453 return IIO_VAL_INT;
0454 }
0455
0456 static int sx9310_read_far_debounce(struct sx_common_data *data, int *val)
0457 {
0458 unsigned int regval;
0459 int ret;
0460
0461 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL10, ®val);
0462 if (ret)
0463 return ret;
0464
0465 regval = FIELD_GET(SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_MASK, regval);
0466 if (regval)
0467 *val = 1 << regval;
0468 else
0469 *val = 0;
0470
0471 return IIO_VAL_INT;
0472 }
0473
0474 static int sx9310_read_close_debounce(struct sx_common_data *data, int *val)
0475 {
0476 unsigned int regval;
0477 int ret;
0478
0479 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL10, ®val);
0480 if (ret)
0481 return ret;
0482
0483 regval = FIELD_GET(SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_MASK, regval);
0484 if (regval)
0485 *val = 1 << regval;
0486 else
0487 *val = 0;
0488
0489 return IIO_VAL_INT;
0490 }
0491
0492 static int sx9310_read_event_val(struct iio_dev *indio_dev,
0493 const struct iio_chan_spec *chan,
0494 enum iio_event_type type,
0495 enum iio_event_direction dir,
0496 enum iio_event_info info, int *val, int *val2)
0497 {
0498 struct sx_common_data *data = iio_priv(indio_dev);
0499
0500 if (chan->type != IIO_PROXIMITY)
0501 return -EINVAL;
0502
0503 switch (info) {
0504 case IIO_EV_INFO_VALUE:
0505 return sx9310_read_thresh(data, chan, val);
0506 case IIO_EV_INFO_PERIOD:
0507 switch (dir) {
0508 case IIO_EV_DIR_RISING:
0509 return sx9310_read_far_debounce(data, val);
0510 case IIO_EV_DIR_FALLING:
0511 return sx9310_read_close_debounce(data, val);
0512 default:
0513 return -EINVAL;
0514 }
0515 case IIO_EV_INFO_HYSTERESIS:
0516 return sx9310_read_hysteresis(data, chan, val);
0517 default:
0518 return -EINVAL;
0519 }
0520 }
0521
0522 static int sx9310_write_thresh(struct sx_common_data *data,
0523 const struct iio_chan_spec *chan, int val)
0524 {
0525 unsigned int reg;
0526 unsigned int regval;
0527 int ret, i;
0528
0529 reg = ret = sx9310_get_thresh_reg(chan->channel);
0530 if (ret < 0)
0531 return ret;
0532
0533 for (i = 0; i < ARRAY_SIZE(sx9310_pthresh_codes); i++) {
0534 if (sx9310_pthresh_codes[i] == val) {
0535 regval = i;
0536 break;
0537 }
0538 }
0539
0540 if (i == ARRAY_SIZE(sx9310_pthresh_codes))
0541 return -EINVAL;
0542
0543 regval = FIELD_PREP(SX9310_REG_PROX_CTRL8_9_PTHRESH_MASK, regval);
0544 mutex_lock(&data->mutex);
0545 ret = regmap_update_bits(data->regmap, reg,
0546 SX9310_REG_PROX_CTRL8_9_PTHRESH_MASK, regval);
0547 mutex_unlock(&data->mutex);
0548
0549 return ret;
0550 }
0551
0552 static int sx9310_write_hysteresis(struct sx_common_data *data,
0553 const struct iio_chan_spec *chan, int _val)
0554 {
0555 unsigned int hyst, val = _val;
0556 int ret, pthresh;
0557
0558 ret = sx9310_read_thresh(data, chan, &pthresh);
0559 if (ret < 0)
0560 return ret;
0561
0562 if (val == 0)
0563 hyst = 0;
0564 else if (val == pthresh >> 2)
0565 hyst = 3;
0566 else if (val == pthresh >> 3)
0567 hyst = 2;
0568 else if (val == pthresh >> 4)
0569 hyst = 1;
0570 else
0571 return -EINVAL;
0572
0573 hyst = FIELD_PREP(SX9310_REG_PROX_CTRL10_HYST_MASK, hyst);
0574 mutex_lock(&data->mutex);
0575 ret = regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL10,
0576 SX9310_REG_PROX_CTRL10_HYST_MASK, hyst);
0577 mutex_unlock(&data->mutex);
0578
0579 return ret;
0580 }
0581
0582 static int sx9310_write_far_debounce(struct sx_common_data *data, int val)
0583 {
0584 int ret;
0585 unsigned int regval;
0586
0587 if (val > 0)
0588 val = ilog2(val);
0589 if (!FIELD_FIT(SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_MASK, val))
0590 return -EINVAL;
0591
0592 regval = FIELD_PREP(SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_MASK, val);
0593
0594 mutex_lock(&data->mutex);
0595 ret = regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL10,
0596 SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_MASK,
0597 regval);
0598 mutex_unlock(&data->mutex);
0599
0600 return ret;
0601 }
0602
0603 static int sx9310_write_close_debounce(struct sx_common_data *data, int val)
0604 {
0605 int ret;
0606 unsigned int regval;
0607
0608 if (val > 0)
0609 val = ilog2(val);
0610 if (!FIELD_FIT(SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_MASK, val))
0611 return -EINVAL;
0612
0613 regval = FIELD_PREP(SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_MASK, val);
0614
0615 mutex_lock(&data->mutex);
0616 ret = regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL10,
0617 SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_MASK,
0618 regval);
0619 mutex_unlock(&data->mutex);
0620
0621 return ret;
0622 }
0623
0624 static int sx9310_write_event_val(struct iio_dev *indio_dev,
0625 const struct iio_chan_spec *chan,
0626 enum iio_event_type type,
0627 enum iio_event_direction dir,
0628 enum iio_event_info info, int val, int val2)
0629 {
0630 struct sx_common_data *data = iio_priv(indio_dev);
0631
0632 if (chan->type != IIO_PROXIMITY)
0633 return -EINVAL;
0634
0635 switch (info) {
0636 case IIO_EV_INFO_VALUE:
0637 return sx9310_write_thresh(data, chan, val);
0638 case IIO_EV_INFO_PERIOD:
0639 switch (dir) {
0640 case IIO_EV_DIR_RISING:
0641 return sx9310_write_far_debounce(data, val);
0642 case IIO_EV_DIR_FALLING:
0643 return sx9310_write_close_debounce(data, val);
0644 default:
0645 return -EINVAL;
0646 }
0647 case IIO_EV_INFO_HYSTERESIS:
0648 return sx9310_write_hysteresis(data, chan, val);
0649 default:
0650 return -EINVAL;
0651 }
0652 }
0653
0654 static int sx9310_set_samp_freq(struct sx_common_data *data, int val, int val2)
0655 {
0656 int i, ret;
0657
0658 for (i = 0; i < ARRAY_SIZE(sx9310_samp_freq_table); i++)
0659 if (val == sx9310_samp_freq_table[i].val &&
0660 val2 == sx9310_samp_freq_table[i].val2)
0661 break;
0662
0663 if (i == ARRAY_SIZE(sx9310_samp_freq_table))
0664 return -EINVAL;
0665
0666 mutex_lock(&data->mutex);
0667
0668 ret = regmap_update_bits(
0669 data->regmap, SX9310_REG_PROX_CTRL0,
0670 SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK,
0671 FIELD_PREP(SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, i));
0672
0673 mutex_unlock(&data->mutex);
0674
0675 return ret;
0676 }
0677
0678 static int sx9310_write_gain(struct sx_common_data *data,
0679 const struct iio_chan_spec *chan, int val)
0680 {
0681 unsigned int gain, mask;
0682 int ret;
0683
0684 gain = ilog2(val);
0685
0686 switch (chan->channel) {
0687 case 0:
0688 case 3:
0689 mask = SX9310_REG_PROX_CTRL3_GAIN0_MASK;
0690 gain = FIELD_PREP(SX9310_REG_PROX_CTRL3_GAIN0_MASK, gain);
0691 break;
0692 case 1:
0693 case 2:
0694 mask = SX9310_REG_PROX_CTRL3_GAIN12_MASK;
0695 gain = FIELD_PREP(SX9310_REG_PROX_CTRL3_GAIN12_MASK, gain);
0696 break;
0697 default:
0698 return -EINVAL;
0699 }
0700
0701 mutex_lock(&data->mutex);
0702 ret = regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL3, mask,
0703 gain);
0704 mutex_unlock(&data->mutex);
0705
0706 return ret;
0707 }
0708
0709 static int sx9310_write_raw(struct iio_dev *indio_dev,
0710 const struct iio_chan_spec *chan, int val, int val2,
0711 long mask)
0712 {
0713 struct sx_common_data *data = iio_priv(indio_dev);
0714
0715 if (chan->type != IIO_PROXIMITY)
0716 return -EINVAL;
0717
0718 switch (mask) {
0719 case IIO_CHAN_INFO_SAMP_FREQ:
0720 return sx9310_set_samp_freq(data, val, val2);
0721 case IIO_CHAN_INFO_HARDWAREGAIN:
0722 return sx9310_write_gain(data, chan, val);
0723 default:
0724 return -EINVAL;
0725 }
0726 }
0727
0728 static const struct sx_common_reg_default sx9310_default_regs[] = {
0729 { SX9310_REG_IRQ_MSK, 0x00 },
0730 { SX9310_REG_IRQ_FUNC, 0x00 },
0731
0732
0733
0734
0735
0736 { SX9310_REG_PROX_CTRL0, SX9310_REG_PROX_CTRL0_SCANPERIOD_15MS },
0737 { SX9310_REG_PROX_CTRL1, 0x00 },
0738 { SX9310_REG_PROX_CTRL2, SX9310_REG_PROX_CTRL2_COMBMODE_CS1_CS2 |
0739 SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC },
0740 { SX9310_REG_PROX_CTRL3, SX9310_REG_PROX_CTRL3_GAIN0_X8 |
0741 SX9310_REG_PROX_CTRL3_GAIN12_X4 },
0742 { SX9310_REG_PROX_CTRL4, SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST },
0743 { SX9310_REG_PROX_CTRL5, SX9310_REG_PROX_CTRL5_RANGE_SMALL |
0744 SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 |
0745 SX9310_REG_PROX_CTRL5_RAWFILT_1P25 },
0746 { SX9310_REG_PROX_CTRL6, SX9310_REG_PROX_CTRL6_AVGTHRESH_DEFAULT },
0747 { SX9310_REG_PROX_CTRL7, SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 |
0748 SX9310_REG_PROX_CTRL7_AVGPOSFILT_512 },
0749 { SX9310_REG_PROX_CTRL8, SX9310_REG_PROX_CTRL8_9_PTHRESH_96 |
0750 SX9310_REG_PROX_CTRL8_9_BODYTHRESH_1500 },
0751 { SX9310_REG_PROX_CTRL9, SX9310_REG_PROX_CTRL8_9_PTHRESH_28 |
0752 SX9310_REG_PROX_CTRL8_9_BODYTHRESH_900 },
0753 { SX9310_REG_PROX_CTRL10, SX9310_REG_PROX_CTRL10_HYST_6PCT |
0754 SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_2 },
0755 { SX9310_REG_PROX_CTRL11, 0x00 },
0756 { SX9310_REG_PROX_CTRL12, 0x00 },
0757 { SX9310_REG_PROX_CTRL13, 0x00 },
0758 { SX9310_REG_PROX_CTRL14, 0x00 },
0759 { SX9310_REG_PROX_CTRL15, 0x00 },
0760 { SX9310_REG_PROX_CTRL16, 0x00 },
0761 { SX9310_REG_PROX_CTRL17, 0x00 },
0762 { SX9310_REG_PROX_CTRL18, 0x00 },
0763 { SX9310_REG_PROX_CTRL19, 0x00 },
0764 { SX9310_REG_SAR_CTRL0, SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES |
0765 SX9310_REG_SAR_CTRL0_SARHYST_8 },
0766 { SX9310_REG_SAR_CTRL1, SX9310_REG_SAR_CTRL1_SLOPE(10781250) },
0767 { SX9310_REG_SAR_CTRL2, SX9310_REG_SAR_CTRL2_SAROFFSET_DEFAULT },
0768 };
0769
0770
0771 static int sx9310_init_compensation(struct iio_dev *indio_dev)
0772 {
0773 struct sx_common_data *data = iio_priv(indio_dev);
0774 int ret;
0775 unsigned int val;
0776 unsigned int ctrl0;
0777
0778 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, &ctrl0);
0779 if (ret)
0780 return ret;
0781
0782
0783 ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0,
0784 ctrl0 | SX9310_REG_PROX_CTRL0_SENSOREN_MASK);
0785 if (ret)
0786 return ret;
0787
0788 ret = regmap_read_poll_timeout(data->regmap, SX9310_REG_STAT1, val,
0789 !(val & SX9310_REG_STAT1_COMPSTAT_MASK),
0790 20000, 2000000);
0791 if (ret)
0792 return ret;
0793
0794 regmap_write(data->regmap, SX9310_REG_PROX_CTRL0, ctrl0);
0795 return ret;
0796 }
0797
0798 static const struct sx_common_reg_default *
0799 sx9310_get_default_reg(struct device *dev, int idx,
0800 struct sx_common_reg_default *reg_def)
0801 {
0802 u32 combined[SX9310_NUM_CHANNELS];
0803 u32 start = 0, raw = 0, pos = 0;
0804 unsigned long comb_mask = 0;
0805 int ret, i, count;
0806 const char *res;
0807
0808 memcpy(reg_def, &sx9310_default_regs[idx], sizeof(*reg_def));
0809 switch (reg_def->reg) {
0810 case SX9310_REG_PROX_CTRL2:
0811 if (device_property_read_bool(dev, "semtech,cs0-ground")) {
0812 reg_def->def &= ~SX9310_REG_PROX_CTRL2_SHIELDEN_MASK;
0813 reg_def->def |= SX9310_REG_PROX_CTRL2_SHIELDEN_GROUND;
0814 }
0815
0816 count = device_property_count_u32(dev, "semtech,combined-sensors");
0817 if (count < 0 || count > ARRAY_SIZE(combined))
0818 break;
0819 ret = device_property_read_u32_array(dev, "semtech,combined-sensors",
0820 combined, count);
0821 if (ret)
0822 break;
0823
0824 for (i = 0; i < count; i++)
0825 comb_mask |= BIT(combined[i]);
0826
0827 reg_def->def &= ~SX9310_REG_PROX_CTRL2_COMBMODE_MASK;
0828 if (comb_mask == (BIT(3) | BIT(2) | BIT(1) | BIT(0)))
0829 reg_def->def |= SX9310_REG_PROX_CTRL2_COMBMODE_CS0_CS1_CS2_CS3;
0830 else if (comb_mask == (BIT(1) | BIT(2)))
0831 reg_def->def |= SX9310_REG_PROX_CTRL2_COMBMODE_CS1_CS2;
0832 else if (comb_mask == (BIT(0) | BIT(1)))
0833 reg_def->def |= SX9310_REG_PROX_CTRL2_COMBMODE_CS0_CS1;
0834 else if (comb_mask == BIT(3))
0835 reg_def->def |= SX9310_REG_PROX_CTRL2_COMBMODE_CS3;
0836
0837 break;
0838 case SX9310_REG_PROX_CTRL4:
0839 ret = device_property_read_string(dev, "semtech,resolution", &res);
0840 if (ret)
0841 break;
0842
0843 reg_def->def &= ~SX9310_REG_PROX_CTRL4_RESOLUTION_MASK;
0844 if (!strcmp(res, "coarsest"))
0845 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_COARSEST;
0846 else if (!strcmp(res, "very-coarse"))
0847 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_VERY_COARSE;
0848 else if (!strcmp(res, "coarse"))
0849 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_COARSE;
0850 else if (!strcmp(res, "medium-coarse"))
0851 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_MEDIUM_COARSE;
0852 else if (!strcmp(res, "medium"))
0853 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_MEDIUM;
0854 else if (!strcmp(res, "fine"))
0855 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_FINE;
0856 else if (!strcmp(res, "very-fine"))
0857 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_VERY_FINE;
0858 else if (!strcmp(res, "finest"))
0859 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST;
0860
0861 break;
0862 case SX9310_REG_PROX_CTRL5:
0863 ret = device_property_read_u32(dev, "semtech,startup-sensor", &start);
0864 if (ret) {
0865 start = FIELD_GET(SX9310_REG_PROX_CTRL5_STARTUPSENS_MASK,
0866 reg_def->def);
0867 }
0868
0869 reg_def->def &= ~SX9310_REG_PROX_CTRL5_STARTUPSENS_MASK;
0870 reg_def->def |= FIELD_PREP(SX9310_REG_PROX_CTRL5_STARTUPSENS_MASK,
0871 start);
0872
0873 ret = device_property_read_u32(dev, "semtech,proxraw-strength", &raw);
0874 if (ret) {
0875 raw = FIELD_GET(SX9310_REG_PROX_CTRL5_RAWFILT_MASK,
0876 reg_def->def);
0877 } else {
0878 raw = ilog2(raw);
0879 }
0880
0881 reg_def->def &= ~SX9310_REG_PROX_CTRL5_RAWFILT_MASK;
0882 reg_def->def |= FIELD_PREP(SX9310_REG_PROX_CTRL5_RAWFILT_MASK,
0883 raw);
0884 break;
0885 case SX9310_REG_PROX_CTRL7:
0886 ret = device_property_read_u32(dev, "semtech,avg-pos-strength", &pos);
0887 if (ret)
0888 break;
0889
0890
0891 pos = clamp(ilog2(pos), 3, 11) - (pos >= 32 ? 4 : 3);
0892 reg_def->def &= ~SX9310_REG_PROX_CTRL7_AVGPOSFILT_MASK;
0893 reg_def->def |= FIELD_PREP(SX9310_REG_PROX_CTRL7_AVGPOSFILT_MASK,
0894 pos);
0895 break;
0896 }
0897
0898 return reg_def;
0899 }
0900
0901 static int sx9310_check_whoami(struct device *dev,
0902 struct iio_dev *indio_dev)
0903 {
0904 struct sx_common_data *data = iio_priv(indio_dev);
0905 unsigned int long ddata;
0906 unsigned int whoami;
0907 int ret;
0908
0909 ret = regmap_read(data->regmap, SX9310_REG_WHOAMI, &whoami);
0910 if (ret)
0911 return ret;
0912
0913 ddata = (uintptr_t)device_get_match_data(dev);
0914 if (ddata != whoami)
0915 return -EINVAL;
0916
0917 switch (whoami) {
0918 case SX9310_WHOAMI_VALUE:
0919 indio_dev->name = "sx9310";
0920 break;
0921 case SX9311_WHOAMI_VALUE:
0922 indio_dev->name = "sx9311";
0923 break;
0924 default:
0925 return -ENODEV;
0926 }
0927
0928 return 0;
0929 }
0930
0931 static const struct sx_common_chip_info sx9310_chip_info = {
0932 .reg_stat = SX9310_REG_STAT0,
0933 .reg_irq_msk = SX9310_REG_IRQ_MSK,
0934 .reg_enable_chan = SX9310_REG_PROX_CTRL0,
0935 .reg_reset = SX9310_REG_RESET,
0936
0937 .mask_enable_chan = SX9310_REG_STAT1_COMPSTAT_MASK,
0938 .irq_msk_offset = 3,
0939 .num_channels = SX9310_NUM_CHANNELS,
0940 .num_default_regs = ARRAY_SIZE(sx9310_default_regs),
0941
0942 .ops = {
0943 .read_prox_data = sx9310_read_prox_data,
0944 .check_whoami = sx9310_check_whoami,
0945 .init_compensation = sx9310_init_compensation,
0946 .wait_for_sample = sx9310_wait_for_sample,
0947 .get_default_reg = sx9310_get_default_reg,
0948 },
0949
0950 .iio_channels = sx9310_channels,
0951 .num_iio_channels = ARRAY_SIZE(sx9310_channels),
0952 .iio_info = {
0953 .read_raw = sx9310_read_raw,
0954 .read_avail = sx9310_read_avail,
0955 .read_event_value = sx9310_read_event_val,
0956 .write_event_value = sx9310_write_event_val,
0957 .write_raw = sx9310_write_raw,
0958 .read_event_config = sx_common_read_event_config,
0959 .write_event_config = sx_common_write_event_config,
0960 },
0961 };
0962
0963 static int sx9310_probe(struct i2c_client *client)
0964 {
0965 return sx_common_probe(client, &sx9310_chip_info, &sx9310_regmap_config);
0966 }
0967
0968 static int __maybe_unused sx9310_suspend(struct device *dev)
0969 {
0970 struct sx_common_data *data = iio_priv(dev_get_drvdata(dev));
0971 u8 ctrl0;
0972 int ret;
0973
0974 disable_irq_nosync(data->client->irq);
0975
0976 mutex_lock(&data->mutex);
0977 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0,
0978 &data->suspend_ctrl);
0979 if (ret)
0980 goto out;
0981
0982 ctrl0 = data->suspend_ctrl & ~SX9310_REG_PROX_CTRL0_SENSOREN_MASK;
0983 ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0, ctrl0);
0984 if (ret)
0985 goto out;
0986
0987 ret = regmap_write(data->regmap, SX9310_REG_PAUSE, 0);
0988
0989 out:
0990 mutex_unlock(&data->mutex);
0991 return ret;
0992 }
0993
0994 static int __maybe_unused sx9310_resume(struct device *dev)
0995 {
0996 struct sx_common_data *data = iio_priv(dev_get_drvdata(dev));
0997 int ret;
0998
0999 mutex_lock(&data->mutex);
1000 ret = regmap_write(data->regmap, SX9310_REG_PAUSE, 1);
1001 if (ret)
1002 goto out;
1003
1004 ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0,
1005 data->suspend_ctrl);
1006
1007 out:
1008 mutex_unlock(&data->mutex);
1009 if (ret)
1010 return ret;
1011
1012 enable_irq(data->client->irq);
1013 return 0;
1014 }
1015
1016 static SIMPLE_DEV_PM_OPS(sx9310_pm_ops, sx9310_suspend, sx9310_resume);
1017
1018 static const struct acpi_device_id sx9310_acpi_match[] = {
1019 { "STH9310", SX9310_WHOAMI_VALUE },
1020 { "STH9311", SX9311_WHOAMI_VALUE },
1021 {}
1022 };
1023 MODULE_DEVICE_TABLE(acpi, sx9310_acpi_match);
1024
1025 static const struct of_device_id sx9310_of_match[] = {
1026 { .compatible = "semtech,sx9310", (void *)SX9310_WHOAMI_VALUE },
1027 { .compatible = "semtech,sx9311", (void *)SX9311_WHOAMI_VALUE },
1028 {}
1029 };
1030 MODULE_DEVICE_TABLE(of, sx9310_of_match);
1031
1032 static const struct i2c_device_id sx9310_id[] = {
1033 { "sx9310", SX9310_WHOAMI_VALUE },
1034 { "sx9311", SX9311_WHOAMI_VALUE },
1035 {}
1036 };
1037 MODULE_DEVICE_TABLE(i2c, sx9310_id);
1038
1039 static struct i2c_driver sx9310_driver = {
1040 .driver = {
1041 .name = "sx9310",
1042 .acpi_match_table = sx9310_acpi_match,
1043 .of_match_table = sx9310_of_match,
1044 .pm = &sx9310_pm_ops,
1045
1046
1047
1048
1049
1050
1051 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
1052 },
1053 .probe_new = sx9310_probe,
1054 .id_table = sx9310_id,
1055 };
1056 module_i2c_driver(sx9310_driver);
1057
1058 MODULE_AUTHOR("Gwendal Grignou <gwendal@chromium.org>");
1059 MODULE_AUTHOR("Daniel Campello <campello@chromium.org>");
1060 MODULE_DESCRIPTION("Driver for Semtech SX9310/SX9311 proximity sensor");
1061 MODULE_LICENSE("GPL v2");
1062 MODULE_IMPORT_NS(SEMTECH_PROX);