diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-23 16:39:56 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-23 16:39:56 -0400 |
| commit | 234a56c80a6aa7a05fec05d8b7184354d8765b48 (patch) | |
| tree | 12f8a05b005ced034316a8c865b51cdbe3f79802 | |
| parent | a57f14bac07f63118d947f53976d7f15c04b062a (diff) | |
| parent | 761c1770f2bf36a323ab97e2e1780db4f9b8a6fe (diff) | |
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
| -rw-r--r-- | Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt | 1 | ||||
| -rw-r--r-- | Documentation/hwmon/ntc_thermistor | 6 | ||||
| -rw-r--r-- | Documentation/hwmon/tc74 | 20 | ||||
| -rw-r--r-- | drivers/hwmon/Kconfig | 18 | ||||
| -rw-r--r-- | drivers/hwmon/Makefile | 1 | ||||
| -rw-r--r-- | drivers/hwmon/atxp1.c | 58 | ||||
| -rw-r--r-- | drivers/hwmon/max197.c | 2 | ||||
| -rw-r--r-- | drivers/hwmon/ntc_thermistor.c | 82 | ||||
| -rw-r--r-- | drivers/hwmon/sht15.c | 2 | ||||
| -rw-r--r-- | drivers/hwmon/tc74.c | 177 | ||||
| -rw-r--r-- | include/linux/platform_data/ntc_thermistor.h | 1 |
11 files changed, 290 insertions, 78 deletions
diff --git a/Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt b/Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt index fcca8e744f41..a04a80f9cc70 100644 --- a/Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt +++ b/Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt | |||
| @@ -9,6 +9,7 @@ Requires node properties: | |||
| 9 | "murata,ncp21wb473" | 9 | "murata,ncp21wb473" |
| 10 | "murata,ncp03wb473" | 10 | "murata,ncp03wb473" |
| 11 | "murata,ncp15wl333" | 11 | "murata,ncp15wl333" |
| 12 | "murata,ncp03wf104" | ||
| 12 | 13 | ||
| 13 | /* Usage of vendor name "ntc" is deprecated */ | 14 | /* Usage of vendor name "ntc" is deprecated */ |
| 14 | <DEPRECATED> "ntc,ncp15wb473" | 15 | <DEPRECATED> "ntc,ncp15wb473" |
diff --git a/Documentation/hwmon/ntc_thermistor b/Documentation/hwmon/ntc_thermistor index c5e05e2900a3..1d4cc847c6fe 100644 --- a/Documentation/hwmon/ntc_thermistor +++ b/Documentation/hwmon/ntc_thermistor | |||
| @@ -2,8 +2,10 @@ Kernel driver ntc_thermistor | |||
| 2 | ================= | 2 | ================= |
| 3 | 3 | ||
| 4 | Supported thermistors from Murata: | 4 | Supported thermistors from Murata: |
| 5 | * Murata NTC Thermistors NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473, NCP15WL333 | 5 | * Murata NTC Thermistors NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473, |
| 6 | Prefixes: 'ncp15wb473', 'ncp18wb473', 'ncp21wb473', 'ncp03wb473', 'ncp15wl333' | 6 | NCP15WL333, NCP03WF104 |
| 7 | Prefixes: 'ncp15wb473', 'ncp18wb473', 'ncp21wb473', 'ncp03wb473', | ||
| 8 | 'ncp15wl333', 'ncp03wf104' | ||
| 7 | Datasheet: Publicly available at Murata | 9 | Datasheet: Publicly available at Murata |
| 8 | 10 | ||
| 9 | Supported thermistors from EPCOS: | 11 | Supported thermistors from EPCOS: |
diff --git a/Documentation/hwmon/tc74 b/Documentation/hwmon/tc74 new file mode 100644 index 000000000000..43027aad5f8e --- /dev/null +++ b/Documentation/hwmon/tc74 | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | Kernel driver tc74 | ||
| 2 | ==================== | ||
| 3 | |||
| 4 | Supported chips: | ||
| 5 | * Microchip TC74 | ||
| 6 | Prefix: 'tc74' | ||
| 7 | Datasheet: Publicly available at Microchip website. | ||
| 8 | |||
| 9 | Description | ||
| 10 | ----------- | ||
| 11 | |||
| 12 | Driver supports the above part. | ||
| 13 | |||
| 14 | The tc74 has an 8-bit sensor, with 1 degree centigrade resolution | ||
| 15 | and +- 2 degrees centigrade accuracy. | ||
| 16 | |||
| 17 | Notes | ||
| 18 | ----- | ||
| 19 | |||
| 20 | Currently entering low power standby mode is not supported. | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 25d9e72627e9..54075a07d2a1 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
| @@ -509,7 +509,7 @@ config SENSORS_G762 | |||
| 509 | 509 | ||
| 510 | config SENSORS_GPIO_FAN | 510 | config SENSORS_GPIO_FAN |
| 511 | tristate "GPIO fan" | 511 | tristate "GPIO fan" |
| 512 | depends on GPIOLIB | 512 | depends on GPIOLIB || COMPILE_TEST |
| 513 | depends on THERMAL || THERMAL=n | 513 | depends on THERMAL || THERMAL=n |
| 514 | help | 514 | help |
| 515 | If you say yes here you get support for fans connected to GPIO lines. | 515 | If you say yes here you get support for fans connected to GPIO lines. |
| @@ -1106,8 +1106,8 @@ config SENSORS_NTC_THERMISTOR | |||
| 1106 | send notifications about the temperature. | 1106 | send notifications about the temperature. |
| 1107 | 1107 | ||
| 1108 | Currently, this driver supports | 1108 | Currently, this driver supports |
| 1109 | NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473, and NCP15WL333 | 1109 | NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473, NCP15WL333, |
| 1110 | from Murata and B57330V2103 from EPCOS. | 1110 | and NCP03WF104 from Murata and B57330V2103 from EPCOS. |
| 1111 | 1111 | ||
| 1112 | This driver can also be built as a module. If so, the module | 1112 | This driver can also be built as a module. If so, the module |
| 1113 | will be called ntc-thermistor. | 1113 | will be called ntc-thermistor. |
| @@ -1186,7 +1186,7 @@ config SENSORS_PWM_FAN | |||
| 1186 | 1186 | ||
| 1187 | config SENSORS_SHT15 | 1187 | config SENSORS_SHT15 |
| 1188 | tristate "Sensiron humidity and temperature sensors. SHT15 and compat." | 1188 | tristate "Sensiron humidity and temperature sensors. SHT15 and compat." |
| 1189 | depends on GPIOLIB | 1189 | depends on GPIOLIB || COMPILE_TEST |
| 1190 | help | 1190 | help |
| 1191 | If you say yes here you get support for the Sensiron SHT10, SHT11, | 1191 | If you say yes here you get support for the Sensiron SHT10, SHT11, |
| 1192 | SHT15, SHT71, SHT75 humidity and temperature sensors. | 1192 | SHT15, SHT71, SHT75 humidity and temperature sensors. |
| @@ -1452,6 +1452,16 @@ config SENSORS_INA2XX | |||
| 1452 | This driver can also be built as a module. If so, the module | 1452 | This driver can also be built as a module. If so, the module |
| 1453 | will be called ina2xx. | 1453 | will be called ina2xx. |
| 1454 | 1454 | ||
| 1455 | config SENSORS_TC74 | ||
| 1456 | tristate "Microchip TC74" | ||
| 1457 | depends on I2C | ||
| 1458 | help | ||
| 1459 | If you say yes here you get support for Microchip TC74 single | ||
| 1460 | input temperature sensor chips. | ||
| 1461 | |||
| 1462 | This driver can also be built as a module. If so, the module | ||
| 1463 | will be called tc74. | ||
| 1464 | |||
| 1455 | config SENSORS_THMC50 | 1465 | config SENSORS_THMC50 |
| 1456 | tristate "Texas Instruments THMC50 / Analog Devices ADM1022" | 1466 | tristate "Texas Instruments THMC50 / Analog Devices ADM1022" |
| 1457 | depends on I2C | 1467 | depends on I2C |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index b4a40f17e2aa..ab904027f074 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
| @@ -140,6 +140,7 @@ obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o | |||
| 140 | obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o | 140 | obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o |
| 141 | obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o | 141 | obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o |
| 142 | obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o | 142 | obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o |
| 143 | obj-$(CONFIG_SENSORS_TC74) += tc74.o | ||
| 143 | obj-$(CONFIG_SENSORS_THMC50) += thmc50.o | 144 | obj-$(CONFIG_SENSORS_THMC50) += thmc50.o |
| 144 | obj-$(CONFIG_SENSORS_TMP102) += tmp102.o | 145 | obj-$(CONFIG_SENSORS_TMP102) += tmp102.o |
| 145 | obj-$(CONFIG_SENSORS_TMP103) += tmp103.o | 146 | obj-$(CONFIG_SENSORS_TMP103) += tmp103.o |
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 4c829bb2f9db..f2f2f2fc755a 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c | |||
| @@ -12,10 +12,9 @@ | |||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | * GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
| 14 | * | 14 | * |
| 15 | * You should have received a copy of the GNU General Public License | 15 | * The ATXP1 can reside on I2C addresses 0x37 or 0x4e. The chip is |
| 16 | * along with this program; if not, write to the Free Software | 16 | * not auto-detected by the driver and must be instantiated explicitly. |
| 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 17 | * See Documentation/i2c/instantiating-devices for more information. |
| 18 | * | ||
| 19 | */ | 18 | */ |
| 20 | 19 | ||
| 21 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
| @@ -43,8 +42,6 @@ MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>"); | |||
| 43 | #define ATXP1_VIDMASK 0x1f | 42 | #define ATXP1_VIDMASK 0x1f |
| 44 | #define ATXP1_GPIO1MASK 0x0f | 43 | #define ATXP1_GPIO1MASK 0x0f |
| 45 | 44 | ||
| 46 | static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END }; | ||
| 47 | |||
| 48 | struct atxp1_data { | 45 | struct atxp1_data { |
| 49 | struct i2c_client *client; | 46 | struct i2c_client *client; |
| 50 | struct mutex update_lock; | 47 | struct mutex update_lock; |
| @@ -259,48 +256,6 @@ static struct attribute *atxp1_attrs[] = { | |||
| 259 | }; | 256 | }; |
| 260 | ATTRIBUTE_GROUPS(atxp1); | 257 | ATTRIBUTE_GROUPS(atxp1); |
| 261 | 258 | ||
| 262 | /* Return 0 if detection is successful, -ENODEV otherwise */ | ||
| 263 | static int atxp1_detect(struct i2c_client *new_client, | ||
| 264 | struct i2c_board_info *info) | ||
| 265 | { | ||
| 266 | struct i2c_adapter *adapter = new_client->adapter; | ||
| 267 | |||
| 268 | u8 temp; | ||
| 269 | |||
| 270 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
| 271 | return -ENODEV; | ||
| 272 | |||
| 273 | /* Detect ATXP1, checking if vendor ID registers are all zero */ | ||
| 274 | if (!((i2c_smbus_read_byte_data(new_client, 0x3e) == 0) && | ||
| 275 | (i2c_smbus_read_byte_data(new_client, 0x3f) == 0) && | ||
| 276 | (i2c_smbus_read_byte_data(new_client, 0xfe) == 0) && | ||
| 277 | (i2c_smbus_read_byte_data(new_client, 0xff) == 0))) | ||
| 278 | return -ENODEV; | ||
| 279 | |||
| 280 | /* | ||
| 281 | * No vendor ID, now checking if registers 0x10,0x11 (non-existent) | ||
| 282 | * showing the same as register 0x00 | ||
| 283 | */ | ||
| 284 | temp = i2c_smbus_read_byte_data(new_client, 0x00); | ||
| 285 | |||
| 286 | if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) && | ||
| 287 | (i2c_smbus_read_byte_data(new_client, 0x11) == temp))) | ||
| 288 | return -ENODEV; | ||
| 289 | |||
| 290 | /* Get VRM */ | ||
| 291 | temp = vid_which_vrm(); | ||
| 292 | |||
| 293 | if ((temp != 90) && (temp != 91)) { | ||
| 294 | dev_err(&adapter->dev, "atxp1: Not supporting VRM %d.%d\n", | ||
| 295 | temp / 10, temp % 10); | ||
| 296 | return -ENODEV; | ||
| 297 | } | ||
| 298 | |||
| 299 | strlcpy(info->type, "atxp1", I2C_NAME_SIZE); | ||
| 300 | |||
| 301 | return 0; | ||
| 302 | } | ||
| 303 | |||
| 304 | static int atxp1_probe(struct i2c_client *client, | 259 | static int atxp1_probe(struct i2c_client *client, |
| 305 | const struct i2c_device_id *id) | 260 | const struct i2c_device_id *id) |
| 306 | { | 261 | { |
| @@ -314,6 +269,11 @@ static int atxp1_probe(struct i2c_client *client, | |||
| 314 | 269 | ||
| 315 | /* Get VRM */ | 270 | /* Get VRM */ |
| 316 | data->vrm = vid_which_vrm(); | 271 | data->vrm = vid_which_vrm(); |
| 272 | if (data->vrm != 90 && data->vrm != 91) { | ||
| 273 | dev_err(dev, "atxp1: Not supporting VRM %d.%d\n", | ||
| 274 | data->vrm / 10, data->vrm % 10); | ||
| 275 | return -ENODEV; | ||
| 276 | } | ||
| 317 | 277 | ||
| 318 | data->client = client; | 278 | data->client = client; |
| 319 | mutex_init(&data->update_lock); | 279 | mutex_init(&data->update_lock); |
| @@ -342,8 +302,6 @@ static struct i2c_driver atxp1_driver = { | |||
| 342 | }, | 302 | }, |
| 343 | .probe = atxp1_probe, | 303 | .probe = atxp1_probe, |
| 344 | .id_table = atxp1_id, | 304 | .id_table = atxp1_id, |
| 345 | .detect = atxp1_detect, | ||
| 346 | .address_list = normal_i2c, | ||
| 347 | }; | 305 | }; |
| 348 | 306 | ||
| 349 | module_i2c_driver(atxp1_driver); | 307 | module_i2c_driver(atxp1_driver); |
diff --git a/drivers/hwmon/max197.c b/drivers/hwmon/max197.c index cb0dcfda958c..07628569547a 100644 --- a/drivers/hwmon/max197.c +++ b/drivers/hwmon/max197.c | |||
| @@ -324,7 +324,7 @@ static int max197_remove(struct platform_device *pdev) | |||
| 324 | return 0; | 324 | return 0; |
| 325 | } | 325 | } |
| 326 | 326 | ||
| 327 | static struct platform_device_id max197_device_ids[] = { | 327 | static const struct platform_device_id max197_device_ids[] = { |
| 328 | { "max197", max197 }, | 328 | { "max197", max197 }, |
| 329 | { "max199", max199 }, | 329 | { "max199", max199 }, |
| 330 | { } | 330 | { } |
diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index 68800115876b..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[] = { | |||
| 53 | { "ncp03wb473", TYPE_NCPXXWB473 }, | 53 | { "ncp03wb473", TYPE_NCPXXWB473 }, |
| 54 | { "ncp15wl333", TYPE_NCPXXWL333 }, | 54 | { "ncp15wl333", TYPE_NCPXXWL333 }, |
| 55 | { "b57330v2103", TYPE_B57330V2103}, | 55 | { "b57330v2103", TYPE_B57330V2103}, |
| 56 | { "ncp03wf104", TYPE_NCPXXWF104 }, | ||
| 56 | { }, | 57 | { }, |
| 57 | }; | 58 | }; |
| 58 | 59 | ||
| @@ -135,6 +136,43 @@ static const struct ntc_compensation ncpXXwl333[] = { | |||
| 135 | { .temp_c = 125, .ohm = 707 }, | 136 | { .temp_c = 125, .ohm = 707 }, |
| 136 | }; | 137 | }; |
| 137 | 138 | ||
| 139 | static const struct ntc_compensation ncpXXwf104[] = { | ||
| 140 | { .temp_c = -40, .ohm = 4397119 }, | ||
| 141 | { .temp_c = -35, .ohm = 3088599 }, | ||
| 142 | { .temp_c = -30, .ohm = 2197225 }, | ||
| 143 | { .temp_c = -25, .ohm = 1581881 }, | ||
| 144 | { .temp_c = -20, .ohm = 1151037 }, | ||
| 145 | { .temp_c = -15, .ohm = 846579 }, | ||
| 146 | { .temp_c = -10, .ohm = 628988 }, | ||
| 147 | { .temp_c = -5, .ohm = 471632 }, | ||
| 148 | { .temp_c = 0, .ohm = 357012 }, | ||
| 149 | { .temp_c = 5, .ohm = 272500 }, | ||
| 150 | { .temp_c = 10, .ohm = 209710 }, | ||
| 151 | { .temp_c = 15, .ohm = 162651 }, | ||
| 152 | { .temp_c = 20, .ohm = 127080 }, | ||
| 153 | { .temp_c = 25, .ohm = 100000 }, | ||
| 154 | { .temp_c = 30, .ohm = 79222 }, | ||
| 155 | { .temp_c = 35, .ohm = 63167 }, | ||
| 156 | { .temp_c = 40, .ohm = 50677 }, | ||
| 157 | { .temp_c = 45, .ohm = 40904 }, | ||
| 158 | { .temp_c = 50, .ohm = 33195 }, | ||
| 159 | { .temp_c = 55, .ohm = 27091 }, | ||
| 160 | { .temp_c = 60, .ohm = 22224 }, | ||
| 161 | { .temp_c = 65, .ohm = 18323 }, | ||
| 162 | { .temp_c = 70, .ohm = 15184 }, | ||
| 163 | { .temp_c = 75, .ohm = 12635 }, | ||
| 164 | { .temp_c = 80, .ohm = 10566 }, | ||
| 165 | { .temp_c = 85, .ohm = 8873 }, | ||
| 166 | { .temp_c = 90, .ohm = 7481 }, | ||
| 167 | { .temp_c = 95, .ohm = 6337 }, | ||
| 168 | { .temp_c = 100, .ohm = 5384 }, | ||
| 169 | { .temp_c = 105, .ohm = 4594 }, | ||
| 170 | { .temp_c = 110, .ohm = 3934 }, | ||
| 171 | { .temp_c = 115, .ohm = 3380 }, | ||
| 172 | { .temp_c = 120, .ohm = 2916 }, | ||
| 173 | { .temp_c = 125, .ohm = 2522 }, | ||
| 174 | }; | ||
| 175 | |||
| 138 | /* | 176 | /* |
| 139 | * The following compensation table is from the specification of EPCOS NTC | 177 | * The following compensation table is from the specification of EPCOS NTC |
| 140 | * Thermistors Datasheet | 178 | * Thermistors Datasheet |
| @@ -190,20 +228,21 @@ struct ntc_data { | |||
| 190 | static int ntc_adc_iio_read(struct ntc_thermistor_platform_data *pdata) | 228 | static int ntc_adc_iio_read(struct ntc_thermistor_platform_data *pdata) |
| 191 | { | 229 | { |
| 192 | struct iio_channel *channel = pdata->chan; | 230 | struct iio_channel *channel = pdata->chan; |
| 193 | s64 result; | 231 | int raw, uv, ret; |
| 194 | int val, ret; | ||
| 195 | 232 | ||
| 196 | ret = iio_read_channel_raw(channel, &val); | 233 | ret = iio_read_channel_raw(channel, &raw); |
| 197 | if (ret < 0) { | 234 | if (ret < 0) { |
| 198 | pr_err("read channel() error: %d\n", ret); | 235 | pr_err("read channel() error: %d\n", ret); |
| 199 | return ret; | 236 | return ret; |
| 200 | } | 237 | } |
| 201 | 238 | ||
| 202 | /* unit: mV */ | 239 | ret = iio_convert_raw_to_processed(channel, raw, &uv, 1000); |
| 203 | result = pdata->pullup_uv * (s64) val; | 240 | if (ret < 0) { |
| 204 | result >>= 12; | 241 | /* Assume 12 bit ADC with vref at pullup_uv */ |
| 242 | uv = (pdata->pullup_uv * (s64)raw) >> 12; | ||
| 243 | } | ||
| 205 | 244 | ||
| 206 | return (int)result; | 245 | return uv; |
| 207 | } | 246 | } |
| 208 | 247 | ||
| 209 | static const struct of_device_id ntc_match[] = { | 248 | static const struct of_device_id ntc_match[] = { |
| @@ -219,6 +258,8 @@ static const struct of_device_id ntc_match[] = { | |||
| 219 | .data = &ntc_thermistor_id[4] }, | 258 | .data = &ntc_thermistor_id[4] }, |
| 220 | { .compatible = "epcos,b57330v2103", | 259 | { .compatible = "epcos,b57330v2103", |
| 221 | .data = &ntc_thermistor_id[5]}, | 260 | .data = &ntc_thermistor_id[5]}, |
| 261 | { .compatible = "murata,ncp03wf104", | ||
| 262 | .data = &ntc_thermistor_id[6] }, | ||
| 222 | 263 | ||
| 223 | /* Usage of vendor name "ntc" is deprecated */ | 264 | /* Usage of vendor name "ntc" is deprecated */ |
| 224 | { .compatible = "ntc,ncp15wb473", | 265 | { .compatible = "ntc,ncp15wb473", |
| @@ -309,30 +350,27 @@ static inline u64 div64_u64_safe(u64 dividend, u64 divisor) | |||
| 309 | static int get_ohm_of_thermistor(struct ntc_data *data, unsigned int uv) | 350 | static int get_ohm_of_thermistor(struct ntc_data *data, unsigned int uv) |
| 310 | { | 351 | { |
| 311 | struct ntc_thermistor_platform_data *pdata = data->pdata; | 352 | struct ntc_thermistor_platform_data *pdata = data->pdata; |
| 312 | u64 mv = uv / 1000; | 353 | u32 puv = pdata->pullup_uv; |
| 313 | u64 pmv = pdata->pullup_uv / 1000; | ||
| 314 | u64 n, puo, pdo; | 354 | u64 n, puo, pdo; |
| 315 | puo = pdata->pullup_ohm; | 355 | puo = pdata->pullup_ohm; |
| 316 | pdo = pdata->pulldown_ohm; | 356 | pdo = pdata->pulldown_ohm; |
| 317 | 357 | ||
| 318 | if (mv == 0) { | 358 | if (uv == 0) |
| 319 | if (pdata->connect == NTC_CONNECTED_POSITIVE) | 359 | return (pdata->connect == NTC_CONNECTED_POSITIVE) ? |
| 320 | return INT_MAX; | 360 | INT_MAX : 0; |
| 321 | return 0; | 361 | if (uv >= puv) |
| 322 | } | ||
| 323 | if (mv >= pmv) | ||
| 324 | return (pdata->connect == NTC_CONNECTED_POSITIVE) ? | 362 | return (pdata->connect == NTC_CONNECTED_POSITIVE) ? |
| 325 | 0 : INT_MAX; | 363 | 0 : INT_MAX; |
| 326 | 364 | ||
| 327 | if (pdata->connect == NTC_CONNECTED_POSITIVE && puo == 0) | 365 | if (pdata->connect == NTC_CONNECTED_POSITIVE && puo == 0) |
| 328 | n = div64_u64_safe(pdo * (pmv - mv), mv); | 366 | n = div_u64(pdo * (puv - uv), uv); |
| 329 | else if (pdata->connect == NTC_CONNECTED_GROUND && pdo == 0) | 367 | else if (pdata->connect == NTC_CONNECTED_GROUND && pdo == 0) |
| 330 | n = div64_u64_safe(puo * mv, pmv - mv); | 368 | n = div_u64(puo * uv, puv - uv); |
| 331 | else if (pdata->connect == NTC_CONNECTED_POSITIVE) | 369 | else if (pdata->connect == NTC_CONNECTED_POSITIVE) |
| 332 | n = div64_u64_safe(pdo * puo * (pmv - mv), | 370 | n = div64_u64_safe(pdo * puo * (puv - uv), |
| 333 | puo * mv - pdo * (pmv - mv)); | 371 | puo * uv - pdo * (puv - uv)); |
| 334 | else | 372 | else |
| 335 | n = div64_u64_safe(pdo * puo * mv, pdo * (pmv - mv) - puo * mv); | 373 | n = div64_u64_safe(pdo * puo * uv, pdo * (puv - uv) - puo * uv); |
| 336 | 374 | ||
| 337 | if (n > INT_MAX) | 375 | if (n > INT_MAX) |
| 338 | n = INT_MAX; | 376 | n = INT_MAX; |
| @@ -567,6 +605,10 @@ static int ntc_thermistor_probe(struct platform_device *pdev) | |||
| 567 | data->comp = b57330v2103; | 605 | data->comp = b57330v2103; |
| 568 | data->n_comp = ARRAY_SIZE(b57330v2103); | 606 | data->n_comp = ARRAY_SIZE(b57330v2103); |
| 569 | break; | 607 | break; |
| 608 | case TYPE_NCPXXWF104: | ||
| 609 | data->comp = ncpXXwf104; | ||
| 610 | data->n_comp = ARRAY_SIZE(ncpXXwf104); | ||
| 611 | break; | ||
| 570 | default: | 612 | default: |
| 571 | dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n", | 613 | dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n", |
| 572 | pdev_id->driver_data, pdev_id->name); | 614 | pdev_id->driver_data, pdev_id->name); |
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index d4f0935daaa1..497a7f822a12 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c | |||
| @@ -1074,7 +1074,7 @@ static int sht15_remove(struct platform_device *pdev) | |||
| 1074 | return 0; | 1074 | return 0; |
| 1075 | } | 1075 | } |
| 1076 | 1076 | ||
| 1077 | static struct platform_device_id sht15_device_ids[] = { | 1077 | static const struct platform_device_id sht15_device_ids[] = { |
| 1078 | { "sht10", sht10 }, | 1078 | { "sht10", sht10 }, |
| 1079 | { "sht11", sht11 }, | 1079 | { "sht11", sht11 }, |
| 1080 | { "sht15", sht15 }, | 1080 | { "sht15", sht15 }, |
diff --git a/drivers/hwmon/tc74.c b/drivers/hwmon/tc74.c new file mode 100644 index 000000000000..d95165158800 --- /dev/null +++ b/drivers/hwmon/tc74.c | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | /* | ||
| 2 | * An hwmon driver for the Microchip TC74 | ||
| 3 | * | ||
| 4 | * Copyright 2015 Maciej Szmigiero <mail@maciej.szmigiero.name> | ||
| 5 | * | ||
| 6 | * Based on ad7414.c: | ||
| 7 | * Copyright 2006 Stefan Roese, DENX Software Engineering | ||
| 8 | * Copyright 2008 Sean MacLennan, PIKA Technologies | ||
| 9 | * Copyright 2008 Frank Edelhaeuser, Spansion Inc. | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License as published by | ||
| 13 | * the Free Software Foundation; either version 2 of the License, or | ||
| 14 | * (at your option) any later version. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/bitops.h> | ||
| 18 | #include <linux/err.h> | ||
| 19 | #include <linux/hwmon.h> | ||
| 20 | #include <linux/hwmon-sysfs.h> | ||
| 21 | #include <linux/i2c.h> | ||
| 22 | #include <linux/jiffies.h> | ||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/mutex.h> | ||
| 25 | #include <linux/slab.h> | ||
| 26 | #include <linux/sysfs.h> | ||
| 27 | |||
| 28 | /* TC74 registers */ | ||
| 29 | #define TC74_REG_TEMP 0x00 | ||
| 30 | #define TC74_REG_CONFIG 0x01 | ||
| 31 | |||
| 32 | struct tc74_data { | ||
| 33 | struct i2c_client *client; | ||
| 34 | struct mutex lock; /* atomic read data updates */ | ||
| 35 | bool valid; /* validity of fields below */ | ||
| 36 | unsigned long next_update; /* In jiffies */ | ||
| 37 | s8 temp_input; /* Temp value in dC */ | ||
| 38 | }; | ||
| 39 | |||
| 40 | static int tc74_update_device(struct device *dev) | ||
| 41 | { | ||
| 42 | struct tc74_data *data = dev_get_drvdata(dev); | ||
| 43 | struct i2c_client *client = data->client; | ||
| 44 | int ret; | ||
| 45 | |||
| 46 | ret = mutex_lock_interruptible(&data->lock); | ||
| 47 | if (ret) | ||
| 48 | return ret; | ||
| 49 | |||
| 50 | if (time_after(jiffies, data->next_update) || !data->valid) { | ||
| 51 | s32 value; | ||
| 52 | |||
| 53 | value = i2c_smbus_read_byte_data(client, TC74_REG_CONFIG); | ||
| 54 | if (value < 0) { | ||
| 55 | dev_dbg(&client->dev, "TC74_REG_CONFIG read err %d\n", | ||
| 56 | (int)value); | ||
| 57 | |||
| 58 | ret = value; | ||
| 59 | goto ret_unlock; | ||
| 60 | } | ||
| 61 | |||
| 62 | if (!(value & BIT(6))) { | ||
| 63 | /* not ready yet */ | ||
| 64 | |||
| 65 | ret = -EAGAIN; | ||
| 66 | goto ret_unlock; | ||
| 67 | } | ||
| 68 | |||
| 69 | value = i2c_smbus_read_byte_data(client, TC74_REG_TEMP); | ||
| 70 | if (value < 0) { | ||
| 71 | dev_dbg(&client->dev, "TC74_REG_TEMP read err %d\n", | ||
| 72 | (int)value); | ||
| 73 | |||
| 74 | ret = value; | ||
| 75 | goto ret_unlock; | ||
| 76 | } | ||
| 77 | |||
| 78 | data->temp_input = value; | ||
| 79 | data->next_update = jiffies + HZ / 4; | ||
| 80 | data->valid = true; | ||
| 81 | } | ||
| 82 | |||
| 83 | ret_unlock: | ||
| 84 | mutex_unlock(&data->lock); | ||
| 85 | |||
| 86 | return ret; | ||
| 87 | } | ||
| 88 | |||
| 89 | static ssize_t show_temp_input(struct device *dev, | ||
| 90 | struct device_attribute *attr, char *buf) | ||
| 91 | { | ||
| 92 | struct tc74_data *data = dev_get_drvdata(dev); | ||
| 93 | int ret; | ||
| 94 | |||
| 95 | ret = tc74_update_device(dev); | ||
| 96 | if (ret) | ||
| 97 | return ret; | ||
| 98 | |||
| 99 | return sprintf(buf, "%d\n", data->temp_input * 1000); | ||
| 100 | } | ||
| 101 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL, 0); | ||
| 102 | |||
| 103 | static struct attribute *tc74_attrs[] = { | ||
| 104 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
| 105 | NULL | ||
| 106 | }; | ||
| 107 | |||
| 108 | ATTRIBUTE_GROUPS(tc74); | ||
| 109 | |||
| 110 | static int tc74_probe(struct i2c_client *client, | ||
| 111 | const struct i2c_device_id *dev_id) | ||
| 112 | { | ||
| 113 | struct device *dev = &client->dev; | ||
| 114 | struct tc74_data *data; | ||
| 115 | struct device *hwmon_dev; | ||
| 116 | s32 conf; | ||
| 117 | |||
| 118 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
| 119 | return -EOPNOTSUPP; | ||
| 120 | |||
| 121 | data = devm_kzalloc(dev, sizeof(struct tc74_data), GFP_KERNEL); | ||
| 122 | if (!data) | ||
| 123 | return -ENOMEM; | ||
| 124 | |||
| 125 | data->client = client; | ||
| 126 | mutex_init(&data->lock); | ||
| 127 | |||
| 128 | /* Make sure the chip is powered up. */ | ||
| 129 | conf = i2c_smbus_read_byte_data(client, TC74_REG_CONFIG); | ||
| 130 | if (conf < 0) { | ||
| 131 | dev_err(dev, "unable to read config register\n"); | ||
| 132 | |||
| 133 | return conf; | ||
| 134 | } | ||
| 135 | |||
| 136 | if (conf & 0x3f) { | ||
| 137 | dev_err(dev, "invalid config register value\n"); | ||
| 138 | |||
| 139 | return -ENODEV; | ||
| 140 | } | ||
| 141 | |||
| 142 | if (conf & BIT(7)) { | ||
| 143 | s32 ret; | ||
| 144 | |||
| 145 | conf &= ~BIT(7); | ||
| 146 | |||
| 147 | ret = i2c_smbus_write_byte_data(client, TC74_REG_CONFIG, conf); | ||
| 148 | if (ret) | ||
| 149 | dev_warn(dev, "unable to disable STANDBY\n"); | ||
| 150 | } | ||
| 151 | |||
| 152 | hwmon_dev = devm_hwmon_device_register_with_groups(dev, | ||
| 153 | client->name, | ||
| 154 | data, tc74_groups); | ||
| 155 | return PTR_ERR_OR_ZERO(hwmon_dev); | ||
| 156 | } | ||
| 157 | |||
| 158 | static const struct i2c_device_id tc74_id[] = { | ||
| 159 | { "tc74", 0 }, | ||
| 160 | {} | ||
| 161 | }; | ||
| 162 | MODULE_DEVICE_TABLE(i2c, tc74_id); | ||
| 163 | |||
| 164 | static struct i2c_driver tc74_driver = { | ||
| 165 | .driver = { | ||
| 166 | .name = "tc74", | ||
| 167 | }, | ||
| 168 | .probe = tc74_probe, | ||
| 169 | .id_table = tc74_id, | ||
| 170 | }; | ||
| 171 | |||
| 172 | module_i2c_driver(tc74_driver); | ||
| 173 | |||
| 174 | MODULE_AUTHOR("Maciej Szmigiero <mail@maciej.szmigiero.name>"); | ||
| 175 | |||
| 176 | MODULE_DESCRIPTION("TC74 driver"); | ||
| 177 | MODULE_LICENSE("GPL"); | ||
diff --git a/include/linux/platform_data/ntc_thermistor.h b/include/linux/platform_data/ntc_thermistor.h index 0a6de4ca4930..aed170588b74 100644 --- a/include/linux/platform_data/ntc_thermistor.h +++ b/include/linux/platform_data/ntc_thermistor.h | |||
| @@ -27,6 +27,7 @@ enum ntc_thermistor_type { | |||
| 27 | TYPE_NCPXXWB473, | 27 | TYPE_NCPXXWB473, |
| 28 | TYPE_NCPXXWL333, | 28 | TYPE_NCPXXWL333, |
| 29 | TYPE_B57330V2103, | 29 | TYPE_B57330V2103, |
| 30 | TYPE_NCPXXWF104, | ||
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| 32 | struct ntc_thermistor_platform_data { | 33 | struct ntc_thermistor_platform_data { |
