1 /*
2  * Copyright (c) 2022 Thomas Stranger
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @brief Common functions for Maxim DS2477,DS2485 1-Wire Masters
9  */
10 
11 #include "w1_ds2477_85_common.h"
12 
13 #include <zephyr/drivers/i2c.h>
14 #include <zephyr/drivers/w1.h>
15 #include <zephyr/logging/log.h>
16 #include <zephyr/kernel.h>
17 
18 LOG_MODULE_REGISTER(w1_ds2477_85, CONFIG_W1_LOG_LEVEL);
19 
ds2477_85_write_port_config(const struct device * dev,uint8_t reg,uint16_t value)20 int ds2477_85_write_port_config(const struct device *dev, uint8_t reg, uint16_t value)
21 {
22 	const struct w1_ds2477_85_config *cfg = dev->config;
23 	uint8_t buf[5] = {CMD_WR_W1_PORT_CFG, CMD_WR_W1_PORT_CFG_LEN, reg};
24 	int ret;
25 
26 	__ASSERT_NO_MSG(reg <= PORT_REG_COUNT);
27 
28 	sys_put_le16(value, &buf[3]);
29 	ret = i2c_write_dt(&cfg->i2c_spec, buf, (CMD_WR_W1_PORT_CFG_LEN + CMD_OVERHEAD_LEN));
30 	if (ret < 0) {
31 		return ret;
32 	}
33 
34 	k_usleep(cfg->t_op_us);
35 
36 	ret = i2c_read_dt(&cfg->i2c_spec, buf, 2);
37 	if (ret < 0) {
38 		return ret;
39 	}
40 	if ((buf[0] != 1) || (buf[1] != DS2477_88_RES_SUCCESS)) {
41 		return -EIO;
42 	}
43 
44 	return 0;
45 }
46 
ds2477_85_read_port_config(const struct device * dev,uint8_t reg,uint16_t * value)47 int ds2477_85_read_port_config(const struct device *dev, uint8_t reg, uint16_t *value)
48 {
49 	const struct w1_ds2477_85_config *cfg = dev->config;
50 	uint8_t buf[4] = {CMD_RD_W1_PORT_CFG, CMD_RD_W1_PORT_CFG_LEN, reg};
51 	int ret;
52 
53 	__ASSERT_NO_MSG(value != NULL && reg <= PORT_REG_COUNT);
54 
55 	ret = i2c_write_dt(&cfg->i2c_spec, buf, (CMD_RD_W1_PORT_CFG_LEN + CMD_OVERHEAD_LEN));
56 	if (ret < 0) {
57 		return ret;
58 	}
59 
60 	k_usleep(cfg->t_op_us);
61 
62 	ret = i2c_read_dt(&cfg->i2c_spec, buf, 4);
63 	if (ret < 0) {
64 		return ret;
65 	}
66 	if ((buf[0] != 3) || (buf[1] != DS2477_88_RES_SUCCESS)) {
67 		return -EIO;
68 	}
69 
70 	*value = sys_get_le16(&buf[2]);
71 
72 	return 0;
73 }
74 
ds2477_85_reset_master(const struct device * dev)75 int ds2477_85_reset_master(const struct device *dev)
76 {
77 	const struct w1_ds2477_85_config *cfg = dev->config;
78 	uint8_t buf[2] = {CMD_MASTER_RESET};
79 	int ret;
80 
81 	ret = i2c_write_dt(&cfg->i2c_spec, buf, 1);
82 	if (ret < 0) {
83 		LOG_ERR("initiate reset failed");
84 		return ret;
85 	}
86 
87 	k_usleep(cfg->t_op_us);
88 
89 	ret = i2c_read_dt(&cfg->i2c_spec, buf, 2);
90 	if (ret < 0) {
91 		return ret;
92 	}
93 	if ((buf[0] != 1) || (buf[1] != DS2477_88_RES_SUCCESS)) {
94 		return -EIO;
95 	}
96 
97 	return 0;
98 }
99 
ds2477_85_reset_bus(const struct device * dev)100 int ds2477_85_reset_bus(const struct device *dev)
101 {
102 	const struct w1_ds2477_85_config *cfg = dev->config;
103 	struct w1_ds2477_85_data *data = dev->data;
104 	uint16_t delay_us = cfg->mode_timing[data->master_reg.od_active].t_reset;
105 	uint8_t tx_data;
106 	uint8_t rx_data;
107 	int ret;
108 
109 	tx_data = data->master_reg.od_active ? BIT(3) : BIT(7);
110 	ret = cfg->w1_script_cmd(dev, delay_us, SCRIPT_OW_RESET, &tx_data, 1, &rx_data, 1);
111 
112 	switch (ret) {
113 	case DS2477_88_RES_COMM_FAILURE:
114 		/* presence not detected */
115 		return 0;
116 	case DS2477_88_RES_SUCCESS:
117 		/* at least 1 device present */
118 		return 1;
119 	default:
120 		return -EIO;
121 	}
122 }
123 
ds2477_85_read_bit(const struct device * dev)124 int ds2477_85_read_bit(const struct device *dev)
125 {
126 	const struct w1_ds2477_85_config *cfg = dev->config;
127 	struct w1_ds2477_85_data *data = dev->data;
128 	uint16_t delay_us = cfg->mode_timing[data->master_reg.od_active].t_slot;
129 	uint8_t rx_data;
130 	int ret;
131 
132 	ret = cfg->w1_script_cmd(dev, delay_us, SCRIPT_OW_READ_BIT, NULL, 0, &rx_data, 1);
133 	if (ret != DS2477_88_RES_SUCCESS) {
134 		return -EIO;
135 	}
136 
137 	return (rx_data & BIT(5)) ? 1 : 0;
138 }
139 
ds2477_85_write_bit(const struct device * dev,const bool bit)140 int ds2477_85_write_bit(const struct device *dev, const bool bit)
141 {
142 	const struct w1_ds2477_85_config *cfg = dev->config;
143 	struct w1_ds2477_85_data *data = dev->data;
144 	uint16_t delay_us = cfg->mode_timing[data->master_reg.od_active].t_slot;
145 	uint8_t tx_data = (uint8_t)bit;
146 	uint8_t rx_data;
147 	int ret;
148 
149 	ret = cfg->w1_script_cmd(dev, delay_us, SCRIPT_OW_WRITE_BIT, &tx_data, 1, &rx_data, 1);
150 	if (ret != DS2477_88_RES_SUCCESS) {
151 		return -EIO;
152 	}
153 
154 	return 0;
155 }
156 
ds2477_85_read_byte(const struct device * dev)157 int ds2477_85_read_byte(const struct device *dev)
158 {
159 	const struct w1_ds2477_85_config *cfg = dev->config;
160 	struct w1_ds2477_85_data *data = dev->data;
161 	uint16_t delay_us = cfg->mode_timing[data->master_reg.od_active].t_slot * 8;
162 	uint8_t rx_data;
163 	int ret;
164 
165 	ret = cfg->w1_script_cmd(dev, delay_us, SCRIPT_OW_READ_BYTE, NULL, 0, &rx_data, 1);
166 	if (ret != DS2477_88_RES_SUCCESS) {
167 		return -EIO;
168 	}
169 
170 	return rx_data;
171 }
172 
ds2477_85_write_byte(const struct device * dev,const uint8_t tx_byte)173 int ds2477_85_write_byte(const struct device *dev, const uint8_t tx_byte)
174 {
175 	const struct w1_ds2477_85_config *cfg = dev->config;
176 	struct w1_ds2477_85_data *data = dev->data;
177 	uint16_t delay_us = cfg->mode_timing[data->master_reg.od_active].t_slot * 8;
178 	uint8_t rx_data;
179 	int ret;
180 
181 	ret = cfg->w1_script_cmd(dev, delay_us, SCRIPT_OW_WRITE_BYTE, &tx_byte, 1, &rx_data, 1);
182 	if (ret != DS2477_88_RES_SUCCESS) {
183 		return -EIO;
184 	}
185 
186 	return 0;
187 }
188 
ds2477_85_write_block(const struct device * dev,const uint8_t * buffer,size_t tx_len)189 int ds2477_85_write_block(const struct device *dev, const uint8_t *buffer, size_t tx_len)
190 {
191 	const struct w1_ds2477_85_config *cfg = dev->config;
192 	struct w1_ds2477_85_data *data = dev->data;
193 	int w1_timing = cfg->mode_timing[data->master_reg.od_active].t_slot * 8 * tx_len;
194 	uint8_t buf[3] = {CMD_WR_BLOCK, (tx_len + CMD_WR_BLOCK_LEN), 0};
195 	struct i2c_msg tx_msg[2] = {
196 		{.buf = buf, .len = (CMD_WR_BLOCK_LEN + CMD_OVERHEAD_LEN), .flags = I2C_MSG_WRITE},
197 		{.buf = (uint8_t *)buffer, .len = tx_len, .flags = (I2C_MSG_WRITE | I2C_MSG_STOP)},
198 	};
199 	int ret;
200 
201 	__ASSERT_NO_MSG(tx_len <= MAX_BLOCK_LEN);
202 
203 	if (tx_len == 0) {
204 		return 0;
205 	}
206 
207 	ret = i2c_transfer_dt(&cfg->i2c_spec, tx_msg, 2);
208 	if (ret < 0) {
209 		LOG_ERR("write block fail: %x", ret);
210 		return ret;
211 	}
212 
213 	k_usleep(cfg->t_op_us + (cfg->t_seq_us * tx_len) +  w1_timing);
214 
215 	ret = i2c_read_dt(&cfg->i2c_spec, buf, 2);
216 	if (ret < 0) {
217 		return ret;
218 	}
219 	if ((buf[0] != 1) || (buf[1] != DS2477_88_RES_SUCCESS)) {
220 		return -EIO;
221 	}
222 
223 	return 0;
224 }
225 
ds2477_85_read_block(const struct device * dev,uint8_t * buffer,size_t rx_len)226 int ds2477_85_read_block(const struct device *dev, uint8_t *buffer, size_t rx_len)
227 {
228 	const struct w1_ds2477_85_config *cfg = dev->config;
229 	struct w1_ds2477_85_data *data = dev->data;
230 	int w1_timing = cfg->mode_timing[data->master_reg.od_active].t_slot * 8 * rx_len;
231 	uint8_t buf[3] = {CMD_RD_BLOCK, CMD_RD_BLOCK_LEN, rx_len};
232 	struct i2c_msg rx_msg[2] = {
233 		{.buf = buf, .len = 2, .flags = I2C_MSG_READ},
234 		{.buf = buffer, .len = rx_len, .flags = (I2C_MSG_READ | I2C_MSG_STOP)}
235 	};
236 	int ret;
237 
238 	__ASSERT_NO_MSG(rx_len <= MAX_BLOCK_LEN);
239 
240 	if (rx_len == 0) {
241 		return 0;
242 	}
243 
244 	ret = i2c_write_dt(&cfg->i2c_spec, buf, (CMD_RD_BLOCK_LEN + CMD_OVERHEAD_LEN));
245 	if (ret < 0) {
246 		LOG_ERR("read block fail: %x", ret);
247 		return ret;
248 	}
249 
250 	k_usleep(cfg->t_op_us + (cfg->t_seq_us * rx_len) +  w1_timing);
251 
252 	ret = i2c_transfer_dt(&cfg->i2c_spec, rx_msg, 2);
253 	if (ret < 0) {
254 		return ret;
255 	}
256 	if (buf[1] != DS2477_88_RES_SUCCESS) {
257 		return -EIO;
258 	}
259 
260 	return 0;
261 }
262 
ds2477_85_configure(const struct device * dev,enum w1_settings_type type,uint32_t value)263 int ds2477_85_configure(const struct device *dev, enum w1_settings_type type, uint32_t value)
264 {
265 	struct w1_ds2477_85_data *data = dev->data;
266 
267 	switch (type) {
268 	case W1_SETTING_SPEED:
269 		__ASSERT_NO_MSG(value <= 1);
270 		data->master_reg.od_active = value;
271 		break;
272 	default:
273 		return -EINVAL;
274 	}
275 
276 	return ds2477_85_write_port_config(dev, PORT_REG_MASTER_CONFIGURATION,
277 					   data->master_reg.value);
278 }
279 
w1_ds2477_85_init(const struct device * dev)280 int w1_ds2477_85_init(const struct device *dev)
281 {
282 	const struct w1_ds2477_85_config *cfg = dev->config;
283 	struct w1_ds2477_85_data *data = dev->data;
284 
285 	data->master_reg.apu = cfg->apu;
286 
287 	if (ds2477_85_write_port_config(dev, PORT_REG_MASTER_CONFIGURATION,
288 					data->master_reg.value) < 0) {
289 		return -EIO;
290 	}
291 
292 	if (ds2477_85_write_port_config(dev, PORT_REG_RPUP_BUF, cfg->rpup_buf) < 0) {
293 		return -EIO;
294 	}
295 
296 	if (ds2477_85_write_port_config(dev, PORT_REG_PDSLEW, cfg->pdslew) < 0) {
297 		return -EIO;
298 	}
299 
300 	LOG_DBG("cfg: rpup_buf=%02x, pdslew:%02x", cfg->rpup_buf, cfg->pdslew);
301 
302 	/* RPUP/BUF configuration is applied after a bus reset */
303 	(void)ds2477_85_reset_bus(dev);
304 
305 	LOG_DBG("w1-ds2477/85 init; %d slave devices",
306 		cfg->master_config.slave_count);
307 
308 	return 0;
309 }
310