static int bfin_lq035_fb_open(struct fb_info *info, int user) { unsigned long flags; spin_lock_irqsave(&bfin_lq035_lock, flags); lq035_open_cnt++; spin_unlock_irqrestore(&bfin_lq035_lock, flags); if (lq035_open_cnt <= 1) { bfin_write_PPI_CONTROL(0); SSYNC(); set_vcomm(); config_dma(); config_ppi(); /* start dma */ enable_dma(CH_PPI); SSYNC(); bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() | PORT_EN); SSYNC(); if (!t_conf_done) { config_timers(); start_timers(); } /* gpio_set_value(MOD,1); */ } return 0; }
static int __init ppi_adc_init(void) { int ret; ret = dma_init(); if(ret) { return ret; } ret = ppi_init(); if(ret) { dma_close(); return ret; } ret = device_init(); if(ret) { ppi_close(); dma_close(); return ret; } /* Disable everything */ disable_dma(CH_PPI); bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() & (~PORT_EN)); SSYNC(); return 0; }
static int ppi_chr_release(struct inode* i, struct file* filp) { /* Disable PPI */ bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() & (~PORT_EN)); /* Disable DMA */ disable_dma(CH_PPI); return 0; }
static int ppi_chr_open(struct inode* i, struct file* filp) { /* Reset global values */ current_buffer_index = 0; current_buffer_pointer = 0; /* Enable DMA */ enable_dma(CH_PPI); /* Enable PPI */ bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() | PORT_EN); return 0; }
/* * FUNCTION NAME: ppi_read * * INPUTS/OUTPUTS: * in_filp - Description of openned file. * in_count - how many bytes user wants to get. * out_buf - data would be write to this address. * * RETURN * positive number: bytes read back * -EINVIL When word size is set to 16, reading odd bytes. * -EAGAIN When reading mode is set to non block and there is no rx data. * * FUNCTION(S) CALLED: * * GLOBAL VARIABLES REFERENCED: ppiinfo * * GLOBAL VARIABLES MODIFIED: NIL * * DESCRIPTION: It is invoked when user call 'read' system call * to read from system. * * CAUTION: */ static ssize_t ppi_read(struct file *filp, char *buf, size_t count, loff_t * pos) { int ierr; ppi_device_t *pdev = filp->private_data; pr_debug("ppi_read:\n"); if (count <= 0) return 0; pdev->done = 0; /* Invalidate allocated memory in Data Cache */ blackfin_dcache_invalidate_range((u_long) buf, (u_long) (buf + count)); pr_debug("ppi_read: blackfin_dcache_invalidate_range : DONE\n"); /* configure ppi port for DMA RX */ set_dma_config(CH_PPI, pdev->dma_config); set_dma_start_addr(CH_PPI, (u_long) buf); set_dma_x_count(CH_PPI, pdev->pixel_per_line / 2); // Div 2 because of 16-bit packing set_dma_y_count(CH_PPI, pdev->lines_per_frame); set_dma_y_modify(CH_PPI, 2); if (pdev->bpp > 8 || pdev->dma_config & WDSIZE_16) set_dma_x_modify(CH_PPI, 2); else set_dma_x_modify(CH_PPI, 1); pr_debug("ppi_read: SETUP DMA : DONE\n"); enable_dma(CH_PPI); /* Enable PPI */ bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() | PORT_EN); SSYNC(); if (pdev->ppi_trigger_gpio > NO_TRIGGER) { gpio_set_value(pdev->ppi_trigger_gpio, 1); udelay(1); gpio_set_value(pdev->ppi_trigger_gpio, 0); } pr_debug("ppi_read: PPI ENABLED : DONE\n"); /* Wait for data available */ if (1) { if (pdev->nonblock) return -EAGAIN; else { pr_debug("PPI wait_event_interruptible\n"); ierr = wait_event_interruptible(*(pdev->rx_avail), pdev->done); if (ierr) { /* waiting is broken by a signal */ pr_debug("PPI wait_event_interruptible ierr\n"); return ierr; } } } pr_debug("PPI wait_event_interruptible done\n"); disable_dma(CH_PPI); pr_debug("ppi_read: return\n"); return count; }