<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.dissonant.dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Uart</id>
	<title>dissonant.dev wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.dissonant.dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Uart"/>
	<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/wiki/Special:Contributions/Uart"/>
	<updated>2026-09-23T17:49:05Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/Adding_a_new_device&amp;diff=172</id>
		<title>Mainline:Broadcom Kona/Adding a new device</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/Adding_a_new_device&amp;diff=172"/>
		<updated>2026-08-23T19:56:09Z</updated>

		<summary type="html">&lt;p&gt;Uart: /* Getting the downstream kernel source */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page goes over the process of adding support for a Broadcom Kona device to the mainline Linux kernel.&lt;br /&gt;
&lt;br /&gt;
General outline of the process:&lt;br /&gt;
&lt;br /&gt;
* Get the downstream/vendor kernel source code&lt;br /&gt;
** Identify your device&#039;s board files&lt;br /&gt;
* Get the mainline kernel source code&lt;br /&gt;
* Add a DTS for your device based on values from downstream&lt;br /&gt;
* Build the kernel and flash it to the device&lt;br /&gt;
* Test it!&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In the mainline kernel, a device&#039;s components are described in a structure known as the [https://wiki.mainlining.org/wiki/Devicetree device tree] (or devicetree, as is the official spelling). Device trees are compiled into DTBs (device tree blobs) from DTS (device tree source) files.&lt;br /&gt;
&lt;br /&gt;
Adding support for a new device involves &#039;&#039;&#039;creating a DTS for that device&#039;&#039;&#039; - this is the process covered in this guide.&lt;br /&gt;
&lt;br /&gt;
Device trees appeared in the kernel around version 3.4, and didn&#039;t see widespread use in vendor kernels until a few LTS versions later. Before device trees, each device usually had a &#039;&#039;board file&#039;&#039; - a C file that contained structs with driver data and initialization functions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The downstream Kona kernels used board files.&#039;&#039;&#039; (They did have some partial DT support, but it was never used for any production devices.)&lt;br /&gt;
&lt;br /&gt;
== Kernel compilation toolchain ==&lt;br /&gt;
&lt;br /&gt;
To compile the kernel for the device, we will need a compiler toolchain for the ARM architecture.&lt;br /&gt;
&lt;br /&gt;
For convenience, we will use pmbootstrap (the postmarketOS build tool) with its envkernel.sh script, which handles toolchain setup automatically (everything is installed in a chroot managed by pmbootstrap, so no manual work needs to be done on the host system), and gives us the extra benefit of building a ready initramfs and rootfs image to boot with.&lt;br /&gt;
&lt;br /&gt;
=== mainline-tools setup ===&lt;br /&gt;
&lt;br /&gt;
[https://uart.sh serialuart] uses a convenience script that wraps around envkernel.sh and automates the setup process and most commonly used commands: [https://github.com/refractionware/linux/tree/meta/mt mainline-tools].&lt;br /&gt;
&lt;br /&gt;
This script sets up a couple of aliases, including:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mb&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;mainline-build&amp;lt;/code&amp;gt;) - shorthand for &amp;lt;code&amp;gt;make -j$(nproc)&amp;lt;/code&amp;gt;, used to build the kernel.&lt;br /&gt;
* &amp;lt;code&amp;gt;mp&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;mainline-package&amp;lt;/code&amp;gt;) - creates a boot.img image for the built kernel.&lt;br /&gt;
* &amp;lt;code&amp;gt;mf&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;mainline-flash&amp;lt;/code&amp;gt;) - flashes the boot.img generated with &amp;lt;code&amp;gt;mp&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;mbp&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;mainline-build-package&amp;lt;/code&amp;gt;) - updates the postmarketOS kernel package (&amp;lt;code&amp;gt;linux-postmarketos-brcm-kona&amp;lt;/code&amp;gt;) based on the build done with &amp;lt;code&amp;gt;mb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;msp&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;mainline-sideload-pkg&amp;lt;/code&amp;gt;) - sideloads the latest kernel package (needed to update modules).&lt;br /&gt;
&lt;br /&gt;
{{note|A note about kernel packaging:&lt;br /&gt;
&lt;br /&gt;
* boot.img only contains the kernel and built-in drivers (Y in defconfig).&lt;br /&gt;
* The kernel package (linux-postmarketos-brcm-kona) contains modules (M in defconfig).&lt;br /&gt;
&lt;br /&gt;
Flashing boot.img (&amp;lt;code&amp;gt;mp&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;mf&amp;lt;/code&amp;gt;) will only update built-in modules; to update non-built-in modules on the device, use &amp;lt;code&amp;gt;mbp&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;msp&amp;lt;/code&amp;gt; to sideload over USB (or regenerate the image with &amp;lt;code&amp;gt;pmbootstrap install&amp;lt;/code&amp;gt;).}}&lt;br /&gt;
&lt;br /&gt;
To set up that script, run the following commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell-session&amp;quot;&amp;gt;&lt;br /&gt;
$ mkdir ~/code&lt;br /&gt;
$ cd ~/code&lt;br /&gt;
$ git clone https://gitlab.postmarketos.org/postmarketOS/pmbootstrap  # git clone is needed for envkernel.sh, even if you already have pmbootstrap installed&lt;br /&gt;
$ wget https://raw.githubusercontent.com/refractionware/linux/refs/heads/meta/mt/mt.sh&lt;br /&gt;
$ source ~/code/mt.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you start a session, run &amp;lt;code&amp;gt;source ~/code/mt.sh&amp;lt;/code&amp;gt; to enable mainline-tools.&lt;br /&gt;
&lt;br /&gt;
== Getting the mainline kernel source ==&lt;br /&gt;
&lt;br /&gt;
Broadcom Kona development happens in a close-to-mainline fork hosted on GitHub: [https://github.com/bcm-kona-mainline/linux bcm-kona-mainline/linux]&lt;br /&gt;
&lt;br /&gt;
Clone the kernel from GitHub:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell-session&amp;quot;&amp;gt;&lt;br /&gt;
$ cd ~/code&lt;br /&gt;
$ git clone https://github.com/bcm-kona-mainline/linux&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Getting the downstream kernel source ==&lt;br /&gt;
&lt;br /&gt;
You will need to reference the downstream kernel for your device for the porting process; most likely someone has uploaded it to GitHub (look for android_kernel_(vendor)_(codename) repos).&lt;br /&gt;
&lt;br /&gt;
Once you have the kernel downloaded, find the &#039;&#039;&#039;defconfig&#039;&#039;&#039; and &#039;&#039;&#039;board file&#039;&#039;&#039; for your device.&lt;br /&gt;
&lt;br /&gt;
* The defconfig is in &amp;lt;code&amp;gt;arch/arm/configs&amp;lt;/code&amp;gt;; if you got a CyanogenMod/LineageOS kernel, look for a &amp;lt;code&amp;gt;cyanogenmod_XXX_defconfig&amp;lt;/code&amp;gt;; otherwise, there should be a config with a name like &amp;lt;code&amp;gt;bcmXXXXX_codename_revXX_defconfig&amp;lt;/code&amp;gt; (pick the highest revision number).&lt;br /&gt;
* The board file is in &amp;lt;code&amp;gt;arch/arm/mach-PLATFORM/board-ss_CODENAME.c&amp;lt;/code&amp;gt; (or just &amp;lt;code&amp;gt;board-CODENAME.c&amp;lt;/code&amp;gt;), where PLATFORM is &amp;lt;code&amp;gt;capri&amp;lt;/code&amp;gt; for BCM218xx, &amp;lt;code&amp;gt;rhea&amp;lt;/code&amp;gt; for BCM21654, &amp;lt;code&amp;gt;hawaii&amp;lt;/code&amp;gt; for BCM21664 and &amp;lt;code&amp;gt;java&amp;lt;/code&amp;gt; for BCM23550.&lt;br /&gt;
&lt;br /&gt;
== Adding a device package in postmarketOS ==&lt;br /&gt;
&lt;br /&gt;
Run &amp;lt;code&amp;gt;pmbootstrap init&amp;lt;/code&amp;gt;. When asked for the device, provide the vendor and codename.&lt;br /&gt;
&lt;br /&gt;
* If you&#039;re asked to create a new device, follow the [https://wiki.postmarketos.org/wiki/Porting_to_a_new_device Porting Guide], using the &amp;lt;code&amp;gt;linux-postmarketos-brcm-kona&amp;lt;/code&amp;gt; mainline kernel package.&lt;br /&gt;
* If this ends up selecting an existing downstream/archived device, you&#039;ll need to update the device package - see [https://gitlab.postmarketos.org/postmarketOS/pmaports/-/merge_requests/8981/diffs?commit_id=fc2eb16282fe1b9dea7fb010533568899fad1bcb the commit doing this for samsung-baffinlite] as an example.&lt;br /&gt;
&lt;br /&gt;
== Adding a DTS for your device ==&lt;br /&gt;
&lt;br /&gt;
The DTS describes the hardware of the device. DTS files for Broadcom-based devices are located in &amp;lt;code&amp;gt;arch/arm/boot/dts/broadcom&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{hint|&amp;lt;code&amp;gt;[https://github.com/bcm-kona-mainline/linux/blob/kona/7.1/arch/arm/boot/dts/broadcom/bcm23550-samsung-baffinlite.dts bcm23550-samsung-baffinlite.dts]&amp;lt;/code&amp;gt; is a good reference point for DTSes for all Kona chips.}}&lt;br /&gt;
&lt;br /&gt;
Create a new file in &amp;lt;code&amp;gt;arch/arm/boot/dts/broadcom&amp;lt;/code&amp;gt; for your device with the filename &amp;lt;code&amp;gt;(soc)-(vendor)-(codename).dts&amp;lt;/code&amp;gt; - for example, for a BCM21664 device with the codename samsung-kylepro, the filename will be &amp;lt;code&amp;gt;bcm21664-samsung-kylepro.dts&amp;lt;/code&amp;gt;. Start from the following template (remove the comments when you&#039;re done):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
// SPDX-License-Identifier: GPL-2.0-only&lt;br /&gt;
/*&lt;br /&gt;
 * Common device tree for Samsung Galaxy Trend Plus/S Duos 2&lt;br /&gt;
 * (kylepro/kyleprods).&lt;br /&gt;
 *&lt;br /&gt;
 * Copyright (c) 2026 Your Name &amp;lt;youremail@example.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/dts-v1/;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;dt-bindings/gpio/gpio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dt-bindings/input/input.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dt-bindings/leds/common.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Depending on which SoC your device uses, change the following to:&lt;br /&gt;
// BCM2166x - &amp;quot;bcm21664.dtsi&amp;quot;&lt;br /&gt;
// BCM23550 - &amp;quot;bcm23550.dtsi&amp;quot;&lt;br /&gt;
// BCM281x5 - &amp;quot;bcm11351.dtsi&amp;quot;&lt;br /&gt;
#include &amp;quot;bcm21664.dtsi&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/ {&lt;br /&gt;
	model = &amp;quot;Vendor Codename (MODEL-NUMBER)&amp;quot;;&lt;br /&gt;
	compatible = &amp;quot;vendor,codename&amp;quot;, &amp;quot;brcm,bcm21664&amp;quot;;  // remember to change the SoC compatible&lt;br /&gt;
	chassis-type = &amp;quot;handset&amp;quot;;  // usually &amp;quot;handset&amp;quot; (smartphone) or &amp;quot;tablet&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	memory@80000000 {&lt;br /&gt;
		device_type = &amp;quot;memory&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;0x80000000 0x30000000&amp;gt;; /* 768 MB; CHANGEME */&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	reserved-memory {&lt;br /&gt;
		#address-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
		#size-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
		ranges;&lt;br /&gt;
&lt;br /&gt;
		coprocessor_mem: coprocessor-mem@80000000 {&lt;br /&gt;
			reg = &amp;lt;0x80000000 0x1e00000&amp;gt;;&lt;br /&gt;
			no-map;&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		secure_mem: secure-mem@9d800000 {&lt;br /&gt;
			reg = &amp;lt;0x9d800000 0x100000&amp;gt;;&lt;br /&gt;
			no-map;&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		mobicore: mobicore@9d900000 {&lt;br /&gt;
			reg = &amp;lt;0x9d900000 0x300000&amp;gt;;&lt;br /&gt;
			no-map;&lt;br /&gt;
		};&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, open &amp;lt;code&amp;gt;arch/arm/boot/dts/broadcom/Makefile&amp;lt;/code&amp;gt;, and locate the following section:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;makefile&amp;quot;&amp;gt;&lt;br /&gt;
dtb-$(CONFIG_ARCH_BCM_MOBILE) += \&lt;br /&gt;
	bcm28155-ap.dtb \&lt;br /&gt;
	bcm21664-garnet.dtb \&lt;br /&gt;
	bcm21664-samsung-kylepro.dtb \&lt;br /&gt;
	bcm23550-samsung-baffinlite.dtb \&lt;br /&gt;
	bcm23550-sparrow.dtb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add your DTS to the list, changing &amp;lt;code&amp;gt;.dts&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;.dtb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Filling out the memory node ===&lt;br /&gt;
&lt;br /&gt;
To get the memory size, as well as reserved regions, run the following command under a downstream kernel (e.g. under TWRP):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell-session&amp;quot;&amp;gt;&lt;br /&gt;
$ cat /proc/iomem&lt;br /&gt;
81e00000-afffffff : System RAM&lt;br /&gt;
  81e08000-823ec57b : Kernel code&lt;br /&gt;
  8251c000-826d72ff : Kernel data&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
From the above, the RAM would begin at &amp;lt;code&amp;gt;81e00000&amp;lt;/code&amp;gt; and have a size of &amp;lt;code&amp;gt;(0xafffffff+1) - 0x81e00000 = &amp;lt;b&amp;gt;0x2e200000&amp;lt;/b&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{todo|A lot of Samsung device kernels seem to be configured with a mem base of 0x81e00000, but in ATAG_MEM the 0x80000000 - 0x81e00000 chunk is also reported as a separate memory block as well.&lt;br /&gt;
&lt;br /&gt;
This memory region is likely used for storing coprocessor firmware blobs and communication with the modem and other coprocessors (see {{downstream|baffinlite|arch/arm/mach-java/include/mach/comms/platform_mconfig_hawaii.h}}).&lt;br /&gt;
&lt;br /&gt;
While from initial testing it seems safe to use with the modem disabled, I have included a &amp;lt;code&amp;gt;coprocessor_mem&amp;lt;/code&amp;gt; block in the DTS snippet above to block out this region.&lt;br /&gt;
&lt;br /&gt;
TODO - figure out how to print ATAGs without serial. Typically they get printed over UART by the bootloader right before loading the kernel.}}&lt;br /&gt;
&lt;br /&gt;
=== UART ===&lt;br /&gt;
&lt;br /&gt;
UART/serial is most notably used for sending debug logs over USB, but is also used for talking to the Bluetooth and GPS chip.&lt;br /&gt;
&lt;br /&gt;
Check the downstream board file; look for a struct of type &amp;lt;code&amp;gt;plat_serial8250_port&amp;lt;/code&amp;gt;. It should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static struct plat_serial8250_port hawaii_uart_platform_data[] = {&lt;br /&gt;
	HAWAII_8250PORT(UART0, UARTB_PERI_CLK_NAME_STR, 48000000,&lt;br /&gt;
					&amp;quot;bluetooth&amp;quot;, NULL),&lt;br /&gt;
	HAWAII_8250PORT(UART1, UARTB2_PERI_CLK_NAME_STR, 26000000,&lt;br /&gt;
				&amp;quot;gps&amp;quot;, &amp;amp;power_save_enable),&lt;br /&gt;
	HAWAII_8250PORT(UART2, UARTB3_PERI_CLK_NAME_STR, 26000000,&lt;br /&gt;
				&amp;quot;console&amp;quot;, NULL),&lt;br /&gt;
	{&lt;br /&gt;
		.flags = 0,&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the numbers in the XXX_8250PORT macros; these represent the clock frequency.&lt;br /&gt;
&lt;br /&gt;
Also note the names given to the ports; there are a hint for what the ports are used for. As seen above, the layout is usually - uartb for Bluetooth, uartb2 for GPS and uartb3 for serial console.&lt;br /&gt;
&lt;br /&gt;
At the bottom of your DTS, add (change clock frequencies to match board file):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&amp;amp;uartb {&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
	clock-frequency = &amp;lt;48000000&amp;gt;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;amp;uartb2 {&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
	clock-frequency = &amp;lt;26000000&amp;gt;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;amp;uartb3 {&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
	clock-frequency = &amp;lt;26000000&amp;gt;;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PMIC ===&lt;br /&gt;
&lt;br /&gt;
Most Kona devices use BCM590xx series PMICs: BCM59054 for BCM21664/BCM23550, BCM59056 for BCM281xx and BCM59039 for BCM21654. The only known exceptions are the GT-I9150 (BCM281xx device with a BCM59054 and SMB358 for charging) and the GT-S6810 (Dialog DA2083).&lt;br /&gt;
&lt;br /&gt;
The PMIC is connected to a separate PMIC I2C bus (or BSC, as Broadcom calls their &amp;quot;I2C-compatible&amp;quot; bus):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;pmu_bsc {&lt;br /&gt;
	clock-frequency = &amp;lt;3400000&amp;gt;; /* 3.2mhz? Downstream refers to this as a HS bus, but it doesn&#039;t give any speed information other than that. */&lt;br /&gt;
&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;pmbsc_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	pmu: pmu@8 {&lt;br /&gt;
		compatible = &amp;quot;brcm,bcm59054&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;0x08&amp;gt;;&lt;br /&gt;
		interrupt-parent = &amp;lt;&amp;amp;gpio&amp;gt;;&lt;br /&gt;
		interrupts = &amp;lt;29 IRQ_TYPE_EDGE_FALLING&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
		regulators {&lt;br /&gt;
			/* ... */&lt;br /&gt;
		};&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PMIC configuration is stored in a separate file in downstream, beginning with &amp;lt;code&amp;gt;board-bcm59xxx-(...).c&amp;lt;/code&amp;gt; (same directory as the board file). Every regulator is described in this file, in &amp;lt;code&amp;gt;regulator_init_data&amp;lt;/code&amp;gt; structs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__weak struct regulator_consumer_supply rf_supply[] = {&lt;br /&gt;
	{.supply = &amp;quot;rf&amp;quot;},&lt;br /&gt;
};&lt;br /&gt;
static struct regulator_init_data bcm59xxx_rfldo_data = {&lt;br /&gt;
	.constraints = {&lt;br /&gt;
			.name = &amp;quot;rfldo&amp;quot;,&lt;br /&gt;
			.min_uV = 1300000,&lt;br /&gt;
			.max_uV = 3300000,&lt;br /&gt;
			.valid_ops_mask = REGULATOR_CHANGE_STATUS |&lt;br /&gt;
			REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,&lt;br /&gt;
			.valid_modes_mask = REGULATOR_MODE_NORMAL |&lt;br /&gt;
			REGULATOR_MODE_IDLE |&lt;br /&gt;
			REGULATOR_MODE_STANDBY,&lt;br /&gt;
			.always_on = 0,&lt;br /&gt;
			.initial_mode = REGULATOR_MODE_STANDBY,&lt;br /&gt;
			},&lt;br /&gt;
	.num_consumer_supplies = ARRAY_SIZE(rf_supply),&lt;br /&gt;
	.consumer_supplies = rf_supply,&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Equivalent DTS fragment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
			rfldo_reg: rfldo {&lt;br /&gt;
				regulator-min-microvolt = &amp;lt;1300000&amp;gt;;&lt;br /&gt;
				regulator-max-microvolt = &amp;lt;3300000&amp;gt;;&lt;br /&gt;
				regulator-always-on;&lt;br /&gt;
				/* regulator-allowed-modes = &amp;lt;0x2 0x4 0x8&amp;gt;; */ /* NORMAL, IDLE, STANDBY */&lt;br /&gt;
				/* regulator-initial-mode = &amp;lt;0x8&amp;gt;; */ /* REGULATOR_MODE_STANDBY */&lt;br /&gt;
			};&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Repeat for all regulator types; see DT bindings for reference ([https://github.com/bcm-kona-mainline/linux/blob/kona/7.1/Documentation/devicetree/bindings/regulator/brcm%2Cbcm59054.yaml BCM59054], [https://github.com/bcm-kona-mainline/linux/blob/kona/7.1/Documentation/devicetree/bindings/regulator/brcm%2Cbcm59056.yaml BCM59056]).&lt;br /&gt;
&lt;br /&gt;
=== SDIO/Storage ===&lt;br /&gt;
&lt;br /&gt;
SDIO is used for internal storage, the SD card and WiFi.&lt;br /&gt;
&lt;br /&gt;
In the downstream board file, look for &amp;lt;code&amp;gt;sdio_platform_cfg&amp;lt;/code&amp;gt; structs. Here&#039;s an example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
static struct sdio_platform_cfg hawaii_sdio_param[] = {&lt;br /&gt;
	{&lt;br /&gt;
		.id = 0,&lt;br /&gt;
		.data_pullup = 0,&lt;br /&gt;
		.cd_gpio = SD_CARDDET_GPIO_PIN,&lt;br /&gt;
		.devtype = SDIO_DEV_TYPE_SDMMC,&lt;br /&gt;
		.flags = KONA_SDIO_FLAGS_DEVICE_REMOVABLE,&lt;br /&gt;
		.peri_clk_name = &amp;quot;sdio1_clk&amp;quot;,&lt;br /&gt;
		.ahb_clk_name = &amp;quot;sdio1_ahb_clk&amp;quot;,&lt;br /&gt;
		.sleep_clk_name = &amp;quot;sdio1_sleep_clk&amp;quot;,&lt;br /&gt;
		.peri_clk_rate = 48000000,&lt;br /&gt;
		/*The SD card regulator*/&lt;br /&gt;
		.vddo_regulator_name = &amp;quot;vdd_sdio&amp;quot;,&lt;br /&gt;
		/*The SD controller regulator*/&lt;br /&gt;
		.vddsdxc_regulator_name = &amp;quot;vdd_sdxc&amp;quot;,&lt;br /&gt;
		.configure_sdio_pullup = configure_sdio_pullup,&lt;br /&gt;
	},&lt;br /&gt;
	{&lt;br /&gt;
		.id = 1,&lt;br /&gt;
		.data_pullup = 0,&lt;br /&gt;
		.is_8bit = 1,&lt;br /&gt;
		.devtype = SDIO_DEV_TYPE_EMMC,&lt;br /&gt;
		.flags = KONA_SDIO_FLAGS_DEVICE_NON_REMOVABLE ,&lt;br /&gt;
		.peri_clk_name = &amp;quot;sdio2_clk&amp;quot;,&lt;br /&gt;
		.ahb_clk_name = &amp;quot;sdio2_ahb_clk&amp;quot;,&lt;br /&gt;
		.sleep_clk_name = &amp;quot;sdio2_sleep_clk&amp;quot;,&lt;br /&gt;
		.peri_clk_rate = 52000000,&lt;br /&gt;
		},&lt;br /&gt;
	{&lt;br /&gt;
		.id = 2,&lt;br /&gt;
		.data_pullup = 0,&lt;br /&gt;
		.devtype = SDIO_DEV_TYPE_WIFI,&lt;br /&gt;
		.flags = KONA_SDIO_FLAGS_DEVICE_REMOVABLE,&lt;br /&gt;
		.peri_clk_name = &amp;quot;sdio3_clk&amp;quot;,&lt;br /&gt;
		.ahb_clk_name = &amp;quot;sdio3_ahb_clk&amp;quot;,&lt;br /&gt;
		.sleep_clk_name = &amp;quot;sdio3_sleep_clk&amp;quot;,&lt;br /&gt;
		.peri_clk_rate = 48000000,&lt;br /&gt;
#ifdef CONFIG_BRCM_UNIFIED_DHD_SUPPORT&lt;br /&gt;
		.wifi_gpio = {&lt;br /&gt;
			.reset          = 3,&lt;br /&gt;
			.reg            = -1,&lt;br /&gt;
			.host_wake      = 74,&lt;br /&gt;
			.shutdown       = -1,&lt;br /&gt;
		},&lt;br /&gt;
		.register_status_notify = hawaii_wifi_status_register,&lt;br /&gt;
#endif&lt;br /&gt;
        },&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Things of note:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;.peri_clk_rate&amp;lt;/code&amp;gt; is equivalent to &amp;lt;code&amp;gt;max-frequency&amp;lt;/code&amp;gt; in DT;&lt;br /&gt;
* &amp;lt;code&amp;gt;.is_8bit = 1&amp;lt;/code&amp;gt; is equivalent to &amp;lt;code&amp;gt;bus-width = &amp;amp;lt;8&amp;amp;gt;&amp;lt;/code&amp;gt;;&lt;br /&gt;
* &amp;lt;code&amp;gt;.cd_gpio&amp;lt;/code&amp;gt; contains the card detect GPIO for the SD card slot. It is usually defined as a macro, the value is defined earlier in the board file. Here it&#039;s &amp;lt;code&amp;gt;91&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;.vddo_regulator_name&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.vddsdxc_regulator_name&amp;lt;/code&amp;gt; become &amp;lt;code&amp;gt;vmmc-supply&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;vqmmc-supply&amp;lt;/code&amp;gt; respectively. To find which regulator they are attached to, look up the names in your board file; you might find a struct like such: &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;struct regulator_consumer_supply sd_supply[] = {&lt;br /&gt;
	{.supply = &amp;quot;sdldo_uc&amp;quot;},&lt;br /&gt;
	REGULATOR_SUPPLY(&amp;quot;vddmmc&amp;quot;, &amp;quot;sdhci.3&amp;quot;), /* 0x3f1b0000.sdhci */&lt;br /&gt;
	{.supply = &amp;quot;vdd_sdio&amp;quot;},&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct regulator_consumer_supply sdx_supply[] = {&lt;br /&gt;
	{.supply = &amp;quot;sdxldo_uc&amp;quot;},&lt;br /&gt;
	REGULATOR_SUPPLY(&amp;quot;vddo&amp;quot;, &amp;quot;sdhci.3&amp;quot;), /* 0x3f1b0000.sdhci */&lt;br /&gt;
	{.supply = &amp;quot;vdd_sdxc&amp;quot;},&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 The first listed supply should show you the name of the BCM59xxx supply - in this case, &amp;lt;code&amp;gt;sdldo&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;sdxldo&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Equivalent mainline DTS:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* SD card */&lt;br /&gt;
&amp;amp;sdio1 {&lt;br /&gt;
	max-frequency = &amp;lt;48000000&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	cd-gpios = &amp;lt;&amp;amp;gpio 91 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)&amp;gt;;&lt;br /&gt;
	vmmc-supply = &amp;lt;&amp;amp;sdldo_reg&amp;gt;;&lt;br /&gt;
	vqmmc-supply = &amp;lt;&amp;amp;sdxldo_reg&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    /* NOTE: skip pinctrl here and in the other nodes for BCM28155, we don&#039;t have ready-made pinctrl definitions for it yet */&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;sd_width4_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/* Internal storage */&lt;br /&gt;
&amp;amp;sdio2 {&lt;br /&gt;
	max-frequency = &amp;lt;52000000&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	keep-power-in-suspend;&lt;br /&gt;
	non-removable;&lt;br /&gt;
	bus-width = &amp;lt;8&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;mmc0_width8_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/* WiFi */&lt;br /&gt;
&amp;amp;sdio3 {&lt;br /&gt;
	max-frequency = &amp;lt;48000000&amp;gt;;&lt;br /&gt;
    &lt;br /&gt;
	#address-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
	#size-cells = &amp;lt;0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;mmc1_width4_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // NOTE: Non-removable is hardcoded for the WiFi SDIO in the downstream driver, even if the board file claims it&#039;s removable.&lt;br /&gt;
	keep-power-in-suspend;&lt;br /&gt;
	non-removable;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== I2C/BSC ===&lt;br /&gt;
&lt;br /&gt;
Most sensors, as well as the touchscreen, are connected over I2C. Broadcom SoCs actually have an I2C-compatible bus called BSC.&lt;br /&gt;
&lt;br /&gt;
Finding exactly which sensors are used is a bit difficult, because board files tend to have data for a lot of sensors that is unused. You will need to look for sections guarded with &amp;lt;code&amp;gt;#ifdef CONFIG_...&amp;lt;/code&amp;gt;; for the config option values, reference the downstream defconfig file for your device.&lt;br /&gt;
&lt;br /&gt;
In general, it&#039;s best to look through the defconfig first and find all the relevant options for sensors (look up keywords like SENSOR, PROXIMITY, ACCEL, MAG, LIGHT, TOUCH, INPUT...).&lt;br /&gt;
&lt;br /&gt;
(Alternatively, if you have a Samsung device, reference [https://docs.google.com/spreadsheets/d/1NioX9a2vgbEcO_Zs9COUFO-n3a2Rqf1JWWU1cfsktLM/edit?gid=0#gid=0 the spreadsheet].)&lt;br /&gt;
&lt;br /&gt;
In the board file, look for &amp;lt;code&amp;gt;i2c_board_info&amp;lt;/code&amp;gt; structs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if defined(CONFIG_SENSORS_BMM050)&lt;br /&gt;
#define BMA2X2_SLAVE_ADDR  0x10&lt;br /&gt;
#else&lt;br /&gt;
#define BMA2X2_SLAVE_ADDR  0x18&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
static struct i2c_board_info __initdata bsc3_i2c_boardinfo[] =&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
#if defined(CONFIG_SENSORS_BMC150)&lt;br /&gt;
#if defined(CONFIG_SENSORS_BMA2X2)&lt;br /&gt;
        {&lt;br /&gt;
		I2C_BOARD_INFO(&amp;quot;bma2x2&amp;quot;, BMA2X2_SLAVE_ADDR),&lt;br /&gt;
		.platform_data = &amp;amp;bss_bma2x2,&lt;br /&gt;
        },&lt;br /&gt;
#endif&lt;br /&gt;
#if defined(CONFIG_SENSORS_BMM050)&lt;br /&gt;
        {&lt;br /&gt;
		I2C_BOARD_INFO(&amp;quot;bmm050&amp;quot;, 0x12),&lt;br /&gt;
		.platform_data = &amp;amp;bss_bmm050,&lt;br /&gt;
        },&lt;br /&gt;
#endif        &lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if defined  (CONFIG_SENSORS_HSCDTD006A) || defined(CONFIG_SENSORS_HSCDTD008A) &lt;br /&gt;
	{&lt;br /&gt;
		I2C_BOARD_INFO(&amp;quot;hscd_i2c&amp;quot;, 0x0c),&lt;br /&gt;
		.platform_data = &amp;amp;hscd_i2c_platform_data,               &lt;br /&gt;
	},&lt;br /&gt;
 #endif&lt;br /&gt;
&lt;br /&gt;
#if defined(CONFIG_SENSORS_GP2AP002)&lt;br /&gt;
        {&lt;br /&gt;
             I2C_BOARD_INFO(&amp;quot;gp2ap002&amp;quot;,0x44),&lt;br /&gt;
             .platform_data = &amp;amp;gp2ap002_platform_data,&lt;br /&gt;
        }&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do a &amp;lt;code&amp;gt;grep -iR&amp;lt;/code&amp;gt; with the codename in &amp;lt;code&amp;gt;drivers&amp;lt;/code&amp;gt; in mainline to see if you can spot a driver for the sensor you want to add. Many sensors from that era are already supported in mainline. You can look at other device trees (&amp;lt;code&amp;gt;arch/arm/boot/dts&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;arch/arm64/boot/dts&amp;lt;/code&amp;gt;) as well as DT bindings (&amp;lt;code&amp;gt;Documentation/devicetree/bindings&amp;lt;/code&amp;gt;) to figure out how to add them to your DTS.&lt;br /&gt;
&lt;br /&gt;
For the exact values to use in DT, you&#039;ll have to look at the &amp;lt;code&amp;gt;platform_data&amp;lt;/code&amp;gt; struct, and sometimes at the driver for the peripheral (which you can usually find by grepping the downstream source code for the model number/driver name).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&amp;amp;bsc3 {&lt;br /&gt;
	clock-frequency = &amp;lt;400000&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    // NOTE: again, pinctrl only applies to BCM21664/BCM23550 at the moment&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;bsc3_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	magnetometer@c {&lt;br /&gt;
		compatible = &amp;quot;alps,hscdtd008a&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;0x0c&amp;gt;;&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	accel@18 {&lt;br /&gt;
		compatible = &amp;quot;bosch,bma254&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;0x18&amp;gt;;&lt;br /&gt;
        &lt;br /&gt;
		/* ... */&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	proximity@44 {&lt;br /&gt;
		compatible = &amp;quot;sharp,gp2ap002s00f&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;0x44&amp;gt;;&lt;br /&gt;
        &lt;br /&gt;
		/* ... */&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== USB ===&lt;br /&gt;
&lt;br /&gt;
USB comprises of 3 parts:&lt;br /&gt;
&lt;br /&gt;
* The USB OTG controller (usbotg node);&lt;br /&gt;
* The USB PHY (usbphy node);&lt;br /&gt;
* The USB mode switch (not all devices - BCM59039 devices don&#039;t seem to be paired with a switch).&lt;br /&gt;
&lt;br /&gt;
Commonly used switches include the FSA9480/9485, TSUxxxx and RTxxxx. Look them up in your defconfig (keywords: FSA, TSU, RT).&lt;br /&gt;
&lt;br /&gt;
On Samsung devices, the switches are often connected over I2C-GPIO (which is an I2C bus bitbanged over GPIO pins).  Example from baffinlite:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define GPIO_FSA9485_I2C_SDA 113&lt;br /&gt;
#define GPIO_FSA9485_I2C_SCL 114&lt;br /&gt;
#define GPIO_FSA9485_INT 56&lt;br /&gt;
&lt;br /&gt;
/* ... */&lt;br /&gt;
&lt;br /&gt;
static struct i2c_board_info  __initdata micro_usb_i2c_devices_info[]  = {&lt;br /&gt;
	{&lt;br /&gt;
		I2C_BOARD_INFO(&amp;quot;fsa9485&amp;quot;, 0x4A &amp;gt;&amp;gt; 1),&lt;br /&gt;
		.platform_data = &amp;amp;fsa9485_pdata,&lt;br /&gt;
		.irq = gpio_to_irq(GPIO_FSA9485_INT),&lt;br /&gt;
	},&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
static struct i2c_gpio_platform_data fsa_i2c_gpio_data={&lt;br /&gt;
	.sda_pin = GPIO_FSA9485_I2C_SDA,&lt;br /&gt;
	.scl_pin = GPIO_FSA9485_I2C_SCL,&lt;br /&gt;
	.udelay	 = 2,&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note - &amp;lt;code&amp;gt;0x4A &amp;gt;&amp;gt; 1&amp;lt;/code&amp;gt; means a bit shift, you can paste it into the Python interpreter and it will give you the value (&amp;lt;code&amp;gt;hex(0x4A &amp;gt;&amp;gt; 1)&amp;lt;/code&amp;gt; gives &amp;lt;code&amp;gt;0x25&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
In mainline, this becomes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
/ {&lt;br /&gt;
/* (add this under the / node ) */&lt;br /&gt;
&lt;br /&gt;
    /* ... */&lt;br /&gt;
&lt;br /&gt;
	/* USB switch */&lt;br /&gt;
	i2c-musb {&lt;br /&gt;
		#address-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
		#size-cells = &amp;lt;0&amp;gt;;&lt;br /&gt;
		compatible = &amp;quot;i2c-gpio&amp;quot;;&lt;br /&gt;
		sda-gpios = &amp;lt;&amp;amp;gpio 113 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)&amp;gt;;&lt;br /&gt;
		scl-gpios = &amp;lt;&amp;amp;gpio 114 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)&amp;gt;;&lt;br /&gt;
		i2c-gpio,delay-us = &amp;lt;2&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
		musb@25 {&lt;br /&gt;
			compatible = &amp;quot;fcs,fsa9480&amp;quot;;&lt;br /&gt;
			reg = &amp;lt;0x25&amp;gt;;&lt;br /&gt;
			interrupt-parent = &amp;lt;&amp;amp;gpio&amp;gt;;&lt;br /&gt;
			interrupts = &amp;lt;56 IRQ_TYPE_LEVEL_HIGH&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
			connector {&lt;br /&gt;
				compatible = &amp;quot;samsung,usb-connector-11pin&amp;quot;,&lt;br /&gt;
					     &amp;quot;usb-b-connector&amp;quot;;&lt;br /&gt;
				label = &amp;quot;micro-USB&amp;quot;;&lt;br /&gt;
				type = &amp;quot;micro&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
				ports {&lt;br /&gt;
					#address-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
					#size-cells = &amp;lt;0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
					port@0 {&lt;br /&gt;
						reg = &amp;lt;0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
						muic_to_usb: endpoint {&lt;br /&gt;
							remote-endpoint = &amp;lt;&amp;amp;usb_to_muic&amp;gt;;&lt;br /&gt;
						};&lt;br /&gt;
					};&lt;br /&gt;
				};&lt;br /&gt;
			};&lt;br /&gt;
&lt;br /&gt;
		};&lt;br /&gt;
	};&lt;br /&gt;
    /* ... */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the switch, you can add the remaining USB nodes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&amp;amp;usbotg {&lt;br /&gt;
	vusb_d-supply = &amp;lt;&amp;amp;usbldo_reg&amp;gt;;&lt;br /&gt;
	vusb_a-supply = &amp;lt;&amp;amp;iosr1_reg&amp;gt;;&lt;br /&gt;
	vbus-supply = &amp;lt;&amp;amp;vbus_reg&amp;gt;;&lt;br /&gt;
	dr_mode = &amp;quot;otg&amp;quot;;&lt;br /&gt;
	role-switch-default-mode = &amp;quot;peripheral&amp;quot;;&lt;br /&gt;
	usb-role-switch;&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // if your device has no switch, drop the port node below&lt;br /&gt;
	port {&lt;br /&gt;
		usb_to_muic: endpoint {&lt;br /&gt;
			remote-endpoint = &amp;lt;&amp;amp;muic_to_usb&amp;gt;;&lt;br /&gt;
		};&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;amp;usbphy {&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== WiFi and Bluetooth ===&lt;br /&gt;
&lt;br /&gt;
Most Broadcom devices use Broadcom WiFi/Bluetooth chips from the BCM43xx series. (Look up BCM43 in your defconfig, or reference downstream kernel dmesg for the exact model.)&lt;br /&gt;
&lt;br /&gt;
The below examples are for BCM4330. If you have another chip, you can grep for it in the mainline kernel (&amp;lt;code&amp;gt;arch/arm/boot/dts&amp;lt;/code&amp;gt;) and see what compatibles are used by other devices.&lt;br /&gt;
&lt;br /&gt;
The Bluetooth chip goes under the UART bus that was labeled as &amp;quot;bluetooth&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&amp;amp;uartb {&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
	clock-frequency = &amp;lt;48000000&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	bluetooth {&lt;br /&gt;
		compatible = &amp;quot;brcm,bcm4330-bt&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		shutdown-gpios = &amp;lt;&amp;amp;gpio 28 GPIO_ACTIVE_HIGH&amp;gt;;&lt;br /&gt;
		device-wakeup-gpios = &amp;lt;&amp;amp;gpio 32 GPIO_ACTIVE_HIGH&amp;gt;;&lt;br /&gt;
		host-wakeup-gpios = &amp;lt;&amp;amp;gpio 72 GPIO_ACTIVE_HIGH&amp;gt;;&lt;br /&gt;
		reset-gpios = &amp;lt;&amp;amp;gpio 71 GPIO_ACTIVE_LOW&amp;gt;;&lt;br /&gt;
		interrupt-parent = &amp;lt;&amp;amp;gpio&amp;gt;;&lt;br /&gt;
		interrupts = &amp;lt;72 IRQ_TYPE_EDGE_FALLING&amp;gt;;&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get the GPIOs:&lt;br /&gt;
&lt;br /&gt;
* Look for &amp;lt;code&amp;gt;bcmbt_platform_data&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;.bt_wake_gpio&amp;lt;/code&amp;gt; becomes &amp;lt;code&amp;gt;device-wakeup-gpios&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;.host_wake_gpio&amp;lt;/code&amp;gt; becomes &amp;lt;code&amp;gt;host-wakeup-gpios&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Look for &amp;lt;code&amp;gt;bcmbt_rfkill_platform_data&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;.vreg_gpio&amp;lt;/code&amp;gt; becomes &amp;lt;code&amp;gt;shutdown-gpios&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;.n_reset_gpio&amp;lt;/code&amp;gt; becomes &amp;lt;code&amp;gt;reset-gpios&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For WiFi, add the following under the &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; node:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
/ {&lt;br /&gt;
    /* ... */&lt;br /&gt;
    &lt;br /&gt;
	/* GPIO regulator for WiFi */&lt;br /&gt;
	wl_reg: regulator-gpio-wlan {&lt;br /&gt;
		compatible = &amp;quot;regulator-fixed&amp;quot;;&lt;br /&gt;
		regulator-name = &amp;quot;WL_REG_ON&amp;quot;;&lt;br /&gt;
		regulator-min-microvolt = &amp;lt;3000000&amp;gt;;&lt;br /&gt;
		regulator-max-microvolt = &amp;lt;3000000&amp;gt;;&lt;br /&gt;
		startup-delay-us = &amp;lt;100000&amp;gt;;&lt;br /&gt;
		gpio = &amp;lt;&amp;amp;gpio 3 GPIO_ACTIVE_HIGH&amp;gt;;&lt;br /&gt;
		enable-active-high;&lt;br /&gt;
	};&lt;br /&gt;
    &lt;br /&gt;
    /* ... */&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Get the GPIO from &amp;lt;code&amp;gt;board_wifi_info&amp;lt;/code&amp;gt;, member &amp;lt;code&amp;gt;.wl_reset_gpio&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Then, update the SDIO node for WiFi:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
/* WiFi */&lt;br /&gt;
&amp;amp;sdio3 {&lt;br /&gt;
	max-frequency = &amp;lt;48000000&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	/* Actually a regulator for the WiFi chip */&lt;br /&gt;
	vmmc-supply = &amp;lt;&amp;amp;wl_reg&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	#address-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
	#size-cells = &amp;lt;0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;mmc1_width4_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	keep-power-in-suspend;&lt;br /&gt;
	non-removable;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	wifi@1 {&lt;br /&gt;
		compatible = &amp;quot;brcm,bcm4330-fmac&amp;quot;, &amp;quot;brcm,bcm4329-fmac&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
		interrupt-parent = &amp;lt;&amp;amp;gpio&amp;gt;;&lt;br /&gt;
		interrupts = &amp;lt;74 IRQ_TYPE_EDGE_FALLING&amp;gt;;&lt;br /&gt;
		interrupt-names = &amp;quot;host-wake&amp;quot;;&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Get the interrupt from &amp;lt;code&amp;gt;board_wifi_info&amp;lt;/code&amp;gt;, member &amp;lt;code&amp;gt;.host_wake_gpio&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== GPIO keys ===&lt;br /&gt;
&lt;br /&gt;
Many Samsung devices use GPIO-based keys for the volume up/down and home keys. (The power button is handled by the PMIC, and the touchkeys (menu/back next to home button) are usually handled by the touchscreen).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define GPIO_KEYS_SETTINGS { \&lt;br /&gt;
      { KEY_VOLUMEUP,9, 1, &amp;quot;VOLUMEUP&amp;quot;, EV_KEY, 0, 64}, \&lt;br /&gt;
	{ KEY_HOME, 10, 1, &amp;quot;HOME&amp;quot;, EV_KEY, 0, 64},	\&lt;br /&gt;
      { KEY_VOLUMEDOWN,11, 1, &amp;quot;VOLUMEDOWN&amp;quot;, EV_KEY, 0, 64}, \&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)&lt;br /&gt;
static struct gpio_keys_button board_gpio_keys[] = GPIO_KEYS_SETTINGS;&lt;br /&gt;
/* ... */&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Equivalent DT fragment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
/ {&lt;br /&gt;
    /* ... */&lt;br /&gt;
&lt;br /&gt;
	/* Buttons */&lt;br /&gt;
	gpio-keys {&lt;br /&gt;
		compatible = &amp;quot;gpio-keys&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		key-volume-up {&lt;br /&gt;
			label = &amp;quot;Volume Up&amp;quot;;&lt;br /&gt;
			gpios = &amp;lt;&amp;amp;gpio 9 GPIO_ACTIVE_LOW&amp;gt;;&lt;br /&gt;
			linux,code = &amp;lt;KEY_VOLUMEUP&amp;gt;;&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		key-home {&lt;br /&gt;
			label = &amp;quot;Home&amp;quot;;&lt;br /&gt;
			gpios = &amp;lt;&amp;amp;gpio 10 GPIO_ACTIVE_LOW&amp;gt;;&lt;br /&gt;
			linux,code = &amp;lt;KEY_HOMEPAGE&amp;gt;;&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		key-volume-down {&lt;br /&gt;
			label = &amp;quot;Volume Down&amp;quot;;&lt;br /&gt;
			gpios = &amp;lt;&amp;amp;gpio 11 GPIO_ACTIVE_LOW&amp;gt;;&lt;br /&gt;
			linux,code = &amp;lt;KEY_VOLUMEDOWN&amp;gt;;&lt;br /&gt;
		};&lt;br /&gt;
	};&lt;br /&gt;
    &lt;br /&gt;
    /* ... */&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Keypad ===&lt;br /&gt;
&lt;br /&gt;
{{note|Keypad is only added for BCM21664/BCM23550 at the moment; it&#039;s most likely the same for BCM28155, just a matter of adding the right node like [https://github.com/bcm-kona-mainline/linux/commit/86a15664bdfe457bcd994b2ae72f722509259b53 in the equivalent bcm21664-common.dtsi commit].}}&lt;br /&gt;
&lt;br /&gt;
Some devices use the built-in keypad peripheral for volume up/down keys. If you have &amp;lt;code&amp;gt;CONFIG_KEYBOARD_BCM&amp;lt;/code&amp;gt; enabled in downstream defconfig, look for &amp;lt;code&amp;gt;bcm_keymap&amp;lt;/code&amp;gt; in your board file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#ifdef CONFIG_KEYBOARD_BCM&lt;br /&gt;
static struct bcm_keymap hawaii_keymap[] = {&lt;br /&gt;
	{BCM_KEY_ROW_0, BCM_KEY_COL_0, &amp;quot;unused&amp;quot;, 0},&lt;br /&gt;
	{BCM_KEY_ROW_0, BCM_KEY_COL_1, &amp;quot;Vol Down Key&amp;quot;, KEY_VOLUMEDOWN},&lt;br /&gt;
	{BCM_KEY_ROW_0, BCM_KEY_COL_2, &amp;quot;unused&amp;quot;, 0},&lt;br /&gt;
	{BCM_KEY_ROW_0, BCM_KEY_COL_3, &amp;quot;Vol Up Key&amp;quot;, KEY_VOLUMEUP},&lt;br /&gt;
	{BCM_KEY_ROW_0, BCM_KEY_COL_4, &amp;quot;unused&amp;quot;, 0},&lt;br /&gt;
	{BCM_KEY_ROW_0, BCM_KEY_COL_5, &amp;quot;unused&amp;quot;, 0},&lt;br /&gt;
    /* ... */&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
static struct bcm_keypad_platform_info hawaii_keypad_data = {&lt;br /&gt;
	.row_num = 1,&lt;br /&gt;
	.col_num = 5,&lt;br /&gt;
	.keymap = hawaii_keymap,&lt;br /&gt;
	.bcm_keypad_base = (void *)__iomem HW_IO_PHYS_TO_VIRT(KEYPAD_BASE_ADDR),&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Equivalent DTS:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&amp;amp;keypad {&lt;br /&gt;
	keypad,num-rows = &amp;lt;1&amp;gt;;&lt;br /&gt;
	keypad,num-columns = &amp;lt;5&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	linux,keymap = &amp;lt;MATRIX_KEY(0x00, 0x01, KEY_VOLUMEDOWN)&amp;gt;,&lt;br /&gt;
		       &amp;lt;MATRIX_KEY(0x00, 0x03, KEY_VOLUMEUP)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Building the kernel ==&lt;br /&gt;
&lt;br /&gt;
To apply the pmOS Broadcom Kona defconfig:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell-session&amp;quot;&amp;gt;&lt;br /&gt;
$ make bcmkona_pmos_defconfig&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To build the kernel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell-session&amp;quot;&amp;gt;&lt;br /&gt;
$ make -j$(nproc)&lt;br /&gt;
-- or, with mainline-tools: --&lt;br /&gt;
$ mb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have mainline-tools, you can flash the kernel with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell-session&amp;quot;&amp;gt;&lt;br /&gt;
$ mp&lt;br /&gt;
$ mf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/Adding_a_new_device&amp;diff=171</id>
		<title>Mainline:Broadcom Kona/Adding a new device</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/Adding_a_new_device&amp;diff=171"/>
		<updated>2026-08-23T19:52:19Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page goes over the process of adding support for a Broadcom Kona device to the mainline Linux kernel.&lt;br /&gt;
&lt;br /&gt;
General outline of the process:&lt;br /&gt;
&lt;br /&gt;
* Get the downstream/vendor kernel source code&lt;br /&gt;
** Identify your device&#039;s board files&lt;br /&gt;
* Get the mainline kernel source code&lt;br /&gt;
* Add a DTS for your device based on values from downstream&lt;br /&gt;
* Build the kernel and flash it to the device&lt;br /&gt;
* Test it!&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In the mainline kernel, a device&#039;s components are described in a structure known as the [https://wiki.mainlining.org/wiki/Devicetree device tree] (or devicetree, as is the official spelling). Device trees are compiled into DTBs (device tree blobs) from DTS (device tree source) files.&lt;br /&gt;
&lt;br /&gt;
Adding support for a new device involves &#039;&#039;&#039;creating a DTS for that device&#039;&#039;&#039; - this is the process covered in this guide.&lt;br /&gt;
&lt;br /&gt;
Device trees appeared in the kernel around version 3.4, and didn&#039;t see widespread use in vendor kernels until a few LTS versions later. Before device trees, each device usually had a &#039;&#039;board file&#039;&#039; - a C file that contained structs with driver data and initialization functions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The downstream Kona kernels used board files.&#039;&#039;&#039; (They did have some partial DT support, but it was never used for any production devices.)&lt;br /&gt;
&lt;br /&gt;
== Kernel compilation toolchain ==&lt;br /&gt;
&lt;br /&gt;
To compile the kernel for the device, we will need a compiler toolchain for the ARM architecture.&lt;br /&gt;
&lt;br /&gt;
For convenience, we will use pmbootstrap (the postmarketOS build tool) with its envkernel.sh script, which handles toolchain setup automatically (everything is installed in a chroot managed by pmbootstrap, so no manual work needs to be done on the host system), and gives us the extra benefit of building a ready initramfs and rootfs image to boot with.&lt;br /&gt;
&lt;br /&gt;
=== mainline-tools setup ===&lt;br /&gt;
&lt;br /&gt;
[https://uart.sh serialuart] uses a convenience script that wraps around envkernel.sh and automates the setup process and most commonly used commands: [https://github.com/refractionware/linux/tree/meta/mt mainline-tools].&lt;br /&gt;
&lt;br /&gt;
This script sets up a couple of aliases, including:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mb&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;mainline-build&amp;lt;/code&amp;gt;) - shorthand for &amp;lt;code&amp;gt;make -j$(nproc)&amp;lt;/code&amp;gt;, used to build the kernel.&lt;br /&gt;
* &amp;lt;code&amp;gt;mp&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;mainline-package&amp;lt;/code&amp;gt;) - creates a boot.img image for the built kernel.&lt;br /&gt;
* &amp;lt;code&amp;gt;mf&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;mainline-flash&amp;lt;/code&amp;gt;) - flashes the boot.img generated with &amp;lt;code&amp;gt;mp&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;mbp&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;mainline-build-package&amp;lt;/code&amp;gt;) - updates the postmarketOS kernel package (&amp;lt;code&amp;gt;linux-postmarketos-brcm-kona&amp;lt;/code&amp;gt;) based on the build done with &amp;lt;code&amp;gt;mb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;msp&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;mainline-sideload-pkg&amp;lt;/code&amp;gt;) - sideloads the latest kernel package (needed to update modules).&lt;br /&gt;
&lt;br /&gt;
{{note|A note about kernel packaging:&lt;br /&gt;
&lt;br /&gt;
* boot.img only contains the kernel and built-in drivers (Y in defconfig).&lt;br /&gt;
* The kernel package (linux-postmarketos-brcm-kona) contains modules (M in defconfig).&lt;br /&gt;
&lt;br /&gt;
Flashing boot.img (&amp;lt;code&amp;gt;mp&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;mf&amp;lt;/code&amp;gt;) will only update built-in modules; to update non-built-in modules on the device, use &amp;lt;code&amp;gt;mbp&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;msp&amp;lt;/code&amp;gt; to sideload over USB (or regenerate the image with &amp;lt;code&amp;gt;pmbootstrap install&amp;lt;/code&amp;gt;).}}&lt;br /&gt;
&lt;br /&gt;
To set up that script, run the following commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell-session&amp;quot;&amp;gt;&lt;br /&gt;
$ mkdir ~/code&lt;br /&gt;
$ cd ~/code&lt;br /&gt;
$ git clone https://gitlab.postmarketos.org/postmarketOS/pmbootstrap  # git clone is needed for envkernel.sh, even if you already have pmbootstrap installed&lt;br /&gt;
$ wget https://raw.githubusercontent.com/refractionware/linux/refs/heads/meta/mt/mt.sh&lt;br /&gt;
$ source ~/code/mt.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you start a session, run &amp;lt;code&amp;gt;source ~/code/mt.sh&amp;lt;/code&amp;gt; to enable mainline-tools.&lt;br /&gt;
&lt;br /&gt;
== Getting the mainline kernel source ==&lt;br /&gt;
&lt;br /&gt;
Broadcom Kona development happens in a close-to-mainline fork hosted on GitHub: [https://github.com/bcm-kona-mainline/linux bcm-kona-mainline/linux]&lt;br /&gt;
&lt;br /&gt;
Clone the kernel from GitHub:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell-session&amp;quot;&amp;gt;&lt;br /&gt;
$ cd ~/code&lt;br /&gt;
$ git clone https://github.com/bcm-kona-mainline/linux&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Getting the downstream kernel source ==&lt;br /&gt;
&lt;br /&gt;
You will need to reference the downstream kernel for your device for the porting process; most likely someone has uploaded it to GitHub (look for android_kernel_(vendor)_(codename) repos).&lt;br /&gt;
&lt;br /&gt;
Once you have the kernel downloaded, find the &#039;&#039;&#039;defconfig&#039;&#039;&#039; and &#039;&#039;&#039;board file&#039;&#039;&#039; for your device.&lt;br /&gt;
&lt;br /&gt;
* The defconfig is in &amp;lt;code&amp;gt;arch/arm/configs&amp;lt;/code&amp;gt;; if you got a CyanogenMod/LineageOS kernel, look for a &amp;lt;code&amp;gt;cyanogenmod_XXX_defconfig&amp;lt;/code&amp;gt;; otherwise, there should be a config with a name like &amp;lt;code&amp;gt;bcmXXXXX_codename_revXX_defconfig&amp;lt;/code&amp;gt; (pick the highest revision number).&lt;br /&gt;
* The board config is in &amp;lt;code&amp;gt;arch/arm/mach-PLATFORM/board-ss_CODENAME.c&amp;lt;/code&amp;gt; (or just &amp;lt;code&amp;gt;board-CODENAME.c&amp;lt;/code&amp;gt;), where PLATFORM is &amp;lt;code&amp;gt;capri&amp;lt;/code&amp;gt; for BCM218xx, &amp;lt;code&amp;gt;rhea&amp;lt;/code&amp;gt; for BCM21654, &amp;lt;code&amp;gt;hawaii&amp;lt;/code&amp;gt; for BCM21664 and &amp;lt;code&amp;gt;java&amp;lt;/code&amp;gt; for BCM23550.&lt;br /&gt;
&lt;br /&gt;
== Adding a device package in postmarketOS ==&lt;br /&gt;
&lt;br /&gt;
Run &amp;lt;code&amp;gt;pmbootstrap init&amp;lt;/code&amp;gt;. When asked for the device, provide the vendor and codename.&lt;br /&gt;
&lt;br /&gt;
* If you&#039;re asked to create a new device, follow the [https://wiki.postmarketos.org/wiki/Porting_to_a_new_device Porting Guide], using the &amp;lt;code&amp;gt;linux-postmarketos-brcm-kona&amp;lt;/code&amp;gt; mainline kernel package.&lt;br /&gt;
* If this ends up selecting an existing downstream/archived device, you&#039;ll need to update the device package - see [https://gitlab.postmarketos.org/postmarketOS/pmaports/-/merge_requests/8981/diffs?commit_id=fc2eb16282fe1b9dea7fb010533568899fad1bcb the commit doing this for samsung-baffinlite] as an example.&lt;br /&gt;
&lt;br /&gt;
== Adding a DTS for your device ==&lt;br /&gt;
&lt;br /&gt;
The DTS describes the hardware of the device. DTS files for Broadcom-based devices are located in &amp;lt;code&amp;gt;arch/arm/boot/dts/broadcom&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{hint|&amp;lt;code&amp;gt;[https://github.com/bcm-kona-mainline/linux/blob/kona/7.1/arch/arm/boot/dts/broadcom/bcm23550-samsung-baffinlite.dts bcm23550-samsung-baffinlite.dts]&amp;lt;/code&amp;gt; is a good reference point for DTSes for all Kona chips.}}&lt;br /&gt;
&lt;br /&gt;
Create a new file in &amp;lt;code&amp;gt;arch/arm/boot/dts/broadcom&amp;lt;/code&amp;gt; for your device with the filename &amp;lt;code&amp;gt;(soc)-(vendor)-(codename).dts&amp;lt;/code&amp;gt; - for example, for a BCM21664 device with the codename samsung-kylepro, the filename will be &amp;lt;code&amp;gt;bcm21664-samsung-kylepro.dts&amp;lt;/code&amp;gt;. Start from the following template (remove the comments when you&#039;re done):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
// SPDX-License-Identifier: GPL-2.0-only&lt;br /&gt;
/*&lt;br /&gt;
 * Common device tree for Samsung Galaxy Trend Plus/S Duos 2&lt;br /&gt;
 * (kylepro/kyleprods).&lt;br /&gt;
 *&lt;br /&gt;
 * Copyright (c) 2026 Your Name &amp;lt;youremail@example.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/dts-v1/;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;dt-bindings/gpio/gpio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dt-bindings/input/input.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dt-bindings/leds/common.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Depending on which SoC your device uses, change the following to:&lt;br /&gt;
// BCM2166x - &amp;quot;bcm21664.dtsi&amp;quot;&lt;br /&gt;
// BCM23550 - &amp;quot;bcm23550.dtsi&amp;quot;&lt;br /&gt;
// BCM281x5 - &amp;quot;bcm11351.dtsi&amp;quot;&lt;br /&gt;
#include &amp;quot;bcm21664.dtsi&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/ {&lt;br /&gt;
	model = &amp;quot;Vendor Codename (MODEL-NUMBER)&amp;quot;;&lt;br /&gt;
	compatible = &amp;quot;vendor,codename&amp;quot;, &amp;quot;brcm,bcm21664&amp;quot;;  // remember to change the SoC compatible&lt;br /&gt;
	chassis-type = &amp;quot;handset&amp;quot;;  // usually &amp;quot;handset&amp;quot; (smartphone) or &amp;quot;tablet&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	memory@80000000 {&lt;br /&gt;
		device_type = &amp;quot;memory&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;0x80000000 0x30000000&amp;gt;; /* 768 MB; CHANGEME */&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	reserved-memory {&lt;br /&gt;
		#address-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
		#size-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
		ranges;&lt;br /&gt;
&lt;br /&gt;
		coprocessor_mem: coprocessor-mem@80000000 {&lt;br /&gt;
			reg = &amp;lt;0x80000000 0x1e00000&amp;gt;;&lt;br /&gt;
			no-map;&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		secure_mem: secure-mem@9d800000 {&lt;br /&gt;
			reg = &amp;lt;0x9d800000 0x100000&amp;gt;;&lt;br /&gt;
			no-map;&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		mobicore: mobicore@9d900000 {&lt;br /&gt;
			reg = &amp;lt;0x9d900000 0x300000&amp;gt;;&lt;br /&gt;
			no-map;&lt;br /&gt;
		};&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, open &amp;lt;code&amp;gt;arch/arm/boot/dts/broadcom/Makefile&amp;lt;/code&amp;gt;, and locate the following section:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;makefile&amp;quot;&amp;gt;&lt;br /&gt;
dtb-$(CONFIG_ARCH_BCM_MOBILE) += \&lt;br /&gt;
	bcm28155-ap.dtb \&lt;br /&gt;
	bcm21664-garnet.dtb \&lt;br /&gt;
	bcm21664-samsung-kylepro.dtb \&lt;br /&gt;
	bcm23550-samsung-baffinlite.dtb \&lt;br /&gt;
	bcm23550-sparrow.dtb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add your DTS to the list, changing &amp;lt;code&amp;gt;.dts&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;.dtb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Filling out the memory node ===&lt;br /&gt;
&lt;br /&gt;
To get the memory size, as well as reserved regions, run the following command under a downstream kernel (e.g. under TWRP):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell-session&amp;quot;&amp;gt;&lt;br /&gt;
$ cat /proc/iomem&lt;br /&gt;
81e00000-afffffff : System RAM&lt;br /&gt;
  81e08000-823ec57b : Kernel code&lt;br /&gt;
  8251c000-826d72ff : Kernel data&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
From the above, the RAM would begin at &amp;lt;code&amp;gt;81e00000&amp;lt;/code&amp;gt; and have a size of &amp;lt;code&amp;gt;(0xafffffff+1) - 0x81e00000 = &amp;lt;b&amp;gt;0x2e200000&amp;lt;/b&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{todo|A lot of Samsung device kernels seem to be configured with a mem base of 0x81e00000, but in ATAG_MEM the 0x80000000 - 0x81e00000 chunk is also reported as a separate memory block as well.&lt;br /&gt;
&lt;br /&gt;
This memory region is likely used for storing coprocessor firmware blobs and communication with the modem and other coprocessors (see {{downstream|baffinlite|arch/arm/mach-java/include/mach/comms/platform_mconfig_hawaii.h}}).&lt;br /&gt;
&lt;br /&gt;
While from initial testing it seems safe to use with the modem disabled, I have included a &amp;lt;code&amp;gt;coprocessor_mem&amp;lt;/code&amp;gt; block in the DTS snippet above to block out this region.&lt;br /&gt;
&lt;br /&gt;
TODO - figure out how to print ATAGs without serial. Typically they get printed over UART by the bootloader right before loading the kernel.}}&lt;br /&gt;
&lt;br /&gt;
=== UART ===&lt;br /&gt;
&lt;br /&gt;
UART/serial is most notably used for sending debug logs over USB, but is also used for talking to the Bluetooth and GPS chip.&lt;br /&gt;
&lt;br /&gt;
Check the downstream board file; look for a struct of type &amp;lt;code&amp;gt;plat_serial8250_port&amp;lt;/code&amp;gt;. It should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static struct plat_serial8250_port hawaii_uart_platform_data[] = {&lt;br /&gt;
	HAWAII_8250PORT(UART0, UARTB_PERI_CLK_NAME_STR, 48000000,&lt;br /&gt;
					&amp;quot;bluetooth&amp;quot;, NULL),&lt;br /&gt;
	HAWAII_8250PORT(UART1, UARTB2_PERI_CLK_NAME_STR, 26000000,&lt;br /&gt;
				&amp;quot;gps&amp;quot;, &amp;amp;power_save_enable),&lt;br /&gt;
	HAWAII_8250PORT(UART2, UARTB3_PERI_CLK_NAME_STR, 26000000,&lt;br /&gt;
				&amp;quot;console&amp;quot;, NULL),&lt;br /&gt;
	{&lt;br /&gt;
		.flags = 0,&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the numbers in the XXX_8250PORT macros; these represent the clock frequency.&lt;br /&gt;
&lt;br /&gt;
Also note the names given to the ports; there are a hint for what the ports are used for. As seen above, the layout is usually - uartb for Bluetooth, uartb2 for GPS and uartb3 for serial console.&lt;br /&gt;
&lt;br /&gt;
At the bottom of your DTS, add (change clock frequencies to match board file):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&amp;amp;uartb {&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
	clock-frequency = &amp;lt;48000000&amp;gt;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;amp;uartb2 {&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
	clock-frequency = &amp;lt;26000000&amp;gt;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;amp;uartb3 {&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
	clock-frequency = &amp;lt;26000000&amp;gt;;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PMIC ===&lt;br /&gt;
&lt;br /&gt;
Most Kona devices use BCM590xx series PMICs: BCM59054 for BCM21664/BCM23550, BCM59056 for BCM281xx and BCM59039 for BCM21654. The only known exceptions are the GT-I9150 (BCM281xx device with a BCM59054 and SMB358 for charging) and the GT-S6810 (Dialog DA2083).&lt;br /&gt;
&lt;br /&gt;
The PMIC is connected to a separate PMIC I2C bus (or BSC, as Broadcom calls their &amp;quot;I2C-compatible&amp;quot; bus):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;pmu_bsc {&lt;br /&gt;
	clock-frequency = &amp;lt;3400000&amp;gt;; /* 3.2mhz? Downstream refers to this as a HS bus, but it doesn&#039;t give any speed information other than that. */&lt;br /&gt;
&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;pmbsc_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	pmu: pmu@8 {&lt;br /&gt;
		compatible = &amp;quot;brcm,bcm59054&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;0x08&amp;gt;;&lt;br /&gt;
		interrupt-parent = &amp;lt;&amp;amp;gpio&amp;gt;;&lt;br /&gt;
		interrupts = &amp;lt;29 IRQ_TYPE_EDGE_FALLING&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
		regulators {&lt;br /&gt;
			/* ... */&lt;br /&gt;
		};&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PMIC configuration is stored in a separate file in downstream, beginning with &amp;lt;code&amp;gt;board-bcm59xxx-(...).c&amp;lt;/code&amp;gt; (same directory as the board file). Every regulator is described in this file, in &amp;lt;code&amp;gt;regulator_init_data&amp;lt;/code&amp;gt; structs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__weak struct regulator_consumer_supply rf_supply[] = {&lt;br /&gt;
	{.supply = &amp;quot;rf&amp;quot;},&lt;br /&gt;
};&lt;br /&gt;
static struct regulator_init_data bcm59xxx_rfldo_data = {&lt;br /&gt;
	.constraints = {&lt;br /&gt;
			.name = &amp;quot;rfldo&amp;quot;,&lt;br /&gt;
			.min_uV = 1300000,&lt;br /&gt;
			.max_uV = 3300000,&lt;br /&gt;
			.valid_ops_mask = REGULATOR_CHANGE_STATUS |&lt;br /&gt;
			REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,&lt;br /&gt;
			.valid_modes_mask = REGULATOR_MODE_NORMAL |&lt;br /&gt;
			REGULATOR_MODE_IDLE |&lt;br /&gt;
			REGULATOR_MODE_STANDBY,&lt;br /&gt;
			.always_on = 0,&lt;br /&gt;
			.initial_mode = REGULATOR_MODE_STANDBY,&lt;br /&gt;
			},&lt;br /&gt;
	.num_consumer_supplies = ARRAY_SIZE(rf_supply),&lt;br /&gt;
	.consumer_supplies = rf_supply,&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Equivalent DTS fragment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
			rfldo_reg: rfldo {&lt;br /&gt;
				regulator-min-microvolt = &amp;lt;1300000&amp;gt;;&lt;br /&gt;
				regulator-max-microvolt = &amp;lt;3300000&amp;gt;;&lt;br /&gt;
				regulator-always-on;&lt;br /&gt;
				/* regulator-allowed-modes = &amp;lt;0x2 0x4 0x8&amp;gt;; */ /* NORMAL, IDLE, STANDBY */&lt;br /&gt;
				/* regulator-initial-mode = &amp;lt;0x8&amp;gt;; */ /* REGULATOR_MODE_STANDBY */&lt;br /&gt;
			};&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Repeat for all regulator types; see DT bindings for reference ([https://github.com/bcm-kona-mainline/linux/blob/kona/7.1/Documentation/devicetree/bindings/regulator/brcm%2Cbcm59054.yaml BCM59054], [https://github.com/bcm-kona-mainline/linux/blob/kona/7.1/Documentation/devicetree/bindings/regulator/brcm%2Cbcm59056.yaml BCM59056]).&lt;br /&gt;
&lt;br /&gt;
=== SDIO/Storage ===&lt;br /&gt;
&lt;br /&gt;
SDIO is used for internal storage, the SD card and WiFi.&lt;br /&gt;
&lt;br /&gt;
In the downstream board file, look for &amp;lt;code&amp;gt;sdio_platform_cfg&amp;lt;/code&amp;gt; structs. Here&#039;s an example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
static struct sdio_platform_cfg hawaii_sdio_param[] = {&lt;br /&gt;
	{&lt;br /&gt;
		.id = 0,&lt;br /&gt;
		.data_pullup = 0,&lt;br /&gt;
		.cd_gpio = SD_CARDDET_GPIO_PIN,&lt;br /&gt;
		.devtype = SDIO_DEV_TYPE_SDMMC,&lt;br /&gt;
		.flags = KONA_SDIO_FLAGS_DEVICE_REMOVABLE,&lt;br /&gt;
		.peri_clk_name = &amp;quot;sdio1_clk&amp;quot;,&lt;br /&gt;
		.ahb_clk_name = &amp;quot;sdio1_ahb_clk&amp;quot;,&lt;br /&gt;
		.sleep_clk_name = &amp;quot;sdio1_sleep_clk&amp;quot;,&lt;br /&gt;
		.peri_clk_rate = 48000000,&lt;br /&gt;
		/*The SD card regulator*/&lt;br /&gt;
		.vddo_regulator_name = &amp;quot;vdd_sdio&amp;quot;,&lt;br /&gt;
		/*The SD controller regulator*/&lt;br /&gt;
		.vddsdxc_regulator_name = &amp;quot;vdd_sdxc&amp;quot;,&lt;br /&gt;
		.configure_sdio_pullup = configure_sdio_pullup,&lt;br /&gt;
	},&lt;br /&gt;
	{&lt;br /&gt;
		.id = 1,&lt;br /&gt;
		.data_pullup = 0,&lt;br /&gt;
		.is_8bit = 1,&lt;br /&gt;
		.devtype = SDIO_DEV_TYPE_EMMC,&lt;br /&gt;
		.flags = KONA_SDIO_FLAGS_DEVICE_NON_REMOVABLE ,&lt;br /&gt;
		.peri_clk_name = &amp;quot;sdio2_clk&amp;quot;,&lt;br /&gt;
		.ahb_clk_name = &amp;quot;sdio2_ahb_clk&amp;quot;,&lt;br /&gt;
		.sleep_clk_name = &amp;quot;sdio2_sleep_clk&amp;quot;,&lt;br /&gt;
		.peri_clk_rate = 52000000,&lt;br /&gt;
		},&lt;br /&gt;
	{&lt;br /&gt;
		.id = 2,&lt;br /&gt;
		.data_pullup = 0,&lt;br /&gt;
		.devtype = SDIO_DEV_TYPE_WIFI,&lt;br /&gt;
		.flags = KONA_SDIO_FLAGS_DEVICE_REMOVABLE,&lt;br /&gt;
		.peri_clk_name = &amp;quot;sdio3_clk&amp;quot;,&lt;br /&gt;
		.ahb_clk_name = &amp;quot;sdio3_ahb_clk&amp;quot;,&lt;br /&gt;
		.sleep_clk_name = &amp;quot;sdio3_sleep_clk&amp;quot;,&lt;br /&gt;
		.peri_clk_rate = 48000000,&lt;br /&gt;
#ifdef CONFIG_BRCM_UNIFIED_DHD_SUPPORT&lt;br /&gt;
		.wifi_gpio = {&lt;br /&gt;
			.reset          = 3,&lt;br /&gt;
			.reg            = -1,&lt;br /&gt;
			.host_wake      = 74,&lt;br /&gt;
			.shutdown       = -1,&lt;br /&gt;
		},&lt;br /&gt;
		.register_status_notify = hawaii_wifi_status_register,&lt;br /&gt;
#endif&lt;br /&gt;
        },&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Things of note:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;.peri_clk_rate&amp;lt;/code&amp;gt; is equivalent to &amp;lt;code&amp;gt;max-frequency&amp;lt;/code&amp;gt; in DT;&lt;br /&gt;
* &amp;lt;code&amp;gt;.is_8bit = 1&amp;lt;/code&amp;gt; is equivalent to &amp;lt;code&amp;gt;bus-width = &amp;amp;lt;8&amp;amp;gt;&amp;lt;/code&amp;gt;;&lt;br /&gt;
* &amp;lt;code&amp;gt;.cd_gpio&amp;lt;/code&amp;gt; contains the card detect GPIO for the SD card slot. It is usually defined as a macro, the value is defined earlier in the board file. Here it&#039;s &amp;lt;code&amp;gt;91&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;.vddo_regulator_name&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.vddsdxc_regulator_name&amp;lt;/code&amp;gt; become &amp;lt;code&amp;gt;vmmc-supply&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;vqmmc-supply&amp;lt;/code&amp;gt; respectively. To find which regulator they are attached to, look up the names in your board file; you might find a struct like such: &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;struct regulator_consumer_supply sd_supply[] = {&lt;br /&gt;
	{.supply = &amp;quot;sdldo_uc&amp;quot;},&lt;br /&gt;
	REGULATOR_SUPPLY(&amp;quot;vddmmc&amp;quot;, &amp;quot;sdhci.3&amp;quot;), /* 0x3f1b0000.sdhci */&lt;br /&gt;
	{.supply = &amp;quot;vdd_sdio&amp;quot;},&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct regulator_consumer_supply sdx_supply[] = {&lt;br /&gt;
	{.supply = &amp;quot;sdxldo_uc&amp;quot;},&lt;br /&gt;
	REGULATOR_SUPPLY(&amp;quot;vddo&amp;quot;, &amp;quot;sdhci.3&amp;quot;), /* 0x3f1b0000.sdhci */&lt;br /&gt;
	{.supply = &amp;quot;vdd_sdxc&amp;quot;},&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 The first listed supply should show you the name of the BCM59xxx supply - in this case, &amp;lt;code&amp;gt;sdldo&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;sdxldo&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Equivalent mainline DTS:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* SD card */&lt;br /&gt;
&amp;amp;sdio1 {&lt;br /&gt;
	max-frequency = &amp;lt;48000000&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	cd-gpios = &amp;lt;&amp;amp;gpio 91 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)&amp;gt;;&lt;br /&gt;
	vmmc-supply = &amp;lt;&amp;amp;sdldo_reg&amp;gt;;&lt;br /&gt;
	vqmmc-supply = &amp;lt;&amp;amp;sdxldo_reg&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    /* NOTE: skip pinctrl here and in the other nodes for BCM28155, we don&#039;t have ready-made pinctrl definitions for it yet */&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;sd_width4_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/* Internal storage */&lt;br /&gt;
&amp;amp;sdio2 {&lt;br /&gt;
	max-frequency = &amp;lt;52000000&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	keep-power-in-suspend;&lt;br /&gt;
	non-removable;&lt;br /&gt;
	bus-width = &amp;lt;8&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;mmc0_width8_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/* WiFi */&lt;br /&gt;
&amp;amp;sdio3 {&lt;br /&gt;
	max-frequency = &amp;lt;48000000&amp;gt;;&lt;br /&gt;
    &lt;br /&gt;
	#address-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
	#size-cells = &amp;lt;0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;mmc1_width4_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // NOTE: Non-removable is hardcoded for the WiFi SDIO in the downstream driver, even if the board file claims it&#039;s removable.&lt;br /&gt;
	keep-power-in-suspend;&lt;br /&gt;
	non-removable;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== I2C/BSC ===&lt;br /&gt;
&lt;br /&gt;
Most sensors, as well as the touchscreen, are connected over I2C. Broadcom SoCs actually have an I2C-compatible bus called BSC.&lt;br /&gt;
&lt;br /&gt;
Finding exactly which sensors are used is a bit difficult, because board files tend to have data for a lot of sensors that is unused. You will need to look for sections guarded with &amp;lt;code&amp;gt;#ifdef CONFIG_...&amp;lt;/code&amp;gt;; for the config option values, reference the downstream defconfig file for your device.&lt;br /&gt;
&lt;br /&gt;
In general, it&#039;s best to look through the defconfig first and find all the relevant options for sensors (look up keywords like SENSOR, PROXIMITY, ACCEL, MAG, LIGHT, TOUCH, INPUT...).&lt;br /&gt;
&lt;br /&gt;
(Alternatively, if you have a Samsung device, reference [https://docs.google.com/spreadsheets/d/1NioX9a2vgbEcO_Zs9COUFO-n3a2Rqf1JWWU1cfsktLM/edit?gid=0#gid=0 the spreadsheet].)&lt;br /&gt;
&lt;br /&gt;
In the board file, look for &amp;lt;code&amp;gt;i2c_board_info&amp;lt;/code&amp;gt; structs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if defined(CONFIG_SENSORS_BMM050)&lt;br /&gt;
#define BMA2X2_SLAVE_ADDR  0x10&lt;br /&gt;
#else&lt;br /&gt;
#define BMA2X2_SLAVE_ADDR  0x18&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
static struct i2c_board_info __initdata bsc3_i2c_boardinfo[] =&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
#if defined(CONFIG_SENSORS_BMC150)&lt;br /&gt;
#if defined(CONFIG_SENSORS_BMA2X2)&lt;br /&gt;
        {&lt;br /&gt;
		I2C_BOARD_INFO(&amp;quot;bma2x2&amp;quot;, BMA2X2_SLAVE_ADDR),&lt;br /&gt;
		.platform_data = &amp;amp;bss_bma2x2,&lt;br /&gt;
        },&lt;br /&gt;
#endif&lt;br /&gt;
#if defined(CONFIG_SENSORS_BMM050)&lt;br /&gt;
        {&lt;br /&gt;
		I2C_BOARD_INFO(&amp;quot;bmm050&amp;quot;, 0x12),&lt;br /&gt;
		.platform_data = &amp;amp;bss_bmm050,&lt;br /&gt;
        },&lt;br /&gt;
#endif        &lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if defined  (CONFIG_SENSORS_HSCDTD006A) || defined(CONFIG_SENSORS_HSCDTD008A) &lt;br /&gt;
	{&lt;br /&gt;
		I2C_BOARD_INFO(&amp;quot;hscd_i2c&amp;quot;, 0x0c),&lt;br /&gt;
		.platform_data = &amp;amp;hscd_i2c_platform_data,               &lt;br /&gt;
	},&lt;br /&gt;
 #endif&lt;br /&gt;
&lt;br /&gt;
#if defined(CONFIG_SENSORS_GP2AP002)&lt;br /&gt;
        {&lt;br /&gt;
             I2C_BOARD_INFO(&amp;quot;gp2ap002&amp;quot;,0x44),&lt;br /&gt;
             .platform_data = &amp;amp;gp2ap002_platform_data,&lt;br /&gt;
        }&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do a &amp;lt;code&amp;gt;grep -iR&amp;lt;/code&amp;gt; with the codename in &amp;lt;code&amp;gt;drivers&amp;lt;/code&amp;gt; in mainline to see if you can spot a driver for the sensor you want to add. Many sensors from that era are already supported in mainline. You can look at other device trees (&amp;lt;code&amp;gt;arch/arm/boot/dts&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;arch/arm64/boot/dts&amp;lt;/code&amp;gt;) as well as DT bindings (&amp;lt;code&amp;gt;Documentation/devicetree/bindings&amp;lt;/code&amp;gt;) to figure out how to add them to your DTS.&lt;br /&gt;
&lt;br /&gt;
For the exact values to use in DT, you&#039;ll have to look at the &amp;lt;code&amp;gt;platform_data&amp;lt;/code&amp;gt; struct, and sometimes at the driver for the peripheral (which you can usually find by grepping the downstream source code for the model number/driver name).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&amp;amp;bsc3 {&lt;br /&gt;
	clock-frequency = &amp;lt;400000&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    // NOTE: again, pinctrl only applies to BCM21664/BCM23550 at the moment&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;bsc3_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	magnetometer@c {&lt;br /&gt;
		compatible = &amp;quot;alps,hscdtd008a&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;0x0c&amp;gt;;&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	accel@18 {&lt;br /&gt;
		compatible = &amp;quot;bosch,bma254&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;0x18&amp;gt;;&lt;br /&gt;
        &lt;br /&gt;
		/* ... */&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	proximity@44 {&lt;br /&gt;
		compatible = &amp;quot;sharp,gp2ap002s00f&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;0x44&amp;gt;;&lt;br /&gt;
        &lt;br /&gt;
		/* ... */&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== USB ===&lt;br /&gt;
&lt;br /&gt;
USB comprises of 3 parts:&lt;br /&gt;
&lt;br /&gt;
* The USB OTG controller (usbotg node);&lt;br /&gt;
* The USB PHY (usbphy node);&lt;br /&gt;
* The USB mode switch (not all devices - BCM59039 devices don&#039;t seem to be paired with a switch).&lt;br /&gt;
&lt;br /&gt;
Commonly used switches include the FSA9480/9485, TSUxxxx and RTxxxx. Look them up in your defconfig (keywords: FSA, TSU, RT).&lt;br /&gt;
&lt;br /&gt;
On Samsung devices, the switches are often connected over I2C-GPIO (which is an I2C bus bitbanged over GPIO pins).  Example from baffinlite:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define GPIO_FSA9485_I2C_SDA 113&lt;br /&gt;
#define GPIO_FSA9485_I2C_SCL 114&lt;br /&gt;
#define GPIO_FSA9485_INT 56&lt;br /&gt;
&lt;br /&gt;
/* ... */&lt;br /&gt;
&lt;br /&gt;
static struct i2c_board_info  __initdata micro_usb_i2c_devices_info[]  = {&lt;br /&gt;
	{&lt;br /&gt;
		I2C_BOARD_INFO(&amp;quot;fsa9485&amp;quot;, 0x4A &amp;gt;&amp;gt; 1),&lt;br /&gt;
		.platform_data = &amp;amp;fsa9485_pdata,&lt;br /&gt;
		.irq = gpio_to_irq(GPIO_FSA9485_INT),&lt;br /&gt;
	},&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
static struct i2c_gpio_platform_data fsa_i2c_gpio_data={&lt;br /&gt;
	.sda_pin = GPIO_FSA9485_I2C_SDA,&lt;br /&gt;
	.scl_pin = GPIO_FSA9485_I2C_SCL,&lt;br /&gt;
	.udelay	 = 2,&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note - &amp;lt;code&amp;gt;0x4A &amp;gt;&amp;gt; 1&amp;lt;/code&amp;gt; means a bit shift, you can paste it into the Python interpreter and it will give you the value (&amp;lt;code&amp;gt;hex(0x4A &amp;gt;&amp;gt; 1)&amp;lt;/code&amp;gt; gives &amp;lt;code&amp;gt;0x25&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
In mainline, this becomes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
/ {&lt;br /&gt;
/* (add this under the / node ) */&lt;br /&gt;
&lt;br /&gt;
    /* ... */&lt;br /&gt;
&lt;br /&gt;
	/* USB switch */&lt;br /&gt;
	i2c-musb {&lt;br /&gt;
		#address-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
		#size-cells = &amp;lt;0&amp;gt;;&lt;br /&gt;
		compatible = &amp;quot;i2c-gpio&amp;quot;;&lt;br /&gt;
		sda-gpios = &amp;lt;&amp;amp;gpio 113 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)&amp;gt;;&lt;br /&gt;
		scl-gpios = &amp;lt;&amp;amp;gpio 114 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)&amp;gt;;&lt;br /&gt;
		i2c-gpio,delay-us = &amp;lt;2&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
		musb@25 {&lt;br /&gt;
			compatible = &amp;quot;fcs,fsa9480&amp;quot;;&lt;br /&gt;
			reg = &amp;lt;0x25&amp;gt;;&lt;br /&gt;
			interrupt-parent = &amp;lt;&amp;amp;gpio&amp;gt;;&lt;br /&gt;
			interrupts = &amp;lt;56 IRQ_TYPE_LEVEL_HIGH&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
			connector {&lt;br /&gt;
				compatible = &amp;quot;samsung,usb-connector-11pin&amp;quot;,&lt;br /&gt;
					     &amp;quot;usb-b-connector&amp;quot;;&lt;br /&gt;
				label = &amp;quot;micro-USB&amp;quot;;&lt;br /&gt;
				type = &amp;quot;micro&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
				ports {&lt;br /&gt;
					#address-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
					#size-cells = &amp;lt;0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
					port@0 {&lt;br /&gt;
						reg = &amp;lt;0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
						muic_to_usb: endpoint {&lt;br /&gt;
							remote-endpoint = &amp;lt;&amp;amp;usb_to_muic&amp;gt;;&lt;br /&gt;
						};&lt;br /&gt;
					};&lt;br /&gt;
				};&lt;br /&gt;
			};&lt;br /&gt;
&lt;br /&gt;
		};&lt;br /&gt;
	};&lt;br /&gt;
    /* ... */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the switch, you can add the remaining USB nodes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&amp;amp;usbotg {&lt;br /&gt;
	vusb_d-supply = &amp;lt;&amp;amp;usbldo_reg&amp;gt;;&lt;br /&gt;
	vusb_a-supply = &amp;lt;&amp;amp;iosr1_reg&amp;gt;;&lt;br /&gt;
	vbus-supply = &amp;lt;&amp;amp;vbus_reg&amp;gt;;&lt;br /&gt;
	dr_mode = &amp;quot;otg&amp;quot;;&lt;br /&gt;
	role-switch-default-mode = &amp;quot;peripheral&amp;quot;;&lt;br /&gt;
	usb-role-switch;&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // if your device has no switch, drop the port node below&lt;br /&gt;
	port {&lt;br /&gt;
		usb_to_muic: endpoint {&lt;br /&gt;
			remote-endpoint = &amp;lt;&amp;amp;muic_to_usb&amp;gt;;&lt;br /&gt;
		};&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;amp;usbphy {&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== WiFi and Bluetooth ===&lt;br /&gt;
&lt;br /&gt;
Most Broadcom devices use Broadcom WiFi/Bluetooth chips from the BCM43xx series. (Look up BCM43 in your defconfig, or reference downstream kernel dmesg for the exact model.)&lt;br /&gt;
&lt;br /&gt;
The below examples are for BCM4330. If you have another chip, you can grep for it in the mainline kernel (&amp;lt;code&amp;gt;arch/arm/boot/dts&amp;lt;/code&amp;gt;) and see what compatibles are used by other devices.&lt;br /&gt;
&lt;br /&gt;
The Bluetooth chip goes under the UART bus that was labeled as &amp;quot;bluetooth&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&amp;amp;uartb {&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
	clock-frequency = &amp;lt;48000000&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	bluetooth {&lt;br /&gt;
		compatible = &amp;quot;brcm,bcm4330-bt&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		shutdown-gpios = &amp;lt;&amp;amp;gpio 28 GPIO_ACTIVE_HIGH&amp;gt;;&lt;br /&gt;
		device-wakeup-gpios = &amp;lt;&amp;amp;gpio 32 GPIO_ACTIVE_HIGH&amp;gt;;&lt;br /&gt;
		host-wakeup-gpios = &amp;lt;&amp;amp;gpio 72 GPIO_ACTIVE_HIGH&amp;gt;;&lt;br /&gt;
		reset-gpios = &amp;lt;&amp;amp;gpio 71 GPIO_ACTIVE_LOW&amp;gt;;&lt;br /&gt;
		interrupt-parent = &amp;lt;&amp;amp;gpio&amp;gt;;&lt;br /&gt;
		interrupts = &amp;lt;72 IRQ_TYPE_EDGE_FALLING&amp;gt;;&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get the GPIOs:&lt;br /&gt;
&lt;br /&gt;
* Look for &amp;lt;code&amp;gt;bcmbt_platform_data&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;.bt_wake_gpio&amp;lt;/code&amp;gt; becomes &amp;lt;code&amp;gt;device-wakeup-gpios&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;.host_wake_gpio&amp;lt;/code&amp;gt; becomes &amp;lt;code&amp;gt;host-wakeup-gpios&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Look for &amp;lt;code&amp;gt;bcmbt_rfkill_platform_data&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;.vreg_gpio&amp;lt;/code&amp;gt; becomes &amp;lt;code&amp;gt;shutdown-gpios&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;.n_reset_gpio&amp;lt;/code&amp;gt; becomes &amp;lt;code&amp;gt;reset-gpios&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For WiFi, add the following under the &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; node:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
/ {&lt;br /&gt;
    /* ... */&lt;br /&gt;
    &lt;br /&gt;
	/* GPIO regulator for WiFi */&lt;br /&gt;
	wl_reg: regulator-gpio-wlan {&lt;br /&gt;
		compatible = &amp;quot;regulator-fixed&amp;quot;;&lt;br /&gt;
		regulator-name = &amp;quot;WL_REG_ON&amp;quot;;&lt;br /&gt;
		regulator-min-microvolt = &amp;lt;3000000&amp;gt;;&lt;br /&gt;
		regulator-max-microvolt = &amp;lt;3000000&amp;gt;;&lt;br /&gt;
		startup-delay-us = &amp;lt;100000&amp;gt;;&lt;br /&gt;
		gpio = &amp;lt;&amp;amp;gpio 3 GPIO_ACTIVE_HIGH&amp;gt;;&lt;br /&gt;
		enable-active-high;&lt;br /&gt;
	};&lt;br /&gt;
    &lt;br /&gt;
    /* ... */&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Get the GPIO from &amp;lt;code&amp;gt;board_wifi_info&amp;lt;/code&amp;gt;, member &amp;lt;code&amp;gt;.wl_reset_gpio&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Then, update the SDIO node for WiFi:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
/* WiFi */&lt;br /&gt;
&amp;amp;sdio3 {&lt;br /&gt;
	max-frequency = &amp;lt;48000000&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	/* Actually a regulator for the WiFi chip */&lt;br /&gt;
	vmmc-supply = &amp;lt;&amp;amp;wl_reg&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	#address-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
	#size-cells = &amp;lt;0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;mmc1_width4_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	keep-power-in-suspend;&lt;br /&gt;
	non-removable;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	wifi@1 {&lt;br /&gt;
		compatible = &amp;quot;brcm,bcm4330-fmac&amp;quot;, &amp;quot;brcm,bcm4329-fmac&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
		interrupt-parent = &amp;lt;&amp;amp;gpio&amp;gt;;&lt;br /&gt;
		interrupts = &amp;lt;74 IRQ_TYPE_EDGE_FALLING&amp;gt;;&lt;br /&gt;
		interrupt-names = &amp;quot;host-wake&amp;quot;;&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Get the interrupt from &amp;lt;code&amp;gt;board_wifi_info&amp;lt;/code&amp;gt;, member &amp;lt;code&amp;gt;.host_wake_gpio&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== GPIO keys ===&lt;br /&gt;
&lt;br /&gt;
Many Samsung devices use GPIO-based keys for the volume up/down and home keys. (The power button is handled by the PMIC, and the touchkeys (menu/back next to home button) are usually handled by the touchscreen).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define GPIO_KEYS_SETTINGS { \&lt;br /&gt;
      { KEY_VOLUMEUP,9, 1, &amp;quot;VOLUMEUP&amp;quot;, EV_KEY, 0, 64}, \&lt;br /&gt;
	{ KEY_HOME, 10, 1, &amp;quot;HOME&amp;quot;, EV_KEY, 0, 64},	\&lt;br /&gt;
      { KEY_VOLUMEDOWN,11, 1, &amp;quot;VOLUMEDOWN&amp;quot;, EV_KEY, 0, 64}, \&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)&lt;br /&gt;
static struct gpio_keys_button board_gpio_keys[] = GPIO_KEYS_SETTINGS;&lt;br /&gt;
/* ... */&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Equivalent DT fragment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
/ {&lt;br /&gt;
    /* ... */&lt;br /&gt;
&lt;br /&gt;
	/* Buttons */&lt;br /&gt;
	gpio-keys {&lt;br /&gt;
		compatible = &amp;quot;gpio-keys&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		key-volume-up {&lt;br /&gt;
			label = &amp;quot;Volume Up&amp;quot;;&lt;br /&gt;
			gpios = &amp;lt;&amp;amp;gpio 9 GPIO_ACTIVE_LOW&amp;gt;;&lt;br /&gt;
			linux,code = &amp;lt;KEY_VOLUMEUP&amp;gt;;&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		key-home {&lt;br /&gt;
			label = &amp;quot;Home&amp;quot;;&lt;br /&gt;
			gpios = &amp;lt;&amp;amp;gpio 10 GPIO_ACTIVE_LOW&amp;gt;;&lt;br /&gt;
			linux,code = &amp;lt;KEY_HOMEPAGE&amp;gt;;&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		key-volume-down {&lt;br /&gt;
			label = &amp;quot;Volume Down&amp;quot;;&lt;br /&gt;
			gpios = &amp;lt;&amp;amp;gpio 11 GPIO_ACTIVE_LOW&amp;gt;;&lt;br /&gt;
			linux,code = &amp;lt;KEY_VOLUMEDOWN&amp;gt;;&lt;br /&gt;
		};&lt;br /&gt;
	};&lt;br /&gt;
    &lt;br /&gt;
    /* ... */&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Keypad ===&lt;br /&gt;
&lt;br /&gt;
{{note|Keypad is only added for BCM21664/BCM23550 at the moment; it&#039;s most likely the same for BCM28155, just a matter of adding the right node like [https://github.com/bcm-kona-mainline/linux/commit/86a15664bdfe457bcd994b2ae72f722509259b53 in the equivalent bcm21664-common.dtsi commit].}}&lt;br /&gt;
&lt;br /&gt;
Some devices use the built-in keypad peripheral for volume up/down keys. If you have &amp;lt;code&amp;gt;CONFIG_KEYBOARD_BCM&amp;lt;/code&amp;gt; enabled in downstream defconfig, look for &amp;lt;code&amp;gt;bcm_keymap&amp;lt;/code&amp;gt; in your board file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#ifdef CONFIG_KEYBOARD_BCM&lt;br /&gt;
static struct bcm_keymap hawaii_keymap[] = {&lt;br /&gt;
	{BCM_KEY_ROW_0, BCM_KEY_COL_0, &amp;quot;unused&amp;quot;, 0},&lt;br /&gt;
	{BCM_KEY_ROW_0, BCM_KEY_COL_1, &amp;quot;Vol Down Key&amp;quot;, KEY_VOLUMEDOWN},&lt;br /&gt;
	{BCM_KEY_ROW_0, BCM_KEY_COL_2, &amp;quot;unused&amp;quot;, 0},&lt;br /&gt;
	{BCM_KEY_ROW_0, BCM_KEY_COL_3, &amp;quot;Vol Up Key&amp;quot;, KEY_VOLUMEUP},&lt;br /&gt;
	{BCM_KEY_ROW_0, BCM_KEY_COL_4, &amp;quot;unused&amp;quot;, 0},&lt;br /&gt;
	{BCM_KEY_ROW_0, BCM_KEY_COL_5, &amp;quot;unused&amp;quot;, 0},&lt;br /&gt;
    /* ... */&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
static struct bcm_keypad_platform_info hawaii_keypad_data = {&lt;br /&gt;
	.row_num = 1,&lt;br /&gt;
	.col_num = 5,&lt;br /&gt;
	.keymap = hawaii_keymap,&lt;br /&gt;
	.bcm_keypad_base = (void *)__iomem HW_IO_PHYS_TO_VIRT(KEYPAD_BASE_ADDR),&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Equivalent DTS:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&amp;amp;keypad {&lt;br /&gt;
	keypad,num-rows = &amp;lt;1&amp;gt;;&lt;br /&gt;
	keypad,num-columns = &amp;lt;5&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	linux,keymap = &amp;lt;MATRIX_KEY(0x00, 0x01, KEY_VOLUMEDOWN)&amp;gt;,&lt;br /&gt;
		       &amp;lt;MATRIX_KEY(0x00, 0x03, KEY_VOLUMEUP)&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Building the kernel ==&lt;br /&gt;
&lt;br /&gt;
To apply the pmOS Broadcom Kona defconfig:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell-session&amp;quot;&amp;gt;&lt;br /&gt;
$ make bcmkona_pmos_defconfig&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To build the kernel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell-session&amp;quot;&amp;gt;&lt;br /&gt;
$ make -j$(nproc)&lt;br /&gt;
-- or, with mainline-tools: --&lt;br /&gt;
$ mb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have mainline-tools, you can flash the kernel with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell-session&amp;quot;&amp;gt;&lt;br /&gt;
$ mp&lt;br /&gt;
$ mf&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/Adding_a_new_device&amp;diff=170</id>
		<title>Mainline:Broadcom Kona/Adding a new device</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/Adding_a_new_device&amp;diff=170"/>
		<updated>2026-08-23T14:10:52Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page goes over the process of adding support for a Broadcom Kona device to the mainline Linux kernel.&lt;br /&gt;
&lt;br /&gt;
General outline of the process:&lt;br /&gt;
&lt;br /&gt;
* Get the downstream/vendor kernel source code&lt;br /&gt;
** Identify your device&#039;s board files&lt;br /&gt;
* Get the mainline kernel source code&lt;br /&gt;
* Add a DTS for your device based on values from downstream&lt;br /&gt;
* Build the kernel and flash it to the device&lt;br /&gt;
* Test it!&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In the mainline kernel, a device&#039;s components are described in a structure known as the [https://wiki.mainlining.org/wiki/Devicetree device tree] (or devicetree, as is the official spelling). Device trees are compiled into DTBs (device tree blobs) from DTS (device tree source) files.&lt;br /&gt;
&lt;br /&gt;
Adding support for a new device involves &#039;&#039;&#039;creating a DTS for that device&#039;&#039;&#039; - this is the process covered in this guide.&lt;br /&gt;
&lt;br /&gt;
Device trees appeared in the kernel around version 3.4, and didn&#039;t see widespread use in vendor kernels until a few LTS versions later. Before device trees, each device usually had a &#039;&#039;board file&#039;&#039; - a C file that contained structs with driver data and initialization functions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The downstream Kona kernels used board files.&#039;&#039;&#039; (They did have some partial DT support, but it was never used for any production devices.)&lt;br /&gt;
&lt;br /&gt;
== Kernel compilation toolchain ==&lt;br /&gt;
&lt;br /&gt;
To compile the kernel for the device, we will need a compiler toolchain for the ARM architecture.&lt;br /&gt;
&lt;br /&gt;
For convenience, we will use pmbootstrap (the postmarketOS build tool) with its envkernel.sh script, which handles toolchain setup automatically (everything is installed in a chroot managed by pmbootstrap, so no manual work needs to be done on the host system), and gives us the extra benefit of building a ready initramfs and rootfs image to boot with.&lt;br /&gt;
&lt;br /&gt;
=== mainline-tools setup ===&lt;br /&gt;
&lt;br /&gt;
[https://uart.sh serialuart] uses a convenience script that wraps around envkernel.sh and automates the setup process and most commonly used commands: [https://github.com/refractionware/linux/tree/meta/mt mainline-tools].&lt;br /&gt;
&lt;br /&gt;
This script sets up a couple of aliases, including:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;mb&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;mainline-build&amp;lt;/code&amp;gt;) - shorthand for &amp;lt;code&amp;gt;make -j$(nproc)&amp;lt;/code&amp;gt;, used to build the kernel.&lt;br /&gt;
* &amp;lt;code&amp;gt;mp&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;mainline-package&amp;lt;/code&amp;gt;) - creates a boot.img image for the built kernel.&lt;br /&gt;
* &amp;lt;code&amp;gt;mf&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;mainline-flash&amp;lt;/code&amp;gt;) - flashes the boot.img generated with &amp;lt;code&amp;gt;mp&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;mbp&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;mainline-build-package&amp;lt;/code&amp;gt;) - updates the postmarketOS kernel package (&amp;lt;code&amp;gt;linux-postmarketos-brcm-kona&amp;lt;/code&amp;gt;) based on the build done with &amp;lt;code&amp;gt;mb&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;msp&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;mainline-sideload-pkg&amp;lt;/code&amp;gt;) - sideloads the latest kernel package (needed to update modules).&lt;br /&gt;
&lt;br /&gt;
{{note|A note about kernel packaging:&lt;br /&gt;
&lt;br /&gt;
* boot.img only contains the kernel and built-in drivers (Y in defconfig).&lt;br /&gt;
* The kernel package (linux-postmarketos-brcm-kona) contains modules (M in defconfig).&lt;br /&gt;
&lt;br /&gt;
Flashing boot.img (&amp;lt;code&amp;gt;mp&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;mf&amp;lt;/code&amp;gt;) will only update built-in modules; to update non-built-in modules on the device, use &amp;lt;code&amp;gt;mbp&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;msp&amp;lt;/code&amp;gt; to sideload over USB (or regenerate the image with &amp;lt;code&amp;gt;pmbootstrap install&amp;lt;/code&amp;gt;).}}&lt;br /&gt;
&lt;br /&gt;
To set up that script, run the following commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell-session&amp;quot;&amp;gt;&lt;br /&gt;
$ mkdir ~/code&lt;br /&gt;
$ cd ~/code&lt;br /&gt;
$ git clone https://gitlab.postmarketos.org/postmarketOS/pmbootstrap  # git clone is needed for envkernel.sh, even if you already have pmbootstrap installed&lt;br /&gt;
$ wget https://raw.githubusercontent.com/refractionware/linux/refs/heads/meta/mt/mt.sh&lt;br /&gt;
$ source ~/code/mt.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you start a session, run &amp;lt;code&amp;gt;source ~/code/mt.sh&amp;lt;/code&amp;gt; to enable mainline-tools.&lt;br /&gt;
&lt;br /&gt;
== Getting the mainline kernel source ==&lt;br /&gt;
&lt;br /&gt;
Broadcom Kona development happens in a close-to-mainline fork hosted on GitHub: [https://github.com/bcm-kona-mainline/linux bcm-kona-mainline/linux]&lt;br /&gt;
&lt;br /&gt;
Clone the kernel from GitHub:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell-session&amp;quot;&amp;gt;&lt;br /&gt;
$ cd ~/code&lt;br /&gt;
$ git clone https://github.com/bcm-kona-mainline/linux&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Getting the downstream kernel source ==&lt;br /&gt;
&lt;br /&gt;
You will need to reference the downstream kernel for your device for the porting process; most likely someone has uploaded it to GitHub (look for android_kernel_(vendor)_(codename) repos).&lt;br /&gt;
&lt;br /&gt;
Once you have the kernel downloaded, find the &#039;&#039;&#039;defconfig&#039;&#039;&#039; and &#039;&#039;&#039;board file&#039;&#039;&#039; for your device.&lt;br /&gt;
&lt;br /&gt;
* The defconfig is in &amp;lt;code&amp;gt;arch/arm/configs&amp;lt;/code&amp;gt;; if you got a CyanogenMod/LineageOS kernel, look for a &amp;lt;code&amp;gt;cyanogenmod_XXX_defconfig&amp;lt;/code&amp;gt;; otherwise, there should be a config with a name like &amp;lt;code&amp;gt;bcmXXXXX_codename_revXX_defconfig&amp;lt;/code&amp;gt; (pick the highest revision number).&lt;br /&gt;
* The board config is in &amp;lt;code&amp;gt;arch/arm/mach-PLATFORM/board-ss_CODENAME.c&amp;lt;/code&amp;gt; (or just &amp;lt;code&amp;gt;board-CODENAME.c&amp;lt;/code&amp;gt;), where PLATFORM is &amp;lt;code&amp;gt;capri&amp;lt;/code&amp;gt; for BCM218xx, &amp;lt;code&amp;gt;rhea&amp;lt;/code&amp;gt; for BCM21654, &amp;lt;code&amp;gt;hawaii&amp;lt;/code&amp;gt; for BCM21664 and &amp;lt;code&amp;gt;java&amp;lt;/code&amp;gt; for BCM23550.&lt;br /&gt;
&lt;br /&gt;
== Adding a DTS for your device ==&lt;br /&gt;
&lt;br /&gt;
The DTS describes the hardware of the device. DTS files for Broadcom-based devices are located in &amp;lt;code&amp;gt;arch/arm/boot/dts/broadcom&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{hint|&amp;lt;code&amp;gt;[https://github.com/bcm-kona-mainline/linux/blob/kona/7.1/arch/arm/boot/dts/broadcom/bcm23550-samsung-baffinlite.dts bcm23550-samsung-baffinlite.dts]&amp;lt;/code&amp;gt; is a good reference point for DTSes for all Kona chips.}}&lt;br /&gt;
&lt;br /&gt;
Create a new file in &amp;lt;code&amp;gt;arch/arm/boot/dts/broadcom&amp;lt;/code&amp;gt; for your device with the filename &amp;lt;code&amp;gt;(soc)-(vendor)-(codename).dts&amp;lt;/code&amp;gt; - for example, for a BCM21664 device with the codename samsung-kylepro, the filename will be &amp;lt;code&amp;gt;bcm21664-samsung-kylepro.dts&amp;lt;/code&amp;gt;. Start from the following template (remove the comments when you&#039;re done):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
// SPDX-License-Identifier: GPL-2.0-only&lt;br /&gt;
/*&lt;br /&gt;
 * Common device tree for Samsung Galaxy Trend Plus/S Duos 2&lt;br /&gt;
 * (kylepro/kyleprods).&lt;br /&gt;
 *&lt;br /&gt;
 * Copyright (c) 2026 Your Name &amp;lt;youremail@example.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/dts-v1/;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;dt-bindings/gpio/gpio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dt-bindings/input/input.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dt-bindings/leds/common.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Depending on which SoC your device uses, change the following to:&lt;br /&gt;
// BCM2166x - &amp;quot;bcm21664.dtsi&amp;quot;&lt;br /&gt;
// BCM23550 - &amp;quot;bcm23550.dtsi&amp;quot;&lt;br /&gt;
// BCM281x5 - &amp;quot;bcm11351.dtsi&amp;quot;&lt;br /&gt;
#include &amp;quot;bcm21664.dtsi&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/ {&lt;br /&gt;
	model = &amp;quot;Vendor Codename (MODEL-NUMBER)&amp;quot;;&lt;br /&gt;
	compatible = &amp;quot;vendor,codename&amp;quot;, &amp;quot;brcm,bcm21664&amp;quot;;  // remember to change the SoC compatible&lt;br /&gt;
	chassis-type = &amp;quot;handset&amp;quot;;  // usually &amp;quot;handset&amp;quot; (smartphone) or &amp;quot;tablet&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	memory@80000000 {&lt;br /&gt;
		device_type = &amp;quot;memory&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;0x80000000 0x30000000&amp;gt;; /* 768 MB; CHANGEME */&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	reserved-memory {&lt;br /&gt;
		#address-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
		#size-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
		ranges;&lt;br /&gt;
&lt;br /&gt;
		coprocessor_mem: coprocessor-mem@80000000 {&lt;br /&gt;
			reg = &amp;lt;0x80000000 0x1e00000&amp;gt;;&lt;br /&gt;
			no-map;&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		secure_mem: secure-mem@9d800000 {&lt;br /&gt;
			reg = &amp;lt;0x9d800000 0x100000&amp;gt;;&lt;br /&gt;
			no-map;&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		mobicore: mobicore@9d900000 {&lt;br /&gt;
			reg = &amp;lt;0x9d900000 0x300000&amp;gt;;&lt;br /&gt;
			no-map;&lt;br /&gt;
		};&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, open &amp;lt;code&amp;gt;arch/arm/boot/dts/broadcom/Makefile&amp;lt;/code&amp;gt;, and locate the following section:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;makefile&amp;quot;&amp;gt;&lt;br /&gt;
dtb-$(CONFIG_ARCH_BCM_MOBILE) += \&lt;br /&gt;
	bcm28155-ap.dtb \&lt;br /&gt;
	bcm21664-garnet.dtb \&lt;br /&gt;
	bcm21664-samsung-kylepro.dtb \&lt;br /&gt;
	bcm23550-samsung-baffinlite.dtb \&lt;br /&gt;
	bcm23550-sparrow.dtb&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add your DTS to the list, changing &amp;lt;code&amp;gt;.dts&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;.dtb&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Filling out the memory node ===&lt;br /&gt;
&lt;br /&gt;
To get the memory size, as well as reserved regions, run the following command under a downstream kernel (e.g. under TWRP):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell-session&amp;quot;&amp;gt;&lt;br /&gt;
$ cat /proc/iomem&lt;br /&gt;
81e00000-afffffff : System RAM&lt;br /&gt;
  81e08000-823ec57b : Kernel code&lt;br /&gt;
  8251c000-826d72ff : Kernel data&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
From the above, the RAM would begin at &amp;lt;code&amp;gt;81e00000&amp;lt;/code&amp;gt; and have a size of &amp;lt;code&amp;gt;(0xafffffff+1) - 0x81e00000 = &amp;lt;b&amp;gt;0x2e200000&amp;lt;/b&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{todo|A lot of Samsung device kernels seem to be configured with a mem base of 0x81e00000, but in ATAG_MEM the 0x80000000 - 0x81e00000 chunk is also reported as a separate memory block as well.&lt;br /&gt;
&lt;br /&gt;
This memory region is likely used for storing coprocessor firmware blobs and communication with the modem and other coprocessors (see {{downstream|baffinlite|arch/arm/mach-java/include/mach/comms/platform_mconfig_hawaii.h}}).&lt;br /&gt;
&lt;br /&gt;
While from initial testing it seems safe to use with the modem disabled, I have included a &amp;lt;code&amp;gt;coprocessor_mem&amp;lt;/code&amp;gt; block in the DTS snippet above to block out this region.&lt;br /&gt;
&lt;br /&gt;
TODO - figure out how to print ATAGs without serial. Typically they get printed over UART by the bootloader right before loading the kernel.}}&lt;br /&gt;
&lt;br /&gt;
=== UART ===&lt;br /&gt;
&lt;br /&gt;
UART/serial is most notably used for sending debug logs over USB, but is also used for talking to the Bluetooth and GPS chip.&lt;br /&gt;
&lt;br /&gt;
Check the downstream board file; look for a struct of type &amp;lt;code&amp;gt;plat_serial8250_port&amp;lt;/code&amp;gt;. It should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static struct plat_serial8250_port hawaii_uart_platform_data[] = {&lt;br /&gt;
	HAWAII_8250PORT(UART0, UARTB_PERI_CLK_NAME_STR, 48000000,&lt;br /&gt;
					&amp;quot;bluetooth&amp;quot;, NULL),&lt;br /&gt;
	HAWAII_8250PORT(UART1, UARTB2_PERI_CLK_NAME_STR, 26000000,&lt;br /&gt;
				&amp;quot;gps&amp;quot;, &amp;amp;power_save_enable),&lt;br /&gt;
	HAWAII_8250PORT(UART2, UARTB3_PERI_CLK_NAME_STR, 26000000,&lt;br /&gt;
				&amp;quot;console&amp;quot;, NULL),&lt;br /&gt;
	{&lt;br /&gt;
		.flags = 0,&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the numbers in the XXX_8250PORT macros; these represent the clock frequency.&lt;br /&gt;
&lt;br /&gt;
Also note the names given to the ports; there are a hint for what the ports are used for. As seen above, the layout is usually - uartb for Bluetooth, uartb2 for GPS and uartb3 for serial console.&lt;br /&gt;
&lt;br /&gt;
At the bottom of your DTS, add (change clock frequencies to match board file):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&amp;amp;uartb {&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
	clock-frequency = &amp;lt;48000000&amp;gt;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;amp;uartb2 {&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
	clock-frequency = &amp;lt;26000000&amp;gt;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;amp;uartb3 {&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
	clock-frequency = &amp;lt;26000000&amp;gt;;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PMIC ===&lt;br /&gt;
&lt;br /&gt;
Most Kona devices use BCM590xx series PMICs: BCM59054 for BCM21664/BCM23550, BCM59056 for BCM281xx and BCM59039 for BCM21654. The only known exceptions are the GT-I9150 (BCM281xx device with a BCM59054 and SMB358 for charging) and the GT-S6810 (Dialog DA2083).&lt;br /&gt;
&lt;br /&gt;
The PMIC is connected to a separate PMIC I2C bus (or BSC, as Broadcom calls their &amp;quot;I2C-compatible&amp;quot; bus):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;pmu_bsc {&lt;br /&gt;
	clock-frequency = &amp;lt;3400000&amp;gt;; /* 3.2mhz? Downstream refers to this as a HS bus, but it doesn&#039;t give any speed information other than that. */&lt;br /&gt;
&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;pmbsc_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	pmu: pmu@8 {&lt;br /&gt;
		compatible = &amp;quot;brcm,bcm59054&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;0x08&amp;gt;;&lt;br /&gt;
		interrupt-parent = &amp;lt;&amp;amp;gpio&amp;gt;;&lt;br /&gt;
		interrupts = &amp;lt;29 IRQ_TYPE_EDGE_FALLING&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
		regulators {&lt;br /&gt;
			/* ... */&lt;br /&gt;
		};&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PMIC configuration is stored in a separate file in downstream, beginning with &amp;lt;code&amp;gt;board-bcm59xxx-(...).c&amp;lt;/code&amp;gt; (same directory as the board file). Every regulator is described in this file, in &amp;lt;code&amp;gt;regulator_init_data&amp;lt;/code&amp;gt; structs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__weak struct regulator_consumer_supply rf_supply[] = {&lt;br /&gt;
	{.supply = &amp;quot;rf&amp;quot;},&lt;br /&gt;
};&lt;br /&gt;
static struct regulator_init_data bcm59xxx_rfldo_data = {&lt;br /&gt;
	.constraints = {&lt;br /&gt;
			.name = &amp;quot;rfldo&amp;quot;,&lt;br /&gt;
			.min_uV = 1300000,&lt;br /&gt;
			.max_uV = 3300000,&lt;br /&gt;
			.valid_ops_mask = REGULATOR_CHANGE_STATUS |&lt;br /&gt;
			REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,&lt;br /&gt;
			.valid_modes_mask = REGULATOR_MODE_NORMAL |&lt;br /&gt;
			REGULATOR_MODE_IDLE |&lt;br /&gt;
			REGULATOR_MODE_STANDBY,&lt;br /&gt;
			.always_on = 0,&lt;br /&gt;
			.initial_mode = REGULATOR_MODE_STANDBY,&lt;br /&gt;
			},&lt;br /&gt;
	.num_consumer_supplies = ARRAY_SIZE(rf_supply),&lt;br /&gt;
	.consumer_supplies = rf_supply,&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Equivalent DTS fragment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
			rfldo_reg: rfldo {&lt;br /&gt;
				regulator-min-microvolt = &amp;lt;1300000&amp;gt;;&lt;br /&gt;
				regulator-max-microvolt = &amp;lt;3300000&amp;gt;;&lt;br /&gt;
				regulator-always-on;&lt;br /&gt;
				/* regulator-allowed-modes = &amp;lt;0x2 0x4 0x8&amp;gt;; */ /* NORMAL, IDLE, STANDBY */&lt;br /&gt;
				/* regulator-initial-mode = &amp;lt;0x8&amp;gt;; */ /* REGULATOR_MODE_STANDBY */&lt;br /&gt;
			};&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Repeat for all regulator types; see DT bindings for reference ([https://github.com/bcm-kona-mainline/linux/blob/kona/7.1/Documentation/devicetree/bindings/regulator/brcm%2Cbcm59054.yaml BCM59054], [https://github.com/bcm-kona-mainline/linux/blob/kona/7.1/Documentation/devicetree/bindings/regulator/brcm%2Cbcm59056.yaml BCM59056]).&lt;br /&gt;
&lt;br /&gt;
=== SDIO/Storage ===&lt;br /&gt;
&lt;br /&gt;
SDIO is used for internal storage, the SD card and WiFi.&lt;br /&gt;
&lt;br /&gt;
In the downstream board file, look for &amp;lt;code&amp;gt;sdio_platform_cfg&amp;lt;/code&amp;gt; structs. Here&#039;s an example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
static struct sdio_platform_cfg hawaii_sdio_param[] = {&lt;br /&gt;
	{&lt;br /&gt;
		.id = 0,&lt;br /&gt;
		.data_pullup = 0,&lt;br /&gt;
		.cd_gpio = SD_CARDDET_GPIO_PIN,&lt;br /&gt;
		.devtype = SDIO_DEV_TYPE_SDMMC,&lt;br /&gt;
		.flags = KONA_SDIO_FLAGS_DEVICE_REMOVABLE,&lt;br /&gt;
		.peri_clk_name = &amp;quot;sdio1_clk&amp;quot;,&lt;br /&gt;
		.ahb_clk_name = &amp;quot;sdio1_ahb_clk&amp;quot;,&lt;br /&gt;
		.sleep_clk_name = &amp;quot;sdio1_sleep_clk&amp;quot;,&lt;br /&gt;
		.peri_clk_rate = 48000000,&lt;br /&gt;
		/*The SD card regulator*/&lt;br /&gt;
		.vddo_regulator_name = &amp;quot;vdd_sdio&amp;quot;,&lt;br /&gt;
		/*The SD controller regulator*/&lt;br /&gt;
		.vddsdxc_regulator_name = &amp;quot;vdd_sdxc&amp;quot;,&lt;br /&gt;
		.configure_sdio_pullup = configure_sdio_pullup,&lt;br /&gt;
	},&lt;br /&gt;
	{&lt;br /&gt;
		.id = 1,&lt;br /&gt;
		.data_pullup = 0,&lt;br /&gt;
		.is_8bit = 1,&lt;br /&gt;
		.devtype = SDIO_DEV_TYPE_EMMC,&lt;br /&gt;
		.flags = KONA_SDIO_FLAGS_DEVICE_NON_REMOVABLE ,&lt;br /&gt;
		.peri_clk_name = &amp;quot;sdio2_clk&amp;quot;,&lt;br /&gt;
		.ahb_clk_name = &amp;quot;sdio2_ahb_clk&amp;quot;,&lt;br /&gt;
		.sleep_clk_name = &amp;quot;sdio2_sleep_clk&amp;quot;,&lt;br /&gt;
		.peri_clk_rate = 52000000,&lt;br /&gt;
		},&lt;br /&gt;
	{&lt;br /&gt;
		.id = 2,&lt;br /&gt;
		.data_pullup = 0,&lt;br /&gt;
		.devtype = SDIO_DEV_TYPE_WIFI,&lt;br /&gt;
		.flags = KONA_SDIO_FLAGS_DEVICE_REMOVABLE,&lt;br /&gt;
		.peri_clk_name = &amp;quot;sdio3_clk&amp;quot;,&lt;br /&gt;
		.ahb_clk_name = &amp;quot;sdio3_ahb_clk&amp;quot;,&lt;br /&gt;
		.sleep_clk_name = &amp;quot;sdio3_sleep_clk&amp;quot;,&lt;br /&gt;
		.peri_clk_rate = 48000000,&lt;br /&gt;
#ifdef CONFIG_BRCM_UNIFIED_DHD_SUPPORT&lt;br /&gt;
		.wifi_gpio = {&lt;br /&gt;
			.reset          = 3,&lt;br /&gt;
			.reg            = -1,&lt;br /&gt;
			.host_wake      = 74,&lt;br /&gt;
			.shutdown       = -1,&lt;br /&gt;
		},&lt;br /&gt;
		.register_status_notify = hawaii_wifi_status_register,&lt;br /&gt;
#endif&lt;br /&gt;
        },&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Things of note:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;.peri_clk_rate&amp;lt;/code&amp;gt; is equivalent to &amp;lt;code&amp;gt;max-frequency&amp;lt;/code&amp;gt; in DT;&lt;br /&gt;
* &amp;lt;code&amp;gt;.is_8bit = 1&amp;lt;/code&amp;gt; is equivalent to &amp;lt;code&amp;gt;bus-width = &amp;amp;lt;8&amp;amp;gt;&amp;lt;/code&amp;gt;;&lt;br /&gt;
* &amp;lt;code&amp;gt;.cd_gpio&amp;lt;/code&amp;gt; contains the card detect GPIO for the SD card slot. It is usually defined as a macro, the value is defined earlier in the board file. Here it&#039;s &amp;lt;code&amp;gt;91&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;.vddo_regulator_name&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;.vddsdxc_regulator_name&amp;lt;/code&amp;gt; become &amp;lt;code&amp;gt;vmmc-supply&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;vqmmc-supply&amp;lt;/code&amp;gt; respectively. To find which regulator they are attached to, look up the names in your board file; you might find a struct like such: &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;struct regulator_consumer_supply sd_supply[] = {&lt;br /&gt;
	{.supply = &amp;quot;sdldo_uc&amp;quot;},&lt;br /&gt;
	REGULATOR_SUPPLY(&amp;quot;vddmmc&amp;quot;, &amp;quot;sdhci.3&amp;quot;), /* 0x3f1b0000.sdhci */&lt;br /&gt;
	{.supply = &amp;quot;vdd_sdio&amp;quot;},&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct regulator_consumer_supply sdx_supply[] = {&lt;br /&gt;
	{.supply = &amp;quot;sdxldo_uc&amp;quot;},&lt;br /&gt;
	REGULATOR_SUPPLY(&amp;quot;vddo&amp;quot;, &amp;quot;sdhci.3&amp;quot;), /* 0x3f1b0000.sdhci */&lt;br /&gt;
	{.supply = &amp;quot;vdd_sdxc&amp;quot;},&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 The first listed supply should show you the name of the BCM59xxx supply - in this case, &amp;lt;code&amp;gt;sdldo&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;sdxldo&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Equivalent mainline DTS:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* SD card */&lt;br /&gt;
&amp;amp;sdio1 {&lt;br /&gt;
	max-frequency = &amp;lt;48000000&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	cd-gpios = &amp;lt;&amp;amp;gpio 91 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)&amp;gt;;&lt;br /&gt;
	vmmc-supply = &amp;lt;&amp;amp;sdldo_reg&amp;gt;;&lt;br /&gt;
	vqmmc-supply = &amp;lt;&amp;amp;sdxldo_reg&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    /* NOTE: skip pinctrl here and in the other nodes for BCM28155, we don&#039;t have ready-made pinctrl definitions for it yet */&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;sd_width4_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/* Internal storage */&lt;br /&gt;
&amp;amp;sdio2 {&lt;br /&gt;
	max-frequency = &amp;lt;52000000&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	keep-power-in-suspend;&lt;br /&gt;
	non-removable;&lt;br /&gt;
	bus-width = &amp;lt;8&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;mmc0_width8_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/* WiFi */&lt;br /&gt;
&amp;amp;sdio3 {&lt;br /&gt;
	max-frequency = &amp;lt;48000000&amp;gt;;&lt;br /&gt;
    &lt;br /&gt;
	#address-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
	#size-cells = &amp;lt;0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;mmc1_width4_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // NOTE: Non-removable is hardcoded for the WiFi SDIO in the downstream driver, even if the board file claims it&#039;s removable.&lt;br /&gt;
	keep-power-in-suspend;&lt;br /&gt;
	non-removable;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== I2C/BSC ===&lt;br /&gt;
&lt;br /&gt;
Most sensors, as well as the touchscreen, are connected over I2C. Broadcom SoCs actually have an I2C-compatible bus called BSC.&lt;br /&gt;
&lt;br /&gt;
Finding exactly which sensors are used is a bit difficult, because board files tend to have data for a lot of sensors that is unused. You will need to look for sections guarded with &amp;lt;code&amp;gt;#ifdef CONFIG_...&amp;lt;/code&amp;gt;; for the config option values, reference the downstream defconfig file for your device.&lt;br /&gt;
&lt;br /&gt;
In general, it&#039;s best to look through the defconfig first and find all the relevant options for sensors (look up keywords like SENSOR, PROXIMITY, ACCEL, MAG, LIGHT, TOUCH, INPUT...).&lt;br /&gt;
&lt;br /&gt;
(Alternatively, if you have a Samsung device, reference [https://docs.google.com/spreadsheets/d/1NioX9a2vgbEcO_Zs9COUFO-n3a2Rqf1JWWU1cfsktLM/edit?gid=0#gid=0 the spreadsheet].)&lt;br /&gt;
&lt;br /&gt;
In the board file, look for &amp;lt;code&amp;gt;i2c_board_info&amp;lt;/code&amp;gt; structs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if defined(CONFIG_SENSORS_BMM050)&lt;br /&gt;
#define BMA2X2_SLAVE_ADDR  0x10&lt;br /&gt;
#else&lt;br /&gt;
#define BMA2X2_SLAVE_ADDR  0x18&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
static struct i2c_board_info __initdata bsc3_i2c_boardinfo[] =&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
#if defined(CONFIG_SENSORS_BMC150)&lt;br /&gt;
#if defined(CONFIG_SENSORS_BMA2X2)&lt;br /&gt;
        {&lt;br /&gt;
		I2C_BOARD_INFO(&amp;quot;bma2x2&amp;quot;, BMA2X2_SLAVE_ADDR),&lt;br /&gt;
		.platform_data = &amp;amp;bss_bma2x2,&lt;br /&gt;
        },&lt;br /&gt;
#endif&lt;br /&gt;
#if defined(CONFIG_SENSORS_BMM050)&lt;br /&gt;
        {&lt;br /&gt;
		I2C_BOARD_INFO(&amp;quot;bmm050&amp;quot;, 0x12),&lt;br /&gt;
		.platform_data = &amp;amp;bss_bmm050,&lt;br /&gt;
        },&lt;br /&gt;
#endif        &lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if defined  (CONFIG_SENSORS_HSCDTD006A) || defined(CONFIG_SENSORS_HSCDTD008A) &lt;br /&gt;
	{&lt;br /&gt;
		I2C_BOARD_INFO(&amp;quot;hscd_i2c&amp;quot;, 0x0c),&lt;br /&gt;
		.platform_data = &amp;amp;hscd_i2c_platform_data,               &lt;br /&gt;
	},&lt;br /&gt;
 #endif&lt;br /&gt;
&lt;br /&gt;
#if defined(CONFIG_SENSORS_GP2AP002)&lt;br /&gt;
        {&lt;br /&gt;
             I2C_BOARD_INFO(&amp;quot;gp2ap002&amp;quot;,0x44),&lt;br /&gt;
             .platform_data = &amp;amp;gp2ap002_platform_data,&lt;br /&gt;
        }&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do a &amp;lt;code&amp;gt;grep -iR&amp;lt;/code&amp;gt; with the codename in &amp;lt;code&amp;gt;drivers&amp;lt;/code&amp;gt; in mainline to see if you can spot a driver for the sensor you want to add. Many sensors from that era are already supported in mainline. You can look at other device trees (&amp;lt;code&amp;gt;arch/arm/boot/dts&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;arch/arm64/boot/dts&amp;lt;/code&amp;gt;) as well as DT bindings (&amp;lt;code&amp;gt;Documentation/devicetree/bindings&amp;lt;/code&amp;gt;) to figure out how to add them to your DTS.&lt;br /&gt;
&lt;br /&gt;
For the exact values to use in DT, you&#039;ll have to look at the &amp;lt;code&amp;gt;platform_data&amp;lt;/code&amp;gt; struct, and sometimes at the driver for the peripheral (which you can usually find by grepping the downstream source code for the model number/driver name).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&amp;amp;bsc3 {&lt;br /&gt;
	clock-frequency = &amp;lt;400000&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    // NOTE: again, pinctrl only applies to BCM21664/BCM23550 at the moment&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;bsc3_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	magnetometer@c {&lt;br /&gt;
		compatible = &amp;quot;alps,hscdtd008a&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;0x0c&amp;gt;;&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	accel@18 {&lt;br /&gt;
		compatible = &amp;quot;bosch,bma254&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;0x18&amp;gt;;&lt;br /&gt;
        &lt;br /&gt;
		/* ... */&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	proximity@44 {&lt;br /&gt;
		compatible = &amp;quot;sharp,gp2ap002s00f&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;0x44&amp;gt;;&lt;br /&gt;
        &lt;br /&gt;
		/* ... */&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== USB ===&lt;br /&gt;
&lt;br /&gt;
USB comprises of 3 parts:&lt;br /&gt;
&lt;br /&gt;
* The USB OTG controller (usbotg node);&lt;br /&gt;
* The USB PHY (usbphy node);&lt;br /&gt;
* The USB mode switch (not all devices - BCM59039 devices don&#039;t seem to be paired with a switch).&lt;br /&gt;
&lt;br /&gt;
Commonly used switches include the FSA9480/9485, TSUxxxx and RTxxxx. Look them up in your defconfig (keywords: FSA, TSU, RT).&lt;br /&gt;
&lt;br /&gt;
On Samsung devices, the switches are often connected over I2C-GPIO (which is an I2C bus bitbanged over GPIO pins).  Example from baffinlite:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define GPIO_FSA9485_I2C_SDA 113&lt;br /&gt;
#define GPIO_FSA9485_I2C_SCL 114&lt;br /&gt;
#define GPIO_FSA9485_INT 56&lt;br /&gt;
&lt;br /&gt;
/* ... */&lt;br /&gt;
&lt;br /&gt;
static struct i2c_board_info  __initdata micro_usb_i2c_devices_info[]  = {&lt;br /&gt;
	{&lt;br /&gt;
		I2C_BOARD_INFO(&amp;quot;fsa9485&amp;quot;, 0x4A &amp;gt;&amp;gt; 1),&lt;br /&gt;
		.platform_data = &amp;amp;fsa9485_pdata,&lt;br /&gt;
		.irq = gpio_to_irq(GPIO_FSA9485_INT),&lt;br /&gt;
	},&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
static struct i2c_gpio_platform_data fsa_i2c_gpio_data={&lt;br /&gt;
	.sda_pin = GPIO_FSA9485_I2C_SDA,&lt;br /&gt;
	.scl_pin = GPIO_FSA9485_I2C_SCL,&lt;br /&gt;
	.udelay	 = 2,&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note - &amp;lt;code&amp;gt;0x4A &amp;gt;&amp;gt; 1&amp;lt;/code&amp;gt; means a bit shift, you can paste it into the Python interpreter and it will give you the value (&amp;lt;code&amp;gt;hex(0x4A &amp;gt;&amp;gt; 1)&amp;lt;/code&amp;gt; gives &amp;lt;code&amp;gt;0x25&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
In mainline, this becomes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
/ {&lt;br /&gt;
/* (add this under the / node ) */&lt;br /&gt;
&lt;br /&gt;
    /* ... */&lt;br /&gt;
&lt;br /&gt;
	/* USB switch */&lt;br /&gt;
	i2c-musb {&lt;br /&gt;
		#address-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
		#size-cells = &amp;lt;0&amp;gt;;&lt;br /&gt;
		compatible = &amp;quot;i2c-gpio&amp;quot;;&lt;br /&gt;
		sda-gpios = &amp;lt;&amp;amp;gpio 113 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)&amp;gt;;&lt;br /&gt;
		scl-gpios = &amp;lt;&amp;amp;gpio 114 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)&amp;gt;;&lt;br /&gt;
		i2c-gpio,delay-us = &amp;lt;2&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
		musb@25 {&lt;br /&gt;
			compatible = &amp;quot;fcs,fsa9480&amp;quot;;&lt;br /&gt;
			reg = &amp;lt;0x25&amp;gt;;&lt;br /&gt;
			interrupt-parent = &amp;lt;&amp;amp;gpio&amp;gt;;&lt;br /&gt;
			interrupts = &amp;lt;56 IRQ_TYPE_LEVEL_HIGH&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
			connector {&lt;br /&gt;
				compatible = &amp;quot;samsung,usb-connector-11pin&amp;quot;,&lt;br /&gt;
					     &amp;quot;usb-b-connector&amp;quot;;&lt;br /&gt;
				label = &amp;quot;micro-USB&amp;quot;;&lt;br /&gt;
				type = &amp;quot;micro&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
				ports {&lt;br /&gt;
					#address-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
					#size-cells = &amp;lt;0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
					port@0 {&lt;br /&gt;
						reg = &amp;lt;0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
						muic_to_usb: endpoint {&lt;br /&gt;
							remote-endpoint = &amp;lt;&amp;amp;usb_to_muic&amp;gt;;&lt;br /&gt;
						};&lt;br /&gt;
					};&lt;br /&gt;
				};&lt;br /&gt;
			};&lt;br /&gt;
&lt;br /&gt;
		};&lt;br /&gt;
	};&lt;br /&gt;
    /* ... */&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have the switch, you can add the remaining USB nodes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&amp;amp;usbotg {&lt;br /&gt;
	vusb_d-supply = &amp;lt;&amp;amp;usbldo_reg&amp;gt;;&lt;br /&gt;
	vusb_a-supply = &amp;lt;&amp;amp;iosr1_reg&amp;gt;;&lt;br /&gt;
	vbus-supply = &amp;lt;&amp;amp;vbus_reg&amp;gt;;&lt;br /&gt;
	dr_mode = &amp;quot;otg&amp;quot;;&lt;br /&gt;
	role-switch-default-mode = &amp;quot;peripheral&amp;quot;;&lt;br /&gt;
	usb-role-switch;&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // if your device has no switch, drop the port node below&lt;br /&gt;
	port {&lt;br /&gt;
		usb_to_muic: endpoint {&lt;br /&gt;
			remote-endpoint = &amp;lt;&amp;amp;muic_to_usb&amp;gt;;&lt;br /&gt;
		};&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;amp;usbphy {&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== WiFi and Bluetooth ==&lt;br /&gt;
&lt;br /&gt;
Most Broadcom devices use Broadcom WiFi/Bluetooth chips from the BCM43xx series. (Look up BCM43 in your defconfig, or reference downstream kernel dmesg for the exact model.)&lt;br /&gt;
&lt;br /&gt;
The below examples are for BCM4330. If you have another chip, you can grep for it in the mainline kernel (&amp;lt;code&amp;gt;arch/arm/boot/dts&amp;lt;/code&amp;gt;) and see what compatibles are used by other devices.&lt;br /&gt;
&lt;br /&gt;
The Bluetooth chip goes under the UART bus that was labeled as &amp;quot;bluetooth&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
&amp;amp;uartb {&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
	clock-frequency = &amp;lt;48000000&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	bluetooth {&lt;br /&gt;
		compatible = &amp;quot;brcm,bcm4330-bt&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		shutdown-gpios = &amp;lt;&amp;amp;gpio 28 GPIO_ACTIVE_HIGH&amp;gt;;&lt;br /&gt;
		device-wakeup-gpios = &amp;lt;&amp;amp;gpio 32 GPIO_ACTIVE_HIGH&amp;gt;;&lt;br /&gt;
		host-wakeup-gpios = &amp;lt;&amp;amp;gpio 72 GPIO_ACTIVE_HIGH&amp;gt;;&lt;br /&gt;
		reset-gpios = &amp;lt;&amp;amp;gpio 71 GPIO_ACTIVE_LOW&amp;gt;;&lt;br /&gt;
		interrupt-parent = &amp;lt;&amp;amp;gpio&amp;gt;;&lt;br /&gt;
		interrupts = &amp;lt;72 IRQ_TYPE_EDGE_FALLING&amp;gt;;&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get the GPIOs:&lt;br /&gt;
&lt;br /&gt;
* Look for &amp;lt;code&amp;gt;bcmbt_platform_data&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;.bt_wake_gpio&amp;lt;/code&amp;gt; becomes &amp;lt;code&amp;gt;device-wakeup-gpios&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;.host_wake_gpio&amp;lt;/code&amp;gt; becomes &amp;lt;code&amp;gt;host-wakeup-gpios&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Look for &amp;lt;code&amp;gt;bcmbt_rfkill_platform_data&amp;lt;/code&amp;gt;; &amp;lt;code&amp;gt;.vreg_gpio&amp;lt;/code&amp;gt; becomes &amp;lt;code&amp;gt;shutdown-gpios&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;.n_reset_gpio&amp;lt;/code&amp;gt; becomes &amp;lt;code&amp;gt;reset-gpios&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For WiFi, add the following under the &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; node:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
/ {&lt;br /&gt;
    /* ... */&lt;br /&gt;
    &lt;br /&gt;
	/* GPIO regulator for WiFi */&lt;br /&gt;
	wl_reg: regulator-gpio-wlan {&lt;br /&gt;
		compatible = &amp;quot;regulator-fixed&amp;quot;;&lt;br /&gt;
		regulator-name = &amp;quot;WL_REG_ON&amp;quot;;&lt;br /&gt;
		regulator-min-microvolt = &amp;lt;3000000&amp;gt;;&lt;br /&gt;
		regulator-max-microvolt = &amp;lt;3000000&amp;gt;;&lt;br /&gt;
		startup-delay-us = &amp;lt;100000&amp;gt;;&lt;br /&gt;
		gpio = &amp;lt;&amp;amp;gpio 3 GPIO_ACTIVE_HIGH&amp;gt;;&lt;br /&gt;
		enable-active-high;&lt;br /&gt;
	};&lt;br /&gt;
    &lt;br /&gt;
    /* ... */&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Get the GPIO from &amp;lt;code&amp;gt;board_wifi_info&amp;lt;/code&amp;gt;, member &amp;lt;code&amp;gt;.wl_reset_gpio&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Then, update the SDIO node for WiFi:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;devicetree&amp;quot;&amp;gt;&lt;br /&gt;
/* WiFi */&lt;br /&gt;
&amp;amp;sdio3 {&lt;br /&gt;
	max-frequency = &amp;lt;48000000&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	/* Actually a regulator for the WiFi chip */&lt;br /&gt;
	vmmc-supply = &amp;lt;&amp;amp;wl_reg&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	#address-cells = &amp;lt;1&amp;gt;;&lt;br /&gt;
	#size-cells = &amp;lt;0&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
	pinctrl-0 = &amp;lt;&amp;amp;mmc1_width4_pins&amp;gt;;&lt;br /&gt;
	pinctrl-names = &amp;quot;default&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	keep-power-in-suspend;&lt;br /&gt;
	non-removable;&lt;br /&gt;
&lt;br /&gt;
	status = &amp;quot;okay&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	wifi@1 {&lt;br /&gt;
		compatible = &amp;quot;brcm,bcm4330-fmac&amp;quot;, &amp;quot;brcm,bcm4329-fmac&amp;quot;;&lt;br /&gt;
		reg = &amp;lt;1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
		interrupt-parent = &amp;lt;&amp;amp;gpio&amp;gt;;&lt;br /&gt;
		interrupts = &amp;lt;74 IRQ_TYPE_EDGE_FALLING&amp;gt;;&lt;br /&gt;
		interrupt-names = &amp;quot;host-wake&amp;quot;;&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Get the interrupt from &amp;lt;code&amp;gt;board_wifi_info&amp;lt;/code&amp;gt;, member &amp;lt;code&amp;gt;.host_wake_gpio&amp;lt;/code&amp;gt;).&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/Adding_a_new_device&amp;diff=169</id>
		<title>Mainline:Broadcom Kona/Adding a new device</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/Adding_a_new_device&amp;diff=169"/>
		<updated>2026-08-20T21:54:58Z</updated>

		<summary type="html">&lt;p&gt;Uart: start writing draft&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page goes over the process of adding support for a Broadcom Kona device to the mainline Linux kernel.&lt;br /&gt;
&lt;br /&gt;
General outline of the process:&lt;br /&gt;
&lt;br /&gt;
* Get the downstream/vendor kernel source code&lt;br /&gt;
** Identify your device&#039;s board files&lt;br /&gt;
* Get the mainline kernel source code&lt;br /&gt;
* Add a DTS for your device based on values from downstream&lt;br /&gt;
* Build the kernel and flash it to the device&lt;br /&gt;
* Test it!&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
In the mainline kernel, a device&#039;s components are described in a structure known as the [https://wiki.mainlining.org/wiki/Devicetree device tree] (or devicetree, as is the official spelling). Device trees are compiled into DTBs (device tree blobs) from DTS (device tree source) files.&lt;br /&gt;
&lt;br /&gt;
Adding support for a new device involves &#039;&#039;&#039;creating a DTS for that device&#039;&#039;&#039; - this is the process covered in this guide.&lt;br /&gt;
&lt;br /&gt;
Device trees appeared in the kernel around version 3.4, and didn&#039;t see widespread use in vendor kernels until a few LTS versions later. Before device trees, each device usually had a &#039;&#039;board file&#039;&#039; - a C file that contained structs with driver data and initialization functions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The downstream Kona kernels used board files.&#039;&#039;&#039; (They did have some partial DT support, but it was never used for any production devices.)&lt;br /&gt;
&lt;br /&gt;
== Getting the kernel source ==&lt;br /&gt;
&lt;br /&gt;
(WIP)&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=User:Uart/Draft:pmOS_wiki_admin_processes&amp;diff=168</id>
		<title>User:Uart/Draft:pmOS wiki admin processes</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=User:Uart/Draft:pmOS_wiki_admin_processes&amp;diff=168"/>
		<updated>2026-08-18T11:49:33Z</updated>

		<summary type="html">&lt;p&gt;Uart: Created page with &amp;quot;{{todo|Not sure if this will be on the wiki itself or in a separate note...}}  == Monitoring changes ==  Look through Special:RecentChanges and note:  * New article creations. Make sure they are of good enough quality and usefulness to be in the main namespace, if not they should be moved under the user&amp;#039;s userpage. * Redirects or page blanks.  == Approving sign-ups ==  Sign-up approvals have historically been used to stop spambots. These are pretty much a non-issue n...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{todo|Not sure if this will be on the wiki itself or in a separate note...}}&lt;br /&gt;
&lt;br /&gt;
== Monitoring changes ==&lt;br /&gt;
&lt;br /&gt;
Look through [[Special:RecentChanges]] and note:&lt;br /&gt;
&lt;br /&gt;
* New article creations. Make sure they are of good enough quality and usefulness to be in the main namespace, if not they should be moved under the user&#039;s userpage.&lt;br /&gt;
* Redirects or page blanks.&lt;br /&gt;
&lt;br /&gt;
== Approving sign-ups ==&lt;br /&gt;
&lt;br /&gt;
Sign-up approvals have historically been used to stop spambots. These are pretty much a non-issue nowadays as they seem to have been completely stopped by Anubis, but it&#039;s still worth pre-screening potential editors.&lt;br /&gt;
&lt;br /&gt;
When email-confirmed signups are pending, you will see a banner on the top of [[Special:RecentChanges]].&lt;br /&gt;
&lt;br /&gt;
To approve accounts, go to [[Special:ConfirmAccounts]] and click on the &amp;quot;Open requests&amp;quot; tab. For each account:&lt;br /&gt;
&lt;br /&gt;
* Open the &amp;quot;Review&amp;quot; tab.&lt;br /&gt;
* Look at the provided information.&lt;br /&gt;
** &#039;&#039;&#039;Things to look out for&#039;&#039;&#039; that might disqualify an account:&lt;br /&gt;
*** Presence of racist dogwhistles or slurs in username, bio, email or linked websites/socials: e.g. the number 1488 is used by Nazis. Deny with &amp;quot;Spam (do not send email)&amp;quot;.&lt;br /&gt;
*** Nonsensical repeating phrases in bio.&lt;br /&gt;
**** Folks usually do this to get around the 6 words in bio requirement; check if they listed something in the Additional notes that might hint at what they actually want to do on the wiki. If not, feel free to deny the request and in the reason, politely ask them to explain why they want to sign up to the postmarketOS wiki (TODO write a template for this).&lt;br /&gt;
** &#039;&#039;&#039;Things that don&#039;t always disqualify candidates&#039;&#039;&#039;:&lt;br /&gt;
*** Foreign language bios. (Make sure to translate them first in case they contain something inappropriate.)&lt;br /&gt;
*** People who mention running AI/agents, have vibecoded projects in their links, etc.&lt;br /&gt;
**** Exception - if you suspect an AI agent is attempting to create an account as part of a larger change plan (for example, there&#039;s a link to a code forge repo with AI-generated plans); in this case, deny the account and link to the AI policy in the reasoning.&lt;br /&gt;
** If you&#039;re unsure, you can leave the account request for another admin.&lt;br /&gt;
* Select &amp;quot;Approve&amp;quot; on the bottom, and click &amp;quot;Create account&amp;quot;.&lt;br /&gt;
* You will be redirected to the CreateAccount page; click &amp;quot;Create account&amp;quot; there. This might take a few seconds.&lt;br /&gt;
&lt;br /&gt;
If during either of these operations you get an error about expired session or cookies, just click the Approve/Create button again (it should remember the data).&lt;br /&gt;
&lt;br /&gt;
== Renaming accounts ==&lt;br /&gt;
&lt;br /&gt;
{{todo|Create a workflow for users to submit these requests privately; right now they have to go through public chats or guess who the admins are which is not ideal.}}&lt;br /&gt;
&lt;br /&gt;
Admins can rename a user&#039;s account. To do so, go to [[Special:RenameUser]] and change the user&#039;s name.&lt;br /&gt;
&lt;br /&gt;
Keep the &amp;quot;Move user and talk pages (and their subpages) to new name&amp;quot; option selected.&lt;br /&gt;
&lt;br /&gt;
== Deleting accounts ==&lt;br /&gt;
&lt;br /&gt;
If a user requests account deletion:&lt;br /&gt;
&lt;br /&gt;
* Delete their user page and user talk page with the reason &amp;quot;Requested by user&amp;quot;&lt;br /&gt;
* Go to [[Special:BlockUser]] and block the user&#039;s account&lt;br /&gt;
** Block type: &#039;&#039;&#039;Sitewide&#039;&#039;&#039;&lt;br /&gt;
** Block details: &#039;&#039;&#039;Sending email, Editing their own talk page&#039;&#039;&#039;&lt;br /&gt;
** Expiration: &#039;&#039;&#039;indefinite&#039;&#039;&#039;&lt;br /&gt;
** Reason: &#039;&#039;&#039;Other&#039;&#039;&#039;, &amp;quot;Requested by user&amp;quot;&lt;br /&gt;
** Additional options: &#039;&#039;&#039;Hide username from edits and lists&#039;&#039;&#039;&lt;br /&gt;
* Disable the account via [[Special:DisableAccount]]&lt;br /&gt;
&lt;br /&gt;
TODO - if [https://www.mediawiki.org/wiki/Extension:UserMerge UserMerge] ever gets added: go to [[Special:UserMerge]] and merge the user, leaving the New User field empty (or write Anonymous)&lt;br /&gt;
&lt;br /&gt;
== New admin onboarding ==&lt;br /&gt;
&lt;br /&gt;
* Wiki admins should enable issue notifications on [https://gitlab.postmarketos.org/postmarketOS/wiki/-/work_items the wiki repo].&lt;br /&gt;
* Wiki admins should join and monitor the #postmarketOS-wiki IRC/Matrix channel.&lt;br /&gt;
* Go to the user&#039;s page and select &amp;quot;Change user groups&amp;quot; from the sidebar (or go to [[Special:UserRights]] and type in their username). Add them to the &amp;quot;administrators&amp;quot;, &amp;quot;interface administrators&amp;quot;, &amp;quot;bureaucrats&amp;quot;, &amp;quot;suppressor&amp;quot; and &amp;quot;trusted&amp;quot; groups.&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/USB_PHY_(HSOTGCTRL)&amp;diff=162</id>
		<title>Mainline:Broadcom Kona/USB PHY (HSOTGCTRL)</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/USB_PHY_(HSOTGCTRL)&amp;diff=162"/>
		<updated>2026-07-07T05:48:38Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;HSOTGCTRL&#039;&#039;&#039; is the USB2 PHY used in Broadcom Kona chips.&lt;br /&gt;
&lt;br /&gt;
== Drivers ==&lt;br /&gt;
&lt;br /&gt;
=== Downstream ===&lt;br /&gt;
&lt;br /&gt;
Split into two parts:&lt;br /&gt;
&lt;br /&gt;
* {{downstream|baffinlite|arch/arm/plat-kona/bcm-hsotgctrl.c}} which handles all HSOTGCTRL functions;&lt;br /&gt;
** {{downstream|baffinlite|arch/arm/plat-kona/bcm-hsotgctrl-phy-mdio.c}} which specifically has [[#MDIO]] setup&lt;br /&gt;
* {{downstream|baffinlite|drivers/usb/otg/bcmpmu59xxx_otg_xceiv.c}} which hooks into Linux&#039;s USB PHY API, calls the HSOTGCTRL functions and also handles some PMU-related bits of the process (mostly related to VBUS control)&lt;br /&gt;
&lt;br /&gt;
=== Mainline ===&lt;br /&gt;
&lt;br /&gt;
The mainline driver uses the generic PHY framework; it is located in &amp;lt;code&amp;gt;drivers/phy/broadcom/phy-bcm-kona-usb2.c&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== MDIO ==&lt;br /&gt;
&lt;br /&gt;
MDIO most likely stands for [https://en.wikipedia.org/wiki/Management_Data_Input/Output Management Data Input/Output], a PHY management interface used primarily for Ethernet PHYs. While there is a standard for Ethernet MDIO registers, the USB MDIO does not appear to follow it, instead using its own values. Like the Ethernet MDIO, however, both the addresses and values are 16-bit.&lt;br /&gt;
&lt;br /&gt;
MDIO read/write registers are located in CHIPREGS. There is a single read and write register - which internal MDIO device/address to read is selected by first writing the ID/address to the upper bits of the write register (TODO: write down full sequence). USB MDIO has an ID of 9, and 6 registers are written in downstream (docs taken mostly from &amp;lt;code&amp;gt;arch/arm/plat-kona/bcm_hsotgctrl.c&amp;lt;/code&amp;gt; in Rhea downstream):&lt;br /&gt;
&lt;br /&gt;
* MDIO0 - current reference adjustment (&amp;quot;afe_pll_tst lower 16 bits&amp;quot;)&lt;br /&gt;
* MDIO1 - voltage reference adjustment (&amp;quot;afe_pll_tst upper 16 bits&amp;quot;)&lt;br /&gt;
* MDIO2 - ???; not set in Rhea driver, set to 0x0000 in Hawaii driver&lt;br /&gt;
* MDIO3 - transmitter current; valid values are documented in Hawaii driver. Set to 0x2600 on most devices, 0x0400 on Garnet board; TX current value has mask &amp;lt;code&amp;gt;0x07e0&amp;lt;/code&amp;gt;, what the upper bit does is unknown.&lt;br /&gt;
* MDIO4 - USB PHY receiver sensitivity/squelch (valid values are documented in aforementioned Rhea driver and Hawaii driver).&lt;br /&gt;
* MDIO5 - ???; only set in Hawaii driver, set to 0x0000 on all devices. Might have been included by mistake.&lt;br /&gt;
&lt;br /&gt;
{{todo|Write down MDIO3/4 valid values}}&lt;br /&gt;
&lt;br /&gt;
On at least the Samsung Galaxy Grand Neo, the correct MDIO values are already written by the bootloader.&lt;br /&gt;
&lt;br /&gt;
== USB PHY regs ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Main offset:&#039;&#039;&#039; 0x????&lt;br /&gt;
&lt;br /&gt;
=== USBOTGCONTROL (&amp;lt;code&amp;gt;0x00&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
&lt;br /&gt;
Called &amp;lt;code&amp;gt;OTGCTL&amp;lt;/code&amp;gt; in mainline driver. Controls various settings related to USB handling.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| OTGSTAT2, OTGSTAT1&lt;br /&gt;
| 31:30&lt;br /&gt;
| ???; mainline driver clears these bits when powering on.&lt;br /&gt;
|-&lt;br /&gt;
| REG_OTGSTAT2, REG_OTGSTAT1&lt;br /&gt;
| 29:28&lt;br /&gt;
| Controls VBUS valid state; a value of 1 indicates VBUS on, a value of 0 indicates VBUS off. (&amp;lt;code&amp;gt;bcm_hsotgctrl_phy_set_vbus_stat&amp;lt;/code&amp;gt; in downstream)&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Main_Page&amp;diff=161</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Main_Page&amp;diff=161"/>
		<updated>2026-04-28T19:07:03Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Meta:Infrastructure]]&lt;br /&gt;
* [[Mainline:Onyx Go 6]]&lt;br /&gt;
* [[Mainline:Broadcom Kona]]&lt;br /&gt;
* [[Mainline:Exynos 4]]&lt;br /&gt;
* [[Mainline:BCM215xx]]&lt;br /&gt;
&lt;br /&gt;
contact [[User:Knuxify]] for an account.&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:BCM215xx/Introduction&amp;diff=160</id>
		<title>Mainline:BCM215xx/Introduction</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:BCM215xx/Introduction&amp;diff=160"/>
		<updated>2026-04-25T06:40:28Z</updated>

		<summary type="html">&lt;p&gt;Uart: Created page with &amp;quot;BCM215xx is a family of ARMv6 SoCs/APs from Broadcom, released around 2010. The BCM21552/BCM21553 appears to be codenamed Athena. The kernel also contains support for the BCM1160, which appears to be closely related.  The following development boards and devices are found in the Samsung release of the BCM215xx kernel:  * AthenaRay (which follows Broadcom&amp;#039;s tradition of having development boards named &amp;lt;Platform&amp;gt;Ray, see Broadcom Kona kernels) (variants: EDN10, EDN20) * Th...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;BCM215xx is a family of ARMv6 SoCs/APs from Broadcom, released around 2010. The BCM21552/BCM21553 appears to be codenamed Athena. The kernel also contains support for the BCM1160, which appears to be closely related.&lt;br /&gt;
&lt;br /&gt;
The following development boards and devices are found in the Samsung release of the BCM215xx kernel:&lt;br /&gt;
&lt;br /&gt;
* AthenaRay (which follows Broadcom&#039;s tradition of having development boards named &amp;lt;Platform&amp;gt;Ray, see Broadcom Kona kernels) (variants: EDN10, EDN20)&lt;br /&gt;
* Thunderbird (variants: EDN31, EDN5x)&lt;br /&gt;
* Samsung-specific:&lt;br /&gt;
** &#039;&#039;&#039;totoro&#039;&#039;&#039; (Galaxy Y, GT-S5360)&lt;br /&gt;
** &#039;&#039;&#039;tassve&#039;&#039;&#039; (Galaxy Mini Plus/Pop Plus/Mini Turbo, GT-S5570i)&lt;br /&gt;
** &#039;&#039;&#039;cooperve&#039;&#039;&#039; (Galaxy Ace i, GT-S5830i)&lt;br /&gt;
** &#039;&#039;&#039;luisa&#039;&#039;&#039; (Samsung Galaxy Y Pro, GT-B5510)&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:BCM215xx&amp;diff=159</id>
		<title>Mainline:BCM215xx</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:BCM215xx&amp;diff=159"/>
		<updated>2026-04-25T06:25:54Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This &#039;&#039;&#039;root page&#039;&#039;&#039; connects pages for reverse-engineering of BCM215xx (&amp;quot;Athena&amp;quot;?) SoCs (notably the BCM21552/BCM21553 used in the Samsung Galaxy Y (GT-S5360) and some other Samsung budget phones).&lt;br /&gt;
&lt;br /&gt;
It appears to be similar to the BCM116X (notably the I2C driver in downstream is named after it), which is an SoC for VoIP phones&amp;lt;ref&amp;gt;http://www.datasheet.hk/download.php?id=1537788&amp;amp;pdfid=863799B80309819F85E3CF80C6F1C111&amp;amp;file=0270%5Cbcm1160_318075.pdf&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Category:Mainline]] [[Category:SoC]]&lt;br /&gt;
&lt;br /&gt;
== Subpages ==&lt;br /&gt;
&lt;br /&gt;
{{Subpages|stripprefix=true}}&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Template:Downstream&amp;diff=158</id>
		<title>Template:Downstream</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Template:Downstream&amp;diff=158"/>
		<updated>2026-04-25T06:13:03Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;templatedata&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;params&amp;quot;: {&lt;br /&gt;
		&amp;quot;repo&amp;quot;: {&lt;br /&gt;
			&amp;quot;aliases&amp;quot;: [&lt;br /&gt;
				&amp;quot;1&amp;quot;&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;label&amp;quot;: &amp;quot;Repository to link to&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
			&amp;quot;suggestedvalues&amp;quot;: [&lt;br /&gt;
				&amp;quot;baffinlite&amp;quot;,&lt;br /&gt;
				&amp;quot;totoro&amp;quot;&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;required&amp;quot;: true&lt;br /&gt;
		},&lt;br /&gt;
		&amp;quot;file&amp;quot;: {&lt;br /&gt;
			&amp;quot;aliases&amp;quot;: [&lt;br /&gt;
				&amp;quot;2&amp;quot;&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;label&amp;quot;: &amp;quot;File to link to&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
			&amp;quot;required&amp;quot;: true&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;description&amp;quot;: &amp;quot;Link to file in downstream kernel repo&amp;quot;,&lt;br /&gt;
	&amp;quot;format&amp;quot;: &amp;quot;inline&amp;quot;,&lt;br /&gt;
	&amp;quot;paramOrder&amp;quot;: [&lt;br /&gt;
		&amp;quot;repo&amp;quot;,&lt;br /&gt;
		&amp;quot;file&amp;quot;&lt;br /&gt;
	]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/templatedata&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;[{{#switch: {{{repo|{{{1|}}}}}}&lt;br /&gt;
|baffinlite=https://github.com/knuxdroid/android_kernel_samsung_baffinlite/blob/cm-12.1/{{{file|{{{2|}}}}}}&lt;br /&gt;
|totoro=https://github.com/androidarmv6/android_kernel_samsung_bcm21553-common/blob/cm-11.0/{{{file|{{{2|}}}}}}}} &amp;lt;span style=&amp;quot;font-family: monospace;&amp;quot;&amp;gt;{{{file|{{{2|}}}}}}&amp;lt;/span&amp;gt;]&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Template:Downstream&amp;diff=157</id>
		<title>Template:Downstream</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Template:Downstream&amp;diff=157"/>
		<updated>2026-04-25T06:11:48Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;templatedata&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;params&amp;quot;: {&lt;br /&gt;
		&amp;quot;repo&amp;quot;: {&lt;br /&gt;
			&amp;quot;aliases&amp;quot;: [&lt;br /&gt;
				&amp;quot;1&amp;quot;&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;label&amp;quot;: &amp;quot;Repository to link to&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
			&amp;quot;suggestedvalues&amp;quot;: [&lt;br /&gt;
				&amp;quot;baffinlite&amp;quot;,&lt;br /&gt;
				&amp;quot;totoro&amp;quot;&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;required&amp;quot;: true&lt;br /&gt;
		},&lt;br /&gt;
		&amp;quot;file&amp;quot;: {&lt;br /&gt;
			&amp;quot;aliases&amp;quot;: [&lt;br /&gt;
				&amp;quot;2&amp;quot;&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;label&amp;quot;: &amp;quot;File to link to&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
			&amp;quot;required&amp;quot;: true&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;description&amp;quot;: &amp;quot;Link to file in downstream kernel repo&amp;quot;,&lt;br /&gt;
	&amp;quot;format&amp;quot;: &amp;quot;inline&amp;quot;,&lt;br /&gt;
	&amp;quot;paramOrder&amp;quot;: [&lt;br /&gt;
		&amp;quot;repo&amp;quot;,&lt;br /&gt;
		&amp;quot;file&amp;quot;&lt;br /&gt;
	]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/templatedata&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;[{{#switch: {{{repo|{{{1|}}}}}}&lt;br /&gt;
|baffinlite=https://github.com/knuxdroid/android_kernel_samsung_baffinlite/blob/cm-12.1/{{{file|{{{2|}}}}}}&lt;br /&gt;
|totoro=github.com/androidarmv6/android_kernel_samsung_bcm21553-common/blob/cm-11.0/{{{file|{{{2|}}}}}}}} &amp;lt;span style=&amp;quot;font-family: monospace;&amp;quot;&amp;gt;{{{file|{{{2|}}}}}}&amp;lt;/span&amp;gt;]&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:BCM215xx&amp;diff=156</id>
		<title>Mainline:BCM215xx</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:BCM215xx&amp;diff=156"/>
		<updated>2026-04-25T06:02:35Z</updated>

		<summary type="html">&lt;p&gt;Uart: Created page with &amp;quot;This &amp;#039;&amp;#039;&amp;#039;root page&amp;#039;&amp;#039;&amp;#039; connects pages for reverse-engineering of BCM215xx (&amp;quot;Athena&amp;quot;?) SoCs (notably the BCM21552/BCM21553 used in the Samsung Galaxy Y (GT-S5360) and some other Samsung budget phones).  Category:Mainline Category:SoC  == Subpages ==  {{Subpages|stripprefix=true}}&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This &#039;&#039;&#039;root page&#039;&#039;&#039; connects pages for reverse-engineering of BCM215xx (&amp;quot;Athena&amp;quot;?) SoCs (notably the BCM21552/BCM21553 used in the Samsung Galaxy Y (GT-S5360) and some other Samsung budget phones).&lt;br /&gt;
&lt;br /&gt;
[[Category:Mainline]] [[Category:SoC]]&lt;br /&gt;
&lt;br /&gt;
== Subpages ==&lt;br /&gt;
&lt;br /&gt;
{{Subpages|stripprefix=true}}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=MediaWiki:Sidebar/Category:Sidebar_test&amp;diff=155</id>
		<title>MediaWiki:Sidebar/Category:Sidebar test</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=MediaWiki:Sidebar/Category:Sidebar_test&amp;diff=155"/>
		<updated>2026-03-10T15:27:00Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;** https://dissonant.dev | Test&lt;br /&gt;
*** https://wiki.dissonant.dev | Test 2&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=MediaWiki:Sidebar/Category:Sidebar_test&amp;diff=154</id>
		<title>MediaWiki:Sidebar/Category:Sidebar test</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=MediaWiki:Sidebar/Category:Sidebar_test&amp;diff=154"/>
		<updated>2026-03-10T15:22:45Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;** https://dissonant.dev | Test&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=MediaWiki:Sidebar/Category:Sidebar_test&amp;diff=153</id>
		<title>MediaWiki:Sidebar/Category:Sidebar test</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=MediaWiki:Sidebar/Category:Sidebar_test&amp;diff=153"/>
		<updated>2026-03-10T14:52:39Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* https://dissonant.dev | Test&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Category:Sidebar_test&amp;diff=152</id>
		<title>Category:Sidebar test</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Category:Sidebar_test&amp;diff=152"/>
		<updated>2026-03-10T14:48:20Z</updated>

		<summary type="html">&lt;p&gt;Uart: Created page with &amp;quot;(test page)&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(test page)&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Meta:Infrastructure&amp;diff=151</id>
		<title>Meta:Infrastructure</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Meta:Infrastructure&amp;diff=151"/>
		<updated>2026-03-10T14:44:36Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page acts as an overview of dissonant.dev&#039;s infrastructure.&lt;br /&gt;
&lt;br /&gt;
== Servers ==&lt;br /&gt;
&lt;br /&gt;
dissonant.dev currently operates on two servers:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;code&amp;gt;franky&amp;lt;/code&amp;gt;&#039;&#039;&#039; - the main VPS, a [https://www.hetzner.com/ Hetzner] CX22 node. (2x2.1GHz, 4GB RAM, 40GB storage)&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;code&amp;gt;pandemonica&amp;lt;/code&amp;gt;&#039;&#039;&#039; (a.k.a &#039;&#039;pandy&#039;&#039;) - tiny VPS hosting fxtumblr/tpmblr.com; kindly provided by [https://sdomi.pl/ sdomi]. (1x4.2GHz, 2GB RAM, 10GB storage)&lt;br /&gt;
&lt;br /&gt;
Decomissioned servers:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;code&amp;gt;arisu&amp;lt;/code&amp;gt;&#039;&#039;&#039; - the previous main VPS, a [https://homecloud.pl/ homecloud.pl] Cloud VPS M node. They stopped offering Cloud VPS nodes, and moved them to their main offering at a marked-up price, which forced me to reconsider my hosting options. (2x2GHz, 4GB RAM, 80GB storage)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;&amp;lt;code&amp;gt;franky&amp;lt;/code&amp;gt; is named after Franky from &#039;&#039;Flying Saucer Video&#039;&#039;. &amp;lt;code&amp;gt;pandemonica&amp;lt;/code&amp;gt; is named after Pandemonica from &#039;&#039;Helltaker&#039;&#039; (I don&#039;t even know what that game&#039;s about I just thought she was neat). &amp;lt;code&amp;gt;arisu&amp;lt;/code&amp;gt; was a Lain reference. I am cringe but I am free.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Expansion possibilities ==&lt;br /&gt;
&lt;br /&gt;
I would like to look into self-hosting some services from home; the main issue is getting a static IPv4 address, but my ISP provides public IPv6 addresses so that would leave us with having to find a proxy of some sort.&lt;br /&gt;
&lt;br /&gt;
[[Category:Sidebar test]]&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=MediaWiki:Sidebar&amp;diff=150</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=MediaWiki:Sidebar&amp;diff=150"/>
		<updated>2026-03-10T14:44:01Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* Links&lt;br /&gt;
** Meta:Infrastructure|Infrastructure&lt;br /&gt;
* CATEGORY-SIDEBAR&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=User:Uart/sidebartest&amp;diff=149</id>
		<title>User:Uart/sidebartest</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=User:Uart/sidebartest&amp;diff=149"/>
		<updated>2026-03-10T14:42:43Z</updated>

		<summary type="html">&lt;p&gt;Uart: Created page with &amp;quot;This is an example page Category:Sidebar test&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is an example page&lt;br /&gt;
[[Category:Sidebar test]]&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=MediaWiki:Sidebar/Category:Sidebar_test&amp;diff=148</id>
		<title>MediaWiki:Sidebar/Category:Sidebar test</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=MediaWiki:Sidebar/Category:Sidebar_test&amp;diff=148"/>
		<updated>2026-03-10T14:42:11Z</updated>

		<summary type="html">&lt;p&gt;Uart: Created page with &amp;quot; * navigation ** mainpage|mainpage-description ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help-mediawiki * https://dissonant.dev|Test * SEARCH * TOOLBOX * LANGUAGES&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* https://dissonant.dev|Test&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=MediaWiki:Editnotice-notext&amp;diff=147</id>
		<title>MediaWiki:Editnotice-notext</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=MediaWiki:Editnotice-notext&amp;diff=147"/>
		<updated>2025-10-04T05:48:38Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;test&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=MediaWiki:Edittools&amp;diff=146</id>
		<title>MediaWiki:Edittools</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=MediaWiki:Edittools&amp;diff=146"/>
		<updated>2025-10-04T05:48:13Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- Text here will be shown below edit and upload forms. --&amp;gt;&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=MediaWiki:Edittools&amp;diff=145</id>
		<title>MediaWiki:Edittools</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=MediaWiki:Edittools&amp;diff=145"/>
		<updated>2025-10-04T05:48:05Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- Text here will be shown below edit and upload forms. --&amp;gt;&lt;br /&gt;
a&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx&amp;diff=144</id>
		<title>Mainline:Broadcom Kona/BCM590xx</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx&amp;diff=144"/>
		<updated>2025-09-15T19:46:32Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This &#039;&#039;&#039;root page&#039;&#039;&#039; connects all pages related to the BCM590xx series of PMICs, in particular the BCM59054 and BCM59056.&lt;br /&gt;
&lt;br /&gt;
The BCM590xx PMICs comprise of the following parts:&lt;br /&gt;
&lt;br /&gt;
* Internal interrupt controller ([[/Interrupts]])&lt;br /&gt;
* Regulators ([[/Regulators]])&lt;br /&gt;
* Power-on key controller/PONKEY ([[/PONKEY]])&lt;br /&gt;
* RTC ([[/RTC]])&lt;br /&gt;
* Charger [[/Charger]])&lt;br /&gt;
* Fuel gauge ([[/Fuel gauge]])&lt;br /&gt;
* USB OTG control ([[/USB]])&lt;br /&gt;
* Audio amplifier (?)&lt;br /&gt;
* PWM LED controller&lt;br /&gt;
* ADC used e.g. for thermal monitoring ([[/ADC]])&lt;br /&gt;
&lt;br /&gt;
== Subpages ==&lt;br /&gt;
&lt;br /&gt;
{{Subpages|stripprefix=true}}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/Regulators&amp;diff=143</id>
		<title>Mainline:Broadcom Kona/BCM590xx/Regulators</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/Regulators&amp;diff=143"/>
		<updated>2025-09-15T19:46:20Z</updated>

		<summary type="html">&lt;p&gt;Uart: Created page with &amp;quot;{{hatnote|Relevant downstream drivers: {{downstream|baffinlite|drivers/regulator/bcmpmu59xxx-regulator.c}}; {{downstream|baffinlite|bcmpmu-regulator.c}}; {{downstream|baffinlite|drivers/regulator/bcm590xx-regulator.c}} and {{downstream|baffinlite|drivers/regulator/bcm59055_regulator.c}} for BCM59055.}}  The BCM590xx PMUs have configurable voltage regulators.  == Regulator types ==  There are two types of regulators: &amp;#039;&amp;#039;&amp;#039;LDO&amp;#039;&amp;#039;&amp;#039; (low dropout) and &amp;#039;&amp;#039;&amp;#039;SR&amp;#039;&amp;#039;&amp;#039; (switcher). Regula...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{hatnote|Relevant downstream drivers: {{downstream|baffinlite|drivers/regulator/bcmpmu59xxx-regulator.c}}; {{downstream|baffinlite|bcmpmu-regulator.c}}; {{downstream|baffinlite|drivers/regulator/bcm590xx-regulator.c}} and {{downstream|baffinlite|drivers/regulator/bcm59055_regulator.c}} for BCM59055.}}&lt;br /&gt;
&lt;br /&gt;
The BCM590xx PMUs have configurable voltage regulators.&lt;br /&gt;
&lt;br /&gt;
== Regulator types ==&lt;br /&gt;
&lt;br /&gt;
There are two types of regulators: &#039;&#039;&#039;LDO&#039;&#039;&#039; (low dropout) and &#039;&#039;&#039;SR&#039;&#039;&#039; (switcher). Regulator names are suffixed with these shortcuts to indicate their type (e.g. &#039;&#039;LVLDO1&#039;&#039; is an LDO, &#039;&#039;CSR&#039;&#039; is an SR).&lt;br /&gt;
&lt;br /&gt;
== Operating modes ==&lt;br /&gt;
&lt;br /&gt;
The operating modes for each regulator are stored in &amp;lt;code&amp;gt;PMMODE&amp;lt;/code&amp;gt; registers. These registers are used to store operating modes for various &#039;&#039;&#039;PC&#039;&#039;&#039; (pin control) configurations. The mode that ends up being used is determined based on the state of PC1 and PC2 pins (and  optionally the GPIO1 pin, if it&#039;s configured to the PC3 function in GPIOCTRL).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LDOs&#039;&#039;&#039; have &#039;&#039;&#039;2-bit modes&#039;&#039;&#039;. The available modes are &amp;lt;code&amp;gt;ON&amp;lt;/code&amp;gt; (0), &amp;lt;code&amp;gt;LPM&amp;lt;/code&amp;gt; (low power mode; 1) and &amp;lt;code&amp;gt;OFF&amp;lt;/code&amp;gt; (2). {{speculation|Mode 3 is presumably invalid, but hasn&#039;t been tested.}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SRs&#039;&#039;&#039; have &#039;&#039;&#039;3-bit modes&#039;&#039;&#039;. The exact function of each mode is unknown; the vendor kernel does not bother with the distinction and applies the LDO modes described above.&lt;br /&gt;
&lt;br /&gt;
LDOs get 2 PMMODE registers each; SRs get 4 PMMODE registers. This is to accomodate the different mode sizes.&lt;br /&gt;
&lt;br /&gt;
There is no known way to query the state of PC pins from the BCM590xx itself; instead, the SoC&#039;s pinmux interface could be used.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[User:Knuxify/Old BCM590xx regulator notes|Old BCM590xx regulator notes]], very messy.&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=User:Uart/Old_BCM590xx_regulator_notes&amp;diff=142</id>
		<title>User:Uart/Old BCM590xx regulator notes</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=User:Uart/Old_BCM590xx_regulator_notes&amp;diff=142"/>
		<updated>2025-09-15T19:18:25Z</updated>

		<summary type="html">&lt;p&gt;Uart: Knuxify moved page Mainline:Broadcom Kona/BCM590xx/Regulators to User:Knuxify/Old BCM590xx regulator notes without leaving a redirect&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(note: this article has not been cleaned up &#039;&#039;at all&#039;&#039;, it is imported from my local notes as-is.)&lt;br /&gt;
&lt;br /&gt;
== Revisions ==&lt;br /&gt;
&lt;br /&gt;
BCMPMU_59054_ID is ID for 59054&lt;br /&gt;
&lt;br /&gt;
BCMPMU_59054A1_ANA_REV refers to A1 which has ACLD, A0 does not&lt;br /&gt;
&lt;br /&gt;
== Downstream driver notes ==&lt;br /&gt;
&lt;br /&gt;
* The downstream driver used is BCM59xxx, which despite the name is only for the BCM59054&lt;br /&gt;
** In the tree there are also drivers for BCM59056, a handful of other PMUs including BCM59055, and BCM590xx (which confusingly is &#039;&#039;&#039;not&#039;&#039;&#039; the same as BCM59xxx).&lt;br /&gt;
* The whole driver is fragmented as it&#039;s an MFD device, but the most important files are:&lt;br /&gt;
** &amp;lt;code&amp;gt;arch/arm/mach-{codename}/board-bcm59xxx_{device}.c&amp;lt;/code&amp;gt; - contains PMU setup data, including voltages, regulator modes, battery values, etc.&lt;br /&gt;
** various files in &amp;lt;code&amp;gt;drivers/mfd/&amp;lt;/code&amp;gt; starting from &amp;lt;code&amp;gt;bcmpmu59xxx-&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;drivers/regulator/bcmpmu-rgltr-bcm59xxx.c&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;drivers/regulator/bcmpmu59xxx-regulator.c&amp;lt;/code&amp;gt;&lt;br /&gt;
** there&#039;s some OTG related driver in &amp;lt;code&amp;gt;drivers/usb/otg/&amp;lt;/code&amp;gt;? investigate&lt;br /&gt;
** &amp;lt;code&amp;gt;drivers/misc/bcmpmu59xxx_audio.c&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;include/linux/mfd/bcmpmu59xxx_reg.h&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;include/linux/mfd/bcmpmu59054_reg.h&amp;lt;/code&amp;gt;&lt;br /&gt;
** and others not mentioned here. todo&lt;br /&gt;
&lt;br /&gt;
== Regulators ==&lt;br /&gt;
&lt;br /&gt;
SR apparently means &amp;quot;switcher&amp;quot; (drivers/regulator/bcmpmu-regulator-56.c line 249). Rest is LDOs.&lt;br /&gt;
&lt;br /&gt;
== Modes ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(see &amp;lt;code&amp;gt;drivers/regulator/bcmpmu59xxx-regulator.c&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;include/linux/mfd/bcmpmu59xxx.h&amp;lt;/code&amp;gt;)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There are two mode settings: 3bit (GPLDOs only) and 2bit (everything else, including all regs in bcm59056).&lt;br /&gt;
&lt;br /&gt;
A standard regulator can have 3 modes: * ON (&amp;lt;code&amp;gt;REGULATOR_MODE_FAST&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;REGULATOR_MODE_NORMAL&amp;lt;/code&amp;gt;) (0) * LPM (&amp;lt;code&amp;gt;REGULATOR_MODE_IDLE&amp;lt;/code&amp;gt;) (1) * OFF (&amp;lt;code&amp;gt;REGULATOR_MODE_STANDBY&amp;lt;/code&amp;gt;) (2)&lt;br /&gt;
&lt;br /&gt;
* 2-bit mode regulators have 4 PM values in the PMMODE registers, at offsets 0, 2, 4 and 6 respectively (PM0, PM1, PM2, PM3), and &#039;&#039;&#039;2 PMMODE registers&#039;&#039;&#039;. (PMCTRL1 and PMCTRL2)&lt;br /&gt;
* 3-bit mode regulators have 2 PM values in the PMMODE registers, at offsets 0 and 3 respectively, and &#039;&#039;&#039;4 PMMODE registers&#039;&#039;&#039;. (PMCTRL1-&amp;gt;4)&lt;br /&gt;
&lt;br /&gt;
Each PM value corresponds to a different mode.&lt;br /&gt;
&lt;br /&gt;
== BCM59056 and modes ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;(see &amp;lt;code&amp;gt;drivers/regulator/bcmpmu-regulator-56.c&amp;lt;/code&amp;gt;)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strike&amp;gt;Unlike BCM59054, there&#039;s only one PMMODE register&amp;lt;/strike&amp;gt; (this is completely wrong! BCM59056 also has multiple PMMODE regs), and it has values PM0 to PM3. DSM (deep sleep) is pins PM0 and PM2. Regular value is written to PM1 and PM3.&lt;br /&gt;
&lt;br /&gt;
I have a sneaking suspicion, based on the mainline driver, and the fact that the function described in the &amp;quot;Enabling the regulator&amp;quot; part will gleefuly ignore PM0 mostly, that PM0 may be some sort of &amp;quot;perma-override&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*State of enabled regualtor in deep sleep     &lt;br /&gt;
Used to program PC2PC1 = 0b10 &amp;amp; 0b00 case     &lt;br /&gt;
when the regulator is enabled*/     &lt;br /&gt;
enum {     &lt;br /&gt;
        BCMPMU_REGL_ON_IN_DSM = 1,     &lt;br /&gt;
        BCMPMU_REGL_LPM_IN_DSM,     &lt;br /&gt;
        BCMPMU_REGL_OFF_IN_DSM     &lt;br /&gt;
};   &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...a PC reference? You&#039;ll see these in the next section.&lt;br /&gt;
&lt;br /&gt;
=== BCM59054 and modes ===&lt;br /&gt;
&lt;br /&gt;
Here, the situation is a bit more complicated because there are multiple PMMODE regs. (Actually BCM59056 seems to have these as well? weird.)&lt;br /&gt;
&lt;br /&gt;
=== Enabling a regulator ===&lt;br /&gt;
&lt;br /&gt;
In theory, enabling a regulator can be done by setting all of its modes to &amp;lt;code&amp;gt;PMMODE_ON&amp;lt;/code&amp;gt;. In practice, however, each regulator has specific &amp;quot;pins&amp;quot; which, when enabled, will enable the regulator. The pins used are stored in &amp;lt;code&amp;gt;arch/arm/mach-java/board-bcm59xxx_*&amp;lt;/code&amp;gt;, under &amp;lt;code&amp;gt;pc_pins_map&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This has a value created with the &amp;quot;PCPIN_MAP_ENC&amp;quot; macro, which effectively packs two &amp;quot;sets&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Set 1&#039;&#039;&#039;, which is the first parameter - if this is set, then &#039;&#039;&#039;all pins in this set must be enabled&#039;&#039;&#039; to enable this regulator.&lt;br /&gt;
* &#039;&#039;&#039;Set 0&#039;&#039;&#039;, which is the second parameter - if this is set, then &#039;&#039;&#039;one of the pins in this set must be enabled&#039;&#039;&#039; to enable this regulator.&lt;br /&gt;
&lt;br /&gt;
The functions &amp;lt;code&amp;gt;__is_2bit_pmmode_regl_enabled&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;__is_3bit_pmmode_regl_enabled&amp;lt;/code&amp;gt; check if a regulator is enabled based on those pin maps, and the &amp;lt;code&amp;gt;pmmode&amp;lt;/code&amp;gt; value as read out from the PMMODE registers.&lt;br /&gt;
&lt;br /&gt;
For every &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; from 0 to 7 (&amp;lt;code&amp;gt;REGL_PMMODE_VAL_MAX&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
* get the PM reg shift by &amp;lt;code&amp;gt;PMMODE_2BIT_PMx_MASK &amp;amp; i&amp;lt;/code&amp;gt; (PMMODE_2BIT_PMx_MASK == 3)&lt;br /&gt;
* if this &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; gives a value through &amp;lt;code&amp;gt;setval &amp;amp; i&amp;lt;/code&amp;gt; in set0 or set1, then the value of whether the regulator is enabled is calculated using &amp;lt;code&amp;gt;PMMODE_2BIT_PMx_MASK &amp;amp; (pmmode[inx] &amp;gt;&amp;gt; shift)&amp;lt;/code&amp;gt;, where &amp;lt;code&amp;gt;inx&amp;lt;/code&amp;gt; is increased for every value where &amp;lt;code&amp;gt;PMMODE_2BIT_PMx_MASK &amp;amp; i&amp;lt;/code&amp;gt; == 3.&lt;br /&gt;
&lt;br /&gt;
In normal words: if the mode corresponding to the pin in &#039;&#039;any&#039;&#039; of the PMMODE registers is ON, then the regulator is on.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a table of what that looks like:&lt;br /&gt;
&lt;br /&gt;
(i - i iterator, s - pm offset, x - pmmode register no., set0 - matches against joined set0; pc1, pc2, pc3 - the result of the check for each of the possible pins in set0)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;i s x set0   pc1   pc2   pc3&lt;br /&gt;
0 0 0 False [False, False, False]&lt;br /&gt;
1 2 0 True [True, False, False]&lt;br /&gt;
2 4 0 True [False, True, False]&lt;br /&gt;
3 6 0 True [True, True, False]&lt;br /&gt;
4 0 1 True [False, False, True]&lt;br /&gt;
5 2 1 True [True, False, True]&lt;br /&gt;
6 4 1 True [False, True, True]&lt;br /&gt;
7 6 1 True [True, True, True]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
One thing of note - PC1 matches exactly the same configuration as the non-deep-sleep pins from the BCM59056 driver mentioned earlier. PC2 matches offsets 4 and 6, and PC3 matches everything in the second register, but not the first one.&lt;br /&gt;
&lt;br /&gt;
So, how can the BCM59056 driver ignore that second register? Maybe I just didn&#039;t read something right? (probably...) (update: I think it&#039;s just BCM59054 that pokes multiple regs?)&lt;br /&gt;
&lt;br /&gt;
Update: I found this a little later, in the bcm59&#039;&#039;&#039;0xx&#039;&#039;&#039; driver (actually for the BCM59055).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;#define PC2_IS_0_PC1_IS_0                       0    &lt;br /&gt;
#define PC2_IS_0_PC1_IS_1                       2    &lt;br /&gt;
#define PC2_IS_1_PC1_IS_0                       4    &lt;br /&gt;
#define PC2_IS_1_PC1_IS_1                       6    &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I suppose this should match the table above?&lt;br /&gt;
&lt;br /&gt;
In any case - what I think is happening here is that which registers are read from to determine the notes are controlled by some kind of pins. Each PMMODE offset represents a different combination of pins to set.&lt;br /&gt;
&lt;br /&gt;
=== The actual function called to prepare the enable value ===&lt;br /&gt;
&lt;br /&gt;
Now that we know how these pins work, we can analyze the second function, &amp;lt;code&amp;gt;__2bit_pmmode_frm_map&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This one&#039;s similar to the previous function:&lt;br /&gt;
&lt;br /&gt;
For every &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; from 0 to 7 (&amp;lt;code&amp;gt;REGL_PMMODE_VAL_MAX&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
* If the value is in set0 or set1, set the value to &amp;lt;code&amp;gt;PMMODE_ON&amp;lt;/code&amp;gt;; otherwise, use &#039;&#039;&#039;&amp;lt;code&amp;gt;dsm_pmmode&amp;lt;/code&amp;gt;&#039;&#039;&#039; (a variable passed at init time). Oooh, DSM again!&lt;br /&gt;
* Figure out the shift and register like before.&lt;br /&gt;
* Add the value to a temp variable by ORing &amp;lt;code&amp;gt;val &amp;lt;&amp;lt; shift&amp;lt;/code&amp;gt; to it.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s the thing: &amp;lt;code&amp;gt;dsm_pmmode&amp;lt;/code&amp;gt;... is the mode value provided in &amp;lt;code&amp;gt;__bcmpmuldo_set_mode&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The mode is set in a few places in the code, and next to one of them, I found this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;                        /* We need to set mode here as regulator framework     &lt;br /&gt;
                        (set_machine_constraints) set the mode first and     &lt;br /&gt;
                        then call enable. We have updated enable function     &lt;br /&gt;
                        to set ON for all states based on customer request     &lt;br /&gt;
                        set_mode function sets PMMODE as needed*/     &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== TL;DR, summary ====&lt;br /&gt;
&lt;br /&gt;
Regulators can be enabled by setting specific offsets at the PMMODE registers to PMMODE_ON. A combination of PC pins can be used to select which offsets and PMMODE registers actually apply - by default, only offsets in PMCTRL1 is used, but the others can be used as well if PC3 is present - see below.&lt;br /&gt;
&lt;br /&gt;
As a gross oversimplification, you can simply set &#039;&#039;every&#039;&#039; register to PMMODE_ON and it should work.&lt;br /&gt;
&lt;br /&gt;
PM0 and PM2 (offsets 0 and 4) may or may not be related to deep sleep mode.&lt;br /&gt;
&lt;br /&gt;
== A note about PC pins ==&lt;br /&gt;
&lt;br /&gt;
According to schematics, on the Grand Neo, PC1 and PC2 are connected to the accordingly named PC1 and PC2 pinctrl pins. PC3 is an alternative function of LCDCS0 - and it&#039;s connected, as PMU_PC3, to the GPIO1 pin on the PMIC.&lt;br /&gt;
&lt;br /&gt;
Turns out, the function of the GPIO pins can be programmed by writing to the GPIOCTRL registers. Here&#039;s the relevant downstream code:&lt;br /&gt;
&lt;br /&gt;
(arch/arm/mach-java/board-bcm59xxx_ss_baffinlite.c)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; 121         /*  enable PC3 function */&lt;br /&gt;
 122         {.addr = PMU_REG_GPIOCTRL2, .val = 0x0E, .mask = 0xFF},&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Sadly, these regs are completely undocumented, so we can&#039;t know for sure which exact bit enables this function. We also don&#039;t know what happens if it&#039;s &#039;&#039;not&#039;&#039; enabled.&lt;br /&gt;
&lt;br /&gt;
== What about the regulator modes? ==&lt;br /&gt;
&lt;br /&gt;
Somehow, &amp;lt;code&amp;gt;__2bit_pmmode_frm_map&amp;lt;/code&amp;gt; &#039;&#039;doesn&#039;t&#039;&#039; set all of the PMMODE offsets! For the offsets matching the PC pin map, it actually &#039;&#039;leaves them on&#039;&#039;, and only sets the requested mode for the remaining ones! Given that the variable name for the provided mode is &amp;lt;code&amp;gt;dsm_pmmode&amp;lt;/code&amp;gt;, I suspect that Broadcom might&#039;ve abused the mode system to provide the &#039;&#039;deep sleep regulator mode&#039;&#039; instead.&lt;br /&gt;
&lt;br /&gt;
Still, this doesn&#039;t explain how the PC pins are controlled. I can&#039;t find any place in the downstream code that would do it. I suspect I should look at the suspend code...&lt;br /&gt;
&lt;br /&gt;
Note to self: CHIPREG seems interesting. Has a whole bunch of stuff.&lt;br /&gt;
&lt;br /&gt;
Another unrelated note: looks like i2c sets up slew rate for its pins in the driver, investigate&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Template:Todo/style.css&amp;diff=141</id>
		<title>Template:Todo/style.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Template:Todo/style.css&amp;diff=141"/>
		<updated>2025-09-15T18:56:31Z</updated>

		<summary type="html">&lt;p&gt;Uart: Created page with &amp;quot;html.skin-theme-clientpref-night .box-todo { 	color: #fff !important; 	background-color: #5c1e1e !important; 	border-color: #c64242 !important; }  @media (prefers-color-scheme: dark) { 	html.skin-theme-clientpref-os .box-todo { 		color: #fff !important; 		background-color: #5c1e1e !important; 		border-color: #c64242 !important; 	} }&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;html.skin-theme-clientpref-night .box-todo {&lt;br /&gt;
	color: #fff !important;&lt;br /&gt;
	background-color: #5c1e1e !important;&lt;br /&gt;
	border-color: #c64242 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (prefers-color-scheme: dark) {&lt;br /&gt;
	html.skin-theme-clientpref-os .box-todo {&lt;br /&gt;
		color: #fff !important;&lt;br /&gt;
		background-color: #5c1e1e !important;&lt;br /&gt;
		border-color: #c64242 !important;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Template:Note/style.css&amp;diff=140</id>
		<title>Template:Note/style.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Template:Note/style.css&amp;diff=140"/>
		<updated>2025-09-15T18:56:03Z</updated>

		<summary type="html">&lt;p&gt;Uart: Created page with &amp;quot;html.skin-theme-clientpref-night .box-note { 	color: #fff !important; 	background-color: #261c09 !important; 	border-color: #6a481c !important; }  @media (prefers-color-scheme: dark) { 	html.skin-theme-clientpref-os .box-note { 		color: #fff !important; 		background-color: #261c09 !important; 		border-color: #6a481c !important; 	} }&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;html.skin-theme-clientpref-night .box-note {&lt;br /&gt;
	color: #fff !important;&lt;br /&gt;
	background-color: #261c09 !important;&lt;br /&gt;
	border-color: #6a481c !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (prefers-color-scheme: dark) {&lt;br /&gt;
	html.skin-theme-clientpref-os .box-note {&lt;br /&gt;
		color: #fff !important;&lt;br /&gt;
		background-color: #261c09 !important;&lt;br /&gt;
		border-color: #6a481c !important;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Template:Note&amp;diff=139</id>
		<title>Template:Note</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Template:Note&amp;diff=139"/>
		<updated>2025-09-15T18:45:42Z</updated>

		<summary type="html">&lt;p&gt;Uart: Created page with &amp;quot;&amp;lt;!-- Dark-mode colors are defined in the template style --&amp;gt;&amp;lt;templatestyles src=&amp;quot;Note/style.css&amp;quot;/&amp;gt;&amp;lt;!-- --&amp;gt;&amp;lt;includeonly&amp;gt;{{Icon box | box-icons = Note | box-text = {{{1}}} | border-color = #ac6600 | border-width = 1px | background = #f6efe5 | class = box-note }}&amp;lt;/includeonly&amp;gt;&amp;lt;!--  --&amp;gt;&amp;lt;noinclude&amp;gt; &amp;lt;templatedata&amp;gt; { 	&amp;quot;params&amp;quot;: { 		&amp;quot;1&amp;quot;: { 			&amp;quot;label&amp;quot;: &amp;quot;Text&amp;quot;, 			&amp;quot;description&amp;quot;: &amp;quot;Text to place in the box&amp;quot;, 			&amp;quot;type&amp;quot;: &amp;quot;unbalanced-wikitext&amp;quot;,...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- Dark-mode colors are defined in the template style --&amp;gt;&amp;lt;templatestyles src=&amp;quot;Note/style.css&amp;quot;/&amp;gt;&amp;lt;!--&lt;br /&gt;
--&amp;gt;&amp;lt;includeonly&amp;gt;{{Icon box&lt;br /&gt;
| box-icons = [[File:Reference icon.svg|20px|link=|Note]]&lt;br /&gt;
| box-text = {{{1}}}&lt;br /&gt;
| border-color = #ac6600&lt;br /&gt;
| border-width = 1px&lt;br /&gt;
| background = #f6efe5&lt;br /&gt;
| class = box-note&lt;br /&gt;
}}&amp;lt;/includeonly&amp;gt;&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;templatedata&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;params&amp;quot;: {&lt;br /&gt;
		&amp;quot;1&amp;quot;: {&lt;br /&gt;
			&amp;quot;label&amp;quot;: &amp;quot;Text&amp;quot;,&lt;br /&gt;
			&amp;quot;description&amp;quot;: &amp;quot;Text to place in the box&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;: &amp;quot;unbalanced-wikitext&amp;quot;,&lt;br /&gt;
			&amp;quot;required&amp;quot;: true&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;description&amp;quot;: &amp;quot;Note box containing a note.&amp;quot;,&lt;br /&gt;
	&amp;quot;format&amp;quot;: &amp;quot;inline&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/templatedata&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;{{note|This is quite &#039;&#039;&#039;note-worthy&#039;&#039;&#039;.}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{note|This is quite &#039;&#039;&#039;note-worthy&#039;&#039;&#039;.}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/ADC&amp;diff=138</id>
		<title>Mainline:Broadcom Kona/BCM590xx/ADC</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/ADC&amp;diff=138"/>
		<updated>2025-08-31T15:37:26Z</updated>

		<summary type="html">&lt;p&gt;Uart: /* RTM (Real-Time Measurment) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/hwmon/bcmpmu59xxx-hwmon.c}}, {{downstream|baffinlite|drivers/misc/bcm59055-adc.c}} (for BCM59055 but very well commented, and seems to be about the same as other models).}}&lt;br /&gt;
&lt;br /&gt;
The BCM590xx PMUs provide a 10-bit SAR (Successive Approximation) ADC.&lt;br /&gt;
&lt;br /&gt;
== Reading the ADC data ==&lt;br /&gt;
&lt;br /&gt;
Each ADC channel has two registers which immediately succeed each other. These registers follow the layout outlined below.&lt;br /&gt;
&lt;br /&gt;
To read the ADC data, one needs to combine the DATA_MSB bits (upper 2 bits, first two bits of the first register) with the DATA_LSB (lower 8 bits, entire value of the second register). An additional value at bit 2 is available to check the validity of the read data.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
data = ((reg1 &amp;amp; 0x3) &amp;lt;&amp;lt; 8) | reg2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRLx ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7:3&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;READ_INVALID&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2&lt;br /&gt;
| If 1, the read is invalid; 0 otherwise.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;DATA_MSB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 1:0&lt;br /&gt;
| Upper (most significant) 2 bits of the ADC data.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRLx+1 ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;DATA_LSB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7:0&lt;br /&gt;
| Lower (least significant) 8 bits of the ADC data.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RTM (Real-Time Measurment) ==&lt;br /&gt;
&lt;br /&gt;
The last ADC channel, RTM, is reserved for RTM (Real-Time Measurment) mode.&lt;br /&gt;
&lt;br /&gt;
The process for performing an RTM read is as follows:&lt;br /&gt;
&lt;br /&gt;
* In &amp;lt;code&amp;gt;ADCCTRL1&amp;lt;/code&amp;gt;: (these can all be performed in one write)&lt;br /&gt;
** Set the the &amp;lt;code&amp;gt;RTM_CONVERSION&amp;lt;/code&amp;gt; bit to enable RTM mode&lt;br /&gt;
** Write the channel number to read to the &amp;lt;code&amp;gt;RTM_CHANN&amp;lt;/code&amp;gt; offset&lt;br /&gt;
** Write the &amp;lt;code&amp;gt;RTM_START&amp;lt;/code&amp;gt; bit to start the RTM read&lt;br /&gt;
* Wait for the &amp;lt;code&amp;gt;ADC_RTM_DATA_READY&amp;lt;/code&amp;gt; interrupt.&lt;br /&gt;
* Perform a standard data read from the RTM ADC channel registers (see [[#Reading the ADC data]]).&lt;br /&gt;
* Clear the &amp;lt;code&amp;gt;RTM_CONVERSION&amp;lt;/code&amp;gt; bit to disable RTM mode.&lt;br /&gt;
&lt;br /&gt;
== Register layout ==&lt;br /&gt;
&lt;br /&gt;
Values given here are for the BCM59054. These registers are located on map 1.&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRL1 (0x20) ===&lt;br /&gt;
&lt;br /&gt;
Contains settings for RTM mode.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;RTM_CHANN&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7:4&lt;br /&gt;
| Channel to read in RTM mode.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;RTM_CONVERSION&amp;lt;/code&amp;gt;&lt;br /&gt;
| 3&lt;br /&gt;
| Enable (0) or disable (1) RTM mode. Prerequisite for performing an RTM read.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;RTM_START&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2&lt;br /&gt;
| When set to 1, starts the RTM reading.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;RTM_MAX_RST_CNT&amp;lt;/code&amp;gt;&lt;br /&gt;
| 1:0&lt;br /&gt;
| Max reset count for RTM mode. Valid values are:&lt;br /&gt;
* 0 (0b00) - 1&lt;br /&gt;
* 1 (0b01) - 3&lt;br /&gt;
* 2 (0b10) - 5&lt;br /&gt;
* 3 (0b11) - 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRL2 (0x21) ===&lt;br /&gt;
&lt;br /&gt;
{{note|These are taken from the BCM59055 driver, and haven&#039;t been tested on the BCM59054 yet. {{Speculation|Still, given that the ADCCTRL1 layout is the same, I suspect this one should be the same as well...}}}}&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7:6&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;GSM_DEBOUNCE&amp;lt;/code&amp;gt;&lt;br /&gt;
| 5&lt;br /&gt;
| If set to 1, enables ADC burst mode (todo, how does it work?).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;RTM_DLY&amp;lt;/code&amp;gt;&lt;br /&gt;
| 4:0&lt;br /&gt;
| RTM read delay. Valid values:&lt;br /&gt;
* 0  (0b00000) - 0ns&lt;br /&gt;
* 1  (0b00001) - 31.25ns&lt;br /&gt;
* 2  (0b00010) - 62.50ns&lt;br /&gt;
* 3  (0b00011) - 93.75ns&lt;br /&gt;
* 4  (0b00100) - 125ns&lt;br /&gt;
* 5  (0b00101) - 156.25ns&lt;br /&gt;
* 6  (0b00110) - 187.50ns&lt;br /&gt;
* 7  (0b00111) - 218.75ns&lt;br /&gt;
* 8  (0b01000) - 250ns&lt;br /&gt;
* 9  (0b01001) - 281.25ns&lt;br /&gt;
* 10 (0b01010) - 312.50ns&lt;br /&gt;
* 11 (0b01011) - 343.75ns&lt;br /&gt;
* 12 (0b01100) - 375ns&lt;br /&gt;
* 13 (0b01101) - 406.25ns&lt;br /&gt;
* 14 (0b01110) - 437.50ns&lt;br /&gt;
* 15 (0b01111) - 468.75ns&lt;br /&gt;
* 16 (0b10000) - 500ns&lt;br /&gt;
* 17 (0b10001) - 531.25ns&lt;br /&gt;
* 18 (0b10010) - 562.50ns&lt;br /&gt;
* 19 (0b10011) - 593.75ns&lt;br /&gt;
* 20 (0b10100) - 625ns&lt;br /&gt;
* 21 (0b10101) - 656.25ns&lt;br /&gt;
* 22 (0b10110) - 687.50ns&lt;br /&gt;
* 23 (0b10111) - 718.75ns&lt;br /&gt;
* 24 (0b11000) - 750ns&lt;br /&gt;
* 25 (0b11001) - 781.25ns&lt;br /&gt;
* 26 (0b11010) - 812.50ns&lt;br /&gt;
* 27 (0b11011) - 843.75ns&lt;br /&gt;
* 28 (0b11100) - 875ns&lt;br /&gt;
* 29 (0b11101) - 906.25ns&lt;br /&gt;
* 30 (0b11110) - 937.50ns&lt;br /&gt;
* 31 (0b11111) - 968.75ns&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRL3 - ADCCTRL28 ===&lt;br /&gt;
&lt;br /&gt;
ADC channel registers; see layout above.&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRL29 and ADCCTRL30 ===&lt;br /&gt;
&lt;br /&gt;
Unknown.&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/ADC&amp;diff=137</id>
		<title>Mainline:Broadcom Kona/BCM590xx/ADC</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/ADC&amp;diff=137"/>
		<updated>2025-08-31T15:34:27Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/hwmon/bcmpmu59xxx-hwmon.c}}, {{downstream|baffinlite|drivers/misc/bcm59055-adc.c}} (for BCM59055 but very well commented, and seems to be about the same as other models).}}&lt;br /&gt;
&lt;br /&gt;
The BCM590xx PMUs provide a 10-bit SAR (Successive Approximation) ADC.&lt;br /&gt;
&lt;br /&gt;
== Reading the ADC data ==&lt;br /&gt;
&lt;br /&gt;
Each ADC channel has two registers which immediately succeed each other. These registers follow the layout outlined below.&lt;br /&gt;
&lt;br /&gt;
To read the ADC data, one needs to combine the DATA_MSB bits (upper 2 bits, first two bits of the first register) with the DATA_LSB (lower 8 bits, entire value of the second register). An additional value at bit 2 is available to check the validity of the read data.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
data = ((reg1 &amp;amp; 0x3) &amp;lt;&amp;lt; 8) | reg2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRLx ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7:3&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;READ_INVALID&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2&lt;br /&gt;
| If 1, the read is invalid; 0 otherwise.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;DATA_MSB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 1:0&lt;br /&gt;
| Upper (most significant) 2 bits of the ADC data.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRLx+1 ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;DATA_LSB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7:0&lt;br /&gt;
| Lower (least significant) 8 bits of the ADC data.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RTM (Real-Time Measurment) ==&lt;br /&gt;
&lt;br /&gt;
The last ADC channel, RTM, is reserved for RTM (Real-Time Measurment) mode.&lt;br /&gt;
&lt;br /&gt;
The process for performing an RTM read is as follows:&lt;br /&gt;
&lt;br /&gt;
* In &amp;lt;code&amp;gt;ADCCTRL1&amp;lt;/code&amp;gt;: (these can all be performed in one write)&lt;br /&gt;
** Set the the &amp;lt;code&amp;gt;RTM_CONVERSION&amp;lt;/code&amp;gt; bit to enable RTM mode&lt;br /&gt;
** Write the channel number to read to the &amp;lt;code&amp;gt;RTM_CHAN&amp;lt;/code&amp;gt; offset&lt;br /&gt;
** Write the &amp;lt;code&amp;gt;RTM_START&amp;lt;/code&amp;gt; bit to start the RTM read&lt;br /&gt;
* Wait for the &amp;lt;code&amp;gt;ADC_RTM_DATA_READY&amp;lt;/code&amp;gt; interrupt.&lt;br /&gt;
* Perform a standard data read from the RTM ADC channel registers (see [[#Reading the data]]).&lt;br /&gt;
* Clear the &amp;lt;code&amp;gt;RTM_CONVERSION&amp;lt;/code&amp;gt; bit to disable RTM mode.&lt;br /&gt;
&lt;br /&gt;
== Register layout ==&lt;br /&gt;
&lt;br /&gt;
Values given here are for the BCM59054. These registers are located on map 1.&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRL1 (0x20) ===&lt;br /&gt;
&lt;br /&gt;
Contains settings for RTM mode.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;RTM_CHANN&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7:4&lt;br /&gt;
| Channel to read in RTM mode.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;RTM_CONVERSION&amp;lt;/code&amp;gt;&lt;br /&gt;
| 3&lt;br /&gt;
| Enable (0) or disable (1) RTM mode. Prerequisite for performing an RTM read.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;RTM_START&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2&lt;br /&gt;
| When set to 1, starts the RTM reading.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;RTM_MAX_RST_CNT&amp;lt;/code&amp;gt;&lt;br /&gt;
| 1:0&lt;br /&gt;
| Max reset count for RTM mode. Valid values are:&lt;br /&gt;
* 0 (0b00) - 1&lt;br /&gt;
* 1 (0b01) - 3&lt;br /&gt;
* 2 (0b10) - 5&lt;br /&gt;
* 3 (0b11) - 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRL2 (0x21) ===&lt;br /&gt;
&lt;br /&gt;
{{note|These are taken from the BCM59055 driver, and haven&#039;t been tested on the BCM59054 yet. {{Speculation|Still, given that the ADCCTRL1 layout is the same, I suspect this one should be the same as well...}}}}&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7:6&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;GSM_DEBOUNCE&amp;lt;/code&amp;gt;&lt;br /&gt;
| 5&lt;br /&gt;
| If set to 1, enables ADC burst mode (todo, how does it work?).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;RTM_DLY&amp;lt;/code&amp;gt;&lt;br /&gt;
| 4:0&lt;br /&gt;
| RTM read delay. Valid values:&lt;br /&gt;
* 0  (0b00000) - 0ns&lt;br /&gt;
* 1  (0b00001) - 31.25ns&lt;br /&gt;
* 2  (0b00010) - 62.50ns&lt;br /&gt;
* 3  (0b00011) - 93.75ns&lt;br /&gt;
* 4  (0b00100) - 125ns&lt;br /&gt;
* 5  (0b00101) - 156.25ns&lt;br /&gt;
* 6  (0b00110) - 187.50ns&lt;br /&gt;
* 7  (0b00111) - 218.75ns&lt;br /&gt;
* 8  (0b01000) - 250ns&lt;br /&gt;
* 9  (0b01001) - 281.25ns&lt;br /&gt;
* 10 (0b01010) - 312.50ns&lt;br /&gt;
* 11 (0b01011) - 343.75ns&lt;br /&gt;
* 12 (0b01100) - 375ns&lt;br /&gt;
* 13 (0b01101) - 406.25ns&lt;br /&gt;
* 14 (0b01110) - 437.50ns&lt;br /&gt;
* 15 (0b01111) - 468.75ns&lt;br /&gt;
* 16 (0b10000) - 500ns&lt;br /&gt;
* 17 (0b10001) - 531.25ns&lt;br /&gt;
* 18 (0b10010) - 562.50ns&lt;br /&gt;
* 19 (0b10011) - 593.75ns&lt;br /&gt;
* 20 (0b10100) - 625ns&lt;br /&gt;
* 21 (0b10101) - 656.25ns&lt;br /&gt;
* 22 (0b10110) - 687.50ns&lt;br /&gt;
* 23 (0b10111) - 718.75ns&lt;br /&gt;
* 24 (0b11000) - 750ns&lt;br /&gt;
* 25 (0b11001) - 781.25ns&lt;br /&gt;
* 26 (0b11010) - 812.50ns&lt;br /&gt;
* 27 (0b11011) - 843.75ns&lt;br /&gt;
* 28 (0b11100) - 875ns&lt;br /&gt;
* 29 (0b11101) - 906.25ns&lt;br /&gt;
* 30 (0b11110) - 937.50ns&lt;br /&gt;
* 31 (0b11111) - 968.75ns&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRL3 - ADCCTRL28 ===&lt;br /&gt;
&lt;br /&gt;
ADC channel registers; see layout above.&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRL29 and ADCCTRL30 ===&lt;br /&gt;
&lt;br /&gt;
Unknown.&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/ADC&amp;diff=136</id>
		<title>Mainline:Broadcom Kona/BCM590xx/ADC</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/ADC&amp;diff=136"/>
		<updated>2025-08-31T15:26:40Z</updated>

		<summary type="html">&lt;p&gt;Uart: /* RTM (Real-Time Measurment) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/hwmon/bcmpmu59xxx-hwmon.c}}, {{downstream|baffinlite|drivers/misc/bcm59055-adc.c}} (for BCM59055 but very well commented, and seems to be about the same as other models).}}&lt;br /&gt;
&lt;br /&gt;
The BCM590xx PMUs provide a 10-bit SAR (Successive Approximation) ADC.&lt;br /&gt;
&lt;br /&gt;
== Reading the ADC data ==&lt;br /&gt;
&lt;br /&gt;
Each ADC channel has two registers which immediately succeed each other. These registers follow the layout outlined below.&lt;br /&gt;
&lt;br /&gt;
To read the ADC data, one needs to combine the DATA_MSB bits (upper 2 bits, first two bits of the first register) with the DATA_LSB (lower 8 bits, entire value of the second register). An additional value at bit 2 is available to check the validity of the read data.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
data = ((reg1 &amp;amp; 0x3) &amp;lt;&amp;lt; 8) | reg2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRLx ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7:3&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;READ_INVALID&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2&lt;br /&gt;
| If 1, the read is invalid; 0 otherwise.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;DATA_MSB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 1:0&lt;br /&gt;
| Upper (most significant) 2 bits of the ADC data.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRLx+1 ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;DATA_LSB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7:0&lt;br /&gt;
| Lower (least significant) 8 bits of the ADC data.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RTM (Real-Time Measurment) ==&lt;br /&gt;
&lt;br /&gt;
The last ADC channel, RTM, is reserved for RTM (Real-Time Measurment) mode.&lt;br /&gt;
&lt;br /&gt;
The process for performing an RTM read is as follows:&lt;br /&gt;
&lt;br /&gt;
* In &amp;lt;code&amp;gt;ADCCTRL1&amp;lt;/code&amp;gt;: (these can all be performed in one write)&lt;br /&gt;
** Set the the &amp;lt;code&amp;gt;RTM_CONVERSION&amp;lt;/code&amp;gt; bit to enable RTM mode&lt;br /&gt;
** Write the channel number to read to the &amp;lt;code&amp;gt;RTM_CHAN&amp;lt;/code&amp;gt; offset&lt;br /&gt;
** Write the &amp;lt;code&amp;gt;RTM_START&amp;lt;/code&amp;gt; bit to start the RTM read&lt;br /&gt;
* Wait for the &amp;lt;code&amp;gt;ADC_RTM_DATA_READY&amp;lt;/code&amp;gt; interrupt.&lt;br /&gt;
* Perform a standard data read from the RTM ADC channel registers (see [[#Reading the data]]).&lt;br /&gt;
* Clear the &amp;lt;code&amp;gt;RTM_CONVERSION&amp;lt;/code&amp;gt; bit to disable RTM mode.&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/ADC&amp;diff=135</id>
		<title>Mainline:Broadcom Kona/BCM590xx/ADC</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/ADC&amp;diff=135"/>
		<updated>2025-08-31T14:58:15Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/hwmon/bcmpmu59xxx-hwmon.c}}, {{downstream|baffinlite|drivers/misc/bcm59055-adc.c}} (for BCM59055 but very well commented, and seems to be about the same as other models).}}&lt;br /&gt;
&lt;br /&gt;
The BCM590xx PMUs provide a 10-bit SAR (Successive Approximation) ADC.&lt;br /&gt;
&lt;br /&gt;
== Reading the ADC data ==&lt;br /&gt;
&lt;br /&gt;
Each ADC channel has two registers which immediately succeed each other. These registers follow the layout outlined below.&lt;br /&gt;
&lt;br /&gt;
To read the ADC data, one needs to combine the DATA_MSB bits (upper 2 bits, first two bits of the first register) with the DATA_LSB (lower 8 bits, entire value of the second register). An additional value at bit 2 is available to check the validity of the read data.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
data = ((reg1 &amp;amp; 0x3) &amp;lt;&amp;lt; 8) | reg2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRLx ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7:3&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;READ_INVALID&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2&lt;br /&gt;
| If 1, the read is invalid; 0 otherwise.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;DATA_MSB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 1:0&lt;br /&gt;
| Upper (most significant) 2 bits of the ADC data.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRLx+1 ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;DATA_LSB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7:0&lt;br /&gt;
| Lower (least significant) 8 bits of the ADC data.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RTM (Real-Time Measurment) ==&lt;br /&gt;
&lt;br /&gt;
The last ADC channel, RTM, is reserved for RTM (Real-Time Measurment) mode.&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/ADC&amp;diff=134</id>
		<title>Mainline:Broadcom Kona/BCM590xx/ADC</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/ADC&amp;diff=134"/>
		<updated>2025-08-31T14:56:28Z</updated>

		<summary type="html">&lt;p&gt;Uart: Created page with &amp;quot;{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/hwmon/bcmpmu59xxx-hwmon.c}}, {{downstream|baffinlite|drivers/misc/bcm59055-adc.}} (for BCM59055 but very well commented, and seems to be about the same as other models).}}  The BCM590xx PMUs provide a 10-bit SAR (Successive Approximation) ADC.  == Reading the ADC data ==  Each ADC channel has two registers which immediately succeed each other. These registers follow the layout outlined below.  To read the ADC d...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/hwmon/bcmpmu59xxx-hwmon.c}}, {{downstream|baffinlite|drivers/misc/bcm59055-adc.}} (for BCM59055 but very well commented, and seems to be about the same as other models).}}&lt;br /&gt;
&lt;br /&gt;
The BCM590xx PMUs provide a 10-bit SAR (Successive Approximation) ADC.&lt;br /&gt;
&lt;br /&gt;
== Reading the ADC data ==&lt;br /&gt;
&lt;br /&gt;
Each ADC channel has two registers which immediately succeed each other. These registers follow the layout outlined below.&lt;br /&gt;
&lt;br /&gt;
To read the ADC data, one needs to combine the DATA_MSB bits (upper 2 bits, first two bits of the first register) with the DATA_LSB (lower 8 bits, entire value of the second register). An additional value at bit 2 is available to check the validity of the read data.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
data = ((reg1 &amp;amp; 0x3) &amp;lt;&amp;lt; 8) | reg2;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRLx ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7:3&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;READ_INVALID&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2&lt;br /&gt;
| If 1, the read is invalid; 0 otherwise.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;DATA_MSB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 1:0&lt;br /&gt;
| Upper (most significant) 2 bits of the ADC data.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ADCCTRLx+1 ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;DATA_LSB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7:0&lt;br /&gt;
| Lower (least significant) 8 bits of the ADC data.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== RTM (Real-Time Measurment) ==&lt;br /&gt;
&lt;br /&gt;
The last ADC channel, RTM, is reserved for RTM (Real-Time Measurment) mode.&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx&amp;diff=133</id>
		<title>Mainline:Broadcom Kona/BCM590xx</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx&amp;diff=133"/>
		<updated>2025-08-31T14:45:25Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This &#039;&#039;&#039;root page&#039;&#039;&#039; connects all pages related to the BCM590xx series of PMICs, in particular the BCM59054 and BCM59056.&lt;br /&gt;
&lt;br /&gt;
The BCM590xx PMICs comprise of the following parts:&lt;br /&gt;
&lt;br /&gt;
* Internal interrupt controller ([[/Interrupts]])&lt;br /&gt;
* Regulators ([[/Regulators]] - WIP article, needs updates)&lt;br /&gt;
* Power-on key controller/PONKEY ([[/PONKEY]])&lt;br /&gt;
* RTC ([[/RTC]])&lt;br /&gt;
* Charger [[/Charger]])&lt;br /&gt;
* Fuel gauge ([[/Fuel gauge]])&lt;br /&gt;
* USB OTG control ([[/USB]])&lt;br /&gt;
* Audio amplifier (?)&lt;br /&gt;
* PWM LED controller&lt;br /&gt;
* ADC used e.g. for thermal monitoring ([[/ADC]])&lt;br /&gt;
&lt;br /&gt;
== Subpages ==&lt;br /&gt;
&lt;br /&gt;
{{Subpages|stripprefix=true}}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/USB&amp;diff=132</id>
		<title>Mainline:Broadcom Kona/BCM590xx/USB</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/USB&amp;diff=132"/>
		<updated>2025-08-27T13:11:27Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Hatnote|Downstream drivers: {{downstream|baffinlite|drivers/mfd/bcmpmu59xxx-accy-core.c}}, {{downstream|baffinlite|bcmpmu59xxx-accy-detect.c}}, {{downstream|baffinlite|drivers/mfd/bcmpmu59xxx-accy.c}} which is unused?, {{downstream|baffinlite|drivers/mfd/bcm590xx-usb.c}} for the BCM59055; {{downstream|baffinlite|drivers/usb/otg/bcm_otg_adp.c}}, {{downstream|baffinlite|drivers/usb/otg/bcmpmu59xxx_otg_xceiv.c}}, and to some extent external MUIC drivers which hook into the BCM59xxx drivers:}}&lt;br /&gt;
&lt;br /&gt;
The BCM590xx PMUs are capable of USB port management and cable detection.&lt;br /&gt;
&lt;br /&gt;
== Glossary ==&lt;br /&gt;
&lt;br /&gt;
Some terms get mentioned repeatedly in USB OTG code. These are common terms related to either the USB 2.0 spec or the USB OTG spec, and appear often in other drivers as well.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VBUS&#039;&#039;&#039; - the 5V power rail in an USB cable. When the device is charging or plugged in as a peripheral (e.g. to a computer), the voltage is provided by the charger; when an USB OTG dongle is plugged in (the device operates in host mode), it needs to provide its own voltage. Most PMUs, the BCM590xx included, provide a &amp;quot;VBUS boost&amp;quot; (&#039;&#039;VBUSB&#039;&#039;) mode to enable VBUS from the device for host mode and disable it for peripheral mode/charging.&lt;br /&gt;
* &#039;&#039;&#039;ID&#039;&#039;&#039; - The ID pin on the microUSB connector. A floating (not connected to ground) ID pin indicates that the device is to be connected as a peripheral; a grounded ID pin indicates the device should act as the host, and different resistance values between GND and ID can be used to switch between different device types (per the USB Carkit standard).&lt;br /&gt;
* &#039;&#039;&#039;ADP&#039;&#039;&#039; - From USB OTG docs: &amp;quot;The Attach Detection Protocol (ADP) allows an SRP-capable Targeted Host or peripheral-only B-device to detect when a remote device has been attached or detached when VBUS is not present.&amp;quot;&amp;lt;ref&amp;gt;https://ia601605.us.archive.org/7/items/usb_20_202303/USB_OTG_and_EH_2-0-version%201_1a.pdf section 5.4.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;SRP&#039;&#039;&#039; - Stands for &#039;&#039;Session Request Protocol&#039;&#039;. An SRP request can be sent by an USB peripheral to the host device to enable VBUS.&lt;br /&gt;
* &#039;&#039;&#039;BC1.2&#039;&#039;&#039; - the [https://www.usb.org/document-library/battery-charging-v12-spec-and-adopters-agreement USB Battery Charging 1.2 specification]. (Code might use &amp;quot;BC&amp;quot; or &amp;quot;BC12&amp;quot; to refer to it.)&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/USB&amp;diff=131</id>
		<title>Mainline:Broadcom Kona/BCM590xx/USB</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/USB&amp;diff=131"/>
		<updated>2025-08-27T13:01:33Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Hatnote|Downstream drivers: {{downstream|baffinlite|drivers/mfd/bcmpmu59xxx-accy-core.c}}, {{downstream|baffinlite|bcmpmu59xxx-accy-detect.c}}, {{downstream|baffinlite|drivers/mfd/bcmpmu59xxx-accy.c}} which is unused?, {{downstream|baffinlite|drivers/mfd/bcm590xx-usb.c}} for the BCM59055; {{downstream|baffinlite|drivers/usb/otg/bcm_otg_adp.c}}, {{downstream|baffinlite|drivers/usb/otg/bcmpmu59xxx_otg_xceiv.c}}, and to some extent external MUIC drivers which hook into the BCM59xxx drivers:}}&lt;br /&gt;
&lt;br /&gt;
The BCM590xx PMUs are capable of USB port management and cable detection.&lt;br /&gt;
&lt;br /&gt;
== Glossary ==&lt;br /&gt;
&lt;br /&gt;
Some terms get mentioned repeatedly in USB OTG code. These are common terms related to either the USB 2.0 spec or the USB OTG spec, and appear often in other drivers as well.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VBUS&#039;&#039;&#039; - the 5V power rail in an USB cable. When the device is charging or plugged in as a peripheral (e.g. to a computer), the voltage is provided by the charger; when an USB OTG dongle is plugged in (the device operates in host mode), it needs to provide its own voltage. Most PMUs, the BCM590xx included, provide a &amp;quot;VBUS boost&amp;quot; (&#039;&#039;VBUSB&#039;&#039;) mode to enable VBUS from the device for host mode and disable it for peripheral mode/charging.&lt;br /&gt;
* &#039;&#039;&#039;ID&#039;&#039;&#039; - The ID pin on the microUSB connector. A floating (not connected to ground) ID pin indicates that the device is to be connected as a peripheral; a grounded ID pin indicates the device should act as the host, and different resistance values between GND and ID can be used to switch between different device types (per the USB Carkit standard).&lt;br /&gt;
* &#039;&#039;&#039;ADP&#039;&#039;&#039; - From USB OTG docs: &amp;quot;The Attach Detection Protocol (ADP) allows an SRP-capable Targeted Host or peripheral-only B-device to detect when a remote device has been attached or detached when VBUS is not present.&amp;quot;&amp;lt;ref&amp;gt;https://ia601605.us.archive.org/7/items/usb_20_202303/USB_OTG_and_EH_2-0-version%201_1a.pdf section 5.4.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;SRP&#039;&#039;&#039; - Stands for &#039;&#039;Session Request Protocol&#039;&#039;. An SRP request can be sent by an USB peripheral to the host device to enable VBUS.&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/USB&amp;diff=130</id>
		<title>Mainline:Broadcom Kona/BCM590xx/USB</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/USB&amp;diff=130"/>
		<updated>2025-08-27T08:07:28Z</updated>

		<summary type="html">&lt;p&gt;Uart: /* Glossary */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Hatnote|Downstream drivers: {{downstream|baffinlite|drivers/mfd/bcmpmu59xxx-accy-core.c}}, {{downstream|baffinlite|bcmpmu59xxx-accy-detect.c}}, {{downstream|baffinlite|drivers/mfd/bcmpmu59xxx-accy.c}} which is unused?, {{downstream|baffinlite|drivers/mfd/bcm590xx-usb.c}} for the BCM59055.}}&lt;br /&gt;
&lt;br /&gt;
The BCM590xx PMUs are capable of USB port management and cable detection.&lt;br /&gt;
&lt;br /&gt;
== Glossary ==&lt;br /&gt;
&lt;br /&gt;
Some terms get mentioned repeatedly in USB OTG code. These are common terms related to either the USB 2.0 spec or the USB OTG spec, and appear often in other drivers as well.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VBUS&#039;&#039;&#039; - the 5V power rail in an USB cable. When the device is charging or plugged in as a peripheral (e.g. to a computer), the voltage is provided by the charger; when an USB OTG dongle is plugged in (the device operates in host mode), it needs to provide its own voltage. Most PMUs, the BCM590xx included, provide a &amp;quot;VBUS boost&amp;quot; (&#039;&#039;VBUSB&#039;&#039;) mode to enable VBUS from the device for host mode and disable it for peripheral mode/charging.&lt;br /&gt;
* &#039;&#039;&#039;ID&#039;&#039;&#039; - The ID pin on the microUSB connector. A floating (not connected to ground) ID pin indicates that the device is to be connected as a peripheral; a grounded ID pin indicates the device should act as the host, and different resistance values between GND and ID can be used to switch between different device types (per the USB Carkit standard).&lt;br /&gt;
* &#039;&#039;&#039;ADP&#039;&#039;&#039; - From USB OTG docs: &amp;quot;The Attach Detection Protocol (ADP) allows an SRP-capable Targeted Host or peripheral-only B-device to detect when a remote device has been attached or detached when VBUS is not present.&amp;quot;&amp;lt;ref&amp;gt;https://ia601605.us.archive.org/7/items/usb_20_202303/USB_OTG_and_EH_2-0-version%201_1a.pdf section 5.4.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;SRP&#039;&#039;&#039; - Stands for &#039;&#039;Session Request Protocol&#039;&#039;. An SRP request can be sent by an USB peripheral to the host device to enable VBUS.&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/USB&amp;diff=129</id>
		<title>Mainline:Broadcom Kona/BCM590xx/USB</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/USB&amp;diff=129"/>
		<updated>2025-08-27T06:22:11Z</updated>

		<summary type="html">&lt;p&gt;Uart: Created page with &amp;quot;{{Hatnote|Downstream drivers: {{downstream|baffinlite|drivers/mfd/bcmpmu59xxx-accy-core.c}}, {{downstream|baffinlite|bcmpmu59xxx-accy-detect.c}}, {{downstream|baffinlite|drivers/mfd/bcmpmu59xxx-accy.c}} which is unused?, {{downstream|baffinlite|drivers/mfd/bcm590xx-usb.c}} for the BCM59055.}}  The BCM590xx PMUs are capable of USB port management and cable detection.  == Glossary ==  Some terms get mentioned repeatedly in USB OTG code. These are common terms related to ei...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Hatnote|Downstream drivers: {{downstream|baffinlite|drivers/mfd/bcmpmu59xxx-accy-core.c}}, {{downstream|baffinlite|bcmpmu59xxx-accy-detect.c}}, {{downstream|baffinlite|drivers/mfd/bcmpmu59xxx-accy.c}} which is unused?, {{downstream|baffinlite|drivers/mfd/bcm590xx-usb.c}} for the BCM59055.}}&lt;br /&gt;
&lt;br /&gt;
The BCM590xx PMUs are capable of USB port management and cable detection.&lt;br /&gt;
&lt;br /&gt;
== Glossary ==&lt;br /&gt;
&lt;br /&gt;
Some terms get mentioned repeatedly in USB OTG code. These are common terms related to either the USB 2.0 spec or the USB OTG spec, and appear often in other drivers as well.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VBUS&#039;&#039;&#039; - the 5V power rail in an USB cable. When the device is charging or plugged in as a peripheral (e.g. to a computer), the voltage is provided by the charger; when an USB OTG dongle is plugged in (the device operates in host mode), it needs to provide its own voltage. Most PMUs, the BCM590xx included, provide a &amp;quot;VBUS boost&amp;quot; (&#039;&#039;VBUSB&#039;&#039;) mode to enable VBUS from the device for host mode and disable it for peripheral mode/charging.&lt;br /&gt;
* &#039;&#039;&#039;ID&#039;&#039;&#039; - The ID pin on the microUSB connector. A floating (not connected to ground) ID pin indicates that the device is to be connected as a peripheral; a grounded ID pin indicates the device should act as the host, and different resistance values between GND and ID can be used to switch between different device types (per the USB Carkit standard).&lt;br /&gt;
* &#039;&#039;&#039;ADP&#039;&#039;&#039; - From USB OTG docs: &amp;quot;The Attach Detection Protocol (ADP) allows an SRP-capable Targeted Host or peripheral-only B-device to detect when a remote device has been attached or detached when VBUS is not present.&amp;quot;&amp;lt;ref&amp;gt;https://ia601605.us.archive.org/7/items/usb_20_202303/USB_OTG_and_EH_2-0-version%201_1a.pdf section 5.4.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;SRP&#039;&#039;&#039; - Stands for &#039;&#039;Session Request Protocol&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/PONKEY&amp;diff=128</id>
		<title>Mainline:Broadcom Kona/BCM590xx/PONKEY</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/PONKEY&amp;diff=128"/>
		<updated>2025-08-17T09:56:37Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/input/misc/bcmpmu59xxx_ponkey.c}}}}&lt;br /&gt;
&lt;br /&gt;
The BCM590XX PMU can handle a power-on key (the responsible section is nicknamed PONKEY).&lt;br /&gt;
&lt;br /&gt;
== Key press detection ==&lt;br /&gt;
&lt;br /&gt;
When a key is pressed, the internal IRQ for a key press (BCM59054_IRQ_POK_PRESSED/BCM59056_IRQ_PONKEYB_F) is raised; when it is released, the internal IRQ for a key release (BCM59054_IRQ_POK_RELEASED/BCM59056_IRQ_PONKEYB_R) is raised. A driver can interpret these IRQs to toggle a key on/off (in downstream, it&#039;s wired up to &amp;lt;code&amp;gt;KEY_POWER&amp;lt;/code&amp;gt; by default.&lt;br /&gt;
&lt;br /&gt;
=== Debounce interval ===&lt;br /&gt;
&lt;br /&gt;
A debounce interval can be configured independently for button press and release. The debounce values are 3 bits wide and stored in &amp;lt;code&amp;gt;PONKEYCTRL1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For the BCM59054/BCM59056, the allowed values are 330ns, 1.2ms, 10ms, 50ms, 100ms, 500ms, 1000ms and 2000ms. For the BCM59039/BCM59042/BCM59055, the allowed values are undocumented, but different from BCM59054/56 - &amp;lt;code&amp;gt;3&amp;lt;/code&amp;gt; is equal to 100ms (whereas it&#039;s 50ms on 54/56).&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
TODO. Seems like it might be possible to control long-press function using a timer (one of &amp;quot;poweroff&amp;quot;, &amp;quot;restart&amp;quot; or &amp;quot;smart reset&amp;quot;). [https://github.com/knuxdroid/android_kernel_samsung_baffinlite/blob/cm-12.1/drivers/input/misc/bcmpmu59xxx_ponkey.c#L204-L277 Relevant kernel sources], notably commented out.&lt;br /&gt;
&lt;br /&gt;
== Registers (BCM59054) ==&lt;br /&gt;
&lt;br /&gt;
{{hatnote|See {{downstream|baffinlite|include/linux/mfd/bcmpmu59054_reg.h}}.}}&lt;br /&gt;
&lt;br /&gt;
All of them are on MAP0.&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL1 (0x08) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;RELEASE_DEB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 5:3&lt;br /&gt;
| Represents the release debounce. &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;PRESS_DEB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2:0&lt;br /&gt;
| Represents the press debounce.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL2 (0x09) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TX1_ACTION&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7:6&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TX1_DLY&amp;lt;/code&amp;gt;&lt;br /&gt;
| 5:3&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TX1_DEB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2:0&lt;br /&gt;
| TODO&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL3 (0x0A) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TX2_ACTION&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7:6&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TX2_DLY&amp;lt;/code&amp;gt;&lt;br /&gt;
| 5:3&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TX2_DEB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2:0&lt;br /&gt;
| TODO&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL4 (0x0B) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KEY_PAD_LOCK_MODE&amp;lt;/code&amp;gt;&lt;br /&gt;
| 6&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KEY_PAD_LOCK&amp;lt;/code&amp;gt;&lt;br /&gt;
| 5&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;POK_RESTART_EN&amp;lt;/code&amp;gt;&lt;br /&gt;
| 4&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 3&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;POK_WAKUP_DEB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2:0&lt;br /&gt;
| TODO&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL5 (0x0C) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7:0&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL6 (0x0D) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7:5&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SMART_RST_DLY&amp;lt;/code&amp;gt;&lt;br /&gt;
| 4:3&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SMART_RST_STATUS&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SMART_RST_PWR_EN&amp;lt;/code&amp;gt;&lt;br /&gt;
| 1&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SMART_RST_EN&amp;lt;/code&amp;gt;&lt;br /&gt;
| 0&lt;br /&gt;
| TODO&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL7 (0x0E) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7:0&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL8 (0x0F) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TX3_ACTION&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7:6&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TX3_DLY&amp;lt;/code&amp;gt;&lt;br /&gt;
| 5:3&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TX3_DEB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2:0&lt;br /&gt;
| TODO&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Template:Todo&amp;diff=127</id>
		<title>Template:Todo</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Template:Todo&amp;diff=127"/>
		<updated>2025-08-17T09:39:41Z</updated>

		<summary type="html">&lt;p&gt;Uart: Created page with &amp;quot;&amp;lt;!-- Dark-mode colors are defined in the template style --&amp;gt;&amp;lt;templatestyles src=&amp;quot;Todo/style.css&amp;quot;/&amp;gt;&amp;lt;!-- --&amp;gt;&amp;lt;includeonly&amp;gt;{{Icon box | box-icons = TODO | box-text = &amp;lt;b&amp;gt;TODO:&amp;lt;/b&amp;gt; {{{1}}} | border-color = #b60000 | border-width = 1px | background = #fdd1d1 | class = box-todo }}&amp;lt;!-- Category: --&amp;gt;{{#if: {{{nocategory|}}}||Category:To-do items}}&amp;lt;/includeonly&amp;gt;&amp;lt;!--  --&amp;gt;&amp;lt;noinclude&amp;gt; &amp;lt;templatedata&amp;gt; { 	&amp;quot;params&amp;quot;: { 		&amp;quot;1&amp;quot;: { 			&amp;quot;label&amp;quot;: &amp;quot;Text&amp;quot;...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- Dark-mode colors are defined in the template style --&amp;gt;&amp;lt;templatestyles src=&amp;quot;Todo/style.css&amp;quot;/&amp;gt;&amp;lt;!--&lt;br /&gt;
--&amp;gt;&amp;lt;includeonly&amp;gt;{{Icon box&lt;br /&gt;
| box-icons = [[File:Red warning icon.svg|20px|link=|TODO]]&lt;br /&gt;
| box-text = &amp;lt;b&amp;gt;TODO:&amp;lt;/b&amp;gt; {{{1}}}&lt;br /&gt;
| border-color = #b60000&lt;br /&gt;
| border-width = 1px&lt;br /&gt;
| background = #fdd1d1&lt;br /&gt;
| class = box-todo&lt;br /&gt;
}}&amp;lt;!--&lt;br /&gt;
Category:&lt;br /&gt;
--&amp;gt;{{#if: {{{nocategory|}}}||[[Category:To-do items]]}}&amp;lt;/includeonly&amp;gt;&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;templatedata&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;params&amp;quot;: {&lt;br /&gt;
		&amp;quot;1&amp;quot;: {&lt;br /&gt;
			&amp;quot;label&amp;quot;: &amp;quot;Text&amp;quot;,&lt;br /&gt;
			&amp;quot;description&amp;quot;: &amp;quot;Text to place in the box&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;: &amp;quot;unbalanced-wikitext&amp;quot;,&lt;br /&gt;
			&amp;quot;required&amp;quot;: true&lt;br /&gt;
		},&lt;br /&gt;
		&amp;quot;nocategory&amp;quot;: {&lt;br /&gt;
			&amp;quot;label&amp;quot;: &amp;quot;No category&amp;quot;,&lt;br /&gt;
			&amp;quot;description&amp;quot;: &amp;quot;If true/yes, do not add this page to the \&amp;quot;To-do items\&amp;quot; category.&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;: &amp;quot;boolean&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;description&amp;quot;: &amp;quot;TODO box containing a to-do item. Also adds the page to the \&amp;quot;To-do items\&amp;quot; category; this behavior can be disabled with the \&amp;quot;nocategory\&amp;quot; parameter.&amp;quot;,&lt;br /&gt;
	&amp;quot;format&amp;quot;: &amp;quot;inline&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/templatedata&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;{{todo|This is &#039;&#039;&#039;yet to be done&#039;&#039;&#039;.}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{todo|This is &#039;&#039;&#039;yet to be done&#039;&#039;&#039;.|nocategory=yes}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/RTC&amp;diff=126</id>
		<title>Mainline:Broadcom Kona/BCM590xx/RTC</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/RTC&amp;diff=126"/>
		<updated>2025-08-15T17:41:04Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/rtc/rtc-bcmpmu59xxx.c}}}}&lt;br /&gt;
&lt;br /&gt;
The BCM590XX PMUs provide a real-time clock.&lt;br /&gt;
&lt;br /&gt;
== Time data ==&lt;br /&gt;
&lt;br /&gt;
The RTC stores the time in the following format:&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Purpose&lt;br /&gt;
!Mask&lt;br /&gt;
!Value&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|Second (&amp;lt;code&amp;gt;SC&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x3F&lt;br /&gt;
|Current second, from 0 to 59.&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Minute (&amp;lt;code&amp;gt;MN&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x3F&lt;br /&gt;
|Current minute of the hour, from 0 to 59.&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Hour (&amp;lt;code&amp;gt;HR&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x1F&lt;br /&gt;
|Current hour of the day, from 0 to 23.&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Weekday (&amp;lt;code&amp;gt;WD&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x07&lt;br /&gt;
|Day of week, from 0 to 6. Appears to roll over whenever the day changes; {{speculation|the hardware does not enforce a specific start.}} Sets itself to 0 on reset. &#039;&#039;&#039;Not used in downstream.&#039;&#039;&#039;&amp;lt;br&amp;gt;{{speculation|The day of month sets itself to 0 on reset, which should be an invalid value, but would suggest that the range is 0 -&amp;gt; Sunday, 6 -&amp;gt; Monday, but there is no downstream code to confirm this.}}&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Day of month (&amp;lt;code&amp;gt;DT&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x1F&lt;br /&gt;
|Day of month, starting from 1. Sets itself to 0 on reset.&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Month (&amp;lt;code&amp;gt;MT_WD&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x0F&lt;br /&gt;
|Number of the month. 1 to 12 represent January-December.&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|Year (&amp;lt;code&amp;gt;YR&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0xFF&lt;br /&gt;
|Amount of years since 2000 (0 = 2000, 1 = 2001, etc.)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This exact format is used for both the time and alarm registers. The masks are enforced by hardware - any bit written outside of the mask gets ignored.&lt;br /&gt;
&lt;br /&gt;
== Getting the time ==&lt;br /&gt;
&lt;br /&gt;
On the BCM59054 and BCM59056, time registers start at 0xE0 and follow the format outlined above.&lt;br /&gt;
&lt;br /&gt;
There are interrupts for updates of each of the time values.&lt;br /&gt;
&lt;br /&gt;
The default reset value is &amp;lt;code&amp;gt;0 0 0 0 0 1 7&amp;lt;/code&amp;gt; (2007-01-00 00:00:00, weekday 0). Notably, the day of month is invalid (0).&lt;br /&gt;
&lt;br /&gt;
If the date overflows (1 second after 2255-12-31 23:59:59), the clock returns to 2255-12-01 00:00:00.&lt;br /&gt;
&lt;br /&gt;
=== Adjustment IRQ ===&lt;br /&gt;
&lt;br /&gt;
There is an RTCADJ IRQ that is supposed to fire when the RTC value is invalid (at least according to the comments of the downstream driver, and the downstream BCM59055 RTC driver). However, I haven&#039;t been able to get it to fire in my testing.&lt;br /&gt;
&lt;br /&gt;
== Alarm ==&lt;br /&gt;
&lt;br /&gt;
On the BCM59054 and BCM59056, the alarm registers start at 0xE7.&lt;br /&gt;
&lt;br /&gt;
There is an interrupt that is triggered when the alarm is triggered.&lt;br /&gt;
&lt;br /&gt;
== Calibration ==&lt;br /&gt;
&lt;br /&gt;
{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/char/broadcom/rtc_cal/bcm_rtc_cal.c}}}}&lt;br /&gt;
&lt;br /&gt;
There are three calibration registers: CALIB1, CALIB2 and CALIB3.&lt;br /&gt;
&lt;br /&gt;
{{todo|Figure out how the calibration process works, this is just my initial idea}}&lt;br /&gt;
&lt;br /&gt;
{{speculation|Calibration appears to be triggered based on a CP (communications processor) event; it receives a message from the CP and uses a value from it as the &amp;quot;ratio&amp;quot;.}} The ratio value is then compared against &amp;lt;code&amp;gt;RTCCAL_Ratio&amp;lt;/code&amp;gt; (taken from &amp;lt;code&amp;gt;rtccal_data.nom_ratio&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;8666667&amp;lt;/code&amp;gt;); if &amp;lt;code&amp;gt;ratio &amp;gt; RTCCAL_Ratio&amp;lt;/code&amp;gt;, then direction is 1, otherwise it&#039;s 0.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; value is then calculated based on the difference between the new and old ratio (&amp;lt;code&amp;gt;diff = abs(ratio - RTCCAL_Ratio)&amp;lt;/code&amp;gt;): &amp;lt;code&amp;gt;clk_val = RTCCAL_Ratio / diff&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
TODO - what is the ratio value?&lt;br /&gt;
&lt;br /&gt;
=== CALIB1 (0xF4) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; (1)&lt;br /&gt;
| 7:0&lt;br /&gt;
| Lower 8 bits of the calibration offset.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CALIB2 (0xF5) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; (2)&lt;br /&gt;
| 7:0&lt;br /&gt;
| Upper 8 bits of the calibration offset.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CALIB3 (0xF6) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;???&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7&lt;br /&gt;
| Set to 1 during calibration.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;direction&amp;lt;/code&amp;gt;&lt;br /&gt;
| 6&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| Unknown/reserved&lt;br /&gt;
| 5:0&lt;br /&gt;
| Unknown/reserved.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/PONKEY&amp;diff=125</id>
		<title>Mainline:Broadcom Kona/BCM590xx/PONKEY</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/PONKEY&amp;diff=125"/>
		<updated>2025-08-15T17:32:35Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/input/misc/bcmpmu59xxx_ponkey.c}}}}&lt;br /&gt;
&lt;br /&gt;
The BCM590XX PMU can handle a power-on key (the responsible section is nicknamed PONKEY).&lt;br /&gt;
&lt;br /&gt;
== Key press detection ==&lt;br /&gt;
&lt;br /&gt;
When a key is pressed, the internal IRQ for a key press (BCM59054_IRQ_POK_PRESSED/BCM59056_IRQ_PONKEYB_F) is raised; when it is released, the internal IRQ for a key release (BCM59054_IRQ_POK_RELEASED/BCM59056_IRQ_PONKEYB_R) is raised. A driver can interpret these IRQs to toggle a key on/off (in downstream, it&#039;s wired up to &amp;lt;code&amp;gt;KEY_POWER&amp;lt;/code&amp;gt; by default.&lt;br /&gt;
&lt;br /&gt;
=== Debounce interval ===&lt;br /&gt;
&lt;br /&gt;
A debounce interval can be configured independently for button press and release. The debounce values are 3 bits wide and stored in &amp;lt;code&amp;gt;PONKEYCTRL1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For the BCM59054/BCM59056, the allowed values are 330ns, 1.2ms, 10ms, 50ms, 100ms, 500ms, 1000ms and 2000ms. For the BCM59039/BCM59042/BCM59055, the allowed values are undocumented, but different from BCM59054/56 - &amp;lt;code&amp;gt;3&amp;lt;/code&amp;gt; is equal to 100ms (whereas it&#039;s 50ms on 54/56).&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
TODO. Seems like it might be possible to control long-press function using a timer (one of &amp;quot;poweroff&amp;quot;, &amp;quot;restart&amp;quot; or &amp;quot;smart reset&amp;quot;). [https://github.com/knuxdroid/android_kernel_samsung_baffinlite/blob/cm-12.1/drivers/input/misc/bcmpmu59xxx_ponkey.c#L204-L277 Relevant kernel sources], notably commented out.&lt;br /&gt;
&lt;br /&gt;
== Registers (BCM59054) ==&lt;br /&gt;
&lt;br /&gt;
{{hatnote|See {{downstream|baffinlite|include/linux/mfd/bcmpmu59054_reg.h}}.}}&lt;br /&gt;
&lt;br /&gt;
All of them are on MAP0.&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL1 (0x08) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;RELEASE_DEB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 5:3&lt;br /&gt;
| Represents the release debounce. &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;PRESS_DEB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2:0&lt;br /&gt;
| Represents the press debounce.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL2 (0x09) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TX_ACTION&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7:6&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TX_DLY&amp;lt;/code&amp;gt;&lt;br /&gt;
| 5:3&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TX_DEB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2:0&lt;br /&gt;
| TODO&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL3 (0x0A) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7:0&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL4 (0x0B) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KEY_PAD_LOCK_MODE&amp;lt;/code&amp;gt;&lt;br /&gt;
| 6&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KEY_PAD_LOCK&amp;lt;/code&amp;gt;&lt;br /&gt;
| 5&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;POK_RESTART_EN&amp;lt;/code&amp;gt;&lt;br /&gt;
| 4&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 3&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;POK_WAKUP_DEB&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2:0&lt;br /&gt;
| TODO&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL5 (0x0C) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7:0&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL6 (0x0D) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7:5&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SMART_RST_DLY&amp;lt;/code&amp;gt;&lt;br /&gt;
| 4:3&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SMART_RST_STATUS&amp;lt;/code&amp;gt;&lt;br /&gt;
| 2&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SMART_RST_PWR_EN&amp;lt;/code&amp;gt;&lt;br /&gt;
| 1&lt;br /&gt;
| TODO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SMART_RST_EN&amp;lt;/code&amp;gt;&lt;br /&gt;
| 0&lt;br /&gt;
| TODO&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL7 (0x0E) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7:0&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== PONKEYCTRL8 (0x0F) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
| 7:0&lt;br /&gt;
| Reserved/unknown&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/PONKEY&amp;diff=124</id>
		<title>Mainline:Broadcom Kona/BCM590xx/PONKEY</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/PONKEY&amp;diff=124"/>
		<updated>2025-08-15T17:16:30Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The BCM590XX PMU can handle a power-on key (the responsible section is nicknamed PONKEY).&lt;br /&gt;
&lt;br /&gt;
== Key press detection ==&lt;br /&gt;
&lt;br /&gt;
When a key is pressed, the internal IRQ for a key press (BCM59054_IRQ_POK_PRESSED/BCM59056_IRQ_PONKEYB_F) is raised; when it is released, the internal IRQ for a key release (BCM59054_IRQ_POK_RELEASED/BCM59056_IRQ_PONKEYB_R) is raised. A driver can interpret these IRQs to toggle a key on/off (in downstream, it&#039;s wired up to &amp;lt;code&amp;gt;KEY_POWER&amp;lt;/code&amp;gt; by default.&lt;br /&gt;
&lt;br /&gt;
=== Debounce interval ===&lt;br /&gt;
&lt;br /&gt;
A debounce interval can be configured independently for button press and release. The debounce values are 3 bits wide and stored in &amp;lt;code&amp;gt;PONKEYCTRL1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For the BCM59054/BCM59056, the allowed values are 330ns, 1.2ms, 10ms, 50ms, 100ms, 500ms, 1000ms and 2000ms. For the BCM59039/BCM59042/BCM59055, the allowed values are undocumented, but different from BCM59054/56 - &amp;lt;code&amp;gt;3&amp;lt;/code&amp;gt; is equal to 100ms (whereas it&#039;s 50ms on 54/56).&lt;br /&gt;
&lt;br /&gt;
== Timer ==&lt;br /&gt;
&lt;br /&gt;
TODO. Seems like it might be possible to control long-press function using a timer (one of &amp;quot;poweroff&amp;quot;, &amp;quot;restart&amp;quot; or &amp;quot;smart reset&amp;quot;). [https://github.com/knuxdroid/android_kernel_samsung_baffinlite/blob/cm-12.1/drivers/input/misc/bcmpmu59xxx_ponkey.c#L204-L277 Relevant kernel sources], notably commented out.&lt;br /&gt;
&lt;br /&gt;
{{Subpages}}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/RTC&amp;diff=123</id>
		<title>Mainline:Broadcom Kona/BCM590xx/RTC</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/RTC&amp;diff=123"/>
		<updated>2025-08-15T12:57:56Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/rtc/rtc-bcmpmu59xxx.c}}}}&lt;br /&gt;
&lt;br /&gt;
The BCM590XX PMUs provide a real-time clock.&lt;br /&gt;
&lt;br /&gt;
== Time data ==&lt;br /&gt;
&lt;br /&gt;
The RTC stores the time in the following format:&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Purpose&lt;br /&gt;
!Mask&lt;br /&gt;
!Value&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|Second (&amp;lt;code&amp;gt;SC&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x3F&lt;br /&gt;
|Current second, from 0 to 59.&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Minute (&amp;lt;code&amp;gt;MN&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x3F&lt;br /&gt;
|Current minute of the hour, from 0 to 59.&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Hour (&amp;lt;code&amp;gt;HR&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x1F&lt;br /&gt;
|Current hour of the day, from 0 to 23.&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Weekday (&amp;lt;code&amp;gt;WD&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x07&lt;br /&gt;
|Day of week, from 0 to 6. Appears to roll over whenever the day changes; {{speculation|the hardware does not enforce a specific start.}} Sets itself to 0 on reset. &#039;&#039;&#039;Not used in downstream.&#039;&#039;&#039;&amp;lt;br&amp;gt;{{speculation|The day of month sets itself to 0 on reset, which should be an invalid value, but would suggest that the range is 0 -&amp;gt; Sunday, 6 -&amp;gt; Monday, but there is no downstream code to confirm this.}}&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Day of month (&amp;lt;code&amp;gt;DT&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x1F&lt;br /&gt;
|Day of month, starting from 1. Sets itself to 0 on reset.&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Month (&amp;lt;code&amp;gt;MT_WD&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x0F&lt;br /&gt;
|Number of the month. 1 to 12 represent January-December.&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|Year (&amp;lt;code&amp;gt;YR&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0xFF&lt;br /&gt;
|Amount of years since 2000 (0 = 2000, 1 = 2001, etc.)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This exact format is used for both the time and alarm registers. The masks are enforced by hardware - any bit written outside of the mask gets ignored.&lt;br /&gt;
&lt;br /&gt;
== Getting the time ==&lt;br /&gt;
&lt;br /&gt;
On the BCM59054 and BCM59056, time registers start at 0xE0 and follow the format outlined above.&lt;br /&gt;
&lt;br /&gt;
There are interrupts for updates of each of the time values.&lt;br /&gt;
&lt;br /&gt;
The default reset value is &amp;lt;code&amp;gt;0 0 0 0 0 1 7&amp;lt;/code&amp;gt; (2007-01-00 00:00:00, weekday 0). Notably, the day of month is invalid (0). In this state, the RTCADJ interrupt will be raised.&lt;br /&gt;
&lt;br /&gt;
If the date overflows (1 second after 2255-12-31 23:59:59), the clock returns to 2255-12-01 00:00:00.&lt;br /&gt;
&lt;br /&gt;
=== Adjustment IRQ ===&lt;br /&gt;
&lt;br /&gt;
There is an RTCADJ IRQ that is supposed to fire when the RTC value is invalid (at least according to the comments of the downstream driver, and the downstream BCM59055 RTC driver). However, I haven&#039;t been able to get it to fire in my testing.&lt;br /&gt;
&lt;br /&gt;
== Alarm ==&lt;br /&gt;
&lt;br /&gt;
On the BCM59054 and BCM59056, the alarm registers start at 0xE7.&lt;br /&gt;
&lt;br /&gt;
There is an interrupt that is triggered when the alarm is triggered.&lt;br /&gt;
&lt;br /&gt;
== Calibration ==&lt;br /&gt;
&lt;br /&gt;
{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/char/broadcom/rtc_cal/bcm_rtc_cal.c}}}}&lt;br /&gt;
&lt;br /&gt;
There are three calibration registers: CALIB1, CALIB2 and CALIB3.&lt;br /&gt;
&lt;br /&gt;
{{todo|Figure out how the calibration process works, this is just my initial idea}}&lt;br /&gt;
&lt;br /&gt;
{{speculation|Calibration appears to be triggered based on a CP (communications processor) event; it receives a message from the CP and uses a value from it as the &amp;quot;ratio&amp;quot;.}} The ratio value is then compared against &amp;lt;code&amp;gt;RTCCAL_Ratio&amp;lt;/code&amp;gt; (taken from &amp;lt;code&amp;gt;rtccal_data.nom_ratio&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;8666667&amp;lt;/code&amp;gt;); if &amp;lt;code&amp;gt;ratio &amp;gt; RTCCAL_Ratio&amp;lt;/code&amp;gt;, then direction is 1, otherwise it&#039;s 0.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; value is then calculated based on the difference between the new and old ratio (&amp;lt;code&amp;gt;diff = abs(ratio - RTCCAL_Ratio)&amp;lt;/code&amp;gt;): &amp;lt;code&amp;gt;clk_val = RTCCAL_Ratio / diff&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
TODO - what is the ratio value?&lt;br /&gt;
&lt;br /&gt;
=== CALIB1 (0xF4) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; (1)&lt;br /&gt;
| 7:0&lt;br /&gt;
| Lower 8 bits of the calibration offset.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CALIB2 (0xF5) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; (2)&lt;br /&gt;
| 7:0&lt;br /&gt;
| Upper 8 bits of the calibration offset.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CALIB3 (0xF6) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;???&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7&lt;br /&gt;
| Set to 1 during calibration.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;direction&amp;lt;/code&amp;gt;&lt;br /&gt;
| 6&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| Unknown/reserved&lt;br /&gt;
| 5:0&lt;br /&gt;
| Unknown/reserved.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/RTC&amp;diff=122</id>
		<title>Mainline:Broadcom Kona/BCM590xx/RTC</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/RTC&amp;diff=122"/>
		<updated>2025-08-15T12:47:29Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/rtc/rtc-bcmpmu59xxx.c}}}}&lt;br /&gt;
&lt;br /&gt;
The BCM590XX PMUs provide a real-time clock.&lt;br /&gt;
&lt;br /&gt;
== Time data ==&lt;br /&gt;
&lt;br /&gt;
The RTC stores the time in the following format:&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Purpose&lt;br /&gt;
!Mask&lt;br /&gt;
!Value&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|Second (&amp;lt;code&amp;gt;SC&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x3F&lt;br /&gt;
|Current second, from 0 to 59.&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Minute (&amp;lt;code&amp;gt;MN&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x3F&lt;br /&gt;
|Current minute of the hour, from 0 to 59.&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Hour (&amp;lt;code&amp;gt;HR&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x1F&lt;br /&gt;
|Current hour of the day, from 0 to 23.&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Weekday (&amp;lt;code&amp;gt;WD&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x07&lt;br /&gt;
|Day of week, from 0 to 6. Appears to roll over whenever the day changes; {{speculation|the hardware does not enforce a specific start.}} Sets itself to 0 on reset. &#039;&#039;&#039;Not used in downstream.&#039;&#039;&#039;&amp;lt;br&amp;gt;{{speculation|The day of month sets itself to 0 on reset, which should be an invalid value, but would suggest that the range is 0 -&amp;gt; Sunday, 6 -&amp;gt; Monday, but there is no downstream code to confirm this.}}&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Day of month (&amp;lt;code&amp;gt;DT&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x1F&lt;br /&gt;
|Day of month, starting from 1. Sets itself to 0 on reset.&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Month (&amp;lt;code&amp;gt;MT_WD&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x0F&lt;br /&gt;
|Number of the month. 1 to 12 represent January-December.&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|Year (&amp;lt;code&amp;gt;YR&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0xFF&lt;br /&gt;
|Amount of years since 2000 (0 = 2000, 1 = 2001, etc.)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This exact format is used for both the time and alarm registers. In the time registers, the masks are enforced by hardware - any bit written outside of the mask gets ignored.&lt;br /&gt;
&lt;br /&gt;
== Getting the time ==&lt;br /&gt;
&lt;br /&gt;
On the BCM59054 and BCM59056, time registers start at 0xE0 and follow the format outlined above.&lt;br /&gt;
&lt;br /&gt;
There are interrupts for updates of each of the time values.&lt;br /&gt;
&lt;br /&gt;
The default reset value is &amp;lt;code&amp;gt;0 0 0 0 0 1 7&amp;lt;/code&amp;gt; (2007-01-00 00:00:00, weekday 0). Notably, the day of month is invalid (0). In this state, the RTCADJ interrupt will be raised.&lt;br /&gt;
&lt;br /&gt;
If the date overflows (1 second after 2255-12-31 23:59:59), the clock returns to 2255-12-01 00:00:00.&lt;br /&gt;
&lt;br /&gt;
=== Adjustment IRQ ===&lt;br /&gt;
&lt;br /&gt;
There is an RTCADJ IRQ that is supposed to fire when the RTC value is invalid (at least according to the comments of the downstream driver, and the downstream BCM59055 RTC driver). However, I haven&#039;t been able to get it to fire in my testing.&lt;br /&gt;
&lt;br /&gt;
== Alarm ==&lt;br /&gt;
&lt;br /&gt;
On the BCM59054 and BCM59056, the alarm registers start at 0xE7.&lt;br /&gt;
&lt;br /&gt;
There is an interrupt that is triggered when the alarm is triggered.&lt;br /&gt;
&lt;br /&gt;
== Calibration ==&lt;br /&gt;
&lt;br /&gt;
{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/char/broadcom/rtc_cal/bcm_rtc_cal.c}}}}&lt;br /&gt;
&lt;br /&gt;
There are three calibration registers: CALIB1, CALIB2 and CALIB3.&lt;br /&gt;
&lt;br /&gt;
{{todo|Figure out how the calibration process works, this is just my initial idea}}&lt;br /&gt;
&lt;br /&gt;
{{speculation|Calibration appears to be triggered based on a CP (communications processor) event; it receives a message from the CP and uses a value from it as the &amp;quot;ratio&amp;quot;.}} The ratio value is then compared against &amp;lt;code&amp;gt;RTCCAL_Ratio&amp;lt;/code&amp;gt; (taken from &amp;lt;code&amp;gt;rtccal_data.nom_ratio&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;8666667&amp;lt;/code&amp;gt;); if &amp;lt;code&amp;gt;ratio &amp;gt; RTCCAL_Ratio&amp;lt;/code&amp;gt;, then direction is 1, otherwise it&#039;s 0.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; value is then calculated based on the difference between the new and old ratio (&amp;lt;code&amp;gt;diff = abs(ratio - RTCCAL_Ratio)&amp;lt;/code&amp;gt;): &amp;lt;code&amp;gt;clk_val = RTCCAL_Ratio / diff&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
TODO - what is the ratio value?&lt;br /&gt;
&lt;br /&gt;
=== CALIB1 (0xF4) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; (1)&lt;br /&gt;
| 7:0&lt;br /&gt;
| Lower 8 bits of the calibration offset.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CALIB2 (0xF5) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; (2)&lt;br /&gt;
| 7:0&lt;br /&gt;
| Upper 8 bits of the calibration offset.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CALIB3 (0xF6) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;???&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7&lt;br /&gt;
| Set to 1 during calibration.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;direction&amp;lt;/code&amp;gt;&lt;br /&gt;
| 6&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| Unknown/reserved&lt;br /&gt;
| 5:0&lt;br /&gt;
| Unknown/reserved.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/RTC&amp;diff=121</id>
		<title>Mainline:Broadcom Kona/BCM590xx/RTC</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/RTC&amp;diff=121"/>
		<updated>2025-08-15T12:45:20Z</updated>

		<summary type="html">&lt;p&gt;Uart: /* Getting the time */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/rtc/rtc-bcmpmu59xxx.c}}}}&lt;br /&gt;
&lt;br /&gt;
The BCM590XX PMUs provide a real-time clock.&lt;br /&gt;
&lt;br /&gt;
== Time data ==&lt;br /&gt;
&lt;br /&gt;
The RTC stores the time in the following format:&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Purpose&lt;br /&gt;
!Mask&lt;br /&gt;
!Value&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|Second (&amp;lt;code&amp;gt;SC&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x3F&lt;br /&gt;
|Current second, from 0 to 59.&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Minute (&amp;lt;code&amp;gt;MN&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x3F&lt;br /&gt;
|Current minute of the hour, from 0 to 59.&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Hour (&amp;lt;code&amp;gt;HR&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x1F&lt;br /&gt;
|Current hour of the day, from 0 to 23.&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Weekday (&amp;lt;code&amp;gt;WD&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x07&lt;br /&gt;
|Day of week, from 0 to 6. Appears to roll over whenever the day changes; {{speculation|the hardware does not enforce a specific start.}} Sets itself to 0 on reset. &#039;&#039;&#039;Not used in downstream.&#039;&#039;&#039;&amp;lt;br&amp;gt;{{speculation|The day of month sets itself to 0 on reset, which should be an invalid value, but would suggest that the range is 0 -&amp;gt; Sunday, 6 -&amp;gt; Monday, but there is no downstream code to confirm this.}}&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Day of month (&amp;lt;code&amp;gt;DT&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x1F&lt;br /&gt;
|Day of month, starting from 1. Sets itself to 0 on reset.&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Month (&amp;lt;code&amp;gt;MT_WD&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x0F&lt;br /&gt;
|Number of the month. 1 to 12 represent January-December.&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|Year (&amp;lt;code&amp;gt;YR&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0xFF&lt;br /&gt;
|Amount of years since 2000 (0 = 2000, 1 = 2001, etc.)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This exact format is used for both the time and alarm registers. In the time registers, the masks are enforced by hardware - any bit written outside of the mask gets ignored.&lt;br /&gt;
&lt;br /&gt;
== Getting the time ==&lt;br /&gt;
&lt;br /&gt;
On the BCM59054 and BCM59056, time registers start at 0xE0 and follow the format outlined above.&lt;br /&gt;
&lt;br /&gt;
There are interrupts for updates of each of the time values.&lt;br /&gt;
&lt;br /&gt;
The default reset value is &amp;lt;code&amp;gt;0 0 0 0 0 1 7&amp;lt;/code&amp;gt; (2007-01-00 00:00:00, weekday 0). Notably, the day of month is invalid (0). In this state, the RTCADJ interrupt will be raised.&lt;br /&gt;
&lt;br /&gt;
If the date overflows (1 second after 2255-12-31 23:59:59), the clock returns to 2255-12-01 00:00:00.&lt;br /&gt;
&lt;br /&gt;
== Alarm ==&lt;br /&gt;
&lt;br /&gt;
On the BCM59054 and BCM59056, the alarm registers start at 0xE7.&lt;br /&gt;
&lt;br /&gt;
There is an interrupt that is triggered when the alarm is triggered.&lt;br /&gt;
&lt;br /&gt;
== Calibration ==&lt;br /&gt;
&lt;br /&gt;
{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/char/broadcom/rtc_cal/bcm_rtc_cal.c}}}}&lt;br /&gt;
&lt;br /&gt;
There are three calibration registers: CALIB1, CALIB2 and CALIB3.&lt;br /&gt;
&lt;br /&gt;
{{todo|Figure out how the calibration process works, this is just my initial idea}}&lt;br /&gt;
&lt;br /&gt;
{{speculation|Calibration appears to be triggered based on a CP (communications processor) event; it receives a message from the CP and uses a value from it as the &amp;quot;ratio&amp;quot;.}} The ratio value is then compared against &amp;lt;code&amp;gt;RTCCAL_Ratio&amp;lt;/code&amp;gt; (taken from &amp;lt;code&amp;gt;rtccal_data.nom_ratio&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;8666667&amp;lt;/code&amp;gt;); if &amp;lt;code&amp;gt;ratio &amp;gt; RTCCAL_Ratio&amp;lt;/code&amp;gt;, then direction is 1, otherwise it&#039;s 0.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; value is then calculated based on the difference between the new and old ratio (&amp;lt;code&amp;gt;diff = abs(ratio - RTCCAL_Ratio)&amp;lt;/code&amp;gt;): &amp;lt;code&amp;gt;clk_val = RTCCAL_Ratio / diff&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
TODO - what is the ratio value?&lt;br /&gt;
&lt;br /&gt;
=== CALIB1 (0xF4) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; (1)&lt;br /&gt;
| 7:0&lt;br /&gt;
| Lower 8 bits of the calibration offset.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CALIB2 (0xF5) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; (2)&lt;br /&gt;
| 7:0&lt;br /&gt;
| Upper 8 bits of the calibration offset.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CALIB3 (0xF6) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;???&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7&lt;br /&gt;
| Set to 1 during calibration.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;direction&amp;lt;/code&amp;gt;&lt;br /&gt;
| 6&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| Unknown/reserved&lt;br /&gt;
| 5:0&lt;br /&gt;
| Unknown/reserved.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/RTC&amp;diff=120</id>
		<title>Mainline:Broadcom Kona/BCM590xx/RTC</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/RTC&amp;diff=120"/>
		<updated>2025-08-15T12:44:06Z</updated>

		<summary type="html">&lt;p&gt;Uart: /* Time data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/rtc/rtc-bcmpmu59xxx.c}}}}&lt;br /&gt;
&lt;br /&gt;
The BCM590XX PMUs provide a real-time clock.&lt;br /&gt;
&lt;br /&gt;
== Time data ==&lt;br /&gt;
&lt;br /&gt;
The RTC stores the time in the following format:&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Purpose&lt;br /&gt;
!Mask&lt;br /&gt;
!Value&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|Second (&amp;lt;code&amp;gt;SC&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x3F&lt;br /&gt;
|Current second, from 0 to 59.&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Minute (&amp;lt;code&amp;gt;MN&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x3F&lt;br /&gt;
|Current minute of the hour, from 0 to 59.&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Hour (&amp;lt;code&amp;gt;HR&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x1F&lt;br /&gt;
|Current hour of the day, from 0 to 23.&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Weekday (&amp;lt;code&amp;gt;WD&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x07&lt;br /&gt;
|Day of week, from 0 to 6. Appears to roll over whenever the day changes; {{speculation|the hardware does not enforce a specific start.}} Sets itself to 0 on reset. &#039;&#039;&#039;Not used in downstream.&#039;&#039;&#039;&amp;lt;br&amp;gt;{{speculation|The day of month sets itself to 0 on reset, which should be an invalid value, but would suggest that the range is 0 -&amp;gt; Sunday, 6 -&amp;gt; Monday, but there is no downstream code to confirm this.}}&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Day of month (&amp;lt;code&amp;gt;DT&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x1F&lt;br /&gt;
|Day of month, starting from 1. Sets itself to 0 on reset.&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Month (&amp;lt;code&amp;gt;MT_WD&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x0F&lt;br /&gt;
|Number of the month. 1 to 12 represent January-December.&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|Year (&amp;lt;code&amp;gt;YR&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0xFF&lt;br /&gt;
|Amount of years since 2000 (0 = 2000, 1 = 2001, etc.)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This exact format is used for both the time and alarm registers. In the time registers, the masks are enforced by hardware - any bit written outside of the mask gets ignored.&lt;br /&gt;
&lt;br /&gt;
== Getting the time ==&lt;br /&gt;
&lt;br /&gt;
On the BCM59054 and BCM59056, time registers start at 0xE0 and follow the format outlined above.&lt;br /&gt;
&lt;br /&gt;
There are interrupts for updates of each of the time values.&lt;br /&gt;
&lt;br /&gt;
The default reset value is &amp;lt;code&amp;gt;0 0 0 0 0 1 7&amp;lt;/code&amp;gt; (2007-01-00 00:00:00, weekday 0). Notably, the day of month is invalid (0). In this state, the RTCADJ interrupt will be raised.&lt;br /&gt;
&lt;br /&gt;
== Alarm ==&lt;br /&gt;
&lt;br /&gt;
On the BCM59054 and BCM59056, the alarm registers start at 0xE7.&lt;br /&gt;
&lt;br /&gt;
There is an interrupt that is triggered when the alarm is triggered.&lt;br /&gt;
&lt;br /&gt;
== Calibration ==&lt;br /&gt;
&lt;br /&gt;
{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/char/broadcom/rtc_cal/bcm_rtc_cal.c}}}}&lt;br /&gt;
&lt;br /&gt;
There are three calibration registers: CALIB1, CALIB2 and CALIB3.&lt;br /&gt;
&lt;br /&gt;
{{todo|Figure out how the calibration process works, this is just my initial idea}}&lt;br /&gt;
&lt;br /&gt;
{{speculation|Calibration appears to be triggered based on a CP (communications processor) event; it receives a message from the CP and uses a value from it as the &amp;quot;ratio&amp;quot;.}} The ratio value is then compared against &amp;lt;code&amp;gt;RTCCAL_Ratio&amp;lt;/code&amp;gt; (taken from &amp;lt;code&amp;gt;rtccal_data.nom_ratio&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;8666667&amp;lt;/code&amp;gt;); if &amp;lt;code&amp;gt;ratio &amp;gt; RTCCAL_Ratio&amp;lt;/code&amp;gt;, then direction is 1, otherwise it&#039;s 0.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; value is then calculated based on the difference between the new and old ratio (&amp;lt;code&amp;gt;diff = abs(ratio - RTCCAL_Ratio)&amp;lt;/code&amp;gt;): &amp;lt;code&amp;gt;clk_val = RTCCAL_Ratio / diff&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
TODO - what is the ratio value?&lt;br /&gt;
&lt;br /&gt;
=== CALIB1 (0xF4) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; (1)&lt;br /&gt;
| 7:0&lt;br /&gt;
| Lower 8 bits of the calibration offset.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CALIB2 (0xF5) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; (2)&lt;br /&gt;
| 7:0&lt;br /&gt;
| Upper 8 bits of the calibration offset.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CALIB3 (0xF6) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;???&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7&lt;br /&gt;
| Set to 1 during calibration.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;direction&amp;lt;/code&amp;gt;&lt;br /&gt;
| 6&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| Unknown/reserved&lt;br /&gt;
| 5:0&lt;br /&gt;
| Unknown/reserved.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/RTC&amp;diff=119</id>
		<title>Mainline:Broadcom Kona/BCM590xx/RTC</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/RTC&amp;diff=119"/>
		<updated>2025-08-15T12:38:57Z</updated>

		<summary type="html">&lt;p&gt;Uart: /* Time data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/rtc/rtc-bcmpmu59xxx.c}}}}&lt;br /&gt;
&lt;br /&gt;
The BCM590XX PMUs provide a real-time clock.&lt;br /&gt;
&lt;br /&gt;
== Time data ==&lt;br /&gt;
&lt;br /&gt;
The RTC stores the time in the following format:&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Purpose&lt;br /&gt;
!Mask&lt;br /&gt;
!Value&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|Second (&amp;lt;code&amp;gt;SC&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x3F&lt;br /&gt;
|Current second, from 0 to 59.&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Minute (&amp;lt;code&amp;gt;MN&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x3F&lt;br /&gt;
|Current minute of the hour, from 0 to 59.&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Hour (&amp;lt;code&amp;gt;HR&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x1F&lt;br /&gt;
|Current hour of the day, from 0 to 23.&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Weekday (&amp;lt;code&amp;gt;WD&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x0F&lt;br /&gt;
|Day of week, from 0 to 6. Appears to roll over whenever the day changes; {{speculation|the hardware does not enforce a specific start.}} Sets itself to 0 on reset. &#039;&#039;&#039;Not used in downstream.&#039;&#039;&#039;&amp;lt;br&amp;gt;{{speculation|The day of month sets itself to 0 on reset, which should be an invalid value, but would suggest that the range is 0 -&amp;gt; Sunday, 6 -&amp;gt; Monday, but there is no downstream code to confirm this.}}&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Day of month (&amp;lt;code&amp;gt;DT&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x1F&lt;br /&gt;
|Day of month, starting from 1. Sets itself to 0 on reset.&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Month (&amp;lt;code&amp;gt;MT_WD&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x0F&lt;br /&gt;
|Number of the month. 1 to 12 represent January-December.&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|Year (&amp;lt;code&amp;gt;YR&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0xFF&lt;br /&gt;
|Amount of years since 2000 (0 = 2000, 1 = 2001, etc.)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This exact format is used for both the time and alarm registers. In the time registers, the masks are enforced by hardware - any bit written outside of the mask gets ignored.&lt;br /&gt;
&lt;br /&gt;
TODO: What happens on year overflow? Is there a reason as to why the downstream driver limits the values it gets?&lt;br /&gt;
&lt;br /&gt;
== Getting the time ==&lt;br /&gt;
&lt;br /&gt;
On the BCM59054 and BCM59056, time registers start at 0xE0 and follow the format outlined above.&lt;br /&gt;
&lt;br /&gt;
There are interrupts for updates of each of the time values.&lt;br /&gt;
&lt;br /&gt;
The default reset value is &amp;lt;code&amp;gt;0 0 0 0 0 1 7&amp;lt;/code&amp;gt; (2007-01-00 00:00:00, weekday 0). Notably, the day of month is invalid (0). In this state, the RTCADJ interrupt will be raised.&lt;br /&gt;
&lt;br /&gt;
== Alarm ==&lt;br /&gt;
&lt;br /&gt;
On the BCM59054 and BCM59056, the alarm registers start at 0xE7.&lt;br /&gt;
&lt;br /&gt;
There is an interrupt that is triggered when the alarm is triggered.&lt;br /&gt;
&lt;br /&gt;
== Calibration ==&lt;br /&gt;
&lt;br /&gt;
{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/char/broadcom/rtc_cal/bcm_rtc_cal.c}}}}&lt;br /&gt;
&lt;br /&gt;
There are three calibration registers: CALIB1, CALIB2 and CALIB3.&lt;br /&gt;
&lt;br /&gt;
{{todo|Figure out how the calibration process works, this is just my initial idea}}&lt;br /&gt;
&lt;br /&gt;
{{speculation|Calibration appears to be triggered based on a CP (communications processor) event; it receives a message from the CP and uses a value from it as the &amp;quot;ratio&amp;quot;.}} The ratio value is then compared against &amp;lt;code&amp;gt;RTCCAL_Ratio&amp;lt;/code&amp;gt; (taken from &amp;lt;code&amp;gt;rtccal_data.nom_ratio&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;8666667&amp;lt;/code&amp;gt;); if &amp;lt;code&amp;gt;ratio &amp;gt; RTCCAL_Ratio&amp;lt;/code&amp;gt;, then direction is 1, otherwise it&#039;s 0.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; value is then calculated based on the difference between the new and old ratio (&amp;lt;code&amp;gt;diff = abs(ratio - RTCCAL_Ratio)&amp;lt;/code&amp;gt;): &amp;lt;code&amp;gt;clk_val = RTCCAL_Ratio / diff&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
TODO - what is the ratio value?&lt;br /&gt;
&lt;br /&gt;
=== CALIB1 (0xF4) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; (1)&lt;br /&gt;
| 7:0&lt;br /&gt;
| Lower 8 bits of the calibration offset.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CALIB2 (0xF5) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; (2)&lt;br /&gt;
| 7:0&lt;br /&gt;
| Upper 8 bits of the calibration offset.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CALIB3 (0xF6) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;???&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7&lt;br /&gt;
| Set to 1 during calibration.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;direction&amp;lt;/code&amp;gt;&lt;br /&gt;
| 6&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| Unknown/reserved&lt;br /&gt;
| 5:0&lt;br /&gt;
| Unknown/reserved.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
	<entry>
		<id>https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/RTC&amp;diff=118</id>
		<title>Mainline:Broadcom Kona/BCM590xx/RTC</title>
		<link rel="alternate" type="text/html" href="https://wiki.dissonant.dev/index.php?title=Mainline:Broadcom_Kona/BCM590xx/RTC&amp;diff=118"/>
		<updated>2025-08-15T12:21:16Z</updated>

		<summary type="html">&lt;p&gt;Uart: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/rtc/rtc-bcmpmu59xxx.c}}}}&lt;br /&gt;
&lt;br /&gt;
The BCM590XX PMUs provide a real-time clock.&lt;br /&gt;
&lt;br /&gt;
== Time data ==&lt;br /&gt;
&lt;br /&gt;
The RTC stores the time in the following format:&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Purpose&lt;br /&gt;
!Mask&lt;br /&gt;
!Value&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|Second (&amp;lt;code&amp;gt;SC&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x3F&lt;br /&gt;
|Current second, from 0 to 59.&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Minute (&amp;lt;code&amp;gt;MN&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x3F&lt;br /&gt;
|Current minute of the hour, from 0 to 59.&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Hour (&amp;lt;code&amp;gt;HR&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x1F&lt;br /&gt;
|Current hour of the day, from 0 to 23.&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Weekday (&amp;lt;code&amp;gt;WD&amp;lt;/code&amp;gt;)&lt;br /&gt;
|{{speculation|0x0F}}&lt;br /&gt;
|Day of week, from 0 to 6. Appears to roll over whenever the day changes; {{speculation|the hardware does not enforce a specific start.}} Sets itself to 0 on reset. &#039;&#039;&#039;Not used in downstream.&#039;&#039;&#039;&amp;lt;br&amp;gt;{{speculation|The day of month sets itself to 0 on reset, which should be an invalid value, but would suggest that the range is 0 -&amp;gt; Sunday, 6 -&amp;gt; Monday, but there is no downstream code to confirm this.}}&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Day of month (&amp;lt;code&amp;gt;DT&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x1F&lt;br /&gt;
|Day of month, starting from 1. Sets itself to 0 on reset.&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Month (&amp;lt;code&amp;gt;MT_WD&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0x0F&lt;br /&gt;
|Number of the month. 1 to 12 represent January-December.&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|Year (&amp;lt;code&amp;gt;YR&amp;lt;/code&amp;gt;)&lt;br /&gt;
|0xFF&lt;br /&gt;
|Amount of years since 2000 (0 = 2000, 1 = 2001, etc.)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This exact format is used for both the time and alarm registers.&lt;br /&gt;
&lt;br /&gt;
TODO: What happens on year overflow? Is there a reason as to why the downstream driver limits the values it gets?&lt;br /&gt;
&lt;br /&gt;
== Getting the time ==&lt;br /&gt;
&lt;br /&gt;
On the BCM59054 and BCM59056, time registers start at 0xE0 and follow the format outlined above.&lt;br /&gt;
&lt;br /&gt;
There are interrupts for updates of each of the time values.&lt;br /&gt;
&lt;br /&gt;
The default reset value is &amp;lt;code&amp;gt;0 0 0 0 0 1 7&amp;lt;/code&amp;gt; (2007-01-00 00:00:00, weekday 0). Notably, the day of month is invalid (0). In this state, the RTCADJ interrupt will be raised.&lt;br /&gt;
&lt;br /&gt;
== Alarm ==&lt;br /&gt;
&lt;br /&gt;
On the BCM59054 and BCM59056, the alarm registers start at 0xE7.&lt;br /&gt;
&lt;br /&gt;
There is an interrupt that is triggered when the alarm is triggered.&lt;br /&gt;
&lt;br /&gt;
== Calibration ==&lt;br /&gt;
&lt;br /&gt;
{{hatnote|Downstream driver: {{downstream|baffinlite|drivers/char/broadcom/rtc_cal/bcm_rtc_cal.c}}}}&lt;br /&gt;
&lt;br /&gt;
There are three calibration registers: CALIB1, CALIB2 and CALIB3.&lt;br /&gt;
&lt;br /&gt;
{{todo|Figure out how the calibration process works, this is just my initial idea}}&lt;br /&gt;
&lt;br /&gt;
{{speculation|Calibration appears to be triggered based on a CP (communications processor) event; it receives a message from the CP and uses a value from it as the &amp;quot;ratio&amp;quot;.}} The ratio value is then compared against &amp;lt;code&amp;gt;RTCCAL_Ratio&amp;lt;/code&amp;gt; (taken from &amp;lt;code&amp;gt;rtccal_data.nom_ratio&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;8666667&amp;lt;/code&amp;gt;); if &amp;lt;code&amp;gt;ratio &amp;gt; RTCCAL_Ratio&amp;lt;/code&amp;gt;, then direction is 1, otherwise it&#039;s 0.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; value is then calculated based on the difference between the new and old ratio (&amp;lt;code&amp;gt;diff = abs(ratio - RTCCAL_Ratio)&amp;lt;/code&amp;gt;): &amp;lt;code&amp;gt;clk_val = RTCCAL_Ratio / diff&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
TODO - what is the ratio value?&lt;br /&gt;
&lt;br /&gt;
=== CALIB1 (0xF4) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; (1)&lt;br /&gt;
| 7:0&lt;br /&gt;
| Lower 8 bits of the calibration offset.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CALIB2 (0xF5) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clk_val&amp;lt;/code&amp;gt; (2)&lt;br /&gt;
| 7:0&lt;br /&gt;
| Upper 8 bits of the calibration offset.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== CALIB3 (0xF6) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable bittable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Bit&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;???&amp;lt;/code&amp;gt;&lt;br /&gt;
| 7&lt;br /&gt;
| Set to 1 during calibration.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;direction&amp;lt;/code&amp;gt;&lt;br /&gt;
| 6&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| Unknown/reserved&lt;br /&gt;
| 5:0&lt;br /&gt;
| Unknown/reserved.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Uart</name></author>
	</entry>
</feed>