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