⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bfin_ppifcd.c

📁 This is the source code of Camera driver for OV2640 camera from OmniVision using in Blackfin platfor
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * File:         drivers/char/bfin_ppifcd.c * Based on: * Author:       Michael Hennerich * * Created:      Sept. 10th 2004 * Description:  Simple PPI Frame Capture driver for ADSP-BF5xx * * Rev:          $Id: bfin_ppifcd.c 4091 2008-01-10 14:17:04Z hennerich $ * * Modified: *               Copyright 2004-2008 Analog Devices Inc. * * Bugs:         Enter bugs at http://blackfin.uclinux.org/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see the file COPYING, or write * to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */#include <linux/kernel.h>#include <linux/module.h>#include <linux/sched.h>#include <linux/wait.h>#include <linux/poll.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/string.h>#include <linux/spinlock.h>#include <linux/delay.h>#include <linux/miscdevice.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/blackfin.h>#include <asm/dma.h>#include <asm/cacheflush.h>#include <asm/portmux.h>#include <asm/gpio.h>#include "bfin_ppifcd.h"/************************************************************//* manual fix for use this driver with BF561 (2 PPI) */#ifdef _CDEF_BF561_H#ifdef CH_PPI#undef CH_PPI#endif#define CAM_2		// use 1 for CAM_1 on EXT board, use 2 for CAM_2 on EXT board, currently just support 1 CAM at once#ifdef CAM_1/* Parallel Peripheral Interface (PPI) 0 registers (0xFFC0 1000-0xFFC0 10FF) */#define CH_PPI (CH_PPI0)		//mach-bf561/dma.h#define bfin_read_PPI_CONTROL()				bfin_read_PPI0_CONTROL()#define bfin_write_PPI_CONTROL(val)			bfin_write_PPI0_CONTROL(val)#define bfin_read_PPI_STATUS()				bfin_read_PPI0_STATUS()#define bfin_write_PPI_STATUS(val)			bfin_write_PPI0_STATUS(val)#define bfin_clear_PPI_STATUS()				bfin_clear_PPI0_STATUS()#define bfin_read_PPI_COUNT()				bfin_read_PPI0_COUNT()#define bfin_write_PPI_COUNT(val)			bfin_write_PPI0_COUNT(val)#define bfin_read_PPI_DELAY()				bfin_read_PPI0_DELAY()#define bfin_write_PPI_DELAY(val)			bfin_write_PPI0_DELAY(val)#define bfin_read_PPI_FRAME()				bfin_read_PPI0_FRAME()#define bfin_write_PPI_FRAME(val)			bfin_write_PPI0_FRAME(val)u16 ppifcd_ppi_req[] = {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, P_PPI0_D0,\	 P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, P_PPI0_D4, P_PPI0_D5, P_PPI0_D6,\	 P_PPI0_D7, 0};#endif#ifdef CAM_2/* Parallel Peripheral Interface (PPI) 1 registers (0xFFC0 1300-0xFFC0 13FF) */#define CH_PPI (CH_PPI1)		//mach-bf561/dma.h#define bfin_read_PPI_CONTROL()				bfin_read_PPI1_CONTROL()#define bfin_write_PPI_CONTROL(val)			bfin_write_PPI1_CONTROL(val)#define bfin_read_PPI_STATUS()				bfin_read_PPI1_STATUS()#define bfin_write_PPI_STATUS(val)			bfin_write_PPI1_STATUS(val)#define bfin_clear_PPI_STATUS()				bfin_clear_PPI1_STATUS()#define bfin_read_PPI_COUNT()				bfin_read_PPI1_COUNT()#define bfin_write_PPI_COUNT(val)			bfin_write_PPI1_COUNT(val)#define bfin_read_PPI_DELAY()				bfin_read_PPI1_DELAY()#define bfin_write_PPI_DELAY(val)			bfin_write_PPI1_DELAY(val)#define bfin_read_PPI_FRAME()				bfin_read_PPI1_FRAME()#define bfin_write_PPI_FRAME(val)			bfin_write_PPI1_FRAME(val)u16 ppifcd_ppi_req[] = {P_PPI1_CLK, P_PPI1_FS1, P_PPI1_FS2, P_PPI1_D0,\	 P_PPI1_D1, P_PPI1_D2, P_PPI1_D3, P_PPI1_D4, P_PPI1_D5, P_PPI1_D6,\	 P_PPI1_D7, 0};#endif#elseu16 ppifcd_ppi_req[] = {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, P_PPI0_D0,\	 P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, P_PPI0_D4, P_PPI0_D5, P_PPI0_D6,\	 P_PPI0_D7, 0};#endif/************************************************************//* definitions */#define PPI1_MINOR         248#define PPI_DEVNAME       "PPIFCP"#define PPI_INTNAME       "PPI-FCP-INT"	/* Should be less than 19 chars. *//************************************************************/typedef struct PPI_Device_t {	int opened;	int nonblock;	unsigned short irqnum;	unsigned short done;	unsigned short dma_config;	unsigned short pixel_per_line;	unsigned short lines_per_frame;	unsigned short bpp;	unsigned short ppi_control;	unsigned short ppi_status;	unsigned short ppi_delay;	short ppi_trigger_gpio;	struct fasync_struct *fasyc;	wait_queue_head_t *rx_avail;} ppi_device_t;/************************************************************//* Globals */static DECLARE_WAIT_QUEUE_HEAD(ppirxq0);static ppi_device_t ppiinfo;static DEFINE_SPINLOCK(ppifcd_lock);/* * FUNCTION NAME: ppifcd_reg_reset * * INPUTS/OUTPUTS: * in_idev - device number , other unavailable. * VALUE RETURNED: * void * * FUNCTION(S) CALLED: * * GLOBAL VARIABLES REFERENCED: * * GLOBAL VARIABLES MODIFIED: NIL * * DESCRIPTION: Reset PPI to initialization state. * * CAUTION: */void ppifcd_reg_reset(ppi_device_t *pdev){/* Do some initializaion stuff here based on the defined Camera Module   so we don't have to use ioctls                     */	bfin_clear_PPI_STATUS();	bfin_write_PPI_CONTROL(pdev->ppi_control & ~PORT_EN);	bfin_write_PPI_DELAY(pdev->ppi_delay);	bfin_write_PPI_COUNT(pdev->pixel_per_line - 1);	bfin_write_PPI_FRAME(pdev->lines_per_frame);	return;}/* * FUNCTION NAME: ppifcd_irq * * INPUTS/OUTPUTS: * in_irq - Interrupt vector number. * in_dev_id  - point to device information structure base address. * in_regs - unuse here. * * VALUE RETURNED: * void * * FUNCTION(S) CALLED: * * GLOBAL VARIABLES REFERENCED: ppiinfo * * GLOBAL VARIABLES MODIFIED: NIL * * DESCRIPTION: ISR of PPI * * CAUTION: */static irqreturn_t ppifcd_irq(int irq, void *dev_id, struct pt_regs *regs){	ppi_device_t *pdev = (ppi_device_t *) dev_id;//printk(KERN_INFO "PPIFCD_irg: Interrupt triggered\n");	pr_debug("ppifcd_irq:\n");//printk(KERN_INFO "PPIFCD_irg: Acknowledge DMA Interrupt (clear DMA interrupt state)\n");	/* Acknowledge DMA Interrupt */	clear_dma_irqstat(CH_PPI);	/* disable ppi *///printk(KERN_INFO "PPIFCD_irg: Disable PPI\n");	bfin_write_PPI_CONTROL(pdev->ppi_control & ~PORT_EN);//printk(KERN_INFO "PPIFCD_irg: Set DONE flag\n");	pdev->done = 1;	/* Give a signal to user program. *///printk(KERN_INFO "PPIFCD_irg: Give a signal to user program (fasyc)\n");	if (pdev->fasyc)		kill_fasync(&(pdev->fasyc), SIGIO, POLLIN);//printk(KERN_INFO "PPIFCD_irg: wake_up_interruptible pdev->done=%d\n", pdev->done);	pr_debug("ppifcd_irq: wake_up_interruptible pdev->done=%d\n",		pdev->done);	/* wake up read *///printk(KERN_INFO "PPIFCD_irg: wake up read\n");	wake_up_interruptible(pdev->rx_avail);//printk(KERN_INFO "PPIFCD_irg: Return\n");	pr_debug("ppifcd_irq: return\n");	return IRQ_HANDLED;}static irqreturn_t ppifcd_irq_error(int irq, void *dev_id, struct pt_regs *regs){	ppi_device_t *pdev = (ppi_device_t *) dev_id;//printk(KERN_ERR "PPIFCD_error_irq: DMA data transfer ERROR, irq_error triggered\n");	pr_debug("ppifcd_error_irq:\n");	pr_debug("PPI Status = 0x%X\n", bfin_read_PPI_STATUS());	bfin_clear_PPI_STATUS();	/* Acknowledge DMA Interrupt */	clear_dma_irqstat(CH_PPI);	/* disable ppi */	bfin_write_PPI_CONTROL(pdev->ppi_control & ~PORT_EN);	pdev->done = 1;	/* Give a signal to user program. */	if (pdev->fasyc)		kill_fasync(&(pdev->fasyc), SIGIO, POLLIN);	pr_debug("ppifcd_error_irq: wake_up_interruptible pdev->done=%d\n",		pdev->done);	/* wake up read */	wake_up_interruptible(pdev->rx_avail);	pr_debug("ppifcd_error_irq: return\n");	return IRQ_HANDLED;}/* * FUNCTION NAME: ppi_ioctl * * INPUTS/OUTPUTS: * in_inode - Description of openned file. * in_filp - Description of openned file. * in_cmd - Command passed into ioctl system call. * in/out_arg - It is parameters which is specified by last command * * RETURN: * 0 OK * -EINVAL  Invalid * * FUNCTION(S) CALLED: * * GLOBAL VARIABLES REFERENCED: ppiinfo * * GLOBAL VARIABLES MODIFIED: NIL * * DESCRIPTION: * * CAUTION: */static int ppi_ioctl(struct inode *inode, struct file *filp, uint cmd,		     unsigned long arg){	u_long value;	ppi_device_t *pdev = filp->private_data;	switch (cmd) {	case CMD_PPI_SET_PIXELS_PER_LINE:		{//printk(KERN_INFO "PPI_ioctl: CMD_PPI_SET_PIXELS_PER_LINE %d\n", (unsigned short)arg);			pr_debug("ppi_ioctl: CMD_PPI_SET_PIXELS_PER_LINE\n");			pdev->pixel_per_line = (unsigned short)arg;			bfin_write_PPI_COUNT(pdev->pixel_per_line - 1);			break;		}	case CMD_PPI_SET_LINES_PER_FRAME:		{//printk(KERN_INFO "PPI_ioctl: CMD_PPI_SET_LINES_PER_FRAME %d\n", (unsigned short)arg);			pr_debug("ppi_ioctl: CMD_PPI_SET_LINES_PER_FRAME\n");			pdev->lines_per_frame = (unsigned short)arg;			bfin_write_PPI_FRAME(pdev->lines_per_frame);			break;		}	case CMD_PPI_SET_PPICONTROL_REG:		{//printk(KERN_INFO "PPI_ioctl: CMD_PPI_SET_PPICONTROL_REG 0x%x\n", (unsigned short)arg);			pr_debug("ppi_ioctl: CMD_PPI_SET_PPICONTROL_REG\n");			pdev->ppi_control = ((unsigned short)arg) & ~PORT_EN;			bfin_write_PPI_CONTROL(pdev->ppi_control);			break;		}	case CMD_PPI_SET_PPIDELAY_REG:		{//printk(KERN_INFO "PPI_ioctl: CMD_PPI_SET_PPIDELAY_REG %d\n", (unsigned short)arg);			pr_debug("ppi_ioctl: CMD_PPI_SET_PPIDELAY_REG\n");			pdev->ppi_delay = (unsigned short)arg;			bfin_write_PPI_DELAY(pdev->ppi_delay);			break;		}	case CMD_SET_TRIGGER_GPIO:		{//printk(KERN_INFO "PPI_ioctl: CMD_SET_TRIGGER_GPIO %d\n", (unsigned short)arg);			pr_debug("ppi_ioctl: CMD_SET_TRIGGER_GPIO\n");			pdev->ppi_trigger_gpio = (unsigned short)arg;			if (pdev->ppi_trigger_gpio == NO_TRIGGER) {				break;			}			if (gpio_request(pdev->ppi_trigger_gpio, PPI_DEVNAME)) {				printk(KERN_ERR"Requesting GPIO %d faild\n",						pdev->ppi_trigger_gpio);				return -EFAULT;			}			gpio_direction_output(pdev->ppi_trigger_gpio, 0);			break;		}	case CMD_PPI_GET_ALLCONFIG:		{//printk(KERN_INFO "PPI_ioctl: CMD_PPI_GET_ALLCONFIG (Fix me)\n");			break;		}	case CMD_PPI_GET_SYSTEMCLOCK:		{			value = get_sclk();//printk(KERN_INFO "PPI_ioctl: CMD_PPI_GET_SYSTEMCLOCK SCLK: %d\n", (int)value);			pr_debug			    ("ppi_ioctl: CMD_PPI_GET_SYSTEMCLOCK SCLK: %d \n",			     (int)value);			copy_to_user((unsigned long *)arg, &value,				     sizeof(unsigned long));			break;		}	default:		return -EINVAL;	}	return 0;}/* * FUNCTION NAME: ppi_fasync *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -