Re: [PATCH v4 1/2] hwmon: (max127) Add Maxim MAX127 hardware monitoring driver

2020-11-23 Thread Tao Ren
On Mon, Nov 23, 2020 at 05:18:32AM -0800, Guenter Roeck wrote:
> On Sun, Nov 22, 2020 at 11:45:31PM -0800, rentao.b...@gmail.com wrote:
> > From: Tao Ren 
> > 
> > Add hardware monitoring driver for the Maxim MAX127 chip.
> > 
> > MAX127 min/max range handling code is inspired by the max197 driver.
> > 
> > Signed-off-by: Tao Ren 
> > ---
> >  Changes in v4:
> >- delete unnecessary "#include" lines.
> >- simplify i2c_transfer() error handling.
> >- add mutex to protect ctrl_byte in write_min|max() functions.
> >  Changes in v3:
> >- no code change. xdp maintainers were removed from to/cc list.
> >  Changes in v2:
> >- replace devm_hwmon_device_register_with_groups() with
> >  devm_hwmon_device_register_with_info() API.
> >- divide min/max read and write methods to separate functions.
> >- fix raw-to-vin conversion logic.
> >- refine ctrl_byte handling so mutex is not needed to protect the
> >  byte.
> >- improve i2c_transfer() error handling.
> >- a few other improvements (comments, variable naming, and etc.).
> > 
> >  drivers/hwmon/Kconfig  |   9 ++
> >  drivers/hwmon/Makefile |   1 +
> >  drivers/hwmon/max127.c | 346 +
> >  3 files changed, 356 insertions(+)
> >  create mode 100644 drivers/hwmon/max127.c
> > 
> > diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> > index 9d600e0c5584..716df51edc87 100644
> > --- a/drivers/hwmon/Kconfig
> > +++ b/drivers/hwmon/Kconfig
> > @@ -950,6 +950,15 @@ config SENSORS_MAX
> >   This driver can also be built as a module. If so, the module
> >   will be called max.
> >  
> > +config SENSORS_MAX127
> > +   tristate "Maxim MAX127 12-bit 8-channel Data Acquisition System"
> > +   depends on I2C
> > +   help
> > + Say y here to support Maxim's MAX127 DAS chips.
> > +
> > + This driver can also be built as a module. If so, the module
> > + will be called max127.
> > +
> >  config SENSORS_MAX16065
> > tristate "Maxim MAX16065 System Manager and compatibles"
> > depends on I2C
> > diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> > index 1083bbfac779..01ca5d3fbad4 100644
> > --- a/drivers/hwmon/Makefile
> > +++ b/drivers/hwmon/Makefile
> > @@ -127,6 +127,7 @@ obj-$(CONFIG_SENSORS_LTC4260)   += ltc4260.o
> >  obj-$(CONFIG_SENSORS_LTC4261)  += ltc4261.o
> >  obj-$(CONFIG_SENSORS_LTQ_CPUTEMP) += ltq-cputemp.o
> >  obj-$(CONFIG_SENSORS_MAX)  += max.o
> > +obj-$(CONFIG_SENSORS_MAX127)   += max127.o
> >  obj-$(CONFIG_SENSORS_MAX16065) += max16065.o
> >  obj-$(CONFIG_SENSORS_MAX1619)  += max1619.o
> >  obj-$(CONFIG_SENSORS_MAX1668)  += max1668.o
> > diff --git a/drivers/hwmon/max127.c b/drivers/hwmon/max127.c
> > new file mode 100644
> > index ..1c54146b6086
> > --- /dev/null
> > +++ b/drivers/hwmon/max127.c
> > @@ -0,0 +1,346 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Hardware monitoring driver for MAX127.
> > + *
> > + * Copyright (c) 2020 Facebook Inc.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +/*
> > + * MAX127 Control Byte. Refer to MAX127 datasheet, Table 1 "Control-Byte
> > + * Format" for details.
> > + */
> > +#define MAX127_CTRL_START  BIT(7)
> > +#define MAX127_CTRL_SEL_SHIFT  4
> > +#define MAX127_CTRL_RNGBIT(3)
> > +#define MAX127_CTRL_BIPBIT(2)
> > +#define MAX127_CTRL_PD1BIT(1)
> > +#define MAX127_CTRL_PD0BIT(0)
> > +
> > +#define MAX127_NUM_CHANNELS8
> > +#define MAX127_SET_CHANNEL(ch) (((ch) & 7) << MAX127_CTRL_SEL_SHIFT)
> > +
> > +/*
> > + * MAX127 channel input ranges. Refer to MAX127 datasheet, Table 3 "Range
> > + * and Polarity Selection" for details.
> > + */
> > +#define MAX127_FULL_RANGE  1   /* 10V */
> > +#define MAX127_HALF_RANGE  5000/* 5V */
> > +
> > +/*
> > + * MAX127 returns 2 bytes at read:
> > + *   - the first byte contains data[11:4].
> > + *   - the second byte contains data[3:0] (MSB) and 4 dummy 0s (LSB).
> > + * Refer to MAX127 datasheet, "Read a Conversion (Read Cycle)" section
> > + * for details.
> > + */
> > +#define MAX127_DATA_LEN2
> > +#define MAX127_DATA_SHIFT  4
> > +
> > +#define MAX127_SIGN_BITBIT(11)
> > +
> > +struct max127_data {
> > +   struct mutex lock;
> > +   struct i2c_client *client;
> > +   u8 ctrl_byte[MAX127_NUM_CHANNELS];
> > +};
> > +
> > +static int max127_select_channel(struct i2c_client *client, u8 ctrl_byte)
> > +{
> > +   int status;
> > +   struct i2c_msg msg = {
> > +   .addr = client->addr,
> > +   .flags = 0,
> > +   .len = sizeof(ctrl_byte),
> > +   .buf = &ctrl_byte,
> > +   };
> > +
> > +   status = i2c_transfer(client->adapter, &msg, 1);
> > +
> > +   return (status == 1) ? 0 : -EIO;
> 
> This isn't what I said and asked for. It drops the unnecessary else,
> but now it overwrites an error value.
> 
> Guenter
> 
> 

Re: [PATCH v4 1/2] hwmon: (max127) Add Maxim MAX127 hardware monitoring driver

2020-11-23 Thread Guenter Roeck
On Sun, Nov 22, 2020 at 11:45:31PM -0800, rentao.b...@gmail.com wrote:
> From: Tao Ren 
> 
> Add hardware monitoring driver for the Maxim MAX127 chip.
> 
> MAX127 min/max range handling code is inspired by the max197 driver.
> 
> Signed-off-by: Tao Ren 
> ---
>  Changes in v4:
>- delete unnecessary "#include" lines.
>- simplify i2c_transfer() error handling.
>- add mutex to protect ctrl_byte in write_min|max() functions.
>  Changes in v3:
>- no code change. xdp maintainers were removed from to/cc list.
>  Changes in v2:
>- replace devm_hwmon_device_register_with_groups() with
>  devm_hwmon_device_register_with_info() API.
>- divide min/max read and write methods to separate functions.
>- fix raw-to-vin conversion logic.
>- refine ctrl_byte handling so mutex is not needed to protect the
>  byte.
>- improve i2c_transfer() error handling.
>- a few other improvements (comments, variable naming, and etc.).
> 
>  drivers/hwmon/Kconfig  |   9 ++
>  drivers/hwmon/Makefile |   1 +
>  drivers/hwmon/max127.c | 346 +
>  3 files changed, 356 insertions(+)
>  create mode 100644 drivers/hwmon/max127.c
> 
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index 9d600e0c5584..716df51edc87 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -950,6 +950,15 @@ config SENSORS_MAX
> This driver can also be built as a module. If so, the module
> will be called max.
>  
> +config SENSORS_MAX127
> + tristate "Maxim MAX127 12-bit 8-channel Data Acquisition System"
> + depends on I2C
> + help
> +   Say y here to support Maxim's MAX127 DAS chips.
> +
> +   This driver can also be built as a module. If so, the module
> +   will be called max127.
> +
>  config SENSORS_MAX16065
>   tristate "Maxim MAX16065 System Manager and compatibles"
>   depends on I2C
> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> index 1083bbfac779..01ca5d3fbad4 100644
> --- a/drivers/hwmon/Makefile
> +++ b/drivers/hwmon/Makefile
> @@ -127,6 +127,7 @@ obj-$(CONFIG_SENSORS_LTC4260) += ltc4260.o
>  obj-$(CONFIG_SENSORS_LTC4261)+= ltc4261.o
>  obj-$(CONFIG_SENSORS_LTQ_CPUTEMP) += ltq-cputemp.o
>  obj-$(CONFIG_SENSORS_MAX)+= max.o
> +obj-$(CONFIG_SENSORS_MAX127) += max127.o
>  obj-$(CONFIG_SENSORS_MAX16065)   += max16065.o
>  obj-$(CONFIG_SENSORS_MAX1619)+= max1619.o
>  obj-$(CONFIG_SENSORS_MAX1668)+= max1668.o
> diff --git a/drivers/hwmon/max127.c b/drivers/hwmon/max127.c
> new file mode 100644
> index ..1c54146b6086
> --- /dev/null
> +++ b/drivers/hwmon/max127.c
> @@ -0,0 +1,346 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Hardware monitoring driver for MAX127.
> + *
> + * Copyright (c) 2020 Facebook Inc.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +/*
> + * MAX127 Control Byte. Refer to MAX127 datasheet, Table 1 "Control-Byte
> + * Format" for details.
> + */
> +#define MAX127_CTRL_STARTBIT(7)
> +#define MAX127_CTRL_SEL_SHIFT4
> +#define MAX127_CTRL_RNG  BIT(3)
> +#define MAX127_CTRL_BIP  BIT(2)
> +#define MAX127_CTRL_PD1  BIT(1)
> +#define MAX127_CTRL_PD0  BIT(0)
> +
> +#define MAX127_NUM_CHANNELS  8
> +#define MAX127_SET_CHANNEL(ch)   (((ch) & 7) << MAX127_CTRL_SEL_SHIFT)
> +
> +/*
> + * MAX127 channel input ranges. Refer to MAX127 datasheet, Table 3 "Range
> + * and Polarity Selection" for details.
> + */
> +#define MAX127_FULL_RANGE1   /* 10V */
> +#define MAX127_HALF_RANGE5000/* 5V */
> +
> +/*
> + * MAX127 returns 2 bytes at read:
> + *   - the first byte contains data[11:4].
> + *   - the second byte contains data[3:0] (MSB) and 4 dummy 0s (LSB).
> + * Refer to MAX127 datasheet, "Read a Conversion (Read Cycle)" section
> + * for details.
> + */
> +#define MAX127_DATA_LEN  2
> +#define MAX127_DATA_SHIFT4
> +
> +#define MAX127_SIGN_BIT  BIT(11)
> +
> +struct max127_data {
> + struct mutex lock;
> + struct i2c_client *client;
> + u8 ctrl_byte[MAX127_NUM_CHANNELS];
> +};
> +
> +static int max127_select_channel(struct i2c_client *client, u8 ctrl_byte)
> +{
> + int status;
> + struct i2c_msg msg = {
> + .addr = client->addr,
> + .flags = 0,
> + .len = sizeof(ctrl_byte),
> + .buf = &ctrl_byte,
> + };
> +
> + status = i2c_transfer(client->adapter, &msg, 1);
> +
> + return (status == 1) ? 0 : -EIO;

This isn't what I said and asked for. It drops the unnecessary else,
but now it overwrites an error value.

Guenter

> +}
> +
> +static int max127_read_channel(struct i2c_client *client, long *val)
> +{
> + int status;
> + u8 i2c_data[MAX127_DATA_LEN];
> + struct i2c_msg msg = {
> + .addr = client->addr,
> + .flags = I2C_M_RD,
> + .len = sizeof

[PATCH v4 1/2] hwmon: (max127) Add Maxim MAX127 hardware monitoring driver

2020-11-22 Thread rentao . bupt
From: Tao Ren 

Add hardware monitoring driver for the Maxim MAX127 chip.

MAX127 min/max range handling code is inspired by the max197 driver.

Signed-off-by: Tao Ren 
---
 Changes in v4:
   - delete unnecessary "#include" lines.
   - simplify i2c_transfer() error handling.
   - add mutex to protect ctrl_byte in write_min|max() functions.
 Changes in v3:
   - no code change. xdp maintainers were removed from to/cc list.
 Changes in v2:
   - replace devm_hwmon_device_register_with_groups() with
 devm_hwmon_device_register_with_info() API.
   - divide min/max read and write methods to separate functions.
   - fix raw-to-vin conversion logic.
   - refine ctrl_byte handling so mutex is not needed to protect the
 byte.
   - improve i2c_transfer() error handling.
   - a few other improvements (comments, variable naming, and etc.).

 drivers/hwmon/Kconfig  |   9 ++
 drivers/hwmon/Makefile |   1 +
 drivers/hwmon/max127.c | 346 +
 3 files changed, 356 insertions(+)
 create mode 100644 drivers/hwmon/max127.c

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 9d600e0c5584..716df51edc87 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -950,6 +950,15 @@ config SENSORS_MAX
  This driver can also be built as a module. If so, the module
  will be called max.
 
+config SENSORS_MAX127
+   tristate "Maxim MAX127 12-bit 8-channel Data Acquisition System"
+   depends on I2C
+   help
+ Say y here to support Maxim's MAX127 DAS chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called max127.
+
 config SENSORS_MAX16065
tristate "Maxim MAX16065 System Manager and compatibles"
depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 1083bbfac779..01ca5d3fbad4 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -127,6 +127,7 @@ obj-$(CONFIG_SENSORS_LTC4260)   += ltc4260.o
 obj-$(CONFIG_SENSORS_LTC4261)  += ltc4261.o
 obj-$(CONFIG_SENSORS_LTQ_CPUTEMP) += ltq-cputemp.o
 obj-$(CONFIG_SENSORS_MAX)  += max.o
+obj-$(CONFIG_SENSORS_MAX127)   += max127.o
 obj-$(CONFIG_SENSORS_MAX16065) += max16065.o
 obj-$(CONFIG_SENSORS_MAX1619)  += max1619.o
 obj-$(CONFIG_SENSORS_MAX1668)  += max1668.o
diff --git a/drivers/hwmon/max127.c b/drivers/hwmon/max127.c
new file mode 100644
index ..1c54146b6086
--- /dev/null
+++ b/drivers/hwmon/max127.c
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Hardware monitoring driver for MAX127.
+ *
+ * Copyright (c) 2020 Facebook Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * MAX127 Control Byte. Refer to MAX127 datasheet, Table 1 "Control-Byte
+ * Format" for details.
+ */
+#define MAX127_CTRL_START  BIT(7)
+#define MAX127_CTRL_SEL_SHIFT  4
+#define MAX127_CTRL_RNGBIT(3)
+#define MAX127_CTRL_BIPBIT(2)
+#define MAX127_CTRL_PD1BIT(1)
+#define MAX127_CTRL_PD0BIT(0)
+
+#define MAX127_NUM_CHANNELS8
+#define MAX127_SET_CHANNEL(ch) (((ch) & 7) << MAX127_CTRL_SEL_SHIFT)
+
+/*
+ * MAX127 channel input ranges. Refer to MAX127 datasheet, Table 3 "Range
+ * and Polarity Selection" for details.
+ */
+#define MAX127_FULL_RANGE  1   /* 10V */
+#define MAX127_HALF_RANGE  5000/* 5V */
+
+/*
+ * MAX127 returns 2 bytes at read:
+ *   - the first byte contains data[11:4].
+ *   - the second byte contains data[3:0] (MSB) and 4 dummy 0s (LSB).
+ * Refer to MAX127 datasheet, "Read a Conversion (Read Cycle)" section
+ * for details.
+ */
+#define MAX127_DATA_LEN2
+#define MAX127_DATA_SHIFT  4
+
+#define MAX127_SIGN_BITBIT(11)
+
+struct max127_data {
+   struct mutex lock;
+   struct i2c_client *client;
+   u8 ctrl_byte[MAX127_NUM_CHANNELS];
+};
+
+static int max127_select_channel(struct i2c_client *client, u8 ctrl_byte)
+{
+   int status;
+   struct i2c_msg msg = {
+   .addr = client->addr,
+   .flags = 0,
+   .len = sizeof(ctrl_byte),
+   .buf = &ctrl_byte,
+   };
+
+   status = i2c_transfer(client->adapter, &msg, 1);
+
+   return (status == 1) ? 0 : -EIO;
+}
+
+static int max127_read_channel(struct i2c_client *client, long *val)
+{
+   int status;
+   u8 i2c_data[MAX127_DATA_LEN];
+   struct i2c_msg msg = {
+   .addr = client->addr,
+   .flags = I2C_M_RD,
+   .len = sizeof(i2c_data),
+   .buf = i2c_data,
+   };
+
+   status = i2c_transfer(client->adapter, &msg, 1);
+   if (status != 1)
+   return -EIO;
+
+   *val = (i2c_data[1] >> MAX127_DATA_SHIFT) |
+   ((u16)i2c_data[0] << MAX127_DATA_SHIFT);
+   return 0;
+}
+
+static long max127_process_raw(u8 ctrl_byte, long raw)
+{
+   long scale, weight;
+
+   /*
+* MAX127's data coding