diff options
Diffstat (limited to 'drivers/w1/w1_io.c')
-rw-r--r-- | drivers/w1/w1_io.c | 117 |
1 files changed, 105 insertions, 12 deletions
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c index 02796b5a39f6..00f032220173 100644 --- a/drivers/w1/w1_io.c +++ b/drivers/w1/w1_io.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * w1_io.c | 2 | * w1_io.c |
3 | * | 3 | * |
4 | * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 4 | * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> |
5 | * | 5 | * |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -55,15 +55,29 @@ void w1_delay(unsigned long tm) | |||
55 | udelay(tm * w1_delay_parm); | 55 | udelay(tm * w1_delay_parm); |
56 | } | 56 | } |
57 | 57 | ||
58 | static void w1_write_bit(struct w1_master *dev, int bit); | ||
59 | static u8 w1_read_bit(struct w1_master *dev); | ||
60 | |||
61 | /** | ||
62 | * Generates a write-0 or write-1 cycle and samples the level. | ||
63 | */ | ||
58 | u8 w1_touch_bit(struct w1_master *dev, int bit) | 64 | u8 w1_touch_bit(struct w1_master *dev, int bit) |
59 | { | 65 | { |
60 | if (dev->bus_master->touch_bit) | 66 | if (dev->bus_master->touch_bit) |
61 | return dev->bus_master->touch_bit(dev->bus_master->data, bit); | 67 | return dev->bus_master->touch_bit(dev->bus_master->data, bit); |
62 | else | 68 | else if (bit) |
63 | return w1_read_bit(dev); | 69 | return w1_read_bit(dev); |
70 | else { | ||
71 | w1_write_bit(dev, 0); | ||
72 | return(0); | ||
73 | } | ||
64 | } | 74 | } |
65 | 75 | ||
66 | void w1_write_bit(struct w1_master *dev, int bit) | 76 | /** |
77 | * Generates a write-0 or write-1 cycle. | ||
78 | * Only call if dev->bus_master->touch_bit is NULL | ||
79 | */ | ||
80 | static void w1_write_bit(struct w1_master *dev, int bit) | ||
67 | { | 81 | { |
68 | if (bit) { | 82 | if (bit) { |
69 | dev->bus_master->write_bit(dev->bus_master->data, 0); | 83 | dev->bus_master->write_bit(dev->bus_master->data, 0); |
@@ -78,6 +92,12 @@ void w1_write_bit(struct w1_master *dev, int bit) | |||
78 | } | 92 | } |
79 | } | 93 | } |
80 | 94 | ||
95 | /** | ||
96 | * Writes 8 bits. | ||
97 | * | ||
98 | * @param dev the master device | ||
99 | * @param byte the byte to write | ||
100 | */ | ||
81 | void w1_write_8(struct w1_master *dev, u8 byte) | 101 | void w1_write_8(struct w1_master *dev, u8 byte) |
82 | { | 102 | { |
83 | int i; | 103 | int i; |
@@ -86,10 +106,15 @@ void w1_write_8(struct w1_master *dev, u8 byte) | |||
86 | dev->bus_master->write_byte(dev->bus_master->data, byte); | 106 | dev->bus_master->write_byte(dev->bus_master->data, byte); |
87 | else | 107 | else |
88 | for (i = 0; i < 8; ++i) | 108 | for (i = 0; i < 8; ++i) |
89 | w1_write_bit(dev, (byte >> i) & 0x1); | 109 | w1_touch_bit(dev, (byte >> i) & 0x1); |
90 | } | 110 | } |
91 | 111 | ||
92 | u8 w1_read_bit(struct w1_master *dev) | 112 | |
113 | /** | ||
114 | * Generates a write-1 cycle and samples the level. | ||
115 | * Only call if dev->bus_master->touch_bit is NULL | ||
116 | */ | ||
117 | static u8 w1_read_bit(struct w1_master *dev) | ||
93 | { | 118 | { |
94 | int result; | 119 | int result; |
95 | 120 | ||
@@ -104,6 +129,53 @@ u8 w1_read_bit(struct w1_master *dev) | |||
104 | return result & 0x1; | 129 | return result & 0x1; |
105 | } | 130 | } |
106 | 131 | ||
132 | /** | ||
133 | * Does a triplet - used for searching ROM addresses. | ||
134 | * Return bits: | ||
135 | * bit 0 = id_bit | ||
136 | * bit 1 = comp_bit | ||
137 | * bit 2 = dir_taken | ||
138 | * If both bits 0 & 1 are set, the search should be restarted. | ||
139 | * | ||
140 | * @param dev the master device | ||
141 | * @param bdir the bit to write if both id_bit and comp_bit are 0 | ||
142 | * @return bit fields - see above | ||
143 | */ | ||
144 | u8 w1_triplet(struct w1_master *dev, int bdir) | ||
145 | { | ||
146 | if ( dev->bus_master->triplet ) | ||
147 | return(dev->bus_master->triplet(dev->bus_master->data, bdir)); | ||
148 | else { | ||
149 | u8 id_bit = w1_touch_bit(dev, 1); | ||
150 | u8 comp_bit = w1_touch_bit(dev, 1); | ||
151 | u8 retval; | ||
152 | |||
153 | if ( id_bit && comp_bit ) | ||
154 | return(0x03); /* error */ | ||
155 | |||
156 | if ( !id_bit && !comp_bit ) { | ||
157 | /* Both bits are valid, take the direction given */ | ||
158 | retval = bdir ? 0x04 : 0; | ||
159 | } else { | ||
160 | /* Only one bit is valid, take that direction */ | ||
161 | bdir = id_bit; | ||
162 | retval = id_bit ? 0x05 : 0x02; | ||
163 | } | ||
164 | |||
165 | if ( dev->bus_master->touch_bit ) | ||
166 | w1_touch_bit(dev, bdir); | ||
167 | else | ||
168 | w1_write_bit(dev, bdir); | ||
169 | return(retval); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * Reads 8 bits. | ||
175 | * | ||
176 | * @param dev the master device | ||
177 | * @return the byte read | ||
178 | */ | ||
107 | u8 w1_read_8(struct w1_master * dev) | 179 | u8 w1_read_8(struct w1_master * dev) |
108 | { | 180 | { |
109 | int i; | 181 | int i; |
@@ -113,12 +185,20 @@ u8 w1_read_8(struct w1_master * dev) | |||
113 | res = dev->bus_master->read_byte(dev->bus_master->data); | 185 | res = dev->bus_master->read_byte(dev->bus_master->data); |
114 | else | 186 | else |
115 | for (i = 0; i < 8; ++i) | 187 | for (i = 0; i < 8; ++i) |
116 | res |= (w1_read_bit(dev) << i); | 188 | res |= (w1_touch_bit(dev,1) << i); |
117 | 189 | ||
118 | return res; | 190 | return res; |
119 | } | 191 | } |
120 | 192 | ||
121 | void w1_write_block(struct w1_master *dev, u8 *buf, int len) | 193 | /** |
194 | * Writes a series of bytes. | ||
195 | * | ||
196 | * @param dev the master device | ||
197 | * @param buf pointer to the data to write | ||
198 | * @param len the number of bytes to write | ||
199 | * @return the byte read | ||
200 | */ | ||
201 | void w1_write_block(struct w1_master *dev, const u8 *buf, int len) | ||
122 | { | 202 | { |
123 | int i; | 203 | int i; |
124 | 204 | ||
@@ -129,6 +209,14 @@ void w1_write_block(struct w1_master *dev, u8 *buf, int len) | |||
129 | w1_write_8(dev, buf[i]); | 209 | w1_write_8(dev, buf[i]); |
130 | } | 210 | } |
131 | 211 | ||
212 | /** | ||
213 | * Reads a series of bytes. | ||
214 | * | ||
215 | * @param dev the master device | ||
216 | * @param buf pointer to the buffer to fill | ||
217 | * @param len the number of bytes to read | ||
218 | * @return the number of bytes read | ||
219 | */ | ||
132 | u8 w1_read_block(struct w1_master *dev, u8 *buf, int len) | 220 | u8 w1_read_block(struct w1_master *dev, u8 *buf, int len) |
133 | { | 221 | { |
134 | int i; | 222 | int i; |
@@ -145,9 +233,15 @@ u8 w1_read_block(struct w1_master *dev, u8 *buf, int len) | |||
145 | return ret; | 233 | return ret; |
146 | } | 234 | } |
147 | 235 | ||
236 | /** | ||
237 | * Issues a reset bus sequence. | ||
238 | * | ||
239 | * @param dev The bus master pointer | ||
240 | * @return 0=Device present, 1=No device present or error | ||
241 | */ | ||
148 | int w1_reset_bus(struct w1_master *dev) | 242 | int w1_reset_bus(struct w1_master *dev) |
149 | { | 243 | { |
150 | int result = 0; | 244 | int result; |
151 | 245 | ||
152 | if (dev->bus_master->reset_bus) | 246 | if (dev->bus_master->reset_bus) |
153 | result = dev->bus_master->reset_bus(dev->bus_master->data) & 0x1; | 247 | result = dev->bus_master->reset_bus(dev->bus_master->data) & 0x1; |
@@ -180,12 +274,11 @@ void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb) | |||
180 | if (dev->bus_master->search) | 274 | if (dev->bus_master->search) |
181 | dev->bus_master->search(dev->bus_master->data, cb); | 275 | dev->bus_master->search(dev->bus_master->data, cb); |
182 | else | 276 | else |
183 | w1_search(dev); | 277 | w1_search(dev, cb); |
184 | } | 278 | } |
185 | 279 | ||
186 | EXPORT_SYMBOL(w1_write_bit); | 280 | EXPORT_SYMBOL(w1_touch_bit); |
187 | EXPORT_SYMBOL(w1_write_8); | 281 | EXPORT_SYMBOL(w1_write_8); |
188 | EXPORT_SYMBOL(w1_read_bit); | ||
189 | EXPORT_SYMBOL(w1_read_8); | 282 | EXPORT_SYMBOL(w1_read_8); |
190 | EXPORT_SYMBOL(w1_reset_bus); | 283 | EXPORT_SYMBOL(w1_reset_bus); |
191 | EXPORT_SYMBOL(w1_calc_crc8); | 284 | EXPORT_SYMBOL(w1_calc_crc8); |