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