aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMika Laitio <lamikr@pilppa.org>2011-01-12 20:01:06 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-13 11:03:22 -0500
commit17fecb5582962c2ca5627a51ec9ab0979fb673ef (patch)
tree108d8b25267e91ec6aeb0781bc4f705e8296541f
parent496fc1a68a45ae159d26331775411f6fea36d4d3 (diff)
w1: DS2423 counter driver and documentation
This is a 1-wire/w1 DS2423 slave driver for reading the values from all 4 counters available DS2423 devices by using standard w1_slave file. In ds2423 the counters are tied to ram pages 12-15 in and each of those ram-pages. Each of these counter values (and asoociated ram page values) are represented as a own line in w1_slave file. Driver has been tested on mips and x86. usage example: cat /sys/bus/w1/devices/1d-00000009b964/w1_slave 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 5a 0e 5f 18 00 00 00 00 0b 28 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=408882778 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 Patch includes also the documentation. [randy.dunlap@oracle.com: fix ds2423 build, needs to select CRC16] Signed-off-by: Mika Laitio <lamikr@pilppa.org> Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com> Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/w1/slaves/00-INDEX2
-rw-r--r--Documentation/w1/slaves/w1_ds242347
-rw-r--r--drivers/w1/slaves/Kconfig11
-rw-r--r--drivers/w1/slaves/Makefile1
-rw-r--r--drivers/w1/slaves/w1_ds2423.c166
-rw-r--r--drivers/w1/w1_family.h1
6 files changed, 228 insertions, 0 deletions
diff --git a/Documentation/w1/slaves/00-INDEX b/Documentation/w1/slaves/00-INDEX
index f8101d6b07b7..75613c9ac4db 100644
--- a/Documentation/w1/slaves/00-INDEX
+++ b/Documentation/w1/slaves/00-INDEX
@@ -2,3 +2,5 @@
2 - This file 2 - This file
3w1_therm 3w1_therm
4 - The Maxim/Dallas Semiconductor ds18*20 temperature sensor. 4 - The Maxim/Dallas Semiconductor ds18*20 temperature sensor.
5w1_ds2423
6 - The Maxim/Dallas Semiconductor ds2423 counter device.
diff --git a/Documentation/w1/slaves/w1_ds2423 b/Documentation/w1/slaves/w1_ds2423
new file mode 100644
index 000000000000..90a65d23cf59
--- /dev/null
+++ b/Documentation/w1/slaves/w1_ds2423
@@ -0,0 +1,47 @@
1Kernel driver w1_ds2423
2=======================
3
4Supported chips:
5 * Maxim DS2423 based counter devices.
6
7supported family codes:
8 W1_THERM_DS2423 0x1D
9
10Author: Mika Laitio <lamikr@pilppa.org>
11
12Description
13-----------
14
15Support is provided through the sysfs w1_slave file. Each opening and
16read sequence of w1_slave file initiates the read of counters and ram
17available in DS2423 pages 12 - 15.
18
19Result of each page is provided as an ASCII output where each counter
20value and associated ram buffer is outpputed to own line.
21
22Each lines will contain the values of 42 bytes read from the counter and
23memory page along the crc=YES or NO for indicating whether the read operation
24was successfull and CRC matched.
25If the operation was successfull, there is also in the end of each line
26a counter value expressed as an integer after c=
27
28Meaning of 42 bytes represented is following:
29 - 1 byte from ram page
30 - 4 bytes for the counter value
31 - 4 zero bytes
32 - 2 bytes for crc16 which was calculated from the data read since the previous crc bytes
33 - 31 remaining bytes from the ram page
34 - crc=YES/NO indicating whether read was ok and crc matched
35 - c=<int> current counter value
36
37example from the successfull read:
3800 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
3900 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
4000 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
4100 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
42
43example from the read with crc errors:
4400 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
4500 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
4600 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
4700 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/Kconfig b/drivers/w1/slaves/Kconfig
index 1f51366417b9..f0c909625bd1 100644
--- a/drivers/w1/slaves/Kconfig
+++ b/drivers/w1/slaves/Kconfig
@@ -16,6 +16,17 @@ config W1_SLAVE_SMEM
16 Say Y here if you want to connect 1-wire 16 Say Y here if you want to connect 1-wire
17 simple 64bit memory rom(ds2401/ds2411/ds1990*) to your wire. 17 simple 64bit memory rom(ds2401/ds2411/ds1990*) to your wire.
18 18
19config W1_SLAVE_DS2423
20 tristate "Counter 1-wire device (DS2423)"
21 select CRC16
22 help
23 If you enable this you can read the counter values available
24 in the DS2423 chipset from the w1_slave file under the
25 sys file system.
26
27 Say Y here if you want to use a 1-wire
28 counter family device (DS2423).
29
19config W1_SLAVE_DS2431 30config W1_SLAVE_DS2431
20 tristate "1kb EEPROM family support (DS2431)" 31 tristate "1kb EEPROM family support (DS2431)"
21 help 32 help
diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile
index f1f51f19b129..3c76350a24f7 100644
--- a/drivers/w1/slaves/Makefile
+++ b/drivers/w1/slaves/Makefile
@@ -4,6 +4,7 @@
4 4
5obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o 5obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o
6obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o 6obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o
7obj-$(CONFIG_W1_SLAVE_DS2423) += w1_ds2423.o
7obj-$(CONFIG_W1_SLAVE_DS2431) += w1_ds2431.o 8obj-$(CONFIG_W1_SLAVE_DS2431) += w1_ds2431.o
8obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o 9obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o
9obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o 10obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o
diff --git a/drivers/w1/slaves/w1_ds2423.c b/drivers/w1/slaves/w1_ds2423.c
new file mode 100644
index 000000000000..7a7dbe5026f1
--- /dev/null
+++ b/drivers/w1/slaves/w1_ds2423.c
@@ -0,0 +1,166 @@
1/*
2 * w1_ds2423.c
3 *
4 * Copyright (c) 2010 Mika Laitio <lamikr@pilppa.org>
5 *
6 * This driver will read and write the value of 4 counters to w1_slave file in
7 * sys filesystem.
8 * Inspired by the w1_therm and w1_ds2431 drivers.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the therms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/device.h>
29#include <linux/types.h>
30#include <linux/delay.h>
31#include <linux/crc16.h>
32
33#include "../w1.h"
34#include "../w1_int.h"
35#include "../w1_family.h"
36
37#define CRC16_VALID 0xb001
38#define CRC16_INIT 0
39
40#define COUNTER_COUNT 4
41#define READ_BYTE_COUNT 42
42
43static ssize_t w1_counter_read(struct device *device,
44 struct device_attribute *attr, char *buf);
45
46static struct device_attribute w1_counter_attr =
47 __ATTR(w1_slave, S_IRUGO, w1_counter_read, NULL);
48
49static ssize_t w1_counter_read(struct device *device,
50 struct device_attribute *attr, char *out_buf)
51{
52 struct w1_slave *sl = dev_to_w1_slave(device);
53 struct w1_master *dev = sl->master;
54 u8 rbuf[COUNTER_COUNT * READ_BYTE_COUNT];
55 u8 wrbuf[3];
56 int rom_addr;
57 int read_byte_count;
58 int result;
59 ssize_t c;
60 int ii;
61 int p;
62 int crc;
63
64 c = PAGE_SIZE;
65 rom_addr = (12 << 5) + 31;
66 wrbuf[0] = 0xA5;
67 wrbuf[1] = rom_addr & 0xFF;
68 wrbuf[2] = rom_addr >> 8;
69 mutex_lock(&dev->mutex);
70 if (!w1_reset_select_slave(sl)) {
71 w1_write_block(dev, wrbuf, 3);
72 read_byte_count = 0;
73 for (p = 0; p < 4; p++) {
74 /*
75 * 1 byte for first bytes in ram page read
76 * 4 bytes for counter
77 * 4 bytes for zero bits
78 * 2 bytes for crc
79 * 31 remaining bytes from the ram page
80 */
81 read_byte_count += w1_read_block(dev,
82 rbuf + (p * READ_BYTE_COUNT), READ_BYTE_COUNT);
83 for (ii = 0; ii < READ_BYTE_COUNT; ++ii)
84 c -= snprintf(out_buf + PAGE_SIZE - c,
85 c, "%02x ",
86 rbuf[(p * READ_BYTE_COUNT) + ii]);
87 if (read_byte_count != (p + 1) * READ_BYTE_COUNT) {
88 dev_warn(device,
89 "w1_counter_read() returned %u bytes "
90 "instead of %d bytes wanted.\n",
91 read_byte_count,
92 READ_BYTE_COUNT);
93 c -= snprintf(out_buf + PAGE_SIZE - c,
94 c, "crc=NO\n");
95 } else {
96 if (p == 0) {
97 crc = crc16(CRC16_INIT, wrbuf, 3);
98 crc = crc16(crc, rbuf, 11);
99 } else {
100 /*
101 * DS2423 calculates crc from all bytes
102 * read after the previous crc bytes.
103 */
104 crc = crc16(CRC16_INIT,
105 (rbuf + 11) +
106 ((p - 1) * READ_BYTE_COUNT),
107 READ_BYTE_COUNT);
108 }
109 if (crc == CRC16_VALID) {
110 result = 0;
111 for (ii = 4; ii > 0; ii--) {
112 result <<= 8;
113 result |= rbuf[(p *
114 READ_BYTE_COUNT) + ii];
115 }
116 c -= snprintf(out_buf + PAGE_SIZE - c,
117 c, "crc=YES c=%d\n", result);
118 } else {
119 c -= snprintf(out_buf + PAGE_SIZE - c,
120 c, "crc=NO\n");
121 }
122 }
123 }
124 } else {
125 c -= snprintf(out_buf + PAGE_SIZE - c, c, "Connection error");
126 }
127 mutex_unlock(&dev->mutex);
128 return PAGE_SIZE - c;
129}
130
131static int w1_f1d_add_slave(struct w1_slave *sl)
132{
133 return device_create_file(&sl->dev, &w1_counter_attr);
134}
135
136static void w1_f1d_remove_slave(struct w1_slave *sl)
137{
138 device_remove_file(&sl->dev, &w1_counter_attr);
139}
140
141static struct w1_family_ops w1_f1d_fops = {
142 .add_slave = w1_f1d_add_slave,
143 .remove_slave = w1_f1d_remove_slave,
144};
145
146static struct w1_family w1_family_1d = {
147 .fid = W1_COUNTER_DS2423,
148 .fops = &w1_f1d_fops,
149};
150
151static int __init w1_f1d_init(void)
152{
153 return w1_register_family(&w1_family_1d);
154}
155
156static void __exit w1_f1d_exit(void)
157{
158 w1_unregister_family(&w1_family_1d);
159}
160
161module_init(w1_f1d_init);
162module_exit(w1_f1d_exit);
163
164MODULE_LICENSE("GPL");
165MODULE_AUTHOR("Mika Laitio <lamikr@pilppa.org>");
166MODULE_DESCRIPTION("w1 family 1d driver for DS2423, 4 counters and 4kb ram");
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h
index 3ca1b9298f21..f3b636d7cafe 100644
--- a/drivers/w1/w1_family.h
+++ b/drivers/w1/w1_family.h
@@ -30,6 +30,7 @@
30#define W1_FAMILY_SMEM_01 0x01 30#define W1_FAMILY_SMEM_01 0x01
31#define W1_FAMILY_SMEM_81 0x81 31#define W1_FAMILY_SMEM_81 0x81
32#define W1_THERM_DS18S20 0x10 32#define W1_THERM_DS18S20 0x10
33#define W1_COUNTER_DS2423 0x1D
33#define W1_THERM_DS1822 0x22 34#define W1_THERM_DS1822 0x22
34#define W1_EEPROM_DS2433 0x23 35#define W1_EEPROM_DS2433 0x23
35#define W1_THERM_DS18B20 0x28 36#define W1_THERM_DS18B20 0x28