Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  w1_ds2408.c - w1 family 29 (DS2408) driver
0004  *
0005  * Copyright (c) 2010 Jean-Francois Dagenais <dagenaisj@sonatest.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 
0016 #include <linux/w1.h>
0017 
0018 #define W1_FAMILY_DS2408    0x29
0019 
0020 #define W1_F29_RETRIES      3
0021 
0022 #define W1_F29_REG_LOGIG_STATE             0x88 /* R */
0023 #define W1_F29_REG_OUTPUT_LATCH_STATE      0x89 /* R */
0024 #define W1_F29_REG_ACTIVITY_LATCH_STATE    0x8A /* R */
0025 #define W1_F29_REG_COND_SEARCH_SELECT_MASK 0x8B /* RW */
0026 #define W1_F29_REG_COND_SEARCH_POL_SELECT  0x8C /* RW */
0027 #define W1_F29_REG_CONTROL_AND_STATUS      0x8D /* RW */
0028 
0029 #define W1_F29_FUNC_READ_PIO_REGS          0xF0
0030 #define W1_F29_FUNC_CHANN_ACCESS_READ      0xF5
0031 #define W1_F29_FUNC_CHANN_ACCESS_WRITE     0x5A
0032 /* also used to write the control/status reg (0x8D): */
0033 #define W1_F29_FUNC_WRITE_COND_SEARCH_REG  0xCC
0034 #define W1_F29_FUNC_RESET_ACTIVITY_LATCHES 0xC3
0035 
0036 #define W1_F29_SUCCESS_CONFIRM_BYTE        0xAA
0037 
0038 static int _read_reg(struct w1_slave *sl, u8 address, unsigned char* buf)
0039 {
0040     u8 wrbuf[3];
0041     dev_dbg(&sl->dev,
0042             "Reading with slave: %p, reg addr: %0#4x, buff addr: %p",
0043             sl, (unsigned int)address, buf);
0044 
0045     if (!buf)
0046         return -EINVAL;
0047 
0048     mutex_lock(&sl->master->bus_mutex);
0049     dev_dbg(&sl->dev, "mutex locked");
0050 
0051     if (w1_reset_select_slave(sl)) {
0052         mutex_unlock(&sl->master->bus_mutex);
0053         return -EIO;
0054     }
0055 
0056     wrbuf[0] = W1_F29_FUNC_READ_PIO_REGS;
0057     wrbuf[1] = address;
0058     wrbuf[2] = 0;
0059     w1_write_block(sl->master, wrbuf, 3);
0060     *buf = w1_read_8(sl->master);
0061 
0062     mutex_unlock(&sl->master->bus_mutex);
0063     dev_dbg(&sl->dev, "mutex unlocked");
0064     return 1;
0065 }
0066 
0067 static ssize_t state_read(struct file *filp, struct kobject *kobj,
0068               struct bin_attribute *bin_attr, char *buf, loff_t off,
0069               size_t count)
0070 {
0071     dev_dbg(&kobj_to_w1_slave(kobj)->dev,
0072         "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
0073         bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
0074     if (count != 1 || off != 0)
0075         return -EFAULT;
0076     return _read_reg(kobj_to_w1_slave(kobj), W1_F29_REG_LOGIG_STATE, buf);
0077 }
0078 
0079 static ssize_t output_read(struct file *filp, struct kobject *kobj,
0080                struct bin_attribute *bin_attr, char *buf,
0081                loff_t off, size_t count)
0082 {
0083     dev_dbg(&kobj_to_w1_slave(kobj)->dev,
0084         "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
0085         bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
0086     if (count != 1 || off != 0)
0087         return -EFAULT;
0088     return _read_reg(kobj_to_w1_slave(kobj),
0089                      W1_F29_REG_OUTPUT_LATCH_STATE, buf);
0090 }
0091 
0092 static ssize_t activity_read(struct file *filp, struct kobject *kobj,
0093                  struct bin_attribute *bin_attr, char *buf,
0094                  loff_t off, size_t count)
0095 {
0096     dev_dbg(&kobj_to_w1_slave(kobj)->dev,
0097         "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
0098         bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
0099     if (count != 1 || off != 0)
0100         return -EFAULT;
0101     return _read_reg(kobj_to_w1_slave(kobj),
0102                      W1_F29_REG_ACTIVITY_LATCH_STATE, buf);
0103 }
0104 
0105 static ssize_t cond_search_mask_read(struct file *filp, struct kobject *kobj,
0106                      struct bin_attribute *bin_attr, char *buf,
0107                      loff_t off, size_t count)
0108 {
0109     dev_dbg(&kobj_to_w1_slave(kobj)->dev,
0110         "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
0111         bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
0112     if (count != 1 || off != 0)
0113         return -EFAULT;
0114     return _read_reg(kobj_to_w1_slave(kobj),
0115         W1_F29_REG_COND_SEARCH_SELECT_MASK, buf);
0116 }
0117 
0118 static ssize_t cond_search_polarity_read(struct file *filp,
0119                      struct kobject *kobj,
0120                      struct bin_attribute *bin_attr,
0121                      char *buf, loff_t off, size_t count)
0122 {
0123     if (count != 1 || off != 0)
0124         return -EFAULT;
0125     return _read_reg(kobj_to_w1_slave(kobj),
0126         W1_F29_REG_COND_SEARCH_POL_SELECT, buf);
0127 }
0128 
0129 static ssize_t status_control_read(struct file *filp, struct kobject *kobj,
0130                    struct bin_attribute *bin_attr, char *buf,
0131                    loff_t off, size_t count)
0132 {
0133     if (count != 1 || off != 0)
0134         return -EFAULT;
0135     return _read_reg(kobj_to_w1_slave(kobj),
0136         W1_F29_REG_CONTROL_AND_STATUS, buf);
0137 }
0138 
0139 #ifdef CONFIG_W1_SLAVE_DS2408_READBACK
0140 static bool optional_read_back_valid(struct w1_slave *sl, u8 expected)
0141 {
0142     u8 w1_buf[3];
0143 
0144     if (w1_reset_resume_command(sl->master))
0145         return false;
0146 
0147     w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
0148     w1_buf[1] = W1_F29_REG_OUTPUT_LATCH_STATE;
0149     w1_buf[2] = 0;
0150 
0151     w1_write_block(sl->master, w1_buf, 3);
0152 
0153     return (w1_read_8(sl->master) == expected);
0154 }
0155 #else
0156 static bool optional_read_back_valid(struct w1_slave *sl, u8 expected)
0157 {
0158     return true;
0159 }
0160 #endif
0161 
0162 static ssize_t output_write(struct file *filp, struct kobject *kobj,
0163                 struct bin_attribute *bin_attr, char *buf,
0164                 loff_t off, size_t count)
0165 {
0166     struct w1_slave *sl = kobj_to_w1_slave(kobj);
0167     u8 w1_buf[3];
0168     unsigned int retries = W1_F29_RETRIES;
0169     ssize_t bytes_written = -EIO;
0170 
0171     if (count != 1 || off != 0)
0172         return -EFAULT;
0173 
0174     dev_dbg(&sl->dev, "locking mutex for write_output");
0175     mutex_lock(&sl->master->bus_mutex);
0176     dev_dbg(&sl->dev, "mutex locked");
0177 
0178     if (w1_reset_select_slave(sl))
0179         goto out;
0180 
0181     do {
0182         w1_buf[0] = W1_F29_FUNC_CHANN_ACCESS_WRITE;
0183         w1_buf[1] = *buf;
0184         w1_buf[2] = ~(*buf);
0185 
0186         w1_write_block(sl->master, w1_buf, 3);
0187 
0188         if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE &&
0189             optional_read_back_valid(sl, *buf)) {
0190             bytes_written = 1;
0191             goto out;
0192         }
0193 
0194         if (w1_reset_resume_command(sl->master))
0195             goto out; /* unrecoverable error */
0196         /* try again, the slave is ready for a command */
0197     } while (--retries);
0198 
0199 out:
0200     mutex_unlock(&sl->master->bus_mutex);
0201 
0202     dev_dbg(&sl->dev, "%s, mutex unlocked retries:%d\n",
0203         (bytes_written > 0) ? "succeeded" : "error", retries);
0204 
0205     return bytes_written;
0206 }
0207 
0208 
0209 /**
0210  * Writing to the activity file resets the activity latches.
0211  */
0212 static ssize_t activity_write(struct file *filp, struct kobject *kobj,
0213                   struct bin_attribute *bin_attr, char *buf,
0214                   loff_t off, size_t count)
0215 {
0216     struct w1_slave *sl = kobj_to_w1_slave(kobj);
0217     unsigned int retries = W1_F29_RETRIES;
0218 
0219     if (count != 1 || off != 0)
0220         return -EFAULT;
0221 
0222     mutex_lock(&sl->master->bus_mutex);
0223 
0224     if (w1_reset_select_slave(sl))
0225         goto error;
0226 
0227     while (retries--) {
0228         w1_write_8(sl->master, W1_F29_FUNC_RESET_ACTIVITY_LATCHES);
0229         if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE) {
0230             mutex_unlock(&sl->master->bus_mutex);
0231             return 1;
0232         }
0233         if (w1_reset_resume_command(sl->master))
0234             goto error;
0235     }
0236 
0237 error:
0238     mutex_unlock(&sl->master->bus_mutex);
0239     return -EIO;
0240 }
0241 
0242 static ssize_t status_control_write(struct file *filp, struct kobject *kobj,
0243                     struct bin_attribute *bin_attr, char *buf,
0244                     loff_t off, size_t count)
0245 {
0246     struct w1_slave *sl = kobj_to_w1_slave(kobj);
0247     u8 w1_buf[4];
0248     unsigned int retries = W1_F29_RETRIES;
0249 
0250     if (count != 1 || off != 0)
0251         return -EFAULT;
0252 
0253     mutex_lock(&sl->master->bus_mutex);
0254 
0255     if (w1_reset_select_slave(sl))
0256         goto error;
0257 
0258     while (retries--) {
0259         w1_buf[0] = W1_F29_FUNC_WRITE_COND_SEARCH_REG;
0260         w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
0261         w1_buf[2] = 0;
0262         w1_buf[3] = *buf;
0263 
0264         w1_write_block(sl->master, w1_buf, 4);
0265         if (w1_reset_resume_command(sl->master))
0266             goto error;
0267 
0268         w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
0269         w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
0270         w1_buf[2] = 0;
0271 
0272         w1_write_block(sl->master, w1_buf, 3);
0273         if (w1_read_8(sl->master) == *buf) {
0274             /* success! */
0275             mutex_unlock(&sl->master->bus_mutex);
0276             return 1;
0277         }
0278     }
0279 error:
0280     mutex_unlock(&sl->master->bus_mutex);
0281 
0282     return -EIO;
0283 }
0284 
0285 /*
0286  * This is a special sequence we must do to ensure the P0 output is not stuck
0287  * in test mode. This is described in rev 2 of the ds2408's datasheet
0288  * (http://datasheets.maximintegrated.com/en/ds/DS2408.pdf) under
0289  * "APPLICATION INFORMATION/Power-up timing".
0290  */
0291 static int w1_f29_disable_test_mode(struct w1_slave *sl)
0292 {
0293     int res;
0294     u8 magic[10] = {0x96, };
0295     u64 rn = le64_to_cpu(*((u64*)&sl->reg_num));
0296 
0297     memcpy(&magic[1], &rn, 8);
0298     magic[9] = 0x3C;
0299 
0300     mutex_lock(&sl->master->bus_mutex);
0301 
0302     res = w1_reset_bus(sl->master);
0303     if (res)
0304         goto out;
0305     w1_write_block(sl->master, magic, ARRAY_SIZE(magic));
0306 
0307     res = w1_reset_bus(sl->master);
0308 out:
0309     mutex_unlock(&sl->master->bus_mutex);
0310     return res;
0311 }
0312 
0313 static BIN_ATTR_RO(state, 1);
0314 static BIN_ATTR_RW(output, 1);
0315 static BIN_ATTR_RW(activity, 1);
0316 static BIN_ATTR_RO(cond_search_mask, 1);
0317 static BIN_ATTR_RO(cond_search_polarity, 1);
0318 static BIN_ATTR_RW(status_control, 1);
0319 
0320 static struct bin_attribute *w1_f29_bin_attrs[] = {
0321     &bin_attr_state,
0322     &bin_attr_output,
0323     &bin_attr_activity,
0324     &bin_attr_cond_search_mask,
0325     &bin_attr_cond_search_polarity,
0326     &bin_attr_status_control,
0327     NULL,
0328 };
0329 
0330 static const struct attribute_group w1_f29_group = {
0331     .bin_attrs = w1_f29_bin_attrs,
0332 };
0333 
0334 static const struct attribute_group *w1_f29_groups[] = {
0335     &w1_f29_group,
0336     NULL,
0337 };
0338 
0339 static const struct w1_family_ops w1_f29_fops = {
0340     .add_slave      = w1_f29_disable_test_mode,
0341     .groups     = w1_f29_groups,
0342 };
0343 
0344 static struct w1_family w1_family_29 = {
0345     .fid = W1_FAMILY_DS2408,
0346     .fops = &w1_f29_fops,
0347 };
0348 module_w1_family(w1_family_29);
0349 
0350 MODULE_AUTHOR("Jean-Francois Dagenais <dagenaisj@sonatest.com>");
0351 MODULE_DESCRIPTION("w1 family 29 driver for DS2408 8 Pin IO");
0352 MODULE_LICENSE("GPL");
0353 MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2408));