hwmon changes for v4.2
- New driver for Microchip TC74 - Support for ncpXXwf104 added to ntc_thermistor driver - Minor cleanup -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJViAvaAAoJEMsfJm/On5mBr2UP/jAuFjcIwyEeTIRaDjSyqPCm y/wEGGIBhXg3VEbOnGLz7lrJvnZiQ4Ma7dPrY9QJmaY2l0mPmDLcc6iwQ0vl+pnS uCP2g5q5w0C8uvaqHvY6oN75uMgS6TpJBfnHKtGVE1xf7+HmQ/tLHOIP/DTXBWjs p/f0AQiwfjt2nepaI+Lemqasw3rLtgO6Ne2w3gDK//g35elgBcdCst+xPv9o5YdW SBoyde6OzBVmqOgf2svzlWwK/hLTEUYVBSTMs1UpzJE/M6HWaPoAbjLkuDNWMwE7 V1HhV6kwpuf+WHyJbPDV0rQLseKpDHQGFGwb3pu7f7oVmOKlKBrymesiHooit+9i s23wzB5Kezikyskcd4rC2CWBIyd6r43ngkuyJYyOfqKEkYmBuhQIpfkdtc4wFPce TTWdUOBOFAvhKRMYXMTgPvVkBuCkp/6LI/8UIj08LdMStQwkg0Ehg6xZha6UWZQf 0cUPoTiUjfiuWlYr3g2siTSKMOQXX4eOU8ywloelr8NORQexk9d3Bihl8B/npRcm prriEUVrriNGFgwEpwK4DrdKhMUAZnjV3ZUGtD43XXmSHkNfmdBCOQqW5NO9t03l /JLtc3tnaMNmv7TeOiAxhxQWUppFq5JRfJ6DO33yl5Ij98M9rL9rmDa2tz6+nVy1 67ufV9zu4cRYkMIqQVrQ =ZKHZ -----END PGP SIGNATURE----- Merge tag 'hwmon-for-linus-v4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging Pull hwmon updates from Guenter Roeck: - new driver for Microchip TC74 - support for ncpXXwf104 added to ntc_thermistor driver - minor cleanup * tag 'hwmon-for-linus-v4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: hwmon: add driver for Microchip TC74 hwmon: (ntc_thermistor) Improve precision of resistance calculation hwmon: (ntc_thermistor) fix iio raw to microvolts conversion hwmon: (atxp1) Drop auto-detection hwmon: (atxp1) Drop FSF mailing address hwmon: Allow compile test of GPIO consumers if !GPIOLIB hwmon: (sht15) Constify platform_device_id hwmon: (max197) Constify platform_device_id hwmon: (ntc_thermistor) Add support for ncpXXwf104
This commit is contained in:
commit
234a56c80a
|
@ -9,6 +9,7 @@ Requires node properties:
|
|||
"murata,ncp21wb473"
|
||||
"murata,ncp03wb473"
|
||||
"murata,ncp15wl333"
|
||||
"murata,ncp03wf104"
|
||||
|
||||
/* Usage of vendor name "ntc" is deprecated */
|
||||
<DEPRECATED> "ntc,ncp15wb473"
|
||||
|
|
|
@ -2,8 +2,10 @@ Kernel driver ntc_thermistor
|
|||
=================
|
||||
|
||||
Supported thermistors from Murata:
|
||||
* Murata NTC Thermistors NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473, NCP15WL333
|
||||
Prefixes: 'ncp15wb473', 'ncp18wb473', 'ncp21wb473', 'ncp03wb473', 'ncp15wl333'
|
||||
* Murata NTC Thermistors NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473,
|
||||
NCP15WL333, NCP03WF104
|
||||
Prefixes: 'ncp15wb473', 'ncp18wb473', 'ncp21wb473', 'ncp03wb473',
|
||||
'ncp15wl333', 'ncp03wf104'
|
||||
Datasheet: Publicly available at Murata
|
||||
|
||||
Supported thermistors from EPCOS:
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
Kernel driver tc74
|
||||
====================
|
||||
|
||||
Supported chips:
|
||||
* Microchip TC74
|
||||
Prefix: 'tc74'
|
||||
Datasheet: Publicly available at Microchip website.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
Driver supports the above part.
|
||||
|
||||
The tc74 has an 8-bit sensor, with 1 degree centigrade resolution
|
||||
and +- 2 degrees centigrade accuracy.
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
Currently entering low power standby mode is not supported.
|
|
@ -509,7 +509,7 @@ config SENSORS_G762
|
|||
|
||||
config SENSORS_GPIO_FAN
|
||||
tristate "GPIO fan"
|
||||
depends on GPIOLIB
|
||||
depends on GPIOLIB || COMPILE_TEST
|
||||
depends on THERMAL || THERMAL=n
|
||||
help
|
||||
If you say yes here you get support for fans connected to GPIO lines.
|
||||
|
@ -1106,8 +1106,8 @@ config SENSORS_NTC_THERMISTOR
|
|||
send notifications about the temperature.
|
||||
|
||||
Currently, this driver supports
|
||||
NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473, and NCP15WL333
|
||||
from Murata and B57330V2103 from EPCOS.
|
||||
NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473, NCP15WL333,
|
||||
and NCP03WF104 from Murata and B57330V2103 from EPCOS.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called ntc-thermistor.
|
||||
|
@ -1186,7 +1186,7 @@ config SENSORS_PWM_FAN
|
|||
|
||||
config SENSORS_SHT15
|
||||
tristate "Sensiron humidity and temperature sensors. SHT15 and compat."
|
||||
depends on GPIOLIB
|
||||
depends on GPIOLIB || COMPILE_TEST
|
||||
help
|
||||
If you say yes here you get support for the Sensiron SHT10, SHT11,
|
||||
SHT15, SHT71, SHT75 humidity and temperature sensors.
|
||||
|
@ -1452,6 +1452,16 @@ config SENSORS_INA2XX
|
|||
This driver can also be built as a module. If so, the module
|
||||
will be called ina2xx.
|
||||
|
||||
config SENSORS_TC74
|
||||
tristate "Microchip TC74"
|
||||
depends on I2C
|
||||
help
|
||||
If you say yes here you get support for Microchip TC74 single
|
||||
input temperature sensor chips.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called tc74.
|
||||
|
||||
config SENSORS_THMC50
|
||||
tristate "Texas Instruments THMC50 / Analog Devices ADM1022"
|
||||
depends on I2C
|
||||
|
|
|
@ -140,6 +140,7 @@ obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
|
|||
obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
|
||||
obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
|
||||
obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o
|
||||
obj-$(CONFIG_SENSORS_TC74) += tc74.o
|
||||
obj-$(CONFIG_SENSORS_THMC50) += thmc50.o
|
||||
obj-$(CONFIG_SENSORS_TMP102) += tmp102.o
|
||||
obj-$(CONFIG_SENSORS_TMP103) += tmp103.o
|
||||
|
|
|
@ -12,10 +12,9 @@
|
|||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* The ATXP1 can reside on I2C addresses 0x37 or 0x4e. The chip is
|
||||
* not auto-detected by the driver and must be instantiated explicitly.
|
||||
* See Documentation/i2c/instantiating-devices for more information.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -43,8 +42,6 @@ MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>");
|
|||
#define ATXP1_VIDMASK 0x1f
|
||||
#define ATXP1_GPIO1MASK 0x0f
|
||||
|
||||
static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END };
|
||||
|
||||
struct atxp1_data {
|
||||
struct i2c_client *client;
|
||||
struct mutex update_lock;
|
||||
|
@ -259,48 +256,6 @@ static struct attribute *atxp1_attrs[] = {
|
|||
};
|
||||
ATTRIBUTE_GROUPS(atxp1);
|
||||
|
||||
/* Return 0 if detection is successful, -ENODEV otherwise */
|
||||
static int atxp1_detect(struct i2c_client *new_client,
|
||||
struct i2c_board_info *info)
|
||||
{
|
||||
struct i2c_adapter *adapter = new_client->adapter;
|
||||
|
||||
u8 temp;
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
||||
return -ENODEV;
|
||||
|
||||
/* Detect ATXP1, checking if vendor ID registers are all zero */
|
||||
if (!((i2c_smbus_read_byte_data(new_client, 0x3e) == 0) &&
|
||||
(i2c_smbus_read_byte_data(new_client, 0x3f) == 0) &&
|
||||
(i2c_smbus_read_byte_data(new_client, 0xfe) == 0) &&
|
||||
(i2c_smbus_read_byte_data(new_client, 0xff) == 0)))
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* No vendor ID, now checking if registers 0x10,0x11 (non-existent)
|
||||
* showing the same as register 0x00
|
||||
*/
|
||||
temp = i2c_smbus_read_byte_data(new_client, 0x00);
|
||||
|
||||
if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) &&
|
||||
(i2c_smbus_read_byte_data(new_client, 0x11) == temp)))
|
||||
return -ENODEV;
|
||||
|
||||
/* Get VRM */
|
||||
temp = vid_which_vrm();
|
||||
|
||||
if ((temp != 90) && (temp != 91)) {
|
||||
dev_err(&adapter->dev, "atxp1: Not supporting VRM %d.%d\n",
|
||||
temp / 10, temp % 10);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
strlcpy(info->type, "atxp1", I2C_NAME_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atxp1_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
|
@ -314,6 +269,11 @@ static int atxp1_probe(struct i2c_client *client,
|
|||
|
||||
/* Get VRM */
|
||||
data->vrm = vid_which_vrm();
|
||||
if (data->vrm != 90 && data->vrm != 91) {
|
||||
dev_err(dev, "atxp1: Not supporting VRM %d.%d\n",
|
||||
data->vrm / 10, data->vrm % 10);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
data->client = client;
|
||||
mutex_init(&data->update_lock);
|
||||
|
@ -342,8 +302,6 @@ static struct i2c_driver atxp1_driver = {
|
|||
},
|
||||
.probe = atxp1_probe,
|
||||
.id_table = atxp1_id,
|
||||
.detect = atxp1_detect,
|
||||
.address_list = normal_i2c,
|
||||
};
|
||||
|
||||
module_i2c_driver(atxp1_driver);
|
||||
|
|
|
@ -324,7 +324,7 @@ static int max197_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_device_id max197_device_ids[] = {
|
||||
static const struct platform_device_id max197_device_ids[] = {
|
||||
{ "max197", max197 },
|
||||
{ "max199", max199 },
|
||||
{ }
|
||||
|
|
|
@ -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",
|
||||
|
@ -309,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;
|
||||
|
@ -567,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);
|
||||
|
|
|
@ -1074,7 +1074,7 @@ static int sht15_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_device_id sht15_device_ids[] = {
|
||||
static const struct platform_device_id sht15_device_ids[] = {
|
||||
{ "sht10", sht10 },
|
||||
{ "sht11", sht11 },
|
||||
{ "sht15", sht15 },
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* An hwmon driver for the Microchip TC74
|
||||
*
|
||||
* Copyright 2015 Maciej Szmigiero <mail@maciej.szmigiero.name>
|
||||
*
|
||||
* Based on ad7414.c:
|
||||
* Copyright 2006 Stefan Roese, DENX Software Engineering
|
||||
* Copyright 2008 Sean MacLennan, PIKA Technologies
|
||||
* Copyright 2008 Frank Edelhaeuser, Spansion Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
/* TC74 registers */
|
||||
#define TC74_REG_TEMP 0x00
|
||||
#define TC74_REG_CONFIG 0x01
|
||||
|
||||
struct tc74_data {
|
||||
struct i2c_client *client;
|
||||
struct mutex lock; /* atomic read data updates */
|
||||
bool valid; /* validity of fields below */
|
||||
unsigned long next_update; /* In jiffies */
|
||||
s8 temp_input; /* Temp value in dC */
|
||||
};
|
||||
|
||||
static int tc74_update_device(struct device *dev)
|
||||
{
|
||||
struct tc74_data *data = dev_get_drvdata(dev);
|
||||
struct i2c_client *client = data->client;
|
||||
int ret;
|
||||
|
||||
ret = mutex_lock_interruptible(&data->lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (time_after(jiffies, data->next_update) || !data->valid) {
|
||||
s32 value;
|
||||
|
||||
value = i2c_smbus_read_byte_data(client, TC74_REG_CONFIG);
|
||||
if (value < 0) {
|
||||
dev_dbg(&client->dev, "TC74_REG_CONFIG read err %d\n",
|
||||
(int)value);
|
||||
|
||||
ret = value;
|
||||
goto ret_unlock;
|
||||
}
|
||||
|
||||
if (!(value & BIT(6))) {
|
||||
/* not ready yet */
|
||||
|
||||
ret = -EAGAIN;
|
||||
goto ret_unlock;
|
||||
}
|
||||
|
||||
value = i2c_smbus_read_byte_data(client, TC74_REG_TEMP);
|
||||
if (value < 0) {
|
||||
dev_dbg(&client->dev, "TC74_REG_TEMP read err %d\n",
|
||||
(int)value);
|
||||
|
||||
ret = value;
|
||||
goto ret_unlock;
|
||||
}
|
||||
|
||||
data->temp_input = value;
|
||||
data->next_update = jiffies + HZ / 4;
|
||||
data->valid = true;
|
||||
}
|
||||
|
||||
ret_unlock:
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t show_temp_input(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct tc74_data *data = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = tc74_update_device(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return sprintf(buf, "%d\n", data->temp_input * 1000);
|
||||
}
|
||||
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL, 0);
|
||||
|
||||
static struct attribute *tc74_attrs[] = {
|
||||
&sensor_dev_attr_temp1_input.dev_attr.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
ATTRIBUTE_GROUPS(tc74);
|
||||
|
||||
static int tc74_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *dev_id)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct tc74_data *data;
|
||||
struct device *hwmon_dev;
|
||||
s32 conf;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
data = devm_kzalloc(dev, sizeof(struct tc74_data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
data->client = client;
|
||||
mutex_init(&data->lock);
|
||||
|
||||
/* Make sure the chip is powered up. */
|
||||
conf = i2c_smbus_read_byte_data(client, TC74_REG_CONFIG);
|
||||
if (conf < 0) {
|
||||
dev_err(dev, "unable to read config register\n");
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
if (conf & 0x3f) {
|
||||
dev_err(dev, "invalid config register value\n");
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (conf & BIT(7)) {
|
||||
s32 ret;
|
||||
|
||||
conf &= ~BIT(7);
|
||||
|
||||
ret = i2c_smbus_write_byte_data(client, TC74_REG_CONFIG, conf);
|
||||
if (ret)
|
||||
dev_warn(dev, "unable to disable STANDBY\n");
|
||||
}
|
||||
|
||||
hwmon_dev = devm_hwmon_device_register_with_groups(dev,
|
||||
client->name,
|
||||
data, tc74_groups);
|
||||
return PTR_ERR_OR_ZERO(hwmon_dev);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id tc74_id[] = {
|
||||
{ "tc74", 0 },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, tc74_id);
|
||||
|
||||
static struct i2c_driver tc74_driver = {
|
||||
.driver = {
|
||||
.name = "tc74",
|
||||
},
|
||||
.probe = tc74_probe,
|
||||
.id_table = tc74_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(tc74_driver);
|
||||
|
||||
MODULE_AUTHOR("Maciej Szmigiero <mail@maciej.szmigiero.name>");
|
||||
|
||||
MODULE_DESCRIPTION("TC74 driver");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -27,6 +27,7 @@ enum ntc_thermistor_type {
|
|||
TYPE_NCPXXWB473,
|
||||
TYPE_NCPXXWL333,
|
||||
TYPE_B57330V2103,
|
||||
TYPE_NCPXXWF104,
|
||||
};
|
||||
|
||||
struct ntc_thermistor_platform_data {
|
||||
|
|
Loading…
Reference in New Issue