summaryrefslogtreecommitdiff
path: root/drivers/hwmon/ntc_thermistor.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/ntc_thermistor.c')
-rw-r--r--drivers/hwmon/ntc_thermistor.c91
1 files changed, 71 insertions, 20 deletions
diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c
index 112e4d45e4a0..dc0b76c5e302 100644
--- a/drivers/hwmon/ntc_thermistor.c
+++ b/drivers/hwmon/ntc_thermistor.c
@@ -53,6 +53,7 @@ static const struct platform_device_id ntc_thermistor_id[] = {
{ "ncp03wb473", TYPE_NCPXXWB473 },
{ "ncp15wl333", TYPE_NCPXXWL333 },
{ "b57330v2103", TYPE_B57330V2103},
+ { "ncp03wf104", TYPE_NCPXXWF104 },
{ },
};
@@ -135,6 +136,43 @@ static const struct ntc_compensation ncpXXwl333[] = {
{ .temp_c = 125, .ohm = 707 },
};
+static const struct ntc_compensation ncpXXwf104[] = {
+ { .temp_c = -40, .ohm = 4397119 },
+ { .temp_c = -35, .ohm = 3088599 },
+ { .temp_c = -30, .ohm = 2197225 },
+ { .temp_c = -25, .ohm = 1581881 },
+ { .temp_c = -20, .ohm = 1151037 },
+ { .temp_c = -15, .ohm = 846579 },
+ { .temp_c = -10, .ohm = 628988 },
+ { .temp_c = -5, .ohm = 471632 },
+ { .temp_c = 0, .ohm = 357012 },
+ { .temp_c = 5, .ohm = 272500 },
+ { .temp_c = 10, .ohm = 209710 },
+ { .temp_c = 15, .ohm = 162651 },
+ { .temp_c = 20, .ohm = 127080 },
+ { .temp_c = 25, .ohm = 100000 },
+ { .temp_c = 30, .ohm = 79222 },
+ { .temp_c = 35, .ohm = 63167 },
+ { .temp_c = 40, .ohm = 50677 },
+ { .temp_c = 45, .ohm = 40904 },
+ { .temp_c = 50, .ohm = 33195 },
+ { .temp_c = 55, .ohm = 27091 },
+ { .temp_c = 60, .ohm = 22224 },
+ { .temp_c = 65, .ohm = 18323 },
+ { .temp_c = 70, .ohm = 15184 },
+ { .temp_c = 75, .ohm = 12635 },
+ { .temp_c = 80, .ohm = 10566 },
+ { .temp_c = 85, .ohm = 8873 },
+ { .temp_c = 90, .ohm = 7481 },
+ { .temp_c = 95, .ohm = 6337 },
+ { .temp_c = 100, .ohm = 5384 },
+ { .temp_c = 105, .ohm = 4594 },
+ { .temp_c = 110, .ohm = 3934 },
+ { .temp_c = 115, .ohm = 3380 },
+ { .temp_c = 120, .ohm = 2916 },
+ { .temp_c = 125, .ohm = 2522 },
+};
+
/*
* The following compensation table is from the specification of EPCOS NTC
* Thermistors Datasheet
@@ -190,20 +228,21 @@ struct ntc_data {
static int ntc_adc_iio_read(struct ntc_thermistor_platform_data *pdata)
{
struct iio_channel *channel = pdata->chan;
- s64 result;
- int val, ret;
+ int raw, uv, ret;
- ret = iio_read_channel_raw(channel, &val);
+ ret = iio_read_channel_raw(channel, &raw);
if (ret < 0) {
pr_err("read channel() error: %d\n", ret);
return ret;
}
- /* unit: mV */
- result = pdata->pullup_uv * (s64) val;
- result >>= 12;
+ ret = iio_convert_raw_to_processed(channel, raw, &uv, 1000);
+ if (ret < 0) {
+ /* Assume 12 bit ADC with vref at pullup_uv */
+ uv = (pdata->pullup_uv * (s64)raw) >> 12;
+ }
- return (int)result;
+ return uv;
}
static const struct of_device_id ntc_match[] = {
@@ -219,6 +258,8 @@ static const struct of_device_id ntc_match[] = {
.data = &ntc_thermistor_id[4] },
{ .compatible = "epcos,b57330v2103",
.data = &ntc_thermistor_id[5]},
+ { .compatible = "murata,ncp03wf104",
+ .data = &ntc_thermistor_id[6] },
/* Usage of vendor name "ntc" is deprecated */
{ .compatible = "ntc,ncp15wb473",
@@ -239,8 +280,10 @@ static struct ntc_thermistor_platform_data *
ntc_thermistor_parse_dt(struct platform_device *pdev)
{
struct iio_channel *chan;
+ enum iio_chan_type type;
struct device_node *np = pdev->dev.of_node;
struct ntc_thermistor_platform_data *pdata;
+ int ret;
if (!np)
return NULL;
@@ -253,6 +296,13 @@ ntc_thermistor_parse_dt(struct platform_device *pdev)
if (IS_ERR(chan))
return ERR_CAST(chan);
+ ret = iio_get_channel_type(chan, &type);
+ if (ret < 0)
+ return ERR_PTR(ret);
+
+ if (type != IIO_VOLTAGE)
+ return ERR_PTR(-EINVAL);
+
if (of_property_read_u32(np, "pullup-uv", &pdata->pullup_uv))
return ERR_PTR(-ENODEV);
if (of_property_read_u32(np, "pullup-ohm", &pdata->pullup_ohm))
@@ -300,30 +350,27 @@ static inline u64 div64_u64_safe(u64 dividend, u64 divisor)
static int get_ohm_of_thermistor(struct ntc_data *data, unsigned int uv)
{
struct ntc_thermistor_platform_data *pdata = data->pdata;
- u64 mv = uv / 1000;
- u64 pmv = pdata->pullup_uv / 1000;
+ u32 puv = pdata->pullup_uv;
u64 n, puo, pdo;
puo = pdata->pullup_ohm;
pdo = pdata->pulldown_ohm;
- if (mv == 0) {
- if (pdata->connect == NTC_CONNECTED_POSITIVE)
- return INT_MAX;
- return 0;
- }
- if (mv >= pmv)
+ if (uv == 0)
+ return (pdata->connect == NTC_CONNECTED_POSITIVE) ?
+ INT_MAX : 0;
+ if (uv >= puv)
return (pdata->connect == NTC_CONNECTED_POSITIVE) ?
0 : INT_MAX;
if (pdata->connect == NTC_CONNECTED_POSITIVE && puo == 0)
- n = div64_u64_safe(pdo * (pmv - mv), mv);
+ n = div_u64(pdo * (puv - uv), uv);
else if (pdata->connect == NTC_CONNECTED_GROUND && pdo == 0)
- n = div64_u64_safe(puo * mv, pmv - mv);
+ n = div_u64(puo * uv, puv - uv);
else if (pdata->connect == NTC_CONNECTED_POSITIVE)
- n = div64_u64_safe(pdo * puo * (pmv - mv),
- puo * mv - pdo * (pmv - mv));
+ n = div64_u64_safe(pdo * puo * (puv - uv),
+ puo * uv - pdo * (puv - uv));
else
- n = div64_u64_safe(pdo * puo * mv, pdo * (pmv - mv) - puo * mv);
+ n = div64_u64_safe(pdo * puo * uv, pdo * (puv - uv) - puo * uv);
if (n > INT_MAX)
n = INT_MAX;
@@ -558,6 +605,10 @@ static int ntc_thermistor_probe(struct platform_device *pdev)
data->comp = b57330v2103;
data->n_comp = ARRAY_SIZE(b57330v2103);
break;
+ case TYPE_NCPXXWF104:
+ data->comp = ncpXXwf104;
+ data->n_comp = ARRAY_SIZE(ncpXXwf104);
+ break;
default:
dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n",
pdev_id->driver_data, pdev_id->name);