^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * w1_ds2413.c - w1 family 3a (DS2413) driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * based on w1_ds2408.c by Jean-Francois Dagenais <dagenaisj@sonatest.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2013 Mariusz Bialonczyk <manio@skyboo.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/w1.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define W1_FAMILY_DS2413 0x3A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define W1_F3A_RETRIES 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define W1_F3A_FUNC_PIO_ACCESS_READ 0xF5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define W1_F3A_FUNC_PIO_ACCESS_WRITE 0x5A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define W1_F3A_SUCCESS_CONFIRM_BYTE 0xAA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define W1_F3A_INVALID_PIO_STATE 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static ssize_t state_read(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct bin_attribute *bin_attr, char *buf, loff_t off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct w1_slave *sl = kobj_to_w1_slave(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) unsigned int retries = W1_F3A_RETRIES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ssize_t bytes_read = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) u8 state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) dev_dbg(&sl->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (off != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) mutex_lock(&sl->master->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) dev_dbg(&sl->dev, "mutex locked");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (w1_reset_select_slave(sl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) while (retries--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) w1_write_8(sl->master, W1_F3A_FUNC_PIO_ACCESS_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) state = w1_read_8(sl->master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if ((state & 0x0F) == ((~state >> 4) & 0x0F)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* complement is correct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) *buf = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) bytes_read = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) } else if (state == W1_F3A_INVALID_PIO_STATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* slave didn't respond, try to select it again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) dev_warn(&sl->dev, "slave device did not respond to PIO_ACCESS_READ, " \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) "reselecting, retries left: %d\n", retries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (w1_reset_resume_command(sl->master))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) goto out; /* unrecoverable error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) dev_warn(&sl->dev, "PIO_ACCESS_READ error, retries left: %d\n", retries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) mutex_unlock(&sl->master->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) dev_dbg(&sl->dev, "%s, mutex unlocked, retries: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) (bytes_read > 0) ? "succeeded" : "error", retries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return bytes_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static BIN_ATTR_RO(state, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static ssize_t output_write(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct bin_attribute *bin_attr, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct w1_slave *sl = kobj_to_w1_slave(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u8 w1_buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned int retries = W1_F3A_RETRIES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ssize_t bytes_written = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (count != 1 || off != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) dev_dbg(&sl->dev, "locking mutex for write_output");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) mutex_lock(&sl->master->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) dev_dbg(&sl->dev, "mutex locked");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (w1_reset_select_slave(sl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* according to the DS2413 datasheet the most significant 6 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) should be set to "1"s, so do it now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) *buf = *buf | 0xFC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) while (retries--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) w1_buf[0] = W1_F3A_FUNC_PIO_ACCESS_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) w1_buf[1] = *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) w1_buf[2] = ~(*buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) w1_write_block(sl->master, w1_buf, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (w1_read_8(sl->master) == W1_F3A_SUCCESS_CONFIRM_BYTE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) bytes_written = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (w1_reset_resume_command(sl->master))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) goto out; /* unrecoverable error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) dev_warn(&sl->dev, "PIO_ACCESS_WRITE error, retries left: %d\n", retries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) mutex_unlock(&sl->master->bus_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) dev_dbg(&sl->dev, "%s, mutex unlocked, retries: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) (bytes_written > 0) ? "succeeded" : "error", retries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return bytes_written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static BIN_ATTR(output, S_IRUGO | S_IWUSR | S_IWGRP, NULL, output_write, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static struct bin_attribute *w1_f3a_bin_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) &bin_attr_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) &bin_attr_output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static const struct attribute_group w1_f3a_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .bin_attrs = w1_f3a_bin_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static const struct attribute_group *w1_f3a_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) &w1_f3a_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static const struct w1_family_ops w1_f3a_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .groups = w1_f3a_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static struct w1_family w1_family_3a = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .fid = W1_FAMILY_DS2413,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .fops = &w1_f3a_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) module_w1_family(w1_family_3a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) MODULE_AUTHOR("Mariusz Bialonczyk <manio@skyboo.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) MODULE_DESCRIPTION("w1 family 3a driver for DS2413 2 Pin IO");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2413));