178 lines
4.6 KiB
Diff
178 lines
4.6 KiB
Diff
|
From 0612580e68fa584d415f8080f65da2d4873664fe Mon Sep 17 00:00:00 2001
|
||
|
From: Ondrej Jirman <megous@megous.com>
|
||
|
Date: Tue, 11 Feb 2020 14:10:05 +0100
|
||
|
Subject: [PATCH 23/29] pinephone: Add volume_key environment variable
|
||
|
|
||
|
When the user has a volume key pressed volume_key variable will
|
||
|
contain either value 'down' or 'up', otherwise it will be empty.
|
||
|
|
||
|
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||
|
---
|
||
|
board/sunxi/Makefile | 1 +
|
||
|
board/sunxi/board.c | 18 ++++++++++
|
||
|
board/sunxi/lradc.c | 81 ++++++++++++++++++++++++++++++++++++++++++++
|
||
|
board/sunxi/lradc.h | 11 ++++++
|
||
|
4 files changed, 111 insertions(+)
|
||
|
create mode 100644 board/sunxi/lradc.c
|
||
|
create mode 100644 board/sunxi/lradc.h
|
||
|
|
||
|
diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
|
||
|
index d96b7897..a096a5c7 100644
|
||
|
--- a/board/sunxi/Makefile
|
||
|
+++ b/board/sunxi/Makefile
|
||
|
@@ -12,3 +12,4 @@ obj-$(CONFIG_MACH_SUN4I) += dram_sun4i_auto.o
|
||
|
obj-$(CONFIG_MACH_SUN5I) += dram_sun5i_auto.o
|
||
|
obj-$(CONFIG_MACH_SUN7I) += dram_sun5i_auto.o
|
||
|
obj-$(CONFIG_CHIP_DIP_SCAN) += chip.o
|
||
|
+obj-$(CONFIG_MACH_SUN50I) += lradc.o
|
||
|
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
|
||
|
index 2790a0f9..50344342 100644
|
||
|
--- a/board/sunxi/board.c
|
||
|
+++ b/board/sunxi/board.c
|
||
|
@@ -46,6 +46,7 @@
|
||
|
#include <spl.h>
|
||
|
#include <sy8106a.h>
|
||
|
#include <asm/setup.h>
|
||
|
+#include "lradc.h"
|
||
|
#include <status_led.h>
|
||
|
|
||
|
DECLARE_GLOBAL_DATA_PTR;
|
||
|
@@ -588,6 +589,12 @@ void sunxi_board_init(void)
|
||
|
{
|
||
|
int power_failed = 0;
|
||
|
|
||
|
+#ifdef CONFIG_MACH_SUN50I
|
||
|
+ // we init the lradc in SPL to get the ADC started early to have
|
||
|
+ // a valid sample when U-Boot main binary gets executed.
|
||
|
+ lradc_enable();
|
||
|
+#endif
|
||
|
+
|
||
|
#ifdef CONFIG_LED_STATUS
|
||
|
if (IS_ENABLED(CONFIG_SPL_DRIVERS_MISC))
|
||
|
status_led_init();
|
||
|
@@ -861,6 +868,17 @@ int misc_init_r(void)
|
||
|
env_set("fdtfile", str);
|
||
|
}
|
||
|
|
||
|
+#ifdef CONFIG_MACH_SUN50I
|
||
|
+ int key = lradc_get_pressed_key();
|
||
|
+ if (key == KEY_VOLUMEDOWN)
|
||
|
+ env_set("volume_key", "down");
|
||
|
+ else if (key == KEY_VOLUMEUP)
|
||
|
+ env_set("volume_key", "up");
|
||
|
+
|
||
|
+ // no longer needed
|
||
|
+ lradc_disable();
|
||
|
+#endif
|
||
|
+
|
||
|
setup_environment(gd->fdt_blob);
|
||
|
|
||
|
return 0;
|
||
|
diff --git a/board/sunxi/lradc.c b/board/sunxi/lradc.c
|
||
|
new file mode 100644
|
||
|
index 00000000..693b198e
|
||
|
--- /dev/null
|
||
|
+++ b/board/sunxi/lradc.c
|
||
|
@@ -0,0 +1,81 @@
|
||
|
+#include <common.h>
|
||
|
+#include <asm/io.h>
|
||
|
+#include "lradc.h"
|
||
|
+
|
||
|
+#define LRADC_BASE 0x1c21800
|
||
|
+
|
||
|
+#define LRADC_CTRL (LRADC_BASE + 0x00)
|
||
|
+#define LRADC_INTC (LRADC_BASE + 0x04)
|
||
|
+#define LRADC_INTS (LRADC_BASE + 0x08)
|
||
|
+#define LRADC_DATA0 (LRADC_BASE + 0x0c)
|
||
|
+#define LRADC_DATA1 (LRADC_BASE + 0x10)
|
||
|
+
|
||
|
+/* LRADC_CTRL bits */
|
||
|
+#define FIRST_CONVERT_DLY(x) ((x) << 24) /* 8 bits */
|
||
|
+#define CHAN_SELECT(x) ((x) << 22) /* 2 bits */
|
||
|
+#define CONTINUE_TIME_SEL(x) ((x) << 16) /* 4 bits */
|
||
|
+#define KEY_MODE_SEL(x) ((x) << 12) /* 2 bits */
|
||
|
+#define LEVELA_B_CNT(x) ((x) << 8) /* 4 bits */
|
||
|
+#define HOLD_KEY_EN(x) ((x) << 7)
|
||
|
+#define HOLD_EN(x) ((x) << 6)
|
||
|
+#define LEVELB_VOL(x) ((x) << 4) /* 2 bits */
|
||
|
+#define SAMPLE_RATE(x) ((x) << 2) /* 2 bits */
|
||
|
+#define ENABLE(x) ((x) << 0)
|
||
|
+
|
||
|
+/* LRADC_INTC and LRADC_INTS bits */
|
||
|
+#define CHAN1_KEYUP_IRQ BIT(12)
|
||
|
+#define CHAN1_ALRDY_HOLD_IRQ BIT(11)
|
||
|
+#define CHAN1_HOLD_IRQ BIT(10)
|
||
|
+#define CHAN1_KEYDOWN_IRQ BIT(9)
|
||
|
+#define CHAN1_DATA_IRQ BIT(8)
|
||
|
+#define CHAN0_KEYUP_IRQ BIT(4)
|
||
|
+#define CHAN0_ALRDY_HOLD_IRQ BIT(3)
|
||
|
+#define CHAN0_HOLD_IRQ BIT(2)
|
||
|
+#define CHAN0_KEYDOWN_IRQ BIT(1)
|
||
|
+#define CHAN0_DATA_IRQ BIT(0)
|
||
|
+
|
||
|
+// this is for PinePhone only
|
||
|
+
|
||
|
+int lradc_get_pressed_key(void)
|
||
|
+{
|
||
|
+ uint32_t val;
|
||
|
+ uint32_t vref = 3000000 * 2 / 3;
|
||
|
+
|
||
|
+ val = readl(LRADC_DATA0) & 0x3f;
|
||
|
+ val = val * vref / 63;
|
||
|
+
|
||
|
+// printf("lradc=%u\n", val);
|
||
|
+
|
||
|
+ if (val < 200000) // 158730
|
||
|
+ return KEY_VOLUMEUP;
|
||
|
+ else if (val < 400000) // 349206
|
||
|
+ return KEY_VOLUMEDOWN;
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+void lradc_enable(void)
|
||
|
+{
|
||
|
+ // aldo3 is always on and defaults to 3V
|
||
|
+
|
||
|
+ writel(0xffffffff, LRADC_INTS);
|
||
|
+ writel(0, LRADC_INTC);
|
||
|
+
|
||
|
+ /*
|
||
|
+ * Set sample time to 4 ms / 250 Hz. Wait 2 * 4 ms for key to
|
||
|
+ * stabilize on press, wait (1 + 1) * 4 ms for key release
|
||
|
+ */
|
||
|
+ writel(FIRST_CONVERT_DLY(0) | LEVELA_B_CNT(0) | HOLD_EN(0) |
|
||
|
+ SAMPLE_RATE(0) | ENABLE(1), LRADC_CTRL);
|
||
|
+
|
||
|
+}
|
||
|
+
|
||
|
+void lradc_disable(void)
|
||
|
+{
|
||
|
+ writel(0xffffffff, LRADC_INTS);
|
||
|
+ writel(0, LRADC_INTC);
|
||
|
+
|
||
|
+ /* Disable lradc, leave other settings unchanged */
|
||
|
+ writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) |
|
||
|
+ SAMPLE_RATE(2), LRADC_CTRL);
|
||
|
+}
|
||
|
diff --git a/board/sunxi/lradc.h b/board/sunxi/lradc.h
|
||
|
new file mode 100644
|
||
|
index 00000000..c908401b
|
||
|
--- /dev/null
|
||
|
+++ b/board/sunxi/lradc.h
|
||
|
@@ -0,0 +1,11 @@
|
||
|
+#pragma once
|
||
|
+
|
||
|
+enum {
|
||
|
+ KEY_NONE = 0,
|
||
|
+ KEY_VOLUMEDOWN = 1,
|
||
|
+ KEY_VOLUMEUP = 2,
|
||
|
+};
|
||
|
+
|
||
|
+int lradc_get_pressed_key(void);
|
||
|
+void lradc_enable(void);
|
||
|
+void lradc_disable(void);
|
||
|
--
|
||
|
2.34.1
|
||
|
|