2 * Motion Eye video4linux driver for Sony Vaio PictureBook
4 * Copyright (C) 2001-2002 Stelian Pop <stelian@popies.net>
6 * Copyright (C) 2001-2002 AlcĂ´ve <www.alcove.com>
8 * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
10 * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
12 * Some parts borrowed from various video4linux drivers, especially
13 * bttv-driver.c and zoran.c, see original files for credits.
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #include <linux/config.h>
30 #include <linux/module.h>
31 #include <linux/pci.h>
32 #include <linux/sched.h>
33 #include <linux/init.h>
34 #include <linux/videodev.h>
35 #include <asm/uaccess.h>
37 #include <linux/delay.h>
38 #include <linux/wrapper.h>
39 #include <linux/interrupt.h>
40 #include <linux/vmalloc.h>
43 #include "linux/meye.h"
45 /* driver structure - only one possible */
46 static struct meye meye;
47 /* number of grab buffers */
48 static unsigned int gbuffers = 2;
49 /* size of a grab buffer */
50 static unsigned int gbufsize = MEYE_MAX_BUFSIZE;
51 /* /dev/videoX registration number */
52 static int video_nr = -1;
54 /****************************************************************************/
56 /****************************************************************************/
59 static inline void meye_initq(struct meye_queue *queue) {
60 queue->head = queue->tail = 0;
62 queue->s_lock = (spinlock_t)SPIN_LOCK_UNLOCKED;
63 init_waitqueue_head(&queue->proc_list);
66 /* Pulls an element from the queue */
67 static inline int meye_pullq(struct meye_queue *queue) {
71 spin_lock_irqsave(&queue->s_lock, flags);
73 spin_unlock_irqrestore(&queue->s_lock, flags);
76 result = queue->buf[queue->head];
78 queue->head &= (MEYE_QUEUE_SIZE - 1);
80 spin_unlock_irqrestore(&queue->s_lock, flags);
84 /* Pushes an element into the queue */
85 static inline void meye_pushq(struct meye_queue *queue, int element) {
88 spin_lock_irqsave(&queue->s_lock, flags);
89 if (queue->len == MEYE_QUEUE_SIZE) {
90 /* remove the first element */
92 queue->head &= (MEYE_QUEUE_SIZE - 1);
95 queue->buf[queue->tail] = element;
97 queue->tail &= (MEYE_QUEUE_SIZE - 1);
100 spin_unlock_irqrestore(&queue->s_lock, flags);
103 /* Tests if the queue is empty */
104 static inline int meye_emptyq(struct meye_queue *queue, int *elem) {
108 spin_lock_irqsave(&queue->s_lock, flags);
109 result = (queue->len == 0);
111 *elem = queue->buf[queue->head];
112 spin_unlock_irqrestore(&queue->s_lock, flags);
116 /****************************************************************************/
117 /* Memory allocation routines (stolen from bttv-driver.c) */
118 /****************************************************************************/
120 /* Here we want the physical address of the memory.
121 * This is used when initializing the contents of the area.
123 static inline unsigned long kvirt_to_pa(unsigned long adr) {
124 unsigned long kva, ret;
126 kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
127 kva |= adr & (PAGE_SIZE-1); /* restore the offset */
132 static void *rvmalloc(unsigned long size) {
136 size = PAGE_ALIGN(size);
137 mem = vmalloc_32(size);
139 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
140 adr = (unsigned long)mem;
142 mem_map_reserve(vmalloc_to_page((void *)adr));
150 static void rvfree(void * mem, unsigned long size) {
154 adr = (unsigned long) mem;
155 while ((long) size > 0) {
156 mem_map_unreserve(vmalloc_to_page((void *)adr));
164 /* return a page table pointing to N pages of locked memory */
165 static int ptable_alloc(void) {
169 memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
171 meye.mchip_ptable[MCHIP_NB_PAGES] = pci_alloc_consistent(meye.mchip_dev,
173 &meye.mchip_dmahandle);
174 if (!meye.mchip_ptable[MCHIP_NB_PAGES]) {
175 meye.mchip_dmahandle = 0;
179 pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
180 for (i = 0; i < MCHIP_NB_PAGES; i++) {
181 meye.mchip_ptable[i] = pci_alloc_consistent(meye.mchip_dev,
184 if (!meye.mchip_ptable[i]) {
186 pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
187 for (j = 0; j < i; ++j) {
188 pci_free_consistent(meye.mchip_dev,
190 meye.mchip_ptable[j], *pt);
193 meye.mchip_dmahandle = 0;
201 static void ptable_free(void) {
205 pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES];
206 for (i = 0; i < MCHIP_NB_PAGES; i++) {
207 if (meye.mchip_ptable[i])
208 pci_free_consistent(meye.mchip_dev,
210 meye.mchip_ptable[i], *pt);
214 if (meye.mchip_ptable[MCHIP_NB_PAGES])
215 pci_free_consistent(meye.mchip_dev,
217 meye.mchip_ptable[MCHIP_NB_PAGES],
218 meye.mchip_dmahandle);
220 memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
221 meye.mchip_dmahandle = 0;
224 /* copy data from ptable into buf */
225 static void ptable_copy(u8 *buf, int start, int size, int pt_pages) {
228 for (i = 0; i < (size / PAGE_SIZE) * PAGE_SIZE; i += PAGE_SIZE) {
229 memcpy(buf + i, meye.mchip_ptable[start++], PAGE_SIZE);
230 if (start >= pt_pages)
233 memcpy(buf + i, meye.mchip_ptable[start], size % PAGE_SIZE);
237 /****************************************************************************/
238 /* JPEG tables at different qualities to load into the VRJ chip */
239 /****************************************************************************/
241 /* return a set of quantisation tables based on a quality from 1 to 10 */
242 static u16 *jpeg_quantisation_tables(int *size, int quality) {
243 static u16 tables0[] = {
244 0xdbff, 0x4300, 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
245 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
246 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
247 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
248 0xffff, 0xffff, 0xffff,
249 0xdbff, 0x4300, 0xff01, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
250 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
251 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
252 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
253 0xffff, 0xffff, 0xffff,
255 static u16 tables1[] = {
256 0xdbff, 0x4300, 0x5000, 0x3c37, 0x3c46, 0x5032, 0x4146, 0x5a46,
257 0x5055, 0x785f, 0x82c8, 0x6e78, 0x786e, 0xaff5, 0x91b9, 0xffc8,
258 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
259 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
260 0xffff, 0xffff, 0xffff,
261 0xdbff, 0x4300, 0x5501, 0x5a5a, 0x6978, 0xeb78, 0x8282, 0xffeb,
262 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
263 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
264 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
265 0xffff, 0xffff, 0xffff,
267 static u16 tables2[] = {
268 0xdbff, 0x4300, 0x2800, 0x1e1c, 0x1e23, 0x2819, 0x2123, 0x2d23,
269 0x282b, 0x3c30, 0x4164, 0x373c, 0x3c37, 0x587b, 0x495d, 0x9164,
270 0x9980, 0x8f96, 0x8c80, 0xa08a, 0xe6b4, 0xa0c3, 0xdaaa, 0x8aad,
271 0xc88c, 0xcbff, 0xeeda, 0xfff5, 0xffff, 0xc19b, 0xffff, 0xfaff,
272 0xe6ff, 0xfffd, 0xfff8,
273 0xdbff, 0x4300, 0x2b01, 0x2d2d, 0x353c, 0x763c, 0x4141, 0xf876,
274 0x8ca5, 0xf8a5, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
275 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
276 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
277 0xf8f8, 0xf8f8, 0xfff8,
279 static u16 tables3[] = {
280 0xdbff, 0x4300, 0x1b00, 0x1412, 0x1417, 0x1b11, 0x1617, 0x1e17,
281 0x1b1c, 0x2820, 0x2b42, 0x2528, 0x2825, 0x3a51, 0x303d, 0x6042,
282 0x6555, 0x5f64, 0x5d55, 0x6a5b, 0x9978, 0x6a81, 0x9071, 0x5b73,
283 0x855d, 0x86b5, 0x9e90, 0xaba3, 0xabad, 0x8067, 0xc9bc, 0xa6ba,
284 0x99c7, 0xaba8, 0xffa4,
285 0xdbff, 0x4300, 0x1c01, 0x1e1e, 0x2328, 0x4e28, 0x2b2b, 0xa44e,
286 0x5d6e, 0xa46e, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
287 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
288 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
289 0xa4a4, 0xa4a4, 0xffa4,
291 static u16 tables4[] = {
292 0xdbff, 0x4300, 0x1400, 0x0f0e, 0x0f12, 0x140d, 0x1012, 0x1712,
293 0x1415, 0x1e18, 0x2132, 0x1c1e, 0x1e1c, 0x2c3d, 0x242e, 0x4932,
294 0x4c40, 0x474b, 0x4640, 0x5045, 0x735a, 0x5062, 0x6d55, 0x4556,
295 0x6446, 0x6588, 0x776d, 0x817b, 0x8182, 0x604e, 0x978d, 0x7d8c,
296 0x7396, 0x817e, 0xff7c,
297 0xdbff, 0x4300, 0x1501, 0x1717, 0x1a1e, 0x3b1e, 0x2121, 0x7c3b,
298 0x4653, 0x7c53, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
299 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
300 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
301 0x7c7c, 0x7c7c, 0xff7c,
303 static u16 tables5[] = {
304 0xdbff, 0x4300, 0x1000, 0x0c0b, 0x0c0e, 0x100a, 0x0d0e, 0x120e,
305 0x1011, 0x1813, 0x1a28, 0x1618, 0x1816, 0x2331, 0x1d25, 0x3a28,
306 0x3d33, 0x393c, 0x3833, 0x4037, 0x5c48, 0x404e, 0x5744, 0x3745,
307 0x5038, 0x516d, 0x5f57, 0x6762, 0x6768, 0x4d3e, 0x7971, 0x6470,
308 0x5c78, 0x6765, 0xff63,
309 0xdbff, 0x4300, 0x1101, 0x1212, 0x1518, 0x2f18, 0x1a1a, 0x632f,
310 0x3842, 0x6342, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
311 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
312 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
313 0x6363, 0x6363, 0xff63,
315 static u16 tables6[] = {
316 0xdbff, 0x4300, 0x0d00, 0x0a09, 0x0a0b, 0x0d08, 0x0a0b, 0x0e0b,
317 0x0d0e, 0x130f, 0x1520, 0x1213, 0x1312, 0x1c27, 0x171e, 0x2e20,
318 0x3129, 0x2e30, 0x2d29, 0x332c, 0x4a3a, 0x333e, 0x4636, 0x2c37,
319 0x402d, 0x4157, 0x4c46, 0x524e, 0x5253, 0x3e32, 0x615a, 0x505a,
320 0x4a60, 0x5251, 0xff4f,
321 0xdbff, 0x4300, 0x0e01, 0x0e0e, 0x1113, 0x2613, 0x1515, 0x4f26,
322 0x2d35, 0x4f35, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
323 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
324 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
325 0x4f4f, 0x4f4f, 0xff4f,
327 static u16 tables7[] = {
328 0xdbff, 0x4300, 0x0a00, 0x0707, 0x0708, 0x0a06, 0x0808, 0x0b08,
329 0x0a0a, 0x0e0b, 0x1018, 0x0d0e, 0x0e0d, 0x151d, 0x1116, 0x2318,
330 0x251f, 0x2224, 0x221f, 0x2621, 0x372b, 0x262f, 0x3429, 0x2129,
331 0x3022, 0x3141, 0x3934, 0x3e3b, 0x3e3e, 0x2e25, 0x4944, 0x3c43,
332 0x3748, 0x3e3d, 0xff3b,
333 0xdbff, 0x4300, 0x0a01, 0x0b0b, 0x0d0e, 0x1c0e, 0x1010, 0x3b1c,
334 0x2228, 0x3b28, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
335 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
336 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
337 0x3b3b, 0x3b3b, 0xff3b,
339 static u16 tables8[] = {
340 0xdbff, 0x4300, 0x0600, 0x0504, 0x0506, 0x0604, 0x0506, 0x0706,
341 0x0607, 0x0a08, 0x0a10, 0x090a, 0x0a09, 0x0e14, 0x0c0f, 0x1710,
342 0x1814, 0x1718, 0x1614, 0x1a16, 0x251d, 0x1a1f, 0x231b, 0x161c,
343 0x2016, 0x202c, 0x2623, 0x2927, 0x292a, 0x1f19, 0x302d, 0x282d,
344 0x2530, 0x2928, 0xff28,
345 0xdbff, 0x4300, 0x0701, 0x0707, 0x080a, 0x130a, 0x0a0a, 0x2813,
346 0x161a, 0x281a, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
347 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
348 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
349 0x2828, 0x2828, 0xff28,
351 static u16 tables9[] = {
352 0xdbff, 0x4300, 0x0300, 0x0202, 0x0203, 0x0302, 0x0303, 0x0403,
353 0x0303, 0x0504, 0x0508, 0x0405, 0x0504, 0x070a, 0x0607, 0x0c08,
354 0x0c0a, 0x0b0c, 0x0b0a, 0x0d0b, 0x120e, 0x0d10, 0x110e, 0x0b0e,
355 0x100b, 0x1016, 0x1311, 0x1514, 0x1515, 0x0f0c, 0x1817, 0x1416,
356 0x1218, 0x1514, 0xff14,
357 0xdbff, 0x4300, 0x0301, 0x0404, 0x0405, 0x0905, 0x0505, 0x1409,
358 0x0b0d, 0x140d, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
359 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
360 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
361 0x1414, 0x1414, 0xff14,
363 static u16 tables10[] = {
364 0xdbff, 0x4300, 0x0100, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
365 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
366 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
367 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
368 0x0101, 0x0101, 0xff01,
369 0xdbff, 0x4300, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
370 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
371 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
372 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
373 0x0101, 0x0101, 0xff01,
378 *size = sizeof(tables0);
381 *size = sizeof(tables1);
384 *size = sizeof(tables2);
387 *size = sizeof(tables3);
390 *size = sizeof(tables4);
393 *size = sizeof(tables5);
396 *size = sizeof(tables6);
399 *size = sizeof(tables7);
402 *size = sizeof(tables8);
405 *size = sizeof(tables9);
408 *size = sizeof(tables10);
411 printk(KERN_WARNING "meye: invalid quality level %d - using 8\n", quality);
412 *size = sizeof(tables8);
418 /* return a generic set of huffman tables */
419 static u16 *jpeg_huffman_tables(int *size) {
420 static u16 tables[] = {
421 0xC4FF, 0xB500, 0x0010, 0x0102, 0x0303, 0x0402, 0x0503, 0x0405,
422 0x0004, 0x0100, 0x017D, 0x0302, 0x0400, 0x0511, 0x2112, 0x4131,
423 0x1306, 0x6151, 0x2207, 0x1471, 0x8132, 0xA191, 0x2308, 0xB142,
424 0x15C1, 0xD152, 0x24F0, 0x6233, 0x8272, 0x0A09, 0x1716, 0x1918,
425 0x251A, 0x2726, 0x2928, 0x342A, 0x3635, 0x3837, 0x3A39, 0x4443,
426 0x4645, 0x4847, 0x4A49, 0x5453, 0x5655, 0x5857, 0x5A59, 0x6463,
427 0x6665, 0x6867, 0x6A69, 0x7473, 0x7675, 0x7877, 0x7A79, 0x8483,
428 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998, 0xA29A,
429 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6, 0xB9B8,
430 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4, 0xD7D6,
431 0xD9D8, 0xE1DA, 0xE3E2, 0xE5E4, 0xE7E6, 0xE9E8, 0xF1EA, 0xF3F2,
432 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA,
433 0xC4FF, 0xB500, 0x0011, 0x0102, 0x0402, 0x0304, 0x0704, 0x0405,
434 0x0004, 0x0201, 0x0077, 0x0201, 0x1103, 0x0504, 0x3121, 0x1206,
435 0x5141, 0x6107, 0x1371, 0x3222, 0x0881, 0x4214, 0xA191, 0xC1B1,
436 0x2309, 0x5233, 0x15F0, 0x7262, 0x0AD1, 0x2416, 0xE134, 0xF125,
437 0x1817, 0x1A19, 0x2726, 0x2928, 0x352A, 0x3736, 0x3938, 0x433A,
438 0x4544, 0x4746, 0x4948, 0x534A, 0x5554, 0x5756, 0x5958, 0x635A,
439 0x6564, 0x6766, 0x6968, 0x736A, 0x7574, 0x7776, 0x7978, 0x827A,
440 0x8483, 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998,
441 0xA29A, 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6,
442 0xB9B8, 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4,
443 0xD7D6, 0xD9D8, 0xE2DA, 0xE4E3, 0xE6E5, 0xE8E7, 0xEAE9, 0xF3F2,
444 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA,
445 0xC4FF, 0x1F00, 0x0000, 0x0501, 0x0101, 0x0101, 0x0101, 0x0000,
446 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09,
448 0xC4FF, 0x1F00, 0x0001, 0x0103, 0x0101, 0x0101, 0x0101, 0x0101,
449 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09,
453 *size = sizeof(tables);
457 /****************************************************************************/
458 /* MCHIP low-level functions */
459 /****************************************************************************/
461 /* waits for the specified miliseconds */
462 static inline void wait_ms(unsigned int ms) {
463 if (!in_interrupt()) {
464 set_current_state(TASK_UNINTERRUPTIBLE);
465 schedule_timeout(1 + ms * HZ / 1000);
471 /* returns the horizontal capture size */
472 static inline int mchip_hsize(void) {
473 return meye.params.subsample ? 320 : 640;
476 /* returns the vertical capture size */
477 static inline int mchip_vsize(void) {
478 return meye.params.subsample ? 240 : 480;
481 /* waits for a register to be available */
482 static void mchip_sync(int reg) {
486 if (reg == MCHIP_MM_FIFO_DATA) {
487 for (i = 0; i < MCHIP_REG_TIMEOUT; i++) {
488 status = readl(meye.mchip_mmregs + MCHIP_MM_FIFO_STATUS);
489 if (!(status & MCHIP_MM_FIFO_WAIT)) {
490 printk(KERN_WARNING "meye: fifo not ready\n");
493 if (status & MCHIP_MM_FIFO_READY)
498 else if (reg > 0x80) {
499 u32 mask = (reg < 0x100) ? MCHIP_HIC_STATUS_MCC_RDY
500 : MCHIP_HIC_STATUS_VRJ_RDY;
501 for (i = 0; i < MCHIP_REG_TIMEOUT; i++) {
502 status = readl(meye.mchip_mmregs + MCHIP_HIC_STATUS);
510 printk(KERN_WARNING "meye: mchip_sync() timeout on reg 0x%x status=0x%x\n", reg, status);
513 /* sets a value into the register */
514 static inline void mchip_set(int reg, u32 v) {
516 writel(v, meye.mchip_mmregs + reg);
519 /* get the register value */
520 static inline u32 mchip_read(int reg) {
522 return readl(meye.mchip_mmregs + reg);
525 /* wait for a register to become a particular value */
526 static inline int mchip_delay(u32 reg, u32 v) {
528 while (--n && mchip_read(reg) != v)
533 /* setup subsampling */
534 static void mchip_subsample(void) {
535 mchip_set(MCHIP_MCC_R_SAMPLING, meye.params.subsample);
536 mchip_set(MCHIP_MCC_R_XRANGE, mchip_hsize());
537 mchip_set(MCHIP_MCC_R_YRANGE, mchip_vsize());
538 mchip_set(MCHIP_MCC_B_XRANGE, mchip_hsize());
539 mchip_set(MCHIP_MCC_B_YRANGE, mchip_vsize());
540 mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
543 /* set the framerate into the mchip */
544 static void mchip_set_framerate(void) {
545 mchip_set(MCHIP_HIC_S_RATE, meye.params.framerate);
548 /* load some huffman and quantisation tables into the VRJ chip ready
549 for JPEG compression */
550 static void mchip_load_tables(void) {
555 tables = jpeg_huffman_tables(&size);
556 for (i = 0; i < size / 2; i++)
557 writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA);
559 tables = jpeg_quantisation_tables(&size, meye.params.quality);
560 for (i = 0; i < size / 2; i++)
561 writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA);
564 /* setup the VRJ parameters in the chip */
565 static void mchip_vrj_setup(u8 mode) {
567 mchip_set(MCHIP_VRJ_BUS_MODE, 5);
568 mchip_set(MCHIP_VRJ_SIGNAL_ACTIVE_LEVEL, 0x1f);
569 mchip_set(MCHIP_VRJ_PDAT_USE, 1);
570 mchip_set(MCHIP_VRJ_IRQ_FLAG, 0xa0);
571 mchip_set(MCHIP_VRJ_MODE_SPECIFY, mode);
572 mchip_set(MCHIP_VRJ_NUM_LINES, mchip_vsize());
573 mchip_set(MCHIP_VRJ_NUM_PIXELS, mchip_hsize());
574 mchip_set(MCHIP_VRJ_NUM_COMPONENTS, 0x1b);
575 mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_LO, 0xFFFF);
576 mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_HI, 0xFFFF);
577 mchip_set(MCHIP_VRJ_COMP_DATA_FORMAT, 0xC);
578 mchip_set(MCHIP_VRJ_RESTART_INTERVAL, 0);
579 mchip_set(MCHIP_VRJ_SOF1, 0x601);
580 mchip_set(MCHIP_VRJ_SOF2, 0x1502);
581 mchip_set(MCHIP_VRJ_SOF3, 0x1503);
582 mchip_set(MCHIP_VRJ_SOF4, 0x1596);
583 mchip_set(MCHIP_VRJ_SOS, 0x0ed0);
588 /* sets the DMA parameters into the chip */
589 static void mchip_dma_setup(u32 dma_addr) {
592 mchip_set(MCHIP_MM_PT_ADDR, dma_addr);
593 for (i = 0; i < 4; i++)
594 mchip_set(MCHIP_MM_FIR(i), 0);
598 /* setup for DMA transfers - also zeros the framebuffer */
599 static int mchip_dma_alloc(void) {
600 if (!meye.mchip_dmahandle)
606 /* frees the DMA buffer */
607 static void mchip_dma_free(void) {
608 if (meye.mchip_dmahandle) {
614 /* stop any existing HIC action and wait for any dma to complete then
615 reset the dma engine */
616 static void mchip_hic_stop(void) {
619 meye.mchip_mode = MCHIP_HIC_MODE_NOOP;
620 if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY))
622 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP);
623 mchip_delay(MCHIP_HIC_CMD, 0);
624 while (!mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE)) {
626 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP);
627 mchip_delay(MCHIP_HIC_CMD, 0);
628 mchip_set(MCHIP_HIC_CTL, MCHIP_HIC_CTL_SOFT_RESET);
631 printk(KERN_ERR "meye: resetting HIC hanged!\n");
638 /****************************************************************************/
639 /* MCHIP frame processing functions */
640 /****************************************************************************/
642 /* get the next ready frame from the dma engine */
643 static u32 mchip_get_frame(void) {
646 v = mchip_read(MCHIP_MM_FIR(meye.mchip_fnum));
650 /* frees the current frame from the dma engine */
651 static void mchip_free_frame(void) {
652 mchip_set(MCHIP_MM_FIR(meye.mchip_fnum), 0);
654 meye.mchip_fnum %= 4;
657 /* read one frame from the framebuffer assuming it was captured using
658 a uncompressed transfer */
659 static void mchip_cont_read_frame(u32 v, u8 *buf, int size) {
662 pt_id = (v >> 17) & 0x3FF;
664 ptable_copy(buf, pt_id, size, MCHIP_NB_PAGES);
668 /* read a compressed frame from the framebuffer */
669 static int mchip_comp_read_frame(u32 v, u8 *buf, int size) {
670 int pt_start, pt_end, trailer;
674 pt_start = (v >> 19) & 0xFF;
675 pt_end = (v >> 11) & 0xFF;
676 trailer = (v >> 1) & 0x3FF;
678 if (pt_end < pt_start)
679 fsize = (MCHIP_NB_PAGES_MJPEG - pt_start) * PAGE_SIZE +
680 pt_end * PAGE_SIZE + trailer * 4;
682 fsize = (pt_end - pt_start) * PAGE_SIZE + trailer * 4;
685 printk(KERN_WARNING "meye: oversized compressed frame %d\n",
690 ptable_copy(buf, pt_start, fsize, MCHIP_NB_PAGES_MJPEG);
693 #ifdef MEYE_JPEG_CORRECTION
695 /* Some mchip generated jpeg frames are incorrect. In most
696 * (all ?) of those cases, the final EOI (0xff 0xd9) marker
697 * is not present at the end of the frame.
699 * Since adding the final marker is not enough to restore
700 * the jpeg integrity, we drop the frame.
703 for (i = fsize - 1; i > 0 && buf[i] == 0xff; i--) ;
705 if (i < 2 || buf[i - 1] != 0xff || buf[i] != 0xd9)
713 /* take a picture into SDRAM */
714 static void mchip_take_picture(void) {
719 mchip_dma_setup(meye.mchip_dmahandle);
721 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_CAP);
722 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
724 mchip_delay(MCHIP_HIC_CMD, 0);
726 for (i = 0; i < 100; ++i) {
727 if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
733 /* dma a previously taken picture into a buffer */
734 static void mchip_get_picture(u8 *buf, int bufsize) {
738 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_OUT);
739 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
741 mchip_delay(MCHIP_HIC_CMD, 0);
742 for (i = 0; i < 100; ++i) {
743 if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
747 for (i = 0; i < 4 ; ++i) {
748 v = mchip_get_frame();
749 if (v & MCHIP_MM_FIR_RDY) {
750 mchip_cont_read_frame(v, buf, bufsize);
757 /* start continuous dma capture */
758 static void mchip_continuous_start(void) {
761 mchip_set_framerate();
762 mchip_dma_setup(meye.mchip_dmahandle);
764 meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT;
766 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_OUT);
767 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
769 mchip_delay(MCHIP_HIC_CMD, 0);
772 /* compress one frame into a buffer */
773 static int mchip_compress_frame(u8 *buf, int bufsize) {
777 mchip_vrj_setup(0x3f);
780 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_COMP);
781 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
783 mchip_delay(MCHIP_HIC_CMD, 0);
784 for (i = 0; i < 100; ++i) {
785 if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
790 for (i = 0; i < 4 ; ++i) {
791 v = mchip_get_frame();
792 if (v & MCHIP_MM_FIR_RDY) {
793 len = mchip_comp_read_frame(v, buf, bufsize);
802 /* uncompress one image into a buffer */
803 static int mchip_uncompress_frame(u8 *img, int imgsize, u8 *buf, int bufsize) {
804 mchip_vrj_setup(0x3f);
807 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_DECOMP);
808 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
810 mchip_delay(MCHIP_HIC_CMD, 0);
812 return mchip_comp_read_frame(buf, bufsize);
816 /* start continuous compressed capture */
817 static void mchip_cont_compression_start(void) {
819 mchip_vrj_setup(0x3f);
821 mchip_set_framerate();
822 mchip_dma_setup(meye.mchip_dmahandle);
824 meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP;
826 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_COMP);
827 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
829 mchip_delay(MCHIP_HIC_CMD, 0);
832 /****************************************************************************/
833 /* Interrupt handling */
834 /****************************************************************************/
836 static void meye_irq(int irq, void *dev_id, struct pt_regs *regs) {
839 v = mchip_read(MCHIP_MM_INTA);
842 v = mchip_get_frame();
843 if (!(v & MCHIP_MM_FIR_RDY))
845 switch (meye.mchip_mode) {
847 case MCHIP_HIC_MODE_CONT_OUT:
848 if (!meye_emptyq(&meye.grabq, NULL)) {
849 int nr = meye_pullq(&meye.grabq);
850 mchip_cont_read_frame(
852 meye.grab_fbuffer + gbufsize * nr,
853 mchip_hsize() * mchip_vsize() * 2);
854 meye.grab_buffer[nr].state = MEYE_BUF_DONE;
855 wake_up_interruptible(&meye.grabq.proc_list);
859 case MCHIP_HIC_MODE_CONT_COMP:
860 if (!meye_emptyq(&meye.grabq, &reqnr)) {
862 size = mchip_comp_read_frame(
864 meye.grab_fbuffer + gbufsize * reqnr,
868 reqnr = meye_pullq(&meye.grabq);
869 meye.grab_buffer[reqnr].size = size;
870 meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
871 wake_up_interruptible(&meye.grabq.proc_list);
876 /* do not free frame, since it can be a snap */
884 /****************************************************************************/
885 /* video4linux integration */
886 /****************************************************************************/
888 static int meye_open(struct inode *inode, struct file *file) {
891 err = video_exclusive_open(inode,file);
895 if (mchip_dma_alloc()) {
896 printk(KERN_ERR "meye: mchip framebuffer allocation failed\n");
897 video_exclusive_release(inode,file);
901 meye_initq(&meye.grabq);
902 for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
903 meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
907 static int meye_release(struct inode *inode, struct file *file) {
910 video_exclusive_release(inode,file);
914 static int meye_do_ioctl(struct inode *inode, struct file *file,
915 unsigned int cmd, void *arg) {
920 struct video_capability *b = arg;
921 strcpy(b->name,meye.video_dev.name);
922 b->type = VID_TYPE_CAPTURE;
933 struct video_channel *v = arg;
936 v->type = VIDEO_TYPE_CAMERA;
939 strcpy(v->name,"Camera");
944 struct video_channel *v = arg;
951 struct video_picture *p = arg;
957 struct video_picture *p = arg;
960 if (p->palette != VIDEO_PALETTE_YUV422)
963 sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS,
964 p->brightness >> 10);
965 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE,
967 sonypi_camera_command(SONYPI_COMMAND_SETCAMERACOLOR,
969 sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST,
979 if (*i < 0 || *i >= gbuffers)
982 switch (meye.grab_buffer[*i].state) {
984 case MEYE_BUF_UNUSED:
987 if (wait_event_interruptible(meye.grabq.proc_list,
988 (meye.grab_buffer[*i].state != MEYE_BUF_USING)))
992 meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
997 case VIDIOCMCAPTURE: {
998 struct video_mmap *vm = arg;
1001 if (vm->frame >= gbuffers || vm->frame < 0)
1003 if (vm->format != VIDEO_PALETTE_YUV422)
1005 if (vm->height * vm->width * 2 > gbufsize)
1007 if (!meye.grab_fbuffer)
1009 if (meye.grab_buffer[vm->frame].state != MEYE_BUF_UNUSED)
1013 if (vm->width == 640 && vm->height == 480) {
1014 if (meye.params.subsample) {
1015 meye.params.subsample = 0;
1019 else if (vm->width == 320 && vm->height == 240) {
1020 if (!meye.params.subsample) {
1021 meye.params.subsample = 1;
1030 if (restart || meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT)
1031 mchip_continuous_start();
1032 meye.grab_buffer[vm->frame].state = MEYE_BUF_USING;
1033 meye_pushq(&meye.grabq, vm->frame);
1039 struct video_mbuf *vm = arg;
1042 memset(vm, 0 , sizeof(*vm));
1043 vm->size = gbufsize * gbuffers;
1044 vm->frames = gbuffers;
1045 for (i = 0; i < gbuffers; i++)
1046 vm->offsets[i] = i * gbufsize;
1050 case MEYEIOC_G_PARAMS: {
1051 struct meye_params *p = arg;
1056 case MEYEIOC_S_PARAMS: {
1057 struct meye_params *jp = arg;
1058 if (jp->subsample > 1)
1060 if (jp->quality > 10)
1062 if (jp->sharpness > 63 || jp->agc > 63 || jp->picture > 63)
1064 if (jp->framerate > 31)
1067 if (meye.params.subsample != jp->subsample ||
1068 meye.params.quality != jp->quality)
1069 mchip_hic_stop(); /* need restart */
1071 sonypi_camera_command(SONYPI_COMMAND_SETCAMERASHARPNESS,
1072 meye.params.sharpness);
1073 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC,
1075 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAPICTURE,
1076 meye.params.picture);
1081 case MEYEIOC_QBUF_CAPT: {
1084 if (!meye.grab_fbuffer)
1086 if (*nb >= gbuffers)
1093 if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED)
1096 if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)
1097 mchip_cont_compression_start();
1098 meye.grab_buffer[*nb].state = MEYE_BUF_USING;
1099 meye_pushq(&meye.grabq, *nb);
1104 case MEYEIOC_SYNC: {
1107 if (*i < 0 || *i >= gbuffers)
1110 switch (meye.grab_buffer[*i].state) {
1112 case MEYE_BUF_UNUSED:
1114 case MEYE_BUF_USING:
1115 if (wait_event_interruptible(meye.grabq.proc_list,
1116 (meye.grab_buffer[*i].state != MEYE_BUF_USING)))
1120 meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
1122 *i = meye.grab_buffer[*i].size;
1126 case MEYEIOC_STILLCAPT: {
1128 if (!meye.grab_fbuffer)
1130 if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
1133 meye.grab_buffer[0].state = MEYE_BUF_USING;
1134 mchip_take_picture();
1137 mchip_hsize() * mchip_vsize() * 2);
1138 meye.grab_buffer[0].state = MEYE_BUF_DONE;
1143 case MEYEIOC_STILLJCAPT: {
1146 if (!meye.grab_fbuffer)
1148 if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
1151 meye.grab_buffer[0].state = MEYE_BUF_USING;
1153 while (*len == -1) {
1154 mchip_take_picture();
1155 *len = mchip_compress_frame(meye.grab_fbuffer, gbufsize);
1157 meye.grab_buffer[0].state = MEYE_BUF_DONE;
1163 return -ENOIOCTLCMD;
1170 static int meye_ioctl(struct inode *inode, struct file *file,
1171 unsigned int cmd, unsigned long arg)
1173 return video_usercopy(inode, file, cmd, arg, meye_do_ioctl);
1176 static int meye_mmap(struct file *file, struct vm_area_struct *vma) {
1177 unsigned long start = vma->vm_start;
1178 unsigned long size = vma->vm_end - vma->vm_start;
1179 unsigned long page, pos;
1182 if (size > gbuffers * gbufsize) {
1186 if (!meye.grab_fbuffer) {
1187 /* lazy allocation */
1188 meye.grab_fbuffer = rvmalloc(gbuffers*gbufsize);
1189 if (!meye.grab_fbuffer) {
1190 printk(KERN_ERR "meye: v4l framebuffer allocation failed\n");
1195 pos = (unsigned long)meye.grab_fbuffer;
1198 page = kvirt_to_pa(pos);
1199 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
1211 static struct file_operations meye_fops = {
1212 .owner = THIS_MODULE,
1214 .release = meye_release,
1216 .ioctl = meye_ioctl,
1217 .llseek = no_llseek,
1220 static struct video_device meye_template = {
1221 .owner = THIS_MODULE,
1223 .type = VID_TYPE_CAPTURE,
1224 .hardware = VID_HARDWARE_MEYE,
1228 static int __devinit meye_probe(struct pci_dev *pcidev,
1229 const struct pci_device_id *ent) {
1231 unsigned long mchip_adr;
1234 if (meye.mchip_dev != NULL) {
1235 printk(KERN_ERR "meye: only one device allowed!\n");
1240 sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 1);
1242 meye.mchip_dev = pcidev;
1243 memcpy(&meye.video_dev, &meye_template, sizeof(meye_template));
1245 if ((ret = pci_enable_device(meye.mchip_dev))) {
1246 printk(KERN_ERR "meye: pci_enable_device failed\n");
1250 meye.mchip_irq = pcidev->irq;
1251 mchip_adr = pci_resource_start(meye.mchip_dev,0);
1253 printk(KERN_ERR "meye: mchip has no device base address\n");
1257 if (!request_mem_region(pci_resource_start(meye.mchip_dev, 0),
1258 pci_resource_len(meye.mchip_dev, 0),
1261 printk(KERN_ERR "meye: request_mem_region failed\n");
1265 pci_read_config_byte(meye.mchip_dev, PCI_REVISION_ID, &revision);
1267 pci_set_master(meye.mchip_dev);
1269 pci_write_config_byte(meye.mchip_dev, PCI_CACHE_LINE_SIZE, 8);
1270 pci_write_config_byte(meye.mchip_dev, PCI_LATENCY_TIMER, 64);
1272 if ((ret = request_irq(meye.mchip_irq, meye_irq,
1273 SA_INTERRUPT | SA_SHIRQ, "meye", meye_irq))) {
1274 printk(KERN_ERR "meye: request_irq failed (ret=%d)\n", ret);
1278 meye.mchip_mmregs = ioremap(mchip_adr, MCHIP_MM_REGS);
1279 if (!meye.mchip_mmregs) {
1280 printk(KERN_ERR "meye: ioremap failed\n");
1285 /* Ask the camera to perform a soft reset. */
1286 pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);
1288 mchip_delay(MCHIP_HIC_CMD, 0);
1289 mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
1292 mchip_set(MCHIP_VRJ_SOFT_RESET, 1);
1295 mchip_set(MCHIP_MM_PCI_MODE, 5);
1298 mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
1300 if (video_register_device(&meye.video_dev, VFL_TYPE_GRABBER, video_nr) < 0) {
1302 printk(KERN_ERR "meye: video_register_device failed\n");
1307 printk(KERN_INFO "meye: Motion Eye Camera Driver v%d.%d.\n",
1308 MEYE_DRIVER_MAJORVERSION,
1309 MEYE_DRIVER_MINORVERSION);
1310 printk(KERN_INFO "meye: mchip KL5A72002 rev. %d, base %lx, irq %d\n",
1311 revision, mchip_adr, meye.mchip_irq);
1313 /* init all fields */
1314 init_MUTEX(&meye.lock);
1316 meye.picture.depth = 2;
1317 meye.picture.palette = VIDEO_PALETTE_YUV422;
1318 meye.picture.brightness = 32 << 10;
1319 meye.picture.hue = 32 << 10;
1320 meye.picture.colour = 32 << 10;
1321 meye.picture.contrast = 32 << 10;
1322 meye.picture.whiteness = 0;
1323 meye.params.subsample = 0;
1324 meye.params.quality = 7;
1325 meye.params.sharpness = 32;
1326 meye.params.agc = 48;
1327 meye.params.picture = 0;
1328 meye.params.framerate = 0;
1329 sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS, 32);
1330 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE, 32);
1331 sonypi_camera_command(SONYPI_COMMAND_SETCAMERACOLOR, 32);
1332 sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST, 32);
1333 sonypi_camera_command(SONYPI_COMMAND_SETCAMERASHARPNESS, 32);
1334 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAPICTURE, 0);
1335 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC, 48);
1339 iounmap(meye.mchip_mmregs);
1341 free_irq(meye.mchip_irq, meye_irq);
1343 release_mem_region(pci_resource_start(meye.mchip_dev, 0),
1344 pci_resource_len(meye.mchip_dev, 0));
1346 pci_disable_device(meye.mchip_dev);
1348 sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0);
1353 static void __devexit meye_remove(struct pci_dev *pcidev) {
1355 video_unregister_device(&meye.video_dev);
1359 /* disable interrupts */
1360 mchip_set(MCHIP_MM_INTA, 0x0);
1362 free_irq(meye.mchip_irq, meye_irq);
1364 iounmap(meye.mchip_mmregs);
1366 release_mem_region(pci_resource_start(meye.mchip_dev, 0),
1367 pci_resource_len(meye.mchip_dev, 0));
1369 pci_disable_device(meye.mchip_dev);
1373 if (meye.grab_fbuffer)
1374 rvfree(meye.grab_fbuffer, gbuffers*gbufsize);
1376 sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0);
1378 printk(KERN_INFO "meye: removed\n");
1381 static struct pci_device_id meye_pci_tbl[] __devinitdata = {
1382 { PCI_VENDOR_ID_KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002,
1383 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
1387 MODULE_DEVICE_TABLE(pci, meye_pci_tbl);
1389 static struct pci_driver meye_driver = {
1391 .id_table = meye_pci_tbl,
1392 .probe = meye_probe,
1393 .remove = __devexit_p(meye_remove),
1396 static int __init meye_init_module(void) {
1399 if (gbuffers > MEYE_MAX_BUFNBRS)
1400 gbuffers = MEYE_MAX_BUFNBRS;
1401 if (gbufsize < 0 || gbufsize > MEYE_MAX_BUFSIZE)
1402 gbufsize = MEYE_MAX_BUFSIZE;
1403 printk(KERN_INFO "meye: using %d buffers with %dk (%dk total) for capture\n",
1404 gbuffers, gbufsize/1024, gbuffers*gbufsize/1024);
1405 return pci_module_init(&meye_driver);
1408 static void __exit meye_cleanup_module(void) {
1409 pci_unregister_driver(&meye_driver);
1413 static int __init meye_setup(char *str) {
1416 str = get_options(str, ARRAY_SIZE(ints), ints);
1430 __setup("meye=", meye_setup);
1433 MODULE_AUTHOR("Stelian Pop <stelian@popies.net>");
1434 MODULE_DESCRIPTION("video4linux driver for the MotionEye camera");
1435 MODULE_LICENSE("GPL");
1439 MODULE_PARM(gbuffers,"i");
1440 MODULE_PARM_DESC(gbuffers,"number of capture buffers, default is 2 (32 max)");
1441 MODULE_PARM(gbufsize,"i");
1442 MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 614400");
1443 MODULE_PARM(video_nr,"i");
1444 MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)");
1446 /* Module entry points */
1447 module_init(meye_init_module);
1448 module_exit(meye_cleanup_module);