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