]>
Commit | Line | Data |
---|---|---|
3db3562b WH |
1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* | |
3 | * Driver for Murata IRS-D200 PIR sensor. | |
4 | * | |
5 | * Copyright (C) 2023 Axis Communications AB | |
6 | */ | |
7 | ||
8 | #include <asm/unaligned.h> | |
9 | #include <linux/bitfield.h> | |
10 | #include <linux/gpio.h> | |
11 | #include <linux/i2c.h> | |
12 | #include <linux/module.h> | |
13 | #include <linux/regmap.h> | |
14 | ||
15 | #include <linux/iio/buffer.h> | |
16 | #include <linux/iio/events.h> | |
17 | #include <linux/iio/iio.h> | |
18 | #include <linux/iio/trigger.h> | |
19 | #include <linux/iio/trigger_consumer.h> | |
20 | #include <linux/iio/triggered_buffer.h> | |
21 | #include <linux/iio/types.h> | |
22 | ||
23 | #define IRS_DRV_NAME "irsd200" | |
24 | ||
25 | /* Registers. */ | |
26 | #define IRS_REG_OP 0x00 /* Operation mode. */ | |
27 | #define IRS_REG_DATA_LO 0x02 /* Sensor data LSB. */ | |
28 | #define IRS_REG_DATA_HI 0x03 /* Sensor data MSB. */ | |
29 | #define IRS_REG_STATUS 0x04 /* Interrupt status. */ | |
30 | #define IRS_REG_COUNT 0x05 /* Count of exceeding threshold. */ | |
31 | #define IRS_REG_DATA_RATE 0x06 /* Output data rate. */ | |
32 | #define IRS_REG_FILTER 0x07 /* High-pass and low-pass filter. */ | |
33 | #define IRS_REG_INTR 0x09 /* Interrupt mode. */ | |
34 | #define IRS_REG_NR_COUNT 0x0a /* Number of counts before interrupt. */ | |
35 | #define IRS_REG_THR_HI 0x0b /* Upper threshold. */ | |
36 | #define IRS_REG_THR_LO 0x0c /* Lower threshold. */ | |
37 | #define IRS_REG_TIMER_LO 0x0d /* Timer setting LSB. */ | |
38 | #define IRS_REG_TIMER_HI 0x0e /* Timer setting MSB. */ | |
39 | ||
40 | /* Interrupt status bits. */ | |
41 | #define IRS_INTR_DATA 0 /* Data update. */ | |
42 | #define IRS_INTR_TIMER 1 /* Timer expiration. */ | |
43 | #define IRS_INTR_COUNT_THR_AND 2 /* Count "AND" threshold. */ | |
44 | #define IRS_INTR_COUNT_THR_OR 3 /* Count "OR" threshold. */ | |
45 | ||
46 | /* Operation states. */ | |
47 | #define IRS_OP_ACTIVE 0x00 | |
48 | #define IRS_OP_SLEEP 0x01 | |
49 | ||
50 | /* | |
51 | * Quantization scale value for threshold. Used for conversion from/to register | |
52 | * value. | |
53 | */ | |
54 | #define IRS_THR_QUANT_SCALE 128 | |
55 | ||
56 | #define IRS_UPPER_COUNT(count) FIELD_GET(GENMASK(7, 4), count) | |
57 | #define IRS_LOWER_COUNT(count) FIELD_GET(GENMASK(3, 0), count) | |
58 | ||
59 | /* Index corresponds to the value of IRS_REG_DATA_RATE register. */ | |
60 | static const int irsd200_data_rates[] = { | |
61 | 50, | |
62 | 100, | |
63 | }; | |
64 | ||
65 | /* Index corresponds to the (field) value of IRS_REG_FILTER register. */ | |
66 | static const unsigned int irsd200_lp_filter_freq[] = { | |
67 | 10, | |
68 | 7, | |
69 | }; | |
70 | ||
71 | /* | |
72 | * Index corresponds to the (field) value of IRS_REG_FILTER register. Note that | |
73 | * this represents a fractional value (e.g the first value corresponds to 3 / 10 | |
74 | * = 0.3 Hz). | |
75 | */ | |
76 | static const unsigned int irsd200_hp_filter_freq[][2] = { | |
77 | { 3, 10 }, | |
78 | { 5, 10 }, | |
79 | }; | |
80 | ||
81 | /* Register fields. */ | |
82 | enum irsd200_regfield { | |
83 | /* Data interrupt. */ | |
84 | IRS_REGF_INTR_DATA, | |
85 | /* Timer interrupt. */ | |
86 | IRS_REGF_INTR_TIMER, | |
87 | /* AND count threshold interrupt. */ | |
88 | IRS_REGF_INTR_COUNT_THR_AND, | |
89 | /* OR count threshold interrupt. */ | |
90 | IRS_REGF_INTR_COUNT_THR_OR, | |
91 | ||
92 | /* Low-pass filter frequency. */ | |
93 | IRS_REGF_LP_FILTER, | |
94 | /* High-pass filter frequency. */ | |
95 | IRS_REGF_HP_FILTER, | |
96 | ||
97 | /* Sentinel value. */ | |
98 | IRS_REGF_MAX | |
99 | }; | |
100 | ||
101 | static const struct reg_field irsd200_regfields[] = { | |
102 | [IRS_REGF_INTR_DATA] = | |
103 | REG_FIELD(IRS_REG_INTR, IRS_INTR_DATA, IRS_INTR_DATA), | |
104 | [IRS_REGF_INTR_TIMER] = | |
105 | REG_FIELD(IRS_REG_INTR, IRS_INTR_TIMER, IRS_INTR_TIMER), | |
106 | [IRS_REGF_INTR_COUNT_THR_AND] = REG_FIELD( | |
107 | IRS_REG_INTR, IRS_INTR_COUNT_THR_AND, IRS_INTR_COUNT_THR_AND), | |
108 | [IRS_REGF_INTR_COUNT_THR_OR] = REG_FIELD( | |
109 | IRS_REG_INTR, IRS_INTR_COUNT_THR_OR, IRS_INTR_COUNT_THR_OR), | |
110 | ||
111 | [IRS_REGF_LP_FILTER] = REG_FIELD(IRS_REG_FILTER, 1, 1), | |
112 | [IRS_REGF_HP_FILTER] = REG_FIELD(IRS_REG_FILTER, 0, 0), | |
113 | }; | |
114 | ||
115 | static const struct regmap_config irsd200_regmap_config = { | |
116 | .reg_bits = 8, | |
117 | .val_bits = 8, | |
118 | .max_register = IRS_REG_TIMER_HI, | |
119 | }; | |
120 | ||
121 | struct irsd200_data { | |
122 | struct regmap *regmap; | |
123 | struct regmap_field *regfields[IRS_REGF_MAX]; | |
124 | struct device *dev; | |
125 | }; | |
126 | ||
127 | static int irsd200_setup(struct irsd200_data *data) | |
128 | { | |
129 | unsigned int val; | |
130 | int ret; | |
131 | ||
132 | /* Disable all interrupt sources. */ | |
133 | ret = regmap_write(data->regmap, IRS_REG_INTR, 0); | |
134 | if (ret) { | |
135 | dev_err(data->dev, "Could not set interrupt sources (%d)\n", | |
136 | ret); | |
137 | return ret; | |
138 | } | |
139 | ||
140 | /* Set operation to active. */ | |
141 | ret = regmap_write(data->regmap, IRS_REG_OP, IRS_OP_ACTIVE); | |
142 | if (ret) { | |
143 | dev_err(data->dev, "Could not set operation mode (%d)\n", ret); | |
144 | return ret; | |
145 | } | |
146 | ||
147 | /* Clear threshold count. */ | |
148 | ret = regmap_read(data->regmap, IRS_REG_COUNT, &val); | |
149 | if (ret) { | |
150 | dev_err(data->dev, "Could not clear threshold count (%d)\n", | |
151 | ret); | |
152 | return ret; | |
153 | } | |
154 | ||
155 | /* Clear status. */ | |
156 | ret = regmap_write(data->regmap, IRS_REG_STATUS, 0x0f); | |
157 | if (ret) { | |
158 | dev_err(data->dev, "Could not clear status (%d)\n", ret); | |
159 | return ret; | |
160 | } | |
161 | ||
162 | return 0; | |
163 | } | |
164 | ||
165 | static int irsd200_read_threshold(struct irsd200_data *data, | |
166 | enum iio_event_direction dir, int *val) | |
167 | { | |
168 | unsigned int regval; | |
169 | unsigned int reg; | |
170 | int scale; | |
171 | int ret; | |
172 | ||
173 | /* Set quantization scale. */ | |
174 | if (dir == IIO_EV_DIR_RISING) { | |
175 | scale = IRS_THR_QUANT_SCALE; | |
176 | reg = IRS_REG_THR_HI; | |
177 | } else if (dir == IIO_EV_DIR_FALLING) { | |
178 | scale = -IRS_THR_QUANT_SCALE; | |
179 | reg = IRS_REG_THR_LO; | |
180 | } else { | |
181 | return -EINVAL; | |
182 | } | |
183 | ||
184 | ret = regmap_read(data->regmap, reg, ®val); | |
185 | if (ret) { | |
186 | dev_err(data->dev, "Could not read threshold (%d)\n", ret); | |
187 | return ret; | |
188 | } | |
189 | ||
190 | *val = ((int)regval) * scale; | |
191 | ||
192 | return 0; | |
193 | } | |
194 | ||
195 | static int irsd200_write_threshold(struct irsd200_data *data, | |
196 | enum iio_event_direction dir, int val) | |
197 | { | |
198 | unsigned int regval; | |
199 | unsigned int reg; | |
200 | int scale; | |
201 | int ret; | |
202 | ||
203 | /* Set quantization scale. */ | |
204 | if (dir == IIO_EV_DIR_RISING) { | |
205 | if (val < 0) | |
206 | return -ERANGE; | |
207 | ||
208 | scale = IRS_THR_QUANT_SCALE; | |
209 | reg = IRS_REG_THR_HI; | |
210 | } else if (dir == IIO_EV_DIR_FALLING) { | |
211 | if (val > 0) | |
212 | return -ERANGE; | |
213 | ||
214 | scale = -IRS_THR_QUANT_SCALE; | |
215 | reg = IRS_REG_THR_LO; | |
216 | } else { | |
217 | return -EINVAL; | |
218 | } | |
219 | ||
220 | regval = val / scale; | |
221 | ||
222 | if (regval >= BIT(8)) | |
223 | return -ERANGE; | |
224 | ||
225 | ret = regmap_write(data->regmap, reg, regval); | |
226 | if (ret) { | |
227 | dev_err(data->dev, "Could not write threshold (%d)\n", ret); | |
228 | return ret; | |
229 | } | |
230 | ||
231 | return 0; | |
232 | } | |
233 | ||
234 | static int irsd200_read_data(struct irsd200_data *data, s16 *val) | |
235 | { | |
236 | __le16 buf; | |
237 | int ret; | |
238 | ||
239 | ret = regmap_bulk_read(data->regmap, IRS_REG_DATA_LO, &buf, | |
240 | sizeof(buf)); | |
241 | if (ret) { | |
242 | dev_err(data->dev, "Could not bulk read data (%d)\n", ret); | |
243 | return ret; | |
244 | } | |
245 | ||
246 | *val = le16_to_cpu(buf); | |
247 | ||
248 | return 0; | |
249 | } | |
250 | ||
251 | static int irsd200_read_data_rate(struct irsd200_data *data, int *val) | |
252 | { | |
253 | unsigned int regval; | |
254 | int ret; | |
255 | ||
256 | ret = regmap_read(data->regmap, IRS_REG_DATA_RATE, ®val); | |
257 | if (ret) { | |
258 | dev_err(data->dev, "Could not read data rate (%d)\n", ret); | |
259 | return ret; | |
260 | } | |
261 | ||
262 | if (regval >= ARRAY_SIZE(irsd200_data_rates)) | |
263 | return -ERANGE; | |
264 | ||
265 | *val = irsd200_data_rates[regval]; | |
266 | ||
267 | return 0; | |
268 | } | |
269 | ||
270 | static int irsd200_write_data_rate(struct irsd200_data *data, int val) | |
271 | { | |
272 | size_t idx; | |
273 | int ret; | |
274 | ||
275 | for (idx = 0; idx < ARRAY_SIZE(irsd200_data_rates); ++idx) { | |
276 | if (irsd200_data_rates[idx] == val) | |
277 | break; | |
278 | } | |
279 | ||
280 | if (idx == ARRAY_SIZE(irsd200_data_rates)) | |
281 | return -ERANGE; | |
282 | ||
283 | ret = regmap_write(data->regmap, IRS_REG_DATA_RATE, idx); | |
284 | if (ret) { | |
285 | dev_err(data->dev, "Could not write data rate (%d)\n", ret); | |
286 | return ret; | |
287 | } | |
288 | ||
289 | /* | |
290 | * Data sheet says the device needs 3 seconds of settling time. The | |
291 | * device operates normally during this period though. This is more of a | |
292 | * "guarantee" than trying to prevent other user space reads/writes. | |
293 | */ | |
294 | ssleep(3); | |
295 | ||
296 | return 0; | |
297 | } | |
298 | ||
299 | static int irsd200_read_timer(struct irsd200_data *data, int *val, int *val2) | |
300 | { | |
301 | __le16 buf; | |
302 | int ret; | |
303 | ||
304 | ret = regmap_bulk_read(data->regmap, IRS_REG_TIMER_LO, &buf, | |
305 | sizeof(buf)); | |
306 | if (ret) { | |
307 | dev_err(data->dev, "Could not bulk read timer (%d)\n", ret); | |
308 | return ret; | |
309 | } | |
310 | ||
311 | ret = irsd200_read_data_rate(data, val2); | |
312 | if (ret) | |
313 | return ret; | |
314 | ||
315 | *val = le16_to_cpu(buf); | |
316 | ||
317 | return 0; | |
318 | } | |
319 | ||
320 | static int irsd200_write_timer(struct irsd200_data *data, int val, int val2) | |
321 | { | |
322 | unsigned int regval; | |
323 | int data_rate; | |
324 | __le16 buf; | |
325 | int ret; | |
326 | ||
327 | if (val < 0 || val2 < 0) | |
328 | return -ERANGE; | |
329 | ||
330 | ret = irsd200_read_data_rate(data, &data_rate); | |
331 | if (ret) | |
332 | return ret; | |
333 | ||
334 | /* Quantize from seconds. */ | |
335 | regval = val * data_rate + (val2 * data_rate) / 1000000; | |
336 | ||
337 | /* Value is 10 bits. */ | |
338 | if (regval >= BIT(10)) | |
339 | return -ERANGE; | |
340 | ||
341 | buf = cpu_to_le16((u16)regval); | |
342 | ||
343 | ret = regmap_bulk_write(data->regmap, IRS_REG_TIMER_LO, &buf, | |
344 | sizeof(buf)); | |
345 | if (ret) { | |
346 | dev_err(data->dev, "Could not bulk write timer (%d)\n", ret); | |
347 | return ret; | |
348 | } | |
349 | ||
350 | return 0; | |
351 | } | |
352 | ||
353 | static int irsd200_read_nr_count(struct irsd200_data *data, int *val) | |
354 | { | |
355 | unsigned int regval; | |
356 | int ret; | |
357 | ||
358 | ret = regmap_read(data->regmap, IRS_REG_NR_COUNT, ®val); | |
359 | if (ret) { | |
360 | dev_err(data->dev, "Could not read nr count (%d)\n", ret); | |
361 | return ret; | |
362 | } | |
363 | ||
364 | *val = regval; | |
365 | ||
366 | return 0; | |
367 | } | |
368 | ||
369 | static int irsd200_write_nr_count(struct irsd200_data *data, int val) | |
370 | { | |
371 | unsigned int regval; | |
372 | int ret; | |
373 | ||
374 | /* A value of zero means that IRS_REG_STATUS is never set. */ | |
375 | if (val <= 0 || val >= 8) | |
376 | return -ERANGE; | |
377 | ||
378 | regval = val; | |
379 | ||
380 | if (regval >= 2) { | |
381 | /* | |
382 | * According to the data sheet, timer must be also set in this | |
383 | * case (i.e. be non-zero). Check and enforce that. | |
384 | */ | |
385 | ret = irsd200_read_timer(data, &val, &val); | |
386 | if (ret) | |
387 | return ret; | |
388 | ||
389 | if (val == 0) { | |
390 | dev_err(data->dev, | |
391 | "Timer must be non-zero when nr count is %u\n", | |
392 | regval); | |
393 | return -EPERM; | |
394 | } | |
395 | } | |
396 | ||
397 | ret = regmap_write(data->regmap, IRS_REG_NR_COUNT, regval); | |
398 | if (ret) { | |
399 | dev_err(data->dev, "Could not write nr count (%d)\n", ret); | |
400 | return ret; | |
401 | } | |
402 | ||
403 | return 0; | |
404 | } | |
405 | ||
406 | static int irsd200_read_lp_filter(struct irsd200_data *data, int *val) | |
407 | { | |
408 | unsigned int regval; | |
409 | int ret; | |
410 | ||
411 | ret = regmap_field_read(data->regfields[IRS_REGF_LP_FILTER], ®val); | |
412 | if (ret) { | |
413 | dev_err(data->dev, "Could not read lp filter frequency (%d)\n", | |
414 | ret); | |
415 | return ret; | |
416 | } | |
417 | ||
418 | *val = irsd200_lp_filter_freq[regval]; | |
419 | ||
420 | return 0; | |
421 | } | |
422 | ||
423 | static int irsd200_write_lp_filter(struct irsd200_data *data, int val) | |
424 | { | |
425 | size_t idx; | |
426 | int ret; | |
427 | ||
428 | for (idx = 0; idx < ARRAY_SIZE(irsd200_lp_filter_freq); ++idx) { | |
429 | if (irsd200_lp_filter_freq[idx] == val) | |
430 | break; | |
431 | } | |
432 | ||
433 | if (idx == ARRAY_SIZE(irsd200_lp_filter_freq)) | |
434 | return -ERANGE; | |
435 | ||
436 | ret = regmap_field_write(data->regfields[IRS_REGF_LP_FILTER], idx); | |
437 | if (ret) { | |
438 | dev_err(data->dev, "Could not write lp filter frequency (%d)\n", | |
439 | ret); | |
440 | return ret; | |
441 | } | |
442 | ||
443 | return 0; | |
444 | } | |
445 | ||
446 | static int irsd200_read_hp_filter(struct irsd200_data *data, int *val, | |
447 | int *val2) | |
448 | { | |
449 | unsigned int regval; | |
450 | int ret; | |
451 | ||
452 | ret = regmap_field_read(data->regfields[IRS_REGF_HP_FILTER], ®val); | |
453 | if (ret) { | |
454 | dev_err(data->dev, "Could not read hp filter frequency (%d)\n", | |
455 | ret); | |
456 | return ret; | |
457 | } | |
458 | ||
459 | *val = irsd200_hp_filter_freq[regval][0]; | |
460 | *val2 = irsd200_hp_filter_freq[regval][1]; | |
461 | ||
462 | return 0; | |
463 | } | |
464 | ||
465 | static int irsd200_write_hp_filter(struct irsd200_data *data, int val, int val2) | |
466 | { | |
467 | size_t idx; | |
468 | int ret; | |
469 | ||
470 | /* Truncate fractional part to one digit. */ | |
471 | val2 /= 100000; | |
472 | ||
473 | for (idx = 0; idx < ARRAY_SIZE(irsd200_hp_filter_freq); ++idx) { | |
474 | if (irsd200_hp_filter_freq[idx][0] == val2) | |
475 | break; | |
476 | } | |
477 | ||
478 | if (idx == ARRAY_SIZE(irsd200_hp_filter_freq) || val != 0) | |
479 | return -ERANGE; | |
480 | ||
481 | ret = regmap_field_write(data->regfields[IRS_REGF_HP_FILTER], idx); | |
482 | if (ret) { | |
483 | dev_err(data->dev, "Could not write hp filter frequency (%d)\n", | |
484 | ret); | |
485 | return ret; | |
486 | } | |
487 | ||
488 | return 0; | |
489 | } | |
490 | ||
491 | static int irsd200_read_raw(struct iio_dev *indio_dev, | |
492 | struct iio_chan_spec const *chan, int *val, | |
493 | int *val2, long mask) | |
494 | { | |
495 | struct irsd200_data *data = iio_priv(indio_dev); | |
496 | int ret; | |
497 | s16 buf; | |
498 | ||
499 | switch (mask) { | |
500 | case IIO_CHAN_INFO_RAW: | |
501 | ret = irsd200_read_data(data, &buf); | |
502 | if (ret) | |
503 | return ret; | |
504 | ||
505 | *val = buf; | |
506 | return IIO_VAL_INT; | |
507 | case IIO_CHAN_INFO_SAMP_FREQ: | |
508 | ret = irsd200_read_data_rate(data, val); | |
509 | if (ret) | |
510 | return ret; | |
511 | ||
512 | return IIO_VAL_INT; | |
513 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: | |
514 | ret = irsd200_read_lp_filter(data, val); | |
515 | if (ret) | |
516 | return ret; | |
517 | ||
518 | return IIO_VAL_INT; | |
519 | case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: | |
520 | ret = irsd200_read_hp_filter(data, val, val2); | |
521 | if (ret) | |
522 | return ret; | |
523 | ||
524 | return IIO_VAL_FRACTIONAL; | |
525 | default: | |
526 | return -EINVAL; | |
527 | } | |
528 | } | |
529 | ||
530 | static int irsd200_read_avail(struct iio_dev *indio_dev, | |
531 | struct iio_chan_spec const *chan, | |
532 | const int **vals, int *type, int *length, | |
533 | long mask) | |
534 | { | |
535 | switch (mask) { | |
536 | case IIO_CHAN_INFO_SAMP_FREQ: | |
537 | *vals = irsd200_data_rates; | |
538 | *type = IIO_VAL_INT; | |
539 | *length = ARRAY_SIZE(irsd200_data_rates); | |
540 | return IIO_AVAIL_LIST; | |
541 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: | |
542 | *vals = irsd200_lp_filter_freq; | |
543 | *type = IIO_VAL_INT; | |
544 | *length = ARRAY_SIZE(irsd200_lp_filter_freq); | |
545 | return IIO_AVAIL_LIST; | |
546 | case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: | |
547 | *vals = (int *)irsd200_hp_filter_freq; | |
548 | *type = IIO_VAL_FRACTIONAL; | |
549 | *length = 2 * ARRAY_SIZE(irsd200_hp_filter_freq); | |
550 | return IIO_AVAIL_LIST; | |
551 | default: | |
552 | return -EINVAL; | |
553 | } | |
554 | } | |
555 | ||
556 | static int irsd200_write_raw(struct iio_dev *indio_dev, | |
557 | struct iio_chan_spec const *chan, int val, | |
558 | int val2, long mask) | |
559 | { | |
560 | struct irsd200_data *data = iio_priv(indio_dev); | |
561 | ||
562 | switch (mask) { | |
563 | case IIO_CHAN_INFO_SAMP_FREQ: | |
564 | return irsd200_write_data_rate(data, val); | |
565 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: | |
566 | return irsd200_write_lp_filter(data, val); | |
567 | case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: | |
568 | return irsd200_write_hp_filter(data, val, val2); | |
569 | default: | |
570 | return -EINVAL; | |
571 | } | |
572 | } | |
573 | ||
574 | static int irsd200_read_event(struct iio_dev *indio_dev, | |
575 | const struct iio_chan_spec *chan, | |
576 | enum iio_event_type type, | |
577 | enum iio_event_direction dir, | |
578 | enum iio_event_info info, int *val, int *val2) | |
579 | { | |
580 | struct irsd200_data *data = iio_priv(indio_dev); | |
581 | int ret; | |
582 | ||
583 | switch (info) { | |
584 | case IIO_EV_INFO_VALUE: | |
585 | ret = irsd200_read_threshold(data, dir, val); | |
586 | if (ret) | |
587 | return ret; | |
588 | ||
589 | return IIO_VAL_INT; | |
590 | case IIO_EV_INFO_RUNNING_PERIOD: | |
591 | ret = irsd200_read_timer(data, val, val2); | |
592 | if (ret) | |
593 | return ret; | |
594 | ||
595 | return IIO_VAL_FRACTIONAL; | |
596 | case IIO_EV_INFO_RUNNING_COUNT: | |
597 | ret = irsd200_read_nr_count(data, val); | |
598 | if (ret) | |
599 | return ret; | |
600 | ||
601 | return IIO_VAL_INT; | |
602 | default: | |
603 | return -EINVAL; | |
604 | } | |
605 | } | |
606 | ||
607 | static int irsd200_write_event(struct iio_dev *indio_dev, | |
608 | const struct iio_chan_spec *chan, | |
609 | enum iio_event_type type, | |
610 | enum iio_event_direction dir, | |
611 | enum iio_event_info info, int val, int val2) | |
612 | { | |
613 | struct irsd200_data *data = iio_priv(indio_dev); | |
614 | ||
615 | switch (info) { | |
616 | case IIO_EV_INFO_VALUE: | |
617 | return irsd200_write_threshold(data, dir, val); | |
618 | case IIO_EV_INFO_RUNNING_PERIOD: | |
619 | return irsd200_write_timer(data, val, val2); | |
620 | case IIO_EV_INFO_RUNNING_COUNT: | |
621 | return irsd200_write_nr_count(data, val); | |
622 | default: | |
623 | return -EINVAL; | |
624 | } | |
625 | } | |
626 | ||
627 | static int irsd200_read_event_config(struct iio_dev *indio_dev, | |
628 | const struct iio_chan_spec *chan, | |
629 | enum iio_event_type type, | |
630 | enum iio_event_direction dir) | |
631 | { | |
632 | struct irsd200_data *data = iio_priv(indio_dev); | |
633 | unsigned int val; | |
634 | int ret; | |
635 | ||
636 | switch (type) { | |
637 | case IIO_EV_TYPE_THRESH: | |
638 | ret = regmap_field_read( | |
639 | data->regfields[IRS_REGF_INTR_COUNT_THR_OR], &val); | |
640 | if (ret) | |
641 | return ret; | |
642 | ||
643 | return val; | |
644 | default: | |
645 | return -EINVAL; | |
646 | } | |
647 | } | |
648 | ||
649 | static int irsd200_write_event_config(struct iio_dev *indio_dev, | |
650 | const struct iio_chan_spec *chan, | |
651 | enum iio_event_type type, | |
652 | enum iio_event_direction dir, int state) | |
653 | { | |
654 | struct irsd200_data *data = iio_priv(indio_dev); | |
655 | unsigned int tmp; | |
656 | int ret; | |
657 | ||
658 | switch (type) { | |
659 | case IIO_EV_TYPE_THRESH: | |
660 | /* Clear the count register (by reading from it). */ | |
661 | ret = regmap_read(data->regmap, IRS_REG_COUNT, &tmp); | |
662 | if (ret) | |
663 | return ret; | |
664 | ||
665 | return regmap_field_write( | |
666 | data->regfields[IRS_REGF_INTR_COUNT_THR_OR], !!state); | |
667 | default: | |
668 | return -EINVAL; | |
669 | } | |
670 | } | |
671 | ||
672 | static irqreturn_t irsd200_irq_thread(int irq, void *dev_id) | |
673 | { | |
674 | struct iio_dev *indio_dev = dev_id; | |
675 | struct irsd200_data *data = iio_priv(indio_dev); | |
676 | enum iio_event_direction dir; | |
677 | unsigned int lower_count; | |
678 | unsigned int upper_count; | |
679 | unsigned int status = 0; | |
680 | unsigned int source = 0; | |
681 | unsigned int clear = 0; | |
682 | unsigned int count = 0; | |
683 | int ret; | |
684 | ||
685 | ret = regmap_read(data->regmap, IRS_REG_INTR, &source); | |
686 | if (ret) { | |
687 | dev_err(data->dev, "Could not read interrupt source (%d)\n", | |
688 | ret); | |
689 | return IRQ_HANDLED; | |
690 | } | |
691 | ||
692 | ret = regmap_read(data->regmap, IRS_REG_STATUS, &status); | |
693 | if (ret) { | |
694 | dev_err(data->dev, "Could not acknowledge interrupt (%d)\n", | |
695 | ret); | |
696 | return IRQ_HANDLED; | |
697 | } | |
698 | ||
699 | if (status & BIT(IRS_INTR_DATA) && iio_buffer_enabled(indio_dev)) { | |
700 | iio_trigger_poll_nested(indio_dev->trig); | |
701 | clear |= BIT(IRS_INTR_DATA); | |
702 | } | |
703 | ||
704 | if (status & BIT(IRS_INTR_COUNT_THR_OR) && | |
705 | source & BIT(IRS_INTR_COUNT_THR_OR)) { | |
706 | /* | |
707 | * The register value resets to zero after reading. We therefore | |
708 | * need to read once and manually extract the lower and upper | |
709 | * count register fields. | |
710 | */ | |
711 | ret = regmap_read(data->regmap, IRS_REG_COUNT, &count); | |
712 | if (ret) | |
713 | dev_err(data->dev, "Could not read count (%d)\n", ret); | |
714 | ||
715 | upper_count = IRS_UPPER_COUNT(count); | |
716 | lower_count = IRS_LOWER_COUNT(count); | |
717 | ||
718 | /* | |
719 | * We only check the OR mode to be able to push events for | |
720 | * rising and falling thresholds. AND mode is covered when both | |
721 | * upper and lower count is non-zero, and is signaled with | |
722 | * IIO_EV_DIR_EITHER. | |
723 | */ | |
724 | if (upper_count && !lower_count) | |
725 | dir = IIO_EV_DIR_RISING; | |
726 | else if (!upper_count && lower_count) | |
727 | dir = IIO_EV_DIR_FALLING; | |
728 | else | |
729 | dir = IIO_EV_DIR_EITHER; | |
730 | ||
731 | iio_push_event(indio_dev, | |
732 | IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0, | |
733 | IIO_EV_TYPE_THRESH, dir), | |
734 | iio_get_time_ns(indio_dev)); | |
735 | ||
736 | /* | |
737 | * The OR mode will always trigger when the AND mode does, but | |
738 | * not vice versa. However, it seems like the AND bit needs to | |
739 | * be cleared if data capture _and_ threshold count interrupts | |
740 | * are desirable, even though it hasn't explicitly been selected | |
741 | * (with IRS_REG_INTR). Either way, it doesn't hurt... | |
742 | */ | |
743 | clear |= BIT(IRS_INTR_COUNT_THR_OR) | | |
744 | BIT(IRS_INTR_COUNT_THR_AND); | |
745 | } | |
746 | ||
747 | if (!clear) | |
748 | return IRQ_NONE; | |
749 | ||
750 | ret = regmap_write(data->regmap, IRS_REG_STATUS, clear); | |
751 | if (ret) | |
752 | dev_err(data->dev, | |
753 | "Could not clear interrupt status (%d)\n", ret); | |
754 | ||
755 | return IRQ_HANDLED; | |
756 | } | |
757 | ||
758 | static irqreturn_t irsd200_trigger_handler(int irq, void *pollf) | |
759 | { | |
760 | struct iio_dev *indio_dev = ((struct iio_poll_func *)pollf)->indio_dev; | |
761 | struct irsd200_data *data = iio_priv(indio_dev); | |
ea191d0f | 762 | s64 buf[2] = {}; |
3db3562b WH |
763 | int ret; |
764 | ||
ea191d0f | 765 | ret = irsd200_read_data(data, (s16 *)buf); |
3db3562b WH |
766 | if (ret) |
767 | goto end; | |
768 | ||
ea191d0f | 769 | iio_push_to_buffers_with_timestamp(indio_dev, buf, |
3db3562b WH |
770 | iio_get_time_ns(indio_dev)); |
771 | ||
772 | end: | |
773 | iio_trigger_notify_done(indio_dev->trig); | |
774 | ||
775 | return IRQ_HANDLED; | |
776 | } | |
777 | ||
778 | static int irsd200_set_trigger_state(struct iio_trigger *trig, bool state) | |
779 | { | |
780 | struct irsd200_data *data = iio_trigger_get_drvdata(trig); | |
781 | int ret; | |
782 | ||
783 | ret = regmap_field_write(data->regfields[IRS_REGF_INTR_DATA], state); | |
784 | if (ret) { | |
785 | dev_err(data->dev, "Could not %s data interrupt source (%d)\n", | |
786 | state ? "enable" : "disable", ret); | |
787 | } | |
788 | ||
789 | return ret; | |
790 | } | |
791 | ||
792 | static const struct iio_info irsd200_info = { | |
793 | .read_raw = irsd200_read_raw, | |
794 | .read_avail = irsd200_read_avail, | |
795 | .write_raw = irsd200_write_raw, | |
796 | .read_event_value = irsd200_read_event, | |
797 | .write_event_value = irsd200_write_event, | |
798 | .read_event_config = irsd200_read_event_config, | |
799 | .write_event_config = irsd200_write_event_config, | |
800 | }; | |
801 | ||
802 | static const struct iio_trigger_ops irsd200_trigger_ops = { | |
803 | .set_trigger_state = irsd200_set_trigger_state, | |
804 | .validate_device = iio_trigger_validate_own_device, | |
805 | }; | |
806 | ||
807 | static const struct iio_event_spec irsd200_event_spec[] = { | |
808 | { | |
809 | .type = IIO_EV_TYPE_THRESH, | |
810 | .dir = IIO_EV_DIR_RISING, | |
811 | .mask_separate = BIT(IIO_EV_INFO_VALUE), | |
812 | }, | |
813 | { | |
814 | .type = IIO_EV_TYPE_THRESH, | |
815 | .dir = IIO_EV_DIR_FALLING, | |
816 | .mask_separate = BIT(IIO_EV_INFO_VALUE), | |
817 | }, | |
818 | { | |
819 | .type = IIO_EV_TYPE_THRESH, | |
820 | .dir = IIO_EV_DIR_EITHER, | |
821 | .mask_separate = | |
822 | BIT(IIO_EV_INFO_RUNNING_PERIOD) | | |
823 | BIT(IIO_EV_INFO_RUNNING_COUNT) | | |
824 | BIT(IIO_EV_INFO_ENABLE), | |
825 | }, | |
826 | }; | |
827 | ||
828 | static const struct iio_chan_spec irsd200_channels[] = { | |
829 | { | |
830 | .type = IIO_PROXIMITY, | |
831 | .info_mask_separate = | |
832 | BIT(IIO_CHAN_INFO_RAW) | | |
833 | BIT(IIO_CHAN_INFO_SAMP_FREQ) | | |
834 | BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | | |
835 | BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), | |
836 | .info_mask_separate_available = | |
837 | BIT(IIO_CHAN_INFO_SAMP_FREQ) | | |
838 | BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | | |
839 | BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), | |
840 | .event_spec = irsd200_event_spec, | |
841 | .num_event_specs = ARRAY_SIZE(irsd200_event_spec), | |
842 | .scan_type = { | |
843 | .sign = 's', | |
844 | .realbits = 16, | |
845 | .storagebits = 16, | |
846 | .endianness = IIO_CPU, | |
847 | }, | |
848 | }, | |
849 | }; | |
850 | ||
851 | static int irsd200_probe(struct i2c_client *client) | |
852 | { | |
853 | struct iio_trigger *trigger; | |
854 | struct irsd200_data *data; | |
855 | struct iio_dev *indio_dev; | |
856 | size_t i; | |
857 | int ret; | |
858 | ||
859 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); | |
860 | if (!indio_dev) | |
861 | return dev_err_probe(&client->dev, -ENOMEM, | |
862 | "Could not allocate iio device\n"); | |
863 | ||
864 | data = iio_priv(indio_dev); | |
865 | data->dev = &client->dev; | |
866 | ||
867 | data->regmap = devm_regmap_init_i2c(client, &irsd200_regmap_config); | |
868 | if (IS_ERR(data->regmap)) | |
869 | return dev_err_probe(data->dev, PTR_ERR(data->regmap), | |
870 | "Could not initialize regmap\n"); | |
871 | ||
872 | for (i = 0; i < IRS_REGF_MAX; ++i) { | |
873 | data->regfields[i] = devm_regmap_field_alloc( | |
874 | data->dev, data->regmap, irsd200_regfields[i]); | |
875 | if (IS_ERR(data->regfields[i])) | |
876 | return dev_err_probe( | |
877 | data->dev, PTR_ERR(data->regfields[i]), | |
878 | "Could not allocate register field %zu\n", i); | |
879 | } | |
880 | ||
881 | ret = devm_regulator_get_enable(data->dev, "vdd"); | |
882 | if (ret) | |
883 | return dev_err_probe( | |
884 | data->dev, ret, | |
885 | "Could not get and enable regulator (%d)\n", ret); | |
886 | ||
887 | ret = irsd200_setup(data); | |
888 | if (ret) | |
889 | return ret; | |
890 | ||
891 | indio_dev->info = &irsd200_info; | |
892 | indio_dev->name = IRS_DRV_NAME; | |
893 | indio_dev->channels = irsd200_channels; | |
894 | indio_dev->num_channels = ARRAY_SIZE(irsd200_channels); | |
895 | indio_dev->modes = INDIO_DIRECT_MODE; | |
896 | ||
897 | if (!client->irq) | |
898 | return dev_err_probe(data->dev, -ENXIO, "No irq available\n"); | |
899 | ||
900 | ret = devm_iio_triggered_buffer_setup(data->dev, indio_dev, NULL, | |
901 | irsd200_trigger_handler, NULL); | |
902 | if (ret) | |
903 | return dev_err_probe( | |
904 | data->dev, ret, | |
905 | "Could not setup iio triggered buffer (%d)\n", ret); | |
906 | ||
907 | ret = devm_request_threaded_irq(data->dev, client->irq, NULL, | |
908 | irsd200_irq_thread, | |
909 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | |
910 | NULL, indio_dev); | |
911 | if (ret) | |
912 | return dev_err_probe(data->dev, ret, | |
913 | "Could not request irq (%d)\n", ret); | |
914 | ||
915 | trigger = devm_iio_trigger_alloc(data->dev, "%s-dev%d", indio_dev->name, | |
916 | iio_device_id(indio_dev)); | |
917 | if (!trigger) | |
918 | return dev_err_probe(data->dev, -ENOMEM, | |
919 | "Could not allocate iio trigger\n"); | |
920 | ||
921 | trigger->ops = &irsd200_trigger_ops; | |
922 | iio_trigger_set_drvdata(trigger, data); | |
923 | ||
924 | ret = devm_iio_trigger_register(data->dev, trigger); | |
925 | if (ret) | |
926 | return dev_err_probe(data->dev, ret, | |
927 | "Could not register iio trigger (%d)\n", | |
928 | ret); | |
929 | ||
930 | ret = devm_iio_device_register(data->dev, indio_dev); | |
931 | if (ret) | |
932 | return dev_err_probe(data->dev, ret, | |
933 | "Could not register iio device (%d)\n", | |
934 | ret); | |
935 | ||
936 | return 0; | |
937 | } | |
938 | ||
939 | static const struct of_device_id irsd200_of_match[] = { | |
940 | { | |
941 | .compatible = "murata,irsd200", | |
942 | }, | |
943 | {} | |
944 | }; | |
945 | MODULE_DEVICE_TABLE(of, irsd200_of_match); | |
946 | ||
947 | static struct i2c_driver irsd200_driver = { | |
948 | .driver = { | |
949 | .name = IRS_DRV_NAME, | |
950 | .of_match_table = irsd200_of_match, | |
951 | }, | |
952 | .probe = irsd200_probe, | |
953 | }; | |
954 | module_i2c_driver(irsd200_driver); | |
955 | ||
956 | MODULE_AUTHOR("Waqar Hameed <waqar.hameed@axis.com>"); | |
957 | MODULE_DESCRIPTION("Murata IRS-D200 PIR sensor driver"); | |
958 | MODULE_LICENSE("GPL"); |