This patch contains w1 sysfs slave driver and openwrt support for ds2423 1-wire counter chipset. Same driver works at least with 2.6.32, 2.6.34 and 2.6.36 kernels. I have submitted the same driver to kernel mailing list and it's now in -mm patch series waiting for the 2.6.38 merge window to open.
I have tested the patch with openwrt trunk. >From 3c3fe9d120a75d37276e8036288645db9865cc03 Mon Sep 17 00:00:00 2001 From: Mika Laitio <[email protected]> Date: Mon, 8 Nov 2010 21:30:15 +0200 Subject: [PATCH 2/2] ds2423 1-wire counter support Signed-off-by: Mika Laitio <[email protected]> --- package/kernel/modules/w1.mk | 15 ++ target/linux/generic/config-2.6.34 | 1 + ...s2423-w1-counter-driver-and-documentation.patch | 242 ++++++++++++++++++++ 3 files changed, 258 insertions(+), 0 deletions(-) create mode 100644 target/linux/generic/patches-2.6.34/270-ds2423-w1-counter-driver-and-documentation.patch diff --git a/package/kernel/modules/w1.mk b/package/kernel/modules/w1.mk index c1c7665..c2f446f 100644 --- a/package/kernel/modules/w1.mk +++ b/package/kernel/modules/w1.mk @@ -98,6 +98,21 @@ endef $(eval $(call KernelPackage,w1-slave-smem)) +define KernelPackage/w1-slave-ds2423 + TITLE:=1-Wire Counter device support (DS2423) + KCONFIG:= CONFIG_W1_SLAVE_DS2423 + FILES:=$(W1_SLAVES_DIR)/w1_ds2423.ko + AUTOLOAD:=$(call AutoLoad,70,w1_ds2423) + $(call AddDepends/w1) +endef + +define KernelPackage/w1-slave-ds2423/description + Kernel module for 1-wire counter(ds2423) +endef + +$(eval $(call KernelPackage,w1-slave-ds2423)) + + define KernelPackage/w1-slave-ds2433 TITLE:=Simple 64bit memory family implementation KCONFIG:= \ diff --git a/target/linux/generic/config-2.6.34 b/target/linux/generic/config-2.6.34 index bde140f..ef53f67 100644 --- a/target/linux/generic/config-2.6.34 +++ b/target/linux/generic/config-2.6.34 @@ -2903,6 +2903,7 @@ CONFIG_VMSPLIT_3G=y # CONFIG_W1_MASTER_GPIO is not set # CONFIG_W1_MASTER_MATROX is not set # CONFIG_W1_SLAVE_BQ27000 is not set +# CONFIG_W1_SLAVE_DS2423 is not set # CONFIG_W1_SLAVE_DS2431 is not set # CONFIG_W1_SLAVE_DS2433 is not set # CONFIG_W1_SLAVE_DS2760 is not set diff --git a/target/linux/generic/patches-2.6.34/270-ds2423-w1-counter-driver-and-documentation.patch b/target/linux/generic/patches-2.6.34/270-ds2423-w1-counter-driver-and-documentation.patch new file mode 100644 index 0000000..5d2010f --- /dev/null +++ b/target/linux/generic/patches-2.6.34/270-ds2423-w1-counter-driver-and-documentation.patch @@ -0,0 +1,242 @@ +From 01a34a50eb40a27dfc52a0c802c0003269d9c2d6 Mon Sep 17 00:00:00 2001 +From: Mika Laitio <[email protected]> +Date: Fri, 5 Nov 2010 16:31:39 +0200 +Subject: [PATCH] w1 driver for DS2423 + + +Signed-off-by: Mika Laitio <[email protected]> +--- + Documentation/w1/slaves/w1_ds2423 | 47 +++++++++++ + drivers/w1/slaves/w1_ds2423.c | 166 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 213 insertions(+), 0 deletions(-) + create mode 100644 Documentation/w1/slaves/w1_ds2423 + create mode 100644 drivers/w1/slaves/w1_ds2423.c + +diff --git a/Documentation/w1/slaves/w1_ds2423 b/Documentation/w1/slaves/w1_ds2423 +new file mode 100644 +index 0000000..90a65d2 +--- /dev/null ++++ b/Documentation/w1/slaves/w1_ds2423 +@@ -0,0 +1,47 @@ ++Kernel driver w1_ds2423 ++======================= ++ ++Supported chips: ++ * Maxim DS2423 based counter devices. ++ ++supported family codes: ++ W1_THERM_DS2423 0x1D ++ ++Author: Mika Laitio <[email protected]> ++ ++Description ++----------- ++ ++Support is provided through the sysfs w1_slave file. Each opening and ++read sequence of w1_slave file initiates the read of counters and ram ++available in DS2423 pages 12 - 15. ++ ++Result of each page is provided as an ASCII output where each counter ++value and associated ram buffer is outpputed to own line. ++ ++Each lines will contain the values of 42 bytes read from the counter and ++memory page along the crc=YES or NO for indicating whether the read operation ++was successfull and CRC matched. ++If the operation was successfull, there is also in the end of each line ++a counter value expressed as an integer after c= ++ ++Meaning of 42 bytes represented is following: ++ - 1 byte from ram page ++ - 4 bytes for the counter value ++ - 4 zero bytes ++ - 2 bytes for crc16 which was calculated from the data read since the previous crc bytes ++ - 31 remaining bytes from the ram page ++ - crc=YES/NO indicating whether read was ok and crc matched ++ - c=<int> current counter value ++ ++example from the successfull read: ++00 02 00 00 00 00 00 00 00 6d 38 00 ff ff 00 00 fe ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff crc=YES c=2 ++00 02 00 00 00 00 00 00 00 e0 1f 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff crc=YES c=2 ++00 29 c6 5d 18 00 00 00 00 04 37 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff crc=YES c=408798761 ++00 05 00 00 00 00 00 00 00 8d 39 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff crc=YES c=5 ++ ++example from the read with crc errors: ++00 02 00 00 00 00 00 00 00 6d 38 00 ff ff 00 00 fe ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff crc=YES c=2 ++00 02 00 00 22 00 00 00 00 e0 1f 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff crc=NO ++00 e1 61 5d 19 00 00 00 00 df 0b 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff crc=NO ++00 05 00 00 20 00 00 00 00 8d 39 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff crc=NO +diff --git a/drivers/w1/slaves/w1_ds2423.c b/drivers/w1/slaves/w1_ds2423.c +new file mode 100644 +index 0000000..7a7dbe5 +--- /dev/null ++++ b/drivers/w1/slaves/w1_ds2423.c +@@ -0,0 +1,166 @@ ++/* ++ * w1_ds2423.c ++ * ++ * Copyright (c) 2010 Mika Laitio <[email protected]> ++ * ++ * This driver will read and write the value of 4 counters to w1_slave file in ++ * sys filesystem. ++ * Inspired by the w1_therm and w1_ds2431 drivers. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the therms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/device.h> ++#include <linux/types.h> ++#include <linux/delay.h> ++#include <linux/crc16.h> ++ ++#include "../w1.h" ++#include "../w1_int.h" ++#include "../w1_family.h" ++ ++#define CRC16_VALID 0xb001 ++#define CRC16_INIT 0 ++ ++#define COUNTER_COUNT 4 ++#define READ_BYTE_COUNT 42 ++ ++static ssize_t w1_counter_read(struct device *device, ++ struct device_attribute *attr, char *buf); ++ ++static struct device_attribute w1_counter_attr = ++ __ATTR(w1_slave, S_IRUGO, w1_counter_read, NULL); ++ ++static ssize_t w1_counter_read(struct device *device, ++ struct device_attribute *attr, char *out_buf) ++{ ++ struct w1_slave *sl = dev_to_w1_slave(device); ++ struct w1_master *dev = sl->master; ++ u8 rbuf[COUNTER_COUNT * READ_BYTE_COUNT]; ++ u8 wrbuf[3]; ++ int rom_addr; ++ int read_byte_count; ++ int result; ++ ssize_t c; ++ int ii; ++ int p; ++ int crc; ++ ++ c = PAGE_SIZE; ++ rom_addr = (12 << 5) + 31; ++ wrbuf[0] = 0xA5; ++ wrbuf[1] = rom_addr & 0xFF; ++ wrbuf[2] = rom_addr >> 8; ++ mutex_lock(&dev->mutex); ++ if (!w1_reset_select_slave(sl)) { ++ w1_write_block(dev, wrbuf, 3); ++ read_byte_count = 0; ++ for (p = 0; p < 4; p++) { ++ /* ++ * 1 byte for first bytes in ram page read ++ * 4 bytes for counter ++ * 4 bytes for zero bits ++ * 2 bytes for crc ++ * 31 remaining bytes from the ram page ++ */ ++ read_byte_count += w1_read_block(dev, ++ rbuf + (p * READ_BYTE_COUNT), READ_BYTE_COUNT); ++ for (ii = 0; ii < READ_BYTE_COUNT; ++ii) ++ c -= snprintf(out_buf + PAGE_SIZE - c, ++ c, "%02x ", ++ rbuf[(p * READ_BYTE_COUNT) + ii]); ++ if (read_byte_count != (p + 1) * READ_BYTE_COUNT) { ++ dev_warn(device, ++ "w1_counter_read() returned %u bytes " ++ "instead of %d bytes wanted.\n", ++ read_byte_count, ++ READ_BYTE_COUNT); ++ c -= snprintf(out_buf + PAGE_SIZE - c, ++ c, "crc=NO\n"); ++ } else { ++ if (p == 0) { ++ crc = crc16(CRC16_INIT, wrbuf, 3); ++ crc = crc16(crc, rbuf, 11); ++ } else { ++ /* ++ * DS2423 calculates crc from all bytes ++ * read after the previous crc bytes. ++ */ ++ crc = crc16(CRC16_INIT, ++ (rbuf + 11) + ++ ((p - 1) * READ_BYTE_COUNT), ++ READ_BYTE_COUNT); ++ } ++ if (crc == CRC16_VALID) { ++ result = 0; ++ for (ii = 4; ii > 0; ii--) { ++ result <<= 8; ++ result |= rbuf[(p * ++ READ_BYTE_COUNT) + ii]; ++ } ++ c -= snprintf(out_buf + PAGE_SIZE - c, ++ c, "crc=YES c=%d\n", result); ++ } else { ++ c -= snprintf(out_buf + PAGE_SIZE - c, ++ c, "crc=NO\n"); ++ } ++ } ++ } ++ } else { ++ c -= snprintf(out_buf + PAGE_SIZE - c, c, "Connection error"); ++ } ++ mutex_unlock(&dev->mutex); ++ return PAGE_SIZE - c; ++} ++ ++static int w1_f1d_add_slave(struct w1_slave *sl) ++{ ++ return device_create_file(&sl->dev, &w1_counter_attr); ++} ++ ++static void w1_f1d_remove_slave(struct w1_slave *sl) ++{ ++ device_remove_file(&sl->dev, &w1_counter_attr); ++} ++ ++static struct w1_family_ops w1_f1d_fops = { ++ .add_slave = w1_f1d_add_slave, ++ .remove_slave = w1_f1d_remove_slave, ++}; ++ ++static struct w1_family w1_family_1d = { ++ .fid = W1_COUNTER_DS2423, ++ .fops = &w1_f1d_fops, ++}; ++ ++static int __init w1_f1d_init(void) ++{ ++ return w1_register_family(&w1_family_1d); ++} ++ ++static void __exit w1_f1d_exit(void) ++{ ++ w1_unregister_family(&w1_family_1d); ++} ++ ++module_init(w1_f1d_init); ++module_exit(w1_f1d_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Mika Laitio <[email protected]>"); ++MODULE_DESCRIPTION("w1 family 1d driver for DS2423, 4 counters and 4kb ram"); +-- +1.7.1 + -- 1.7.1 -- Mika _______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/mailman/listinfo/openwrt-devel
