Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Staging: dt3155: remove the driver

There is now a proper V4L driver for this device in the tree,
so remove this one.

Cc: Scott Smedley <ss@aao.gov.au>
Cc: H Hartley Sweeten <hartleys@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

-2771
-2
drivers/staging/Kconfig
··· 131 131 132 132 source "drivers/staging/sm7xx/Kconfig" 133 133 134 - source "drivers/staging/dt3155/Kconfig" 135 - 136 134 source "drivers/staging/dt3155v4l/Kconfig" 137 135 138 136 source "drivers/staging/crystalhd/Kconfig"
-1
drivers/staging/Makefile
··· 46 46 obj-$(CONFIG_BATMAN_ADV) += batman-adv/ 47 47 obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop/ 48 48 obj-$(CONFIG_FB_SM7XX) += sm7xx/ 49 - obj-$(CONFIG_DT3155) += dt3155/ 50 49 obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ 51 50 obj-$(CONFIG_CRYSTALHD) += crystalhd/ 52 51 obj-$(CONFIG_CXT1E1) += cxt1e1/
-4
drivers/staging/dt3155/Kconfig
··· 1 - config DT3155 2 - tristate "DT3155 Digitizer support" 3 - depends on PCI 4 -
-6
drivers/staging/dt3155/Makefile
··· 1 - obj-$(CONFIG_DT3155) += dt3155.o 2 - dt3155-objs := \ 3 - dt3155_drv.o \ 4 - dt3155_isr.o \ 5 - dt3155_io.o \ 6 - allocator.o
-10
drivers/staging/dt3155/TODO
··· 1 - TODO: 2 - - fix checkpatch.pl issues 3 - - remove old kernel support, it is not needed 4 - - convert to proper PCI device API 5 - - fix sparse warnings 6 - - audit for correct subsystem interaction 7 - - review review review! 8 - 9 - Please send patches to Greg Kroah-Hartman <greg@kroah.com> 10 - and Scott Smedley <ss@aao.gov.au>
-98
drivers/staging/dt3155/allocator.README
··· 1 - 2 - The allocator shown here exploits high memory. This document explains 3 - how a user can deal with drivers uses this allocator and how a 4 - programmer can link in the module. 5 - 6 - The module is being used by my pxc and pxdrv device drivers (as well as 7 - other ones), available from ftp.systemy.it/pub/develop and 8 - ftp.linux.it/pub/People/Rubini 9 - 10 - User's manual 11 - ============= 12 - 13 - 14 - One of the most compelling problems with any DMA-capable device is the 15 - allocation of a suitable memory buffer. The "allocator" module tries 16 - to deal with the problem in a clean way. The module is able to use 17 - high memory (above the one used in normal operation) for DMA 18 - allocation. 19 - 20 - To prevent the kernel for using high memory, so that it remains 21 - available for DMA, you should pass a command line argument to the 22 - kernel. Command line arguments can be passed to Lilo, to Loadlin or 23 - to whichever loader you are using (unless it's very poor in design). 24 - For Lilo, either use "append=" in /etc/lilo.conf or add commandline 25 - arguments to the interactive prompt. For example, I have a 32MB box 26 - and reserve two megs for DMA: 27 - 28 - In lilo.conf: 29 - image = /zImage 30 - label = linux 31 - append = "mem=30M" 32 - 33 - Or, interactively: 34 - LILO: linux mem=30M 35 - 36 - Once the kernel is booted with the right command-line argument, any 37 - driver linked with the allocator module will be able to get 38 - DMA-capable memory without much trouble (unless the various drivers 39 - need more memory than available). 40 - 41 - The module implements an alloc/free mechanism, so that it can serve 42 - multiple drivers at the same time. Note however that the allocator 43 - uses all of high memory and assumes to be the only piece of software 44 - using such memory. 45 - 46 - 47 - Programmer's manual 48 - =================== 49 - 50 - The allocator, as released, is designed to be linked to a device 51 - driver. In this case, the driver must call allocator_init() before 52 - using the allocator and must call allocator_cleanup() before 53 - unloading. This is usually done from within init_module() and 54 - cleanup_module(). If the allocator is linked to a driver, it won't be 55 - possible for several drivers to allocate high DMA memory, as explained 56 - above. 57 - 58 - It is possible, on the other hand, to compile the module as a standalone 59 - module, so that several modules can rely on the allocator for they DMA 60 - buffers. To compile the allocator as a standalone module, do the 61 - following in this directory (or provide a suitable Makefile, or edit 62 - the source code): 63 - 64 - make allocator.o CC="gcc -Dallocator_init=init_module -Dallocator_cleanup=cleanup_module -include /usr/include/linux/module.h" 65 - 66 - The previous commandline tells to include <linux/module.h> in the 67 - first place, and to rename the init and cleanup function to the ones 68 - needed for module loading and unloading. Drivers using a standalone 69 - allocator won't need to call allocator_init() nor allocator_cleanup(). 70 - 71 - The allocator exports the following functions (declared in allocator.h): 72 - 73 - unsigned long allocator_allocate_dma (unsigned long kilobytes, 74 - int priority); 75 - 76 - This function returns a physical address, over high_memory, 77 - which corresponds to an area of at least "kilobytes" kilobytes. 78 - The area will be owned by the module calling the function. 79 - The returned address can be passed to device boards, to instruct 80 - their DMA controllers, via phys_to_bus(). The address can be used 81 - by C code after vremap()/ioremap(). The "priority" argument should 82 - be GFP_KERNEL or GFP_ATOMIC, according to the context of the 83 - caller; it is used to call kmalloc(), as the allocator must keep 84 - track of any region it gives away. In case of error the function 85 - returns 0, and the caller is expected to issue a -ENOMEM error. 86 - 87 - 88 - void allocator_free_dma (unsigned long address); 89 - 90 - This function is the reverse of the previous one. If a driver 91 - doesn't free the DMA memory it allocated, the allocator will 92 - consider such memory as busy. Note, however, that 93 - allocator_cleanup() calls kfree() on every region it reclaimed, 94 - so that a driver with the allocator linked in can avoid calling 95 - allocator_free_dma() at unload time. 96 - 97 - 98 -
-294
drivers/staging/dt3155/allocator.c
··· 1 - /* 2 - * allocator.c -- allocate after high_memory, if available 3 - * 4 - * NOTE: this is different from my previous allocator, the one that 5 - * assembles pages, which revealed itself both slow and unreliable. 6 - * 7 - * Copyright (C) 1998 rubini@linux.it (Alessandro Rubini) 8 - * 9 - * This program is free software; you can redistribute it and/or modify 10 - * it under the terms of the GNU General Public License as published by 11 - * the Free Software Foundation; either version 2 of the License, or 12 - * (at your option) any later version. 13 - * 14 - * This program is distributed in the hope that it will be useful, 15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 - * GNU General Public License for more details. 18 - * 19 - * You should have received a copy of the GNU General Public License 20 - * along with this program; if not, write to the Free Software 21 - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 - * 23 - 24 - -- Changes -- 25 - 26 - Date Programmer Description of changes made 27 - ------------------------------------------------------------------- 28 - 02-Aug-2002 NJC allocator now steps in 1MB increments, rather 29 - than doubling its size each time. 30 - Also, allocator_init(u32 *) now returns 31 - (in the first arg) the size of the free 32 - space. This is no longer consistent with 33 - using the allocator as a module, and some changes 34 - may be necessary for that purpose. This was 35 - designed to work with the DT3155 driver, in 36 - stand alone mode only!!! 37 - 26-Oct-2009 SS Port to 2.6.30 kernel. 38 - */ 39 - 40 - 41 - #ifndef __KERNEL__ 42 - # define __KERNEL__ 43 - #endif 44 - #ifndef MODULE 45 - # define MODULE 46 - #endif 47 - 48 - 49 - #include <linux/sched.h> 50 - #include <linux/kernel.h> 51 - #include <linux/fs.h> 52 - #include <linux/proc_fs.h> 53 - #include <linux/errno.h> 54 - #include <linux/types.h> 55 - #include <linux/mm.h> /* PAGE_ALIGN() */ 56 - #include <linux/io.h> 57 - #include <linux/slab.h> 58 - 59 - #include <asm/page.h> 60 - 61 - #include "allocator.h" 62 - 63 - /*#define ALL_DEBUG*/ 64 - #define ALL_MSG "allocator: " 65 - 66 - #undef PDEBUG /* undef it, just in case */ 67 - #ifdef ALL_DEBUG 68 - # define __static 69 - # define DUMP_LIST() dump_list() 70 - # ifdef __KERNEL__ 71 - /* This one if debugging is on, and kernel space */ 72 - # define PDEBUG(fmt, args...) printk(KERN_DEBUG ALL_MSG fmt, ## args) 73 - # else 74 - /* This one for user space */ 75 - # define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args) 76 - # endif 77 - #else 78 - # define PDEBUG(fmt, args...) /* not debugging: nothing */ 79 - # define DUMP_LIST() 80 - # define __static static 81 - #endif 82 - 83 - #undef PDEBUGG 84 - #define PDEBUGG(fmt, args...) 85 - /*#define PDEBUGG(fmt, args...) printk( KERN_DEBUG ALL_MSG fmt, ## args)*/ 86 - 87 - 88 - static int allocator_himem = 1; /* 0 = probe, pos. = megs, neg. = disable */ 89 - static int allocator_step = 1; /* This is the step size in MB */ 90 - static int allocator_probe = 1; /* This is a flag -- 1=probe, 0=don't probe */ 91 - 92 - static unsigned long allocator_buffer; /* physical address */ 93 - static unsigned long allocator_buffer_size; /* kilobytes */ 94 - 95 - /* 96 - * The allocator keeps a list of DMA areas, so multiple devices 97 - * can coexist. The list is kept sorted by address 98 - */ 99 - 100 - struct allocator_struct { 101 - unsigned long address; 102 - unsigned long size; 103 - struct allocator_struct *next; 104 - }; 105 - 106 - static struct allocator_struct *allocator_list; 107 - 108 - #ifdef ALL_DEBUG 109 - static int dump_list(void) 110 - { 111 - struct allocator_struct *ptr; 112 - 113 - PDEBUG("Current list:\n"); 114 - for (ptr = allocator_list; ptr; ptr = ptr->next) 115 - PDEBUG("0x%08lx (size %likB)\n", ptr->address, ptr->size>>10); 116 - return 0; 117 - } 118 - #endif 119 - 120 - /* ======================================================================== 121 - * This function is the actual allocator. 122 - * 123 - * If space is available in high memory (as detected at load time), that 124 - * one is returned. The return value is a physical address (i.e., it can 125 - * be used straight ahead for DMA, but needs remapping for program use). 126 - */ 127 - 128 - unsigned long allocator_allocate_dma(unsigned long kilobytes, gfp_t flags) 129 - { 130 - struct allocator_struct *ptr = allocator_list, *newptr; 131 - unsigned long bytes = kilobytes << 10; 132 - 133 - /* check if high memory is available */ 134 - if (!allocator_buffer) 135 - return 0; 136 - 137 - /* Round it to a multiple of the pagesize */ 138 - bytes = PAGE_ALIGN(bytes); 139 - PDEBUG("request for %li bytes\n", bytes); 140 - 141 - while (ptr && ptr->next) { 142 - if (ptr->next->address - (ptr->address + ptr->size) >= bytes) 143 - break; /* enough space */ 144 - ptr = ptr->next; 145 - } 146 - if (!ptr->next) { 147 - DUMP_LIST(); 148 - PDEBUG("alloc failed\n"); 149 - return 0; /* end of list */ 150 - } 151 - newptr = kmalloc(sizeof(struct allocator_struct), flags); 152 - if (!newptr) 153 - return 0; 154 - 155 - /* ok, now stick it after ptr */ 156 - newptr->address = ptr->address + ptr->size; 157 - newptr->size = bytes; 158 - newptr->next = ptr->next; 159 - ptr->next = newptr; 160 - 161 - DUMP_LIST(); 162 - PDEBUG("returning 0x%08lx\n", newptr->address); 163 - return newptr->address; 164 - } 165 - 166 - int allocator_free_dma(unsigned long address) 167 - { 168 - struct allocator_struct *ptr = allocator_list, *prev; 169 - 170 - while (ptr && ptr->next) { 171 - if (ptr->next->address == address) 172 - break; 173 - ptr = ptr->next; 174 - } 175 - /* the one being freed is ptr->next */ 176 - prev = ptr; ptr = ptr->next; 177 - 178 - if (!ptr) { 179 - pr_err(ALL_MSG "free_dma but add. not allocated\n"); 180 - return -EINVAL; 181 - } 182 - PDEBUGG("freeing: %08lx (%li) next %08lx\n", ptr->address, ptr->size, 183 - ptr->next->address); 184 - prev->next = ptr->next; 185 - kfree(ptr); 186 - 187 - /* dump_list(); */ 188 - return 0; 189 - } 190 - 191 - /* ======================================================================== 192 - * Init and cleanup 193 - * 194 - * On cleanup everything is released. If the list is not empty, that a 195 - * problem of our clients 196 - */ 197 - int allocator_init(u32 *allocator_max) 198 - { 199 - /* check how much free memory is there */ 200 - void *remapped; 201 - unsigned long max; 202 - unsigned long trial_size = allocator_himem<<20; 203 - unsigned long last_trial = 0; 204 - unsigned long step = allocator_step<<20; 205 - unsigned long i = 0; 206 - struct allocator_struct *head, *tail; 207 - char test_string[] = "0123456789abcde"; /* 16 bytes */ 208 - 209 - PDEBUGG("himem = %i\n", allocator_himem); 210 - if (allocator_himem < 0) /* don't even try */ 211 - return -EINVAL; 212 - 213 - if (!trial_size) 214 - trial_size = 1<<20; /* not specified: try one meg */ 215 - 216 - while (1) { 217 - remapped = ioremap(__pa(high_memory), trial_size); 218 - if (!remapped) { 219 - PDEBUGG("%li megs failed!\n", trial_size>>20); 220 - break; 221 - } 222 - PDEBUGG("Trying %li megs (at %p, %p)\n", trial_size>>20, 223 - (void *)__pa(high_memory), remapped); 224 - for (i = last_trial; i < trial_size; i += 16) { 225 - strcpy((char *)(remapped)+i, test_string); 226 - if (strcmp((char *)(remapped)+i, test_string)) 227 - break; 228 - } 229 - iounmap((void *)remapped); 230 - schedule(); 231 - last_trial = trial_size; 232 - if (i == trial_size) 233 - trial_size += step; /* increment, if all went well */ 234 - else { 235 - PDEBUGG("%li megs copy test failed!\n", trial_size>>20); 236 - break; 237 - } 238 - if (!allocator_probe) 239 - break; 240 - } 241 - PDEBUG("%li megs (%li k, %li b)\n", i>>20, i>>10, i); 242 - allocator_buffer_size = i>>10; /* kilobytes */ 243 - allocator_buffer = __pa(high_memory); 244 - if (!allocator_buffer_size) { 245 - printk(KERN_WARNING ALL_MSG "no free high memory to use\n"); 246 - return -ENOMEM; 247 - } 248 - 249 - /* 250 - * to simplify things, always have two cells in the list: 251 - * the first and the last. This avoids some conditionals and 252 - * extra code when allocating and deallocating: we only play 253 - * in the middle of the list 254 - */ 255 - head = kmalloc(sizeof(struct allocator_struct), GFP_KERNEL); 256 - if (!head) 257 - return -ENOMEM; 258 - tail = kmalloc(sizeof(struct allocator_struct), GFP_KERNEL); 259 - if (!tail) { 260 - kfree(head); 261 - return -ENOMEM; 262 - } 263 - 264 - max = allocator_buffer_size<<10; 265 - 266 - head->size = tail->size = 0; 267 - head->address = allocator_buffer; 268 - tail->address = allocator_buffer + max; 269 - head->next = tail; 270 - tail->next = NULL; 271 - allocator_list = head; 272 - 273 - /* Back to the user code, in KB */ 274 - *allocator_max = allocator_buffer_size; 275 - 276 - return 0; /* ok, ready */ 277 - } 278 - 279 - void allocator_cleanup(void) 280 - { 281 - struct allocator_struct *ptr, *next; 282 - 283 - for (ptr = allocator_list; ptr; ptr = next) { 284 - next = ptr->next; 285 - PDEBUG("freeing list: 0x%08lx\n", ptr->address); 286 - kfree(ptr); 287 - } 288 - 289 - allocator_buffer = 0; 290 - allocator_buffer_size = 0; 291 - allocator_list = NULL; 292 - } 293 - 294 -
-28
drivers/staging/dt3155/allocator.h
··· 1 - /* 2 - * allocator.h -- prototypes for allocating high memory 3 - * 4 - * NOTE: this is different from my previous allocator, the one that 5 - * assembles pages, which revealed itself both slow and unreliable. 6 - * 7 - * Copyright (C) 1998 rubini@linux.it (Alessandro Rubini) 8 - * 9 - * This program is free software; you can redistribute it and/or modify 10 - * it under the terms of the GNU General Public License as published by 11 - * the Free Software Foundation; either version 2 of the License, or 12 - * (at your option) any later version. 13 - * 14 - * This program is distributed in the hope that it will be useful, 15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 - * GNU General Public License for more details. 18 - * 19 - * You should have received a copy of the GNU General Public License 20 - * along with this program; if not, write to the Free Software 21 - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 - * 23 - */ 24 - 25 - int allocator_free_dma(unsigned long address); 26 - unsigned long allocator_allocate_dma(unsigned long kilobytes, gfp_t flags); 27 - int allocator_init(u32 *); 28 - void allocator_cleanup(void);
-161
drivers/staging/dt3155/dt3155.h
··· 1 - /* 2 - 3 - Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, 4 - Jason Lapenta, Scott Smedley 5 - 6 - This file is part of the DT3155 Device Driver. 7 - 8 - The DT3155 Device Driver is free software; you can redistribute it 9 - and/or modify it under the terms of the GNU General Public License as 10 - published by the Free Software Foundation; either version 2 of the 11 - License, or (at your option) any later version. 12 - 13 - The DT3155 Device Driver is distributed in the hope that it will be 14 - useful, but WITHOUT ANY WARRANTY; without even the implied warranty 15 - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with the DT3155 Device Driver; if not, write to the Free 20 - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 - MA 02111-1307 USA 22 - 23 - -- Changes -- 24 - 25 - Date Programmer Description of changes made 26 - ------------------------------------------------------------------- 27 - 03-Jul-2000 JML n/a 28 - 10-Oct-2001 SS port to 2.4 kernel. 29 - 24-Jul-2002 SS remove unused code & added GPL licence. 30 - 05-Aug-2005 SS port to 2.6 kernel; make CCIR mode default. 31 - 32 - */ 33 - 34 - #ifndef _DT3155_INC 35 - #define _DT3155_INC 36 - 37 - #include <linux/types.h> 38 - #include <linux/time.h> /* struct timeval */ 39 - 40 - 41 - /* Uncomment this for 50Hz CCIR */ 42 - #define CCIR 1 43 - 44 - /* Can be 1 or 2 */ 45 - #define MAXBOARDS 1 46 - 47 - #define BOARD_MAX_BUFFS 3 48 - #define MAXBUFFERS (BOARD_MAX_BUFFS*MAXBOARDS) 49 - 50 - #define PCI_PAGE_SIZE (1 << 12) 51 - 52 - #ifdef CCIR 53 - #define DT3155_MAX_ROWS 576 54 - #define DT3155_MAX_COLS 768 55 - #define FORMAT50HZ 1 56 - #else 57 - #define DT3155_MAX_ROWS 480 58 - #define DT3155_MAX_COLS 640 59 - #define FORMAT50HZ 0 60 - #endif 61 - 62 - /* Configuration structure */ 63 - struct dt3155_config { 64 - u32 acq_mode; 65 - u32 cols, rows; 66 - u32 continuous; 67 - }; 68 - 69 - 70 - /* hold data for each frame */ 71 - struct frame_info { 72 - u32 addr; /* address of the buffer with the frame */ 73 - u32 tag; /* unique number for the frame */ 74 - struct timeval time; /* time that capture took place */ 75 - }; 76 - 77 - /* 78 - * Structure for interrupt and buffer handling. 79 - * This is the setup for 1 card 80 - */ 81 - struct dt3155_fbuffer { 82 - int nbuffers; 83 - 84 - struct frame_info frame_info[BOARD_MAX_BUFFS]; 85 - 86 - int empty_buffers[BOARD_MAX_BUFFS]; /* indexes empty frames */ 87 - int empty_len; /* Number of empty buffers */ 88 - /* Zero means empty */ 89 - 90 - int active_buf; /* Where data is currently dma'ing */ 91 - int locked_buf; /* Buffers used by user */ 92 - 93 - int ready_que[BOARD_MAX_BUFFS]; 94 - u32 ready_head; /* The most recent buffer located here */ 95 - u32 ready_len; /* The number of ready buffers */ 96 - 97 - int even_happened; 98 - int even_stopped; 99 - 100 - int stop_acquire; /* Flag to stop interrupts */ 101 - u32 frame_count; /* Counter for frames acquired by this card */ 102 - }; 103 - 104 - 105 - 106 - #define DT3155_MODE_FRAME 1 107 - #define DT3155_MODE_FIELD 2 108 - 109 - #define DT3155_SNAP 1 110 - #define DT3155_ACQ 2 111 - 112 - /* There is one status structure for each card. */ 113 - struct dt3155_status { 114 - int fixed_mode; /* if 1, we are in fixed frame mode */ 115 - u32 reg_addr; /* Register address for a single card */ 116 - u32 mem_addr; /* Buffer start addr for this card */ 117 - u32 mem_size; /* This is the amount of mem available */ 118 - u32 irq; /* this card's irq */ 119 - struct dt3155_config config; /* configuration struct */ 120 - struct dt3155_fbuffer fbuffer; /* frame buffer state struct */ 121 - u32 state; /* this card's state */ 122 - u32 device_installed; /* Flag if installed. 1=installed */ 123 - }; 124 - 125 - /* Reference to global status structure */ 126 - extern struct dt3155_status dt3155_status[MAXBOARDS]; 127 - 128 - #define DT3155_STATE_IDLE 0x00 129 - #define DT3155_STATE_FRAME 0x01 130 - #define DT3155_STATE_FLD 0x02 131 - #define DT3155_STATE_STOP 0x100 132 - #define DT3155_STATE_ERROR 0x200 133 - #define DT3155_STATE_MODE 0x0ff 134 - 135 - #define DT3155_IOC_MAGIC '!' 136 - 137 - #define DT3155_SET_CONFIG _IOW(DT3155_IOC_MAGIC, 1, struct dt3155_config) 138 - #define DT3155_GET_CONFIG _IOR(DT3155_IOC_MAGIC, 2, struct dt3155_status) 139 - #define DT3155_STOP _IO(DT3155_IOC_MAGIC, 3) 140 - #define DT3155_START _IO(DT3155_IOC_MAGIC, 4) 141 - #define DT3155_FLUSH _IO(DT3155_IOC_MAGIC, 5) 142 - #define DT3155_IOC_MAXNR 5 143 - 144 - /* Error codes */ 145 - 146 - #define DT_ERR_NO_BUFFERS 0x10000 /* not used but it might be one day */ 147 - #define DT_ERR_CORRUPT 0x20000 148 - #define DT_ERR_OVERRUN 0x30000 149 - #define DT_ERR_I2C_TIMEOUT 0x40000 150 - #define DT_ERR_MASK 0xff0000/* not used but it might be one day */ 151 - 152 - /* User code will probably want to declare one of these for each card */ 153 - struct dt3155_read { 154 - u32 offset; 155 - u32 frame_seq; 156 - u32 state; 157 - 158 - struct frame_info frame_info; 159 - }; 160 - 161 - #endif /* _DT3155_inc */
-60
drivers/staging/dt3155/dt3155.sysvinit
··· 1 - #! /bin/sh 2 - # 3 - # Module load/unload script for use with SysV-style /etc/init.d/ systems. 4 - # On a Debian system, copy this to /etc/init.d/dt3155 and then run 5 - # /usr/sbin/update-rc.d dt3155 defaults 55 6 - # to create the appropriate /etc/rc?.d/[SK]55dt3155 start/stop links. 7 - # (The "55" is arbitrary but is what I use to load this rather late.) 8 - # 9 - # Andy Dougherty Feb 22 2000 doughera@lafayette.edu 10 - # Dept. of Physics 11 - # Lafayette College, Easton PA 18042 12 - # 13 - 14 - PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 15 - 16 - # Edit to point to your local copy. 17 - FILE=/usr/local/lib/modules/dt3155/dt3155.o 18 - NAME="dt3155" 19 - DESC="dt3155 Frame Grabber module" 20 - DEV="dt3155" 21 - 22 - if test ! -f $FILE; then 23 - echo "Unable to locate $FILE" 24 - exit 0 25 - fi 26 - 27 - set -e 28 - 29 - case "$1" in 30 - start) 31 - echo -n "Loading $DESC " 32 - if /sbin/insmod -v -f $FILE; then 33 - major=`grep $DEV /proc/devices | awk "{print \\$1}"` 34 - rm -f /dev/dt3155? 35 - mknod /dev/dt3155a c $major 0 36 - mknod /dev/dt3155b c $major 1 37 - chmod go+rw /dev/dt3155? 38 - echo 39 - else 40 - echo "$FILE not loaded." 41 - fi 42 - ;; 43 - stop) 44 - echo -n "Unloading $DESC: " 45 - if /sbin/rmmod $NAME ; then 46 - echo 47 - else 48 - echo "$DEV not removed" 49 - exit 0 50 - fi 51 - rm -f /dev/dt3155? 52 - ;; 53 - *) 54 - echo "Usage: /etc/init.d/$NAME {start|stop}" 55 - exit 1 56 - ;; 57 - esac 58 - 59 - exit 0 60 -
-1092
drivers/staging/dt3155/dt3155_drv.c
··· 1 - /* 2 - 3 - Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, 4 - Jason Lapenta, Scott Smedley, Greg Sharp 5 - 6 - This file is part of the DT3155 Device Driver. 7 - 8 - The DT3155 Device Driver is free software; you can redistribute it 9 - and/or modify it under the terms of the GNU General Public License as 10 - published by the Free Software Foundation; either version 2 of the 11 - License, or (at your option) any later version. 12 - 13 - The DT3155 Device Driver is distributed in the hope that it will be 14 - useful, but WITHOUT ANY WARRANTY; without even the implied warranty 15 - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with the DT3155 Device Driver; if not, write to the Free 20 - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 - MA 02111-1307 USA 22 - 23 - -- Changes -- 24 - 25 - Date Programmer Description of changes made 26 - ------------------------------------------------------------------- 27 - 03-Jul-2000 JML n/a 28 - 10-Oct-2001 SS port to 2.4 kernel 29 - 02-Apr-2002 SS Mods to use allocator as a standalone module; 30 - Merged John Roll's changes (john@cfa.harvard.edu) 31 - to make work with multiple boards. 32 - 02-Jul-2002 SS Merged James Rose's chages (rosejr@purdue.edu) to: 33 - * fix successive interrupt-driven captures 34 - * add select/poll support. 35 - 10-Jul-2002 GCS Add error check when ndevices > MAXBOARDS. 36 - 02-Aug-2002 GCS Fix field mode so that odd (lower) field is stored 37 - in lower half of buffer. 38 - 05-Aug-2005 SS port to 2.6 kernel. 39 - 26-Oct-2009 SS port to 2.6.30 kernel. 40 - 41 - -- Notes -- 42 - 43 - ** appended "mem=124" in lilo.conf to allow for 4megs free on my 128meg system. 44 - * using allocator.c and allocator.h from o'reilly book (alessandro rubini) 45 - ftp://ftp.systemy.it/pub/develop (see README.allocator) 46 - 47 - + might want to get rid of MAXboards for allocating initial buffer. 48 - confusing and not necessary 49 - 50 - + in dt3155_exit the MOD_IN_USE looks like it is check after it should 51 - 52 - * GFP_DMA should not be set with a PCI system (pg 291) 53 - 54 - - NJC why are only two buffers allowed? (see isr, approx line 358) 55 - 56 - */ 57 - 58 - #include <linux/module.h> 59 - #include <linux/interrupt.h> 60 - #include <linux/mutex.h> 61 - #include <linux/pci.h> 62 - #include <linux/types.h> 63 - #include <linux/poll.h> 64 - #include <linux/sched.h> 65 - #include <linux/smp_lock.h> 66 - #include <linux/io.h> 67 - 68 - #include <linux/uaccess.h> 69 - 70 - #include "dt3155.h" 71 - #include "dt3155_drv.h" 72 - #include "dt3155_isr.h" 73 - #include "dt3155_io.h" 74 - #include "allocator.h" 75 - 76 - 77 - MODULE_LICENSE("GPL"); 78 - 79 - /* Error variable. Zero means no error. */ 80 - static DEFINE_MUTEX(dt3155_mutex); 81 - int dt3155_errno = 0; 82 - 83 - #ifndef PCI_DEVICE_ID_INTEL_7116 84 - #define PCI_DEVICE_ID_INTEL_7116 0x1223 85 - #endif 86 - 87 - #define DT3155_VENDORID PCI_VENDOR_ID_INTEL 88 - #define DT3155_DEVICEID PCI_DEVICE_ID_INTEL_7116 89 - #define MAXPCI 16 90 - 91 - #ifdef DT_DEBUG 92 - #define DT_3155_DEBUG_MSG(x,y) printk(x,y) 93 - #else 94 - #define DT_3155_DEBUG_MSG(x,y) 95 - #endif 96 - 97 - /* wait queue for interrupts */ 98 - wait_queue_head_t dt3155_read_wait_queue[MAXBOARDS]; 99 - 100 - /* set to dynamicaly allocate, but it is tunable: */ 101 - /* insmod DT_3155 dt3155 dt3155_major=XX */ 102 - int dt3155_major = 0; 103 - 104 - /* The minor numbers are 0 and 1 ... they are not tunable. 105 - * They are used as the indices for the structure vectors, 106 - * and register address vectors 107 - */ 108 - 109 - /* Global structures and variables */ 110 - 111 - /* Status of each device */ 112 - struct dt3155_status dt3155_status[MAXBOARDS]; 113 - 114 - /* kernel logical address of the board */ 115 - static void __iomem *dt3155_lbase[MAXBOARDS] = { NULL 116 - #if MAXBOARDS == 2 117 - , NULL 118 - #endif 119 - }; 120 - 121 - u32 dt3155_dev_open[MAXBOARDS] = {0 122 - #if MAXBOARDS == 2 123 - , 0 124 - #endif 125 - }; 126 - 127 - u32 ndevices = 0; 128 - u32 unique_tag = 0;; 129 - 130 - 131 - /* 132 - * Stops interrupt generation right away and resets the status 133 - * to idle. I don't know why this works and the other way doesn't. 134 - * (James Rose) 135 - */ 136 - static void quick_stop (int minor) 137 - { 138 - struct dt3155_status *dts = &dt3155_status[minor]; 139 - struct dt3155_fbuffer *fb = &dts->fbuffer; 140 - 141 - // TODO: scott was here 142 - #if 1 143 - INT_CSR_R int_csr_r; 144 - 145 - int_csr_r.reg = readl(dt3155_lbase[minor] + INT_CSR); 146 - /* disable interrupts */ 147 - int_csr_r.fld.FLD_END_EVE_EN = 0; 148 - int_csr_r.fld.FLD_END_ODD_EN = 0; 149 - writel(int_csr_r.reg, dt3155_lbase[minor] + INT_CSR); 150 - 151 - dts->state &= ~(DT3155_STATE_STOP|0xff); 152 - /* mark the system stopped: */ 153 - dts->state |= DT3155_STATE_IDLE; 154 - fb->stop_acquire = 0; 155 - fb->even_stopped = 0; 156 - #else 157 - dts->state |= DT3155_STATE_STOP; 158 - fb->stop_acquire = 1; 159 - #endif 160 - 161 - } 162 - 163 - 164 - /***************************************************** 165 - * dt3155_isr() Interrupt service routien 166 - * 167 - * - looks like this isr supports IRQ sharing (or could) JML 168 - * - Assumes irq's are disabled, via SA_INTERRUPT flag 169 - * being set in request_irq() call from dt3155_init() 170 - *****************************************************/ 171 - static void dt3155_isr(int irq, void *dev_id, struct pt_regs *regs) 172 - { 173 - int minor = -1; 174 - int index; 175 - unsigned long flags; 176 - u32 buffer_addr; 177 - void __iomem *mmio; 178 - struct dt3155_status *dts; 179 - struct dt3155_fbuffer *fb; 180 - INT_CSR_R int_csr_r; 181 - CSR1_R csr1_r; 182 - I2C_EVEN_CSR i2c_even_csr; 183 - I2C_ODD_CSR i2c_odd_csr; 184 - 185 - /* find out who issued the interrupt */ 186 - for (index = 0; index < ndevices; index++) { 187 - if(dev_id == (void*) &dt3155_status[index]) 188 - { 189 - minor = index; 190 - break; 191 - } 192 - } 193 - 194 - /* hopefully we should not get here */ 195 - if (minor < 0 || minor >= MAXBOARDS) { 196 - printk(KERN_ERR "dt3155_isr called with invalid dev_id\n"); 197 - return; 198 - } 199 - 200 - mmio = dt3155_lbase[minor]; 201 - dts = &dt3155_status[minor]; 202 - fb = &dts->fbuffer; 203 - 204 - /* Check for corruption and set a flag if so */ 205 - csr1_r.reg = readl(mmio + CSR1); 206 - 207 - if ((csr1_r.fld.FLD_CRPT_EVE) || (csr1_r.fld.FLD_CRPT_ODD)) 208 - { 209 - /* TODO: this should probably stop acquisition */ 210 - /* and set some flags so that dt3155_read */ 211 - /* returns an error next time it is called */ 212 - dt3155_errno = DT_ERR_CORRUPT; 213 - printk(KERN_ERR "dt3155: corrupt field\n"); 214 - return; 215 - } 216 - 217 - int_csr_r.reg = readl(mmio + INT_CSR); 218 - 219 - /* Handle the even field ... */ 220 - if (int_csr_r.fld.FLD_END_EVE) 221 - { 222 - if ((dts->state & DT3155_STATE_MODE) == DT3155_STATE_FLD) 223 - { 224 - fb->frame_count++; 225 - } 226 - 227 - ReadI2C(mmio, EVEN_CSR, &i2c_even_csr.reg); 228 - 229 - /* Clear the interrupt? */ 230 - int_csr_r.fld.FLD_END_EVE = 1; 231 - 232 - /* disable the interrupt if last field */ 233 - if (fb->stop_acquire) 234 - { 235 - printk(KERN_INFO "dt3155: even stopped.\n"); 236 - fb->even_stopped = 1; 237 - if (i2c_even_csr.fld.SNGL_EVE) 238 - { 239 - int_csr_r.fld.FLD_END_EVE_EN = 0; 240 - } 241 - else 242 - { 243 - i2c_even_csr.fld.SNGL_EVE = 1; 244 - } 245 - } 246 - 247 - writel(int_csr_r.reg, mmio + INT_CSR); 248 - 249 - /* Set up next DMA if we are doing FIELDS */ 250 - if ((dts->state & DT3155_STATE_MODE) == DT3155_STATE_FLD) 251 - { 252 - /* GCS (Aug 2, 2002) -- In field mode, dma the odd field 253 - into the lower half of the buffer */ 254 - const u32 stride = dts->config.cols; 255 - buffer_addr = fb->frame_info[fb->active_buf].addr + 256 - (DT3155_MAX_ROWS / 2) * stride; 257 - local_save_flags(flags); 258 - local_irq_disable(); 259 - wake_up_interruptible(&dt3155_read_wait_queue[minor]); 260 - 261 - /* Set up the DMA address for the next field */ 262 - local_irq_restore(flags); 263 - writel(buffer_addr, mmio + ODD_DMA_START); 264 - } 265 - 266 - /* Check for errors. */ 267 - i2c_even_csr.fld.DONE_EVE = 1; 268 - if (i2c_even_csr.fld.ERROR_EVE) 269 - dt3155_errno = DT_ERR_OVERRUN; 270 - 271 - WriteI2C(mmio, EVEN_CSR, i2c_even_csr.reg); 272 - 273 - /* Note that we actually saw an even field meaning */ 274 - /* that subsequent odd field complete the frame */ 275 - fb->even_happened = 1; 276 - 277 - /* recording the time that the even field finished, this should be */ 278 - /* about time in the middle of the frame */ 279 - do_gettimeofday(&fb->frame_info[fb->active_buf].time); 280 - return; 281 - } 282 - 283 - /* ... now handle the odd field */ 284 - if (int_csr_r.fld.FLD_END_ODD) 285 - { 286 - ReadI2C(mmio, ODD_CSR, &i2c_odd_csr.reg); 287 - 288 - /* Clear the interrupt? */ 289 - int_csr_r.fld.FLD_END_ODD = 1; 290 - 291 - if (fb->even_happened || 292 - (dts->state & DT3155_STATE_MODE) == DT3155_STATE_FLD) 293 - { 294 - fb->frame_count++; 295 - } 296 - 297 - if (fb->stop_acquire && fb->even_stopped) 298 - { 299 - printk(KERN_DEBUG "dt3155: stopping odd..\n"); 300 - if (i2c_odd_csr.fld.SNGL_ODD) 301 - { 302 - /* disable interrupts */ 303 - int_csr_r.fld.FLD_END_ODD_EN = 0; 304 - dts->state &= ~(DT3155_STATE_STOP|0xff); 305 - 306 - /* mark the system stopped: */ 307 - dts->state |= DT3155_STATE_IDLE; 308 - fb->stop_acquire = 0; 309 - fb->even_stopped = 0; 310 - 311 - printk(KERN_DEBUG "dt3155: state is now %x\n", dts->state); 312 - } 313 - else 314 - { 315 - i2c_odd_csr.fld.SNGL_ODD = 1; 316 - } 317 - } 318 - 319 - writel(int_csr_r.reg, mmio + INT_CSR); 320 - 321 - /* if the odd field has been acquired, then */ 322 - /* change the next dma location for both fields */ 323 - /* and wake up the process if sleeping */ 324 - if (fb->even_happened || 325 - (dts->state & DT3155_STATE_MODE) == DT3155_STATE_FLD) 326 - { 327 - 328 - local_save_flags(flags); 329 - local_irq_disable(); 330 - 331 - #ifdef DEBUG_QUES_B 332 - printques(fb); 333 - #endif 334 - if (fb->nbuffers > 2) 335 - { 336 - if (!are_empty_buffers(fb)) 337 - { 338 - /* The number of active + locked buffers is 339 - * at most 2, and since there are none empty, there 340 - * must be at least nbuffers-2 ready buffers. 341 - * This is where we 'drop frames', oldest first. */ 342 - push_empty(fb, pop_ready(fb)); 343 - } 344 - 345 - /* The ready_que can't be full, since we know 346 - * there is one active buffer right now, so it's safe 347 - * to push the active buf on the ready_que. */ 348 - push_ready(fb, fb->active_buf); 349 - /* There's at least 1 empty -- make it active */ 350 - fb->active_buf = pop_empty(fb); 351 - fb->frame_info[fb->active_buf].tag = ++unique_tag; 352 - } 353 - else /* nbuffers == 2, special case */ 354 - { /* There is 1 active buffer. 355 - * If there is a locked buffer, keep the active buffer 356 - * the same -- that means we drop a frame. 357 - */ 358 - if (fb->locked_buf < 0) 359 - { 360 - push_ready(fb, fb->active_buf); 361 - if (are_empty_buffers(fb)) 362 - { 363 - fb->active_buf = pop_empty(fb); 364 - } 365 - else 366 - { /* no empty or locked buffers, so use a readybuf */ 367 - fb->active_buf = pop_ready(fb); 368 - } 369 - } 370 - } 371 - 372 - #ifdef DEBUG_QUES_B 373 - printques(fb); 374 - #endif 375 - 376 - fb->even_happened = 0; 377 - 378 - wake_up_interruptible(&dt3155_read_wait_queue[minor]); 379 - 380 - local_irq_restore(flags); 381 - } 382 - 383 - 384 - /* Set up the DMA address for the next frame/field */ 385 - buffer_addr = fb->frame_info[fb->active_buf].addr; 386 - if ((dts->state & DT3155_STATE_MODE) == DT3155_STATE_FLD) 387 - { 388 - writel(buffer_addr, mmio + EVEN_DMA_START); 389 - } 390 - else 391 - { 392 - writel(buffer_addr, mmio + EVEN_DMA_START); 393 - 394 - writel(buffer_addr + dts->config.cols, mmio + ODD_DMA_START); 395 - } 396 - 397 - /* Do error checking */ 398 - i2c_odd_csr.fld.DONE_ODD = 1; 399 - if (i2c_odd_csr.fld.ERROR_ODD) 400 - dt3155_errno = DT_ERR_OVERRUN; 401 - 402 - WriteI2C(mmio, ODD_CSR, i2c_odd_csr.reg); 403 - 404 - return; 405 - } 406 - /* If we get here, the Odd Field wasn't it either... */ 407 - printk(KERN_DEBUG "neither even nor odd. shared perhaps?\n"); 408 - } 409 - 410 - /***************************************************** 411 - * init_isr(int minor) 412 - * turns on interupt generation for the card 413 - * designated by "minor". 414 - * It is called *only* from inside ioctl(). 415 - *****************************************************/ 416 - static void dt3155_init_isr(int minor) 417 - { 418 - struct dt3155_status *dts = &dt3155_status[minor]; 419 - struct dt3155_fbuffer *fb = &dts->fbuffer; 420 - void __iomem *mmio = dt3155_lbase[minor]; 421 - u32 dma_addr = fb->frame_info[fb->active_buf].addr; 422 - const u32 stride = dts->config.cols; 423 - CSR1_R csr1_r; 424 - INT_CSR_R int_csr_r; 425 - I2C_CSR2 i2c_csr2; 426 - 427 - switch (dts->state & DT3155_STATE_MODE) 428 - { 429 - case DT3155_STATE_FLD: 430 - { 431 - writel(dma_addr, mmio + EVEN_DMA_START); 432 - writel(0, mmio + EVEN_DMA_STRIDE); 433 - writel(0, mmio + ODD_DMA_STRIDE); 434 - break; 435 - } 436 - 437 - case DT3155_STATE_FRAME: 438 - default: 439 - { 440 - writel(dma_addr, mmio + EVEN_DMA_START); 441 - writel(dma_addr + stride, mmio + ODD_DMA_START); 442 - writel(stride, mmio + EVEN_DMA_STRIDE); 443 - writel(stride, mmio + ODD_DMA_STRIDE); 444 - break; 445 - } 446 - } 447 - 448 - /* 50/60 Hz should be set before this point but let's make sure it is */ 449 - /* right anyway */ 450 - 451 - ReadI2C(mmio, CSR2, &i2c_csr2.reg); 452 - i2c_csr2.fld.HZ50 = FORMAT50HZ; 453 - WriteI2C(mmio, CSR2, i2c_csr2.reg); 454 - 455 - /* enable busmaster chip, clear flags */ 456 - 457 - /* 458 - * TODO: 459 - * shouldn't we be concered with continuous values of 460 - * DT3155_SNAP & DT3155_ACQ here? (SS) 461 - */ 462 - 463 - csr1_r.reg = 0; 464 - csr1_r.fld.CAP_CONT_EVE = 1; /* use continuous capture bits to */ 465 - csr1_r.fld.CAP_CONT_ODD = 1; /* enable */ 466 - csr1_r.fld.FLD_DN_EVE = 1; /* writing a 1 clears flags */ 467 - csr1_r.fld.FLD_DN_ODD = 1; 468 - csr1_r.fld.SRST = 1; /* reset - must be 1 */ 469 - csr1_r.fld.FIFO_EN = 1; /* fifo control - must be 1 */ 470 - csr1_r.fld.FLD_CRPT_EVE = 1; /* writing a 1 clears flags */ 471 - csr1_r.fld.FLD_CRPT_ODD = 1; 472 - 473 - writel(csr1_r.reg, mmio + CSR1); 474 - 475 - /* Enable interrupts at the end of each field */ 476 - 477 - int_csr_r.reg = 0; 478 - int_csr_r.fld.FLD_END_EVE_EN = 1; 479 - int_csr_r.fld.FLD_END_ODD_EN = 1; 480 - int_csr_r.fld.FLD_START_EN = 0; 481 - 482 - writel(int_csr_r.reg, mmio + INT_CSR); 483 - 484 - /* start internal BUSY bits */ 485 - 486 - ReadI2C(mmio, CSR2, &i2c_csr2.reg); 487 - i2c_csr2.fld.BUSY_ODD = 1; 488 - i2c_csr2.fld.BUSY_EVE = 1; 489 - WriteI2C(mmio, CSR2, i2c_csr2.reg); 490 - 491 - /* Now its up to the interrupt routine!! */ 492 - 493 - return; 494 - } 495 - 496 - 497 - /***************************************************** 498 - * ioctl() 499 - * 500 - *****************************************************/ 501 - static int dt3155_ioctl(struct inode *inode, 502 - struct file *file, 503 - unsigned int cmd, 504 - unsigned long arg) 505 - { 506 - int minor = MINOR(inode->i_rdev); /* What device are we ioctl()'ing? */ 507 - void __user *up = (void __user *)arg; 508 - struct dt3155_status *dts = &dt3155_status[minor]; 509 - struct dt3155_fbuffer *fb = &dts->fbuffer; 510 - 511 - if (minor >= MAXBOARDS || minor < 0) 512 - return -ENODEV; 513 - 514 - /* make sure it is valid command */ 515 - if (_IOC_NR(cmd) > DT3155_IOC_MAXNR) 516 - { 517 - printk(KERN_INFO "DT3155: invalid IOCTL(0x%x)\n", cmd); 518 - printk(KERN_INFO "DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n", 519 - (unsigned int)DT3155_GET_CONFIG, 520 - (unsigned int)DT3155_SET_CONFIG, 521 - (unsigned int)DT3155_START, 522 - (unsigned int)DT3155_STOP, 523 - (unsigned int)DT3155_FLUSH); 524 - return -EINVAL; 525 - } 526 - 527 - switch (cmd) 528 - { 529 - case DT3155_SET_CONFIG: 530 - { 531 - if (dts->state != DT3155_STATE_IDLE) 532 - return -EBUSY; 533 - 534 - { 535 - struct dt3155_config tmp; 536 - if (copy_from_user(&tmp, up, sizeof(tmp))) 537 - return -EFAULT; 538 - /* check for valid settings */ 539 - if (tmp.rows > DT3155_MAX_ROWS || 540 - tmp.cols > DT3155_MAX_COLS || 541 - (tmp.acq_mode != DT3155_MODE_FRAME && 542 - tmp.acq_mode != DT3155_MODE_FIELD) || 543 - (tmp.continuous != DT3155_SNAP && 544 - tmp.continuous != DT3155_ACQ)) 545 - { 546 - return -EINVAL; 547 - } 548 - dts->config = tmp; 549 - } 550 - return 0; 551 - } 552 - case DT3155_GET_CONFIG: 553 - { 554 - if (copy_to_user(up, dts, sizeof(*dts))) 555 - return -EFAULT; 556 - return 0; 557 - } 558 - case DT3155_FLUSH: /* Flushes the buffers -- ensures fresh data */ 559 - { 560 - if (dts->state != DT3155_STATE_IDLE) 561 - return -EBUSY; 562 - return dt3155_flush(fb); 563 - } 564 - case DT3155_STOP: 565 - { 566 - if (dts->state & DT3155_STATE_STOP || fb->stop_acquire) 567 - return -EBUSY; 568 - 569 - if (dts->state == DT3155_STATE_IDLE) 570 - return 0; 571 - 572 - quick_stop(minor); 573 - if (copy_to_user(up, dts, sizeof(*dts))) 574 - return -EFAULT; 575 - return 0; 576 - } 577 - case DT3155_START: 578 - { 579 - if (dts->state != DT3155_STATE_IDLE) 580 - return -EBUSY; 581 - 582 - fb->stop_acquire = 0; 583 - fb->frame_count = 0; 584 - 585 - /* Set the MODE in the status -- we default to FRAME */ 586 - if (dts->config.acq_mode == DT3155_MODE_FIELD) 587 - { 588 - dts->state = DT3155_STATE_FLD; 589 - } 590 - else 591 - { 592 - dts->state = DT3155_STATE_FRAME; 593 - } 594 - 595 - dt3155_init_isr(minor); 596 - if (copy_to_user(up, dts, sizeof(*dts))) 597 - return -EFAULT; 598 - return 0; 599 - } 600 - default: 601 - { 602 - printk(KERN_INFO "DT3155: invalid IOCTL(0x%x)\n", cmd); 603 - printk(KERN_INFO "DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n", 604 - (unsigned int)DT3155_GET_CONFIG, 605 - (unsigned int)DT3155_SET_CONFIG, 606 - DT3155_START, DT3155_STOP, DT3155_FLUSH); 607 - return -ENOSYS; 608 - } 609 - } 610 - return -ENOSYS; 611 - } 612 - 613 - /***************************************************** 614 - * mmap() 615 - * 616 - * only allow the user to mmap the registers and buffer 617 - * It is quite possible that this is broken, since the 618 - * addition of of the capacity for two cards!!!!!!!! 619 - * It *looks* like it should work but since I'm not 620 - * sure how to use it, I'm not actually sure. (NJC? ditto by SS) 621 - *****************************************************/ 622 - static int dt3155_mmap (struct file * file, struct vm_area_struct * vma) 623 - { 624 - /* which device are we mmapping? */ 625 - int minor = MINOR(file->f_dentry->d_inode->i_rdev); 626 - struct dt3155_status *dts = &dt3155_status[minor]; 627 - unsigned long offset; 628 - offset = vma->vm_pgoff << PAGE_SHIFT; 629 - 630 - if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC)) 631 - vma->vm_flags |= VM_IO; 632 - 633 - /* Don't try to swap out physical pages.. */ 634 - vma->vm_flags |= VM_RESERVED; 635 - 636 - /* they are mapping the registers or the buffer */ 637 - if ((offset == dts->reg_addr && 638 - vma->vm_end - vma->vm_start == PCI_PAGE_SIZE) || 639 - (offset == dts->mem_addr && 640 - vma->vm_end - vma->vm_start == dts->mem_size)) 641 - { 642 - if (remap_pfn_range(vma, 643 - vma->vm_start, 644 - offset >> PAGE_SHIFT, 645 - vma->vm_end - vma->vm_start, 646 - vma->vm_page_prot)) { 647 - printk(KERN_INFO "DT3155: remap_page_range() failed.\n"); 648 - return -EAGAIN; 649 - } 650 - } 651 - else 652 - { 653 - printk(KERN_INFO "DT3155: dt3155_mmap() bad call.\n"); 654 - return -ENXIO; 655 - } 656 - 657 - return 0; 658 - } 659 - 660 - 661 - /***************************************************** 662 - * open() 663 - * 664 - * Our special open code. 665 - * MOD_INC_USE_COUNT make sure that the driver memory is not freed 666 - * while the device is in use. 667 - *****************************************************/ 668 - static int dt3155_open(struct inode* inode, struct file* filep) 669 - { 670 - int minor = MINOR(inode->i_rdev); /* what device are we opening? */ 671 - struct dt3155_status *dts = &dt3155_status[minor]; 672 - struct dt3155_fbuffer *fb = &dts->fbuffer; 673 - 674 - if (dt3155_dev_open[minor]) { 675 - printk(KERN_INFO "DT3155: Already opened by another process.\n"); 676 - return -EBUSY; 677 - } 678 - 679 - if (dts->device_installed==0) 680 - { 681 - printk(KERN_INFO "DT3155 Open Error: No such device dt3155 minor number %d\n", 682 - minor); 683 - return -EIO; 684 - } 685 - 686 - if (dts->state != DT3155_STATE_IDLE) { 687 - printk(KERN_INFO "DT3155: Not in idle state (state = %x)\n", 688 - dts->state); 689 - return -EBUSY; 690 - } 691 - 692 - printk(KERN_INFO "DT3155: Device opened.\n"); 693 - 694 - dt3155_dev_open[minor] = 1 ; 695 - 696 - dt3155_flush(fb); 697 - 698 - /* Disable ALL interrupts */ 699 - writel(0, dt3155_lbase[minor] + INT_CSR); 700 - 701 - init_waitqueue_head(&(dt3155_read_wait_queue[minor])); 702 - 703 - return 0; 704 - } 705 - 706 - 707 - /***************************************************** 708 - * close() 709 - * 710 - * Now decrement the use count. 711 - * 712 - *****************************************************/ 713 - static int dt3155_close(struct inode *inode, struct file *filep) 714 - { 715 - int minor = MINOR(inode->i_rdev); /* which device are we closing */ 716 - struct dt3155_status *dts = &dt3155_status[minor]; 717 - 718 - if (!dt3155_dev_open[minor]) 719 - { 720 - printk(KERN_INFO "DT3155: attempt to CLOSE a not OPEN device\n"); 721 - } 722 - else 723 - { 724 - dt3155_dev_open[minor] = 0; 725 - 726 - if (dts->state != DT3155_STATE_IDLE) 727 - { 728 - quick_stop(minor); 729 - } 730 - } 731 - return 0; 732 - } 733 - 734 - /***************************************************** 735 - * read() 736 - * 737 - *****************************************************/ 738 - static ssize_t dt3155_read(struct file *filep, char __user *buf, 739 - size_t count, loff_t *ppos) 740 - { 741 - /* which device are we reading from? */ 742 - int minor = MINOR(filep->f_dentry->d_inode->i_rdev); 743 - u32 offset; 744 - int frame_index; 745 - struct dt3155_status *dts = &dt3155_status[minor]; 746 - struct dt3155_fbuffer *fb = &dts->fbuffer; 747 - struct frame_info *frame_info; 748 - 749 - /* TODO: this should check the error flag and */ 750 - /* return an error on hardware failures */ 751 - if (count != sizeof(struct dt3155_read)) 752 - { 753 - printk(KERN_INFO "DT3155 ERROR (NJC): count is not right\n"); 754 - return -EINVAL; 755 - } 756 - 757 - 758 - /* Hack here -- I'm going to allow reading even when idle. 759 - * this is so that the frames can be read after STOP has 760 - * been called. Leaving it here, commented out, as a reminder 761 - * for a short while to make sure there are no problems. 762 - * Note that if the driver is not opened in non_blocking mode, 763 - * and the device is idle, then it could sit here forever! */ 764 - 765 - /* if (dts->state == DT3155_STATE_IDLE)*/ 766 - /* return -EBUSY;*/ 767 - 768 - /* non-blocking reads should return if no data */ 769 - if (filep->f_flags & O_NDELAY) 770 - { 771 - if ((frame_index = dt3155_get_ready_buffer(fb)) < 0) { 772 - /* printk("dt3155: no buffers available (?)\n"); */ 773 - /* printques(fb); */ 774 - return -EAGAIN; 775 - } 776 - } 777 - else 778 - { 779 - /* 780 - * sleep till data arrives , or we get interrupted. 781 - * Note that wait_event_interruptible() does not actually 782 - * sleep/wait if it's condition evaluates to true upon entry. 783 - */ 784 - frame_index = dt3155_get_ready_buffer(fb); 785 - wait_event_interruptible(dt3155_read_wait_queue[minor], frame_index >= 0); 786 - 787 - if (frame_index < 0) 788 - { 789 - printk(KERN_INFO "DT3155: read: interrupted\n"); 790 - quick_stop (minor); 791 - printques(fb); 792 - return -EINTR; 793 - } 794 - } 795 - 796 - frame_info = &fb->frame_info[frame_index]; 797 - 798 - /* make this an offset */ 799 - offset = frame_info->addr - dts->mem_addr; 800 - 801 - put_user(offset, (unsigned int __user *)buf); 802 - buf += sizeof(u32); 803 - put_user(fb->frame_count, (unsigned int __user *)buf); 804 - buf += sizeof(u32); 805 - put_user(dts->state, (unsigned int __user *)buf); 806 - buf += sizeof(u32); 807 - if (copy_to_user(buf, frame_info, sizeof(*frame_info))) 808 - return -EFAULT; 809 - 810 - return sizeof(struct dt3155_read); 811 - } 812 - 813 - static unsigned int dt3155_poll (struct file * filp, poll_table *wait) 814 - { 815 - int minor = MINOR(filp->f_dentry->d_inode->i_rdev); 816 - struct dt3155_status *dts = &dt3155_status[minor]; 817 - struct dt3155_fbuffer *fb = &dts->fbuffer; 818 - 819 - if (!is_ready_buf_empty(fb)) 820 - return POLLIN | POLLRDNORM; 821 - 822 - poll_wait (filp, &dt3155_read_wait_queue[minor], wait); 823 - 824 - return 0; 825 - } 826 - 827 - static long 828 - dt3155_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 829 - { 830 - int ret; 831 - 832 - mutex_lock(&dt3155_mutex); 833 - ret = dt3155_ioctl(file->f_path.dentry->d_inode, file, cmd, arg); 834 - mutex_unlock(&dt3155_mutex); 835 - 836 - return ret; 837 - } 838 - 839 - /***************************************************** 840 - * file operations supported by DT3155 driver 841 - * needed by dt3155_init 842 - * register_chrdev 843 - *****************************************************/ 844 - static struct file_operations dt3155_fops = { 845 - .read = dt3155_read, 846 - .unlocked_ioctl = dt3155_unlocked_ioctl, 847 - .mmap = dt3155_mmap, 848 - .poll = dt3155_poll, 849 - .open = dt3155_open, 850 - .release = dt3155_close 851 - }; 852 - 853 - 854 - /***************************************************** 855 - * find_PCI(); 856 - * 857 - * PCI has been totally reworked in 2.1.. 858 - *****************************************************/ 859 - static int find_PCI (void) 860 - { 861 - struct pci_dev *pci_dev = NULL; 862 - struct dt3155_status *dts; 863 - int error, pci_index = 0; 864 - unsigned short rev_device; 865 - unsigned long base; 866 - unsigned char irq; 867 - 868 - while ((pci_dev = pci_get_device 869 - (DT3155_VENDORID, DT3155_DEVICEID, pci_dev)) != NULL) 870 - { 871 - dts = &dt3155_status[pci_index++]; 872 - 873 - /* Is it really there? */ 874 - if ((error = 875 - pci_read_config_word(pci_dev, PCI_CLASS_DEVICE, &rev_device))) 876 - continue; 877 - 878 - /* Found a board */ 879 - DT_3155_DEBUG_MSG("DT3155: Device number %d \n", pci_index); 880 - 881 - /* Make sure the driver was compiled with enough buffers to handle 882 - this many boards */ 883 - if (pci_index > MAXBOARDS) { 884 - printk(KERN_ERR "DT3155: Found %d devices, but driver only configured " 885 - "for %d devices\n" 886 - "DT3155: Please change MAXBOARDS in dt3155.h\n", 887 - pci_index, MAXBOARDS); 888 - goto err; 889 - } 890 - 891 - /* Now, just go out and make sure that this/these device(s) is/are 892 - actually mapped into the kernel address space */ 893 - if ((error = pci_read_config_dword(pci_dev, PCI_BASE_ADDRESS_0, 894 - (u32 *) &base))) 895 - { 896 - printk(KERN_INFO "DT3155: Was not able to find device\n"); 897 - goto err; 898 - } 899 - 900 - DT_3155_DEBUG_MSG("DT3155: Base address 0 for device is %lx \n", base); 901 - dts->reg_addr = base; 902 - 903 - /* Remap the base address to a logical address through which we 904 - * can access it. */ 905 - dt3155_lbase[pci_index - 1] = ioremap(base, PCI_PAGE_SIZE); 906 - dts->reg_addr = base; 907 - DT_3155_DEBUG_MSG("DT3155: New logical address is %p \n", 908 - dt3155_lbase[pci_index-1]); 909 - if (!dt3155_lbase[pci_index-1]) 910 - { 911 - printk(KERN_INFO "DT3155: Unable to remap control registers\n"); 912 - goto err; 913 - } 914 - 915 - if ((error = pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &irq))) 916 - { 917 - printk(KERN_INFO "DT3155: Was not able to find device\n"); 918 - goto err; 919 - } 920 - 921 - DT_3155_DEBUG_MSG("DT3155: IRQ is %d \n",irq); 922 - dts->irq = irq; 923 - /* Set flag: kth device found! */ 924 - dts->device_installed = 1; 925 - printk(KERN_INFO "DT3155: Installing device %d w/irq %d and address %p\n", 926 - pci_index, 927 - dts->irq, 928 - dt3155_lbase[pci_index-1]); 929 - 930 - } 931 - ndevices = pci_index; 932 - 933 - return 0; 934 - 935 - err: 936 - pci_dev_put(pci_dev); 937 - return -EIO; 938 - } 939 - 940 - u32 allocatorAddr = 0; 941 - 942 - 943 - static int __init dt3155_init(void) 944 - { 945 - struct dt3155_status *dts; 946 - int index; 947 - int rcode = 0; 948 - char *devname[MAXBOARDS]; 949 - 950 - devname[0] = "dt3155a"; 951 - #if MAXBOARDS == 2 952 - devname[1] = "dt3155b"; 953 - #endif 954 - 955 - printk(KERN_INFO "DT3155: Loading module...\n"); 956 - 957 - /* Register the device driver */ 958 - rcode = register_chrdev(dt3155_major, "dt3155", &dt3155_fops); 959 - if(rcode < 0) 960 - { 961 - printk(KERN_INFO "DT3155: register_chrdev failed \n"); 962 - return rcode; 963 - } 964 - 965 - if(dt3155_major == 0) 966 - dt3155_major = rcode; /* dynamic */ 967 - 968 - 969 - /* init the status variables. */ 970 - /* DMA memory is taken care of in setup_buffers() */ 971 - for (index = 0; index < MAXBOARDS; index++) 972 - { 973 - dts = &dt3155_status[index]; 974 - 975 - dts->config.acq_mode = DT3155_MODE_FRAME; 976 - dts->config.continuous = DT3155_ACQ; 977 - dts->config.cols = DT3155_MAX_COLS; 978 - dts->config.rows = DT3155_MAX_ROWS; 979 - dts->state = DT3155_STATE_IDLE; 980 - 981 - /* find_PCI() will check if devices are installed; */ 982 - /* first assume they're not: */ 983 - dts->mem_addr = 0; 984 - dts->mem_size = 0; 985 - dts->state = DT3155_STATE_IDLE; 986 - dts->device_installed = 0; 987 - } 988 - 989 - /* Now let's find the hardware. find_PCI() will set ndevices to the 990 - * number of cards found in this machine. */ 991 - { 992 - if ((rcode = find_PCI()) != 0) 993 - { 994 - printk(KERN_INFO "DT3155 error: find_PCI() failed to find dt3155 board(s)\n"); 995 - unregister_chrdev(dt3155_major, "dt3155"); 996 - return rcode; 997 - } 998 - } 999 - 1000 - /* Ok, time to setup the frame buffers */ 1001 - if((rcode = dt3155_setup_buffers(&allocatorAddr)) < 0) 1002 - { 1003 - printk(KERN_INFO "DT3155: Error: setting up buffer not large enough."); 1004 - unregister_chrdev(dt3155_major, "dt3155"); 1005 - return rcode; 1006 - } 1007 - 1008 - /* If we are this far, then there is enough RAM */ 1009 - /* for the buffers: Print the configuration. */ 1010 - for( index = 0; index < ndevices; index++) 1011 - { 1012 - dts = &dt3155_status[index]; 1013 - 1014 - printk(KERN_INFO "DT3155: Device = %d; acq_mode = %d;" 1015 - "continuous = %d; cols = %d; rows = %d;\n", 1016 - index , 1017 - dts->config.acq_mode, 1018 - dts->config.continuous, 1019 - dts->config.cols, 1020 - dts->config.rows); 1021 - printk(KERN_INFO "DT3155: m_addr = 0x%x; m_size = %ld;" 1022 - "state = %d; device_installed = %d\n", 1023 - dts->mem_addr, 1024 - (long int)dts->mem_size, 1025 - dts->state, 1026 - dts->device_installed); 1027 - } 1028 - 1029 - /* Disable ALL interrupts */ 1030 - for( index = 0; index < ndevices; index++) 1031 - { 1032 - dts = &dt3155_status[index]; 1033 - 1034 - writel(0, dt3155_lbase[index] + INT_CSR); 1035 - if(dts->device_installed) 1036 - { 1037 - /* 1038 - * This driver *looks* like it can handle sharing interrupts, 1039 - * but I can't actually test myself. I've had reports that it 1040 - * DOES work so I'll enable it for now. This comment will remain 1041 - * as a reminder in case any problems arise. (SS) 1042 - */ 1043 - /* in older kernels flags are: SA_SHIRQ | SA_INTERRUPT */ 1044 - rcode = request_irq(dts->irq, (void *)dt3155_isr, 1045 - IRQF_SHARED | IRQF_DISABLED, devname[index], 1046 - (void *)dts); 1047 - if(rcode < 0) 1048 - { 1049 - printk(KERN_INFO "DT3155: minor %d request_irq failed for IRQ %d\n", 1050 - index, dts->irq); 1051 - unregister_chrdev(dt3155_major, "dt3155"); 1052 - return rcode; 1053 - } 1054 - } 1055 - } 1056 - 1057 - printk(KERN_INFO "DT3155: finished loading\n"); 1058 - 1059 - return 0; 1060 - } 1061 - 1062 - static void __exit dt3155_exit(void) 1063 - { 1064 - struct dt3155_status *dts; 1065 - int index; 1066 - 1067 - printk(KERN_INFO "DT3155: dt3155_exit called\n"); 1068 - 1069 - /* removed DMA allocated with the allocator */ 1070 - #ifdef STANDALONE_ALLOCATOR 1071 - if (allocatorAddr != 0) 1072 - allocator_free_dma(allocatorAddr); 1073 - #else 1074 - allocator_cleanup(); 1075 - #endif 1076 - 1077 - unregister_chrdev(dt3155_major, "dt3155"); 1078 - 1079 - for(index = 0; index < ndevices; index++) 1080 - { 1081 - dts = &dt3155_status[index]; 1082 - if(dts->device_installed == 1) 1083 - { 1084 - printk(KERN_INFO "DT3155: Freeing irq %d for device %d\n", 1085 - dts->irq, index); 1086 - free_irq(dts->irq, (void *)dts); 1087 - } 1088 - } 1089 - } 1090 - 1091 - module_init(dt3155_init); 1092 - module_exit(dt3155_exit);
-39
drivers/staging/dt3155/dt3155_drv.h
··· 1 - /* 2 - 3 - Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, 4 - Scott Smedley 5 - 6 - This file is part of the DT3155 Device Driver. 7 - 8 - The DT3155 Device Driver is free software; you can redistribute it 9 - and/or modify it under the terms of the GNU General Public License as 10 - published by the Free Software Foundation; either version 2 of the 11 - License, or (at your option) any later version. 12 - 13 - The DT3155 Device Driver is distributed in the hope that it will be 14 - useful, but WITHOUT ANY WARRANTY; without even the implied warranty 15 - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with the DT3155 Device Driver; if not, write to the Free 20 - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 - MA 02111-1307 USA 22 - */ 23 - 24 - #ifndef DT3155_DRV_INC 25 - #define DT3155_DRV_INC 26 - 27 - #ifdef __KERNEL__ 28 - #include <linux/wait.h> 29 - 30 - /* wait queue for reads */ 31 - extern wait_queue_head_t dt3155_read_wait_queue[MAXBOARDS]; 32 - #endif 33 - 34 - /* number of devices */ 35 - extern u32 ndevices; 36 - 37 - extern int dt3155_errno; 38 - 39 - #endif
-128
drivers/staging/dt3155/dt3155_io.c
··· 1 - /* 2 - * Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, 3 - * Jason Lapenta, Scott Smedley 4 - * 5 - * This file is part of the DT3155 Device Driver. 6 - * 7 - * The DT3155 Device Driver is free software; you can redistribute it and/or 8 - * modify it under the terms of the GNU General Public License as published by 9 - * the Free Software Foundation; either version 2 of the License, or (at your 10 - * option) any later version. 11 - * 12 - * The DT3155 Device Driver is distributed in the hope that it will be useful, 13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15 - * Public License for more details. 16 - */ 17 - 18 - /* 19 - * This file provides some basic register io routines. It is modified from 20 - * demo code provided by Data Translations. 21 - */ 22 - 23 - #include <linux/delay.h> 24 - #include <linux/io.h> 25 - 26 - #include "dt3155.h" 27 - #include "dt3155_io.h" 28 - #include "dt3155_drv.h" 29 - 30 - 31 - /* 32 - * wait_ibsyclr() 33 - * 34 - * This function handles read/write timing and r/w timeout error 35 - */ 36 - static int wait_ibsyclr(void __iomem *mmio) 37 - { 38 - IIC_CSR2_R iic_csr2_r; 39 - 40 - /* wait 100 microseconds */ 41 - udelay(100L); 42 - /* __delay(loops_per_sec/10000); */ 43 - 44 - iic_csr2_r.reg = readl(mmio + IIC_CSR2); 45 - if (iic_csr2_r.fld.NEW_CYCLE) { 46 - /* if NEW_CYCLE didn't clear */ 47 - /* TIMEOUT ERROR */ 48 - dt3155_errno = DT_ERR_I2C_TIMEOUT; 49 - return -ETIMEDOUT; 50 - } 51 - 52 - return 0; /* no error */ 53 - } 54 - 55 - /* 56 - * WriteI2C() 57 - * 58 - * This function handles writing to 8-bit DT3155 registers 59 - * 60 - * 1st parameter is pointer to 32-bit register base address 61 - * 2nd parameter is reg. index; 62 - * 3rd is value to be written 63 - */ 64 - int WriteI2C(void __iomem *mmio, u_short wIregIndex, u8 byVal) 65 - { 66 - IIC_CSR2_R iic_csr2_r; 67 - 68 - /* read 32 bit IIC_CSR2 register data into union */ 69 - iic_csr2_r.reg = readl(mmio + IIC_CSR2); 70 - 71 - /* for write operation */ 72 - iic_csr2_r.fld.DIR_RD = 0; 73 - /* I2C address of I2C register: */ 74 - iic_csr2_r.fld.DIR_ADDR = wIregIndex; 75 - /* 8 bit data to be written to I2C reg */ 76 - iic_csr2_r.fld.DIR_WR_DATA = byVal; 77 - /* will start a direct I2C cycle: */ 78 - iic_csr2_r.fld.NEW_CYCLE = 1; 79 - 80 - /* xfer union data into 32 bit IIC_CSR2 register */ 81 - writel(iic_csr2_r.reg, mmio + IIC_CSR2); 82 - 83 - /* wait for IIC cycle to finish */ 84 - return wait_ibsyclr(mmio); 85 - } 86 - 87 - /* 88 - * ReadI2C() 89 - * 90 - * This function handles reading from 8-bit DT3155 registers 91 - * 92 - * 1st parameter is pointer to 32-bit register base address 93 - * 2nd parameter is reg. index; 94 - * 3rd is adrs of value to be read 95 - */ 96 - int ReadI2C(void __iomem *mmio, u_short wIregIndex, u8 *byVal) 97 - { 98 - IIC_CSR1_R iic_csr1_r; 99 - IIC_CSR2_R iic_csr2_r; 100 - int writestat; /* status for return */ 101 - 102 - /* read 32 bit IIC_CSR2 register data into union */ 103 - iic_csr2_r.reg = readl(mmio + IIC_CSR2); 104 - 105 - /* for read operation */ 106 - iic_csr2_r.fld.DIR_RD = 1; 107 - 108 - /* I2C address of I2C register: */ 109 - iic_csr2_r.fld.DIR_ADDR = wIregIndex; 110 - 111 - /* will start a direct I2C cycle: */ 112 - iic_csr2_r.fld.NEW_CYCLE = 1; 113 - 114 - /* xfer union's data into 32 bit IIC_CSR2 register */ 115 - writel(iic_csr2_r.reg, mmio + IIC_CSR2); 116 - 117 - /* wait for IIC cycle to finish */ 118 - writestat = wait_ibsyclr(mmio); 119 - 120 - /* Next 2 commands read 32 bit IIC_CSR1 register's data into union */ 121 - /* first read data is in IIC_CSR1 */ 122 - iic_csr1_r.reg = readl(mmio + IIC_CSR1); 123 - 124 - /* now get data u8 out of register */ 125 - *byVal = (u8) iic_csr1_r.fld.RD_DATA; 126 - 127 - return writestat; 128 - }
-304
drivers/staging/dt3155/dt3155_io.h
··· 1 - /* 2 - 3 - Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, 4 - Jason Lapenta, Scott Smedley 5 - 6 - This file is part of the DT3155 Device Driver. 7 - 8 - The DT3155 Device Driver is free software; you can redistribute it 9 - and/or modify it under the terms of the GNU General Public License as 10 - published by the Free Software Foundation; either version 2 of the 11 - License, or (at your option) any later version. 12 - 13 - The DT3155 Device Driver is distributed in the hope that it will be 14 - useful, but WITHOUT ANY WARRANTY; without even the implied warranty 15 - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with the DT3155 Device Driver; if not, write to the Free 20 - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 - MA 02111-1307 USA 22 - 23 - 24 - -- Changes -- 25 - 26 - Date Programmer Description of changes made 27 - ------------------------------------------------------------------- 28 - 24-Jul-2002 SS GPL licence. 29 - 30 - */ 31 - 32 - /* This code is a modified version of examples provided by Data Translations.*/ 33 - 34 - #ifndef DT3155_IO_INC 35 - #define DT3155_IO_INC 36 - 37 - /***************** 32 bit register globals **************/ 38 - 39 - /* offsets for 32-bit memory mapped registers */ 40 - 41 - #define EVEN_DMA_START 0x000 42 - #define ODD_DMA_START 0x00C 43 - #define EVEN_DMA_STRIDE 0x018 44 - #define ODD_DMA_STRIDE 0x024 45 - #define EVEN_PIXEL_FMT 0x030 46 - #define ODD_PIXEL_FMT 0x034 47 - #define FIFO_TRIGGER 0x038 48 - #define XFER_MODE 0x03C 49 - #define CSR1 0x040 50 - #define RETRY_WAIT_CNT 0x044 51 - #define INT_CSR 0x048 52 - #define EVEN_FLD_MASK 0x04C 53 - #define ODD_FLD_MASK 0x050 54 - #define MASK_LENGTH 0x054 55 - #define FIFO_FLAG_CNT 0x058 56 - #define IIC_CLK_DUR 0x05C 57 - #define IIC_CSR1 0x060 58 - #define IIC_CSR2 0x064 59 - #define EVEN_DMA_UPPR_LMT 0x08C 60 - #define ODD_DMA_UPPR_LMT 0x090 61 - 62 - #define CLK_DUR_VAL 0x01010101 63 - 64 - 65 - 66 - /******** Assignments and Typedefs for 32 bit Memory Mapped Registers ********/ 67 - 68 - typedef union fifo_trigger_tag { 69 - u32 reg; 70 - struct { 71 - u32 PACKED:6; 72 - u32 :9; 73 - u32 PLANER:7; 74 - u32 :9; 75 - } fld; 76 - } FIFO_TRIGGER_R; 77 - 78 - typedef union xfer_mode_tag { 79 - u32 reg; 80 - struct { 81 - u32 :2; 82 - u32 FIELD_TOGGLE:1; 83 - u32 :5; 84 - u32 :2; 85 - u32 :22; 86 - } fld; 87 - } XFER_MODE_R; 88 - 89 - typedef union csr1_tag { 90 - u32 reg; 91 - struct { 92 - u32 CAP_CONT_EVE:1; 93 - u32 CAP_CONT_ODD:1; 94 - u32 CAP_SNGL_EVE:1; 95 - u32 CAP_SNGL_ODD:1; 96 - u32 FLD_DN_EVE :1; 97 - u32 FLD_DN_ODD :1; 98 - u32 SRST :1; 99 - u32 FIFO_EN :1; 100 - u32 FLD_CRPT_EVE:1; 101 - u32 FLD_CRPT_ODD:1; 102 - u32 ADDR_ERR_EVE:1; 103 - u32 ADDR_ERR_ODD:1; 104 - u32 CRPT_DIS :1; 105 - u32 RANGE_EN :1; 106 - u32 :16; 107 - } fld; 108 - } CSR1_R; 109 - 110 - typedef union retry_wait_cnt_tag { 111 - u32 reg; 112 - struct { 113 - u32 RTRY_WAIT_CNT:8; 114 - u32 :24; 115 - } fld; 116 - } RETRY_WAIT_CNT_R; 117 - 118 - typedef union int_csr_tag { 119 - u32 reg; 120 - struct { 121 - u32 FLD_END_EVE :1; 122 - u32 FLD_END_ODD :1; 123 - u32 FLD_START :1; 124 - u32 :5; 125 - u32 FLD_END_EVE_EN:1; 126 - u32 FLD_END_ODD_EN:1; 127 - u32 FLD_START_EN :1; 128 - u32 :21; 129 - } fld; 130 - } INT_CSR_R; 131 - 132 - typedef union mask_length_tag { 133 - u32 reg; 134 - struct { 135 - u32 MASK_LEN_EVE:5; 136 - u32 :11; 137 - u32 MASK_LEN_ODD:5; 138 - u32 :11; 139 - } fld; 140 - } MASK_LENGTH_R; 141 - 142 - typedef union fifo_flag_cnt_tag { 143 - u32 reg; 144 - struct { 145 - u32 AF_COUNT:7; 146 - u32 :9; 147 - u32 AE_COUNT:7; 148 - u32 :9; 149 - } fld; 150 - } FIFO_FLAG_CNT_R; 151 - 152 - typedef union iic_clk_dur { 153 - u32 reg; 154 - struct { 155 - u32 PHASE_1:8; 156 - u32 PHASE_2:8; 157 - u32 PHASE_3:8; 158 - u32 PHASE_4:8; 159 - } fld; 160 - } IIC_CLK_DUR_R; 161 - 162 - typedef union iic_csr1_tag { 163 - u32 reg; 164 - struct { 165 - u32 AUTO_EN :1; 166 - u32 BYPASS :1; 167 - u32 SDA_OUT :1; 168 - u32 SCL_OUT :1; 169 - u32 :4; 170 - u32 AUTO_ABORT :1; 171 - u32 DIRECT_ABORT:1; 172 - u32 SDA_IN :1; 173 - u32 SCL_IN :1; 174 - u32 :4; 175 - u32 AUTO_ADDR :8; 176 - u32 RD_DATA :8; 177 - } fld; 178 - } IIC_CSR1_R; 179 - 180 - /********************************** 181 - * iic_csr2_tag 182 - */ 183 - typedef union iic_csr2_tag { 184 - u32 reg; 185 - struct { 186 - u32 DIR_WR_DATA :8; 187 - u32 DIR_SUB_ADDR:8; 188 - u32 DIR_RD :1; 189 - u32 DIR_ADDR :7; 190 - u32 NEW_CYCLE :1; 191 - u32 :7; 192 - } fld; 193 - } IIC_CSR2_R; 194 - 195 - /* use for both EVEN and ODD DMA UPPER LIMITS */ 196 - 197 - /* 198 - * dma_upper_lmt_tag 199 - */ 200 - typedef union dma_upper_lmt_tag { 201 - u32 reg; 202 - struct { 203 - u32 DMA_UPPER_LMT_VAL:24; 204 - u32 :8; 205 - } fld; 206 - } DMA_UPPER_LMT_R; 207 - 208 - 209 - /***************** 8 bit I2C register globals ***********/ 210 - #define CSR2 0x010 /* indices of 8-bit I2C mapped reg's*/ 211 - #define EVEN_CSR 0x011 212 - #define ODD_CSR 0x012 213 - #define CONFIG 0x013 214 - #define DT_ID 0x01F 215 - #define X_CLIP_START 0x020 216 - #define Y_CLIP_START 0x022 217 - #define X_CLIP_END 0x024 218 - #define Y_CLIP_END 0x026 219 - #define AD_ADDR 0x030 220 - #define AD_LUT 0x031 221 - #define AD_CMD 0x032 222 - #define DIG_OUT 0x040 223 - #define PM_LUT_ADDR 0x050 224 - #define PM_LUT_DATA 0x051 225 - 226 - 227 - /******** Assignments and Typedefs for 8 bit I2C Registers********************/ 228 - 229 - typedef union i2c_csr2_tag { 230 - u8 reg; 231 - struct { 232 - u8 CHROM_FIL:1; 233 - u8 SYNC_SNTL:1; 234 - u8 HZ50:1; 235 - u8 SYNC_PRESENT:1; 236 - u8 BUSY_EVE:1; 237 - u8 BUSY_ODD:1; 238 - u8 DISP_PASS:1; 239 - } fld; 240 - } I2C_CSR2; 241 - 242 - typedef union i2c_even_csr_tag { 243 - u8 reg; 244 - struct { 245 - u8 DONE_EVE :1; 246 - u8 SNGL_EVE :1; 247 - u8 ERROR_EVE:1; 248 - u8 :5; 249 - } fld; 250 - } I2C_EVEN_CSR; 251 - 252 - typedef union i2c_odd_csr_tag { 253 - u8 reg; 254 - struct { 255 - u8 DONE_ODD:1; 256 - u8 SNGL_ODD:1; 257 - u8 ERROR_ODD:1; 258 - u8 :5; 259 - } fld; 260 - } I2C_ODD_CSR; 261 - 262 - typedef union i2c_config_tag { 263 - u8 reg; 264 - struct { 265 - u8 ACQ_MODE:2; 266 - u8 EXT_TRIG_EN:1; 267 - u8 EXT_TRIG_POL:1; 268 - u8 H_SCALE:1; 269 - u8 CLIP:1; 270 - u8 PM_LUT_SEL:1; 271 - u8 PM_LUT_PGM:1; 272 - } fld; 273 - } I2C_CONFIG; 274 - 275 - 276 - typedef union i2c_ad_cmd_tag { 277 - /* bits can have 3 different meanings depending on value of AD_ADDR */ 278 - u8 reg; 279 - /* Bt252 Command Register if AD_ADDR = 00h */ 280 - struct { 281 - u8 :2; 282 - u8 SYNC_LVL_SEL:2; 283 - u8 SYNC_CNL_SEL:2; 284 - u8 DIGITIZE_CNL_SEL1:2; 285 - } bt252_command; 286 - 287 - /* Bt252 IOUT0 register if AD_ADDR = 01h */ 288 - struct { 289 - u8 IOUT_DATA:8; 290 - } bt252_iout0; 291 - 292 - /* BT252 IOUT1 register if AD_ADDR = 02h */ 293 - struct { 294 - u8 IOUT_DATA:8; 295 - } bt252_iout1; 296 - } I2C_AD_CMD; 297 - 298 - 299 - /* access 8-bit IIC registers */ 300 - 301 - extern int ReadI2C(void __iomem *mmio, u_short wIregIndex, u8 *byVal); 302 - extern int WriteI2C(void __iomem *mmio, u_short wIregIndex, u8 byVal); 303 - 304 - #endif
-461
drivers/staging/dt3155/dt3155_isr.c
··· 1 - /* 2 - 3 - Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, 4 - Jason Lapenta, Scott Smedley, Greg Sharp 5 - 6 - This file is part of the DT3155 Device Driver. 7 - 8 - The DT3155 Device Driver is free software; you can redistribute it 9 - and/or modify it under the terms of the GNU General Public License as 10 - published by the Free Software Foundation; either version 2 of the 11 - License, or (at your option) any later version. 12 - 13 - The DT3155 Device Driver is distributed in the hope that it will be 14 - useful, but WITHOUT ANY WARRANTY; without even the implied warranty 15 - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with the DT3155 Device Driver; if not, write to the Free 20 - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 - MA 02111-1307 USA 22 - 23 - File: dt3155_isr.c 24 - Purpose: Buffer management routines, and other routines for the ISR 25 - (the actual isr is in dt3155_drv.c) 26 - 27 - -- Changes -- 28 - 29 - Date Programmer Description of changes made 30 - ------------------------------------------------------------------- 31 - 03-Jul-2000 JML n/a 32 - 02-Apr-2002 SS Mods to make work with separate allocator 33 - module; Merged John Roll's mods to make work with 34 - multiple boards. 35 - 10-Jul-2002 GCS Complete rewrite of setup_buffers to disallow 36 - buffers which span a 4MB boundary. 37 - 24-Jul-2002 SS GPL licence. 38 - 30-Jul-2002 NJC Added support for buffer loop. 39 - 31-Jul-2002 NJC Complete rewrite of buffer management 40 - 02-Aug-2002 NJC Including slab.h instead of malloc.h (no warning). 41 - Also, allocator_init() now returns allocator_max 42 - so cleaned up allocate_buffers() accordingly. 43 - 08-Aug-2005 SS port to 2.6 kernel. 44 - 45 - */ 46 - 47 - #include <asm/system.h> 48 - #include <linux/gfp.h> 49 - #include <linux/sched.h> 50 - #include <linux/types.h> 51 - 52 - #include "dt3155.h" 53 - #include "dt3155_drv.h" 54 - #include "dt3155_io.h" 55 - #include "dt3155_isr.h" 56 - #include "allocator.h" 57 - 58 - #define FOUR_MB (0x0400000) /* Can't DMA accross a 4MB boundary!*/ 59 - #define UPPER_10_BITS (0x3FF<<22) /* Can't DMA accross a 4MB boundary!*/ 60 - 61 - 62 - /****************************************************************************** 63 - * Simple array based que struct 64 - * 65 - * Some handy functions using the buffering structure. 66 - *****************************************************************************/ 67 - 68 - /*************************** 69 - * are_empty_buffers 70 - ***************************/ 71 - bool are_empty_buffers(struct dt3155_fbuffer *fb) 72 - { 73 - return fb->empty_len; 74 - } 75 - 76 - /************************** 77 - * push_empty 78 - * 79 - * This is slightly confusing. The number empty_len is the literal # 80 - * of empty buffers. After calling, empty_len-1 is the index into the 81 - * empty buffer stack. So, if empty_len == 1, there is one empty buffer, 82 - * given by fb->empty_buffers[0]. 83 - * empty_buffers should never fill up, though this is not checked. 84 - **************************/ 85 - void push_empty(struct dt3155_fbuffer *fb, int index) 86 - { 87 - fb->empty_buffers[fb->empty_len] = index; 88 - fb->empty_len++; 89 - } 90 - 91 - /************************** 92 - * pop_empty 93 - **************************/ 94 - int pop_empty(struct dt3155_fbuffer *fb) 95 - { 96 - fb->empty_len--; 97 - return fb->empty_buffers[fb->empty_len]; 98 - } 99 - 100 - /************************* 101 - * is_ready_buf_empty 102 - *************************/ 103 - bool is_ready_buf_empty(struct dt3155_fbuffer *fb) 104 - { 105 - return fb->ready_len == 0; 106 - } 107 - 108 - /************************* 109 - * is_ready_buf_full 110 - * 111 - * this should *never* be true if there are any active, locked or empty 112 - * buffers, since it corresponds to nbuffers ready buffers!! 113 - * 7/31/02: total rewrite. --NJC 114 - *************************/ 115 - bool is_ready_buf_full(struct dt3155_fbuffer *fb) 116 - { 117 - return fb->ready_len == fb->nbuffers; 118 - } 119 - 120 - /***************************************************** 121 - * push_ready 122 - *****************************************************/ 123 - void push_ready(struct dt3155_fbuffer *fb, int index) 124 - { 125 - int head = fb->ready_head; 126 - 127 - fb->ready_que[head] = index; 128 - fb->ready_head = (head + 1) % fb->nbuffers; 129 - fb->ready_len++; 130 - } 131 - 132 - /***************************************************** 133 - * get_tail 134 - * 135 - * Simply comptutes the tail given the head and the length. 136 - *****************************************************/ 137 - static int get_tail(struct dt3155_fbuffer *fb) 138 - { 139 - return (fb->ready_head - fb->ready_len + fb->nbuffers) % fb->nbuffers; 140 - } 141 - 142 - /***************************************************** 143 - * pop_ready 144 - * 145 - * This assumes that there is a ready buffer ready... should 146 - * be checked (e.g. with is_ready_buf_empty() prior to call. 147 - *****************************************************/ 148 - int pop_ready(struct dt3155_fbuffer *fb) 149 - { 150 - int tail = get_tail(fb); 151 - 152 - fb->ready_len--; 153 - return fb->ready_que[tail]; 154 - } 155 - 156 - /***************************************************** 157 - * printques 158 - *****************************************************/ 159 - void printques(struct dt3155_fbuffer *fb) 160 - { 161 - int i; 162 - 163 - printk(KERN_INFO "\n R:"); 164 - for (i = get_tail(fb); i != fb->ready_head; i++, i %= fb->nbuffers) 165 - printk(" %d ", fb->ready_que[i]); 166 - 167 - printk(KERN_INFO "\n E:"); 168 - for (i = 0; i < fb->empty_len; i++) 169 - printk(" %d ", fb->empty_buffers[i]); 170 - 171 - printk(KERN_INFO "\n A: %d", fb->active_buf); 172 - 173 - printk(KERN_INFO "\n L: %d\n", fb->locked_buf); 174 - } 175 - 176 - /***************************************************** 177 - * adjust_4MB 178 - * 179 - * If a buffer intersects the 4MB boundary, push 180 - * the start address up to the beginning of the 181 - * next 4MB chunk (assuming bufsize < 4MB). 182 - *****************************************************/ 183 - static u32 adjust_4MB(u32 buf_addr, u32 bufsize) 184 - { 185 - if (((buf_addr+bufsize) & UPPER_10_BITS) != (buf_addr & UPPER_10_BITS)) 186 - return (buf_addr+bufsize) & UPPER_10_BITS; 187 - else 188 - return buf_addr; 189 - } 190 - 191 - 192 - /***************************************************** 193 - * allocate_buffers 194 - * 195 - * Try to allocate enough memory for all requested 196 - * buffers. If there is not enough free space 197 - * try for less memory. 198 - *****************************************************/ 199 - static void allocate_buffers(u32 *buf_addr, u32* total_size_kbs, 200 - u32 bufsize) 201 - { 202 - /* Compute the minimum amount of memory guaranteed to hold all 203 - MAXBUFFERS such that no buffer crosses the 4MB boundary. 204 - Store this value in the variable "full_size" */ 205 - 206 - u32 allocator_max; 207 - u32 bufs_per_chunk = (FOUR_MB / bufsize); 208 - u32 filled_chunks = (MAXBUFFERS-1) / bufs_per_chunk; 209 - u32 leftover_bufs = MAXBUFFERS - filled_chunks * bufs_per_chunk; 210 - 211 - u32 full_size = bufsize /* possibly unusable part of 1st chunk */ 212 - + filled_chunks * FOUR_MB /* max # of completely filled 4mb chunks */ 213 - + leftover_bufs * bufsize; /* these buffs will be in a partly filled 214 - chunk at beginning or end */ 215 - 216 - u32 full_size_kbs = 1 + (full_size-1) / 1024; 217 - u32 min_size_kbs = 2*ndevices*bufsize / 1024; 218 - u32 size_kbs; 219 - 220 - /* Now, try to allocate full_size. If this fails, keep trying for 221 - less & less memory until it succeeds. */ 222 - #ifndef STANDALONE_ALLOCATOR 223 - /* initialize the allocator */ 224 - allocator_init(&allocator_max); 225 - #endif 226 - size_kbs = full_size_kbs; 227 - *buf_addr = 0; 228 - printk(KERN_INFO "DT3155: We would like to get: %d KB\n", full_size_kbs); 229 - printk(KERN_INFO "DT3155: ...but need at least: %d KB\n", min_size_kbs); 230 - printk(KERN_INFO "DT3155: ...the allocator has: %d KB\n", allocator_max); 231 - size_kbs = (full_size_kbs <= allocator_max ? full_size_kbs : allocator_max); 232 - if (size_kbs > min_size_kbs) { 233 - *buf_addr = allocator_allocate_dma(size_kbs, GFP_KERNEL); 234 - if (*buf_addr != 0) { 235 - printk(KERN_INFO "DT3155: Managed to allocate: %d KB\n", 236 - size_kbs); 237 - *total_size_kbs = size_kbs; 238 - return; 239 - } 240 - } 241 - /* If we got here, the allocation failed */ 242 - printk(KERN_INFO "DT3155: Allocator failed!\n"); 243 - *buf_addr = 0; 244 - *total_size_kbs = 0; 245 - return; 246 - 247 - } 248 - 249 - 250 - /***************************************************** 251 - * dt3155_setup_buffers 252 - * 253 - * setup_buffers just puts the buffering system into 254 - * a consistent state before the start of interrupts 255 - * 256 - * JML : it looks like all the buffers need to be 257 - * continuous. So I'm going to try and allocate one 258 - * continuous buffer. 259 - * 260 - * GCS : Fix DMA problems when buffer spans 261 - * 4MB boundary. Also, add error checking. This 262 - * function will return -ENOMEM when not enough memory. 263 - *****************************************************/ 264 - u32 dt3155_setup_buffers(u32 *allocatorAddr) 265 - 266 - { 267 - struct dt3155_fbuffer *fb; 268 - u32 index; 269 - u32 rambuff_addr; /* start of allocation */ 270 - u32 rambuff_size; /* total size allocated to driver */ 271 - u32 rambuff_acm; /* accumlator, keep track of how much 272 - is left after being split up*/ 273 - u32 rambuff_end; /* end of rambuff */ 274 - u32 numbufs; /* number of useful buffers allocated (per device) */ 275 - u32 bufsize = DT3155_MAX_ROWS * DT3155_MAX_COLS; 276 - int minor; 277 - 278 - /* zero the fbuffer status and address structure */ 279 - for (minor = 0; minor < ndevices; minor++) { 280 - fb = &dt3155_status[minor].fbuffer; 281 - memset(fb, 0, sizeof(*fb)); 282 - } 283 - 284 - /* allocate a large contiguous chunk of RAM */ 285 - allocate_buffers(&rambuff_addr, &rambuff_size, bufsize); 286 - printk(KERN_INFO "DT3155: mem info\n"); 287 - printk(KERN_INFO " - rambuf_addr = 0x%x\n", rambuff_addr); 288 - printk(KERN_INFO " - length (kb) = %u\n", rambuff_size); 289 - if (rambuff_addr == 0) { 290 - printk(KERN_INFO 291 - "DT3155: Error setup_buffers() allocator dma failed\n"); 292 - return -ENOMEM; 293 - } 294 - *allocatorAddr = rambuff_addr; 295 - rambuff_end = rambuff_addr + 1024 * rambuff_size; 296 - 297 - /* after allocation, we need to count how many useful buffers there 298 - are so we can give an equal number to each device */ 299 - rambuff_acm = rambuff_addr; 300 - for (index = 0; index < MAXBUFFERS; index++) { 301 - /*avoid spanning 4MB bdry*/ 302 - rambuff_acm = adjust_4MB(rambuff_acm, bufsize); 303 - if (rambuff_acm + bufsize > rambuff_end) 304 - break; 305 - rambuff_acm += bufsize; 306 - } 307 - /* Following line is OK, will waste buffers if index 308 - * not evenly divisible by ndevices -NJC*/ 309 - numbufs = index / ndevices; 310 - printk(KERN_INFO " - numbufs = %u\n", numbufs); 311 - if (numbufs < 2) { 312 - printk(KERN_INFO 313 - "DT3155: Error setup_buffers() couldn't allocate 2 bufs/board\n"); 314 - return -ENOMEM; 315 - } 316 - 317 - /* now that we have board memory we spit it up */ 318 - /* between the boards and the buffers */ 319 - rambuff_acm = rambuff_addr; 320 - for (minor = 0; minor < ndevices; minor++) { 321 - fb = &dt3155_status[minor].fbuffer; 322 - rambuff_acm = adjust_4MB(rambuff_acm, bufsize); 323 - 324 - /* Save the start of this boards buffer space (for mmap). */ 325 - dt3155_status[minor].mem_addr = rambuff_acm; 326 - 327 - for (index = 0; index < numbufs; index++) { 328 - rambuff_acm = adjust_4MB(rambuff_acm, bufsize); 329 - if (rambuff_acm + bufsize > rambuff_end) { 330 - /* Should never happen */ 331 - printk(KERN_INFO "DT3155 PROGRAM ERROR (GCS)\n" 332 - "Error distributing allocated buffers\n"); 333 - return -ENOMEM; 334 - } 335 - 336 - fb->frame_info[index].addr = rambuff_acm; 337 - push_empty(fb, index); 338 - /* printk(" - Buffer : %lx\n", fb->frame_info[index].addr); */ 339 - fb->nbuffers += 1; 340 - rambuff_acm += bufsize; 341 - } 342 - 343 - /* Make sure there is an active buffer there. */ 344 - fb->active_buf = pop_empty(fb); 345 - fb->even_happened = 0; 346 - fb->even_stopped = 0; 347 - 348 - /* make sure there is no locked_buf JML 2/28/00 */ 349 - fb->locked_buf = -1; 350 - 351 - dt3155_status[minor].mem_size = rambuff_acm - 352 - dt3155_status[minor].mem_addr; 353 - 354 - /* setup the ready queue */ 355 - fb->ready_head = 0; 356 - fb->ready_len = 0; 357 - printk(KERN_INFO "Available buffers for device %d: %d\n", 358 - minor, fb->nbuffers); 359 - } 360 - 361 - return 1; 362 - } 363 - 364 - /***************************************************** 365 - * internal_release_locked_buffer 366 - * 367 - * The internal function for releasing a locked buffer. 368 - * It assumes interrupts are turned off. 369 - *****************************************************/ 370 - static void internal_release_locked_buffer(struct dt3155_fbuffer *fb) 371 - { 372 - if (fb->locked_buf >= 0) { 373 - push_empty(fb, fb->locked_buf); 374 - fb->locked_buf = -1; 375 - } 376 - } 377 - 378 - /***************************************************** 379 - * dt3155_release_locked_buffer 380 - * 381 - * The user function of the above. 382 - *****************************************************/ 383 - void dt3155_release_locked_buffer(struct dt3155_fbuffer *fb) 384 - { 385 - unsigned long int flags; 386 - 387 - local_save_flags(flags); 388 - local_irq_disable(); 389 - internal_release_locked_buffer(fb); 390 - local_irq_restore(flags); 391 - } 392 - 393 - /***************************************************** 394 - * dt3155_flush 395 - *****************************************************/ 396 - int dt3155_flush(struct dt3155_fbuffer *fb) 397 - { 398 - unsigned long int flags; 399 - int index; 400 - 401 - local_save_flags(flags); 402 - local_irq_disable(); 403 - 404 - internal_release_locked_buffer(fb); 405 - fb->empty_len = 0; 406 - 407 - for (index = 0; index < fb->nbuffers; index++) 408 - push_empty(fb, index); 409 - 410 - /* Make sure there is an active buffer there. */ 411 - fb->active_buf = pop_empty(fb); 412 - 413 - fb->even_happened = 0; 414 - fb->even_stopped = 0; 415 - 416 - /* setup the ready queue */ 417 - fb->ready_head = 0; 418 - fb->ready_len = 0; 419 - 420 - local_irq_restore(flags); 421 - 422 - return 0; 423 - } 424 - 425 - /***************************************************** 426 - * dt3155_get_ready_buffer 427 - * 428 - * get_ready_buffer will grab the next chunk of data 429 - * if it is already there, otherwise it returns 0. 430 - * If the user has a buffer locked it will unlock 431 - * that buffer before returning the new one. 432 - *****************************************************/ 433 - int dt3155_get_ready_buffer(struct dt3155_fbuffer *fb) 434 - { 435 - unsigned long int flags; 436 - int frame_index; 437 - 438 - local_save_flags(flags); 439 - local_irq_disable(); 440 - 441 - #ifdef DEBUG_QUES_A 442 - printques(fb); 443 - #endif 444 - 445 - internal_release_locked_buffer(fb); 446 - 447 - if (is_ready_buf_empty(fb)) { 448 - frame_index = -1; 449 - } else { 450 - frame_index = pop_ready(fb); 451 - fb->locked_buf = frame_index; 452 - } 453 - 454 - #ifdef DEBUG_QUES_B 455 - printques(fb); 456 - #endif 457 - 458 - local_irq_restore(flags); 459 - 460 - return frame_index; 461 - }
-83
drivers/staging/dt3155/dt3155_isr.h
··· 1 - /* 2 - 3 - Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, 4 - Jason Lapenta, Scott Smedley 5 - 6 - This file is part of the DT3155 Device Driver. 7 - 8 - The DT3155 Device Driver is free software; you can redistribute it 9 - and/or modify it under the terms of the GNU General Public License as 10 - published by the Free Software Foundation; either version 2 of the 11 - License, or (at your option) any later version. 12 - 13 - The DT3155 Device Driver is distributed in the hope that it will be 14 - useful, but WITHOUT ANY WARRANTY; without even the implied warranty 15 - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - GNU General Public License for more details. 17 - 18 - You should have received a copy of the GNU General Public License 19 - along with the DT3155 Device Driver; if not, write to the Free 20 - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 - MA 02111-1307 USA 22 - 23 - 24 - -- Changes -- 25 - 26 - Date Programmer Description of changes made 27 - ------------------------------------------------------------------- 28 - 03-Jul-2000 JML n/a 29 - 24-Jul-2002 SS GPL licence. 30 - 26-Oct-2009 SS Porting to 2.6.30 kernel. 31 - 32 - -- notes -- 33 - 34 - */ 35 - 36 - #ifndef DT3155_ISR_H 37 - #define DT3155_ISR_H 38 - 39 - /********************************** 40 - * User functions for buffering 41 - **********************************/ 42 - 43 - /* 44 - * Initialize the buffering system. 45 - * This should be called prior to enabling interrupts 46 - */ 47 - u32 dt3155_setup_buffers(u32 *allocatorAddr); 48 - 49 - /* 50 - * Get the next frame of data if it is ready. 51 - * Returns zero if no data is ready. If there is data but the user has a 52 - * locked buffer, it will unlock that buffer and return it to the free list. 53 - */ 54 - int dt3155_get_ready_buffer(struct dt3155_fbuffer *fb); 55 - 56 - /* 57 - * Return a locked buffer to the free list. 58 - */ 59 - void dt3155_release_locked_buffer(struct dt3155_fbuffer *fb); 60 - 61 - /* 62 - * Flush the buffer system. 63 - */ 64 - int dt3155_flush(struct dt3155_fbuffer *fb); 65 - 66 - /********************************** 67 - * Simple array based que struct 68 - **********************************/ 69 - 70 - bool are_empty_buffers(struct dt3155_fbuffer *fb); 71 - void push_empty(struct dt3155_fbuffer *fb, int index); 72 - 73 - int pop_empty(struct dt3155_fbuffer *fb); 74 - 75 - bool is_ready_buf_empty(struct dt3155_fbuffer *fb); 76 - bool is_ready_buf_full(struct dt3155_fbuffer *fb); 77 - 78 - void push_ready(struct dt3155_fbuffer *fb, int index); 79 - int pop_ready(struct dt3155_fbuffer *fb); 80 - 81 - void printques(struct dt3155_fbuffer *fb); 82 - 83 - #endif