1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright 2018 Google LLC.
4 *
5 * Driver for Semtech's SX9310/SX9311 capacitive proximity/button solution.
6 * Based on SX9500 driver and Semtech driver using the input framework
7 * <https://my.syncplicity.com/share/teouwsim8niiaud/
8 * linux-driver-SX9310_NoSmartHSensing>.
9 * Reworked in April 2019 by Evan Green <evgreen@chromium.org>
10 * and in January 2020 by Daniel Campello <campello@chromium.org>.
11 */
12
13 #include <linux/bitfield.h>
14 #include <linux/delay.h>
15 #include <linux/i2c.h>
16 #include <linux/interrupt.h>
17 #include <linux/kernel.h>
18 #include <linux/log2.h>
19 #include <linux/mod_devicetable.h>
20 #include <linux/module.h>
21 #include <linux/pm.h>
22 #include <linux/property.h>
23 #include <linux/regmap.h>
24 #include <linux/iio/iio.h>
25
26 #include "sx_common.h"
27
28 /* Register definitions. */
29 #define SX9310_REG_IRQ_SRC SX_COMMON_REG_IRQ_SRC
30 #define SX9310_REG_STAT0 0x01
31 #define SX9310_REG_STAT1 0x02
32 #define SX9310_REG_STAT1_COMPSTAT_MASK GENMASK(3, 0)
33 #define SX9310_REG_IRQ_MSK 0x03
34 #define SX9310_CONVDONE_IRQ BIT(3)
35 #define SX9310_FAR_IRQ BIT(5)
36 #define SX9310_CLOSE_IRQ BIT(6)
37 #define SX9310_REG_IRQ_FUNC 0x04
38
39 #define SX9310_REG_PROX_CTRL0 0x10
40 #define SX9310_REG_PROX_CTRL0_SENSOREN_MASK GENMASK(3, 0)
41 #define SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK GENMASK(7, 4)
42 #define SX9310_REG_PROX_CTRL0_SCANPERIOD_15MS 0x01
43 #define SX9310_REG_PROX_CTRL1 0x11
44 #define SX9310_REG_PROX_CTRL2 0x12
45 #define SX9310_REG_PROX_CTRL2_COMBMODE_MASK GENMASK(7, 6)
46 #define SX9310_REG_PROX_CTRL2_COMBMODE_CS0_CS1_CS2_CS3 (0x03 << 6)
47 #define SX9310_REG_PROX_CTRL2_COMBMODE_CS1_CS2 (0x02 << 6)
48 #define SX9310_REG_PROX_CTRL2_COMBMODE_CS0_CS1 (0x01 << 6)
49 #define SX9310_REG_PROX_CTRL2_COMBMODE_CS3 (0x00 << 6)
50 #define SX9310_REG_PROX_CTRL2_SHIELDEN_MASK GENMASK(3, 2)
51 #define SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC (0x01 << 2)
52 #define SX9310_REG_PROX_CTRL2_SHIELDEN_GROUND (0x02 << 2)
53 #define SX9310_REG_PROX_CTRL3 0x13
54 #define SX9310_REG_PROX_CTRL3_GAIN0_MASK GENMASK(3, 2)
55 #define SX9310_REG_PROX_CTRL3_GAIN0_X8 (0x03 << 2)
56 #define SX9310_REG_PROX_CTRL3_GAIN12_MASK GENMASK(1, 0)
57 #define SX9310_REG_PROX_CTRL3_GAIN12_X4 0x02
58 #define SX9310_REG_PROX_CTRL4 0x14
59 #define SX9310_REG_PROX_CTRL4_RESOLUTION_MASK GENMASK(2, 0)
60 #define SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST 0x07
61 #define SX9310_REG_PROX_CTRL4_RESOLUTION_VERY_FINE 0x06
62 #define SX9310_REG_PROX_CTRL4_RESOLUTION_FINE 0x05
63 #define SX9310_REG_PROX_CTRL4_RESOLUTION_MEDIUM 0x04
64 #define SX9310_REG_PROX_CTRL4_RESOLUTION_MEDIUM_COARSE 0x03
65 #define SX9310_REG_PROX_CTRL4_RESOLUTION_COARSE 0x02
66 #define SX9310_REG_PROX_CTRL4_RESOLUTION_VERY_COARSE 0x01
67 #define SX9310_REG_PROX_CTRL4_RESOLUTION_COARSEST 0x00
68 #define SX9310_REG_PROX_CTRL5 0x15
69 #define SX9310_REG_PROX_CTRL5_RANGE_SMALL (0x03 << 6)
70 #define SX9310_REG_PROX_CTRL5_STARTUPSENS_MASK GENMASK(3, 2)
71 #define SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 (0x01 << 2)
72 #define SX9310_REG_PROX_CTRL5_RAWFILT_MASK GENMASK(1, 0)
73 #define SX9310_REG_PROX_CTRL5_RAWFILT_SHIFT 0
74 #define SX9310_REG_PROX_CTRL5_RAWFILT_1P25 0x02
75 #define SX9310_REG_PROX_CTRL6 0x16
76 #define SX9310_REG_PROX_CTRL6_AVGTHRESH_DEFAULT 0x20
77 #define SX9310_REG_PROX_CTRL7 0x17
78 #define SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 (0x01 << 3)
79 #define SX9310_REG_PROX_CTRL7_AVGPOSFILT_MASK GENMASK(2, 0)
80 #define SX9310_REG_PROX_CTRL7_AVGPOSFILT_SHIFT 0
81 #define SX9310_REG_PROX_CTRL7_AVGPOSFILT_512 0x05
82 #define SX9310_REG_PROX_CTRL8 0x18
83 #define SX9310_REG_PROX_CTRL8_9_PTHRESH_MASK GENMASK(7, 3)
84 #define SX9310_REG_PROX_CTRL9 0x19
85 #define SX9310_REG_PROX_CTRL8_9_PTHRESH_28 (0x08 << 3)
86 #define SX9310_REG_PROX_CTRL8_9_PTHRESH_96 (0x11 << 3)
87 #define SX9310_REG_PROX_CTRL8_9_BODYTHRESH_900 0x03
88 #define SX9310_REG_PROX_CTRL8_9_BODYTHRESH_1500 0x05
89 #define SX9310_REG_PROX_CTRL10 0x1a
90 #define SX9310_REG_PROX_CTRL10_HYST_MASK GENMASK(5, 4)
91 #define SX9310_REG_PROX_CTRL10_HYST_6PCT (0x01 << 4)
92 #define SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_MASK GENMASK(3, 2)
93 #define SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_MASK GENMASK(1, 0)
94 #define SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_2 0x01
95 #define SX9310_REG_PROX_CTRL11 0x1b
96 #define SX9310_REG_PROX_CTRL12 0x1c
97 #define SX9310_REG_PROX_CTRL13 0x1d
98 #define SX9310_REG_PROX_CTRL14 0x1e
99 #define SX9310_REG_PROX_CTRL15 0x1f
100 #define SX9310_REG_PROX_CTRL16 0x20
101 #define SX9310_REG_PROX_CTRL17 0x21
102 #define SX9310_REG_PROX_CTRL18 0x22
103 #define SX9310_REG_PROX_CTRL19 0x23
104 #define SX9310_REG_SAR_CTRL0 0x2a
105 #define SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES (0x02 << 5)
106 #define SX9310_REG_SAR_CTRL0_SARHYST_8 (0x02 << 3)
107 #define SX9310_REG_SAR_CTRL1 0x2b
108 /* Each increment of the slope register is 0.0078125. */
109 #define SX9310_REG_SAR_CTRL1_SLOPE(_hnslope) (_hnslope / 78125)
110 #define SX9310_REG_SAR_CTRL2 0x2c
111 #define SX9310_REG_SAR_CTRL2_SAROFFSET_DEFAULT 0x3c
112
113 #define SX9310_REG_SENSOR_SEL 0x30
114 #define SX9310_REG_USE_MSB 0x31
115 #define SX9310_REG_USE_LSB 0x32
116 #define SX9310_REG_AVG_MSB 0x33
117 #define SX9310_REG_AVG_LSB 0x34
118 #define SX9310_REG_DIFF_MSB 0x35
119 #define SX9310_REG_DIFF_LSB 0x36
120 #define SX9310_REG_OFFSET_MSB 0x37
121 #define SX9310_REG_OFFSET_LSB 0x38
122 #define SX9310_REG_SAR_MSB 0x39
123 #define SX9310_REG_SAR_LSB 0x3a
124 #define SX9310_REG_I2C_ADDR 0x40
125 #define SX9310_REG_PAUSE 0x41
126 #define SX9310_REG_WHOAMI 0x42
127 #define SX9310_WHOAMI_VALUE 0x01
128 #define SX9311_WHOAMI_VALUE 0x02
129 #define SX9310_REG_RESET 0x7f
130
131
132 /* 4 hardware channels, as defined in STAT0: COMB, CS2, CS1 and CS0. */
133 #define SX9310_NUM_CHANNELS 4
134 static_assert(SX9310_NUM_CHANNELS <= SX_COMMON_MAX_NUM_CHANNELS);
135
136 #define SX9310_NAMED_CHANNEL(idx, name) \
137 { \
138 .type = IIO_PROXIMITY, \
139 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
140 BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
141 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
142 .info_mask_separate_available = \
143 BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
144 .info_mask_shared_by_all_available = \
145 BIT(IIO_CHAN_INFO_SAMP_FREQ), \
146 .indexed = 1, \
147 .channel = idx, \
148 .extend_name = name, \
149 .address = SX9310_REG_DIFF_MSB, \
150 .event_spec = sx_common_events, \
151 .num_event_specs = ARRAY_SIZE(sx_common_events), \
152 .scan_index = idx, \
153 .scan_type = { \
154 .sign = 's', \
155 .realbits = 12, \
156 .storagebits = 16, \
157 .endianness = IIO_BE, \
158 }, \
159 }
160 #define SX9310_CHANNEL(idx) SX9310_NAMED_CHANNEL(idx, NULL)
161
162 struct sx931x_info {
163 const char *name;
164 unsigned int whoami;
165 };
166
167 static const struct iio_chan_spec sx9310_channels[] = {
168 SX9310_CHANNEL(0), /* CS0 */
169 SX9310_CHANNEL(1), /* CS1 */
170 SX9310_CHANNEL(2), /* CS2 */
171 SX9310_NAMED_CHANNEL(3, "comb"), /* COMB */
172
173 IIO_CHAN_SOFT_TIMESTAMP(4),
174 };
175
176 /*
177 * Each entry contains the integer part (val) and the fractional part, in micro
178 * seconds. It conforms to the IIO output IIO_VAL_INT_PLUS_MICRO.
179 */
180 static const struct {
181 int val;
182 int val2;
183 } sx9310_samp_freq_table[] = {
184 { 500, 0 }, /* 0000: Min (no idle time) */
185 { 66, 666666 }, /* 0001: 15 ms */
186 { 33, 333333 }, /* 0010: 30 ms (Typ.) */
187 { 22, 222222 }, /* 0011: 45 ms */
188 { 16, 666666 }, /* 0100: 60 ms */
189 { 11, 111111 }, /* 0101: 90 ms */
190 { 8, 333333 }, /* 0110: 120 ms */
191 { 5, 0 }, /* 0111: 200 ms */
192 { 2, 500000 }, /* 1000: 400 ms */
193 { 1, 666666 }, /* 1001: 600 ms */
194 { 1, 250000 }, /* 1010: 800 ms */
195 { 1, 0 }, /* 1011: 1 s */
196 { 0, 500000 }, /* 1100: 2 s */
197 { 0, 333333 }, /* 1101: 3 s */
198 { 0, 250000 }, /* 1110: 4 s */
199 { 0, 200000 }, /* 1111: 5 s */
200 };
201 static const unsigned int sx9310_scan_period_table[] = {
202 2, 15, 30, 45, 60, 90, 120, 200,
203 400, 600, 800, 1000, 2000, 3000, 4000, 5000,
204 };
205
206 static const struct regmap_range sx9310_writable_reg_ranges[] = {
207 regmap_reg_range(SX9310_REG_IRQ_MSK, SX9310_REG_IRQ_FUNC),
208 regmap_reg_range(SX9310_REG_PROX_CTRL0, SX9310_REG_PROX_CTRL19),
209 regmap_reg_range(SX9310_REG_SAR_CTRL0, SX9310_REG_SAR_CTRL2),
210 regmap_reg_range(SX9310_REG_SENSOR_SEL, SX9310_REG_SENSOR_SEL),
211 regmap_reg_range(SX9310_REG_OFFSET_MSB, SX9310_REG_OFFSET_LSB),
212 regmap_reg_range(SX9310_REG_PAUSE, SX9310_REG_PAUSE),
213 regmap_reg_range(SX9310_REG_RESET, SX9310_REG_RESET),
214 };
215
216 static const struct regmap_access_table sx9310_writeable_regs = {
217 .yes_ranges = sx9310_writable_reg_ranges,
218 .n_yes_ranges = ARRAY_SIZE(sx9310_writable_reg_ranges),
219 };
220
221 static const struct regmap_range sx9310_readable_reg_ranges[] = {
222 regmap_reg_range(SX9310_REG_IRQ_SRC, SX9310_REG_IRQ_FUNC),
223 regmap_reg_range(SX9310_REG_PROX_CTRL0, SX9310_REG_PROX_CTRL19),
224 regmap_reg_range(SX9310_REG_SAR_CTRL0, SX9310_REG_SAR_CTRL2),
225 regmap_reg_range(SX9310_REG_SENSOR_SEL, SX9310_REG_SAR_LSB),
226 regmap_reg_range(SX9310_REG_I2C_ADDR, SX9310_REG_WHOAMI),
227 regmap_reg_range(SX9310_REG_RESET, SX9310_REG_RESET),
228 };
229
230 static const struct regmap_access_table sx9310_readable_regs = {
231 .yes_ranges = sx9310_readable_reg_ranges,
232 .n_yes_ranges = ARRAY_SIZE(sx9310_readable_reg_ranges),
233 };
234
235 static const struct regmap_range sx9310_volatile_reg_ranges[] = {
236 regmap_reg_range(SX9310_REG_IRQ_SRC, SX9310_REG_STAT1),
237 regmap_reg_range(SX9310_REG_USE_MSB, SX9310_REG_DIFF_LSB),
238 regmap_reg_range(SX9310_REG_SAR_MSB, SX9310_REG_SAR_LSB),
239 regmap_reg_range(SX9310_REG_RESET, SX9310_REG_RESET),
240 };
241
242 static const struct regmap_access_table sx9310_volatile_regs = {
243 .yes_ranges = sx9310_volatile_reg_ranges,
244 .n_yes_ranges = ARRAY_SIZE(sx9310_volatile_reg_ranges),
245 };
246
247 static const struct regmap_config sx9310_regmap_config = {
248 .reg_bits = 8,
249 .val_bits = 8,
250
251 .max_register = SX9310_REG_RESET,
252 .cache_type = REGCACHE_RBTREE,
253
254 .wr_table = &sx9310_writeable_regs,
255 .rd_table = &sx9310_readable_regs,
256 .volatile_table = &sx9310_volatile_regs,
257 };
258
sx9310_read_prox_data(struct sx_common_data * data,const struct iio_chan_spec * chan,__be16 * val)259 static int sx9310_read_prox_data(struct sx_common_data *data,
260 const struct iio_chan_spec *chan, __be16 *val)
261 {
262 int ret;
263
264 ret = regmap_write(data->regmap, SX9310_REG_SENSOR_SEL, chan->channel);
265 if (ret)
266 return ret;
267
268 return regmap_bulk_read(data->regmap, chan->address, val, sizeof(*val));
269 }
270
271 /*
272 * If we have no interrupt support, we have to wait for a scan period
273 * after enabling a channel to get a result.
274 */
sx9310_wait_for_sample(struct sx_common_data * data)275 static int sx9310_wait_for_sample(struct sx_common_data *data)
276 {
277 int ret;
278 unsigned int val;
279
280 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, &val);
281 if (ret)
282 return ret;
283
284 val = FIELD_GET(SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, val);
285
286 msleep(sx9310_scan_period_table[val]);
287
288 return 0;
289 }
290
sx9310_read_gain(struct sx_common_data * data,const struct iio_chan_spec * chan,int * val)291 static int sx9310_read_gain(struct sx_common_data *data,
292 const struct iio_chan_spec *chan, int *val)
293 {
294 unsigned int regval, gain;
295 int ret;
296
297 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL3, ®val);
298 if (ret)
299 return ret;
300
301 switch (chan->channel) {
302 case 0:
303 case 3:
304 gain = FIELD_GET(SX9310_REG_PROX_CTRL3_GAIN0_MASK, regval);
305 break;
306 case 1:
307 case 2:
308 gain = FIELD_GET(SX9310_REG_PROX_CTRL3_GAIN12_MASK, regval);
309 break;
310 default:
311 return -EINVAL;
312 }
313
314 *val = 1 << gain;
315
316 return IIO_VAL_INT;
317 }
318
sx9310_read_samp_freq(struct sx_common_data * data,int * val,int * val2)319 static int sx9310_read_samp_freq(struct sx_common_data *data, int *val, int *val2)
320 {
321 unsigned int regval;
322 int ret;
323
324 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, ®val);
325 if (ret)
326 return ret;
327
328 regval = FIELD_GET(SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, regval);
329 *val = sx9310_samp_freq_table[regval].val;
330 *val2 = sx9310_samp_freq_table[regval].val2;
331
332 return IIO_VAL_INT_PLUS_MICRO;
333 }
334
sx9310_read_raw(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,int * val,int * val2,long mask)335 static int sx9310_read_raw(struct iio_dev *indio_dev,
336 const struct iio_chan_spec *chan, int *val,
337 int *val2, long mask)
338 {
339 struct sx_common_data *data = iio_priv(indio_dev);
340 int ret;
341
342 if (chan->type != IIO_PROXIMITY)
343 return -EINVAL;
344
345 switch (mask) {
346 case IIO_CHAN_INFO_RAW:
347 if (!iio_device_claim_direct(indio_dev))
348 return -EBUSY;
349
350 ret = sx_common_read_proximity(data, chan, val);
351 iio_device_release_direct(indio_dev);
352 return ret;
353 case IIO_CHAN_INFO_HARDWAREGAIN:
354 if (!iio_device_claim_direct(indio_dev))
355 return -EBUSY;
356
357 ret = sx9310_read_gain(data, chan, val);
358 iio_device_release_direct(indio_dev);
359 return ret;
360 case IIO_CHAN_INFO_SAMP_FREQ:
361 return sx9310_read_samp_freq(data, val, val2);
362 default:
363 return -EINVAL;
364 }
365 }
366
367 static const int sx9310_gain_vals[] = { 1, 2, 4, 8 };
368
sx9310_read_avail(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,const int ** vals,int * type,int * length,long mask)369 static int sx9310_read_avail(struct iio_dev *indio_dev,
370 struct iio_chan_spec const *chan,
371 const int **vals, int *type, int *length,
372 long mask)
373 {
374 if (chan->type != IIO_PROXIMITY)
375 return -EINVAL;
376
377 switch (mask) {
378 case IIO_CHAN_INFO_HARDWAREGAIN:
379 *type = IIO_VAL_INT;
380 *length = ARRAY_SIZE(sx9310_gain_vals);
381 *vals = sx9310_gain_vals;
382 return IIO_AVAIL_LIST;
383 case IIO_CHAN_INFO_SAMP_FREQ:
384 *type = IIO_VAL_INT_PLUS_MICRO;
385 *length = ARRAY_SIZE(sx9310_samp_freq_table) * 2;
386 *vals = (int *)sx9310_samp_freq_table;
387 return IIO_AVAIL_LIST;
388 default:
389 return -EINVAL;
390 }
391 }
392
393 static const unsigned int sx9310_pthresh_codes[] = {
394 2, 4, 6, 8, 12, 16, 20, 24, 28, 32, 40, 48, 56, 64, 72, 80, 88, 96, 112,
395 128, 144, 160, 192, 224, 256, 320, 384, 512, 640, 768, 1024, 1536
396 };
397
sx9310_get_thresh_reg(unsigned int channel)398 static int sx9310_get_thresh_reg(unsigned int channel)
399 {
400 switch (channel) {
401 case 0:
402 case 3:
403 return SX9310_REG_PROX_CTRL8;
404 case 1:
405 case 2:
406 return SX9310_REG_PROX_CTRL9;
407 default:
408 return -EINVAL;
409 }
410 }
411
sx9310_read_thresh(struct sx_common_data * data,const struct iio_chan_spec * chan,int * val)412 static int sx9310_read_thresh(struct sx_common_data *data,
413 const struct iio_chan_spec *chan, int *val)
414 {
415 unsigned int reg;
416 unsigned int regval;
417 int ret;
418
419 reg = ret = sx9310_get_thresh_reg(chan->channel);
420 if (ret < 0)
421 return ret;
422
423 ret = regmap_read(data->regmap, reg, ®val);
424 if (ret)
425 return ret;
426
427 regval = FIELD_GET(SX9310_REG_PROX_CTRL8_9_PTHRESH_MASK, regval);
428 if (regval >= ARRAY_SIZE(sx9310_pthresh_codes))
429 return -EINVAL;
430
431 *val = sx9310_pthresh_codes[regval];
432 return IIO_VAL_INT;
433 }
434
sx9310_read_hysteresis(struct sx_common_data * data,const struct iio_chan_spec * chan,int * val)435 static int sx9310_read_hysteresis(struct sx_common_data *data,
436 const struct iio_chan_spec *chan, int *val)
437 {
438 unsigned int regval, pthresh;
439 int ret;
440
441 ret = sx9310_read_thresh(data, chan, &pthresh);
442 if (ret < 0)
443 return ret;
444
445 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL10, ®val);
446 if (ret)
447 return ret;
448
449 regval = FIELD_GET(SX9310_REG_PROX_CTRL10_HYST_MASK, regval);
450 if (!regval)
451 regval = 5;
452
453 /* regval is at most 5 */
454 *val = pthresh >> (5 - regval);
455
456 return IIO_VAL_INT;
457 }
458
sx9310_read_far_debounce(struct sx_common_data * data,int * val)459 static int sx9310_read_far_debounce(struct sx_common_data *data, int *val)
460 {
461 unsigned int regval;
462 int ret;
463
464 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL10, ®val);
465 if (ret)
466 return ret;
467
468 regval = FIELD_GET(SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_MASK, regval);
469 if (regval)
470 *val = 1 << regval;
471 else
472 *val = 0;
473
474 return IIO_VAL_INT;
475 }
476
sx9310_read_close_debounce(struct sx_common_data * data,int * val)477 static int sx9310_read_close_debounce(struct sx_common_data *data, int *val)
478 {
479 unsigned int regval;
480 int ret;
481
482 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL10, ®val);
483 if (ret)
484 return ret;
485
486 regval = FIELD_GET(SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_MASK, regval);
487 if (regval)
488 *val = 1 << regval;
489 else
490 *val = 0;
491
492 return IIO_VAL_INT;
493 }
494
sx9310_read_event_val(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,enum iio_event_info info,int * val,int * val2)495 static int sx9310_read_event_val(struct iio_dev *indio_dev,
496 const struct iio_chan_spec *chan,
497 enum iio_event_type type,
498 enum iio_event_direction dir,
499 enum iio_event_info info, int *val, int *val2)
500 {
501 struct sx_common_data *data = iio_priv(indio_dev);
502
503 if (chan->type != IIO_PROXIMITY)
504 return -EINVAL;
505
506 switch (info) {
507 case IIO_EV_INFO_VALUE:
508 return sx9310_read_thresh(data, chan, val);
509 case IIO_EV_INFO_PERIOD:
510 switch (dir) {
511 case IIO_EV_DIR_RISING:
512 return sx9310_read_far_debounce(data, val);
513 case IIO_EV_DIR_FALLING:
514 return sx9310_read_close_debounce(data, val);
515 default:
516 return -EINVAL;
517 }
518 case IIO_EV_INFO_HYSTERESIS:
519 return sx9310_read_hysteresis(data, chan, val);
520 default:
521 return -EINVAL;
522 }
523 }
524
sx9310_write_thresh(struct sx_common_data * data,const struct iio_chan_spec * chan,int val)525 static int sx9310_write_thresh(struct sx_common_data *data,
526 const struct iio_chan_spec *chan, int val)
527 {
528 unsigned int reg;
529 unsigned int regval;
530 int ret, i;
531
532 reg = ret = sx9310_get_thresh_reg(chan->channel);
533 if (ret < 0)
534 return ret;
535
536 for (i = 0; i < ARRAY_SIZE(sx9310_pthresh_codes); i++) {
537 if (sx9310_pthresh_codes[i] == val) {
538 regval = i;
539 break;
540 }
541 }
542
543 if (i == ARRAY_SIZE(sx9310_pthresh_codes))
544 return -EINVAL;
545
546 regval = FIELD_PREP(SX9310_REG_PROX_CTRL8_9_PTHRESH_MASK, regval);
547
548 guard(mutex)(&data->mutex);
549 return regmap_update_bits(data->regmap, reg,
550 SX9310_REG_PROX_CTRL8_9_PTHRESH_MASK, regval);
551 }
552
sx9310_write_hysteresis(struct sx_common_data * data,const struct iio_chan_spec * chan,int _val)553 static int sx9310_write_hysteresis(struct sx_common_data *data,
554 const struct iio_chan_spec *chan, int _val)
555 {
556 unsigned int hyst, val = _val;
557 int ret, pthresh;
558
559 ret = sx9310_read_thresh(data, chan, &pthresh);
560 if (ret < 0)
561 return ret;
562
563 if (val == 0)
564 hyst = 0;
565 else if (val == pthresh >> 2)
566 hyst = 3;
567 else if (val == pthresh >> 3)
568 hyst = 2;
569 else if (val == pthresh >> 4)
570 hyst = 1;
571 else
572 return -EINVAL;
573
574 hyst = FIELD_PREP(SX9310_REG_PROX_CTRL10_HYST_MASK, hyst);
575
576 guard(mutex)(&data->mutex);
577 return regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL10,
578 SX9310_REG_PROX_CTRL10_HYST_MASK, hyst);
579 }
580
sx9310_write_far_debounce(struct sx_common_data * data,int val)581 static int sx9310_write_far_debounce(struct sx_common_data *data, int val)
582 {
583 unsigned int regval;
584
585 if (val > 0)
586 val = ilog2(val);
587 if (!FIELD_FIT(SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_MASK, val))
588 return -EINVAL;
589
590 regval = FIELD_PREP(SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_MASK, val);
591
592 guard(mutex)(&data->mutex);
593 return regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL10,
594 SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_MASK,
595 regval);
596 }
597
sx9310_write_close_debounce(struct sx_common_data * data,int val)598 static int sx9310_write_close_debounce(struct sx_common_data *data, int val)
599 {
600 unsigned int regval;
601
602 if (val > 0)
603 val = ilog2(val);
604 if (!FIELD_FIT(SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_MASK, val))
605 return -EINVAL;
606
607 regval = FIELD_PREP(SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_MASK, val);
608
609 guard(mutex)(&data->mutex);
610 return regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL10,
611 SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_MASK,
612 regval);
613 }
614
sx9310_write_event_val(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,enum iio_event_info info,int val,int val2)615 static int sx9310_write_event_val(struct iio_dev *indio_dev,
616 const struct iio_chan_spec *chan,
617 enum iio_event_type type,
618 enum iio_event_direction dir,
619 enum iio_event_info info, int val, int val2)
620 {
621 struct sx_common_data *data = iio_priv(indio_dev);
622
623 if (chan->type != IIO_PROXIMITY)
624 return -EINVAL;
625
626 switch (info) {
627 case IIO_EV_INFO_VALUE:
628 return sx9310_write_thresh(data, chan, val);
629 case IIO_EV_INFO_PERIOD:
630 switch (dir) {
631 case IIO_EV_DIR_RISING:
632 return sx9310_write_far_debounce(data, val);
633 case IIO_EV_DIR_FALLING:
634 return sx9310_write_close_debounce(data, val);
635 default:
636 return -EINVAL;
637 }
638 case IIO_EV_INFO_HYSTERESIS:
639 return sx9310_write_hysteresis(data, chan, val);
640 default:
641 return -EINVAL;
642 }
643 }
644
sx9310_set_samp_freq(struct sx_common_data * data,int val,int val2)645 static int sx9310_set_samp_freq(struct sx_common_data *data, int val, int val2)
646 {
647 int i;
648
649 for (i = 0; i < ARRAY_SIZE(sx9310_samp_freq_table); i++)
650 if (val == sx9310_samp_freq_table[i].val &&
651 val2 == sx9310_samp_freq_table[i].val2)
652 break;
653
654 if (i == ARRAY_SIZE(sx9310_samp_freq_table))
655 return -EINVAL;
656
657 guard(mutex)(&data->mutex);
658 return regmap_update_bits(
659 data->regmap, SX9310_REG_PROX_CTRL0,
660 SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK,
661 FIELD_PREP(SX9310_REG_PROX_CTRL0_SCANPERIOD_MASK, i));
662 }
663
sx9310_write_gain(struct sx_common_data * data,const struct iio_chan_spec * chan,int val)664 static int sx9310_write_gain(struct sx_common_data *data,
665 const struct iio_chan_spec *chan, int val)
666 {
667 unsigned int gain, mask;
668
669 gain = ilog2(val);
670
671 switch (chan->channel) {
672 case 0:
673 case 3:
674 mask = SX9310_REG_PROX_CTRL3_GAIN0_MASK;
675 gain = FIELD_PREP(SX9310_REG_PROX_CTRL3_GAIN0_MASK, gain);
676 break;
677 case 1:
678 case 2:
679 mask = SX9310_REG_PROX_CTRL3_GAIN12_MASK;
680 gain = FIELD_PREP(SX9310_REG_PROX_CTRL3_GAIN12_MASK, gain);
681 break;
682 default:
683 return -EINVAL;
684 }
685
686 guard(mutex)(&data->mutex);
687 return regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL3, mask,
688 gain);
689 }
690
sx9310_write_raw(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,int val,int val2,long mask)691 static int sx9310_write_raw(struct iio_dev *indio_dev,
692 const struct iio_chan_spec *chan, int val, int val2,
693 long mask)
694 {
695 struct sx_common_data *data = iio_priv(indio_dev);
696
697 if (chan->type != IIO_PROXIMITY)
698 return -EINVAL;
699
700 switch (mask) {
701 case IIO_CHAN_INFO_SAMP_FREQ:
702 return sx9310_set_samp_freq(data, val, val2);
703 case IIO_CHAN_INFO_HARDWAREGAIN:
704 return sx9310_write_gain(data, chan, val);
705 default:
706 return -EINVAL;
707 }
708 }
709
710 static const struct sx_common_reg_default sx9310_default_regs[] = {
711 { SX9310_REG_IRQ_MSK, 0x00 },
712 { SX9310_REG_IRQ_FUNC, 0x00 },
713 /*
714 * The lower 4 bits should not be set as it enable sensors measurements.
715 * Turning the detection on before the configuration values are set to
716 * good values can cause the device to return erroneous readings.
717 */
718 { SX9310_REG_PROX_CTRL0, SX9310_REG_PROX_CTRL0_SCANPERIOD_15MS },
719 { SX9310_REG_PROX_CTRL1, 0x00 },
720 { SX9310_REG_PROX_CTRL2, SX9310_REG_PROX_CTRL2_COMBMODE_CS1_CS2 |
721 SX9310_REG_PROX_CTRL2_SHIELDEN_DYNAMIC },
722 { SX9310_REG_PROX_CTRL3, SX9310_REG_PROX_CTRL3_GAIN0_X8 |
723 SX9310_REG_PROX_CTRL3_GAIN12_X4 },
724 { SX9310_REG_PROX_CTRL4, SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST },
725 { SX9310_REG_PROX_CTRL5, SX9310_REG_PROX_CTRL5_RANGE_SMALL |
726 SX9310_REG_PROX_CTRL5_STARTUPSENS_CS1 |
727 SX9310_REG_PROX_CTRL5_RAWFILT_1P25 },
728 { SX9310_REG_PROX_CTRL6, SX9310_REG_PROX_CTRL6_AVGTHRESH_DEFAULT },
729 { SX9310_REG_PROX_CTRL7, SX9310_REG_PROX_CTRL7_AVGNEGFILT_2 |
730 SX9310_REG_PROX_CTRL7_AVGPOSFILT_512 },
731 { SX9310_REG_PROX_CTRL8, SX9310_REG_PROX_CTRL8_9_PTHRESH_96 |
732 SX9310_REG_PROX_CTRL8_9_BODYTHRESH_1500 },
733 { SX9310_REG_PROX_CTRL9, SX9310_REG_PROX_CTRL8_9_PTHRESH_28 |
734 SX9310_REG_PROX_CTRL8_9_BODYTHRESH_900 },
735 { SX9310_REG_PROX_CTRL10, SX9310_REG_PROX_CTRL10_HYST_6PCT |
736 SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_2 },
737 { SX9310_REG_PROX_CTRL11, 0x00 },
738 { SX9310_REG_PROX_CTRL12, 0x00 },
739 { SX9310_REG_PROX_CTRL13, 0x00 },
740 { SX9310_REG_PROX_CTRL14, 0x00 },
741 { SX9310_REG_PROX_CTRL15, 0x00 },
742 { SX9310_REG_PROX_CTRL16, 0x00 },
743 { SX9310_REG_PROX_CTRL17, 0x00 },
744 { SX9310_REG_PROX_CTRL18, 0x00 },
745 { SX9310_REG_PROX_CTRL19, 0x00 },
746 { SX9310_REG_SAR_CTRL0, SX9310_REG_SAR_CTRL0_SARDEB_4_SAMPLES |
747 SX9310_REG_SAR_CTRL0_SARHYST_8 },
748 { SX9310_REG_SAR_CTRL1, SX9310_REG_SAR_CTRL1_SLOPE(10781250) },
749 { SX9310_REG_SAR_CTRL2, SX9310_REG_SAR_CTRL2_SAROFFSET_DEFAULT },
750 };
751
752 /* Activate all channels and perform an initial compensation. */
sx9310_init_compensation(struct iio_dev * indio_dev)753 static int sx9310_init_compensation(struct iio_dev *indio_dev)
754 {
755 struct sx_common_data *data = iio_priv(indio_dev);
756 int ret;
757 unsigned int val;
758 unsigned int ctrl0;
759
760 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0, &ctrl0);
761 if (ret)
762 return ret;
763
764 /* run the compensation phase on all channels */
765 ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0,
766 ctrl0 | SX9310_REG_PROX_CTRL0_SENSOREN_MASK);
767 if (ret)
768 return ret;
769
770 ret = regmap_read_poll_timeout(data->regmap, SX9310_REG_STAT1, val,
771 !(val & SX9310_REG_STAT1_COMPSTAT_MASK),
772 20000, 2000000);
773 if (ret)
774 return ret;
775
776 regmap_write(data->regmap, SX9310_REG_PROX_CTRL0, ctrl0);
777 return ret;
778 }
779
780 static const struct sx_common_reg_default *
sx9310_get_default_reg(struct device * dev,int idx,struct sx_common_reg_default * reg_def)781 sx9310_get_default_reg(struct device *dev, int idx,
782 struct sx_common_reg_default *reg_def)
783 {
784 u32 combined[SX9310_NUM_CHANNELS];
785 u32 start = 0, raw = 0, pos = 0;
786 unsigned long comb_mask = 0;
787 int ret, i, count;
788 const char *res;
789
790 memcpy(reg_def, &sx9310_default_regs[idx], sizeof(*reg_def));
791 switch (reg_def->reg) {
792 case SX9310_REG_PROX_CTRL2:
793 if (device_property_read_bool(dev, "semtech,cs0-ground")) {
794 reg_def->def &= ~SX9310_REG_PROX_CTRL2_SHIELDEN_MASK;
795 reg_def->def |= SX9310_REG_PROX_CTRL2_SHIELDEN_GROUND;
796 }
797
798 count = device_property_count_u32(dev, "semtech,combined-sensors");
799 if (count < 0 || count > ARRAY_SIZE(combined))
800 break;
801 ret = device_property_read_u32_array(dev, "semtech,combined-sensors",
802 combined, count);
803 if (ret)
804 break;
805
806 for (i = 0; i < count; i++)
807 comb_mask |= BIT(combined[i]);
808
809 reg_def->def &= ~SX9310_REG_PROX_CTRL2_COMBMODE_MASK;
810 if (comb_mask == (BIT(3) | BIT(2) | BIT(1) | BIT(0)))
811 reg_def->def |= SX9310_REG_PROX_CTRL2_COMBMODE_CS0_CS1_CS2_CS3;
812 else if (comb_mask == (BIT(1) | BIT(2)))
813 reg_def->def |= SX9310_REG_PROX_CTRL2_COMBMODE_CS1_CS2;
814 else if (comb_mask == (BIT(0) | BIT(1)))
815 reg_def->def |= SX9310_REG_PROX_CTRL2_COMBMODE_CS0_CS1;
816 else if (comb_mask == BIT(3))
817 reg_def->def |= SX9310_REG_PROX_CTRL2_COMBMODE_CS3;
818
819 break;
820 case SX9310_REG_PROX_CTRL4:
821 ret = device_property_read_string(dev, "semtech,resolution", &res);
822 if (ret)
823 break;
824
825 reg_def->def &= ~SX9310_REG_PROX_CTRL4_RESOLUTION_MASK;
826 if (!strcmp(res, "coarsest"))
827 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_COARSEST;
828 else if (!strcmp(res, "very-coarse"))
829 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_VERY_COARSE;
830 else if (!strcmp(res, "coarse"))
831 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_COARSE;
832 else if (!strcmp(res, "medium-coarse"))
833 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_MEDIUM_COARSE;
834 else if (!strcmp(res, "medium"))
835 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_MEDIUM;
836 else if (!strcmp(res, "fine"))
837 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_FINE;
838 else if (!strcmp(res, "very-fine"))
839 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_VERY_FINE;
840 else if (!strcmp(res, "finest"))
841 reg_def->def |= SX9310_REG_PROX_CTRL4_RESOLUTION_FINEST;
842
843 break;
844 case SX9310_REG_PROX_CTRL5:
845 ret = device_property_read_u32(dev, "semtech,startup-sensor", &start);
846 if (ret) {
847 start = FIELD_GET(SX9310_REG_PROX_CTRL5_STARTUPSENS_MASK,
848 reg_def->def);
849 }
850
851 reg_def->def &= ~SX9310_REG_PROX_CTRL5_STARTUPSENS_MASK;
852 reg_def->def |= FIELD_PREP(SX9310_REG_PROX_CTRL5_STARTUPSENS_MASK,
853 start);
854
855 ret = device_property_read_u32(dev, "semtech,proxraw-strength", &raw);
856 if (ret) {
857 raw = FIELD_GET(SX9310_REG_PROX_CTRL5_RAWFILT_MASK,
858 reg_def->def);
859 } else {
860 raw = ilog2(raw);
861 }
862
863 reg_def->def &= ~SX9310_REG_PROX_CTRL5_RAWFILT_MASK;
864 reg_def->def |= FIELD_PREP(SX9310_REG_PROX_CTRL5_RAWFILT_MASK,
865 raw);
866 break;
867 case SX9310_REG_PROX_CTRL7:
868 ret = device_property_read_u32(dev, "semtech,avg-pos-strength", &pos);
869 if (ret)
870 break;
871
872 /* Powers of 2, except for a gap between 16 and 64 */
873 pos = clamp(ilog2(pos), 3, 11) - (pos >= 32 ? 4 : 3);
874 reg_def->def &= ~SX9310_REG_PROX_CTRL7_AVGPOSFILT_MASK;
875 reg_def->def |= FIELD_PREP(SX9310_REG_PROX_CTRL7_AVGPOSFILT_MASK,
876 pos);
877 break;
878 }
879
880 return reg_def;
881 }
882
sx9310_check_whoami(struct device * dev,struct iio_dev * indio_dev)883 static int sx9310_check_whoami(struct device *dev,
884 struct iio_dev *indio_dev)
885 {
886 struct sx_common_data *data = iio_priv(indio_dev);
887 const struct sx931x_info *ddata;
888 unsigned int whoami;
889 int ret;
890
891 ret = regmap_read(data->regmap, SX9310_REG_WHOAMI, &whoami);
892 if (ret)
893 return ret;
894
895 ddata = device_get_match_data(dev);
896 if (ddata->whoami != whoami)
897 return -ENODEV;
898
899 indio_dev->name = ddata->name;
900
901 return 0;
902 }
903
904 static const struct sx_common_chip_info sx9310_chip_info = {
905 .reg_stat = SX9310_REG_STAT0,
906 .reg_irq_msk = SX9310_REG_IRQ_MSK,
907 .reg_enable_chan = SX9310_REG_PROX_CTRL0,
908 .reg_reset = SX9310_REG_RESET,
909
910 .mask_enable_chan = SX9310_REG_STAT1_COMPSTAT_MASK,
911 .irq_msk_offset = 3,
912 .num_channels = SX9310_NUM_CHANNELS,
913 .num_default_regs = ARRAY_SIZE(sx9310_default_regs),
914
915 .ops = {
916 .read_prox_data = sx9310_read_prox_data,
917 .check_whoami = sx9310_check_whoami,
918 .init_compensation = sx9310_init_compensation,
919 .wait_for_sample = sx9310_wait_for_sample,
920 .get_default_reg = sx9310_get_default_reg,
921 },
922
923 .iio_channels = sx9310_channels,
924 .num_iio_channels = ARRAY_SIZE(sx9310_channels),
925 .iio_info = {
926 .read_raw = sx9310_read_raw,
927 .read_avail = sx9310_read_avail,
928 .read_event_value = sx9310_read_event_val,
929 .write_event_value = sx9310_write_event_val,
930 .write_raw = sx9310_write_raw,
931 .read_event_config = sx_common_read_event_config,
932 .write_event_config = sx_common_write_event_config,
933 },
934 };
935
sx9310_probe(struct i2c_client * client)936 static int sx9310_probe(struct i2c_client *client)
937 {
938 return sx_common_probe(client, &sx9310_chip_info, &sx9310_regmap_config);
939 }
940
sx9310_suspend(struct device * dev)941 static int sx9310_suspend(struct device *dev)
942 {
943 struct sx_common_data *data = iio_priv(dev_get_drvdata(dev));
944 u8 ctrl0;
945 int ret;
946
947 disable_irq_nosync(data->client->irq);
948
949 guard(mutex)(&data->mutex);
950 ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL0,
951 &data->suspend_ctrl);
952 if (ret)
953 return ret;
954
955 ctrl0 = data->suspend_ctrl & ~SX9310_REG_PROX_CTRL0_SENSOREN_MASK;
956 ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0, ctrl0);
957 if (ret)
958 return ret;
959
960 return regmap_write(data->regmap, SX9310_REG_PAUSE, 0);
961 }
962
sx9310_resume(struct device * dev)963 static int sx9310_resume(struct device *dev)
964 {
965 struct sx_common_data *data = iio_priv(dev_get_drvdata(dev));
966 int ret;
967
968 scoped_guard(mutex, &data->mutex) {
969 ret = regmap_write(data->regmap, SX9310_REG_PAUSE, 1);
970 if (ret)
971 return ret;
972
973 ret = regmap_write(data->regmap, SX9310_REG_PROX_CTRL0,
974 data->suspend_ctrl);
975 if (ret)
976 return ret;
977 }
978
979 enable_irq(data->client->irq);
980 return 0;
981 }
982
983 static DEFINE_SIMPLE_DEV_PM_OPS(sx9310_pm_ops, sx9310_suspend, sx9310_resume);
984
985 static const struct sx931x_info sx9310_info = {
986 .name = "sx9310",
987 .whoami = SX9310_WHOAMI_VALUE,
988 };
989
990 static const struct sx931x_info sx9311_info = {
991 .name = "sx9311",
992 .whoami = SX9311_WHOAMI_VALUE,
993 };
994
995 static const struct acpi_device_id sx9310_acpi_match[] = {
996 { "STH9310", (kernel_ulong_t)&sx9310_info },
997 { "STH9311", (kernel_ulong_t)&sx9311_info },
998 { }
999 };
1000 MODULE_DEVICE_TABLE(acpi, sx9310_acpi_match);
1001
1002 static const struct of_device_id sx9310_of_match[] = {
1003 { .compatible = "semtech,sx9310", &sx9310_info },
1004 { .compatible = "semtech,sx9311", &sx9311_info },
1005 { }
1006 };
1007 MODULE_DEVICE_TABLE(of, sx9310_of_match);
1008
1009 static const struct i2c_device_id sx9310_id[] = {
1010 { "sx9310", (kernel_ulong_t)&sx9310_info },
1011 { "sx9311", (kernel_ulong_t)&sx9311_info },
1012 { }
1013 };
1014 MODULE_DEVICE_TABLE(i2c, sx9310_id);
1015
1016 static struct i2c_driver sx9310_driver = {
1017 .driver = {
1018 .name = "sx9310",
1019 .acpi_match_table = sx9310_acpi_match,
1020 .of_match_table = sx9310_of_match,
1021 .pm = pm_sleep_ptr(&sx9310_pm_ops),
1022
1023 /*
1024 * Lots of i2c transfers in probe + over 200 ms waiting in
1025 * sx9310_init_compensation() mean a slow probe; prefer async
1026 * so we don't delay boot if we're builtin to the kernel.
1027 */
1028 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
1029 },
1030 .probe = sx9310_probe,
1031 .id_table = sx9310_id,
1032 };
1033 module_i2c_driver(sx9310_driver);
1034
1035 MODULE_AUTHOR("Gwendal Grignou <gwendal@chromium.org>");
1036 MODULE_AUTHOR("Daniel Campello <campello@chromium.org>");
1037 MODULE_DESCRIPTION("Driver for Semtech SX9310/SX9311 proximity sensor");
1038 MODULE_LICENSE("GPL v2");
1039 MODULE_IMPORT_NS("SEMTECH_PROX");
1040