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
onewire_crc(const void * buf,int len)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
onewire_crc16(const void * buf,int len)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 *
onewire_famname(int type)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
onewire_matchbyfam(struct onewire_attach_args * oa,const struct onewire_matchfam * fams,int nent)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