📄 fipkernel.c
字号:
fip_usleep(20);#endif}static void fip_user_display(int adr, int data){#ifdef __KERNEL__#ifdef ENABLE_WRITE_INTR fip_wait_ready(); fip_queue_command(FIP_CMD_ADR_SETTING | (adr), data);#else fip_wait_ready(); fip_write_reg(FIP_DISPLAY_DATA, data); fip_write_reg(FIP_COMMAND, FIP_CMD_ADR_SETTING | (adr));#endif#else fip_wait_ready(); fip_write_reg(FIP_DISPLAY_DATA, data); fip_wait_ready(); fip_write_reg(FIP_COMMAND, FIP_CMD_ADR_SETTING | (adr)); fip_wait_ready();#endif}#ifdef __KERNEL__static#endif /* __KERNEL__ */int fip_display_character(const int position, const char character) { int i, byte1, byte2; unsigned char current_contents0, current_contents1;#if defined(CONFIG_EM86XX_FIP_REF1) const int min_pos = 1;#elif defined(CONFIG_EM86XX_FIP_REF2) const int min_pos = 0;#endif if ((position < min_pos) || (position > NUM_DIGITS)) {#ifdef __KERNEL__ printk(KERN_DEBUG "%s: position %d not available/supported.\n", fip_devname, position);#else uart_printf("%s: position %d not available/supported.\n", fip_devname, position);#endif /* __KERNEL__ */ return(0); } for (i = 0; i < NUM_CHARACTERS; i++) { if (character == fipcharactersmap[i]) { byte1 = 24 - (3 * position); byte2 = 25 - (3 * position); current_contents0 = fipram[byte1]; current_contents1 = fipram[byte2]; /* clear */ fipram[byte1] &= fipcharactermask[0]; fipram[byte2] &= fipcharactermask[1]; /* set new bits */ fipram[byte1] |= fipcharacters[i][0]; fipram[byte2] |= fipcharacters[i][1]; /* display if necessary */ if (current_contents0 != fipram[byte1]) fip_user_display(byte1, fipram[byte1]); if (current_contents1 != fipram[byte2]) fip_user_display(byte2, fipram[byte2]); return(1); } }#ifdef __KERNEL__ printk(KERN_DEBUG "%s: character '%c' not available/supported.\n", fip_devname, character);#else uart_printf("%s: character '%c' not available/supported.\n", fip_devname, character);#endif /* __KERNEL__ */ return(0);}#ifdef __KERNEL__static#endif /* __KERNEL__ */void fip_clear(void){ register int i; for (i = 0; i < MAX_FIP_RAM; i++) { fipram[i] = 0; fip_user_display(i, fipram[i]); }}#ifdef __KERNEL__static#endif /* __KERNEL__ */void fip_display_raw(const int byte, const int bit, const int on) { unsigned char current_contents; current_contents = fipram[byte]; if (on != 0) fipram[byte] |= (1 << bit); else fipram[byte] &= ~(1 << bit); /* display only if necessary */ if (current_contents != fipram[byte]) fip_user_display(byte, fipram[byte]);}#ifdef __KERNEL__static#endif /* __KERNEL__ */void fip_display_symbol(const int symbol, const int on) { if ((symbol < 0) || (symbol >= NUM_SYMBOLS)) {#ifdef __KERNEL__ printk(KERN_DEBUG "%s: symbol #%d not available/supported.\n", fip_devname, symbol);#else uart_printf("%s: symbol #%d not available/supported.\n", fip_devname, symbol);#endif /* __KERNEL__ */ return; }#if defined(CONFIG_EM86XX_FIP_REF1) fip_display_raw(fipsymbols[symbol][0], fipsymbols[symbol][1], on);#elif defined(CONFIG_EM86XX_FIP_REF2) //0-99 displays tra/chap number field (0-99) //100-199 displays title number field (0-99) //200 clears all in this area //201-206 displays symbols without effecting other fields if (symbol > 200) { //fip_display_raw(fipsymbols[symbol-200][0], fipsymbols[symbol-200][1], on); switch(symbol) { case 201: fip_user_display(0, 1); break; case 202: fip_user_display(0, 2); break; case 203: fip_user_display(0, 4); break; case 204: fip_user_display(0, 8); break; case 205: fip_user_display(27, 1); break; case 206: fip_user_display(29, 1); break; } } else if (symbol == 200) { fipram[27] = fipxcharacters[11]; fipram[28] = fipxcharacters[11]; fipram[30] = fipxcharacters[11]; fipram[31] = fipxcharacters[11]; fip_user_display(27, fipram[27]); fip_user_display(28, fipram[28]); fip_user_display(30, fipram[30]); fip_user_display(31, fipram[31]); } else if (symbol >= 100) { fipram[27] = fipxcharacters[(symbol-100)/10]; fipram[28] = fipxcharacters[(symbol-100)%10]; fip_user_display(27, fipram[27]); fip_user_display(28, fipram[28]); } else if (symbol >= 0) { fipram[30] = fipxcharacters[symbol/10]; fipram[31] = fipxcharacters[symbol%10]; fip_user_display(30, fipram[30]); fip_user_display(31, fipram[31]); }#endif}#ifdef __KERNEL__static#endif /* __KERNEL__ */void fip_write_text(const int position, const char *text, const int flags) { int x, i, j; int textLen = strlen (text);#if defined(CONFIG_EM86XX_FIP_REF1) if (flags & FIP_CENTER) x = (position > 0) ? position - textLen / 2 : (NUM_DIGITS - textLen) / 2 + 1; else if (flags & FIP_RIGHT) x = (position > 0) ? position - textLen : NUM_DIGITS - textLen + 1; else x = (position > 0) ? position : 1; if (x < 1) x = 1; if ((flags & FIP_NO_CLEAR) == 0) { /* clear colons */ fip_display_symbol(COLON_HOUR_MIN_FIP_ON, 0); fip_display_symbol(COLON_MIN_SEC_FIP_ON, 0); }#elif defined(CONFIG_EM86XX_FIP_REF2) if (flags & FIP_CENTER) x = (position >= 0) ? position - textLen / 2 : (NUM_DIGITS - textLen) / 2 + 1; else if (flags & FIP_RIGHT) x = (position >= 0) ? position - textLen : NUM_DIGITS - textLen + 1; else x = (position >= 0) ? position : 1; if (x < 1) x = 1;#endif /* show/write text */ j = 0; for (i = 1; i <= NUM_DIGITS; i++) { if ((i < x) || (i >= (x+textLen))) fip_display_character(i, ' '); else if (!fip_display_character(i, text[j++])) {#ifdef __KERNEL__ printk(KERN_DEBUG "%s: cannot show text '%s'.\n", fip_devname, text);#else uart_printf("%s: cannot show text '%s'.\n", fip_devname, text);#endif /* __KERNEL__ */ break; } }}#ifdef __KERNEL__ static #endif /* __KERNEL__ */int fip_show_hms(int hour, int minute, int second){ if (hour < L_OFF || minute < L_OFF || second < L_OFF || hour > 99 || minute > 59 || second > 59) {#ifdef __KERNEL__ printk(KERN_DEBUG "%s: parameters passed not in valid range\n", fip_devname);#else uart_printf("%s: parameters passed not in valid range\n", fip_devname);#endif return(1); } #if defined(CONFIG_EM86XX_FIP_REF1) // hour fip_display_character(1, ' '); fip_display_character(2, (hour==L_OFF) ? ' ' : hour/10 + '0'); fip_display_character(3, (hour==L_OFF) ? ' ' : hour%10 + '0'); // minute fip_display_character(4, (minute==L_OFF) ? ' ' : minute/10 + '0'); fip_display_character(5, (minute==L_OFF) ? ' ' : minute%10 + '0'); // second fip_display_character(6, (second==L_OFF) ? ' ' : second/10 + '0'); fip_display_character(7, (second==L_OFF) ? ' ' : second%10 + '0'); // show colons if needed fip_display_symbol(COLON_HOUR_MIN_FIP_ON, (hour == L_OFF) ? 0 : 1); fip_display_symbol(COLON_MIN_SEC_FIP_ON, ((hour == L_OFF) && (minute == L_OFF)) ? 0 : 1);#elif defined(CONFIG_EM86XX_FIP_REF2) // hour fip_display_character(0, (hour==L_OFF) ? ' ' : hour/10 + '0'); fip_display_character(1, (hour==L_OFF) ? ' ' : hour%10 + '0'); // minute fip_display_character(2, (minute==L_OFF) ? ' ' : minute/10 + '0'); fip_display_character(3, (minute==L_OFF) ? ' ' : minute%10 + '0'); // second fip_display_character(4, (second==L_OFF) ? ' ' : second/10 + '0'); fip_display_character(5, (second==L_OFF) ? ' ' : second%10 + '0'); fip_display_character(6, ' '); fip_display_character(7, ' ');#endif return(0);}#ifdef __KERNEL__ static #endif /* __KERNEL__ */int fip_init(void){ static int initflag = 0; if (initflag != 0) return(0);#ifdef __KERNEL__ /* Disable FIP and interrupt first */ fip_wait_ready(); fip_write_reg(FIP_CONFIG, 0); fip_wait_ready();#ifdef ENABLE_WRITE_INTR /* Enable FIP and interrupts (read: 0x20000, write: 0x10000) */ fip_write_reg(FIP_CONFIG, (FIP_DIVIDER | FIP_ENABLE | 0x30000));#else /* Enable FIP and interrupts (read: 0x20000) */ fip_write_reg(FIP_CONFIG, (FIP_DIVIDER | FIP_ENABLE | 0x20000));#endif#else fip_wait_ready(); /* Enable FIP wthout enabling interrupt */ fip_write_reg(FIP_CONFIG, (FIP_DIVIDER | FIP_ENABLE));#endif /* __KERNEL__ */ fip_wait_ready(); /* Clear exisiting IRQ, if any */ fip_write_reg(FIP_INT, 0x3); fip_wait_ready(); /* select display mode */ fip_write_reg(FIP_COMMAND, FIP_DISPLAY_MODE); fip_wait_ready(); /* select brightness of display and turn it on */ fip_write_reg(FIP_COMMAND, FIP_CMD_DISP_CTRL_TURN_DISPLAY_ON | brightness); fip_wait_ready(); /* select write to display and fixed addressing */ fip_write_reg(FIP_COMMAND, FIP_CMD_DATA_SET_ADR_MODE_FIXED_ADR); fip_wait_ready(); fip_clear(); fip_wait_ready(); initflag = 1; return(0);}#ifdef __KERNEL__ static #endif /* __KERNEL__ */int fip_exit(void){ fip_clear(); /* Disable FIP and interrupt */ fip_write_reg(FIP_CONFIG, 0); fip_wait_ready(); return(0); fip_wait_ready();}#ifndef __KERNEL__ unsigned long fip_readkey(void){ unsigned long key = 0L; fip_wait_ready(); fip_write_reg(FIP_COMMAND, FIP_CMD_DATA_SET_RW_MODE_READ_KEYS); key = fip_read_reg(FIP_KEY_DATA1); return(key);}#endif /* __KERNEL__ */#ifdef __KERNEL__int __init fip_init_module(void){ int status = 0; /* Initialize private data structure */ memset(&fip_priv, 0, sizeof(struct fip_private)); #ifdef ENABLE_WRITE_INTR fip_priv.cmdq_empty = 1;#endif spin_lock_init(fip_priv.lock); if (buffer_size < 1) { printk(KERN_ERR "%s: buffer size (%d) error\n", fip_devname, buffer_size); return(-EIO); } if ((fip_priv.buffer = kmalloc(buffer_size * sizeof(unsigned long), GFP_KERNEL)) == NULL) { printk(KERN_ERR "%s: out of memory for buffer\n", fip_devname); return(-ENOMEM); } /* Register device, and may be allocating major# */ status = register_chrdev(fip_major, fip_devname, &fip_fops); if (status < 0) { printk(KERN_ERR "%s: cannot get major number\n", fip_devname); if (fip_priv.buffer != NULL) kfree(fip_priv.buffer); return(status); } else if (fip_major == 0) fip_major = status; /* Dynamic major# allocation */ /* Hook up ISR */ if (request_irq(fip_irq, fip_isr, 0, fip_devname, &fip_priv) != 0) { printk(KERN_ERR "%s: cannot register IRQ (%d)\n", fip_devname, fip_irq); unregister_chrdev(fip_major, fip_devname); if (fip_priv.buffer != NULL) kfree(fip_priv.buffer); return(-EIO); } /* Do nothing is CONFIG_DEVFS_FS is not enabled */ devfs_handle = devfs_register(NULL, fip_devname, DEVFS_FL_AUTO_DEVNUM, fip_major, 0, S_IFCHR | S_IRUGO | S_IWUGO, &fip_fops, NULL); if (devfs_handle == NULL) printk(KERN_WARNING "%s: devfs module not registered\n", fip_devname); fip_init(); init_timer(&fip_timer); printk("%s: driver loaded (buffer_size = %d)\n", fip_devname, buffer_size); return(0);}void __exit fip_cleanup_module(void){ /* Do nothing is CONFIG_DEVFS_FS is not enabled */ if (devfs_handle != NULL) devfs_unregister(devfs_handle); unregister_chrdev(fip_major, fip_devname); free_irq(fip_irq, &fip_priv); if (fip_priv.buffer != NULL) kfree(fip_priv.buffer); fip_exit(); printk(KERN_DEBUG "%s: driver unloaded\n", fip_devname);}module_init(fip_init_module);module_exit(fip_cleanup_module);#endif /* __KERNEL__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -