1 /* $OpenBSD: onewire_subr.c,v 1.4 2010/07/19 23:44:09 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * 1-Wire bus miscellaneous routines. 21 */ 22 23 #include <sys/param.h> 24 #include <sys/systm.h> 25 #include <sys/device.h> 26 27 #include <dev/onewire/onewiredevs.h> 28 #include <dev/onewire/onewirereg.h> 29 #include <dev/onewire/onewirevar.h> 30 31 #ifdef ONEWIREVERBOSE 32 #include <dev/onewire/onewiredevs_data.h> 33 #endif 34 35 static const u_int8_t crc8_table[] = { 36 0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83, 37 0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41, 38 0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e, 39 0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc, 40 0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0, 41 0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62, 42 0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d, 43 0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff, 44 0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5, 45 0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07, 46 0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58, 47 0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a, 48 0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6, 49 0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24, 50 0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b, 51 0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9, 52 0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f, 53 0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd, 54 0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92, 55 0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50, 56 0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c, 57 0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee, 58 0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1, 59 0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73, 60 0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49, 61 0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b, 62 0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4, 63 0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16, 64 0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a, 65 0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8, 66 0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7, 67 0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35 68 }; 69 70 static const u_int8_t crc16_table_low[] = { 71 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 72 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 73 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 74 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 75 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 76 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 77 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 78 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 79 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 80 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 81 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 82 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 83 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 84 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 85 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 86 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 87 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 88 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 89 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 90 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 91 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 92 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 93 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 94 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 95 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 96 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 97 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 98 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 99 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40, 100 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 101 0x00, 0xc1, 0x81, 0x40, 0x01, 0xc0, 0x80, 0x41, 102 0x01, 0xc0, 0x80, 0x41, 0x00, 0xc1, 0x81, 0x40 103 }; 104 105 static const u_int8_t crc16_table_high[] = { 106 0x00, 0xc0, 0xc1, 0x01, 0xc3, 0x03, 0x02, 0xc2, 107 0xc6, 0x06, 0x07, 0xc7, 0x05, 0xc5, 0xc4, 0x04, 108 0xcc, 0x0c, 0x0d, 0xcd, 0x0f, 0xcf, 0xce, 0x0e, 109 0x0a, 0xca, 0xcb, 0x0b, 0xc9, 0x09, 0x08, 0xc8, 110 0xd8, 0x18, 0x19, 0xd9, 0x1b, 0xdb, 0xda, 0x1a, 111 0x1e, 0xde, 0xdf, 0x1f, 0xdd, 0x1d, 0x1c, 0xdc, 112 0x14, 0xd4, 0xd5, 0x15, 0xd7, 0x17, 0x16, 0xd6, 113 0xd2, 0x12, 0x13, 0xd3, 0x11, 0xd1, 0xd0, 0x10, 114 0xf0, 0x30, 0x31, 0xf1, 0x33, 0xf3, 0xf2, 0x32, 115 0x36, 0xf6, 0xf7, 0x37, 0xf5, 0x35, 0x34, 0xf4, 116 0x3c, 0xfc, 0xfd, 0x3d, 0xff, 0x3f, 0x3e, 0xfe, 117 0xfa, 0x3a, 0x3b, 0xfb, 0x39, 0xf9, 0xf8, 0x38, 118 0x28, 0xe8, 0xe9, 0x29, 0xeb, 0x2b, 0x2a, 0xea, 119 0xee, 0x2e, 0x2f, 0xef, 0x2d, 0xed, 0xec, 0x2c, 120 0xe4, 0x24, 0x25, 0xe5, 0x27, 0xe7, 0xe6, 0x26, 121 0x22, 0xe2, 0xe3, 0x23, 0xe1, 0x21, 0x20, 0xe0, 122 0xa0, 0x60, 0x61, 0xa1, 0x63, 0xa3, 0xa2, 0x62, 123 0x66, 0xa6, 0xa7, 0x67, 0xa5, 0x65, 0x64, 0xa4, 124 0x6c, 0xac, 0xad, 0x6d, 0xaf, 0x6f, 0x6e, 0xae, 125 0xaa, 0x6a, 0x6b, 0xab, 0x69, 0xa9, 0xa8, 0x68, 126 0x78, 0xb8, 0xb9, 0x79, 0xbb, 0x7b, 0x7a, 0xba, 127 0xbe, 0x7e, 0x7f, 0xbf, 0x7d, 0xbd, 0xbc, 0x7c, 128 0xb4, 0x74, 0x75, 0xb5, 0x77, 0xb7, 0xb6, 0x76, 129 0x72, 0xb2, 0xb3, 0x73, 0xb1, 0x71, 0x70, 0xb0, 130 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 131 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 132 0x9c, 0x5c, 0x5d, 0x9d, 0x5f, 0x9f, 0x9e, 0x5e, 133 0x5a, 0x9a, 0x9b, 0x5b, 0x99, 0x59, 0x58, 0x98, 134 0x88, 0x48, 0x49, 0x89, 0x4b, 0x8b, 0x8a, 0x4a, 135 0x4e, 0x8e, 0x8f, 0x4f, 0x8d, 0x4d, 0x4c, 0x8c, 136 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 137 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 138 }; 139 140 int 141 onewire_crc(const void *buf, int len) 142 { 143 const u_int8_t *p = buf; 144 u_int8_t crc = 0; 145 146 while (len--) 147 crc = crc8_table[crc ^ *p++]; 148 149 return (crc); 150 } 151 152 u_int16_t 153 onewire_crc16(const void *buf, int len) 154 { 155 const u_int8_t *p = buf; 156 u_int16_t crc = 0; 157 u_int16_t tmpcrc; 158 int idx; 159 160 while (len--) { 161 idx = (crc & 0xff) ^ *p++; 162 tmpcrc = crc16_table_high[idx] << 8; 163 tmpcrc |= crc16_table_low[idx] ^ (crc >> 8); 164 crc = tmpcrc; 165 } 166 167 return (crc); 168 } 169 170 const char * 171 onewire_famname(int type) 172 { 173 #ifdef ONEWIREVERBOSE 174 const struct onewire_family *of; 175 176 for (of = onewire_famtab; of->of_name != NULL; of++) 177 if (of->of_type == type) 178 return (of->of_name); 179 #endif 180 181 return (NULL); 182 } 183 184 int 185 onewire_matchbyfam(struct onewire_attach_args *oa, 186 const struct onewire_matchfam *fams, int nent) 187 { 188 const struct onewire_matchfam *om; 189 int i; 190 191 for (i = 0, om = fams; i < nent; i++, om++) 192 if (ONEWIRE_ROM_FAMILY_TYPE(oa->oa_rom) == om->om_type) 193 return (1); 194 195 return (0); 196 } 197