📄 1008.fip.patch
字号:
+ {DIGIT_L(0,0,1,1,0,0,0,0), DIGIT_H(0,0,0,0,0,0,0,0)}, // v+ {DIGIT_L(0,0,1,1,0,1,1,0), DIGIT_H(0,0,0,0,0,0,0,0)}, // w+ {DIGIT_L(0,0,0,1,1,0,0,0), DIGIT_H(1,1,0,0,0,0,0,0)}, // x+ {DIGIT_L(0,0,0,0,1,0,0,0), DIGIT_H(0,0,0,1,1,0,0,0)}, // y+ {DIGIT_L(0,0,0,0,1,0,0,1), DIGIT_H(1,1,0,0,0,0,0,0)}, // z++ {DIGIT_L(0,0,0,0,1,0,0,0), DIGIT_H(0,0,0,1,0,0,0,0)}, // |+ {DIGIT_L(0,0,0,0,0,0,0,1), DIGIT_H(0,0,0,0,0,0,0,0)} // _+};+#elif defined(CONFIG_TANGO2_FIP_REF2)+/* the format is lower byte, higher byte */+static const char fipcharacters[NUM_CHARACTERS][2] = {+ {DIGIT_L(0,1,1,0,0,0,1,1), DIGIT_H(1,1,1,0,0,0,0,0)}, // 0+ {DIGIT_L(0,0,0,0,1,0,0,1), DIGIT_H(0,0,0,0,1,0,0,1)}, // 1+ {DIGIT_L(1,0,1,0,0,0,1,1), DIGIT_H(1,1,0,0,0,0,1,1)}, // 2+ {DIGIT_L(1,1,0,0,0,0,1,1), DIGIT_H(1,1,0,0,0,0,0,0)}, // 3+ {DIGIT_L(1,1,0,0,0,0,0,1), DIGIT_H(0,1,1,0,0,0,1,1)}, // 4+ {DIGIT_L(1,1,0,0,0,0,1,1), DIGIT_H(1,0,1,0,0,0,1,1)}, // 5+ {DIGIT_L(1,1,1,0,0,0,1,1), DIGIT_H(1,0,1,0,0,0,1,1)}, // 6+ {DIGIT_L(0,1,0,0,0,0,0,1), DIGIT_H(1,1,0,0,0,0,0,0)}, // 7+ {DIGIT_L(1,1,1,0,0,0,1,1), DIGIT_H(1,1,1,0,0,0,1,1)}, // 8+ {DIGIT_L(1,1,0,0,0,0,0,1), DIGIT_H(1,1,1,0,0,0,1,1)}, // 9+ {DIGIT_L(1,1,1,0,0,0,0,0), DIGIT_H(1,1,1,0,0,0,1,1)}, // A+ {DIGIT_L(1,1,0,0,1,0,1,0), DIGIT_H(1,1,0,0,1,0,0,1)}, // B+ {DIGIT_L(0,0,1,0,0,0,1,0), DIGIT_H(1,0,1,0,0,0,0,0)}, // C+ {DIGIT_L(0,1,0,0,1,0,1,0), DIGIT_H(1,1,0,0,1,0,0,1)}, // D+ {DIGIT_L(1,0,1,0,0,0,1,0), DIGIT_H(1,0,1,0,0,0,1,1)}, // E+ {DIGIT_L(0,0,1,0,0,0,0,0), DIGIT_H(1,0,1,0,0,0,1,1)}, // F+ {DIGIT_L(1,1,1,0,0,0,1,0), DIGIT_H(1,0,1,0,0,0,0,0)}, // G+ {DIGIT_L(1,1,1,0,0,0,0,0), DIGIT_H(0,1,1,0,0,0,1,1)}, // H+ {DIGIT_L(0,0,0,0,1,0,0,0), DIGIT_H(0,0,0,0,1,0,0,1)}, // I+ {DIGIT_L(0,1,1,0,0,0,1,0), DIGIT_H(0,1,0,0,0,0,0,0)}, // J+ {DIGIT_L(0,0,1,0,0,1,0,0), DIGIT_H(0,0,1,0,0,1,1,1)}, // K+ {DIGIT_L(0,0,1,0,0,0,1,0), DIGIT_H(0,0,1,0,0,0,0,0)}, // L+ {DIGIT_L(0,1,1,0,0,0,0,0), DIGIT_H(0,1,1,1,0,1,0,1)}, // M+ {DIGIT_L(0,1,1,0,0,1,0,0), DIGIT_H(0,1,1,1,0,0,0,1)}, // N+ {DIGIT_L(0,1,1,0,0,0,1,0), DIGIT_H(1,1,1,0,0,0,0,0)}, // O+ {DIGIT_L(1,0,1,0,0,0,0,0), DIGIT_H(1,1,1,0,0,0,1,1)}, // P+ {DIGIT_L(0,1,1,0,0,1,1,0), DIGIT_H(1,1,1,0,0,0,0,0)}, // Q+ {DIGIT_L(1,0,1,0,0,1,0,0), DIGIT_H(1,1,1,0,0,0,1,1)}, // R+ {DIGIT_L(1,1,0,0,0,0,1,0), DIGIT_H(1,0,1,0,0,0,1,1)}, // S+ {DIGIT_L(0,0,0,0,1,0,0,0), DIGIT_H(1,0,0,0,1,0,0,1)}, // T+ {DIGIT_L(0,1,1,0,0,0,1,0), DIGIT_H(0,1,1,0,0,0,0,0)}, // U+ {DIGIT_L(0,0,1,1,0,0,0,0), DIGIT_H(0,0,1,0,0,1,0,1)}, // V+ {DIGIT_L(0,1,1,1,0,1,0,0), DIGIT_H(0,1,1,0,0,0,0,1)}, // W+ {DIGIT_L(0,0,0,1,0,1,0,0), DIGIT_H(0,0,0,1,0,1,0,0)}, // X+ {DIGIT_L(0,0,0,0,1,0,0,0), DIGIT_H(0,0,0,1,0,1,0,1)}, // Y+ {DIGIT_L(0,0,0,1,0,0,1,0), DIGIT_H(1,0,0,0,0,1,0,1)}, // Z+ {0,0}, // Space+ {DIGIT_L(0,0,0,0,1,0,0,0), DIGIT_H(0,0,0,0,1,0,0,1)}, // !+ {DIGIT_L(0,0,0,0,0,0,0,0), DIGIT_H(0,0,1,0,1,0,0,0)}, // "+ {DIGIT_L(1,0,0,1,1,0,0,0), DIGIT_H(0,0,0,1,1,0,1,1)}, // #+ {DIGIT_L(1,1,0,0,1,0,1,0), DIGIT_H(1,0,1,0,1,0,1,1)}, // $+ {DIGIT_L(0,1,0,1,0,0,0,0), DIGIT_H(0,0,1,0,0,1,0,1)}, // %+ {DIGIT_L(0,0,1,0,1,0,1,0), DIGIT_H(1,0,0,1,0,1,1,1)}, // &+ {DIGIT_L(0,0,0,0,0,0,0,0), DIGIT_H(0,0,0,0,0,1,0,0)}, // '+ {DIGIT_L(0,0,0,0,0,1,0,0), DIGIT_H(0,0,0,0,0,1,0,0)}, // (+ {DIGIT_L(0,0,0,1,0,0,0,0), DIGIT_H(0,0,0,1,0,0,0,0)}, // )+ {DIGIT_L(1,0,0,1,1,1,0,0), DIGIT_H(0,0,0,1,1,1,1,1)}, // *+ {DIGIT_L(1,0,0,0,1,0,0,0), DIGIT_H(0,0,0,0,1,0,1,1)}, // ++ {DIGIT_L(0,0,0,1,0,0,0,0), DIGIT_H(0,0,0,0,0,0,0,0)}, // ,+ {DIGIT_L(1,0,0,0,0,0,0,0), DIGIT_H(0,0,0,0,0,0,1,1)}, // -+ {DIGIT_L(0,0,0,0,0,0,0,0), DIGIT_H(0,0,0,0,0,0,0,1)}, // .+ {DIGIT_L(0,0,0,1,0,0,0,0), DIGIT_H(0,0,0,0,0,1,0,1)}, // /+ {DIGIT_L(0,0,0,0,1,0,0,0), DIGIT_H(0,0,0,0,0,0,0,1)}, // :+ {DIGIT_L(0,0,0,1,0,0,0,0), DIGIT_H(0,0,0,0,0,0,0,1)}, // ;+ {DIGIT_L(0,0,0,0,0,1,0,0), DIGIT_H(0,0,0,0,0,1,0,1)}, // <+ {DIGIT_L(1,0,0,0,0,0,1,0), DIGIT_H(0,0,0,0,0,0,1,1)}, // =+ {DIGIT_L(0,0,0,1,0,0,0,0), DIGIT_H(0,0,0,1,0,0,0,1)}, // >+ {DIGIT_L(0,0,0,0,1,0,0,0), DIGIT_H(1,0,1,0,0,1,0,1)}, // ?+ {DIGIT_L(1,0,1,0,0,0,1,0), DIGIT_H(1,1,1,0,1,1,0,1)}, // @+ {DIGIT_L(0,0,0,1,0,0,1,0), DIGIT_H(1,0,0,1,0,0,0,0)}, // [+ {DIGIT_L(0,0,0,0,0,1,0,0), DIGIT_H(0,0,0,1,0,0,0,1)}, // / + {DIGIT_L(0,1,0,0,0,0,1,0), DIGIT_H(1,1,0,0,0,0,0,0)}, // ]+ {DIGIT_L(0,0,0,1,0,1,0,0), DIGIT_H(0,0,0,0,0,0,0,1)}, // ^+ {DIGIT_L(0,0,0,0,0,0,1,0), DIGIT_H(0,0,0,0,0,0,0,0)}, // _+ {DIGIT_L(0,0,0,0,0,0,0,0), DIGIT_H(0,0,0,1,0,0,0,0)}, // `+ {DIGIT_L(0,0,0,1,0,0,1,0), DIGIT_H(1,0,0,1,0,0,1,0)}, // {+ {DIGIT_L(0,0,0,0,1,0,0,0), DIGIT_H(0,0,0,0,1,0,0,1)}, // |+ {DIGIT_L(1,0,0,0,0,1,1,0), DIGIT_H(1,0,0,0,0,1,0,1)}, // }+ {DIGIT_L(1,0,0,0,0,0,0,0), DIGIT_H(0,0,0,0,0,0,1,0)} // ~+};++static const char fipxcharacters[NUM_X_CHARACTERS] = {+ DIGIT_X(1,1,1,0,1,1,1,1), // 0+ DIGIT_X(0,1,0,0,1,0,0,1), // 1+ DIGIT_X(1,1,0,1,0,1,1,1), // 2+ DIGIT_X(1,1,0,1,1,0,1,1), // 3+ DIGIT_X(0,1,1,1,1,0,0,1), // 4+ DIGIT_X(1,0,1,1,1,0,1,1), // 5+ DIGIT_X(1,0,1,1,1,1,1,1), // 6+ DIGIT_X(1,1,0,0,1,0,0,1), // 7+ DIGIT_X(1,1,1,1,1,1,1,1), // 8+ DIGIT_X(1,1,1,1,1,0,1,1), // 9+ DIGIT_X(0,0,0,1,0,0,0,0), // -+ DIGIT_X(0,0,0,0,0,0,0,0) // +};+#endif++#if defined(CONFIG_TANGO2_FIP_REF1)+/* this array is used to display individual symbols+ the format is [byte position][bit to turn on] - both zero based */+static const char fipsymbols[NUM_SYMBOLS][2] = {+ {0, 0}, /* DVD */+ {0, 1}, /* PLAY */+ {0, 2}, /* DTS */+ {0, 3}, /* MP3 */+ {0, 4}, /* DOLBY DIGITAL */+ {0, 5}, /* MPEG4 */+ {0, 6}, /* PAUSE */+ {0, 7}, /* DVI */+ {1, 0}, /* TWIRL1 */+ {1, 1}, /* TWIRL2 */+ {1, 2}, /* TWIRL3 */+ {1, 3}, /* TWIRL4 */+ {1, 4}, /* TWIRL5 */+ {1, 5}, /* TWIRL6 */+ {1, 6}, /* ALL */+ {1, 7}, /* REPEAT */+ {9, 6}, /* COLON_MIN_SEC */+ {9, 7}, /* R1080 */+ {12, 7}, /* R720 */+ {15, 6}, /* COLON_HOUR_MIN */+ {15, 7}, /* R480 */+ {18, 7}, /* PAL */+ {21, 7}, /* NTSC */+};+#elif defined(CONFIG_TANGO2_FIP_REF2)+/* this array is used to display individual symbols+ the format is [byte position][bit to turn on] - both zero based */+static const char fipsymbols[NUM_SYMBOLS][2] = {+ {0, 1}, // DVD+ {0, 2}, // VCD+ {0, 4}, // MP3+ {0, 8}, // CD+ {29, 1}, // Title+ {27, 1} // Track+};+#endif++/* The buffer size defines the size of circular buffer to keep the FIP keys */+#define BUF_SIZE 2++/* Wait period, to avoid bouncing or repeatation? */+#define WAIT_PERIOD 100++/* Default brightness level */+#define BRIGHTNESS 0x7++/* The number of key polling per second */+#define POLL_PER_SECOND 10++#ifdef __KERNEL__+/* The major device number and name */+#ifdef CONFIG_DEVFS_FS+#define FIP_DEV_MAJOR 0+#else+#define FIP_DEV_MAJOR 128 /* May need to be changed?? */+#endif ++#define DRIVER_VERSION "1.14"++MODULE_DESCRIPTION("TANGO2 front panel fip driver\n");+MODULE_AUTHOR("Mambo standalone team");+MODULE_LICENSE("GPL");++/* Wait queue, may be used if block mode is on */+DECLARE_WAIT_QUEUE_HEAD(fip_wq);++MODULE_PARM(major_num, "i");+MODULE_PARM(buffer_size, "i");+MODULE_PARM(wait_period, "i");+MODULE_PARM(brightness, "i");+MODULE_PARM(poll_per_sec, "i");++/* Some prototypes */+static int fip_open(struct inode *, struct file *);+static int fip_release(struct inode *, struct file *);+static int fip_read(struct file *, char *, size_t, loff_t *);+static int fip_write(struct file *, const char *, size_t, loff_t *);+static int fip_ioctl(struct inode *, struct file *, unsigned int, unsigned long);+static unsigned int fip_poll(struct file *, struct poll_table_struct *);+static int buffer_size = BUF_SIZE;+static int wait_period = WAIT_PERIOD;+static unsigned int poll_per_sec = POLL_PER_SECOND;+static int fip_irq = LOG2_CPU_FRONTPANEL_INT + IRQ_CONTROLLER_IRQ_BASE;+static void fip_isr(int irq, void *dev_id, struct pt_regs *regs);+static void fip_poll_key(unsigned long devid);++static struct timer_list fip_timer;+#if 0+static struct tq_struct immediate;+#endif++static void fip_write_text(const int position, const char *text, const int flags);+static int fip_show_hms(int hour, int minute, int second);+static void fip_display_symbol(const int symbol, const int on);+static int fip_display_character(const int position, const char character);+static void fip_display_raw(const int byte, const int bit, const int on); +static int is_fip_busy(void);+static int is_fip_busy_nowait(void);+static void fip_clear(void);++#else /* For Bootloader */++void fip_write_text(const int position, const char *text, const int flags);+void fip_display_symbol(const int symbol, const int on);+int fip_display_character(const int position, const char character);+void fip_display_raw(const int byte, const int bit, const int on); +int is_fip_busy(void);+void fip_clear(void);+int fip_init(void);+int fip_exit(void);++/* Some external functions from bootloader core */+void em86xx_usleep(int usec);+int uart_printf(const char *fmt, ...);+int strlen(const char *str);++#endif /* __KERNEL__ */++#define FIP_DEV_NAME "fip"++static void fip_write_reg(unsigned int offset, unsigned int val);+static unsigned int fip_read_reg(unsigned int offset);++#ifdef __KERNEL__ +#define CMDQ_SIZE 256++/* Private data structure */+struct cmd_request {+ unsigned int cmd;+ unsigned int data;+};++struct fip_private {+ unsigned long *buffer; /* Circular buffer */+ unsigned p_idx; /* Index of producer */+ unsigned c_idx; /* Index of consumer */+ unsigned ref_cnt; /* Reference count */+ spinlock_t lock; /* Spin lock */+ unsigned char b_mode; /* Blocking mode or not */+ unsigned long last_jiffies; /* Timestamp for last reception */+#ifdef ENABLE_WRITE_INTR+ struct cmd_request cmds[CMDQ_SIZE];+ unsigned cmd_pidx;+ unsigned cmd_cidx;+ unsigned cmdq_empty;+#endif+};++static struct file_operations fip_fops = {+ open: fip_open,+ read: fip_read,+ ioctl: fip_ioctl,+ poll: fip_poll,+ write: fip_write,+ release: fip_release,+ owner: THIS_MODULE,+};++static void fip_push_key(struct fip_private *priv, unsigned long key);+#ifdef ENABLE_WRITE_INTR+static void fip_issue_command(struct fip_private *priv);+static void fip_queue_command(unsigned int cmd, unsigned int data);+#endif++/* Global data */+static struct fip_private fip_priv;+static devfs_handle_t devfs_handle = NULL;+static int major_num = FIP_DEV_MAJOR;+#endif /* __KERNEL__ */++static char *fip_devname = FIP_DEV_NAME;+static int brightness = BRIGHTNESS;+static unsigned long fip_base = (unsigned long)FIP_BASE;+static char fipram[MAX_FIP_RAM] = {0};++#ifdef __KERNEL__++static void fip_isr(int irq, void *dev_id, struct pt_regs *regs)+{+ struct fip_private *priv = (struct fip_private *)dev_id;+ unsigned long stat;+ unsigned long key;++ if (irq == fip_irq) {+ //gbus_write_uint32(pGBus, REG_BASE_CPU + CPU_edge_rawstat, IRQMASKOF(irq));+ stat = (fip_read_reg(FIP_INT) & 0x3);+ fip_write_reg(FIP_INT, stat); /* Clear the interrupt */++ if (!is_fip_busy_nowait()) {+ if (stat & 0x2) {+ key = fip_read_reg(FIP_KEY_DATA1);+ fip_push_key(priv, key);+ }+#ifdef ENABLE_WRITE_INTR+ fip_issue_command(priv);+#endif+ }+ } else+ printk("Unknown IRQ %d\n", irq);+}++static void fip_poll_key(unsigned long devid)+{+ struct fip_private *priv = (struct fip_private *)devid;++ /* Sending command, and later ISR will pick up the interrupt and read+ the key */+ if (!is_fip_busy_nowait()) {+ fip_write_reg(FIP_COMMAND, FIP_CMD_DATA_SET_RW_MODE_READ_KEYS);+#ifdef ENABLE_WRITE_INTR+ if (priv->cmdq_empty != 0) {+ fip_issue_command(priv);+ }+#endif+ }++ if (priv->ref_cnt != 0) {+ mod_timer(&fip_timer, jiffies + (HZ / poll_per_sec));+#if 0+ queue_task(&immediate, &tq_immediate);+ mark_bh(IMMEDIATE_BH);+#endif+ }+}++/* Produce data */+static void fip_push_key(struct fip_private *priv, unsigned long key)+{+ unsigned pidx;+ static unsigned long oldkey = 0;++ spin_lock(&priv->lock);++ if ((key == 0) || (key == 0xffffffff)) {+ oldkey = 0;+ goto out;+ } else if (time_after(priv->last_jiffies + wait_period, jiffies) + && (key == oldkey))+ goto out;+ else+ priv->last_jiffies = jiffies;+ + printk(KERN_DEBUG "%s: got data 0x%08lx\n", fip_devname, key);++ pidx = priv->p_idx; /* Save the old index before proceeding */++ /* Save it to buffer */+ if (((priv->p_idx + 1) % buffer_size) == priv->c_idx) {+ /* Adjust consumer index since buffer is full */+ /* Keep the latest one and drop the oldest one */+ priv->c_idx = (priv->c_idx + 1) % buffer_size;++ printk(KERN_WARNING "%s: buffer full\n", fip_devname);+ }++ priv->buffer[priv->p_idx] = oldkey = key;+ priv->p_idx = (priv->p_idx + 1) % buffer_size;++ /* Buffer was empty and block mode is on, wake up the reader */+ if ((priv->b_mode != 0) && (priv->c_idx == pidx))+ wake_up_interruptible(&fip_wq);++out:+ spin_unlock(&priv->lock);+}++/* Reading from driver's buffer, note that it can return read size+ less than specified */+static int fip_consume(void *dev_id, unsigned long *buf, int count)+{+ struct fip_private *priv = (struct fip_private *)dev_id;+ int cnt;+ unsigned long flags;++ /* If block mode is on, check the emptiness of buffer */+ if (priv->b_mode != 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -