* RE: [PATCH v7 RESEND 07/13] spi: imx: fix ERR009165
From: Robin Gong @ 2020-05-13 8:38 UTC (permalink / raw)
To: Sascha Hauer
Cc: vkoul@kernel.org, shawnguo@kernel.org,
u.kleine-koenig@pengutronix.de, robh+dt@kernel.org,
festevam@gmail.com, dan.j.williams@intel.com,
mark.rutland@arm.com, catalin.marinas@arm.com,
will.deacon@arm.com, l.stach@pengutronix.de,
martin.fuzzey@flowbird.group, kernel@pengutronix.de,
linux-spi@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, dl-linux-imx,
dmaengine@vger.kernel.org, devicetree@vger.kernel.org
In-Reply-To: <20200513072132.GL5877@pengutronix.de>
On 2020/05/13 Sascha Hauer <s.hauer@pengutronix.de> wrote:
> This patch is the one bisecting will end up with when somebody uses an older
> SDMA firmware or the ROM scripts. It should have a better description what
> happens and what should be done about it.
Emm..That's true. Timeout will be caught in such case, hence, maybe we can fall back it to pio always.
> >
> > Signed-off-by: Robin Gong <yibin.gong@nxp.com>
> > Acked-by: Mark Brown <broonie@kernel.org>
> > ---
> > drivers/spi/spi-imx.c | 16 ++++++++--------
> > 1 file changed, 8 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index
> > f4f28a4..70df8e6 100644
> > --- a/drivers/spi/spi-imx.c
> > +++ b/drivers/spi/spi-imx.c
> > @@ -585,8 +585,8 @@ static int mx51_ecspi_prepare_transfer(struct
> spi_imx_data *spi_imx,
> > ctrl |= mx51_ecspi_clkdiv(spi_imx, t->speed_hz, &clk);
> > spi_imx->spi_bus_clk = clk;
> >
> > - if (spi_imx->usedma)
> > - ctrl |= MX51_ECSPI_CTRL_SMC;
> > + /* ERR009165: work in XHC mode as PIO */
> > + ctrl &= ~MX51_ECSPI_CTRL_SMC;
> >
> > writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
> >
> > @@ -617,7 +617,7 @@ static void mx51_setup_wml(struct spi_imx_data
> *spi_imx)
> > * and enable DMA request.
> > */
> > writel(MX51_ECSPI_DMA_RX_WML(spi_imx->wml - 1) |
> > - MX51_ECSPI_DMA_TX_WML(spi_imx->wml) |
> > + MX51_ECSPI_DMA_TX_WML(0) |
> > MX51_ECSPI_DMA_RXT_WML(spi_imx->wml) |
> > MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN |
> > MX51_ECSPI_DMA_RXTDEN, spi_imx->base + MX51_ECSPI_DMA);
> @@ -1171,7
> > +1171,11 @@ static int spi_imx_dma_configure(struct spi_master *master)
> > tx.direction = DMA_MEM_TO_DEV;
> > tx.dst_addr = spi_imx->base_phys + MXC_CSPITXDATA;
> > tx.dst_addr_width = buswidth;
> > - tx.dst_maxburst = spi_imx->wml;
> > + /*
> > + * For ERR009165 with tx_wml = 0 could enlarge burst size to fifo size
> > + * to speed up fifo filling as possible.
> > + */
> > + tx.dst_maxburst = spi_imx->devtype_data->fifo_size;
> > ret = dmaengine_slave_config(master->dma_tx, &tx);
> > if (ret) {
> > dev_err(spi_imx->dev, "TX dma configuration failed with %d\n",
> > ret); @@ -1265,10 +1269,6 @@ static int spi_imx_sdma_init(struct
> > device *dev, struct spi_imx_data *spi_imx, {
> > int ret;
> >
> > - /* use pio mode for i.mx6dl chip TKT238285 */
> > - if (of_machine_is_compatible("fsl,imx6dl"))
> > - return 0;
> > -
> > spi_imx->wml = spi_imx->devtype_data->fifo_size / 2;
> >
> > /* Prepare for TX DMA: */
> > --
> > 2.7.4
> >
> >
>
> --
> Pengutronix e.K. |
> |
> Steuerwalder Str. 21 |
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.pe
> ngutronix.de%2F&data=02%7C01%7Cyibin.gong%40nxp.com%7C2f49309
> 819cc4c45418108d7f70e46fb%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%
> 7C1%7C637249513003506970&sdata=RoLVnDaCfG20i88OmmlpbMH6lZu
> qqW2CJv4VSSDkPcM%3D&reserved=0 |
> 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686 | Fax:
> +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCH] dt-bindings: display: analogix_dp.txt: convert to yaml
From: Ricardo Cañuelo @ 2020-05-13 8:42 UTC (permalink / raw)
To: Rob Herring; +Cc: devicetree, kernel, dri-devel, airlied
In-Reply-To: <20200511213108.GA3374@bogus>
Hi Rob,
Thanks for reviewing the patch and I'm sorry it had so many mistakes,
this was my first attempt at converting a DT binding to schema.
On lun 11-05-2020 16:31:08, Rob Herring wrote:
> > This binding is meant to be used in conjunction with
> > Documentation/bindings/display/rockchip/analogix_dp-rockchip.txt
> > and
> > Documentation/bindings/display/exynos/exynos_dp.txt
> >
> > I was careful to define the bindings to be flexible enough for both
> > cases, since the properties might be slightly different depending
> > on the SoC.
>
> They need to be converted all at once to schema.
I'll queue that up to work on next and I'll try to come up with a good
patch series to convert the three bindings.
Cheers,
Ricardo
^ permalink raw reply
* Re: [PATCH v7 RESEND 07/13] spi: imx: fix ERR009165
From: Sascha Hauer @ 2020-05-13 8:48 UTC (permalink / raw)
To: Robin Gong
Cc: vkoul@kernel.org, shawnguo@kernel.org,
u.kleine-koenig@pengutronix.de, robh+dt@kernel.org,
festevam@gmail.com, dan.j.williams@intel.com,
mark.rutland@arm.com, catalin.marinas@arm.com,
will.deacon@arm.com, l.stach@pengutronix.de,
martin.fuzzey@flowbird.group, kernel@pengutronix.de,
linux-spi@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, dl-linux-imx,
dmaengine@vger.kernel.org, devicetree@vger.kernel.org
In-Reply-To: <VE1PR04MB6638F5096376BA0AF204C64189BF0@VE1PR04MB6638.eurprd04.prod.outlook.com>
On Wed, May 13, 2020 at 08:38:26AM +0000, Robin Gong wrote:
> On 2020/05/13 Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > This patch is the one bisecting will end up with when somebody uses an older
> > SDMA firmware or the ROM scripts. It should have a better description what
> > happens and what should be done about it.
> Emm..That's true. Timeout will be caught in such case, hence, maybe we can fall back it to pio always.
With my patch applied sdma_load_context() will fail. I don't know how
exactly this hits into the SPI driver, but it won't be a timeout.
Sascha
> > >
> > > Signed-off-by: Robin Gong <yibin.gong@nxp.com>
> > > Acked-by: Mark Brown <broonie@kernel.org>
> > > ---
> > > drivers/spi/spi-imx.c | 16 ++++++++--------
> > > 1 file changed, 8 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index
> > > f4f28a4..70df8e6 100644
> > > --- a/drivers/spi/spi-imx.c
> > > +++ b/drivers/spi/spi-imx.c
> > > @@ -585,8 +585,8 @@ static int mx51_ecspi_prepare_transfer(struct
> > spi_imx_data *spi_imx,
> > > ctrl |= mx51_ecspi_clkdiv(spi_imx, t->speed_hz, &clk);
> > > spi_imx->spi_bus_clk = clk;
> > >
> > > - if (spi_imx->usedma)
> > > - ctrl |= MX51_ECSPI_CTRL_SMC;
> > > + /* ERR009165: work in XHC mode as PIO */
> > > + ctrl &= ~MX51_ECSPI_CTRL_SMC;
> > >
> > > writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
> > >
> > > @@ -617,7 +617,7 @@ static void mx51_setup_wml(struct spi_imx_data
> > *spi_imx)
> > > * and enable DMA request.
> > > */
> > > writel(MX51_ECSPI_DMA_RX_WML(spi_imx->wml - 1) |
> > > - MX51_ECSPI_DMA_TX_WML(spi_imx->wml) |
> > > + MX51_ECSPI_DMA_TX_WML(0) |
> > > MX51_ECSPI_DMA_RXT_WML(spi_imx->wml) |
> > > MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN |
> > > MX51_ECSPI_DMA_RXTDEN, spi_imx->base + MX51_ECSPI_DMA);
> > @@ -1171,7
> > > +1171,11 @@ static int spi_imx_dma_configure(struct spi_master *master)
> > > tx.direction = DMA_MEM_TO_DEV;
> > > tx.dst_addr = spi_imx->base_phys + MXC_CSPITXDATA;
> > > tx.dst_addr_width = buswidth;
> > > - tx.dst_maxburst = spi_imx->wml;
> > > + /*
> > > + * For ERR009165 with tx_wml = 0 could enlarge burst size to fifo size
> > > + * to speed up fifo filling as possible.
> > > + */
> > > + tx.dst_maxburst = spi_imx->devtype_data->fifo_size;
> > > ret = dmaengine_slave_config(master->dma_tx, &tx);
> > > if (ret) {
> > > dev_err(spi_imx->dev, "TX dma configuration failed with %d\n",
> > > ret); @@ -1265,10 +1269,6 @@ static int spi_imx_sdma_init(struct
> > > device *dev, struct spi_imx_data *spi_imx, {
> > > int ret;
> > >
> > > - /* use pio mode for i.mx6dl chip TKT238285 */
> > > - if (of_machine_is_compatible("fsl,imx6dl"))
> > > - return 0;
> > > -
> > > spi_imx->wml = spi_imx->devtype_data->fifo_size / 2;
> > >
> > > /* Prepare for TX DMA: */
> > > --
> > > 2.7.4
> > >
> > >
> >
> > --
> > Pengutronix e.K. |
> > |
> > Steuerwalder Str. 21 |
> > https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.pe
> > ngutronix.de%2F&data=02%7C01%7Cyibin.gong%40nxp.com%7C2f49309
> > 819cc4c45418108d7f70e46fb%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%
> > 7C1%7C637249513003506970&sdata=RoLVnDaCfG20i88OmmlpbMH6lZu
> > qqW2CJv4VSSDkPcM%3D&reserved=0 |
> > 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> > |
> > Amtsgericht Hildesheim, HRA 2686 | Fax:
> > +49-5121-206917-5555 |
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCH 1/1] arm64: dts: imx8mp: add "fsl,imx6sx-fec" compatible string
From: Shawn Guo @ 2020-05-13 8:49 UTC (permalink / raw)
To: fugang.duan
Cc: robh+dt, s.hauer, kernel, festevam, Anson.Huang, devicetree,
aisheng.dong, linux-arm-kernel, linux-kernel
In-Reply-To: <1588154654-13684-1-git-send-email-fugang.duan@nxp.com>
On Wed, Apr 29, 2020 at 06:04:14PM +0800, fugang.duan@nxp.com wrote:
> From: Fugang Duan <fugang.duan@nxp.com>
>
> Add "fsl,imx6sx-fec" compatible string for fec node, then
> i.MX8MP EVK ethernet function can work now.
>
> Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
> ---
> arch/arm64/boot/dts/freescale/imx8mp.dtsi | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> index 9b1616e59d58..b5df957c5063 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> @@ -615,7 +615,7 @@
> };
>
> fec: ethernet@30be0000 {
> - compatible = "fsl,imx8mp-fec", "fsl,imx8mq-fec";
> + compatible = "fsl,imx8mp-fec", "fsl,imx8mq-fec", "fsl,imx6sx-fec";
In this case, "fsl,imx8mq-fec" can be dropped?
Shawn
> reg = <0x30be0000 0x10000>;
> interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
> <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
> --
> 2.17.1
>
^ permalink raw reply
* RE: [PATCH v7 RESEND 07/13] spi: imx: fix ERR009165
From: Robin Gong @ 2020-05-13 8:52 UTC (permalink / raw)
To: Sascha Hauer
Cc: vkoul@kernel.org, shawnguo@kernel.org,
u.kleine-koenig@pengutronix.de, robh+dt@kernel.org,
festevam@gmail.com, dan.j.williams@intel.com,
mark.rutland@arm.com, catalin.marinas@arm.com,
will.deacon@arm.com, l.stach@pengutronix.de,
martin.fuzzey@flowbird.group, kernel@pengutronix.de,
linux-spi@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, dl-linux-imx,
dmaengine@vger.kernel.org, devicetree@vger.kernel.org
In-Reply-To: <20200513084815.GP5877@pengutronix.de>
On 2020/05/13 16:48 Sascha Hauer <s.hauer@pengutronix.de> wrote:
> On Wed, May 13, 2020 at 08:38:26AM +0000, Robin Gong wrote:
> > On 2020/05/13 Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > > This patch is the one bisecting will end up with when somebody uses
> > > an older SDMA firmware or the ROM scripts. It should have a better
> > > description what happens and what should be done about it.
> > Emm..That's true. Timeout will be caught in such case, hence, maybe we can
> fall back it to pio always.
>
> With my patch applied sdma_load_context() will fail. I don't know how exactly
> this hits into the SPI driver, but it won't be a timeout.
Thanks for your quick test, assume you use ROM firmware, right?
^ permalink raw reply
* RE: [EXT] Re: [PATCH 1/1] arm64: dts: imx8mp: add "fsl,imx6sx-fec" compatible string
From: Andy Duan @ 2020-05-13 8:58 UTC (permalink / raw)
To: Shawn Guo
Cc: robh+dt@kernel.org, s.hauer@pengutronix.de, kernel@pengutronix.de,
festevam@gmail.com, Anson Huang, devicetree@vger.kernel.org,
Aisheng Dong, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20200513084933.GF26997@dragon>
From: Shawn Guo <shawnguo@kernel.org> Sent: Wednesday, May 13, 2020 4:50 PM
> On Wed, Apr 29, 2020 at 06:04:14PM +0800, fugang.duan@nxp.com wrote:
> > From: Fugang Duan <fugang.duan@nxp.com>
> >
> > Add "fsl,imx6sx-fec" compatible string for fec node, then i.MX8MP EVK
> > ethernet function can work now.
> >
> > Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
> > ---
> > arch/arm64/boot/dts/freescale/imx8mp.dtsi | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > index 9b1616e59d58..b5df957c5063 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > @@ -615,7 +615,7 @@
> > };
> >
> > fec: ethernet@30be0000 {
> > - compatible = "fsl,imx8mp-fec",
> "fsl,imx8mq-fec";
> > + compatible = "fsl,imx8mp-fec",
> > + "fsl,imx8mq-fec", "fsl,imx6sx-fec";
>
> In this case, "fsl,imx8mq-fec" can be dropped?
>
> Shawn
Please don't drop the compatible string, there have little difference for 8mq
that support eee feature, the feature will be upstreamed.
Thanks.
>
> > reg = <0x30be0000 0x10000>;
> > interrupts = <GIC_SPI 118
> IRQ_TYPE_LEVEL_HIGH>,
> > <GIC_SPI 119
> > IRQ_TYPE_LEVEL_HIGH>,
> > --
> > 2.17.1
> >
^ permalink raw reply
* RE: [PATCH v7 RESEND 07/13] spi: imx: fix ERR009165
From: Robin Gong @ 2020-05-13 9:05 UTC (permalink / raw)
To: Sascha Hauer
Cc: vkoul@kernel.org, shawnguo@kernel.org,
u.kleine-koenig@pengutronix.de, robh+dt@kernel.org,
festevam@gmail.com, dan.j.williams@intel.com,
mark.rutland@arm.com, catalin.marinas@arm.com,
will.deacon@arm.com, l.stach@pengutronix.de,
martin.fuzzey@flowbird.group, kernel@pengutronix.de,
linux-spi@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, dl-linux-imx,
dmaengine@vger.kernel.org, devicetree@vger.kernel.org
In-Reply-To: <20200513073359.GM5877@pengutronix.de>
On 2020/05/13 Sascha Hauer <s.hauer@pengutronix.de> wrote:d
> > drivers/spi/spi-imx.c | 16 ++++++++--------
> > 1 file changed, 8 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index
> > f4f28a4..70df8e6 100644
> > --- a/drivers/spi/spi-imx.c
> > +++ b/drivers/spi/spi-imx.c
> > @@ -585,8 +585,8 @@ static int mx51_ecspi_prepare_transfer(struct
> spi_imx_data *spi_imx,
> > ctrl |= mx51_ecspi_clkdiv(spi_imx, t->speed_hz, &clk);
> > spi_imx->spi_bus_clk = clk;
> >
> > - if (spi_imx->usedma)
> > - ctrl |= MX51_ECSPI_CTRL_SMC;
> > + /* ERR009165: work in XHC mode as PIO */
> > + ctrl &= ~MX51_ECSPI_CTRL_SMC;
> >
> > writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
> >
> > @@ -617,7 +617,7 @@ static void mx51_setup_wml(struct spi_imx_data
> *spi_imx)
> > * and enable DMA request.
> > */
> > writel(MX51_ECSPI_DMA_RX_WML(spi_imx->wml - 1) |
> > - MX51_ECSPI_DMA_TX_WML(spi_imx->wml) |
> > + MX51_ECSPI_DMA_TX_WML(0) |
> > MX51_ECSPI_DMA_RXT_WML(spi_imx->wml) |
> > MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN |
> > MX51_ECSPI_DMA_RXTDEN, spi_imx->base + MX51_ECSPI_DMA);
> @@ -1171,7
> > +1171,11 @@ static int spi_imx_dma_configure(struct spi_master *master)
> > tx.direction = DMA_MEM_TO_DEV;
> > tx.dst_addr = spi_imx->base_phys + MXC_CSPITXDATA;
> > tx.dst_addr_width = buswidth;
> > - tx.dst_maxburst = spi_imx->wml;
> > + /*
> > + * For ERR009165 with tx_wml = 0 could enlarge burst size to fifo size
> > + * to speed up fifo filling as possible.
> > + */
> > + tx.dst_maxburst = spi_imx->devtype_data->fifo_size;
>
> In the next patch this is changed again to:
>
> + if (spi_imx->devtype_data->tx_glitch_fixed)
> + tx.dst_maxburst = spi_imx->wml;
> + else
> + tx.dst_maxburst = spi_imx->devtype_data->fifo_size;
>
> So with tx_glitch_fixed we end up with tx.dst_maxburst being the same as two
> patches before which is rather confusing. Better introduce tx_glitch_fixed in
> this patch, or maybe even merge this patch and the next one.
Sorry confused you, I should repleace 'tx_wml=0' in the above comments with ' TX_THRESHOLD=0', which means tx transfer dma have to wait all the tx data in tx fifo transferred with ERR009165 rather than generically 'tx_wml' (for example --half fifo size used as TX_THRESHOLD). Obviously TX_THRESHOLD=0 would down performance, so enlarge dst_maxburst to fifo size as PIO with ERR009165. After ERR009165 fixed at HW level. TX_THRESHOLD could be used as common 'spi_imx->wml' so change it back. Will add more detail information in v8.
^ permalink raw reply
* Re: [PATCH V2 3/3] iio: adc: Add support for PMIC7 ADC
From: Jishnu Prakash @ 2020-05-13 9:20 UTC (permalink / raw)
To: Andy Shevchenko
Cc: agross, Bjorn Andersson, devicetree, Linux Kernel Mailing List,
Matthias Kaehlcke, Linus Walleij, Jonathan Cameron, smohanad,
kgunda, aghayal, Jonathan Cameron, Hartmut Knaack,
Lars-Peter Clausen, Peter Meerwald-Stadler, linux-arm-msm,
linux-iio, linux-arm-msm-owner
In-Reply-To: <CAHp75Vdu4HvaTg5ij=DFhwn=y_JCb9ae9L5-iV72Zk-k9CBHuw@mail.gmail.com>
Hi Andy,
On 4/27/2020 6:58 PM, Andy Shevchenko wrote:
> On Mon, Apr 27, 2020 at 3:56 PM Jishnu Prakash <jprakash@codeaurora.org> wrote:
>> On 4/17/2020 3:51 PM, Andy Shevchenko wrote:
>> On Thu, Apr 16, 2020 at 1:48 AM Jishnu Prakash <jprakash@codeaurora.org> wrote:
> Stop using HTML. It breaks badly the reply and discussion.
>
> ...
>
>> +static const struct adc5_data adc7_data_pmic;
>>
>> Global variable? Hmm...
>>
>> adc7_data_pmic is referenced twice before its actual definition (which was added along with corresponding adc5_data struct for PMIC5 ADC), so I have given the initial declaration here.
> Maybe you can realize how to avoid global variable at all?
There is a way to remove this, I'll make this change with some other
changes in the fifth patch of my latest post.
>
> ...
>
>> + buf[1] &= 0xff & ~ADC5_USR_FAST_AVG_CTL_SAMPLES_MASK;
>>
>> What the point of 0xff & part?
>>
>> This was something you suggested in my first post:
>>
>>> + buf[1] &= (u8) ~ADC5_USR_FAST_AVG_CTL_SAMPLES_MASK;
>> Use '0xFF ^ _MASK' instead of casting.
>>
>> ...
>>
>>> + buf[3] &= (u8) ~ADC5_USR_HW_SETTLE_DELAY_MASK;
>> Ditto.
>>
>> I think "0xff &" works as intended here in place of casting to (u8)...
> Does it work without casting? (Note, I suggested slightly different expression)
> I.o.w. what the problem casting solves?
I checked this part again. It looks like casting is not strictly
required here, I'll remove it in my latest post.
>
>> + buf[1] |= prop->avg_samples;
>> +
>> + /* Select ADC channel */
>> + buf[2] = prop->channel;
>> +
>> + /* Select HW settle delay for channel */
>> + buf[3] &= 0xff & ~ADC5_USR_HW_SETTLE_DELAY_MASK;
>>
>> Ditto.
>>
>> + buf[3] |= prop->hw_settle_time;
>
^ permalink raw reply
* Re: [PATCH v7 RESEND 07/13] spi: imx: fix ERR009165
From: Sascha Hauer @ 2020-05-13 9:20 UTC (permalink / raw)
To: Robin Gong
Cc: mark.rutland@arm.com, devicetree@vger.kernel.org,
catalin.marinas@arm.com, kernel@pengutronix.de,
shawnguo@kernel.org, will.deacon@arm.com,
linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org,
vkoul@kernel.org, robh+dt@kernel.org, dl-linux-imx,
martin.fuzzey@flowbird.group, u.kleine-koenig@pengutronix.de,
dmaengine@vger.kernel.org, dan.j.williams@intel.com,
festevam@gmail.com, linux-arm-kernel@lists.infradead.org,
l.stach@pengutronix.de
In-Reply-To: <VE1PR04MB6638DE9AB1E51213DACCCA0F89BF0@VE1PR04MB6638.eurprd04.prod.outlook.com>
On Wed, May 13, 2020 at 09:05:33AM +0000, Robin Gong wrote:
> On 2020/05/13 Sascha Hauer <s.hauer@pengutronix.de> wrote:d
> > > drivers/spi/spi-imx.c | 16 ++++++++--------
> > > 1 file changed, 8 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index
> > > f4f28a4..70df8e6 100644
> > > --- a/drivers/spi/spi-imx.c
> > > +++ b/drivers/spi/spi-imx.c
> > > @@ -585,8 +585,8 @@ static int mx51_ecspi_prepare_transfer(struct
> > spi_imx_data *spi_imx,
> > > ctrl |= mx51_ecspi_clkdiv(spi_imx, t->speed_hz, &clk);
> > > spi_imx->spi_bus_clk = clk;
> > >
> > > - if (spi_imx->usedma)
> > > - ctrl |= MX51_ECSPI_CTRL_SMC;
> > > + /* ERR009165: work in XHC mode as PIO */
> > > + ctrl &= ~MX51_ECSPI_CTRL_SMC;
> > >
> > > writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
> > >
> > > @@ -617,7 +617,7 @@ static void mx51_setup_wml(struct spi_imx_data
> > *spi_imx)
> > > * and enable DMA request.
> > > */
> > > writel(MX51_ECSPI_DMA_RX_WML(spi_imx->wml - 1) |
> > > - MX51_ECSPI_DMA_TX_WML(spi_imx->wml) |
> > > + MX51_ECSPI_DMA_TX_WML(0) |
> > > MX51_ECSPI_DMA_RXT_WML(spi_imx->wml) |
> > > MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN |
> > > MX51_ECSPI_DMA_RXTDEN, spi_imx->base + MX51_ECSPI_DMA);
> > @@ -1171,7
> > > +1171,11 @@ static int spi_imx_dma_configure(struct spi_master *master)
> > > tx.direction = DMA_MEM_TO_DEV;
> > > tx.dst_addr = spi_imx->base_phys + MXC_CSPITXDATA;
> > > tx.dst_addr_width = buswidth;
> > > - tx.dst_maxburst = spi_imx->wml;
> > > + /*
> > > + * For ERR009165 with tx_wml = 0 could enlarge burst size to fifo size
> > > + * to speed up fifo filling as possible.
> > > + */
> > > + tx.dst_maxburst = spi_imx->devtype_data->fifo_size;
> >
> > In the next patch this is changed again to:
> >
> > + if (spi_imx->devtype_data->tx_glitch_fixed)
> > + tx.dst_maxburst = spi_imx->wml;
> > + else
> > + tx.dst_maxburst = spi_imx->devtype_data->fifo_size;
> >
> > So with tx_glitch_fixed we end up with tx.dst_maxburst being the same as two
> > patches before which is rather confusing. Better introduce tx_glitch_fixed in
> > this patch, or maybe even merge this patch and the next one.
> Sorry confused you, I should repleace 'tx_wml=0' in the above comments
> with ' TX_THRESHOLD=0', which means tx transfer dma have to wait all
> the tx data in tx fifo transferred with ERR009165 rather than
> generically 'tx_wml' (for example --half fifo size used as
> TX_THRESHOLD). Obviously TX_THRESHOLD=0 would down performance, so
> enlarge dst_maxburst to fifo size as PIO with ERR009165. After
> ERR009165 fixed at HW level. TX_THRESHOLD could be used as common
> 'spi_imx->wml' so change it back. Will add more detail information in
> v8.
I am not confused, I meant the patches are confusing. What you are doing
is:
No patch:
tx.dst_maxburst = a;
1st patch
tx.dst_maxburst = b;
2nd patch:
if (foo)
tx.dst_maxburst = a;
else
tx.dst_maxburst = b;
It would be better readable and understandable if you did that in one
patch, because that would directly say "Under certain conditions we have
to choose a, otherwise b". That's much better than changing "a" to "b" and
then to "a or b"
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCH v7 RESEND 07/13] spi: imx: fix ERR009165
From: Sascha Hauer @ 2020-05-13 9:20 UTC (permalink / raw)
To: Robin Gong
Cc: vkoul@kernel.org, shawnguo@kernel.org,
u.kleine-koenig@pengutronix.de, robh+dt@kernel.org,
festevam@gmail.com, dan.j.williams@intel.com,
mark.rutland@arm.com, catalin.marinas@arm.com,
will.deacon@arm.com, l.stach@pengutronix.de,
martin.fuzzey@flowbird.group, kernel@pengutronix.de,
linux-spi@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, dl-linux-imx,
dmaengine@vger.kernel.org, devicetree@vger.kernel.org
In-Reply-To: <VE1PR04MB6638857DD94A05DC7252E69589BF0@VE1PR04MB6638.eurprd04.prod.outlook.com>
On Wed, May 13, 2020 at 08:52:39AM +0000, Robin Gong wrote:
> On 2020/05/13 16:48 Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > On Wed, May 13, 2020 at 08:38:26AM +0000, Robin Gong wrote:
> > > On 2020/05/13 Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > > > This patch is the one bisecting will end up with when somebody uses
> > > > an older SDMA firmware or the ROM scripts. It should have a better
> > > > description what happens and what should be done about it.
> > > Emm..That's true. Timeout will be caught in such case, hence, maybe we can
> > fall back it to pio always.
> >
> > With my patch applied sdma_load_context() will fail. I don't know how exactly
> > this hits into the SPI driver, but it won't be a timeout.
> Thanks for your quick test, assume you use ROM firmware, right?
Yes.
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCH V3 3/4] iio: adc: Add support for PMIC7 ADC
From: Jishnu Prakash @ 2020-05-13 9:20 UTC (permalink / raw)
To: Amit Kucheria
Cc: Andy Gross, Bjorn Andersson,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, LKML,
Matthias Kaehlcke, Linus Walleij, Jonathan.Cameron, smohanad,
kgunda, aghayal, Jonathan Cameron, Hartmut Knaack,
Lars-Peter Clausen, Peter Meerwald-Stadler, linux-arm-msm,
linux-iio, linux-arm-msm-owner
In-Reply-To: <CAHLCerPrZNBt+J_yZom1dtJ20r-H2_dAmHWFf9_bs3QV823Lgw@mail.gmail.com>
Hi Amit,
On 5/5/2020 3:33 PM, Amit Kucheria wrote:
> Hi Jishnu,
>
> It is nice to cc a reviewer from a previous version. Just saw this.
>
> On Mon, Apr 27, 2020 at 6:55 PM Jishnu Prakash <jprakash@codeaurora.org> wrote:
>> The ADC architecture on PMIC7 is changed as compared to PMIC5. The
>> major change from PMIC5 is that all SW communication to ADC goes through
>> PMK8350, which communicates with other PMICs through PBS when the ADC
>> on PMK8350 works in master mode. The SID register is used to identify the
>> PMICs with which the PBS needs to communicate. Add support for the same.
>>
>> Signed-off-by: Jishnu Prakash <jprakash@codeaurora.org>
>> ---
>> drivers/iio/adc/qcom-spmi-adc5.c | 239 +++++++++++++++++++++++++++++++++-
>> drivers/iio/adc/qcom-vadc-common.c | 260 +++++++++++++++++++++++++++++++++++++
>> drivers/iio/adc/qcom-vadc-common.h | 15 +++
>> 3 files changed, 510 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c
>> index 21fdcde..a66eeb7 100644
>> --- a/drivers/iio/adc/qcom-spmi-adc5.c
>> +++ b/drivers/iio/adc/qcom-spmi-adc5.c
>> @@ -1,6 +1,6 @@
>> // SPDX-License-Identifier: GPL-2.0
>> /*
>> - * Copyright (c) 2018, The Linux Foundation. All rights reserved.
>> + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved.
>> */
>>
>> #include <linux/bitops.h>
>> @@ -23,6 +23,7 @@
>>
>> #define ADC5_USR_REVISION1 0x0
>> #define ADC5_USR_STATUS1 0x8
>> +#define ADC5_USR_STATUS1_CONV_FAULT BIT(7)
>> #define ADC5_USR_STATUS1_REQ_STS BIT(1)
>> #define ADC5_USR_STATUS1_EOC BIT(0)
>> #define ADC5_USR_STATUS1_REQ_STS_EOC_MASK 0x3
>> @@ -65,6 +66,9 @@
>>
>> #define ADC5_USR_IBAT_DATA1 0x53
>>
>> +#define ADC_CHANNEL_OFFSET 0x8
>> +#define ADC_CHANNEL_MASK GENMASK(7, 0)
>> +
>> /*
>> * Conversion time varies based on the decimation, clock rate, fast average
>> * samples and measurements queued across different VADC peripherals.
>> @@ -79,6 +83,11 @@
>> #define ADC5_HW_SETTLE_DIFF_MINOR 3
>> #define ADC5_HW_SETTLE_DIFF_MAJOR 5
>>
>> +/* For PMIC7 */
>> +#define ADC_APP_SID 0x40
>> +#define ADC_APP_SID_MASK GENMASK(3, 0)
>> +#define ADC7_CONV_TIMEOUT msecs_to_jiffies(10)
>> +
>> enum adc5_cal_method {
>> ADC5_NO_CAL = 0,
>> ADC5_RATIOMETRIC_CAL,
>> @@ -96,6 +105,7 @@ enum adc5_cal_val {
>> * @cal_method: calibration method.
>> * @cal_val: calibration value
>> * @decimation: sampling rate supported for the channel.
>> + * @sid: slave id of PMIC owning the channel, for PMIC7.
>> * @prescale: channel scaling performed on the input signal.
>> * @hw_settle_time: the time between AMUX being configured and the
>> * start of conversion.
>> @@ -110,6 +120,7 @@ struct adc5_channel_prop {
>> enum adc5_cal_method cal_method;
>> enum adc5_cal_val cal_val;
>> unsigned int decimation;
>> + unsigned int sid;
>> unsigned int prescale;
>> unsigned int hw_settle_time;
>> unsigned int avg_samples;
>> @@ -140,6 +151,7 @@ struct adc5_chip {
>> bool poll_eoc;
>> struct completion complete;
>> struct mutex lock;
>> + int irq_eoc;
>> const struct adc5_data *data;
>> };
>>
>> @@ -155,6 +167,8 @@ static const struct vadc_prescale_ratio adc5_prescale_ratios[] = {
>> {.num = 1, .den = 16}
>> };
>>
>> +static const struct adc5_data adc7_data_pmic;
>> +
>> static int adc5_read(struct adc5_chip *adc, u16 offset, u8 *data, int len)
>> {
>> return regmap_bulk_read(adc->regmap, adc->base + offset, data, len);
>> @@ -165,6 +179,11 @@ static int adc5_write(struct adc5_chip *adc, u16 offset, u8 *data, int len)
>> return regmap_bulk_write(adc->regmap, adc->base + offset, data, len);
>> }
>>
>> +static int adc5_masked_write(struct adc5_chip *adc, u16 offset, u8 mask, u8 val)
>> +{
>> + return regmap_update_bits(adc->regmap, adc->base + offset, mask, val);
>> +}
>> +
>> static int adc5_prescaling_from_dt(u32 num, u32 den)
>> {
>> unsigned int pre;
>> @@ -314,6 +333,47 @@ static int adc5_configure(struct adc5_chip *adc,
>> return adc5_write(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf));
>> }
>>
>> +static int adc7_configure(struct adc5_chip *adc,
>> + struct adc5_channel_prop *prop)
>> +{
>> + int ret;
>> + u8 conv_req = 0, buf[4];
>> +
>> + ret = adc5_masked_write(adc, ADC_APP_SID, ADC_APP_SID_MASK, prop->sid);
>> + if (ret)
>> + return ret;
>> +
>> + ret = adc5_read(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf));
>> + if (ret < 0)
>> + return ret;
>> +
>> + /* Digital param selection */
>> + adc5_update_dig_param(adc, prop, &buf[0]);
>> +
>> + /* Update fast average sample value */
>> + buf[1] &= 0xff & ~ADC5_USR_FAST_AVG_CTL_SAMPLES_MASK;
> Did you answer Andy's query about this in v2? I couldn't find it.
I missed it at earlier, I have replied now and will make the change in
my latest post.
>
>> + buf[1] |= prop->avg_samples;
>> +
>> + /* Select ADC channel */
>> + buf[2] = prop->channel;
>> +
>> + /* Select HW settle delay for channel */
>> + buf[3] &= 0xff & ~ADC5_USR_HW_SETTLE_DELAY_MASK;
> Same here.
I missed it at earlier, I have replied now and will make the change in
my latest post.
>
>> + buf[3] |= prop->hw_settle_time;
>> +
>> + /* Select CONV request */
>> + conv_req = ADC5_USR_CONV_REQ_REQ;
>> +
>> + if (!adc->poll_eoc)
>> + reinit_completion(&adc->complete);
>> +
>> + ret = adc5_write(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf));
>> + if (ret)
>> + return ret;
>> +
>> + return adc5_write(adc, ADC5_USR_CONV_REQ, &conv_req, 1);
> Is it required to call adc5_write() twice here in sequence on the
> adc7? adc5_configure() above manages just fine by having an extra
> element in buf and one call.
In PMIC5, that write is used to write to registers 0x42-0x47. Register
0x46 has been removed for PMIC7 ADC, so we use two writes, for 0x42-0x45
and for 0x47 alone.
>
>> +}
>> +
>> static int adc5_do_conversion(struct adc5_chip *adc,
>> struct adc5_channel_prop *prop,
>> struct iio_chan_spec const *chan,
>> @@ -355,6 +415,43 @@ static int adc5_do_conversion(struct adc5_chip *adc,
>> return ret;
>> }
>>
>> +static int adc7_do_conversion(struct adc5_chip *adc,
>> + struct adc5_channel_prop *prop,
>> + struct iio_chan_spec const *chan,
>> + u16 *data_volt, u16 *data_cur)
>> +{
>> + int ret;
>> + u8 status;
>> +
>> + mutex_lock(&adc->lock);
>> +
>> + ret = adc7_configure(adc, prop);
>> + if (ret) {
>> + dev_err(adc->dev, "ADC configure failed with %d\n", ret);
>> + goto unlock;
>> + }
>> +
>> + /* No support for polling mode at present */
>> + wait_for_completion_timeout(&adc->complete, ADC7_CONV_TIMEOUT);
>> +
>> + ret = adc5_read(adc, ADC5_USR_STATUS1, &status, 1);
>> + if (ret < 0)
>> + goto unlock;
>> +
>> + if (status & ADC5_USR_STATUS1_CONV_FAULT) {
>> + dev_err(adc->dev, "Unexpected conversion fault\n");
>> + ret = -EIO;
>> + goto unlock;
>> + }
>> +
>> + ret = adc5_read_voltage_data(adc, data_volt);
>> +
>> +unlock:
>> + mutex_unlock(&adc->lock);
>> +
>> + return ret;
>> +}
>> +
>> static irqreturn_t adc5_isr(int irq, void *dev_id)
>> {
>> struct adc5_chip *adc = dev_id;
>> @@ -377,6 +474,56 @@ static int adc5_of_xlate(struct iio_dev *indio_dev,
>> return -EINVAL;
>> }
>>
>> +static int adc7_of_xlate(struct iio_dev *indio_dev,
>> + const struct of_phandle_args *iiospec)
>> +{
>> + struct adc5_chip *adc = iio_priv(indio_dev);
>> + int i, v_channel;
>> +
>> + for (i = 0; i < adc->nchannels; i++) {
>> + v_channel = (adc->chan_props[i].sid << ADC_CHANNEL_OFFSET |
>> + adc->chan_props[i].channel);
>> + if (v_channel == iiospec->args[0])
>> + return i;
>> + }
>> +
>> + return -EINVAL;
>> +}
>> +
>> +static int adc7_read_raw(struct iio_dev *indio_dev,
>> + struct iio_chan_spec const *chan, int *val, int *val2,
>> + long mask)
> Just a nit. Since all your adc7 functions follow your adc5 functions,
> please move this below adc5_read_raw for consistency.
I'll do it in the next post.
>
>> +{
>> + struct adc5_chip *adc = iio_priv(indio_dev);
>> + struct adc5_channel_prop *prop;
>> + u16 adc_code_volt, adc_code_cur;
>> + int ret;
>> +
>> + prop = &adc->chan_props[chan->address];
>> +
>> + switch (mask) {
>> + case IIO_CHAN_INFO_PROCESSED:
>> + ret = adc7_do_conversion(adc, prop, chan,
> Except for this bit (call to adc7_do_conversion instead of
> adc5_do_conversion), this function is identical to adc5_read_raw.
>
> How about making adc5_read_raw and adc7_read_raw a shim around a
> function adc_read_raw_common() that takes a function pointer?
I'll do this in the next post.
>
>> + &adc_code_volt, &adc_code_cur);
>> + if (ret)
>> + return ret;
>> +
>> + ret = qcom_adc5_hw_scale(prop->scale_fn_type,
>> + &adc5_prescale_ratios[prop->prescale],
>> + adc->data,
>> + adc_code_volt, val);
>> +
>> + if (ret)
>> + return ret;
>> +
>> + return IIO_VAL_INT;
>> + default:
>> + return -EINVAL;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> static int adc5_read_raw(struct iio_dev *indio_dev,
>> struct iio_chan_spec const *chan, int *val, int *val2,
>> long mask)
>> @@ -415,6 +562,11 @@ static const struct iio_info adc5_info = {
>> .of_xlate = adc5_of_xlate,
>> };
>>
>> +static const struct iio_info adc7_info = {
>> + .read_raw = adc7_read_raw,
>> + .of_xlate = adc7_of_xlate,
>> +};
>> +
>> struct adc5_channels {
>> const char *datasheet_name;
>> unsigned int prescale_index;
>> @@ -477,6 +629,39 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = {
>> SCALE_HW_CALIB_PM5_SMB_TEMP)
>> };
>>
>> +static const struct adc5_channels adc7_chans_pmic[ADC5_MAX_CHANNEL] = {
>> + [ADC7_REF_GND] = ADC5_CHAN_VOLT("ref_gnd", 0,
>> + SCALE_HW_CALIB_DEFAULT)
>> + [ADC7_1P25VREF] = ADC5_CHAN_VOLT("vref_1p25", 0,
>> + SCALE_HW_CALIB_DEFAULT)
>> + [ADC7_VPH_PWR] = ADC5_CHAN_VOLT("vph_pwr", 1,
>> + SCALE_HW_CALIB_DEFAULT)
>> + [ADC7_VBAT_SNS] = ADC5_CHAN_VOLT("vbat_sns", 3,
>> + SCALE_HW_CALIB_DEFAULT)
>> + [ADC7_DIE_TEMP] = ADC5_CHAN_TEMP("die_temp", 0,
>> + SCALE_HW_CALIB_PMIC_THERM_PM7)
>> + [ADC7_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_pu2", 0,
>> + SCALE_HW_CALIB_THERM_100K_PU_PM7)
>> + [ADC7_AMUX_THM2_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_pu2", 0,
>> + SCALE_HW_CALIB_THERM_100K_PU_PM7)
>> + [ADC7_AMUX_THM3_100K_PU] = ADC5_CHAN_TEMP("amux_thm3_pu2", 0,
>> + SCALE_HW_CALIB_THERM_100K_PU_PM7)
>> + [ADC7_AMUX_THM4_100K_PU] = ADC5_CHAN_TEMP("amux_thm4_pu2", 0,
>> + SCALE_HW_CALIB_THERM_100K_PU_PM7)
>> + [ADC7_AMUX_THM5_100K_PU] = ADC5_CHAN_TEMP("amux_thm5_pu2", 0,
>> + SCALE_HW_CALIB_THERM_100K_PU_PM7)
>> + [ADC7_AMUX_THM6_100K_PU] = ADC5_CHAN_TEMP("amux_thm6_pu2", 0,
> Use space instead of tab for indentation in all the THMx channels to
> make it look more in line.
I'll do this in the next post.
>
>> + SCALE_HW_CALIB_THERM_100K_PU_PM7)
>> + [ADC7_GPIO1_100K_PU] = ADC5_CHAN_TEMP("gpio1_pu2", 0,
>> + SCALE_HW_CALIB_THERM_100K_PU_PM7)
>> + [ADC7_GPIO2_100K_PU] = ADC5_CHAN_TEMP("gpio2_pu2", 0,
>> + SCALE_HW_CALIB_THERM_100K_PU_PM7)
>> + [ADC7_GPIO3_100K_PU] = ADC5_CHAN_TEMP("gpio3_pu2", 0,
>> + SCALE_HW_CALIB_THERM_100K_PU_PM7)
>> + [ADC7_GPIO4_100K_PU] = ADC5_CHAN_TEMP("gpio4_pu2", 0,
>> + SCALE_HW_CALIB_THERM_100K_PU_PM7)
>> +};
>> +
>> static const struct adc5_channels adc5_chans_rev2[ADC5_MAX_CHANNEL] = {
>> [ADC5_REF_GND] = ADC5_CHAN_VOLT("ref_gnd", 0,
>> SCALE_HW_CALIB_DEFAULT)
>> @@ -511,6 +696,7 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc,
>> {
>> const char *name = node->name, *channel_name;
>> u32 chan, value, varr[2];
>> + u32 sid = 0;
>> int ret;
>> struct device *dev = adc->dev;
>>
>> @@ -520,6 +706,15 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc,
>> return ret;
>> }
>>
>> + /* Value read from "reg" is virtual channel number */
>> +
>> + /* virtual channel number = sid << 8 | channel number */
>> +
>> + if (adc->data == &adc7_data_pmic) {
>> + sid = chan >> ADC_CHANNEL_OFFSET;
>> + chan = chan & ADC_CHANNEL_MASK;
>> + }
>> +
>> if (chan > ADC5_PARALLEL_ISENSE_VBAT_IDATA ||
>> !data->adc_chans[chan].datasheet_name) {
>> dev_err(dev, "%s invalid channel number %d\n", name, chan);
>> @@ -528,6 +723,7 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc,
>>
>> /* the channel has DT description */
>> prop->channel = chan;
>> + prop->sid = sid;
>>
>> channel_name = of_get_property(node,
>> "label", NULL) ? : node->name;
>> @@ -578,8 +774,9 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc,
>> pr_debug("dig_ver:minor:%d, major:%d\n", dig_version[0],
>> dig_version[1]);
>> /* Digital controller >= 5.3 have hw_settle_2 option */
>> - if (dig_version[0] >= ADC5_HW_SETTLE_DIFF_MINOR &&
>> - dig_version[1] >= ADC5_HW_SETTLE_DIFF_MAJOR)
>> + if ((dig_version[0] >= ADC5_HW_SETTLE_DIFF_MINOR &&
>> + dig_version[1] >= ADC5_HW_SETTLE_DIFF_MAJOR) ||
>> + adc->data == &adc7_data_pmic)
>> ret = adc5_hw_settle_time_from_dt(value,
>> data->hw_settle_2);
>> else
>> @@ -629,6 +826,7 @@ static const struct adc5_data adc5_data_pmic = {
>> .full_scale_code_volt = 0x70e4,
>> .full_scale_code_cur = 0x2710,
>> .adc_chans = adc5_chans_pmic,
>> + .info = &adc5_info,
> This belongs in a separate patch along with the change in
> adc5_data_pmic_rev2 below
I'll add a separate patch for this in the next post.
>
>> .decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX])
>> {250, 420, 840},
>> .hw_settle_1 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
>> @@ -639,10 +837,23 @@ static const struct adc5_data adc5_data_pmic = {
>> 1, 2, 4, 8, 16, 32, 64, 128},
>> };
>>
>> +static const struct adc5_data adc7_data_pmic = {
>> + .full_scale_code_volt = 0x70e4,
>> + .adc_chans = adc7_chans_pmic,
>> + .info = &adc7_info,
>> + .decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX])
>> + {85, 340, 1360},
>> + .hw_settle_2 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
>> + {15, 100, 200, 300, 400, 500, 600, 700,
>> + 1000, 2000, 4000, 8000, 16000, 32000,
>> + 64000, 128000},
>> +};
>> +
>> static const struct adc5_data adc5_data_pmic_rev2 = {
>> .full_scale_code_volt = 0x4000,
>> .full_scale_code_cur = 0x1800,
>> .adc_chans = adc5_chans_rev2,
>> + .info = &adc5_info,
> Separate patch.
I'll add a separate patch for this in the next post.
>
>> .decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX])
>> {256, 512, 1024},
>> .hw_settle_1 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
>> @@ -659,6 +870,10 @@ static const struct of_device_id adc5_match_table[] = {
>> .data = &adc5_data_pmic,
>> },
>> {
>> + .compatible = "qcom,spmi-adc7",
>> + .data = &adc7_data_pmic,
>> + },
>> + {
>> .compatible = "qcom,spmi-adc-rev2",
>> .data = &adc5_data_pmic_rev2,
>> },
>> @@ -752,6 +967,9 @@ static int adc5_probe(struct platform_device *pdev)
>> adc->regmap = regmap;
>> adc->dev = dev;
>> adc->base = reg;
>> +
>> + platform_set_drvdata(pdev, adc);
>> +
>> init_completion(&adc->complete);
>> mutex_init(&adc->lock);
>>
>> @@ -761,6 +979,8 @@ static int adc5_probe(struct platform_device *pdev)
>> return ret;
>> }
>>
>> + indio_dev->info = adc->data->info;
>> +
>> irq_eoc = platform_get_irq(pdev, 0);
>> if (irq_eoc < 0) {
>> if (irq_eoc == -EPROBE_DEFER || irq_eoc == -EINVAL)
>> @@ -773,23 +993,34 @@ static int adc5_probe(struct platform_device *pdev)
>> return ret;
>> }
>>
>> + adc->irq_eoc = irq_eoc;
>> +
> I think this belongs in a separate patch along with the adc5_exit
> function below.
I'll add a separate patch for this in the next post.
>
>> indio_dev->dev.parent = dev;
>> indio_dev->dev.of_node = node;
>> indio_dev->name = pdev->name;
>> indio_dev->modes = INDIO_DIRECT_MODE;
>> - indio_dev->info = &adc5_info;
>> indio_dev->channels = adc->iio_chans;
>> indio_dev->num_channels = adc->nchannels;
>>
>> return devm_iio_device_register(dev, indio_dev);
>> }
>>
>> +static int adc5_exit(struct platform_device *pdev)
>> +{
>> + struct adc5_chip *adc = platform_get_drvdata(pdev);
>> +
>> + if (adc->irq_eoc >= 0)
>> + disable_irq(adc->irq_eoc);
>> + return 0;
>> +}
>> +
>> static struct platform_driver adc5_driver = {
>> .driver = {
>> .name = "qcom-spmi-adc5.c",
>> .of_match_table = adc5_match_table,
>> },
>> .probe = adc5_probe,
>> + .remove = adc5_exit,
> This really belongs in a separate patch
I'll add a separate patch for this and the above changes mentioned in
the next post.
>
>> };
>> module_platform_driver(adc5_driver);
>>
>>
^ permalink raw reply
* [PATCH V4 0/5] iio: adc: Add support for QCOM SPMI PMIC7 ADC
From: Jishnu Prakash @ 2020-05-13 9:22 UTC (permalink / raw)
To: agross, bjorn.andersson, devicetree, linux-kernel, mka,
linus.walleij, Jonathan.Cameron, andy.shevchenko, amit.kucheria,
smohanad, kgunda, aghayal
Cc: linux-arm-msm, linux-arm-msm-owner, Jishnu Prakash
The following changes are made in V4:
Made some recommended minor changes in the third patch. Removed
the info member from adc5_data, and adc exit function, to be
added back in fifth patch.
Added a fifth patch to clean up code common to PMIC5 and PMIC7 ADC.
Jishnu Prakash (5):
iio: adc: Convert the QCOM SPMI ADC bindings to .yaml format
iio: adc: Add PMIC7 ADC bindings
iio: adc: Add support for PMIC7 ADC
iio: adc: Update error checks and debug prints
iio: adc: Clean up ADC code common to PMIC5 and PMIC7
.../devicetree/bindings/iio/adc/qcom,spmi-vadc.txt | 173 -------------
.../bindings/iio/adc/qcom,spmi-vadc.yaml | 278 +++++++++++++++++++++
drivers/iio/adc/qcom-spmi-adc5.c | 266 ++++++++++++++++++--
drivers/iio/adc/qcom-vadc-common.c | 260 +++++++++++++++++++
drivers/iio/adc/qcom-vadc-common.h | 15 ++
include/dt-bindings/iio/qcom,spmi-adc7-pm8350.h | 67 +++++
include/dt-bindings/iio/qcom,spmi-adc7-pm8350b.h | 88 +++++++
include/dt-bindings/iio/qcom,spmi-adc7-pmk8350.h | 46 ++++
include/dt-bindings/iio/qcom,spmi-adc7-pmr735a.h | 28 +++
include/dt-bindings/iio/qcom,spmi-adc7-pmr735b.h | 28 +++
include/dt-bindings/iio/qcom,spmi-vadc.h | 78 +++++-
11 files changed, 1134 insertions(+), 193 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt
create mode 100644 Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml
create mode 100644 include/dt-bindings/iio/qcom,spmi-adc7-pm8350.h
create mode 100644 include/dt-bindings/iio/qcom,spmi-adc7-pm8350b.h
create mode 100644 include/dt-bindings/iio/qcom,spmi-adc7-pmk8350.h
create mode 100644 include/dt-bindings/iio/qcom,spmi-adc7-pmr735a.h
create mode 100644 include/dt-bindings/iio/qcom,spmi-adc7-pmr735b.h
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH V4 1/5] iio: adc: Convert the QCOM SPMI ADC bindings to .yaml format
From: Jishnu Prakash @ 2020-05-13 9:22 UTC (permalink / raw)
To: agross, bjorn.andersson, devicetree, linux-kernel, mka,
linus.walleij, Jonathan.Cameron, andy.shevchenko, amit.kucheria,
smohanad, kgunda, aghayal, Jonathan Cameron, Hartmut Knaack,
Lars-Peter Clausen, Peter Meerwald-Stadler, Rob Herring,
Mark Rutland, Jishnu Prakash, Amit Kucheria, linux-iio
Cc: linux-arm-msm, linux-arm-msm-owner
In-Reply-To: <1589361736-816-1-git-send-email-jprakash@codeaurora.org>
Convert the adc bindings from .txt to .yaml format.
Signed-off-by: Jishnu Prakash <jprakash@codeaurora.org>
Reviewed-by: Amit Kucheria <amit.kucheria@linaro.org>
Reviewed-by: Rob Herring <robh@kernel.org>
---
.../devicetree/bindings/iio/adc/qcom,spmi-vadc.txt | 173 --------------
.../bindings/iio/adc/qcom,spmi-vadc.yaml | 252 +++++++++++++++++++++
2 files changed, 252 insertions(+), 173 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt
create mode 100644 Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml
diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt
deleted file mode 100644
index c878768..0000000
--- a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt
+++ /dev/null
@@ -1,173 +0,0 @@
-Qualcomm's SPMI PMIC ADC
-
-- SPMI PMIC voltage ADC (VADC) provides interface to clients to read
- voltage. The VADC is a 15-bit sigma-delta ADC.
-- SPMI PMIC5 voltage ADC (ADC) provides interface to clients to read
- voltage. The VADC is a 16-bit sigma-delta ADC.
-
-VADC node:
-
-- compatible:
- Usage: required
- Value type: <string>
- Definition: Should contain "qcom,spmi-vadc".
- Should contain "qcom,spmi-adc5" for PMIC5 ADC driver.
- Should contain "qcom,spmi-adc-rev2" for PMIC rev2 ADC driver.
- Should contain "qcom,pms405-adc" for PMS405 PMIC
-
-- reg:
- Usage: required
- Value type: <prop-encoded-array>
- Definition: VADC base address in the SPMI PMIC register map.
-
-- #address-cells:
- Usage: required
- Value type: <u32>
- Definition: Must be one. Child node 'reg' property should define ADC
- channel number.
-
-- #size-cells:
- Usage: required
- Value type: <u32>
- Definition: Must be zero.
-
-- #io-channel-cells:
- Usage: required
- Value type: <u32>
- Definition: Must be one. For details about IIO bindings see:
- Documentation/devicetree/bindings/iio/iio-bindings.txt
-
-- interrupts:
- Usage: optional
- Value type: <prop-encoded-array>
- Definition: End of conversion interrupt.
-
-Channel node properties:
-
-- reg:
- Usage: required
- Value type: <u32>
- Definition: ADC channel number.
- See include/dt-bindings/iio/qcom,spmi-vadc.h
-
-- label:
- Usage: required for "qcom,spmi-adc5" and "qcom,spmi-adc-rev2"
- Value type: <empty>
- Definition: ADC input of the platform as seen in the schematics.
- For thermistor inputs connected to generic AMUX or GPIO inputs
- these can vary across platform for the same pins. Hence select
- the platform schematics name for this channel.
-
-- qcom,decimation:
- Usage: optional
- Value type: <u32>
- Definition: This parameter is used to decrease ADC sampling rate.
- Quicker measurements can be made by reducing decimation ratio.
- - For compatible property "qcom,spmi-vadc", valid values are
- 512, 1024, 2048, 4096. If property is not found, default value
- of 512 will be used.
- - For compatible property "qcom,spmi-adc5", valid values are 250, 420
- and 840. If property is not found, default value of 840 is used.
- - For compatible property "qcom,spmi-adc-rev2", valid values are 256,
- 512 and 1024. If property is not present, default value is 1024.
-
-- qcom,pre-scaling:
- Usage: optional
- Value type: <u32 array>
- Definition: Used for scaling the channel input signal before the signal is
- fed to VADC. The configuration for this node is to know the
- pre-determined ratio and use it for post scaling. Select one from
- the following options.
- <1 1>, <1 3>, <1 4>, <1 6>, <1 20>, <1 8>, <10 81>, <1 10>
- If property is not found default value depending on chip will be used.
-
-- qcom,ratiometric:
- Usage: optional
- Value type: <empty>
- Definition: Channel calibration type.
- - For compatible property "qcom,spmi-vadc", if this property is
- specified VADC will use the VDD reference (1.8V) and GND for
- channel calibration. If property is not found, channel will be
- calibrated with 0.625V and 1.25V reference channels, also
- known as absolute calibration.
- - For compatible property "qcom,spmi-adc5" and "qcom,spmi-adc-rev2",
- if this property is specified VADC will use the VDD reference
- (1.875V) and GND for channel calibration. If property is not found,
- channel will be calibrated with 0V and 1.25V reference channels,
- also known as absolute calibration.
-
-- qcom,hw-settle-time:
- Usage: optional
- Value type: <u32>
- Definition: Time between AMUX getting configured and the ADC starting
- conversion. The 'hw_settle_time' is an index used from valid values
- and programmed in hardware to achieve the hardware settling delay.
- - For compatible property "qcom,spmi-vadc" and "qcom,spmi-adc-rev2",
- Delay = 100us * (hw_settle_time) for hw_settle_time < 11,
- and 2ms * (hw_settle_time - 10) otherwise.
- Valid values are: 0, 100, 200, 300, 400, 500, 600, 700, 800,
- 900 us and 1, 2, 4, 6, 8, 10 ms.
- If property is not found, channel will use 0us.
- - For compatible property "qcom,spmi-adc5", delay = 15us for
- value 0, 100us * (value) for values < 11,
- and 2ms * (value - 10) otherwise.
- Valid values are: 15, 100, 200, 300, 400, 500, 600, 700, 800,
- 900 us and 1, 2, 4, 6, 8, 10 ms
- Certain controller digital versions have valid values of
- 15, 100, 200, 300, 400, 500, 600, 700, 1, 2, 4, 8, 16, 32, 64, 128 ms
- If property is not found, channel will use 15us.
-
-- qcom,avg-samples:
- Usage: optional
- Value type: <u32>
- Definition: Number of samples to be used for measurement.
- Averaging provides the option to obtain a single measurement
- from the ADC that is an average of multiple samples. The value
- selected is 2^(value).
- - For compatible property "qcom,spmi-vadc", valid values
- are: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512
- If property is not found, 1 sample will be used.
- - For compatible property "qcom,spmi-adc5" and "qcom,spmi-adc-rev2",
- valid values are: 1, 2, 4, 8, 16
- If property is not found, 1 sample will be used.
-
-NOTE:
-
-For compatible property "qcom,spmi-vadc" following channels, also known as
-reference point channels, are used for result calibration and their channel
-configuration nodes should be defined:
-VADC_REF_625MV and/or VADC_SPARE1(based on PMIC version) VADC_REF_1250MV,
-VADC_GND_REF and VADC_VDD_VADC.
-
-Example:
-
-#include <dt-bindings/iio/qcom,spmi-vadc.h>
-#include <linux/irq.h>
-/* ... */
-
- /* VADC node */
- pmic_vadc: vadc@3100 {
- compatible = "qcom,spmi-vadc";
- reg = <0x3100>;
- interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
- #address-cells = <1>;
- #size-cells = <0>;
- #io-channel-cells = <1>;
- io-channel-ranges;
-
- /* Channel node */
- adc-chan@VADC_LR_MUX10_USB_ID {
- reg = <VADC_LR_MUX10_USB_ID>;
- qcom,decimation = <512>;
- qcom,ratiometric;
- qcom,hw-settle-time = <200>;
- qcom,avg-samples = <1>;
- qcom,pre-scaling = <1 3>;
- };
- };
-
- /* IIO client node */
- usb {
- io-channels = <&pmic_vadc VADC_LR_MUX10_USB_ID>;
- io-channel-names = "vadc";
- };
diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml
new file mode 100644
index 0000000..de8d243
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml
@@ -0,0 +1,252 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/qcom,spmi-vadc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm's SPMI PMIC ADC
+
+maintainers:
+ - Andy Gross <agross@kernel.org>
+ - Bjorn Andersson <bjorn.andersson@linaro.org>
+
+description: |
+ SPMI PMIC voltage ADC (VADC) provides interface to clients to read
+ voltage. The VADC is a 15-bit sigma-delta ADC.
+ SPMI PMIC5 voltage ADC (ADC) provides interface to clients to read
+ voltage. The VADC is a 16-bit sigma-delta ADC.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: qcom,pms405-adc
+ - const: qcom,spmi-adc-rev2
+
+ - items:
+ - enum:
+ - qcom,spmi-vadc
+ - qcom,spmi-adc5
+ - qcom,spmi-adc-rev2
+
+ reg:
+ description: VADC base address in the SPMI PMIC register map
+ maxItems: 1
+
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+ '#io-channel-cells':
+ const: 1
+
+ interrupts:
+ maxItems: 1
+ description:
+ End of conversion interrupt.
+
+required:
+ - compatible
+ - reg
+ - '#address-cells'
+ - '#size-cells'
+ - '#io-channel-cells'
+
+patternProperties:
+ "^.*@[0-9a-f]+$":
+ type: object
+ description: |
+ Represents the external channels which are connected to the ADC.
+ For compatible property "qcom,spmi-vadc" following channels, also known as
+ reference point channels, are used for result calibration and their channel
+ configuration nodes should be defined:
+ VADC_REF_625MV and/or VADC_SPARE1(based on PMIC version) VADC_REF_1250MV,
+ VADC_GND_REF and VADC_VDD_VADC.
+
+ properties:
+ reg:
+ description: |
+ ADC channel number.
+ See include/dt-bindings/iio/qcom,spmi-vadc.h
+
+ label:
+ $ref: /schemas/types.yaml#/definitions/string
+ description: |
+ ADC input of the platform as seen in the schematics.
+ For thermistor inputs connected to generic AMUX or GPIO inputs
+ these can vary across platform for the same pins. Hence select
+ the platform schematics name for this channel.
+
+ qcom,decimation:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ This parameter is used to decrease ADC sampling rate.
+ Quicker measurements can be made by reducing decimation ratio.
+
+ qcom,pre-scaling:
+ description: |
+ Used for scaling the channel input signal before the signal is
+ fed to VADC. The configuration for this node is to know the
+ pre-determined ratio and use it for post scaling. It is a pair of
+ integers, denoting the numerator and denominator of the fraction by which
+ input signal is multiplied. For example, <1 3> indicates the signal is scaled
+ down to 1/3 of its value before ADC measurement.
+ If property is not found default value depending on chip will be used.
+ allOf:
+ - $ref: /schemas/types.yaml#/definitions/uint32-array
+ oneOf:
+ - items:
+ - const: 1
+ - enum: [ 1, 3, 4, 6, 20, 8, 10 ]
+
+ - items:
+ - const: 10
+ - const: 81
+
+ qcom,ratiometric:
+ description: |
+ Channel calibration type.
+ - For compatible property "qcom,spmi-vadc", if this property is
+ specified VADC will use the VDD reference (1.8V) and GND for
+ channel calibration. If property is not found, channel will be
+ calibrated with 0.625V and 1.25V reference channels, also
+ known as absolute calibration.
+ - For compatible property "qcom,spmi-adc5" and "qcom,spmi-adc-rev2",
+ if this property is specified VADC will use the VDD reference (1.875V)
+ and GND for channel calibration. If property is not found, channel
+ will be calibrated with 0V and 1.25V reference channels, also known
+ as absolute calibration.
+ type: boolean
+
+ qcom,hw-settle-time:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Time between AMUX getting configured and the ADC starting
+ conversion. The 'hw_settle_time' is an index used from valid values
+ and programmed in hardware to achieve the hardware settling delay.
+
+ qcom,avg-samples:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Number of samples to be used for measurement.
+ Averaging provides the option to obtain a single measurement
+ from the ADC that is an average of multiple samples. The value
+ selected is 2^(value).
+
+ required:
+ - reg
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: qcom,spmi-vadc
+
+ then:
+ patternProperties:
+ "^.*@[0-9a-f]+$":
+ properties:
+ qcom,decimation:
+ enum: [ 512, 1024, 2048, 4096 ]
+ default: 512
+
+ qcom,hw-settle-time:
+ enum: [ 0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1, 2,
+ 4, 6, 8, 10 ]
+ default: 0
+
+ qcom,avg-samples:
+ enum: [ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 ]
+ default: 1
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: qcom,spmi-adc-rev2
+
+ then:
+ patternProperties:
+ "^.*@[0-9a-f]+$":
+ properties:
+ qcom,decimation:
+ enum: [ 256, 512, 1024 ]
+ default: 1024
+
+ qcom,hw-settle-time:
+ enum: [ 0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1, 2,
+ 4, 6, 8, 10 ]
+ default: 0
+
+ qcom,avg-samples:
+ enum: [ 1, 2, 4, 8, 16 ]
+ default: 1
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: qcom,spmi-adc5
+
+ then:
+ patternProperties:
+ "^.*@[0-9a-f]+$":
+ properties:
+ qcom,decimation:
+ enum: [ 250, 420, 840 ]
+ default: 840
+
+ qcom,hw-settle-time:
+ enum: [ 15, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1, 2,
+ 4, 6, 8, 10, 16, 32, 64, 128 ]
+ default: 15
+
+ qcom,avg-samples:
+ enum: [ 1, 2, 4, 8, 16 ]
+ default: 1
+
+examples:
+ - |
+ spmi_bus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /* VADC node */
+ pmic_vadc: adc@3100 {
+ compatible = "qcom,spmi-vadc";
+ reg = <0x3100>;
+ interrupts = <0x0 0x31 0x0 0x1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #io-channel-cells = <1>;
+ io-channel-ranges;
+
+ /* Channel node */
+ adc-chan@39 {
+ reg = <0x39>;
+ qcom,decimation = <512>;
+ qcom,ratiometric;
+ qcom,hw-settle-time = <200>;
+ qcom,avg-samples = <1>;
+ qcom,pre-scaling = <1 3>;
+ };
+
+ adc-chan@9 {
+ reg = <0x9>;
+ };
+
+ adc-chan@a {
+ reg = <0xa>;
+ };
+
+ adc-chan@e {
+ reg = <0xe>;
+ };
+
+ adc-chan@f {
+ reg = <0xf>;
+ };
+ };
+ };
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related
* [PATCH V4 2/5] iio: adc: Add PMIC7 ADC bindings
From: Jishnu Prakash @ 2020-05-13 9:22 UTC (permalink / raw)
To: agross, bjorn.andersson, devicetree, linux-kernel, mka,
linus.walleij, Jonathan.Cameron, andy.shevchenko, amit.kucheria,
smohanad, kgunda, aghayal, Jonathan Cameron, Hartmut Knaack,
Lars-Peter Clausen, Peter Meerwald-Stadler, Rob Herring,
Mark Rutland, Jishnu Prakash, Amit Kucheria, linux-iio,
linux-arm-msm
Cc: linux-arm-msm-owner
In-Reply-To: <1589361736-816-1-git-send-email-jprakash@codeaurora.org>
Add documentation for PMIC7 ADC peripheral.
For the PMIC7-type PMICs, ADC peripheral is present in HW for the
following PMICs: PMK8350, PM8350, PM8350b, PMR735a and PMR735b.
Of these, only the ADC peripheral on PMK8350 is exposed directly to SW.
If SW needs to communicate with ADCs on other PMICs, it specifies the
PMIC to PMK8350 through the newly added SID register and communication
between PMK8350 ADC and other PMIC ADCs is carried out through
PBS(Programmable Boot Sequence) at the firmware level.
In addition, add definitions for ADC channels and virtual channel
definitions (combination of ADC channel number and PMIC SID number)
per PMIC, to be used by ADC clients for PMIC7.
Signed-off-by: Jishnu Prakash <jprakash@codeaurora.org>
Reviewed-by: Amit Kucheria <amit.kucheria@linaro.org>
Reviewed-by: Rob Herring <robh@kernel.org>
---
.../bindings/iio/adc/qcom,spmi-vadc.yaml | 38 ++++++++--
include/dt-bindings/iio/qcom,spmi-adc7-pm8350.h | 67 ++++++++++++++++
include/dt-bindings/iio/qcom,spmi-adc7-pm8350b.h | 88 ++++++++++++++++++++++
include/dt-bindings/iio/qcom,spmi-adc7-pmk8350.h | 46 +++++++++++
include/dt-bindings/iio/qcom,spmi-adc7-pmr735a.h | 28 +++++++
include/dt-bindings/iio/qcom,spmi-adc7-pmr735b.h | 28 +++++++
include/dt-bindings/iio/qcom,spmi-vadc.h | 78 ++++++++++++++++++-
7 files changed, 366 insertions(+), 7 deletions(-)
create mode 100644 include/dt-bindings/iio/qcom,spmi-adc7-pm8350.h
create mode 100644 include/dt-bindings/iio/qcom,spmi-adc7-pm8350b.h
create mode 100644 include/dt-bindings/iio/qcom,spmi-adc7-pmk8350.h
create mode 100644 include/dt-bindings/iio/qcom,spmi-adc7-pmr735a.h
create mode 100644 include/dt-bindings/iio/qcom,spmi-adc7-pmr735b.h
diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml
index de8d243..e6263b6 100644
--- a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml
@@ -13,7 +13,7 @@ maintainers:
description: |
SPMI PMIC voltage ADC (VADC) provides interface to clients to read
voltage. The VADC is a 15-bit sigma-delta ADC.
- SPMI PMIC5 voltage ADC (ADC) provides interface to clients to read
+ SPMI PMIC5/PMIC7 voltage ADC (ADC) provides interface to clients to read
voltage. The VADC is a 16-bit sigma-delta ADC.
properties:
@@ -28,6 +28,7 @@ properties:
- qcom,spmi-vadc
- qcom,spmi-adc5
- qcom,spmi-adc-rev2
+ - qcom,spmi-adc7
reg:
description: VADC base address in the SPMI PMIC register map
@@ -70,6 +71,8 @@ patternProperties:
description: |
ADC channel number.
See include/dt-bindings/iio/qcom,spmi-vadc.h
+ For PMIC7 ADC, the channel numbers are specified separately per PMIC
+ in the PMIC-specific files in include/dt-bindings/iio/.
label:
$ref: /schemas/types.yaml#/definitions/string
@@ -113,11 +116,11 @@ patternProperties:
channel calibration. If property is not found, channel will be
calibrated with 0.625V and 1.25V reference channels, also
known as absolute calibration.
- - For compatible property "qcom,spmi-adc5" and "qcom,spmi-adc-rev2",
- if this property is specified VADC will use the VDD reference (1.875V)
- and GND for channel calibration. If property is not found, channel
- will be calibrated with 0V and 1.25V reference channels, also known
- as absolute calibration.
+ - For compatible property "qcom,spmi-adc5", "qcom,spmi-adc7" and
+ "qcom,spmi-adc-rev2", if this property is specified VADC will use
+ the VDD reference (1.875V) and GND for channel calibration. If
+ property is not found, channel will be calibrated with 0V and 1.25V
+ reference channels, also known as absolute calibration.
type: boolean
qcom,hw-settle-time:
@@ -208,6 +211,29 @@ allOf:
enum: [ 1, 2, 4, 8, 16 ]
default: 1
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: qcom,spmi-adc7
+
+ then:
+ patternProperties:
+ "^.*@[0-9a-f]+$":
+ properties:
+ qcom,decimation:
+ enum: [ 85, 340, 1360 ]
+ default: 1360
+
+ qcom,hw-settle-time:
+ enum: [ 15, 100, 200, 300, 400, 500, 600, 700, 1000, 2000, 4000,
+ 8000, 16000, 32000, 64000, 128000 ]
+ default: 15
+
+ qcom,avg-samples:
+ enum: [ 1, 2, 4, 8, 16 ]
+ default: 1
+
examples:
- |
spmi_bus {
diff --git a/include/dt-bindings/iio/qcom,spmi-adc7-pm8350.h b/include/dt-bindings/iio/qcom,spmi-adc7-pm8350.h
new file mode 100644
index 0000000..9426f27
--- /dev/null
+++ b/include/dt-bindings/iio/qcom,spmi-adc7-pm8350.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_QCOM_SPMI_VADC_PM8350_H
+#define _DT_BINDINGS_QCOM_SPMI_VADC_PM8350_H
+
+#ifndef PM8350_SID
+#define PM8350_SID 1
+#endif
+
+/* ADC channels for PM8350_ADC for PMIC7 */
+#define PM8350_ADC7_REF_GND (PM8350_SID << 8 | 0x0)
+#define PM8350_ADC7_1P25VREF (PM8350_SID << 8 | 0x01)
+#define PM8350_ADC7_VREF_VADC (PM8350_SID << 8 | 0x02)
+#define PM8350_ADC7_DIE_TEMP (PM8350_SID << 8 | 0x03)
+
+#define PM8350_ADC7_AMUX_THM1 (PM8350_SID << 8 | 0x04)
+#define PM8350_ADC7_AMUX_THM2 (PM8350_SID << 8 | 0x05)
+#define PM8350_ADC7_AMUX_THM3 (PM8350_SID << 8 | 0x06)
+#define PM8350_ADC7_AMUX_THM4 (PM8350_SID << 8 | 0x07)
+#define PM8350_ADC7_AMUX_THM5 (PM8350_SID << 8 | 0x08)
+#define PM8350_ADC7_GPIO1 (PM8350_SID << 8 | 0x0a)
+#define PM8350_ADC7_GPIO2 (PM8350_SID << 8 | 0x0b)
+#define PM8350_ADC7_GPIO3 (PM8350_SID << 8 | 0x0c)
+#define PM8350_ADC7_GPIO4 (PM8350_SID << 8 | 0x0d)
+
+/* 30k pull-up1 */
+#define PM8350_ADC7_AMUX_THM1_30K_PU (PM8350_SID << 8 | 0x24)
+#define PM8350_ADC7_AMUX_THM2_30K_PU (PM8350_SID << 8 | 0x25)
+#define PM8350_ADC7_AMUX_THM3_30K_PU (PM8350_SID << 8 | 0x26)
+#define PM8350_ADC7_AMUX_THM4_30K_PU (PM8350_SID << 8 | 0x27)
+#define PM8350_ADC7_AMUX_THM5_30K_PU (PM8350_SID << 8 | 0x28)
+#define PM8350_ADC7_GPIO1_30K_PU (PM8350_SID << 8 | 0x2a)
+#define PM8350_ADC7_GPIO2_30K_PU (PM8350_SID << 8 | 0x2b)
+#define PM8350_ADC7_GPIO3_30K_PU (PM8350_SID << 8 | 0x2c)
+#define PM8350_ADC7_GPIO4_30K_PU (PM8350_SID << 8 | 0x2d)
+
+/* 100k pull-up2 */
+#define PM8350_ADC7_AMUX_THM1_100K_PU (PM8350_SID << 8 | 0x44)
+#define PM8350_ADC7_AMUX_THM2_100K_PU (PM8350_SID << 8 | 0x45)
+#define PM8350_ADC7_AMUX_THM3_100K_PU (PM8350_SID << 8 | 0x46)
+#define PM8350_ADC7_AMUX_THM4_100K_PU (PM8350_SID << 8 | 0x47)
+#define PM8350_ADC7_AMUX_THM5_100K_PU (PM8350_SID << 8 | 0x48)
+#define PM8350_ADC7_GPIO1_100K_PU (PM8350_SID << 8 | 0x4a)
+#define PM8350_ADC7_GPIO2_100K_PU (PM8350_SID << 8 | 0x4b)
+#define PM8350_ADC7_GPIO3_100K_PU (PM8350_SID << 8 | 0x4c)
+#define PM8350_ADC7_GPIO4_100K_PU (PM8350_SID << 8 | 0x4d)
+
+/* 400k pull-up3 */
+#define PM8350_ADC7_AMUX_THM1_400K_PU (PM8350_SID << 8 | 0x64)
+#define PM8350_ADC7_AMUX_THM2_400K_PU (PM8350_SID << 8 | 0x65)
+#define PM8350_ADC7_AMUX_THM3_400K_PU (PM8350_SID << 8 | 0x66)
+#define PM8350_ADC7_AMUX_THM4_400K_PU (PM8350_SID << 8 | 0x67)
+#define PM8350_ADC7_AMUX_THM5_400K_PU (PM8350_SID << 8 | 0x68)
+#define PM8350_ADC7_GPIO1_400K_PU (PM8350_SID << 8 | 0x6a)
+#define PM8350_ADC7_GPIO2_400K_PU (PM8350_SID << 8 | 0x6b)
+#define PM8350_ADC7_GPIO3_400K_PU (PM8350_SID << 8 | 0x6c)
+#define PM8350_ADC7_GPIO4_400K_PU (PM8350_SID << 8 | 0x6d)
+
+/* 1/3 Divider */
+#define PM8350_ADC7_GPIO4_DIV3 (PM8350_SID << 8 | 0x8d)
+
+#define PM8350_ADC7_VPH_PWR (PM8350_SID << 8 | 0x8e)
+
+#endif /* _DT_BINDINGS_QCOM_SPMI_VADC_PM8350_H */
diff --git a/include/dt-bindings/iio/qcom,spmi-adc7-pm8350b.h b/include/dt-bindings/iio/qcom,spmi-adc7-pm8350b.h
new file mode 100644
index 0000000..dc2497c
--- /dev/null
+++ b/include/dt-bindings/iio/qcom,spmi-adc7-pm8350b.h
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_QCOM_SPMI_VADC_PM8350B_H
+#define _DT_BINDINGS_QCOM_SPMI_VADC_PM8350B_H
+
+#ifndef PM8350B_SID
+#define PM8350B_SID 3
+#endif
+
+/* ADC channels for PM8350B_ADC for PMIC7 */
+#define PM8350B_ADC7_REF_GND (PM8350B_SID << 8 | 0x0)
+#define PM8350B_ADC7_1P25VREF (PM8350B_SID << 8 | 0x01)
+#define PM8350B_ADC7_VREF_VADC (PM8350B_SID << 8 | 0x02)
+#define PM8350B_ADC7_DIE_TEMP (PM8350B_SID << 8 | 0x03)
+
+#define PM8350B_ADC7_AMUX_THM1 (PM8350B_SID << 8 | 0x04)
+#define PM8350B_ADC7_AMUX_THM2 (PM8350B_SID << 8 | 0x05)
+#define PM8350B_ADC7_AMUX_THM3 (PM8350B_SID << 8 | 0x06)
+#define PM8350B_ADC7_AMUX_THM4 (PM8350B_SID << 8 | 0x07)
+#define PM8350B_ADC7_AMUX_THM5 (PM8350B_SID << 8 | 0x08)
+#define PM8350B_ADC7_AMUX_THM6 (PM8350B_SID << 8 | 0x09)
+#define PM8350B_ADC7_GPIO1 (PM8350B_SID << 8 | 0x0a)
+#define PM8350B_ADC7_GPIO2 (PM8350B_SID << 8 | 0x0b)
+#define PM8350B_ADC7_GPIO3 (PM8350B_SID << 8 | 0x0c)
+#define PM8350B_ADC7_GPIO4 (PM8350B_SID << 8 | 0x0d)
+
+#define PM8350B_ADC7_CHG_TEMP (PM8350B_SID << 8 | 0x10)
+#define PM8350B_ADC7_USB_IN_V_16 (PM8350B_SID << 8 | 0x11)
+#define PM8350B_ADC7_VDC_16 (PM8350B_SID << 8 | 0x12)
+#define PM8350B_ADC7_CC1_ID (PM8350B_SID << 8 | 0x13)
+#define PM8350B_ADC7_VREF_BAT_THERM (PM8350B_SID << 8 | 0x15)
+#define PM8350B_ADC7_IIN_FB (PM8350B_SID << 8 | 0x17)
+
+/* 30k pull-up1 */
+#define PM8350B_ADC7_AMUX_THM1_30K_PU (PM8350B_SID << 8 | 0x24)
+#define PM8350B_ADC7_AMUX_THM2_30K_PU (PM8350B_SID << 8 | 0x25)
+#define PM8350B_ADC7_AMUX_THM3_30K_PU (PM8350B_SID << 8 | 0x26)
+#define PM8350B_ADC7_AMUX_THM4_30K_PU (PM8350B_SID << 8 | 0x27)
+#define PM8350B_ADC7_AMUX_THM5_30K_PU (PM8350B_SID << 8 | 0x28)
+#define PM8350B_ADC7_AMUX_THM6_30K_PU (PM8350B_SID << 8 | 0x29)
+#define PM8350B_ADC7_GPIO1_30K_PU (PM8350B_SID << 8 | 0x2a)
+#define PM8350B_ADC7_GPIO2_30K_PU (PM8350B_SID << 8 | 0x2b)
+#define PM8350B_ADC7_GPIO3_30K_PU (PM8350B_SID << 8 | 0x2c)
+#define PM8350B_ADC7_GPIO4_30K_PU (PM8350B_SID << 8 | 0x2d)
+#define PM8350B_ADC7_CC1_ID_30K_PU (PM8350B_SID << 8 | 0x33)
+
+/* 100k pull-up2 */
+#define PM8350B_ADC7_AMUX_THM1_100K_PU (PM8350B_SID << 8 | 0x44)
+#define PM8350B_ADC7_AMUX_THM2_100K_PU (PM8350B_SID << 8 | 0x45)
+#define PM8350B_ADC7_AMUX_THM3_100K_PU (PM8350B_SID << 8 | 0x46)
+#define PM8350B_ADC7_AMUX_THM4_100K_PU (PM8350B_SID << 8 | 0x47)
+#define PM8350B_ADC7_AMUX_THM5_100K_PU (PM8350B_SID << 8 | 0x48)
+#define PM8350B_ADC7_AMUX_THM6_100K_PU (PM8350B_SID << 8 | 0x49)
+#define PM8350B_ADC7_GPIO1_100K_PU (PM8350B_SID << 8 | 0x4a)
+#define PM8350B_ADC7_GPIO2_100K_PU (PM8350B_SID << 8 | 0x4b)
+#define PM8350B_ADC7_GPIO3_100K_PU (PM8350B_SID << 8 | 0x4c)
+#define PM8350B_ADC7_GPIO4_100K_PU (PM8350B_SID << 8 | 0x4d)
+#define PM8350B_ADC7_CC1_ID_100K_PU (PM8350B_SID << 8 | 0x53)
+
+/* 400k pull-up3 */
+#define PM8350B_ADC7_AMUX_THM1_400K_PU (PM8350B_SID << 8 | 0x64)
+#define PM8350B_ADC7_AMUX_THM2_400K_PU (PM8350B_SID << 8 | 0x65)
+#define PM8350B_ADC7_AMUX_THM3_400K_PU (PM8350B_SID << 8 | 0x66)
+#define PM8350B_ADC7_AMUX_THM4_400K_PU (PM8350B_SID << 8 | 0x67)
+#define PM8350B_ADC7_AMUX_THM5_400K_PU (PM8350B_SID << 8 | 0x68)
+#define PM8350B_ADC7_AMUX_THM6_400K_PU (PM8350B_SID << 8 | 0x69)
+#define PM8350B_ADC7_GPIO1_400K_PU (PM8350B_SID << 8 | 0x6a)
+#define PM8350B_ADC7_GPIO2_400K_PU (PM8350B_SID << 8 | 0x6b)
+#define PM8350B_ADC7_GPIO3_400K_PU (PM8350B_SID << 8 | 0x6c)
+#define PM8350B_ADC7_GPIO4_400K_PU (PM8350B_SID << 8 | 0x6d)
+#define PM8350B_ADC7_CC1_ID_400K_PU (PM8350B_SID << 8 | 0x73)
+
+/* 1/3 Divider */
+#define PM8350B_ADC7_GPIO1_DIV3 (PM8350B_SID << 8 | 0x8a)
+#define PM8350B_ADC7_GPIO2_DIV3 (PM8350B_SID << 8 | 0x8b)
+#define PM8350B_ADC7_GPIO3_DIV3 (PM8350B_SID << 8 | 0x8c)
+#define PM8350B_ADC7_GPIO4_DIV3 (PM8350B_SID << 8 | 0x8d)
+
+#define PM8350B_ADC7_VPH_PWR (PM8350B_SID << 8 | 0x8e)
+#define PM8350B_ADC7_VBAT_SNS (PM8350B_SID << 8 | 0x8f)
+
+#define PM8350B_ADC7_SBUx (PM8350B_SID << 8 | 0x94)
+#define PM8350B_ADC7_VBAT_2S_MID (PM8350B_SID << 8 | 0x96)
+
+#endif /* _DT_BINDINGS_QCOM_SPMI_VADC_PM8350B_H */
diff --git a/include/dt-bindings/iio/qcom,spmi-adc7-pmk8350.h b/include/dt-bindings/iio/qcom,spmi-adc7-pmk8350.h
new file mode 100644
index 0000000..6c29687
--- /dev/null
+++ b/include/dt-bindings/iio/qcom,spmi-adc7-pmk8350.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_QCOM_SPMI_VADC_PMK8350_H
+#define _DT_BINDINGS_QCOM_SPMI_VADC_PMK8350_H
+
+#ifndef PMK8350_SID
+#define PMK8350_SID 0
+#endif
+
+/* ADC channels for PMK8350_ADC for PMIC7 */
+#define PMK8350_ADC7_REF_GND (PMK8350_SID << 8 | 0x0)
+#define PMK8350_ADC7_1P25VREF (PMK8350_SID << 8 | 0x01)
+#define PMK8350_ADC7_VREF_VADC (PMK8350_SID << 8 | 0x02)
+#define PMK8350_ADC7_DIE_TEMP (PMK8350_SID << 8 | 0x03)
+
+#define PMK8350_ADC7_AMUX_THM1 (PMK8350_SID << 8 | 0x04)
+#define PMK8350_ADC7_AMUX_THM2 (PMK8350_SID << 8 | 0x05)
+#define PMK8350_ADC7_AMUX_THM3 (PMK8350_SID << 8 | 0x06)
+#define PMK8350_ADC7_AMUX_THM4 (PMK8350_SID << 8 | 0x07)
+#define PMK8350_ADC7_AMUX_THM5 (PMK8350_SID << 8 | 0x08)
+
+/* 30k pull-up1 */
+#define PMK8350_ADC7_AMUX_THM1_30K_PU (PMK8350_SID << 8 | 0x24)
+#define PMK8350_ADC7_AMUX_THM2_30K_PU (PMK8350_SID << 8 | 0x25)
+#define PMK8350_ADC7_AMUX_THM3_30K_PU (PMK8350_SID << 8 | 0x26)
+#define PMK8350_ADC7_AMUX_THM4_30K_PU (PMK8350_SID << 8 | 0x27)
+#define PMK8350_ADC7_AMUX_THM5_30K_PU (PMK8350_SID << 8 | 0x28)
+
+/* 100k pull-up2 */
+#define PMK8350_ADC7_AMUX_THM1_100K_PU (PMK8350_SID << 8 | 0x44)
+#define PMK8350_ADC7_AMUX_THM2_100K_PU (PMK8350_SID << 8 | 0x45)
+#define PMK8350_ADC7_AMUX_THM3_100K_PU (PMK8350_SID << 8 | 0x46)
+#define PMK8350_ADC7_AMUX_THM4_100K_PU (PMK8350_SID << 8 | 0x47)
+#define PMK8350_ADC7_AMUX_THM5_100K_PU (PMK8350_SID << 8 | 0x48)
+
+/* 400k pull-up3 */
+#define PMK8350_ADC7_AMUX_THM1_400K_PU (PMK8350_SID << 8 | 0x64)
+#define PMK8350_ADC7_AMUX_THM2_400K_PU (PMK8350_SID << 8 | 0x65)
+#define PMK8350_ADC7_AMUX_THM3_400K_PU (PMK8350_SID << 8 | 0x66)
+#define PMK8350_ADC7_AMUX_THM4_400K_PU (PMK8350_SID << 8 | 0x67)
+#define PMK8350_ADC7_AMUX_THM5_400K_PU (PMK8350_SID << 8 | 0x68)
+
+#endif /* _DT_BINDINGS_QCOM_SPMI_VADC_PMK8350_H */
diff --git a/include/dt-bindings/iio/qcom,spmi-adc7-pmr735a.h b/include/dt-bindings/iio/qcom,spmi-adc7-pmr735a.h
new file mode 100644
index 0000000..d6df1b1
--- /dev/null
+++ b/include/dt-bindings/iio/qcom,spmi-adc7-pmr735a.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_QCOM_SPMI_VADC_PMR735A_H
+#define _DT_BINDINGS_QCOM_SPMI_VADC_PMR735A_H
+
+#ifndef PMR735A_SID
+#define PMR735A_SID 4
+#endif
+
+/* ADC channels for PMR735A_ADC for PMIC7 */
+#define PMR735A_ADC7_REF_GND (PMR735A_SID << 8 | 0x0)
+#define PMR735A_ADC7_1P25VREF (PMR735A_SID << 8 | 0x01)
+#define PMR735A_ADC7_VREF_VADC (PMR735A_SID << 8 | 0x02)
+#define PMR735A_ADC7_DIE_TEMP (PMR735A_SID << 8 | 0x03)
+
+#define PMR735A_ADC7_GPIO1 (PMR735A_SID << 8 | 0x0a)
+#define PMR735A_ADC7_GPIO2 (PMR735A_SID << 8 | 0x0b)
+#define PMR735A_ADC7_GPIO3 (PMR735A_SID << 8 | 0x0c)
+
+/* 100k pull-up2 */
+#define PMR735A_ADC7_GPIO1_100K_PU (PMR735A_SID << 8 | 0x4a)
+#define PMR735A_ADC7_GPIO2_100K_PU (PMR735A_SID << 8 | 0x4b)
+#define PMR735A_ADC7_GPIO3_100K_PU (PMR735A_SID << 8 | 0x4c)
+
+#endif /* _DT_BINDINGS_QCOM_SPMI_VADC_PMR735A_H */
diff --git a/include/dt-bindings/iio/qcom,spmi-adc7-pmr735b.h b/include/dt-bindings/iio/qcom,spmi-adc7-pmr735b.h
new file mode 100644
index 0000000..8da0e7d
--- /dev/null
+++ b/include/dt-bindings/iio/qcom,spmi-adc7-pmr735b.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_QCOM_SPMI_VADC_PMR735B_H
+#define _DT_BINDINGS_QCOM_SPMI_VADC_PMR735B_H
+
+#ifndef PMR735B_SID
+#define PMR735B_SID 5
+#endif
+
+/* ADC channels for PMR735B_ADC for PMIC7 */
+#define PMR735B_ADC7_REF_GND (PMR735B_SID << 8 | 0x0)
+#define PMR735B_ADC7_1P25VREF (PMR735B_SID << 8 | 0x01)
+#define PMR735B_ADC7_VREF_VADC (PMR735B_SID << 8 | 0x02)
+#define PMR735B_ADC7_DIE_TEMP (PMR735B_SID << 8 | 0x03)
+
+#define PMR735B_ADC7_GPIO1 (PMR735B_SID << 8 | 0x0a)
+#define PMR735B_ADC7_GPIO2 (PMR735B_SID << 8 | 0x0b)
+#define PMR735B_ADC7_GPIO3 (PMR735B_SID << 8 | 0x0c)
+
+/* 100k pull-up2 */
+#define PMR735B_ADC7_GPIO1_100K_PU (PMR735B_SID << 8 | 0x4a)
+#define PMR735B_ADC7_GPIO2_100K_PU (PMR735B_SID << 8 | 0x4b)
+#define PMR735B_ADC7_GPIO3_100K_PU (PMR735B_SID << 8 | 0x4c)
+
+#endif /* _DT_BINDINGS_QCOM_SPMI_VADC_PMR735B_H */
diff --git a/include/dt-bindings/iio/qcom,spmi-vadc.h b/include/dt-bindings/iio/qcom,spmi-vadc.h
index 61d556d..08adfe2 100644
--- a/include/dt-bindings/iio/qcom,spmi-vadc.h
+++ b/include/dt-bindings/iio/qcom,spmi-vadc.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (c) 2012-2014,2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014,2018,2020 The Linux Foundation. All rights reserved.
*/
#ifndef _DT_BINDINGS_QCOM_SPMI_VADC_H
@@ -221,4 +221,80 @@
#define ADC5_MAX_CHANNEL 0xc0
+/* ADC channels for ADC for PMIC7 */
+
+#define ADC7_REF_GND 0x00
+#define ADC7_1P25VREF 0x01
+#define ADC7_VREF_VADC 0x02
+#define ADC7_DIE_TEMP 0x03
+
+#define ADC7_AMUX_THM1 0x04
+#define ADC7_AMUX_THM2 0x05
+#define ADC7_AMUX_THM3 0x06
+#define ADC7_AMUX_THM4 0x07
+#define ADC7_AMUX_THM5 0x08
+#define ADC7_AMUX_THM6 0x09
+#define ADC7_GPIO1 0x0a
+#define ADC7_GPIO2 0x0b
+#define ADC7_GPIO3 0x0c
+#define ADC7_GPIO4 0x0d
+
+#define ADC7_CHG_TEMP 0x10
+#define ADC7_USB_IN_V_16 0x11
+#define ADC7_VDC_16 0x12
+#define ADC7_CC1_ID 0x13
+#define ADC7_VREF_BAT_THERM 0x15
+#define ADC7_IIN_FB 0x17
+
+/* 30k pull-up1 */
+#define ADC7_AMUX_THM1_30K_PU 0x24
+#define ADC7_AMUX_THM2_30K_PU 0x25
+#define ADC7_AMUX_THM3_30K_PU 0x26
+#define ADC7_AMUX_THM4_30K_PU 0x27
+#define ADC7_AMUX_THM5_30K_PU 0x28
+#define ADC7_AMUX_THM6_30K_PU 0x29
+#define ADC7_GPIO1_30K_PU 0x2a
+#define ADC7_GPIO2_30K_PU 0x2b
+#define ADC7_GPIO3_30K_PU 0x2c
+#define ADC7_GPIO4_30K_PU 0x2d
+#define ADC7_CC1_ID_30K_PU 0x33
+
+/* 100k pull-up2 */
+#define ADC7_AMUX_THM1_100K_PU 0x44
+#define ADC7_AMUX_THM2_100K_PU 0x45
+#define ADC7_AMUX_THM3_100K_PU 0x46
+#define ADC7_AMUX_THM4_100K_PU 0x47
+#define ADC7_AMUX_THM5_100K_PU 0x48
+#define ADC7_AMUX_THM6_100K_PU 0x49
+#define ADC7_GPIO1_100K_PU 0x4a
+#define ADC7_GPIO2_100K_PU 0x4b
+#define ADC7_GPIO3_100K_PU 0x4c
+#define ADC7_GPIO4_100K_PU 0x4d
+#define ADC7_CC1_ID_100K_PU 0x53
+
+/* 400k pull-up3 */
+#define ADC7_AMUX_THM1_400K_PU 0x64
+#define ADC7_AMUX_THM2_400K_PU 0x65
+#define ADC7_AMUX_THM3_400K_PU 0x66
+#define ADC7_AMUX_THM4_400K_PU 0x67
+#define ADC7_AMUX_THM5_400K_PU 0x68
+#define ADC7_AMUX_THM6_400K_PU 0x69
+#define ADC7_GPIO1_400K_PU 0x6a
+#define ADC7_GPIO2_400K_PU 0x6b
+#define ADC7_GPIO3_400K_PU 0x6c
+#define ADC7_GPIO4_400K_PU 0x6d
+#define ADC7_CC1_ID_400K_PU 0x73
+
+/* 1/3 Divider */
+#define ADC7_GPIO1_DIV3 0x8a
+#define ADC7_GPIO2_DIV3 0x8b
+#define ADC7_GPIO3_DIV3 0x8c
+#define ADC7_GPIO4_DIV3 0x8d
+
+#define ADC7_VPH_PWR 0x8e
+#define ADC7_VBAT_SNS 0x8f
+
+#define ADC7_SBUx 0x94
+#define ADC7_VBAT_2S_MID 0x96
+
#endif /* _DT_BINDINGS_QCOM_SPMI_VADC_H */
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related
* [PATCH V4 3/5] iio: adc: Add support for PMIC7 ADC
From: Jishnu Prakash @ 2020-05-13 9:22 UTC (permalink / raw)
To: agross, bjorn.andersson, devicetree, linux-kernel, mka,
linus.walleij, Jonathan.Cameron, andy.shevchenko, amit.kucheria,
smohanad, kgunda, aghayal, Jonathan Cameron, Hartmut Knaack,
Lars-Peter Clausen, Peter Meerwald-Stadler, linux-arm-msm,
linux-iio
Cc: linux-arm-msm-owner, Jishnu Prakash
In-Reply-To: <1589361736-816-1-git-send-email-jprakash@codeaurora.org>
The ADC architecture on PMIC7 is changed as compared to PMIC5. The
major change from PMIC5 is that all SW communication to ADC goes through
PMK8350, which communicates with other PMICs through PBS when the ADC
on PMK8350 works in master mode. The SID register is used to identify the
PMICs with which the PBS needs to communicate. Add support for the same.
Signed-off-by: Jishnu Prakash <jprakash@codeaurora.org>
---
drivers/iio/adc/qcom-spmi-adc5.c | 225 +++++++++++++++++++++++++++++++-
drivers/iio/adc/qcom-vadc-common.c | 260 +++++++++++++++++++++++++++++++++++++
drivers/iio/adc/qcom-vadc-common.h | 14 ++
3 files changed, 495 insertions(+), 4 deletions(-)
diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c
index 21fdcde..6d6b611 100644
--- a/drivers/iio/adc/qcom-spmi-adc5.c
+++ b/drivers/iio/adc/qcom-spmi-adc5.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved.
*/
#include <linux/bitops.h>
@@ -23,6 +23,7 @@
#define ADC5_USR_REVISION1 0x0
#define ADC5_USR_STATUS1 0x8
+#define ADC5_USR_STATUS1_CONV_FAULT BIT(7)
#define ADC5_USR_STATUS1_REQ_STS BIT(1)
#define ADC5_USR_STATUS1_EOC BIT(0)
#define ADC5_USR_STATUS1_REQ_STS_EOC_MASK 0x3
@@ -65,6 +66,9 @@
#define ADC5_USR_IBAT_DATA1 0x53
+#define ADC_CHANNEL_OFFSET 0x8
+#define ADC_CHANNEL_MASK GENMASK(7, 0)
+
/*
* Conversion time varies based on the decimation, clock rate, fast average
* samples and measurements queued across different VADC peripherals.
@@ -79,6 +83,11 @@
#define ADC5_HW_SETTLE_DIFF_MINOR 3
#define ADC5_HW_SETTLE_DIFF_MAJOR 5
+/* For PMIC7 */
+#define ADC_APP_SID 0x40
+#define ADC_APP_SID_MASK GENMASK(3, 0)
+#define ADC7_CONV_TIMEOUT msecs_to_jiffies(10)
+
enum adc5_cal_method {
ADC5_NO_CAL = 0,
ADC5_RATIOMETRIC_CAL,
@@ -96,6 +105,7 @@ enum adc5_cal_val {
* @cal_method: calibration method.
* @cal_val: calibration value
* @decimation: sampling rate supported for the channel.
+ * @sid: slave id of PMIC owning the channel, for PMIC7.
* @prescale: channel scaling performed on the input signal.
* @hw_settle_time: the time between AMUX being configured and the
* start of conversion.
@@ -110,6 +120,7 @@ struct adc5_channel_prop {
enum adc5_cal_method cal_method;
enum adc5_cal_val cal_val;
unsigned int decimation;
+ unsigned int sid;
unsigned int prescale;
unsigned int hw_settle_time;
unsigned int avg_samples;
@@ -140,6 +151,7 @@ struct adc5_chip {
bool poll_eoc;
struct completion complete;
struct mutex lock;
+ int irq_eoc;
const struct adc5_data *data;
};
@@ -155,6 +167,8 @@ static const struct vadc_prescale_ratio adc5_prescale_ratios[] = {
{.num = 1, .den = 16}
};
+static const struct adc5_data adc7_data_pmic;
+
static int adc5_read(struct adc5_chip *adc, u16 offset, u8 *data, int len)
{
return regmap_bulk_read(adc->regmap, adc->base + offset, data, len);
@@ -165,6 +179,11 @@ static int adc5_write(struct adc5_chip *adc, u16 offset, u8 *data, int len)
return regmap_bulk_write(adc->regmap, adc->base + offset, data, len);
}
+static int adc5_masked_write(struct adc5_chip *adc, u16 offset, u8 mask, u8 val)
+{
+ return regmap_update_bits(adc->regmap, adc->base + offset, mask, val);
+}
+
static int adc5_prescaling_from_dt(u32 num, u32 den)
{
unsigned int pre;
@@ -314,6 +333,47 @@ static int adc5_configure(struct adc5_chip *adc,
return adc5_write(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf));
}
+static int adc7_configure(struct adc5_chip *adc,
+ struct adc5_channel_prop *prop)
+{
+ int ret;
+ u8 conv_req = 0, buf[4];
+
+ ret = adc5_masked_write(adc, ADC_APP_SID, ADC_APP_SID_MASK, prop->sid);
+ if (ret)
+ return ret;
+
+ ret = adc5_read(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf));
+ if (ret < 0)
+ return ret;
+
+ /* Digital param selection */
+ adc5_update_dig_param(adc, prop, &buf[0]);
+
+ /* Update fast average sample value */
+ buf[1] &= ~ADC5_USR_FAST_AVG_CTL_SAMPLES_MASK;
+ buf[1] |= prop->avg_samples;
+
+ /* Select ADC channel */
+ buf[2] = prop->channel;
+
+ /* Select HW settle delay for channel */
+ buf[3] &= ~ADC5_USR_HW_SETTLE_DELAY_MASK;
+ buf[3] |= prop->hw_settle_time;
+
+ /* Select CONV request */
+ conv_req = ADC5_USR_CONV_REQ_REQ;
+
+ if (!adc->poll_eoc)
+ reinit_completion(&adc->complete);
+
+ ret = adc5_write(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf));
+ if (ret)
+ return ret;
+
+ return adc5_write(adc, ADC5_USR_CONV_REQ, &conv_req, 1);
+}
+
static int adc5_do_conversion(struct adc5_chip *adc,
struct adc5_channel_prop *prop,
struct iio_chan_spec const *chan,
@@ -355,6 +415,43 @@ static int adc5_do_conversion(struct adc5_chip *adc,
return ret;
}
+static int adc7_do_conversion(struct adc5_chip *adc,
+ struct adc5_channel_prop *prop,
+ struct iio_chan_spec const *chan,
+ u16 *data_volt, u16 *data_cur)
+{
+ int ret;
+ u8 status;
+
+ mutex_lock(&adc->lock);
+
+ ret = adc7_configure(adc, prop);
+ if (ret) {
+ dev_err(adc->dev, "ADC configure failed with %d\n", ret);
+ goto unlock;
+ }
+
+ /* No support for polling mode at present */
+ wait_for_completion_timeout(&adc->complete, ADC7_CONV_TIMEOUT);
+
+ ret = adc5_read(adc, ADC5_USR_STATUS1, &status, 1);
+ if (ret < 0)
+ goto unlock;
+
+ if (status & ADC5_USR_STATUS1_CONV_FAULT) {
+ dev_err(adc->dev, "Unexpected conversion fault\n");
+ ret = -EIO;
+ goto unlock;
+ }
+
+ ret = adc5_read_voltage_data(adc, data_volt);
+
+unlock:
+ mutex_unlock(&adc->lock);
+
+ return ret;
+}
+
static irqreturn_t adc5_isr(int irq, void *dev_id)
{
struct adc5_chip *adc = dev_id;
@@ -377,6 +474,22 @@ static int adc5_of_xlate(struct iio_dev *indio_dev,
return -EINVAL;
}
+static int adc7_of_xlate(struct iio_dev *indio_dev,
+ const struct of_phandle_args *iiospec)
+{
+ struct adc5_chip *adc = iio_priv(indio_dev);
+ int i, v_channel;
+
+ for (i = 0; i < adc->nchannels; i++) {
+ v_channel = (adc->chan_props[i].sid << ADC_CHANNEL_OFFSET |
+ adc->chan_props[i].channel);
+ if (v_channel == iiospec->args[0])
+ return i;
+ }
+
+ return -EINVAL;
+}
+
static int adc5_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, int *val2,
long mask)
@@ -410,11 +523,50 @@ static int adc5_read_raw(struct iio_dev *indio_dev,
return 0;
}
+static int adc7_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val, int *val2,
+ long mask)
+{
+ struct adc5_chip *adc = iio_priv(indio_dev);
+ struct adc5_channel_prop *prop;
+ u16 adc_code_volt, adc_code_cur;
+ int ret;
+
+ prop = &adc->chan_props[chan->address];
+
+ switch (mask) {
+ case IIO_CHAN_INFO_PROCESSED:
+ ret = adc7_do_conversion(adc, prop, chan,
+ &adc_code_volt, &adc_code_cur);
+ if (ret)
+ return ret;
+
+ ret = qcom_adc5_hw_scale(prop->scale_fn_type,
+ &adc5_prescale_ratios[prop->prescale],
+ adc->data,
+ adc_code_volt, val);
+
+ if (ret)
+ return ret;
+
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static const struct iio_info adc5_info = {
.read_raw = adc5_read_raw,
.of_xlate = adc5_of_xlate,
};
+static const struct iio_info adc7_info = {
+ .read_raw = adc7_read_raw,
+ .of_xlate = adc7_of_xlate,
+};
+
struct adc5_channels {
const char *datasheet_name;
unsigned int prescale_index;
@@ -477,6 +629,39 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = {
SCALE_HW_CALIB_PM5_SMB_TEMP)
};
+static const struct adc5_channels adc7_chans_pmic[ADC5_MAX_CHANNEL] = {
+ [ADC7_REF_GND] = ADC5_CHAN_VOLT("ref_gnd", 0,
+ SCALE_HW_CALIB_DEFAULT)
+ [ADC7_1P25VREF] = ADC5_CHAN_VOLT("vref_1p25", 0,
+ SCALE_HW_CALIB_DEFAULT)
+ [ADC7_VPH_PWR] = ADC5_CHAN_VOLT("vph_pwr", 1,
+ SCALE_HW_CALIB_DEFAULT)
+ [ADC7_VBAT_SNS] = ADC5_CHAN_VOLT("vbat_sns", 3,
+ SCALE_HW_CALIB_DEFAULT)
+ [ADC7_DIE_TEMP] = ADC5_CHAN_TEMP("die_temp", 0,
+ SCALE_HW_CALIB_PMIC_THERM_PM7)
+ [ADC7_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_pu2", 0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC7_AMUX_THM2_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_pu2", 0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC7_AMUX_THM3_100K_PU] = ADC5_CHAN_TEMP("amux_thm3_pu2", 0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC7_AMUX_THM4_100K_PU] = ADC5_CHAN_TEMP("amux_thm4_pu2", 0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC7_AMUX_THM5_100K_PU] = ADC5_CHAN_TEMP("amux_thm5_pu2", 0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC7_AMUX_THM6_100K_PU] = ADC5_CHAN_TEMP("amux_thm6_pu2", 0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC7_GPIO1_100K_PU] = ADC5_CHAN_TEMP("gpio1_pu2", 0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC7_GPIO2_100K_PU] = ADC5_CHAN_TEMP("gpio2_pu2", 0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC7_GPIO3_100K_PU] = ADC5_CHAN_TEMP("gpio3_pu2", 0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC7_GPIO4_100K_PU] = ADC5_CHAN_TEMP("gpio4_pu2", 0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+};
+
static const struct adc5_channels adc5_chans_rev2[ADC5_MAX_CHANNEL] = {
[ADC5_REF_GND] = ADC5_CHAN_VOLT("ref_gnd", 0,
SCALE_HW_CALIB_DEFAULT)
@@ -511,6 +696,7 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc,
{
const char *name = node->name, *channel_name;
u32 chan, value, varr[2];
+ u32 sid = 0;
int ret;
struct device *dev = adc->dev;
@@ -520,6 +706,15 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc,
return ret;
}
+ /* Value read from "reg" is virtual channel number */
+
+ /* virtual channel number = sid << 8 | channel number */
+
+ if (adc->data == &adc7_data_pmic) {
+ sid = chan >> ADC_CHANNEL_OFFSET;
+ chan = chan & ADC_CHANNEL_MASK;
+ }
+
if (chan > ADC5_PARALLEL_ISENSE_VBAT_IDATA ||
!data->adc_chans[chan].datasheet_name) {
dev_err(dev, "%s invalid channel number %d\n", name, chan);
@@ -528,6 +723,7 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc,
/* the channel has DT description */
prop->channel = chan;
+ prop->sid = sid;
channel_name = of_get_property(node,
"label", NULL) ? : node->name;
@@ -578,8 +774,9 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc,
pr_debug("dig_ver:minor:%d, major:%d\n", dig_version[0],
dig_version[1]);
/* Digital controller >= 5.3 have hw_settle_2 option */
- if (dig_version[0] >= ADC5_HW_SETTLE_DIFF_MINOR &&
- dig_version[1] >= ADC5_HW_SETTLE_DIFF_MAJOR)
+ if ((dig_version[0] >= ADC5_HW_SETTLE_DIFF_MINOR &&
+ dig_version[1] >= ADC5_HW_SETTLE_DIFF_MAJOR) ||
+ adc->data == &adc7_data_pmic)
ret = adc5_hw_settle_time_from_dt(value,
data->hw_settle_2);
else
@@ -639,6 +836,17 @@ static const struct adc5_data adc5_data_pmic = {
1, 2, 4, 8, 16, 32, 64, 128},
};
+static const struct adc5_data adc7_data_pmic = {
+ .full_scale_code_volt = 0x70e4,
+ .adc_chans = adc7_chans_pmic,
+ .decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX])
+ {85, 340, 1360},
+ .hw_settle_2 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
+ {15, 100, 200, 300, 400, 500, 600, 700,
+ 1000, 2000, 4000, 8000, 16000, 32000,
+ 64000, 128000},
+};
+
static const struct adc5_data adc5_data_pmic_rev2 = {
.full_scale_code_volt = 0x4000,
.full_scale_code_cur = 0x1800,
@@ -659,6 +867,10 @@ static const struct of_device_id adc5_match_table[] = {
.data = &adc5_data_pmic,
},
{
+ .compatible = "qcom,spmi-adc7",
+ .data = &adc7_data_pmic,
+ },
+ {
.compatible = "qcom,spmi-adc-rev2",
.data = &adc5_data_pmic_rev2,
},
@@ -752,6 +964,12 @@ static int adc5_probe(struct platform_device *pdev)
adc->regmap = regmap;
adc->dev = dev;
adc->base = reg;
+
+ if (of_device_is_compatible(node, "qcom,spmi-adc7"))
+ indio_dev->info = &adc7_info;
+ else
+ indio_dev->info = &adc5_info;
+
init_completion(&adc->complete);
mutex_init(&adc->lock);
@@ -777,7 +995,6 @@ static int adc5_probe(struct platform_device *pdev)
indio_dev->dev.of_node = node;
indio_dev->name = pdev->name;
indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->info = &adc5_info;
indio_dev->channels = adc->iio_chans;
indio_dev->num_channels = adc->nchannels;
diff --git a/drivers/iio/adc/qcom-vadc-common.c b/drivers/iio/adc/qcom-vadc-common.c
index 2bb78d1..b6915c2 100644
--- a/drivers/iio/adc/qcom-vadc-common.c
+++ b/drivers/iio/adc/qcom-vadc-common.c
@@ -89,6 +89,195 @@ static const struct vadc_map_pt adcmap_100k_104ef_104fb_1875_vref[] = {
{ 46, 125000 },
};
+static const struct vadc_map_pt adcmap7_die_temp[] = {
+ { 433700, 1967},
+ { 473100, 1964},
+ { 512400, 1957},
+ { 551500, 1949},
+ { 590500, 1940},
+ { 629300, 1930},
+ { 667900, 1921},
+ { 706400, 1910},
+ { 744600, 1896},
+ { 782500, 1878},
+ { 820100, 1859},
+ { 857300, 0},
+};
+
+/*
+ * Resistance to temperature table for 100k pull up for NTCG104EF104.
+ */
+static const struct vadc_map_pt adcmap7_100k[] = {
+ { 4250657, -40960 },
+ { 3962085, -39936 },
+ { 3694875, -38912 },
+ { 3447322, -37888 },
+ { 3217867, -36864 },
+ { 3005082, -35840 },
+ { 2807660, -34816 },
+ { 2624405, -33792 },
+ { 2454218, -32768 },
+ { 2296094, -31744 },
+ { 2149108, -30720 },
+ { 2012414, -29696 },
+ { 1885232, -28672 },
+ { 1766846, -27648 },
+ { 1656598, -26624 },
+ { 1553884, -25600 },
+ { 1458147, -24576 },
+ { 1368873, -23552 },
+ { 1285590, -22528 },
+ { 1207863, -21504 },
+ { 1135290, -20480 },
+ { 1067501, -19456 },
+ { 1004155, -18432 },
+ { 944935, -17408 },
+ { 889550, -16384 },
+ { 837731, -15360 },
+ { 789229, -14336 },
+ { 743813, -13312 },
+ { 701271, -12288 },
+ { 661405, -11264 },
+ { 624032, -10240 },
+ { 588982, -9216 },
+ { 556100, -8192 },
+ { 525239, -7168 },
+ { 496264, -6144 },
+ { 469050, -5120 },
+ { 443480, -4096 },
+ { 419448, -3072 },
+ { 396851, -2048 },
+ { 375597, -1024 },
+ { 355598, 0 },
+ { 336775, 1024 },
+ { 319052, 2048 },
+ { 302359, 3072 },
+ { 286630, 4096 },
+ { 271806, 5120 },
+ { 257829, 6144 },
+ { 244646, 7168 },
+ { 232209, 8192 },
+ { 220471, 9216 },
+ { 209390, 10240 },
+ { 198926, 11264 },
+ { 189040, 12288 },
+ { 179698, 13312 },
+ { 170868, 14336 },
+ { 162519, 15360 },
+ { 154622, 16384 },
+ { 147150, 17408 },
+ { 140079, 18432 },
+ { 133385, 19456 },
+ { 127046, 20480 },
+ { 121042, 21504 },
+ { 115352, 22528 },
+ { 109960, 23552 },
+ { 104848, 24576 },
+ { 100000, 25600 },
+ { 95402, 26624 },
+ { 91038, 27648 },
+ { 86897, 28672 },
+ { 82965, 29696 },
+ { 79232, 30720 },
+ { 75686, 31744 },
+ { 72316, 32768 },
+ { 69114, 33792 },
+ { 66070, 34816 },
+ { 63176, 35840 },
+ { 60423, 36864 },
+ { 57804, 37888 },
+ { 55312, 38912 },
+ { 52940, 39936 },
+ { 50681, 40960 },
+ { 48531, 41984 },
+ { 46482, 43008 },
+ { 44530, 44032 },
+ { 42670, 45056 },
+ { 40897, 46080 },
+ { 39207, 47104 },
+ { 37595, 48128 },
+ { 36057, 49152 },
+ { 34590, 50176 },
+ { 33190, 51200 },
+ { 31853, 52224 },
+ { 30577, 53248 },
+ { 29358, 54272 },
+ { 28194, 55296 },
+ { 27082, 56320 },
+ { 26020, 57344 },
+ { 25004, 58368 },
+ { 24033, 59392 },
+ { 23104, 60416 },
+ { 22216, 61440 },
+ { 21367, 62464 },
+ { 20554, 63488 },
+ { 19776, 64512 },
+ { 19031, 65536 },
+ { 18318, 66560 },
+ { 17636, 67584 },
+ { 16982, 68608 },
+ { 16355, 69632 },
+ { 15755, 70656 },
+ { 15180, 71680 },
+ { 14628, 72704 },
+ { 14099, 73728 },
+ { 13592, 74752 },
+ { 13106, 75776 },
+ { 12640, 76800 },
+ { 12192, 77824 },
+ { 11762, 78848 },
+ { 11350, 79872 },
+ { 10954, 80896 },
+ { 10574, 81920 },
+ { 10209, 82944 },
+ { 9858, 83968 },
+ { 9521, 84992 },
+ { 9197, 86016 },
+ { 8886, 87040 },
+ { 8587, 88064 },
+ { 8299, 89088 },
+ { 8023, 90112 },
+ { 7757, 91136 },
+ { 7501, 92160 },
+ { 7254, 93184 },
+ { 7017, 94208 },
+ { 6789, 95232 },
+ { 6570, 96256 },
+ { 6358, 97280 },
+ { 6155, 98304 },
+ { 5959, 99328 },
+ { 5770, 100352 },
+ { 5588, 101376 },
+ { 5412, 102400 },
+ { 5243, 103424 },
+ { 5080, 104448 },
+ { 4923, 105472 },
+ { 4771, 106496 },
+ { 4625, 107520 },
+ { 4484, 108544 },
+ { 4348, 109568 },
+ { 4217, 110592 },
+ { 4090, 111616 },
+ { 3968, 112640 },
+ { 3850, 113664 },
+ { 3736, 114688 },
+ { 3626, 115712 },
+ { 3519, 116736 },
+ { 3417, 117760 },
+ { 3317, 118784 },
+ { 3221, 119808 },
+ { 3129, 120832 },
+ { 3039, 121856 },
+ { 2952, 122880 },
+ { 2868, 123904 },
+ { 2787, 124928 },
+ { 2709, 125952 },
+ { 2633, 126976 },
+ { 2560, 128000 },
+ { 2489, 129024 },
+ { 2420, 130048 }
+};
+
static int qcom_vadc_scale_hw_calib_volt(
const struct vadc_prescale_ratio *prescale,
const struct adc5_data *data,
@@ -97,6 +286,10 @@ static int qcom_vadc_scale_hw_calib_therm(
const struct vadc_prescale_ratio *prescale,
const struct adc5_data *data,
u16 adc_code, int *result_mdec);
+static int qcom_vadc7_scale_hw_calib_therm(
+ const struct vadc_prescale_ratio *prescale,
+ const struct adc5_data *data,
+ u16 adc_code, int *result_mdec);
static int qcom_vadc_scale_hw_smb_temp(
const struct vadc_prescale_ratio *prescale,
const struct adc5_data *data,
@@ -109,12 +302,20 @@ static int qcom_vadc_scale_hw_calib_die_temp(
const struct vadc_prescale_ratio *prescale,
const struct adc5_data *data,
u16 adc_code, int *result_mdec);
+static int qcom_vadc7_scale_hw_calib_die_temp(
+ const struct vadc_prescale_ratio *prescale,
+ const struct adc5_data *data,
+ u16 adc_code, int *result_mdec);
static struct qcom_adc5_scale_type scale_adc5_fn[] = {
[SCALE_HW_CALIB_DEFAULT] = {qcom_vadc_scale_hw_calib_volt},
[SCALE_HW_CALIB_THERM_100K_PULLUP] = {qcom_vadc_scale_hw_calib_therm},
[SCALE_HW_CALIB_XOTHERM] = {qcom_vadc_scale_hw_calib_therm},
+ [SCALE_HW_CALIB_THERM_100K_PU_PM7] = {
+ qcom_vadc7_scale_hw_calib_therm},
[SCALE_HW_CALIB_PMIC_THERM] = {qcom_vadc_scale_hw_calib_die_temp},
+ [SCALE_HW_CALIB_PMIC_THERM_PM7] = {
+ qcom_vadc7_scale_hw_calib_die_temp},
[SCALE_HW_CALIB_PM5_CHG_TEMP] = {qcom_vadc_scale_hw_chg5_temp},
[SCALE_HW_CALIB_PM5_SMB_TEMP] = {qcom_vadc_scale_hw_smb_temp},
};
@@ -291,6 +492,32 @@ static int qcom_vadc_scale_code_voltage_factor(u16 adc_code,
return (int) voltage;
}
+static int qcom_vadc7_scale_hw_calib_therm(
+ const struct vadc_prescale_ratio *prescale,
+ const struct adc5_data *data,
+ u16 adc_code, int *result_mdec)
+{
+ s64 resistance = adc_code;
+ int ret, result;
+
+ if (adc_code >= RATIO_MAX_ADC7)
+ return -EINVAL;
+
+ /* (ADC code * R_PULLUP (100Kohm)) / (full_scale_code - ADC code)*/
+ resistance *= R_PU_100K;
+ resistance = div64_s64(resistance, RATIO_MAX_ADC7 - adc_code);
+
+ ret = qcom_vadc_map_voltage_temp(adcmap7_100k,
+ ARRAY_SIZE(adcmap7_100k),
+ resistance, &result);
+ if (ret)
+ return ret;
+
+ *result_mdec = result;
+
+ return 0;
+}
+
static int qcom_vadc_scale_hw_calib_volt(
const struct vadc_prescale_ratio *prescale,
const struct adc5_data *data,
@@ -330,6 +557,39 @@ static int qcom_vadc_scale_hw_calib_die_temp(
return 0;
}
+static int qcom_vadc7_scale_hw_calib_die_temp(
+ const struct vadc_prescale_ratio *prescale,
+ const struct adc5_data *data,
+ u16 adc_code, int *result_mdec)
+{
+
+ int voltage, vtemp0, temp, i = ARRAY_SIZE(adcmap7_die_temp) - 1;
+
+ voltage = qcom_vadc_scale_code_voltage_factor(adc_code,
+ prescale, data, 1);
+
+ if (adcmap7_die_temp[0].x > voltage) {
+ *result_mdec = DIE_TEMP_ADC7_SCALE_1;
+ return 0;
+ } else if (adcmap7_die_temp[i].x <= voltage) {
+ *result_mdec = DIE_TEMP_ADC7_MAX;
+ return 0;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(adcmap7_die_temp); i++)
+ if (adcmap7_die_temp[i].x > voltage)
+ break;
+
+ vtemp0 = adcmap7_die_temp[i - 1].x;
+ voltage = voltage - vtemp0;
+ temp = div64_s64(voltage * DIE_TEMP_ADC7_SCALE_FACTOR,
+ adcmap7_die_temp[i - 1].y);
+ temp += DIE_TEMP_ADC7_SCALE_1 + (DIE_TEMP_ADC7_SCALE_2 * (i - 1));
+ *result_mdec = temp;
+
+ return 0;
+}
+
static int qcom_vadc_scale_hw_smb_temp(
const struct vadc_prescale_ratio *prescale,
const struct adc5_data *data,
diff --git a/drivers/iio/adc/qcom-vadc-common.h b/drivers/iio/adc/qcom-vadc-common.h
index e074902a..5f9e680 100644
--- a/drivers/iio/adc/qcom-vadc-common.h
+++ b/drivers/iio/adc/qcom-vadc-common.h
@@ -49,6 +49,14 @@
#define ADC5_FULL_SCALE_CODE 0x70e4
#define ADC5_USR_DATA_CHECK 0x8000
+#define R_PU_100K 100000
+#define RATIO_MAX_ADC7 0x4000
+
+#define DIE_TEMP_ADC7_SCALE_1 -60000
+#define DIE_TEMP_ADC7_SCALE_2 20000
+#define DIE_TEMP_ADC7_SCALE_FACTOR 1000
+#define DIE_TEMP_ADC7_MAX 160000
+
/**
* struct vadc_map_pt - Map the graph representation for ADC channel
* @x: Represent the ADC digitized code.
@@ -110,8 +118,12 @@ struct vadc_prescale_ratio {
* lookup table. The hardware applies offset/slope to adc code.
* SCALE_HW_CALIB_XOTHERM: Returns XO thermistor voltage in millidegC using
* 100k pullup. The hardware applies offset/slope to adc code.
+ * SCALE_HW_CALIB_THERM_100K_PU_PM7: Returns temperature in millidegC using
+ * lookup table for PMIC7. The hardware applies offset/slope to adc code.
* SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade.
* The hardware applies offset/slope to adc code.
+ * SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade.
+ * The hardware applies offset/slope to adc code. This is for PMIC7.
* SCALE_HW_CALIB_PM5_CHG_TEMP: Returns result in millidegrees for PMIC5
* charger temperature.
* SCALE_HW_CALIB_PM5_SMB_TEMP: Returns result in millidegrees for PMIC5
@@ -126,7 +138,9 @@ enum vadc_scale_fn_type {
SCALE_HW_CALIB_DEFAULT,
SCALE_HW_CALIB_THERM_100K_PULLUP,
SCALE_HW_CALIB_XOTHERM,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7,
SCALE_HW_CALIB_PMIC_THERM,
+ SCALE_HW_CALIB_PMIC_THERM_PM7,
SCALE_HW_CALIB_PM5_CHG_TEMP,
SCALE_HW_CALIB_PM5_SMB_TEMP,
SCALE_HW_CALIB_INVALID,
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related
* [PATCH V4 5/5] iio: adc: Clean up ADC code common to PMIC5 and PMIC7
From: Jishnu Prakash @ 2020-05-13 9:22 UTC (permalink / raw)
To: agross, bjorn.andersson, devicetree, linux-kernel, mka,
linus.walleij, Jonathan.Cameron, andy.shevchenko, amit.kucheria,
smohanad, kgunda, aghayal, Jonathan Cameron, Hartmut Knaack,
Lars-Peter Clausen, Peter Meerwald-Stadler, linux-arm-msm,
linux-iio
Cc: linux-arm-msm-owner, Jishnu Prakash
In-Reply-To: <1589361736-816-1-git-send-email-jprakash@codeaurora.org>
This commit includes the following changes:
Add a common function used for read_raw callback for
both PMIC5 and PMIC7 ADCs.
Add exit function for ADC.
Add info_property under adc_data to more efficiently
distinguish PMIC5 and PMIC7 ADCs.
Signed-off-by: Jishnu Prakash <jprakash@codeaurora.org>
---
drivers/iio/adc/qcom-spmi-adc5.c | 83 +++++++++++++++++++++-----------------
drivers/iio/adc/qcom-vadc-common.h | 1 +
2 files changed, 48 insertions(+), 36 deletions(-)
diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c
index 974073f..fbe7a39 100644
--- a/drivers/iio/adc/qcom-spmi-adc5.c
+++ b/drivers/iio/adc/qcom-spmi-adc5.c
@@ -167,8 +167,6 @@ static const struct vadc_prescale_ratio adc5_prescale_ratios[] = {
{.num = 1, .den = 16}
};
-static const struct adc5_data adc7_data_pmic;
-
static int adc5_read(struct adc5_chip *adc, u16 offset, u8 *data, int len)
{
return regmap_bulk_read(adc->regmap, adc->base + offset, data, len);
@@ -452,6 +450,13 @@ static int adc7_do_conversion(struct adc5_chip *adc,
return ret;
}
+struct adc_do_conversion {
+ int (*adc_do_conversion)(struct adc5_chip *adc,
+ struct adc5_channel_prop *prop,
+ struct iio_chan_spec const *chan,
+ u16 *data_volt, u16 *data_cur);
+};
+
static irqreturn_t adc5_isr(int irq, void *dev_id)
{
struct adc5_chip *adc = dev_id;
@@ -490,9 +495,9 @@ static int adc7_of_xlate(struct iio_dev *indio_dev,
return -EINVAL;
}
-static int adc5_read_raw(struct iio_dev *indio_dev,
+static int adc_read_raw_common(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, int *val2,
- long mask)
+ long mask, struct adc_do_conversion do_conv)
{
struct adc5_chip *adc = iio_priv(indio_dev);
struct adc5_channel_prop *prop;
@@ -503,8 +508,9 @@ static int adc5_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_PROCESSED:
- ret = adc5_do_conversion(adc, prop, chan,
- &adc_code_volt, &adc_code_cur);
+ ret = do_conv.adc_do_conversion(adc, prop, chan,
+ &adc_code_volt, &adc_code_cur);
+
if (ret)
return ret;
@@ -512,6 +518,7 @@ static int adc5_read_raw(struct iio_dev *indio_dev,
&adc5_prescale_ratios[prop->prescale],
adc->data,
adc_code_volt, val);
+
if (ret)
return ret;
@@ -523,38 +530,28 @@ static int adc5_read_raw(struct iio_dev *indio_dev,
return 0;
}
-static int adc7_read_raw(struct iio_dev *indio_dev,
+static int adc5_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, int *val2,
long mask)
{
- struct adc5_chip *adc = iio_priv(indio_dev);
- struct adc5_channel_prop *prop;
- u16 adc_code_volt, adc_code_cur;
- int ret;
-
- prop = &adc->chan_props[chan->address];
+ struct adc_do_conversion do_conv;
- switch (mask) {
- case IIO_CHAN_INFO_PROCESSED:
- ret = adc7_do_conversion(adc, prop, chan,
- &adc_code_volt, &adc_code_cur);
- if (ret)
- return ret;
+ do_conv.adc_do_conversion = adc5_do_conversion;
- ret = qcom_adc5_hw_scale(prop->scale_fn_type,
- &adc5_prescale_ratios[prop->prescale],
- adc->data,
- adc_code_volt, val);
+ return adc_read_raw_common(indio_dev, chan, val, val2,
+ mask, do_conv);
+}
- if (ret)
- return ret;
+static int adc7_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val, int *val2,
+ long mask)
+{
+ struct adc_do_conversion do_conv;
- return IIO_VAL_INT;
- default:
- return -EINVAL;
- }
+ do_conv.adc_do_conversion = adc7_do_conversion;
- return 0;
+ return adc_read_raw_common(indio_dev, chan, val, val2,
+ mask, do_conv);
}
static const struct iio_info adc5_info = {
@@ -710,7 +707,7 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc,
/* virtual channel number = sid << 8 | channel number */
- if (adc->data == &adc7_data_pmic) {
+ if (adc->data->info == &adc7_info) {
sid = chan >> ADC_CHANNEL_OFFSET;
chan = chan & ADC_CHANNEL_MASK;
}
@@ -776,7 +773,7 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc,
/* Digital controller >= 5.3 have hw_settle_2 option */
if ((dig_version[0] >= ADC5_HW_SETTLE_DIFF_MINOR &&
dig_version[1] >= ADC5_HW_SETTLE_DIFF_MAJOR) ||
- adc->data == &adc7_data_pmic)
+ adc->data->info == &adc7_info)
ret = adc5_hw_settle_time_from_dt(value,
data->hw_settle_2);
else
@@ -826,6 +823,7 @@ static const struct adc5_data adc5_data_pmic = {
.full_scale_code_volt = 0x70e4,
.full_scale_code_cur = 0x2710,
.adc_chans = adc5_chans_pmic,
+ .info = &adc5_info,
.decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX])
{250, 420, 840},
.hw_settle_1 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
@@ -839,6 +837,7 @@ static const struct adc5_data adc5_data_pmic = {
static const struct adc5_data adc7_data_pmic = {
.full_scale_code_volt = 0x70e4,
.adc_chans = adc7_chans_pmic,
+ .info = &adc7_info,
.decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX])
{85, 340, 1360},
.hw_settle_2 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
@@ -851,6 +850,7 @@ static const struct adc5_data adc5_data_pmic_rev2 = {
.full_scale_code_volt = 0x4000,
.full_scale_code_cur = 0x1800,
.adc_chans = adc5_chans_rev2,
+ .info = &adc5_info,
.decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX])
{256, 512, 1024},
.hw_settle_1 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
@@ -965,10 +965,7 @@ static int adc5_probe(struct platform_device *pdev)
adc->dev = dev;
adc->base = reg;
- if (of_device_is_compatible(node, "qcom,spmi-adc7"))
- indio_dev->info = &adc7_info;
- else
- indio_dev->info = &adc5_info;
+ platform_set_drvdata(pdev, adc);
init_completion(&adc->complete);
mutex_init(&adc->lock);
@@ -979,6 +976,8 @@ static int adc5_probe(struct platform_device *pdev)
return ret;
}
+ indio_dev->info = adc->data->info;
+
irq_eoc = platform_get_irq(pdev, 0);
if (irq_eoc < 0) {
if (irq_eoc == -EPROBE_DEFER || irq_eoc == -EINVAL)
@@ -991,6 +990,8 @@ static int adc5_probe(struct platform_device *pdev)
return ret;
}
+ adc->irq_eoc = irq_eoc;
+
indio_dev->dev.parent = dev;
indio_dev->dev.of_node = node;
indio_dev->name = pdev->name;
@@ -1001,12 +1002,22 @@ static int adc5_probe(struct platform_device *pdev)
return devm_iio_device_register(dev, indio_dev);
}
+static int adc5_exit(struct platform_device *pdev)
+{
+ struct adc5_chip *adc = platform_get_drvdata(pdev);
+
+ if (adc->irq_eoc >= 0)
+ disable_irq(adc->irq_eoc);
+ return 0;
+}
+
static struct platform_driver adc5_driver = {
.driver = {
.name = "qcom-spmi-adc5.c",
.of_match_table = adc5_match_table,
},
.probe = adc5_probe,
+ .remove = adc5_exit,
};
module_platform_driver(adc5_driver);
diff --git a/drivers/iio/adc/qcom-vadc-common.h b/drivers/iio/adc/qcom-vadc-common.h
index 5f9e680..d195e83 100644
--- a/drivers/iio/adc/qcom-vadc-common.h
+++ b/drivers/iio/adc/qcom-vadc-common.h
@@ -150,6 +150,7 @@ struct adc5_data {
const u32 full_scale_code_volt;
const u32 full_scale_code_cur;
const struct adc5_channels *adc_chans;
+ const struct iio_info *info;
unsigned int *decimation;
unsigned int *hw_settle_1;
unsigned int *hw_settle_2;
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related
* [PATCH V4 4/5] iio: adc: Update error checks and debug prints
From: Jishnu Prakash @ 2020-05-13 9:22 UTC (permalink / raw)
To: agross, bjorn.andersson, devicetree, linux-kernel, mka,
linus.walleij, Jonathan.Cameron, andy.shevchenko, amit.kucheria,
smohanad, kgunda, aghayal, Jonathan Cameron, Hartmut Knaack,
Lars-Peter Clausen, Peter Meerwald-Stadler, linux-arm-msm,
linux-iio
Cc: linux-arm-msm-owner, Jishnu Prakash
In-Reply-To: <1589361736-816-1-git-send-email-jprakash@codeaurora.org>
Change pr_err/pr_debug statements to dev_err/dev_dbg for
increased clarity. Also clean up some return value checks.
Signed-off-by: Jishnu Prakash <jprakash@codeaurora.org>
---
drivers/iio/adc/qcom-spmi-adc5.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c
index 6d6b611..974073f 100644
--- a/drivers/iio/adc/qcom-spmi-adc5.c
+++ b/drivers/iio/adc/qcom-spmi-adc5.c
@@ -249,11 +249,11 @@ static int adc5_read_voltage_data(struct adc5_chip *adc, u16 *data)
*data = (rslt_msb << 8) | rslt_lsb;
if (*data == ADC5_USR_DATA_CHECK) {
- pr_err("Invalid data:0x%x\n", *data);
+ dev_err(adc->dev, "Invalid data:0x%x\n", *data);
return -EINVAL;
}
- pr_debug("voltage raw code:0x%x\n", *data);
+ dev_dbg(adc->dev, "voltage raw code:0x%x\n", *data);
return 0;
}
@@ -304,7 +304,7 @@ static int adc5_configure(struct adc5_chip *adc,
/* Read registers 0x42 through 0x46 */
ret = adc5_read(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf));
- if (ret < 0)
+ if (ret)
return ret;
/* Digital param selection */
@@ -344,7 +344,7 @@ static int adc7_configure(struct adc5_chip *adc,
return ret;
ret = adc5_read(adc, ADC5_USR_DIG_PARAM, buf, sizeof(buf));
- if (ret < 0)
+ if (ret)
return ret;
/* Digital param selection */
@@ -385,24 +385,24 @@ static int adc5_do_conversion(struct adc5_chip *adc,
ret = adc5_configure(adc, prop);
if (ret) {
- pr_err("ADC configure failed with %d\n", ret);
+ dev_err(adc->dev, "ADC configure failed with %d\n", ret);
goto unlock;
}
if (adc->poll_eoc) {
ret = adc5_poll_wait_eoc(adc);
if (ret < 0) {
- pr_err("EOC bit not set\n");
+ dev_err(adc->dev, "EOC bit not set\n");
goto unlock;
}
} else {
ret = wait_for_completion_timeout(&adc->complete,
ADC5_CONV_TIMEOUT);
if (!ret) {
- pr_debug("Did not get completion timeout.\n");
+ dev_dbg(adc->dev, "Did not get completion timeout.\n");
ret = adc5_poll_wait_eoc(adc);
if (ret < 0) {
- pr_err("EOC bit not set\n");
+ dev_err(adc->dev, "EOC bit not set\n");
goto unlock;
}
}
@@ -435,7 +435,7 @@ static int adc7_do_conversion(struct adc5_chip *adc,
wait_for_completion_timeout(&adc->complete, ADC7_CONV_TIMEOUT);
ret = adc5_read(adc, ADC5_USR_STATUS1, &status, 1);
- if (ret < 0)
+ if (ret)
goto unlock;
if (status & ADC5_USR_STATUS1_CONV_FAULT) {
@@ -481,8 +481,8 @@ static int adc7_of_xlate(struct iio_dev *indio_dev,
int i, v_channel;
for (i = 0; i < adc->nchannels; i++) {
- v_channel = (adc->chan_props[i].sid << ADC_CHANNEL_OFFSET |
- adc->chan_props[i].channel);
+ v_channel = (adc->chan_props[i].sid << ADC_CHANNEL_OFFSET) |
+ adc->chan_props[i].channel;
if (v_channel == iiospec->args[0])
return i;
}
@@ -728,7 +728,7 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc,
channel_name = of_get_property(node,
"label", NULL) ? : node->name;
if (!channel_name) {
- pr_err("Invalid channel name\n");
+ dev_err(dev, "Invalid channel name\n");
return -EINVAL;
}
prop->datasheet_name = channel_name;
@@ -766,12 +766,12 @@ static int adc5_get_dt_channel_data(struct adc5_chip *adc,
ret = adc5_read(adc, ADC5_USR_REVISION1, dig_version,
sizeof(dig_version));
- if (ret < 0) {
+ if (ret) {
dev_err(dev, "Invalid dig version read %d\n", ret);
return ret;
}
- pr_debug("dig_ver:minor:%d, major:%d\n", dig_version[0],
+ dev_dbg(dev, "dig_ver:minor:%d, major:%d\n", dig_version[0],
dig_version[1]);
/* Digital controller >= 5.3 have hw_settle_2 option */
if ((dig_version[0] >= ADC5_HW_SETTLE_DIFF_MINOR &&
@@ -975,7 +975,7 @@ static int adc5_probe(struct platform_device *pdev)
ret = adc5_get_dt_data(adc, node);
if (ret) {
- pr_err("adc get dt data failed\n");
+ dev_err(dev, "adc get dt data failed\n");
return ret;
}
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related
* Re: [PATCH 1/2] i2c: pxa: implement generic i2c bus recovery
From: Russell King - ARM Linux admin @ 2020-05-13 9:29 UTC (permalink / raw)
To: Andrew Lunn
Cc: linux-i2c, devicetree, Gregory Clement, Jason Cooper,
linux-arm-kernel, Rob Herring, Sebastian Hesselbarth,
Vladimir Vid
In-Reply-To: <20200506140054.GG224913@lunn.ch>
On Wed, May 06, 2020 at 04:00:54PM +0200, Andrew Lunn wrote:
> On Wed, May 06, 2020 at 10:40:31AM +0100, Russell King wrote:
> > Implement generic GPIO-based I2C bus recovery for the PXA I2C driver.
> >
> > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> > ---
> > drivers/i2c/busses/i2c-pxa.c | 176 +++++++++++++++++++++++++++++++----
> > 1 file changed, 159 insertions(+), 17 deletions(-)
> >
> > diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
> > index 0e194d6cd1b5..da15ab2a519e 100644
> > --- a/drivers/i2c/busses/i2c-pxa.c
> > +++ b/drivers/i2c/busses/i2c-pxa.c
> > @@ -20,6 +20,7 @@
> > #include <linux/delay.h>
> > #include <linux/err.h>
> > #include <linux/errno.h>
> > +#include <linux/gpio/consumer.h>
> > #include <linux/i2c.h>
> > #include <linux/init.h>
> > #include <linux/interrupt.h>
> > @@ -28,6 +29,7 @@
> > #include <linux/module.h>
> > #include <linux/of.h>
> > #include <linux/of_device.h>
> > +#include <linux/pinctrl/consumer.h>
> > #include <linux/platform_device.h>
> > #include <linux/platform_data/i2c-pxa.h>
> > #include <linux/slab.h>
> > @@ -260,6 +262,11 @@ struct pxa_i2c {
> > bool highmode_enter;
> > u32 fm_mask;
> > u32 hs_mask;
> > +
> > + struct i2c_bus_recovery_info recovery;
> > + struct pinctrl *pinctrl;
> > + struct pinctrl_state *pinctrl_default;
> > + struct pinctrl_state *pinctrl_recovery;
> > };
> >
> > #define _IBMR(i2c) ((i2c)->reg_ibmr)
> > @@ -559,13 +566,8 @@ static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
> > #define i2c_pxa_set_slave(i2c, err) do { } while (0)
> > #endif
> >
> > -static void i2c_pxa_reset(struct pxa_i2c *i2c)
> > +static void i2c_pxa_do_reset(struct pxa_i2c *i2c)
> > {
> > - pr_debug("Resetting I2C Controller Unit\n");
> > -
> > - /* abort any transfer currently under way */
> > - i2c_pxa_abort(i2c);
> > -
> > /* reset according to 9.8 */
> > writel(ICR_UR, _ICR(i2c));
> > writel(I2C_ISR_INIT, _ISR(i2c));
> > @@ -584,12 +586,25 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
> > #endif
> >
> > i2c_pxa_set_slave(i2c, 0);
> > +}
> >
> > +static void i2c_pxa_enable(struct pxa_i2c *i2c)
> > +{
> > /* enable unit */
> > writel(readl(_ICR(i2c)) | ICR_IUE, _ICR(i2c));
> > udelay(100);
> > }
> >
> > +static void i2c_pxa_reset(struct pxa_i2c *i2c)
> > +{
> > + pr_debug("Resetting I2C Controller Unit\n");
>
> Hi Russell
>
> I know you are just moving code around, but maybe pr_debug() could be
> cleaned up to dev_debug()?
Yes, but I don't want to add irrelevant changes into this; changing
the way the driver prints stuff wouldn't be part of adding recovery
support, and would likely get review comments suggesting it should
be a separate patch.
> > + /*
> > + * Claiming GPIOs can change the pinmux state, which confuses the
> > + * pinctrl since since pinctrl's idea of the current setting is
>
> since since
>
> I don't know too much about this hardware, but for what it is worth,
>
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 10.2Mbps down 587kbps up
^ permalink raw reply
* [PATCH V5 01/10] remoteproc: qcom: Add PRNG proxy clock
From: Gokul Sriram Palanisamy @ 2020-05-13 9:30 UTC (permalink / raw)
To: gokulsri, sboyd, agross, bjorn.andersson, david.brown, devicetree,
jassisinghbrar, linux-arm-msm, linux-clk, linux-kernel,
linux-remoteproc, mark.rutland, mturquette, ohad, robh+dt,
sricharan, nprakash
In-Reply-To: <1589362265-22702-1-git-send-email-gokulsri@codeaurora.org>
PRNG clock is needed by the secure PIL, support for the same
is added in subsequent patches.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 65 +++++++++++++++++++++++++++----------
1 file changed, 47 insertions(+), 18 deletions(-)
diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c
index fff681a..0700d68 100644
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -91,19 +91,6 @@ enum {
WCSS_QCS404,
};
-struct wcss_data {
- const char *firmware_name;
- int crash_reason_smem;
- u32 version;
- bool aon_reset_required;
- bool wcss_q6_reset_required;
- const char *ssr_name;
- const char *sysmon_name;
- int ssctl_id;
- const struct rproc_ops *ops;
- bool requires_force_stop;
-};
-
struct q6v5_wcss {
struct device *dev;
@@ -128,6 +115,7 @@ struct q6v5_wcss {
struct clk *qdsp6ss_xo_cbcr;
struct clk *qdsp6ss_core_gfmux;
struct clk *lcc_bcr_sleep;
+ struct clk *prng_clk;
struct regulator *cx_supply;
struct qcom_rproc_glink glink_subdev;
@@ -151,6 +139,21 @@ struct q6v5_wcss {
bool requires_force_stop;
};
+struct wcss_data {
+ int (*init_clock)(struct q6v5_wcss *wcss);
+ int (*init_regulator)(struct q6v5_wcss *wcss);
+ const char *firmware_name;
+ int crash_reason_smem;
+ u32 version;
+ bool aon_reset_required;
+ bool wcss_q6_reset_required;
+ const char *ssr_name;
+ const char *sysmon_name;
+ int ssctl_id;
+ const struct rproc_ops *ops;
+ bool requires_force_stop;
+};
+
static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
{
int ret;
@@ -240,6 +243,12 @@ static int q6v5_wcss_start(struct rproc *rproc)
struct q6v5_wcss *wcss = rproc->priv;
int ret;
+ ret = clk_prepare_enable(wcss->prng_clk);
+ if (ret) {
+ dev_err(wcss->dev, "prng clock enable failed\n");
+ return ret;
+ }
+
qcom_q6v5_prepare(&wcss->q6v5);
/* Release Q6 and WCSS reset */
@@ -732,6 +741,7 @@ static int q6v5_wcss_stop(struct rproc *rproc)
return ret;
}
+ clk_disable_unprepare(wcss->prng_clk);
qcom_q6v5_unprepare(&wcss->q6v5);
return 0;
@@ -889,7 +899,21 @@ static int q6v5_alloc_memory_region(struct q6v5_wcss *wcss)
return 0;
}
-static int q6v5_wcss_init_clock(struct q6v5_wcss *wcss)
+static int ipq8074_init_clock(struct q6v5_wcss *wcss)
+{
+ int ret;
+
+ wcss->prng_clk = devm_clk_get(wcss->dev, "prng");
+ if (IS_ERR(wcss->prng_clk)) {
+ ret = PTR_ERR(wcss->prng_clk);
+ if (ret != -EPROBE_DEFER)
+ dev_err(wcss->dev, "Failed to get prng clock\n");
+ return ret;
+ }
+ return 0;
+}
+
+static int qcs404_init_clock(struct q6v5_wcss *wcss)
{
int ret;
@@ -979,7 +1003,7 @@ static int q6v5_wcss_init_clock(struct q6v5_wcss *wcss)
return 0;
}
-static int q6v5_wcss_init_regulator(struct q6v5_wcss *wcss)
+static int qcs404_init_regulator(struct q6v5_wcss *wcss)
{
wcss->cx_supply = devm_regulator_get(wcss->dev, "cx");
if (IS_ERR(wcss->cx_supply))
@@ -1023,12 +1047,14 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
if (ret)
goto free_rproc;
- if (wcss->version == WCSS_QCS404) {
- ret = q6v5_wcss_init_clock(wcss);
+ if (desc->init_clock) {
+ ret = desc->init_clock(wcss);
if (ret)
goto free_rproc;
+ }
- ret = q6v5_wcss_init_regulator(wcss);
+ if (desc->init_regulator) {
+ ret = desc->init_regulator(wcss);
if (ret)
goto free_rproc;
}
@@ -1073,6 +1099,7 @@ static int q6v5_wcss_remove(struct platform_device *pdev)
}
static const struct wcss_data wcss_ipq8074_res_init = {
+ .init_clock = ipq8074_init_clock,
.firmware_name = "IPQ8074/q6_fw.mdt",
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
@@ -1082,6 +1109,8 @@ static const struct wcss_data wcss_ipq8074_res_init = {
};
static const struct wcss_data wcss_qcs404_res_init = {
+ .init_clock = qcs404_init_clock,
+ .init_regulator = qcs404_init_regulator,
.crash_reason_smem = WCSS_CRASH_REASON,
.firmware_name = "wcnss.mdt",
.version = WCSS_QCS404,
--
2.7.4
^ permalink raw reply related
* [PATCH V5 06/10] dt-bindings: clock: qcom: Add reset for WCSSAON
From: Gokul Sriram Palanisamy @ 2020-05-13 9:31 UTC (permalink / raw)
To: gokulsri, sboyd, agross, bjorn.andersson, david.brown, devicetree,
jassisinghbrar, linux-arm-msm, linux-clk, linux-kernel,
linux-remoteproc, mark.rutland, mturquette, ohad, robh+dt,
sricharan, nprakash
In-Reply-To: <1589362265-22702-1-git-send-email-gokulsri@codeaurora.org>
Add binding for WCSSAON reset required for Q6v5 reset on IPQ8074 SoC.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Stephen Boyd <sboyd@kernel.org>
---
include/dt-bindings/clock/qcom,gcc-ipq8074.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/dt-bindings/clock/qcom,gcc-ipq8074.h b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
index 4de4811..04e1f57 100644
--- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h
+++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
@@ -362,5 +362,6 @@
#define GCC_PCIE1_AXI_SLAVE_ARES 128
#define GCC_PCIE1_AHB_ARES 129
#define GCC_PCIE1_AXI_MASTER_STICKY_ARES 130
+#define GCC_WCSSAON_RESET 131
#endif
--
2.7.4
^ permalink raw reply related
* [PATCH V5 03/10] remoteproc: qcom: Add support for split q6 + m3 wlan firmware
From: Gokul Sriram Palanisamy @ 2020-05-13 9:30 UTC (permalink / raw)
To: gokulsri, sboyd, agross, bjorn.andersson, david.brown, devicetree,
jassisinghbrar, linux-arm-msm, linux-clk, linux-kernel,
linux-remoteproc, mark.rutland, mturquette, ohad, robh+dt,
sricharan, nprakash
In-Reply-To: <1589362265-22702-1-git-send-email-gokulsri@codeaurora.org>
IPQ8074 supports split firmware for q6 and m3 as well.
So add support for loading the m3 firmware before q6.
Now the drivers works fine for both split and unified
firmwares.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 34 ++++++++++++++++++++++++++++++----
1 file changed, 30 insertions(+), 4 deletions(-)
diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c
index 44ab9bb..31239c0 100644
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -142,12 +142,14 @@ struct q6v5_wcss {
u32 version;
bool requires_force_stop;
bool need_mem_protection;
+ const char *m3_firmware_name;
};
struct wcss_data {
int (*init_clock)(struct q6v5_wcss *wcss);
int (*init_regulator)(struct q6v5_wcss *wcss);
- const char *firmware_name;
+ const char *q6_firmware_name;
+ const char *m3_firmware_name;
int crash_reason_smem;
u32 version;
bool aon_reset_required;
@@ -788,7 +790,29 @@ static void *q6v5_wcss_da_to_va(struct rproc *rproc, u64 da, size_t len)
static int q6v5_wcss_load(struct rproc *rproc, const struct firmware *fw)
{
struct q6v5_wcss *wcss = rproc->priv;
+ const struct firmware *m3_fw;
+ int ret;
+
+ if (wcss->m3_firmware_name) {
+ ret = request_firmware(&m3_fw, wcss->m3_firmware_name,
+ wcss->dev);
+ if (ret)
+ goto skip_m3;
+
+ ret = qcom_mdt_load_no_init(wcss->dev, m3_fw,
+ wcss->m3_firmware_name, 0,
+ wcss->mem_region, wcss->mem_phys,
+ wcss->mem_size, &wcss->mem_reloc);
+
+ release_firmware(m3_fw);
+
+ if (ret) {
+ dev_err(wcss->dev, "can't load m3_fw.bXX\n");
+ return ret;
+ }
+ }
+skip_m3:
if (wcss->need_mem_protection)
return qcom_mdt_load(wcss->dev, fw, rproc->firmware,
WCNSS_PAS_ID, wcss->mem_region,
@@ -1061,7 +1085,7 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops,
- desc->firmware_name, sizeof(*wcss));
+ desc->q6_firmware_name, sizeof(*wcss));
if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n");
return -ENOMEM;
@@ -1074,6 +1098,7 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
wcss->version = desc->version;
wcss->requires_force_stop = desc->requires_force_stop;
wcss->need_mem_protection = desc->need_mem_protection;
+ wcss->m3_firmware_name = desc->m3_firmware_name;
ret = q6v5_wcss_init_mmio(wcss, pdev);
if (ret)
@@ -1136,7 +1161,8 @@ static int q6v5_wcss_remove(struct platform_device *pdev)
static const struct wcss_data wcss_ipq8074_res_init = {
.init_clock = ipq8074_init_clock,
- .firmware_name = "IPQ8074/q6_fw.mdt",
+ .q6_firmware_name = "IPQ8074/q6_fw.mdt",
+ .m3_firmware_name = "IPQ8074/m3_fw.mdt",
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
.wcss_q6_reset_required = true,
@@ -1149,7 +1175,7 @@ static const struct wcss_data wcss_qcs404_res_init = {
.init_clock = qcs404_init_clock,
.init_regulator = qcs404_init_regulator,
.crash_reason_smem = WCSS_CRASH_REASON,
- .firmware_name = "wcnss.mdt",
+ .q6_firmware_name = "wcnss.mdt",
.version = WCSS_QCS404,
.aon_reset_required = false,
.wcss_q6_reset_required = false,
--
2.7.4
^ permalink raw reply related
* [PATCH V5 02/10] remoteproc: qcom: Add secure PIL support
From: Gokul Sriram Palanisamy @ 2020-05-13 9:30 UTC (permalink / raw)
To: gokulsri, sboyd, agross, bjorn.andersson, david.brown, devicetree,
jassisinghbrar, linux-arm-msm, linux-clk, linux-kernel,
linux-remoteproc, mark.rutland, mturquette, ohad, robh+dt,
sricharan, nprakash
In-Reply-To: <1589362265-22702-1-git-send-email-gokulsri@codeaurora.org>
IPQ8074 uses secure PIL. Hence, adding the support for the same.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c
index 0700d68..44ab9bb 100644
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -19,6 +19,7 @@
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/soc/qcom/mdt_loader.h>
+#include <linux/qcom_scm.h>
#include "qcom_common.h"
#include "qcom_q6v5.h"
@@ -86,6 +87,9 @@
#define TCSR_WCSS_CLK_ENABLE 0x14
#define MAX_HALT_REG 3
+
+#define WCNSS_PAS_ID 6
+
enum {
WCSS_IPQ8074,
WCSS_QCS404,
@@ -137,6 +141,7 @@ struct q6v5_wcss {
int crash_reason_smem;
u32 version;
bool requires_force_stop;
+ bool need_mem_protection;
};
struct wcss_data {
@@ -152,6 +157,7 @@ struct wcss_data {
int ssctl_id;
const struct rproc_ops *ops;
bool requires_force_stop;
+ bool need_mem_protection;
};
static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
@@ -251,6 +257,15 @@ static int q6v5_wcss_start(struct rproc *rproc)
qcom_q6v5_prepare(&wcss->q6v5);
+ if (wcss->need_mem_protection) {
+ ret = qcom_scm_pas_auth_and_reset(WCNSS_PAS_ID);
+ if (ret) {
+ dev_err(wcss->dev, "wcss_reset failed\n");
+ return ret;
+ }
+ goto wait_for_reset;
+ }
+
/* Release Q6 and WCSS reset */
ret = reset_control_deassert(wcss->wcss_reset);
if (ret) {
@@ -285,6 +300,7 @@ static int q6v5_wcss_start(struct rproc *rproc)
if (ret)
goto wcss_q6_reset;
+wait_for_reset:
ret = qcom_q6v5_wait_for_start(&wcss->q6v5, 5 * HZ);
if (ret == -ETIMEDOUT)
dev_err(wcss->dev, "start timed out\n");
@@ -717,6 +733,15 @@ static int q6v5_wcss_stop(struct rproc *rproc)
struct q6v5_wcss *wcss = rproc->priv;
int ret;
+ if (wcss->need_mem_protection) {
+ ret = qcom_scm_pas_shutdown(WCNSS_PAS_ID);
+ if (ret) {
+ dev_err(wcss->dev, "not able to shutdown\n");
+ return ret;
+ }
+ goto pas_done;
+ }
+
/* WCSS powerdown */
if (wcss->requires_force_stop) {
ret = qcom_q6v5_request_stop(&wcss->q6v5);
@@ -741,6 +766,7 @@ static int q6v5_wcss_stop(struct rproc *rproc)
return ret;
}
+pas_done:
clk_disable_unprepare(wcss->prng_clk);
qcom_q6v5_unprepare(&wcss->q6v5);
@@ -763,6 +789,12 @@ static int q6v5_wcss_load(struct rproc *rproc, const struct firmware *fw)
{
struct q6v5_wcss *wcss = rproc->priv;
+ if (wcss->need_mem_protection)
+ return qcom_mdt_load(wcss->dev, fw, rproc->firmware,
+ WCNSS_PAS_ID, wcss->mem_region,
+ wcss->mem_phys, wcss->mem_size,
+ &wcss->mem_reloc);
+
return qcom_mdt_load_no_init(wcss->dev, fw, rproc->firmware,
0, wcss->mem_region, wcss->mem_phys,
wcss->mem_size, &wcss->mem_reloc);
@@ -1025,6 +1057,9 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
if (!desc)
return -EINVAL;
+ if (desc->need_mem_protection && !qcom_scm_is_available())
+ return -EPROBE_DEFER;
+
rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops,
desc->firmware_name, sizeof(*wcss));
if (!rproc) {
@@ -1038,6 +1073,7 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
wcss->version = desc->version;
wcss->requires_force_stop = desc->requires_force_stop;
+ wcss->need_mem_protection = desc->need_mem_protection;
ret = q6v5_wcss_init_mmio(wcss, pdev);
if (ret)
@@ -1106,6 +1142,7 @@ static const struct wcss_data wcss_ipq8074_res_init = {
.wcss_q6_reset_required = true,
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
+ .need_mem_protection = true,
};
static const struct wcss_data wcss_qcs404_res_init = {
--
2.7.4
^ permalink raw reply related
* [PATCH V5 07/10] clk: qcom: Add WCSSAON reset
From: Gokul Sriram Palanisamy @ 2020-05-13 9:31 UTC (permalink / raw)
To: gokulsri, sboyd, agross, bjorn.andersson, david.brown, devicetree,
jassisinghbrar, linux-arm-msm, linux-clk, linux-kernel,
linux-remoteproc, mark.rutland, mturquette, ohad, robh+dt,
sricharan, nprakash
In-Reply-To: <1589362265-22702-1-git-send-email-gokulsri@codeaurora.org>
Add WCSSAON reset required for Q6v5 on IPQ8074 SoC.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
Acked-by: Stephen Boyd <sboyd@kernel.org>
---
drivers/clk/qcom/gcc-ipq8074.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
index e01f5f5..1e5758f 100644
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -4685,6 +4685,7 @@ static const struct qcom_reset_map gcc_ipq8074_resets[] = {
[GCC_PCIE1_AXI_SLAVE_ARES] = { 0x76040, 4 },
[GCC_PCIE1_AHB_ARES] = { 0x76040, 5 },
[GCC_PCIE1_AXI_MASTER_STICKY_ARES] = { 0x76040, 6 },
+ [GCC_WCSSAON_RESET] = { 0x59010, 0 },
};
static const struct of_device_id gcc_ipq8074_match_table[] = {
--
2.7.4
^ permalink raw reply related
* [PATCH V5 08/10] dt-bindings: firmware: qcom: Add compatible for IPQ8074 SoC
From: Gokul Sriram Palanisamy @ 2020-05-13 9:31 UTC (permalink / raw)
To: gokulsri, sboyd, agross, bjorn.andersson, david.brown, devicetree,
jassisinghbrar, linux-arm-msm, linux-clk, linux-kernel,
linux-remoteproc, mark.rutland, mturquette, ohad, robh+dt,
sricharan, nprakash
In-Reply-To: <1589362265-22702-1-git-send-email-gokulsri@codeaurora.org>
Add compatible for IPQ8074 support.
This does not need clocks for scm calls.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Documentation/devicetree/bindings/firmware/qcom,scm.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.txt b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
index 354b448..7fdd4a1 100644
--- a/Documentation/devicetree/bindings/firmware/qcom,scm.txt
+++ b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
@@ -11,6 +11,7 @@ Required properties:
* "qcom,scm-apq8084"
* "qcom,scm-ipq4019"
* "qcom,scm-ipq806x"
+ * "qcom,scm-ipq8074"
* "qcom,scm-msm8660"
* "qcom,scm-msm8916"
* "qcom,scm-msm8960"
--
2.7.4
^ permalink raw reply related
* [PATCH V5 05/10] remoteproc: qcom: Update regmap offsets for halt register
From: Gokul Sriram Palanisamy @ 2020-05-13 9:31 UTC (permalink / raw)
To: gokulsri, sboyd, agross, bjorn.andersson, david.brown, devicetree,
jassisinghbrar, linux-arm-msm, linux-clk, linux-kernel,
linux-remoteproc, mark.rutland, mturquette, ohad, robh+dt,
sricharan, nprakash
In-Reply-To: <1589362265-22702-1-git-send-email-gokulsri@codeaurora.org>
Fixed issue in reading halt-regs parameter from device-tree.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c
index 0a23aca..49f2d31 100644
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -86,7 +86,7 @@
#define TCSR_WCSS_CLK_MASK 0x1F
#define TCSR_WCSS_CLK_ENABLE 0x14
-#define MAX_HALT_REG 3
+#define MAX_HALT_REG 4
#define WCNSS_PAS_ID 6
@@ -154,6 +154,7 @@ struct wcss_data {
u32 version;
bool aon_reset_required;
bool wcss_q6_reset_required;
+ bool bcr_reset_required;
const char *ssr_name;
const char *sysmon_name;
int ssctl_id;
@@ -868,10 +869,13 @@ static int q6v5_wcss_init_reset(struct q6v5_wcss *wcss,
}
}
- wcss->wcss_q6_bcr_reset = devm_reset_control_get_exclusive(dev, "wcss_q6_bcr_reset");
- if (IS_ERR(wcss->wcss_q6_bcr_reset)) {
- dev_err(wcss->dev, "unable to acquire wcss_q6_bcr_reset\n");
- return PTR_ERR(wcss->wcss_q6_bcr_reset);
+ if (desc->bcr_reset_required) {
+ wcss->wcss_q6_bcr_reset = devm_reset_control_get_exclusive(dev,
+ "wcss_q6_bcr_reset");
+ if (IS_ERR(wcss->wcss_q6_bcr_reset)) {
+ dev_err(wcss->dev, "unable to acquire wcss_q6_bcr_reset\n");
+ return PTR_ERR(wcss->wcss_q6_bcr_reset);
+ }
}
return 0;
@@ -919,9 +923,9 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss,
return -EINVAL;
}
- wcss->halt_q6 = halt_reg[0];
- wcss->halt_wcss = halt_reg[1];
- wcss->halt_nc = halt_reg[2];
+ wcss->halt_q6 = halt_reg[1];
+ wcss->halt_wcss = halt_reg[2];
+ wcss->halt_nc = halt_reg[3];
return 0;
}
@@ -1166,6 +1170,7 @@ static const struct wcss_data wcss_ipq8074_res_init = {
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
.wcss_q6_reset_required = true,
+ .bcr_reset_required = false,
.ssr_name = "q6wcss",
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
@@ -1180,6 +1185,7 @@ static const struct wcss_data wcss_qcs404_res_init = {
.version = WCSS_QCS404,
.aon_reset_required = false,
.wcss_q6_reset_required = false,
+ .bcr_reset_required = true,
.ssr_name = "mpss",
.sysmon_name = "wcnss",
.ssctl_id = 0x12,
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox