* [PATCH 0/2] Update MAX31827 driver @ 2024-05-22 12:39 Radu Sabau 2024-05-22 12:39 ` [PATCH 1/2] drivers: hwmon: max31827: Add PEC support Radu Sabau 2024-05-22 12:39 ` [PATCH 2/2] drivers: hwmon: max31827: Add debugfs support Radu Sabau 0 siblings, 2 replies; 8+ messages in thread From: Radu Sabau @ 2024-05-22 12:39 UTC (permalink / raw) To: Jean Delvare, Guenter Roeck, Jonathan Corbet, linux-hwmon, linux-doc, linux-kernel Cc: Radu Sabau Add PEC support for MAX31827 by inspiring from lm90.c driver, hence creating "pec" file and attaching it to the i2c device. Add debugfs support for MAX31827 by creating max31827 directory in /sys/kernel/debug/ folder that includes debugfs files specific for configuration bits in the configuration register that one may want to use in order to configure the chip in a specific way. Radu Sabau (2): drivers: hwmon: max31827: Add PEC support drivers: hwmon: max31827: Add debugfs support Documentation/hwmon/max31827.rst | 38 +++- drivers/hwmon/max31827.c | 297 +++++++++++++++++++++++++++++-- 2 files changed, 317 insertions(+), 18 deletions(-) -- 2.34.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] drivers: hwmon: max31827: Add PEC support 2024-05-22 12:39 [PATCH 0/2] Update MAX31827 driver Radu Sabau @ 2024-05-22 12:39 ` Radu Sabau 2024-05-22 13:08 ` Nuno Sá ` (2 more replies) 2024-05-22 12:39 ` [PATCH 2/2] drivers: hwmon: max31827: Add debugfs support Radu Sabau 1 sibling, 3 replies; 8+ messages in thread From: Radu Sabau @ 2024-05-22 12:39 UTC (permalink / raw) To: Jean Delvare, Guenter Roeck, Jonathan Corbet, linux-hwmon, linux-doc, linux-kernel Cc: Radu Sabau Add support for PEC by attaching PEC attribute to the i2c device. Add pec_store and pec_show function for accesing the "pec" file. Signed-off-by: Radu Sabau <radu.sabau@analog.com> --- Documentation/hwmon/max31827.rst | 13 ++++- drivers/hwmon/max31827.c | 95 +++++++++++++++++++++++++++----- 2 files changed, 92 insertions(+), 16 deletions(-) diff --git a/Documentation/hwmon/max31827.rst b/Documentation/hwmon/max31827.rst index 44ab9dc064cb..9c11a9518c67 100644 --- a/Documentation/hwmon/max31827.rst +++ b/Documentation/hwmon/max31827.rst @@ -131,7 +131,14 @@ The Fault Queue bits select how many consecutive temperature faults must occur before overtemperature or undertemperature faults are indicated in the corresponding status bits. -Notes ------ +PEC Support +----------- + +When reading a register value, the PEC byte is computed and sent by the chip. + +PEC on word data transaction respresents a signifcant increase in bandwitdh +usage (+33% for both write and reads) in normal conditions. -PEC is not implemented. +Since this operation implies there will be an extra delay to each +transaction, PEC can be disabled or enabled through sysfs. +Just write 1 to the "pec" file for enabling PEC and 0 for disabling it. diff --git a/drivers/hwmon/max31827.c b/drivers/hwmon/max31827.c index f8a13b30f100..16a1524413db 100644 --- a/drivers/hwmon/max31827.c +++ b/drivers/hwmon/max31827.c @@ -11,19 +11,20 @@ #include <linux/hwmon.h> #include <linux/i2c.h> #include <linux/mutex.h> -#include <linux/of_device.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> +#include <linux/of_device.h> -#define MAX31827_T_REG 0x0 +#define MAX31827_T_REG 0x0 #define MAX31827_CONFIGURATION_REG 0x2 -#define MAX31827_TH_REG 0x4 -#define MAX31827_TL_REG 0x6 -#define MAX31827_TH_HYST_REG 0x8 -#define MAX31827_TL_HYST_REG 0xA +#define MAX31827_TH_REG 0x4 +#define MAX31827_TL_REG 0x6 +#define MAX31827_TH_HYST_REG 0x8 +#define MAX31827_TL_HYST_REG 0xA #define MAX31827_CONFIGURATION_1SHOT_MASK BIT(0) #define MAX31827_CONFIGURATION_CNV_RATE_MASK GENMASK(3, 1) +#define MAX31827_CONFIGURATION_PEC_EN_MASK BIT(4) #define MAX31827_CONFIGURATION_TIMEOUT_MASK BIT(5) #define MAX31827_CONFIGURATION_RESOLUTION_MASK GENMASK(7, 6) #define MAX31827_CONFIGURATION_ALRM_POL_MASK BIT(8) @@ -46,6 +47,8 @@ #define MAX31827_M_DGR_TO_16_BIT(x) (((x) << 4) / 1000) #define MAX31827_DEVICE_ENABLE(x) ((x) ? 0xA : 0x0) +#define DEBUG_FS_DATA_MAX 16 + enum chips { max31827 = 1, max31828, max31829 }; enum max31827_cnv { @@ -151,8 +154,8 @@ static int shutdown_write(struct max31827_state *st, unsigned int reg, goto unlock; ret = regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG, - MAX31827_CONFIGURATION_CNV_RATE_MASK, - cnv_rate); + MAX31827_CONFIGURATION_CNV_RATE_MASK, + cnv_rate); unlock: mutex_unlock(&st->lock); @@ -344,7 +347,7 @@ static int max31827_write(struct device *dev, enum hwmon_sensor_types type, switch (attr) { case hwmon_temp_enable: if (val >> 1) - return -EINVAL; + return -EOPNOTSUPP; mutex_lock(&st->lock); /** @@ -384,7 +387,7 @@ static int max31827_write(struct device *dev, enum hwmon_sensor_types type, case hwmon_chip: if (attr == hwmon_chip_update_interval) { if (!st->enable) - return -EINVAL; + return -EOPNOTSUPP; /* * Convert the desired conversion rate into register @@ -472,11 +475,60 @@ static ssize_t temp1_resolution_store(struct device *dev, return ret ? ret : count; } - static DEVICE_ATTR_RW(temp1_resolution); +static ssize_t pec_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + + return scnprintf(buf, PAGE_SIZE, "%d\n", !!(client->flags & I2C_CLIENT_PEC)); +} + +static ssize_t pec_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct max31827_state *st = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + unsigned int val, val2; + int err; + + err = kstrtouint(buf, 10, &val); + if (err < 0) + return err; + + val2 = FIELD_PREP(MAX31827_CONFIGURATION_PEC_EN_MASK, !!val); + + switch (val) { + case 0: + err = regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG, + MAX31827_CONFIGURATION_PEC_EN_MASK, + val2); + if (err) + return err; + + client->flags &= ~I2C_CLIENT_PEC; + break; + case 1: + err = regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG, + MAX31827_CONFIGURATION_PEC_EN_MASK, + val2); + if (err) + return err; + + client->flags |= I2C_CLIENT_PEC; + break; + default: + return -EINVAL; + } + + return count; +} +static DEVICE_ATTR_RW(pec); + static struct attribute *max31827_attrs[] = { &dev_attr_temp1_resolution.attr, + &dev_attr_pec.attr, NULL }; ATTRIBUTE_GROUPS(max31827); @@ -493,8 +545,8 @@ static int max31827_init_client(struct max31827_state *st, struct device *dev) { struct fwnode_handle *fwnode; + unsigned int data, lsb_idx; unsigned int res = 0; - u32 data, lsb_idx; enum chips type; bool prop; int ret; @@ -578,6 +630,11 @@ static int max31827_init_client(struct max31827_state *st, return regmap_write(st->regmap, MAX31827_CONFIGURATION_REG, res); } +static void max31827_remove_pec(void *dev) +{ + device_remove_file(dev, &dev_attr_pec); +} + static const struct hwmon_channel_info *max31827_info[] = { HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MIN_HYST | HWMON_T_MIN_ALARM | @@ -627,6 +684,16 @@ static int max31827_probe(struct i2c_client *client) if (err) return err; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_PEC)) { + err = device_create_file(dev, &dev_attr_pec); + if (err) + return err; + + err = devm_add_action_or_reset(dev, max31827_remove_pec, dev); + if (err) + return err; + } + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, st, &max31827_chip_info, max31827_groups); @@ -652,15 +719,17 @@ static const struct of_device_id max31827_of_match[] = { MODULE_DEVICE_TABLE(of, max31827_of_match); static struct i2c_driver max31827_driver = { + .class = I2C_CLASS_HWMON, .driver = { .name = "max31827", .of_match_table = max31827_of_match, }, - .probe = max31827_probe, + .probe_new = max31827_probe, .id_table = max31827_i2c_ids, }; module_i2c_driver(max31827_driver); MODULE_AUTHOR("Daniel Matyas <daniel.matyas@analog.com>"); +MODULE_AUTHOR("Radu Sabau <radu.sabau@analog.com>"); MODULE_DESCRIPTION("Maxim MAX31827 low-power temperature switch driver"); MODULE_LICENSE("GPL"); -- 2.34.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] drivers: hwmon: max31827: Add PEC support 2024-05-22 12:39 ` [PATCH 1/2] drivers: hwmon: max31827: Add PEC support Radu Sabau @ 2024-05-22 13:08 ` Nuno Sá 2024-05-23 4:37 ` kernel test robot 2024-05-23 5:11 ` Guenter Roeck 2 siblings, 0 replies; 8+ messages in thread From: Nuno Sá @ 2024-05-22 13:08 UTC (permalink / raw) To: Radu Sabau, Jean Delvare, Guenter Roeck, Jonathan Corbet, linux-hwmon, linux-doc, linux-kernel On Wed, 2024-05-22 at 15:39 +0300, Radu Sabau wrote: > Add support for PEC by attaching PEC attribute to the i2c device. > Add pec_store and pec_show function for accesing the "pec" file. > > Signed-off-by: Radu Sabau <radu.sabau@analog.com> > --- > Documentation/hwmon/max31827.rst | 13 ++++- > drivers/hwmon/max31827.c | 95 +++++++++++++++++++++++++++----- > 2 files changed, 92 insertions(+), 16 deletions(-) > > diff --git a/Documentation/hwmon/max31827.rst b/Documentation/hwmon/max31827.rst > index 44ab9dc064cb..9c11a9518c67 100644 > --- a/Documentation/hwmon/max31827.rst > +++ b/Documentation/hwmon/max31827.rst > @@ -131,7 +131,14 @@ The Fault Queue bits select how many consecutive temperature > faults must occur > before overtemperature or undertemperature faults are indicated in the > corresponding status bits. > > -Notes > ------ > +PEC Support > +----------- > + > +When reading a register value, the PEC byte is computed and sent by the chip. > + > +PEC on word data transaction respresents a signifcant increase in bandwitdh > +usage (+33% for both write and reads) in normal conditions. > > -PEC is not implemented. > +Since this operation implies there will be an extra delay to each > +transaction, PEC can be disabled or enabled through sysfs. > +Just write 1 to the "pec" file for enabling PEC and 0 for disabling it. > diff --git a/drivers/hwmon/max31827.c b/drivers/hwmon/max31827.c > index f8a13b30f100..16a1524413db 100644 > --- a/drivers/hwmon/max31827.c > +++ b/drivers/hwmon/max31827.c > @@ -11,19 +11,20 @@ > #include <linux/hwmon.h> > #include <linux/i2c.h> > #include <linux/mutex.h> > -#include <linux/of_device.h> > #include <linux/regmap.h> > #include <linux/regulator/consumer.h> > +#include <linux/of_device.h> > Looks like unrelated change... > -#define MAX31827_T_REG 0x0 > +#define MAX31827_T_REG 0x0 > #define MAX31827_CONFIGURATION_REG 0x2 > -#define MAX31827_TH_REG 0x4 > -#define MAX31827_TL_REG 0x6 > -#define MAX31827_TH_HYST_REG 0x8 > -#define MAX31827_TL_HYST_REG 0xA > +#define MAX31827_TH_REG 0x4 > +#define MAX31827_TL_REG 0x6 > +#define MAX31827_TH_HYST_REG 0x8 > +#define MAX31827_TL_HYST_REG 0xA ditto for all the other places ... > > +static ssize_t pec_show(struct device *dev, struct device_attribute *devattr, > + char *buf) > +{ > + struct i2c_client *client = to_i2c_client(dev); > + > + return scnprintf(buf, PAGE_SIZE, "%d\n", !!(client->flags & > I2C_CLIENT_PEC)); sysfs_emit() > +} > + > +static ssize_t pec_store(struct device *dev, struct device_attribute *devattr, > + const char *buf, size_t count) > +{ > + struct max31827_state *st = dev_get_drvdata(dev); > + struct i2c_client *client = to_i2c_client(dev); > + unsigned int val, val2; > + int err; > + > + err = kstrtouint(buf, 10, &val); > + if (err < 0) > + return err; > + > + val2 = FIELD_PREP(MAX31827_CONFIGURATION_PEC_EN_MASK, !!val); > + Why not just val? > + switch (val) { > + case 0: > + err = regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG, > + MAX31827_CONFIGURATION_PEC_EN_MASK, > + val2); > + if (err) > + return err; > + > + client->flags &= ~I2C_CLIENT_PEC; > + break; > + case 1: > + err = regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG, > + MAX31827_CONFIGURATION_PEC_EN_MASK, > + val2); > + if (err) > + return err; > + > + client->flags |= I2C_CLIENT_PEC; > + break; > + default: > + return -EINVAL; > + } > + > + return count; > +} > +static DEVICE_ATTR_RW(pec); > + > static struct attribute *max31827_attrs[] = { > &dev_attr_temp1_resolution.attr, > + &dev_attr_pec.attr, Do we need it in here?? - Nuno Sá ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] drivers: hwmon: max31827: Add PEC support 2024-05-22 12:39 ` [PATCH 1/2] drivers: hwmon: max31827: Add PEC support Radu Sabau 2024-05-22 13:08 ` Nuno Sá @ 2024-05-23 4:37 ` kernel test robot 2024-05-23 5:11 ` Guenter Roeck 2 siblings, 0 replies; 8+ messages in thread From: kernel test robot @ 2024-05-23 4:37 UTC (permalink / raw) To: Radu Sabau, Jean Delvare, Guenter Roeck, Jonathan Corbet, linux-hwmon, linux-doc, linux-kernel Cc: llvm, oe-kbuild-all, Radu Sabau Hi Radu, kernel test robot noticed the following build errors: [auto build test ERROR on groeck-staging/hwmon-next] [also build test ERROR on linus/master v6.9 next-20240523] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Radu-Sabau/drivers-hwmon-max31827-Add-PEC-support/20240523-004248 base: https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next patch link: https://lore.kernel.org/r/20240522123923.22320-2-radu.sabau%40analog.com patch subject: [PATCH 1/2] drivers: hwmon: max31827: Add PEC support config: i386-buildonly-randconfig-003-20240523 (https://download.01.org/0day-ci/archive/20240523/202405231257.IOuSANzt-lkp@intel.com/config) compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240523/202405231257.IOuSANzt-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202405231257.IOuSANzt-lkp@intel.com/ All errors (new ones prefixed by >>): >> drivers/hwmon/max31827.c:727:3: error: field designator 'probe_new' does not refer to any field in type 'struct i2c_driver' 727 | .probe_new = max31827_probe, | ~^~~~~~~~~~~~~~~~~~~~~~~~~~ 1 error generated. vim +727 drivers/hwmon/max31827.c 720 721 static struct i2c_driver max31827_driver = { 722 .class = I2C_CLASS_HWMON, 723 .driver = { 724 .name = "max31827", 725 .of_match_table = max31827_of_match, 726 }, > 727 .probe_new = max31827_probe, 728 .id_table = max31827_i2c_ids, 729 }; 730 module_i2c_driver(max31827_driver); 731 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] drivers: hwmon: max31827: Add PEC support 2024-05-22 12:39 ` [PATCH 1/2] drivers: hwmon: max31827: Add PEC support Radu Sabau 2024-05-22 13:08 ` Nuno Sá 2024-05-23 4:37 ` kernel test robot @ 2024-05-23 5:11 ` Guenter Roeck 2 siblings, 0 replies; 8+ messages in thread From: Guenter Roeck @ 2024-05-23 5:11 UTC (permalink / raw) To: Radu Sabau, Jean Delvare, Jonathan Corbet, linux-hwmon, linux-doc, linux-kernel On 5/22/24 05:39, Radu Sabau wrote: > Add support for PEC by attaching PEC attribute to the i2c device. > Add pec_store and pec_show function for accesing the "pec" file. > accessing > Signed-off-by: Radu Sabau <radu.sabau@analog.com> > --- There are lots of unrelated changes. Please drop all those, or if they are supposed to fix checkpatch problems submit as separate patches. I will not accept coding style changes unless they fix checkpatch problems. The patch is not based on the latest kernel. Please rebase at least on top of v6.9. More comments inline. > Documentation/hwmon/max31827.rst | 13 ++++- > drivers/hwmon/max31827.c | 95 +++++++++++++++++++++++++++----- > 2 files changed, 92 insertions(+), 16 deletions(-) > > diff --git a/Documentation/hwmon/max31827.rst b/Documentation/hwmon/max31827.rst > index 44ab9dc064cb..9c11a9518c67 100644 > --- a/Documentation/hwmon/max31827.rst > +++ b/Documentation/hwmon/max31827.rst > @@ -131,7 +131,14 @@ The Fault Queue bits select how many consecutive temperature faults must occur > before overtemperature or undertemperature faults are indicated in the > corresponding status bits. > > -Notes > ------ > +PEC Support > +----------- > + > +When reading a register value, the PEC byte is computed and sent by the chip. > + > +PEC on word data transaction respresents a signifcant increase in bandwitdh > +usage (+33% for both write and reads) in normal conditions. > > -PEC is not implemented. > +Since this operation implies there will be an extra delay to each > +transaction, PEC can be disabled or enabled through sysfs. > +Just write 1 to the "pec" file for enabling PEC and 0 for disabling it. > diff --git a/drivers/hwmon/max31827.c b/drivers/hwmon/max31827.c > index f8a13b30f100..16a1524413db 100644 > --- a/drivers/hwmon/max31827.c > +++ b/drivers/hwmon/max31827.c > @@ -11,19 +11,20 @@ > #include <linux/hwmon.h> > #include <linux/i2c.h> > #include <linux/mutex.h> > -#include <linux/of_device.h> > #include <linux/regmap.h> > #include <linux/regulator/consumer.h> > +#include <linux/of_device.h> > Include files should be in alphabetic order. The above change deserves a NACK. > -#define MAX31827_T_REG 0x0 > +#define MAX31827_T_REG 0x0 > #define MAX31827_CONFIGURATION_REG 0x2 > -#define MAX31827_TH_REG 0x4 > -#define MAX31827_TL_REG 0x6 > -#define MAX31827_TH_HYST_REG 0x8 > -#define MAX31827_TL_HYST_REG 0xA > +#define MAX31827_TH_REG 0x4 > +#define MAX31827_TL_REG 0x6 > +#define MAX31827_TH_HYST_REG 0x8 > +#define MAX31827_TL_HYST_REG 0xA > > #define MAX31827_CONFIGURATION_1SHOT_MASK BIT(0) > #define MAX31827_CONFIGURATION_CNV_RATE_MASK GENMASK(3, 1) > +#define MAX31827_CONFIGURATION_PEC_EN_MASK BIT(4) > #define MAX31827_CONFIGURATION_TIMEOUT_MASK BIT(5) > #define MAX31827_CONFIGURATION_RESOLUTION_MASK GENMASK(7, 6) > #define MAX31827_CONFIGURATION_ALRM_POL_MASK BIT(8) > @@ -46,6 +47,8 @@ > #define MAX31827_M_DGR_TO_16_BIT(x) (((x) << 4) / 1000) > #define MAX31827_DEVICE_ENABLE(x) ((x) ? 0xA : 0x0) > > +#define DEBUG_FS_DATA_MAX 16 > + > enum chips { max31827 = 1, max31828, max31829 }; > > enum max31827_cnv { > @@ -151,8 +154,8 @@ static int shutdown_write(struct max31827_state *st, unsigned int reg, > goto unlock; > > ret = regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG, > - MAX31827_CONFIGURATION_CNV_RATE_MASK, > - cnv_rate); > + MAX31827_CONFIGURATION_CNV_RATE_MASK, > + cnv_rate); > > unlock: > mutex_unlock(&st->lock); > @@ -344,7 +347,7 @@ static int max31827_write(struct device *dev, enum hwmon_sensor_types type, > switch (attr) { > case hwmon_temp_enable: > if (val >> 1) > - return -EINVAL; > + return -EOPNOTSUPP; Why ? > > mutex_lock(&st->lock); > /** > @@ -384,7 +387,7 @@ static int max31827_write(struct device *dev, enum hwmon_sensor_types type, > case hwmon_chip: > if (attr == hwmon_chip_update_interval) { > if (!st->enable) > - return -EINVAL; > + return -EOPNOTSUPP; > > /* > * Convert the desired conversion rate into register > @@ -472,11 +475,60 @@ static ssize_t temp1_resolution_store(struct device *dev, > > return ret ? ret : count; > } > - > static DEVICE_ATTR_RW(temp1_resolution); > > +static ssize_t pec_show(struct device *dev, struct device_attribute *devattr, > + char *buf) > +{ > + struct i2c_client *client = to_i2c_client(dev); > + > + return scnprintf(buf, PAGE_SIZE, "%d\n", !!(client->flags & I2C_CLIENT_PEC)); > +} > + > +static ssize_t pec_store(struct device *dev, struct device_attribute *devattr, > + const char *buf, size_t count) > +{ > + struct max31827_state *st = dev_get_drvdata(dev); > + struct i2c_client *client = to_i2c_client(dev); > + unsigned int val, val2; > + int err; > + > + err = kstrtouint(buf, 10, &val); > + if (err < 0) > + return err; > + > + val2 = FIELD_PREP(MAX31827_CONFIGURATION_PEC_EN_MASK, !!val); This is completely unnecessary. > + > + switch (val) { > + case 0: > + err = regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG, > + MAX31827_CONFIGURATION_PEC_EN_MASK, > + val2); s/val2/0/ > + if (err) > + return err; > + > + client->flags &= ~I2C_CLIENT_PEC; > + break; > + case 1: > + err = regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG, > + MAX31827_CONFIGURATION_PEC_EN_MASK, > + val2); s/val2/MAX31827_CONFIGURATION_PEC_EN_MASK/ > + if (err) > + return err; > + > + client->flags |= I2C_CLIENT_PEC; > + break; > + default: > + return -EINVAL; > + } > + > + return count; > +} > +static DEVICE_ATTR_RW(pec); > + > static struct attribute *max31827_attrs[] = { > &dev_attr_temp1_resolution.attr, > + &dev_attr_pec.attr, Attach to i2c interface. Oh, wait, you are doing that as well. So there would be two "pec" attribute files, one attached to the i2c interface and one attached to the hwmon interface. Care to explain ? > NULL > }; > ATTRIBUTE_GROUPS(max31827); > @@ -493,8 +545,8 @@ static int max31827_init_client(struct max31827_state *st, > struct device *dev) > { > struct fwnode_handle *fwnode; > + unsigned int data, lsb_idx; > unsigned int res = 0; > - u32 data, lsb_idx; I am quite completely at loss trying to understand why you are making those changes. > enum chips type; > bool prop; > int ret; > @@ -578,6 +630,11 @@ static int max31827_init_client(struct max31827_state *st, > return regmap_write(st->regmap, MAX31827_CONFIGURATION_REG, res); > } > > +static void max31827_remove_pec(void *dev) > +{ > + device_remove_file(dev, &dev_attr_pec); > +} > + > static const struct hwmon_channel_info *max31827_info[] = { > HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT | HWMON_T_MIN | > HWMON_T_MIN_HYST | HWMON_T_MIN_ALARM | > @@ -627,6 +684,16 @@ static int max31827_probe(struct i2c_client *client) > if (err) > return err; > > + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_PEC)) { This does not make sense. If the controller does not support PEC, it does not make sense to provide an attribute to enable it. > + err = device_create_file(dev, &dev_attr_pec); > + if (err) > + return err; > + > + err = devm_add_action_or_reset(dev, max31827_remove_pec, dev); > + if (err) > + return err; > + } > + > hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, st, > &max31827_chip_info, > max31827_groups); > @@ -652,15 +719,17 @@ static const struct of_device_id max31827_of_match[] = { > MODULE_DEVICE_TABLE(of, max31827_of_match); > > static struct i2c_driver max31827_driver = { > + .class = I2C_CLASS_HWMON, > .driver = { > .name = "max31827", > .of_match_table = max31827_of_match, > }, > - .probe = max31827_probe, > + .probe_new = max31827_probe, > .id_table = max31827_i2c_ids, > }; > module_i2c_driver(max31827_driver); > > MODULE_AUTHOR("Daniel Matyas <daniel.matyas@analog.com>"); > +MODULE_AUTHOR("Radu Sabau <radu.sabau@analog.com>"); Providing a patch to a driver does not make you the author. > MODULE_DESCRIPTION("Maxim MAX31827 low-power temperature switch driver"); > MODULE_LICENSE("GPL"); ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/2] drivers: hwmon: max31827: Add debugfs support 2024-05-22 12:39 [PATCH 0/2] Update MAX31827 driver Radu Sabau 2024-05-22 12:39 ` [PATCH 1/2] drivers: hwmon: max31827: Add PEC support Radu Sabau @ 2024-05-22 12:39 ` Radu Sabau 2024-05-22 13:10 ` Nuno Sá 1 sibling, 1 reply; 8+ messages in thread From: Radu Sabau @ 2024-05-22 12:39 UTC (permalink / raw) To: Jean Delvare, Guenter Roeck, Jonathan Corbet, linux-hwmon, linux-doc, linux-kernel Cc: Radu Sabau Add debugfs support by creating directory in sys-fs which includes debugfs specific files used for configuring the device by preference. Signed-off-b: Radu Sabau <radu.sabau@analog.com> --- Documentation/hwmon/max31827.rst | 25 ++++ drivers/hwmon/max31827.c | 202 ++++++++++++++++++++++++++++++- 2 files changed, 225 insertions(+), 2 deletions(-) diff --git a/Documentation/hwmon/max31827.rst b/Documentation/hwmon/max31827.rst index 9c11a9518c67..940310be6075 100644 --- a/Documentation/hwmon/max31827.rst +++ b/Documentation/hwmon/max31827.rst @@ -142,3 +142,28 @@ usage (+33% for both write and reads) in normal conditions. Since this operation implies there will be an extra delay to each transaction, PEC can be disabled or enabled through sysfs. Just write 1 to the "pec" file for enabling PEC and 0 for disabling it. + +DebugFs entries +--------------- + +The chip also has a configuration register where each bit stands for a specific +functionality to be configured. Hence as one would like to have access to these +features, we give access to them in debugfs. + +.. warning:: The debugfs interface is subject to change without notice + and is only available when the kernel is compiled with + ``CONFIG_DEBUG_FS`` defined. + +``/sys/kernel/debug/max31827/`` +contains the following attributes: + +============== =============================================================== +alarm_polarity Write 1 for ALARM pin active state is low, 0 otherwise +comp_int Set to 1 if OT and UT status bits are in interrupt mode +fault_queue Number of consecutive temperature faults until OT and UT faults + are indicated in status bits +pec_error Set to 1 if PEC Enable bit is set, 0 otherwise +resolution 2-bit value that select the conversion resolution, please see + datasheet for corresponding values +timeout Write 1 do disable bus timeout, 0 otherwise +============== =============================================================== diff --git a/drivers/hwmon/max31827.c b/drivers/hwmon/max31827.c index 16a1524413db..1303ea81250d 100644 --- a/drivers/hwmon/max31827.c +++ b/drivers/hwmon/max31827.c @@ -13,8 +13,19 @@ #include <linux/mutex.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> +#include <linux/debugfs.h> #include <linux/of_device.h> +enum { + MAX31827_DEBUGFS_TIMEOUT = 0, + MAX31827_DEBUGFS_RESOLUTION, + MAX31827_DEBUGFS_ALARM_POLARITY, + MAX31827_DEBUGFS_COMP_INT, + MAX31827_DEBUGFS_FAULT_QUEUE, + MAX31827_DEBUGFS_PEC_ERROR, + MAX31827_DEBUGFS_NUM_ENTRIES +}; + #define MAX31827_T_REG 0x0 #define MAX31827_CONFIGURATION_REG 0x2 #define MAX31827_TH_REG 0x4 @@ -30,6 +41,7 @@ #define MAX31827_CONFIGURATION_ALRM_POL_MASK BIT(8) #define MAX31827_CONFIGURATION_COMP_INT_MASK BIT(9) #define MAX31827_CONFIGURATION_FLT_Q_MASK GENMASK(11, 10) +#define MAX31827_CONFIGURATION_PEC_ERR_MASK BIT(13) #define MAX31827_CONFIGURATION_U_TEMP_STAT_MASK BIT(14) #define MAX31827_CONFIGURATION_O_TEMP_STAT_MASK BIT(15) @@ -92,12 +104,17 @@ static const u16 max31827_conv_times[] = { [MAX31827_RES_12_BIT] = MAX31827_12_BIT_CNV_TIME, }; +struct max31827_debugfs_data { + int debugfs_entries[MAX31827_DEBUGFS_NUM_ENTRIES]; +}; + struct max31827_state { /* * Prevent simultaneous access to the i2c client. */ struct mutex lock; struct regmap *regmap; + struct max31827_debugfs_data psu; bool enable; unsigned int resolution; unsigned int update_interval; @@ -552,7 +569,6 @@ static int max31827_init_client(struct max31827_state *st, int ret; fwnode = dev_fwnode(dev); - st->enable = true; res |= MAX31827_DEVICE_ENABLE(1); @@ -655,6 +671,182 @@ static const struct hwmon_chip_info max31827_chip_info = { .info = max31827_info, }; +#ifdef CONFIG_DEBUG_FS +static ssize_t max31827_debugfs_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + char tbuf[DEBUG_FS_DATA_MAX] = { 0 }; + struct max31827_debugfs_data *psu; + struct max31827_state *st; + int *attrp = file_inode(file)->i_private; + int attr = *attrp; + unsigned int uval; + int ret, len; + + psu = container_of(attrp, struct max31827_debugfs_data, debugfs_entries[attr]); + st = container_of(psu, struct max31827_state, psu); + + ret = regmap_read(st->regmap, MAX31827_CONFIGURATION_REG, &uval); + if (ret) + return ret; + + switch (attr) { + case MAX31827_DEBUGFS_TIMEOUT: + uval = FIELD_GET(MAX31827_CONFIGURATION_TIMEOUT_MASK, uval); + len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", uval); + break; + case MAX31827_DEBUGFS_RESOLUTION: + uval = FIELD_GET(MAX31827_CONFIGURATION_RESOLUTION_MASK, uval); + len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", uval); + break; + case MAX31827_DEBUGFS_ALARM_POLARITY: + uval = FIELD_GET(MAX31827_CONFIGURATION_ALRM_POL_MASK, uval); + len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", uval); + break; + case MAX31827_DEBUGFS_COMP_INT: + uval = FIELD_GET(MAX31827_CONFIGURATION_COMP_INT_MASK, uval); + len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", uval); + break; + case MAX31827_DEBUGFS_FAULT_QUEUE: + uval = FIELD_GET(MAX31827_CONFIGURATION_FLT_Q_MASK, uval); + len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", uval); + break; + case MAX31827_DEBUGFS_PEC_ERROR: + uval = FIELD_GET(MAX31827_CONFIGURATION_PEC_ERR_MASK, uval); + len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", uval); + break; + default: + len = strscpy(tbuf, "Invalid\n", DEBUG_FS_DATA_MAX); + } + + return simple_read_from_buffer(buf, count, ppos, tbuf, len); +} + +static ssize_t max31827_debugfs_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + char tbuf[DEBUG_FS_DATA_MAX] = { 0 }; + struct max31827_debugfs_data *psu; + struct max31827_state *st; + int *attrp = file_inode(file)->i_private; + int attr = *attrp; + u16 uval; + int ret; + + pr_info("attr = %d\n", attr); + psu = container_of(attrp, struct max31827_debugfs_data, debugfs_entries[attr]); + pr_info("First container ok.\n"); + st = container_of(psu, struct max31827_state, psu); + + ret = kstrtou16_from_user(buf, count, 0, &uval); + if (ret) + return ret; + + pr_info("uval = %s\n", tbuf); + + switch (attr) { + case MAX31827_DEBUGFS_TIMEOUT: + uval = FIELD_PREP(MAX31827_CONFIGURATION_TIMEOUT_MASK, uval); + ret = regmap_update_bits(st->regmap, + MAX31827_CONFIGURATION_REG, + MAX31827_CONFIGURATION_TIMEOUT_MASK, + uval); + break; + case MAX31827_DEBUGFS_RESOLUTION: + uval = FIELD_PREP(MAX31827_CONFIGURATION_RESOLUTION_MASK, uval); + ret = regmap_update_bits(st->regmap, + MAX31827_CONFIGURATION_REG, + MAX31827_CONFIGURATION_RESOLUTION_MASK, + uval); + break; + case MAX31827_DEBUGFS_ALARM_POLARITY: + uval = FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK, uval); + ret = regmap_update_bits(st->regmap, + MAX31827_CONFIGURATION_REG, + MAX31827_CONFIGURATION_ALRM_POL_MASK, + uval); + break; + case MAX31827_DEBUGFS_COMP_INT: + uval = FIELD_PREP(MAX31827_CONFIGURATION_COMP_INT_MASK, uval); + ret = regmap_update_bits(st->regmap, + MAX31827_CONFIGURATION_REG, + MAX31827_CONFIGURATION_COMP_INT_MASK, + uval); + break; + case MAX31827_DEBUGFS_FAULT_QUEUE: + uval = FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK, uval); + ret = regmap_update_bits(st->regmap, + MAX31827_CONFIGURATION_REG, + MAX31827_CONFIGURATION_FLT_Q_MASK, + uval); + break; + default: + return -EINVAL; + } + + if (ret) + return ret; + + return count; +} + +static const struct file_operations max31827_fops = { + .read = max31827_debugfs_read, + .write = max31827_debugfs_write, +}; + +static void max31827_debugfs_remove(void *dir) +{ + debugfs_remove_recursive(dir); +} + +static int max31827_init_debugfs(struct max31827_state *st, + struct i2c_client *client) +{ + struct dentry *debugfs; + int ret, i; + + debugfs = debugfs_create_dir(client->name, NULL); + if (!debugfs) + return -ENOENT; + + for (i = 0; i < MAX31827_DEBUGFS_NUM_ENTRIES; ++i) + st->psu.debugfs_entries[i] = i; + + ret = devm_add_action_or_reset(&client->dev, max31827_debugfs_remove, + debugfs); + if (ret) + return ret; + + debugfs_create_file("timeout", 0644, debugfs, + &st->psu.debugfs_entries[MAX31827_DEBUGFS_TIMEOUT], + &max31827_fops); + debugfs_create_file("resolution", 0644, debugfs, + &st->psu.debugfs_entries[MAX31827_DEBUGFS_RESOLUTION], + &max31827_fops); + debugfs_create_file("alarm_polarity", 0644, debugfs, + &st->psu.debugfs_entries[MAX31827_DEBUGFS_ALARM_POLARITY], + &max31827_fops); + debugfs_create_file("comp_int", 0644, debugfs, + &st->psu.debugfs_entries[MAX31827_DEBUGFS_COMP_INT], + &max31827_fops); + debugfs_create_file("fault_queue", 0644, debugfs, + &st->psu.debugfs_entries[MAX31827_DEBUGFS_FAULT_QUEUE], + &max31827_fops); + debugfs_create_file("pec_error", 0444, debugfs, + &st->psu.debugfs_entries[MAX31827_DEBUGFS_PEC_ERROR], + &max31827_fops); + + return 0; +} +#else +static int max31827_init_debugfs(struct max31827_state *st, + struct i2c_client *client) +{ + return 0; +} +#endif /* CONFIG_DEBUG_FS */ + static int max31827_probe(struct i2c_client *client) { struct device *dev = &client->dev; @@ -698,7 +890,13 @@ static int max31827_probe(struct i2c_client *client) &max31827_chip_info, max31827_groups); - return PTR_ERR_OR_ZERO(hwmon_dev); + if (IS_ERR(hwmon_dev)) + return dev_err_probe(dev, PTR_ERR(hwmon_dev), + "Failed to register device"); + + max31827_init_debugfs(st, client); + + return 0; } static const struct of_device_id max31827_of_match[] = { -- 2.34.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] drivers: hwmon: max31827: Add debugfs support 2024-05-22 12:39 ` [PATCH 2/2] drivers: hwmon: max31827: Add debugfs support Radu Sabau @ 2024-05-22 13:10 ` Nuno Sá 2024-05-23 4:53 ` Guenter Roeck 0 siblings, 1 reply; 8+ messages in thread From: Nuno Sá @ 2024-05-22 13:10 UTC (permalink / raw) To: Radu Sabau, Jean Delvare, Guenter Roeck, Jonathan Corbet, linux-hwmon, linux-doc, linux-kernel On Wed, 2024-05-22 at 15:39 +0300, Radu Sabau wrote: > Add debugfs support by creating directory in sys-fs which includes > debugfs specific files used for configuring the device by > preference. > > Signed-off-b: Radu Sabau <radu.sabau@analog.com> > --- > Documentation/hwmon/max31827.rst | 25 ++++ > drivers/hwmon/max31827.c | 202 ++++++++++++++++++++++++++++++- > 2 files changed, 225 insertions(+), 2 deletions(-) > > diff --git a/Documentation/hwmon/max31827.rst b/Documentation/hwmon/max31827.rst > index 9c11a9518c67..940310be6075 100644 > --- a/Documentation/hwmon/max31827.rst > +++ b/Documentation/hwmon/max31827.rst > @@ -142,3 +142,28 @@ usage (+33% for both write and reads) in normal conditions. > Since this operation implies there will be an extra delay to each > transaction, PEC can be disabled or enabled through sysfs. > Just write 1 to the "pec" file for enabling PEC and 0 for disabling it. > + > +DebugFs entries > +--------------- > + > +The chip also has a configuration register where each bit stands for a specific > +functionality to be configured. Hence as one would like to have access to these > +features, we give access to them in debugfs. > + > +.. warning:: The debugfs interface is subject to change without notice > + and is only available when the kernel is compiled with > + ``CONFIG_DEBUG_FS`` defined. > + > +``/sys/kernel/debug/max31827/`` > +contains the following attributes: > + > +============== =============================================================== > +alarm_polarity Write 1 for ALARM pin active state is low, 0 otherwise > +comp_int Set to 1 if OT and UT status bits are in interrupt mode > +fault_queue Number of consecutive temperature faults until OT and UT faults > + are indicated in status bits > +pec_error Set to 1 if PEC Enable bit is set, 0 otherwise > +resolution 2-bit value that select the conversion resolution, please see > + datasheet for corresponding values > +timeout Write 1 do disable bus timeout, 0 otherwise From the description, the above really don't look like they belong into a debug interface... - Nuno Sá > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] drivers: hwmon: max31827: Add debugfs support 2024-05-22 13:10 ` Nuno Sá @ 2024-05-23 4:53 ` Guenter Roeck 0 siblings, 0 replies; 8+ messages in thread From: Guenter Roeck @ 2024-05-23 4:53 UTC (permalink / raw) To: Nuno Sá, Radu Sabau, Jean Delvare, Jonathan Corbet, linux-hwmon, linux-doc, linux-kernel On 5/22/24 06:10, Nuno Sá wrote: > On Wed, 2024-05-22 at 15:39 +0300, Radu Sabau wrote: >> Add debugfs support by creating directory in sys-fs which includes >> debugfs specific files used for configuring the device by >> preference. >> >> Signed-off-b: Radu Sabau <radu.sabau@analog.com> >> --- >> Documentation/hwmon/max31827.rst | 25 ++++ >> drivers/hwmon/max31827.c | 202 ++++++++++++++++++++++++++++++- >> 2 files changed, 225 insertions(+), 2 deletions(-) >> >> diff --git a/Documentation/hwmon/max31827.rst b/Documentation/hwmon/max31827.rst >> index 9c11a9518c67..940310be6075 100644 >> --- a/Documentation/hwmon/max31827.rst >> +++ b/Documentation/hwmon/max31827.rst >> @@ -142,3 +142,28 @@ usage (+33% for both write and reads) in normal conditions. >> Since this operation implies there will be an extra delay to each >> transaction, PEC can be disabled or enabled through sysfs. >> Just write 1 to the "pec" file for enabling PEC and 0 for disabling it. >> + >> +DebugFs entries >> +--------------- >> + >> +The chip also has a configuration register where each bit stands for a specific >> +functionality to be configured. Hence as one would like to have access to these >> +features, we give access to them in debugfs. >> + >> +.. warning:: The debugfs interface is subject to change without notice >> + and is only available when the kernel is compiled with >> + ``CONFIG_DEBUG_FS`` defined. >> + >> +``/sys/kernel/debug/max31827/`` >> +contains the following attributes: >> + >> +============== =============================================================== >> +alarm_polarity Write 1 for ALARM pin active state is low, 0 otherwise >> +comp_int Set to 1 if OT and UT status bits are in interrupt mode >> +fault_queue Number of consecutive temperature faults until OT and UT faults >> + are indicated in status bits >> +pec_error Set to 1 if PEC Enable bit is set, 0 otherwise >> +resolution 2-bit value that select the conversion resolution, please see >> + datasheet for corresponding values >> +timeout Write 1 do disable bus timeout, 0 otherwise > >>From the description, the above really don't look like they belong into a debug > interface... > Correct. The chip should be configured using firmware properties, which for the most part is already supported. An acceptable exception is PEC, but that configuration flag, if implemented as attribute, should be attached to the i2c client interface to match other drivers. Guenter ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2024-05-23 5:11 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-05-22 12:39 [PATCH 0/2] Update MAX31827 driver Radu Sabau 2024-05-22 12:39 ` [PATCH 1/2] drivers: hwmon: max31827: Add PEC support Radu Sabau 2024-05-22 13:08 ` Nuno Sá 2024-05-23 4:37 ` kernel test robot 2024-05-23 5:11 ` Guenter Roeck 2024-05-22 12:39 ` [PATCH 2/2] drivers: hwmon: max31827: Add debugfs support Radu Sabau 2024-05-22 13:10 ` Nuno Sá 2024-05-23 4:53 ` Guenter Roeck
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).