//extern struct file_operations vfd_fops; static int __init nuvoton_init_module(void) { int i = 0; int result; // Address for Interrupt enable/disable unsigned int *ASC_X_INT_EN = (unsigned int*)(ASCXBaseAddress + ASC_INT_EN); // Address for FiFo enable/disable unsigned int *ASC_X_CTRL = (unsigned int*)(ASCXBaseAddress + ASC_CTRL); dprintk(5, "%s >\n", __func__); //Disable all ASC 2 interrupts *ASC_X_INT_EN = *ASC_X_INT_EN & ~0x000001ff; serial_init(); init_waitqueue_head(&wq); init_waitqueue_head(&rx_wq); init_waitqueue_head(&ack_wq); for (i = 0; i < LASTMINOR; i++) sema_init(&FrontPanelOpen[i].sem, 1); kernel_thread(nuvotonTask, NULL, 0); //Enable the FIFO *ASC_X_CTRL = *ASC_X_CTRL | ASC_CTRL_FIFO_EN; #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17) i = request_irq(InterruptLine, (void*)FP_interrupt, IRQF_DISABLED, "FP_serial", NULL); #else i = request_irq(InterruptLine, (void*)FP_interrupt, SA_INTERRUPT, "FP_serial", NULL); #endif if (!i) *ASC_X_INT_EN = *ASC_X_INT_EN | 0x00000001; else printk("FP: Can't get irq\n"); msleep(1000); nuvoton_init_func(); //if (register_chrdev(VFD_MAJOR, "VFD", &vfd_fops)) // printk("unable to get major %d for VFD/NUVOTON\n",VFD_MAJOR); vfd_dev_num = MKDEV(VFD_MAJOR, 0); result = register_chrdev_region(vfd_dev_num, LASTMINOR, DEVICE_NAME); if (result < 0) { printk( KERN_ALERT "VFD cannot register device (%d)\n", result); return result; } cdev_init(&vfd_cdev, &vfd_fops); vfd_cdev.owner = THIS_MODULE; vfd_cdev.ops = &vfd_fops; if (cdev_add(&vfd_cdev, vfd_dev_num, LASTMINOR) < 0) { printk("VFD couldn't register '%s' driver\n", DEVICE_NAME); return -1; } vfd_class = class_create(THIS_MODULE, DEVICE_NAME); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) device_create(vfd_class, NULL, MKDEV(VFD_MAJOR, 0), NULL, "vfd", 0); device_create(vfd_class, NULL, MKDEV(VFD_MAJOR, 1), NULL, "rc", 1); #else class_device_create(vfd_class, NULL, MKDEV(VFD_MAJOR, 0), NULL, "vfd", 0); class_device_create(vfd_class, NULL, MKDEV(VFD_MAJOR, 1), NULL, "rc", 1); #endif dprintk(10, "%s < %d\n", __func__, result); return result; }
static int NUVOTONdev_ioctl(struct inode *Inode, struct file *File, unsigned int cmd, unsigned long arg) { static int mode = 0; struct nuvoton_ioctl_data * nuvoton = (struct nuvoton_ioctl_data *)arg; int res = 0; dprintk(100, "%s > 0x%.8x\n", __func__, cmd); if(down_interruptible (&write_sem)) return -ERESTARTSYS; switch(cmd) { case VFDSETMODE: mode = nuvoton->u.mode.compat; break; case VFDSETLED: res = nuvotonSetLED(nuvoton->u.led.led_nr, nuvoton->u.led.on); break; case VFDBRIGHTNESS: if (mode == 0) { struct vfd_ioctl_data *data = (struct vfd_ioctl_data *) arg; res = nuvotonSetBrightness(data->start_address); } else { res = nuvotonSetBrightness(nuvoton->u.brightness.level); } mode = 0; break; case VFDPWRLED: if (mode == 0) { struct vfd_ioctl_data *data = (struct vfd_ioctl_data *) arg; res = nuvotonSetPwrLed(data->start_address); } else { res = nuvotonSetPwrLed(nuvoton->u.pwrled.level); } mode = 0; break; case VFDDRIVERINIT: res = nuvoton_init_func(); mode = 0; break; case VFDICONDISPLAYONOFF: #ifndef ATEVIO7500 if (mode == 0) { struct vfd_ioctl_data *data = (struct vfd_ioctl_data *) arg; int icon_nr = (data->data[0] & 0xf) + 1; int on = data->data[4]; res = nuvotonSetIcon(icon_nr, on); } else { res = nuvotonSetIcon(nuvoton->u.icon.icon_nr, nuvoton->u.icon.on); } #else res = 0; #endif mode = 0; break; case VFDSTANDBY: res = nuvotonSetStandby(nuvoton->u.standby.time); break; case VFDSETTIME: if (nuvoton->u.time.time != 0) res = nuvotonSetTime(nuvoton->u.time.time); break; case VFDGETTIME: res = nuvotonGetTime(); copy_to_user(arg, &ioctl_data, 5); break; case VFDGETWAKEUPMODE: res = nuvotonGetWakeUpMode(); copy_to_user(arg, &ioctl_data, 1); break; case VFDDISPLAYCHARS: if (mode == 0) { struct vfd_ioctl_data *data = (struct vfd_ioctl_data *) arg; res = nuvotonWriteString(data->data, data->length); } else { //not suppoerted } mode = 0; break; case VFDDISPLAYWRITEONOFF: /* ->alles abschalten ? VFD_Display_Write_On_Off */ printk("VFDDISPLAYWRITEONOFF ->not yet implemented\n"); break; case 0x5401: mode = 0; break; default: printk("VFD/Nuvoton: unknown IOCTL 0x%x\n", cmd); mode = 0; break; } up(&write_sem); dprintk(100, "%s <\n", __func__); return res; }