summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package/kbd/Makefile4
-rw-r--r--package/kbd/files/hpjornada.map279
-rwxr-xr-xscripts/install.sh2
-rw-r--r--target/config/Config.in.runtime2
-rw-r--r--target/config/Config.in.subsystem12
-rw-r--r--target/linux/Config.in1
-rw-r--r--target/linux/Config.in.kernelcfg1
-rw-r--r--target/linux/config/Config.in.hpjornada12
-rw-r--r--target/linux/patches/6.15.6/0001-pcmcia-Add-Hitachi-HD6446x-PCMCIA-socket-support.patch720
-rw-r--r--target/linux/patches/6.15.6/orinoco.patch12933
-rwxr-xr-xtarget/sh/hp-jornada/Autorun.infbin0 -> 58 bytes
-rw-r--r--target/sh/hp-jornada/shlo.exebin0 -> 64000 bytes
-rw-r--r--target/sh/hp-jornada/shlo.txt.68015
-rw-r--r--target/sh/hp-jornada/shlo.txt.69015
-rw-r--r--target/sh/kernel/hp-jornada2201
-rw-r--r--target/sh/systems/hp-jornada13
16 files changed, 16209 insertions, 1 deletions
diff --git a/package/kbd/Makefile b/package/kbd/Makefile
index 7c0b62efa..97b2b691f 100644
--- a/package/kbd/Makefile
+++ b/package/kbd/Makefile
@@ -43,6 +43,10 @@ kbd-install:
$(IDIR_KBD)/usr/bin
$(INSTALL_BIN) $(WRKINST)/usr/bin/loadkeys \
$(IDIR_KBD)/usr/bin
+ifeq ($(ADK_TARGET_SYSTEM_HP_JORNADA),y)
+ $(INSTALL_DIR) $(IDIR_KBD)/etc
+ $(CP) ./files/hpjornada.map $(IDIR_KBD)/etc
+endif
ifeq ($(ADK_TARGET_SYSTEM_SHARP_ZAURUS),y)
$(INSTALL_DIR) $(IDIR_KBD)/etc
$(CP) ./files/zaurus.map $(IDIR_KBD)/etc
diff --git a/package/kbd/files/hpjornada.map b/package/kbd/files/hpjornada.map
new file mode 100644
index 000000000..c7fc2a670
--- /dev/null
+++ b/package/kbd/files/hpjornada.map
@@ -0,0 +1,279 @@
+# English keymap for Jornada 6xx devices.
+#
+# Created by Tibor Zenis ( zenis <at> fmph.uniba.sk )
+# (Lightly) Modified by Alex Palestras ( B_Linuz <at> yahoo.com )
+# plain, shift, altgr, ctrl, shift + ctrl, alt, ctrl + alt
+
+keymaps 0-2,4-5,8,12
+keycode 1 = Escape Escape
+ alt keycode 1 = Meta_Escape
+keycode 2 = one exclam asciitilde
+ alt keycode 2 = Meta_one
+keycode 3 = two at grave
+ alt keycode 3 = Meta_two
+keycode 4 = three numbersign
+ alt keycode 4 = Meta_three
+ altgr keycode 4 = pound
+keycode 5 = four dollar
+ control keycode 5 = Control_backslash
+ alt keycode 5 = Meta_four
+ altgr keycode 5 = currency
+keycode 6 = five percent
+ control keycode 6 = Control_bracketright
+ alt keycode 6 = Meta_five
+keycode 7 = six asciicircum
+ control keycode 7 = Control_asciicircum
+ alt keycode 7 = Meta_six
+keycode 8 = seven ampersand braceleft
+ control keycode 8 = Control_underscore
+ altgr keycode 8 = KP_7
+keycode 9 = eight asterisk bracketleft
+ control keycode 9 = Delete
+ altgr keycode 9 = KP_8
+keycode 10 = nine parenleft bracketright
+ altgr keycode 10 = KP_9
+keycode 11 = zero parenright braceright
+ altgr keycode 11 = KP_Divide
+keycode 12 = minus underscore backslash
+ control keycode 11 = Control_underscore
+ shift control keycode 11 = Control_underscore
+ alt keycode 11 = Meta_minus
+keycode 13 = equal plus
+ alt keycode 13 = Meta_equal
+keycode 14 = Delete Delete
+ control keycode 14 = BackSpace
+ alt keycode 14 = Meta_Delete
+keycode 15 = Tab Tab
+ alt keycode 15 = Meta_Tab
+keycode 16 = q
+keycode 17 = w
+keycode 18 = e
+ Shift keycode 18 = E
+keycode 19 = r
+keycode 20 = t
+keycode 21 = y
+ altgr keycode 21 = KP_4
+keycode 22 = u
+ altgr keycode 22 = KP_5
+keycode 23 = i
+ altgr keycode 23 = KP_6
+keycode 24 = o
+ altgr keycode 24 = KP_Multiply
+keycode 25 = p
+ AltGr keycode 25 = braceleft
+keycode 26 = backslash bar
+ AltGr keycode 26 = braceright
+keycode 28 = Return
+ alt keycode 28 = Meta_Control_m
+keycode 29 = Control
+ altgr keycode 29 = Num_Lock
+keycode 30 = a
+keycode 31 = s
+keycode 32 = d
+keycode 33 = f
+keycode 34 = g
+keycode 35 = h
+ altgr keycode 35 = KP_1
+keycode 36 = j
+ altgr keycode 36 = KP_2
+keycode 37 = k
+ altgr keycode 37 = KP_3
+keycode 38 = l
+ altgr keycode 38 = KP_Subtract
+keycode 39 = semicolon colon bracketleft
+ alt keycode 39 = Meta_semicolon
+keycode 40 = apostrophe quotedbl bracketright
+ control keycode 40 = Control_g
+ alt keycode 40 = Meta_apostrophe
+keycode 41 = F11
+ shift keycode 41 = F21
+ altgr keycode 41 = Console_23
+ alt keycode 41 = Console_11
+ control alt keycode 41 = Console_11
+keycode 42 = Shift
+ altgr keycode 42 = Caps_Lock
+keycode 44 = z
+keycode 45 = x
+keycode 46 = c
+keycode 47 = v
+keycode 48 = b
+keycode 49 = n
+ altgr keycode 49 = KP_0
+keycode 50 = m
+ altgr keycode 50 = KP_Comma
+keycode 51 = comma less
+ altgr keycode 51 = KP_Period
+keycode 52 = period greater
+ control keycode 52 = Compose
+ altgr keycode 52 = KP_Add
+keycode 54 = Shift
+keycode 56 = Alt
+keycode 57 = space space
+ alt keycode 57 = Meta_space
+keycode 58 = F9
+ shift keycode 58 = F19
+ altgr keycode 58 = Console_21
+ alt keycode 58 = Console_9
+ control alt keycode 58 = Console_9
+keycode 59 = F1
+ altgr keycode 59 = Console_13
+ alt keycode 59 = Console_1
+ control alt keycode 59 = Console_1
+keycode 60 = F2
+ shift keycode 60 = F12
+ altgr keycode 60 = Console_14
+ alt keycode 60 = Console_2
+ control alt keycode 60 = Console_2
+keycode 61 = F3
+ shift keycode 61 = F13
+ altgr keycode 61 = Console_15
+ alt keycode 61 = Console_3
+ control alt keycode 61 = Console_3
+keycode 62 = F4
+ shift keycode 62 = F14
+ altgr keycode 62 = Console_16
+ alt keycode 62 = Console_4
+ control alt keycode 62 = Console_4
+keycode 63 = F5
+ shift keycode 63 = F15
+ altgr keycode 63 = Console_17
+ alt keycode 63 = Console_5
+ control alt keycode 63 = Console_5
+keycode 64 = F6
+ shift keycode 64 = F16
+ altgr keycode 64 = Console_18
+ alt keycode 64 = Console_6
+ control alt keycode 64 = Console_6
+keycode 65 = F7
+ shift keycode 65 = F17
+ altgr keycode 65 = Console_19
+ alt keycode 65 = Console_7
+ control alt keycode 65 = Console_7
+keycode 66 = F8
+ shift keycode 66 = F18
+ altgr keycode 66 = Console_20
+ alt keycode 66 = Console_8
+ control alt keycode 66 = Console_8
+keycode 72 = Up
+ shift keycode 72 = Scroll_Backward
+ altgr keycode 72 = Scroll_Backward
+ alt keycode 72 = Prior
+keycode 74 = Control
+keycode 75 = Left
+ altgr keycode 75 = Decr_Console
+ alt keycode 75 = Find
+keycode 77 = Right
+ altgr keycode 77 = Incr_Console
+ alt keycode 77 = Select
+keycode 80 = Down
+ shift keycode 80 = Scroll_Forward
+ altgr keycode 80 = Scroll_Forward
+ alt keycode 80 = Next
+keycode 83 = Remove Remove Meta_Delete
+ alt keycode 83 = Meta_Delete
+keycode 112 = F10
+ shift keycode 112 = F20
+ altgr keycode 112 = Console_22
+ alt keycode 112 = Console_10
+ control alt keycode 112 = Console_10
+keycode 115 = slash question
+ control keycode 115 = Delete
+ alt keycode 115 = Meta_slash
+keycode 123 = AltGr
+keycode 0 = Insert
+string F1 = "\033[[A"
+string F2 = "\033[[B"
+string F3 = "\033[[C"
+string F4 = "\033[[D"
+string F5 = "\033[[E"
+string F6 = "\033[17~"
+string F7 = "\033[18~"
+string F8 = "\033[19~"
+string F9 = "\033[20~"
+string F10 = "\033[21~"
+string F11 = "\033[23~"
+string F12 = "\033[24~"
+string F13 = "\033[25~"
+string F14 = "\033[26~"
+string F15 = "\033[28~"
+string F16 = "\033[29~"
+string F17 = "\033[31~"
+string F18 = "\033[32~"
+string F19 = "\033[33~"
+string F20 = "\033[34~"
+string Find = "\033[1~"
+string Insert = "\033[2~"
+string Remove = "\033[3~"
+string Select = "\033[4~"
+string Prior = "\033[5~"
+string Next = "\033[6~"
+string Macro = "\033[M"
+string Pause = "\033[P"
+compose '`' 'A' to 'À'
+compose '`' 'a' to 'à'
+compose '\'' 'A' to 'Á'
+compose '\'' 'a' to 'á'
+compose '^' 'A' to 'Â'
+compose '^' 'a' to 'â'
+compose '~' 'A' to 'Ã'
+compose '~' 'a' to 'ã'
+compose '"' 'A' to 'Ä'
+compose '"' 'a' to 'ä'
+compose 'O' 'A' to 'Å'
+compose 'o' 'a' to 'å'
+compose '0' 'A' to 'Å'
+compose '0' 'a' to 'å'
+compose 'A' 'A' to 'Å'
+compose 'a' 'a' to 'å'
+compose 'A' 'E' to 'Æ'
+compose 'a' 'e' to 'æ'
+compose ',' 'C' to 'Ç'
+compose ',' 'c' to 'ç'
+compose '`' 'E' to 'È'
+compose '`' 'e' to 'è'
+compose '\'' 'E' to 'É'
+compose '\'' 'e' to 'é'
+compose '^' 'E' to 'Ê'
+compose '^' 'e' to 'ê'
+compose '"' 'E' to 'Ë'
+compose '"' 'e' to 'ë'
+compose '`' 'I' to 'Ì'
+compose '`' 'i' to 'ì'
+compose '\'' 'I' to 'Í'
+compose '\'' 'i' to 'í'
+compose '^' 'I' to 'Î'
+compose '^' 'i' to 'î'
+compose '"' 'I' to 'Ï'
+compose '"' 'i' to 'ï'
+compose '-' 'D' to 'Ð'
+compose '-' 'd' to 'ð'
+compose '~' 'N' to 'Ñ'
+compose '~' 'n' to 'ñ'
+compose '`' 'O' to 'Ò'
+compose '`' 'o' to 'ò'
+compose '\'' 'O' to 'Ó'
+compose '\'' 'o' to 'ó'
+compose '^' 'O' to 'Ô'
+compose '^' 'o' to 'ô'
+compose '~' 'O' to 'Õ'
+compose '~' 'o' to 'õ'
+compose '"' 'O' to 'Ö'
+compose '"' 'o' to 'ö'
+compose '/' 'O' to 'Ø'
+compose '/' 'o' to 'ø'
+compose '`' 'U' to 'Ù'
+compose '`' 'u' to 'ù'
+compose '\'' 'U' to 'Ú'
+compose '\'' 'u' to 'ú'
+compose '^' 'U' to 'Û'
+compose '^' 'u' to 'û'
+compose '"' 'U' to 'Ü'
+compose '"' 'u' to 'ü'
+compose '\'' 'Y' to 'Ý'
+compose '\'' 'y' to 'ý'
+compose 'T' 'H' to 'Þ'
+compose 't' 'h' to 'þ'
+compose 's' 's' to 'ß'
+compose '"' 'y' to 'ÿ'
+compose 's' 'z' to 'ß'
+compose 'i' 'j' to 'ÿ'
diff --git a/scripts/install.sh b/scripts/install.sh
index 1efbaad02..dd541c396 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -148,7 +148,7 @@ tgt=$2
src=$3
case $target {
-(atmel-ngw100|banana-pro|banana-pro-zero|orange-pi0|pcengines-apu|phytec-imx6|phytec-wega|raspberry-pi|raspberry-pi0|raspberry-pi2|raspberry-pi3|raspberry-pi3-64|raspberry-pi4|raspberry-pi4-64|raspberry-pi5|rockpi4-plus|solidrun-imx6|solidrun-clearfog|imgtec-ci20|default) ;;
+(atmel-ngw100|banana-pro|banana-pro-zero|orange-pi0|pcengines-apu|phytec-imx6|phytec-wega|raspberry-pi|raspberry-pi0|raspberry-pi2|raspberry-pi3|raspberry-pi3-64|raspberry-pi4|raspberry-pi4-64|raspberry-pi5|rockpi4-plus|solidrun-imx6|solidrun-clearfog|imgtec-ci20|hp-jornada|default) ;;
(*)
print -u2 "Unknown target '$target', exiting"
exit 1 ;;
diff --git a/target/config/Config.in.runtime b/target/config/Config.in.runtime
index e1a5600f6..4f2b135c0 100644
--- a/target/config/Config.in.runtime
+++ b/target/config/Config.in.runtime
@@ -314,6 +314,7 @@ config ADK_RUNTIME_GETTY_VGA
default y if ADK_TARGET_SYSTEM_SOLIDRUN_IMX6
default y if ADK_TARGET_SYSTEM_LEMOTE_YEELONG
default y if ADK_TARGET_SYSTEM_ARANYM_M68K
+ default y if ADK_TARGET_SYSTEM_HP_JORNADA
default y if ADK_TARGET_MODEL_PCENGINES_ALIX1C
default n
help
@@ -367,6 +368,7 @@ config ADK_RUNTIME_CONSOLE_SERIAL_DEVICE
|| ADK_TARGET_SYSTEM_QEMU_AARCH64
default "ttyARC0" if ADK_TARGET_SYSTEM_SYNOPSYS_NSIM && ADK_TARGET_CPU_ARC_ARC700
default "ttySC1" if ADK_TARGET_SYSTEM_QEMU_SH
+ default "ttySC1" if ADK_TARGET_SYSTEM_HP_JORNADA
default "ttySC0" if ADK_TARGET_SYSTEM_SIM_H8300H
default "ttySC2" if ADK_TARGET_SYSTEM_HITACHI_EDOSK2674
default "ttySIF0" if ADK_TARGET_SYSTEM_SIPEED_MAIX_BIT
diff --git a/target/config/Config.in.subsystem b/target/config/Config.in.subsystem
index ce43f391c..1a8c46348 100644
--- a/target/config/Config.in.subsystem
+++ b/target/config/Config.in.subsystem
@@ -2,6 +2,18 @@
# material, please see the LICENCE file in the top-level directory.
choice
+prompt "HP Jornada model"
+depends on ADK_TARGET_SYSTEM_HP_JORNADA
+
+config ADK_TARGET_MODEL_HP_JORNADA_690
+ bool "HP Jornada 690"
+
+config ADK_TARGET_MODEL_HP_JORNADA_680
+ bool "HP Jornada 680"
+
+endchoice
+
+choice
prompt "PCengines ALIX model"
depends on ADK_TARGET_SYSTEM_PCENGINES_ALIX
diff --git a/target/linux/Config.in b/target/linux/Config.in
index fb9d1810e..3709af90e 100644
--- a/target/linux/Config.in
+++ b/target/linux/Config.in
@@ -29,3 +29,4 @@ source target/linux/config/Config.in.kvm
source target/linux/config/Config.in.virtio
source target/linux/config/Config.in.debug
source target/linux/config/Config.in.compat
+source target/linux/config/Config.in.hpjornada
diff --git a/target/linux/Config.in.kernelcfg b/target/linux/Config.in.kernelcfg
index 0fed13df7..d848147fc 100644
--- a/target/linux/Config.in.kernelcfg
+++ b/target/linux/Config.in.kernelcfg
@@ -73,6 +73,7 @@ config ADK_TARGET_LINUX_KERNEL_DEFCONFIG
default "ci20_defconfig" if ADK_TARGET_SYSTEM_IMGTEC_CI20
default "lemote2f_defconfig" if ADK_TARGET_SYSTEM_LEMOTE_FULOONG
default "etraxfs_defconfig" if ADK_TARGET_SYSTEM_AXIS_89_DEVICE_SERVER
+ default "hp6xx_defconfig" if ADK_TARGET_SYSTEM_HP_JORNADA
default ""
config ADK_TARGET_LINUX_KERNEL_CUSTOMCONFIG_PATH
diff --git a/target/linux/config/Config.in.hpjornada b/target/linux/config/Config.in.hpjornada
new file mode 100644
index 000000000..fc46c316f
--- /dev/null
+++ b/target/linux/config/Config.in.hpjornada
@@ -0,0 +1,12 @@
+# This file is part of the OpenADK project. OpenADK is copyrighted
+# material, please see the LICENCE file in the top-level directory.
+
+config ADK_LINUX_KERNEL_MEMORY_SIZE
+ hex
+ default "0x2000000"
+ depends on ADK_TARGET_MODEL_HP_JORNADA_690
+
+config ADK_LINUX_KERNEL_MEMORY_SIZE
+ hex
+ default "0x1000000"
+ depends on ADK_TARGET_MODEL_HP_JORNADA_680
diff --git a/target/linux/patches/6.15.6/0001-pcmcia-Add-Hitachi-HD6446x-PCMCIA-socket-support.patch b/target/linux/patches/6.15.6/0001-pcmcia-Add-Hitachi-HD6446x-PCMCIA-socket-support.patch
new file mode 100644
index 000000000..5c46fe5e4
--- /dev/null
+++ b/target/linux/patches/6.15.6/0001-pcmcia-Add-Hitachi-HD6446x-PCMCIA-socket-support.patch
@@ -0,0 +1,720 @@
+From b6ffbcb525539139a9b2255b992622f92757ea37 Mon Sep 17 00:00:00 2001
+From: Artur Rojek <contact@artur-rojek.eu>
+Date: Fri, 1 Aug 2025 22:52:22 +0200
+Subject: [PATCH] pcmcia: Add Hitachi HD6446x PCMCIA socket support
+
+Introduce support for the PC Card Controller part of the Hitachi HD6446x
+series of Intelligent Peripheral Controllers.
+
+WIP code. DO NOT UPSTREAM!
+---
+ arch/sh/boards/mach-hp6xx/setup.c | 45 ++-
+ arch/sh/cchips/hd6446x/hd64461.c | 56 +++-
+ arch/sh/include/asm/hd64461.h | 6 +-
+ drivers/pcmcia/Kconfig | 7 +
+ drivers/pcmcia/Makefile | 1 +
+ drivers/pcmcia/hd6446x_pcc.c | 453 ++++++++++++++++++++++++++++++
+ include/pcmcia/hd6446x_pcc.h | 9 +
+ 7 files changed, 569 insertions(+), 8 deletions(-)
+ create mode 100644 drivers/pcmcia/hd6446x_pcc.c
+ create mode 100644 include/pcmcia/hd6446x_pcc.h
+
+diff --git a/arch/sh/boards/mach-hp6xx/setup.c b/arch/sh/boards/mach-hp6xx/setup.c
+index 2ceead68d7bf..c697b8e1f5ac 100644
+--- a/arch/sh/boards/mach-hp6xx/setup.c
++++ b/arch/sh/boards/mach-hp6xx/setup.c
+@@ -18,19 +18,23 @@
+ #include <mach/hp6xx.h>
+ #include <cpu/dac.h>
+
++#include <pcmcia/hd6446x_pcc.h>
++
+ #define SCPCR 0xa4000116
+ #define SCPDR 0xa4000136
+
++#define CF_MEM_ATTR (0x15000000 - 0)
++
+ /* CF Slot */
+ static struct resource cf_ide_resources[] = {
+ [0] = {
+- .start = 0x15000000 + 0x1f0,
+- .end = 0x15000000 + 0x1f0 + 0x08 - 0x01,
++ .start = CF_MEM_ATTR + 0x1f0,
++ .end = CF_MEM_ATTR + 0x1f0 + 0x08 - 0x01,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+- .start = 0x15000000 + 0x1fe,
+- .end = 0x15000000 + 0x1fe + 0x01,
++ .start = CF_MEM_ATTR + 0x1fe,
++ .end = CF_MEM_ATTR + 0x1fe + 0x01,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+@@ -51,6 +55,36 @@ static struct platform_device jornadakbd_device = {
+ .id = -1,
+ };
+
++static struct resource hd6446x_pcc_resources[] = {
++ [0] = {
++ .start = HD64461_PCC0ISR,
++ .end = HD64461_PCC0ISR + 0x10,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = HD64461_PCC0_BASE,
++ .end = HD64461_PCC0_BASE + 0x4000000,
++ .flags = IORESOURCE_MEM,
++ },
++ [2] = {
++ .start = HD64461_IRQ_PCC0,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct hd6446x_pcc_plat_data hd6446x_pcc_platform_data = {
++ .slot_id = 1,
++ .io_support = true,
++};
++
++static struct platform_device hp6446x_pcc_device = {
++ .name = "hd6446x_pcc",
++ .id = -1,
++ .num_resources = ARRAY_SIZE(hd6446x_pcc_resources),
++ .resource = hd6446x_pcc_resources,
++ .dev.platform_data = &hd6446x_pcc_platform_data,
++};
++
+ static void dac_audio_start(struct dac_audio_pdata *pdata)
+ {
+ u16 v;
+@@ -108,6 +142,7 @@ static struct platform_device *hp6xx_devices[] __initdata = {
+ &cf_ide_device,
+ &jornadakbd_device,
+ &dac_audio_device,
++ &hp6446x_pcc_device,
+ };
+
+ static void __init hp6xx_init_irq(void)
+@@ -126,6 +161,8 @@ static void __init hp6xx_setup(char **cmdline_p)
+ u8 v8;
+ u16 v;
+
++ __set_io_port_base(0);
++
+ v = inw(HD64461_STBCR);
+ v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST |
+ HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST |
+diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c
+index 81764882d87d..965486584ee5 100644
+--- a/arch/sh/cchips/hd6446x/hd64461.c
++++ b/arch/sh/cchips/hd6446x/hd64461.c
+@@ -4,7 +4,9 @@
+ * Hitachi HD64461 companion chip support
+ */
+
++#include <linux/clkdev.h>
+ #include <linux/sched.h>
++#include <linux/sh_clk.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/param.h>
+@@ -45,7 +47,7 @@ static void hd64461_mask_and_ack_irq(struct irq_data *data)
+ hd64461_mask_irq(data);
+
+ #ifdef CONFIG_HD64461_ENABLER
+- if (data->irq == HD64461_IRQBASE + 13)
++ if (data->irq == HD64461_IRQ_PCC1)
+ __raw_writeb(0x00, HD64461_PCC1CSCR);
+ #endif
+ }
+@@ -72,6 +74,51 @@ static void hd64461_irq_demux(struct irq_desc *desc)
+ }
+ }
+
++static int hd64461_clk_enable(struct clk *clk)
++{
++ u16 reg = __raw_readw(HD64461_STBCR);
++
++ printk("clk enable: %d\n", clk->enable_bit);
++
++ __raw_writew(reg & ~(1 << clk->enable_bit), HD64461_STBCR);
++
++ return 0;
++}
++
++static void hd64461_clk_disable(struct clk *clk)
++{
++ u16 reg = __raw_readw(HD64461_STBCR);
++
++ printk("clk disable: %d\n", clk->enable_bit);
++ //panic("clk disable: %d\n", clk->enable_bit);
++
++
++ __raw_writew(reg | (1 << clk->enable_bit), HD64461_STBCR);
++}
++
++static struct sh_clk_ops hd64461_clk_ops = {
++ .enable = hd64461_clk_enable,
++ .disable = hd64461_clk_disable,
++};
++
++static struct clk hd64461_clk[] = {
++ {
++ .enable_bit = 5,
++ .ops = &hd64461_clk_ops,
++ .flags = CLK_ENABLE_ON_INIT,
++ },
++ {
++ .enable_bit = 6,
++ .ops = &hd64461_clk_ops,
++ .flags = CLK_ENABLE_ON_INIT,
++ },
++};
++
++static struct clk_lookup hd64461_clk_lookup[] = {
++ CLKDEV_CON_ID("pcc1", &hd64461_clk[0]),
++ CLKDEV_CON_ID("pcc0", &hd64461_clk[1]),
++};
++
+ static int __init setup_hd64461(void)
+ {
+ int irq_base, i;
+@@ -106,6 +153,13 @@ static int __init setup_hd64461(void)
+ __raw_writeb(0x00, HD64461_PCC1CSCR);
+ #endif
+
++// for (i = 0; i < ARRAY_SIZE(hd64461_clk); i++)
++// clk_register(&hd64461_clk[i]);
++ clk_register(&hd64461_clk[1]);
++ clkdev_add_table(hd64461_clk_lookup, ARRAY_SIZE(hd64461_clk_lookup));
++
++ printk("done with clk setup\n");
++
+ return 0;
+ }
+
+diff --git a/arch/sh/include/asm/hd64461.h b/arch/sh/include/asm/hd64461.h
+index d2c485fa333b..91823ec07f79 100644
+--- a/arch/sh/include/asm/hd64461.h
++++ b/arch/sh/include/asm/hd64461.h
+@@ -17,9 +17,9 @@
+ #define HD64461_IOBASE 0xb0000000
+ #define HD64461_IO_OFFSET(x) (HD64461_IOBASE + (x))
+ #define HD64461_PCC0_BASE HD64461_IO_OFFSET(0x8000000)
+-#define HD64461_PCC0_ATTR (HD64461_PCC0_BASE) /* 0xb80000000 */
+-#define HD64461_PCC0_COMM (HD64461_PCC0_BASE+HD64461_PCC_WINDOW) /* 0xb90000000 */
+-#define HD64461_PCC0_IO (HD64461_PCC0_BASE+2*HD64461_PCC_WINDOW) /* 0xba0000000 */
++#define HD64461_PCC0_ATTR (HD64461_PCC0_BASE) /* 0xb8000000 */
++#define HD64461_PCC0_COMM (HD64461_PCC0_BASE+HD64461_PCC_WINDOW) /* 0xb9000000 */
++#define HD64461_PCC0_IO (HD64461_PCC0_BASE+2*HD64461_PCC_WINDOW) /* 0xba000000 */
+
+ /* Area 5 - Slot 1 - memory card only */
+ #define HD64461_PCC1_BASE HD64461_IO_OFFSET(0x4000000)
+diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
+index dddb235dd020..f2434ca15c8e 100644
+--- a/drivers/pcmcia/Kconfig
++++ b/drivers/pcmcia/Kconfig
+@@ -159,6 +159,13 @@ config PCMCIA_ALCHEMY_DEVBOARD
+
+ This driver is also available as a module called db1xxx_ss.ko
+
++config PCMCIA_HD6446X_PCC
++ tristate "Hitachi HD6446x PCMCIA socket support"
++ depends on PCMCIA && HD6446X_SERIES
++ help
++ Say Y here to include support for the PC Card Controller part of
++ the Hitachi HD6446x series of Intelligent Peripheral Controllers.
++
+ config PCMCIA_XXS1500
+ tristate "MyCable XXS1500 PCMCIA socket support"
+ depends on PCMCIA && MIPS_XXS1500
+diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
+index c9d51b150682..764df19be544 100644
+--- a/drivers/pcmcia/Makefile
++++ b/drivers/pcmcia/Makefile
+@@ -33,6 +33,7 @@ obj-$(CONFIG_OMAP_CF) += omap_cf.o
+ obj-$(CONFIG_ELECTRA_CF) += electra_cf.o
+ obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o
+ obj-$(CONFIG_PCMCIA_MAX1600) += max1600.o
++obj-$(CONFIG_PCMCIA_HD6446X_PCC) += hd6446x_pcc.o
+
+ sa1111_cs-y += sa1111_generic.o
+ sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1111_neponset.o
+diff --git a/drivers/pcmcia/hd6446x_pcc.c b/drivers/pcmcia/hd6446x_pcc.c
+new file mode 100644
+index 000000000000..31074f93b55b
+--- /dev/null
++++ b/drivers/pcmcia/hd6446x_pcc.c
+@@ -0,0 +1,453 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * PC Card Controller driver for the Hitachi HD6446x series of Intelligent
++ * Peripheral Controllers.
++ *
++ * Copyright (c) 2023 - 2024 Artur Rojek <contact@artur-rojek.eu>
++ */
++
++#include <linux/clk.h>
++#include <linux/interrupt.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <pcmcia/hd6446x_pcc.h>
++#include <pcmcia/ss.h>
++#include <asm/hd64461.h>
++
++#include "mach-common/mach/hp6xx.h"
++
++#define HD6446X_PCC_ISR 0x00
++#define HD6446X_PCC_GCR 0x02
++#define HD6446X_PCC_CSCR 0x04
++#define HD6446X_PCC_CSCIER 0x06
++#define HD6446X_PCC_SCR 0x08
++
++#define HD6446X_PCC_ISR_CD (BIT(2) | BIT(3))
++#define HD6446X_PCC_ISR_VS1 BIT(4)
++#define HD6446X_PCC_ISR_VS2 BIT(5)
++#define HD6446X_PCC_ISR_MWP BIT(6)
++#define HD6446X_PCC_ISR_READY BIT(7)
++
++#define HD6446X_PCC_GCR_PMMOD BIT(3)
++#define HD6446X_PCC_GCR_VCC0 BIT(4)
++#define HD6446X_PCC_GCR_PCCT BIT(5)
++#define HD6446X_PCC_GCR_PCCR BIT(6)
++#define HD6446X_PCC_GCR_DRV BIT(7)
++
++#define HD6446X_PCC_CSCR_BD BIT(0)
++#define HD6446X_PCC_CSCR_BW BIT(1)
++#define HD6446X_PCC_CSCR_RC BIT(2)
++#define HD6446X_PCC_CSCR_CDC BIT(3)
++#define HD6446X_PCC_CSCR_SC BIT(4)
++#define HD6446X_PCC_CSCR_IREQ BIT(5)
++#define HD6446X_PCC_CSCR_SCDI BIT(7)
++
++#define HD6446X_PCC_CSCIER_BDE BIT(0)
++#define HD6446X_PCC_CSCIER_BWE BIT(1)
++#define HD6446X_PCC_CSCIER_RE BIT(2)
++#define HD6446X_PCC_CSCIER_CDE BIT(3)
++#define HD6446X_PCC_CSCIER_SCE BIT(4)
++#define HD6446X_PCC_CSCIER_IREQE_FALLING BIT(6)
++
++#define HD6446X_PCC_SCR_VCC1 BIT(1)
++
++#define HD6446X_PCC_WINDOW 0x1000000 /* 16 MiB */
++
++struct hd6446x_pcc {
++ const struct hd6446x_pcc_plat_data *pdata;
++ void __iomem *reg;
++ void __iomem *base;
++ struct clk *clk;
++ struct pcmcia_socket socket;
++ struct socket_state_t state;
++ bool memory_card;
++};
++
++static int hd64461_pcmcia_socket_set_voltage(struct hd6446x_pcc *pcc, int Vcc)
++{
++ int gcr, scr, stbcr;
++
++ gcr = readb(pcc->reg + HD6446X_PCC_GCR);
++ scr = readb(pcc->reg + HD6446X_PCC_SCR);
++
++ switch (Vcc) {
++ case 0:
++ gcr |= HD6446X_PCC_GCR_VCC0;
++ scr |= HD6446X_PCC_SCR_VCC1;
++ break;
++ case 33:
++ gcr |= HD6446X_PCC_GCR_VCC0;
++ scr &= ~HD6446X_PCC_SCR_VCC1;
++ break;
++ case 50:
++ gcr &= ~HD6446X_PCC_GCR_VCC0;
++ scr &= ~HD6446X_PCC_SCR_VCC1;
++ break;
++ default:
++ printk("Unsupported voltage: %d\n", Vcc);
++ return -EINVAL;
++ }
++
++ writeb(gcr, pcc->reg + HD6446X_PCC_GCR);
++ writeb(scr, pcc->reg + HD6446X_PCC_SCR);
++
++// stbcr = readw(HD64461_STBCR);
++
++ if (Vcc > 0)
++ clk_enable(pcc->clk);
++// stbcr &= ~HD64461_STBCR_SPC0ST;
++ else
++ clk_disable(pcc->clk);
++// stbcr |= HD64461_STBCR_SPC0ST;
++
++// writew(stbcr, HD64461_STBCR);
++
++ return 0;
++}
++
++static int hd64461_pcmcia_socket_init(struct pcmcia_socket *sock)
++{
++ struct hd6446x_pcc *pcc = sock->driver_data;
++ int reg;
++
++ printk("socket_init\n");
++
++// printk("init BCR1: %04x\n", readw(0xffffff60));
++
++ (void)hd64461_pcmcia_socket_set_voltage(pcc, 0);
++
++ reg = readb(HD64461_GPADR);
++ reg &= ~HD64461_GPADR_PCMCIA0;
++ writeb(reg, HD64461_GPADR);
++
++ return 0;
++}
++
++static int hd64461_pcmcia_socket_get_status(struct pcmcia_socket *sock,
++ unsigned int *value)
++{
++// struct hd64461_pcmcia_socket *socket = sock->driver_data;
++ struct hd6446x_pcc *pcc = sock->driver_data;
++ unsigned int status = 0;
++ int reg;
++
++ printk("get_status\n");
++
++ reg = readb(pcc->reg + HD6446X_PCC_ISR);
++
++// printk("PCC0ISR: %02x\n", reg);
++
++ if (reg & HD6446X_PCC_ISR_CD)
++ goto end; /* No card detected. */
++ status |= SS_DETECT;
++
++ if (pcc->memory_card) {
++ if (reg & HD6446X_PCC_ISR_READY)
++ status |= SS_READY;
++
++ if (reg & HD6446X_PCC_ISR_MWP)
++ status |= SS_WRPROT;
++ } else
++ status |= SS_STSCHG;
++
++ if (!(reg & HD6446X_PCC_ISR_VS1)) {
++ status |= SS_3VCARD;
++ printk("3v3 card\n");
++ }
++
++ if (!(reg & HD6446X_PCC_ISR_VS2)) {
++ status |= SS_XVCARD;
++ printk("X.Xv card\n");
++ }
++
++ if (pcc->state.Vcc || pcc->state.Vpp)
++ status |= SS_POWERON;
++
++end:
++ *value = status;
++// printk("status: %x, memory: %d\n", status, socket->memory_card);
++
++ return 0;
++}
++
++static int hd64461_pcmcia_socket_configure(struct pcmcia_socket *sock,
++ struct socket_state_t *state)
++{
++// struct hd64461_pcmcia_socket *socket = sock->driver_data;
++ struct hd6446x_pcc *pcc = sock->driver_data;
++ int reg = 0;
++// unsigned long flags;
++
++ writeb(0x0, pcc->reg + HD6446X_PCC_CSCIER);
++
++// local_irq_save(flags);
++
++// printk("socket_configure, flags: %x, csc_mask: %x, Vcc: %d, Vpp: %d, io_irq: %x\n",
++// state->flags, state->csc_mask, state->Vcc, state->Vpp, state->io_irq);
++
++ if (state->Vcc != pcc->state.Vcc || state->Vpp != pcc->state.Vpp)
++ if (hd64461_pcmcia_socket_set_voltage(pcc, state->Vcc)) {
++// local_irq_restore(flags);
++ return -EINVAL;
++ }
++
++ //reg = readb(HD64461_PCC0CSCIER) & HD64461_PCCCSCIER_IREQE_MASK;
++ reg = HD6446X_PCC_CSCIER_IREQE_FALLING;
++// reg = 0;
++
++ if (state->csc_mask & SS_DETECT)
++ reg |= HD6446X_PCC_CSCIER_CDE;
++ if (state->csc_mask & SS_READY)
++ reg |= HD6446X_PCC_CSCIER_RE;
++ if (state->csc_mask & SS_BATDEAD)
++ reg |= HD6446X_PCC_CSCIER_BDE;
++ if (state->csc_mask & SS_BATWARN)
++ reg |= HD6446X_PCC_CSCIER_BWE;
++ if (state->csc_mask & SS_STSCHG)
++ reg |= HD6446X_PCC_CSCIER_SCE;
++// if (state->flags & SS_IOCARD)
++// reg = HD64461_PCCCSCIER_IREQE_FALLING;
++
++
++ writeb(reg, pcc->reg + HD6446X_PCC_CSCIER);
++
++// reg = readb(HD64461_PCC0GCR);
++// reg = 0;
++// reg = HD6446X_PCC_GCR_PMMOD;
++ reg = readb(pcc->reg + HD6446X_PCC_GCR) & ~(HD6446X_PCC_GCR_PCCT |
++ HD6446X_PCC_GCR_PCCR |
++ HD6446X_PCC_GCR_DRV);
++
++ pcc->memory_card = !(state->flags & SS_IOCARD);
++ if (!pcc->memory_card)
++ reg |= HD6446X_PCC_GCR_PCCT;
++ if (state->flags & SS_RESET)
++ reg |= HD6446X_PCC_GCR_PCCR;
++ if (state->flags & SS_OUTPUT_ENA)
++ reg |= HD6446X_PCC_GCR_DRV;
++
++#if 0
++ if (socket->memory_card)
++ reg &= ~HD64461_PCCGCR_PCCT;
++ else
++ reg |= HD64461_PCCGCR_PCCT;
++ if (state->flags & SS_RESET)
++ reg |= HD64461_PCCGCR_PCCR;
++ else
++ reg &= ~HD64461_PCCGCR_PCCR;
++ if (state->flags & SS_OUTPUT_ENA)
++ reg |= HD64461_PCCGCR_DRVE;
++ else
++ reg &= ~HD64461_PCCGCR_DRVE;
++#endif
++
++ writeb(reg, pcc->reg + HD6446X_PCC_GCR);
++
++ pcc->state = *state;
++
++// local_irq_restore(flags);
++
++// printk("Configured: %x\n", state->flags);
++// printk("config BCR1: %04x\n", readw(0xffffff60));
++
++ return 0;
++}
++
++static int hd6446x_pcc_set_io_map(struct pcmcia_socket *socket,
++ struct pccard_io_map *io)
++{
++ /* We use a static map. */
++ printk("hd6446x_pcc_set_io_map\n");
++ return 0;
++}
++
++static int hd64461_pcmcia_socket_set_mem_map(struct pcmcia_socket *sock,
++ struct pccard_mem_map *map)
++{
++ struct hd6446x_pcc *pcc = sock->driver_data;
++// printk("set_mem_map\n");
++
++ if (map->map >= MAX_WIN)
++ return -EINVAL;
++
++ map->static_start = (uintptr_t)pcc->base + map->card_start;
++// map->static_start = HD64461_PCC0_BASE + map->card_start;
++// map->static_start = 0x8000000 + map->card_start;
++
++// printk("map->flags %d: %x\n", map->map, map->flags);
++
++ if (!(map->flags & MAP_ATTRIB))
++ map->static_start += HD6446X_PCC_WINDOW;
++
++ return 0;
++}
++
++static struct pccard_operations hd64461_pcmcia_socket_ops = {
++ .init = hd64461_pcmcia_socket_init,
++ .get_status = hd64461_pcmcia_socket_get_status,
++ .set_socket = hd64461_pcmcia_socket_configure,
++ .set_io_map = hd6446x_pcc_set_io_map,
++ .set_mem_map = hd64461_pcmcia_socket_set_mem_map,
++};
++
++static irqreturn_t hd64461_pcmcia_socket_irq(int irq, void *data)
++{
++ struct hd6446x_pcc *pcc = data;
++ int reg = readb(pcc->reg + HD6446X_PCC_CSCR) & ~HD6446X_PCC_CSCR_SCDI;
++ unsigned int events = 0;
++
++ if (reg & HD6446X_PCC_CSCR_IREQ) {
++ reg &= ~HD6446X_PCC_CSCR_IREQ;
++ writeb(reg, pcc->reg + HD6446X_PCC_CSCR);
++
++ return IRQ_NONE;
++ }
++
++ if (reg & HD6446X_PCC_CSCR_CDC) {
++ reg &= ~HD6446X_PCC_CSCR_CDC;
++ events |= SS_DETECT;
++
++ /* Card has been ejected. */
++ if (readb(pcc->reg + HD6446X_PCC_ISR) & HD6446X_PCC_ISR_CD)
++ reg &= ~(HD6446X_PCC_CSCR_RC | HD6446X_PCC_CSCR_BW |
++ HD6446X_PCC_CSCR_BD | HD6446X_PCC_CSCR_SC);
++ }
++
++ if (pcc->memory_card) {
++ if (reg & HD6446X_PCC_CSCR_RC) {
++ reg &= ~HD6446X_PCC_CSCR_RC;
++ events |= SS_READY;
++ }
++
++ if (reg & HD6446X_PCC_CSCR_BW) {
++ reg &= ~HD6446X_PCC_CSCR_BW;
++ events |= SS_BATWARN;
++ }
++
++ if (reg & HD6446X_PCC_CSCR_BD) {
++ reg &= ~HD6446X_PCC_CSCR_BD;
++ events |= SS_BATDEAD;
++ }
++ } else if (reg & HD6446X_PCC_CSCR_SC) {
++ reg &= ~HD6446X_PCC_CSCR_SC;
++ events |= SS_STSCHG;
++ }
++
++ writeb(reg, pcc->reg + HD6446X_PCC_CSCR);
++
++ if (events)
++ pcmcia_parse_events(&pcc->socket, events);
++
++// writeb(reg, HD64461_PCC0CSCR);
++
++ return IRQ_HANDLED;
++}
++
++static int hd64461_pcmcia_socket_probe(struct platform_device *pdev)
++{
++ struct hd6446x_pcc *pcc;
++ struct device *dev = &pdev->dev;
++ struct pcmcia_socket *sock;
++ int irq;
++ int reg, re