imx6 snvs-pwrkey not working

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

imx6 snvs-pwrkey not working

Jump to solution
4,679 Views
deschamp
Contributor II

I am trying to get snvs-pwrkey to function on my custom hardware using a imx6Q to detect a power off request.

I modified my device tree and defconfig files to include the snvs-pwrkey driver, and I see it is instantiated and registered as a keyboard in dmesg.

However when I run evtest to test the keyboard I get no response from the keypress.

snvs-rtc is working fine, and I have another keyboard kpp working fine as well.

added to arch/arm/boot/dts/imx6qdl.dtsi

snvs_pwrkey: snvs-pwrkey@0x020cc000 {

compatible = "fsl,imx6sx-snvs-pwrkey";

reg = <0x020cc000 0x4000>;

interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;

fsl,keycode = <116>; /* KEY_POWER */

fsl,wakeup;

};

added to arch/arm/boot/dts/imx6qdl-wandboard.dtsi

&snvs_pwrkey {

status = "okay";

};

Labels (3)
Tags (2)
0 Kudos
1 Solution
1,823 Views
deschamp
Contributor II

Correct usage is:

snvs-pwrkey@0x020cc000 {

     compatible = "fsl,imx6sx-snvs-pwrkey";

     reg = <0x020cc000 0x4000>;

     interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;

     fsl,keycode = <116>; /* KEY_POWER */

     fsl,wakeup;

};

However, there is an issue with the driver.

The interrupt only triggers on the release of the key. The driver is looking for a change in the state of the key, but since the interrupt triggers on release the key value is always 0. Removing this check make the driver work fine.

I am using a quad processor, so I am not sure if this is different for the others.

Patch looks like this:

---

drivers/input/keyboard/snvs_pwrkey.c | 37 +++++++++++++++++++++---------------

1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c

index 1d6d62c..fa85b69 100644

--- a/drivers/input/keyboard/snvs_pwrkey.c

+++ b/drivers/input/keyboard/snvs_pwrkey.c

@@ -46,21 +46,28 @@ static void imx_imx_snvs_check_for_events(unsigned long data)

  void __iomem *ioaddr = pdata->ioaddr;

  u32 state;

- state = ((readl_relaxed(ioaddr + SNVS_HPSR_REG) & SNVS_HPSR_BTN) ?

- 1 : 0);

-

- /* only report new event if status changed */

- if (state ^ pdata->keystate) {

- pdata->keystate = state;

- input_event(input, EV_KEY, pdata->keycode, state);

- input_sync(input);

- }

-

- /* repeat check if pressed long */

- if (state) {

- mod_timer(&pdata->check_timer,

-  jiffies + msecs_to_jiffies(60));

- }

+ //state = ((readl_relaxed(ioaddr + SNVS_HPSR_REG) & SNVS_HPSR_BTN) ? 1 : 0);

+

+ ///* only report new event if status changed */

+ //if (state ^ pdata->keystate) {

+ // pdata->keystate = state;

+ // input_event(input, EV_KEY, pdata->keycode, state);

+ // input_sync(input);

+ //}

+

+ ///* repeat check if pressed long */

+ //if (state) {

+ // mod_timer(&pdata->check_timer,

+ //  jiffies + msecs_to_jiffies(60));

+ //}

+

+ /* interrupt only reports release of key so do not wait for state change */

+ state=1;

+ input_event(input, EV_KEY, pdata->keycode, state);

+ input_sync(input);

+ state=0;

+ input_event(input, EV_KEY, pdata->keycode, state);

+ input_sync(input);

}

static irqreturn_t imx_snvs_pwrkey_interrupt(int irq, void *dev_id)

--

1.9.1

View solution in original post

0 Kudos
4 Replies
1,823 Views
kenlin
Contributor II

I experienced the same issues with iMx6 dual. The bit 6 (BTN) in SNVS_HPSR_REG was not being set. Is there anyone from NXP can help identify the root cause ?

0 Kudos
1,824 Views
deschamp
Contributor II

Correct usage is:

snvs-pwrkey@0x020cc000 {

     compatible = "fsl,imx6sx-snvs-pwrkey";

     reg = <0x020cc000 0x4000>;

     interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;

     fsl,keycode = <116>; /* KEY_POWER */

     fsl,wakeup;

};

However, there is an issue with the driver.

The interrupt only triggers on the release of the key. The driver is looking for a change in the state of the key, but since the interrupt triggers on release the key value is always 0. Removing this check make the driver work fine.

I am using a quad processor, so I am not sure if this is different for the others.

Patch looks like this:

---

drivers/input/keyboard/snvs_pwrkey.c | 37 +++++++++++++++++++++---------------

1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c

index 1d6d62c..fa85b69 100644

--- a/drivers/input/keyboard/snvs_pwrkey.c

+++ b/drivers/input/keyboard/snvs_pwrkey.c

@@ -46,21 +46,28 @@ static void imx_imx_snvs_check_for_events(unsigned long data)

  void __iomem *ioaddr = pdata->ioaddr;

  u32 state;

- state = ((readl_relaxed(ioaddr + SNVS_HPSR_REG) & SNVS_HPSR_BTN) ?

- 1 : 0);

-

- /* only report new event if status changed */

- if (state ^ pdata->keystate) {

- pdata->keystate = state;

- input_event(input, EV_KEY, pdata->keycode, state);

- input_sync(input);

- }

-

- /* repeat check if pressed long */

- if (state) {

- mod_timer(&pdata->check_timer,

-  jiffies + msecs_to_jiffies(60));

- }

+ //state = ((readl_relaxed(ioaddr + SNVS_HPSR_REG) & SNVS_HPSR_BTN) ? 1 : 0);

+

+ ///* only report new event if status changed */

+ //if (state ^ pdata->keystate) {

+ // pdata->keystate = state;

+ // input_event(input, EV_KEY, pdata->keycode, state);

+ // input_sync(input);

+ //}

+

+ ///* repeat check if pressed long */

+ //if (state) {

+ // mod_timer(&pdata->check_timer,

+ //  jiffies + msecs_to_jiffies(60));

+ //}

+

+ /* interrupt only reports release of key so do not wait for state change */

+ state=1;

+ input_event(input, EV_KEY, pdata->keycode, state);

+ input_sync(input);

+ state=0;

+ input_event(input, EV_KEY, pdata->keycode, state);

+ input_sync(input);

}

static irqreturn_t imx_snvs_pwrkey_interrupt(int irq, void *dev_id)

--

1.9.1

0 Kudos
1,823 Views
igorpadykov
NXP Employee
NXP Employee

Hi Joe

one can look at linux documents in ..Documentation/devicetree/bindings/input/snvs-pwrkey.txt

[PATCH v2 2/3] document: devicetree: input: imx: i.mx snvs power device tree bindings -- Linux Input

Discussing the Linux ARM kernel

Best regards

igor

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,823 Views
deschamp
Contributor II

Hi Igor,

Thanks for the response.

I looked at these documents and modified to match exactly:

snvs-pwrkey@0x020cc000 {

  compatible = "fsl,imx6sx-snvs-pwrkey";

  reg = <0x020cc000 0x4000>;

  interrupts = <0 4 0x4>;

  linux,keycode = <116>; /* KEY_POWER */

  linux,wakeup;

  };

However, I still get the same result.

Running evtest shows that the driver is loading, but it does not receive the keypress when the ON_OFF button is pressed.

If I press and hold the ON_OFF button, for 6 seconds or so, it shuts down the system as expected.

Thanks

Joe

0 Kudos