1 /*
2  * Copyright (c) 2022 Thomas Stranger
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_DRIVERS_W1_DS2477_DS2485_COMMON_H_
8 #define ZEPHYR_DRIVERS_W1_DS2477_DS2485_COMMON_H_
9 
10 #include <zephyr/drivers/i2c.h>
11 #include <zephyr/drivers/w1.h>
12 #include <zephyr/kernel.h>
13 
14 /* memory specific commands */
15 #define CMD_WR_MEM		 0x96
16 #define CMD_RD_MEM		 0x44
17 #define CMD_SET_PAGE_PROTECT	 0xc3
18 #define CMD_RD_STATUS		 0xaa
19 /* configuration specific commands */
20 #define CMD_SET_I2C_ADDR	 0x75
21 #define CMD_RD_W1_PORT_CFG	 0x52
22 #define CMD_WR_W1_PORT_CFG	 0x99
23 #define CMD_MASTER_RESET	 0x62
24 /* 1-Wire specific commands */
25 #define CMD_W1_SCRIPT		 0x88
26 #define CMD_W1_BLOCK		 0xab
27 #define CMD_RD_BLOCK		 0x50
28 #define CMD_WR_BLOCK		 0x68
29 #define CMD_SEARCH		 0x11
30 #define CMD_FULL_CMD_SEQ	 0x57
31 /* crc16 specific commands */
32 #define CMD_COMPUTE_CRC		 0xcc
33 
34 /* i2c command overhead len */
35 #define CMD_OVERHEAD_LEN         2U
36 /* memory specific commands' data length */
37 #define CMD_WR_MEM_LEN		 33U
38 #define CMD_RD_MEM_LEN		 1U
39 #define CMD_SET_PAGE_PROTECT_LEN 2U
40 #define CMD_RD_STATUS_LEN	 1U
41 /* configuration specific commands */
42 #define CMD_SET_I2C_ADDR_LEN	 1U
43 #define CMD_RD_W1_PORT_CFG_LEN	 1U
44 #define CMD_WR_W1_PORT_CFG_LEN	 3U
45 /* 1-Wire specific commands */
46 #define CMD_W1_SCRIPT_LEN	 1U
47 #define CMD_W1_BLOCK_LEN	 1U
48 #define CMD_RD_BLOCK_LEN	 1U
49 #define CMD_WR_BLOCK_LEN	 1U
50 #define CMD_SEARCH_LEN		 2U
51 #define CMD_FULL_CMD_SEQ_LEN	 9U
52 /* crc16 specific commands */
53 #define CMD_COMPUTE_CRC_LEN	 1U
54 
55 /* I2C communication result bytes */
56 #define DS2477_88_RES_SUCCESS	    0xaa
57 #define DS2477_88_RES_INVALID_PARAM 0x77
58 #define DS2477_88_RES_COMM_FAILURE  0x22
59 #define DS2477_88_RES_RESET_FAILURE 0x22
60 #define DS2477_88_RES_NO_PRESENCE   0x33
61 #define DS2477_88_RES_WP_FAILURE    0x55
62 
63 /* primitive commands, executable via the script command */
64 #define SCRIPT_OW_RESET	      0x00
65 #define SCRIPT_OW_WRITE_BIT   0x01
66 #define SCRIPT_OW_READ_BIT    0x02
67 #define SCRIPT_OW_WRITE_BYTE  0x03
68 #define SCRIPT_OW_READ_BYTE   0x04
69 #define SCRIPT_OW_TRIPLET     0x05
70 #define SCRIPT_OW_OV_SKIP     0x06
71 #define SCRIPT_OW_SKIP	      0x07
72 #define SCRIPT_OW_READ_BLOCK  0x08
73 #define SCRIPT_OW_WRITE_BLOCK 0x09
74 #define SCRIPT_OW_DELAY	      0x0a
75 #define SCRIPT_OW_PRIME_SPU   0x0b
76 #define SCRIPT_OW_SPU_OFF     0x0c
77 #define SCRIPT_OW_SPEED	      0x0d
78 
79 /* port configuration register offsets */
80 #define PORT_REG_MASTER_CONFIGURATION	0x00
81 #define PORT_REG_STANDARD_SPEED_T_RSTL	0x01
82 #define PORT_REG_STANDARD_SPEED_T_MSI	0x02
83 #define PORT_REG_STANDARD_SPEED_T_MSP	0x03
84 #define PORT_REG_STANDARD_SPEED_T_RSTH	0x04
85 #define PORT_REG_STANDARD_SPEED_T_W0L	0x05
86 #define PORT_REG_STANDARD_SPEED_T_W1L	0x06
87 #define PORT_REG_STANDARD_SPEED_T_MSR	0x07
88 #define PORT_REG_STANDARD_SPEED_T_REC	0x08
89 #define PORT_REG_OVERDRIVE_SPEED_T_RSTL 0x09
90 #define PORT_REG_OVERDRIVE_SPEED_T_MSI	0x0a
91 #define PORT_REG_OVERDRIVE_SPEED_T_MSP	0x0b
92 #define PORT_REG_OVERDRIVE_SPEED_T_RSTH 0x0c
93 #define PORT_REG_OVERDRIVE_SPEED_T_W0L	0x0d
94 #define PORT_REG_OVERDRIVE_SPEED_T_W1L	0x0e
95 #define PORT_REG_OVERDRIVE_SPEED_T_MSR	0x0f
96 #define PORT_REG_OVERDRIVE_SPEED_T_REC	0x10
97 #define PORT_REG_RPUP_BUF		0x11
98 #define PORT_REG_PDSLEW			0x12
99 #define PORT_REG_COUNT			0x13
100 
101 /* upper limit of 1-wire command length supported(in bytes) */
102 #define MAX_BLOCK_LEN	 126U
103 /* limit of 1-wire command len is 126 bytes, but currently not used: */
104 #define SCRIPT_WR_LEN 1U
105 
106 /* variant independent timing */
107 #define DS2477_85_T_RM_us 50000U
108 #define DS2477_85_T_WM_us 100000U
109 #define DS2477_85_T_WS_us 15000U
110 
111 /* default 1-wire timing parameters (cfg. value==6) */
112 #define DS2477_85_STD_SPD_T_RSTL_us 560U
113 #define DS2477_85_STD_SPD_T_MSI_us  7U
114 #define DS2477_85_STD_SPD_T_MSP_us  68U
115 #define DS2477_85_STD_SPD_T_RSTH_us 560U
116 #define DS2477_85_STD_SPD_T_W0L_us  68U
117 #define DS2477_85_STD_SPD_T_W1L_us  8U
118 #define DS2477_85_STD_SPD_T_MSR_us  12U
119 #define DS2477_85_STD_SPD_T_REC_us  6U
120 
121 #define DS2477_85_OVD_SPD_T_RSTL_us 56U
122 #define DS2477_85_OVD_SPD_T_MSI_us  2U
123 #define DS2477_85_OVD_SPD_T_MSP_us  8U
124 #define DS2477_85_OVD_SPD_T_RSTH_us 56U
125 #define DS2477_85_OVD_SPD_T_W0L_us  8U
126 #define DS2477_85_OVD_SPD_T_W1L_us  1U
127 #define DS2477_85_OVD_SPD_T_MSR_us  2U
128 #define DS2477_85_OVD_SPD_T_REC_us  6U
129 
130 #define DS2477_85_STD_SPD_T_SLOT_us                                            \
131 	(DS2477_85_STD_SPD_T_W0L_us + DS2477_85_STD_SPD_T_REC_us)
132 #define DS2477_85_STD_SPD_T_RESET_us                                           \
133 	(DS2477_85_STD_SPD_T_RSTL_us + DS2477_85_STD_SPD_T_RSTH_us)
134 
135 #define DS2477_85_OVD_SPD_T_SLOT_us                                            \
136 	(DS2477_85_OVD_SPD_T_W0L_us + DS2477_85_OVD_SPD_T_REC_us)
137 #define DS2477_85_OVD_SPD_T_RESET_us                                           \
138 	(DS2477_85_OVD_SPD_T_RSTL_us + DS2477_85_OVD_SPD_T_RSTH_us)
139 
140 /* defines for DTS switching-th, active-pull-th and weak-pullup enums */
141 #define RPUP_BUF_CUSTOM BIT(15)
142 
143 #define RPUP_BUF_SW_TH_Msk	  GENMASK(5, 4)
144 #define RPUP_BUF_SW_TH_PREP(x)	  FIELD_PREP(RPUP_BUF_SW_TH_Msk, x)
145 #define RPUP_BUF_SW_TH_LOW	  RPUP_BUF_SW_TH_PREP(0)
146 #define RPUP_BUF_SW_TH_MEDIUM	  RPUP_BUF_SW_TH_PREP(1)
147 #define RPUP_BUF_SW_TH_HIGH	  RPUP_BUF_SW_TH_PREP(2)
148 #define RPUP_BUF_SW_TH_OFF	  RPUP_BUF_SW_TH_PREP(3)
149 #define RPUP_BUF_APULL_TH_Msk	  GENMASK(3, 2)
150 #define RPUP_BUF_APULL_TH_PREP(x) FIELD_PREP(RPUP_BUF_APULL_TH_Msk, x)
151 #define RPUP_BUF_APULL_TH_LOW	  RPUP_BUF_APULL_TH_PREP(0)
152 #define RPUP_BUF_APULL_TH_MEDIUM  RPUP_BUF_APULL_TH_PREP(1)
153 #define RPUP_BUF_APULL_TH_HIGH	  RPUP_BUF_APULL_TH_PREP(2)
154 #define RPUP_BUF_APULL_TH_OFF	  RPUP_BUF_APULL_TH_PREP(3)
155 #define RPUP_BUF_WPULL_Msk	  GENMASK(1, 0)
156 #define RPUP_BUF_WPULL_PREP(x)	  FIELD_PREP(RPUP_BUF_WPULL_Msk, x)
157 #define RPUP_BUF_WPULL_EXTERN	  RPUP_BUF_WPULL_PREP(0)
158 #define RPUP_BUF_WPULL_500	  RPUP_BUF_WPULL_PREP(1)
159 #define RPUP_BUF_WPULL_1000	  RPUP_BUF_WPULL_PREP(2)
160 #define RPUP_BUF_WPULL_333	  RPUP_BUF_WPULL_PREP(3)
161 
162 /* defines for standard and overdrive slew enums */
163 #define PDSLEW_CUSTOM	   BIT(15)
164 #define PDSLEW_STD_Msk	   GENMASK(5, 3)
165 #define PDSLEW_STD_PREP(x) FIELD_PREP(PDSLEW_STD_Msk, BIT(x))
166 #define PDSLEW_STD_50	   PDSLEW_STD_PREP(0)
167 #define PDSLEW_STD_150	   PDSLEW_STD_PREP(1)
168 #define PDSLEW_STD_1300	   PDSLEW_STD_PREP(2)
169 #define PDSLEW_OVD_Msk	   GENMASK(2, 0)
170 #define PDSLEW_OVD_PREP(x) FIELD_PREP(PDSLEW_OVD_Msk, BIT(x))
171 #define PDSLEW_OVD_50	   PDSLEW_OVD_PREP(0)
172 #define PDSLEW_OVD_150	   PDSLEW_OVD_PREP(1)
173 
174 /* speed mode dependent timing parameters */
175 struct mode_timing {
176 	uint16_t t_slot;
177 	uint16_t t_reset;
178 };
179 
180 union master_config_reg {
181 	struct {
182 		uint16_t res : 12;
183 		uint16_t apu : 1;
184 		uint16_t spu : 1;
185 		uint16_t pdn : 1;
186 		uint16_t od_active : 1;
187 	};
188 	uint16_t value;
189 };
190 
191 typedef int (*variant_w1_script_cmd_fn)(const struct device *dev,
192 					int w1_delay_us, uint8_t w1_cmd,
193 					const uint8_t *tx_buf,
194 					const uint8_t tx_len, uint8_t *rx_buf,
195 					uint8_t rx_len);
196 
197 struct w1_ds2477_85_config {
198 	/** w1 master config, common to all drivers */
199 	struct w1_master_config master_config;
200 	/** I2C device */
201 	const struct i2c_dt_spec i2c_spec;
202 	/** config reg of weak pullup, active pullup, and switch threshold */
203 	uint16_t rpup_buf;
204 	/** config reg of standard and overdrive slew */
205 	uint16_t pdslew;
206 	/** mode dependent timing parameters (@0: standard, @1: overdrive) */
207 	struct mode_timing mode_timing[2];
208 	/** variant dependent time of 1 operation in us */
209 	uint16_t t_op_us;
210 	/** variant dependent time of 1 sequence in us */
211 	uint16_t t_seq_us;
212 	/** variant specific script command */
213 	variant_w1_script_cmd_fn w1_script_cmd;
214 	/** indicates enable active pull-up configuration */
215 	bool apu;
216 };
217 
218 struct w1_ds2477_85_data {
219 	/** w1 master data, common to all drivers */
220 	struct w1_master_data master_data;
221 	/** master specific runtime configuration */
222 	union master_config_reg master_reg;
223 };
224 
225 #define W1_DS2477_85_DT_CONFIG_GET(node_id, _t_op, _t_seq, _script_cmd)        \
226 	{                                                                      \
227 		.i2c_spec = I2C_DT_SPEC_GET(node_id),                          \
228 		.master_config.slave_count =                                   \
229 			W1_SLAVE_COUNT(node_id),                               \
230 		.rpup_buf = RPUP_BUF_CUSTOM |                                  \
231 			RPUP_BUF_SW_TH_PREP(DT_ENUM_IDX(node_id,               \
232 						       switching_threshold)) | \
233 			RPUP_BUF_APULL_TH_PREP(DT_ENUM_IDX(node_id,            \
234 						     active_pull_threshold)) | \
235 			RPUP_BUF_WPULL_PREP(DT_ENUM_IDX(node_id, weak_pullup)),\
236 		.pdslew = PDSLEW_CUSTOM |                                      \
237 			  PDSLEW_STD_PREP(DT_ENUM_IDX(node_id,                 \
238 						      standard_slew)) |        \
239 			  PDSLEW_OVD_PREP(DT_ENUM_IDX(node_id,                 \
240 						      overdrive_slew)),        \
241 		.apu = DT_PROP(node_id, active_pullup),                        \
242 		.mode_timing = {                                               \
243 			{                                                      \
244 				.t_slot = DS2477_85_STD_SPD_T_SLOT_us,         \
245 				.t_reset = DS2477_85_STD_SPD_T_RESET_us,       \
246 			},                                                     \
247 			{                                                      \
248 				.t_slot = DS2477_85_OVD_SPD_T_SLOT_us,         \
249 				.t_reset = DS2477_85_OVD_SPD_T_RESET_us,       \
250 			},                                                     \
251 		},                                                             \
252 		.t_op_us = _t_op,                                              \
253 		.t_seq_us = _t_seq,                                            \
254 		.w1_script_cmd = _script_cmd,                                  \
255 	}
256 
257 #define W1_DS2477_85_DT_CONFIG_INST_GET(inst, _t_op, _t_seq, _script_cmd)      \
258 	W1_DS2477_85_DT_CONFIG_GET(DT_DRV_INST(inst), _t_op, _t_seq,           \
259 				   _script_cmd)
260 
261 int w1_ds2477_85_init(const struct device *dev);
262 int ds2477_85_write_port_config(const struct device *dev, uint8_t reg,
263 				uint16_t value);
264 int ds2477_85_read_port_config(const struct device *dev, uint8_t reg,
265 			       uint16_t *value);
266 int ds2477_85_reset_master(const struct device *dev);
267 int ds2477_85_reset_bus(const struct device *dev);
268 int ds2477_85_read_bit(const struct device *dev);
269 int ds2477_85_write_bit(const struct device *dev, const bool bit);
270 int ds2477_85_read_byte(const struct device *dev);
271 int ds2477_85_write_byte(const struct device *dev, const uint8_t tx_byte);
272 int ds2477_85_write_block(const struct device *dev, const uint8_t *buffer,
273 			  size_t tx_len);
274 int ds2477_85_read_block(const struct device *dev, uint8_t *buffer,
275 			 size_t rx_len);
276 int ds2477_85_configure(const struct device *dev, enum w1_settings_type type,
277 			uint32_t value);
278 
279 #endif /* ZEPHYR_DRIVERS_W1_DS2477_DS2485_COMMON_H_ */
280