0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/device.h>
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/moduleparam.h>
0013 #include <linux/mutex.h>
0014 #include <linux/string.h>
0015 #include <linux/types.h>
0016
0017 #include <linux/w1.h>
0018
0019 #define W1_FAMILY_DS2405 0x05
0020
0021 MODULE_LICENSE("GPL");
0022 MODULE_AUTHOR("Maciej S. Szmigiero <mail@maciej.szmigiero.name>");
0023 MODULE_DESCRIPTION("Driver for 1-wire Dallas DS2405 PIO.");
0024 MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2405));
0025
0026 static int w1_ds2405_select(struct w1_slave *sl, bool only_active)
0027 {
0028 struct w1_master *dev = sl->master;
0029
0030 u64 dev_addr = le64_to_cpu(*(u64 *)&sl->reg_num);
0031 unsigned int bit_ctr;
0032
0033 if (w1_reset_bus(dev) != 0)
0034 return 0;
0035
0036
0037
0038
0039
0040 w1_write_8(dev, only_active ? W1_ALARM_SEARCH : W1_SEARCH);
0041
0042 for (bit_ctr = 0; bit_ctr < 64; bit_ctr++) {
0043 int bit2send = !!(dev_addr & BIT(bit_ctr));
0044 u8 ret;
0045
0046 ret = w1_triplet(dev, bit2send);
0047
0048 if ((ret & (BIT(0) | BIT(1))) ==
0049 (BIT(0) | BIT(1)))
0050 return 0;
0051
0052 if (!!(ret & BIT(2)) != bit2send)
0053
0054 return 0;
0055 }
0056
0057 return 1;
0058 }
0059
0060 static int w1_ds2405_read_pio(struct w1_slave *sl)
0061 {
0062 if (w1_ds2405_select(sl, true))
0063 return 0;
0064
0065 if (w1_ds2405_select(sl, false))
0066 return 1;
0067
0068 return -ENODEV;
0069 }
0070
0071 static ssize_t state_show(struct device *device,
0072 struct device_attribute *attr, char *buf)
0073 {
0074 struct w1_slave *sl = dev_to_w1_slave(device);
0075 struct w1_master *dev = sl->master;
0076
0077 int ret;
0078 ssize_t f_retval;
0079 u8 state;
0080
0081 ret = mutex_lock_interruptible(&dev->bus_mutex);
0082 if (ret)
0083 return ret;
0084
0085 if (!w1_ds2405_select(sl, false)) {
0086 f_retval = -ENODEV;
0087 goto out_unlock;
0088 }
0089
0090 state = w1_read_8(dev);
0091 if (state != 0 &&
0092 state != 0xff) {
0093 dev_err(device, "non-consistent state %x\n", state);
0094 f_retval = -EIO;
0095 goto out_unlock;
0096 }
0097
0098 *buf = state ? '1' : '0';
0099 f_retval = 1;
0100
0101 out_unlock:
0102 w1_reset_bus(dev);
0103 mutex_unlock(&dev->bus_mutex);
0104
0105 return f_retval;
0106 }
0107
0108 static ssize_t output_show(struct device *device,
0109 struct device_attribute *attr, char *buf)
0110 {
0111 struct w1_slave *sl = dev_to_w1_slave(device);
0112 struct w1_master *dev = sl->master;
0113
0114 int ret;
0115 ssize_t f_retval;
0116
0117 ret = mutex_lock_interruptible(&dev->bus_mutex);
0118 if (ret)
0119 return ret;
0120
0121 ret = w1_ds2405_read_pio(sl);
0122 if (ret < 0) {
0123 f_retval = ret;
0124 goto out_unlock;
0125 }
0126
0127 *buf = ret ? '1' : '0';
0128 f_retval = 1;
0129
0130 out_unlock:
0131 w1_reset_bus(dev);
0132 mutex_unlock(&dev->bus_mutex);
0133
0134 return f_retval;
0135 }
0136
0137 static ssize_t output_store(struct device *device,
0138 struct device_attribute *attr,
0139 const char *buf, size_t count)
0140 {
0141 struct w1_slave *sl = dev_to_w1_slave(device);
0142 struct w1_master *dev = sl->master;
0143
0144 int ret, current_pio;
0145 unsigned int val;
0146 ssize_t f_retval;
0147
0148 if (count < 1)
0149 return -EINVAL;
0150
0151 if (sscanf(buf, " %u%n", &val, &ret) < 1)
0152 return -EINVAL;
0153
0154 if (val != 0 && val != 1)
0155 return -EINVAL;
0156
0157 f_retval = ret;
0158
0159 ret = mutex_lock_interruptible(&dev->bus_mutex);
0160 if (ret)
0161 return ret;
0162
0163 current_pio = w1_ds2405_read_pio(sl);
0164 if (current_pio < 0) {
0165 f_retval = current_pio;
0166 goto out_unlock;
0167 }
0168
0169 if (current_pio == val)
0170 goto out_unlock;
0171
0172 if (w1_reset_bus(dev) != 0) {
0173 f_retval = -ENODEV;
0174 goto out_unlock;
0175 }
0176
0177
0178
0179
0180
0181 do {
0182 u64 dev_addr = le64_to_cpu(*(u64 *)&sl->reg_num);
0183 u8 cmd[9];
0184
0185 cmd[0] = W1_MATCH_ROM;
0186 memcpy(&cmd[1], &dev_addr, sizeof(dev_addr));
0187
0188 w1_write_block(dev, cmd, sizeof(cmd));
0189 } while (0);
0190
0191 out_unlock:
0192 w1_reset_bus(dev);
0193 mutex_unlock(&dev->bus_mutex);
0194
0195 return f_retval;
0196 }
0197
0198 static DEVICE_ATTR_RO(state);
0199 static DEVICE_ATTR_RW(output);
0200
0201 static struct attribute *w1_ds2405_attrs[] = {
0202 &dev_attr_state.attr,
0203 &dev_attr_output.attr,
0204 NULL
0205 };
0206
0207 ATTRIBUTE_GROUPS(w1_ds2405);
0208
0209 static const struct w1_family_ops w1_ds2405_fops = {
0210 .groups = w1_ds2405_groups
0211 };
0212
0213 static struct w1_family w1_family_ds2405 = {
0214 .fid = W1_FAMILY_DS2405,
0215 .fops = &w1_ds2405_fops
0216 };
0217
0218 module_w1_family(w1_family_ds2405);