* [PATCH 1/3] dt-bindings: Update QorIQ TMU thermal bindings
From: Jia Hongtao @ 2017-01-04 8:57 UTC (permalink / raw)
To: oss, rui.zhang, edubezval, yuantian.tang, robh+dt
Cc: linux-pm, devicetree, linux-kernel, hongtao.jia
In-Reply-To: <1483520271-3838-1-git-send-email-hongtao.jia@nxp.com>
For different types of SoC the sensor id and endianness may vary.
"#thermal-sensor-cells" is used to provide sensor id information.
"little-endian" property is to tell the endianness of TMU.
Signed-off-by: Jia Hongtao <hongtao.jia@nxp.com>
Acked-by: Rob Herring <robh@kernel.org>
---
Documentation/devicetree/bindings/thermal/qoriq-thermal.txt | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt b/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
index 66223d5..20ca4ef 100644
--- a/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
@@ -17,6 +17,12 @@ Required properties:
calibration data, as specified by the SoC reference manual.
The first cell of each pair is the value to be written to TTCFGR,
and the second is the value to be written to TSCFGR.
+- #thermal-sensor-cells : Must be 1. The sensor specifier is the monitoring
+ site ID, and represents the "n" in TRITSRn and TRATSRn.
+
+Optional property:
+- little-endian : If present, the TMU registers are little endian. If absent,
+ the default is big endian.
Example:
@@ -60,4 +66,5 @@ tmu@f0000 {
0x00030000 0x00000012
0x00030001 0x0000001d>;
+ #thermal-sensor-cells = <1>;
};
--
2.1.0.27.g96db324
^ permalink raw reply related
* [PATCH 2/3] powerpc/mpc85xx: Update TMU device tree node for T1040/T1042
From: Jia Hongtao @ 2017-01-04 8:57 UTC (permalink / raw)
To: oss, rui.zhang, edubezval, yuantian.tang, robh+dt
Cc: linux-pm, devicetree, linux-kernel, hongtao.jia
In-Reply-To: <1483520271-3838-1-git-send-email-hongtao.jia@nxp.com>
From: Hongtao Jia <hongtao.jia@nxp.com>
Update #thermal-sensor-cells from 0 to 1 according to the new binding. The
sensor specifier added is the monitoring site ID, and represents the "n" in
TRITSRn and TRATSRn.
Signed-off-by: Jia Hongtao <hongtao.jia@nxp.com>
---
arch/powerpc/boot/dts/fsl/t1040si-post.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
index 44e399b..145c7f4 100644
--- a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
@@ -526,7 +526,7 @@
0x00030000 0x00000012
0x00030001 0x0000001d>;
- #thermal-sensor-cells = <0>;
+ #thermal-sensor-cells = <1>;
};
thermal-zones {
@@ -534,7 +534,7 @@
polling-delay-passive = <1000>;
polling-delay = <5000>;
- thermal-sensors = <&tmu>;
+ thermal-sensors = <&tmu 2>;
trips {
cpu_alert: cpu-alert {
--
2.1.0.27.g96db324
^ permalink raw reply related
* [PATCH 3/3] powerpc/mpc85xx: Update TMU device tree node for T1023/T1024
From: Jia Hongtao @ 2017-01-04 8:57 UTC (permalink / raw)
To: oss, rui.zhang, edubezval, yuantian.tang, robh+dt
Cc: linux-pm, devicetree, linux-kernel, hongtao.jia
In-Reply-To: <1483520271-3838-1-git-send-email-hongtao.jia@nxp.com>
From: Hongtao Jia <hongtao.jia@nxp.com>
Update #thermal-sensor-cells from 0 to 1 according to the new binding. The
sensor specifier added is the monitoring site ID, and represents the "n" in
TRITSRn and TRATSRn.
Signed-off-by: Jia Hongtao <hongtao.jia@nxp.com>
---
arch/powerpc/boot/dts/fsl/t1023si-post.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
index da2894c..4908af5 100644
--- a/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1023si-post.dtsi
@@ -422,7 +422,7 @@
0x00030001 0x0000000d
0x00030002 0x00000019
0x00030003 0x00000024>;
- #thermal-sensor-cells = <0>;
+ #thermal-sensor-cells = <1>;
};
thermal-zones {
@@ -430,7 +430,7 @@
polling-delay-passive = <1000>;
polling-delay = <5000>;
- thermal-sensors = <&tmu>;
+ thermal-sensors = <&tmu 0>;
trips {
cpu_alert: cpu-alert {
--
2.1.0.27.g96db324
^ permalink raw reply related
* Re: [PATCH v5 1/3] drm/exynos: mic: Add mode_set callback function
From: Andrzej Hajda @ 2017-01-04 9:05 UTC (permalink / raw)
To: Hoegeun Kwon, robh, thierry.reding, airlied, kgene, krzk,
inki.dae
Cc: devicetree, linux-samsung-soc, linux-kernel, dri-devel,
jh80.chung, cw00.choi
In-Reply-To: <1483517711-23849-2-git-send-email-hoegeun.kwon@samsung.com>
On 04.01.2017 09:15, Hoegeun Kwon wrote:
> Before applying the patch, used the of_get_videomode function to
> parse the display-timings in the panel which is the child driver
> of dsi in the devicetree. this is wrong. So removed the
> of_get_videomode and fixed to get videomode struct through
> mode_set callback function.
>
> Signed-off-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Only one, non-blocking comment below.
> ---
> drivers/gpu/drm/exynos/exynos_drm_mic.c | 30 +++++++++++++++++++-----------
> 1 file changed, 19 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c
> index a0def0b..a0f459c 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_mic.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c
> @@ -286,13 +286,6 @@ static int parse_dt(struct exynos_mic *mic)
> }
> nodes[j++] = remote_node;
>
> - ret = of_get_videomode(remote_node,
> - &mic->vm, 0);
> - if (ret) {
> - DRM_ERROR("mic: failed to get videomode");
> - goto exit;
> - }
> -
I think the whole parse_dt function should be refactored, but it can be
done later in separate patch.
Regards
Andrzej
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* RE: [PATCH 0/3] QorIQ TMU bindings and device tree update
From: Y.T. Tang @ 2017-01-04 9:19 UTC (permalink / raw)
To: oss@buserror.net, rui.zhang@intel.com, edubezval@gmail.com,
robh+dt@kernel.org, Scott Wood
Cc: linux-pm@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, Troy Jia
In-Reply-To: <1483520271-3838-1-git-send-email-hongtao.jia@nxp.com>
++Scott NXP email address.
Hi Scott,
Could you please give these patch set a little higher priority as Troy's last day is Friday?
We want those get ACKed or address all the major issues before Friday.
Thanks,
Yuantian
> -----Original Message-----
> From: Jia Hongtao [mailto:hongtao.jia@nxp.com]
> Sent: Wednesday, January 04, 2017 4:58 PM
> To: oss@buserror.net; rui.zhang@intel.com; edubezval@gmail.com; Y.T.
> Tang <yuantian.tang@nxp.com>; robh+dt@kernel.org
> Cc: linux-pm@vger.kernel.org; devicetree@vger.kernel.org; linux-
> kernel@vger.kernel.org; Troy Jia <hongtao.jia@nxp.com>
> Subject: [PATCH 0/3] QorIQ TMU bindings and device tree update
>
> As Rui Zhang suggested I combine TMU binding patch and two device tree
> patchset together. He will take all of them after the device tree patchset got
> ACK.
>
> @Scott please help to review the device tree patchset.
> Thanks.
>
> Jia Hongtao (3):
> dt-bindings: Update QorIQ TMU thermal bindings
> powerpc/mpc85xx: Update TMU device tree node for T1040/T1042
> powerpc/mpc85xx: Update TMU device tree node for T1023/T1024
>
> Documentation/devicetree/bindings/thermal/qoriq-thermal.txt | 7
> +++++++
> arch/powerpc/boot/dts/fsl/t1023si-post.dtsi | 4 ++--
> arch/powerpc/boot/dts/fsl/t1040si-post.dtsi | 4 ++--
> 3 files changed, 11 insertions(+), 4 deletions(-)
>
> --
> 2.1.0.27.g96db324
^ permalink raw reply
* [PATCH 0/5] i2c: mux: pca954x: Add interrupt controller support
From: Phil Reid @ 2017-01-04 9:29 UTC (permalink / raw)
To: peda, wsa, robh+dt, mark.rutland, preid, linux-i2c, devicetree
Various muxes can aggregate multiple interrupts from each i2c bus.
All of the muxes with interrupt support combine the active low irq lines
using an internal 'and' function and generate a combined active low
output. The muxes do provide the ability to read a control register to
determine which irq is active. By making the mux an irq controller isr
latenct can potentially be reduced by reading the status register and
then only calling the registered isr on that bus segment.
In addition an additional enable mask is added to work around devices
that assert irq immediately before being setup buy disabling the irq
from the mux until all devices are registered.
Phil Reid (5):
i2c: mux: pca954x: Add missing pca9542 definition to chip_desc
dt: bindings: i2c-mux-pca954x: Add documentation for interrupt
controller
i2c: mux: pca954x: Add interrupt controller support
dt: bindings: i2c-mux-pca954x: Add documentation for
i2c-mux-irq-mask-en
i2c: mux: pca954x: Add irq_mask_en to delay enabling irqs
.../devicetree/bindings/i2c/i2c-mux-pca954x.txt | 17 ++-
drivers/i2c/muxes/i2c-mux-pca954x.c | 140 ++++++++++++++++++++-
2 files changed, 155 insertions(+), 2 deletions(-)
--
1.8.3.1
^ permalink raw reply
* [PATCH 1/5] i2c: mux: pca954x: Add missing pca9542 definition to chip_desc
From: Phil Reid @ 2017-01-04 9:29 UTC (permalink / raw)
To: peda, wsa, robh+dt, mark.rutland, preid, linux-i2c, devicetree
In-Reply-To: <1483522197-38819-1-git-send-email-preid@electromag.com.au>
The spec for the pca954x was missing. This chip is the same as the pca9540
except that it has interrupt lines. While the i2c_device_id table mapped
the pca9542 to the pca9540 definition the compatible table did not. In
preparation for irq support add the pca9542 definition.
Signed-off-by: Phil Reid <preid@electromag.com.au>
---
drivers/i2c/muxes/i2c-mux-pca954x.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index 8bc3d36..981d145 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -83,6 +83,11 @@ struct pca954x {
.enable = 0x4,
.muxtype = pca954x_ismux,
},
+ [pca_9542] = {
+ .nchans = 2,
+ .enable = 0x4,
+ .muxtype = pca954x_ismux,
+ },
[pca_9543] = {
.nchans = 2,
.muxtype = pca954x_isswi,
@@ -109,7 +114,7 @@ struct pca954x {
static const struct i2c_device_id pca954x_id[] = {
{ "pca9540", pca_9540 },
- { "pca9542", pca_9540 },
+ { "pca9542", pca_9542 },
{ "pca9543", pca_9543 },
{ "pca9544", pca_9544 },
{ "pca9545", pca_9545 },
--
1.8.3.1
^ permalink raw reply related
* [PATCH 2/5] dt: bindings: i2c-mux-pca954x: Add documentation for interrupt controller
From: Phil Reid @ 2017-01-04 9:29 UTC (permalink / raw)
To: peda, wsa, robh+dt, mark.rutland, preid, linux-i2c, devicetree
In-Reply-To: <1483522197-38819-1-git-send-email-preid@electromag.com.au>
Various muxes can aggregate multiple irq lines and provide a control
register to determine the active line. Add bindings for interrupt
controller support.
Signed-off-by: Phil Reid <preid@electromag.com.au>
---
Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
index cf53d5f..9f7c275 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
@@ -19,7 +19,14 @@ Optional Properties:
- i2c-mux-idle-disconnect: Boolean; if defined, forces mux to disconnect all
children in idle state. This is necessary for example, if there are several
multiplexers on the bus and the devices behind them use same I2C addresses.
-
+ - interrupt-parent: Phandle for the interrupt controller that services
+ interrupts for this device.
+ - interrupts: Interrupt mapping for IRQ.
+ - interrupt-controller: Marks the device node as a interrupt controller.
+ - #interrupt-cells : Should be two.
+ - first cell is the pin number
+ - second cell is used to specify flags.
+ See also Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
Example:
@@ -29,6 +36,11 @@ Example:
#size-cells = <0>;
reg = <0x74>;
+ interrupt-parent = <&ipic>;
+ interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+ #interrupt-cells=<2>;
+
i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 3/5] i2c: mux: pca954x: Add interrupt controller support
From: Phil Reid @ 2017-01-04 9:29 UTC (permalink / raw)
To: peda, wsa, robh+dt, mark.rutland, preid, linux-i2c, devicetree
In-Reply-To: <1483522197-38819-1-git-send-email-preid@electromag.com.au>
Various muxes can aggregate multiple interrupts from each i2c bus.
All of the muxes with interrupt support combine the active low irq lines
using an internal 'and' function and generate a combined active low
output. The muxes do provide the ability to read a control register to
determine which irq is active. By making the mux an irq controller isr
can potentially be reduced by reading the status register and then only
calling the registered isr on that bus segment.
As there is no irq masking on the mux irq are disabled until irq_unmask is
called at least once.
Signed-off-by: Phil Reid <preid@electromag.com.au>
---
drivers/i2c/muxes/i2c-mux-pca954x.c | 126 ++++++++++++++++++++++++++++++++++++
1 file changed, 126 insertions(+)
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index 981d145..f2dba7c 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -40,14 +40,19 @@
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/i2c/pca954x.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_irq.h>
#include <linux/pm.h>
#include <linux/slab.h>
#define PCA954X_MAX_NCHANS 8
+#define PCA954X_IRQ_OFFSET 4
+
enum pca_type {
pca_9540,
pca_9542,
@@ -62,6 +67,7 @@ enum pca_type {
struct chip_desc {
u8 nchans;
u8 enable; /* used for muxes only */
+ u8 has_irq;
enum muxtype {
pca954x_ismux = 0,
pca954x_isswi
@@ -74,6 +80,9 @@ struct pca954x {
u8 last_chan; /* last register value */
u8 deselect;
struct i2c_client *client;
+
+ struct irq_domain *irq;
+ unsigned int irq_mask;
};
/* Provide specs for the PCA954x types we know about */
@@ -86,19 +95,23 @@ struct pca954x {
[pca_9542] = {
.nchans = 2,
.enable = 0x4,
+ .has_irq = 1,
.muxtype = pca954x_ismux,
},
[pca_9543] = {
.nchans = 2,
+ .has_irq = 1,
.muxtype = pca954x_isswi,
},
[pca_9544] = {
.nchans = 4,
.enable = 0x4,
+ .has_irq = 1,
.muxtype = pca954x_ismux,
},
[pca_9545] = {
.nchans = 4,
+ .has_irq = 1,
.muxtype = pca954x_isswi,
},
[pca_9547] = {
@@ -203,6 +216,104 @@ static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan)
return pca954x_reg_write(muxc->parent, client, data->last_chan);
}
+static irqreturn_t pca954x_irq_handler(int irq, void *dev_id)
+{
+ struct pca954x *data = dev_id;
+ unsigned int child_irq;
+ int ret, i, handled;
+
+ ret = i2c_smbus_read_byte(data->client);
+ if (ret < 0)
+ return IRQ_NONE;
+
+ for (i = 0; i < data->chip->nchans; i++) {
+ if (ret & BIT(PCA954X_IRQ_OFFSET+i)) {
+ child_irq = irq_linear_revmap(data->irq, i);
+ handle_nested_irq(child_irq);
+ handled++;
+ }
+ }
+ return handled ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static void pca954x_irq_mask(struct irq_data *idata)
+{
+ struct pca954x *data = irq_data_get_irq_chip_data(idata);
+ unsigned int pos = idata->hwirq;
+
+ data->irq_mask &= ~BIT(pos);
+ if (!data->irq_mask)
+ disable_irq(data->client->irq);
+}
+
+static void pca954x_irq_unmask(struct irq_data *idata)
+{
+ struct pca954x *data = irq_data_get_irq_chip_data(idata);
+ unsigned int pos = idata->hwirq;
+
+ if (!data->irq_mask)
+ enable_irq(data->client->irq);
+ data->irq_mask |= BIT(pos);
+}
+
+static int pca954x_irq_set_type(struct irq_data *idata, unsigned int type)
+{
+ if ((type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_LEVEL_LOW)
+ return -EINVAL;
+ return 0;
+}
+
+static struct irq_chip pca954x_irq_chip = {
+ .name = "i2c-mux-pca954x",
+ .irq_mask = pca954x_irq_mask,
+ .irq_unmask = pca954x_irq_unmask,
+ .irq_set_type = pca954x_irq_set_type,
+};
+
+static int pca953x_irq_setup(struct i2c_mux_core *muxc)
+{
+ struct pca954x *data = i2c_mux_priv(muxc);
+ struct i2c_client *client = data->client;
+ int c, err, irq;
+
+ if (!data->chip->has_irq || client->irq <= 0)
+ return 0;
+
+ data->irq = irq_domain_add_linear(client->dev.of_node,
+ data->chip->nchans,
+ &irq_domain_simple_ops, data);
+ if (!data->irq) {
+ err = -ENODEV;
+ goto err_irq_domain;
+ }
+
+ for (c = 0; c < data->chip->nchans; c++) {
+ irq = irq_create_mapping(data->irq, c);
+ irq_set_chip_data(irq, data);
+ irq_set_chip_and_handler(irq, &pca954x_irq_chip,
+ handle_simple_irq);
+ }
+
+ err = devm_request_threaded_irq(&client->dev, data->client->irq, NULL,
+ pca954x_irq_handler,
+ IRQF_ONESHOT | IRQF_SHARED,
+ "pca953x", data);
+ if (err)
+ goto err_req_irq;
+
+ disable_irq(data->client->irq);
+
+ return 0;
+err_req_irq:
+ for (c = 0; c < data->chip->nchans; c++) {
+ irq = irq_find_mapping(data->irq, c);
+ irq_dispose_mapping(irq);
+ }
+ irq_domain_remove(data->irq);
+err_irq_domain:
+ return err;
+}
+
/*
* I2C init/probing/exit functions
*/
@@ -258,6 +369,10 @@ static int pca954x_probe(struct i2c_client *client,
idle_disconnect_dt = of_node &&
of_property_read_bool(of_node, "i2c-mux-idle-disconnect");
+ ret = pca953x_irq_setup(muxc);
+ if (ret)
+ goto irq_setup_failed;
+
/* Now create an adapter for each channel */
for (num = 0; num < data->chip->nchans; num++) {
bool idle_disconnect_pd = false;
@@ -294,6 +409,7 @@ static int pca954x_probe(struct i2c_client *client,
return 0;
+irq_setup_failed:
virt_reg_failed:
i2c_mux_del_adapters(muxc);
return ret;
@@ -302,6 +418,16 @@ static int pca954x_probe(struct i2c_client *client,
static int pca954x_remove(struct i2c_client *client)
{
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
+ struct pca954x *data = i2c_mux_priv(muxc);
+ int c, irq;
+
+ if (data->irq) {
+ for (c = 0; c < data->chip->nchans; c++) {
+ irq = irq_find_mapping(data->irq, c);
+ irq_dispose_mapping(irq);
+ }
+ irq_domain_remove(data->irq);
+ }
i2c_mux_del_adapters(muxc);
return 0;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 4/5] dt: bindings: i2c-mux-pca954x: Add documentation for i2c-mux-irq-mask-en
From: Phil Reid @ 2017-01-04 9:29 UTC (permalink / raw)
To: peda, wsa, robh+dt, mark.rutland, preid, linux-i2c, devicetree
In-Reply-To: <1483522197-38819-1-git-send-email-preid@electromag.com.au>
Unfortunately some hardware device will assert their irq line immediately
on power on and provide no mechanism to mask the irq. As the i2c muxes
provide no method to mask irq line this provides a work around by keeping
the parent irq masked until enough device drivers have loaded to service
all pending interrupts.
For example the the ltc1760 assert its SMBALERT irq immediately on power
on. With two ltc1760 attached to bus 0 & 1 on a pca954x mux when the first
device is registered irq are enabled and fire continuously as the second
device driver has not yet loaded. Setting this parameter to 0x3 while
delay the irq being enabled until both devices are ready.
Signed-off-by: Phil Reid <preid@electromag.com.au>
---
Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
index 9f7c275..d3e63dc 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
@@ -19,6 +19,8 @@ Optional Properties:
- i2c-mux-idle-disconnect: Boolean; if defined, forces mux to disconnect all
children in idle state. This is necessary for example, if there are several
multiplexers on the bus and the devices behind them use same I2C addresses.
+ - i2c-mux-irq-mask-en: BitMask; Defines a mask for which irq lines need to be
+ unmasked before the parent irq line in enabled.
- interrupt-parent: Phandle for the interrupt controller that services
interrupts for this device.
- interrupts: Interrupt mapping for IRQ.
@@ -36,6 +38,7 @@ Example:
#size-cells = <0>;
reg = <0x74>;
+ i2c-mux-irq-mask-en = <0x3>;
interrupt-parent = <&ipic>;
interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 5/5] i2c: mux: pca954x: Add irq_mask_en to delay enabling irqs
From: Phil Reid @ 2017-01-04 9:29 UTC (permalink / raw)
To: peda, wsa, robh+dt, mark.rutland, preid, linux-i2c, devicetree
In-Reply-To: <1483522197-38819-1-git-send-email-preid@electromag.com.au>
Unfortunately some hardware device will assert their irq line immediately
on power on and provide no mechanism to mask the irq. As the i2c muxes
provide no method to mask irq line this provides a work around by keeping
the parent irq masked until enough device drivers have loaded to service
all pending interrupts.
For example the the ltc1760 assert its SMBALERT irq immediately on power
on. With two ltc1760 attached to bus 0 & 1 on a pca954x mux when the first
device is registered irq are enabled and fire continuously as the second
device driver has not yet loaded. Setting this parameter to 0x3 while
delay the irq being enabled until both devices are ready.
Signed-off-by: Phil Reid <preid@electromag.com.au>
---
drivers/i2c/muxes/i2c-mux-pca954x.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index f2dba7c..16269e7 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -83,6 +83,7 @@ struct pca954x {
struct irq_domain *irq;
unsigned int irq_mask;
+ unsigned int irq_mask_en;
};
/* Provide specs for the PCA954x types we know about */
@@ -251,9 +252,12 @@ static void pca954x_irq_unmask(struct irq_data *idata)
struct pca954x *data = irq_data_get_irq_chip_data(idata);
unsigned int pos = idata->hwirq;
- if (!data->irq_mask)
+ if (!data->irq_mask_en && !data->irq_mask)
enable_irq(data->client->irq);
data->irq_mask |= BIT(pos);
+ if (data->irq_mask_en &&
+ (data->irq_mask & data->irq_mask) == data->irq_mask_en)
+ enable_irq(data->client->irq);
}
static int pca954x_irq_set_type(struct irq_data *idata, unsigned int type)
@@ -369,6 +373,9 @@ static int pca954x_probe(struct i2c_client *client,
idle_disconnect_dt = of_node &&
of_property_read_bool(of_node, "i2c-mux-idle-disconnect");
+ of_property_read_u32(of_node, "i2c-mux-irq-mask-en",
+ &data->irq_mask_en);
+
ret = pca953x_irq_setup(muxc);
if (ret)
goto irq_setup_failed;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 0/2] ARM: dts: oxnas: Update with dt-bindings
From: Neil Armstrong @ 2017-01-04 9:30 UTC (permalink / raw)
To: linux-oxnas; +Cc: Neil Armstrong, linux-arm-kernel, devicetree, linux-kernel
This patchsets updates the OX810SE and OX820 dtsi with the reset and
clock dt-bindings includes then replaces magic values with bindings
defines.
Neil Armstrong (2):
ARM: dts: OX810: Update with dt-bindings includes
ARM: dts: OX820: Update with dt-bindings includes
arch/arm/boot/dts/ox810se.dtsi | 10 ++++++----
arch/arm/boot/dts/ox820.dtsi | 14 ++++++++------
2 files changed, 14 insertions(+), 10 deletions(-)
--
2.7.0
^ permalink raw reply
* [PATCH 1/2] ARM: dts: OX810: Update with dt-bindings includes
From: Neil Armstrong @ 2017-01-04 9:30 UTC (permalink / raw)
To: linux-oxnas; +Cc: Neil Armstrong, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20170104093046.12428-1-narmstrong@baylibre.com>
Add OX810SE dt-bindings includes files for clocks and resets, replace
resets numbers by human readable defines.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm/boot/dts/ox810se.dtsi | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/ox810se.dtsi b/arch/arm/boot/dts/ox810se.dtsi
index ce13705..46aa6db 100644
--- a/arch/arm/boot/dts/ox810se.dtsi
+++ b/arch/arm/boot/dts/ox810se.dtsi
@@ -7,6 +7,8 @@
*/
/include/ "skeleton.dtsi"
+#include <dt-bindings/clock/oxsemi,ox810se.h>
+#include <dt-bindings/reset/oxsemi,ox810se.h>
/ {
compatible = "oxsemi,ox810se";
@@ -242,7 +244,7 @@
current-speed = <115200>;
no-loopback-test;
status = "disabled";
- resets = <&reset 17>;
+ resets = <&reset RESET_UART1>;
};
uart1: serial@300000 {
@@ -256,7 +258,7 @@
current-speed = <115200>;
no-loopback-test;
status = "disabled";
- resets = <&reset 18>;
+ resets = <&reset RESET_UART2>;
};
uart2: serial@900000 {
@@ -270,7 +272,7 @@
current-speed = <115200>;
no-loopback-test;
status = "disabled";
- resets = <&reset 22>;
+ resets = <&reset RESET_UART3>;
};
uart3: serial@a00000 {
@@ -284,7 +286,7 @@
current-speed = <115200>;
no-loopback-test;
status = "disabled";
- resets = <&reset 23>;
+ resets = <&reset RESET_UART4>;
};
};
--
2.7.0
^ permalink raw reply related
* [PATCH 2/2] ARM: dts: OX820: Update with dt-bindings includes
From: Neil Armstrong @ 2017-01-04 9:30 UTC (permalink / raw)
To: linux-oxnas; +Cc: devicetree, linux-kernel, linux-arm-kernel, Neil Armstrong
In-Reply-To: <20170104093046.12428-1-narmstrong@baylibre.com>
Add OX820 dt-bindings includes files for clocks and resets, replace
resets numbers by human readable defines.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm/boot/dts/ox820.dtsi | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/arch/arm/boot/dts/ox820.dtsi b/arch/arm/boot/dts/ox820.dtsi
index e40f282..4592075 100644
--- a/arch/arm/boot/dts/ox820.dtsi
+++ b/arch/arm/boot/dts/ox820.dtsi
@@ -8,6 +8,8 @@
/include/ "skeleton.dtsi"
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/oxsemi,ox820.h>
+#include <dt-bindings/reset/oxsemi,ox820.h>
/ {
compatible = "oxsemi,ox820";
@@ -83,8 +85,8 @@
nandc: nand-controller@41000000 {
compatible = "oxsemi,ox820-nand";
reg = <0x41000000 0x100000>;
- clocks = <&stdclk 11>;
- resets = <&reset 15>;
+ clocks = <&stdclk CLK_820_NAND>;
+ resets = <&reset RESET_NAND>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
@@ -99,9 +101,9 @@
mac-address = [000000000000]; /* Filled in by U-Boot */
phy-mode = "rgmii";
- clocks = <&stdclk 9>, <&gmacclk>;
+ clocks = <&stdclk CLK_820_ETHA>, <&gmacclk>;
clock-names = "gmac", "stmmaceth";
- resets = <&reset 6>;
+ resets = <&reset RESET_MAC>;
/* Regmap for sys registers */
oxsemi,sys-ctrl = <&sys>;
@@ -208,7 +210,7 @@
no-loopback-test;
status = "disabled";
clocks = <&sysclk>;
- resets = <&reset 17>;
+ resets = <&reset RESET_UART1>;
};
uart1: serial@300000 {
@@ -222,7 +224,7 @@
no-loopback-test;
status = "disabled";
clocks = <&sysclk>;
- resets = <&reset 18>;
+ resets = <&reset RESET_UART2>;
};
rps@400000 {
--
2.7.0
^ permalink raw reply related
* Re: [PATCH v5 2/3] drm/panel: Add support for S6E3HA2 panel driver on TM2 board
From: Andrzej Hajda @ 2017-01-04 9:39 UTC (permalink / raw)
To: Hoegeun Kwon, robh, thierry.reding, airlied, kgene, krzk,
inki.dae
Cc: devicetree, linux-samsung-soc, Donghwa Lee, linux-kernel,
dri-devel, jh80.chung, cw00.choi, Hyungwon Hwang
In-Reply-To: <1483517711-23849-3-git-send-email-hoegeun.kwon@samsung.com>
On 04.01.2017 09:15, Hoegeun Kwon wrote:
> This patch add support for MIPI-DSI based S6E3HA2 AMOLED panel
> driver. This panel has 1440x2560 resolution in 5.7-inch physical
> panel in the TM2 device.
>
> Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> Signed-off-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
> ---
> .../bindings/display/panel/samsung,s6e3ha2.txt | 40 ++
> drivers/gpu/drm/panel/Kconfig | 6 +
> drivers/gpu/drm/panel/Makefile | 1 +
> drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c | 741 +++++++++++++++++++++
> 4 files changed, 788 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
> create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c
>
> diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt b/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
> new file mode 100644
> index 0000000..6879f51
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
> @@ -0,0 +1,40 @@
> +Samsung S6E3HA2 5.7" 1440x2560 AMOLED panel
> +
> +Required properties:
> + - compatible: "samsung,s6e3ha2"
> + - reg: the virtual channel number of a DSI peripheral
> + - vdd3-supply: I/O voltage supply
> + - vci-supply: voltage supply for analog circuits
> + - reset-gpios: a GPIO spec for the reset pin (active low)
> + - enable-gpios: a GPIO spec for the panel enable pin (active high)
> + - te-gpios: a GPIO spec for the tearing effect synchronization signal
> + gpio pin (active high)
> +
> +The device node can contain one 'port' child node with one child
> +'endpoint' node, according to the bindings defined in [1]. This
> +node should describe panel's video bus.
> +
> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
> +
> +Example:
> +
> +&dsi {
> + ...
> +
> + panel@0 {
> + compatible = "samsung,s6e3ha2";
> + reg = <0>;
> + vdd3-supply = <&ldo27_reg>;
> + vci-supply = <&ldo28_reg>;
> + reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
> + enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
> + te-gpios = <&gpf1 3 GPIO_ACTIVE_HIGH>;
> +
> + port {
> + panel_in: endpoint {
> + remote-endpoint = <&dsi_out>;
> + };
> + };
> + };
> +};
> +
> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> index 62aba97..eea2902 100644
> --- a/drivers/gpu/drm/panel/Kconfig
> +++ b/drivers/gpu/drm/panel/Kconfig
> @@ -52,6 +52,12 @@ config DRM_PANEL_PANASONIC_VVX10F034N00
> WUXGA (1920x1200) Novatek NT1397-based DSI panel as found in some
> Xperia Z2 tablets
>
> +config DRM_PANEL_SAMSUNG_S6E3HA2
> + tristate "Samsung S6E3HA2 DSI video mode panel"
> + depends on OF
> + depends on DRM_MIPI_DSI
Spare space.
> + select VIDEOMODE_HELPERS
> +
> config DRM_PANEL_SAMSUNG_S6E8AA0
> tristate "Samsung S6E8AA0 DSI video mode panel"
> depends on OF
> diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
> index a5c7ec0..1d483b0 100644
> --- a/drivers/gpu/drm/panel/Makefile
> +++ b/drivers/gpu/drm/panel/Makefile
> @@ -3,6 +3,7 @@ obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
> obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
> obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o
> obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
> +obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o
> obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o
> obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
> obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
> diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c b/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c
> new file mode 100644
> index 0000000..8c5a1c2
> --- /dev/null
> +++ b/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c
> @@ -0,0 +1,741 @@
> +/*
> + * MIPI-DSI based s6e3ha2 AMOLED 5.7 inch panel driver.
> + *
> + * Copyright (c) 2016 Samsung Electronics Co., Ltd.
> + * Donghwa Lee <dh09.lee@samsung.com>
> + * Hyungwon Hwang <human.hwang@samsung.com>
> + * Hoegeun Kwon <hoegeun.kwon@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <drm/drmP.h>
> +#include <drm/drm_mipi_dsi.h>
> +#include <drm/drm_panel.h>
> +#include <linux/backlight.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/regulator/consumer.h>
> +
> +#define S6E3HA2_MIN_BRIGHTNESS 0
> +#define S6E3HA2_MAX_BRIGHTNESS 100
> +#define S6E3HA2_DEFAULT_BRIGHTNESS 80
> +
> +#define S6E3HA2_NUM_GAMMA_STEPS 46
> +#define S6E3HA2_GAMMA_CMD_CNT 35
> +#define S6E3HA2_VINT_STATUS_MAX 10
> +
> +static const u8 gamma_tbl[S6E3HA2_NUM_GAMMA_STEPS][S6E3HA2_GAMMA_CMD_CNT] = {
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x82, 0x83,
> + 0x85, 0x88, 0x8b, 0x8b, 0x84, 0x88, 0x82, 0x82, 0x89, 0x86, 0x8c,
> + 0x94, 0x84, 0xb1, 0xaf, 0x8e, 0xcf, 0xad, 0xc9, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x84, 0x84,
> + 0x85, 0x87, 0x8b, 0x8a, 0x84, 0x88, 0x82, 0x82, 0x89, 0x86, 0x8a,
> + 0x93, 0x84, 0xb0, 0xae, 0x8e, 0xc9, 0xa8, 0xc5, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
> + 0x85, 0x86, 0x8a, 0x8a, 0x84, 0x88, 0x81, 0x84, 0x8a, 0x88, 0x8a,
> + 0x91, 0x84, 0xb1, 0xae, 0x8b, 0xd5, 0xb2, 0xcc, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
> + 0x85, 0x86, 0x8a, 0x8a, 0x84, 0x87, 0x81, 0x84, 0x8a, 0x87, 0x8a,
> + 0x91, 0x85, 0xae, 0xac, 0x8a, 0xc3, 0xa3, 0xc0, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x85, 0x85,
> + 0x86, 0x85, 0x88, 0x89, 0x84, 0x89, 0x82, 0x84, 0x87, 0x85, 0x8b,
> + 0x91, 0x88, 0xad, 0xab, 0x8a, 0xb7, 0x9b, 0xb6, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
> + 0x85, 0x86, 0x89, 0x8a, 0x84, 0x89, 0x83, 0x83, 0x86, 0x84, 0x8b,
> + 0x90, 0x84, 0xb0, 0xae, 0x8b, 0xce, 0xad, 0xc8, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
> + 0x85, 0x87, 0x89, 0x8a, 0x83, 0x87, 0x82, 0x85, 0x88, 0x87, 0x89,
> + 0x8f, 0x84, 0xac, 0xaa, 0x89, 0xb1, 0x98, 0xaf, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
> + 0x85, 0x86, 0x88, 0x89, 0x84, 0x88, 0x83, 0x82, 0x85, 0x84, 0x8c,
> + 0x91, 0x86, 0xac, 0xaa, 0x89, 0xc2, 0xa5, 0xbd, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> + 0x85, 0x87, 0x89, 0x8a, 0x83, 0x87, 0x82, 0x85, 0x88, 0x87, 0x88,
> + 0x8b, 0x82, 0xad, 0xaa, 0x8a, 0xc2, 0xa5, 0xbd, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
> + 0x85, 0x86, 0x87, 0x89, 0x84, 0x88, 0x83, 0x82, 0x85, 0x84, 0x8a,
> + 0x8e, 0x84, 0xae, 0xac, 0x89, 0xda, 0xb7, 0xd0, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> + 0x85, 0x86, 0x87, 0x89, 0x84, 0x88, 0x83, 0x80, 0x83, 0x82, 0x8b,
> + 0x8e, 0x85, 0xac, 0xaa, 0x89, 0xc8, 0xaa, 0xc1, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> + 0x85, 0x86, 0x87, 0x89, 0x81, 0x85, 0x81, 0x84, 0x86, 0x84, 0x8c,
> + 0x8c, 0x84, 0xa9, 0xa8, 0x87, 0xa3, 0x92, 0xa1, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> + 0x85, 0x86, 0x87, 0x89, 0x84, 0x86, 0x83, 0x80, 0x83, 0x81, 0x8c,
> + 0x8d, 0x84, 0xaa, 0xaa, 0x89, 0xce, 0xaf, 0xc5, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> + 0x85, 0x86, 0x87, 0x89, 0x81, 0x83, 0x80, 0x83, 0x85, 0x85, 0x8c,
> + 0x8c, 0x84, 0xa8, 0xa8, 0x88, 0xb5, 0x9f, 0xb0, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> + 0x86, 0x86, 0x87, 0x88, 0x81, 0x83, 0x80, 0x83, 0x85, 0x85, 0x8c,
> + 0x8b, 0x84, 0xab, 0xa8, 0x86, 0xd4, 0xb4, 0xc9, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> + 0x86, 0x86, 0x87, 0x88, 0x81, 0x83, 0x80, 0x84, 0x84, 0x85, 0x8b,
> + 0x8a, 0x83, 0xa6, 0xa5, 0x84, 0xbb, 0xa4, 0xb3, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> + 0x86, 0x85, 0x86, 0x86, 0x82, 0x85, 0x81, 0x82, 0x83, 0x84, 0x8e,
> + 0x8b, 0x83, 0xa4, 0xa3, 0x8a, 0xa1, 0x93, 0x9d, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83,
> + 0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x82, 0x82, 0x84, 0x8e,
> + 0x8b, 0x83, 0xa4, 0xa2, 0x86, 0xc1, 0xa9, 0xb7, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83,
> + 0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x82, 0x82, 0x84, 0x8d,
> + 0x89, 0x82, 0xa2, 0xa1, 0x84, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83,
> + 0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x83, 0x83, 0x85, 0x8c,
> + 0x87, 0x7f, 0xa2, 0x9d, 0x88, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xbb, 0x00, 0xc5, 0x00, 0xb4, 0x87, 0x86, 0x86, 0x84, 0x83,
> + 0x86, 0x87, 0x87, 0x87, 0x80, 0x82, 0x7f, 0x86, 0x86, 0x88, 0x8a,
> + 0x84, 0x7e, 0x9d, 0x9c, 0x82, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xbd, 0x00, 0xc7, 0x00, 0xb7, 0x87, 0x85, 0x85, 0x84, 0x83,
> + 0x86, 0x86, 0x86, 0x88, 0x81, 0x83, 0x80, 0x83, 0x84, 0x85, 0x8a,
> + 0x85, 0x7e, 0x9c, 0x9b, 0x85, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xc0, 0x00, 0xca, 0x00, 0xbb, 0x87, 0x86, 0x85, 0x83, 0x83,
> + 0x85, 0x86, 0x86, 0x88, 0x81, 0x83, 0x80, 0x84, 0x85, 0x86, 0x89,
> + 0x83, 0x7d, 0x9c, 0x99, 0x87, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xc4, 0x00, 0xcd, 0x00, 0xbe, 0x87, 0x86, 0x85, 0x83, 0x83,
> + 0x86, 0x85, 0x85, 0x87, 0x81, 0x82, 0x80, 0x82, 0x82, 0x83, 0x8a,
> + 0x85, 0x7f, 0x9f, 0x9b, 0x86, 0xb4, 0xa1, 0xac, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xc7, 0x00, 0xd0, 0x00, 0xc2, 0x87, 0x85, 0x85, 0x83, 0x82,
> + 0x85, 0x85, 0x85, 0x86, 0x82, 0x83, 0x80, 0x82, 0x82, 0x84, 0x87,
> + 0x86, 0x80, 0x9e, 0x9a, 0x87, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xca, 0x00, 0xd2, 0x00, 0xc5, 0x87, 0x85, 0x84, 0x82, 0x82,
> + 0x84, 0x85, 0x85, 0x86, 0x81, 0x82, 0x7f, 0x82, 0x82, 0x84, 0x88,
> + 0x86, 0x81, 0x9d, 0x98, 0x86, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xce, 0x00, 0xd6, 0x00, 0xca, 0x86, 0x85, 0x84, 0x83, 0x83,
> + 0x85, 0x84, 0x84, 0x85, 0x81, 0x82, 0x80, 0x81, 0x81, 0x82, 0x89,
> + 0x86, 0x81, 0x9c, 0x97, 0x86, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xd1, 0x00, 0xd9, 0x00, 0xce, 0x86, 0x84, 0x83, 0x83, 0x82,
> + 0x85, 0x85, 0x85, 0x86, 0x81, 0x83, 0x81, 0x82, 0x82, 0x83, 0x86,
> + 0x83, 0x7f, 0x99, 0x95, 0x86, 0xbb, 0xa4, 0xb3, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xd4, 0x00, 0xdb, 0x00, 0xd1, 0x86, 0x85, 0x83, 0x83, 0x82,
> + 0x85, 0x84, 0x84, 0x85, 0x80, 0x83, 0x82, 0x80, 0x80, 0x81, 0x87,
> + 0x84, 0x81, 0x98, 0x93, 0x85, 0xae, 0x9c, 0xa8, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xd8, 0x00, 0xde, 0x00, 0xd6, 0x86, 0x84, 0x83, 0x81, 0x81,
> + 0x83, 0x85, 0x85, 0x85, 0x82, 0x83, 0x81, 0x81, 0x81, 0x83, 0x86,
> + 0x84, 0x80, 0x98, 0x91, 0x85, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xdc, 0x00, 0xe2, 0x00, 0xda, 0x85, 0x84, 0x83, 0x82, 0x82,
> + 0x84, 0x84, 0x84, 0x85, 0x81, 0x82, 0x82, 0x80, 0x80, 0x81, 0x83,
> + 0x82, 0x7f, 0x99, 0x93, 0x86, 0x94, 0x8b, 0x92, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xdf, 0x00, 0xe5, 0x00, 0xde, 0x85, 0x84, 0x82, 0x82, 0x82,
> + 0x84, 0x83, 0x83, 0x84, 0x81, 0x81, 0x80, 0x83, 0x82, 0x84, 0x82,
> + 0x81, 0x7f, 0x99, 0x92, 0x86, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
> + 0x82, 0x83, 0x83, 0x84, 0x80, 0x81, 0x80, 0x83, 0x83, 0x84, 0x80,
> + 0x81, 0x7c, 0x99, 0x92, 0x87, 0xa1, 0x93, 0x9d, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x85, 0x84, 0x83, 0x81, 0x81,
> + 0x82, 0x82, 0x82, 0x83, 0x80, 0x81, 0x80, 0x81, 0x80, 0x82, 0x83,
> + 0x82, 0x80, 0x91, 0x8d, 0x83, 0x9a, 0x90, 0x96, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
> + 0x82, 0x83, 0x83, 0x84, 0x80, 0x81, 0x80, 0x81, 0x80, 0x82, 0x83,
> + 0x81, 0x7f, 0x91, 0x8c, 0x82, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
> + 0x82, 0x83, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x80, 0x82, 0x82,
> + 0x82, 0x7f, 0x94, 0x89, 0x84, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
> + 0x82, 0x83, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x80, 0x82, 0x83,
> + 0x82, 0x7f, 0x91, 0x85, 0x81, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
> + 0x82, 0x83, 0x83, 0x83, 0x80, 0x80, 0x7f, 0x83, 0x82, 0x84, 0x83,
> + 0x82, 0x7f, 0x90, 0x84, 0x81, 0x9a, 0x90, 0x96, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x80, 0x80,
> + 0x82, 0x83, 0x83, 0x83, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x81, 0x81,
> + 0x82, 0x83, 0x7e, 0x80, 0x7c, 0xa4, 0x97, 0x9f, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xe9, 0x00, 0xec, 0x00, 0xe8, 0x84, 0x83, 0x82, 0x81, 0x81,
> + 0x82, 0x82, 0x82, 0x83, 0x7f, 0x7f, 0x7f, 0x81, 0x80, 0x82, 0x83,
> + 0x83, 0x84, 0x79, 0x7c, 0x79, 0xb1, 0xa0, 0xaa, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xed, 0x00, 0xf0, 0x00, 0xec, 0x83, 0x83, 0x82, 0x80, 0x80,
> + 0x81, 0x82, 0x82, 0x82, 0x7f, 0x7f, 0x7e, 0x81, 0x81, 0x82, 0x80,
> + 0x81, 0x81, 0x84, 0x84, 0x83, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xf1, 0x00, 0xf4, 0x00, 0xf1, 0x83, 0x82, 0x82, 0x80, 0x80,
> + 0x81, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x7d,
> + 0x7e, 0x7f, 0x84, 0x84, 0x83, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xf6, 0x00, 0xf7, 0x00, 0xf5, 0x82, 0x82, 0x81, 0x80, 0x80,
> + 0x80, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x82,
> + 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x00, 0xfa, 0x00, 0xfb, 0x00, 0xfa, 0x81, 0x81, 0x81, 0x80, 0x80,
> + 0x80, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
> + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80,
> + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
> + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> + 0x00, 0x00 },
> + { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80,
> + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
> + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> + 0x00, 0x00 }
> +};
> +
> +unsigned char vint_table[S6E3HA2_VINT_STATUS_MAX] = {
> + 0x18, 0x19, 0x1a, 0x1b, 0x1c,
> + 0x1d, 0x1e, 0x1f, 0x20, 0x21
> +};
> +
> +struct s6e3ha2 {
> + struct device *dev;
> + struct drm_panel panel;
> + struct backlight_device *bl_dev;
> +
> + struct regulator_bulk_data supplies[2];
> + struct gpio_desc *reset_gpio;
> + struct gpio_desc *enable_gpio;
> +
> + /* This field is tested by functions directly accessing DSI bus before
> + * transfer, transfer is skipped if it is set. In case of transfer
> + * failure or unexpected response the field is set to error value.
> + * Such construct allows to eliminate many checks in higher level
> + * functions.
> + */
> + int error;
> +};
> +
> +static int s6e3ha2_clear_error(struct s6e3ha2 *ctx)
> +{
> + int ret = ctx->error;
> +
> + ctx->error = 0;
> + return ret;
> +}
> +
> +static void s6e3ha2_dcs_write(struct s6e3ha2 *ctx, const void *data, size_t len)
> +{
> + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
> + ssize_t ret;
> +
> + if (ctx->error < 0)
> + return;
> +
> + ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
> + if (ret < 0) {
> + dev_err(ctx->dev, "error %zd writing dcs seq: %*ph\n",
> + ret, (int)len, data);
> + ctx->error = ret;
> + }
> +}
> +
> +#define s6e3ha2_dcs_write_seq_static(ctx, seq...) do { \
> + static const u8 d[] = { seq }; \
> + s6e3ha2_dcs_write(ctx, d, ARRAY_SIZE(d)); \
> +} while (0)
> +
> +static void s6e3ha2_test_key_on_f0(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xf0, 0x5a, 0x5a);
> +}
> +
> +static void s6e3ha2_test_key_off_f0(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xf0, 0xa5, 0xa5);
> +}
> +
> +static void s6e3ha2_test_key_on_fc(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xfc, 0x5a, 0x5a);
> +}
> +
> +static void s6e3ha2_test_key_off_fc(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xfc, 0xa5, 0xa5);
> +}
> +
> +static void s6e3ha2_single_dsi_set(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xf2, 0x67);
> + s6e3ha2_dcs_write_seq_static(ctx, 0xf9, 0x09);
> +}
> +
> +static void s6e3ha2_freq_calibration(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xfd, 0x1c);
> + s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x20, 0x39);
> + s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0xa0);
> + s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x20);
> + s6e3ha2_dcs_write_seq_static(ctx, 0xce, 0x03, 0x3b, 0x12, 0x62,
> + 0x40, 0x80, 0xc0, 0x28, 0x28, 0x28, 0x28, 0x39, 0xc5);
> +}
> +
> +static void s6e3ha2_aor_control(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xb2, 0x03, 0x10);
> +}
> +
> +static void s6e3ha2_caps_elvss_set(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xb6, 0x9c, 0x0a);
> +}
> +
> +static void s6e3ha2_acl_off(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0x55, 0x00);
> +}
> +
> +static void s6e3ha2_acl_off_opr(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xb5, 0x40);
> +}
> +
> +static void s6e3ha2_test_global(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xb0, 0x07);
> +}
> +
> +static void s6e3ha2_test(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xb8, 0x19);
> +}
> +
> +static void s6e3ha2_touch_hsync_on1(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx,
> + 0xbd, 0x33, 0x11, 0x02, 0x16, 0x02, 0x16);
> +}
> +
> +static void s6e3ha2_pentile_control(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xc0, 0x00, 0x00, 0xd8, 0xd8);
> +}
> +
> +static void s6e3ha2_poc_global(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xb0, 0x20);
> +}
> +
> +static void s6e3ha2_poc_setting(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x08);
> +}
> +
> +static void s6e3ha2_pcd_set_off(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xcc, 0x40, 0x51);
> +}
> +
> +static void s6e3ha2_err_fg_set(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xed, 0x44);
> +}
> +
> +static void s6e3ha2_hbm_off(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0x53, 0x00);
> +}
> +
> +static void s6e3ha2_te_start_setting(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xb9, 0x10, 0x09, 0xff, 0x00, 0x09);
> +}
> +
> +static void s6e3ha2_gamma_update(struct s6e3ha2 *ctx)
> +{
> + s6e3ha2_dcs_write_seq_static(ctx, 0xf7, 0x03);
> + ndelay(100); /* need for 100ns delay */
> + s6e3ha2_dcs_write_seq_static(ctx, 0xf7, 0x00);
> +}
> +
> +static int s6e3ha2_get_brightness(struct backlight_device *bl_dev)
> +{
> + return bl_dev->props.brightness;
> +}
> +
> +static void s6e3ha2_set_vint(struct s6e3ha2 *ctx)
> +{
> + struct backlight_device *bl_dev = ctx->bl_dev;
> + unsigned int brightness = bl_dev->props.brightness;
> + unsigned char data[] = { 0xf4, 0x8b,
> + vint_table[brightness * (S6E3HA2_VINT_STATUS_MAX - 1) /
> + S6E3HA2_MAX_BRIGHTNESS] };
> +
> + s6e3ha2_dcs_write(ctx, data, 3);
It would be safer/cleaner to use sizeof(data) or ARRAY_SIZE(data)
instead of 3 here.
> +}
> +
> +static unsigned int s6e3ha2_get_brightness_index(unsigned int brightness)
> +{
> + return (brightness * (S6E3HA2_NUM_GAMMA_STEPS - 1)) /
> + S6E3HA2_MAX_BRIGHTNESS;
> +}
> +
> +static int s6e3ha2_update_gamma(struct s6e3ha2 *ctx, unsigned int brightness)
> +{
> + struct backlight_device *bl_dev = ctx->bl_dev;
> + unsigned int index = s6e3ha2_get_brightness_index(brightness);
> + u8 data[S6E3HA2_GAMMA_CMD_CNT + 1] = { 0xca, };
> +
> + memcpy(data + 1, gamma_tbl + index, S6E3HA2_GAMMA_CMD_CNT);
> + s6e3ha2_dcs_write(ctx, data, ARRAY_SIZE(data));
> +
> + s6e3ha2_gamma_update(ctx);
> + bl_dev->props.brightness = brightness;
> +
> + return 0;
> +}
> +
> +static int s6e3ha2_set_brightness(struct backlight_device *bl_dev)
> +{
> + struct s6e3ha2 *ctx = (struct s6e3ha2 *)bl_get_data(bl_dev);
I think explicit casting is not necessary here.
> + unsigned int brightness = bl_dev->props.brightness;
> +
> + if (brightness < S6E3HA2_MIN_BRIGHTNESS ||
> + brightness > bl_dev->props.max_brightness) {
> + dev_err(ctx->dev, "Invalid brightness: %u\n", brightness);
> + return -EINVAL;
> + }
> +
> + if (bl_dev->props.power > FB_BLANK_NORMAL)
> + return -EPERM;
> +
> + s6e3ha2_test_key_on_f0(ctx);
> + s6e3ha2_update_gamma(ctx, brightness);
> + s6e3ha2_aor_control(ctx);
> + s6e3ha2_set_vint(ctx);
> + s6e3ha2_test_key_off_f0(ctx);
> +
> + return ctx->error;
> +}
> +
> +static const struct backlight_ops s6e3ha2_bl_ops = {
> + .get_brightness = s6e3ha2_get_brightness,
> + .update_status = s6e3ha2_set_brightness,
> +};
> +
> +static void s6e3ha2_panel_init(struct s6e3ha2 *ctx)
> +{
> + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
> +
> + mipi_dsi_dcs_exit_sleep_mode(dsi);
> + usleep_range(5000, 6000);
> +
> + s6e3ha2_test_key_on_f0(ctx);
> + s6e3ha2_single_dsi_set(ctx);
> + s6e3ha2_test_key_on_fc(ctx);
> + s6e3ha2_freq_calibration(ctx);
> + s6e3ha2_test_key_off_fc(ctx);
> + s6e3ha2_test_key_off_f0(ctx);
> +}
> +
> +static int s6e3ha2_power_off(struct s6e3ha2 *ctx)
> +{
> + return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
> +}
> +
> +static int s6e3ha2_disable(struct drm_panel *panel)
> +{
> + struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
> + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
> +
> + mipi_dsi_dcs_enter_sleep_mode(dsi);
> + if (ctx->error != 0)
> + goto err;
> +
> + mipi_dsi_dcs_set_display_off(dsi);
> + if (ctx->error != 0)
> + goto err;
Both mipi* functions are external functions, you should check return
value instead of ctx->error.
> +
> + msleep(40);
> + ctx->bl_dev->props.power = FB_BLANK_NORMAL;
> +
> + return 0;
> +err:
> + return ctx->error;
> +}
> +
> +static int s6e3ha2_unprepare(struct drm_panel *panel)
> +{
> + struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
> + int ret;
> +
> + ret = s6e3ha2_clear_error(ctx);
> + if (!ret)
> + ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
> +
> + return s6e3ha2_power_off(ctx);
> +}
> +
> +static int s6e3ha2_power_on(struct s6e3ha2 *ctx)
> +{
> + int ret;
> +
> + ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
> + if (ret < 0)
> + return ret;
> +
> + msleep(120);
> +
> + gpiod_set_value(ctx->enable_gpio, 0);
> + usleep_range(5000, 6000);
> + gpiod_set_value(ctx->enable_gpio, 1);
> +
> + gpiod_set_value(ctx->reset_gpio, 1);
> + usleep_range(5000, 6000);
> + gpiod_set_value(ctx->reset_gpio, 0);
> + usleep_range(5000, 6000);
> +
> + return 0;
> +}
> +static int s6e3ha2_prepare(struct drm_panel *panel)
> +{
> + struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
> + int ret;
> +
> + ret = s6e3ha2_power_on(ctx);
> + if (ret < 0)
> + return ret;
> +
> + s6e3ha2_panel_init(ctx);
> +
> + ret = s6e3ha2_clear_error(ctx);
> + if (ret < 0) {
> + s6e3ha2_power_off(ctx);
> + return ret;
> + }
> +
> + ctx->bl_dev->props.power = FB_BLANK_NORMAL;
> +
> + return 0;
> +}
> +
> +static int s6e3ha2_enable(struct drm_panel *panel)
> +{
> + struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
> + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
> +
> + /* common setting */
> + mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
> +
> + s6e3ha2_test_key_on_f0(ctx);
> + s6e3ha2_test_key_on_fc(ctx);
> + s6e3ha2_touch_hsync_on1(ctx);
> + s6e3ha2_pentile_control(ctx);
> + s6e3ha2_poc_global(ctx);
> + s6e3ha2_poc_setting(ctx);
> + s6e3ha2_test_key_off_fc(ctx);
> +
> + /* pcd setting off for TB */
> + s6e3ha2_pcd_set_off(ctx);
> + s6e3ha2_err_fg_set(ctx);
> + s6e3ha2_te_start_setting(ctx);
> +
> + /* brightness setting */
> + s6e3ha2_set_brightness(ctx->bl_dev);
> + s6e3ha2_aor_control(ctx);
> + s6e3ha2_caps_elvss_set(ctx);
> + s6e3ha2_gamma_update(ctx);
> + s6e3ha2_acl_off(ctx);
> + s6e3ha2_acl_off_opr(ctx);
> + s6e3ha2_hbm_off(ctx);
> +
> + /* elvss temp compensation */
> + s6e3ha2_test_global(ctx);
> + s6e3ha2_test(ctx);
> + s6e3ha2_test_key_off_f0(ctx);
> +
> + mipi_dsi_dcs_set_display_on(dsi);
> + if (ctx->error != 0)
> + return ctx->error;
> +
> + ctx->bl_dev->props.power = FB_BLANK_UNBLANK;
> +
> + return 0;
> +}
> +
> +static const struct drm_display_mode default_mode = {
> + .clock = 14874,
> + .hdisplay = 1440,
> + .hsync_start = 1440 + 1,
> + .hsync_end = 1440 + 1 + 1,
> + .htotal = 1440 + 1 + 1 + 1,
> + .vdisplay = 2560,
> + .vsync_start = 2560 + 1,
> + .vsync_end = 2560 + 1 + 1,
> + .vtotal = 2560 + 1 + 1 + 15,
> + .vrefresh = 60,
Below equation should be true:
clock * 1000 == vtotal * htotal * vrefresh
It is not. I think clock should be adjusted, another thing is that in
case of this panel vrefresh is little below 60Hz,
modetest shows about 59.8, if I remember correctly.
So clock should be 1443*2577*59.8 / 1000 = 222372.
> + .flags = 0,
> +};
> +
> +static int s6e3ha2_get_modes(struct drm_panel *panel)
> +{
> + struct drm_connector *connector = panel->connector;
> + struct drm_display_mode *mode;
> +
> + mode = drm_mode_duplicate(panel->drm, &default_mode);
> + if (!mode) {
> + DRM_ERROR("failed to create a new display mode\n");
> + DRM_ERROR("failed to add mode %ux%ux@%u\n",
> + default_mode.hdisplay, default_mode.vdisplay,
> + default_mode.vrefresh);
I think 1st DRM_ERROR could be dropped.
I think 2nd one also, as allocator will dump stack in case of failure.
Regards
Andrzej
> + return -ENOMEM;
> + }
> +
> + drm_mode_set_name(mode);
> +
> + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
> + drm_mode_probed_add(connector, mode);
> +
> + connector->display_info.width_mm = 71;
> + connector->display_info.height_mm = 125;
> +
> + return 1;
> +}
> +
> +static const struct drm_panel_funcs s6e3ha2_drm_funcs = {
> + .disable = s6e3ha2_disable,
> + .unprepare = s6e3ha2_unprepare,
> + .prepare = s6e3ha2_prepare,
> + .enable = s6e3ha2_enable,
> + .get_modes = s6e3ha2_get_modes,
> +};
> +
> +static int s6e3ha2_probe(struct mipi_dsi_device *dsi)
> +{
> + struct device *dev = &dsi->dev;
> + struct s6e3ha2 *ctx;
> + int ret;
> +
> + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> + if (!ctx)
> + return -ENOMEM;
> +
> + mipi_dsi_set_drvdata(dsi, ctx);
> +
> + ctx->dev = dev;
> +
> + dsi->lanes = 4;
> + dsi->format = MIPI_DSI_FMT_RGB888;
> + dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS;
> +
> + ctx->supplies[0].supply = "vdd3";
> + ctx->supplies[1].supply = "vci";
> +
> + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
> + ctx->supplies);
> + if (ret < 0) {
> + dev_err(dev, "failed to get regulators: %d\n", ret);
> + return ret;
> + }
> +
> + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
> + if (IS_ERR(ctx->reset_gpio)) {
> + dev_err(dev, "cannot get reset-gpios %ld\n",
> + PTR_ERR(ctx->reset_gpio));
> + return PTR_ERR(ctx->reset_gpio);
> + }
> +
> + ctx->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
> + if (IS_ERR(ctx->enable_gpio)) {
> + dev_err(dev, "cannot get enable-gpios %ld\n",
> + PTR_ERR(ctx->enable_gpio));
> + return PTR_ERR(ctx->enable_gpio);
> + }
> +
> + ctx->bl_dev = backlight_device_register("s6e3ha2", dev, ctx,
> + &s6e3ha2_bl_ops, NULL);
> + if (IS_ERR(ctx->bl_dev)) {
> + dev_err(dev, "failed to register backlight device\n");
> + return PTR_ERR(ctx->bl_dev);
> + }
> +
> + ctx->bl_dev->props.max_brightness = S6E3HA2_MAX_BRIGHTNESS;
> + ctx->bl_dev->props.brightness = S6E3HA2_DEFAULT_BRIGHTNESS;
> + ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
> +
> + drm_panel_init(&ctx->panel);
> + ctx->panel.dev = dev;
> + ctx->panel.funcs = &s6e3ha2_drm_funcs;
> +
> + ret = drm_panel_add(&ctx->panel);
> + if (ret < 0)
> + goto unregister_backlight;
> +
> + ret = mipi_dsi_attach(dsi);
> + if (ret < 0)
> + goto remove_panel;
> +
> + return ret;
> +
> +remove_panel:
> + drm_panel_remove(&ctx->panel);
> +
> +unregister_backlight:
> + backlight_device_unregister(ctx->bl_dev);
> +
> + return ret;
> +}
> +
> +static int s6e3ha2_remove(struct mipi_dsi_device *dsi)
> +{
> + struct s6e3ha2 *ctx = mipi_dsi_get_drvdata(dsi);
> +
> + mipi_dsi_detach(dsi);
> + drm_panel_remove(&ctx->panel);
> + backlight_device_unregister(ctx->bl_dev);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id s6e3ha2_of_match[] = {
> + { .compatible = "samsung,s6e3ha2" },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, s6e3ha2_of_match);
> +
> +static struct mipi_dsi_driver s6e3ha2_driver = {
> + .probe = s6e3ha2_probe,
> + .remove = s6e3ha2_remove,
> + .driver = {
> + .name = "panel-samsung-s6e3ha2",
> + .of_match_table = s6e3ha2_of_match,
> + },
> +};
> +module_mipi_dsi_driver(s6e3ha2_driver);
> +
> +MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
> +MODULE_AUTHOR("Hyungwon Hwang <human.hwang@samsung.com>");
> +MODULE_AUTHOR("Hoegeun Kwon <hoegeun.kwon@samsung.com>");
> +MODULE_DESCRIPTION("MIPI-DSI based s6e3ha2 AMOLED Panel Driver");
> +MODULE_LICENSE("GPL v2");
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH v2 06/11] mfd: axp20x: add separate MFD cell for AXP223
From: Lee Jones @ 2017-01-04 9:45 UTC (permalink / raw)
To: Quentin Schulz
Cc: sre, robh+dt, mark.rutland, wens, linux, maxime.ripard, linux-pm,
devicetree, linux-kernel, linux-arm-kernel, thomas.petazzoni
In-Reply-To: <20161209110419.28981-7-quentin.schulz@free-electrons.com>
On Fri, 09 Dec 2016, Quentin Schulz wrote:
> The AXP223 shares most of its logic with the AXP221 but has some
> differences for the VBUS power supply driver. Thus, to probe the driver
> with the correct compatible, the AXP221 and the AXP223 now have separate
> MFD cells.
>
> AXP221 MFD cells are renamed from axp22x_cells to axp221_cells to avoid
> confusion.
>
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
> Acked-by: Chen-Yu Tsai <wens@csie.org>
> ---
>
> v2:
> - correct indentation,
> - renaming axp22x_cells to axp221_cells to avoid confusion between axp22x,
> axp221 and axp223
>
> drivers/mfd/axp20x.c | 28 ++++++++++++++++++++++++----
> 1 file changed, 24 insertions(+), 4 deletions(-)
Applied, thanks.
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index 6ee2cc6..b31f123 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -591,7 +591,22 @@ static struct mfd_cell axp20x_cells[] = {
> },
> };
>
> -static struct mfd_cell axp22x_cells[] = {
> +static struct mfd_cell axp221_cells[] = {
> + {
> + .name = "axp20x-pek",
> + .num_resources = ARRAY_SIZE(axp22x_pek_resources),
> + .resources = axp22x_pek_resources,
> + }, {
> + .name = "axp20x-regulator",
> + }, {
> + .name = "axp20x-usb-power-supply",
> + .of_compatible = "x-powers,axp221-usb-power-supply",
> + .num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources),
> + .resources = axp22x_usb_power_supply_resources,
> + },
> +};
> +
> +static struct mfd_cell axp223_cells[] = {
> {
> .name = "axp20x-pek",
> .num_resources = ARRAY_SIZE(axp22x_pek_resources),
> @@ -600,7 +615,7 @@ static struct mfd_cell axp22x_cells[] = {
> .name = "axp20x-regulator",
> }, {
> .name = "axp20x-usb-power-supply",
> - .of_compatible = "x-powers,axp221-usb-power-supply",
> + .of_compatible = "x-powers,axp223-usb-power-supply",
> .num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources),
> .resources = axp22x_usb_power_supply_resources,
> },
> @@ -793,9 +808,14 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
> axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip;
> break;
> case AXP221_ID:
> + axp20x->nr_cells = ARRAY_SIZE(axp221_cells);
> + axp20x->cells = axp221_cells;
> + axp20x->regmap_cfg = &axp22x_regmap_config;
> + axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
> + break;
> case AXP223_ID:
> - axp20x->nr_cells = ARRAY_SIZE(axp22x_cells);
> - axp20x->cells = axp22x_cells;
> + axp20x->nr_cells = ARRAY_SIZE(axp223_cells);
> + axp20x->cells = axp223_cells;
> axp20x->regmap_cfg = &axp22x_regmap_config;
> axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
> break;
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [PATCH v5 3/3] arm64: dts: exynos: Add support for S6E3HA2 panel device on TM2 board
From: Andrzej Hajda @ 2017-01-04 9:57 UTC (permalink / raw)
To: Hoegeun Kwon, robh, thierry.reding, airlied, kgene, krzk,
inki.dae
Cc: devicetree, linux-samsung-soc, linux-kernel, dri-devel,
jh80.chung, cw00.choi, Hyungwon Hwang
In-Reply-To: <1483517711-23849-4-git-send-email-hoegeun.kwon@samsung.com>
On 04.01.2017 09:15, Hoegeun Kwon wrote:
> From: Hyungwon Hwang <human.hwang@samsung.com>
>
> This patch add the panel device tree node for S6E3HA2 display
> controller to TM2 dts.
>
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
> Signed-off-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
--
Regards
Andrzej
> ---
> arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
> index 5b9451d..b3ba1ac 100644
> --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
> +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
> @@ -304,11 +304,28 @@
> reg = <1>;
>
> dsi_out: endpoint {
> + remote-endpoint = <&panel_in>;
> samsung,burst-clock-frequency = <512000000>;
> samsung,esc-clock-frequency = <16000000>;
> };
> };
> };
> +
> + panel@0 {
> + compatible = "samsung,s6e3ha2";
> + reg = <0>;
> + vdd3-supply = <&ldo27_reg>;
> + vci-supply = <&ldo28_reg>;
> + reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
> + enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
> + te-gpios = <&gpf1 3 GPIO_ACTIVE_HIGH>;
> +
> + port {
> + panel_in: endpoint {
> + remote-endpoint = <&dsi_out>;
> + };
> + };
> + };
> };
>
> &hsi2c_0 {
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH v5 0/3] Add support for the S6E3HA2 panel on TM2 board
From: Andi Shyti @ 2017-01-04 9:58 UTC (permalink / raw)
To: Hoegeun Kwon
Cc: robh, thierry.reding, airlied, kgene, krzk, inki.dae, dri-devel,
linux-kernel, devicetree, linux-samsung-soc, a.hajda, cw00.choi,
jh80.chung
In-Reply-To: <1483517711-23849-1-git-send-email-hoegeun.kwon@samsung.com>
Hi Hoegeun,
On Wed, Jan 04, 2017 at 05:15:08PM +0900, Hoegeun Kwon wrote:
> Purpose of this patch is add support for S6E3HA2 AMOLED panel on
> the TM2 board. The first patch adds support for S6E3HA2 panel
> device tree document and driver, the second patch add support for
> S6E3HA2 panel device tree.
>
> Change for V5:
> - The V5 has only one fix in V4 below.
> - Removed the enable check of the mic driver in mode_set
> callback, because mode_set should be performed every time.
>
> Changes for V4:
> - Removed display-timings in devicetree, the display-timings has
> been fixed to be provided by the device driver.
> - Added the mode_set callback function into exynos_drm_mic,
> because the exynos_drm_mic driver can not parse a videomode
> struct by removing the display-timings from the devicetree.
Next time, please add the full history, from "Changes for V1".
Moreover in this patchset you haven't added the
"Tested-by: Chanwoo..." in patch 2 and 3.
Andi
>
> Hoegeun Kwon (2):
> drm/exynos: mic: Add mode_set callback function
> drm/panel: Add support for S6E3HA2 panel driver on TM2 board
>
> Hyungwon Hwang (1):
> arm64: dts: exynos: Add support for S6E3HA2 panel device on TM2 board
>
> .../bindings/display/panel/samsung,s6e3ha2.txt | 40 ++
> arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 17 +
> drivers/gpu/drm/exynos/exynos_drm_mic.c | 30 +-
> drivers/gpu/drm/panel/Kconfig | 6 +
> drivers/gpu/drm/panel/Makefile | 1 +
> drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c | 741 +++++++++++++++++++++
> 6 files changed, 824 insertions(+), 11 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
> create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c
>
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v3 2/3] dmaeninge: xilinx_dma: Fix bug in multiple frame stores scenario in vdma
From: Jose Abreu @ 2017-01-04 9:59 UTC (permalink / raw)
To: Kedareswara rao Appana, robh+dt, mark.rutland, dan.j.williams,
vinod.koul, michal.simek, soren.brinkmann, appanad,
moritz.fischer, laurent.pinchart, luis, Jose.Abreu
Cc: dmaengine, devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <1483512847-25710-3-git-send-email-appanad@xilinx.com>
Hi Kedar,
On 04-01-2017 06:54, Kedareswara rao Appana wrote:
> When VDMA is configured for more than one frame in the h/w
> for example h/w is configured for n number of frames and user
> Submits n number of frames and triggered the DMA using issue_pending API.
> In the current driver flow we are submitting one frame at a time
> but we should submit all the n number of frames at one time as the h/w
> Is configured for n number of frames.
>
> This patch fixes this issue.
>
> Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
Looks fine. I have a couple of minor comments, if you address
them you can add "Reviewed-by: Jose Abreu <joabreu@synopsys.com>"
in next version.
> ---
> Changes for v3:
> ---> Added Checks for frame store configuration. If frame store
> Configuration is not present at the h/w level and user
> Submits less frames added debug prints in the driver as relevant.
> Changes for v2:
> ---> Fixed race conditions in the driver as suggested by Jose Abreu
> ---> Fixed unnecessray if else checks in the vdma_start_transfer
> as suggested by Laurent Pinchart.
>
> .../devicetree/bindings/dma/xilinx/xilinx_dma.txt | 2 +
> drivers/dma/xilinx/xilinx_dma.c | 78 +++++++++++++++-------
> 2 files changed, 57 insertions(+), 23 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
> index a2b8bfa..1f65e09 100644
> --- a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
> +++ b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
> @@ -66,6 +66,8 @@ Optional child node properties:
> Optional child node properties for VDMA:
> - xlnx,genlock-mode: Tells Genlock synchronization is
> enabled/disabled in hardware.
> +- xlnx,fstore-config: Tells Whether Frame Store Configuration is
> + enabled/disabled in hardware.
> Optional child node properties for AXI DMA:
> -dma-channels: Number of dma channels in child node.
>
> diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
> index be7eb41..7cd8e08 100644
> --- a/drivers/dma/xilinx/xilinx_dma.c
> +++ b/drivers/dma/xilinx/xilinx_dma.c
> @@ -322,6 +322,7 @@ struct xilinx_dma_tx_descriptor {
> * @genlock: Support genlock mode
> * @err: Channel has errors
> * @idle: Check for channel idle
> + * @has_fstoreconfig: Check for frame store configuration
> * @tasklet: Cleanup work after irq
> * @config: Device configuration info
> * @flush_on_fsync: Flush on Frame sync
> @@ -353,6 +354,7 @@ struct xilinx_dma_chan {
> bool genlock;
> bool err;
> bool idle;
> + bool has_fstoreconfig;
> struct tasklet_struct tasklet;
> struct xilinx_vdma_config config;
> bool flush_on_fsync;
> @@ -990,6 +992,26 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
> if (list_empty(&chan->pending_list))
> return;
>
> + /*
> + * Note: When VDMA is built with default h/w configuration
> + * On the S2MM(recv) side user should submit frames upto
> + * H/W configured. If users submits less than h/w configured
> + * VDMA engine tries to write to a invalid location
> + * Results undefined behaviour/memory corruption.
> + *
> + * If user would like to submit frames less than h/w capable
> + * On S2MM side please enable debug info 13 at the h/w level
> + * It will allows the frame buffers numbers to be modified at runtime.
> + */
> + if (!chan->has_fstoreconfig && chan->direction == DMA_DEV_TO_MEM &&
> + chan->desc_pendingcount < chan->num_frms) {
> + dev_dbg(chan->dev, "Frame Store Configuration is not enabled at the");
> + dev_dbg(chan->dev, " H/w level enable Debug info 13 at the h/w level");
> + dev_dbg(chan->dev, " OR Submit the frames upto h/w Capable\n\r");
> +
> + return;
> + }
Hmm, may dev_warn would be more suitable because with dev_dbg and
no dynamic debug enabled user will not know what happened. Also,
I am aware that in direction DMA_MEM_TO_DEV there will be no
corruption in PC side but it will be corruption in VDMA side
because it will read from invalid memory locations. Maybe drop
the check for channel direction.
I am also not fancy about dropping prints that are not grep'able
(you do not break line in each print so a user searching for the
whole string will not find it). Try to do a line break in each
print or change the string to be smaller.
Best regards,
Jose Miguel Abreu
> +
> desc = list_first_entry(&chan->pending_list,
> struct xilinx_dma_tx_descriptor, node);
> tail_desc = list_last_entry(&chan->pending_list,
> @@ -1052,25 +1074,38 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
> if (chan->has_sg) {
> dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC,
> tail_segment->phys);
> + list_splice_tail_init(&chan->pending_list, &chan->active_list);
> + chan->desc_pendingcount = 0;
> } else {
> struct xilinx_vdma_tx_segment *segment, *last = NULL;
> - int i = 0;
> + int i = 0, j = 0;
>
> if (chan->desc_submitcount < chan->num_frms)
> i = chan->desc_submitcount;
>
> - list_for_each_entry(segment, &desc->segments, node) {
> - if (chan->ext_addr)
> - vdma_desc_write_64(chan,
> - XILINX_VDMA_REG_START_ADDRESS_64(i++),
> - segment->hw.buf_addr,
> - segment->hw.buf_addr_msb);
> - else
> - vdma_desc_write(chan,
> - XILINX_VDMA_REG_START_ADDRESS(i++),
> - segment->hw.buf_addr);
> -
> - last = segment;
> + for (j = 0; j < chan->num_frms; ) {
> + list_for_each_entry(segment, &desc->segments, node) {
> + if (chan->ext_addr)
> + vdma_desc_write_64(chan,
> + XILINX_VDMA_REG_START_ADDRESS_64(i++),
> + segment->hw.buf_addr,
> + segment->hw.buf_addr_msb);
> + else
> + vdma_desc_write(chan,
> + XILINX_VDMA_REG_START_ADDRESS(i++),
> + segment->hw.buf_addr);
> +
> + last = segment;
> + }
> + list_del(&desc->node);
> + list_add_tail(&desc->node, &chan->active_list);
> + j++;
> + if (list_empty(&chan->pending_list) ||
> + (i == chan->num_frms))
> + break;
> + desc = list_first_entry(&chan->pending_list,
> + struct xilinx_dma_tx_descriptor,
> + node);
> }
>
> if (!last)
> @@ -1081,20 +1116,14 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
> vdma_desc_write(chan, XILINX_DMA_REG_FRMDLY_STRIDE,
> last->hw.stride);
> vdma_desc_write(chan, XILINX_DMA_REG_VSIZE, last->hw.vsize);
> - }
>
> - chan->idle = false;
> - if (!chan->has_sg) {
> - list_del(&desc->node);
> - list_add_tail(&desc->node, &chan->active_list);
> - chan->desc_submitcount++;
> - chan->desc_pendingcount--;
> + chan->desc_submitcount += j;
> + chan->desc_pendingcount -= j;
> if (chan->desc_submitcount == chan->num_frms)
> chan->desc_submitcount = 0;
> - } else {
> - list_splice_tail_init(&chan->pending_list, &chan->active_list);
> - chan->desc_pendingcount = 0;
> }
> +
> + chan->idle = false;
> }
>
> /**
> @@ -1342,6 +1371,7 @@ static int xilinx_dma_reset(struct xilinx_dma_chan *chan)
>
> chan->err = false;
> chan->idle = true;
> + chan->desc_submitcount = 0;
>
> return err;
> }
> @@ -2315,6 +2345,8 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
> has_dre = of_property_read_bool(node, "xlnx,include-dre");
>
> chan->genlock = of_property_read_bool(node, "xlnx,genlock-mode");
> + chan->has_fstoreconfig = of_property_read_bool(node,
> + "xlnx,fstore-config");
>
> err = of_property_read_u32(node, "xlnx,datawidth", &value);
> if (err) {
^ permalink raw reply
* Re: [PATCH V5 1/3] dt-bindings: document common IEEE 802.11 frequency limit property
From: Arend Van Spriel @ 2017-01-04 10:02 UTC (permalink / raw)
To: Rafał Miłecki, Johannes Berg,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, Rob Herring
Cc: Martin Blumenstingl, Felix Fietkau, Arend van Spriel,
Arnd Bergmann, devicetree-u79uwXL29TY76Z2rM5mHXA,
Rafał Miłecki
In-Reply-To: <d90127bd-6a9e-2773-fdf9-527afdc004a6-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On 4-1-2017 7:20, Rafał Miłecki wrote:
> Hi Rob,
>
> On 01/03/2017 11:57 PM, Rafał Miłecki wrote:
>> From: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
>>
>> This new file should be used for properties that apply to all wireless
>> devices.
>>
>> Signed-off-by: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
>> ---
>> V2: Switch to a single ieee80211-freq-limit property that allows
>> specifying
>> *multiple* ranges. This resolves problem with more complex rules
>> as pointed
>> by Felx.
>> Make description implementation agnostic as pointed by Arend.
>> Rename node to wifi as suggested by Martin.
>> V3: Use more real-life frequencies in the example.
>> V5: Describe hardware design as possible use for this property
>> ---
>> .../devicetree/bindings/net/wireless/ieee80211.txt | 20
>> ++++++++++++++++++++
>> 1 file changed, 20 insertions(+)
>> create mode 100644
>> Documentation/devicetree/bindings/net/wireless/ieee80211.txt
>>
>> diff --git
>> a/Documentation/devicetree/bindings/net/wireless/ieee80211.txt
>> b/Documentation/devicetree/bindings/net/wireless/ieee80211.txt
>> new file mode 100644
>> index 0000000..1c82c16
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/net/wireless/ieee80211.txt
>> @@ -0,0 +1,20 @@
>> +Common IEEE 802.11 properties
>> +
>> +This provides documentation of common properties that are valid for
>> all wireless
>> +devices.
>> +
>> +Optional properties:
>> + - ieee80211-freq-limit : list of supported frequency ranges in KHz.
>> This can be
>> + used to specify extra hardware limitations caused by e.g. used
>> antennas
>> + or power amplifiers.
>
> Do you find this description sufficient now? I'm not sure how/if I could
> answer
> "Where would this data normally come from?" question.
>
> One vendor may hardcode choice of channels in their PHP web UI.
> Another one may do it in Andoid app.
> OpenWrt so far was describing this limitation on their wiki page.
>
> It doesn't sound like any valuable info if I understand this correctly.
> We also
> don't describe where to get information about amount o RAM. One may just
> check
> the hardware, one may use vendor firmware, one could check product data
> sheet.
>
> If I missed the point, could you help me get this?
There is probably no easy answer. DT is used to describe device
properties that are not otherwise discoverable (at least that is my rule
of thumb). So what is the "device" in this context? You may consider
just the chip, but in this case it is combination of the chip and its RF
path that determine the frequency range that it can operate in.
Apparently this was assured in user-space due to lack of a better
option. Having this specified in DT seems a viable option getting rid of
having a particular platform impose a requirement upon user-space.
You could consider these properties global as they are describing the
platform, but again this depends on what you consider the "device". If
you want to do this global you may add a global node for wifi properties
and use references to the device.
Regards,
Arend
^ permalink raw reply
* Re: [PATCH V5 4/8] mfd: da9061: MFD core support
From: Lee Jones @ 2017-01-04 10:12 UTC (permalink / raw)
To: Steve Twiss
Cc: LINUX-KERNEL, DEVICETREE, Dmitry Torokhov, Eduardo Valentin,
Guenter Roeck, LINUX-INPUT, LINUX-PM, LINUX-WATCHDOG,
Liam Girdwood, Mark Brown, Mark Rutland, Rob Herring,
Support Opensource, Wim Van Sebroeck, Zhang Rui
In-Reply-To: <ad649a91daa6191f2385dfe79c6ec8ca339f597c.1481828921.git.stwiss.opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org>
On Thu, 15 Dec 2016, Steve Twiss wrote:
> From: Steve Twiss <stwiss.opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org>
>
> MFD support for DA9061 is provided as part of the DA9062 device driver.
>
> The registers header file adds two new chip variant IDs defined in DA9061
> and DA9062 hardware. The core header file adds new software enumerations
> for listing the valid DA9061 IRQs and a da9062_compatible_types enumeration
> for distinguishing between DA9061/62 devices in software.
>
> The core source code adds a new .compatible of_device_id entry. This is
> extended from DA9062 to support both "dlg,da9061" and "dlg,da9062". The
> .data entry now holds a reference to the enumerated device type.
>
> A new regmap_irq_chip model is added for DA9061 and this supports the new
> list of regmap_irq entries. A new mfd_cell da9061_devs[] array lists the
> new sub system components for DA9061. Support is added for a new DA9061
> regmap_config which lists the correct readable, writable and volatile
> ranges for this chip.
>
> The probe function uses the device tree compatible string to switch on the
> da9062_compatible_types and configure the correct mfd cells, irq chip and
> regmap config.
>
> Kconfig is updated to reflect support for DA9061 and DA9062 PMICs.
>
> Signed-off-by: Steve Twiss <stwiss.opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org>
>
> ---
> This patch applies against linux-next and v4.9
>
> v4 -> v5
> - NO CODE CHANGE
> - Rebased from v4.8 to v4.9
>
> v3 -> v4
> - Patch renamed from [PATCH V3 5/9] to [PATCH V4 4/8]
> - Removed DEFINE_RES_NAMED() macros for DA9061 resources and replaced
> them with DEFINE_RES_IRQ_NAMED().
> - Removed whitespace
> - Reverted change for badly defined mfd_cell da9062_devs of_compatible
> string from "dlg,da9062-watchdog" back to "dlg,da9062-wdt"
>
> v2 -> v3
> - NO CODE CHANGE
> - Patch renamed from [PATCH V2 05/10] to [PATCH V3 5/9]
>
> v1 -> v2
> - Patch renamed from [PATCH V1 01/10] to [PATCH V2 05/10] -- these
> changes were made to fix checkpatch warnings caused by the patch
> set dependency order
> - Fixed typo in the commit message "readble" to "readable"
> - Removed the explicit cross-check to decide if there is a conflict
> between the device tree compatible string and the hardware definition.
> This patch assumes the device tree is correctly written and therefore
> removes the need for a hardware/DT sanity check.
> - Removed extra semicolon in drivers/mfd/da9062-core.c:877
> - Re-write compatible entries into numerical order
>
> Lee,
>
> Changes as described in the version history above.
>
> As previously:
> This patch adds support for the DA9061 PMIC. This is done as part of the
> existing DA9062 device driver by extending the of_device_id match table.
> This in turn allows new MFD cells, irq chip and regmap definitions to
> support DA9061.
>
> Regards,
> Steve Twiss, Dialog Semiconductor Ltd.
>
>
> drivers/mfd/Kconfig | 5 +-
> drivers/mfd/da9062-core.c | 424 +++++++++++++++++++++++++++++++++--
> include/linux/mfd/da9062/core.h | 27 ++-
> include/linux/mfd/da9062/registers.h | 2 +
> 4 files changed, 439 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index c6df644..a1a780c 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -246,13 +246,14 @@ config MFD_DA9055
> called "da9055"
>
> config MFD_DA9062
> - tristate "Dialog Semiconductor DA9062 PMIC Support"
> + tristate "Dialog Semiconductor DA9062/61 PMIC Support"
> select MFD_CORE
> select REGMAP_I2C
> select REGMAP_IRQ
> depends on I2C
> help
> - Say yes here for support for the Dialog Semiconductor DA9062 PMIC.
> + Say yes here for support for the Dialog Semiconductor DA9061 and
> + DA9062 PMICs.
> This includes the I2C driver and core APIs.
> Additional drivers must be enabled in order to use the functionality
> of the device.
> diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c
> index 8f873866..4b5f70f 100644
> --- a/drivers/mfd/da9062-core.c
> +++ b/drivers/mfd/da9062-core.c
> @@ -1,5 +1,5 @@
> /*
> - * Core, IRQ and I2C device driver for DA9062 PMIC
> + * Core, IRQ and I2C device driver for DA9061 and DA9062 PMICs
> * Copyright (C) 2015 Dialog Semiconductor Ltd.
> *
> * This program is free software; you can redistribute it and/or
> @@ -30,6 +30,70 @@
> #define DA9062_REG_EVENT_B_OFFSET 1
> #define DA9062_REG_EVENT_C_OFFSET 2
>
> +static struct regmap_irq da9061_irqs[] = {
> + /* EVENT A */
> + [DA9061_IRQ_ONKEY] = {
> + .reg_offset = DA9062_REG_EVENT_A_OFFSET,
> + .mask = DA9062AA_M_NONKEY_MASK,
> + },
> + [DA9061_IRQ_WDG_WARN] = {
> + .reg_offset = DA9062_REG_EVENT_A_OFFSET,
> + .mask = DA9062AA_M_WDG_WARN_MASK,
> + },
> + [DA9061_IRQ_SEQ_RDY] = {
> + .reg_offset = DA9062_REG_EVENT_A_OFFSET,
> + .mask = DA9062AA_M_SEQ_RDY_MASK,
> + },
> + /* EVENT B */
> + [DA9061_IRQ_TEMP] = {
> + .reg_offset = DA9062_REG_EVENT_B_OFFSET,
> + .mask = DA9062AA_M_TEMP_MASK,
> + },
> + [DA9061_IRQ_LDO_LIM] = {
> + .reg_offset = DA9062_REG_EVENT_B_OFFSET,
> + .mask = DA9062AA_M_LDO_LIM_MASK,
> + },
> + [DA9061_IRQ_DVC_RDY] = {
> + .reg_offset = DA9062_REG_EVENT_B_OFFSET,
> + .mask = DA9062AA_M_DVC_RDY_MASK,
> + },
> + [DA9061_IRQ_VDD_WARN] = {
> + .reg_offset = DA9062_REG_EVENT_B_OFFSET,
> + .mask = DA9062AA_M_VDD_WARN_MASK,
> + },
> + /* EVENT C */
> + [DA9061_IRQ_GPI0] = {
> + .reg_offset = DA9062_REG_EVENT_C_OFFSET,
> + .mask = DA9062AA_M_GPI0_MASK,
> + },
> + [DA9061_IRQ_GPI1] = {
> + .reg_offset = DA9062_REG_EVENT_C_OFFSET,
> + .mask = DA9062AA_M_GPI1_MASK,
> + },
> + [DA9061_IRQ_GPI2] = {
> + .reg_offset = DA9062_REG_EVENT_C_OFFSET,
> + .mask = DA9062AA_M_GPI2_MASK,
> + },
> + [DA9061_IRQ_GPI3] = {
> + .reg_offset = DA9062_REG_EVENT_C_OFFSET,
> + .mask = DA9062AA_M_GPI3_MASK,
> + },
> + [DA9061_IRQ_GPI4] = {
> + .reg_offset = DA9062_REG_EVENT_C_OFFSET,
> + .mask = DA9062AA_M_GPI4_MASK,
> + },
> +};
> +
> +static struct regmap_irq_chip da9061_irq_chip = {
> + .name = "da9061-irq",
> + .irqs = da9061_irqs,
> + .num_irqs = DA9061_NUM_IRQ,
> + .num_regs = 3,
> + .status_base = DA9062AA_EVENT_A,
> + .mask_base = DA9062AA_IRQ_MASK_A,
> + .ack_base = DA9062AA_EVENT_A,
> +};
> +
> static struct regmap_irq da9062_irqs[] = {
> /* EVENT A */
> [DA9062_IRQ_ONKEY] = {
> @@ -102,6 +166,57 @@
> .ack_base = DA9062AA_EVENT_A,
> };
>
> +static struct resource da9061_core_resources[] = {
> + DEFINE_RES_IRQ_NAMED(DA9061_IRQ_VDD_WARN, "VDD_WARN"),
> +};
> +
> +static struct resource da9061_regulators_resources[] = {
> + DEFINE_RES_IRQ_NAMED(DA9061_IRQ_LDO_LIM, "LDO_LIM"),
> +};
> +
> +static struct resource da9061_thermal_resources[] = {
> + DEFINE_RES_IRQ_NAMED(DA9061_IRQ_TEMP, "THERMAL"),
> +};
> +
> +static struct resource da9061_wdt_resources[] = {
> + DEFINE_RES_IRQ_NAMED(DA9061_IRQ_WDG_WARN, "WD_WARN"),
> +};
> +
> +static struct resource da9061_onkey_resources[] = {
> + DEFINE_RES_IRQ_NAMED(DA9061_IRQ_ONKEY, "ONKEY"),
> +};
> +
> +static const struct mfd_cell da9061_devs[] = {
> + {
> + .name = "da9061-core",
> + .num_resources = ARRAY_SIZE(da9061_core_resources),
> + .resources = da9061_core_resources,
> + },
> + {
> + .name = "da9062-regulators",
> + .num_resources = ARRAY_SIZE(da9061_regulators_resources),
> + .resources = da9061_regulators_resources,
> + },
> + {
> + .name = "da9061-watchdog",
> + .num_resources = ARRAY_SIZE(da9061_wdt_resources),
> + .resources = da9061_wdt_resources,
> + .of_compatible = "dlg,da9061-watchdog",
> + },
> + {
> + .name = "da9061-thermal",
> + .num_resources = ARRAY_SIZE(da9061_thermal_resources),
> + .resources = da9061_thermal_resources,
> + .of_compatible = "dlg,da9061-thermal",
> + },
> + {
> + .name = "da9061-onkey",
> + .num_resources = ARRAY_SIZE(da9061_onkey_resources),
> + .resources = da9061_onkey_resources,
> + .of_compatible = "dlg,da9061-onkey",
> + },
> +};
> +
> static struct resource da9062_core_resources[] = {
> DEFINE_RES_NAMED(DA9062_IRQ_VDD_WARN, 1, "VDD_WARN", IORESOURCE_IRQ),
> };
> @@ -200,7 +315,8 @@ static int da9062_clear_fault_log(struct da9062 *chip)
>
> static int da9062_get_device_type(struct da9062 *chip)
> {
> - int device_id, variant_id, variant_mrc;
> + int device_id, variant_id, variant_mrc, variant_vrc;
> + char *type;
> int ret;
>
> ret = regmap_read(chip->regmap, DA9062AA_DEVICE_ID, &device_id);
> @@ -219,9 +335,23 @@ static int da9062_get_device_type(struct da9062 *chip)
> return -EIO;
> }
>
> + variant_vrc = (variant_id & DA9062AA_VRC_MASK) >> DA9062AA_VRC_SHIFT;
> +
> + switch (variant_vrc) {
> + case DA9062_PMIC_VARIANT_VRC_DA9061:
> + type = "DA9061";
> + break;
> + case DA9062_PMIC_VARIANT_VRC_DA9062:
> + type = "DA9062";
> + break;
> + default:
> + type = "Unknown";
> + break;
> + }
> +
> dev_info(chip->dev,
> - "Device detected (device-ID: 0x%02X, var-ID: 0x%02X)\n",
> - device_id, variant_id);
> + "Device detected (device-ID: 0x%02X, var-ID: 0x%02X, %s)\n",
> + device_id, variant_id, type);
>
> variant_mrc = (variant_id & DA9062AA_MRC_MASK) >> DA9062AA_MRC_SHIFT;
>
> @@ -234,6 +364,234 @@ static int da9062_get_device_type(struct da9062 *chip)
> return ret;
> }
>
> +static const struct regmap_range da9061_aa_readable_ranges[] = {
> + {
> + .range_min = DA9062AA_PAGE_CON,
> + .range_max = DA9062AA_STATUS_B,
> + }, {
> + .range_min = DA9062AA_STATUS_D,
> + .range_max = DA9062AA_EVENT_C,
> + }, {
> + .range_min = DA9062AA_IRQ_MASK_A,
> + .range_max = DA9062AA_IRQ_MASK_C,
> + }, {
> + .range_min = DA9062AA_CONTROL_A,
> + .range_max = DA9062AA_GPIO_4,
> + }, {
> + .range_min = DA9062AA_GPIO_WKUP_MODE,
> + .range_max = DA9062AA_GPIO_OUT3_4,
> + }, {
> + .range_min = DA9062AA_BUCK1_CONT,
> + .range_max = DA9062AA_BUCK4_CONT,
> + }, {
> + .range_min = DA9062AA_BUCK3_CONT,
> + .range_max = DA9062AA_BUCK3_CONT,
> + }, {
> + .range_min = DA9062AA_LDO1_CONT,
> + .range_max = DA9062AA_LDO4_CONT,
> + }, {
> + .range_min = DA9062AA_DVC_1,
> + .range_max = DA9062AA_DVC_1,
> + }, {
> + .range_min = DA9062AA_SEQ,
> + .range_max = DA9062AA_ID_4_3,
> + }, {
> + .range_min = DA9062AA_ID_12_11,
> + .range_max = DA9062AA_ID_16_15,
> + }, {
> + .range_min = DA9062AA_ID_22_21,
> + .range_max = DA9062AA_ID_32_31,
> + }, {
> + .range_min = DA9062AA_SEQ_A,
> + .range_max = DA9062AA_WAIT,
> + }, {
> + .range_min = DA9062AA_RESET,
> + .range_max = DA9062AA_BUCK_ILIM_C,
> + }, {
> + .range_min = DA9062AA_BUCK1_CFG,
> + .range_max = DA9062AA_BUCK3_CFG,
> + }, {
> + .range_min = DA9062AA_VBUCK1_A,
> + .range_max = DA9062AA_VBUCK4_A,
> + }, {
> + .range_min = DA9062AA_VBUCK3_A,
> + .range_max = DA9062AA_VBUCK3_A,
> + }, {
> + .range_min = DA9062AA_VLDO1_A,
> + .range_max = DA9062AA_VLDO4_A,
> + }, {
> + .range_min = DA9062AA_VBUCK1_B,
> + .range_max = DA9062AA_VBUCK4_B,
> + }, {
> + .range_min = DA9062AA_VBUCK3_B,
> + .range_max = DA9062AA_VBUCK3_B,
> + }, {
> + .range_min = DA9062AA_VLDO1_B,
> + .range_max = DA9062AA_VLDO4_B,
> + }, {
> + .range_min = DA9062AA_BBAT_CONT,
> + .range_max = DA9062AA_BBAT_CONT,
> + }, {
> + .range_min = DA9062AA_INTERFACE,
> + .range_max = DA9062AA_CONFIG_E,
> + }, {
> + .range_min = DA9062AA_CONFIG_G,
> + .range_max = DA9062AA_CONFIG_K,
> + }, {
> + .range_min = DA9062AA_CONFIG_M,
> + .range_max = DA9062AA_CONFIG_M,
> + }, {
> + .range_min = DA9062AA_GP_ID_0,
> + .range_max = DA9062AA_GP_ID_19,
> + }, {
> + .range_min = DA9062AA_DEVICE_ID,
> + .range_max = DA9062AA_CONFIG_ID,
> + },
> +};
> +
> +static const struct regmap_range da9061_aa_writeable_ranges[] = {
> + {
> + .range_min = DA9062AA_PAGE_CON,
> + .range_max = DA9062AA_PAGE_CON,
> + }, {
> + .range_min = DA9062AA_FAULT_LOG,
> + .range_max = DA9062AA_EVENT_C,
> + }, {
> + .range_min = DA9062AA_IRQ_MASK_A,
> + .range_max = DA9062AA_IRQ_MASK_C,
> + }, {
> + .range_min = DA9062AA_CONTROL_A,
> + .range_max = DA9062AA_GPIO_4,
> + }, {
> + .range_min = DA9062AA_GPIO_WKUP_MODE,
> + .range_max = DA9062AA_GPIO_OUT3_4,
> + }, {
> + .range_min = DA9062AA_BUCK1_CONT,
> + .range_max = DA9062AA_BUCK4_CONT,
> + }, {
> + .range_min = DA9062AA_BUCK3_CONT,
> + .range_max = DA9062AA_BUCK3_CONT,
> + }, {
> + .range_min = DA9062AA_LDO1_CONT,
> + .range_max = DA9062AA_LDO4_CONT,
> + }, {
> + .range_min = DA9062AA_DVC_1,
> + .range_max = DA9062AA_DVC_1,
> + }, {
> + .range_min = DA9062AA_SEQ,
> + .range_max = DA9062AA_ID_4_3,
> + }, {
> + .range_min = DA9062AA_ID_12_11,
> + .range_max = DA9062AA_ID_16_15,
> + }, {
> + .range_min = DA9062AA_ID_22_21,
> + .range_max = DA9062AA_ID_32_31,
> + }, {
> + .range_min = DA9062AA_SEQ_A,
> + .range_max = DA9062AA_WAIT,
> + }, {
> + .range_min = DA9062AA_RESET,
> + .range_max = DA9062AA_BUCK_ILIM_C,
> + }, {
> + .range_min = DA9062AA_BUCK1_CFG,
> + .range_max = DA9062AA_BUCK3_CFG,
> + }, {
> + .range_min = DA9062AA_VBUCK1_A,
> + .range_max = DA9062AA_VBUCK4_A,
> + }, {
> + .range_min = DA9062AA_VBUCK3_A,
> + .range_max = DA9062AA_VBUCK3_A,
> + }, {
> + .range_min = DA9062AA_VLDO1_A,
> + .range_max = DA9062AA_VLDO4_A,
> + }, {
> + .range_min = DA9062AA_VBUCK1_B,
> + .range_max = DA9062AA_VBUCK4_B,
> + }, {
> + .range_min = DA9062AA_VBUCK3_B,
> + .range_max = DA9062AA_VBUCK3_B,
> + }, {
> + .range_min = DA9062AA_VLDO1_B,
> + .range_max = DA9062AA_VLDO4_B,
> + }, {
> + .range_min = DA9062AA_BBAT_CONT,
> + .range_max = DA9062AA_BBAT_CONT,
> + }, {
> + .range_min = DA9062AA_GP_ID_0,
> + .range_max = DA9062AA_GP_ID_19,
> + },
> +};
> +
> +static const struct regmap_range da9061_aa_volatile_ranges[] = {
> + {
> + .range_min = DA9062AA_PAGE_CON,
> + .range_max = DA9062AA_STATUS_B,
> + }, {
> + .range_min = DA9062AA_STATUS_D,
> + .range_max = DA9062AA_EVENT_C,
> + }, {
> + .range_min = DA9062AA_CONTROL_A,
> + .range_max = DA9062AA_CONTROL_B,
> + }, {
> + .range_min = DA9062AA_CONTROL_E,
> + .range_max = DA9062AA_CONTROL_F,
> + }, {
> + .range_min = DA9062AA_BUCK1_CONT,
> + .range_max = DA9062AA_BUCK4_CONT,
> + }, {
> + .range_min = DA9062AA_BUCK3_CONT,
> + .range_max = DA9062AA_BUCK3_CONT,
> + }, {
> + .range_min = DA9062AA_LDO1_CONT,
> + .range_max = DA9062AA_LDO4_CONT,
> + }, {
> + .range_min = DA9062AA_DVC_1,
> + .range_max = DA9062AA_DVC_1,
> + }, {
> + .range_min = DA9062AA_SEQ,
> + .range_max = DA9062AA_SEQ,
> + },
> +};
> +
> +static const struct regmap_access_table da9061_aa_readable_table = {
> + .yes_ranges = da9061_aa_readable_ranges,
> + .n_yes_ranges = ARRAY_SIZE(da9061_aa_readable_ranges),
> +};
> +
> +static const struct regmap_access_table da9061_aa_writeable_table = {
> + .yes_ranges = da9061_aa_writeable_ranges,
> + .n_yes_ranges = ARRAY_SIZE(da9061_aa_writeable_ranges),
> +};
> +
> +static const struct regmap_access_table da9061_aa_volatile_table = {
> + .yes_ranges = da9061_aa_volatile_ranges,
> + .n_yes_ranges = ARRAY_SIZE(da9061_aa_volatile_ranges),
> +};
> +
> +static const struct regmap_range_cfg da9061_range_cfg[] = {
> + {
> + .range_min = DA9062AA_PAGE_CON,
> + .range_max = DA9062AA_CONFIG_ID,
> + .selector_reg = DA9062AA_PAGE_CON,
> + .selector_mask = 1 << DA9062_I2C_PAGE_SEL_SHIFT,
> + .selector_shift = DA9062_I2C_PAGE_SEL_SHIFT,
> + .window_start = 0,
> + .window_len = 256,
> + }
> +};
> +
> +static struct regmap_config da9061_regmap_config = {
> + .reg_bits = 8,
> + .val_bits = 8,
> + .ranges = da9061_range_cfg,
> + .num_ranges = ARRAY_SIZE(da9061_range_cfg),
> + .max_register = DA9062AA_CONFIG_ID,
> + .cache_type = REGCACHE_RBTREE,
> + .rd_table = &da9061_aa_readable_table,
> + .wr_table = &da9061_aa_writeable_table,
> + .volatile_table = &da9061_aa_volatile_table,
> +};
> +
> static const struct regmap_range da9062_aa_readable_ranges[] = {
> {
> .range_min = DA9062AA_PAGE_CON,
> @@ -456,17 +814,38 @@ static int da9062_get_device_type(struct da9062 *chip)
> .volatile_table = &da9062_aa_volatile_table,
> };
>
> +static const struct of_device_id da9062_dt_ids[] = {
> + { .compatible = "dlg,da9061", .data = (void *)COMPAT_TYPE_DA9061, },
> + { .compatible = "dlg,da9062", .data = (void *)COMPAT_TYPE_DA9062, },
It looks like this device can dynamically obtain this information from
the device. Please use that method instead.
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, da9062_dt_ids);
> +
> static int da9062_i2c_probe(struct i2c_client *i2c,
> const struct i2c_device_id *id)
> {
> struct da9062 *chip;
> + const struct of_device_id *match;
> unsigned int irq_base;
> + const struct mfd_cell *cell;
> + const struct regmap_irq_chip *irq_chip;
> + const struct regmap_config *config;
> + int cell_num;
> int ret;
>
> chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL);
> if (!chip)
> return -ENOMEM;
>
> + if (i2c->dev.of_node) {
> + match = of_match_node(da9062_dt_ids, i2c->dev.of_node);
> + if (!match)
> + return -EINVAL;
> +
> + chip->chip_type = (int)match->data;
> + } else
> + chip->chip_type = id->driver_data;
Please obtain this information from DA9062AA_VARIANT_ID.
> i2c_set_clientdata(i2c, chip);
> chip->dev = &i2c->dev;
>
> @@ -475,7 +854,25 @@ static int da9062_i2c_probe(struct i2c_client *i2c,
> return -EINVAL;
> }
>
> - chip->regmap = devm_regmap_init_i2c(i2c, &da9062_regmap_config);
> + switch (chip->chip_type) {
> + case(COMPAT_TYPE_DA9061):
> + cell = da9061_devs;
> + cell_num = ARRAY_SIZE(da9061_devs);
> + irq_chip = &da9061_irq_chip;
> + config = &da9061_regmap_config;
> + break;
> + case(COMPAT_TYPE_DA9062):
> + cell = da9062_devs;
> + cell_num = ARRAY_SIZE(da9062_devs);
> + irq_chip = &da9062_irq_chip;
> + config = &da9062_regmap_config;
> + break;
> + default:
> + dev_err(chip->dev, "Unrecognised chip type\n");
> + return -ENODEV;
> + }
> +
> + chip->regmap = devm_regmap_init_i2c(i2c, config);
> if (IS_ERR(chip->regmap)) {
> ret = PTR_ERR(chip->regmap);
> dev_err(chip->dev, "Failed to allocate register map: %d\n",
> @@ -493,7 +890,7 @@ static int da9062_i2c_probe(struct i2c_client *i2c,
>
> ret = regmap_add_irq_chip(chip->regmap, i2c->irq,
> IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
> - -1, &da9062_irq_chip,
> + -1, irq_chip,
> &chip->regmap_irq);
> if (ret) {
> dev_err(chip->dev, "Failed to request IRQ %d: %d\n",
> @@ -503,8 +900,8 @@ static int da9062_i2c_probe(struct i2c_client *i2c,
>
> irq_base = regmap_irq_chip_get_base(chip->regmap_irq);
>
> - ret = mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE, da9062_devs,
> - ARRAY_SIZE(da9062_devs), NULL, irq_base,
> + ret = mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE, cell,
> + cell_num, NULL, irq_base,
> NULL);
> if (ret) {
> dev_err(chip->dev, "Cannot register child devices\n");
> @@ -526,17 +923,12 @@ static int da9062_i2c_remove(struct i2c_client *i2c)
> }
>
> static const struct i2c_device_id da9062_i2c_id[] = {
> - { "da9062", 0 },
> + { "da9061", COMPAT_TYPE_DA9061 },
> + { "da9062", COMPAT_TYPE_DA9062 },
This too.
> { },
> };
> MODULE_DEVICE_TABLE(i2c, da9062_i2c_id);
>
> -static const struct of_device_id da9062_dt_ids[] = {
> - { .compatible = "dlg,da9062", },
> - { }
> -};
> -MODULE_DEVICE_TABLE(of, da9062_dt_ids);
> -
> static struct i2c_driver da9062_i2c_driver = {
> .driver = {
> .name = "da9062",
> @@ -549,6 +941,6 @@ static int da9062_i2c_remove(struct i2c_client *i2c)
>
> module_i2c_driver(da9062_i2c_driver);
>
> -MODULE_DESCRIPTION("Core device driver for Dialog DA9062");
> +MODULE_DESCRIPTION("Core device driver for Dialog DA9061 and DA9062");
> MODULE_AUTHOR("Steve Twiss <stwiss.opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org>");
> MODULE_LICENSE("GPL");
> diff --git a/include/linux/mfd/da9062/core.h b/include/linux/mfd/da9062/core.h
> index 376ba84..199c524 100644
> --- a/include/linux/mfd/da9062/core.h
> +++ b/include/linux/mfd/da9062/core.h
> @@ -18,7 +18,31 @@
> #include <linux/interrupt.h>
> #include <linux/mfd/da9062/registers.h>
>
> -/* Interrupts */
> +enum da9062_compatible_types {
> + COMPAT_TYPE_DA9061 = 1,
> + COMPAT_TYPE_DA9062,
> +};
> +
> +enum da9061_irqs {
> + /* IRQ A */
> + DA9061_IRQ_ONKEY,
> + DA9061_IRQ_WDG_WARN,
> + DA9061_IRQ_SEQ_RDY,
> + /* IRQ B*/
> + DA9061_IRQ_TEMP,
> + DA9061_IRQ_LDO_LIM,
> + DA9061_IRQ_DVC_RDY,
> + DA9061_IRQ_VDD_WARN,
> + /* IRQ C */
> + DA9061_IRQ_GPI0,
> + DA9061_IRQ_GPI1,
> + DA9061_IRQ_GPI2,
> + DA9061_IRQ_GPI3,
> + DA9061_IRQ_GPI4,
> +
> + DA9061_NUM_IRQ,
> +};
> +
> enum da9062_irqs {
> /* IRQ A */
> DA9062_IRQ_ONKEY,
> @@ -45,6 +69,7 @@ struct da9062 {
> struct device *dev;
> struct regmap *regmap;
> struct regmap_irq_chip_data *regmap_irq;
> + enum da9062_compatible_types chip_type;
> };
>
> #endif /* __MFD_DA9062_CORE_H__ */
> diff --git a/include/linux/mfd/da9062/registers.h b/include/linux/mfd/da9062/registers.h
> index 97790d1..4457fdc 100644
> --- a/include/linux/mfd/da9062/registers.h
> +++ b/include/linux/mfd/da9062/registers.h
> @@ -18,6 +18,8 @@
>
> #define DA9062_PMIC_DEVICE_ID 0x62
> #define DA9062_PMIC_VARIANT_MRC_AA 0x01
> +#define DA9062_PMIC_VARIANT_VRC_DA9061 0x01
> +#define DA9062_PMIC_VARIANT_VRC_DA9062 0x02
>
> #define DA9062_I2C_PAGE_SEL_SHIFT 1
>
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] gpio: pca953x: Add optional reset gpio control
From: Vladimir Zapolskiy @ 2017-01-04 10:20 UTC (permalink / raw)
To: Andy Shevchenko, Steve Longerbeam
Cc: Linus Walleij, Alexandre Courbot, Rob Herring, Mark Rutland,
linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, devicetree,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Steve Longerbeam
In-Reply-To: <CAHp75VeCKPy4B51P_N9Bp03zPUbRodKzitc-n16ZRKJWcEF4fA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On 01/04/2017 01:37 AM, Andy Shevchenko wrote:
> On Mon, Jan 2, 2017 at 11:07 PM, Steve Longerbeam <slongerbeam-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> Add optional reset-gpios pin control. If present, de-assert the
>> specified reset gpio pin to bring the chip out of reset.
>
>> --- a/drivers/gpio/gpio-pca953x.c
>> +++ b/drivers/gpio/gpio-pca953x.c
>> @@ -22,6 +22,7 @@
>> #include <linux/of_platform.h>
>> #include <linux/acpi.h>
>> #include <linux/regulator/consumer.h>
>
>> +#include <linux/gpio/consumer.h>
>
> Please, try to put it somehow alphabetically ordered (yes, I see it's
> not in general, but try to squeeze it into longest part which is
> ordered).
>
>>
>> #define PCA953X_INPUT 0
>> #define PCA953X_OUTPUT 1
>> @@ -754,8 +755,18 @@ static int pca953x_probe(struct i2c_client *client,
>> invert = pdata->invert;
>> chip->names = pdata->names;
>> } else {
>> + struct gpio_desc *reset_gpio;
>> +
>> chip->gpio_start = -1;
>> irq_base = 0;
>> +
>> + /* see if we need to de-assert a reset pin */
>
> see -> See
>
>> + reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
>> + GPIOD_OUT_LOW);
>
> Shouldn't be _optional_exclusive?
> See this recent discussion https://patchwork.ozlabs.org/patch/706002/
There is no devm_gpiod_get_optional_exclusive(), probably you confuse
the function with devm_reset_control_get_optional_exclusive().
>> + if (IS_ERR(reset_gpio)) {
>> + dev_err(&client->dev, "request for reset pin failed\n");
>> + return PTR_ERR(reset_gpio);
>> + }
>> }
>
--
With best wishes,
Vladimir
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 2/4] dt-bindings: mfd: Remove TPS65217 interrupts
From: Lee Jones @ 2017-01-04 10:21 UTC (permalink / raw)
To: Milo Kim
Cc: bcousson-rdvid1DuHRBWk0Htik3J/w, Tony Lindgren, Arnd Bergmann,
Sebastian Reichel, Dmitry Torokhov,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20161209062833.5768-3-woogyom.kim-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On Fri, 09 Dec 2016, Milo Kim wrote:
> Interrupt numbers are from the datasheet, so no need to keep them in
> the ABI. Use the number in the DT file.
>
> Signed-off-by: Milo Kim <woogyom.kim-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
> arch/arm/boot/dts/am335x-bone-common.dtsi | 8 +++-----
> include/dt-bindings/mfd/tps65217.h | 26 --------------------------
> 2 files changed, 3 insertions(+), 31 deletions(-)
> delete mode 100644 include/dt-bindings/mfd/tps65217.h
Acked-by: Lee Jones <lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
I'm happy for this to go in via your respective ARM tree.
> diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
> index 14b6269..3e32dd1 100644
> --- a/arch/arm/boot/dts/am335x-bone-common.dtsi
> +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
> @@ -6,8 +6,6 @@
> * published by the Free Software Foundation.
> */
>
> -#include <dt-bindings/mfd/tps65217.h>
> -
> / {
> cpus {
> cpu@0 {
> @@ -319,13 +317,13 @@
> ti,pmic-shutdown-controller;
>
> charger {
> - interrupts = <TPS65217_IRQ_AC>, <TPS65217_IRQ_USB>;
> - interrupt-names = "AC", "USB";
> + interrupts = <0>, <1>;
> + interrupt-names = "USB", "AC";
> status = "okay";
> };
>
> pwrbutton {
> - interrupts = <TPS65217_IRQ_PB>;
> + interrupts = <2>;
> status = "okay";
> };
>
> diff --git a/include/dt-bindings/mfd/tps65217.h b/include/dt-bindings/mfd/tps65217.h
> deleted file mode 100644
> index cafb9e6..0000000
> --- a/include/dt-bindings/mfd/tps65217.h
> +++ /dev/null
> @@ -1,26 +0,0 @@
> -/*
> - * This header provides macros for TI TPS65217 DT bindings.
> - *
> - * Copyright (C) 2016 Texas Instruments
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful, but
> - * WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - * General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License along with
> - * this program. If not, see <http://www.gnu.org/licenses/>.
> - */
> -
> -#ifndef __DT_BINDINGS_TPS65217_H__
> -#define __DT_BINDINGS_TPS65217_H__
> -
> -#define TPS65217_IRQ_USB 0
> -#define TPS65217_IRQ_AC 1
> -#define TPS65217_IRQ_PB 2
> -
> -#endif
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] gpio: pca953x: Add optional reset gpio control
From: Vladimir Zapolskiy @ 2017-01-04 10:25 UTC (permalink / raw)
To: Steve Longerbeam, linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
gnurou-Re5JQEeQqe8AvxtiuMwx3w, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8
Cc: linux-gpio-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Steve Longerbeam
In-Reply-To: <1483391271-17304-2-git-send-email-steve_longerbeam-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>
Hi Steve,
On 01/02/2017 11:07 PM, Steve Longerbeam wrote:
> Add optional reset-gpios pin control. If present, de-assert the
> specified reset gpio pin to bring the chip out of reset.
>
> Signed-off-by: Steve Longerbeam <steve_longerbeam-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>
> Cc: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Cc: Alexandre Courbot <gnurou-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Cc: linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> ---
> Documentation/devicetree/bindings/gpio/gpio-pca953x.txt | 4 ++++
> drivers/gpio/gpio-pca953x.c | 11 +++++++++++
> 2 files changed, 15 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt b/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt
> index 08dd15f..da54f4c 100644
> --- a/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt
> +++ b/Documentation/devicetree/bindings/gpio/gpio-pca953x.txt
> @@ -29,6 +29,10 @@ Required properties:
> onsemi,pca9654
> exar,xra1202
>
> +Optional properties:
> + - reset-gpios: GPIO specification for the RESET input
> +
> +
Drop the surplus empty line above.
> Example:
>
>
> diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
> index d5d72d8..ca2ddea 100644
> --- a/drivers/gpio/gpio-pca953x.c
> +++ b/drivers/gpio/gpio-pca953x.c
> @@ -22,6 +22,7 @@
> #include <linux/of_platform.h>
> #include <linux/acpi.h>
> #include <linux/regulator/consumer.h>
> +#include <linux/gpio/consumer.h>
>
> #define PCA953X_INPUT 0
> #define PCA953X_OUTPUT 1
> @@ -754,8 +755,18 @@ static int pca953x_probe(struct i2c_client *client,
> invert = pdata->invert;
> chip->names = pdata->names;
> } else {
> + struct gpio_desc *reset_gpio;
> +
> chip->gpio_start = -1;
> irq_base = 0;
> +
> + /* see if we need to de-assert a reset pin */
> + reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
> + GPIOD_OUT_LOW);
> + if (IS_ERR(reset_gpio)) {
> + dev_err(&client->dev, "request for reset pin failed\n");
I'm not confident that the error message is wanted here, you may consider either
to remove it or at least print it out if (PTR_ERR(reset_gpio) != -EPROBE_DEFER).
> + return PTR_ERR(reset_gpio);
> + }
> }
>
> chip->client = client;
>
Reviewed-by: Vladimir Zapolskiy <vladimir_zapolskiy-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>
--
With best wishes,
Vladimir
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] gpio: pca953x: Add optional reset gpio control
From: Andy Shevchenko @ 2017-01-04 10:31 UTC (permalink / raw)
To: Vladimir Zapolskiy
Cc: Steve Longerbeam, Linus Walleij, Alexandre Courbot, Rob Herring,
Mark Rutland, linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Steve Longerbeam
In-Reply-To: <7bfce806-7670-0bf3-bdf2-00aaf68b5b11-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>
On Wed, Jan 4, 2017 at 12:20 PM, Vladimir Zapolskiy
<vladimir_zapolskiy-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org> wrote:
> On 01/04/2017 01:37 AM, Andy Shevchenko wrote:
>> On Mon, Jan 2, 2017 at 11:07 PM, Steve Longerbeam <slongerbeam-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>>> Add optional reset-gpios pin control. If present, de-assert the
>>> specified reset gpio pin to bring the chip out of reset.
>>
>>> --- a/drivers/gpio/gpio-pca953x.c
>>> +++ b/drivers/gpio/gpio-pca953x.c
>>> @@ -22,6 +22,7 @@
>>> #include <linux/of_platform.h>
>>> #include <linux/acpi.h>
>>> #include <linux/regulator/consumer.h>
>>
>>> +#include <linux/gpio/consumer.h>
>>
>> Please, try to put it somehow alphabetically ordered (yes, I see it's
>> not in general, but try to squeeze it into longest part which is
>> ordered).
>>
>>>
>>> #define PCA953X_INPUT 0
>>> #define PCA953X_OUTPUT 1
>>> @@ -754,8 +755,18 @@ static int pca953x_probe(struct i2c_client *client,
>>> invert = pdata->invert;
>>> chip->names = pdata->names;
>>> } else {
>>> + struct gpio_desc *reset_gpio;
>>> +
>>> chip->gpio_start = -1;
>>> irq_base = 0;
>>> +
>>> + /* see if we need to de-assert a reset pin */
>>
>> see -> See
>>
>>> + reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
>>> + GPIOD_OUT_LOW);
>>
>> Shouldn't be _optional_exclusive?
>> See this recent discussion https://patchwork.ozlabs.org/patch/706002/
>
> There is no devm_gpiod_get_optional_exclusive(), probably you confuse
> the function with devm_reset_control_get_optional_exclusive().
Perhaps it's time to add
drivers/reset/reset-gpio.c ?
>
>>> + if (IS_ERR(reset_gpio)) {
>>> + dev_err(&client->dev, "request for reset pin failed\n");
>>> + return PTR_ERR(reset_gpio);
>>> + }
>>> }
>>
>
> --
> With best wishes,
> Vladimir
--
With Best Regards,
Andy Shevchenko
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
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