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