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