1 /*
2  * Copyright (c) 2019 Peter Bigot Consulting, LLC
3  * Copyright (c) 2016 Intel Corporation
4  * Copyright (c) 2024 Vogl Electronic GmbH
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #ifndef ZEPHYR_DRIVERS_SENSOR_JEDEC_JC42_H_
10 #define ZEPHYR_DRIVERS_SENSOR_JEDEC_JC42_H_
11 
12 #include <errno.h>
13 
14 #include <zephyr/types.h>
15 #include <zephyr/device.h>
16 #include <zephyr/drivers/sensor.h>
17 #include <zephyr/sys/util.h>
18 #include <zephyr/drivers/i2c.h>
19 #include <zephyr/drivers/gpio.h>
20 
21 #define JC42_REG_CONFIG      0x01
22 #define JC42_REG_UPPER_LIMIT 0x02
23 #define JC42_REG_LOWER_LIMIT 0x03
24 #define JC42_REG_CRITICAL    0x04
25 #define JC42_REG_TEMP_AMB    0x05
26 
27 /* 16 bits control configuration and state.
28  *
29  * * Bit 0 controls alert signal output mode
30  * * Bit 1 controls interrupt polarity
31  * * Bit 2 disables upper and lower threshold checking
32  * * Bit 3 enables alert signal output
33  * * Bit 4 records alert status
34  * * Bit 5 records interrupt status
35  * * Bit 6 locks the upper/lower window registers
36  * * Bit 7 locks the critical register
37  * * Bit 8 enters shutdown mode
38  * * Bits 9-10 control threshold hysteresis
39  */
40 #define JC42_CFG_ALERT_MODE_INT BIT(0)
41 #define JC42_CFG_ALERT_ENA      BIT(3)
42 #define JC42_CFG_ALERT_STATE    BIT(4)
43 #define JC42_CFG_INT_CLEAR      BIT(5)
44 
45 /* 16 bits are used for temperature and state encoding:
46  * * Bits 0..11 encode the temperature in a 2s complement signed value
47  *   in Celsius with 1/16 Cel resolution
48  * * Bit 12 is set to indicate a negative temperature
49  * * Bit 13 is set to indicate a temperature below the lower threshold
50  * * Bit 14 is set to indicate a temperature above the upper threshold
51  * * Bit 15 is set to indicate a temperature above the critical threshold
52  */
53 #define JC42_TEMP_SCALE_CEL 16 /* signed */
54 #define JC42_TEMP_SIGN_BIT  BIT(12)
55 #define JC42_TEMP_ABS_MASK  ((uint16_t)(JC42_TEMP_SIGN_BIT - 1U))
56 #define JC42_TEMP_LWR_BIT   BIT(13)
57 #define JC42_TEMP_UPR_BIT   BIT(14)
58 #define JC42_TEMP_CRT_BIT   BIT(15)
59 
60 #define JC42_REG_RESOLUTION 0x08
61 
62 struct jc42_data {
63 	uint16_t reg_val;
64 
65 #ifdef CONFIG_JC42_TRIGGER
66 	struct gpio_callback alert_cb;
67 
68 	const struct device *dev;
69 
70 	const struct sensor_trigger *trig;
71 	sensor_trigger_handler_t trigger_handler;
72 #endif
73 
74 #ifdef CONFIG_JC42_TRIGGER_OWN_THREAD
75 	struct k_sem sem;
76 #endif
77 
78 #ifdef CONFIG_JC42_TRIGGER_GLOBAL_THREAD
79 	struct k_work work;
80 #endif
81 };
82 
83 struct jc42_config {
84 	struct i2c_dt_spec i2c;
85 	uint8_t resolution;
86 #ifdef CONFIG_JC42_TRIGGER
87 	struct gpio_dt_spec int_gpio;
88 #endif /* CONFIG_JC42_TRIGGER */
89 };
90 
91 int jc42_reg_read(const struct device *dev, uint8_t reg, uint16_t *val);
92 int jc42_reg_write_16bit(const struct device *dev, uint8_t reg, uint16_t val);
93 int jc42_reg_write_8bit(const struct device *dev, uint8_t reg, uint8_t val);
94 
95 #ifdef CONFIG_JC42_TRIGGER
96 int jc42_attr_set(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr,
97 		  const struct sensor_value *val);
98 int jc42_trigger_set(const struct device *dev, const struct sensor_trigger *trig,
99 		     sensor_trigger_handler_t handler);
100 int jc42_setup_interrupt(const struct device *dev);
101 #endif /* CONFIG_JC42_TRIGGER */
102 
103 /* Encode a signed temperature in scaled Celsius to the format used in
104  * register values.
105  */
jc42_temp_reg_from_signed(int temp)106 static inline uint16_t jc42_temp_reg_from_signed(int temp)
107 {
108 	/* Get the 12-bit 2s complement value */
109 	uint16_t rv = temp & JC42_TEMP_ABS_MASK;
110 
111 	if (temp < 0) {
112 		rv |= JC42_TEMP_SIGN_BIT;
113 	}
114 	return rv;
115 }
116 
117 /* Decode a register temperature value to a signed temperature in
118  * scaled Celsius.
119  */
jc42_temp_signed_from_reg(uint16_t reg)120 static inline int jc42_temp_signed_from_reg(uint16_t reg)
121 {
122 	int rv = reg & JC42_TEMP_ABS_MASK;
123 
124 	if (reg & JC42_TEMP_SIGN_BIT) {
125 		/* Convert 12-bit 2s complement to signed negative
126 		 * value.
127 		 */
128 		rv = -(1U + (rv ^ JC42_TEMP_ABS_MASK));
129 	}
130 	return rv;
131 }
132 
133 #endif /* ZEPHYR_DRIVERS_SENSOR_JEDEC_JC42_H_ */
134