[bsp/raspberry-pi] update DM support

- reorganize common Raspberry Pi drivers under the device framework
- add the Raspberry Pi 5 BSP, configuration and documentation
- add BCM2712 and DesignWare AXI DMA controller support
- distinguish BCM2712 DMA32 and DMA40 channels by channel mask
- restore DesignWare AXI DMA enable bits after controller reset
- support a shared AXI maximum burst length across DMA channels

Signed-off-by: GuEe-GUI <2991707448@qq.com>
This commit is contained in:
GuEe-GUI
2026-08-16 19:56:03 +08:00
committed by Rbb666
parent 2bcc47d418
commit f7258a6bb8
266 changed files with 35759 additions and 17641 deletions
+8 -8
View File
@@ -271,14 +271,14 @@ This document is based on the RT-Thread mainline repository and categorizes the
#### 🟡 Raspberry Pi
| BSP Name | GPIO | UART | I2C | SPI | RTC | SD Card | SDIO | MailBox | WDT | SMP | HDMI | Timer | Bluetooth | Ethernet | MIPI DSI | ILI9486 SPI LCD | XPT2046 TOUCH |
|----------|------|------|-----|-----|-----|---------|------|---------|-----|-----|------|-------|-----------|----------|----------|-----------------|----------------|
| [raspi-dm2.0](raspberry-pi/raspi-dm2.0) | - | ✅ | - | - | - | ✅ | - | - | - | - | - | - | - | - | - | - | - |
| [raspi2](raspberry-pi/raspi2) | - | ✅ | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - |
| [raspi3-32](raspberry-pi/raspi3-32) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - | ✅ | ✅ | ✅ | ✅ | ✅ | - | - | - | - | - |
| [raspi3-64](raspberry-pi/raspi3-64) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - | ✅ | ✅ | - | ✅ | ✅ | - | - | - | - | - |
| [raspi4-32](raspberry-pi/raspi4-32) | ✅ | ✅ | ✅ | ✅ | ✅ | - | ✅ | ✅ | ✅ | - | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| [raspi4-64](raspberry-pi/raspi4-64) | ✅ | ✅ | - | ✅ | - | - | ✅ | ✅ | ✅ | - | ✅ | ✅ | - | ✅ | - | - | - |
| BSP Name | GPIO | UART | I2C | SPI | RTC | SD Card | SDIO | MailBox | WDT | SMP | HDMI | Timer | Bluetooth | Ethernet | PCIe | DMA | ADC | PWM | MIPI DSI | ILI9486 SPI LCD | XPT2046 TOUCH |
|----------|------|------|-----|-----|-----|---------|------|---------|-----|-----|------|-------|-----------|----------|------|-----|-----|-----|----------|-----------------|----------------|
| [raspi2](raspberry-pi/raspi2) | - | ✅ | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - |
| [raspi3-32](raspberry-pi/raspi3-32) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - | ✅ | ✅ | ✅ | ✅ | ✅ | - | - | - | - | - | - | - | - | - |
| [raspi3-64](raspberry-pi/raspi3-64) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - | - | - | ✅ | - | ✅ | - | - | - |
| [raspi4-32](raspberry-pi/raspi4-32) | ✅ | ✅ | ✅ | ✅ | ✅ | - | ✅ | ✅ | ✅ | - | ✅ | ✅ | ✅ | ✅ | - | - | - | - | ✅ | ✅ | ✅ |
| [raspi4-64](raspberry-pi/raspi4-64) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - | ✅ | ✅ | ✅ | - | ✅ | - | ✅ | ✅ |
| [raspi5](raspberry-pi/raspi5) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - | ✅ | ✅ | ✅ | ✅ | ✅ | - | ✅ | ✅ |
#### 🟡 AT32
+8
View File
@@ -0,0 +1,8 @@
kernel*.img
rtthread.bin
*.dtb
*.qcow2
flash.bin
rtt.asm
rtthread.map
build/
+33
View File
@@ -0,0 +1,33 @@
SOC_DM_ADC_DIR = $(SOC_DM_DIR)/adc
SOC_DM_AUDIO_DIR = $(SOC_DM_DIR)/audio
SOC_DM_CLK_DIR = $(SOC_DM_DIR)/clk
SOC_DM_DMA_DIR = $(SOC_DM_DIR)/dma
SOC_DM_DVFS_CPUFREQ_DIR = $(SOC_DM_DIR)/dvfs
SOC_DM_ETHERNET_DIR = $(SOC_DM_DIR)/ethernet
SOC_DM_FIRMWARE_DIR = $(SOC_DM_DIR)/firmware
SOC_DM_GRAPHIC_BACKLIGHT_DIR = $(SOC_DM_DIR)/graphic/backlight
SOC_DM_GRAPHIC_FB_DIR = $(SOC_DM_DIR)/graphic/framebuffer
SOC_DM_GRAPHIC_LOGO_DIR = $(SOC_DM_DIR)/graphic/logo
SOC_DM_HWCRYPTO_DIR = $(SOC_DM_DIR)/hwcrypto
SOC_DM_CLOCK_TIME_DIR = $(SOC_DM_DIR)/clock_time
SOC_DM_I2C_DIR = $(SOC_DM_DIR)/i2c
SOC_DM_INPUT_JOYSTICK_DIR = $(SOC_DM_DIR)/input/joystick
SOC_DM_INPUT_TOUCHSCREEN_DIR = $(SOC_DM_DIR)/input/touchscreen
SOC_DM_MBOX_DIR = $(SOC_DM_DIR)/mailbox
SOC_DM_MFD_DIR = $(SOC_DM_DIR)/mfd
SOC_DM_NVMEM_DIR = $(SOC_DM_DIR)/nvmem
SOC_DM_PCI_DIR = $(SOC_DM_DIR)/pci
SOC_DM_PHY_DIR = $(SOC_DM_DIR)/phy
SOC_DM_PIC_DIR = $(SOC_DM_DIR)/pic
SOC_DM_PIN_DIR = $(SOC_DM_DIR)/pin
SOC_DM_PINCTRL_DIR = $(SOC_DM_DIR)/pinctrl
SOC_DM_PMDOMAIN_DIR = $(SOC_DM_DIR)/pmdomain
SOC_DM_PWM_DIR = $(SOC_DM_DIR)/pwm
SOC_DM_RESET_DIR = $(SOC_DM_DIR)/reset
SOC_DM_RTC_DIR = $(SOC_DM_DIR)/rtc
SOC_DM_SDIO_DIR = $(SOC_DM_DIR)/sdio
SOC_DM_SERIAL_DIR = $(SOC_DM_DIR)/serial
SOC_DM_SOC_DIR = $(SOC_DM_DIR)/soc
SOC_DM_SPI_DIR = $(SOC_DM_DIR)/spi
SOC_DM_THERMAL_DIR = $(SOC_DM_DIR)/thermal
SOC_DM_WDT_DIR = $(SOC_DM_DIR)/watchdog
-1
View File
@@ -1,4 +1,3 @@
# for module compiling
import os
from building import *
+6
View File
@@ -0,0 +1,6 @@
config RT_ADC_RP1
bool "RP1 ADC and temperature sensor driver"
depends on RT_USING_DM
depends on RT_USING_ADC
depends on RT_USING_REGULATOR
default n
+13
View File
@@ -0,0 +1,13 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_ADC_RP1']):
src += ['adc-rp1.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
+328
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -0,0 +1,4 @@
config RT_AUDIO_BCM2835_I2S
bool "Broadcom BCM2835 I2S"
depends on RT_USING_DMA
default n
+13
View File
@@ -0,0 +1,13 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_AUDIO_BCM2835_I2S']):
src += ['bcm2835-i2s.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
+19
View File
@@ -0,0 +1,19 @@
config RT_CLK_BCM2711_DVP
bool "Broadcom BCM2711 DVP support"
depends on RT_USING_OFW
default n
config RT_CLK_BCM2835
bool "Broadcom BCM2835 clock support"
depends on RT_USING_OFW
default n
config RT_CLK_RASPBERRYPI
bool "Raspberry Pi firmware based clock support"
depends on RT_USING_OFW
default n
config RT_CLK_RP1
bool "RP1 clock support"
depends on RT_USING_OFW
default n
+22
View File
@@ -0,0 +1,22 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_CLK_BCM2711_DVP']):
src += ['clk-bcm2711-dvp.c']
if GetDepend(['RT_CLK_BCM2835']):
src += ['clk-bcm2835-aux.c', 'clk-bcm2835.c', 'clk-dsi.c']
if GetDepend(['RT_CLK_RASPBERRYPI']):
src += ['clk-raspberrypi.c']
if GetDepend(['RT_CLK_RP1']):
src += ['clk-rp1.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1976
View File
File diff suppressed because it is too large Load Diff
+139
View File
@@ -0,0 +1,139 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-26 GuEe-GUI first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#define DBG_TAG "clk.dsi"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
struct dsi_clk
{
struct rt_clk_node parent;
};
struct dsi_clk_output
{
struct rt_clk_cell cell;
rt_ubase_t div;
};
static rt_ubase_t dsi_clk_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t parent_rate)
{
struct dsi_clk_output *clk = rt_container_of(cell, struct dsi_clk_output, cell);
return parent_rate / clk->div;
}
static rt_base_t dsi_clk_round_rate(struct rt_clk_cell *cell, rt_ubase_t drate, rt_ubase_t *prate)
{
struct dsi_clk_output *clk = rt_container_of(cell, struct dsi_clk_output, cell);
return *prate / clk->div;
}
const struct rt_clk_ops dsi_clk_ops =
{
.recalc_rate = dsi_clk_recalc_rate,
.round_rate = dsi_clk_round_rate,
};
#define REGISTER_CLK_DSI(_name, _div) \
(void *)&(struct dsi_clk_output) \
{ \
.cell.name = _name, \
.cell.ops = &dsi_clk_ops, \
.div = _div, \
}
static struct rt_clk_cell *dsi0_clk_cell[] =
{
REGISTER_CLK_DSI("dsi0_byte", 8),
REGISTER_CLK_DSI("dsi0_ddr2", 4),
REGISTER_CLK_DSI("dsi0_ddr", 2),
};
static struct rt_clk_cell *dsi1_clk_cell[] =
{
REGISTER_CLK_DSI("dsi1_byte", 8),
REGISTER_CLK_DSI("dsi1_ddr2", 4),
REGISTER_CLK_DSI("dsi1_ddr", 2),
};
static rt_err_t dsi_clk_probe(struct rt_platform_device *pdev)
{
rt_err_t err;
struct rt_device *dev = &pdev->parent;
struct rt_clk_cell **dsi_clk_cell = (void *)pdev->id->data;
struct dsi_clk *dclk = rt_calloc(1, sizeof(*dclk));
if (!dclk)
{
return -RT_ENOMEM;
}
for (int i = 0; i < 3; ++i)
{
struct dsi_clk_output *clk = rt_container_of(dsi_clk_cell[i], struct dsi_clk_output, cell);
rt_dm_dev_prop_read_string_index(dev, "clock-output-names", i, &clk->cell.name);
}
dclk->parent.dev = dev;
dclk->parent.cells = dsi_clk_cell;
dclk->parent.cells_nr = 3;
dclk->parent.parents_clk = rt_err_ptr(-RT_EEMPTY);
if ((err = rt_clk_register(&dclk->parent)))
{
goto _fail;
}
return RT_EOK;
_fail:
rt_free(dclk);
return err;
}
static const struct rt_ofw_node_id dsi_clk_ofw_ids[] =
{
{ .compatible = "brcm,bcm2835-dsi0", .data = dsi0_clk_cell },
{ .compatible = "brcm,bcm2835-dsi1", .data = dsi1_clk_cell },
{ .compatible = "brcm,bcm2711-dsi0", .data = dsi0_clk_cell },
{ .compatible = "brcm,bcm2711-dsi1", .data = dsi1_clk_cell },
{ /* sentinel */ }
};
static struct rt_platform_driver dsi_clk_driver =
{
.name = "clk-dsi",
.ids = dsi_clk_ofw_ids,
.probe = dsi_clk_probe,
};
static int dsi_clk_register(void)
{
struct rt_ofw_node *np = RT_NULL;
rt_platform_driver_register(&dsi_clk_driver);
/* Force probing of the DSIx clock */
while ((np = rt_ofw_find_node_by_ids(np, dsi_clk_ofw_ids)))
{
rt_platform_ofw_device_probe_child(np);
}
return 0;
}
INIT_SUBSYS_EXPORT(dsi_clk_register);
File diff suppressed because it is too large Load Diff
+1797
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
config RT_CLOCK_TIME_BCM2835
bool "BCM2835 Timer"
default y
+13
View File
@@ -0,0 +1,13 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_CLOCK_TIME_BCM2835']):
src += ['clock_time-bcm2835_timer.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
config RT_DMA_BCM2835
bool "BCM2835 DMA"
default n
+13
View File
@@ -0,0 +1,13 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_DMA_BCM2835']):
src += ['dma-bcm2835.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+4
View File
@@ -0,0 +1,4 @@
config RT_DVFS_RASPBERRY_CPUFREQ
bool "Raspberry firmware CPUfreq driver"
depends on RT_USING_DVFS
default n
+13
View File
@@ -0,0 +1,13 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_DVFS_RASPBERRY_CPUFREQ']):
src += ['dvfs-raspberrypi-cpufreq.c']
group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_DVFS'], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
config RT_ETHERNET_BCMGENET
bool "BCMGENET V5 Ethernet MAC"
default n
+13
View File
@@ -0,0 +1,13 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_ETHERNET_BCMGENET']):
src += ['eth-bcmgenet.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
+6
View File
@@ -0,0 +1,6 @@
config RT_FIRMWARE_RASPBERRYPI
bool "Raspberrypi Firmware"
depends on RT_USING_OFW
depends on RT_USING_MBOX
depends on RT_USING_DMA
default n
+13
View File
@@ -0,0 +1,13 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_FIRMWARE_RASPBERRYPI']):
src += ['firmware-raspberrypi.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
+13
View File
@@ -0,0 +1,13 @@
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')
+5
View File
@@ -0,0 +1,5 @@
config RT_GRAPHIC_BACKLIGHT_RPI
bool "Raspberry Pi display firmware driven backlight"
depends on RT_GRAPHIC_BACKLIGHT
depends on RT_FIRMWARE_RASPBERRYPI
default n
+13
View File
@@ -0,0 +1,13 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_GRAPHIC_BACKLIGHT_RPI']):
src += ['backlight-rpi.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
+148
View File
@@ -0,0 +1,148 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#define DBG_TAG "video.backlight.rpi"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#include <firmware-raspberrypi.h>
struct rpi_backlight
{
struct rt_backlight_device parent;
struct rpi_firmware *rpi_fw;
};
#define raw_to_rpi_backlight(raw) rt_container_of(raw, struct rpi_backlight, parent)
static rt_err_t rpi_backlight_update_status(struct rt_backlight_device *bl)
{
rt_err_t err;
struct rpi_backlight *rbl = raw_to_rpi_backlight(bl);
rt_uint32_t brightness = bl->props.brightness;
if (bl->props.power != RT_BACKLIGHT_POWER_UNBLANK)
{
brightness = 0;
}
err = rpi_firmware_property(rbl->rpi_fw,
RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT, &brightness, sizeof(brightness));
if (err)
{
LOG_E("Failed to set brightness");
return err;
}
if ((int)brightness < 0)
{
LOG_E("Backlight change failed");
return -RT_ERROR;
}
return RT_EOK;
}
static struct rt_backlight_ops rpi_backlight_ops =
{
.update_status = rpi_backlight_update_status,
};
static rt_err_t rpi_backlight_probe(struct rt_platform_device *pdev)
{
rt_err_t err = RT_EOK;
struct rpi_firmware *rpi_fw;
struct rt_device *dev = &pdev->parent;
struct rt_ofw_node *np = dev->ofw_node, *fw_np;
struct rpi_backlight *rbl = rt_calloc(1, sizeof(*rbl));
if (!rbl)
{
return -RT_ENOMEM;
}
fw_np = rt_ofw_parse_phandle(np, "firmware", 0);
if (!fw_np)
{
err = -RT_EINVAL;
goto _fail;
}
rpi_fw = rpi_firmware_get(fw_np);
rt_ofw_node_put(fw_np);
if (!rpi_fw)
{
err = -RT_EINVAL;
goto _fail;
}
dev->user_data = rbl;
rbl->rpi_fw = rpi_fw;
rbl->parent.props.max_brightness = 255;
rbl->parent.ops = &rpi_backlight_ops;
if ((err = rt_backlight_register(&rbl->parent)))
{
goto _fail;
}
rt_backlight_set_brightness(&rbl->parent, 255);
return RT_EOK;
_fail:
if (rbl->rpi_fw)
{
rpi_firmware_put(rbl->rpi_fw);
}
rt_free(rbl);
return err;
}
static rt_err_t rpi_backlight_remove(struct rt_platform_device *pdev)
{
struct rpi_backlight *rbl = pdev->parent.user_data;
rt_backlight_unregister(&rbl->parent);
rpi_firmware_put(rbl->rpi_fw);
rt_free(rbl);
return RT_EOK;
}
static const struct rt_ofw_node_id rpi_backlight_ofw_ids[] =
{
{ .compatible = "raspberrypi,rpi-backlight" },
{ /* sentinel */ }
};
static struct rt_platform_driver rpi_backlight_driver =
{
.name = "rpi-backlight",
.ids = rpi_backlight_ofw_ids,
.probe = rpi_backlight_probe,
.remove = rpi_backlight_remove,
};
RT_PLATFORM_DRIVER_EXPORT(rpi_backlight_driver);
+9
View File
@@ -0,0 +1,9 @@
config RT_GRAPHIC_FB_BCM2708
bool "BCM2708 framebuffer support"
depends on RT_FIRMWARE_RASPBERRYPI
default n
config RT_GRAPHIC_FB_RPISENSE
bool "Raspberry Pi Sense HAT framebuffer"
depends on RT_MFD_RPI_SENSE
default n
+16
View File
@@ -0,0 +1,16 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_GRAPHIC_FB_BCM2708']):
src += ['fb-bcm2708.c']
if GetDepend(['RT_GRAPHIC_FB_RPISENSE']):
src += ['fb-rpisense.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2
View File
@@ -0,0 +1,2 @@
config RT_GRAPHIC_LOGO_RASPI_CLUT224
bool "Standard 224-color Raspberry PI logo"
+5
View File
@@ -0,0 +1,5 @@
if RT_GRAPHIC_LOGO_RASPI_CLUT224
config RT_GRAPHIC_LOGO_RASPI_CLUT224_PATH
string
default "../dm/graphic/logo/logo-raspi-clut224.ppm"
endif
File diff suppressed because it is too large Load Diff
+14
View File
@@ -0,0 +1,14 @@
config RT_HWCRYPTO_RNG_BCM2835
bool "Broadcom BCM2835/BCM63xx Random Number Generator support"
depends on RT_USING_DM
depends on RT_USING_HWCRYPTO
depends on RT_HWCRYPTO_USING_RNG
depends on RT_USING_RESET
default n
config RT_HWCRYPTO_RNG_IPROC_RNG200
bool "Broadcom iProc/STB RNG200 support"
depends on RT_USING_DM
depends on RT_USING_HWCRYPTO
depends on RT_HWCRYPTO_USING_RNG
default n
+16
View File
@@ -0,0 +1,16 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_HWCRYPTO_RNG_BCM2835']):
src += ['hw-rng-bcm2835.c']
if GetDepend(['RT_HWCRYPTO_RNG_IPROC_RNG200']):
src += ['hw-rng-iproc-rng200.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+9
View File
@@ -0,0 +1,9 @@
config RT_I2C_BCM2835
bool "Broadcom BCM2835 I2C controller"
depends on RT_USING_PINCTRL
default n
config RT_I2C_BRCMSTB
bool "BRCM Settop/DSL I2C controller"
depends on RT_USING_PINCTRL
default n
+16
View File
@@ -0,0 +1,16 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_I2C_BCM2835']):
src += ['i2c-bcm2835.c']
if GetDepend(['RT_I2C_BRCMSTB']):
src += ['i2c-brcmstb.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#ifndef __BCM2835_PM_H__
#define __BCM2835_PM_H__
struct bcm2835_pm
{
void *base;
void *asb;
void *rpivid_asb;
void *ofw_node;
};
#endif /* __BCM2835_PM_H__ */
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DT_BINDINGS_CLOCK_BCM2835_AUX_H__
#define __DT_BINDINGS_CLOCK_BCM2835_AUX_H__
#define BCM2835_AUX_CLOCK_UART 0
#define BCM2835_AUX_CLOCK_SPI1 1
#define BCM2835_AUX_CLOCK_SPI2 2
#define BCM2835_AUX_CLOCK_COUNT 3
#endif /* __DT_BINDINGS_CLOCK_BCM2835_AUX_H__ */
+68
View File
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DT_BINDINGS_CLOCK_BCM2835_H__
#define __DT_BINDINGS_CLOCK_BCM2835_H__
#define BCM2835_PLLA 0
#define BCM2835_PLLB 1
#define BCM2835_PLLC 2
#define BCM2835_PLLD 3
#define BCM2835_PLLH 4
#define BCM2835_PLLA_CORE 5
#define BCM2835_PLLA_PER 6
#define BCM2835_PLLB_ARM 7
#define BCM2835_PLLC_CORE0 8
#define BCM2835_PLLC_CORE1 9
#define BCM2835_PLLC_CORE2 10
#define BCM2835_PLLC_PER 11
#define BCM2835_PLLD_CORE 12
#define BCM2835_PLLD_PER 13
#define BCM2835_PLLH_RCAL 14
#define BCM2835_PLLH_AUX 15
#define BCM2835_PLLH_PIX 16
#define BCM2835_CLOCK_TIMER 17
#define BCM2835_CLOCK_OTP 18
#define BCM2835_CLOCK_UART 19
#define BCM2835_CLOCK_VPU 20
#define BCM2835_CLOCK_V3D 21
#define BCM2835_CLOCK_ISP 22
#define BCM2835_CLOCK_H264 23
#define BCM2835_CLOCK_VEC 24
#define BCM2835_CLOCK_HSM 25
#define BCM2835_CLOCK_SDRAM 26
#define BCM2835_CLOCK_TSENS 27
#define BCM2835_CLOCK_EMMC 28
#define BCM2835_CLOCK_PERI_IMAGE 29
#define BCM2835_CLOCK_PWM 30
#define BCM2835_CLOCK_PCM 31
#define BCM2835_PLLA_DSI0 32
#define BCM2835_PLLA_CCP2 33
#define BCM2835_PLLD_DSI0 34
#define BCM2835_PLLD_DSI1 35
#define BCM2835_CLOCK_AVEO 36
#define BCM2835_CLOCK_DFT 37
#define BCM2835_CLOCK_GP0 38
#define BCM2835_CLOCK_GP1 39
#define BCM2835_CLOCK_GP2 40
#define BCM2835_CLOCK_SLIM 41
#define BCM2835_CLOCK_SMI 42
#define BCM2835_CLOCK_TEC 43
#define BCM2835_CLOCK_DPI 44
#define BCM2835_CLOCK_CAM0 45
#define BCM2835_CLOCK_CAM1 46
#define BCM2835_CLOCK_DSI0E 47
#define BCM2835_CLOCK_DSI1E 48
#define BCM2835_CLOCK_DSI0P 49
#define BCM2835_CLOCK_DSI1P 50
#define BCM2711_CLOCK_EMMC2 51
#endif /* __DT_BINDINGS_CLOCK_BCM2835_H__ */
+66
View File
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DT_BINDINGS_CLOCK_RP1_H__
#define __DT_BINDINGS_CLOCK_RP1_H__
#define RP1_PLL_SYS_CORE 0
#define RP1_PLL_AUDIO_CORE 1
#define RP1_PLL_VIDEO_CORE 2
#define RP1_PLL_SYS 3
#define RP1_PLL_AUDIO 4
#define RP1_PLL_VIDEO 5
#define RP1_PLL_SYS_PRI_PH 6
#define RP1_PLL_SYS_SEC_PH 7
#define RP1_PLL_AUDIO_PRI_PH 8
#define RP1_PLL_SYS_SEC 9
#define RP1_PLL_AUDIO_SEC 10
#define RP1_PLL_VIDEO_SEC 11
#define RP1_CLK_SYS 12
#define RP1_CLK_SLOW_SYS 13
#define RP1_CLK_DMA 14
#define RP1_CLK_UART 15
#define RP1_CLK_ETH 16
#define RP1_CLK_PWM0 17
#define RP1_CLK_PWM1 18
#define RP1_CLK_AUDIO_IN 19
#define RP1_CLK_AUDIO_OUT 20
#define RP1_CLK_I2S 21
#define RP1_CLK_MIPI0_CFG 22
#define RP1_CLK_MIPI1_CFG 23
#define RP1_CLK_PCIE_AUX 24
#define RP1_CLK_USBH0_MICROFRAME 25
#define RP1_CLK_USBH1_MICROFRAME 26
#define RP1_CLK_USBH0_SUSPEND 27
#define RP1_CLK_USBH1_SUSPEND 28
#define RP1_CLK_ETH_TSU 29
#define RP1_CLK_ADC 30
#define RP1_CLK_SDIO_TIMER 31
#define RP1_CLK_SDIO_ALT_SRC 32
#define RP1_CLK_GP0 33
#define RP1_CLK_GP1 34
#define RP1_CLK_GP2 35
#define RP1_CLK_GP3 36
#define RP1_CLK_GP4 37
#define RP1_CLK_GP5 38
#define RP1_CLK_VEC 39
#define RP1_CLK_DPI 40
#define RP1_CLK_MIPI0_DPI 41
#define RP1_CLK_MIPI1_DPI 42
/* Extra PLL output channels - RP1B0 only */
#define RP1_PLL_VIDEO_PRI_PH 43
#define RP1_PLL_AUDIO_TERN 44
/* MIPI clocks managed by the DSI driver */
#define RP1_CLK_MIPI0_DSI_BYTECLOCK 45
#define RP1_CLK_MIPI1_DSI_BYTECLOCK 46
#endif /* __DT_BINDINGS_CLOCK_RP1_H__ */
File diff suppressed because it is too large Load Diff
+25
View File
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DT_BINDINGS_PINCTRL_BCM2835_H__
#define __DT_BINDINGS_PINCTRL_BCM2835_H__
/* brcm,function property */
#define BCM2835_FSEL_GPIO_IN 0
#define BCM2835_FSEL_GPIO_OUT 1
#define BCM2835_FSEL_ALT5 2
#define BCM2835_FSEL_ALT4 3
#define BCM2835_FSEL_ALT0 4
#define BCM2835_FSEL_ALT1 5
#define BCM2835_FSEL_ALT2 6
#define BCM2835_FSEL_ALT3 7
/* brcm,pull property */
#define BCM2835_PUD_OFF 0
#define BCM2835_PUD_DOWN 1
#define BCM2835_PUD_UP 2
#endif /* __DT_BINDINGS_PINCTRL_BCM2835_H__ */
+32
View File
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DT_BINDINGS_POWER_BCM2835_PM_H__
#define __DT_BINDINGS_POWER_BCM2835_PM_H__
#define BCM2835_POWER_DOMAIN_GRAFX 0
#define BCM2835_POWER_DOMAIN_GRAFX_V3D 1
#define BCM2835_POWER_DOMAIN_IMAGE 2
#define BCM2835_POWER_DOMAIN_IMAGE_PERI 3
#define BCM2835_POWER_DOMAIN_IMAGE_ISP 4
#define BCM2835_POWER_DOMAIN_IMAGE_H264 5
#define BCM2835_POWER_DOMAIN_USB 6
#define BCM2835_POWER_DOMAIN_DSI0 7
#define BCM2835_POWER_DOMAIN_DSI1 8
#define BCM2835_POWER_DOMAIN_CAM0 9
#define BCM2835_POWER_DOMAIN_CAM1 10
#define BCM2835_POWER_DOMAIN_CCP2TX 11
#define BCM2835_POWER_DOMAIN_HDMI 12
#define BCM2835_POWER_DOMAIN_COUNT 13
#define BCM2835_RESET_V3D 0
#define BCM2835_RESET_ISP 1
#define BCM2835_RESET_H264 2
#define BCM2835_RESET_COUNT 3
#endif /* __DT_BINDINGS_POWER_BCM2835_PM_H__ */
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DT_BINDINGS_POWER_RASPBERRYPI_POWER_H__
#define __DT_BINDINGS_POWER_RASPBERRYPI_POWER_H__
#define RPI_POWER_DOMAIN_I2C0 0
#define RPI_POWER_DOMAIN_I2C1 1
#define RPI_POWER_DOMAIN_I2C2 2
#define RPI_POWER_DOMAIN_VIDEO_SCALER 3
#define RPI_POWER_DOMAIN_VPU1 4
#define RPI_POWER_DOMAIN_HDMI 5
#define RPI_POWER_DOMAIN_USB 6
#define RPI_POWER_DOMAIN_VEC 7
#define RPI_POWER_DOMAIN_JPEG 8
#define RPI_POWER_DOMAIN_H264 9
#define RPI_POWER_DOMAIN_V3D 10
#define RPI_POWER_DOMAIN_ISP 11
#define RPI_POWER_DOMAIN_UNICAM0 12
#define RPI_POWER_DOMAIN_UNICAM1 13
#define RPI_POWER_DOMAIN_CCP2RX 14
#define RPI_POWER_DOMAIN_CSI2 15
#define RPI_POWER_DOMAIN_CPI 16
#define RPI_POWER_DOMAIN_DSI0 17
#define RPI_POWER_DOMAIN_DSI1 18
#define RPI_POWER_DOMAIN_TRANSPOSER 19
#define RPI_POWER_DOMAIN_CCP2TX 20
#define RPI_POWER_DOMAIN_CDP 21
#define RPI_POWER_DOMAIN_ARM 22
#define RPI_POWER_DOMAIN_COUNT 23
#endif /* __DT_BINDINGS_POWER_BCMRASPBERRYPI_POWERH__ */
@@ -0,0 +1,13 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DT_BINDINGS_POWER_RASPBERRYPI_FIRMWARE_RESET_H__
#define __DT_BINDINGS_POWER_RASPBERRYPI_FIRMWARE_RESET_H__
#define RASPBERRYPI_FIRMWARE_RESET_ID_USB 0
#define RASPBERRYPI_FIRMWARE_RESET_NUM_IDS 1
#endif /* __DT_BINDINGS_POWER_RASPBERRYPI_FIRMWARE_RESET_H__ */
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-26 GuEe-GUI first version
*/
#ifndef __DVFS_RASPBERRYPI_CPUFREQ_H__
#define __DVFS_RASPBERRYPI_CPUFREQ_H__
#include <rtdevice.h>
#include <firmware-raspberrypi.h>
struct rt_clk *raspberrypi_arm_clk_get(void);
rt_err_t raspberrypi_cpufreq_register(struct rt_clk *arm_clk, struct rt_ofw_node *cpu_np,
struct rpi_firmware *rpi_fw);
#endif /* __DVFS_RASPBERRYPI_CPUFREQ_H__ */
File diff suppressed because it is too large Load Diff
+44
View File
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#ifndef __RPISENSE_H__
#define __RPISENSE_H__
#include <sys/ioctl.h>
#define SENSEFB_FBIO_IOC_MAGIC 0xf1
#define SENSEFB_FBIOGET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 0)
#define SENSEFB_FBIOSET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 1)
#define SENSEFB_FBIORESET_GAMMA _IO(SENSEFB_FBIO_IOC_MAGIC, 2)
/*
* Register values.
*/
#define RPISENSE_FB 0x00
#define RPISENSE_WAI 0xf0
#define RPISENSE_VER 0xf1
#define RPISENSE_KEYS 0xf2
#define RPISENSE_EE_WP 0xf3
#define RPISENSE_ID 's'
struct rpisense
{
struct rt_i2c_client *i2c_client;
struct rt_platform_device joystick_dev;
struct rt_platform_device framebuffer_dev;
};
rt_int32_t rpisense_reg_read(struct rpisense *rpisense, int reg);
rt_ssize_t rpisense_block_write(struct rpisense *rpisense, const char *buf, int count);
#endif /* __RPISENSE_H__ */
+13
View File
@@ -0,0 +1,13 @@
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')
+5
View File
@@ -0,0 +1,5 @@
config RT_INPUT_JOYSTICK_RPISENSE
bool "Raspberry Pi Sense HAT joystick"
depends on RT_INPUT_JOYSTICK
depends on RT_MFD_RPI_SENSE
default n
+13
View File
@@ -0,0 +1,13 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../../include']
if GetDepend(['RT_INPUT_JOYSTICK_RPISENSE']):
src += ['js-rpisense.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
+154
View File
@@ -0,0 +1,154 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <rpi-sense.h>
struct rpisense_joystick
{
struct rt_input_device parent;
struct rpisense *rpisense;
rt_base_t pin;
rt_uint8_t active_val;
rt_int32_t prev_keys;
struct rt_thread *keys_task;
};
static rt_uint8_t keymap[5] =
{
KEY_DOWN, KEY_RIGHT, KEY_UP, KEY_ENTER, KEY_LEFT
};
static void rpisense_keys_task(void *param)
{
rt_int32_t keys, changes;
struct rpisense_joystick *rpisense_js = param;
while (RT_TRUE)
{
rt_thread_suspend(rpisense_js->keys_task);
rt_schedule();
keys = rpisense_reg_read(rpisense_js->rpisense, RPISENSE_KEYS);
changes = keys ^ rpisense_js->prev_keys;
rpisense_js->prev_keys = keys;
for (int i = 0; i < RT_ARRAY_SIZE(keymap); ++i)
{
if (changes & 1)
{
rt_input_report_key(&rpisense_js->parent, keymap[i], keys & 1);
}
changes >>= 1;
keys >>= 1;
}
rt_input_sync(&rpisense_js->parent);
}
}
static void rpisense_isr(void *args)
{
struct rpisense_joystick *rpisense_js = args;
rt_thread_resume(rpisense_js->keys_task);
}
static rt_err_t rpisense_js_probe(struct rt_platform_device *pdev)
{
rt_err_t err;
struct rpisense *rpisense = pdev->priv;
struct rpisense_joystick *rpisense_js = rt_calloc(1, sizeof(*rpisense_js));
if (!rpisense_js)
{
return -RT_ENOMEM;
}
rpisense_js->rpisense = rpisense;
rpisense_js->pin = rt_pin_get_named_pin(&rpisense->i2c_client->parent,
"keys-int", 0, RT_NULL, &rpisense_js->active_val);
if (rpisense_js->pin < 0)
{
err = rpisense_js->pin;
goto _fail;
}
rt_pin_write(rpisense_js->pin, rpisense_js->active_val);
rt_pin_mode(rpisense_js->pin, PIN_MODE_INPUT);
rt_pin_attach_irq(rpisense_js->pin, PIN_IRQ_MODE_RISING, rpisense_isr, rpisense_js);
rt_pin_irq_enable(rpisense_js->pin, RT_TRUE);
for (int i = 0; i < RT_ARRAY_SIZE(keymap); ++i)
{
rt_input_set_capability(&rpisense_js->parent, EV_KEY, keymap[i]);
}
if ((err = rt_input_device_register(&rpisense_js->parent)))
{
goto _fail;
}
rpisense_js->keys_task = rt_thread_create("rpisense-js", &rpisense_keys_task,
rpisense_js, DM_THREAD_STACK_SIZE, RT_THREAD_PRIORITY_MAX / 2, 10);
if (!rpisense_js->keys_task)
{
rt_input_device_unregister(&rpisense_js->parent);
goto _fail;
}
pdev->parent.user_data = rpisense_js;
rt_thread_startup(rpisense_js->keys_task);
return RT_EOK;
_fail:
if (rpisense_js->pin >= 0)
{
rt_pin_detach_irq(rpisense_js->pin);
}
rt_free(rpisense_js);
return err;
}
static rt_err_t rpisense_js_remove(struct rt_platform_device *pdev)
{
struct rpisense_joystick *rpisense_js = pdev->parent.user_data;
rt_pin_irq_enable(rpisense_js->pin, RT_FALSE);
rt_pin_detach_irq(rpisense_js->pin);
rt_thread_delete(rpisense_js->keys_task);
rt_input_device_unregister(&rpisense_js->parent);
rt_free(rpisense_js);
return RT_EOK;
}
static struct rt_platform_driver rpisense_js_driver =
{
.name = "rpi-sense-js",
.probe = rpisense_js_probe,
.remove = rpisense_js_remove,
};
RT_PLATFORM_DRIVER_EXPORT(rpisense_js_driver);
+9
View File
@@ -0,0 +1,9 @@
config RT_INPUT_TOUCHSCREEN_RASPBERRYPI_FW
bool "Raspberry Pi's firmware base touch screen support"
depends on RT_INPUT_TOUCHSCREEN
depends on RT_USING_OFW
depends on RT_USING_DMA
depends on RT_FIRMWARE_RASPBERRYPI
depends on RT_USING_ADT
depends on RT_USING_ADT_BITMAP
default n
+13
View File
@@ -0,0 +1,13 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../../include']
if GetDepend(['RT_INPUT_TOUCHSCREEN_RASPBERRYPI_FW']):
src += ['ts-raspberrypi.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
config RT_MBOX_BCM2835
bool "BCM2835 Mailbox"
default n
+13
View File
@@ -0,0 +1,13 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_MBOX_BCM2835']):
src += ['mailbox-bcm2835.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
config RT_MFD_BCM2835_PM
bool "BCM2835 PM driver"
depends on RT_USING_MFD
default n
config RT_MFD_RP1
bool "Raspberry Pi RP1 MFD driver"
depends on RT_USING_MFD
depends on RT_USING_PCI
default n
config RT_MFD_RPI_SENSE
bool "Raspberry Pi Sense HAT core functions"
depends on RT_USING_MFD
depends on RT_USING_I2C
depends on RT_USING_OFW
depends on RT_USING_PIN
default n
+19
View File
@@ -0,0 +1,19 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_MFD_BCM2835_PM']):
src += ['bcm2835-pm.c']
if GetDepend(['RT_MFD_RP1']):
src += ['rp1.c']
if GetDepend(['RT_MFD_RPI_SENSE']):
src += ['rpi-sense.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
+119
View File
@@ -0,0 +1,119 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#define DBG_TAG "mfd.bcm2835-pm"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#include <bcm2835-pm.h>
static rt_err_t bcm2835_pm_probe(struct rt_platform_device *pdev)
{
rt_err_t err;
rt_bool_t is_2712 = RT_FALSE;
struct rt_device *dev = &pdev->parent;
struct rt_bus *bus = dev->bus;
struct bcm2835_pm *pm = rt_malloc(sizeof(*pm));
if (!pm)
{
return -RT_ENOMEM;
}
#ifdef RT_USING_OFW
is_2712 = rt_ofw_node_is_compatible(dev->ofw_node, "brcm,bcm2712-pm");
if (rt_ofw_prop_read_bool(dev->ofw_node, "reg-names"))
{
if (!(pm->base = rt_dm_dev_iomap_by_name(dev, "pm")))
{
err = -RT_EIO;
goto _fail;
}
pm->asb = rt_dm_dev_iomap_by_name(dev, "asb");
pm->rpivid_asb = rt_dm_dev_iomap_by_name(dev, "rpivid_asb");
}
else
#endif /* RT_USING_OFW */
{
if (!(pm->base = rt_dm_dev_iomap(dev, 0)))
{
err = -RT_EIO;
goto _fail;
}
pm->asb = rt_dm_dev_iomap(dev, 1);
pm->rpivid_asb = rt_dm_dev_iomap(dev, 2);
}
pm->ofw_node = dev->ofw_node;
pdev->name = "bcm2835-wdt";
pdev->priv = pm;
/* Ask bus to check drivers' name */
pdev->parent.ofw_node = RT_NULL;
rt_bus_remove_device(dev);
rt_bus_add_device(bus, dev);
if (pm->asb || is_2712)
{
pdev = rt_calloc(1, sizeof(*pdev));
if (pdev)
{
pdev->name = "bcm2835-power";
pdev->priv = pm;
rt_bus_add_device(bus, &pdev->parent);
}
else
{
LOG_W("Power will not register");
}
}
/* No Error, No success */
return 1;
_fail:
rt_free(pm);
return err;
}
static const struct rt_ofw_node_id bcm2835_pm_ofw_ids[] =
{
{ .compatible = "brcm,bcm2835-pm-wdt", },
{ .compatible = "brcm,bcm2835-pm", },
{ .compatible = "brcm,bcm2711-pm", },
{ .compatible = "brcm,bcm2712-pm", },
{ /* sentinel */ }
};
static struct rt_platform_driver bcm2835_pm_driver =
{
.name = "pm-bcm2835",
.ids = bcm2835_pm_ofw_ids,
.probe = bcm2835_pm_probe,
};
static int bcm2835_pm_register(void)
{
rt_platform_driver_register(&bcm2835_pm_driver);
return 0;
}
INIT_SUBSYS_EXPORT(bcm2835_pm_register);
+415
View File
File diff suppressed because it is too large Load Diff
+165
View File
@@ -0,0 +1,165 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#define DBG_TAG "mfd.rpi-sense"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#include "rpi-sense.h"
static rt_int32_t i2c_smbus_read_byte_data(struct rt_i2c_client *client,
rt_uint8_t command)
{
rt_int32_t res;
rt_uint8_t ret = 0;
struct rt_i2c_msg msg[2];
msg[0].buf = &command;
msg[0].addr = client->client_addr;
msg[0].len = 1;
msg[0].flags = RT_I2C_WR;
msg[1].buf = &ret;
msg[1].addr = client->client_addr;
msg[1].len = 1;
msg[1].flags = RT_I2C_RD;
res = rt_i2c_transfer(client->bus, msg, 2);
return res == 2 ? ret : res;
}
rt_int32_t rpisense_reg_read(struct rpisense *rpisense, int reg)
{
rt_int32_t ret = i2c_smbus_read_byte_data(rpisense->i2c_client, reg);
if (ret < 0)
{
LOG_E("Read from reg(%d) error = %s", reg, rt_strerror(ret));
}
/*
* As the BCM270x I2C clock stretching bug, some values may have MSB set.
* Clear it to avoid incorrect values.
*/
return ret & 0x7f;
}
rt_ssize_t rpisense_block_write(struct rpisense *rpisense, const char *buf, int count)
{
rt_ssize_t ret;
struct rt_i2c_client *client = rpisense->i2c_client;
ret = rt_i2c_master_send(client->bus, client->client_addr, 0, (void *)buf, count);
if (ret < 0)
{
LOG_E("Write block(%d) error = %s", count, rt_strerror(ret));
}
return ret;
}
static void rpisense_client_dev_register(struct rpisense *rpisense,
const char *name, struct rt_platform_device *pdev)
{
pdev->name = name;
pdev->priv = rpisense;
rt_platform_device_register(pdev);
}
static rt_err_t rpisense_probe(struct rt_i2c_client *client)
{
rt_err_t err;
rt_int32_t value;
struct rt_device *dev = &client->parent;
struct rpisense *rpisense = rt_calloc(1, sizeof(*rpisense));
if (!rpisense)
{
return -RT_ENOMEM;
}
rpisense->i2c_client = client;
value = rpisense_reg_read(rpisense, RPISENSE_WAI);
if (value > 0)
{
if (value != RPISENSE_ID)
{
err = -RT_EINVAL;
goto _fail;
}
}
else
{
err = value;
goto _fail;
}
value = rpisense_reg_read(rpisense, RPISENSE_VER);
if (value < 0)
{
err = value;
goto _fail;
}
LOG_I("Raspberry Pi Sense HAT firmware version %i", value);
dev->user_data = rpisense;
rpisense_client_dev_register(rpisense, "rpi-sense-js", &rpisense->joystick_dev);
rpisense_client_dev_register(rpisense, "rpi-sense-fb", &rpisense->framebuffer_dev);
return RT_EOK;
_fail:
rt_free(rpisense);
return err;
}
static rt_err_t rpisense_remove(struct rt_i2c_client *client)
{
struct rpisense *rpisense = client->parent.user_data;
rt_bus_remove_device(&rpisense->joystick_dev.parent);
rt_bus_remove_device(&rpisense->framebuffer_dev.parent);
rt_free(rpisense);
return RT_EOK;
}
static const struct rt_i2c_device_id rpisense_ids[] =
{
{ .name = "rpi-sense" },
{ /* sentinel */ },
};
static const struct rt_ofw_node_id rpisense_ofw_ids[] =
{
{ .compatible = "rpi,rpi-sense" },
{ /* sentinel */ },
};
static struct rt_i2c_driver rpisense_driver =
{
.ids = rpisense_ids,
.ofw_ids = rpisense_ofw_ids,
.probe = rpisense_probe,
.remove = rpisense_remove,
};
RT_I2C_DRIVER_EXPORT(rpisense_driver);
+4
View File
@@ -0,0 +1,4 @@
config RT_NVMEM_RASPBERRYPI_OTP
bool "Raspberry Pi OTP support"
depends on RT_USING_NVMEM
default n
+13
View File
@@ -0,0 +1,13 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_NVMEM_RASPBERRYPI_OTP']):
src += ['raspberrypi-otp.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
+180
View File
@@ -0,0 +1,180 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#define DBG_TAG "nvmem.raspberrypi"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#include <firmware-raspberrypi.h>
#define MAX_ROWS 192
struct rpi_otp
{
struct rt_nvmem_device parent;
struct rpi_firmware *fw;
rt_uint32_t block;
};
#define raw_to_rpi_otp(raw) rt_container_of(raw, struct rpi_otp, parent)
static rt_ssize_t rpi_otp_read(struct rt_nvmem_device *ndev, int offset,
void *val, rt_size_t bytes)
{
rt_err_t err;
int words, index;
rt_uint32_t data[3 + MAX_ROWS];
struct rpi_otp *otp = raw_to_rpi_otp(ndev);
words = bytes / sizeof(rt_uint32_t);
index = offset / sizeof(rt_uint32_t);
data[0] = otp->block;
data[1] = index;
data[2] = words;
if (words > MAX_ROWS)
{
return -RT_EINVAL;
}
err = rpi_firmware_property(otp->fw, RPI_FIRMWARE_GET_USER_OTP, &data, sizeof(data));
if (!err)
{
rt_memcpy(val, data + 3, bytes);
}
else
{
rt_memset(val, 0xee, bytes);
}
return err ? : bytes;
}
static rt_ssize_t rpi_otp_write(struct rt_nvmem_device *ndev, int offset,
void *val, rt_size_t bytes)
{
int words, index;
rt_uint32_t data[3 + MAX_ROWS];
struct rpi_otp *otp = raw_to_rpi_otp(ndev);
words = bytes / sizeof(rt_uint32_t);
index = offset / sizeof(rt_uint32_t);
data[0] = otp->block;
data[1] = index;
data[2] = words;
if (bytes > MAX_ROWS * sizeof(rt_uint32_t))
{
return -RT_EINVAL;
}
rt_memcpy(data + 3, val, bytes);
return rpi_firmware_property(otp->fw, RPI_FIRMWARE_SET_USER_OTP, &data, sizeof(data)) ? : bytes;
}
static rt_err_t rpi_otp_probe(struct rt_platform_device *pdev)
{
rt_err_t err;
rt_uint32_t reg[2];
struct rt_nvmem_device *nvmem;
struct rt_device *dev = &pdev->parent;
struct rt_ofw_node *np = dev->ofw_node, *fw_np;
struct rpi_otp *otp = rt_calloc(1, sizeof(*otp));
if (!otp)
{
return -RT_ENOMEM;
}
fw_np = rt_ofw_parse_phandle(np, "firmware", 0);
if (!fw_np)
{
err = -RT_EINVAL;
goto _fail;
}
otp->fw = rpi_firmware_get(fw_np);
rt_ofw_node_put(fw_np);
if (!otp->fw)
{
err = -RT_EINVAL;
goto _fail;
}
if (rt_dm_dev_prop_read_u32_array_index(dev, "reg", 0, RT_ARRAY_SIZE(reg), reg) <= 0)
{
err = -RT_EINVAL;
goto _fail;
}
nvmem = &otp->parent;
nvmem->parent.ofw_node = np;
nvmem->reg_read = rpi_otp_read,
nvmem->reg_write = rpi_otp_write,
nvmem->size = reg[1] * sizeof(rt_uint32_t);
nvmem->read_only = !rt_dm_dev_prop_read_bool(dev, "rw");
nvmem->stride = sizeof(rt_uint32_t);
nvmem->word_size = sizeof(rt_uint32_t);
if ((err = rt_nvmem_device_register(nvmem)))
{
goto _fail;
}
return RT_EOK;
_fail:
if (otp->fw)
{
rpi_firmware_put(otp->fw);
}
rt_free(otp);
return err;
}
static rt_err_t rpi_otp_remove(struct rt_platform_device *pdev)
{
rt_err_t err;
struct rpi_otp *otp = pdev->parent.user_data;
err = rt_nvmem_device_unregister(&otp->parent);
rpi_firmware_put(otp->fw);
rt_free(otp);
return err;
}
static const struct rt_ofw_node_id rpi_top_ofw_ids[] =
{
{ .compatible = "raspberrypi,rpi-otp", },
{ /* sentinel */ }
};
static struct rt_platform_driver rpi_top_driver =
{
.name = "nvmem-raspberrypi-otp",
.ids = rpi_top_ofw_ids,
.probe = rpi_otp_probe,
.remove = rpi_otp_remove,
};
RT_PLATFORM_DRIVER_EXPORT(rpi_top_driver);
+5
View File
@@ -0,0 +1,5 @@
config RT_PCIE_BRCMSTB
bool "Broadcom Brcmstb PCIe controller"
depends on RT_PCI_MSI
depends on RT_USING_OFW
default n
+13
View File
@@ -0,0 +1,13 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include', cwd + '/../../../../components/drivers/pci']
if GetDepend(['RT_PCIE_BRCMSTB']):
src += ['pcie-brcmstb.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
+7
View File
@@ -0,0 +1,7 @@
config RT_PHY_MDIO_BCM_UNIMAC
bool "Broadcom UniMAC MDIO bus controller (BCM2711 GENET)"
default n
config RT_PHY_BCM54213
bool "Broadcom BCM54213PE Ethernet PHY (Pi4/Pi5 RJ45)"
default n
+16
View File
@@ -0,0 +1,16 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_PHY_BCM54213']):
src += ['phy-bcm54213.c']
if GetDepend(['RT_PHY_MDIO_BCM_UNIMAC']):
src += ['mdio-bcm-unimac.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
+190
View File
@@ -0,0 +1,190 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2026-06-18 GuEe-GUI BCM54213PE PHY for BCM2711 GENET
*/
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <drivers/phy.h>
#define DBG_TAG "phy.bcm54213"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
/* BCM54213PE on Raspberry Pi 4 (BCM2711 GENET) */
#define PHY_ID_BCM54213PE 0x600d84a2
#define MII_BCM54XX_AUX_CTL 0x18
#define MII_BCM54XX_SHD 0x1c
#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC 0x07
#define MII_BCM54XX_AUXCTL_SHDWSEL_MASK 0x0007
#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12
#define AUXCTL_MISC_RGMII_SKEW_EN (1 << 8)
#define AUXCTL_MISC_WREN (1 << 15)
#define MII_BCM54XX_SHD_WRITE (1 << 15)
#define MII_BCM54XX_SHD_VAL(x) (((x) & 0x1f) << 10)
#define MII_BCM54XX_SHD_DATA(x) (((x) & 0x3ff) << 0)
#define BCM54810_SHD_CLK_CTL 0x3
#define CLK_CTL_GTXCLK_EN (1 << 9)
static int bcm54xx_auxctl_read(struct rt_phy_device *phydev, rt_uint16_t regnum)
{
rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, MII_BCM54XX_AUX_CTL,
MII_BCM54XX_AUXCTL_SHDWSEL_MASK |
(regnum << MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT));
return rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, MII_BCM54XX_AUX_CTL);
}
static int bcm54xx_auxctl_write(struct rt_phy_device *phydev, rt_uint16_t regnum, rt_uint16_t val)
{
return rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, MII_BCM54XX_AUX_CTL, regnum | val);
}
static int bcm_phy_read_shadow(struct rt_phy_device *phydev, rt_uint16_t shadow)
{
int val;
rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, MII_BCM54XX_SHD, MII_BCM54XX_SHD_VAL(shadow));
val = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, MII_BCM54XX_SHD);
return MII_BCM54XX_SHD_DATA(val);
}
static int bcm_phy_write_shadow(struct rt_phy_device *phydev, rt_uint16_t shadow, rt_uint16_t val)
{
return rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, MII_BCM54XX_SHD,
MII_BCM54XX_SHD_WRITE | MII_BCM54XX_SHD_VAL(shadow) | MII_BCM54XX_SHD_DATA(val));
}
static int bcm54xx_config_clock_delay(struct rt_phy_device *phydev)
{
int val, err;
val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
if (val < 0)
{
return val;
}
val |= AUXCTL_MISC_WREN;
if (phydev->interface == RT_PHY_INTERFACE_MODE_RGMII ||
phydev->interface == RT_PHY_INTERFACE_MODE_RGMII_TXID)
{
val &= ~AUXCTL_MISC_RGMII_SKEW_EN;
}
else if (phydev->interface == RT_PHY_INTERFACE_MODE_RGMII_ID ||
phydev->interface == RT_PHY_INTERFACE_MODE_RGMII_RXID)
{
val |= AUXCTL_MISC_RGMII_SKEW_EN;
}
err = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, val);
if (err < 0)
{
return err;
}
val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL);
if (val < 0)
{
return val;
}
if (phydev->interface == RT_PHY_INTERFACE_MODE_RGMII ||
phydev->interface == RT_PHY_INTERFACE_MODE_RGMII_RXID)
{
val &= ~CLK_CTL_GTXCLK_EN;
}
else if (phydev->interface == RT_PHY_INTERFACE_MODE_RGMII_ID ||
phydev->interface == RT_PHY_INTERFACE_MODE_RGMII_TXID)
{
val |= CLK_CTL_GTXCLK_EN;
}
return bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val);
}
static int bcm54213pe_config(struct rt_phy_device *phydev)
{
int err;
err = bcm54xx_config_clock_delay(phydev);
if (err < 0)
{
return err;
}
LOG_D("PHY config if=%d", phydev->interface);
return rt_genphy_config(phydev);
}
static int bcm54213pe_read_bmsr(struct rt_phy_device *phydev)
{
int bmsr;
/* BMSR link status is latch-low; read twice for current value */
bmsr = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_BMSR);
if (bmsr < 0)
{
return bmsr;
}
return rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_BMSR);
}
static int bcm54213pe_startup(struct rt_phy_device *phydev)
{
int bmsr;
/*
* Non-blocking startup: do not wait for autoneg in init context.
* Link-up / retry is handled by GENET link IRQ work and periodic poll.
*/
bmsr = bcm54213pe_read_bmsr(phydev);
if (bmsr < 0)
{
return bmsr;
}
if (bmsr & RT_BMSR_LSTATUS)
{
phydev->link = 1;
rt_genphy_parse_link(phydev);
LOG_I("PHY up: speed=%d duplex=%d", phydev->speed, phydev->duplex);
return 0;
}
phydev->link = 0;
LOG_I("PHY link down at boot, defer to link event / retry work");
return 0;
}
static struct rt_phy_driver bcm54213pe_driver =
{
.uid = PHY_ID_BCM54213PE,
.mask = 0xffffffff,
.name = "Broadcom BCM54213PE",
.features = RT_PHY_GBIT_FEATURES,
.config = bcm54213pe_config,
.startup = bcm54213pe_startup,
};
static int bcm54213_phy_drv_register(void)
{
rt_phy_driver_register(&bcm54213pe_driver);
return 0;
}
INIT_PLATFORM_EXPORT(bcm54213_phy_drv_register);
+19
View File
@@ -0,0 +1,19 @@
config RT_PIC_BCM2712_MIP
bool "Broadcom 2712 MSI-X Interrupt Peripheral support" if RT_PCI_MSI
depends on RT_USING_OFW
default n
config RT_PIC_BCM2835_INTC
bool "BCM2835 intc"
depends on RT_USING_OFW
default n
config RT_PIC_BCM2836_L1_INTC
bool "BCM2836 L1 intc"
depends on RT_USING_OFW
default n
config RT_PIC_BRCMSTB_L2_IRQ
bool "BRCMSTB L2 IRQ"
depends on RT_USING_OFW
default n
+22
View File
@@ -0,0 +1,22 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
if GetDepend(['RT_PIC_BCM2712_MIP']):
src += ['pic-bcm2712-mip.c']
if GetDepend(['RT_PIC_BCM2835_INTC']):
src += ['pic-bcm2835.c']
if GetDepend(['RT_PIC_BCM2836_L1_INTC']):
src += ['pic-bcm2836.c']
if GetDepend(['RT_PIC_BRCMSTB_L2_IRQ']):
src += ['pic-brcmstb-l2.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+15
View File
@@ -0,0 +1,15 @@
config RT_PIN_BCM_VIRT
bool "Broadcom Virt GPIO support"
depends on RT_USING_PIN
default n
config RT_PIN_BRCMSTB
bool "BRCMSTB GPIO support"
depends on RT_USING_PIN
default n
config RT_PIN_RASPBERRYPI_EXP
bool "Raspberry Pi 3 GPIO Expander"
depends on RT_USING_PIN
depends on RT_FIRMWARE_RASPBERRYPI
default n
+19
View File
@@ -0,0 +1,19 @@
from building import *
group = []
src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include', cwd + '/../../../../components/drivers/pin']
if GetDepend(['RT_PIN_BCM_VIRT']):
src += ['pin-bcm-virt.c']
if GetDepend(['RT_PIN_BRCMSTB']):
src += ['pin-brcmstb.c']
if GetDepend(['RT_PIN_RASPBERRYPI_EXP']):
src += ['pin-raspberrypi-exp.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
+188
View File
@@ -0,0 +1,188 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-26 GuEe-GUI first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <firmware-raspberrypi.h>
#include "dev_pin_dm.h"
#define NUM_GPIO 2
struct brcmvirt_gpio
{
struct rt_device_pin parent;
rt_uint32_t *ts_base;
rt_uint32_t enables_disables[NUM_GPIO];
rt_ubase_t bus_addr;
};
#define raw_to_brcmvirt_gpio(raw) rt_container_of(raw, struct brcmvirt_gpio, parent)
static void brcmvirt_gpio_mode(struct rt_device *device, rt_base_t pin, rt_uint8_t mode)
{
}
static void brcmvirt_gpio_write(struct rt_device *device, rt_base_t pin, rt_uint8_t value)
{
rt_bool_t lit;
rt_uint16_t enables, disables;
struct brcmvirt_gpio *gpio = raw_to_brcmvirt_gpio(device);
enables = gpio->enables_disables[pin] >> 16;
disables = gpio->enables_disables[pin] >> 0;
lit = (rt_int16_t)(enables - disables) > 0;
if ((value && lit) || (!value && !lit))
{
return;
}
if (value)
{
enables++;
}
else
{
disables++;
}
gpio->enables_disables[pin] = (enables << 16) | (disables << 0);
HWREG32(gpio->ts_base + pin) = gpio->enables_disables[pin];
}
static rt_ssize_t brcmvirt_gpio_read(struct rt_device *device, rt_base_t pin)
{
rt_uint32_t value;
struct brcmvirt_gpio *gpio = raw_to_brcmvirt_gpio(device);
value = HWREG32(gpio->ts_base + pin);
return (rt_int16_t)((value >> 16) - value) > 0;
}
static const struct rt_pin_ops brcmvirt_gpio_ops =
{
.pin_mode = brcmvirt_gpio_mode,
.pin_write = brcmvirt_gpio_write,
.pin_read = brcmvirt_gpio_read,
};
static rt_err_t brcmvirt_gpio_probe(struct rt_platform_device *pdev)
{
rt_err_t err;
void *ts_base;
rt_uint32_t virtbuf;
struct rpi_firmware *rpi_fw = RT_NULL;
struct rt_device *dev = &pdev->parent;
struct rt_ofw_node *np = dev->ofw_node, *fw_np;
struct brcmvirt_gpio *gpio = rt_calloc(1, sizeof(*gpio));
if (!gpio)
{
return -RT_ENOMEM;
}
fw_np = rt_ofw_parse_phandle(np, "firmware", 0);
if (!fw_np)
{
err = -RT_EINVAL;
goto _fail;
}
rpi_fw = rpi_firmware_get(fw_np);
rt_ofw_node_put(fw_np);
if (!rpi_fw)
{
err = -RT_EINVAL;
goto _fail;
}
ts_base = rt_dma_alloc_coherent(dev, ARCH_PAGE_SIZE, &gpio->bus_addr);
if (!ts_base)
{
err = -RT_ENOMEM;
goto _fail;
}
virtbuf = (rt_uint32_t)gpio->bus_addr;
err = rpi_firmware_property(rpi_fw,
RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF, &gpio->bus_addr, sizeof(virtbuf));
if (err)
{
goto _fail;
}
err = rpi_firmware_property(rpi_fw,
RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF, &virtbuf, sizeof(virtbuf));
if (err)
{
goto _fail;
}
virtbuf &= ~0xc0000000;
gpio->ts_base = rt_ioremap((void *)(rt_ubase_t)virtbuf, ARCH_PAGE_SIZE);
if (!gpio->ts_base)
{
goto _fail;
}
rt_dm_dev_bind_fwdata(dev, RT_NULL, &gpio->parent);
gpio->parent.ops = &brcmvirt_gpio_ops;
pin_api_init(&gpio->parent, NUM_GPIO);
return RT_EOK;
_fail:
if (gpio->bus_addr)
{
rt_dma_free_coherent(dev, ARCH_PAGE_SIZE, ts_base, gpio->bus_addr);
}
if (rpi_fw)
{
rpi_firmware_put(rpi_fw);
}
rt_free(gpio);
return err;
}
static const struct rt_ofw_node_id brcmvirt_gpio_ofw_ids[] =
{
{ .compatible = "brcm,bcm2835-virtgpio" },
{ /* sentinel */ }
};
static struct rt_platform_driver brcmvirt_gpio_driver =
{
.name = "brcmvirt-gpio",
.ids = brcmvirt_gpio_ofw_ids,
.probe = brcmvirt_gpio_probe,
};
static int brcmvirt_gpio_drv_register(void)
{
rt_platform_driver_register(&brcmvirt_gpio_driver);
return 0;
}
INIT_SUBSYS_EXPORT(brcmvirt_gpio_drv_register);

Some files were not shown because too many files have changed in this diff Show More