2019-05-20 10:19:02 +03:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2012-05-21 06:29:48 +04:00
|
|
|
/*
|
|
|
|
* nct6775 - Driver for the hardware monitoring functionality of
|
|
|
|
* Nuvoton NCT677x Super-I/O chips
|
|
|
|
*
|
|
|
|
* Copyright (C) 2012 Guenter Roeck <linux@roeck-us.net>
|
|
|
|
*
|
|
|
|
* Derived from w83627ehf driver
|
2014-01-29 23:40:08 +04:00
|
|
|
* Copyright (C) 2005-2012 Jean Delvare <jdelvare@suse.de>
|
2012-05-21 06:29:48 +04:00
|
|
|
* Copyright (C) 2006 Yuan Mu (Winbond),
|
|
|
|
* Rudolf Marek <r.marek@assembler.cz>
|
|
|
|
* David Hubbard <david.c.hubbard@gmail.com>
|
|
|
|
* Daniel J Blueman <daniel.blueman@gmail.com>
|
|
|
|
* Copyright (C) 2010 Sheng-Yuan Huang (Nuvoton) (PS00)
|
|
|
|
*
|
|
|
|
* Shamelessly ripped from the w83627hf driver
|
|
|
|
* Copyright (C) 2003 Mark Studebaker
|
|
|
|
*
|
|
|
|
* Supports the following chips:
|
|
|
|
*
|
|
|
|
* Chip #vin #fan #pwm #temp chip IDs man ID
|
2012-07-01 19:23:15 +04:00
|
|
|
* nct6106d 9 3 3 6+3 0xc450 0xc1 0x5ca3
|
2019-07-23 19:06:46 +03:00
|
|
|
* nct6116d 9 5 5 3+3 0xd280 0xc1 0x5ca3
|
2012-05-21 06:29:48 +04:00
|
|
|
* nct6775f 9 4 3 6+3 0xb470 0xc1 0x5ca3
|
|
|
|
* nct6776f 9 5 3 6+3 0xc330 0xc1 0x5ca3
|
|
|
|
* nct6779d 15 5 5 2+6 0xc560 0xc1 0x5ca3
|
2013-06-25 09:28:28 +04:00
|
|
|
* nct6791d 15 6 6 2+6 0xc800 0xc1 0x5ca3
|
2014-11-16 20:50:04 +03:00
|
|
|
* nct6792d 15 6 6 2+6 0xc910 0xc1 0x5ca3
|
2015-08-31 05:45:19 +03:00
|
|
|
* nct6793d 15 6 6 2+6 0xd120 0xc1 0x5ca3
|
2017-05-18 04:19:18 +03:00
|
|
|
* nct6795d 14 6 6 2+6 0xd350 0xc1 0x5ca3
|
2018-02-22 00:09:39 +03:00
|
|
|
* nct6796d 14 7 7 2+6 0xd420 0xc1 0x5ca3
|
2018-09-19 06:48:29 +03:00
|
|
|
* nct6797d 14 7 7 2+6 0xd450 0xc1 0x5ca3
|
2018-09-20 06:26:16 +03:00
|
|
|
* (0xd451)
|
2018-12-26 18:34:31 +03:00
|
|
|
* nct6798d 14 7 7 2+6 0xd428 0xc1 0x5ca3
|
|
|
|
* (0xd429)
|
2022-12-28 16:57:44 +03:00
|
|
|
* nct6799d 14 7 7 2+6 0xd802 0xc1 0x5ca3
|
2012-05-21 06:29:48 +04:00
|
|
|
*
|
|
|
|
* #temp lists the number of monitored temperature sources (first value) plus
|
|
|
|
* the number of directly connectable temperature sensors (second value).
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
|
|
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/jiffies.h>
|
|
|
|
#include <linux/hwmon.h>
|
|
|
|
#include <linux/hwmon-sysfs.h>
|
|
|
|
#include <linux/err.h>
|
|
|
|
#include <linux/mutex.h>
|
2017-05-18 04:40:10 +03:00
|
|
|
#include <linux/bitops.h>
|
2018-08-15 16:14:37 +03:00
|
|
|
#include <linux/nospec.h>
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
#include <linux/regmap.h>
|
2012-05-21 06:29:48 +04:00
|
|
|
#include "lm75.h"
|
2022-04-27 04:01:53 +03:00
|
|
|
#include "nct6775.h"
|
2012-05-21 06:29:48 +04:00
|
|
|
|
2022-04-27 04:01:53 +03:00
|
|
|
#undef DEFAULT_SYMBOL_NAMESPACE
|
|
|
|
#define DEFAULT_SYMBOL_NAMESPACE HWMON_NCT6775
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2022-04-27 04:01:53 +03:00
|
|
|
#define USE_ALTERNATE
|
2012-05-21 06:29:48 +04:00
|
|
|
|
|
|
|
/* used to set data->name = nct6775_device_names[data->sio_kind] */
|
|
|
|
static const char * const nct6775_device_names[] = {
|
2012-07-01 19:23:15 +04:00
|
|
|
"nct6106",
|
2019-07-23 19:06:46 +03:00
|
|
|
"nct6116",
|
2012-05-21 06:29:48 +04:00
|
|
|
"nct6775",
|
|
|
|
"nct6776",
|
|
|
|
"nct6779",
|
2013-06-25 09:28:28 +04:00
|
|
|
"nct6791",
|
2014-11-16 20:50:04 +03:00
|
|
|
"nct6792",
|
2015-08-31 05:45:19 +03:00
|
|
|
"nct6793",
|
2017-05-18 04:19:18 +03:00
|
|
|
"nct6795",
|
2018-02-22 00:09:39 +03:00
|
|
|
"nct6796",
|
2018-09-19 06:48:29 +03:00
|
|
|
"nct6797",
|
2018-09-20 06:26:16 +03:00
|
|
|
"nct6798",
|
2022-12-28 16:57:44 +03:00
|
|
|
"nct6799",
|
2015-08-31 05:45:19 +03:00
|
|
|
};
|
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
/* Common and NCT6775 specific data */
|
|
|
|
|
|
|
|
/* Voltage min/max registers for nr=7..14 are in bank 5 */
|
|
|
|
|
|
|
|
static const u16 NCT6775_REG_IN_MAX[] = {
|
|
|
|
0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x554, 0x556, 0x558, 0x55a,
|
|
|
|
0x55c, 0x55e, 0x560, 0x562 };
|
|
|
|
static const u16 NCT6775_REG_IN_MIN[] = {
|
|
|
|
0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x555, 0x557, 0x559, 0x55b,
|
|
|
|
0x55d, 0x55f, 0x561, 0x563 };
|
|
|
|
static const u16 NCT6775_REG_IN[] = {
|
|
|
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x550, 0x551, 0x552
|
|
|
|
};
|
|
|
|
|
|
|
|
#define NCT6775_REG_VBAT 0x5D
|
2012-12-04 15:26:05 +04:00
|
|
|
#define NCT6775_REG_DIODE 0x5E
|
2012-07-01 19:23:15 +04:00
|
|
|
#define NCT6775_DIODE_MASK 0x02
|
2012-05-21 06:29:48 +04:00
|
|
|
|
|
|
|
static const u16 NCT6775_REG_ALARM[NUM_REG_ALARM] = { 0x459, 0x45A, 0x45B };
|
|
|
|
|
2013-06-25 09:21:59 +04:00
|
|
|
/* 0..15 voltages, 16..23 fans, 24..29 temperatures, 30..31 intrusion */
|
2012-05-21 06:29:48 +04:00
|
|
|
|
|
|
|
static const s8 NCT6775_ALARM_BITS[] = {
|
|
|
|
0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
|
|
|
|
17, -1, -1, -1, -1, -1, -1, /* in8..in14 */
|
|
|
|
-1, /* unused */
|
2013-06-24 00:04:04 +04:00
|
|
|
6, 7, 11, -1, -1, /* fan1..fan5 */
|
2012-05-21 06:29:48 +04:00
|
|
|
-1, -1, -1, /* unused */
|
|
|
|
4, 5, 13, -1, -1, -1, /* temp1..temp6 */
|
|
|
|
12, -1 }; /* intrusion0, intrusion1 */
|
|
|
|
|
2013-06-25 09:21:59 +04:00
|
|
|
static const u16 NCT6775_REG_BEEP[NUM_REG_BEEP] = { 0x56, 0x57, 0x453, 0x4e };
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 0..14 voltages, 15 global beep enable, 16..23 fans, 24..29 temperatures,
|
|
|
|
* 30..31 intrusion
|
|
|
|
*/
|
|
|
|
static const s8 NCT6775_BEEP_BITS[] = {
|
|
|
|
0, 1, 2, 3, 8, 9, 10, 16, /* in0.. in7 */
|
|
|
|
17, -1, -1, -1, -1, -1, -1, /* in8..in14 */
|
|
|
|
21, /* global beep enable */
|
|
|
|
6, 7, 11, 28, -1, /* fan1..fan5 */
|
|
|
|
-1, -1, -1, /* unused */
|
|
|
|
4, 5, 13, -1, -1, -1, /* temp1..temp6 */
|
|
|
|
12, -1 }; /* intrusion0, intrusion1 */
|
|
|
|
|
2012-12-04 20:30:54 +04:00
|
|
|
/* DC or PWM output fan configuration */
|
|
|
|
static const u8 NCT6775_REG_PWM_MODE[] = { 0x04, 0x04, 0x12 };
|
|
|
|
static const u8 NCT6775_PWM_MODE_MASK[] = { 0x01, 0x02, 0x01 };
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
/* Advanced Fan control, some values are common for all fans */
|
2012-12-04 20:30:54 +04:00
|
|
|
|
2013-06-25 09:28:28 +04:00
|
|
|
static const u16 NCT6775_REG_TARGET[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x101, 0x201, 0x301, 0x801, 0x901, 0xa01, 0xb01 };
|
2013-06-25 09:28:28 +04:00
|
|
|
static const u16 NCT6775_REG_FAN_MODE[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x102, 0x202, 0x302, 0x802, 0x902, 0xa02, 0xb02 };
|
2012-12-04 21:04:52 +04:00
|
|
|
static const u16 NCT6775_REG_FAN_STEP_DOWN_TIME[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x103, 0x203, 0x303, 0x803, 0x903, 0xa03, 0xb03 };
|
2012-12-04 21:04:52 +04:00
|
|
|
static const u16 NCT6775_REG_FAN_STEP_UP_TIME[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x104, 0x204, 0x304, 0x804, 0x904, 0xa04, 0xb04 };
|
2012-12-04 21:04:52 +04:00
|
|
|
static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x105, 0x205, 0x305, 0x805, 0x905, 0xa05, 0xb05 };
|
2013-06-25 09:28:28 +04:00
|
|
|
static const u16 NCT6775_REG_FAN_START_OUTPUT[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x106, 0x206, 0x306, 0x806, 0x906, 0xa06, 0xb06 };
|
2012-12-04 21:04:52 +04:00
|
|
|
static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a };
|
|
|
|
static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b };
|
|
|
|
|
|
|
|
static const u16 NCT6775_REG_FAN_STOP_TIME[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x107, 0x207, 0x307, 0x807, 0x907, 0xa07, 0xb07 };
|
2013-06-25 09:28:28 +04:00
|
|
|
static const u16 NCT6775_REG_PWM[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x109, 0x209, 0x309, 0x809, 0x909, 0xa09, 0xb09 };
|
2013-06-25 09:28:28 +04:00
|
|
|
static const u16 NCT6775_REG_PWM_READ[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x01, 0x03, 0x11, 0x13, 0x15, 0xa09, 0xb09 };
|
2012-12-04 20:30:54 +04:00
|
|
|
|
2012-12-04 19:56:24 +04:00
|
|
|
static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
|
|
|
|
static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d };
|
2018-09-06 19:47:51 +03:00
|
|
|
static const u16 NCT6775_REG_FAN_PULSES[NUM_FAN] = {
|
|
|
|
0x641, 0x642, 0x643, 0x644 };
|
|
|
|
static const u16 NCT6775_FAN_PULSE_SHIFT[NUM_FAN] = { };
|
2012-12-04 19:56:24 +04:00
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
static const u16 NCT6775_REG_TEMP[] = {
|
|
|
|
0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d };
|
|
|
|
|
2013-11-14 00:46:20 +04:00
|
|
|
static const u16 NCT6775_REG_TEMP_MON[] = { 0x73, 0x75, 0x77 };
|
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
static const u16 NCT6775_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
|
|
|
|
0, 0x152, 0x252, 0x628, 0x629, 0x62A };
|
|
|
|
static const u16 NCT6775_REG_TEMP_HYST[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
|
|
|
|
0x3a, 0x153, 0x253, 0x673, 0x678, 0x67D };
|
|
|
|
static const u16 NCT6775_REG_TEMP_OVER[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
|
|
|
|
0x39, 0x155, 0x255, 0x672, 0x677, 0x67C };
|
|
|
|
|
|
|
|
static const u16 NCT6775_REG_TEMP_SOURCE[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
|
|
|
|
0x621, 0x622, 0x623, 0x624, 0x625, 0x626 };
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
static const u16 NCT6775_REG_TEMP_SEL[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x100, 0x200, 0x300, 0x800, 0x900, 0xa00, 0xb00 };
|
2012-12-04 21:04:52 +04:00
|
|
|
|
2012-12-04 21:08:29 +04:00
|
|
|
static const u16 NCT6775_REG_WEIGHT_TEMP_SEL[] = {
|
2013-06-25 09:28:28 +04:00
|
|
|
0x139, 0x239, 0x339, 0x839, 0x939, 0xa39 };
|
2012-12-04 21:08:29 +04:00
|
|
|
static const u16 NCT6775_REG_WEIGHT_TEMP_STEP[] = {
|
2013-06-25 09:28:28 +04:00
|
|
|
0x13a, 0x23a, 0x33a, 0x83a, 0x93a, 0xa3a };
|
2012-12-04 21:08:29 +04:00
|
|
|
static const u16 NCT6775_REG_WEIGHT_TEMP_STEP_TOL[] = {
|
2013-06-25 09:28:28 +04:00
|
|
|
0x13b, 0x23b, 0x33b, 0x83b, 0x93b, 0xa3b };
|
2012-12-04 21:08:29 +04:00
|
|
|
static const u16 NCT6775_REG_WEIGHT_DUTY_STEP[] = {
|
2013-06-25 09:28:28 +04:00
|
|
|
0x13c, 0x23c, 0x33c, 0x83c, 0x93c, 0xa3c };
|
2012-12-04 21:08:29 +04:00
|
|
|
static const u16 NCT6775_REG_WEIGHT_TEMP_BASE[] = {
|
2013-06-25 09:28:28 +04:00
|
|
|
0x13d, 0x23d, 0x33d, 0x83d, 0x93d, 0xa3d };
|
2012-12-04 21:08:29 +04:00
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 };
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
static const u16 NCT6775_REG_AUTO_TEMP[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x121, 0x221, 0x321, 0x821, 0x921, 0xa21, 0xb21 };
|
2012-12-04 21:04:52 +04:00
|
|
|
static const u16 NCT6775_REG_AUTO_PWM[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x127, 0x227, 0x327, 0x827, 0x927, 0xa27, 0xb27 };
|
2012-12-04 21:04:52 +04:00
|
|
|
|
|
|
|
#define NCT6775_AUTO_TEMP(data, nr, p) ((data)->REG_AUTO_TEMP[nr] + (p))
|
|
|
|
#define NCT6775_AUTO_PWM(data, nr, p) ((data)->REG_AUTO_PWM[nr] + (p))
|
|
|
|
|
|
|
|
static const u16 NCT6775_REG_CRITICAL_ENAB[] = { 0x134, 0x234, 0x334 };
|
|
|
|
|
|
|
|
static const u16 NCT6775_REG_CRITICAL_TEMP[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x135, 0x235, 0x335, 0x835, 0x935, 0xa35, 0xb35 };
|
2012-12-04 21:04:52 +04:00
|
|
|
static const u16 NCT6775_REG_CRITICAL_TEMP_TOLERANCE[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x138, 0x238, 0x338, 0x838, 0x938, 0xa38, 0xb38 };
|
2012-12-04 21:04:52 +04:00
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
static const char *const nct6775_temp_label[] = {
|
|
|
|
"",
|
|
|
|
"SYSTIN",
|
|
|
|
"CPUTIN",
|
|
|
|
"AUXTIN",
|
|
|
|
"AMD SB-TSI",
|
|
|
|
"PECI Agent 0",
|
|
|
|
"PECI Agent 1",
|
|
|
|
"PECI Agent 2",
|
|
|
|
"PECI Agent 3",
|
|
|
|
"PECI Agent 4",
|
|
|
|
"PECI Agent 5",
|
|
|
|
"PECI Agent 6",
|
|
|
|
"PECI Agent 7",
|
|
|
|
"PCH_CHIP_CPU_MAX_TEMP",
|
|
|
|
"PCH_CHIP_TEMP",
|
|
|
|
"PCH_CPU_TEMP",
|
|
|
|
"PCH_MCH_TEMP",
|
|
|
|
"PCH_DIM0_TEMP",
|
|
|
|
"PCH_DIM1_TEMP",
|
|
|
|
"PCH_DIM2_TEMP",
|
|
|
|
"PCH_DIM3_TEMP"
|
|
|
|
};
|
|
|
|
|
2017-05-18 04:05:06 +03:00
|
|
|
#define NCT6775_TEMP_MASK 0x001ffffe
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
#define NCT6775_VIRT_TEMP_MASK 0x00000000
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2017-05-18 04:05:06 +03:00
|
|
|
static const u16 NCT6775_REG_TEMP_ALTERNATE[32] = {
|
|
|
|
[13] = 0x661,
|
|
|
|
[14] = 0x662,
|
|
|
|
[15] = 0x664,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const u16 NCT6775_REG_TEMP_CRIT[32] = {
|
|
|
|
[4] = 0xa00,
|
|
|
|
[5] = 0xa01,
|
|
|
|
[6] = 0xa02,
|
|
|
|
[7] = 0xa03,
|
|
|
|
[8] = 0xa04,
|
|
|
|
[9] = 0xa05,
|
|
|
|
[10] = 0xa06,
|
|
|
|
[11] = 0xa07
|
|
|
|
};
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2022-01-13 19:46:29 +03:00
|
|
|
static const u16 NCT6775_REG_TSI_TEMP[] = { 0x669 };
|
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
/* NCT6776 specific data */
|
|
|
|
|
2015-09-01 02:13:47 +03:00
|
|
|
/* STEP_UP_TIME and STEP_DOWN_TIME regs are swapped for all chips but NCT6775 */
|
|
|
|
#define NCT6776_REG_FAN_STEP_UP_TIME NCT6775_REG_FAN_STEP_DOWN_TIME
|
|
|
|
#define NCT6776_REG_FAN_STEP_DOWN_TIME NCT6775_REG_FAN_STEP_UP_TIME
|
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
static const s8 NCT6776_ALARM_BITS[] = {
|
|
|
|
0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
|
|
|
|
17, -1, -1, -1, -1, -1, -1, /* in8..in14 */
|
|
|
|
-1, /* unused */
|
|
|
|
6, 7, 11, 10, 23, /* fan1..fan5 */
|
|
|
|
-1, -1, -1, /* unused */
|
|
|
|
4, 5, 13, -1, -1, -1, /* temp1..temp6 */
|
|
|
|
12, 9 }; /* intrusion0, intrusion1 */
|
|
|
|
|
2013-06-25 09:21:59 +04:00
|
|
|
static const u16 NCT6776_REG_BEEP[NUM_REG_BEEP] = { 0xb2, 0xb3, 0xb4, 0xb5 };
|
|
|
|
|
|
|
|
static const s8 NCT6776_BEEP_BITS[] = {
|
|
|
|
0, 1, 2, 3, 4, 5, 6, 7, /* in0.. in7 */
|
|
|
|
8, -1, -1, -1, -1, -1, -1, /* in8..in14 */
|
|
|
|
24, /* global beep enable */
|
|
|
|
25, 26, 27, 28, 29, /* fan1..fan5 */
|
|
|
|
-1, -1, -1, /* unused */
|
|
|
|
16, 17, 18, 19, 20, 21, /* temp1..temp6 */
|
|
|
|
30, 31 }; /* intrusion0, intrusion1 */
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
static const u16 NCT6776_REG_TOLERANCE_H[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x10c, 0x20c, 0x30c, 0x80c, 0x90c, 0xa0c, 0xb0c };
|
2012-12-04 21:04:52 +04:00
|
|
|
|
2013-06-25 09:28:28 +04:00
|
|
|
static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0, 0, 0, 0 };
|
|
|
|
static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0, 0, 0, 0 };
|
2012-12-04 20:30:54 +04:00
|
|
|
|
2018-02-22 00:09:37 +03:00
|
|
|
static const u16 NCT6776_REG_FAN_MIN[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x63a, 0x63c, 0x63e, 0x640, 0x642, 0x64a, 0x64c };
|
2018-09-06 19:47:51 +03:00
|
|
|
static const u16 NCT6776_REG_FAN_PULSES[NUM_FAN] = {
|
|
|
|
0x644, 0x645, 0x646, 0x647, 0x648, 0x649 };
|
2012-12-04 19:56:24 +04:00
|
|
|
|
2012-12-04 21:08:29 +04:00
|
|
|
static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] = {
|
2013-06-25 09:28:28 +04:00
|
|
|
0x13e, 0x23e, 0x33e, 0x83e, 0x93e, 0xa3e };
|
2012-12-04 21:08:29 +04:00
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
|
|
|
|
0x18, 0x152, 0x252, 0x628, 0x629, 0x62A };
|
|
|
|
|
|
|
|
static const char *const nct6776_temp_label[] = {
|
|
|
|
"",
|
|
|
|
"SYSTIN",
|
|
|
|
"CPUTIN",
|
|
|
|
"AUXTIN",
|
|
|
|
"SMBUSMASTER 0",
|
|
|
|
"SMBUSMASTER 1",
|
|
|
|
"SMBUSMASTER 2",
|
|
|
|
"SMBUSMASTER 3",
|
|
|
|
"SMBUSMASTER 4",
|
|
|
|
"SMBUSMASTER 5",
|
|
|
|
"SMBUSMASTER 6",
|
|
|
|
"SMBUSMASTER 7",
|
|
|
|
"PECI Agent 0",
|
|
|
|
"PECI Agent 1",
|
|
|
|
"PCH_CHIP_CPU_MAX_TEMP",
|
|
|
|
"PCH_CHIP_TEMP",
|
|
|
|
"PCH_CPU_TEMP",
|
|
|
|
"PCH_MCH_TEMP",
|
|
|
|
"PCH_DIM0_TEMP",
|
|
|
|
"PCH_DIM1_TEMP",
|
|
|
|
"PCH_DIM2_TEMP",
|
|
|
|
"PCH_DIM3_TEMP",
|
|
|
|
"BYTE_TEMP"
|
|
|
|
};
|
|
|
|
|
2017-05-18 04:05:06 +03:00
|
|
|
#define NCT6776_TEMP_MASK 0x007ffffe
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
#define NCT6776_VIRT_TEMP_MASK 0x00000000
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2017-05-18 04:05:06 +03:00
|
|
|
static const u16 NCT6776_REG_TEMP_ALTERNATE[32] = {
|
|
|
|
[14] = 0x401,
|
|
|
|
[15] = 0x402,
|
|
|
|
[16] = 0x404,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const u16 NCT6776_REG_TEMP_CRIT[32] = {
|
|
|
|
[11] = 0x709,
|
|
|
|
[12] = 0x70a,
|
|
|
|
};
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2022-01-13 19:46:29 +03:00
|
|
|
static const u16 NCT6776_REG_TSI_TEMP[] = {
|
|
|
|
0x409, 0x40b, 0x40d, 0x40f, 0x411, 0x413, 0x415, 0x417 };
|
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
/* NCT6779 specific data */
|
|
|
|
|
|
|
|
static const u16 NCT6779_REG_IN[] = {
|
|
|
|
0x480, 0x481, 0x482, 0x483, 0x484, 0x485, 0x486, 0x487,
|
|
|
|
0x488, 0x489, 0x48a, 0x48b, 0x48c, 0x48d, 0x48e };
|
|
|
|
|
|
|
|
static const u16 NCT6779_REG_ALARM[NUM_REG_ALARM] = {
|
|
|
|
0x459, 0x45A, 0x45B, 0x568 };
|
|
|
|
|
|
|
|
static const s8 NCT6779_ALARM_BITS[] = {
|
|
|
|
0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
|
|
|
|
17, 24, 25, 26, 27, 28, 29, /* in8..in14 */
|
|
|
|
-1, /* unused */
|
|
|
|
6, 7, 11, 10, 23, /* fan1..fan5 */
|
|
|
|
-1, -1, -1, /* unused */
|
|
|
|
4, 5, 13, -1, -1, -1, /* temp1..temp6 */
|
|
|
|
12, 9 }; /* intrusion0, intrusion1 */
|
|
|
|
|
2013-06-25 09:21:59 +04:00
|
|
|
static const s8 NCT6779_BEEP_BITS[] = {
|
|
|
|
0, 1, 2, 3, 4, 5, 6, 7, /* in0.. in7 */
|
|
|
|
8, 9, 10, 11, 12, 13, 14, /* in8..in14 */
|
|
|
|
24, /* global beep enable */
|
|
|
|
25, 26, 27, 28, 29, /* fan1..fan5 */
|
|
|
|
-1, -1, -1, /* unused */
|
|
|
|
16, 17, -1, -1, -1, -1, /* temp1..temp6 */
|
|
|
|
30, 31 }; /* intrusion0, intrusion1 */
|
|
|
|
|
2013-06-25 09:28:28 +04:00
|
|
|
static const u16 NCT6779_REG_FAN[] = {
|
2018-09-17 15:23:58 +03:00
|
|
|
0x4c0, 0x4c2, 0x4c4, 0x4c6, 0x4c8, 0x4ca, 0x4ce };
|
2018-09-06 19:47:51 +03:00
|
|
|
static const u16 NCT6779_REG_FAN_PULSES[NUM_FAN] = {
|
2018-09-19 06:48:29 +03:00
|
|
|
0x644, 0x645, 0x646, 0x647, 0x648, 0x649, 0x64f };
|
2012-12-04 19:56:24 +04:00
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x136, 0x236, 0x336, 0x836, 0x936, 0xa36, 0xb36 };
|
2012-07-01 19:23:15 +04:00
|
|
|
#define NCT6779_CRITICAL_PWM_ENABLE_MASK 0x01
|
2012-12-04 21:04:52 +04:00
|
|
|
static const u16 NCT6779_REG_CRITICAL_PWM[] = {
|
2018-02-22 00:09:39 +03:00
|
|
|
0x137, 0x237, 0x337, 0x837, 0x937, 0xa37, 0xb37 };
|
2012-12-04 21:04:52 +04:00
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 };
|
2013-11-14 00:46:20 +04:00
|
|
|
static const u16 NCT6779_REG_TEMP_MON[] = { 0x73, 0x75, 0x77, 0x79, 0x7b };
|
2012-12-04 15:26:05 +04:00
|
|
|
static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
|
|
|
|
0x18, 0x152 };
|
|
|
|
static const u16 NCT6779_REG_TEMP_HYST[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
|
|
|
|
0x3a, 0x153 };
|
|
|
|
static const u16 NCT6779_REG_TEMP_OVER[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
|
|
|
|
0x39, 0x155 };
|
|
|
|
|
|
|
|
static const u16 NCT6779_REG_TEMP_OFFSET[] = {
|
2022-12-28 16:57:44 +03:00
|
|
|
0x454, 0x455, 0x456, 0x44a, 0x44b, 0x44c, 0x44d, 0x449 };
|
2012-12-04 15:26:05 +04:00
|
|
|
|
|
|
|
static const char *const nct6779_temp_label[] = {
|
|
|
|
"",
|
|
|
|
"SYSTIN",
|
|
|
|
"CPUTIN",
|
|
|
|
"AUXTIN0",
|
|
|
|
"AUXTIN1",
|
|
|
|
"AUXTIN2",
|
|
|
|
"AUXTIN3",
|
|
|
|
"",
|
|
|
|
"SMBUSMASTER 0",
|
|
|
|
"SMBUSMASTER 1",
|
|
|
|
"SMBUSMASTER 2",
|
|
|
|
"SMBUSMASTER 3",
|
|
|
|
"SMBUSMASTER 4",
|
|
|
|
"SMBUSMASTER 5",
|
|
|
|
"SMBUSMASTER 6",
|
|
|
|
"SMBUSMASTER 7",
|
|
|
|
"PECI Agent 0",
|
|
|
|
"PECI Agent 1",
|
|
|
|
"PCH_CHIP_CPU_MAX_TEMP",
|
|
|
|
"PCH_CHIP_TEMP",
|
|
|
|
"PCH_CPU_TEMP",
|
|
|
|
"PCH_MCH_TEMP",
|
|
|
|
"PCH_DIM0_TEMP",
|
|
|
|
"PCH_DIM1_TEMP",
|
|
|
|
"PCH_DIM2_TEMP",
|
|
|
|
"PCH_DIM3_TEMP",
|
2015-08-30 01:29:25 +03:00
|
|
|
"BYTE_TEMP",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"Virtual_TEMP"
|
2012-12-04 15:26:05 +04:00
|
|
|
};
|
|
|
|
|
2017-05-18 04:05:06 +03:00
|
|
|
#define NCT6779_TEMP_MASK 0x07ffff7e
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
#define NCT6779_VIRT_TEMP_MASK 0x00000000
|
2017-05-18 04:05:06 +03:00
|
|
|
#define NCT6791_TEMP_MASK 0x87ffff7e
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
#define NCT6791_VIRT_TEMP_MASK 0x80000000
|
2015-08-30 01:29:25 +03:00
|
|
|
|
2017-05-18 04:05:06 +03:00
|
|
|
static const u16 NCT6779_REG_TEMP_ALTERNATE[32]
|
2012-12-04 15:26:05 +04:00
|
|
|
= { 0x490, 0x491, 0x492, 0x493, 0x494, 0x495, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0x400, 0x401, 0x402, 0x404, 0x405, 0x406, 0x407,
|
|
|
|
0x408, 0 };
|
|
|
|
|
2017-05-18 04:05:06 +03:00
|
|
|
static const u16 NCT6779_REG_TEMP_CRIT[32] = {
|
|
|
|
[15] = 0x709,
|
|
|
|
[16] = 0x70a,
|
|
|
|
};
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2013-06-25 09:28:28 +04:00
|
|
|
/* NCT6791 specific data */
|
|
|
|
|
2018-02-22 00:09:36 +03:00
|
|
|
static const u16 NCT6791_REG_WEIGHT_TEMP_SEL[NUM_FAN] = { 0, 0x239 };
|
|
|
|
static const u16 NCT6791_REG_WEIGHT_TEMP_STEP[NUM_FAN] = { 0, 0x23a };
|
|
|
|
static const u16 NCT6791_REG_WEIGHT_TEMP_STEP_TOL[NUM_FAN] = { 0, 0x23b };
|
|
|
|
static const u16 NCT6791_REG_WEIGHT_DUTY_STEP[NUM_FAN] = { 0, 0x23c };
|
|
|
|
static const u16 NCT6791_REG_WEIGHT_TEMP_BASE[NUM_FAN] = { 0, 0x23d };
|
|
|
|
static const u16 NCT6791_REG_WEIGHT_DUTY_BASE[NUM_FAN] = { 0, 0x23e };
|
2013-11-14 00:47:17 +04:00
|
|
|
|
2013-06-25 09:28:28 +04:00
|
|
|
static const u16 NCT6791_REG_ALARM[NUM_REG_ALARM] = {
|
|
|
|
0x459, 0x45A, 0x45B, 0x568, 0x45D };
|
|
|
|
|
|
|
|
static const s8 NCT6791_ALARM_BITS[] = {
|
|
|
|
0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */
|
|
|
|
17, 24, 25, 26, 27, 28, 29, /* in8..in14 */
|
|
|
|
-1, /* unused */
|
|
|
|
6, 7, 11, 10, 23, 33, /* fan1..fan6 */
|
|
|
|
-1, -1, /* unused */
|
|
|
|
4, 5, 13, -1, -1, -1, /* temp1..temp6 */
|
|
|
|
12, 9 }; /* intrusion0, intrusion1 */
|
|
|
|
|
2015-08-31 05:45:19 +03:00
|
|
|
/* NCT6792/NCT6793 specific data */
|
2014-11-16 20:50:04 +03:00
|
|
|
|
|
|
|
static const u16 NCT6792_REG_TEMP_MON[] = {
|
|
|
|
0x73, 0x75, 0x77, 0x79, 0x7b, 0x7d };
|
|
|
|
static const u16 NCT6792_REG_BEEP[NUM_REG_BEEP] = {
|
|
|
|
0xb2, 0xb3, 0xb4, 0xb5, 0xbf };
|
2013-06-25 09:28:28 +04:00
|
|
|
|
2015-10-30 17:52:39 +03:00
|
|
|
static const char *const nct6792_temp_label[] = {
|
|
|
|
"",
|
|
|
|
"SYSTIN",
|
|
|
|
"CPUTIN",
|
|
|
|
"AUXTIN0",
|
|
|
|
"AUXTIN1",
|
|
|
|
"AUXTIN2",
|
|
|
|
"AUXTIN3",
|
|
|
|
"",
|
|
|
|
"SMBUSMASTER 0",
|
|
|
|
"SMBUSMASTER 1",
|
|
|
|
"SMBUSMASTER 2",
|
|
|
|
"SMBUSMASTER 3",
|
|
|
|
"SMBUSMASTER 4",
|
|
|
|
"SMBUSMASTER 5",
|
|
|
|
"SMBUSMASTER 6",
|
|
|
|
"SMBUSMASTER 7",
|
|
|
|
"PECI Agent 0",
|
|
|
|
"PECI Agent 1",
|
|
|
|
"PCH_CHIP_CPU_MAX_TEMP",
|
|
|
|
"PCH_CHIP_TEMP",
|
|
|
|
"PCH_CPU_TEMP",
|
|
|
|
"PCH_MCH_TEMP",
|
|
|
|
"PCH_DIM0_TEMP",
|
|
|
|
"PCH_DIM1_TEMP",
|
|
|
|
"PCH_DIM2_TEMP",
|
|
|
|
"PCH_DIM3_TEMP",
|
|
|
|
"BYTE_TEMP",
|
|
|
|
"PECI Agent 0 Calibration",
|
|
|
|
"PECI Agent 1 Calibration",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"Virtual_TEMP"
|
|
|
|
};
|
|
|
|
|
2017-05-18 04:05:06 +03:00
|
|
|
#define NCT6792_TEMP_MASK 0x9fffff7e
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
#define NCT6792_VIRT_TEMP_MASK 0x80000000
|
2017-05-18 04:05:06 +03:00
|
|
|
|
2015-10-30 17:52:39 +03:00
|
|
|
static const char *const nct6793_temp_label[] = {
|
|
|
|
"",
|
|
|
|
"SYSTIN",
|
|
|
|
"CPUTIN",
|
|
|
|
"AUXTIN0",
|
|
|
|
"AUXTIN1",
|
|
|
|
"AUXTIN2",
|
|
|
|
"AUXTIN3",
|
|
|
|
"",
|
|
|
|
"SMBUSMASTER 0",
|
|
|
|
"SMBUSMASTER 1",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"PECI Agent 0",
|
|
|
|
"PECI Agent 1",
|
|
|
|
"PCH_CHIP_CPU_MAX_TEMP",
|
|
|
|
"PCH_CHIP_TEMP",
|
|
|
|
"PCH_CPU_TEMP",
|
|
|
|
"PCH_MCH_TEMP",
|
|
|
|
"Agent0 Dimm0 ",
|
|
|
|
"Agent0 Dimm1",
|
|
|
|
"Agent1 Dimm0",
|
|
|
|
"Agent1 Dimm1",
|
|
|
|
"BYTE_TEMP0",
|
|
|
|
"BYTE_TEMP1",
|
|
|
|
"PECI Agent 0 Calibration",
|
|
|
|
"PECI Agent 1 Calibration",
|
|
|
|
"",
|
|
|
|
"Virtual_TEMP"
|
|
|
|
};
|
|
|
|
|
2017-05-18 04:05:06 +03:00
|
|
|
#define NCT6793_TEMP_MASK 0xbfff037e
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
#define NCT6793_VIRT_TEMP_MASK 0x80000000
|
2017-05-18 04:05:06 +03:00
|
|
|
|
2017-05-18 04:19:18 +03:00
|
|
|
static const char *const nct6795_temp_label[] = {
|
|
|
|
"",
|
|
|
|
"SYSTIN",
|
|
|
|
"CPUTIN",
|
|
|
|
"AUXTIN0",
|
|
|
|
"AUXTIN1",
|
|
|
|
"AUXTIN2",
|
|
|
|
"AUXTIN3",
|
|
|
|
"",
|
|
|
|
"SMBUSMASTER 0",
|
|
|
|
"SMBUSMASTER 1",
|
|
|
|
"SMBUSMASTER 2",
|
|
|
|
"SMBUSMASTER 3",
|
|
|
|
"SMBUSMASTER 4",
|
|
|
|
"SMBUSMASTER 5",
|
|
|
|
"SMBUSMASTER 6",
|
|
|
|
"SMBUSMASTER 7",
|
|
|
|
"PECI Agent 0",
|
|
|
|
"PECI Agent 1",
|
|
|
|
"PCH_CHIP_CPU_MAX_TEMP",
|
|
|
|
"PCH_CHIP_TEMP",
|
|
|
|
"PCH_CPU_TEMP",
|
|
|
|
"PCH_MCH_TEMP",
|
2018-09-20 07:52:49 +03:00
|
|
|
"Agent0 Dimm0",
|
|
|
|
"Agent0 Dimm1",
|
|
|
|
"Agent1 Dimm0",
|
|
|
|
"Agent1 Dimm1",
|
2017-05-18 04:19:18 +03:00
|
|
|
"BYTE_TEMP0",
|
|
|
|
"BYTE_TEMP1",
|
|
|
|
"PECI Agent 0 Calibration",
|
|
|
|
"PECI Agent 1 Calibration",
|
|
|
|
"",
|
|
|
|
"Virtual_TEMP"
|
|
|
|
};
|
|
|
|
|
|
|
|
#define NCT6795_TEMP_MASK 0xbfffff7e
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
#define NCT6795_VIRT_TEMP_MASK 0x80000000
|
2017-05-18 04:19:18 +03:00
|
|
|
|
2018-02-22 00:09:39 +03:00
|
|
|
static const char *const nct6796_temp_label[] = {
|
|
|
|
"",
|
|
|
|
"SYSTIN",
|
|
|
|
"CPUTIN",
|
|
|
|
"AUXTIN0",
|
|
|
|
"AUXTIN1",
|
|
|
|
"AUXTIN2",
|
|
|
|
"AUXTIN3",
|
|
|
|
"AUXTIN4",
|
|
|
|
"SMBUSMASTER 0",
|
|
|
|
"SMBUSMASTER 1",
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
"Virtual_TEMP",
|
|
|
|
"Virtual_TEMP",
|
2018-02-22 00:09:39 +03:00
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"PECI Agent 0",
|
|
|
|
"PECI Agent 1",
|
|
|
|
"PCH_CHIP_CPU_MAX_TEMP",
|
|
|
|
"PCH_CHIP_TEMP",
|
|
|
|
"PCH_CPU_TEMP",
|
|
|
|
"PCH_MCH_TEMP",
|
2018-09-20 07:52:49 +03:00
|
|
|
"Agent0 Dimm0",
|
|
|
|
"Agent0 Dimm1",
|
|
|
|
"Agent1 Dimm0",
|
|
|
|
"Agent1 Dimm1",
|
2018-02-22 00:09:39 +03:00
|
|
|
"BYTE_TEMP0",
|
|
|
|
"BYTE_TEMP1",
|
|
|
|
"PECI Agent 0 Calibration",
|
|
|
|
"PECI Agent 1 Calibration",
|
|
|
|
"",
|
|
|
|
"Virtual_TEMP"
|
|
|
|
};
|
|
|
|
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
#define NCT6796_TEMP_MASK 0xbfff0ffe
|
|
|
|
#define NCT6796_VIRT_TEMP_MASK 0x80000c00
|
2018-02-22 00:09:39 +03:00
|
|
|
|
2022-01-13 19:46:29 +03:00
|
|
|
static const u16 NCT6796_REG_TSI_TEMP[] = { 0x409, 0x40b };
|
|
|
|
|
2018-09-20 06:26:16 +03:00
|
|
|
static const char *const nct6798_temp_label[] = {
|
|
|
|
"",
|
|
|
|
"SYSTIN",
|
|
|
|
"CPUTIN",
|
|
|
|
"AUXTIN0",
|
|
|
|
"AUXTIN1",
|
|
|
|
"AUXTIN2",
|
|
|
|
"AUXTIN3",
|
|
|
|
"AUXTIN4",
|
|
|
|
"SMBUSMASTER 0",
|
|
|
|
"SMBUSMASTER 1",
|
|
|
|
"Virtual_TEMP",
|
|
|
|
"Virtual_TEMP",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"PECI Agent 0",
|
|
|
|
"PECI Agent 1",
|
|
|
|
"PCH_CHIP_CPU_MAX_TEMP",
|
|
|
|
"PCH_CHIP_TEMP",
|
|
|
|
"PCH_CPU_TEMP",
|
|
|
|
"PCH_MCH_TEMP",
|
|
|
|
"Agent0 Dimm0",
|
|
|
|
"Agent0 Dimm1",
|
|
|
|
"Agent1 Dimm0",
|
|
|
|
"Agent1 Dimm1",
|
|
|
|
"BYTE_TEMP0",
|
|
|
|
"BYTE_TEMP1",
|
2020-07-15 00:31:11 +03:00
|
|
|
"PECI Agent 0 Calibration", /* undocumented */
|
|
|
|
"PECI Agent 1 Calibration", /* undocumented */
|
2018-09-20 06:26:16 +03:00
|
|
|
"",
|
|
|
|
"Virtual_TEMP"
|
|
|
|
};
|
|
|
|
|
2020-07-15 00:31:11 +03:00
|
|
|
#define NCT6798_TEMP_MASK 0xbfff0ffe
|
2018-09-20 06:26:16 +03:00
|
|
|
#define NCT6798_VIRT_TEMP_MASK 0x80000c00
|
|
|
|
|
2022-12-28 16:57:44 +03:00
|
|
|
static const char *const nct6799_temp_label[] = {
|
|
|
|
"",
|
|
|
|
"SYSTIN",
|
|
|
|
"CPUTIN",
|
|
|
|
"AUXTIN0",
|
|
|
|
"AUXTIN1",
|
|
|
|
"AUXTIN2",
|
|
|
|
"AUXTIN3",
|
|
|
|
"AUXTIN4",
|
|
|
|
"SMBUSMASTER 0",
|
|
|
|
"SMBUSMASTER 1",
|
|
|
|
"Virtual_TEMP",
|
|
|
|
"Virtual_TEMP",
|
|
|
|
"",
|
|
|
|
"AUXTIN5",
|
|
|
|
"",
|
|
|
|
"",
|
|
|
|
"PECI Agent 0",
|
|
|
|
"PECI Agent 1",
|
|
|
|
"PCH_CHIP_CPU_MAX_TEMP",
|
|
|
|
"PCH_CHIP_TEMP",
|
|
|
|
"PCH_CPU_TEMP",
|
|
|
|
"PCH_MCH_TEMP",
|
|
|
|
"Agent0 Dimm0",
|
|
|
|
"Agent0 Dimm1",
|
|
|
|
"Agent1 Dimm0",
|
|
|
|
"Agent1 Dimm1",
|
|
|
|
"BYTE_TEMP0",
|
|
|
|
"BYTE_TEMP1",
|
|
|
|
"PECI Agent 0 Calibration", /* undocumented */
|
|
|
|
"PECI Agent 1 Calibration", /* undocumented */
|
|
|
|
"",
|
|
|
|
"Virtual_TEMP"
|
|
|
|
};
|
|
|
|
|
|
|
|
#define NCT6799_TEMP_MASK 0xbfff2ffe
|
|
|
|
#define NCT6799_VIRT_TEMP_MASK 0x80000c00
|
|
|
|
|
2012-07-01 19:23:15 +04:00
|
|
|
/* NCT6102D/NCT6106D specific data */
|
|
|
|
|
|
|
|
#define NCT6106_REG_VBAT 0x318
|
|
|
|
#define NCT6106_REG_DIODE 0x319
|
|
|
|
#define NCT6106_DIODE_MASK 0x01
|
|
|
|
|
|
|
|
static const u16 NCT6106_REG_IN_MAX[] = {
|
|
|
|
0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9e, 0xa0, 0xa2 };
|
|
|
|
static const u16 NCT6106_REG_IN_MIN[] = {
|
|
|
|
0x91, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9f, 0xa1, 0xa3 };
|
|
|
|
static const u16 NCT6106_REG_IN[] = {
|
|
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09 };
|
|
|
|
|
|
|
|
static const u16 NCT6106_REG_TEMP[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15 };
|
2013-11-14 00:46:20 +04:00
|
|
|
static const u16 NCT6106_REG_TEMP_MON[] = { 0x18, 0x19, 0x1a };
|
2012-07-01 19:23:15 +04:00
|
|
|
static const u16 NCT6106_REG_TEMP_HYST[] = {
|
|
|
|
0xc3, 0xc7, 0xcb, 0xcf, 0xd3, 0xd7 };
|
|
|
|
static const u16 NCT6106_REG_TEMP_OVER[] = {
|
2013-04-03 09:14:06 +04:00
|
|
|
0xc2, 0xc6, 0xca, 0xce, 0xd2, 0xd6 };
|
|
|
|
static const u16 NCT6106_REG_TEMP_CRIT_L[] = {
|
|
|
|
0xc0, 0xc4, 0xc8, 0xcc, 0xd0, 0xd4 };
|
|
|
|
static const u16 NCT6106_REG_TEMP_CRIT_H[] = {
|
|
|
|
0xc1, 0xc5, 0xc9, 0xcf, 0xd1, 0xd5 };
|
2012-07-01 19:23:15 +04:00
|
|
|
static const u16 NCT6106_REG_TEMP_OFFSET[] = { 0x311, 0x312, 0x313 };
|
|
|
|
static const u16 NCT6106_REG_TEMP_CONFIG[] = {
|
|
|
|
0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc };
|
|
|
|
|
|
|
|
static const u16 NCT6106_REG_FAN[] = { 0x20, 0x22, 0x24 };
|
|
|
|
static const u16 NCT6106_REG_FAN_MIN[] = { 0xe0, 0xe2, 0xe4 };
|
2018-09-06 19:47:51 +03:00
|
|
|
static const u16 NCT6106_REG_FAN_PULSES[] = { 0xf6, 0xf6, 0xf6 };
|
|
|
|
static const u16 NCT6106_FAN_PULSE_SHIFT[] = { 0, 2, 4 };
|
2012-07-01 19:23:15 +04:00
|
|
|
|
|
|
|
static const u8 NCT6106_REG_PWM_MODE[] = { 0xf3, 0xf3, 0xf3 };
|
|
|
|
static const u8 NCT6106_PWM_MODE_MASK[] = { 0x01, 0x02, 0x04 };
|
|
|
|
static const u16 NCT6106_REG_PWM_READ[] = { 0x4a, 0x4b, 0x4c };
|
|
|
|
static const u16 NCT6106_REG_FAN_MODE[] = { 0x113, 0x123, 0x133 };
|
|
|
|
static const u16 NCT6106_REG_TEMP_SOURCE[] = {
|
|
|
|
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5 };
|
|
|
|
|
|
|
|
static const u16 NCT6106_REG_CRITICAL_TEMP[] = { 0x11a, 0x12a, 0x13a };
|
|
|
|
static const u16 NCT6106_REG_CRITICAL_TEMP_TOLERANCE[] = {
|
|
|
|
0x11b, 0x12b, 0x13b };
|
|
|
|
|
|
|
|
static const u16 NCT6106_REG_CRITICAL_PWM_ENABLE[] = { 0x11c, 0x12c, 0x13c };
|
|
|
|
#define NCT6106_CRITICAL_PWM_ENABLE_MASK 0x10
|
|
|
|
static const u16 NCT6106_REG_CRITICAL_PWM[] = { 0x11d, 0x12d, 0x13d };
|
|
|
|
|
|
|
|
static const u16 NCT6106_REG_FAN_STEP_UP_TIME[] = { 0x114, 0x124, 0x134 };
|
|
|
|
static const u16 NCT6106_REG_FAN_STEP_DOWN_TIME[] = { 0x115, 0x125, 0x135 };
|
|
|
|
static const u16 NCT6106_REG_FAN_STOP_OUTPUT[] = { 0x116, 0x126, 0x136 };
|
|
|
|
static const u16 NCT6106_REG_FAN_START_OUTPUT[] = { 0x117, 0x127, 0x137 };
|
|
|
|
static const u16 NCT6106_REG_FAN_STOP_TIME[] = { 0x118, 0x128, 0x138 };
|
|
|
|
static const u16 NCT6106_REG_TOLERANCE_H[] = { 0x112, 0x122, 0x132 };
|
|
|
|
|
|
|
|
static const u16 NCT6106_REG_TARGET[] = { 0x111, 0x121, 0x131 };
|
|
|
|
|
|
|
|
static const u16 NCT6106_REG_WEIGHT_TEMP_SEL[] = { 0x168, 0x178, 0x188 };
|
|
|
|
static const u16 NCT6106_REG_WEIGHT_TEMP_STEP[] = { 0x169, 0x179, 0x189 };
|
|
|
|
static const u16 NCT6106_REG_WEIGHT_TEMP_STEP_TOL[] = { 0x16a, 0x17a, 0x18a };
|
2019-07-15 19:33:55 +03:00
|
|
|
static const u16 NCT6106_REG_WEIGHT_DUTY_STEP[] = { 0x16b, 0x17b, 0x18b };
|
2012-07-01 19:23:15 +04:00
|
|
|
static const u16 NCT6106_REG_WEIGHT_TEMP_BASE[] = { 0x16c, 0x17c, 0x18c };
|
|
|
|
static const u16 NCT6106_REG_WEIGHT_DUTY_BASE[] = { 0x16d, 0x17d, 0x18d };
|
|
|
|
|
|
|
|
static const u16 NCT6106_REG_AUTO_TEMP[] = { 0x160, 0x170, 0x180 };
|
|
|
|
static const u16 NCT6106_REG_AUTO_PWM[] = { 0x164, 0x174, 0x184 };
|
|
|
|
|
|
|
|
static const u16 NCT6106_REG_ALARM[NUM_REG_ALARM] = {
|
|
|
|
0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d };
|
|
|
|
|
|
|
|
static const s8 NCT6106_ALARM_BITS[] = {
|
|
|
|
0, 1, 2, 3, 4, 5, 7, 8, /* in0.. in7 */
|
|
|
|
9, -1, -1, -1, -1, -1, -1, /* in8..in14 */
|
|
|
|
-1, /* unused */
|
|
|
|
32, 33, 34, -1, -1, /* fan1..fan5 */
|
|
|
|
-1, -1, -1, /* unused */
|
|
|
|
16, 17, 18, 19, 20, 21, /* temp1..temp6 */
|
|
|
|
48, -1 /* intrusion0, intrusion1 */
|
|
|
|
};
|
|
|
|
|
2013-06-25 09:21:59 +04:00
|
|
|
static const u16 NCT6106_REG_BEEP[NUM_REG_BEEP] = {
|
|
|
|
0x3c0, 0x3c1, 0x3c2, 0x3c3, 0x3c4 };
|
|
|
|
|
|
|
|
static const s8 NCT6106_BEEP_BITS[] = {
|
|
|
|
0, 1, 2, 3, 4, 5, 7, 8, /* in0.. in7 */
|
|
|
|
9, 10, 11, 12, -1, -1, -1, /* in8..in14 */
|
|
|
|
32, /* global beep enable */
|
|
|
|
24, 25, 26, 27, 28, /* fan1..fan5 */
|
|
|
|
-1, -1, -1, /* unused */
|
|
|
|
16, 17, 18, 19, 20, 21, /* temp1..temp6 */
|
|
|
|
34, -1 /* intrusion0, intrusion1 */
|
|
|
|
};
|
|
|
|
|
2017-05-18 04:05:06 +03:00
|
|
|
static const u16 NCT6106_REG_TEMP_ALTERNATE[32] = {
|
|
|
|
[14] = 0x51,
|
|
|
|
[15] = 0x52,
|
|
|
|
[16] = 0x54,
|
|
|
|
};
|
2012-07-01 19:23:15 +04:00
|
|
|
|
2017-05-18 04:05:06 +03:00
|
|
|
static const u16 NCT6106_REG_TEMP_CRIT[32] = {
|
|
|
|
[11] = 0x204,
|
|
|
|
[12] = 0x205,
|
|
|
|
};
|
2012-07-01 19:23:15 +04:00
|
|
|
|
2022-01-13 19:46:29 +03:00
|
|
|
static const u16 NCT6106_REG_TSI_TEMP[] = { 0x59, 0x5b, 0x5d, 0x5f, 0x61, 0x63, 0x65, 0x67 };
|
|
|
|
|
2019-07-23 19:06:46 +03:00
|
|
|
/* NCT6112D/NCT6114D/NCT6116D specific data */
|
|
|
|
|
|
|
|
static const u16 NCT6116_REG_FAN[] = { 0x20, 0x22, 0x24, 0x26, 0x28 };
|
|
|
|
static const u16 NCT6116_REG_FAN_MIN[] = { 0xe0, 0xe2, 0xe4, 0xe6, 0xe8 };
|
|
|
|
static const u16 NCT6116_REG_FAN_PULSES[] = { 0xf6, 0xf6, 0xf6, 0xf6, 0xf5 };
|
|
|
|
static const u16 NCT6116_FAN_PULSE_SHIFT[] = { 0, 2, 4, 6, 6 };
|
|
|
|
|
|
|
|
static const u16 NCT6116_REG_PWM[] = { 0x119, 0x129, 0x139, 0x199, 0x1a9 };
|
|
|
|
static const u16 NCT6116_REG_FAN_MODE[] = { 0x113, 0x123, 0x133, 0x193, 0x1a3 };
|
|
|
|
static const u16 NCT6116_REG_TEMP_SEL[] = { 0x110, 0x120, 0x130, 0x190, 0x1a0 };
|
|
|
|
static const u16 NCT6116_REG_TEMP_SOURCE[] = {
|
|
|
|
0xb0, 0xb1, 0xb2 };
|
|
|
|
|
|
|
|
static const u16 NCT6116_REG_CRITICAL_TEMP[] = {
|
|
|
|
0x11a, 0x12a, 0x13a, 0x19a, 0x1aa };
|
|
|
|
static const u16 NCT6116_REG_CRITICAL_TEMP_TOLERANCE[] = {
|
|
|
|
0x11b, 0x12b, 0x13b, 0x19b, 0x1ab };
|
|
|
|
|
|
|
|
static const u16 NCT6116_REG_CRITICAL_PWM_ENABLE[] = {
|
|
|
|
0x11c, 0x12c, 0x13c, 0x19c, 0x1ac };
|
|
|
|
static const u16 NCT6116_REG_CRITICAL_PWM[] = {
|
|
|
|
0x11d, 0x12d, 0x13d, 0x19d, 0x1ad };
|
|
|
|
|
|
|
|
static const u16 NCT6116_REG_FAN_STEP_UP_TIME[] = {
|
|
|
|
0x114, 0x124, 0x134, 0x194, 0x1a4 };
|
|
|
|
static const u16 NCT6116_REG_FAN_STEP_DOWN_TIME[] = {
|
|
|
|
0x115, 0x125, 0x135, 0x195, 0x1a5 };
|
|
|
|
static const u16 NCT6116_REG_FAN_STOP_OUTPUT[] = {
|
|
|
|
0x116, 0x126, 0x136, 0x196, 0x1a6 };
|
|
|
|
static const u16 NCT6116_REG_FAN_START_OUTPUT[] = {
|
|
|
|
0x117, 0x127, 0x137, 0x197, 0x1a7 };
|
|
|
|
static const u16 NCT6116_REG_FAN_STOP_TIME[] = {
|
|
|
|
0x118, 0x128, 0x138, 0x198, 0x1a8 };
|
|
|
|
static const u16 NCT6116_REG_TOLERANCE_H[] = {
|
|
|
|
0x112, 0x122, 0x132, 0x192, 0x1a2 };
|
|
|
|
|
|
|
|
static const u16 NCT6116_REG_TARGET[] = {
|
|
|
|
0x111, 0x121, 0x131, 0x191, 0x1a1 };
|
|
|
|
|
|
|
|
static const u16 NCT6116_REG_AUTO_TEMP[] = {
|
|
|
|
0x160, 0x170, 0x180, 0x1d0, 0x1e0 };
|
|
|
|
static const u16 NCT6116_REG_AUTO_PWM[] = {
|
|
|
|
0x164, 0x174, 0x184, 0x1d4, 0x1e4 };
|
|
|
|
|
|
|
|
static const s8 NCT6116_ALARM_BITS[] = {
|
|
|
|
0, 1, 2, 3, 4, 5, 7, 8, /* in0.. in7 */
|
|
|
|
9, -1, -1, -1, -1, -1, -1, /* in8..in9 */
|
|
|
|
-1, /* unused */
|
|
|
|
32, 33, 34, 35, 36, /* fan1..fan5 */
|
|
|
|
-1, -1, -1, /* unused */
|
|
|
|
16, 17, 18, -1, -1, -1, /* temp1..temp6 */
|
|
|
|
48, -1 /* intrusion0, intrusion1 */
|
|
|
|
};
|
|
|
|
|
|
|
|
static const s8 NCT6116_BEEP_BITS[] = {
|
|
|
|
0, 1, 2, 3, 4, 5, 7, 8, /* in0.. in7 */
|
|
|
|
9, 10, 11, 12, -1, -1, -1, /* in8..in14 */
|
|
|
|
32, /* global beep enable */
|
|
|
|
24, 25, 26, 27, 28, /* fan1..fan5 */
|
|
|
|
-1, -1, -1, /* unused */
|
|
|
|
16, 17, 18, -1, -1, -1, /* temp1..temp6 */
|
|
|
|
34, -1 /* intrusion0, intrusion1 */
|
|
|
|
};
|
|
|
|
|
2022-01-13 19:46:29 +03:00
|
|
|
static const u16 NCT6116_REG_TSI_TEMP[] = { 0x59, 0x5b };
|
|
|
|
|
2012-12-04 20:30:54 +04:00
|
|
|
static enum pwm_enable reg_to_pwm_enable(int pwm, int mode)
|
|
|
|
{
|
|
|
|
if (mode == 0 && pwm == 255)
|
|
|
|
return off;
|
|
|
|
return mode + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pwm_enable_to_reg(enum pwm_enable mode)
|
|
|
|
{
|
|
|
|
if (mode == off)
|
|
|
|
return 0;
|
|
|
|
return mode - 1;
|
|
|
|
}
|
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
/*
|
|
|
|
* Conversions
|
|
|
|
*/
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
/* 1 is DC mode, output in ms */
|
|
|
|
static unsigned int step_time_from_reg(u8 reg, u8 mode)
|
|
|
|
{
|
|
|
|
return mode ? 400 * reg : 100 * reg;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u8 step_time_to_reg(unsigned int msec, u8 mode)
|
|
|
|
{
|
|
|
|
return clamp_val((mode ? (msec + 200) / 400 :
|
|
|
|
(msec + 50) / 100), 1, 255);
|
|
|
|
}
|
|
|
|
|
2012-12-04 19:56:24 +04:00
|
|
|
static unsigned int fan_from_reg8(u16 reg, unsigned int divreg)
|
|
|
|
{
|
|
|
|
if (reg == 0 || reg == 255)
|
|
|
|
return 0;
|
|
|
|
return 1350000U / (reg << divreg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int fan_from_reg13(u16 reg, unsigned int divreg)
|
|
|
|
{
|
|
|
|
if ((reg & 0xff1f) == 0xff1f)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
reg = (reg & 0x1f) | ((reg & 0xff00) >> 3);
|
|
|
|
|
|
|
|
if (reg == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return 1350000U / reg;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int fan_from_reg16(u16 reg, unsigned int divreg)
|
|
|
|
{
|
|
|
|
if (reg == 0 || reg == 0xffff)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Even though the registers are 16 bit wide, the fan divisor
|
|
|
|
* still applies.
|
|
|
|
*/
|
|
|
|
return 1350000U / (reg << divreg);
|
|
|
|
}
|
|
|
|
|
2018-09-14 06:01:12 +03:00
|
|
|
static unsigned int fan_from_reg_rpm(u16 reg, unsigned int divreg)
|
|
|
|
{
|
|
|
|
return reg;
|
|
|
|
}
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
static u16 fan_to_reg(u32 fan, unsigned int divreg)
|
|
|
|
{
|
|
|
|
if (!fan)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return (1350000U / fan) >> divreg;
|
|
|
|
}
|
|
|
|
|
2012-12-04 19:56:24 +04:00
|
|
|
static inline unsigned int
|
|
|
|
div_from_reg(u8 reg)
|
|
|
|
{
|
2017-05-18 04:40:10 +03:00
|
|
|
return BIT(reg);
|
2012-12-04 19:56:24 +04:00
|
|
|
}
|
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
/*
|
|
|
|
* Some of the voltage inputs have internal scaling, the tables below
|
|
|
|
* contain 8 (the ADC LSB in mV) * scaling factor * 100
|
|
|
|
*/
|
|
|
|
static const u16 scale_in[15] = {
|
|
|
|
800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800, 800, 800, 800,
|
|
|
|
800, 800
|
|
|
|
};
|
|
|
|
|
2023-07-19 22:28:48 +03:00
|
|
|
/*
|
|
|
|
* NCT6798 scaling:
|
|
|
|
* CPUVC, IN1, AVSB, 3VCC, IN0, IN8, IN4, 3VSB, VBAT, VTT, IN5, IN6, IN2,
|
|
|
|
* IN3, IN7
|
|
|
|
* Additional scales to be added later: IN9 (800), VHIF (1600)
|
|
|
|
*/
|
|
|
|
static const u16 scale_in_6798[15] = {
|
|
|
|
800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 1600, 1600, 1600, 800,
|
|
|
|
800, 800
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline long in_from_reg(u8 reg, u8 nr, const u16 *scales)
|
2012-05-21 06:29:48 +04:00
|
|
|
{
|
2023-07-19 22:28:48 +03:00
|
|
|
return DIV_ROUND_CLOSEST(reg * scales[nr], 100);
|
2012-05-21 06:29:48 +04:00
|
|
|
}
|
|
|
|
|
2023-07-19 22:28:48 +03:00
|
|
|
static inline u8 in_to_reg(u32 val, u8 nr, const u16 *scales)
|
2012-05-21 06:29:48 +04:00
|
|
|
{
|
2023-07-19 22:28:48 +03:00
|
|
|
return clamp_val(DIV_ROUND_CLOSEST(val * 100, scales[nr]), 0, 255);
|
2012-05-21 06:29:48 +04:00
|
|
|
}
|
|
|
|
|
2022-01-13 19:46:29 +03:00
|
|
|
/* TSI temperatures are in 8.3 format */
|
|
|
|
static inline unsigned int tsi_temp_from_reg(unsigned int reg)
|
|
|
|
{
|
|
|
|
return (reg >> 5) * 125;
|
|
|
|
}
|
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
/*
|
|
|
|
* Data structures and manipulation thereof
|
|
|
|
*/
|
|
|
|
|
2013-03-18 20:22:50 +04:00
|
|
|
struct sensor_device_template {
|
|
|
|
struct device_attribute dev_attr;
|
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
u8 nr;
|
|
|
|
u8 index;
|
|
|
|
} s;
|
|
|
|
int index;
|
|
|
|
} u;
|
|
|
|
bool s2; /* true if both index and nr are used */
|
|
|
|
};
|
|
|
|
|
|
|
|
struct sensor_device_attr_u {
|
|
|
|
union {
|
|
|
|
struct sensor_device_attribute a1;
|
|
|
|
struct sensor_device_attribute_2 a2;
|
|
|
|
} u;
|
|
|
|
char name[32];
|
|
|
|
};
|
|
|
|
|
|
|
|
#define __TEMPLATE_ATTR(_template, _mode, _show, _store) { \
|
|
|
|
.attr = {.name = _template, .mode = _mode }, \
|
|
|
|
.show = _show, \
|
|
|
|
.store = _store, \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, _index) \
|
|
|
|
{ .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \
|
|
|
|
.u.index = _index, \
|
|
|
|
.s2 = false }
|
|
|
|
|
|
|
|
#define SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \
|
|
|
|
_nr, _index) \
|
|
|
|
{ .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store), \
|
|
|
|
.u.s.index = _index, \
|
|
|
|
.u.s.nr = _nr, \
|
|
|
|
.s2 = true }
|
|
|
|
|
|
|
|
#define SENSOR_TEMPLATE(_name, _template, _mode, _show, _store, _index) \
|
|
|
|
static struct sensor_device_template sensor_dev_template_##_name \
|
|
|
|
= SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, \
|
|
|
|
_index)
|
|
|
|
|
|
|
|
#define SENSOR_TEMPLATE_2(_name, _template, _mode, _show, _store, \
|
|
|
|
_nr, _index) \
|
|
|
|
static struct sensor_device_template sensor_dev_template_##_name \
|
|
|
|
= SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store, \
|
|
|
|
_nr, _index)
|
|
|
|
|
|
|
|
struct sensor_template_group {
|
|
|
|
struct sensor_device_template **templates;
|
|
|
|
umode_t (*is_visible)(struct kobject *, struct attribute *, int);
|
|
|
|
int base;
|
|
|
|
};
|
|
|
|
|
2022-04-27 04:01:50 +03:00
|
|
|
static int nct6775_add_template_attr_group(struct device *dev, struct nct6775_data *data,
|
|
|
|
const struct sensor_template_group *tg, int repeat)
|
2013-03-18 20:22:50 +04:00
|
|
|
{
|
|
|
|
struct attribute_group *group;
|
|
|
|
struct sensor_device_attr_u *su;
|
|
|
|
struct sensor_device_attribute *a;
|
|
|
|
struct sensor_device_attribute_2 *a2;
|
|
|
|
struct attribute **attrs;
|
|
|
|
struct sensor_device_template **t;
|
2013-10-19 12:55:15 +04:00
|
|
|
int i, count;
|
2013-03-18 20:22:50 +04:00
|
|
|
|
|
|
|
if (repeat <= 0)
|
2022-04-27 04:01:50 +03:00
|
|
|
return -EINVAL;
|
2013-03-18 20:22:50 +04:00
|
|
|
|
|
|
|
t = tg->templates;
|
|
|
|
for (count = 0; *t; t++, count++)
|
|
|
|
;
|
|
|
|
|
|
|
|
if (count == 0)
|
2022-04-27 04:01:50 +03:00
|
|
|
return -EINVAL;
|
2013-03-18 20:22:50 +04:00
|
|
|
|
|
|
|
group = devm_kzalloc(dev, sizeof(*group), GFP_KERNEL);
|
|
|
|
if (group == NULL)
|
2022-04-27 04:01:50 +03:00
|
|
|
return -ENOMEM;
|
2013-03-18 20:22:50 +04:00
|
|
|
|
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
|
|
|
attrs = devm_kcalloc(dev, repeat * count + 1, sizeof(*attrs),
|
2013-03-18 20:22:50 +04:00
|
|
|
GFP_KERNEL);
|
|
|
|
if (attrs == NULL)
|
2022-04-27 04:01:50 +03:00
|
|
|
return -ENOMEM;
|
2013-03-18 20:22:50 +04:00
|
|
|
|
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
|
|
|
su = devm_kzalloc(dev, array3_size(repeat, count, sizeof(*su)),
|
2013-03-18 20:22:50 +04:00
|
|
|
GFP_KERNEL);
|
|
|
|
if (su == NULL)
|
2022-04-27 04:01:50 +03:00
|
|
|
return -ENOMEM;
|
2013-03-18 20:22:50 +04:00
|
|
|
|
|
|
|
group->attrs = attrs;
|
|
|
|
group->is_visible = tg->is_visible;
|
|
|
|
|
|
|
|
for (i = 0; i < repeat; i++) {
|
|
|
|
t = tg->templates;
|
2013-10-19 12:55:15 +04:00
|
|
|
while (*t != NULL) {
|
2013-03-18 20:22:50 +04:00
|
|
|
snprintf(su->name, sizeof(su->name),
|
|
|
|
(*t)->dev_attr.attr.name, tg->base + i);
|
|
|
|
if ((*t)->s2) {
|
|
|
|
a2 = &su->u.a2;
|
2015-05-28 19:08:09 +03:00
|
|
|
sysfs_attr_init(&a2->dev_attr.attr);
|
2013-03-18 20:22:50 +04:00
|
|
|
a2->dev_attr.attr.name = su->name;
|
|
|
|
a2->nr = (*t)->u.s.nr + i;
|
|
|
|
a2->index = (*t)->u.s.index;
|
|
|
|
a2->dev_attr.attr.mode =
|
|
|
|
(*t)->dev_attr.attr.mode;
|
|
|
|
a2->dev_attr.show = (*t)->dev_attr.show;
|
|
|
|
a2->dev_attr.store = (*t)->dev_attr.store;
|
|
|
|
*attrs = &a2->dev_attr.attr;
|
|
|
|
} else {
|
|
|
|
a = &su->u.a1;
|
2015-05-28 19:08:09 +03:00
|
|
|
sysfs_attr_init(&a->dev_attr.attr);
|
2013-03-18 20:22:50 +04:00
|
|
|
a->dev_attr.attr.name = su->name;
|
|
|
|
a->index = (*t)->u.index + i;
|
|
|
|
a->dev_attr.attr.mode =
|
|
|
|
(*t)->dev_attr.attr.mode;
|
|
|
|
a->dev_attr.show = (*t)->dev_attr.show;
|
|
|
|
a->dev_attr.store = (*t)->dev_attr.store;
|
|
|
|
*attrs = &a->dev_attr.attr;
|
|
|
|
}
|
|
|
|
attrs++;
|
|
|
|
su++;
|
|
|
|
t++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-27 04:01:50 +03:00
|
|
|
return nct6775_add_attr_group(data, group);
|
2013-03-18 20:22:50 +04:00
|
|
|
}
|
|
|
|
|
2022-04-27 04:01:53 +03:00
|
|
|
bool nct6775_reg_is_word_sized(struct nct6775_data *data, u16 reg)
|
2012-05-21 06:29:48 +04:00
|
|
|
{
|
|
|
|
switch (data->kind) {
|
2012-07-01 19:23:15 +04:00
|
|
|
case nct6106:
|
|
|
|
return reg == 0x20 || reg == 0x22 || reg == 0x24 ||
|
2022-01-13 19:46:29 +03:00
|
|
|
(reg >= 0x59 && reg < 0x69 && (reg & 1)) ||
|
2012-07-01 19:23:15 +04:00
|
|
|
reg == 0xe0 || reg == 0xe2 || reg == 0xe4 ||
|
|
|
|
reg == 0x111 || reg == 0x121 || reg == 0x131;
|
2019-07-23 19:06:46 +03:00
|
|
|
case nct6116:
|
|
|
|
return reg == 0x20 || reg == 0x22 || reg == 0x24 ||
|
2022-01-13 19:46:29 +03:00
|
|
|
reg == 0x26 || reg == 0x28 || reg == 0x59 || reg == 0x5b ||
|
|
|
|
reg == 0xe0 || reg == 0xe2 || reg == 0xe4 || reg == 0xe6 ||
|
|
|
|
reg == 0xe8 || reg == 0x111 || reg == 0x121 || reg == 0x131 ||
|
|
|
|
reg == 0x191 || reg == 0x1a1;
|
2012-05-21 06:29:48 +04:00
|
|
|
case nct6775:
|
|
|
|
return (((reg & 0xff00) == 0x100 ||
|
|
|
|
(reg & 0xff00) == 0x200) &&
|
|
|
|
((reg & 0x00ff) == 0x50 ||
|
|
|
|
(reg & 0x00ff) == 0x53 ||
|
|
|
|
(reg & 0x00ff) == 0x55)) ||
|
|
|
|
(reg & 0xfff0) == 0x630 ||
|
|
|
|
reg == 0x640 || reg == 0x642 ||
|
2022-01-13 19:46:29 +03:00
|
|
|
reg == 0x662 || reg == 0x669 ||
|
2012-05-21 06:29:48 +04:00
|
|
|
((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
|
|
|
|
reg == 0x73 || reg == 0x75 || reg == 0x77;
|
|
|
|
case nct6776:
|
|
|
|
return (((reg & 0xff00) == 0x100 ||
|
|
|
|
(reg & 0xff00) == 0x200) &&
|
|
|
|
((reg & 0x00ff) == 0x50 ||
|
|
|
|
(reg & 0x00ff) == 0x53 ||
|
|
|
|
(reg & 0x00ff) == 0x55)) ||
|
|
|
|
(reg & 0xfff0) == 0x630 ||
|
|
|
|
reg == 0x402 ||
|
2022-01-13 19:46:29 +03:00
|
|
|
(reg >= 0x409 && reg < 0x419 && (reg & 1)) ||
|
2012-05-21 06:29:48 +04:00
|
|
|
reg == 0x640 || reg == 0x642 ||
|
|
|
|
((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
|
|
|
|
reg == 0x73 || reg == 0x75 || reg == 0x77;
|
|
|
|
case nct6779:
|
2013-06-25 09:28:28 +04:00
|
|
|
case nct6791:
|
2014-11-16 20:50:04 +03:00
|
|
|
case nct6792:
|
2015-08-31 05:45:19 +03:00
|
|
|
case nct6793:
|
2017-05-18 04:19:18 +03:00
|
|
|
case nct6795:
|
2018-02-22 00:09:39 +03:00
|
|
|
case nct6796:
|
2018-09-19 06:48:29 +03:00
|
|
|
case nct6797:
|
2018-09-20 06:26:16 +03:00
|
|
|
case nct6798:
|
2022-12-28 16:57:44 +03:00
|
|
|
case nct6799:
|
2012-05-21 06:29:48 +04:00
|
|
|
return reg == 0x150 || reg == 0x153 || reg == 0x155 ||
|
2018-09-14 06:01:12 +03:00
|
|
|
(reg & 0xfff0) == 0x4c0 ||
|
2012-05-21 06:29:48 +04:00
|
|
|
reg == 0x402 ||
|
2022-01-13 19:46:29 +03:00
|
|
|
(reg >= 0x409 && reg < 0x419 && (reg & 1)) ||
|
2012-05-21 06:29:48 +04:00
|
|
|
reg == 0x63a || reg == 0x63c || reg == 0x63e ||
|
2018-02-22 00:09:37 +03:00
|
|
|
reg == 0x640 || reg == 0x642 || reg == 0x64a ||
|
2018-09-17 15:23:58 +03:00
|
|
|
reg == 0x64c ||
|
2012-05-21 06:29:48 +04:00
|
|
|
reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 ||
|
2014-11-16 20:50:04 +03:00
|
|
|
reg == 0x7b || reg == 0x7d;
|
2012-05-21 06:29:48 +04:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2022-04-27 04:01:53 +03:00
|
|
|
EXPORT_SYMBOL_GPL(nct6775_reg_is_word_sized);
|
2012-05-21 06:29:48 +04:00
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
/* We left-align 8-bit temperature values to make the code simpler */
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
static int nct6775_read_temp(struct nct6775_data *data, u16 reg, u16 *val)
|
2012-12-04 15:26:05 +04:00
|
|
|
{
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int err;
|
|
|
|
|
|
|
|
err = nct6775_read_value(data, reg, val);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2022-04-27 04:01:53 +03:00
|
|
|
if (!nct6775_reg_is_word_sized(data, reg))
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
*val <<= 8;
|
2012-12-04 15:26:05 +04:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return 0;
|
2012-12-04 15:26:05 +04:00
|
|
|
}
|
|
|
|
|
2012-12-04 19:56:24 +04:00
|
|
|
/* This function assumes that the caller holds data->update_lock */
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
static int nct6775_write_fan_div(struct nct6775_data *data, int nr)
|
2012-12-04 19:56:24 +04:00
|
|
|
{
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
u16 reg;
|
|
|
|
int err;
|
|
|
|
u16 fandiv_reg = nr < 2 ? NCT6775_REG_FANDIV1 : NCT6775_REG_FANDIV2;
|
|
|
|
unsigned int oddshift = (nr & 1) * 4; /* masks shift by four if nr is odd */
|
2012-12-04 19:56:24 +04:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, fandiv_reg, ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
reg &= 0x70 >> oddshift;
|
2023-01-03 00:28:57 +03:00
|
|
|
reg |= (data->fan_div[nr] & 0x7) << oddshift;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return nct6775_write_value(data, fandiv_reg, reg);
|
2012-12-04 19:56:24 +04:00
|
|
|
}
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
static int nct6775_write_fan_div_common(struct nct6775_data *data, int nr)
|
2012-12-04 19:56:24 +04:00
|
|
|
{
|
|
|
|
if (data->kind == nct6775)
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return nct6775_write_fan_div(data, nr);
|
|
|
|
return 0;
|
2012-12-04 19:56:24 +04:00
|
|
|
}
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
static int nct6775_update_fan_div(struct nct6775_data *data)
|
2012-12-04 19:56:24 +04:00
|
|
|
{
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int err;
|
|
|
|
u16 i;
|
2012-12-04 19:56:24 +04:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, NCT6775_REG_FANDIV1, &i);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 19:56:24 +04:00
|
|
|
data->fan_div[0] = i & 0x7;
|
|
|
|
data->fan_div[1] = (i & 0x70) >> 4;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, NCT6775_REG_FANDIV2, &i);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 19:56:24 +04:00
|
|
|
data->fan_div[2] = i & 0x7;
|
2017-05-18 04:40:10 +03:00
|
|
|
if (data->has_fan & BIT(3))
|
2012-12-04 19:56:24 +04:00
|
|
|
data->fan_div[3] = (i & 0x70) >> 4;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
|
|
|
|
return 0;
|
2012-12-04 19:56:24 +04:00
|
|
|
}
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
static int nct6775_update_fan_div_common(struct nct6775_data *data)
|
2012-12-04 19:56:24 +04:00
|
|
|
{
|
|
|
|
if (data->kind == nct6775)
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return nct6775_update_fan_div(data);
|
|
|
|
return 0;
|
2012-12-04 19:56:24 +04:00
|
|
|
}
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
static int nct6775_init_fan_div(struct nct6775_data *data)
|
2012-12-04 19:56:24 +04:00
|
|
|
{
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int i, err;
|
|
|
|
|
|
|
|
err = nct6775_update_fan_div_common(data);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 19:56:24 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* For all fans, start with highest divider value if the divider
|
|
|
|
* register is not initialized. This ensures that we get a
|
|
|
|
* reading from the fan count register, even if it is not optimal.
|
|
|
|
* We'll compute a better divider later on.
|
|
|
|
*/
|
2013-04-09 16:04:00 +04:00
|
|
|
for (i = 0; i < ARRAY_SIZE(data->fan_div); i++) {
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!(data->has_fan & BIT(i)))
|
2012-12-04 19:56:24 +04:00
|
|
|
continue;
|
|
|
|
if (data->fan_div[i] == 0) {
|
|
|
|
data->fan_div[i] = 7;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_fan_div_common(data, i);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 19:56:24 +04:00
|
|
|
}
|
|
|
|
}
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
|
|
|
|
return 0;
|
2012-12-04 19:56:24 +04:00
|
|
|
}
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
static int nct6775_init_fan_common(struct device *dev,
|
|
|
|
struct nct6775_data *data)
|
2012-12-04 19:56:24 +04:00
|
|
|
{
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int i, err;
|
|
|
|
u16 reg;
|
2012-12-04 19:56:24 +04:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (data->has_fan_div) {
|
|
|
|
err = nct6775_init_fan_div(data);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
2012-12-04 19:56:24 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If fan_min is not set (0), set it to 0xff to disable it. This
|
|
|
|
* prevents the unnecessary warning when fanX_min is reported as 0.
|
|
|
|
*/
|
2013-04-09 16:04:00 +04:00
|
|
|
for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
|
2017-05-18 04:40:10 +03:00
|
|
|
if (data->has_fan_min & BIT(i)) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_FAN_MIN[i], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
if (!reg) {
|
|
|
|
err = nct6775_write_value(data, data->REG_FAN_MIN[i],
|
|
|
|
data->has_fan_div ? 0xff : 0xff1f);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
2012-12-04 19:56:24 +04:00
|
|
|
}
|
|
|
|
}
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
|
|
|
|
return 0;
|
2012-12-04 19:56:24 +04:00
|
|
|
}
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
static int nct6775_select_fan_div(struct device *dev,
|
|
|
|
struct nct6775_data *data, int nr, u16 reg)
|
2012-12-04 19:56:24 +04:00
|
|
|
{
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int err;
|
2012-12-04 19:56:24 +04:00
|
|
|
u8 fan_div = data->fan_div[nr];
|
|
|
|
u16 fan_min;
|
|
|
|
|
|
|
|
if (!data->has_fan_div)
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return 0;
|
2012-12-04 19:56:24 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If we failed to measure the fan speed, or the reported value is not
|
|
|
|
* in the optimal range, and the clock divider can be modified,
|
|
|
|
* let's try that for next time.
|
|
|
|
*/
|
|
|
|
if (reg == 0x00 && fan_div < 0x07)
|
|
|
|
fan_div++;
|
|
|
|
else if (reg != 0x00 && reg < 0x30 && fan_div > 0)
|
|
|
|
fan_div--;
|
|
|
|
|
|
|
|
if (fan_div != data->fan_div[nr]) {
|
|
|
|
dev_dbg(dev, "Modifying fan%d clock divider from %u to %u\n",
|
|
|
|
nr + 1, div_from_reg(data->fan_div[nr]),
|
|
|
|
div_from_reg(fan_div));
|
|
|
|
|
|
|
|
/* Preserve min limit if possible */
|
2017-05-18 04:40:10 +03:00
|
|
|
if (data->has_fan_min & BIT(nr)) {
|
2012-12-04 19:56:24 +04:00
|
|
|
fan_min = data->fan_min[nr];
|
|
|
|
if (fan_div > data->fan_div[nr]) {
|
|
|
|
if (fan_min != 255 && fan_min > 1)
|
|
|
|
fan_min >>= 1;
|
|
|
|
} else {
|
|
|
|
if (fan_min != 255) {
|
|
|
|
fan_min <<= 1;
|
|
|
|
if (fan_min > 254)
|
|
|
|
fan_min = 254;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (fan_min != data->fan_min[nr]) {
|
|
|
|
data->fan_min[nr] = fan_min;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_FAN_MIN[nr], fan_min);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 19:56:24 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
data->fan_div[nr] = fan_div;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_fan_div_common(data, nr);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 19:56:24 +04:00
|
|
|
}
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
|
|
|
|
return 0;
|
2012-12-04 19:56:24 +04:00
|
|
|
}
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
static int nct6775_update_pwm(struct device *dev)
|
2012-12-04 20:30:54 +04:00
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int i, j, err;
|
|
|
|
u16 fanmodecfg, reg;
|
2012-12-04 20:30:54 +04:00
|
|
|
bool duty_is_dc;
|
|
|
|
|
|
|
|
for (i = 0; i < data->pwm_num; i++) {
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!(data->has_pwm & BIT(i)))
|
2012-12-04 20:30:54 +04:00
|
|
|
continue;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_PWM_MODE[i], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
duty_is_dc = data->REG_PWM_MODE[i] && (reg & data->PWM_MODE_MASK[i]);
|
2018-03-27 05:50:31 +03:00
|
|
|
data->pwm_mode[i] = !duty_is_dc;
|
2012-12-04 20:30:54 +04:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_FAN_MODE[i], &fanmodecfg);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 20:30:54 +04:00
|
|
|
for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) {
|
|
|
|
if (data->REG_PWM[j] && data->REG_PWM[j][i]) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_PWM[j][i], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
data->pwm[j][i] = reg;
|
2012-12-04 20:30:54 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
data->pwm_enable[i] = reg_to_pwm_enable(data->pwm[0][i],
|
|
|
|
(fanmodecfg >> 4) & 7);
|
2012-12-04 21:04:52 +04:00
|
|
|
|
|
|
|
if (!data->temp_tolerance[0][i] ||
|
|
|
|
data->pwm_enable[i] != speed_cruise)
|
|
|
|
data->temp_tolerance[0][i] = fanmodecfg & 0x0f;
|
|
|
|
if (!data->target_speed_tolerance[i] ||
|
|
|
|
data->pwm_enable[i] == speed_cruise) {
|
|
|
|
u8 t = fanmodecfg & 0x0f;
|
2014-11-16 21:00:06 +03:00
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
if (data->REG_TOLERANCE_H) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_TOLERANCE_H[i], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
t |= (reg & 0x70) >> 1;
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
data->target_speed_tolerance[i] = t;
|
|
|
|
}
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_CRITICAL_TEMP_TOLERANCE[i], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
data->temp_tolerance[1][i] = reg;
|
2012-12-04 21:04:52 +04:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_TEMP_SEL[i], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->pwm_temp_sel[i] = reg & 0x1f;
|
|
|
|
/* If fan can stop, report floor as 0 */
|
|
|
|
if (reg & 0x80)
|
|
|
|
data->pwm[2][i] = 0;
|
2012-12-04 21:08:29 +04:00
|
|
|
|
2013-11-14 00:47:17 +04:00
|
|
|
if (!data->REG_WEIGHT_TEMP_SEL[i])
|
|
|
|
continue;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[i], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 21:08:29 +04:00
|
|
|
data->pwm_weight_temp_sel[i] = reg & 0x1f;
|
|
|
|
/* If weight is disabled, report weight source as 0 */
|
2018-09-05 10:46:27 +03:00
|
|
|
if (!(reg & 0x80))
|
2012-12-04 21:08:29 +04:00
|
|
|
data->pwm_weight_temp_sel[i] = 0;
|
|
|
|
|
|
|
|
/* Weight temp data */
|
2013-04-09 16:04:00 +04:00
|
|
|
for (j = 0; j < ARRAY_SIZE(data->weight_temp); j++) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_WEIGHT_TEMP[j][i], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
data->weight_temp[j][i] = reg;
|
2012-12-04 21:08:29 +04:00
|
|
|
}
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
|
|
|
|
return 0;
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
static int nct6775_update_pwm_limits(struct device *dev)
|
2012-12-04 21:04:52 +04:00
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int i, j, err;
|
|
|
|
u16 reg, reg_t;
|
2012-12-04 21:04:52 +04:00
|
|
|
|
|
|
|
for (i = 0; i < data->pwm_num; i++) {
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!(data->has_pwm & BIT(i)))
|
2012-12-04 21:04:52 +04:00
|
|
|
continue;
|
|
|
|
|
2013-04-09 16:04:00 +04:00
|
|
|
for (j = 0; j < ARRAY_SIZE(data->fan_time); j++) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_FAN_TIME[j][i], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
data->fan_time[j][i] = reg;
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_TARGET[i], ®_t);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
/* Update only in matching mode or if never updated */
|
|
|
|
if (!data->target_temp[i] ||
|
|
|
|
data->pwm_enable[i] == thermal_cruise)
|
|
|
|
data->target_temp[i] = reg_t & data->target_temp_mask;
|
|
|
|
if (!data->target_speed[i] ||
|
|
|
|
data->pwm_enable[i] == speed_cruise) {
|
|
|
|
if (data->REG_TOLERANCE_H) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_TOLERANCE_H[i], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
reg_t |= (reg & 0x0f) << 8;
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
data->target_speed[i] = reg_t;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (j = 0; j < data->auto_pwm_num; j++) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, NCT6775_AUTO_PWM(data, i, j), ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
data->auto_pwm[i][j] = reg;
|
|
|
|
|
|
|
|
err = nct6775_read_value(data, NCT6775_AUTO_TEMP(data, i, j), ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
data->auto_temp[i][j] = reg;
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* critical auto_pwm temperature data */
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_CRITICAL_TEMP[i], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
data->auto_temp[i][data->auto_pwm_num] = reg;
|
2012-12-04 21:04:52 +04:00
|
|
|
|
|
|
|
switch (data->kind) {
|
|
|
|
case nct6775:
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, NCT6775_REG_CRITICAL_ENAB[i], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->auto_pwm[i][data->auto_pwm_num] =
|
|
|
|
(reg & 0x02) ? 0xff : 0x00;
|
|
|
|
break;
|
|
|
|
case nct6776:
|
|
|
|
data->auto_pwm[i][data->auto_pwm_num] = 0xff;
|
|
|
|
break;
|
2012-07-01 19:23:15 +04:00
|
|
|
case nct6106:
|
2019-07-23 19:06:46 +03:00
|
|
|
case nct6116:
|
2012-12-04 21:04:52 +04:00
|
|
|
case nct6779:
|
2013-06-25 09:28:28 +04:00
|
|
|
case nct6791:
|
2014-11-16 20:50:04 +03:00
|
|
|
case nct6792:
|
2015-08-31 05:45:19 +03:00
|
|
|
case nct6793:
|
2017-05-18 04:19:18 +03:00
|
|
|
case nct6795:
|
2018-02-22 00:09:39 +03:00
|
|
|
case nct6796:
|
2018-09-19 06:48:29 +03:00
|
|
|
case nct6797:
|
2018-09-20 06:26:16 +03:00
|
|
|
case nct6798:
|
2022-12-28 16:57:44 +03:00
|
|
|
case nct6799:
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_CRITICAL_PWM_ENABLE[i], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
if (reg & data->CRITICAL_PWM_ENABLE_MASK) {
|
|
|
|
err = nct6775_read_value(data, data->REG_CRITICAL_PWM[i], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
} else {
|
2012-07-01 19:23:15 +04:00
|
|
|
reg = 0xff;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
}
|
2012-07-01 19:23:15 +04:00
|
|
|
data->auto_pwm[i][data->auto_pwm_num] = reg;
|
2012-12-04 21:04:52 +04:00
|
|
|
break;
|
|
|
|
}
|
2012-12-04 20:30:54 +04:00
|
|
|
}
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
|
|
|
|
return 0;
|
2012-12-04 20:30:54 +04:00
|
|
|
}
|
|
|
|
|
2022-08-10 08:26:46 +03:00
|
|
|
struct nct6775_data *nct6775_update_device(struct device *dev)
|
2012-05-21 06:29:48 +04:00
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int i, j, err = 0;
|
|
|
|
u16 reg;
|
2012-05-21 06:29:48 +04:00
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
|
2013-04-21 20:13:28 +04:00
|
|
|
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|
2012-05-21 06:29:48 +04:00
|
|
|
|| !data->valid) {
|
2012-12-04 19:56:24 +04:00
|
|
|
/* Fan clock dividers */
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_update_fan_div_common(data);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
2012-12-04 19:56:24 +04:00
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
/* Measured voltages and limits */
|
|
|
|
for (i = 0; i < data->in_num; i++) {
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!(data->have_in & BIT(i)))
|
2012-05-21 06:29:48 +04:00
|
|
|
continue;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_VIN[i], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
data->in[i][0] = reg;
|
|
|
|
|
|
|
|
err = nct6775_read_value(data, data->REG_IN_MINMAX[0][i], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
data->in[i][1] = reg;
|
|
|
|
|
|
|
|
err = nct6775_read_value(data, data->REG_IN_MINMAX[1][i], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
data->in[i][2] = reg;
|
2012-05-21 06:29:48 +04:00
|
|
|
}
|
|
|
|
|
2012-12-04 19:56:24 +04:00
|
|
|
/* Measured fan speeds and limits */
|
2013-04-09 16:04:00 +04:00
|
|
|
for (i = 0; i < ARRAY_SIZE(data->rpm); i++) {
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!(data->has_fan & BIT(i)))
|
2012-12-04 19:56:24 +04:00
|
|
|
continue;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_FAN[i], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
2012-12-04 19:56:24 +04:00
|
|
|
data->rpm[i] = data->fan_from_reg(reg,
|
|
|
|
data->fan_div[i]);
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (data->has_fan_min & BIT(i)) {
|
|
|
|
err = nct6775_read_value(data, data->REG_FAN_MIN[i], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
data->fan_min[i] = reg;
|
|
|
|
}
|
2018-09-06 19:47:51 +03:00
|
|
|
|
|
|
|
if (data->REG_FAN_PULSES[i]) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_FAN_PULSES[i], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
data->fan_pulses[i] = (reg >> data->FAN_PULSE_SHIFT[i]) & 0x03;
|
2018-09-06 19:47:51 +03:00
|
|
|
}
|
2012-12-04 19:56:24 +04:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_select_fan_div(dev, data, i, reg);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
2012-12-04 19:56:24 +04:00
|
|
|
}
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_update_pwm(dev);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
err = nct6775_update_pwm_limits(dev);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
2012-12-04 20:30:54 +04:00
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
/* Measured temperatures and limits */
|
|
|
|
for (i = 0; i < NUM_TEMP; i++) {
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!(data->have_temp & BIT(i)))
|
2012-12-04 15:26:05 +04:00
|
|
|
continue;
|
2013-04-09 16:04:00 +04:00
|
|
|
for (j = 0; j < ARRAY_SIZE(data->reg_temp); j++) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (data->reg_temp[j][i]) {
|
|
|
|
err = nct6775_read_temp(data, data->reg_temp[j][i], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
data->temp[j][i] = reg;
|
|
|
|
}
|
2012-12-04 15:26:05 +04:00
|
|
|
}
|
2013-09-11 21:35:47 +04:00
|
|
|
if (i >= NUM_TEMP_FIXED ||
|
2017-05-18 04:40:10 +03:00
|
|
|
!(data->have_temp_fixed & BIT(i)))
|
2012-12-04 15:26:05 +04:00
|
|
|
continue;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_TEMP_OFFSET[i], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
data->temp_offset[i] = reg;
|
2012-12-04 15:26:05 +04:00
|
|
|
}
|
|
|
|
|
2022-01-13 19:46:29 +03:00
|
|
|
for (i = 0; i < NUM_TSI_TEMP; i++) {
|
|
|
|
if (!(data->have_tsi_temp & BIT(i)))
|
|
|
|
continue;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_TSI_TEMP[i], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
data->tsi_temp[i] = reg;
|
2022-01-13 19:46:29 +03:00
|
|
|
}
|
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
data->alarms = 0;
|
|
|
|
for (i = 0; i < NUM_REG_ALARM; i++) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
u16 alarm;
|
2014-11-16 21:00:06 +03:00
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
if (!data->REG_ALARM[i])
|
|
|
|
continue;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_ALARM[i], &alarm);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
2012-05-21 06:29:48 +04:00
|
|
|
data->alarms |= ((u64)alarm) << (i << 3);
|
|
|
|
}
|
|
|
|
|
2013-06-25 09:21:59 +04:00
|
|
|
data->beeps = 0;
|
|
|
|
for (i = 0; i < NUM_REG_BEEP; i++) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
u16 beep;
|
2014-11-16 21:00:06 +03:00
|
|
|
|
2013-06-25 09:21:59 +04:00
|
|
|
if (!data->REG_BEEP[i])
|
|
|
|
continue;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_BEEP[i], &beep);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
2013-06-25 09:21:59 +04:00
|
|
|
data->beeps |= ((u64)beep) << (i << 3);
|
|
|
|
}
|
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
data->last_updated = jiffies;
|
|
|
|
data->valid = true;
|
|
|
|
}
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
out:
|
2012-05-21 06:29:48 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? ERR_PTR(err) : data;
|
2012-05-21 06:29:48 +04:00
|
|
|
}
|
2022-08-10 08:26:46 +03:00
|
|
|
EXPORT_SYMBOL_GPL(nct6775_update_device);
|
2012-05-21 06:29:48 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Sysfs callback functions
|
|
|
|
*/
|
|
|
|
static ssize_t
|
|
|
|
show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
int index = sattr->index;
|
2014-11-16 21:00:06 +03:00
|
|
|
int nr = sattr->nr;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2023-07-19 22:28:48 +03:00
|
|
|
return sprintf(buf, "%ld\n",
|
|
|
|
in_from_reg(data->in[nr][index], nr, data->scale_in));
|
2012-05-21 06:29:48 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf,
|
|
|
|
size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
int index = sattr->index;
|
2014-11-16 21:00:06 +03:00
|
|
|
int nr = sattr->nr;
|
2012-05-21 06:29:48 +04:00
|
|
|
unsigned long val;
|
2014-11-16 21:00:06 +03:00
|
|
|
int err;
|
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
2012-05-21 06:29:48 +04:00
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
mutex_lock(&data->update_lock);
|
2023-07-19 22:28:48 +03:00
|
|
|
data->in[nr][index] = in_to_reg(val, nr, data->scale_in);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_IN_MINMAX[index - 1][nr], data->in[nr][index]);
|
2012-05-21 06:29:48 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-05-21 06:29:48 +04:00
|
|
|
}
|
|
|
|
|
2022-04-27 04:01:53 +03:00
|
|
|
ssize_t
|
|
|
|
nct6775_show_alarm(struct device *dev, struct device_attribute *attr, char *buf)
|
2012-05-21 06:29:48 +04:00
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int nr;
|
|
|
|
|
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
2014-11-16 21:00:06 +03:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
nr = data->ALARM_BITS[sattr->index];
|
2012-05-21 06:29:48 +04:00
|
|
|
return sprintf(buf, "%u\n",
|
|
|
|
(unsigned int)((data->alarms >> nr) & 0x01));
|
|
|
|
}
|
2022-04-27 04:01:53 +03:00
|
|
|
EXPORT_SYMBOL_GPL(nct6775_show_alarm);
|
2012-05-21 06:29:48 +04:00
|
|
|
|
2013-06-23 03:15:31 +04:00
|
|
|
static int find_temp_source(struct nct6775_data *data, int index, int count)
|
|
|
|
{
|
|
|
|
int source = data->temp_src[index];
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int nr, err;
|
2013-06-23 03:15:31 +04:00
|
|
|
|
|
|
|
for (nr = 0; nr < count; nr++) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
u16 src;
|
2013-06-23 03:15:31 +04:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_TEMP_SOURCE[nr], &src);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
if ((src & 0x1f) == source)
|
2013-06-23 03:15:31 +04:00
|
|
|
return nr;
|
|
|
|
}
|
2013-09-11 21:32:18 +04:00
|
|
|
return -ENODEV;
|
2013-06-23 03:15:31 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
show_temp_alarm(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
unsigned int alarm = 0;
|
|
|
|
int nr;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2013-06-23 03:15:31 +04:00
|
|
|
/*
|
|
|
|
* For temperatures, there is no fixed mapping from registers to alarm
|
|
|
|
* bits. Alarm bits are determined by the temperature source mapping.
|
|
|
|
*/
|
|
|
|
nr = find_temp_source(data, sattr->index, data->num_temp_alarms);
|
|
|
|
if (nr >= 0) {
|
|
|
|
int bit = data->ALARM_BITS[nr + TEMP_ALARM_BASE];
|
2014-11-16 21:00:06 +03:00
|
|
|
|
2013-06-23 03:15:31 +04:00
|
|
|
alarm = (data->alarms >> bit) & 0x01;
|
|
|
|
}
|
|
|
|
return sprintf(buf, "%u\n", alarm);
|
|
|
|
}
|
|
|
|
|
2022-04-27 04:01:53 +03:00
|
|
|
ssize_t
|
|
|
|
nct6775_show_beep(struct device *dev, struct device_attribute *attr, char *buf)
|
2013-06-25 09:21:59 +04:00
|
|
|
{
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int nr;
|
|
|
|
|
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
|
|
|
nr = data->BEEP_BITS[sattr->index];
|
2013-06-25 09:21:59 +04:00
|
|
|
|
|
|
|
return sprintf(buf, "%u\n",
|
|
|
|
(unsigned int)((data->beeps >> nr) & 0x01));
|
|
|
|
}
|
2022-04-27 04:01:53 +03:00
|
|
|
EXPORT_SYMBOL_GPL(nct6775_show_beep);
|
2013-06-25 09:21:59 +04:00
|
|
|
|
2022-04-27 04:01:53 +03:00
|
|
|
ssize_t
|
|
|
|
nct6775_store_beep(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
|
2013-06-25 09:21:59 +04:00
|
|
|
{
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
int nr = data->BEEP_BITS[sattr->index];
|
|
|
|
int regindex = nr >> 3;
|
|
|
|
unsigned long val;
|
2014-11-16 21:00:06 +03:00
|
|
|
int err;
|
2013-06-25 09:21:59 +04:00
|
|
|
|
2014-11-16 21:00:06 +03:00
|
|
|
err = kstrtoul(buf, 10, &val);
|
2013-06-25 09:21:59 +04:00
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
if (val > 1)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
if (val)
|
|
|
|
data->beeps |= (1ULL << nr);
|
|
|
|
else
|
|
|
|
data->beeps &= ~(1ULL << nr);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_BEEP[regindex],
|
|
|
|
(data->beeps >> (regindex << 3)) & 0xff);
|
2013-06-25 09:21:59 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2013-06-25 09:21:59 +04:00
|
|
|
}
|
2022-04-27 04:01:53 +03:00
|
|
|
EXPORT_SYMBOL_GPL(nct6775_store_beep);
|
2013-06-25 09:21:59 +04:00
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
show_temp_beep(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
unsigned int beep = 0;
|
|
|
|
int nr;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2013-06-25 09:21:59 +04:00
|
|
|
/*
|
|
|
|
* For temperatures, there is no fixed mapping from registers to beep
|
|
|
|
* enable bits. Beep enable bits are determined by the temperature
|
|
|
|
* source mapping.
|
|
|
|
*/
|
|
|
|
nr = find_temp_source(data, sattr->index, data->num_temp_beeps);
|
|
|
|
if (nr >= 0) {
|
|
|
|
int bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE];
|
2014-11-16 21:00:06 +03:00
|
|
|
|
2013-06-25 09:21:59 +04:00
|
|
|
beep = (data->beeps >> bit) & 0x01;
|
|
|
|
}
|
|
|
|
return sprintf(buf, "%u\n", beep);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_temp_beep(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
int nr, bit, regindex;
|
|
|
|
unsigned long val;
|
2014-11-16 21:00:06 +03:00
|
|
|
int err;
|
2013-06-25 09:21:59 +04:00
|
|
|
|
2014-11-16 21:00:06 +03:00
|
|
|
err = kstrtoul(buf, 10, &val);
|
2013-06-25 09:21:59 +04:00
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
if (val > 1)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
nr = find_temp_source(data, sattr->index, data->num_temp_beeps);
|
|
|
|
if (nr < 0)
|
2013-09-11 21:32:18 +04:00
|
|
|
return nr;
|
2013-06-25 09:21:59 +04:00
|
|
|
|
|
|
|
bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE];
|
|
|
|
regindex = bit >> 3;
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
if (val)
|
|
|
|
data->beeps |= (1ULL << bit);
|
|
|
|
else
|
|
|
|
data->beeps &= ~(1ULL << bit);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_BEEP[regindex],
|
|
|
|
(data->beeps >> (regindex << 3)) & 0xff);
|
2013-06-25 09:21:59 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2013-06-25 09:21:59 +04:00
|
|
|
}
|
|
|
|
|
2013-03-18 20:22:50 +04:00
|
|
|
static umode_t nct6775_in_is_visible(struct kobject *kobj,
|
|
|
|
struct attribute *attr, int index)
|
|
|
|
{
|
2020-05-11 06:43:06 +03:00
|
|
|
struct device *dev = kobj_to_dev(kobj);
|
2013-03-18 20:22:50 +04:00
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
2013-06-25 09:21:59 +04:00
|
|
|
int in = index / 5; /* voltage index */
|
2013-03-18 20:22:50 +04:00
|
|
|
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!(data->have_in & BIT(in)))
|
2013-03-18 20:22:50 +04:00
|
|
|
return 0;
|
|
|
|
|
2022-04-27 04:01:51 +03:00
|
|
|
return nct6775_attr_mode(data, attr);
|
2013-03-18 20:22:50 +04:00
|
|
|
}
|
|
|
|
|
2022-04-27 04:01:52 +03:00
|
|
|
SENSOR_TEMPLATE_2(in_input, "in%d_input", 0444, show_in_reg, NULL, 0, 0);
|
2022-04-27 04:01:53 +03:00
|
|
|
SENSOR_TEMPLATE(in_alarm, "in%d_alarm", 0444, nct6775_show_alarm, NULL, 0);
|
|
|
|
SENSOR_TEMPLATE(in_beep, "in%d_beep", 0644, nct6775_show_beep, nct6775_store_beep, 0);
|
2022-04-27 04:01:52 +03:00
|
|
|
SENSOR_TEMPLATE_2(in_min, "in%d_min", 0644, show_in_reg, store_in_reg, 0, 1);
|
|
|
|
SENSOR_TEMPLATE_2(in_max, "in%d_max", 0644, show_in_reg, store_in_reg, 0, 2);
|
2013-03-18 20:22:50 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* nct6775_in_is_visible uses the index into the following array
|
|
|
|
* to determine if attributes should be created or not.
|
|
|
|
* Any change in order or content must be matched.
|
|
|
|
*/
|
|
|
|
static struct sensor_device_template *nct6775_attributes_in_template[] = {
|
|
|
|
&sensor_dev_template_in_input,
|
|
|
|
&sensor_dev_template_in_alarm,
|
2013-06-25 09:21:59 +04:00
|
|
|
&sensor_dev_template_in_beep,
|
2013-03-18 20:22:50 +04:00
|
|
|
&sensor_dev_template_in_min,
|
|
|
|
&sensor_dev_template_in_max,
|
|
|
|
NULL
|
2012-05-21 06:29:48 +04:00
|
|
|
};
|
|
|
|
|
2015-12-12 19:36:39 +03:00
|
|
|
static const struct sensor_template_group nct6775_in_template_group = {
|
2013-03-18 20:22:50 +04:00
|
|
|
.templates = nct6775_attributes_in_template,
|
|
|
|
.is_visible = nct6775_in_is_visible,
|
2012-05-21 06:29:48 +04:00
|
|
|
};
|
|
|
|
|
2012-12-04 19:56:24 +04:00
|
|
|
static ssize_t
|
|
|
|
show_fan(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
2014-11-16 21:00:06 +03:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 19:56:24 +04:00
|
|
|
return sprintf(buf, "%d\n", data->rpm[nr]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
show_fan_min(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
2014-11-16 21:00:06 +03:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 19:56:24 +04:00
|
|
|
return sprintf(buf, "%d\n",
|
|
|
|
data->fan_from_reg_min(data->fan_min[nr],
|
|
|
|
data->fan_div[nr]));
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
show_fan_div(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
2014-11-16 21:00:06 +03:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 19:56:24 +04:00
|
|
|
return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr]));
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_fan_min(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
|
|
|
unsigned long val;
|
|
|
|
unsigned int reg;
|
|
|
|
u8 new_div;
|
2014-11-16 21:00:06 +03:00
|
|
|
int err;
|
2012-12-04 19:56:24 +04:00
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
if (!data->has_fan_div) {
|
|
|
|
/* NCT6776F or NCT6779D; we know this is a 13 bit register */
|
|
|
|
if (!val) {
|
|
|
|
val = 0xff1f;
|
|
|
|
} else {
|
|
|
|
if (val > 1350000U)
|
|
|
|
val = 135000U;
|
|
|
|
val = 1350000U / val;
|
|
|
|
val = (val & 0x1f) | ((val << 3) & 0xff00);
|
|
|
|
}
|
|
|
|
data->fan_min[nr] = val;
|
|
|
|
goto write_min; /* Leave fan divider alone */
|
|
|
|
}
|
|
|
|
if (!val) {
|
|
|
|
/* No min limit, alarm disabled */
|
|
|
|
data->fan_min[nr] = 255;
|
|
|
|
new_div = data->fan_div[nr]; /* No change */
|
|
|
|
dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1);
|
|
|
|
goto write_div;
|
|
|
|
}
|
|
|
|
reg = 1350000U / val;
|
|
|
|
if (reg >= 128 * 255) {
|
|
|
|
/*
|
|
|
|
* Speed below this value cannot possibly be represented,
|
|
|
|
* even with the highest divider (128)
|
|
|
|
*/
|
|
|
|
data->fan_min[nr] = 254;
|
2017-05-18 04:40:10 +03:00
|
|
|
new_div = 7; /* 128 == BIT(7) */
|
2012-12-04 19:56:24 +04:00
|
|
|
dev_warn(dev,
|
|
|
|
"fan%u low limit %lu below minimum %u, set to minimum\n",
|
|
|
|
nr + 1, val, data->fan_from_reg_min(254, 7));
|
|
|
|
} else if (!reg) {
|
|
|
|
/*
|
|
|
|
* Speed above this value cannot possibly be represented,
|
|
|
|
* even with the lowest divider (1)
|
|
|
|
*/
|
|
|
|
data->fan_min[nr] = 1;
|
2017-05-18 04:40:10 +03:00
|
|
|
new_div = 0; /* 1 == BIT(0) */
|
2012-12-04 19:56:24 +04:00
|
|
|
dev_warn(dev,
|
|
|
|
"fan%u low limit %lu above maximum %u, set to maximum\n",
|
|
|
|
nr + 1, val, data->fan_from_reg_min(1, 0));
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Automatically pick the best divider, i.e. the one such
|
|
|
|
* that the min limit will correspond to a register value
|
|
|
|
* in the 96..192 range
|
|
|
|
*/
|
|
|
|
new_div = 0;
|
|
|
|
while (reg > 192 && new_div < 7) {
|
|
|
|
reg >>= 1;
|
|
|
|
new_div++;
|
|
|
|
}
|
|
|
|
data->fan_min[nr] = reg;
|
|
|
|
}
|
|
|
|
|
|
|
|
write_div:
|
|
|
|
/*
|
|
|
|
* Write both the fan clock divider (if it changed) and the new
|
|
|
|
* fan min (unconditionally)
|
|
|
|
*/
|
|
|
|
if (new_div != data->fan_div[nr]) {
|
|
|
|
dev_dbg(dev, "fan%u clock divider changed from %u to %u\n",
|
|
|
|
nr + 1, div_from_reg(data->fan_div[nr]),
|
|
|
|
div_from_reg(new_div));
|
|
|
|
data->fan_div[nr] = new_div;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_fan_div_common(data, nr);
|
|
|
|
if (err)
|
|
|
|
goto write_min;
|
2012-12-04 19:56:24 +04:00
|
|
|
/* Give the chip time to sample a new speed value */
|
|
|
|
data->last_updated = jiffies;
|
|
|
|
}
|
|
|
|
|
|
|
|
write_min:
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_FAN_MIN[nr], data->fan_min[nr]);
|
2012-12-04 19:56:24 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 19:56:24 +04:00
|
|
|
}
|
|
|
|
|
2012-12-11 19:29:06 +04:00
|
|
|
static ssize_t
|
|
|
|
show_fan_pulses(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int p;
|
|
|
|
|
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
2012-12-11 19:29:06 +04:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
p = data->fan_pulses[sattr->index];
|
2012-12-11 19:29:06 +04:00
|
|
|
return sprintf(buf, "%d\n", p ? : 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_fan_pulses(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
|
|
|
unsigned long val;
|
|
|
|
int err;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
u16 reg;
|
2012-12-11 19:29:06 +04:00
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
if (val > 4)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
data->fan_pulses[nr] = val & 3;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_FAN_PULSES[nr], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
2012-07-01 19:23:15 +04:00
|
|
|
reg &= ~(0x03 << data->FAN_PULSE_SHIFT[nr]);
|
|
|
|
reg |= (val & 3) << data->FAN_PULSE_SHIFT[nr];
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_FAN_PULSES[nr], reg);
|
|
|
|
out:
|
2012-12-11 19:29:06 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-11 19:29:06 +04:00
|
|
|
}
|
|
|
|
|
2013-03-18 20:22:50 +04:00
|
|
|
static umode_t nct6775_fan_is_visible(struct kobject *kobj,
|
|
|
|
struct attribute *attr, int index)
|
|
|
|
{
|
2020-05-11 06:43:06 +03:00
|
|
|
struct device *dev = kobj_to_dev(kobj);
|
2013-03-18 20:22:50 +04:00
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
2013-06-25 09:21:59 +04:00
|
|
|
int fan = index / 6; /* fan index */
|
|
|
|
int nr = index % 6; /* attribute index */
|
2012-12-04 19:56:24 +04:00
|
|
|
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!(data->has_fan & BIT(fan)))
|
2013-03-18 20:22:50 +04:00
|
|
|
return 0;
|
2012-12-04 19:56:24 +04:00
|
|
|
|
2013-03-18 20:22:50 +04:00
|
|
|
if (nr == 1 && data->ALARM_BITS[FAN_ALARM_BASE + fan] == -1)
|
|
|
|
return 0;
|
2013-06-25 09:21:59 +04:00
|
|
|
if (nr == 2 && data->BEEP_BITS[FAN_ALARM_BASE + fan] == -1)
|
2013-03-18 20:22:50 +04:00
|
|
|
return 0;
|
2018-02-22 00:09:39 +03:00
|
|
|
if (nr == 3 && !data->REG_FAN_PULSES[fan])
|
|
|
|
return 0;
|
2017-05-18 04:40:10 +03:00
|
|
|
if (nr == 4 && !(data->has_fan_min & BIT(fan)))
|
2013-06-25 09:21:59 +04:00
|
|
|
return 0;
|
|
|
|
if (nr == 5 && data->kind != nct6775)
|
2013-03-18 20:22:50 +04:00
|
|
|
return 0;
|
|
|
|
|
2022-04-27 04:01:51 +03:00
|
|
|
return nct6775_attr_mode(data, attr);
|
2013-03-18 20:22:50 +04:00
|
|
|
}
|
2012-12-04 19:56:24 +04:00
|
|
|
|
2022-04-27 04:01:52 +03:00
|
|
|
SENSOR_TEMPLATE(fan_input, "fan%d_input", 0444, show_fan, NULL, 0);
|
2022-04-27 04:01:53 +03:00
|
|
|
SENSOR_TEMPLATE(fan_alarm, "fan%d_alarm", 0444, nct6775_show_alarm, NULL, FAN_ALARM_BASE);
|
|
|
|
SENSOR_TEMPLATE(fan_beep, "fan%d_beep", 0644, nct6775_show_beep,
|
|
|
|
nct6775_store_beep, FAN_ALARM_BASE);
|
2022-04-27 04:01:52 +03:00
|
|
|
SENSOR_TEMPLATE(fan_pulses, "fan%d_pulses", 0644, show_fan_pulses, store_fan_pulses, 0);
|
|
|
|
SENSOR_TEMPLATE(fan_min, "fan%d_min", 0644, show_fan_min, store_fan_min, 0);
|
|
|
|
SENSOR_TEMPLATE(fan_div, "fan%d_div", 0444, show_fan_div, NULL, 0);
|
2013-03-18 20:22:50 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* nct6775_fan_is_visible uses the index into the following array
|
|
|
|
* to determine if attributes should be created or not.
|
|
|
|
* Any change in order or content must be matched.
|
|
|
|
*/
|
|
|
|
static struct sensor_device_template *nct6775_attributes_fan_template[] = {
|
|
|
|
&sensor_dev_template_fan_input,
|
|
|
|
&sensor_dev_template_fan_alarm, /* 1 */
|
2013-06-25 09:21:59 +04:00
|
|
|
&sensor_dev_template_fan_beep, /* 2 */
|
2013-03-18 20:22:50 +04:00
|
|
|
&sensor_dev_template_fan_pulses,
|
2013-06-25 09:21:59 +04:00
|
|
|
&sensor_dev_template_fan_min, /* 4 */
|
|
|
|
&sensor_dev_template_fan_div, /* 5 */
|
2013-03-18 20:22:50 +04:00
|
|
|
NULL
|
2012-12-11 19:29:06 +04:00
|
|
|
};
|
|
|
|
|
2015-12-12 19:36:39 +03:00
|
|
|
static const struct sensor_template_group nct6775_fan_template_group = {
|
2013-03-18 20:22:50 +04:00
|
|
|
.templates = nct6775_attributes_fan_template,
|
|
|
|
.is_visible = nct6775_fan_is_visible,
|
|
|
|
.base = 1,
|
2012-12-04 19:56:24 +04:00
|
|
|
};
|
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
static ssize_t
|
|
|
|
show_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
2014-11-16 21:00:06 +03:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
return sprintf(buf, "%s\n", data->temp_label[data->temp_src[nr]]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
show_temp(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
int nr = sattr->nr;
|
|
|
|
int index = sattr->index;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->temp[index][nr]));
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_temp(struct device *dev, struct device_attribute *attr, const char *buf,
|
|
|
|
size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
int nr = sattr->nr;
|
|
|
|
int index = sattr->index;
|
|
|
|
int err;
|
|
|
|
long val;
|
|
|
|
|
|
|
|
err = kstrtol(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
data->temp[index][nr] = LM75_TEMP_TO_REG(val);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_temp(data, data->reg_temp[index][nr], data->temp[index][nr]);
|
2012-12-04 15:26:05 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 15:26:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
show_temp_offset(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
return sprintf(buf, "%d\n", data->temp_offset[sattr->index] * 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_temp_offset(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
|
|
|
long val;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = kstrtol(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127);
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
data->temp_offset[nr] = val;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_TEMP_OFFSET[nr], val);
|
2012-12-04 15:26:05 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 15:26:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
show_temp_type(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
2014-11-16 21:00:06 +03:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
return sprintf(buf, "%d\n", (int)data->temp_type[nr]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_temp_type(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
|
|
|
unsigned long val;
|
|
|
|
int err;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
u8 vbit, dbit;
|
|
|
|
u16 vbat, diode;
|
|
|
|
|
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
2012-12-04 15:26:05 +04:00
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
if (val != 1 && val != 3 && val != 4)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
|
|
|
|
data->temp_type[nr] = val;
|
2012-07-01 19:23:15 +04:00
|
|
|
vbit = 0x02 << nr;
|
|
|
|
dbit = data->DIODE_MASK << nr;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
|
|
|
|
err = nct6775_read_value(data, data->REG_VBAT, &vbat);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
vbat &= ~vbit;
|
|
|
|
|
|
|
|
err = nct6775_read_value(data, data->REG_DIODE, &diode);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
diode &= ~dbit;
|
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
switch (val) {
|
|
|
|
case 1: /* CPU diode (diode, current mode) */
|
2012-07-01 19:23:15 +04:00
|
|
|
vbat |= vbit;
|
|
|
|
diode |= dbit;
|
2012-12-04 15:26:05 +04:00
|
|
|
break;
|
|
|
|
case 3: /* diode, voltage mode */
|
2012-07-01 19:23:15 +04:00
|
|
|
vbat |= dbit;
|
2012-12-04 15:26:05 +04:00
|
|
|
break;
|
|
|
|
case 4: /* thermistor */
|
|
|
|
break;
|
|
|
|
}
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_VBAT, vbat);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
err = nct6775_write_value(data, data->REG_DIODE, diode);
|
|
|
|
out:
|
2012-12-04 15:26:05 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 15:26:05 +04:00
|
|
|
}
|
|
|
|
|
2013-03-18 20:22:50 +04:00
|
|
|
static umode_t nct6775_temp_is_visible(struct kobject *kobj,
|
|
|
|
struct attribute *attr, int index)
|
|
|
|
{
|
2020-05-11 06:43:06 +03:00
|
|
|
struct device *dev = kobj_to_dev(kobj);
|
2013-03-18 20:22:50 +04:00
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
2013-06-25 09:21:59 +04:00
|
|
|
int temp = index / 10; /* temp index */
|
|
|
|
int nr = index % 10; /* attribute index */
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!(data->have_temp & BIT(temp)))
|
2013-03-18 20:22:50 +04:00
|
|
|
return 0;
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2017-05-18 04:05:06 +03:00
|
|
|
if (nr == 1 && !data->temp_label)
|
|
|
|
return 0;
|
|
|
|
|
2013-03-18 20:22:50 +04:00
|
|
|
if (nr == 2 && find_temp_source(data, temp, data->num_temp_alarms) < 0)
|
|
|
|
return 0; /* alarm */
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2013-06-25 09:21:59 +04:00
|
|
|
if (nr == 3 && find_temp_source(data, temp, data->num_temp_beeps) < 0)
|
|
|
|
return 0; /* beep */
|
|
|
|
|
|
|
|
if (nr == 4 && !data->reg_temp[1][temp]) /* max */
|
2013-03-18 20:22:50 +04:00
|
|
|
return 0;
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2013-06-25 09:21:59 +04:00
|
|
|
if (nr == 5 && !data->reg_temp[2][temp]) /* max_hyst */
|
2013-03-18 20:22:50 +04:00
|
|
|
return 0;
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2013-06-25 09:21:59 +04:00
|
|
|
if (nr == 6 && !data->reg_temp[3][temp]) /* crit */
|
2013-03-18 20:22:50 +04:00
|
|
|
return 0;
|
|
|
|
|
2013-06-25 09:21:59 +04:00
|
|
|
if (nr == 7 && !data->reg_temp[4][temp]) /* lcrit */
|
2013-04-03 09:14:06 +04:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* offset and type only apply to fixed sensors */
|
2017-05-18 04:40:10 +03:00
|
|
|
if (nr > 7 && !(data->have_temp_fixed & BIT(temp)))
|
2013-03-18 20:22:50 +04:00
|
|
|
return 0;
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2022-04-27 04:01:51 +03:00
|
|
|
return nct6775_attr_mode(data, attr);
|
2013-03-18 20:22:50 +04:00
|
|
|
}
|
|
|
|
|
2022-04-27 04:01:52 +03:00
|
|
|
SENSOR_TEMPLATE_2(temp_input, "temp%d_input", 0444, show_temp, NULL, 0, 0);
|
|
|
|
SENSOR_TEMPLATE(temp_label, "temp%d_label", 0444, show_temp_label, NULL, 0);
|
|
|
|
SENSOR_TEMPLATE_2(temp_max, "temp%d_max", 0644, show_temp, store_temp, 0, 1);
|
|
|
|
SENSOR_TEMPLATE_2(temp_max_hyst, "temp%d_max_hyst", 0644, show_temp, store_temp, 0, 2);
|
|
|
|
SENSOR_TEMPLATE_2(temp_crit, "temp%d_crit", 0644, show_temp, store_temp, 0, 3);
|
|
|
|
SENSOR_TEMPLATE_2(temp_lcrit, "temp%d_lcrit", 0644, show_temp, store_temp, 0, 4);
|
|
|
|
SENSOR_TEMPLATE(temp_offset, "temp%d_offset", 0644, show_temp_offset, store_temp_offset, 0);
|
|
|
|
SENSOR_TEMPLATE(temp_type, "temp%d_type", 0644, show_temp_type, store_temp_type, 0);
|
|
|
|
SENSOR_TEMPLATE(temp_alarm, "temp%d_alarm", 0444, show_temp_alarm, NULL, 0);
|
|
|
|
SENSOR_TEMPLATE(temp_beep, "temp%d_beep", 0644, show_temp_beep, store_temp_beep, 0);
|
2013-03-18 20:22:50 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* nct6775_temp_is_visible uses the index into the following array
|
|
|
|
* to determine if attributes should be created or not.
|
|
|
|
* Any change in order or content must be matched.
|
|
|
|
*/
|
|
|
|
static struct sensor_device_template *nct6775_attributes_temp_template[] = {
|
|
|
|
&sensor_dev_template_temp_input,
|
|
|
|
&sensor_dev_template_temp_label,
|
|
|
|
&sensor_dev_template_temp_alarm, /* 2 */
|
2013-06-25 09:21:59 +04:00
|
|
|
&sensor_dev_template_temp_beep, /* 3 */
|
|
|
|
&sensor_dev_template_temp_max, /* 4 */
|
|
|
|
&sensor_dev_template_temp_max_hyst, /* 5 */
|
|
|
|
&sensor_dev_template_temp_crit, /* 6 */
|
|
|
|
&sensor_dev_template_temp_lcrit, /* 7 */
|
|
|
|
&sensor_dev_template_temp_offset, /* 8 */
|
|
|
|
&sensor_dev_template_temp_type, /* 9 */
|
2013-03-18 20:22:50 +04:00
|
|
|
NULL
|
2012-12-04 15:26:05 +04:00
|
|
|
};
|
|
|
|
|
2015-12-12 19:36:39 +03:00
|
|
|
static const struct sensor_template_group nct6775_temp_template_group = {
|
2013-03-18 20:22:50 +04:00
|
|
|
.templates = nct6775_attributes_temp_template,
|
|
|
|
.is_visible = nct6775_temp_is_visible,
|
|
|
|
.base = 1,
|
2012-12-04 15:26:05 +04:00
|
|
|
};
|
|
|
|
|
2022-01-13 19:46:29 +03:00
|
|
|
static ssize_t show_tsi_temp(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2022-01-13 19:46:29 +03:00
|
|
|
return sysfs_emit(buf, "%u\n", tsi_temp_from_reg(data->tsi_temp[sattr->index]));
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t show_tsi_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
|
|
|
|
return sysfs_emit(buf, "TSI%d_TEMP\n", sattr->index);
|
|
|
|
}
|
|
|
|
|
|
|
|
SENSOR_TEMPLATE(tsi_temp_input, "temp%d_input", 0444, show_tsi_temp, NULL, 0);
|
|
|
|
SENSOR_TEMPLATE(tsi_temp_label, "temp%d_label", 0444, show_tsi_temp_label, NULL, 0);
|
|
|
|
|
|
|
|
static umode_t nct6775_tsi_temp_is_visible(struct kobject *kobj, struct attribute *attr,
|
|
|
|
int index)
|
|
|
|
{
|
|
|
|
struct device *dev = kobj_to_dev(kobj);
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
int temp = index / 2;
|
|
|
|
|
2022-04-27 04:01:51 +03:00
|
|
|
return (data->have_tsi_temp & BIT(temp)) ? nct6775_attr_mode(data, attr) : 0;
|
2022-01-13 19:46:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The index calculation in nct6775_tsi_temp_is_visible() must be kept in
|
|
|
|
* sync with the size of this array.
|
|
|
|
*/
|
|
|
|
static struct sensor_device_template *nct6775_tsi_temp_template[] = {
|
|
|
|
&sensor_dev_template_tsi_temp_input,
|
|
|
|
&sensor_dev_template_tsi_temp_label,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2012-12-04 20:30:54 +04:00
|
|
|
static ssize_t
|
|
|
|
show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2018-03-27 05:50:31 +03:00
|
|
|
return sprintf(buf, "%d\n", data->pwm_mode[sattr->index]);
|
2012-12-04 20:30:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_pwm_mode(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
|
|
|
unsigned long val;
|
|
|
|
int err;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
u16 reg;
|
2012-12-04 20:30:54 +04:00
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
if (val > 1)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2018-03-27 05:50:31 +03:00
|
|
|
/* Setting DC mode (0) is not supported for all chips/channels */
|
2012-12-04 20:30:54 +04:00
|
|
|
if (data->REG_PWM_MODE[nr] == 0) {
|
2018-03-27 05:50:31 +03:00
|
|
|
if (!val)
|
2012-12-04 20:30:54 +04:00
|
|
|
return -EINVAL;
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
data->pwm_mode[nr] = val;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_PWM_MODE[nr], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
2012-12-04 20:30:54 +04:00
|
|
|
reg &= ~data->PWM_MODE_MASK[nr];
|
2018-03-27 05:50:31 +03:00
|
|
|
if (!val)
|
2012-12-04 20:30:54 +04:00
|
|
|
reg |= data->PWM_MODE_MASK[nr];
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_PWM_MODE[nr], reg);
|
|
|
|
out:
|
2012-12-04 20:30:54 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 20:30:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
int nr = sattr->nr;
|
|
|
|
int index = sattr->index;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int err;
|
|
|
|
u16 pwm;
|
|
|
|
|
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
2012-12-04 20:30:54 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* For automatic fan control modes, show current pwm readings.
|
|
|
|
* Otherwise, show the configured value.
|
|
|
|
*/
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (index == 0 && data->pwm_enable[nr] > manual) {
|
|
|
|
err = nct6775_read_value(data, data->REG_PWM_READ[nr], &pwm);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
} else {
|
2012-12-04 20:30:54 +04:00
|
|
|
pwm = data->pwm[index][nr];
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
}
|
2012-12-04 20:30:54 +04:00
|
|
|
|
|
|
|
return sprintf(buf, "%d\n", pwm);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
|
|
|
|
size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
int nr = sattr->nr;
|
|
|
|
int index = sattr->index;
|
|
|
|
unsigned long val;
|
2012-12-04 21:08:29 +04:00
|
|
|
int minval[7] = { 0, 1, 1, data->pwm[2][nr], 0, 0, 0 };
|
|
|
|
int maxval[7]
|
|
|
|
= { 255, 255, data->pwm[3][nr] ? : 255, 255, 255, 255, 255 };
|
2012-12-04 20:30:54 +04:00
|
|
|
int err;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
u16 reg;
|
2012-12-04 20:30:54 +04:00
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
2012-12-04 21:04:52 +04:00
|
|
|
val = clamp_val(val, minval[index], maxval[index]);
|
2012-12-04 20:30:54 +04:00
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
data->pwm[index][nr] = val;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_PWM[index][nr], val);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
2012-12-04 21:04:52 +04:00
|
|
|
if (index == 2) { /* floor: disable if val == 0 */
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_TEMP_SEL[nr], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
2012-12-04 21:04:52 +04:00
|
|
|
reg &= 0x7f;
|
|
|
|
if (val)
|
|
|
|
reg |= 0x80;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
out:
|
2012-12-04 20:30:54 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 20:30:54 +04:00
|
|
|
}
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
/* Returns 0 if OK, -EINVAL otherwise */
|
|
|
|
static int check_trip_points(struct nct6775_data *data, int nr)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < data->auto_pwm_num - 1; i++) {
|
|
|
|
if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1])
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
for (i = 0; i < data->auto_pwm_num - 1; i++) {
|
|
|
|
if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1])
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
/* validate critical temperature and pwm if enabled (pwm > 0) */
|
|
|
|
if (data->auto_pwm[nr][data->auto_pwm_num]) {
|
|
|
|
if (data->auto_temp[nr][data->auto_pwm_num - 1] >
|
|
|
|
data->auto_temp[nr][data->auto_pwm_num] ||
|
|
|
|
data->auto_pwm[nr][data->auto_pwm_num - 1] >
|
|
|
|
data->auto_pwm[nr][data->auto_pwm_num])
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
static int pwm_update_registers(struct nct6775_data *data, int nr)
|
2012-12-04 21:04:52 +04:00
|
|
|
{
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
u16 reg;
|
|
|
|
int err;
|
2012-12-04 21:04:52 +04:00
|
|
|
|
|
|
|
switch (data->pwm_enable[nr]) {
|
|
|
|
case off:
|
|
|
|
case manual:
|
|
|
|
break;
|
|
|
|
case speed_cruise:
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_FAN_MODE[nr], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 21:04:52 +04:00
|
|
|
reg = (reg & ~data->tolerance_mask) |
|
|
|
|
(data->target_speed_tolerance[nr] & data->tolerance_mask);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
err = nct6775_write_value(data, data->REG_TARGET[nr],
|
|
|
|
data->target_speed[nr] & 0xff);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 21:04:52 +04:00
|
|
|
if (data->REG_TOLERANCE_H) {
|
|
|
|
reg = (data->target_speed[nr] >> 8) & 0x0f;
|
|
|
|
reg |= (data->target_speed_tolerance[nr] & 0x38) << 1;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_TOLERANCE_H[nr], reg);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case thermal_cruise:
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_TARGET[nr], data->target_temp[nr]);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2020-08-24 01:36:59 +03:00
|
|
|
fallthrough;
|
2012-12-04 21:04:52 +04:00
|
|
|
default:
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_FAN_MODE[nr], ®);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 21:04:52 +04:00
|
|
|
reg = (reg & ~data->tolerance_mask) |
|
|
|
|
data->temp_tolerance[0][nr];
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 21:04:52 +04:00
|
|
|
break;
|
|
|
|
}
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
|
|
|
|
return 0;
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
|
2012-12-04 20:30:54 +04:00
|
|
|
static ssize_t
|
|
|
|
show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 20:30:54 +04:00
|
|
|
return sprintf(buf, "%d\n", data->pwm_enable[sattr->index]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_pwm_enable(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
|
|
|
unsigned long val;
|
|
|
|
int err;
|
|
|
|
u16 reg;
|
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
if (val > sf4)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (val == sf3 && data->kind != nct6775)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
if (val == sf4 && check_trip_points(data, nr)) {
|
|
|
|
dev_err(dev, "Inconsistent trip points, not switching to SmartFan IV mode\n");
|
|
|
|
dev_err(dev, "Adjust trip points and try again\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2012-12-04 20:30:54 +04:00
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
data->pwm_enable[nr] = val;
|
|
|
|
if (val == off) {
|
|
|
|
/*
|
|
|
|
* turn off pwm control: select manual mode, set pwm to maximum
|
|
|
|
*/
|
|
|
|
data->pwm[0][nr] = 255;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_PWM[0][nr], 255);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
2012-12-04 20:30:54 +04:00
|
|
|
}
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = pwm_update_registers(data, nr);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
err = nct6775_read_value(data, data->REG_FAN_MODE[nr], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
2012-12-04 20:30:54 +04:00
|
|
|
reg &= 0x0f;
|
|
|
|
reg |= pwm_enable_to_reg(val) << 4;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
|
|
|
|
out:
|
2012-12-04 20:30:54 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 20:30:54 +04:00
|
|
|
}
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
static ssize_t
|
2012-12-04 21:08:29 +04:00
|
|
|
show_pwm_temp_sel_common(struct nct6775_data *data, char *buf, int src)
|
2012-12-04 21:04:52 +04:00
|
|
|
{
|
2012-12-04 21:08:29 +04:00
|
|
|
int i, sel = 0;
|
2012-12-04 21:04:52 +04:00
|
|
|
|
|
|
|
for (i = 0; i < NUM_TEMP; i++) {
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!(data->have_temp & BIT(i)))
|
2012-12-04 21:04:52 +04:00
|
|
|
continue;
|
|
|
|
if (src == data->temp_src[i]) {
|
|
|
|
sel = i + 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return sprintf(buf, "%d\n", sel);
|
|
|
|
}
|
|
|
|
|
2012-12-04 21:08:29 +04:00
|
|
|
static ssize_t
|
|
|
|
show_pwm_temp_sel(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int index = sattr->index;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 21:08:29 +04:00
|
|
|
return show_pwm_temp_sel_common(data, buf, data->pwm_temp_sel[index]);
|
|
|
|
}
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
static ssize_t
|
|
|
|
store_pwm_temp_sel(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
|
|
|
unsigned long val;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int err, src;
|
|
|
|
u16 reg;
|
|
|
|
|
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
2012-12-04 21:04:52 +04:00
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
if (val == 0 || val > NUM_TEMP)
|
|
|
|
return -EINVAL;
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!(data->have_temp & BIT(val - 1)) || !data->temp_src[val - 1])
|
2012-12-04 21:04:52 +04:00
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
src = data->temp_src[val - 1];
|
|
|
|
data->pwm_temp_sel[nr] = src;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_TEMP_SEL[nr], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
2012-12-04 21:04:52 +04:00
|
|
|
reg &= 0xe0;
|
|
|
|
reg |= src;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
|
|
|
|
out:
|
2012-12-04 21:04:52 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
|
2012-12-04 21:08:29 +04:00
|
|
|
static ssize_t
|
|
|
|
show_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
|
|
|
|
char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int index = sattr->index;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 21:08:29 +04:00
|
|
|
return show_pwm_temp_sel_common(data, buf,
|
|
|
|
data->pwm_weight_temp_sel[index]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
|
|
|
unsigned long val;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int err, src;
|
|
|
|
u16 reg;
|
|
|
|
|
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
2012-12-04 21:08:29 +04:00
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
if (val > NUM_TEMP)
|
|
|
|
return -EINVAL;
|
2018-08-15 16:14:37 +03:00
|
|
|
val = array_index_nospec(val, NUM_TEMP + 1);
|
2017-05-18 04:40:10 +03:00
|
|
|
if (val && (!(data->have_temp & BIT(val - 1)) ||
|
2012-12-04 21:08:29 +04:00
|
|
|
!data->temp_src[val - 1]))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
if (val) {
|
|
|
|
src = data->temp_src[val - 1];
|
|
|
|
data->pwm_weight_temp_sel[nr] = src;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
2012-12-04 21:08:29 +04:00
|
|
|
reg &= 0xe0;
|
|
|
|
reg |= (src | 0x80);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
|
2012-12-04 21:08:29 +04:00
|
|
|
} else {
|
|
|
|
data->pwm_weight_temp_sel[nr] = 0;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr], ®);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
2012-12-04 21:08:29 +04:00
|
|
|
reg &= 0x7f;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
|
2012-12-04 21:08:29 +04:00
|
|
|
}
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
out:
|
2012-12-04 21:08:29 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 21:08:29 +04:00
|
|
|
}
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
static ssize_t
|
|
|
|
show_target_temp(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
return sprintf(buf, "%d\n", data->target_temp[sattr->index] * 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_target_temp(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
|
|
|
unsigned long val;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0,
|
|
|
|
data->target_temp_mask);
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
data->target_temp[nr] = val;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = pwm_update_registers(data, nr);
|
2012-12-04 21:04:52 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
show_target_speed(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
return sprintf(buf, "%d\n",
|
|
|
|
fan_from_reg16(data->target_speed[nr],
|
|
|
|
data->fan_div[nr]));
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_target_speed(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
|
|
|
unsigned long val;
|
|
|
|
int err;
|
|
|
|
u16 speed;
|
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
val = clamp_val(val, 0, 1350000U);
|
|
|
|
speed = fan_to_reg(val, data->fan_div[nr]);
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
data->target_speed[nr] = speed;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = pwm_update_registers(data, nr);
|
2012-12-04 21:04:52 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
show_temp_tolerance(struct device *dev, struct device_attribute *attr,
|
|
|
|
char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
int nr = sattr->nr;
|
|
|
|
int index = sattr->index;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
return sprintf(buf, "%d\n", data->temp_tolerance[index][nr] * 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_temp_tolerance(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
int nr = sattr->nr;
|
|
|
|
int index = sattr->index;
|
|
|
|
unsigned long val;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
/* Limit tolerance as needed */
|
|
|
|
val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, data->tolerance_mask);
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
data->temp_tolerance[index][nr] = val;
|
|
|
|
if (index)
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = pwm_update_registers(data, nr);
|
2012-12-04 21:04:52 +04:00
|
|
|
else
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_CRITICAL_TEMP_TOLERANCE[nr], val);
|
2012-12-04 21:04:52 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Fan speed tolerance is a tricky beast, since the associated register is
|
|
|
|
* a tick counter, but the value is reported and configured as rpm.
|
|
|
|
* Compute resulting low and high rpm values and report the difference.
|
2018-09-17 19:24:11 +03:00
|
|
|
* A fan speed tolerance only makes sense if a fan target speed has been
|
|
|
|
* configured, so only display values other than 0 if that is the case.
|
2012-12-04 21:04:52 +04:00
|
|
|
*/
|
|
|
|
static ssize_t
|
|
|
|
show_speed_tolerance(struct device *dev, struct device_attribute *attr,
|
|
|
|
char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int target, tolerance = 0;
|
|
|
|
|
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
|
|
|
target = data->target_speed[nr];
|
2018-09-17 19:24:11 +03:00
|
|
|
|
|
|
|
if (target) {
|
|
|
|
int low = target - data->target_speed_tolerance[nr];
|
|
|
|
int high = target + data->target_speed_tolerance[nr];
|
|
|
|
|
|
|
|
if (low <= 0)
|
|
|
|
low = 1;
|
|
|
|
if (high > 0xffff)
|
|
|
|
high = 0xffff;
|
|
|
|
if (high < low)
|
|
|
|
high = low;
|
|
|
|
|
|
|
|
tolerance = (fan_from_reg16(low, data->fan_div[nr])
|
|
|
|
- fan_from_reg16(high, data->fan_div[nr])) / 2;
|
|
|
|
}
|
2012-12-04 21:04:52 +04:00
|
|
|
|
|
|
|
return sprintf(buf, "%d\n", tolerance);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_speed_tolerance(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
|
|
|
|
int nr = sattr->index;
|
|
|
|
unsigned long val;
|
|
|
|
int err;
|
|
|
|
int low, high;
|
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
2021-12-15 14:40:50 +03:00
|
|
|
high = fan_from_reg16(data->target_speed[nr], data->fan_div[nr]) + val;
|
|
|
|
low = fan_from_reg16(data->target_speed[nr], data->fan_div[nr]) - val;
|
2012-12-04 21:04:52 +04:00
|
|
|
if (low <= 0)
|
|
|
|
low = 1;
|
|
|
|
if (high < low)
|
|
|
|
high = low;
|
|
|
|
|
|
|
|
val = (fan_to_reg(low, data->fan_div[nr]) -
|
|
|
|
fan_to_reg(high, data->fan_div[nr])) / 2;
|
|
|
|
|
|
|
|
/* Limit tolerance as needed */
|
|
|
|
val = clamp_val(val, 0, data->speed_tolerance_limit);
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
data->target_speed_tolerance[nr] = val;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = pwm_update_registers(data, nr);
|
2012-12-04 21:04:52 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
|
2022-04-27 04:01:52 +03:00
|
|
|
SENSOR_TEMPLATE_2(pwm, "pwm%d", 0644, show_pwm, store_pwm, 0, 0);
|
|
|
|
SENSOR_TEMPLATE(pwm_mode, "pwm%d_mode", 0644, show_pwm_mode, store_pwm_mode, 0);
|
|
|
|
SENSOR_TEMPLATE(pwm_enable, "pwm%d_enable", 0644, show_pwm_enable, store_pwm_enable, 0);
|
|
|
|
SENSOR_TEMPLATE(pwm_temp_sel, "pwm%d_temp_sel", 0644, show_pwm_temp_sel, store_pwm_temp_sel, 0);
|
|
|
|
SENSOR_TEMPLATE(pwm_target_temp, "pwm%d_target_temp", 0644, show_target_temp, store_target_temp, 0);
|
|
|
|
SENSOR_TEMPLATE(fan_target, "fan%d_target", 0644, show_target_speed, store_target_speed, 0);
|
|
|
|
SENSOR_TEMPLATE(fan_tolerance, "fan%d_tolerance", 0644, show_speed_tolerance,
|
|
|
|
store_speed_tolerance, 0);
|
2012-12-04 21:04:52 +04:00
|
|
|
|
|
|
|
/* Smart Fan registers */
|
|
|
|
|
2012-12-04 21:08:29 +04:00
|
|
|
static ssize_t
|
|
|
|
show_weight_temp(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
int nr = sattr->nr;
|
|
|
|
int index = sattr->index;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 21:08:29 +04:00
|
|
|
return sprintf(buf, "%d\n", data->weight_temp[index][nr] * 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_weight_temp(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
int nr = sattr->nr;
|
|
|
|
int index = sattr->index;
|
|
|
|
unsigned long val;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255);
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
data->weight_temp[index][nr] = val;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_WEIGHT_TEMP[index][nr], val);
|
2012-12-04 21:08:29 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 21:08:29 +04:00
|
|
|
}
|
|
|
|
|
2022-04-27 04:01:52 +03:00
|
|
|
SENSOR_TEMPLATE(pwm_weight_temp_sel, "pwm%d_weight_temp_sel", 0644,
|
|
|
|
show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, 0);
|
2013-03-18 20:22:50 +04:00
|
|
|
SENSOR_TEMPLATE_2(pwm_weight_temp_step, "pwm%d_weight_temp_step",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_weight_temp, store_weight_temp, 0, 0);
|
2013-03-18 20:22:50 +04:00
|
|
|
SENSOR_TEMPLATE_2(pwm_weight_temp_step_tol, "pwm%d_weight_temp_step_tol",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_weight_temp, store_weight_temp, 0, 1);
|
2013-03-18 20:22:50 +04:00
|
|
|
SENSOR_TEMPLATE_2(pwm_weight_temp_step_base, "pwm%d_weight_temp_step_base",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_weight_temp, store_weight_temp, 0, 2);
|
|
|
|
SENSOR_TEMPLATE_2(pwm_weight_duty_step, "pwm%d_weight_duty_step", 0644, show_pwm, store_pwm, 0, 5);
|
|
|
|
SENSOR_TEMPLATE_2(pwm_weight_duty_base, "pwm%d_weight_duty_base", 0644, show_pwm, store_pwm, 0, 6);
|
2012-12-04 21:08:29 +04:00
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
static ssize_t
|
|
|
|
show_fan_time(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
int nr = sattr->nr;
|
|
|
|
int index = sattr->index;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
return sprintf(buf, "%d\n",
|
|
|
|
step_time_from_reg(data->fan_time[index][nr],
|
|
|
|
data->pwm_mode[nr]));
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_fan_time(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
int nr = sattr->nr;
|
|
|
|
int index = sattr->index;
|
|
|
|
unsigned long val;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
val = step_time_to_reg(val, data->pwm_mode[nr]);
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
data->fan_time[index][nr] = val;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_FAN_TIME[index][nr], val);
|
2012-12-04 21:04:52 +04:00
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
show_auto_pwm(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
return sprintf(buf, "%d\n", data->auto_pwm[sattr->nr][sattr->index]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_auto_pwm(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
int nr = sattr->nr;
|
|
|
|
int point = sattr->index;
|
|
|
|
unsigned long val;
|
|
|
|
int err;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
u16 reg;
|
2012-12-04 21:04:52 +04:00
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
if (val > 255)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (point == data->auto_pwm_num) {
|
|
|
|
if (data->kind != nct6775 && !val)
|
|
|
|
return -EINVAL;
|
|
|
|
if (data->kind != nct6779 && val)
|
|
|
|
val = 0xff;
|
|
|
|
}
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
data->auto_pwm[nr][point] = val;
|
|
|
|
if (point < data->auto_pwm_num) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, NCT6775_AUTO_PWM(data, nr, point),
|
|
|
|
data->auto_pwm[nr][point]);
|
2012-12-04 21:04:52 +04:00
|
|
|
} else {
|
|
|
|
switch (data->kind) {
|
|
|
|
case nct6775:
|
|
|
|
/* disable if needed (pwm == 0) */
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, NCT6775_REG_CRITICAL_ENAB[nr], ®);
|
|
|
|
if (err)
|
|
|
|
break;
|
2012-12-04 21:04:52 +04:00
|
|
|
if (val)
|
|
|
|
reg |= 0x02;
|
|
|
|
else
|
|
|
|
reg &= ~0x02;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, NCT6775_REG_CRITICAL_ENAB[nr], reg);
|
2012-12-04 21:04:52 +04:00
|
|
|
break;
|
|
|
|
case nct6776:
|
|
|
|
break; /* always enabled, nothing to do */
|
2012-07-01 19:23:15 +04:00
|
|
|
case nct6106:
|
2019-07-23 19:06:46 +03:00
|
|
|
case nct6116:
|
2012-12-04 21:04:52 +04:00
|
|
|
case nct6779:
|
2013-06-25 09:28:28 +04:00
|
|
|
case nct6791:
|
2014-11-16 20:50:04 +03:00
|
|
|
case nct6792:
|
2015-08-31 05:45:19 +03:00
|
|
|
case nct6793:
|
2017-05-18 04:19:18 +03:00
|
|
|
case nct6795:
|
2018-02-22 00:09:39 +03:00
|
|
|
case nct6796:
|
2018-09-19 06:48:29 +03:00
|
|
|
case nct6797:
|
2018-09-20 06:26:16 +03:00
|
|
|
case nct6798:
|
2022-12-28 16:57:44 +03:00
|
|
|
case nct6799:
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_CRITICAL_PWM[nr], val);
|
|
|
|
if (err)
|
|
|
|
break;
|
|
|
|
err = nct6775_read_value(data, data->REG_CRITICAL_PWM_ENABLE[nr], ®);
|
|
|
|
if (err)
|
|
|
|
break;
|
2012-12-04 21:04:52 +04:00
|
|
|
if (val == 255)
|
2012-07-01 19:23:15 +04:00
|
|
|
reg &= ~data->CRITICAL_PWM_ENABLE_MASK;
|
2012-12-04 21:04:52 +04:00
|
|
|
else
|
2012-07-01 19:23:15 +04:00
|
|
|
reg |= data->CRITICAL_PWM_ENABLE_MASK;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_CRITICAL_PWM_ENABLE[nr], reg);
|
2012-12-04 21:04:52 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
show_auto_temp(struct device *dev, struct device_attribute *attr, char *buf)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = nct6775_update_device(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
int nr = sattr->nr;
|
|
|
|
int point = sattr->index;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
if (IS_ERR(data))
|
|
|
|
return PTR_ERR(data);
|
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
/*
|
|
|
|
* We don't know for sure if the temperature is signed or unsigned.
|
|
|
|
* Assume it is unsigned.
|
|
|
|
*/
|
|
|
|
return sprintf(buf, "%d\n", data->auto_temp[nr][point] * 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t
|
|
|
|
store_auto_temp(struct device *dev, struct device_attribute *attr,
|
|
|
|
const char *buf, size_t count)
|
|
|
|
{
|
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
|
|
|
|
int nr = sattr->nr;
|
|
|
|
int point = sattr->index;
|
|
|
|
unsigned long val;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = kstrtoul(buf, 10, &val);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
if (val > 255000)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
mutex_lock(&data->update_lock);
|
|
|
|
data->auto_temp[nr][point] = DIV_ROUND_CLOSEST(val, 1000);
|
|
|
|
if (point < data->auto_pwm_num) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, NCT6775_AUTO_TEMP(data, nr, point),
|
|
|
|
data->auto_temp[nr][point]);
|
2012-12-04 21:04:52 +04:00
|
|
|
} else {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_CRITICAL_TEMP[nr],
|
|
|
|
data->auto_temp[nr][point]);
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
mutex_unlock(&data->update_lock);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
return err ? : count;
|
2012-12-04 21:04:52 +04:00
|
|
|
}
|
|
|
|
|
2013-03-18 20:22:50 +04:00
|
|
|
static umode_t nct6775_pwm_is_visible(struct kobject *kobj,
|
|
|
|
struct attribute *attr, int index)
|
|
|
|
{
|
2020-05-11 06:43:06 +03:00
|
|
|
struct device *dev = kobj_to_dev(kobj);
|
2013-03-18 20:22:50 +04:00
|
|
|
struct nct6775_data *data = dev_get_drvdata(dev);
|
|
|
|
int pwm = index / 36; /* pwm index */
|
|
|
|
int nr = index % 36; /* attribute index */
|
|
|
|
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!(data->has_pwm & BIT(pwm)))
|
2013-03-18 20:22:50 +04:00
|
|
|
return 0;
|
|
|
|
|
2013-11-14 00:47:17 +04:00
|
|
|
if ((nr >= 14 && nr <= 18) || nr == 21) /* weight */
|
|
|
|
if (!data->REG_WEIGHT_TEMP_SEL[pwm])
|
|
|
|
return 0;
|
2013-03-18 20:22:50 +04:00
|
|
|
if (nr == 19 && data->REG_PWM[3] == NULL) /* pwm_max */
|
|
|
|
return 0;
|
|
|
|
if (nr == 20 && data->REG_PWM[4] == NULL) /* pwm_step */
|
|
|
|
return 0;
|
|
|
|
if (nr == 21 && data->REG_PWM[6] == NULL) /* weight_duty_base */
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (nr >= 22 && nr <= 35) { /* auto point */
|
|
|
|
int api = (nr - 22) / 2; /* auto point index */
|
|
|
|
|
|
|
|
if (api > data->auto_pwm_num)
|
|
|
|
return 0;
|
|
|
|
}
|
2022-04-27 04:01:51 +03:00
|
|
|
return nct6775_attr_mode(data, attr);
|
2013-03-18 20:22:50 +04:00
|
|
|
}
|
|
|
|
|
2022-04-27 04:01:52 +03:00
|
|
|
SENSOR_TEMPLATE_2(pwm_stop_time, "pwm%d_stop_time", 0644, show_fan_time, store_fan_time, 0, 0);
|
|
|
|
SENSOR_TEMPLATE_2(pwm_step_up_time, "pwm%d_step_up_time", 0644,
|
2013-03-18 20:22:50 +04:00
|
|
|
show_fan_time, store_fan_time, 0, 1);
|
2022-04-27 04:01:52 +03:00
|
|
|
SENSOR_TEMPLATE_2(pwm_step_down_time, "pwm%d_step_down_time", 0644,
|
2013-03-18 20:22:50 +04:00
|
|
|
show_fan_time, store_fan_time, 0, 2);
|
2022-04-27 04:01:52 +03:00
|
|
|
SENSOR_TEMPLATE_2(pwm_start, "pwm%d_start", 0644, show_pwm, store_pwm, 0, 1);
|
|
|
|
SENSOR_TEMPLATE_2(pwm_floor, "pwm%d_floor", 0644, show_pwm, store_pwm, 0, 2);
|
|
|
|
SENSOR_TEMPLATE_2(pwm_temp_tolerance, "pwm%d_temp_tolerance", 0644,
|
2013-03-18 20:22:50 +04:00
|
|
|
show_temp_tolerance, store_temp_tolerance, 0, 0);
|
|
|
|
SENSOR_TEMPLATE_2(pwm_crit_temp_tolerance, "pwm%d_crit_temp_tolerance",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_temp_tolerance, store_temp_tolerance, 0, 1);
|
2013-03-18 20:22:50 +04:00
|
|
|
|
2022-04-27 04:01:52 +03:00
|
|
|
SENSOR_TEMPLATE_2(pwm_max, "pwm%d_max", 0644, show_pwm, store_pwm, 0, 3);
|
2013-03-18 20:22:50 +04:00
|
|
|
|
2022-04-27 04:01:52 +03:00
|
|
|
SENSOR_TEMPLATE_2(pwm_step, "pwm%d_step", 0644, show_pwm, store_pwm, 0, 4);
|
2013-03-18 20:22:50 +04:00
|
|
|
|
|
|
|
SENSOR_TEMPLATE_2(pwm_auto_point1_pwm, "pwm%d_auto_point1_pwm",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_auto_pwm, store_auto_pwm, 0, 0);
|
2013-03-18 20:22:50 +04:00
|
|
|
SENSOR_TEMPLATE_2(pwm_auto_point1_temp, "pwm%d_auto_point1_temp",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_auto_temp, store_auto_temp, 0, 0);
|
2013-03-18 20:22:50 +04:00
|
|
|
|
|
|
|
SENSOR_TEMPLATE_2(pwm_auto_point2_pwm, "pwm%d_auto_point2_pwm",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_auto_pwm, store_auto_pwm, 0, 1);
|
2013-03-18 20:22:50 +04:00
|
|
|
SENSOR_TEMPLATE_2(pwm_auto_point2_temp, "pwm%d_auto_point2_temp",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_auto_temp, store_auto_temp, 0, 1);
|
2013-03-18 20:22:50 +04:00
|
|
|
|
|
|
|
SENSOR_TEMPLATE_2(pwm_auto_point3_pwm, "pwm%d_auto_point3_pwm",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_auto_pwm, store_auto_pwm, 0, 2);
|
2013-03-18 20:22:50 +04:00
|
|
|
SENSOR_TEMPLATE_2(pwm_auto_point3_temp, "pwm%d_auto_point3_temp",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_auto_temp, store_auto_temp, 0, 2);
|
2013-03-18 20:22:50 +04:00
|
|
|
|
|
|
|
SENSOR_TEMPLATE_2(pwm_auto_point4_pwm, "pwm%d_auto_point4_pwm",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_auto_pwm, store_auto_pwm, 0, 3);
|
2013-03-18 20:22:50 +04:00
|
|
|
SENSOR_TEMPLATE_2(pwm_auto_point4_temp, "pwm%d_auto_point4_temp",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_auto_temp, store_auto_temp, 0, 3);
|
2013-03-18 20:22:50 +04:00
|
|
|
|
|
|
|
SENSOR_TEMPLATE_2(pwm_auto_point5_pwm, "pwm%d_auto_point5_pwm",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_auto_pwm, store_auto_pwm, 0, 4);
|
2013-03-18 20:22:50 +04:00
|
|
|
SENSOR_TEMPLATE_2(pwm_auto_point5_temp, "pwm%d_auto_point5_temp",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_auto_temp, store_auto_temp, 0, 4);
|
2013-03-18 20:22:50 +04:00
|
|
|
|
|
|
|
SENSOR_TEMPLATE_2(pwm_auto_point6_pwm, "pwm%d_auto_point6_pwm",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_auto_pwm, store_auto_pwm, 0, 5);
|
2013-03-18 20:22:50 +04:00
|
|
|
SENSOR_TEMPLATE_2(pwm_auto_point6_temp, "pwm%d_auto_point6_temp",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_auto_temp, store_auto_temp, 0, 5);
|
2013-03-18 20:22:50 +04:00
|
|
|
|
|
|
|
SENSOR_TEMPLATE_2(pwm_auto_point7_pwm, "pwm%d_auto_point7_pwm",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_auto_pwm, store_auto_pwm, 0, 6);
|
2013-03-18 20:22:50 +04:00
|
|
|
SENSOR_TEMPLATE_2(pwm_auto_point7_temp, "pwm%d_auto_point7_temp",
|
2022-04-27 04:01:52 +03:00
|
|
|
0644, show_auto_temp, store_auto_temp, 0, 6);
|
2013-03-18 20:22:50 +04:00
|
|
|
|
2012-12-04 21:04:52 +04:00
|
|
|
/*
|
2013-03-18 20:22:50 +04:00
|
|
|
* nct6775_pwm_is_visible uses the index into the following array
|
|
|
|
* to determine if attributes should be created or not.
|
|
|
|
* Any change in order or content must be matched.
|
2012-12-04 21:04:52 +04:00
|
|
|
*/
|
2013-03-18 20:22:50 +04:00
|
|
|
static struct sensor_device_template *nct6775_attributes_pwm_template[] = {
|
|
|
|
&sensor_dev_template_pwm,
|
|
|
|
&sensor_dev_template_pwm_mode,
|
|
|
|
&sensor_dev_template_pwm_enable,
|
|
|
|
&sensor_dev_template_pwm_temp_sel,
|
|
|
|
&sensor_dev_template_pwm_temp_tolerance,
|
|
|
|
&sensor_dev_template_pwm_crit_temp_tolerance,
|
|
|
|
&sensor_dev_template_pwm_target_temp,
|
|
|
|
&sensor_dev_template_fan_target,
|
|
|
|
&sensor_dev_template_fan_tolerance,
|
|
|
|
&sensor_dev_template_pwm_stop_time,
|
|
|
|
&sensor_dev_template_pwm_step_up_time,
|
|
|
|
&sensor_dev_template_pwm_step_down_time,
|
|
|
|
&sensor_dev_template_pwm_start,
|
|
|
|
&sensor_dev_template_pwm_floor,
|
2013-11-14 00:47:17 +04:00
|
|
|
&sensor_dev_template_pwm_weight_temp_sel, /* 14 */
|
2013-03-18 20:22:50 +04:00
|
|
|
&sensor_dev_template_pwm_weight_temp_step,
|
|
|
|
&sensor_dev_template_pwm_weight_temp_step_tol,
|
|
|
|
&sensor_dev_template_pwm_weight_temp_step_base,
|
2013-11-14 00:47:17 +04:00
|
|
|
&sensor_dev_template_pwm_weight_duty_step, /* 18 */
|
2013-03-18 20:22:50 +04:00
|
|
|
&sensor_dev_template_pwm_max, /* 19 */
|
|
|
|
&sensor_dev_template_pwm_step, /* 20 */
|
|
|
|
&sensor_dev_template_pwm_weight_duty_base, /* 21 */
|
|
|
|
&sensor_dev_template_pwm_auto_point1_pwm, /* 22 */
|
|
|
|
&sensor_dev_template_pwm_auto_point1_temp,
|
|
|
|
&sensor_dev_template_pwm_auto_point2_pwm,
|
|
|
|
&sensor_dev_template_pwm_auto_point2_temp,
|
|
|
|
&sensor_dev_template_pwm_auto_point3_pwm,
|
|
|
|
&sensor_dev_template_pwm_auto_point3_temp,
|
|
|
|
&sensor_dev_template_pwm_auto_point4_pwm,
|
|
|
|
&sensor_dev_template_pwm_auto_point4_temp,
|
|
|
|
&sensor_dev_template_pwm_auto_point5_pwm,
|
|
|
|
&sensor_dev_template_pwm_auto_point5_temp,
|
|
|
|
&sensor_dev_template_pwm_auto_point6_pwm,
|
|
|
|
&sensor_dev_template_pwm_auto_point6_temp,
|
|
|
|
&sensor_dev_template_pwm_auto_point7_pwm,
|
|
|
|
&sensor_dev_template_pwm_auto_point7_temp, /* 35 */
|
|
|
|
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2015-12-12 19:36:39 +03:00
|
|
|
static const struct sensor_template_group nct6775_pwm_template_group = {
|
2013-03-18 20:22:50 +04:00
|
|
|
.templates = nct6775_attributes_pwm_template,
|
|
|
|
.is_visible = nct6775_pwm_is_visible,
|
|
|
|
.base = 1,
|
2012-12-04 21:04:52 +04:00
|
|
|
};
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
static inline int nct6775_init_device(struct nct6775_data *data)
|
2012-05-21 06:29:48 +04:00
|
|
|
{
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int i, err;
|
|
|
|
u16 tmp, diode;
|
2012-05-21 06:29:48 +04:00
|
|
|
|
|
|
|
/* Start monitoring if needed */
|
|
|
|
if (data->REG_CONFIG) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_CONFIG, &tmp);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
if (!(tmp & 0x01)) {
|
|
|
|
err = nct6775_write_value(data, data->REG_CONFIG, tmp | 0x01);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
2012-05-21 06:29:48 +04:00
|
|
|
}
|
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
/* Enable temperature sensors if needed */
|
|
|
|
for (i = 0; i < NUM_TEMP; i++) {
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!(data->have_temp & BIT(i)))
|
2012-12-04 15:26:05 +04:00
|
|
|
continue;
|
|
|
|
if (!data->reg_temp_config[i])
|
|
|
|
continue;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->reg_temp_config[i], &tmp);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
if (tmp & 0x01) {
|
|
|
|
err = nct6775_write_value(data, data->reg_temp_config[i], tmp & 0xfe);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
2012-12-04 15:26:05 +04:00
|
|
|
}
|
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
/* Enable VBAT monitoring if needed */
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_VBAT, &tmp);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
if (!(tmp & 0x01)) {
|
|
|
|
err = nct6775_write_value(data, data->REG_VBAT, tmp | 0x01);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
2012-12-04 15:26:05 +04:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_DIODE, &diode);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 15:26:05 +04:00
|
|
|
|
|
|
|
for (i = 0; i < data->temp_fixed_num; i++) {
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!(data->have_temp_fixed & BIT(i)))
|
2012-12-04 15:26:05 +04:00
|
|
|
continue;
|
2012-07-01 19:23:15 +04:00
|
|
|
if ((tmp & (data->DIODE_MASK << i))) /* diode */
|
|
|
|
data->temp_type[i]
|
|
|
|
= 3 - ((diode >> i) & data->DIODE_MASK);
|
2012-12-04 15:26:05 +04:00
|
|
|
else /* thermistor */
|
|
|
|
data->temp_type[i] = 4;
|
|
|
|
}
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
|
|
|
|
return 0;
|
2012-05-21 06:29:48 +04:00
|
|
|
}
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
static int add_temp_sensors(struct nct6775_data *data, const u16 *regp,
|
|
|
|
int *available, int *mask)
|
2012-12-04 20:03:37 +04:00
|
|
|
{
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int i, err;
|
|
|
|
u16 src;
|
2012-12-04 20:03:37 +04:00
|
|
|
|
|
|
|
for (i = 0; i < data->pwm_num && *available; i++) {
|
|
|
|
int index;
|
|
|
|
|
|
|
|
if (!regp[i])
|
|
|
|
continue;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, regp[i], &src);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 20:03:37 +04:00
|
|
|
src &= 0x1f;
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!src || (*mask & BIT(src)))
|
2012-12-04 20:03:37 +04:00
|
|
|
continue;
|
2017-05-18 04:05:06 +03:00
|
|
|
if (!(data->temp_mask & BIT(src)))
|
2012-12-04 20:03:37 +04:00
|
|
|
continue;
|
|
|
|
|
|
|
|
index = __ffs(*available);
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_write_value(data, data->REG_TEMP_SOURCE[index], src);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2017-05-18 04:40:10 +03:00
|
|
|
*available &= ~BIT(index);
|
|
|
|
*mask |= BIT(src);
|
2012-12-04 20:03:37 +04:00
|
|
|
}
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
|
|
|
|
return 0;
|
2012-12-04 20:03:37 +04:00
|
|
|
}
|
|
|
|
|
2022-04-27 04:01:53 +03:00
|
|
|
int nct6775_probe(struct device *dev, struct nct6775_data *data,
|
|
|
|
const struct regmap_config *regmapcfg)
|
2012-05-21 06:29:48 +04:00
|
|
|
{
|
2012-12-04 15:26:05 +04:00
|
|
|
int i, s, err = 0;
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
int mask, available;
|
|
|
|
u16 src;
|
2012-12-04 15:26:05 +04:00
|
|
|
const u16 *reg_temp, *reg_temp_over, *reg_temp_hyst, *reg_temp_config;
|
2013-11-14 00:46:20 +04:00
|
|
|
const u16 *reg_temp_mon, *reg_temp_alternate, *reg_temp_crit;
|
2013-04-03 09:14:06 +04:00
|
|
|
const u16 *reg_temp_crit_l = NULL, *reg_temp_crit_h = NULL;
|
2022-01-13 19:46:29 +03:00
|
|
|
int num_reg_temp, num_reg_temp_mon, num_reg_tsi_temp;
|
2013-07-12 09:55:22 +04:00
|
|
|
struct device *hwmon_dev;
|
2022-01-13 19:46:29 +03:00
|
|
|
struct sensor_template_group tsi_temp_tg;
|
hwmon: (nct6775) Support access via Asus WMI
Support accessing the NCT677x via Asus WMI functions.
On mainboards that support this way of accessing the chip, the driver will
usually not work without this option since in these mainboards, ACPI will
mark the I/O port as used.
Code uses ACPI firmware interface to communicate with sensors with ASUS
motherboards:
* PRIME B460-PLUS,
* ROG CROSSHAIR VIII IMPACT,
* ROG STRIX B550-E GAMING,
* ROG STRIX B550-F GAMING,
* ROG STRIX B550-F GAMING (WI-FI),
* ROG STRIX Z490-I GAMING,
* TUF GAMING B550M-PLUS,
* TUF GAMING B550M-PLUS (WI-FI),
* TUF GAMING B550-PLUS,
* TUF GAMING X570-PLUS,
* TUF GAMING X570-PRO (WI-FI).
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204807
Signed-off-by: Denis Pauk <pauk.denis@gmail.com>
Co-developed-by: Bernhard Seibold <mail@bernhard-seibold.de>
Signed-off-by: Bernhard Seibold <mail@bernhard-seibold.de>
Tested-by: Pär Ekholm <pehlm@pekholm.org>
Tested-by: <to.eivind@gmail.com>
Tested-by: Artem S. Tashkinov <aros@gmx.com>
Tested-by: Vittorio Roberto Alfieri <me@rebtoor.com>
Tested-by: Sahan Fernando <sahan.h.fernando@gmail.com>
Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: Guenter Roeck <linux@roeck-us.net>
Link: https://lore.kernel.org/r/20210917220240.56553-4-pauk.denis@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2021-09-18 01:02:40 +03:00
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
data->regmap = devm_regmap_init(dev, NULL, data, regmapcfg);
|
|
|
|
if (IS_ERR(data->regmap))
|
|
|
|
return PTR_ERR(data->regmap);
|
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
mutex_init(&data->update_lock);
|
|
|
|
data->name = nct6775_device_names[data->kind];
|
|
|
|
data->bank = 0xff; /* Force initial bank selection */
|
2023-07-19 22:28:48 +03:00
|
|
|
data->scale_in = scale_in;
|
2012-05-21 06:29:48 +04:00
|
|
|
|
|
|
|
switch (data->kind) {
|
2012-07-01 19:23:15 +04:00
|
|
|
case nct6106:
|
|
|
|
data->in_num = 9;
|
|
|
|
data->pwm_num = 3;
|
|
|
|
data->auto_pwm_num = 4;
|
|
|
|
data->temp_fixed_num = 3;
|
|
|
|
data->num_temp_alarms = 6;
|
2013-06-25 09:21:59 +04:00
|
|
|
data->num_temp_beeps = 6;
|
2012-07-01 19:23:15 +04:00
|
|
|
|
|
|
|
data->fan_from_reg = fan_from_reg13;
|
|
|
|
data->fan_from_reg_min = fan_from_reg13;
|
|
|
|
|
|
|
|
data->temp_label = nct6776_temp_label;
|
2017-05-18 04:05:06 +03:00
|
|
|
data->temp_mask = NCT6776_TEMP_MASK;
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
data->virt_temp_mask = NCT6776_VIRT_TEMP_MASK;
|
2012-07-01 19:23:15 +04:00
|
|
|
|
|
|
|
data->REG_VBAT = NCT6106_REG_VBAT;
|
|
|
|
data->REG_DIODE = NCT6106_REG_DIODE;
|
|
|
|
data->DIODE_MASK = NCT6106_DIODE_MASK;
|
|
|
|
data->REG_VIN = NCT6106_REG_IN;
|
|
|
|
data->REG_IN_MINMAX[0] = NCT6106_REG_IN_MIN;
|
|
|
|
data->REG_IN_MINMAX[1] = NCT6106_REG_IN_MAX;
|
|
|
|
data->REG_TARGET = NCT6106_REG_TARGET;
|
|
|
|
data->REG_FAN = NCT6106_REG_FAN;
|
|
|
|
data->REG_FAN_MODE = NCT6106_REG_FAN_MODE;
|
|
|
|
data->REG_FAN_MIN = NCT6106_REG_FAN_MIN;
|
|
|
|
data->REG_FAN_PULSES = NCT6106_REG_FAN_PULSES;
|
|
|
|
data->FAN_PULSE_SHIFT = NCT6106_FAN_PULSE_SHIFT;
|
|
|
|
data->REG_FAN_TIME[0] = NCT6106_REG_FAN_STOP_TIME;
|
|
|
|
data->REG_FAN_TIME[1] = NCT6106_REG_FAN_STEP_UP_TIME;
|
|
|
|
data->REG_FAN_TIME[2] = NCT6106_REG_FAN_STEP_DOWN_TIME;
|
2019-07-15 19:33:55 +03:00
|
|
|
data->REG_TOLERANCE_H = NCT6106_REG_TOLERANCE_H;
|
2019-07-23 19:06:46 +03:00
|
|
|
data->REG_PWM[0] = NCT6116_REG_PWM;
|
2012-07-01 19:23:15 +04:00
|
|
|
data->REG_PWM[1] = NCT6106_REG_FAN_START_OUTPUT;
|
|
|
|
data->REG_PWM[2] = NCT6106_REG_FAN_STOP_OUTPUT;
|
|
|
|
data->REG_PWM[5] = NCT6106_REG_WEIGHT_DUTY_STEP;
|
|
|
|
data->REG_PWM[6] = NCT6106_REG_WEIGHT_DUTY_BASE;
|
|
|
|
data->REG_PWM_READ = NCT6106_REG_PWM_READ;
|
|
|
|
data->REG_PWM_MODE = NCT6106_REG_PWM_MODE;
|
|
|
|
data->PWM_MODE_MASK = NCT6106_PWM_MODE_MASK;
|
|
|
|
data->REG_AUTO_TEMP = NCT6106_REG_AUTO_TEMP;
|
|
|
|
data->REG_AUTO_PWM = NCT6106_REG_AUTO_PWM;
|
|
|
|
data->REG_CRITICAL_TEMP = NCT6106_REG_CRITICAL_TEMP;
|
|
|
|
data->REG_CRITICAL_TEMP_TOLERANCE
|
|
|
|
= NCT6106_REG_CRITICAL_TEMP_TOLERANCE;
|
|
|
|
data->REG_CRITICAL_PWM_ENABLE = NCT6106_REG_CRITICAL_PWM_ENABLE;
|
|
|
|
data->CRITICAL_PWM_ENABLE_MASK
|
|
|
|
= NCT6106_CRITICAL_PWM_ENABLE_MASK;
|
|
|
|
data->REG_CRITICAL_PWM = NCT6106_REG_CRITICAL_PWM;
|
|
|
|
data->REG_TEMP_OFFSET = NCT6106_REG_TEMP_OFFSET;
|
|
|
|
data->REG_TEMP_SOURCE = NCT6106_REG_TEMP_SOURCE;
|
2019-07-23 19:06:46 +03:00
|
|
|
data->REG_TEMP_SEL = NCT6116_REG_TEMP_SEL;
|
2012-07-01 19:23:15 +04:00
|
|
|
data->REG_WEIGHT_TEMP_SEL = NCT6106_REG_WEIGHT_TEMP_SEL;
|
|
|
|
data->REG_WEIGHT_TEMP[0] = NCT6106_REG_WEIGHT_TEMP_STEP;
|
|
|
|
data->REG_WEIGHT_TEMP[1] = NCT6106_REG_WEIGHT_TEMP_STEP_TOL;
|
|
|
|
data->REG_WEIGHT_TEMP[2] = NCT6106_REG_WEIGHT_TEMP_BASE;
|
|
|
|
data->REG_ALARM = NCT6106_REG_ALARM;
|
|
|
|
data->ALARM_BITS = NCT6106_ALARM_BITS;
|
2013-06-25 09:21:59 +04:00
|
|
|
data->REG_BEEP = NCT6106_REG_BEEP;
|
|
|
|
data->BEEP_BITS = NCT6106_BEEP_BITS;
|
2022-01-13 19:46:29 +03:00
|
|
|
data->REG_TSI_TEMP = NCT6106_REG_TSI_TEMP;
|
2012-07-01 19:23:15 +04:00
|
|
|
|
|
|
|
reg_temp = NCT6106_REG_TEMP;
|
2013-11-14 00:46:20 +04:00
|
|
|
reg_temp_mon = NCT6106_REG_TEMP_MON;
|
2012-07-01 19:23:15 +04:00
|
|
|
num_reg_temp = ARRAY_SIZE(NCT6106_REG_TEMP);
|
2013-11-14 00:46:20 +04:00
|
|
|
num_reg_temp_mon = ARRAY_SIZE(NCT6106_REG_TEMP_MON);
|
2022-01-13 19:46:29 +03:00
|
|
|
num_reg_tsi_temp = ARRAY_SIZE(NCT6106_REG_TSI_TEMP);
|
2012-07-01 19:23:15 +04:00
|
|
|
reg_temp_over = NCT6106_REG_TEMP_OVER;
|
|
|
|
reg_temp_hyst = NCT6106_REG_TEMP_HYST;
|
|
|
|
reg_temp_config = NCT6106_REG_TEMP_CONFIG;
|
|
|
|
reg_temp_alternate = NCT6106_REG_TEMP_ALTERNATE;
|
|
|
|
reg_temp_crit = NCT6106_REG_TEMP_CRIT;
|
2013-04-03 09:14:06 +04:00
|
|
|
reg_temp_crit_l = NCT6106_REG_TEMP_CRIT_L;
|
|
|
|
reg_temp_crit_h = NCT6106_REG_TEMP_CRIT_H;
|
2012-07-01 19:23:15 +04:00
|
|
|
|
2019-07-23 19:06:46 +03:00
|
|
|
break;
|
|
|
|
case nct6116:
|
|
|
|
data->in_num = 9;
|
|
|
|
data->pwm_num = 3;
|
|
|
|
data->auto_pwm_num = 4;
|
|
|
|
data->temp_fixed_num = 3;
|
|
|
|
data->num_temp_alarms = 3;
|
|
|
|
data->num_temp_beeps = 3;
|
|
|
|
|
|
|
|
data->fan_from_reg = fan_from_reg13;
|
|
|
|
data->fan_from_reg_min = fan_from_reg13;
|
|
|
|
|
|
|
|
data->temp_label = nct6776_temp_label;
|
|
|
|
data->temp_mask = NCT6776_TEMP_MASK;
|
|
|
|
data->virt_temp_mask = NCT6776_VIRT_TEMP_MASK;
|
|
|
|
|
|
|
|
data->REG_VBAT = NCT6106_REG_VBAT;
|
|
|
|
data->REG_DIODE = NCT6106_REG_DIODE;
|
|
|
|
data->DIODE_MASK = NCT6106_DIODE_MASK;
|
|
|
|
data->REG_VIN = NCT6106_REG_IN;
|
|
|
|
data->REG_IN_MINMAX[0] = NCT6106_REG_IN_MIN;
|
|
|
|
data->REG_IN_MINMAX[1] = NCT6106_REG_IN_MAX;
|
|
|
|
data->REG_TARGET = NCT6116_REG_TARGET;
|
|
|
|
data->REG_FAN = NCT6116_REG_FAN;
|
|
|
|
data->REG_FAN_MODE = NCT6116_REG_FAN_MODE;
|
|
|
|
data->REG_FAN_MIN = NCT6116_REG_FAN_MIN;
|
|
|
|
data->REG_FAN_PULSES = NCT6116_REG_FAN_PULSES;
|
|
|
|
data->FAN_PULSE_SHIFT = NCT6116_FAN_PULSE_SHIFT;
|
|
|
|
data->REG_FAN_TIME[0] = NCT6116_REG_FAN_STOP_TIME;
|
|
|
|
data->REG_FAN_TIME[1] = NCT6116_REG_FAN_STEP_UP_TIME;
|
|
|
|
data->REG_FAN_TIME[2] = NCT6116_REG_FAN_STEP_DOWN_TIME;
|
|
|
|
data->REG_TOLERANCE_H = NCT6116_REG_TOLERANCE_H;
|
|
|
|
data->REG_PWM[0] = NCT6116_REG_PWM;
|
|
|
|
data->REG_PWM[1] = NCT6116_REG_FAN_START_OUTPUT;
|
|
|
|
data->REG_PWM[2] = NCT6116_REG_FAN_STOP_OUTPUT;
|
|
|
|
data->REG_PWM[5] = NCT6106_REG_WEIGHT_DUTY_STEP;
|
|
|
|
data->REG_PWM[6] = NCT6106_REG_WEIGHT_DUTY_BASE;
|
|
|
|
data->REG_PWM_READ = NCT6106_REG_PWM_READ;
|
|
|
|
data->REG_PWM_MODE = NCT6106_REG_PWM_MODE;
|
|
|
|
data->PWM_MODE_MASK = NCT6106_PWM_MODE_MASK;
|
|
|
|
data->REG_AUTO_TEMP = NCT6116_REG_AUTO_TEMP;
|
|
|
|
data->REG_AUTO_PWM = NCT6116_REG_AUTO_PWM;
|
|
|
|
data->REG_CRITICAL_TEMP = NCT6116_REG_CRITICAL_TEMP;
|
|
|
|
data->REG_CRITICAL_TEMP_TOLERANCE
|
|
|
|
= NCT6116_REG_CRITICAL_TEMP_TOLERANCE;
|
|
|
|
data->REG_CRITICAL_PWM_ENABLE = NCT6116_REG_CRITICAL_PWM_ENABLE;
|
|
|
|
data->CRITICAL_PWM_ENABLE_MASK
|
|
|
|
= NCT6106_CRITICAL_PWM_ENABLE_MASK;
|
|
|
|
data->REG_CRITICAL_PWM = NCT6116_REG_CRITICAL_PWM;
|
|
|
|
data->REG_TEMP_OFFSET = NCT6106_REG_TEMP_OFFSET;
|
|
|
|
data->REG_TEMP_SOURCE = NCT6116_REG_TEMP_SOURCE;
|
|
|
|
data->REG_TEMP_SEL = NCT6116_REG_TEMP_SEL;
|
|
|
|
data->REG_WEIGHT_TEMP_SEL = NCT6106_REG_WEIGHT_TEMP_SEL;
|
|
|
|
data->REG_WEIGHT_TEMP[0] = NCT6106_REG_WEIGHT_TEMP_STEP;
|
|
|
|
data->REG_WEIGHT_TEMP[1] = NCT6106_REG_WEIGHT_TEMP_STEP_TOL;
|
|
|
|
data->REG_WEIGHT_TEMP[2] = NCT6106_REG_WEIGHT_TEMP_BASE;
|
|
|
|
data->REG_ALARM = NCT6106_REG_ALARM;
|
|
|
|
data->ALARM_BITS = NCT6116_ALARM_BITS;
|
|
|
|
data->REG_BEEP = NCT6106_REG_BEEP;
|
|
|
|
data->BEEP_BITS = NCT6116_BEEP_BITS;
|
2022-01-13 19:46:29 +03:00
|
|
|
data->REG_TSI_TEMP = NCT6116_REG_TSI_TEMP;
|
2019-07-23 19:06:46 +03:00
|
|
|
|
|
|
|
reg_temp = NCT6106_REG_TEMP;
|
|
|
|
reg_temp_mon = NCT6106_REG_TEMP_MON;
|
|
|
|
num_reg_temp = ARRAY_SIZE(NCT6106_REG_TEMP);
|
|
|
|
num_reg_temp_mon = ARRAY_SIZE(NCT6106_REG_TEMP_MON);
|
2022-01-13 19:46:29 +03:00
|
|
|
num_reg_tsi_temp = ARRAY_SIZE(NCT6116_REG_TSI_TEMP);
|
2019-07-23 19:06:46 +03:00
|
|
|
reg_temp_over = NCT6106_REG_TEMP_OVER;
|
|
|
|
reg_temp_hyst = NCT6106_REG_TEMP_HYST;
|
|
|
|
reg_temp_config = NCT6106_REG_TEMP_CONFIG;
|
|
|
|
reg_temp_alternate = NCT6106_REG_TEMP_ALTERNATE;
|
|
|
|
reg_temp_crit = NCT6106_REG_TEMP_CRIT;
|
|
|
|
reg_temp_crit_l = NCT6106_REG_TEMP_CRIT_L;
|
|
|
|
reg_temp_crit_h = NCT6106_REG_TEMP_CRIT_H;
|
|
|
|
|
2012-07-01 19:23:15 +04:00
|
|
|
break;
|
2012-05-21 06:29:48 +04:00
|
|
|
case nct6775:
|
|
|
|
data->in_num = 9;
|
2012-12-04 20:30:54 +04:00
|
|
|
data->pwm_num = 3;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->auto_pwm_num = 6;
|
2012-12-04 19:56:24 +04:00
|
|
|
data->has_fan_div = true;
|
2012-12-04 15:26:05 +04:00
|
|
|
data->temp_fixed_num = 3;
|
2013-06-23 03:15:31 +04:00
|
|
|
data->num_temp_alarms = 3;
|
2013-06-25 09:21:59 +04:00
|
|
|
data->num_temp_beeps = 3;
|
2012-05-21 06:29:48 +04:00
|
|
|
|
|
|
|
data->ALARM_BITS = NCT6775_ALARM_BITS;
|
2013-06-25 09:21:59 +04:00
|
|
|
data->BEEP_BITS = NCT6775_BEEP_BITS;
|
2012-05-21 06:29:48 +04:00
|
|
|
|
2012-12-04 19:56:24 +04:00
|
|
|
data->fan_from_reg = fan_from_reg16;
|
|
|
|
data->fan_from_reg_min = fan_from_reg8;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->target_temp_mask = 0x7f;
|
|
|
|
data->tolerance_mask = 0x0f;
|
|
|
|
data->speed_tolerance_limit = 15;
|
2012-12-04 19:56:24 +04:00
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
data->temp_label = nct6775_temp_label;
|
2017-05-18 04:05:06 +03:00
|
|
|
data->temp_mask = NCT6775_TEMP_MASK;
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
data->virt_temp_mask = NCT6775_VIRT_TEMP_MASK;
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
data->REG_CONFIG = NCT6775_REG_CONFIG;
|
|
|
|
data->REG_VBAT = NCT6775_REG_VBAT;
|
2012-12-04 15:26:05 +04:00
|
|
|
data->REG_DIODE = NCT6775_REG_DIODE;
|
2012-07-01 19:23:15 +04:00
|
|
|
data->DIODE_MASK = NCT6775_DIODE_MASK;
|
2012-05-21 06:29:48 +04:00
|
|
|
data->REG_VIN = NCT6775_REG_IN;
|
|
|
|
data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
|
|
|
|
data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_TARGET = NCT6775_REG_TARGET;
|
2012-12-04 19:56:24 +04:00
|
|
|
data->REG_FAN = NCT6775_REG_FAN;
|
2012-12-04 20:30:54 +04:00
|
|
|
data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
|
2012-12-04 19:56:24 +04:00
|
|
|
data->REG_FAN_MIN = NCT6775_REG_FAN_MIN;
|
2012-12-11 19:29:06 +04:00
|
|
|
data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES;
|
2012-07-01 19:23:15 +04:00
|
|
|
data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
|
|
|
|
data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
|
|
|
|
data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
|
2012-12-04 20:30:54 +04:00
|
|
|
data->REG_PWM[0] = NCT6775_REG_PWM;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
|
|
|
|
data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
|
|
|
|
data->REG_PWM[3] = NCT6775_REG_FAN_MAX_OUTPUT;
|
|
|
|
data->REG_PWM[4] = NCT6775_REG_FAN_STEP_OUTPUT;
|
2012-12-04 21:08:29 +04:00
|
|
|
data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
|
2012-12-04 20:30:54 +04:00
|
|
|
data->REG_PWM_READ = NCT6775_REG_PWM_READ;
|
|
|
|
data->REG_PWM_MODE = NCT6775_REG_PWM_MODE;
|
|
|
|
data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
|
|
|
|
data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
|
|
|
|
data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
|
|
|
|
data->REG_CRITICAL_TEMP_TOLERANCE
|
|
|
|
= NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
|
2012-12-04 15:26:05 +04:00
|
|
|
data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
|
|
|
|
data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
|
2012-12-04 21:08:29 +04:00
|
|
|
data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
|
|
|
|
data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
|
|
|
|
data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
|
|
|
|
data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
|
2012-05-21 06:29:48 +04:00
|
|
|
data->REG_ALARM = NCT6775_REG_ALARM;
|
2013-06-25 09:21:59 +04:00
|
|
|
data->REG_BEEP = NCT6775_REG_BEEP;
|
2022-01-13 19:46:29 +03:00
|
|
|
data->REG_TSI_TEMP = NCT6775_REG_TSI_TEMP;
|
2012-12-04 15:26:05 +04:00
|
|
|
|
|
|
|
reg_temp = NCT6775_REG_TEMP;
|
2013-11-14 00:46:20 +04:00
|
|
|
reg_temp_mon = NCT6775_REG_TEMP_MON;
|
2012-12-04 15:26:05 +04:00
|
|
|
num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
|
2013-11-14 00:46:20 +04:00
|
|
|
num_reg_temp_mon = ARRAY_SIZE(NCT6775_REG_TEMP_MON);
|
2022-01-13 19:46:29 +03:00
|
|
|
num_reg_tsi_temp = ARRAY_SIZE(NCT6775_REG_TSI_TEMP);
|
2012-12-04 15:26:05 +04:00
|
|
|
reg_temp_over = NCT6775_REG_TEMP_OVER;
|
|
|
|
reg_temp_hyst = NCT6775_REG_TEMP_HYST;
|
|
|
|
reg_temp_config = NCT6775_REG_TEMP_CONFIG;
|
|
|
|
reg_temp_alternate = NCT6775_REG_TEMP_ALTERNATE;
|
|
|
|
reg_temp_crit = NCT6775_REG_TEMP_CRIT;
|
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
break;
|
|
|
|
case nct6776:
|
|
|
|
data->in_num = 9;
|
2012-12-04 20:30:54 +04:00
|
|
|
data->pwm_num = 3;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->auto_pwm_num = 4;
|
2012-12-04 19:56:24 +04:00
|
|
|
data->has_fan_div = false;
|
2012-12-04 15:26:05 +04:00
|
|
|
data->temp_fixed_num = 3;
|
2013-06-23 03:15:31 +04:00
|
|
|
data->num_temp_alarms = 3;
|
2013-06-25 09:21:59 +04:00
|
|
|
data->num_temp_beeps = 6;
|
2012-05-21 06:29:48 +04:00
|
|
|
|
|
|
|
data->ALARM_BITS = NCT6776_ALARM_BITS;
|
2013-06-25 09:21:59 +04:00
|
|
|
data->BEEP_BITS = NCT6776_BEEP_BITS;
|
2012-05-21 06:29:48 +04:00
|
|
|
|
2012-12-04 19:56:24 +04:00
|
|
|
data->fan_from_reg = fan_from_reg13;
|
|
|
|
data->fan_from_reg_min = fan_from_reg13;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->target_temp_mask = 0xff;
|
|
|
|
data->tolerance_mask = 0x07;
|
|
|
|
data->speed_tolerance_limit = 63;
|
2012-12-04 19:56:24 +04:00
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
data->temp_label = nct6776_temp_label;
|
2017-05-18 04:05:06 +03:00
|
|
|
data->temp_mask = NCT6776_TEMP_MASK;
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
data->virt_temp_mask = NCT6776_VIRT_TEMP_MASK;
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
data->REG_CONFIG = NCT6775_REG_CONFIG;
|
|
|
|
data->REG_VBAT = NCT6775_REG_VBAT;
|
2012-12-04 15:26:05 +04:00
|
|
|
data->REG_DIODE = NCT6775_REG_DIODE;
|
2012-07-01 19:23:15 +04:00
|
|
|
data->DIODE_MASK = NCT6775_DIODE_MASK;
|
2012-05-21 06:29:48 +04:00
|
|
|
data->REG_VIN = NCT6775_REG_IN;
|
|
|
|
data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
|
|
|
|
data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_TARGET = NCT6775_REG_TARGET;
|
2012-12-04 19:56:24 +04:00
|
|
|
data->REG_FAN = NCT6775_REG_FAN;
|
2012-12-04 20:30:54 +04:00
|
|
|
data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
|
2012-12-04 19:56:24 +04:00
|
|
|
data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
|
2012-12-11 19:29:06 +04:00
|
|
|
data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES;
|
2012-07-01 19:23:15 +04:00
|
|
|
data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
|
2015-09-01 02:13:47 +03:00
|
|
|
data->REG_FAN_TIME[1] = NCT6776_REG_FAN_STEP_UP_TIME;
|
|
|
|
data->REG_FAN_TIME[2] = NCT6776_REG_FAN_STEP_DOWN_TIME;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
|
2012-12-04 20:30:54 +04:00
|
|
|
data->REG_PWM[0] = NCT6775_REG_PWM;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
|
|
|
|
data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
|
2012-12-04 21:08:29 +04:00
|
|
|
data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
|
|
|
|
data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
|
2012-12-04 20:30:54 +04:00
|
|
|
data->REG_PWM_READ = NCT6775_REG_PWM_READ;
|
|
|
|
data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
|
|
|
|
data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
|
|
|
|
data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
|
|
|
|
data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
|
|
|
|
data->REG_CRITICAL_TEMP_TOLERANCE
|
|
|
|
= NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
|
2012-12-04 15:26:05 +04:00
|
|
|
data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
|
|
|
|
data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
|
2012-12-04 21:08:29 +04:00
|
|
|
data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
|
|
|
|
data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
|
|
|
|
data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
|
|
|
|
data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
|
2012-05-21 06:29:48 +04:00
|
|
|
data->REG_ALARM = NCT6775_REG_ALARM;
|
2013-06-25 09:21:59 +04:00
|
|
|
data->REG_BEEP = NCT6776_REG_BEEP;
|
2022-01-13 19:46:29 +03:00
|
|
|
data->REG_TSI_TEMP = NCT6776_REG_TSI_TEMP;
|
2012-12-04 15:26:05 +04:00
|
|
|
|
|
|
|
reg_temp = NCT6775_REG_TEMP;
|
2013-11-14 00:46:20 +04:00
|
|
|
reg_temp_mon = NCT6775_REG_TEMP_MON;
|
2012-12-04 15:26:05 +04:00
|
|
|
num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
|
2013-11-14 00:46:20 +04:00
|
|
|
num_reg_temp_mon = ARRAY_SIZE(NCT6775_REG_TEMP_MON);
|
2022-01-13 19:46:29 +03:00
|
|
|
num_reg_tsi_temp = ARRAY_SIZE(NCT6776_REG_TSI_TEMP);
|
2012-12-04 15:26:05 +04:00
|
|
|
reg_temp_over = NCT6775_REG_TEMP_OVER;
|
|
|
|
reg_temp_hyst = NCT6775_REG_TEMP_HYST;
|
|
|
|
reg_temp_config = NCT6776_REG_TEMP_CONFIG;
|
|
|
|
reg_temp_alternate = NCT6776_REG_TEMP_ALTERNATE;
|
|
|
|
reg_temp_crit = NCT6776_REG_TEMP_CRIT;
|
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
break;
|
|
|
|
case nct6779:
|
|
|
|
data->in_num = 15;
|
2012-12-04 20:30:54 +04:00
|
|
|
data->pwm_num = 5;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->auto_pwm_num = 4;
|
2012-12-04 19:56:24 +04:00
|
|
|
data->has_fan_div = false;
|
2012-12-04 15:26:05 +04:00
|
|
|
data->temp_fixed_num = 6;
|
2013-06-23 03:15:31 +04:00
|
|
|
data->num_temp_alarms = 2;
|
2013-06-25 09:21:59 +04:00
|
|
|
data->num_temp_beeps = 2;
|
2012-05-21 06:29:48 +04:00
|
|
|
|
|
|
|
data->ALARM_BITS = NCT6779_ALARM_BITS;
|
2013-06-25 09:21:59 +04:00
|
|
|
data->BEEP_BITS = NCT6779_BEEP_BITS;
|
2012-05-21 06:29:48 +04:00
|
|
|
|
2018-09-14 06:01:12 +03:00
|
|
|
data->fan_from_reg = fan_from_reg_rpm;
|
2012-12-04 19:56:24 +04:00
|
|
|
data->fan_from_reg_min = fan_from_reg13;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->target_temp_mask = 0xff;
|
|
|
|
data->tolerance_mask = 0x07;
|
|
|
|
data->speed_tolerance_limit = 63;
|
2012-12-04 19:56:24 +04:00
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
data->temp_label = nct6779_temp_label;
|
2017-05-18 04:05:06 +03:00
|
|
|
data->temp_mask = NCT6779_TEMP_MASK;
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
data->virt_temp_mask = NCT6779_VIRT_TEMP_MASK;
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
data->REG_CONFIG = NCT6775_REG_CONFIG;
|
|
|
|
data->REG_VBAT = NCT6775_REG_VBAT;
|
2012-12-04 15:26:05 +04:00
|
|
|
data->REG_DIODE = NCT6775_REG_DIODE;
|
2012-07-01 19:23:15 +04:00
|
|
|
data->DIODE_MASK = NCT6775_DIODE_MASK;
|
2012-05-21 06:29:48 +04:00
|
|
|
data->REG_VIN = NCT6779_REG_IN;
|
|
|
|
data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
|
|
|
|
data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_TARGET = NCT6775_REG_TARGET;
|
2012-12-04 19:56:24 +04:00
|
|
|
data->REG_FAN = NCT6779_REG_FAN;
|
2012-12-04 20:30:54 +04:00
|
|
|
data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
|
2012-12-04 19:56:24 +04:00
|
|
|
data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
|
2012-12-11 19:29:06 +04:00
|
|
|
data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
|
2012-07-01 19:23:15 +04:00
|
|
|
data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
|
2015-09-01 02:13:47 +03:00
|
|
|
data->REG_FAN_TIME[1] = NCT6776_REG_FAN_STEP_UP_TIME;
|
|
|
|
data->REG_FAN_TIME[2] = NCT6776_REG_FAN_STEP_DOWN_TIME;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
|
2012-12-04 20:30:54 +04:00
|
|
|
data->REG_PWM[0] = NCT6775_REG_PWM;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
|
|
|
|
data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
|
2012-12-04 21:08:29 +04:00
|
|
|
data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
|
|
|
|
data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
|
2012-12-04 20:30:54 +04:00
|
|
|
data->REG_PWM_READ = NCT6775_REG_PWM_READ;
|
|
|
|
data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
|
|
|
|
data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
|
|
|
|
data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
|
|
|
|
data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
|
|
|
|
data->REG_CRITICAL_TEMP_TOLERANCE
|
|
|
|
= NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
|
2012-07-01 19:23:15 +04:00
|
|
|
data->REG_CRITICAL_PWM_ENABLE = NCT6779_REG_CRITICAL_PWM_ENABLE;
|
|
|
|
data->CRITICAL_PWM_ENABLE_MASK
|
|
|
|
= NCT6779_CRITICAL_PWM_ENABLE_MASK;
|
|
|
|
data->REG_CRITICAL_PWM = NCT6779_REG_CRITICAL_PWM;
|
2012-12-04 15:26:05 +04:00
|
|
|
data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
|
|
|
|
data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
|
2012-12-04 21:04:52 +04:00
|
|
|
data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
|
2012-12-04 21:08:29 +04:00
|
|
|
data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
|
|
|
|
data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
|
|
|
|
data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
|
|
|
|
data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
|
2012-05-21 06:29:48 +04:00
|
|
|
data->REG_ALARM = NCT6779_REG_ALARM;
|
2013-06-25 09:21:59 +04:00
|
|
|
data->REG_BEEP = NCT6776_REG_BEEP;
|
2022-01-13 19:46:29 +03:00
|
|
|
data->REG_TSI_TEMP = NCT6776_REG_TSI_TEMP;
|
2012-12-04 15:26:05 +04:00
|
|
|
|
|
|
|
reg_temp = NCT6779_REG_TEMP;
|
2013-11-14 00:46:20 +04:00
|
|
|
reg_temp_mon = NCT6779_REG_TEMP_MON;
|
2012-12-04 15:26:05 +04:00
|
|
|
num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP);
|
2013-11-14 00:46:20 +04:00
|
|
|
num_reg_temp_mon = ARRAY_SIZE(NCT6779_REG_TEMP_MON);
|
2022-01-13 19:46:29 +03:00
|
|
|
num_reg_tsi_temp = ARRAY_SIZE(NCT6776_REG_TSI_TEMP);
|
2012-12-04 15:26:05 +04:00
|
|
|
reg_temp_over = NCT6779_REG_TEMP_OVER;
|
|
|
|
reg_temp_hyst = NCT6779_REG_TEMP_HYST;
|
|
|
|
reg_temp_config = NCT6779_REG_TEMP_CONFIG;
|
|
|
|
reg_temp_alternate = NCT6779_REG_TEMP_ALTERNATE;
|
|
|
|
reg_temp_crit = NCT6779_REG_TEMP_CRIT;
|
|
|
|
|
2013-06-25 09:28:28 +04:00
|
|
|
break;
|
|
|
|
case nct6791:
|
2014-11-16 20:50:04 +03:00
|
|
|
case nct6792:
|
2015-08-31 05:45:19 +03:00
|
|
|
case nct6793:
|
2017-05-18 04:19:18 +03:00
|
|
|
case nct6795:
|
2018-02-22 00:09:39 +03:00
|
|
|
case nct6796:
|
2018-09-19 06:48:29 +03:00
|
|
|
case nct6797:
|
2018-09-20 06:26:16 +03:00
|
|
|
case nct6798:
|
2022-12-28 16:57:44 +03:00
|
|
|
case nct6799:
|
2013-06-25 09:28:28 +04:00
|
|
|
data->in_num = 15;
|
2018-09-19 06:48:29 +03:00
|
|
|
data->pwm_num = (data->kind == nct6796 ||
|
2018-09-20 06:26:16 +03:00
|
|
|
data->kind == nct6797 ||
|
2022-12-28 16:57:44 +03:00
|
|
|
data->kind == nct6798 ||
|
|
|
|
data->kind == nct6799) ? 7 : 6;
|
2013-06-25 09:28:28 +04:00
|
|
|
data->auto_pwm_num = 4;
|
|
|
|
data->has_fan_div = false;
|
|
|
|
data->temp_fixed_num = 6;
|
|
|
|
data->num_temp_alarms = 2;
|
|
|
|
data->num_temp_beeps = 2;
|
|
|
|
|
|
|
|
data->ALARM_BITS = NCT6791_ALARM_BITS;
|
|
|
|
data->BEEP_BITS = NCT6779_BEEP_BITS;
|
|
|
|
|
2018-09-14 06:01:12 +03:00
|
|
|
data->fan_from_reg = fan_from_reg_rpm;
|
2013-06-25 09:28:28 +04:00
|
|
|
data->fan_from_reg_min = fan_from_reg13;
|
|
|
|
data->target_temp_mask = 0xff;
|
|
|
|
data->tolerance_mask = 0x07;
|
|
|
|
data->speed_tolerance_limit = 63;
|
|
|
|
|
2015-10-30 17:52:39 +03:00
|
|
|
switch (data->kind) {
|
|
|
|
default:
|
|
|
|
case nct6791:
|
|
|
|
data->temp_label = nct6779_temp_label;
|
2017-05-18 04:05:06 +03:00
|
|
|
data->temp_mask = NCT6791_TEMP_MASK;
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
data->virt_temp_mask = NCT6791_VIRT_TEMP_MASK;
|
2015-10-30 17:52:39 +03:00
|
|
|
break;
|
|
|
|
case nct6792:
|
|
|
|
data->temp_label = nct6792_temp_label;
|
2017-05-18 04:05:06 +03:00
|
|
|
data->temp_mask = NCT6792_TEMP_MASK;
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
data->virt_temp_mask = NCT6792_VIRT_TEMP_MASK;
|
2015-10-30 17:52:39 +03:00
|
|
|
break;
|
|
|
|
case nct6793:
|
|
|
|
data->temp_label = nct6793_temp_label;
|
2017-05-18 04:05:06 +03:00
|
|
|
data->temp_mask = NCT6793_TEMP_MASK;
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
data->virt_temp_mask = NCT6793_VIRT_TEMP_MASK;
|
2015-10-30 17:52:39 +03:00
|
|
|
break;
|
2017-05-18 04:19:18 +03:00
|
|
|
case nct6795:
|
2018-09-19 06:48:29 +03:00
|
|
|
case nct6797:
|
2017-05-18 04:19:18 +03:00
|
|
|
data->temp_label = nct6795_temp_label;
|
|
|
|
data->temp_mask = NCT6795_TEMP_MASK;
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
data->virt_temp_mask = NCT6795_VIRT_TEMP_MASK;
|
2017-05-18 04:19:18 +03:00
|
|
|
break;
|
2018-02-22 00:09:39 +03:00
|
|
|
case nct6796:
|
|
|
|
data->temp_label = nct6796_temp_label;
|
|
|
|
data->temp_mask = NCT6796_TEMP_MASK;
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
data->virt_temp_mask = NCT6796_VIRT_TEMP_MASK;
|
2018-02-22 00:09:39 +03:00
|
|
|
break;
|
2018-09-20 06:26:16 +03:00
|
|
|
case nct6798:
|
|
|
|
data->temp_label = nct6798_temp_label;
|
|
|
|
data->temp_mask = NCT6798_TEMP_MASK;
|
|
|
|
data->virt_temp_mask = NCT6798_VIRT_TEMP_MASK;
|
|
|
|
break;
|
2022-12-28 16:57:44 +03:00
|
|
|
case nct6799:
|
|
|
|
data->temp_label = nct6799_temp_label;
|
|
|
|
data->temp_mask = NCT6799_TEMP_MASK;
|
|
|
|
data->virt_temp_mask = NCT6799_VIRT_TEMP_MASK;
|
|
|
|
break;
|
2015-10-30 17:52:39 +03:00
|
|
|
}
|
2013-06-25 09:28:28 +04:00
|
|
|
|
|
|
|
data->REG_CONFIG = NCT6775_REG_CONFIG;
|
|
|
|
data->REG_VBAT = NCT6775_REG_VBAT;
|
|
|
|
data->REG_DIODE = NCT6775_REG_DIODE;
|
|
|
|
data->DIODE_MASK = NCT6775_DIODE_MASK;
|
|
|
|
data->REG_VIN = NCT6779_REG_IN;
|
|
|
|
data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
|
|
|
|
data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
|
|
|
|
data->REG_TARGET = NCT6775_REG_TARGET;
|
|
|
|
data->REG_FAN = NCT6779_REG_FAN;
|
|
|
|
data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
|
|
|
|
data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
|
|
|
|
data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
|
|
|
|
data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
|
|
|
|
data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
|
2015-09-01 02:13:47 +03:00
|
|
|
data->REG_FAN_TIME[1] = NCT6776_REG_FAN_STEP_UP_TIME;
|
|
|
|
data->REG_FAN_TIME[2] = NCT6776_REG_FAN_STEP_DOWN_TIME;
|
2013-06-25 09:28:28 +04:00
|
|
|
data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
|
|
|
|
data->REG_PWM[0] = NCT6775_REG_PWM;
|
|
|
|
data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
|
|
|
|
data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
|
2013-11-14 00:47:17 +04:00
|
|
|
data->REG_PWM[5] = NCT6791_REG_WEIGHT_DUTY_STEP;
|
|
|
|
data->REG_PWM[6] = NCT6791_REG_WEIGHT_DUTY_BASE;
|
2013-06-25 09:28:28 +04:00
|
|
|
data->REG_PWM_READ = NCT6775_REG_PWM_READ;
|
|
|
|
data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
|
|
|
|
data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
|
|
|
|
data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
|
|
|
|
data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
|
|
|
|
data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
|
|
|
|
data->REG_CRITICAL_TEMP_TOLERANCE
|
|
|
|
= NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
|
|
|
|
data->REG_CRITICAL_PWM_ENABLE = NCT6779_REG_CRITICAL_PWM_ENABLE;
|
|
|
|
data->CRITICAL_PWM_ENABLE_MASK
|
|
|
|
= NCT6779_CRITICAL_PWM_ENABLE_MASK;
|
|
|
|
data->REG_CRITICAL_PWM = NCT6779_REG_CRITICAL_PWM;
|
|
|
|
data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
|
|
|
|
data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
|
|
|
|
data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
|
2013-11-14 00:47:17 +04:00
|
|
|
data->REG_WEIGHT_TEMP_SEL = NCT6791_REG_WEIGHT_TEMP_SEL;
|
|
|
|
data->REG_WEIGHT_TEMP[0] = NCT6791_REG_WEIGHT_TEMP_STEP;
|
|
|
|
data->REG_WEIGHT_TEMP[1] = NCT6791_REG_WEIGHT_TEMP_STEP_TOL;
|
|
|
|
data->REG_WEIGHT_TEMP[2] = NCT6791_REG_WEIGHT_TEMP_BASE;
|
2013-06-25 09:28:28 +04:00
|
|
|
data->REG_ALARM = NCT6791_REG_ALARM;
|
2014-11-16 20:50:04 +03:00
|
|
|
if (data->kind == nct6791)
|
|
|
|
data->REG_BEEP = NCT6776_REG_BEEP;
|
|
|
|
else
|
|
|
|
data->REG_BEEP = NCT6792_REG_BEEP;
|
2022-01-13 19:46:29 +03:00
|
|
|
switch (data->kind) {
|
|
|
|
case nct6791:
|
|
|
|
case nct6792:
|
|
|
|
case nct6793:
|
|
|
|
data->REG_TSI_TEMP = NCT6776_REG_TSI_TEMP;
|
|
|
|
num_reg_tsi_temp = ARRAY_SIZE(NCT6776_REG_TSI_TEMP);
|
|
|
|
break;
|
|
|
|
case nct6795:
|
|
|
|
case nct6796:
|
|
|
|
case nct6797:
|
|
|
|
case nct6798:
|
2022-12-28 16:57:44 +03:00
|
|
|
case nct6799:
|
2022-01-13 19:46:29 +03:00
|
|
|
data->REG_TSI_TEMP = NCT6796_REG_TSI_TEMP;
|
|
|
|
num_reg_tsi_temp = ARRAY_SIZE(NCT6796_REG_TSI_TEMP);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
num_reg_tsi_temp = 0;
|
|
|
|
break;
|
|
|
|
}
|
2013-06-25 09:28:28 +04:00
|
|
|
|
2023-07-19 22:28:48 +03:00
|
|
|
if (data->kind == nct6798 || data->kind == nct6799)
|
|
|
|
data->scale_in = scale_in_6798;
|
|
|
|
|
2013-06-25 09:28:28 +04:00
|
|
|
reg_temp = NCT6779_REG_TEMP;
|
|
|
|
num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP);
|
2014-11-16 20:50:04 +03:00
|
|
|
if (data->kind == nct6791) {
|
|
|
|
reg_temp_mon = NCT6779_REG_TEMP_MON;
|
|
|
|
num_reg_temp_mon = ARRAY_SIZE(NCT6779_REG_TEMP_MON);
|
|
|
|
} else {
|
|
|
|
reg_temp_mon = NCT6792_REG_TEMP_MON;
|
|
|
|
num_reg_temp_mon = ARRAY_SIZE(NCT6792_REG_TEMP_MON);
|
|
|
|
}
|
2013-06-25 09:28:28 +04:00
|
|
|
reg_temp_over = NCT6779_REG_TEMP_OVER;
|
|
|
|
reg_temp_hyst = NCT6779_REG_TEMP_HYST;
|
|
|
|
reg_temp_config = NCT6779_REG_TEMP_CONFIG;
|
|
|
|
reg_temp_alternate = NCT6779_REG_TEMP_ALTERNATE;
|
|
|
|
reg_temp_crit = NCT6779_REG_TEMP_CRIT;
|
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
2017-05-18 04:40:10 +03:00
|
|
|
data->have_in = BIT(data->in_num) - 1;
|
2012-12-04 15:26:05 +04:00
|
|
|
data->have_temp = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* On some boards, not all available temperature sources are monitored,
|
|
|
|
* even though some of the monitoring registers are unused.
|
|
|
|
* Get list of unused monitoring registers, then detect if any fan
|
|
|
|
* controls are configured to use unmonitored temperature sources.
|
|
|
|
* If so, assign the unmonitored temperature sources to available
|
|
|
|
* monitoring registers.
|
|
|
|
*/
|
|
|
|
mask = 0;
|
|
|
|
available = 0;
|
|
|
|
for (i = 0; i < num_reg_temp; i++) {
|
|
|
|
if (reg_temp[i] == 0)
|
|
|
|
continue;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_TEMP_SOURCE[i], &src);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
src &= 0x1f;
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!src || (mask & BIT(src)))
|
|
|
|
available |= BIT(i);
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2017-05-18 04:40:10 +03:00
|
|
|
mask |= BIT(src);
|
2012-12-04 15:26:05 +04:00
|
|
|
}
|
|
|
|
|
2012-12-04 20:03:37 +04:00
|
|
|
/*
|
|
|
|
* Now find unmonitored temperature registers and enable monitoring
|
|
|
|
* if additional monitoring registers are available.
|
|
|
|
*/
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = add_temp_sensors(data, data->REG_TEMP_SEL, &available, &mask);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
err = add_temp_sensors(data, data->REG_WEIGHT_TEMP_SEL, &available, &mask);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 20:03:37 +04:00
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
mask = 0;
|
|
|
|
s = NUM_TEMP_FIXED; /* First dynamic temperature attribute */
|
|
|
|
for (i = 0; i < num_reg_temp; i++) {
|
|
|
|
if (reg_temp[i] == 0)
|
|
|
|
continue;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_TEMP_SOURCE[i], &src);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
src &= 0x1f;
|
2017-05-18 04:40:10 +03:00
|
|
|
if (!src || (mask & BIT(src)))
|
2012-12-04 15:26:05 +04:00
|
|
|
continue;
|
|
|
|
|
2017-05-18 04:05:06 +03:00
|
|
|
if (!(data->temp_mask & BIT(src))) {
|
2012-12-04 15:26:05 +04:00
|
|
|
dev_info(dev,
|
|
|
|
"Invalid temperature source %d at index %d, source register 0x%x, temp register 0x%x\n",
|
|
|
|
src, i, data->REG_TEMP_SOURCE[i], reg_temp[i]);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-05-18 04:40:10 +03:00
|
|
|
mask |= BIT(src);
|
2012-12-04 15:26:05 +04:00
|
|
|
|
|
|
|
/* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */
|
|
|
|
if (src <= data->temp_fixed_num) {
|
2017-05-18 04:40:10 +03:00
|
|
|
data->have_temp |= BIT(src - 1);
|
|
|
|
data->have_temp_fixed |= BIT(src - 1);
|
2012-12-04 15:26:05 +04:00
|
|
|
data->reg_temp[0][src - 1] = reg_temp[i];
|
|
|
|
data->reg_temp[1][src - 1] = reg_temp_over[i];
|
|
|
|
data->reg_temp[2][src - 1] = reg_temp_hyst[i];
|
2013-04-03 09:14:06 +04:00
|
|
|
if (reg_temp_crit_h && reg_temp_crit_h[i])
|
|
|
|
data->reg_temp[3][src - 1] = reg_temp_crit_h[i];
|
|
|
|
else if (reg_temp_crit[src - 1])
|
|
|
|
data->reg_temp[3][src - 1]
|
|
|
|
= reg_temp_crit[src - 1];
|
|
|
|
if (reg_temp_crit_l && reg_temp_crit_l[i])
|
|
|
|
data->reg_temp[4][src - 1] = reg_temp_crit_l[i];
|
2012-12-04 15:26:05 +04:00
|
|
|
data->reg_temp_config[src - 1] = reg_temp_config[i];
|
|
|
|
data->temp_src[src - 1] = src;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (s >= NUM_TEMP)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Use dynamic index for other sources */
|
2017-05-18 04:40:10 +03:00
|
|
|
data->have_temp |= BIT(s);
|
2012-12-04 15:26:05 +04:00
|
|
|
data->reg_temp[0][s] = reg_temp[i];
|
|
|
|
data->reg_temp[1][s] = reg_temp_over[i];
|
|
|
|
data->reg_temp[2][s] = reg_temp_hyst[i];
|
|
|
|
data->reg_temp_config[s] = reg_temp_config[i];
|
2013-04-03 09:14:06 +04:00
|
|
|
if (reg_temp_crit_h && reg_temp_crit_h[i])
|
|
|
|
data->reg_temp[3][s] = reg_temp_crit_h[i];
|
|
|
|
else if (reg_temp_crit[src - 1])
|
2012-12-04 15:26:05 +04:00
|
|
|
data->reg_temp[3][s] = reg_temp_crit[src - 1];
|
2013-04-03 09:14:06 +04:00
|
|
|
if (reg_temp_crit_l && reg_temp_crit_l[i])
|
|
|
|
data->reg_temp[4][s] = reg_temp_crit_l[i];
|
2012-12-04 15:26:05 +04:00
|
|
|
|
|
|
|
data->temp_src[s] = src;
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
|
2013-11-14 00:46:20 +04:00
|
|
|
/*
|
|
|
|
* Repeat with temperatures used for fan control.
|
|
|
|
* This set of registers does not support limits.
|
|
|
|
*/
|
|
|
|
for (i = 0; i < num_reg_temp_mon; i++) {
|
|
|
|
if (reg_temp_mon[i] == 0)
|
|
|
|
continue;
|
|
|
|
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_read_value(data, data->REG_TEMP_SEL[i], &src);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
src &= 0x1f;
|
2016-09-11 22:42:52 +03:00
|
|
|
if (!src)
|
2013-11-14 00:46:20 +04:00
|
|
|
continue;
|
|
|
|
|
2017-05-18 04:05:06 +03:00
|
|
|
if (!(data->temp_mask & BIT(src))) {
|
2013-11-14 00:46:20 +04:00
|
|
|
dev_info(dev,
|
|
|
|
"Invalid temperature source %d at index %d, source register 0x%x, temp register 0x%x\n",
|
|
|
|
src, i, data->REG_TEMP_SEL[i],
|
|
|
|
reg_temp_mon[i]);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-09-11 22:42:52 +03:00
|
|
|
/*
|
|
|
|
* For virtual temperature sources, the 'virtual' temperature
|
|
|
|
* for each fan reflects a different temperature, and there
|
|
|
|
* are no duplicates.
|
|
|
|
*/
|
hwmon: (nct6775) Fix virtual temperature sources for NCT6796D
The following kernel log message is reported for the nct6775 driver
on ASUS WS X299 SAGE.
nct6775: Found NCT6796D or compatible chip at 0x2e:0x290
nct6775 nct6775.656: Invalid temperature source 11 at index 0,
source register 0x100, temp register 0x73
nct6775 nct6775.656: Invalid temperature source 11 at index 2,
source register 0x300, temp register 0x77
nct6775 nct6775.656: Invalid temperature source 11 at index 3,
source register 0x800, temp register 0x79
nct6775 nct6775.656: Invalid temperature source 11 at index 4,
source register 0x900, temp register 0x7b
A recent version of the datasheet lists temperature source 11 as reserved.
However, an older version of the datasheet lists temperature sources 10
and 11 as supported virtual temperature sources. Apparently the older
version of the datasheet is correct, so list those temperature sources
as supported.
Virtual temperature sources are different than other temperature sources:
Values are not read from a temperature sensor, but written either from
BIOS or an embedded controller. As such, each virtual temperature has to
be reported. Since there is now more than one temperature source, we have
to keep virtual temperature sources in a chip-specific mask and can no
longer rely on the assumption that there is only one virtual temperature
source with a fixed index. This accounts for most of the complexity of this
patch.
Reported-by: Robert Kern <ulteq@web.de>
Cc: Robert Kern <ulteq@web.de>
Fixes: 81820059a428 ("hwmon: (nct6775) Add support for NCT6796D")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-09-14 05:43:58 +03:00
|
|
|
if (!(data->virt_temp_mask & BIT(src))) {
|
2017-05-18 04:40:10 +03:00
|
|
|
if (mask & BIT(src))
|
2016-09-11 22:42:52 +03:00
|
|
|
continue;
|
2017-05-18 04:40:10 +03:00
|
|
|
mask |= BIT(src);
|
2016-09-11 22:42:52 +03:00
|
|
|
}
|
2013-11-14 00:46:20 +04:00
|
|
|
|
|
|
|
/* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */
|
|
|
|
if (src <= data->temp_fixed_num) {
|
2017-05-18 04:40:10 +03:00
|
|
|
if (data->have_temp & BIT(src - 1))
|
2013-11-14 00:46:20 +04:00
|
|
|
continue;
|
2017-05-18 04:40:10 +03:00
|
|
|
data->have_temp |= BIT(src - 1);
|
|
|
|
data->have_temp_fixed |= BIT(src - 1);
|
2013-11-14 00:46:20 +04:00
|
|
|
data->reg_temp[0][src - 1] = reg_temp_mon[i];
|
|
|
|
data->temp_src[src - 1] = src;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (s >= NUM_TEMP)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Use dynamic index for other sources */
|
2017-05-18 04:40:10 +03:00
|
|
|
data->have_temp |= BIT(s);
|
2013-11-14 00:46:20 +04:00
|
|
|
data->reg_temp[0][s] = reg_temp_mon[i];
|
|
|
|
data->temp_src[s] = src;
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
|
2012-12-04 15:26:05 +04:00
|
|
|
#ifdef USE_ALTERNATE
|
|
|
|
/*
|
|
|
|
* Go through the list of alternate temp registers and enable
|
|
|
|
* if possible.
|
|
|
|
* The temperature is already monitored if the respective bit in <mask>
|
|
|
|
* is set.
|
|
|
|
*/
|
2018-06-13 01:19:35 +03:00
|
|
|
for (i = 0; i < 31; i++) {
|
2017-05-18 04:05:06 +03:00
|
|
|
if (!(data->temp_mask & BIT(i + 1)))
|
|
|
|
continue;
|
2012-12-04 15:26:05 +04:00
|
|
|
if (!reg_temp_alternate[i])
|
|
|
|
continue;
|
2017-05-18 04:40:10 +03:00
|
|
|
if (mask & BIT(i + 1))
|
2012-12-04 15:26:05 +04:00
|
|
|
continue;
|
|
|
|
if (i < data->temp_fixed_num) {
|
2017-05-18 04:40:10 +03:00
|
|
|
if (data->have_temp & BIT(i))
|
2012-12-04 15:26:05 +04:00
|
|
|
continue;
|
2017-05-18 04:40:10 +03:00
|
|
|
data->have_temp |= BIT(i);
|
|
|
|
data->have_temp_fixed |= BIT(i);
|
2012-12-04 15:26:05 +04:00
|
|
|
data->reg_temp[0][i] = reg_temp_alternate[i];
|
2013-05-09 21:40:01 +04:00
|
|
|
if (i < num_reg_temp) {
|
|
|
|
data->reg_temp[1][i] = reg_temp_over[i];
|
|
|
|
data->reg_temp[2][i] = reg_temp_hyst[i];
|
|
|
|
}
|
2012-12-04 15:26:05 +04:00
|
|
|
data->temp_src[i] = i + 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (s >= NUM_TEMP) /* Abort if no more space */
|
|
|
|
break;
|
|
|
|
|
2017-05-18 04:40:10 +03:00
|
|
|
data->have_temp |= BIT(s);
|
2012-12-04 15:26:05 +04:00
|
|
|
data->reg_temp[0][s] = reg_temp_alternate[i];
|
|
|
|
data->temp_src[s] = i + 1;
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
#endif /* USE_ALTERNATE */
|
|
|
|
|
2022-01-13 19:46:29 +03:00
|
|
|
/* Check which TSIx_TEMP registers are active */
|
|
|
|
for (i = 0; i < num_reg_tsi_temp; i++) {
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
u16 tmp;
|
|
|
|
|
|
|
|
err = nct6775_read_value(data, data->REG_TSI_TEMP[i], &tmp);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
if (tmp)
|
2022-01-13 19:46:29 +03:00
|
|
|
data->have_tsi_temp |= BIT(i);
|
|
|
|
}
|
|
|
|
|
2012-05-21 06:29:48 +04:00
|
|
|
/* Initialize the chip */
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_init_device(data);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-05-21 06:29:48 +04:00
|
|
|
|
2022-04-27 04:01:53 +03:00
|
|
|
if (data->driver_init) {
|
|
|
|
err = data->driver_init(data);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 19:59:32 +04:00
|
|
|
}
|
|
|
|
|
2012-12-04 19:56:24 +04:00
|
|
|
/* Read fan clock dividers immediately */
|
hwmon: (nct6775) Convert register access to regmap API
This replaces the nct6775_data->{read,write}_value function pointers
with a regmap.
The major difference is that the regmap access functions may fail, and
hence require checking at each call site. While the existing WMI
register-access code had potential failure paths, they were masked by
the fact that the read_value() function returned the register value
directly, and hence squashed errors undetectably by simply returning
zero, and while the write_value() functions were capable of reporting
errors, all callers ignored them.
This improves the robustness of the existing code, and also prepares
the driver for an i2c version to be added soon, for which register
accesses are much more likely to actually fail.
The conversion of the register-access call sites is largely mechanical
(reading a register now returns the value via an out-param pointer,
and returned errors must be checked for and propagated to callers),
though the nct6775_write_fan_div() function is refactored slightly to
avoid duplicating nearly identical (and now lengthier) code in each
switch case.
Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20220427010154.29749-3-zev@bewilderbeest.net
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2022-04-27 04:01:49 +03:00
|
|
|
err = nct6775_init_fan_common(dev, data);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 19:56:24 +04:00
|
|
|
|
2012-12-04 20:30:54 +04:00
|
|
|
/* Register sysfs hooks */
|
2022-04-27 04:01:50 +03:00
|
|
|
err = nct6775_add_template_attr_group(dev, data, &nct6775_pwm_template_group,
|
|
|
|
data->pwm_num);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2013-07-06 20:43:30 +04:00
|
|
|
|
2022-04-27 04:01:50 +03:00
|
|
|
err = nct6775_add_template_attr_group(dev, data, &nct6775_in_template_group,
|
|
|
|
fls(data->have_in));
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 15:26:05 +04:00
|
|
|
|
2022-04-27 04:01:50 +03:00
|
|
|
err = nct6775_add_template_attr_group(dev, data, &nct6775_fan_template_group,
|
|
|
|
fls(data->has_fan));
|
|
|
|
if (err)
|
|
|
|
return err;
|
2012-12-04 15:13:34 +04:00
|
|
|
|
2022-04-27 04:01:50 +03:00
|
|
|
err = nct6775_add_template_attr_group(dev, data, &nct6775_temp_template_group,
|
|
|
|
fls(data->have_temp));
|
|
|
|
if (err)
|
|
|
|
return err;
|
2022-01-13 19:46:29 +03:00
|
|
|
|
|
|
|
if (data->have_tsi_temp) {
|
|
|
|
tsi_temp_tg.templates = nct6775_tsi_temp_template;
|
|
|
|
tsi_temp_tg.is_visible = nct6775_tsi_temp_is_visible;
|
|
|
|
tsi_temp_tg.base = fls(data->have_temp) + 1;
|
2022-04-27 04:01:50 +03:00
|
|
|
err = nct6775_add_template_attr_group(dev, data, &tsi_temp_tg,
|
|
|
|
fls(data->have_tsi_temp));
|
|
|
|
if (err)
|
|
|
|
return err;
|
2022-01-13 19:46:29 +03:00
|
|
|
}
|
|
|
|
|
2013-07-12 09:55:22 +04:00
|
|
|
hwmon_dev = devm_hwmon_device_register_with_groups(dev, data->name,
|
|
|
|
data, data->groups);
|
2013-09-17 17:43:42 +04:00
|
|
|
return PTR_ERR_OR_ZERO(hwmon_dev);
|
2012-05-21 06:29:48 +04:00
|
|
|
}
|
2022-04-27 04:01:53 +03:00
|
|
|
EXPORT_SYMBOL_GPL(nct6775_probe);
|
2012-05-21 06:29:48 +04:00
|
|
|
|
|
|
|
MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
|
2022-04-27 04:01:53 +03:00
|
|
|
MODULE_DESCRIPTION("Core driver for NCT6775F and compatible chips");
|
2012-05-21 06:29:48 +04:00
|
|
|
MODULE_LICENSE("GPL");
|