Use regmap for caching and regmap operations for register bit manipulations to simplify the code. No functional change intended. Signed-off-by: Guenter Roeck <linux@xxxxxxxxxxxx> --- Documentation/hwmon/g762.rst | 2 - drivers/hwmon/g762.c | 523 +++++++++++++---------------------- 2 files changed, 195 insertions(+), 330 deletions(-) diff --git a/Documentation/hwmon/g762.rst b/Documentation/hwmon/g762.rst index 3dc5294b2181..0c170596a1ac 100644 --- a/Documentation/hwmon/g762.rst +++ b/Documentation/hwmon/g762.rst @@ -68,5 +68,3 @@ is performed to match that target value. The fan speed value is computed based on the parameters associated with the physical characteristics of the system: a reference clock source frequency, a number of pulses per fan revolution, etc. - -Note that the driver will update its values at most once per second. diff --git a/drivers/hwmon/g762.c b/drivers/hwmon/g762.c index 0ddaa0bd1075..5f8fd723a694 100644 --- a/drivers/hwmon/g762.c +++ b/drivers/hwmon/g762.c @@ -36,11 +36,11 @@ #include <linux/init.h> #include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> -#include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/of.h> +#include <linux/regmap.h> #define DRVNAME "g762" @@ -68,19 +68,6 @@ enum g762_regs { #define G762_REG_FAN_STA_FAIL BIT(1) /* fan fail */ #define G762_REG_FAN_STA_OOC BIT(0) /* fan out of control */ -/* Config register values */ -#define G762_OUT_MODE_PWM 1 -#define G762_OUT_MODE_DC 0 - -#define G762_FAN_MODE_CLOSED_LOOP 2 -#define G762_FAN_MODE_OPEN_LOOP 1 - -#define G762_PWM_POLARITY_NEGATIVE 1 -#define G762_PWM_POLARITY_POSITIVE 0 - -/* Register data is read (and cached) at most once per second. */ -#define G762_UPDATE_INTERVAL HZ - /* * Extract pulse count per fan revolution value (2 or 4) from given * FAN_CMD1 register value. @@ -103,48 +90,13 @@ enum g762_regs { BIT(FIELD_GET(G762_REG_FAN_CMD2_GEAR_MASK, reg)) struct g762_data { - struct i2c_client *client; + struct regmap *regmap; /* update mutex */ struct mutex update_lock; /* board specific parameters. */ u32 clk_freq; - - /* g762 register cache */ - bool valid; - unsigned long last_updated; /* in jiffies */ - - u8 set_cnt; /* controls fan rotation speed in closed-loop mode */ - u8 act_cnt; /* provides access to current fan RPM value */ - u8 fan_sta; /* bit 0: set when actual fan speed is more than - * 25% outside requested fan speed - * bit 1: set when no transition occurs on fan - * pin for 0.7s - */ - u8 set_out; /* controls fan rotation speed in open-loop mode */ - u8 fan_cmd1; /* 0: FG_PLS_ID0 FG pulses count per revolution - * 0: 2 counts per revolution - * 1: 4 counts per revolution - * 1: PWM_POLARITY 1: negative_duty - * 0: positive_duty - * 2,3: [FG_CLOCK_ID0, FG_CLK_ID1] - * 00: Divide fan clock by 1 - * 01: Divide fan clock by 2 - * 10: Divide fan clock by 4 - * 11: Divide fan clock by 8 - * 4: FAN_MODE 1:closed-loop, 0:open-loop - * 5: OUT_MODE 1:PWM, 0:DC - * 6: DET_FAN_OOC enable "fan ooc" status - * 7: DET_FAN_FAIL enable "fan fail" status - */ - u8 fan_cmd2; /* 0,1: FAN_STARTV 0,1,2,3 -> 0,32,64,96 dac_code - * 2,3: FG_GEAR_MODE - * 00: multiplier = 1 - * 01: multiplier = 2 - * 10: multiplier = 4 - * 4: Mask ALERT# (g763 only) - */ }; /* @@ -179,59 +131,6 @@ static inline unsigned char cnt_from_rpm(unsigned long rpm, u32 clk_freq, u16 p, return DIV_ROUND_CLOSEST(f1, rpm * f2); } -/* helper to grab and cache data, at most one time per second */ -static struct g762_data *g762_update_client(struct device *dev) -{ - struct g762_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; - int ret = 0; - - mutex_lock(&data->update_lock); - if (time_before(jiffies, data->last_updated + G762_UPDATE_INTERVAL) && - likely(data->valid)) - goto out; - - ret = i2c_smbus_read_byte_data(client, G762_REG_SET_CNT); - if (ret < 0) - goto out; - data->set_cnt = ret; - - ret = i2c_smbus_read_byte_data(client, G762_REG_ACT_CNT); - if (ret < 0) - goto out; - data->act_cnt = ret; - - ret = i2c_smbus_read_byte_data(client, G762_REG_FAN_STA); - if (ret < 0) - goto out; - data->fan_sta = ret; - - ret = i2c_smbus_read_byte_data(client, G762_REG_SET_OUT); - if (ret < 0) - goto out; - data->set_out = ret; - - ret = i2c_smbus_read_byte_data(client, G762_REG_FAN_CMD1); - if (ret < 0) - goto out; - data->fan_cmd1 = ret; - - ret = i2c_smbus_read_byte_data(client, G762_REG_FAN_CMD2); - if (ret < 0) - goto out; - data->fan_cmd2 = ret; - - data->last_updated = jiffies; - data->valid = true; - out: - mutex_unlock(&data->update_lock); - - if (ret < 0) /* upon error, encode it in return value */ - data = ERR_PTR(ret); - - return data; -} - /* helpers for writing hardware parameters */ /* @@ -257,125 +156,72 @@ static int do_set_clk_freq(struct device *dev, unsigned long val) /* Set pwm mode. Accepts either 0 (PWM mode) or 1 (DC mode) */ static int do_set_pwm_mode(struct device *dev, unsigned long val) { - struct g762_data *data = g762_update_client(dev); - int ret; + struct g762_data *data = dev_get_drvdata(dev); - if (IS_ERR(data)) - return PTR_ERR(data); + if (val && val != 1) + return -EINVAL; - mutex_lock(&data->update_lock); - switch (val) { - case G762_OUT_MODE_PWM: - data->fan_cmd1 |= G762_REG_FAN_CMD1_OUT_MODE; - break; - case G762_OUT_MODE_DC: - data->fan_cmd1 &= ~G762_REG_FAN_CMD1_OUT_MODE; - break; - default: - ret = -EINVAL; - goto out; - } - ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, - data->fan_cmd1); - data->valid = false; - out: - mutex_unlock(&data->update_lock); - - return ret; + return regmap_update_bits(data->regmap, G762_REG_FAN_CMD1, + G762_REG_FAN_CMD1_OUT_MODE, + val ? G762_REG_FAN_CMD1_OUT_MODE : 0); } /* Set fan clock divisor. Accepts either 1, 2, 4 or 8. */ static int do_set_fan_div(struct device *dev, unsigned long val) { - struct g762_data *data = g762_update_client(dev); - int ret; - - if (IS_ERR(data)) - return PTR_ERR(data); + struct g762_data *data = dev_get_drvdata(dev); if (hweight_long(val) != 1 || val > 8) return -EINVAL; - mutex_lock(&data->update_lock); - data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_MASK; - data->fan_cmd1 |= FIELD_PREP(G762_REG_FAN_CMD1_CLK_DIV_MASK, __ffs(val)); - ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, - data->fan_cmd1); - data->valid = false; - mutex_unlock(&data->update_lock); - - return ret; + return regmap_update_bits(data->regmap, G762_REG_FAN_CMD1, + G762_REG_FAN_CMD1_CLK_DIV_MASK, + FIELD_PREP(G762_REG_FAN_CMD1_CLK_DIV_MASK, __ffs(val))); } /* Set fan gear mode. Accepts either 0, 1 or 2. */ static int do_set_fan_gear_mode(struct device *dev, u32 val) { - struct g762_data *data = g762_update_client(dev); - int ret; - - if (IS_ERR(data)) - return PTR_ERR(data); + struct g762_data *data = dev_get_drvdata(dev); if (val > 2) return -EINVAL; - mutex_lock(&data->update_lock); - data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MASK; - data->fan_cmd2 |= FIELD_PREP(G762_REG_FAN_CMD2_GEAR_MASK, val); - ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2, - data->fan_cmd2); - data->valid = false; - mutex_unlock(&data->update_lock); - - return ret; + return regmap_update_bits(data->regmap, G762_REG_FAN_CMD2, + G762_REG_FAN_CMD2_GEAR_MASK, + FIELD_PREP(G762_REG_FAN_CMD2_GEAR_MASK, val)); } /* Set number of fan pulses per revolution. Accepts either 2 or 4. */ static int do_set_fan_pulses(struct device *dev, unsigned long val) { - struct g762_data *data = g762_update_client(dev); - int ret; + struct g762_data *data = dev_get_drvdata(dev); - if (IS_ERR(data)) - return PTR_ERR(data); + if (val != 2 && val != 4) + return -EINVAL; - mutex_lock(&data->update_lock); - switch (val) { - case 2: - data->fan_cmd1 &= ~G762_REG_FAN_CMD1_PULSE_PER_REV; - break; - case 4: - data->fan_cmd1 |= G762_REG_FAN_CMD1_PULSE_PER_REV; - break; - default: - ret = -EINVAL; - goto out; - } - ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, - data->fan_cmd1); - data->valid = false; - out: - mutex_unlock(&data->update_lock); - - return ret; + return regmap_update_bits(data->regmap, G762_REG_FAN_CMD1, + G762_REG_FAN_CMD1_PULSE_PER_REV, + val == 4 ? G762_REG_FAN_CMD1_PULSE_PER_REV : 0); } /* Set fan mode. Accepts either 1 (open-loop) or 2 (closed-loop). */ static int do_set_pwm_enable(struct device *dev, unsigned long val) { - struct g762_data *data = g762_update_client(dev); + struct g762_data *data = dev_get_drvdata(dev); + struct regmap *regmap = data->regmap; int ret; - if (IS_ERR(data)) - return PTR_ERR(data); + if (val != 1 && val != 2) + return -EINVAL; mutex_lock(&data->update_lock); - switch (val) { - case G762_FAN_MODE_CLOSED_LOOP: - data->fan_cmd1 |= G762_REG_FAN_CMD1_FAN_MODE; - break; - case G762_FAN_MODE_OPEN_LOOP: - data->fan_cmd1 &= ~G762_REG_FAN_CMD1_FAN_MODE; + if (val == 1) { + u32 regval; + + ret = regmap_read(regmap, G762_REG_SET_CNT, ®val); + if (ret) + goto unlock; /* * BUG FIX: if SET_CNT register value is 255 then, for some * unknown reason, fan will not rotate as expected, no matter @@ -383,52 +229,26 @@ static int do_set_pwm_enable(struct device *dev, unsigned long val) * only in PWM mode). To workaround this bug, we give SET_CNT * value of 254 if it is 255 when switching to open-loop. */ - if (data->set_cnt == 0xff) - i2c_smbus_write_byte_data(data->client, - G762_REG_SET_CNT, 254); - break; - default: - ret = -EINVAL; - goto out; + if (regval == 0xff) + regmap_write(regmap, G762_REG_SET_CNT, 254); } - - ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, - data->fan_cmd1); - data->valid = false; - out: + ret = regmap_update_bits(regmap, G762_REG_FAN_CMD1, G762_REG_FAN_CMD1_FAN_MODE, + val == 2 ? G762_REG_FAN_CMD1_FAN_MODE : 0); +unlock: mutex_unlock(&data->update_lock); - return ret; } /* Set PWM polarity. Accepts either 0 (positive duty) or 1 (negative duty) */ static int do_set_pwm_polarity(struct device *dev, unsigned long val) { - struct g762_data *data = g762_update_client(dev); - int ret; + struct g762_data *data = dev_get_drvdata(dev); - if (IS_ERR(data)) - return PTR_ERR(data); + if (val && val != 1) + return -EINVAL; - mutex_lock(&data->update_lock); - switch (val) { - case G762_PWM_POLARITY_POSITIVE: - data->fan_cmd1 &= ~G762_REG_FAN_CMD1_PWM_POLARITY; - break; - case G762_PWM_POLARITY_NEGATIVE: - data->fan_cmd1 |= G762_REG_FAN_CMD1_PWM_POLARITY; - break; - default: - ret = -EINVAL; - goto out; - } - ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, - data->fan_cmd1); - data->valid = false; - out: - mutex_unlock(&data->update_lock); - - return ret; + return regmap_update_bits(data->regmap, G762_REG_FAN_CMD1, G762_REG_FAN_CMD1_PWM_POLARITY, + val ? G762_REG_FAN_CMD1_PWM_POLARITY : 0); } /* @@ -438,18 +258,11 @@ static int do_set_pwm_polarity(struct device *dev, unsigned long val) static int do_set_pwm(struct device *dev, unsigned long val) { struct g762_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; - int ret; if (val > 255) return -EINVAL; - mutex_lock(&data->update_lock); - ret = i2c_smbus_write_byte_data(client, G762_REG_SET_OUT, val); - data->valid = false; - mutex_unlock(&data->update_lock); - - return ret; + return regmap_write(data->regmap, G762_REG_SET_OUT, val); } /* @@ -458,52 +271,81 @@ static int do_set_pwm(struct device *dev, unsigned long val) */ static int do_set_fan_target(struct device *dev, unsigned long val) { - struct g762_data *data = g762_update_client(dev); + struct g762_data *data = dev_get_drvdata(dev); + struct regmap *regmap = data->regmap; + u32 cmd1, cmd2; + u8 set_cnt; int ret; - if (IS_ERR(data)) - return PTR_ERR(data); - mutex_lock(&data->update_lock); - data->set_cnt = cnt_from_rpm(val, data->clk_freq, - G762_PULSE_FROM_REG(data->fan_cmd1), - G762_CLKDIV_FROM_REG(data->fan_cmd1), - G762_GEARMULT_FROM_REG(data->fan_cmd2)); - ret = i2c_smbus_write_byte_data(data->client, G762_REG_SET_CNT, - data->set_cnt); - data->valid = false; - mutex_unlock(&data->update_lock); + ret = regmap_read(regmap, G762_REG_FAN_CMD1, &cmd1); + if (ret) + goto unlock; + ret = regmap_read(regmap, G762_REG_FAN_CMD2, &cmd2); + if (ret) + goto unlock; + + set_cnt = cnt_from_rpm(val, data->clk_freq, + G762_PULSE_FROM_REG(cmd1), + G762_CLKDIV_FROM_REG(cmd1), + G762_GEARMULT_FROM_REG(cmd2)); + ret = regmap_write(regmap, G762_REG_SET_CNT, set_cnt); +unlock: + mutex_unlock(&data->update_lock); return ret; } /* Set fan startup voltage. Accepted values are either 0, 1, 2 or 3. */ static int do_set_fan_startv(struct device *dev, unsigned long val) { - struct g762_data *data = g762_update_client(dev); - int ret; - - if (IS_ERR(data)) - return PTR_ERR(data); + struct g762_data *data = dev_get_drvdata(dev); if (val > 3) return -EINVAL; - mutex_lock(&data->update_lock); - data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_MASK; - data->fan_cmd2 |= FIELD_PREP(G762_REG_FAN_CMD2_FAN_STARTV_MASK, val); - ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2, - data->fan_cmd2); - data->valid = false; - mutex_unlock(&data->update_lock); - - return ret; + return regmap_update_bits(data->regmap, G762_REG_FAN_CMD2, + G762_REG_FAN_CMD2_FAN_STARTV_MASK, + FIELD_PREP(G762_REG_FAN_CMD2_FAN_STARTV_MASK, val)); } /* * sysfs attributes */ +static int get_fan_rpm_locked(struct g762_data *data, int reg) +{ + struct regmap *regmap = data->regmap; + u32 cmd1, cmd2, count; + int ret; + + ret = regmap_read(regmap, reg, &count); + if (ret) + return ret; + ret = regmap_read(regmap, G762_REG_FAN_CMD1, &cmd1); + if (ret) + return ret; + ret = regmap_read(regmap, G762_REG_FAN_CMD2, &cmd2); + if (ret) + return ret; + + return rpm_from_cnt(count, data->clk_freq, + G762_PULSE_FROM_REG(cmd1), + G762_CLKDIV_FROM_REG(cmd1), + G762_GEARMULT_FROM_REG(cmd2)); +} + +static int get_fan_rpm(struct g762_data *data, int reg) +{ + int ret; + + mutex_lock(&data->update_lock); + ret = get_fan_rpm_locked(data, reg); + mutex_unlock(&data->update_lock); + + return ret; +} + /* * Read function for fan1_input sysfs file. Return current fan RPM value, or * 0 if fan is out of control. @@ -511,23 +353,24 @@ static int do_set_fan_startv(struct device *dev, unsigned long val) static ssize_t fan1_input_show(struct device *dev, struct device_attribute *da, char *buf) { - struct g762_data *data = g762_update_client(dev); - unsigned int rpm = 0; - - if (IS_ERR(data)) - return PTR_ERR(data); + struct g762_data *data = dev_get_drvdata(dev); + u32 status; + int ret; mutex_lock(&data->update_lock); + ret = regmap_read(data->regmap, G762_REG_FAN_STA, &status); /* reverse logic: fan out of control reporting is enabled low */ - if (data->fan_sta & G762_REG_FAN_STA_OOC) { - rpm = rpm_from_cnt(data->act_cnt, data->clk_freq, - G762_PULSE_FROM_REG(data->fan_cmd1), - G762_CLKDIV_FROM_REG(data->fan_cmd1), - G762_GEARMULT_FROM_REG(data->fan_cmd2)); - } - mutex_unlock(&data->update_lock); + if (ret || !(status & G762_REG_FAN_STA_OOC)) + goto unlock; - return sprintf(buf, "%u\n", rpm); + ret = get_fan_rpm_locked(data, G762_REG_ACT_CNT); + if (ret < 0) + goto unlock; + + ret = sprintf(buf, "%u\n", ret); +unlock: + mutex_unlock(&data->update_lock); + return ret; } /* @@ -537,13 +380,15 @@ static ssize_t fan1_input_show(struct device *dev, static ssize_t pwm1_mode_show(struct device *dev, struct device_attribute *da, char *buf) { - struct g762_data *data = g762_update_client(dev); + struct g762_data *data = dev_get_drvdata(dev); + u32 cmd1; + int ret; - if (IS_ERR(data)) - return PTR_ERR(data); + ret = regmap_read(data->regmap, G762_REG_FAN_CMD1, &cmd1); + if (ret < 0) + return ret; - return sprintf(buf, "%d\n", - !!(data->fan_cmd1 & G762_REG_FAN_CMD1_OUT_MODE)); + return sprintf(buf, "%d\n", !!(cmd1 & G762_REG_FAN_CMD1_OUT_MODE)); } static ssize_t pwm1_mode_store(struct device *dev, @@ -570,12 +415,15 @@ static ssize_t pwm1_mode_store(struct device *dev, static ssize_t fan1_div_show(struct device *dev, struct device_attribute *da, char *buf) { - struct g762_data *data = g762_update_client(dev); + struct g762_data *data = dev_get_drvdata(dev); + u32 cmd1; + int ret; - if (IS_ERR(data)) - return PTR_ERR(data); + ret = regmap_read(data->regmap, G762_REG_FAN_CMD1, &cmd1); + if (ret < 0) + return ret; - return sprintf(buf, "%ld\n", G762_CLKDIV_FROM_REG(data->fan_cmd1)); + return sprintf(buf, "%ld\n", G762_CLKDIV_FROM_REG(cmd1)); } static ssize_t fan1_div_store(struct device *dev, struct device_attribute *da, @@ -601,12 +449,15 @@ static ssize_t fan1_div_store(struct device *dev, struct device_attribute *da, static ssize_t fan1_pulses_show(struct device *dev, struct device_attribute *da, char *buf) { - struct g762_data *data = g762_update_client(dev); + struct g762_data *data = dev_get_drvdata(dev); + u32 cmd1; + int ret; - if (IS_ERR(data)) - return PTR_ERR(data); + ret = regmap_read(data->regmap, G762_REG_FAN_CMD1, &cmd1); + if (ret < 0) + return ret; - return sprintf(buf, "%ld\n", G762_PULSE_FROM_REG(data->fan_cmd1)); + return sprintf(buf, "%ld\n", G762_PULSE_FROM_REG(cmd1)); } static ssize_t fan1_pulses_store(struct device *dev, @@ -643,13 +494,16 @@ static ssize_t fan1_pulses_store(struct device *dev, static ssize_t pwm1_enable_show(struct device *dev, struct device_attribute *da, char *buf) { - struct g762_data *data = g762_update_client(dev); + struct g762_data *data = dev_get_drvdata(dev); + u32 cmd1; + int ret; - if (IS_ERR(data)) - return PTR_ERR(data); + ret = regmap_read(data->regmap, G762_REG_FAN_CMD1, &cmd1); + if (ret < 0) + return ret; return sprintf(buf, "%d\n", - (!!(data->fan_cmd1 & G762_REG_FAN_CMD1_FAN_MODE)) + 1); + !!(cmd1 & G762_REG_FAN_CMD1_FAN_MODE) + 1); } static ssize_t pwm1_enable_store(struct device *dev, @@ -677,12 +531,15 @@ static ssize_t pwm1_enable_store(struct device *dev, static ssize_t pwm1_show(struct device *dev, struct device_attribute *da, char *buf) { - struct g762_data *data = g762_update_client(dev); + struct g762_data *data = dev_get_drvdata(dev); + int ret; + u32 pwm; - if (IS_ERR(data)) - return PTR_ERR(data); + ret = regmap_read(data->regmap, G762_REG_SET_OUT, &pwm); + if (ret < 0) + return ret; - return sprintf(buf, "%d\n", data->set_out); + return sprintf(buf, "%u\n", pwm); } static ssize_t pwm1_store(struct device *dev, struct device_attribute *da, @@ -715,20 +572,14 @@ static ssize_t pwm1_store(struct device *dev, struct device_attribute *da, static ssize_t fan1_target_show(struct device *dev, struct device_attribute *da, char *buf) { - struct g762_data *data = g762_update_client(dev); - unsigned int rpm; + struct g762_data *data = dev_get_drvdata(dev); + int rpm; - if (IS_ERR(data)) - return PTR_ERR(data); + rpm = get_fan_rpm(data, G762_REG_SET_CNT); + if (rpm < 0) + return rpm; - mutex_lock(&data->update_lock); - rpm = rpm_from_cnt(data->set_cnt, data->clk_freq, - G762_PULSE_FROM_REG(data->fan_cmd1), - G762_CLKDIV_FROM_REG(data->fan_cmd1), - G762_GEARMULT_FROM_REG(data->fan_cmd2)); - mutex_unlock(&data->update_lock); - - return sprintf(buf, "%u\n", rpm); + return sprintf(buf, "%d\n", rpm); } static ssize_t fan1_target_store(struct device *dev, @@ -752,12 +603,15 @@ static ssize_t fan1_target_store(struct device *dev, static ssize_t fan1_fault_show(struct device *dev, struct device_attribute *da, char *buf) { - struct g762_data *data = g762_update_client(dev); + struct g762_data *data = dev_get_drvdata(dev); + u32 status; + int ret; - if (IS_ERR(data)) - return PTR_ERR(data); + ret = regmap_read(data->regmap, G762_REG_FAN_STA, &status); + if (ret < 0) + return ret; - return sprintf(buf, "%u\n", !!(data->fan_sta & G762_REG_FAN_STA_FAIL)); + return sprintf(buf, "%u\n", !!(status & G762_REG_FAN_STA_FAIL)); } /* @@ -767,12 +621,15 @@ static ssize_t fan1_fault_show(struct device *dev, struct device_attribute *da, static ssize_t fan1_alarm_show(struct device *dev, struct device_attribute *da, char *buf) { - struct g762_data *data = g762_update_client(dev); + struct g762_data *data = dev_get_drvdata(dev); + u32 status; + int ret; - if (IS_ERR(data)) - return PTR_ERR(data); + ret = regmap_read(data->regmap, G762_REG_FAN_STA, &status); + if (ret < 0) + return ret; - return sprintf(buf, "%u\n", !(data->fan_sta & G762_REG_FAN_STA_OOC)); + return sprintf(buf, "%u\n", !(status & G762_REG_FAN_STA_OOC)); } static DEVICE_ATTR_RW(pwm1); @@ -802,23 +659,14 @@ static struct attribute *g762_attrs[] = { ATTRIBUTE_GROUPS(g762); /* - * Enable both fan failure detection and fan out of control protection. The - * function does not protect change/access to data structure; it must thus - * only be called during initialization. + * Enable both fan failure detection and fan out of control protection. */ static inline int g762_fan_init(struct device *dev) { - struct g762_data *data = g762_update_client(dev); + struct g762_data *data = dev_get_drvdata(dev); - if (IS_ERR(data)) - return PTR_ERR(data); - - data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_FAIL; - data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_OOC; - data->valid = false; - - return i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, - data->fan_cmd1); + return regmap_set_bits(data->regmap, G762_REG_FAN_CMD1, + G762_REG_FAN_CMD1_DET_FAN_FAIL | G762_REG_FAN_CMD1_DET_FAN_OOC); } /* @@ -880,6 +728,26 @@ static int g762_configure(struct device *dev) return 0; } +static bool g762_writeable_reg(struct device *dev, unsigned int reg) +{ + return reg == G762_REG_SET_CNT || reg == G762_REG_SET_OUT || + reg == G762_REG_FAN_CMD1 || reg == G762_REG_FAN_CMD2; +} + +static bool g762_volatile_reg(struct device *dev, unsigned int reg) +{ + return reg == G762_REG_ACT_CNT || reg == G762_REG_FAN_STA; +} + +static const struct regmap_config g762_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = G762_REG_FAN_CMD2, + .writeable_reg = g762_writeable_reg, + .volatile_reg = g762_volatile_reg, + .cache_type = REGCACHE_MAPLE, +}; + static int g762_probe(struct i2c_client *client) { struct device *dev = &client->dev; @@ -887,16 +755,15 @@ static int g762_probe(struct i2c_client *client) struct g762_data *data; int ret; - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; - data = devm_kzalloc(dev, sizeof(struct g762_data), GFP_KERNEL); if (!data) return -ENOMEM; + data->regmap = devm_regmap_init_i2c(client, &g762_regmap_config); + if (IS_ERR(data->regmap)) + return PTR_ERR(data->regmap); + dev_set_drvdata(dev, data); - data->client = client; mutex_init(&data->update_lock); ret = g762_configure(dev); -- 2.39.2