Messages in this thread Patch in this message | | | From | Julian Haller <> | Subject | [PATCH 3/4] w1: ds1wm: Add support for permanent strong pull-up | Date | Thu, 30 Jun 2022 13:26:50 +0200 |
| |
From: Julian Haller <julian.haller@philips.com>
Add support for enabling the strong pull-up, both via device tree and platform data.
Signed-off-by: Julian Haller <julian.haller@philips.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
| |