mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-10-01 08:27:30 +08:00
[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:
+8
-8
@@ -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
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
kernel*.img
|
||||
rtthread.bin
|
||||
*.dtb
|
||||
*.qcow2
|
||||
flash.bin
|
||||
rtt.asm
|
||||
rtthread.map
|
||||
build/
|
||||
Executable
+33
@@ -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
|
||||
Regular → Executable
-1
@@ -1,4 +1,3 @@
|
||||
# for module compiling
|
||||
import os
|
||||
from building import *
|
||||
|
||||
Executable
+6
@@ -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
|
||||
Executable
+13
@@ -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')
|
||||
Executable
+328
File diff suppressed because it is too large
Load Diff
Executable
+4
@@ -0,0 +1,4 @@
|
||||
config RT_AUDIO_BCM2835_I2S
|
||||
bool "Broadcom BCM2835 I2S"
|
||||
depends on RT_USING_DMA
|
||||
default n
|
||||
Executable
+13
@@ -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')
|
||||
Executable
+724
File diff suppressed because it is too large
Load Diff
Executable
+19
@@ -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
|
||||
Executable
+22
@@ -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')
|
||||
Executable
+237
File diff suppressed because it is too large
Load Diff
Executable
+220
File diff suppressed because it is too large
Load Diff
Executable
+1976
File diff suppressed because it is too large
Load Diff
Executable
+139
@@ -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);
|
||||
Executable
+405
File diff suppressed because it is too large
Load Diff
Executable
+1797
File diff suppressed because it is too large
Load Diff
Executable
+3
@@ -0,0 +1,3 @@
|
||||
config RT_CLOCK_TIME_BCM2835
|
||||
bool "BCM2835 Timer"
|
||||
default y
|
||||
Executable
+13
@@ -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')
|
||||
+268
File diff suppressed because it is too large
Load Diff
Executable
+3
@@ -0,0 +1,3 @@
|
||||
config RT_DMA_BCM2835
|
||||
bool "BCM2835 DMA"
|
||||
default n
|
||||
Executable
+13
@@ -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')
|
||||
Executable
+805
File diff suppressed because it is too large
Load Diff
Executable
+796
File diff suppressed because it is too large
Load Diff
Executable
+657
File diff suppressed because it is too large
Load Diff
Executable
+4
@@ -0,0 +1,4 @@
|
||||
config RT_DVFS_RASPBERRY_CPUFREQ
|
||||
bool "Raspberry firmware CPUfreq driver"
|
||||
depends on RT_USING_DVFS
|
||||
default n
|
||||
Executable
+13
@@ -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')
|
||||
+276
File diff suppressed because it is too large
Load Diff
Executable
+3
@@ -0,0 +1,3 @@
|
||||
config RT_ETHERNET_BCMGENET
|
||||
bool "BCMGENET V5 Ethernet MAC"
|
||||
default n
|
||||
Executable
+13
@@ -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')
|
||||
Executable
+1219
File diff suppressed because it is too large
Load Diff
Executable
+6
@@ -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
|
||||
Executable
+13
@@ -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')
|
||||
+453
File diff suppressed because it is too large
Load Diff
Executable
+13
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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')
|
||||
+508
File diff suppressed because it is too large
Load Diff
+215
File diff suppressed because it is too large
Load Diff
Executable
+2
@@ -0,0 +1,2 @@
|
||||
config RT_GRAPHIC_LOGO_RASPI_CLUT224
|
||||
bool "Standard 224-color Raspberry PI logo"
|
||||
+5
@@ -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
|
||||
+883
File diff suppressed because it is too large
Load Diff
Executable
+14
@@ -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
|
||||
Executable
+16
@@ -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')
|
||||
+330
File diff suppressed because it is too large
Load Diff
+326
File diff suppressed because it is too large
Load Diff
Executable
+9
@@ -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
|
||||
Executable
+16
@@ -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')
|
||||
Executable
+502
File diff suppressed because it is too large
Load Diff
Executable
+723
File diff suppressed because it is too large
Load Diff
Executable
+23
@@ -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
@@ -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
@@ -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__ */
|
||||
+236
File diff suppressed because it is too large
Load Diff
@@ -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__ */
|
||||
@@ -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__ */
|
||||
+219
File diff suppressed because it is too large
Load Diff
Executable
+44
@@ -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__ */
|
||||
Executable
+13
@@ -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')
|
||||
Executable
+5
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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')
|
||||
+264
File diff suppressed because it is too large
Load Diff
Executable
+3
@@ -0,0 +1,3 @@
|
||||
config RT_MBOX_BCM2835
|
||||
bool "BCM2835 Mailbox"
|
||||
default n
|
||||
Executable
+13
@@ -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')
|
||||
+251
File diff suppressed because it is too large
Load Diff
Executable
+18
@@ -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
|
||||
Executable
+19
@@ -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')
|
||||
Executable
+119
@@ -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);
|
||||
Executable
+415
File diff suppressed because it is too large
Load Diff
Executable
+165
@@ -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);
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
config RT_NVMEM_RASPBERRYPI_OTP
|
||||
bool "Raspberry Pi OTP support"
|
||||
depends on RT_USING_NVMEM
|
||||
default n
|
||||
Executable
+13
@@ -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')
|
||||
Executable
+180
@@ -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);
|
||||
Executable
+5
@@ -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
|
||||
Executable
+13
@@ -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')
|
||||
Executable
+2669
File diff suppressed because it is too large
Load Diff
Executable
+7
@@ -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
|
||||
Executable
+16
@@ -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')
|
||||
Executable
+324
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
Executable
+19
@@ -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
|
||||
Executable
+22
@@ -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')
|
||||
Executable
+435
File diff suppressed because it is too large
Load Diff
Executable
+247
File diff suppressed because it is too large
Load Diff
Executable
+341
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Executable
+15
@@ -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
|
||||
Executable
+19
@@ -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')
|
||||
Executable
+188
@@ -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
Reference in New Issue
Block a user