/* * /proc/sys/board - Interface to the SIMpad cs3 register * * (c) 2004 by Till Harbaum, BeeCon GmbH, * * 2007/03/05 mrdata: * porting from kernel24 * */ #include #include #include #include #include #include #include #include #include #include extern long get_cs3_shadow(void); extern void set_cs3_bit(int value); extern void clear_cs3_bit(int value); /* * This is the number for the "board" entry in /proc/sys: */ #define SIMPAD_SYSCTL 1312 /* * These are the numbers for the entries in /etc/sys/board */ enum { CTL_NAME=991, CTL_CS3, // the complete latch CTL_VCC_5V_EN, // For 5V PCMCIA CTL_VCC_3V_EN, // FOR 3.3V PCMCIA CTL_EN1, // This is only for EPROM's CTL_EN0, // Both should be enable for 3.3V or 5V CTL_DISPLAY_ON, CTL_PCMCIA_BUFF_DIS, CTL_MQ_RESET, CTL_PCMCIA_RESET, CTL_DECT_POWER_ON, CTL_IRDA_SD, // Shutdown for powersave CTL_RS232_ON, CTL_SD_MEDIAQ, // Shutdown for powersave CTL_LED2_ON, CTL_IRDA_MODE, // Fast/Slow IrDA mode CTL_ENABLE_5V, // Enable 5V circuit CTL_RESET_SIMCARD }; static const char simpad_board_name[] = "SIMpad"; static int dummy_int; static char dummy_str[80]; static int simpad_sysctl_handler(ctl_table * ctl, int write, struct file *filp, void *buffer, size_t *lenp, loff_t *ppos) { int *valp = ctl->data; int val; int ret; // Update parameters from the real registers switch (ctl->ctl_name) { case CTL_CS3: sprintf(dummy_str, "0x%04lx", get_cs3_shadow()); return proc_dostring(ctl,write,filp,buffer,lenp,ppos); break; // the 16 control bits of the cs3 register case CTL_VCC_5V_EN: case CTL_VCC_3V_EN: case CTL_EN1: case CTL_EN0: case CTL_DISPLAY_ON: case CTL_PCMCIA_BUFF_DIS: case CTL_MQ_RESET: case CTL_PCMCIA_RESET: case CTL_DECT_POWER_ON: case CTL_IRDA_SD: case CTL_RS232_ON: case CTL_SD_MEDIAQ: case CTL_LED2_ON: case CTL_IRDA_MODE: case CTL_ENABLE_5V: case CTL_RESET_SIMCARD: *valp = (get_cs3_shadow() & (1u << (ctl->ctl_name-CTL_VCC_5V_EN)))?1:0; break; default: // Just ignore unsupported parameters break; } // the strings are all handled now and ran onto a return; // Save old state val = *valp; // Perform the generic integer operation if ((ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos)) != 0) return (ret); // Write changes out to the registers if (write && *valp != val) { val = *valp; switch (ctl->ctl_name) { // the 16 control bits of the cs3 register case CTL_DISPLAY_ON: case CTL_DECT_POWER_ON: case CTL_IRDA_SD: case CTL_SD_MEDIAQ: case CTL_LED2_ON: case CTL_IRDA_MODE: case CTL_RESET_SIMCARD: if (val) set_cs3_bit(1u << (ctl->ctl_name-CTL_VCC_5V_EN)); else clear_cs3_bit(1u << (ctl->ctl_name-CTL_VCC_5V_EN)); break; default: // Just ignore unsupported parameters break; } } return ret; } #define PROC_RDONLY 0444 #define PROC_RDWR 0664 static ctl_table simpad_table[] = { { procname: "sys_name", ctl_name: CTL_NAME, data: &simpad_board_name, maxlen: sizeof(simpad_board_name), proc_handler: &proc_dostring, mode: PROC_RDONLY, }, { procname: "cs3", ctl_name: CTL_CS3, data: &dummy_str, maxlen: sizeof(dummy_str), proc_handler: &simpad_sysctl_handler, mode: PROC_RDONLY, }, { procname: "vcc_5v_en", ctl_name: CTL_VCC_5V_EN, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDONLY, }, { procname: "vcc_3v_en", ctl_name: CTL_VCC_3V_EN, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDONLY, }, { procname: "en1", ctl_name: CTL_EN1, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDONLY, }, { procname: "en0", ctl_name: CTL_EN0, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDONLY, }, { procname: "display_on", ctl_name: CTL_DISPLAY_ON, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDWR, }, { procname: "pcmcia_buff_dis", ctl_name: CTL_PCMCIA_BUFF_DIS, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDONLY, }, { procname: "mq_reset", ctl_name: CTL_MQ_RESET, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDONLY, }, { procname: "pcmcia_reset", ctl_name: CTL_PCMCIA_RESET, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDONLY, }, { procname: "dect_power_on", ctl_name: CTL_DECT_POWER_ON, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDWR, }, { procname: "irda_sd", ctl_name: CTL_IRDA_SD, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDWR, }, { procname: "rs232_on", ctl_name: CTL_RS232_ON, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDONLY, }, { procname: "sd_mediaq", ctl_name: CTL_SD_MEDIAQ, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDWR, }, { procname: "led2_on", ctl_name: CTL_LED2_ON, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDWR, }, { procname: "irda_mode", ctl_name: CTL_IRDA_MODE, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDWR, }, { procname: "enable_5v", ctl_name: CTL_ENABLE_5V, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDONLY, }, { procname: "reset_simcard", ctl_name: CTL_RESET_SIMCARD, data: &dummy_int, maxlen: sizeof(int), proc_handler: &simpad_sysctl_handler, mode: PROC_RDWR, }, {0} }; static ctl_table simpad_root_table[] = { {SIMPAD_SYSCTL, "board", NULL, 0, 0555, simpad_table}, {0} }; static struct ctl_table_header *simpad_table_header; static int __init simpad_sysctl_init(void) { simpad_table_header = register_sysctl_table(simpad_root_table, 0); if (!simpad_table_header) return -ENOMEM; return 0; } static void __exit simpad_sysctl_exit(void) { unregister_sysctl_table(simpad_table_header); } module_init(simpad_sysctl_init); module_exit(simpad_sysctl_exit); MODULE_AUTHOR("Till Harbaum "); MODULE_DESCRIPTION("Implements /proc/sys/board"); MODULE_LICENSE("GPL");