[PATCH 2/8] mfd: Add support for Azoteq IQS620A/621/622/624/625

2019-10-20 Thread Jeff LaBundy
This patch adds support for core functions common to all six-channel
members of the Azoteq ProxFusion family of sensor devices.

Signed-off-by: Jeff LaBundy 
---
 drivers/mfd/Kconfig |  13 +
 drivers/mfd/Makefile|   2 +
 drivers/mfd/iqs62x-core.c   | 638 
 drivers/mfd/iqs62x-tables.c | 424 +
 include/linux/mfd/iqs62x.h  | 148 ++
 5 files changed, 1225 insertions(+)
 create mode 100644 drivers/mfd/iqs62x-core.c
 create mode 100644 drivers/mfd/iqs62x-tables.c
 create mode 100644 include/linux/mfd/iqs62x.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ae24d3e..df391f7 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -642,6 +642,19 @@ config MFD_IPAQ_MICRO
  AT90LS8535 microcontroller flashed with a special iPAQ
  firmware using the custom protocol implemented in this driver.
 
+config MFD_IQS62X
+   tristate "Azoteq IQS620A/621/622/624/625 core support"
+   depends on I2C
+   select MFD_CORE
+   select REGMAP_I2C
+   help
+ Say Y here if you want to build support for six-channel members of
+ the Azoteq ProxFusion family of sensor devices. Additional options
+ must be selected to enable device-specific functions.
+
+ To compile this driver as a module, choose M here: the module will
+ be called iqs62x.
+
 config MFD_JANZ_CMODIO
tristate "Janz CMOD-IO PCI MODULbus Carrier Board"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index c1067ea..23dd71c6 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -256,3 +256,5 @@ obj-$(CONFIG_MFD_ROHM_BD70528)  += rohm-bd70528.o
 obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o
 obj-$(CONFIG_MFD_STMFX)+= stmfx.o
 
