📄 1008.fip.patch
字号:
+ /* Sleep when buffer is empty */+ wait_event_interruptible(fip_wq, priv->c_idx != priv->p_idx); + }++ spin_lock_irqsave(&priv->lock, flags);++ /* Get the data out and adjust consumer index */+ for (cnt = 0; (priv->c_idx != priv->p_idx) && (cnt < count); cnt++) {+ *buf = priv->buffer[priv->c_idx];+ priv->c_idx = (priv->c_idx + 1) % buffer_size;+ buf++;+ }++ spin_unlock_irqrestore(&priv->lock, flags);++ return(cnt);+}++/* Poll function */+static unsigned int fip_poll(struct file *fptr, struct poll_table_struct *ptable){+ struct fip_private *priv = (struct fip_private *)fptr->private_data;+ unsigned int mask = 0;++ poll_wait(fptr, &fip_wq, ptable);+ if (priv->c_idx != priv->p_idx)+ mask |= (POLLIN | POLLRDNORM);+ return(mask);+}++#ifdef ENABLE_WRITE_INTR+static void fip_issue_command(struct fip_private *priv)+{+ unsigned long flags;++ spin_lock_irqsave(&priv->lock, flags);++ if (priv->cmd_pidx == priv->cmd_cidx) {+ priv->cmdq_empty = 1;+ goto out;+ } else if (!is_fip_busy_nowait()) {+ priv->cmdq_empty = 0;+ fip_wait_ready();+ fip_write_reg(FIP_DISPLAY_DATA, priv->cmds[priv->cmd_cidx].data);+ fip_wait_ready();+ fip_write_reg(FIP_COMMAND, priv->cmds[priv->cmd_cidx].cmd);+ fip_wait_ready();+ priv->cmd_cidx = ((priv->cmd_cidx + 1) % CMDQ_SIZE);+ if (priv->cmd_pidx == priv->cmd_cidx) + priv->cmdq_empty = 1;+ }+out:+ spin_unlock_irqrestore(&priv->lock, flags);+}+#endif++static int fip_open(struct inode *inode_ptr, struct file *fptr)+{+ MOD_INC_USE_COUNT;++ /* This device is exclusive, that is, only one process can use it */+ if (fip_priv.ref_cnt != 0) {+ printk(KERN_WARNING "%s: exclusive access only\n", fip_devname);+ return(-EIO);+ } ++ /* Set the block mode and increase reference count */+ fip_priv.ref_cnt++;+ fip_priv.b_mode = ((fptr->f_flags & O_NONBLOCK) ? 0 : 1);+ fip_priv.last_jiffies = jiffies;++ /* Flush the buffer */+ fip_priv.p_idx = fip_priv.c_idx = 0;++ fptr->f_op = &fip_fops;+ fptr->private_data = (void *)&fip_priv;++ fip_timer.function = fip_poll_key;+ fip_timer.data = (unsigned long)&fip_priv;+ fip_timer.expires = jiffies + (HZ / poll_per_sec);+ add_timer(&fip_timer);++#if 0+ immediate.sync = 0;+ immediate.data = (void *)&fip_priv;+ immediate.routine = fip_poll_key;+ queue_task(&immediate, &tq_immediate);+ mark_bh(IMMEDIATE_BH);+#endif++ fip_clear();+ return(0);+}++static int fip_release(struct inode *inode_ptr, struct file *fptr) +{+ unsigned long start = 0;+ MOD_DEC_USE_COUNT;++ /* Adjust reference count */+ fip_priv.ref_cnt--;++ /* Wait for timer expiration */+ for (start = jiffies; time_after(start + 2 * (HZ / poll_per_sec), jiffies););+ del_timer_sync(&fip_timer);+ return(0);+}++static int fip_read(struct file *fptr, char *bufptr, size_t size, loff_t *fp)+{+ unsigned long buf[buffer_size];+ int count = 0;++ /* Check the alignment */+ if (size % sizeof(unsigned long)) {+ printk(KERN_WARNING "%s: read size not aligned to %ld\n",+ fip_devname, sizeof(unsigned long));+ return(-EIO);+ }++ count = fip_consume(fptr->private_data, &buf[0], + size / sizeof(unsigned long)) * sizeof(unsigned long);++ /* Get the data to user */+ if (count && copy_to_user(bufptr, (char *)&buf[0], count)) + return(-EFAULT);++ return(count);+}++static int fip_write(struct file *fptr, const char *bufptr, size_t size, loff_t *fp)+{+ fip_wait_ready();+ fip_write_text(0, bufptr, FIP_CENTER); + fip_wait_ready();+ return(size);+}++static int fip_ioctl(struct inode *inode, struct file *fptr, unsigned int cmd, unsigned long arg)+{+ int on = 0;+ int symbol;+ int i, j, k;++ switch(cmd) {+ case FIP_IOCSHOWSYMBOL:+ on = ((arg & 0x80000000)) == 0 ? 0 : 1;+ symbol = (int)(arg & 0xff);+ fip_display_symbol(symbol, on);+ break;+ case FIP_IOCSHOWHMS:+ k = (int)(arg & 0xff);+ j = (int)((arg >> 8) & 0xff);+ i = (int)((arg >> 16) & 0xff);+ fip_show_hms(i, j, k);+ break;+ case FIP_IOCDISPCHAR:+ k = (int)(arg & 0xff);+ j = (int)((arg >> 8) & 0xff);+ fip_display_character(j, k);+ break;+ case FIP_IOCDISPRAW:+ on = ((arg & 0x80000000)) == 0 ? 0 : 1;+ k = (int)(arg & 0xff);+ j = (int)((arg >> 8) & 0xff);+ fip_display_raw(j, k, on);+ break;+ case FIP_IOCDISPTEXT:+ printk("%s: ioctl FIP_IOCDISPTEXT not implemented.\n", fip_devname);+ return(-EIO);+ case FIP_IOCCLEAR:+ fip_clear();+ break;+ case FIP_IOCGETFPTYPE:+ {+ unsigned long *ptr = (unsigned long *)arg;+ unsigned long type = 0;+#if defined(CONFIG_TANGO2_FIP_REF1)+ type = 1;+#elif defined(CONFIG_TANGO2_FIP_REF2)+ type = 2;+#else+ return(-EIO);+#endif+ if (copy_to_user(ptr, (char *)&type, sizeof(unsigned long))) + return(-EFAULT);+ }+ break;+ default:+ return(-EIO);+ }+ return(0);+}++#endif /* __KERNEL__ */++/* Micro-second sleep */+static void fip_usleep(unsigned usec)+{+#ifdef __KERNEL__+ udelay(usec);+#else+ em86xx_usleep(usec);+#endif /* __KERNEL__ */+}++static unsigned int fip_read_reg(unsigned int offset)+{+// unsigned int val = *((volatile unsigned int *)(fip_base + offset));+ unsigned int val = gbus_read_uint32(pGBus, fip_base + offset);+ return(val);+}++static void fip_write_reg(unsigned int offset, unsigned int val)+{+ fip_wait_ready();+// *((volatile unsigned int *)(fip_base + offset)) = val;+ gbus_write_uint32(pGBus, fip_base + offset, val);+ fip_wait_ready();+}++#ifdef __KERNEL__+#ifdef ENABLE_WRITE_INTR+/* To queue the write request */+static void fip_queue_command(unsigned int cmd, unsigned int data)+{+ unsigned long flags;++ spin_lock_irqsave(&fip_priv.lock, flags);+ if (((fip_priv.cmd_pidx + 1) % CMDQ_SIZE) == fip_priv.cmd_cidx) {+ printk(KERN_ERR "Command queue full.\n");+ fip_issue_command(&fip_priv);+ } else {+ fip_priv.cmds[fip_priv.cmd_pidx].cmd = cmd;+ fip_priv.cmds[fip_priv.cmd_pidx].data = data;+ fip_priv.cmd_pidx = ((fip_priv.cmd_pidx + 1) % CMDQ_SIZE);+ }+ spin_unlock_irqrestore(&fip_priv.lock, flags);+}+#endif+#endif++#ifdef __KERNEL__+static int is_fip_busy_nowait(void)+{+ return((fip_read_reg(FIP_CONFIG) & FIP_BUSY) != 0);+}+#endif++#ifdef __KERNEL__+static+#endif /* __KERNEL__ */+int is_fip_busy(void)+{+#if defined(CONFIG_TANGO2_FIP_REF1)+ fip_usleep(10);+#elif defined(CONFIG_TANGO2_FIP_REF2)+ fip_usleep(20);+#endif+ return((fip_read_reg(FIP_CONFIG) & FIP_BUSY) != 0);+}++#ifdef __KERNEL__+static+#endif /* __KERNEL__ */+void fip_wait_ready(void)+{+ while (is_fip_busy());+#if defined(CONFIG_TANGO2_FIP_REF2)+ 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_TANGO2_FIP_REF1)+ const int min_pos = 1;+#elif defined(CONFIG_TANGO2_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__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -