2 * w1_ds2406.c - w1 family 12 (DS2406) driver
3 * based on w1_ds2413.c by Mariusz Bialonczyk <manio@skyboo.net>
5 * Copyright (c) 2014 Scott Alfter <scott@alfter.us>
7 * This source code is licensed under the GNU General Public License,
8 * Version 2. See the file COPYING for more details.
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/moduleparam.h>
14 #include <linux/device.h>
15 #include <linux/types.h>
16 #include <linux/delay.h>
17 #include <linux/slab.h>
18 #include <linux/crc16.h>
22 #define W1_FAMILY_DS2406 0x12
24 #define W1_F12_FUNC_READ_STATUS 0xAA
25 #define W1_F12_FUNC_WRITE_STATUS 0x55
27 static ssize_t
w1_f12_read_state(
28 struct file
*filp
, struct kobject
*kobj
,
29 struct bin_attribute
*bin_attr
,
30 char *buf
, loff_t off
, size_t count
)
32 u8 w1_buf
[6]={W1_F12_FUNC_READ_STATUS
, 7, 0, 0, 0, 0};
33 struct w1_slave
*sl
= kobj_to_w1_slave(kobj
);
43 mutex_lock(&sl
->master
->bus_mutex
);
45 if (w1_reset_select_slave(sl
)) {
46 mutex_unlock(&sl
->master
->bus_mutex
);
50 w1_write_block(sl
->master
, w1_buf
, 3);
51 w1_read_block(sl
->master
, w1_buf
+3, 3);
53 crc
=crc16_byte(crc
, w1_buf
[i
]);
54 if (crc
==0xb001) /* good read? */
55 *buf
=((w1_buf
[3]>>5)&3)|0x30;
59 mutex_unlock(&sl
->master
->bus_mutex
);
64 static ssize_t
w1_f12_write_output(
65 struct file
*filp
, struct kobject
*kobj
,
66 struct bin_attribute
*bin_attr
,
67 char *buf
, loff_t off
, size_t count
)
69 struct w1_slave
*sl
= kobj_to_w1_slave(kobj
);
70 u8 w1_buf
[6]={W1_F12_FUNC_WRITE_STATUS
, 7, 0, 0, 0, 0};
75 if (count
!= 1 || off
!= 0)
78 mutex_lock(&sl
->master
->bus_mutex
);
80 if (w1_reset_select_slave(sl
)) {
81 mutex_unlock(&sl
->master
->bus_mutex
);
85 w1_buf
[3] = (((*buf
)&3)<<5)|0x1F;
86 w1_write_block(sl
->master
, w1_buf
, 4);
87 w1_read_block(sl
->master
, w1_buf
+4, 2);
89 crc
=crc16_byte(crc
, w1_buf
[i
]);
90 if (crc
==0xb001) /* good read? */
91 w1_write_8(sl
->master
, 0xFF);
95 mutex_unlock(&sl
->master
->bus_mutex
);
99 #define NB_SYSFS_BIN_FILES 2
100 static struct bin_attribute w1_f12_sysfs_bin_files
[NB_SYSFS_BIN_FILES
] = {
107 .read
= w1_f12_read_state
,
112 .mode
= S_IRUGO
| S_IWUSR
| S_IWGRP
,
115 .write
= w1_f12_write_output
,
119 static int w1_f12_add_slave(struct w1_slave
*sl
)
124 for (i
= 0; i
< NB_SYSFS_BIN_FILES
&& !err
; ++i
)
125 err
= sysfs_create_bin_file(
127 &(w1_f12_sysfs_bin_files
[i
]));
130 sysfs_remove_bin_file(&sl
->dev
.kobj
,
131 &(w1_f12_sysfs_bin_files
[i
]));
135 static void w1_f12_remove_slave(struct w1_slave
*sl
)
138 for (i
= NB_SYSFS_BIN_FILES
- 1; i
>= 0; --i
)
139 sysfs_remove_bin_file(&sl
->dev
.kobj
,
140 &(w1_f12_sysfs_bin_files
[i
]));
143 static struct w1_family_ops w1_f12_fops
= {
144 .add_slave
= w1_f12_add_slave
,
145 .remove_slave
= w1_f12_remove_slave
,
148 static struct w1_family w1_family_12
= {
149 .fid
= W1_FAMILY_DS2406
,
150 .fops
= &w1_f12_fops
,
152 module_w1_family(w1_family_12
);
154 MODULE_AUTHOR("Scott Alfter <scott@alfter.us>");
155 MODULE_DESCRIPTION("w1 family 12 driver for DS2406 2 Pin IO");
156 MODULE_LICENSE("GPL");