1 /*
2 * Copyright (c) 2021 Jimmy Johnson <catch22@fastmail.net>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/drivers/sensor.h>
8 #include <zephyr/logging/log.h>
9 #include <zephyr/kernel.h>
10
11 #include "tmp108.h"
12
13 #define TMP108_ONE_SHOT_RETRY_TIME_IN_MS 10
14
15 LOG_MODULE_DECLARE(TMP108, CONFIG_SENSOR_LOG_LEVEL);
16
tmp108_trigger_handle_one_shot(struct k_work * work)17 void tmp108_trigger_handle_one_shot(struct k_work *work)
18 {
19 struct k_work_delayable *delayable_work = k_work_delayable_from_work(work);
20 struct tmp108_data *drv_data = CONTAINER_OF(delayable_work,
21 struct tmp108_data,
22 scheduled_work);
23
24 uint16_t config = 0;
25 bool shutdown_mode = false;
26
27 tmp108_reg_read(drv_data->tmp108_dev, TI_TMP108_REG_CONF, &config);
28
29 /* check shutdown mode which indicates a one shot read was successful */
30 shutdown_mode = (config & (TI_TMP108_CONF_M1(drv_data->tmp108_dev) |
31 TI_TMP108_CONF_M0(drv_data->tmp108_dev))) == 0;
32
33 if (shutdown_mode == true) {
34 ti_tmp108_read_temp(drv_data->tmp108_dev);
35 } else {
36 LOG_ERR("Temperature one shot mode read failed, retrying");
37 /* Wait for typical wake up time, retry if the read fails
38 * assuming the chip should wake up and take a reading after the typical
39 * wake up time and call of this thread plus 10 ms time has passed
40 */
41 k_work_reschedule(&drv_data->scheduled_work,
42 K_MSEC(TMP108_ONE_SHOT_RETRY_TIME_IN_MS));
43 return;
44 }
45
46 /* Successful read, call set callbacks */
47 if (drv_data->data_ready_handler) {
48 drv_data->data_ready_handler(drv_data->tmp108_dev,
49 drv_data->data_ready_trigger);
50 }
51 }
52
tmp108_trigger_handle_alert(const struct device * gpio,struct gpio_callback * cb,gpio_port_pins_t pins)53 void tmp108_trigger_handle_alert(const struct device *gpio,
54 struct gpio_callback *cb,
55 gpio_port_pins_t pins)
56 {
57
58 struct tmp108_data *drv_data = CONTAINER_OF(cb,
59 struct tmp108_data,
60 temp_alert_gpio_cb);
61
62 /* Successful read, call set callbacks */
63 if (drv_data->temp_alert_handler) {
64 drv_data->temp_alert_handler(drv_data->tmp108_dev,
65 drv_data->temp_alert_trigger);
66 }
67 }
68
tmp_108_trigger_set(const struct device * dev,const struct sensor_trigger * trig,sensor_trigger_handler_t handler)69 int tmp_108_trigger_set(const struct device *dev,
70 const struct sensor_trigger *trig,
71 sensor_trigger_handler_t handler)
72 {
73 struct tmp108_data *drv_data = dev->data;
74
75 if (trig->type == SENSOR_TRIG_DATA_READY) {
76 drv_data->data_ready_handler = handler;
77 drv_data->data_ready_trigger = trig;
78 return 0;
79 }
80
81 if (trig->type == SENSOR_TRIG_THRESHOLD) {
82 drv_data->temp_alert_handler = handler;
83 drv_data->temp_alert_trigger = trig;
84 return 0;
85 }
86
87 return -ENOTSUP;
88 }
89