xref: /openbsd/sys/dev/onewire/onewire_subr.c (revision ca4f184d)
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