diff options
author | Jan Kandziora <jjj@gmx.de> | 2017-09-20 17:52:46 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-04 04:29:22 -0400 |
commit | ebc4768ac4971eab4b570e733e47ac9dfd0e4175 (patch) | |
tree | cfe3e1128131d87a19cbcb81a92db4b1925931e0 | |
parent | eb8470db8bc018fc28901e4e3b0f48e33f1ea7df (diff) |
add w1_ds28e17 driver for the DS28E17 Onewire to I2C master bridge
This subpatch adds a driver for the DS28E17 Onewire to I2C master bridge.
Signed-off-by: Jan Kandziora <jjj@gmx.de>
Acked-by: Evgeniy Polyakov <zbr@ioremap.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | Documentation/ABI/testing/sysfs-driver-w1_ds28e17 | 21 | ||||
-rw-r--r-- | Documentation/w1/slaves/00-INDEX | 2 | ||||
-rw-r--r-- | Documentation/w1/slaves/w1_ds28e17 | 68 | ||||
-rw-r--r-- | drivers/w1/slaves/Kconfig | 15 | ||||
-rw-r--r-- | drivers/w1/slaves/Makefile | 1 | ||||
-rw-r--r-- | drivers/w1/slaves/w1_ds28e17.c | 771 |
6 files changed, 878 insertions, 0 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-w1_ds28e17 b/Documentation/ABI/testing/sysfs-driver-w1_ds28e17 new file mode 100644 index 000000000000..d301e7017afe --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-w1_ds28e17 | |||
@@ -0,0 +1,21 @@ | |||
1 | What: /sys/bus/w1/devices/19-<id>/speed | ||
2 | Date: Sep 2017 | ||
3 | KernelVersion: 4.14 | ||
4 | Contact: Jan Kandziora <jjj@gmx.de> | ||
5 | Description: When written, this file sets the I2C speed on the connected | ||
6 | DS28E17 chip. When read, it reads the current setting from | ||
7 | the DS28E17 chip. | ||
8 | Valid values: 100, 400, 900 [kBaud]. | ||
9 | Default 100, can be set by w1_ds28e17.speed= module parameter. | ||
10 | Users: w1_ds28e17 driver | ||
11 | |||
12 | What: /sys/bus/w1/devices/19-<id>/stretch | ||
13 | Date: Sep 2017 | ||
14 | KernelVersion: 4.14 | ||
15 | Contact: Jan Kandziora <jjj@gmx.de> | ||
16 | Description: When written, this file sets the multiplier used to calculate | ||
17 | the busy timeout for I2C operations on the connected DS28E17 | ||
18 | chip. When read, returns the current setting. | ||
19 | Valid values: 1 to 9. | ||
20 | Default 1, can be set by w1_ds28e17.stretch= module parameter. | ||
21 | Users: w1_ds28e17 driver | ||
diff --git a/Documentation/w1/slaves/00-INDEX b/Documentation/w1/slaves/00-INDEX index 8d76718e1ea2..68946f83e579 100644 --- a/Documentation/w1/slaves/00-INDEX +++ b/Documentation/w1/slaves/00-INDEX | |||
@@ -10,3 +10,5 @@ w1_ds2438 | |||
10 | - The Maxim/Dallas Semiconductor ds2438 smart battery monitor. | 10 | - The Maxim/Dallas Semiconductor ds2438 smart battery monitor. |
11 | w1_ds28e04 | 11 | w1_ds28e04 |
12 | - The Maxim/Dallas Semiconductor ds28e04 eeprom. | 12 | - The Maxim/Dallas Semiconductor ds28e04 eeprom. |
13 | w1_ds28e17 | ||
14 | - The Maxim/Dallas Semiconductor ds28e17 1-Wire-to-I2C Master Bridge. | ||
diff --git a/Documentation/w1/slaves/w1_ds28e17 b/Documentation/w1/slaves/w1_ds28e17 new file mode 100644 index 000000000000..7fcfad5b4a37 --- /dev/null +++ b/Documentation/w1/slaves/w1_ds28e17 | |||
@@ -0,0 +1,68 @@ | |||
1 | Kernel driver w1_ds28e17 | ||
2 | ======================== | ||
3 | |||
4 | Supported chips: | ||
5 | * Maxim DS28E17 1-Wire-to-I2C Master Bridge | ||
6 | |||
7 | supported family codes: | ||
8 | W1_FAMILY_DS28E17 0x19 | ||
9 | |||
10 | Author: Jan Kandziora <jjj@gmx.de> | ||
11 | |||
12 | |||
13 | Description | ||
14 | ----------- | ||
15 | The DS28E17 is a Onewire slave device which acts as an I2C bus master. | ||
16 | |||
17 | This driver creates a new I2C bus for any DS28E17 device detected. I2C buses | ||
18 | come and go as the DS28E17 devices come and go. I2C slave devices connected to | ||
19 | a DS28E17 can be accessed by the kernel or userspace tools as if they were | ||
20 | connected to a "native" I2C bus master. | ||
21 | |||
22 | |||
23 | An udev rule like the following | ||
24 | ------------------------------------------------------------------------------- | ||
25 | SUBSYSTEM=="i2c-dev", KERNEL=="i2c-[0-9]*", ATTRS{name}=="w1-19-*", \ | ||
26 | SYMLINK+="i2c-$attr{name}" | ||
27 | ------------------------------------------------------------------------------- | ||
28 | may be used to create stable /dev/i2c- entries based on the unique id of the | ||
29 | DS28E17 chip. | ||
30 | |||
31 | |||
32 | Driver parameters are: | ||
33 | |||
34 | speed: | ||
35 | This sets up the default I2C speed a DS28E17 get configured for as soon | ||
36 | it is connected. The power-on default of the DS28E17 is 400kBaud, but | ||
37 | chips may come and go on the Onewire bus without being de-powered and | ||
38 | as soon the "w1_ds28e17" driver notices a freshly connected, or | ||
39 | reconnected DS28E17 device on the Onewire bus, it will re-apply this | ||
40 | setting. | ||
41 | |||
42 | Valid values are 100, 400, 900 [kBaud]. Any other value means to leave | ||
43 | alone the current DS28E17 setting on detect. The default value is 100. | ||
44 | |||
45 | stretch: | ||
46 | This sets up the default stretch value used for freshly connected | ||
47 | DS28E17 devices. It is a multiplier used on the calculation of the busy | ||
48 | wait time for an I2C transfer. This is to account for I2C slave devices | ||
49 | which make heavy use of the I2C clock stretching feature and thus, the | ||
50 | needed timeout cannot be pre-calculated correctly. As the w1_ds28e17 | ||
51 | driver checks the DS28E17's busy flag in a loop after the precalculated | ||
52 | wait time, it should be hardly needed to tweak this setting. | ||
53 | |||
54 | Leave it at 1 unless you get ETIMEDOUT errors and a "w1_slave_driver | ||
55 | 19-00000002dbd8: busy timeout" in the kernel log. | ||
56 | |||
57 | Valid values are 1 to 9. The default is 1. | ||
58 | |||
59 | |||
60 | The driver creates sysfs files /sys/bus/w1/devices/19-<id>/speed and | ||
61 | /sys/bus/w1/devices/19-<id>/stretch for each device, preloaded with the default | ||
62 | settings from the driver parameters. They may be changed anytime. In addition a | ||
63 | directory /sys/bus/w1/devices/19-<id>/i2c-<nnn> for the I2C bus master sysfs | ||
64 | structure is created. | ||
65 | |||
66 | |||
67 | See https://github.com/ianka/w1_ds28e17 for even more information. | ||
68 | |||
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig index 3c945f9f5f0f..7931231d8e80 100644 --- a/drivers/w1/slaves/Kconfig +++ b/drivers/w1/slaves/Kconfig | |||
@@ -148,4 +148,19 @@ config W1_SLAVE_DS28E04 | |||
148 | 148 | ||
149 | If you are unsure, say N. | 149 | If you are unsure, say N. |
150 | 150 | ||
151 | config W1_SLAVE_DS28E17 | ||
152 | tristate "1-wire-to-I2C master bridge (DS28E17)" | ||
153 | select CRC16 | ||
154 | depends on I2C | ||
155 | help | ||
156 | Say Y here if you want to use the DS28E17 1-wire-to-I2C master bridge. | ||
157 | For each DS28E17 detected, a new I2C adapter is created within the | ||
158 | kernel. I2C devices on that bus can be configured to be used by the | ||
159 | kernel and userspace tools as on any other "native" I2C bus. | ||
160 | |||
161 | This driver is also available as a module. If so, the module | ||
162 | will be called w1_ds28e17. | ||
163 | |||
164 | If you are unsure, say N. | ||
165 | |||
151 | endmenu | 166 | endmenu |
diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile index 36b22fb2d3a1..855371a99e6a 100644 --- a/drivers/w1/slaves/Makefile +++ b/drivers/w1/slaves/Makefile | |||
@@ -17,3 +17,4 @@ obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o | |||
17 | obj-$(CONFIG_W1_SLAVE_DS2780) += w1_ds2780.o | 17 | obj-$(CONFIG_W1_SLAVE_DS2780) += w1_ds2780.o |
18 | obj-$(CONFIG_W1_SLAVE_DS2781) += w1_ds2781.o | 18 | obj-$(CONFIG_W1_SLAVE_DS2781) += w1_ds2781.o |
19 | obj-$(CONFIG_W1_SLAVE_DS28E04) += w1_ds28e04.o | 19 | obj-$(CONFIG_W1_SLAVE_DS28E04) += w1_ds28e04.o |
20 | obj-$(CONFIG_W1_SLAVE_DS28E17) += w1_ds28e17.o | ||
diff --git a/drivers/w1/slaves/w1_ds28e17.c b/drivers/w1/slaves/w1_ds28e17.c new file mode 100644 index 000000000000..e78b63ea4daf --- /dev/null +++ b/drivers/w1/slaves/w1_ds28e17.c | |||
@@ -0,0 +1,771 @@ | |||
1 | /* | ||
2 | * w1_ds28e17.c - w1 family 19 (DS28E17) driver | ||
3 | * | ||
4 | * Copyright (c) 2016 Jan Kandziora <jjj@gmx.de> | ||
5 | * | ||
6 | * This source code is licensed under the GNU General Public License, | ||
7 | * Version 2. See the file COPYING for more details. | ||
8 | */ | ||
9 | |||
10 | #include <linux/crc16.h> | ||
11 | #include <linux/delay.h> | ||
12 | #include <linux/device.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/moduleparam.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/types.h> | ||
19 | #include <linux/uaccess.h> | ||
20 | |||
21 | #define CRC16_INIT 0 | ||
22 | |||
23 | #include <linux/w1.h> | ||
24 | |||
25 | #define W1_FAMILY_DS28E17 0x19 | ||
26 | |||
27 | /* Module setup. */ | ||
28 | MODULE_LICENSE("GPL v2"); | ||
29 | MODULE_AUTHOR("Jan Kandziora <jjj@gmx.de>"); | ||
30 | MODULE_DESCRIPTION("w1 family 19 driver for DS28E17, 1-wire to I2C master bridge"); | ||
31 | MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS28E17)); | ||
32 | |||
33 | |||
34 | /* Default I2C speed to be set when a DS28E17 is detected. */ | ||
35 | static int i2c_speed = 100; | ||
36 | module_param_named(speed, i2c_speed, int, (S_IRUSR | S_IWUSR)); | ||
37 | MODULE_PARM_DESC(speed, "Default I2C speed to be set when a DS28E17 is detected"); | ||
38 | |||
39 | /* Default I2C stretch value to be set when a DS28E17 is detected. */ | ||
40 | static char i2c_stretch = 1; | ||
41 | module_param_named(stretch, i2c_stretch, byte, (S_IRUSR | S_IWUSR)); | ||
42 | MODULE_PARM_DESC(stretch, "Default I2C stretch value to be set when a DS28E17 is detected"); | ||
43 | |||
44 | /* DS28E17 device command codes. */ | ||
45 | #define W1_F19_WRITE_DATA_WITH_STOP 0x4B | ||
46 | #define W1_F19_WRITE_DATA_NO_STOP 0x5A | ||
47 | #define W1_F19_WRITE_DATA_ONLY 0x69 | ||
48 | #define W1_F19_WRITE_DATA_ONLY_WITH_STOP 0x78 | ||
49 | #define W1_F19_READ_DATA_WITH_STOP 0x87 | ||
50 | #define W1_F19_WRITE_READ_DATA_WITH_STOP 0x2D | ||
51 | #define W1_F19_WRITE_CONFIGURATION 0xD2 | ||
52 | #define W1_F19_READ_CONFIGURATION 0xE1 | ||
53 | #define W1_F19_ENABLE_SLEEP_MODE 0x1E | ||
54 | #define W1_F19_READ_DEVICE_REVISION 0xC4 | ||
55 | |||
56 | /* DS28E17 status bits */ | ||
57 | #define W1_F19_STATUS_CRC 0x01 | ||
58 | #define W1_F19_STATUS_ADDRESS 0x02 | ||
59 | #define W1_F19_STATUS_START 0x08 | ||
60 | |||
61 | /* | ||
62 | * Maximum number of I2C bytes to transfer within one CRC16 protected onewire | ||
63 | * command. | ||
64 | * */ | ||
65 | #define W1_F19_WRITE_DATA_LIMIT 255 | ||
66 | |||
67 | /* Maximum number of I2C bytes to read with one onewire command. */ | ||
68 | #define W1_F19_READ_DATA_LIMIT 255 | ||
69 | |||
70 | /* Constants for calculating the busy sleep. */ | ||
71 | #define W1_F19_BUSY_TIMEBASES { 90, 23, 10 } | ||
72 | #define W1_F19_BUSY_GRATUITY 1000 | ||
73 | |||
74 | /* Number of checks for the busy flag before timeout. */ | ||
75 | #define W1_F19_BUSY_CHECKS 1000 | ||
76 | |||
77 | |||
78 | /* Slave specific data. */ | ||
79 | struct w1_f19_data { | ||
80 | u8 speed; | ||
81 | u8 stretch; | ||
82 | struct i2c_adapter adapter; | ||
83 | }; | ||
84 | |||
85 | |||
86 | /* Wait a while until the busy flag clears. */ | ||
87 | static int w1_f19_i2c_busy_wait(struct w1_slave *sl, size_t count) | ||
88 | { | ||
89 | const unsigned long timebases[3] = W1_F19_BUSY_TIMEBASES; | ||
90 | struct w1_f19_data *data = sl->family_data; | ||
91 | unsigned int checks; | ||
92 | |||
93 | /* Check the busy flag first in any case.*/ | ||
94 | if (w1_touch_bit(sl->master, 1) == 0) | ||
95 | return 0; | ||
96 | |||
97 | /* | ||
98 | * Do a generously long sleep in the beginning, | ||
99 | * as we have to wait at least this time for all | ||
100 | * the I2C bytes at the given speed to be transferred. | ||
101 | */ | ||
102 | usleep_range(timebases[data->speed] * (data->stretch) * count, | ||
103 | timebases[data->speed] * (data->stretch) * count | ||
104 | + W1_F19_BUSY_GRATUITY); | ||
105 | |||
106 | /* Now continusly check the busy flag sent by the DS28E17. */ | ||
107 | checks = W1_F19_BUSY_CHECKS; | ||
108 | while ((checks--) > 0) { | ||
109 | /* Return success if the busy flag is cleared. */ | ||
110 | if (w1_touch_bit(sl->master, 1) == 0) | ||
111 | return 0; | ||
112 | |||
113 | /* Wait one non-streched byte timeslot. */ | ||
114 | udelay(timebases[data->speed]); | ||
115 | } | ||
116 | |||
117 | /* Timeout. */ | ||
118 | dev_warn(&sl->dev, "busy timeout\n"); | ||
119 | return -ETIMEDOUT; | ||
120 | } | ||
121 | |||
122 | |||
123 | /* Utility function: result. */ | ||
124 | static size_t w1_f19_error(struct w1_slave *sl, u8 w1_buf[]) | ||
125 | { | ||
126 | /* Warnings. */ | ||
127 | if (w1_buf[0] & W1_F19_STATUS_CRC) | ||
128 | dev_warn(&sl->dev, "crc16 mismatch\n"); | ||
129 | if (w1_buf[0] & W1_F19_STATUS_ADDRESS) | ||
130 | dev_warn(&sl->dev, "i2c device not responding\n"); | ||
131 | if ((w1_buf[0] & (W1_F19_STATUS_CRC | W1_F19_STATUS_ADDRESS)) == 0 | ||
132 | && w1_buf[1] != 0) { | ||
133 | dev_warn(&sl->dev, "i2c short write, %d bytes not acknowledged\n", | ||
134 | w1_buf[1]); | ||
135 | } | ||
136 | |||
137 | /* Check error conditions. */ | ||
138 | if (w1_buf[0] & W1_F19_STATUS_ADDRESS) | ||
139 | return -ENXIO; | ||
140 | if (w1_buf[0] & W1_F19_STATUS_START) | ||
141 | return -EAGAIN; | ||
142 | if (w1_buf[0] != 0 || w1_buf[1] != 0) | ||
143 | return -EIO; | ||
144 | |||
145 | /* All ok. */ | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | |||
150 | /* Utility function: write data to I2C slave, single chunk. */ | ||
151 | static int __w1_f19_i2c_write(struct w1_slave *sl, | ||
152 | const u8 *command, size_t command_count, | ||
153 | const u8 *buffer, size_t count) | ||
154 | { | ||
155 | u16 crc; | ||
156 | int error; | ||
157 | u8 w1_buf[2]; | ||
158 | |||
159 | /* Send command and I2C data to DS28E17. */ | ||
160 | crc = crc16(CRC16_INIT, command, command_count); | ||
161 | w1_write_block(sl->master, command, command_count); | ||
162 | |||
163 | w1_buf[0] = count; | ||
164 | crc = crc16(crc, w1_buf, 1); | ||
165 | w1_write_8(sl->master, w1_buf[0]); | ||
166 | |||
167 | crc = crc16(crc, buffer, count); | ||
168 | w1_write_block(sl->master, buffer, count); | ||
169 | |||
170 | w1_buf[0] = ~(crc & 0xFF); | ||
171 | w1_buf[1] = ~((crc >> 8) & 0xFF); | ||
172 | w1_write_block(sl->master, w1_buf, 2); | ||
173 | |||
174 | /* Wait until busy flag clears (or timeout). */ | ||
175 | if (w1_f19_i2c_busy_wait(sl, count + 1) < 0) | ||
176 | return -ETIMEDOUT; | ||
177 | |||
178 | /* Read status from DS28E17. */ | ||
179 | w1_read_block(sl->master, w1_buf, 2); | ||
180 | |||
181 | /* Check error conditions. */ | ||
182 | error = w1_f19_error(sl, w1_buf); | ||
183 | if (error < 0) | ||
184 | return error; | ||
185 | |||
186 | /* Return number of bytes written. */ | ||
187 | return count; | ||
188 | } | ||
189 | |||
190 | |||
191 | /* Write data to I2C slave. */ | ||
192 | static int w1_f19_i2c_write(struct w1_slave *sl, u16 i2c_address, | ||
193 | const u8 *buffer, size_t count, bool stop) | ||
194 | { | ||
195 | int result; | ||
196 | int remaining = count; | ||
197 | const u8 *p; | ||
198 | u8 command[2]; | ||
199 | |||
200 | /* Check input. */ | ||
201 | if (count == 0) | ||
202 | return -EOPNOTSUPP; | ||
203 | |||
204 | /* Check whether we need multiple commands. */ | ||
205 | if (count <= W1_F19_WRITE_DATA_LIMIT) { | ||
206 | /* | ||
207 | * Small data amount. Data can be sent with | ||
208 | * a single onewire command. | ||
209 | */ | ||
210 | |||
211 | /* Send all data to DS28E17. */ | ||
212 | command[0] = (stop ? W1_F19_WRITE_DATA_WITH_STOP | ||
213 | : W1_F19_WRITE_DATA_NO_STOP); | ||
214 | command[1] = i2c_address << 1; | ||
215 | result = __w1_f19_i2c_write(sl, command, 2, buffer, count); | ||
216 | } else { | ||
217 | /* Large data amount. Data has to be sent in multiple chunks. */ | ||
218 | |||
219 | /* Send first chunk to DS28E17. */ | ||
220 | p = buffer; | ||
221 | command[0] = W1_F19_WRITE_DATA_NO_STOP; | ||
222 | command[1] = i2c_address << 1; | ||
223 | result = __w1_f19_i2c_write(sl, command, 2, p, | ||
224 | W1_F19_WRITE_DATA_LIMIT); | ||
225 | if (result < 0) | ||
226 | return result; | ||
227 | |||
228 | /* Resume to same DS28E17. */ | ||
229 | if (w1_reset_resume_command(sl->master)) | ||
230 | return -EIO; | ||
231 | |||
232 | /* Next data chunk. */ | ||
233 | p += W1_F19_WRITE_DATA_LIMIT; | ||
234 | remaining -= W1_F19_WRITE_DATA_LIMIT; | ||
235 | |||
236 | while (remaining > W1_F19_WRITE_DATA_LIMIT) { | ||
237 | /* Send intermediate chunk to DS28E17. */ | ||
238 | command[0] = W1_F19_WRITE_DATA_ONLY; | ||
239 | result = __w1_f19_i2c_write(sl, command, 1, p, | ||
240 | W1_F19_WRITE_DATA_LIMIT); | ||
241 | if (result < 0) | ||
242 | return result; | ||
243 | |||
244 | /* Resume to same DS28E17. */ | ||
245 | if (w1_reset_resume_command(sl->master)) | ||
246 | return -EIO; | ||
247 | |||
248 | /* Next data chunk. */ | ||
249 | p += W1_F19_WRITE_DATA_LIMIT; | ||
250 | remaining -= W1_F19_WRITE_DATA_LIMIT; | ||
251 | } | ||
252 | |||
253 | /* Send final chunk to DS28E17. */ | ||
254 | command[0] = (stop ? W1_F19_WRITE_DATA_ONLY_WITH_STOP | ||
255 | : W1_F19_WRITE_DATA_ONLY); | ||
256 | result = __w1_f19_i2c_write(sl, command, 1, p, remaining); | ||
257 | } | ||
258 | |||
259 | return result; | ||
260 | } | ||
261 | |||
262 | |||
263 | /* Read data from I2C slave. */ | ||
264 | static int w1_f19_i2c_read(struct w1_slave *sl, u16 i2c_address, | ||
265 | u8 *buffer, size_t count) | ||
266 | { | ||
267 | u16 crc; | ||
268 | int error; | ||
269 | u8 w1_buf[5]; | ||
270 | |||
271 | /* Check input. */ | ||
272 | if (count == 0) | ||
273 | return -EOPNOTSUPP; | ||
274 | |||
275 | /* Send command to DS28E17. */ | ||
276 | w1_buf[0] = W1_F19_READ_DATA_WITH_STOP; | ||
277 | w1_buf[1] = i2c_address << 1 | 0x01; | ||
278 | w1_buf[2] = count; | ||
279 | crc = crc16(CRC16_INIT, w1_buf, 3); | ||
280 | w1_buf[3] = ~(crc & 0xFF); | ||
281 | w1_buf[4] = ~((crc >> 8) & 0xFF); | ||
282 | w1_write_block(sl->master, w1_buf, 5); | ||
283 | |||
284 | /* Wait until busy flag clears (or timeout). */ | ||
285 | if (w1_f19_i2c_busy_wait(sl, count + 1) < 0) | ||
286 | return -ETIMEDOUT; | ||
287 | |||
288 | /* Read status from DS28E17. */ | ||
289 | w1_buf[0] = w1_read_8(sl->master); | ||
290 | w1_buf[1] = 0; | ||
291 | |||
292 | /* Check error conditions. */ | ||
293 | error = w1_f19_error(sl, w1_buf); | ||
294 | if (error < 0) | ||
295 | return error; | ||
296 | |||
297 | /* Read received I2C data from DS28E17. */ | ||
298 | return w1_read_block(sl->master, buffer, count); | ||
299 | } | ||
300 | |||
301 | |||
302 | /* Write to, then read data from I2C slave. */ | ||
303 | static int w1_f19_i2c_write_read(struct w1_slave *sl, u16 i2c_address, | ||
304 | const u8 *wbuffer, size_t wcount, u8 *rbuffer, size_t rcount) | ||
305 | { | ||
306 | u16 crc; | ||
307 | int error; | ||
308 | u8 w1_buf[3]; | ||
309 | |||
310 | /* Check input. */ | ||
311 | if (wcount == 0 || rcount == 0) | ||
312 | return -EOPNOTSUPP; | ||
313 | |||
314 | /* Send command and I2C data to DS28E17. */ | ||
315 | w1_buf[0] = W1_F19_WRITE_READ_DATA_WITH_STOP; | ||
316 | w1_buf[1] = i2c_address << 1; | ||
317 | w1_buf[2] = wcount; | ||
318 | crc = crc16(CRC16_INIT, w1_buf, 3); | ||
319 | w1_write_block(sl->master, w1_buf, 3); | ||
320 | |||
321 | crc = crc16(crc, wbuffer, wcount); | ||
322 | w1_write_block(sl->master, wbuffer, wcount); | ||
323 | |||
324 | w1_buf[0] = rcount; | ||
325 | crc = crc16(crc, w1_buf, 1); | ||
326 | w1_buf[1] = ~(crc & 0xFF); | ||
327 | w1_buf[2] = ~((crc >> 8) & 0xFF); | ||
328 | w1_write_block(sl->master, w1_buf, 3); | ||
329 | |||
330 | /* Wait until busy flag clears (or timeout). */ | ||
331 | if (w1_f19_i2c_busy_wait(sl, wcount + rcount + 2) < 0) | ||
332 | return -ETIMEDOUT; | ||
333 | |||
334 | /* Read status from DS28E17. */ | ||
335 | w1_read_block(sl->master, w1_buf, 2); | ||
336 | |||
337 | /* Check error conditions. */ | ||
338 | error = w1_f19_error(sl, w1_buf); | ||
339 | if (error < 0) | ||
340 | return error; | ||
341 | |||
342 | /* Read received I2C data from DS28E17. */ | ||
343 | return w1_read_block(sl->master, rbuffer, rcount); | ||
344 | } | ||
345 | |||
346 | |||
347 | /* Do an I2C master transfer. */ | ||
348 | static int w1_f19_i2c_master_transfer(struct i2c_adapter *adapter, | ||
349 | struct i2c_msg *msgs, int num) | ||
350 | { | ||
351 | struct w1_slave *sl = (struct w1_slave *) adapter->algo_data; | ||
352 | int i = 0; | ||
353 | int result = 0; | ||
354 | |||
355 | /* Start onewire transaction. */ | ||
356 | mutex_lock(&sl->master->bus_mutex); | ||
357 | |||
358 | /* Select DS28E17. */ | ||
359 | if (w1_reset_select_slave(sl)) { | ||
360 | i = -EIO; | ||
361 | goto error; | ||
362 | } | ||
363 | |||
364 | /* Loop while there are still messages to transfer. */ | ||
365 | while (i < num) { | ||
366 | /* | ||
367 | * Check for special case: Small write followed | ||
368 | * by read to same I2C device. | ||
369 | */ | ||
370 | if (i < (num-1) | ||
371 | && msgs[i].addr == msgs[i+1].addr | ||
372 | && !(msgs[i].flags & I2C_M_RD) | ||
373 | && (msgs[i+1].flags & I2C_M_RD) | ||
374 | && (msgs[i].len <= W1_F19_WRITE_DATA_LIMIT)) { | ||
375 | /* | ||
376 | * The DS28E17 has a combined transfer | ||
377 | * for small write+read. | ||
378 | */ | ||
379 | result = w1_f19_i2c_write_read(sl, msgs[i].addr, | ||
380 | msgs[i].buf, msgs[i].len, | ||
381 | msgs[i+1].buf, msgs[i+1].len); | ||
382 | if (result < 0) { | ||
383 | i = result; | ||
384 | goto error; | ||
385 | } | ||
386 | |||
387 | /* | ||
388 | * Check if we should interpret the read data | ||
389 | * as a length byte. The DS28E17 unfortunately | ||
390 | * has no read without stop, so we can just do | ||
391 | * another simple read in that case. | ||
392 | */ | ||
393 | if (msgs[i+1].flags & I2C_M_RECV_LEN) { | ||
394 | result = w1_f19_i2c_read(sl, msgs[i+1].addr, | ||
395 | &(msgs[i+1].buf[1]), msgs[i+1].buf[0]); | ||
396 | if (result < 0) { | ||
397 | i = result; | ||
398 | goto error; | ||
399 | } | ||
400 | } | ||
401 | |||
402 | /* Eat up read message, too. */ | ||
403 | i++; | ||
404 | } else if (msgs[i].flags & I2C_M_RD) { | ||
405 | /* Read transfer. */ | ||
406 | result = w1_f19_i2c_read(sl, msgs[i].addr, | ||
407 | msgs[i].buf, msgs[i].len); | ||
408 | if (result < 0) { | ||
409 | i = result; | ||
410 | goto error; | ||
411 | } | ||
412 | |||
413 | /* | ||
414 | * Check if we should interpret the read data | ||
415 | * as a length byte. The DS28E17 unfortunately | ||
416 | * has no read without stop, so we can just do | ||
417 | * another simple read in that case. | ||
418 | */ | ||
419 | if (msgs[i].flags & I2C_M_RECV_LEN) { | ||
420 | result = w1_f19_i2c_read(sl, | ||
421 | msgs[i].addr, | ||
422 | &(msgs[i].buf[1]), | ||
423 | msgs[i].buf[0]); | ||
424 | if (result < 0) { | ||
425 | i = result; | ||
426 | goto error; | ||
427 | } | ||
428 | } | ||
429 | } else { | ||
430 | /* | ||
431 | * Write transfer. | ||
432 | * Stop condition only for last | ||
433 | * transfer. | ||
434 | */ | ||
435 | result = w1_f19_i2c_write(sl, | ||
436 | msgs[i].addr, | ||
437 | msgs[i].buf, | ||
438 | msgs[i].len, | ||
439 | i == (num-1)); | ||
440 | if (result < 0) { | ||
441 | i = result; | ||
442 | goto error; | ||
443 | } | ||
444 | } | ||
445 | |||
446 | /* Next message. */ | ||
447 | i++; | ||
448 | |||
449 | /* Are there still messages to send/receive? */ | ||
450 | if (i < num) { | ||
451 | /* Yes. Resume to same DS28E17. */ | ||
452 | if (w1_reset_resume_command(sl->master)) { | ||
453 | i = -EIO; | ||
454 | goto error; | ||
455 | } | ||
456 | } | ||
457 | } | ||
458 | |||
459 | error: | ||
460 | /* End onewire transaction. */ | ||
461 | mutex_unlock(&sl->master->bus_mutex); | ||
462 | |||
463 | /* Return number of messages processed or error. */ | ||
464 | return i; | ||
465 | } | ||
466 | |||
467 | |||
468 | /* Get I2C adapter functionality. */ | ||
469 | static u32 w1_f19_i2c_functionality(struct i2c_adapter *adapter) | ||
470 | { | ||
471 | /* | ||
472 | * Plain I2C functions only. | ||
473 | * SMBus is emulated by the kernel's I2C layer. | ||
474 | * No "I2C_FUNC_SMBUS_QUICK" | ||
475 | * No "I2C_FUNC_SMBUS_READ_BLOCK_DATA" | ||
476 | * No "I2C_FUNC_SMBUS_BLOCK_PROC_CALL" | ||
477 | */ | ||
478 | return I2C_FUNC_I2C | | ||
479 | I2C_FUNC_SMBUS_BYTE | | ||
480 | I2C_FUNC_SMBUS_BYTE_DATA | | ||
481 | I2C_FUNC_SMBUS_WORD_DATA | | ||
482 | I2C_FUNC_SMBUS_PROC_CALL | | ||
483 | I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | | ||
484 | I2C_FUNC_SMBUS_I2C_BLOCK | | ||
485 | I2C_FUNC_SMBUS_PEC; | ||
486 | } | ||
487 | |||
488 | |||
489 | /* I2C adapter quirks. */ | ||
490 | static const struct i2c_adapter_quirks w1_f19_i2c_adapter_quirks = { | ||
491 | .max_read_len = W1_F19_READ_DATA_LIMIT, | ||
492 | }; | ||
493 | |||
494 | /* I2C algorithm. */ | ||
495 | static const struct i2c_algorithm w1_f19_i2c_algorithm = { | ||
496 | .master_xfer = w1_f19_i2c_master_transfer, | ||
497 | .functionality = w1_f19_i2c_functionality, | ||
498 | }; | ||
499 | |||
500 | |||
501 | /* Read I2C speed from DS28E17. */ | ||
502 | static int w1_f19_get_i2c_speed(struct w1_slave *sl) | ||
503 | { | ||
504 | struct w1_f19_data *data = sl->family_data; | ||
505 | int result = -EIO; | ||
506 | |||
507 | /* Start onewire transaction. */ | ||
508 | mutex_lock(&sl->master->bus_mutex); | ||
509 | |||
510 | /* Select slave. */ | ||
511 | if (w1_reset_select_slave(sl)) | ||
512 | goto error; | ||
513 | |||
514 | /* Read slave configuration byte. */ | ||
515 | w1_write_8(sl->master, W1_F19_READ_CONFIGURATION); | ||
516 | result = w1_read_8(sl->master); | ||
517 | if (result < 0 || result > 2) { | ||
518 | result = -EIO; | ||
519 | goto error; | ||
520 | } | ||
521 | |||
522 | /* Update speed in slave specific data. */ | ||
523 | data->speed = result; | ||
524 | |||
525 | error: | ||
526 | /* End onewire transaction. */ | ||
527 | mutex_unlock(&sl->master->bus_mutex); | ||
528 | |||
529 | return result; | ||
530 | } | ||
531 | |||
532 | |||
533 | /* Set I2C speed on DS28E17. */ | ||
534 | static int __w1_f19_set_i2c_speed(struct w1_slave *sl, u8 speed) | ||
535 | { | ||
536 | struct w1_f19_data *data = sl->family_data; | ||
537 | const int i2c_speeds[3] = { 100, 400, 900 }; | ||
538 | u8 w1_buf[2]; | ||
539 | |||
540 | /* Select slave. */ | ||
541 | if (w1_reset_select_slave(sl)) | ||
542 | return -EIO; | ||
543 | |||
544 | w1_buf[0] = W1_F19_WRITE_CONFIGURATION; | ||
545 | w1_buf[1] = speed; | ||
546 | w1_write_block(sl->master, w1_buf, 2); | ||
547 | |||
548 | /* Update speed in slave specific data. */ | ||
549 | data->speed = speed; | ||
550 | |||
551 | dev_info(&sl->dev, "i2c speed set to %d kBaud\n", i2c_speeds[speed]); | ||
552 | |||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | static int w1_f19_set_i2c_speed(struct w1_slave *sl, u8 speed) | ||
557 | { | ||
558 | int result; | ||
559 | |||
560 | /* Start onewire transaction. */ | ||
561 | mutex_lock(&sl->master->bus_mutex); | ||
562 | |||
563 | /* Set I2C speed on DS28E17. */ | ||
564 | result = __w1_f19_set_i2c_speed(sl, speed); | ||
565 | |||
566 | /* End onewire transaction. */ | ||
567 | mutex_unlock(&sl->master->bus_mutex); | ||
568 | |||
569 | return result; | ||
570 | } | ||
571 | |||
572 | |||
573 | /* Sysfs attributes. */ | ||
574 | |||
575 | /* I2C speed attribute for a single chip. */ | ||
576 | static ssize_t speed_show(struct device *dev, struct device_attribute *attr, | ||
577 | char *buf) | ||
578 | { | ||
579 | struct w1_slave *sl = dev_to_w1_slave(dev); | ||
580 | int result; | ||
581 | |||
582 | /* Read current speed from slave. Updates data->speed. */ | ||
583 | result = w1_f19_get_i2c_speed(sl); | ||
584 | if (result < 0) | ||
585 | return result; | ||
586 | |||
587 | /* Return current speed value. */ | ||
588 | return sprintf(buf, "%d\n", result); | ||
589 | } | ||
590 | |||
591 | static ssize_t speed_store(struct device *dev, struct device_attribute *attr, | ||
592 | const char *buf, size_t count) | ||
593 | { | ||
594 | struct w1_slave *sl = dev_to_w1_slave(dev); | ||
595 | int error; | ||
596 | |||
597 | /* Valid values are: "100", "400", "900" */ | ||
598 | if (count < 3 || count > 4 || !buf) | ||
599 | return -EINVAL; | ||
600 | if (count == 4 && buf[3] != '\n') | ||
601 | return -EINVAL; | ||
602 | if (buf[1] != '0' || buf[2] != '0') | ||
603 | return -EINVAL; | ||
604 | |||
605 | /* Set speed on slave. */ | ||
606 | switch (buf[0]) { | ||
607 | case '1': | ||
608 | error = w1_f19_set_i2c_speed(sl, 0); | ||
609 | break; | ||
610 | case '4': | ||
611 | error = w1_f19_set_i2c_speed(sl, 1); | ||
612 | break; | ||
613 | case '9': | ||
614 | error = w1_f19_set_i2c_speed(sl, 2); | ||
615 | break; | ||
616 | default: | ||
617 | return -EINVAL; | ||
618 | } | ||
619 | |||
620 | if (error < 0) | ||
621 | return error; | ||
622 | |||
623 | /* Return bytes written. */ | ||
624 | return count; | ||
625 | } | ||
626 | |||
627 | static DEVICE_ATTR_RW(speed); | ||
628 | |||
629 | |||
630 | /* Busy stretch attribute for a single chip. */ | ||
631 | static ssize_t stretch_show(struct device *dev, struct device_attribute *attr, | ||
632 | char *buf) | ||
633 | { | ||
634 | struct w1_slave *sl = dev_to_w1_slave(dev); | ||
635 | struct w1_f19_data *data = sl->family_data; | ||
636 | |||
637 | /* Return current stretch value. */ | ||
638 | return sprintf(buf, "%d\n", data->stretch); | ||
639 | } | ||
640 | |||
641 | static ssize_t stretch_store(struct device *dev, struct device_attribute *attr, | ||
642 | const char *buf, size_t count) | ||
643 | { | ||
644 | struct w1_slave *sl = dev_to_w1_slave(dev); | ||
645 | struct w1_f19_data *data = sl->family_data; | ||
646 | |||
647 | /* Valid values are '1' to '9' */ | ||
648 | if (count < 1 || count > 2 || !buf) | ||
649 | return -EINVAL; | ||
650 | if (count == 2 && buf[1] != '\n') | ||
651 | return -EINVAL; | ||
652 | if (buf[0] < '1' || buf[0] > '9') | ||
653 | return -EINVAL; | ||
654 | |||
655 | /* Set busy stretch value. */ | ||
656 | data->stretch = buf[0] & 0x0F; | ||
657 | |||
658 | /* Return bytes written. */ | ||
659 | return count; | ||
660 | } | ||
661 | |||
662 | static DEVICE_ATTR_RW(stretch); | ||
663 | |||
664 | |||
665 | /* All attributes. */ | ||
666 | static struct attribute *w1_f19_attrs[] = { | ||
667 | &dev_attr_speed.attr, | ||
668 | &dev_attr_stretch.attr, | ||
669 | NULL, | ||
670 | }; | ||
671 | |||
672 | static const struct attribute_group w1_f19_group = { | ||
673 | .attrs = w1_f19_attrs, | ||
674 | }; | ||
675 | |||
676 | static const struct attribute_group *w1_f19_groups[] = { | ||
677 | &w1_f19_group, | ||
678 | NULL, | ||
679 | }; | ||
680 | |||
681 | |||
682 | /* Slave add and remove functions. */ | ||
683 | static int w1_f19_add_slave(struct w1_slave *sl) | ||
684 | { | ||
685 | struct w1_f19_data *data = NULL; | ||
686 | |||
687 | /* Allocate memory for slave specific data. */ | ||
688 | data = devm_kzalloc(&sl->dev, sizeof(*data), GFP_KERNEL); | ||
689 | if (!data) | ||
690 | return -ENOMEM; | ||
691 | sl->family_data = data; | ||
692 | |||
693 | /* Setup default I2C speed on slave. */ | ||
694 | switch (i2c_speed) { | ||
695 | case 100: | ||
696 | __w1_f19_set_i2c_speed(sl, 0); | ||
697 | break; | ||
698 | case 400: | ||
699 | __w1_f19_set_i2c_speed(sl, 1); | ||
700 | break; | ||
701 | case 900: | ||
702 | __w1_f19_set_i2c_speed(sl, 2); | ||
703 | break; | ||
704 | default: | ||
705 | /* | ||
706 | * A i2c_speed module parameter of anything else | ||
707 | * than 100, 400, 900 means not to touch the | ||
708 | * speed of the DS28E17. | ||
709 | * We assume 400kBaud, the power-on value. | ||
710 | */ | ||
711 | data->speed = 1; | ||
712 | } | ||
713 | |||
714 | /* | ||
715 | * Setup default busy stretch | ||
716 | * configuration for the DS28E17. | ||
717 | */ | ||
718 | data->stretch = i2c_stretch; | ||
719 | |||
720 | /* Setup I2C adapter. */ | ||
721 | data->adapter.owner = THIS_MODULE; | ||
722 | data->adapter.algo = &w1_f19_i2c_algorithm; | ||
723 | data->adapter.algo_data = sl; | ||
724 | strcpy(data->adapter.name, "w1-"); | ||
725 | strcat(data->adapter.name, sl->name); | ||
726 | data->adapter.dev.parent = &sl->dev; | ||
727 | data->adapter.quirks = &w1_f19_i2c_adapter_quirks; | ||
728 | |||
729 | return i2c_add_adapter(&data->adapter); | ||
730 | } | ||
731 | |||
732 | static void w1_f19_remove_slave(struct w1_slave *sl) | ||
733 | { | ||
734 | struct w1_f19_data *family_data = sl->family_data; | ||
735 | |||
736 | /* Delete I2C adapter. */ | ||
737 | i2c_del_adapter(&family_data->adapter); | ||
738 | |||
739 | /* Free slave specific data. */ | ||
740 | devm_kfree(&sl->dev, family_data); | ||
741 | sl->family_data = NULL; | ||
742 | } | ||
743 | |||
744 | |||
745 | /* Declarations within the w1 subsystem. */ | ||
746 | static struct w1_family_ops w1_f19_fops = { | ||
747 | .add_slave = w1_f19_add_slave, | ||
748 | .remove_slave = w1_f19_remove_slave, | ||
749 | .groups = w1_f19_groups, | ||
750 | }; | ||
751 | |||
752 | static struct w1_family w1_family_19 = { | ||
753 | .fid = W1_FAMILY_DS28E17, | ||
754 | .fops = &w1_f19_fops, | ||
755 | }; | ||
756 | |||
757 | |||
758 | /* Module init and remove functions. */ | ||
759 | static int __init w1_f19_init(void) | ||
760 | { | ||
761 | return w1_register_family(&w1_family_19); | ||
762 | } | ||
763 | |||
764 | static void __exit w1_f19_fini(void) | ||
765 | { | ||
766 | w1_unregister_family(&w1_family_19); | ||
767 | } | ||
768 | |||
769 | module_init(w1_f19_init); | ||
770 | module_exit(w1_f19_fini); | ||
771 | |||