1 /*
2     OWFS -- One-Wire filesystem
3     OWHTTPD -- One-Wire Web Server
4     Written 2003 Paul H Alfille
5     email: paul.alfille@gmail.com
6     Released under the GPL
7     See the header file: ow.h for full attribution
8     1wire/iButton system from Dallas Semiconductor
9  */
10 /* i2c support for the DS2482-100 and DS2482-800 1-wire host adapters */
11 /* Stolen shamelessly from Ben Gardners kernel module */
12 /* Actually, Dallas datasheet has the information,
13    the module code showed a nice implementation,
14    the eventual format is owfs-specific (using similar primatives, data structures)
15    Testing by Jan Kandziora and Daniel Höper.
16  */
17 /**
18  * ds2482.c - provides i2c to w1-master bridge(s)
19  * Copyright (C) 2005  Ben Gardner <bgardner@wabtec.com>
20  *
21  * The DS2482 is a sensor chip made by Dallas Semiconductor (Maxim).
22  * It is a I2C to 1-wire bridge.
23  * There are two variations: -100 and -800, which have 1 or 8 1-wire ports.
24  * The complete datasheet can be obtained from MAXIM's website at:
25  *   http://www.maxim-ic.com/quick_view2.cfm/qv_pk/4382
26  *
27  * This program is free software; you can redistribute it and/or modify
28  * it under the terms of the GNU General Public License as published by
29  * the Free Software Foundation; version 2 of the License.
30  *
31  * MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
32  * MODULE_DESCRIPTION("DS2482 driver");
33  * MODULE_LICENSE("GPL");
34  */
35 
36 #include <config.h>
37 #include "owfs_config.h"
38 #include "ow.h"
39 #include "ow_counters.h"
40 #include "ow_connection.h"
41 
42 #if OW_I2C
43 // Header taken from lm-sensors code
44 // specifically lm-sensors-2.10.0
45 #include "i2c-dev.h"
46 
47 enum ds2482_address {
48 	ds2482_any=-2,
49 	ds2482_all=-1,
50 	ds2482_18, ds2482_19, ds2482_1A, ds2482_1B, ds2482_1C, ds2482_1D, ds2482_1E, ds2482_1F,
51 	ds2482_too_far
52 } ;
53 
54 static GOOD_OR_BAD DS2482_detect_bus(enum ds2482_address chip_num, char * i2c_device, struct port_in *pin) ;
55 static GOOD_OR_BAD DS2482_detect_sys( int any, enum ds2482_address chip_num, struct port_in *pin) ;
56 static GOOD_OR_BAD DS2482_detect_dir( int any, enum ds2482_address chip_num, struct port_in *pin) ;
57 static GOOD_OR_BAD DS2482_detect_single(int lowindex, int highindex, char * i2c_device, struct port_in *pin) ;
58 static enum search_status DS2482_next_both(struct device_search *ds, const struct parsedname *pn);
59 static GOOD_OR_BAD DS2482_triple(BYTE * bits, int direction, FILE_DESCRIPTOR_OR_ERROR file_descriptor);
60 static GOOD_OR_BAD DS2482_send_and_get(FILE_DESCRIPTOR_OR_ERROR file_descriptor, const BYTE wr, BYTE * rd);
61 static RESET_TYPE DS2482_reset(const struct parsedname *pn);
62 static GOOD_OR_BAD DS2482_sendback_data(const BYTE * data, BYTE * resp, const size_t len, const struct parsedname *pn);
63 static GOOD_OR_BAD DS2483_test(FILE_DESCRIPTOR_OR_ERROR file_descriptor);
64 static void DS2482_setroutines(struct connection_in *in);
65 static GOOD_OR_BAD HeadChannel(struct connection_in *head);
66 static GOOD_OR_BAD CreateChannels(struct connection_in *head);
67 static GOOD_OR_BAD DS2482_channel_select(struct connection_in * in);
68 static GOOD_OR_BAD DS2482_readstatus(BYTE * c, FILE_DESCRIPTOR_OR_ERROR file_descriptor, unsigned long int min_usec, unsigned long int max_usec);
69 static GOOD_OR_BAD SetConfiguration(BYTE c, struct connection_in *in);
70 static void DS2482_close(struct connection_in *in);
71 static GOOD_OR_BAD DS2482_redetect(const struct parsedname *pn);
72 static GOOD_OR_BAD DS2482_PowerByte(const BYTE byte, BYTE * resp, const UINT delay, const struct parsedname *pn);
73 
74 /**
75  * The DS2482 registers - there are 3 registers that are addressed by a read
76  * pointer. The read pointer is set by the last command executed.
77  *
78  * To read the data, issue a register read for any address
79  */
80 #define DS2482_CMD_RESET               0xF0	/* No param */
81 #define DS2482_CMD_SET_READ_PTR        0xE1	/* Param: DS2482_PTR_CODE_xxx */
82 #define DS2482_CMD_CHANNEL_SELECT      0xC3	/* Param: Channel byte - DS2482-800 only */
83 #define DS2482_CMD_WRITE_CONFIG        0xD2	/* Param: Config byte */
84 #define DS2482_CMD_1WIRE_RESET         0xB4	/* Param: None */
85 #define DS2482_CMD_1WIRE_SINGLE_BIT    0x87	/* Param: Bit byte (bit7) */
86 #define DS2482_CMD_1WIRE_WRITE_BYTE    0xA5	/* Param: Data byte */
87 #define DS2482_CMD_1WIRE_READ_BYTE     0x96	/* Param: None */
88 /* Note to read the byte, Set the ReadPtr to Data then read (any addr) */
89 #define DS2482_CMD_1WIRE_TRIPLET       0x78	/* Param: Dir byte (bit7) */
90 
91 /* Values for DS2482_CMD_SET_READ_PTR */
92 #define DS2482_STATUS_REGISTER         		 0xF0
93 #define DS2482_READ_DATA_REGISTER            0xE1
94 #define DS2482_DEVICE_CONFIGURATION_REGISTER 0xC3
95 #define DS2482_CHANNEL_SELECTION_REGISTER    0xD2	/* DS2482-800 only */
96 #define DS2482_PORT_CONFIGURATION_REGISTER   0xB4   /* DS2483 only */
97 
98 /**
99  * Configure Register bit definitions
100  * The top 4 bits always read 0.
101  * To write, the top nibble must be the 1's compl. of the low nibble.
102  */
103 #define DS2482_REG_CFG_1WS     0x08
104 #define DS2482_REG_CFG_SPU     0x04
105 #define DS2482_REG_CFG_PDN     0x02 /* DS2483 only, power down */
106 #define DS2482_REG_CFG_PPM     0x02 /* non-DS2483, presence pulse masking */
107 #define DS2482_REG_CFG_APU     0x01
108 
109 /**
110  * Status Register bit definitions (read only)
111  */
112 #define DS2482_REG_STS_DIR     0x80
113 #define DS2482_REG_STS_TSB     0x40
114 #define DS2482_REG_STS_SBR     0x20
115 #define DS2482_REG_STS_RST     0x10
116 #define DS2482_REG_STS_LL      0x08
117 #define DS2482_REG_STS_SD      0x04
118 #define DS2482_REG_STS_PPD     0x02
119 #define DS2482_REG_STS_1WB     0x01
120 
121 /* Time limits for communication
122     unsigned long int min_usec, unsigned long int max_usec */
123 #define DS2482_Chip_reset_usec   1, 2
124 #define DS2482_1wire_reset_usec   1125, 1250
125 #define DS2482_1wire_write_usec   530, 585
126 #define DS2482_1wire_triplet_usec   198, 219
127 
128 /* Defines for making messages more explicit */
129 #define I2Cformat "I2C bus %s, channel %d/%d"
130 #define I2Cvar(in)  DEVICENAME(in), (in)->master.i2c.index, (in)->master.i2c.channels
131 
132 /* Device-specific functions */
DS2482_setroutines(struct connection_in * in)133 static void DS2482_setroutines(struct connection_in *in)
134 {
135 	in->iroutines.detect = DS2482_detect;
136 	in->iroutines.reset = DS2482_reset;
137 	in->iroutines.next_both = DS2482_next_both;
138 	in->iroutines.PowerByte = DS2482_PowerByte;
139     in->iroutines.ProgramPulse = NO_PROGRAMPULSE_ROUTINE;
140 	in->iroutines.sendback_data = DS2482_sendback_data;
141 	in->iroutines.sendback_bits = NO_SENDBACKBITS_ROUTINE;
142 	in->iroutines.select = NO_SELECT_ROUTINE;
143 	in->iroutines.select_and_sendback = NO_SELECTANDSENDBACK_ROUTINE;
144 	in->iroutines.set_config = NO_SET_CONFIG_ROUTINE;
145 	in->iroutines.get_config = NO_GET_CONFIG_ROUTINE;
146 	in->iroutines.reconnect = DS2482_redetect;
147 	in->iroutines.close = DS2482_close;
148 	in->iroutines.verify = NO_VERIFY_ROUTINE ;
149 	in->iroutines.flags = ADAP_FLAG_overdrive;
150 	in->bundling_length = I2C_FIFO_SIZE;
151 }
152 
153 /* All the rest of the program sees is the DS2482_detect and the entry in iroutines */
154 /* Open a DS2482 */
155 /* Top level detect routine */
DS2482_detect(struct port_in * pin)156 GOOD_OR_BAD DS2482_detect(struct port_in *pin)
157 {
158 	struct address_pair ap ;
159 	GOOD_OR_BAD gbResult ;
160 	enum ds2482_address chip_num ;
161 
162 	Parse_Address( pin->init_data, &ap ) ;
163 
164 	switch ( ap.second.type ) {
165 		case address_numeric:
166 			if ( ap.second.number < ds2482_18 || ap.second.number >= ds2482_too_far ) {
167 				LEVEL_CALL("DS2482 bus address <%s> invalid. Will search.", ap.second.alpha) ;
168 				chip_num = ds2482_any ;
169 			} else {
170 				chip_num = ap.second.number ;
171 			}
172 			break ;
173 		case address_all:
174 		case address_asterix:
175 			chip_num = ds2482_all ;
176 			break ;
177 		case address_none:
178 			chip_num = ds2482_any ;
179 			break ;
180 		default:
181 			LEVEL_CALL("DS2482 bus address <%s> invalid. Will scan.", ap.second.alpha) ;
182 			chip_num = ds2482_any ;
183 			break ;
184 	}
185 
186 	switch ( ap.first.type ) {
187 		case address_all:
188 		case address_asterix:
189 			// All adapters
190 			gbResult = DS2482_detect_sys( 0, chip_num, pin ) ;
191 			break ;
192 		case address_none:
193 			// Any adapter -- first one found
194 			gbResult = DS2482_detect_sys( 1, chip_num, pin ) ;
195 			break ;
196 		default:
197 			// traditional, actual bus specified
198 			gbResult = DS2482_detect_bus( chip_num, ap.first.alpha, pin ) ;
199 			break ;
200 	}
201 
202 	Free_Address( &ap ) ;
203 	return gbResult ;
204 }
205 
206 #define SYSFS_I2C_Path "/sys/class/i2c-adapter"
207 
208 /* Use sysfs to find i2c adapters */
209 /* cycle through SYSFS_I2C_Path */
210 /* return GOOD if any found */
DS2482_detect_sys(int any,enum ds2482_address chip_num,struct port_in * pin_original)211 static GOOD_OR_BAD DS2482_detect_sys( int any, enum ds2482_address chip_num, struct port_in *pin_original)
212 {
213 	DIR * i2c_list_dir ;
214 	struct dirent * i2c_bus ;
215 	int found = 0 ;
216 	struct port_in * pin_current = pin_original ;
217 
218 	// We'll look in this directory for available i2c adapters.
219 	// This may be linux 2.6 specific
220 	i2c_list_dir = opendir( SYSFS_I2C_Path ) ;
221 	if ( i2c_list_dir == NULL ) {
222 		ERROR_CONNECT( "Cannot open %d to find available i2c devices",SYSFS_I2C_Path ) ;
223 		// Use the cruder approach of trying all possible numbers
224 		return DS2482_detect_dir( any, chip_num, pin_original ) ;
225 	}
226 
227 	/* cycle through entries in /sys/class/i2c-adapter */
228 	while ( (i2c_bus=readdir(i2c_list_dir)) != NULL ) {
229 		char dev_name[128] ; // room for /dev/name
230 		int sn_ret ;
231 
232 		UCLIBCLOCK ;
233 		sn_ret = snprintf( dev_name, 128, "/dev/%s", i2c_bus->d_name ) ;
234 		UCLIBCUNLOCK ;
235 		if ( sn_ret < 0 ) {
236 			break ;
237 		}
238 
239 		// Now look for the ds2482's
240 		if ( BAD( DS2482_detect_bus( chip_num, dev_name, pin_current ) ) ) {
241 			continue ; // none found on this i2c bus
242 		}
243 
244 		// at least one found on this i2c bus
245 		++found ;
246 		if ( any ) { // found one -- that's enough
247 			closedir( i2c_list_dir ) ;
248 			return gbGOOD ;
249 		}
250 
251 		// ALL? then set up a new connection_in slot for the next one
252 		pin_current = NewPort(pin_current) ;
253 		if ( pin_current == NULL ) {
254 			break ;
255 		}
256 	}
257 
258 	closedir( i2c_list_dir ) ;
259 
260 	if ( found==0 ) {
261 		return gbBAD ;
262 	}
263 
264 	if ( pin_current != pin_original ) {
265 		RemovePort( pin_current ) ;
266 	}
267 	return gbGOOD ;
268 }
269 
270 /* non sysfs method -- try by bus name */
271 /* cycle through /dev/i2c-n */
272 /* returns GOOD if any adpters found */
DS2482_detect_dir(int any,enum ds2482_address chip_num,struct port_in * pin_original)273 static GOOD_OR_BAD DS2482_detect_dir( int any, enum ds2482_address chip_num, struct port_in *pin_original)
274 {
275 	int found = 0 ;
276 	struct port_in * pin_current = pin_original ;
277 	int bus = 0 ;
278 	int sn_ret ;
279 
280 	for ( bus=0 ; bus<99 ; ++bus ) {
281 		char dev_name[128] ;
282 
283 		UCLIBCLOCK ;
284 		sn_ret = snprintf( dev_name, 128-1, "/dev/i2c-%d", bus ) ;
285 		UCLIBCUNLOCK ;
286 		if ( sn_ret < 0 ) {
287 				break ;
288 		}
289 
290 		if ( access(dev_name, F_OK) < 0 ) {
291 			continue ;
292 		}
293 
294 		// Now look for the ds2482's
295 		if ( BAD( DS2482_detect_bus( chip_num, dev_name, pin_current ) ) ) {
296 			continue ;
297 		}
298 
299 		// at least one found
300 		++found ;
301 		if ( any ) {
302 			return gbGOOD ;
303 		}
304 
305 		// ALL? then set up a new connection_in slot
306 		pin_current = NewPort(pin_current) ;
307 		if ( pin_current == NULL ) {
308 			break ;
309 		}
310 	}
311 
312 	if ( found == 0 ) {
313 		return gbBAD ;
314 	}
315 
316 	if ( pin_original != pin_current ) {
317 		RemovePort(pin_current) ;
318 	}
319 	return gbGOOD ;
320 }
321 
322 /* Try to see if there is a DS2482 device on the specified i2c bus */
323 /* Includes  a fix from Pascal Baerten */
DS2482_detect_bus(enum ds2482_address chip_num,char * i2c_device,struct port_in * pin_original)324 static GOOD_OR_BAD DS2482_detect_bus(enum ds2482_address chip_num, char * i2c_device, struct port_in * pin_original)
325 {
326 	switch (chip_num) {
327 		case ds2482_any:
328 			// usual case, find the first adapter
329 			return DS2482_detect_single( 0, 7, i2c_device, pin_original ) ;
330 		case ds2482_all:
331 			// Look through all the possible i2c addresses
332 			{
333 				int start_chip = 0 ;
334 				struct port_in * all_pin = pin_original ;
335 				do {
336 					if ( BAD( DS2482_detect_single( start_chip, 7, i2c_device, all_pin ) ) ) {
337 						if ( pin_original == all_pin ) { //first time
338 							return gbBAD ;
339 						}
340 						LEVEL_DEBUG("Cleaning excess allocated i2c structure");
341 						RemovePort(all_pin); //Pascal Baerten :this removes the false DS2482-100 provisioned
342 						return gbGOOD ;
343 					}
344 					start_chip = all_pin->first->master.i2c.i2c_index + 1 ;
345 					if ( start_chip > 7 ) {
346 						return gbGOOD ;
347 					}
348 					all_pin = NewPort(all_pin) ;
349 					if ( all_pin == NULL ) {
350 						return gbBAD ;
351 					}
352 				} while (1) ;
353 			}
354 			break ;
355 		default:
356 			// specific i2c address
357 			return DS2482_detect_single( chip_num, chip_num, i2c_device, pin_original ) ;
358 	}
359 }
360 
361 /* Try to see if there is a DS2482 device on the specified i2c bus */
DS2482_detect_single(int lowindex,int highindex,char * i2c_device,struct port_in * pin)362 static GOOD_OR_BAD DS2482_detect_single(int lowindex, int highindex, char * i2c_device, struct port_in *pin)
363 {
364 	int test_address[8] = { 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, };	// the last 4 are -800 only
365 	int i2c_index;
366 	FILE_DESCRIPTOR_OR_ERROR file_descriptor;
367 	struct connection_in * in = pin->first ;
368 
369 	/* Sanity check */
370 	if ( lowindex < 0 ) {
371 		LEVEL_DEBUG("Bad lower bound");
372 		return gbBAD ;
373 	}
374 	if ( highindex >= (int) (sizeof(test_address)/sizeof(int)) ) {
375 		LEVEL_DEBUG("Bad upper bound");
376 		return gbBAD ;
377 	}
378 
379 	/* open the i2c port */
380 	file_descriptor = open(i2c_device, O_RDWR);
381 	if ( FILE_DESCRIPTOR_NOT_VALID(file_descriptor) ) {
382 		ERROR_CONNECT("Could not open i2c device %s", i2c_device);
383 		return gbBAD;
384 	}
385 
386 	/* Set up low-level routines */
387 	DS2482_setroutines(in);
388 
389 	for (i2c_index = lowindex; i2c_index <= highindex; ++i2c_index) {
390 		int trial_address = test_address[i2c_index] ;
391 		/* set the candidate address */
392 		if (ioctl(file_descriptor, I2C_SLAVE, trial_address) < 0) {
393 			ERROR_CONNECT("Cound not set trial i2c address to %.2X", trial_address);
394 		} else {
395 			BYTE c;
396 			LEVEL_CONNECT("Found an i2c device at %s address %.2X", i2c_device, trial_address);
397 			/* Provisional setup as a DS2482-100 ( 1 channel ) */
398 			in->pown->file_descriptor = file_descriptor;
399 			pin->state = cs_deflowered;
400 			pin->type = ct_i2c ;
401 			in->master.i2c.i2c_address = trial_address;
402 			in->master.i2c.i2c_index = i2c_index;
403 			in->master.i2c.index = 0;
404 			in->master.i2c.channels = 1;
405 			in->master.i2c.current = 0;
406 			in->master.i2c.head = in;
407 			in->adapter_name = "DS2482-100";
408 			in->master.i2c.configreg = 0x00 ;	// default configuration setting desired
409 			if ( Globals.i2c_APU ) {
410 				in->master.i2c.configreg |= DS2482_REG_CFG_APU ;
411 			}
412 			if ( Globals.i2c_PPM ) {
413 				in->master.i2c.configreg |= DS2482_REG_CFG_PPM ;
414 			}
415 			in->Adapter = adapter_DS2482_100;
416 
417 			/* write the RESET code */
418 			if (i2c_smbus_write_byte(file_descriptor, DS2482_CMD_RESET)	// reset
419 				|| BAD(DS2482_readstatus(&c, file_descriptor, DS2482_Chip_reset_usec))	// pause .5 usec then read status
420 				|| (c != (DS2482_REG_STS_LL | DS2482_REG_STS_RST))	// make sure status is properly set
421 				) {
422 				LEVEL_CONNECT("i2c device at %s address %.2X cannot be reset. Not a DS2482.", i2c_device, trial_address);
423 				in->pown->file_descriptor = FILE_DESCRIPTOR_BAD ;
424 				continue;
425 			}
426 			LEVEL_CONNECT("i2c device at %s address %.2X appears to be DS2482-x00", i2c_device, trial_address);
427 			in->master.i2c.configchip = 0x00;	// default configuration register after RESET
428 			// Note, only the lower nibble of the device config stored
429 
430 			// Create name
431 			SAFEFREE( DEVICENAME(in) ) ;
432 			DEVICENAME(in) = owmalloc( strlen(i2c_device) + 10 ) ;
433 			if ( DEVICENAME(in) ) {
434 				UCLIBCLOCK;
435 				snprintf(DEVICENAME(in), strlen(i2c_device) + 10, "%s:%.2X", i2c_device, trial_address);
436 				UCLIBCUNLOCK;
437 			}
438 
439 			/* Now see if DS2482-100 or DS2482-800 */
440 			return HeadChannel(in);
441 		}
442 	}
443 	/* fell though, no device found */
444 	COM_close( in ) ;
445 	Test_and_Close( & file_descriptor ) ;
446 	return gbBAD;
447 }
448 
449 /* Re-open a DS2482 */
DS2482_redetect(const struct parsedname * pn)450 static GOOD_OR_BAD DS2482_redetect(const struct parsedname *pn)
451 {
452 	struct connection_in *head = pn->selected_connection->master.i2c.head;
453 	int address = head->master.i2c.i2c_address;
454 	FILE_DESCRIPTOR_OR_ERROR file_descriptor;
455 	struct address_pair ap ; // to get device name from device:address
456 
457 	/* open the i2c port */
458 	Parse_Address( DEVICENAME(head), &ap ) ;
459 	file_descriptor = open(ap.first.alpha, O_RDWR );
460 	Free_Address( &ap ) ;
461 	if ( FILE_DESCRIPTOR_NOT_VALID(file_descriptor) ) {
462 		ERROR_CONNECT("Could not open i2c device %s", DEVICENAME(head));
463 		return gbBAD;
464 	}
465 
466 	/* address is known */
467 	if (ioctl(file_descriptor, I2C_SLAVE, address) < 0) {
468 		ERROR_CONNECT("Cound not set i2c address to %.2X", address);
469 	} else {
470 		BYTE c;
471 		/* write the RESET code */
472 		if (i2c_smbus_write_byte(file_descriptor, DS2482_CMD_RESET)	// reset
473 			|| BAD(DS2482_readstatus(&c, file_descriptor, DS2482_Chip_reset_usec))	// pause .5 usec then read status
474 			|| (c != (DS2482_REG_STS_LL | DS2482_REG_STS_RST))	// make sure status is properly set
475 			) {
476 			LEVEL_CONNECT("i2c device at %s address %d cannot be reset. Not a DS2482.", DEVICENAME(head), address);
477 		} else {
478 			struct connection_in * next ;
479 			head->master.i2c.current = 0;
480 			head->pown->file_descriptor = file_descriptor;
481 			head->pown->state = cs_deflowered ;
482 			head->pown->type = ct_i2c ;
483 			head->master.i2c.configchip = 0x00;	// default configuration register after RESET
484 			LEVEL_CONNECT("i2c device at %s address %d reset successfully", DEVICENAME(head), address);
485 			for ( next = head->pown->first; next; next = next->next ) {
486 				/* loop through devices, matching those that have the same "head" */
487 				/* BUSLOCK also locks the sister channels for this */
488 				next->reconnect_state = reconnect_ok;
489 			}
490 			return gbGOOD;
491 		}
492 	}
493 	/* fellthough, no device found */
494 	close(file_descriptor);
495 	return gbBAD;
496 }
497 
498 /* read status register */
499 /* should already be set to read from there */
500 /* will read at min time, avg time, max time, and another 50% */
501 /* returns 0 good, 1 bad */
502 /* tests to make sure bus not busy */
DS2482_readstatus(BYTE * c,FILE_DESCRIPTOR_OR_ERROR file_descriptor,unsigned long int min_usec,unsigned long int max_usec)503 static GOOD_OR_BAD DS2482_readstatus(BYTE * c, FILE_DESCRIPTOR_OR_ERROR file_descriptor, unsigned long int min_usec, unsigned long int max_usec)
504 {
505 	unsigned long int delta_usec = (max_usec - min_usec + 1) / 2;
506 	int i = 0;
507 	UT_delay_us(min_usec);		// at least get minimum out of the way
508 	do {
509 		int ret = i2c_smbus_read_byte(file_descriptor);
510 		if (ret < 0) {
511 			LEVEL_DEBUG("problem min=%lu max=%lu i=%d ret=%d", min_usec, max_usec, i, ret);
512 			return gbBAD;
513 		}
514 		if ((ret & DS2482_REG_STS_1WB) == 0x00) {
515 			c[0] = (BYTE) ret;
516 			LEVEL_DEBUG("ok");
517 			return gbGOOD;
518 		}
519 		if (i++ == 3) {
520 			LEVEL_DEBUG("still busy min=%lu max=%lu i=%d ret=%d", min_usec, max_usec, i, ret);
521 			return gbBAD;
522 		}
523 		UT_delay_us(delta_usec);	// increment up to three times
524 	} while (1);
525 }
526 
527 /* uses the "Triple" primative for faster search */
DS2482_next_both(struct device_search * ds,const struct parsedname * pn)528 static enum search_status DS2482_next_both(struct device_search *ds, const struct parsedname *pn)
529 {
530 	int search_direction = 0;	/* initialization just to forestall incorrect compiler warning */
531 	int bit_number;
532 	int last_zero = -1;
533 	FILE_DESCRIPTOR_OR_ERROR file_descriptor = pn->selected_connection->pown->file_descriptor;
534 	BYTE bits[3];
535 
536 	// initialize for search
537 	// if the last call was not the last one
538 	if (ds->LastDevice) {
539 		return search_done;
540 	}
541 
542 	if ( BAD( BUS_select(pn) ) ) {
543 		return search_error ;
544 	}
545 
546 	// need the reset done in BUS-select to set AnyDevices
547 	if ( pn->selected_connection->AnyDevices == anydevices_no ) {
548 		ds->LastDevice = 1;
549 		return search_done;
550 	}
551 
552 	/* Make sure we're using the correct channel */
553 	/* Appropriate search command */
554 	if ( BAD(BUS_send_data(&(ds->search), 1, pn)) ) {
555 		return search_error;
556 	}
557 	// loop to do the search
558 	for (bit_number = 0; bit_number < 64; ++bit_number) {
559 		LEVEL_DEBUG("bit number %d", bit_number);
560 		/* Set the direction bit */
561 		if (bit_number < ds->LastDiscrepancy) {
562 			search_direction = UT_getbit(ds->sn, bit_number);
563 		} else {
564 			search_direction = (bit_number == ds->LastDiscrepancy) ? 1 : 0;
565 		}
566 		/* Appropriate search command */
567 		if ( BAD( DS2482_triple(bits, search_direction, file_descriptor) ) )  {
568 			return search_error;
569 		}
570 		if (bits[0] || bits[1] || bits[2]) {
571 			if (bits[0] && bits[1]) {	/* 1,1 */
572 				/* No devices respond */
573 				ds->LastDevice = 1;
574 				return search_done;
575 			}
576 		} else {				/* 0,0,0 */
577 			last_zero = bit_number;
578 		}
579 		UT_setbit(ds->sn, bit_number, bits[2]);
580 	}							// loop until through serial number bits
581 
582 	if (CRC8(ds->sn, SERIAL_NUMBER_SIZE) || (bit_number < 64) || (ds->sn[0] == 0)) {
583 		/* Unsuccessful search or error -- possibly a device suddenly added */
584 		return search_error;
585 	}
586 	// if the search was successful then
587 	ds->LastDiscrepancy = last_zero;
588 	ds->LastDevice = (last_zero < 0);
589 	LEVEL_DEBUG("SN found: " SNformat, SNvar(ds->sn));
590 	return search_good;
591 }
592 
593 /* DS2482 Reset -- A little different from DS2480B */
594 // return 1 shorted, 0 ok, <0 error
DS2482_reset(const struct parsedname * pn)595 static RESET_TYPE DS2482_reset(const struct parsedname *pn)
596 {
597 	BYTE status_byte;
598 	struct connection_in * in = pn->selected_connection ;
599 	FILE_DESCRIPTOR_OR_ERROR file_descriptor = in->pown->file_descriptor;
600 
601 	/* Make sure we're using the correct channel */
602 	if ( BAD(DS2482_channel_select(in)) ) {
603 		return BUS_RESET_ERROR;
604 	}
605 
606 	/* write the RESET code */
607 	if (i2c_smbus_write_byte(file_descriptor, DS2482_CMD_1WIRE_RESET)) {
608 		return BUS_RESET_ERROR;
609 	}
610 
611 	/* wait */
612 	// rstl+rsth+.25 usec
613 
614 	/* read status */
615 	if ( BAD( DS2482_readstatus(&status_byte, file_descriptor, DS2482_1wire_reset_usec) ) ) {
616 		return BUS_RESET_ERROR;			// 8 * Tslot
617 	}
618 
619 	in->AnyDevices = (status_byte & DS2482_REG_STS_PPD) ? anydevices_yes : anydevices_no ;
620 	LEVEL_DEBUG("DS2482 "I2Cformat" Any devices found on reset? %s",I2Cvar(in),in->AnyDevices==anydevices_yes?"Yes":"No");
621 	return (status_byte & DS2482_REG_STS_SD) ? BUS_RESET_SHORT : BUS_RESET_OK;
622 }
623 
DS2482_sendback_data(const BYTE * data,BYTE * resp,const size_t len,const struct parsedname * pn)624 static GOOD_OR_BAD DS2482_sendback_data(const BYTE * data, BYTE * resp, const size_t len, const struct parsedname *pn)
625 {
626 	struct connection_in * in = pn->selected_connection ;
627 	FILE_DESCRIPTOR_OR_ERROR file_descriptor = in->pown->file_descriptor;
628 	size_t i;
629 
630 	/* Make sure we're using the correct channel */
631 	RETURN_BAD_IF_BAD(DS2482_channel_select(in)) ;
632 
633 	TrafficOut( "write", data, len, in ) ;
634 	for (i = 0; i < len; ++i) {
635 		RETURN_BAD_IF_BAD(DS2482_send_and_get(file_descriptor, data[i], &resp[i])) ;
636 	}
637 	TrafficOut( "response", resp, len, in ) ;
638 	return gbGOOD;
639 }
640 
641 /* Single byte -- assumes channel selection already done */
DS2482_send_and_get(FILE_DESCRIPTOR_OR_ERROR file_descriptor,const BYTE wr,BYTE * rd)642 static GOOD_OR_BAD DS2482_send_and_get(FILE_DESCRIPTOR_OR_ERROR file_descriptor, const BYTE wr, BYTE * rd)
643 {
644 	int read_back;
645 	BYTE c;
646 
647 	/* Write data byte */
648 	if (i2c_smbus_write_byte_data(file_descriptor, DS2482_CMD_1WIRE_WRITE_BYTE, wr) < 0) {
649 		return gbBAD;
650 	}
651 
652 	/* read status for done */
653 	RETURN_BAD_IF_BAD( DS2482_readstatus(&c, file_descriptor, DS2482_1wire_write_usec) ) ;
654 
655 	/* Select the data register */
656 	if (i2c_smbus_write_byte_data(file_descriptor, DS2482_CMD_SET_READ_PTR, DS2482_READ_DATA_REGISTER) < 0) {
657 		return gbBAD;
658 	}
659 
660 	/* Read the data byte */
661 	read_back = i2c_smbus_read_byte(file_descriptor);
662 
663 	if (read_back < 0) {
664 		return gbBAD;
665 	}
666 	rd[0] = (BYTE) read_back;
667 
668 	return gbGOOD;
669 }
670 
671 /* Is this a DS2483? Try to set to new register */
DS2483_test(FILE_DESCRIPTOR_OR_ERROR file_descriptor)672 static GOOD_OR_BAD DS2483_test(FILE_DESCRIPTOR_OR_ERROR file_descriptor)
673 {
674 	/* Select the data register */
675 	if (i2c_smbus_write_byte_data(file_descriptor, DS2482_CMD_SET_READ_PTR, DS2482_PORT_CONFIGURATION_REGISTER) < 0) {
676 		LEVEL_DEBUG("Cannot set to port configuration -- not a DS2483");
677 		return gbBAD;
678 	}
679 	LEVEL_DEBUG("Can set to port configuration! a DS2483!");
680 	return gbGOOD;
681 }
682 
683 /* It's a DS2482 -- whether 1 channel or 8 channel not yet determined */
684 /* All general stored data will be assigned to this "head" channel */
HeadChannel(struct connection_in * head)685 static GOOD_OR_BAD HeadChannel(struct connection_in *head)
686 {
687 	/* Intentionally put the wrong index */
688 	head->master.i2c.index = 1;
689 
690 	if ( BAD(DS2482_channel_select(head)) ) {	/* Couldn't switch */
691 		head->master.i2c.index = 0;	/* restore correct value */
692 		LEVEL_CONNECT("DS2482-100 (Single channel)");
693 		if ( GOOD(DS2483_test(head->pown->file_descriptor)) ) {
694 			head->master.i2c.type = ds2483 ;
695 		} else {
696 				head->master.i2c.type = ds2482_100 ;
697 		}
698 
699 		return gbGOOD;				/* happy as DS2482-100 */
700 	}
701 
702 	// It's a DS2482-800 (8 channels) to set up other 7 with this one as "head"
703 	LEVEL_CONNECT("DS2482-800 (Eight channels)");
704 	/* Must be a DS2482-800 */
705 	head->master.i2c.channels = 8;
706 	head->master.i2c.type = ds2482_800 ;
707 	head->Adapter = adapter_DS2482_800;
708 
709 	return CreateChannels(head);
710 }
711 
712 /* create more channels,
713    inserts in connection_in chain
714    "in" points to  first (head) channel
715    called only for DS12482-800
716    NOTE: coded assuming num = 1 or 8 only
717  */
CreateChannels(struct connection_in * head)718 static GOOD_OR_BAD CreateChannels(struct connection_in *head)
719 {
720 	int i;
721 	char *name[] = { "DS2482-800(0)", "DS2482-800(1)", "DS2482-800(2)",
722 		"DS2482-800(3)", "DS2482-800(4)", "DS2482-800(5)", "DS2482-800(6)",
723 		"DS2482-800(7)",
724 	};
725 	head->master.i2c.index = 0;
726 	head->adapter_name = name[0];
727 	for (i = 1; i < 8; ++i) {
728 		struct connection_in * added = AddtoPort(head->pown);
729 		if (added == NO_CONNECTION) {
730 			return gbBAD;
731 		}
732 		added->master.i2c.index = i;
733 		added->adapter_name = name[i];
734 	}
735 	return gbGOOD;
736 }
737 
DS2482_triple(BYTE * bits,int direction,FILE_DESCRIPTOR_OR_ERROR file_descriptor)738 static GOOD_OR_BAD DS2482_triple(BYTE * bits, int direction, FILE_DESCRIPTOR_OR_ERROR file_descriptor)
739 {
740 	/* 3 bits in bits */
741 	BYTE c;
742 
743 	LEVEL_DEBUG("-> TRIPLET attempt direction %d", direction);
744 	/* Write TRIPLE command */
745 	if (i2c_smbus_write_byte_data(file_descriptor, DS2482_CMD_1WIRE_TRIPLET, direction ? 0xFF : 0) < 0) {
746 		return gbBAD;
747 	}
748 
749 	/* read status */
750 	RETURN_BAD_IF_BAD(DS2482_readstatus(&c, file_descriptor, DS2482_1wire_triplet_usec)) ;
751 
752 	bits[0] = (c & DS2482_REG_STS_SBR) != 0;
753 	bits[1] = (c & DS2482_REG_STS_TSB) != 0;
754 	bits[2] = (c & DS2482_REG_STS_DIR) != 0;
755 	LEVEL_DEBUG("<- TRIPLET %d %d %d", bits[0], bits[1], bits[2]);
756 	return gbGOOD;
757 }
758 
DS2482_channel_select(struct connection_in * in)759 static GOOD_OR_BAD DS2482_channel_select(struct connection_in * in)
760 {
761 	struct connection_in *head = in->master.i2c.head;
762 	int chan = in->master.i2c.index;
763 	FILE_DESCRIPTOR_OR_ERROR file_descriptor = in->pown->file_descriptor;
764 
765 	/*
766 		Write and verify codes for the CHANNEL_SELECT command (DS2482-800 only).
767 		To set the channel, write the value at the index of the channel.
768 		Read and compare against the corresponding value to verify the change.
769 	*/
770 	static const BYTE W_chan[8] = { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 };
771 	static const BYTE R_chan[8] = { 0xB8, 0xB1, 0xAA, 0xA3, 0x9C, 0x95, 0x8E, 0x87 };
772 
773 	if ( FILE_DESCRIPTOR_NOT_VALID(file_descriptor) ) {
774 		LEVEL_CONNECT("Calling a closed i2c channel (%d) "I2Cformat" ", chan,I2Cvar(in));
775 		return gbBAD;
776 	}
777 
778 	/* Already properly selected? */
779 	/* All `100 (1 channel) will be caught here */
780 	if (chan != head->master.i2c.current) {
781 		int read_back;
782 
783 		/* Select command */
784 		if (i2c_smbus_write_byte_data(file_descriptor, DS2482_CMD_CHANNEL_SELECT, W_chan[chan]) < 0) {
785 			LEVEL_DEBUG("Channel select set error");
786 			return gbBAD;
787 		}
788 
789 		/* Read back and confirm */
790 		read_back = i2c_smbus_read_byte(file_descriptor);
791 		if (read_back < 0) {
792 			LEVEL_DEBUG("Channel select get error");
793 			return gbBAD; // flag for DS2482-100 vs -800 detection
794 		}
795 		if (((BYTE) read_back) != R_chan[chan]) {
796 			LEVEL_DEBUG("Channel selected doesn't match");
797 			return gbBAD; // flag for DS2482-100 vs -800 detection
798 		}
799 
800 		/* Set the channel in head */
801 		head->master.i2c.current = in->master.i2c.index;
802 	}
803 
804 	/* Now check the configuration register */
805 	/* This is since configuration is per chip, not just channel */
806 	if (in->master.i2c.configreg != head->master.i2c.configchip) {
807 		return SetConfiguration(in->master.i2c.configreg, in);
808 	}
809 
810 	return gbGOOD;
811 }
812 
813 /* Set the configuration register, both for this channel, and for head global data */
814 /* Note, config is stored as only the lower nibble */
SetConfiguration(BYTE c,struct connection_in * in)815 static GOOD_OR_BAD SetConfiguration(BYTE c, struct connection_in *in)
816 {
817 	struct connection_in *head = in->master.i2c.head;
818 	FILE_DESCRIPTOR_OR_ERROR file_descriptor = in->pown->file_descriptor;
819 	int read_back;
820 
821 	/* Write, readback, and compare configuration register */
822 	/* Logic error fix from Uli Raich */
823 	if (i2c_smbus_write_byte_data(file_descriptor, DS2482_CMD_WRITE_CONFIG, c | ((~c) << 4))
824 		|| (read_back = i2c_smbus_read_byte(file_descriptor)) < 0 || ((BYTE) read_back != c)
825 		) {
826 		head->master.i2c.configchip = 0xFF;	// bad value to trigger retry
827 		LEVEL_CONNECT("Trouble changing DS2482 configuration register "I2Cformat" ",I2Cvar(in));
828 		return gbBAD;
829 	}
830 	/* Clear the strong pull-up power bit(register is automatically cleared by reset) */
831 	in->master.i2c.configreg = head->master.i2c.configchip = c & ~DS2482_REG_CFG_SPU;
832 	return gbGOOD;
833 }
834 
DS2482_PowerByte(const BYTE byte,BYTE * resp,const UINT delay,const struct parsedname * pn)835 static GOOD_OR_BAD DS2482_PowerByte(const BYTE byte, BYTE * resp, const UINT delay, const struct parsedname *pn)
836 {
837 	struct connection_in * in = pn->selected_connection ;
838 
839 	/* Make sure we're using the correct channel */
840 	RETURN_BAD_IF_BAD(DS2482_channel_select(in)) ;
841 
842 	/* Set the power (bit is automatically cleared by reset) */
843 	TrafficOut("power write", &byte, 1, in ) ;
844 	RETURN_BAD_IF_BAD(SetConfiguration(  in->master.i2c.configreg | DS2482_REG_CFG_SPU, in)) ;
845 
846 	/* send and get byte (and trigger strong pull-up */
847 	RETURN_BAD_IF_BAD(DS2482_send_and_get( in->pown->file_descriptor, byte, resp)) ;
848 	TrafficOut("power response", resp, 1, in ) ;
849 
850 	UT_delay(delay);
851 
852 	return gbGOOD;
853 }
854 
DS2482_close(struct connection_in * in)855 static void DS2482_close(struct connection_in *in)
856 {
857 	if (in == NO_CONNECTION) {
858 		return;
859 	}
860 }
861 #endif							/* OW_I2C */
862