#include #include #include #include #include #include // for current #include #include "shared_utils.h" #include #include #include "bcm_gpio.h" #define XDSL_DISTPOINT_PROC_ENTRY_NAME "xdsl_distpoint" // Hardware related xdsl distpoint information (see board parameters) XDSL_DISTPOINT_INFO xdslDistpointInfo; #define BUFFER_SIZE 128 char buffer[BUFFER_SIZE]; int buffer_len; static void _show_reset_status(void); static void _show_gpio_value(void); static int _set_gpio_value(unsigned short gpio, unsigned short value); //{{{ tty static int mtty_write(char *text) { struct tty_struct *my_tty; static int null_tty = 0; my_tty = current->signal->tty; if (my_tty != NULL) tty_write_message(my_tty, text); else null_tty++; return strlen (text); } static int mtty_writeln(char *text) { int r = 0; r += mtty_write(text); r += mtty_write ("\015\012"); /* crlf */ return r; } static int mtty_writeln_buffer(void) { int r = 0; int i = 0; buffer[buffer_len + 1] = '\0'; r = mtty_writeln(buffer); for (i=0;i "); mtty_writeln(" gpio [ ]"); mtty_writeln(" status"); } static int _proc_show(struct seq_file *f, void *v) { seq_printf(f, "Usage: echo command > /proc/" XDSL_DISTPOINT_PROC_ENTRY_NAME "\n\n"); seq_printf(f, "supported commands: \n"); seq_printf(f, " reset \n"); seq_printf(f, " gpio [ ]\n"); seq_printf(f, " status\n"); return 0; } static int _proc_open(struct inode *inode, struct file *file) { return single_open(file, _proc_show, NULL); } static int _proc_control_reset(char * cmd, char * id_or_name) { unsigned short i = 0; unsigned long j = 0; unsigned short gpio_num = 0; int is_user_gpio = 0; // search by id if (0 == kstrtoul(id_or_name, 10, &j)) { gpio_num = (unsigned short) j; for (i=0;i KBUF_SIZE) cnt = KBUF_SIZE; if (copy_from_user(kbuf, buf, cnt)) return -EFAULT; kbuf[cnt]='\0'; argc = sscanf(kbuf, "%s %s %s", arg[0], arg[1], arg[2]); if (argc < 1) { mtty_writeln("Need at-least 1 argument"); return -EFAULT; } for (i=0; i "); return -EFAULT; } if (_proc_control_reset(arg[1], arg[2])) { return -EFAULT; } } else if (0 == strcmp(arg[0], "gpio")) { switch (argc) { case 1: _show_gpio_value(); break; case 3: if (kstrtoul(arg[1], 10, &gpio_num)) { buffer_len = sprintf(buffer, "invalid gpio id %s", arg[1]); mtty_writeln_buffer(); return -EFAULT; } if (kstrtoul(arg[2], 10, &gpio_value)) { buffer_len = sprintf(buffer, "invalid gpio value %s", arg[2]); mtty_writeln_buffer(); return -EFAULT; } if (_set_gpio_value((unsigned short) gpio_num, (unsigned short) gpio_value)) { return -EFAULT; } break; default: mtty_writeln("Invalid number of arguments for gpio command."); mtty_writeln("gpio command: gpio [ [value]]"); return -EFAULT; } } else if (0 == strcmp(arg[0], "status")) { _show_reset_status(); _show_gpio_value(); } else { mtty_writeln("Invalid command."); _proc_show_supported_commands(); return -EFAULT; } return cnt; } static void _show_reset_status(void) { unsigned short i = 0; unsigned short gpio; int max_name_len = 0; int name_len = 0; int is_active_low = 0; for (i=0;i max_name_len) max_name_len = name_len; } mtty_writeln("+-------------------------+"); mtty_writeln("| status of reset outputs |"); mtty_writeln("+-------------------------+"); buffer_len = sprintf(buffer, "%-*s\tvalue\tgpio", max_name_len, "name"); mtty_writeln_buffer(); for (i=0;i max_info_len) max_info_len = info_len; } mtty_writeln("+-----------------------------------------------------+"); mtty_writeln("| status of user controllable general purpose outputs |"); mtty_writeln("+-----------------------------------------------------+"); buffer_len = mtty_write("gpio\t"); buffer_len += sprintf(buffer + buffer_len, "%-*s\t", max_info_len, "info"); buffer_len += sprintf(buffer + buffer_len, "value"); mtty_writeln_buffer(); for (i=0;i