PCI: hotplug: Embed hotplug_slot
[linux/fpc-iii.git] / drivers / w1 / slaves / w1_ds2406.c
blobfac266366ca398bcaaeaeb1208546d89dfbcceae
1 /*
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.
9 */
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>
20 #include <linux/w1.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);
34 u16 crc=0;
35 int i;
36 ssize_t rtnval=1;
38 if (off != 0)
39 return 0;
40 if (!buf)
41 return -EINVAL;
43 mutex_lock(&sl->master->bus_mutex);
45 if (w1_reset_select_slave(sl)) {
46 mutex_unlock(&sl->master->bus_mutex);
47 return -EIO;
50 w1_write_block(sl->master, w1_buf, 3);
51 w1_read_block(sl->master, w1_buf+3, 3);
52 for (i=0; i<6; i++)
53 crc=crc16_byte(crc, w1_buf[i]);
54 if (crc==0xb001) /* good read? */
55 *buf=((w1_buf[3]>>5)&3)|0x30;
56 else
57 rtnval=-EIO;
59 mutex_unlock(&sl->master->bus_mutex);
61 return rtnval;
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};
71 u16 crc=0;
72 int i;
73 ssize_t rtnval=1;
75 if (count != 1 || off != 0)
76 return -EFAULT;
78 mutex_lock(&sl->master->bus_mutex);
80 if (w1_reset_select_slave(sl)) {
81 mutex_unlock(&sl->master->bus_mutex);
82 return -EIO;
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);
88 for (i=0; i<6; i++)
89 crc=crc16_byte(crc, w1_buf[i]);
90 if (crc==0xb001) /* good read? */
91 w1_write_8(sl->master, 0xFF);
92 else
93 rtnval=-EIO;
95 mutex_unlock(&sl->master->bus_mutex);
96 return rtnval;
99 #define NB_SYSFS_BIN_FILES 2
100 static struct bin_attribute w1_f12_sysfs_bin_files[NB_SYSFS_BIN_FILES] = {
102 .attr = {
103 .name = "state",
104 .mode = S_IRUGO,
106 .size = 1,
107 .read = w1_f12_read_state,
110 .attr = {
111 .name = "output",
112 .mode = S_IRUGO | S_IWUSR | S_IWGRP,
114 .size = 1,
115 .write = w1_f12_write_output,
119 static int w1_f12_add_slave(struct w1_slave *sl)
121 int err = 0;
122 int i;
124 for (i = 0; i < NB_SYSFS_BIN_FILES && !err; ++i)
125 err = sysfs_create_bin_file(
126 &sl->dev.kobj,
127 &(w1_f12_sysfs_bin_files[i]));
128 if (err)
129 while (--i >= 0)
130 sysfs_remove_bin_file(&sl->dev.kobj,
131 &(w1_f12_sysfs_bin_files[i]));
132 return err;
135 static void w1_f12_remove_slave(struct w1_slave *sl)
137 int i;
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");