Merge branch 'for-next/rs485'
Conflicts: common/console_common.c
This commit is contained in:
commit
ebf9022f2e
|
@ -327,20 +327,37 @@ static int animeo_ip_devices_init(void)
|
||||||
|
|
||||||
device_initcall(animeo_ip_devices_init);
|
device_initcall(animeo_ip_devices_init);
|
||||||
|
|
||||||
static int animeo_ip_console_init(void)
|
static struct device_d *usart0, *usart1;
|
||||||
|
|
||||||
|
static void animeo_ip_shutdown_uart(void *base)
|
||||||
|
{
|
||||||
|
#define ATMEL_US_BRGR 0x0020
|
||||||
|
writel(0, base + ATMEL_US_BRGR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void animeo_ip_shutdown(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* disable the dbgu enable by the bootstrap
|
* disable the dbgu and others enable by the bootstrap
|
||||||
* so linux can detect that we only enable the uart2
|
* so linux can detect that we only enable the uart2
|
||||||
* and use it for decompress
|
* and use it for decompress
|
||||||
*/
|
*/
|
||||||
#define ATMEL_US_BRGR 0x0020
|
animeo_ip_shutdown_uart(IOMEM(AT91_DBGU + AT91_BASE_SYS));
|
||||||
at91_sys_write(AT91_DBGU + ATMEL_US_BRGR, 0);
|
animeo_ip_shutdown_uart(IOMEM(AT91SAM9260_BASE_US0));
|
||||||
|
animeo_ip_shutdown_uart(IOMEM(AT91SAM9260_BASE_US1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int animeo_ip_console_init(void)
|
||||||
|
{
|
||||||
|
at91_register_uart(3, 0);
|
||||||
|
|
||||||
|
usart0 = at91_register_uart(1, ATMEL_UART_RTS);
|
||||||
|
usart1 = at91_register_uart(2, ATMEL_UART_RTS);
|
||||||
|
board_shutdown = animeo_ip_shutdown;
|
||||||
|
|
||||||
barebox_set_model("Somfy Animeo IP");
|
barebox_set_model("Somfy Animeo IP");
|
||||||
barebox_set_hostname("animeoip");
|
barebox_set_hostname("animeoip");
|
||||||
|
|
||||||
at91_register_uart(3, 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
console_initcall(animeo_ip_console_init);
|
console_initcall(animeo_ip_console_init);
|
||||||
|
@ -351,3 +368,64 @@ static int animeo_ip_main_clock(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pure_initcall(animeo_ip_main_clock);
|
pure_initcall(animeo_ip_main_clock);
|
||||||
|
|
||||||
|
static unsigned int get_char_timeout(struct console_device *cs, int timeout)
|
||||||
|
{
|
||||||
|
uint64_t start = get_time_ns();
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (!cs->tstc(cs))
|
||||||
|
continue;
|
||||||
|
return cs->getc(cs);
|
||||||
|
} while (!is_timeout(start, timeout));
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int animeo_ip_cross_detect_init(void)
|
||||||
|
{
|
||||||
|
struct console_device *cs0, *cs1;
|
||||||
|
int i;
|
||||||
|
char *s = "loop";
|
||||||
|
int crossed = 0;
|
||||||
|
|
||||||
|
cs0 = console_get_by_dev(usart0);
|
||||||
|
if (!cs0)
|
||||||
|
return -EINVAL;
|
||||||
|
cs1 = console_get_by_dev(usart1);
|
||||||
|
if (!cs1)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
at91_set_gpio_input(AT91_PIN_PC16, 0);
|
||||||
|
cs0->set_mode(cs0, CONSOLE_MODE_RS485);
|
||||||
|
cs0->setbrg(cs0, 38400);
|
||||||
|
cs1->set_mode(cs1, CONSOLE_MODE_RS485);
|
||||||
|
cs1->setbrg(cs1, 38400);
|
||||||
|
|
||||||
|
/* empty the bus */
|
||||||
|
while (cs1->tstc(cs1))
|
||||||
|
cs1->getc(cs1);
|
||||||
|
|
||||||
|
for (i = 0; i < strlen(s); i++) {
|
||||||
|
unsigned int ch = s[i];
|
||||||
|
unsigned int c;
|
||||||
|
|
||||||
|
resend:
|
||||||
|
cs0->putc(cs0, ch);
|
||||||
|
c = get_char_timeout(cs1, 10 * MSECOND);
|
||||||
|
if (c == 0)
|
||||||
|
goto resend;
|
||||||
|
else if (c != ch)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
crossed = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
export_env_ull("rs485_crossed", crossed);
|
||||||
|
|
||||||
|
pr_info("rs485 ports %scrossed\n", crossed ? "" : "not ");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
late_initcall(animeo_ip_cross_detect_init);
|
||||||
|
|
|
@ -16,7 +16,6 @@ CONFIG_PROMPT_HUSH_PS2="y"
|
||||||
CONFIG_HUSH_FANCY_PROMPT=y
|
CONFIG_HUSH_FANCY_PROMPT=y
|
||||||
CONFIG_CMDLINE_EDITING=y
|
CONFIG_CMDLINE_EDITING=y
|
||||||
CONFIG_AUTO_COMPLETE=y
|
CONFIG_AUTO_COMPLETE=y
|
||||||
CONFIG_CONSOLE_ACTIVATE_ALL=y
|
|
||||||
CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
|
CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
|
||||||
CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/animeo_ip/env"
|
CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/animeo_ip/env"
|
||||||
CONFIG_CMD_EDIT=y
|
CONFIG_CMD_EDIT=y
|
||||||
|
|
|
@ -169,6 +169,19 @@ int fputc(int fd, char c)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(fputc);
|
EXPORT_SYMBOL(fputc);
|
||||||
|
|
||||||
|
struct console_device *console_get_by_dev(struct device_d *dev)
|
||||||
|
{
|
||||||
|
struct console_device *cdev;
|
||||||
|
|
||||||
|
for_each_console(cdev) {
|
||||||
|
if (cdev->dev == dev)
|
||||||
|
return cdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(console_get_by_dev);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief returns current used console device
|
* @brief returns current used console device
|
||||||
*
|
*
|
||||||
|
|
|
@ -161,6 +161,8 @@ void __noreturn hang (void)
|
||||||
for (;;);
|
for (;;);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void (*board_shutdown)(void);
|
||||||
|
|
||||||
/* Everything needed to cleanly shutdown barebox.
|
/* Everything needed to cleanly shutdown barebox.
|
||||||
* Should be called before starting an OS to get
|
* Should be called before starting an OS to get
|
||||||
* the devices into a clean state
|
* the devices into a clean state
|
||||||
|
@ -171,4 +173,6 @@ void shutdown_barebox(void)
|
||||||
#ifdef ARCH_SHUTDOWN
|
#ifdef ARCH_SHUTDOWN
|
||||||
arch_shutdown();
|
arch_shutdown();
|
||||||
#endif
|
#endif
|
||||||
|
if (board_shutdown)
|
||||||
|
board_shutdown();
|
||||||
}
|
}
|
||||||
|
|
|
@ -362,6 +362,32 @@ static int atmel_serial_setbaudrate(struct console_device *cdev, int baudrate)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int atmel_serial_set_mode(struct console_device *cdev, enum console_mode mode)
|
||||||
|
{
|
||||||
|
struct atmel_uart_port *uart = to_atmel_uart_port(cdev);
|
||||||
|
u32 mr;
|
||||||
|
u8 m;
|
||||||
|
|
||||||
|
mr = readl(uart->base + USART3_MR);
|
||||||
|
mr &= ~0xf;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case CONSOLE_MODE_NORMAL:
|
||||||
|
m = USART3_USART_MODE_NORMAL;
|
||||||
|
break;
|
||||||
|
case CONSOLE_MODE_RS485:
|
||||||
|
m = USART3_USART_MODE_RS485;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mr |= USART3_BF(USART_MODE, m);
|
||||||
|
writel(mr, uart->base + USART3_MR);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialise the serial port with the given baudrate. The settings
|
* Initialise the serial port with the given baudrate. The settings
|
||||||
* are always 8 data bits, no parity, 1 stop bit, no start bits.
|
* are always 8 data bits, no parity, 1 stop bit, no start bits.
|
||||||
|
@ -401,6 +427,7 @@ static int atmel_serial_probe(struct device_d *dev)
|
||||||
cdev->putc = atmel_serial_putc;
|
cdev->putc = atmel_serial_putc;
|
||||||
cdev->getc = atmel_serial_getc;
|
cdev->getc = atmel_serial_getc;
|
||||||
cdev->setbrg = atmel_serial_setbaudrate;
|
cdev->setbrg = atmel_serial_setbaudrate;
|
||||||
|
cdev->set_mode = atmel_serial_set_mode;
|
||||||
|
|
||||||
atmel_serial_init_port(cdev);
|
atmel_serial_init_port(cdev);
|
||||||
|
|
||||||
|
|
|
@ -152,6 +152,7 @@ extern int (*barebox_main)(void);
|
||||||
|
|
||||||
void __noreturn start_barebox(void);
|
void __noreturn start_barebox(void);
|
||||||
void shutdown_barebox(void);
|
void shutdown_barebox(void);
|
||||||
|
extern void (*board_shutdown)(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* architectures which have special calling conventions for
|
* architectures which have special calling conventions for
|
||||||
|
|
|
@ -28,6 +28,11 @@
|
||||||
#define CONSOLE_STDOUT (1 << 1)
|
#define CONSOLE_STDOUT (1 << 1)
|
||||||
#define CONSOLE_STDERR (1 << 2)
|
#define CONSOLE_STDERR (1 << 2)
|
||||||
|
|
||||||
|
enum console_mode {
|
||||||
|
CONSOLE_MODE_NORMAL,
|
||||||
|
CONSOLE_MODE_RS485,
|
||||||
|
};
|
||||||
|
|
||||||
struct console_device {
|
struct console_device {
|
||||||
struct device_d *dev;
|
struct device_d *dev;
|
||||||
struct device_d class_dev;
|
struct device_d class_dev;
|
||||||
|
@ -37,6 +42,7 @@ struct console_device {
|
||||||
int (*getc)(struct console_device *cdev);
|
int (*getc)(struct console_device *cdev);
|
||||||
int (*setbrg)(struct console_device *cdev, int baudrate);
|
int (*setbrg)(struct console_device *cdev, int baudrate);
|
||||||
void (*flush)(struct console_device *cdev);
|
void (*flush)(struct console_device *cdev);
|
||||||
|
int (*set_mode)(struct console_device *cdev, enum console_mode mode);
|
||||||
|
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
|
||||||
|
@ -48,6 +54,8 @@ struct console_device {
|
||||||
int console_register(struct console_device *cdev);
|
int console_register(struct console_device *cdev);
|
||||||
int console_unregister(struct console_device *cdev);
|
int console_unregister(struct console_device *cdev);
|
||||||
|
|
||||||
|
struct console_device *console_get_by_dev(struct device_d *dev);
|
||||||
|
|
||||||
extern struct list_head console_list;
|
extern struct list_head console_list;
|
||||||
#define for_each_console(console) list_for_each_entry(console, &console_list, list)
|
#define for_each_console(console) list_for_each_entry(console, &console_list, list)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue