diff --git a/device/testing/device-clockworkpi-uconsole-cm4/95-vchiq-permissions.rules b/device/testing/device-clockworkpi-uconsole-cm4/95-vchiq-permissions.rules new file mode 100644 index 000000000..1237f5fed --- /dev/null +++ b/device/testing/device-clockworkpi-uconsole-cm4/95-vchiq-permissions.rules @@ -0,0 +1 @@ +SUBSYSTEM=="vchiq", GROUP="video", MODE="0660" diff --git a/device/testing/device-clockworkpi-uconsole-cm4/APKBUILD b/device/testing/device-clockworkpi-uconsole-cm4/APKBUILD new file mode 100644 index 000000000..9f6fe3763 --- /dev/null +++ b/device/testing/device-clockworkpi-uconsole-cm4/APKBUILD @@ -0,0 +1,48 @@ +# Reference: +# Maintainer: Federico Amedeo Izzo +pkgname=device-clockworkpi-uconsole-cm4 +pkgdesc="Clockwork Tech ClockworkPi uConsole CM4" +pkgver=1 +pkgrel=0 +url="https://postmarketos.org" +license="MIT" +arch="aarch64" +options="!check !archcheck" +depends=" + linux-clockworkpi-uconsole-cm4 + postmarketos-base + raspberrypi-bootloader +" +makedepends="devicepkg-dev" +install="$pkgname.post-install $pkgname.post-upgrade" +subpackages="$pkgname-nonfree-firmware:nonfree_firmware" +source=" + deviceinfo + modules-initfs + usercfg.txt + 95-vchiq-permissions.rules +" + +build() { + devicepkg_build $startdir $pkgname +} + +package() { + devicepkg_package $startdir $pkgname + install -Dm644 "$srcdir"/usercfg.txt "$pkgdir"/boot/usercfg.txt + install -Dm644 "$srcdir"/95-vchiq-permissions.rules \ + "$pkgdir"/usr/lib/udev/rules.d/95-vchiq-permissions.rules +} + +nonfree_firmware() { + pkgdesc="WiFi/Bluetooth firmware" + depends="linux-firmware-brcm" + mkdir "$subpkgdir" +} + +sha512sums=" +8239d117839d3e3603c7ab73e598059bb521b81aeec5d6f7d0ec68d00cb9912bbad9fe5a0741e41e7ec94250729042dce91a6efb412c4e30c43a9c0b0a81a5b5 deviceinfo +bc630857d9b0b6a89b3d9ff794be1133f5d7a681f26cd826ea4315649f8bf6c0c24aafa220093cbb313aa8bd6d46d2621c7aacb62e445a2d60c87e50099b45a5 modules-initfs +43c2aca99ee3e02f4563bc27d331fa6e4e3c540732487c5806fd7574025cabc69347b74e2cea72f9c36fde8876833126063ca808a7398c5754dd53aecd6df7bf usercfg.txt +7e5505cb07d5b4a81bd28443d508336b5c547356538f1c06f91ed93ad0d7d456d4f74f1d24df5a2e08c17e74f0a66607352ac4874e967e9a91dfec9522d2d58d 95-vchiq-permissions.rules +" diff --git a/device/testing/device-clockworkpi-uconsole-cm4/device-clockworkpi-uconsole-cm4.post-install b/device/testing/device-clockworkpi-uconsole-cm4/device-clockworkpi-uconsole-cm4.post-install new file mode 100644 index 000000000..2fc9041fc --- /dev/null +++ b/device/testing/device-clockworkpi-uconsole-cm4/device-clockworkpi-uconsole-cm4.post-install @@ -0,0 +1,3 @@ +#!/bin/sh + +rc-update add swclock boot diff --git a/device/testing/device-clockworkpi-uconsole-cm4/device-clockworkpi-uconsole-cm4.post-upgrade b/device/testing/device-clockworkpi-uconsole-cm4/device-clockworkpi-uconsole-cm4.post-upgrade new file mode 100644 index 000000000..2fc9041fc --- /dev/null +++ b/device/testing/device-clockworkpi-uconsole-cm4/device-clockworkpi-uconsole-cm4.post-upgrade @@ -0,0 +1,3 @@ +#!/bin/sh + +rc-update add swclock boot diff --git a/device/testing/device-clockworkpi-uconsole-cm4/deviceinfo b/device/testing/device-clockworkpi-uconsole-cm4/deviceinfo new file mode 100644 index 000000000..598cf244a --- /dev/null +++ b/device/testing/device-clockworkpi-uconsole-cm4/deviceinfo @@ -0,0 +1,23 @@ +# Reference: +# Maintainer: Federico Amedeo Izzo +# Please use double quotes only. You can source this file in shell +# scripts. + +deviceinfo_format_version="0" +deviceinfo_name="Clockwork Tech ClockworkPi uConsole CM4" +deviceinfo_manufacturer="Clockwork Tech" +deviceinfo_codename="clockworkpi-uconsole-cm4" +deviceinfo_year="2023" +deviceinfo_arch="aarch64" +deviceinfo_disable_dhcpd="true" + +# Device related +deviceinfo_gpu_accelerated="true" +deviceinfo_chassis="embedded" +deviceinfo_keyboard="true" +deviceinfo_external_storage="true" +deviceinfo_mesa_driver="vc4" + +# Bootloader related +deviceinfo_flash_method="none" +deviceinfo_boot_filesystem="fat32" diff --git a/device/testing/device-clockworkpi-uconsole-cm4/modules-initfs b/device/testing/device-clockworkpi-uconsole-cm4/modules-initfs new file mode 100644 index 000000000..8eade702d --- /dev/null +++ b/device/testing/device-clockworkpi-uconsole-cm4/modules-initfs @@ -0,0 +1,3 @@ +vc4 +panel_clockwork_cwu50 +ocp8178_bl diff --git a/device/testing/device-clockworkpi-uconsole-cm4/usercfg.txt b/device/testing/device-clockworkpi-uconsole-cm4/usercfg.txt new file mode 100644 index 000000000..da6127c95 --- /dev/null +++ b/device/testing/device-clockworkpi-uconsole-cm4/usercfg.txt @@ -0,0 +1,14 @@ +ignore_lcd=1 +disable_fw_kms_setup=1 +max_framebuffers=2 +arm_boost=1 + +# setup headphone detect pin +gpio=10=ip,np + +# overlays +dtoverlay=dwc2,dr_mode=host +dtoverlay=vc4-kms-v3d +dtoverlay=audremap,pins_12_13 +dtparam=audio=on +dtoverlay=uconsole diff --git a/device/testing/linux-clockworkpi-uconsole-cm4/0001-video-backlight-Add-OCP8178-backlight-driver.patch b/device/testing/linux-clockworkpi-uconsole-cm4/0001-video-backlight-Add-OCP8178-backlight-driver.patch new file mode 100644 index 000000000..a55f3a245 --- /dev/null +++ b/device/testing/linux-clockworkpi-uconsole-cm4/0001-video-backlight-Add-OCP8178-backlight-driver.patch @@ -0,0 +1,295 @@ +From c541b4c80043848ff19e4906ecfc49c6f6818198 Mon Sep 17 00:00:00 2001 +From: Potato +Date: Mon, 2 Oct 2023 15:14:09 +0800 +Subject: [PATCH 1/6] video: backlight: Add OCP8178 backlight driver + +This driver is taken from +https://github.com/clockworkpi/DevTerm/blob/main/Code/patch/armbian_build_a06/patch/kernel-005-backlight.patch +and optimized for v6.5. +--- + drivers/video/backlight/Kconfig | 6 + + drivers/video/backlight/Makefile | 1 + + drivers/video/backlight/ocp8178_bl.c | 245 +++++++++++++++++++++++++++ + 3 files changed, 252 insertions(+) + create mode 100644 drivers/video/backlight/ocp8178_bl.c + +diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig +index 0e66152b02e6..efb66e7abb85 100644 +--- a/drivers/video/backlight/Kconfig ++++ b/drivers/video/backlight/Kconfig +@@ -484,6 +484,12 @@ config BACKLIGHT_LED + If you have a LCD backlight adjustable by LED class driver, say Y + to enable this driver. + ++config BACKLIGHT_OCP8178 ++ tristate "OCP8178 Backlight Driver" ++ depends on GPIOLIB || COMPILE_TEST ++ help ++ If you have an OCP8178, say Y to enable the backlight driver. ++ + endif # BACKLIGHT_CLASS_DEVICE + + endmenu +diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile +index ac878b4fb0ee..4d431321f1f2 100644 +--- a/drivers/video/backlight/Makefile ++++ b/drivers/video/backlight/Makefile +@@ -60,3 +60,4 @@ obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o + obj-$(CONFIG_BACKLIGHT_ARCXCNN) += arcxcnn_bl.o + obj-$(CONFIG_BACKLIGHT_RAVE_SP) += rave-sp-backlight.o + obj-$(CONFIG_BACKLIGHT_LED) += led_bl.o ++obj-$(CONFIG_BACKLIGHT_OCP8178) += ocp8178_bl.o +diff --git a/drivers/video/backlight/ocp8178_bl.c b/drivers/video/backlight/ocp8178_bl.c +new file mode 100644 +index 000000000000..2b0d1b159500 +--- /dev/null ++++ b/drivers/video/backlight/ocp8178_bl.c +@@ -0,0 +1,245 @@ ++/* ++ * ocp8178_bl.c - ocp8178 backlight driver ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct ocp8178_backlight { ++ struct device *dev; ++ struct device *fbdev; ++ ++ struct gpio_desc *gpiod; ++ int def_value; ++ int current_value; ++}; ++ ++#define DETECT_DELAY 200 ++#define DETECT_TIME 500 ++#define DETECT_WINDOW_TIME 1000 ++#define START_TIME 10 ++#define END_TIME 10 ++#define SHUTDOWN_TIME 3000 ++#define LOW_BIT_HIGH_TIME 10 ++#define LOW_BIT_LOW_TIME 50 ++#define HIGH_BIT_HIGH_TIME 50 ++#define HIGH_BIT_LOW_TIME 10 ++#define MAX_BRIGHTNESS_VALUE 9 ++ ++static void entry_1wire_mode(struct ocp8178_backlight *gbl) ++{ ++ unsigned long flags = 0; ++ local_irq_save(flags); ++ gpiod_set_value(gbl->gpiod, 0); ++ mdelay(SHUTDOWN_TIME/1000); ++ gpiod_set_value(gbl->gpiod, 1); ++ udelay(DETECT_DELAY); ++ gpiod_set_value(gbl->gpiod, 0); ++ udelay(DETECT_TIME); ++ gpiod_set_value(gbl->gpiod, 1); ++ udelay(DETECT_WINDOW_TIME); ++ local_irq_restore(flags); ++} ++ ++static inline void write_bit(struct ocp8178_backlight *gbl, int bit) ++{ ++ if (bit) { ++ gpiod_set_value(gbl->gpiod, 0); ++ udelay(HIGH_BIT_LOW_TIME); ++ gpiod_set_value(gbl->gpiod, 1); ++ udelay(HIGH_BIT_HIGH_TIME); ++ } else { ++ gpiod_set_value(gbl->gpiod, 0); ++ udelay(LOW_BIT_LOW_TIME); ++ gpiod_set_value(gbl->gpiod, 1); ++ udelay(LOW_BIT_HIGH_TIME); ++ } ++} ++ ++static void write_byte(struct ocp8178_backlight *gbl, int byte) ++{ ++ unsigned long flags = 0; ++ unsigned char data = 0x72; ++ int i; ++ ++ local_irq_save(flags); ++ ++ gpiod_set_value(gbl->gpiod, 1); ++ udelay(START_TIME); ++ for(i = 0; i < 8; i++) { ++ if(data & 0x80) { ++ write_bit(gbl, 1); ++ } else { ++ write_bit(gbl, 0); ++ } ++ data <<= 1; ++ } ++ gpiod_set_value(gbl->gpiod, 0); ++ udelay(END_TIME); ++ ++ data = byte & 0x1f; ++ ++ gpiod_set_value(gbl->gpiod, 1); ++ udelay(START_TIME); ++ for(i = 0; i < 8; i++) { ++ if(data & 0x80) { ++ write_bit(gbl, 1); ++ } else { ++ write_bit(gbl, 0); ++ } ++ data <<= 1; ++ } ++ gpiod_set_value(gbl->gpiod, 0); ++ udelay(END_TIME); ++ gpiod_set_value(gbl->gpiod, 1); ++ ++ local_irq_restore(flags); ++} ++ ++unsigned char ocp8178_bl_table[MAX_BRIGHTNESS_VALUE+1] = {0, 1, 4, 8, 12, 16, 20, 24, 28, 31}; ++ ++static int ocp8178_update_status(struct backlight_device *bl) ++{ ++ struct ocp8178_backlight *gbl = bl_get_data(bl); ++ int brightness = bl->props.brightness, i; ++ ++ if (bl->props.power != FB_BLANK_UNBLANK || ++ bl->props.fb_blank != FB_BLANK_UNBLANK || ++ bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) ++ brightness = 0; ++ ++ if(brightness > MAX_BRIGHTNESS_VALUE) ++ brightness = MAX_BRIGHTNESS_VALUE; ++ ++ for(i = 0; i < 2; i++) { ++ entry_1wire_mode(gbl); ++ write_byte(gbl, ocp8178_bl_table[brightness]); ++ } ++ gbl->current_value = brightness; ++ ++ return 0; ++} ++ ++static int ocp8178_get_brightness(struct backlight_device *bl) ++{ ++ struct ocp8178_backlight *gbl = bl_get_data(bl); ++ return gbl->current_value; ++} ++ ++static int ocp8178_check_fb(struct backlight_device *bl, ++ struct fb_info *info) ++{ ++ struct ocp8178_backlight *gbl = bl_get_data(bl); ++ return gbl->fbdev == NULL || gbl->fbdev == info->dev; ++} ++ ++static const struct backlight_ops ocp8178_backlight_ops = { ++ .options = BL_CORE_SUSPENDRESUME, ++ .update_status = ocp8178_update_status, ++ .get_brightness = ocp8178_get_brightness, ++ .check_fb = ocp8178_check_fb, ++}; ++ ++static int ocp8178_probe_dt(struct platform_device *pdev, ++ struct ocp8178_backlight *gbl) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *of_node = dev->of_node; ++ enum gpiod_flags flags; ++ int ret = 0; ++ u32 default_brightness; ++ ++ of_property_read_u32(of_node, "default-brightness", &default_brightness); ++ if(default_brightness > MAX_BRIGHTNESS_VALUE) ++ gbl->def_value = MAX_BRIGHTNESS_VALUE; ++ else ++ gbl->def_value = default_brightness; ++ flags = gbl->def_value ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; ++ ++ gbl->gpiod = devm_gpiod_get(dev, "backlight-control", flags); ++ if (IS_ERR(gbl->gpiod)) { ++ ret = PTR_ERR(gbl->gpiod); ++ return dev_err_probe(dev, ret, ++ "Error: The backlight-control-gpios parameter is missing or invalid.\n"); ++ } ++ ++ return ret; ++} ++ ++static int ocp8178_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct backlight_properties props; ++ struct backlight_device *bl; ++ struct ocp8178_backlight *gbl; ++ struct device_node *of_node = dev->of_node; ++ int ret; ++ ++ if (!of_node) { ++ dev_err(&pdev->dev, ++ "failed to find platform data or device tree node.\n"); ++ return -ENODEV; ++ } ++ ++ gbl = devm_kzalloc(dev, sizeof(*gbl), GFP_KERNEL); ++ if (gbl == NULL) ++ return -ENOMEM; ++ ++ gbl->dev = dev; ++ ++ ret = ocp8178_probe_dt(pdev, gbl); ++ if (ret) ++ return ret; ++ ++ gbl->current_value = gbl->def_value; ++ ++ memset(&props, 0, sizeof(props)); ++ props.type = BACKLIGHT_RAW; ++ props.max_brightness = MAX_BRIGHTNESS_VALUE; ++ bl = devm_backlight_device_register(&pdev->dev, dev_name(&pdev->dev), ++ &pdev->dev, gbl, &ocp8178_backlight_ops, ++ &props); ++ if (IS_ERR(bl)) { ++ dev_err(&pdev->dev, "failed to register backlight\n"); ++ return PTR_ERR(bl); ++ } ++ ++ bl->props.brightness = gbl->def_value; ++ backlight_update_status(bl); ++ ++ platform_set_drvdata(pdev, bl); ++ return 0; ++} ++ ++static struct of_device_id ocp8178_of_match[] = { ++ { .compatible = "ocp8178-backlight" }, ++ { /* sentinel */ } ++}; ++ ++MODULE_DEVICE_TABLE(of, ocp8178_of_match); ++ ++static struct platform_driver ocp8178_driver = { ++ .driver = { ++ .name = "ocp8178-backlight", ++ .of_match_table = of_match_ptr(ocp8178_of_match), ++ }, ++ .probe = ocp8178_probe, ++}; ++ ++module_platform_driver(ocp8178_driver); ++ ++MODULE_DESCRIPTION("OCP8178 Driver"); ++MODULE_LICENSE("GPL"); +-- +2.43.0 + diff --git a/device/testing/linux-clockworkpi-uconsole-cm4/0002-drm-panel-add-clockwork-cwu50.patch b/device/testing/linux-clockworkpi-uconsole-cm4/0002-drm-panel-add-clockwork-cwu50.patch new file mode 100644 index 000000000..dda8b3dc2 --- /dev/null +++ b/device/testing/linux-clockworkpi-uconsole-cm4/0002-drm-panel-add-clockwork-cwu50.patch @@ -0,0 +1,625 @@ +From aa593278d760e468f79e2c785a96b7b049653a2e Mon Sep 17 00:00:00 2001 +From: Potato +Date: Fri, 20 Oct 2023 23:18:19 +0800 +Subject: [PATCH 2/6] drm: panel: add clockwork cwu50 + +- set `power_off_case` to 2(other than 1) to enable power off by + DCS command +--- + drivers/gpu/drm/panel/Kconfig | 12 + + drivers/gpu/drm/panel/Makefile | 1 + + drivers/gpu/drm/panel/panel-clockwork-cwu50.c | 567 ++++++++++++++++++ + 3 files changed, 580 insertions(+) + create mode 100644 drivers/gpu/drm/panel/panel-clockwork-cwu50.c + +diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig +index 168403f59175..4a99ef1b0178 100644 +--- a/drivers/gpu/drm/panel/Kconfig ++++ b/drivers/gpu/drm/panel/Kconfig +@@ -68,6 +68,18 @@ config DRM_PANEL_BOE_TV101WUM_NL6 + Say Y here if you want to support for BOE TV101WUM and AUO KD101N80 + 45NA WUXGA PANEL DSI Video Mode panel + ++config DRM_PANEL_CLOCKWORK_CWU50 ++ tristate "Clockwork CWU50 panel" ++ depends on OF ++ depends on DRM_MIPI_DSI ++ depends on BACKLIGHT_CLASS_DEVICE ++ help ++ Say Y here if you want to enable support for the Clockwork CWU50 ++ JD9365D-based panel, e.g. as used within the Clockwork uConsole. ++ The panel has a 720x1280 resolution and uses 24 bit RGB per pixel. ++ ++ To compile this driver as a module, choose M here. ++ + config DRM_PANEL_DSI_CM + tristate "Generic DSI command mode panels" + depends on OF +diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile +index bc4ded65aa4b..25d9c19d9cd0 100644 +--- a/drivers/gpu/drm/panel/Makefile ++++ b/drivers/gpu/drm/panel/Makefile +@@ -5,6 +5,7 @@ obj-$(CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596) += panel-asus-z00t-tm5p5-n35596. + obj-$(CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0) += panel-boe-bf060y8m-aj0.o + obj-$(CONFIG_DRM_PANEL_BOE_HIMAX8279D) += panel-boe-himax8279d.o + obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6) += panel-boe-tv101wum-nl6.o ++obj-$(CONFIG_DRM_PANEL_CLOCKWORK_CWU50) += panel-clockwork-cwu50.o + obj-$(CONFIG_DRM_PANEL_DSI_CM) += panel-dsi-cm.o + obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o + obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o +diff --git a/drivers/gpu/drm/panel/panel-clockwork-cwu50.c b/drivers/gpu/drm/panel/panel-clockwork-cwu50.c +new file mode 100644 +index 000000000000..a814d6bb25dd +--- /dev/null ++++ b/drivers/gpu/drm/panel/panel-clockwork-cwu50.c +@@ -0,0 +1,567 @@ ++/* ++ * SPDX-License-Identifier: GPL-2.0+ ++ * Copyright (c) 2021 Clockwork Tech LLC ++ * Copyright (c) 2021 Max Fierke ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include