1 /*
2  * Copyright (c) 2023 Caspar Friedrich <c.s.w.friedrich@gmail.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_DRIVERS_W1_W1_DS2482_84_H_
8 #define ZEPHYR_DRIVERS_W1_W1_DS2482_84_H_
9 
10 #include <zephyr/drivers/i2c.h>
11 #include <zephyr/kernel.h>
12 
13 #define CMD_1WT	 0x78
14 #define CMD_1WSB 0x87
15 #define CMD_1WRB 0x96
16 #define CMD_1WWB 0xa5
17 #define CMD_1WRS 0xb4
18 #define CMD_CHSL 0xc3 /* DS2482-800 only */
19 #define CMD_ADJP 0xc3 /* DS2484 only */
20 #define CMD_WCFG 0xd2
21 #define CMD_SRP	 0xe1
22 #define CMD_DRST 0xf0
23 
24 #define REG_NONE    0x00 /* special value */
25 #define REG_CONFIG  0xc3
26 #define REG_DATA    0xe1
27 #define REG_STATUS  0xf0
28 #define REG_CHANNEL 0xd2 /* DS2482-800 only */
29 #define REG_PORT    0xb4 /* DS2484 only */
30 
31 /*
32  * Device Configuration Register
33  */
34 #define DEVICE_APU_pos 0
35 #define DEVICE_APU_msk BIT(DEVICE_APU_pos)
36 #define DEVICE_PDN_pos 1		   /* DS2484 only */
37 #define DEVICE_PDN_msk BIT(DEVICE_PDN_pos) /* DS2484 only */
38 #define DEVICE_SPU_pos 2
39 #define DEVICE_SPU_msk BIT(DEVICE_SPU_pos)
40 #define DEVICE_1WS_pos 3
41 #define DEVICE_1WS_msk BIT(DEVICE_1WS_pos)
42 
43 /*
44  * Status Register
45  */
46 #define STATUS_1WB_pos 0
47 #define STATUS_1WB_msk BIT(STATUS_1WB_pos)
48 #define STATUS_PPD_pos 1
49 #define STATUS_PPD_msk BIT(STATUS_PPD_pos)
50 #define STATUS_SD_pos  2
51 #define STATUS_SD_msk  BIT(STATUS_SD_pos)
52 #define STATUS_LL_pos  3
53 #define STATUS_LL_msk  BIT(STATUS_LL_pos)
54 #define STATUS_RST_pos 4
55 #define STATUS_RST_msk BIT(STATUS_RST_pos)
56 #define STATUS_SBR_pos 5
57 #define STATUS_SBR_msk BIT(STATUS_SBR_pos)
58 #define STATUS_TSB_pos 6
59 #define STATUS_TSB_msk BIT(STATUS_TSB_pos)
60 #define STATUS_DIR_pos 7
61 #define STATUS_DIR_msk BIT(STATUS_DIR_pos)
62 
63 /*
64  * Channel Selection Codes, DS2482-800 only
65  */
66 #define CHSL_IO0 0xf0
67 #define CHSL_IO1 0xe1
68 #define CHSL_IO2 0xd2
69 #define CHSL_IO3 0xc3
70 #define CHSL_IO4 0xb4
71 #define CHSL_IO5 0xa5
72 #define CHSL_IO6 0x96
73 #define CHSL_IO7 0x87
74 
75 /*
76  * Channel Selection Codes (read back values), DS2482-800 only
77  */
78 #define CHSL_RB_IO0 0xb8
79 #define CHSL_RB_IO1 0xb1
80 #define CHSL_RB_IO2 0xaa
81 #define CHSL_RB_IO3 0xa3
82 #define CHSL_RB_IO4 0x9c
83 #define CHSL_RB_IO5 0x95
84 #define CHSL_RB_IO6 0x8e
85 #define CHSL_RB_IO7 0x87
86 
87 /*
88  * Port Configuration Register, DS2484 only
89  */
90 #define PORT_VAL0_pos 0
91 #define PORT_VAL0_msk BIT(PORT_VAL0_pos)
92 #define PORT_VAL1_pos 1
93 #define PORT_VAL1_msk BIT(PORT_VAL1_pos)
94 #define PORT_VAL2_pos 2
95 #define PORT_VAL2_msk BIT(PORT_VAL2_pos)
96 #define PORT_VAL3_pos 3
97 #define PORT_VAL3_msk BIT(PORT_VAL3_pos)
98 
99 /*
100  * Bit Byte
101  */
102 #define BIT_CLR_msk 0
103 #define BIT_SET_msk BIT(7)
104 
ds2482_84_write(const struct i2c_dt_spec * spec,uint8_t cmd,const uint8_t * data)105 static inline int ds2482_84_write(const struct i2c_dt_spec *spec, uint8_t cmd, const uint8_t *data)
106 {
107 	int ret;
108 
109 	const uint8_t buf[] = {cmd, data ? *data : 0};
110 
111 	ret = i2c_write_dt(spec, buf, data ? 2 : 1);
112 	if (ret < 0) {
113 		return ret;
114 	}
115 
116 	return 0;
117 }
118 
ds2482_84_read(const struct i2c_dt_spec * spec,uint8_t rp,uint8_t * reg)119 static inline int ds2482_84_read(const struct i2c_dt_spec *spec, uint8_t rp, uint8_t *reg)
120 {
121 	int ret;
122 
123 	switch (rp) {
124 	case REG_NONE:
125 		/*
126 		 * Special value: Don't change read pointer
127 		 */
128 		break;
129 	case REG_PORT:
130 		__fallthrough;
131 	case REG_CONFIG:
132 		__fallthrough;
133 	case REG_CHANNEL:
134 		__fallthrough;
135 	case REG_DATA:
136 		__fallthrough;
137 	case REG_STATUS:
138 		ret = ds2482_84_write(spec, CMD_SRP, &rp);
139 		if (ret < 0) {
140 			return ret;
141 		}
142 		break;
143 	default:
144 		return -EINVAL;
145 	}
146 
147 	ret = i2c_read_dt(spec, reg, 1);
148 	if (ret < 0) {
149 		return ret;
150 	}
151 
152 	return 0;
153 }
154 
ds2482_84_reset_bus(const struct i2c_dt_spec * spec)155 static inline int ds2482_84_reset_bus(const struct i2c_dt_spec *spec)
156 {
157 	int ret;
158 
159 	uint8_t reg;
160 
161 	ret = ds2482_84_write(spec, CMD_1WRS, NULL);
162 	if (ret < 0) {
163 		return ret;
164 	}
165 
166 	do {
167 		ret = ds2482_84_read(spec, REG_NONE, &reg);
168 		if (ret < 0) {
169 			return ret;
170 		}
171 	} while (reg & STATUS_1WB_msk);
172 
173 	return reg & STATUS_PPD_msk ? 1 : 0;
174 }
175 
ds2482_84_reset_device(const struct i2c_dt_spec * spec)176 static inline int ds2482_84_reset_device(const struct i2c_dt_spec *spec)
177 {
178 	int ret;
179 
180 	uint8_t reg;
181 
182 	ret = ds2482_84_write(spec, CMD_DRST, NULL);
183 	if (ret < 0) {
184 		return ret;
185 	}
186 
187 	do {
188 		ret = ds2482_84_read(spec, REG_NONE, &reg);
189 		if (ret < 0) {
190 			return ret;
191 		}
192 	} while (!(reg & STATUS_RST_msk));
193 
194 	return 0;
195 }
196 
ds2482_84_single_bit(const struct i2c_dt_spec * spec,uint8_t bit_msk)197 static inline int ds2482_84_single_bit(const struct i2c_dt_spec *spec, uint8_t bit_msk)
198 {
199 	int ret;
200 
201 	uint8_t reg;
202 
203 	ret = ds2482_84_write(spec, CMD_1WSB, &bit_msk);
204 	if (ret < 0) {
205 		return ret;
206 	}
207 
208 	do {
209 		ret = ds2482_84_read(spec, REG_NONE, &reg);
210 		if (ret < 0) {
211 			return ret;
212 		}
213 	} while (reg & STATUS_1WB_msk);
214 
215 	return reg & STATUS_SBR_msk ? 1 : 0;
216 }
217 
ds2482_84_read_bit(const struct i2c_dt_spec * spec)218 static inline int ds2482_84_read_bit(const struct i2c_dt_spec *spec)
219 {
220 	return ds2482_84_single_bit(spec, BIT_SET_msk);
221 }
222 
ds2482_84_write_bit(const struct i2c_dt_spec * spec,bool bit)223 static inline int ds2482_84_write_bit(const struct i2c_dt_spec *spec, bool bit)
224 {
225 	return ds2482_84_single_bit(spec, bit ? BIT_SET_msk : BIT_CLR_msk);
226 }
227 
ds2482_84_read_byte(const struct i2c_dt_spec * spec)228 static inline int ds2482_84_read_byte(const struct i2c_dt_spec *spec)
229 {
230 	int ret;
231 
232 	uint8_t reg;
233 
234 	ret = ds2482_84_write(spec, CMD_1WRB, NULL);
235 	if (ret < 0) {
236 		return ret;
237 	}
238 
239 	do {
240 		ret = ds2482_84_read(spec, REG_NONE, &reg);
241 		if (ret < 0) {
242 			return ret;
243 		}
244 	} while (reg & STATUS_1WB_msk);
245 
246 	ret = ds2482_84_read(spec, REG_DATA, &reg);
247 	if (ret < 0) {
248 		return ret;
249 	}
250 
251 	return reg;
252 }
253 
ds2482_84_write_byte(const struct i2c_dt_spec * spec,uint8_t byte)254 static inline int ds2482_84_write_byte(const struct i2c_dt_spec *spec, uint8_t byte)
255 {
256 	int ret;
257 
258 	uint8_t reg;
259 
260 	ret = ds2482_84_write(spec, CMD_1WWB, &byte);
261 	if (ret < 0) {
262 		return ret;
263 	}
264 
265 	do {
266 		ret = ds2482_84_read(spec, REG_NONE, &reg);
267 		if (ret < 0) {
268 			return ret;
269 		}
270 	} while (reg & STATUS_1WB_msk);
271 
272 	return 0;
273 }
274 
ds2482_84_write_config(const struct i2c_dt_spec * spec,uint8_t cfg)275 static inline int ds2482_84_write_config(const struct i2c_dt_spec *spec, uint8_t cfg)
276 {
277 	int ret;
278 
279 	uint8_t reg = cfg | ~cfg << 4;
280 
281 	if (cfg & ~(DEVICE_APU_msk | DEVICE_PDN_msk | DEVICE_SPU_msk | DEVICE_1WS_msk)) {
282 		return -EINVAL;
283 	}
284 
285 	ret = ds2482_84_write(spec, CMD_WCFG, &reg);
286 	if (ret < 0) {
287 		return ret;
288 	}
289 
290 	ret = ds2482_84_read(spec, REG_NONE, &reg);
291 	if (ret < 0) {
292 		return ret;
293 	}
294 
295 	return (reg == cfg) ? 0 : -EIO;
296 }
297 
298 #endif /* ZEPHYR_DRIVERS_W1_W1_DS2482_84_H_ */
299