Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  w1_ds28e04.c - w1 family 1C (DS28E04) driver
0004  *
0005  * Copyright (c) 2012 Markus Franke <franke.m@sebakmt.com>
0006  */
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/module.h>
0010 #include <linux/moduleparam.h>
0011 #include <linux/device.h>
0012 #include <linux/types.h>
0013 #include <linux/delay.h>
0014 #include <linux/slab.h>
0015 #include <linux/crc16.h>
0016 #include <linux/uaccess.h>
0017 
0018 #define CRC16_INIT      0
0019 #define CRC16_VALID     0xb001
0020 
0021 #include <linux/w1.h>
0022 
0023 #define W1_FAMILY_DS28E04   0x1C
0024 
0025 /* Allow the strong pullup to be disabled, but default to enabled.
0026  * If it was disabled a parasite powered device might not get the required
0027  * current to copy the data from the scratchpad to EEPROM.  If it is enabled
0028  * parasite powered devices have a better chance of getting the current
0029  * required.
0030  */
0031 static int w1_strong_pullup = 1;
0032 module_param_named(strong_pullup, w1_strong_pullup, int, 0);
0033 
0034 /* enable/disable CRC checking on DS28E04-100 memory accesses */
0035 static bool w1_enable_crccheck = true;
0036 
0037 #define W1_EEPROM_SIZE      512
0038 #define W1_PAGE_COUNT       16
0039 #define W1_PAGE_SIZE        32
0040 #define W1_PAGE_BITS        5
0041 #define W1_PAGE_MASK        0x1F
0042 
0043 #define W1_F1C_READ_EEPROM  0xF0
0044 #define W1_F1C_WRITE_SCRATCH    0x0F
0045 #define W1_F1C_READ_SCRATCH 0xAA
0046 #define W1_F1C_COPY_SCRATCH 0x55
0047 #define W1_F1C_ACCESS_WRITE 0x5A
0048 
0049 #define W1_1C_REG_LOGIC_STATE   0x220
0050 
0051 struct w1_f1C_data {
0052     u8  memory[W1_EEPROM_SIZE];
0053     u32 validcrc;
0054 };
0055 
0056 /**
0057  * Check the file size bounds and adjusts count as needed.
0058  * This would not be needed if the file size didn't reset to 0 after a write.
0059  */
0060 static inline size_t w1_f1C_fix_count(loff_t off, size_t count, size_t size)
0061 {
0062     if (off > size)
0063         return 0;
0064 
0065     if ((off + count) > size)
0066         return size - off;
0067 
0068     return count;
0069 }
0070 
0071 static int w1_f1C_refresh_block(struct w1_slave *sl, struct w1_f1C_data *data,
0072                 int block)
0073 {
0074     u8  wrbuf[3];
0075     int off = block * W1_PAGE_SIZE;
0076 
0077     if (data->validcrc & (1 << block))
0078         return 0;
0079 
0080     if (w1_reset_select_slave(sl)) {
0081         data->validcrc = 0;
0082         return -EIO;
0083     }
0084 
0085     wrbuf[0] = W1_F1C_READ_EEPROM;
0086     wrbuf[1] = off & 0xff;
0087     wrbuf[2] = off >> 8;
0088     w1_write_block(sl->master, wrbuf, 3);
0089     w1_read_block(sl->master, &data->memory[off], W1_PAGE_SIZE);
0090 
0091     /* cache the block if the CRC is valid */
0092     if (crc16(CRC16_INIT, &data->memory[off], W1_PAGE_SIZE) == CRC16_VALID)
0093         data->validcrc |= (1 << block);
0094 
0095     return 0;
0096 }
0097 
0098 static int w1_f1C_read(struct w1_slave *sl, int addr, int len, char *data)
0099 {
0100     u8 wrbuf[3];
0101 
0102     /* read directly from the EEPROM */
0103     if (w1_reset_select_slave(sl))
0104         return -EIO;
0105 
0106     wrbuf[0] = W1_F1C_READ_EEPROM;
0107     wrbuf[1] = addr & 0xff;
0108     wrbuf[2] = addr >> 8;
0109 
0110     w1_write_block(sl->master, wrbuf, sizeof(wrbuf));
0111     return w1_read_block(sl->master, data, len);
0112 }
0113 
0114 static ssize_t eeprom_read(struct file *filp, struct kobject *kobj,
0115                struct bin_attribute *bin_attr, char *buf,
0116                loff_t off, size_t count)
0117 {
0118     struct w1_slave *sl = kobj_to_w1_slave(kobj);
0119     struct w1_f1C_data *data = sl->family_data;
0120     int i, min_page, max_page;
0121 
0122     count = w1_f1C_fix_count(off, count, W1_EEPROM_SIZE);
0123     if (count == 0)
0124         return 0;
0125 
0126     mutex_lock(&sl->master->mutex);
0127 
0128     if (w1_enable_crccheck) {
0129         min_page = (off >> W1_PAGE_BITS);
0130         max_page = (off + count - 1) >> W1_PAGE_BITS;
0131         for (i = min_page; i <= max_page; i++) {
0132             if (w1_f1C_refresh_block(sl, data, i)) {
0133                 count = -EIO;
0134                 goto out_up;
0135             }
0136         }
0137         memcpy(buf, &data->memory[off], count);
0138     } else {
0139         count = w1_f1C_read(sl, off, count, buf);
0140     }
0141 
0142 out_up:
0143     mutex_unlock(&sl->master->mutex);
0144 
0145     return count;
0146 }
0147 
0148 /**
0149  * Writes to the scratchpad and reads it back for verification.
0150  * Then copies the scratchpad to EEPROM.
0151  * The data must be on one page.
0152  * The master must be locked.
0153  *
0154  * @param sl    The slave structure
0155  * @param addr  Address for the write
0156  * @param len   length must be <= (W1_PAGE_SIZE - (addr & W1_PAGE_MASK))
0157  * @param data  The data to write
0158  * @return  0=Success -1=failure
0159  */
0160 static int w1_f1C_write(struct w1_slave *sl, int addr, int len, const u8 *data)
0161 {
0162     u8 wrbuf[4];
0163     u8 rdbuf[W1_PAGE_SIZE + 3];
0164     u8 es = (addr + len - 1) & 0x1f;
0165     unsigned int tm = 10;
0166     int i;
0167     struct w1_f1C_data *f1C = sl->family_data;
0168 
0169     /* Write the data to the scratchpad */
0170     if (w1_reset_select_slave(sl))
0171         return -1;
0172 
0173     wrbuf[0] = W1_F1C_WRITE_SCRATCH;
0174     wrbuf[1] = addr & 0xff;
0175     wrbuf[2] = addr >> 8;
0176 
0177     w1_write_block(sl->master, wrbuf, 3);
0178     w1_write_block(sl->master, data, len);
0179 
0180     /* Read the scratchpad and verify */
0181     if (w1_reset_select_slave(sl))
0182         return -1;
0183 
0184     w1_write_8(sl->master, W1_F1C_READ_SCRATCH);
0185     w1_read_block(sl->master, rdbuf, len + 3);
0186 
0187     /* Compare what was read against the data written */
0188     if ((rdbuf[0] != wrbuf[1]) || (rdbuf[1] != wrbuf[2]) ||
0189         (rdbuf[2] != es) || (memcmp(data, &rdbuf[3], len) != 0))
0190         return -1;
0191 
0192     /* Copy the scratchpad to EEPROM */
0193     if (w1_reset_select_slave(sl))
0194         return -1;
0195 
0196     wrbuf[0] = W1_F1C_COPY_SCRATCH;
0197     wrbuf[3] = es;
0198 
0199     for (i = 0; i < sizeof(wrbuf); ++i) {
0200         /* issue 10ms strong pullup (or delay) on the last byte
0201            for writing the data from the scratchpad to EEPROM */
0202         if (w1_strong_pullup && i == sizeof(wrbuf)-1)
0203             w1_next_pullup(sl->master, tm);
0204 
0205         w1_write_8(sl->master, wrbuf[i]);
0206     }
0207 
0208     if (!w1_strong_pullup)
0209         msleep(tm);
0210 
0211     if (w1_enable_crccheck) {
0212         /* invalidate cached data */
0213         f1C->validcrc &= ~(1 << (addr >> W1_PAGE_BITS));
0214     }
0215 
0216     /* Reset the bus to wake up the EEPROM (this may not be needed) */
0217     w1_reset_bus(sl->master);
0218 
0219     return 0;
0220 }
0221 
0222 static ssize_t eeprom_write(struct file *filp, struct kobject *kobj,
0223                 struct bin_attribute *bin_attr, char *buf,
0224                 loff_t off, size_t count)
0225 
0226 {
0227     struct w1_slave *sl = kobj_to_w1_slave(kobj);
0228     int addr, len, idx;
0229 
0230     count = w1_f1C_fix_count(off, count, W1_EEPROM_SIZE);
0231     if (count == 0)
0232         return 0;
0233 
0234     if (w1_enable_crccheck) {
0235         /* can only write full blocks in cached mode */
0236         if ((off & W1_PAGE_MASK) || (count & W1_PAGE_MASK)) {
0237             dev_err(&sl->dev, "invalid offset/count off=%d cnt=%zd\n",
0238                 (int)off, count);
0239             return -EINVAL;
0240         }
0241 
0242         /* make sure the block CRCs are valid */
0243         for (idx = 0; idx < count; idx += W1_PAGE_SIZE) {
0244             if (crc16(CRC16_INIT, &buf[idx], W1_PAGE_SIZE)
0245                 != CRC16_VALID) {
0246                 dev_err(&sl->dev, "bad CRC at offset %d\n",
0247                     (int)off);
0248                 return -EINVAL;
0249             }
0250         }
0251     }
0252 
0253     mutex_lock(&sl->master->mutex);
0254 
0255     /* Can only write data to one page at a time */
0256     idx = 0;
0257     while (idx < count) {
0258         addr = off + idx;
0259         len = W1_PAGE_SIZE - (addr & W1_PAGE_MASK);
0260         if (len > (count - idx))
0261             len = count - idx;
0262 
0263         if (w1_f1C_write(sl, addr, len, &buf[idx]) < 0) {
0264             count = -EIO;
0265             goto out_up;
0266         }
0267         idx += len;
0268     }
0269 
0270 out_up:
0271     mutex_unlock(&sl->master->mutex);
0272 
0273     return count;
0274 }
0275 
0276 static BIN_ATTR_RW(eeprom, W1_EEPROM_SIZE);
0277 
0278 static ssize_t pio_read(struct file *filp, struct kobject *kobj,
0279             struct bin_attribute *bin_attr, char *buf, loff_t off,
0280             size_t count)
0281 
0282 {
0283     struct w1_slave *sl = kobj_to_w1_slave(kobj);
0284     int ret;
0285 
0286     /* check arguments */
0287     if (off != 0 || count != 1 || buf == NULL)
0288         return -EINVAL;
0289 
0290     mutex_lock(&sl->master->mutex);
0291     ret = w1_f1C_read(sl, W1_1C_REG_LOGIC_STATE, count, buf);
0292     mutex_unlock(&sl->master->mutex);
0293 
0294     return ret;
0295 }
0296 
0297 static ssize_t pio_write(struct file *filp, struct kobject *kobj,
0298              struct bin_attribute *bin_attr, char *buf, loff_t off,
0299              size_t count)
0300 
0301 {
0302     struct w1_slave *sl = kobj_to_w1_slave(kobj);
0303     u8 wrbuf[3];
0304     u8 ack;
0305 
0306     /* check arguments */
0307     if (off != 0 || count != 1 || buf == NULL)
0308         return -EINVAL;
0309 
0310     mutex_lock(&sl->master->mutex);
0311 
0312     /* Write the PIO data */
0313     if (w1_reset_select_slave(sl)) {
0314         mutex_unlock(&sl->master->mutex);
0315         return -1;
0316     }
0317 
0318     /* set bit 7..2 to value '1' */
0319     *buf = *buf | 0xFC;
0320 
0321     wrbuf[0] = W1_F1C_ACCESS_WRITE;
0322     wrbuf[1] = *buf;
0323     wrbuf[2] = ~(*buf);
0324     w1_write_block(sl->master, wrbuf, 3);
0325 
0326     w1_read_block(sl->master, &ack, sizeof(ack));
0327 
0328     mutex_unlock(&sl->master->mutex);
0329 
0330     /* check for acknowledgement */
0331     if (ack != 0xAA)
0332         return -EIO;
0333 
0334     return count;
0335 }
0336 
0337 static BIN_ATTR_RW(pio, 1);
0338 
0339 static ssize_t crccheck_show(struct device *dev, struct device_attribute *attr,
0340                  char *buf)
0341 {
0342     return sysfs_emit(buf, "%d\n", w1_enable_crccheck);
0343 }
0344 
0345 static ssize_t crccheck_store(struct device *dev, struct device_attribute *attr,
0346                   const char *buf, size_t count)
0347 {
0348     int err = kstrtobool(buf, &w1_enable_crccheck);
0349 
0350     if (err)
0351         return err;
0352 
0353     return count;
0354 }
0355 
0356 static DEVICE_ATTR_RW(crccheck);
0357 
0358 static struct attribute *w1_f1C_attrs[] = {
0359     &dev_attr_crccheck.attr,
0360     NULL,
0361 };
0362 
0363 static struct bin_attribute *w1_f1C_bin_attrs[] = {
0364     &bin_attr_eeprom,
0365     &bin_attr_pio,
0366     NULL,
0367 };
0368 
0369 static const struct attribute_group w1_f1C_group = {
0370     .attrs      = w1_f1C_attrs,
0371     .bin_attrs  = w1_f1C_bin_attrs,
0372 };
0373 
0374 static const struct attribute_group *w1_f1C_groups[] = {
0375     &w1_f1C_group,
0376     NULL,
0377 };
0378 
0379 static int w1_f1C_add_slave(struct w1_slave *sl)
0380 {
0381     struct w1_f1C_data *data = NULL;
0382 
0383     if (w1_enable_crccheck) {
0384         data = kzalloc(sizeof(struct w1_f1C_data), GFP_KERNEL);
0385         if (!data)
0386             return -ENOMEM;
0387         sl->family_data = data;
0388     }
0389 
0390     return 0;
0391 }
0392 
0393 static void w1_f1C_remove_slave(struct w1_slave *sl)
0394 {
0395     kfree(sl->family_data);
0396     sl->family_data = NULL;
0397 }
0398 
0399 static const struct w1_family_ops w1_f1C_fops = {
0400     .add_slave      = w1_f1C_add_slave,
0401     .remove_slave   = w1_f1C_remove_slave,
0402     .groups     = w1_f1C_groups,
0403 };
0404 
0405 static struct w1_family w1_family_1C = {
0406     .fid = W1_FAMILY_DS28E04,
0407     .fops = &w1_f1C_fops,
0408 };
0409 module_w1_family(w1_family_1C);
0410 
0411 MODULE_AUTHOR("Markus Franke <franke.m@sebakmt.com>, <franm@hrz.tu-chemnitz.de>");
0412 MODULE_DESCRIPTION("w1 family 1C driver for DS28E04, 4kb EEPROM and PIO");
0413 MODULE_LICENSE("GPL");
0414 MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS28E04));