lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220630112651.2739425-3-julian.haller@bbl.ms.philips.com>
Date:   Thu, 30 Jun 2022 13:26:50 +0200
From:   Julian Haller <julian.haller@....ms.philips.com>
To:     linux-kernel@...r.kernel.org
Cc:     julian.haller@...lips.com, zbr@...emap.net
Subject: [PATCH 3/4] w1: ds1wm: Add support for permanent strong pull-up

From: Julian Haller <julian.haller@...lips.com>

Add support for enabling the strong pull-up, both via device tree and
platform data.

Signed-off-by: Julian Haller <julian.haller@...lips.com>
---
 drivers/w1/masters/ds1wm.c | 38 +++++++++++++++++++++++++++++++++++---
 include/linux/mfd/ds1wm.h  |  2 ++
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index a764b016758f..5768430a536e 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -25,6 +25,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/bitops.h>
 
 #include <asm/io.h>
 
@@ -36,7 +37,7 @@
 #define DS1WM_INT	0x02	/* R/W interrupt status */
 #define DS1WM_INT_EN	0x03	/* R/W interrupt enable */
 #define DS1WM_CLKDIV	0x04	/* R/W 5 bits of divisor and pre-scale */
-#define DS1WM_CNTRL	0x05	/* R/W master control register (not used yet) */
+#define DS1WM_CNTRL	0x05	/* R/W master control register */
 
 #define DS1WM_CMD_1W_RESET  (1 << 0)	/* force reset on 1-wire bus */
 #define DS1WM_CMD_SRA	    (1 << 1)	/* enable Search ROM accelerator mode */
@@ -60,6 +61,15 @@
 #define DS1WM_INTEN_ERSRF   (1 << 5)	/* enable rx shift register full int */
 #define DS1WM_INTEN_DQO	    (1 << 6)	/* enable direct bus driving ops */
 
+#define DS1WM_CNTRL_LLM     BIT(0)	/* long line mode */
+#define DS1WM_CNTRL_PPM     BIT(1)	/* presence pulse masking */
+#define DS1WM_CNTRL_EN_FOW  BIT(2)	/* enable force 1 wire command */
+#define DS1WM_CNTRL_STPEN   BIT(3)	/* active pullup enable */
+#define DS1WM_CNTRL_STP_SPLY BIT(4)	/* strong pullup power delivery */
+#define DS1WM_CNTRL_BIT_CTL BIT(5)	/* bit control */
+#define DS1WM_CNTRL_OD      BIT(6)	/* overdrive speed */
+
+
 #define DS1WM_INTEN_NOT_IAS (~DS1WM_INTEN_IAS)	/* all but INTR active state */
 
 #define DS1WM_TIMEOUT (HZ * 5)
@@ -115,6 +125,8 @@ struct ds1wm_data {
 	/* considering active_state (IAS) (optimization) */
 	u8       int_en_reg_none;
 	unsigned int reset_recover_delay; /* see ds1wm.h */
+	bool     strong_pullup_enable;
+	bool     strong_pullup_supply;
 };
 
 static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg,
@@ -313,6 +325,7 @@ static void ds1wm_up(struct ds1wm_data *ds1wm_data)
 {
 	int divisor;
 	struct device *dev = &ds1wm_data->pdev->dev;
+	u8 cntrl;
 
 	if (ds1wm_data->cell && ds1wm_data->cell->enable)
 		ds1wm_data->cell->enable(ds1wm_data->pdev);
@@ -330,6 +343,20 @@ static void ds1wm_up(struct ds1wm_data *ds1wm_data)
 	/* Let the w1 clock stabilize. */
 	msleep(1);
 
+	/* Set strong pullup */
+	cntrl = ds1wm_read_register(ds1wm_data, DS1WM_CNTRL);
+	if (ds1wm_data->strong_pullup_enable) {
+		cntrl |= DS1WM_CNTRL_STPEN;
+		if (ds1wm_data->strong_pullup_supply)
+			cntrl |= DS1WM_CNTRL_STP_SPLY;
+		else
+			cntrl &= ~DS1WM_CNTRL_STP_SPLY;
+	} else {
+		cntrl &= ~DS1WM_CNTRL_STPEN;
+		cntrl &= ~DS1WM_CNTRL_STP_SPLY;
+	}
+	ds1wm_write_register(ds1wm_data, DS1WM_CNTRL, cntrl);
+
 	ds1wm_reset(ds1wm_data);
 }
 
@@ -589,8 +616,10 @@ static int ds1wm_probe(struct platform_device *pdev)
 		}
 		ds1wm_data->clock_rate = clock_rate;
 
-		ds1wm_data->strong_pullup = of_property_read_bool(node,
-				"maxim,strong-pullup");
+		ds1wm_data->strong_pullup_enable = of_property_read_bool(node,
+				"maxim,strong-pullup-enable");
+		ds1wm_data->strong_pullup_supply = of_property_read_bool(node,
+				"maxim,strong-pullup-supply");
 	} else {
 		/* Using platform data */
 		ds1wm_data->cell = mfd_get_cell(pdev);
@@ -608,6 +637,9 @@ static int ds1wm_probe(struct platform_device *pdev)
 		ds1wm_data->reset_recover_delay = plat->reset_recover_delay;
 
 		ds1wm_data->clock_rate = plat->clock_rate;
+
+		ds1wm_data->strong_pullup_enable = plat->strong_pullup_enable;
+		ds1wm_data->strong_pullup_supply = plat->strong_pullup_supply;
 	}
 
 	/* how many bits to shift register number to get register offset */
diff --git a/include/linux/mfd/ds1wm.h b/include/linux/mfd/ds1wm.h
index 43dfca1c9702..dd9285ea507b 100644
--- a/include/linux/mfd/ds1wm.h
+++ b/include/linux/mfd/ds1wm.h
@@ -26,4 +26,6 @@ struct ds1wm_driver_data {
 	 * Only 0,1,2 allowed for 8,16 or 32 bit bus width respectively
 	 */
 	unsigned int bus_shift;
+	bool strong_pullup_enable;
+	bool strong_pullup_supply;
 };
-- 
2.25.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