-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 197163 b: refs/heads/master c: d42bffb h: refs/heads/master i: 197161: 226f227 197159: 9ac5451 v: v3
- Loading branch information
Marin Mitov
authored and
Greg Kroah-Hartman
committed
May 11, 2010
1 parent
8392ccb
commit edcc2f0
Showing
8 changed files
with
2,136 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 6608224c9e5c8aacf88914697be2d5f1fc7a0be6 | ||
refs/heads/master: d42bffb8990ca9e74cc1ba625ce23dda2bd8c8c5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
config VIDEO_DT3155 | ||
tristate "DT3155 frame grabber, Video4Linux interface" | ||
depends on PCI && VIDEO_DEV && VIDEO_V4L2 | ||
select VIDEOBUF_DMA_CONTIG | ||
default n | ||
---help--- | ||
Enables dt3155 device driver for the DataTranslation DT3155 frame grabber. | ||
Say Y here if you have this hardware. | ||
In doubt, say N. | ||
|
||
To compile this driver as a module, choose M here: the | ||
module will be called dt3155_v4l. | ||
|
||
config DT3155_CCIR | ||
bool "Selects CCIR/50Hz vertical refresh" | ||
depends on VIDEO_DT3155 | ||
default y | ||
---help--- | ||
Select it for CCIR/50Hz (European region), | ||
or leave it unselected for RS-170/60Hz (North America). | ||
|
||
config DT3155_STREAMING | ||
bool "Selects mmap streaming instead of read method" | ||
depends on VIDEO_DT3155 | ||
default y | ||
---help--- | ||
Select it if you wish to try mmap streaming, or | ||
or leave it unselected for using read method. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
obj-$(CONFIG_VIDEO_DT3155) += dt3155_v4l.o | ||
dt3155_v4l-objs := \ | ||
dt3155-bufs.o \ | ||
dt3155v4l.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,256 @@ | ||
/*************************************************************************** | ||
* Copyright (C) 2006-2010 by Marin Mitov * | ||
* mitov@issp.bas.bg * | ||
* * | ||
* 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., * | ||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
***************************************************************************/ | ||
|
||
#include "dt3155-bufs.h" | ||
|
||
/** | ||
* dt3155_init_chunks_buf - creates a chunk buffer and allocates memory for it | ||
* | ||
* returns: a pointer to the struct dt3155_buf or NULL if failed | ||
* | ||
* Creates a struct dt3155_buf, then allocates a chunk of memory of | ||
* size DT3155_CHUNK_SIZE and sets all the pages in it as Reserved. | ||
* This is done to be able to use remap_pfn_range() on these buffers | ||
* (which do not work on normal memory if Reserved bit is not set) | ||
*/ | ||
struct dt3155_buf * | ||
dt3155_init_chunks_buf(void) | ||
{ /* could sleep */ | ||
struct dt3155_buf *buf; | ||
int i; | ||
|
||
buf = kzalloc(sizeof(*buf), GFP_KERNEL); | ||
if (!buf) | ||
return NULL; | ||
buf->cpu = (void *)__get_free_pages(DT3155_CHUNK_FLAGS, | ||
get_order(DT3155_CHUNK_SIZE)); | ||
if (!buf->cpu) { | ||
kfree(buf); | ||
return NULL; | ||
} | ||
for (i = 0; i < DT3155_CHUNK_SIZE; i += PAGE_SIZE) | ||
SetPageReserved(virt_to_page(buf->cpu + i)); | ||
return buf; /* success */ | ||
} | ||
|
||
/** | ||
* dt3155_free_chunks_buf - destroys the specified buffer | ||
* | ||
* @buf: the buffer to be freed | ||
* | ||
* Clears Reserved bit of all pages in the chunk, frees the chunk memory | ||
* and destroys struct dt3155_buf. | ||
*/ | ||
void | ||
dt3155_free_chunks_buf(struct dt3155_buf *buf) | ||
{ | ||
int i; | ||
|
||
for (i = 0; i < DT3155_CHUNK_SIZE; i += PAGE_SIZE) | ||
ClearPageReserved(virt_to_page(buf->cpu + i)); | ||
free_pages((unsigned long)buf->cpu, get_order(DT3155_CHUNK_SIZE)); | ||
kfree(buf); | ||
} | ||
|
||
/** | ||
* dt3155_init_fifo - creates and initializes a fifo | ||
* | ||
* returns: a pointer to the crated and initialized struct dt3155_fifo | ||
* or NULL if failed | ||
*/ | ||
struct dt3155_fifo * | ||
dt3155_init_fifo(void) | ||
{ /* could sleep */ | ||
struct dt3155_fifo *fifo = kzalloc(sizeof(*fifo), GFP_KERNEL); | ||
if (fifo) | ||
spin_lock_init(&fifo->lock); | ||
return fifo; | ||
} | ||
|
||
/* dt3155_free_fifo(x) defined as macro in dt3155.h */ | ||
|
||
/** | ||
* dt3155_get_buf - gets a buffer from the fifo | ||
* | ||
* @fifo: the fifo to get a buffer from | ||
* | ||
* returns: a pointer to the buffer or NULL if failed | ||
* | ||
* dt3155_get_buf gets the fifo's spin_lock and returns the | ||
* buffer pointed by the head. Could be used in any context. | ||
*/ | ||
struct dt3155_buf * | ||
dt3155_get_buf(struct dt3155_fifo *fifo) | ||
{ | ||
unsigned long flags; | ||
struct dt3155_buf *tmp_buf; | ||
|
||
spin_lock_irqsave(&fifo->lock, flags); | ||
tmp_buf = fifo->head; | ||
if (fifo->head) | ||
fifo->head = fifo->head->next; | ||
if (!fifo->head) | ||
fifo->tail = NULL; | ||
spin_unlock_irqrestore(&fifo->lock, flags); | ||
return tmp_buf; | ||
} | ||
|
||
/** | ||
* dt3155_put_buf - puts a buffer into a fifo | ||
* | ||
* @buf: the buffer to put | ||
* @fifo: the fifo to put the buffer in | ||
* | ||
* dt3155_put_buf gets the fifo's spin_lock and puts the buf | ||
* at the tail of the fifo. Could be used in any context. | ||
*/ | ||
void | ||
dt3155_put_buf(struct dt3155_buf *buf, struct dt3155_fifo *fifo) | ||
{ | ||
unsigned long flags; | ||
|
||
spin_lock_irqsave(&fifo->lock, flags); | ||
buf->next = NULL; | ||
if (fifo->tail) | ||
fifo->tail->next = buf; | ||
fifo->tail = buf; | ||
if (!fifo->head) | ||
fifo->head = buf; | ||
spin_unlock_irqrestore(&fifo->lock, flags); | ||
} | ||
|
||
/** | ||
* dt3155_init_chunks_fifo - creates and fills a chunks_fifo | ||
* | ||
* returns: a pointer to the fifo or NULL if failed | ||
* | ||
* dt3155_init_chunks_fifo creates and fills the fifo with | ||
* a number of chunks <= DT3155_CHUNK_NUM. The returned fifo | ||
* contains at least one chunk. | ||
*/ | ||
struct dt3155_fifo * | ||
dt3155_init_chunks_fifo(void) | ||
{ /* could sleep */ | ||
int i; | ||
|
||
struct dt3155_fifo *chunks; | ||
struct dt3155_buf *tmp_buf; | ||
|
||
chunks = dt3155_init_fifo(); | ||
if (!chunks) | ||
return NULL; | ||
tmp_buf = dt3155_init_chunks_buf(); | ||
if (!tmp_buf) { | ||
dt3155_free_fifo(chunks); | ||
return NULL; | ||
} | ||
dt3155_put_buf(tmp_buf, chunks); | ||
for (i = 1; i < DT3155_CHUNK_NUM; i++) { | ||
tmp_buf = dt3155_init_chunks_buf(); | ||
if (!tmp_buf) | ||
break; | ||
dt3155_put_buf(tmp_buf, chunks); | ||
} | ||
return chunks; | ||
} | ||
|
||
/** | ||
* dt3155_free_chunks_fifo - empties and destroys the chunks_fifo | ||
* | ||
* @chunks: the chunks_fifo to be freed | ||
* | ||
* dt3155_free_chunks_fifo deallocates all chunks in the fifo and | ||
* destroys it. | ||
*/ | ||
void | ||
dt3155_free_chunks_fifo(struct dt3155_fifo *chunks) | ||
{ | ||
int buf_count = 0; | ||
struct dt3155_buf *buf; | ||
|
||
while ((buf = dt3155_get_buf(chunks))) { | ||
dt3155_free_chunks_buf(buf); | ||
buf_count++; | ||
} | ||
dt3155_free_fifo(chunks); | ||
printk(KERN_INFO "dt3155: %i chunks freed\n", buf_count); | ||
} | ||
|
||
/** | ||
* dt3155_init_ibufs_fifo - creates and fills an image buffer fifo | ||
* | ||
* @chunks: chunks_fifo to take memory from | ||
* @buf_size: the size of image buffers | ||
* | ||
* returns: a pointer to the fifo filled with image buffers | ||
* | ||
* dt3155_init_ibufs_fifo takes chunks from chunks_fifo, chops them | ||
* into pieces of size buf_size and fills image fifo with them. | ||
*/ | ||
struct dt3155_fifo * | ||
dt3155_init_ibufs_fifo(struct dt3155_fifo *chunks, int buf_size) | ||
{ /* could sleep */ | ||
int i, buf_count = 0; | ||
struct dt3155_buf *tmp_ibuf, *chunks_buf, *last_chunk; | ||
struct dt3155_fifo *tmp_fifo; | ||
|
||
tmp_fifo = dt3155_init_fifo(); | ||
if (!tmp_fifo) | ||
return NULL; | ||
last_chunk = chunks->tail; | ||
do { | ||
chunks_buf = dt3155_get_buf(chunks); | ||
dt3155_put_buf(chunks_buf, chunks); | ||
for (i = 0; i < DT3155_CHUNK_SIZE / buf_size; i++) { | ||
tmp_ibuf = kzalloc(sizeof(*tmp_ibuf), GFP_KERNEL); | ||
if (tmp_ibuf) { | ||
tmp_ibuf->cpu = | ||
chunks_buf->cpu + DT3155_BUF_SIZE * i; | ||
dt3155_put_buf(tmp_ibuf, tmp_fifo); | ||
buf_count++; | ||
} else { | ||
if (buf_count) { | ||
goto print_num_bufs; | ||
} else { | ||
dt3155_free_fifo(tmp_fifo); | ||
return NULL; | ||
} | ||
} | ||
} | ||
} while (chunks_buf != last_chunk); | ||
print_num_bufs: | ||
printk(KERN_INFO "dt3155: %i image buffers available\n", buf_count); | ||
return tmp_fifo; | ||
} | ||
|
||
/** | ||
* dt3155_free_ibufs_fifo - empties and destroys an image fifo | ||
* | ||
* @fifo: the fifo to free | ||
*/ | ||
void | ||
dt3155_free_ibufs_fifo(struct dt3155_fifo *fifo) | ||
{ | ||
struct dt3155_buf *tmp_ibuf; | ||
|
||
while ((tmp_ibuf = dt3155_get_buf(fifo))) | ||
kfree(tmp_ibuf); | ||
kfree(fifo); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/*************************************************************************** | ||
* Copyright (C) 2006-2010 by Marin Mitov * | ||
* mitov@issp.bas.bg * | ||
* * | ||
* 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., * | ||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
***************************************************************************/ | ||
|
||
#ifndef _DT3155_BUFS_H_ | ||
#define _DT3155_BUFS_H_ | ||
|
||
#include <linux/pci.h> | ||
|
||
/* 4 chunks of 4MB, 9 buffers each = 36 buffers (> VIDEO_MAX_FRAME) */ | ||
#define DT3155_CHUNK_NUM 4 | ||
|
||
/* DT3155_CHUNK_SIZE should be 4M (2^22) or less, but more than image size */ | ||
#define DT3155_CHUNK_SIZE (1U << 22) | ||
#define DT3155_CHUNK_FLAGS (GFP_KERNEL | GFP_DMA32 | __GFP_COLD | __GFP_NOWARN) | ||
|
||
/* DT3155_BUF_SIZE = 108 * PAGE_SIZE, so each buf is PAGE_SIZE alligned */ | ||
#define DT3155_BUF_SIZE (768 * 576) | ||
|
||
/** | ||
* struct dt3155_buf - image buffer structure | ||
* | ||
* @cpu: virtual kernel address of the buffer | ||
* @dma: dma (bus) address of the buffer | ||
* @next: pointer to the next buffer in the fifo | ||
* @tv: time value when the image has been acquired | ||
*/ | ||
struct dt3155_buf { | ||
void *cpu; | ||
dma_addr_t dma; | ||
struct dt3155_buf *next; | ||
struct timeval tv; | ||
}; | ||
|
||
/** | ||
* struct dt3155_fifo - fifo structure | ||
* | ||
* @head: pointer to the head of the fifo | ||
* @tail: pionter to the tail of the fifo | ||
* @lock: spin_lock to protect the fifo | ||
*/ | ||
struct dt3155_fifo { | ||
struct dt3155_buf *head; | ||
struct dt3155_buf *tail; | ||
spinlock_t lock; | ||
}; | ||
|
||
struct dt3155_buf * __must_check | ||
dt3155_init_chunks_buf(void); | ||
void | ||
dt3155_free_chunks_buf(struct dt3155_buf *buf); | ||
|
||
struct dt3155_fifo * __must_check | ||
dt3155_init_fifo(void); | ||
#define dt3155_free_fifo(x) kfree(x) | ||
|
||
struct dt3155_buf * __must_check | ||
dt3155_get_buf(struct dt3155_fifo *fifo); | ||
void | ||
dt3155_put_buf(struct dt3155_buf *buf, struct dt3155_fifo *fifo); | ||
|
||
struct dt3155_fifo * __must_check | ||
dt3155_init_chunks_fifo(void); | ||
void | ||
dt3155_free_chunks_fifo(struct dt3155_fifo *chunks); | ||
|
||
struct dt3155_fifo * __must_check | ||
dt3155_init_ibufs_fifo(struct dt3155_fifo *chunks, int buf_size); | ||
void | ||
dt3155_free_ibufs_fifo(struct dt3155_fifo *fifo); | ||
|
||
#endif /* _DT3155_BUFS_H_ */ |
Oops, something went wrong.