Blame view
drivers/hwmon/ntc_thermistor.c
14.3 KB
f22aaaa70 hwmon: Driver for... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
/* * ntc_thermistor.c - NTC Thermistors * * Copyright (C) 2010 Samsung Electronics * MyungJoo Ham <myungjoo.ham@samsung.com> * * This program is free software; you can redistribute it and/or modify * it under the terms 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/slab.h> #include <linux/module.h> #include <linux/pm_runtime.h> #include <linux/math64.h> #include <linux/platform_device.h> #include <linux/err.h> |
9e8269de1 hwmon: (ntc_therm... |
29 30 |
#include <linux/of.h> #include <linux/of_device.h> |
f22aaaa70 hwmon: Driver for... |
31 32 |
#include <linux/platform_data/ntc_thermistor.h> |
9e8269de1 hwmon: (ntc_therm... |
33 34 35 36 |
#include <linux/iio/iio.h> #include <linux/iio/machine.h> #include <linux/iio/driver.h> #include <linux/iio/consumer.h> |
f22aaaa70 hwmon: Driver for... |
37 38 39 40 |
#include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> struct ntc_compensation { |
088ce2ac9 hwmon: Fix CamelC... |
41 |
int temp_c; |
f22aaaa70 hwmon: Driver for... |
42 43 |
unsigned int ohm; }; |
9e8269de1 hwmon: (ntc_therm... |
44 45 46 47 48 49 50 51 |
static const struct platform_device_id ntc_thermistor_id[] = { { "ncp15wb473", TYPE_NCPXXWB473 }, { "ncp18wb473", TYPE_NCPXXWB473 }, { "ncp21wb473", TYPE_NCPXXWB473 }, { "ncp03wb473", TYPE_NCPXXWB473 }, { "ncp15wl333", TYPE_NCPXXWL333 }, { }, }; |
f22aaaa70 hwmon: Driver for... |
52 53 54 55 56 57 |
/* * A compensation table should be sorted by the values of .ohm * in descending order. * The following compensation tables are from the specification of Murata NTC * Thermistors Datasheet */ |
4626dcff7 hwmon: (ntc_therm... |
58 |
static const struct ntc_compensation ncpXXwb473[] = { |
088ce2ac9 hwmon: Fix CamelC... |
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
{ .temp_c = -40, .ohm = 1747920 }, { .temp_c = -35, .ohm = 1245428 }, { .temp_c = -30, .ohm = 898485 }, { .temp_c = -25, .ohm = 655802 }, { .temp_c = -20, .ohm = 483954 }, { .temp_c = -15, .ohm = 360850 }, { .temp_c = -10, .ohm = 271697 }, { .temp_c = -5, .ohm = 206463 }, { .temp_c = 0, .ohm = 158214 }, { .temp_c = 5, .ohm = 122259 }, { .temp_c = 10, .ohm = 95227 }, { .temp_c = 15, .ohm = 74730 }, { .temp_c = 20, .ohm = 59065 }, { .temp_c = 25, .ohm = 47000 }, { .temp_c = 30, .ohm = 37643 }, { .temp_c = 35, .ohm = 30334 }, { .temp_c = 40, .ohm = 24591 }, { .temp_c = 45, .ohm = 20048 }, { .temp_c = 50, .ohm = 16433 }, { .temp_c = 55, .ohm = 13539 }, { .temp_c = 60, .ohm = 11209 }, { .temp_c = 65, .ohm = 9328 }, { .temp_c = 70, .ohm = 7798 }, { .temp_c = 75, .ohm = 6544 }, { .temp_c = 80, .ohm = 5518 }, { .temp_c = 85, .ohm = 4674 }, { .temp_c = 90, .ohm = 3972 }, { .temp_c = 95, .ohm = 3388 }, { .temp_c = 100, .ohm = 2902 }, { .temp_c = 105, .ohm = 2494 }, { .temp_c = 110, .ohm = 2150 }, { .temp_c = 115, .ohm = 1860 }, { .temp_c = 120, .ohm = 1615 }, { .temp_c = 125, .ohm = 1406 }, |
f22aaaa70 hwmon: Driver for... |
93 |
}; |
4626dcff7 hwmon: (ntc_therm... |
94 |
static const struct ntc_compensation ncpXXwl333[] = { |
088ce2ac9 hwmon: Fix CamelC... |
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
{ .temp_c = -40, .ohm = 1610154 }, { .temp_c = -35, .ohm = 1130850 }, { .temp_c = -30, .ohm = 802609 }, { .temp_c = -25, .ohm = 575385 }, { .temp_c = -20, .ohm = 416464 }, { .temp_c = -15, .ohm = 304219 }, { .temp_c = -10, .ohm = 224193 }, { .temp_c = -5, .ohm = 166623 }, { .temp_c = 0, .ohm = 124850 }, { .temp_c = 5, .ohm = 94287 }, { .temp_c = 10, .ohm = 71747 }, { .temp_c = 15, .ohm = 54996 }, { .temp_c = 20, .ohm = 42455 }, { .temp_c = 25, .ohm = 33000 }, { .temp_c = 30, .ohm = 25822 }, { .temp_c = 35, .ohm = 20335 }, { .temp_c = 40, .ohm = 16115 }, { .temp_c = 45, .ohm = 12849 }, { .temp_c = 50, .ohm = 10306 }, { .temp_c = 55, .ohm = 8314 }, { .temp_c = 60, .ohm = 6746 }, { .temp_c = 65, .ohm = 5503 }, { .temp_c = 70, .ohm = 4513 }, { .temp_c = 75, .ohm = 3721 }, { .temp_c = 80, .ohm = 3084 }, { .temp_c = 85, .ohm = 2569 }, { .temp_c = 90, .ohm = 2151 }, { .temp_c = 95, .ohm = 1809 }, { .temp_c = 100, .ohm = 1529 }, { .temp_c = 105, .ohm = 1299 }, { .temp_c = 110, .ohm = 1108 }, { .temp_c = 115, .ohm = 949 }, { .temp_c = 120, .ohm = 817 }, { .temp_c = 125, .ohm = 707 }, |
f22aaaa70 hwmon: Driver for... |
129 130 131 132 133 134 135 136 137 138 |
}; struct ntc_data { struct device *hwmon_dev; struct ntc_thermistor_platform_data *pdata; const struct ntc_compensation *comp; struct device *dev; int n_comp; char name[PLATFORM_NAME_SIZE]; }; |
9e8269de1 hwmon: (ntc_therm... |
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
#ifdef CONFIG_OF static int ntc_adc_iio_read(struct ntc_thermistor_platform_data *pdata) { struct iio_channel *channel = pdata->chan; unsigned int result; int val, ret; ret = iio_read_channel_raw(channel, &val); if (ret < 0) { pr_err("read channel() error: %d ", ret); return ret; } /* unit: mV */ |
088ce2ac9 hwmon: Fix CamelC... |
154 |
result = pdata->pullup_uv * val; |
9e8269de1 hwmon: (ntc_therm... |
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
result >>= 12; return result; } static const struct of_device_id ntc_match[] = { { .compatible = "ntc,ncp15wb473", .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, { .compatible = "ntc,ncp18wb473", .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, { .compatible = "ntc,ncp21wb473", .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, { .compatible = "ntc,ncp03wb473", .data = &ntc_thermistor_id[TYPE_NCPXXWB473] }, { .compatible = "ntc,ncp15wl333", .data = &ntc_thermistor_id[TYPE_NCPXXWL333] }, { }, }; MODULE_DEVICE_TABLE(of, ntc_match); static struct ntc_thermistor_platform_data * ntc_thermistor_parse_dt(struct platform_device *pdev) { struct iio_channel *chan; struct device_node *np = pdev->dev.of_node; struct ntc_thermistor_platform_data *pdata; if (!np) return NULL; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return ERR_PTR(-ENOMEM); chan = iio_channel_get(&pdev->dev, NULL); if (IS_ERR(chan)) return ERR_CAST(chan); |
088ce2ac9 hwmon: Fix CamelC... |
192 |
if (of_property_read_u32(np, "pullup-uv", &pdata->pullup_uv)) |
9e8269de1 hwmon: (ntc_therm... |
193 194 195 196 197 198 199 200 201 202 203 204 |
return ERR_PTR(-ENODEV); if (of_property_read_u32(np, "pullup-ohm", &pdata->pullup_ohm)) return ERR_PTR(-ENODEV); if (of_property_read_u32(np, "pulldown-ohm", &pdata->pulldown_ohm)) return ERR_PTR(-ENODEV); if (of_find_property(np, "connected-positive", NULL)) pdata->connect = NTC_CONNECTED_POSITIVE; else /* status change should be possible if not always on. */ pdata->connect = NTC_CONNECTED_GROUND; pdata->chan = chan; |
088ce2ac9 hwmon: Fix CamelC... |
205 |
pdata->read_uv = ntc_adc_iio_read; |
9e8269de1 hwmon: (ntc_therm... |
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
return pdata; } static void ntc_iio_channel_release(struct ntc_thermistor_platform_data *pdata) { if (pdata->chan) iio_channel_release(pdata->chan); } #else static struct ntc_thermistor_platform_data * ntc_thermistor_parse_dt(struct platform_device *pdev) { return NULL; } static void ntc_iio_channel_release(struct ntc_thermistor_platform_data *pdata) { } #endif |
f22aaaa70 hwmon: Driver for... |
224 225 226 227 228 229 230 231 |
static inline u64 div64_u64_safe(u64 dividend, u64 divisor) { if (divisor == 0 && dividend == 0) return 0; if (divisor == 0) return UINT_MAX; return div64_u64(dividend, divisor); } |
088ce2ac9 hwmon: Fix CamelC... |
232 |
static int get_ohm_of_thermistor(struct ntc_data *data, unsigned int uv) |
f22aaaa70 hwmon: Driver for... |
233 234 |
{ struct ntc_thermistor_platform_data *pdata = data->pdata; |
088ce2ac9 hwmon: Fix CamelC... |
235 236 237 238 239 |
u64 mv = uv / 1000; u64 pmv = pdata->pullup_uv / 1000; u64 n, puo, pdo; puo = pdata->pullup_ohm; pdo = pdata->pulldown_ohm; |
f22aaaa70 hwmon: Driver for... |
240 |
|
088ce2ac9 hwmon: Fix CamelC... |
241 |
if (mv == 0) { |
f22aaaa70 hwmon: Driver for... |
242 |
if (pdata->connect == NTC_CONNECTED_POSITIVE) |
dbe43a627 hwmon: (ntc_therm... |
243 |
return INT_MAX; |
f22aaaa70 hwmon: Driver for... |
244 245 |
return 0; } |
088ce2ac9 hwmon: Fix CamelC... |
246 |
if (mv >= pmv) |
f22aaaa70 hwmon: Driver for... |
247 |
return (pdata->connect == NTC_CONNECTED_POSITIVE) ? |
dbe43a627 hwmon: (ntc_therm... |
248 |
0 : INT_MAX; |
f22aaaa70 hwmon: Driver for... |
249 |
|
088ce2ac9 hwmon: Fix CamelC... |
250 251 252 253 |
if (pdata->connect == NTC_CONNECTED_POSITIVE && puo == 0) n = div64_u64_safe(pdo * (pmv - mv), mv); else if (pdata->connect == NTC_CONNECTED_GROUND && pdo == 0) n = div64_u64_safe(puo * mv, pmv - mv); |
f22aaaa70 hwmon: Driver for... |
254 |
else if (pdata->connect == NTC_CONNECTED_POSITIVE) |
088ce2ac9 hwmon: Fix CamelC... |
255 256 |
n = div64_u64_safe(pdo * puo * (pmv - mv), puo * mv - pdo * (pmv - mv)); |
f22aaaa70 hwmon: Driver for... |
257 |
else |
088ce2ac9 hwmon: Fix CamelC... |
258 |
n = div64_u64_safe(pdo * puo * mv, pdo * (pmv - mv) - puo * mv); |
f22aaaa70 hwmon: Driver for... |
259 |
|
088ce2ac9 hwmon: Fix CamelC... |
260 261 262 |
if (n > INT_MAX) n = INT_MAX; return n; |
f22aaaa70 hwmon: Driver for... |
263 |
} |
dbe43a627 hwmon: (ntc_therm... |
264 265 |
static void lookup_comp(struct ntc_data *data, unsigned int ohm, int *i_low, int *i_high) |
f22aaaa70 hwmon: Driver for... |
266 |
{ |
dbe43a627 hwmon: (ntc_therm... |
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
int start, end, mid; /* * Handle special cases: Resistance is higher than or equal to * resistance in first table entry, or resistance is lower or equal * to resistance in last table entry. * In these cases, return i_low == i_high, either pointing to the * beginning or to the end of the table depending on the condition. */ if (ohm >= data->comp[0].ohm) { *i_low = 0; *i_high = 0; return; } if (ohm <= data->comp[data->n_comp - 1].ohm) { *i_low = data->n_comp - 1; *i_high = data->n_comp - 1; return; } |
f22aaaa70 hwmon: Driver for... |
286 287 288 289 |
/* Do a binary search on compensation table */ start = 0; end = data->n_comp; |
dbe43a627 hwmon: (ntc_therm... |
290 |
while (start < end) { |
f22aaaa70 hwmon: Driver for... |
291 |
mid = start + (end - start) / 2; |
dbe43a627 hwmon: (ntc_therm... |
292 293 294 295 296 297 298 299 300 301 |
/* * start <= mid < end * data->comp[start].ohm > ohm >= data->comp[end].ohm * * We could check for "ohm == data->comp[mid].ohm" here, but * that is a quite unlikely condition, and we would have to * check again after updating start. Check it at the end instead * for simplicity. */ if (ohm >= data->comp[mid].ohm) { |
f22aaaa70 hwmon: Driver for... |
302 |
end = mid; |
f22aaaa70 hwmon: Driver for... |
303 |
} else { |
dbe43a627 hwmon: (ntc_therm... |
304 305 306 307 308 309 310 311 312 |
start = mid + 1; /* * ohm >= data->comp[start].ohm might be true here, * since we set start to mid + 1. In that case, we are * done. We could keep going, but the condition is quite * likely to occur, so it is worth checking for it. */ if (ohm >= data->comp[start].ohm) end = start; |
f22aaaa70 hwmon: Driver for... |
313 |
} |
dbe43a627 hwmon: (ntc_therm... |
314 315 316 317 |
/* * start <= end * data->comp[start].ohm >= ohm >= data->comp[end].ohm */ |
f22aaaa70 hwmon: Driver for... |
318 |
} |
dbe43a627 hwmon: (ntc_therm... |
319 320 321 322 323 324 325 326 327 |
/* * start == end * ohm >= data->comp[end].ohm */ *i_low = end; if (ohm == data->comp[end].ohm) *i_high = end; else *i_high = end - 1; |
f22aaaa70 hwmon: Driver for... |
328 |
} |
088ce2ac9 hwmon: Fix CamelC... |
329 |
static int get_temp_mc(struct ntc_data *data, unsigned int ohm) |
f22aaaa70 hwmon: Driver for... |
330 331 |
{ int low, high; |
dbe43a627 hwmon: (ntc_therm... |
332 |
int temp; |
f22aaaa70 hwmon: Driver for... |
333 |
|
dbe43a627 hwmon: (ntc_therm... |
334 335 |
lookup_comp(data, ohm, &low, &high); if (low == high) { |
f22aaaa70 hwmon: Driver for... |
336 |
/* Unable to use linear approximation */ |
088ce2ac9 hwmon: Fix CamelC... |
337 |
temp = data->comp[low].temp_c * 1000; |
f22aaaa70 hwmon: Driver for... |
338 |
} else { |
088ce2ac9 hwmon: Fix CamelC... |
339 340 |
temp = data->comp[low].temp_c * 1000 + ((data->comp[high].temp_c - data->comp[low].temp_c) * |
f22aaaa70 hwmon: Driver for... |
341 342 343 |
1000 * ((int)ohm - (int)data->comp[low].ohm)) / ((int)data->comp[high].ohm - (int)data->comp[low].ohm); } |
dbe43a627 hwmon: (ntc_therm... |
344 |
return temp; |
f22aaaa70 hwmon: Driver for... |
345 |
} |
dbe43a627 hwmon: (ntc_therm... |
346 |
static int ntc_thermistor_get_ohm(struct ntc_data *data) |
f22aaaa70 hwmon: Driver for... |
347 |
{ |
088ce2ac9 hwmon: Fix CamelC... |
348 |
int read_uv; |
f22aaaa70 hwmon: Driver for... |
349 |
|
dbe43a627 hwmon: (ntc_therm... |
350 351 |
if (data->pdata->read_ohm) return data->pdata->read_ohm(); |
f22aaaa70 hwmon: Driver for... |
352 |
|
088ce2ac9 hwmon: Fix CamelC... |
353 354 355 356 357 |
if (data->pdata->read_uv) { read_uv = data->pdata->read_uv(data->pdata); if (read_uv < 0) return read_uv; return get_ohm_of_thermistor(data, read_uv); |
f22aaaa70 hwmon: Driver for... |
358 |
} |
dbe43a627 hwmon: (ntc_therm... |
359 |
return -EINVAL; |
f22aaaa70 hwmon: Driver for... |
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 |
} static ssize_t ntc_show_name(struct device *dev, struct device_attribute *attr, char *buf) { struct ntc_data *data = dev_get_drvdata(dev); return sprintf(buf, "%s ", data->name); } static ssize_t ntc_show_type(struct device *dev, struct device_attribute *attr, char *buf) { return sprintf(buf, "4 "); } static ssize_t ntc_show_temp(struct device *dev, struct device_attribute *attr, char *buf) { struct ntc_data *data = dev_get_drvdata(dev); |
dbe43a627 hwmon: (ntc_therm... |
382 383 384 385 386 |
int ohm; ohm = ntc_thermistor_get_ohm(data); if (ohm < 0) return ohm; |
f22aaaa70 hwmon: Driver for... |
387 |
|
088ce2ac9 hwmon: Fix CamelC... |
388 389 |
return sprintf(buf, "%d ", get_temp_mc(data, ohm)); |
f22aaaa70 hwmon: Driver for... |
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 |
} static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO, ntc_show_type, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ntc_show_temp, NULL, 0); static DEVICE_ATTR(name, S_IRUGO, ntc_show_name, NULL); static struct attribute *ntc_attributes[] = { &dev_attr_name.attr, &sensor_dev_attr_temp1_type.dev_attr.attr, &sensor_dev_attr_temp1_input.dev_attr.attr, NULL, }; static const struct attribute_group ntc_attr_group = { .attrs = ntc_attributes, }; |
6c931ae1c hwmon: remove use... |
406 |
static int ntc_thermistor_probe(struct platform_device *pdev) |
f22aaaa70 hwmon: Driver for... |
407 |
{ |
9e8269de1 hwmon: (ntc_therm... |
408 409 410 411 |
const struct of_device_id *of_id = of_match_device(of_match_ptr(ntc_match), &pdev->dev); const struct platform_device_id *pdev_id; struct ntc_thermistor_platform_data *pdata; |
f22aaaa70 hwmon: Driver for... |
412 |
struct ntc_data *data; |
9e8269de1 hwmon: (ntc_therm... |
413 414 415 416 417 418 419 |
int ret; pdata = ntc_thermistor_parse_dt(pdev); if (IS_ERR(pdata)) return PTR_ERR(pdata); else if (pdata == NULL) pdata = pdev->dev.platform_data; |
f22aaaa70 hwmon: Driver for... |
420 421 422 423 424 425 426 427 |
if (!pdata) { dev_err(&pdev->dev, "No platform init data supplied. "); return -ENODEV; } /* Either one of the two is required. */ |
088ce2ac9 hwmon: Fix CamelC... |
428 |
if (!pdata->read_uv && !pdata->read_ohm) { |
a7871def6 hwmon: (ntc_therm... |
429 |
dev_err(&pdev->dev, |
088ce2ac9 hwmon: Fix CamelC... |
430 431 |
"Both read_uv and read_ohm missing. Need either one of the two. "); |
f22aaaa70 hwmon: Driver for... |
432 433 |
return -EINVAL; } |
088ce2ac9 hwmon: Fix CamelC... |
434 |
if (pdata->read_uv && pdata->read_ohm) { |
a7871def6 hwmon: (ntc_therm... |
435 |
dev_warn(&pdev->dev, |
088ce2ac9 hwmon: Fix CamelC... |
436 437 438 |
"Only one of read_uv and read_ohm is needed; ignoring read_uv. "); pdata->read_uv = NULL; |
f22aaaa70 hwmon: Driver for... |
439 |
} |
088ce2ac9 hwmon: Fix CamelC... |
440 |
if (pdata->read_uv && (pdata->pullup_uv == 0 || |
f22aaaa70 hwmon: Driver for... |
441 442 443 444 445 446 |
(pdata->pullup_ohm == 0 && pdata->connect == NTC_CONNECTED_GROUND) || (pdata->pulldown_ohm == 0 && pdata->connect == NTC_CONNECTED_POSITIVE) || (pdata->connect != NTC_CONNECTED_POSITIVE && pdata->connect != NTC_CONNECTED_GROUND))) { |
a7871def6 hwmon: (ntc_therm... |
447 |
dev_err(&pdev->dev, |
088ce2ac9 hwmon: Fix CamelC... |
448 449 |
"Required data to use read_uv not supplied. "); |
f22aaaa70 hwmon: Driver for... |
450 451 |
return -EINVAL; } |
41141e64e hwmon: (ntc_therm... |
452 |
data = devm_kzalloc(&pdev->dev, sizeof(struct ntc_data), GFP_KERNEL); |
f22aaaa70 hwmon: Driver for... |
453 454 |
if (!data) return -ENOMEM; |
9e8269de1 hwmon: (ntc_therm... |
455 |
pdev_id = of_id ? of_id->data : platform_get_device_id(pdev); |
f22aaaa70 hwmon: Driver for... |
456 457 |
data->dev = &pdev->dev; data->pdata = pdata; |
9e8269de1 hwmon: (ntc_therm... |
458 |
strlcpy(data->name, pdev_id->name, sizeof(data->name)); |
f22aaaa70 hwmon: Driver for... |
459 |
|
9e8269de1 hwmon: (ntc_therm... |
460 |
switch (pdev_id->driver_data) { |
f22aaaa70 hwmon: Driver for... |
461 462 463 464 465 466 467 468 469 470 471 |
case TYPE_NCPXXWB473: data->comp = ncpXXwb473; data->n_comp = ARRAY_SIZE(ncpXXwb473); break; case TYPE_NCPXXWL333: data->comp = ncpXXwl333; data->n_comp = ARRAY_SIZE(ncpXXwl333); break; default: dev_err(&pdev->dev, "Unknown device type: %lu(%s) ", |
9e8269de1 hwmon: (ntc_therm... |
472 |
pdev_id->driver_data, pdev_id->name); |
41141e64e hwmon: (ntc_therm... |
473 |
return -EINVAL; |
f22aaaa70 hwmon: Driver for... |
474 475 476 477 478 479 480 481 |
} platform_set_drvdata(pdev, data); ret = sysfs_create_group(&data->dev->kobj, &ntc_attr_group); if (ret) { dev_err(data->dev, "unable to create sysfs files "); |
41141e64e hwmon: (ntc_therm... |
482 |
return ret; |
f22aaaa70 hwmon: Driver for... |
483 484 485 |
} data->hwmon_dev = hwmon_device_register(data->dev); |
425d24768 hwmon: (ntc_therm... |
486 |
if (IS_ERR(data->hwmon_dev)) { |
f22aaaa70 hwmon: Driver for... |
487 488 |
dev_err(data->dev, "unable to register as hwmon device. "); |
425d24768 hwmon: (ntc_therm... |
489 |
ret = PTR_ERR(data->hwmon_dev); |
f22aaaa70 hwmon: Driver for... |
490 491 |
goto err_after_sysfs; } |
9e8269de1 hwmon: (ntc_therm... |
492 493 494 |
dev_info(&pdev->dev, "Thermistor type: %s successfully probed. ", pdev->name); |
f22aaaa70 hwmon: Driver for... |
495 496 497 |
return 0; err_after_sysfs: sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); |
9e8269de1 hwmon: (ntc_therm... |
498 |
ntc_iio_channel_release(pdata); |
f22aaaa70 hwmon: Driver for... |
499 500 |
return ret; } |
281dfd0b6 hwmon: remove use... |
501 |
static int ntc_thermistor_remove(struct platform_device *pdev) |
f22aaaa70 hwmon: Driver for... |
502 503 |
{ struct ntc_data *data = platform_get_drvdata(pdev); |
9e8269de1 hwmon: (ntc_therm... |
504 |
struct ntc_thermistor_platform_data *pdata = data->pdata; |
f22aaaa70 hwmon: Driver for... |
505 506 507 |
hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&data->dev->kobj, &ntc_attr_group); |
9e8269de1 hwmon: (ntc_therm... |
508 |
ntc_iio_channel_release(pdata); |
f22aaaa70 hwmon: Driver for... |
509 |
platform_set_drvdata(pdev, NULL); |
f22aaaa70 hwmon: Driver for... |
510 511 |
return 0; } |
f22aaaa70 hwmon: Driver for... |
512 513 514 515 |
static struct platform_driver ntc_thermistor_driver = { .driver = { .name = "ntc-thermistor", .owner = THIS_MODULE, |
9e8269de1 hwmon: (ntc_therm... |
516 |
.of_match_table = of_match_ptr(ntc_match), |
f22aaaa70 hwmon: Driver for... |
517 518 |
}, .probe = ntc_thermistor_probe, |
9e5e9b7a9 hwmon: remove use... |
519 |
.remove = ntc_thermistor_remove, |
f22aaaa70 hwmon: Driver for... |
520 521 |
.id_table = ntc_thermistor_id, }; |
25a236a5d hwmon: convert dr... |
522 |
module_platform_driver(ntc_thermistor_driver); |
f22aaaa70 hwmon: Driver for... |
523 524 525 526 527 |
MODULE_DESCRIPTION("NTC Thermistor Driver"); MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:ntc-thermistor"); |