1 /*
2  * Copyright (c) 2021 Jimmy Johnson <catch22@fastmail.net>
3  * Copyright (c) 2022 T-Mobile USA, Inc.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #ifndef ZEPHYR_DRIVERS_SENSOR_TMP108_TMP108_H_
9 #define ZEPHYR_DRIVERS_SENSOR_TMP108_TMP108_H_
10 
11 #include <stdint.h>
12 
13 #include <zephyr/drivers/i2c.h>
14 #include <zephyr/drivers/sensor.h>
15 #include <zephyr/drivers/gpio.h>
16 #include <zephyr/drivers/sensor/tmp108.h>
17 
18 #define TI_TMP108_REG_TEMP		0x00   /** Temperature register */
19 #define TI_TMP108_REG_CONF		0x01   /** Configuration register */
20 #define TI_TMP108_REG_LOW_LIMIT		0x02   /** Low alert set register */
21 #define TI_TMP108_REG_HIGH_LIMIT	0x03   /** High alert set register */
22 
23 #define AMS_AS6212_CONF	{.CONF_HYS1 = TI_TMP108_CONF_NA,\
24 			 .CONF_HYS0 = TI_TMP108_CONF_NA,\
25 			 .CONF_CR0  = 0x0040,	\
26 			 .CONF_CR1  = 0x0080,	\
27 			 .CONF_M1   = 0x0000,	\
28 			 .CONF_TM   = 0x0200,	\
29 			 .CONF_POL  = 0x0400,	\
30 			 .CONF_M0   = 0x8000,	\
31 			 .CONF_RST  = 0x0080,	\
32 			 .TEMP_MULT = 15625,	\
33 			 .TEMP_DIV  = 2,        \
34 			 .WAKEUP_TIME_IN_MS = 120 }
35 
36 #define TI_TMP108_CONF	{.CONF_HYS0  = 0x0010,	\
37 			 .CONF_HYS1  = 0x0020,	\
38 			 .CONF_POL   = 0x0080,	\
39 			 .CONF_M0    = 0x0100,	\
40 			 .CONF_M1    = 0x0200,	\
41 			 .CONF_TM    = 0x0400,	\
42 			 .CONF_CR0   = 0x2000,	\
43 			 .CONF_CR1   = 0x4000,	\
44 			 .CONF_RST   = 0x0022,	\
45 			 .TEMP_MULT  = 15625,	\
46 			 .TEMP_DIV   = 4,       \
47 			 .WAKEUP_TIME_IN_MS = 30 }
48 
49 #define TI_TMP108_MODE_SHUTDOWN(x) 0
50 #define TI_TMP108_MODE_ONE_SHOT(x) TI_TMP108_CONF_M0(x)
51 #define TI_TMP108_MODE_CONTINUOUS(x) TI_TMP108_CONF_M1(x)
52 #define TI_TMP108_MODE_MASK(x)	~(TI_TMP108_CONF_M0(x) | TI_TMP108_CONF_M1(x))
53 
54 #define TI_TMP108_FREQ_4_SECS(x) 0
55 #define TI_TMP108_FREQ_1_HZ(x) TI_TMP108_GET_CONF(x, CONF_CR0)
56 #define TI_TMP108_FREQ_4_HZ(x) TI_TMP108_GET_CONF(x, CONF_CR1)
57 #define TI_TMP108_FREQ_16_HZ(x)	(TI_TMP108_GET_CONF(x, CONF_CR1) | \
58 				TI_TMP108_GET_CONF(x, CONF_CR0))
59 #define TI_TMP108_FREQ_MASK(x)	~(TI_TMP108_GET_CONF(x, CONF_CR1) | \
60 				TI_TMP108_GET_CONF(x, CONF_CR0))
61 
62 #define TI_TMP108_CONF_POL_LOW(x) 0
63 #define TI_TMP108_CONF_POL_HIGH(x) TI_TMP108_GET_CONF(x, CONF_POL)
64 #define TI_TMP108_CONF_POL_MASK(x) ~(TI_TMP108_GET_CONF(x, CONF_POL))
65 
66 #define TI_TMP108_CONF_TM_CMP(x) 0
67 #define TI_TMP108_CONF_TM_INT(x) TI_TMP108_GET_CONF(x, CONF_TM)
68 #define TI_TMP108_CONF_TM_MASK(x) ~(TI_TMP108_GET_CONF(x, CONF_TM))
69 
70 #define TI_TMP108_HYSTER_0_C(x)	0
71 #define TI_TMP108_HYSTER_1_C(x)	TI_TMP108_GET_CONF(x, CONF_HYS0)
72 #define TI_TMP108_HYSTER_2_C(x)	TI_TMP108_GET_CONF(x, CONF_HYS1)
73 #define TI_TMP108_HYSTER_4_C(x)	(TI_TMP108_GET_CONF(x, CONF_HYS1) | \
74 				TI_TMP108_GET_CONF(x, CONF_HYS0))
75 #define TI_TMP108_HYSTER_MASK(x) ~(TI_TMP108_GET_CONF(x, CONF_HYS1) | \
76 				 TI_TMP108_GET_CONF(x, CONF_HYS0))
77 
78 #define TI_TMP108_CONF_M1(x) TI_TMP108_GET_CONF(x, CONF_M1)
79 #define TI_TMP108_CONF_M0(x) TI_TMP108_GET_CONF(x, CONF_M0)
80 
81 #define TMP108_TEMP_MULTIPLIER(x)	TI_TMP108_GET_CONF(x, TEMP_MULT)
82 #define TMP108_TEMP_DIVISOR(x)	TI_TMP108_GET_CONF(x, TEMP_DIV)
83 #define TMP108_WAKEUP_TIME_IN_MS(x)	TI_TMP108_GET_CONF(x, WAKEUP_TIME_IN_MS)
84 #define TMP108_CONF_RST(x)	TI_TMP108_GET_CONF(x, CONF_RST)
85 
86 #define TI_TMP108_CONF_NA 0x0000
87 
88 struct tmp_108_reg_def {
89 	uint16_t CONF_M0;	/** Mode 1 configuration bit */
90 	uint16_t CONF_M1;	/** Mode 2 configuration bit */
91 	uint16_t CONF_CR0;	/** Conversion rate 1 configuration bit */
92 	uint16_t CONF_CR1;	/** Conversion rate 2 configuration bit */
93 	uint16_t CONF_POL;	/** Alert pin Polarity configuration bit */
94 	uint16_t CONF_TM;	/** Thermostat mode setting bit */
95 	uint16_t CONF_HYS1;	/** Temperature hysteresis config 1 bit  */
96 	uint16_t CONF_HYS0;	/** Temperature hysteresis config 2 bit */
97 	int32_t TEMP_MULT;	/** Temperature multiplier */
98 	int32_t TEMP_DIV;	/** Temperature divisor */
99 	uint16_t WAKEUP_TIME_IN_MS; /** Wake up and conversion time from one shot */
100 	uint16_t CONF_RST;	/** default reset values on init */
101 };
102 
103 #define TI_TMP108_GET_CONF(x, cfg) ((struct tmp108_config *)(x->config))->reg_def.cfg
104 
105 struct tmp108_config {
106 	const struct i2c_dt_spec i2c_spec;
107 	const struct gpio_dt_spec alert_gpio;
108 	struct tmp_108_reg_def reg_def;
109 };
110 
111 struct tmp108_data {
112 	const struct device *tmp108_dev;
113 
114 	int16_t sample;
115 
116 	bool one_shot_mode;
117 
118 	struct k_work_delayable scheduled_work;
119 
120 	const struct sensor_trigger *temp_alert_trigger;
121 	sensor_trigger_handler_t temp_alert_handler;
122 
123 	sensor_trigger_handler_t data_ready_handler;
124 	const struct sensor_trigger *data_ready_trigger;
125 
126 	struct gpio_callback temp_alert_gpio_cb;
127 };
128 
129 int tmp_108_trigger_set(const struct device *dev,
130 			const struct sensor_trigger *trig,
131 			sensor_trigger_handler_t handler);
132 
133 int tmp108_reg_read(const struct device *dev, uint8_t reg, uint16_t *val);
134 
135 int ti_tmp108_read_temp(const struct device *dev);
136 void tmp108_trigger_handle_one_shot(struct k_work *work);
137 void tmp108_trigger_handle_alert(const struct device *port,
138 				 struct gpio_callback *cb,
139 				 gpio_port_pins_t pins);
140 
141 #endif /*  ZEPHYR_DRIVERS_SENSOR_TMP108_TMP108_H_ */
142