ADD: [uboot16] support for gnsscan shield

BugzID: 54934
This commit is contained in:
Marcel Reichmuth 2018-12-21 14:43:34 +01:00 committed by Moritz Rosenthal
parent 1c281a330d
commit c02a80a048
5 changed files with 167 additions and 2 deletions

View File

@ -10,4 +10,4 @@ ifeq ($(CONFIG_SKIP_LOWLEVEL_INIT),)
obj-y := mux.o
endif
obj-y += board.o ../common/bdparser.o ../common/board_descriptor.o shield.o shield_can.o shield_comio.o fileaccess.o
obj-y += board.o ../common/bdparser.o ../common/board_descriptor.o shield.o shield_can.o shield_comio.o shield_gnsscan.o fileaccess.o

View File

@ -40,6 +40,7 @@
#include "shield.h"
#include "shield_can.h"
#include "shield_comio.h"
#include "shield_gnsscan.h"
#include "fileaccess.h"
DECLARE_GLOBAL_DATA_PTR;
@ -82,6 +83,7 @@ static BD_Context bdctx[3]; /* The descriptor context */
#define SHIELD_COM_IO 0
#define SHIELD_DUALCAN 1
#define SHIELD_GNSSCAN 2
static int _bd_init(void)
{
@ -597,6 +599,16 @@ static struct shield_command known_shield_commands[] = {
"fdt set $can1 status okay;",
can_shield_init
},
{
SHIELD_GNSSCAN,
"gnsscan",
"shield gnsscan termination off",
"fdt get value serial0 /aliases serial0;" \
"fdt get value can1 /aliases d_can1;" \
"fdt set $serial0 status okay;" \
"fdt set $can1 status okay;",
gnsscan_shield_init
},
};
static const struct shield_command* get_shield_command(int shield_id)

View File

@ -67,7 +67,8 @@ static int do_shieldmode(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
U_BOOT_CMD(
shield, 6, 1, do_shieldmode,
"Set the shield mode",
"dualcan termination on|off on|off\n"
"shield dualcan termination on|off on|off\n"
"shield comio mode rs232|rs485 [termination on|off]\n"
"shield gnsscan termination on|off\n"
);

View File

@ -0,0 +1,143 @@
#undef DEBUG
#include <common.h>
#include <asm/gpio.h>
#include <asm/arch/mux.h>
#include "shield.h"
#include "board.h"
#define NETBIRD_GPIO_RST_SHIELD_N GPIO_TO_PIN(0, 27)
#define NETBIRD_GPIO_EN_CAN_TERM_N GPIO_TO_PIN(0, 7)
static int shield_slot_initialized = 0;
static struct module_pin_mux gnsscan_shield_netbird_pin_mux_final[] = {
/* Leave UART0 unconfigured because we want to configure it as needed by linux (can/spi/uart/etc) */
{OFFSET(uart0_rxd), (MODE(7) | PULLUDDIS | RXACTIVE)}, /* (E15) UART0_RXD */
{OFFSET(uart0_txd), (MODE(7) | PULLUDDIS | RXACTIVE)}, /* (E16) UART0_TXD */
{OFFSET(uart0_ctsn), (MODE(2) | PULLUDEN | PULLUP_EN)}, /* CAN1 tx */
{OFFSET(uart0_rtsn), (MODE(2) | PULLUDDIS | RXACTIVE)}, /* CAN1 rx */
{OFFSET(ecap0_in_pwm0_out), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* EN_CAN1_TERM_N */
{-1},
};
static int request_gpios(void)
{
int ret;
debug("Shield configure gpios\n");
ret = shield_gpio_request_as_input(NETBIRD_GPIO_RST_SHIELD_N, "shield-rst");
if ((ret < 0))
return -1;
ret = shield_gpio_request_as_input(NETBIRD_GPIO_EN_CAN_TERM_N, "shield-can-term-n");
if ((ret < 0))
return -1;
shield_slot_initialized = 1;
return 0;
}
static int configure_shieldmode(int mode)
{
int ret;
if (mode < 0 || mode > 1) {
debug("Invalid shield mode %d\n", mode);
return -1;
}
debug("Shield type gnsscan\n");
debug ("Set shield mode to %d\n", mode);
if (!shield_slot_initialized) {
if (request_gpios()) {
puts("Failed to request gpios\n");
return -1;
}
}
debug("Set final gnsscan shield muxing\n");
configure_module_pin_mux(gnsscan_shield_netbird_pin_mux_final);
debug("Make sure shield module is in reset\n");
ret = gpio_direction_output(NETBIRD_GPIO_RST_SHIELD_N, 0);
if (ret < 0) {
puts("Can not set shield-rst as output\n");
return -1;
}
udelay(10);
debug("Set termination on/off\n");
ret = gpio_direction_output(NETBIRD_GPIO_EN_CAN_TERM_N, mode);
if (ret < 0) {
puts("Can not set shield-can-term as output\n");
return -1;
}
udelay(10);
debug("Take shield out of reset\n");
gpio_set_value(NETBIRD_GPIO_RST_SHIELD_N, 1);
udelay(10);
return 0;
}
static int get_termination(const char* termination)
{
if (strcmp("on", termination) == 0) {
return 1;
}
else if (strcmp("off", termination) == 0) {
return 0;
}
debug ("Invalid termination mode %s (falling back to off)", termination);
return -1;
}
static int get_mode_from_args(char * const argv[], int argc)
{
#define CAN_PORTS 1
int terminations[CAN_PORTS];
int i;
assert(argc == (CAN_PORTS + 1));
if (strcmp ("termination", argv[0])) {
debug("The only option for dualcan is terminations\n");
return -1;
}
for (i = 0; i < CAN_PORTS; i ++) {
terminations[i] = get_termination(argv[i + 1]);
if (terminations[i] < 0) {
return -1;
}
}
/* Termination is inverse */
return (!terminations[0] << 0);
}
static int set_shieldmode(char * const argv[], int argc)
{
if (argc != 2) {
debug("Too few arguments for gnsscan\n");
return -1;
}
return configure_shieldmode(get_mode_from_args(argv, argc));
}
struct shield_t gnsscan_shield = {
"gnsscan", set_shieldmode
};
void gnsscan_shield_init(void)
{
shield_register(&gnsscan_shield);
}

View File

@ -0,0 +1,9 @@
#ifndef SHIELD_GNSSCAN_H
#define SHIELD_GNSSCAN_H
int shield_gnsscan_init(void);
int shield_gnscan_setmode(int mode);
void gnsscan_shield_init(void);
#endif // SHIELD_CAN_H