Commit 7f048482 authored by carbon's avatar carbon

buildroot: add duo-pinmux

parent 0c1ee95d
......@@ -269,6 +269,7 @@ BR2_PACKAGE_BUSYBOX_CONFIG_FRAGMENT_FILES=""
# BR2_PACKAGE_BUSYBOX_INDIVIDUAL_BINARIES is not set
# BR2_PACKAGE_BUSYBOX_WATCHDOG is not set
BR2_PACKAGE_WIRINGX=y
BR2_PACKAGE_DUO_PINMUX=y
BR2_PACKAGE_SKELETON=y
BR2_PACKAGE_HAS_SKELETON=y
BR2_PACKAGE_PROVIDES_SKELETON="skeleton-init-sysv"
......
......@@ -2,6 +2,7 @@ menu "Target packages"
source "package/busybox/Config.in"
source "package/wiringx/Config.in"
source "package/duo-pinmux/Config.in"
source "package/skeleton/Config.in"
source "package/skeleton-custom/Config.in"
source "package/skeleton-init-common/Config.in"
......
config BR2_PACKAGE_DUO_PINMUX
bool "Duo pinmux"
help
Pinmux for Milk-V Duo
DUO_PINMUX_SITE = $(TOPDIR)/package/duo-pinmux/src
DUO_PINMUX_VERSION = 1.0.0
DUO_PINMUX_SITE_METHOD = local
define DUO_PINMUX_BUILD_CMDS
$(TARGET_MAKE_ENV) $(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_LDFLAGS) \
$(@D)/*.c -o $(@D)/duo-pinmux
endef
define DUO_PINMUX_INSTALL_TARGET_CMDS
$(INSTALL) -D -m 0755 $(@D)/duo-pinmux $(TARGET_DIR)/usr/bin/
endef
$(eval $(generic-package))
/*
** read/write phy addr in userspace
** open /dev/mem
** taiqiang.cao@bitmain.com
*/
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <termios.h>
#include <unistd.h>
#include "devmem.h"
// DEBUG_SET_LEVEL(DEBUG_LEVEL_ERR);
#define ERR printf
#define DEBUG printf
static int devmem_fd;
void *devm_map(unsigned long addr, int len)
{
off_t offset;
void *map_base;
devmem_fd = open("/dev/mem", O_RDWR | O_SYNC);
if (devmem_fd == -1) {
ERR("cannot open '/dev/mem'\n");
goto open_err;
}
// DEBUG("/dev/mem opened.\n");
offset = addr & ~(sysconf(_SC_PAGE_SIZE) - 1);
map_base = mmap(NULL, len + addr - offset, PROT_READ | PROT_WRITE, MAP_SHARED, devmem_fd, offset);
if (map_base == MAP_FAILED) {
ERR("mmap failed\n");
goto mmap_err;
}
// DEBUG("Memory mapped at address %p.\n", map_base + addr - offset);
return map_base + addr - offset;
mmap_err:
close(devmem_fd);
open_err:
return NULL;
}
void devm_unmap(void *virt_addr, int len)
{
unsigned long addr;
if (devmem_fd == -1) {
ERR("'/dev/mem' is closed\n");
return;
}
/* page align */
addr = (((unsigned long)virt_addr) & ~(sysconf(_SC_PAGE_SIZE) - 1));
munmap((void *)addr, len + (unsigned long)virt_addr - addr);
close(devmem_fd);
}
/* read/write 32bit data*/
uint32_t devmem_readl(unsigned long addr)
{
uint32_t val;
void *virt_addr;
virt_addr = devm_map(addr, 4);
if (virt_addr == NULL) {
ERR("readl addr map failed\n");
return 0;
}
val = *(uint32_t *)virt_addr;
devm_unmap(virt_addr, 4);
return val;
}
void devmem_writel(unsigned long addr, uint32_t val)
{
void *virt_addr;
virt_addr = devm_map(addr, 4);
if (virt_addr == NULL) {
ERR("writel addr map failed\n");
return;
}
*(uint32_t *)virt_addr = val;
devm_unmap(virt_addr, 4);
}
#ifndef _DEVMEM_H_
#define _DEVMEM_H_
#include <stdint.h>
void *devm_map(unsigned long addr, int len);
void devm_unmap(void *virt_addr, int len);
uint32_t devmem_readl(unsigned long addr);
void devmem_writel(unsigned long addr, uint32_t val);
#endif
#include "devmem.h"
#include "func.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
#define PINMUX_BASE 0x03001000
#define INVALID_PIN 9999
struct pinlist {
char name[32];
uint32_t offset;
} pinlist_st;
struct pinlist cv180x_pin[] = {
{ "GP0", 0x4c }, // IIC0_SCL
{ "GP1", 0x50 }, // IIC0_SDA
{ "GP2", 0x84 }, // SD1_GPIO1
{ "GP3", 0x88 }, // SD1_GPIO0
{ "GP4", 0x90 }, // SD1_D2
{ "GP5", 0x94 }, // SD1_D1
{ "GP6", 0xa0 }, // SD1_CLK
{ "GP7", 0x9c }, // SD1_CMD
{ "GP8", 0x98 }, // SD1_D0
{ "GP9", 0x8c }, // SD1_D3
{ "GP10", 0xf0 }, // PAD_MIPIRX1P
{ "GP11", 0xf4 }, // PAD_MIPIRX0N
{ "GP12", 0x24 }, // UART0_TX
{ "GP13", 0x28 }, // UART0_RX
{ "GP14", 0x1c }, // SD0_PWR_EN
{ "GP15", 0x20 }, // SPK_EN
{ "GP16", 0x3c }, // SPINOR_MISO
{ "GP17", 0x40 }, // SPINOR_CS_X
{ "GP18", 0x30 }, // SPINOR_SCK
{ "GP19", 0x34 }, // SPINOR_MOSI
{ "GP20", 0x38 }, // SPINOR_WP_X
{ "GP21", 0x2c }, // SPINOR_HOLD_X
{ "GP22", 0x68 }, // PWR_SEQ2
{ "GP26", 0xa8 }, // ADC1
{ "GP27", 0xac }, // USB_VBUS_DET
{ "GP25", 0x12c }, // PAD_AUD_AOUTR
};
uint32_t convert_func_to_value(char *pin, char *func)
{
uint32_t i = 0;
uint32_t max_fun_num = NELEMS(cv180x_pin_func);
char v;
for (i = 0; i < max_fun_num; i++) {
if (strcmp(cv180x_pin_func[i].func, func) == 0) {
if (strncmp(cv180x_pin_func[i].name, pin, strlen(pin)) == 0) {
v = cv180x_pin_func[i].name[strlen(cv180x_pin_func[i].name) - 1];
break;
}
}
}
if (i == max_fun_num) {
printf("ERROR: invalid pin or func\n");
return INVALID_PIN;
}
return (v - 0x30);
}
void print_fun(char *name, uint32_t value)
{
uint32_t i = 0;
uint32_t max_fun_num = NELEMS(cv180x_pin_func);
char pinname[128];
sprintf(pinname, "%s%d", name, value);
printf("%s function:\n", name);
for (i = 0; i < max_fun_num; i++) {
if (strlen(cv180x_pin_func[i].name) != (strlen(name) + 1)) {
continue;
}
if (strncmp(pinname, cv180x_pin_func[i].name, strlen(name)) == 0) {
if (strcmp(pinname, cv180x_pin_func[i].name) == 0)
printf("[v] %s\n", cv180x_pin_func[i].func);
else
printf("[ ] %s\n", cv180x_pin_func[i].func);
// break;
}
}
printf("\n");
}
void print_usage(const char *prog)
{
printf("pinmux for duo\n");
printf("%s -p <== List all pins\n", prog);
printf("%s -l <== List all pins and its func\n", prog);
printf("%s -r pin <== Get func from pin\n", prog);
printf("%s -w pin/func <== Set func to pin\n", prog);
}
int main(int argc, char *argv[])
{
int opt = 0;
uint32_t i = 0;
uint32_t value;
char pin[32];
char func[32];
uint32_t f_val;
if (argc == 1) {
print_usage(argv[0]);
return 1;
}
while ((opt = getopt(argc, argv, "hplr:w:")) != -1) {
switch (opt) {
case 'r':
for (i = 0; i < NELEMS(cv180x_pin); i++) {
if (strcmp(optarg, cv180x_pin[i].name) == 0)
break;
}
if (i != NELEMS(cv180x_pin)) {
value = devmem_readl(PINMUX_BASE + cv180x_pin[i].offset);
// printf("value %d\n", value);
print_fun(optarg, value);
printf("register: 0x%x\n", PINMUX_BASE + cv180x_pin[i].offset);
printf("value: %d\n", value);
} else {
printf("\nInvalid option: %s", optarg);
}
break;
case 'w':
// printf("optarg %s\n", optarg);
if (sscanf(optarg, "%[^/]/%s", pin, func) != 2)
print_usage(argv[0]);
printf("pin %s\n", pin);
printf("func %s\n", func);
for (i = 0; i < NELEMS(cv180x_pin); i++) {
if (strcmp(pin, cv180x_pin[i].name) == 0)
break;
}
if (i != NELEMS(cv180x_pin)) {
f_val = convert_func_to_value(pin, func);
if (f_val == INVALID_PIN)
return 1;
devmem_writel(PINMUX_BASE + cv180x_pin[i].offset, f_val);
printf("register: %x\n", PINMUX_BASE + cv180x_pin[i].offset);
printf("value: %d\n", f_val);
// printf("value %d\n", value);
} else {
printf("\nInvalid option: %s\n", optarg);
}
break;
case 'p':
printf("Pinlist:\n");
for (i = 0; i < NELEMS(cv180x_pin); i++)
printf("%s\n", cv180x_pin[i].name);
break;
case 'l':
for (i = 0; i < NELEMS(cv180x_pin); i++) {
value = devmem_readl(PINMUX_BASE + cv180x_pin[i].offset);
// printf("value %d\n", value);
print_fun(cv180x_pin[i].name, value);
}
break;
case 'h':
print_usage(argv[0]);
break;
case '?':
print_usage(argv[0]);
break;
default:
print_usage(argv[0]);
break;
}
}
return 0;
}
struct funlist {
char name[32];
char func[32];
} funlist_st;
struct funlist cv180x_pin_func[] = {
// GP0 IIC0_SCL
{ "GP00", "JTAG_TDI"},
{ "GP01", "UART1_TX"},
{ "GP02", "UART2_TX"},
{ "GP03", "GP0"},
{ "GP04", "IIC0_SCL"},
{ "GP05", "WG0_D0"},
{ "GP07", "DBG_10"},
// GP1 IIC0_SDA
{ "GP10", "JTAG_TDO"},
{ "GP11", "UART1_RX"},
{ "GP12", "UART2_RX"},
{ "GP13", "GP1"},
{ "GP14", "IIC0_SDA"},
{ "GP15", "WG0_D1"},
{ "GP16", "WG1_D0"},
{ "GP17", "DBG_11"},
// GP2 SD1_GPIO1
{ "GP21", "UART4_TX"},
{ "GP23", "GP2"},
{ "GP27", "PWM_10"},
// GP3 SD1_GPIO0
{ "GP31", "UART4_RX"},
{ "GP33", "GP3"},
{ "GP37", "PWM_11"},
// GP4 SD1_D2
{ "GP40", "PWR_SD1_D2"},
{ "GP41", "IIC1_SCL"},
{ "GP42", "UART2_TX"},
{ "GP43", "GP4"},
{ "GP44", "CAM_MCLK0"},
{ "GP45", "UART3_TX"},
{ "GP46", "PWR_SPINOR1_HOLD_X"},
{ "GP47", "PWM_5"},
// GP5 SD1_D1
{ "GP50", "PWR_SD1_D1"},
{ "GP51", "IIC1_SDA"},
{ "GP52", "UART2_RX"},
{ "GP53", "GP5"},
{ "GP54", "CAM_MCLK1"},
{ "GP55", "UART3_RX"},
{ "GP56", "PWR_SPINOR1_WP_X"},
{ "GP57", "PWM_6"},
// GP6 SD1_CLK
{ "GP60", "PWR_SD1_CLK"},
{ "GP61", "SPI2_SCK"},
{ "GP62", "IIC3_SDA"},
{ "GP63", "GP6"},
{ "GP64", "CAM_HS0"},
{ "GP65", "EPHY_SPD_LED"},
{ "GP66", "PWR_SPINOR1_SCK"},
{ "GP67", "PWM_9"},
// GP7 SD1_CMD
{ "GP70", "PWR_SD1_CMD"},
{ "GP71", "SPI2_SDO"},
{ "GP72", "IIC3_SCL"},
{ "GP73", "GP7"},
{ "GP74", "CAM_VS0"},
{ "GP75", "EPHY_LNK_LED"},
{ "GP76", "PWR_SPINOR1_MOSI"},
{ "GP77", "PWM_8"},
// GP8 SD1_D0
{ "GP80", "PWR_SD1_D0"},
{ "GP81", "SPI2_SDI"},
{ "GP82", "IIC1_SDA"},
{ "GP83", "GP8"},
{ "GP84", "CAM_MCLK1"},
{ "GP85", "UART3_RTS"},
{ "GP86", "PWR_SPINOR1_MISO"},
{ "GP87", "PWM_7"},
// GP9 SD1_D3
{ "GP90", "PWR_SD1_D3"},
{ "GP91", "SPI2_CS_X"},
{ "GP92", "IIC1_SCL"},
{ "GP93", "GP9"},
{ "GP94", "CAM_MCLK0"},
{ "GP95", "UART3_CTS"},
{ "GP96", "PWR_SPINOR1_CS_X"},
{ "GP97", "PWM_4"},
// GP10 PAD_MIPIRX1P
{ "GP101", "VI0_D_6"},
{ "GP103", "GP10"},
{ "GP104", "IIC1_SDA"},
{ "GP106", "KEY_ROW2"},
{ "GP107", "DBG_9"},
// GP11 PAD_MIPIRX0N
{ "GP111", "VI0_D_7"},
{ "GP113", "GP11"},
{ "GP114", "IIC1_SCL"},
{ "GP115", "CAM_MCLK1"},
{ "GP117", "DBG_10"},
// GP12 UART0_TX
{ "GP120", "UART0_TX"},
{ "GP121", "CAM_MCLK1"},
{ "GP122", "PWM_4"},
{ "GP123", "GP12"},
{ "GP124", "UART1_TX"},
{ "GP125", "AUX1"},
{ "GP126", "JTAG_TMS"},
{ "GP127", "DBG_6"},
// GP13 UART0_RX
{ "GP130", "UART0_RX"},
{ "GP131", "CAM_MCLK0"},
{ "GP132", "PWM_5"},
{ "GP133", "GP13"},
{ "GP134", "UART1_RX"},
{ "GP135", "AUX0"},
{ "GP136", "JTAG_TCK"},
{ "GP137", "DBG_7"},
// GP14 SD0_PWR_EN
{ "GP140", "SDIO0_PWR_EN"},
{ "GP143", "GP14"},
// GP15 SPK_EN
{ "GP153", "GP15"},
// GP16 SPINOR_MISO
{ "GP161", "SPINOR_MISO"},
{ "GP162", "SPINAND_MISO"},
{ "GP163", "GP16"},
// GP17 SPINOR_CS_X
{ "GP171", "SPINOR_CS_X"},
{ "GP172", "SPINAND_CS"},
{ "GP173", "GP17"},
// GP18 SPINOR_SCK
{ "GP181", "SPINOR_SCK"},
{ "GP182", "SPINAND_CLK"},
{ "GP183", "GP18"},
// GP19 SPINOR_MOSI
{ "GP191", "SPINOR_MOSI"},
{ "GP192", "SPINAND_MOSI"},
{ "GP193", "GP19"},
// GP20 SPINOR_WP_X
{ "GP201", "SPINOR_WP_X"},
{ "GP202", "SPINAND_WP"},
{ "GP203", "GP20"},
// GP21 SPINOR_HOLD_X
{ "GP211", "SPINOR_HOLD_X"},
{ "GP212", "SPINAND_HOLD"},
{ "GP213", "GP21"},
// GP22 PWR_SEQ2
{ "GP220", "PWR_SEQ2"},
{ "GP223", "GP22"},
// GP25 PAD_AUD_AOUTR
{ "GP253", "GP25"},
{ "GP254", "IIS1_DI"},
{ "GP255", "IIS2_DO"},
{ "GP256", "IIS1_DO"},
// GP26 ADC1
{ "GP263", "GP26"},
{ "GP264", "KEY_COL2"},
{ "GP266", "PWM_3"},
// GP27 USB_VBUS_DET
{ "GP270", "USB_VBUS_DET"},
{ "GP273", "GP27"},
{ "GP274", "CAM_MCLK0"},
{ "GP275", "CAM_MCLK1"},
{ "GP276", "PWM_4"},
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment