1 /*
2  * Copyright 2023 Daniel DeGrasse <daniel@degrasse.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef _DRIVERS_SENSOR_TCN75A_H_
8 #define _DRIVERS_SENSOR_TCN75A_H_
9 
10 #include <zephyr/drivers/gpio.h>
11 #include <zephyr/drivers/i2c.h>
12 #include <zephyr/drivers/sensor.h>
13 #include <zephyr/sys/byteorder.h>
14 
15 #define TCN75A_TEMP_REG	  0x0
16 #define TCN75A_CONFIG_REG 0x1
17 #define TCN75A_THYST_REG  0x2
18 #define TCN75A_TSET_REG	  0x3
19 
20 /* TCN75A TEMP register constants */
21 #define TCN75A_TEMP_MSB_POS  8
22 #define TCN75A_TEMP_MSB_MASK 0xFF00
23 #define TCN75A_TEMP_LSB_MASK 0xFF
24 #define TCN75A_TEMP_LSB_POS  0
25 
26 /* TCN75A CONFIG register constants */
27 #define TCN75A_CONFIG_ONEDOWN	BIT(7)
28 #define TCN75A_CONFIG_RES(x)    (((x) & 0x3) << 5)
29 #define TCN75A_CONFIG_INT_EN	0x2
30 #define TCN75A_CONFIG_SHUTDOWN	0x1
31 
32 struct tcn75a_config {
33 	struct i2c_dt_spec i2c_spec;
34 	bool oneshot_mode;
35 	uint8_t resolution;
36 #ifdef CONFIG_TCN75A_TRIGGER
37 	struct gpio_dt_spec alert_gpios;
38 #endif
39 };
40 
41 struct tcn75a_data {
42 	uint16_t temp_sample;
43 #ifdef CONFIG_TCN75A_TRIGGER
44 	const struct device *dev;
45 	struct gpio_callback gpio_cb;
46 	sensor_trigger_handler_t sensor_cb;
47 	const struct sensor_trigger *sensor_trig;
48 #endif
49 #ifdef CONFIG_TCN75A_TRIGGER_GLOBAL_THREAD
50 	struct k_work work;
51 #endif
52 #ifdef CONFIG_TCN75A_TRIGGER_OWN_THREAD
53 	K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_TCN75A_THREAD_STACK_SIZE);
54 	struct k_thread thread;
55 	struct k_sem trig_sem;
56 #endif
57 };
58 
59 /* Helpers to convert from TCN75A temperature fixed point format
60  * to sensor val2 format. When the LSB of the TCN75A temperature sample
61  * is treated as an integer, the format to convert to sensor val2 is
62  * FIXED_POINT_VAL * 3906.25
63  */
64 #define TCN75A_FIXED_PT_TO_SENSOR(x) (((x)*3906) + ((x) >> 2))
65 /* This conversion is imprecise, but because the 4 least significant bits
66  * of the temperature register aren't used, it doesn't matter.
67  */
68 #define TCN75A_SENSOR_TO_FIXED_PT(x) ((x) / 3906)
69 
70 #ifdef CONFIG_TCN75A_TRIGGER
71 
72 int tcn75a_trigger_init(const struct device *dev);
73 int tcn75a_attr_get(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr,
74 		    struct sensor_value *val);
75 
76 int tcn75a_attr_set(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr,
77 		    const struct sensor_value *val);
78 int tcn75a_trigger_set(const struct device *dev, const struct sensor_trigger *trig,
79 		       sensor_trigger_handler_t handler);
80 #endif
81 int tcn75a_sample_fetch(const struct device *dev, enum sensor_channel chan);
82 
83 #endif /* _DRIVERS_SENSOR_TCN75A_H_ */
84