aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1/w1_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/w1/w1_io.c')
-rw-r--r--drivers/w1/w1_io.c117
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
58static void w1_write_bit(struct w1_master *dev, int bit);
59static u8 w1_read_bit(struct w1_master *dev);
60
61/**
62 * Generates a write-0 or write-1 cycle and samples the level.
63 */
58u8 w1_touch_bit(struct w1_master *dev, int bit) 64u8 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
66void 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 */
80static 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 */
81void w1_write_8(struct w1_master *dev, u8 byte) 101void 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
92u8 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 */
117static 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 */
144u8 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 */
107u8 w1_read_8(struct w1_master * dev) 179u8 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
121void 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 */
201void 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 */
132u8 w1_read_block(struct w1_master *dev, u8 *buf, int len) 220u8 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 */
148int w1_reset_bus(struct w1_master *dev) 242int 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
186EXPORT_SYMBOL(w1_write_bit); 280EXPORT_SYMBOL(w1_touch_bit);
187EXPORT_SYMBOL(w1_write_8); 281EXPORT_SYMBOL(w1_write_8);
188EXPORT_SYMBOL(w1_read_bit);
189EXPORT_SYMBOL(w1_read_8); 282EXPORT_SYMBOL(w1_read_8);
190EXPORT_SYMBOL(w1_reset_bus); 283EXPORT_SYMBOL(w1_reset_bus);
191EXPORT_SYMBOL(w1_calc_crc8); 284EXPORT_SYMBOL(w1_calc_crc8);