0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/moduleparam.h>
0012 #include <linux/device.h>
0013 #include <linux/types.h>
0014 #include <linux/delay.h>
0015 #include <linux/slab.h>
0016
0017 #include <linux/w1.h>
0018
0019 #define W1_FAMILY_DS2413 0x3A
0020
0021 #define W1_F3A_RETRIES 3
0022 #define W1_F3A_FUNC_PIO_ACCESS_READ 0xF5
0023 #define W1_F3A_FUNC_PIO_ACCESS_WRITE 0x5A
0024 #define W1_F3A_SUCCESS_CONFIRM_BYTE 0xAA
0025 #define W1_F3A_INVALID_PIO_STATE 0xFF
0026
0027 static ssize_t state_read(struct file *filp, struct kobject *kobj,
0028 struct bin_attribute *bin_attr, char *buf, loff_t off,
0029 size_t count)
0030 {
0031 struct w1_slave *sl = kobj_to_w1_slave(kobj);
0032 unsigned int retries = W1_F3A_RETRIES;
0033 ssize_t bytes_read = -EIO;
0034 u8 state;
0035
0036 dev_dbg(&sl->dev,
0037 "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
0038 bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
0039
0040 if (off != 0)
0041 return 0;
0042 if (!buf)
0043 return -EINVAL;
0044
0045 mutex_lock(&sl->master->bus_mutex);
0046 dev_dbg(&sl->dev, "mutex locked");
0047
0048 next:
0049 if (w1_reset_select_slave(sl))
0050 goto out;
0051
0052 while (retries--) {
0053 w1_write_8(sl->master, W1_F3A_FUNC_PIO_ACCESS_READ);
0054
0055 state = w1_read_8(sl->master);
0056 if ((state & 0x0F) == ((~state >> 4) & 0x0F)) {
0057
0058 *buf = state;
0059 bytes_read = 1;
0060 goto out;
0061 } else if (state == W1_F3A_INVALID_PIO_STATE) {
0062
0063 dev_warn(&sl->dev, "slave device did not respond to PIO_ACCESS_READ, " \
0064 "reselecting, retries left: %d\n", retries);
0065 goto next;
0066 }
0067
0068 if (w1_reset_resume_command(sl->master))
0069 goto out;
0070
0071 dev_warn(&sl->dev, "PIO_ACCESS_READ error, retries left: %d\n", retries);
0072 }
0073
0074 out:
0075 mutex_unlock(&sl->master->bus_mutex);
0076 dev_dbg(&sl->dev, "%s, mutex unlocked, retries: %d\n",
0077 (bytes_read > 0) ? "succeeded" : "error", retries);
0078 return bytes_read;
0079 }
0080
0081 static BIN_ATTR_RO(state, 1);
0082
0083 static ssize_t output_write(struct file *filp, struct kobject *kobj,
0084 struct bin_attribute *bin_attr, char *buf,
0085 loff_t off, size_t count)
0086 {
0087 struct w1_slave *sl = kobj_to_w1_slave(kobj);
0088 u8 w1_buf[3];
0089 unsigned int retries = W1_F3A_RETRIES;
0090 ssize_t bytes_written = -EIO;
0091
0092 if (count != 1 || off != 0)
0093 return -EFAULT;
0094
0095 dev_dbg(&sl->dev, "locking mutex for write_output");
0096 mutex_lock(&sl->master->bus_mutex);
0097 dev_dbg(&sl->dev, "mutex locked");
0098
0099 if (w1_reset_select_slave(sl))
0100 goto out;
0101
0102
0103
0104 *buf = *buf | 0xFC;
0105
0106 while (retries--) {
0107 w1_buf[0] = W1_F3A_FUNC_PIO_ACCESS_WRITE;
0108 w1_buf[1] = *buf;
0109 w1_buf[2] = ~(*buf);
0110 w1_write_block(sl->master, w1_buf, 3);
0111
0112 if (w1_read_8(sl->master) == W1_F3A_SUCCESS_CONFIRM_BYTE) {
0113 bytes_written = 1;
0114 goto out;
0115 }
0116 if (w1_reset_resume_command(sl->master))
0117 goto out;
0118
0119 dev_warn(&sl->dev, "PIO_ACCESS_WRITE error, retries left: %d\n", retries);
0120 }
0121
0122 out:
0123 mutex_unlock(&sl->master->bus_mutex);
0124 dev_dbg(&sl->dev, "%s, mutex unlocked, retries: %d\n",
0125 (bytes_written > 0) ? "succeeded" : "error", retries);
0126 return bytes_written;
0127 }
0128
0129 static BIN_ATTR(output, S_IRUGO | S_IWUSR | S_IWGRP, NULL, output_write, 1);
0130
0131 static struct bin_attribute *w1_f3a_bin_attrs[] = {
0132 &bin_attr_state,
0133 &bin_attr_output,
0134 NULL,
0135 };
0136
0137 static const struct attribute_group w1_f3a_group = {
0138 .bin_attrs = w1_f3a_bin_attrs,
0139 };
0140
0141 static const struct attribute_group *w1_f3a_groups[] = {
0142 &w1_f3a_group,
0143 NULL,
0144 };
0145
0146 static const struct w1_family_ops w1_f3a_fops = {
0147 .groups = w1_f3a_groups,
0148 };
0149
0150 static struct w1_family w1_family_3a = {
0151 .fid = W1_FAMILY_DS2413,
0152 .fops = &w1_f3a_fops,
0153 };
0154 module_w1_family(w1_family_3a);
0155
0156 MODULE_AUTHOR("Mariusz Bialonczyk <manio@skyboo.net>");
0157 MODULE_DESCRIPTION("w1 family 3a driver for DS2413 2 Pin IO");
0158 MODULE_LICENSE("GPL");
0159 MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2413));