/*************************************************************************** * exit_zion_dmaif **************************************************************************/ void exit_zion_dmaif(void) { zion_params_t *zion_params; PINFO("Cleanup ZION DMAIF module ..."); /* get ZION parameters */ zion_params = find_zion (0); if (zion_params == NULL) { return; } /* Check Fireball */ if((zion_params->revision & 0xF000) == 0xF000) { return; } /* Disable backend interrupts */ mbus_writew(0, MBUS_ADDR(zion_params, ZION_MBUS_INTGEN_B)); /* INT Gen B Enable */ zion_disable_mbus_interrupt(zion_params, Dmaif_Int); mbus_writew(0, MBUS_ADDR(zion_params, ZION_MBUS_IOSEL)); /* DMA select */ free_zion_dmaif_private_space(ZION_DMAIF_PARAM (zion_params)); PINFO( "done.\n" ); return; }
void zion_audio_proc_event(zion_params_t *zion_params, int bit, int irq, void *dev_id, u16 pci_status) { u16 int_status_12; u16 int_status_34; /* Read Interrupt Status */ int_status_12 = mbus_readw(MBUS_ADDR(zion_params, DMA12_Interrupt_Status)); int_status_34 = mbus_readw(MBUS_ADDR(zion_params, DMA34_Interrupt_Status)); /* Memorize it ! */ zion_params->interrupt_bits.AUDIO_INT[0] |= int_status_12; zion_params->interrupt_bits.AUDIO_INT[1] |= int_status_34; /* Do Nothing Now... */ /* Clear them */ if(int_status_12) { mbus_writew(int_status_12, MBUS_ADDR(zion_params, DMA12_Interrupt_Clear)); } if(int_status_34) { mbus_writew(int_status_34, MBUS_ADDR(zion_params, DMA34_Interrupt_Clear)); } zion_mbus_int_clear(zion_params, AudioProc_Int); return; }
/*************************************************************************** * init_zion_dmaif **************************************************************************/ int init_zion_dmaif(void) { zion_params_t *zion_params; int ret, i; /* get ZION parameters */ zion_params = find_zion(0); if (zion_params == NULL) { return -ENODEV; } /* Check Fireball */ if((zion_params->revision & 0xF000) == 0xF000) { PINFO("This is fireball! ZION DMA IF cannot be used!!\n"); return 0; } /* register fuctions for operation */ for (i = 0; i < ZION_EDMA_PORT; i++) { zion_params->zion_operations[ZION_DMAIF + i] = &zion_dmaif_port_fops; } /* Set Private Data Area */ zion_params->zion_private[ZION_DMAIF] = kmalloc(sizeof(zion_dmaif_params_t), GFP_KERNEL); if (ZION_DMAIF_PARAM(zion_params) == NULL) { PERROR ("Can't get enough space for private data.\n"); return -ENOMEM; } initialize_zion_dmaif_private_space(ZION_DMAIF_PARAM (zion_params)); #ifndef NEO_DEBUG PINFO("ZION DMAIF(EDMA) module ver. %d.%d Installed.\n", DMAIF_MAJORVER, DMAIF_MINORVER); #else /* NEO_DEBUG */ PINFO("ZION DMAIF(EDMA) module ver. %d.%d-DEBUG Installed.\n", DMAIF_MAJORVER, DMAIF_MINORVER); #endif /* !NEO_DEBUG */ /* enable interruption */ mbus_writew(ZION_MBUS_DMASEL_ENB, MBUS_ADDR(zion_params, ZION_MBUS_IOSEL)); /* DMA select */ ret = zion_enable_mbus_interrupt(zion_params, Dmaif_Int, zion_dmaif_event); if (ret) { PERROR ("registering interruption failed.\n"); return -EINVAL; } mbus_writew(ZION_MBUS_INTGB_MPU1ENB, MBUS_ADDR(zion_params, ZION_MBUS_INTGEN_B)); /* INT Gen B Enable */ return 0; }
void debug_print_debugstts( zion_params_t *params, int ch, char *str ) { unsigned short extmode = 0; int itr = 0; for ( itr = 0; itr < 3; ++itr ) { /* Disable TestEn all channel */ mbus_writew( 0, MBUS_ADDR(params, ZION_MBUS_EDMA_EXT_MODE(itr)) ); } /* Test mode 2 */ mbus_writeb( 0x21, MBUS_ADDR(params, ZION_MBUS_EDMA_EXT_MODE(ch)+1) ); extmode = (unsigned short)mbus_readw( MBUS_ADDR(params, ZION_MBUS_EDMA_EXT_MODE(ch)) ); PDEBUG( "%sCH%d ExtMode mode 2: 0x%04X\n", str, ch, extmode ); /* Test mode 5 */ mbus_writeb( 0x51, MBUS_ADDR(params, ZION_MBUS_EDMA_EXT_MODE(ch)+1) ); extmode = (unsigned short)mbus_readw( MBUS_ADDR(params, ZION_MBUS_EDMA_EXT_MODE(ch)) ); PDEBUG( "%sCH%d ExtMode mode 5: 0x%04X\n", str, ch, extmode ); /* Test mode 6 */ mbus_writeb( 0x61, MBUS_ADDR(params, ZION_MBUS_EDMA_EXT_MODE(ch)+1) ); extmode = (unsigned short)mbus_readw( MBUS_ADDR(params, ZION_MBUS_EDMA_EXT_MODE(ch)) ); PDEBUG( "%sCH%d ExtMode mode 6: 0x%04X\n", str, ch, extmode ); }
static int zionvga_image_reflection(int frame) { u16 reg; zion_params_t *params = find_zion(0); if(params == NULL){ return -ENODEV; } reg = mbus_readw(MBUS_ADDR(params,ZIONVGA_VGA_SETTING)); if(frame==0) { reg &= ~(VGA_SEL); } else { reg |= VGA_SEL; } //reg |= (VGA_RSTR_EN|CSC_EN|TRS_ON); #if defined(CONFIG_P2PF_K240) || defined(CONFIG_P2PF_K202) || defined(CONFIG_P2PF_K246A) reg |= (CSC_EN); #else reg |= (CSC_EN|TRS_ON); //VGA_RSTR_EN is supporsed to be set by TX #endif //CONFIG_P2PF_K240 || CONFIG_P2PF_K246A mbus_writew(reg, MBUS_ADDR(params,ZIONVGA_VGA_SETTING)); //Just for assurance reg = mbus_readw(MBUS_ADDR(params,ZIONVGA_VGA_SETTING)); return 0; }
/*************************************************************************** * zion_edma_timeout * @func * Timedout function of ZION-NEO EDMA * @args * unsigned long *prms [in/out]: parameters of ZION driver * @return * void * @comment * static function * @author * H. Hoshino **************************************************************************/ static void zion_edma_timeout(unsigned long prms) { zion_params_t *params = (zion_params_t *)prms; int ch = 0; zion_edma_params_t *edma_prms = NULL; /* Check argument */ if (NULL == params) { PERROR("Invalid ZION parameters!\n"); return; } /* Print error message */ PERROR("Timedout occured!\n"); for (ch = 0; ch < ZION_EDMA_NR_CH; ++ch) { /* Get EDMA parameters */ edma_prms = &(ZION_DMAIF_PARAM(params)->port_params[ZION_EDMA_DMA_PORTNO(ch)]); /* Clear DMA command */ /* NOTE: Need not write 0 to DmaRun the case of SyncMode = 0 */ mbus_writew(0, MBUS_ADDR(params, ZION_MBUS_EDMA_DMACMD(ch))); /* Clear interrupt status: DMA done */ mbus_writew(ZION_MBUS_EDMA_DMADONEINT, MBUS_ADDR(params, ZION_MBUS_EDMA_INTCLR(ch))); /* Wake up */ edma_prms->condition = ZION_DMAIF_DISPATCH_TIMEOUT; wake_up(&(edma_prms->zion_dmaif_wait_queue)); } /* for DEBUG XXX */ debug_print_debugstts( params, 0, "" ); debug_print_debugstts( params, 2, "" ); debug_print_stts( params, 0, "" ); debug_print_stts( params, 1, "" ); debug_print_stts( params, 2, "" ); }
static int zionvga_init_phase(struct zionvga_phase_arg *phase) { zion_params_t *params = find_zion(0); unsigned short v_phase = phase->v_phase; unsigned short h_phase = phase->h_phase; if(params == NULL){ return -ENODEV; } mbus_writew(v_phase, MBUS_ADDR(params, ZIONVGA_VIDEO_V_PHASE)); mbus_writew(v_phase, MBUS_ADDR(params, ZIONVGA_SYSTEM_V_PHASE)); mbus_writew(h_phase, MBUS_ADDR(params, ZIONVGA_VIDEO_H_PHASE)); mbus_writew(h_phase, MBUS_ADDR(params, ZIONVGA_SYSTEM_H_PHASE)); // Just for Assurance v_phase = mbus_readw(MBUS_ADDR(params, ZIONVGA_VIDEO_V_PHASE)); v_phase = mbus_readw(MBUS_ADDR(params, ZIONVGA_SYSTEM_V_PHASE)); h_phase = mbus_readw(MBUS_ADDR(params, ZIONVGA_VIDEO_H_PHASE)); h_phase = mbus_readw(MBUS_ADDR(params, ZIONVGA_SYSTEM_H_PHASE)); return 0; }
static int zionvga_rstr_enable(void) { u16 reg; zion_params_t *params = find_zion(0); if(params == NULL){ return -ENODEV; } reg = mbus_readw(MBUS_ADDR(params,ZIONVGA_VGA_SETTING)); reg |= VGA_RSTR_EN; mbus_writew(reg, MBUS_ADDR(params,ZIONVGA_VGA_SETTING)); reg = mbus_readw(MBUS_ADDR(params,ZIONVGA_VGA_SETTING)); //Just for assurance return 0; }
/*************************************************************************** * zion_edma_set_region * @func * set EDMA buffer addresses * @args * zion_params_t *params [in]: parameters of ZION driver * int dma_ch [in]: channel * int num [in]: buffer number * unsigned long lower [in]: lower address * unsigned long upper [in]: upper address * @return * int * 0 : success * -EINVAL : invalid argument * @comment * static function * @author * H. Hoshino **************************************************************************/ static int zion_edma_set_region(zion_params_t * params, int dma_ch, int num, unsigned long lower, unsigned long upper) { unsigned short tlower = (unsigned short)( (lower&0x07FF0000L) >> 16 ); /* Check channel number */ if (dma_ch >= ZION_EDMA_NR_CH) { PERROR("Invalid EDMA Channel.\n"); return (-EINVAL); } /* for DEBUG */ PDEBUG( "[CH%d Buf%d] lower: 0x%08lX, tlower: 0x%04X, upper: 0x%08lX\n", dma_ch, num, lower, tlower, upper ); /* Set addresses */ mbus_writew(tlower, MBUS_ADDR(params, ZION_MBUS_EDMA_BUFF_LWR_ADRS(dma_ch, num))); mbus_writel(upper, MBUS_ADDR(params, ZION_MBUS_EDMA_BUFF_UPR_ADRS(dma_ch, num))); return (0); }
/*************************************************************************** * zion_dmaif_event * @func * Interruption handler for EDMA * @args * zion_params_t *params [in/out]: parameters of ZION driver * int irq [in] : IRQ number * void *dev_id [in] : Device ID * u16 pci_status[in] : PCI config interrupt status * @return * void * @comment * * @author * H. Hoshino **************************************************************************/ void zion_dmaif_event(zion_params_t * params, int bit, int irq, void *dev_id, u16 pci_status) { unsigned short int_status = 0; unsigned short int_mask = 0; int ch = 0; zion_edma_params_t *edma_prms = NULL; /*** Check EDMA interruption for each channel ***/ for (ch = 0; ch < ZION_EDMA_NR_CH; ++ch) { /* Get interrupt status and mask(enable) */ int_status = (unsigned short)mbus_readw( MBUS_ADDR(params, ZION_MBUS_EDMA_INTSTTS(ch)) ); int_mask = (unsigned short)mbus_readw( MBUS_ADDR(params, ZION_MBUS_EDMA_INTENB(ch)) ); /* Memorize it ! */ params->interrupt_bits.DMA_INT[ch] |= int_status; /* for DEBUG */ /* PDEBUG( "CH%d int_status: 0x%04X, mask: 0x%04X\n", */ /* ch, int_status, int_mask ); */ /** Check interruptions (Common port) **/ if ( int_status & int_mask ) { /* Get EDMA params */ edma_prms = &(ZION_DMAIF_PARAM(params)->port_params[ZION_EDMA_CMN_PORTNO(ch)]); /* for DEBUG */ /* PDEBUG( "[CH%d port%d] Get interruptions!\n", */ /* ch, ZION_EDMA_CMN_PORTNO(ch) ); */ if ( NULL == edma_prms ) { PERROR( "[CH%d port%d] EDMA params is NULL!!\n", ch, ZION_EDMA_CMN_PORTNO(ch) ); mbus_writew( (ZION_MBUS_EDMA_DMADONEINT | ZION_MBUS_EDMA_SYNCFRMINT | ZION_MBUS_EDMA_BUFFINT_MASK | ZION_MBUS_EDMA_ERRINT_MASK), MBUS_ADDR(params, ZION_MBUS_EDMA_INTCLR(ch))); /** Clear interrupt status INT B reg **/ zion_mbus_int_clear(params, Dmaif_Int); return; } /* Set interrupt status */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ edma_prms->int_status |= int_status; /* edma_prms->int_status = int_status; */ spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ /* Wake up */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ edma_prms->condition = ZION_DMAIF_DISPATCH_DONE; spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ wake_up(&(edma_prms->zion_dmaif_wait_queue)); } /** Check sync frame pulse interruption **/ if ( int_status & int_mask & ZION_MBUS_EDMA_SYNCFRMINT ) { /* Get EDMA params */ edma_prms = &(ZION_DMAIF_PARAM(params)->port_params[ZION_EDMA_FRM_PORTNO(ch)]); /* for DEBUG */ /* PDEBUG( "[CH%d port%d] Sync frame pulse!\n", */ /* ch, ZION_EDMA_FRM_PORTNO(ch) ); */ /* Set interrupt status */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ if ( 0 == edma_prms->int_status ) { edma_prms->int_status = int_status; } else { /* PDEBUG( "[CH%d port%d] int_status is already set(0x%04X, 0x%04X)!\n", */ /* ch, ZION_EDMA_DMA_PORTNO(ch), edma_prms->int_status, int_status ); */ } spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ /* Clear interrupt status: sync frame pulse */ mbus_writew(ZION_MBUS_EDMA_SYNCFRMINT, MBUS_ADDR(params, ZION_MBUS_EDMA_INTCLR(ch))); /* Wake up */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ edma_prms->condition = ZION_DMAIF_DISPATCH_DONE; spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ wake_up(&(edma_prms->zion_dmaif_wait_queue)); } /** Check DMA done interruption **/ if ( int_status & int_mask & ZION_MBUS_EDMA_DMADONEINT ) { /* Get EDMA params */ edma_prms = &(ZION_DMAIF_PARAM(params)->port_params[ZION_EDMA_DMA_PORTNO(ch)]); /* for DEBUG */ PDEBUG( "[CH%d port%d] DMA Done!\n", ch, ZION_EDMA_DMA_PORTNO(ch) ); /* PINFO( "[CH%d port%d] DMA Done!\n", */ /* ch, ZION_EDMA_DMA_PORTNO(ch) ); */ /* Stop DMA for G1&G2 transfer mode */ { unsigned char cmd = mbus_readb( MBUS_ADDR(params, (ZION_MBUS_EDMA_DMACMD(ch)+1)) ); mbus_writeb( (cmd & (~0x02)), MBUS_ADDR(params, (ZION_MBUS_EDMA_DMACMD(ch)+1)) ); } /* for DEBUG XXX*/ /* { */ /* unsigned short usPMT = mbus_readw( MBUS_ADDR(params, ZION_MBUS_EDMA_CURRPMT(ch)) ); */ /* PDEBUG( "[CH%d port%d] CurrPMT: 0x%04X\n", */ /* ch, ZION_EDMA_DMA_PORTNO(ch), usPMT ); */ /* } */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ /* Set interrupt status */ /* PDEBUG( "[CH%d] int_status: 0x%04X, old: 0x%04X!\n", */ /* ch, int_status, edma_prms->int_status ); */ if ( 0 == edma_prms->int_status ) { edma_prms->int_status = int_status; } else { /* PDEBUG( "[CH%d port%d] int_status is already set(0x%04X, 0x%04X)!\n", */ /* ch, ZION_EDMA_DMA_PORTNO(ch), edma_prms->int_status, int_status ); */ } /* Delete timer */ del_timer_sync(&(edma_prms->timer)); spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ /* Clear interrupt status: DMA done */ mbus_writew(ZION_MBUS_EDMA_DMADONEINT, MBUS_ADDR(params, ZION_MBUS_EDMA_INTCLR(ch))); /* Wake up */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ edma_prms->condition = ZION_DMAIF_DISPATCH_DONE; spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ wake_up(&(edma_prms->zion_dmaif_wait_queue)); } /** Check error and buffer empty/almost empty/almost full/full interruption **/ if ( int_status & int_mask & (ZION_MBUS_EDMA_BUFFINT_MASK | ZION_MBUS_EDMA_ERRINT_MASK) ) { /* Get EDMA parameters */ edma_prms = &(ZION_DMAIF_PARAM (params)->port_params[ZION_EDMA_BUF_PORTNO(ch)]); /* for DEBUG */ PDEBUG( "[CH%d port%d] Error or warning!\n", ch, ZION_EDMA_BUF_PORTNO(ch) ); /* Set interrupt status */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ /* PDEBUG( "[CH%d] int_status: 0x%04X, old: 0x%04X!\n", */ /* ch, int_status, edma_prms->int_status ); */ if ( 0 == edma_prms->int_status ) { edma_prms->int_status = int_status; } else { /* PDEBUG( "[CH%d port%d] int_status is already set(0x%04X, 0x%04X)!\n", */ /* ch, ZION_EDMA_BUF_PORTNO(ch), edma_prms->int_status, int_status ); */ } spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ /* Clear interrupt status */ mbus_writew((ZION_MBUS_EDMA_BUFFINT_MASK | ZION_MBUS_EDMA_ERRINT_MASK), MBUS_ADDR(params, ZION_MBUS_EDMA_INTCLR(ch))); /* Wake up */ spin_lock( &(edma_prms->params_lock) ); /* Spin lock */ edma_prms->condition = ZION_DMAIF_DISPATCH_DONE; spin_unlock( &(edma_prms->params_lock) ); /* Unlock spin lock */ wake_up(&(edma_prms->zion_dmaif_wait_queue)); } } /* The end of FOR(ch) */ /** Clear interrupt status INT B reg **/ zion_mbus_int_clear(params, Dmaif_Int); /* PDEBUG ("exit %s\n", __FUNCTION__); */ return; }
int zion_set_params(struct zionvga_reset_arg *reset_arg) { u16 reg = 0; int pal_line = reset_arg->pal_line; int spl_line = reset_arg->spl_line; zion_params_t *params = find_zion(0); if(params == NULL){ return -ENODEV; } reg = mbus_readw(MBUS_ADDR(params,ZIONVGA_VGA_SETTING)); reg &= VGA_RSTR_EN; //Don't touch VGA_RSTR_EN bit (It should be set by TX) if(pal_line==576) { reg |= PAL_LINE_SEL; ZIONVGA_Y_RES = 576; } else if(pal_line==480) { reg &= ~PAL_LINE_SEL; ZIONVGA_Y_RES = 480; } else { PERROR("Unsupported VGA SIZE : PAL-Line=%d",pal_line); return -EINVAL; } if(spl_line==720) { reg |= SPL_SEL; ZIONVGA_X_RES = 720; } else if(spl_line==640) { reg &= ~SPL_SEL; ZIONVGA_X_RES = 640; } else { PERROR("Unsupported VGA SIZE : SPL-Line=%d",spl_line); return -EINVAL; } #if defined(CONFIG_P2PF_K240) || defined(CONFIG_P2PF_K202) || defined(CONFIG_P2PF_K246A) reg |= (CSC_EN); #else reg |= (CSC_EN|TRS_ON); #endif //CONFIG_P2PF_K240 || CONFIG_P2PF_K246A mbus_writew(reg, MBUS_ADDR(params,ZIONVGA_VGA_SETTING)); // Just for assurance reg = mbus_readw(MBUS_ADDR(params,ZIONVGA_VGA_SETTING)); zionvga_encode_var( &default_var ); zion_fb_info.fb_info.var = default_var; return 0; }
static int zion_common_ioctl(zion_params_t *zion_params, struct inode *inode, struct file *filp, unsigned int function, unsigned long arg) { struct zion_config_byte zion_config_byte = {0}; struct zion_config_word zion_config_word = {0}; struct zion_config_dword zion_config_dword = {0}; struct zion_buf zion_buf; struct ZION_Interrupt_Bits zion_interrupt = {0}; u16 revision; switch(function) { case ZION_MBUS_READ_CONFIG_BYTE: if(copy_from_user((void *)&zion_config_byte, (void *)arg, sizeof(struct zion_config_byte))) return -EFAULT; zion_config_byte.val = (u8) mbus_readb( MBUS_ADDR(zion_params, zion_config_byte.where) ); if(copy_to_user((void *)arg, (void *)&zion_config_byte, sizeof(struct zion_config_byte))) return -EFAULT; break; case ZION_MBUS_READ_CONFIG_WORD: if(copy_from_user((void *)&zion_config_word, (void *)arg, sizeof(struct zion_config_word))) return -EFAULT; zion_config_word.val = (u16) mbus_readw( MBUS_ADDR(zion_params,zion_config_word.where) ); if(copy_to_user((void *)arg, (void *)&zion_config_word, sizeof(struct zion_config_word))) return -EFAULT; break; case ZION_MBUS_READ_CONFIG_DWORD: if(copy_from_user((void *)&zion_config_dword, (void *)arg, sizeof(struct zion_config_dword))) return -EFAULT; zion_config_dword.val = (u32) mbus_readl( MBUS_ADDR(zion_params,zion_config_dword.where) ); if(copy_to_user((void *)arg, (void *)&zion_config_dword, sizeof(struct zion_config_dword))) return -EFAULT; break; case ZION_MBUS_WRITE_CONFIG_BYTE: if(copy_from_user((void *)&zion_config_byte, (void *)arg, sizeof(struct zion_config_byte))) return -EFAULT; mbus_writeb(zion_config_byte.val, MBUS_ADDR(zion_params, zion_config_byte.where) ); if(copy_to_user((void *)arg, (void *)&zion_config_byte, sizeof(struct zion_config_byte))) return -EFAULT; break; case ZION_MBUS_WRITE_CONFIG_WORD: if(copy_from_user((void *)&zion_config_word, (void *)arg, sizeof(struct zion_config_word))) return -EFAULT; mbus_writew(zion_config_word.val, MBUS_ADDR(zion_params, zion_config_word.where) ); if(copy_to_user((void *)arg, (void *)&zion_config_word, sizeof(struct zion_config_word))) return -EFAULT; break; case ZION_MBUS_WRITE_CONFIG_DWORD: if(copy_from_user((void *)&zion_config_dword, (void *)arg, sizeof(struct zion_config_dword))) return -EFAULT; mbus_writel(zion_config_dword.val, MBUS_ADDR(zion_params, zion_config_dword.where) ); if(copy_to_user((void *)arg, (void *)&zion_config_dword, sizeof(struct zion_config_dword))) return -EFAULT; break; case ZION_WRAM_READ: if(copy_from_user((void *)&zion_buf, (void *)arg, sizeof(struct zion_buf))) return -EFAULT; if((zion_buf.size = neo_wram_pio_read(zion_params, zion_buf.addr, zion_buf.buf, zion_buf.size, zion_buf.access_type))==0) return -EINVAL; if(copy_to_user((void *)arg, (void *)&zion_buf, sizeof(struct zion_buf))) return -EFAULT; break; case ZION_WRAM_WRITE: if(copy_from_user((void *)&zion_buf, (void *)arg, sizeof(struct zion_buf))) return -EFAULT; if((zion_buf.size = neo_wram_pio_write(zion_params, zion_buf.addr, zion_buf.buf, zion_buf.size, zion_buf.access_type))==0) return -EINVAL; if(copy_to_user((void *)arg, (void *)&zion_buf, sizeof(struct zion_buf))) return -EFAULT; break; case ZION_WAIT_INTERRUPT: zion_goto_bed(zion_params, &zion_interrupt); /* zion_interrupt.c */ if(copy_to_user((void *)arg, (void *)&zion_interrupt, sizeof(struct ZION_Interrupt_Bits))) return -EFAULT; break; case ZION_WAKE_THREADS_UP: zion_rout_them_up(zion_params); /* zion_interrupt.c */ break; case ZION_SET_ENABLE_BITS: if(copy_from_user((void *)&zion_interrupt, (void *)arg, sizeof(struct ZION_Interrupt_Bits))) return -EFAULT; zion_set_enable_bits(zion_params, &zion_interrupt); /* zion_interrupt.c */ break; case ZION_GET_ENABLE_BITS: zion_get_enable_bits(zion_params, &zion_interrupt); /* zion_interrupt.c */ if(copy_to_user((void *)arg, (void *)&zion_interrupt, sizeof(struct ZION_Interrupt_Bits))) return -EFAULT; break; case ZION_SET_TIMEOUT: zion_params->wait_timeout = arg; /* by jiffies */ break; case ZION_GET_REVISION: revision = zion_params->revision; if(copy_to_user((void *)arg, (void *)&revision, sizeof(u16))) { return -EFAULT; } break; default: PERROR("No such IOCTL.\n"); return -EINVAL; } return 0; }