aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1/w1_therm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/w1/w1_therm.c')
-rw-r--r--drivers/w1/w1_therm.c92
1 files changed, 82 insertions, 10 deletions
diff --git a/drivers/w1/w1_therm.c b/drivers/w1/w1_therm.c
index 70310f7a722e..84e8043a4499 100644
--- a/drivers/w1/w1_therm.c
+++ b/drivers/w1/w1_therm.c
@@ -53,6 +53,50 @@ static struct w1_family_ops w1_therm_fops = {
53 .rvalname = "temp1_input", 53 .rvalname = "temp1_input",
54}; 54};
55 55
56static struct w1_family w1_therm_family_DS18S20 = {
57 .fid = W1_THERM_DS18S20,
58 .fops = &w1_therm_fops,
59};
60
61static struct w1_family w1_therm_family_DS18B20 = {
62 .fid = W1_THERM_DS18B20,
63 .fops = &w1_therm_fops,
64};
65static struct w1_family w1_therm_family_DS1822 = {
66 .fid = W1_THERM_DS1822,
67 .fops = &w1_therm_fops,
68};
69
70struct w1_therm_family_converter
71{
72 u8 fid;
73 u8 broken;
74 u16 reserved;
75 struct w1_family *f;
76 int (*convert)(u8 rom[9]);
77};
78
79static inline int w1_DS18B20_convert_temp(u8 rom[9]);
80static inline int w1_DS18S20_convert_temp(u8 rom[9]);
81
82static struct w1_therm_family_converter w1_therm_families[] = {
83 {
84 .fid = W1_THERM_DS18S20,
85 .f = &w1_therm_family_DS18S20,
86 .convert = w1_DS18S20_convert_temp
87 },
88 {
89 .fid = W1_THERM_DS1822,
90 .f = &w1_therm_family_DS1822,
91 .convert = w1_DS18B20_convert_temp
92 },
93 {
94 .fid = W1_THERM_DS18B20,
95 .f = &w1_therm_family_DS18B20,
96 .convert = w1_DS18B20_convert_temp
97 },
98};
99
56static ssize_t w1_therm_read_name(struct device *dev, struct device_attribute *attr, char *buf) 100static ssize_t w1_therm_read_name(struct device *dev, struct device_attribute *attr, char *buf)
57{ 101{
58 struct w1_slave *sl = container_of(dev, struct w1_slave, dev); 102 struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
@@ -60,9 +104,19 @@ static ssize_t w1_therm_read_name(struct device *dev, struct device_attribute *a
60 return sprintf(buf, "%s\n", sl->name); 104 return sprintf(buf, "%s\n", sl->name);
61} 105}
62 106
63static inline int w1_convert_temp(u8 rom[9]) 107static inline int w1_DS18B20_convert_temp(u8 rom[9])
108{
109 int t = (rom[1] << 8) | rom[0];
110 t /= 16;
111 return t;
112}
113
114static inline int w1_DS18S20_convert_temp(u8 rom[9])
64{ 115{
65 int t, h; 116 int t, h;
117
118 if (!rom[7])
119 return 0;
66 120
67 if (rom[1] == 0) 121 if (rom[1] == 0)
68 t = ((s32)rom[0] >> 1)*1000; 122 t = ((s32)rom[0] >> 1)*1000;
@@ -77,11 +131,22 @@ static inline int w1_convert_temp(u8 rom[9])
77 return t; 131 return t;
78} 132}
79 133
134static inline int w1_convert_temp(u8 rom[9], u8 fid)
135{
136 int i;
137
138 for (i=0; i<sizeof(w1_therm_families)/sizeof(w1_therm_families[0]); ++i)
139 if (w1_therm_families[i].fid == fid)
140 return w1_therm_families[i].convert(rom);
141
142 return 0;
143}
144
80static ssize_t w1_therm_read_temp(struct device *dev, struct device_attribute *attr, char *buf) 145static ssize_t w1_therm_read_temp(struct device *dev, struct device_attribute *attr, char *buf)
81{ 146{
82 struct w1_slave *sl = container_of(dev, struct w1_slave, dev); 147 struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
83 148
84 return sprintf(buf, "%d\n", w1_convert_temp(sl->rom)); 149 return sprintf(buf, "%d\n", w1_convert_temp(sl->rom, sl->family->fid));
85} 150}
86 151
87static int w1_therm_check_rom(u8 rom[9]) 152static int w1_therm_check_rom(u8 rom[9])
@@ -176,7 +241,7 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, si
176 for (i = 0; i < 9; ++i) 241 for (i = 0; i < 9; ++i)
177 count += sprintf(buf + count, "%02x ", sl->rom[i]); 242 count += sprintf(buf + count, "%02x ", sl->rom[i]);
178 243
179 count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom)); 244 count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom, sl->family->fid));
180out: 245out:
181 up(&dev->mutex); 246 up(&dev->mutex);
182out_dec: 247out_dec:
@@ -186,19 +251,26 @@ out_dec:
186 return count; 251 return count;
187} 252}
188 253
189static struct w1_family w1_therm_family = {
190 .fid = W1_FAMILY_THERM,
191 .fops = &w1_therm_fops,
192};
193
194static int __init w1_therm_init(void) 254static int __init w1_therm_init(void)
195{ 255{
196 return w1_register_family(&w1_therm_family); 256 int err, i;
257
258 for (i=0; i<sizeof(w1_therm_families)/sizeof(w1_therm_families[0]); ++i) {
259 err = w1_register_family(w1_therm_families[i].f);
260 if (err)
261 w1_therm_families[i].broken = 1;
262 }
263
264 return 0;
197} 265}
198 266
199static void __exit w1_therm_fini(void) 267static void __exit w1_therm_fini(void)
200{ 268{
201 w1_unregister_family(&w1_therm_family); 269 int i;
270
271 for (i=0; i<sizeof(w1_therm_families)/sizeof(w1_therm_families[0]); ++i)
272 if (!w1_therm_families[i].broken)
273 w1_unregister_family(w1_therm_families[i].f);
202} 274}
203 275
204module_init(w1_therm_init); 276module_init(w1_therm_init);