diff options
Diffstat (limited to 'drivers/w1/w1_io.c')
-rw-r--r-- | drivers/w1/w1_io.c | 68 |
1 files changed, 64 insertions, 4 deletions
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c index 0056ef69009b..97b338a16abc 100644 --- a/drivers/w1/w1_io.c +++ b/drivers/w1/w1_io.c | |||
@@ -93,6 +93,40 @@ static void w1_write_bit(struct w1_master *dev, int bit) | |||
93 | } | 93 | } |
94 | 94 | ||
95 | /** | 95 | /** |
96 | * Pre-write operation, currently only supporting strong pullups. | ||
97 | * Program the hardware for a strong pullup, if one has been requested and | ||
98 | * the hardware supports it. | ||
99 | * | ||
100 | * @param dev the master device | ||
101 | */ | ||
102 | static void w1_pre_write(struct w1_master *dev) | ||
103 | { | ||
104 | if (dev->pullup_duration && | ||
105 | dev->enable_pullup && dev->bus_master->set_pullup) { | ||
106 | dev->bus_master->set_pullup(dev->bus_master->data, | ||
107 | dev->pullup_duration); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | /** | ||
112 | * Post-write operation, currently only supporting strong pullups. | ||
113 | * If a strong pullup was requested, clear it if the hardware supports | ||
114 | * them, or execute the delay otherwise, in either case clear the request. | ||
115 | * | ||
116 | * @param dev the master device | ||
117 | */ | ||
118 | static void w1_post_write(struct w1_master *dev) | ||
119 | { | ||
120 | if (dev->pullup_duration) { | ||
121 | if (dev->enable_pullup && dev->bus_master->set_pullup) | ||
122 | dev->bus_master->set_pullup(dev->bus_master->data, 0); | ||
123 | else | ||
124 | msleep(dev->pullup_duration); | ||
125 | dev->pullup_duration = 0; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | /** | ||
96 | * Writes 8 bits. | 130 | * Writes 8 bits. |
97 | * | 131 | * |
98 | * @param dev the master device | 132 | * @param dev the master device |
@@ -102,11 +136,17 @@ void w1_write_8(struct w1_master *dev, u8 byte) | |||
102 | { | 136 | { |
103 | int i; | 137 | int i; |
104 | 138 | ||
105 | if (dev->bus_master->write_byte) | 139 | if (dev->bus_master->write_byte) { |
140 | w1_pre_write(dev); | ||
106 | dev->bus_master->write_byte(dev->bus_master->data, byte); | 141 | dev->bus_master->write_byte(dev->bus_master->data, byte); |
142 | } | ||
107 | else | 143 | else |
108 | for (i = 0; i < 8; ++i) | 144 | for (i = 0; i < 8; ++i) { |
145 | if (i == 7) | ||
146 | w1_pre_write(dev); | ||
109 | w1_touch_bit(dev, (byte >> i) & 0x1); | 147 | w1_touch_bit(dev, (byte >> i) & 0x1); |
148 | } | ||
149 | w1_post_write(dev); | ||
110 | } | 150 | } |
111 | EXPORT_SYMBOL_GPL(w1_write_8); | 151 | EXPORT_SYMBOL_GPL(w1_write_8); |
112 | 152 | ||
@@ -203,11 +243,14 @@ void w1_write_block(struct w1_master *dev, const u8 *buf, int len) | |||
203 | { | 243 | { |
204 | int i; | 244 | int i; |
205 | 245 | ||
206 | if (dev->bus_master->write_block) | 246 | if (dev->bus_master->write_block) { |
247 | w1_pre_write(dev); | ||
207 | dev->bus_master->write_block(dev->bus_master->data, buf, len); | 248 | dev->bus_master->write_block(dev->bus_master->data, buf, len); |
249 | } | ||
208 | else | 250 | else |
209 | for (i = 0; i < len; ++i) | 251 | for (i = 0; i < len; ++i) |
210 | w1_write_8(dev, buf[i]); | 252 | w1_write_8(dev, buf[i]); /* calls w1_pre_write */ |
253 | w1_post_write(dev); | ||
211 | } | 254 | } |
212 | EXPORT_SYMBOL_GPL(w1_write_block); | 255 | EXPORT_SYMBOL_GPL(w1_write_block); |
213 | 256 | ||
@@ -306,3 +349,20 @@ int w1_reset_select_slave(struct w1_slave *sl) | |||
306 | return 0; | 349 | return 0; |
307 | } | 350 | } |
308 | EXPORT_SYMBOL_GPL(w1_reset_select_slave); | 351 | EXPORT_SYMBOL_GPL(w1_reset_select_slave); |
352 | |||
353 | /** | ||
354 | * Put out a strong pull-up of the specified duration after the next write | ||
355 | * operation. Not all hardware supports strong pullups. Hardware that | ||
356 | * doesn't support strong pullups will sleep for the given time after the | ||
357 | * write operation without a strong pullup. This is a one shot request for | ||
358 | * the next write, specifying zero will clear a previous request. | ||
359 | * The w1 master lock must be held. | ||
360 | * | ||
361 | * @param delay time in milliseconds | ||
362 | * @return 0=success, anything else=error | ||
363 | */ | ||
364 | void w1_next_pullup(struct w1_master *dev, int delay) | ||
365 | { | ||
366 | dev->pullup_duration = delay; | ||
367 | } | ||
368 | EXPORT_SYMBOL_GPL(w1_next_pullup); | ||