You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Staging: add dt3155 driver
This is a driver for the DT3155 Digitizer Signed-off-by: Scott Smedley <ss@aao.gov.au> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
da94a755ca
commit
aa337ef1fb
@@ -0,0 +1,27 @@
|
||||
|
||||
ifeq ($(shell [[ `uname -r | cut -f 1,2 -d\.` < 2.6 ]] && echo pre2.6),pre2.6)
|
||||
# system with a pre 2.6 kernel _don't_ use kbuild.
|
||||
all:
|
||||
$(MAKE) -f Makefile.pre-2.6
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
|
||||
else
|
||||
# systems with a 2.6 or later kernel use kbuild.
|
||||
ifneq ($(KERNELRELEASE),)
|
||||
obj-m := dt3155.o
|
||||
dt3155-objs := dt3155_drv.o dt3155_isr.o dt3155_io.o allocator.o
|
||||
|
||||
else
|
||||
KDIR := /lib/modules/$(shell uname -r)/build
|
||||
PWD := $(shell pwd)
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KDIR) M=$(PWD) modules
|
||||
|
||||
clean:
|
||||
rm -rf *.o *.mod *.mod.c *.ko .dt3155* .allocator.o.cmd .tmp_versions
|
||||
|
||||
endif
|
||||
endif
|
||||
@@ -0,0 +1,98 @@
|
||||
|
||||
The allocator shown here exploits high memory. This document explains
|
||||
how a user can deal with drivers uses this allocator and how a
|
||||
programmer can link in the module.
|
||||
|
||||
The module is being used by my pxc and pxdrv device drivers (as well as
|
||||
other ones), available from ftp.systemy.it/pub/develop and
|
||||
ftp.linux.it/pub/People/Rubini
|
||||
|
||||
User's manual
|
||||
=============
|
||||
|
||||
|
||||
One of the most compelling problems with any DMA-capable device is the
|
||||
allocation of a suitable memory buffer. The "allocator" module tries
|
||||
to deal with the problem in a clean way. The module is able to use
|
||||
high memory (above the one used in normal operation) for DMA
|
||||
allocation.
|
||||
|
||||
To prevent the kernel for using high memory, so that it remains
|
||||
available for DMA, you should pass a command line argument to the
|
||||
kernel. Command line arguments can be passed to Lilo, to Loadlin or
|
||||
to whichever loader you are using (unless it's very poor in design).
|
||||
For Lilo, either use "append=" in /etc/lilo.conf or add commandline
|
||||
arguments to the interactive prompt. For example, I have a 32MB box
|
||||
and reserve two megs for DMA:
|
||||
|
||||
In lilo.conf:
|
||||
image = /zImage
|
||||
label = linux
|
||||
append = "mem=30M"
|
||||
|
||||
Or, interactively:
|
||||
LILO: linux mem=30M
|
||||
|
||||
Once the kernel is booted with the right command-line argument, any
|
||||
driver linked with the allocator module will be able to get
|
||||
DMA-capable memory without much trouble (unless the various drivers
|
||||
need more memory than available).
|
||||
|
||||
The module implements an alloc/free mechanism, so that it can serve
|
||||
multiple drivers at the same time. Note however that the allocator
|
||||
uses all of high memory and assumes to be the only piece of software
|
||||
using such memory.
|
||||
|
||||
|
||||
Programmer's manual
|
||||
===================
|
||||
|
||||
The allocator, as released, is designed to be linked to a device
|
||||
driver. In this case, the driver must call allocator_init() before
|
||||
using the allocator and must call allocator_cleanup() before
|
||||
unloading. This is usually done from within init_module() and
|
||||
cleanup_module(). If the allocator is linked to a driver, it won't be
|
||||
possible for several drivers to allocate high DMA memory, as explained
|
||||
above.
|
||||
|
||||
It is possible, on the other hand, to compile the module as a standalone
|
||||
module, so that several modules can rely on the allocator for they DMA
|
||||
buffers. To compile the allocator as a standalone module, do the
|
||||
following in this directory (or provide a suitable Makefile, or edit
|
||||
the source code):
|
||||
|
||||
make allocator.o CC="gcc -Dallocator_init=init_module -Dallocator_cleanup=cleanup_module -include /usr/include/linux/module.h"
|
||||
|
||||
The previous commandline tells to include <linux/module.h> in the
|
||||
first place, and to rename the init and cleanup function to the ones
|
||||
needed for module loading and unloading. Drivers using a standalone
|
||||
allocator won't need to call allocator_init() nor allocator_cleanup().
|
||||
|
||||
The allocator exports the following functions (declared in allocator.h):
|
||||
|
||||
unsigned long allocator_allocate_dma (unsigned long kilobytes,
|
||||
int priority);
|
||||
|
||||
This function returns a physical address, over high_memory,
|
||||
which corresponds to an area of at least "kilobytes" kilobytes.
|
||||
The area will be owned by the module calling the function.
|
||||
The returned address can be passed to device boards, to instruct
|
||||
their DMA controllers, via phys_to_bus(). The address can be used
|
||||
by C code after vremap()/ioremap(). The "priority" argument should
|
||||
be GFP_KERNEL or GFP_ATOMIC, according to the context of the
|
||||
caller; it is used to call kmalloc(), as the allocator must keep
|
||||
track of any region it gives away. In case of error the function
|
||||
returns 0, and the caller is expected to issue a -ENOMEM error.
|
||||
|
||||
|
||||
void allocator_free_dma (unsigned long address);
|
||||
|
||||
This function is the reverse of the previous one. If a driver
|
||||
doesn't free the DMA memory it allocated, the allocator will
|
||||
consider such memory as busy. Note, however, that
|
||||
allocator_cleanup() calls kfree() on every region it reclaimed,
|
||||
so that a driver with the allocator linked in can avoid calling
|
||||
allocator_free_dma() at unload time.
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* allocator.c -- allocate after high_memory, if available
|
||||
*
|
||||
* NOTE: this is different from my previous allocator, the one that
|
||||
* assembles pages, which revealed itself both slow and unreliable.
|
||||
*
|
||||
* Copyright (C) 1998 rubini@linux.it (Alessandro Rubini)
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
|
||||
-- Changes --
|
||||
|
||||
Date Programmer Description of changes made
|
||||
-------------------------------------------------------------------
|
||||
02-Aug-2002 NJC allocator now steps in 1MB increments, rather
|
||||
than doubling its size each time.
|
||||
Also, allocator_init(u_int *) now returns
|
||||
(in the first arg) the size of the free
|
||||
space. This is no longer consistent with
|
||||
using the allocator as a module, and some changes
|
||||
may be necessary for that purpose. This was
|
||||
designed to work with the DT3155 driver, in
|
||||
stand alone mode only!!!
|
||||
26-Oct-2009 SS Port to 2.6.30 kernel.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __KERNEL__
|
||||
# define __KERNEL__
|
||||
#endif
|
||||
#ifndef MODULE
|
||||
# define MODULE
|
||||
#endif
|
||||
|
||||
#include <linux/version.h>
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/mm.h> /* PAGE_ALIGN() */
|
||||
|
||||
#include <asm/page.h>
|
||||
|
||||
#include "sysdep.h"
|
||||
|
||||
/*#define ALL_DEBUG*/
|
||||
#define ALL_MSG "allocator: "
|
||||
|
||||
#undef PDEBUG /* undef it, just in case */
|
||||
#ifdef ALL_DEBUG
|
||||
# define __static
|
||||
# define DUMP_LIST() dump_list()
|
||||
# ifdef __KERNEL__
|
||||
/* This one if debugging is on, and kernel space */
|
||||
# define PDEBUG(fmt, args...) printk( KERN_DEBUG ALL_MSG fmt, ## args)
|
||||
# else
|
||||
/* This one for user space */
|
||||
# define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
|
||||
# endif
|
||||
#else
|
||||
# define PDEBUG(fmt, args...) /* not debugging: nothing */
|
||||
# define DUMP_LIST()
|
||||
# define __static static
|
||||
#endif
|
||||
|
||||
#undef PDEBUGG
|
||||
#define PDEBUGG(fmt, args...)
|
||||
/*#define PDEBUGG(fmt, args...) printk( KERN_DEBUG ALL_MSG fmt, ## args)*/
|
||||
|
||||
|
||||
int allocator_himem = 1; /* 0 = probe, pos. = megs, neg. = disable */
|
||||
int allocator_step = 1; /* This is the step size in MB */
|
||||
int allocator_probe = 1; /* This is a flag -- 1=probe, 0=don't probe */
|
||||
|
||||
static unsigned long allocator_buffer = 0; /* physical address */
|
||||
static unsigned long allocator_buffer_size = 0; /* kilobytes */
|
||||
|
||||
/*
|
||||
* The allocator keeps a list of DMA areas, so multiple devices
|
||||
* can coexist. The list is kept sorted by address
|
||||
*/
|
||||
|
||||
struct allocator_struct {
|
||||
unsigned long address;
|
||||
unsigned long size;
|
||||
struct allocator_struct *next;
|
||||
};
|
||||
|
||||
struct allocator_struct *allocator_list = NULL;
|
||||
|
||||
|
||||
#ifdef ALL_DEBUG
|
||||
static int dump_list(void)
|
||||
{
|
||||
struct allocator_struct *ptr;
|
||||
|
||||
PDEBUG("Current list:\n");
|
||||
for (ptr = allocator_list; ptr; ptr = ptr->next) {
|
||||
PDEBUG("0x%08lx (size %likB)\n",ptr->address,ptr->size>>10);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ========================================================================
|
||||
* This function is the actual allocator.
|
||||
*
|
||||
* If space is available in high memory (as detected at load time), that
|
||||
* one is returned. The return value is a physical address (i.e., it can
|
||||
* be used straight ahead for DMA, but needs remapping for program use).
|
||||
*/
|
||||
|
||||
unsigned long allocator_allocate_dma (unsigned long kilobytes, int prio)
|
||||
{
|
||||
struct allocator_struct *ptr = allocator_list, *newptr;
|
||||
unsigned long bytes = kilobytes << 10;
|
||||
|
||||
/* check if high memory is available */
|
||||
if (!allocator_buffer)
|
||||
return 0;
|
||||
|
||||
/* Round it to a multiple of the pagesize */
|
||||
bytes = PAGE_ALIGN(bytes);
|
||||
PDEBUG("request for %li bytes\n", bytes);
|
||||
|
||||
while (ptr && ptr->next) {
|
||||
if (ptr->next->address - (ptr->address + ptr->size) >= bytes)
|
||||
break; /* enough space */
|
||||
ptr = ptr->next;
|
||||
}
|
||||
if (!ptr->next) {
|
||||
DUMP_LIST();
|
||||
PDEBUG("alloc failed\n");
|
||||
return 0; /* end of list */
|
||||
}
|
||||
newptr = kmalloc(sizeof(struct allocator_struct),prio);
|
||||
if (!newptr)
|
||||
return 0;
|
||||
|
||||
/* ok, now stick it after ptr */
|
||||
newptr->address = ptr->address + ptr->size;
|
||||
newptr->size = bytes;
|
||||
newptr->next = ptr->next;
|
||||
ptr->next = newptr;
|
||||
|
||||
DUMP_LIST();
|
||||
PDEBUG("returning 0x%08lx\n",newptr->address);
|
||||
return newptr->address;
|
||||
}
|
||||
|
||||
int allocator_free_dma (unsigned long address)
|
||||
{
|
||||
struct allocator_struct *ptr = allocator_list, *prev;
|
||||
|
||||
while (ptr && ptr->next) {
|
||||
if (ptr->next->address == address)
|
||||
break;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
/* the one being freed is ptr->next */
|
||||
prev = ptr; ptr = ptr->next;
|
||||
|
||||
if (!ptr) {
|
||||
printk(KERN_ERR ALL_MSG "free_dma(0x%08lx) but add. not allocated\n",
|
||||
ptr->address);
|
||||
return -EINVAL;
|
||||
}
|
||||
PDEBUGG("freeing: %08lx (%li) next %08lx\n",ptr->address,ptr->size,
|
||||
ptr->next->address);
|
||||
prev->next = ptr->next;
|
||||
kfree(ptr);
|
||||
|
||||
/* dump_list(); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Init and cleanup
|
||||
*
|
||||
* On cleanup everything is released. If the list is not empty, that a
|
||||
* problem of our clients
|
||||
*/
|
||||
int allocator_init(u_long *allocator_max)
|
||||
{
|
||||
/* check how much free memory is there */
|
||||
|
||||
volatile void *remapped;
|
||||
unsigned long max;
|
||||
unsigned long trial_size = allocator_himem<<20;
|
||||
unsigned long last_trial = 0;
|
||||
unsigned long step = allocator_step<<20;
|
||||
unsigned long i=0;
|
||||
struct allocator_struct *head, *tail;
|
||||
char test_string[]="0123456789abcde"; /* 16 bytes */
|
||||
|
||||
PDEBUGG("himem = %i\n",allocator_himem);
|
||||
if (allocator_himem < 0) /* don't even try */
|
||||
return -EINVAL;
|
||||
|
||||
if (!trial_size) trial_size = 1<<20; /* not specified: try one meg */
|
||||
|
||||
while (1) {
|
||||
remapped = ioremap(__pa(high_memory), trial_size);
|
||||
if (!remapped)
|
||||
{
|
||||
PDEBUGG("%li megs failed!\n",trial_size>>20);
|
||||
break;
|
||||
}
|
||||
PDEBUGG("Trying %li megs (at %p, %p)\n",trial_size>>20,
|
||||
(void *)__pa(high_memory), remapped);
|
||||
for (i=last_trial; i<trial_size; i+=16) {
|
||||
strcpy((char *)(remapped)+i, test_string);
|
||||
if (strcmp((char *)(remapped)+i, test_string))
|
||||
break;
|
||||
}
|
||||
iounmap((void *)remapped);
|
||||
schedule();
|
||||
last_trial = trial_size;
|
||||
if (i==trial_size)
|
||||
trial_size += step; /* increment, if all went well */
|
||||
else
|
||||
{
|
||||
PDEBUGG("%li megs copy test failed!\n",trial_size>>20);
|
||||
break;
|
||||
}
|
||||
if (!allocator_probe) break;
|
||||
}
|
||||
PDEBUG("%li megs (%li k, %li b)\n",i>>20,i>>10,i);
|
||||
allocator_buffer_size = i>>10; /* kilobytes */
|
||||
allocator_buffer = __pa(high_memory);
|
||||
if (!allocator_buffer_size) {
|
||||
printk(KERN_WARNING ALL_MSG "no free high memory to use\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* to simplify things, always have two cells in the list:
|
||||
* the first and the last. This avoids some conditionals and
|
||||
* extra code when allocating and deallocating: we only play
|
||||
* in the middle of the list
|
||||
*/
|
||||
head = kmalloc(sizeof(struct allocator_struct),GFP_KERNEL);
|
||||
if (!head)
|
||||
return -ENOMEM;
|
||||
tail = kmalloc(sizeof(struct allocator_struct),GFP_KERNEL);
|
||||
if (!tail) {
|
||||
kfree(head);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
max = allocator_buffer_size<<10;
|
||||
|
||||
head->size = tail->size = 0;
|
||||
head->address = allocator_buffer;
|
||||
tail->address = allocator_buffer + max;
|
||||
head->next = tail;
|
||||
tail->next = NULL;
|
||||
allocator_list = head;
|
||||
|
||||
*allocator_max = allocator_buffer_size; /* Back to the user code, in KB */
|
||||
|
||||
return 0; /* ok, ready */
|
||||
}
|
||||
|
||||
void allocator_cleanup(void)
|
||||
{
|
||||
struct allocator_struct *ptr, *next;
|
||||
|
||||
for (ptr = allocator_list; ptr; ptr = next) {
|
||||
next = ptr->next;
|
||||
PDEBUG("freeing list: 0x%08lx\n",ptr->address);
|
||||
kfree(ptr);
|
||||
}
|
||||
|
||||
allocator_buffer = 0;
|
||||
allocator_buffer_size = 0;
|
||||
allocator_list = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* allocator.h -- prototypes for allocating high memory
|
||||
*
|
||||
* NOTE: this is different from my previous allocator, the one that
|
||||
* assembles pages, which revealed itself both slow and unreliable.
|
||||
*
|
||||
* Copyright (C) 1998 rubini@linux.it (Alessandro Rubini)
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
void allocator_free_dma(unsigned long address);
|
||||
unsigned long allocator_allocate_dma (unsigned long kilobytes, int priority);
|
||||
int allocator_init(u_long *);
|
||||
void allocator_cleanup(void);
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
|
||||
Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
|
||||
Jason Lapenta, Scott Smedley
|
||||
|
||||
This file is part of the DT3155 Device Driver.
|
||||
|
||||
The DT3155 Device Driver 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.
|
||||
|
||||
The DT3155 Device Driver 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 the DT3155 Device Driver; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
MA 02111-1307 USA
|
||||
|
||||
$Id: dt3155.h,v 1.11 2005/08/09 06:08:51 ssmedley Exp $
|
||||
|
||||
-- Changes --
|
||||
|
||||
Date Programmer Description of changes made
|
||||
-------------------------------------------------------------------
|
||||
03-Jul-2000 JML n/a
|
||||
10-Oct-2001 SS port to 2.4 kernel.
|
||||
24-Jul-2002 SS remove unused code & added GPL licence.
|
||||
05-Aug-2005 SS port to 2.6 kernel; make CCIR mode default.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _DT3155_INC
|
||||
#define _DT3155_INC
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/types.h> /* u_int etc. */
|
||||
#include <linux/time.h> /* struct timeval */
|
||||
#else
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
/* Uncomment this for 50Hz CCIR */
|
||||
#define CCIR 1
|
||||
|
||||
/* Can be 1 or 2 */
|
||||
#define MAXBOARDS 1
|
||||
|
||||
#define BOARD_MAX_BUFFS 3
|
||||
#define MAXBUFFERS BOARD_MAX_BUFFS*MAXBOARDS
|
||||
|
||||
#define PCI_PAGE_SIZE (1 << 12)
|
||||
|
||||
#ifdef CCIR
|
||||
#define DT3155_MAX_ROWS 576
|
||||
#define DT3155_MAX_COLS 768
|
||||
#define FORMAT50HZ TRUE
|
||||
#else
|
||||
#define DT3155_MAX_ROWS 480
|
||||
#define DT3155_MAX_COLS 640
|
||||
#define FORMAT50HZ FALSE
|
||||
#endif
|
||||
|
||||
/* Configuration structure */
|
||||
struct dt3155_config_s {
|
||||
u_int acq_mode;
|
||||
u_int cols, rows;
|
||||
u_int continuous;
|
||||
};
|
||||
|
||||
|
||||
/* hold data for each frame */
|
||||
typedef struct
|
||||
{
|
||||
u_long addr; /* address of the buffer with the frame */
|
||||
u_long tag; /* unique number for the frame */
|
||||
struct timeval time; /* time that capture took place */
|
||||
} frame_info_t;
|
||||
|
||||
/* Structure for interrupt and buffer handling. */
|
||||
/* This is the setup for 1 card */
|
||||
struct dt3155_fbuffer_s {
|
||||
int nbuffers;
|
||||
|
||||
frame_info_t frame_info[ BOARD_MAX_BUFFS ];
|
||||
|
||||
int empty_buffers[ BOARD_MAX_BUFFS ]; /* indexes empty frames */
|
||||
int empty_len; /* Number of empty buffers */
|
||||
/* Zero means empty */
|
||||
|
||||
int active_buf; /* Where data is currently dma'ing */
|
||||
int locked_buf; /* Buffers used by user */
|
||||
|
||||
int ready_que[ BOARD_MAX_BUFFS ];
|
||||
u_long ready_head; /* The most recent buffer located here */
|
||||
u_long ready_len; /* The number of ready buffers */
|
||||
|
||||
int even_happened;
|
||||
int even_stopped;
|
||||
|
||||
int stop_acquire; /* Flag to stop interrupts */
|
||||
u_long frame_count; /* Counter for frames acquired by this card */
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define DT3155_MODE_FRAME 1
|
||||
#define DT3155_MODE_FIELD 2
|
||||
|
||||
#define DT3155_SNAP 1
|
||||
#define DT3155_ACQ 2
|
||||
|
||||
/* There is one status structure for each card. */
|
||||
typedef struct dt3155_status_s
|
||||
{
|
||||
int fixed_mode; /* if 1, we are in fixed frame mode */
|
||||
u_long reg_addr; /* Register address for a single card */
|
||||
u_long mem_addr; /* Buffer start addr for this card */
|
||||
u_long mem_size; /* This is the amount of mem available */
|
||||
u_int irq; /* this card's irq */
|
||||
struct dt3155_config_s config; /* configuration struct */
|
||||
struct dt3155_fbuffer_s fbuffer;/* frame buffer state struct */
|
||||
u_long state; /* this card's state */
|
||||
u_int device_installed; /* Flag if installed. 1=installed */
|
||||
} dt3155_status_t;
|
||||
|
||||
/* Reference to global status structure */
|
||||
extern struct dt3155_status_s dt3155_status[MAXBOARDS];
|
||||
|
||||
#define DT3155_STATE_IDLE 0x00
|
||||
#define DT3155_STATE_FRAME 0x01
|
||||
#define DT3155_STATE_FLD 0x02
|
||||
#define DT3155_STATE_STOP 0x100
|
||||
#define DT3155_STATE_ERROR 0x200
|
||||
#define DT3155_STATE_MODE 0x0ff
|
||||
|
||||
#define DT3155_IOC_MAGIC '!'
|
||||
|
||||
#define DT3155_SET_CONFIG _IOW( DT3155_IOC_MAGIC, 1, struct dt3155_config_s )
|
||||
#define DT3155_GET_CONFIG _IOR( DT3155_IOC_MAGIC, 2, struct dt3155_status_s )
|
||||
#define DT3155_STOP _IO( DT3155_IOC_MAGIC, 3 )
|
||||
#define DT3155_START _IO( DT3155_IOC_MAGIC, 4 )
|
||||
#define DT3155_FLUSH _IO( DT3155_IOC_MAGIC, 5 )
|
||||
#define DT3155_IOC_MAXNR 5
|
||||
|
||||
/* Error codes */
|
||||
|
||||
#define DT_ERR_NO_BUFFERS 0x10000 /* not used but it might be one day - SS */
|
||||
#define DT_ERR_CORRUPT 0x20000
|
||||
#define DT_ERR_OVERRUN 0x30000
|
||||
#define DT_ERR_I2C_TIMEOUT 0x40000
|
||||
#define DT_ERR_MASK 0xff0000/* not used but it might be one day - SS */
|
||||
|
||||
/* User code will probably want to declare one of these for each card */
|
||||
typedef struct dt3155_read_s
|
||||
{
|
||||
u_long offset;
|
||||
u_long frame_seq;
|
||||
u_long state;
|
||||
|
||||
frame_info_t frame_info;
|
||||
} dt3155_read_t;
|
||||
|
||||
#endif /* _DT3155_inc */
|
||||
@@ -0,0 +1,60 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# Module load/unload script for use with SysV-style /etc/init.d/ systems.
|
||||
# On a Debian system, copy this to /etc/init.d/dt3155 and then run
|
||||
# /usr/sbin/update-rc.d dt3155 defaults 55
|
||||
# to create the appropriate /etc/rc?.d/[SK]55dt3155 start/stop links.
|
||||
# (The "55" is arbitrary but is what I use to load this rather late.)
|
||||
#
|
||||
# Andy Dougherty Feb 22 2000 doughera@lafayette.edu
|
||||
# Dept. of Physics
|
||||
# Lafayette College, Easton PA 18042
|
||||
#
|
||||
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||
|
||||
# Edit to point to your local copy.
|
||||
FILE=/usr/local/lib/modules/dt3155/dt3155.o
|
||||
NAME="dt3155"
|
||||
DESC="dt3155 Frame Grabber module"
|
||||
DEV="dt3155"
|
||||
|
||||
if test ! -f $FILE; then
|
||||
echo "Unable to locate $FILE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Loading $DESC "
|
||||
if /sbin/insmod -v -f $FILE; then
|
||||
major=`grep $DEV /proc/devices | awk "{print \\$1}"`
|
||||
rm -f /dev/dt3155?
|
||||
mknod /dev/dt3155a c $major 0
|
||||
mknod /dev/dt3155b c $major 1
|
||||
chmod go+rw /dev/dt3155?
|
||||
echo
|
||||
else
|
||||
echo "$FILE not loaded."
|
||||
fi
|
||||
;;
|
||||
stop)
|
||||
echo -n "Unloading $DESC: "
|
||||
if /sbin/rmmod $NAME ; then
|
||||
echo
|
||||
else
|
||||
echo "$DEV not removed"
|
||||
exit 0
|
||||
fi
|
||||
rm -f /dev/dt3155?
|
||||
;;
|
||||
*)
|
||||
echo "Usage: /etc/init.d/$NAME {start|stop}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
|
||||
Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
|
||||
Scott Smedley
|
||||
|
||||
This file is part of the DT3155 Device Driver.
|
||||
|
||||
The DT3155 Device Driver 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.
|
||||
|
||||
The DT3155 Device Driver 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 the DT3155 Device Driver; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef DT3155_DRV_INC
|
||||
#define DT3155_DRV_INC
|
||||
|
||||
/* kernel logical address of the frame grabbers */
|
||||
extern u_char *dt3155_lbase[ MAXBOARDS ];
|
||||
|
||||
/* kernel logical address of ram buffer */
|
||||
extern u_char *dt3155_bbase;
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/wait.h>
|
||||
|
||||
#include <linux/version.h> /* need access to LINUX_VERSION_CODE */
|
||||
/* wait queue for reads */
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,1)
|
||||
extern wait_queue_head_t dt3155_read_wait_queue[MAXBOARDS];
|
||||
#else
|
||||
extern struct wait_queue *dt3155_read_wait_queue[MAXBOARDS];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* number of devices */
|
||||
extern u_int ndevices;
|
||||
|
||||
extern int dt3155_errno;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
|
||||
Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
|
||||
Jason Lapenta, Scott Smedley
|
||||
|
||||
This file is part of the DT3155 Device Driver.
|
||||
|
||||
The DT3155 Device Driver 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.
|
||||
|
||||
The DT3155 Device Driver 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 the DT3155 Device Driver; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
MA 02111-1307 USA
|
||||
|
||||
|
||||
-- Changes --
|
||||
|
||||
Date Programmer Description of changes made
|
||||
-------------------------------------------------------------------
|
||||
10-Oct-2001 SS port to 2.4 kernel.
|
||||
24-Jul-2002 SS GPL licence.
|
||||
26-Jul-2002 SS Bug fix: timing logic was wrong.
|
||||
08-Aug-2005 SS port to 2.6 kernel.
|
||||
|
||||
*/
|
||||
|
||||
/* This file provides some basic register io routines. It is modified
|
||||
from demo code provided by Data Translations. */
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <asm/delay.h>
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "dt3155.h"
|
||||
#include "dt3155_io.h"
|
||||
#include "dt3155_drv.h"
|
||||
|
||||
#ifndef __KERNEL__
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
|
||||
/****** local copies of board's 32 bit registers ******/
|
||||
u_long even_dma_start_r; /* bit 0 should always be 0 */
|
||||
u_long odd_dma_start_r; /* .. */
|
||||
u_long even_dma_stride_r; /* bits 0&1 should always be 0 */
|
||||
u_long odd_dma_stride_r; /* .. */
|
||||
u_long even_pixel_fmt_r;
|
||||
u_long odd_pixel_fmt_r;
|
||||
|
||||
FIFO_TRIGGER_R fifo_trigger_r;
|
||||
XFER_MODE_R xfer_mode_r;
|
||||
CSR1_R csr1_r;
|
||||
RETRY_WAIT_CNT_R retry_wait_cnt_r;
|
||||
INT_CSR_R int_csr_r;
|
||||
|
||||
u_long even_fld_mask_r;
|
||||
u_long odd_fld_mask_r;
|
||||
|
||||
MASK_LENGTH_R mask_length_r;
|
||||
FIFO_FLAG_CNT_R fifo_flag_cnt_r;
|
||||
IIC_CLK_DUR_R iic_clk_dur_r;
|
||||
IIC_CSR1_R iic_csr1_r;
|
||||
IIC_CSR2_R iic_csr2_r;
|
||||
DMA_UPPER_LMT_R even_dma_upper_lmt_r;
|
||||
DMA_UPPER_LMT_R odd_dma_upper_lmt_r;
|
||||
|
||||
|
||||
|
||||
/******** local copies of board's 8 bit I2C registers ******/
|
||||
I2C_CSR2 i2c_csr2;
|
||||
I2C_EVEN_CSR i2c_even_csr;
|
||||
I2C_ODD_CSR i2c_odd_csr;
|
||||
I2C_CONFIG i2c_config;
|
||||
u_char i2c_dt_id;
|
||||
u_char i2c_x_clip_start;
|
||||
u_char i2c_y_clip_start;
|
||||
u_char i2c_x_clip_end;
|
||||
u_char i2c_y_clip_end;
|
||||
u_char i2c_ad_addr;
|
||||
u_char i2c_ad_lut;
|
||||
I2C_AD_CMD i2c_ad_cmd;
|
||||
u_char i2c_dig_out;
|
||||
u_char i2c_pm_lut_addr;
|
||||
u_char i2c_pm_lut_data;
|
||||
|
||||
|
||||
// return the time difference (in microseconds) b/w <a> & <b>.
|
||||
long elapsed2 (const struct timeval *pStart, const struct timeval *pEnd)
|
||||
{
|
||||
long i = (pEnd->tv_sec - pStart->tv_sec) * 1000000;
|
||||
i += pEnd->tv_usec - pStart->tv_usec;
|
||||
return i;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
wait_ibsyclr()
|
||||
|
||||
This function handles read/write timing and r/w timeout error
|
||||
|
||||
Returns TRUE if NEW_CYCLE clears
|
||||
Returns FALSE if NEW_CYCLE doesn't clear in roughly 3 msecs,
|
||||
otherwise returns 0
|
||||
|
||||
***********************************************************************/
|
||||
int wait_ibsyclr(u_char * lpReg)
|
||||
{
|
||||
/* wait 100 microseconds */
|
||||
|
||||
#ifdef __KERNEL__
|
||||
udelay(100L);
|
||||
/* __delay(loops_per_sec/10000); */
|
||||
if (iic_csr2_r.fld.NEW_CYCLE )
|
||||
{ /* if NEW_CYCLE didn't clear */
|
||||
/* TIMEOUT ERROR */
|
||||
dt3155_errno = DT_ERR_I2C_TIMEOUT;
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return TRUE; /* no error */
|
||||
#else
|
||||
struct timeval StartTime;
|
||||
struct timeval EndTime;
|
||||
|
||||
const int to_3ms = 3000; /* time out of 3ms = 3000us */
|
||||
|
||||
gettimeofday( &StartTime, NULL );
|
||||
do {
|
||||
/* get new iic_csr2 value: */
|
||||
ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
|
||||
gettimeofday( &EndTime, NULL );
|
||||
}
|
||||
while ((elapsed2(&StartTime, &EndTime) < to_3ms) && iic_csr2_r.fld.NEW_CYCLE);
|
||||
|
||||
if (iic_csr2_r.fld.NEW_CYCLE )
|
||||
{ /* if NEW_CYCLE didn't clear */
|
||||
printf("Timed out waiting for NEW_CYCLE to clear!");
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return TRUE; /* no error */
|
||||
#endif
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
WriteI2C()
|
||||
|
||||
This function handles writing to 8-bit DT3155 registers
|
||||
|
||||
1st parameter is pointer to 32-bit register base address
|
||||
2nd parameter is reg. index;
|
||||
3rd is value to be written
|
||||
|
||||
Returns TRUE - Successful completion
|
||||
FALSE - Timeout error - cycle did not complete!
|
||||
***********************************************************************/
|
||||
int WriteI2C (u_char * lpReg, u_short wIregIndex, u_char byVal)
|
||||
{
|
||||
int writestat; /* status for return */
|
||||
|
||||
/* read 32 bit IIC_CSR2 register data into union */
|
||||
|
||||
ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
|
||||
|
||||
iic_csr2_r.fld.DIR_RD = 0; /* for write operation */
|
||||
iic_csr2_r.fld.DIR_ADDR = wIregIndex; /* I2C address of I2C register: */
|
||||
iic_csr2_r.fld.DIR_WR_DATA = byVal; /* 8 bit data to be written to I2C reg */
|
||||
iic_csr2_r.fld.NEW_CYCLE = 1; /* will start a direct I2C cycle: */
|
||||
|
||||
/* xfer union data into 32 bit IIC_CSR2 register */
|
||||
|
||||
WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
|
||||
|
||||
/* wait for IIC cycle to finish */
|
||||
|
||||
writestat = wait_ibsyclr( lpReg );
|
||||
return writestat; /* return with status */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
ReadI2C()
|
||||
|
||||
This function handles reading from 8-bit DT3155 registers
|
||||
|
||||
1st parameter is pointer to 32-bit register base address
|
||||
2nd parameter is reg. index;
|
||||
3rd is adrs of value to be read
|
||||
|
||||
Returns TRUE - Successful completion
|
||||
FALSE - Timeout error - cycle did not complete!
|
||||
***********************************************************************/
|
||||
int ReadI2C (u_char * lpReg, u_short wIregIndex, u_char * byVal)
|
||||
{
|
||||
int writestat; /* status for return */
|
||||
|
||||
/* read 32 bit IIC_CSR2 register data into union */
|
||||
ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
|
||||
|
||||
/* for read operation */
|
||||
iic_csr2_r.fld.DIR_RD = 1;
|
||||
|
||||
/* I2C address of I2C register: */
|
||||
iic_csr2_r.fld.DIR_ADDR = wIregIndex;
|
||||
|
||||
/* will start a direct I2C cycle: */
|
||||
iic_csr2_r.fld.NEW_CYCLE = 1;
|
||||
|
||||
/* xfer union's data into 32 bit IIC_CSR2 register */
|
||||
WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
|
||||
|
||||
/* wait for IIC cycle to finish */
|
||||
writestat = wait_ibsyclr(lpReg);
|
||||
|
||||
/* Next 2 commands read 32 bit IIC_CSR1 register's data into union */
|
||||
/* first read data is in IIC_CSR1 */
|
||||
ReadMReg((lpReg + IIC_CSR1), iic_csr1_r.reg);
|
||||
|
||||
/* now get data u_char out of register */
|
||||
*byVal = (u_char) iic_csr1_r.fld.RD_DATA;
|
||||
|
||||
return writestat; /* return with status */
|
||||
}
|
||||
@@ -0,0 +1,400 @@
|
||||
/*
|
||||
|
||||
Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
|
||||
Jason Lapenta, Scott Smedley
|
||||
|
||||
This file is part of the DT3155 Device Driver.
|
||||
|
||||
The DT3155 Device Driver 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.
|
||||
|
||||
The DT3155 Device Driver 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 the DT3155 Device Driver; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
MA 02111-1307 USA
|
||||
|
||||
|
||||
-- Changes --
|
||||
|
||||
Date Programmer Description of changes made
|
||||
-------------------------------------------------------------------
|
||||
24-Jul-2002 SS GPL licence.
|
||||
|
||||
*/
|
||||
|
||||
/* This code is a modified version of examples provided by Data Translations.*/
|
||||
|
||||
#ifndef DT3155_IO_INC
|
||||
#define DT3155_IO_INC
|
||||
|
||||
/* macros to access registers */
|
||||
|
||||
#define WriteMReg(Address, Data) * ((u_long *) (Address)) = Data
|
||||
#define ReadMReg(Address, Data) Data = * ((u_long *) (Address))
|
||||
|
||||
/***************** 32 bit register globals **************/
|
||||
|
||||
/* offsets for 32-bit memory mapped registers */
|
||||
|
||||
#define EVEN_DMA_START 0x000
|
||||
#define ODD_DMA_START 0x00C
|
||||
#define EVEN_DMA_STRIDE 0x018
|
||||
#define ODD_DMA_STRIDE 0x024
|
||||
#define EVEN_PIXEL_FMT 0x030
|
||||
#define ODD_PIXEL_FMT 0x034
|
||||
#define FIFO_TRIGGER 0x038
|
||||
#define XFER_MODE 0x03C
|
||||
#define CSR1 0x040
|
||||
#define RETRY_WAIT_CNT 0x044
|
||||
#define INT_CSR 0x048
|
||||
#define EVEN_FLD_MASK 0x04C
|
||||
#define ODD_FLD_MASK 0x050
|
||||
#define MASK_LENGTH 0x054
|
||||
#define FIFO_FLAG_CNT 0x058
|
||||
#define IIC_CLK_DUR 0x05C
|
||||
#define IIC_CSR1 0x060
|
||||
#define IIC_CSR2 0x064
|
||||
#define EVEN_DMA_UPPR_LMT 0x08C
|
||||
#define ODD_DMA_UPPR_LMT 0x090
|
||||
|
||||
#define CLK_DUR_VAL 0x01010101
|
||||
|
||||
|
||||
|
||||
/******** Assignments and Typedefs for 32 bit Memory Mapped Registers ********/
|
||||
|
||||
/**********************************
|
||||
* fifo_trigger_tag
|
||||
*/
|
||||
typedef union fifo_trigger_tag {
|
||||
u_long reg;
|
||||
struct
|
||||
{
|
||||
u_long PACKED : 6;
|
||||
u_long : 9;
|
||||
u_long PLANER : 7;
|
||||
u_long : 9;
|
||||
} fld;
|
||||
} FIFO_TRIGGER_R;
|
||||
|
||||
/**********************************
|
||||
* xfer_mode_tag
|
||||
*/
|
||||
typedef union xfer_mode_tag {
|
||||
u_long reg;
|
||||
struct
|
||||
{
|
||||
u_long : 2;
|
||||
u_long FIELD_TOGGLE : 1;
|
||||
u_long : 5;
|
||||
u_long : 2;
|
||||
u_long : 22;
|
||||
} fld;
|
||||
} XFER_MODE_R;
|
||||
|
||||
/**********************************
|
||||
* csr1_tag
|
||||
*/
|
||||
typedef union csr1_tag {
|
||||
u_long reg;
|
||||
struct
|
||||
{
|
||||
u_long CAP_CONT_EVE : 1;
|
||||
u_long CAP_CONT_ODD : 1;
|
||||
u_long CAP_SNGL_EVE : 1;
|
||||
u_long CAP_SNGL_ODD : 1;
|
||||
u_long FLD_DN_EVE : 1;
|
||||
u_long FLD_DN_ODD : 1;
|
||||
u_long SRST : 1;
|
||||
u_long FIFO_EN : 1;
|
||||
u_long FLD_CRPT_EVE : 1;
|
||||
u_long FLD_CRPT_ODD : 1;
|
||||
u_long ADDR_ERR_EVE : 1;
|
||||
u_long ADDR_ERR_ODD : 1;
|
||||
u_long CRPT_DIS : 1;
|
||||
u_long RANGE_EN : 1;
|
||||
u_long : 16;
|
||||
} fld;
|
||||
} CSR1_R;
|
||||
|
||||
/**********************************
|
||||
* retry_wait_cnt_tag
|
||||
*/
|
||||
typedef union retry_wait_cnt_tag {
|
||||
u_long reg;
|
||||
struct
|
||||
{
|
||||
u_long RTRY_WAIT_CNT : 8;
|
||||
u_long : 24;
|
||||
} fld;
|
||||
} RETRY_WAIT_CNT_R;
|
||||
|
||||
/**********************************
|
||||
* int_csr_tag
|
||||
*/
|
||||
typedef union int_csr_tag {
|
||||
u_long reg;
|
||||
struct
|
||||
{
|
||||
u_long FLD_END_EVE : 1;
|
||||
u_long FLD_END_ODD : 1;
|
||||
u_long FLD_START : 1;
|
||||
u_long : 5;
|
||||
u_long FLD_END_EVE_EN : 1;
|
||||
u_long FLD_END_ODD_EN : 1;
|
||||
u_long FLD_START_EN : 1;
|
||||
u_long : 21;
|
||||
} fld;
|
||||
} INT_CSR_R;
|
||||
|
||||
/**********************************
|
||||
* mask_length_tag
|
||||
*/
|
||||
typedef union mask_length_tag {
|
||||
u_long reg;
|
||||
struct
|
||||
{
|
||||
u_long MASK_LEN_EVE : 5;
|
||||
u_long : 11;
|
||||
u_long MASK_LEN_ODD : 5;
|
||||
u_long : 11;
|
||||
} fld;
|
||||
} MASK_LENGTH_R;
|
||||
|
||||
/**********************************
|
||||
* fifo_flag_cnt_tag
|
||||
*/
|
||||
typedef union fifo_flag_cnt_tag {
|
||||
u_long reg;
|
||||
struct
|
||||
{
|
||||
u_long AF_COUNT : 7;
|
||||
u_long : 9;
|
||||
u_long AE_COUNT : 7;
|
||||
u_long : 9;
|
||||
} fld;
|
||||
} FIFO_FLAG_CNT_R;
|
||||
|
||||
/**********************************
|
||||
* iic_clk_dur
|
||||
*/
|
||||
typedef union iic_clk_dur {
|
||||
u_long reg;
|
||||
struct
|
||||
{
|
||||
u_long PHASE_1 : 8;
|
||||
u_long PHASE_2 : 8;
|
||||
u_long PHASE_3 : 8;
|
||||
u_long PHASE_4 : 8;
|
||||
} fld;
|
||||
} IIC_CLK_DUR_R;
|
||||
|
||||
/**********************************
|
||||
* iic_csr1_tag
|
||||
*/
|
||||
typedef union iic_csr1_tag {
|
||||
u_long reg;
|
||||
struct
|
||||
{
|
||||
u_long AUTO_EN : 1;
|
||||
u_long BYPASS : 1;
|
||||
u_long SDA_OUT : 1;
|
||||
u_long SCL_OUT : 1;
|
||||
u_long : 4;
|
||||
u_long AUTO_ABORT : 1;
|
||||
u_long DIRECT_ABORT : 1;
|
||||
u_long SDA_IN : 1;
|
||||
u_long SCL_IN : 1;
|
||||
u_long : 4;
|
||||
u_long AUTO_ADDR : 8;
|
||||
u_long RD_DATA : 8;
|
||||
} fld;
|
||||
} IIC_CSR1_R;
|
||||
|
||||
/**********************************
|
||||
* iic_csr2_tag
|
||||
*/
|
||||
typedef union iic_csr2_tag {
|
||||
u_long reg;
|
||||
struct
|
||||
{
|
||||
u_long DIR_WR_DATA : 8;
|
||||
u_long DIR_SUB_ADDR : 8;
|
||||
u_long DIR_RD : 1;
|
||||
u_long DIR_ADDR : 7;
|
||||
u_long NEW_CYCLE : 1;
|
||||
u_long : 7;
|
||||
} fld;
|
||||
} IIC_CSR2_R;
|
||||
|
||||
/* use for both EVEN and ODD DMA UPPER LIMITS */
|
||||
|
||||
/**********************************
|
||||
* dma_upper_lmt_tag
|
||||
*/
|
||||
typedef union dma_upper_lmt_tag {
|
||||
u_long reg;
|
||||
struct
|
||||
{
|
||||
u_long DMA_UPPER_LMT_VAL : 24;
|
||||
u_long : 8;
|
||||
} fld;
|
||||
} DMA_UPPER_LMT_R;
|
||||
|
||||
|
||||
/***************************************
|
||||
* Global declarations of local copies
|
||||
* of boards' 32 bit registers
|
||||
***************************************/
|
||||
extern u_long even_dma_start_r; /* bit 0 should always be 0 */
|
||||
extern u_long odd_dma_start_r; /* .. */
|
||||
extern u_long even_dma_stride_r; /* bits 0&1 should always be 0 */
|
||||
extern u_long odd_dma_stride_r; /* .. */
|
||||
extern u_long even_pixel_fmt_r;
|
||||
extern u_long odd_pixel_fmt_r;
|
||||
|
||||
extern FIFO_TRIGGER_R fifo_trigger_r;
|
||||
extern XFER_MODE_R xfer_mode_r;
|
||||
extern CSR1_R csr1_r;
|
||||
extern RETRY_WAIT_CNT_R retry_wait_cnt_r;
|
||||
extern INT_CSR_R int_csr_r;
|
||||
|
||||
extern u_long even_fld_mask_r;
|
||||
extern u_long odd_fld_mask_r;
|
||||
|
||||
extern MASK_LENGTH_R mask_length_r;
|
||||
extern FIFO_FLAG_CNT_R fifo_flag_cnt_r;
|
||||
extern IIC_CLK_DUR_R iic_clk_dur_r;
|
||||
extern IIC_CSR1_R iic_csr1_r;
|
||||
extern IIC_CSR2_R iic_csr2_r;
|
||||
extern DMA_UPPER_LMT_R even_dma_upper_lmt_r;
|
||||
extern DMA_UPPER_LMT_R odd_dma_upper_lmt_r;
|
||||
|
||||
|
||||
|
||||
/***************** 8 bit I2C register globals ***********/
|
||||
|
||||
#define CSR2 0x010 /* indices of 8-bit I2C mapped reg's*/
|
||||
#define EVEN_CSR 0x011
|
||||
#define ODD_CSR 0x012
|
||||
#define CONFIG 0x013
|
||||
#define DT_ID 0x01F
|
||||
#define X_CLIP_START 0x020
|
||||
#define Y_CLIP_START 0x022
|
||||
#define X_CLIP_END 0x024
|
||||
#define Y_CLIP_END 0x026
|
||||
#define AD_ADDR 0x030
|
||||
#define AD_LUT 0x031
|
||||
#define AD_CMD 0x032
|
||||
#define DIG_OUT 0x040
|
||||
#define PM_LUT_ADDR 0x050
|
||||
#define PM_LUT_DATA 0x051
|
||||
|
||||
|
||||
/******** Assignments and Typedefs for 8 bit I2C Registers********************/
|
||||
|
||||
typedef union i2c_csr2_tag {
|
||||
u_char reg;
|
||||
struct
|
||||
{
|
||||
u_char CHROM_FIL : 1;
|
||||
u_char SYNC_SNTL : 1;
|
||||
u_char HZ50 : 1;
|
||||
u_char SYNC_PRESENT : 1;
|
||||
u_char BUSY_EVE : 1;
|
||||
u_char BUSY_ODD : 1;
|
||||
u_char DISP_PASS : 1;
|
||||
} fld;
|
||||
} I2C_CSR2;
|
||||
|
||||
typedef union i2c_even_csr_tag {
|
||||
u_char reg;
|
||||
struct
|
||||
{
|
||||
u_char DONE_EVE : 1;
|
||||
u_char SNGL_EVE : 1;
|
||||
u_char ERROR_EVE : 1;
|
||||
u_char : 5;
|
||||
} fld;
|
||||
} I2C_EVEN_CSR;
|
||||
|
||||
typedef union i2c_odd_csr_tag {
|
||||
u_char reg;
|
||||
struct
|
||||
{
|
||||
u_char DONE_ODD : 1;
|
||||
u_char SNGL_ODD : 1;
|
||||
u_char ERROR_ODD : 1;
|
||||
u_char : 5;
|
||||
} fld;
|
||||
} I2C_ODD_CSR;
|
||||
|
||||
typedef union i2c_config_tag {
|
||||
u_char reg;
|
||||
struct
|
||||
{
|
||||
u_char ACQ_MODE : 2;
|
||||
u_char EXT_TRIG_EN : 1;
|
||||
u_char EXT_TRIG_POL : 1;
|
||||
u_char H_SCALE : 1;
|
||||
u_char CLIP : 1;
|
||||
u_char PM_LUT_SEL : 1;
|
||||
u_char PM_LUT_PGM : 1;
|
||||
} fld;
|
||||
} I2C_CONFIG;
|
||||
|
||||
|
||||
typedef union i2c_ad_cmd_tag { /* bits can have 3 different meanings
|
||||
depending on value of AD_ADDR */
|
||||
u_char reg;
|
||||
struct
|
||||
{
|
||||
u_char : 2;
|
||||
u_char SYNC_LVL_SEL : 2;
|
||||
u_char SYNC_CNL_SEL : 2;
|
||||
u_char DIGITIZE_CNL_SEL1 : 2;
|
||||
} bt252_command; /* Bt252 Command Register */
|
||||
struct /* if AD_ADDR = 00h */
|
||||
{
|
||||
u_char IOUT_DATA : 8;
|
||||
} bt252_iout0; /* Bt252 IOUT0 register */
|
||||
struct /* if AD_ADDR = 01h */
|
||||
{
|
||||
u_char IOUT_DATA : 8;
|
||||
} bt252_iout1; /* BT252 IOUT1 register */
|
||||
} I2C_AD_CMD; /* if AD_ADDR = 02h */
|
||||
|
||||
|
||||
/***** Global declarations of local copies of boards' 8 bit I2C registers ***/
|
||||
|
||||
extern I2C_CSR2 i2c_csr2;
|
||||
extern I2C_EVEN_CSR i2c_even_csr;
|
||||
extern I2C_ODD_CSR i2c_odd_csr;
|
||||
extern I2C_CONFIG i2c_config;
|
||||
extern u_char i2c_dt_id;
|
||||
extern u_char i2c_x_clip_start;
|
||||
extern u_char i2c_y_clip_start;
|
||||
extern u_char i2c_x_clip_end;
|
||||
extern u_char i2c_y_clip_end;
|
||||
extern u_char i2c_ad_addr;
|
||||
extern u_char i2c_ad_lut;
|
||||
extern I2C_AD_CMD i2c_ad_cmd;
|
||||
extern u_char i2c_dig_out;
|
||||
extern u_char i2c_pm_lut_addr;
|
||||
extern u_char i2c_pm_lut_data;
|
||||
|
||||
/* Functions for Global use */
|
||||
|
||||
/* access 8-bit IIC registers */
|
||||
|
||||
extern int ReadI2C (u_char * lpReg, u_short wIregIndex, u_char * byVal);
|
||||
extern int WriteI2C (u_char * lpReg, u_short wIregIndex, u_char byVal);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
|
||||
Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
|
||||
Jason Lapenta, Scott Smedley
|
||||
|
||||
This file is part of the DT3155 Device Driver.
|
||||
|
||||
The DT3155 Device Driver 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.
|
||||
|
||||
The DT3155 Device Driver 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 the DT3155 Device Driver; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
MA 02111-1307 USA
|
||||
|
||||
|
||||
-- Changes --
|
||||
|
||||
Date Programmer Description of changes made
|
||||
-------------------------------------------------------------------
|
||||
03-Jul-2000 JML n/a
|
||||
24-Jul-2002 SS GPL licence.
|
||||
26-Oct-2009 SS Porting to 2.6.30 kernel.
|
||||
|
||||
-- notes --
|
||||
|
||||
*/
|
||||
|
||||
#ifndef DT3155_ISR_H
|
||||
#define DT3155_ISR_H
|
||||
|
||||
extern struct dt3155_fbuffer_s *dt3155_fbuffer[MAXBOARDS];
|
||||
|
||||
/* User functions for buffering */
|
||||
/* Initialize the buffering system. This should */
|
||||
/* be called prior to enabling interrupts */
|
||||
|
||||
u_long dt3155_setup_buffers(u_long *allocatorAddr);
|
||||
|
||||
/* Get the next frame of data if it is ready. Returns */
|
||||
/* zero if no data is ready. If there is data but */
|
||||
/* the user has a locked buffer, it will unlock that */
|
||||
/* buffer and return it to the free list. */
|
||||
|
||||
int dt3155_get_ready_buffer(int minor);
|
||||
|
||||
/* Return a locked buffer to the free list */
|
||||
|
||||
void dt3155_release_locked_buffer(int minor);
|
||||
|
||||
/* Flush the buffer system */
|
||||
int dt3155_flush(int minor);
|
||||
|
||||
/**********************************
|
||||
* Simple array based que struct
|
||||
**********************************/
|
||||
|
||||
bool are_empty_buffers( int minor );
|
||||
void push_empty( int index, int minor );
|
||||
|
||||
int pop_empty( int minor );
|
||||
|
||||
bool is_ready_buf_empty( int minor );
|
||||
bool is_ready_buf_full( int minor );
|
||||
|
||||
void push_ready( int minor, int index );
|
||||
int pop_ready( int minor );
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,97 @@
|
||||
|
||||
/* This header only makes send when included in a 2.0 compile */
|
||||
|
||||
#ifndef _PCI_COMPAT_H_
|
||||
#define _PCI_COMPAT_H_
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/bios32.h> /* pcibios_* */
|
||||
#include <linux/pci.h> /* pcibios_* */
|
||||
#include <linux/malloc.h> /* kmalloc */
|
||||
|
||||
/* fake the new pci interface based on the old one: encapsulate bus/devfn */
|
||||
struct pci_fake_dev {
|
||||
u8 bus;
|
||||
u8 devfn;
|
||||
int index;
|
||||
};
|
||||
#define pci_dev pci_fake_dev /* the other pci_dev is unused by 2.0 drivers */
|
||||
|
||||
extern inline struct pci_dev *pci_find_device(unsigned int vendorid,
|
||||
unsigned int devid,
|
||||
struct pci_dev *from)
|
||||
{
|
||||
struct pci_dev *pptr = kmalloc(sizeof(*pptr), GFP_KERNEL);
|
||||
int index = 0;
|
||||
int ret;
|
||||
|
||||
if (!pptr) return NULL;
|
||||
if (from) index = pptr->index + 1;
|
||||
ret = pcibios_find_device(vendorid, devid, index,
|
||||
&pptr->bus, &pptr->devfn);
|
||||
if (ret) { kfree(pptr); return NULL; }
|
||||
return pptr;
|
||||
}
|
||||
|
||||
extern inline struct pci_dev *pci_find_class(unsigned int class,
|
||||
struct pci_dev *from)
|
||||
{
|
||||
return NULL; /* FIXME */
|
||||
}
|
||||
|
||||
extern inline void pci_release_device(struct pci_dev *dev)
|
||||
{
|
||||
kfree(dev);
|
||||
}
|
||||
|
||||
/* struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); */
|
||||
|
||||
#define pci_present pcibios_present
|
||||
|
||||
extern inline int
|
||||
pci_read_config_byte(struct pci_dev *dev, u8 where, u8 *val)
|
||||
{
|
||||
return pcibios_read_config_byte(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
|
||||
extern inline int
|
||||
pci_read_config_word(struct pci_dev *dev, u8 where, u16 *val)
|
||||
{
|
||||
return pcibios_read_config_word(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
|
||||
extern inline int
|
||||
pci_read_config_dword(struct pci_dev *dev, u8 where, u32 *val)
|
||||
{
|
||||
return pcibios_read_config_dword(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
|
||||
extern inline int
|
||||
pci_write_config_byte(struct pci_dev *dev, u8 where, u8 val)
|
||||
{
|
||||
return pcibios_write_config_byte(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
|
||||
extern inline int
|
||||
pci_write_config_word(struct pci_dev *dev, u8 where, u16 val)
|
||||
{
|
||||
return pcibios_write_config_word(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
|
||||
extern inline int
|
||||
pci_write_config_dword(struct pci_dev *dev, u8 where, u32 val)
|
||||
{
|
||||
return pcibios_write_config_dword(dev->bus, dev->devfn, where, val);
|
||||
}
|
||||
|
||||
extern inline void pci_set_master(struct pci_dev *dev)
|
||||
{
|
||||
u16 cmd;
|
||||
pcibios_read_config_word(dev->bus, dev->devfn, PCI_COMMAND, &cmd);
|
||||
cmd |= PCI_COMMAND_MASTER;
|
||||
pcibios_write_config_word(dev->bus, dev->devfn, PCI_COMMAND, cmd);
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _PCI_COMPAT_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user