+iqs62x-objs:= iqs62x-core.o iqs62x-tables.o
+obj-$(CONFIG_MFD_IQS62X)   += iqs62x.o
diff --git a/drivers/mfd/iqs62x-core.c b/drivers/mfd/iqs62x-core.c
new file mode 100644
index 000..e2200c8
--- /dev/null
+++ b/drivers/mfd/iqs62x-core.c
@@ -0,0 +1,638 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Azoteq IQS620A/621/622/624/625 ProxFusion Sensor Family
+ *
+ * Copyright (C) 2019
+ * Author: Jeff LaBundy 
+ *
+ * These devices rely on application-specific register settings and calibration
+ * data developed in and exported from a suite of GUIs offered by the vendor. A
+ * separate tool converts the GUIs' ASCII-based output into a standard firmware
+ * file parsed by the driver.
+ *
+ * Link to data sheets and GUIs: https://www.azoteq.com/products/proxfusion/
+ *
+ * Link to conversion tool: https://github.com/jlabundy/iqs62x-h2bin.git
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#define IQS62X_PROD_NUM0x00
+
+#define IQS62X_SYS_FLAGS   0x10
+#define IQS62X_SYS_FLAGS_IN_ATIBIT(2)
+
+#define IQS622_PROX_SETTINGS_4 0x48
+#define IQS620_PROX_SETTINGS_4 0x50
+#define IQS620_PROX_SETTINGS_4_SAR_EN  BIT(7)
+
+#define IQS62X_SYS_SETTINGS0xD0
+#define IQS62X_SYS_SETTINGS_SOFT_RESET BIT(7)
+#define IQS62X_SYS_SETTINGS_ACK_RESET  BIT(6)
+#define IQS62X_SYS_SETTINGS_EVENT_MODE BIT(5)
+#define IQS62X_SYS_SETTINGS_REDO_ATI   BIT(1)
+
+#define IQS62X_PWR_SETTINGS0xD2
+#define IQS62X_PWR_SETTINGS_DIS_AUTO   BIT(5)
+#define IQS62X_PWR_SETTINGS_PWR_MODE_MASK  (BIT(4) | BIT(3))
+#define IQS62X_PWR_SETTINGS_PWR_MODE_HALT  (BIT(4) | BIT(3))
+#define IQS62X_PWR_SETTINGS_PWR_MODE_NORM  0
+
+#define IQS62X_OTP_CMD 0xF0
+#define IQS62X_OTP_CMD_FG3 0x13
+#define IQS62X_OTP_DATA0xF1
+#define IQS62X_MAX_REG 0xFF
+
+#define IQS62X_HALL_CAL_MASK   0x0F
+
+#define IQS62X_ATI_TIMEOUT 10
+
+#define IQS62X_FW_REC_TYPE_INFO0
+#define IQS62X_FW_REC_TYPE_PROD1
+#define IQS62X_FW_REC_TYPE_HALL2
+#define IQS62X_FW_REC_TYPE_MASK3
+#define IQS62X_FW_REC_TYPE_DATA4
+
+struct iqs62x_fw_rec {
+   u8 type;
+   u8 addr;
+   u8 len;
+   u8 data;
+} __packed;
+
+struct iqs62x_fw_blk {
+   struct list_head list;
+   u8 addr;
+   u8 mask;
+   u8 len;
+   u8 data[];
+};
+
+struct iqs62x_info {
+   u8 prod_num;
+   u8 sw_num;
+   u8 hw_num;
+} __packed;
+
+static int iqs62x_dev_init(struct iqs62x_core *iqs62x)
+{
+   struct iqs62x_fw_blk *fw_blk;
+   unsigned int val;
+   int error, i;
+
+   list_for_each_entry(fw_blk, >fw_blk_head, list) {
+   

[PATCH 5/8] pwm: Add support for Azoteq IQS620A PWM generator

2019-10-20 Thread Jeff LaBundy
This patch adds support for the Azoteq IQS620A, capable of generating
a 1-kHz PWM output with duty cycle between 0.4% and 100% (inclusive).

Signed-off-by: Jeff LaBundy 
---
 drivers/pwm/Kconfig   |  10 +++
 drivers/pwm/Makefile  |   1 +
 drivers/pwm/pwm-iqs620a.c | 167 ++
 3 files changed, 178 insertions(+)
 create mode 100644 drivers/pwm/pwm-iqs620a.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index e3a2518..712445e 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -222,6 +222,16 @@ config PWM_IMX_TPM
  To compile this driver as a module, choose M here: the module
  will be called pwm-imx-tpm.
 
+config PWM_IQS620A
+   tristate "Azoteq IQS620A PWM support"
+   depends on MFD_IQS62X
+   help
+ Generic PWM framework driver for the Azoteq IQS620A multi-function
+ sensor.
+
+ To compile this driver as a module, choose M here: the module will
+ be called pwm-iqs620a.
+
 config PWM_JZ4740
tristate "Ingenic JZ47xx PWM support"
depends on MACH_INGENIC
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 26326ad..27c9bfa 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_PWM_IMG) += pwm-img.o
 obj-$(CONFIG_PWM_IMX1) += pwm-imx1.o
 obj-$(CONFIG_PWM_IMX27)+= pwm-imx27.o
 obj-$(CONFIG_PWM_IMX_TPM)  += pwm-imx-tpm.o
+obj-$(CONFIG_PWM_IQS620A)  += pwm-iqs620a.o
 obj-$(CONFIG_PWM_JZ4740)   += pwm-jz4740.o
 obj-$(CONFIG_PWM_LP3943)   += pwm-lp3943.o
 obj-$(CONFIG_PWM_LPC18XX_SCT)  += pwm-lpc18xx-sct.o
diff --git a/drivers/pwm/pwm-iqs620a.c b/drivers/pwm/pwm-iqs620a.c
new file mode 100644
index 000..6451eb1
--- /dev/null
+++ b/drivers/pwm/pwm-iqs620a.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Azoteq IQS620A PWM Generator
+ *
+ * Copyright (C) 2019
+ * Author: Jeff LaBundy 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define IQS620_PWR_SETTINGS0xD2
+#define IQS620_PWR_SETTINGS_PWM_OUTBIT(7)
+
+#define IQS620_PWM_DUTY_CYCLE  0xD8
+
+#define IQS620_PWM_PERIOD_NS   100
+
+struct iqs620_pwm_private {
+   struct iqs62x_core *iqs62x;
+   struct pwm_chip chip;
+   struct notifier_block notifier;
+   bool ready;
+};
+
+static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+   struct pwm_state *state)
+{
+   struct iqs620_pwm_private *iqs620_pwm;
+   struct iqs62x_core *iqs62x;
+   int error;
+   int duty_calc = state->duty_cycle * 256 / IQS620_PWM_PERIOD_NS - 1;
+   u8 duty_clamp = clamp(duty_calc, 0, 0xFF);
+
+   iqs620_pwm = container_of(chip, struct iqs620_pwm_private, chip);
+   iqs62x = iqs620_pwm->iqs62x;
+
+   error = regmap_write(iqs62x->map, IQS620_PWM_DUTY_CYCLE, duty_clamp);
+   if (error)
+   return error;
+
+   state->period = IQS620_PWM_PERIOD_NS;
+   state->duty_cycle = (duty_clamp + 1) * IQS620_PWM_PERIOD_NS / 256;
+
+   return regmap_update_bits(iqs62x->map, IQS620_PWR_SETTINGS,
+ IQS620_PWR_SETTINGS_PWM_OUT,
+ state->enabled ? 0xFF : 0);
+}
+
+static int iqs620_pwm_notifier(struct notifier_block *notifier,
+  unsigned long event_flags, void *context)
+{
+   struct iqs620_pwm_private *iqs620_pwm;
+   struct pwm_state state;
+   int error;
+
+   iqs620_pwm = container_of(notifier, struct iqs620_pwm_private,
+ notifier);
+
+   if (!iqs620_pwm->ready || !(event_flags & BIT(IQS62X_EVENT_SYS_RESET)))
+   return NOTIFY_DONE;
+
+   pwm_get_state(_pwm->chip.pwms[0], );
+
+   error = iqs620_pwm_apply(_pwm->chip,
+_pwm->chip.pwms[0], );
+   if (error) {
+   dev_err(iqs620_pwm->chip.dev,
+   "Failed to re-initialize device: %d\n", error);
+   return NOTIFY_BAD;
+   }
+
+   return NOTIFY_OK;
+}
+
+static void iqs620_pwm_notifier_unregister(void *context)
+{
+   struct iqs620_pwm_private *iqs620_pwm = context;
+   int error;
+
+   error = blocking_notifier_chain_unregister(_pwm->iqs62x->nh,
+  _pwm->notifier);
+   if (error)
+   dev_err(iqs620_pwm->chip.dev,
+   "Failed to unregister notifier: %d\n", error);
+}
+
+static const struct pwm_ops iqs620_pwm_ops = {
+   .apply  = iqs620_pwm_apply,
+   .owner  = THIS_MODULE,
+};
+
+static int iqs620_pwm_probe(struct platform_device *pdev)
+{
+   struct iqs620_pwm_private *iqs620_pwm;
+   int error;
+
+   iqs620_pwm = devm_kzalloc(>dev, sizeof(*iqs620_pwm), GFP_KERNEL);
+   if (!iqs620_pwm)
+   

[PATCH 0/8] Add support for Azoteq IQS620A/621/622/624/625

2019-10-20 Thread Jeff LaBundy
This series adds support for six-channel members of the Azoteq ProxFusion
family of sensor devices: IQS620A, IQS621, IQS622, IQS624 and IQS625. Each
device integrates multiple sensor technologies in a single package.

A multi-function device (MFD) driver supports core functions common to all
devices, including device identification, firmware, interrupt handling and
runtime power management. The MFD driver is also responsible for adding all
product-specific sub-devices.

Each device supports self-capacitive, Hall-effect, and (in some cases) mutual-
inductive sensing. These functions represent keys or switches and are supported
by an input driver that covers all five devices. An assortment of pwm, hwmon
and iio drivers support device-specific functions.

This series was tested using the following development hardware: IQS620AEV04,
IQS621EV04, IQS622EV04 and IQS624/5EV04.

Jeff LaBundy (8):
  dt-bindings: mfd: iqs62x: Add bindings
  mfd: Add support for Azoteq IQS620A/621/622/624/625
  input: keyboard: Add support for Azoteq IQS620A/621/622/624/625
  hwmon: Add support for Azoteq IQS620AT temperature sensor
  pwm: Add support for Azoteq IQS620A PWM generator
  iio: light: Add support for Azoteq IQS621 ambient light sensor
  iio: proximity: Add support for Azoteq IQS622 proximity sensor
  iio: position: Add support for Azoteq IQS624/625 angle sensor

 Documentation/devicetree/bindings/mfd/iqs62x.txt | 242 +
 drivers/hwmon/Kconfig|  12 +-
 drivers/hwmon/Makefile   |   1 +
 drivers/hwmon/iqs620at-temp.c|  96 
 drivers/iio/Kconfig  |   1 +
 drivers/iio/Makefile |   1 +
 drivers/iio/light/Kconfig|  10 +
 drivers/iio/light/Makefile   |   1 +
 drivers/iio/light/iqs621-als.c   | 361 +
 drivers/iio/position/Kconfig |  19 +
 drivers/iio/position/Makefile|   7 +
 drivers/iio/position/iqs624-pos.c| 302 +++
 drivers/iio/proximity/Kconfig|  10 +
 drivers/iio/proximity/Makefile   |   1 +
 drivers/iio/proximity/iqs622-prox.c  | 334 
 drivers/input/keyboard/Kconfig   |  10 +
 drivers/input/keyboard/Makefile  |   1 +
 drivers/input/keyboard/iqs62x-keys.c | 340 
 drivers/mfd/Kconfig  |  13 +
 drivers/mfd/Makefile |   2 +
 drivers/mfd/iqs62x-core.c| 638 +++
 drivers/mfd/iqs62x-tables.c  | 424 +++
 drivers/pwm/Kconfig  |  10 +
 drivers/pwm/Makefile |   1 +
 drivers/pwm/pwm-iqs620a.c| 167 ++
 include/linux/mfd/iqs62x.h   | 148 ++
 26 files changed, 3151 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/iqs62x.txt
 create mode 100644 drivers/hwmon/iqs620at-temp.c
 create mode 100644 drivers/iio/light/iqs621-als.c
 create mode 100644 drivers/iio/position/Kconfig
 create mode 100644 drivers/iio/position/Makefile
 create mode 100644 drivers/iio/position/iqs624-pos.c
 create mode 100644 drivers/iio/proximity/iqs622-prox.c
 create mode 100644 drivers/input/keyboard/iqs62x-keys.c
 create mode 100644 drivers/mfd/iqs62x-core.c
 create mode 100644 drivers/mfd/iqs62x-tables.c
 create mode 100644 drivers/pwm/pwm-iqs620a.c
 create mode 100644 include/linux/mfd/iqs62x.h

--
2.7.4



[PATCH 7/8] iio: proximity: Add support for Azoteq IQS622 proximity sensor

2019-10-20 Thread Jeff LaBundy
This patch adds support for the Azoteq IQS622 proximity sensor,
capable of reporting a unitless measurement of a target's prox-
imity to the sensor.

Signed-off-by: Jeff LaBundy 
---
 drivers/iio/proximity/Kconfig   |  10 ++
 drivers/iio/proximity/Makefile  |   1 +
 drivers/iio/proximity/iqs622-prox.c | 334 
 3 files changed, 345 insertions(+)
 create mode 100644 drivers/iio/proximity/iqs622-prox.c

diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig
index d536014..2366fd7 100644
--- a/drivers/iio/proximity/Kconfig
+++ b/drivers/iio/proximity/Kconfig
@@ -21,6 +21,16 @@ endmenu
 
 menu "Proximity and distance sensors"
 
+config IQS622_PROX
+   tristate "Azoteq IQS622 proximity sensor"
+   depends on MFD_IQS62X
+   help
+ Say Y here if you want to build support for the Azoteq IQS622
+ proximity sensor.
+
+ To compile this driver as a module, choose M here: the module
+ will be called iqs622-prox.
+
 config ISL29501
tristate "Intersil ISL29501 Time Of Flight sensor"
depends on I2C
diff --git a/drivers/iio/proximity/Makefile b/drivers/iio/proximity/Makefile
index 0bb5f9d..802ba9d 100644
--- a/drivers/iio/proximity/Makefile
+++ b/drivers/iio/proximity/Makefile
@@ -5,6 +5,7 @@
 
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_AS3935)   += as3935.o
+obj-$(CONFIG_IQS622_PROX)  += iqs622-prox.o
 obj-$(CONFIG_ISL29501) += isl29501.o
 obj-$(CONFIG_LIDAR_LITE_V2)+= pulsedlight-lidar-lite-v2.o
 obj-$(CONFIG_MB1232)   += mb1232.o
diff --git a/drivers/iio/proximity/iqs622-prox.c 
b/drivers/iio/proximity/iqs622-prox.c
new file mode 100644
index 000..a805fb21
--- /dev/null
+++ b/drivers/iio/proximity/iqs622-prox.c
@@ -0,0 +1,334 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Azoteq IQS622 Proximity Sensor
+ *
+ * Copyright (C) 2019
+ * Author: Jeff LaBundy 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define IQS622_IR_FLAGS0x16
+#define IQS622_IR_FLAGS_TOUCH  BIT(1)
+#define IQS622_IR_FLAGS_PROX   BIT(0)
+
+#define IQS622_IR_UI_OUT   0x17
+
+#define IQS622_IR_THRESH_PROX  0x91
+#define IQS622_IR_THRESH_PROX_MAX  255
+#define IQS622_IR_THRESH_PROX_SHIFT0
+
+#define IQS622_IR_THRESH_TOUCH 0x92
+#define IQS622_IR_THRESH_TOUCH_MAX 1020
+#define IQS622_IR_THRESH_TOUCH_SHIFT   2
+
+struct iqs622_prox_private {
+   struct iqs62x_core *iqs62x;
+   struct notifier_block notifier;
+   struct mutex lock;
+   bool thresh_prox;
+   bool event_en;
+   u8 thresh;
+   u8 flags;
+};
+
+static int iqs622_prox_init(struct iqs622_prox_private *iqs622_prox)
+{
+   struct iqs62x_core *iqs62x = iqs622_prox->iqs62x;
+   unsigned int val;
+   int error;
+
+   mutex_lock(_prox->lock);
+
+   error = regmap_write(iqs62x->map,
+iqs622_prox->thresh_prox ? IQS622_IR_THRESH_PROX :
+   IQS622_IR_THRESH_TOUCH,
+iqs622_prox->thresh);
+   if (error)
+   goto err_mutex;
+
+   error = regmap_read(iqs62x->map, IQS622_IR_FLAGS, );
+   if (error)
+   goto err_mutex;
+   iqs622_prox->flags = val;
+
+   error = regmap_update_bits(iqs62x->map, IQS620_GLBL_EVENT_MASK,
+  iqs62x->dev_desc->ir_mask,
+  iqs622_prox->event_en ? 0 : 0xFF);
+
+err_mutex:
+   mutex_unlock(_prox->lock);
+
+   return error;
+}
+
+static int iqs622_prox_notifier(struct notifier_block *notifier,
+   unsigned long event_flags, void *context)
+{
+   struct iqs62x_event_data *event_data = context;
+   struct iqs622_prox_private *iqs622_prox;
+   struct iio_dev *indio_dev;
+   enum iio_event_direction dir;
+   int error;
+   u8 flags_mask;
+
+   iqs622_prox = container_of(notifier, struct iqs622_prox_private,
+  notifier);
+   indio_dev = iio_priv_to_dev(iqs622_prox);
+
+   if (event_flags & BIT(IQS62X_EVENT_SYS_RESET)) {
+   error = iqs622_prox_init(iqs622_prox);
+   if (error) {
+   dev_err(indio_dev->dev.parent,
+   "Failed to re-initialize device: %d\n", error);
+   return NOTIFY_BAD;
+   }
+
+   return NOTIFY_OK;
+   }
+
+   flags_mask = iqs622_prox->thresh_prox ? IQS622_IR_FLAGS_PROX :
+   IQS622_IR_FLAGS_TOUCH;
+
+   if (!((event_data->ir_flags ^ iqs622_prox->flags) & flags_mask))
+   return NOTIFY_DONE;
+
+   

[PATCH 1/8] dt-bindings: mfd: iqs62x: Add bindings

2019-10-20 Thread Jeff LaBundy
This patch adds binding documentation for six-channel members of the
Azoteq ProxFusion family of sensor devices.

Signed-off-by: Jeff LaBundy 
---
 Documentation/devicetree/bindings/mfd/iqs62x.txt | 242 +++
 1 file changed, 242 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/iqs62x.txt

diff --git a/Documentation/devicetree/bindings/mfd/iqs62x.txt 
b/Documentation/devicetree/bindings/mfd/iqs62x.txt
new file mode 100644
index 000..089f567
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/iqs62x.txt
@@ -0,0 +1,242 @@
+Azoteq IQS620A/621/622/624/625 ProxFusion Sensor Family
+
+Required properties:
+
+- compatible   : Must be equal to one of the following:
+ "azoteq,iqs620a"
+ "azoteq,iqs621"
+ "azoteq,iqs622"
+ "azoteq,iqs624"
+ "azoteq,iqs625"
+
+- reg  : I2C slave address for the device.
+
+- interrupts   : GPIO to which the device's active-low RDY
+ output is connected (see [0]).
+
+Optional properties:
+
+- linux,fw-file: Specifies the name of the calibration 
and
+ configuration file selected by the driver.
+ If this property is omitted, the filename
+ is selected based on the device name with
+ ".bin" as the extension (e.g. iqs620a.bin
+ for IQS620A).
+
+All devices accommodate a child node (e.g. "keys") that represents touch key
+support. Required properties for the "keys" child node include:
+
+- compatible   : Must be equal to one of the following:
+ "azoteq,iqs620a-keys"
+ "azoteq,iqs621-keys"
+ "azoteq,iqs622-keys"
+ "azoteq,iqs624-keys"
+ "azoteq,iqs625-keys"
+
+- linux,keycodes   : Specifies an array of up to 16 numeric key-
+ codes corresponding to each available touch
+ or proximity event. An 'x' in the following
+ table indicates an event is supported for a
+ given device; specify 0 for unused events.
+
+  
+  | #  | Event | IQS620A | IQS621 | IQS622 | IQS624 | IQS625 |
+  
+  | 0  | CH0 Touch |x|x   |x   |x   |x   |
+  || Antenna 1 Touch*  |x|||||
+  
+  | 1  | CH0 Proximity |x|x   |x   |x   |x   |
+  || Antenna 1 Proximity*  |x|||||
+  
+  | 2  | CH1 Touch |x|x   |x   |x   |x   |
+  || Antenna 1 Deep Touch* |x|||||
+  
+  | 3  | CH1 Proximity |x|x   |x   |x   |x   |
+  
+  | 4  | CH2 Touch |x|||||
+  
+  | 5  | CH2 Proximity |x|||||
+  || Antenna 2 Proximity*  |x|||||
+  
+  | 6  | Metal (+) Touch** |x|x   ||||
+  || Antenna 2 Deep Touch* |x|||||
+  
+  | 7  | Metal (+) Proximity** |x|x   ||||
+  || Antenna 2 Touch*  |x|||||
+  
+  | 8  | Metal (-) Touch** |x|x   ||||
+  
+  | 9  | Metal (-) Proximity** |x|x   ||||
+  
+  | 10 | SAR Active*** |x||x   |||
+  

[PATCH 8/8] iio: position: Add support for Azoteq IQS624/625 angle sensor

2019-10-20 Thread Jeff LaBundy
This patch adds support for the Azoteq IQS624 and IQS625 angular position
sensors, capable of reporting the angle of a rotating shaft down to 1 and
10 degrees of accuracy, respectively.

This patch also introduces a home for linear and angular position sensors.
Unlike resolvers, they are typically contactless and use the Hall effect.

Signed-off-by: Jeff LaBundy 
---
 drivers/iio/Kconfig   |   1 +
 drivers/iio/Makefile  |   1 +
 drivers/iio/position/Kconfig  |  19 +++
 drivers/iio/position/Makefile |   7 +
 drivers/iio/position/iqs624-pos.c | 302 ++
 5 files changed, 330 insertions(+)
 create mode 100644 drivers/iio/position/Kconfig
 create mode 100644 drivers/iio/position/Makefile
 create mode 100644 drivers/iio/position/iqs624-pos.c

diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
index 5bd5185..d5c073a 100644
--- a/drivers/iio/Kconfig
+++ b/drivers/iio/Kconfig
@@ -88,6 +88,7 @@ source "drivers/iio/orientation/Kconfig"
 if IIO_TRIGGER
source "drivers/iio/trigger/Kconfig"
 endif #IIO_TRIGGER
+source "drivers/iio/position/Kconfig"
 source "drivers/iio/potentiometer/Kconfig"
 source "drivers/iio/potentiostat/Kconfig"
 source "drivers/iio/pressure/Kconfig"
diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
index bff682a..1712011 100644
--- a/drivers/iio/Makefile
+++ b/drivers/iio/Makefile
@@ -31,6 +31,7 @@ obj-y += light/
 obj-y += magnetometer/
 obj-y += multiplexer/
 obj-y += orientation/
+obj-y += position/
 obj-y += potentiometer/
 obj-y += potentiostat/
 obj-y += pressure/
diff --git a/drivers/iio/position/Kconfig b/drivers/iio/position/Kconfig
new file mode 100644
index 000..ed9f975
--- /dev/null
+++ b/drivers/iio/position/Kconfig
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Linear and angular position sensors
+#
+# When adding new entries keep the list in alphabetical order
+
+menu "Linear and angular position sensors"
+
+config IQS624_POS
+   tristate "Azoteq IQS624/625 angular position sensor"
+   depends on MFD_IQS62X
+   help
+ Say Y here if you want to build support for the Azoteq IQS624
+ and IQS625 angular position sensors.
+
+ To compile this driver as a module, choose M here: the module
+ will be called iqs624-pos.
+
+endmenu
diff --git a/drivers/iio/position/Makefile b/drivers/iio/position/Makefile
new file mode 100644
index 000..3cbe7a7
--- /dev/null
+++ b/drivers/iio/position/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for IIO linear and angular position sensors
+#
+
+# When adding new entries keep the list in alphabetical order
+
+obj-$(CONFIG_IQS624_POS)   += iqs624-pos.o
diff --git a/drivers/iio/position/iqs624-pos.c 
b/drivers/iio/position/iqs624-pos.c
new file mode 100644
index 000..d975065
--- /dev/null
+++ b/drivers/iio/position/iqs624-pos.c
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Azoteq IQS624/625 Angular Position Sensor
+ *
+ * Copyright (C) 2019
+ * Author: Jeff LaBundy 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define IQS624_POS_DEG_OUT 0x16
+
+#define IQS624_POS_SCALE1  (314159 / 180)
+#define IQS624_POS_SCALE2  10
+
+struct iqs624_pos_private {
+   struct iqs62x_core *iqs62x;
+   struct notifier_block notifier;
+   struct mutex lock;
+   bool event_en;
+   union {
+   u16 angle;
+   u8 interval;
+   };
+};
+
+static int iqs624_pos_init(struct iqs624_pos_private *iqs624_pos)
+{
+   struct iqs62x_core *iqs62x = iqs624_pos->iqs62x;
+   unsigned int val;
+   int error;
+   __le16 val_buf;
+
+   if (iqs62x->dev_desc->prod_num == IQS624_PROD_NUM) {
+   error = regmap_raw_read(iqs62x->map, IQS624_POS_DEG_OUT,
+   _buf, sizeof(val_buf));
+   if (error)
+   return error;
+
+   iqs624_pos->angle = le16_to_cpu(val_buf);
+   } else {
+   error = regmap_read(iqs62x->map, iqs62x->dev_desc->interval,
+   );
+   if (error)
+   return error;
+
+   iqs624_pos->interval = val;
+   }
+
+   mutex_lock(_pos->lock);
+
+   /*
+* The IQS625 reports angular position in the form of coarse intervals,
+* so only interval change events are unmasked. Conversely, the IQS624
+* reports angular position down to one degree of resolution, so wheel
+* movement events are unmasked instead.
+*/
+   error = regmap_update_bits(iqs62x->map, IQS624_HALL_UI,
+  iqs62x->dev_desc->prod_num ==
+  IQS624_PROD_NUM ? IQS624_HALL_UI_WHL_EVENT :
+IQS624_HALL_UI_INT_EVENT,
+  

[PATCH 6/8] iio: light: Add support for Azoteq IQS621 ambient light sensor

2019-10-20 Thread Jeff LaBundy
This patch adds support for the Azoteq IQS621 ambient light sensor,
capable of reporting intensity directly in units of lux.

Signed-off-by: Jeff LaBundy 
---
 drivers/iio/light/Kconfig  |  10 ++
 drivers/iio/light/Makefile |   1 +
 drivers/iio/light/iqs621-als.c | 361 +
 3 files changed, 372 insertions(+)
 create mode 100644 drivers/iio/light/iqs621-als.c

diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index 4a1a883..aad26dc 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -162,6 +162,16 @@ config GP2AP020A00F
  To compile this driver as a module, choose M here: the
  module will be called gp2ap020a00f.
 
+config IQS621_ALS
+   tristate "Azoteq IQS621 ambient light sensor"
+   depends on MFD_IQS62X
+   help
+ Say Y here if you want to build support for the Azoteq IQS621
+ ambient light sensor.
+
+ To compile this driver as a module, choose M here: the module
+ will be called iqs621-als.
+
 config SENSORS_ISL29018
tristate "Intersil 29018 light and proximity sensor"
depends on I2C
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index 00d1f9b..aa34358 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_IIO_CROS_EC_LIGHT_PROX) += cros_ec_light_prox.o
 obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o
 obj-$(CONFIG_HID_SENSOR_ALS)   += hid-sensor-als.o
 obj-$(CONFIG_HID_SENSOR_PROX)  += hid-sensor-prox.o
+obj-$(CONFIG_IQS621_ALS)   += iqs621-als.o
 obj-$(CONFIG_SENSORS_ISL29018) += isl29018.o
 obj-$(CONFIG_SENSORS_ISL29028) += isl29028.o
 obj-$(CONFIG_ISL29125) += isl29125.o
diff --git a/drivers/iio/light/iqs621-als.c b/drivers/iio/light/iqs621-als.c
new file mode 100644
index 000..92a6173
--- /dev/null
+++ b/drivers/iio/light/iqs621-als.c
@@ -0,0 +1,361 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Azoteq IQS621 Ambient Light Sensor
+ *
+ * Copyright (C) 2019
+ * Author: Jeff LaBundy 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define IQS621_ALS_FLAGS   0x16
+#define IQS621_ALS_FLAGS_LIGHT BIT(7)
+
+#define IQS621_ALS_UI_OUT  0x17
+
+#define IQS621_ALS_THRESH_DARK 0x80
+#define IQS621_ALS_THRESH_DARK_MAX 1020
+#define IQS621_ALS_THRESH_DARK_SHIFT   2
+
+#define IQS621_ALS_THRESH_LIGHT0x81
+#define IQS621_ALS_THRESH_LIGHT_MAX4080
+#define IQS621_ALS_THRESH_LIGHT_SHIFT  4
+
+struct iqs621_als_private {
+   struct iqs62x_core *iqs62x;
+   struct notifier_block notifier;
+   struct mutex lock;
+   bool event_en;
+   u8 thresh_light;
+   u8 thresh_dark;
+   u8 flags;
+};
+
+static int iqs621_als_init(struct iqs621_als_private *iqs621_als)
+{
+   struct iqs62x_core *iqs62x = iqs621_als->iqs62x;
+   unsigned int val;
+   int error;
+
+   mutex_lock(_als->lock);
+
+   error = regmap_write(iqs62x->map, IQS621_ALS_THRESH_LIGHT,
+iqs621_als->thresh_light);
+   if (error)
+   goto err_mutex;
+
+   error = regmap_write(iqs62x->map, IQS621_ALS_THRESH_DARK,
+iqs621_als->thresh_dark);
+   if (error)
+   goto err_mutex;
+
+   error = regmap_read(iqs62x->map, IQS621_ALS_FLAGS, );
+   if (error)
+   goto err_mutex;
+   iqs621_als->flags = val;
+
+   error = regmap_update_bits(iqs62x->map, IQS620_GLBL_EVENT_MASK,
+  iqs62x->dev_desc->als_mask,
+  iqs621_als->event_en ? 0 : 0xFF);
+
+err_mutex:
+   mutex_unlock(_als->lock);
+
+   return error;
+}
+
+static int iqs621_als_notifier(struct notifier_block *notifier,
+  unsigned long event_flags, void *context)
+{
+   struct iqs62x_event_data *event_data = context;
+   struct iqs621_als_private *iqs621_als;
+   struct iio_dev *indio_dev;
+   enum iio_event_direction dir;
+   int error;
+
+   iqs621_als = container_of(notifier, struct iqs621_als_private,
+ notifier);
+   indio_dev = iio_priv_to_dev(iqs621_als);
+
+   if (event_flags & BIT(IQS62X_EVENT_SYS_RESET)) {
+   error = iqs621_als_init(iqs621_als);
+   if (error) {
+   dev_err(indio_dev->dev.parent,
+   "Failed to re-initialize device: %d\n", error);
+   return NOTIFY_BAD;
+   }
+
+   return NOTIFY_OK;
+   }
+
+   if (!((event_data->als_flags ^ iqs621_als->flags) &
+   IQS621_ALS_FLAGS_LIGHT))
+   return NOTIFY_DONE;
+
+   iqs621_als->flags = event_data->als_flags;
+
+   if 

[PATCH 3/8] input: keyboard: Add support for Azoteq IQS620A/621/622/624/625

2019-10-20 Thread Jeff LaBundy
This patch adds touch key support for six-channel members of the
Azoteq ProxFusion family of sensor devices.

Signed-off-by: Jeff LaBundy 
---
 drivers/input/keyboard/Kconfig   |  10 ++
 drivers/input/keyboard/Makefile  |   1 +
 drivers/input/keyboard/iqs62x-keys.c | 340 +++
 3 files changed, 351 insertions(+)
 create mode 100644 drivers/input/keyboard/iqs62x-keys.c

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 8911bc2..ab10aff 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -657,6 +657,16 @@ config KEYBOARD_IPAQ_MICRO
  To compile this driver as a module, choose M here: the
  module will be called ipaq-micro-keys.
 
+config KEYBOARD_IQS62X
+   tristate "Azoteq IQS620A/621/622/624/625 touch keys"
+   depends on MFD_IQS62X
+   help
+ Say Y here to enable touch-key support for six-channel members of
+ the Azoteq ProxFusion family of sensor devices.
+
+ To compile this driver as a module, choose M here: the module will
+ be called iqs62x-keys.
+
 config KEYBOARD_OMAP
tristate "TI OMAP keypad support"
depends on ARCH_OMAP1
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 9510325..ee85b7f 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_KEYBOARD_TCA8418)+= 
tca8418_keypad.o
 obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
 obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
 obj-$(CONFIG_KEYBOARD_IPAQ_MICRO)  += ipaq-micro-keys.o
+obj-$(CONFIG_KEYBOARD_IQS62X)  += iqs62x-keys.o
 obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o
 obj-$(CONFIG_KEYBOARD_HP6XX)   += jornada680_kbd.o
 obj-$(CONFIG_KEYBOARD_HP7XX)   += jornada720_kbd.o
diff --git a/drivers/input/keyboard/iqs62x-keys.c 
b/drivers/input/keyboard/iqs62x-keys.c
new file mode 100644
index 000..9d929f1
--- /dev/null
+++ b/drivers/input/keyboard/iqs62x-keys.c
@@ -0,0 +1,340 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Azoteq IQS620A/621/622/624/625 Touch Keys
+ *
+ * Copyright (C) 2019
+ * Author: Jeff LaBundy 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+enum {
+   IQS62X_SW_HALL_N,
+   IQS62X_SW_HALL_S,
+};
+
+static const char * const iqs62x_switch_names[] = {
+   [IQS62X_SW_HALL_N] = "hall_switch_north",
+   [IQS62X_SW_HALL_S] = "hall_switch_south",
+};
+
+struct iqs62x_switch_desc {
+   enum iqs62x_event_flag flag;
+   unsigned int code;
+   bool enabled;
+};
+
+struct iqs62x_keys_private {
+   struct iqs62x_core *iqs62x;
+   struct input_dev *input;
+   struct notifier_block notifier;
+   struct iqs62x_switch_desc switches[ARRAY_SIZE(iqs62x_switch_names)];
+   unsigned int keycode[IQS62X_NUM_KEYS];
+   unsigned int keycodemax;
+   u8 interval;
+};
+
+static int iqs62x_keys_parse_prop(struct platform_device *pdev,
+ struct iqs62x_keys_private *iqs62x_keys)
+{
+   struct device_node *keys_node = pdev->dev.of_node;
+   struct device_node *hall_node;
+   unsigned int val;
+   int ret, i;
+
+   if (!keys_node)
+   return 0;
+
+   ret = of_property_read_variable_u32_array(keys_node, "linux,keycodes",
+ iqs62x_keys->keycode, 0,
+ IQS62X_NUM_KEYS);
+   if (ret < 0) {
+   dev_err(>dev, "Failed to read keycodes: %d\n", ret);
+   return ret;
+   }
+   iqs62x_keys->keycodemax = ret;
+
+   for (i = 0; i < ARRAY_SIZE(iqs62x_keys->switches); i++) {
+   hall_node = of_get_child_by_name(keys_node,
+iqs62x_switch_names[i]);
+   if (!hall_node)
+   continue;
+
+   ret = of_property_read_u32(hall_node, "linux,code", );
+   if (ret < 0) {
+   dev_err(>dev, "Failed to read switch code: %d\n",
+   ret);
+   of_node_put(hall_node);
+   return ret;
+   }
+
+   if (of_property_read_bool(hall_node, "azoteq,use-prox"))
+   iqs62x_keys->switches[i].flag = (i == IQS62X_SW_HALL_N ?
+IQS62X_EVENT_HALL_N_P :
+IQS62X_EVENT_HALL_S_P);
+   else
+   iqs62x_keys->switches[i].flag = (i == IQS62X_SW_HALL_N ?
+IQS62X_EVENT_HALL_N_T :
+IQS62X_EVENT_HALL_S_T);
+
+   iqs62x_keys->switches[i].code = val;
+   

Re: [v1,1/1] hwmon: (nct7904) Fix the incorrect value of vsen_mask & tcpu_mask & temp_mode in nct7904_data struct.

2019-10-20 Thread Guenter Roeck
On Mon, Oct 14, 2019 at 04:24:51PM +0800, amy.s...@advantech.com.tw wrote:
> From: "amy.shih" 
> 
> Voltage sensors overlap with external temperature sensors. Detect
> the multi-function of voltage, thermal diode, thermistor and
> reserved from register VT_ADC_MD_REG to set value of vsen_mask &
> tcpu_mask & temp_mode in nct7904_data struct. If the value is
> reserved, needs to disable the vsen_mask & tcpu_mask.
> 
> Signed-off-by: amy.shih 

Applied.

Thanks,
Guenter

> ---
>  drivers/hwmon/nct7904.c | 15 ---
>  1 file changed, 12 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/hwmon/nct7904.c b/drivers/hwmon/nct7904.c
> index b26419dbe840..281c81edabc6 100644
> --- a/drivers/hwmon/nct7904.c
> +++ b/drivers/hwmon/nct7904.c
> @@ -82,6 +82,10 @@
>  #define FANCTL1_FMR_REG  0x00/* Bank 3; 1 reg per channel */
>  #define FANCTL1_OUT_REG  0x10/* Bank 3; 1 reg per channel */
>  
> +#define VOLT_MONITOR_MODE0x0
> +#define THERMAL_DIODE_MODE   0x1
> +#define THERMISTOR_MODE  0x3
> +
>  #define ENABLE_TSI   BIT(1)
>  
>  static const unsigned short normal_i2c[] = {
> @@ -935,11 +939,16 @@ static int nct7904_probe(struct i2c_client *client,
>   for (i = 0; i < 4; i++) {
>   val = (ret >> (i * 2)) & 0x03;
>   bit = (1 << i);
> - if (val == 0) {
> + if (val == VOLT_MONITOR_MODE) {
>   data->tcpu_mask &= ~bit;
> + } else if (val == THERMAL_DIODE_MODE && i < 2) {
> + data->temp_mode |= bit;
> + data->vsen_mask &= ~(0x06 << (i * 2));
> + } else if (val == THERMISTOR_MODE) {
> + data->vsen_mask &= ~(0x02 << (i * 2));
>   } else {
> - if (val == 0x1 || val == 0x2)
> - data->temp_mode |= bit;
> + /* Reserved */
> + data->tcpu_mask &= ~bit;
>   data->vsen_mask &= ~(0x06 << (i * 2));
>   }
>   }


Re: [PATCH v2 1/2] hwmon: Support ADI Fan Control IP

2019-10-20 Thread Guenter Roeck
On Wed, Oct 09, 2019 at 12:28:05PM +0200, Nuno Sá wrote:
> The purpose of this IP Core is to control the fan used for the cooling of a
> Xilinx Zynq Ultrascale+ MPSoC without the need of any external temperature
> sensors. To achieve this, the IP core uses the PL SYSMONE4 primitive to
> obtain the PL temperature and, based on those readings, it then outputs
> a PWM signal to control the fan rotation accordingly.
> 
> Signed-off-by: Nuno Sá 

Applied to hwmon-next.

Thanks,
Guenter

> ---
> Changes in v2:
>  * define AXI_PCORE macros in the driver source for now;
>  * include linux/bits.h;
>  * axi_fan_control_io{read/write} renamed with shorter names;
>  * Make sure tach is != 0 when getting the fan rpm;
>  * Read only once the clk rate;
>  * Remove unneeded struct clk;
>  * Fixed typo in millidegrees;
>  * Use devm_platform_ioremap_resource();
>  * Remove unneeded error logs;
>  * Check valid values for pulses per revolution;
>  * Clear the fault attribute after reading it;
>  * Notify userspace if HW changed the PWM;
>  * Add comments on how the core works in other to better understand the IRQ 
> handling.
> 
>  MAINTAINERS |   7 +
>  drivers/hwmon/Kconfig   |   9 +
>  drivers/hwmon/Makefile  |   1 +
>  drivers/hwmon/axi-fan-control.c | 473 
>  4 files changed, 490 insertions(+)
>  create mode 100644 drivers/hwmon/axi-fan-control.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 296de2b51c83..caa80ae1925e 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2873,6 +2873,13 @@ S: Maintained
>  F:   Documentation/devicetree/bindings/sound/axentia,*
>  F:   sound/soc/atmel/tse850-pcm5142.c
>  
> +AXI-FAN-CONTROL HARDWARE MONITOR DRIVER
> +M:   Nuno Sá 
> +W:   http://ez.analog.com/community/linux-device-drivers
> +L:   linux-hwmon@vger.kernel.org
> +S:   Supported
> +F:   drivers/hwmon/axi-fan-control.c
> +
>  AXXIA I2C CONTROLLER
>  M:   Krzysztof Adamski 
>  L:   linux-...@vger.kernel.org
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index 7b6c4025b827..ca53bb33b965 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -269,6 +269,15 @@ config SENSORS_ASC7621
> This driver can also be built as a module. If so, the module
> will be called asc7621.
>  
> +config SENSORS_AXI_FAN_CONTROL
> + tristate "Analog Devices FAN Control HDL Core driver"
> + help
> +   If you say yes here you get support for the Analog Devices
> +   AXI HDL FAN monitoring core.
> +
> +   This driver can also be built as a module. If so, the module
> +   will be called axi-fan-control
> +
>  config SENSORS_K8TEMP
>   tristate "AMD Athlon64/FX or Opteron temperature sensor"
>   depends on X86 && PCI
> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> index 40c036ea45e6..dcb4b64e1f4d 100644
> --- a/drivers/hwmon/Makefile
> +++ b/drivers/hwmon/Makefile
> @@ -51,6 +51,7 @@ obj-$(CONFIG_SENSORS_AS370) += as370-hwmon.o
>  obj-$(CONFIG_SENSORS_ASC7621)+= asc7621.o
>  obj-$(CONFIG_SENSORS_ASPEED) += aspeed-pwm-tacho.o
>  obj-$(CONFIG_SENSORS_ATXP1)  += atxp1.o
> +obj-$(CONFIG_SENSORS_AXI_FAN_CONTROL) += axi-fan-control.o
>  obj-$(CONFIG_SENSORS_CORETEMP)   += coretemp.o
>  obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o
>  obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o
> diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c
> new file mode 100644
> index ..6c1bd3269c8c
> --- /dev/null
> +++ b/drivers/hwmon/axi-fan-control.c
> @@ -0,0 +1,473 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Fan Control HDL CORE driver
> + *
> + * Copyright 2019 Analog Devices Inc.
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define ADI_AXI_PCORE_VER_MAJOR(version) (((version) >> 16) & 0xff)
> +#define ADI_AXI_PCORE_VER_MINOR(version) (((version) >> 8) & 0xff)
> +#define ADI_AXI_PCORE_VER_PATCH(version) ((version) & 0xff)
> +
> +/* register map */
> +#define ADI_REG_RSTN 0x0080
> +#define ADI_REG_PWM_WIDTH0x0084
> +#define ADI_REG_TACH_PERIOD  0x0088
> +#define ADI_REG_TACH_TOLERANCE   0x008c
> +#define ADI_REG_PWM_PERIOD   0x00c0
> +#define ADI_REG_TACH_MEASUR  0x00c4
> +#define ADI_REG_TEMPERATURE  0x00c8
> +
> +#define ADI_REG_IRQ_MASK 0x0040
> +#define ADI_REG_IRQ_PENDING  0x0044
> +#define ADI_REG_IRQ_SRC  0x0048
> +
> +/* IRQ sources */
> +#define ADI_IRQ_SRC_PWM_CHANGED  BIT(0)
> +#define ADI_IRQ_SRC_TACH_ERR BIT(1)
> +#define ADI_IRQ_SRC_TEMP_INCREASEBIT(2)
> +#define ADI_IRQ_SRC_NEW_MEASUR   BIT(3)
> +#define ADI_IRQ_SRC_MASK GENMASK(3, 0)
> +#define ADI_IRQ_MASK_OUT_ALL 0xU
> +
> +#define SYSFS_PWM_MAX255
> +
> +struct axi_fan_control_data {
> + void __iomem *base;
> + struct device *hdev;
> +   

Re: [PATCH v2 2/2] dt-bindings: hwmon: Add AXI FAN Control documentation

2019-10-20 Thread Guenter Roeck
On Wed, Oct 09, 2019 at 12:28:06PM +0200, Nuno Sá wrote:
> Document the AXI FAN Control IP core devicetree bindings.
> 
> Signed-off-by: Nuno Sá 
> Reviewed-by: Rob Herring 

Applied to hwmon-next.

Thanks,
Guenter

> ---
> Changes in v2:
>  * Set the correct license for new bindings;
>  * Fix wrong compatible in the example;
>  * Wrap long line;
>  * Update adi,pulses-per-revolution with accepted values.
> 
>  .../bindings/hwmon/adi,axi-fan-control.yaml   | 62 +++
>  MAINTAINERS   |  1 +
>  2 files changed, 63 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/hwmon/adi,axi-fan-control.yaml
> 
> diff --git a/Documentation/devicetree/bindings/hwmon/adi,axi-fan-control.yaml 
> b/Documentation/devicetree/bindings/hwmon/adi,axi-fan-control.yaml
> new file mode 100644
> index ..dc82b9748c9d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/hwmon/adi,axi-fan-control.yaml
> @@ -0,0 +1,62 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# Copyright 2019 Analog Devices Inc.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/bindings/hwmon/adi,axi-fan-control.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Analog Devices AXI FAN Control Device Tree Bindings
> +
> +maintainers:
> +  - Nuno Sá 
> +
> +description: |+
> +  Bindings for the Analog Devices AXI FAN Control driver. Spefications of the
> +  core can be found in:
> +
> +  https://wiki.analog.com/resources/fpga/docs/axi_fan_control
> +
> +properties:
> +  compatible:
> +enum:
> +- adi,axi-fan-control-1.00.a
> +
> +  reg:
> +maxItems: 1
> +
> +  clocks:
> +maxItems: 1
> +
> +  interrupts:
> +maxItems: 1
> +
> +  adi,pulses-per-revolution:
> +description:
> +  Value specifying the number of pulses per revolution of the controlled
> +  FAN.
> +allOf:
> +  - $ref: /schemas/types.yaml#/definitions/uint32
> +enum: [1, 2, 4]
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - interrupts
> +  - adi,pulses-per-revolution
> +
> +examples:
> +  - |
> +fpga_axi: fpga-axi@0 {
> +#address-cells = <0x2>;
> +#size-cells = <0x1>;
> +
> +axi_fan_control: axi-fan-control@8000 {
> +compatible = "adi,axi-fan-control-1.00.a";
> +reg = <0x0 0x8000 0x1>;
> +clocks = < 71>;
> +interrupts = <0 110 0>;
> +adi,pulses-per-revolution = <2>;
> +};
> +};
> +...
> diff --git a/MAINTAINERS b/MAINTAINERS
> index caa80ae1925e..74ddcb3e1fd9 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2879,6 +2879,7 @@ W:  
> http://ez.analog.com/community/linux-device-drivers
>  L:   linux-hwmon@vger.kernel.org
>  S:   Supported
>  F:   drivers/hwmon/axi-fan-control.c
> +F:   Documentation/devicetree/bindings/hwmon/adi,axi-fan-control.yaml
>  
>  AXXIA I2C CONTROLLER
>  M:   Krzysztof Adamski 


Re: [PATCH v4 1/2] hwmon: Add driver for Texas Instruments TMP512/513 sensor chips

2019-10-20 Thread Guenter Roeck
On Mon, Oct 07, 2019 at 08:46:22PM +, Tremblay, Eric wrote:
> hwmon: Add driver for Texas Instruments TMP512/513 sensor chips.
> 
> TI's TMP512/513 are I2C/SMBus system monitor chips. These chips
> monitor the supply voltage, supply current, power consumption
> and provide one local and up to three (TMP513) remote temperature sensors.
> 
> It has been tested using a TI TMP513 development kit (TMP513EVM)
> 
> Signed-off-by: Eric Tremblay 
> ---
>  Documentation/hwmon/tmp513.rst | 102 +
>  MAINTAINERS|   7 +
>  drivers/hwmon/Kconfig  |  10 +
>  drivers/hwmon/Makefile |   1 +
>  drivers/hwmon/tmp513.c | 795 +
>  5 files changed, 915 insertions(+)
>  create mode 100644 Documentation/hwmon/tmp513.rst
>  create mode 100644 drivers/hwmon/tmp513.c
> 
> diff --git a/Documentation/hwmon/tmp513.rst b/Documentation/hwmon/tmp513.rst
> new file mode 100644
> index ..b3837748ca7e
> --- /dev/null
> +++ b/Documentation/hwmon/tmp513.rst
> @@ -0,0 +1,102 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +Kernel driver tmp513
> +
> +
> +Supported chips:
> +
> +  * Texas Instruments TMP512
> +
> +Prefix: 'tmp512'
> +
> +Datasheet: http://www.ti.com/lit/ds/symlink/tmp512.pdf
> +
> +  * Texas Instruments TMP513
> +
> +Prefix: 'tmp513'
> +
> +Datasheet: http://www.ti.com/lit/ds/symlink/tmp513.pdf
> +
> +Authors:
> +
> + Eric Tremblay 
> +
> +Description
> +---
> +
> +This driver implements support for Texas Instruments TMP512, and TMP513
> +temperature and power supply sensor chips. These chips implement one
> +local and up to three (TMP513) temperature sensors. The chips also implement
> +power supply monitoring such as shunt voltage, shunt current, bus voltage
> +and power consumption.
> +
> +The temperatures are measured in degrees Celsius with a range of
> +-40 to + 125 degrees with a resolution of 0.0625 degree C.
> +
> +For hysteresis value, only the first channel is writable. Writing to it
> +will affect all other values since each channels are sharing the same
> +hysteresis value. The hysteresis is in degrees Celsius with a range of
> +0 to 127.5 degrees with a resolution of 0.5 degree.
> +
> +The driver exports the temperature values via the following sysfs files:
> +
> +**temp[1-4]_input**
> +
> +**temp[1-4]_crit**
> +
> +**temp[1-4]_crit_alarm**
> +
> +**temp[1-4]_crit_hyst**
> +
> +The shunt voltage is measured in micro volts. There are four configurable
> +range: 320mV, 160mV, 80mV and 40mV all of them with a resolution of 10 uV.
> +The range depends on the pga gain specified in the device tree
> +with "pga-gain" (default to 8). The range will be equal to pga gain
> +multiply by 40mV.
> +
> +The driver exports the shunt voltage values via the following sysFs files:
> +
> +**in0_input**
> +
> +**in0_lcrit**
> +
> +**in0_lcrit_alarm**
> +
> +**in0_crit**
> +
> +**in0_crit_alarm**
> +
> +The bus voltage is measured in milli volts. There are two configuable
> +range: 32V and 16V both with a resolution of 4mV. It can be configured in the
> +device tree with "bus-voltage-range" (default to 32V);
> +
> +The driver exports the bus voltage values via the following sysFs files:
> +
> +**in0_input**
> +
> +**in0_lcrit**
> +
> +**in0_lcrit_alarm**
> +
> +**in0_crit**
> +
> +**in0_crit_alarm**
> +
> +The power and the currents range and resolution depends on the calibration
> +register value. Those values are calculate by the hardware using those
> +formula:
> +
> +Current = (ShuntVoltage * CalibrationRegister) / 4096
> +Power   = (Current * BusVoltage) / 5000
> +
> +The driver exports the current and power values via the following sysFs 
> files:
> +
> +**curr0_input**
> +
> +**power1_input**
> +
> +**power1_crit**
> +
> +**power1_crit_alarm**
> +
> +The calibration process follow the procedure of the datasheet (without 
> overflow)
> +and depend on the shunt resistor value and the pga_gain value.
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 55199ef7fa74..64b36fa3a436 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16373,6 +16373,13 @@ S:   Maintained
>  F:   Documentation/hwmon/tmp401.rst
>  F:   drivers/hwmon/tmp401.c
>  
> +TMP513 HARDWARE MONITOR DRIVER
> +M:   Eric Tremblay 
> +L:   linux-hwmon@vger.kernel.org
> +S:   Maintained
> +F:   Documentation/hwmon/tmp513.rst
> +F:   drivers/hwmon/tmp513.c
> +
>  TMPFS (SHMEM FILESYSTEM)
>  M:   Hugh Dickins 
>  L:   linux...@kvack.org
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index 13a6b4afb4b3..926e3c98dbdf 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -1709,6 +1709,16 @@ config SENSORS_TMP421
> This driver can also be built as a module. If so, the module
> will be called tmp421.
>  
> +config SENSORS_TMP513
> + tristate "Texas Instruments TMP513 and compatibles"
> + depends on I2C
> + help
> +   If you say yes here you get support for Texas Instruments 

Re: [PATCH v4 2/2] hwmon: Add driver for Texas Instruments TMP512/513 sensor chips

2019-10-20 Thread Guenter Roeck
On Mon, Oct 07, 2019 at 08:47:03PM +, Tremblay, Eric wrote:
> dt-bindings: Add TMP512/513 documentation
> 
> Add documentation for TMP512/513 sensor chips
> 
Since this is the devicetree documentation, it will need to be approved by
a devicetree maintainer. Wondering why that didn't happen, I just realized
what you did not copy the devicetree mailing list. Please do that when you
resend.

Note that they may require devicetree documentation in yaml format nowadays.

Guenter

> Signed-off-by: Eric Tremblay 
> ---
>  .../devicetree/bindings/hwmon/tmp513.txt  | 32 +++
>  1 file changed, 32 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/hwmon/tmp513.txt
> 
> diff --git a/Documentation/devicetree/bindings/hwmon/tmp513.txt 
> b/Documentation/devicetree/bindings/hwmon/tmp513.txt
> new file mode 100644
> index ..dbfade74f6b1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/hwmon/tmp513.txt
> @@ -0,0 +1,32 @@
> +TMP513 system monitor sensor
> +-
> +
> +Require node properties:
> +- compatible: one of
> + "ti,tmp512"
> + "ti,tmp513"
> +- reg : the I2C address of the device. This is 0x5c, 0x5d, 0x5e, or 0x5f.
> +
> +Optional properties:
> +- shunt-resistor-uohm : The shunt resistor value in uOhm. If 0, the 
> calibration process
> + will be skiped and the current and power measurement engine 
> will not work.
> + Temperature and voltage measurement will continue to work. The 
> shunt value also
> + need to respect : rshunt <= pga-gain * 40 * 1000 * 1000. If 
> not, it's not possible
> + to compute a valid calibration value. Default to 1000 uOhm.
> +- pga-gain: The gain value for the PGA function. This is 8, 4, 2 or 1. 
> Default to 8.
> + The PGA gain affect the shunt voltage range.
> + The range will be equal to: pga-gain * 40mV.
> +- bus-voltage-range: 32V or 16V, default to 32V.
> +- nfactor: u8 array of three(TMP513) or two(TMP512) n-Factor value for each 
> remote
> + temperature channel. Default to 0.
> + See datasheet Table 11 for n-Factor range list and value 
> interpretation.
> +
> +Example:
> + tmp513@5c {
> +   compatible = "ti,tmp513";
> +   reg = <0x5C>;
> +   shunt-resistor-uohm = <33>;
> +   bus-voltage-range = <32>;
> +   pga-gain = <8>;
> +   nfactor = [01 F3 00];
> + };