Message ID | 20240416171720.2875916-1-naresh.solanki@9elements.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Series | [1/4] hwmon (max6639): Use regmap | expand |
On Tue, Apr 16, 2024 at 10:47:14PM +0530, Naresh Solanki wrote: > Add regmap support. > Missing (and not really utilizing) the benefits of using regmap. > Signed-off-by: Naresh Solanki <naresh.solanki@9elements.com> > --- > drivers/hwmon/Kconfig | 1 + > drivers/hwmon/max6639.c | 157 ++++++++++++++++++++-------------------- > 2 files changed, 80 insertions(+), 78 deletions(-) > > diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig > index c89776d91795..257ec5360e35 100644 > --- a/drivers/hwmon/Kconfig > +++ b/drivers/hwmon/Kconfig > @@ -1223,6 +1223,7 @@ config SENSORS_MAX6621 > config SENSORS_MAX6639 > tristate "Maxim MAX6639 sensor chip" > depends on I2C > + select REGMAP_I2C > help > If you say yes here you get support for the MAX6639 > sensor chips. > diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c > index aa7f21ab2395..1af93fc53cb5 100644 > --- a/drivers/hwmon/max6639.c > +++ b/drivers/hwmon/max6639.c > @@ -20,6 +20,7 @@ > #include <linux/err.h> > #include <linux/mutex.h> > #include <linux/platform_data/max6639.h> > +#include <linux/regmap.h> > > /* Addresses to scan */ > static const unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; > @@ -57,6 +58,8 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; > > #define MAX6639_FAN_CONFIG3_THERM_FULL_SPEED 0x40 > > +#define MAX6639_NDEV 2 > + > static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; > > #define FAN_FROM_REG(val, rpm_range) ((val) == 0 || (val) == 255 ? \ > @@ -67,7 +70,7 @@ static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; > * Client data (each client gets its own) > */ > struct max6639_data { > - struct i2c_client *client; > + struct regmap *regmap; > struct mutex update_lock; > bool valid; /* true if following fields are valid */ > unsigned long last_updated; /* In jiffies */ > @@ -95,9 +98,8 @@ struct max6639_data { > static struct max6639_data *max6639_update_device(struct device *dev) > { > struct max6639_data *data = dev_get_drvdata(dev); > - struct i2c_client *client = data->client; > struct max6639_data *ret = data; > - int i; > + int i, err; > int status_reg; > > mutex_lock(&data->update_lock); > @@ -105,39 +107,35 @@ static struct max6639_data *max6639_update_device(struct device *dev) Conversions to regmap should drop all local caching and use regmap for caching (where appropriate) instead. Guenter
Hi Guenter, On Wed, 17 Apr 2024 at 02:55, Guenter Roeck <linux@roeck-us.net> wrote: > > On Tue, Apr 16, 2024 at 10:47:14PM +0530, Naresh Solanki wrote: > > Add regmap support. > > > > Missing (and not really utilizing) the benefits of using regmap. This is just replacing with regmap support > > > Signed-off-by: Naresh Solanki <naresh.solanki@9elements.com> > > --- > > drivers/hwmon/Kconfig | 1 + > > drivers/hwmon/max6639.c | 157 ++++++++++++++++++++-------------------- > > 2 files changed, 80 insertions(+), 78 deletions(-) > > > > diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig > > index c89776d91795..257ec5360e35 100644 > > --- a/drivers/hwmon/Kconfig > > +++ b/drivers/hwmon/Kconfig > > @@ -1223,6 +1223,7 @@ config SENSORS_MAX6621 > > config SENSORS_MAX6639 > > tristate "Maxim MAX6639 sensor chip" > > depends on I2C > > + select REGMAP_I2C > > help > > If you say yes here you get support for the MAX6639 > > sensor chips. > > diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c > > index aa7f21ab2395..1af93fc53cb5 100644 > > --- a/drivers/hwmon/max6639.c > > +++ b/drivers/hwmon/max6639.c > > @@ -20,6 +20,7 @@ > > #include <linux/err.h> > > #include <linux/mutex.h> > > #include <linux/platform_data/max6639.h> > > +#include <linux/regmap.h> > > > > /* Addresses to scan */ > > static const unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; > > @@ -57,6 +58,8 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; > > > > #define MAX6639_FAN_CONFIG3_THERM_FULL_SPEED 0x40 > > > > +#define MAX6639_NDEV 2 > > + > > static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; > > > > #define FAN_FROM_REG(val, rpm_range) ((val) == 0 || (val) == 255 ? \ > > @@ -67,7 +70,7 @@ static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; > > * Client data (each client gets its own) > > */ > > struct max6639_data { > > - struct i2c_client *client; > > + struct regmap *regmap; > > struct mutex update_lock; > > bool valid; /* true if following fields are valid */ > > unsigned long last_updated; /* In jiffies */ > > @@ -95,9 +98,8 @@ struct max6639_data { > > static struct max6639_data *max6639_update_device(struct device *dev) > > { > > struct max6639_data *data = dev_get_drvdata(dev); > > - struct i2c_client *client = data->client; > > struct max6639_data *ret = data; > > - int i; > > + int i, err; > > int status_reg; > > > > mutex_lock(&data->update_lock); > > @@ -105,39 +107,35 @@ static struct max6639_data *max6639_update_device(struct device *dev) > > Conversions to regmap should drop all local caching and use regmap > for caching (where appropriate) instead. max6639_update_device deals with volatile registers & caching isn't available for these. Please let me know if there is specific optimization that you were looking for. Regards, Naresh > > Guenter
On Mon, Apr 22, 2024 at 04:06:16PM +0530, Naresh Solanki wrote: > Hi Guenter, > > On Wed, 17 Apr 2024 at 02:55, Guenter Roeck <linux@roeck-us.net> wrote: > > > > On Tue, Apr 16, 2024 at 10:47:14PM +0530, Naresh Solanki wrote: > > > Add regmap support. > > > > > > > Missing (and not really utilizing) the benefits of using regmap. > This is just replacing with regmap support > > > > > Signed-off-by: Naresh Solanki <naresh.solanki@9elements.com> > > > --- > > > drivers/hwmon/Kconfig | 1 + > > > drivers/hwmon/max6639.c | 157 ++++++++++++++++++++-------------------- > > > 2 files changed, 80 insertions(+), 78 deletions(-) > > > > > > diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig > > > index c89776d91795..257ec5360e35 100644 > > > --- a/drivers/hwmon/Kconfig > > > +++ b/drivers/hwmon/Kconfig > > > @@ -1223,6 +1223,7 @@ config SENSORS_MAX6621 > > > config SENSORS_MAX6639 > > > tristate "Maxim MAX6639 sensor chip" > > > depends on I2C > > > + select REGMAP_I2C > > > help > > > If you say yes here you get support for the MAX6639 > > > sensor chips. > > > diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c > > > index aa7f21ab2395..1af93fc53cb5 100644 > > > --- a/drivers/hwmon/max6639.c > > > +++ b/drivers/hwmon/max6639.c > > > @@ -20,6 +20,7 @@ > > > #include <linux/err.h> > > > #include <linux/mutex.h> > > > #include <linux/platform_data/max6639.h> > > > +#include <linux/regmap.h> > > > > > > /* Addresses to scan */ > > > static const unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; > > > @@ -57,6 +58,8 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; > > > > > > #define MAX6639_FAN_CONFIG3_THERM_FULL_SPEED 0x40 > > > > > > +#define MAX6639_NDEV 2 > > > + > > > static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; > > > > > > #define FAN_FROM_REG(val, rpm_range) ((val) == 0 || (val) == 255 ? \ > > > @@ -67,7 +70,7 @@ static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; > > > * Client data (each client gets its own) > > > */ > > > struct max6639_data { > > > - struct i2c_client *client; > > > + struct regmap *regmap; > > > struct mutex update_lock; > > > bool valid; /* true if following fields are valid */ > > > unsigned long last_updated; /* In jiffies */ > > > @@ -95,9 +98,8 @@ struct max6639_data { > > > static struct max6639_data *max6639_update_device(struct device *dev) > > > { > > > struct max6639_data *data = dev_get_drvdata(dev); > > > - struct i2c_client *client = data->client; > > > struct max6639_data *ret = data; > > > - int i; > > > + int i, err; > > > int status_reg; > > > > > > mutex_lock(&data->update_lock); > > > @@ -105,39 +107,35 @@ static struct max6639_data *max6639_update_device(struct device *dev) > > > > Conversions to regmap should drop all local caching and use regmap > > for caching (where appropriate) instead. > max6639_update_device deals with volatile registers & caching isn't > available for these. > So ? Unless you replace caching (and accept that volatile registers are not cached) I do not see the value of this patch. Replacing direct chip accesses with regmap should have a reason better than "because". Using regmap for caching would be a valid reason. At the same time, the value of caching volatile registers is very much questionable. Guenter
Hi Guenter, On Mon, 22 Apr 2024 at 21:32, Guenter Roeck <linux@roeck-us.net> wrote: > > On Mon, Apr 22, 2024 at 04:06:16PM +0530, Naresh Solanki wrote: > > Hi Guenter, > > > > On Wed, 17 Apr 2024 at 02:55, Guenter Roeck <linux@roeck-us.net> wrote: > > > > > > On Tue, Apr 16, 2024 at 10:47:14PM +0530, Naresh Solanki wrote: > > > > Add regmap support. > > > > > > > > > > Missing (and not really utilizing) the benefits of using regmap. > > This is just replacing with regmap support > > > > > > > Signed-off-by: Naresh Solanki <naresh.solanki@9elements.com> > > > > --- > > > > drivers/hwmon/Kconfig | 1 + > > > > drivers/hwmon/max6639.c | 157 ++++++++++++++++++++-------------------- > > > > 2 files changed, 80 insertions(+), 78 deletions(-) > > > > > > > > diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig > > > > index c89776d91795..257ec5360e35 100644 > > > > --- a/drivers/hwmon/Kconfig > > > > +++ b/drivers/hwmon/Kconfig > > > > @@ -1223,6 +1223,7 @@ config SENSORS_MAX6621 > > > > config SENSORS_MAX6639 > > > > tristate "Maxim MAX6639 sensor chip" > > > > depends on I2C > > > > + select REGMAP_I2C > > > > help > > > > If you say yes here you get support for the MAX6639 > > > > sensor chips. > > > > diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c > > > > index aa7f21ab2395..1af93fc53cb5 100644 > > > > --- a/drivers/hwmon/max6639.c > > > > +++ b/drivers/hwmon/max6639.c > > > > @@ -20,6 +20,7 @@ > > > > #include <linux/err.h> > > > > #include <linux/mutex.h> > > > > #include <linux/platform_data/max6639.h> > > > > +#include <linux/regmap.h> > > > > > > > > /* Addresses to scan */ > > > > static const unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; > > > > @@ -57,6 +58,8 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; > > > > > > > > #define MAX6639_FAN_CONFIG3_THERM_FULL_SPEED 0x40 > > > > > > > > +#define MAX6639_NDEV 2 > > > > + > > > > static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; > > > > > > > > #define FAN_FROM_REG(val, rpm_range) ((val) == 0 || (val) == 255 ? \ > > > > @@ -67,7 +70,7 @@ static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; > > > > * Client data (each client gets its own) > > > > */ > > > > struct max6639_data { > > > > - struct i2c_client *client; > > > > + struct regmap *regmap; > > > > struct mutex update_lock; > > > > bool valid; /* true if following fields are valid */ > > > > unsigned long last_updated; /* In jiffies */ > > > > @@ -95,9 +98,8 @@ struct max6639_data { > > > > static struct max6639_data *max6639_update_device(struct device *dev) > > > > { > > > > struct max6639_data *data = dev_get_drvdata(dev); > > > > - struct i2c_client *client = data->client; > > > > struct max6639_data *ret = data; > > > > - int i; > > > > + int i, err; > > > > int status_reg; > > > > > > > > mutex_lock(&data->update_lock); > > > > @@ -105,39 +107,35 @@ static struct max6639_data *max6639_update_device(struct device *dev) > > > > > > Conversions to regmap should drop all local caching and use regmap > > > for caching (where appropriate) instead. > > max6639_update_device deals with volatile registers & caching isn't > > available for these. > > > > So ? Unless you replace caching (and accept that volatile registers > are not cached) I do not see the value of this patch. Replacing direct > chip accesses with regmap should have a reason better than "because". > Using regmap for caching would be a valid reason. At the same time, > the value of caching volatile registers is very much questionable. This driver has 27 regmap accesses. Except volatile registers, others are cached by regmap. Some function which only access volatile registers will not be able to take advantage of caching. This is also the case in various other drivers for similar devices. Also regmap offers bit handling which makes the code much cleaner. Regards, Naresh > > Guenter
On 4/25/24 02:50, Naresh Solanki wrote: ... > This driver has 27 regmap accesses. Except volatile registers, others are > cached by regmap. > Some function which only access volatile registers will not be able to take > advantage of caching. This is also the case in various other drivers for similar > devices. > Also regmap offers bit handling which makes the code much cleaner. > Maybe I need to make it explicit in documentation. I will not accept regmap conversions unless local caching is dropped. Yes, that means that volatile registers will not be cached. I consider that a positive. Guenter
Hi Guenter, On Sun, 28 Apr 2024 at 22:48, Guenter Roeck <linux@roeck-us.net> wrote: > > On 4/25/24 02:50, Naresh Solanki wrote: > ... > > This driver has 27 regmap accesses. Except volatile registers, others are > > cached by regmap. > > Some function which only access volatile registers will not be able to take > > advantage of caching. This is also the case in various other drivers for similar > > devices. > > Also regmap offers bit handling which makes the code much cleaner. > > > > Maybe I need to make it explicit in documentation. I will not accept regmap > conversions unless local caching is dropped. Yes, that means that volatile > registers will not be cached. I consider that a positive. I agree with you. Regmap conversion wouldn't make sense if local caching is present. Correct me if I'm wrong, but in this context, local caching points to the various variables in max6639_data ? i.e., bool valid; /* true if following fields are valid */ unsigned long last_updated; /* In jiffies */ /* Register values sampled regularly */ u16 temp[2]; /* Temperature, in 1/8 C, 0..255 C */ bool temp_fault[2]; /* Detected temperature diode failure */ u8 fan[2]; /* Register value: TACH count for fans >=30 */ u8 status; /* Detected channel alarms and fan failures */ /* Register values only written to */ u8 pwm[2]; /* Register value: Duty cycle 0..120 */ u8 temp_therm[2]; /* THERM Temperature, 0..255 C (->_max) */ u8 temp_alert[2]; /* ALERT Temperature, 0..255 C (->_crit) */ u8 temp_ot[2]; /* OT Temperature, 0..255 C (->_emergency) */ /* Register values initialized only once */ u8 ppr; /* Pulses per rotation 0..3 for 1..4 ppr */ u8 rpm_range; /* Index in above rpm_ranges table */ Are you asking for removal of all these variables & each read sysfs attribute read should access regmap cache directly ? Regards, Naresh > > Guenter >
On 4/29/24 01:19, Naresh Solanki wrote: > Hi Guenter, > > > On Sun, 28 Apr 2024 at 22:48, Guenter Roeck <linux@roeck-us.net> wrote: >> >> On 4/25/24 02:50, Naresh Solanki wrote: >> ... >>> This driver has 27 regmap accesses. Except volatile registers, others are >>> cached by regmap. >>> Some function which only access volatile registers will not be able to take >>> advantage of caching. This is also the case in various other drivers for similar >>> devices. >>> Also regmap offers bit handling which makes the code much cleaner. >>> >> >> Maybe I need to make it explicit in documentation. I will not accept regmap >> conversions unless local caching is dropped. Yes, that means that volatile >> registers will not be cached. I consider that a positive. > I agree with you. Regmap conversion wouldn't make sense if local caching > is present. > Correct me if I'm wrong, but in this context, local caching points to the > various variables in max6639_data ? > i.e., > bool valid; /* true if following fields are valid */ > unsigned long last_updated; /* In jiffies */ > > /* Register values sampled regularly */ > u16 temp[2]; /* Temperature, in 1/8 C, 0..255 C */ > bool temp_fault[2]; /* Detected temperature diode failure */ > u8 fan[2]; /* Register value: TACH count for fans >=30 */ > u8 status; /* Detected channel alarms and fan failures */ > > /* Register values only written to */ > u8 pwm[2]; /* Register value: Duty cycle 0..120 */ > u8 temp_therm[2]; /* THERM Temperature, 0..255 C (->_max) */ > u8 temp_alert[2]; /* ALERT Temperature, 0..255 C (->_crit) */ > u8 temp_ot[2]; /* OT Temperature, 0..255 C (->_emergency) */ > > /* Register values initialized only once */ > u8 ppr; /* Pulses per rotation 0..3 for 1..4 ppr */ > u8 rpm_range; /* Index in above rpm_ranges table */ > > Are you asking for removal of all these variables & each read sysfs > attribute read should access regmap cache directly ? > Mostly yes. Note that "ppr" is only used in max6639_init_client(), and it is unnecessary to keep it in max6639_data to start with. rpm_range is ok to keep because it is a calculated initialization value. The fixed initialization of temp_therm, temp_alert, and temp_ot is questionable to start with because it overrides bios/rommon initialization values. Guenter
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index c89776d91795..257ec5360e35 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1223,6 +1223,7 @@ config SENSORS_MAX6621 config SENSORS_MAX6639 tristate "Maxim MAX6639 sensor chip" depends on I2C + select REGMAP_I2C help If you say yes here you get support for the MAX6639 sensor chips. diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c index aa7f21ab2395..1af93fc53cb5 100644 --- a/drivers/hwmon/max6639.c +++ b/drivers/hwmon/max6639.c @@ -20,6 +20,7 @@ #include <linux/err.h> #include <linux/mutex.h> #include <linux/platform_data/max6639.h> +#include <linux/regmap.h> /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; @@ -57,6 +58,8 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END }; #define MAX6639_FAN_CONFIG3_THERM_FULL_SPEED 0x40 +#define MAX6639_NDEV 2 + static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; #define FAN_FROM_REG(val, rpm_range) ((val) == 0 || (val) == 255 ? \ @@ -67,7 +70,7 @@ static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 }; * Client data (each client gets its own) */ struct max6639_data { - struct i2c_client *client; + struct regmap *regmap; struct mutex update_lock; bool valid; /* true if following fields are valid */ unsigned long last_updated; /* In jiffies */ @@ -95,9 +98,8 @@ struct max6639_data { static struct max6639_data *max6639_update_device(struct device *dev) { struct max6639_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; struct max6639_data *ret = data; - int i; + int i, err; int status_reg; mutex_lock(&data->update_lock); @@ -105,39 +107,35 @@ static struct max6639_data *max6639_update_device(struct device *dev) if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { int res; - dev_dbg(&client->dev, "Starting max6639 update\n"); + dev_dbg(dev, "Starting max6639 update\n"); - status_reg = i2c_smbus_read_byte_data(client, - MAX6639_REG_STATUS); - if (status_reg < 0) { - ret = ERR_PTR(status_reg); + err = regmap_read(data->regmap, MAX6639_REG_STATUS, &status_reg); + if (err < 0) { + ret = ERR_PTR(err); goto abort; } data->status = status_reg; for (i = 0; i < 2; i++) { - res = i2c_smbus_read_byte_data(client, - MAX6639_REG_FAN_CNT(i)); - if (res < 0) { - ret = ERR_PTR(res); + err = regmap_read(data->regmap, MAX6639_REG_FAN_CNT(i), &res); + if (err < 0) { + ret = ERR_PTR(err); goto abort; } data->fan[i] = res; - res = i2c_smbus_read_byte_data(client, - MAX6639_REG_TEMP_EXT(i)); - if (res < 0) { - ret = ERR_PTR(res); + err = regmap_read(data->regmap, MAX6639_REG_TEMP_EXT(i), &res); + if (err < 0) { + ret = ERR_PTR(err); goto abort; } data->temp[i] = res >> 5; data->temp_fault[i] = res & 0x01; - res = i2c_smbus_read_byte_data(client, - MAX6639_REG_TEMP(i)); - if (res < 0) { - ret = ERR_PTR(res); + err = regmap_read(data->regmap, MAX6639_REG_TEMP(i), &res); + if (err < 0) { + ret = ERR_PTR(err); goto abort; } data->temp[i] |= res << 3; @@ -193,7 +191,6 @@ static ssize_t temp_max_store(struct device *dev, { struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); struct max6639_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; unsigned long val; int res; @@ -203,9 +200,8 @@ static ssize_t temp_max_store(struct device *dev, mutex_lock(&data->update_lock); data->temp_therm[attr->index] = TEMP_LIMIT_TO_REG(val); - i2c_smbus_write_byte_data(client, - MAX6639_REG_THERM_LIMIT(attr->index), - data->temp_therm[attr->index]); + regmap_write(data->regmap, MAX6639_REG_THERM_LIMIT(attr->index), + data->temp_therm[attr->index]); mutex_unlock(&data->update_lock); return count; } @@ -225,7 +221,6 @@ static ssize_t temp_crit_store(struct device *dev, { struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); struct max6639_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; unsigned long val; int res; @@ -235,9 +230,8 @@ static ssize_t temp_crit_store(struct device *dev, mutex_lock(&data->update_lock); data->temp_alert[attr->index] = TEMP_LIMIT_TO_REG(val); - i2c_smbus_write_byte_data(client, - MAX6639_REG_ALERT_LIMIT(attr->index), - data->temp_alert[attr->index]); + regmap_write(data->regmap, MAX6639_REG_ALERT_LIMIT(attr->index), + data->temp_alert[attr->index]); mutex_unlock(&data->update_lock); return count; } @@ -258,7 +252,6 @@ static ssize_t temp_emergency_store(struct device *dev, { struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); struct max6639_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; unsigned long val; int res; @@ -268,9 +261,7 @@ static ssize_t temp_emergency_store(struct device *dev, mutex_lock(&data->update_lock); data->temp_ot[attr->index] = TEMP_LIMIT_TO_REG(val); - i2c_smbus_write_byte_data(client, - MAX6639_REG_OT_LIMIT(attr->index), - data->temp_ot[attr->index]); + regmap_write(data->regmap, MAX6639_REG_OT_LIMIT(attr->index), data->temp_ot[attr->index]); mutex_unlock(&data->update_lock); return count; } @@ -290,7 +281,6 @@ static ssize_t pwm_store(struct device *dev, { struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); struct max6639_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; unsigned long val; int res; @@ -302,9 +292,7 @@ static ssize_t pwm_store(struct device *dev, mutex_lock(&data->update_lock); data->pwm[attr->index] = (u8)(val * 120 / 255); - i2c_smbus_write_byte_data(client, - MAX6639_REG_TARGTDUTY(attr->index), - data->pwm[attr->index]); + regmap_write(data->regmap, MAX6639_REG_TARGTDUTY(attr->index), data->pwm[attr->index]); mutex_unlock(&data->update_lock); return count; } @@ -411,8 +399,7 @@ static int max6639_init_client(struct i2c_client *client, int err; /* Reset chip to default values, see below for GCONFIG setup */ - err = i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG, - MAX6639_GCONFIG_POR); + err = regmap_write(data->regmap, MAX6639_REG_GCONFIG, MAX6639_GCONFIG_POR); if (err) goto exit; @@ -431,26 +418,21 @@ static int max6639_init_client(struct i2c_client *client, for (i = 0; i < 2; i++) { /* Set Fan pulse per revolution */ - err = i2c_smbus_write_byte_data(client, - MAX6639_REG_FAN_PPR(i), - data->ppr << 6); + err = regmap_write(data->regmap, MAX6639_REG_FAN_PPR(i), data->ppr << 6); if (err) goto exit; /* Fans config PWM, RPM */ - err = i2c_smbus_write_byte_data(client, - MAX6639_REG_FAN_CONFIG1(i), - MAX6639_FAN_CONFIG1_PWM | rpm_range); + err = regmap_write(data->regmap, MAX6639_REG_FAN_CONFIG1(i), + MAX6639_FAN_CONFIG1_PWM | rpm_range); if (err) goto exit; /* Fans PWM polarity high by default */ if (max6639_info && max6639_info->pwm_polarity == 0) - err = i2c_smbus_write_byte_data(client, - MAX6639_REG_FAN_CONFIG2a(i), 0x00); + err = regmap_write(data->regmap, MAX6639_REG_FAN_CONFIG2a(i), 0x00); else - err = i2c_smbus_write_byte_data(client, - MAX6639_REG_FAN_CONFIG2a(i), 0x02); + err = regmap_write(data->regmap, MAX6639_REG_FAN_CONFIG2a(i), 0x02); if (err) goto exit; @@ -458,9 +440,8 @@ static int max6639_init_client(struct i2c_client *client, * /THERM full speed enable, * PWM frequency 25kHz, see also GCONFIG below */ - err = i2c_smbus_write_byte_data(client, - MAX6639_REG_FAN_CONFIG3(i), - MAX6639_FAN_CONFIG3_THERM_FULL_SPEED | 0x03); + err = regmap_write(data->regmap, MAX6639_REG_FAN_CONFIG3(i), + MAX6639_FAN_CONFIG3_THERM_FULL_SPEED | 0x03); if (err) goto exit; @@ -468,32 +449,26 @@ static int max6639_init_client(struct i2c_client *client, data->temp_therm[i] = 80; data->temp_alert[i] = 90; data->temp_ot[i] = 100; - err = i2c_smbus_write_byte_data(client, - MAX6639_REG_THERM_LIMIT(i), - data->temp_therm[i]); + err = regmap_write(data->regmap, MAX6639_REG_THERM_LIMIT(i), data->temp_therm[i]); if (err) goto exit; - err = i2c_smbus_write_byte_data(client, - MAX6639_REG_ALERT_LIMIT(i), - data->temp_alert[i]); + err = regmap_write(data->regmap, MAX6639_REG_ALERT_LIMIT(i), data->temp_alert[i]); if (err) goto exit; - err = i2c_smbus_write_byte_data(client, - MAX6639_REG_OT_LIMIT(i), data->temp_ot[i]); + err = regmap_write(data->regmap, MAX6639_REG_OT_LIMIT(i), data->temp_ot[i]); if (err) goto exit; /* PWM 120/120 (i.e. 100%) */ data->pwm[i] = 120; - err = i2c_smbus_write_byte_data(client, - MAX6639_REG_TARGTDUTY(i), data->pwm[i]); + err = regmap_write(data->regmap, MAX6639_REG_TARGTDUTY(i), data->pwm[i]); if (err) goto exit; } /* Start monitoring */ - err = i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG, - MAX6639_GCONFIG_DISABLE_TIMEOUT | MAX6639_GCONFIG_CH2_LOCAL | - MAX6639_GCONFIG_PWM_FREQ_HI); + err = regmap_write(data->regmap, MAX6639_REG_GCONFIG, + MAX6639_GCONFIG_DISABLE_TIMEOUT | MAX6639_GCONFIG_CH2_LOCAL | + MAX6639_GCONFIG_PWM_FREQ_HI); exit: return err; } @@ -524,6 +499,30 @@ static void max6639_regulator_disable(void *data) regulator_disable(data); } +static bool max6639_regmap_is_volatile(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MAX6639_REG_TEMP(0): + case MAX6639_REG_TEMP_EXT(0): + case MAX6639_REG_TEMP(1): + case MAX6639_REG_TEMP_EXT(1): + case MAX6639_REG_STATUS: + case MAX6639_REG_FAN_CNT(0): + case MAX6639_REG_FAN_CNT(1): + return true; + default: + return false; + } +} + +static const struct regmap_config max6639_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = MAX6639_REG_DEVREV, + .cache_type = REGCACHE_MAPLE, + .volatile_reg = max6639_regmap_is_volatile, +}; + static int max6639_probe(struct i2c_client *client) { struct device *dev = &client->dev; @@ -535,7 +534,11 @@ static int max6639_probe(struct i2c_client *client) if (!data) return -ENOMEM; - data->client = client; + data->regmap = devm_regmap_init_i2c(client, &max6639_regmap_config); + if (IS_ERR(data->regmap)) + return dev_err_probe(dev, + PTR_ERR(data->regmap), + "regmap initialization failed\n"); data->reg = devm_regulator_get_optional(dev, "fan"); if (IS_ERR(data->reg)) { @@ -573,25 +576,24 @@ static int max6639_probe(struct i2c_client *client) static int max6639_suspend(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); struct max6639_data *data = dev_get_drvdata(dev); - int ret = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG); + int ret, err; + + err = regmap_read(data->regmap, MAX6639_REG_GCONFIG, &ret); - if (ret < 0) - return ret; + if (err < 0) + return err; if (data->reg) regulator_disable(data->reg); - return i2c_smbus_write_byte_data(client, - MAX6639_REG_GCONFIG, ret | MAX6639_GCONFIG_STANDBY); + return regmap_write(data->regmap, MAX6639_REG_GCONFIG, ret | MAX6639_GCONFIG_STANDBY); } static int max6639_resume(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); struct max6639_data *data = dev_get_drvdata(dev); - int ret; + int ret, err; if (data->reg) { ret = regulator_enable(data->reg); @@ -601,12 +603,11 @@ static int max6639_resume(struct device *dev) } } - ret = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG); - if (ret < 0) - return ret; + err = regmap_read(data->regmap, MAX6639_REG_GCONFIG, &ret); + if (err < 0) + return err; - return i2c_smbus_write_byte_data(client, - MAX6639_REG_GCONFIG, ret & ~MAX6639_GCONFIG_STANDBY); + return regmap_write(data->regmap, MAX6639_REG_GCONFIG, ret & ~MAX6639_GCONFIG_STANDBY); } static const struct i2c_device_id max6639_id[] = {
Add regmap support. Signed-off-by: Naresh Solanki <naresh.solanki@9elements.com> --- drivers/hwmon/Kconfig | 1 + drivers/hwmon/max6639.c | 157 ++++++++++++++++++++-------------------- 2 files changed, 80 insertions(+), 78 deletions(-) base-commit: db85dba9fee5fed54e2c37eed465f8fd243a92e8