Merge tag 'for-5.10-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[linux-2.6-microblaze.git] / drivers / w1 / slaves / w1_ds2430.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * w1_ds2430.c - w1 family 14 (DS2430) driver
4  **
5  * Copyright (c) 2019 Angelo Dureghello <angelo.dureghello@timesys.com>
6  *
7  * Cloned and modified from ds2431
8  * Copyright (c) 2008 Bernhard Weirich <bernhard.weirich@riedel.net>
9  *
10  */
11
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/moduleparam.h>
15 #include <linux/device.h>
16 #include <linux/types.h>
17 #include <linux/delay.h>
18
19 #include <linux/w1.h>
20
21 #define W1_EEPROM_DS2430        0x14
22
23 #define W1_F14_EEPROM_SIZE      32
24 #define W1_F14_PAGE_COUNT       1
25 #define W1_F14_PAGE_BITS        5
26 #define W1_F14_PAGE_SIZE        (1 << W1_F14_PAGE_BITS)
27 #define W1_F14_PAGE_MASK        0x1F
28
29 #define W1_F14_SCRATCH_BITS     5
30 #define W1_F14_SCRATCH_SIZE     (1 << W1_F14_SCRATCH_BITS)
31 #define W1_F14_SCRATCH_MASK     (W1_F14_SCRATCH_SIZE-1)
32
33 #define W1_F14_READ_EEPROM      0xF0
34 #define W1_F14_WRITE_SCRATCH    0x0F
35 #define W1_F14_READ_SCRATCH     0xAA
36 #define W1_F14_COPY_SCRATCH     0x55
37 #define W1_F14_VALIDATION_KEY   0xa5
38
39 #define W1_F14_TPROG_MS         11
40 #define W1_F14_READ_RETRIES     10
41 #define W1_F14_READ_MAXLEN      W1_F14_SCRATCH_SIZE
42
43 /*
44  * Check the file size bounds and adjusts count as needed.
45  * This would not be needed if the file size didn't reset to 0 after a write.
46  */
47 static inline size_t w1_f14_fix_count(loff_t off, size_t count, size_t size)
48 {
49         if (off > size)
50                 return 0;
51
52         if ((off + count) > size)
53                 return size - off;
54
55         return count;
56 }
57
58 /*
59  * Read a block from W1 ROM two times and compares the results.
60  * If they are equal they are returned, otherwise the read
61  * is repeated W1_F14_READ_RETRIES times.
62  *
63  * count must not exceed W1_F14_READ_MAXLEN.
64  */
65 static int w1_f14_readblock(struct w1_slave *sl, int off, int count, char *buf)
66 {
67         u8 wrbuf[2];
68         u8 cmp[W1_F14_READ_MAXLEN];
69         int tries = W1_F14_READ_RETRIES;
70
71         do {
72                 wrbuf[0] = W1_F14_READ_EEPROM;
73                 wrbuf[1] = off & 0xff;
74
75                 if (w1_reset_select_slave(sl))
76                         return -1;
77
78                 w1_write_block(sl->master, wrbuf, 2);
79                 w1_read_block(sl->master, buf, count);
80
81                 if (w1_reset_select_slave(sl))
82                         return -1;
83
84                 w1_write_block(sl->master, wrbuf, 2);
85                 w1_read_block(sl->master, cmp, count);
86
87                 if (!memcmp(cmp, buf, count))
88                         return 0;
89         } while (--tries);
90
91         dev_err(&sl->dev, "proof reading failed %d times\n",
92                         W1_F14_READ_RETRIES);
93
94         return -1;
95 }
96
97 static ssize_t eeprom_read(struct file *filp, struct kobject *kobj,
98                            struct bin_attribute *bin_attr, char *buf,
99                            loff_t off, size_t count)
100 {
101         struct w1_slave *sl = kobj_to_w1_slave(kobj);
102         int todo = count;
103
104         count = w1_f14_fix_count(off, count, W1_F14_EEPROM_SIZE);
105         if (count == 0)
106                 return 0;
107
108         mutex_lock(&sl->master->bus_mutex);
109
110         /* read directly from the EEPROM in chunks of W1_F14_READ_MAXLEN */
111         while (todo > 0) {
112                 int block_read;
113
114                 if (todo >= W1_F14_READ_MAXLEN)
115                         block_read = W1_F14_READ_MAXLEN;
116                 else
117                         block_read = todo;
118
119                 if (w1_f14_readblock(sl, off, block_read, buf) < 0)
120                         count = -EIO;
121
122                 todo -= W1_F14_READ_MAXLEN;
123                 buf += W1_F14_READ_MAXLEN;
124                 off += W1_F14_READ_MAXLEN;
125         }
126
127         mutex_unlock(&sl->master->bus_mutex);
128
129         return count;
130 }
131
132 /*
133  * Writes to the scratchpad and reads it back for verification.
134  * Then copies the scratchpad to EEPROM.
135  * The data must be aligned at W1_F14_SCRATCH_SIZE bytes and
136  * must be W1_F14_SCRATCH_SIZE bytes long.
137  * The master must be locked.
138  *
139  * @param sl    The slave structure
140  * @param addr  Address for the write
141  * @param len   length must be <= (W1_F14_PAGE_SIZE - (addr & W1_F14_PAGE_MASK))
142  * @param data  The data to write
143  * @return      0=Success -1=failure
144  */
145 static int w1_f14_write(struct w1_slave *sl, int addr, int len, const u8 *data)
146 {
147         int tries = W1_F14_READ_RETRIES;
148         u8 wrbuf[2];
149         u8 rdbuf[W1_F14_SCRATCH_SIZE + 3];
150
151 retry:
152
153         /* Write the data to the scratchpad */
154         if (w1_reset_select_slave(sl))
155                 return -1;
156
157         wrbuf[0] = W1_F14_WRITE_SCRATCH;
158         wrbuf[1] = addr & 0xff;
159
160         w1_write_block(sl->master, wrbuf, 2);
161         w1_write_block(sl->master, data, len);
162
163         /* Read the scratchpad and verify */
164         if (w1_reset_select_slave(sl))
165                 return -1;
166
167         w1_write_8(sl->master, W1_F14_READ_SCRATCH);
168         w1_read_block(sl->master, rdbuf, len + 2);
169
170         /*
171          * Compare what was read against the data written
172          * Note: on read scratchpad, device returns 2 bulk 0xff bytes,
173          * to be discarded.
174          */
175         if ((memcmp(data, &rdbuf[2], len) != 0)) {
176
177                 if (--tries)
178                         goto retry;
179
180                 dev_err(&sl->dev,
181                         "could not write to eeprom, scratchpad compare failed %d times\n",
182                         W1_F14_READ_RETRIES);
183
184                 return -1;
185         }
186
187         /* Copy the scratchpad to EEPROM */
188         if (w1_reset_select_slave(sl))
189                 return -1;
190
191         wrbuf[0] = W1_F14_COPY_SCRATCH;
192         wrbuf[1] = W1_F14_VALIDATION_KEY;
193         w1_write_block(sl->master, wrbuf, 2);
194
195         /* Sleep for tprog ms to wait for the write to complete */
196         msleep(W1_F14_TPROG_MS);
197
198         /* Reset the bus to wake up the EEPROM  */
199         w1_reset_bus(sl->master);
200
201         return 0;
202 }
203
204 static ssize_t eeprom_write(struct file *filp, struct kobject *kobj,
205                             struct bin_attribute *bin_attr, char *buf,
206                             loff_t off, size_t count)
207 {
208         struct w1_slave *sl = kobj_to_w1_slave(kobj);
209         int addr, len;
210         int copy;
211
212         count = w1_f14_fix_count(off, count, W1_F14_EEPROM_SIZE);
213         if (count == 0)
214                 return 0;
215
216         mutex_lock(&sl->master->bus_mutex);
217
218         /* Can only write data in blocks of the size of the scratchpad */
219         addr = off;
220         len = count;
221         while (len > 0) {
222
223                 /* if len too short or addr not aligned */
224                 if (len < W1_F14_SCRATCH_SIZE || addr & W1_F14_SCRATCH_MASK) {
225                         char tmp[W1_F14_SCRATCH_SIZE];
226
227                         /* read the block and update the parts to be written */
228                         if (w1_f14_readblock(sl, addr & ~W1_F14_SCRATCH_MASK,
229                                         W1_F14_SCRATCH_SIZE, tmp)) {
230                                 count = -EIO;
231                                 goto out_up;
232                         }
233
234                         /* copy at most to the boundary of the PAGE or len */
235                         copy = W1_F14_SCRATCH_SIZE -
236                                 (addr & W1_F14_SCRATCH_MASK);
237
238                         if (copy > len)
239                                 copy = len;
240
241                         memcpy(&tmp[addr & W1_F14_SCRATCH_MASK], buf, copy);
242                         if (w1_f14_write(sl, addr & ~W1_F14_SCRATCH_MASK,
243                                         W1_F14_SCRATCH_SIZE, tmp) < 0) {
244                                 count = -EIO;
245                                 goto out_up;
246                         }
247                 } else {
248
249                         copy = W1_F14_SCRATCH_SIZE;
250                         if (w1_f14_write(sl, addr, copy, buf) < 0) {
251                                 count = -EIO;
252                                 goto out_up;
253                         }
254                 }
255                 buf += copy;
256                 addr += copy;
257                 len -= copy;
258         }
259
260 out_up:
261         mutex_unlock(&sl->master->bus_mutex);
262
263         return count;
264 }
265
266 static BIN_ATTR_RW(eeprom, W1_F14_EEPROM_SIZE);
267
268 static struct bin_attribute *w1_f14_bin_attrs[] = {
269         &bin_attr_eeprom,
270         NULL,
271 };
272
273 static const struct attribute_group w1_f14_group = {
274         .bin_attrs = w1_f14_bin_attrs,
275 };
276
277 static const struct attribute_group *w1_f14_groups[] = {
278         &w1_f14_group,
279         NULL,
280 };
281
282 static const struct w1_family_ops w1_f14_fops = {
283         .groups = w1_f14_groups,
284 };
285
286 static struct w1_family w1_family_14 = {
287         .fid = W1_EEPROM_DS2430,
288         .fops = &w1_f14_fops,
289 };
290 module_w1_family(w1_family_14);
291
292 MODULE_AUTHOR("Angelo Dureghello <angelo.dureghello@timesys.com>");
293 MODULE_DESCRIPTION("w1 family 14 driver for DS2430, 256b EEPROM");
294 MODULE_LICENSE("GPL");
295 MODULE_ALIAS("w1-family-" __stringify(W1_EEPROM_DS2430));